Skip to content

Commit

Permalink
support void functions
Browse files Browse the repository at this point in the history
  • Loading branch information
omaraflak committed Sep 7, 2023
1 parent 2a46202 commit 1db6e5c
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/banana_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ TEST(Function, NoParameters) {
EXPECT_EQ("true\n", exe("int sayHello() { print true; return 1; } sayHello();"));
}

TEST(Function, Void) {
EXPECT_EQ("true\n", exe("void hello() { print true; } hello();"));
}

TEST(Function, ParametersConversion) {
EXPECT_EQ("11\n", exe("long add(long x, long y) { return x + y; } int x = add(5, 6); print x;"));
EXPECT_EQ("A\n", exe("long num() { return 65; } char z = num(); print z;"));
Expand Down
20 changes: 11 additions & 9 deletions src/lib/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,21 +280,23 @@ FunctionNode::FunctionNode(const bool& is_main) : AbstractSyntaxTree() {
}

void FunctionNode::write(std::vector<const Instruction*>& instructions) {
JumpInstruction* jump = nullptr;
if (!is_main) {
jump = new JumpInstruction();
instructions.push_back(jump);
if (is_main) {
AbstractSyntaxTree::write(instructions);
for (auto parameter : parameters) {
instructions.push_back(new StoreInstruction(parameter->get_address()));
}
body->write(instructions);
return;
}

JumpInstruction* jump = jump = new JumpInstruction();
instructions.push_back(jump);
AbstractSyntaxTree::write(instructions);
for (auto parameter : parameters) {
instructions.push_back(new StoreInstruction(parameter->get_address()));
}
body->write(instructions);

if (!is_main) {
jump->set_address(ast::count_bytes(instructions));
}
instructions.push_back(new RetInstruction(0));
jump->set_address(ast::count_bytes(instructions));
}

std::vector<std::shared_ptr<const VariableNode>> FunctionNode::get_parameters() const {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class LiteralNode: public AbstractSyntaxTree {

namespace ast {
enum AstVarType {
BOOL, CHAR, INT, LONG,
BOOL, CHAR, INT, LONG, VOID
};
}

Expand Down
9 changes: 8 additions & 1 deletion src/lib/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const std::map<TokenType, ast::AstVarType> TOKEN_TO_AST = {
{TOKEN_CHAR, ast::CHAR},
{TOKEN_INT, ast::INT},
{TOKEN_LONG, ast::LONG},
{TOKEN_VOID, ast::VOID},
};

const std::map<ast::AstVarType, TokenType> AST_TO_TOKEN = maputils::reverse(TOKEN_TO_AST);
Expand All @@ -42,11 +43,16 @@ const std::set<TokenType> TYPES = {
TOKEN_BOOL, TOKEN_CHAR, TOKEN_INT, TOKEN_LONG
};

const std::set<TokenType> RETURN_TYPES = {
TOKEN_BOOL, TOKEN_CHAR, TOKEN_INT, TOKEN_LONG, TOKEN_VOID
};

const std::map<TokenType, std::string> TYPE_NAME = {
{TOKEN_BOOL, "bool"},
{TOKEN_CHAR, "char"},
{TOKEN_INT, "int"},
{TOKEN_LONG, "long"},
{TOKEN_VOID, "void"},
};

const std::map<cinterface::ArgType, std::string> C_TYPE_NAME = {
Expand All @@ -61,6 +67,7 @@ const std::map<ast::AstVarType, std::string> AST_TYPE_NAME = {
{ast::CHAR, "char"},
{ast::INT, "int"},
{ast::LONG, "long"},
{ast::VOID, "void"},
};

const std::map<cinterface::ArgType, ast::AstVarType> C_TYPE_TO_AST_TYPE = {
Expand Down Expand Up @@ -642,7 +649,7 @@ std::shared_ptr<AbstractSyntaxTree> statement(Parser& parser) {
if (match_sequence(parser, {TYPES, {TOKEN_IDENTIFIER}, {TOKEN_EQUAL}})) {
return var_statement(parser, previous(parser, 3), previous(parser, 2));
}
if (match_sequence(parser, {TYPES, {TOKEN_IDENTIFIER}, {TOKEN_LEFT_PAREN}})) {
if (match_sequence(parser, {RETURN_TYPES, {TOKEN_IDENTIFIER}, {TOKEN_LEFT_PAREN}})) {
return fun_statement(parser, previous(parser, 3), previous(parser, 2));
}
if (match_sequence(parser, {{TOKEN_IDENTIFIER}, {TOKEN_LEFT_PAREN}})) {
Expand Down
9 changes: 9 additions & 0 deletions src/lib/scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,15 @@ std::vector<Token> scanner::scan(const std::string& code) {
tokens.push_back(create_token(TOKEN_IDENTIFIER, scanner));
}
break;
case 'v':
if (match_string(scanner, "void", /* keyword */ true)) {
scanner.current += 4;
tokens.push_back(create_token(TOKEN_VOID, scanner));
} else {
scanner.current = match_identifier(scanner);
tokens.push_back(create_token(TOKEN_IDENTIFIER, scanner));
}
break;
case '"': {
int quote = match_quote(scanner);
if (quote == -1) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ enum TokenType {
TOKEN_RETURN, TOKEN_IF, TOKEN_ELSE, TOKEN_FOR,
TOKEN_WHILE, TOKEN_AND, TOKEN_OR, TOKEN_PRINT,
TOKEN_BOOL, TOKEN_CHAR, TOKEN_INT, TOKEN_LONG,
TOKEN_TRUE, TOKEN_FALSE, TOKEN_AT_NATIVE
TOKEN_TRUE, TOKEN_FALSE, TOKEN_VOID, TOKEN_AT_NATIVE
};

struct Token{
Expand Down

0 comments on commit 1db6e5c

Please sign in to comment.