Skip to content
This repository has been archived by the owner on May 31, 2018. It is now read-only.

Commit

Permalink
lexer: insert semicolon after end of line for less erroneous expressi…
Browse files Browse the repository at this point in the history
…on parsing
  • Loading branch information
glhrmfrts committed Feb 28, 2016
1 parent ab916b4 commit dce7dd1
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 10 deletions.
5 changes: 2 additions & 3 deletions examples/declaration.luna
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# declaration

let a = 2
b = 5
let a = 2, b = "foo"

type foo
a, b: int
Expand All @@ -24,7 +23,7 @@ def repeat(a: string, n = 0)
let res: string
while n > 0
res += a
n -= 1
--n
end
return res
end
15 changes: 14 additions & 1 deletion src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@

#define error(msg) (self->error = msg, token(ILLEGAL))

/*
* True if the lexer should insert a semicolon after `t`.
*/

#define need_semi(t) \
(t == LUNA_TOKEN_ID || t == LUNA_TOKEN_FLOAT || t == LUNA_TOKEN_INT || \
t == LUNA_TOKEN_STRING || t == LUNA_TOKEN_RETURN)

/*
* Initialize lexer with the given `source` and `filename`.
*/
Expand Down Expand Up @@ -267,7 +275,6 @@ scan_number(luna_lexer_t *self, int c) {
int
luna_scan(luna_lexer_t *self) {
int c;
token(ILLEGAL);

// scan
scan:
Expand Down Expand Up @@ -350,8 +357,13 @@ luna_scan(luna_lexer_t *self) {
case '#':
while ((c = next) != '\n' && c) ; undo;
goto scan;
case ';':
return token(SEMICOLON);
case '\n':
case '\r':
if (need_semi(self->tok.type)) {
return undo, token(SEMICOLON);
}
++self->lineno;
goto scan;
case '"':
Expand All @@ -363,6 +375,7 @@ luna_scan(luna_lexer_t *self) {
default:
if (isalpha(c) || '_' == c) return scan_ident(self, c);
if (isdigit(c) || '.' == c) return scan_number(self, c);
token(ILLEGAL);
error("illegal character");
return 0;
}
Expand Down
23 changes: 21 additions & 2 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ unary_expr(luna_parser_t *self) {
|| is(OP_PLUS)
|| is(OP_MINUS)
|| is(OP_NOT)) {
luna_token_t *op = self->tok;
int op = self->tok->type;
next;
return (luna_node_t *) luna_unary_op_node_new(op->type, unary_expr(self), 0);
return (luna_node_t *) luna_unary_op_node_new(op, unary_expr(self), 0);
}
return postfix_expr(self);
}
Expand Down Expand Up @@ -931,11 +931,17 @@ type_stmt(luna_parser_t *self) {
type = luna_type_node_new(name);
next;

// semicolon might have been inserted here
accept(SEMICOLON);

// type fields
do {
luna_node_t *decl = decl_expr(self, true);
if (!decl) return error("expecting field");

// semicolon might have been inserted here
accept(SEMICOLON);

luna_vec_push(type->fields, luna_node(decl));
} while (!accept(END));

Expand Down Expand Up @@ -1013,6 +1019,9 @@ if_stmt(luna_parser_t *self) {
return NULL;
}

// semicolon might have been inserted here
accept(SEMICOLON);

// block
context("if statement");
if (!(body = block(self))) {
Expand All @@ -1030,6 +1039,10 @@ if_stmt(luna_parser_t *self) {
if (accept(IF)) {
context("else if statement condition");
if (!(cond = expr(self))) return NULL;

// semicolon might have been inserted here
accept(SEMICOLON);

context("else if statement");
if (!(body = block(self))) return NULL;
luna_vec_push(node->else_ifs, luna_node((luna_node_t *) luna_if_node_new(0, cond, body)));
Expand Down Expand Up @@ -1066,6 +1079,9 @@ while_stmt(luna_parser_t *self) {
if (!(cond = expr(self))) return NULL;
context("while statement");

// semicolon might have been inserted here
accept(SEMICOLON);

// block
if (!(body = block(self))) return NULL;

Expand Down Expand Up @@ -1126,6 +1142,8 @@ block(luna_parser_t *self) {

do {
if (!(node = stmt(self))) return NULL;
accept(SEMICOLON);

luna_vec_push(block->stmts, luna_node(node));
} while (!accept(END) && !is(ELSE));

Expand All @@ -1145,6 +1163,7 @@ program(luna_parser_t *self) {
next;
while (!is(EOS)) {
if (node = stmt(self)) {
accept(SEMICOLON);
luna_vec_push(block->stmts, luna_node(node));
} else {
return NULL;
Expand Down
13 changes: 10 additions & 3 deletions src/prettyprint.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,16 @@ visit_string(luna_visitor_t *self, luna_string_node_t *node) {

static void
visit_unary_op(luna_visitor_t *self, luna_unary_op_node_t *node) {
int c = node->postfix ? '@' : 0;
print_func("(%c%s ", c, luna_token_type_string(node->op));
visit(node->expr);
print_func("(");

if (node->postfix) {
visit(node->expr);
print_func(" %s", luna_token_type_string(node->op));
} else {
print_func("%s ", luna_token_type_string(node->op));
visit(node->expr);
}

print_func(")");
}

Expand Down
2 changes: 1 addition & 1 deletion src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ file_read(const char *filename) {
size_t read = fread(buf, sizeof(char), len, fh);

fclose(fh);
buf[len] = 0;
buf[read] = 0;
return buf;
}

Expand Down

0 comments on commit dce7dd1

Please sign in to comment.