#!/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)