Skip to content

Commit f298a80

Browse files
committed
Add strict mode support
- throw error when const/let variable declaration when strict mode is not enabled - add strict mode enable control - store mutable/immutable state into identifier value
1 parent ce9298e commit f298a80

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

mini-javascript.y

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
node *node;
1010
}
1111

12-
%type <val> value_literal object_literal array_literal
12+
%type <val> value_literal object_literal array_literal type_specifier
1313
%type <node> script statements statement scope
1414
if_statement for_statement jump_statement while_statement do_while_statement expression_statement
1515
expression primary_expression assignment_expression conditional_expression postfix_expression
@@ -138,7 +138,7 @@ object_key
138138
;
139139

140140
primary_expression
141-
: IDENTIFIER { $$ = identifier_node($1); }
141+
: IDENTIFIER { $$ = identifier_node($1, 1); }
142142
| value_literal { $$ = literal_node($1); }
143143
| array_literal { $$ = literal_node($1); }
144144
| object_literal { $$ = literal_node($1); }
@@ -239,7 +239,7 @@ statement
239239
| switch_statement
240240
| jump_statement
241241
| declaration
242-
| STRICT_MODE { debug("strict mode enabled", ""); }
242+
| STRICT_MODE { strict_mode = 1; debug("strict mode enabled", ""); }
243243
;
244244

245245
expression_statement
@@ -303,18 +303,18 @@ declaration
303303
;
304304

305305
variable_declaration
306-
: type_specifier IDENTIFIER { $$ = identifier_node($2); debug("variable declaration", $2); }
306+
: type_specifier IDENTIFIER { $$ = identifier_node($2, !strcmp($1, "const")); debug("variable declaration", $2); }
307307
| type_specifier IDENTIFIER ASSIGN expression {
308-
$$ = identifier_node($2);
308+
$$ = identifier_node($2, strcmp($1, "const"));
309309
debug("variable declaration with value", $2);
310310
$$->child = $4;
311311
}
312312
;
313313

314314
type_specifier
315-
: VAR
316-
| LET
317-
| CONST
315+
: VAR { $$ = strdup("var"); }
316+
| LET { $$ = strdup("let"); }
317+
| CONST { $$ = strdup("const"); }
318318
;
319319

320320
assignment_operator
@@ -328,9 +328,9 @@ assignment_operator
328328

329329
parameters
330330
: /* None */ { $$ = NULL; debug("empty function parameter", ""); }
331-
| IDENTIFIER { $$ = identifier_node($1); debug("function parameter", $1); }
331+
| IDENTIFIER { $$ = identifier_node($1, 1); debug("function parameter", $1); }
332332
| parameters IDENTIFIER {
333-
$$ = sibling_node($1, identifier_node($2));
333+
$$ = sibling_node($1, identifier_node($2, 1));
334334
}
335335
;
336336

parser.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,21 @@ void print_node(node *node, int depth) {
3838
}
3939

4040
node *function_node(char *name, int async, node *parameters, node *statements) {
41+
if (strict_mode == 0 && async == 1) {
42+
yyerror("Error: async function requires strict mode.");
43+
}
4144
node *scope = put_node(async ? AsyncScope : Scope, NULL, NULL, NULL, statements);
4245
node *params = put_node(Parameter, NULL, NULL, scope, parameters);
4346
return put_node(Function, name, NULL, NULL, params);
4447
}
4548

46-
node *identifier_node(char *name) {
47-
return put_node(Identifier, name, NULL, NULL, NULL);
49+
/**
50+
* parameter mutable
51+
* 1: mutable
52+
* 0: immutable
53+
*/
54+
node *identifier_node(char *name, int mutable) {
55+
return put_node(Identifier, name, strdup(mutable == 1 ? "mutable" : "immutable"), NULL, NULL);
4856
}
4957

5058
node *literal_node(char *value) {

parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ typedef struct NODE {
1616
} node;
1717

1818
node *sibling_node(node *before, node *next);
19-
node *identifier_node(char *name);
19+
node *identifier_node(char *name, int mutable);
2020
node *literal_node(char *value);
2121
node *operator_node(char *name, node *left, node *right);
2222
node *statement_node(char *name);
@@ -25,4 +25,5 @@ node *put_node(NODEType type, char *name, char *value, node *next_sibling, node
2525
node *create_node();
2626
void delete_node(node *node);
2727

28-
node *root;
28+
node *root;
29+
int strict_mode = 0;

0 commit comments

Comments
 (0)