diff --git a/lang/compile.py b/lang/compile.py new file mode 100755 index 0000000..2775344 --- /dev/null +++ b/lang/compile.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: MIT +# Copyright (c) 2023 John Watts and the LuminaSensum contributors + +## PARSER + +class ASTStatement(): + def __repr__(self): + return 'ASTStatement' + +class ASTFunction(): + def __init__(self, name, statements): + self.name = name + self.statements = statements + + def __repr__(self): + return 'ASTFunction(name="%s", statements="%s")' % (self.name, self.statements) + +def tokenize(code): + line = [] + lines = [] + tok = "" + for c in code.strip(): + if c == ' ': + line.append(tok) + tok = "" + elif c == '\n': + line.append(tok) + lines.append(line) + line = [] + tok = "" + else: + tok += c + line.append(tok) + lines.append(line) + return lines + +def parse_statement(lines): + line = lines[0] + instr = line[0] + if instr == "Set": + print("SET") + # ASTSet + elif instr == "Return": + print("RETURN") + # ASTReturn + else: + print("COMMAND") + # ASTCommand + statement = ASTStatement() + return (statement, lines[1:]) + +def parse_function(lines): + line = lines[0] + lines = lines[1:] + if len(line) != 2 or line[0] != "Function": + print("not a function? line: %s" % (' '.join(line))) + return (None, []) + name = line[1] + statements = [] + print(lines) + while len(lines) != 0: + first_word = lines[0][0] + if first_word == "EndFunction": + lines = lines[1:] + break + (statement, lines) = parse_statement(lines) + if statement == None: + return None + else: + statements.append(statement) + func = ASTFunction(name, statements) + return (func, lines) + +def parse_toplevel(lines): + ast = [] + while len(lines) != 0: + (func, lines) = parse_function(lines) + if func == None: + return None + else: + ast.append(func) + return ast + +code = """ +Function MakeNumber +Set Halfish To 618 +Set Double To Halfish Add Halfish +Set Final To Out Minus 2 +Return Final +EndFunction +""" + +lines = tokenize(code) +ast = parse_toplevel(lines) +print(ast)