Skip to content

Commit 0da5f57

Browse files
committed
feat(semantic): add array parsing
1 parent bede885 commit 0da5f57

File tree

13 files changed

+469
-50
lines changed

13 files changed

+469
-50
lines changed

src/ast.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ static void ast_expr_destroy(AstExpr *expr)
167167
}
168168
free(expr->data.call.args.items);
169169
break;
170+
case EXPR_ARRAY_LITERAL:
171+
ast_expr_list_destroy(&expr->data.array_literal.elements);
172+
break;
173+
case EXPR_SUBSCRIPT:
174+
ast_expr_destroy(expr->data.subscript.array);
175+
ast_expr_destroy(expr->data.subscript.index);
176+
break;
170177
case EXPR_INT_LITERAL:
171178
case EXPR_FLOAT_LITERAL:
172179
case EXPR_BOOL_LITERAL:
@@ -227,11 +234,20 @@ void ast_stmt_list_destroy(AstStmtList *list)
227234
{
228235
ast_expr_destroy(stmt->data.decl.init);
229236
}
237+
if (stmt->data.decl.array_init)
238+
{
239+
ast_expr_destroy(stmt->data.decl.array_init);
240+
}
230241
break;
231242
case STMT_ASSIGN:
232243
free(stmt->data.assign.name);
233244
ast_expr_destroy(stmt->data.assign.value);
234245
break;
246+
case STMT_ARRAY_ASSIGN:
247+
free(stmt->data.array_assign.name);
248+
ast_expr_destroy(stmt->data.array_assign.index);
249+
ast_expr_destroy(stmt->data.array_assign.value);
250+
break;
235251
case STMT_EXPR:
236252
case STMT_RETURN:
237253
if (stmt->data.expr)
@@ -276,6 +292,9 @@ AstStmt *ast_stmt_make_decl(TypeKind type, char *name, AstExpr *init)
276292
stmt->data.decl.type = type;
277293
stmt->data.decl.name = name;
278294
stmt->data.decl.init = init;
295+
stmt->data.decl.is_array = 0;
296+
stmt->data.decl.array_size = 0;
297+
stmt->data.decl.array_init = NULL;
279298
return stmt;
280299
}
281300

@@ -289,6 +308,31 @@ AstStmt *ast_stmt_make_assign(char *name, AstExpr *value)
289308
return stmt;
290309
}
291310

311+
AstStmt *ast_stmt_make_array_decl(TypeKind type, char *name, size_t size, AstExpr *init)
312+
{
313+
AstStmt *stmt = xcalloc(1, sizeof(AstStmt));
314+
stmt->kind = STMT_DECL;
315+
stmt->data.decl.type = type;
316+
stmt->data.decl.name = name;
317+
stmt->data.decl.init = NULL;
318+
stmt->data.decl.is_array = 1;
319+
stmt->data.decl.array_size = size;
320+
stmt->data.decl.array_init = init;
321+
return stmt;
322+
}
323+
324+
AstStmt *ast_stmt_make_array_assign(char *name, AstExpr *index, AstExpr *value)
325+
{
326+
AstStmt *stmt = xcalloc(1, sizeof(AstStmt));
327+
stmt->kind = STMT_ARRAY_ASSIGN;
328+
stmt->data.array_assign.name = name;
329+
stmt->data.array_assign.index = index;
330+
stmt->data.array_assign.value = value;
331+
stmt->data.array_assign.element_type = TYPE_UNKNOWN;
332+
stmt->data.array_assign.array_size = 0;
333+
return stmt;
334+
}
335+
292336
AstStmt *ast_stmt_make_expr(AstExpr *expr)
293337
{
294338
AstStmt *stmt = xcalloc(1, sizeof(AstStmt));
@@ -384,6 +428,28 @@ AstExpr *ast_expr_make_call(char *callee, AstExprList *args)
384428
return expr;
385429
}
386430

