📄 gram.js
字号:
this.expr = expr;
}
/*
* Expressions.
*/
/* This. */
function JSC$expr_this (ln)
{
this.etype = JSC$EXPR_THIS;
this.linenum = ln;
this.asm = JSC$expr_this_asm;
}
function JSC$expr_this_asm ()
{
new JSC$ASM_load_arg (this.linenum, 0).link ();
}
/* Identifier. */
function JSC$expr_identifier (ln, value)
{
this.etype = JSC$EXPR_IDENTIFIER;
this.linenum = ln;
this.value = value;
this.asm = JSC$expr_identifier_asm;
}
function JSC$expr_identifier_asm ()
{
JSC$asm_expr_lvalue_load_asm (this);
}
/* Float. */
function JSC$expr_float (ln, value)
{
this.etype = JSC$EXPR_FLOAT;
this.lang_type = JSC$JS_FLOAT;
this.linenum = ln;
this.value = value;
this.asm = JSC$expr_float_asm;
}
function JSC$expr_float_asm ()
{
new JSC$ASM_const (this.linenum, this.value).link ();
}
/* Integer. */
function JSC$expr_integer (ln, value)
{
this.etype = JSC$EXPR_INTEGER;
this.lang_type = JSC$JS_INTEGER;
this.linenum = ln;
this.value = value;
this.asm = JSC$expr_integer_asm;
}
function JSC$expr_integer_asm ()
{
if (this.value == 0)
new JSC$ASM_const_i0 (this.linenum).link ();
else if (this.value == 1)
new JSC$ASM_const_i1 (this.linenum).link ();
else if (this.value == 2)
new JSC$ASM_const_i2 (this.linenum).link ();
else if (this.value == 3)
new JSC$ASM_const_i3 (this.linenum).link ();
else
new JSC$ASM_const_i (this.linenum, this.value).link ();
}
/* String. */
function JSC$expr_string (ln, value)
{
this.etype = JSC$EXPR_STRING;
this.lang_type = JSC$JS_STRING;
this.linenum = ln;
this.value = value;
this.asm = JSC$expr_string_asm;
}
function JSC$expr_string_asm ()
{
new JSC$ASM_const (this.linenum, this.value).link ();
}
/* Regexp. */
function JSC$expr_regexp (ln, value)
{
this.etype = JSC$EXPR_REGEXP;
this.lang_type = JSC$JS_BUILTIN;
this.linenum = ln;
this.value = value;
this.asm = JSC$expr_regexp_asm;
}
function JSC$expr_regexp_asm ()
{
new JSC$ASM_const (this.linenum, this.value).link ();
}
/* Array initializer. */
function JSC$expr_array_initializer (ln, items)
{
this.etype = JSC$EXPR_ARRAY_INITIALIZER;
this.lang_type = JSC$JS_ARRAY;
this.linenum = ln;
this.items = items;
this.asm = JSC$expr_array_initializer_asm;
}
function JSC$expr_array_initializer_asm ()
{
/* Generate assembler for the individual items. */
var i;
for (i = this.items.length - 1; i >= 0; i--)
{
if (this.items[i])
this.items[i].asm ();
else
new JSC$ASM_const_undefined (this.linenum).link ();
}
/*
* The number of items as a negative integer. The Array object's
* constructor knows that if the number of arguments is negative, it
* is called from the array initializer. Why? Because the code:
*
* new Array (5);
*
* creates an array of length of 5, but code:
*
* [5]
*
* creates an array with one item: integer number five. These cases
* must be separatable from the code and that's why the argument
* counts for the array initializers are negative.
*/
new JSC$ASM_const (this.linenum, -this.items.length).link ();
/* Call the constructor. */
new JSC$ASM_load_global (this.linenum, "Array").link ();
new JSC$ASM_new (this.linenum).link ();
new JSC$ASM_swap (this.linenum).link ();
new JSC$ASM_apop (this.linenum, this.items.length + 2).link ();
}
/* Object initializer. */
function JSC$expr_object_initializer (ln, items)
{
this.etype = JSC$EXPR_OBJECT_INITIALIZER;
this.lang_type = JSC$JS_OBJECT;
this.linenum = ln;
this.items = items;
this.asm = JSC$expr_object_initializer_asm;
}
function JSC$expr_object_initializer_asm ()
{
/* Create a new object. */
new JSC$ASM_const_i0 (this.linenum).link ();
new JSC$ASM_load_global (this.linenum, "Object").link ();
new JSC$ASM_new (this.linenum).link ();
new JSC$ASM_swap (this.linenum).link ();
new JSC$ASM_apop (this.linenum, 2).link ();
/* Insert the items. */
for (var i = 0; i < this.items.length; i++)
{
var item = this.items[i];
new JSC$ASM_dup (item.linenum).link ();
item.expr.asm ();
new JSC$ASM_swap (item.linenum).link ();
switch (item.id_type)
{
case JSC$tIDENTIFIER:
new JSC$ASM_store_property (item.linenum, item.id).link ();
break;
case JSC$tSTRING:
new JSC$ASM_const (item.linenum, item.id).link ();
new JSC$ASM_store_array (item.linenum).link ();
break;
case JSC$tINTEGER:
switch (item.id)
{
case 0:
new JSC$ASM_const_i0 (item.linenum).link ();
break;
case 1:
new JSC$ASM_const_i1 (item.linenum).link ();
break;
case 2:
new JSC$ASM_const_i2 (item.linenum).link ();
break;
case 3:
new JSC$ASM_const_i3 (item.linenum).link ();
break;
default:
new JSC$ASM_const_i (item.linenum, item.id).link ();
break;
}
new JSC$ASM_store_array (item.linenum).link ();
break;
}
}
}
/* Null. */
function JSC$expr_null (ln)
{
this.etype = JSC$EXPR_NULL;
this.lang_type = JSC$JS_NULL;
this.linenum = ln;
this.asm = JSC$expr_null_asm;
}
function JSC$expr_null_asm ()
{
new JSC$ASM_const_null (this.linenum).link ();
}
/* True. */
function JSC$expr_true (ln)
{
this.etype = JSC$EXPR_TRUE;
this.lang_type = JSC$JS_BOOLEAN;
this.linenum = ln;
this.asm = JSC$expr_true_asm;
}
function JSC$expr_true_asm ()
{
new JSC$ASM_const_true (this.linenum).link ();
}
/* False. */
function JSC$expr_false (ln)
{
this.etype = JSC$EXPR_FALSE;
this.lang_type = JSC$JS_BOOLEAN;
this.linenum = ln;
this.asm = JSC$expr_false_asm;
}
function JSC$expr_false_asm ()
{
new JSC$ASM_const_false (this.linenum).link ();
}
/* Multiplicative expr. */
function JSC$expr_multiplicative (ln, type, e1, e2)
{
this.etype = JSC$EXPR_MULTIPLICATIVE;
this.linenum = ln;
this.type = type;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_multiplicative_asm;
}
function JSC$expr_multiplicative_asm ()
{
this.e1.asm ();
this.e2.asm ();
if (this.type == #'*')
new JSC$ASM_mul (this.linenum).link ();
else if (this.type == #'/')
new JSC$ASM_div (this.linenum).link ();
else
new JSC$ASM_mod (this.linenum).link ();
}
/* Additive expr. */
function JSC$expr_additive (ln, type, e1, e2)
{
this.etype = JSC$EXPR_ADDITIVE;
this.linenum = ln;
this.type = type;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_additive_asm;
this.constant_folding = JSC$expr_additive_constant_folding;
}
function JSC$expr_additive_asm ()
{
this.e1.asm ();
this.e2.asm ();
if (this.type == #'+')
new JSC$ASM_add (this.linenum).link ();
else
new JSC$ASM_sub (this.linenum).link ();
}
function JSC$expr_additive_constant_folding ()
{
if (this.e1.constant_folding)
this.e1 = this.e1.constant_folding ();
if (this.e2.constant_folding)
this.e2 = this.e2.constant_folding ();
/* This could be smarter. */
if (this.e1.lang_type && this.e2.lang_type
&& this.e1.lang_type == this.e2.lang_type)
{
switch (this.e1.lang_type)
{
case JSC$JS_INTEGER:
return new JSC$expr_integer (this.linenum,
this.type == #'+'
? this.e1.value + this.e2.value
: this.e1.value - this.e2.value);
break;
case JSC$JS_FLOAT:
return new JSC$expr_float (this.linenum,
this.type == #'+'
? this.e1.value + this.e2.value
: this.e1.value - this.e2.value);
break;
case JSC$JS_STRING:
if (this.type == #'+')
/* Only the addition is available for the strings. */
return new JSC$expr_string (this.linenum,
this.e1.value + this.e2.value);
break;
default:
/* FALLTHROUGH */
break;
}
}
return this;
}
/* Shift expr. */
function JSC$expr_shift (ln, type, e1, e2)
{
this.etype = JSC$EXPR_SHIFT;
this.linenum = ln;
this.type = type;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_shift_asm;
}
function JSC$expr_shift_asm ()
{
this.e1.asm ();
this.e2.asm ();
if (this.type == JSC$tLSHIFT)
new JSC$ASM_shift_left (this.linenum).link ();
else if (this.type == JSC$tRSHIFT)
new JSC$ASM_shift_right (this.linenum).link ();
else
new JSC$ASM_shift_rright (this.linenum).link ();
}
/* Relational expr. */
function JSC$expr_relational (ln, type, e1, e2)
{
this.etype = JSC$EXPR_RELATIONAL;
this.lang_type = JSC$JS_BOOLEAN;
this.linenum = ln;
this.type = type;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_relational_asm;
}
function JSC$expr_relational_asm ()
{
this.e1.asm ();
this.e2.asm ();
if (this.type == #'<')
new JSC$ASM_cmp_lt (this.linenum).link ();
else if (this.type == #'>')
new JSC$ASM_cmp_gt (this.linenum).link ();
else if (this.type == JSC$tLE)
new JSC$ASM_cmp_le (this.linenum).link ();
else
new JSC$ASM_cmp_ge (this.linenum).link ();
}
/* Equality expr. */
function JSC$expr_equality (ln, type, e1, e2)
{
this.etype = JSC$EXPR_EQUALITY;
this.lang_type = JSC$JS_BOOLEAN;
this.linenum = ln;
this.type = type;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_equality_asm;
}
function JSC$expr_equality_asm ()
{
this.e1.asm ();
this.e2.asm ();
switch (this.type)
{
case JSC$tEQUAL:
new JSC$ASM_cmp_eq (this.linenum).link ();
break;
case JSC$tNEQUAL:
new JSC$ASM_cmp_ne (this.linenum).link ();
break;
case JSC$tSEQUAL:
new JSC$ASM_cmp_seq (this.linenum).link ();
break;
case JSC$tSNEQUAL:
new JSC$ASM_cmp_sne (this.linenum).link ();
break;
default:
error ("jsc: expr_equality: internal compiler error");
break;
}
}
/* Bitwise and expr. */
function JSC$expr_bitwise_and (ln, e1, e2)
{
this.etype = JSC$EXPR_BITWISE;
this.linenum = ln;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_bitwise_and_asm;
}
function JSC$expr_bitwise_and_asm ()
{
this.e1.asm ();
this.e2.asm ();
new JSC$ASM_and (this.linenum).link ();
}
/* Bitwise or expr. */
function JSC$expr_bitwise_or (ln, e1, e2)
{
this.etype = JSC$EXPR_BITWISE;
this.linenum = ln;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_bitwise_or_asm;
}
function JSC$expr_bitwise_or_asm ()
{
this.e1.asm ();
this.e2.asm ();
new JSC$ASM_or (this.linenum).link ();
}
/* Bitwise xor expr. */
function JSC$expr_bitwise_xor (ln, e1, e2)
{
this.etype = JSC$EXPR_BITWISE;
this.linenum = ln;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_bitwise_xor_asm;
}
function JSC$expr_bitwise_xor_asm ()
{
this.e1.asm ();
this.e2.asm ();
new JSC$ASM_xor (this.linenum).link ();
}
/* Logical and expr. */
function JSC$expr_logical_and (ln, e1, e2)
{
this.etype = JSC$EXPR_LOGICAL;
if (e1.lang_type && e2.lang_type
&& e1.lang_type == JSC$JS_BOOLEAN && e2.lang_type == JSC$JS_BOOLEAN)
this.lang_type = JSC$JS_BOOLEAN;
this.linenum = ln;
this.e1 = e1;
this.e2 = e2;
this.asm = JSC$expr_logical_and_asm;
}
function JSC$expr_logical_and_asm ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -