[Swfdec-commits] vivified/code

Benjamin Otte company at kemper.freedesktop.org
Sun Apr 13 13:17:35 PDT 2008


 vivified/code/Makefile.am                |    9 +
 vivified/code/vivi_code_and.c            |   59 ++++++++++++
 vivified/code/vivi_code_and.h            |   55 +++++++++++
 vivified/code/vivi_code_binary.c         |   97 +--------------------
 vivified/code/vivi_code_binary.h         |   13 +-
 vivified/code/vivi_code_binary_default.c |   62 +++++++++++++
 vivified/code/vivi_code_binary_default.h |   41 ++++++++
 vivified/code/vivi_code_defaults.h       |   52 +++++++++++
 vivified/code/vivi_code_or.c             |   59 ++++++++++++
 vivified/code/vivi_code_or.h             |   55 +++++++++++
 vivified/code/vivi_code_value.h          |    1 
 vivified/code/vivi_decompiler.c          |   23 +++-
 vivified/code/vivi_parser.c              |  143 +++++++++++++++++++------------
 13 files changed, 515 insertions(+), 154 deletions(-)

New commits:
commit 4964ab12312bfa961b02e240cde99ba041821283
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Apr 13 21:52:53 2008 +0200

    convert binary handling to use one class per token
    
    I'm not sure yet if it's a good idea. It feels cleaner though.

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 789bae3..205e734 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -16,8 +16,10 @@ libvivified_compiler_la_LIBADD = \
 	libvivified-parser-lex.la
 
 libvivified_compiler_la_SOURCES = \
+	vivi_code_and.c \
 	vivi_code_assignment.c \
 	vivi_code_binary.c \
+	vivi_code_binary_default.c \
 	vivi_code_block.c \
 	vivi_code_break.c \
 	vivi_code_comment.c \
@@ -34,6 +36,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_init_object.c \
 	vivi_code_label.c \
 	vivi_code_loop.c \
+	vivi_code_or.c \
 	vivi_code_play.c \
 	vivi_code_printer.c \
 	vivi_code_return.c \
@@ -58,14 +61,17 @@ libvivified_compiler_la_SOURCES = \
 	vivi_parser_scanner.c
 
 noinst_HEADERS = \
+	vivi_code_and.h \
 	vivi_code_assignment.h \
-	vivi_code_binary.c \
+	vivi_code_binary.h \
+	vivi_code_binary_default.h \
 	vivi_code_block.h \
 	vivi_code_break.h \
 	vivi_code_comment.h \
 	vivi_code_compiler.h \
 	vivi_code_constant.h \
 	vivi_code_continue.h \
+	vivi_code_defaults.h \
 	vivi_code_function.h \
 	vivi_code_function_call.h \
 	vivi_code_get.h \
@@ -76,6 +82,7 @@ noinst_HEADERS = \
 	vivi_code_init_object.h \
 	vivi_code_label.h \
 	vivi_code_loop.h \
+	vivi_code_or.h \
 	vivi_code_play.h \
 	vivi_code_printer.h \
 	vivi_code_return.h \
