closer to guess number example working
This commit is contained in:
@@ -102,6 +102,8 @@ const char *node_type_str(NodeType node_type) {
|
||||
return "NumberLiteral";
|
||||
case NodeTypeStringLiteral:
|
||||
return "StringLiteral";
|
||||
case NodeTypeCharLiteral:
|
||||
return "CharLiteral";
|
||||
case NodeTypeUnreachable:
|
||||
return "Unreachable";
|
||||
case NodeTypeSymbol:
|
||||
@@ -313,6 +315,11 @@ void ast_print(AstNode *node, int indent) {
|
||||
buf_ptr(&node->data.string_literal.buf));
|
||||
break;
|
||||
}
|
||||
case NodeTypeCharLiteral:
|
||||
{
|
||||
fprintf(stderr, "%s '%c'\n", node_type_str(node->type), node->data.char_literal.value);
|
||||
break;
|
||||
}
|
||||
case NodeTypeUnreachable:
|
||||
fprintf(stderr, "Unreachable\n");
|
||||
break;
|
||||
@@ -575,6 +582,55 @@ static void parse_asm_template(ParseContext *pc, AstNode *node) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t parse_char_literal(ParseContext *pc, Token *token) {
|
||||
// skip the single quotes at beginning and end
|
||||
// convert escape sequences
|
||||
bool escape = false;
|
||||
int return_count = 0;
|
||||
uint8_t return_value;
|
||||
for (int i = token->start_pos + 1; i < token->end_pos - 1; i += 1) {
|
||||
uint8_t c = *((uint8_t*)buf_ptr(pc->buf) + i);
|
||||
if (escape) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
return_value = '\\';
|
||||
return_count += 1;
|
||||
break;
|
||||
case 'r':
|
||||
return_value = '\r';
|
||||
return_count += 1;
|
||||
break;
|
||||
case 'n':
|
||||
return_value = '\n';
|
||||
return_count += 1;
|
||||
break;
|
||||
case 't':
|
||||
return_value = '\t';
|
||||
return_count += 1;
|
||||
break;
|
||||
case '\'':
|
||||
return_value = '\'';
|
||||
return_count += 1;
|
||||
break;
|
||||
default:
|
||||
ast_error(pc, token, "invalid escape character");
|
||||
}
|
||||
escape = false;
|
||||
} else if (c == '\\') {
|
||||
escape = true;
|
||||
} else {
|
||||
return_value = c;
|
||||
return_count += 1;
|
||||
}
|
||||
}
|
||||
if (return_count == 0) {
|
||||
ast_error(pc, token, "character literal too short");
|
||||
} else if (return_count > 1) {
|
||||
ast_error(pc, token, "character literal too long");
|
||||
}
|
||||
return return_count;
|
||||
}
|
||||
|
||||
static void parse_string_literal(ParseContext *pc, Token *token, Buf *buf, bool *out_c_str,
|
||||
ZigList<SrcPos> *offset_map)
|
||||
{
|
||||
@@ -620,6 +676,9 @@ static void parse_string_literal(ParseContext *pc, Token *token, Buf *buf, bool
|
||||
buf_append_char(buf, '"');
|
||||
if (offset_map) offset_map->append(pos);
|
||||
break;
|
||||
default:
|
||||
ast_error(pc, token, "invalid escape character");
|
||||
break;
|
||||
}
|
||||
escape = false;
|
||||
} else if (c == '\\') {
|
||||
@@ -1136,7 +1195,7 @@ static AstNode *ast_parse_struct_val_expr(ParseContext *pc, int *token_index) {
|
||||
}
|
||||
|
||||
/*
|
||||
PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | Goto | token(Break) | token(Continue) | BlockExpression | token(Symbol) | StructValueExpression
|
||||
PrimaryExpression : token(Number) | token(String) | token(CharLiteral) | KeywordLiteral | GroupedExpression | Goto | token(Break) | token(Continue) | BlockExpression | token(Symbol) | StructValueExpression
|
||||
*/
|
||||
static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@@ -1151,6 +1210,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
|
||||
parse_string_literal(pc, token, &node->data.string_literal.buf, &node->data.string_literal.c, nullptr);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdCharLiteral) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeCharLiteral, token);
|
||||
node->data.char_literal.value = parse_char_literal(pc, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordUnreachable) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token);
|
||||
*token_index += 1;
|
||||
@@ -1733,7 +1797,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
|
||||
}
|
||||
|
||||
/*
|
||||
VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
VariableDeclaration : option(FnVisibleMod) (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
*/
|
||||
static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *var_or_const_tok = &pc->tokens->at(*token_index);
|
||||
|
||||
Reference in New Issue
Block a user