summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xhenshin138
-rw-r--r--test/test.test9
2 files changed, 134 insertions, 13 deletions
diff --git a/henshin b/henshin
index 9958da3..c780b17 100755
--- a/henshin
+++ b/henshin
@@ -72,6 +72,9 @@ tokens = [
"BRACKET_RIGHT",
+ "AND",
+ "OR",
+ "BIT_AND",
"BIT_OR",
@@ -102,12 +105,15 @@ t_OPERATOR_PIPE_REPLACEMENT = r'\$'
t_PARENTHESIS_LEFT = r'\('
t_PARENTHESIS_RIGHT = r'\)'
-t_BRACE_LEFT = r'\['
-t_BRACE_RIGHT = r'\]'
-t_BRACKET_LEFT = r'{'
-t_BRACKET_RIGHT = r'}'
+t_BRACKET_LEFT = r'\['
+t_BRACKET_RIGHT = r'\]'
+t_BRACE_LEFT = r'{'
+t_BRACE_RIGHT = r'}'
+t_AND = r'\&\&'
+t_OR = r'\|\|'
+t_BIT_AND = r'\&'
t_BIT_OR = r'\|'
@@ -189,7 +195,7 @@ class AstNodeVariableDeclarationStatement(AstNode):
class AstNodeVariableReassignmentStatement(AstNode):
def __init__(self, name, value):
- self.type = type
+ self.name = name
self.value = value
class AstNodeExpression(AstNode):
@@ -203,6 +209,32 @@ class AstNodeOperatorExpression(AstNode):
self.left = left
self.right = right
+class AstNodeFunctionDeclaration(AstNode):
+ def __init__(self, name, parameters, return_type, body):
+ self.name = name
+ self.parameters = parameters
+ self.return_type = return_type
+ self.body = body
+
+class AstNodeFunctionDeclarationParameter(AstNode):
+ def __init__(self, name, type):
+ self.name = name
+ self.type = type
+
+class AstNodeReturnStatement(AstNode):
+ def __init__(self, expression):
+ self.expression = expression
+
+class AstNodeFunctionCall(AstNode):
+ def __init__(self, name, parameters):
+ self.name = name
+ self.parameters = parameters
+
+class AstNodeFunctionCallParameter(AstNode):
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
precedence = (
('left', 'OPERATOR_PLUS', 'OPERATOR_MINUS'),
@@ -217,9 +249,20 @@ def p_statements(p):
def resolve_nodes(node, level):
node_dict = node.__dict__
for property in node_dict:
- if isinstance(node_dict[property], AstNode):
- print('> '*level, property, node_dict[property].__class__.__name__)
- resolve_nodes(node_dict[property], level+1)
+ node_value = node_dict[property]
+
+ if isinstance(node_value, AstNode):
+ print('> '*level, property, node_value.__class__.__name__)
+ resolve_nodes(node_value, level+1)
+ elif isinstance(node_value, list):
+ list_length = len(node_value)
+ print('> '*level, property + '[' + str(list_length) + ']:')
+
+ for idx in range(list_length):
+ item = node_value[idx]
+
+ print('> '*(level+1), str(idx+1)+'.', item.__class__.__name__)
+ resolve_nodes(item, level+2)
else:
print('> '*level, property, node_dict[property])
@@ -227,15 +270,67 @@ def p_statements(p):
print(p[1].__class__.__name__)
resolve_nodes(p[1], 0)
+ statements = [p[1]]
+ if len(p) > 2:
+ statements.extend(p[2])
+ p[0] = statements
+
def p_statement(p):
'''statement : variable_declaration_statement
- | variable_reassignment_statement'''
+ | variable_reassignment_statement
+ | function_declaration
+ | return_statement'''
p[0] = p[1]
-# def p_function(p):
-# '''function : FUNCTION IDENTIFIER PARENTHESIS_LEFT function_parameters PARENTHESIS_RIGHT COLON return_type BRACKET_LEFT statements BRACKET_RIGHT'''
-# pass
+
+def p_function_declaration(p):
+ '''function_declaration : FUNCTION IDENTIFIER PARENTHESIS_LEFT function_declaration_parameters PARENTHESIS_RIGHT COLON return_type BRACE_LEFT statements BRACE_RIGHT'''
+
+ p[0] = AstNodeFunctionDeclaration(p[2], p[4], p[7], p[9])
+
+def p_function_declaration_parameters(p):
+ '''function_declaration_parameters : function_declaration_parameter COMMA function_declaration_parameters
+ | function_declaration_parameter
+ |'''
+
+ parameters = [p[1]]
+ if len(p) > 2:
+ parameters.append(p[3])
+
+ p[0] = parameters
+
+def p_function_declaration_parameter(p):
+ '''function_declaration_parameter : IDENTIFIER COLON variable_type'''
+
+ p[0] = AstNodeFunctionDeclarationParameter(p[1], p[3])
+
+
+def p_function_call(p):
+ '''function_call : IDENTIFIER PARENTHESIS_LEFT function_call_parameters PARENTHESIS_RIGHT SEMICOLON'''
+
+ p[0] = AstNodeFunctionCall(p[1], p[3])
+
+def p_function_call_parameters(p):
+ '''function_call_parameters : function_call_parameter COMMA function_call_parameters
+ | function_call_parameter
+ |'''
+
+ parameters = [p[1]]
+ if len(p) > 2:
+ parameters.append(p[3])
+
+ p[0] = parameters
+
+def p_function_call_parameter(p):
+ '''function_call_parameter : IDENTIFIER ASSIGN expression
+ | expression'''
+
+ if len(p) > 2:
+ p[0] = AstNodeFunctionCallParameter(p[1], p[3])
+ else:
+ p[0] = AstNodeFunctionCallParameter("", p[1])
+
def p_variable_declaration_statement(p):
'''variable_declaration_statement : variable_declarator IDENTIFIER COLON variable_type ASSIGN expression SEMICOLON'''
@@ -244,7 +339,8 @@ def p_variable_declaration_statement(p):
def p_variable_reassignment_statement(p):
'''variable_reassignment_statement : IDENTIFIER ASSIGN expression SEMICOLON'''
- pass
+
+ p[0] = AstNodeVariableReassignmentStatement(p[1], p[3])
def p_variable_declarator(p):
'''variable_declarator : CONST
@@ -256,6 +352,18 @@ def p_variable_type(p):
| TYPE_STRING'''
p[0] = p[1]
+
+def p_return_statement(p):
+ '''return_statement : RETURN expression SEMICOLON'''
+
+ p[0] = AstNodeReturnStatement(p[2])
+
+def p_return_type(p):
+ '''return_type : variable_type
+ | TYPE_VOID'''
+ p[0] = p[1]
+
+
def p_identifier(p):
'''identifier : IDENTIFIER'''
@@ -275,6 +383,7 @@ def p_expression(p):
'''expression : identifier
| number
| string
+ | function_call
| expression OPERATOR_PLUS expression
| expression OPERATOR_MINUS expression
| expression OPERATOR_MULTIPLY expression
@@ -293,3 +402,6 @@ def p_error(p):
parser = yacc.yacc(debug=True, debuglog=log)
result = parser.parse(input)
# print(result)
+
+# if __name__ == "__main__":
+# lex.runmain()
diff --git a/test/test.test b/test/test.test
index 5e3f420..2ffe743 100644
--- a/test/test.test
+++ b/test/test.test
@@ -6,3 +6,12 @@ ply = "way cooler!!";
const new: integer = henshin * 5 + 10;
const test: integer = 1 + 1;
+
+function main(input: string): void {
+ const hello: string = "world!";
+ const bye: string = "bye!";
+
+ return hello;
+}
+
+main(test);