⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gram.js

📁 一个类似windows
💻 JS
📖 第 1 页 / 共 5 页
字号:

/* Labeled statement. */
function JSC$stmt_labeled_stmt (ln, id, stmt)
{
  this.stype = JSC$STMT_LABELED_STMT;
  this.linenum = ln;
  this.id = id;
  this.stmt = stmt;
  this.asm = JSC$stmt_labeled_stmt_asm;
  this.count_locals = JSC$stmt_labeled_stmt_count_locals;
}

function JSC$stmt_labeled_stmt_asm ()
{
  var l_continue = new JSC$ASM_label ();
  var l_break = new JSC$ASM_label ();

  /*
   * It is an error if we already have a labeled statement with the
   * same id.
   */
  if (!JSC$cont_break.is_unique_label (this.id))
    error (JSC$filename + ":" + this.linenum.toString ()
	   + ": labeled statement is enclosed by another labeled statement "
	   + "with the same label");

  /* Push the break and continue labels. */
  JSC$cont_break.push (l_break, l_continue, false, this.id);

  /* Dump the assembler. */
  l_continue.link ();
  this.stmt.asm ();
  l_break.link ();

  /* And we'r done with out label scope. */
  JSC$cont_break.pop ();
}

function JSC$stmt_labeled_stmt_count_locals (recursive)
{
  return this.stmt.count_locals (recursive);
}


/* Expression. */

function JSC$stmt_expr (expr)
{
  this.stype = JSC$STMT_EXPR;
  this.linenum = expr.linenum;
  this.expr = expr;
  this.asm = JSC$stmt_expr_asm;
  this.count_locals = JSC$zero_function;
}

function JSC$stmt_expr_asm ()
{
  this.expr.asm ();
  new JSC$ASM_pop (this.linenum).link ();
}


/* If. */

function JSC$stmt_if (ln, expr, stmt1, stmt2)
{
  this.stype = JSC$STMT_IF;
  this.linenum = ln;
  this.expr = expr;
  this.stmt1 = stmt1;
  this.stmt2 = stmt2;
  this.asm = JSC$stmt_if_asm;
  this.count_locals = JSC$stmt_if_count_locals;
}

