nac3-spec/toy-impl/main.py

62 lines
1.9 KiB
Python
Raw Permalink Normal View History

2020-12-23 10:34:56 +08:00
import ast
import sys
2020-12-23 16:05:45 +08:00
import copy
2020-12-23 10:34:56 +08:00
from helper import CustomError
2020-12-23 13:43:34 +08:00
from type_def import SelfType, ClassType
2020-12-23 10:34:56 +08:00
from parse_stmt import parse_stmts
from primitives import simplest_ctx
from top_level import parse_top_level
2020-12-23 13:43:34 +08:00
from inheritance import class_fixup
2021-01-07 11:57:28 +08:00
from lifetime import Lifetime, assign_stmt
2020-12-23 10:34:56 +08:00
if len(sys.argv) != 2:
print('please pass the python script name as argument')
exit()
with open(sys.argv[1], 'r') as f:
source = f.read()
tree = ast.parse(source, filename=sys.argv[1])
try:
ctx, fns = parse_top_level(simplest_ctx, tree)
2020-12-23 13:43:34 +08:00
for c in ctx.types.values():
if isinstance(c, ClassType):
class_fixup(c)
2020-12-23 10:34:56 +08:00
for c, name, fn in fns:
if c is None:
2020-12-23 16:05:45 +08:00
params, result, var = ctx.functions[name]
2020-12-23 10:34:56 +08:00
else:
2020-12-23 16:05:45 +08:00
params, result, var = ctx.types[c].methods[name]
# create substitution for type variables
subst = {k: copy.deepcopy(ctx.variables[k]) for k in var}
2020-12-23 10:34:56 +08:00
# check if fully annotated all params
sym_table = {}
for n, ty in zip(fn.args.args, params):
if ty is None:
raise CustomError(
'Function parameters must be annotated',
fn)
if isinstance(ty, SelfType):
ty = ctx.types[c]
2020-12-23 16:05:45 +08:00
sym_table[n.arg] = ty.subst(subst)
2021-01-07 11:57:28 +08:00
try:
print()
print('checking:')
print(ast.unparse(fn))
print('typecheck...')
_, _, returned = parse_stmts(ctx, sym_table, sym_table, result, fn.body)
if result is not None and not returned:
raise CustomError('Function may have no return value', fn)
print('lifetime check...')
sym_table = {k: Lifetime(1) for k in sym_table}
assign_stmt(2, sym_table, fn.body)
print('OK!')
except AssertionError:
pass
2020-12-23 10:34:56 +08:00
except CustomError as e:
print('Error while type checking:')
print(e.msg)