431+
AstExpr *ast_expr_make_array_literal(AstExprList *elements)
432+
{
433+
AstExpr *expr = xcalloc(1, sizeof(AstExpr));
434+
expr->kind = EXPR_ARRAY_LITERAL;
435+
expr->type = TYPE_ARRAY;
436+
if (elements)
437+
{
438+
expr->data.array_literal.elements = *elements;
439+
}
440+
return expr;
441+
}
442+
443+
AstExpr *ast_expr_make_subscript(AstExpr *array, AstExpr *index)
444+
{
445+
AstExpr *expr = xcalloc(1, sizeof(AstExpr));
446+
expr->kind = EXPR_SUBSCRIPT;
447+
expr->type = TYPE_UNKNOWN;
448+
expr->data.subscript.array = array;
449+
expr->data.subscript.index = index;
450+
return expr;
451+
}
452+
387453
TypeKind ast_type_from_keyword(const char *kw)
388454
{
389455
if (!kw)
@@ -425,6 +491,8 @@ const char *ast_type_name(TypeKind type)
425491
return "bool";
426492
case TYPE_STRING:
427493
return "string";
494+
case TYPE_ARRAY:
495+
return "array";
428496
case TYPE_VOID:
429497
return "void";
430498
case TYPE_UNKNOWN:

src/ast.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ typedef enum
1010
TYPE_FLOAT,
1111
TYPE_BOOL,
1212
TYPE_STRING,
13+
TYPE_ARRAY,
1314
TYPE_VOID
1415
} TypeKind;
1516

@@ -88,7 +89,9 @@ typedef struct AstExpr
8889
EXPR_IDENTIFIER,
8990
EXPR_BINARY,
9091
EXPR_UNARY,
91-
EXPR_CALL
92+
EXPR_CALL,
93+
EXPR_ARRAY_LITERAL,
94+
EXPR_SUBSCRIPT
9295
} kind;
9396
TypeKind type;
9497
union
@@ -114,6 +117,15 @@ typedef struct AstExpr
114117
char *callee;
115118
AstExprList args;
116119
} call;
120+
struct
121+
{
122+
AstExprList elements;
123+
} array_literal;
124+
struct
125+
{
126+
struct AstExpr *array;
127+
struct AstExpr *index;
128+
} subscript;
117129
} data;
118130
} AstExpr;
119131

@@ -129,6 +141,7 @@ typedef struct AstStmt
129141
STMT_BLOCK,
130142
STMT_DECL,
131143
STMT_ASSIGN,
144+
STMT_ARRAY_ASSIGN,
132145
STMT_EXPR,
133146
STMT_RETURN
134147
} kind;
@@ -140,13 +153,24 @@ typedef struct AstStmt
140153
TypeKind type;
141154
char *name;
142155
AstExpr *init;
156+
int is_array;
157+
size_t array_size;
158+
AstExpr *array_init;
143159
} decl;
144160
struct
145161
{
146162
char *name;
147163
AstExpr *value;
148164
TypeKind type;
149165
} assign;
166+
struct
167+
{
168+
char *name;
169+
AstExpr *index;
170+
AstExpr *value;
171+
TypeKind element_type;
172+
size_t array_size;
173+
} array_assign;
150174
AstExpr *expr;
151175
} data;
152176
} AstStmt;
@@ -188,8 +212,12 @@ AstBlock ast_block_from_list(AstStmtList *list);
188212
AstStmt *ast_stmt_make_block(AstBlock *block);
189213
AstStmt *ast_stmt_make_decl(TypeKind type, char *name, AstExpr *init);
190214
AstStmt *ast_stmt_make_assign(char *name, AstExpr *value);
215+
AstStmt *ast_stmt_make_array_decl(TypeKind type, char *name, size_t size, AstExpr *init);
216+
AstStmt *ast_stmt_make_array_assign(char *name, AstExpr *index, AstExpr *value);
191217
AstStmt *ast_stmt_make_expr(AstExpr *expr);
192218
AstStmt *ast_stmt_make_return(AstExpr *expr);
219+
AstExpr *ast_expr_make_array_literal(AstExprList *elements);
220+
AstExpr *ast_expr_make_subscript(AstExpr *array, AstExpr *index);
193221