function JSC$stmt_if_asm ()
{
  this.expr.asm ();

  var l1 = new JSC$ASM_label ();
  var l2 = new JSC$ASM_label ();

  if (JSC$optimize_type && this.expr.lang_type
      && this.expr.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 then branch. */
  this.stmt1.asm ();
  new JSC$ASM_jmp (this.linenum, l2).link ();

  /* Code for the else branch. */
  l1.link ();
  if (this.stmt2 != null)
    this.stmt2.asm ();

  /* Done label. */
  l2.link ();
}


function JSC$stmt_if_count_locals (recursive)
{
  var lcount;

  if (!recursive)
    {
      lcount = 0;
      if (this.stmt1.stype == JSC$STMT_VARIABLE)
	lcount += this.stmt1.list.length;

      if (this.stmt2 != null && this.stmt2.stype == JSC$STMT_VARIABLE)
	lcount += this.stmt2.list.length;
    }
  else
    {
      lcount = this.stmt1.count_locals (true);

      if (this.stmt2)
	{
	  var c = this.stmt2.count_locals (true);
	  if (c > lcount)
	    lcount = c;
	}
    }

  return lcount;
}


/* Do...While. */

function JSC$stmt_do_while (ln, expr, stmt)
{
  this.stype = JSC$STMT_DO_WHILE;
  this.linenum = ln;
  this.expr = expr;
  this.stmt = stmt;
  this.asm = JSC$stmt_do_while_asm;
  this.count_locals = JSC$stmt_do_while_count_locals;
}

function JSC$stmt_do_while_asm ()
{
  var l1 = new JSC$ASM_label ();
  var l2 = new JSC$ASM_label ();
  var l3 = new JSC$ASM_label ();

  /* Loop label. */
  l1.link ();

  /* Body. */
  JSC$cont_break.push (l3, l2, false, null);
  this.stmt.asm ();
  JSC$cont_break.pop ();

  /* Condition & continue. */
  l2.link ();
  this.expr.asm ();
  if (JSC$optimize_type && this.expr.lang_type
      && this.expr.lang_type == JSC$JS_BOOLEAN)
    new JSC$ASM_iftrue_b (this.linenum, l1).link ();
  else
    new JSC$ASM_iftrue (this.linenum, l1).link ();

  /* Break label. */
  l3.link ();
}

function JSC$stmt_do_while_count_locals (recursive)
{
  if (!recursive)
    {
      if (this.stmt.stype == JSC$STMT_VARIABLE)
	return this.stmt.list.length;

      return 0;
    }
  else
    return this.stmt.count_locals (true);
}

/* While. */

function JSC$stmt_while (ln, expr, stmt)
{
  this.stype = JSC$STMT_WHILE;
  this.linenum = ln;
  this.expr = expr;
  this.stmt = stmt;
  this.asm = JSC$stmt_while_asm;
  this.count_locals = JSC$stmt_while_count_locals;
}

function JSC$stmt_while_asm ()
{
  var l1 = new JSC$ASM_label ();
  var l2 = new JSC$ASM_label ();

  /* Loop label. */
  l1.link ();

  /* Condition. */
  this.expr.asm ();
  if (JSC$optimize_type && this.expr.lang_type
      && this.expr.lang_type == JSC$JS_BOOLEAN)
    new JSC$ASM_iffalse_b (this.linenum, l2).link ();
  else
    new JSC$ASM_iffalse (this.linenum, l2).link ();

  /* Body. */
  JSC$cont_break.push (l2, l1, false, null);
  this.stmt.asm ();
  JSC$cont_break.pop ();

  /* Goto loop. */
  new JSC$ASM_jmp (this.linenum, l1).link ();

  /* Break label. */
  l2.link ();
}


function JSC$stmt_while_count_locals (recursive)
{
  if (!recursive)
    {
      if (this.stmt.stype == JSC$STMT_VARIABLE)
	return this.stmt.list.length;

      return 0;
    }
  else
    return this.stmt.count_locals (true);
}


/* For. */

function JSC$stmt_for (ln, vars, e1, e2, e3, stmt)
{
  this.stype = JSC$STMT_FOR;
  this.linenum = ln;
  this.vars = vars;
  this.expr1 = e1;
  this.expr2 = e2;
  this.expr3 = e3;
  this.stmt = stmt;
  this.asm = JSC$stmt_for_asm;
  this.count_locals = JSC$stmt_for_count_locals;
}

function JSC$stmt_for_asm ()
{
  /* Code for the init. */
  if (this.vars)
    {
      /* We have our own variable scope. */
      JSC$ns.push_frame ();

      var i;
      for (i = 0; i < this.vars.length; i++)
	{
	  var decl = this.vars[i];

	  JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL,
				JSC$ns.alloc_local (), this.linenum);

	  /* Possible init. */
	  if (decl.expr)
	    {
	      decl.expr.asm ();

	      var r = JSC$ns.lookup_symbol (decl.id);
	      if (r == null || r.scope != JSC$SCOPE_LOCAL)
		error (JSC$filename + ":" + this.liennum.toString ()
		       + ": internal compiler error in local variable "
		       + "declaration in for statement");

	      new JSC$ASM_store_local (this.linenum, r.value).link ();
	    }
	}
    }
  else if (this.expr1 != null)
    {
      this.expr1.asm ();
      new JSC$ASM_pop (this.linenum).link ();
    }

  var l1 = new JSC$ASM_label ();
  var l2 = new JSC$ASM_label ();
  var l3 = new JSC$ASM_label ();

  /* Loop label. */
  l1.link ();

  /* Condition. */
  var type_op = false;
  if (this.expr2 != null)
    {
      this.expr2.asm ();
      if (JSC$optimize_type && this.expr2.lang_type
	  && this.expr2.lang_type == JSC$JS_BOOLEAN)
	type_op = true;
    }
  else
    {
      new JSC$ASM_const_true (this.linenum).link ();
      type_op = JSC$optimize_type;
    }
  if (type_op)
    new JSC$ASM_iffalse_b (this.linenum, l3).link ();
  else
    new JSC$ASM_iffalse (this.linenum, l3).link ();

  JSC$cont_break.push (l3, l2, false, null);
  /* Body. */
  this.stmt.asm ();
  JSC$cont_break.pop ();

  /* Continue label. */
  l2.link ();

  /* Increment. */
  if (this.expr3 != null)
    {
      this.expr3.asm ();
      new JSC$ASM_pop (this.linenum).link ();
    }

  /* Goto loop. */
  new JSC$ASM_jmp (this.linenum, l1).link ();

  /* Break label. */
  l3.link ();

  if (this.vars)
    /* Pop the local variable scope. */
    JSC$ns.pop_frame ();
}


function JSC$stmt_for_count_locals (recursive)
{
  var count = 0;

  if (recursive)
    {
      if (this.vars)
	count += this.vars.length;

      count += this.stmt.count_locals (true);
    }
  else
    {
      if (this.stmt.stype == JSC$STMT_VARIABLE)
	count += this.stmt.list.length;
    }

  return count;
}


/* For...in. */

