Dynamic array syntax [...]Type; make entities private with a prefix of _; fix extension checking

This commit is contained in:
Ginger Bill
2017-02-11 17:33:23 +00:00
parent 346aa5f71c
commit 4306345ff1
14 changed files with 173 additions and 89 deletions
+26 -17
View File
@@ -1,4 +1,13 @@
#import "fmt.odin"; #import . "fmt.odin";
#import "atomic.odin";
#import "hash.odin";
#import "math.odin";
#import "mem.odin";
#import "opengl.odin";
#import "os.odin";
#import "sync.odin";
#import "types.odin";
#import "utf8.odin";
main :: proc() { main :: proc() {
@@ -8,7 +17,7 @@ main :: proc() {
BANANA, BANANA,
COCONUT, COCONUT,
} }
fmt.println(Fruit.names); println(x, Fruit.names);
} }
when false { when false {
@@ -24,16 +33,16 @@ when false {
c := m[3.0]; c := m[3.0];
assert(ok && c == 564); assert(ok && c == 564);
fmt.print("map["); print("map[");
i := 0; i := 0;
for val, key in m { for val, key in m {
if i > 0 { if i > 0 {
fmt.print(", "); print(", ");
} }
fmt.printf("%v=%v", key, val); printf("%v=%v", key, val);
i += 1; i += 1;
} }
fmt.println("]"); println("]");
} }
{ {
m := map[string]u32{ m := map[string]u32{
@@ -47,11 +56,11 @@ when false {
_, ok := m["c"]; _, ok := m["c"];
assert(ok && c == 7654); assert(ok && c == 7654);
fmt.println(m); println(m);
} }
{ {
fmt.println("Hellope!"); println("Hellope!");
x: [dynamic]f64; x: [dynamic]f64;
reserve(x, 16); reserve(x, 16);
@@ -59,24 +68,24 @@ when false {
append(x, 2_000_000.500_000, 3, 5, 7); append(x, 2_000_000.500_000, 3, 5, 7);
for p, i in x { for p, i in x {
if i > 0 { fmt.print(", "); } if i > 0 { print(", "); }
fmt.print(p); print(p);
} }
fmt.println(); println();
{ {
Vec3 :: [vector 3]f32; Vec3 :: [vector 3]f32;
x := Vec3{1, 2, 3}; x := Vec3{1, 2, 3};
y := Vec3{4, 5, 6}; y := Vec3{4, 5, 6};
fmt.println(x < y); println(x < y);
fmt.println(x + y); println(x + y);
fmt.println(x - y); println(x - y);
fmt.println(x * y); println(x * y);
fmt.println(x / y); println(x / y);
for i in x { for i in x {
fmt.println(i); println(i);
} }
} }
} }
+1 -1
View File
@@ -373,7 +373,7 @@ Raw_Dynamic_Array :: struct #ordered {
}; };
Raw_Dynamic_Map :: struct #ordered { Raw_Dynamic_Map :: struct #ordered {
hashes: [dynamic]int, hashes: [...]int,
entries: Raw_Dynamic_Array, entries: Raw_Dynamic_Array,
}; };
+1 -1
View File
@@ -5,7 +5,7 @@
_ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version _ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
yield_thread :: proc() { win32._mm_pause(); } yield_thread :: proc() { win32.mm_pause(); }
mfence :: proc() { win32.ReadWriteBarrier(); } mfence :: proc() { win32.ReadWriteBarrier(); }
sfence :: proc() { win32.WriteBarrier(); } sfence :: proc() { win32.WriteBarrier(); }
lfence :: proc() { win32.ReadBarrier(); } lfence :: proc() { win32.ReadBarrier(); }
+11 -11
View File
@@ -3,7 +3,8 @@
#import "utf8.odin"; #import "utf8.odin";
#import "types.odin"; #import "types.odin";
DEFAULT_BUFFER_SIZE :: 1<<12;
_BUFFER_SIZE :: 1<<12;
Buffer :: struct { Buffer :: struct {
data: []byte, data: []byte,
@@ -60,7 +61,7 @@ Fmt_Info :: struct {
fprint :: proc(fd: os.Handle, args: ...any) -> int { fprint :: proc(fd: os.Handle, args: ...any) -> int {
data: [DEFAULT_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := Buffer{data[:], 0}; buf := Buffer{data[:], 0};
bprint(^buf, ...args); bprint(^buf, ...args);
os.write(fd, buf.data[:buf.length]); os.write(fd, buf.data[:buf.length]);
@@ -68,14 +69,14 @@ fprint :: proc(fd: os.Handle, args: ...any) -> int {
} }
fprintln :: proc(fd: os.Handle, args: ...any) -> int { fprintln :: proc(fd: os.Handle, args: ...any) -> int {
data: [DEFAULT_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := Buffer{data[:], 0}; buf := Buffer{data[:], 0};
bprintln(^buf, ...args); bprintln(^buf, ...args);
os.write(fd, buf.data[:buf.length]); os.write(fd, buf.data[:buf.length]);
return buf.length; return buf.length;
} }
fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int { fprintf :: proc(fd: os.Handle, fmt: string, args: ...any) -> int {
data: [DEFAULT_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := Buffer{data[:], 0}; buf := Buffer{data[:], 0};
bprintf(^buf, fmt, ...args); bprintf(^buf, fmt, ...args);
os.write(fd, buf.data[:buf.length]); os.write(fd, buf.data[:buf.length]);
@@ -95,7 +96,7 @@ printf :: proc(fmt: string, args: ...any) -> int {
fprint_type :: proc(fd: os.Handle, info: ^Type_Info) { fprint_type :: proc(fd: os.Handle, info: ^Type_Info) {
data: [DEFAULT_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := Buffer{data[:], 0}; buf := Buffer{data[:], 0};
buffer_write_type(^buf, info); buffer_write_type(^buf, info);
os.write(fd, buf.data[:buf.length]); os.write(fd, buf.data[:buf.length]);
@@ -174,8 +175,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
buffer_write_string(buf, "]"); buffer_write_string(buf, "]");
buffer_write_type(buf, info.elem); buffer_write_type(buf, info.elem);
case Dynamic_Array: case Dynamic_Array:
buffer_write_string(buf, "[dynamic"); buffer_write_string(buf, "[...]");
buffer_write_string(buf, "]");
buffer_write_type(buf, info.elem); buffer_write_type(buf, info.elem);
case Slice: case Slice:
buffer_write_string(buf, "["); buffer_write_string(buf, "[");
@@ -316,7 +316,7 @@ parse_int :: proc(s: string, offset: int) -> (int, int, bool) {
return result, offset+i, i != 0; return result, offset+i, i != 0;
} }
arg_number :: proc(fi: ^Fmt_Info, arg_index: int, format: string, offset: int, arg_count: int) -> (int, int, bool) { _arg_number :: proc(fi: ^Fmt_Info, arg_index: int, format: string, offset: int, arg_count: int) -> (int, int, bool) {
parse_arg_number :: proc(format: string) -> (int, int, bool) { parse_arg_number :: proc(format: string) -> (int, int, bool) {
if format.count < 3 { if format.count < 3 {
return 0, 1, false; return 0, 1, false;
@@ -961,7 +961,7 @@ bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
} }
} }
arg_index, i, was_prev_index = arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count);
// Width // Width
if i < end && fmt[i] == '*' { if i < end && fmt[i] == '*' {
@@ -991,7 +991,7 @@ bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
fi.good_arg_index = false; fi.good_arg_index = false;
} }
if i < end && fmt[i] == '*' { if i < end && fmt[i] == '*' {
arg_index, i, was_prev_index = arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count);
i += 1; i += 1;
fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index); fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index);
if fi.prec < 0 { if fi.prec < 0 {
@@ -1012,7 +1012,7 @@ bprintf :: proc(b: ^Buffer, fmt: string, args: ...any) -> int {
} }
if !was_prev_index { if !was_prev_index {
arg_index, i, was_prev_index = arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count);
} }
if i >= end { if i >= end {
+2 -2
View File
@@ -22,7 +22,7 @@ BOOL :: i32;
WNDPROC :: #type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c; WNDPROC :: #type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c;
INVALID_HANDLE_VALUE :: cast(HANDLE)(~cast(int)0); INVALID_HANDLE_VALUE :: cast(HANDLE)~cast(int)0;
FALSE: BOOL : 0; FALSE: BOOL : 0;
TRUE: BOOL : 1; TRUE: BOOL : 1;
@@ -288,7 +288,7 @@ InterlockedExchangeAdd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign ke
InterlockedAnd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign kernel32; InterlockedAnd64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign kernel32;
InterlockedOr64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign kernel32; InterlockedOr64 :: proc(dst: ^i64, desired: i64) -> i64 #foreign kernel32;
_mm_pause :: proc() #foreign kernel32; mm_pause :: proc() #foreign kernel32 "_mm_pause";
ReadWriteBarrier :: proc() #foreign kernel32; ReadWriteBarrier :: proc() #foreign kernel32;
WriteBarrier :: proc() #foreign kernel32; WriteBarrier :: proc() #foreign kernel32;
ReadBarrier :: proc() #foreign kernel32; ReadBarrier :: proc() #foreign kernel32;
+44 -13
View File
@@ -1081,6 +1081,11 @@ i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) {
return 0; return 0;
} }
Operand o = {0}; Operand o = {0};
if (e->kind == AstNode_UnaryExpr &&
e->UnaryExpr.op.kind == Token_Question) {
return -1;
}
check_expr(c, &o, e); check_expr(c, &o, e);
if (o.mode != Addressing_Constant) { if (o.mode != Addressing_Constant) {
if (o.mode != Addressing_Invalid) { if (o.mode != Addressing_Invalid) {
@@ -1314,7 +1319,12 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) {
case_ast_node(at, ArrayType, e); case_ast_node(at, ArrayType, e);
if (at->count != NULL) { if (at->count != NULL) {
Type *elem = check_type_extra(c, at->elem, NULL); Type *elem = check_type_extra(c, at->elem, NULL);
type = make_type_array(c->allocator, elem, check_array_or_map_count(c, at->count, false)); i64 count = check_array_or_map_count(c, at->count, false);
if (count < 0) {
error_node(at->count, "? can only be used in conjuction with compound literals");
count = 0;
}
type = make_type_array(c->allocator, elem, count);
} else { } else {
Type *elem = check_type(c, at->elem); Type *elem = check_type(c, at->elem);
type = make_type_slice(c->allocator, elem); type = make_type_slice(c->allocator, elem);
@@ -2529,8 +2539,11 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
add_entity_use(c, op_expr, e); add_entity_use(c, op_expr, e);
expr_entity = e; expr_entity = e;
if (e != NULL && e->kind == Entity_ImportName && if (e != NULL && e->kind == Entity_ImportName && selector->kind == AstNode_Ident) {
selector->kind == AstNode_Ident) { // IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile
// It pretty much needs to be in this order and this way
// If you can clean this up, please do but be really careful
String sel_name = selector->Ident.string; String sel_name = selector->Ident.string;
check_op_expr = false; check_op_expr = false;
@@ -2539,8 +2552,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
if (is_declared) { if (is_declared) {
if (entity->kind == Entity_Builtin) { if (entity->kind == Entity_Builtin) {
is_declared = false; is_declared = false;
} } else if (entity->scope->is_global && !e->ImportName.scope->is_global) {
if (entity->scope->is_global && !e->ImportName.scope->is_global) {
is_declared = false; is_declared = false;
} }
} }
@@ -2564,6 +2576,17 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
} }
} }
is_not_exported = !is_entity_name_exported(entity);
if (is_not_exported) {
gbString sel_str = expr_to_string(selector);
error_node(op_expr, "`%s` is not exported by `%.*s`", sel_str, LIT(name));
gb_string_free(sel_str);
// NOTE(bill): We will have to cause an error his even though it exists
goto error;
}
if (is_overloaded) { if (is_overloaded) {
Scope *s = entity->scope; Scope *s = entity->scope;
bool skip = false; bool skip = false;
@@ -2608,7 +2631,6 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
} }
bool *found = map_bool_get(&e->ImportName.scope->implicit, hash_pointer(entity)); bool *found = map_bool_get(&e->ImportName.scope->implicit, hash_pointer(entity));
if (!found) { if (!found) {
is_not_exported = false; is_not_exported = false;
} else { } else {
@@ -4479,16 +4501,18 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
case_ast_node(cl, CompoundLit, node); case_ast_node(cl, CompoundLit, node);
Type *type = type_hint; Type *type = type_hint;
bool ellipsis_array = false; bool is_to_be_determined_array_count = false;
bool is_constant = true; bool is_constant = true;
if (cl->type != NULL) { if (cl->type != NULL) {
type = NULL; type = NULL;
// [..]Type // [..]Type
if (cl->type->kind == AstNode_ArrayType && cl->type->ArrayType.count != NULL) { if (cl->type->kind == AstNode_ArrayType && cl->type->ArrayType.count != NULL) {
if (cl->type->ArrayType.count->kind == AstNode_Ellipsis) { AstNode *count = cl->type->ArrayType.count;
if (count->kind == AstNode_UnaryExpr &&
count->UnaryExpr.op.kind == Token_Question) {
type = make_type_array(c->allocator, check_type(c, cl->type->ArrayType.elem), -1); type = make_type_array(c->allocator, check_type(c, cl->type->ArrayType.elem), -1);
ellipsis_array = true; is_to_be_determined_array_count = true;
} }
} }
@@ -4663,7 +4687,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
} }
} }
if (t->kind == Type_Array && ellipsis_array) { if (t->kind == Type_Array && is_to_be_determined_array_count) {
t->Array.count = max; t->Array.count = max;
} }
} break; } break;
@@ -5185,11 +5209,13 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
case AstNode_ProcType: case AstNode_ProcType:
case AstNode_PointerType: case AstNode_PointerType:
case AstNode_ArrayType: case AstNode_ArrayType:
case AstNode_DynamicArrayType:
case AstNode_VectorType: case AstNode_VectorType:
case AstNode_StructType: case AstNode_StructType:
case AstNode_UnionType: case AstNode_UnionType:
case AstNode_RawUnionType: case AstNode_RawUnionType:
case AstNode_EnumType: case AstNode_EnumType:
case AstNode_MapType:
o->mode = Addressing_Type; o->mode = Addressing_Type;
o->type = check_type(c, node); o->type = check_type(c, node);
break; break;
@@ -5417,7 +5443,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_end; case_end;
case_ast_node(e, Ellipsis, node); case_ast_node(e, Ellipsis, node);
str = gb_string_appendc(str, ".."); str = gb_string_appendc(str, "...");
case_end; case_end;
case_ast_node(fv, FieldValue, node); case_ast_node(fv, FieldValue, node);
@@ -5433,13 +5459,18 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_ast_node(at, ArrayType, node); case_ast_node(at, ArrayType, node);
str = gb_string_appendc(str, "["); str = gb_string_appendc(str, "[");
str = write_expr_to_string(str, at->count); if (at->count->kind == AstNode_UnaryExpr &&
at->count->UnaryExpr.op.kind == Token_Hash) {
str = gb_string_appendc(str, "#");
} else {
str = write_expr_to_string(str, at->count);
}
str = gb_string_appendc(str, "]"); str = gb_string_appendc(str, "]");
str = write_expr_to_string(str, at->elem); str = write_expr_to_string(str, at->elem);
case_end; case_end;
case_ast_node(at, DynamicArrayType, node); case_ast_node(at, DynamicArrayType, node);
str = gb_string_appendc(str, "[dynamic]"); str = gb_string_appendc(str, "[...]");
str = write_expr_to_string(str, at->elem); str = write_expr_to_string(str, at->elem);
case_end; case_end;
+37 -3
View File
@@ -1531,6 +1531,8 @@ void check_all_global_entities(Checker *c) {
add_curr_ast_file(c, d->scope->file); add_curr_ast_file(c, d->scope->file);
if (!d->scope->has_been_imported) { if (!d->scope->has_been_imported) {
// NOTE(bill): All of these unchecked entities could mean a lot of unused allocations
// TODO(bill): Should this be worried about?
continue; continue;
} }
@@ -1567,6 +1569,30 @@ void check_all_global_entities(Checker *c) {
} }
bool is_string_an_identifier(String s) {
isize offset = 0;
if (s.len < 1) {
return false;
}
while (offset < s.len) {
bool ok = false;
Rune r = -1;
isize size = gb_utf8_decode(s.text+offset, s.len-offset, &r);
if (offset == 0) {
ok = rune_is_letter(r);
} else {
ok = rune_is_letter(r) || rune_is_digit(r);
}
if (!ok) {
return false;
}
offset += size;
}
return offset == s.len;
}
String path_to_entity_name(String name, String fullpath) { String path_to_entity_name(String name, String fullpath) {
if (name.len != 0) { if (name.len != 0) {
return name; return name;
@@ -1677,9 +1703,17 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
case Entity_LibraryName: case Entity_LibraryName:
break; break;
default: { default: {
bool ok = add_entity(c, parent_scope, NULL, e);
if (ok && id->is_import) { // `#import`ed entities don't get exported if (id->is_import) {
map_bool_set(&parent_scope->implicit, hash_pointer(e), true); if (is_entity_name_exported(e)) {
// TODO(bill): Should these entities be imported but cause an error when used?
bool ok = add_entity(c, parent_scope, NULL, e);
if (ok) {
map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
}
}
} else {
/* bool ok = */add_entity(c, parent_scope, NULL, e);
} }
} break; } break;
} }
+1
View File
@@ -6,6 +6,7 @@ gbAllocator heap_allocator(void) {
return gb_heap_allocator(); return gb_heap_allocator();
} }
#include "unicode.c"
#include "string.c" #include "string.c"
#include "array.c" #include "array.c"
+9
View File
@@ -98,6 +98,15 @@ struct Entity {
gb_global Entity *e_context = NULL; gb_global Entity *e_context = NULL;
bool is_entity_name_exported(Entity *e) {
GB_ASSERT(e != NULL);
String name = e->token.string;
if (name.len == 0) {
return false;
}
return name.text[0] != '_';
}
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) { Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
Entity *entity = gb_alloc_item(a, Entity); Entity *entity = gb_alloc_item(a, Entity);
-1
View File
@@ -4,7 +4,6 @@ extern "C" {
#include "common.c" #include "common.c"
#include "timings.c" #include "timings.c"
#include "unicode.c"
#include "build.c" #include "build.c"
#include "tokenizer.c" #include "tokenizer.c"
#include "parser.c" #include "parser.c"
+9 -4
View File
@@ -1832,6 +1832,7 @@ bool is_literal_type(AstNode *node) {
case AstNode_ArrayType: case AstNode_ArrayType:
case AstNode_VectorType: case AstNode_VectorType:
case AstNode_StructType: case AstNode_StructType:
case AstNode_DynamicArrayType:
case AstNode_MapType: case AstNode_MapType:
return true; return true;
} }
@@ -2575,8 +2576,8 @@ AstNode *parse_type_or_ident(AstFile *f) {
AstNode *count_expr = NULL; AstNode *count_expr = NULL;
bool is_vector = false; bool is_vector = false;
if (f->curr_token.kind == Token_Ellipsis) { if (f->curr_token.kind == Token_Question) {
count_expr = ast_ellipsis(f, expect_token(f, Token_Ellipsis), NULL); count_expr = ast_unary_expr(f, expect_token(f, Token_Question), NULL);
} else if (f->curr_token.kind == Token_vector) { } else if (f->curr_token.kind == Token_vector) {
next_token(f); next_token(f);
if (f->curr_token.kind != Token_CloseBracket) { if (f->curr_token.kind != Token_CloseBracket) {
@@ -2587,7 +2588,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
syntax_error(f->curr_token, "Vector type missing count"); syntax_error(f->curr_token, "Vector type missing count");
} }
is_vector = true; is_vector = true;
} else if (f->curr_token.kind == Token_dynamic) { } else if (f->curr_token.kind == Token_Ellipsis) {
next_token(f); next_token(f);
expect_token(f, Token_CloseBracket); expect_token(f, Token_CloseBracket);
return ast_dynamic_array_type(f, token, parse_type(f)); return ast_dynamic_array_type(f, token, parse_type(f));
@@ -3527,6 +3528,7 @@ AstNodeArray parse_stmt_list(AstFile *f) {
ParseFileError init_ast_file(AstFile *f, String fullpath) { ParseFileError init_ast_file(AstFile *f, String fullpath) {
fullpath = string_trim_whitespace(fullpath); // Just in case
if (!string_has_extension(fullpath, str_lit("odin"))) { if (!string_has_extension(fullpath, str_lit("odin"))) {
return ParseFile_WrongExtension; return ParseFile_WrongExtension;
} }
@@ -3606,6 +3608,9 @@ void destroy_parser(Parser *p) {
bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) { bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
gb_mutex_lock(&p->mutex); gb_mutex_lock(&p->mutex);
path = string_trim_whitespace(path);
rel_path = string_trim_whitespace(rel_path);
for_array(i, p->imports) { for_array(i, p->imports) {
String import = p->imports.e[i].path; String import = p->imports.e[i].path;
if (str_eq(import, path)) { if (str_eq(import, path)) {
@@ -3786,7 +3791,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
gb_printf_err("Invalid file extension: File must have the extension `.odin`"); gb_printf_err("Invalid file extension: File must have the extension `.odin`");
break; break;
case ParseFile_InvalidFile: case ParseFile_InvalidFile:
gb_printf_err("Invalid file"); gb_printf_err("Invalid file or cannot be found");
break; break;
case ParseFile_Permission: case ParseFile_Permission:
gb_printf_err("File permissions problem"); gb_printf_err("File permissions problem");
+28 -7
View File
@@ -145,16 +145,37 @@ gb_inline isize string_extension_position(String str) {
return dot_pos; return dot_pos;
} }
String string_trim_whitespace(String str) {
while (str.len > 0 && rune_is_whitespace(str.text[str.len-1])) {
str.len--;
}
while (str.len > 0 && rune_is_whitespace(str.text[0])) {
str.text++;
str.len--;
}
return str;
}
gb_inline bool string_has_extension(String str, String ext) { gb_inline bool string_has_extension(String str, String ext) {
if (str.len > ext.len+1) { str = string_trim_whitespace(str);
u8 *s = str.text+str.len - ext.len-1; if (str.len <= ext.len+1) {
if (s[0] == '.') {
s++;
return gb_memcompare(s, ext.text, ext.len) == 0;
}
return false; return false;
} }
return false; isize len = str.len;
for (isize i = len-1; i >= 0; i--) {
if (str.text[i] == '.') {
break;
}
len--;
}
if (len == 0) {
return false;
}
u8 *s = str.text + len;
return gb_memcompare(s, ext.text, ext.len) == 0;
} }
bool string_contains_char(String s, u8 c) { bool string_contains_char(String s, u8 c) {
+4 -4
View File
@@ -107,12 +107,12 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_enum, "enum"), \ TOKEN_KIND(Token_enum, "enum"), \
TOKEN_KIND(Token_vector, "vector"), \ TOKEN_KIND(Token_vector, "vector"), \
TOKEN_KIND(Token_map, "map"), \ TOKEN_KIND(Token_map, "map"), \
TOKEN_KIND(Token_static, "static"), \ /* TOKEN_KIND(Token_static, "static"), */ \
TOKEN_KIND(Token_dynamic, "dynamic"), \ /* TOKEN_KIND(Token_dynamic, "dynamic"), */ \
TOKEN_KIND(Token_using, "using"), \ TOKEN_KIND(Token_using, "using"), \
TOKEN_KIND(Token_no_alias, "no_alias"), \ TOKEN_KIND(Token_no_alias, "no_alias"), \
/* TOKEN_KIND(Token_mutable, "mutable"), */ \ /* TOKEN_KIND(Token_mutable, "mutable"), */ \
/* TOKEN_KIND(Token_immutable, "immutable"), */\ /* TOKEN_KIND(Token_immutable, "immutable"), */ \
TOKEN_KIND(Token_thread_local, "thread_local"), \ TOKEN_KIND(Token_thread_local, "thread_local"), \
TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_cast, "cast"), \
TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_transmute, "transmute"), \
-25
View File
@@ -39,28 +39,3 @@ bool rune_is_whitespace(Rune r) {
} }
return false; return false;
} }
bool is_string_an_identifier(String s) {
isize offset = 0;
if (s.len < 1) {
return false;
}
while (offset < s.len) {
bool ok = false;
Rune r = -1;
isize size = gb_utf8_decode(s.text+offset, s.len-offset, &r);
if (offset == 0) {
ok = rune_is_letter(r);
} else {
ok = rune_is_letter(r) || rune_is_digit(r);
}
if (!ok) {
return false;
}
offset += size;
}
return offset == s.len;
}