[Swfdec-commits] 18 commits - configure.ac swfdec/swfdec_text_field_movie.c vivified/code
Pekka Lampila
medar at kemper.freedesktop.org
Thu Apr 3 07:56:10 PDT 2008
configure.ac | 2
swfdec/swfdec_text_field_movie.c | 2
vivified/code/.gitignore | 3
vivified/code/Makefile.am | 13
vivified/code/compiler.c | 11
vivified/code/vivi_code_assignment.c | 2
vivified/code/vivi_code_get.c | 13
vivified/code/vivi_code_get.h | 2
vivified/code/vivi_compiler.c | 1066 +++++++++++++---------
vivified/code/vivi_compiler.h | 5
vivified/code/vivi_compiler_get_temporary.c | 56 +
vivified/code/vivi_compiler_get_temporary.h | 54 +
vivified/code/vivi_compiler_scanner.c | 253 +++++
vivified/code/vivi_compiler_scanner.h | 193 +++
vivified/code/vivi_compiler_scanner_lex.lex | 147 +++
vivified/code/vivi_compiler_scanner_lex_include.h | 8
16 files changed, 1431 insertions(+), 399 deletions(-)
New commits:
commit 5369653d8d00e6c99e910f3d64ff90754cdafd4a
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 17:55:52 2008 +0300
Fix a compiler warning in swfdec_text_field_movie_mouse_press
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 94babd7..e96d39e 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -1521,7 +1521,7 @@ swfdec_text_field_movie_mouse_press (SwfdecActor *actor, guint button)
{
SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (actor);
double x, y;
- gsize index_;
+ guint index_;
gboolean direct, before;
if (button != 0) {
commit e185365241707870d01a1322dc9bf5f4d26456ec
Merge: a8293a9... 1c356c4...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 17:55:13 2008 +0300
Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec
Conflicts:
vivified/code/vivi_compiler.c
commit a8293a963a39d2559afdeb485bbebc6ba2601ce2
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 17:50:16 2008 +0300
Fix handling of assignment and get when compiling
diff --git a/vivified/code/vivi_code_assignment.c b/vivified/code/vivi_code_assignment.c
index 1bc2d29..eee40ee 100644
--- a/vivified/code/vivi_code_assignment.c
+++ b/vivified/code/vivi_code_assignment.c
@@ -49,8 +49,6 @@ vivi_code_assignment_print (ViviCodeToken *token, ViviCodePrinter*printer)
if (VIVI_IS_CODE_CONSTANT (assignment->name)) {
varname = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (assignment->name));
- } else if (VIVI_IS_CODE_GET (assignment->name)) {
- varname = vivi_code_get_get_variable_name (VIVI_CODE_GET (assignment->name));
} else {
varname = NULL;
}
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index b4275fa..54027c9 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -131,6 +131,51 @@ vivi_compiler_combine_statements (guint count, ...)
return VIVI_CODE_STATEMENT (block);
}
+static ViviCodeStatement *
+vivi_compiler_assignment_new (ViviCodeValue *left, ViviCodeValue *right)
+{
+ ViviCodeValue *from;
+
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
+
+ from = NULL;
+
+ if (VIVI_IS_CODE_GET (left)) {
+ ViviCodeGet *get = VIVI_CODE_GET (left);
+
+ if (get->from != NULL) {
+ from = g_object_ref (get->from);
+ left = g_object_ref (get->name);
+ }
+ }
+
+ if (VIVI_IS_CODE_GET (left)) {
+ ViviCodeGet *get = VIVI_CODE_GET (left);
+
+ if (get->from == NULL)
+ left = g_object_ref (get->name);
+ }
+
+ return vivi_code_assignment_new (from, left, right);
+}
+
+static ViviCodeValue *
+vivi_compiler_get_new (ViviCodeValue *from, ViviCodeValue *name)
+{
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (from), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (name), NULL);
+
+ if (VIVI_IS_CODE_GET (name)) {
+ ViviCodeGet *get = VIVI_CODE_GET (name);
+
+ if (get->from == NULL)
+ name = g_object_ref (get->name);
+ }
+
+ return vivi_code_get_new (from, name);
+}
+
// values
static int
@@ -460,7 +505,7 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
}
tmp = *value;
- *value = vivi_code_get_new (tmp, VIVI_CODE_VALUE (member));
+ *value = vivi_compiler_get_new (tmp, member);
g_object_unref (tmp);
g_object_unref (member);
} while (TRUE);
@@ -903,10 +948,10 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
}
if (operator != NULL) {
- assignment = vivi_code_assignment_new (NULL, *value,
+ assignment = vivi_compiler_assignment_new (*value,
vivi_code_binary_new_name (*value, right, operator));
} else {
- assignment = vivi_code_assignment_new (NULL, *value, right);
+ assignment = vivi_compiler_assignment_new (*value, right);
}
g_object_unref (right);
@@ -930,6 +975,7 @@ parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
int expected;
*statement = NULL;
+ statement_one = NULL;
expected = parse_assignment_expression (scanner, value, &statement_one);
if (expected != TOKEN_NONE)
@@ -942,6 +988,7 @@ parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
if (!check_token (scanner, TOKEN_COMMA))
break;
+ statement_one = NULL;
expected = parse_assignment_expression (scanner, value, &statement_one);
if (expected != TOKEN_NONE && expected >= 0) {
g_object_unref (*value);
commit a70ddc6c91d6662a855e8ed32e3030f5586ef5f4
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 16:04:33 2008 +0300
Clean up compiler code with new vivi_compiler_combine_statements function
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 0403a67..b4275fa 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -94,6 +94,43 @@ free_value_list (ViviCodeValue **list)
g_free (list);
}
+static ViviCodeStatement *
+vivi_compiler_combine_statements (guint count, ...)
+{
+ va_list args;
+ ViviCodeBlock *block;
+ guint i;
+
+ if (count == 0)
+ return NULL;
+
+ va_start (args, count);
+ block = NULL;
+ for (i = 0; i < count; i++) {
+ ViviCodeStatement *statement = va_arg (args, ViviCodeStatement *);
+
+ if (statement == NULL)
+ continue;
+
+ g_assert (VIVI_IS_CODE_STATEMENT (statement));
+
+ if (block == NULL) {
+ if (VIVI_IS_CODE_BLOCK (statement)) {
+ block = VIVI_CODE_BLOCK (statement);
+ continue;
+ } else {
+ block = VIVI_CODE_BLOCK (vivi_code_block_new ());
+ }
+ }
+
+ vivi_code_block_add_statement (block, statement);
+ g_object_unref (statement);
+ }
+ va_end (args);
+
+ return VIVI_CODE_STATEMENT (block);
+}
+
// values
static int
@@ -258,13 +295,8 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value,
return FAIL (expected);
}
- if (statement_new != NULL) {
- if (*statement == NULL)
- *statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_new);
- g_object_unref (statement_new);
- }
+ *statement =
+ vivi_compiler_combine_statements (2, *statement, statement_new);
vivi_code_init_object_add_variable (VIVI_CODE_INIT_OBJECT (*value),
property, initializer);
@@ -314,16 +346,8 @@ parse_variable_declaration (ViviCompilerScanner *scanner,
assignment = vivi_code_assignment_new (NULL, identifier, value);
vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assignment), TRUE);
- if (statement_right != NULL) {
- *statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_right);
- g_object_unref (statement_right);
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement), assignment);
- g_object_unref (assignment);
- } else {
- *statement = assignment;
- }
+ *statement =
+ vivi_compiler_combine_statements (2, statement_right, assignment);
return TOKEN_NONE;
}
@@ -403,12 +427,29 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
ViviCodeValue *tmp;
if (check_token (scanner, TOKEN_BRACKET_LEFT)) {
- // TODO: statement
expected = parse_expression (scanner, &member, &statement_member);
- if (expected != TOKEN_NONE)
+ if (expected != TOKEN_NONE) {
+ g_object_unref (*value);
+ *value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return FAIL (expected);
- if (!check_token (scanner, TOKEN_BRACKET_RIGHT))
+ }
+
+ *statement = vivi_compiler_combine_statements (2, *statement,
+ statement_member);
+
+ if (!check_token (scanner, TOKEN_BRACKET_RIGHT)) {
+ g_object_unref (*value);
+ *value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return TOKEN_BRACKET_RIGHT;
+ }
} else if (check_token (scanner, TOKEN_DOT)) {
expected = parse_identifier (scanner, &member);
g_assert (statement_member == NULL);
@@ -502,14 +543,9 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
operation = vivi_code_binary_new_name (*value, one, operator);
g_object_unref (one);
- g_assert (*statement == NULL);
-
- *statement = vivi_code_block_new ();
-
temporary = vivi_compiler_get_temporary_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- vivi_code_assignment_new (NULL, temporary, *value));
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ *statement = vivi_compiler_combine_statements (3, *statement,
+ vivi_code_assignment_new (NULL, temporary, *value),
vivi_code_assignment_new (NULL, *value, operation));
g_object_unref (operation);
@@ -556,9 +592,8 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
tmp = vivi_code_binary_new_name (*value, one, operator);
g_object_unref (one);
- g_assert (*statement == NULL);
-
- *statement = vivi_code_assignment_new (NULL, *value, tmp);
+ *statement = vivi_compiler_combine_statements (2, *statement,
+ vivi_code_assignment_new (NULL, *value, tmp));
g_object_unref (tmp);
return TOKEN_NONE;
@@ -612,7 +647,7 @@ parse_operator_expression (ViviCompilerScanner *scanner,
}
if (statement_right != NULL) {
- ViviCodeStatement *statement_left, *tmp;
+ ViviCodeStatement *tmp;
switch (pass) {
case PASS_LOGICAL_OR:
@@ -634,12 +669,8 @@ parse_operator_expression (ViviCompilerScanner *scanner,
g_assert_not_reached ();
}
- statement_left = *statement;
- *statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_left);
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_right);
+ *statement = vivi_compiler_combine_statements (2, *statement,
+ *statement_right);
}
left = VIVI_CODE_VALUE (*value);
@@ -835,8 +866,6 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
if (!VIVI_IS_CODE_GET (*value))
return TOKEN_NONE;
- g_assert (*statement == NULL);
-
operator = NULL;
vivi_compiler_scanner_peek_next_token (scanner);
@@ -881,17 +910,8 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
}
g_object_unref (right);
- if (statement_right != NULL) {
- *statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_right);
- g_object_unref (statement_right);
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- assignment);
- g_object_unref (assignment);
- } else {
- *statement = assignment;
- }
+ *statement = vivi_compiler_combine_statements (3, *statement,
+ statement_right, assignment);
break;
default:
@@ -915,14 +935,9 @@ parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
if (expected != TOKEN_NONE)
return expected;
- *statement = vivi_code_block_new ();
-
do {
- if (statement_one != NULL) {
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- statement_one);
- g_object_unref (statement_one);
- }
+ *statement =
+ vivi_compiler_combine_statements (2, *statement, statement_one);
if (!check_token (scanner, TOKEN_COMMA))
break;
commit 5035f25268eda1320dfb8b2fdd53e65bb6ba9850
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 16:04:02 2008 +0300
Oops, brackets were reversed in the .lex file
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
index 875bdb3..fdcf654 100644
--- a/vivified/code/vivi_compiler_scanner_lex.lex
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -13,8 +13,8 @@ identifier_part [$_a-zA-Z0-9]
"{" { return TOKEN_BRACE_LEFT; }
"}" { return TOKEN_BRACE_RIGHT; }
-"[" { return TOKEN_BRACKET_RIGHT; }
-"]" { return TOKEN_BRACKET_LEFT; }
+"[" { return TOKEN_BRACKET_LEFT; }
+"]" { return TOKEN_BRACKET_RIGHT; }
"(" { return TOKEN_PARENTHESIS_LEFT; }
")" { return TOKEN_PARENTHESIS_RIGHT; }
commit 4a1a4c10b1904998a5f90dccf9decc8f6ba3c7c6
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 16:03:29 2008 +0300
Fixex to the variable name getting for ViviCodeGet
diff --git a/vivified/code/vivi_code_assignment.c b/vivified/code/vivi_code_assignment.c
index af4c909..1bc2d29 100644
--- a/vivified/code/vivi_code_assignment.c
+++ b/vivified/code/vivi_code_assignment.c
@@ -50,7 +50,7 @@ vivi_code_assignment_print (ViviCodeToken *token, ViviCodePrinter*printer)
if (VIVI_IS_CODE_CONSTANT (assignment->name)) {
varname = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (assignment->name));
} else if (VIVI_IS_CODE_GET (assignment->name)) {
- varname = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (VIVI_CODE_GET (assignment->name)->name));
+ varname = vivi_code_get_get_variable_name (VIVI_CODE_GET (assignment->name));
} else {
varname = NULL;
}
diff --git a/vivified/code/vivi_code_get.c b/vivified/code/vivi_code_get.c
index edac7f9..d90731a 100644
--- a/vivified/code/vivi_code_get.c
+++ b/vivified/code/vivi_code_get.c
@@ -100,6 +100,19 @@ vivi_code_get_init (ViviCodeGet *get)
vivi_code_value_set_precedence (value, VIVI_PRECEDENCE_MEMBER);
}
+char *
+vivi_code_get_get_variable_name (ViviCodeGet *get)
+{
+ if (VIVI_IS_CODE_CONSTANT (get->name)) {
+ return
+ vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (get->name));
+ } else if (VIVI_IS_CODE_GET (get->name)) {
+ return vivi_code_get_get_variable_name (VIVI_CODE_GET (get->name));
+ } else {
+ return NULL;
+ }
+}
+
ViviCodeValue *
vivi_code_get_new (ViviCodeValue *from, ViviCodeValue *name)
{
diff --git a/vivified/code/vivi_code_get.h b/vivified/code/vivi_code_get.h
index fbdf13f..896c600 100644
--- a/vivified/code/vivi_code_get.h
+++ b/vivified/code/vivi_code_get.h
@@ -54,6 +54,8 @@ ViviCodeValue * vivi_code_get_new (ViviCodeValue * from,
ViviCodeValue * name);
ViviCodeValue * vivi_code_get_new_name (const char * name);
+char * vivi_code_get_get_variable_name (ViviCodeGet * get);
+
G_END_DECLS
#endif
commit 8dc7415a19d22ecd56d3c4e498b5c93a26484288
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 15:12:19 2008 +0300
Clean up the compiler code
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 1513e0a..0403a67 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -61,19 +61,20 @@ enum {
#define FAIL(x) ((x) < 0 ? -x : x)
+typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
+typedef int (*ParseValueStatementFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **statement);
typedef int (*ParseStatementFunction) (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
-typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **pre_statement);
-typedef int (*ParseLiteralFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
static int
parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
static int
-parse_literal_list (ViviCompilerScanner *scanner, ParseLiteralFunction function, ViviCodeValue ***list, guint separator);
+parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
+ ViviCodeValue ***list, guint separator);
// helpers
static gboolean
-check_token (ViviCompilerScanner *scanner, guint token)
+check_token (ViviCompilerScanner *scanner, ViviCompilerScannerToken token)
{
vivi_compiler_scanner_peek_next_token (scanner);
if (scanner->next_token != token)
@@ -147,7 +148,7 @@ static int
parse_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
- ParseLiteralFunction functions[] = {
+ ParseValueFunction functions[] = {
parse_null_literal,
parse_boolean_literal,
parse_numeric_literal,
@@ -183,7 +184,7 @@ static int
parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
- ParseLiteralFunction functions[] = {
+ ParseValueFunction functions[] = {
parse_identifier,
parse_string_literal,
parse_numeric_literal,
@@ -202,14 +203,17 @@ parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_logical_or_expression (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **pre_statement);
+parse_assignment_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCodeStatement **statement);
static int
-parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
int expected;
*value = NULL;
+ *statement = NULL;
if (!check_token (scanner, TOKEN_BRACE_LEFT))
return -TOKEN_BRACE_LEFT;
@@ -219,29 +223,49 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
do {
ViviCodeValue *property, *initializer;
- ViviCodeStatement *pre_statement = NULL;
+ ViviCodeStatement *statement_new;
expected = parse_property_name (scanner, &property);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return FAIL (expected);
}
if (!check_token (scanner, TOKEN_COLON)) {
g_object_unref (*value);
*value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return TOKEN_COLON;
}
- // FIXME: assignment expression
- expected = parse_logical_or_expression (scanner, &initializer, &pre_statement);
+ expected = parse_assignment_expression (scanner, &initializer,
+ &statement_new);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return FAIL (expected);
}
+ if (statement_new != NULL) {
+ if (*statement == NULL)
+ *statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ statement_new);
+ g_object_unref (statement_new);
+ }
+
vivi_code_init_object_add_variable (VIVI_CODE_INIT_OBJECT (*value),
property, initializer);
} while (check_token (scanner, TOKEN_COMMA));
@@ -250,6 +274,10 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
g_object_unref (*value);
*value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return TOKEN_BRACE_RIGHT;
}
@@ -259,42 +287,38 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
// misc
static int
-parse_assignment_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement);
-
-static int
parse_variable_declaration (ViviCompilerScanner *scanner,
ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *identifier, *value;
- ViviCodeStatement *pre_statement, *assignment;
+ ViviCodeStatement *assignment, *statement_right;
*statement = NULL;
- pre_statement = NULL;
expected = parse_identifier (scanner, &identifier);
if (expected != TOKEN_NONE)
return expected;
if (check_token (scanner, TOKEN_ASSIGN)) {
- expected = parse_assignment_expression (scanner, &value, &pre_statement);
+ expected = parse_assignment_expression (scanner, &value, &statement_right);
if (expected != TOKEN_NONE) {
g_object_unref (identifier);
return FAIL (expected);
}
} else {
value = vivi_code_constant_new_undefined ();
+ statement_right = NULL;
}
assignment = vivi_code_assignment_new (NULL, identifier, value);
vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assignment), TRUE);
- if (pre_statement != NULL) {
+ if (statement_right != NULL) {
*statement = vivi_code_block_new ();
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- pre_statement);
- g_object_unref (pre_statement);
+ statement_right);
+ g_object_unref (statement_right);
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement), assignment);
g_object_unref (assignment);
} else {
@@ -307,18 +331,22 @@ parse_variable_declaration (ViviCompilerScanner *scanner,
// expression
static int
-parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **statement);
+
+static int
+parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
int i, expected;
- ParseLiteralFunction functions[] = {
+ ParseValueFunction functions[] = {
parse_identifier,
parse_literal,
//parse_array_literal,
- parse_object_literal,
NULL
};
*value = NULL;
+ *statement = NULL;
if (check_token (scanner, TOKEN_THIS)) {
*value = vivi_code_get_new_name ("this");
@@ -326,9 +354,7 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
if (check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
- ViviCodeStatement *pre_statement = NULL;
- // FIXME: assignment expression
- expected = parse_logical_or_expression (scanner, value, &pre_statement);
+ expected = parse_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
@@ -339,6 +365,11 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
return TOKEN_NONE;
}
+
+ expected = parse_object_literal (scanner, value, statement);
+ if (expected == TOKEN_NONE || expected >= 0)
+ return expected;
+
for (i = 0; functions[i] != NULL; i++) {
expected = functions[i] (scanner, value);
if (expected >= 0)
@@ -349,15 +380,19 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *member;
- ViviCodeStatement *pre_statement = NULL;
+ ViviCodeStatement *statement_member;
+
+ *value = NULL;
+ *statement = NULL;
// TODO: new MemberExpression Arguments
- expected = parse_primary_expression (scanner, value);
+ expected = parse_primary_expression (scanner, value, statement);
//if (expected == STATUS_CANCEL)
// expected = parse_function_expression (scanner, value);
@@ -368,14 +403,15 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
ViviCodeValue *tmp;
if (check_token (scanner, TOKEN_BRACKET_LEFT)) {
- // FIXME: expression
- expected = parse_logical_or_expression (scanner, &member, &pre_statement);
+ // TODO: statement
+ expected = parse_expression (scanner, &member, &statement_member);
if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, TOKEN_BRACKET_RIGHT))
return TOKEN_BRACKET_RIGHT;
} else if (check_token (scanner, TOKEN_DOT)) {
expected = parse_identifier (scanner, &member);
+ g_assert (statement_member == NULL);
if (expected != TOKEN_NONE)
return FAIL (expected);
} else {
@@ -392,14 +428,16 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
int expected;
*value = NULL;
+ *statement = NULL;
if (check_token (scanner, TOKEN_NEW)) {
- expected = parse_new_expression (scanner, value);
+ expected = parse_new_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
if (!VIVI_IS_CODE_FUNCTION_CALL (*value)) {
@@ -411,18 +449,19 @@ parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
TRUE);
return TOKEN_NONE;
} else {
- return parse_member_expression (scanner, value);
+ return parse_member_expression (scanner, value, statement);
}
}
static int
-parse_left_hand_side_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_left_hand_side_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
int expected;
*value = NULL;
- expected = parse_new_expression (scanner, value);
+ expected = parse_new_expression (scanner, value, statement);
//if (expected == STATUS_CANCEL)
// expected = parse_call_expression (scanner, value);
@@ -431,15 +470,16 @@ parse_left_hand_side_expression (ViviCompilerScanner *scanner, ViviCodeValue **v
static int
parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
- ViviCodeStatement **pre_statement)
+ ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *operation, *one, *temporary;
const char *operator;
*value = NULL;
+ *statement = NULL;
- expected = parse_left_hand_side_expression (scanner, value);
+ expected = parse_left_hand_side_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return expected;
@@ -462,14 +502,14 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
operation = vivi_code_binary_new_name (*value, one, operator);
g_object_unref (one);
- g_assert (*pre_statement == NULL);
+ g_assert (*statement == NULL);
- *pre_statement = vivi_code_block_new ();
+ *statement = vivi_code_block_new ();
temporary = vivi_compiler_get_temporary_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
vivi_code_assignment_new (NULL, temporary, *value));
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
vivi_code_assignment_new (NULL, *value, operation));
g_object_unref (operation);
@@ -481,7 +521,7 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
static int
parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
- ViviCodeStatement **pre_statement)
+ ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *tmp, *one;
@@ -503,7 +543,7 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
if (!operator) operator = "-";
vivi_compiler_scanner_get_next_token (scanner);
- expected = parse_unary_expression (scanner, value, pre_statement);
+ expected = parse_unary_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
@@ -516,9 +556,9 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
tmp = vivi_code_binary_new_name (*value, one, operator);
g_object_unref (one);
- g_assert (*pre_statement == NULL);
+ g_assert (*statement == NULL);
- *pre_statement = vivi_code_assignment_new (NULL, *value, tmp);
+ *statement = vivi_code_assignment_new (NULL, *value, tmp);
g_object_unref (tmp);
return TOKEN_NONE;
@@ -527,7 +567,7 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
case TOKEN_BITWISE_NOT:*/
case TOKEN_LOGICAL_NOT:
vivi_compiler_scanner_get_next_token (scanner);
- expected = parse_unary_expression (scanner, value, pre_statement);
+ expected = parse_unary_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
tmp = VIVI_CODE_VALUE (*value);
@@ -535,7 +575,7 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
g_object_unref (tmp);
return TOKEN_NONE;
default:
- return parse_postfix_expression (scanner, value, pre_statement);
+ return parse_postfix_expression (scanner, value, statement);
}
}
@@ -547,45 +587,45 @@ typedef enum {
static int
parse_operator_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement,
+ ViviCodeValue **value, ViviCodeStatement **statement,
const ViviCompilerScannerToken *tokens, ParseOperatorPass pass,
- ParseValueFunction next_parse_function)
+ ParseValueStatementFunction next_parse_function)
{
int expected, i;
ViviCodeValue *left, *right;
- ViviCodeStatement *pre_statement_right;
+ ViviCodeStatement *statement_right;
*value = NULL;
- *pre_statement = NULL;
+ *statement = NULL;
- expected = next_parse_function (scanner, value, pre_statement);
+ expected = next_parse_function (scanner, value, statement);
if (expected != TOKEN_NONE)
return expected;
for (i = 0; tokens[i] != TOKEN_NONE; i++) {
if (check_token (scanner, tokens[i])) {
- expected = next_parse_function (scanner, &right, &pre_statement_right);
+ expected = next_parse_function (scanner, &right, &statement_right);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
return FAIL (expected);
}
- if (pre_statement_right != NULL) {
- ViviCodeStatement *pre_statement_left, *tmp;
+ if (statement_right != NULL) {
+ ViviCodeStatement *statement_left, *tmp;
switch (pass) {
case PASS_LOGICAL_OR:
tmp = vivi_code_if_new (vivi_code_unary_new (*value, '!'));
- vivi_code_if_set_if (VIVI_CODE_IF (tmp), pre_statement_right);
- g_object_unref (pre_statement_right);
- pre_statement_right = tmp;
+ vivi_code_if_set_if (VIVI_CODE_IF (tmp), statement_right);
+ g_object_unref (statement_right);
+ statement_right = tmp;
break;
case PASS_LOGICAL_AND:
tmp = vivi_code_if_new (*value);
- vivi_code_if_set_if (VIVI_CODE_IF (tmp), pre_statement_right);
- g_object_unref (pre_statement_right);
- pre_statement_right = tmp;
+ vivi_code_if_set_if (VIVI_CODE_IF (tmp), statement_right);
+ g_object_unref (statement_right);
+ statement_right = tmp;
break;
case PASS_ALWAYS:
// nothing
@@ -594,12 +634,12 @@ parse_operator_expression (ViviCompilerScanner *scanner,
g_assert_not_reached ();
}
- pre_statement_left = *pre_statement;
- *pre_statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
- pre_statement_left);
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
- pre_statement_right);
+ statement_left = *statement;
+ *statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ statement_left);
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ statement_right);
}
left = VIVI_CODE_VALUE (*value);
@@ -615,126 +655,126 @@ parse_operator_expression (ViviCompilerScanner *scanner,
static int
parse_multiplicative_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_MULTIPLY,
TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_unary_expression);
}
static int
parse_additive_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_PLUS, TOKEN_MINUS,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_multiplicative_expression);
}
static int
parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
- ViviCodeStatement **pre_statement)
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_SHIFT_LEFT,
TOKEN_SHIFT_RIGHT, TOKEN_SHIFT_RIGHT_UNSIGNED, TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_additive_expression);
}
static int
parse_relational_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LESS_THAN,
TOKEN_GREATER_THAN, /*TOKEN_LESS_THAN_OR_EQUAL,
TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, TOKEN_IN,*/ TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_shift_expression);
}
static int
parse_equality_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_EQUAL,
/*TOKEN_NOT_EQUAL,*/ TOKEN_STRICT_EQUAL, /*TOKEN_NOT_STRICT_EQUAL,*/
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_relational_expression);
}
static int
parse_bitwise_and_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_equality_expression);
}
static int
parse_bitwise_xor_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_XOR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_bitwise_and_expression);
}
static int
parse_bitwise_or_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_ALWAYS, parse_bitwise_xor_expression);
}
static int
parse_logical_and_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_LOGICAL_AND, parse_bitwise_or_expression);
}
static int
parse_logical_or_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, pre_statement, tokens,
+ return parse_operator_expression (scanner, value, statement, tokens,
PASS_LOGICAL_OR, parse_logical_and_expression);
}
static int
parse_conditional_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
int expected;
//ViviCodeStatement *if_statement, *else_statement;
*value = NULL;
- expected = parse_logical_or_expression (scanner, value, pre_statement);
+ expected = parse_logical_or_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return expected;
@@ -778,24 +818,24 @@ parse_conditional_expression (ViviCompilerScanner *scanner,
static int
parse_assignment_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCodeStatement **pre_statement)
+ ViviCodeValue **value, ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *right;
- ViviCodeStatement *assignment, *pre_statement_right;
+ ViviCodeStatement *assignment, *statement_right;
const char *operator;
*value = NULL;
- *pre_statement = NULL;
+ *statement = NULL;
- expected = parse_conditional_expression (scanner, value, pre_statement);
+ expected = parse_conditional_expression (scanner, value, statement);
if (expected != TOKEN_NONE)
return expected;
if (!VIVI_IS_CODE_GET (*value))
return TOKEN_NONE;
- g_assert (*pre_statement == NULL);
+ g_assert (*statement == NULL);
operator = NULL;
@@ -826,7 +866,7 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
case TOKEN_ASSIGN:
vivi_compiler_scanner_get_next_token (scanner);
expected = parse_assignment_expression (scanner, &right,
- &pre_statement_right);
+ &statement_right);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
@@ -841,16 +881,16 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
}
g_object_unref (right);
- if (pre_statement_right != NULL) {
- *pre_statement = vivi_code_block_new ();
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
- pre_statement_right);
- g_object_unref (pre_statement_right);
- vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ if (statement_right != NULL) {
+ *statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ statement_right);
+ g_object_unref (statement_right);
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
assignment);
g_object_unref (assignment);
} else {
- *pre_statement = assignment;
+ *statement = assignment;
}
break;
@@ -863,32 +903,34 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
}
static int
-parse_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
- ViviCodeValue *value;
- ViviCodeStatement *pre_statement;
+ ViviCodeStatement *statement_one;
int expected;
*statement = NULL;
- expected = parse_assignment_expression (scanner, &value, &pre_statement);
+ expected = parse_assignment_expression (scanner, value, &statement_one);
if (expected != TOKEN_NONE)
return expected;
*statement = vivi_code_block_new ();
do {
- if (pre_statement != NULL) {
+ if (statement_one != NULL) {
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
- pre_statement);
- g_object_unref (pre_statement);
+ statement_one);
+ g_object_unref (statement_one);
}
if (!check_token (scanner, TOKEN_COMMA))
break;
- expected = parse_assignment_expression (scanner, &value, &pre_statement);
+ expected = parse_assignment_expression (scanner, value, &statement_one);
if (expected != TOKEN_NONE && expected >= 0) {
+ g_object_unref (*value);
+ *value = NULL;
g_object_unref (*statement);
*statement = NULL;
return expected;
@@ -905,6 +947,7 @@ parse_expression_statement (ViviCompilerScanner *scanner,
ViviCodeStatement **statement)
{
int expected;
+ ViviCodeValue *value;
*statement = NULL;
@@ -913,11 +956,12 @@ parse_expression_statement (ViviCompilerScanner *scanner,
scanner->next_token == TOKEN_FUNCTION)
return -ERROR_TOKEN_EXPRESSION_STATEMENT;
- expected = parse_expression (scanner, statement);
+ expected = parse_expression (scanner, &value, statement);
if (expected != TOKEN_NONE)
return expected;
if (!check_token (scanner, TOKEN_SEMICOLON)) {
+ g_object_unref (value);
g_object_unref (*statement);
*statement = NULL;
return TOKEN_SEMICOLON;
@@ -1060,7 +1104,8 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
return TOKEN_PARENTHESIS_LEFT;
}
- expected = parse_literal_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
+ expected =
+ parse_value_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
if (expected != TOKEN_NONE && expected >= 0)
return expected;
@@ -1179,8 +1224,8 @@ parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction funct
}
static int
-parse_literal_list (ViviCompilerScanner *scanner,
- ParseLiteralFunction function, ViviCodeValue ***list, guint separator)
+parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
+ ViviCodeValue ***list, guint separator)
{
GPtrArray *array;
ViviCodeValue *value;
@@ -1190,6 +1235,8 @@ parse_literal_list (ViviCompilerScanner *scanner,
g_assert (function != NULL);
g_assert (list != NULL);
+ **list = NULL;
+
expected = function (scanner, &value);
if (expected != TOKEN_NONE)
return expected;
commit a0a050ebcd63967ac65a5ad43224b8c3f74abf83
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 14:23:33 2008 +0300
Implement the parsing of assignment expressions
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 3a1ef0f..1513e0a 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -781,8 +781,12 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
int expected;
+ ViviCodeValue *right;
+ ViviCodeStatement *assignment, *pre_statement_right;
+ const char *operator;
*value = NULL;
+ *pre_statement = NULL;
expected = parse_conditional_expression (scanner, value, pre_statement);
if (expected != TOKEN_NONE)
@@ -791,20 +795,65 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
if (!VIVI_IS_CODE_GET (*value))
return TOKEN_NONE;
+ g_assert (*pre_statement == NULL);
+
+ operator = NULL;
+
vivi_compiler_scanner_peek_next_token (scanner);
switch ((int)scanner->next_token) {
- case TOKEN_ASSIGN:
- /*case TOKEN_ASSIGN_MULTIPLY:
+ case TOKEN_ASSIGN_MULTIPLY:
+ if (operator == NULL) operator = "*";
case TOKEN_ASSIGN_DIVIDE:
+ if (operator == NULL) operator = "/";
case TOKEN_ASSIGN_REMAINDER:
+ if (operator == NULL) operator = "%";
case TOKEN_ASSIGN_ADD:
+ if (operator == NULL) operator = "+";
case TOKEN_ASSIGN_MINUS:
+ if (operator == NULL) operator = "-";
case TOKEN_ASSIGN_SHIFT_LEFT:
+ if (operator == NULL) operator = "<<";
case TOKEN_ASSIGN_SHIFT_RIGHT:
+ if (operator == NULL) operator = ">>";
case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
+ if (operator == NULL) operator = ">>>";
case TOKEN_ASSIGN_BITWISE_AND:
+ if (operator == NULL) operator = "&";
case TOKEN_ASSIGN_BITWISE_OR:
- case TOKEN_ASSIGN_BITWISE_XOR:*/
+ if (operator == NULL) operator = "|";
+ case TOKEN_ASSIGN_BITWISE_XOR:
+ if (operator == NULL) operator = "^";
+ case TOKEN_ASSIGN:
+ vivi_compiler_scanner_get_next_token (scanner);
+ expected = parse_assignment_expression (scanner, &right,
+ &pre_statement_right);
+ if (expected != TOKEN_NONE) {
+ g_object_unref (*value);
+ *value = NULL;
+ return FAIL (expected);
+ }
+
+ if (operator != NULL) {
+ assignment = vivi_code_assignment_new (NULL, *value,
+ vivi_code_binary_new_name (*value, right, operator));
+ } else {
+ assignment = vivi_code_assignment_new (NULL, *value, right);
+ }
+ g_object_unref (right);
+
+ if (pre_statement_right != NULL) {
+ *pre_statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ pre_statement_right);
+ g_object_unref (pre_statement_right);
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ assignment);
+ g_object_unref (assignment);
+ } else {
+ *pre_statement = assignment;
+ }
+
+ break;
default:
return TOKEN_NONE;
}
commit 585e399677054e86b0f7e70e6f1a960db9a11d60
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 14:01:43 2008 +0300
Handle || and && better with side-effects
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 128757b..3a1ef0f 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -539,10 +539,16 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
}
}
+typedef enum {
+ PASS_ALWAYS,
+ PASS_LOGICAL_OR,
+ PASS_LOGICAL_AND
+} ParseOperatorPass;
+
static int
parse_operator_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value, ViviCodeStatement **pre_statement,
- const ViviCompilerScannerToken *tokens,
+ const ViviCompilerScannerToken *tokens, ParseOperatorPass pass,
ParseValueFunction next_parse_function)
{
int expected, i;
@@ -566,7 +572,29 @@ parse_operator_expression (ViviCompilerScanner *scanner,
}
if (pre_statement_right != NULL) {
- ViviCodeStatement *pre_statement_left = *pre_statement;
+ ViviCodeStatement *pre_statement_left, *tmp;
+
+ switch (pass) {
+ case PASS_LOGICAL_OR:
+ tmp = vivi_code_if_new (vivi_code_unary_new (*value, '!'));
+ vivi_code_if_set_if (VIVI_CODE_IF (tmp), pre_statement_right);
+ g_object_unref (pre_statement_right);
+ pre_statement_right = tmp;
+ break;
+ case PASS_LOGICAL_AND:
+ tmp = vivi_code_if_new (*value);
+ vivi_code_if_set_if (VIVI_CODE_IF (tmp), pre_statement_right);
+ g_object_unref (pre_statement_right);
+ pre_statement_right = tmp;
+ break;
+ case PASS_ALWAYS:
+ // nothing
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ pre_statement_left = *pre_statement;
*pre_statement = vivi_code_block_new ();
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
pre_statement_left);
@@ -593,7 +621,7 @@ parse_multiplicative_expression (ViviCompilerScanner *scanner,
TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_unary_expression);
+ PASS_ALWAYS, parse_unary_expression);
}
static int
@@ -604,7 +632,7 @@ parse_additive_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_multiplicative_expression);
+ PASS_ALWAYS, parse_multiplicative_expression);
}
static int
@@ -615,7 +643,7 @@ parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
TOKEN_SHIFT_RIGHT, TOKEN_SHIFT_RIGHT_UNSIGNED, TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_additive_expression);
+ PASS_ALWAYS, parse_additive_expression);
}
static int
@@ -627,7 +655,7 @@ parse_relational_expression (ViviCompilerScanner *scanner,
TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, TOKEN_IN,*/ TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_shift_expression);
+ PASS_ALWAYS, parse_shift_expression);
}
static int
@@ -639,7 +667,7 @@ parse_equality_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_relational_expression);
+ PASS_ALWAYS, parse_relational_expression);
}
static int
@@ -650,7 +678,7 @@ parse_bitwise_and_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_equality_expression);
+ PASS_ALWAYS, parse_equality_expression);
}
static int
@@ -661,7 +689,7 @@ parse_bitwise_xor_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_bitwise_and_expression);
+ PASS_ALWAYS, parse_bitwise_and_expression);
}
static int
@@ -672,7 +700,7 @@ parse_bitwise_or_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_bitwise_xor_expression);
+ PASS_ALWAYS, parse_bitwise_xor_expression);
}
static int
@@ -683,7 +711,7 @@ parse_logical_and_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_bitwise_or_expression);
+ PASS_LOGICAL_AND, parse_bitwise_or_expression);
}
static int
@@ -694,7 +722,7 @@ parse_logical_or_expression (ViviCompilerScanner *scanner,
TOKEN_NONE };
return parse_operator_expression (scanner, value, pre_statement, tokens,
- parse_logical_and_expression);
+ PASS_LOGICAL_OR, parse_logical_and_expression);
}
static int
commit 41cf66655511e0b671098030d812123c474957cd
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 13:45:49 2008 +0300
Make postfix operators (hopefully) work right
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 85d2055..128757b 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -46,6 +46,8 @@
#include "vivi_code_unary.h"
#include "vivi_code_value_statement.h"
#include "vivi_compiler_empty_statement.h"
+#include "vivi_compiler_get_temporary.h"
+
#include "vivi_code_text_printer.h"
@@ -432,7 +434,7 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
ViviCodeStatement **pre_statement)
{
int expected;
- ViviCodeValue *tmp, *one;
+ ViviCodeValue *operation, *one, *temporary;
const char *operator;
*value = NULL;
@@ -457,15 +459,22 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
}
one = vivi_code_constant_new_number (1);
- tmp = vivi_code_binary_new_name (*value, one, operator);
+ operation = vivi_code_binary_new_name (*value, one, operator);
g_object_unref (one);
g_assert (*pre_statement == NULL);
*pre_statement = vivi_code_block_new ();
+
+ temporary = vivi_compiler_get_temporary_new ();
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
- vivi_code_assignment_new (NULL, *value, tmp));
- g_object_unref (tmp);
+ vivi_code_assignment_new (NULL, temporary, *value));
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ vivi_code_assignment_new (NULL, *value, operation));
+ g_object_unref (operation);
+
+ g_object_unref (*value);
+ *value = temporary;
return TOKEN_NONE;
}
@@ -556,6 +565,15 @@ parse_operator_expression (ViviCompilerScanner *scanner,
return FAIL (expected);
}
+ if (pre_statement_right != NULL) {
+ ViviCodeStatement *pre_statement_left = *pre_statement;
+ *pre_statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ pre_statement_left);
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ pre_statement_right);
+ }
+
left = VIVI_CODE_VALUE (*value);
*value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right),
vivi_compiler_scanner_token_name (tokens[i]));
@@ -734,11 +752,37 @@ static int
parse_assignment_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
+ int expected;
+
*value = NULL;
- // TODO
+ expected = parse_conditional_expression (scanner, value, pre_statement);
+ if (expected != TOKEN_NONE)
+ return expected;
- return parse_conditional_expression (scanner, value, pre_statement);
+ if (!VIVI_IS_CODE_GET (*value))
+ return TOKEN_NONE;
+
+ vivi_compiler_scanner_peek_next_token (scanner);
+ switch ((int)scanner->next_token) {
+ case TOKEN_ASSIGN:
+ /*case TOKEN_ASSIGN_MULTIPLY:
+ case TOKEN_ASSIGN_DIVIDE:
+ case TOKEN_ASSIGN_REMAINDER:
+ case TOKEN_ASSIGN_ADD:
+ case TOKEN_ASSIGN_MINUS:
+ case TOKEN_ASSIGN_SHIFT_LEFT:
+ case TOKEN_ASSIGN_SHIFT_RIGHT:
+ case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
+ case TOKEN_ASSIGN_BITWISE_AND:
+ case TOKEN_ASSIGN_BITWISE_OR:
+ case TOKEN_ASSIGN_BITWISE_XOR:*/
+ default:
+ return TOKEN_NONE;
+ }
+
+
+ return TOKEN_NONE;
}
static int
diff --git a/vivified/code/vivi_compiler_get_temporary.c b/vivified/code/vivi_compiler_get_temporary.c
index 8876502..2b5b515 100644
--- a/vivified/code/vivi_compiler_get_temporary.c
+++ b/vivified/code/vivi_compiler_get_temporary.c
@@ -45,7 +45,7 @@ vivi_compiler_get_temporary_new (void)
{
static int counter = 0;
ViviCompilerGetTemporary *get;
- char *name = g_strdup_printf ("_%i", ++counter);
+ char *name = g_strdup_printf ("$%i", ++counter);
get = g_object_new (VIVI_TYPE_COMPILER_GET_TEMPORARY, NULL);
VIVI_CODE_GET (get)->name = vivi_code_constant_new_string (name);
diff --git a/vivified/code/vivi_compiler_get_temporary.h b/vivified/code/vivi_compiler_get_temporary.h
index 5c5bcf8..43b0baf 100644
--- a/vivified/code/vivi_compiler_get_temporary.h
+++ b/vivified/code/vivi_compiler_get_temporary.h
@@ -20,7 +20,7 @@
#ifndef _VIVI_COMPILER_GET_TEMPORARY_H_
#define _VIVI_COMPILER_GET_TEMPORARY_H_
-#include <vivified/code/vivi_code_value.h>
+#include <vivified/code/vivi_code_get.h>
G_BEGIN_DECLS
@@ -37,12 +37,12 @@ typedef struct _ViviCompilerGetTemporaryClass ViviCompilerGetTemporaryClass;
struct _ViviCompilerGetTemporary
{
- ViviCodeValue value;
+ ViviCodeGet value;
};
struct _ViviCompilerGetTemporaryClass
{
- ViviCodeValueClass value_class;
+ ViviCodeGetClass value_class;
};
GType vivi_compiler_get_temporary_get_type (void);
commit a503cf49aaae664f65b9be838fe984e702718524
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 13:04:56 2008 +0300
Checking for a wrong token here
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index dd448f7..85d2055 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -261,7 +261,8 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value, ViviCodeStatement **pre_statement);
static int
-parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_variable_declaration (ViviCompilerScanner *scanner,
+ ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *identifier, *value;
@@ -274,7 +275,7 @@ parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
if (expected != TOKEN_NONE)
return expected;
- if (check_token (scanner, TOKEN_EQUAL)) {
+ if (check_token (scanner, TOKEN_ASSIGN)) {
expected = parse_assignment_expression (scanner, &value, &pre_statement);
if (expected != TOKEN_NONE) {
g_object_unref (identifier);
@@ -284,7 +285,6 @@ parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
value = vivi_code_constant_new_undefined ();
}
-
assignment = vivi_code_assignment_new (NULL, identifier, value);
vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assignment), TRUE);
@@ -860,8 +860,8 @@ parse_variable_statement (ViviCompilerScanner *scanner, ViviCodeStatement **stat
if (!check_token (scanner, TOKEN_VAR))
return -TOKEN_VAR;
- expected =
- parse_statement_list (scanner, parse_variable_declaration, statement, TOKEN_COMMA);
+ expected = parse_statement_list (scanner, parse_variable_declaration,
+ statement, TOKEN_COMMA);
if (expected != TOKEN_NONE)
return FAIL (expected);
commit 758206ecba33302efa867cd1b948612f63eec2cb
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 12:53:11 2008 +0300
Start working on expression side effect support and add simple error messages
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index cd866af..64a6960 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -33,6 +33,7 @@ libvivified_compiler_la_SOURCES = \
vivi_code_value_statement.c \
vivi_compiler.c \
vivi_compiler_empty_statement.c \
+ vivi_compiler_get_temporary.c \
vivi_compiler_scanner.c \
vivi_compiler_scanner_lex.c \
vivi_decompiler_block.c \
@@ -69,6 +70,7 @@ noinst_HEADERS = \
vivi_code_value_statement.h \
vivi_compiler.h \
vivi_compiler_empty_statement.h \
+ vivi_compiler_get_temporary.h \
vivi_compiler_scanner.h \
vivi_compiler_scanner_lex.h \
vivi_compiler_scanner_lex_include.h \
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 70b5832..dd448f7 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -60,12 +60,13 @@ enum {
#define FAIL(x) ((x) < 0 ? -x : x)
typedef int (*ParseStatementFunction) (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
-typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
+typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **pre_statement);
+typedef int (*ParseLiteralFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
static int
parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
static int
-parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function, ViviCodeValue ***list, guint separator);
+parse_literal_list (ViviCompilerScanner *scanner, ParseLiteralFunction function, ViviCodeValue ***list, guint separator);
// helpers
@@ -144,7 +145,7 @@ static int
parse_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
- ParseValueFunction functions[] = {
+ ParseLiteralFunction functions[] = {
parse_null_literal,
parse_boolean_literal,
parse_numeric_literal,
@@ -180,7 +181,7 @@ static int
parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
- ParseValueFunction functions[] = {
+ ParseLiteralFunction functions[] = {
parse_identifier,
parse_string_literal,
parse_numeric_literal,
@@ -199,7 +200,7 @@ parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_logical_or_expression (ViviCompilerScanner *scanner, ViviCodeValue **value);
+parse_logical_or_expression (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **pre_statement);
static int
parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
@@ -216,6 +217,7 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
do {
ViviCodeValue *property, *initializer;
+ ViviCodeStatement *pre_statement = NULL;
expected = parse_property_name (scanner, &property);
if (expected != TOKEN_NONE) {
@@ -231,7 +233,7 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
// FIXME: assignment expression
- expected = parse_logical_or_expression (scanner, &initializer);
+ expected = parse_logical_or_expression (scanner, &initializer, &pre_statement);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
@@ -255,21 +257,25 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
// misc
static int
+parse_assignment_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCodeStatement **pre_statement);
+
+static int
parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
- ViviCodeValue *identifier;
- ViviCodeValue *value;
+ ViviCodeValue *identifier, *value;
+ ViviCodeStatement *pre_statement, *assignment;
*statement = NULL;
+ pre_statement = NULL;
expected = parse_identifier (scanner, &identifier);
if (expected != TOKEN_NONE)
return expected;
if (check_token (scanner, TOKEN_EQUAL)) {
- // FIXME: assignment expression
- expected = parse_logical_or_expression (scanner, &value);
+ expected = parse_assignment_expression (scanner, &value, &pre_statement);
if (expected != TOKEN_NONE) {
g_object_unref (identifier);
return FAIL (expected);
@@ -278,8 +284,20 @@ parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
value = vivi_code_constant_new_undefined ();
}
- *statement = vivi_code_assignment_new (NULL, identifier, value);
- vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (*statement), TRUE);
+
+ assignment = vivi_code_assignment_new (NULL, identifier, value);
+ vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assignment), TRUE);
+
+ if (pre_statement != NULL) {
+ *statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ pre_statement);
+ g_object_unref (pre_statement);
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement), assignment);
+ g_object_unref (assignment);
+ } else {
+ *statement = assignment;
+ }
return TOKEN_NONE;
}
@@ -290,7 +308,7 @@ static int
parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
- ParseValueFunction functions[] = {
+ ParseLiteralFunction functions[] = {
parse_identifier,
parse_literal,
//parse_array_literal,
@@ -306,8 +324,9 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
if (check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
+ ViviCodeStatement *pre_statement = NULL;
// FIXME: assignment expression
- expected = parse_logical_or_expression (scanner, value);
+ expected = parse_logical_or_expression (scanner, value, &pre_statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
@@ -332,6 +351,7 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
ViviCodeValue *member;
+ ViviCodeStatement *pre_statement = NULL;
// TODO: new MemberExpression Arguments
@@ -347,7 +367,7 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
if (check_token (scanner, TOKEN_BRACKET_LEFT)) {
// FIXME: expression
- expected = parse_logical_or_expression (scanner, &member);
+ expected = parse_logical_or_expression (scanner, &member, &pre_statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, TOKEN_BRACKET_RIGHT))
@@ -408,12 +428,15 @@ parse_left_hand_side_expression (ViviCompilerScanner *scanner, ViviCodeValue **v
}
static int
-parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **pre_statement)
{
int expected;
ViviCodeValue *tmp, *one;
const char *operator;
+ *value = NULL;
+
expected = parse_left_hand_side_expression (scanner, value);
if (expected != TOKEN_NONE)
return expected;
@@ -428,39 +451,74 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
return TOKEN_NONE;
}
+ if (!VIVI_IS_CODE_GET (*value)) {
+ g_printerr ("Invalid INCREASE/DECREASE\n");
+ return -scanner->token;
+ }
+
one = vivi_code_constant_new_number (1);
+ tmp = vivi_code_binary_new_name (*value, one, operator);
+ g_object_unref (one);
- // FIXME: Side effect!
- tmp = *value;
- *value = vivi_code_binary_new_name (tmp, one, operator);
- g_object_unref (tmp);
+ g_assert (*pre_statement == NULL);
- g_object_unref (one);
+ *pre_statement = vivi_code_block_new ();
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*pre_statement),
+ vivi_code_assignment_new (NULL, *value, tmp));
+ g_object_unref (tmp);
return TOKEN_NONE;
}
static int
-parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **pre_statement)
{
int expected;
- ViviCodeValue *tmp;
+ ViviCodeValue *tmp, *one;
+ const char *operator;
*value = NULL;
+ operator = NULL;
+
vivi_compiler_scanner_peek_next_token (scanner);
switch ((int)scanner->next_token) {
/*case TOKEN_DELETE:
case TOKEN_VOID:
- case TOKEN_TYPEOF:
+ case TOKEN_TYPEOF:*/
case TOKEN_INCREASE:
+ operator = "+";
+ // fall through
case TOKEN_DESCREASE:
- case TOKEN_PLUS:
+ if (!operator) operator = "-";
+
+ vivi_compiler_scanner_get_next_token (scanner);
+ expected = parse_unary_expression (scanner, value, pre_statement);
+ if (expected != TOKEN_NONE)
+ return FAIL (expected);
+
+ if (!VIVI_IS_CODE_GET (*value)) {
+ g_printerr ("Invalid INCREASE/DECREASE\n");
+ return -scanner->token;
+ }
+
+ one = vivi_code_constant_new_number (1);
+ tmp = vivi_code_binary_new_name (*value, one, operator);
+ g_object_unref (one);
+
+ g_assert (*pre_statement == NULL);
+
+ *pre_statement = vivi_code_assignment_new (NULL, *value, tmp);
+ g_object_unref (tmp);
+
+ return TOKEN_NONE;
+ /*case TOKEN_PLUS:
case TOKEN_MINUS:
case TOKEN_BITWISE_NOT:*/
case TOKEN_LOGICAL_NOT:
vivi_compiler_scanner_get_next_token (scanner);
- expected = parse_unary_expression (scanner, value);
+ expected = parse_unary_expression (scanner, value, pre_statement);
if (expected != TOKEN_NONE)
return FAIL (expected);
tmp = VIVI_CODE_VALUE (*value);
@@ -468,28 +526,30 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
g_object_unref (tmp);
return TOKEN_NONE;
default:
- return parse_postfix_expression (scanner, value);
+ return parse_postfix_expression (scanner, value, pre_statement);
}
}
static int
parse_operator_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, const ViviCompilerScannerToken *tokens,
+ ViviCodeValue **value, ViviCodeStatement **pre_statement,
+ const ViviCompilerScannerToken *tokens,
ParseValueFunction next_parse_function)
{
int expected, i;
- ViviCodeValue *left;
- ViviCodeValue *right;
+ ViviCodeValue *left, *right;
+ ViviCodeStatement *pre_statement_right;
*value = NULL;
+ *pre_statement = NULL;
- expected = next_parse_function (scanner, value);
+ expected = next_parse_function (scanner, value, pre_statement);
if (expected != TOKEN_NONE)
return expected;
for (i = 0; tokens[i] != TOKEN_NONE; i++) {
if (check_token (scanner, tokens[i])) {
- expected = next_parse_function (scanner, &right);
+ expected = next_parse_function (scanner, &right, &pre_statement_right);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
@@ -509,131 +569,130 @@ parse_operator_expression (ViviCompilerScanner *scanner,
static int
parse_multiplicative_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_MULTIPLY,
TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_unary_expression);
}
static int
parse_additive_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_PLUS, TOKEN_MINUS,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_multiplicative_expression);
}
static int
-parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+ ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_SHIFT_LEFT,
TOKEN_SHIFT_RIGHT, TOKEN_SHIFT_RIGHT_UNSIGNED, TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_additive_expression);
}
static int
parse_relational_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LESS_THAN,
TOKEN_GREATER_THAN, /*TOKEN_LESS_THAN_OR_EQUAL,
TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, TOKEN_IN,*/ TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_shift_expression);
}
static int
parse_equality_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_EQUAL,
/*TOKEN_NOT_EQUAL,*/ TOKEN_STRICT_EQUAL, /*TOKEN_NOT_STRICT_EQUAL,*/
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_relational_expression);
}
static int
parse_bitwise_and_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_equality_expression);
}
static int
parse_bitwise_xor_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_XOR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_bitwise_and_expression);
}
static int
parse_bitwise_or_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_bitwise_xor_expression);
}
static int
parse_logical_and_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_bitwise_or_expression);
}
static int
parse_logical_or_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value)
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, tokens,
+ return parse_operator_expression (scanner, value, pre_statement, tokens,
parse_logical_and_expression);
}
static int
-parse_assignment_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
-
-static int
-parse_conditional_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_conditional_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
int expected;
- ViviCodeValue *value;
- ViviCodeStatement *if_statement, *else_statement;
+ //ViviCodeStatement *if_statement, *else_statement;
- *statement = NULL;
+ *value = NULL;
- expected = parse_logical_or_expression (scanner, &value);
+ expected = parse_logical_or_expression (scanner, value, pre_statement);
if (expected != TOKEN_NONE)
return expected;
+#if 0
if (!check_token (scanner, TOKEN_QUESTION_MARK)) {
*statement = vivi_code_value_statement_new (VIVI_CODE_VALUE (value));
g_object_unref (value);
@@ -666,40 +725,71 @@ parse_conditional_expression (ViviCompilerScanner *scanner, ViviCodeStatement **
g_object_unref (value);
g_object_unref (if_statement);
g_object_unref (else_statement);
+#endif
return TOKEN_NONE;
}
static int
-parse_assignment_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_assignment_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCodeStatement **pre_statement)
{
- *statement = NULL;
+ *value = NULL;
// TODO
- return parse_conditional_expression (scanner, statement);
+ return parse_conditional_expression (scanner, value, pre_statement);
}
static int
parse_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
+ ViviCodeValue *value;
+ ViviCodeStatement *pre_statement;
+ int expected;
+
*statement = NULL;
- return parse_statement_list (scanner, parse_assignment_expression, statement,
- TOKEN_COMMA);
+ expected = parse_assignment_expression (scanner, &value, &pre_statement);
+ if (expected != TOKEN_NONE)
+ return expected;
+
+ *statement = vivi_code_block_new ();
+
+ do {
+ if (pre_statement != NULL) {
+ vivi_code_block_add_statement (VIVI_CODE_BLOCK (*statement),
+ pre_statement);
+ g_object_unref (pre_statement);
+ }
+
+ if (!check_token (scanner, TOKEN_COMMA))
+ break;
+
+ expected = parse_assignment_expression (scanner, &value, &pre_statement);
+ if (expected != TOKEN_NONE && expected >= 0) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ return expected;
+ }
+ } while (expected == TOKEN_NONE);
+
+ return TOKEN_NONE;
}
// statement
static int
-parse_expression_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_expression_statement (ViviCompilerScanner *scanner,
+ ViviCodeStatement **statement)
{
int expected;
*statement = NULL;
vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token == TOKEN_BRACE_LEFT || scanner->next_token == TOKEN_FUNCTION)
+ if (scanner->next_token == TOKEN_BRACE_LEFT ||
+ scanner->next_token == TOKEN_FUNCTION)
return -ERROR_TOKEN_EXPRESSION_STATEMENT;
expected = parse_expression (scanner, statement);
@@ -849,7 +939,7 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
return TOKEN_PARENTHESIS_LEFT;
}
- expected = parse_value_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
+ expected = parse_literal_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
if (expected != TOKEN_NONE && expected >= 0)
return expected;
@@ -968,8 +1058,8 @@ parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction funct
}
static int
-parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
- ViviCodeValue ***list, guint separator)
+parse_literal_list (ViviCompilerScanner *scanner,
+ ParseLiteralFunction function, ViviCodeValue ***list, guint separator)
{
GPtrArray *array;
ViviCodeValue *value;
@@ -1019,6 +1109,11 @@ vivi_compile_file (FILE *file, const char *input_name)
g_assert ((expected == TOKEN_NONE && VIVI_IS_CODE_STATEMENT (statement)) ||
(expected != TOKEN_NONE && statement == NULL));
+ if (expected != TOKEN_NONE) {
+ vivi_compiler_scanner_get_next_token (scanner);
+ vivi_compiler_scanner_unexp_token (scanner, expected);
+ }
+
g_object_unref (scanner);
return statement;
diff --git a/vivified/code/vivi_compiler_get_temporary.c b/vivified/code/vivi_compiler_get_temporary.c
new file mode 100644
index 0000000..8876502
--- /dev/null
+++ b/vivified/code/vivi_compiler_get_temporary.c
@@ -0,0 +1,56 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ * 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_compiler_get_temporary.h"
+
+#include "vivi_code_get.h"
+#include "vivi_code_constant.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCompilerGetTemporary, vivi_compiler_get_temporary, VIVI_TYPE_CODE_GET)
+
+static void
+vivi_compiler_get_temporary_class_init (ViviCompilerGetTemporaryClass *klass)
+{
+}
+
+static void
+vivi_compiler_get_temporary_init (ViviCompilerGetTemporary *get)
+{
+}
+
+ViviCodeValue *
+vivi_compiler_get_temporary_new (void)
+{
+ static int counter = 0;
+ ViviCompilerGetTemporary *get;
+ char *name = g_strdup_printf ("_%i", ++counter);
+
+ get = g_object_new (VIVI_TYPE_COMPILER_GET_TEMPORARY, NULL);
+ VIVI_CODE_GET (get)->name = vivi_code_constant_new_string (name);
+
+ g_free (name);
+
+ return VIVI_CODE_VALUE (get);
+}
diff --git a/vivified/code/vivi_compiler_get_temporary.h b/vivified/code/vivi_compiler_get_temporary.h
new file mode 100644
index 0000000..5c5bcf8
--- /dev/null
+++ b/vivified/code/vivi_compiler_get_temporary.h
@@ -0,0 +1,54 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VIVI_COMPILER_GET_TEMPORARY_H_
+#define _VIVI_COMPILER_GET_TEMPORARY_H_
+
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCompilerGetTemporary ViviCompilerGetTemporary;
+typedef struct _ViviCompilerGetTemporaryClass ViviCompilerGetTemporaryClass;
+
+#define VIVI_TYPE_COMPILER_GET_TEMPORARY (vivi_compiler_get_temporary_get_type())
+#define VIVI_IS_COMPILER_GET_TEMPORARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_COMPILER_GET_TEMPORARY))
+#define VIVI_IS_COMPILER_GET_TEMPORARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_COMPILER_GET_TEMPORARY))
+#define VIVI_COMPILER_GET_TEMPORARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_COMPILER_GET_TEMPORARY, ViviCompilerGetTemporary))
+#define VIVI_COMPILER_GET_TEMPORARY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_COMPILER_GET_TEMPORARY, ViviCompilerGetTemporaryClass))
+#define VIVI_COMPILER_GET_TEMPORARY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_COMPILER_GET_TEMPORARY, ViviCompilerGetTemporaryClass))
+
+struct _ViviCompilerGetTemporary
+{
+ ViviCodeValue value;
+};
+
+struct _ViviCompilerGetTemporaryClass
+{
+ ViviCodeValueClass value_class;
+};
+
+GType vivi_compiler_get_temporary_get_type (void);
+
+ViviCodeValue * vivi_compiler_get_temporary_new (void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index b931818..a350529 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -233,3 +233,21 @@ vivi_compiler_scanner_peek_next_token (ViviCompilerScanner *scanner)
return scanner->next_token;
}
+
+guint
+vivi_compiler_scanner_cur_line (ViviCompilerScanner *scanner)
+{
+ g_return_val_if_fail (VIVI_IS_COMPILER_SCANNER (scanner), 0);
+
+ return yylineno;
+}
+
+void
+vivi_compiler_scanner_unexp_token (ViviCompilerScanner *scanner,
+ ViviCompilerScannerToken expected)
+{
+ g_printerr ("%i: Unexpected token %s, expected %s\n",
+ vivi_compiler_scanner_cur_line (scanner),
+ vivi_compiler_scanner_token_name (scanner->token),
+ vivi_compiler_scanner_token_name (expected));
+}
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 26b8d1d..f782a3a 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -183,6 +183,11 @@ ViviCompilerScannerToken vivi_compiler_scanner_peek_next_token (ViviCompilerScan
const char * vivi_compiler_scanner_token_name (ViviCompilerScannerToken token);
+guint vivi_compiler_scanner_cur_line (ViviCompilerScanner *scanner);
+
+void vivi_compiler_scanner_unexp_token (ViviCompilerScanner * scanner,
+ ViviCompilerScannerToken expected);
+
G_END_DECLS
#endif
commit d74042af00286a50c162fabb6af56f380d5843ad
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 01:20:06 2008 +0300
Define missing tokens
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 2f54365..70b5832 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -49,65 +49,6 @@
#include "vivi_code_text_printer.h"
-#if 0
- { TOKEN_BREAK, "break" },
- { TOKEN_CASE, "case" },
- { TOKEN_CATCH, "catch" },
- { TOKEN_CONTINUE, "continue" },
- { TOKEN_DEFAULT, "default" },
- { TOKEN_DELETE, "delete" },
- { TOKEN_DO, "do" },
- { TOKEN_ELSE, "else" },
- { TOKEN_FINALLY, "finally" },
- { TOKEN_FOR, "for" },
- { TOKEN_FUNCTION, "function" },
- { TOKEN_IF, "if" },
- { TOKEN_IN, "in" },
- { TOKEN_INSTANCEOF, "instanceof" },
- { TOKEN_NEW, "new" },
- { TOKEN_RETURN, "return" },
- { TOKEN_SWITCH, "switch" },
- { TOKEN_THIS, "this" },
- { TOKEN_THROW, "throw" },
- { TOKEN_TRY, "try" },
- { TOKEN_TYPEOF, "typeof" },
- { TOKEN_VAR, "var" },
- { TOKEN_VOID, "while" },
- { TOKEN_WITH, "with" },
- // reserved keywords
- { TOKEN_FUTURE, "abstract" },
- { TOKEN_FUTURE, "boolean" },
- { TOKEN_FUTURE, "byte" },
- { TOKEN_FUTURE, "char" },
- { TOKEN_FUTURE, "class" },
- { TOKEN_FUTURE, "const" },
- { TOKEN_FUTURE, "debugger" },
- { TOKEN_FUTURE, "double" },
- { TOKEN_FUTURE, "enum" },
- { TOKEN_FUTURE, "export" },
- { TOKEN_FUTURE, "extends" },
- { TOKEN_FUTURE, "final" },
- { TOKEN_FUTURE, "float" },
- { TOKEN_FUTURE, "goto" },
- { TOKEN_FUTURE, "implements" },
- { TOKEN_FUTURE, "import" },
- { TOKEN_FUTURE, "int" },
- { TOKEN_FUTURE, "interface" },
- { TOKEN_FUTURE, "long" },
- { TOKEN_FUTURE, "native" },
- { TOKEN_FUTURE, "package" },
- { TOKEN_FUTURE, "private" },
- { TOKEN_FUTURE, "protected" },
- { TOKEN_FUTURE, "public" },
- { TOKEN_FUTURE, "short" },
- { TOKEN_FUTURE, "static" },
- { TOKEN_FUTURE, "super" },
- { TOKEN_FUTURE, "synchronized" },
- { TOKEN_FUTURE, "throws" },
- { TOKEN_FUTURE, "transient" },
- { TOKEN_FUTURE, "volatile" },
-#endif
-
enum {
ERROR_TOKEN_LITERAL = TOKEN_LAST + 1,
ERROR_TOKEN_PROPERTY_NAME,
@@ -479,9 +420,9 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
// FIXME: Don't allow new line here
- if (check_token (scanner, TOKEN_PLUSPLUS)) {
+ if (check_token (scanner, TOKEN_INCREASE)) {
operator = "+";
- } else if (check_token (scanner, TOKEN_MINUSMINUS)) {
+ } else if (check_token (scanner, TOKEN_DESCREASE)) {
operator = "-";
} else {
return TOKEN_NONE;
@@ -512,8 +453,8 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
/*case TOKEN_DELETE:
case TOKEN_VOID:
case TOKEN_TYPEOF:
- case TOKEN_PLUSPLUS:
- case TOKEN_MINUSMINUS:
+ case TOKEN_INCREASE:
+ case TOKEN_DESCREASE:
case TOKEN_PLUS:
case TOKEN_MINUS:
case TOKEN_BITWISE_NOT:*/
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index bcef86f..b931818 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -103,8 +103,8 @@ static const struct {
// unary/postfix
{ TOKEN_LOGICAL_NOT, "!" },
{ TOKEN_BITWISE_NOT, "~" },
- { TOKEN_PLUSPLUS, "++" },
- { TOKEN_MINUSMINUS, "--" },
+ { TOKEN_INCREASE, "++" },
+ { TOKEN_DESCREASE, "--" },
// conditional
{ TOKEN_QUESTION_MARK, "?" },
@@ -129,7 +129,7 @@ static const struct {
{ TOKEN_ASSIGN_BITWISE_OR, "|=" },
// values
- { TOKEN_NULL, "null" },
+ { TOKEN_NULL, "NULL" },
{ TOKEN_BOOLEAN, "BOOLEAN" },
{ TOKEN_NUMBER, "NUMBER" },
{ TOKEN_STRING, "STRING" },
@@ -138,28 +138,28 @@ static const struct {
// keywords
{ TOKEN_BREAK, "break" },
{ TOKEN_CASE, "case" },
- { TOKEN_CATCH, "" },
- { TOKEN_CONTINUE, "" },
- { TOKEN_DEFAULT, "" },
- { TOKEN_DELETE, "" },
- { TOKEN_DO, "" },
- { TOKEN_ELSE, "" },
- { TOKEN_FINALLY, "" },
- { TOKEN_FOR, "" },
- { TOKEN_FUNCTION, "" },
- { TOKEN_IF, "" },
- { TOKEN_IN, "" },
- { TOKEN_INSTANCEOF, "" },
- { TOKEN_NEW, "" },
- { TOKEN_RETURN, "" },
- { TOKEN_SWITCH, "" },
- { TOKEN_THIS, "" },
- { TOKEN_THROW, "" },
- { TOKEN_TRY, "" },
- { TOKEN_TYPEOF, "" },
- { TOKEN_VAR, "" },
- { TOKEN_VOID, "" },
- { TOKEN_WITH, "" },
+ { TOKEN_CATCH, "catch" },
+ { TOKEN_CONTINUE, "continue" },
+ { TOKEN_DEFAULT, "default" },
+ { TOKEN_DELETE, "delete" },
+ { TOKEN_DO, "do" },
+ { TOKEN_ELSE, "else" },
+ { TOKEN_FINALLY, "finally" },
+ { TOKEN_FOR, "for" },
+ { TOKEN_FUNCTION, "function" },
+ { TOKEN_IF, "if" },
+ { TOKEN_IN, "in" },
+ { TOKEN_INSTANCEOF, "instanceof" },
+ { TOKEN_NEW, "new" },
+ { TOKEN_RETURN, "return" },
+ { TOKEN_SWITCH, "switch" },
+ { TOKEN_THIS, "this" },
+ { TOKEN_THROW, "throw" },
+ { TOKEN_TRY, "try" },
+ { TOKEN_TYPEOF, "typeof" },
+ { TOKEN_VAR, "var" },
+ { TOKEN_VOID, "void" },
+ { TOKEN_WITH, "with" },
// reserved keywords
{ TOKEN_FUTURE, "RESERVED KEYWORD" },
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 37207fd..26b8d1d 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -77,8 +77,8 @@ typedef enum {
// unary/postfix
TOKEN_LOGICAL_NOT,
TOKEN_BITWISE_NOT,
- TOKEN_PLUSPLUS,
- TOKEN_MINUSMINUS,
+ TOKEN_INCREASE,
+ TOKEN_DESCREASE,
// conditional
TOKEN_QUESTION_MARK,
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
index 9cbfa1e..875bdb3 100644
--- a/vivified/code/vivi_compiler_scanner_lex.lex
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -48,8 +48,8 @@ identifier_part [$_a-zA-Z0-9]
"!" { return TOKEN_LOGICAL_NOT; }
"~" { return TOKEN_BITWISE_NOT; }
-"++" { return TOKEN_PLUSPLUS; }
-"--" { return TOKEN_MINUSMINUS; }
+"++" { return TOKEN_INCREASE; }
+"--" { return TOKEN_DESCREASE; }
"?" { return TOKEN_QUESTION_MARK; }
":" { return TOKEN_COLON; }
@@ -75,11 +75,63 @@ identifier_part [$_a-zA-Z0-9]
return TOKEN_BOOLEAN; }
"false" { yylval.v_boolean = 0;
return TOKEN_BOOLEAN; }
-"this" { return TOKEN_THIS; }
"break" { return TOKEN_BREAK; }
+"case" { return TOKEN_CASE; }
+"catch" { return TOKEN_CATCH; }
+"continue" { return TOKEN_CONTINUE; }
+"default" { return TOKEN_DEFAULT; }
+"delete" { return TOKEN_DELETE; }
+"do" { return TOKEN_DO; }
+"else" { return TOKEN_ELSE; }
+"finally" { return TOKEN_FINALLY; }
+"for" { return TOKEN_FOR; }
+"function" { return TOKEN_FUNCTION; }
+"if" { return TOKEN_IF; }
+"in" { return TOKEN_IN; }
+"instanceof" { return TOKEN_INSTANCEOF; }
+"new" { return TOKEN_NEW; }
+"return" { return TOKEN_RETURN; }
+"switch" { return TOKEN_SWITCH; }
+"this" { return TOKEN_THIS; }
+"throw" { return TOKEN_THROW; }
+"try" { return TOKEN_TRY; }
+"typeof" { return TOKEN_TYPEOF; }
+"var" { return TOKEN_VAR; }
+"void" { return TOKEN_VOID; }
+"with" { return TOKEN_WITH; }
"abstract" { return TOKEN_FUTURE; }
+"boolean" { return TOKEN_FUTURE; }
+"byte" { return TOKEN_FUTURE; }
+"char" { return TOKEN_FUTURE; }
+"class" { return TOKEN_FUTURE; }
+"const" { return TOKEN_FUTURE; }
+"debugger" { return TOKEN_FUTURE; }
+"double" { return TOKEN_FUTURE; }
+"enum" { return TOKEN_FUTURE; }
+"export" { return TOKEN_FUTURE; }
+"extends" { return TOKEN_FUTURE; }
+"final" { return TOKEN_FUTURE; }
+"float" { return TOKEN_FUTURE; }
+"goto" { return TOKEN_FUTURE; }
+"implements" { return TOKEN_FUTURE; }
+"import" { return TOKEN_FUTURE; }
+"int" { return TOKEN_FUTURE; }
+"interface" { return TOKEN_FUTURE; }
+"long" { return TOKEN_FUTURE; }
+"native" { return TOKEN_FUTURE; }
+"package" { return TOKEN_FUTURE; }
+"private" { return TOKEN_FUTURE; }
+"protected" { return TOKEN_FUTURE; }
+"public" { return TOKEN_FUTURE; }
+"short" { return TOKEN_FUTURE; }
+"static" { return TOKEN_FUTURE; }
+"super" { return TOKEN_FUTURE; }
+"synchronized" { return TOKEN_FUTURE; }
+"throws" { return TOKEN_FUTURE; }
+"transient" { return TOKEN_FUTURE; }
+"volatile" { return TOKEN_FUTURE; }
{digit}+ { yylval.v_number = atoi(yytext);
return TOKEN_NUMBER; }
commit c1bc85ce6f7b9f529ef748d538992e562603e944
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 01:10:02 2008 +0300
More improvements to the operator parsing
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 562e5fb..2f54365 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -502,20 +502,32 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
static int
parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
+ int expected;
ViviCodeValue *tmp;
*value = NULL;
- if (check_token (scanner, TOKEN_LOGICAL_NOT)) {
- int expected = parse_unary_expression (scanner, value);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
- tmp = VIVI_CODE_VALUE (*value);
- *value = vivi_code_unary_new (tmp, '!');
- g_object_unref (tmp);
- return TOKEN_NONE;
- } else {
- return parse_postfix_expression (scanner, value);
+ vivi_compiler_scanner_peek_next_token (scanner);
+ switch ((int)scanner->next_token) {
+ /*case TOKEN_DELETE:
+ case TOKEN_VOID:
+ case TOKEN_TYPEOF:
+ case TOKEN_PLUSPLUS:
+ case TOKEN_MINUSMINUS:
+ case TOKEN_PLUS:
+ case TOKEN_MINUS:
+ case TOKEN_BITWISE_NOT:*/
+ case TOKEN_LOGICAL_NOT:
+ vivi_compiler_scanner_get_next_token (scanner);
+ expected = parse_unary_expression (scanner, value);
+ if (expected != TOKEN_NONE)
+ return FAIL (expected);
+ tmp = VIVI_CODE_VALUE (*value);
+ *value = vivi_code_unary_new (tmp, '!');
+ g_object_unref (tmp);
+ return TOKEN_NONE;
+ default:
+ return parse_postfix_expression (scanner, value);
}
}
@@ -555,14 +567,59 @@ parse_operator_expression (ViviCompilerScanner *scanner,
}
static int
+parse_multiplicative_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_MULTIPLY,
+ TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_unary_expression);
+}
+
+static int
+parse_additive_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_PLUS, TOKEN_MINUS,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_multiplicative_expression);
+}
+
+static int
+parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_SHIFT_LEFT,
+ TOKEN_SHIFT_RIGHT, TOKEN_SHIFT_RIGHT_UNSIGNED, TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_additive_expression);
+}
+
+static int
+parse_relational_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_LESS_THAN,
+ TOKEN_GREATER_THAN, /*TOKEN_LESS_THAN_OR_EQUAL,
+ TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, TOKEN_IN,*/ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_shift_expression);
+}
+
+static int
parse_equality_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_EQUAL,
- TOKEN_NOT_EQUAL, TOKEN_STRICT_EQUAL, TOKEN_NOT_STRICT_EQUAL, TOKEN_NONE };
+ /*TOKEN_NOT_EQUAL,*/ TOKEN_STRICT_EQUAL, /*TOKEN_NOT_STRICT_EQUAL,*/
+ TOKEN_NONE };
return parse_operator_expression (scanner, value, tokens,
- parse_unary_expression);
+ parse_relational_expression);
}
static int
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 18a7772..bcef86f 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -75,7 +75,7 @@ static const struct {
{ TOKEN_LESS_THAN, "<" },
{ TOKEN_GREATER_THAN, ">" },
{ TOKEN_LESS_THAN_OR_EQUAL, "<=" },
- { TOKEN_EQUAL_OR_MORE_THAN, "=>" },
+ { TOKEN_EQUAL_OR_GREATER_THAN, "=>" },
// equality
{ TOKEN_EQUAL, "=" },
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 9a1dc03..37207fd 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -49,7 +49,7 @@ typedef enum {
TOKEN_LESS_THAN,
TOKEN_GREATER_THAN,
TOKEN_LESS_THAN_OR_EQUAL,
- TOKEN_EQUAL_OR_MORE_THAN,
+ TOKEN_EQUAL_OR_GREATER_THAN,
// equality
TOKEN_EQUAL,
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
index 8429618..9cbfa1e 100644
--- a/vivified/code/vivi_compiler_scanner_lex.lex
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -25,7 +25,7 @@ identifier_part [$_a-zA-Z0-9]
"<" { return TOKEN_LESS_THAN; }
">" { return TOKEN_GREATER_THAN; }
"<=" { return TOKEN_LESS_THAN_OR_EQUAL; }
-"=>" { return TOKEN_EQUAL_OR_MORE_THAN; }
+"=>" { return TOKEN_EQUAL_OR_GREATER_THAN; }
"==", { return TOKEN_EQUAL; }
"!=", { return TOKEN_NOT_EQUAL; }
commit 1ee9194bada58237a2f5b9cab8b8266858fdb8ec
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 00:56:32 2008 +0300
Improvements to operator parsing
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 2b2d03f..562e5fb 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -521,10 +521,10 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
static int
parse_operator_expression (ViviCompilerScanner *scanner,
- ViviCodeValue **value, ViviCompilerScannerToken token, const char *name,
+ ViviCodeValue **value, const ViviCompilerScannerToken *tokens,
ParseValueFunction next_parse_function)
{
- int expected;
+ int expected, i;
ViviCodeValue *left;
ViviCodeValue *right;
@@ -534,44 +534,78 @@ parse_operator_expression (ViviCompilerScanner *scanner,
if (expected != TOKEN_NONE)
return expected;
- while (check_token (scanner, token)) {
- expected = next_parse_function (scanner, &right);
- if (expected != TOKEN_NONE) {
- g_object_unref (*value);
- *value = NULL;
- return FAIL (expected);
- }
+ for (i = 0; tokens[i] != TOKEN_NONE; i++) {
+ if (check_token (scanner, tokens[i])) {
+ expected = next_parse_function (scanner, &right);
+ if (expected != TOKEN_NONE) {
+ g_object_unref (*value);
+ *value = NULL;
+ return FAIL (expected);
+ }
- left = VIVI_CODE_VALUE (*value);
- *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right), name);
- g_object_unref (left);
- g_object_unref (right);
- };
+ left = VIVI_CODE_VALUE (*value);
+ *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right),
+ vivi_compiler_scanner_token_name (tokens[i]));
+ g_object_unref (left);
+ g_object_unref (right);
+ };
+ }
return TOKEN_NONE;
}
static int
-parse_bitwise_and_expression (ViviCompilerScanner *scanner,
+parse_equality_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value)
{
- return parse_operator_expression (scanner, value, TOKEN_BITWISE_AND, "&",
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_EQUAL,
+ TOKEN_NOT_EQUAL, TOKEN_STRICT_EQUAL, TOKEN_NOT_STRICT_EQUAL, TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
parse_unary_expression);
}
static int
-parse_bitwise_or_expression (ViviCompilerScanner *scanner,
+parse_bitwise_and_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value)
{
- return parse_operator_expression (scanner, value, TOKEN_BITWISE_OR, "|",
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_AND,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_equality_expression);
+}
+
+static int
+parse_bitwise_xor_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_XOR,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
parse_bitwise_and_expression);
}
static int
+parse_bitwise_or_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_OR,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
+ parse_bitwise_xor_expression);
+}
+
+static int
parse_logical_and_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value)
{
- return parse_operator_expression (scanner, value, TOKEN_LOGICAL_AND, "&&",
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_AND,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
parse_bitwise_or_expression);
}
@@ -579,7 +613,10 @@ static int
parse_logical_or_expression (ViviCompilerScanner *scanner,
ViviCodeValue **value)
{
- return parse_operator_expression (scanner, value, TOKEN_LOGICAL_OR, "||",
+ static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_OR,
+ TOKEN_NONE };
+
+ return parse_operator_expression (scanner, value, tokens,
parse_logical_and_expression);
}
commit 7621685773df5871374534967e8a0048d55d6859
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 00:43:41 2008 +0300
Fix bugs in the GScanner -> ViviCompilerScanner conversion
diff --git a/vivified/code/compiler.c b/vivified/code/compiler.c
index d0b78e4..08d85b6 100644
--- a/vivified/code/compiler.c
+++ b/vivified/code/compiler.c
@@ -47,6 +47,9 @@ main (int argc, char *argv[])
}
statement = vivi_compile_file (file, argv[1]);
+
+ fclose (file);
+
if (statement == NULL) {
g_printerr ("Compilation failed\n");
return -1;
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index ad05557..2b2d03f 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -192,8 +192,8 @@ parse_string_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, G_TOKEN_STRING))
- return -G_TOKEN_STRING;
+ if (!check_token (scanner, TOKEN_STRING))
+ return -TOKEN_STRING;
*value = vivi_code_constant_new_string (scanner->value.v_string);
return TOKEN_NONE;
@@ -227,8 +227,8 @@ parse_identifier (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, G_TOKEN_IDENTIFIER))
- return -G_TOKEN_IDENTIFIER;
+ if (!check_token (scanner, TOKEN_IDENTIFIER))
+ return -TOKEN_IDENTIFIER;
*value = vivi_code_get_new_name (scanner->value.v_identifier);
@@ -258,7 +258,7 @@ parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value);
+parse_logical_or_expression (ViviCompilerScanner *scanner, ViviCodeValue **value);
static int
parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
@@ -267,12 +267,12 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
*value = NULL;
- if (!check_token (scanner, '{'))
- return -'{';
+ if (!check_token (scanner, TOKEN_BRACE_LEFT))
+ return -TOKEN_BRACE_LEFT;
*value = vivi_code_init_object_new ();
- if (!check_token (scanner, '}')) {
+ if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
do {
ViviCodeValue *property, *initializer;
@@ -283,14 +283,14 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
return FAIL (expected);
}
- if (!check_token (scanner, ':')) {
+ if (!check_token (scanner, TOKEN_COLON)) {
g_object_unref (*value);
*value = NULL;
- return ':';
+ return TOKEN_COLON;
}
// FIXME: assignment expression
- expected = parse_operator_expression (scanner, &initializer);
+ expected = parse_logical_or_expression (scanner, &initializer);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
@@ -299,13 +299,13 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
vivi_code_init_object_add_variable (VIVI_CODE_INIT_OBJECT (*value),
property, initializer);
- } while (check_token (scanner, ','));
+ } while (check_token (scanner, TOKEN_COMMA));
}
- if (!check_token (scanner, '}')) {
+ if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
g_object_unref (*value);
*value = NULL;
- return '}';
+ return TOKEN_BRACE_RIGHT;
}
return TOKEN_NONE;
@@ -326,9 +326,9 @@ parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
if (expected != TOKEN_NONE)
return expected;
- if (check_token (scanner, '=')) {
+ if (check_token (scanner, TOKEN_EQUAL)) {
// FIXME: assignment expression
- expected = parse_operator_expression (scanner, &value);
+ expected = parse_logical_or_expression (scanner, &value);
if (expected != TOKEN_NONE) {
g_object_unref (identifier);
return FAIL (expected);
@@ -364,15 +364,15 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
return TOKEN_NONE;
}
- if (check_token (scanner, '(')) {
+ if (check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
// FIXME: assignment expression
- expected = parse_operator_expression (scanner, value);
+ expected = parse_logical_or_expression (scanner, value);
if (expected != TOKEN_NONE)
return FAIL (expected);
- if (!check_token (scanner, ')')) {
+ if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
g_object_unref (*value);
*value = NULL;
- return ')';
+ return TOKEN_PARENTHESIS_RIGHT;
}
return TOKEN_NONE;
}
@@ -404,14 +404,14 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
do {
ViviCodeValue *tmp;
- if (check_token (scanner, '[')) {
+ if (check_token (scanner, TOKEN_BRACKET_LEFT)) {
// FIXME: expression
- expected = parse_operator_expression (scanner, &member);
+ expected = parse_logical_or_expression (scanner, &member);
if (expected != TOKEN_NONE)
return FAIL (expected);
- if (!check_token (scanner, ']'))
- return ']';
- } else if (check_token (scanner, '.')) {
+ if (!check_token (scanner, TOKEN_BRACKET_RIGHT))
+ return TOKEN_BRACKET_RIGHT;
+ } else if (check_token (scanner, TOKEN_DOT)) {
expected = parse_identifier (scanner, &member);
if (expected != TOKEN_NONE)
return FAIL (expected);
@@ -506,7 +506,7 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
*value = NULL;
- if (check_token (scanner, '!')) {
+ if (check_token (scanner, TOKEN_LOGICAL_NOT)) {
int expected = parse_unary_expression (scanner, value);
if (expected != TOKEN_NONE)
return FAIL (expected);
@@ -520,7 +520,9 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
-parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
+parse_operator_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value, ViviCompilerScannerToken token, const char *name,
+ ParseValueFunction next_parse_function)
{
int expected;
ViviCodeValue *left;
@@ -528,12 +530,12 @@ parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
*value = NULL;
- expected = parse_unary_expression (scanner, value);
+ expected = next_parse_function (scanner, value);
if (expected != TOKEN_NONE)
return expected;
- while (check_token (scanner, '+')) {
- expected = parse_unary_expression (scanner, &right);
+ while (check_token (scanner, token)) {
+ expected = next_parse_function (scanner, &right);
if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
@@ -541,7 +543,7 @@ parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
left = VIVI_CODE_VALUE (*value);
- *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right), "+");
+ *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right), name);
g_object_unref (left);
g_object_unref (right);
};
@@ -550,6 +552,38 @@ parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
}
static int
+parse_bitwise_and_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ return parse_operator_expression (scanner, value, TOKEN_BITWISE_AND, "&",
+ parse_unary_expression);
+}
+
+static int
+parse_bitwise_or_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ return parse_operator_expression (scanner, value, TOKEN_BITWISE_OR, "|",
+ parse_bitwise_and_expression);
+}
+
+static int
+parse_logical_and_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ return parse_operator_expression (scanner, value, TOKEN_LOGICAL_AND, "&&",
+ parse_bitwise_or_expression);
+}
+
+static int
+parse_logical_or_expression (ViviCompilerScanner *scanner,
+ ViviCodeValue **value)
+{
+ return parse_operator_expression (scanner, value, TOKEN_LOGICAL_OR, "||",
+ parse_logical_and_expression);
+}
+
+static int
parse_assignment_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
static int
@@ -561,11 +595,11 @@ parse_conditional_expression (ViviCompilerScanner *scanner, ViviCodeStatement **
*statement = NULL;
- expected = parse_operator_expression (scanner, &value);
+ expected = parse_logical_or_expression (scanner, &value);
if (expected != TOKEN_NONE)
return expected;
- if (!check_token (scanner, '?')) {
+ if (!check_token (scanner, TOKEN_QUESTION_MARK)) {
*statement = vivi_code_value_statement_new (VIVI_CODE_VALUE (value));
g_object_unref (value);
return TOKEN_NONE;
@@ -577,10 +611,10 @@ parse_conditional_expression (ViviCompilerScanner *scanner, ViviCodeStatement **
return FAIL (expected);
}
- if (!check_token (scanner, ':')) {
+ if (!check_token (scanner, TOKEN_COLON)) {
g_object_unref (value);
g_object_unref (if_statement);
- return ':';
+ return TOKEN_COLON;
}
expected = parse_assignment_expression (scanner, &else_statement);
@@ -617,7 +651,7 @@ parse_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
*statement = NULL;
return parse_statement_list (scanner, parse_assignment_expression, statement,
- ',');
+ TOKEN_COMMA);
}
// statement
@@ -630,17 +664,17 @@ parse_expression_statement (ViviCompilerScanner *scanner, ViviCodeStatement **st
*statement = NULL;
vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token == '{' || scanner->next_token == TOKEN_FUNCTION)
+ if (scanner->next_token == TOKEN_BRACE_LEFT || scanner->next_token == TOKEN_FUNCTION)
return -ERROR_TOKEN_EXPRESSION_STATEMENT;
expected = parse_expression (scanner, statement);
if (expected != TOKEN_NONE)
return expected;
- if (!check_token (scanner, ';')) {
+ if (!check_token (scanner, TOKEN_SEMICOLON)) {
g_object_unref (*statement);
*statement = NULL;
- return ';';
+ return TOKEN_SEMICOLON;
}
return TOKEN_NONE;
@@ -651,8 +685,8 @@ parse_empty_statement (ViviCompilerScanner *scanner, ViviCodeStatement **stateme
{
*statement = NULL;
- if (!check_token (scanner, ';'))
- return -';';
+ if (!check_token (scanner, TOKEN_SEMICOLON))
+ return -TOKEN_SEMICOLON;
*statement = vivi_compiler_empty_statement_new ();
@@ -669,11 +703,11 @@ parse_block (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
*statement = NULL;
- if (!check_token (scanner, '{'))
- return -'{';
+ if (!check_token (scanner, TOKEN_BRACE_LEFT))
+ return -TOKEN_BRACE_LEFT;
vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token != '}') {
+ if (scanner->next_token != TOKEN_BRACE_RIGHT) {
expected =
parse_statement_list (scanner, parse_statement, statement, TOKEN_NONE);
if (expected != TOKEN_NONE)
@@ -682,10 +716,10 @@ parse_block (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
*statement = vivi_code_block_new ();
}
- if (!check_token (scanner, '}')) {
+ if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
g_object_unref (*statement);
*statement = NULL;
- return '}';
+ return TOKEN_BRACE_RIGHT;
}
return TOKEN_NONE;
@@ -702,14 +736,14 @@ parse_variable_statement (ViviCompilerScanner *scanner, ViviCodeStatement **stat
return -TOKEN_VAR;
expected =
- parse_statement_list (scanner, parse_variable_declaration, statement, ',');
+ parse_statement_list (scanner, parse_variable_declaration, statement, TOKEN_COMMA);
if (expected != TOKEN_NONE)
return FAIL (expected);
- if (!check_token (scanner, ';')) {
+ if (!check_token (scanner, TOKEN_SEMICOLON)) {
g_object_unref (*statement);
*statement = NULL;
- return ';';
+ return TOKEN_SEMICOLON;
}
return TOKEN_NONE;
@@ -775,25 +809,25 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
if (expected != TOKEN_NONE)
return FAIL (expected);
- if (!check_token (scanner, '(')) {
+ if (!check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
g_object_unref (identifier);
- return '(';
+ return TOKEN_PARENTHESIS_LEFT;
}
- expected = parse_value_list (scanner, parse_identifier, &arguments, ',');
+ expected = parse_value_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
if (expected != TOKEN_NONE && expected >= 0)
return expected;
- if (!check_token (scanner, ')')) {
+ if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
g_object_unref (identifier);
free_value_list (arguments);
- return ')';
+ return TOKEN_PARENTHESIS_RIGHT;
}
- if (!check_token (scanner, '{')) {
+ if (!check_token (scanner, TOKEN_BRACE_LEFT)) {
g_object_unref (identifier);
free_value_list (arguments);
- return '{';
+ return TOKEN_BRACE_LEFT;
}
expected = parse_statement_list (scanner, parse_source_element, &body,
@@ -804,11 +838,11 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
return expected;
}
- if (!check_token (scanner, '}')) {
+ if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
g_object_unref (identifier);
free_value_list (arguments);
g_object_unref (body);
- return '}';
+ return TOKEN_BRACE_RIGHT;
}
/*function = vivi_code_function_new (arguments, body);
@@ -851,7 +885,7 @@ parse_program (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
if (expected != TOKEN_NONE)
return FAIL (expected);
- if (!check_token (scanner, G_TOKEN_EOF)) {
+ if (!check_token (scanner, TOKEN_EOF)) {
*statement = NULL;
return FAIL (parse_statement (scanner, statement));
}
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 81cd0a7..18a7772 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -49,17 +49,136 @@ vivi_compiler_scanner_init (ViviCompilerScanner *token)
{
}
-ViviCompilerScanner *
-vivi_compiler_scanner_new (FILE *file)
+static const struct {
+ ViviCompilerScannerToken token;
+ const char * name;
+} token_names[] = {
+ // special
+ { TOKEN_NONE, "NONE" },
+ { TOKEN_EOF, "EOF" },
+ { TOKEN_UNKNOWN, "UNKNOWN" },
+
+ // comparision
+ { TOKEN_BRACE_LEFT, "{", },
+ { TOKEN_BRACE_RIGHT, "}", },
+ { TOKEN_BRACKET_LEFT, "[", },
+ { TOKEN_BRACKET_RIGHT, "]", },
+ { TOKEN_PARENTHESIS_LEFT, "(", },
+ { TOKEN_PARENTHESIS_RIGHT, ")", },
+
+ // punctuation
+ { TOKEN_DOT, ".", },
+ { TOKEN_SEMICOLON, ";" },
+ { TOKEN_COMMA, "," },
+
+ // comparision
+ { TOKEN_LESS_THAN, "<" },
+ { TOKEN_GREATER_THAN, ">" },
+ { TOKEN_LESS_THAN_OR_EQUAL, "<=" },
+ { TOKEN_EQUAL_OR_MORE_THAN, "=>" },
+
+ // equality
+ { TOKEN_EQUAL, "=" },
+ { TOKEN_NOT_EQUAL, "!=" },
+ { TOKEN_STRICT_EQUAL, "===" },
+ { TOKEN_NOT_STRICT_EQUAL, "!==" },
+
+ // operator
+ { TOKEN_PLUS, "+" },
+ { TOKEN_MINUS, "-" },
+ { TOKEN_MULTIPLY, "*" },
+ { TOKEN_DIVIDE, "/" },
+ { TOKEN_REMAINDER, "%" },
+
+ // shift
+ { TOKEN_SHIFT_LEFT, "<<" },
+ { TOKEN_SHIFT_RIGHT, ">>" },
+ { TOKEN_SHIFT_RIGHT_UNSIGNED, ">>>" },
+
+ // bitwise
+ { TOKEN_BITWISE_AND, "&" },
+ { TOKEN_BITWISE_OR, "|" },
+ { TOKEN_BITWISE_XOR, "^" },
+
+ // unary/postfix
+ { TOKEN_LOGICAL_NOT, "!" },
+ { TOKEN_BITWISE_NOT, "~" },
+ { TOKEN_PLUSPLUS, "++" },
+ { TOKEN_MINUSMINUS, "--" },
+
+ // conditional
+ { TOKEN_QUESTION_MARK, "?" },
+ { TOKEN_COLON, ":" },
+
+ // logical
+ { TOKEN_LOGICAL_AND, "&&" },
+ { TOKEN_LOGICAL_OR, "||" },
+
+ // assign
+ { TOKEN_ASSIGN, "=" },
+ { TOKEN_ASSIGN_MULTIPLY, "*=" },
+ { TOKEN_ASSIGN_DIVIDE, "/=" },
+ { TOKEN_ASSIGN_REMAINDER, "%=" },
+ { TOKEN_ASSIGN_ADD, "+=" },
+ { TOKEN_ASSIGN_MINUS, "-=" },
+ { TOKEN_ASSIGN_SHIFT_LEFT, "<<=" },
+ { TOKEN_ASSIGN_SHIFT_RIGHT, ">>=" },
+ { TOKEN_ASSIGN_SHIFT_RIGHT_ZERO, ">>>=" },
+ { TOKEN_ASSIGN_BITWISE_AND, "&=" },
+ { TOKEN_ASSIGN_BITWISE_XOR, "^=" },
+ { TOKEN_ASSIGN_BITWISE_OR, "|=" },
+
+ // values
+ { TOKEN_NULL, "null" },
+ { TOKEN_BOOLEAN, "BOOLEAN" },
+ { TOKEN_NUMBER, "NUMBER" },
+ { TOKEN_STRING, "STRING" },
+ { TOKEN_IDENTIFIER, "IDENTIFIER" },
+
+ // keywords
+ { TOKEN_BREAK, "break" },
+ { TOKEN_CASE, "case" },
+ { TOKEN_CATCH, "" },
+ { TOKEN_CONTINUE, "" },
+ { TOKEN_DEFAULT, "" },
+ { TOKEN_DELETE, "" },
+ { TOKEN_DO, "" },
+ { TOKEN_ELSE, "" },
+ { TOKEN_FINALLY, "" },
+ { TOKEN_FOR, "" },
+ { TOKEN_FUNCTION, "" },
+ { TOKEN_IF, "" },
+ { TOKEN_IN, "" },
+ { TOKEN_INSTANCEOF, "" },
+ { TOKEN_NEW, "" },
+ { TOKEN_RETURN, "" },
+ { TOKEN_SWITCH, "" },
+ { TOKEN_THIS, "" },
+ { TOKEN_THROW, "" },
+ { TOKEN_TRY, "" },
+ { TOKEN_TYPEOF, "" },
+ { TOKEN_VAR, "" },
+ { TOKEN_VOID, "" },
+ { TOKEN_WITH, "" },
+
+ // reserved keywords
+ { TOKEN_FUTURE, "RESERVED KEYWORD" },
+
+ { TOKEN_LAST, NULL }
+};
+
+const char *vivi_compiler_scanner_token_name (ViviCompilerScannerToken token)
{
- ViviCompilerScanner *scanner;
+ int i;
- g_return_val_if_fail (file != NULL, NULL);
+ for (i = 0; token_names[i].token != TOKEN_LAST; i++) {
+ if (token_names[i].token == token)
+ return token_names[i].name;
+ }
- scanner = g_object_new (VIVI_TYPE_COMPILER_SCANNER, NULL);
- scanner->file = file;
+ g_assert_not_reached ();
- return scanner;
+ return "INVALID TOKEN";
}
static void
@@ -79,6 +198,24 @@ vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
}
}
+ViviCompilerScanner *
+vivi_compiler_scanner_new (FILE *file)
+{
+ ViviCompilerScanner *scanner;
+
+ g_return_val_if_fail (file != NULL, NULL);
+
+ scanner = g_object_new (VIVI_TYPE_COMPILER_SCANNER, NULL);
+ scanner->file = file;
+
+ yyrestart (file);
+ yyout = stdout;
+
+ vivi_compiler_scanner_advance (scanner);
+
+ return scanner;
+}
+
ViviCompilerScannerToken
vivi_compiler_scanner_get_next_token (ViviCompilerScanner *scanner)
{
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 16618cb..9a1dc03 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -25,7 +25,9 @@
G_BEGIN_DECLS
+
typedef enum {
+ // special
TOKEN_NONE = 0,
TOKEN_EOF,
TOKEN_UNKNOWN,
@@ -33,8 +35,8 @@ typedef enum {
// comparision
TOKEN_BRACE_LEFT,
TOKEN_BRACE_RIGHT,
- TOKEN_BRACKET_RIGHT,
TOKEN_BRACKET_LEFT,
+ TOKEN_BRACKET_RIGHT,
TOKEN_PARENTHESIS_LEFT,
TOKEN_PARENTHESIS_RIGHT,
@@ -104,6 +106,7 @@ typedef enum {
TOKEN_NULL,
TOKEN_BOOLEAN,
TOKEN_NUMBER,
+ TOKEN_STRING,
TOKEN_IDENTIFIER,
// keywords
@@ -178,5 +181,8 @@ ViviCompilerScanner * vivi_compiler_scanner_new (FILE * file);
ViviCompilerScannerToken vivi_compiler_scanner_get_next_token (ViviCompilerScanner * scanner);
ViviCompilerScannerToken vivi_compiler_scanner_peek_next_token (ViviCompilerScanner * scanner);
+const char * vivi_compiler_scanner_token_name (ViviCompilerScannerToken token);
+
+
G_END_DECLS
#endif
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
index b35fe96..8429618 100644
--- a/vivified/code/vivi_compiler_scanner_lex.lex
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -9,6 +9,8 @@ identifier_part [$_a-zA-Z0-9]
%%
[ \t\n\r] /* skip whitespace */
+<<EOF>> { return TOKEN_EOF; }
+
"{" { return TOKEN_BRACE_LEFT; }
"}" { return TOKEN_BRACE_RIGHT; }
"[" { return TOKEN_BRACKET_RIGHT; }
commit ae92e76a913892ff0687c018dce37f1679327c16
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Wed Apr 2 00:12:36 2008 +0300
Convert from GScanner to ViviCompilerScanner
diff --git a/vivified/code/compiler.c b/vivified/code/compiler.c
index 1e5cd3a..d0b78e4 100644
--- a/vivified/code/compiler.c
+++ b/vivified/code/compiler.c
@@ -30,8 +30,7 @@ int
main (int argc, char *argv[])
{
SwfdecPlayer *player;
- char *text;
- gsize text_len;
+ FILE *file;
ViviCodeStatement *statement;
player = swfdec_player_new (NULL);
@@ -41,12 +40,13 @@ main (int argc, char *argv[])
return 1;
}
- if (!g_file_get_contents (argv[1], &text, &text_len, NULL)) {
+ file = fopen (argv[1], "r");
+ if (file == NULL) {
g_printerr ("Couldn't open file %s", argv[1]);
return -1;
}
- statement = vivi_compile_text (text, text_len, argv[1]);
+ statement = vivi_compile_file (file, argv[1]);
if (statement == NULL) {
g_printerr ("Compilation failed\n");
return -1;
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 760c14e..ad05557 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -25,6 +25,8 @@
#include "vivi_compiler.h"
+#include "vivi_compiler_scanner.h"
+
#include "vivi_code_assignment.h"
#include "vivi_code_binary.h"
#include "vivi_code_block.h"
@@ -47,57 +49,7 @@
#include "vivi_code_text_printer.h"
-enum {
- // keywords
- TOKEN_BREAK = G_TOKEN_LAST + 1,
- TOKEN_CASE,
- TOKEN_CATCH,
- TOKEN_CONTINUE,
- TOKEN_DEFAULT,
- TOKEN_DELETE,
- TOKEN_DO,
- TOKEN_ELSE,
- TOKEN_FINALLY,
- TOKEN_FOR,
- TOKEN_FUNCTION,
- TOKEN_IF,
- TOKEN_IN,
- TOKEN_INSTANCEOF,
- TOKEN_NEW,
- TOKEN_RETURN,
- TOKEN_SWITCH,
- TOKEN_THIS,
- TOKEN_THROW,
- TOKEN_TRY,
- TOKEN_TYPEOF,
- TOKEN_VAR,
- TOKEN_VOID,
- TOKEN_WITH,
- // reserved keywords
- TOKEN_FUTURE,
- // values
- TOKEN_TRUE,
- TOKEN_FALSE,
- TOKEN_NULL,
- // misc
- TOKEN_PLUSPLUS,
- TOKEN_MINUSMINUS,
- // errors
- ERROR_TOKEN_BOOLEAN,
- ERROR_TOKEN_LITERAL,
- ERROR_TOKEN_PROPERTY_NAME,
- ERROR_TOKEN_PRIMARY_EXPRESSION,
- ERROR_TOKEN_EXPRESSION_STATEMENT,
- ERROR_TOKEN_STATEMENT
-};
-
-typedef struct {
- guint token;
- const char * symbol;
-} TokenDescription;
-
-static const TokenDescription custom_tokens[] = {
- // keywords
+#if 0
{ TOKEN_BREAK, "break" },
{ TOKEN_CASE, "case" },
{ TOKEN_CATCH, "catch" },
@@ -154,48 +106,35 @@ static const TokenDescription custom_tokens[] = {
{ TOKEN_FUTURE, "throws" },
{ TOKEN_FUTURE, "transient" },
{ TOKEN_FUTURE, "volatile" },
- // values
- { TOKEN_TRUE, "true" },
- { TOKEN_FALSE, "false" },
- { TOKEN_NULL, "null" },
- // misc
- { TOKEN_PLUSPLUS, "++" },
- { TOKEN_MINUSMINUS, "--" },
- { G_TOKEN_NONE, NULL }
-};
+#endif
-static const TokenDescription error_tokens[] = {
- // errors
- { ERROR_TOKEN_BOOLEAN, "boolean" },
- { ERROR_TOKEN_LITERAL, "literal" },
- { ERROR_TOKEN_PROPERTY_NAME, "property name" },
- { ERROR_TOKEN_PRIMARY_EXPRESSION, "primary expression" },
- { ERROR_TOKEN_EXPRESSION_STATEMENT, "expression statement" },
- { ERROR_TOKEN_STATEMENT, "statement" },
- { G_TOKEN_NONE, NULL }
+enum {
+ ERROR_TOKEN_LITERAL = TOKEN_LAST + 1,
+ ERROR_TOKEN_PROPERTY_NAME,
+ ERROR_TOKEN_PRIMARY_EXPRESSION,
+ ERROR_TOKEN_EXPRESSION_STATEMENT,
+ ERROR_TOKEN_STATEMENT
};
#define FAIL(x) ((x) < 0 ? -x : x)
-typedef int (*ParseStatementFunction) (GScanner *scanner, ViviCodeStatement **statement);
-typedef int (*ParseValueFunction) (GScanner *scanner, ViviCodeValue **value);
+typedef int (*ParseStatementFunction) (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
+typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
static int
-parse_statement_list (GScanner *scanner, ParseStatementFunction function,
- ViviCodeStatement **statement, guint separator);
+parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
static int
-parse_value_list (GScanner *scanner, ParseValueFunction function,
- ViviCodeValue ***list, guint separator);
+parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function, ViviCodeValue ***list, guint separator);
// helpers
static gboolean
-check_token (GScanner *scanner, guint token)
+check_token (ViviCompilerScanner *scanner, guint token)
{
- g_scanner_peek_next_token (scanner);
+ vivi_compiler_scanner_peek_next_token (scanner);
if (scanner->next_token != token)
return FALSE;
- g_scanner_get_next_token (scanner);
+ vivi_compiler_scanner_get_next_token (scanner);
return TRUE;
}
@@ -213,7 +152,7 @@ free_value_list (ViviCodeValue **list)
// values
static int
-parse_null_literal (GScanner *scanner, ViviCodeValue **value)
+parse_null_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
@@ -221,39 +160,35 @@ parse_null_literal (GScanner *scanner, ViviCodeValue **value)
return -TOKEN_NULL;
*value = vivi_code_constant_new_null ();
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_boolean_literal (GScanner *scanner, ViviCodeValue **value)
+parse_boolean_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
- if (check_token (scanner, TOKEN_TRUE)) {
- *value = vivi_code_constant_new_boolean (TRUE);
- return G_TOKEN_NONE;
- } else if (check_token (scanner, TOKEN_FALSE)) {
- *value = vivi_code_constant_new_boolean (FALSE);
- return G_TOKEN_NONE;
- } else {
- return -ERROR_TOKEN_BOOLEAN;
- }
+ if (!check_token (scanner, TOKEN_BOOLEAN))
+ return -TOKEN_BOOLEAN;
+
+ *value = vivi_code_constant_new_boolean (scanner->value.v_boolean);
+ return TOKEN_NONE;
}
static int
-parse_numeric_literal (GScanner *scanner, ViviCodeValue **value)
+parse_numeric_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, G_TOKEN_FLOAT))
- return -G_TOKEN_FLOAT;
+ if (!check_token (scanner, TOKEN_NUMBER))
+ return -TOKEN_NUMBER;
- *value = vivi_code_constant_new_number (scanner->value.v_float);
- return G_TOKEN_NONE;
+ *value = vivi_code_constant_new_number (scanner->value.v_number);
+ return TOKEN_NONE;
}
static int
-parse_string_literal (GScanner *scanner, ViviCodeValue **value)
+parse_string_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
@@ -261,11 +196,11 @@ parse_string_literal (GScanner *scanner, ViviCodeValue **value)
return -G_TOKEN_STRING;
*value = vivi_code_constant_new_string (scanner->value.v_string);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_literal (GScanner *scanner, ViviCodeValue **value)
+parse_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
ParseValueFunction functions[] = {
@@ -288,7 +223,7 @@ parse_literal (GScanner *scanner, ViviCodeValue **value)
}
static int
-parse_identifier (GScanner *scanner, ViviCodeValue **value)
+parse_identifier (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
*value = NULL;
@@ -297,11 +232,11 @@ parse_identifier (GScanner *scanner, ViviCodeValue **value)
*value = vivi_code_get_new_name (scanner->value.v_identifier);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_property_name (GScanner *scanner, ViviCodeValue **value)
+parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
ParseValueFunction functions[] = {
@@ -323,10 +258,10 @@ parse_property_name (GScanner *scanner, ViviCodeValue **value)
}
static int
-parse_operator_expression (GScanner *scanner, ViviCodeValue **value);
+parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value);
static int
-parse_object_literal (GScanner *scanner, ViviCodeValue **value)
+parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
@@ -342,7 +277,7 @@ parse_object_literal (GScanner *scanner, ViviCodeValue **value)
ViviCodeValue *property, *initializer;
expected = parse_property_name (scanner, &property);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
return FAIL (expected);
@@ -356,7 +291,7 @@ parse_object_literal (GScanner *scanner, ViviCodeValue **value)
// FIXME: assignment expression
expected = parse_operator_expression (scanner, &initializer);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
return FAIL (expected);
@@ -373,13 +308,13 @@ parse_object_literal (GScanner *scanner, ViviCodeValue **value)
return '}';
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
// misc
static int
-parse_variable_declaration (GScanner *scanner, ViviCodeStatement **statement)
+parse_variable_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *identifier;
@@ -388,13 +323,13 @@ parse_variable_declaration (GScanner *scanner, ViviCodeStatement **statement)
*statement = NULL;
expected = parse_identifier (scanner, &identifier);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
if (check_token (scanner, '=')) {
// FIXME: assignment expression
expected = parse_operator_expression (scanner, &value);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (identifier);
return FAIL (expected);
}
@@ -405,13 +340,13 @@ parse_variable_declaration (GScanner *scanner, ViviCodeStatement **statement)
*statement = vivi_code_assignment_new (NULL, identifier, value);
vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (*statement), TRUE);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
// expression
static int
-parse_primary_expression (GScanner *scanner, ViviCodeValue **value)
+parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int i, expected;
ParseValueFunction functions[] = {
@@ -426,20 +361,20 @@ parse_primary_expression (GScanner *scanner, ViviCodeValue **value)
if (check_token (scanner, TOKEN_THIS)) {
*value = vivi_code_get_new_name ("this");
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
if (check_token (scanner, '(')) {
// FIXME: assignment expression
expected = parse_operator_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, ')')) {
g_object_unref (*value);
*value = NULL;
return ')';
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
for (i = 0; functions[i] != NULL; i++) {
@@ -452,7 +387,7 @@ parse_primary_expression (GScanner *scanner, ViviCodeValue **value)
}
static int
-parse_member_expression (GScanner *scanner, ViviCodeValue **value)
+parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
ViviCodeValue *member;
@@ -463,7 +398,7 @@ parse_member_expression (GScanner *scanner, ViviCodeValue **value)
//if (expected == STATUS_CANCEL)
// expected = parse_function_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
do {
@@ -472,16 +407,16 @@ parse_member_expression (GScanner *scanner, ViviCodeValue **value)
if (check_token (scanner, '[')) {
// FIXME: expression
expected = parse_operator_expression (scanner, &member);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, ']'))
return ']';
} else if (check_token (scanner, '.')) {
expected = parse_identifier (scanner, &member);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
} else {
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
tmp = *value;
@@ -494,7 +429,7 @@ parse_member_expression (GScanner *scanner, ViviCodeValue **value)
}
static int
-parse_new_expression (GScanner *scanner, ViviCodeValue **value)
+parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
@@ -502,7 +437,7 @@ parse_new_expression (GScanner *scanner, ViviCodeValue **value)
if (check_token (scanner, TOKEN_NEW)) {
expected = parse_new_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!VIVI_IS_CODE_FUNCTION_CALL (*value)) {
ViviCodeValue *tmp = VIVI_CODE_VALUE (*value);
@@ -511,14 +446,14 @@ parse_new_expression (GScanner *scanner, ViviCodeValue **value)
}
vivi_code_function_call_set_construct (VIVI_CODE_FUNCTION_CALL (*value),
TRUE);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
} else {
return parse_member_expression (scanner, value);
}
}
static int
-parse_left_hand_side_expression (GScanner *scanner, ViviCodeValue **value)
+parse_left_hand_side_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
@@ -532,14 +467,14 @@ parse_left_hand_side_expression (GScanner *scanner, ViviCodeValue **value)
}
static int
-parse_postfix_expression (GScanner *scanner, ViviCodeValue **value)
+parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
ViviCodeValue *tmp, *one;
const char *operator;
expected = parse_left_hand_side_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
// FIXME: Don't allow new line here
@@ -549,7 +484,7 @@ parse_postfix_expression (GScanner *scanner, ViviCodeValue **value)
} else if (check_token (scanner, TOKEN_MINUSMINUS)) {
operator = "-";
} else {
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
one = vivi_code_constant_new_number (1);
@@ -561,11 +496,11 @@ parse_postfix_expression (GScanner *scanner, ViviCodeValue **value)
g_object_unref (one);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_unary_expression (GScanner *scanner, ViviCodeValue **value)
+parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
ViviCodeValue *tmp;
@@ -573,19 +508,19 @@ parse_unary_expression (GScanner *scanner, ViviCodeValue **value)
if (check_token (scanner, '!')) {
int expected = parse_unary_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
tmp = VIVI_CODE_VALUE (*value);
*value = vivi_code_unary_new (tmp, '!');
g_object_unref (tmp);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
} else {
return parse_postfix_expression (scanner, value);
}
}
static int
-parse_operator_expression (GScanner *scanner, ViviCodeValue **value)
+parse_operator_expression (ViviCompilerScanner *scanner, ViviCodeValue **value)
{
int expected;
ViviCodeValue *left;
@@ -594,12 +529,12 @@ parse_operator_expression (GScanner *scanner, ViviCodeValue **value)
*value = NULL;
expected = parse_unary_expression (scanner, value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
while (check_token (scanner, '+')) {
expected = parse_unary_expression (scanner, &right);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (*value);
*value = NULL;
return FAIL (expected);
@@ -611,14 +546,14 @@ parse_operator_expression (GScanner *scanner, ViviCodeValue **value)
g_object_unref (right);
};
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_assignment_expression (GScanner *scanner, ViviCodeStatement **statement);
+parse_assignment_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
static int
-parse_conditional_expression (GScanner *scanner, ViviCodeStatement **statement)
+parse_conditional_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
ViviCodeValue *value;
@@ -627,17 +562,17 @@ parse_conditional_expression (GScanner *scanner, ViviCodeStatement **statement)
*statement = NULL;
expected = parse_operator_expression (scanner, &value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
if (!check_token (scanner, '?')) {
*statement = vivi_code_value_statement_new (VIVI_CODE_VALUE (value));
g_object_unref (value);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
expected = parse_assignment_expression (scanner, &if_statement);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (value);
return FAIL (expected);
}
@@ -649,7 +584,7 @@ parse_conditional_expression (GScanner *scanner, ViviCodeStatement **statement)
}
expected = parse_assignment_expression (scanner, &else_statement);
- if (expected != G_TOKEN_NONE) {
+ if (expected != TOKEN_NONE) {
g_object_unref (value);
g_object_unref (if_statement);
return FAIL (expected);
@@ -663,11 +598,11 @@ parse_conditional_expression (GScanner *scanner, ViviCodeStatement **statement)
g_object_unref (if_statement);
g_object_unref (else_statement);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_assignment_expression (GScanner *scanner, ViviCodeStatement **statement)
+parse_assignment_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
*statement = NULL;
@@ -677,7 +612,7 @@ parse_assignment_expression (GScanner *scanner, ViviCodeStatement **statement)
}
static int
-parse_expression (GScanner *scanner, ViviCodeStatement **statement)
+parse_expression (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
*statement = NULL;
@@ -688,18 +623,18 @@ parse_expression (GScanner *scanner, ViviCodeStatement **statement)
// statement
static int
-parse_expression_statement (GScanner *scanner, ViviCodeStatement **statement)
+parse_expression_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
*statement = NULL;
- g_scanner_peek_next_token (scanner);
+ vivi_compiler_scanner_peek_next_token (scanner);
if (scanner->next_token == '{' || scanner->next_token == TOKEN_FUNCTION)
return -ERROR_TOKEN_EXPRESSION_STATEMENT;
expected = parse_expression (scanner, statement);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
if (!check_token (scanner, ';')) {
@@ -708,11 +643,11 @@ parse_expression_statement (GScanner *scanner, ViviCodeStatement **statement)
return ';';
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_empty_statement (GScanner *scanner, ViviCodeStatement **statement)
+parse_empty_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
*statement = NULL;
@@ -721,14 +656,14 @@ parse_empty_statement (GScanner *scanner, ViviCodeStatement **statement)
*statement = vivi_compiler_empty_statement_new ();
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_statement (GScanner *scanner, ViviCodeStatement **statement);
+parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
static int
-parse_block (GScanner *scanner, ViviCodeStatement **statement)
+parse_block (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
@@ -737,11 +672,11 @@ parse_block (GScanner *scanner, ViviCodeStatement **statement)
if (!check_token (scanner, '{'))
return -'{';
- g_scanner_peek_next_token (scanner);
+ vivi_compiler_scanner_peek_next_token (scanner);
if (scanner->next_token != '}') {
expected =
- parse_statement_list (scanner, parse_statement, statement, G_TOKEN_NONE);
- if (expected != G_TOKEN_NONE)
+ parse_statement_list (scanner, parse_statement, statement, TOKEN_NONE);
+ if (expected != TOKEN_NONE)
return FAIL (expected);
} else {
*statement = vivi_code_block_new ();
@@ -753,11 +688,11 @@ parse_block (GScanner *scanner, ViviCodeStatement **statement)
return '}';
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_variable_statement (GScanner *scanner, ViviCodeStatement **statement)
+parse_variable_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
@@ -768,7 +703,7 @@ parse_variable_statement (GScanner *scanner, ViviCodeStatement **statement)
expected =
parse_statement_list (scanner, parse_variable_declaration, statement, ',');
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, ';')) {
@@ -777,11 +712,11 @@ parse_variable_statement (GScanner *scanner, ViviCodeStatement **statement)
return ';';
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_statement (GScanner *scanner, ViviCodeStatement **statement)
+parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int i, expected;
ParseStatementFunction functions[] = {
@@ -816,10 +751,10 @@ parse_statement (GScanner *scanner, ViviCodeStatement **statement)
// function
static int
-parse_source_element (GScanner *scanner, ViviCodeStatement **statement);
+parse_source_element (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
static int
-parse_function_declaration (GScanner *scanner, ViviCodeStatement **statement)
+parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
//ViviCodeStatement *function;
ViviCodeValue *identifier;
@@ -837,7 +772,7 @@ parse_function_declaration (GScanner *scanner, ViviCodeStatement **statement)
return -TOKEN_FUNCTION;
expected = parse_identifier (scanner, &identifier);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, '(')) {
@@ -846,7 +781,7 @@ parse_function_declaration (GScanner *scanner, ViviCodeStatement **statement)
}
expected = parse_value_list (scanner, parse_identifier, &arguments, ',');
- if (expected != G_TOKEN_NONE && expected >= 0)
+ if (expected != TOKEN_NONE && expected >= 0)
return expected;
if (!check_token (scanner, ')')) {
@@ -862,8 +797,8 @@ parse_function_declaration (GScanner *scanner, ViviCodeStatement **statement)
}
expected = parse_statement_list (scanner, parse_source_element, &body,
- G_TOKEN_NONE);
- if (expected != G_TOKEN_NONE && expected >= 0) {
+ TOKEN_NONE);
+ if (expected != TOKEN_NONE && expected >= 0) {
g_object_unref (identifier);
free_value_list (arguments);
return expected;
@@ -885,13 +820,13 @@ parse_function_declaration (GScanner *scanner, ViviCodeStatement **statement)
free_value_list (arguments);
g_object_unref (body);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
// top
static int
-parse_source_element (GScanner *scanner, ViviCodeStatement **statement)
+parse_source_element (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
@@ -905,15 +840,15 @@ parse_source_element (GScanner *scanner, ViviCodeStatement **statement)
}
static int
-parse_program (GScanner *scanner, ViviCodeStatement **statement)
+parse_program (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
*statement = NULL;
expected = parse_statement_list (scanner, parse_source_element, statement,
- G_TOKEN_NONE);
- if (expected != G_TOKEN_NONE)
+ TOKEN_NONE);
+ if (expected != TOKEN_NONE)
return FAIL (expected);
if (!check_token (scanner, G_TOKEN_EOF)) {
@@ -921,13 +856,13 @@ parse_program (GScanner *scanner, ViviCodeStatement **statement)
return FAIL (parse_statement (scanner, statement));
}
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
// parsing
static int
-parse_statement_list (GScanner *scanner, ParseStatementFunction function,
+parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function,
ViviCodeStatement **block, guint separator)
{
ViviCodeStatement *statement;
@@ -940,7 +875,7 @@ parse_statement_list (GScanner *scanner, ParseStatementFunction function,
*block = NULL;
expected = function (scanner, &statement);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
*block = vivi_code_block_new ();
@@ -949,22 +884,22 @@ parse_statement_list (GScanner *scanner, ParseStatementFunction function,
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*block), statement);
g_object_unref (statement);
- if (separator != G_TOKEN_NONE && !check_token (scanner, separator))
+ if (separator != TOKEN_NONE && !check_token (scanner, separator))
break;
expected = function (scanner, &statement);
- if (expected != G_TOKEN_NONE && expected >= 0) {
+ if (expected != TOKEN_NONE && expected >= 0) {
g_object_unref (*block);
*block = NULL;
return expected;
}
- } while (expected == G_TOKEN_NONE);
+ } while (expected == TOKEN_NONE);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
static int
-parse_value_list (GScanner *scanner, ParseValueFunction function,
+parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
ViviCodeValue ***list, guint separator)
{
GPtrArray *array;
@@ -976,7 +911,7 @@ parse_value_list (GScanner *scanner, ParseValueFunction function,
g_assert (list != NULL);
expected = function (scanner, &value);
- if (expected != G_TOKEN_NONE)
+ if (expected != TOKEN_NONE)
return expected;
array = g_ptr_array_new ();
@@ -984,79 +919,38 @@ parse_value_list (GScanner *scanner, ParseValueFunction function,
do {
g_ptr_array_add (array, value);
- if (separator != G_TOKEN_NONE && !check_token (scanner, separator))
+ if (separator != TOKEN_NONE && !check_token (scanner, separator))
break;
expected = function (scanner, &value);
- if (expected != G_TOKEN_NONE && expected >= 0)
+ if (expected != TOKEN_NONE && expected >= 0)
return expected;
- } while (expected == G_TOKEN_NONE);
+ } while (expected == TOKEN_NONE);
g_ptr_array_add (array, NULL);
*list = (ViviCodeValue **)g_ptr_array_free (array, FALSE);
- return G_TOKEN_NONE;
+ return TOKEN_NONE;
}
// public
ViviCodeStatement *
-vivi_compile_text (const char *text, gsize len, const char *input_name)
+vivi_compile_file (FILE *file, const char *input_name)
{
- GScanner *scanner;
+ ViviCompilerScanner *scanner;
ViviCodeStatement *statement;
- int expected, i;
-
- g_return_val_if_fail (text != NULL, NULL);
-
- scanner = g_scanner_new (NULL);
-
- scanner->config->numbers_2_int = TRUE;
- scanner->config->int_2_float = TRUE;
- scanner->config->symbol_2_token = TRUE;
- // FIXME: Should allow other Unicode characters
- scanner->config->cset_identifier_first =
- g_strdup (G_CSET_A_2_Z G_CSET_a_2_z G_CSET_LATINS G_CSET_LATINC "_$");
- scanner->config->cset_identifier_nth = g_strdup (G_CSET_A_2_Z G_CSET_a_2_z
- G_CSET_LATINS G_CSET_LATINC "_$" G_CSET_DIGITS);
- scanner->config->scan_identifier_1char = TRUE;
-
- g_scanner_set_scope (scanner, 0);
- for (i = 0; custom_tokens[i].token != G_TOKEN_NONE; i++) {
- g_scanner_scope_add_symbol (scanner, 0, custom_tokens[i].symbol,
- GINT_TO_POINTER (custom_tokens[i].token));
- }
+ int expected;
- scanner->input_name = input_name;
- g_scanner_input_text (scanner, text, len);
+ g_return_val_if_fail (file != NULL, NULL);
- expected = parse_program (scanner, &statement);
- g_assert ((expected == G_TOKEN_NONE && VIVI_IS_CODE_STATEMENT (statement)) ||
- (expected != G_TOKEN_NONE && statement == NULL));
- if (expected != G_TOKEN_NONE) {
- char *name = NULL;
-
- for (i = 0; custom_tokens[i].token != G_TOKEN_NONE; i++) {
- if (custom_tokens[i].token == FAIL (expected)) {
- name = g_ascii_strup (custom_tokens[i].symbol, -1);
- break;
- }
- }
- if (custom_tokens[i].token == G_TOKEN_NONE) {
- for (i = 0; error_tokens[i].token != G_TOKEN_NONE; i++) {
- if (error_tokens[i].token == FAIL (expected)) {
- name = g_ascii_strup (error_tokens[i].symbol, -1);
- break;
- }
- }
- }
+ scanner = vivi_compiler_scanner_new (file);
- g_scanner_get_next_token (scanner);
- g_scanner_unexp_token (scanner, FAIL (expected), NULL, name, NULL, NULL,
- TRUE);
- }
+ expected = parse_program (scanner, &statement);
+ g_assert ((expected == TOKEN_NONE && VIVI_IS_CODE_STATEMENT (statement)) ||
+ (expected != TOKEN_NONE && statement == NULL));
- g_scanner_destroy (scanner);
+ g_object_unref (scanner);
return statement;
}
diff --git a/vivified/code/vivi_compiler.h b/vivified/code/vivi_compiler.h
index f15108a..4a8529b 100644
--- a/vivified/code/vivi_compiler.h
+++ b/vivified/code/vivi_compiler.h
@@ -20,14 +20,15 @@
#ifndef _VIVI_DECOMPILER_H_
#define _VIVI_DECOMPILER_H_
+#include <stdio.h>
+
#include <swfdec/swfdec.h>
#include <vivified/code/vivi_code_statement.h>
G_BEGIN_DECLS
-ViviCodeStatement * vivi_compile_text (const char * text,
- gsize len,
+ViviCodeStatement * vivi_compile_file (FILE * file,
const char * input_name);
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 39a5c51..81cd0a7 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -72,7 +72,7 @@ vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
if (scanner->file == NULL) {
scanner->next_token = TOKEN_EOF;
- scanner->next_value.string = NULL;
+ scanner->next_value.v_string = NULL;
} else {
scanner->next_token = yylex ();
scanner->next_value = yylval;
@@ -80,7 +80,7 @@ vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
}
ViviCompilerScannerToken
-vivi_compiler_scanner_get_token (ViviCompilerScanner *scanner)
+vivi_compiler_scanner_get_next_token (ViviCompilerScanner *scanner)
{
g_return_val_if_fail (VIVI_IS_COMPILER_SCANNER (scanner), TOKEN_EOF);
@@ -90,7 +90,7 @@ vivi_compiler_scanner_get_token (ViviCompilerScanner *scanner)
}
ViviCompilerScannerToken
-vivi_compiler_scanner_peek_token (ViviCompilerScanner *scanner)
+vivi_compiler_scanner_peek_next_token (ViviCompilerScanner *scanner)
{
g_return_val_if_fail (VIVI_IS_COMPILER_SCANNER (scanner), TOKEN_EOF);
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 103ed2a..16618cb 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -26,6 +26,7 @@
G_BEGIN_DECLS
typedef enum {
+ TOKEN_NONE = 0,
TOKEN_EOF,
TOKEN_UNKNOWN,
@@ -132,14 +133,16 @@ typedef enum {
TOKEN_WITH,
// reserved keywords
- TOKEN_FUTURE
+ TOKEN_FUTURE,
+
+ TOKEN_LAST
} ViviCompilerScannerToken;
typedef union {
- gboolean boolean;
- double number;
- char * string;
- char * identifier;
+ gboolean v_boolean;
+ double v_number;
+ char * v_string;
+ char * v_identifier;
} ViviCompilerScannerValue;
typedef struct _ViviCompilerScanner ViviCompilerScanner;
@@ -172,8 +175,8 @@ struct _ViviCompilerScannerClass
GType vivi_compiler_scanner_get_type (void);
ViviCompilerScanner * vivi_compiler_scanner_new (FILE * file);
-ViviCompilerScannerToken vivi_compiler_scanner_get_token (ViviCompilerScanner * scanner);
-ViviCompilerScannerToken vivi_compiler_scanner_peek_token (ViviCompilerScanner * scanner);
+ViviCompilerScannerToken vivi_compiler_scanner_get_next_token (ViviCompilerScanner * scanner);
+ViviCompilerScannerToken vivi_compiler_scanner_peek_next_token (ViviCompilerScanner * scanner);
G_END_DECLS
#endif
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
index c6b8f70..b35fe96 100644
--- a/vivified/code/vivi_compiler_scanner_lex.lex
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -69,9 +69,9 @@ identifier_part [$_a-zA-Z0-9]
"|=" { return TOKEN_ASSIGN_BITWISE_OR; }
"null" { return TOKEN_NULL; }
-"true" { yylval.boolean = 1;
+"true" { yylval.v_boolean = 1;
return TOKEN_BOOLEAN; }
-"false" { yylval.boolean = 0;
+"false" { yylval.v_boolean = 0;
return TOKEN_BOOLEAN; }
"this" { return TOKEN_THIS; }
@@ -79,11 +79,11 @@ identifier_part [$_a-zA-Z0-9]
"abstract" { return TOKEN_FUTURE; }
-{digit}+ { yylval.number = atoi(yytext);
+{digit}+ { yylval.v_number = atoi(yytext);
return TOKEN_NUMBER; }
{identifier_start}({identifier_part})* {
- yylval.identifier = (char *)strdup(yytext);
+ yylval.v_identifier = (char *)strdup(yytext);
return TOKEN_IDENTIFIER; }
. { printf("Unknown character [%c]\n",yytext[0]);
commit aed0aa90596e180169e89f33f16848bac0e6c7f6
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Tue Apr 1 23:55:37 2008 +0300
Start implementing ViviCompilerScanner using flex
diff --git a/configure.ac b/configure.ac
index a3e186b..a5bb805 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,8 @@ AM_PROG_CC_STDC
AM_PROG_CC_C_O
AM_PROG_AS
AC_PROG_AWK
+dnl FIXME only require lex for vivi
+AM_PROG_LEX
AC_HEADER_STDC
diff --git a/vivified/code/.gitignore b/vivified/code/.gitignore
index b85daef..70af836 100644
--- a/vivified/code/.gitignore
+++ b/vivified/code/.gitignore
@@ -11,5 +11,8 @@ Makefile.in
*.lo
*.loT
+vivi_compiler_scanner_lex.c
+vivi_compiler_scanner_lex.h
+
vivi-decompile
vivi-compile
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index a0d2807..cd866af 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -33,6 +33,8 @@ libvivified_compiler_la_SOURCES = \
vivi_code_value_statement.c \
vivi_compiler.c \
vivi_compiler_empty_statement.c \
+ vivi_compiler_scanner.c \
+ vivi_compiler_scanner_lex.c \
vivi_decompiler_block.c \
vivi_decompiler_duplicate.c \
vivi_decompiler_state.c \
@@ -67,6 +69,10 @@ noinst_HEADERS = \
vivi_code_value_statement.h \
vivi_compiler.h \
vivi_compiler_empty_statement.h \
+ vivi_compiler_scanner.h \
+ vivi_compiler_scanner_lex.h \
+ vivi_compiler_scanner_lex_include.h \
+ vivi_compiler_scanner_lex.lex \
vivi_decompiler.h \
vivi_decompiler_block.h \
vivi_decompiler_duplicate.h \
@@ -74,9 +80,12 @@ noinst_HEADERS = \
vivi_decompiler_unknown.h \
vivified-compiler.h
-
noinst_PROGRAMS = vivi-decompile vivi-compile
+vivi_compiler_scanner_lex.h: vivi_compiler_scanner_lex.c
+vivi_compiler_scanner_lex.c: vivi_compiler_scanner_lex.lex
+ $(LEX) -o vivi_compiler_scanner_lex.c --header-file=vivi_compiler_scanner_lex.h vivi_compiler_scanner_lex.lex
+
vivi_decompile_SOURCES = \
decompiler.c
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
new file mode 100644
index 0000000..39a5c51
--- /dev/null
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -0,0 +1,98 @@
+/* Vivified
+ * Copyright (C) Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_compiler_scanner.h"
+
+#include "vivi_compiler_scanner_lex.h"
+#include "vivi_compiler_scanner_lex_include.h"
+
+G_DEFINE_TYPE (ViviCompilerScanner, vivi_compiler_scanner, G_TYPE_OBJECT)
+
+static void
+vivi_compiler_scanner_dispose (GObject *object)
+{
+ //ViviCompilerScanner *scanner = VIVI_COMPILER_SCANNER (object);
+
+ G_OBJECT_CLASS (vivi_compiler_scanner_parent_class)->dispose (object);
+}
+
+static void
+vivi_compiler_scanner_class_init (ViviCompilerScannerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = vivi_compiler_scanner_dispose;
+}
+
+static void
+vivi_compiler_scanner_init (ViviCompilerScanner *token)
+{
+}
+
+ViviCompilerScanner *
+vivi_compiler_scanner_new (FILE *file)
+{
+ ViviCompilerScanner *scanner;
+
+ g_return_val_if_fail (file != NULL, NULL);
+
+ scanner = g_object_new (VIVI_TYPE_COMPILER_SCANNER, NULL);
+ scanner->file = file;
+
+ return scanner;
+}
+
+static void
+vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
+{
+ g_return_if_fail (VIVI_IS_COMPILER_SCANNER (scanner));
+
+ scanner->token = scanner->next_token;
+ scanner->value = scanner->next_value;
+
+ if (scanner->file == NULL) {
+ scanner->next_token = TOKEN_EOF;
+ scanner->next_value.string = NULL;
+ } else {
+ scanner->next_token = yylex ();
+ scanner->next_value = yylval;
+ }
+}
+
+ViviCompilerScannerToken
+vivi_compiler_scanner_get_token (ViviCompilerScanner *scanner)
+{
+ g_return_val_if_fail (VIVI_IS_COMPILER_SCANNER (scanner), TOKEN_EOF);
+
+ vivi_compiler_scanner_advance (scanner);
+
+ return scanner->token;
+}
+
+ViviCompilerScannerToken
+vivi_compiler_scanner_peek_token (ViviCompilerScanner *scanner)
+{
+ g_return_val_if_fail (VIVI_IS_COMPILER_SCANNER (scanner), TOKEN_EOF);
+
+ return scanner->next_token;
+}
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
new file mode 100644
index 0000000..103ed2a
--- /dev/null
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -0,0 +1,179 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _VIVI_COMPILER_SCANNER_H_
+#define _VIVI_COMPILER_SCANNER_H_
+
+#include <stdio.h>
+#include <swfdec/swfdec.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ TOKEN_EOF,
+ TOKEN_UNKNOWN,
+
+ // comparision
+ TOKEN_BRACE_LEFT,
+ TOKEN_BRACE_RIGHT,
+ TOKEN_BRACKET_RIGHT,
+ TOKEN_BRACKET_LEFT,
+ TOKEN_PARENTHESIS_LEFT,
+ TOKEN_PARENTHESIS_RIGHT,
+
+ // punctuation
+ TOKEN_DOT,
+ TOKEN_SEMICOLON,
+ TOKEN_COMMA,
+
+ // comparision
+ TOKEN_LESS_THAN,
+ TOKEN_GREATER_THAN,
+ TOKEN_LESS_THAN_OR_EQUAL,
+ TOKEN_EQUAL_OR_MORE_THAN,
+
+ // equality
+ TOKEN_EQUAL,
+ TOKEN_NOT_EQUAL,
+ TOKEN_STRICT_EQUAL,
+ TOKEN_NOT_STRICT_EQUAL,
+
+ // operator
+ TOKEN_PLUS,
+ TOKEN_MINUS,
+ TOKEN_MULTIPLY,
+ TOKEN_DIVIDE,
+ TOKEN_REMAINDER,
+
+ // shift
+ TOKEN_SHIFT_LEFT,
+ TOKEN_SHIFT_RIGHT,
+ TOKEN_SHIFT_RIGHT_UNSIGNED,
+
+ // bitwise
+ TOKEN_BITWISE_AND,
+ TOKEN_BITWISE_OR,
+ TOKEN_BITWISE_XOR,
+
+ // unary/postfix
+ TOKEN_LOGICAL_NOT,
+ TOKEN_BITWISE_NOT,
+ TOKEN_PLUSPLUS,
+ TOKEN_MINUSMINUS,
+
+ // conditional
+ TOKEN_QUESTION_MARK,
+ TOKEN_COLON,
+
+ // logical
+ TOKEN_LOGICAL_AND,
+ TOKEN_LOGICAL_OR,
+
+ // assign
+ TOKEN_ASSIGN,
+ TOKEN_ASSIGN_MULTIPLY,
+ TOKEN_ASSIGN_DIVIDE,
+ TOKEN_ASSIGN_REMAINDER,
+ TOKEN_ASSIGN_ADD,
+ TOKEN_ASSIGN_MINUS,
+ TOKEN_ASSIGN_SHIFT_LEFT,
+ TOKEN_ASSIGN_SHIFT_RIGHT,
+ TOKEN_ASSIGN_SHIFT_RIGHT_ZERO,
+ TOKEN_ASSIGN_BITWISE_AND,
+ TOKEN_ASSIGN_BITWISE_XOR,
+ TOKEN_ASSIGN_BITWISE_OR,
+
+ // values
+ TOKEN_NULL,
+ TOKEN_BOOLEAN,
+ TOKEN_NUMBER,
+ TOKEN_IDENTIFIER,
+
+ // keywords
+ TOKEN_BREAK,
+ TOKEN_CASE,
+ TOKEN_CATCH,
+ TOKEN_CONTINUE,
+ TOKEN_DEFAULT,
+ TOKEN_DELETE,
+ TOKEN_DO,
+ TOKEN_ELSE,
+ TOKEN_FINALLY,
+ TOKEN_FOR,
+ TOKEN_FUNCTION,
+ TOKEN_IF,
+ TOKEN_IN,
+ TOKEN_INSTANCEOF,
+ TOKEN_NEW,
+ TOKEN_RETURN,
+ TOKEN_SWITCH,
+ TOKEN_THIS,
+ TOKEN_THROW,
+ TOKEN_TRY,
+ TOKEN_TYPEOF,
+ TOKEN_VAR,
+ TOKEN_VOID,
+ TOKEN_WITH,
+
+ // reserved keywords
+ TOKEN_FUTURE
+} ViviCompilerScannerToken;
+
+typedef union {
+ gboolean boolean;
+ double number;
+ char * string;
+ char * identifier;
+} ViviCompilerScannerValue;
+
+typedef struct _ViviCompilerScanner ViviCompilerScanner;
+typedef struct _ViviCompilerScannerClass ViviCompilerScannerClass;
+
+#define VIVI_TYPE_COMPILER_SCANNER (vivi_compiler_scanner_get_type())
+#define VIVI_IS_COMPILER_SCANNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_COMPILER_SCANNER))
+#define VIVI_IS_COMPILER_SCANNER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_COMPILER_SCANNER))
+#define VIVI_COMPILER_SCANNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_COMPILER_SCANNER, ViviCompilerScanner))
+#define VIVI_COMPILER_SCANNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_COMPILER_SCANNER, ViviCompilerScannerClass))
+#define VIVI_COMPILER_SCANNER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_COMPILER_SCANNER, ViviCompilerScannerClass))
+
+struct _ViviCompilerScanner
+{
+ GObject object;
+
+ FILE * file;
+
+ ViviCompilerScannerToken token;
+ ViviCompilerScannerToken next_token;
+ ViviCompilerScannerValue value;
+ ViviCompilerScannerValue next_value;
+};
+
+struct _ViviCompilerScannerClass
+{
+ GObjectClass object_class;
+};
+
+GType vivi_compiler_scanner_get_type (void);
+
+ViviCompilerScanner * vivi_compiler_scanner_new (FILE * file);
+ViviCompilerScannerToken vivi_compiler_scanner_get_token (ViviCompilerScanner * scanner);
+ViviCompilerScannerToken vivi_compiler_scanner_peek_token (ViviCompilerScanner * scanner);
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_compiler_scanner_lex.lex b/vivified/code/vivi_compiler_scanner_lex.lex
new file mode 100644
index 0000000..c6b8f70
--- /dev/null
+++ b/vivified/code/vivi_compiler_scanner_lex.lex
@@ -0,0 +1,93 @@
+%{
+#include "vivi_compiler_scanner_lex_include.h"
+%}
+
+digit [0-9]
+identifier_start [$_a-zA-Z]
+identifier_part [$_a-zA-Z0-9]
+
+%%
+
+[ \t\n\r] /* skip whitespace */
+"{" { return TOKEN_BRACE_LEFT; }
+"}" { return TOKEN_BRACE_RIGHT; }
+"[" { return TOKEN_BRACKET_RIGHT; }
+"]" { return TOKEN_BRACKET_LEFT; }
+"(" { return TOKEN_PARENTHESIS_LEFT; }
+")" { return TOKEN_PARENTHESIS_RIGHT; }
+
+"." { return TOKEN_DOT; }
+";" { return TOKEN_SEMICOLON; }
+"," { return TOKEN_COMMA; }
+
+"<" { return TOKEN_LESS_THAN; }
+">" { return TOKEN_GREATER_THAN; }
+"<=" { return TOKEN_LESS_THAN_OR_EQUAL; }
+"=>" { return TOKEN_EQUAL_OR_MORE_THAN; }
+
+"==", { return TOKEN_EQUAL; }
+"!=", { return TOKEN_NOT_EQUAL; }
+"===", { return TOKEN_STRICT_EQUAL; }
+"!==", { return TOKEN_NOT_STRICT_EQUAL; }
+
+"+" { return TOKEN_PLUS; }
+"-" { return TOKEN_MINUS; }
+"*" { return TOKEN_MULTIPLY; }
+"/" { return TOKEN_DIVIDE; }
+"%" { return TOKEN_REMAINDER; }
+
+"<<" { return TOKEN_SHIFT_LEFT; }
+">>" { return TOKEN_SHIFT_RIGHT; }
+">>>" { return TOKEN_SHIFT_RIGHT_UNSIGNED; }
+
+"&" { return TOKEN_BITWISE_AND; }
+"|" { return TOKEN_BITWISE_OR; }
+"^" { return TOKEN_BITWISE_XOR; }
+
+"!" { return TOKEN_LOGICAL_NOT; }
+"~" { return TOKEN_BITWISE_NOT; }
+"++" { return TOKEN_PLUSPLUS; }
+"--" { return TOKEN_MINUSMINUS; }
+
+"?" { return TOKEN_QUESTION_MARK; }
+":" { return TOKEN_COLON; }
+
+"&&" { return TOKEN_LOGICAL_AND; }
+"||" { return TOKEN_LOGICAL_OR; }
+
+"=" { return TOKEN_ASSIGN; }
+"*=" { return TOKEN_ASSIGN_MULTIPLY; }
+"/=" { return TOKEN_ASSIGN_DIVIDE; }
+"%=" { return TOKEN_ASSIGN_REMAINDER; }
+"+=" { return TOKEN_ASSIGN_ADD; }
+"-=" { return TOKEN_ASSIGN_MINUS; }
+"<<=" { return TOKEN_ASSIGN_SHIFT_LEFT; }
+">>=" { return TOKEN_ASSIGN_SHIFT_RIGHT; }
+">>>=" { return TOKEN_ASSIGN_SHIFT_RIGHT_ZERO; }
+"&=" { return TOKEN_ASSIGN_BITWISE_AND; }
+"^=" { return TOKEN_ASSIGN_BITWISE_XOR; }
+"|=" { return TOKEN_ASSIGN_BITWISE_OR; }
+
+"null" { return TOKEN_NULL; }
+"true" { yylval.boolean = 1;
+ return TOKEN_BOOLEAN; }
+"false" { yylval.boolean = 0;
+ return TOKEN_BOOLEAN; }
+"this" { return TOKEN_THIS; }
+
+"break" { return TOKEN_BREAK; }
+
+"abstract" { return TOKEN_FUTURE; }
+
+{digit}+ { yylval.number = atoi(yytext);
+ return TOKEN_NUMBER; }
+
+{identifier_start}({identifier_part})* {
+ yylval.identifier = (char *)strdup(yytext);
+ return TOKEN_IDENTIFIER; }
+
+. { printf("Unknown character [%c]\n",yytext[0]);
+ return TOKEN_UNKNOWN; }
+%%
+
+int yywrap(void){return 1;}
diff --git a/vivified/code/vivi_compiler_scanner_lex_include.h b/vivified/code/vivi_compiler_scanner_lex_include.h
new file mode 100644
index 0000000..2224b2f
--- /dev/null
+++ b/vivified/code/vivi_compiler_scanner_lex_include.h
@@ -0,0 +1,8 @@
+#ifndef _VIVI_COMPILER_SCANNER_LEX_INCLUDE_H_
+#define _VIVI_COMPILER_SCANNER_LEX_INCLUDE_H_
+
+#include "vivi_compiler_scanner.h"
+
+ViviCompilerScannerValue yylval;
+
+#endif // _VIVI_COMPILER_SCANNER_LEX_INCLUDE_H_
More information about the Swfdec-commits
mailing list