diff --git a/vivified/code/vivi_code_and.c b/vivified/code/vivi_code_and.c
new file mode 100644
index 0000000..b2af31c
--- /dev/null
+++ b/vivified/code/vivi_code_and.c
@@ -0,0 +1,59 @@
+/* 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_and.h"
+
+G_DEFINE_TYPE (ViviCodeAnd, vivi_code_and, VIVI_TYPE_CODE_BINARY)
+
+static void
+vivi_code_and_class_init (ViviCodeAndClass *klass)
+{
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+  ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
+
+  token_class->compile = NULL; /* FIXME */
+
+  binary_class->operator_name = "&&";
+}
+
+static void
+vivi_code_and_init (ViviCodeAnd *and)
+{
+  vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_AND);
+}
+
+ViviCodeValue *
+vivi_code_and_new (ViviCodeValue *left, ViviCodeValue *right)
+{
+  ViviCodeBinary *binary;
+
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
+
+  binary = g_object_new (VIVI_TYPE_CODE_AND, NULL);
+  binary->left = g_object_ref (left);
+  binary->right = g_object_ref (right);
+
+  return VIVI_CODE_VALUE (binary);
+}
+
diff --git a/vivified/code/vivi_code_and.h b/vivified/code/vivi_code_and.h
new file mode 100644
index 0000000..fbe3fa8
--- /dev/null
+++ b/vivified/code/vivi_code_and.h
@@ -0,0 +1,55 @@
+/* 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_AND_H_
+#define _VIVI_CODE_AND_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeAnd ViviCodeAnd;
+typedef struct _ViviCodeAndClass ViviCodeAndClass;
+
+#define VIVI_TYPE_CODE_AND                    (vivi_code_and_get_type())
+#define VIVI_IS_CODE_AND(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_AND))
+#define VIVI_IS_CODE_AND_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_AND))
+#define VIVI_CODE_AND(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_AND, ViviCodeAnd))
+#define VIVI_CODE_AND_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_AND, ViviCodeAndClass))
+#define VIVI_CODE_AND_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_AND, ViviCodeAndClass))
+
+struct _ViviCodeAnd
+{
+  ViviCodeBinary	binary;
+};
+
+struct _ViviCodeAndClass
+{
+  ViviCodeBinaryClass	binary_class;
+};
+
+GType			vivi_code_and_get_type   	(void);
+
+ViviCodeValue *		vivi_code_and_new		(ViviCodeValue *	left,
+							 ViviCodeValue *	right);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_binary.c b/vivified/code/vivi_code_binary.c
index ec78597..2995c0e 100644
--- a/vivified/code/vivi_code_binary.c
+++ b/vivified/code/vivi_code_binary.c
@@ -27,37 +27,6 @@
 #include "vivi_code_printer.h"
 #include "vivi_code_compiler.h"
 
-static struct {
-  const char *		operation;
-  guint			bytecode;
-  ViviPrecedence	precedence;
-} operation_table[] = {
-  { "add",	SWFDEC_AS_ACTION_ADD,		VIVI_PRECEDENCE_ADD },
-  { "-",	SWFDEC_AS_ACTION_SUBTRACT,	VIVI_PRECEDENCE_ADD },
-  { "*",	SWFDEC_AS_ACTION_MULTIPLY,	VIVI_PRECEDENCE_MULTIPLY },
-  { "/",	SWFDEC_AS_ACTION_DIVIDE,	VIVI_PRECEDENCE_MULTIPLY },
-  { "==",	SWFDEC_AS_ACTION_EQUALS,	VIVI_PRECEDENCE_EQUALITY },
-  { "<",	SWFDEC_AS_ACTION_LESS,		VIVI_PRECEDENCE_RELATIONAL },
-  { "and",	SWFDEC_AS_ACTION_AND,		VIVI_PRECEDENCE_AND },
-  { "or",	SWFDEC_AS_ACTION_OR,		VIVI_PRECEDENCE_OR },
-  { "eq",	SWFDEC_AS_ACTION_STRING_EQUALS,	VIVI_PRECEDENCE_EQUALITY },
-  { "lt",	SWFDEC_AS_ACTION_STRING_LESS,	VIVI_PRECEDENCE_RELATIONAL },
-  { "+",	SWFDEC_AS_ACTION_ADD2,		VIVI_PRECEDENCE_ADD },
-  { "<",	SWFDEC_AS_ACTION_LESS2,		VIVI_PRECEDENCE_RELATIONAL },
-  { "==",	SWFDEC_AS_ACTION_EQUALS2,	VIVI_PRECEDENCE_EQUALITY },
-  { "&",	SWFDEC_AS_ACTION_BIT_AND,	VIVI_PRECEDENCE_BINARY_AND },
-  { "|",	SWFDEC_AS_ACTION_BIT_OR,	VIVI_PRECEDENCE_BINARY_OR },
-  { "^",	SWFDEC_AS_ACTION_BIT_XOR,	VIVI_PRECEDENCE_BINARY_XOR },
-  { "<<",	SWFDEC_AS_ACTION_BIT_LSHIFT,	VIVI_PRECEDENCE_SHIFT },
-  { ">>",	SWFDEC_AS_ACTION_BIT_RSHIFT,	VIVI_PRECEDENCE_SHIFT },
-  { ">>>",	SWFDEC_AS_ACTION_BIT_URSHIFT,	VIVI_PRECEDENCE_SHIFT },
-  { "===",	SWFDEC_AS_ACTION_STRICT_EQUALS,	VIVI_PRECEDENCE_EQUALITY },
-  { ">",	SWFDEC_AS_ACTION_GREATER,	VIVI_PRECEDENCE_RELATIONAL },
-  { "gt",	SWFDEC_AS_ACTION_STRING_GREATER,VIVI_PRECEDENCE_RELATIONAL },
-  { "&&",	0,				VIVI_PRECEDENCE_AND },
-  { "||",	0,				VIVI_PRECEDENCE_OR }
-};
-
 G_DEFINE_TYPE (ViviCodeBinary, vivi_code_binary, VIVI_TYPE_CODE_VALUE)
 
 static void
@@ -75,28 +44,29 @@ static void
 vivi_code_binary_print (ViviCodeToken *token, ViviCodePrinter*printer)
 {
   ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
+  ViviCodeValue *value = VIVI_CODE_VALUE (token);
+  ViviCodeBinaryClass *klass = VIVI_CODE_BINARY_GET_CLASS (binary);
 
   vivi_code_printer_print_value (printer, binary->left, 
-      operation_table[binary->operation_index].precedence);
+      vivi_code_value_get_precedence (value));
   vivi_code_printer_print (printer, " ");
-  vivi_code_printer_print (printer, operation_table[binary->operation_index].operation);
+  vivi_code_printer_print (printer, klass->operator_name);
   vivi_code_printer_print (printer, " ");
   vivi_code_printer_print_value (printer, binary->right, 
-      operation_table[binary->operation_index].precedence);
+      vivi_code_value_get_precedence (value));
 }
 
 static void
 vivi_code_binary_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
-
-  g_assert (operation_table[binary->operation_index].bytecode != 0);
+  ViviCodeBinaryClass *klass = VIVI_CODE_BINARY_GET_CLASS (binary);
 
   vivi_code_compiler_compile_value (compiler, binary->left);
   vivi_code_compiler_compile_value (compiler, binary->right);
 
-  vivi_code_compiler_write_empty_action (compiler,
-      operation_table[binary->operation_index].bytecode);
+  g_assert (klass->bytecode != 0);
+  vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
 }
 
 static gboolean
@@ -128,54 +98,3 @@ vivi_code_binary_init (ViviCodeBinary *binary)
 {
 }
 
-ViviCodeValue *
-vivi_code_binary_new_bytecode (ViviCodeValue *left, ViviCodeValue *right, guint code)
-{
-  ViviCodeBinary *binary;
-  guint id;
-
-  g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
-  g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
-  for (id = 0; id < G_N_ELEMENTS (operation_table); id++) {
-    if (operation_table[id].bytecode == code)
-      break;
-  }
-  g_return_val_if_fail (id < G_N_ELEMENTS (operation_table), NULL);
-
-  binary = g_object_new (VIVI_TYPE_CODE_BINARY, NULL);
-  binary->left = g_object_ref (left);
-  binary->right = g_object_ref (right);
-  binary->operation_index = id;
-
-  vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary), 
-      operation_table[id].precedence);
-
-  return VIVI_CODE_VALUE (binary);
-}
-
-ViviCodeValue *
-vivi_code_binary_new_name (ViviCodeValue *left, ViviCodeValue *right, const char *name)
-{
-  ViviCodeBinary *binary;
-  guint id;
-
-  g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
-  g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
-  g_return_val_if_fail (name != NULL, NULL);
-  for (id = 0; id < G_N_ELEMENTS (operation_table); id++) {
-    if (g_str_equal (operation_table[id].operation, name))
-      break;
-  }
-  g_return_val_if_fail (id < G_N_ELEMENTS (operation_table), NULL);
-
-  binary = g_object_new (VIVI_TYPE_CODE_BINARY, NULL);
-  binary->left = g_object_ref (left);
-  binary->right = g_object_ref (right);
-  binary->operation_index = id;
-
-  vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary), 
-      operation_table[id].precedence);
-
-  return VIVI_CODE_VALUE (binary);
-}
-
diff --git a/vivified/code/vivi_code_binary.h b/vivified/code/vivi_code_binary.h
index cd71f97..b11cd03 100644
--- a/vivified/code/vivi_code_binary.h
+++ b/vivified/code/vivi_code_binary.h
@@ -20,6 +20,7 @@
 #ifndef _VIVI_CODE_BINARY_H_
 #define _VIVI_CODE_BINARY_H_
 
+#include <swfdec/swfdec_as_interpret.h>
 #include <vivified/code/vivi_code_value.h>
 
 G_BEGIN_DECLS
@@ -39,7 +40,6 @@ struct _ViviCodeBinary
 {
   ViviCodeValue		parent;
 
-  guint			operation_index;
   ViviCodeValue *	left;
   ViviCodeValue *	right;
 };
@@ -47,16 +47,15 @@ struct _ViviCodeBinary
 struct _ViviCodeBinaryClass
 {
   ViviCodeValueClass	value_class;
+
+  /*< private >*/
+  /* use vivi_code_default.h */
+  const char *		operator_name;
+  SwfdecAsAction	bytecode;
 };
 
 GType			vivi_code_binary_get_type   	(void);
 
