add bool literals

This commit is contained in:
Josh Wolfe 2015-12-03 12:15:07 -07:00
parent 6494cf208e
commit f1aaf1353e
8 changed files with 52 additions and 2 deletions

View File

@ -163,11 +163,13 @@ FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)
PrefixOp : token(Not) | token(Dash) | token(Tilde) PrefixOp : token(Not) | token(Dash) | token(Tilde)
PrimaryExpression : token(Number) | token(String) | token(Unreachable) | GroupedExpression | token(Symbol) | Goto PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | token(Symbol) | Goto
Goto: token(Goto) token(Symbol) Goto: token(Goto) token(Symbol)
GroupedExpression : token(LParen) Expression token(RParen) GroupedExpression : token(LParen) Expression token(RParen)
KeywordLiteral : token(Unreachable) | token(Void) | token(True) | token(False)
``` ```
### Operator Precedence ### Operator Precedence

View File

@ -4,6 +4,12 @@ extern {
fn exit(code: i32) -> unreachable; fn exit(code: i32) -> unreachable;
} }
fn other_exit() -> unreachable {
if (true) { exit(0); }
// the unreachable statement is the programmer assuring the compiler that this code is impossible to execute.
unreachable;
}
export fn _start() -> unreachable { export fn _start() -> unreachable {
let a : i32 = 1; let a : i32 = 1;
let b = 2; let b = 2;
@ -19,5 +25,5 @@ export fn _start() -> unreachable {
no_conflict no_conflict
}; };
if (c == 10) { puts("OK 2"); } if (c == 10) { puts("OK 2"); }
exit(0); other_exit();
} }

View File

@ -297,6 +297,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
case NodeTypeStringLiteral: case NodeTypeStringLiteral:
case NodeTypeUnreachable: case NodeTypeUnreachable:
case NodeTypeVoid: case NodeTypeVoid:
case NodeTypeBoolLiteral:
case NodeTypeSymbol: case NodeTypeSymbol:
case NodeTypeCastExpr: case NodeTypeCastExpr:
case NodeTypePrefixOpExpr: case NodeTypePrefixOpExpr:
@ -592,6 +593,10 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
return_type = g->builtin_types.entry_void; return_type = g->builtin_types.entry_void;
break; break;
case NodeTypeBoolLiteral:
return_type = g->builtin_types.entry_bool;
break;
case NodeTypeSymbol: case NodeTypeSymbol:
{ {
Buf *symbol_name = &node->data.symbol; Buf *symbol_name = &node->data.symbol;
@ -766,6 +771,7 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
case NodeTypeStringLiteral: case NodeTypeStringLiteral:
case NodeTypeUnreachable: case NodeTypeUnreachable:
case NodeTypeVoid: case NodeTypeVoid:
case NodeTypeBoolLiteral:
case NodeTypeSymbol: case NodeTypeSymbol:
case NodeTypeCastExpr: case NodeTypeCastExpr:
case NodeTypePrefixOpExpr: case NodeTypePrefixOpExpr:

View File

@ -487,6 +487,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
return LLVMBuildUnreachable(g->builder); return LLVMBuildUnreachable(g->builder);
case NodeTypeVoid: case NodeTypeVoid:
return nullptr; return nullptr;
case NodeTypeBoolLiteral:
if (node->data.bool_literal)
return LLVMConstAllOnes(LLVMInt1Type());
else
return LLVMConstNull(LLVMInt1Type());
case NodeTypeIfExpr: case NodeTypeIfExpr:
return gen_if_expr(g, node); return gen_if_expr(g, node);
case NodeTypeNumberLiteral: case NodeTypeNumberLiteral:

View File

@ -93,6 +93,8 @@ const char *node_type_str(NodeType node_type) {
return "Use"; return "Use";
case NodeTypeVoid: case NodeTypeVoid:
return "Void"; return "Void";
case NodeTypeBoolLiteral:
return "BoolLiteral";
case NodeTypeIfExpr: case NodeTypeIfExpr:
return "IfExpr"; return "IfExpr";
case NodeTypeLabel: case NodeTypeLabel:
@ -256,6 +258,9 @@ void ast_print(AstNode *node, int indent) {
case NodeTypeVoid: case NodeTypeVoid:
fprintf(stderr, "%s\n", node_type_str(node->type)); fprintf(stderr, "%s\n", node_type_str(node->type));
break; break;
case NodeTypeBoolLiteral:
fprintf(stderr, "%s '%s'\n", node_type_str(node->type), node->data.bool_literal ? "true" : "false");
break;
case NodeTypeIfExpr: case NodeTypeIfExpr:
fprintf(stderr, "%s\n", node_type_str(node->type)); fprintf(stderr, "%s\n", node_type_str(node->type));
if (node->data.if_expr.condition) if (node->data.if_expr.condition)
@ -457,6 +462,12 @@ static AstNode *ast_parse_type(ParseContext *pc, int token_index, int *new_token
} else if (token->id == TokenIdKeywordVoid) { } else if (token->id == TokenIdKeywordVoid) {
node->data.type.type = AstNodeTypeTypePrimitive; node->data.type.type = AstNodeTypeTypePrimitive;
buf_init_from_str(&node->data.type.primitive_name, "void"); buf_init_from_str(&node->data.type.primitive_name, "void");
} else if (token->id == TokenIdKeywordTrue) {
node->data.type.type = AstNodeTypeTypePrimitive;
buf_init_from_str(&node->data.type.primitive_name, "true");
} else if (token->id == TokenIdKeywordFalse) {
node->data.type.type = AstNodeTypeTypePrimitive;
buf_init_from_str(&node->data.type.primitive_name, "false");
} else if (token->id == TokenIdSymbol) { } else if (token->id == TokenIdSymbol) {
node->data.type.type = AstNodeTypeTypePrimitive; node->data.type.type = AstNodeTypeTypePrimitive;
ast_buf_from_token(pc, token, &node->data.type.primitive_name); ast_buf_from_token(pc, token, &node->data.type.primitive_name);
@ -614,6 +625,16 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
AstNode *node = ast_create_node(pc, NodeTypeVoid, token); AstNode *node = ast_create_node(pc, NodeTypeVoid, token);
*token_index += 1; *token_index += 1;
return node; return node;
} else if (token->id == TokenIdKeywordTrue) {
AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
node->data.bool_literal = true;
*token_index += 1;
return node;
} else if (token->id == TokenIdKeywordFalse) {
AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
node->data.bool_literal = false;
*token_index += 1;
return node;
} else if (token->id == TokenIdSymbol) { } else if (token->id == TokenIdSymbol) {
AstNode *node = ast_create_node(pc, NodeTypeSymbol, token); AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
ast_buf_from_token(pc, token, &node->data.symbol); ast_buf_from_token(pc, token, &node->data.symbol);

View File

@ -40,6 +40,7 @@ enum NodeType {
NodeTypeFnCallExpr, NodeTypeFnCallExpr,
NodeTypeUse, NodeTypeUse,
NodeTypeVoid, NodeTypeVoid,
NodeTypeBoolLiteral,
NodeTypeIfExpr, NodeTypeIfExpr,
NodeTypeLabel, NodeTypeLabel,
NodeTypeGoto, NodeTypeGoto,
@ -222,6 +223,7 @@ struct AstNode {
Buf number; Buf number;
Buf string; Buf string;
Buf symbol; Buf symbol;
bool bool_literal;
} data; } data;
}; };

View File

@ -185,6 +185,10 @@ static void end_token(Tokenize *t) {
t->cur_tok->id = TokenIdKeywordUse; t->cur_tok->id = TokenIdKeywordUse;
} else if (mem_eql_str(token_mem, token_len, "void")) { } else if (mem_eql_str(token_mem, token_len, "void")) {
t->cur_tok->id = TokenIdKeywordVoid; t->cur_tok->id = TokenIdKeywordVoid;
} else if (mem_eql_str(token_mem, token_len, "true")) {
t->cur_tok->id = TokenIdKeywordTrue;
} else if (mem_eql_str(token_mem, token_len, "false")) {
t->cur_tok->id = TokenIdKeywordFalse;
} else if (mem_eql_str(token_mem, token_len, "if")) { } else if (mem_eql_str(token_mem, token_len, "if")) {
t->cur_tok->id = TokenIdKeywordIf; t->cur_tok->id = TokenIdKeywordIf;
} else if (mem_eql_str(token_mem, token_len, "else")) { } else if (mem_eql_str(token_mem, token_len, "else")) {
@ -586,6 +590,8 @@ static const char * token_name(Token *token) {
case TokenIdKeywordAs: return "As"; case TokenIdKeywordAs: return "As";
case TokenIdKeywordUse: return "Use"; case TokenIdKeywordUse: return "Use";
case TokenIdKeywordVoid: return "Void"; case TokenIdKeywordVoid: return "Void";
case TokenIdKeywordTrue: return "True";
case TokenIdKeywordFalse: return "False";
case TokenIdKeywordIf: return "If"; case TokenIdKeywordIf: return "If";
case TokenIdKeywordElse: return "Else"; case TokenIdKeywordElse: return "Else";
case TokenIdKeywordGoto: return "Goto"; case TokenIdKeywordGoto: return "Goto";

View File

@ -25,6 +25,8 @@ enum TokenId {
TokenIdKeywordAs, TokenIdKeywordAs,
TokenIdKeywordUse, TokenIdKeywordUse,
TokenIdKeywordVoid, TokenIdKeywordVoid,
TokenIdKeywordTrue,
TokenIdKeywordFalse,
TokenIdKeywordIf, TokenIdKeywordIf,
TokenIdKeywordElse, TokenIdKeywordElse,
TokenIdKeywordGoto, TokenIdKeywordGoto,