Working on euler using the compiler + squashing bugs
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,3 +4,5 @@
|
||||
*.txt
|
||||
*.4c
|
||||
*.bin
|
||||
|
||||
*.c
|
||||
95
ast.c
95
ast.c
@@ -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;
|
||||
}
|
||||
@@ -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
72
euler.kl
Normal 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, ...)
|
||||
8
main.cpp
8
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]);
|
||||
|
||||
29
program.c
29
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("<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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user