Functions can now return

main
Micke Nordin 2 years ago
parent 888dd29517
commit 0317cb731b
Signed by: micke
GPG Key ID: 0DA0A7A5708FE257

@ -24,9 +24,11 @@ def parse_expression(variable_list, expression, all_tokens):
if len(split_on_space) == 1: if len(split_on_space) == 1:
for param in variable_list: for param in variable_list:
if param['signifier'] == expression: if param['signifier'] == expression:
if type(param['expression']) == type(dict()):
return param['expression']['expression']
match param['type']: match param['type']:
case 'string': case 'string':
return param['expression'] return str(param['expression'])
case 'number': case 'number':
resolved = list() resolved = list()
for part in param['expression'].split(' '): for part in param['expression'].split(' '):

@ -5,6 +5,31 @@ import sys
def find(needle: str, haystack: str) -> bool: def find(needle: str, haystack: str) -> bool:
return haystack.find(needle) != -1 return haystack.find(needle) != -1
def parse_lparen(line: str) -> list:
tokens = list()
split_on_lparen = line.split('(')
name = split_on_lparen[0].strip()
if find('=', line):
name = name.split('=')[1].strip()
without_name = '('.join(split_on_lparen[1:])
split_on_rparen = without_name.split(')')
params_str = ')'.join(split_on_rparen[:-1])
params = list(map(str.strip,params_str.split(',')))
if name not in ['if', 'while']:
function_call = {"variant": "function_call", "value": name, "params": params, "line_number": lineno}
tokens.append(function_call)
elif name == "if":
conditional = {"variant": "conditional", "value": name, "condition": ','.join(params), "line_number": lineno}
tokens.append(conditional)
expression = {"variant": "start_block", "value": "{", "line_number": lineno}
tokens.append(expression)
else:
loop = {"variant": "loop", "value": name, "condition": ','.join(params), "line_number": lineno}
tokens.append(loop)
expression = {"variant": "start_block", "value": "{", "line_number": lineno}
tokens.append(expression)
return tokens
source: list = list() source: list = list()
program = './prog.mn' program = './prog.mn'
if len(sys.argv) > 1: if len(sys.argv) > 1:
@ -44,14 +69,19 @@ for lineno in range(1, num_lines + 1):
signifier = {"variant": "function_declaration", "value": name, "params": params, "line_number": lineno} signifier = {"variant": "function_declaration", "value": name, "params": params, "line_number": lineno}
tokens.append(signifier) tokens.append(signifier)
if find('=', line): if find('=', line):
expressions = list()
colon_equals_rhs = '='.join(colon_rhs_split_on_equals[1:]) colon_equals_rhs = '='.join(colon_rhs_split_on_equals[1:])
operator = {"variant": "operator", "value": '=', "line_number": lineno} operator = {"variant": "operator", "value": '=', "line_number": lineno}
tokens.append(operator) tokens.append(operator)
expr = colon_equals_rhs.strip() expr = colon_equals_rhs.strip()
expression = {"variant": "expression", "value": expr, "line_number": lineno} expressions.append({"variant": "expression", "value": expr, "line_number": lineno})
if expr == '{': if expr == '{':
expression = {"variant": "start_block", "value": expr, "line_number": lineno} expressions[0] = {"variant": "start_block", "value": expr, "line_number": lineno}
elif find('(', line) and find(')', line):
expressions = parse_lparen(line)
for expression in expressions:
tokens.append(expression) tokens.append(expression)
elif find('=', line): elif find('=', line):
equals_rhs = '='.join(split_on_equals[1:]) equals_rhs = '='.join(split_on_equals[1:])
signifier = {"variant": "signifier", "value": equals_lhs.strip(), "line_number": lineno} signifier = {"variant": "signifier", "value": equals_lhs.strip(), "line_number": lineno}
@ -67,24 +97,11 @@ for lineno in range(1, num_lines + 1):
expression = {"variant": "end_block", "value": '}', "line_number": lineno} expression = {"variant": "end_block", "value": '}', "line_number": lineno}
tokens.append(expression) tokens.append(expression)
elif find('(', line): elif find('(', line):
split_on_lparen = line.split('(') for expression in parse_lparen(line):
name = split_on_lparen[0].strip()
without_name = '('.join(split_on_lparen[1:])
split_on_rparen = without_name.split(')')
params_str = ')'.join(split_on_rparen[:-1])
params = list(map(str.strip,params_str.split(',')))
if name not in ['if', 'while']:
function_call = {"variant": "function_call", "value": name, "params": params, "line_number": lineno}
tokens.append(function_call)
elif name == "if":
conditional = {"variant": "conditional", "value": name, "condition": ','.join(params), "line_number": lineno}
tokens.append(conditional)
expression = {"variant": "start_block", "value": "{", "line_number": lineno}
tokens.append(expression) tokens.append(expression)
else: elif find('return', line):
loop = {"variant": "loop", "value": name, "condition": ','.join(params), "line_number": lineno} rhs = line.strip().split()[1]
tokens.append(loop) expression = {"variant": "return", "value": rhs, "line_number": lineno}
expression = {"variant": "start_block", "value": "{", "line_number": lineno}
tokens.append(expression) tokens.append(expression)
else: else:
if line.strip() == '{': if line.strip() == '{':

