Working on euler using the compiler + squashing bugs

This commit is contained in:
Krzosa Karol
2022-06-08 09:53:13 +02:00
parent 5744da8899
commit 87d6737a10
7 changed files with 116 additions and 102 deletions

2
.gitignore vendored
View File

@@ -4,3 +4,5 @@
*.txt
*.4c
*.bin
*.c

95
ast.c
View File

@@ -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;
}

View File

@@ -503,6 +503,7 @@ compile_string(String filecontent, String filename = "default_name"_s){
gen(R"==(
#include <stdint.h>
#include <stdio.h>
#include <math.h>
typedef int8_t S8;
typedef int16_t S16;
typedef int32_t S32;

72
euler.kl Normal file
View File

@@ -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, ...)

View File

@@ -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]);

View File

@@ -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("<Number>");
}
else{
#line 16
return LIT("<Unknown>");
}
}
#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;(i<tokens.len);(i++)){
#line 24
Token *t = (&(((Token *)tokens.data)[i]));
#line 25
printf("%d. %.*s", i, ((S32 )t->len), 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;(i<string_to_lex.len);i+=1){
#line 34
if(is_numeric((string_to_lex.str[i]))){
#line 35
t.kind=0;
#line 36
t.str=(&(string_to_lex.str[i]));
#line 37
t.len=i;
#line 38
for(;is_numeric((string_to_lex.str[i]));){
#line 39
i+=1;
}
#line 40
t.len=(i-t.len);
#line 41
(((Token *)token_array.data)[(token_count++)])=t;
}
}
#line 42
print_tokens(token_array);
}

View File

@@ -758,6 +758,9 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
Ast_Resolved_Type *type = resolve_typespec(node->typespec);
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();
}