-ViviCodeValue *		vivi_code_binary_new_bytecode 	(ViviCodeValue *	left,
-							 ViviCodeValue *	right,
-							 guint			code);
-ViviCodeValue *		vivi_code_binary_new_name	(ViviCodeValue *	left,
-							 ViviCodeValue *	right,
-							 const char *		name);
 
 G_END_DECLS
 #endif
diff --git a/vivified/code/vivi_code_binary_default.c b/vivified/code/vivi_code_binary_default.c
new file mode 100644
index 0000000..dbb3ba4
--- /dev/null
+++ b/vivified/code/vivi_code_binary_default.c
@@ -0,0 +1,62 @@
+/* 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 <swfdec/swfdec_as_interpret.h>
+
+#include "vivi_code_binary_default.h"
+
+#define DEFAULT_BINARY(CapsName, underscore_name, operatorname, bc, precedence) \
+\
+G_DEFINE_TYPE (ViviCode ## CapsName, vivi_code_ ## underscore_name, VIVI_TYPE_CODE_BINARY) \
+\
+static void \
+vivi_code_ ## underscore_name ## _class_init (ViviCodeBinaryClass *klass) \
+{ \
+  ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass); \
+\
+  binary_class->operator_name = operatorname; \
+  binary_class->bytecode = bc; \
+} \
+\
+static void \
+vivi_code_ ## underscore_name ## _init (ViviCodeBinary *binary) \
+{ \
+  vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary), precedence); \
+} \
+\
+ViviCodeValue * \
+vivi_code_ ## underscore_name ## _new (ViviCodeValue *left, ViviCodeValue *right) \
+{ \
+  ViviCodeBinary *binary; \
+\
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL); \
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL); \
+\
+  binary = g_object_new (vivi_code_ ## underscore_name ## _get_type (), NULL); \
+  binary->left = g_object_ref (left); \
+  binary->right = g_object_ref (right); \
+\
+  return VIVI_CODE_VALUE (binary); \
+}
+
+#include "vivi_code_defaults.h"
diff --git a/vivified/code/vivi_code_binary_default.h b/vivified/code/vivi_code_binary_default.h
new file mode 100644
index 0000000..18a4926
--- /dev/null
+++ b/vivified/code/vivi_code_binary_default.h
@@ -0,0 +1,41 @@
+/* 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_BINARY_DEFAULT_H_
+#define _VIVI_CODE_BINARY_DEFAULT_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+#define DEFAULT_BINARY(CapsName, underscore_name, operator_name, bytecode, precedence) \
+\
+typedef ViviCodeBinary ViviCode ## CapsName; \
+typedef ViviCodeBinaryClass ViviCode ## CapsName ## Class; \
+\
+GType			vivi_code_ ## underscore_name ## _get_type   	(void); \
+\
+ViviCodeValue *		vivi_code_## underscore_name ## _new		(ViviCodeValue *	left, \
+									 ViviCodeValue *	right);
+
+#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
new file mode 100644
index 0000000..c6d3d45
--- /dev/null
+++ b/vivified/code/vivi_code_defaults.h
@@ -0,0 +1,52 @@
+/* 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 DEFAULT_BINARY
+#define DEFAULT_BINARY(CapsName, underscore_name, operator_name, bytecode, precedence)
+#endif
+
+DEFAULT_BINARY (Add,		add,		"add",	SWFDEC_AS_ACTION_ADD,		VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Subtract,	subtract,	"-",	SWFDEC_AS_ACTION_SUBTRACT,	VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Multiply,	multiply,	"*",	SWFDEC_AS_ACTION_MULTIPLY,	VIVI_PRECEDENCE_MULTIPLY)
+DEFAULT_BINARY (Divide,		divide,		"/",	SWFDEC_AS_ACTION_DIVIDE,	VIVI_PRECEDENCE_MULTIPLY)
+DEFAULT_BINARY (Modulo,		modulo,		"%",	SWFDEC_AS_ACTION_MODULO,	VIVI_PRECEDENCE_MODULO)
+DEFAULT_BINARY (Equals,		equals,		"==",	SWFDEC_AS_ACTION_EQUALS,	VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (Less,		less,		"<",	SWFDEC_AS_ACTION_LESS,		VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (LogicalAnd,	logical_and,	"and",	SWFDEC_AS_ACTION_AND,		VIVI_PRECEDENCE_AND)
+DEFAULT_BINARY (LogicalOr,	logical_or,	"or",	SWFDEC_AS_ACTION_OR,		VIVI_PRECEDENCE_OR)
+DEFAULT_BINARY (StringEquals,	string_equals,	"eq",	SWFDEC_AS_ACTION_STRING_EQUALS,	VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (StringLess,	string_less,	"lt",	SWFDEC_AS_ACTION_STRING_LESS,	VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (Add2,		add2,	  	"+",	SWFDEC_AS_ACTION_ADD2,		VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Less2,		less2,		"<",	SWFDEC_AS_ACTION_LESS2,		VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (Equals2,	equals2,	"==",	SWFDEC_AS_ACTION_EQUALS2,	VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (BitwiseAnd,	bitwise_and,	"&",	SWFDEC_AS_ACTION_BIT_AND,	VIVI_PRECEDENCE_BINARY_AND)
+DEFAULT_BINARY (BitwiseOr,	bitwise_or,	"|",	SWFDEC_AS_ACTION_BIT_OR,	VIVI_PRECEDENCE_BINARY_OR)
+DEFAULT_BINARY (BitwiseXor,	bitwise_xor,	"^",	SWFDEC_AS_ACTION_BIT_XOR,	VIVI_PRECEDENCE_BINARY_XOR)
+DEFAULT_BINARY (LeftShift,	left_shift,	"<<",	SWFDEC_AS_ACTION_BIT_LSHIFT,	VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (RightShift,	right_shift,	">>",	SWFDEC_AS_ACTION_BIT_RSHIFT,	VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (UnsignedRightShift,unsigned_right_shift,">>>",SWFDEC_AS_ACTION_BIT_URSHIFT,VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (StrictEquals,	strict_equals,	"===",	SWFDEC_AS_ACTION_STRICT_EQUALS,	VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (Greater,	greater,	">",	SWFDEC_AS_ACTION_GREATER,	VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (StringGreater,	string_greater,	"gt",	SWFDEC_AS_ACTION_STRING_GREATER,VIVI_PRECEDENCE_RELATIONAL)
+/* other special ones:
+DEFAULT_BINARY (And,		and,		"&&",	???,				VIVI_PRECEDENCE_AND)
+DEFAULT_BINARY (Or,		or,		"||",	???,				VIVI_PRECEDENCE_AND)
+*/
+
+#undef DEFAULT_BINARY
diff --git a/vivified/code/vivi_code_or.c b/vivified/code/vivi_code_or.c
new file mode 100644
index 0000000..ae215bf
--- /dev/null
+++ b/vivified/code/vivi_code_or.c
@@ -0,0 +1,59 @@
+/* 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_or.h"
+
+G_DEFINE_TYPE (ViviCodeOr, vivi_code_or, VIVI_TYPE_CODE_BINARY)
+
+static void
+vivi_code_or_class_init (ViviCodeOrClass *klass)
+{
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+  ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
+
+  token_class->compile = NULL; /* FIXME */
+
+  binary_class->operator_name = "&&";
+}
+
+static void
+vivi_code_or_init (ViviCodeOr *and)
+{
+  vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_AND);
+}
+
+ViviCodeValue *
+vivi_code_or_new (ViviCodeValue *left, ViviCodeValue *right)
+{
+  ViviCodeBinary *binary;
+
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
+  g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
+
+  binary = g_object_new (VIVI_TYPE_CODE_OR, NULL);
+  binary->left = g_object_ref (left);
+  binary->right = g_object_ref (right);
+
+  return VIVI_CODE_VALUE (binary);
+}
+
diff --git a/vivified/code/vivi_code_or.h b/vivified/code/vivi_code_or.h
new file mode 100644
index 0000000..583bc77
--- /dev/null
+++ b/vivified/code/vivi_code_or.h
@@ -0,0 +1,55 @@
+/* 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_OR_H_
+#define _VIVI_CODE_OR_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeOr ViviCodeOr;
+typedef struct _ViviCodeOrClass ViviCodeOrClass;
+
+#define VIVI_TYPE_CODE_OR                    (vivi_code_or_get_type())
+#define VIVI_IS_CODE_OR(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_OR))
+#define VIVI_IS_CODE_OR_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_OR))
+#define VIVI_CODE_OR(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_OR, ViviCodeOr))
+#define VIVI_CODE_OR_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_OR, ViviCodeOrClass))
+#define VIVI_CODE_OR_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_OR, ViviCodeOrClass))
+
+struct _ViviCodeOr
+{
+  ViviCodeBinary	binary;
+};
+
+struct _ViviCodeOrClass
+{
+  ViviCodeBinaryClass	binary_class;
+};
+
+GType			vivi_code_or_get_type   	(void);
+
+ViviCodeValue *		vivi_code_or_new		(ViviCodeValue *	left,
+							 ViviCodeValue *	right);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_value.h b/vivified/code/vivi_code_value.h
index ae66a9c..61ea81a 100644
--- a/vivified/code/vivi_code_value.h
+++ b/vivified/code/vivi_code_value.h
@@ -38,6 +38,7 @@ typedef enum {
   VIVI_PRECEDENCE_RELATIONAL,
   VIVI_PRECEDENCE_SHIFT,
   VIVI_PRECEDENCE_ADD,
+  VIVI_PRECEDENCE_MODULO,
   VIVI_PRECEDENCE_MULTIPLY,
   VIVI_PRECEDENCE_UNARY,
   VIVI_PRECEDENCE_INCREMENT,
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index d4b5759..fc63fb0 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -28,8 +28,9 @@
 #include <swfdec/swfdec_script_internal.h>
 
 #include "vivi_decompiler.h"
+#include "vivi_code_and.h"
 #include "vivi_code_assignment.h"
-#include "vivi_code_binary.h"
+#include "vivi_code_binary_default.h"
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
 #include "vivi_code_constant.h"
@@ -42,6 +43,7 @@
 #include "vivi_code_if.h"
 #include "vivi_code_init_object.h"
 #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"
@@ -402,10 +404,19 @@ vivi_decompile_binary (ViviDecompilerBlock *block, ViviDecompilerState *state,
     guint code, const guint8 *data, guint len)
 {
   ViviCodeValue *right, *left, *result;
+#define DEFAULT_BINARY(CapsName, underscore_name, operatore_name, bytecode, precedence) \
+    case bytecode: \
+      result = vivi_code_ ## underscore_name ## _new (left, right); \
+      break;
 
   right = vivi_decompiler_state_pop (state);
   left = vivi_decompiler_state_pop (state);
-  result = vivi_code_binary_new_bytecode (left, right, code);
+  switch (code) {
+#include "vivi_code_defaults.h"
+    default:
+      g_assert_not_reached ();
+      return FALSE;
+  }
   g_object_unref (left);
   g_object_unref (right);
   vivi_decompiler_state_push (state, result);
@@ -1062,9 +1073,9 @@ vivi_decompiler_merge_andor (GList **list)
 {
   ViviDecompilerBlock *block, *andor, *next;
   gboolean result;
-  const char *type;
   ViviCodeValue *value, *value2;
   ViviDecompilerState *state;
+  ViviCodeValue * (* func) (ViviCodeValue *, ViviCodeValue *);
 
   GList *walk;
   result = FALSE;
@@ -1087,9 +1098,9 @@ vivi_decompiler_merge_andor (GList **list)
     value = vivi_decompiler_block_get_branch_condition (block);
     if (VIVI_IS_CODE_UNARY (value)) {
       value = vivi_code_unary_get_value (VIVI_CODE_UNARY (value));
-      type = "&&";
+      func = vivi_code_and_new;
     } else {
-      type = "||";
+      func = vivi_code_or_new;
     }
     if (!VIVI_IS_DECOMPILER_DUPLICATE (value))
       continue;
@@ -1121,7 +1132,7 @@ vivi_decompiler_merge_andor (GList **list)
     DEBUG ("merging %s code for %p\n", type, vivi_decompiler_block_get_start (andor));
 
     /* update our finish state */
