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
aafb3bcc
Commit
aafb3bcc
authored
Jan 14, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP virtual classes
parent
deb3fc4d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
71 additions
and
33 deletions
+71
-33
Absyn.cpp
src/Absyn.cpp
+1
-1
Compiler.cpp
src/Compiler.cpp
+29
-19
Compiler.h
src/Compiler.h
+13
-0
Info.cpp
src/Info.cpp
+1
-1
Info.h
src/Info.h
+3
-0
TypeCheck.cpp
src/TypeCheck.cpp
+2
-1
Quadruple.h
src/codeGen/Quadruple.h
+2
-2
QuadrupleGenerator.cpp
src/codeGen/QuadrupleGenerator.cpp
+18
-9
Variable.h
src/codeGen/Variable.h
+2
-0
No files found.
src/Absyn.cpp
View file @
aafb3bcc
...
...
@@ -2898,7 +2898,7 @@ bool Fun::isEqual(Type const *other, bool sub) const {
return
false
;
}
for
(
unsigned
int
i
=
0
;
i
<
listtype_
->
size
();
i
++
)
{
if
(
!
casted
->
listtype_
->
at
(
i
)
->
isEqual
(
listtype_
->
at
(
i
),
true
))
{
if
(
!
listtype_
->
at
(
i
)
->
isEqual
(
casted
->
listtype_
->
at
(
i
),
true
))
{
return
false
;
}
}
...
...
src/Compiler.cpp
View file @
aafb3bcc
...
...
@@ -182,8 +182,8 @@ void Compiler::printFunction(const QuadrupleGenerator::Result& quadEnv, const Fu
void
Compiler
::
genVirtTables
()
{
for
(
const
auto
&
c
:
scope
->
classes
)
{
if
(
!
c
->
functionCount
)
continue
;
buf
<<
quoted
(
getVirtName
(
c
))
<<
":
\n
"
;
if
(
!
c
->
functionCount
)
continue
;
vector
<
string
>
names
(
c
->
functionCount
,
""
);
auto
p
=
c
;
while
(
p
)
{
...
...
@@ -241,7 +241,8 @@ string Compiler::getRef(const VariablePtr &v) {
}
void
Compiler
::
generateQAlloc
(
QAlloc
&
q
)
{
if
(
!
q
.
aliveAfter
.
count
(
q
.
loc
))
{
return
;
}
if
(
!
q
.
aliveAfter
.
count
(
q
.
loc
)
&&
!
q
.
loc
->
isInstanceVariable
())
{
return
;
}
// jesli zaden nie rejestr to obliczyc adres do eax
// int len, size_t size, void* virtTab
auto
saveRegs
=
registersToSave
(
q
);
for
(
auto
r
:
saveRegs
)
{
...
...
@@ -255,11 +256,12 @@ void Compiler::generateQAlloc(QAlloc &q) {
append
(
"PUSHL"
,
"$"
+
quote
(
q
.
virtSymbol
));
}
append
(
"PUSHL"
,
"$"
+
to_string
(
q
.
size
));
if
(
q
.
count
)
{
append
(
"PUSHL"
,
getRef
(
q
.
count
));
}
append
(
"PUSHL"
,
"$"
+
to_string
(
q
.
size
));
append
(
"CALL"
,
q
.
count
?
"__latte_mem_init_array"
:
"__latte_mem_init"
);
append
(
"ADDL"
,
"$"
+
to_string
(
q
.
count
?
12
:
8
),
"%esp"
);
...
...
@@ -273,12 +275,12 @@ void Compiler::generateQAlloc(QAlloc &q) {
void
Compiler
::
generateQWrite
(
QWrite
&
q
)
{
// memory = extension
throw
runtime_error
(
"Memory write unimplemented!"
);
append
(
"MOVL"
,
getRef
(
q
.
val
),
getRef
(
q
.
loc
)
);
}
void
Compiler
::
generateQAccess
(
QAccess
&
q
)
{
// memory = extension
throw
runtime_error
(
"Memory access unimplemented!"
);
append
(
"MOVL"
,
getRef
(
q
.
access
),
getRef
(
q
.
loc
)
);
}
void
Compiler
::
generateQReturn
(
QReturn
&
q
)
{
...
...
@@ -290,11 +292,18 @@ void Compiler::generateQReturn(QReturn &q) {
void
Compiler
::
generateQCall
(
QCall
&
q
)
{
if
(
q
.
self
)
{
throw
runtime_error
(
"Class call unimplemented!"
);
auto
tg
=
Register
(
q
.
self
);
auto
eax
=
Register
(
0
);
if
(
tg
==
0
)
{
append
(
"MOVL"
,
getRef
(
q
.
self
),
tg
);
}
append
(
"MOVL"
,
"("
+
(
string
)
tg
+
")"
,
eax
);
// eax := virt table's address
append
(
"CALL"
,
"*"
+
to_string
(
q
.
fn
->
offset
*
4
)
+
"(%eax)"
);
// get proper function from virt table
}
else
{
append
(
"CALL"
,
quote
(
mangleFunctionName
(
q
.
fn
)));
}
append
(
"CALL"
,
quote
(
mangleFunctionName
(
q
.
fn
)));
if
(
q
.
params
)
{
append
(
"ADDL"
,
"$"
+
to_string
(
q
.
params
*
4
),
"%esp"
);
append
(
"ADDL"
,
"$"
+
to_string
(
q
.
params
*
4
+
(
q
.
self
?
4
:
0
)
),
"%esp"
);
}
auto
popRegs
=
registersToSave
(
q
);
for
(
auto
r
=
popRegs
.
rbegin
();
r
!=
popRegs
.
rend
();
r
++
)
{
...
...
@@ -307,8 +316,18 @@ void Compiler::generateQCall(QCall &q) {
}
void
Compiler
::
generateQParam
(
QParam
&
q
)
{
// return Quadruple::generateAsm();
if
(
q
.
num
<
0
)
{
if
(
q
.
call
)
{
assert
(
q
.
num
>=
0
);
if
(
q
.
num
==
1
)
{
// first argument, need to save registers
for
(
auto
r
:
registersToSave
(
*
q
.
call
))
{
if
(
r
!=
Register
(
q
.
call
->
loc
))
append
(
"PUSHL"
,
r
);
}
}
append
(
"PUSHL"
,
getRef
(
q
.
param
));
}
else
{
assert
(
q
.
num
<=
0
);
auto
reg
=
Register
(
q
.
param
);
auto
offset
=
4
*
(
q
.
num
-
Register
::
calleeSaved
.
size
()
-
1
);
// push regs + ebp
if
(
reg
==
0
)
{
...
...
@@ -317,15 +336,6 @@ void Compiler::generateQParam(QParam &q) {
}
else
{
append
(
"MOVL"
,
to_string
(
-
offset
)
+
"(%ebp)"
,
reg
);
}
}
else
{
if
(
q
.
num
==
1
&&
q
.
call
)
{
// first argument, need to save registers
for
(
auto
r
:
registersToSave
(
*
q
.
call
))
{
if
(
r
!=
Register
(
q
.
call
->
loc
))
append
(
"PUSHL"
,
r
);
}
}
append
(
"PUSHL"
,
getRef
(
q
.
param
));
}
}
...
...
src/Compiler.h
View file @
aafb3bcc
...
...
@@ -91,6 +91,19 @@ private:
void
genVirtTables
();
string
getRef
(
const
VariablePtr
&
v
);
string
getRef
(
const
VariableLocation
&
loc
)
{
int
offset
=
loc
.
offset
;
if
(
loc
.
index
)
{
if
(
loc
.
index
->
constExpr
)
{
offset
+=
loc
.
index
->
val
*
loc
.
multiplier
;
}
else
{
auto
ret
=
to_string
(
offset
)
+
"("
+
getRef
(
loc
.
base
)
+
","
+
getRef
(
loc
.
index
);
if
(
loc
.
multiplier
!=
1
)
ret
+=
","
+
to_string
(
loc
.
multiplier
);
return
ret
+
")"
;
}
}
return
to_string
(
offset
)
+
"("
+
getRef
(
loc
.
base
)
+
")"
;
}
void
generatePhiXCHG
(
const
map
<
VariablePtr
,
VariablePtr
>
&
varMap
);
static
string
getOpName
(
Quadruple
::
Op
op
)
{
...
...
src/Info.cpp
View file @
aafb3bcc
...
...
@@ -55,7 +55,7 @@ size_t ClassInfo::calculateSize() {
if
(
auto
pv
=
parent
->
functions
.
find
(
f
->
name
))
{
// verify types
if
(
!
f
->
type
->
isEqual
(
pv
->
type
,
true
))
{
throw
InvalidTypeError
(
*
f
->
type
,
{
pv
->
type
},
f
->
ident
);
throw
InvalidTypeError
(
*
pv
->
type
,
{
f
->
type
},
f
->
ident
);
}
f
->
offset
=
pv
->
offset
;
continue
;
...
...
src/Info.h
View file @
aafb3bcc
...
...
@@ -43,11 +43,14 @@ public:
vector
<
VarInfoPtr
>
arguments
;
weak_ptr
<
ClassInfo
>
klass
;
weak_ptr
<
Binding
>
binding
;
VarInfoPtr
self
;
FunctionInfo
(
FuncDef
*
expr
,
ClassInfoPtr
klass
=
nullptr
);
FunctionInfo
(
string
name
,
TypePtr
type
)
:
VarInfo
(
name
,
type
),
block
(
nullptr
)
{};
// FunctionInfo(PIdent *ident, ClassInfoPtr klass = nullptr) : VarInfo(ident), block(NULL), klass(klass) {};
virtual
string
kind
()
const
{
return
"function"
;
}
ClassInfoPtr
getClass
()
const
{
return
klass
.
lock
();
}
BindingPtr
getBinding
()
const
{
return
binding
.
lock
();
}
};
...
...
src/TypeCheck.cpp
View file @
aafb3bcc
...
...
@@ -661,7 +661,8 @@ void TypeCheck::checkFunction(FunctionInfoPtr f)
BindingPtr
binding
=
make_shared
<
Binding
>
(
getParentBinding
());
f
->
binding
=
binding
;
if
(
scope
->
currentClass
)
{
binding
->
variables
<<
make_shared
<
VarInfo
>
(
"self"
,
scope
->
currentClass
->
type
);
f
->
self
=
make_shared
<
VarInfo
>
(
"self"
,
scope
->
currentClass
->
type
);
binding
->
variables
<<
f
->
self
;
}
for
(
auto
arg
:
f
->
arguments
)
{
...
...
src/codeGen/Quadruple.h
View file @
aafb3bcc
...
...
@@ -202,13 +202,13 @@ public:
vector
<
VariablePtr
>
vars
()
const
override
{
auto
ret
=
Quadruple
::
vars
();
if
(
param
&&
num
>=
0
)
ret
.
emplace_back
(
param
);
if
(
param
&&
call
)
ret
.
emplace_back
(
param
);
return
ret
;
}
vector
<
VariablePtr
>
definitions
()
const
override
{
auto
ret
=
Quadruple
::
definitions
();
if
(
param
&&
num
<
0
)
ret
.
emplace_back
(
param
);
if
(
param
&&
!
call
)
ret
.
emplace_back
(
param
);
return
ret
;
};
void
generateAsm
(
Compiler
&
c
)
override
;
...
...
src/codeGen/QuadrupleGenerator.cpp
View file @
aafb3bcc
...
...
@@ -17,6 +17,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
addQuad
(
make_shared
<
QParam
>
(
var
,
-
param
));
param
++
;
}
if
(
VarInfoPtr
self
=
f
->
self
){
auto
var
=
alloc
(
self
);
addQuad
(
make_shared
<
QParam
>
(
var
,
-
param
));
}
}
f
->
block
->
accept
(
this
);
...
...
@@ -104,6 +108,11 @@ VariableLayout QuadrupleGenerator::captureEnv() {
void
QuadrupleGenerator
::
visitEVar
(
EVar
*
p
)
{
auto
var
=
p
->
pident_
->
var
.
lock
();
lastVar
=
alloc
(
var
);
if
(
var
->
isInstanceVariable
())
{
auto
fn
=
scope
->
currentFunction
;
auto
self
=
fn
->
self
;
addQuad
<
QAccess
>
(
lastVar
,
alloc
(
self
),
nullptr
,
0
,
(
int
)
var
->
offset
);
}
Bool
b
;
if
(
var
->
type
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
...
...
@@ -312,16 +321,16 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) {
}
if
(
type
->
type_
->
size
()
>
4
)
{
// calculate quantifier, we multiply index because size is larger than 4
auto
q
=
alloc
(
type
->
type_
->
size
()
/
4
);
// calculate var = index * quantifier
addQuad
<
QAssign
>
(
lastVar
,
index
,
Op
::
Mul
,
q
);
auto
q
=
alloc
(
type
->
type_
->
size
());
// allocate new lastVar, index is now calculated multiplied index
index
=
alloc
();
swap
(
index
,
lastVar
);
auto
newIndex
=
alloc
();
// calculate var = index * quantifier
addQuad
<
QAssign
>
(
newIndex
,
index
,
Op
::
Mul
,
q
);
addQuad
<
QAccess
>
(
lastVar
,
lhs
,
newIndex
,
1
,
0
);
}
else
{
addQuad
<
QAccess
>
(
lastVar
,
lhs
,
index
,
type
->
type_
->
size
(),
0
);
}
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
addQuad
(
quad
);
Bool
b
;
if
(
type
->
type_
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
...
...
@@ -338,7 +347,7 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
size_t
offset
=
var
->
offset
;
if
(
dynamic_cast
<
EIndexAcc
*>
(
p
->
expr_
))
{
// opt if EIndexAcc is used inside visitEClsMmbr
auto
access
=
dynamic_pointer_cast
<
QAccess
>
(
block
->
quads
.
back
()
);
auto
access
=
dynamic_pointer_cast
<
QAccess
>
(
lastQuad
);
access
->
access
.
offset
+=
offset
;
l
->
info
=
var
;
lastVar
=
l
;
...
...
src/codeGen/Variable.h
View file @
aafb3bcc
...
...
@@ -24,6 +24,8 @@ public:
std
::
string
name
;
int
registerColor
=
0
;
bool
isInstanceVariable
()
const
{
return
info
&&
info
->
isInstanceVariable
();
}
vector
<
QuadruplePtr
>
uses
;
vector
<
QuadruplePtr
>
writes
;
...
...
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