function JSC$stmt_for_in (ln, vars, e1, e2, stmt)
{
  this.stype = JSC$STMT_FOR_IN;
  this.linenum = ln;
  this.vars = vars;
  this.expr1 = e1;
  this.expr2 = e2;
  this.stmt = stmt;
  this.asm = JSC$stmt_for_in_asm;
  this.count_locals = JSC$stmt_for_in_count_locals;
}

function JSC$stmt_for_in_asm ()
{
  var local_id;

  if (this.vars)
    {
      /* We need our own variable scope here. */
      JSC$ns.push_frame ();

      var decl = this.vars[0];
      local_id = JSC$ns.alloc_local ();
      JSC$ns.define_symbol (decl.id, JSC$SCOPE_LOCAL, local_id, this.linenum);

      /* Possible init. */
      if (decl.expr)
	{
	  decl.expr.asm ();
	  new JSC$ASM_store_local (this.linenum, local_id).link ();
	}
    }

  /* Init the world. */
  this.expr2.asm ();
  new JSC$ASM_dup (this.linenum).link ();
  new JSC$ASM_const_i0 (this.linenum).link ();
  new JSC$ASM_swap (this.linenum).link ();
  new JSC$ASM_const_i0 (this.linenum).link ();

  var l_loop = new JSC$ASM_label ();
  var l_cont = new JSC$ASM_label ();
  var l_iffalse_b = new JSC$ASM_label ();
  var l_break = new JSC$ASM_label ();

  /* Loop label. */
  l_loop.link ();

  /* Fetch nth. */
  new JSC$ASM_nth (this.linenum).link ();
  new JSC$ASM_iffalse_b (this.linenum, l_iffalse_b).link ();

  /* Store value to variable. */
  if (this.vars)
    new JSC$ASM_store_local (this.linenum, local_id).link ();
  else
    JSC$asm_expr_lvalue_store_asm (this.expr1);

  /* Body. */
  JSC$cont_break.push (l_break, l_cont, false, null);
  this.stmt.asm ();
  JSC$cont_break.pop ();

  /* Continue label. */
  l_cont.link ();

  /* Increment. */
  new JSC$ASM_const_i1 (this.linenum).link ();
  new JSC$ASM_add (this.linenum).link ();
  new JSC$ASM_dup (this.linenum).link ();
  new JSC$ASM_roll (this.linenum, -3).link ();
  new JSC$ASM_dup (this.linenum).link ();
  new JSC$ASM_roll (this.linenum, 4).link ();
  new JSC$ASM_swap (this.linenum).link ();

  /* Goto loop. */
  new JSC$ASM_jmp (this.linenum, l_loop).link ();

  /* Out label. */
  l_iffalse_b.link ();

  new JSC$ASM_pop (this.linenum).link ();

  /* Break label. */
  l_break.link ();
  new JSC$ASM_pop_n (this.linenum, 2).link ();

  if (this.vars)
    /* Pop the variable scope. */
    JSC$ns.pop_frame ();
}

function JSC$stmt_for_in_count_locals (recursive)
{
  var count = 0;

  if (recursive)
    {
      if (this.vars)
	count++;

      count += this.stmt.count_locals (true);
    }
  else
    {
      if (this.stmt.stype == JSC$STMT_VARIABLE)
	count += this.stmt.list.length;

    }

  return count;
}


/* Variable. */

function JSC$stmt_variable (ln, list)
{
  this.stype = JSC$STMT_VARIABLE;
  this.linenum = ln;
  this.global_level = false;
  this.list = list;
  this.asm = JSC$stmt_variable_asm;
  this.count_locals = JSC$stmt_variable_count_locals;
}

function JSC$stmt_variable_asm ()
{
  var j, r;

  /* Define all local variables to our namespace. */
  for (j = 0; j < this.list.length; j++)
    {
      var i = this.list[j];

      if (!this.global_level)
	JSC$ns.define_symbol (i.id, JSC$SCOPE_LOCAL,
			      JSC$ns.alloc_local (), this.linenum);
      if (i.expr)
	{
	  i.expr.asm ();

	  if (this.global_level)
	    new JSC$ASM_store_global (this.linenum, i.id).link ();
	  else
	    {
	      r = JSC$ns.lookup_symbol (i.id);
	      if (r == null || r.scope != JSC$SCOPE_LOCAL)
		error (JSC$filename + ":" + this.linenum.toString()
		       + ": internal compiler error in local variable declaration");

	      new JSC$ASM_store_local (this.linenum, r.value).link ();
	    }
	}
    }
}

function JSC$stmt_variable_count_locals (recursive)
{
  if (!recursive)
    {
      if (this.global_level)
	/* We define these as global variables. */
	return 0;

      return this.list.length;
    }

  return 0;
}

function JSC$var_declaration (id, expr)
{
  this.id = id;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -