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
5f84c1c3
Commit
5f84c1c3
authored
Dec 11, 2020
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Scope dziedziczy z binding i kazda klasa ma jako parent binding global
scope
parent
08a16dd0
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
190 additions
and
165 deletions
+190
-165
Absyn.cpp
Absyn.cpp
+10
-6
Absyn.h
Absyn.h
+1
-1
Info.cpp
Info.cpp
+8
-6
Info.h
Info.h
+13
-11
InfoList.h
InfoList.h
+6
-4
Latte.cpp
Latte.cpp
+1
-1
ParseError.cpp
ParseError.cpp
+44
-2
ParseError.h
ParseError.h
+4
-2
Printer.cpp
Printer.cpp
+3
-0
TypeCheck.cpp
TypeCheck.cpp
+93
-127
TypeCheck.h
TypeCheck.h
+6
-5
TypeDefs.h
TypeDefs.h
+1
-0
No files found.
Absyn.cpp
View file @
5f84c1c3
...
...
@@ -1200,7 +1200,10 @@ Item::~Item()
void
Item
::
accept
(
Visitor
*
v
)
{
v
->
visitItem
(
this
);
if
(
this
->
expr_
)
v
->
visitInit
(
this
);
else
v
->
visitNoInit
(
this
);
}
Item
*
Item
::
clone
()
const
...
...
@@ -2888,9 +2891,10 @@ std::string Fun::printName() const{
}
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
;
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
}
return
false
;
}
Absyn.h
View file @
5f84c1c3
...
...
@@ -223,6 +223,7 @@ public:
class
Type
:
public
Visitable
{
public:
std
::
weak_ptr
<
Binding
>
binding
;
virtual
Type
*
clone
()
const
=
0
;
virtual
std
::
string
printName
()
const
=
0
;
virtual
bool
isEqual
(
Type
const
*
f
)
const
=
0
;
...
...
@@ -258,7 +259,6 @@ public:
};
class
VarInfo
;
class
PIdent
:
public
Visitable
{
...
...
Info.cpp
View file @
5f84c1c3
...
...
@@ -11,7 +11,9 @@ FunctionInfo::FunctionInfo(FuncDef *expr, ClassInfoPtr klass)
Binding
::
Binding
(
shared_ptr
<
Binding
>
parent
)
:
variables
(
parent
?
parent
->
variables
:
nullptr
),
:
variables
(
parent
?
&
parent
->
variables
:
nullptr
),
classes
(
parent
?
&
parent
->
classes
:
nullptr
,
&
variables
),
functions
(
parent
?
&
parent
->
functions
:
nullptr
,
&
variables
),
parent
(
parent
)
{
...
...
@@ -19,16 +21,16 @@ Binding::Binding(shared_ptr<Binding> parent)
ClassInfo
::
ClassInfo
(
PIdent
*
ident
,
ClassInfo
Ptr
parent
/*= nullptr*/
)
ClassInfo
::
ClassInfo
(
PIdent
*
ident
,
Binding
Ptr
parent
/*= nullptr*/
)
:
VarInfo
(
ident
),
Binding
(
parent
),
functions
(
parent
?
parent
->
functions
:
nullptr
)
Binding
(
parent
)
{
};
Scope
::
Scope
()
:
currentClass
(
nullptr
)
:
currentClass
()
{
}
\ No newline at end of file
}
Info.h
View file @
5f84c1c3
...
...
@@ -10,12 +10,14 @@ using namespace std;
class
VarInfo
{
public:
VarInfo
(
PIdent
*
ident
,
Type
*
type
=
NULL
)
:
ident
(
ident
),
name
(
ident
->
string_
),
type
(
type
),
lineLocation
(
ident
->
lineno
)
{}
VarInfo
(
PIdent
*
ident
,
TypePtr
type
)
:
ident
(
ident
),
name
(
ident
->
string_
),
type
(
type
),
lineLocation
(
ident
->
lineno
)
{}
VarInfo
(
PIdent
*
ident
,
Type
*
type
=
nullptr
)
:
ident
(
ident
),
name
(
ident
->
string_
),
type
(
type
),
lineLocation
(
ident
->
lineno
)
{}
VarInfo
(
Ar
*
arg
)
:
VarInfo
(
arg
->
pident_
,
arg
->
type_
)
{}
virtual
~
VarInfo
()
{}
PIdent
*
ident
;
string
name
;
Type
*
type
;
Type
Ptr
type
;
int
lineLocation
;
bool
operator
<
(
const
VarInfo
&
other
)
const
{
...
...
@@ -29,7 +31,7 @@ public:
Block
*
block
;
vector
<
VarInfoPtr
>
arguments
;
weak_ptr
<
ClassInfo
>
klass
;
weak
_ptr
<
Binding
>
binding
;
shared
_ptr
<
Binding
>
binding
;
FunctionInfo
(
FuncDef
*
expr
,
ClassInfoPtr
klass
=
nullptr
);
// FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
};
...
...
@@ -39,8 +41,11 @@ public:
class
Binding
{
public:
InfoList
<
VarInfo
>
variables
;
InfoList
<
ClassInfo
>
classes
;
InfoList
<
FunctionInfo
>
functions
;
BindingPtr
parent
;
Binding
(
BindingPtr
parent
);
Binding
(
BindingPtr
parent
=
nullptr
);
BindingPtr
getParent
()
const
{
return
parent
;
};
};
...
...
@@ -48,22 +53,19 @@ public:
class
ClassInfo
:
public
VarInfo
,
public
Binding
{
public:
InfoList
<
FunctionInfo
>
functions
;
ClassInfo
(
PIdent
*
ident
,
ClassInfo
Ptr
parent
=
nullptr
);
ClassInfo
(
PIdent
*
ident
,
Binding
Ptr
parent
=
nullptr
);
ClassInfoPtr
getParent
()
const
{
return
stat
ic_pointer_cast
<
ClassInfo
>
(
parent
);
};
// ClassInfoPtr getParent() const { return dynam
ic_pointer_cast<ClassInfo>(parent); };
};
class
Scope
{
class
Scope
:
public
Binding
{
public:
InfoList
<
ClassInfo
>
classes
;
InfoList
<
FunctionInfo
>
functions
;
BindingPtr
currentBinding
;
ClassInfoPtr
currentClass
;
FunctionInfoPtr
currentFunction
;
Scope
();
};
#endif
\ No newline at end of file
#endif
InfoList.h
View file @
5f84c1c3
...
...
@@ -17,13 +17,12 @@ struct Compare
};
template
<
typename
T
,
typename
=
typename
std
::
enable_if
<
std
::
is_base_of
<
VarInfo
,
T
>::
value
>::
type
,
typename
TPtr
=
shared_ptr
<
T
>>
template
<
typename
T
,
typename
TPtr
=
shared_ptr
<
T
>>
class
InfoList
:
public
set
<
TPtr
,
Compare
<
TPtr
>>
{
public:
InfoList
<
T
>
*
parent
;
InfoList
(
InfoList
<
T
>
*
p
=
nullptr
)
{
parent
=
p
;
};
InfoList
<
VarInfo
>
*
broader
;
InfoList
(
InfoList
<
T
>
*
p
=
nullptr
,
InfoList
<
VarInfo
>
*
b
=
nullptr
)
:
parent
(
p
),
broader
(
b
)
{};
TPtr
operator
[](
PIdent
*
ident
)
const
{
TPtr
ret
=
local
(
ident
->
string_
);
if
(
ret
)
return
ret
;
...
...
@@ -37,6 +36,9 @@ public:
}
void
add
(
TPtr
obj
)
{
if
(
broader
)
{
broader
->
add
(
obj
);
}
auto
ret
=
this
->
emplace
(
obj
);
if
(
!
ret
.
second
)
{
throw
RedefinedError
(
obj
->
ident
,
*
ret
.
first
);
...
...
Latte.cpp
View file @
5f84c1c3
...
...
@@ -69,7 +69,7 @@ int main(int argc, char ** argv)
TypeCheck
checker
;
checker
.
check
(
parse_tree
);
}
catch
(
ParseError
const
&
e
)
{
std
::
cerr
<<
e
.
what
()
<<
std
::
endl
;
std
::
cerr
<<
"Error: "
<<
e
.
what
()
<<
std
::
endl
;
return
1
;
}
std
::
cout
<<
"OK!"
<<
endl
;
...
...
ParseError.cpp
View file @
5f84c1c3
...
...
@@ -4,6 +4,31 @@
#include <sstream>
using
namespace
std
;
ParseError
::
ParseError
(
string
reason
,
int
line
)
:
runtime_error
(
"ParseError"
),
line
(
line
)
{
stringstream
ss
;
ss
<<
"ParseError"
;
if
(
line
!=
-
1
)
{
ss
<<
" at line "
<<
line
;
}
ss
<<
": "
<<
reason
;
msg
=
ss
.
str
();
}
ParseError
::
ParseError
(
string
reason
,
Visitable
*
expr
)
:
runtime_error
(
"ParseError"
)
{
stringstream
ss
;
ss
<<
"ParseError"
;
if
(
expr
)
{
line
=
expr
->
lineno
;
ss
<<
" at line "
<<
line
;
}
ss
<<
": "
<<
reason
;
if
(
expr
)
{
ss
<<
" Expression: "
<<
PrintAbsyn
().
print
(
expr
);
}
}
RedefinedError
::
RedefinedError
(
PIdent
*
ident
,
VarInfoPtr
orig
)
{
stringstream
ss
;
ss
<<
"Variable
\"
"
<<
ident
->
string_
<<
"
\"
at line "
<<
ident
->
lineno
<<
" redeclared! First declaration at line "
<<
orig
->
lineLocation
;
...
...
@@ -18,7 +43,6 @@ UndefinedError::UndefinedError(PIdent *ident) {
line
=
ident
->
lineno
;
}
InvalidTypeError
::
InvalidTypeError
(
Type
&
expected
,
vector
<
shared_ptr
<
Type
>>
received
,
Visitable
*
expr
)
{
stringstream
ss
;
ss
<<
"Invalid expression type at line "
<<
expr
->
lineno
<<
". Expected
\"
"
<<
expected
.
printName
()
<<
"
\"
, instead received "
;
...
...
@@ -36,5 +60,23 @@ InvalidTypeError::InvalidTypeError(Type &expected, vector<shared_ptr<Type>> rece
}
msg
=
ss
.
str
();
line
=
expr
->
lineno
;
}
}
\ No newline at end of file
InvalidTypeError
::
InvalidTypeError
(
Type
&
expected
,
vector
<
Type
*>
received
,
Visitable
*
expr
)
{
stringstream
ss
;
ss
<<
"Invalid expression type at line "
<<
expr
->
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
<<
" In: "
;
PrintAbsyn
p
;
ss
<<
p
.
print
(
expr
);
}
msg
=
ss
.
str
();
line
=
expr
->
lineno
;
}
ParseError.h
View file @
5f84c1c3
...
...
@@ -14,9 +14,10 @@ class ParseError : std::runtime_error {
protected:
string
msg
;
int
line
;
ParseError
()
:
runtime_error
(
"ParseError"
)
,
line
(
-
1
)
{}
ParseError
()
:
runtime_error
(
"ParseError"
)
{}
public:
ParseError
(
string
reason
,
int
line
=
-
1
)
:
runtime_error
(
"ParseError"
),
line
(
line
)
{}
ParseError
(
string
reason
,
int
line
=
-
1
);
ParseError
(
string
reason
,
Visitable
*
expr
);
virtual
const
char
*
what
()
const
_GLIBCXX_TXN_SAFE_DYN
_GLIBCXX_NOTHROW
{
return
msg
.
data
();
}
};
...
...
@@ -35,6 +36,7 @@ public:
class
InvalidTypeError
:
public
ParseError
{
public:
InvalidTypeError
(
Type
&
expected
,
vector
<
shared_ptr
<
Type
>>
received
,
Visitable
*
expr
=
NULL
);
InvalidTypeError
(
Type
&
expected
,
vector
<
Type
*>
received
,
Visitable
*
expr
=
NULL
);
};
#endif
\ No newline at end of file
Printer.cpp
View file @
5f84c1c3
...
...
@@ -103,6 +103,9 @@ PrintAbsyn::PrintAbsyn(void)
PrintAbsyn
::~
PrintAbsyn
(
void
)
{
if
(
buf_
)
{
free
(
buf_
);
}
}
char
*
PrintAbsyn
::
print
(
Visitable
*
v
)
...
...
TypeCheck.cpp
View file @
5f84c1c3
...
...
@@ -4,24 +4,29 @@
#include <iostream>
void
TypeCheck
::
visitClassDef
(
ClassDef
*
t
)
{
const
string
name
=
t
->
getName
()
->
string_
;
ClassInfoPtr
parent
=
NULL
;
BindingPtr
parent
;
if
(
t
->
getParent
())
{
parent
=
scope
.
classes
[
t
->
getParent
()];
parent
=
scope
->
classes
[
t
->
getParent
()];
if
(
!
parent
)
{
throw
UndefinedError
(
t
->
getParent
());
}
}
else
{
parent
=
scope
;
}
auto
c
=
make_shared
<
ClassInfo
>
(
t
->
getName
(),
parent
);
scope
.
classes
<<
c
;
scope
->
classes
<<
c
;
scope
.
currentClass
=
c
;
scope
->
currentBinding
=
scope
->
currentClass
=
c
;
t
->
getBlock
()
->
accept
(
this
);
scope
.
currentClass
=
NULL
;
scope
->
currentBinding
=
scope
->
currentClass
=
nullptr
;
}
void
TypeCheck
::
visitPIdent
(
PIdent
*
p_ident
)
{
visitString
(
p_ident
->
string_
);
// visitString(p_ident->string_);
auto
var
=
scope
->
currentBinding
->
variables
[
p_ident
];
p_ident
->
var
=
var
;
lastType
=
var
->
type
;
}
void
TypeCheck
::
visitProg
(
Prog
*
prog
)
...
...
@@ -50,12 +55,16 @@ void TypeCheck::visitClDef(ClDef *cl_def)
void
TypeCheck
::
visitFuncDef
(
FuncDef
*
def
)
{
FunctionInfoPtr
f
=
make_shared
<
FunctionInfo
>
(
def
,
scope
.
currentClass
);
FunctionInfoPtr
f
=
make_shared
<
FunctionInfo
>
(
def
,
scope
->
currentClass
);
def
->
type_
->
accept
(
this
);
def
->
pident_
->
accept
(
this
);
// FunctionInfo tworzy argumenty
def
->
listarg_
->
accept
(
this
);
auto
&
target
Vector
=
scope
.
currentClass
?
scope
.
currentClass
->
functions
:
scope
.
functions
;
target
Vector
<<
f
;
auto
&
target
=
scope
->
currentClass
?
scope
->
currentClass
->
functions
:
scope
->
functions
;
target
<<
f
;
}
void
TypeCheck
::
visitClassDefN
(
ClassDefN
*
class_def_n
)
...
...
@@ -84,12 +93,23 @@ void TypeCheck::visitClassMthd(ClassMthd *class_mthd)
}
void
TypeCheck
::
visitClassFld
(
ClassFld
*
class_fld
)
void
TypeCheck
::
visitClassFld
(
ClassFld
*
decl
)
{
/* Code For ClassFld Goes Here */
decl
->
type_
->
accept
(
this
);
decl
->
listitem_
->
accept
(
this
);
class_fld
->
type_
->
accept
(
this
);
class_fld
->
listitem_
->
accept
(
this
);
Type
*
type
=
decl
->
type_
;
for
(
Item
*
el
:
*
decl
->
listitem_
)
{
if
(
el
->
expr_
)
{
throw
ParseError
(
"Initialization in class variable definition"
,
decl
);
}
VarInfoPtr
var
=
make_shared
<
VarInfo
>
(
el
->
pident_
,
type
);
el
->
pident_
->
var
=
var
;
scope
->
currentClass
->
variables
<<
var
;
cout
<<
"class "
<<
scope
->
currentClass
<<
" adding ident "
<<
el
->
pident_
->
string_
<<
endl
;
}
}
...
...
@@ -97,15 +117,15 @@ void TypeCheck::visitBlk(Blk *blk)
{
BindingPtr
binding
=
blk
->
binding
.
lock
();
if
(
!
binding
)
{
binding
=
make_shared
<
Binding
>
(
scope
.
currentBinding
);
binding
=
make_shared
<
Binding
>
(
scope
->
currentBinding
);
blk
->
binding
=
binding
;
}
scope
.
currentBinding
=
binding
;
scope
->
currentBinding
=
binding
;
blk
->
liststmt_
->
accept
(
this
);
scope
.
currentBinding
=
binding
->
getParent
();
scope
->
currentBinding
=
binding
->
getParent
();
}
void
TypeCheck
::
visitBStmt
(
BStmt
*
b_stmt
)
...
...
@@ -118,11 +138,16 @@ void TypeCheck::visitDecl(Decl *decl)
Type
*
type
=
decl
->
type_
;
for
(
Item
*
el
:
*
decl
->
listitem_
)
{
el
->
expr_
->
accept
(
this
);
if
(
el
->
expr_
)
{
el
->
expr_
->
accept
(
this
);
if
(
*
type
!=
*
lastType
)
{
throw
InvalidTypeError
(
*
type
,
{
lastType
},
el
->
expr_
);
}
}
VarInfoPtr
var
=
make_shared
<
VarInfo
>
(
el
->
pident_
,
type
);
el
->
pident_
->
var
=
var
;
scope
.
currentBinding
->
variables
<<
var
;
scope
->
currentBinding
->
variables
<<
var
;
}
}
...
...
@@ -161,12 +186,12 @@ void TypeCheck::visitRet(Ret *ret)
{
/* Code For Ret Goes Here */
ret
->
expr_
->
accept
(
this
);
checkReturn
(
lastType
,
ret
);
checkReturn
Statement
(
lastType
,
ret
);
}
void
TypeCheck
::
visitVRet
(
VRet
*
v_ret
)
{
checkReturn
(
make_shared
<
Void
>
(),
v_ret
);
checkReturn
Statement
(
make_shared
<
Void
>
(),
v_ret
);
}
void
TypeCheck
::
visitCond
(
Cond
*
cond
)
...
...
@@ -221,71 +246,54 @@ void TypeCheck::visitWhile(While *while_)
void
TypeCheck
::
visitSExp
(
SExp
*
s_exp
)
{
/* Code For SExp Goes Here */
s_exp
->
expr_
->
accept
(
this
);
}
void
TypeCheck
::
visitForEach
(
ForEach
*
for_each
)
{
/* Code For ForEach Goes Here */
for_each
->
type_
->
accept
(
this
);
for_each
->
pident_
->
accept
(
this
);
BindingPtr
binding
=
make_shared
<
Binding
>
(
scope
->
currentBinding
);
Array
expect
(
for_each
->
type_
);
for_each
->
expr_
->
accept
(
this
);
if
(
*
lastType
!=
expect
)
{
throw
InvalidTypeError
(
expect
,
{
lastType
},
for_each
->
expr_
);
}
VarInfoPtr
var
=
make_shared
<
VarInfo
>
(
for_each
->
pident_
,
lastType
);
binding
->
variables
<<
var
;
scope
->
currentBinding
=
binding
;
for_each
->
stmt_
->
accept
(
this
);
scope
->
currentBinding
=
binding
->
getParent
();
}
void
TypeCheck
::
visitInt
(
Int
*
int_
)
{
/* Code For Int Goes Here */
}
{}
void
TypeCheck
::
visitStr
(
Str
*
str
)
{
/* Code For Str Goes Here */
}
{}
void
TypeCheck
::
visitBool
(
Bool
*
bool_
)
{
/* Code For Bool Goes Here */
}
{}
void
TypeCheck
::
visitVoid
(
Void
*
void_
)
{
/* Code For Void Goes Here */
}
{}
void
TypeCheck
::
visitArray
(
Array
*
array
)
{
/* Code For Array Goes Here */
array
->
binding
=
scope
->
currentBinding
;
array
->
type_
->
accept
(
this
);
}
void
TypeCheck
::
visitClassT
(
ClassT
*
class_t
)
{
/* Code For ClassT Goes Here */
class_t
->
binding
=
scope
->
currentBinding
;
scope
->
currentBinding
->
classes
[
class_t
->
pident_
];
class_t
->
pident_
->
accept
(
this
);
}
void
TypeCheck
::
visitFun
(
Fun
*
fun
)
{
/* Code For Fun Goes Here */
fun
->
type_
->
accept
(
this
);
fun
->
listtype_
->
accept
(
this
);
...
...
@@ -344,14 +352,7 @@ void TypeCheck::visitELitFalse(ELitFalse *e_lit_false)
void
TypeCheck
::
visitEString
(
EString
*
e
)
{
/* Code For EString Goes Here */
visitString
(
e
->
string_
);
auto
a
=
lastType
;
Str
expect
;
if
(
*
a
!=
expect
)
{
throw
InvalidTypeError
(
expect
,
{
a
},
e
);
}
lastType
=
make_shared
<
Str
>
();
}
...
...
@@ -383,49 +384,6 @@ void TypeCheck::visitNullCast(NullCast *null_cast)
}
// void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
// {
// /* Code For EClsMmbr Goes Here */
// e_cls_mmbr->expr_->accept(this);
// e_cls_mmbr->pident_->accept(this);
// }
// void TypeCheck::visitEClsMthd(EClsMthd *e_cls_mthd)
// {
// /* Code For EClsMthd Goes Here */
// e_cls_mthd->expr_->accept(this);
// e_cls_mthd->pident_->accept(this);
// e_cls_mthd->listexpr_->accept(this);
// }
// void TypeCheck::visitNull(Null *e)
// {
// PIdent *ident = new PIdent("null", e->lineno);
// lastType = make_shared<ClassT>(ident); // TODO
// }
// void TypeCheck::visitEIndexAcc(EIndexAcc *e_index_acc)
// {
// /* Code For EIndexAcc Goes Here */
// e_index_acc->pident_->accept(this);
// e_index_acc->expr_->accept(this);
// throw UndefinedError(e_index_acc->pident_); // TODO
// }
// void TypeCheck::visitECast(ECast *e_cast)
// {
// /* Code For ECast Goes Here */
// e_cast->pident_->accept(this);
// e_cast->expr_->accept(this);
// lastType = make_shared<ClassT>(e_cast->pident_);
// }
void
TypeCheck
::
visitNeg
(
Neg
*
e
)
{
e
->
expr_
->
accept
(
this
);
...
...
@@ -582,7 +540,7 @@ void TypeCheck::visitString(String x)
}
TypeCheck
::
TypeCheck
()
:
state
(
initialized
)
:
state
(
initialized
)
,
scope
(
make_shared
<
Scope
>
())
{
}
...
...
@@ -594,55 +552,63 @@ void TypeCheck::check(Visitable *v)
state
=
State
::
checkType
;
v
->
accept
(
this
);
for
(
auto
c
:
scope
.
classes
)
{
scope
.
currentClass
=
c
;
for
(
auto
c
:
scope
->
classes
)
{
scope
->
currentClass
=
c
;
for
(
auto
f
:
c
->
functions
)
{
checkFunction
(
f
);
}
scope
.
currentClass
=
nullptr
;
scope
->
currentClass
=
nullptr
;
}
for
(
auto
f
:
scope
.
functions
)
{
for
(
auto
f
:
scope
->
functions
)
{
checkFunction
(
f
);
}
}
void
TypeCheck
::
checkReturnStatement
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
)
{
lastType
=
returnType
=
type
;
if
(
*
type
!=
*
scope
->
currentFunction
->
type
)
{
throw
InvalidTypeError
(
*
scope
->
currentFunction
->
type
,
{
type
},
stmt
);
}
}
void
TypeCheck
::
checkFunction
(
FunctionInfoPtr
f
)
{
scope
.
currentFunction
=
f
;
scope
->
currentFunction
=
f
;
std
::
cout
<<
"checking fun "
<<
f
->
name
<<
" at line "
<<
f
->
lineLocation
<<
endl
;
if
(
f
->
binding
)
throw
runtime_error
(
"Ale ten binding juz istnieje"
)
;
BindingPtr
binding
=
make_shared
<
Binding
>
(
nullptr
);
BindingPtr
binding
=
make_shared
<
Binding
>
(
scope
->
currentClass
);
f
->
binding
=
binding
;
for
(
auto
arg
:
f
->
arguments
)
{
binding
->
variables
<<
arg
;
}
scope
->
currentBinding
=
binding
;
returnType
=
lastType
=
nullptr
;
f
->
block
->
accept
(
this
);
scope
->
currentBinding
=
nullptr
;
scope
->
currentFunction
=
nullptr
;
}
void
TypeCheck
::
checkFunctionRet
()
{
auto
&
f
=
scope
->
currentFunction
;
if
(
*
f
->
type
!=
Void
())
{
if
(
!
returnType
)
{
if
(
!
returnType
||
returnType
==
nullptr
)
{
throw
ParseError
(
"Funkcja nie zwróciła wyniku!"
,
f
->
lineLocation
);
}
if
(
*
returnType
!=
*
f
->
type
)
{
throw
InvalidTypeError
(
*
returnType
,
{
&*
f
->
type
},
f
->
block
);
throw
InvalidTypeError
(
*
returnType
,
{
f
->
type
},
f
->
block
);
}
}
else
{
if
(
returnType
&&
*
returnType
!=
*
f
->
type
)
{
throw
InvalidTypeError
(
*
returnType
,
{
&*
f
->
type
},
f
->
block
);
throw
InvalidTypeError
(
*
returnType
,
{
f
->
type
},
f
->
block
);
}
}
scope
.
currentFunction
=
nullptr
;
}
void
TypeCheck
::
checkReturn
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
)
{
lastType
=
returnType
=
type
;
if
(
*
type
!=
*
scope
.
currentFunction
->
type
)
{
throw
InvalidTypeError
(
*
scope
.
currentFunction
->
type
,
{
type
},
stmt
);
}
}
\ No newline at end of file
TypeCheck.h
View file @
5f84c1c3
...
...
@@ -15,11 +15,12 @@ class TypeCheck : public Visitor
checkType
}
state
;
Scope
scope
;
shared_ptr
<
Scope
>
scope
;
shared_ptr
<
Type
>
lastType
,
returnType
;
void
checkFunction
(
FunctionInfoPtr
f
);
void
checkReturn
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
);
void
checkReturnStatement
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
);
void
checkFunctionRet
();
public:
TypeCheck
();
void
check
(
Visitable
*
v
);
...
...
@@ -106,9 +107,9 @@ protected:
// stmts
void
visitEmpty
(
Empty
*
p
)
{};
void
visitNoInit
(
NoInit
*
p
)
{};
void
visitInit
(
Init
*
p
)
{};
void
visitAr
(
Ar
*
p
)
{};
void
visitNoInit
(
NoInit
*
p
)
{
};
void
visitInit
(
Init
*
p
)
{
};
void
visitAr
(
Ar
*
p
)
{
p
->
type_
->
accept
(
this
);
};
// exprs
void
visitPlus
(
Plus
*
p
)
{};
...
...
TypeDefs.h
View file @
5f84c1c3
...
...
@@ -14,6 +14,7 @@ using VarInfoPtr = shared_ptr<VarInfo>;
using
FunctionInfoPtr
=
shared_ptr
<
FunctionInfo
>
;
using
ClassInfoPtr
=
shared_ptr
<
ClassInfo
>
;
using
BindingPtr
=
shared_ptr
<
Binding
>
;
using
TypePtr
=
shared_ptr
<
Type
>
;
class
Visitable
;
...
...
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