diff --git a/ccodegen.cpp b/ccodegen.cpp index 79c8da5..30aad02 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -76,6 +76,8 @@ gen_expr(Ast_Expr *ast){ if(is_int(node->type)) gen("%lld", node->int_val); else if(is_string(node->type)) gen("LIT(\"%s\")", node->intern_val.str); else if(is_bool(node->type)) node->bool_val ? gen("true"):gen("false"); + else if(node->type == type_f32) gen("%f", node->f32_val); + else if(is_float(node->type)) gen("%f", node->f64_val); else invalid_codepath; BREAK(); } @@ -310,16 +312,16 @@ gen_ast(Ast *ast){ gen(";"); } } - else if(sym->type == type_f64){ + else if(sym->type == untyped_float){ gen("// constant F64 %s = %f;", node->name.str, sym->f64_val); } - else if(sym->type == type_int){ + else if(sym->type == untyped_int){ gen("// constant Int %s = %lld;", node->name.str, sym->int_val); } - else if(sym->type == type_string){ + else if(sym->type == untyped_string){ gen("// const String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str); } - else if(sym->type == type_bool){ + else if(sym->type == untyped_bool){ gen("// const Bool %s = %d;", node->name.str, sym->bool_val); } else if(sym->type == type_type){ diff --git a/main.cpp b/main.cpp index 497e377..d55384a 100644 --- a/main.cpp +++ b/main.cpp @@ -46,6 +46,7 @@ For now I don't thing it should be overloadable. [ ] - Add single line lambda expressions [ ] - Ternary operator [ ] - 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 the big int stuff [ ] - Order independent constants in structs [ ] - Can you even have recursive lambdas in structs, other recursive stuff [ ] - Casting to basic types by call S64(x) @@ -102,16 +103,16 @@ int main(){ String result = {}; #if 1 - result = compile_file("globals.kl"_s); - printf("%s", result.str); - result = compile_file("enums.kl"_s); - printf("%s", result.str); - result = compile_file("order1.kl"_s); - printf("%s", result.str); - result = compile_file("lambdas.kl"_s); - printf("%s", result.str); - result = compile_file("order2.kl"_s); - printf("%s", result.str); + // result = compile_file("globals.kl"_s); + // printf("%s", result.str); + // result = compile_file("enums.kl"_s); + // printf("%s", result.str); + // result = compile_file("order1.kl"_s); + // printf("%s", result.str); + // result = compile_file("lambdas.kl"_s); + // printf("%s", result.str); + // result = compile_file("order2.kl"_s); + // printf("%s", result.str); result = compile_file("new_types.kl"_s); printf("%s", result.str); #endif diff --git a/new_ast.cpp b/new_ast.cpp index 26cbf44..5f63db1 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -287,7 +287,7 @@ struct Ast_Package:Ast{ function Ast_Atom * ast_str(Token *pos, Intern_String string){ AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); - result->type = type_string; + result->type = untyped_string; result->intern_val = string; return result; } @@ -303,14 +303,14 @@ function Ast_Atom * ast_bool(Token *pos, B32 bool_val){ AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); result->bool_val = bool_val; - result->type = type_bool; + result->type = untyped_bool; return result; } function Ast_Atom * ast_float(Token *pos, F64 value){ AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); - result->type = type_f64; + result->type = untyped_float; result->f64_val = value; return result; } @@ -318,7 +318,7 @@ ast_float(Token *pos, F64 value){ function Ast_Atom * ast_int(Token *pos, S64 integer){ AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); - result->type = type_int; + result->type = untyped_int; result->int_val = integer; return result; } diff --git a/new_parse.cpp b/new_parse.cpp index 10c3d7e..f23a49f 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -312,6 +312,8 @@ binding_power(Binding binding, Token_Kind kind){ case TK_OpenBracket: case TK_Keyword: case TK_OpenParen: + case TK_Sub: + case TK_Add: return{-2, 20}; default: return {-1, -1}; } @@ -365,6 +367,8 @@ parse_expr(S64 min_bp){ case TK_Float : left = ast_float(token, token->f64_val); break; case TK_Pointer : left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right)); break; case TK_Dereference: left = ast_expr_unary(token, TK_Dereference, parse_expr(prefix_bp.right)); break; + case TK_Sub : left = ast_expr_unary(token, TK_Sub, parse_expr(prefix_bp.right)); break; + case TK_Add : left = ast_expr_unary(token, TK_Add, parse_expr(prefix_bp.right)); break; case TK_OpenBracket: { Ast_Array *result = ast_array(token, parse_expr(0)); diff --git a/new_types.kl b/new_types.kl index ba9c236..507b447 100644 --- a/new_types.kl +++ b/new_types.kl @@ -4,3 +4,11 @@ main :: (argc: S64, argv: **U8) thing: Bool = some_constant + + float_val :: 325.42 + float_var := float_val + int_val :: 1251525 + int_var: Int = int_val + conversion: F64 = int_val + + diff --git a/typecheck.cpp b/typecheck.cpp index cc9a5a9..f918b28 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -369,6 +369,11 @@ 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_Sub:{ + + }break; + case TK_Add:{ + }break; invalid_default_case; return {}; } @@ -572,13 +577,53 @@ resolve_const(Ast_Expr *ast, Sym *sym){ } } +#define CASE_OVERFLOW(pos, int_val, kind_val, TYPE, min, max) \ + case TYPE:{ \ + if(int_val > max) parsing_error(pos, "Overflow when converting from %s constant to %s, value out of range: %d, max is: %d", type_names[kind_val], type_names[TYPE], int_val, max); \ + if(int_val < min) parsing_error(pos, "Underflow when converting from %s constant to %s, value out of range: %d, min is: %d", type_names[kind_val], type_names[TYPE], int_val, min);\ + }break; + function Operand resolve_binding(Ast *ast, Sym *sym){ switch(ast->kind){ CASE(VAR, Var){ Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); Operand expr = resolve_expr(node->expr, type); - expr.type = resolve_type_pair(node->pos, type, expr.type); + if(!type) expr.type = if_untyped_get_default_conversion(expr.type); + if(is_untyped(expr.type)){ + Ast_Resolved_Type *untyped = expr.type; + if(is_int(type) && is_int(untyped)){ + switch(type->kind){ + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_INT, TYPE_INT_MIN, TYPE_INT_MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_UINT, TYPE_UINT_MIN, TYPE_INT_MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_S8 , S8MIN, S8MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_S16, S16MIN, S16MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_S32, S32MIN, S32MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_S64, S64MIN, S64MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_U8 , U8MIN, U8MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_U16, U16MIN, U16MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_U32, U32MIN, U32MAX) + CASE_OVERFLOW(node->pos, expr.int_val, untyped->kind, TYPE_U64, U64MIN, U64MAX) + invalid_default_case; + } + } + else if(is_float(type) && is_int(untyped)){ + switch(type->kind){ + case TYPE_F32:{expr.f32_val = expr.int_val;}break; + case TYPE_F64:{expr.f64_val = expr.int_val;}break; + invalid_default_case; + } + } + else if(type->kind == TYPE_F32 && is_float(untyped)){ + expr.f32_val = expr.f64_val; + } + else if(is_bool(type) && is_bool(untyped)); + else if(is_string(type) && is_string(untyped)); + else parsing_error(node->pos, "Type mismatch when converting from %s to %s", type_names[untyped->kind], type_names[type->kind]); + + expr.type = type; + } + type_complete(expr.type); return expr; BREAK(); diff --git a/types.h b/types.h index 99eb06f..98691a5 100644 --- a/types.h +++ b/types.h @@ -1,3 +1,7 @@ +#define TYPE_INT_MIN S64MIN +#define TYPE_INT_MAX S64MAX +#define TYPE_UINT_MIN U64MIN +#define TYPE_UINT_MAX U64MAX //----------------------------------------------------------------------------- // Resolved Types //----------------------------------------------------------------------------- @@ -207,9 +211,20 @@ force_inline B32 is_bool(Ast_Resolved_Type *a){return a->kind == TYPE_BOOL || a- force_inline B32 is_untyped(Ast_Resolved_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;} force_inline B32 is_typed(Ast_Resolved_Type *a){return !is_untyped(a);} - force_inline B32 is_numeric(Ast_Resolved_Type *type){ return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); } + +function Ast_Resolved_Type * +if_untyped_get_default_conversion(Ast_Resolved_Type *type){ + if(is_untyped(type)){ + if(type->kind == TYPE_UNTYPED_INT) return type_int; + else if(type->kind == TYPE_UNTYPED_BOOL) return type_bool; + else if(type->kind == TYPE_UNTYPED_STRING) return type_string; + else if(type->kind == TYPE_UNTYPED_FLOAT) return type_f64; + invalid_return; + } + return type; +}