function calls work!!!
This commit is contained in:
16
AST.py
16
AST.py
@@ -16,6 +16,7 @@ class NodeType(Enum):
|
|||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
InfixExpression = "InfixExpression"
|
InfixExpression = "InfixExpression"
|
||||||
|
CallExpression = "CallExpression"
|
||||||
|
|
||||||
# Literals
|
# Literals
|
||||||
IntegerLiteral = "IntegerLiteral"
|
IntegerLiteral = "IntegerLiteral"
|
||||||
@@ -231,4 +232,19 @@ class InfixExpression(Expression):
|
|||||||
"operator": self.operator,
|
"operator": self.operator,
|
||||||
"right_node": self.right_node.json()
|
"right_node": self.right_node.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CallExpression(Expression):
|
||||||
|
def __init__(self, function: Expression = None, arguments: list[Expression] = None) -> None:
|
||||||
|
self.function = function
|
||||||
|
self.arguments = arguments
|
||||||
|
|
||||||
|
def type(self) -> NodeType:
|
||||||
|
return NodeType.CallExpression
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"type": self.type().value,
|
||||||
|
"function": self.function.json(),
|
||||||
|
"arguments": [arg.json() for arg in self.arguments]
|
||||||
|
}
|
||||||
# endregion
|
# endregion
|
||||||
21
compiler.py
21
compiler.py
@@ -2,7 +2,7 @@ from llvmlite import ir
|
|||||||
|
|
||||||
from AST import Node, NodeType, Program, Expression
|
from AST import Node, NodeType, Program, Expression
|
||||||
from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement
|
from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement
|
||||||
from AST import InfixExpression
|
from AST import InfixExpression, CallExpression
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
||||||
|
|
||||||
from environment import Environment
|
from environment import Environment
|
||||||
@@ -69,6 +69,8 @@ class Compiler:
|
|||||||
# Expressions
|
# Expressions
|
||||||
case NodeType.InfixExpression:
|
case NodeType.InfixExpression:
|
||||||
self.__visit_infix_expression(node)
|
self.__visit_infix_expression(node)
|
||||||
|
case NodeType.CallExpression:
|
||||||
|
self.__visit_call_expression(node)
|
||||||
|
|
||||||
# region Visit Methods
|
# region Visit Methods
|
||||||
def __visit_program(self, node: Program) -> None:
|
def __visit_program(self, node: Program) -> None:
|
||||||
@@ -257,6 +259,21 @@ class Compiler:
|
|||||||
Type = ir.IntType(1)
|
Type = ir.IntType(1)
|
||||||
|
|
||||||
return value, Type
|
return value, Type
|
||||||
|
|
||||||
|
def __visit_call_expression(self, node: CallExpression) -> None:
|
||||||
|
name: str = node.function.value
|
||||||
|
params: list[Expression] = node.arguments
|
||||||
|
|
||||||
|
args = []
|
||||||
|
types = []
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
match name:
|
||||||
|
case _:
|
||||||
|
func, ret_type = self.environment.lookup(name)
|
||||||
|
ret = self.builder.call(func, args)
|
||||||
|
|
||||||
|
return ret, ret_type
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
@@ -283,4 +300,6 @@ class Compiler:
|
|||||||
# expression value
|
# expression value
|
||||||
case NodeType.InfixExpression:
|
case NodeType.InfixExpression:
|
||||||
return self.__visit_infix_expression(node)
|
return self.__visit_infix_expression(node)
|
||||||
|
case NodeType.CallExpression:
|
||||||
|
return self.__visit_call_expression(node)
|
||||||
# endregion
|
# endregion
|
||||||
55
debug/ast.json
Normal file
55
debug/ast.json
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"type": "Program",
|
||||||
|
"statements": [
|
||||||
|
{
|
||||||
|
"FunctionStatement": {
|
||||||
|
"type": "FunctionStatement",
|
||||||
|
"name": {
|
||||||
|
"type": "IdentifierLiteral",
|
||||||
|
"value": "test"
|
||||||
|
},
|
||||||
|
"return_type": "Int",
|
||||||
|
"parameters": [],
|
||||||
|
"body": {
|
||||||
|
"type": "BlockStatement",
|
||||||
|
"statements": [
|
||||||
|
{
|
||||||
|
"type": "ReturnStatement",
|
||||||
|
"return_value": {
|
||||||
|
"type": "IntegerLiteral",
|
||||||
|
"value": 123
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FunctionStatement": {
|
||||||
|
"type": "FunctionStatement",
|
||||||
|
"name": {
|
||||||
|
"type": "IdentifierLiteral",
|
||||||
|
"value": "main"
|
||||||
|
},
|
||||||
|
"return_type": "Int",
|
||||||
|
"parameters": [],
|
||||||
|
"body": {
|
||||||
|
"type": "BlockStatement",
|
||||||
|
"statements": [
|
||||||
|
{
|
||||||
|
"type": "ReturnStatement",
|
||||||
|
"return_value": {
|
||||||
|
"type": "CallExpression",
|
||||||
|
"function": {
|
||||||
|
"type": "IdentifierLiteral",
|
||||||
|
"value": "test"
|
||||||
|
},
|
||||||
|
"arguments": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
23
debug/ir.ll
23
debug/ir.ll
@@ -4,18 +4,19 @@ target datalayout = ""
|
|||||||
|
|
||||||
@"true" = constant i1 1
|
@"true" = constant i1 1
|
||||||
@"false" = constant i1 0
|
@"false" = constant i1 0
|
||||||
|
define i32 @"test"()
|
||||||
|
{
|
||||||
|
test_entry:
|
||||||
|
%".2" = alloca i32
|
||||||
|
store i32 3, i32* %".2"
|
||||||
|
%".4" = load i32, i32* %".2"
|
||||||
|
%".5" = add i32 %".4", 2
|
||||||
|
ret i32 %".5"
|
||||||
|
}
|
||||||
|
|
||||||
define i32 @"main"()
|
define i32 @"main"()
|
||||||
{
|
{
|
||||||
main_entry:
|
main_entry:
|
||||||
%".2" = alloca float
|
%".2" = call i32 @"test"()
|
||||||
store float 0x4014000000000000, float* %".2"
|
ret i32 %".2"
|
||||||
%".4" = load float, float* %".2"
|
|
||||||
%".5" = fcmp oeq float %".4", 0x4014000000000000
|
|
||||||
br i1 %".5", label %"main_entry.if", label %"main_entry.else"
|
|
||||||
main_entry.if:
|
|
||||||
ret i32 1
|
|
||||||
main_entry.else:
|
|
||||||
ret i32 0
|
|
||||||
main_entry.endif:
|
|
||||||
ret i32 0
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from enum import Enum, auto
|
|||||||
|
|
||||||
from AST import Statement, Expression, Program
|
from AST import Statement, Expression, Program
|
||||||
from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement
|
from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement
|
||||||
from AST import InfixExpression
|
from AST import InfixExpression, CallExpression
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
||||||
|
|
||||||
class PrecedenceType(Enum):
|
class PrecedenceType(Enum):
|
||||||
@@ -31,7 +31,8 @@ PRECEDENCES: dict[TokenType, PrecedenceType] = {
|
|||||||
TokenType.LT: PrecedenceType.P_LESSGREATER,
|
TokenType.LT: PrecedenceType.P_LESSGREATER,
|
||||||
TokenType.GT: PrecedenceType.P_LESSGREATER,
|
TokenType.GT: PrecedenceType.P_LESSGREATER,
|
||||||
TokenType.LT_EQ: PrecedenceType.P_LESSGREATER,
|
TokenType.LT_EQ: PrecedenceType.P_LESSGREATER,
|
||||||
TokenType.GT_EQ: PrecedenceType.P_LESSGREATER
|
TokenType.GT_EQ: PrecedenceType.P_LESSGREATER,
|
||||||
|
TokenType.LPAREN: PrecedenceType.P_CALL
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
@@ -65,6 +66,7 @@ class Parser:
|
|||||||
TokenType.GT: self.__parse_infix_expression,
|
TokenType.GT: self.__parse_infix_expression,
|
||||||
TokenType.LT_EQ: self.__parse_infix_expression,
|
TokenType.LT_EQ: self.__parse_infix_expression,
|
||||||
TokenType.GT_EQ: self.__parse_infix_expression,
|
TokenType.GT_EQ: self.__parse_infix_expression,
|
||||||
|
TokenType.LPAREN: self.__parse_call_expression
|
||||||
}
|
}
|
||||||
|
|
||||||
self.__next_token()
|
self.__next_token()
|
||||||
@@ -305,6 +307,16 @@ class Parser:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
return expr
|
return expr
|
||||||
|
|
||||||
|
def __parse_call_expression(self, function: Expression) -> CallExpression:
|
||||||
|
expr: CallExpression = CallExpression(function=function)
|
||||||
|
|
||||||
|
expr.arguments = [] # TODO
|
||||||
|
if not self.__expect_peek(TokenType.RPAREN):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return expr
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Prefix Methods
|
# region Prefix Methods
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
test = Func(): Int {
|
test = Func(): Int {
|
||||||
return 123;
|
x: Int = 3;
|
||||||
|
return x + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
main = Func(): Int {
|
main = Func(): Int {
|
||||||
|
|||||||
Reference in New Issue
Block a user