Skip to content

Commit

Permalink
Make the input file a command-line argument
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Oct 18, 2020
1 parent b2742a6 commit 911ff5d
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 33 deletions.
8 changes: 6 additions & 2 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## This is documentation for my Lisp compiler that targets the x86-64 architecture.

### Effeciency:
### Efficiency:
- I have not had the chance to compare my output's speed compared to C.
- However, I have noticed that for many examples, the line length of the output assembly code size produced is around half of Clang's. That may be a good sign!

Expand All @@ -16,6 +16,8 @@
- It may be hard to follow the flow control looking at the outputted `.asm` file (as assembly flow control is essentially glorified `goto`s) but it has been tested exhaustively. Do not worry!)
### `include`
- Imports a file from the relative path of the importer.
### `macro`
- Declares an unhygenic macro. Its form is parallel to `define`, like this: `macro (add a b c) (+ a b c))`

### Built-in procedures:
#### Operators, two arguments:
Expand All @@ -24,5 +26,7 @@
- `not`
#### Eventual features:
- I'll get to division and floating-point arithmetic sometime soon.
- The same goes for symbols and lists.
- If I have time I would like to implement a pattern-matching system and an ability to call C functions.
#### Impure procedures:
- `display`, `newline`
- `display`, `newline`
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LINK = $(LINK_WITH) -o out/$(OUT) tests/$(OUT).asm
CFLAGS = -O0 -mstackrealign -masm=intel $(LINK)

all: # compiler + assembler
python3 src/compiler.py
python3 src/compiler.py test.lisp debug
make build # must go after running the compiler
build: # assembler
$(CC) $(CFLAGS)
Expand Down
40 changes: 32 additions & 8 deletions src/compiler.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import parser
from procedures import *
import re
from re import compile as regex
from copy import copy
from sys import argv

special_forms = "define", "lambda", "if", "include"
special_forms = "define", "macro", "lambda", "if", "include"
builtin_procs = "display", "newline"
branch_id = 0
number_pattern = regex("^-?\d*(\.\d+)?$")
global_vars = []
number_pattern = re.compile("^-?\d*(\.\d+)?$")
macros = {}

def expand_macro(macro, param_arg_map):
for index, item in enumerate(macro):
if isinstance(item, list):
macro[index] = expand_macro(item, param_arg_map)
elif item in param_arg_map:
macro[index] = param_arg_map[item]
return macro

def check_for_unbound_vars(ast):
for node in ast[1:]:
Expand Down Expand Up @@ -64,6 +75,10 @@ def make_branch(sexpr, b_type, b_id):
for sexpr in parser.tokenize_file("tests/" + sexpr[1]):
eval_lisp(parser.parse(sexpr), program, eval_proc = True)

elif form == "macro":
name, args, body = sexpr[1][0], sexpr[1][1:], sexpr[2]
macros[name] = args, body

def define_proc(sexpr, program, has_caller = False):
name, params, body = sexpr
make_procedure(name, params)
Expand Down Expand Up @@ -92,6 +107,11 @@ def eval_lisp(sexpr, program, has_caller = False, eval_proc = False, compiling_i
eval_special_form(sexpr, program, has_caller)
return

elif procedure in macros:
macro = macros[procedure]
eval_lisp(expand_macro(macro[1], dict(zip(macro[0], sexpr[1:]))), program, has_caller)
return

check_for_unbound_vars(sexpr)

proc_obj = procedures[procedure]
Expand Down Expand Up @@ -124,7 +144,14 @@ def main(infile, outfile):
program.export(outfile)

if __name__ == "__main__":
main("tests/test.lisp", "tests/test.asm")
try:
infile = argv[1]
outfile = infile.rstrip("lisp") + "asm"
if len(argv) >= 3 and argv[2] == "debug":
infile = "tests/" + infile; outfile = "tests/" + outfile
main(infile, outfile)
except IndexError:
print("Please provide a filename.")

"""
Bugs:
Expand All @@ -138,8 +165,5 @@ def main(infile, outfile):
cond
case
curses bindings
Test:
Recursion, specifically factorial
Recursion works!!!
I just added macros!
"""
12 changes: 0 additions & 12 deletions tests/procedure.asm

This file was deleted.

8 changes: 2 additions & 6 deletions tests/test.asm
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
.global _main
.text
_main:
push 12 # push argument to factorial
push 10 # push argument to factorial
call factorial
add rsp, 8 # discard 1 local argument
mov [result + rip], rax
mov rsi, [result + rip]
push rsi # push variable
push rax # result of factorial
call display
add rsp, 8 # discard 1 local argument
mov rdi, 0
Expand Down Expand Up @@ -44,5 +42,3 @@ factorial:
ret

.data
result:
.quad 0
5 changes: 1 addition & 4 deletions tests/test.lisp
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
(define (factorial x)
(if (= x 1) 1
(* x (factorial (- x 1)))))

(define result (factorial 12))

(display result)
(display (factorial 10))

0 comments on commit 911ff5d

Please sign in to comment.