-    value = vivi_code_binary_new_name (value, value2, type);
+    value = func (value, value2);
     state = (ViviDecompilerState *) vivi_decompiler_block_get_end_state (block);
     g_object_unref (vivi_decompiler_state_pop (state));
     vivi_decompiler_state_push (state, value);
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 5423bca..4f37bb6 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -27,8 +27,9 @@
 
 #include "vivi_parser_scanner.h"
 
+#include "vivi_code_and.h"
 #include "vivi_code_assignment.h"
-#include "vivi_code_binary.h"
+#include "vivi_code_binary_default.h"
 #include "vivi_code_block.h"
 #include "vivi_code_break.h"
 #include "vivi_code_constant.h"
@@ -42,6 +43,7 @@
 #include "vivi_code_init_array.h"
 #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"
@@ -1278,7 +1280,7 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
 {
   ViviCodeStatement *assignment;
   ViviCodeValue *operation, *one, *temporary;
-  const char *operator;
+  gboolean add;
 
   vivi_parser_start_code_token (data);
 
@@ -1290,9 +1292,9 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
   }
 
   if (try_parse_token (data, TOKEN_INCREASE)) {
-    operator = "+";
+    add = TRUE;
   } else if (try_parse_token (data, TOKEN_DESCREASE)) {
-    operator = "-";
+    add = FALSE;
   } else {
     vivi_parser_end_code_token (data, NULL);
     return;
@@ -1305,7 +1307,7 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
   }
 
   one = vivi_code_constant_new_number (1);
