/* ------------------------------------------------------------------------------- 2022.05.28 - On lambda expressions I think it's not wise to add the multiline lambda expressions As is the case with python it would require new alternative syntax. The idea was to imply that the whitespace significant syntax is just inserting '{' '}' ';' automatically and if you decide to write a brace it stops being whitespace significant and you can type everything with semicolons and braces Problem is first of all it's kind of weird to have a completly different syntax in a language to solve something that is a minor inconvenience, second of all it turned out to be kind of bad, maybe if it would be more complicated then it would be ok but it implies that you have to semicolon end a lot of thing unintuitively. Probably single line lambdas should be ok. Currently braces turn off indentation awareness. There might be something you can do by trying to turn that on problem is that complicates parsing a lot cause you have to account for multiple indent styles, which means error messages become bad. ------------------------------------------------------------------------------- 2022.05.30 - On constructors and compound expressions I unified the compound expression syntax (Type){} with function call syntax Type(). It's differentiating on whether you used type. I think there is a benefit to the language not having an idea of overloading the type constructor. You will always know what will happen. Unlike C++ for example. It seems like a minefield that can fuck your mind up. So many corner cases and variants. having the idea of compounds doing one thing is reassuring I think. You can always do a constructor by writing a function with lower case type if you want that. For now I don't thing it should be overloadable. ------------------------------------------------------------------------------- We compile lot's of files, we keep track of them in Parse_Ctx, making sure we don't parse same thing twice. Files belong to a module, files can be loaded #load "file". All the files see all the decls from all the files in that module. We can import other modules using a different directive #import. #import perhaps should be lazily evaluated, making sure we don't resolve stuff we don't require. Currently probably want to export all the symbols, we can namespace them optionally. ------------------------------------------------------------------------------- @todo [ ] - Fix field access, cant cast, cant index [ ] - Add parent_scope to Ast_Type [ ] - Should compound resolution use an algorithm to reorder compounds to initialize all fields in order [ ] - Switch [ ] - Some way to take slice of data [ ] - Optional function renaming in codegen [ ] - #assert that handles constants at compile time and vars at runtime [ ] - Comma notation when declaring variables thing1, thing2: S32 [ ] - Array of inferred size [ ] - Add single line lambda expressions [ ] - Ternary operator [ ] - Disable ability to parse inner structs, functions, constants etc. ? [ ] - Write up on order independent declarations [ ] - constructor => thing :: (i: S32) -> {i = i, thing = 10} [ ] - 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 [ ] - Var args using Any array - args: []Any - delete vargs [ ] - [Using] keyword that brings in the struct enviroment into current scope etc. [ ] - Constant arrays that evaluate fully at compile time [ ] - Rust like enum where you associate values(other structs) with keys [ ] - Compound that zeros values - .{} , Compound that assumes defaults from struct definition - {} [ ] - Inject stack traces into the program [ ] - Conditional compilation #if @donzo [x] - Add c string [x] - slices should be properly displayed in debugger [x] - Imports inside of import shouldn't spill outside [x] - Scope [x] - Hex 0x42 [x] - Rewrite where # happen, [x] - elif [x] - cast -> [x] - Remodel compound from call to {} [x] - Fix codegen renames [x] - Field access rewrite [-] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix [-] - Order independent constants in structs [-] - 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 [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 [x] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression [x] - Passing down program to compile through command line [x] - More basic types [x] - Implementing required operations int128 [x] - Fix casting [x] - More for loop variations [x] - Add basic support for floats [x] - Converting from U64 token to S64 Atom introduces unnanounced error (negates) - probably need big int [x] - Add basic setup for new type system [x] - Access through struct names to constants Arena.CONSTANT [x] - Enums [x] - Make sure pointer arithmetic works [x] - Initial for loop [x] - Enum . access to values [x] - Character literal [x] - Compiling and running a program [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 [x] - Lexer: Need to insert scope endings when hitting End of file [x] - Resolving calls with named args, with indexed args [x] - Structs [x] - Struct field access [x] - Struct field access with dots while compiling to arrows in c [x] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int [x] - Initial order independence algorithm [x] - Think about compound expressions, unify with calls - maybe Thing(a=1) instead of Thing{a=1} */ #include "base.cpp" #include "base_unicode.cpp" #include "big_int_c3.cpp" #include "compiler.h" #include "lexing.cpp" #include "types.h" #include "ast.cpp" #include "parsing.cpp" #include "typechecking.h" #include "typechecking.cpp" #include "ccodegen.cpp" #include "tests.cpp" int main(int argument_count, char **arguments){ test_os_memory(); thread_ctx_init(); test_unicode(); test_types(); map_test(); test_array(); test_string_builder(); test_intern_table(); #if 0 if(argument_count > 1){ Scratch scratch; String name = string_fmt(scratch, "%s.kl", arguments[1]); String c_filename = string_fmt(scratch, "%s.c", arguments[1]); String compiler_call = string_fmt(scratch, "clang.exe %s.c -g -o %s.exe", arguments[1], arguments[1]); String run_program = string_fmt(scratch, "%s.exe", arguments[1]); Array files = {scratch}; files.add(name); String result = compile_files(files); assert(f); F64 begin = os_time(); system((const char *)compiler_call.str); printf("\nCompile time: %f", os_time() - begin); system((const char *)run_program.str); } #else emit_line_directives = true; F64 total_time = os_time(); begin_compilation(); Ast_Module *module = add_module(pctx->intern("main.kl"_s)); parse_all_modules(); assert(module); resolve_everything_in_module(module); String result = end_compilation(); assert(os_write_file("program.c"_s, result)); printf("\nTotal time = %f", os_time() - total_time); printf("\nTotal parsing = %f", parsing_time_end - parsing_time_begin); printf("\nTotal resolving = %f", resolving_time_end - resolving_time_begin); printf("\nTotal generatin = %f", generating_time_end - generating_time_begin); #endif __debugbreak(); }