StatementInterpreter.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. functionDeclaration.Body,
  94. identifier,
  95. functionDeclaration.Parameters.ToArray(),
  96. _engine.Function.Prototype,
  97. _engine.Object.Construct(new dynamic[0]),
  98. LexicalEnvironment.NewDeclarativeEnvironment(_engine.CurrentExecutionContext.LexicalEnvironment)
  99. )
  100. );
  101. }
  102. public void ExecuteIfStatement(IfStatement ifStatement)
  103. {
  104. var test = _engine.EvaluateExpression(ifStatement.Test);
  105. if (test)
  106. {
  107. _engine.ExecuteStatement(ifStatement.Consequent);
  108. }
  109. else if (ifStatement.Alternate != null)
  110. {
  111. _engine.ExecuteStatement(ifStatement.Alternate);
  112. }
  113. }
  114. public void ExecuteWhileStatement(WhileStatement whileStatement)
  115. {
  116. bool test = _engine.EvaluateExpression(whileStatement.Test);
  117. while(test)
  118. {
  119. ExecuteStatement(whileStatement.Body);
  120. test = _engine.EvaluateExpression(whileStatement.Test);
  121. }
  122. }
  123. public void ExecuteDebuggerStatement(DebuggerStatement debuggerStatement)
  124. {
  125. throw new System.NotImplementedException();
  126. }
  127. public void ExecuteForStatement(ForStatement forStatement)
  128. {
  129. if (forStatement.Init.Type == SyntaxNodes.VariableDeclaration)
  130. {
  131. _engine.ExecuteStatement(forStatement.Init.As<Statement>());
  132. }
  133. else
  134. {
  135. _engine.EvaluateExpression(forStatement.Init.As<Expression>());
  136. }
  137. while (_engine.EvaluateExpression(forStatement.Test))
  138. {
  139. _engine.ExecuteStatement(forStatement.Body);
  140. _engine.EvaluateExpression(forStatement.Update);
  141. }
  142. }
  143. }
  144. }