194222
AstExpr *ast_expr_make_int(long long value);
195223
AstExpr *ast_expr_make_float(double value);

src/codegen_lua.c

Lines changed: 149 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ static void emit_puts_call(FILE *out, const AstExpr *expr, const FunctionTable *
1717
static void emit_printf_args(FILE *out, const AstExpr *expr, const FunctionTable *functions);
1818
static void emit_string_literal_n(FILE *out, const char *value, size_t length);
1919
static void emit_string_literal(FILE *out, const char *value);
20+
static void emit_array_declaration(FILE *out, const AstStmt *stmt, const FunctionTable *functions, int indent);
21+
static void emit_array_literal_expr(FILE *out, const AstExprList *elements, const FunctionTable *functions);
22+
static void emit_array_index(FILE *out, const AstExpr *expr, const FunctionTable *functions);
23+
static void emit_array_default_value(FILE *out, TypeKind type);
2024
static const FunctionSignature *lookup_signature(const FunctionTable *functions, const char *name);
2125
static const char *binary_op_token(AstBinaryOp op);
2226
static void emit_indent(FILE *out, int indent);
@@ -153,21 +157,36 @@ static void emit_statement(FILE *out, const AstStmt *stmt, const FunctionTable *
153157
emit_block(out, &stmt->data.block, functions, signature, indent, 1);
154158
break;
155159
case STMT_DECL:
156-
emit_indent(out, indent);
157-
fprintf(out, "local %s", stmt->data.decl.name);
158-
if (stmt->data.decl.init)
160+
if (stmt->data.decl.is_array)
159161
{
160-
fputs(" = ", out);
161-
emit_expression_expected(out, stmt->data.decl.init, functions, stmt->data.decl.type);
162+
emit_array_declaration(out, stmt, functions, indent);
163+
}
164+
else
165+
{
166+
emit_indent(out, indent);
167+
fprintf(out, "local %s", stmt->data.decl.name);
168+
if (stmt->data.decl.init)
169+
{
170+
fputs(" = ", out);
171+
emit_expression_expected(out, stmt->data.decl.init, functions, stmt->data.decl.type);
172+
}
173+
fputc('\n', out);
162174
}
163-
fputc('\n', out);
164175
break;
165176
case STMT_ASSIGN:
166177
emit_indent(out, indent);
167178
fprintf(out, "%s = ", stmt->data.assign.name);
168179
emit_expression_expected(out, stmt->data.assign.value, functions, stmt->data.assign.type);
169180
fputc('\n', out);
170181
break;
182+
case STMT_ARRAY_ASSIGN:
183+
emit_indent(out, indent);
184+
fprintf(out, "%s[", stmt->data.array_assign.name);
185+
emit_array_index(out, stmt->data.array_assign.index, functions);
186+
fputs("] = ", out);
187+
emit_expression_expected(out, stmt->data.array_assign.value, functions, stmt->data.array_assign.element_type);
188+
fputc('\n', out);
189+
break;
171190
case STMT_EXPR:
172191
if (stmt->data.expr)
173192
{
@@ -256,6 +275,9 @@ static void emit_expression_raw(FILE *out, const AstExpr *expr, const FunctionTa
256275
case EXPR_STRING_LITERAL:
257276
emit_string_literal(out, expr->data.string_literal);
258277
break;
278+
case EXPR_ARRAY_LITERAL:
279+
emit_array_literal_expr(out, &expr->data.array_literal.elements, functions);
280+
break;
259281
case EXPR_IDENTIFIER:
260282
fputs(expr->data.identifier, out);
261283
break;
@@ -308,6 +330,21 @@ static void emit_expression_raw(FILE *out, const AstExpr *expr, const FunctionTa
308330
case EXPR_CALL:
309331
emit_call(out, expr, functions);
310332
break;
333+
case EXPR_SUBSCRIPT:
334+
if (expr->data.subscript.array && expr->data.subscript.array->kind == EXPR_IDENTIFIER)
335+
{
336+
emit_expression_raw(out, expr->data.subscript.array, functions);
337+
}
338+
else
339+
{
340+
fputc('(', out);
341+
emit_expression_raw(out, expr->data.subscript.array, functions);
342+
fputc(')', out);
343+
}
344+
fputc('[', out);
345+
emit_array_index(out, expr->data.subscript.index, functions);
346+
fputc(']', out);
347+
break;
311348
}
312349
}
313350

@@ -459,6 +496,112 @@ static void emit_string_literal(FILE *out, const char *value)
459496
emit_string_literal_n(out, value, strlen(value));
460497
}
461498

499+
static void emit_array_declaration(FILE *out, const AstStmt *stmt, const FunctionTable *functions, int indent)
500+
{
501+
if (!stmt)
502+
{
503+
return;
504+
}
505+
const AstExpr *init = stmt->data.decl.array_init;
506+
emit_indent(out, indent);
507+
fprintf(out, "local %s = {", stmt->data.decl.name);
508+
size_t emitted = 0;
509+
int first = 1;
510+
if (init && init->kind == EXPR_ARRAY_LITERAL)
511+
{
512+
const AstExprList *elements = &init->data.array_literal.elements;
513+
for (size_t i = 0; i < elements->count; ++i)
514+
{
515+
if (first)
516+
{
517+
fputc(' ', out);
518+
first = 0;
519+
}
520+
else
521+
{
522+
fputs(", ", out);
523+
}
524+
emit_expression_expected(out, elements->items[i], functions, stmt->data.decl.type);
525+
emitted++;
526+
}
527+
}
528+
for (; emitted < stmt->data.decl.array_size; ++emitted)
529+
{
530+
if (first)
531+
{
532+
fputc(' ', out);
533+
first = 0;
534+
}
535+
else
536+
{
537+
fputs(", ", out);
538+
}
539+
emit_array_default_value(out, stmt->data.decl.type);
540+
}
541+
fputs(" }\n", out);
542+
}
543+
544+
static void emit_array_literal_expr(FILE *out, const AstExprList *elements, const FunctionTable *functions)
545+
{
546+
fputc('{', out);
547+
int first = 1;
548+
if (elements)
549+
{
550+
for (size_t i = 0; i < elements->count; ++i)
551+
{
552+
if (first)
553+
{
554+
fputc(' ', out);
555+
first = 0;
556+
}
557+
else
558+
{
559+
fputs(", ", out);
560+
}
561+
emit_expression_raw(out, elements->items[i], functions);
562+
}
563+
}
564+
if (first)
565+
{
566+
fputc(' ', out);
567+
}
568+
fputs(" }", out);
569+
}
570+
571+
static void emit_array_index(FILE *out, const AstExpr *expr, const FunctionTable *functions)
572+
{
573+
if (expr && expr->kind == EXPR_INT_LITERAL)
574+
{
575+
fprintf(out, "%lld", expr->data.int_value + 1);
576+
return;
577+
}
578+
fputc('(', out);
579+
emit_expression_raw(out, expr, functions);
580+
fputs(" + 1)", out);
581+
}
582+
583+
static void emit_array_default_value(FILE *out, TypeKind type)
584+
{
585+
switch (type)
586+
{
587+
case TYPE_INT:
588+
fputs("0", out);
589+
break;
590+
case TYPE_FLOAT:
591+
fputs("0.0", out);
592+
break;
593+
case TYPE_BOOL:
594+
fputs("false", out);
595+
break;
596+
case TYPE_STRING:
597+
emit_string_literal(out, "");
598+
break;
599+
default:
600+
fputs("nil", out);
601+
break;
602+
}
603+
}
604+
462605
static int emit_builtin_expr_statement(FILE *out, const AstExpr *expr, const FunctionTable *functions, int indent)
463606
{
464607
if (!expr || expr->kind != EXPR_CALL)

0 commit comments

Comments
 (0)