function arguments are getting added to the AST!
This commit is contained in:
22
AST.py
22
AST.py
@@ -24,6 +24,9 @@ class NodeType(Enum):
|
|||||||
IdentifierLiteral = "IdentifierLiteral"
|
IdentifierLiteral = "IdentifierLiteral"
|
||||||
BooleanLiteral = "BooleanLiteral"
|
BooleanLiteral = "BooleanLiteral"
|
||||||
|
|
||||||
|
# Helper
|
||||||
|
FunctionParameter = "FunctionParameter"
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def type(self) -> NodeType:
|
def type(self) -> NodeType:
|
||||||
@@ -52,6 +55,23 @@ class Program(Node):
|
|||||||
"statements": [{stmt.type().value: stmt.json()} for stmt in self.statements]
|
"statements": [{stmt.type().value: stmt.json()} for stmt in self.statements]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# region Helpers
|
||||||
|
class FunctionParameter(Expression):
|
||||||
|
def __init__(self, name: str, value_type: str = None) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.value_type = value_type
|
||||||
|
|
||||||
|
def type(self) -> NodeType:
|
||||||
|
return NodeType.FunctionParameter
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"type": self.type().value,
|
||||||
|
"name": self.name,
|
||||||
|
"value_type": self.value_type
|
||||||
|
}
|
||||||
|
# endregion
|
||||||
|
|
||||||
# region Literals
|
# region Literals
|
||||||
class IntegerLiteral(Expression):
|
class IntegerLiteral(Expression):
|
||||||
def __init__(self, value: int = None) -> None:
|
def __init__(self, value: int = None) -> None:
|
||||||
@@ -164,7 +184,7 @@ class ReturnStatement(Statement):
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FunctionStatement(Statement):
|
class FunctionStatement(Statement):
|
||||||
def __init__(self, parameters: list = [], body: BlockStatement = None, name: IdentifierLiteral = None, return_type: str = None):
|
def __init__(self, parameters: list[FunctionParameter] = [], body: BlockStatement = None, name: IdentifierLiteral = None, return_type: str = None):
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
self.body = body
|
self.body = body
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|||||||
@@ -6,18 +6,37 @@
|
|||||||
"type": "FunctionStatement",
|
"type": "FunctionStatement",
|
||||||
"name": {
|
"name": {
|
||||||
"type": "IdentifierLiteral",
|
"type": "IdentifierLiteral",
|
||||||
"value": "test"
|
"value": "add"
|
||||||
},
|
},
|
||||||
"return_type": "Int",
|
"return_type": "Int",
|
||||||
"parameters": [],
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "FunctionParameter",
|
||||||
|
"name": "a",
|
||||||
|
"value_type": "Int"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "FunctionParameter",
|
||||||
|
"name": "b",
|
||||||
|
"value_type": "Int"
|
||||||
|
}
|
||||||
|
],
|
||||||
"body": {
|
"body": {
|
||||||
"type": "BlockStatement",
|
"type": "BlockStatement",
|
||||||
"statements": [
|
"statements": [
|
||||||
{
|
{
|
||||||
"type": "ReturnStatement",
|
"type": "ReturnStatement",
|
||||||
"return_value": {
|
"return_value": {
|
||||||
"type": "IntegerLiteral",
|
"type": "InfixExpression",
|
||||||
"value": 123
|
"left_node": {
|
||||||
|
"type": "IdentifierLiteral",
|
||||||
|
"value": "a"
|
||||||
|
},
|
||||||
|
"operator": "+",
|
||||||
|
"right_node": {
|
||||||
|
"type": "IdentifierLiteral",
|
||||||
|
"value": "b"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -42,9 +61,18 @@
|
|||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
"function": {
|
"function": {
|
||||||
"type": "IdentifierLiteral",
|
"type": "IdentifierLiteral",
|
||||||
"value": "test"
|
"value": "add"
|
||||||
},
|
},
|
||||||
"arguments": []
|
"arguments": [
|
||||||
|
{
|
||||||
|
"type": "IntegerLiteral",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "IntegerLiteral",
|
||||||
|
"value": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,11 +7,8 @@ target datalayout = ""
|
|||||||
define i32 @"test"()
|
define i32 @"test"()
|
||||||
{
|
{
|
||||||
test_entry:
|
test_entry:
|
||||||
%".2" = alloca i32
|
%".2" = add i32 77, 33
|
||||||
store i32 3, i32* %".2"
|
ret i32 %".2"
|
||||||
%".4" = load i32, i32* %".2"
|
|
||||||
%".5" = add i32 %".4", 2
|
|
||||||
ret i32 %".5"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @"main"()
|
define i32 @"main"()
|
||||||
|
|||||||
2
lexer.py
2
lexer.py
@@ -144,6 +144,8 @@ class Lexer:
|
|||||||
tok = self.__new_token(TokenType.SEMICOLON, self.current_char)
|
tok = self.__new_token(TokenType.SEMICOLON, self.current_char)
|
||||||
case ":":
|
case ":":
|
||||||
tok = self.__new_token(TokenType.COLON, self.current_char)
|
tok = self.__new_token(TokenType.COLON, self.current_char)
|
||||||
|
case ",":
|
||||||
|
tok = self.__new_token(TokenType.COMMA, self.current_char)
|
||||||
case None:
|
case None:
|
||||||
tok = self.__new_token(TokenType.EOF, "")
|
tok = self.__new_token(TokenType.EOF, "")
|
||||||
case _:
|
case _:
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class TokenType(Enum):
|
|||||||
RBRACE = "RBRACE"
|
RBRACE = "RBRACE"
|
||||||
COLON = "COLON"
|
COLON = "COLON"
|
||||||
SEMICOLON = "SEMICOLON"
|
SEMICOLON = "SEMICOLON"
|
||||||
|
COMMA = "COMMA"
|
||||||
|
|
||||||
# Keywords
|
# Keywords
|
||||||
RETURN = "RETURN"
|
RETURN = "RETURN"
|
||||||
|
|||||||
6
main.py
6
main.py
@@ -10,9 +10,9 @@ import llvmlite.binding as llvm
|
|||||||
from ctypes import CFUNCTYPE, c_int, c_float
|
from ctypes import CFUNCTYPE, c_int, c_float
|
||||||
|
|
||||||
LEXER_DEBUG: bool = False
|
LEXER_DEBUG: bool = False
|
||||||
PARSER_DEBUG: bool = False
|
PARSER_DEBUG: bool = True
|
||||||
COMPILER_DEBUG: bool = True
|
COMPILER_DEBUG: bool = False
|
||||||
RUN_CODE: bool = True
|
RUN_CODE: bool = False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ 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, CallExpression
|
from AST import InfixExpression, CallExpression
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
||||||
|
from AST import FunctionParameter
|
||||||
|
|
||||||
class PrecedenceType(Enum):
|
class PrecedenceType(Enum):
|
||||||
P_LOWEST = 0
|
P_LOWEST = 0
|
||||||
@@ -164,10 +165,9 @@ class Parser:
|
|||||||
if not self.__expect_peek(TokenType.LPAREN):
|
if not self.__expect_peek(TokenType.LPAREN):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
func_stmt.parameters = []
|
func_stmt.parameters = self.__parse_function_parameters()
|
||||||
|
|
||||||
|
|
||||||
if not self.__expect_peek(TokenType.RPAREN):
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not self.__expect_peek(TokenType.COLON):
|
if not self.__expect_peek(TokenType.COLON):
|
||||||
return None
|
return None
|
||||||
@@ -217,6 +217,38 @@ class Parser:
|
|||||||
|
|
||||||
return stmt
|
return stmt
|
||||||
|
|
||||||
|
def __parse_function_parameters(self) -> list[FunctionParameter]:
|
||||||
|
params: list[FunctionParameter] = []
|
||||||
|
|
||||||
|
if self.__peek_token_is(TokenType.RPAREN):
|
||||||
|
self.__next_token()
|
||||||
|
return params
|
||||||
|
|
||||||
|
self.__next_token()
|
||||||
|
|
||||||
|
first_param: FunctionParameter = FunctionParameter(name=self.current_token.literal)
|
||||||
|
if not self.__expect_peek(TokenType.COLON):
|
||||||
|
return None
|
||||||
|
self.__next_token()
|
||||||
|
first_param.value_type = self.current_token.literal
|
||||||
|
params.append(first_param)
|
||||||
|
|
||||||
|
while self.__peek_token_is(TokenType.COMMA):
|
||||||
|
self.__next_token()
|
||||||
|
self.__next_token()
|
||||||
|
|
||||||
|
param: FunctionParameter = FunctionParameter(name=self.current_token.literal)
|
||||||
|
if not self.__expect_peek(TokenType.COLON):
|
||||||
|
return None
|
||||||
|
self.__next_token()
|
||||||
|
param.value_type = self.current_token.literal
|
||||||
|
params.append(param)
|
||||||
|
|
||||||
|
if not self.__expect_peek(TokenType.RPAREN):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return params
|
||||||
|
|
||||||
def __parse_return_statement(self) -> ReturnStatement:
|
def __parse_return_statement(self) -> ReturnStatement:
|
||||||
stmt: ReturnStatement = ReturnStatement()
|
stmt: ReturnStatement = ReturnStatement()
|
||||||
|
|
||||||
@@ -311,12 +343,31 @@ class Parser:
|
|||||||
def __parse_call_expression(self, function: Expression) -> CallExpression:
|
def __parse_call_expression(self, function: Expression) -> CallExpression:
|
||||||
expr: CallExpression = CallExpression(function=function)
|
expr: CallExpression = CallExpression(function=function)
|
||||||
|
|
||||||
expr.arguments = [] # TODO
|
expr.arguments = self.__parse_expression_list(TokenType.RPAREN)
|
||||||
if not self.__expect_peek(TokenType.RPAREN):
|
|
||||||
return None
|
|
||||||
|
|
||||||
return expr
|
return expr
|
||||||
|
|
||||||
|
def __parse_expression_list(self, end: TokenType) -> list[Expression]:
|
||||||
|
e_list: list[Expression] = []
|
||||||
|
|
||||||
|
if self.__peek_token_is(end):
|
||||||
|
self.__next_token()
|
||||||
|
return e_list
|
||||||
|
|
||||||
|
self.__next_token()
|
||||||
|
|
||||||
|
e_list.append(self.__parse_expression(PrecedenceType.P_LOWEST))
|
||||||
|
|
||||||
|
while self.__peek_token_is(TokenType.COMMA):
|
||||||
|
self.__next_token()
|
||||||
|
self.__next_token()
|
||||||
|
|
||||||
|
e_list.append(self.__parse_expression(PrecedenceType.P_LOWEST))
|
||||||
|
|
||||||
|
if not self.__expect_peek(end):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return e_list
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Prefix Methods
|
# region Prefix Methods
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
test = Func(): Int {
|
add = Func(a: Int, b: Int): Int {
|
||||||
x: Int = 3;
|
return a + b;
|
||||||
return x + 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main = Func(): Int {
|
main = Func(): Int {
|
||||||
return test();
|
return add(2, 3);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user