Set :: as a single token

This commit is contained in:
Ginger Bill
2016-12-07 10:20:25 +00:00
parent d9bd770992
commit 60b6538a7a
5 changed files with 128 additions and 118 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
// IMPORTANT NOTE(bill): Do not change the order of any of this data
// The compiler relies upon this _exact_ order
Type_Info :: union {
Member :: type struct #ordered {
Member :: struct #ordered {
name: string; // can be empty if tuple
type_info: ^Type_Info
offset: int; // offsets are not used in tuples
+1 -1
View File
@@ -46,7 +46,7 @@ encode_rune :: proc(r_: rune) -> ([4]byte, int) {
r := r_
buf: [4]byte
i := r as u32
mask: byte : 0x3f
mask :: 0x3f as byte
if i <= 1<<7-1 {
buf[0] = r as byte
return buf, 1
+3 -3
View File
@@ -110,8 +110,8 @@ WIN32_FILE_ATTRIBUTE_DATA :: struct #ordered {
}
GET_FILEEX_INFO_LEVELS :: type i32
GetFileExInfoStandard : GET_FILEEX_INFO_LEVELS : 0
GetFileExMaxInfoLevel : GET_FILEEX_INFO_LEVELS : 1
GetFileExInfoStandard :: 0 as GET_FILEEX_INFO_LEVELS
GetFileExMaxInfoLevel :: 1 as GET_FILEEX_INFO_LEVELS
GetLastError :: proc() -> i32 #foreign #dll_import
ExitProcess :: proc(exit_code: u32) #foreign #dll_import
@@ -232,7 +232,7 @@ RGBQUAD :: struct #ordered {
BI_RGB :: 0
DIB_RGB_COLORS :: 0x00
SRCCOPY : u32 : 0x00cc0020
SRCCOPY :: 0x00cc0020 as u32
StretchDIBits :: proc(hdc: HDC,
x_dst, y_dst, width_dst, height_dst: i32,
+118 -113
View File
@@ -102,9 +102,11 @@ AstNodeArray make_ast_node_array(AstFile *f) {
AstNode *expr; \
}) \
AST_NODE_KIND(ProcLit, "procedure literal", struct { \
AstNode *type; \
AstNode *body; \
u64 tags; \
AstNode *type; \
AstNode *body; \
u64 tags; \
String foreign_name; \
String link_name; \
}) \
AST_NODE_KIND(CompoundLit, "compound literal", struct { \
AstNode *type; \
@@ -245,7 +247,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
u64 tags; \
String foreign_name; \
String link_name; \
AstNode *note; \
AstNode *note; \
}) \
AST_NODE_KIND(TypeDecl, "type declaration", struct { \
Token token; \
@@ -277,6 +279,7 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
Token token; \
AstNodeArray params; \
AstNodeArray results; \
u64 tags; \
}) \
AST_NODE_KIND(PointerType, "pointer type", struct { \
Token token; \
@@ -683,11 +686,13 @@ AstNode *make_ellipsis(AstFile *f, Token token, AstNode *expr) {
}
AstNode *make_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags) {
AstNode *make_proc_lit(AstFile *f, AstNode *type, AstNode *body, u64 tags, String foreign_name, String link_name) {
AstNode *result = make_node(f, AstNode_ProcLit);
result->ProcLit.type = type;
result->ProcLit.body = body;
result->ProcLit.tags = tags;
result->ProcLit.foreign_name = foreign_name;
result->ProcLit.link_name = link_name;
return result;
}
@@ -912,11 +917,12 @@ AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, bool is_u
return result;
}
AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results) {
AstNode *make_proc_type(AstFile *f, Token token, AstNodeArray params, AstNodeArray results, u64 tags) {
AstNode *result = make_node(f, AstNode_ProcType);
result->ProcType.token = token;
result->ProcType.params = params;
result->ProcType.results = results;
result->ProcType.tags = tags;
return result;
}
@@ -1300,7 +1306,7 @@ AstNode *parse_value(AstFile *f) {
return value;
}
AstNode *parse_identifier_or_type(AstFile *f, u32 flags);
AstNode *parse_identifier_or_type(AstFile *f);
void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, String tag_name) {
@@ -1544,14 +1550,17 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
body = parse_body(f);
f->expr_level--;
type = make_proc_lit(f, type, body, tags);
type = make_proc_lit(f, type, body, tags, foreign_name, link_name);
} else if (type != NULL && type->kind == AstNode_ProcType) {
type->ProcType.tags = tags;
}
f->curr_proc = curr_proc;
return type;
}
default: {
AstNode *type = parse_identifier_or_type(f, 0);
AstNode *type = parse_identifier_or_type(f);
if (type != NULL) {
// NOTE(bill): Sanity check as identifiers should be handled already
GB_ASSERT_MSG(type->kind != AstNode_Ident, "Type Cannot be identifier");
@@ -1832,7 +1841,22 @@ AstNodeArray parse_rhs_expr_list(AstFile *f) {
return parse_expr_list(f, false);
}
AstNode *parse_decl(AstFile *f, AstNodeArray names);
void parse_check_name_list_for_reserves(AstFile *f, AstNodeArray names) {
for_array(i, names) {
AstNode *name = names.e[i];
if (name->kind == AstNode_Ident) {
String n = name->Ident.string;
// NOTE(bill): Check for reserved identifiers
if (str_eq(n, str_lit("context"))) {
syntax_error_node(name, "`context` is a reserved identifier");
break;
}
}
}
}
AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name);
AstNode *parse_simple_stmt(AstFile *f) {
isize lhs_count = 0, rhs_count = 0;
@@ -1870,8 +1894,83 @@ AstNode *parse_simple_stmt(AstFile *f) {
return make_assign_stmt(f, token, lhs, rhs);
} break;
case Token_Colon: // Declare
return parse_decl(f, lhs);
case Token_Colon: { // Declare
AstNodeArray names = lhs;
parse_check_name_list_for_reserves(f, names);
Token colon = expect_token(f, Token_Colon);
AstNode *type = parse_identifier_or_type(f);
AstNodeArray values = {0};
if (allow_token(f, Token_Eq)) {
values = parse_rhs_expr_list(f);
if (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (values.count == 0) {
syntax_error(f->curr_token, "Expected an expression for this declaration");
}
if (type == NULL && values.count == 0) {
syntax_error(f->curr_token, "Missing variable type or initialization");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
}
if (values.e == NULL) {
values = make_ast_node_array(f);
}
return make_var_decl(f, names, type, values);
} break;
case Token_ColonColon: {
AstNodeArray names = lhs;
parse_check_name_list_for_reserves(f, names);
Token colon_colon = expect_token(f, Token_ColonColon);
if (f->curr_token.kind == Token_type ||
f->curr_token.kind == Token_struct ||
f->curr_token.kind == Token_enum ||
f->curr_token.kind == Token_union ||
f->curr_token.kind == Token_raw_union) {
Token token = f->curr_token;
if (token.kind == Token_type) {
next_token(f);
}
if (names.count != 1) {
syntax_error_node(names.e[0], "You can only declare one type at a time");
return make_bad_decl(f, names.e[0]->Ident, token);
}
return make_type_decl(f, token, names.e[0], parse_type(f));
} else if (f->curr_token.kind == Token_proc) {
// NOTE(bill): Procedure declarations
Token proc_token = f->curr_token;
AstNode *name = names.e[0];
if (names.count != 1) {
syntax_error(proc_token, "You can only declare one procedure at a time");
return make_bad_decl(f, name->Ident, proc_token);
}
return parse_proc_decl(f, proc_token, name);
}
AstNodeArray values = parse_rhs_expr_list(f);
if (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (values.count < names.count) {
syntax_error(f->curr_token, "All constant declarations must be defined");
} else if (values.count == 0) {
syntax_error(f->curr_token, "Expected an expression for this declaration");
}
if (values.count == 0 && names.count > 0) {
syntax_error(f->curr_token, "Missing constant value");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
return make_const_decl(f, names, NULL, values);
} break;
}
if (lhs_count > 1) {
@@ -1936,7 +2035,7 @@ AstNodeArray parse_identfier_list(AstFile *f) {
AstNode *parse_type_attempt(AstFile *f) {
AstNode *type = parse_identifier_or_type(f, 0);
AstNode *type = parse_identifier_or_type(f);
if (type != NULL) {
// TODO(bill): Handle?
}
@@ -1963,7 +2062,7 @@ AstNode *parse_proc_type(AstFile *f) {
Token proc_token = parse_proc_signature(f, &params, &results);
return make_proc_type(f, proc_token, params, results);
return make_proc_type(f, proc_token, params, results, 0);
}
@@ -2087,7 +2186,7 @@ AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool using_allo
return decls;
}
AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
AstNode *parse_identifier_or_type(AstFile *f) {
switch (f->curr_token.kind) {
case Token_Ident: {
AstNode *e = parse_identifier(f);
@@ -2104,6 +2203,10 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
return e;
}
case Token_type:
expect_token(f, Token_type);
return parse_identifier_or_type(f);
case Token_Pointer: {
Token token = expect_token(f, Token_Pointer);
AstNode *elem = parse_type(f);
@@ -2342,104 +2445,6 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
return make_proc_decl(f, name, proc_type, body, tags, foreign_name, link_name);
}
AstNode *parse_decl(AstFile *f, AstNodeArray names) {
AstNodeArray values = {0};
AstNode *type = NULL;
for_array(i, names) {
AstNode *name = names.e[i];
if (name->kind == AstNode_Ident) {
String n = name->Ident.string;
// NOTE(bill): Check for reserved identifiers
if (str_eq(n, str_lit("context"))) {
syntax_error_node(name, "`context` is a reserved identifier");
break;
}
}
}
if (allow_token(f, Token_Colon)) {
if (!allow_token(f, Token_type)) {
type = parse_identifier_or_type(f, 0);
}
} else if (f->curr_token.kind != Token_Eq && f->curr_token.kind != Token_Semicolon) {
syntax_error(f->curr_token, "Expected type separator `:` or `=`");
}
bool is_mutable = true;
if (f->curr_token.kind == Token_Eq || f->curr_token.kind == Token_Colon) {
if (f->curr_token.kind == Token_Colon) {
is_mutable = false;
}
next_token(f);
if (f->curr_token.kind == Token_type ||
f->curr_token.kind == Token_struct ||
f->curr_token.kind == Token_enum ||
f->curr_token.kind == Token_union ||
f->curr_token.kind == Token_raw_union) {
Token token = f->curr_token;
if (token.kind == Token_type) {
next_token(f);
}
if (names.count != 1) {
syntax_error_node(names.e[0], "You can only declare one type at a time");
return make_bad_decl(f, names.e[0]->Ident, token);
}
if (type != NULL) {
syntax_error(f->prev_token, "Expected either `type` or nothing between : and :");
// NOTE(bill): Do not fail though
}
return make_type_decl(f, token, names.e[0], parse_type(f));
} else if (f->curr_token.kind == Token_proc && is_mutable == false) {
// NOTE(bill): Procedure declarations
Token proc_token = f->curr_token;
AstNode *name = names.e[0];
if (names.count != 1) {
syntax_error(proc_token, "You can only declare one procedure at a time");
return make_bad_decl(f, name->Ident, proc_token);
}
return parse_proc_decl(f, proc_token, name);
} else {
values = parse_rhs_expr_list(f);
if (values.count > names.count) {
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
} else if (values.count < names.count && !is_mutable) {
syntax_error(f->curr_token, "All constant declarations must be defined");
} else if (values.count == 0) {
syntax_error(f->curr_token, "Expected an expression for this declaration");
}
}
}
if (is_mutable) {
if (type == NULL && values.count == 0) {
syntax_error(f->curr_token, "Missing variable type or initialization");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
} else {
if (type == NULL && values.count == 0 && names.count > 0) {
syntax_error(f->curr_token, "Missing constant value");
return make_bad_decl(f, f->curr_token, f->curr_token);
}
}
if (values.e == NULL) {
values = make_ast_node_array(f);
}
if (is_mutable) {
return make_var_decl(f, names, type, values);
}
return make_const_decl(f, names, type, values);
}
AstNode *parse_if_stmt(AstFile *f) {
if (f->curr_proc == NULL) {
syntax_error(f->curr_token, "You cannot use an if statement in the file scope");
+5
View File
@@ -74,6 +74,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
TOKEN_KIND(Token_OpenBrace, "{"), \
TOKEN_KIND(Token_CloseBrace, "}"), \
TOKEN_KIND(Token_Colon, ":"), \
TOKEN_KIND(Token_ColonColon, "::"), \
TOKEN_KIND(Token_Semicolon, ";"), \
TOKEN_KIND(Token_Period, "."), \
TOKEN_KIND(Token_Comma, ","), \
@@ -871,6 +872,10 @@ Token tokenizer_get_token(Tokenizer *t) {
break;
case ':':
token.kind = Token_Colon;
if (t->curr_rune == ':') {
advance_to_next_rune(t);
token.kind = Token_ColonColon;
}
break;
case '(':
token.kind = Token_OpenParen;