From 87d6737a107fb9872204d18fe09e82ca5e92dfb8 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Wed, 8 Jun 2022 09:53:13 +0200 Subject: [PATCH] Working on euler using the compiler + squashing bugs --- .gitignore | 2 ++ ast.c | 95 --------------------------------------------------- ccodegen.cpp | 1 + euler.kl | 72 ++++++++++++++++++++++++++++++++++++++ main.cpp | 8 +++-- program.c | 29 ++++++++++++++++ typecheck.cpp | 11 +++--- 7 files changed, 116 insertions(+), 102 deletions(-) delete mode 100644 ast.c create mode 100644 euler.kl diff --git a/.gitignore b/.gitignore index c8a9632..5a6df94 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ *.txt *.4c *.bin + +*.c \ No newline at end of file diff --git a/ast.c b/ast.c deleted file mode 100644 index 0bd6115..0000000 --- a/ast.c +++ /dev/null @@ -1,95 +0,0 @@ - -function void -ast_remove(AST *node){ - AST_Parent *l = node->parent; - assert(l); - if (l->first==l->last){ - assert(node==l->last); - l->first=l->last=0; - } - else if (l->last==node){ - l->last=l->last->prev; - l->last->next=0; - } - else if (l->first==node){ - l->first=l->first->next; - l->first->prev=0; - } - else { - node->prev->next=node->next; - node->next->prev=node->prev; - } - node->parent=0; - node->prev=0; - node->next=0; -} - -function void -ast_push_last(AST_Parent *l, AST *node){ - if (l->first==0){ - l->first=l->last=node; - node->prev=0; - node->next=0; - } - else { - l->last->next=node; - node->prev=l->last; - node->next=0; - l->last=node; - } - node->parent=l; -} - -function void -ast_push_first(AST_Parent *l, AST *node){ - if(l->first == 0){ - l->first = l->last = node; - node->prev = 0; - node->next = 0; - } - else { - node->next = l->first; - l->first->prev = node; - node->prev = 0; - l->first = node; - } - node->parent = l; -} - -function void -ast_push_after(AST *in_list, AST *node){ - AST_Parent *parent = in_list->parent; - assert(parent); - assert(parent->first && parent->last); - - node->prev = in_list; - if(in_list == parent->last){ - in_list->next = node; - parent->last = node; - } - else { - node->next = in_list->next; - in_list->next = node; - node->next->prev = node; - } - node->parent=parent; -} - -function void -ast_push_before(AST *in_list, AST *node){ - AST_Parent *parent = in_list->parent; - assert(parent); - assert(parent->first && parent->last); - - node->next = in_list; - if(parent->first == in_list){ - in_list->prev = node; - parent->first = node; - } - else{ - node->prev = in_list->prev; - in_list->prev = node; - node->prev->next = node; - } - node->parent = parent; -} diff --git a/ccodegen.cpp b/ccodegen.cpp index 708c593..12a43a9 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -503,6 +503,7 @@ compile_string(String filecontent, String filename = "default_name"_s){ gen(R"==( #include #include +#include typedef int8_t S8; typedef int16_t S16; typedef int32_t S32; diff --git a/euler.kl b/euler.kl new file mode 100644 index 0000000..0184105 --- /dev/null +++ b/euler.kl @@ -0,0 +1,72 @@ + + +entry :: () + printf("\n") + euler1() + euler3() + +// @todo: Add more stats in the preview +euler1 :: () + end := 1000 + result := 0 + // @todo: for 0..1000(implicit i) and for i in 0..1000 + for i := 0, i < end, i++ + if i % 3 == 0 + result += i + else if i % 5 == 0 + result += i + printf("Euler1: %lld\n", result) + + +int_sqrt :: (s: S64): S64 + result := sqrt(cast(s: F64)) + return cast(result: S64) + +// https://en.wikipedia.org/wiki/Integer_square_root +int_sqrt1 :: (s: S64): S64 + x0 := s / 2 + + if x0 != 0 + x1 := ( x0 + s / x0 ) / 2 + for x1 < x0 + x0 = x1 + x1 = ( x0 + s / x0 ) / 2 + return x0 + else + return s + +euler3 :: () + n := 13195 + results: [32]S64 + results_len := 0 + + // First search all 2's + for n % 2 == 0 + results[results_len++] = 2 + n /= 2 + + print_int(int_sqrt(n)) + // Then search other primes, 3, 5, 7 etc. + for i := 3, i <= int_sqrt(n), i += 2 + for n % i == 0 + results[results_len++] = i + n /= i + + printf("Euler3: ") + + is_correct: S64 = 1 + for i := 0, i < results_len, i++ + is_correct = is_correct * results[i] + printf("%lld ", results[i]) + + printf(":: %lld", is_correct) + + + + + +print_int :: (i: S64) + printf("%lld ", i) + +#foreign sqrt :: (v: F64): F64 +#foreign printf :: (str: String, ...) \ No newline at end of file diff --git a/main.cpp b/main.cpp index 6a14377..8980be8 100644 --- a/main.cpp +++ b/main.cpp @@ -77,10 +77,10 @@ Expr: @todo -[ ] - Arrays with size passed [ ] - Switch -[ ] - Values inited to 0 by default [ ] - Add c string +[ ] - Some way to take slice of data +[ ] - slices should be properly displayed in debugger [ ] - Comma notation when declaring variables thing1, thing2: S32 [ ] - Array of inferred size @@ -114,6 +114,8 @@ Expr: [x] - Emitting #line [x] - Making sure debugger works [x] - We need ++ -- operators +[x] - Arrays with size passed +[x] - Values inited to 0 by default [x] - Some way to call foreign functions [x] - We are parsing wrong here: (t.str=(&string_to_lex.str)[i]); [x] - Test new operators, add constant eval for them @@ -180,7 +182,7 @@ int main(int argument_count, char **arguments){ - emit_line_directives = false; + emit_line_directives = true; if(argument_count > 1){ Scratch scratch; String name = string_fmt(scratch, "%s.kl", arguments[1]); diff --git a/program.c b/program.c index c08bdc0..23a78bf 100644 --- a/program.c +++ b/program.c @@ -35,7 +35,10 @@ int main(){ entry(); } +#line 0 "program.kl" +#line 1 +#line 3 typedef struct Token{ U8 kind; U8 *str; @@ -44,40 +47,66 @@ typedef struct Token{ Number = 0, };*/ }Token; +#line 12 String kind_name(U8 kind){ + #line 15 if((kind==0)){ + #line 14 return LIT(""); } else{ + #line 16 return LIT(""); } } +#line 18 Bool is_numeric(U8 c){ + #line 19 Bool result = ((c>=48)&&(c<=57)); + #line 20 return result; } +#line 22 void print_tokens(Slice tokens){ + #line 23 for(S64 i = 0;(ilen), t->str); } } +#line 27 void entry(){ + #line 28 String string_to_lex = LIT("Identifier 2425525 Not_Number"); + #line 29 Slice token_array = (Slice){32, (Token [32]){}}; + #line 30 S64 token_count = 0; + #line 32 Token t = {}; + #line 33 for(S64 i = 0;(itypespec); Ast_Resolved_Type *original_type = expr.type; + // @todo: cleanup, probably just want one big if + // @todo: factor this into a function for easier search + switch(expr.type->kind){ case TYPE_POINTER:{ if(is_pointer(type)) @@ -773,7 +776,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res expr.type = type; else if(is_float(type)){ expr.value.type = type; - expr.value.f64_val = bigint_as_float(&expr.big_int_val); // @leak + if(expr.is_const) expr.value.f64_val = bigint_as_float(&expr.big_int_val); // @leak } else goto failure; } break; case TYPE_F32: case TYPE_F64: { @@ -781,15 +784,15 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res expr.type = type; } else if(is_int(type)){ - expr.value.big_int_val = bigint_s64((S64)expr.value.f64_val); // @todo: What to do here??? + if(expr.is_const) expr.value.big_int_val = bigint_s64((S64)expr.value.f64_val); // @todo: What to do here??? expr.type = type; } else goto failure; - } + } break; default: failure: parsing_error(node->pos, "Failed to cast from %s to %s", docname(expr.type), docname(type));; } if(original_type != type) assert(expr.type == type); - check_value_bounds(node->pos, &expr.value); + if(expr.is_const) check_value_bounds(node->pos, &expr.value); return expr; BREAK(); }