📄 gram.js
字号:
{
this.e1.asm ();
var l = new JSC$ASM_label ();
new JSC$ASM_dup (this.linenum).link ();
if (JSC$optimize_type && this.e1.lang_type
&& this.e1.lang_type == JSC$JS_BOOLEAN)
new JSC$ASM_iffalse_b (this.linenum, l).link ();
else
new JSC$ASM_iffalse (this.linenum, l).link ();
new JSC$ASM_pop (this.linenum).link ();
this.e2.asm ();
/* Done label. */
l.link ();
}
/* Logical or expr. */
function JSC$expr_logical_or (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_or_asm;
}
function JSC$expr_logical_or_asm ()
{
this.e1.asm ();
var l = new JSC$ASM_label ();
new JSC$ASM_dup (this.linenum).link ();
if (JSC$optimize_type && this.e1.lang_type
&& this.e1.lang_type == JSC$JS_BOOLEAN)
new JSC$ASM_iftrue_b (this.linenum, l).link ();
else
new JSC$ASM_iftrue (this.linenum, l).link ();
new JSC$ASM_pop (this.linenum).link ();
this.e2.asm ();
/* Done label. */
l.link ();
}
/* New expr. */
function JSC$expr_new (ln, expr, args)
{
this.etype = JSC$EXPR_NEW;
this.linenum = ln;
this.expr = expr;
this.args = args;
this.asm = JSC$expr_new_asm;
}
function JSC$expr_new_asm ()
{
var i;
if (this.args)
{
/* Code for the arguments. */
for (i = this.args.length - 1; i >= 0; i--)
this.args[i].asm ();
if (this.args.length == 0)
new JSC$ASM_const_i0 (this.linenum).link ();
else if (this.args.length == 1)
new JSC$ASM_const_i1 (this.linenum).link ();
else if (this.args.length == 2)
new JSC$ASM_const_i2 (this.linenum).link ();
else if (this.args.length == 3)
new JSC$ASM_const_i3 (this.linenum).link ();
else
new JSC$ASM_const (this.linenum, this.args.length).link ();
}
else
{
/* A `new Foo' call. This is identical to `new Foo ()'. */
new JSC$ASM_const_i0 (this.linenum).link ();
}
/* Object. */
this.expr.asm ();
/* Call new. */
new JSC$ASM_new (this.linenum).link ();
/* Replace the constructor's return value with the object. */
new JSC$ASM_swap (this.linenum).link ();
/* Remove the arguments and return the new object. */
new JSC$ASM_apop (this.linenum,
(this.args ? this.args.length : 0) + 2).link ();
}
/* Object property expr. */
function JSC$expr_object_property (ln, expr, id)
{
this.etype = JSC$EXPR_OBJECT_PROPERTY;
this.linenum = ln;
this.expr = expr;
this.id = id;
this.asm = JSC$expr_object_property_asm;
}
function JSC$expr_object_property_asm ()
{
JSC$asm_expr_lvalue_load_asm (this);
}
/* Object array expr. */
function JSC$expr_object_array (ln, expr1, expr2)
{
this.etype = JSC$EXPR_OBJECT_ARRAY;
this.linenum = ln;
this.expr1 = expr1;
this.expr2 = expr2;
this.asm = JSC$expr_object_array_asm;
}
function JSC$expr_object_array_asm ()
{
JSC$asm_expr_lvalue_load_asm (this);
}
/* Call. */
function JSC$expr_call (ln, expr, args)
{
this.etype = JSC$EXPR_CALL;
this.linenum = ln;
this.expr = expr;
this.args = args;
this.asm = JSC$expr_call_asm;
}
function JSC$expr_call_asm ()
{
var i;
/* Code for the arguments. */
for (i = this.args.length - 1; i >= 0; i--)
this.args[i].asm ();
if (this.args.length == 0)
new JSC$ASM_const_i0 (this.linenum).link ();
else if (this.args.length == 1)
new JSC$ASM_const_i1 (this.linenum).link ();
else if (this.args.length == 2)
new JSC$ASM_const_i2 (this.linenum).link ();
else if (this.args.length == 3)
new JSC$ASM_const_i3 (this.linenum).link ();
else
new JSC$ASM_const (this.linenum, this.args.length).link ();
/* Check the function type. */
if (this.expr.etype == JSC$EXPR_IDENTIFIER)
{
/* The simple subroutine or global object method invocation. */
var saved_with_nesting = JSC$cont_break.top.with_nesting;
JSC$cont_break.top.with_nesting = 0;
JSC$asm_expr_lvalue_load_asm (this.expr);
JSC$cont_break.top.with_nesting = saved_with_nesting;
if (JSC$cont_break.top.with_nesting > 0)
new JSC$ASM_jsr_w (this.linenum, this.expr.value).link ();
else
new JSC$ASM_jsr (this.linenum).link ();
new JSC$ASM_apop (this.linenum, this.args.length + 2).link ();
}
else if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY)
{
/* Method invocation. */
this.expr.expr.asm ();
new JSC$ASM_call_method (this.linenum, this.expr.id).link ();
new JSC$ASM_apop (this.linenum, this.args.length + 2).link ();
}
else
{
/* Something like a function pointer invocation. */
JSC$asm_expr_lvalue_load_asm (this.expr);
new JSC$ASM_jsr (this.linenum).link ();
new JSC$ASM_apop (this.linenum, this.args.length + 2).link ();
}
}
/* Assignment. */
function JSC$expr_assignment (ln, type, expr1, expr2)
{
this.etype = JSC$EXPR_ASSIGNMENT;
this.linenum = ln;
this.type = type;
this.expr1 = expr1;
this.expr2 = expr2;
this.asm = JSC$expr_assignment_asm;
}
function JSC$expr_assignment_asm ()
{
if (this.type != #'=')
JSC$asm_expr_lvalue_load_asm (this.expr1);
/* Count the rvalue. */
this.expr2.asm ();
if (this.type == #'=')
/* Nothing here. */
;
else if (this.type == JSC$tMULA)
new JSC$ASM_mul (this.linenum).link ();
else if (this.type == JSC$tDIVA)
new JSC$ASM_div (this.linenum).link ();
else if (this.type == JSC$tMODA)
new JSC$ASM_mod (this.linenum).link ();
else if (this.type == JSC$tADDA)
new JSC$ASM_add (this.linenum).link ();
else if (this.type == JSC$tSUBA)
new JSC$ASM_sub (this.linenum).link ();
else if (this.type == JSC$tLSIA)
new JSC$ASM_shift_left (this.linenum).link ();
else if (this.type == JSC$tRSIA)
new JSC$ASM_shift_right (this.linenum).link ();
else if (this.type == JSC$tRRSA)
new JSC$ASM_shift_rright (this.linenum).link ();
else if (this.type == JSC$tANDA)
new JSC$ASM_and (this.linenum).link ();
else if (this.type == JSC$tXORA)
new JSC$ASM_xor (this.linenum).link ();
else if (this.type == JSC$tORA)
new JSC$ASM_or (this.linenum).link ();
else
error (JSC$filename + ":" + this.linenum.toString ()
+ ": internal compiler error in assignment expression");
/* Duplicate the value. */
new JSC$ASM_dup (this.linenum).link ();
/* Store it to the lvalue. */
JSC$asm_expr_lvalue_store_asm (this.expr1);
}
function JSC$asm_expr_lvalue_load_asm (expr)
{
var i;
if (expr.etype == JSC$EXPR_IDENTIFIER)
{
/* Must check global / local / argument. */
i = JSC$ns.lookup_symbol (expr.value);
if (i == null)
{
if (JSC$cont_break.top.with_nesting > 0)
new JSC$ASM_load_global_w (expr.linenum, expr.value).link ();
else
new JSC$ASM_load_global (expr.linenum, expr.value).link ();
}
else if (i.scope == JSC$SCOPE_ARG)
{
if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber)
JSC$warning (JSC$filename + ":" + expr.linenum.toString ()
+ ": warning: the with-lookup of symbol `" + i.symbol
+ "' is clobbered by the argument definition");
new JSC$ASM_load_arg (expr.linenum, i.value).link ();
}
else
{
if (JSC$cont_break.top.with_nesting > 0 && JSC$warn_with_clobber)
JSC$warning (JSC$filename + ":" + expr.linenum.toString ()
+ ": warning: the with-lookup of symbol `" + i.symbol
+ "' is clobbered by the local variable definition");
new JSC$ASM_load_local (expr.linenum, i.value).link ();
}
}
else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY)
{
expr.expr.asm ();
new JSC$ASM_load_property (expr.linenum, expr.id).link ();
}
else if (expr.etype == JSC$EXPR_OBJECT_ARRAY)
{
expr.expr1.asm ();
expr.expr2.asm ();
new JSC$ASM_load_array (expr.linenum).link ();
}
else
error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error");
}
function JSC$asm_expr_lvalue_store_asm (expr)
{
var i;
if (expr.etype == JSC$EXPR_IDENTIFIER)
{
i = JSC$ns.lookup_symbol (expr.value);
if (i == null)
new JSC$ASM_store_global (expr.linenum, expr.value).link ();
else if (i.scope == JSC$SCOPE_ARG)
new JSC$ASM_store_arg (expr.linenum, i.value).link ();
else
new JSC$ASM_store_local (expr.linenum, i.value).link ();
}
else if (expr.etype == JSC$EXPR_OBJECT_PROPERTY)
{
expr.expr.asm ();
new JSC$ASM_store_property (expr.linenum, expr.id).link ();
}
else if (expr.etype == JSC$EXPR_OBJECT_ARRAY)
{
expr.expr1.asm ();
expr.expr2.asm ();
new JSC$ASM_store_array (expr.linenum).link ();
}
else
error (JSC$filename + ":" + expr.linenum.toString () + ": syntax error");
}
/* Quest colon. */
function JSC$expr_quest_colon (ln, e1, e2, e3)
{
this.etype = JSC$EXPR_QUEST_COLON;
this.linenum = ln;
this.e1 = e1;
this.e2 = e2;
this.e3 = e3;
this.asm = JSC$expr_quest_colon_asm;
}
function JSC$expr_quest_colon_asm()
{
/* Code for the condition. */
this.e1.asm ();
var l1 = new JSC$ASM_label ();
var l2 = new JSC$ASM_label ();
if (JSC$optimize_type && this.e1.lang_type
&& this.e1.lang_type == JSC$JS_BOOLEAN)
new JSC$ASM_iffalse_b (this.linenum, l1).link ();
else
new JSC$ASM_iffalse (this.linenum, l1).link ();
/* Code for the true branch. */
this.e2.asm ();
new JSC$ASM_jmp (this.linenum, l2).link ();
/* Code for the false branch. */
l1.link ();
this.e3.asm ();
/* Done label. */
l2.link ();
}
/* Unary. */
function JSC$expr_unary (ln, type, expr)
{
this.etype = JSC$EXPR_UNARY;
this.linenum = ln;
this.type = type;
this.expr = expr;
this.asm = JSC$expr_unary_asm;
}
function JSC$expr_unary_asm ()
{
if (this.type == #'!')
{
this.expr.asm ();
new JSC$ASM_not (this.linenum).link ();
}
else if (this.type == #'+')
{
this.expr.asm ();
/* Nothing here. */
}
else if (this.type == #'~')
{
this.expr.asm ();
new JSC$ASM_const (this.linenum, -1).link ();
new JSC$ASM_xor (this.linenum).link ();
}
else if (this.type == #'-')
{
this.expr.asm ();
new JSC$ASM_neg (this.linenum).link ();
}
else if (this.type == JSC$tDELETE)
{
if (this.expr.etype == JSC$EXPR_OBJECT_PROPERTY)
{
this.expr.expr.asm ();
new JSC$ASM_delete_property (this.linenum, this.expr.id).link ();
}
else if (this.expr.etype == JSC$EXPR_OBJECT_ARRAY)
{
this.expr.expr1.asm ();
this.expr.expr2.asm ();
new JSC$ASM_delete_array (this.linenum).link ();
}
else if (this.expr.etype == JSC$EXPR_IDENTIFIER)
{
if (JSC$cont_break.top.with_nesting == 0)
error (JSC$filename + ":" + this.linenum.toString ()
+ ": `delete property' called outside of a with-block");
new JSC$ASM_const_null (this.linenum).link ();
new JSC$ASM_delete_property (this.linenum, this.expr.value).link ();
}
else
error (JSC$filename + ":" + this.linenum.toString ()
+ ": illegal target for the delete operand");
}
else if (this.type == JSC$tVOID)
{
this.expr.asm ();
new JSC$ASM_pop (this.linenum).link ();
new JSC$ASM_const_undefined (this.linenum).link ();
}
else if (this.type == JSC$tTYPEOF)
{
this.expr.asm ();
new JSC$ASM_typeof (this.linenum).link ();
}
else if (this.type == JSC$tPLUSPLUS
|| this.type == JSC$tMINUSMINUS)
{
/* Fetch the old value. */
JSC$asm_expr_lvalue_load_asm (this.expr);
/* Do the operation. */
new JSC$ASM_const_i1 (this.linenum).link ();
if (this.type == JSC$tPLUSPLUS)
new JSC$ASM_add (this.linenum).link ();
else
new JSC$ASM_sub (this.linenum).link ();
/* Duplicate the value and store one copy pack to lvalue. */
new JSC$ASM_dup (this.linenum).link ();
JSC$asm_expr_lvalue_store_asm (this.expr);
}
else
{
error ("jsc: internal error: unary expr's type is "
+ this.type.toString ());
}
}
/* Postfix. */
function JSC$expr_postfix (ln, type, expr)
{
this.etype = JSC$EXPR_POSTFIX;
this.linenum = ln;
this.type = type;
this.expr = expr;
this.asm = JSC$expr_postfix_asm;
}
function JSC$expr_postfix_asm ()
{
/* Fetch the old value. */
JSC$asm_expr_lvalue_load_asm (this.expr);
/* Duplicate the value since it is the expression's value. */
new JSC$ASM_dup (this.linenum).link ();
/* Do the operation. */
new JSC$ASM_const_i1 (this.linenum).link ();
if (this.type == JSC$tPLUSPLUS)
new JSC$ASM_add (this.linenum).link ();
else
new JSC$ASM_sub (this.linenum).link ();
/* And finally, store it back. */
JSC$asm_expr_lvalue_store_asm (this.expr);
}
/* Postfix. */
function JSC$expr_comma (ln, expr1, expr2)
{
this.etype = JSC$EXPR_COMMA;
this.linenum = ln;
this.expr1 = expr1;
this.expr2 = expr2;
this.asm = JSC$expr_comma_asm;
}
function JSC$expr_comma_asm ()
{
this.expr1.asm ();
new JSC$ASM_pop (this.linenum).link ();
this.expr2.asm ();
}
/*
Local variables:
mode: c
End:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -