Skip to content

Commit

Permalink
Added parser support for conjunctions, disjunctions, and comparison o…
Browse files Browse the repository at this point in the history
…perators.
  • Loading branch information
Goubermouche committed Jan 29, 2024
1 parent 07f51db commit 32a123b
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 161 deletions.
58 changes: 34 additions & 24 deletions source/abstract_syntax_tree/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,49 @@ namespace sigma::ast {

auto node_type::to_string() const->std::string {
switch(type) {
case UNKNOWN: return "UNKNOWN";
case UNKNOWN: return "UNKNOWN";

case VARIABLE_DECLARATION: return "VARIABLE_DECLARATION";
case FUNCTION_DECLARATION: return "FUNCTION_DECLARATION";
case NAMESPACE_DECLARATION: return "NAMESPACE_DECLARATION";
case VARIABLE_DECLARATION: return "VARIABLE_DECLARATION";
case FUNCTION_DECLARATION: return "FUNCTION_DECLARATION";
case NAMESPACE_DECLARATION: return "NAMESPACE_DECLARATION";

case FUNCTION_CALL: return "FUNCTION_CALL";
case RETURN: return "RETURN";
case FUNCTION_CALL: return "FUNCTION_CALL";
case RETURN: return "RETURN";

case SIZEOF: return "SIZEOF";
case SIZEOF: return "SIZEOF";

case BRANCH: return "BRANCH";
case CONDITIONAL_BRANCH: return "CONDITIONAL_BRANCH";
case BRANCH: return "BRANCH";
case CONDITIONAL_BRANCH: return "CONDITIONAL_BRANCH";

case ARRAY_ACCESS: return "ARRAY_ACCESS";
case VARIABLE_ACCESS: return "VARIABLE_ACCESS";
case ARRAY_ACCESS: return "ARRAY_ACCESS";
case VARIABLE_ACCESS: return "VARIABLE_ACCESS";

case STORE: return "STORE";
case LOAD: return "LOAD";
case STORE: return "STORE";
case LOAD: return "LOAD";

case OPERATOR_ADD: return "OPERATOR_ADD";
case OPERATOR_SUBTRACT: return "OPERATOR_SUBTRACT";
case OPERATOR_MULTIPLY: return "OPERATOR_MULTIPLY";
case OPERATOR_DIVIDE: return "OPERATOR_DIVIDE";
case OPERATOR_MODULO: return "OPERATOR_MODULO";
case OPERATOR_ADD: return "OPERATOR_ADD";
case OPERATOR_SUBTRACT: return "OPERATOR_SUBTRACT";
case OPERATOR_MULTIPLY: return "OPERATOR_MULTIPLY";
case OPERATOR_DIVIDE: return "OPERATOR_DIVIDE";
case OPERATOR_MODULO: return "OPERATOR_MODULO";

case CAST: return "CAST";
case OPERATOR_CONJUNCTION: return "OPERATOR_CONJUNCTION";
case OPERATOR_DISJUNCTION: return "OPERATOR_DISJUNCTION";

case NUMERICAL_LITERAL: return "NUMERICAL_LITERAL";
case CHARACTER_LITERAL: return "CHARACTER_LITERAL";
case STRING_LITERAL: return "STRING_LITERAL";
case BOOL_LITERAL: return "BOOL_LITERAL";
case NULL_LITERAL: return "NULL_LITERAL";
case OPERATOR_GREATER_THAN: return "OPERATOR_GREATER_THAN";
case OPERATOR_LESS_THAN: return "OPERATOR_LESS_THAN";
case OPERATOR_GREATER_THAN_OR_EQUAL: return "OPERATOR_GREATER_THAN_OR_EQUAL";
case OPERATOR_LESS_THAN_OR_EQUAL: return "OPERATOR_LESS_THAN_OR_EQUAL";
case OPERATOR_EQUAL: return "OPERATOR_EQUAL";
case OPERATOR_NOT_EQUAL: return "OPERATOR_NOT_EQUAL";

case CAST: return "CAST";

case NUMERICAL_LITERAL: return "NUMERICAL_LITERAL";
case CHARACTER_LITERAL: return "CHARACTER_LITERAL";
case STRING_LITERAL: return "STRING_LITERAL";
case BOOL_LITERAL: return "BOOL_LITERAL";
case NULL_LITERAL: return "NULL_LITERAL";

default: PANIC("to_string() not implemented for node '{}'", static_cast<u16>(type));
}
Expand Down
10 changes: 10 additions & 0 deletions source/abstract_syntax_tree/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ namespace sigma::ast {
OPERATOR_DIVIDE,
OPERATOR_MODULO,

OPERATOR_CONJUNCTION,
OPERATOR_DISJUNCTION,

OPERATOR_GREATER_THAN,
OPERATOR_LESS_THAN,
OPERATOR_GREATER_THAN_OR_EQUAL,
OPERATOR_LESS_THAN_OR_EQUAL,
OPERATOR_EQUAL,
OPERATOR_NOT_EQUAL,

// cast
// children[0] = value
CAST,
Expand Down
9 changes: 2 additions & 7 deletions source/compiler/compiler/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,16 @@ namespace sigma {
// TODO: the entire frontend can be multi-threaded
frontend_context frontend;

// generate tokens
// generate the AST
TRY(const std::string file, utility::fs::file<std::string>::load(m_description.path));
TRY(tokenizer::tokenize(file, &m_description.path, frontend));
// TRY(parser::parse(frontend));

frontend.print_tokens();
return SUCCESS;
TRY(parser::parse(frontend));

// backend
// at this point we want to merge all frontend contexts into the backend context
backend_context backend(frontend.syntax, m_description.target);
frontend.syntax.print_ast();

return SUCCESS;

// run analysis on the generated AST
TRY(type_checker::type_check(backend));
TRY(ir_translator::translate(backend));
Expand Down
5 changes: 3 additions & 2 deletions source/compiler/test/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

// - cleanup ir gen alignment sizes (u64 vs u32 vs u16)

i32 main() {
if(true && false || true) {}
// CHECK:
// - bool b = 100 > 200;

i32 main() {
ret 0;
}
54 changes: 48 additions & 6 deletions source/parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,20 +549,62 @@ namespace sigma {
}

auto parser::parse_logical_conjunction() -> parse_result {
TRY(const handle<ast::node> left_node, parse_logical_disjunction());
// TODO
TRY(handle<ast::node> left_node, parse_logical_disjunction());

while(m_tokens.get_current_token() == token_type::CONJUNCTION) {
m_tokens.next(); // prime the term
TRY(const handle<ast::node> right_node, parse_logical_disjunction());

left_node = create_binary_expression(ast::node_type::OPERATOR_CONJUNCTION, left_node, right_node);
}

return left_node;
}

auto parser::parse_logical_disjunction() -> parse_result {
TRY(const handle<ast::node> left_node, parse_comparison());
// TODO
TRY(handle<ast::node> left_node, parse_comparison());

while(m_tokens.get_current_token() == token_type::DISJUNCTION) {
m_tokens.next(); // prime the term
TRY(const handle<ast::node> right_node, parse_comparison());

left_node = create_binary_expression(ast::node_type::OPERATOR_DISJUNCTION, left_node, right_node);
}

return left_node;
}

auto parser::parse_comparison() -> parse_result {
TRY(const handle<ast::node> left_node, parse_term());
// TODO
TRY(handle<ast::node> left_node, parse_term());
token operation = m_tokens.get_current_token();

while (
operation == token_type::GREATER_THAN_OR_EQUAL ||
operation == token_type::LESS_THAN_OR_EQUAL ||
operation == token_type::GREATER_THAN ||
operation == token_type::NOT_EQUALS ||
operation == token_type::LESS_THAN ||
operation == token_type::EQUALS
) {
m_tokens.next(); // prime the comparison

TRY(const handle<ast::node> right_node, parse_term());
ast::node_type operator_type = ast::node_type::UNKNOWN;

switch (operation) {
case token_type::GREATER_THAN_OR_EQUAL: operator_type = ast::node_type::OPERATOR_GREATER_THAN_OR_EQUAL; break;
case token_type::LESS_THAN_OR_EQUAL: operator_type = ast::node_type::OPERATOR_LESS_THAN_OR_EQUAL; break;
case token_type::GREATER_THAN: operator_type = ast::node_type::OPERATOR_GREATER_THAN; break;
case token_type::NOT_EQUALS: operator_type = ast::node_type::OPERATOR_NOT_EQUAL; break;
case token_type::LESS_THAN: operator_type = ast::node_type::OPERATOR_LESS_THAN; break;
case token_type::EQUALS: operator_type = ast::node_type::OPERATOR_EQUAL; break;
default: PANIC("unhandled term case for token '{}'", operation.to_string());
}

left_node = create_binary_expression(operator_type, left_node, right_node);
operation = m_tokens.get_current_token();
}

return left_node;
}

Expand Down
116 changes: 60 additions & 56 deletions source/tokenizer/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,70 +39,74 @@ namespace sigma {

auto token::to_string() const -> std::string {
switch (type) {
case token_type::UNKNOWN: return "UNKNOWN";
case token_type::LEFT_PARENTHESIS: return "(";
case token_type::RIGHT_PARENTHESIS: return ")";
case token_type::LEFT_BRACE: return "{";
case token_type::RIGHT_BRACE: return "}";
case token_type::LEFT_BRACKET: return "[";
case token_type::RIGHT_BRACKET: return "]";
case token_type::COMMA: return ",";
case token_type::SEMICOLON: return ";";
case token_type::SINGLE_QUOTE: return "'";
case token_type::DOUBLE_QUOTE: return "\"";
case token_type::MODULO: return "%";
case token_type::SLASH: return "/";
case token_type::ASTERISK: return "*";
case token_type::PLUS_SIGN: return "+";
case token_type::MINUS_SIGN: return "-";
case token_type::EQUALS_SIGN: return "=";
case token_type::COLON: return ":";
case token_type::LESS_THAN: return "<";
case token_type::GREATER_THAN: return ">";

case token_type::CONJUNCTION: return "&&";
case token_type::DISJUNCTION: return "||";
case token_type::INLINE_COMMENT: return "//";
case token_type::UNKNOWN: return "UNKNOWN";
case token_type::LEFT_PARENTHESIS: return "(";
case token_type::RIGHT_PARENTHESIS: return ")";
case token_type::LEFT_BRACE: return "{";
case token_type::RIGHT_BRACE: return "}";
case token_type::LEFT_BRACKET: return "[";
case token_type::RIGHT_BRACKET: return "]";
case token_type::COMMA: return ",";
case token_type::SEMICOLON: return ";";
case token_type::SINGLE_QUOTE: return "'";
case token_type::DOUBLE_QUOTE: return "\"";
case token_type::MODULO: return "%";
case token_type::SLASH: return "/";
case token_type::ASTERISK: return "*";
case token_type::PLUS_SIGN: return "+";
case token_type::MINUS_SIGN: return "-";
case token_type::EQUALS_SIGN: return "=";
case token_type::COLON: return ":";
case token_type::LESS_THAN: return "<";
case token_type::GREATER_THAN: return ">";
case token_type::LESS_THAN_OR_EQUAL: return "<=";
case token_type::GREATER_THAN_OR_EQUAL: return ">=";
case token_type::EQUALS: return "==";
case token_type::NOT_EQUALS: return "!=";

case token_type::CONJUNCTION: return "&&";
case token_type::DISJUNCTION: return "||";
case token_type::INLINE_COMMENT: return "//";

// default type keywords
case token_type::I8: return "I8";
case token_type::I16: return "I16";
case token_type::I32: return "I32";
case token_type::I64: return "I64";
case token_type::U8: return "U8";
case token_type::U16: return "U16";
case token_type::U32: return "U32";
case token_type::U64: return "U64";

case token_type::BOOL: return "BOOL";
case token_type::VOID: return "VOID";
case token_type::CHAR: return "CHAR";
case token_type::I8: return "I8";
case token_type::I16: return "I16";
case token_type::I32: return "I32";
case token_type::I64: return "I64";
case token_type::U8: return "U8";
case token_type::U16: return "U16";
case token_type::U32: return "U32";
case token_type::U64: return "U64";

case token_type::BOOL: return "BOOL";
case token_type::VOID: return "VOID";
case token_type::CHAR: return "CHAR";

// control flow
case token_type::RET: return "RET";
case token_type::IF: return "IF";
case token_type::ELSE: return "ELSE";
case token_type::RET: return "RET";
case token_type::IF: return "IF";
case token_type::ELSE: return "ELSE";

// other keywords
case token_type::NAMESPACE: return "NAMESPACE";
case token_type::CAST: return "CAST";
case token_type::SIZEOF: return "SIZEOF";
case token_type::NAMESPACE: return "NAMESPACE";
case token_type::CAST: return "CAST";
case token_type::SIZEOF: return "SIZEOF";

// literals
case token_type::SIGNED_LITERAL: return "SIGNED_LITERAL";
case token_type::UNSIGNED_LITERAL: return "UNSIGNED_LITERAL";
case token_type::F32_LITERAL: return "F32_LITERAL";
case token_type::F64_LITERAL: return "F64_LITERAL";
case token_type::HEXADECIMAL_LITERAL: return "HEXADECIMAL_LITERAL";
case token_type::BINARY_LITERAL: return "BINARY_LITERAL";
case token_type::STRING_LITERAL: return "STRING_LITERAL";
case token_type::CHARACTER_LITERAL: return "CHARACTER_LITERAL";
case token_type::BOOL_LITERAL_TRUE: return "BOOL_LITERAL_TRUE";
case token_type::BOOL_LITERAL_FALSE: return "BOOL_LITERAL_FALSE";
case token_type::NULL_LITERAL: return "NULL";

case token_type::IDENTIFIER: return "IDENTIFIER";
case token_type::END_OF_FILE: return "EOF";
case token_type::SIGNED_LITERAL: return "SIGNED_LITERAL";
case token_type::UNSIGNED_LITERAL: return "UNSIGNED_LITERAL";
case token_type::F32_LITERAL: return "F32_LITERAL";
case token_type::F64_LITERAL: return "F64_LITERAL";
case token_type::HEXADECIMAL_LITERAL: return "HEXADECIMAL_LITERAL";
case token_type::BINARY_LITERAL: return "BINARY_LITERAL";
case token_type::STRING_LITERAL: return "STRING_LITERAL";
case token_type::CHARACTER_LITERAL: return "CHARACTER_LITERAL";
case token_type::BOOL_LITERAL_TRUE: return "BOOL_LITERAL_TRUE";
case token_type::BOOL_LITERAL_FALSE: return "BOOL_LITERAL_FALSE";
case token_type::NULL_LITERAL: return "null";

case token_type::IDENTIFIER: return "IDENTIFIER";
case token_type::END_OF_FILE: return "EOF";
}

NOT_IMPLEMENTED();
Expand Down
Loading

0 comments on commit 32a123b

Please sign in to comment.