[Swfdec-commits] 29 commits - vivified/code

Pekka Lampila medar at kemper.freedesktop.org
Mon May 12 14:16:53 PDT 2008


 vivified/code/Makefile.am                                  |    2 
 vivified/code/compiler.c                                   |   11 
 vivified/code/test/compiler/Makefile.am                    |   32 +
 vivified/code/test/compiler/and.as                         |    1 
 vivified/code/test/compiler/and.as.expect                  |   15 
 vivified/code/test/compiler/array_literal.as               |    1 
 vivified/code/test/compiler/array_literal.as.expect        |    9 
 vivified/code/test/compiler/asm_empty.as                   |    2 
 vivified/code/test/compiler/asm_empty.as.expect            |    3 
 vivified/code/test/compiler/assignment.as                  |    1 
 vivified/code/test/compiler/assignment.as.expect           |    6 
 vivified/code/test/compiler/assignment_operator.as         |   11 
 vivified/code/test/compiler/assignment_operator.as.expect  |   59 ++
 vivified/code/test/compiler/empty_block.as                 |    1 
 vivified/code/test/compiler/empty_block.as.expect          |    3 
 vivified/code/test/compiler/function_declaration.as        |    3 
 vivified/code/test/compiler/function_declaration.as.expect |    7 
 vivified/code/test/compiler/function_expression.as         |    3 
 vivified/code/test/compiler/function_expression.as.expect  |   10 
 vivified/code/test/compiler/if.as                          |    3 
 vivified/code/test/compiler/if.as.expect                   |   11 
 vivified/code/test/compiler/if_else.as                     |    5 
 vivified/code/test/compiler/if_else.as.expect              |   14 
 vivified/code/test/compiler/label.as                       |    1 
 vivified/code/test/compiler/label.as.expect                |    5 
 vivified/code/test/compiler/object_literal.as              |    1 
 vivified/code/test/compiler/object_literal.as.expect       |    7 
 vivified/code/test/compiler/operator.as                    |   20 
 vivified/code/test/compiler/operator.as.expect             |  128 +++++
 vivified/code/test/compiler/or.as                          |    1 
 vivified/code/test/compiler/or.as.expect                   |   14 
 vivified/code/test/compiler/while.as                       |    3 
 vivified/code/test/compiler/while.as.expect                |   14 
 vivified/code/vivi_code_and.c                              |   37 +
 vivified/code/vivi_code_asm.h                              |    3 
 vivified/code/vivi_code_asm_code.c                         |   33 -
 vivified/code/vivi_code_asm_code.h                         |    2 
 vivified/code/vivi_code_assembler.c                        |   24 -
 vivified/code/vivi_code_comment.c                          |    8 
 vivified/code/vivi_code_compiler.c                         |   32 +
 vivified/code/vivi_code_compiler.h                         |    2 
 vivified/code/vivi_code_defaults.h                         |   13 
 vivified/code/vivi_code_function.c                         |   27 -
 vivified/code/vivi_code_function.h                         |    5 
 vivified/code/vivi_code_function_declaration.c             |  165 +++++++
 vivified/code/vivi_code_function_declaration.h             |   64 ++
 vivified/code/vivi_code_if.c                               |   33 -
 vivified/code/vivi_code_init_array.c                       |    4 
 vivified/code/vivi_code_init_object.c                      |    2 
 vivified/code/vivi_code_label.c                            |    8 
 vivified/code/vivi_code_loop.c                             |   43 +
 vivified/code/vivi_code_or.c                               |   33 +
 vivified/code/vivi_code_unary.c                            |    2 
 vivified/code/vivi_parser.c                                |  296 +++++++------
 vivified/code/vivi_parser_scanner_lex.l                    |   43 +
 55 files changed, 1062 insertions(+), 224 deletions(-)

New commits:
commit 09bc865929ff016b07e9e4fa1f282bd3ca0573b5
Merge: 3ff8553... 8bacc28...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue May 13 00:12:02 2008 +0300

    Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec

commit 3ff85531e081cee441042531cb6751375db15f21
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 13:47:21 2008 +0300

    Parse \u escape sequences in the strings

diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index b4a7428..76d6c62 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -279,7 +279,8 @@ identifier_part		[$_a-zA-Z0-9]
 			  if (result > 0xff || result == 0) {
 			    ERROR ("Invalid escape sequence %s", yytext);
 			  } else {
-			    g_string_append_c (value->value.v_string, result);
+			    g_string_append_unichar (value->value.v_string,
+				result);
 			  }
 			}
   \\[0-9]+		{ ERROR ("Invalid escape sequence %s", yytext); }
@@ -289,7 +290,18 @@ identifier_part		[$_a-zA-Z0-9]
 			  if (result == 0) {
 			    ERROR ("Invalid escape sequence %s", yytext);
 			  } else {
-			    g_string_append_c (value->value.v_string, result);
+			    g_string_append_unichar (value->value.v_string,
+				result);
+			  }
+			}
+  \\u[0-9a-fA-F]{4}	{
+			  guint64 result;
+			  result = g_ascii_strtoull (yytext + 2, NULL, 16);
+			  if (result == 0) {
+			    ERROR ("Invalid escape sequence %s", yytext);
+			  } else {
+			    g_print (":: %lu\n", result);
+			    g_string_append_unichar (value->value.v_string, result);
 			  }
 			}
   \\b			{ g_string_append_c (value->value.v_string, '\b'); }
commit 7f1fb40db9e46d98f214ee1f50d35b4284988164
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 13:28:07 2008 +0300

    Parse also strings started with single quote instead of double quote

diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index 47dfde8..b4a7428 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -27,6 +27,8 @@ extern YY_DECL;
 }
 
 %{
+static char begin_char;
+
 #define RESET_POSITION value->position = G_MAXSIZE
 
 #define ERROR(...) vivi_parser_scanner_error (yyextra, yylineno, yycolumn, __VA_ARGS__)
@@ -237,14 +239,33 @@ identifier_part		[$_a-zA-Z0-9]
 			}
 
 \"			{
+			  begin_char = '"';
+			  value->value.v_string = g_string_new ("");
+			  BEGIN(str);
+			}
+
+\'			{
+			  begin_char = '\'';
 			  value->value.v_string = g_string_new ("");
 			  BEGIN(str);
 			}
 
 <str>{
   \"			{
-			  BEGIN(INITIAL);
-			  return TOKEN_STRING;
+			  if (begin_char == '"') {
+			    BEGIN(INITIAL);
+			    return TOKEN_STRING;
+			  } else {
+			    g_string_append_c (value->value.v_string, '"');
+			  }
+			}
+  \'			{
+			  if (begin_char == '\'') {
+			    BEGIN(INITIAL);
+			    return TOKEN_STRING;
+			  } else {
+			    g_string_append_c (value->value.v_string, '\'');
+			  }
 			}
   \n			{
 			  BEGIN(INITIAL);
@@ -278,7 +299,7 @@ identifier_part		[$_a-zA-Z0-9]
   \\t			{ g_string_append_c (value->value.v_string, '\t'); }
   \\v			{ g_string_append_c (value->value.v_string, '\v'); }
   \\.			{ g_string_append_c (value->value.v_string, yytext[1]); }
-  [^\\\n\"]+		{
+  [^\\\n\"\']+		{
 			  char *p;
 			  for (p = yytext; *p != '\0'; p++) {
 			    g_string_append_c (value->value.v_string, *p);
commit 551ca7b8b84753f15f0e8bc6e53f277181a86893
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 12:07:49 2008 +0300

    Fix the compiling of array literals. Add a test

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 8e0c3f6..b65167a 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -16,6 +16,8 @@ check-local: $(top_builddir)/vivified/code/vivi-compile
 EXTRA_DIST = \
 	and.as \
 	and.as.expect \
+	array_literal.as \
+	array_literal.as.expect \
 	asm_empty.as \
 	asm_empty.as.expect \
 	assignment.as \
diff --git a/vivified/code/test/compiler/array_literal.as b/vivified/code/test/compiler/array_literal.as
new file mode 100644
index 0000000..f366964
--- /dev/null
+++ b/vivified/code/test/compiler/array_literal.as
@@ -0,0 +1 @@
+a = [a, "b", 3];
diff --git a/vivified/code/test/compiler/array_literal.as.expect b/vivified/code/test/compiler/array_literal.as.expect
new file mode 100644
index 0000000..babf2a8
--- /dev/null
+++ b/vivified/code/test/compiler/array_literal.as.expect
@@ -0,0 +1,9 @@
+asm {
+  pool "a", "b"
+  push pool 0, 3, pool 1, pool 0
+  get_variable
+  push 3
+  init_array
+  set_variable
+  end
+}
diff --git a/vivified/code/vivi_code_init_array.c b/vivified/code/vivi_code_init_array.c
index fd52f36..778b4fe 100644
--- a/vivified/code/vivi_code_init_array.c
+++ b/vivified/code/vivi_code_init_array.c
@@ -88,9 +88,9 @@ vivi_code_init_array_compile (ViviCodeToken *token,
   ViviCodeAsm *code;
   guint i;
 
-  for (i = 0; i < array->variables->len; i++) {
+  for (i = array->variables->len; i > 0; i--) {
     vivi_code_compiler_compile_value (compiler,
-	VIVI_CODE_VALUE (g_ptr_array_index (array->variables, i)));
+	VIVI_CODE_VALUE (g_ptr_array_index (array->variables, i - 1)));
   }
   count = vivi_code_number_new (array->variables->len);
   vivi_code_compiler_compile_value (compiler, count);
commit 62ac3c79763d86e3cd985a53e1bf4a994d6b8aff
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 12:02:55 2008 +0300

    Fix compiling of object literals. Add a test

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 2c294fc..8e0c3f6 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -46,6 +46,8 @@ EXTRA_DIST = \
 	label.as.expect \
 	operator.as \
 	operator.as.expect \
+	object_literal.as \
+	object_literal.as.expect \
 	or.as \
 	or.as.expect \
 	trace.as \
diff --git a/vivified/code/test/compiler/object_literal.as b/vivified/code/test/compiler/object_literal.as
new file mode 100644
index 0000000..d4ca4a5
--- /dev/null
+++ b/vivified/code/test/compiler/object_literal.as
@@ -0,0 +1 @@
+o = { a: 1, "b": 2, 3: 3 };
diff --git a/vivified/code/test/compiler/object_literal.as.expect b/vivified/code/test/compiler/object_literal.as.expect
new file mode 100644
index 0000000..7017084
--- /dev/null
+++ b/vivified/code/test/compiler/object_literal.as.expect
@@ -0,0 +1,7 @@
+asm {
+  pool "o", "a", "b", "3"
+  push pool 0, pool 1, 1, pool 2, 2, pool 3, 3, 3
+  init_object
+  set_variable
+  end
+}
diff --git a/vivified/code/vivi_code_init_object.c b/vivified/code/vivi_code_init_object.c
index 912deed..3521d09 100644
--- a/vivified/code/vivi_code_init_object.c
+++ b/vivified/code/vivi_code_init_object.c
@@ -89,8 +89,8 @@ vivi_code_init_object_compile (ViviCodeToken *token,
 
   for (i = 0; i < object->variables->len; i++) {
     VariableEntry *entry = &g_array_index (object->variables, VariableEntry, i);
-    vivi_code_compiler_compile_value (compiler, entry->value);
     vivi_code_compiler_compile_value (compiler, entry->name);
+    vivi_code_compiler_compile_value (compiler, entry->value);
   }
 
   count = vivi_code_number_new (object->variables->len);
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index daced14..aa74e9c 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -861,44 +861,27 @@ parse_identifier (ParseData *data)
   return value;
 }
 
-static const struct {
-  PeekFunction peek;
-  ParseValueFunction parse;
-} property_name_functions[] = {
-  { peek_identifier, parse_identifier },
-  { peek_string, parse_string },
-  { peek_numeric, parse_numeric },
-  { NULL, NULL }
-};
-
-G_GNUC_UNUSED static gboolean
-peek_property_name (ParseData *data)
-{
-  guint i;
-
-  for (i = 0; property_name_functions[i].peek != NULL; i++) {
-    if (property_name_functions[i].peek (data))
-      return TRUE;
-  }
-
-  return FALSE;
-}
-
 static ViviCodeValue *
 parse_property_name (ParseData *data)
 {
   ViviCodeValue *value;
-  guint i;
 
-  for (i = 0; property_name_functions[i].peek != NULL; i++) {
-    if (property_name_functions[i].peek (data)) {
-      return property_name_functions[i].parse (data);
-    }
+  vivi_parser_start_code_token (data);
+
+  if (peek_identifier (data)) {
+    value = vivi_code_string_new (parse_identifier_value (data));
+  } else if (peek_string (data)) {
+    value = parse_string (data);
+  } else if (peek_numeric (data)) {
+    char s[G_ASCII_DTOSTR_BUF_SIZE];
+    double d = parse_numeric_value (data);
+    g_ascii_dtostr (s, G_ASCII_DTOSTR_BUF_SIZE, d);
+    value = vivi_code_string_new (s);
+  } else {
+    vivi_parser_error_unexpected (data, ERROR_TOKEN_PROPERTY_NAME);
+    value = vivi_code_string_new ("undefined");
   }
 
-  vivi_parser_error_unexpected (data, ERROR_TOKEN_PROPERTY_NAME);
-  vivi_parser_start_code_token (data);
-  value = vivi_code_string_new ("undefined");
   vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (value));
 
   return value;
commit 72c4c31af0437266d45b1bdd8fafc62fdea6e5be
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 11:46:02 2008 +0300

    Rename some auto generated labels

diff --git a/vivified/code/test/compiler/if.as.expect b/vivified/code/test/compiler/if.as.expect
index 86ffa60..b811c3e 100644
--- a/vivified/code/test/compiler/if.as.expect
+++ b/vivified/code/test/compiler/if.as.expect
@@ -3,9 +3,9 @@ asm {
   push pool 0
   get_variable
   not
-  if end_0001
+  if if_end_0001
   play
 
-end_0001:
+if_end_0001:
   end
 }
diff --git a/vivified/code/test/compiler/if_else.as.expect b/vivified/code/test/compiler/if_else.as.expect
index b7d54c5..56ca8c9 100644
--- a/vivified/code/test/compiler/if_else.as.expect
+++ b/vivified/code/test/compiler/if_else.as.expect
@@ -2,13 +2,13 @@ asm {
   pool "a"
   push pool 0
   get_variable
-  if if_0001
+  if if_true_0001
   stop
-  jump end_0002
+  jump if_end_0002
 
-if_0001:
+if_true_0001:
   play
 
-end_0002:
+if_end_0002:
   end
 }
diff --git a/vivified/code/test/compiler/while.as.expect b/vivified/code/test/compiler/while.as.expect
index 6661774..9f78738 100644
--- a/vivified/code/test/compiler/while.as.expect
+++ b/vivified/code/test/compiler/while.as.expect
@@ -1,14 +1,14 @@
 asm {
   pool "a"
 
-start_0001:
+loop_start_0001:
   push pool 0
   get_variable
   not
-  if end_0002
+  if loop_end_0002
   play
-  jump start_0001
+  jump loop_start_0001
 
-end_0002:
+loop_end_0002:
   end
 }
diff --git a/vivified/code/vivi_code_if.c b/vivified/code/vivi_code_if.c
index a3c82bd..0a04c0f 100644
--- a/vivified/code/vivi_code_if.c
+++ b/vivified/code/vivi_code_if.c
@@ -138,14 +138,14 @@ vivi_code_if_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   vivi_code_compiler_compile_value (compiler, stmt->condition);
 
   if (stmt->else_statement) {
-    label_if = vivi_code_compiler_create_label (compiler, "if");
+    label_if = vivi_code_compiler_create_label (compiler, "if_true");
     code = vivi_code_asm_if_new (label_if);
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
 
     vivi_code_compiler_compile_statement (compiler, stmt->else_statement);
 
-    label_end = vivi_code_compiler_create_label (compiler, "end");
+    label_end = vivi_code_compiler_create_label (compiler, "if_end");
     code = vivi_code_asm_jump_new (label_end);
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
@@ -157,7 +157,7 @@ vivi_code_if_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
 
-    label_end = vivi_code_compiler_create_label (compiler, "end");
+    label_end = vivi_code_compiler_create_label (compiler, "if_end");
     code = vivi_code_asm_if_new (label_end);
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
diff --git a/vivified/code/vivi_code_loop.c b/vivified/code/vivi_code_loop.c
index 7f1c5db..ae3bdd4 100644
--- a/vivified/code/vivi_code_loop.c
+++ b/vivified/code/vivi_code_loop.c
@@ -82,7 +82,7 @@ vivi_code_loop_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   ViviCodeLabel *label_start, *label_end = NULL;
   ViviCodeAsm *code;
 
-  label_start = vivi_code_compiler_create_label (compiler, "start");
+  label_start = vivi_code_compiler_create_label (compiler, "loop_start");
   vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_start));
 
   if (loop->condition) {
@@ -92,7 +92,7 @@ vivi_code_loop_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
 
-    label_end = vivi_code_compiler_create_label (compiler, "end");
+    label_end = vivi_code_compiler_create_label (compiler, "loop_end");
     code = vivi_code_asm_if_new (label_end);
     vivi_code_compiler_add_code (compiler, code);
     g_object_unref (code);
commit c00e29a4dc786e0f4eebe24bc20d76e1baf34679
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 11:42:08 2008 +0300

    Add a vivi-compile test for function declaration

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 3d02697..2c294fc 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -34,6 +34,8 @@ EXTRA_DIST = \
 	empty_block.as.expect \
 	empty_statement.as \
 	empty_statement.as.expect \
+	function_declaration.as \
+	function_declaration.as.expect \
 	function_expression.as \
 	function_expression.as.expect \
 	if.as \
diff --git a/vivified/code/test/compiler/function_declaration.as b/vivified/code/test/compiler/function_declaration.as
new file mode 100644
index 0000000..480e66d
--- /dev/null
+++ b/vivified/code/test/compiler/function_declaration.as
@@ -0,0 +1,3 @@
+function test () {
+  play ();
+};
diff --git a/vivified/code/test/compiler/function_declaration.as.expect b/vivified/code/test/compiler/function_declaration.as.expect
new file mode 100644
index 0000000..15e1e43
--- /dev/null
+++ b/vivified/code/test/compiler/function_declaration.as.expect
@@ -0,0 +1,7 @@
+asm {
+  function2 "test" function_end_0001
+  play
+
+function_end_0001:
+  end
+}
commit 0e0f32039f9faf71e940bd7d06b81e16385a2ab6
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon May 12 11:39:39 2008 +0300

    Create ViviCodeFunctionDeclaration for named functions (statement, not value)

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 441d551..93a75c0 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -63,6 +63,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_error.c \
 	vivi_code_function.c \
 	vivi_code_function_call.c \
+	vivi_code_function_declaration.c \
 	vivi_code_get.c \
 	vivi_code_get_timer.c \
 	vivi_code_get_url.c \
@@ -138,6 +139,7 @@ noinst_HEADERS = \
 	vivi_code_error.h \
 	vivi_code_function.h \
 	vivi_code_function_call.h \
+	vivi_code_function_declaration.h \
 	vivi_code_get.h \
 	vivi_code_get_timer.h \
 	vivi_code_get_url.h \
diff --git a/vivified/code/vivi_code_function.c b/vivified/code/vivi_code_function.c
index afa64b7..9a349b8 100644
--- a/vivified/code/vivi_code_function.c
+++ b/vivified/code/vivi_code_function.c
@@ -40,9 +40,6 @@ vivi_code_function_dispose (GObject *object)
   ViviCodeFunction *function = VIVI_CODE_FUNCTION (object);
   guint i;
 
-  if (function->name != NULL)
-    g_free (function->name);
-
   if (function->body)
     g_object_unref (function->body);
 
@@ -60,12 +57,7 @@ vivi_code_function_print (ViviCodeToken *token, ViviCodePrinter*printer)
   ViviCodeFunction *function = VIVI_CODE_FUNCTION (token);
   guint i;
 
-  vivi_code_printer_print (printer, "function ");
-  if (function->name != NULL) {
-    vivi_code_printer_print (printer, function->name);
-    vivi_code_printer_print (printer, " ");
-  }
-  vivi_code_printer_print (printer, "(");
+  vivi_code_printer_print (printer, "function (");
   for (i = 0; i < function->arguments->len; i++) {
     if (i != 0)
       vivi_code_printer_print (printer, ", ");
@@ -92,7 +84,7 @@ vivi_code_function_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 
   label_end = vivi_code_compiler_create_label (compiler, "function_end");
 
-  code = vivi_code_asm_function2_new (label_end, function->name, 0, 0);
+  code = vivi_code_asm_function2_new (label_end, NULL, 0, 0);
   for (i = 0; i < function->arguments->len; i++) {
     vivi_code_asm_function2_add_argument (VIVI_CODE_ASM_FUNCTION2 (code),
 	g_ptr_array_index (function->arguments, i), 0);
@@ -140,28 +132,16 @@ vivi_code_function_init (ViviCodeFunction *function)
 }
 
 ViviCodeValue *
-vivi_code_function_new (const char *name)
+vivi_code_function_new (void)
 {
   ViviCodeValue *function;
 
   function = VIVI_CODE_VALUE (g_object_new (VIVI_TYPE_CODE_FUNCTION, NULL));
 
-  VIVI_CODE_FUNCTION (function)->name = g_strdup (name);
-
   return function;
 }
 
 void
-vivi_code_function_set_name (ViviCodeFunction *function, const char *name)
-{
-  g_return_if_fail (VIVI_IS_CODE_FUNCTION (function));
-
-  if (function->name != NULL)
-    g_free (function->name);
-  function->name = g_strdup (name);
-}
-
-void
 vivi_code_function_set_body (ViviCodeFunction *function,
     ViviCodeStatement *body)
 {
@@ -189,7 +169,6 @@ vivi_code_function_new_from_script (SwfdecScript *script)
   g_return_val_if_fail (script != NULL, NULL);
 
   function = g_object_new (VIVI_TYPE_CODE_FUNCTION, NULL);
-  // TODO: set name
   function->body = vivi_decompile_script (script);
 
   for (i = 0; i < script->n_arguments; i++) {
diff --git a/vivified/code/vivi_code_function.h b/vivified/code/vivi_code_function.h
index 9ce708e..221da93 100644
--- a/vivified/code/vivi_code_function.h
+++ b/vivified/code/vivi_code_function.h
@@ -40,7 +40,6 @@ struct _ViviCodeFunction
 {
   ViviCodeValue		value;
 
-  char *		name;
   GPtrArray *		arguments;		// char *
   ViviCodeStatement *	body;
 };
@@ -52,11 +51,9 @@ struct _ViviCodeFunctionClass
 
 GType			vivi_code_function_get_type   	(void);
 
-ViviCodeValue *		vivi_code_function_new		(const char *name);
+ViviCodeValue *		vivi_code_function_new		(void);
 ViviCodeValue *		vivi_code_function_new_from_script (SwfdecScript *	script);
 
-void			vivi_code_function_set_name	(ViviCodeFunction *	function,
-							 const char *		name);
 void			vivi_code_function_set_body	(ViviCodeFunction *	function,
 							 ViviCodeStatement *	body);
 void			vivi_code_function_add_argument	(ViviCodeFunction *	function,
diff --git a/vivified/code/vivi_code_function_declaration.c b/vivified/code/vivi_code_function_declaration.c
new file mode 100644
index 0000000..e157bd2
--- /dev/null
+++ b/vivified/code/vivi_code_function_declaration.c
@@ -0,0 +1,165 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *               2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_function_declaration.h"
+#include "vivi_code_constant.h"
+#include "vivi_code_label.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+#include "vivi_code_asm_function2.h"
+
+#include "vivi_decompiler.h"
+
+G_DEFINE_TYPE (ViviCodeFunctionDeclaration, vivi_code_function_declaration, VIVI_TYPE_CODE_STATEMENT)
+
+static void
+vivi_code_function_declaration_dispose (GObject *object)
+{
+  ViviCodeFunctionDeclaration *function =
+    VIVI_CODE_FUNCTION_DECLARATION (object);
+  guint i;
+
+  g_free (function->name);
+
+  if (function->body)
+    g_object_unref (function->body);
+
+  for (i = 0; i < function->arguments->len; i++) {
+    g_free (g_ptr_array_index (function->arguments, i));
+  }
+  g_ptr_array_free (function->arguments, TRUE);
+
+  G_OBJECT_CLASS (vivi_code_function_declaration_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_function_declaration_print (ViviCodeToken *token,
+    ViviCodePrinter *printer)
+{
+  ViviCodeFunctionDeclaration *function =
+    VIVI_CODE_FUNCTION_DECLARATION (token);
+  guint i;
+
+  vivi_code_printer_print (printer, "function ");
+  vivi_code_printer_print (printer, function->name);
+
+  vivi_code_printer_print (printer, " (");
+  for (i = 0; i < function->arguments->len; i++) {
+    if (i != 0)
+      vivi_code_printer_print (printer, ", ");
+    vivi_code_printer_print (printer,
+	g_ptr_array_index (function->arguments, i));
+  }
+  vivi_code_printer_print (printer, ") {");
+  vivi_code_printer_new_line (printer, FALSE);
+
+  if (function->body) {
+    vivi_code_printer_push_indentation (printer);
+    vivi_code_printer_print_token (printer, VIVI_CODE_TOKEN (function->body));
+    vivi_code_printer_pop_indentation (printer);
+  }
+
+  vivi_code_printer_print (printer, "}");
+}
+
+static void
+vivi_code_function_declaration_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeFunctionDeclaration *function =
+    VIVI_CODE_FUNCTION_DECLARATION (token);
+  ViviCodeLabel *label_end;
+  ViviCodeAsm *code;
+  guint i;
+
+  label_end = vivi_code_compiler_create_label (compiler, "function_end");
+
+  code = vivi_code_asm_function2_new (label_end, function->name, 0, 0);
+  for (i = 0; i < function->arguments->len; i++) {
+    vivi_code_asm_function2_add_argument (VIVI_CODE_ASM_FUNCTION2 (code),
+	g_ptr_array_index (function->arguments, i), 0);
+  }
+
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  if (function->body != NULL)
+    vivi_code_compiler_compile_statement (compiler, function->body);
+
+  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
+  g_object_unref (label_end);
+}
+
+static void
+vivi_code_function_declaration_class_init (
+    ViviCodeFunctionDeclarationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  object_class->dispose = vivi_code_function_declaration_dispose;
+
+  token_class->print = vivi_code_function_declaration_print;
+  token_class->compile = vivi_code_function_declaration_compile;
+}
+
+static void
+vivi_code_function_declaration_init (ViviCodeFunctionDeclaration *function)
+{
+  function->arguments = g_ptr_array_new ();
+}
+
+ViviCodeStatement *
+vivi_code_function_declaration_new (const char *name)
+{
+  ViviCodeStatement *function;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  function = VIVI_CODE_STATEMENT (g_object_new (
+	VIVI_TYPE_CODE_FUNCTION_DECLARATION, NULL));
+  VIVI_CODE_FUNCTION_DECLARATION (function)->name = g_strdup (name);
+
+  return function;
+}
+
+void
+vivi_code_function_declaration_set_body (ViviCodeFunctionDeclaration *function,
+    ViviCodeStatement *body)
+{
+  g_return_if_fail (VIVI_IS_CODE_FUNCTION_DECLARATION (function));
+  g_return_if_fail (VIVI_IS_CODE_STATEMENT (body));
+
+  function->body = g_object_ref (body);
+}
+
+void
+vivi_code_function_declaration_add_argument (
+    ViviCodeFunctionDeclaration *function, const char *name)
+{
+  g_return_if_fail (VIVI_IS_CODE_FUNCTION_DECLARATION (function));
+  g_return_if_fail (name != NULL);
+
+  g_ptr_array_add (function->arguments, g_strdup (name));
+}
diff --git a/vivified/code/vivi_code_function_declaration.h b/vivified/code/vivi_code_function_declaration.h
new file mode 100644
index 0000000..cc26f81
--- /dev/null
+++ b/vivified/code/vivi_code_function_declaration.h
@@ -0,0 +1,64 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *               2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_FUNCTION_DECLARATION_H_
+#define _VIVI_CODE_FUNCTION_DECLARATION_H_
+
+#include <vivified/code/vivi_code_statement.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeFunctionDeclaration ViviCodeFunctionDeclaration;
+typedef struct _ViviCodeFunctionDeclarationClass ViviCodeFunctionDeclarationClass;
+
+#define VIVI_TYPE_CODE_FUNCTION_DECLARATION                    (vivi_code_function_declaration_get_type())
+#define VIVI_IS_CODE_FUNCTION_DECLARATION(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_FUNCTION_DECLARATION))
+#define VIVI_IS_CODE_FUNCTION_DECLARATION_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_FUNCTION_DECLARATION))
+#define VIVI_CODE_FUNCTION_DECLARATION(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_FUNCTION_DECLARATION, ViviCodeFunctionDeclaration))
+#define VIVI_CODE_FUNCTION_DECLARATION_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_FUNCTION_DECLARATION, ViviCodeFunctionDeclarationClass))
+#define VIVI_CODE_FUNCTION_DECLARATION_FUNCTION_DECLARATION_CLASS(obj)          (G_TYPE_INSTANCE_FUNCTION_DECLARATION_CLASS ((obj), VIVI_TYPE_CODE_FUNCTION_DECLARATION, ViviCodeFunctionDeclarationClass))
+
+struct _ViviCodeFunctionDeclaration
+{
+  ViviCodeStatement	statement;
+
+  char *			name;
+  GPtrArray *			arguments;	// char *
+  ViviCodeStatement *		body;
+};
+
+struct _ViviCodeFunctionDeclarationClass
+{
+  ViviCodeStatementClass	statement_class;
+};
+
+GType		vivi_code_function_declaration_get_type   	(void);
+
+ViviCodeStatement *vivi_code_function_declaration_new		(const char *			name);
+
+void		vivi_code_function_declaration_set_body	(ViviCodeFunctionDeclaration *		function,
+								 ViviCodeStatement *		body);
+void		vivi_code_function_declaration_add_argument	(ViviCodeFunctionDeclaration *	function,
+								 const char *			name);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 26d2506..daced14 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -44,6 +44,7 @@
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
 #include "vivi_code_function_call.h"
+#include "vivi_code_function_declaration.h"
 #include "vivi_code_get.h"
 #include "vivi_code_get_timer.h"
 #include "vivi_code_get_url.h"
@@ -2985,55 +2986,44 @@ parse_statement (ParseData *data)
 // function
 
 static gboolean
-peek_function_definition (ParseData *data)
-{
-  return peek_token (data, TOKEN_FUNCTION);
-}
-
-static gboolean
 peek_source_element (ParseData *data);
 
 static ViviCodeStatement *
 parse_source_element (ParseData *data);
 
-static ViviCodeValue *
-parse_function_definition (ParseData *data, gboolean name_required)
+static gboolean
+peek_function_declaration (ParseData *data)
 {
-  ViviCodeValue *function;
-  ViviCodeStatement *body;
-  char *name;
+  return peek_token (data, TOKEN_FUNCTION);
+}
 
-  body = NULL;
+static ViviCodeStatement *
+parse_function_declaration (ParseData *data)
+{
+  ViviCodeFunctionDeclaration *function;
+  ViviCodeStatement *body;
 
   parse_token (data, TOKEN_FUNCTION);
 
-  if (name_required) {
-    name = g_strdup (parse_identifier_value (data));
-    parse_token (data, TOKEN_PARENTHESIS_LEFT);
-  } else {
-    if (!try_parse_token (data, TOKEN_PARENTHESIS_LEFT)) {
-      if (peek_identifier (data)) {
-	name = g_strdup (parse_identifier_value (data));
-	parse_token (data, TOKEN_PARENTHESIS_LEFT);
-      } else {
-	vivi_parser_error_unexpected_or (data, TOKEN_PARENTHESIS_LEFT,
-	    ERROR_TOKEN_IDENTIFIER, TOKEN_NONE);
-	name = NULL;
-      }
-    } else {
-      name = NULL;
-    }
-  }
+  function = VIVI_CODE_FUNCTION_DECLARATION (
+    vivi_code_function_declaration_new (parse_identifier_value (data)));
 
-  function = vivi_code_function_new (name);
-  g_free (name);
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
 
-  if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+  if (peek_identifier (data)) {
     do {
-      vivi_code_function_add_argument (VIVI_CODE_FUNCTION (function),
+      vivi_code_function_declaration_add_argument (function,
 	  parse_identifier_value (data));
     } while (try_parse_token (data, TOKEN_COMMA));
-    parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+    if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+      vivi_parser_error_unexpected_or (data, TOKEN_PARENTHESIS_RIGHT,
+	  TOKEN_COMMA, TOKEN_NONE);
+    }
+  } else {
+    if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+      vivi_parser_error_unexpected_or (data, TOKEN_PARENTHESIS_RIGHT,
+	  TOKEN_IDENTIFIER, TOKEN_NONE);
+    }
   }
 
   parse_token (data, TOKEN_BRACE_LEFT);
@@ -3046,42 +3036,61 @@ parse_function_definition (ParseData *data, gboolean name_required)
   parse_token (data, TOKEN_BRACE_RIGHT);
 
   if (body != NULL) {
-    vivi_code_function_set_body (VIVI_CODE_FUNCTION (function), body);
+    vivi_code_function_declaration_set_body (function, body);
     g_object_unref (body);
   }
 
-  return function;
+  return VIVI_CODE_STATEMENT (function);
 }
 
 static gboolean
-peek_function_declaration (ParseData *data)
+peek_function_expression (ParseData *data)
 {
-  return peek_function_definition (data);
+  return peek_token (data, TOKEN_FUNCTION);
 }
 
-static ViviCodeStatement *
-parse_function_declaration (ParseData *data)
+static ViviCodeValue *
+parse_function_expression (ParseData *data)
 {
-  ViviCodeStatement *statement;
-  ViviCodeValue *function;
+  ViviCodeFunction *function;
+  ViviCodeStatement *body;
 
-  function = parse_function_definition (data, TRUE);
-  statement = vivi_code_value_statement_new (function);
-  g_object_unref (function);
+  parse_token (data, TOKEN_FUNCTION);
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
 
-  return statement;
-}
+  function = VIVI_CODE_FUNCTION (vivi_code_function_new ());
 
-static gboolean
-peek_function_expression (ParseData *data)
-{
-  return peek_function_definition (data);
-}
+  if (peek_identifier (data)) {
+    do {
+      vivi_code_function_add_argument (function,
+	  parse_identifier_value (data));
+    } while (try_parse_token (data, TOKEN_COMMA));
+    if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+      vivi_parser_error_unexpected_or (data, TOKEN_PARENTHESIS_RIGHT,
+	  TOKEN_COMMA, TOKEN_NONE);
+    }
+  } else {
+    if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+      vivi_parser_error_unexpected_or (data, TOKEN_PARENTHESIS_RIGHT,
+	  TOKEN_IDENTIFIER, TOKEN_NONE);
+    }
+  }
 
-static ViviCodeValue *
-parse_function_expression (ParseData *data)
-{
-  return parse_function_definition (data, FALSE);
+  parse_token (data, TOKEN_BRACE_LEFT);
+
+  vivi_parser_start_level (data);
+  body = parse_statement_list (data, peek_source_element, parse_source_element,
+      TOKEN_NONE);
+  vivi_parser_end_level (data);
+
+  parse_token (data, TOKEN_BRACE_RIGHT);
+
+  if (body != NULL) {
+    vivi_code_function_set_body (function, body);
+    g_object_unref (body);
+  }
+
+  return VIVI_CODE_VALUE (function);
 }
 
 // top
commit feab1ed6c9221f18d3ded4bf3935480f7698a19d
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 20:57:43 2008 +0300

    Compile && expressions. Add a test

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 7f51d1c..3d02697 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -14,6 +14,8 @@ check-local: $(top_builddir)/vivified/code/vivi-compile
 	fi
 
 EXTRA_DIST = \
+	and.as \
+	and.as.expect \
 	asm_empty.as \
 	asm_empty.as.expect \
 	assignment.as \
diff --git a/vivified/code/test/compiler/and.as b/vivified/code/test/compiler/and.as
new file mode 100644
index 0000000..3d26993
--- /dev/null
+++ b/vivified/code/test/compiler/and.as
@@ -0,0 +1 @@
+trace (a && b);
diff --git a/vivified/code/test/compiler/and.as.expect b/vivified/code/test/compiler/and.as.expect
new file mode 100644
index 0000000..382d28d
--- /dev/null
+++ b/vivified/code/test/compiler/and.as.expect
@@ -0,0 +1,15 @@
+asm {
+  pool "a", "b"
+  push pool 0
+  get_variable
+  push_duplicate
+  not
+  if and_end_0001
+  pop
+  push pool 1
+  get_variable
+
+and_end_0001:
+  trace
+  end
+}
diff --git a/vivified/code/vivi_code_and.c b/vivified/code/vivi_code_and.c
index b2af31c..34bb2cf 100644
--- a/vivified/code/vivi_code_and.c
+++ b/vivified/code/vivi_code_and.c
@@ -22,16 +22,51 @@
 #endif
 
 #include "vivi_code_and.h"
+#include "vivi_code_compiler.h"
+#include "vivi_code_asm_code_default.h"
+#include "vivi_code_asm_if.h"
 
 G_DEFINE_TYPE (ViviCodeAnd, vivi_code_and, VIVI_TYPE_CODE_BINARY)
 
 static void
+vivi_code_and_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
+  ViviCodeAsm *code;
+  ViviCodeLabel *label_end;
+
+  vivi_code_compiler_compile_value (compiler, binary->left);
+
+  code = vivi_code_asm_push_duplicate_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  code = vivi_code_asm_not_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  label_end = vivi_code_compiler_create_label (compiler, "and_end");
+  code = vivi_code_asm_if_new (label_end);
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  code = vivi_code_asm_pop_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  vivi_code_compiler_compile_value (compiler, binary->right);
+
+  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
+  g_object_unref (label_end);
+}
+
+static void
 vivi_code_and_class_init (ViviCodeAndClass *klass)
 {
   ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
   ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
 
-  token_class->compile = NULL; /* FIXME */
+  token_class->compile = vivi_code_and_compile;
 
   binary_class->operator_name = "&&";
 }
commit 0310cf53b629b48728dad5f7ef5b4705d04cf49a
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 20:50:44 2008 +0300

    Compile || expressions. Add a test

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 1954769..7f51d1c 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -42,6 +42,8 @@ EXTRA_DIST = \
 	label.as.expect \
 	operator.as \
 	operator.as.expect \
+	or.as \
+	or.as.expect \
 	trace.as \
 	trace.as.expect \
 	while.as \
diff --git a/vivified/code/test/compiler/or.as b/vivified/code/test/compiler/or.as
new file mode 100644
index 0000000..cac9508
--- /dev/null
+++ b/vivified/code/test/compiler/or.as
@@ -0,0 +1 @@
+trace (a || b);
diff --git a/vivified/code/test/compiler/or.as.expect b/vivified/code/test/compiler/or.as.expect
new file mode 100644
index 0000000..2878ecf
--- /dev/null
+++ b/vivified/code/test/compiler/or.as.expect
@@ -0,0 +1,14 @@
+asm {
+  pool "a", "b"
+  push pool 0
+  get_variable
+  push_duplicate
+  if or_end_0001
+  pop
+  push pool 1
+  get_variable
+
+or_end_0001:
+  trace
+  end
+}
diff --git a/vivified/code/vivi_code_or.c b/vivified/code/vivi_code_or.c
index 0a952ae..843dfc4 100644
--- a/vivified/code/vivi_code_or.c
+++ b/vivified/code/vivi_code_or.c
@@ -22,16 +22,47 @@
 #endif
 
 #include "vivi_code_or.h"
+#include "vivi_code_compiler.h"
+#include "vivi_code_asm_code_default.h"
+#include "vivi_code_asm_if.h"
 
 G_DEFINE_TYPE (ViviCodeOr, vivi_code_or, VIVI_TYPE_CODE_BINARY)
 
 static void
+vivi_code_or_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
+  ViviCodeAsm *code;
+  ViviCodeLabel *label_end;
+
+  vivi_code_compiler_compile_value (compiler, binary->left);
+
+  code = vivi_code_asm_push_duplicate_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  label_end = vivi_code_compiler_create_label (compiler, "or_end");
+  code = vivi_code_asm_if_new (label_end);
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  code = vivi_code_asm_pop_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  vivi_code_compiler_compile_value (compiler, binary->right);
+
+  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
+  g_object_unref (label_end);
+}
+
+static void
 vivi_code_or_class_init (ViviCodeOrClass *klass)
 {
   ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
   ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
 
-  token_class->compile = NULL; /* FIXME */
+  token_class->compile = vivi_code_or_compile;
 
   binary_class->operator_name = "||";
 }
commit 874d8a9f19c230e31a9187896d84e7c61ba6d412
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 20:39:12 2008 +0300

    Add a vivi-compile test for various operators

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index ec6b6b2..1954769 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -40,6 +40,8 @@ EXTRA_DIST = \
 	if_else.as.expect \
 	label.as \
 	label.as.expect \
+	operator.as \
+	operator.as.expect \
 	trace.as \
 	trace.as.expect \
 	while.as \
diff --git a/vivified/code/test/compiler/operator.as b/vivified/code/test/compiler/operator.as
new file mode 100644
index 0000000..9be1d7e
--- /dev/null
+++ b/vivified/code/test/compiler/operator.as
@@ -0,0 +1,20 @@
+trace (a | a);
+trace (a ^ a);
+trace (a & a);
+trace (a == a);
+trace (a != a);
+trace (a === a);
+trace (a !== a);
+trace (a < a);
+trace (a > a);
+trace (a <= a);
+trace (a >= a);
+trace (a instanceof a);
+trace (a << a);
+trace (a >> a);
+trace (a >>> a);
+trace (a + a);
+trace (a - a);
+trace (a * a);
+trace (a / a);
+trace (a % a);
diff --git a/vivified/code/test/compiler/operator.as.expect b/vivified/code/test/compiler/operator.as.expect
new file mode 100644
index 0000000..3b62e15
--- /dev/null
+++ b/vivified/code/test/compiler/operator.as.expect
@@ -0,0 +1,128 @@
+asm {
+  pool "a"
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_or
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_xor
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_and
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  equals2
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  equals2
+  not
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  strict_equals
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  strict_equals
+  not
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  less2
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  greater
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  greater
+  not
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  less2
+  not
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  instance_of
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_lshift
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_rshift
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  bit_urshift
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  add2
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  subtract
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  multiply
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  divide
+  trace
+  push pool 0
+  get_variable
+  push pool 0
+  get_variable
+  modulo
+  trace
+  end
+}
commit b183392dafb211a3e3903fab6bcfe60e29e51f66
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 20:38:15 2008 +0300

    Fix compiling of some operators

diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index 57672b4..4039a6b 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -35,6 +35,7 @@ DEFAULT_BINARY (StringEquals,	string_equals,	"eq",	SWFDEC_AS_ACTION_STRING_EQUAL
 DEFAULT_BINARY (StringLess,	string_less,	"lt",	SWFDEC_AS_ACTION_STRING_LESS,	VIVI_PRECEDENCE_RELATIONAL)
 DEFAULT_BINARY (Add2,		add2,		"+",	SWFDEC_AS_ACTION_ADD2,		VIVI_PRECEDENCE_ADD)
 DEFAULT_BINARY (Less2,		less2,		"<",	SWFDEC_AS_ACTION_LESS2,		VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (InstanceOf,	instance_of,	"instanceof", SWFDEC_AS_ACTION_INSTANCE_OF,VIVI_PRECEDENCE_RELATIONAL)
 DEFAULT_BINARY (Equals2,	equals2,	"==",	SWFDEC_AS_ACTION_EQUALS2,	VIVI_PRECEDENCE_EQUALITY)
 DEFAULT_BINARY (BitAnd,		bit_and,	"&",	SWFDEC_AS_ACTION_BIT_AND,	VIVI_PRECEDENCE_BINARY_AND)
 DEFAULT_BINARY (BitOr,		bit_or,		"|",	SWFDEC_AS_ACTION_BIT_OR,	VIVI_PRECEDENCE_BINARY_OR)
diff --git a/vivified/code/vivi_code_unary.c b/vivified/code/vivi_code_unary.c
index 0ba5387..0c5c1be 100644
--- a/vivified/code/vivi_code_unary.c
+++ b/vivified/code/vivi_code_unary.c
@@ -75,7 +75,7 @@ vivi_code_unary_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   ViviCodeUnary *unary = VIVI_CODE_UNARY (token);
   ViviCodeAsm *code;
 
-  g_return_if_fail (unary->operation != '!');
+  g_return_if_fail (unary->operation == '!');
 
   vivi_code_compiler_compile_value (compiler, unary->value);
 
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 7238c33..26d2506 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -2064,15 +2064,20 @@ parse_operator_expression (ParseData *data, ViviCodeStatement **statement,
 //    { TOKEN_, vivi_code_string_less_new },
     { TOKEN_PLUS, vivi_code_add2_new },
     { TOKEN_LESS_THAN, vivi_code_less2_new },
+    { TOKEN_LESS_THAN_OR_EQUAL, vivi_code_greater_new },
     { TOKEN_EQUAL, vivi_code_equals2_new },
-//    { TOKEN_BITWISE_AND, vivi_code_bitwise_and_new },
-//    { TOKEN_BITWISE_OR, vivi_code_bitwise_or_new },
-//    { TOKEN_BITWISE_XOR, vivi_code_bitwise_xor_new },
-//    { TOKEN_SHIFT_LEFT, vivi_code_left_shift_new },
-//    { TOKEN_SHIFT_RIGHT, vivi_code_right_shift_new },
-//    { TOKEN_SHIFT_RIGHT_UNSIGNED, vivi_code_unsigned_right_shift_new },
+    { TOKEN_NOT_EQUAL, vivi_code_equals2_new },
+    { TOKEN_BITWISE_AND, vivi_code_bit_and_new },
+    { TOKEN_BITWISE_OR, vivi_code_bit_or_new },
+    { TOKEN_BITWISE_XOR, vivi_code_bit_xor_new },
+    { TOKEN_SHIFT_LEFT, vivi_code_bit_lshift_new },
+    { TOKEN_SHIFT_RIGHT, vivi_code_bit_rshift_new },
+    { TOKEN_SHIFT_RIGHT_UNSIGNED, vivi_code_bit_urshift_new },
     { TOKEN_STRICT_EQUAL, vivi_code_strict_equals_new },
+    { TOKEN_NOT_STRICT_EQUAL, vivi_code_strict_equals_new },
     { TOKEN_GREATER_THAN, vivi_code_greater_new },
+    { TOKEN_EQUAL_OR_GREATER_THAN, vivi_code_less2_new },
+    { TOKEN_INSTANCEOF, vivi_code_instance_of_new },
 //    { TOKEN_, vivi_code_string_greater_new },
     { TOKEN_LOGICAL_AND, vivi_code_and_new },
     { TOKEN_LOGICAL_OR, vivi_code_or_new }
@@ -2125,6 +2130,18 @@ again:
 	vivi_parser_duplicate_code_token (data);
 	vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (value));
 
+	if (tokens[i] == TOKEN_NOT_EQUAL ||
+	    tokens[i] == TOKEN_NOT_STRICT_EQUAL ||
+	    tokens[i] == TOKEN_LESS_THAN_OR_EQUAL ||
+	    tokens[i] == TOKEN_EQUAL_OR_GREATER_THAN) {
+	  left = vivi_code_unary_new (value, '!');
+	  g_object_unref (value);
+	  value = left;
+
+	  vivi_parser_duplicate_code_token (data);
+	  vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (value));
+	}
+
 	goto again;
       }
       g_assert_not_reached ();
@@ -2195,8 +2212,8 @@ static ViviCodeValue *
 parse_relational_expression (ParseData *data, ViviCodeStatement **statement)
 {
   static const ViviParserScannerToken tokens[] = { TOKEN_LESS_THAN,
-    TOKEN_GREATER_THAN, /*TOKEN_LESS_THAN_OR_EQUAL,
-    TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, TOKEN_IN,*/ TOKEN_NONE };
+    TOKEN_GREATER_THAN, TOKEN_LESS_THAN_OR_EQUAL,
+    TOKEN_EQUAL_OR_GREATER_THAN, TOKEN_INSTANCEOF, /*TOKEN_IN,*/ TOKEN_NONE };
 
   return parse_operator_expression (data, statement, tokens, PASS_ALWAYS,
       parse_shift_expression);
@@ -2212,7 +2229,7 @@ static ViviCodeValue *
 parse_equality_expression (ParseData *data, ViviCodeStatement **statement)
 {
   static const ViviParserScannerToken tokens[] = { TOKEN_EQUAL,
-    /*TOKEN_NOT_EQUAL,*/ TOKEN_STRICT_EQUAL, /*TOKEN_NOT_STRICT_EQUAL,*/
+    TOKEN_NOT_EQUAL, TOKEN_STRICT_EQUAL, TOKEN_NOT_STRICT_EQUAL,
     TOKEN_NONE };
 
   return parse_operator_expression (data, statement, tokens, PASS_ALWAYS,
commit dda99fe078af3ac686912ece888e5eab2351c2a0
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 16:07:39 2008 +0300

    Add a vivi-compile test for assignments with operators attached

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 79176a4..ec6b6b2 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -18,6 +18,8 @@ EXTRA_DIST = \
 	asm_empty.as.expect \
 	assignment.as \
 	assignment.as.expect \
+	assignment_operator.as \
+	assignment_operator.as.expect \
 	builtin_statement.as \
 	builtin_statement.as.expect \
 	call_function.as \
diff --git a/vivified/code/test/compiler/assignment_operator.as b/vivified/code/test/compiler/assignment_operator.as
new file mode 100644
index 0000000..ca62516
--- /dev/null
+++ b/vivified/code/test/compiler/assignment_operator.as
@@ -0,0 +1,11 @@
+a *= 1;
+a /= 1;
+a %= 1;
+a += 1;
+a -= 1;
+a <<= 1;
+a >>= 1;
+a >>>= 1;
+a &= 1;
+a ^= 1;
+a |= 1;
diff --git a/vivified/code/test/compiler/assignment_operator.as.expect b/vivified/code/test/compiler/assignment_operator.as.expect
new file mode 100644
index 0000000..a99dde1
--- /dev/null
+++ b/vivified/code/test/compiler/assignment_operator.as.expect
@@ -0,0 +1,59 @@
+asm {
+  pool "a"
+  push pool 0, pool 0
+  get_variable
+  push 1
+  multiply
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  divide
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  modulo
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  add2
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  subtract
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_lshift
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_rshift
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_urshift
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_and
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_xor
+  set_variable
+  push pool 0, pool 0
+  get_variable
+  push 1
+  bit_or
+  set_variable
+  end
+}
commit 3d17e7da1112faaccf97df4809f48e3d4f21a3f5
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 16:06:39 2008 +0300

    Fix parsing of assignments with operators attached (+=, &= etc.)

diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index 28759ac..57672b4 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -36,12 +36,12 @@ DEFAULT_BINARY (StringLess,	string_less,	"lt",	SWFDEC_AS_ACTION_STRING_LESS,	VIV
 DEFAULT_BINARY (Add2,		add2,		"+",	SWFDEC_AS_ACTION_ADD2,		VIVI_PRECEDENCE_ADD)
 DEFAULT_BINARY (Less2,		less2,		"<",	SWFDEC_AS_ACTION_LESS2,		VIVI_PRECEDENCE_RELATIONAL)
 DEFAULT_BINARY (Equals2,	equals2,	"==",	SWFDEC_AS_ACTION_EQUALS2,	VIVI_PRECEDENCE_EQUALITY)
-//DEFAULT_BINARY (BitwiseAnd,	bitwise_and,	"&",	SWFDEC_AS_ACTION_BIT_AND,	VIVI_PRECEDENCE_BINARY_AND)
-//DEFAULT_BINARY (BitwiseOr,	bitwise_or,	"|",	SWFDEC_AS_ACTION_BIT_OR,	VIVI_PRECEDENCE_BINARY_OR)
-//DEFAULT_BINARY (BitwiseXor,	bitwise_xor,	"^",	SWFDEC_AS_ACTION_BIT_XOR,	VIVI_PRECEDENCE_BINARY_XOR)
-//DEFAULT_BINARY (LeftShift,	left_shift,	"<<",	SWFDEC_AS_ACTION_BIT_LSHIFT,	VIVI_PRECEDENCE_SHIFT)
-//DEFAULT_BINARY (RightShift,	right_shift,	">>",	SWFDEC_AS_ACTION_BIT_RSHIFT,	VIVI_PRECEDENCE_SHIFT)
-//DEFAULT_BINARY (UnsignedRightShift,unsigned_right_shift,">>>",SWFDEC_AS_ACTION_BIT_URSHIFT,VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (BitAnd,		bit_and,	"&",	SWFDEC_AS_ACTION_BIT_AND,	VIVI_PRECEDENCE_BINARY_AND)
+DEFAULT_BINARY (BitOr,		bit_or,		"|",	SWFDEC_AS_ACTION_BIT_OR,	VIVI_PRECEDENCE_BINARY_OR)
+DEFAULT_BINARY (BitXor,		bit_xor,	"^",	SWFDEC_AS_ACTION_BIT_XOR,	VIVI_PRECEDENCE_BINARY_XOR)
+DEFAULT_BINARY (BitLShift,	bit_lshift,	"<<",	SWFDEC_AS_ACTION_BIT_LSHIFT,	VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (BitRShift,	bit_rshift,	">>",	SWFDEC_AS_ACTION_BIT_RSHIFT,	VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (BitURShift,	bit_urshift,	">>>",	SWFDEC_AS_ACTION_BIT_URSHIFT,VIVI_PRECEDENCE_SHIFT)
 DEFAULT_BINARY (StrictEquals,	strict_equals,	"===",	SWFDEC_AS_ACTION_STRICT_EQUALS, VIVI_PRECEDENCE_EQUALITY)
 DEFAULT_BINARY (Greater,	greater,	">",	SWFDEC_AS_ACTION_GREATER,	VIVI_PRECEDENCE_RELATIONAL)
 DEFAULT_BINARY (StringGreater,	string_greater, "gt",	SWFDEC_AS_ACTION_STRING_GREATER,VIVI_PRECEDENCE_RELATIONAL)
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 8105260..7238c33 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -2372,6 +2372,7 @@ parse_assignment_expression (ParseData *data, ViviCodeStatement **statement)
   }
 
   switch ((guint) vivi_parser_scanner_peek_next_token (data->scanner)) {
+    case TOKEN_ASSIGN_MULTIPLY:
       func = vivi_code_multiply_new;
       break;
     case TOKEN_ASSIGN_DIVIDE:
@@ -2386,24 +2387,24 @@ parse_assignment_expression (ParseData *data, ViviCodeStatement **statement)
     case TOKEN_ASSIGN_MINUS:
       func = vivi_code_subtract_new;
       break;
-    //case TOKEN_ASSIGN_SHIFT_LEFT:
-    //  func = vivi_code_left_shift_new;
-    //  break;
-    //case TOKEN_ASSIGN_SHIFT_RIGHT:
-    //  func = vivi_code_right_shift_new;
-    //  break;
-    //case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
-    //  func = vivi_code_unsigned_right_shift_new;
-    //  break;
-    //case TOKEN_ASSIGN_BITWISE_AND:
-    //  func = vivi_code_bitwise_and_new;
-    //  break;
-    //case TOKEN_ASSIGN_BITWISE_OR:
-    //  func = vivi_code_bitwise_or_new;
-    //  break;
-    //case TOKEN_ASSIGN_BITWISE_XOR:
-    //  func = vivi_code_bitwise_xor_new;
-    //  break;
+    case TOKEN_ASSIGN_SHIFT_LEFT:
+      func = vivi_code_bit_lshift_new;
+      break;
+    case TOKEN_ASSIGN_SHIFT_RIGHT:
+      func = vivi_code_bit_rshift_new;
+      break;
+    case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
+      func = vivi_code_bit_urshift_new;
+      break;
+    case TOKEN_ASSIGN_BITWISE_AND:
+      func = vivi_code_bit_and_new;
+      break;
+    case TOKEN_ASSIGN_BITWISE_OR:
+      func = vivi_code_bit_or_new;
+      break;
+    case TOKEN_ASSIGN_BITWISE_XOR:
+      func = vivi_code_bit_xor_new;
+      break;
     case TOKEN_ASSIGN:
       func = NULL;
       break;
commit 4a527914a94f5f524d36b2019f5b1d4cf02bd51d
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 15:02:17 2008 +0300

    Add a test for compiling assignment

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index b792d52..79176a4 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -16,6 +16,8 @@ check-local: $(top_builddir)/vivified/code/vivi-compile
 EXTRA_DIST = \
 	asm_empty.as \
 	asm_empty.as.expect \
+	assignment.as \
+	assignment.as.expect \
 	builtin_statement.as \
 	builtin_statement.as.expect \
 	call_function.as \
diff --git a/vivified/code/test/compiler/assignment.as b/vivified/code/test/compiler/assignment.as
new file mode 100644
index 0000000..5040b77
--- /dev/null
+++ b/vivified/code/test/compiler/assignment.as
@@ -0,0 +1 @@
+a = 1;
diff --git a/vivified/code/test/compiler/assignment.as.expect b/vivified/code/test/compiler/assignment.as.expect
new file mode 100644
index 0000000..2451364
--- /dev/null
+++ b/vivified/code/test/compiler/assignment.as.expect
@@ -0,0 +1,6 @@
+asm {
+  pool "a"
+  push pool 0, 1
+  set_variable
+  end
+}
commit ff1479e6d5edad66a51a13bd1c07043007b43759
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 14:53:31 2008 +0300

    Add a test for compiling labels

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index dc28504..b792d52 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -34,6 +34,8 @@ EXTRA_DIST = \
 	if.as.expect \
 	if_else.as \
 	if_else.as.expect \
+	label.as \
+	label.as.expect \
 	trace.as \
 	trace.as.expect \
 	while.as \
diff --git a/vivified/code/test/compiler/label.as b/vivified/code/test/compiler/label.as
new file mode 100644
index 0000000..8507427
--- /dev/null
+++ b/vivified/code/test/compiler/label.as
@@ -0,0 +1 @@
+hello:
diff --git a/vivified/code/test/compiler/label.as.expect b/vivified/code/test/compiler/label.as.expect
new file mode 100644
index 0000000..bb3700b
--- /dev/null
+++ b/vivified/code/test/compiler/label.as.expect
@@ -0,0 +1,5 @@
+asm {
+
+hello_0001:
+  end
+}
commit 644e72f408e7959d1eb2797436ee16ca83a60227
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 10 14:51:55 2008 +0300

    Fix the parsing of labels

diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 31bb98f..8105260 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -408,14 +408,6 @@ vivi_parser_value_is_left_hand_side (ViviCodeValue *value)
   return VIVI_IS_CODE_GET (value);
 }
 
-static gboolean
-vivi_parser_value_is_identifier (ViviCodeValue *value)
-{
-  if (!VIVI_IS_CODE_GET (value))
-    return FALSE;
-  return VIVI_IS_CODE_CONSTANT (VIVI_CODE_GET (value)->name);
-}
-
 static void
 vivi_parser_start_level (ParseData *data)
 {
@@ -2807,16 +2799,6 @@ parse_expression_statement (ParseData *data)
 
   value = parse_expression (data, &statement);
 
-  // check for label
-  if (statement == NULL && vivi_parser_value_is_identifier (value) &&
-      try_parse_token (data, TOKEN_COLON))
-  {
-    statement = vivi_code_label_new (vivi_code_constant_get_variable_name (
-	  VIVI_CODE_CONSTANT (VIVI_CODE_GET (value)->name)));
-    if (!vivi_parser_add_label (data, VIVI_CODE_LABEL (statement)))
-      vivi_parser_error (data, "Same label name used twice");
-  }
-
   parse_automatic_semicolon (data);
 
   // add a value statement, if the last statement is not an assignment with the
@@ -2847,6 +2829,34 @@ parse_expression_statement (ParseData *data)
 }
 
 static gboolean
+peek_label_statement (ParseData *data)
+{
+  const ViviParserValue *value;
+
+  if (!peek_token (data, TOKEN_IDENTIFIER))
+    return FALSE;
+
+  value = vivi_parser_scanner_get_value (data->scanner, 2);
+
+  return value->token == TOKEN_COLON;
+}
+
+static ViviCodeStatement *
+parse_label_statement (ParseData *data)
+{
+  ViviCodeStatement *statement;
+
+  statement = vivi_code_label_new (parse_identifier_value (data));
+
+  parse_token (data, TOKEN_COLON);
+
+  if (!vivi_parser_add_label (data, VIVI_CODE_LABEL (statement)))
+    vivi_parser_error (data, "Same label name used twice");
+
+  return statement;
+}
+
+static gboolean
 peek_empty_statement (ParseData *data)
 {
   return peek_token (data, TOKEN_SEMICOLON);
@@ -2912,6 +2922,7 @@ static const struct {
   { peek_block, parse_block },
   { peek_variable_statement, parse_variable_statement },
   { peek_empty_statement, parse_empty_statement },
+  { peek_label_statement, parse_label_statement },
   { peek_expression_statement, parse_expression_statement },
   { peek_if_statement, parse_if_statement },
   { peek_iteration_statement, parse_iteration_statement },
commit a55d7894a5b92699e2cc107ea1c23ccda08e775c
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 18:41:48 2008 +0300

    Handle NULL condition and statement when compiling loops

diff --git a/vivified/code/vivi_code_loop.c b/vivified/code/vivi_code_loop.c
index a8a758b..7f1c5db 100644
--- a/vivified/code/vivi_code_loop.c
+++ b/vivified/code/vivi_code_loop.c
@@ -79,32 +79,37 @@ static void
 vivi_code_loop_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeLoop *loop = VIVI_CODE_LOOP (token);
-  ViviCodeLabel *label_start, *label_end;
+  ViviCodeLabel *label_start, *label_end = NULL;
   ViviCodeAsm *code;
 
   label_start = vivi_code_compiler_create_label (compiler, "start");
   vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_start));
 
-  vivi_code_compiler_compile_value (compiler, loop->condition);
+  if (loop->condition) {
+    vivi_code_compiler_compile_value (compiler, loop->condition);
 
-  code = vivi_code_asm_not_new ();
-  vivi_code_compiler_add_code (compiler, code);
-  g_object_unref (code);
+    code = vivi_code_asm_not_new ();
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
 
-  label_end = vivi_code_compiler_create_label (compiler, "end");
-  code = vivi_code_asm_if_new (label_end);
-  vivi_code_compiler_add_code (compiler, code);
-  g_object_unref (code);
+    label_end = vivi_code_compiler_create_label (compiler, "end");
+    code = vivi_code_asm_if_new (label_end);
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
+  }
 
-  vivi_code_compiler_compile_statement (compiler, loop->statement);
+  if (loop->statement)
+    vivi_code_compiler_compile_statement (compiler, loop->statement);
 
   code = vivi_code_asm_jump_new (label_start);
   vivi_code_compiler_add_code (compiler, code);
   g_object_unref (code);
   g_object_unref (label_start);
 
-  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
-  g_object_unref (label_end);
+  if (loop->condition) {
+    vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
+    g_object_unref (label_end);
+  }
 }
 
 static void
commit 97f0bfb5e70e21ac927992e2ddf52da3bd410c08
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 18:41:22 2008 +0300

    Don't crash when compiling do while

diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 722c7f9..31bb98f 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -2733,7 +2733,16 @@ parse_iteration_statement (ParseData *data)
   vivi_code_loop_set_statement (VIVI_CODE_LOOP (statement), loop_statement);
   g_object_unref (loop_statement);
 
-  statement = vivi_parser_join_statements (pre_statement, statement);
+  // can't use join_statements here
+  // because we don't want to put statement inside pre_statement
+  if (pre_statement != NULL) {
+    ViviCodeStatement *block = vivi_code_block_new ();
+    vivi_code_block_add_statement (VIVI_CODE_BLOCK (block), pre_statement);
+    g_object_unref (pre_statement);
+    vivi_code_block_add_statement (VIVI_CODE_BLOCK (block), statement);
+    g_object_unref (statement);
+    statement = block;
+  }
 
   return statement;
 }
commit ea5221f5fc3f2d3707c80795f6b0d2a4428d5226
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 12:17:39 2008 +0300

    Add a test for compiling an empty asm statement

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 517529d..dc28504 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -14,6 +14,8 @@ check-local: $(top_builddir)/vivified/code/vivi-compile
 	fi
 
 EXTRA_DIST = \
+	asm_empty.as \
+	asm_empty.as.expect \
 	builtin_statement.as \
 	builtin_statement.as.expect \
 	call_function.as \
diff --git a/vivified/code/test/compiler/asm_empty.as b/vivified/code/test/compiler/asm_empty.as
new file mode 100644
index 0000000..15bc82b
--- /dev/null
+++ b/vivified/code/test/compiler/asm_empty.as
@@ -0,0 +1,2 @@
+asm {
+}
diff --git a/vivified/code/test/compiler/asm_empty.as.expect b/vivified/code/test/compiler/asm_empty.as.expect
new file mode 100644
index 0000000..08304fb
--- /dev/null
+++ b/vivified/code/test/compiler/asm_empty.as.expect
@@ -0,0 +1,3 @@
+asm {
+  end
+}
commit 4bfa91871a00c797603df5aa884c9c973f543b1e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 12:14:13 2008 +0300

    Add a test for compiling an empty block

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index d505367..517529d 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -22,6 +22,8 @@ EXTRA_DIST = \
 	comment.as.expect \
 	empty.as \
 	empty.as.expect \
+	empty_block.as \
+	empty_block.as.expect \
 	empty_statement.as \
 	empty_statement.as.expect \
 	function_expression.as \
diff --git a/vivified/code/test/compiler/empty_block.as b/vivified/code/test/compiler/empty_block.as
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/vivified/code/test/compiler/empty_block.as
@@ -0,0 +1 @@
+{}
diff --git a/vivified/code/test/compiler/empty_block.as.expect b/vivified/code/test/compiler/empty_block.as.expect
new file mode 100644
index 0000000..08304fb
--- /dev/null
+++ b/vivified/code/test/compiler/empty_block.as.expect
@@ -0,0 +1,3 @@
+asm {
+  end
+}
commit d491b525c86de2e99c4930d7d820dd3ba8739ed4
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 12:13:51 2008 +0300

    Add a test for compiling while

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 83aedb5..d505367 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -31,4 +31,6 @@ EXTRA_DIST = \
 	if_else.as \
 	if_else.as.expect \
 	trace.as \
-	trace.as.expect
+	trace.as.expect \
+	while.as \
+	while.as.expect
diff --git a/vivified/code/test/compiler/while.as b/vivified/code/test/compiler/while.as
new file mode 100644
index 0000000..4b18b49
--- /dev/null
+++ b/vivified/code/test/compiler/while.as
@@ -0,0 +1,3 @@
+while (a) {
+  play ();
+}
diff --git a/vivified/code/test/compiler/while.as.expect b/vivified/code/test/compiler/while.as.expect
new file mode 100644
index 0000000..6661774
--- /dev/null
+++ b/vivified/code/test/compiler/while.as.expect
@@ -0,0 +1,14 @@
+asm {
+  pool "a"
+
+start_0001:
+  push pool 0
+  get_variable
+  not
+  if end_0002
+  play
+  jump start_0001
+
+end_0002:
+  end
+}
commit a14a28d16a32c6c0bccc2cc58864b20f4907e0b4
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 12:08:16 2008 +0300

    Implement compiling of loops

diff --git a/vivified/code/vivi_code_loop.c b/vivified/code/vivi_code_loop.c
index fe6aa76..a8a758b 100644
--- a/vivified/code/vivi_code_loop.c
+++ b/vivified/code/vivi_code_loop.c
@@ -24,6 +24,11 @@
 #include "vivi_code_loop.h"
 #include "vivi_code_printer.h"
 #include "vivi_code_unary.h"
+#include "vivi_code_compiler.h"
+#include "vivi_code_label.h"
+#include "vivi_code_asm_if.h"
+#include "vivi_code_asm_jump.h"
+#include "vivi_code_asm_code_default.h"
 
 G_DEFINE_TYPE (ViviCodeLoop, vivi_code_loop, VIVI_TYPE_CODE_STATEMENT)
 
@@ -71,6 +76,38 @@ vivi_code_loop_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_loop_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeLoop *loop = VIVI_CODE_LOOP (token);
+  ViviCodeLabel *label_start, *label_end;
+  ViviCodeAsm *code;
+
+  label_start = vivi_code_compiler_create_label (compiler, "start");
+  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_start));
+
+  vivi_code_compiler_compile_value (compiler, loop->condition);
+
+  code = vivi_code_asm_not_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  label_end = vivi_code_compiler_create_label (compiler, "end");
+  code = vivi_code_asm_if_new (label_end);
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  vivi_code_compiler_compile_statement (compiler, loop->statement);
+
+  code = vivi_code_asm_jump_new (label_start);
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+  g_object_unref (label_start);
+
+  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_end));
+  g_object_unref (label_end);
+}
+
+static void
 vivi_code_loop_class_init (ViviCodeLoopClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -79,6 +116,7 @@ vivi_code_loop_class_init (ViviCodeLoopClass *klass)
   object_class->dispose = vivi_code_loop_dispose;
 
   token_class->print = vivi_code_loop_print;
+  token_class->compile = vivi_code_loop_compile;
 }
 
 static void
commit 2016d7dcbe82380a3c4f727b80cd19d30ad44593
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:41:32 2008 +0300

    Add a vivi-compile test for function expression

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 79effe4..83aedb5 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -24,6 +24,8 @@ EXTRA_DIST = \
 	empty.as.expect \
 	empty_statement.as \
 	empty_statement.as.expect \
+	function_expression.as \
+	function_expression.as.expect \
 	if.as \
 	if.as.expect \
 	if_else.as \
diff --git a/vivified/code/test/compiler/function_expression.as b/vivified/code/test/compiler/function_expression.as
new file mode 100644
index 0000000..b765b65
--- /dev/null
+++ b/vivified/code/test/compiler/function_expression.as
@@ -0,0 +1,3 @@
+test = function () {
+  play ();
+};
diff --git a/vivified/code/test/compiler/function_expression.as.expect b/vivified/code/test/compiler/function_expression.as.expect
new file mode 100644
index 0000000..ef096a5
--- /dev/null
+++ b/vivified/code/test/compiler/function_expression.as.expect
@@ -0,0 +1,10 @@
+asm {
+  pool "test"
+  push pool 0
+  function2 function_end_0001
+  play
+
+function_end_0001:
+  set_variable
+  end
+}
commit 938dc8b10f7ccc95e1a63dd816903e75aee8d8de
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:33:11 2008 +0300

    Compile if without else as "not; if" not as "if; jump". Add test

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 38348a7..79effe4 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -24,6 +24,8 @@ EXTRA_DIST = \
 	empty.as.expect \
 	empty_statement.as \
 	empty_statement.as.expect \
+	if.as \
+	if.as.expect \
 	if_else.as \
 	if_else.as.expect \
 	trace.as \
diff --git a/vivified/code/test/compiler/if.as b/vivified/code/test/compiler/if.as
new file mode 100644
index 0000000..bbe9b72
--- /dev/null
+++ b/vivified/code/test/compiler/if.as
@@ -0,0 +1,3 @@
+if (a) {
+  play ();
+}
diff --git a/vivified/code/test/compiler/if.as.expect b/vivified/code/test/compiler/if.as.expect
new file mode 100644
index 0000000..86ffa60
--- /dev/null
+++ b/vivified/code/test/compiler/if.as.expect
@@ -0,0 +1,11 @@
+asm {
+  pool "a"
+  push pool 0
+  get_variable
+  not
+  if end_0001
+  play
+
+end_0001:
+  end
+}
diff --git a/vivified/code/vivi_code_if.c b/vivified/code/vivi_code_if.c
index ac02342..a3c82bd 100644
--- a/vivified/code/vivi_code_if.c
+++ b/vivified/code/vivi_code_if.c
@@ -27,6 +27,7 @@
 #include "vivi_code_compiler.h"
 #include "vivi_code_asm_if.h"
 #include "vivi_code_asm_jump.h"
+#include "vivi_code_asm_code_default.h"
 
 G_DEFINE_TYPE (ViviCodeIf, vivi_code_if, VIVI_TYPE_CODE_STATEMENT)
 
@@ -136,21 +137,31 @@ vivi_code_if_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 
   vivi_code_compiler_compile_value (compiler, stmt->condition);
 
-  label_if = vivi_code_compiler_create_label (compiler, "if");
-  code = vivi_code_asm_if_new (label_if);
-  vivi_code_compiler_add_code (compiler, code);
-  g_object_unref (code);
+  if (stmt->else_statement) {
+    label_if = vivi_code_compiler_create_label (compiler, "if");
+    code = vivi_code_asm_if_new (label_if);
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
 
-  if (stmt->else_statement)
     vivi_code_compiler_compile_statement (compiler, stmt->else_statement);
 
-  label_end = vivi_code_compiler_create_label (compiler, "end");
-  code = vivi_code_asm_jump_new (label_end);
-  vivi_code_compiler_add_code (compiler, code);
-  g_object_unref (code);
+    label_end = vivi_code_compiler_create_label (compiler, "end");
+    code = vivi_code_asm_jump_new (label_end);
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
 
-  vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_if));
-  g_object_unref (label_if);
+    vivi_code_compiler_add_code (compiler, VIVI_CODE_ASM (label_if));
+    g_object_unref (label_if);
+  } else {
+    code = vivi_code_asm_not_new ();
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
+
+    label_end = vivi_code_compiler_create_label (compiler, "end");
+    code = vivi_code_asm_if_new (label_end);
+    vivi_code_compiler_add_code (compiler, code);
+    g_object_unref (code);
+  }
 
   vivi_code_compiler_compile_statement (compiler, stmt->if_statement);
 
commit fc46edf5913d00d2c7edf69f1f17da51d53236cb
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:27:16 2008 +0300

    Add a vivi-compile test for if else statement

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index e432751..38348a7 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -24,5 +24,7 @@ EXTRA_DIST = \
 	empty.as.expect \
 	empty_statement.as \
 	empty_statement.as.expect \
+	if_else.as \
+	if_else.as.expect \
 	trace.as \
 	trace.as.expect
diff --git a/vivified/code/test/compiler/if_else.as b/vivified/code/test/compiler/if_else.as
new file mode 100644
index 0000000..6ba49a3
--- /dev/null
+++ b/vivified/code/test/compiler/if_else.as
@@ -0,0 +1,5 @@
+if (a) {
+  play ();
+} else {
+  stop ();
+}
diff --git a/vivified/code/test/compiler/if_else.as.expect b/vivified/code/test/compiler/if_else.as.expect
new file mode 100644
index 0000000..b7d54c5
--- /dev/null
+++ b/vivified/code/test/compiler/if_else.as.expect
@@ -0,0 +1,14 @@
+asm {
+  pool "a"
+  push pool 0
+  get_variable
+  if if_0001
+  stop
+  jump end_0002
+
+if_0001:
+  play
+
+end_0002:
+  end
+}
commit 544da6b8819eba5415cf453224be25276daa2b1b
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:24:18 2008 +0300

    Append a running number for label names in the compiler

diff --git a/vivified/code/vivi_code_compiler.c b/vivified/code/vivi_code_compiler.c
index 689b2e7..a588458 100644
--- a/vivified/code/vivi_code_compiler.c
+++ b/vivified/code/vivi_code_compiler.c
@@ -92,11 +92,19 @@ ViviCodeLabel *
 vivi_code_compiler_create_label (ViviCodeCompiler *compiler,
     const char *prefix)
 {
+  char *name;
+  ViviCodeLabel *label;
+
   g_return_val_if_fail (VIVI_IS_CODE_COMPILER (compiler), NULL);
   g_return_val_if_fail (prefix != NULL, NULL);
 
-  // FIXME
-  return VIVI_CODE_LABEL (vivi_code_label_new (prefix));
+  compiler->num_labels++;
+
+  name = g_strdup_printf ("%s_%04i", prefix, compiler->num_labels);
+  label = VIVI_CODE_LABEL (vivi_code_label_new (name));
+  g_free (name);
+
+  return label;
 }
 
 ViviCodeCompiler *
commit 9281fdbf92889cc825afe36025aaec8942e8a009
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:20:03 2008 +0300

    Require the get_stack_change method for ViviCodeAsm interface

diff --git a/vivified/code/vivi_code_assembler.c b/vivified/code/vivi_code_assembler.c
index 54601b9..86eaffe 100644
--- a/vivified/code/vivi_code_assembler.c
+++ b/vivified/code/vivi_code_assembler.c
@@ -287,12 +287,8 @@ vivi_code_assembler_get_stack_change (ViviCodeAsm *code, int *add, int *remove)
   int add_, remove_;
 
   iface = VIVI_CODE_ASM_GET_INTERFACE (code);
-  if (iface->get_stack_change != NULL) {
-    iface->get_stack_change (code, &add_, &remove_);
-  } else {
-    add_ = 0;
-    remove_ = 0;
-  }
+  g_assert (iface->get_stack_change != NULL);
+  iface->get_stack_change (code, &add_, &remove_);
 
   if (add != NULL)
     *add = add_;
diff --git a/vivified/code/vivi_code_comment.c b/vivified/code/vivi_code_comment.c
index 1efa0b5..5fc1193 100644
--- a/vivified/code/vivi_code_comment.c
+++ b/vivified/code/vivi_code_comment.c
@@ -33,9 +33,17 @@ vivi_code_comment_emit (ViviCodeAsm *code, ViviCodeEmitter *emitter, GError **er
 }
 
 static void
+vivi_code_comment_get_stack_change (ViviCodeAsm *code, int *add, int *remove)
+{
+  *add = 0;
+  *remove = 0;
+}
+
+static void
 vivi_code_comment_asm_init (ViviCodeAsmInterface *iface)
 {
   iface->emit = vivi_code_comment_emit;
+  iface->get_stack_change = vivi_code_comment_get_stack_change;
 }
 
 G_DEFINE_TYPE_WITH_CODE (ViviCodeComment, vivi_code_comment, VIVI_TYPE_CODE_STATEMENT,
diff --git a/vivified/code/vivi_code_label.c b/vivified/code/vivi_code_label.c
index 94eaeb4..2039ebd 100644
--- a/vivified/code/vivi_code_label.c
+++ b/vivified/code/vivi_code_label.c
@@ -38,9 +38,17 @@ vivi_code_label_emit (ViviCodeAsm *code, ViviCodeEmitter *emitter, GError **erro
 }
 
 static void
+vivi_code_label_get_stack_change (ViviCodeAsm *code, int *add, int *remove)
+{
+  *add = 0;
+  *remove = 0;
+}
+
+static void
 vivi_code_label_asm_init (ViviCodeAsmInterface *iface)
 {
   iface->emit = vivi_code_label_emit;
+  iface->get_stack_change = vivi_code_label_get_stack_change;
 }
 
 G_DEFINE_TYPE_WITH_CODE (ViviCodeLabel, vivi_code_label, VIVI_TYPE_CODE_STATEMENT,
commit 8a2203a76b751e4a45e55677ab8e117fbd3d71cc
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 9 11:16:18 2008 +0300

    Fixes/improvements to the compiler

diff --git a/vivified/code/compiler.c b/vivified/code/compiler.c
index 9981267..a41f1b6 100644
--- a/vivified/code/compiler.c
+++ b/vivified/code/compiler.c
@@ -82,7 +82,6 @@ main (int argc, char *argv[])
   ViviCodeStatement *statement;
   ViviCodeCompiler *compiler;
   ViviCodeAssembler *assembler;
-  ViviCodeAsm *code;
   int version = 8;
   int rate = 15;
   char *size_string = NULL;
@@ -183,19 +182,11 @@ main (int argc, char *argv[])
   }
 
   compiler = vivi_code_compiler_new (version);
-  vivi_code_compiler_compile_statement (compiler, statement);
+  vivi_code_compiler_compile_script (compiler, statement);
   g_object_unref (statement);
 
   assembler = g_object_ref (vivi_code_compiler_get_assembler (compiler));
   g_object_unref (compiler);
-  vivi_code_compiler_compile_statement (compiler, statement);
-
-  code = vivi_code_asm_end_new ();
-  vivi_code_assembler_add_code (assembler, code);
-  g_object_unref (code);
-
-  vivi_code_assembler_pool (assembler);
-  vivi_code_assembler_merge_push (assembler);
 
   if (use_asm) {
     ViviCodePrinter *printer = vivi_code_text_printer_new ();
diff --git a/vivified/code/vivi_code_asm.h b/vivified/code/vivi_code_asm.h
index d50fffa..8123a2e 100644
--- a/vivified/code/vivi_code_asm.h
+++ b/vivified/code/vivi_code_asm.h
@@ -42,6 +42,9 @@ struct _ViviCodeAsmInterface {
   gboolean		(* emit)			(ViviCodeAsm *		code,
 							 ViviCodeEmitter *	emitter,
 							 GError **		error);
+  void			(* get_stack_change)		(ViviCodeAsm *		code,
+							 int *			add,
+							 int *			remove);
 };
 
 GType			vivi_code_asm_get_type		(void) G_GNUC_CONST;
diff --git a/vivified/code/vivi_code_asm_code.c b/vivified/code/vivi_code_asm_code.c
index be0f488..4726076 100644
--- a/vivified/code/vivi_code_asm_code.c
+++ b/vivified/code/vivi_code_asm_code.c
@@ -42,9 +42,26 @@ vivi_code_asm_code_emit (ViviCodeAsm *asm_code, ViviCodeEmitter *emitter, GError
 }
 
 static void
+vivi_code_asm_code_get_stack_change (ViviCodeAsm *asm_code, int *add,
+    int *remove)
+{
+  ViviCodeAsmCode *code = VIVI_CODE_ASM_CODE (asm_code);
+  SwfdecAsAction action;
+
+  g_return_if_fail (add != NULL);
+  g_return_if_fail (remove != NULL);
+
+  action = vivi_code_asm_code_get_action (code);
+
+  *add = swfdec_as_actions[action].add;
+  *remove = swfdec_as_actions[action].remove;
+}
+
+static void
 vivi_code_asm_code_asm_init (ViviCodeAsmInterface *iface)
 {
   iface->emit = vivi_code_asm_code_emit;
+  iface->get_stack_change = vivi_code_asm_code_get_stack_change;
 }
 
 G_DEFINE_TYPE_WITH_CODE (ViviCodeAsmCode, vivi_code_asm_code, VIVI_TYPE_CODE_TOKEN,
@@ -71,19 +88,3 @@ vivi_code_asm_code_get_action (ViviCodeAsmCode *code)
 
   return klass->bytecode;
 }
-
-int
-vivi_code_asm_code_get_stack_add (ViviCodeAsmCode *code)
-{
-  g_return_val_if_fail (VIVI_IS_CODE_ASM_CODE (code), -1);
-
-  return swfdec_as_actions[vivi_code_asm_code_get_action (code)].add;
-}
-
-int
-vivi_code_asm_code_get_stack_remove (ViviCodeAsmCode *code)
-{
-  g_return_val_if_fail (VIVI_IS_CODE_ASM_CODE (code), -1);
-
-  return swfdec_as_actions[vivi_code_asm_code_get_action (code)].remove;
-}
diff --git a/vivified/code/vivi_code_asm_code.h b/vivified/code/vivi_code_asm_code.h
index 273c803..575f369 100644
--- a/vivified/code/vivi_code_asm_code.h
+++ b/vivified/code/vivi_code_asm_code.h
@@ -53,8 +53,6 @@ struct _ViviCodeAsmCodeClass
 GType			vivi_code_asm_code_get_type		(void);
 
 SwfdecAsAction		vivi_code_asm_code_get_action		(ViviCodeAsmCode *	code);
-int			vivi_code_asm_code_get_stack_add	(ViviCodeAsmCode *	code);
-int			vivi_code_asm_code_get_stack_remove	(ViviCodeAsmCode *	code);
 
 
 G_END_DECLS
diff --git a/vivified/code/vivi_code_assembler.c b/vivified/code/vivi_code_assembler.c
index 6558f37..54601b9 100644
--- a/vivified/code/vivi_code_assembler.c
+++ b/vivified/code/vivi_code_assembler.c
@@ -280,11 +280,32 @@ vivi_code_assembler_pool (ViviCodeAssembler *assembler)
   return TRUE;
 }
 
+static void
+vivi_code_assembler_get_stack_change (ViviCodeAsm *code, int *add, int *remove)
+{
+  ViviCodeAsmInterface *iface;
+  int add_, remove_;
+
+  iface = VIVI_CODE_ASM_GET_INTERFACE (code);
+  if (iface->get_stack_change != NULL) {
+    iface->get_stack_change (code, &add_, &remove_);
+  } else {
+    add_ = 0;
+    remove_ = 0;
+  }
+
+  if (add != NULL)
+    *add = add_;
+  if (remove != NULL)
+    *remove = remove_;
+}
+
 void
 vivi_code_assembler_merge_push (ViviCodeAssembler *assembler)
 {
   ViviCodeAsmPush *previous;
   guint i, j, depth;
+  int add, remove;
 
   depth = 0;
   previous = NULL;
@@ -305,12 +326,11 @@ vivi_code_assembler_merge_push (ViviCodeAssembler *assembler)
       }
     } else {
       if (previous != NULL) {
-	if (vivi_code_asm_code_get_stack_add (VIVI_CODE_ASM_CODE (
-		g_ptr_array_index (assembler->codes, i))) != 0) {
+	vivi_code_assembler_get_stack_change (VIVI_CODE_ASM (
+		g_ptr_array_index (assembler->codes, i)), &add, &remove);
+	if (add != 0) {
 	  previous = NULL;
 	} else {
-	  int remove = vivi_code_asm_code_get_stack_remove (VIVI_CODE_ASM_CODE (
-		g_ptr_array_index (assembler->codes, i)));
 	  if (remove == -1) {
 	    previous = NULL;
 	  } else {
diff --git a/vivified/code/vivi_code_compiler.c b/vivified/code/vivi_code_compiler.c
index 1947090..689b2e7 100644
--- a/vivified/code/vivi_code_compiler.c
+++ b/vivified/code/vivi_code_compiler.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "vivi_code_compiler.h"
+#include "vivi_code_asm_code_default.h"
 
 G_DEFINE_TYPE (ViviCodeCompiler, vivi_code_compiler, G_TYPE_OBJECT)
 
@@ -60,6 +61,25 @@ vivi_code_compiler_compile_token (ViviCodeCompiler *compiler,
 }
 
 void
+vivi_code_compiler_compile_script (ViviCodeCompiler *compiler,
+    ViviCodeStatement *statement)
+{
+  ViviCodeAsm *code;
+
+  g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
+  g_return_if_fail (VIVI_IS_CODE_STATEMENT (statement));
+
+  vivi_code_compiler_compile_statement (compiler, statement);
+
+  code = vivi_code_asm_end_new ();
+  vivi_code_compiler_add_code (compiler, code);
+  g_object_unref (code);
+
+  vivi_code_assembler_pool (compiler->assembler);
+  vivi_code_assembler_merge_push (compiler->assembler);
+}
+
+void
 vivi_code_compiler_add_code (ViviCodeCompiler *compiler, ViviCodeAsm *code)
 {
   g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
diff --git a/vivified/code/vivi_code_compiler.h b/vivified/code/vivi_code_compiler.h
index 19bfa47..5b7e83f 100644
--- a/vivified/code/vivi_code_compiler.h
+++ b/vivified/code/vivi_code_compiler.h
@@ -60,6 +60,8 @@ ViviCodeCompiler *	vivi_code_compiler_new			(guint			version);
 #define vivi_code_compiler_compile_statement(c,s) vivi_code_compiler_compile_token((c), VIVI_CODE_TOKEN((s)))
 void			vivi_code_compiler_compile_token	(ViviCodeCompiler *	compiler,
 								 ViviCodeToken *	token);
+void			vivi_code_compiler_compile_script	(ViviCodeCompiler *	compiler,
+								 ViviCodeStatement *	statement);
 
 void			vivi_code_compiler_add_code		(ViviCodeCompiler	*compiler,
 								 ViviCodeAsm		*code);


More information about the Swfdec-commits mailing list