Skip to content

Commit

Permalink
More refactoring, prep for #4
Browse files Browse the repository at this point in the history
  • Loading branch information
eigenhombre committed Jul 21, 2022
1 parent fe4b43f commit e2ea86e
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 77 deletions.
3 changes: 3 additions & 0 deletions .projectile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- /dist
- /build
- /venv
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ test:
. venv/bin/activate && ./smallscheme/main.py fact.scm
. venv/bin/activate && ./smallscheme/main.py -t tests.scm


lint:
. venv/bin/activate && pycodestyle smallscheme

Expand All @@ -37,6 +36,8 @@ pip-docker-test:
build-docker-test:
docker build -t smallscheme -f Dockerfile.build .

alltests: test build-docker-test

release:
./bumpver
. venv/bin/activate && python setup.py sdist
17 changes: 17 additions & 0 deletions smallscheme/dtypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def atom(x):
return 'atom', x

def list_(x):
return 'list', x

def bool_(x):
return 'bool', x

def int_(x):
return 'int', x

def float_(x):
return 'float', x

def typ(x):
return x[0]
59 changes: 59 additions & 0 deletions smallscheme/parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import lark
from smallscheme.dtypes import *

grammar = '''
start : _exprs
_exprs : _e* _e
_e : ATOM
| _num
| BOOL
| list
TRUE : "#t"
FALSE : "#f"
BOOL : TRUE | FALSE
list : "(" _exprs? ")"
INT : /[-+]?[0-9]+/
ATOM : /[a-zA-Z]+[a-zA-Z0-9\-\?\!]*/
| /[\*\/\=\>\<]/
| /[\-\+](?![0-9])/
FLOAT : /[-+]?[0-9]+\.[0-9]*/
_num : INT | FLOAT
COMMENT : ";" /(.)*/ NEWLINE?
%import common.WS
%import common.NEWLINE
%ignore WS
%ignore COMMENT
'''

parser = lark.Lark(grammar)

def convert_ast(ast):
"""
Re-cast the Lark representation of the parse tree into our own.
'start' is always the top of the tree and `convert_ast` returns a
list of zero or more parsed expressions.
All other entrypoints are recursively converted into the
appropriate atom, list, int, float etc.
"""
if type(ast) is lark.tree.Tree:
if ast.data == "start":
return [convert_ast(x) for x in ast.children]
if ast.data == "list":
return list_([convert_ast(x) for x in ast.children])
if type(ast) is lark.lexer.Token:
ty = ast.type.lower()
if ty == "int":
return int_(int(ast.value))
if ty == "float":
return float_(float(ast.value))
elif ty == "bool":
return bool_(True if ast.value == "#t" else False)
elif ty == "atom":
return atom(ast.value)
raise Exception("Unparsed AST: '%s'" % ast)

def parse_str(x):
return convert_ast(parser.parse(x))
76 changes: 2 additions & 74 deletions smallscheme/scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,11 @@
import re
import sys
from functools import reduce

parser = lark.Lark(
'''
start : _exprs
_exprs : _e* _e
_e : ATOM
| _num
| BOOL
| list
TRUE : "#t"
FALSE : "#f"
BOOL : TRUE | FALSE
list : "(" _exprs? ")"
INT : /[-+]?[0-9]+/
ATOM : /[a-zA-Z]+[a-zA-Z0-9\-\?\!]*/
| /[\*\/\=\>\<]/
| /[\-\+](?![0-9])/
FLOAT : /[-+]?[0-9]+\.[0-9]*/
_num : INT | FLOAT
COMMENT : ";" /(.)*/ NEWLINE?
%import common.WS
%import common.NEWLINE
%ignore WS
%ignore COMMENT
''')

def atom(x):
return 'atom', x

def list_(x):
return 'list', x

def bool_(x):
return 'bool', x

def int_(x):
return 'int', x

def float_(x):
return 'float', x

def typ(x):
return x[0]
from smallscheme.parse import parse_str
from smallscheme.dtypes import *

noop = 'nop', None

def convert_ast(ast):
"""
Re-cast the Lark representation of the parse tree into our own.
'start' is always the top of the tree and `convert_ast` returns a
list of zero or more parsed expressions.
All other entrypoints are recursively converted into the
appropriate atom, list, int, float etc.
"""
if type(ast) is lark.tree.Tree:
if ast.data == "start":
return [convert_ast(x) for x in ast.children]
if ast.data == "list":
return list_([convert_ast(x) for x in ast.children])
if type(ast) is lark.lexer.Token:
ty = ast.type.lower()
if ty == "int":
return int_(int(ast.value))
if ty == "float":
return float_(float(ast.value))
elif ty == "bool":
return bool_(True if ast.value == "#t" else False)
elif ty == "atom":
return atom(ast.value)
raise Exception("Unparsed AST: '%s'" % ast)

def parse_str(x):
return convert_ast(parser.parse(x))

def argstype(args):
# FIXME: Unit test for argument types
arglist = [x for (x, _) in args]
Expand Down
3 changes: 2 additions & 1 deletion smallscheme/test_parse.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from smallscheme.scheme import *
from smallscheme.dtypes import *
from smallscheme.parse import parse_str
from smallscheme.test_util import teq

def test_parse_str():
Expand Down
4 changes: 3 additions & 1 deletion smallscheme/test_scheme.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sys
from smallscheme.scheme import *
from smallscheme.dtypes import *
from smallscheme.parse import parse_str
from smallscheme.scheme import evalu, printable_value
from smallscheme.test_util import teq

def test_evalu():
Expand Down

0 comments on commit e2ea86e

Please sign in to comment.