162 lines
7.2 KiB
C++
162 lines
7.2 KiB
C++
/*
|
|
-------------------------------------------------------------------------------
|
|
|
|
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.
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
Imports
|
|
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.
|
|
|
|
2022.06.26 - import revision
|
|
Current design is a bit weird, there can be situations where you have colissions and stuff.
|
|
That's not cool. I was thinking of bringing back this idea where you have modules, implicit or
|
|
explicit(module directive at top of the file). Then each file that belongs to a module sees other
|
|
decls in that module and stuff like that. Other modules would be imported using a single keyword.
|
|
BUT on second thought I don't really like that design. It's not really clear how files that
|
|
belong to a module are found and concatenated. Then you would need to specify a directory to
|
|
compile instead of a single file and stuff like that which seems annoying! Current idea is
|
|
to just disallow having same file loaded twice! It's the same result as with the module stuff,
|
|
we cant reuse files, but we avoid file colissions where we load a file and a module we import loads
|
|
a file. I like the load files approach to a module cause we specify which files to compile and load.
|
|
Imports also could be this other thing where we load lazily and we decrease the amount of code
|
|
that we output. Code in our project shouldn't be evaluated lazily cause that's counter intuitive.
|
|
For modules it's a bit different cause they should be distributed as valid.
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
@todo
|
|
[ ] - Fix language_basics.kl string index error
|
|
[ ] - Split Bc into builder and interpreter
|
|
[ ] - Implement functions in the bytecode
|
|
|
|
[ ] - Probably need to give Ast_Expr a Value field, then I can express Type nicely
|
|
[ ] - I would love for String, slice, Any etc. to have their struct declarations in source files, I also would want for stuff like string.str to work without weird special cases
|
|
[ ] - Var args with Any
|
|
|
|
[ ] - #test construct that would gather all tests and run them on start of program or something
|
|
[ ] - Foreign import that would link library
|
|
[ ] - Builtin dynamic arrays
|
|
[ ] - Kilobyte, Megabyte, Gigabyte
|
|
[ ] - Cast from array to pointer?
|
|
[ ] - Fix field access, cant cast, cant index
|
|
[ ] - Add parent_scope to Ast_Type, Add name to Ast_Type?
|
|
[ ] - Some way to take slice of data
|
|
[ ] - Optional function renaming in codegen
|
|
[ ] - Using in structs to embed members, then casting offsets to that embedded member
|
|
|
|
[ ] - Comma notation when declaring variables thing1, thing2: S32 :: probably want to unify it with var unpacking
|
|
[ ] - Add single line lambda expressions
|
|
[ ] - Ternary operator
|
|
[ ] - Disable ability to parse inner structs, functions, constants etc. ?
|
|
[ ] - Write up on order independent declarations
|
|
|
|
[ ] - Consider changing syntax of scopes to use braces { }
|
|
[ ] - Order independent declarations in structs ?
|
|
[ ] - 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
|
|
|
|
@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
|
|
[ ] - Polymorphism - create declaration of a polymorphic thing, when it's called just copy it, replace types and typecheck normally, when someone calls again you just search for the instantiation again
|
|
|
|
*/
|
|
|
|
#include "base.cpp"
|
|
#include "base_unicode.cpp"
|
|
#include "os_windows.cpp"
|
|
#include "c3_big_int.cpp"
|
|
#include "compiler.h"
|
|
#include "lexing.cpp"
|
|
#include "types.h"
|
|
#include "ast.cpp"
|
|
#include "parsing.cpp"
|
|
#include "typechecking.h"
|
|
#include "typechecking.cpp"
|
|
#include "compiler.cpp"
|
|
#include "codegen_c_language.cpp"
|
|
|
|
|
|
int main(int argument_count, char **arguments){
|
|
#if OS_WINDOWS
|
|
// Set output mode to handle virtual terminal sequences
|
|
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
if (hOut == INVALID_HANDLE_VALUE) {
|
|
return GetLastError();
|
|
}
|
|
|
|
DWORD dwMode = 0;
|
|
if (!GetConsoleMode(hOut, &dwMode)) {
|
|
return GetLastError();
|
|
}
|
|
|
|
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
|
if (!SetConsoleMode(hOut, dwMode)) {
|
|
return GetLastError();
|
|
}
|
|
#endif
|
|
|
|
test_os_memory();
|
|
thread_ctx_init();
|
|
test_unicode();
|
|
|
|
map_test();
|
|
test_array();
|
|
test_string_builder();
|
|
test_intern_table();
|
|
|
|
emit_line_directives = true;
|
|
String program_name = "examples/types_as_first_class_values.kl"_s;
|
|
if(argument_count > 1){
|
|
program_name = string_from_cstring(arguments[1]);
|
|
}
|
|
|
|
Scratch scratch;
|
|
Array<OS_File_Info> examples = os_list_dir(scratch, "examples"_s);
|
|
// compile_file("examples/language_basics.kl"_s, COMPILE_AND_RUN);
|
|
For(examples){
|
|
if(it.is_directory) continue;
|
|
compile_file(it.absolute_path, COMPILE_AND_RUN);
|
|
}
|
|
|
|
__debugbreak();
|
|
}
|