-  operation = vivi_code_binary_new_name (*value, one, operator);
+  operation = (add ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
   g_object_unref (one);
 
   vivi_parser_duplicate_code_token (data);
@@ -1352,9 +1354,6 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
     ViviCodeStatement **statement)
 {
   ViviCodeValue *tmp, *one;
-  const char *operator;
-
-  operator = NULL;
 
   vivi_parser_scanner_peek_next_token (data->scanner);
   switch ((guint)data->scanner->next_token) {
@@ -1362,11 +1361,7 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
     case TOKEN_VOID:
     case TOKEN_TYPEOF:*/
     case TOKEN_INCREASE:
-      operator = "+";
-      // fall through
     case TOKEN_DESCREASE:
-      if (!operator) operator = "-";
-
       vivi_parser_start_code_token (data);
 
       vivi_parser_scanner_get_next_token (data->scanner);
@@ -1380,7 +1375,7 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
       }
 
       one = vivi_code_constant_new_number (1);
-      tmp = vivi_code_binary_new_name (*value, one, operator);
+      tmp = (data->scanner->next_token == TOKEN_INCREASE ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
       g_object_unref (one);
 
       vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (tmp));
@@ -1424,7 +1419,37 @@ parse_operator_expression (ParseData *data, ViviCodeValue **value,
 {
   ViviCodeValue *left, *right;
   ViviCodeStatement *statement_right;
-  guint i;
+  guint i, j;
+  static const struct {
+    ViviParserScannerToken	token;
+    ViviCodeValue *		(* func) (ViviCodeValue *, ViviCodeValue *);
+  } table[] = {
+//    { TOKEN_, vivi_code_add_new },
+    { TOKEN_MINUS, vivi_code_subtract_new },
+    { TOKEN_MULTIPLY, vivi_code_multiply_new },
+    { TOKEN_DIVIDE, vivi_code_divide_new },
+    { TOKEN_REMAINDER, vivi_code_modulo_new },
+//    { TOKEN_, vivi_code_equals_new },
+//    { TOKEN_, vivi_code_less_new },
+//    { TOKEN_, vivi_code_logical_and_new },
+//    { TOKEN_, vivi_code_logical_or_new },
+//    { TOKEN_, vivi_code_string_equals_new },
+//    { TOKEN_, vivi_code_string_less_new },
+    { TOKEN_PLUS, vivi_code_add2_new },
+    { TOKEN_LESS_THAN, vivi_code_less2_new },
+    { TOKEN_EQUAL, vivi_code_equals2_new },
+    { TOKEN_BITWISE_AND, vivi_code_bitwise_and_new },
+    { TOKEN_BITWISE_OR, vivi_code_bitwise_or_new },
+    { TOKEN_BITWISE_XOR, vivi_code_bitwise_xor_new },
+    { TOKEN_SHIFT_LEFT, vivi_code_left_shift_new },
+    { TOKEN_SHIFT_RIGHT, vivi_code_right_shift_new },
+    { TOKEN_SHIFT_RIGHT_UNSIGNED, vivi_code_unsigned_right_shift_new },
+    { TOKEN_STRICT_EQUAL, vivi_code_strict_equals_new },
+    { TOKEN_GREATER_THAN, vivi_code_greater_new },
+//    { TOKEN_, vivi_code_string_greater_new },
+    { TOKEN_LOGICAL_AND, vivi_code_and_new },
+    { TOKEN_LOGICAL_OR, vivi_code_or_new }
+  };
 
   vivi_parser_start_code_token (data);
 
@@ -1462,15 +1487,20 @@ again:
       }
 
       left = VIVI_CODE_VALUE (*value);
-      *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right),
-	  vivi_parser_scanner_token_name (tokens[i]));
-      g_object_unref (left);
-      g_object_unref (right);
+      for (j = 0; j < G_N_ELEMENTS (table); j++) {
+	if (tokens[i] != table[j].token)
+	  continue;
 
-      vivi_parser_duplicate_code_token (data);
-      vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
+	*value = table[j].func (left, VIVI_CODE_VALUE (right));
+	g_object_unref (left);
+	g_object_unref (right);
 
-      goto again;
+	vivi_parser_duplicate_code_token (data);
+	vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
+
+	goto again;
+      }
+      g_assert_not_reached ();
     }
   }
 
