[Swfdec-commits] 13 commits - vivified/code

Pekka Lampila medar at kemper.freedesktop.org
Thu Apr 17 05:04:29 PDT 2008


 vivified/code/Makefile.am                                 |   26 
 vivified/code/vivi_code_builtin_call.c                    |   63 ++
 vivified/code/vivi_code_builtin_call.h                    |   57 +
 vivified/code/vivi_code_builtin_statement.c               |   66 ++
 vivified/code/vivi_code_builtin_statement.h               |   57 +
 vivified/code/vivi_code_builtin_statement_default.c       |   52 +
 vivified/code/vivi_code_builtin_statement_default.h       |   41 +
 vivified/code/vivi_code_builtin_value_call.c              |  109 +++
 vivified/code/vivi_code_builtin_value_call.h              |   60 +
 vivified/code/vivi_code_builtin_value_call_default.c      |   58 +
 vivified/code/vivi_code_builtin_value_call_default.h      |   42 +
 vivified/code/vivi_code_builtin_value_statement.c         |  115 +++
 vivified/code/vivi_code_builtin_value_statement.h         |   60 +
 vivified/code/vivi_code_builtin_value_statement_default.c |   58 +
 vivified/code/vivi_code_builtin_value_statement_default.h |   42 +
 vivified/code/vivi_code_concat.c                          |   98 +++
 vivified/code/vivi_code_concat.h                          |   58 +
 vivified/code/vivi_code_defaults.h                        |   42 +
 vivified/code/vivi_code_get_timer.c                       |   48 +
 vivified/code/vivi_code_get_timer.h                       |   36 +
 vivified/code/vivi_code_get_url.c                         |    2 
 vivified/code/vivi_code_play.c                            |   46 -
 vivified/code/vivi_code_play.h                            |   55 -
 vivified/code/vivi_code_special_statement.c               |   81 --
 vivified/code/vivi_code_special_statement.h               |   60 -
 vivified/code/vivi_code_substring.c                       |  106 +++
 vivified/code/vivi_code_substring.h                       |   60 +
 vivified/code/vivi_code_trace.c                           |   79 --
 vivified/code/vivi_code_trace.h                           |   58 -
 vivified/code/vivi_decompiler.c                           |    2 
 vivified/code/vivi_parser.c                               |  424 ++++++++++----
 vivified/code/vivi_parser_scanner_lex.l                   |    2 
 32 files changed, 1684 insertions(+), 479 deletions(-)

New commits:
commit 7ee74466641d40f42c7988cc62c95a95226f481b
Merge: d50c2da... 2cd2514...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Apr 17 14:52:10 2008 +0300

    Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec
    
    Conflicts:
    
    	vivified/code/vivi_code_defaults.h

diff --cc vivified/code/vivi_code_defaults.h
index 1abdada,10f1045..62c62d8
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@@ -52,44 -51,114 +52,155 @@@ DEFAULT_BINARY (Or,		or,		"||",	???
  
  #undef DEFAULT_BINARY
  
 +#ifndef DEFAULT_BUILTIN_STATEMENT
 +#define DEFAULT_BUILTIN_STATEMENT(CapsName, underscore_name, function_name, bytecode)
 +#endif
 +
 +DEFAULT_BUILTIN_STATEMENT (NextFrame,		next_frame,	"nextFrame",		SWFDEC_AS_ACTION_NEXT_FRAME)
 +DEFAULT_BUILTIN_STATEMENT (Play,		play,		"play",			SWFDEC_AS_ACTION_PLAY)
 +DEFAULT_BUILTIN_STATEMENT (PreviousFrame,	previous_frame,	"prevFrame",		SWFDEC_AS_ACTION_PREVIOUS_FRAME)
 +DEFAULT_BUILTIN_STATEMENT (Stop,		stop,		"stop",			SWFDEC_AS_ACTION_STOP)
 +DEFAULT_BUILTIN_STATEMENT (StopDrag,		stop_drag,	"stopDrag",		SWFDEC_AS_ACTION_END_DRAG)
 +DEFAULT_BUILTIN_STATEMENT (StopSounds,		stop_sounds,	"stopSounds",		SWFDEC_AS_ACTION_STOP_SOUNDS)
 +DEFAULT_BUILTIN_STATEMENT (ToggleQuality,	toggle_quality,	"toggleQuality",	SWFDEC_AS_ACTION_TOGGLE_QUALITY)
 +
 +#undef DEFAULT_BUILTIN_STATEMENT
 +
 +#ifndef DEFAULT_BUILTIN_VALUE_STATEMENT
 +#define DEFAULT_BUILTIN_VALUE_STATEMENT(CapsName, underscore_name, function_name, bytecode)
 +#endif
 +
 +//DEFAULT_BUILTIN_VALUE_STATEMENT (CallFrame,		call_frame,		"callFrame",		SWFDEC_AS_ACTION_CALL)
 +//DEFAULT_BUILTIN_VALUE_STATEMENT (GotoAndPlay,		goto_and_play,		"gotoAndPlay",		???)
 +//DEFAULT_BUILTIN_VALUE_STATEMENT (GotoAndStop,		goto_and_stop,		"gotoAndStop",		???)
 +DEFAULT_BUILTIN_VALUE_STATEMENT (RemoveMovieClip,	remove_movie_clip,	"removeMovieClip",	SWFDEC_AS_ACTION_REMOVE_SPRITE)
 +DEFAULT_BUILTIN_VALUE_STATEMENT (SetTarget,		set_target,		"setTarget",		SWFDEC_AS_ACTION_SET_TARGET2)
 +DEFAULT_BUILTIN_VALUE_STATEMENT (Trace,			trace,			"trace",		SWFDEC_AS_ACTION_TRACE)
 +
 +#undef DEFAULT_BUILTIN_VALUE_STATEMENT
 +
 +#ifndef DEFAULT_BUILTIN_VALUE_CALL
 +#define DEFAULT_BUILTIN_VALUE_CALL(CapsName, underscore_name, function_name, bytecode)
 +#endif
 +
 +DEFAULT_BUILTIN_VALUE_CALL (Chr,	chr,		"chr",		SWFDEC_AS_ACTION_ASCII_TO_CHAR)
 +DEFAULT_BUILTIN_VALUE_CALL (Eval,	eval,		"eval",		SWFDEC_AS_ACTION_GET_VARIABLE)
 +DEFAULT_BUILTIN_VALUE_CALL (Int,	int,		"int",		SWFDEC_AS_ACTION_TO_INTEGER)
 +DEFAULT_BUILTIN_VALUE_CALL (Length,	length,		"length",	SWFDEC_AS_ACTION_STRING_LENGTH)
 +DEFAULT_BUILTIN_VALUE_CALL (Ord,	ord,		"ord",		SWFDEC_AS_ACTION_CHAR_TO_ASCII)
 +DEFAULT_BUILTIN_VALUE_CALL (Random,	random,		"random",	SWFDEC_AS_ACTION_RANDOM)
 +DEFAULT_BUILTIN_VALUE_CALL (TargetPath,	target_path,	"targetPath",	SWFDEC_AS_ACTION_TARGET_PATH)
 +DEFAULT_BUILTIN_VALUE_CALL (TypeOf,	type_of,	"typeOf",	SWFDEC_AS_ACTION_TYPE_OF)
 +
 +#undef DEFAULT_BUILTIN_VALUE_CALL
+ 
+ #ifndef DEFAULT_ASM
+ #define DEFAULT_ASM(CapsName, underscore_name, bytecode)
+ #endif
+ 
+ DEFAULT_ASM (End, end, SWFDEC_AS_ACTION_END)
+ DEFAULT_ASM (NextFrame, next_frame, SWFDEC_AS_ACTION_NEXT_FRAME)
+ DEFAULT_ASM (PreviousFrame, previous_frame, SWFDEC_AS_ACTION_PREVIOUS_FRAME)
+ DEFAULT_ASM (Play, play, SWFDEC_AS_ACTION_PLAY)
+ DEFAULT_ASM (Stop, stop, SWFDEC_AS_ACTION_STOP)
+ DEFAULT_ASM (ToggleQuality, toggle_quality, SWFDEC_AS_ACTION_TOGGLE_QUALITY)
+ DEFAULT_ASM (StopSounds, stop_sounds, SWFDEC_AS_ACTION_STOP_SOUNDS)
+ DEFAULT_ASM (Add, add, SWFDEC_AS_ACTION_ADD)
+ DEFAULT_ASM (Subtract, subtract, SWFDEC_AS_ACTION_SUBTRACT)
+ DEFAULT_ASM (Multiply, multiply, SWFDEC_AS_ACTION_MULTIPLY)
+ DEFAULT_ASM (Divide, divide, SWFDEC_AS_ACTION_DIVIDE)
+ DEFAULT_ASM (Equals, equals, SWFDEC_AS_ACTION_EQUALS)
+ DEFAULT_ASM (Less, less, SWFDEC_AS_ACTION_LESS)
+ DEFAULT_ASM (And, and, SWFDEC_AS_ACTION_AND)
+ DEFAULT_ASM (Or, or, SWFDEC_AS_ACTION_OR)
+ DEFAULT_ASM (Not, not, SWFDEC_AS_ACTION_NOT)
+ DEFAULT_ASM (StringEquals, string_equals, SWFDEC_AS_ACTION_STRING_EQUALS)
+ DEFAULT_ASM (StringLength, string_length, SWFDEC_AS_ACTION_STRING_LENGTH)
+ DEFAULT_ASM (StringExtract, string_extract, SWFDEC_AS_ACTION_STRING_EXTRACT)
+ DEFAULT_ASM (Pop, pop, SWFDEC_AS_ACTION_POP)
+ DEFAULT_ASM (ToInteger, to_integer, SWFDEC_AS_ACTION_TO_INTEGER)
+ DEFAULT_ASM (GetVariable, get_variable, SWFDEC_AS_ACTION_GET_VARIABLE)
+ DEFAULT_ASM (SetVariable, set_variable, SWFDEC_AS_ACTION_SET_VARIABLE)
+ DEFAULT_ASM (SetTarget2, set_target2, SWFDEC_AS_ACTION_SET_TARGET2)
+ DEFAULT_ASM (StringAdd, string_add, SWFDEC_AS_ACTION_STRING_ADD)
+ DEFAULT_ASM (GetProperty, get_property, SWFDEC_AS_ACTION_GET_PROPERTY)
+ DEFAULT_ASM (SetProperty, set_property, SWFDEC_AS_ACTION_SET_PROPERTY)
+ DEFAULT_ASM (CloneSprite, clone_sprite, SWFDEC_AS_ACTION_CLONE_SPRITE)
+ DEFAULT_ASM (RemoveSprite, remove_sprite, SWFDEC_AS_ACTION_REMOVE_SPRITE)
+ DEFAULT_ASM (Trace, trace, SWFDEC_AS_ACTION_TRACE)
+ DEFAULT_ASM (StartDrag, start_drag, SWFDEC_AS_ACTION_START_DRAG)
+ DEFAULT_ASM (EndDrag, end_drag, SWFDEC_AS_ACTION_END_DRAG)
+ DEFAULT_ASM (StringLess, string_less, SWFDEC_AS_ACTION_STRING_LESS)
+ DEFAULT_ASM (Throw, throw, SWFDEC_AS_ACTION_THROW)
+ DEFAULT_ASM (Cast, cast, SWFDEC_AS_ACTION_CAST)
+ DEFAULT_ASM (Implements, implements, SWFDEC_AS_ACTION_IMPLEMENTS)
+ DEFAULT_ASM (Random, random, SWFDEC_AS_ACTION_RANDOM)
+ DEFAULT_ASM (MbStringLength, mb_string_length, SWFDEC_AS_ACTION_MB_STRING_LENGTH)
+ DEFAULT_ASM (CharToAscii, char_to_ascii, SWFDEC_AS_ACTION_CHAR_TO_ASCII)
+ DEFAULT_ASM (AsciiToChar, ascii_to_char, SWFDEC_AS_ACTION_ASCII_TO_CHAR)
+ DEFAULT_ASM (GetTime, get_time, SWFDEC_AS_ACTION_GET_TIME)
+ DEFAULT_ASM (MbStringExtract, mb_string_extract, SWFDEC_AS_ACTION_MB_STRING_EXTRACT)
+ DEFAULT_ASM (MbCharToAscii, mb_char_to_ascii, SWFDEC_AS_ACTION_MB_CHAR_TO_ASCII)
+ DEFAULT_ASM (MbAsciiToChar, mb_ascii_to_char, SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR)
+ DEFAULT_ASM (Delete, delete, SWFDEC_AS_ACTION_DELETE)
+ DEFAULT_ASM (Delete2, delete2, SWFDEC_AS_ACTION_DELETE2)
+ DEFAULT_ASM (DefineLocal, define_local, SWFDEC_AS_ACTION_DEFINE_LOCAL)
+ DEFAULT_ASM (CallFunction, call_function, SWFDEC_AS_ACTION_CALL_FUNCTION)
+ DEFAULT_ASM (Return, return, SWFDEC_AS_ACTION_RETURN)
+ DEFAULT_ASM (Modulo, modulo, SWFDEC_AS_ACTION_MODULO)
+ DEFAULT_ASM (NewObject, new_object, SWFDEC_AS_ACTION_NEW_OBJECT)
+ DEFAULT_ASM (DefineLocal2, define_local2, SWFDEC_AS_ACTION_DEFINE_LOCAL2)
+ DEFAULT_ASM (InitArray, init_array, SWFDEC_AS_ACTION_INIT_ARRAY)
+ DEFAULT_ASM (InitObject, init_object, SWFDEC_AS_ACTION_INIT_OBJECT)
+ DEFAULT_ASM (TypeOf, type_of, SWFDEC_AS_ACTION_TYPE_OF)
+ DEFAULT_ASM (TargetPath, target_path, SWFDEC_AS_ACTION_TARGET_PATH)
+ DEFAULT_ASM (Enumerate, enumerate, SWFDEC_AS_ACTION_ENUMERATE)
+ DEFAULT_ASM (Add2, add2, SWFDEC_AS_ACTION_ADD2)
+ DEFAULT_ASM (Less2, less2, SWFDEC_AS_ACTION_LESS2)
+ DEFAULT_ASM (Equals2, equals2, SWFDEC_AS_ACTION_EQUALS2)
+ DEFAULT_ASM (ToNumber, to_number, SWFDEC_AS_ACTION_TO_NUMBER)
+ DEFAULT_ASM (ToString, to_string, SWFDEC_AS_ACTION_TO_STRING)
+ DEFAULT_ASM (PushDuplicate, push_duplicate, SWFDEC_AS_ACTION_PUSH_DUPLICATE)
+ DEFAULT_ASM (Swap, swap, SWFDEC_AS_ACTION_SWAP)
+ DEFAULT_ASM (GetMember, get_member, SWFDEC_AS_ACTION_GET_MEMBER)
+ DEFAULT_ASM (SetMember, set_member, SWFDEC_AS_ACTION_SET_MEMBER)
+ DEFAULT_ASM (Increment, increment, SWFDEC_AS_ACTION_INCREMENT)
+ DEFAULT_ASM (Decrement, decrement, SWFDEC_AS_ACTION_DECREMENT)
+ DEFAULT_ASM (CallMethod, call_method, SWFDEC_AS_ACTION_CALL_METHOD)
+ DEFAULT_ASM (NewMethod, new_method, SWFDEC_AS_ACTION_NEW_METHOD)
+ DEFAULT_ASM (InstanceOf, instance_of, SWFDEC_AS_ACTION_INSTANCE_OF)
+ DEFAULT_ASM (Enumerate2, enumerate2, SWFDEC_AS_ACTION_ENUMERATE2)
+ DEFAULT_ASM (Breakpoint, breakpoint, SWFDEC_AS_ACTION_BREAKPOINT)
+ DEFAULT_ASM (BitAnd, bit_and, SWFDEC_AS_ACTION_BIT_AND)
+ DEFAULT_ASM (BitOr, bit_or, SWFDEC_AS_ACTION_BIT_OR)
+ DEFAULT_ASM (BitXor, bit_xor, SWFDEC_AS_ACTION_BIT_XOR)
+ DEFAULT_ASM (BitLshift, bit_lshift, SWFDEC_AS_ACTION_BIT_LSHIFT)
+ DEFAULT_ASM (BitRshift, bit_rshift, SWFDEC_AS_ACTION_BIT_RSHIFT)
+ DEFAULT_ASM (BitUrshift, bit_urshift, SWFDEC_AS_ACTION_BIT_URSHIFT)
+ DEFAULT_ASM (StrictEquals, strict_equals, SWFDEC_AS_ACTION_STRICT_EQUALS)
+ DEFAULT_ASM (Greater, greater, SWFDEC_AS_ACTION_GREATER)
+ DEFAULT_ASM (StringGreater, string_greater, SWFDEC_AS_ACTION_STRING_GREATER)
+ DEFAULT_ASM (Extends, extends, SWFDEC_AS_ACTION_EXTENDS)
+ #if 0
+ DEFAULT_ASM (GotoFrame, goto_frame, SWFDEC_AS_ACTION_GOTO_FRAME)
+ DEFAULT_ASM (GetUrl, get_url, SWFDEC_AS_ACTION_GET_URL)
+ DEFAULT_ASM (StoreRegister, store_register, SWFDEC_AS_ACTION_STORE_REGISTER)
+ DEFAULT_ASM (ConstantPool, constant_pool, SWFDEC_AS_ACTION_CONSTANT_POOL)
+ DEFAULT_ASM (StrictMode, strict_mode, SWFDEC_AS_ACTION_STRICT_MODE)
+ DEFAULT_ASM (WaitForFrame, wait_for_frame, SWFDEC_AS_ACTION_WAIT_FOR_FRAME)
+ DEFAULT_ASM (SetTarget, set_target, SWFDEC_AS_ACTION_SET_TARGET)
+ DEFAULT_ASM (GotoLabel, goto_label, SWFDEC_AS_ACTION_GOTO_LABEL)
+ DEFAULT_ASM (WaitForFrame2, wait_for_frame2, SWFDEC_AS_ACTION_WAIT_FOR_FRAME2)
+ DEFAULT_ASM (DefineFunction2, define_function2, SWFDEC_AS_ACTION_DEFINE_FUNCTION2)
+ DEFAULT_ASM (Try, try, SWFDEC_AS_ACTION_TRY)
+ DEFAULT_ASM (With, with, SWFDEC_AS_ACTION_WITH)
+ DEFAULT_ASM (Push, push, SWFDEC_AS_ACTION_PUSH)
+ DEFAULT_ASM (Jump, jump, SWFDEC_AS_ACTION_JUMP)
+ DEFAULT_ASM (GetUrl2, get_url2, SWFDEC_AS_ACTION_GET_URL2)
+ DEFAULT_ASM (DefineFunction, define_function, SWFDEC_AS_ACTION_DEFINE_FUNCTION)
+ DEFAULT_ASM (If, if, SWFDEC_AS_ACTION_IF)
+ DEFAULT_ASM (Call, call, SWFDEC_AS_ACTION_CALL)
+ DEFAULT_ASM (GotoFrame2, goto_frame2, SWFDEC_AS_ACTION_GOTO_FRAME2)
+ #endif
+ 
+ #undef DEFAULT_ASM
commit d50c2da24c69fe6c6c931e5e55629a370b16e927
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Apr 17 10:03:38 2008 +0300

    Implement the parsing of getURL2 actions

diff --git a/vivified/code/vivi_code_get_url.c b/vivified/code/vivi_code_get_url.c
index d9723c4..33a74f3 100644
--- a/vivified/code/vivi_code_get_url.c
+++ b/vivified/code/vivi_code_get_url.c
@@ -67,8 +67,8 @@ vivi_code_get_url_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   ViviCodeGetUrl *url = VIVI_CODE_GET_URL (token);
   guint bits;
 
-  vivi_code_compiler_compile_value (compiler, url->target);
   vivi_code_compiler_compile_value (compiler, url->url);
+  vivi_code_compiler_compile_value (compiler, url->target);
 
   vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_GET_URL2);
 
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 96eef42..b73d7c4 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -915,30 +915,122 @@ parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
 
 // builtin functions
 
