StatementInterpreter.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using System.Linq;
  2. using Jint.Native;
  3. using Jint.Parser.Ast;
  4. using Jint.Runtime.Environments;
  5. namespace Jint.Runtime
  6. {
  7. public class StatementInterpreter
  8. {
  9. private readonly Engine _engine;
  10. public StatementInterpreter(Engine engine)
  11. {
  12. _engine = engine;
  13. }
  14. private void ExecuteStatement(Statement statement)
  15. {
  16. _engine.ExecuteStatement(statement);
  17. }
  18. public void ExecuteProgram(Program program)
  19. {
  20. foreach (var statement in program.Body)
  21. {
  22. ExecuteStatement(statement);
  23. }
  24. }
  25. public void ExecuteVariableDeclaration(VariableDeclaration statement)
  26. {
  27. var env = _engine.CurrentExecutionContext.VariableEnvironment.Record;
  28. foreach (var declaration in statement.Declarations)
  29. {
  30. dynamic value = Undefined.Instance;
  31. if (declaration.Init != null)
  32. {
  33. value = _engine.EvaluateExpression(declaration.Init);
  34. }
  35. var dn = declaration.Id.Name;
  36. var varAlreadyDeclared = env.HasBinding(dn);
  37. if (!varAlreadyDeclared)
  38. {
  39. env.CreateMutableBinding(declaration.Id.Name, false);
  40. env.SetMutableBinding(declaration.Id.Name, value, false);
  41. }
  42. }
  43. }
  44. public void ExecuteDoWhileStatement(DoWhileStatement doWhileStatement)
  45. {
  46. bool test;
  47. do
  48. {
  49. ExecuteStatement(doWhileStatement.Body);
  50. test = _engine.EvaluateExpression(doWhileStatement.Test);
  51. } while (test);
  52. }
  53. public void ExecuteContinueStatement(ContinueStatement continueStatement)
  54. {
  55. _engine.CurrentExecutionContext.Continue = continueStatement;
  56. }
  57. public void ExecuteBreakStatement(BreakStatement breakStatement)
  58. {
  59. _engine.CurrentExecutionContext.Break = breakStatement;
  60. }
  61. public void ExecuteBlockStatement(BlockStatement blockStatement)
  62. {
  63. foreach (var statement in blockStatement.Body)
  64. {
  65. ExecuteStatement(statement);
  66. // return has been called, stop execution
  67. if (!_engine.CurrentExecutionContext.Return.Equals(Undefined.Instance))
  68. {
  69. return;
  70. }
  71. }
  72. }
  73. public void ExecuteEmptyStatement(EmptyStatement emptyStatement)
  74. {
  75. }
  76. public void ExecuteExpressionStatement(ExpressionStatement expressionStatement)
  77. {
  78. _engine.EvaluateExpression(expressionStatement.Expression);
  79. }
  80. public void ExecuteReturnStatement(ReturnStatement statement)
  81. {
  82. _engine.CurrentExecutionContext.Return = _engine.EvaluateExpression(statement.Argument);
  83. }
  84. public void ExecuteFunctionDeclaration(FunctionDeclaration functionDeclaration)
  85. {
  86. // create function objects
  87. http://www.ecma-international.org/ecma-262/5.1/#sec-13.2
  88. var identifier = functionDeclaration.Id.Name;
  89. // todo: should be declared in the current context
  90. _engine.Global.Set(
  91. identifier,
  92. new ScriptFunctionInstance(
  93. _engine,
  94. functionDeclaration.Body,
  95. identifier,
  96. functionDeclaration.Parameters.ToArray(),
  97. _engine.Function.Prototype,
  98. _engine.Object.Construct(new dynamic[0]),
  99. LexicalEnvironment.NewDeclarativeEnvironment(_engine.CurrentExecutionContext.LexicalEnvironment)
  100. )
  101. );
  102. }
  103. public void ExecuteIfStatement(IfStatement ifStatement)
  104. {
  105. var test = _engine.EvaluateExpression(ifStatement.Test);
  106. if (test)
  107. {
  108. _engine.ExecuteStatement(ifStatement.Consequent);
  109. }
  110. else if (ifStatement.Alternate != null)
  111. {
  112. _engine.ExecuteStatement(ifStatement.Alternate);
  113. }
  114. }
  115. public void ExecuteWhileStatement(WhileStatement whileStatement)
  116. {
  117. bool test = _engine.EvaluateExpression(whileStatement.Test);
  118. while(test)
  119. {
  120. ExecuteStatement(whileStatement.Body);
  121. test = _engine.EvaluateExpression(whileStatement.Test);
  122. }
  123. }
  124. public void ExecuteDebuggerStatement(DebuggerStatement debuggerStatement)
  125. {
  126. throw new System.NotImplementedException();
  127. }
  128. public void ExecuteForStatement(ForStatement forStatement)
  129. {
  130. if (forStatement.Init.Type == SyntaxNodes.VariableDeclaration)
  131. {
  132. _engine.ExecuteStatement(forStatement.Init.As<Statement>());
  133. }
  134. else
  135. {
  136. _engine.EvaluateExpression(forStatement.Init.As<Expression>());
  137. }
  138. while (_engine.EvaluateExpression(forStatement.Test))
  139. {
  140. _engine.ExecuteStatement(forStatement.Body);
  141. _engine.EvaluateExpression(forStatement.Update);
  142. }
  143. }
  144. }
  145. }