ref: 58fdded930b84287ddc8bbc0a14e2c0e03f008e5
parent: adbbeec67255f04049dbf28a3fe7573e8248f97d
author: Tor Andersson <tor@ccxvii.net>
date: Wed Jan 8 16:09:21 EST 2014
Add syntax tree structs.
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-SRCS := js-state.c js-string.c js-load.c js-lex.c js-parse.c
+SRCS := js-state.c js-string.c js-load.c js-lex.c js-parse.c js-ast.c
HDRS := js.h js-parse.h
OBJS := $(SRCS:%.c=build/%.o)
--- /dev/null
+++ b/js-ast.c
@@ -1,0 +1,142 @@
+#include "js.h"
+#include "js-ast.h"
+
+js_Ast *jsP_newnode(js_State *J, int type, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d)
+{
+ js_Ast *node = malloc(sizeof(js_Ast));
+
+ node->type = type;
+ node->a = a;
+ node->b = b;
+ node->c = c;
+ node->d = d;
+ node->n = 0;
+ node->s = NULL;
+
+ return node;
+}
+
+js_Ast *jsP_newsnode(js_State *J, int type, const char *s)
+{
+ js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0);
+ node->s = js_intern(J, s);
+ return node;
+}
+
+js_Ast *jsP_newnnode(js_State *J, int type, double n)
+{
+ js_Ast *node = jsP_newnode(J, type, 0, 0, 0, 0);
+ node->n = n;
+ return node;
+}
+
+static const char *strast(int type)
+{
+ switch (type) {
+ case AST_LIST: return "LIST";
+ case AST_IDENTIFIER: return "IDENTIFIER";
+ case AST_NUMBER: return "NUMBER";
+ case AST_STRING: return "STRING";
+ case AST_REGEXP: return "REGEXP";
+ case EXP_NULL: return "NULL";
+ case EXP_TRUE: return "TRUE";
+ case EXP_FALSE: return "FALSE";
+ case EXP_THIS: return "THIS";
+ case EXP_ARRAY: return "ARRAY";
+ case EXP_OBJECT: return "OBJECT";
+ case EXP_PROP_VAL: return "PROP_VAL";
+ case EXP_PROP_GET: return "PROP_GET";
+ case EXP_PROP_SET: return "PROP_SET";
+ case EXP_INDEX: return "EXP_INDEX";
+ case EXP_MEMBER: return "EXP_MEMBER";
+ case EXP_NEW: return "new";
+ case EXP_CALL: return "EXP_CALL";
+ case EXP_FUNC: return "EXP_FUNC";
+ case EXP_COND: return "?:";
+ case EXP_COMMA: return ",";
+ case EXP_DELETE: return "delete";
+ case EXP_VOID: return "void";
+ case EXP_TYPEOF: return "typeof";
+ case EXP_PREINC: return "PRE++";
+ case EXP_PREDEC: return "PRE--";
+ case EXP_POSTINC: return "POST++";
+ case EXP_POSTDEC: return "POST--";
+ case EXP_POS: return "+";
+ case EXP_NEG: return "-";
+ case EXP_BITNOT: return "~";
+ case EXP_LOGNOT: return "!";
+ case EXP_LOGOR: return "||";
+ case EXP_LOGAND: return "&&";
+ case EXP_BITOR: return "|";
+ case EXP_BITXOR: return "^";
+ case EXP_BITAND: return "&";
+ case EXP_EQ: return "==";
+ case EXP_NE: return "!=";
+ case EXP_EQ3: return "===";
+ case EXP_NE3: return "!==";
+ case EXP_LT: return "<";
+ case EXP_GT: return ">";
+ case EXP_LE: return "<=";
+ case EXP_GE: return ">=";
+ case EXP_INSTANCEOF: return "instanceof";
+ case EXP_IN: return "in";
+ case EXP_SHL: return "<<";
+ case EXP_SHR: return ">>";
+ case EXP_USHR: return ">>>";
+ case EXP_ADD: return "+";
+ case EXP_SUB: return "-";
+ case EXP_MUL: return "*";
+ case EXP_DIV: return "/";
+ case EXP_MOD: return "%";
+ case EXP_ASS: return "=";
+ case EXP_ASS_MUL: return "*=";
+ case EXP_ASS_DIV: return "/=";
+ case EXP_ASS_MOD: return "%=";
+ case EXP_ASS_ADD: return "+=";
+ case EXP_ASS_SUB: return "-=";
+ case EXP_ASS_SHL: return "<<=";
+ case EXP_ASS_SHR: return ">>=";
+ case EXP_ASS_USHR: return ">>>=";
+ case EXP_ASS_BITAND: return "&=";
+ case EXP_ASS_BITXOR: return "^=";
+ case EXP_ASS_BITOR: return "|=";
+ case STM_NOP: return "STM_NOP";
+ case STM_EXP: return "STM_EXP";
+ case STM_VAR: return "STM_VAR";
+ case STM_IF: return "if";
+ case STM_DO: return "do-while";
+ case STM_WHILE: return "while";
+ case STM_FOR_EXP: return "for_3";
+ case STM_FOR_VAR_EXP: return "for_var_3";
+ case STM_FOR_IN: return "for_in";
+ case STM_FOR_VAR_IN: return "for_var_in";
+ case STM_CONTINUE: return "continue";
+ case STM_BREAK: return "break";
+ case STM_RETURN: return "return";
+ case STM_WITH: return "with";
+ case STM_SWITCH: return "switch";
+ case STM_THROW: return "throw";
+ case STM_TRY: return "try";
+ case STM_LABEL: return "label";
+ case STM_CASE: return "case";
+ case STM_DEFAULT: return "default";
+ case STM_DEBUGGER: return "debugger";
+ default: return "(unknown)";
+ }
+}
+
+void printast(js_Ast *n)
+{
+ switch (n->type) {
+ case AST_IDENTIFIER: printf("%s", n->s); return;
+ case AST_NUMBER: printf("%g", n->n); return;
+ case AST_STRING: printf("'%s'", n->s); return;
+ case AST_REGEXP: printf("/%s/", n->s); return;
+ default: printf("(%s", strast(n->type));
+ }
+ if (n->a) { putchar(' '); printast(n->a); }
+ if (n->b) { putchar(' '); printast(n->b); }
+ if (n->c) { putchar(' '); printast(n->c); }
+ if (n->d) { putchar(' '); printast(n->d); }
+ putchar(')');
+}
--- /dev/null
+++ b/js-ast.h
@@ -1,0 +1,122 @@
+#ifndef js_ast_h
+#define js_ast_h
+
+typedef struct js_Ast js_Ast;
+
+struct js_Ast
+{
+ int type;
+ int op;
+ js_Ast *a, *b, *c, *d;
+ double n;
+ const char *s;
+};
+
+enum
+{
+ AST_LIST,
+
+ AST_IDENTIFIER,
+ AST_NUMBER,
+ AST_STRING,
+ AST_REGEXP,
+
+ /* literals */
+ EXP_NULL,
+ EXP_TRUE,
+ EXP_FALSE,
+ EXP_THIS,
+
+ EXP_ARRAY,
+ EXP_OBJECT,
+ EXP_PROP_VAL,
+ EXP_PROP_GET,
+ EXP_PROP_SET,
+
+ /* expressions */
+ EXP_INDEX,
+ EXP_MEMBER,
+ EXP_NEW,
+ EXP_CALL,
+ EXP_FUNC,
+ EXP_COND,
+ EXP_COMMA,
+
+ EXP_DELETE,
+ EXP_VOID,
+ EXP_TYPEOF,
+ EXP_PREINC,
+ EXP_PREDEC,
+ EXP_POSTINC,
+ EXP_POSTDEC,
+ EXP_POS,
+ EXP_NEG,
+ EXP_BITNOT,
+ EXP_LOGNOT,
+
+ EXP_LOGOR,
+ EXP_LOGAND,
+ EXP_BITOR,
+ EXP_BITXOR,
+ EXP_BITAND,
+ EXP_EQ,
+ EXP_NE,
+ EXP_EQ3,
+ EXP_NE3,
+ EXP_LT,
+ EXP_GT,
+ EXP_LE,
+ EXP_GE,
+ EXP_INSTANCEOF,
+ EXP_IN,
+ EXP_SHL,
+ EXP_SHR,
+ EXP_USHR,
+ EXP_ADD,
+ EXP_SUB,
+ EXP_MUL,
+ EXP_DIV,
+ EXP_MOD,
+
+ EXP_ASS,
+ EXP_ASS_MUL,
+ EXP_ASS_DIV,
+ EXP_ASS_MOD,
+ EXP_ASS_ADD,
+ EXP_ASS_SUB,
+ EXP_ASS_SHL,
+ EXP_ASS_SHR,
+ EXP_ASS_USHR,
+ EXP_ASS_BITAND,
+ EXP_ASS_BITXOR,
+ EXP_ASS_BITOR,
+
+ /* statements */
+ STM_NOP,
+ STM_EXP,
+ STM_VAR,
+ STM_IF,
+ STM_DO,
+ STM_WHILE,
+ STM_FOR_EXP,
+ STM_FOR_VAR_EXP,
+ STM_FOR_IN,
+ STM_FOR_VAR_IN,
+ STM_CONTINUE,
+ STM_BREAK,
+ STM_RETURN,
+ STM_WITH,
+ STM_SWITCH,
+ STM_THROW,
+ STM_TRY,
+ STM_LABEL,
+ STM_CASE,
+ STM_DEFAULT,
+ STM_DEBUGGER,
+};
+
+js_Ast *jsP_newnode(js_State *J, int type, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d);
+js_Ast *jsP_newsnode(js_State *J, int type, const char *s);
+js_Ast *jsP_newnnode(js_State *J, int type, double n);
+
+#endif