Comments
This commit is contained in:
18
README.md
18
README.md
@@ -65,28 +65,28 @@ Release :: (m: *Memory)
|
||||
|
||||
## What's missing ?
|
||||
|
||||
- [x] Constant evaluation and constant folding - Folding and precomputing every expression that can be calculated at compile time. Which allows to check if a given constant expression is actually something that can be computed at compile time.
|
||||
- [ ] Constant expressions with types specified by the user.
|
||||
- [x] Constant evaluation and constant folding - Folding and precomputing every expression that can be calculated at compile time. Which allows to check if a given constant expression is actually something that can be computed at compile time
|
||||
- [ ] Constant expressions with concrete types
|
||||
|
||||
- [x] Untyped types - Context dependent type assignment of constant expressions, this is a feature I really loved in Go, it makes constants work very well with a very strict type system and it makes errors like overflow of constants in C due to bad size specifier impossible.
|
||||
- [x] Infinite precision integers in constants.
|
||||
- [x] Resolution of all untyped types in the typechecking stage.
|
||||
- [x] Special case of booleans and their type propagation.
|
||||
- [x] Untyped types - Context dependent type assignment of constant expressions, this is a feature I really loved in Go, it makes constants work very well with a very strict type system and it makes errors like overflow of constants in C due to bad size specifier impossible
|
||||
- [x] Infinite precision integers in constants
|
||||
- [x] Resolution of all untyped types in the typechecking stage
|
||||
- [x] Special case of booleans and their type propagation
|
||||
|
||||
- [x] Module system
|
||||
- [x] Lazy evaluation of modules (unused code is not compiled or typechecked)
|
||||
- [x] Import module, load project file distinction
|
||||
|
||||
- [x] Order independent declarations - The ordering of functions in code files or modules does not matter, compiler figures all that stuff out for you. "main" can be wherever you want it to be and all functions should be available without problems.
|
||||
- [x] Order independent declarations - The ordering of functions in code files or modules does not matter, compiler figures all that stuff out for you. "main" can be wherever you want it to be and all functions should be available without problems
|
||||
|
||||
- [x] Synchronize generated C code with original source using line directives so that debuggers work.
|
||||
- [x] Synchronize generated C code with original source using line directives so that debuggers work
|
||||
|
||||
- [ ] Expressions
|
||||
- [x] Compounds with named fields and numbered fields
|
||||
- [x] Functions calls with named arguments
|
||||
- [x] All the standard binary, unary expressions
|
||||
- [x] Pointer arithmetic and pointer as array
|
||||
- [ ] Dot access expression needs a redesign
|
||||
- [ ] Dot access expression needs a redesign because it doesn't handle expressions after the dot it requires names instead
|
||||
- [ ] Casting might need a redesign not sure
|
||||
|
||||
- [x] Runtime reflection
|
||||
|
||||
@@ -23,45 +23,6 @@ destroy_compiler(){
|
||||
exp_destroy(&pctx->stage_arena);
|
||||
}
|
||||
|
||||
function void
|
||||
parse_file(Ast_File *file){
|
||||
assert(file);
|
||||
|
||||
Scratch scratch;
|
||||
file->filecontent = os_read_file(pctx->perm, file->absolute_file_path);
|
||||
if(file->filecontent.len == 0){
|
||||
compiler_error(file->pos, "Failed to open file \"%Q\"", file->absolute_file_path);
|
||||
}
|
||||
|
||||
|
||||
pctx->currently_parsed_file = file;
|
||||
pctx->currently_parsed_scope = file;
|
||||
lex_restream(pctx, file->filecontent, file->absolute_file_path);
|
||||
while(token_expect(SAME_SCOPE)){
|
||||
if(token_match_pound(pctx->intern("load"_s))){
|
||||
parse_load(true);
|
||||
continue;
|
||||
} else if(token_match_pound(pctx->intern("import"_s))){
|
||||
parse_import(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
Ast_Decl *decl = parse_decl(true);
|
||||
if(!decl) break;
|
||||
|
||||
set_flag(decl->flags, AST_GLOBAL);
|
||||
if(decl->kind == AST_STRUCT){
|
||||
decl->type = type_type;
|
||||
decl->type_val = type_incomplete(decl);
|
||||
decl->state = DECL_RESOLVED;
|
||||
}
|
||||
|
||||
insert_into_scope(file, decl);
|
||||
}
|
||||
pctx->currently_parsed_scope = 0;
|
||||
pctx->currently_parsed_file = 0;
|
||||
}
|
||||
|
||||
function void
|
||||
insert_builtin_into_scope(Ast_Scope *p, String name, Ast_Type *type){
|
||||
Intern_String string = pctx->intern(name);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/*
|
||||
|
||||
- [ ] Basic
|
||||
- [ ] Idea to fix overshoot when debugging and it goes to the
|
||||
close bracket and there is not enough line directives.
|
||||
- Store the last outputed line and propagate it on the close brace etc.
|
||||
- [ ] Detecting if return was called
|
||||
- [ ] Fix . operator lookups
|
||||
- [ ] Combining casts with . operator
|
||||
|
||||
@@ -736,8 +736,7 @@ register_ast_file(Token *pos, String absolute_file_path, Ast_Module *module, B32
|
||||
break;
|
||||
}
|
||||
|
||||
print_token_context(it->pos);
|
||||
compiler_error(pos, "This file is already loaded by module: %Q, try importing that module to get access to it", module->absolute_file_path);
|
||||
compiler_error(it->pos, pos, "This file is already loaded by module: %Q, try importing that module to get access to it", module->absolute_file_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,3 +865,44 @@ parse_decl(B32 is_global){
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function void insert_into_scope(Ast_Scope *scope, Ast_Decl *decl);
|
||||
function Ast_Type *type_incomplete(Ast *ast);
|
||||
|
||||
function void
|
||||
parse_file(Ast_File *file){
|
||||
assert(file);
|
||||
|
||||
Scratch scratch;
|
||||
file->filecontent = os_read_file(pctx->perm, file->absolute_file_path);
|
||||
if(file->filecontent.len == 0){
|
||||
compiler_error(file->pos, "Failed to open file \"%Q\"", file->absolute_file_path);
|
||||
}
|
||||
|
||||
pctx->currently_parsed_file = file;
|
||||
pctx->currently_parsed_scope = file;
|
||||
lex_restream(pctx, file->filecontent, file->absolute_file_path);
|
||||
while(token_expect(SAME_SCOPE)){
|
||||
if(token_match_pound(pctx->intern("load"_s))){
|
||||
parse_load(true);
|
||||
continue;
|
||||
} else if(token_match_pound(pctx->intern("import"_s))){
|
||||
parse_import(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
Ast_Decl *decl = parse_decl(true);
|
||||
if(!decl) break;
|
||||
|
||||
set_flag(decl->flags, AST_GLOBAL);
|
||||
if(decl->kind == AST_STRUCT){
|
||||
decl->type = type_type;
|
||||
decl->type_val = type_incomplete(decl);
|
||||
decl->state = DECL_RESOLVED;
|
||||
}
|
||||
|
||||
insert_into_scope(file, decl);
|
||||
}
|
||||
pctx->currently_parsed_scope = 0;
|
||||
pctx->currently_parsed_file = 0;
|
||||
}
|
||||
|
||||
@@ -445,19 +445,26 @@ search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){
|
||||
function Ast_Decl *
|
||||
resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){
|
||||
Ast_Decl *decl = search_for_decl(scope, name, search_flags);
|
||||
if(!decl) compiler_error(pos, "Unidentified name [%s]", name.str);
|
||||
if(!decl) {
|
||||
compiler_error(pos, "Unidentified name [%s]", name.str);
|
||||
}
|
||||
|
||||
resolve_decl(decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
function void
|
||||
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
||||
// This function is called when resolving statements
|
||||
// inside code blocks, inserting lambda arguments into scope
|
||||
//
|
||||
// It's also called when scanning top level declarations of a module
|
||||
// as such we probably don't want to call any resolve stuff here
|
||||
Ast_Decl *find = search_for_decl(scope, decl->name);
|
||||
if(find){
|
||||
print_token_context(find->pos);
|
||||
compiler_error(decl->pos, "[%s] is already defined", decl->name.str);
|
||||
// if(find->kind != AST_LAMBDA)
|
||||
compiler_error(find->pos, decl->pos, "[%s] is already defined", decl->name.str);
|
||||
}
|
||||
|
||||
scope->decls.add(decl);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,8 +224,9 @@ type_array(Ast_Type *base, S64 size){
|
||||
function Ast_Type *
|
||||
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
||||
U64 hash = hash_ptr(ret);
|
||||
For(args) hash = hash_mix(hash, hash_ptr(it));
|
||||
U64 hash_without_ret = 13; // @function_overloading scrap this if we changed course
|
||||
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
|
||||
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
||||
|
||||
if(result){
|
||||
@@ -238,6 +239,7 @@ type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||
result->ast = ast;
|
||||
result->func.ret = ret;
|
||||
result->func.args = args.tight_copy(pctx->perm);
|
||||
result->func.hash_without_ret = hash_without_ret; // @function_overloading scrap this if we changed course
|
||||
map_insert(&pctx->type_map, hash, result);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -101,6 +101,7 @@ struct Ast_Type{
|
||||
struct{
|
||||
Ast_Type * ret;
|
||||
Array<Ast_Type *> args;
|
||||
U64 hash_without_ret; // @function_overloading scrap this if we changed course
|
||||
}func;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -50,6 +50,20 @@ Vec3_Add :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.
|
||||
Vec3_Div :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x/b.x, a.y/b.y, a.z/b.z}
|
||||
Vec3_Sub :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x-b.x, a.y-b.y, a.z-b.z}
|
||||
|
||||
/*
|
||||
@todo: Add function overloading
|
||||
Current plan:
|
||||
* allow insert_into_scope to insert multiple lambdas
|
||||
* change resolve_name and search_for_decl to something
|
||||
that can seek multiple lambda declarations
|
||||
resolve them and return a match to hash or type
|
||||
* change the order of lambda call resolution, probably would have to
|
||||
hash the arguments first to match the lambda call
|
||||
|
||||
*/
|
||||
// Add :: (a: Vec3, b: Vec3): Vec3 ;; return Vec3{a.x+b.x, a.y+b.y, a.z+b.z}
|
||||
// Add :: (a: Vec2, b: Vec2): Vec2 ;; return Vec2{a.x+b.x, a.y+b.y}
|
||||
|
||||
F32_Clamp :: (min: F32, value: F32, max: F32): F32
|
||||
if value > max;; return max
|
||||
if value < min;; return min
|
||||
|
||||
Reference in New Issue
Block a user