@ -25,6 +25,15 @@ def find_token_indicies(key: str, tokens: list) -> list:
index = index + 1 index = index + 1
return result return result
def find_return_statement(maybe_expression, usefull_tokens) -> dict:
expression = dict()
for token in usefull_tokens:
if maybe_expression['value'] == token['signifier'] and token['variant'] == 'function_declaration':
for part in token['body']:
if part['variant'] == 'return_statement':
return part
return expression
def collect_body(index: int, tokens: list) -> list: def collect_body(index: int, tokens: list) -> list:
uncollapsed_tokens = list() uncollapsed_tokens = list()
token = peek(index + 1, tokens) token = peek(index + 1, tokens)
@ -86,7 +95,6 @@ def collapse_tokens(uncollapsed_tokens: list) -> list:
block_index = -1 block_index = -1
block_lineno = -1 block_lineno = -1
# This is a declaration
if token['variant'] == 'syntax_error': if token['variant'] == 'syntax_error':
if in_block: if in_block:
compare_lineno = block_lineno + 1 compare_lineno = block_lineno + 1
@ -118,6 +126,8 @@ def collapse_tokens(uncollapsed_tokens: list) -> list:
if maybe_expression and maybe_expression['variant'] == 'expression': if maybe_expression and maybe_expression['variant'] == 'expression':
line_number = maybe_expression['line_number'] line_number = maybe_expression['line_number']
expression = maybe_expression['value'] expression = maybe_expression['value']
elif maybe_expression and maybe_expression['variant'] == 'function_call':
expression = find_return_statement(maybe_expression, usefull_tokens.copy())
usefull_token = { "variant": "variable_declaration", "signifier": name, "type": token['value'], "line_number": line_number, "expression": expression } usefull_token = { "variant": "variable_declaration", "signifier": name, "type": token['value'], "line_number": line_number, "expression": expression }
usefull_tokens.append(usefull_token) usefull_tokens.append(usefull_token)
if token['variant'] == 'function_declaration': if token['variant'] == 'function_declaration':
@ -131,6 +141,11 @@ def collapse_tokens(uncollapsed_tokens: list) -> list:
usefull_token = {"variant": "function_call", "signifier": token['value'], "line_number": token['line_number'], "params": token['params']} usefull_token = {"variant": "function_call", "signifier": token['value'], "line_number": token['line_number'], "params": token['params']}
usefull_tokens.append(usefull_token) usefull_tokens.append(usefull_token)
if token['variant'] == 'return':
for tkn in usefull_tokens.copy():
if token['value'] == tkn['signifier']:
usefull_token = {"variant": "return_statement", "signifier": tkn['signifier'], "type": tkn['type'], "line_number": tkn['line_number'], "expression": tkn['expression']}
usefull_tokens.append(usefull_token)
usefull_tokens.sort(key=operator.itemgetter('line_number')) usefull_tokens.sort(key=operator.itemgetter('line_number'))
return usefull_tokens return usefull_tokens

@ -0,0 +1,14 @@
func: test(void: i) = {
number: x = 10
return x
}
func: print(number: n, string: endl) = {
stdout: out = n
stdout: outln = endl
}
string: end = {
}
void: j = void
number: y = test(j)
print(y, end)
Loading…
Cancel
Save