-/*static void
-parse_url_method (ParseData *data, ViviCodeValue **value)
+static void
+parse_get_url2 (ParseData *data, ViviCodeStatement **statement,
+    gboolean require_two, gboolean level, gboolean internal,
+    gboolean variables)
 {
-  if (peek_identifier (data)) {
-    ViviCodeValue *identifier;
-    const char *method;
+  ViviCodeValue *url, *target;
+  ViviCodeStatement *expression_statement;
+  SwfdecLoaderRequest method;
 
-    parse_identifier (data, &identifier);
-    // FIXME
-    method = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
-	  VIVI_CODE_GET (identifier)->name));
-    if (g_ascii_strcasecmp (method, "GET") != 0 &&
-	g_ascii_strcasecmp (method, "POST") != 0)
-      vivi_parser_error (data, "Invalid URL method: %s\n", method);
-    g_object_unref (identifier);
-    *value = vivi_code_constant_new_string (method);
-  } else if (peek_string_literal (data)) {
-    parse_string_literal (data, value);
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  parse_assignment_expression (data, &url, statement);
+
+  if (require_two || peek_token (data, TOKEN_COMMA)) {
+    parse_token (data, TOKEN_COMMA);
+
+    // target
+    if (!level) {
+      parse_assignment_expression (data, &target, &expression_statement);
+      *statement =
+	vivi_parser_join_statements (*statement, expression_statement);
+    } else {
+      // FIXME: integer only
+      if (peek_numeric_literal (data)) {
+	char *level_name;
+	parse_numeric_literal (data, &target);
+	level_name = g_strdup_printf ("_level%i",
+	    (int)vivi_code_constant_get_number (VIVI_CODE_CONSTANT (target)));
+	g_object_unref (target);
+	target = vivi_code_constant_new_string (level_name);
+	g_free (level_name);
+      } else {
+	// TODO
+	parse_assignment_expression (data, &target, &expression_statement);
+	*statement =
+	  vivi_parser_join_statements (*statement, expression_statement);
+      }
+    }
+
+    // method
+    if (peek_token (data, TOKEN_COMMA)) {
+      parse_token (data, TOKEN_COMMA);
+
+      if (peek_identifier (data) || peek_string_literal (data)) {
+	ViviCodeValue *identifier;
+	const char *method_string;
+
+	if (peek_identifier (data)) {
+	  parse_identifier (data, &identifier);
+	  method_string = vivi_code_constant_get_variable_name (
+	      VIVI_CODE_CONSTANT (VIVI_CODE_GET (identifier)->name));
+	} else {
+	  parse_string_literal (data, &identifier);
+	  method_string = vivi_code_constant_get_variable_name (
+	      VIVI_CODE_CONSTANT (identifier));
+	}
+	// FIXME
+	if (g_ascii_strcasecmp (method_string, "GET") == 0) {
+	  method = SWFDEC_LOADER_REQUEST_GET;
+	} else if (g_ascii_strcasecmp (method_string, "POST") == 0) {
+	  method = SWFDEC_LOADER_REQUEST_POST;
+	} else {
+	  method = SWFDEC_LOADER_REQUEST_DEFAULT;
+	  // only for identifiers?
+	  vivi_parser_error (data, "Invalid URL method: %s\n", method_string);
+	}
+	g_object_unref (identifier);
+      } else {
+	vivi_parser_error_unexpected_or (data, TOKEN_IDENTIFIER, TOKEN_STRING,
+	    TOKEN_NONE);
+	method = SWFDEC_LOADER_REQUEST_DEFAULT;
+      }
+    } else {
+      method = SWFDEC_LOADER_REQUEST_DEFAULT;
+    }
   } else {
-    vivi_parser_error_unexpected_or (data, TOKEN_IDENTIFIER, TOKEN_STRING,
-	TOKEN_NONE);
-    *value = vivi_code_constant_new_string ("DEFAULT");
+    target = vivi_code_constant_new_undefined ();
+    method = SWFDEC_LOADER_REQUEST_DEFAULT;
   }
-}*/
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  *statement = vivi_code_get_url_new (target, url, method, internal, variables);
+  g_object_unref (target);
+  g_object_unref (url);
+}
+
+static void
+parse_get_url (ParseData *data, ViviCodeStatement **statement)
+{
+  parse_get_url2 (data, statement, FALSE, FALSE, FALSE, FALSE);
+}
+
+static void
+parse_load_movie (ParseData *data, ViviCodeStatement **statement)
+{
+  parse_get_url2 (data, statement, TRUE, FALSE, TRUE, FALSE);
+}
+
+static void
+parse_load_movie_num (ParseData *data, ViviCodeStatement **statement)
+{
+  parse_get_url2 (data, statement, TRUE, TRUE, TRUE, FALSE);
+}
+
+static void
+parse_load_variables (ParseData *data, ViviCodeStatement **statement)
+{
+  parse_get_url2 (data, statement, TRUE, FALSE, FALSE, TRUE);
+}
+
+static void
+parse_load_variables_num (ParseData *data, ViviCodeStatement **statement)
+{
+  parse_get_url2 (data, statement, TRUE, TRUE, FALSE, TRUE);
+}
 
 static void
 parse_concat (ParseData *data, ViviCodeValue **value,
@@ -1024,13 +1116,13 @@ static const BuiltinStatement builtin_statements[] = {
   //{ "callFrame",          NULL, vivi_code_call_frame_new, NULL },
   //{ "duplicateMovieClip", NULL, NULL, parse_duplicate_movie_clip },
   //{ "getURL1",            NULL, NULL, parse_get_url1 },
-  //{ "getURL",             NULL, NULL, parse_get_url },
+  { "getURL",             NULL, NULL, parse_get_url },
   //{ "gotoAndPlay",        NULL, vivi_code_goto_and_play_new, NULL },
   //{ "gotoAndStop",        NULL, vivi_code_goto_and_stop_new, NULL },
-  //{ "loadMovie",          NULL, NULL, parse_load_movie },
-  //{ "loadMovieNum",       NULL, NULL, parse_load_movie_num },
-  //{ "loadVariables",      NULL, NULL, parse_load_variables },
-  //{ "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
+  { "loadMovie",          NULL, NULL, parse_load_movie },
+  { "loadMovieNum",       NULL, NULL, parse_load_movie_num },
+  { "loadVariables",      NULL, NULL, parse_load_variables },
+  { "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
   { "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
   { "play",               vivi_code_play_new, NULL, NULL },
   { "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
commit 491b1413ac5311b43e1f96ddb98df959247dd3f4
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Apr 16 16:46:47 2008 +0300

    Allow compiling the built-in concat function

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index e255352..5982db1 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -31,6 +31,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_builtin_value_statement_default.c \
 	vivi_code_comment.c \
 	vivi_code_compiler.c \
+	vivi_code_concat.c \
 	vivi_code_constant.c \
 	vivi_code_continue.c \
 	vivi_code_function.c \
@@ -82,6 +83,7 @@ noinst_HEADERS = \
 	vivi_code_builtin_value_statement_default.h \
 	vivi_code_comment.h \
 	vivi_code_compiler.h \
+	vivi_code_concat.h \
 	vivi_code_constant.h \
 	vivi_code_continue.h \
 	vivi_code_defaults.h \
diff --git a/vivified/code/vivi_code_concat.c b/vivified/code/vivi_code_concat.c
new file mode 100644
index 0000000..4f29155
--- /dev/null
+++ b/vivified/code/vivi_code_concat.c
@@ -0,0 +1,98 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_concat.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_TYPE (ViviCodeConcat, vivi_code_concat, VIVI_TYPE_CODE_VALUE)
+
+static void
+vivi_code_concat_dispose (GObject *object)
+{
+  ViviCodeConcat *concat = VIVI_CODE_CONCAT (object);
+
+  g_object_unref (concat->first);
+  g_object_unref (concat->second);
+
+  G_OBJECT_CLASS (vivi_code_concat_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_concat_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+  ViviCodeConcat *concat = VIVI_CODE_CONCAT (token);
+
+  vivi_code_printer_print (printer, "concat (");
+  vivi_code_printer_print_value (printer, concat->first,
+      VIVI_PRECEDENCE_COMMA);
+  vivi_code_printer_print (printer, ", ");
+  vivi_code_printer_print_value (printer, concat->second,
+      VIVI_PRECEDENCE_COMMA);
+  vivi_code_printer_print (printer, ");");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_concat_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeConcat *concat = VIVI_CODE_CONCAT (token);
+
+  vivi_code_compiler_compile_value (compiler, concat->first);
+  vivi_code_compiler_compile_value (compiler, concat->second);
+
+  vivi_code_compiler_write_empty_action (compiler,
+      SWFDEC_AS_ACTION_STRING_ADD);
+}
+
+static void
+vivi_code_concat_class_init (ViviCodeConcatClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  object_class->dispose = vivi_code_concat_dispose;
+
+  token_class->print = vivi_code_concat_print;
+  token_class->compile = vivi_code_concat_compile;
+}
+
+static void
+vivi_code_concat_init (ViviCodeConcat *token)
+{
+}
+
+ViviCodeValue *
+vivi_code_concat_new (ViviCodeValue *first, ViviCodeValue *second)
+{
+  ViviCodeConcat *ret;
+
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (first), NULL);
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (second), NULL);
+
+  ret = g_object_new (VIVI_TYPE_CODE_CONCAT, NULL);
+  ret->first = g_object_ref (first);
+  ret->second = g_object_ref (second);
+
+  return VIVI_CODE_VALUE (ret);
+}
diff --git a/vivified/code/vivi_code_concat.h b/vivified/code/vivi_code_concat.h
new file mode 100644
index 0000000..19c58ad
--- /dev/null
+++ b/vivified/code/vivi_code_concat.h
@@ -0,0 +1,58 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_CONCAT_H_
+#define _VIVI_CODE_CONCAT_H_
+
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeConcat ViviCodeConcat;
+typedef struct _ViviCodeConcatClass ViviCodeConcatClass;
+
+#define VIVI_TYPE_CODE_CONCAT                    (vivi_code_concat_get_type())
+#define VIVI_IS_CODE_CONCAT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_CONCAT))
+#define VIVI_IS_CODE_CONCAT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_CONCAT))
+#define VIVI_CODE_CONCAT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_CONCAT, ViviCodeConcat))
+#define VIVI_CODE_CONCAT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_CONCAT, ViviCodeConcatClass))
+#define VIVI_CODE_CONCAT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_CONCAT, ViviCodeConcatClass))
+
+struct _ViviCodeConcat
+{
+  ViviCodeValue		value;
+
+  ViviCodeValue *	first;
+  ViviCodeValue *	second;
+};
+
+struct _ViviCodeConcatClass
+{
+  ViviCodeValueClass	value_class;
+};
+
+GType			vivi_code_concat_get_type   	(void);
+
+ViviCodeValue *	vivi_code_concat_new		(ViviCodeValue *	first,
+						 ViviCodeValue *	second);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_substring.c b/vivified/code/vivi_code_substring.c
index 6581471..6144542 100644
--- a/vivified/code/vivi_code_substring.c
+++ b/vivified/code/vivi_code_substring.c
@@ -1,5 +1,5 @@
 /* Vivified
- * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/vivified/code/vivi_code_substring.h b/vivified/code/vivi_code_substring.h
index d28324f..1b6da3c 100644
--- a/vivified/code/vivi_code_substring.h
+++ b/vivified/code/vivi_code_substring.h
@@ -1,5 +1,5 @@
 /* Vivified
- * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 603449e..96eef42 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -35,6 +35,7 @@
 #include "vivi_code_builtin_statement_default.h"
 #include "vivi_code_builtin_value_call_default.h"
 #include "vivi_code_builtin_value_statement_default.h"
+#include "vivi_code_concat.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
@@ -940,6 +941,29 @@ parse_url_method (ParseData *data, ViviCodeValue **value)
 }*/
 
 static void
+parse_concat (ParseData *data, ViviCodeValue **value,
+    ViviCodeStatement **statement)
+{
+  ViviCodeValue *first, *second;
+  ViviCodeStatement *expression_statement;
+
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  parse_assignment_expression (data, &first, statement);
+
+  parse_token (data, TOKEN_COMMA);
+
+  parse_assignment_expression (data, &second, &expression_statement);
+  *statement = vivi_parser_join_statements (*statement, expression_statement);
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  *value = vivi_code_concat_new (first, second);
+  g_object_unref (first);
+  g_object_unref (second);
+}
+
+static void
 parse_substring (ParseData *data, ViviCodeValue **value,
     ViviCodeStatement **statement)
 {
@@ -1033,7 +1057,7 @@ typedef struct {
 
 static const BuiltinCall builtin_calls[] = {
   { "chr",         NULL, vivi_code_chr_new, NULL },
-  //{ "concat",      NULL, NULL, parse_concat },
+  { "concat",      NULL, NULL, parse_concat },
   { "eval",        NULL, vivi_code_eval_new, NULL },
   //{ "getProperty", NULL, NULL, parse_get_property },
   { "getTimer",    vivi_code_get_timer_new, NULL, NULL },
commit 8db3b1b9fb9ac9f6b337f394e9868cf89f98e98a
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Apr 16 16:37:58 2008 +0300

    Enable compiling of eval function and fix the parsing of targetPath function

diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index eb2021e..1abdada 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -84,6 +84,7 @@ DEFAULT_BUILTIN_VALUE_STATEMENT (Trace,			trace,			"trace",		SWFDEC_AS_ACTION_TR
 #endif
 
 DEFAULT_BUILTIN_VALUE_CALL (Chr,	chr,		"chr",		SWFDEC_AS_ACTION_ASCII_TO_CHAR)
+DEFAULT_BUILTIN_VALUE_CALL (Eval,	eval,		"eval",		SWFDEC_AS_ACTION_GET_VARIABLE)
 DEFAULT_BUILTIN_VALUE_CALL (Int,	int,		"int",		SWFDEC_AS_ACTION_TO_INTEGER)
 DEFAULT_BUILTIN_VALUE_CALL (Length,	length,		"length",	SWFDEC_AS_ACTION_STRING_LENGTH)
 DEFAULT_BUILTIN_VALUE_CALL (Ord,	ord,		"ord",		SWFDEC_AS_ACTION_CHAR_TO_ASCII)
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 70ab52f..603449e 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -968,6 +968,24 @@ parse_substring (ParseData *data, ViviCodeValue **value,
   g_object_unref (count);
 }
 
+static void
+parse_target_path (ParseData *data, ViviCodeValue **value,
+    ViviCodeStatement **statement)
+{
+  ViviCodeValue *identifier;
+
+  *statement = NULL;
+
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  parse_identifier (data, &identifier);
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  *value = vivi_code_target_path_new (identifier);
+  g_object_unref (identifier);
+}
+
 typedef ViviCodeStatement *(*NewStatementVoid) (void);
 typedef ViviCodeStatement *(*NewStatementValue) (ViviCodeValue *value);
 
@@ -1016,7 +1034,7 @@ typedef struct {
 static const BuiltinCall builtin_calls[] = {
   { "chr",         NULL, vivi_code_chr_new, NULL },
   //{ "concat",      NULL, NULL, parse_concat },
-  //{ "eval",        NULL, vivi_code_eval_new, NULL },
+  { "eval",        NULL, vivi_code_eval_new, NULL },
   //{ "getProperty", NULL, NULL, parse_get_property },
   { "getTimer",    vivi_code_get_timer_new, NULL, NULL },
   { "int",         NULL, vivi_code_int_new, NULL },
@@ -1024,7 +1042,7 @@ static const BuiltinCall builtin_calls[] = {
   { "ord",         NULL, vivi_code_ord_new, NULL },
   { "random",      NULL, vivi_code_random_new, NULL },
   { "substring",   NULL, NULL, parse_substring },
-  { "targetPath",  NULL, vivi_code_target_path_new, NULL },
+  { "targetPath",  NULL, NULL, parse_target_path },
   { "typeOf",      NULL, vivi_code_type_of_new, NULL }
 };
 
commit 630add2164120e4285bb748d30b59621912200c6
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Apr 16 16:31:56 2008 +0300

    Allow compiling the built-in substring function

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 06d4ff1..e255352 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -48,6 +48,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_printer.c \
 	vivi_code_return.c \
 	vivi_code_statement.c \
+	vivi_code_substring.c \
 	vivi_code_text_printer.c \
 	vivi_code_throw.c \
 	vivi_code_token.c \
@@ -99,6 +100,7 @@ noinst_HEADERS = \
 	vivi_code_printer.h \
 	vivi_code_return.h \
 	vivi_code_statement.h \
+	vivi_code_substring.h \
 	vivi_code_text_printer.h \
 	vivi_code_throw.h \
 	vivi_code_token.h \
diff --git a/vivified/code/vivi_code_substring.c b/vivified/code/vivi_code_substring.c
new file mode 100644
index 0000000..6581471
--- /dev/null
+++ b/vivified/code/vivi_code_substring.c
@@ -0,0 +1,106 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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_substring.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_TYPE (ViviCodeSubstring, vivi_code_substring, VIVI_TYPE_CODE_VALUE)
+
+static void
+vivi_code_substring_dispose (GObject *object)
+{
+  ViviCodeSubstring *substring = VIVI_CODE_SUBSTRING (object);
+
+  g_object_unref (substring->string);
+  g_object_unref (substring->index_);
+  g_object_unref (substring->count);
+
+  G_OBJECT_CLASS (vivi_code_substring_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_substring_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+  ViviCodeSubstring *substring = VIVI_CODE_SUBSTRING (token);
+
+  vivi_code_printer_print (printer, "substring (");
+  vivi_code_printer_print_value (printer, substring->string,
+      VIVI_PRECEDENCE_COMMA);
+  vivi_code_printer_print (printer, ", ");
+  vivi_code_printer_print_value (printer, substring->index_,
+      VIVI_PRECEDENCE_COMMA);
+  vivi_code_printer_print (printer, ", ");
+  vivi_code_printer_print_value (printer, substring->count,
+      VIVI_PRECEDENCE_COMMA);
+  vivi_code_printer_print (printer, ");");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_substring_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeSubstring *substring = VIVI_CODE_SUBSTRING (token);
+
+  vivi_code_compiler_compile_value (compiler, substring->string);
+  vivi_code_compiler_compile_value (compiler, substring->index_);
+  vivi_code_compiler_compile_value (compiler, substring->count);
+
+  vivi_code_compiler_write_empty_action (compiler,
+      SWFDEC_AS_ACTION_STRING_EXTRACT);
+}
+
+static void
+vivi_code_substring_class_init (ViviCodeSubstringClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  object_class->dispose = vivi_code_substring_dispose;
+
+  token_class->print = vivi_code_substring_print;
+  token_class->compile = vivi_code_substring_compile;
+}
+
+static void
+vivi_code_substring_init (ViviCodeSubstring *token)
+{
+}
+
+ViviCodeValue *
+vivi_code_substring_new (ViviCodeValue *string, ViviCodeValue *index_,
+    ViviCodeValue *count)
+{
+  ViviCodeSubstring *ret;
+
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (string), NULL);
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (index_), NULL);
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (count), NULL);
+
+  ret = g_object_new (VIVI_TYPE_CODE_SUBSTRING, NULL);
+  ret->string = g_object_ref (string);
+  ret->index_ = g_object_ref (index_);
+  ret->count = g_object_ref (count);
+
+  return VIVI_CODE_VALUE (ret);
+}
diff --git a/vivified/code/vivi_code_substring.h b/vivified/code/vivi_code_substring.h
new file mode 100644
index 0000000..d28324f
--- /dev/null
+++ b/vivified/code/vivi_code_substring.h
@@ -0,0 +1,60 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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_SUBSTRING_H_
+#define _VIVI_CODE_SUBSTRING_H_
+
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeSubstring ViviCodeSubstring;
+typedef struct _ViviCodeSubstringClass ViviCodeSubstringClass;
+
+#define VIVI_TYPE_CODE_SUBSTRING                    (vivi_code_substring_get_type())
+#define VIVI_IS_CODE_SUBSTRING(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_SUBSTRING))
+#define VIVI_IS_CODE_SUBSTRING_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_SUBSTRING))
+#define VIVI_CODE_SUBSTRING(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_SUBSTRING, ViviCodeSubstring))
+#define VIVI_CODE_SUBSTRING_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_SUBSTRING, ViviCodeSubstringClass))
+#define VIVI_CODE_SUBSTRING_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_SUBSTRING, ViviCodeSubstringClass))
+
+struct _ViviCodeSubstring
+{
+  ViviCodeValue		value;
+
+  ViviCodeValue *	string;
+  ViviCodeValue *	index_;
+  ViviCodeValue *	count;
+};
+
+struct _ViviCodeSubstringClass
+{
+  ViviCodeValueClass	value_class;
+};
+
+GType			vivi_code_substring_get_type   	(void);
+
+ViviCodeValue *	vivi_code_substring_new		(ViviCodeValue *	string,
+							 ViviCodeValue *	index_,
+							 ViviCodeValue *	count);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index c9ae5f8..70ab52f 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -49,6 +49,7 @@
 #include "vivi_code_loop.h"
 #include "vivi_code_or.h"
 #include "vivi_code_return.h"
+#include "vivi_code_substring.h"
 #include "vivi_code_throw.h"
 #include "vivi_code_unary.h"
 #include "vivi_code_value_statement.h"
@@ -913,9 +914,6 @@ parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
 
 // builtin functions
 
-typedef void (*ParseArgumentFunction) (ParseData *data, guint position,
-    ViviCodeValue **value, ViviCodeStatement **statement);
-
 /*static void
 parse_url_method (ParseData *data, ViviCodeValue **value)
 {
@@ -941,6 +939,35 @@ parse_url_method (ParseData *data, ViviCodeValue **value)
   }
 }*/
 
+static void
+parse_substring (ParseData *data, ViviCodeValue **value,
+    ViviCodeStatement **statement)
+{
+  ViviCodeValue *string, *index_, *count;
+  ViviCodeStatement *expression_statement;
+
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  parse_assignment_expression (data, &string, statement);
+
+  parse_token (data, TOKEN_COMMA);
+
+  parse_assignment_expression (data, &index_, &expression_statement);
+  *statement = vivi_parser_join_statements (*statement, expression_statement);
+
+  parse_token (data, TOKEN_COMMA);
+
+  parse_assignment_expression (data, &count, &expression_statement);
+  *statement = vivi_parser_join_statements (*statement, expression_statement);
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  *value = vivi_code_substring_new (string, index_, count);
+  g_object_unref (string);
+  g_object_unref (index_);
+  g_object_unref (count);
+}
+
 typedef ViviCodeStatement *(*NewStatementVoid) (void);
 typedef ViviCodeStatement *(*NewStatementValue) (ViviCodeValue *value);
 
@@ -996,7 +1023,7 @@ static const BuiltinCall builtin_calls[] = {
   { "length",      NULL, vivi_code_length_new, NULL },
   { "ord",         NULL, vivi_code_ord_new, NULL },
   { "random",      NULL, vivi_code_random_new, NULL },
-  //{ "substring",   NULL, NULL, parse_substring },
+  { "substring",   NULL, NULL, parse_substring },
   { "targetPath",  NULL, vivi_code_target_path_new, NULL },
   { "typeOf",      NULL, vivi_code_type_of_new, NULL }
 };
commit b25b1eaed742f6c8039d963784b6d3640e0394d1
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Apr 16 16:03:09 2008 +0300

    Oops, don't require semicolon here

diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 06a70c9..c9ae5f8 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -1056,8 +1056,6 @@ parse_builtin_call (ParseData *data, ViviCodeValue **value,
 
   parse_token (data, TOKEN_PARENTHESIS_RIGHT);
 
-  parse_automatic_semicolon (data);
-
   if (builtin_calls[i].constructor_value != NULL) {
     *value = builtin_calls[i].constructor_value (argument);
     g_object_unref (argument);
commit 2824471e88d1b25a1045be9dea17c7a16c2735d1
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Apr 16 15:56:31 2008 +0300

    Implement compiling of some built-in functions that have a return value

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 2c0eae2..06d4ff1 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -22,8 +22,11 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_binary_default.c \
 	vivi_code_block.c \
 	vivi_code_break.c \
+	vivi_code_builtin_call.c \
 	vivi_code_builtin_statement.c \
 	vivi_code_builtin_statement_default.c \
+	vivi_code_builtin_value_call.c \
+	vivi_code_builtin_value_call_default.c \
 	vivi_code_builtin_value_statement.c \
 	vivi_code_builtin_value_statement_default.c \
 	vivi_code_comment.c \
@@ -33,6 +36,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_function.c \
 	vivi_code_function_call.c \
 	vivi_code_get.c \
+	vivi_code_get_timer.c \
 	vivi_code_get_url.c \
 	vivi_code_goto.c \
 	vivi_code_if.c \
@@ -68,8 +72,11 @@ noinst_HEADERS = \
 	vivi_code_binary_default.h \
 	vivi_code_block.h \
 	vivi_code_break.h \
+	vivi_code_builtin_call.h \
 	vivi_code_builtin_statement.h \
 	vivi_code_builtin_statement_default.h \
+	vivi_code_builtin_value_call.h \
+	vivi_code_builtin_value_call_default.h \
 	vivi_code_builtin_value_statement.h \
 	vivi_code_builtin_value_statement_default.h \
 	vivi_code_comment.h \
@@ -80,6 +87,7 @@ noinst_HEADERS = \
 	vivi_code_function.h \
 	vivi_code_function_call.h \
 	vivi_code_get.h \
+	vivi_code_get_timer.h \
 	vivi_code_get_url.h \
 	vivi_code_goto.h \
 	vivi_code_if.h \
diff --git a/vivified/code/vivi_code_builtin_call.c b/vivified/code/vivi_code_builtin_call.c
new file mode 100644
index 0000000..cc81bb2
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_call.c
@@ -0,0 +1,63 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_builtin_call.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_ABSTRACT_TYPE (ViviCodeBuiltinCall, vivi_code_builtin_call, VIVI_TYPE_CODE_VALUE)
+
+static void
+vivi_code_builtin_call_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+  ViviCodeBuiltinCallClass *klass = VIVI_CODE_BUILTIN_CALL_GET_CLASS (token);
+
+  g_assert (klass->function_name != NULL);
+  vivi_code_printer_print (printer, klass->function_name);
+  vivi_code_printer_print (printer, " ();");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_builtin_call_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeBuiltinCallClass *klass = VIVI_CODE_BUILTIN_CALL_GET_CLASS (token);
+
+  g_assert (klass->bytecode != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
+}
+
+static void
+vivi_code_builtin_call_class_init (ViviCodeBuiltinCallClass *klass)
+{
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  token_class->print = vivi_code_builtin_call_print;
+  token_class->compile = vivi_code_builtin_call_compile;
+}
+
+static void
+vivi_code_builtin_call_init (ViviCodeBuiltinCall *stmt)
+{
+}
diff --git a/vivified/code/vivi_code_builtin_call.h b/vivified/code/vivi_code_builtin_call.h
new file mode 100644
index 0000000..c174a91
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_call.h
@@ -0,0 +1,57 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_BUILTIN_CALL_H_
+#define _VIVI_CODE_BUILTIN_CALL_H_
+
+#include <swfdec/swfdec_as_interpret.h>
+
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeBuiltinCall ViviCodeBuiltinCall;
+typedef struct _ViviCodeBuiltinCallClass ViviCodeBuiltinCallClass;
+
+#define VIVI_TYPE_CODE_BUILTIN_CALL                    (vivi_code_builtin_call_get_type())
+#define VIVI_IS_CODE_BUILTIN_CALL(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_BUILTIN_CALL))
+#define VIVI_IS_CODE_BUILTIN_CALL_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_BUILTIN_CALL))
+#define VIVI_CODE_BUILTIN_CALL(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_BUILTIN_CALL, ViviCodeBuiltinCall))
+#define VIVI_CODE_BUILTIN_CALL_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_BUILTIN_CALL, ViviCodeBuiltinCallClass))
+#define VIVI_CODE_BUILTIN_CALL_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_BUILTIN_CALL, ViviCodeBuiltinCallClass))
+
+struct _ViviCodeBuiltinCall
+{
+  ViviCodeValue			value;
+};
+
+struct _ViviCodeBuiltinCallClass
+{
+  ViviCodeValueClass		value_class;
+
+  const char *			function_name;
+  SwfdecAsAction		bytecode;
+};
+
+GType		vivi_code_builtin_call_get_type		(void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_builtin_value_call.c b/vivified/code/vivi_code_builtin_value_call.c
new file mode 100644
index 0000000..e3f6f9a
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_call.c
@@ -0,0 +1,109 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_builtin_value_call.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_ABSTRACT_TYPE (ViviCodeBuiltinValueCall, vivi_code_builtin_value_call, VIVI_TYPE_CODE_BUILTIN_CALL)
+
+static void
+vivi_code_builtin_value_call_dispose (GObject *object)
+{
+  ViviCodeBuiltinValueCall *call =  VIVI_CODE_BUILTIN_VALUE_CALL (object);
+
+  g_assert (call->value != NULL);
+  g_object_unref (call->value);
+
+  G_OBJECT_CLASS (vivi_code_builtin_value_call_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_builtin_value_call_print (ViviCodeToken *token,
+    ViviCodePrinter *printer)
+{
+  ViviCodeBuiltinCallClass *klass = VIVI_CODE_BUILTIN_CALL_GET_CLASS (token);
+  ViviCodeBuiltinValueCall *call = VIVI_CODE_BUILTIN_VALUE_CALL (token);
+
+  g_assert (klass->function_name != NULL);
+  vivi_code_printer_print (printer, klass->function_name);
+  vivi_code_printer_print (printer, " (");
+
+  g_assert (call->value != NULL);
+  vivi_code_printer_print_value (printer, call->value, VIVI_PRECEDENCE_COMMA);
+
+  vivi_code_printer_print (printer, ");");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_builtin_value_call_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeBuiltinCallClass *klass = VIVI_CODE_BUILTIN_CALL_GET_CLASS (token);
+  ViviCodeBuiltinValueCall *call = VIVI_CODE_BUILTIN_VALUE_CALL (token);
+
+  g_assert (call->value != NULL);
+  vivi_code_compiler_compile_value (compiler, call->value);
+
+  g_assert (klass->bytecode != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
+}
+
+static void
+vivi_code_builtin_value_call_class_init (
+    ViviCodeBuiltinValueCallClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  object_class->dispose = vivi_code_builtin_value_call_dispose;
+
+  token_class->print = vivi_code_builtin_value_call_print;
+  token_class->compile = vivi_code_builtin_value_call_compile;
+}
+
+static void
+vivi_code_builtin_value_call_init (ViviCodeBuiltinValueCall *call)
+{
+}
+
+void
+vivi_code_builtin_value_call_set_value (ViviCodeBuiltinValueCall *call,
+    ViviCodeValue *value)
+{
+  g_return_if_fail (VIVI_IS_CODE_BUILTIN_VALUE_CALL (call));
+  g_return_if_fail (VIVI_IS_CODE_VALUE (value));
+
+  if (call->value)
+    g_object_unref (value);
+  call->value = g_object_ref (value);
+}
+
+ViviCodeValue *
+vivi_code_builtin_value_call_get_value (ViviCodeBuiltinValueCall *call)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_BUILTIN_VALUE_CALL (call), NULL);
+
+  return call->value;
+}
diff --git a/vivified/code/vivi_code_builtin_value_call.h b/vivified/code/vivi_code_builtin_value_call.h
new file mode 100644
index 0000000..a7fa2a9
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_call.h
@@ -0,0 +1,60 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_BUILTIN_VALUE_CALL_H_
+#define _VIVI_CODE_BUILTIN_VALUE_CALL_H_
+
+#include <swfdec/swfdec_as_interpret.h>
+
+#include <vivified/code/vivi_code_builtin_call.h>
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeBuiltinValueCall ViviCodeBuiltinValueCall;
+typedef struct _ViviCodeBuiltinValueCallClass ViviCodeBuiltinValueCallClass;
+
+#define VIVI_TYPE_CODE_BUILTIN_VALUE_CALL                    (vivi_code_builtin_value_call_get_type())
+#define VIVI_IS_CODE_BUILTIN_VALUE_CALL(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_CALL))
+#define VIVI_IS_CODE_BUILTIN_VALUE_CALL_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_BUILTIN_VALUE_CALL))
+#define VIVI_CODE_BUILTIN_VALUE_CALL(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_CALL, ViviCodeBuiltinValueCall))
+#define VIVI_CODE_BUILTIN_VALUE_CALL_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_BUILTIN_VALUE_CALL, ViviCodeBuiltinValueCallClass))
+#define VIVI_CODE_BUILTIN_VALUE_CALL_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_CALL, ViviCodeBuiltinValueCallClass))
+
+struct _ViviCodeBuiltinValueCall
+{
+  ViviCodeBuiltinCall	call;
+
+  ViviCodeValue *		value;
+};
+
+struct _ViviCodeBuiltinValueCallClass
+{
+  ViviCodeBuiltinCallClass	call_class;
+};
+
+GType		vivi_code_builtin_value_call_get_type		(void);
+
+void		vivi_code_builtin_value_call_set_value		(ViviCodeBuiltinValueCall *	call,
+								 ViviCodeValue *		value);
+ViviCodeValue *	vivi_code_builtin_value_call_get_value		(ViviCodeBuiltinValueCall *	call);
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_builtin_value_call_default.c b/vivified/code/vivi_code_builtin_value_call_default.c
new file mode 100644
index 0000000..7be6d08
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_call_default.c
@@ -0,0 +1,58 @@
+/* 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_builtin_value_call_default.h"
+
+#define DEFAULT_BUILTIN_VALUE_CALL(CapsName, underscore_name, name, bc) \
+\
+G_DEFINE_TYPE (ViviCode ## CapsName, vivi_code_ ## underscore_name, VIVI_TYPE_CODE_BUILTIN_VALUE_CALL) \
+\
+static void \
+vivi_code_ ## underscore_name ## _class_init (ViviCodeBuiltinValueCallClass *klass) \
+{ \
+  ViviCodeBuiltinCallClass *builtin_class = VIVI_CODE_BUILTIN_CALL_CLASS (klass); \
+\
+  builtin_class->function_name = name; \
+  builtin_class->bytecode = bc; \
+} \
+\
+static void \
+vivi_code_ ## underscore_name ## _init (ViviCodeBuiltinValueCall *builtin_call) \
+{ \
+} \
+\
+ViviCodeValue * \
+vivi_code_ ## underscore_name ## _new (ViviCodeValue *value) \
+{ \
+  ViviCodeBuiltinValueCall *call; \
+\
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (value), NULL); \
+\
+  call = VIVI_CODE_BUILTIN_VALUE_CALL (g_object_new (vivi_code_ ## underscore_name ## _get_type (), NULL)); \
+  vivi_code_builtin_value_call_set_value (call, value); \
+\
+  return VIVI_CODE_VALUE (call); \
+}
+
+#include "vivi_code_defaults.h"
diff --git a/vivified/code/vivi_code_builtin_value_call_default.h b/vivified/code/vivi_code_builtin_value_call_default.h
new file mode 100644
index 0000000..80bd624
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_call_default.h
@@ -0,0 +1,42 @@
+/* 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_BUILTIN_VALUE_CALL_DEFAULT_H_
+#define _VIVI_CODE_BUILTIN_VALUE_CALL_DEFAULT_H_
+
+#include <vivified/code/vivi_code_builtin_value_call.h>
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+#define DEFAULT_BUILTIN_VALUE_CALL(CapsName, underscore_name, function_name, bytecode) \
+\
+typedef ViviCodeBuiltinValueCall ViviCode ## CapsName; \
+typedef ViviCodeBuiltinValueCallClass ViviCode ## CapsName ## Class; \
+\
+GType			vivi_code_ ## underscore_name ## _get_type	(void); \
+\
+ViviCodeValue *		vivi_code_## underscore_name ## _new		(ViviCodeValue *value);
+
+#include "vivi_code_defaults.h"
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index d5739e6..eb2021e 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -78,3 +78,17 @@ DEFAULT_BUILTIN_VALUE_STATEMENT (SetTarget,		set_target,		"setTarget",		SWFDEC_A
 DEFAULT_BUILTIN_VALUE_STATEMENT (Trace,			trace,			"trace",		SWFDEC_AS_ACTION_TRACE)
 
 #undef DEFAULT_BUILTIN_VALUE_STATEMENT
+
+#ifndef DEFAULT_BUILTIN_VALUE_CALL
+#define DEFAULT_BUILTIN_VALUE_CALL(CapsName, underscore_name, function_name, bytecode)
+#endif
+
+DEFAULT_BUILTIN_VALUE_CALL (Chr,	chr,		"chr",		SWFDEC_AS_ACTION_ASCII_TO_CHAR)
+DEFAULT_BUILTIN_VALUE_CALL (Int,	int,		"int",		SWFDEC_AS_ACTION_TO_INTEGER)
+DEFAULT_BUILTIN_VALUE_CALL (Length,	length,		"length",	SWFDEC_AS_ACTION_STRING_LENGTH)
+DEFAULT_BUILTIN_VALUE_CALL (Ord,	ord,		"ord",		SWFDEC_AS_ACTION_CHAR_TO_ASCII)
+DEFAULT_BUILTIN_VALUE_CALL (Random,	random,		"random",	SWFDEC_AS_ACTION_RANDOM)
+DEFAULT_BUILTIN_VALUE_CALL (TargetPath,	target_path,	"targetPath",	SWFDEC_AS_ACTION_TARGET_PATH)
+DEFAULT_BUILTIN_VALUE_CALL (TypeOf,	type_of,	"typeOf",	SWFDEC_AS_ACTION_TYPE_OF)
+
+#undef DEFAULT_BUILTIN_VALUE_CALL
diff --git a/vivified/code/vivi_code_get_timer.c b/vivified/code/vivi_code_get_timer.c
new file mode 100644
index 0000000..b712feb
--- /dev/null
+++ b/vivified/code/vivi_code_get_timer.c
@@ -0,0 +1,48 @@
+/* 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_get_timer.h"
+
+G_DEFINE_TYPE (ViviCodeGetTimer, vivi_code_get_timer, VIVI_TYPE_CODE_BUILTIN_CALL)
+
+static void
+vivi_code_get_timer_class_init (ViviCodeGetTimerClass *klass)
+{
+  ViviCodeBuiltinCallClass *builtin_class =
+    VIVI_CODE_BUILTIN_CALL_CLASS (klass);
+
+  builtin_class->function_name = "getTimer";
+  builtin_class->bytecode = SWFDEC_AS_ACTION_GET_TIME;
+}
+
+static void
+vivi_code_get_timer_init (ViviCodeBuiltinCall *builtin_statement)
+{
+}
+
+ViviCodeValue *
+vivi_code_get_timer_new (void)
+{
+  return VIVI_CODE_VALUE (g_object_new (vivi_code_get_timer_get_type (), NULL));
+}
diff --git a/vivified/code/vivi_code_get_timer.h b/vivified/code/vivi_code_get_timer.h
new file mode 100644
index 0000000..730e256
--- /dev/null
+++ b/vivified/code/vivi_code_get_timer.h
@@ -0,0 +1,36 @@
+/* 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_GET_TIMER_H_
+#define _VIVI_CODE_GET_TIMER_H_
+
+#include <vivified/code/vivi_code_builtin_call.h>
+
+G_BEGIN_DECLS
+
+typedef ViviCodeBuiltinCall ViviCodeGetTimer;
+typedef ViviCodeBuiltinCallClass ViviCodeGetTimerClass;
+
+GType			vivi_code_get_timer_get_type		(void);
+
+ViviCodeValue *		vivi_code_get_timer_new			(void);
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 4476ba9..06a70c9 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -33,12 +33,14 @@
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
 #include "vivi_code_builtin_statement_default.h"
+#include "vivi_code_builtin_value_call_default.h"
 #include "vivi_code_builtin_value_statement_default.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
 #include "vivi_code_function_call.h"
 #include "vivi_code_get.h"
+#include "vivi_code_get_timer.h"
 #include "vivi_code_get_url.h"
 #include "vivi_code_goto.h"
 #include "vivi_code_if.h"
@@ -909,7 +911,7 @@ parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
   *statement = vivi_parser_join_statements (statement_right, assignment);
 }
 
-// special functions
+// builtin functions
 
 typedef void (*ParseArgumentFunction) (ParseData *data, guint position,
     ViviCodeValue **value, ViviCodeStatement **statement);
@@ -939,56 +941,68 @@ parse_url_method (ParseData *data, ViviCodeValue **value)
   }
 }*/
 
-typedef ViviCodeStatement *(*NewFunctionVoid) (void);
-typedef ViviCodeStatement *(*NewFunctionValue) (ViviCodeValue *value);
+typedef ViviCodeStatement *(*NewStatementVoid) (void);
+typedef ViviCodeStatement *(*NewStatementValue) (ViviCodeValue *value);
 
 typedef struct {
-  gboolean			return_value;
   const char *			name;
-  NewFunctionVoid		constructor_void;
-  NewFunctionValue		constructor_value;
+  NewStatementVoid		constructor_void;
+  NewStatementValue		constructor_value;
   ParseStatementFunction	parse_custom;
-} SpecialFunction;
-
-static const SpecialFunction special_functions[] = {
-  //{ FALSE, "callFrame",          NULL, vivi_code_call_frame_new, NULL },
-  //{ TRUE,  "chr",                NULL, vivi_code_chr_new, NULL },
-  //{ TRUE,  "concat",             NULL, NULL, parse_concat },
-  //{ FALSE, "duplicateMovieClip", NULL, NULL, parse_duplicate_movie_clip },
-  //{ TRUE,  "eval",               NULL, vivi_code_eval_new, NULL },
-  //{ TRUE,  "getProperty",        NULL, NULL, parse_get_property },
-  //{ TRUE,  "getTimer",           vivi_code_get_timer_new, NULL, NULL },
-  //{ FALSE, "getURL1",            NULL, NULL, parse_get_url1 },
-  //{ FALSE, "getURL",             NULL, NULL, parse_get_url },
-  //{ FALSE, "gotoAndPlay",        NULL, vivi_code_goto_and_play_new, NULL },
-  //{ FALSE, "gotoAndStop",        NULL, vivi_code_goto_and_stop_new, NULL },
-  //{ TRUE,  "int",                NULL, vivi_code_int_new, NULL },
-  //{ TRUE,  "length",             NULL, vivi_code_length_new, NULL },
-  //{ FALSE, "loadMovie",          NULL, NULL, parse_load_movie },
-  //{ FALSE, "loadMovieNum",       NULL, NULL, parse_load_movie_num },
-  //{ FALSE, "loadVariables",      NULL, NULL, parse_load_variables },
-  //{ FALSE, "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
-  { FALSE, "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
-  //{ TRUE,  "ord",                NULL, vivi_code_ord_new, NULL },
-  { FALSE, "play",               vivi_code_play_new, NULL, NULL },
-  { FALSE, "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
-  //{ TRUE,  "random",             NULL, vivi_code_random_new, NULL },
-  { FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
-  //{ FALSE, "setProperty",        NULL, NULL, parse_set_property },
-  { FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
-  //{ FALSE, "startDrag",          NULL, NULL, parse_start_drag },
-  { FALSE, "stop",               vivi_code_stop_new, NULL, NULL },
-  { FALSE, "stopDrag",           vivi_code_stop_drag_new,NULL,  NULL },
-  { FALSE, "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
-  //{ TRUE,  "substring",          NULL, NULL, parse_substring },
-  //{ TRUE,  "targetPath",         NULL, vivi_code_target_path_new, NULL },
-  { FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
-  { FALSE, "trace",              NULL, vivi_code_trace_new, NULL }//,
-  //{ TRUE,  "typeOf",             NULL, vivi_code_type_of_new, NULL }
+} BuiltinStatement;
+
+static const BuiltinStatement builtin_statements[] = {
+  //{ "callFrame",          NULL, vivi_code_call_frame_new, NULL },
+  //{ "duplicateMovieClip", NULL, NULL, parse_duplicate_movie_clip },
+  //{ "getURL1",            NULL, NULL, parse_get_url1 },
+  //{ "getURL",             NULL, NULL, parse_get_url },
+  //{ "gotoAndPlay",        NULL, vivi_code_goto_and_play_new, NULL },
+  //{ "gotoAndStop",        NULL, vivi_code_goto_and_stop_new, NULL },
+  //{ "loadMovie",          NULL, NULL, parse_load_movie },
+  //{ "loadMovieNum",       NULL, NULL, parse_load_movie_num },
+  //{ "loadVariables",      NULL, NULL, parse_load_variables },
+  //{ "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
+  { "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
+  { "play",               vivi_code_play_new, NULL, NULL },
+  { "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
+  { "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
+  //{ "setProperty",        NULL, NULL, parse_set_property },
+  { "setTarget",          NULL, vivi_code_set_target_new, NULL },
+  //{ "startDrag",          NULL, NULL, parse_start_drag },
+  { "stop",               vivi_code_stop_new, NULL, NULL },
+  { "stopDrag",           vivi_code_stop_drag_new, NULL, NULL },
+  { "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
+  { "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
+  { "trace",              NULL, vivi_code_trace_new, NULL }
+};
+
+typedef ViviCodeValue *(*NewCallVoid) (void);
+typedef ViviCodeValue *(*NewCallValue) (ViviCodeValue *value);
+
+typedef struct {
+  const char *			name;
+  NewCallVoid			constructor_void;
+  NewCallValue			constructor_value;
+  ParseValueStatementFunction	parse_custom;
+} BuiltinCall;
+
+static const BuiltinCall builtin_calls[] = {
+  { "chr",         NULL, vivi_code_chr_new, NULL },
+  //{ "concat",      NULL, NULL, parse_concat },
+  //{ "eval",        NULL, vivi_code_eval_new, NULL },
+  //{ "getProperty", NULL, NULL, parse_get_property },
+  { "getTimer",    vivi_code_get_timer_new, NULL, NULL },
+  { "int",         NULL, vivi_code_int_new, NULL },
+  { "length",      NULL, vivi_code_length_new, NULL },
+  { "ord",         NULL, vivi_code_ord_new, NULL },
+  { "random",      NULL, vivi_code_random_new, NULL },
+  //{ "substring",   NULL, NULL, parse_substring },
+  { "targetPath",  NULL, vivi_code_target_path_new, NULL },
+  { "typeOf",      NULL, vivi_code_type_of_new, NULL }
 };
 
 static gboolean
-peek_special_statement (ParseData *data)
+peek_builtin_call (ParseData *data)
 {
   guint i;
   const char *identifier;
@@ -1000,9 +1014,8 @@ peek_special_statement (ParseData *data)
 
   // TODO: Check that ( follows?
 
-  for (i = 0; i < G_N_ELEMENTS (special_functions); i++) {
-    if (special_functions[i].return_value == FALSE &&
-	g_ascii_strcasecmp (identifier, special_functions[i].name) == 0)
+  for (i = 0; i < G_N_ELEMENTS (builtin_calls); i++) {
+    if (g_ascii_strcasecmp (identifier, builtin_calls[i].name) == 0)
       return TRUE;
   }
 
@@ -1010,49 +1023,115 @@ peek_special_statement (ParseData *data)
 }
 
 static void
-parse_special_statement (ParseData *data, ViviCodeStatement **statement)
+parse_builtin_call (ParseData *data, ViviCodeValue **value,
+    ViviCodeStatement **statement)
 {
   guint i;
   const char *identifier;
-  ViviCodeValue *value, *argument;
+  ViviCodeValue *argument;
+
+  parse_identifier (data, &argument);
+  identifier = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
+	VIVI_CODE_GET (argument)->name));
+  g_object_unref (argument);
+
+  for (i = 0; i < G_N_ELEMENTS (builtin_calls); i++) {
+    if (g_ascii_strcasecmp (identifier, builtin_calls[i].name) == 0)
+      break;
+  }
+  if (i >= G_N_ELEMENTS (builtin_calls)) {
+    vivi_parser_error (data, "Unknown builtin call: %s", identifier);
+    i = 0;
+  }
+
+  if (builtin_calls[i].parse_custom != NULL) {
+    builtin_calls[i].parse_custom (data, value, statement);
+    return;
+  }
+//
+  parse_token (data, TOKEN_PARENTHESIS_LEFT);
+
+  if (builtin_calls[i].constructor_value != NULL)
+    parse_assignment_expression (data, &argument, statement);
+
+  parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+
+  parse_automatic_semicolon (data);
+
+  if (builtin_calls[i].constructor_value != NULL) {
+    *value = builtin_calls[i].constructor_value (argument);
+    g_object_unref (argument);
+  } else {
+    g_assert (builtin_calls[i].constructor_void != NULL);
+    *value = builtin_calls[i].constructor_void ();
+  }
+}
+
+
+static gboolean
+peek_builtin_statement (ParseData *data)
+{
+  guint i;
+  const char *identifier;
+
+  if (!peek_token (data, TOKEN_IDENTIFIER))
+    return FALSE;
+
+  identifier = data->scanner->next_value.v_identifier;
+
+  // TODO: Check that ( follows?
+
+  for (i = 0; i < G_N_ELEMENTS (builtin_statements); i++) {
+    if (g_ascii_strcasecmp (identifier, builtin_statements[i].name) == 0)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+static void
+parse_builtin_statement (ParseData *data, ViviCodeStatement **statement)
+{
+  guint i;
+  const char *identifier;
+  ViviCodeValue *argument;
   ViviCodeStatement *argument_statement;
 
-  parse_identifier (data, &value);
+  parse_identifier (data, &argument);
   identifier = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
-	VIVI_CODE_GET (value)->name));
-  g_object_unref (value);
+	VIVI_CODE_GET (argument)->name));
+  g_object_unref (argument);
 
-  for (i = 0; i < G_N_ELEMENTS (special_functions); i++) {
-    if (special_functions[i].return_value == FALSE &&
-        g_ascii_strcasecmp (identifier, special_functions[i].name) == 0)
+  for (i = 0; i < G_N_ELEMENTS (builtin_statements); i++) {
+    if (g_ascii_strcasecmp (identifier, builtin_statements[i].name) == 0)
       break;
   }
-  if (i >= G_N_ELEMENTS (special_functions)) {
-    vivi_parser_error (data, "Unknown special statement: %s", identifier);
+  if (i >= G_N_ELEMENTS (builtin_statements)) {
+    vivi_parser_error (data, "Unknown builtin statement: %s", identifier);
     i = 0;
   }
 
-  if (special_functions[i].parse_custom != NULL) {
-    special_functions[i].parse_custom (data, statement);
+  if (builtin_statements[i].parse_custom != NULL) {
+    builtin_statements[i].parse_custom (data, statement);
     return;
   }
 //
   parse_token (data, TOKEN_PARENTHESIS_LEFT);
 
-  if (special_functions[i].constructor_value != NULL)
+  if (builtin_statements[i].constructor_value != NULL)
     parse_assignment_expression (data, &argument, &argument_statement);
 
   parse_token (data, TOKEN_PARENTHESIS_RIGHT);
 
   parse_automatic_semicolon (data);
 
-  if (special_functions[i].constructor_value != NULL) {
-    *statement = special_functions[i].constructor_value (argument);
+  if (builtin_statements[i].constructor_value != NULL) {
+    *statement = builtin_statements[i].constructor_value (argument);
     g_object_unref (argument);
     *statement = vivi_parser_join_statements (argument_statement, *statement);
   } else {
-    g_assert (special_functions[i].constructor_void != NULL);
-    *statement = special_functions[i].constructor_void ();
+    g_assert (builtin_statements[i].constructor_void != NULL);
+    *statement = builtin_statements[i].constructor_void ();
   }
 }
 
@@ -1233,7 +1312,11 @@ parse_left_hand_side_expression (ParseData *data, ViviCodeValue **value,
     return;
   }
 
-  parse_member_expression (data, value, statement);
+  if (peek_builtin_call (data)) {
+    parse_builtin_call (data, value, statement);
+  } else {
+    parse_member_expression (data, value, statement);
+  }
 
   while (try_parse_token (data, TOKEN_PARENTHESIS_LEFT)) {
     if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
@@ -2256,7 +2339,7 @@ static const struct {
   PeekFunction peek;
   ParseStatementFunction parse;
 } statement_functions[] = {
-  { peek_special_statement, parse_special_statement },
+  { peek_builtin_statement, parse_builtin_statement },
   { peek_block, parse_block },
   { peek_variable_statement, parse_variable_statement },
   { peek_empty_statement, parse_empty_statement },
diff --git a/vivified/code/vivi_parser_scanner_lex.l b/vivified/code/vivi_parser_scanner_lex.l
index 8b62e1d..8f6c696 100644
--- a/vivified/code/vivi_parser_scanner_lex.l
+++ b/vivified/code/vivi_parser_scanner_lex.l
@@ -180,7 +180,7 @@ identifier_part		[$_a-zA-Z0-9]
 "goto"			{ count (); return TOKEN_RESERVED_KEYWORD; }
 "implements"		{ count (); return TOKEN_RESERVED_KEYWORD; }
 "import"		{ count (); return TOKEN_RESERVED_KEYWORD; }
-"int"			{ count (); return TOKEN_RESERVED_KEYWORD; }
+	/*"int"			{ count (); return TOKEN_RESERVED_KEYWORD; }*/
 "interface"		{ count (); return TOKEN_RESERVED_KEYWORD; }
 "long"			{ count (); return TOKEN_RESERVED_KEYWORD; }
 "native"		{ count (); return TOKEN_RESERVED_KEYWORD; }
commit 5ec16ee6036689711d2bb89e03dfb75a44b697fe
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 13:19:46 2008 +0300

    Handle BuiltinValueStatements with a macro too

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index ead59b2..2c0eae2 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -25,6 +25,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_builtin_statement.c \
 	vivi_code_builtin_statement_default.c \
 	vivi_code_builtin_value_statement.c \
+	vivi_code_builtin_value_statement_default.c \
 	vivi_code_comment.c \
 	vivi_code_compiler.c \
 	vivi_code_constant.c \
@@ -46,7 +47,6 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_text_printer.c \
 	vivi_code_throw.c \
 	vivi_code_token.c \
-	vivi_code_trace.c \
 	vivi_code_unary.c \
 	vivi_code_value.c \
 	vivi_code_value_statement.c \
@@ -71,6 +71,7 @@ noinst_HEADERS = \
 	vivi_code_builtin_statement.h \
 	vivi_code_builtin_statement_default.h \
 	vivi_code_builtin_value_statement.h \
+	vivi_code_builtin_value_statement_default.h \
 	vivi_code_comment.h \
 	vivi_code_compiler.h \
 	vivi_code_constant.h \
@@ -93,7 +94,6 @@ noinst_HEADERS = \
 	vivi_code_text_printer.h \
 	vivi_code_throw.h \
 	vivi_code_token.h \
-	vivi_code_trace.h \
 	vivi_code_unary.h \
 	vivi_code_value.h \
 	vivi_code_value_statement.h \
diff --git a/vivified/code/vivi_code_builtin_value_statement_default.c b/vivified/code/vivi_code_builtin_value_statement_default.c
new file mode 100644
index 0000000..9d9ab80
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_statement_default.c
@@ -0,0 +1,58 @@
+/* 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_builtin_value_statement_default.h"
+
+#define DEFAULT_BUILTIN_VALUE_STATEMENT(CapsName, underscore_name, name, bc) \
+\
+G_DEFINE_TYPE (ViviCode ## CapsName, vivi_code_ ## underscore_name, VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT) \
+\
+static void \
+vivi_code_ ## underscore_name ## _class_init (ViviCodeBuiltinValueStatementClass *klass) \
+{ \
+  ViviCodeBuiltinStatementClass *builtin_statement_class = VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass); \
+\
+  builtin_statement_class->function_name = name; \
+  builtin_statement_class->bytecode = bc; \
+} \
+\
+static void \
+vivi_code_ ## underscore_name ## _init (ViviCodeBuiltinValueStatement *builtin_statement) \
+{ \
+} \
+\
+ViviCodeStatement * \
+vivi_code_ ## underscore_name ## _new (ViviCodeValue *value) \
+{ \
+  ViviCodeBuiltinValueStatement *stmt; \
+\
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (value), NULL); \
+\
+  stmt = VIVI_CODE_BUILTIN_VALUE_STATEMENT (g_object_new (vivi_code_ ## underscore_name ## _get_type (), NULL)); \
+  vivi_code_builtin_value_statement_set_value (stmt, value); \
+\
+  return VIVI_CODE_STATEMENT (stmt); \
+}
+
+#include "vivi_code_defaults.h"
diff --git a/vivified/code/vivi_code_builtin_value_statement_default.h b/vivified/code/vivi_code_builtin_value_statement_default.h
new file mode 100644
index 0000000..1fb4856
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_statement_default.h
@@ -0,0 +1,42 @@
+/* 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_BUILTIN_VALUE_STATEMENT_DEFAULT_H_
+#define _VIVI_CODE_BUILTIN_VALUE_STATEMENT_DEFAULT_H_
+
+#include <vivified/code/vivi_code_builtin_value_statement.h>
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+#define DEFAULT_BUILTIN_VALUE_STATEMENT(CapsName, underscore_name, function_name, bytecode) \
+\
+typedef ViviCodeBuiltinValueStatement ViviCode ## CapsName; \
+typedef ViviCodeBuiltinValueStatementClass ViviCode ## CapsName ## Class; \
+\
+GType			vivi_code_ ## underscore_name ## _get_type   	(void); \
+\
+ViviCodeStatement *	vivi_code_## underscore_name ## _new		(ViviCodeValue *value);
+
+#include "vivi_code_defaults.h"
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index b271cb8..d5739e6 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -65,3 +65,16 @@ DEFAULT_BUILTIN_STATEMENT (StopSounds,		stop_sounds,	"stopSounds",		SWFDEC_AS_AC
 DEFAULT_BUILTIN_STATEMENT (ToggleQuality,	toggle_quality,	"toggleQuality",	SWFDEC_AS_ACTION_TOGGLE_QUALITY)
 
 #undef DEFAULT_BUILTIN_STATEMENT
+
+#ifndef DEFAULT_BUILTIN_VALUE_STATEMENT
+#define DEFAULT_BUILTIN_VALUE_STATEMENT(CapsName, underscore_name, function_name, bytecode)
+#endif
+
+//DEFAULT_BUILTIN_VALUE_STATEMENT (CallFrame,		call_frame,		"callFrame",		SWFDEC_AS_ACTION_CALL)
+//DEFAULT_BUILTIN_VALUE_STATEMENT (GotoAndPlay,		goto_and_play,		"gotoAndPlay",		???)
+//DEFAULT_BUILTIN_VALUE_STATEMENT (GotoAndStop,		goto_and_stop,		"gotoAndStop",		???)
+DEFAULT_BUILTIN_VALUE_STATEMENT (RemoveMovieClip,	remove_movie_clip,	"removeMovieClip",	SWFDEC_AS_ACTION_REMOVE_SPRITE)
+DEFAULT_BUILTIN_VALUE_STATEMENT (SetTarget,		set_target,		"setTarget",		SWFDEC_AS_ACTION_SET_TARGET2)
+DEFAULT_BUILTIN_VALUE_STATEMENT (Trace,			trace,			"trace",		SWFDEC_AS_ACTION_TRACE)
+
+#undef DEFAULT_BUILTIN_VALUE_STATEMENT
diff --git a/vivified/code/vivi_code_trace.c b/vivified/code/vivi_code_trace.c
deleted file mode 100644
index e30db40..0000000
--- a/vivified/code/vivi_code_trace.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
- *
- * 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_trace.h"
-
-G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT)
-
-static void
-vivi_code_trace_class_init (ViviCodeTraceClass *klass)
-{
-  ViviCodeBuiltinStatementClass *stmt_class =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass);
-
-  stmt_class->function_name = "trace";
-  stmt_class->bytecode = SWFDEC_AS_ACTION_TRACE;
-}
-
-static void
-vivi_code_trace_init (ViviCodeTrace *token)
-{
-}
-
-ViviCodeStatement *
-vivi_code_trace_new (ViviCodeValue *value)
-{
-  ViviCodeBuiltinValueStatement *stmt;
-
-  g_return_val_if_fail (VIVI_IS_CODE_VALUE (value), NULL);
-
-  stmt = VIVI_CODE_BUILTIN_VALUE_STATEMENT (
-      g_object_new (VIVI_TYPE_CODE_TRACE, NULL));
-  vivi_code_builtin_value_statement_set_value (stmt, g_object_ref (value));
-
-  return VIVI_CODE_STATEMENT (stmt);
-}
-
diff --git a/vivified/code/vivi_code_trace.h b/vivified/code/vivi_code_trace.h
deleted file mode 100644
index 2609607..0000000
--- a/vivified/code/vivi_code_trace.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
- *
- * 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_TRACE_H_
-#define _VIVI_CODE_TRACE_H_
-
-#include <vivified/code/vivi_code_builtin_value_statement.h>
-#include <vivified/code/vivi_code_statement.h>
-#include <vivified/code/vivi_code_value.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _ViviCodeTrace ViviCodeTrace;
-typedef struct _ViviCodeTraceClass ViviCodeTraceClass;
-
-#define VIVI_TYPE_CODE_TRACE                    (vivi_code_trace_get_type())
-#define VIVI_IS_CODE_TRACE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_TRACE))
-#define VIVI_IS_CODE_TRACE_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_TRACE))
-#define VIVI_CODE_TRACE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_TRACE, ViviCodeTrace))
-#define VIVI_CODE_TRACE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_TRACE, ViviCodeTraceClass))
-#define VIVI_CODE_TRACE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_TRACE, ViviCodeTraceClass))
-
-struct _ViviCodeTrace
-{
-  ViviCodeBuiltinValueStatement	statement;
-
-  ViviCodeValue *	value;
-};
-
-struct _ViviCodeTraceClass
-{
-  ViviCodeBuiltinValueStatementClass	statement_class;
-};
-
-GType			vivi_code_trace_get_type   	(void);
-
-ViviCodeStatement *	vivi_code_trace_new		(ViviCodeValue *	value);
-
-
-G_END_DECLS
-#endif
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 53787c0..751e5ca 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -33,6 +33,7 @@
 #include "vivi_code_binary_default.h"
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
+#include "vivi_code_builtin_value_statement_default.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
@@ -45,7 +46,6 @@
 #include "vivi_code_loop.h"
 #include "vivi_code_or.h"
 #include "vivi_code_return.h"
-#include "vivi_code_trace.h"
 #include "vivi_code_unary.h"
 #include "vivi_code_value_statement.h"
 #include "vivi_decompiler_block.h"
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index d8cb743..4476ba9 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -33,6 +33,7 @@
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
 #include "vivi_code_builtin_statement_default.h"
+#include "vivi_code_builtin_value_statement_default.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
@@ -47,7 +48,6 @@
 #include "vivi_code_or.h"
 #include "vivi_code_return.h"
 #include "vivi_code_throw.h"
-#include "vivi_code_trace.h"
 #include "vivi_code_unary.h"
 #include "vivi_code_value_statement.h"
 #include "vivi_compiler_empty_statement.h"
@@ -973,9 +973,9 @@ static const SpecialFunction special_functions[] = {
   { FALSE, "play",               vivi_code_play_new, NULL, NULL },
   { FALSE, "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
   //{ TRUE,  "random",             NULL, vivi_code_random_new, NULL },
-  //{ FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
+  { FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
   //{ FALSE, "setProperty",        NULL, NULL, parse_set_property },
-  //{ FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
+  { FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
   //{ FALSE, "startDrag",          NULL, NULL, parse_start_drag },
   { FALSE, "stop",               vivi_code_stop_new, NULL, NULL },
   { FALSE, "stopDrag",           vivi_code_stop_drag_new,NULL,  NULL },
commit afb7f9e3070f006d56b7541dafc0589b5210d317
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 12:53:52 2008 +0300

    Forgot stop and stopDrag builtin statements

diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index e2ba013..b271cb8 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -59,6 +59,8 @@ DEFAULT_BINARY (Or,		or,		"||",	???,				VIVI_PRECEDENCE_AND)
 DEFAULT_BUILTIN_STATEMENT (NextFrame,		next_frame,	"nextFrame",		SWFDEC_AS_ACTION_NEXT_FRAME)
 DEFAULT_BUILTIN_STATEMENT (Play,		play,		"play",			SWFDEC_AS_ACTION_PLAY)
 DEFAULT_BUILTIN_STATEMENT (PreviousFrame,	previous_frame,	"prevFrame",		SWFDEC_AS_ACTION_PREVIOUS_FRAME)
+DEFAULT_BUILTIN_STATEMENT (Stop,		stop,		"stop",			SWFDEC_AS_ACTION_STOP)
+DEFAULT_BUILTIN_STATEMENT (StopDrag,		stop_drag,	"stopDrag",		SWFDEC_AS_ACTION_END_DRAG)
 DEFAULT_BUILTIN_STATEMENT (StopSounds,		stop_sounds,	"stopSounds",		SWFDEC_AS_ACTION_STOP_SOUNDS)
 DEFAULT_BUILTIN_STATEMENT (ToggleQuality,	toggle_quality,	"toggleQuality",	SWFDEC_AS_ACTION_TOGGLE_QUALITY)
 
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 4f17f93..d8cb743 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -952,38 +952,38 @@ typedef struct {
 
 static const SpecialFunction special_functions[] = {
   //{ FALSE, "callFrame",          NULL, vivi_code_call_frame_new, NULL },
+  //{ TRUE,  "chr",                NULL, vivi_code_chr_new, NULL },
+  //{ TRUE,  "concat",             NULL, NULL, parse_concat },
   //{ FALSE, "duplicateMovieClip", NULL, NULL, parse_duplicate_movie_clip },
+  //{ TRUE,  "eval",               NULL, vivi_code_eval_new, NULL },
+  //{ TRUE,  "getProperty",        NULL, NULL, parse_get_property },
+  //{ TRUE,  "getTimer",           vivi_code_get_timer_new, NULL, NULL },
   //{ FALSE, "getURL1",            NULL, NULL, parse_get_url1 },
   //{ FALSE, "getURL",             NULL, NULL, parse_get_url },
   //{ FALSE, "gotoAndPlay",        NULL, vivi_code_goto_and_play_new, NULL },
   //{ FALSE, "gotoAndStop",        NULL, vivi_code_goto_and_stop_new, NULL },
+  //{ TRUE,  "int",                NULL, vivi_code_int_new, NULL },
+  //{ TRUE,  "length",             NULL, vivi_code_length_new, NULL },
   //{ FALSE, "loadMovie",          NULL, NULL, parse_load_movie },
   //{ FALSE, "loadMovieNum",       NULL, NULL, parse_load_movie_num },
   //{ FALSE, "loadVariables",      NULL, NULL, parse_load_variables },
   //{ FALSE, "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
   { FALSE, "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
+  //{ TRUE,  "ord",                NULL, vivi_code_ord_new, NULL },
   { FALSE, "play",               vivi_code_play_new, NULL, NULL },
   { FALSE, "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
+  //{ TRUE,  "random",             NULL, vivi_code_random_new, NULL },
   //{ FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
   //{ FALSE, "setProperty",        NULL, NULL, parse_set_property },
   //{ FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
   //{ FALSE, "startDrag",          NULL, NULL, parse_start_drag },
-  //{ FALSE, "stopDrag",           NULL, vivi_code_stop_drag_new, NULL },
-  //{ FALSE, "stop",               NULL, vivi_code_stop_new, NULL },
+  { FALSE, "stop",               vivi_code_stop_new, NULL, NULL },
+  { FALSE, "stopDrag",           vivi_code_stop_drag_new,NULL,  NULL },
   { FALSE, "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
-  { FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
-  { FALSE, "trace",              NULL, vivi_code_trace_new, NULL }//,
-  //{ TRUE,  "concat",             NULL, NULL, parse_concat },
   //{ TRUE,  "substring",          NULL, NULL, parse_substring },
-  //{ TRUE,  "getProperty",        NULL, NULL, parse_get_property },
   //{ TRUE,  "targetPath",         NULL, vivi_code_target_path_new, NULL },
-  //{ TRUE,  "eval",               NULL, vivi_code_eval_new, NULL },
-  //{ TRUE,  "getTimer",           vivi_code_get_timer_new, NULL, NULL },
-  //{ TRUE,  "random",             NULL, vivi_code_random_new, NULL },
-  //{ TRUE,  "length",             NULL, vivi_code_length_new, NULL },
-  //{ TRUE,  "int",                NULL, vivi_code_int_new, NULL },
-  //{ TRUE,  "ord",                NULL, vivi_code_ord_new, NULL },
-  //{ TRUE,  "chr",                NULL, vivi_code_chr_new, NULL },
+  { FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
+  { FALSE, "trace",              NULL, vivi_code_trace_new, NULL }//,
   //{ TRUE,  "typeOf",             NULL, vivi_code_type_of_new, NULL }
 };
 
commit adeb64f187d732a919f7ea6766a2d50aa976bb6f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 12:37:42 2008 +0300

    Create ViviCodeBuiltinStatements with a macro

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index e23e51c..ead59b2 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -23,6 +23,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_block.c \
 	vivi_code_break.c \
 	vivi_code_builtin_statement.c \
+	vivi_code_builtin_statement_default.c \
 	vivi_code_builtin_value_statement.c \
 	vivi_code_comment.c \
 	vivi_code_compiler.c \
@@ -39,7 +40,6 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_label.c \
 	vivi_code_loop.c \
 	vivi_code_or.c \
-	vivi_code_play.c \
 	vivi_code_printer.c \
 	vivi_code_return.c \
 	vivi_code_statement.c \
@@ -69,6 +69,7 @@ noinst_HEADERS = \
 	vivi_code_block.h \
 	vivi_code_break.h \
 	vivi_code_builtin_statement.h \
+	vivi_code_builtin_statement_default.h \
 	vivi_code_builtin_value_statement.h \
 	vivi_code_comment.h \
 	vivi_code_compiler.h \
@@ -86,7 +87,6 @@ noinst_HEADERS = \
 	vivi_code_label.h \
 	vivi_code_loop.h \
 	vivi_code_or.h \
-	vivi_code_play.h \
 	vivi_code_printer.h \
 	vivi_code_return.h \
 	vivi_code_statement.h \
diff --git a/vivified/code/vivi_code_builtin_statement_default.c b/vivified/code/vivi_code_builtin_statement_default.c
new file mode 100644
index 0000000..c464f02
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_statement_default.c
@@ -0,0 +1,52 @@
+/* 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_builtin_statement_default.h"
+
+#define DEFAULT_BUILTIN_STATEMENT(CapsName, underscore_name, name, bc) \
+\
+G_DEFINE_TYPE (ViviCode ## CapsName, vivi_code_ ## underscore_name, VIVI_TYPE_CODE_BUILTIN_STATEMENT) \
+\
+static void \
+vivi_code_ ## underscore_name ## _class_init (ViviCodeBuiltinStatementClass *klass) \
+{ \
+  ViviCodeBuiltinStatementClass *builtin_statement_class = VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass); \
+\
+  builtin_statement_class->function_name = name; \
+  builtin_statement_class->bytecode = bc; \
+} \
+\
+static void \
+vivi_code_ ## underscore_name ## _init (ViviCodeBuiltinStatement *builtin_statement) \
+{ \
+} \
+\
+ViviCodeStatement * \
+vivi_code_ ## underscore_name ## _new (void) \
+{ \
+  return VIVI_CODE_STATEMENT ( \
+      g_object_new (vivi_code_ ## underscore_name ## _get_type (), NULL)); \
+}
+
+#include "vivi_code_defaults.h"
diff --git a/vivified/code/vivi_code_builtin_statement_default.h b/vivified/code/vivi_code_builtin_statement_default.h
new file mode 100644
index 0000000..78c1611
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_statement_default.h
@@ -0,0 +1,41 @@
+/* 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_BUILTIN_STATEMENT_DEFAULT_H_
+#define _VIVI_CODE_BUILTIN_STATEMENT_DEFAULT_H_
+
+#include <vivified/code/vivi_code_builtin_statement.h>
+
+G_BEGIN_DECLS
+
+#define DEFAULT_BUILTIN_STATEMENT(CapsName, underscore_name, function_name, bytecode) \
+\
+typedef ViviCodeBuiltinStatement ViviCode ## CapsName; \
+typedef ViviCodeBuiltinStatementClass ViviCode ## CapsName ## Class; \
+\
+GType			vivi_code_ ## underscore_name ## _get_type   	(void); \
+\
+ViviCodeStatement *	vivi_code_## underscore_name ## _new		(void);
+
+#include "vivi_code_defaults.h"
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index 28b9b4d..e2ba013 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -56,6 +56,10 @@ DEFAULT_BINARY (Or,		or,		"||",	???,				VIVI_PRECEDENCE_AND)
 #define DEFAULT_BUILTIN_STATEMENT(CapsName, underscore_name, function_name, bytecode)
 #endif
 
-DEFAULT_BUILTIN_STATEMENT (GetTimer,	get_timer,	"getTimer",	SWFDEC_AS_ACTION_GET_TIME)
+DEFAULT_BUILTIN_STATEMENT (NextFrame,		next_frame,	"nextFrame",		SWFDEC_AS_ACTION_NEXT_FRAME)
+DEFAULT_BUILTIN_STATEMENT (Play,		play,		"play",			SWFDEC_AS_ACTION_PLAY)
+DEFAULT_BUILTIN_STATEMENT (PreviousFrame,	previous_frame,	"prevFrame",		SWFDEC_AS_ACTION_PREVIOUS_FRAME)
+DEFAULT_BUILTIN_STATEMENT (StopSounds,		stop_sounds,	"stopSounds",		SWFDEC_AS_ACTION_STOP_SOUNDS)
+DEFAULT_BUILTIN_STATEMENT (ToggleQuality,	toggle_quality,	"toggleQuality",	SWFDEC_AS_ACTION_TOGGLE_QUALITY)
 
 #undef DEFAULT_BUILTIN_STATEMENT
diff --git a/vivified/code/vivi_code_play.c b/vivified/code/vivi_code_play.c
deleted file mode 100644
index e6e0475..0000000
--- a/vivified/code/vivi_code_play.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "vivi_code_play.h"
-
-G_DEFINE_TYPE (ViviCodePlay, vivi_code_play, VIVI_TYPE_CODE_BUILTIN_STATEMENT)
-
-static void
-vivi_code_play_class_init (ViviCodePlayClass *klass)
-{
-  ViviCodeBuiltinStatementClass *stmt_class =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass);
-
-  stmt_class->function_name = "play";
-  stmt_class->bytecode = SWFDEC_AS_ACTION_PLAY;
-}
-
-static void
-vivi_code_play_init (ViviCodePlay *token)
-{
-}
-
-ViviCodeStatement *
-vivi_code_play_new (void)
-{
-  return g_object_new (VIVI_TYPE_CODE_PLAY, NULL);
-}
diff --git a/vivified/code/vivi_code_play.h b/vivified/code/vivi_code_play.h
deleted file mode 100644
index d328738..0000000
--- a/vivified/code/vivi_code_play.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifndef _VIVI_CODE_PLAY_H_
-#define _VIVI_CODE_PLAY_H_
-
-#include <vivified/code/vivi_code_builtin_statement.h>
-#include <vivified/code/vivi_code_statement.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _ViviCodePlay ViviCodePlay;
-typedef struct _ViviCodePlayClass ViviCodePlayClass;
-
-#define VIVI_TYPE_CODE_PLAY                    (vivi_code_play_get_type())
-#define VIVI_IS_CODE_PLAY(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_PLAY))
-#define VIVI_IS_CODE_PLAY_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_PLAY))
-#define VIVI_CODE_PLAY(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_PLAY, ViviCodePlay))
-#define VIVI_CODE_PLAY_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_PLAY, ViviCodePlayClass))
-#define VIVI_CODE_PLAY_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_PLAY, ViviCodePlayClass))
-
-struct _ViviCodePlay
-{
-  ViviCodeBuiltinStatement	statement;
-};
-
-struct _ViviCodePlayClass
-{
-  ViviCodeBuiltinStatementClass	statement_class;
-};
-
-GType			vivi_code_play_get_type   	(void);
-
-ViviCodeStatement *	vivi_code_play_new		(void);
-
-
-G_END_DECLS
-#endif
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 4f37bb6..4f17f93 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -32,6 +32,7 @@
 #include "vivi_code_binary_default.h"
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
+#include "vivi_code_builtin_statement_default.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_continue.h"
 #include "vivi_code_function.h"
@@ -44,7 +45,6 @@
 #include "vivi_code_init_object.h"
 #include "vivi_code_loop.h"
 #include "vivi_code_or.h"
-#include "vivi_code_play.h"
 #include "vivi_code_return.h"
 #include "vivi_code_throw.h"
 #include "vivi_code_trace.h"
@@ -961,17 +961,17 @@ static const SpecialFunction special_functions[] = {
   //{ FALSE, "loadMovieNum",       NULL, NULL, parse_load_movie_num },
   //{ FALSE, "loadVariables",      NULL, NULL, parse_load_variables },
   //{ FALSE, "loadVariablesNum",   NULL, NULL, parse_load_variables_num },
-  //{ FALSE, "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
+  { FALSE, "nextFrame",          vivi_code_next_frame_new, NULL, NULL },
   { FALSE, "play",               vivi_code_play_new, NULL, NULL },
-  //{ FALSE, "prevFrame",          vivi_code_prev_frame_new, NULL, NULL },
+  { FALSE, "prevFrame",          vivi_code_previous_frame_new, NULL, NULL },
   //{ FALSE, "removeMovieClip",    NULL, vivi_code_remove_movie_clip_new, NULL },
   //{ FALSE, "setProperty",        NULL, NULL, parse_set_property },
   //{ FALSE, "setTarget",          NULL, vivi_code_set_target_new, NULL },
   //{ FALSE, "startDrag",          NULL, NULL, parse_start_drag },
   //{ FALSE, "stopDrag",           NULL, vivi_code_stop_drag_new, NULL },
   //{ FALSE, "stop",               NULL, vivi_code_stop_new, NULL },
-  //{ FALSE, "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
-  //{ FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
+  { FALSE, "stopSounds",         vivi_code_stop_sounds_new, NULL, NULL },
+  { FALSE, "toggleQuality",      vivi_code_toggle_quality_new, NULL, NULL },
   { FALSE, "trace",              NULL, vivi_code_trace_new, NULL }//,
   //{ TRUE,  "concat",             NULL, NULL, parse_concat },
   //{ TRUE,  "substring",          NULL, NULL, parse_substring },
commit 1d53eee1b5f80acbebf2d804c0c5d67a2a6506f3
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 12:37:13 2008 +0300

    Oops, use GET_CLASS not CLASS

diff --git a/vivified/code/vivi_code_builtin_statement.c b/vivified/code/vivi_code_builtin_statement.c
index 7f09f4f..0abea7c 100644
--- a/vivified/code/vivi_code_builtin_statement.c
+++ b/vivified/code/vivi_code_builtin_statement.c
@@ -32,7 +32,7 @@ vivi_code_builtin_statement_print (ViviCodeToken *token,
     ViviCodePrinter *printer)
 {
   ViviCodeBuiltinStatementClass *klass =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+    VIVI_CODE_BUILTIN_STATEMENT_GET_CLASS (token);
 
   g_assert (klass->function_name != NULL);
   vivi_code_printer_print (printer, klass->function_name);
@@ -45,7 +45,7 @@ vivi_code_builtin_statement_compile (ViviCodeToken *token,
     ViviCodeCompiler *compiler)
 {
   ViviCodeBuiltinStatementClass *klass =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+    VIVI_CODE_BUILTIN_STATEMENT_GET_CLASS (token);
 
   g_assert (klass->bytecode != SWFDEC_AS_ACTION_END);
   vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
diff --git a/vivified/code/vivi_code_builtin_value_statement.c b/vivified/code/vivi_code_builtin_value_statement.c
index 36919c0..c4f85a5 100644
--- a/vivified/code/vivi_code_builtin_value_statement.c
+++ b/vivified/code/vivi_code_builtin_value_statement.c
@@ -44,7 +44,7 @@ vivi_code_builtin_value_statement_print (ViviCodeToken *token,
     ViviCodePrinter *printer)
 {
   ViviCodeBuiltinStatementClass *klass =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+    VIVI_CODE_BUILTIN_STATEMENT_GET_CLASS (token);
   ViviCodeBuiltinValueStatement *stmt =
     VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
 
@@ -64,7 +64,7 @@ vivi_code_builtin_value_statement_compile (ViviCodeToken *token,
     ViviCodeCompiler *compiler)
 {
   ViviCodeBuiltinStatementClass *klass =
-    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+    VIVI_CODE_BUILTIN_STATEMENT_GET_CLASS (token);
   ViviCodeBuiltinValueStatement *stmt =
     VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
 
commit 12458b9f35e02c49d91093e2b5f186172a557bc3
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 10:17:38 2008 +0300

    Save function name and bytecode to class, not instance, in BuiltinStatement

diff --git a/vivified/code/vivi_code_builtin_statement.c b/vivified/code/vivi_code_builtin_statement.c
index 2fe6b19..7f09f4f 100644
--- a/vivified/code/vivi_code_builtin_statement.c
+++ b/vivified/code/vivi_code_builtin_statement.c
@@ -31,10 +31,11 @@ static void
 vivi_code_builtin_statement_print (ViviCodeToken *token,
     ViviCodePrinter *printer)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+  ViviCodeBuiltinStatementClass *klass =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
 
-  g_assert (stmt->name != NULL);
-  vivi_code_printer_print (printer, stmt->name);
+  g_assert (klass->function_name != NULL);
+  vivi_code_printer_print (printer, klass->function_name);
   vivi_code_printer_print (printer, " ();");
   vivi_code_printer_new_line (printer, FALSE);
 }
@@ -43,10 +44,11 @@ static void
 vivi_code_builtin_statement_compile (ViviCodeToken *token,
     ViviCodeCompiler *compiler)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+  ViviCodeBuiltinStatementClass *klass =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
 
-  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
-  vivi_code_compiler_write_empty_action (compiler, stmt->action);
+  g_assert (klass->bytecode != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
 }
 
 static void
diff --git a/vivified/code/vivi_code_builtin_statement.h b/vivified/code/vivi_code_builtin_statement.h
index 2938ee7..2a26b5b 100644
--- a/vivified/code/vivi_code_builtin_statement.h
+++ b/vivified/code/vivi_code_builtin_statement.h
@@ -39,15 +39,15 @@ typedef struct _ViviCodeBuiltinStatementClass ViviCodeBuiltinStatementClass;
 
 struct _ViviCodeBuiltinStatement
 {
-  ViviCodeStatement	statement;
-
-  const char		*name;
-  SwfdecAsAction	action;
+  ViviCodeStatement		statement;
 };
 
 struct _ViviCodeBuiltinStatementClass
 {
   ViviCodeStatementClass	statement_class;
+
+  const char *			function_name;
+  SwfdecAsAction		bytecode;
 };
 
 GType		vivi_code_builtin_statement_get_type		(void);
diff --git a/vivified/code/vivi_code_builtin_value_statement.c b/vivified/code/vivi_code_builtin_value_statement.c
index 382748a..36919c0 100644
--- a/vivified/code/vivi_code_builtin_value_statement.c
+++ b/vivified/code/vivi_code_builtin_value_statement.c
@@ -43,17 +43,17 @@ static void
 vivi_code_builtin_value_statement_print (ViviCodeToken *token,
     ViviCodePrinter *printer)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
-  ViviCodeBuiltinValueStatement *stmt_value =
+  ViviCodeBuiltinStatementClass *klass =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+  ViviCodeBuiltinValueStatement *stmt =
     VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
 
-  g_assert (stmt->name != NULL);
-  vivi_code_printer_print (printer, stmt->name);
+  g_assert (klass->function_name != NULL);
+  vivi_code_printer_print (printer, klass->function_name);
   vivi_code_printer_print (printer, " (");
 
-  g_assert (stmt_value->value != NULL);
-  vivi_code_printer_print_value (printer, stmt_value->value,
-      VIVI_PRECEDENCE_COMMA);
+  g_assert (stmt->value != NULL);
+  vivi_code_printer_print_value (printer, stmt->value, VIVI_PRECEDENCE_COMMA);
 
   vivi_code_printer_print (printer, ");");
   vivi_code_printer_new_line (printer, FALSE);
@@ -63,15 +63,16 @@ static void
 vivi_code_builtin_value_statement_compile (ViviCodeToken *token,
     ViviCodeCompiler *compiler)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
-  ViviCodeBuiltinValueStatement *stmt_value =
+  ViviCodeBuiltinStatementClass *klass =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (token);
+  ViviCodeBuiltinValueStatement *stmt =
     VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
 
-  g_assert (stmt_value->value != NULL);
-  vivi_code_compiler_compile_value (compiler, stmt_value->value);
+  g_assert (stmt->value != NULL);
+  vivi_code_compiler_compile_value (compiler, stmt->value);
 
-  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
-  vivi_code_compiler_write_empty_action (compiler, stmt->action);
+  g_assert (klass->bytecode != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
 }
 
 static void
diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
index f18b2ce..28b9b4d 100644
--- a/vivified/code/vivi_code_defaults.h
+++ b/vivified/code/vivi_code_defaults.h
@@ -1,5 +1,6 @@
 /* Vivified
  * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *                    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
@@ -50,3 +51,11 @@ DEFAULT_BINARY (Or,		or,		"||",	???,				VIVI_PRECEDENCE_AND)
 */
 
 #undef DEFAULT_BINARY
+
+#ifndef DEFAULT_BUILTIN_STATEMENT
+#define DEFAULT_BUILTIN_STATEMENT(CapsName, underscore_name, function_name, bytecode)
+#endif
+
+DEFAULT_BUILTIN_STATEMENT (GetTimer,	get_timer,	"getTimer",	SWFDEC_AS_ACTION_GET_TIME)
+
+#undef DEFAULT_BUILTIN_STATEMENT
diff --git a/vivified/code/vivi_code_play.c b/vivified/code/vivi_code_play.c
index 7494a64..e6e0475 100644
--- a/vivified/code/vivi_code_play.c
+++ b/vivified/code/vivi_code_play.c
@@ -28,15 +28,16 @@ G_DEFINE_TYPE (ViviCodePlay, vivi_code_play, VIVI_TYPE_CODE_BUILTIN_STATEMENT)
 static void
 vivi_code_play_class_init (ViviCodePlayClass *klass)
 {
+  ViviCodeBuiltinStatementClass *stmt_class =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass);
+
+  stmt_class->function_name = "play";
+  stmt_class->bytecode = SWFDEC_AS_ACTION_PLAY;
 }
 
 static void
 vivi_code_play_init (ViviCodePlay *token)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
-
-  stmt->name = "play";
-  stmt->action = SWFDEC_AS_ACTION_PLAY;
 }
 
 ViviCodeStatement *
diff --git a/vivified/code/vivi_code_trace.c b/vivified/code/vivi_code_trace.c
index a2b7c4f..e30db40 100644
--- a/vivified/code/vivi_code_trace.c
+++ b/vivified/code/vivi_code_trace.c
@@ -28,15 +28,16 @@ G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_BUILTIN_VALUE_STAT
 static void
 vivi_code_trace_class_init (ViviCodeTraceClass *klass)
 {
+  ViviCodeBuiltinStatementClass *stmt_class =
+    VIVI_CODE_BUILTIN_STATEMENT_CLASS (klass);
+
+  stmt_class->function_name = "trace";
+  stmt_class->bytecode = SWFDEC_AS_ACTION_TRACE;
 }
 
 static void
 vivi_code_trace_init (ViviCodeTrace *token)
 {
-  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
-
-  stmt->name = "trace";
-  stmt->action = SWFDEC_AS_ACTION_TRACE;
 }
 
 ViviCodeStatement *
commit 7b511ff97a3cb0ff7c9d05dd9d1ecb292c7514e2
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Apr 14 09:57:10 2008 +0300

    Rename SpecialStatement to BuiltinStatement. Move value handling to subclass

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 205e734..e23e51c 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -22,6 +22,8 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_binary_default.c \
 	vivi_code_block.c \
 	vivi_code_break.c \
+	vivi_code_builtin_statement.c \
+	vivi_code_builtin_value_statement.c \
 	vivi_code_comment.c \
 	vivi_code_compiler.c \
 	vivi_code_constant.c \
@@ -40,7 +42,6 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_play.c \
 	vivi_code_printer.c \
 	vivi_code_return.c \
-	vivi_code_special_statement.c \
 	vivi_code_statement.c \
 	vivi_code_text_printer.c \
 	vivi_code_throw.c \
@@ -67,6 +68,8 @@ noinst_HEADERS = \
 	vivi_code_binary_default.h \
 	vivi_code_block.h \
 	vivi_code_break.h \
+	vivi_code_builtin_statement.h \
+	vivi_code_builtin_value_statement.h \
 	vivi_code_comment.h \
 	vivi_code_compiler.h \
 	vivi_code_constant.h \
@@ -86,7 +89,6 @@ noinst_HEADERS = \
 	vivi_code_play.h \
 	vivi_code_printer.h \
 	vivi_code_return.h \
-	vivi_code_special_statement.h \
 	vivi_code_statement.h \
 	vivi_code_text_printer.h \
 	vivi_code_throw.h \
diff --git a/vivified/code/vivi_code_builtin_statement.c b/vivified/code/vivi_code_builtin_statement.c
new file mode 100644
index 0000000..2fe6b19
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_statement.c
@@ -0,0 +1,64 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_builtin_statement.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_ABSTRACT_TYPE (ViviCodeBuiltinStatement, vivi_code_builtin_statement, VIVI_TYPE_CODE_STATEMENT)
+
+static void
+vivi_code_builtin_statement_print (ViviCodeToken *token,
+    ViviCodePrinter *printer)
+{
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+
+  g_assert (stmt->name != NULL);
+  vivi_code_printer_print (printer, stmt->name);
+  vivi_code_printer_print (printer, " ();");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_builtin_statement_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+
+  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, stmt->action);
+}
+
+static void
+vivi_code_builtin_statement_class_init (ViviCodeBuiltinStatementClass *klass)
+{
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  token_class->print = vivi_code_builtin_statement_print;
+  token_class->compile = vivi_code_builtin_statement_compile;
+}
+
+static void
+vivi_code_builtin_statement_init (ViviCodeBuiltinStatement *stmt)
+{
+}
diff --git a/vivified/code/vivi_code_builtin_statement.h b/vivified/code/vivi_code_builtin_statement.h
new file mode 100644
index 0000000..2938ee7
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_statement.h
@@ -0,0 +1,57 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_BUILTIN_STATEMENT_H_
+#define _VIVI_CODE_BUILTIN_STATEMENT_H_
+
+#include <swfdec/swfdec_as_interpret.h>
+
+#include <vivified/code/vivi_code_statement.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeBuiltinStatement ViviCodeBuiltinStatement;
+typedef struct _ViviCodeBuiltinStatementClass ViviCodeBuiltinStatementClass;
+
+#define VIVI_TYPE_CODE_BUILTIN_STATEMENT                    (vivi_code_builtin_statement_get_type())
+#define VIVI_IS_CODE_BUILTIN_STATEMENT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_BUILTIN_STATEMENT))
+#define VIVI_IS_CODE_BUILTIN_STATEMENT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_BUILTIN_STATEMENT))
+#define VIVI_CODE_BUILTIN_STATEMENT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_BUILTIN_STATEMENT, ViviCodeBuiltinStatement))
+#define VIVI_CODE_BUILTIN_STATEMENT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_BUILTIN_STATEMENT, ViviCodeBuiltinStatementClass))
+#define VIVI_CODE_BUILTIN_STATEMENT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_BUILTIN_STATEMENT, ViviCodeBuiltinStatementClass))
+
+struct _ViviCodeBuiltinStatement
+{
+  ViviCodeStatement	statement;
+
+  const char		*name;
+  SwfdecAsAction	action;
+};
+
+struct _ViviCodeBuiltinStatementClass
+{
+  ViviCodeStatementClass	statement_class;
+};
+
+GType		vivi_code_builtin_statement_get_type		(void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_builtin_value_statement.c b/vivified/code/vivi_code_builtin_value_statement.c
new file mode 100644
index 0000000..382748a
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_statement.c
@@ -0,0 +1,114 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_builtin_value_statement.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
+
+G_DEFINE_ABSTRACT_TYPE (ViviCodeBuiltinValueStatement, vivi_code_builtin_value_statement, VIVI_TYPE_CODE_BUILTIN_STATEMENT)
+
+static void
+vivi_code_builtin_value_statement_dispose (GObject *object)
+{
+  ViviCodeBuiltinValueStatement *stmt =
+    VIVI_CODE_BUILTIN_VALUE_STATEMENT (object);
+
+  g_assert (stmt->value != NULL);
+  g_object_unref (stmt->value);
+
+  G_OBJECT_CLASS (vivi_code_builtin_value_statement_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_builtin_value_statement_print (ViviCodeToken *token,
+    ViviCodePrinter *printer)
+{
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+  ViviCodeBuiltinValueStatement *stmt_value =
+    VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
+
+  g_assert (stmt->name != NULL);
+  vivi_code_printer_print (printer, stmt->name);
+  vivi_code_printer_print (printer, " (");
+
+  g_assert (stmt_value->value != NULL);
+  vivi_code_printer_print_value (printer, stmt_value->value,
+      VIVI_PRECEDENCE_COMMA);
+
+  vivi_code_printer_print (printer, ");");
+  vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_builtin_value_statement_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
+  ViviCodeBuiltinValueStatement *stmt_value =
+    VIVI_CODE_BUILTIN_VALUE_STATEMENT (token);
+
+  g_assert (stmt_value->value != NULL);
+  vivi_code_compiler_compile_value (compiler, stmt_value->value);
+
+  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
+  vivi_code_compiler_write_empty_action (compiler, stmt->action);
+}
+
+static void
+vivi_code_builtin_value_statement_class_init (
+    ViviCodeBuiltinValueStatementClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+  object_class->dispose = vivi_code_builtin_value_statement_dispose;
+
+  token_class->print = vivi_code_builtin_value_statement_print;
+  token_class->compile = vivi_code_builtin_value_statement_compile;
+}
+
+static void
+vivi_code_builtin_value_statement_init (ViviCodeBuiltinValueStatement *stmt)
+{
+}
+
+void
+vivi_code_builtin_value_statement_set_value (
+    ViviCodeBuiltinValueStatement *stmt, ViviCodeValue *value)
+{
+  g_return_if_fail (VIVI_IS_CODE_BUILTIN_VALUE_STATEMENT (stmt));
+  g_return_if_fail (VIVI_IS_CODE_VALUE (value));
+
+  if (stmt->value)
+    g_object_unref (value);
+  stmt->value = g_object_ref (value);
+}
+
+ViviCodeValue *
+vivi_code_builtin_value_statement_get_value (
+    ViviCodeBuiltinValueStatement *stmt)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_BUILTIN_VALUE_STATEMENT (stmt), NULL);
+
+  return stmt->value;
+}
diff --git a/vivified/code/vivi_code_builtin_value_statement.h b/vivified/code/vivi_code_builtin_value_statement.h
new file mode 100644
index 0000000..9366137
--- /dev/null
+++ b/vivified/code/vivi_code_builtin_value_statement.h
@@ -0,0 +1,60 @@
+/* Vivified
+ * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_BUILTIN_VALUE_STATEMENT_H_
+#define _VIVI_CODE_BUILTIN_VALUE_STATEMENT_H_
+
+#include <swfdec/swfdec_as_interpret.h>
+
+#include <vivified/code/vivi_code_builtin_statement.h>
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeBuiltinValueStatement ViviCodeBuiltinValueStatement;
+typedef struct _ViviCodeBuiltinValueStatementClass ViviCodeBuiltinValueStatementClass;
+
+#define VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT                    (vivi_code_builtin_value_statement_get_type())
+#define VIVI_IS_CODE_BUILTIN_VALUE_STATEMENT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT))
+#define VIVI_IS_CODE_BUILTIN_VALUE_STATEMENT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT))
+#define VIVI_CODE_BUILTIN_VALUE_STATEMENT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT, ViviCodeBuiltinValueStatement))
+#define VIVI_CODE_BUILTIN_VALUE_STATEMENT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT, ViviCodeBuiltinValueStatementClass))
+#define VIVI_CODE_BUILTIN_VALUE_STATEMENT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT, ViviCodeBuiltinValueStatementClass))
+
+struct _ViviCodeBuiltinValueStatement
+{
+  ViviCodeBuiltinStatement	statement;
+
+  ViviCodeValue *		value;
+};
+
+struct _ViviCodeBuiltinValueStatementClass
+{
+  ViviCodeBuiltinStatementClass	statement_class;
+};
+
+GType		vivi_code_builtin_value_statement_get_type		(void);
+
+void		vivi_code_builtin_value_statement_set_value		(ViviCodeBuiltinValueStatement *	stmt,
+									 ViviCodeValue *			value);
+ViviCodeValue *	vivi_code_builtin_value_statement_get_value		(ViviCodeBuiltinValueStatement *	stmt);
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_play.c b/vivified/code/vivi_code_play.c
index 4b3f3cf..7494a64 100644
--- a/vivified/code/vivi_code_play.c
+++ b/vivified/code/vivi_code_play.c
@@ -23,7 +23,7 @@
 
 #include "vivi_code_play.h"
 
-G_DEFINE_TYPE (ViviCodePlay, vivi_code_play, VIVI_TYPE_CODE_SPECIAL_STATEMENT)
+G_DEFINE_TYPE (ViviCodePlay, vivi_code_play, VIVI_TYPE_CODE_BUILTIN_STATEMENT)
 
 static void
 vivi_code_play_class_init (ViviCodePlayClass *klass)
@@ -33,7 +33,7 @@ vivi_code_play_class_init (ViviCodePlayClass *klass)
 static void
 vivi_code_play_init (ViviCodePlay *token)
 {
-  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
 
   stmt->name = "play";
   stmt->action = SWFDEC_AS_ACTION_PLAY;
diff --git a/vivified/code/vivi_code_play.h b/vivified/code/vivi_code_play.h
index 371dd57..d328738 100644
--- a/vivified/code/vivi_code_play.h
+++ b/vivified/code/vivi_code_play.h
@@ -20,7 +20,7 @@
 #ifndef _VIVI_CODE_PLAY_H_
 #define _VIVI_CODE_PLAY_H_
 
-#include <vivified/code/vivi_code_special_statement.h>
+#include <vivified/code/vivi_code_builtin_statement.h>
 #include <vivified/code/vivi_code_statement.h>
 
 G_BEGIN_DECLS
@@ -38,12 +38,12 @@ typedef struct _ViviCodePlayClass ViviCodePlayClass;
 
 struct _ViviCodePlay
 {
-  ViviCodeSpecialStatement	statement;
+  ViviCodeBuiltinStatement	statement;
 };
 
 struct _ViviCodePlayClass
 {
-  ViviCodeSpecialStatementClass	statement_class;
+  ViviCodeBuiltinStatementClass	statement_class;
 };
 
 GType			vivi_code_play_get_type   	(void);
diff --git a/vivified/code/vivi_code_special_statement.c b/vivified/code/vivi_code_special_statement.c
deleted file mode 100644
index e0b5e07..0000000
--- a/vivified/code/vivi_code_special_statement.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include "vivi_code_special_statement.h"
-#include "vivi_code_printer.h"
-#include "vivi_code_compiler.h"
-
-G_DEFINE_ABSTRACT_TYPE (ViviCodeSpecialStatement, vivi_code_special_statement, VIVI_TYPE_CODE_STATEMENT)
-
-static void
-vivi_code_special_statement_print (ViviCodeToken *token,
-    ViviCodePrinter *printer)
-{
-  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
-  ViviCodeSpecialStatementClass *klass =
-    VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS (stmt);
-
-  g_assert (stmt->name != NULL);
-  vivi_code_printer_print (printer, stmt->name);
-
-  vivi_code_printer_print (printer, " (");
-
-  if (klass->get_value != NULL) {
-    vivi_code_printer_print_value (printer, klass->get_value (stmt),
-	VIVI_PRECEDENCE_COMMA);
-  }
-
-  vivi_code_printer_print (printer, ");");
-  vivi_code_printer_new_line (printer, FALSE);
-}
-
-static void
-vivi_code_special_statement_compile (ViviCodeToken *token,
-    ViviCodeCompiler *compiler)
-{
-  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
-  ViviCodeSpecialStatementClass *klass =
-    VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS (stmt);
-
-  if (klass->get_value != NULL)
-    vivi_code_compiler_compile_value (compiler, klass->get_value (stmt));
-
-  g_assert (stmt->action != SWFDEC_AS_ACTION_END);
-  vivi_code_compiler_write_empty_action (compiler, stmt->action);
-}
-
-static void
-vivi_code_special_statement_class_init (ViviCodeSpecialStatementClass *klass)
-{
-  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
-
-  token_class->print = vivi_code_special_statement_print;
-  token_class->compile = vivi_code_special_statement_compile;
-}
-
-static void
-vivi_code_special_statement_init (ViviCodeSpecialStatement *stmt)
-{
-}
diff --git a/vivified/code/vivi_code_special_statement.h b/vivified/code/vivi_code_special_statement.h
deleted file mode 100644
index 735c5dd..0000000
--- a/vivified/code/vivi_code_special_statement.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Vivified
- * Copyright (C) 2008 Pekka Lampila <pekka.lampila at iki.fi>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifndef _VIVI_CODE_SPECIAL_STATEMENT_H_
-#define _VIVI_CODE_SPECIAL_STATEMENT_H_
-
-#include <swfdec/swfdec_as_interpret.h>
-
-#include <vivified/code/vivi_code_statement.h>
-#include <vivified/code/vivi_code_value.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _ViviCodeSpecialStatement ViviCodeSpecialStatement;
-typedef struct _ViviCodeSpecialStatementClass ViviCodeSpecialStatementClass;
-
-#define VIVI_TYPE_CODE_SPECIAL_STATEMENT                    (vivi_code_special_statement_get_type())
-#define VIVI_IS_CODE_SPECIAL_STATEMENT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT))
-#define VIVI_IS_CODE_SPECIAL_STATEMENT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_SPECIAL_STATEMENT))
-#define VIVI_CODE_SPECIAL_STATEMENT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatement))
-#define VIVI_CODE_SPECIAL_STATEMENT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatementClass))
-#define VIVI_CODE_SPECIAL_STATEMENT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_SPECIAL_STATEMENT, ViviCodeSpecialStatementClass))
-
-struct _ViviCodeSpecialStatement
-{
-  ViviCodeStatement	statement;
-
-  const char		*name;		// can be NULL, if get_name is not
-  SwfdecAsAction	action;
-};
-
-struct _ViviCodeSpecialStatementClass
-{
-  ViviCodeStatementClass	statement_class;
-
-  ViviCodeValue *	(* get_value)			(ViviCodeSpecialStatement *	stmt);
-};
-
-GType		vivi_code_special_statement_get_type		(void);
-
-
-G_END_DECLS
-#endif
diff --git a/vivified/code/vivi_code_trace.c b/vivified/code/vivi_code_trace.c
index 5fef0ce..a2b7c4f 100644
--- a/vivified/code/vivi_code_trace.c
+++ b/vivified/code/vivi_code_trace.c
@@ -23,42 +23,17 @@
 
 #include "vivi_code_trace.h"
 
-G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_SPECIAL_STATEMENT)
-
-static void
-vivi_code_trace_dispose (GObject *object)
-{
-  ViviCodeTrace *trace = VIVI_CODE_TRACE (object);
-
-  g_object_unref (trace->value);
-
-  G_OBJECT_CLASS (vivi_code_trace_parent_class)->dispose (object);
-}
-
-static ViviCodeValue *
-vivi_code_trace_get_value (ViviCodeSpecialStatement *stmt)
-{
-  ViviCodeTrace *trace = VIVI_CODE_TRACE (stmt);
-
-  return trace->value;
-}
+G_DEFINE_TYPE (ViviCodeTrace, vivi_code_trace, VIVI_TYPE_CODE_BUILTIN_VALUE_STATEMENT)
 
 static void
 vivi_code_trace_class_init (ViviCodeTraceClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  ViviCodeSpecialStatementClass *stmt_class =
-    VIVI_CODE_SPECIAL_STATEMENT_CLASS (klass);
-
-  object_class->dispose = vivi_code_trace_dispose;
-
-  stmt_class->get_value = vivi_code_trace_get_value;
 }
 
 static void
 vivi_code_trace_init (ViviCodeTrace *token)
 {
-  ViviCodeSpecialStatement *stmt = VIVI_CODE_SPECIAL_STATEMENT (token);
+  ViviCodeBuiltinStatement *stmt = VIVI_CODE_BUILTIN_STATEMENT (token);
 
   stmt->name = "trace";
   stmt->action = SWFDEC_AS_ACTION_TRACE;
@@ -67,13 +42,14 @@ vivi_code_trace_init (ViviCodeTrace *token)
 ViviCodeStatement *
 vivi_code_trace_new (ViviCodeValue *value)
 {
-  ViviCodeTrace *trace;
+  ViviCodeBuiltinValueStatement *stmt;
 
   g_return_val_if_fail (VIVI_IS_CODE_VALUE (value), NULL);
 
-  trace = g_object_new (VIVI_TYPE_CODE_TRACE, NULL);
-  trace->value = g_object_ref (value);
+  stmt = VIVI_CODE_BUILTIN_VALUE_STATEMENT (
+      g_object_new (VIVI_TYPE_CODE_TRACE, NULL));
+  vivi_code_builtin_value_statement_set_value (stmt, g_object_ref (value));
 
-  return VIVI_CODE_STATEMENT (trace);
+  return VIVI_CODE_STATEMENT (stmt);
 }
 
diff --git a/vivified/code/vivi_code_trace.h b/vivified/code/vivi_code_trace.h
index 100aa4f..2609607 100644
--- a/vivified/code/vivi_code_trace.h
+++ b/vivified/code/vivi_code_trace.h
@@ -20,7 +20,7 @@
 #ifndef _VIVI_CODE_TRACE_H_
 #define _VIVI_CODE_TRACE_H_
 
-#include <vivified/code/vivi_code_special_statement.h>
+#include <vivified/code/vivi_code_builtin_value_statement.h>
 #include <vivified/code/vivi_code_statement.h>
 #include <vivified/code/vivi_code_value.h>
 
@@ -39,14 +39,14 @@ typedef struct _ViviCodeTraceClass ViviCodeTraceClass;
 
 struct _ViviCodeTrace
 {
-  ViviCodeSpecialStatement	statement;
+  ViviCodeBuiltinValueStatement	statement;
 
   ViviCodeValue *	value;
 };
 
 struct _ViviCodeTraceClass
 {
-  ViviCodeSpecialStatementClass	statement_class;
+  ViviCodeBuiltinValueStatementClass	statement_class;
 };
 
 GType			vivi_code_trace_get_type   	(void);


More information about the Swfdec-commits mailing list