aboutsummaryrefslogtreecommitdiffstats
path: root/compile.h
diff options
context:
space:
mode:
Diffstat (limited to 'compile.h')
-rw-r--r--compile.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/compile.h b/compile.h
new file mode 100644
index 0000000000..2955977688
--- /dev/null
+++ b/compile.h
@@ -0,0 +1,210 @@
+/**********************************************************************
+
+ compile.h -
+
+ $Author$
+ $Date$
+ created at: 04/01/01 23:36:57 JST
+
+ Copyright (C) 2004-2006 Koichi Sasada
+
+**********************************************************************/
+
+#ifndef _COMPILER_H_INCLUDED_
+#define _COMPILER_H_INCLUDED_
+
+#include "version.h"
+
+#if YARVDEBUG > CPDEBUG
+#undef CPDEBUG
+#define CPDEBUG YARVDEBUG
+#endif
+
+/* */
+/**
+ * debug function(macro) interface depend on CPDEBUG
+ *
+ * debug level:
+ * 0: no debug output
+ * 1: show node type
+ * 2: show node important parameters
+ * ...
+ * 5: show other parameters
+ * 10: show every AST array
+ */
+
+#if 0
+#undef CPDEBUG
+#define CPDEBUG 2
+#endif
+
+#if CPDEBUG > 0
+
+#define debugp(header, value) \
+ (debug_indent(0, CPDEBUG, gl_node_level * 2), \
+ debug_value(0, CPDEBUG, header, value))
+
+#define debugi(header, id) \
+ (debug_indent(0, CPDEBUG, gl_node_level * 2), \
+ debug_id(0, CPDEBUG, header, id))
+
+#define debugp_param(header, value) \
+ (debug_indent(1, CPDEBUG, gl_node_level * 2), \
+ debug_value(1, CPDEBUG, header, value))
+
+#define debugp_verbose(header, value) \
+ (debug_indent(2, CPDEBUG, gl_node_level * 2), \
+ debug_value(2, CPDEBUG, header, value))
+
+#define debugp_verbose_node(header, value) \
+ (debug_indent(10, CPDEBUG, gl_node_level * 2), \
+ debug_value(10, CPDEBUG, header, value))
+
+#define debug_nodeprint(node) \
+ debug_indent(-1, CPDEBUG, gl_node_level*2); \
+ printf("node: %s (%d)\n", node_name(nd_type(node)), nd_line(node)); \
+ gl_node_level ++;
+
+#define debug_nodeprint_close() gl_node_level --;
+
+#else
+
+static inline ID
+r_id(ID id)
+{
+ return id;
+}
+
+static inline VALUE
+r_value(VALUE value)
+{
+ return value;
+}
+
+#define debugi(header, id) r_id(id)
+#define debugp(header, value) r_value(value)
+#define debugp_verbose(header, value) r_value(value)
+#define debugp_verbose_node(header, value) r_value(value)
+#define debugp_param(header, value) r_value(value)
+#define debug_nodeprint(node)
+#define debug_nodeprint_close()
+#endif
+
+#if CPDEBUG > 1
+#define debugs debug_indent(-1, CPDEBUG, gl_node_level*2), printf
+#define debug_compile(msg, v) (debug_indent(-1, CPDEBUG, gl_node_level*2), printf("%s", msg), (v))
+#else
+#define debugs if(0)printf
+#define debug_compile(msg, v) (v)
+#endif
+
+
+/* create new label */
+#define NEW_LABEL(l) new_label_body(iseq, l)
+
+#define iseq_filename(iseq) \
+ (((yarv_iseq_t*)DATA_PTR(iseq))->file_name)
+
+#define NEW_ISEQVAL(node, name, type) \
+ new_child_iseq(iseq, node, name, 0, type)
+
+#define NEW_CHILD_ISEQVAL(node, name, type) \
+ new_child_iseq(iseq, node, name, iseq->self, type)
+
+#define NEW_SPECIAQL_BLOCK_ISEQVAL(iseq, sym) \
+ new_child_iseq(iseq, iseq->node, iseq->name, iseq->parent_iseq, iseq->type, sym)
+
+/* add instructions */
+#define ADD_SEQ(seq1, seq2) \
+ APPEND_LIST(seq1, seq2)
+
+/* add an instruction */
+#define ADD_INSN(seq, line, insn) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) new_insn_body(iseq, line, BIN(insn), 0))
+
+/* add an instruction with label operand */
+#define ADD_INSNL(seq, line, insn, label) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) \
+ new_insn_body(iseq, line, BIN(insn), 1, (VALUE)label))
+
+/* add an instruction with some operands (1, 2, 3, 5) */
+#define ADD_INSN1(seq, line, insn, op1) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) \
+ new_insn_body(iseq, line, BIN(insn), 1, (VALUE)op1))
+
+#define ADD_INSN2(seq, line, insn, op1, op2) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) \
+ new_insn_body(iseq, line, BIN(insn), 2, (VALUE)op1, (VALUE)op2))
+
+#define ADD_INSN3(seq, line, insn, op1, op2, op3) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) \
+ new_insn_body(iseq, line, BIN(insn), 3, (VALUE)op1, (VALUE)op2, (VALUE)op3))
+
+/* Specific Insn factory */
+#define ADD_SEND(seq, line, id, argc) \
+ ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(0))
+
+#define ADD_CALL(seq, line, id, argc) \
+ ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
+
+#define ADD_SEND_R(seq, line, id, argc, block, flag) \
+ ADD_ELEM(seq, (LINK_ELEMENT *) \
+ new_insn_send(iseq, line, \
+ (VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag))
+
+/* add label */
+#define ADD_LABEL(seq, label) \
+ ADD_ELEM(seq, (LINK_ELEMENT *)label)
+
+#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
+ (tmp = rb_ary_new(), \
+ rb_ary_push(tmp, type), \
+ rb_ary_push(tmp, (VALUE) ls | 1), \
+ rb_ary_push(tmp, (VALUE) le | 1), \
+ rb_ary_push(tmp, iseqv), \
+ rb_ary_push(tmp, (VALUE) lc | 1), \
+ rb_ary_push(iseq->compile_data->catch_table_ary, tmp))
+
+/* compile node */
+#define COMPILE(anchor, desc, node) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, anchor, node, 0)))
+
+/* compile node, this node's value will be poped */
+#define COMPILE_POPED(anchor, desc, node) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, anchor, node, 1)))
+
+/* compile node, which is poped when 'poped' is true */
+#define COMPILE_(anchor, desc, node, poped) \
+ (debug_compile("== " desc "\n", \
+ iseq_compile_each(iseq, anchor, node, poped)))
+
+#define OPERAND_AT(insn, idx) \
+ (((INSN*)(insn))->operands[idx])
+
+#define INSN_OF(insn) \
+ (((INSN*)(insn))->insn_id)
+
+/* error */
+#define COMPILE_ERROR(strs) \
+{ \
+ VALUE tmp = GET_THREAD()->errinfo; \
+ if(CPDEBUG)rb_bug strs; \
+ GET_THREAD()->errinfo = iseq->compile_data->err_info; \
+ rb_compile_error strs; \
+ iseq->compile_data->err_info = GET_THREAD()->errinfo; \
+ GET_THREAD()->errinfo = tmp; \
+ ret = 0; \
+ break; \
+}
+
+
+#define COMPILE_OK 1
+#define COMPILE_NG 0
+
+#define DECL_ANCHOR(name) \
+ LINK_ANCHOR name##_body__ = {{0,}, &name##_body__.anchor}; \
+ LINK_ANCHOR *name = & name##_body__
+
+#endif // _COMPILER_H_INCLUDED_