Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
latte
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zygzagZ
latte
Commits
167d5a8c
Commit
167d5a8c
authored
Dec 09, 2020
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP type system
parent
e83a94b3
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
365 additions
and
197 deletions
+365
-197
Absyn.cpp
Absyn.cpp
+21
-0
Absyn.h
Absyn.h
+42
-3
Info.cpp
Info.cpp
+1
-2
Info.h
Info.h
+76
-10
Latte.cpp
Latte.cpp
+5
-4
Makefile
Makefile
+6
-6
ParseError.cpp
ParseError.cpp
+41
-0
ParseError.h
ParseError.h
+28
-3
Parser.cpp
Parser.cpp
+1
-0
TypeCheck.cpp
TypeCheck.cpp
+127
-157
TypeCheck.h
TypeCheck.h
+17
-12
No files found.
Absyn.cpp
View file @
167d5a8c
...
@@ -3165,3 +3165,24 @@ ListExpr *ListExpr::clone() const
...
@@ -3165,3 +3165,24 @@ ListExpr *ListExpr::clone() const
{
{
return
new
ListExpr
(
*
this
);
return
new
ListExpr
(
*
this
);
}
}
std
::
string
Fun
::
printName
()
const
{
std
::
string
ret
=
type_
->
printName
()
+
"("
;
bool
fst
=
true
;
for
(
auto
i
:
*
listtype_
)
{
if
(
fst
)
fst
=
false
;
else
ret
+=
", "
;
ret
+=
i
->
printName
();
}
return
ret
+
")"
;
}
bool
Fun
::
isEqual
(
Type
const
*
other
)
const
{
if
(
const
Fun
*
casted
=
dynamic_cast
<
const
Fun
*>
(
other
))
{
if
(
*
type_
!=
*
casted
->
type_
||
listtype_
->
size
()
!=
casted
->
listtype_
->
size
())
return
false
;
}
return
false
;
}
\ No newline at end of file
Absyn.h
View file @
167d5a8c
...
@@ -304,12 +304,16 @@ class Type : public Visitable
...
@@ -304,12 +304,16 @@ class Type : public Visitable
{
{
public:
public:
virtual
Type
*
clone
()
const
=
0
;
virtual
Type
*
clone
()
const
=
0
;
virtual
std
::
string
printName
()
const
=
0
;
virtual
bool
isEqual
(
Type
const
*
f
)
const
=
0
;
bool
operator
==
(
Type
const
&
f
)
{
return
isEqual
(
&
f
);
}
bool
operator
!=
(
Type
const
&
f
)
{
return
!
isEqual
(
&
f
);
}
};
};
class
Expr
:
public
Visitable
class
Expr
:
public
Visitable
{
{
public:
public:
int
lineno
;
virtual
Expr
*
clone
()
const
=
0
;
virtual
Expr
*
clone
()
const
=
0
;
};
};
...
@@ -789,7 +793,6 @@ public:
...
@@ -789,7 +793,6 @@ public:
class
Int
:
public
Type
class
Int
:
public
Type
{
{
public:
public:
Int
(
const
Int
&
);
Int
(
const
Int
&
);
Int
&
operator
=
(
const
Int
&
);
Int
&
operator
=
(
const
Int
&
);
Int
();
Int
();
...
@@ -797,12 +800,17 @@ public:
...
@@ -797,12 +800,17 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Int
*
clone
()
const
;
virtual
Int
*
clone
()
const
;
void
swap
(
Int
&
);
void
swap
(
Int
&
);
std
::
string
printName
()
const
{
return
"int"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
if
(
dynamic_cast
<
const
Int
*>
(
other
))
return
true
;
return
false
;
}
};
};
class
Str
:
public
Type
class
Str
:
public
Type
{
{
public:
public:
Str
(
const
Str
&
);
Str
(
const
Str
&
);
Str
&
operator
=
(
const
Str
&
);
Str
&
operator
=
(
const
Str
&
);
Str
();
Str
();
...
@@ -810,6 +818,12 @@ public:
...
@@ -810,6 +818,12 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Str
*
clone
()
const
;
virtual
Str
*
clone
()
const
;
void
swap
(
Str
&
);
void
swap
(
Str
&
);
std
::
string
printName
()
const
{
return
"str"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
if
(
dynamic_cast
<
const
Str
*>
(
other
))
return
true
;
return
false
;
}
};
};
class
Bool
:
public
Type
class
Bool
:
public
Type
...
@@ -823,6 +837,12 @@ public:
...
@@ -823,6 +837,12 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Bool
*
clone
()
const
;
virtual
Bool
*
clone
()
const
;
void
swap
(
Bool
&
);
void
swap
(
Bool
&
);
std
::
string
printName
()
const
{
return
"bool"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
if
(
dynamic_cast
<
const
Bool
*>
(
other
))
return
true
;
return
false
;
}
};
};
class
Void
:
public
Type
class
Void
:
public
Type
...
@@ -836,6 +856,12 @@ public:
...
@@ -836,6 +856,12 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Void
*
clone
()
const
;
virtual
Void
*
clone
()
const
;
void
swap
(
Void
&
);
void
swap
(
Void
&
);
std
::
string
printName
()
const
{
return
"void"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
if
(
dynamic_cast
<
const
Void
*>
(
other
))
return
true
;
return
false
;
}
};
};
class
Array
:
public
Type
class
Array
:
public
Type
...
@@ -850,6 +876,12 @@ public:
...
@@ -850,6 +876,12 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Array
*
clone
()
const
;
virtual
Array
*
clone
()
const
;
void
swap
(
Array
&
);
void
swap
(
Array
&
);
std
::
string
printName
()
const
{
return
type_
->
printName
()
+
"[]"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
if
(
const
Array
*
casted
=
dynamic_cast
<
const
Array
*>
(
other
))
return
*
type_
==
*
casted
->
type_
;
return
false
;
}
};
};
class
ClassT
:
public
Type
class
ClassT
:
public
Type
...
@@ -864,6 +896,11 @@ public:
...
@@ -864,6 +896,11 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
ClassT
*
clone
()
const
;
virtual
ClassT
*
clone
()
const
;
void
swap
(
ClassT
&
);
void
swap
(
ClassT
&
);
std
::
string
printName
()
const
{
return
"class"
;
}
bool
isEqual
(
Type
const
*
other
)
const
{
// TODO: implement ClassT comparison
return
false
;
}
};
};
class
Fun
:
public
Type
class
Fun
:
public
Type
...
@@ -879,6 +916,8 @@ public:
...
@@ -879,6 +916,8 @@ public:
virtual
void
accept
(
Visitor
*
v
);
virtual
void
accept
(
Visitor
*
v
);
virtual
Fun
*
clone
()
const
;
virtual
Fun
*
clone
()
const
;
void
swap
(
Fun
&
);
void
swap
(
Fun
&
);
std
::
string
printName
()
const
;
bool
isEqual
(
Type
const
*
other
)
const
;
};
};
class
EVar
:
public
Expr
class
EVar
:
public
Expr
...
...
Info.cpp
View file @
167d5a8c
#include "Info.h"
#include "Info.h"
Scope
g_scope
;
\ No newline at end of file
Info.h
View file @
167d5a8c
...
@@ -5,34 +5,100 @@
...
@@ -5,34 +5,100 @@
using
namespace
std
;
using
namespace
std
;
class
VarInfo
{
class
VarInfo
{
public:
VarInfo
(
string
n
,
int
l
)
:
name
(
n
),
lineLocation
(
l
)
{}
VarInfo
(
PIdent
*
ident
)
:
VarInfo
(
ident
->
string_
,
ident
->
integer_
)
{}
string
name
;
string
name
;
string
type
;
Type
*
type
;
int
lineLocation
;
bool
operator
<
(
const
VarInfo
&
other
)
const
{
bool
operator
<
(
const
VarInfo
&
other
)
const
{
return
name
!=
other
.
name
?
name
<
other
.
name
:
type
<
other
.
type
;
return
name
!=
other
.
name
?
name
<
other
.
name
:
type
<
other
.
type
;
}
}
};
};
class
FunctionInfo
:
VarInfo
{
class
ClassInfo
;
vector
<
VarInfo
>
arguments
;
class
FunctionInfo
:
public
VarInfo
{
public:
Block
*
block
;
vector
<
VarInfo
*>
arguments
;
ClassInfo
*
klass
;
FunctionInfo
(
PIdent
*
ident
,
ClassInfo
*
klass
=
NULL
)
:
VarInfo
(
ident
),
klass
(
klass
)
{};
~
FunctionInfo
()
{
for
(
auto
&
a
:
arguments
)
delete
a
;
}
};
};
class
ClassInfo
:
VarInfo
class
ClassInfo
:
public
VarInfo
{
{
ClassInfo
*
parent
;
ClassInfo
*
parent
;
public:
public:
vector
<
FunctionInfo
*>
functions
;
vector
<
VarInfo
*>
variables
;
ClassInfo
(
PIdent
*
ident
,
ClassInfo
*
parent
=
NULL
)
:
VarInfo
(
ident
),
parent
(
parent
)
{};
ClassInfo
*
getParent
()
const
{
return
parent
;
};
ClassInfo
*
getParent
()
const
{
return
parent
;
};
vector
<
FunctionInfo
>
functions
;
FunctionInfo
*
getFunction
(
string
name
)
const
{
vector
<
VarInfo
>
variables
;
for
(
auto
i
:
functions
)
if
(
i
->
name
==
name
)
return
i
;
return
parent
?
parent
->
getFunction
(
name
)
:
NULL
;
}
};
VarInfo
*
getVar
(
string
name
)
const
{
for
(
auto
i
:
variables
)
if
(
i
->
name
==
name
)
return
i
;
return
parent
?
parent
->
getVar
(
name
)
:
NULL
;
}
~
ClassInfo
()
{
for
(
auto
&
f
:
functions
)
delete
f
;
for
(
auto
&
v
:
variables
)
delete
v
;
}
};
class
Scope
{
class
Scope
{
public:
public:
vector
<
ClassInfo
>
classes
;
vector
<
ClassInfo
*>
classes
;
vector
<
FunctionInfo
>
functions
;
vector
<
FunctionInfo
*>
functions
;
ClassInfo
*
currentClass
;
Scope
()
:
currentClass
(
NULL
)
{}
~
Scope
()
{
for
(
auto
&
c
:
classes
)
delete
c
;
for
(
auto
&
f
:
functions
)
delete
f
;
}
ClassInfo
*
getClass
(
string
name
)
const
{
for
(
auto
i
:
classes
)
if
(
i
->
name
==
name
)
return
i
;
return
NULL
;
}
FunctionInfo
*
getFunction
(
string
name
,
bool
local
=
false
)
const
{
if
(
currentClass
&&
!
local
)
if
(
auto
*
f
=
currentClass
->
getFunction
(
name
))
return
f
;
for
(
auto
i
:
functions
)
if
(
i
->
name
==
name
)
return
i
;
return
NULL
;
}
};
};
extern
Scope
g_scope
;
#endif
#endif
\ No newline at end of file
Latte.cpp
View file @
167d5a8c
...
@@ -50,7 +50,7 @@ int main(int argc, char ** argv)
...
@@ -50,7 +50,7 @@ int main(int argc, char ** argv)
/* The default entry point is used. For other options see Parser.H */
/* The default entry point is used. For other options see Parser.H */
Program
*
parse_tree
=
pProgram
(
input
);
Program
*
parse_tree
=
pProgram
(
input
);
if
(
!
parse_tree
)
{
if
(
!
parse_tree
)
{
fprintf
(
stderr
,
"Parser error, invalid syntax!"
);
fprintf
(
stderr
,
"Parser error, invalid syntax!
\n
"
);
return
1
;
return
1
;
}
}
...
@@ -64,12 +64,13 @@ int main(int argc, char ** argv)
...
@@ -64,12 +64,13 @@ int main(int argc, char ** argv)
}
}
binaryPath
=
argv
[
0
];
binaryPath
=
argv
[
0
];
std
::
filesystem
::
path
file
(
filename
?
filename
:
"Instant"
);
std
::
filesystem
::
path
file
(
filename
?
filename
:
"Latte"
);
TypeCheck
checker
;
try
{
try
{
TypeCheck
checker
;
checker
.
check
(
parse_tree
);
checker
.
check
(
parse_tree
);
}
catch
(
ParseError
&
e
)
{
}
catch
(
ParseError
const
&
e
)
{
std
::
cerr
<<
e
.
what
()
<<
std
::
endl
;
std
::
cerr
<<
e
.
what
()
<<
std
::
endl
;
return
1
;
}
}
/*Compiler c(file);
/*Compiler c(file);
std::string out = c.compile(parse_tree);
std::string out = c.compile(parse_tree);
...
...
Makefile
View file @
167d5a8c
...
@@ -7,7 +7,7 @@ FLEX_OPTS=-PGrammar
...
@@ -7,7 +7,7 @@ FLEX_OPTS=-PGrammar
BISON
=
bison
BISON
=
bison
BISON_OPTS
=
-t
-pGrammar
BISON_OPTS
=
-t
-pGrammar
OBJS
=
Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o
OBJS
=
Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o
ParseError.o
.PHONY
:
clean distclean
.PHONY
:
clean distclean
...
@@ -16,9 +16,6 @@ all : latc
...
@@ -16,9 +16,6 @@ all : latc
clean
:
clean
:
rm
-f
*
.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
rm
-f
*
.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
# distclean : clean
# rm -f Absyn.cpp Absyn.h Latte.cpp Parser.cpp Parser.h Lexer.cpp Skeleton.cpp Skeleton.h Printer.cpp Printer.h Makefile Grammar.l Grammar.y Grammar.tex
latc
:
${OBJS} Latte.o
latc
:
${OBJS} Latte.o
@
echo
"Linking latc..."
@
echo
"Linking latc..."
${
CC
}
${
CCFLAGS
}
${
OBJS
}
Latte.o
-o
latc
${
CC
}
${
CCFLAGS
}
${
OBJS
}
Latte.o
-o
latc
...
@@ -44,11 +41,14 @@ Printer.o : Printer.cpp Printer.h Absyn.h
...
@@ -44,11 +41,14 @@ Printer.o : Printer.cpp Printer.h Absyn.h
Skeleton.o
:
Skeleton.cpp Skeleton.h Absyn.h
Skeleton.o
:
Skeleton.cpp Skeleton.h Absyn.h
${
CC
}
${
CCFLAGS
}
-Wno-unused-parameter
-c
Skeleton.cpp
${
CC
}
${
CCFLAGS
}
-Wno-unused-parameter
-c
Skeleton.cpp
Latte.o
:
Latte.cpp Parser.h Printer.h Absyn.h ParseError.h
Latte.o
:
Latte.cpp Parser.h Printer.h Absyn.h ParseError.h
TypeCheck.h Info.h
${
CC
}
${
CCFLAGS
}
-c
Latte.cpp
${
CC
}
${
CCFLAGS
}
-c
Latte.cpp
TypeCheck.o
:
TypeCheck.cpp TypeCheck.h Absyn.h ParseError.h
TypeCheck.o
:
TypeCheck.cpp TypeCheck.h
Info.h
Absyn.h ParseError.h
${
CC
}
${
CCFLAGS
}
-c
TypeCheck.cpp
${
CC
}
${
CCFLAGS
}
-c
TypeCheck.cpp
Info.o
:
Info.cpp Info.h Absyn.h
Info.o
:
Info.cpp Info.h Absyn.h
${
CC
}
${
CCFLAGS
}
-c
Info.cpp
${
CC
}
${
CCFLAGS
}
-c
Info.cpp
ParseError.o
:
ParseError.cpp Info.h Absyn.h ParseError.h
${
CC
}
${
CCFLAGS
}
-c
ParseError.cpp
ParseError.cpp
0 → 100644
View file @
167d5a8c
#include "ParseError.h"
#include "Info.h"
#include "Printer.h"
#include <sstream>
using
namespace
std
;
RedefinedError
::
RedefinedError
(
PIdent
*
ident
,
VarInfo
*
orig
)
{
stringstream
ss
;
ss
<<
"Variable
\"
"
<<
ident
->
string_
<<
"
\"
at line "
<<
ident
->
integer_
<<
" redeclared! First declaration at line "
<<
orig
->
lineLocation
;
msg
=
ss
.
str
();
line
=
ident
->
integer_
;
}
UndefinedError
::
UndefinedError
(
PIdent
*
ident
)
{
stringstream
ss
;
ss
<<
"Undefined reference to
\"
"
<<
ident
->
string_
<<
"
\"
at line "
<<
ident
->
integer_
;
msg
=
ss
.
str
();
line
=
ident
->
integer_
;
}
InvalidTypeError
::
InvalidTypeError
(
int
lineno
,
Type
&
expected
,
vector
<
shared_ptr
<
Type
>>
received
,
Expr
*
expr
)
{
stringstream
ss
;
ss
<<
"Invalid expression type at line "
<<
lineno
<<
". Expected
\"
"
<<
expected
.
printName
()
<<
"
\"
, instead received "
;
bool
fst
=
true
;
for
(
auto
i
:
received
)
{
if
(
fst
)
fst
=
false
;
else
ss
<<
", "
;
ss
<<
i
->
printName
();
}
ss
<<
"."
;
if
(
expr
)
{
ss
<<
" Expression: "
;
PrintAbsyn
p
;
ss
<<
p
.
print
(
expr
);
}
msg
=
ss
.
str
();
line
=
lineno
;
}
\ No newline at end of file
ParseError.h
View file @
167d5a8c
#ifndef ERROR_HEADER
#ifndef ERROR_HEADER
#define ERROR_HEADER
#define ERROR_HEADER
#include "Absyn.h"
#include <string>
#include <string>
#include <stdexcept>
#include <memory>
using
namespace
std
;
using
namespace
std
;
class
ParseError
:
std
::
exception
{
class
ParseError
:
std
::
runtime_error
{
protected:
string
msg
;
string
msg
;
int
line
;
ParseError
()
:
runtime_error
(
"ParseError"
),
line
(
-
1
)
{}
public:
ParseError
(
string
reason
,
int
line
=
-
1
)
:
runtime_error
(
"ParseError"
),
line
(
line
)
{}
virtual
const
char
*
what
()
const
_GLIBCXX_TXN_SAFE_DYN
_GLIBCXX_NOTHROW
{
return
msg
.
data
();
}
};
class
PIdent
;
class
VarInfo
;
class
RedefinedError
:
public
ParseError
{
public:
RedefinedError
(
PIdent
*
ident
,
VarInfo
*
orig
);
};
class
UndefinedError
:
public
ParseError
{
public:
UndefinedError
(
PIdent
*
ident
);
};
class
InvalidTypeError
:
public
ParseError
{
public:
public:
ParseError
(
string
reason
)
:
msg
(
reason
)
{}
InvalidTypeError
(
int
lineno
,
Type
&
expected
,
vector
<
shared_ptr
<
Type
>>
received
,
Expr
*
expr
=
NULL
);
const
char
*
what
()
{
return
msg
.
data
();
}
};
};
#endif
#endif
\ No newline at end of file
Parser.cpp
View file @
167d5a8c
...
@@ -2000,6 +2000,7 @@ yyreduce:
...
@@ -2000,6 +2000,7 @@ yyreduce:
default:
break
;
default:
break
;
}
}
// if (yyval.expr_) yyval.expr_->lineno = yy_mylinenumber;
/* User semantic actions sometimes alter yychar, and that requires
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
approach of translating immediately before every use of yytoken.
...
...
TypeCheck.cpp
View file @
167d5a8c
#include "TypeCheck.h"
#include "TypeCheck.h"
#include "ParseError.h"
#include <stdexcept>
#include <stdexcept>
void
TypeCheck
::
visitProgram
(
Program
*
t
)
{}
//abstract class
void
TypeCheck
::
visitProgram
(
Program
*
t
)
{}
//abstract class
...
@@ -6,10 +7,25 @@ void TypeCheck::visitTopDef(TopDef *t) {} //abstract class
...
@@ -6,10 +7,25 @@ void TypeCheck::visitTopDef(TopDef *t) {} //abstract class
void
TypeCheck
::
visitFunDef
(
FunDef
*
t
)
{}
//abstract class
void
TypeCheck
::
visitFunDef
(
FunDef
*
t
)
{}
//abstract class
void
TypeCheck
::
visitArg
(
Arg
*
t
)
{}
//abstract class
void
TypeCheck
::
visitArg
(
Arg
*
t
)
{}
//abstract class
void
TypeCheck
::
visitClassDef
(
ClassDef
*
t
)
{
void
TypeCheck
::
visitClassDef
(
ClassDef
*
t
)
{
t
->
getName
()
->
accept
(
this
);
const
string
name
=
t
->
getName
()
->
string_
;
if
(
t
->
getParent
())
ClassInfo
*
c
=
scope
.
getClass
(
name
);
t
->
getParent
()
->
accept
(
this
);
if
(
c
)
{
throw
RedefinedError
(
t
->
getName
(),
c
);
}
ClassInfo
*
parent
=
NULL
;
if
(
t
->
getParent
())
{
const
string
parentName
=
t
->
getParent
()
->
string_
;
parent
=
scope
.
getClass
(
parentName
);
if
(
!
parent
)
{
throw
UndefinedError
(
t
->
getParent
());
}
}
c
=
new
ClassInfo
(
t
->
getName
(),
parent
);
scope
.
classes
.
push_back
(
c
);
scope
.
currentClass
=
c
;
t
->
getBlock
()
->
accept
(
this
);
t
->
getBlock
()
->
accept
(
this
);
scope
.
currentClass
=
NULL
;
}
}
void
TypeCheck
::
visitClassBlock
(
ClassBlock
*
t
)
{}
//abstract class
void
TypeCheck
::
visitClassBlock
(
ClassBlock
*
t
)
{}
//abstract class
...
@@ -56,15 +72,19 @@ void TypeCheck::visitClDef(ClDef *cl_def)
...
@@ -56,15 +72,19 @@ void TypeCheck::visitClDef(ClDef *cl_def)
}
}
void
TypeCheck
::
visitFuncDef
(
FuncDef
*
func_
def
)
void
TypeCheck
::
visitFuncDef
(
FuncDef
*
def
)
{
{
/* Code For FuncDef Goes Here */
const
string
name
=
def
->
pident_
->
string_
;
FunctionInfo
*
f
=
scope
.
getFunction
(
name
);
if
(
f
)
{
throw
RedefinedError
(
def
->
pident_
,
f
);
}
func_def
->
type_
->
accept
(
this
);
f
=
new
FunctionInfo
(
def
->
pident_
,
scope
.
currentClass
);
func_def
->
pident_
->
accept
(
this
);
func_def
->
listarg_
->
accept
(
this
);
func_def
->
block_
->
accept
(
this
);
f
->
block
=
def
->
block_
;
auto
&
targetVector
=
scope
.
currentClass
?
scope
.
currentClass
->
functions
:
scope
.
functions
;
targetVector
.
push_back
(
f
);
}
}
void
TypeCheck
::
visitAr
(
Ar
*
ar
)
void
TypeCheck
::
visitAr
(
Ar
*
ar
)
...
@@ -338,24 +358,18 @@ void TypeCheck::visitEVar(EVar *e_var)
...
@@ -338,24 +358,18 @@ void TypeCheck::visitEVar(EVar *e_var)
void
TypeCheck
::
visitELitInt
(
ELitInt
*
e_lit_int
)
void
TypeCheck
::
visitELitInt
(
ELitInt
*
e_lit_int
)
{
{
/* Code For ELitInt Goes Here */
visitInteger
(
e_lit_int
->
integer_
);
visitInteger
(
e_lit_int
->
integer_
);
lastType
=
make_shared
<
Int
>
();
}
}
void
TypeCheck
::
visitELitTrue
(
ELitTrue
*
e_lit_true
)
void
TypeCheck
::
visitELitTrue
(
ELitTrue
*
e_lit_true
)
{
{
/* Code For ELitTrue Goes Here */
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visitELitFalse
(
ELitFalse
*
e_lit_false
)
void
TypeCheck
::
visitELitFalse
(
ELitFalse
*
e_lit_false
)
{
{
/* Code For ELitFalse Goes Here */
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visitEApp
(
EApp
*
e_app
)
void
TypeCheck
::
visitEApp
(
EApp
*
e_app
)
...
@@ -367,29 +381,37 @@ void TypeCheck::visitEApp(EApp *e_app)
...
@@ -367,29 +381,37 @@ void TypeCheck::visitEApp(EApp *e_app)
}
}
void
TypeCheck
::
visitEString
(
EString
*
e
_string
)
void
TypeCheck
::
visitEString
(
EString
*
e
)
{
{
/* Code For EString Goes Here */
/* Code For EString Goes Here */
visitString
(
e_string
->
string_
);
visitString
(
e
->
string_
);
auto
a
=
lastType
;
Str
expect
;
if
(
*
a
!=
expect
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
},
e
);
}
lastType
=
make_shared
<
Str
>
();
}
}
void
TypeCheck
::
visitENewArray
(
ENewArray
*
e
_new_array
)
void
TypeCheck
::
visitENewArray
(
ENewArray
*
e
)
{
{
/* Code For ENewArray Goes Here */
/* Code For ENewArray Goes Here */
e_new_array
->
type_
->
accept
(
this
);
e
->
type_
->
accept
(
this
);
e_new_array
->
expr_
->
accept
(
this
);
e
->
expr_
->
accept
(
this
);
auto
a
=
lastType
;
Array
expect
(
e
->
type_
);
if
(
*
a
!=
expect
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
},
e
);
}
lastType
=
make_shared
<
Array
>
(
e
->
type_
);
}
}
void
TypeCheck
::
visitENewClass
(
ENewClass
*
e_new_class
)
void
TypeCheck
::
visitENewClass
(
ENewClass
*
e_new_class
)
{
{
/* Code For ENewClass Goes Here */
e_new_class
->
pident_
->
accept
(
this
);
e_new_class
->
pident_
->
accept
(
this
);
lastType
=
make_shared
<
ClassT
>
(
e_new_class
->
pident_
);
}
}
void
TypeCheck
::
visitEClsMmbr
(
EClsMmbr
*
e_cls_mmbr
)
void
TypeCheck
::
visitEClsMmbr
(
EClsMmbr
*
e_cls_mmbr
)
...
@@ -411,11 +433,10 @@ void TypeCheck::visitEClsMthd(EClsMthd *e_cls_mthd)
...
@@ -411,11 +433,10 @@ void TypeCheck::visitEClsMthd(EClsMthd *e_cls_mthd)
}
}
void
TypeCheck
::
visitNull
(
Null
*
null
)
void
TypeCheck
::
visitNull
(
Null
*
e
)
{
{
/* Code For Null Goes Here */
PIdent
*
ident
=
new
PIdent
(
"null"
,
e
->
lineno
);
lastType
=
make_shared
<
ClassT
>
(
ident
);
// TODO
}
}
void
TypeCheck
::
visitEIndexAcc
(
EIndexAcc
*
e_index_acc
)
void
TypeCheck
::
visitEIndexAcc
(
EIndexAcc
*
e_index_acc
)
...
@@ -424,7 +445,7 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
...
@@ -424,7 +445,7 @@ void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
e_index_acc
->
pident_
->
accept
(
this
);
e_index_acc
->
pident_
->
accept
(
this
);
e_index_acc
->
expr_
->
accept
(
this
);
e_index_acc
->
expr_
->
accept
(
this
);
throw
UndefinedError
(
e_index_acc
->
pident_
);
// TODO
}
}
void
TypeCheck
::
visitECast
(
ECast
*
e_cast
)
void
TypeCheck
::
visitECast
(
ECast
*
e_cast
)
...
@@ -433,151 +454,96 @@ void TypeCheck::visitECast(ECast *e_cast)
...
@@ -433,151 +454,96 @@ void TypeCheck::visitECast(ECast *e_cast)
e_cast
->
pident_
->
accept
(
this
);
e_cast
->
pident_
->
accept
(
this
);
e_cast
->
expr_
->
accept
(
this
);
e_cast
->
expr_
->
accept
(
this
);
lastType
=
make_shared
<
ClassT
>
(
e_cast
->
pident_
);
}
void
TypeCheck
::
visitNeg
(
Neg
*
neg
)
{
/* Code For Neg Goes Here */
neg
->
expr_
->
accept
(
this
);
}
void
TypeCheck
::
visitNot
(
Not
*
not_
)
{
/* Code For Not Goes Here */
not_
->
expr_
->
accept
(
this
);
}
void
TypeCheck
::
visitEMul
(
EMul
*
e_mul
)
{
/* Code For EMul Goes Here */
e_mul
->
expr_1
->
accept
(
this
);
e_mul
->
mulop_
->
accept
(
this
);
e_mul
->
expr_2
->
accept
(
this
);
}
void
TypeCheck
::
visitEAdd
(
EAdd
*
e_add
)
{
/* Code For EAdd Goes Here */
e_add
->
expr_1
->
accept
(
this
);
e_add
->
addop_
->
accept
(
this
);
e_add
->
expr_2
->
accept
(
this
);
}
void
TypeCheck
::
visitERel
(
ERel
*
e_rel
)
{
/* Code For ERel Goes Here */
e_rel
->
expr_1
->
accept
(
this
);
e_rel
->
relop_
->
accept
(
this
);
e_rel
->
expr_2
->
accept
(
this
);
}
void
TypeCheck
::
visitEAnd
(
EAnd
*
e_and
)
{
/* Code For EAnd Goes Here */
e_and
->
expr_1
->
accept
(
this
);
e_and
->
expr_2
->
accept
(
this
);
}
void
TypeCheck
::
visitEOr
(
EOr
*
e_or
)
{
/* Code For EOr Goes Here */
e_or
->
expr_1
->
accept
(
this
);
e_or
->
expr_2
->
accept
(
this
);
}
void
TypeCheck
::
visitPlus
(
Plus
*
plus
)
{
/* Code For Plus Goes Here */
}
void
TypeCheck
::
visitMinus
(
Minus
*
minus
)
{
/* Code For Minus Goes Here */
}
}
void
TypeCheck
::
visit
Times
(
Times
*
times
)
void
TypeCheck
::
visit
Neg
(
Neg
*
e
)
{
{
/* Code For Times Goes Here */
e
->
expr_
->
accept
(
this
);
auto
a
=
lastType
;
Int
expect
;
}
if
(
*
a
!=
expect
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
},
e
);
void
TypeCheck
::
visitDiv
(
Div
*
div
)
}
{
lastType
=
make_shared
<
Int
>
();
/* Code For Div Goes Here */
}
void
TypeCheck
::
visitMod
(
Mod
*
mod
)
{
/* Code For Mod Goes Here */
}
}
void
TypeCheck
::
visit
LTH
(
LTH
*
lth
)
void
TypeCheck
::
visit
Not
(
Not
*
e
)
{
{
/* Code For LTH Goes Here */
e
->
expr_
->
accept
(
this
);
auto
a
=
lastType
;
Bool
expect
;
if
(
*
a
!=
expect
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
},
e
);
}
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visit
LE
(
LE
*
l
e
)
void
TypeCheck
::
visit
EMul
(
EMul
*
e
)
{
{
/* Code For LE Goes Here */
e
->
expr_1
->
accept
(
this
);
auto
a
=
lastType
;
e
->
expr_2
->
accept
(
this
);
auto
b
=
lastType
;
Int
expect
;
if
(
*
a
!=
expect
||
*
a
!=
*
b
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
,
b
},
e
);
}
lastType
=
make_shared
<
Int
>
();
}
}
void
TypeCheck
::
visit
GTH
(
GTH
*
gth
)
void
TypeCheck
::
visit
EAdd
(
EAdd
*
e
)
{
{
/* Code For GTH Goes Here */
e
->
expr_1
->
accept
(
this
);
auto
a
=
lastType
;
e
->
expr_2
->
accept
(
this
);
auto
b
=
lastType
;
Int
expect
;
if
(
*
a
!=
expect
||
*
a
!=
*
b
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
,
b
},
e
);
}
lastType
=
make_shared
<
Int
>
();
}
}
void
TypeCheck
::
visit
GE
(
GE
*
g
e
)
void
TypeCheck
::
visit
ERel
(
ERel
*
e
)
{
{
/* Code For GE Goes Here */
e
->
expr_1
->
accept
(
this
);
auto
a
=
lastType
;
e
->
expr_2
->
accept
(
this
);
auto
b
=
lastType
;
Int
expect
;
if
(
*
a
!=
expect
||
*
a
!=
*
b
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
,
b
},
e
);
}
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visitE
QU
(
EQU
*
equ
)
void
TypeCheck
::
visitE
And
(
EAnd
*
e
)
{
{
/* Code For EQU Goes Here */
e
->
expr_1
->
accept
(
this
);
auto
a
=
lastType
;
e
->
expr_2
->
accept
(
this
);
auto
b
=
lastType
;
Bool
expect
;
if
(
*
a
!=
expect
||
*
a
!=
*
b
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
,
b
},
e
);
}
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visit
NE
(
NE
*
n
e
)
void
TypeCheck
::
visit
EOr
(
EOr
*
e
)
{
{
/* Code For NE Goes Here */
e
->
expr_1
->
accept
(
this
);
auto
a
=
lastType
;
e
->
expr_2
->
accept
(
this
);
auto
b
=
lastType
;
Bool
expect
;
if
(
*
a
!=
expect
||
*
a
!=
*
b
)
{
throw
InvalidTypeError
(
e
->
lineno
,
expect
,
{
a
,
b
},
e
);
}
lastType
=
make_shared
<
Bool
>
();
}
}
void
TypeCheck
::
visitListTopDef
(
ListTopDef
*
list_top_def
)
void
TypeCheck
::
visitListTopDef
(
ListTopDef
*
list_top_def
)
{
{
for
(
ListTopDef
::
iterator
i
=
list_top_def
->
begin
()
;
i
!=
list_top_def
->
end
()
;
++
i
)
for
(
ListTopDef
::
iterator
i
=
list_top_def
->
begin
()
;
i
!=
list_top_def
->
end
()
;
++
i
)
...
@@ -664,14 +630,18 @@ void TypeCheck::visitIdent(Ident x)
...
@@ -664,14 +630,18 @@ void TypeCheck::visitIdent(Ident x)
TypeCheck
::
TypeCheck
()
:
state
(
initialized
)
{
}
void
TypeCheck
::
check
(
Visitable
*
v
)
void
TypeCheck
::
check
(
Visitable
*
v
)
{
{
if
(
state
!=
State
::
initialized
)
{
if
(
state
!=
State
::
initialized
)
{
throw
std
::
runtime_error
(
"already initialized"
);
throw
std
::
runtime_error
(
"already initialized"
);
}
}
state
=
State
::
buildInfo
;
v
->
accept
(
this
);
state
=
State
::
checkType
;
state
=
State
::
checkType
;
v
->
accept
(
this
);
v
->
accept
(
this
);
}
}
\ No newline at end of file
TypeCheck.h
View file @
167d5a8c
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
/* You might want to change the above name. */
/* You might want to change the above name. */
#include "Absyn.h"
#include "Absyn.h"
#include "Info.h"
#include <memory>
class
TypeCheck
:
public
Visitor
class
TypeCheck
:
public
Visitor
...
@@ -12,8 +14,11 @@ class TypeCheck : public Visitor
...
@@ -12,8 +14,11 @@ class TypeCheck : public Visitor
buildInfo
,
buildInfo
,
checkType
checkType
}
state
;
}
state
;
Scope
scope
;
shared_ptr
<
Type
>
lastType
;
public:
public:
TypeCheck
()
:
state
(
initialized
)
{}
;
TypeCheck
();
void
check
(
Visitable
*
v
);
void
check
(
Visitable
*
v
);
protected:
protected:
void
visitProgram
(
Program
*
p
);
void
visitProgram
(
Program
*
p
);
...
@@ -87,17 +92,17 @@ protected:
...
@@ -87,17 +92,17 @@ protected:
void
visitERel
(
ERel
*
p
);
void
visitERel
(
ERel
*
p
);
void
visitEAnd
(
EAnd
*
p
);
void
visitEAnd
(
EAnd
*
p
);
void
visitEOr
(
EOr
*
p
);
void
visitEOr
(
EOr
*
p
);
void
visitPlus
(
Plus
*
p
);
void
visitPlus
(
Plus
*
p
)
{}
;
void
visitMinus
(
Minus
*
p
);
void
visitMinus
(
Minus
*
p
)
{}
;
void
visitTimes
(
Times
*
p
);
void
visitTimes
(
Times
*
p
)
{}
;
void
visitDiv
(
Div
*
p
);
void
visitDiv
(
Div
*
p
)
{}
;
void
visitMod
(
Mod
*
p
);
void
visitMod
(
Mod
*
p
)
{}
;
void
visitLTH
(
LTH
*
p
);
void
visitLTH
(
LTH
*
p
)
{}
;
void
visitLE
(
LE
*
p
);
void
visitLE
(
LE
*
p
)
{}
;
void
visitGTH
(
GTH
*
p
);
void
visitGTH
(
GTH
*
p
)
{}
;
void
visitGE
(
GE
*
p
);
void
visitGE
(
GE
*
p
)
{}
;
void
visitEQU
(
EQU
*
p
);
void
visitEQU
(
EQU
*
p
)
{}
;
void
visitNE
(
NE
*
p
);
void
visitNE
(
NE
*
p
)
{}
;
void
visitListTopDef
(
ListTopDef
*
p
);
void
visitListTopDef
(
ListTopDef
*
p
);
void
visitListArg
(
ListArg
*
p
);
void
visitListArg
(
ListArg
*
p
);
void
visitListClassBlockDef
(
ListClassBlockDef
*
p
);
void
visitListClassBlockDef
(
ListClassBlockDef
*
p
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment