diff --git a/hello.mn b/hello.mn index 083dbee..62604ff 100644 --- a/hello.mn +++ b/hello.mn @@ -2,13 +2,7 @@ func: hello(string: x) = { stdout: out = x } -string: name -name = hej hopp +string: name = Hello world hello(name) - - -string: micke = Micke Nordin - -hello(micke) diff --git a/hello.tokens b/hello.tokens deleted file mode 100644 index eaf680d..0000000 --- a/hello.tokens +++ /dev/null @@ -1,134 +0,0 @@ -[ - { - "variant": "type", - "value": "func", - "line_number": 1 - }, - { - "variant": "operator", - "value": ":", - "line_number": 1 - }, - { - "variant": "function_declaration", - "value": "hello", - "params": [ - { - "type": "string", - "name": "x" - } - ], - "line_number": 1 - }, - { - "variant": "operator", - "value": "=", - "line_number": 1 - }, - { - "variant": "start_block", - "value": "{", - "line_number": 1 - }, - { - "variant": "type", - "value": "stdout", - "line_number": 2 - }, - { - "variant": "operator", - "value": ":", - "line_number": 2 - }, - { - "variant": "signifier", - "value": "out", - "line_number": 2 - }, - { - "variant": "operator", - "value": "=", - "line_number": 2 - }, - { - "variant": "expression", - "value": "x", - "line_number": 2 - }, - { - "variant": "end_block", - "value": "}", - "line_number": 3 - }, - { - "variant": "type", - "value": "string", - "line_number": 5 - }, - { - "variant": "operator", - "value": ":", - "line_number": 5 - }, - { - "variant": "signifier", - "value": "name", - "line_number": 5 - }, - { - "variant": "signifier", - "value": "name", - "line_number": 6 - }, - { - "variant": "operator", - "value": "=", - "line_number": 6 - }, - { - "variant": "expression", - "value": "hej hopp", - "line_number": 6 - }, - { - "variant": "function_call", - "value": "hello", - "params": [ - "name" - ], - "line_number": 9 - }, - { - "variant": "type", - "value": "string", - "line_number": 12 - }, - { - "variant": "operator", - "value": ":", - "line_number": 12 - }, - { - "variant": "signifier", - "value": "micke", - "line_number": 12 - }, - { - "variant": "operator", - "value": "=", - "line_number": 12 - }, - { - "variant": "expression", - "value": "Micke Nordin", - "line_number": 12 - }, - { - "variant": "function_call", - "value": "hello", - "params": [ - "micke" - ], - "line_number": 14 - } -] diff --git a/interpreter.py b/interpreter.py new file mode 100755 index 0000000..f222b32 --- /dev/null +++ b/interpreter.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +import json +import sys +tokens = dict() +program = './ast.json' +if len(sys.argv) > 1: + program = sys.argv[1] +with open(program, 'r') as json_tokens: + tokens = json.loads(json_tokens.read()) + +def throw(token: dict, message): + print("{} on line {} ".format(message, token['line_number'])) + print("\033[4m" + token['value'] + "\033[0m") + sys.exit(1) + +def parse_expression(params, expression): + split_on_space = expression.split(" ") + if len(split_on_space) == 1: + for param in params: + if param['signifier'] == expression and param['type'] == 'string': + return param['expression'] + else: + return "Unknown" + + +for token in tokens: + if token['variant'] == "syntax_error": + throw(token, "Syntax error") + if token['variant'] == "function_call": + args = token['params'] + function = token['function'] + params = function['params'] + if len(args) != len(params): + throw(token, "Wrong number of arguments") + for index in range(0, len(args)): + if args[index]['type'] != params[index]['type']: + throw(token, "Type missmatch on arguments") + signifier = params[index]['name'] + params[index] = args[index] + params[index]['signifier'] = signifier + for part in function['body']: + if part['type'] == "stdout": + print(parse_expression(params, part['expression'])) + diff --git a/lexer.py b/lexer.py index 91bed77..e514aec 100755 --- a/lexer.py +++ b/lexer.py @@ -91,7 +91,7 @@ for lineno in range(1, num_lines + 1): expression = {"variant": "start_block", "value": '{', "line_number": lineno} tokens.append(expression) elif line != "": - error = {"variant": "syntax_error", "line": line, "line_number": lineno} + error = {"variant": "syntax_error", "value": line, "line_number": lineno} tokens.append(error) print(json.dumps(tokens)) diff --git a/minion b/minion new file mode 100755 index 0000000..4d3bdea --- /dev/null +++ b/minion @@ -0,0 +1,29 @@ +#!/bin/bash + +program=${1} +command=${2} +if [[ "x${program}" == "x" ]]; then + usage "${0} .mn [lex|parse|run]" + exit 1 +fi +if [[ "x${command}" == "x" ]]; then + command="run" +fi + +if [[ "${command}" == "lex" ]]; then + ./lexer.py ${program} | jq . > ${program}.tokens && cat ${program}.tokens + rm ${program}.tokens + exit 0 +fi +if [[ "${command}" == "parse" ]]; then + ./lexer.py ${program} | jq . > ${program}.tokens && ./parser.py ${program}.tokens | jq . > ${program}.ast && cat ${program}.ast + rm ${program}.tokens ${program}.ast + exit 0 +fi +if [[ "${command}" == "run" ]]; then + ./lexer.py ${program} | jq . > ${program}.tokens && ./parser.py ${program}.tokens | jq . > ${program}.ast && ./interpreter.py ${program}.ast + rm ${program}.tokens ${program}.ast + exit 0 +fi +usage "${0} .mn [lex|parse|run]" +exit 1 diff --git a/parser.py b/parser.py index d245c04..271ef70 100755 --- a/parser.py +++ b/parser.py @@ -61,6 +61,10 @@ def collapse_tokens(uncollapsed_tokens: list) -> list: token = uncollapsed_tokens[index] # This is a declaration + if token['variant'] == 'syntax_error': + usefull_token = token + usefull_token['signifier'] = str(token['line_number']) + "_syntax_error" + usefull_tokens.append(usefull_token) if token['variant'] == 'type': maybe_signifier = peek(index + 2, uncollapsed_tokens) expression = '' @@ -72,7 +76,6 @@ def collapse_tokens(uncollapsed_tokens: list) -> list: if maybe_expression and maybe_expression['variant'] == 'expression': line_number = maybe_expression['line_number'] expression = maybe_expression['value'] - break usefull_token = { "variant": "variable_declaration", "signifier": name, "type": token['value'], "line_number": line_number, "expression": expression } usefull_tokens.append(usefull_token) if token['variant'] == 'function_declaration': @@ -96,7 +99,7 @@ for index in range(0, len(collapsed_tokens)): token = collapsed_tokens[index] if token['variant'] == 'function_call': function = coaless_tokens([token['signifier']], token['line_number'],collapsed_tokens.copy(), "function_declaration") - collapsed_tokens[index]['function'] = function + collapsed_tokens[index]['function'] = function.pop() params = coaless_tokens(token['params'], token['line_number'],collapsed_tokens.copy(), "variable_declaration") collapsed_tokens[index]['params'] = params print(json.dumps(collapsed_tokens)) diff --git a/prog.mn b/prog.mn deleted file mode 100644 index 18d91de..0000000 --- a/prog.mn +++ /dev/null @@ -1,28 +0,0 @@ -float: x = 10.1 - -func: hello(float: x) = { - stdout: out = x * 10 -} - -{ - str: name - int: var = 1 - name = hej hopp -} - - -hello(x) - -func: good_bye(void: none) = { - int: getout = 0 -} -good_bye() - -if (x ? 1) { - hello(x) -} - -while (x < 1) { - x = x -1 - hello(x) -} diff --git a/tokens.json b/tokens.json deleted file mode 100644 index a457e7a..0000000 --- a/tokens.json +++ /dev/null @@ -1 +0,0 @@ -[{"variant": "type", "value": "float", "line_number": 1}, {"variant": "operator", "value": ":", "line_number": 1}, {"variant": "signifier", "value": "x", "line_number": 1}, {"variant": "operator", "value": "=", "line_number": 1}, {"variant": "expression", "value": "10.1", "line_number": 1}, {"variant": "type", "value": "func", "line_number": 3}, {"variant": "operator", "value": ":", "line_number": 3}, {"variant": "function_declaration", "value": "hello", "params": [{"type": "float", "name": "x"}], "line_number": 3}, {"variant": "operator", "value": "=", "line_number": 3}, {"variant": "start_block", "value": "{", "line_number": 3}, {"variant": "type", "value": "stdout", "line_number": 4}, {"variant": "operator", "value": ":", "line_number": 4}, {"variant": "signifier", "value": "out", "line_number": 4}, {"variant": "operator", "value": "=", "line_number": 4}, {"variant": "expression", "value": "x * 10", "line_number": 4}, {"variant": "end_block", "value": "}", "line_number": 5}, {"variant": "start_block", "value": "{", "line_number": 7}, {"variant": "type", "value": "str", "line_number": 8}, {"variant": "operator", "value": ":", "line_number": 8}, {"variant": "signifier", "value": "name", "line_number": 8}, {"variant": "type", "value": "int", "line_number": 9}, {"variant": "operator", "value": ":", "line_number": 9}, {"variant": "signifier", "value": "var", "line_number": 9}, {"variant": "operator", "value": "=", "line_number": 9}, {"variant": "expression", "value": "1", "line_number": 9}, {"variant": "signifier", "value": "name", "line_number": 10}, {"variant": "operator", "value": "=", "line_number": 10}, {"variant": "expression", "value": "hej hopp", "line_number": 10}, {"variant": "end_block", "value": "}", "line_number": 11}, {"variant": "function_call", "value": "hello", "params": ["x"], "line_number": 14}, {"variant": "type", "value": "func", "line_number": 16}, {"variant": "operator", "value": ":", "line_number": 16}, {"variant": "function_declaration", "value": "good_bye", "params": [{"type": "void", "name": "none"}], "line_number": 16}, {"variant": "operator", "value": "=", "line_number": 16}, {"variant": "start_block", "value": "{", "line_number": 16}, {"variant": "type", "value": "int", "line_number": 17}, {"variant": "operator", "value": ":", "line_number": 17}, {"variant": "signifier", "value": "getout", "line_number": 17}, {"variant": "operator", "value": "=", "line_number": 17}, {"variant": "expression", "value": "0", "line_number": 17}, {"variant": "end_block", "value": "}", "line_number": 18}, {"variant": "function_call", "value": "good_bye", "params": [""], "line_number": 19}, {"variant": "conditional", "value": "if", "condition": "x ? 1", "line_number": 21}, {"variant": "start_block", "value": "{", "line_number": 21}, {"variant": "function_call", "value": "hello", "params": ["x"], "line_number": 22}, {"variant": "end_block", "value": "}", "line_number": 23}, {"variant": "loop", "value": "while", "condition": "x < 1", "line_number": 25}, {"variant": "start_block", "value": "{", "line_number": 25}, {"variant": "signifier", "value": "x", "line_number": 26}, {"variant": "operator", "value": "=", "line_number": 26}, {"variant": "expression", "value": "x -1", "line_number": 26}, {"variant": "function_call", "value": "hello", "params": ["x"], "line_number": 27}, {"variant": "end_block", "value": "}", "line_number": 28}]