mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-24 08:27:53 +00:00
Fix utf8 stuff, Allow _ in numbers, Begin writing next demo code.
This commit is contained in:
@@ -477,9 +477,19 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body) {
|
||||
GB_ASSERT(body->kind == AstNode_BlockStmt);
|
||||
|
||||
String proc_name = {0};
|
||||
if (token.kind == Token_Ident) {
|
||||
proc_name = token.string;
|
||||
} else {
|
||||
// TODO(bill): Better name
|
||||
proc_name = str_lit("(anonymous-procedure)");
|
||||
}
|
||||
|
||||
CheckerContext old_context = c->context;
|
||||
c->context.scope = decl->scope;
|
||||
c->context.decl = decl;
|
||||
c->context.proc_name = proc_name;
|
||||
|
||||
|
||||
GB_ASSERT(type->kind == Type_Proc);
|
||||
if (type->Proc.param_count > 0) {
|
||||
|
||||
+18
-2
@@ -3892,6 +3892,16 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
} else if (str_eq(bd->name, str_lit("line"))) {
|
||||
o->type = t_untyped_integer;
|
||||
o->value = make_exact_value_integer(bd->token.pos.line);
|
||||
} else if (str_eq(bd->name, str_lit("procedure"))) {
|
||||
if (c->proc_stack.count == 0) {
|
||||
error_node(node, "#procedure may only be used within procedures");
|
||||
o->type = t_untyped_string;
|
||||
o->value = make_exact_value_string(str_lit(""));
|
||||
} else {
|
||||
o->type = t_untyped_string;
|
||||
o->value = make_exact_value_string(c->context.proc_name);
|
||||
}
|
||||
|
||||
} else {
|
||||
GB_PANIC("Unknown basic basic directive");
|
||||
}
|
||||
@@ -3962,9 +3972,11 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
goto error;
|
||||
} else if (operands.count == 1) {
|
||||
Operand operand = operands.e[0];
|
||||
if (type_hint != NULL) {
|
||||
convert_to_typed(c, &operand, type_hint, 0);
|
||||
Type *th = type_hint != NULL ? type_hint : c->context.type_hint;
|
||||
if (th != NULL) {
|
||||
convert_to_typed(c, &operand, th, 0);
|
||||
}
|
||||
// IMPORTANT NOTE(bill): This type could be untyped!!!
|
||||
o->type = default_type(operand.type);
|
||||
o->mode = Addressing_Value;
|
||||
} else {
|
||||
@@ -4012,10 +4024,14 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
goto error;
|
||||
}
|
||||
|
||||
CheckerContext prev_context = c->context;
|
||||
c->context.type_hint = type_hint;
|
||||
check_open_scope(c, node);
|
||||
check_stmt_list(c, be->stmts, Stmt_GiveAllowed);
|
||||
check_close_scope(c);
|
||||
|
||||
c->context = prev_context;
|
||||
|
||||
AstNode *give_node = NULL;
|
||||
if (!check_is_giving(node, &give_node) || give_node == NULL) {
|
||||
error_node(node, "Missing give statement at end of block expression");
|
||||
|
||||
+4
-2
@@ -251,6 +251,8 @@ typedef struct CheckerContext {
|
||||
DeclInfo * decl;
|
||||
u32 stmt_state_flags;
|
||||
bool in_defer; // TODO(bill): Actually handle correctly
|
||||
String proc_name;
|
||||
Type * type_hint;
|
||||
} CheckerContext;
|
||||
|
||||
// NOTE(bill): Symbol tables
|
||||
@@ -276,8 +278,8 @@ typedef struct Checker {
|
||||
BaseTypeSizes sizes;
|
||||
Scope * global_scope;
|
||||
Array(ProcedureInfo) procs; // NOTE(bill): Procedures to check
|
||||
Array(DelayedDecl) delayed_imports;
|
||||
Array(DelayedDecl) delayed_foreign_libraries;
|
||||
Array(DelayedDecl) delayed_imports;
|
||||
Array(DelayedDecl) delayed_foreign_libraries;
|
||||
|
||||
|
||||
gbArena arena;
|
||||
|
||||
+45
-18
@@ -54,30 +54,57 @@ ExactValue make_exact_value_string(String string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue make_exact_value_integer_from_string(String string) {
|
||||
// TODO(bill): Allow for numbers with underscores in them
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
i32 base = 10;
|
||||
if (string.len > 2 && string.text[0] == '0') {
|
||||
switch (string.text[1]) {
|
||||
case 'b': base = 2; break;
|
||||
case 'o': base = 8; break;
|
||||
case 'd': base = 10; break;
|
||||
case 'x': base = 16; break;
|
||||
}
|
||||
}
|
||||
|
||||
result.value_integer = gb_str_to_i64(cast(char *)string.text, NULL, base);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue make_exact_value_integer(i64 i) {
|
||||
ExactValue result = {ExactValue_Integer};
|
||||
result.value_integer = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue make_exact_value_integer_from_string(String string) {
|
||||
// TODO(bill): Allow for numbers with underscores in them
|
||||
i32 base = 10;
|
||||
bool has_prefix = false;
|
||||
if (string.len > 2 && string.text[0] == '0') {
|
||||
switch (string.text[1]) {
|
||||
case 'b': base = 2; has_prefix = true; break;
|
||||
case 'o': base = 8; has_prefix = true; break;
|
||||
case 'd': base = 10; has_prefix = true; break;
|
||||
case 'x': base = 16; has_prefix = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 *text = string.text;
|
||||
isize len = string.len;
|
||||
if (has_prefix) {
|
||||
text += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
i64 result = 0;
|
||||
for (isize i = 0; i < len; i++) {
|
||||
Rune r = cast(Rune)text[i];
|
||||
if (r == '_') {
|
||||
continue;
|
||||
}
|
||||
i64 v = 0;
|
||||
if (gb_char_is_digit(r)) {
|
||||
v = r - '0';
|
||||
} else if (gb_char_is_hex_digit(r)) {
|
||||
v = gb_hex_digit_to_int(r);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
result *= base;
|
||||
result += v;
|
||||
}
|
||||
|
||||
|
||||
return make_exact_value_integer(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ExactValue make_exact_value_float_from_string(String string) {
|
||||
// TODO(bill): Allow for numbers with underscores in them
|
||||
ExactValue result = {ExactValue_Float};
|
||||
|
||||
+4
-5
@@ -1770,11 +1770,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
case Token_Hash: {
|
||||
Token token = expect_token(f, Token_Hash);
|
||||
Token name = expect_token(f, Token_Ident);
|
||||
if (str_eq(name.string, str_lit("file"))) {
|
||||
return make_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("line"))) {
|
||||
return make_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("run"))) {
|
||||
if (str_eq(name.string, str_lit("run"))) {
|
||||
AstNode *expr = parse_expr(f, false);
|
||||
operand = make_run_expr(f, token, name, expr);
|
||||
if (unparen_expr(expr)->kind != AstNode_CallExpr) {
|
||||
@@ -1782,6 +1778,9 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
operand = make_bad_expr(f, token, f->curr_token);
|
||||
}
|
||||
warning(token, "#run is not yet implemented");
|
||||
} else if (str_eq(name.string, str_lit("file"))) { return make_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("line"))) { return make_basic_directive(f, token, name.string);
|
||||
} else if (str_eq(name.string, str_lit("procedure"))) { return make_basic_directive(f, token, name.string);
|
||||
} else {
|
||||
operand = make_tag_expr(f, token, name, parse_expr(f, false));
|
||||
}
|
||||
|
||||
+18
-15
@@ -462,12 +462,15 @@ gb_inline i32 digit_value(Rune r) {
|
||||
return 16; // NOTE(bill): Larger than highest possible
|
||||
}
|
||||
|
||||
gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
|
||||
// TODO(bill): Allow for underscores in numbers as a number separator
|
||||
// TODO(bill): Is this a good idea?
|
||||
// while (digit_value(t->curr_rune) < base || t->curr_rune == '_')
|
||||
while (digit_value(t->curr_rune) < base) {
|
||||
advance_to_next_rune(t);
|
||||
gb_inline void scan_mantissa(Tokenizer *t, i32 base, bool allow_underscore) {
|
||||
if (allow_underscore) {
|
||||
while (digit_value(t->curr_rune) < base || t->curr_rune == '_') {
|
||||
advance_to_next_rune(t);
|
||||
}
|
||||
} else {
|
||||
while (digit_value(t->curr_rune) < base) {
|
||||
advance_to_next_rune(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +485,7 @@ Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
||||
|
||||
if (seen_decimal_point) {
|
||||
token.kind = Token_Float;
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, true);
|
||||
goto exponent;
|
||||
}
|
||||
|
||||
@@ -491,31 +494,31 @@ Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
||||
advance_to_next_rune(t);
|
||||
if (t->curr_rune == 'b') { // Binary
|
||||
advance_to_next_rune(t);
|
||||
scan_mantissa(t, 2);
|
||||
scan_mantissa(t, 2, true);
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
}
|
||||
} else if (t->curr_rune == 'o') { // Octal
|
||||
advance_to_next_rune(t);
|
||||
scan_mantissa(t, 8);
|
||||
scan_mantissa(t, 8, true);
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
}
|
||||
} else if (t->curr_rune == 'd') { // Decimal
|
||||
advance_to_next_rune(t);
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, true);
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
}
|
||||
} else if (t->curr_rune == 'x') { // Hexadecimal
|
||||
advance_to_next_rune(t);
|
||||
scan_mantissa(t, 16);
|
||||
scan_mantissa(t, 16, true);
|
||||
if (t->curr - prev <= 2) {
|
||||
token.kind = Token_Invalid;
|
||||
}
|
||||
} else {
|
||||
seen_decimal_point = false;
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, true);
|
||||
|
||||
if (t->curr_rune == '.' || t->curr_rune == 'e' || t->curr_rune == 'E') {
|
||||
seen_decimal_point = true;
|
||||
@@ -527,7 +530,7 @@ Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
||||
return token;
|
||||
}
|
||||
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, true);
|
||||
|
||||
fraction:
|
||||
if (t->curr_rune == '.') {
|
||||
@@ -540,7 +543,7 @@ fraction:
|
||||
goto end;
|
||||
}
|
||||
token.kind = Token_Float;
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, true);
|
||||
}
|
||||
|
||||
exponent:
|
||||
@@ -550,7 +553,7 @@ exponent:
|
||||
if (t->curr_rune == '-' || t->curr_rune == '+') {
|
||||
advance_to_next_rune(t);
|
||||
}
|
||||
scan_mantissa(t, 10);
|
||||
scan_mantissa(t, 10, false);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
Reference in New Issue
Block a user