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