[Swfdec-commits] 2 commits - vivified/code
Benjamin Otte
company at kemper.freedesktop.org
Thu Apr 17 11:13:54 PDT 2008
vivified/code/Makefile.am | 12 +
vivified/code/vivi_code_asm.h | 6
vivified/code/vivi_code_asm_code_default.c | 5
vivified/code/vivi_code_asm_code_default.h | 4
vivified/code/vivi_code_assignment.c | 11 -
vivified/code/vivi_code_boolean.c | 79 +++++++++
vivified/code/vivi_code_boolean.h | 58 ++++++
vivified/code/vivi_code_constant.c | 242 ----------------------------
vivified/code/vivi_code_constant.h | 16 -
vivified/code/vivi_code_emitter.c | 150 +++++++++++++++++
vivified/code/vivi_code_emitter.h | 76 ++++++++
vivified/code/vivi_code_function_call.c | 6
vivified/code/vivi_code_get.c | 6
vivified/code/vivi_code_init_array.c | 11 -
vivified/code/vivi_code_null.c | 66 +++++++
vivified/code/vivi_code_null.h | 54 ++++++
vivified/code/vivi_code_number.c | 71 ++++++++
vivified/code/vivi_code_number.h | 58 ++++++
vivified/code/vivi_code_string.c | 150 +++++++++++++++++
vivified/code/vivi_code_string.h | 58 ++++++
vivified/code/vivi_code_undefined.c | 66 +++++++
vivified/code/vivi_code_undefined.h | 54 ++++++
vivified/code/vivi_compiler_get_temporary.c | 4
vivified/code/vivi_decompiler.c | 41 ++--
vivified/code/vivi_decompiler_block.c | 4
vivified/code/vivi_decompiler_state.c | 6
vivified/code/vivi_parser.c | 53 +++---
27 files changed, 1047 insertions(+), 320 deletions(-)
New commits:
commit 3aca0af237d694345aa78379a05e9a671f455fc2
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 17 20:06:12 2008 +0200
split the constant class
Now there's a seperate class for Number, Boolean, String, Null and Undefined
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index ec268b2..5819543 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -25,6 +25,7 @@ libvivified_compiler_la_SOURCES = \
vivi_code_binary.c \
vivi_code_binary_default.c \
vivi_code_block.c \
+ vivi_code_boolean.c \
vivi_code_break.c \
vivi_code_builtin_call.c \
vivi_code_builtin_statement.c \
@@ -50,15 +51,19 @@ libvivified_compiler_la_SOURCES = \
vivi_code_init_object.c \
vivi_code_label.c \
vivi_code_loop.c \
+ vivi_code_null.c \
+ vivi_code_number.c \
vivi_code_or.c \
vivi_code_printer.c \
vivi_code_return.c \
vivi_code_statement.c \
+ vivi_code_string.c \
vivi_code_substring.c \
vivi_code_text_printer.c \
vivi_code_throw.c \
vivi_code_token.c \
vivi_code_unary.c \
+ vivi_code_undefined.c \
vivi_code_value.c \
vivi_code_value_statement.c \
vivi_compiler_empty_statement.c \
@@ -82,6 +87,7 @@ noinst_HEADERS = \
vivi_code_binary.h \
vivi_code_binary_default.h \
vivi_code_block.h \
+ vivi_code_boolean.h \
vivi_code_break.h \
vivi_code_builtin_call.h \
vivi_code_builtin_statement.h \
@@ -108,15 +114,19 @@ noinst_HEADERS = \
vivi_code_init_object.h \
vivi_code_label.h \
vivi_code_loop.h \
+ vivi_code_null.h \
+ vivi_code_number.h \
vivi_code_or.h \
vivi_code_printer.h \
vivi_code_return.h \
vivi_code_statement.h \
+ vivi_code_string.h \
vivi_code_substring.h \
vivi_code_text_printer.h \
vivi_code_throw.h \
vivi_code_token.h \
vivi_code_unary.h \
+ vivi_code_undefined.h \
vivi_code_value.h \
vivi_code_value_statement.h \
vivi_compiler_empty_statement.h \
diff --git a/vivified/code/vivi_code_assignment.c b/vivified/code/vivi_code_assignment.c
index 1045031..e16367b 100644
--- a/vivified/code/vivi_code_assignment.c
+++ b/vivified/code/vivi_code_assignment.c
@@ -22,10 +22,11 @@
#endif
#include "vivi_code_assignment.h"
-#include "vivi_code_constant.h"
+#include "vivi_code_compiler.h"
#include "vivi_code_get.h"
#include "vivi_code_printer.h"
-#include "vivi_code_compiler.h"
+#include "vivi_code_string.h"
+#include "vivi_code_undefined.h"
G_DEFINE_TYPE (ViviCodeAssignment, vivi_code_assignment, VIVI_TYPE_CODE_STATEMENT)
@@ -79,9 +80,7 @@ vivi_code_assignment_print (ViviCodeToken *token, ViviCodePrinter*printer)
goto finalize;
}
}
- if (!assignment->local || !VIVI_IS_CODE_CONSTANT (assignment->value) ||
- vivi_code_constant_get_value_type (
- VIVI_CODE_CONSTANT (assignment->value)) != SWFDEC_AS_TYPE_UNDEFINED) {
+ if (!assignment->local || !VIVI_IS_CODE_UNDEFINED (assignment->value)) {
vivi_code_printer_print (printer, " = ");
vivi_code_printer_print_value (printer, assignment->value, VIVI_PRECEDENCE_ASSIGNMENT);
}
@@ -165,7 +164,7 @@ vivi_code_assignment_new_name (const char *name, ViviCodeValue *value)
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (VIVI_IS_CODE_VALUE (value), NULL);
- constant = vivi_code_constant_new_string (name);
+ constant = vivi_code_string_new (name);
result = vivi_code_assignment_new (NULL, constant, value);
g_object_unref (constant);
return result;
diff --git a/vivified/code/vivi_code_boolean.c b/vivified/code/vivi_code_boolean.c
new file mode 100644
index 0000000..5076cf7
--- /dev/null
+++ b/vivified/code/vivi_code_boolean.c
@@ -0,0 +1,79 @@
+/* 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_boolean.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeBoolean, vivi_code_boolean, VIVI_TYPE_CODE_CONSTANT)
+
+static void
+vivi_code_boolean_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ ViviCodeBoolean *b = VIVI_CODE_BOOLEAN (token);
+
+ vivi_code_printer_print (printer, b->value ? "true" : "false");
+}
+
+static char *
+vivi_code_boolean_get_variable_name (ViviCodeConstant *constant)
+{
+ ViviCodeBoolean *b = VIVI_CODE_BOOLEAN (constant);
+
+ return g_strdup (b->value ? "true" : "false");
+}
+
+static void
+vivi_code_boolean_class_init (ViviCodeBooleanClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeConstantClass *constant_class = VIVI_CODE_CONSTANT_CLASS (klass);
+
+ token_class->print = vivi_code_boolean_print;
+
+ constant_class->get_variable_name = vivi_code_boolean_get_variable_name;
+}
+
+static void
+vivi_code_boolean_init (ViviCodeBoolean *boolean)
+{
+}
+
+ViviCodeValue *
+vivi_code_boolean_new (gboolean value)
+{
+ ViviCodeBoolean *b;
+
+ b = g_object_new (VIVI_TYPE_CODE_BOOLEAN, NULL);
+ b->value = value;
+
+ return VIVI_CODE_VALUE (b);
+}
+
+gboolean
+vivi_code_boolean_get_value (ViviCodeBoolean *b)
+{
+ g_return_val_if_fail (VIVI_IS_CODE_BOOLEAN (b), FALSE);
+
+ return b->value;
+}
+
diff --git a/vivified/code/vivi_code_boolean.h b/vivified/code/vivi_code_boolean.h
new file mode 100644
index 0000000..0e27729
--- /dev/null
+++ b/vivified/code/vivi_code_boolean.h
@@ -0,0 +1,58 @@
+/* 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_BOOLEAN_H_
+#define _VIVI_CODE_BOOLEAN_H_
+
+#include <vivified/code/vivi_code_constant.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeBoolean ViviCodeBoolean;
+typedef struct _ViviCodeBooleanClass ViviCodeBooleanClass;
+
+#define VIVI_TYPE_CODE_BOOLEAN (vivi_code_boolean_get_type())
+#define VIVI_IS_CODE_BOOLEAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_BOOLEAN))
+#define VIVI_IS_CODE_BOOLEAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_BOOLEAN))
+#define VIVI_CODE_BOOLEAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_BOOLEAN, ViviCodeBoolean))
+#define VIVI_CODE_BOOLEAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_BOOLEAN, ViviCodeBooleanClass))
+#define VIVI_CODE_BOOLEAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_BOOLEAN, ViviCodeBooleanClass))
+
+struct _ViviCodeBoolean
+{
+ ViviCodeConstant constant;
+
+ gboolean value;
+};
+
+struct _ViviCodeBooleanClass
+{
+ ViviCodeConstantClass constant_class;
+};
+
+GType vivi_code_boolean_get_type (void);
+
+ViviCodeValue * vivi_code_boolean_new (gboolean value);
+
+gboolean vivi_code_boolean_get_value (ViviCodeBoolean * b);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_constant.c b/vivified/code/vivi_code_constant.c
index 5fd6519..f7e2211 100644
--- a/vivified/code/vivi_code_constant.c
+++ b/vivified/code/vivi_code_constant.c
@@ -29,133 +29,7 @@
#include "vivi_code_printer.h"
#include "vivi_code_compiler.h"
-G_DEFINE_TYPE (ViviCodeConstant, vivi_code_constant, VIVI_TYPE_CODE_VALUE)
-
-static void
-vivi_code_constant_dispose (GObject *object)
-{
- ViviCodeConstant *constant = VIVI_CODE_CONSTANT (object);
-
- if (SWFDEC_AS_VALUE_IS_STRING (&constant->value))
- g_free ((char *) SWFDEC_AS_VALUE_GET_STRING (&constant->value));
-
- G_OBJECT_CLASS (vivi_code_constant_parent_class)->dispose (object);
-}
-
-static char *
-escape_string (const char *s)
-{
- GString *str;
- char *next;
-
- str = g_string_new ("\"");
- while ((next = strpbrk (s, "\"\\\b\f\n\r\t\v"))) {
- g_string_append_len (str, s, next - s);
- switch (*next) {
- case '"':
- g_string_append (str, "\\\"");
- break;
- case '\\':
- g_string_append (str, "\\\\");
- break;
- case '\b':
- g_string_append (str, "\\b");
- break;
- case '\f':
- g_string_append (str, "\\f");
- break;
- case '\n':
- g_string_append (str, "\\n");
- break;
- case '\r':
- g_string_append (str, "\\r");
- break;
- case '\t':
- g_string_append (str, "\\t");
- break;
- case '\v':
- g_string_append (str, "\\v");
- break;
- default:
- g_assert_not_reached ();
- }
- s = next + 1;
- }
- g_string_append (str, s);
- g_string_append_c (str, '"');
- return g_string_free (str, FALSE);
-}
-
-static void
-vivi_code_constant_print (ViviCodeToken *token, ViviCodePrinter *printer)
-{
- ViviCodeConstant *constant = VIVI_CODE_CONSTANT (token);
- char *s;
-
- switch (constant->value.type) {
- case SWFDEC_AS_TYPE_UNDEFINED:
- vivi_code_printer_print (printer, "undefined");
- break;
- case SWFDEC_AS_TYPE_NULL:
- vivi_code_printer_print (printer, "null");
- break;
- case SWFDEC_AS_TYPE_BOOLEAN:
- vivi_code_printer_print (printer, SWFDEC_AS_VALUE_GET_BOOLEAN (&constant->value) ? "true" : "false");
- break;
- case SWFDEC_AS_TYPE_NUMBER:
- s = g_strdup_printf ("%.16g", SWFDEC_AS_VALUE_GET_NUMBER (&constant->value));
- vivi_code_printer_print (printer, s);
- g_free (s);
- break;
- case SWFDEC_AS_TYPE_STRING:
- s = escape_string (SWFDEC_AS_VALUE_GET_STRING (&constant->value));
- vivi_code_printer_print (printer, s);
- g_free (s);
- break;
- case SWFDEC_AS_TYPE_INT:
- case SWFDEC_AS_TYPE_OBJECT:
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-vivi_code_constant_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
-{
- ViviCodeConstant *constant = VIVI_CODE_CONSTANT (token);
-
- vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_PUSH);
-
- switch (constant->value.type) {
- case SWFDEC_AS_TYPE_UNDEFINED:
- vivi_code_compiler_write_u8 (compiler, 3);
- break;
- case SWFDEC_AS_TYPE_NULL:
- vivi_code_compiler_write_u8 (compiler, 2);
- break;
- case SWFDEC_AS_TYPE_BOOLEAN:
- vivi_code_compiler_write_u8 (compiler, 5);
- vivi_code_compiler_write_u8 (compiler,
- SWFDEC_AS_VALUE_GET_BOOLEAN (&constant->value));
- break;
- case SWFDEC_AS_TYPE_NUMBER:
- vivi_code_compiler_write_u8 (compiler, 6);
- vivi_code_compiler_write_double (compiler,
- SWFDEC_AS_VALUE_GET_NUMBER (&constant->value));
- break;
- case SWFDEC_AS_TYPE_STRING:
- vivi_code_compiler_write_u8 (compiler, 0);
- vivi_code_compiler_write_string (compiler,
- SWFDEC_AS_VALUE_GET_STRING (&constant->value));
- break;
- case SWFDEC_AS_TYPE_INT:
- case SWFDEC_AS_TYPE_OBJECT:
- default:
- g_assert_not_reached ();
- }
-
- vivi_code_compiler_end_action (compiler);
-}
+G_DEFINE_ABSTRACT_TYPE (ViviCodeConstant, vivi_code_constant, VIVI_TYPE_CODE_VALUE)
static gboolean
vivi_code_constant_is_constant (ViviCodeValue *value)
@@ -166,15 +40,8 @@ vivi_code_constant_is_constant (ViviCodeValue *value)
static void
vivi_code_constant_class_init (ViviCodeConstantClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
ViviCodeValueClass *value_class = VIVI_CODE_VALUE_CLASS (klass);
- object_class->dispose = vivi_code_constant_dispose;
-
- token_class->print = vivi_code_constant_print;
- token_class->compile = vivi_code_constant_compile;
-
value_class->is_constant = vivi_code_constant_is_constant;
}
@@ -184,112 +51,17 @@ vivi_code_constant_init (ViviCodeConstant *constant)
vivi_code_value_set_precedence (VIVI_CODE_VALUE (constant), VIVI_PRECEDENCE_MAX);
}
-static ViviCodeValue *
-vivi_code_constant_new (const SwfdecAsValue *value)
-{
- ViviCodeConstant *constant;
-
- constant = g_object_new (VIVI_TYPE_CODE_CONSTANT, NULL);
- constant->value = *value;
-
- return VIVI_CODE_VALUE (constant);
-}
-
-ViviCodeValue *
-vivi_code_constant_new_undefined (void)
-{
- SwfdecAsValue val = { 0, };
- return vivi_code_constant_new (&val);
-}
-
-ViviCodeValue *
-vivi_code_constant_new_null (void)
-{
- SwfdecAsValue val;
-
- SWFDEC_AS_VALUE_SET_NULL (&val);
- return vivi_code_constant_new (&val);
-}
-
-ViviCodeValue *
-vivi_code_constant_new_string (const char *string)
-{
- SwfdecAsValue val;
-
- g_return_val_if_fail (string != NULL, NULL);
-
- SWFDEC_AS_VALUE_SET_STRING (&val, g_strdup (string));
- return vivi_code_constant_new (&val);
-}
-
-ViviCodeValue *
-vivi_code_constant_new_number (double number)
-{
- SwfdecAsValue val;
-
- SWFDEC_AS_VALUE_SET_NUMBER (&val, number);
- return vivi_code_constant_new (&val);
-}
-
-ViviCodeValue *
-vivi_code_constant_new_boolean (gboolean boolean)
-{
- SwfdecAsValue val;
-
- SWFDEC_AS_VALUE_SET_BOOLEAN (&val, boolean);
- return vivi_code_constant_new (&val);
-}
-
char *
vivi_code_constant_get_variable_name (ViviCodeConstant *constant)
{
- static const char *accept = G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_$";
+ ViviCodeConstantClass *klass;
g_return_val_if_fail (VIVI_IS_CODE_CONSTANT (constant), NULL);
- switch (constant->value.type) {
- case SWFDEC_AS_TYPE_UNDEFINED:
- return g_strdup ("undefined");
- case SWFDEC_AS_TYPE_NULL:
- return g_strdup ("null");
- break;
- case SWFDEC_AS_TYPE_BOOLEAN:
- return g_strdup (SWFDEC_AS_VALUE_GET_BOOLEAN (&constant->value) ? "true" : "false");
- break;
- case SWFDEC_AS_TYPE_STRING:
- {
- const char *s = SWFDEC_AS_VALUE_GET_STRING (&constant->value);
- gsize len = strspn (s, accept);
- if (s[len] == '\0')
- return g_strdup (s);
- else
- return NULL;
- }
- case SWFDEC_AS_TYPE_NUMBER:
- return NULL;
- case SWFDEC_AS_TYPE_INT:
- case SWFDEC_AS_TYPE_OBJECT:
- default:
- g_assert_not_reached ();
- }
-}
-
-SwfdecAsValueType
-vivi_code_constant_get_value_type (ViviCodeConstant *constant)
-{
- g_return_val_if_fail (VIVI_IS_CODE_CONSTANT (constant), SWFDEC_AS_TYPE_UNDEFINED);
-
- return constant->value.type;
-}
+ klass = VIVI_CODE_CONSTANT_GET_CLASS (constant);
+ if (klass->get_variable_name == NULL)
+ return NULL;
-double
-vivi_code_constant_get_number (ViviCodeConstant *constant)
-{
- g_return_val_if_fail (VIVI_IS_CODE_CONSTANT (constant), NAN);
-
- if (SWFDEC_AS_VALUE_IS_NUMBER (&constant->value))
- return SWFDEC_AS_VALUE_GET_NUMBER (&constant->value);
- else
- return NAN;
-}
+ return klass->get_variable_name (constant);
+};
diff --git a/vivified/code/vivi_code_constant.h b/vivified/code/vivi_code_constant.h
index bf46a4b..455ca3d 100644
--- a/vivified/code/vivi_code_constant.h
+++ b/vivified/code/vivi_code_constant.h
@@ -38,30 +38,20 @@ typedef struct _ViviCodeConstantClass ViviCodeConstantClass;
struct _ViviCodeConstant
{
ViviCodeValue parent;
-
- SwfdecAsValue value;
};
struct _ViviCodeConstantClass
{
ViviCodeValueClass value_class;
+
+ char * (* get_variable_name) (ViviCodeConstant * constant);
};
GType vivi_code_constant_get_type (void);
-ViviCodeValue * vivi_code_constant_new_null (void);
-ViviCodeValue * vivi_code_constant_new_undefined(void);
-ViviCodeValue * vivi_code_constant_new_string (const char * string);
-#define vivi_code_constant_new_int vivi_code_constant_new_number
-ViviCodeValue * vivi_code_constant_new_number (double number);
-ViviCodeValue * vivi_code_constant_new_boolean (gboolean boolean);
-
char * vivi_code_constant_get_variable_name
(ViviCodeConstant * constant);
-SwfdecAsValueType vivi_code_constant_get_value_type
- (ViviCodeConstant * constant);
-double vivi_code_constant_get_number (ViviCodeConstant * constant);
-const char * vivi_code_constant_get_string (ViviCodeConstant * constant);
+
G_END_DECLS
#endif
diff --git a/vivified/code/vivi_code_function_call.c b/vivified/code/vivi_code_function_call.c
index 2b8b974..14dc4d6 100644
--- a/vivified/code/vivi_code_function_call.c
+++ b/vivified/code/vivi_code_function_call.c
@@ -22,9 +22,9 @@
#endif
#include "vivi_code_function_call.h"
-#include "vivi_code_constant.h"
-#include "vivi_code_printer.h"
#include "vivi_code_compiler.h"
+#include "vivi_code_number.h"
+#include "vivi_code_printer.h"
G_DEFINE_TYPE (ViviCodeFunctionCall, vivi_code_function_call, VIVI_TYPE_CODE_VALUE)
@@ -133,7 +133,7 @@ vivi_code_function_call_compile (ViviCodeToken *token,
vivi_code_compiler_compile_value (compiler,
g_ptr_array_index (call->arguments, i));
}
- count = vivi_code_constant_new_number (call->arguments->len);
+ count = vivi_code_number_new (call->arguments->len);
vivi_code_compiler_compile_value (compiler, count);
g_object_unref (count);
diff --git a/vivified/code/vivi_code_get.c b/vivified/code/vivi_code_get.c
index 787c822..dced1f1 100644
--- a/vivified/code/vivi_code_get.c
+++ b/vivified/code/vivi_code_get.c
@@ -22,9 +22,9 @@
#endif
#include "vivi_code_get.h"
-#include "vivi_code_constant.h"
-#include "vivi_code_printer.h"
#include "vivi_code_compiler.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_string.h"
G_DEFINE_TYPE (ViviCodeGet, vivi_code_get, VIVI_TYPE_CODE_VALUE)
@@ -157,7 +157,7 @@ vivi_code_get_new_name (const char *name)
g_return_val_if_fail (name != NULL, NULL);
- constant = vivi_code_constant_new_string (name);
+ constant = vivi_code_string_new (name);
result = vivi_code_get_new (NULL, constant);
g_object_unref (constant);
return result;
diff --git a/vivified/code/vivi_code_init_array.c b/vivified/code/vivi_code_init_array.c
index ec73801..e61522f 100644
--- a/vivified/code/vivi_code_init_array.c
+++ b/vivified/code/vivi_code_init_array.c
@@ -23,9 +23,10 @@
#endif
#include "vivi_code_init_array.h"
-#include "vivi_code_constant.h"
-#include "vivi_code_printer.h"
#include "vivi_code_compiler.h"
+#include "vivi_code_number.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_undefined.h"
G_DEFINE_TYPE (ViviCodeInitArray, vivi_code_init_array, VIVI_TYPE_CODE_VALUE)
@@ -71,9 +72,7 @@ vivi_code_init_array_print (ViviCodeToken *token, ViviCodePrinter *printer)
vivi_code_printer_print (printer, ", ");
/* FIXME: precedences? */
// don't write undefined values
- if (!VIVI_IS_CODE_CONSTANT (value) ||
- vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (value))
- != SWFDEC_AS_TYPE_UNDEFINED)
+ if (!VIVI_IS_CODE_UNDEFINED (value))
vivi_code_printer_print_value (printer, value, VIVI_PRECEDENCE_COMMA);
}
vivi_code_printer_print (printer, "]");
@@ -90,7 +89,7 @@ vivi_code_init_array_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
vivi_code_compiler_compile_value (compiler,
VIVI_CODE_VALUE (g_ptr_array_index (array->variables, i)));
}
- count = vivi_code_constant_new_number (array->variables->len);
+ count = vivi_code_number_new (array->variables->len);
vivi_code_compiler_compile_value (compiler, count);
g_object_unref (count);
diff --git a/vivified/code/vivi_code_null.c b/vivified/code/vivi_code_null.c
new file mode 100644
index 0000000..322e5d7
--- /dev/null
+++ b/vivified/code/vivi_code_null.c
@@ -0,0 +1,66 @@
+/* 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 <ctype.h>
+#include <math.h>
+#include <string.h>
+
+#include "vivi_code_null.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeNull, vivi_code_null, VIVI_TYPE_CODE_CONSTANT)
+
+static void
+vivi_code_null_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ vivi_code_printer_print (printer, "null");
+}
+
+static char *
+vivi_code_null_get_variable_name (ViviCodeConstant *constant)
+{
+ return g_strdup ("null");
+}
+
+static void
+vivi_code_null_class_init (ViviCodeNullClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeConstantClass *constant_class = VIVI_CODE_CONSTANT_CLASS (klass);
+
+ token_class->print = vivi_code_null_print;
+
+ constant_class->get_variable_name = vivi_code_null_get_variable_name;
+}
+
+static void
+vivi_code_null_init (ViviCodeNull *null)
+{
+}
+
+ViviCodeValue *
+vivi_code_null_new (void)
+{
+ return g_object_new (VIVI_TYPE_CODE_NULL, NULL);
+}
+
diff --git a/vivified/code/vivi_code_null.h b/vivified/code/vivi_code_null.h
new file mode 100644
index 0000000..c16b924
--- /dev/null
+++ b/vivified/code/vivi_code_null.h
@@ -0,0 +1,54 @@
+/* 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_NULL_H_
+#define _VIVI_CODE_NULL_H_
+
+#include <vivified/code/vivi_code_constant.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeNull ViviCodeNull;
+typedef struct _ViviCodeNullClass ViviCodeNullClass;
+
+#define VIVI_TYPE_CODE_NULL (vivi_code_null_get_type())
+#define VIVI_IS_CODE_NULL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_NULL))
+#define VIVI_IS_CODE_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_NULL))
+#define VIVI_CODE_NULL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_NULL, ViviCodeNull))
+#define VIVI_CODE_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_NULL, ViviCodeNullClass))
+#define VIVI_CODE_NULL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_NULL, ViviCodeNullClass))
+
+struct _ViviCodeNull
+{
+ ViviCodeConstant constant;
+};
+
+struct _ViviCodeNullClass
+{
+ ViviCodeConstantClass constant_class;
+};
+
+GType vivi_code_null_get_type (void);
+
+ViviCodeValue * vivi_code_null_new (void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_number.c b/vivified/code/vivi_code_number.c
new file mode 100644
index 0000000..24b0e84
--- /dev/null
+++ b/vivified/code/vivi_code_number.c
@@ -0,0 +1,71 @@
+/* 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_number.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeNumber, vivi_code_number, VIVI_TYPE_CODE_CONSTANT)
+
+static void
+vivi_code_number_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ ViviCodeNumber *number = VIVI_CODE_NUMBER (token);
+ char *s;
+
+ s = g_strdup_printf ("%g", number->value);
+ vivi_code_printer_print (printer, s);
+ g_free (s);
+}
+
+static void
+vivi_code_number_class_init (ViviCodeNumberClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+
+ token_class->print = vivi_code_number_print;
+}
+
+static void
+vivi_code_number_init (ViviCodeNumber *number)
+{
+}
+
+ViviCodeValue *
+vivi_code_number_new (double value)
+{
+ ViviCodeNumber *number;
+
+ number = g_object_new (VIVI_TYPE_CODE_NUMBER, NULL);
+ number->value = value;
+
+ return VIVI_CODE_VALUE (number);
+}
+
+double
+vivi_code_number_get_value (ViviCodeNumber *number)
+{
+ g_return_val_if_fail (VIVI_IS_CODE_NUMBER (number), 0.0);
+
+ return number->value;
+}
+
diff --git a/vivified/code/vivi_code_number.h b/vivified/code/vivi_code_number.h
new file mode 100644
index 0000000..943041e
--- /dev/null
+++ b/vivified/code/vivi_code_number.h
@@ -0,0 +1,58 @@
+/* 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_NUMBER_H_
+#define _VIVI_CODE_NUMBER_H_
+
+#include <vivified/code/vivi_code_constant.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeNumber ViviCodeNumber;
+typedef struct _ViviCodeNumberClass ViviCodeNumberClass;
+
+#define VIVI_TYPE_CODE_NUMBER (vivi_code_number_get_type())
+#define VIVI_IS_CODE_NUMBER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_NUMBER))
+#define VIVI_IS_CODE_NUMBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_NUMBER))
+#define VIVI_CODE_NUMBER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_NUMBER, ViviCodeNumber))
+#define VIVI_CODE_NUMBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_NUMBER, ViviCodeNumberClass))
+#define VIVI_CODE_NUMBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_NUMBER, ViviCodeNumberClass))
+
+struct _ViviCodeNumber
+{
+ ViviCodeConstant constant;
+
+ double value;
+};
+
+struct _ViviCodeNumberClass
+{
+ ViviCodeConstantClass constant_class;
+};
+
+GType vivi_code_number_get_type (void);
+
+ViviCodeValue * vivi_code_number_new (double value);
+
+double vivi_code_number_get_value (ViviCodeNumber * number);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_string.c b/vivified/code/vivi_code_string.c
new file mode 100644
index 0000000..a561f7d
--- /dev/null
+++ b/vivified/code/vivi_code_string.c
@@ -0,0 +1,150 @@
+/* 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 <string.h>
+
+#include "vivi_code_string.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeString, vivi_code_string, VIVI_TYPE_CODE_CONSTANT)
+
+static void
+vivi_code_string_dispose (GObject *object)
+{
+ ViviCodeString *string = VIVI_CODE_STRING (object);
+
+ g_free (string->value);
+ string->value = NULL;
+
+ G_OBJECT_CLASS (vivi_code_string_parent_class)->dispose (object);
+}
+
+static char *
+escape_string (const char *s)
+{
+ GString *str;
+ char *next;
+
+ str = g_string_new ("\"");
+ while ((next = strpbrk (s, "\"\\\b\f\n\r\t\v"))) {
+ g_string_append_len (str, s, next - s);
+ switch (*next) {
+ case '"':
+ g_string_append (str, "\\\"");
+ break;
+ case '\\':
+ g_string_append (str, "\\\\");
+ break;
+ case '\b':
+ g_string_append (str, "\\b");
+ break;
+ case '\f':
+ g_string_append (str, "\\f");
+ break;
+ case '\n':
+ g_string_append (str, "\\n");
+ break;
+ case '\r':
+ g_string_append (str, "\\r");
+ break;
+ case '\t':
+ g_string_append (str, "\\t");
+ break;
+ case '\v':
+ g_string_append (str, "\\v");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ s = next + 1;
+ }
+ g_string_append (str, s);
+ g_string_append_c (str, '"');
+ return g_string_free (str, FALSE);
+}
+
+static void
+vivi_code_string_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ ViviCodeString *string = VIVI_CODE_STRING (token);
+ char *s;
+
+ s = escape_string (string->value);
+ vivi_code_printer_print (printer, s);
+ g_free (s);
+}
+
+static char *
+vivi_code_string_get_variable_name (ViviCodeConstant *constant)
+{
+ static const char *accept = G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_$";
+ ViviCodeString *string = VIVI_CODE_STRING (constant);
+ gsize len;
+
+ len = strspn (string->value, accept);
+ if (string->value[len] == '\0')
+ return g_strdup (string->value);
+ else
+ return NULL;
+}
+
+static void
+vivi_code_string_class_init (ViviCodeStringClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeConstantClass *constant_class = VIVI_CODE_CONSTANT_CLASS (klass);
+
+ object_class->dispose = vivi_code_string_dispose;
+
+ token_class->print = vivi_code_string_print;
+
+ constant_class->get_variable_name = vivi_code_string_get_variable_name;
+}
+
+static void
+vivi_code_string_init (ViviCodeString *string)
+{
+}
+
+ViviCodeValue *
+vivi_code_string_new (const char *value)
+{
+ ViviCodeString *string;
+
+ g_return_val_if_fail (value != NULL, NULL);
+
+ string = g_object_new (VIVI_TYPE_CODE_STRING, NULL);
+ string->value = g_strdup (value);
+
+ return VIVI_CODE_VALUE (string);
+}
+
+const char *
+vivi_code_string_get_value (ViviCodeString *string)
+{
+ g_return_val_if_fail (VIVI_IS_CODE_STRING (string), NULL);
+
+ return string->value;
+}
+
diff --git a/vivified/code/vivi_code_string.h b/vivified/code/vivi_code_string.h
new file mode 100644
index 0000000..b5aa1ee
--- /dev/null
+++ b/vivified/code/vivi_code_string.h
@@ -0,0 +1,58 @@
+/* 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_STRING_H_
+#define _VIVI_CODE_STRING_H_
+
+#include <vivified/code/vivi_code_constant.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeString ViviCodeString;
+typedef struct _ViviCodeStringClass ViviCodeStringClass;
+
+#define VIVI_TYPE_CODE_STRING (vivi_code_string_get_type())
+#define VIVI_IS_CODE_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_STRING))
+#define VIVI_IS_CODE_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_STRING))
+#define VIVI_CODE_STRING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_STRING, ViviCodeString))
+#define VIVI_CODE_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_STRING, ViviCodeStringClass))
+#define VIVI_CODE_STRING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_STRING, ViviCodeStringClass))
+
+struct _ViviCodeString
+{
+ ViviCodeConstant constant;
+
+ char * value;
+};
+
+struct _ViviCodeStringClass
+{
+ ViviCodeConstantClass constant_class;
+};
+
+GType vivi_code_string_get_type (void);
+
+ViviCodeValue * vivi_code_string_new (const char * value);
+
+const char * vivi_code_string_get_value (ViviCodeString * string);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_undefined.c b/vivified/code/vivi_code_undefined.c
new file mode 100644
index 0000000..2cadf78
--- /dev/null
+++ b/vivified/code/vivi_code_undefined.c
@@ -0,0 +1,66 @@
+/* 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 <ctype.h>
+#include <math.h>
+#include <string.h>
+
+#include "vivi_code_undefined.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeUndefined, vivi_code_undefined, VIVI_TYPE_CODE_CONSTANT)
+
+static void
+vivi_code_undefined_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ vivi_code_printer_print (printer, "undefined");
+}
+
+static char *
+vivi_code_undefined_get_variable_name (ViviCodeConstant *constant)
+{
+ return g_strdup ("undefined");
+}
+
+static void
+vivi_code_undefined_class_init (ViviCodeUndefinedClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeConstantClass *constant_class = VIVI_CODE_CONSTANT_CLASS (klass);
+
+ token_class->print = vivi_code_undefined_print;
+
+ constant_class->get_variable_name = vivi_code_undefined_get_variable_name;
+}
+
+static void
+vivi_code_undefined_init (ViviCodeUndefined *undefined)
+{
+}
+
+ViviCodeValue *
+vivi_code_undefined_new (void)
+{
+ return g_object_new (VIVI_TYPE_CODE_UNDEFINED, NULL);
+}
+
diff --git a/vivified/code/vivi_code_undefined.h b/vivified/code/vivi_code_undefined.h
new file mode 100644
index 0000000..30cb1ec
--- /dev/null
+++ b/vivified/code/vivi_code_undefined.h
@@ -0,0 +1,54 @@
+/* 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_UNDEFINED_H_
+#define _VIVI_CODE_UNDEFINED_H_
+
+#include <vivified/code/vivi_code_constant.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeUndefined ViviCodeUndefined;
+typedef struct _ViviCodeUndefinedClass ViviCodeUndefinedClass;
+
+#define VIVI_TYPE_CODE_UNDEFINED (vivi_code_undefined_get_type())
+#define VIVI_IS_CODE_UNDEFINED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_UNDEFINED))
+#define VIVI_IS_CODE_UNDEFINED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_UNDEFINED))
+#define VIVI_CODE_UNDEFINED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_UNDEFINED, ViviCodeUndefined))
+#define VIVI_CODE_UNDEFINED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_UNDEFINED, ViviCodeUndefinedClass))
+#define VIVI_CODE_UNDEFINED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_UNDEFINED, ViviCodeUndefinedClass))
+
+struct _ViviCodeUndefined
+{
+ ViviCodeConstant constant;
+};
+
+struct _ViviCodeUndefinedClass
+{
+ ViviCodeConstantClass constant_class;
+};
+
+GType vivi_code_undefined_get_type (void);
+
+ViviCodeValue * vivi_code_undefined_new (void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_compiler_get_temporary.c b/vivified/code/vivi_compiler_get_temporary.c
index 2b5b515..1b7e2c7 100644
--- a/vivified/code/vivi_compiler_get_temporary.c
+++ b/vivified/code/vivi_compiler_get_temporary.c
@@ -25,8 +25,8 @@
#include "vivi_compiler_get_temporary.h"
#include "vivi_code_get.h"
-#include "vivi_code_constant.h"
#include "vivi_code_printer.h"
+#include "vivi_code_string.h"
G_DEFINE_TYPE (ViviCompilerGetTemporary, vivi_compiler_get_temporary, VIVI_TYPE_CODE_GET)
@@ -48,7 +48,7 @@ vivi_compiler_get_temporary_new (void)
char *name = g_strdup_printf ("$%i", ++counter);
get = g_object_new (VIVI_TYPE_COMPILER_GET_TEMPORARY, NULL);
- VIVI_CODE_GET (get)->name = vivi_code_constant_new_string (name);
+ VIVI_CODE_GET (get)->name = vivi_code_string_new (name);
g_free (name);
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index caf906e..f95d393 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -32,6 +32,7 @@
#include "vivi_code_assignment.h"
#include "vivi_code_binary_default.h"
#include "vivi_code_block.h"
+#include "vivi_code_boolean.h"
#include "vivi_code_break.h"
#include "vivi_code_builtin_value_statement_default.h"
#include "vivi_code_constant.h"
@@ -44,9 +45,13 @@
#include "vivi_code_if.h"
#include "vivi_code_init_object.h"
#include "vivi_code_loop.h"
+#include "vivi_code_number.h"
+#include "vivi_code_null.h"
#include "vivi_code_or.h"
#include "vivi_code_return.h"
+#include "vivi_code_string.h"
#include "vivi_code_unary.h"
+#include "vivi_code_undefined.h"
#include "vivi_code_value_statement.h"
#include "vivi_decompiler_block.h"
#include "vivi_decompiler_duplicate.h"
@@ -143,31 +148,31 @@ vivi_decompile_push (ViviDecompilerBlock *block, ViviDecompilerState *state,
vivi_decompiler_block_add_error (block, state, "could not read string");
return FALSE;
}
- val = vivi_code_constant_new_string (s);
+ val = vivi_code_string_new (s);
g_free (s);
break;
}
case 1: /* float */
- val = vivi_code_constant_new_number (swfdec_bits_get_float (&bits));
+ val = vivi_code_number_new (swfdec_bits_get_float (&bits));
break;
case 2: /* null */
- val = vivi_code_constant_new_null ();
+ val = vivi_code_null_new ();
break;
case 3: /* undefined */
- val = vivi_code_constant_new_undefined ();
+ val = vivi_code_undefined_new ();
break;
case 4: /* register */
val = vivi_decompiler_state_get_register (
state, swfdec_bits_get_u8 (&bits));
break;
case 5: /* boolean */
- val = vivi_code_constant_new_boolean (swfdec_bits_get_u8 (&bits) ? TRUE : FALSE);
+ val = vivi_code_boolean_new (swfdec_bits_get_u8 (&bits) ? TRUE : FALSE);
break;
case 6: /* double */
- val = vivi_code_constant_new_number (swfdec_bits_get_double (&bits));
+ val = vivi_code_number_new (swfdec_bits_get_double (&bits));
break;
case 7: /* 32bit int */
- val = vivi_code_constant_new_int ((int) swfdec_bits_get_u32 (&bits));
+ val = vivi_code_number_new ((int) swfdec_bits_get_u32 (&bits));
break;
case 8: /* 8bit ConstantPool address */
case 9: /* 16bit ConstantPool address */
@@ -183,7 +188,7 @@ vivi_decompile_push (ViviDecompilerBlock *block, ViviDecompilerState *state,
i, swfdec_constant_pool_size (pool));
return TRUE;
}
- val = vivi_code_constant_new_string (swfdec_constant_pool_get (pool, i));
+ val = vivi_code_string_new (swfdec_constant_pool_get (pool, i));
break;
}
default:
@@ -266,8 +271,7 @@ vivi_decompile_return (ViviDecompilerBlock *block, ViviDecompilerState *state,
value = vivi_decompiler_state_pop (state);
ret = vivi_code_return_new ();
- if (!VIVI_IS_CODE_CONSTANT (value) ||
- vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (value)) != SWFDEC_AS_TYPE_UNDEFINED)
+ if (!VIVI_IS_CODE_UNDEFINED (value))
vivi_code_return_set_value (VIVI_CODE_RETURN (ret), value);
g_object_unref (value);
vivi_code_block_add_statement (VIVI_CODE_BLOCK (block), ret);
@@ -388,7 +392,7 @@ vivi_decompile_define_local (ViviDecompilerBlock *block, ViviDecompilerState *st
if (code == SWFDEC_AS_ACTION_DEFINE_LOCAL)
value = vivi_decompiler_state_pop (state);
else
- value = vivi_code_constant_new_undefined ();
+ value = vivi_code_undefined_new ();
name = vivi_decompiler_state_pop (state);
assign = vivi_code_assignment_new (NULL, name, value);
@@ -450,9 +454,8 @@ vivi_decompile_function_call (ViviDecompilerBlock *block, ViviDecompilerState *s
if (name)
g_object_unref (name);
- if (!VIVI_IS_CODE_CONSTANT (args) ||
- vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (args)) != SWFDEC_AS_TYPE_NUMBER ||
- ((count = d = vivi_code_constant_get_number (VIVI_CODE_CONSTANT (args))) != d)) {
+ if (!VIVI_IS_CODE_NUMBER (args) ||
+ ((count = d = vivi_code_number_get_value (VIVI_CODE_NUMBER (args))) != d)) {
vivi_decompiler_block_add_error (block, state, "could not determine function argument count");
g_object_unref (args);
g_object_unref (call);
@@ -569,9 +572,8 @@ vivi_decompile_define_function (ViviDecompilerBlock *block, ViviDecompilerState
* it will contain the name this function will soon be assigned to.
*/
value = vivi_decompiler_state_peek_nth (state, 0);
- if (VIVI_IS_CODE_CONSTANT (value) &&
- vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (value)) == SWFDEC_AS_TYPE_STRING)
- name = SWFDEC_AS_VALUE_GET_STRING (&VIVI_CODE_CONSTANT (value)->value);
+ if (VIVI_IS_CODE_STRING (value))
+ name = vivi_code_string_get_value (VIVI_CODE_STRING (value));
}
if (name == NULL)
name = "unnamed_function";
@@ -644,9 +646,8 @@ vivi_decompile_init_object (ViviDecompilerBlock *block, ViviDecompilerState *sta
guint i, count;
args = vivi_decompiler_state_pop (state);
- if (!VIVI_IS_CODE_CONSTANT (args) ||
- vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (args)) != SWFDEC_AS_TYPE_NUMBER ||
- ((count = d = vivi_code_constant_get_number (VIVI_CODE_CONSTANT (args))) != d)) {
+ if (!VIVI_IS_CODE_NUMBER (args) ||
+ ((count = d = vivi_code_number_get_value (VIVI_CODE_NUMBER (args))) != d)) {
vivi_decompiler_block_add_error (block, state, "could not determine init object argument count");
g_object_unref (args);
return FALSE;
diff --git a/vivified/code/vivi_decompiler_block.c b/vivified/code/vivi_decompiler_block.c
index 14cec1c..1fc22b2 100644
--- a/vivified/code/vivi_decompiler_block.c
+++ b/vivified/code/vivi_decompiler_block.c
@@ -28,10 +28,10 @@
#include "vivi_code_assignment.h"
#include "vivi_code_block.h"
#include "vivi_code_comment.h"
-#include "vivi_code_constant.h"
#include "vivi_code_goto.h"
#include "vivi_code_if.h"
#include "vivi_code_label.h"
+#include "vivi_code_string.h"
#include "vivi_decompiler_unknown.h"
G_DEFINE_TYPE (ViviDecompilerBlock, vivi_decompiler_block, VIVI_TYPE_CODE_BLOCK)
@@ -330,7 +330,7 @@ vivi_decompiler_block_add_state_transition (ViviDecompilerBlock *from,
return;
}
if (val_from != VIVI_CODE_VALUE (val_to)) {
- name = vivi_code_constant_new_string (vivi_decompiler_unknown_get_name (val_to));
+ name = vivi_code_string_new (vivi_decompiler_unknown_get_name (val_to));
vivi_code_block_add_statement (block,
vivi_code_assignment_new (NULL, name, val_from));
}
diff --git a/vivified/code/vivi_decompiler_state.c b/vivified/code/vivi_decompiler_state.c
index f821f26..5425422 100644
--- a/vivified/code/vivi_decompiler_state.c
+++ b/vivified/code/vivi_decompiler_state.c
@@ -24,7 +24,7 @@
#include <swfdec/swfdec_script_internal.h>
#include "vivi_decompiler_state.h"
-#include "vivi_code_constant.h"
+#include "vivi_code_undefined.h"
#include "vivi_decompiler_unknown.h"
struct _ViviDecompilerState {
@@ -77,7 +77,7 @@ ViviCodeValue *
vivi_decompiler_state_pop (ViviDecompilerState *state)
{
if (state->stack == NULL) {
- return VIVI_CODE_VALUE (vivi_code_constant_new_undefined ());
+ return vivi_code_undefined_new ();
} else {
ViviCodeValue *pop;
pop = state->stack->data;
@@ -125,7 +125,7 @@ ViviCodeValue *
vivi_decompiler_state_get_register (const ViviDecompilerState *state, guint reg)
{
if (reg >= state->n_registers || state->registers[reg] == NULL)
- return VIVI_CODE_VALUE (vivi_code_constant_new_undefined ());
+ return vivi_code_undefined_new ();
else
return g_object_ref (state->registers[reg]);
}
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index b73d7c4..35619a2 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -31,6 +31,7 @@
#include "vivi_code_assignment.h"
#include "vivi_code_binary_default.h"
#include "vivi_code_block.h"
+#include "vivi_code_boolean.h"
#include "vivi_code_break.h"
#include "vivi_code_builtin_statement_default.h"
#include "vivi_code_builtin_value_call_default.h"
@@ -48,11 +49,15 @@
#include "vivi_code_init_array.h"
#include "vivi_code_init_object.h"
#include "vivi_code_loop.h"
+#include "vivi_code_null.h"
+#include "vivi_code_number.h"
#include "vivi_code_or.h"
#include "vivi_code_return.h"
+#include "vivi_code_string.h"
#include "vivi_code_substring.h"
#include "vivi_code_throw.h"
#include "vivi_code_unary.h"
+#include "vivi_code_undefined.h"
#include "vivi_code_value_statement.h"
#include "vivi_compiler_empty_statement.h"
#include "vivi_compiler_get_temporary.h"
@@ -584,7 +589,7 @@ parse_undefined_literal (ParseData *data, ViviCodeValue **value)
parse_token (data, TOKEN_UNDEFINED);
- *value = vivi_code_constant_new_undefined ();
+ *value = vivi_code_undefined_new ();
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
}
@@ -602,7 +607,7 @@ parse_null_literal (ParseData *data, ViviCodeValue **value)
parse_token (data, TOKEN_NULL);
- *value = vivi_code_constant_new_null ();
+ *value = vivi_code_null_new ();
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
}
@@ -620,9 +625,9 @@ parse_boolean_literal (ParseData *data, ViviCodeValue **value)
if (!try_parse_token (data, TOKEN_BOOLEAN)) {
vivi_parser_error_unexpected (data, TOKEN_BOOLEAN);
- *value = vivi_code_constant_new_boolean (0);
+ *value = vivi_code_boolean_new (0);
} else {
- *value = vivi_code_constant_new_boolean (data->scanner->value.v_boolean);
+ *value = vivi_code_boolean_new (data->scanner->value.v_boolean);
}
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
@@ -641,9 +646,9 @@ parse_numeric_literal (ParseData *data, ViviCodeValue **value)
if (!try_parse_token (data, TOKEN_NUMBER)) {
vivi_parser_error_unexpected (data, TOKEN_NUMBER);
- *value = vivi_code_constant_new_number (0);
+ *value = vivi_code_number_new (0);
} else {
- *value = vivi_code_constant_new_number (data->scanner->value.v_number);
+ *value = vivi_code_number_new (data->scanner->value.v_number);
}
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
@@ -662,9 +667,9 @@ parse_string_literal (ParseData *data, ViviCodeValue **value)
if (!try_parse_token (data, TOKEN_STRING)) {
vivi_parser_error_unexpected (data, TOKEN_STRING);
- *value = vivi_code_constant_new_string ("undefined");
+ *value = vivi_code_string_new ("undefined");
} else {
- *value = vivi_code_constant_new_string (data->scanner->value.v_string);
+ *value = vivi_code_string_new (data->scanner->value.v_string);
}
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
@@ -709,7 +714,7 @@ parse_literal (ParseData *data, ViviCodeValue **value)
vivi_parser_error_unexpected (data, ERROR_TOKEN_LITERAL);
vivi_parser_start_code_token (data);
- *value = vivi_code_constant_new_undefined ();
+ *value = vivi_code_undefined_new ();
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
}
@@ -771,7 +776,7 @@ parse_property_name (ParseData *data, ViviCodeValue **value)
vivi_parser_error_unexpected (data, ERROR_TOKEN_PROPERTY_NAME);
vivi_parser_start_code_token (data);
- *value = vivi_code_constant_new_undefined ();
+ *value = vivi_code_undefined_new ();
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
}
@@ -805,11 +810,11 @@ parse_array_literal (ParseData *data, ViviCodeValue **value,
while (TRUE) {
if (try_parse_token (data, TOKEN_BRACKET_RIGHT)) {
vivi_code_init_array_add_variable (VIVI_CODE_INIT_ARRAY (*value),
- vivi_code_constant_new_undefined ());
+ vivi_code_undefined_new ());
break;
} else if (try_parse_token (data, TOKEN_COMMA)) {
vivi_code_init_array_add_variable (VIVI_CODE_INIT_ARRAY (*value),
- vivi_code_constant_new_undefined ());
+ vivi_code_undefined_new ());
}
else if (peek_assignment_expression (data))
{
@@ -899,7 +904,7 @@ parse_variable_declaration (ParseData *data, ViviCodeStatement **statement)
} else {
vivi_parser_start_code_token (data);
- value = vivi_code_constant_new_undefined ();
+ value = vivi_code_undefined_new ();
statement_right = NULL;
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (value));
@@ -942,9 +947,9 @@ parse_get_url2 (ParseData *data, ViviCodeStatement **statement,
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)));
+ (int)vivi_code_number_get_value (VIVI_CODE_NUMBER (target)));
g_object_unref (target);
- target = vivi_code_constant_new_string (level_name);
+ target = vivi_code_string_new (level_name);
g_free (level_name);
} else {
// TODO
@@ -991,7 +996,7 @@ parse_get_url2 (ParseData *data, ViviCodeStatement **statement,
method = SWFDEC_LOADER_REQUEST_DEFAULT;
}
} else {
- target = vivi_code_constant_new_undefined ();
+ target = vivi_code_undefined_new ();
method = SWFDEC_LOADER_REQUEST_DEFAULT;
}
@@ -1368,7 +1373,7 @@ parse_primary_expression (ParseData *data, ViviCodeValue **value,
}
vivi_parser_error_unexpected (data, ERROR_TOKEN_PRIMARY_EXPRESSION);
- *value = vivi_code_constant_new_undefined ();
+ *value = vivi_code_undefined_new ();
*statement = NULL;
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
}
@@ -1402,7 +1407,7 @@ parse_member_expression (ParseData *data, ViviCodeValue **value,
} else {
vivi_parser_error_unexpected_or (data, ERROR_TOKEN_PRIMARY_EXPRESSION,
ERROR_TOKEN_FUNCTION_EXPRESSION, TOKEN_NONE);
- *value = vivi_code_constant_new_undefined ();
+ *value = vivi_code_undefined_new ();
*statement = NULL;
vivi_parser_duplicate_code_token (data);
@@ -1548,7 +1553,7 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
"Invalid left-hand side expression for INCREASE/DECREASE");
}
- one = vivi_code_constant_new_number (1);
+ one = vivi_code_number_new (1);
operation = (add ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
g_object_unref (one);
@@ -1616,7 +1621,7 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
"Invalid left-hand side expression for INCREASE/DECREASE");
}
- one = vivi_code_constant_new_number (1);
+ one = vivi_code_number_new (1);
tmp = (data->scanner->next_token == TOKEN_INCREASE ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
g_object_unref (one);
@@ -2269,7 +2274,7 @@ parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
g_object_unref (pre_value);
if (try_parse_token (data, TOKEN_SEMICOLON)) {
- condition = vivi_code_constant_new_boolean (TRUE);
+ condition = vivi_code_boolean_new (TRUE);
condition_statement = NULL;
} else {
parse_expression (data, &condition, &condition_statement);
@@ -2295,7 +2300,7 @@ parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
vivi_parser_error (data, "for (... in ...) has not been implemented yet");
- condition = vivi_code_constant_new_undefined ();
+ condition = vivi_code_undefined_new ();
condition_statement = NULL;
post_statement = NULL;
} else {
@@ -2306,7 +2311,7 @@ parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
vivi_parser_error_unexpected (data, TOKEN_SEMICOLON);
}
- condition = vivi_code_constant_new_undefined ();
+ condition = vivi_code_undefined_new ();
condition_statement = NULL;
post_statement = NULL;
@@ -2326,7 +2331,7 @@ parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
{
vivi_parser_error_unexpected (data, ERROR_TOKEN_ITERATION_STATEMENT);
- condition = vivi_code_constant_new_undefined ();
+ condition = vivi_code_undefined_new ();
pre_statement = NULL;
condition_statement = NULL;
loop_statement = vivi_compiler_empty_statement_new ();
commit 0c57cbeea50a3b7d7440220ad8e02f129ad08ebf
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Apr 17 16:32:51 2008 +0200
add stubs for the code emitter
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index d0ae8a5..ec268b2 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -38,6 +38,7 @@ libvivified_compiler_la_SOURCES = \
vivi_code_concat.c \
vivi_code_constant.c \
vivi_code_continue.c \
+ vivi_code_emitter.c \
vivi_code_function.c \
vivi_code_function_call.c \
vivi_code_get.c \
@@ -95,6 +96,7 @@ noinst_HEADERS = \
vivi_code_constant.h \
vivi_code_continue.h \
vivi_code_defaults.h \
+ vivi_code_emitter.h \
vivi_code_function.h \
vivi_code_function_call.h \
vivi_code_get.h \
diff --git a/vivified/code/vivi_code_asm.h b/vivified/code/vivi_code_asm.h
index 0687471..cc7465d 100644
--- a/vivified/code/vivi_code_asm.h
+++ b/vivified/code/vivi_code_asm.h
@@ -30,11 +30,17 @@ G_BEGIN_DECLS
#define VIVI_IS_CODE_ASM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_ASM))
#define VIVI_CODE_ASM_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), VIVI_TYPE_CODE_ASM, ViviCodeAsmInterface))
+/* forward declaration */
+typedef struct _ViviCodeEmitter ViviCodeEmitter;
+
typedef struct _ViviCodeAsm ViviCodeAsm; /* dummy object */
typedef struct _ViviCodeAsmInterface ViviCodeAsmInterface;
struct _ViviCodeAsmInterface {
GTypeInterface interface;
+
+ void (* emit) (ViviCodeAsm * code,
+ ViviCodeEmitter * emitter);
};
GType vivi_code_asm_get_type (void) G_GNUC_CONST;
diff --git a/vivified/code/vivi_code_asm_code_default.c b/vivified/code/vivi_code_asm_code_default.c
index 3a40fb6..3daf353 100644
--- a/vivified/code/vivi_code_asm_code_default.c
+++ b/vivified/code/vivi_code_asm_code_default.c
@@ -24,7 +24,7 @@
#include "vivi_code_asm_code_default.h"
#include "vivi_code_printer.h"
-#define DEFAULT_ASM(CapsName, underscore_name, bytecode) \
+#define DEFAULT_ASM(CapsName, underscore_name, byte_code) \
\
G_DEFINE_TYPE (ViviCodeAsm ## CapsName, vivi_code_asm_ ## underscore_name, VIVI_TYPE_CODE_ASM_CODE); \
\
@@ -38,9 +38,12 @@ vivi_code_asm_ ## underscore_name ## _print (ViviCodeToken *token, ViviCodePrint
static void \
vivi_code_asm_ ## underscore_name ## _class_init (ViviCodeAsm ## CapsName ## Class *klass) \
{ \
+ ViviCodeAsmCodeClass *code_class = VIVI_CODE_ASM_CODE_CLASS (klass); \
ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass); \
\
token_class->print = vivi_code_asm_ ## underscore_name ## _print; \
+\
+ code_class->bytecode = byte_code; \
} \
\
static void \
diff --git a/vivified/code/vivi_code_asm_code_default.h b/vivified/code/vivi_code_asm_code_default.h
index d30c181..72bdfba 100644
--- a/vivified/code/vivi_code_asm_code_default.h
+++ b/vivified/code/vivi_code_asm_code_default.h
@@ -17,8 +17,8 @@
* Boston, MA 02110-1301 USA
*/
-#ifndef _VIVI_CODE_BINARY_DEFAULT_H_
-#define _VIVI_CODE_BINARY_DEFAULT_H_
+#ifndef _VIVI_CODE_ASM_CODE_DEFAULT_H_
+#define _VIVI_CODE_ASM_CODE_DEFAULT_H_
#include <vivified/code/vivi_code_asm_code.h>
#include <vivified/code/vivi_code_asm.h>
diff --git a/vivified/code/vivi_code_emitter.c b/vivified/code/vivi_code_emitter.c
new file mode 100644
index 0000000..e73cd57
--- /dev/null
+++ b/vivified/code/vivi_code_emitter.c
@@ -0,0 +1,150 @@
+/* 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_emitter.h"
+
+G_DEFINE_TYPE (ViviCodeEmitter, vivi_code_emitter, G_TYPE_OBJECT)
+
+static void
+vivi_code_emitter_dispose (GObject *object)
+{
+ ViviCodeEmitter *emit = VIVI_CODE_EMITTER (object);
+
+ if (emit->bots) {
+ SwfdecBuffer *buffer = swfdec_bots_close (emit->bots);
+ swfdec_buffer_unref (buffer);
+ emit->bots = NULL;
+ }
+ g_slist_foreach (emit->later, (GFunc) g_free, NULL);
+ g_slist_free (emit->later);
+ emit->later = NULL;
+ g_hash_table_remove_all (emit->labels);
+ emit->labels = NULL;
+
+ G_OBJECT_CLASS (vivi_code_emitter_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_emitter_class_init (ViviCodeEmitterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = vivi_code_emitter_dispose;
+}
+
+static void
+vivi_code_emitter_init (ViviCodeEmitter *emit)
+{
+ emit->bots = swfdec_bots_open ();
+ emit->labels = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ g_object_unref, g_free);
+}
+
+void
+vivi_code_emitter_emit_asm (ViviCodeEmitter *emitter, ViviCodeAsm *code)
+{
+ ViviCodeAsmInterface *iface;
+
+ g_return_if_fail (VIVI_IS_CODE_EMITTER (emitter));
+ g_return_if_fail (VIVI_IS_CODE_ASM (code));
+
+ iface = VIVI_CODE_ASM_GET_INTERFACE (code);
+ iface->emit (code, emitter);
+}
+
+void
+vivi_code_emitter_add_label (ViviCodeEmitter *emitter, ViviCodeLabel *label)
+{
+ g_return_if_fail (VIVI_IS_CODE_EMITTER (emitter));
+ g_return_if_fail (VIVI_IS_CODE_LABEL (label));
+
+ g_assert (g_hash_table_lookup (emitter->labels, label) == NULL);
+ g_hash_table_insert (emitter->labels, g_object_ref (label),
+ GSIZE_TO_POINTER (swfdec_bots_get_bytes (emitter->bots) + 1));
+}
+
+gssize
+vivi_code_emitter_get_label_offset (ViviCodeEmitter *emitter, ViviCodeLabel *label)
+{
+ gsize size;
+
+ g_return_val_if_fail (VIVI_IS_CODE_EMITTER (emitter), -1);
+ g_return_val_if_fail (VIVI_IS_CODE_LABEL (label), -1);
+
+ size = GPOINTER_TO_SIZE (g_hash_table_lookup (emitter->labels, label));
+ return (gssize) size - 1;
+}
+
+typedef struct {
+ ViviCodeEmitLater func;
+ gpointer data;
+} Later;
+
+void
+vivi_code_emitter_add_later (ViviCodeEmitter *emitter, ViviCodeEmitLater func, gpointer data)
+{
+ Later *later;
+
+ g_return_if_fail (VIVI_IS_CODE_EMITTER (emitter));
+ g_return_if_fail (VIVI_IS_CODE_EMITTER (emitter));
+
+ later = g_new (Later, 1);
+ later->func = func;
+ later->data = data;
+ emitter->later = g_slist_prepend (emitter->later, later);
+}
+
+SwfdecBuffer *
+vivi_code_emitter_finish (ViviCodeEmitter *emitter, GError **error)
+{
+ SwfdecBuffer *buffer;
+ GSList *walk;
+
+ g_return_val_if_fail (VIVI_IS_CODE_EMITTER (emitter), NULL);
+
+ buffer = swfdec_bots_close (emitter->bots);
+ emitter->bots = NULL;
+ for (walk = emitter->later; walk; walk = walk->next) {
+ Later *later = walk->data;
+ if (!later->func (emitter, buffer, later->data, error)) {
+ swfdec_buffer_unref (buffer);
+ buffer = NULL;
+ }
+ }
+ g_slist_foreach (emitter->later, (GFunc) g_free, NULL);
+ g_slist_free (emitter->later);
+ emitter->later = NULL;
+ g_hash_table_remove_all (emitter->labels);
+ emitter->bots = swfdec_bots_open ();
+
+ return buffer;
+}
+
+SwfdecBots *
+vivi_code_emitter_get_bots (ViviCodeEmitter *emitter)
+{
+ g_return_val_if_fail (VIVI_IS_CODE_EMITTER (emitter), NULL);
+
+ return emitter->bots;
+}
+
diff --git a/vivified/code/vivi_code_emitter.h b/vivified/code/vivi_code_emitter.h
new file mode 100644
index 0000000..03c2fe4
--- /dev/null
+++ b/vivified/code/vivi_code_emitter.h
@@ -0,0 +1,76 @@
+/* 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_EMITTER_H_
+#define _VIVI_CODE_EMITTER_H_
+
+#include <swfdec/swfdec.h>
+#include <swfdec/swfdec_bots.h>
+#include <vivified/code/vivi_code_asm.h>
+#include <vivified/code/vivi_code_label.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeEmitterClass ViviCodeEmitterClass;
+typedef gboolean (* ViviCodeEmitLater) (ViviCodeEmitter *emitter, SwfdecBuffer *buffer, gpointer data, GError **error);
+
+#define VIVI_TYPE_CODE_EMITTER (vivi_code_emitter_get_type())
+#define VIVI_IS_CODE_EMITTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_EMITTER))
+#define VIVI_IS_CODE_EMITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_EMITTER))
+#define VIVI_CODE_EMITTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_EMITTER, ViviCodeEmitter))
+#define VIVI_CODE_EMITTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_EMITTER, ViviCodeEmitterClass))
+#define VIVI_CODE_EMITTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_EMITTER, ViviCodeEmitterClass))
+
+struct _ViviCodeEmitter
+{
+ GObject object;
+
+ SwfdecBots * bots; /* output stream */
+ GHashTable * labels; /* ViviCodeLabel => offset + 1 */
+ GSList * later; /* ViviCodeEmitLater/data tuples */
+};
+
+struct _ViviCodeEmitterClass
+{
+ GObjectClass object_class;
+};
+
+GType vivi_code_emitter_get_type (void);
+
+ViviCodeEmitter * vivi_code_emitter_new (void);
+
+void vivi_code_emitter_emit_asm (ViviCodeEmitter * emitter,
+ ViviCodeAsm * code);
+
+SwfdecBots * vivi_code_emitter_get_bots (ViviCodeEmitter * emitter);
+void vivi_code_emitter_add_label (ViviCodeEmitter * emitter,
+ ViviCodeLabel * label);
+gssize vivi_code_emitter_get_label_offset
+ (ViviCodeEmitter * emitter,
+ ViviCodeLabel * label);
+void vivi_code_emitter_add_later (ViviCodeEmitter * emitter,
+ ViviCodeEmitLater func,
+ gpointer data);
+SwfdecBuffer * vivi_code_emitter_finish (ViviCodeEmitter * emitter,
+ GError ** error);
+
+
+G_END_DECLS
+#endif
More information about the Swfdec-commits
mailing list