Skip to content

Commit

Permalink
feat: function definition statement
Browse files Browse the repository at this point in the history
  • Loading branch information
SpideyZac committed May 25, 2024
1 parent e131f8b commit 10ebaef
Show file tree
Hide file tree
Showing 3 changed files with 296 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn main() {
}
}

let contents = "HAI 1.2,IM IN loop UPPIN YR x,VISIBLE \"HA HA\",IM OUTTA YR loop,KTHXBYE";
let contents = "HAI 1.2,HOW IZ I sum ITZ NUMBER YR a ITZ NUMBER AN YR b ITZ NUMBER,FOUND YR SUM OF a AN b,IF U SAY SO,KTHXBYE";

let mut l = l::Lexer::init(contents);
let tokens = l.get_tokens();
Expand Down
15 changes: 15 additions & 0 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub enum StatementNodeValueOption {
SwitchStatement(SwitchStatementNode),
GTFOStatement(TokenNode),
LoopStatement(LoopStatementNode),
ReturnStatement(ReturnStatementNode),
FunctionDefinitionStatement(FunctionDefinitionStatementNode),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -310,3 +312,16 @@ pub struct LoopStatementNode {
pub condition_expression: Option<ExpressionNode>,
pub statements: Vec<StatementNode>,
}

#[derive(Debug, Clone)]
pub struct ReturnStatementNode {
pub expression: ExpressionNode,
}

#[derive(Debug, Clone)]
pub struct FunctionDefinitionStatementNode {
pub identifier: TokenNode,
pub return_type: TokenNode,
pub arguments: Vec<(TokenNode, TokenNode)>,
pub statements: Vec<StatementNode>,
}
280 changes: 280 additions & 0 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,44 @@ impl<'a> Parser<'a> {
});
}

let return_statement = self.parse_return_statement();
if let Some(return_statement) = return_statement {
if !self.check_ending() {
self.next_level();
self.create_error(ParserError {
message: "Expected comma or newline to end statement",
token: self.peek(),
});
self.prev_level();
return None;
}

self.prev_level();
return Some(ast::StatementNode {
value: ast::StatementNodeValueOption::ReturnStatement(return_statement),
});
}

let function_definition_statement = self.parse_function_definition_statement();
if let Some(function_definition_statement) = function_definition_statement {
if !self.check_ending() {
self.next_level();
self.create_error(ParserError {
message: "Expected comma or newline to end statement",
token: self.peek(),
});
self.prev_level();
return None;
}

self.prev_level();
return Some(ast::StatementNode {
value: ast::StatementNodeValueOption::FunctionDefinitionStatement(
function_definition_statement,
),
});
}

let expression = self.parse_expression();
if let Some(expression) = expression {
if !self.check_ending() {
Expand Down Expand Up @@ -2554,4 +2592,246 @@ impl<'a> Parser<'a> {
statements,
})
}

pub fn parse_return_statement(&mut self) -> Option<ast::ReturnStatementNode> {
self.next_level();
let start = self.current;

if let None = self.special_consume("Word_FOUND") {
self.create_error(ParserError {
message: "Expected FOUND keyword to start return statement",
token: self.peek(),
});
return None;
}

if let None = self.special_consume("Word_YR") {
self.create_error(ParserError {
message: "Expected YR keyword to start return statement",
token: self.peek(),
});
self.reset(start);
return None;
}

let expression = self.parse_expression();
if let None = expression {
self.create_error(ParserError {
message: "Expected valid expression for return statement",
token: self.peek(),
});
self.reset(start);
return None;
}

self.prev_level();
Some(ast::ReturnStatementNode {
expression: expression.unwrap(),
})
}

pub fn parse_function_definition_statement(
&mut self,
) -> Option<ast::FunctionDefinitionStatementNode> {
self.next_level();
let start = self.current;

if let None = self.special_consume("Word_HOW") {
self.create_error(ParserError {
message: "Expected HOW keyword to start function definition",
token: self.peek(),
});
return None;
}

if let None = self.special_consume("Word_IZ") {
self.create_error(ParserError {
message: "Expected IZ keyword to start function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_I") {
self.create_error(ParserError {
message: "Expected I keyword to start function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let identifier = self.special_consume("Identifier");
if let None = identifier {
self.create_error(ParserError {
message: "Expected identifier for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_ITZ") {
self.create_error(ParserError {
message: "Expected ITZ keyword to start function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let return_type: ast::TokenNode;
if let Some(type_) = self.special_consume("Word_NUMBER") {
return_type = type_;
} else if let Some(type_) = self.special_consume("Word_NUMBAR") {
return_type = type_;
} else if let Some(type_) = self.special_consume("Word_YARN") {
return_type = type_;
} else if let Some(type_) = self.special_consume("Word_TROOF") {
return_type = type_;
} else if let Some(type_) = self.special_consume("Word_NOOB") {
return_type = type_;
} else {
self.create_error(ParserError {
message: "Expected valid return type for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let mut arguments = Vec::new();
while !self.is_at_end() {
if let None = self.special_consume("Word_YR") {
self.create_error(ParserError {
message: "Expected YR keyword for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let identifier = self.special_consume("Identifier");
if let None = identifier {
self.create_error(ParserError {
message: "Expected identifier for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_ITZ") {
self.create_error(ParserError {
message: "Expected ITZ keyword to start function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let type_: ast::TokenNode;
if let Some(type__) = self.special_consume("Word_NUMBER") {
type_ = type__;
} else if let Some(type__) = self.special_consume("Word_NUMBAR") {
type_ = type__;
} else if let Some(type__) = self.special_consume("Word_YARN") {
type_ = type__;
} else if let Some(type__) = self.special_consume("Word_TROOF") {
type_ = type__;
} else {
self.create_error(ParserError {
message: "Expected valid type for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

arguments.push((identifier.unwrap(), type_));

if self.special_check("Word_AN") {
self.special_consume("Word_AN");
} else {
break;
}
}

if !self.check_ending() {
self.create_error(ParserError {
message: "Expected newline or comma to end function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

let mut statements = Vec::new();
while !self.is_at_end() {
if self.special_check("Word_IF")
&& self.special_check_amount("Word_U", 1)
&& self.special_check_amount("Word_SAY", 2)
&& self.special_check_amount("Word_SO", 3)
{
break;
}

let statement = self.parse_statement();
if let None = statement {
self.create_error(ParserError {
message: "Expected valid statement for function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

statements.push(statement.unwrap());
}

if let None = self.special_consume("Word_IF") {
self.create_error(ParserError {
message: "Expected IF keyword to end function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_U") {
self.create_error(ParserError {
message: "Expected U keyword to end function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_SAY") {
self.create_error(ParserError {
message: "Expected SAY keyword to end function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

if let None = self.special_consume("Word_SO") {
self.create_error(ParserError {
message: "Expected SO keyword to end function definition",
token: self.peek(),
});
self.reset(start);
return None;
}

self.prev_level();
Some(ast::FunctionDefinitionStatementNode {
arguments,
identifier: identifier.unwrap(),
return_type,
statements,
})
}
}

0 comments on commit 10ebaef

Please sign in to comment.