@@ -1711,7 +1741,7 @@ parse_assignment_expression (ParseData *data, ViviCodeValue **value,
 {
   ViviCodeValue *right;
   ViviCodeStatement *assignment, *statement_right;
-  const char *operator;
+  ViviCodeValue * (* func) (ViviCodeValue *, ViviCodeValue *);
 
   vivi_parser_start_code_token (data);
 
@@ -1723,53 +1753,64 @@ parse_assignment_expression (ParseData *data, ViviCodeValue **value,
     return;
   }
 
-  operator = NULL;
-
   vivi_parser_scanner_peek_next_token (data->scanner);
   switch ((guint)data->scanner->next_token) {
     case TOKEN_ASSIGN_MULTIPLY:
-      if (operator == NULL) operator = "*";
+      func = vivi_code_multiply_new;
+      break;
     case TOKEN_ASSIGN_DIVIDE:
-      if (operator == NULL) operator = "/";
+      func = vivi_code_divide_new;
+      break;
     case TOKEN_ASSIGN_REMAINDER:
-      if (operator == NULL) operator = "%";
+      func = vivi_code_modulo_new;
+      break;
     case TOKEN_ASSIGN_ADD:
-      if (operator == NULL) operator = "+";
+      func = vivi_code_add2_new;
+      break;
     case TOKEN_ASSIGN_MINUS:
-      if (operator == NULL) operator = "-";
+      func = vivi_code_subtract_new;
+      break;
     case TOKEN_ASSIGN_SHIFT_LEFT:
-      if (operator == NULL) operator = "<<";
+      func = vivi_code_left_shift_new;
+      break;
     case TOKEN_ASSIGN_SHIFT_RIGHT:
-      if (operator == NULL) operator = ">>";
+      func = vivi_code_right_shift_new;
+      break;
     case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
-      if (operator == NULL) operator = ">>>";
+      func = vivi_code_unsigned_right_shift_new;
+      break;
     case TOKEN_ASSIGN_BITWISE_AND:
-      if (operator == NULL) operator = "&";
+      func = vivi_code_bitwise_and_new;
+      break;
     case TOKEN_ASSIGN_BITWISE_OR:
-      if (operator == NULL) operator = "|";
+      func = vivi_code_bitwise_or_new;
+      break;
     case TOKEN_ASSIGN_BITWISE_XOR:
-      if (operator == NULL) operator = "^";
+      func = vivi_code_bitwise_and_new;
+      break;
     case TOKEN_ASSIGN:
-      vivi_parser_scanner_get_next_token (data->scanner);
+      func = NULL;
+      break;
+    default:
+      return;
+  }
+  
+  vivi_parser_scanner_get_next_token (data->scanner);
 
-      parse_assignment_expression (data, &right, &statement_right);
+  parse_assignment_expression (data, &right, &statement_right);
 
-      if (operator != NULL) {
-	assignment = vivi_parser_assignment_new (*value,
-	    vivi_code_binary_new_name (*value, right, operator));
-      } else {
-	assignment = vivi_parser_assignment_new (*value, right);
-      }
-      g_object_unref (right);
+  if (func != NULL) {
+    assignment = vivi_parser_assignment_new (*value,
+	func (*value, right));
+  } else {
+    assignment = vivi_parser_assignment_new (*value, right);
+  }
+  g_object_unref (right);
 
-      vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (assignment));
+  vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (assignment));
 
-      *statement = vivi_parser_join_statements (*statement,
-	  vivi_parser_join_statements (statement_right, assignment));
-      break;
-    default:
-      break;
-  }
+  *statement = vivi_parser_join_statements (*statement,
+      vivi_parser_join_statements (statement_right, assignment));
 }
 
 static gboolean


More information about the Swfdec-commits mailing list