diff --git a/ccodegen.cpp b/ccodegen.cpp index 0504b05..3f100fa 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -405,7 +405,30 @@ compile_string(String filecontent, String filename = "default_name"_s){ gen(R"==( - // Generated + +#include +typedef int8_t S8; +typedef int16_t S16; +typedef int32_t S32; +typedef int64_t S64; +typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; +typedef uint64_t U64; +typedef S8 B8; +typedef S16 B16; +typedef S32 B32; +typedef S64 B64; +typedef U64 SizeU; +typedef S64 SizeI; +typedef float F32; +typedef double F64; + +struct String{ + U8 *str; + S64 len; +}; + )=="); F64 resolve_begin = os_time(); diff --git a/lexer.kl b/lexer.kl deleted file mode 100644 index 28b1f0d..0000000 --- a/lexer.kl +++ /dev/null @@ -1,16 +0,0 @@ -/* -Lex_Stream :: struct - stream: String - offset: Int - -lexc :: (s: *Lex_Stream): String // @todo U8 U S - return s.stream + s.offset // s.offset @todo Actual string support - -main :: () - string_to_lex := "Identifier 2425525 Not_Number" - s := Lex_Stream(stream=string_to_lex) - - for inf:=0, inf, inf // @todo for - pass - -*/ \ No newline at end of file diff --git a/main.cpp b/main.cpp index 34eceaa..ca875b0 100644 --- a/main.cpp +++ b/main.cpp @@ -32,23 +32,26 @@ For now I don't thing it should be overloadable. ------------------------------------------------------------------------------- @todo -[ ] - Operators: Bit negation, Not +[ ] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need big int [ ] - Compiling and running a program [ ] - Passing down program to compile through command line [ ] - More for loop variations -[ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree -[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative [ ] - Write up on order independent declarations [ ] - Switch -[ ] - More basic types + +[ ] - Comma notation when declaring variables thing1, thing2: S32 [ ] - Array of inferred size [ ] - Add single line lambda expressions [ ] - Ternary operator + +[ ] - Field access rewrite [ ] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix -[ ] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need [ ] - Order independent constants in structs -[ ] - Can you even have recursive lambdas in structs, other recursive stuff +[ ] - Fix recursive lambdas in structs +[ ] - Fixing access to functions/structs, in C we cant have functons inside of structs / functions so we need to rewrite the tree + [ ] - Casting to basic types by call S64(x) +[ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative [ ] - Type aliases :: should probably be strictly typed, but assigning constant values should work @ideas @@ -59,16 +62,19 @@ For now I don't thing it should be overloadable. @donzo [x] - Test new operators, add constant eval for them [x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression +[x] - More basic types [x] - Add basic support for floats [x] - Add basic setup for new type system [x] - Access through struct names to constants Arena.CONSTANT [x] - Enums [x] - Initial for loop [x] - Enum . access to values +[x] - Infinite for loop [x] - in new typesystem: Fix calls, fix all example programs [x] - Fix arithmetic operations in new type system [x] - Init statements, different kinds [+=] [-=] etc. [x] - Struct calls +[x] - Operators: Bit negation, Not [x] - Default values in calls [x] - Resolving calls with default values [x] - Pass statement @@ -119,11 +125,11 @@ int main(){ result = compile_file("new_types.kl"_s); printf("%s", result.str); - // result = compile_file("lexer.kl"_s); - // FILE *f = fopen("program.c", "w"); - // assert(f); - // fprintf(f, "%.*s", (int)result.len, result.str); - // fclose(f); + result = compile_file("program.kl"_s); + FILE *f = fopen("program.c", "w"); + assert(f); + fprintf(f, "%.*s", (int)result.len, result.str); + fclose(f); __debugbreak(); } diff --git a/new_parse.cpp b/new_parse.cpp index d39aefe..769afcb 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -193,16 +193,21 @@ parse_block(){ } else if(token_match_keyword(keyword_for)){ - Ast_Expr *expr_first = parse_expr(); - Ast_Expr *init = parse_init_stmt(expr_first); - + Ast_Expr *init = 0; Ast_Expr *cond = 0; Ast_Expr *iter = 0; - if(token_match(TK_Comma)){ - cond = parse_expr(); + + if(!token_is(OPEN_SCOPE)){ + Ast_Expr *expr_first = parse_expr(); + init = parse_init_stmt(expr_first); + + if(token_match(TK_Comma)){ - iter = parse_expr(); - iter = parse_init_stmt(iter); + cond = parse_expr(); + if(token_match(TK_Comma)){ + iter = parse_expr(); + iter = parse_init_stmt(iter); + } } } @@ -345,7 +350,7 @@ binding_power(Binding binding, Token_Kind kind){ case TK_Mod: return {17,18}; case TK_Dot: - return {20,19}; + return {24,23}; default: return {}; } Postfix: switch(kind){ diff --git a/new_types.kl b/new_types.kl index eacf6b4..37d1805 100644 --- a/new_types.kl +++ b/new_types.kl @@ -47,11 +47,11 @@ basic_type_assignment :: () float_var := float_val - +compounds :: () + custom_data := Custom_Data(thing = 23) Custom_Data :: struct thing: S32 - -// compounds :: () -// custom_data := Custom_Data(23) + // constant_proc :: () + // constant_proc() diff --git a/program.c b/program.c index 0fb999a..803a504 100644 --- a/program.c +++ b/program.c @@ -1,6 +1,36 @@ -//------------------------------- -#define NULL_POINTER 0 -#define NULL_LAMBDA 0 -//------------------------------- - \ No newline at end of file + +#include +typedef int8_t S8; +typedef int16_t S16; +typedef int32_t S32; +typedef int64_t S64; +typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; +typedef uint64_t U64; +typedef S8 B8; +typedef S16 B16; +typedef S32 B32; +typedef S64 B64; +typedef U64 SizeU; +typedef S64 SizeI; +typedef float F32; +typedef double F64; + +struct String{ + U8 *str; + S64 len; +}; + + +struct Lex_Stream{ + U8 *stream; + U8 *end; +}; +static Void main(){ + String string_to_lex = LIT("Identifier 2425525 Not_Number"); + for(S64 i = 0;(itype)){ - if(op->type->kind == TYPE_UNTYPED_INT) op->type = type_int; + if(op->type->kind == TYPE_UNTYPED_INT) op->type = type_s64; else if(op->type->kind == TYPE_UNTYPED_BOOL) op->type = type_bool; else if(op->type->kind == TYPE_UNTYPED_STRING) op->type = type_string; else if(op->type->kind == TYPE_UNTYPED_FLOAT) op->type = type_f64; @@ -394,11 +394,6 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ BREAK(); } - CASE(BINARY, Binary){ - resolve_expr(node); - BREAK(); - } - CASE(PASS, Pass){ unused(node); BREAK(); @@ -422,7 +417,12 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ BREAK(); } - invalid_default_case; + default:{ + if(is_flag_set(ast->flags, AST_EXPR)){ + resolve_expr((Ast_Expr *)ast); + } + else invalid_codepath; + } } } @@ -486,6 +486,19 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){ return result; } +function Operand +field_access_string(Ast_Expr *right){ + if(right->kind == AST_BINARY) invalid_codepath; // @todo entire field access needs a rework + assert(right->kind == AST_IDENT); + + auto a = (Ast_Atom *)right; + if(a->intern_val == pctx->intern("len"_s)){ + return operand_lvalue(type_s64); + } else if(a->intern_val == pctx->intern("str"_s)){ + return operand_lvalue(type_pointer(type_u8)); + } else invalid_return; +} + function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){ if(!ast) return {}; // @todo: add option for better error prevention @@ -533,7 +546,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res CASE(INDEX, Index){ Operand left = resolve_expr(node->expr); Operand index = resolve_expr(node->index); - if(left.type->kind != TYPE_ARRAY) parsing_error(node->pos, "Indexing variable that is not an array, it's of type %s instead", docname(left.type)); + if(left.type->kind != TYPE_ARRAY && left.type->kind != TYPE_POINTER) parsing_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %s instead", docname(left.type)); if(!is_int(index.type)) type_error(node->pos, type_int, index.type,"Trying to index the array with invalid type, expected int"); return operand_lvalue(left.type->arr.base); BREAK(); @@ -695,10 +708,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; } }break; case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break; - case TK_Neg: - case TK_Not: - case TK_Add: - case TK_Sub:{ + case TK_Neg:case TK_Not:case TK_Add:case TK_Sub:{ Operand op = resolve_expr(node->expr); if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [%s] cant be applied to value of type %s", token_kind_string(node->op).str, docname(op.type)); if(op.is_const){ @@ -735,7 +745,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res Operand left = resolve_expr(node->left); if(!left.is_lvalue) parsing_error(node->pos, "Assigning to rvalue"); Operand right = resolve_expr(node->right); - try_untyping(&right); + + right.value = convert_untyped(node->pos, right.value, left.type); if(left.type != right.type) parsing_error(node->pos, "Can't assign value when left is %s and right is %s", docname(left.type), docname(right.type)); } //----------------------------------------------------------------------------- @@ -754,68 +765,74 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res } // @copy_paste if(is_pointer(type)) type = type->base; - type_complete(type); - if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); + sym_var({}, resolved_ident.type, node->left); - - // This happens only on binary nodes which further chain with dots and require lookups - // This part cant happen on enums - // x.resolve.y - Ast_Binary *binary = (Ast_Binary *)node->right; - for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){ - assert(is_ident(binary->left)); - Ast_Atom *ident = (Ast_Atom *)binary->left; - assert(is_binary(binary)); - - Ast_Struct *agg = (Ast_Struct *)type->ast; - Ast *query = query_struct(agg, ident->intern_val); - if(query){ - Sym *sym = resolved_get(query); - if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant"); - type = sym->type; - // @copy_paste - if(type == type_type){ - required_to_be_const = true; - type = sym->type_val; - } - if(is_pointer(type)) type = type->base; - type_complete(type); - if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - sym_associate(ident, sym); - - } else parsing_error(ident->pos, "No such member in struct"); + if(is_string(type) && !required_to_be_const){ + result = field_access_string(node->right); } + else{ + type_complete(type); + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - // Here we can resolve the last part, this doesnt need to be a struct - // x.y.resolve - // @copy_paste - Ast_Atom *ident = (Ast_Atom *)binary; - if(is_enum(type)){ - Ast_Enum *enu = (Ast_Enum *)type->ast; - Ast_Enum_Member *query = query_enum(enu, ident->intern_val); - if(query){ - Sym *resolved = resolved_get(query); - assert(resolved); - rewrite_into_const(node, Ast_Binary, resolved); - result = operand(resolved); + // This happens only on binary nodes which further chain with dots and require lookups + // This part cant happen on enums + // x.resolve.y + Ast_Binary *binary = (Ast_Binary *)node->right; + for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){ + assert(is_ident(binary->left)); + Ast_Atom *ident = (Ast_Atom *)binary->left; + assert(is_binary(binary)); + + Ast_Struct *agg = (Ast_Struct *)type->ast; + Ast *query = query_struct(agg, ident->intern_val); + if(query){ + Sym *sym = resolved_get(query); + if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant"); + type = sym->type; + // @copy_paste + if(type == type_type){ + required_to_be_const = true; + type = sym->type_val; + } + if(is_pointer(type)) type = type->base; + type_complete(type); + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); + sym_associate(ident, sym); + + } else parsing_error(ident->pos, "No such member in struct"); } - } - else if(is_struct(type)){ - Ast_Struct *agg = (Ast_Struct *)type->ast; - Ast *query = query_struct(agg, ident->intern_val); - if(query){ - Sym *sym = resolved_get(query); - result = operand(sym); - assert(sym); - if(sym->kind == SYM_CONST) rewrite_into_const(node, Ast_Binary, sym); - else sym_associate(ident, sym); - } else parsing_error(ident->pos, "No such member in struct"); - } - else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [Struct]"); + // Here we can resolve the last part, this doesnt need to be a struct + // x.y.resolve + // @copy_paste + Ast_Atom *ident = (Ast_Atom *)binary; + if(is_enum(type)){ + Ast_Enum *enu = (Ast_Enum *)type->ast; + Ast_Enum_Member *query = query_enum(enu, ident->intern_val); + if(query){ + Sym *resolved = resolved_get(query); + assert(resolved); + rewrite_into_const(node, Ast_Binary, resolved); + result = operand(resolved); + } + } + else if(is_struct(type)){ + Ast_Struct *agg = (Ast_Struct *)type->ast; + Ast *query = query_struct(agg, ident->intern_val); + if(query){ + Sym *sym = resolved_get(query); + result = operand(sym); + assert(sym); + if(sym->kind == SYM_CONST) rewrite_into_const(node, Ast_Binary, sym); + else sym_associate(ident, sym); - if(result.is_const == false && required_to_be_const){ - invalid_codepath; + } else parsing_error(ident->pos, "No such member in struct"); + } + else parsing_error(ident->pos, "Trying to [.] access a value that is not [Enum] or [Struct]"); + + if(result.is_const == false && required_to_be_const){ + invalid_codepath; + } } } //----------------------------------------------------------------------------- @@ -881,7 +898,7 @@ resolve_const(Ast_Expr *ast, Sym *sym){ value = op.int_val + 1; } else{ - op.type = type_int; + op.type = type_s64; op.int_val = value++; }