[Swfdec-commits] 12 commits - vivified/code
Pekka Lampila
medar at kemper.freedesktop.org
Thu Apr 3 15:26:34 PDT 2008
vivified/code/decompiler.c | 2
vivified/code/vivi_code_function.c | 44 -
vivified/code/vivi_code_function.h | 11
vivified/code/vivi_compiler.c | 1247 +++++++++++++++++++-----------
vivified/code/vivi_compiler_scanner.c | 22
vivified/code/vivi_compiler_scanner.h | 7
vivified/code/vivi_compiler_scanner_lex.l | 77 -
vivified/code/vivi_decompiler.c | 2
8 files changed, 921 insertions(+), 491 deletions(-)
New commits:
commit 1d7808def7d202930008c0b062975b177d0d7233
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 4 01:21:26 2008 +0300
Rename TOKEN_FUTURE to TOKEN_RESERVED_KEYWORD
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 0243f8f..e9c576b 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -163,7 +163,7 @@ static const struct {
{ TOKEN_WITH, "with" },
// reserved keywords
- { TOKEN_FUTURE, "RESERVED KEYWORD" },
+ { TOKEN_RESERVED_KEYWORD, "RESERVED KEYWORD" },
{ TOKEN_LAST, NULL }
};
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index c5c72f5..64067bd 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -137,7 +137,7 @@ typedef enum {
TOKEN_WITH,
// reserved keywords
- TOKEN_FUTURE,
+ TOKEN_RESERVED_KEYWORD,
TOKEN_LAST
} ViviCompilerScannerToken;
diff --git a/vivified/code/vivi_compiler_scanner_lex.l b/vivified/code/vivi_compiler_scanner_lex.l
index a4d98d8..2a2c433 100644
--- a/vivified/code/vivi_compiler_scanner_lex.l
+++ b/vivified/code/vivi_compiler_scanner_lex.l
@@ -109,37 +109,37 @@ line_terminator [\n\r]
"while" { return TOKEN_WHILE; }
"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; }
+"abstract" { return TOKEN_RESERVED_KEYWORD; }
+"boolean" { return TOKEN_RESERVED_KEYWORD; }
+"byte" { return TOKEN_RESERVED_KEYWORD; }
+"char" { return TOKEN_RESERVED_KEYWORD; }
+"class" { return TOKEN_RESERVED_KEYWORD; }
+"const" { return TOKEN_RESERVED_KEYWORD; }
+"debugger" { return TOKEN_RESERVED_KEYWORD; }
+"double" { return TOKEN_RESERVED_KEYWORD; }
+"enum" { return TOKEN_RESERVED_KEYWORD; }
+"export" { return TOKEN_RESERVED_KEYWORD; }
+"extends" { return TOKEN_RESERVED_KEYWORD; }
+"final" { return TOKEN_RESERVED_KEYWORD; }
+"float" { return TOKEN_RESERVED_KEYWORD; }
+"goto" { return TOKEN_RESERVED_KEYWORD; }
+"implements" { return TOKEN_RESERVED_KEYWORD; }
+"import" { return TOKEN_RESERVED_KEYWORD; }
+"int" { return TOKEN_RESERVED_KEYWORD; }
+"interface" { return TOKEN_RESERVED_KEYWORD; }
+"long" { return TOKEN_RESERVED_KEYWORD; }
+"native" { return TOKEN_RESERVED_KEYWORD; }
+"package" { return TOKEN_RESERVED_KEYWORD; }
+"private" { return TOKEN_RESERVED_KEYWORD; }
+"protected" { return TOKEN_RESERVED_KEYWORD; }
+"public" { return TOKEN_RESERVED_KEYWORD; }
+"short" { return TOKEN_RESERVED_KEYWORD; }
+"static" { return TOKEN_RESERVED_KEYWORD; }
+"super" { return TOKEN_RESERVED_KEYWORD; }
+"synchronized" { return TOKEN_RESERVED_KEYWORD; }
+"throws" { return TOKEN_RESERVED_KEYWORD; }
+"transient" { return TOKEN_RESERVED_KEYWORD; }
+"volatile" { return TOKEN_RESERVED_KEYWORD; }
[-+]*{digit}+ { yylval.v_number = atoi(yytext);
return TOKEN_NUMBER; }
commit 90eabd4cb45d99e3017b853454623aa8bb787ff1
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 4 01:20:05 2008 +0300
Implement parsing of while loops
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 8b7a00f..c5db218 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -54,6 +54,7 @@ enum {
ERROR_TOKEN_LITERAL = TOKEN_LAST + 1,
ERROR_TOKEN_PROPERTY_NAME,
ERROR_TOKEN_PRIMARY_EXPRESSION,
+ ERROR_TOKEN_ITERATION_STATEMENT,
ERROR_TOKEN_EXPRESSION_STATEMENT,
ERROR_TOKEN_STATEMENT
};
@@ -65,6 +66,7 @@ static const struct {
{ ERROR_TOKEN_LITERAL, "LITERAL" },
{ ERROR_TOKEN_PROPERTY_NAME, "PROPERTY NAME" },
{ ERROR_TOKEN_PRIMARY_EXPRESSION, "PRIMARY EXPRESSION" },
+ { ERROR_TOKEN_ITERATION_STATEMENT, "ITERATION STATEMENT" },
{ ERROR_TOKEN_EXPRESSION_STATEMENT, "EXPRESSION STATEMENT" },
{ ERROR_TOKEN_STATEMENT, "STATEMENT" },
{ TOKEN_LAST, NULL }
@@ -1137,6 +1139,55 @@ static ParseStatus
parse_statement (ParseData *data, ViviCodeStatement **statement);
static ParseStatus
+parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
+{
+ ParseStatus status;
+ ViviCodeValue *condition;
+ ViviCodeStatement *pre_statement, *loop_statement;
+
+ *statement = NULL;
+
+ // TODO: for, do while
+
+ if (check_token (data, TOKEN_WHILE)) {
+ if (!check_token (data, TOKEN_PARENTHESIS_LEFT))
+ return FAIL (TOKEN_PARENTHESIS_LEFT);
+
+ status = parse_expression (data, &condition, &pre_statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
+
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+ g_object_unref (condition);
+ if (pre_statement != NULL)
+ g_object_unref (pre_statement);
+ return FAIL (TOKEN_PARENTHESIS_RIGHT);
+ }
+
+ status = parse_statement (data, &loop_statement);
+ if (status != STATUS_OK) {
+ g_object_unref (condition);
+ if (pre_statement != NULL)
+ g_object_unref (pre_statement);
+ return FAIL_CHILD (status);
+ }
+
+ *statement = vivi_code_loop_new ();
+ vivi_code_loop_set_condition (VIVI_CODE_LOOP (*statement), condition);
+ g_object_unref (condition);
+ vivi_code_loop_set_statement (VIVI_CODE_LOOP (*statement), loop_statement);
+ g_object_unref (loop_statement);
+
+ *statement =
+ vivi_compiler_combine_statements (2, pre_statement, *statement);
+
+ return STATUS_OK;
+ } else {
+ return CANCEL (ERROR_TOKEN_ITERATION_STATEMENT);
+ }
+}
+
+static ParseStatus
parse_if_statement (ParseData *data, ViviCodeStatement **statement)
{
ParseStatus status;
@@ -1317,7 +1368,7 @@ parse_statement (ParseData *data, ViviCodeStatement **statement)
parse_empty_statement,
parse_expression_statement,
parse_if_statement,
- //parse_iteration_statement,
+ parse_iteration_statement,
//parse_continue_statement,
//parse_break_statement,
//parse_return_statement,
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index dcedc9d..0243f8f 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -197,8 +197,6 @@ vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
scanner->next_token = yylex ();
scanner->next_value = yylval;
}
-
- g_print (":: %s\n", vivi_compiler_scanner_token_name (scanner->next_token));
}
ViviCompilerScanner *
diff --git a/vivified/code/vivi_compiler_scanner_lex.l b/vivified/code/vivi_compiler_scanner_lex.l
index 5dc0a1c..a4d98d8 100644
--- a/vivified/code/vivi_compiler_scanner_lex.l
+++ b/vivified/code/vivi_compiler_scanner_lex.l
@@ -141,7 +141,7 @@ line_terminator [\n\r]
"transient" { return TOKEN_FUTURE; }
"volatile" { return TOKEN_FUTURE; }
-{digit}+ { yylval.v_number = atoi(yytext);
+[-+]*{digit}+ { yylval.v_number = atoi(yytext);
return TOKEN_NUMBER; }
"\"".*"\"" { yylval.v_string = g_strndup (yytext + 1, yyleng - 2);
return TOKEN_STRING; }
commit ada5063c038b84a610255c1d7d5272ad32ee306c
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 4 01:07:53 2008 +0300
Add parsing of function expression and function call. Add missing while token
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 266b3c7..8b7a00f 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -95,6 +95,11 @@ static ParseStatus
parse_statement_list (ParseData *data, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
static ParseStatus
+parse_value_statement_list (ParseData *data,
+ ParseValueStatementFunction function, ViviCodeValue ***list,
+ ViviCodeStatement **statement, guint separator);
+
+static ParseStatus
parse_value_list (ParseData *data, ParseValueFunction function,
ViviCodeValue ***list, guint separator);
@@ -121,7 +126,7 @@ free_value_list (ViviCodeValue **list)
g_free (list);
}
-static ViviCodeStatement *
+G_GNUC_WARN_UNUSED_RESULT static ViviCodeStatement *
vivi_compiler_combine_statements (guint count, ...)
{
va_list args;
@@ -158,6 +163,34 @@ vivi_compiler_combine_statements (guint count, ...)
return VIVI_CODE_STATEMENT (block);
}
+static ViviCodeValue *
+vivi_compiler_function_call_new (ViviCodeValue *name)
+{
+ ViviCodeValue *value;
+
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (name), NULL);
+
+ value = NULL;
+
+ if (VIVI_IS_CODE_GET (name)) {
+ ViviCodeGet *get = VIVI_CODE_GET (name);
+
+ if (get->from != NULL) {
+ value = g_object_ref (get->from);
+ name = g_object_ref (get->name);
+ }
+ }
+
+ 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_function_call_new (value, name);
+}
+
static ViviCodeStatement *
vivi_compiler_assignment_new (ViviCodeValue *left, ViviCodeValue *right)
{
@@ -479,6 +512,10 @@ parse_primary_expression (ParseData *data, ViviCodeValue **value,
}
static ParseStatus
+parse_function_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement);
+
+static ParseStatus
parse_member_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
@@ -492,8 +529,8 @@ parse_member_expression (ParseData *data, ViviCodeValue **value,
// TODO: new MemberExpression Arguments
status = parse_primary_expression (data, value, statement);
- //if (status == STATUS_CANCEL)
- // status = parse_function_expression (data, value);
+ if (status == STATUS_CANCEL)
+ status = parse_function_expression (data, value, statement);
if (status != STATUS_OK)
return status;
@@ -569,18 +606,85 @@ parse_new_expression (ParseData *data, ViviCodeValue **value,
}
static ParseStatus
-parse_left_hand_side_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_left_hand_side_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
ParseStatus status;
+ int i;
+ ViviCodeValue *name;
+ ViviCodeValue **arguments;
+ ViviCodeStatement *argument_statement;
*value = NULL;
+ *statement = NULL;
+
+ if (check_token (data, TOKEN_NEW)) {
+ status = parse_new_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
+ if (!VIVI_IS_CODE_FUNCTION_CALL (*value)) {
+ ViviCodeValue *tmp = VIVI_CODE_VALUE (*value);
+ *value = vivi_code_function_call_new (NULL, tmp);
+ g_object_unref (tmp);
+ }
+ vivi_code_function_call_set_construct (VIVI_CODE_FUNCTION_CALL (*value),
+ TRUE);
+ return STATUS_OK;
+ }
- status = parse_new_expression (data, value, statement);
- //if (status == STATUS_CANCEL)
- // status = parse_call_expression (data, value);
+ status = parse_member_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return status;
- return status;
+ while (TRUE) {
+ // TODO: member expressions?
+ if (!check_token (data, TOKEN_PARENTHESIS_LEFT))
+ break;
+
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+ // FIXME: assignment expression
+ status = parse_value_statement_list (data, parse_assignment_expression,
+ &arguments, &argument_statement, TOKEN_COMMA);
+ if (status != STATUS_OK) {
+ g_object_unref (*value);
+ *value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
+ return FAIL_CHILD (status);
+ }
+
+ *statement =
+ vivi_compiler_combine_statements (2, *statement, argument_statement);
+
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+ g_object_unref (*value);
+ *value = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
+ return FAIL (TOKEN_PARENTHESIS_RIGHT);
+ }
+ } else {
+ arguments = NULL;
+ }
+
+ name = *value;
+ *value = vivi_compiler_function_call_new (name);
+ g_object_unref (name);
+
+ if (arguments != NULL) {
+ for (i = 0; arguments[i] != NULL; i++) {
+ vivi_code_function_call_add_argument (VIVI_CODE_FUNCTION_CALL (*value),
+ arguments[i]);
+ }
+ free_value_list (arguments);
+ }
+ }
+
+ return STATUS_OK;
}
static ParseStatus
@@ -1242,73 +1346,112 @@ static ParseStatus
parse_source_element (ParseData *data, ViviCodeStatement **statement);
static ParseStatus
-parse_function_declaration (ParseData *data, ViviCodeStatement **statement)
+parse_function_definition (ParseData *data, ViviCodeValue **function,
+ ViviCodeValue **identifier, gboolean identifier_required)
{
- ViviCodeValue *function, *identifier;
+ ParseStatus status;
ViviCodeValue **arguments;
ViviCodeStatement *body;
- ParseStatus status;
- *statement = NULL;
+ *function = NULL;
+ *identifier = NULL;
- identifier = NULL;
arguments = NULL;
body = NULL;
if (!check_token (data, TOKEN_FUNCTION))
return CANCEL (TOKEN_FUNCTION);
- status = parse_identifier (data, &identifier);
- if (status != STATUS_OK)
+ status = parse_identifier (data, identifier);
+ if (status == STATUS_FAIL ||
+ (identifier_required && status == STATUS_CANCEL))
return FAIL_CHILD (status);
if (!check_token (data, TOKEN_PARENTHESIS_LEFT)) {
- g_object_unref (identifier);
+ g_object_unref (*identifier);
return FAIL (TOKEN_PARENTHESIS_LEFT);
}
status = parse_value_list (data, parse_identifier, &arguments, TOKEN_COMMA);
- if (status == STATUS_FAIL)
- return status;
+ if (status == STATUS_FAIL) {
+ g_object_unref (*identifier);
+ return STATUS_FAIL;
+ }
if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
- g_object_unref (identifier);
+ g_object_unref (*identifier);
free_value_list (arguments);
return FAIL (TOKEN_PARENTHESIS_RIGHT);
}
if (!check_token (data, TOKEN_BRACE_LEFT)) {
- g_object_unref (identifier);
+ g_object_unref (*identifier);
free_value_list (arguments);
return FAIL (TOKEN_BRACE_LEFT);
}
status = parse_statement_list (data, parse_source_element, &body, STATUS_OK);
if (status == STATUS_FAIL) {
- g_object_unref (identifier);
+ g_object_unref (*identifier);
free_value_list (arguments);
- return status;
+ return STATUS_FAIL;
}
if (!check_token (data, TOKEN_BRACE_RIGHT)) {
- g_object_unref (identifier);
+ g_object_unref (*identifier);
free_value_list (arguments);
g_object_unref (body);
return FAIL (TOKEN_BRACE_RIGHT);
}
- function = vivi_code_function_new ();
- vivi_code_function_set_body (VIVI_CODE_FUNCTION (function), body);
- *statement = vivi_compiler_assignment_new (VIVI_CODE_VALUE (identifier),
- VIVI_CODE_VALUE (function));
-
- g_object_unref (identifier);
+ *function = vivi_code_function_new ();
+ vivi_code_function_set_body (VIVI_CODE_FUNCTION (*function), body);
free_value_list (arguments);
g_object_unref (body);
return STATUS_OK;
}
+static ParseStatus
+parse_function_declaration (ParseData *data, ViviCodeStatement **statement)
+{
+ ParseStatus status;
+ ViviCodeValue *function, *identifier;
+
+ *statement = NULL;
+
+ status = parse_function_definition (data, &function, &identifier, TRUE);
+ if (status != STATUS_OK)
+ return status;
+
+ *statement = vivi_compiler_assignment_new (identifier, function);
+ g_object_unref (identifier);
+ g_object_unref (function);
+
+ return STATUS_OK;
+}
+
+static ParseStatus
+parse_function_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
+{
+ ParseStatus status;
+ ViviCodeValue *identifier;
+
+ *statement = NULL;
+
+ status = parse_function_definition (data, value, &identifier, FALSE);
+ if (status != STATUS_OK)
+ return status;
+
+ if (identifier != NULL) {
+ *statement = vivi_compiler_assignment_new (identifier, *value);
+ g_object_unref (identifier);
+ }
+
+ return STATUS_OK;
+}
+
// top
static ParseStatus
@@ -1387,6 +1530,52 @@ parse_statement_list (ParseData *data, ParseStatementFunction function,
}
static ParseStatus
+parse_value_statement_list (ParseData *data,
+ ParseValueStatementFunction function, ViviCodeValue ***list,
+ ViviCodeStatement **statement, guint separator)
+{
+ GPtrArray *array;
+ ViviCodeValue *value;
+ ViviCodeStatement *statement_one;
+ ParseStatus status;
+
+ g_assert (data != NULL);
+ g_assert (function != NULL);
+ g_assert (list != NULL);
+ g_assert (statement != NULL);
+
+ *list = NULL;
+ *statement = NULL;
+
+ status = function (data, &value, statement);
+ if (status != STATUS_OK)
+ return status;
+
+ array = g_ptr_array_new ();
+
+ do {
+ g_ptr_array_add (array, value);
+
+ if (separator != TOKEN_NONE && !check_token (data, separator))
+ break;
+
+ status = function (data, &value, &statement_one);
+ if (status != STATUS_OK) {
+ if (status == STATUS_FAIL || separator != TOKEN_NONE)
+ return FAIL_CHILD (status);
+ } else {
+ *statement =
+ vivi_compiler_combine_statements (2, *statement, statement_one);
+ }
+ } while (status == STATUS_OK);
+ g_ptr_array_add (array, NULL);
+
+ *list = (ViviCodeValue **)g_ptr_array_free (array, FALSE);
+
+ return STATUS_OK;
+}
+
+static ParseStatus
parse_value_list (ParseData *data, ParseValueFunction function,
ViviCodeValue ***list, guint separator)
{
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 8a35437..dcedc9d 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -159,6 +159,7 @@ static const struct {
{ TOKEN_TYPEOF, "typeof" },
{ TOKEN_VAR, "var" },
{ TOKEN_VOID, "void" },
+ { TOKEN_WHILE, "while" },
{ TOKEN_WITH, "with" },
// reserved keywords
@@ -196,6 +197,8 @@ vivi_compiler_scanner_advance (ViviCompilerScanner *scanner)
scanner->next_token = yylex ();
scanner->next_value = yylval;
}
+
+ g_print (":: %s\n", vivi_compiler_scanner_token_name (scanner->next_token));
}
ViviCompilerScanner *
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index cfd1453..c5c72f5 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -133,6 +133,7 @@ typedef enum {
TOKEN_TYPEOF,
TOKEN_VAR,
TOKEN_VOID,
+ TOKEN_WHILE,
TOKEN_WITH,
// reserved keywords
diff --git a/vivified/code/vivi_compiler_scanner_lex.l b/vivified/code/vivi_compiler_scanner_lex.l
index 5585d7e..5dc0a1c 100644
--- a/vivified/code/vivi_compiler_scanner_lex.l
+++ b/vivified/code/vivi_compiler_scanner_lex.l
@@ -2,15 +2,19 @@
#include "vivi_compiler_scanner_lex_include.h"
%}
+%option noyywrap
+
digit [0-9]
identifier_start [$_a-zA-Z]
identifier_part [$_a-zA-Z0-9]
+line_terminator [\n\r]
/* r'([1-9][0-9]*|0)(\.[0-9]*)?([eE][+-][0-9]+)? */
/* '\.[0-9]+([eE][+-][0-9]+)?' */
%%
+"//".*{line_terminator} /* skip single line comments */
[ \t\n\r] /* skip whitespace */
<<EOF>> { return TOKEN_EOF; }
@@ -102,6 +106,7 @@ identifier_part [$_a-zA-Z0-9]
"typeof" { return TOKEN_TYPEOF; }
"var" { return TOKEN_VAR; }
"void" { return TOKEN_VOID; }
+"while" { return TOKEN_WHILE; }
"with" { return TOKEN_WITH; }
"abstract" { return TOKEN_FUTURE; }
@@ -138,13 +143,13 @@ identifier_part [$_a-zA-Z0-9]
{digit}+ { yylval.v_number = atoi(yytext);
return TOKEN_NUMBER; }
+"\"".*"\"" { yylval.v_string = g_strndup (yytext + 1, yyleng - 2);
+ return TOKEN_STRING; }
{identifier_start}({identifier_part})* {
- yylval.v_identifier = (char *)strdup(yytext);
+ yylval.v_identifier = g_strdup (yytext);
return TOKEN_IDENTIFIER; }
. { printf("Unknown character [%c]\n",yytext[0]);
return TOKEN_UNKNOWN; }
%%
-
-int yywrap(void){return 1;}
commit fc1d36fee8e4904e1236f636f3249eea88e5bf67
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 23:33:53 2008 +0300
Just some whitespace fixes to vivi_compiler.c
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index c71436c..266b3c7 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -48,7 +48,6 @@
#include "vivi_compiler_empty_statement.h"
#include "vivi_compiler_get_temporary.h"
-
#include "vivi_code_text_printer.h"
enum {
@@ -88,12 +87,13 @@ typedef struct {
#define CANCEL(x) (data->expected = (x), STATUS_CANCEL)
#define CANCEL_CUSTOM(x) (data->custom_error = (x), STATUS_CANCEL)
-typedef int (*ParseValueFunction) (ParseData *data, ViviCodeValue **value);
-typedef int (*ParseValueStatementFunction) (ParseData *data, ViviCodeValue **value, ViviCodeStatement **statement);
-typedef int (*ParseStatementFunction) (ParseData *data, ViviCodeStatement **statement);
+typedef ParseStatus (*ParseValueFunction) (ParseData *data, ViviCodeValue **value);
+typedef ParseStatus (*ParseValueStatementFunction) (ParseData *data, ViviCodeValue **value, ViviCodeStatement **statement);
+typedef ParseStatus (*ParseStatementFunction) (ParseData *data, ViviCodeStatement **statement);
static ParseStatus
parse_statement_list (ParseData *data, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
+
static ParseStatus
parse_value_list (ParseData *data, ParseValueFunction function,
ViviCodeValue ***list, guint separator);
@@ -314,8 +314,8 @@ parse_property_name (ParseData *data, ViviCodeValue **value)
}
static ParseStatus
-parse_assignment_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement);
+parse_assignment_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement);
static ParseStatus
parse_object_literal (ParseData *data, ViviCodeValue **value,
@@ -393,8 +393,7 @@ parse_object_literal (ParseData *data, ViviCodeValue **value,
// misc
static ParseStatus
-parse_variable_declaration (ParseData *data,
- ViviCodeStatement **statement)
+parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
{
ParseStatus status;
ViviCodeValue *identifier, *value;
@@ -429,7 +428,8 @@ parse_variable_declaration (ParseData *data,
// expression
static ParseStatus
-parse_expression (ParseData *data, ViviCodeValue **value, ViviCodeStatement **statement);
+parse_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement);
static ParseStatus
parse_primary_expression (ParseData *data, ViviCodeValue **value,
@@ -691,10 +691,9 @@ typedef enum {
} ParseOperatorPass;
static ParseStatus
-parse_operator_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement,
- const ViviCompilerScannerToken *tokens, ParseOperatorPass pass,
- ParseValueStatementFunction next_parse_function)
+parse_operator_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement, const ViviCompilerScannerToken *tokens,
+ ParseOperatorPass pass, ParseValueStatementFunction next_parse_function)
{
ParseStatus status;
int i;
@@ -756,8 +755,8 @@ parse_operator_expression (ParseData *data,
}
static ParseStatus
-parse_multiplicative_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_multiplicative_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_MULTIPLY,
TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
@@ -767,8 +766,8 @@ parse_multiplicative_expression (ParseData *data,
}
static ParseStatus
-parse_additive_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_additive_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_PLUS, TOKEN_MINUS,
TOKEN_NONE };
@@ -789,8 +788,8 @@ parse_shift_expression (ParseData *data, ViviCodeValue **value,
}
static ParseStatus
-parse_relational_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_relational_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LESS_THAN,
TOKEN_GREATER_THAN, /*TOKEN_LESS_THAN_OR_EQUAL,
@@ -801,8 +800,8 @@ parse_relational_expression (ParseData *data,
}
static ParseStatus
-parse_equality_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_equality_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_EQUAL,
/*TOKEN_NOT_EQUAL,*/ TOKEN_STRICT_EQUAL, /*TOKEN_NOT_STRICT_EQUAL,*/
@@ -813,8 +812,8 @@ parse_equality_expression (ParseData *data,
}
static ParseStatus
-parse_bitwise_and_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_bitwise_and_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_AND,
TOKEN_NONE };
@@ -824,8 +823,8 @@ parse_bitwise_and_expression (ParseData *data,
}
static ParseStatus
-parse_bitwise_xor_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_bitwise_xor_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_XOR,
TOKEN_NONE };
@@ -835,8 +834,8 @@ parse_bitwise_xor_expression (ParseData *data,
}
static ParseStatus
-parse_bitwise_or_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_bitwise_or_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_OR,
TOKEN_NONE };
@@ -846,8 +845,8 @@ parse_bitwise_or_expression (ParseData *data,
}
static ParseStatus
-parse_logical_and_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_logical_and_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_AND,
TOKEN_NONE };
@@ -857,8 +856,8 @@ parse_logical_and_expression (ParseData *data,
}
static ParseStatus
-parse_logical_or_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_logical_or_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_OR,
TOKEN_NONE };
@@ -868,8 +867,8 @@ parse_logical_or_expression (ParseData *data,
}
static ParseStatus
-parse_conditional_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_conditional_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
ParseStatus status;
//ViviCodeStatement *if_statement, *else_statement;
@@ -919,8 +918,8 @@ parse_conditional_expression (ParseData *data,
}
static ParseStatus
-parse_assignment_expression (ParseData *data,
- ViviCodeValue **value, ViviCodeStatement **statement)
+parse_assignment_expression (ParseData *data, ViviCodeValue **value,
+ ViviCodeStatement **statement)
{
ParseStatus status;
ViviCodeValue *right;
@@ -1034,8 +1033,7 @@ static ParseStatus
parse_statement (ParseData *data, ViviCodeStatement **statement);
static ParseStatus
-parse_if_statement (ParseData *data,
- ViviCodeStatement **statement)
+parse_if_statement (ParseData *data, ViviCodeStatement **statement)
{
ParseStatus status;
ViviCodeValue *condition;
@@ -1139,8 +1137,7 @@ parse_expression_statement (ParseData *data, ViviCodeStatement **statement)
}
static ParseStatus
-parse_empty_statement (ParseData *data,
- ViviCodeStatement **statement)
+parse_empty_statement (ParseData *data, ViviCodeStatement **statement)
{
*statement = NULL;
@@ -1191,8 +1188,8 @@ parse_variable_statement (ParseData *data, ViviCodeStatement **statement)
if (!check_token (data, TOKEN_VAR))
return CANCEL (TOKEN_VAR);
- status = parse_statement_list (data, parse_variable_declaration,
- statement, TOKEN_COMMA);
+ status = parse_statement_list (data, parse_variable_declaration, statement,
+ TOKEN_COMMA);
if (status != STATUS_OK)
return FAIL (status);
@@ -1270,8 +1267,7 @@ parse_function_declaration (ParseData *data, ViviCodeStatement **statement)
return FAIL (TOKEN_PARENTHESIS_LEFT);
}
- status =
- parse_value_list (data, parse_identifier, &arguments, TOKEN_COMMA);
+ status = parse_value_list (data, parse_identifier, &arguments, TOKEN_COMMA);
if (status == STATUS_FAIL)
return status;
@@ -1287,8 +1283,7 @@ parse_function_declaration (ParseData *data, ViviCodeStatement **statement)
return FAIL (TOKEN_BRACE_LEFT);
}
- status = parse_statement_list (data, parse_source_element, &body,
- STATUS_OK);
+ status = parse_statement_list (data, parse_source_element, &body, STATUS_OK);
if (status == STATUS_FAIL) {
g_object_unref (identifier);
free_value_list (arguments);
@@ -1337,8 +1332,8 @@ parse_program (ParseData *data, ViviCodeStatement **statement)
*statement = NULL;
- status = parse_statement_list (data, parse_source_element, statement,
- STATUS_OK);
+ status =
+ parse_statement_list (data, parse_source_element, statement, STATUS_OK);
if (status != STATUS_OK)
return FAIL_CHILD (status);
@@ -1355,9 +1350,8 @@ parse_program (ParseData *data, ViviCodeStatement **statement)
// parsing
static ParseStatus
-parse_statement_list (ParseData *data,
- ParseStatementFunction function, ViviCodeStatement **block,
- guint separator)
+parse_statement_list (ParseData *data, ParseStatementFunction function,
+ ViviCodeStatement **block, guint separator)
{
ViviCodeStatement *statement;
ParseStatus status;
commit 397b78c64e404af861dbb317efecce3040fae66e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 23:26:08 2008 +0300
Oops, fix parsing of multiple same level operators
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 04582f8..c71436c 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -709,7 +709,7 @@ parse_operator_expression (ParseData *data,
return status;
for (i = 0; tokens[i] != STATUS_OK; i++) {
- if (check_token (data, tokens[i])) {
+ while (check_token (data, tokens[i])) {
status = next_parse_function (data, &right, &statement_right);
if (status != STATUS_OK) {
g_object_unref (*value);
commit 841b25656ac1d507a0d988e3a7d8555a592fda63
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 23:20:55 2008 +0300
Fix an error in expression parsing
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 2075ce1..04582f8 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -1007,7 +1007,7 @@ parse_expression (ParseData *data, ViviCodeValue **value,
if (status != STATUS_OK)
return status;
- do {
+ while (TRUE) {
*statement =
vivi_compiler_combine_statements (2, *statement, statement_one);
@@ -1016,14 +1016,14 @@ parse_expression (ParseData *data, ViviCodeValue **value,
statement_one = NULL;
status = parse_assignment_expression (data, value, &statement_one);
- if (status == STATUS_FAIL) {
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
g_object_unref (*statement);
*statement = NULL;
- return status;
+ return FAIL_CHILD (status);
}
- } while (status == STATUS_OK);
+ }
return STATUS_OK;
}
commit 60345df480f0ca6a256133dd93bee30614a3e44a
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 23:10:24 2008 +0300
Compiler: Redo the error handling
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index d4c5aad..2075ce1 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -60,7 +60,7 @@ enum {
};
static const struct {
- int token;
+ guint token;
const char * name;
} error_names[] = {
{ ERROR_TOKEN_LITERAL, "LITERAL" },
@@ -71,27 +71,42 @@ static const struct {
{ TOKEN_LAST, NULL }
};
-#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);
-
-static int
-parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
-static int
-parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
+typedef enum {
+ STATUS_CANCEL = -1,
+ STATUS_OK = 0,
+ STATUS_FAIL = 1
+} ParseStatus;
+
+typedef struct {
+ ViviCompilerScanner * scanner;
+ guint expected;
+ const char * custom_error;
+} ParseData;
+
+#define FAIL(x) (data->expected = (x), STATUS_FAIL)
+#define FAIL_CHILD(x) STATUS_FAIL
+#define CANCEL(x) (data->expected = (x), STATUS_CANCEL)
+#define CANCEL_CUSTOM(x) (data->custom_error = (x), STATUS_CANCEL)
+
+typedef int (*ParseValueFunction) (ParseData *data, ViviCodeValue **value);
+typedef int (*ParseValueStatementFunction) (ParseData *data, ViviCodeValue **value, ViviCodeStatement **statement);
+typedef int (*ParseStatementFunction) (ParseData *data, ViviCodeStatement **statement);
+
+static ParseStatus
+parse_statement_list (ParseData *data, ParseStatementFunction function, ViviCodeStatement **statement, guint separator);
+static ParseStatus
+parse_value_list (ParseData *data, ParseValueFunction function,
ViviCodeValue ***list, guint separator);
// helpers
static gboolean
-check_token (ViviCompilerScanner *scanner, ViviCompilerScannerToken token)
+check_token (ParseData *data, ViviCompilerScannerToken token)
{
- vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token != token)
+ vivi_compiler_scanner_peek_next_token (data->scanner);
+ if (data->scanner->next_token != token)
return FALSE;
- vivi_compiler_scanner_get_next_token (scanner);
+ vivi_compiler_scanner_get_next_token (data->scanner);
return TRUE;
}
@@ -190,58 +205,59 @@ vivi_compiler_get_new (ViviCodeValue *from, ViviCodeValue *name)
// values
-static int
-parse_null_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_null_literal (ParseData *data, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, TOKEN_NULL))
- return -TOKEN_NULL;
+ if (!check_token (data, TOKEN_NULL))
+ return CANCEL (TOKEN_NULL);
*value = vivi_code_constant_new_null ();
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_boolean_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_boolean_literal (ParseData *data, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, TOKEN_BOOLEAN))
- return -TOKEN_BOOLEAN;
+ if (!check_token (data, TOKEN_BOOLEAN))
+ return CANCEL (TOKEN_BOOLEAN);
- *value = vivi_code_constant_new_boolean (scanner->value.v_boolean);
- return TOKEN_NONE;
+ *value = vivi_code_constant_new_boolean (data->scanner->value.v_boolean);
+ return STATUS_OK;
}
-static int
-parse_numeric_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_numeric_literal (ParseData *data, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, TOKEN_NUMBER))
- return -TOKEN_NUMBER;
+ if (!check_token (data, TOKEN_NUMBER))
+ return CANCEL (TOKEN_NUMBER);
- *value = vivi_code_constant_new_number (scanner->value.v_number);
- return TOKEN_NONE;
+ *value = vivi_code_constant_new_number (data->scanner->value.v_number);
+ return STATUS_OK;
}
-static int
-parse_string_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_string_literal (ParseData *data, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, TOKEN_STRING))
- return -TOKEN_STRING;
+ if (!check_token (data, TOKEN_STRING))
+ return CANCEL (TOKEN_STRING);
- *value = vivi_code_constant_new_string (scanner->value.v_string);
- return TOKEN_NONE;
+ *value = vivi_code_constant_new_string (data->scanner->value.v_string);
+ return STATUS_OK;
}
-static int
-parse_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_literal (ParseData *data, ViviCodeValue **value)
{
- int i, expected;
+ ParseStatus status;
+ int i;
ParseValueFunction functions[] = {
parse_null_literal,
parse_boolean_literal,
@@ -253,31 +269,32 @@ parse_literal (ViviCompilerScanner *scanner, ViviCodeValue **value)
*value = NULL;
for (i = 0; functions[i] != NULL; i++) {
- expected = functions[i] (scanner, value);
- if (expected >= 0)
- return expected;
+ status = functions[i] (data, value);
+ if (status != STATUS_CANCEL)
+ return status;
}
- return -ERROR_TOKEN_LITERAL;
+ return CANCEL (ERROR_TOKEN_LITERAL);
}
-static int
-parse_identifier (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_identifier (ParseData *data, ViviCodeValue **value)
{
*value = NULL;
- if (!check_token (scanner, TOKEN_IDENTIFIER))
- return -TOKEN_IDENTIFIER;
+ if (!check_token (data, TOKEN_IDENTIFIER))
+ return CANCEL (TOKEN_IDENTIFIER);
- *value = vivi_code_get_new_name (scanner->value.v_identifier);
+ *value = vivi_code_get_new_name (data->scanner->value.v_identifier);
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
+static ParseStatus
+parse_property_name (ParseData *data, ViviCodeValue **value)
{
- int i, expected;
+ ParseStatus status;
+ int i;
ParseValueFunction functions[] = {
parse_identifier,
parse_string_literal,
@@ -288,68 +305,68 @@ parse_property_name (ViviCompilerScanner *scanner, ViviCodeValue **value)
*value = NULL;
for (i = 0; functions[i] != NULL; i++) {
- expected = functions[i] (scanner, value);
- if (expected >= 0)
- return expected;
+ status = functions[i] (data, value);
+ if (status != STATUS_CANCEL)
+ return status;
}
- return -ERROR_TOKEN_PROPERTY_NAME;
+ return CANCEL (ERROR_TOKEN_PROPERTY_NAME);
}
-static int
-parse_assignment_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_assignment_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement);
-static int
-parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_object_literal (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*value = NULL;
*statement = NULL;
- if (!check_token (scanner, TOKEN_BRACE_LEFT))
- return -TOKEN_BRACE_LEFT;
+ if (!check_token (data, TOKEN_BRACE_LEFT))
+ return CANCEL (TOKEN_BRACE_LEFT);
*value = vivi_code_init_object_new ();
- if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
+ if (!check_token (data, TOKEN_BRACE_RIGHT)) {
do {
ViviCodeValue *property, *initializer;
ViviCodeStatement *statement_new;
- expected = parse_property_name (scanner, &property);
- if (expected != TOKEN_NONE) {
+ status = parse_property_name (data, &property);
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
- if (!check_token (scanner, TOKEN_COLON)) {
+ if (!check_token (data, TOKEN_COLON)) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return TOKEN_COLON;
+ return FAIL (TOKEN_COLON);
}
- expected = parse_assignment_expression (scanner, &initializer,
+ status = parse_assignment_expression (data, &initializer,
&statement_new);
- if (expected != TOKEN_NONE) {
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
*statement =
@@ -357,43 +374,43 @@ parse_object_literal (ViviCompilerScanner *scanner, ViviCodeValue **value,
vivi_code_init_object_add_variable (VIVI_CODE_INIT_OBJECT (*value),
property, initializer);
- } while (check_token (scanner, TOKEN_COMMA));
+ } while (check_token (data, TOKEN_COMMA));
}
- if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
+ if (!check_token (data, TOKEN_BRACE_RIGHT)) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return TOKEN_BRACE_RIGHT;
+ return FAIL (TOKEN_BRACE_RIGHT);
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
// misc
-static int
-parse_variable_declaration (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_variable_declaration (ParseData *data,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *identifier, *value;
ViviCodeStatement *assignment, *statement_right;
*statement = NULL;
- expected = parse_identifier (scanner, &identifier);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_identifier (data, &identifier);
+ if (status != STATUS_OK)
+ return status;
- if (check_token (scanner, TOKEN_ASSIGN)) {
- expected = parse_assignment_expression (scanner, &value, &statement_right);
- if (expected != TOKEN_NONE) {
+ if (check_token (data, TOKEN_ASSIGN)) {
+ status = parse_assignment_expression (data, &value, &statement_right);
+ if (status != STATUS_OK) {
g_object_unref (identifier);
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
} else {
value = vivi_code_constant_new_undefined ();
@@ -406,19 +423,20 @@ parse_variable_declaration (ViviCompilerScanner *scanner,
*statement =
vivi_compiler_combine_statements (2, statement_right, assignment);
- return TOKEN_NONE;
+ return STATUS_OK;
}
// expression
-static int
-parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **statement);
+static ParseStatus
+parse_expression (ParseData *data, ViviCodeValue **value, ViviCodeStatement **statement);
-static int
-parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_primary_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int i, expected;
+ ParseStatus status;
+ int i;
ParseValueFunction functions[] = {
parse_identifier,
parse_literal,
@@ -429,42 +447,42 @@ parse_primary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
*value = NULL;
*statement = NULL;
- if (check_token (scanner, TOKEN_THIS)) {
+ if (check_token (data, TOKEN_THIS)) {
*value = vivi_code_get_new_name ("this");
- return TOKEN_NONE;
+ return STATUS_OK;
}
- if (check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
- expected = parse_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
- if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
+ if (check_token (data, TOKEN_PARENTHESIS_LEFT)) {
+ status = parse_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
g_object_unref (*value);
*value = NULL;
- return TOKEN_PARENTHESIS_RIGHT;
+ return FAIL (TOKEN_PARENTHESIS_RIGHT);
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
- expected = parse_object_literal (scanner, value, statement);
- if (expected == TOKEN_NONE || expected >= 0)
- return expected;
+ status = parse_object_literal (data, value, statement);
+ if (status != STATUS_CANCEL)
+ return status;
for (i = 0; functions[i] != NULL; i++) {
- expected = functions[i] (scanner, value);
- if (expected >= 0)
- return expected;
+ status = functions[i] (data, value);
+ if (status != STATUS_CANCEL)
+ return status;
}
- return -ERROR_TOKEN_PRIMARY_EXPRESSION;
+ return CANCEL (ERROR_TOKEN_PRIMARY_EXPRESSION);
}
-static int
-parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_member_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *member;
ViviCodeStatement *statement_member;
@@ -473,46 +491,46 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
// TODO: new MemberExpression Arguments
- expected = parse_primary_expression (scanner, value, statement);
- //if (expected == STATUS_CANCEL)
- // expected = parse_function_expression (scanner, value);
+ status = parse_primary_expression (data, value, statement);
+ //if (status == STATUS_CANCEL)
+ // status = parse_function_expression (data, value);
- if (expected != TOKEN_NONE)
- return expected;
+ if (status != STATUS_OK)
+ return status;
do {
ViviCodeValue *tmp;
- if (check_token (scanner, TOKEN_BRACKET_LEFT)) {
- expected = parse_expression (scanner, &member, &statement_member);
- if (expected != TOKEN_NONE) {
+ if (check_token (data, TOKEN_BRACKET_LEFT)) {
+ status = parse_expression (data, &member, &statement_member);
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
*statement = vivi_compiler_combine_statements (2, *statement,
statement_member);
- if (!check_token (scanner, TOKEN_BRACKET_RIGHT)) {
+ if (!check_token (data, TOKEN_BRACKET_RIGHT)) {
g_object_unref (*value);
*value = NULL;
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return TOKEN_BRACKET_RIGHT;
+ return FAIL (TOKEN_BRACKET_RIGHT);
}
- } else if (check_token (scanner, TOKEN_DOT)) {
- expected = parse_identifier (scanner, &member);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ } else if (check_token (data, TOKEN_DOT)) {
+ status = parse_identifier (data, &member);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
} else {
- return TOKEN_NONE;
+ return STATUS_OK;
}
tmp = *value;
@@ -524,19 +542,19 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
g_assert_not_reached ();
}
-static int
-parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_new_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*value = NULL;
*statement = NULL;
- if (check_token (scanner, TOKEN_NEW)) {
- expected = parse_new_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ if (check_token (data, TOKEN_NEW)) {
+ status = parse_new_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
if (!VIVI_IS_CODE_FUNCTION_CALL (*value)) {
ViviCodeValue *tmp = VIVI_CODE_VALUE (*value);
*value = vivi_code_function_call_new (NULL, tmp);
@@ -544,56 +562,54 @@ parse_new_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
}
vivi_code_function_call_set_construct (VIVI_CODE_FUNCTION_CALL (*value),
TRUE);
- return TOKEN_NONE;
+ return STATUS_OK;
} else {
- return parse_member_expression (scanner, value, statement);
+ return parse_member_expression (data, value, statement);
}
}
-static int
-parse_left_hand_side_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_left_hand_side_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*value = NULL;
- expected = parse_new_expression (scanner, value, statement);
- //if (expected == STATUS_CANCEL)
- // expected = parse_call_expression (scanner, value);
+ status = parse_new_expression (data, value, statement);
+ //if (status == STATUS_CANCEL)
+ // status = parse_call_expression (data, value);
- return expected;
+ return status;
}
-static int
-parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_postfix_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *operation, *one, *temporary;
const char *operator;
*value = NULL;
*statement = NULL;
- expected = parse_left_hand_side_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_left_hand_side_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return status;
// FIXME: Don't allow new line here
- if (check_token (scanner, TOKEN_INCREASE)) {
+ if (check_token (data, TOKEN_INCREASE)) {
operator = "+";
- } else if (check_token (scanner, TOKEN_DESCREASE)) {
+ } else if (check_token (data, TOKEN_DESCREASE)) {
operator = "-";
} else {
- return TOKEN_NONE;
+ return STATUS_OK;
}
- if (!VIVI_IS_CODE_GET (*value)) {
- g_printerr ("Invalid INCREASE/DECREASE\n");
- return -scanner->token;
- }
+ if (!VIVI_IS_CODE_GET (*value))
+ return CANCEL_CUSTOM ("INCREASE/DECREASE not allowed here");
one = vivi_code_constant_new_number (1);
operation = vivi_code_binary_new_name (*value, one, operator);
@@ -608,14 +624,14 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
g_object_unref (*value);
*value = temporary;
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_unary_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *tmp, *one;
const char *operator;
@@ -623,8 +639,8 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
operator = NULL;
- vivi_compiler_scanner_peek_next_token (scanner);
- switch ((int)scanner->next_token) {
+ vivi_compiler_scanner_peek_next_token (data->scanner);
+ switch ((guint)data->scanner->next_token) {
/*case TOKEN_DELETE:
case TOKEN_VOID:
case TOKEN_TYPEOF:*/
@@ -634,15 +650,13 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
case TOKEN_DESCREASE:
if (!operator) operator = "-";
- vivi_compiler_scanner_get_next_token (scanner);
- expected = parse_unary_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ vivi_compiler_scanner_get_next_token (data->scanner);
+ status = parse_unary_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
- if (!VIVI_IS_CODE_GET (*value)) {
- g_printerr ("Invalid INCREASE/DECREASE\n");
- return -scanner->token;
- }
+ if (!VIVI_IS_CODE_GET (*value))
+ return CANCEL_CUSTOM ("INCREASE/DECREASE not allowed here");
one = vivi_code_constant_new_number (1);
tmp = vivi_code_binary_new_name (*value, one, operator);
@@ -652,21 +666,21 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
vivi_compiler_assignment_new (*value, tmp));
g_object_unref (tmp);
- return TOKEN_NONE;
+ return STATUS_OK;
/*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, statement);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ vivi_compiler_scanner_get_next_token (data->scanner);
+ status = parse_unary_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
tmp = VIVI_CODE_VALUE (*value);
*value = vivi_code_unary_new (tmp, '!');
g_object_unref (tmp);
- return TOKEN_NONE;
+ return STATUS_OK;
default:
- return parse_postfix_expression (scanner, value, statement);
+ return parse_postfix_expression (data, value, statement);
}
}
@@ -676,30 +690,31 @@ typedef enum {
PASS_LOGICAL_AND
} ParseOperatorPass;
-static int
-parse_operator_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_operator_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement,
const ViviCompilerScannerToken *tokens, ParseOperatorPass pass,
ParseValueStatementFunction next_parse_function)
{
- int expected, i;
+ ParseStatus status;
+ int i;
ViviCodeValue *left, *right;
ViviCodeStatement *statement_right;
*value = NULL;
*statement = NULL;
- expected = next_parse_function (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = next_parse_function (data, value, statement);
+ if (status != STATUS_OK)
+ return status;
- for (i = 0; tokens[i] != TOKEN_NONE; i++) {
- if (check_token (scanner, tokens[i])) {
- expected = next_parse_function (scanner, &right, &statement_right);
- if (expected != TOKEN_NONE) {
+ for (i = 0; tokens[i] != STATUS_OK; i++) {
+ if (check_token (data, tokens[i])) {
+ status = next_parse_function (data, &right, &statement_right);
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
if (statement_right != NULL) {
@@ -737,158 +752,158 @@ parse_operator_expression (ViviCompilerScanner *scanner,
};
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_multiplicative_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_multiplicative_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_MULTIPLY,
TOKEN_DIVIDE, TOKEN_REMAINDER, TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_unary_expression);
}
-static int
-parse_additive_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_additive_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_PLUS, TOKEN_MINUS,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_multiplicative_expression);
}
-static int
-parse_shift_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_shift_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_SHIFT_LEFT,
TOKEN_SHIFT_RIGHT, TOKEN_SHIFT_RIGHT_UNSIGNED, TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_additive_expression);
}
-static int
-parse_relational_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_relational_expression (ParseData *data,
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, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_shift_expression);
}
-static int
-parse_equality_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_equality_expression (ParseData *data,
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, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_relational_expression);
}
-static int
-parse_bitwise_and_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_bitwise_and_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_equality_expression);
}
-static int
-parse_bitwise_xor_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_bitwise_xor_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_XOR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_bitwise_and_expression);
}
-static int
-parse_bitwise_or_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_bitwise_or_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_BITWISE_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_ALWAYS, parse_bitwise_xor_expression);
}
-static int
-parse_logical_and_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_logical_and_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_AND,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_LOGICAL_AND, parse_bitwise_or_expression);
}
-static int
-parse_logical_or_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_logical_or_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
static const ViviCompilerScannerToken tokens[] = { TOKEN_LOGICAL_OR,
TOKEN_NONE };
- return parse_operator_expression (scanner, value, statement, tokens,
+ return parse_operator_expression (data, value, statement, tokens,
PASS_LOGICAL_OR, parse_logical_and_expression);
}
-static int
-parse_conditional_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_conditional_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
//ViviCodeStatement *if_statement, *else_statement;
*value = NULL;
- expected = parse_logical_or_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_logical_or_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return status;
#if 0
- if (!check_token (scanner, TOKEN_QUESTION_MARK)) {
+ if (!check_token (data, TOKEN_QUESTION_MARK)) {
*statement = vivi_code_value_statement_new (VIVI_CODE_VALUE (value));
g_object_unref (value);
- return TOKEN_NONE;
+ return STATUS_OK;
}
- expected = parse_assignment_expression (scanner, &if_statement);
- if (expected != TOKEN_NONE) {
+ status = parse_assignment_expression (data, &if_statement);
+ if (status != STATUS_OK) {
g_object_unref (value);
- return FAIL (expected);
+ return FAIL (status);
}
- if (!check_token (scanner, TOKEN_COLON)) {
+ if (!check_token (data, TOKEN_COLON)) {
g_object_unref (value);
g_object_unref (if_statement);
return TOKEN_COLON;
}
- expected = parse_assignment_expression (scanner, &else_statement);
- if (expected != TOKEN_NONE) {
+ status = parse_assignment_expression (data, &else_statement);
+ if (status != STATUS_OK) {
g_object_unref (value);
g_object_unref (if_statement);
- return FAIL (expected);
+ return FAIL (status);
}
*statement = vivi_code_if_new (value);
@@ -900,14 +915,14 @@ parse_conditional_expression (ViviCompilerScanner *scanner,
g_object_unref (else_statement);
#endif
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_assignment_expression (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_assignment_expression (ParseData *data,
ViviCodeValue **value, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *right;
ViviCodeStatement *assignment, *statement_right;
const char *operator;
@@ -915,17 +930,17 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
*value = NULL;
*statement = NULL;
- expected = parse_conditional_expression (scanner, value, statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_conditional_expression (data, value, statement);
+ if (status != STATUS_OK)
+ return status;
if (!VIVI_IS_CODE_GET (*value))
- return TOKEN_NONE;
+ return STATUS_OK;
operator = NULL;
- vivi_compiler_scanner_peek_next_token (scanner);
- switch ((int)scanner->next_token) {
+ vivi_compiler_scanner_peek_next_token (data->scanner);
+ switch ((int)data->scanner->next_token) {
case TOKEN_ASSIGN_MULTIPLY:
if (operator == NULL) operator = "*";
case TOKEN_ASSIGN_DIVIDE:
@@ -949,13 +964,13 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
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,
+ vivi_compiler_scanner_get_next_token (data->scanner);
+ status = parse_assignment_expression (data, &right,
&statement_right);
- if (expected != TOKEN_NONE) {
+ if (status != STATUS_OK) {
g_object_unref (*value);
*value = NULL;
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
if (operator != NULL) {
@@ -971,102 +986,102 @@ parse_assignment_expression (ViviCompilerScanner *scanner,
break;
default:
- return TOKEN_NONE;
+ return STATUS_OK;
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
+static ParseStatus
+parse_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
ViviCodeStatement *statement_one;
- int expected;
+ ParseStatus status;
*statement = NULL;
statement_one = NULL;
- expected = parse_assignment_expression (scanner, value, &statement_one);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_assignment_expression (data, value, &statement_one);
+ if (status != STATUS_OK)
+ return status;
do {
*statement =
vivi_compiler_combine_statements (2, *statement, statement_one);
- if (!check_token (scanner, TOKEN_COMMA))
+ if (!check_token (data, TOKEN_COMMA))
break;
statement_one = NULL;
- expected = parse_assignment_expression (scanner, value, &statement_one);
- if (expected != TOKEN_NONE && expected >= 0) {
+ status = parse_assignment_expression (data, value, &statement_one);
+ if (status == STATUS_FAIL) {
g_object_unref (*value);
*value = NULL;
g_object_unref (*statement);
*statement = NULL;
- return expected;
+ return status;
}
- } while (expected == TOKEN_NONE);
+ } while (status == STATUS_OK);
- return TOKEN_NONE;
+ return STATUS_OK;
}
// statement
-static int
-parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
+static ParseStatus
+parse_statement (ParseData *data, ViviCodeStatement **statement);
-static int
-parse_if_statement (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_if_statement (ParseData *data,
ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *condition;
ViviCodeStatement *pre_statement, *if_statement, *else_statement;
*statement = NULL;
- if (!check_token (scanner, TOKEN_IF))
- return -TOKEN_IF;
+ if (!check_token (data, TOKEN_IF))
+ return CANCEL (TOKEN_IF);
- if (!check_token (scanner, TOKEN_PARENTHESIS_LEFT))
- return TOKEN_PARENTHESIS_LEFT;
+ if (!check_token (data, TOKEN_PARENTHESIS_LEFT))
+ return FAIL (TOKEN_PARENTHESIS_LEFT);
- expected = parse_expression (scanner, &condition, &pre_statement);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ status = parse_expression (data, &condition, &pre_statement);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
- if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
g_object_unref (condition);
if (pre_statement != NULL) {
g_object_unref (pre_statement);
pre_statement = NULL;
}
- return TOKEN_PARENTHESIS_RIGHT;
+ return FAIL (TOKEN_PARENTHESIS_RIGHT);
}
- expected = parse_statement (scanner, &if_statement);
- if (expected != TOKEN_NONE) {
+ status = parse_statement (data, &if_statement);
+ if (status != STATUS_OK) {
g_object_unref (condition);
if (pre_statement != NULL) {
g_object_unref (pre_statement);
pre_statement = NULL;
}
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
- if (check_token (scanner, TOKEN_ELSE)) {
- expected = parse_statement (scanner, &else_statement);
- if (expected != TOKEN_NONE) {
+ if (check_token (data, TOKEN_ELSE)) {
+ status = parse_statement (data, &else_statement);
+ if (status != STATUS_OK) {
g_object_unref (condition);
if (pre_statement != NULL) {
g_object_unref (pre_statement);
pre_statement = NULL;
}
g_object_unref (if_statement);
- return FAIL (expected);
+ return FAIL_CHILD (status);
}
} else {
else_statement = NULL;
@@ -1087,114 +1102,114 @@ parse_if_statement (ViviCompilerScanner *scanner,
g_assert (*statement != NULL);
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_expression_statement (ViviCompilerScanner *scanner,
- ViviCodeStatement **statement)
+static ParseStatus
+parse_expression_statement (ParseData *data, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
ViviCodeValue *value;
*statement = NULL;
- vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token == TOKEN_BRACE_LEFT ||
- scanner->next_token == TOKEN_FUNCTION)
- return -ERROR_TOKEN_EXPRESSION_STATEMENT;
+ vivi_compiler_scanner_peek_next_token (data->scanner);
+ if (data->scanner->next_token == TOKEN_BRACE_LEFT ||
+ data->scanner->next_token == TOKEN_FUNCTION)
+ return CANCEL (ERROR_TOKEN_EXPRESSION_STATEMENT);
- expected = parse_expression (scanner, &value, statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = parse_expression (data, &value, statement);
+ if (status != STATUS_OK)
+ return status;
- if (!check_token (scanner, TOKEN_SEMICOLON)) {
+ if (!check_token (data, TOKEN_SEMICOLON)) {
g_object_unref (value);
if (*statement != NULL) {
g_object_unref (*statement);
*statement = NULL;
}
- return TOKEN_SEMICOLON;
+ return FAIL (TOKEN_SEMICOLON);
}
*statement = vivi_compiler_combine_statements (2, *statement,
vivi_code_value_statement_new (value));
g_object_unref (value);
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_empty_statement (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_empty_statement (ParseData *data,
ViviCodeStatement **statement)
{
*statement = NULL;
- if (!check_token (scanner, TOKEN_SEMICOLON))
- return -TOKEN_SEMICOLON;
+ if (!check_token (data, TOKEN_SEMICOLON))
+ return CANCEL (TOKEN_SEMICOLON);
*statement = vivi_compiler_empty_statement_new ();
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_block (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_block (ParseData *data, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*statement = NULL;
- if (!check_token (scanner, TOKEN_BRACE_LEFT))
- return -TOKEN_BRACE_LEFT;
+ if (!check_token (data, TOKEN_BRACE_LEFT))
+ return CANCEL (TOKEN_BRACE_LEFT);
- vivi_compiler_scanner_peek_next_token (scanner);
- if (scanner->next_token != TOKEN_BRACE_RIGHT) {
- expected =
- parse_statement_list (scanner, parse_statement, statement, TOKEN_NONE);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ vivi_compiler_scanner_peek_next_token (data->scanner);
+ if (data->scanner->next_token != TOKEN_BRACE_RIGHT) {
+ status =
+ parse_statement_list (data, parse_statement, statement, STATUS_OK);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
} else {
*statement = vivi_code_block_new ();
}
- if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
+ if (!check_token (data, TOKEN_BRACE_RIGHT)) {
g_object_unref (*statement);
*statement = NULL;
- return TOKEN_BRACE_RIGHT;
+ return FAIL (TOKEN_BRACE_RIGHT);
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_variable_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_variable_statement (ParseData *data, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*statement = NULL;
- if (!check_token (scanner, TOKEN_VAR))
- return -TOKEN_VAR;
+ if (!check_token (data, TOKEN_VAR))
+ return CANCEL (TOKEN_VAR);
- expected = parse_statement_list (scanner, parse_variable_declaration,
+ status = parse_statement_list (data, parse_variable_declaration,
statement, TOKEN_COMMA);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ if (status != STATUS_OK)
+ return FAIL (status);
- if (!check_token (scanner, TOKEN_SEMICOLON)) {
+ if (!check_token (data, TOKEN_SEMICOLON)) {
g_object_unref (*statement);
*statement = NULL;
- return TOKEN_SEMICOLON;
+ return FAIL (TOKEN_SEMICOLON);
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_statement (ParseData *data, ViviCodeStatement **statement)
{
- int i, expected;
+ ParseStatus status;
+ int i;
ParseStatementFunction functions[] = {
parse_block,
parse_variable_statement,
@@ -1216,29 +1231,26 @@ parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
*statement = NULL;
for (i = 0; functions[i] != NULL; i++) {
- expected = functions[i] (scanner, statement);
- if (expected >= 0) {
- g_assert ((expected == TOKEN_NONE && *statement != NULL) ||
- (expected != TOKEN_NONE && *statement == NULL));
- return expected;
- }
+ status = functions[i] (data, statement);
+ if (status != STATUS_CANCEL)
+ return status;
}
- return -ERROR_TOKEN_STATEMENT;
+ return CANCEL (ERROR_TOKEN_STATEMENT);
}
// function
-static int
-parse_source_element (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
+static ParseStatus
+parse_source_element (ParseData *data, ViviCodeStatement **statement);
-static int
-parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_function_declaration (ParseData *data, ViviCodeStatement **statement)
{
ViviCodeValue *function, *identifier;
ViviCodeValue **arguments;
ViviCodeStatement *body;
- int expected;
+ ParseStatus status;
*statement = NULL;
@@ -1246,48 +1258,48 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
arguments = NULL;
body = NULL;
- if (!check_token (scanner, TOKEN_FUNCTION))
- return -TOKEN_FUNCTION;
+ if (!check_token (data, TOKEN_FUNCTION))
+ return CANCEL (TOKEN_FUNCTION);
- expected = parse_identifier (scanner, &identifier);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ status = parse_identifier (data, &identifier);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
- if (!check_token (scanner, TOKEN_PARENTHESIS_LEFT)) {
+ if (!check_token (data, TOKEN_PARENTHESIS_LEFT)) {
g_object_unref (identifier);
- return TOKEN_PARENTHESIS_LEFT;
+ return FAIL (TOKEN_PARENTHESIS_LEFT);
}
- expected =
- parse_value_list (scanner, parse_identifier, &arguments, TOKEN_COMMA);
- if (expected != TOKEN_NONE && expected >= 0)
- return expected;
+ status =
+ parse_value_list (data, parse_identifier, &arguments, TOKEN_COMMA);
+ if (status == STATUS_FAIL)
+ return status;
- if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
+ if (!check_token (data, TOKEN_PARENTHESIS_RIGHT)) {
g_object_unref (identifier);
free_value_list (arguments);
- return TOKEN_PARENTHESIS_RIGHT;
+ return FAIL (TOKEN_PARENTHESIS_RIGHT);
}
- if (!check_token (scanner, TOKEN_BRACE_LEFT)) {
+ if (!check_token (data, TOKEN_BRACE_LEFT)) {
g_object_unref (identifier);
free_value_list (arguments);
- return TOKEN_BRACE_LEFT;
+ return FAIL (TOKEN_BRACE_LEFT);
}
- expected = parse_statement_list (scanner, parse_source_element, &body,
- TOKEN_NONE);
- if (expected != TOKEN_NONE && expected >= 0) {
+ status = parse_statement_list (data, parse_source_element, &body,
+ STATUS_OK);
+ if (status == STATUS_FAIL) {
g_object_unref (identifier);
free_value_list (arguments);
- return expected;
+ return status;
}
- if (!check_token (scanner, TOKEN_BRACE_RIGHT)) {
+ if (!check_token (data, TOKEN_BRACE_RIGHT)) {
g_object_unref (identifier);
free_value_list (arguments);
g_object_unref (body);
- return TOKEN_BRACE_RIGHT;
+ return FAIL (TOKEN_BRACE_RIGHT);
}
function = vivi_code_function_new ();
@@ -1299,64 +1311,66 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
free_value_list (arguments);
g_object_unref (body);
- return TOKEN_NONE;
+ return STATUS_OK;
}
// top
-static int
-parse_source_element (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_source_element (ParseData *data, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*statement = NULL;
- expected = parse_function_declaration (scanner, statement);
- if (expected < 0)
- expected = parse_statement (scanner, statement);
+ status = parse_function_declaration (data, statement);
+ if (status == STATUS_CANCEL)
+ status = parse_statement (data, statement);
- return expected;
+ return status;
}
-static int
-parse_program (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+static ParseStatus
+parse_program (ParseData *data, ViviCodeStatement **statement)
{
- int expected;
+ ParseStatus status;
*statement = NULL;
- expected = parse_statement_list (scanner, parse_source_element, statement,
- TOKEN_NONE);
- if (expected != TOKEN_NONE)
- return FAIL (expected);
+ status = parse_statement_list (data, parse_source_element, statement,
+ STATUS_OK);
+ if (status != STATUS_OK)
+ return FAIL_CHILD (status);
- if (!check_token (scanner, TOKEN_EOF)) {
+ if (!check_token (data, TOKEN_EOF)) {
+ g_object_unref (*statement);
*statement = NULL;
- return FAIL (parse_statement (scanner, statement));
+ status = parse_statement (data, statement);
+ return FAIL_CHILD (status);
}
- return TOKEN_NONE;
+ return STATUS_OK;
}
// parsing
-static int
-parse_statement_list (ViviCompilerScanner *scanner,
+static ParseStatus
+parse_statement_list (ParseData *data,
ParseStatementFunction function, ViviCodeStatement **block,
guint separator)
{
ViviCodeStatement *statement;
- int expected;
+ ParseStatus status;
- g_assert (scanner != NULL);
+ g_assert (data != NULL);
g_assert (function != NULL);
g_assert (block != NULL);
*block = NULL;
- expected = function (scanner, &statement);
- if (expected != TOKEN_NONE)
- return expected;
+ status = function (data, &statement);
+ if (status != STATUS_OK)
+ return status;
*block = vivi_code_block_new ();
@@ -1364,55 +1378,55 @@ parse_statement_list (ViviCompilerScanner *scanner,
vivi_code_block_add_statement (VIVI_CODE_BLOCK (*block), statement);
g_object_unref (statement);
- if (separator != TOKEN_NONE && !check_token (scanner, separator))
+ if (separator != STATUS_OK && !check_token (data, separator))
break;
- expected = function (scanner, &statement);
- if (expected != TOKEN_NONE && expected >= 0) {
+ status = function (data, &statement);
+ if (status == STATUS_FAIL) {
g_object_unref (*block);
*block = NULL;
- return expected;
+ return STATUS_FAIL;
}
- } while (expected == TOKEN_NONE);
+ } while (status == STATUS_OK);
- return TOKEN_NONE;
+ return STATUS_OK;
}
-static int
-parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
+static ParseStatus
+parse_value_list (ParseData *data, ParseValueFunction function,
ViviCodeValue ***list, guint separator)
{
GPtrArray *array;
ViviCodeValue *value;
- int expected;
+ ParseStatus status;
- g_assert (scanner != NULL);
+ g_assert (data != NULL);
g_assert (function != NULL);
g_assert (list != NULL);
*list = NULL;
- expected = function (scanner, &value);
- if (expected != TOKEN_NONE)
- return expected;
+ status = function (data, &value);
+ if (status != STATUS_OK)
+ return status;
array = g_ptr_array_new ();
do {
g_ptr_array_add (array, value);
- if (separator != TOKEN_NONE && !check_token (scanner, separator))
+ if (separator != STATUS_OK && !check_token (data, separator))
break;
- expected = function (scanner, &value);
- if (expected != TOKEN_NONE && expected >= 0)
- return expected;
- } while (expected == TOKEN_NONE);
+ status = function (data, &value);
+ if (status == STATUS_FAIL)
+ return STATUS_FAIL;
+ } while (status == STATUS_OK);
g_ptr_array_add (array, NULL);
*list = (ViviCodeValue **)g_ptr_array_free (array, FALSE);
- return TOKEN_NONE;
+ return STATUS_OK;
}
// public
@@ -1420,30 +1434,34 @@ parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
ViviCodeStatement *
vivi_compile_file (FILE *file, const char *input_name)
{
- ViviCompilerScanner *scanner;
+ ParseData data;
ViviCodeStatement *statement;
- int expected;
+ ParseStatus status;
g_return_val_if_fail (file != NULL, NULL);
- scanner = vivi_compiler_scanner_new (file);
-
- expected = parse_program (scanner, &statement);
- g_assert ((expected == TOKEN_NONE && VIVI_IS_CODE_STATEMENT (statement)) ||
- (expected != TOKEN_NONE && statement == NULL));
- g_assert (expected >= 0);
-
- if (expected != TOKEN_NONE) {
- vivi_compiler_scanner_get_next_token (scanner);
- if (expected < TOKEN_LAST) {
- vivi_compiler_scanner_unexp_token (scanner, expected);
+ data.scanner = vivi_compiler_scanner_new (file);
+ data.expected = TOKEN_NONE;
+ data.custom_error = NULL;
+
+ status = parse_program (&data, &statement);
+ g_assert ((status == STATUS_OK && VIVI_IS_CODE_STATEMENT (statement)) ||
+ (status != STATUS_OK && statement == NULL));
+ g_assert (status >= 0);
+
+ if (status != STATUS_OK) {
+ vivi_compiler_scanner_get_next_token (data.scanner);
+ if (data.custom_error != NULL) {
+ g_printerr ("%s\n", data.custom_error);
+ } else if (data.expected < TOKEN_LAST) {
+ vivi_compiler_scanner_unexp_token (data.scanner, data.expected);
} else {
guint i;
const char *name;
name = NULL;
for (i = 0; error_names[i].token != TOKEN_LAST; i++) {
- if (error_names[i].token == expected) {
+ if (error_names[i].token == data.expected) {
name = error_names[i].name;
break;
}
@@ -1451,11 +1469,11 @@ vivi_compile_file (FILE *file, const char *input_name)
g_assert (name != NULL);
- vivi_compiler_scanner_unexp_token_string (scanner, name);
+ vivi_compiler_scanner_unexp_token_custom (data.scanner, name);
}
}
- g_object_unref (scanner);
+ g_object_unref (data.scanner);
return statement;
}
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index 55e29b8..8a35437 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -260,7 +260,7 @@ vivi_compiler_scanner_unexp_token (ViviCompilerScanner *scanner,
}
void
-vivi_compiler_scanner_unexp_token_string (ViviCompilerScanner *scanner,
+vivi_compiler_scanner_unexp_token_custom (ViviCompilerScanner *scanner,
const char *expected)
{
vivi_compiler_scanner_print_unexp_token_message (scanner,
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index 02721b4..cfd1453 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -168,6 +168,8 @@ struct _ViviCompilerScanner
ViviCompilerScannerToken next_token;
ViviCompilerScannerValue value;
ViviCompilerScannerValue next_value;
+
+ ViviCompilerScannerToken expected;
};
struct _ViviCompilerScannerClass
@@ -187,7 +189,7 @@ guint vivi_compiler_scanner_cur_line (ViviCompilerScanner *scanner);
void vivi_compiler_scanner_unexp_token (ViviCompilerScanner * scanner,
ViviCompilerScannerToken expected);
-void vivi_compiler_scanner_unexp_token_string (ViviCompilerScanner * scanner,
+void vivi_compiler_scanner_unexp_token_custom (ViviCompilerScanner * scanner,
const char * expected);
commit eb709e112191e9d30e6fcbbbebb723d7408d51a7
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 22:17:47 2008 +0300
Make ViviCodeFunction not save reference to script, only use it in constructor
Also started fixing function declaration parsing
diff --git a/vivified/code/decompiler.c b/vivified/code/decompiler.c
index 296fa25..078a3fb 100644
--- a/vivified/code/decompiler.c
+++ b/vivified/code/decompiler.c
@@ -39,7 +39,7 @@ decode_script (gpointer scriptp, gpointer unused)
ViviCodePrinter *printer;
g_print ("/* %s */\n", script->name);
- fun = vivi_code_function_new (scriptp);
+ fun = vivi_code_function_new_from_script (scriptp);
printer = vivi_code_text_printer_new ();
vivi_code_printer_print_token (printer, VIVI_CODE_TOKEN (fun));
diff --git a/vivified/code/vivi_code_function.c b/vivified/code/vivi_code_function.c
index 94d282e..518f60c 100644
--- a/vivified/code/vivi_code_function.c
+++ b/vivified/code/vivi_code_function.c
@@ -24,6 +24,7 @@
#include <swfdec/swfdec_script_internal.h>
#include "vivi_code_function.h"
+#include "vivi_code_constant.h"
#include "vivi_code_printer.h"
#include "vivi_decompiler.h"
@@ -35,7 +36,6 @@ vivi_code_function_dispose (GObject *object)
{
ViviCodeFunction *function = VIVI_CODE_FUNCTION (object);
- swfdec_script_unref (function->script);
if (function->body)
g_object_unref (function->body);
@@ -49,10 +49,11 @@ vivi_code_function_print (ViviCodeToken *token, ViviCodePrinter*printer)
guint i;
vivi_code_printer_print (printer, "function (");
- for (i = 0; i < function->script->n_arguments; i++) {
+ for (i = 0; i < function->n_arguments; i++) {
if (i != 0)
vivi_code_printer_print (printer, ", ");
- vivi_code_printer_print (printer, function->script->arguments[i].name);
+ vivi_code_printer_print_token (printer,
+ VIVI_CODE_TOKEN (&function->arguments[i]));
}
vivi_code_printer_print (printer, ") {");
vivi_code_printer_new_line (printer, FALSE);
@@ -93,16 +94,49 @@ vivi_code_function_init (ViviCodeFunction *function)
}
ViviCodeValue *
-vivi_code_function_new (SwfdecScript *script)
+vivi_code_function_new (void)
+{
+ return VIVI_CODE_VALUE (g_object_new (VIVI_TYPE_CODE_FUNCTION, NULL));
+}
+
+void
+vivi_code_function_set_body (ViviCodeFunction *function,
+ ViviCodeStatement *body)
+{
+ g_return_if_fail (VIVI_IS_CODE_FUNCTION (function));
+ g_return_if_fail (VIVI_IS_CODE_STATEMENT (body));
+
+ function->body = g_object_ref (body);
+}
+
+void
+vivi_code_function_add_argument (ViviCodeFunction *function,
+ ViviCodeValue *argument)
+{
+ g_return_if_fail (VIVI_IS_CODE_FUNCTION (function));
+ g_return_if_fail (VIVI_IS_CODE_VALUE (argument));
+
+ // TODO
+}
+
+ViviCodeValue *
+vivi_code_function_new_from_script (SwfdecScript *script)
{
ViviCodeFunction *function;
+ guint i;
g_return_val_if_fail (script != NULL, NULL);
function = g_object_new (VIVI_TYPE_CODE_FUNCTION, NULL);
- function->script = swfdec_script_ref (script);
function->body = vivi_decompile_script (script);
+ for (i = 0; i < script->n_arguments; i++) {
+ ViviCodeValue *argument =
+ vivi_code_constant_new_string (script->arguments[i].name);
+ vivi_code_function_add_argument (function, argument);
+ g_object_unref (argument);
+ }
+
return VIVI_CODE_VALUE (function);
}
diff --git a/vivified/code/vivi_code_function.h b/vivified/code/vivi_code_function.h
index 1b33857..00c1dc1 100644
--- a/vivified/code/vivi_code_function.h
+++ b/vivified/code/vivi_code_function.h
@@ -40,7 +40,8 @@ struct _ViviCodeFunction
{
ViviCodeValue value;
- SwfdecScript * script;
+ guint n_arguments; /* number of arguments */
+ ViviCodeValue * arguments; /* arguments or NULL if none */
ViviCodeStatement * body;
};
@@ -51,7 +52,13 @@ struct _ViviCodeFunctionClass
GType vivi_code_function_get_type (void);
-ViviCodeValue * vivi_code_function_new (SwfdecScript * script);
+ViviCodeValue * vivi_code_function_new (void);
+ViviCodeValue * vivi_code_function_new_from_script (SwfdecScript * script);
+
+void vivi_code_function_set_body (ViviCodeFunction * function,
+ ViviCodeStatement * body);
+void vivi_code_function_add_argument (ViviCodeFunction * function,
+ ViviCodeValue * argument);
G_END_DECLS
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 65355ae..d4c5aad 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -1110,8 +1110,10 @@ parse_expression_statement (ViviCompilerScanner *scanner,
if (!check_token (scanner, TOKEN_SEMICOLON)) {
g_object_unref (value);
- g_object_unref (*statement);
- *statement = NULL;
+ if (*statement != NULL) {
+ g_object_unref (*statement);
+ *statement = NULL;
+ }
return TOKEN_SEMICOLON;
}
@@ -1233,8 +1235,7 @@ parse_source_element (ViviCompilerScanner *scanner, ViviCodeStatement **statemen
static int
parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
- //ViviCodeStatement *function;
- ViviCodeValue *identifier;
+ ViviCodeValue *function, *identifier;
ViviCodeValue **arguments;
ViviCodeStatement *body;
int expected;
@@ -1289,10 +1290,10 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
return TOKEN_BRACE_RIGHT;
}
- /*function = vivi_code_function_new (arguments, body);
+ function = vivi_code_function_new ();
+ vivi_code_function_set_body (VIVI_CODE_FUNCTION (function), body);
*statement = vivi_compiler_assignment_new (VIVI_CODE_VALUE (identifier),
- VIVI_CODE_VALUE (function));*/
- *statement = vivi_compiler_empty_statement_new ();
+ VIVI_CODE_VALUE (function));
g_object_unref (identifier);
free_value_list (arguments);
@@ -1389,7 +1390,7 @@ parse_value_list (ViviCompilerScanner *scanner, ParseValueFunction function,
g_assert (function != NULL);
g_assert (list != NULL);
- **list = NULL;
+ *list = NULL;
expected = function (scanner, &value);
if (expected != TOKEN_NONE)
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 1914ef5..d4b5759 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -581,7 +581,7 @@ vivi_decompile_define_function (ViviDecompilerBlock *block, ViviDecompilerState
script->n_arguments = n_args;
script->arguments = args;
- value = vivi_code_function_new (script);
+ value = vivi_code_function_new_from_script (script);
/* attach the function */
if (*function_name == '\0') {
vivi_decompiler_state_push (state, value);
commit aea5fa38f878c218fd50ec2637c2b918e620381c
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 21:53:36 2008 +0300
Fix unary/postfix assignments
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index b3d5535..65355ae 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -400,7 +400,7 @@ parse_variable_declaration (ViviCompilerScanner *scanner,
statement_right = NULL;
}
- assignment = vivi_code_assignment_new (NULL, identifier, value);
+ assignment = vivi_compiler_assignment_new (identifier, value);
vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assignment), TRUE);
*statement =
@@ -601,8 +601,8 @@ parse_postfix_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
temporary = vivi_compiler_get_temporary_new ();
*statement = vivi_compiler_combine_statements (3, *statement,
- vivi_code_assignment_new (NULL, temporary, *value),
- vivi_code_assignment_new (NULL, *value, operation));
+ vivi_compiler_assignment_new (temporary, *value),
+ vivi_compiler_assignment_new (*value, operation));
g_object_unref (operation);
g_object_unref (*value);
@@ -649,7 +649,7 @@ parse_unary_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
g_object_unref (one);
*statement = vivi_compiler_combine_statements (2, *statement,
- vivi_code_assignment_new (NULL, *value, tmp));
+ vivi_compiler_assignment_new (*value, tmp));
g_object_unref (tmp);
return TOKEN_NONE;
@@ -1290,7 +1290,7 @@ parse_function_declaration (ViviCompilerScanner *scanner, ViviCodeStatement **st
}
/*function = vivi_code_function_new (arguments, body);
- *statement = vivi_code_assignment_new (NULL, VIVI_CODE_VALUE (identifier),
+ *statement = vivi_compiler_assignment_new (VIVI_CODE_VALUE (identifier),
VIVI_CODE_VALUE (function));*/
*statement = vivi_compiler_empty_statement_new ();
commit 541d2b7d1cb5ec6637718ee52412340b7ffdffed
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 21:48:24 2008 +0300
Fix parsing of expression statements
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index d6da199..b3d5535 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -1115,6 +1115,10 @@ parse_expression_statement (ViviCompilerScanner *scanner,
return TOKEN_SEMICOLON;
}
+ *statement = vivi_compiler_combine_statements (2, *statement,
+ vivi_code_value_statement_new (value));
+ g_object_unref (value);
+
return TOKEN_NONE;
}
commit f89e3f0b8ee64a3626558385e8adf593f14bd43a
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 21:45:26 2008 +0300
Fix bug when parsing else branch
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 67413ac..d6da199 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -1079,7 +1079,7 @@ parse_if_statement (ViviCompilerScanner *scanner,
g_object_unref (if_statement);
if (else_statement != NULL) {
- vivi_code_if_set_if (VIVI_CODE_IF (*statement), else_statement);
+ vivi_code_if_set_else (VIVI_CODE_IF (*statement), else_statement);
g_object_unref (else_statement);
}
commit 77de59344fc4f0b18e987075060fa58687798ba9
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Thu Apr 3 21:42:35 2008 +0300
Fixes to unexpected token messages. Implement if-statement parsing
diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index 54027c9..67413ac 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -59,7 +59,19 @@ enum {
ERROR_TOKEN_STATEMENT
};
-#define FAIL(x) ((x) < 0 ? -x : x)
+static const struct {
+ int token;
+ const char * name;
+} error_names[] = {
+ { 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" },
+ { TOKEN_LAST, NULL }
+};
+
+#define FAIL(x) ((x) < 0 ? -(x) : (x))
typedef int (*ParseValueFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value);
typedef int (*ParseValueStatementFunction) (ViviCompilerScanner *scanner, ViviCodeValue **value, ViviCodeStatement **statement);
@@ -497,7 +509,6 @@ parse_member_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
}
} 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 {
@@ -1005,6 +1016,81 @@ parse_expression (ViviCompilerScanner *scanner, ViviCodeValue **value,
// statement
static int
+parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
+
+static int
+parse_if_statement (ViviCompilerScanner *scanner,
+ ViviCodeStatement **statement)
+{
+ int expected;
+ ViviCodeValue *condition;
+ ViviCodeStatement *pre_statement, *if_statement, *else_statement;
+
+ *statement = NULL;
+
+ if (!check_token (scanner, TOKEN_IF))
+ return -TOKEN_IF;
+
+ if (!check_token (scanner, TOKEN_PARENTHESIS_LEFT))
+ return TOKEN_PARENTHESIS_LEFT;
+
+ expected = parse_expression (scanner, &condition, &pre_statement);
+ if (expected != TOKEN_NONE)
+ return FAIL (expected);
+
+ if (!check_token (scanner, TOKEN_PARENTHESIS_RIGHT)) {
+ g_object_unref (condition);
+ if (pre_statement != NULL) {
+ g_object_unref (pre_statement);
+ pre_statement = NULL;
+ }
+ return TOKEN_PARENTHESIS_RIGHT;
+ }
+
+ expected = parse_statement (scanner, &if_statement);
+ if (expected != TOKEN_NONE) {
+ g_object_unref (condition);
+ if (pre_statement != NULL) {
+ g_object_unref (pre_statement);
+ pre_statement = NULL;
+ }
+ return FAIL (expected);
+ }
+
+ if (check_token (scanner, TOKEN_ELSE)) {
+ expected = parse_statement (scanner, &else_statement);
+ if (expected != TOKEN_NONE) {
+ g_object_unref (condition);
+ if (pre_statement != NULL) {
+ g_object_unref (pre_statement);
+ pre_statement = NULL;
+ }
+ g_object_unref (if_statement);
+ return FAIL (expected);
+ }
+ } else {
+ else_statement = NULL;
+ }
+
+ *statement = vivi_code_if_new (condition);
+ g_object_unref (condition);
+
+ vivi_code_if_set_if (VIVI_CODE_IF (*statement), if_statement);
+ g_object_unref (if_statement);
+
+ if (else_statement != NULL) {
+ vivi_code_if_set_if (VIVI_CODE_IF (*statement), else_statement);
+ g_object_unref (else_statement);
+ }
+
+ *statement = vivi_compiler_combine_statements (2, pre_statement, *statement);
+
+ g_assert (*statement != NULL);
+
+ return TOKEN_NONE;
+}
+
+static int
parse_expression_statement (ViviCompilerScanner *scanner,
ViviCodeStatement **statement)
{
@@ -1033,7 +1119,8 @@ parse_expression_statement (ViviCompilerScanner *scanner,
}
static int
-parse_empty_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
+parse_empty_statement (ViviCompilerScanner *scanner,
+ ViviCodeStatement **statement)
{
*statement = NULL;
@@ -1046,9 +1133,6 @@ parse_empty_statement (ViviCompilerScanner *scanner, ViviCodeStatement **stateme
}
static int
-parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement);
-
-static int
parse_block (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
{
int expected;
@@ -1110,7 +1194,7 @@ parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
parse_variable_statement,
parse_empty_statement,
parse_expression_statement,
- //parse_if_statement,
+ parse_if_statement,
//parse_iteration_statement,
//parse_continue_statement,
//parse_break_statement,
@@ -1127,8 +1211,11 @@ parse_statement (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
for (i = 0; functions[i] != NULL; i++) {
expected = functions[i] (scanner, statement);
- if (expected >= 0)
+ if (expected >= 0) {
+ g_assert ((expected == TOKEN_NONE && *statement != NULL) ||
+ (expected != TOKEN_NONE && *statement == NULL));
return expected;
+ }
}
return -ERROR_TOKEN_STATEMENT;
@@ -1249,8 +1336,9 @@ parse_program (ViviCompilerScanner *scanner, ViviCodeStatement **statement)
// parsing
static int
-parse_statement_list (ViviCompilerScanner *scanner, ParseStatementFunction function,
- ViviCodeStatement **block, guint separator)
+parse_statement_list (ViviCompilerScanner *scanner,
+ ParseStatementFunction function, ViviCodeStatement **block,
+ guint separator)
{
ViviCodeStatement *statement;
int expected;
@@ -1338,10 +1426,28 @@ vivi_compile_file (FILE *file, const char *input_name)
expected = parse_program (scanner, &statement);
g_assert ((expected == TOKEN_NONE && VIVI_IS_CODE_STATEMENT (statement)) ||
(expected != TOKEN_NONE && statement == NULL));
+ g_assert (expected >= 0);
if (expected != TOKEN_NONE) {
vivi_compiler_scanner_get_next_token (scanner);
- vivi_compiler_scanner_unexp_token (scanner, expected);
+ if (expected < TOKEN_LAST) {
+ vivi_compiler_scanner_unexp_token (scanner, expected);
+ } else {
+ guint i;
+ const char *name;
+
+ name = NULL;
+ for (i = 0; error_names[i].token != TOKEN_LAST; i++) {
+ if (error_names[i].token == expected) {
+ name = error_names[i].name;
+ break;
+ }
+ }
+
+ g_assert (name != NULL);
+
+ vivi_compiler_scanner_unexp_token_string (scanner, name);
+ }
}
g_object_unref (scanner);
diff --git a/vivified/code/vivi_compiler_scanner.c b/vivified/code/vivi_compiler_scanner.c
index a350529..55e29b8 100644
--- a/vivified/code/vivi_compiler_scanner.c
+++ b/vivified/code/vivi_compiler_scanner.c
@@ -242,12 +242,27 @@ vivi_compiler_scanner_cur_line (ViviCompilerScanner *scanner)
return yylineno;
}
+static void
+vivi_compiler_scanner_print_unexp_token_message (ViviCompilerScanner *scanner,
+ const char *unexpected, const char *expected)
+{
+ g_printerr ("%i: Unexpected token %s expected %s\n",
+ vivi_compiler_scanner_cur_line (scanner), unexpected, expected);
+}
+
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_print_unexp_token_message (scanner,
vivi_compiler_scanner_token_name (scanner->token),
vivi_compiler_scanner_token_name (expected));
}
+
+void
+vivi_compiler_scanner_unexp_token_string (ViviCompilerScanner *scanner,
+ const char *expected)
+{
+ vivi_compiler_scanner_print_unexp_token_message (scanner,
+ vivi_compiler_scanner_token_name (scanner->token), expected);
+}
diff --git a/vivified/code/vivi_compiler_scanner.h b/vivified/code/vivi_compiler_scanner.h
index f782a3a..02721b4 100644
--- a/vivified/code/vivi_compiler_scanner.h
+++ b/vivified/code/vivi_compiler_scanner.h
@@ -187,6 +187,8 @@ guint vivi_compiler_scanner_cur_line (ViviCompilerScanner *scanner);
void vivi_compiler_scanner_unexp_token (ViviCompilerScanner * scanner,
ViviCompilerScannerToken expected);
+void vivi_compiler_scanner_unexp_token_string (ViviCompilerScanner * scanner,
+ const char * expected);
G_END_DECLS
More information about the Swfdec-commits
mailing list