Skip to content

Commit

Permalink
Update a bunch of stuff, idek
Browse files Browse the repository at this point in the history
  • Loading branch information
mustafaquraish committed Nov 3, 2023
1 parent 6dc7bfc commit e5d8e3a
Show file tree
Hide file tree
Showing 25 changed files with 310 additions and 116 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ type inference, namespaces, stricter types and a module system. It transpiles to
Use the following command to build the initial compiler:

```shell
$ ./meta/bootstrap.sh # Generates ./bootstrap/ocen if successful
$ ./meta/bootstrap.sh # Generates initial compiler
$ ./bootstrap/ocen --help
```

### Compiling other programs
Expand Down
65 changes: 51 additions & 14 deletions bootstrap/stage0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,7 @@ bool silent = false;
bool debug = false;
u32 error_level = ((u32)2);
char *docs_path = NULL;
bool include_stdlib = true;
/* function declarations */
FILE *std_File_open(char *path, char *mode);
i32 std_File_read(FILE *this, void *buf, u32 size);
Expand All @@ -1531,8 +1532,12 @@ bool char_is_alnum(char this);
bool char_is_print(char this);
i32 i32_min(i32 this, i32 b);
i32 i32_max(i32 this, i32 b);
i8 i8_min(i8 this, i8 b);
i8 i8_max(i8 this, i8 b);
u32 u32_min(u32 this, u32 other);
u32 u32_max(u32 this, u32 other);
u8 u8_min(u8 this, u8 other);
u8 u8_max(u8 this, u8 other);
std_value_Value *std_compact_map_Map__0_at(std_compact_map_Map__0 *this, char *key);
void std_compact_map_Map__0_free(std_compact_map_Map__0 *this);
u32 std_compact_map_Map__0_get_index(std_compact_map_Map__0 *this, char *key, u32 hash);
Expand Down Expand Up @@ -2196,7 +2201,7 @@ bool parser_Parser_load_import_path(parser_Parser *this, ast_nodes_AST *import_s
void parser_Parser_load_file(parser_Parser *this, char *filename);
void parser_couldnt_find_stdlib(void);
void parser_Parser_find_and_import_stdlib(parser_Parser *this);
void parser_Parser_parse_toplevel(ast_program_Program *program, char *filename);
void parser_Parser_parse_toplevel(ast_program_Program *program, char *filename, bool include_stdlib);
u32 utils_edit_distance(char *str1, char *str2);
char *utils_find_word_suggestion(char *s, std_vector_Vector__5 *options);
bool utils_directory_exists(char *path);
Expand Down Expand Up @@ -2542,6 +2547,14 @@ i32 i32_max(i32 this, i32 b) {
return ((this > b) ? this : b);
}

i8 i8_min(i8 this, i8 b) {
return ((this < b) ? this : b);
}

i8 i8_max(i8 this, i8 b) {
return ((this > b) ? this : b);
}

u32 u32_min(u32 this, u32 other) {
return ((this < other) ? this : other);
}
Expand All @@ -2550,6 +2563,14 @@ u32 u32_max(u32 this, u32 other) {
return ((this > other) ? this : other);
}

u8 u8_min(u8 this, u8 other) {
return ((this < other) ? this : other);
}

u8 u8_max(u8 this, u8 other) {
return ((this > other) ? this : other);
}

std_value_Value *std_compact_map_Map__0_at(std_compact_map_Map__0 *this, char *key) {
u32 hash = str_hash(key);
u32 index = std_compact_map_Map__0_get_index(this, key, hash);
Expand Down Expand Up @@ -8544,7 +8565,7 @@ void parser_Parser_find_and_import_stdlib(parser_Parser *this) {
std_map_Map__3_insert(this->program->global->namespaces, "std", std_ns);
}

void parser_Parser_parse_toplevel(ast_program_Program *program, char *filename) {
void parser_Parser_parse_toplevel(ast_program_Program *program, char *filename, bool include_stdlib) {
char *t1 = strdup(filename);
char *dir = strdup(dirname(t1));
free(t1);
Expand All @@ -8565,7 +8586,9 @@ void parser_Parser_parse_toplevel(ast_program_Program *program, char *filename)
ns->sym->u.ns=ns;
std_map_Map__3_insert(project_ns->namespaces, base, ns);
parser_Parser parser = parser_Parser_make(program, ns);
parser_Parser_find_and_import_stdlib(&parser);
if (include_stdlib) {
parser_Parser_find_and_import_stdlib(&parser);
}
parser_Parser_load_file(&parser, filename);
}

Expand Down Expand Up @@ -8940,6 +8963,12 @@ void passes_generic_pass_GenericPass_import_all_from_namespace(passes_generic_pa
passes_generic_pass_GenericPass_insert_into_scope_checked(this, var->sym, NULL);
}
}
for (std_map_Iterator__2 __iter = std_map_Map__2_iter(ns->typedefs); std_map_Iterator__2_has_value(&__iter); std_map_Iterator__2_next(&__iter)) {
std_map_Node__2 *it = std_map_Iterator__2_cur(&__iter);
{
passes_generic_pass_GenericPass_insert_into_scope_checked(this, it->value->sym, it->key);
}
}
}

void passes_generic_pass_GenericPass_import_all_from_symbol(passes_generic_pass_GenericPass *this, ast_scopes_Symbol *sym) {
Expand Down Expand Up @@ -10901,7 +10930,6 @@ types_Type *passes_typechecker_TypeChecker_check_member(passes_typechecker_TypeC
node->resolved_symbol=method->sym;
return method->type;
}
passes_typechecker_TypeChecker_error(this, errors_Error_new(node->span, format_string("Type %s has no member named '%s'", types_Type_str(lhs), node->u.member.rhs_name)));
}
passes_typechecker_TypeChecker_error(this, errors_Error_new(node->span, format_string("Type %s has no member named '%s'", types_Type_str(lhs), node->u.member.rhs_name)));
return NULL;
Expand Down Expand Up @@ -12001,13 +12029,6 @@ void passes_typechecker_TypeChecker_check_function_declaration(passes_typechecke
void passes_typechecker_TypeChecker_check_post_import(passes_typechecker_TypeChecker *this, ast_program_Namespace *ns) {
passes_generic_pass_GenericPass_push_scope(this->o, ns->scope);
passes_generic_pass_GenericPass_push_namespace(this->o, ns);
for (std_map_Iterator__2 __iter = std_map_Map__2_iter(ns->typedefs); std_map_Iterator__2_has_value(&__iter); std_map_Iterator__2_next(&__iter)) {
std_map_Node__2 *it = std_map_Iterator__2_cur(&__iter);
{
ast_scopes_Symbol *sym = ast_scopes_Scope_lookup_recursive(passes_generic_pass_GenericPass_scope(this->o), it->key);
ae_assert(((bool)sym), "compiler/passes/typechecker.oc:1837:16: Assertion failed: `sym?`", "Should have added the symbol into scope already"); ae_assert(sym->type==ast_scopes_SymbolType_TypeDef, "compiler/passes/typechecker.oc:1838:16: Assertion failed: `sym.type == TypeDef`", NULL); sym->u.type_def=passes_typechecker_TypeChecker_resolve_type(this, it->value, false, true, true);
}
}
for (std_vector_Iterator__10 __iter = std_vector_Vector__10_iter(ns->functions); std_vector_Iterator__10_has_value(&__iter); std_vector_Iterator__10_next(&__iter)) {
ast_nodes_Function *func = std_vector_Iterator__10_cur(&__iter);
{
Expand Down Expand Up @@ -12064,6 +12085,15 @@ void passes_typechecker_TypeChecker_check_pre_import(passes_typechecker_TypeChec
passes_typechecker_TypeChecker_pre_check_function(this, ns, func);
}
}
for (std_map_Iterator__2 __iter = std_map_Map__2_iter(ns->typedefs); std_map_Iterator__2_has_value(&__iter); std_map_Iterator__2_next(&__iter)) {
std_map_Node__2 *it = std_map_Iterator__2_cur(&__iter);
{
ast_scopes_Symbol *sym = ast_scopes_Scope_lookup_recursive(passes_generic_pass_GenericPass_scope(this->o), it->key);
ae_assert(((bool)sym), "compiler/passes/typechecker.oc:1879:16: Assertion failed: `sym?`", "Should have added the symbol into scope already"); ae_assert(sym->type==ast_scopes_SymbolType_TypeDef, "compiler/passes/typechecker.oc:1880:16: Assertion failed: `sym.type == TypeDef`", NULL); types_Type *res = passes_typechecker_TypeChecker_resolve_type(this, it->value, false, true, true);
sym->u.type_def=res;
it->value=res;
}
}
for (std_map_ValueIterator__3 __iter = std_map_Map__3_iter_values(ns->namespaces); std_map_ValueIterator__3_has_value(&__iter); std_map_ValueIterator__3_next(&__iter)) {
ast_program_Namespace *child = std_map_ValueIterator__3_cur(&__iter);
{
Expand Down Expand Up @@ -12413,6 +12443,10 @@ ast_scopes_Symbol *ast_program_Namespace_find_importable_symbol(ast_program_Name

}
}
types_Type *td = std_map_Map__2_get(this->typedefs, name, NULL);
if (((bool)td))
return td->sym;

return NULL;
}

Expand Down Expand Up @@ -12515,7 +12549,7 @@ bool ast_program_NSIterator_has_value(ast_program_NSIterator *this) {
}

void ast_program_NSIterator_next(ast_program_NSIterator *this) {
ae_assert(!std_vector_Vector__7_is_empty(this->stack), "compiler/ast/program.oc:244:12: Assertion failed: `not .stack.is_empty()`", NULL); this->curr=std_vector_Vector__7_pop(this->stack);
ae_assert(!std_vector_Vector__7_is_empty(this->stack), "compiler/ast/program.oc:247:12: Assertion failed: `not .stack.is_empty()`", NULL); this->curr=std_vector_Vector__7_pop(this->stack);
for (std_map_ValueIterator__3 __iter = std_map_Map__3_iter_values(this->curr->namespaces); std_map_ValueIterator__3_has_value(&__iter); std_map_ValueIterator__3_next(&__iter)) {
ast_program_Namespace *ns = std_map_ValueIterator__3_cur(&__iter);
{
Expand Down Expand Up @@ -13794,7 +13828,7 @@ char *types_Type_str(types_Type *this) {
__yield_0 = this->u.enum_->sym->display;
} break;
case types_BaseType_Alias: {
__yield_0 = format_string("%s", this->name);
__yield_0 = this->name;
} break;
default: {
__yield_0 = types_BaseType_str(this->base);
Expand All @@ -13809,6 +13843,7 @@ void usage(i32 code) {
printf("Options:""\n");
printf(" -o path Output executable (default: ./out)""\n");
printf(" -c path Output C code (default: {out}.c)""\n");
printf(" --no-stdlid Don't include the standard library""\n");
printf(" -e0 Minimal one-line errors""\n");
printf(" -e1 Error messages with source code (default)""\n");
printf(" -e2 Error messages with source / hints""\n");
Expand Down Expand Up @@ -13885,6 +13920,8 @@ void parse_args(i32 argc, char **argv, ast_program_Program *program) {
i+=((u32)1);
docs_path=argv[i];
program->check_doc_links=true;
} else if (!strcmp(__match_str, "--no-stdlib")) {
include_stdlib=false;
} else {
if (argv[i][((u32)0)]=='-') {
printf("Unknown option: %s""\n", argv[i]);
Expand Down Expand Up @@ -13915,7 +13952,7 @@ i32 main(i32 argc, char **argv) {
parse_args(argc, argv, program);
program->error_level=error_level;
program->gen_debug_info=debug;
parser_Parser_parse_toplevel(program, filename);
parser_Parser_parse_toplevel(program, filename, include_stdlib);
if (!std_vector_Vector__14_is_empty(program->errors))
ast_program_Program_exit_with_errors(program);

Expand Down
5 changes: 4 additions & 1 deletion compiler/ast/program.oc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ def Namespace::find_importable_symbol(&this, name: str): &Symbol {
if var.sym.name.eq(name) return var.sym
}


for func : .functions.iter() {
if func.is_method then continue
if func.sym.name.eq(name) return func.sym
Expand All @@ -91,6 +90,10 @@ def Namespace::find_importable_symbol(&this, name: str): &Symbol {
for enum_ : .enums.iter() {
if enum_.sym.name.eq(name) return enum_.sym
}

let td = .typedefs.get(name, null)
if td? then return td.sym

return null
}

Expand Down
5 changes: 4 additions & 1 deletion compiler/main.oc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def usage(code: i32) {
println("Options:")
println(" -o path Output executable (default: ./out)")
println(" -c path Output C code (default: {out}.c)")
println(" --no-stdlid Don't include the standard library")
println(" -e0 Minimal one-line errors")
println(" -e1 Error messages with source code (default)")
println(" -e2 Error messages with source / hints")
Expand All @@ -34,6 +35,7 @@ let silent: bool = false
let debug: bool = false
let error_level: u32 = 2
let docs_path: str = null
let include_stdlib: bool = true

def save_and_compile_code(program: &Program, code: str) {
if not c_path? {
Expand Down Expand Up @@ -93,6 +95,7 @@ def parse_args(argc: i32, argv: &str, program: &Program) {
docs_path = argv[i]
program.check_doc_links = true
}
"--no-stdlib" => include_stdlib = false
else => {
if argv[i][0] == '-' {
println("Unknown option: %s", argv[i])
Expand Down Expand Up @@ -126,7 +129,7 @@ def main(argc: i32, argv: &str) {

program.error_level = error_level
program.gen_debug_info = debug
Parser::parse_toplevel(program, filename)
Parser::parse_toplevel(program, filename, include_stdlib)

if not program.errors.is_empty() then program.exit_with_errors()

Expand Down
6 changes: 4 additions & 2 deletions compiler/parser.oc
Original file line number Diff line number Diff line change
Expand Up @@ -1734,7 +1734,7 @@ def Parser::find_and_import_stdlib(&this) {
.program.global.namespaces.insert("std", std_ns)
}

def Parser::parse_toplevel(program: &Program, filename: str) {
def Parser::parse_toplevel(program: &Program, filename: str, include_stdlib: bool) {
// Path to the directory of the file
let t1 = filename.copy()
let dir = dirname(t1).copy()
Expand Down Expand Up @@ -1780,6 +1780,8 @@ def Parser::parse_toplevel(program: &Program, filename: str) {


let parser = Parser::make(program, ns)
parser.find_and_import_stdlib()
if include_stdlib {
parser.find_and_import_stdlib()
}
parser.load_file(filename)
}
4 changes: 4 additions & 0 deletions compiler/passes/generic_pass.oc
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ def GenericPass::import_all_from_namespace(&this, ns: &Namespace) {
let var = node.u.var_decl.var
.insert_into_scope_checked(var.sym)
}

for it : ns.typedefs.iter() {
.insert_into_scope_checked(it.value.sym, it.key)
}
}

def GenericPass::import_all_from_symbol(&this, sym: &Symbol) {
Expand Down
22 changes: 12 additions & 10 deletions compiler/passes/typechecker.oc
Original file line number Diff line number Diff line change
Expand Up @@ -1831,16 +1831,6 @@ def TypeChecker::check_post_import(&this, ns: &Namespace) {
.o.push_scope(ns.scope)
.o.push_namespace(ns)

for it : ns.typedefs.iter() {
let sym = .o.scope().lookup_recursive(it.key)
assert sym?, "Should have added the symbol into scope already"
assert sym.type == TypeDef

// FIXME: Why is there a `typedef` and `alias` at symbol/type level? Only one
// should really be sufficient.
sym.u.type_def = .resolve_type(it.value)
}

for func : ns.functions.iter() {
.check_function_declaration(func)
}
Expand Down Expand Up @@ -1884,6 +1874,18 @@ def TypeChecker::check_pre_import(&this, ns: &Namespace) {
.pre_check_function(ns, func)
}

for it : ns.typedefs.iter() {
let sym = .o.scope().lookup_recursive(it.key)
assert sym?, "Should have added the symbol into scope already"
assert sym.type == TypeDef

// FIXME: Why is there a `typedef` and `alias` at symbol/type level? Only one
// should really be sufficient.
let res = .resolve_type(it.value)
sym.u.type_def = res
it.value = res
}

for child : ns.namespaces.iter_values() {
.check_pre_import(child)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/types.oc
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,6 @@ def Type::str(&this): str => match .base {
Function => "<function>"
Structure => .u.struc.sym.display
Enum => .u.enum_.sym.display
Alias => `{.name}`
Alias => .name
else => .base.str()
}
20 changes: 10 additions & 10 deletions examples/jpegify.oc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import std::fft::{ fft2, ifft2 }
import std::math::{ TAU }
import std::image::Image
import std::image::{ Image, Color }
import std::vec::Vec
import std::complex::Complex
import std::libc::{ free, memcpy }
Expand All @@ -10,24 +10,24 @@ def get_image_channel(img: &Image, out: &Complex, channel: i32) {
for let i = 0; i < img.height * img.width; i++ {
let col = img.data[i]
let val = match channel {
0 => col.x,
1 => col.y,
2 => col.z,
else => (col.x + col.y + col.z) / 3.0
0 => col.r as f32 / 255.0,
1 => col.g as f32 / 255.0,
2 => col.b as f32 / 255.0,
else => (col.r + col.g + col.b) as f32 / (3.0 * 255.0)
}
out[i] = Complex::new(val, 0.0)
}
}

def save_image_channel(img: &Image, data: &Complex, channel: i32) {
for let i = 0; i < img.height * img.width; i++ {
let col = img.data[i]
let val = data[i].real().clamp01()
let val_u8 = (val * 255.0) as u8
match channel {
0 => img.data[i].x = val
1 => img.data[i].y = val
2 => img.data[i].z = val
else => img.data[i] = Vec(val, val, val)
0 => img.data[i].r = val_u8
1 => img.data[i].g = val_u8
2 => img.data[i].b = val_u8
else => img.data[i] = Color(val_u8, val_u8, val_u8)
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions examples/raytrace.oc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import std::vec::Vec
import std::vector::Vector
import std::image::Image
import std::image::{ Image, Color }
import std::math::{ rand01 }
import std::libc::malloc

Expand Down Expand Up @@ -164,7 +164,13 @@ def main() {
let color = raytrace(&ray, objs, 5)
total_col = total_col.add(color)
}
img.set(x, y, total_col.multf(div_factor))
total_col = total_col.multf(div_factor * 255.0)
let u8col = Color(
total_col.x as u8,
total_col.y as u8,
total_col.z as u8,
)
img.set(x, y, u8col)
}
}
println("")
Expand Down
Loading

0 comments on commit e5d8e3a

Please sign in to comment.