Can run hello world

main
Micke Nordin 6 months ago
parent c38f5ffacc
commit 62718009e9
Signed by: micke
GPG Key ID: 0DA0A7A5708FE257
  1. 8
      hello.mn
  2. 134
      hello.tokens
  3. 44
      interpreter.py
  4. 2
      lexer.py
  5. 29
      minion
  6. 7
      parser.py
  7. 28
      prog.mn
  8. 1
      tokens.json

@ -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)

@ -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
}
]

@ -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']))

@ -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))

@ -0,0 +1,29 @@
#!/bin/bash
program=${1}
command=${2}
if [[ "x${program}" == "x" ]]; then
usage "${0} <program>.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} <program>.mn [lex|parse|run]"
exit 1

@ -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))

@ -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)
}

@ -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}]
Loading…
Cancel
Save