Skip to content

Commit

Permalink
fix(parser): negative numbers are converted to a single literal
Browse files Browse the repository at this point in the history
  • Loading branch information
JaDogg committed Apr 6, 2024
1 parent 79d1499 commit 24ed1c9
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 154 deletions.
270 changes: 130 additions & 140 deletions compiler/carpntr/main.yaka.c

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions compiler/src/ast/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#pragma ide diagnostic ignored "misc-no-recursion"
// parser.cpp
#include "ast/parser.h"
#include "compiler/literal_utils.h"
#include "tokenizer/block_analyzer.h"
#include "utilities/cpp_util.h"
#include "yaksha_lisp/macro_processor.h"
Expand Down Expand Up @@ -186,9 +187,60 @@ expr *parser::factor() {
return ex;
}
expr *parser::unary() {
// TODO if it is - token and next is a number literal
// then we can convert it to a negative number literal
// and remove the unary operator
if (match({token_type::SUB, token_type::KEYWORD_NOT, token_type::TILDE})) {
auto opr = previous();
expr *right = unary();
// optimize - then num -> -num
if (opr->type_ == token_type::SUB &&
right->get_type() == ast_type::EXPR_LITERAL) {
auto lit = dynamic_cast<literal_expr *>(right);
if (lit->literal_token_->type_ == token_type::FLOAT_NUMBER ||
lit->literal_token_->type_ == token_type::DOUBLE_NUMBER ||
lit->literal_token_->type_ == token_type::INTEGER_DECIMAL_8 ||
lit->literal_token_->type_ == token_type::INTEGER_HEX_8 ||
lit->literal_token_->type_ == token_type::INTEGER_OCT_8 ||
lit->literal_token_->type_ == token_type::INTEGER_BIN_8 ||
lit->literal_token_->type_ == token_type::INTEGER_DECIMAL_16 ||
lit->literal_token_->type_ == token_type::INTEGER_HEX_16 ||
lit->literal_token_->type_ == token_type::INTEGER_OCT_16 ||
lit->literal_token_->type_ == token_type::INTEGER_BIN_16 ||
lit->literal_token_->type_ == token_type::INTEGER_DECIMAL ||
lit->literal_token_->type_ == token_type::INTEGER_HEX ||
lit->literal_token_->type_ == token_type::INTEGER_OCT ||
lit->literal_token_->type_ == token_type::INTEGER_BIN ||
lit->literal_token_->type_ == token_type::INTEGER_DECIMAL_64 ||
lit->literal_token_->type_ == token_type::INTEGER_HEX_64 ||
lit->literal_token_->type_ == token_type::INTEGER_OCT_64 ||
lit->literal_token_->type_ == token_type::INTEGER_BIN_64) {
auto lit_tok = lit->literal_token_;
auto converted = convert_literal(lit_tok->type_, lit_tok);
if (!converted.error_.empty()) {
throw error(lit_tok, converted.error_);
}
auto bits = get_bits(lit_tok->type_);
auto new_token_string = converted.decimal_string_;
// if it is a negative number, make it positive
if (new_token_string[0] == '-') {
lit_tok->token_ = new_token_string.substr(1);
} else {// make it negative
lit_tok->token_ = "-" + new_token_string;
}
if (bits == 32) {
lit_tok->type_ = token_type::INTEGER_DECIMAL;
} else if (bits == 64) {
lit_tok->type_ = token_type::INTEGER_DECIMAL_64;
} else if (bits == 16) {
lit_tok->type_ = token_type::INTEGER_DECIMAL_16;
} else if (bits == 8) {
lit_tok->type_ = token_type::INTEGER_DECIMAL_8;
}
// else it is a float / double, keep as is
return right;
}
}
return pool_.c_unary_expr(opr, right);
}
return fncall();
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/compiler/literal_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ bool can_fit_in_bits_unsigned(std::uintmax_t number, std::size_t bits) {
}
return false;
}
std::size_t get_bits(token_type token_type_val) {
std::size_t yaksha::get_bits(token_type token_type_val) {
switch (token_type_val) {
case token_type::INTEGER_BIN_8:
case token_type::UINTEGER_BIN_8:
Expand Down
1 change: 1 addition & 0 deletions compiler/src/compiler/literal_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace yaksha {
std::string error_{};
std::string decimal_string_{};
};
std::size_t get_bits(token_type type);
literal_conversion_result convert_literal(token_type token_type_val,
token *literal_token);
}// namespace yaksha
Expand Down
2 changes: 1 addition & 1 deletion compiler/test_data/compiler_tests/sort_test.yaka.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int32_t yy__main()
yk__arrput(yy__x, INT32_C(30));
yk__arrput(yy__x, INT32_C(10));
yk__arrput(yy__x, INT32_C(40));
yk__arrput(yy__x, (-(INT32_C(1))));
yk__arrput(yy__x, INT32_C(-1));
yk__arrput(yy__x, INT32_C(20));
yk__printlnstr("before:");
yk__printstr("len=");
Expand Down
14 changes: 7 additions & 7 deletions compiler/test_data/document_samples/factorial.yaka.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ void yy__console_set_color(int32_t nn__c)
{
if (nn__c == 0) { // rewind
yk__set_colour(YK__CONSOLE_REWIND);
} else if (nn__c == 1) { // red
} else if (nn__c == 1) { // red
yk__set_colour(YK__CONSOLE_RED);
} else if (nn__c == 2) { // green
} else if (nn__c == 2) { // green
yk__set_colour(YK__CONSOLE_GREEN);
} else if (nn__c == 3) { // white
} else if (nn__c == 3) { // white
yk__set_colour(YK__CONSOLE_WHITE);
} else if (nn__c == 4) { // blue
} else if (nn__c == 4) { // blue
yk__set_colour(YK__CONSOLE_BLUE);
} else if (nn__c == 5) { // purple
} else if (nn__c == 5) { // purple
yk__set_colour(YK__CONSOLE_PURPLE);
} else if (nn__c == 6) { // yellow
} else if (nn__c == 6) { // yellow
yk__set_colour(YK__CONSOLE_YELLOW);
} else if (nn__c == 7) { // cyan
} else if (nn__c == 7) { // cyan
yk__set_colour(YK__CONSOLE_CYAN);
};
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/test_data/document_samples/notes.yaka.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ bool yy__i2s(int32_t yy__x, uint8_t* yy__target)
yy__clear_buf(yy__target);
int32_t yy__pos = INT32_C(0);
int32_t yy__y = yy__x;
if ((yy__x > INT32_C(999999999)) || (yy__x < (-(INT32_C(99999999)))))
if ((yy__x > INT32_C(999999999)) || (yy__x < INT32_C(-99999999)))
{
yy__target[INT32_C(0)] = ((uint8_t)(((yk__sds)yy__charset)[INT32_C(10)]));
return false;
}
if (yy__x < INT32_C(0))
{
yy__y *= (-(INT32_C(1)));
yy__y *= INT32_C(-1);
yy__target[yy__pos] = ((uint8_t)(((yk__sds)yy__charset)[INT32_C(10)]));
}
else
Expand Down
4 changes: 2 additions & 2 deletions compiler/test_data/document_samples/snake_w4.yaka.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void yy__snake_up(struct yy__Snake* yy__snake)
if (yy__snake->yy__direction->yy__y == INT16_C(0))
{
yy__snake->yy__direction->yy__x = INT16_C(0);
yy__snake->yy__direction->yy__y = (-(INT16_C(1)));
yy__snake->yy__direction->yy__y = INT16_C(-1);
}
return;
}
Expand All @@ -166,7 +166,7 @@ void yy__snake_left(struct yy__Snake* yy__snake)
{
if (yy__snake->yy__direction->yy__x == INT16_C(0))
{
yy__snake->yy__direction->yy__x = (-(INT16_C(1)));
yy__snake->yy__direction->yy__x = INT16_C(-1);
yy__snake->yy__direction->yy__y = INT16_C(0);
}
return;
Expand Down
2 changes: 1 addition & 1 deletion compiler/test_data/sample_negative_numbers.yaka.ast.l
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
(let a:int (- 10))
(let a:int -10)

0 comments on commit 24ed1c9

Please sign in to comment.