Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cs444
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Xun Yang
cs444
Commits
59ff3526
Commit
59ff3526
authored
5 years ago
by
pycsham
Browse files
Options
Downloads
Plain Diff
Merge branch 'master' of
https://git.uwaterloo.ca/x299yang/cs444
parents
9501b41b
f43e96ab
No related branches found
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
.gitignore
+1
-0
1 addition, 0 deletions
.gitignore
AstBuilding.py
+11
-7
11 additions, 7 deletions
AstBuilding.py
Test.py
+12
-5
12 additions, 5 deletions
Test.py
TypeNodes.py
+22
-17
22 additions, 17 deletions
TypeNodes.py
testAssemble.sh
+42
-0
42 additions, 0 deletions
testAssemble.sh
with
88 additions
and
29 deletions
.gitignore
+
1
−
0
View file @
59ff3526
...
...
@@ -3,3 +3,4 @@ __pycache__/
ErrorTest.py
Test.py
*.zip
output/
This diff is collapsed.
Click to expand it.
AstBuilding.py
+
11
−
7
View file @
59ff3526
from
CompNode
import
CompNode
from
pprint
import
pprint
from
Environment
import
GlobalEnv
from
CodeGenUtils
import
p
,
genProcedure
from
CodeGenUtils
import
p
,
genProcedure
,
used_labels
,
local_labels
# tree: (filename, parseTree)
def
astBuild
(
trees
):
...
...
@@ -57,26 +57,30 @@ def reachabilityChecking(ASTs):
t
[
1
].
reachCheck
()
####################################################
def
codeGen
(
ASTs
):
def
codeGen
(
ASTs
,
output
=
"
output
"
):
for
t
in
ASTs
:
t
[
1
].
codeGen
()
# Outputting the generated code into className.s
# Outputting the generated code into className.s
# Note: Interfaces do not generate any code
for
t
in
ASTs
:
classInterNode
=
t
[
1
].
typeDcl
if
classInterNode
and
classInterNode
.
__class__
.
__name__
==
"
ClassNode
"
:
fileName
=
"
output/
"
+
classInterNode
.
name
+
"
.s
"
fileName
=
output
+
"
/
"
+
classInterNode
.
name
+
"
.s
"
f
=
open
(
fileName
,
"
w
"
)
f
.
write
(
classInterNode
.
code
)
f
.
close
()
# ASTs[0][1].codeGen()
startGen
(
ASTs
[
0
][
1
])
# pass in the first AST that contains the test method
startGen
(
ASTs
[
0
][
1
]
,
output
)
# pass in the first AST that contains the test method
def
startGen
(
ast
):
# reset lables for running multiple testCases
used_labels
=
set
()
local_labels
=
0
def
startGen
(
ast
,
output
):
className
=
ast
.
typeDcl
.
name
method_label
=
"
M_
"
+
className
+
"
_test_None
"
f
=
open
(
"
output/RunTest.s
"
,
"
w
"
)
f
=
open
(
output
+
"
/RunTest.s
"
,
"
w
"
)
result
=
"
global _start
\n
_start:
\n
"
\
+
p
(
"
extern
"
,
method_label
,
None
,
None
)
\
...
...
This diff is collapsed.
Click to expand it.
Test.py
+
12
−
5
View file @
59ff3526
import
sys
import
time
from
os
import
listdir
,
scandir
,
walk
from
os.path
import
isfile
,
join
from
os
import
listdir
,
scandir
,
walk
,
makedirs
from
os.path
import
isfile
,
join
,
exists
from
shutil
import
rmtree
,
copyfile
import
traceback
from
Scanning
import
scan
...
...
@@ -45,7 +46,13 @@ def a2Multiple():
testFiles
=
[
join
(
dp
,
f
)
for
dp
,
dn
,
filenames
in
walk
(
c
)
for
f
in
filenames
]
+
testFiles
ret
=
run
(
testFiles
)
testOutput
=
"
output/
"
+
c
.
split
(
"
/
"
)[
-
1
]
if
exists
(
testOutput
):
rmtree
(
testOutput
)
makedirs
(
testOutput
)
copyfile
(
'
stdlib/5.0/runtime.s
'
,
testOutput
+
"
/runtime.s
"
)
ret
=
run
(
testFiles
,
testOutput
)
total
+=
1
if
ret
==
""
:
...
...
@@ -67,7 +74,7 @@ def a2Multiple():
print
(
"
\n
Time Elapsed: {}
"
.
format
(
time
.
strftime
(
'
%H:%M:%S
'
,
time
.
gmtime
(
end
-
start
))))
print
(
"
SCORE: {} / {} -> {:.3g}%
"
.
format
(
correct
,
total
,
(
correct
/
total
)
*
100
))
def
run
(
testFiles
):
def
run
(
testFiles
,
testOutput
):
parseTrees
=
[]
for
f
in
testFiles
:
...
...
@@ -140,7 +147,7 @@ def run(testFiles):
except
Exception
as
e
:
return
"
reachabilityChecking:
"
+
e
.
args
[
0
]
try
:
codeGen
(
ASTs
)
codeGen
(
ASTs
,
testOutput
)
except
Exception
as
e
:
return
"
code generation:
"
+
e
.
args
[
0
]
...
...
This diff is collapsed.
Click to expand it.
TypeNodes.py
+
22
−
17
View file @
59ff3526
...
...
@@ -165,7 +165,7 @@ class ClassNode(ClassInterNode):
self
.
label
=
""
# label in assembly
self
.
methodOffset
=
{}
# a dictionary that maps method signatures (method.name, method.paramTypes) to offsets in the CLASS memory layout
self
.
fieldOffset
=
{}
# a dictionary that maps field names to offsets in OBJECT memory layout
self
.
staticFieldLabels
=
[]
# a list of static field labels
self
.
staticFieldLabels
=
[]
# a list of static field labels
for
node
in
parseTree
.
children
:
if
node
.
name
==
'
classMod
'
:
...
...
@@ -257,7 +257,12 @@ class ClassNode(ClassInterNode):
# overlapping class/interface logic
super
().
checkHierarchy
()
# point superClass to java.lang.Object after hierarchy checking is done
if
self
.
canonName
!=
'
java.lang.Object
'
and
not
self
.
superClass
:
self
.
superClass
=
self
.
env
.
getNode
(
'
java.lang.Object
'
,
'
type
'
)
def
checkType
(
self
):
super
().
checkType
()
...
...
@@ -278,19 +283,19 @@ class ClassNode(ClassInterNode):
self
.
label
=
pLabel
(
name
=
self
.
name
,
type
=
"
class
"
)
self
.
code
+=
"
;START OF CLASS MEMORY LAYOUT FOR CLASS:
"
+
self
.
canonName
+
"
\n
"
self
.
code
+=
self
.
label
# TODO: SIT and subtype testing tables
####### ADDING METHODS TO CLASS MEMORY LAYOUT AND FIELDS TO FIELD OFFSET TABLE #########
# 1.
# a) Copying over the offsets of methods from superclass and DECLARING memory segment for the methods
# 1.
# a) Copying over the offsets of methods from superclass and DECLARING memory segment for the methods
# b) copying over the offsets of fields from superclass (TO BE USED LATER FOR OBJECT MEMORY LAYOUT)
lastMethodOffset
=
-
4
# stores the largest method offset in the superCalss
lastMethodOffset
=
-
4
# stores the largest method offset in the superCalss
# TODO: set this to 4 after the implemntation of both the SIT and subtype testing table
# Note: This is 4 less than the offset of where the next method would be located
# This is to accomodate for the addition of 4 to lastMethodOffset in EVERY (including the first) iteration in the
# This is to accomodate for the addition of 4 to lastMethodOffset in EVERY (including the first) iteration in the
# loops that loops through self.constructors and self.methods, in the case where there is no superClass
lastFieldOffset
=
0
lastFieldOffset
=
0
if
self
.
superClass
:
if
not
hasattr
(
self
.
superClass
,
"
code
"
):
...
...
@@ -301,20 +306,20 @@ class ClassNode(ClassInterNode):
self
.
code
+=
pLabel
(
name
=
self
.
name
+
"
_
"
+
key
[
0
]
+
"
_
"
+
key
[
1
],
type
=
"
vtable
"
)
self
.
code
+=
p
(
instruction
=
"
dd
"
,
arg1
=
64
)
# just declaring a memory segment with a random number
lastMethodOffset
=
max
(
value
,
lastMethodOffset
)
# Iterating through field offset table sorted by offset
for
key
,
value
in
self
.
superClass
.
fieldOffset
.
items
():
self
.
fieldOffset
[
key
]
=
value
lastFieldOffset
=
max
(
value
,
lastFieldOffset
)
# 2. Assigning offsets to constructors and DECLARING memory segment for the methods
# 2. Assigning offsets to constructors and DECLARING memory segment for the methods
for
method
in
self
.
constructors
:
lastMethodOffset
+=
4
self
.
methodOffset
[(
method
.
name
,
method
.
paramTypes
)]
=
lastMethodOffset
self
.
code
+=
pLabel
(
name
=
self
.
name
+
"
_
"
+
method
.
name
+
"
_
"
+
method
.
paramTypes
,
type
=
"
vtable
"
)
self
.
code
+=
p
(
instruction
=
"
dd
"
,
arg1
=
64
)
# just declaring a memory segment with a random number
# 3. Assigning offsets to methods that aren't in the super class DECLARING memory segment for the methods
# 3. Assigning offsets to methods that aren't in the super class DECLARING memory segment for the methods
for
method
in
self
.
methods
:
if
not
(
method
.
name
,
method
.
paramTypes
)
in
self
.
methodOffset
:
lastMethodOffset
+=
4
...
...
@@ -324,13 +329,13 @@ class ClassNode(ClassInterNode):
# print(self.methodOffset)
self
.
code
+=
"
;END OF CLASS MEMORY LAYOUT FOR CLASS
"
+
self
.
name
+
"
\n
"
# 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations
# 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations
for
key
,
value
in
self
.
methodOffset
.
items
():
vLabel
=
"
V_
"
+
self
.
name
+
"
_
"
+
key
[
0
]
+
"
_
"
+
key
[
1
]
+
""
# method at class's vtable
mLabel
=
"
M_
"
+
self
.
name
+
"
_
"
+
key
[
0
]
+
"
_
"
+
key
[
1
]
# method implementation
self
.
code
+=
p
(
instruction
=
"
mov
"
,
arg1
=
"
eax
"
,
arg2
=
vLabel
,
comment
=
"
Filling in class memory segment for method
"
+
mLabel
)
self
.
code
+=
p
(
instruction
=
"
mov
"
,
arg1
=
"
[eax]
"
,
arg2
=
mLabel
)
#5. Adding in fields that are not inherited from parent class to offset table
# Note: excluding static fields
for
field
in
self
.
fields
:
...
...
@@ -339,7 +344,7 @@ class ClassNode(ClassInterNode):
self
.
fieldOffset
[
field
.
name
]
=
lastFieldOffset
# print(self.name)
# print(self.fieldOffset)
# print(self.code)
###########################################################
...
...
@@ -350,7 +355,7 @@ class ClassNode(ClassInterNode):
if
c
and
hasattr
(
c
,
"
codeGen
"
):
if
not
hasattr
(
c
,
"
code
"
):
# children hasn't generated code yet
c
.
codeGen
()
self
.
code
+=
c
.
code
self
.
code
+=
c
.
code
#####################################################################
...
...
This diff is collapsed.
Click to expand it.
testAssemble.sh
0 → 100644
+
42
−
0
View file @
59ff3526
#!/bin/bash
# can supply folder name as argument to run 1 test test case
# run one case: ./testAssemble.sh J1_00_Step0.java
# run all cases: ./testAssemble.sh
cd
output
if
[
"$#"
-eq
0
]
;
then
# assemble and link and output results of running each test case
for
d
in
./
*
/
;
do
cd
$d
echo
"-----------------------------------"
echo
"Run generated code for "
+
$d
for
filename
in
./
*
.s
;
do
/u/cs444/bin/nasm
-O1
-f
elf
-g
-F
dwarf
$filename
done
ld
-melf_i386
-o
main ./
*
.o
# run main
./main
# echo the exit code
echo
$?
echo
"-----------------------------------"
cd
..
done
else
cd
$1
for
filename
in
./
*
.s
;
do
/u/cs444/bin/nasm
-O1
-f
elf
-g
-F
dwarf
$filename
done
ld
-melf_i386
-o
main ./
*
.o
# run main
./main
# echo the exit code
echo
$?
fi
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment