#!/usr/bin/env python3 # SPDX-License-Identifier: MIT # Copyright 2021 Jookia <contact@jookia.org> import log import parse def text_create(value): return ("text", value) def text_value(object): return object[1] def text_dispatch(object, verb, args): value = text_value(object) if verb == "Append": appendix = text_value(args[0]) return text_create(value + " " + appendix) return None def module_create(verbs): return ("module", verbs) def module_dispatch(object, verb, args): (type, functions) = object return functions[verb](object, args) def do_system_print(subject, args): print(text_value(args[0])) return None def do_system_read(subject, args): return text_create(input()) system_module = module_create({ "Print": do_system_print, "Read": do_system_read, }) def resolve_value(env, value): if value.__class__ == parse.Reference: return env[value.value] elif value.__class__ == parse.Text: return text_create(value.value) else: print("Unimplemented value: %s" % (value)) def run_statement(env, ast): subject = resolve_value(env, ast.subject) if ast.verb == None: return subject args = [] for arg in ast.arguments: args.append(resolve_value(env, arg)) if subject[0] == "text": return text_dispatch(subject, ast.verb, args) elif subject[0] == "module": return module_dispatch(subject, ast.verb, args) return None def run_set(env, ast): env[ast[1]] = run_statement(env, ast[2]) return env[ast[1]] def run_if(env, ast): print("Unimplemented if") return None def run_command(env, ast): if ast.__class__ == parse.Statement: return run_statement(env, ast) type = ast[0] if type == "set": return run_set(env, ast) elif type == "if": return run_if(env, ast) else: print("Unknown command type %s" % (ast)) return None def main(args): if len(args) != 2: print("Usage: main.py FILENAME") return 1 log.set_default_log_level() filename = args[1] code = open(filename).read() if code[0:2] == '#!': next_line = code.find('\n') + 1 code = code[next_line:] ast = parse.parse_file(code) if not ast: return 1 env = { "System": system_module, } for command in ast: run_command(env, command) return 0 if __name__ == "__main__": import sys sys.exit(main(sys.argv))