-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
94 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,78 @@ | ||
from ast_exprs import Assignment, AstirExpr, Identifier, Lambda, Symbol # type: ignore | ||
from common import Cursor | ||
from ast_exprs import Assignment, AstirExpr, Identifier, Lambda, Literal, Reference, ShuntingYardAlgorithmResults, Symbol, SymbolTable # type: ignore | ||
from common import Cursor, PrimitiveTypes | ||
|
||
|
||
class ASM(Cursor): | ||
def __init__(self, input: list[AstirExpr]) -> None: | ||
def __init__( | ||
self, input: list[AstirExpr], symbol_tables: dict[int, SymbolTable] | ||
) -> None: | ||
super().__init__(input) | ||
self.lines: list[str] = [".global _start", ".p2align 3"] | ||
self.lines: list[str] = [".global main", ".p2align 3"] | ||
self.symbol_tables: dict[int, SymbolTable] = symbol_tables | ||
# Format (ref_id, register) | ||
self.ref_id_and_register: list[tuple[int, int]] = [] | ||
self.current_usable_register = 0 | ||
|
||
def generate(self) -> None: | ||
c_expr = self.current() | ||
def lookup_symbol(self, symbol_table: int, symbol_id: int) -> Symbol | None: | ||
if symbol_table not in self.symbol_tables: | ||
return None | ||
_symbol_table: SymbolTable | None = self.symbol_tables[symbol_table] | ||
if _symbol_table is None: | ||
return None | ||
symbol = _symbol_table.lookup_by_id(symbol_id) | ||
return symbol | ||
|
||
def generate(self, expr: AstirExpr | None = None) -> list[str]: | ||
c_expr = self.current() if expr is None else expr | ||
to_add: list[str] = [] | ||
if isinstance(c_expr, Assignment): | ||
if isinstance(c_expr.right, Lambda) and isinstance(c_expr.left, Identifier): | ||
lambda_def = c_expr.right.definition | ||
parameters_to_registers: dict[str, str] = {} | ||
last_reg = 0 | ||
for k in lambda_def.parameters.symbols.keys(): | ||
parameter = lambda_def.parameters.symbols.get(k) | ||
if parameter is None or not isinstance(parameter, Symbol): | ||
break | ||
elif parameter.name == "ret": | ||
continue | ||
parameters_to_registers[parameter.name] = f"X{last_reg}" | ||
last_reg += 1 | ||
# -1 to get rid of the return type. the length in the name may be temporary :) | ||
self.lines.append( | ||
f"{c_expr.left.value}_{len(lambda_def.parameters.symbols.keys())-1}:" | ||
to_add.append(f"{c_expr.left.value}:") | ||
print(f"Being added: {to_add}") | ||
generated_body = self.generate(c_expr.right.body) | ||
print(f"Generated body -> {generated_body}") | ||
to_add.extend(generated_body) | ||
to_add.append("ret") | ||
self.lines.extend(to_add) | ||
elif isinstance(c_expr, Reference): | ||
symbol = self.lookup_symbol(c_expr.belongs_to, c_expr.symbol_id) | ||
if symbol is None: | ||
raise Exception("failed to lookup symbol") | ||
if isinstance(symbol.val, Reference): | ||
symbol2 = self.lookup_symbol( | ||
symbol.val.belongs_to, symbol.val.symbol_id | ||
) | ||
pass | ||
return None | ||
register = self.current_usable_register | ||
self.ref_id_and_register.append((symbol.val.symbol_id, register)) | ||
to_add.append(f"x{register}") # Temp | ||
self.current_usable_register += 1 | ||
elif isinstance(c_expr, ShuntingYardAlgorithmResults): | ||
if len(c_expr.oeprators) > 0: | ||
raise Exception("Invalid shunting yard algorithm") | ||
stack: list[str] = [] | ||
c_expr.results.reverse() | ||
while len(c_expr.results) > 0 and (term := c_expr.results.pop()): | ||
# TODO: make some like class method or something | ||
# to make this cleaner?? | ||
if isinstance(term, Reference): | ||
stack.extend(self.generate(term)) | ||
elif isinstance(term, Literal): | ||
if term.ty != PrimitiveTypes.INT: | ||
raise Exception("Unexpected type.") | ||
stack.append(str(term.val)) | ||
elif isinstance(term, str): | ||
if term == "+": | ||
stack.reverse() | ||
(item1, item2) = (stack.pop(), stack.pop()) | ||
if not item1.startswith("x"): | ||
register = self.current_usable_register | ||
to_add.append(f"mov x{register}, {item1}") | ||
item1 = f"x{register}" | ||
self.current_usable_register += 1 | ||
print( | ||
f"Adding last two items on stack: {item1}, {item2} = {item1 + item2}" | ||
) | ||
to_add.append(f"add x0, {item1}, {item2}") | ||
|
||
print(f"{c_expr}") | ||
return to_add |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
take_int_and_add_2\ x int :: int → x + 2 | ||
|
||
main\ :: int → take_int_and_add_2 2 | ||
_start\ :: int → take_int_and_add_2 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,26 @@ | ||
// Assembler program to print "Hello World!" | ||
// to stdout. | ||
// | ||
// X0-X2 - parameters to linux function services | ||
// X16 - linux function number | ||
// | ||
.global _start // Provide program starting address to linker | ||
.global _start | ||
.p2align 3 | ||
|
||
_return_int: | ||
add X1, X0, 2 | ||
mov X0, X1 | ||
add X0, X0, 2 | ||
|
||
ret | ||
|
||
_start: | ||
mov X0, 2 | ||
bl _return_int // This take the 2 from X0 and adds 2 to it | ||
cmp X0, 4 // We want to check if the rseult from _return_in | ||
// is eq to 4 | ||
bl _return_int | ||
cmp X0, 4 | ||
b.eq print_hello_world | ||
|
||
mov X0, #0 // Use 0 return code | ||
mov X16, #1 // Service command code 1 terminates this program | ||
svc 0 // Call MacOS to terminate the program | ||
mov X0, #0 | ||
mov X16, #1 | ||
svc 0 | ||
|
||
// Setup the parameters to print hello world | ||
// and then call Linux to do it. | ||
print_hello_world: mov X0, #1 // 1 = StdOut | ||
adr X1, helloworld // string to print | ||
mov X2, #13 // length of our string | ||
mov X16, #4 // MacOS write system call | ||
svc 0 // Call linux to output the string | ||
print_hello_world: mov X0, #1 | ||
adr X1, helloworld | ||
mov X2, #13 | ||
mov X16, #4 | ||
svc 0 | ||
ret | ||
|
||
; print_goodbye: mov X0, #1 // 1 = StdOut | ||
; adr X1, goodbyeworld // string to print | ||
; mov X2, #13 // length of our string | ||
; mov X16, #4 // MacOS write system call | ||
; svc 0 // Call linux to output the string | ||
; ret | ||
|
||
; _start: MOV X10, 1 | ||
; MOV X11, 4 | ||
; MOV X12, helloworld | ||
; MOV X13, goodbyeworld | ||
; ADD X9, X10, X11 | ||
; CMP X9, 3 | ||
; csel X12, X14, X13, EQ | ||
|
||
; ; B.EQ print_hello_world | ||
; ; B.NE print_goodbye | ||
|
||
; mov X0, #1 // 1 = StdOut | ||
; adr X1, X14 // string to print` | ||
; mov X2, #13 // length of our string | ||
; mov X16, #4 // MacOS write system call | ||
; svc 0 // Call linux to output the string | ||
/* | ||
mov X0, #1 // 1 = StdOut | ||
adr X1, 123 // string to print | ||
mov X2, #3 // length of our string | ||
mov X16, #4 // MacOS write system call | ||
svc 0 // Call linux to output the string | ||
*/ | ||
// Setup the parameters to exit the program | ||
// and then call Linux to do it. | ||
|
||
helloworld: .ascii "Hello World!\n" // 13 |