function calls work!!!
This commit is contained in:
16
AST.py
16
AST.py
@@ -16,6 +16,7 @@ class NodeType(Enum):
|
||||
|
||||
# Expressions
|
||||
InfixExpression = "InfixExpression"
|
||||
CallExpression = "CallExpression"
|
||||
|
||||
# Literals
|
||||
IntegerLiteral = "IntegerLiteral"
|
||||
@@ -231,4 +232,19 @@ class InfixExpression(Expression):
|
||||
"operator": self.operator,
|
||||
"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
|
||||
21
compiler.py
21
compiler.py
@@ -2,7 +2,7 @@ from llvmlite import ir
|
||||
|
||||
from AST import Node, NodeType, Program, Expression
|
||||
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 environment import Environment
|
||||
@@ -69,6 +69,8 @@ class Compiler:
|
||||
# Expressions
|
||||
case NodeType.InfixExpression:
|
||||
self.__visit_infix_expression(node)
|
||||
case NodeType.CallExpression:
|
||||
self.__visit_call_expression(node)
|
||||
|
||||
# region Visit Methods
|
||||
def __visit_program(self, node: Program) -> None:
|
||||
@@ -257,6 +259,21 @@ class Compiler:
|
||||
Type = ir.IntType(1)
|
||||
|
||||
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
|
||||
@@ -283,4 +300,6 @@ class Compiler:
|
||||
# expression value
|
||||
case NodeType.InfixExpression:
|
||||
return self.__visit_infix_expression(node)
|
||||
case NodeType.CallExpression:
|
||||
return self.__visit_call_expression(node)
|
||||
# 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
|
||||
@"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"()
|
||||
{
|
||||
main_entry:
|
||||
%".2" = alloca float
|
||||
store float 0x4014000000000000, float* %".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
|
||||
%".2" = call i32 @"test"()
|
||||
ret i32 %".2"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ from enum import Enum, auto
|
||||
|
||||
from AST import Statement, Expression, Program
|
||||
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
|
||||
|
||||
class PrecedenceType(Enum):
|
||||
@@ -31,7 +31,8 @@ PRECEDENCES: dict[TokenType, PrecedenceType] = {
|
||||
TokenType.LT: PrecedenceType.P_LESSGREATER,
|
||||
TokenType.GT: 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:
|
||||
@@ -65,6 +66,7 @@ class Parser:
|
||||
TokenType.GT: self.__parse_infix_expression,
|
||||
TokenType.LT_EQ: self.__parse_infix_expression,
|
||||
TokenType.GT_EQ: self.__parse_infix_expression,
|
||||
TokenType.LPAREN: self.__parse_call_expression
|
||||
}
|
||||
|
||||
self.__next_token()
|
||||
@@ -305,6 +307,16 @@ class Parser:
|
||||
return None
|
||||
|
||||
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
|
||||
|
||||
# region Prefix Methods
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
test = Func(): Int {
|
||||
return 123;
|
||||
x: Int = 3;
|
||||
return x + 2;
|
||||
}
|
||||
|
||||
main = Func(): Int {
|
||||
|
||||
Reference in New Issue
Block a user