public int DefineVariable(string name, SymbolType type) { RegisterScopeIfNeeded(); try { int varIdx; if (type == SymbolType.Variable) { varIdx = _currentContext.DefineVariable(name).CodeIndex; } else { varIdx = _currentContext.DefineProperty(name).CodeIndex; } _predefinedVariables.Add(varIdx); return(varIdx); } catch { _currentContext.PopScope(); _scope = null; throw; } }
public void SymbolScope_Symbols_AreEmptyByDefault() { MockScope mockScope = new MockScope(); SymbolScope symbolScope = new SymbolScope(mockScope); Assert.Null(symbolScope.Symbols); // By default, Symbols is empty until Define is called }
public void SymbolScope_Description_ReturnsParentDesription() { MockScope mockScope = new MockScope(); SymbolScope symbolScope = new SymbolScope(mockScope); Assert.Equal(mockScope.Description, symbolScope.Description); }
void ProcessCallExpression_returns_returnType_when_ok() { var scope = new SymbolScope(); var name = new IdentifierToken("print", default); var funcSymbol = new FunctionSymbol(name.Value, DataType.Long, // return new DataType[] { DataType.Double, DataType.Double }); // need scope.AddSymbol(funcSymbol); var param1 = new Mock <ExpressionAst>().Object; var param2 = new Mock <ExpressionAst>().Object; var callParamList = new CallParamListAst(new[] { param1, param2 }); var ast = new CallExpressionAst( name, new OperatorToken(Operator.LeftParen, default), callParamList, new OperatorToken(Operator.RightParen, default)); var generator = ConfigureGenerator(scope, mock => { mock.Setup(p => p.ProcessExpression(param1)).Returns(DataType.Double); // provide mock.Setup(p => p.ProcessExpression(param2)).Returns(DataType.Double); // provide }); Assert.Equal(DataType.Long, generator.ProcessCallExpression(ast)); }
void ProcessCallExpression_throw_when_param_number_not_match() { var scope = new SymbolScope(); var name = new IdentifierToken("print", default); var funcSymbol = new FunctionSymbol(name.Value, DataType.Long, new DataType[] { DataType.Long }); scope.AddSymbol(funcSymbol); var param1 = new Mock <ExpressionAst>().Object; var param2 = new Mock <ExpressionAst>().Object; var callParamList = new CallParamListAst(new[] { param1, param2 }); var ast = new CallExpressionAst( name, new OperatorToken(Operator.LeftParen, default), callParamList, new OperatorToken(Operator.RightParen, default)); var generator = ConfigureGenerator(scope, mock => { mock.Setup(p => p.ProcessExpression(param1)).Returns(DataType.Long); mock.Setup(p => p.ProcessExpression(param2)).Returns(DataType.Long); }); Assert.Throws <SemanticException>(() => generator.ProcessCallExpression(ast)); }
public SymbolLeaf(SymbolNode parent, string name, SymbolType type, SymbolScope scope) { Parent = parent ?? throw new ArgumentNullException(nameof(parent)); Name = name ?? throw new ArgumentNullException(nameof(name)); Type = type; Scope = scope; }
private void RegisterScopeIfNeeded() { if (_scope == null) { _scope = new SymbolScope(); _currentContext.PushScope(_scope); } }
public SymbolMethodImpl(PortablePdbReader reader, int token, SymbolScope rootScope, SymbolSequencePoint[] sequencePoints, int kickoffMethod) { this.reader = reader; this.token = token; this.rootScope = rootScope; this.sequencePoints = sequencePoints; this.kickoffMethod = kickoffMethod; }
void ILocalSymbolTable.PushScope() { Debug.Assert(currentScope != null); SymbolScope parentScope = currentScope; currentScope = new SymbolScope(parentScope); parentScope.AddChildScope(currentScope); }
void ILocalSymbolTable.PushScope() { Debug.Assert(_currentScope != null); var parentScope = _currentScope; _currentScope = new SymbolScope(parentScope); parentScope.AddChildScope(_currentScope); }
public ModuleImage Compile(ICodeSource source) { try { return(CompileInternal(source)); } finally { _currentContext.PopScope(); _scope = null; } }
static IntermediateCodeGenerator ConfigureGenerator( SymbolScope symbolScope, Action <Mock <IntermediateCodeGenerator> > action) { var mock = new Mock <IntermediateCodeGenerator>(symbolScope); mock.CallBase = true; action(mock); return(mock.Object); }
public ScriptModuleHandle CreateModule(ICodeSource source) { try { return(Compile(source)); } finally { _currentContext.PopScope(); _scope = null; } }
public DbiScope(SymbolMethod method, SymbolScope parent, string name, uint offset, uint length) { this.method = method; this.parent = parent; Name = name; startOffset = (int)offset; endOffset = (int)(offset + length); childrenList = new List <SymbolScope>(); localsList = new List <SymbolVariable>(); namespacesList = new List <SymbolNamespace>(); }
public bool TryEnterNew(string scopeName, SymbolType type, SymbolScope scope) { if (!Current.Children.TryGetValue(scopeName, out var symbol)) { Current = Current.EnterNew(scopeName, type, scope); return(true); } else { return(false); } }
public Symbol Define(string identifier, SymbolScope scope) { var symbol = new Symbol { Index = Store.Where(item => item.Value.Scope != SymbolScope.Function).Count(), Name = identifier, Scope = scope }; Store[symbol.Name] = symbol; return(symbol); }
void Function_success_and_write_self_and_params_to_symbol_table() { var name = new IdentifierToken("SendRequest", default); var scope = new SymbolScope(); scope.AddSymbol(new VariableSymbol("lll3", false, false, DataType.Long)); var param1 = new FunctionParamAst(null, new IdentifierToken("length1", default), new OperatorToken(Operator.Colon, default), new IdentifierToken("int", default)); var paramList = new FunctionParamListAst(new FunctionParamAst[] { param1 }); var functionBlock = new Mock <BlockStatementAst>().Object; var ast = new FunctionAst( new KeywordToken(Keyword.Fn, default), name, new OperatorToken(Operator.LeftParen, default), paramList, new OperatorToken(Operator.RightParen, default), new OperatorToken(Operator.Arrow, default), returnType: new IdentifierToken("int", default), functionBlock ); var generator = ConfigureGenerator(scope, mock => { mock.Setup(p => p.ProcessBlockStatement(functionBlock, It.IsAny <bool>())).Returns(false); }); generator.ProcessFunction(ast); // Assert // self Assert.True(scope.FindSymbolShallow(ast.Name.Value, out Symbol symx)); var funcSym = Assert.IsType <FunctionSymbol>(symx); Assert.Equal(DataType.Long, funcSym.ReturnType); Assert.Equal(DataType.Long, funcSym.ParamTypes.Single()); // params Assert.True(scope.FindSymbolShallow(name.Value, out Symbol s0)); scope = (s0 as FunctionSymbol).BodyBlockScope; Assert.True(scope.FindSymbolShallow(param1.Name.Value, out Symbol sym1)); var var1 = Assert.IsType <VariableSymbol>(sym1); Assert.Equal(param1.IsConstant, var1.IsConstant); Assert.False(var1.IsGlobal); Assert.Equal(DataType.Long, var1.Type); Assert.Equal(param1.Name.Value, var1.Name); }
void ProcessContinueStatement_throws_when_not_in_while() { var scope = new SymbolScope(); var ast = new ContinueStatementAst( new KeywordToken(Keyword.Continue, default), new OperatorToken(Operator.Semicolon, default)); var generator = ConfigureGenerator(scope, mock => { }); Assert.Throws <SemanticException>(() => generator.ProcessContinueStatement(ast)); }
void ProcessIdentExpression_throws_when_symbol_not_found() { var scope = new SymbolScope(); var name = new IdentifierToken("aCounter", default); var ast = new IdentExpressionAst(name); var generator = ConfigureGenerator(scope, mock => { }); Assert.Throws <SemanticException>(() => generator.ProcessIdentExpression(ast)); }
private SymbolType(char symbolTypeChar, SymbolScope symbolScope) { var symDesc = SymbolTypeDescription.SymbolTypes.SingleOrDefault(s => Char.ToLowerInvariant(s.SymbolType) == Char.ToLowerInvariant(symbolTypeChar)); if (symDesc != null) { SymbolTypeDescription = symDesc; } else { throw new InvalidDataException($"The symbol type {symbolTypeChar} is undefined"); } SymbolScope = symbolScope; }
void ProcessReturnStatement_throws_when_not_in_function() { var scope = new SymbolScope(); var returnExpr = new Mock <ExpressionAst>().Object; var ast = new ReturnStatementAst( new KeywordToken(Keyword.Return, default), returnExpr, new OperatorToken(Operator.Semicolon, default)); var generator = ConfigureGenerator(scope, mock => { }); Assert.Throws <SemanticException>(() => generator.ProcessReturnStatement(ast)); }
void ProcessLetDeclaration_registers_to_function_and_writes_function_bucket_when_in_func() { // Arrange var expr = new Mock <ExpressionAst>().Object; var ast = new LetDeclarationStatementAst( new KeywordToken(Keyword.Let, default), new IdentifierToken("x", default), new OperatorToken(Operator.Colon, default), new IdentifierToken("int", default), new OperatorToken(Operator.Assign, default), expr, new OperatorToken(Operator.Semicolon, default)); var function = new FunctionSymbol("print", DataType.Long, new DataType[0]); var scope = new SymbolScope(); var generator = ConfigureGenerator(scope, mock => { mock.Setup(p => p.ProcessExpression(expr)).Returns(DataType.Long); }); generator.GlobalBuilder.RegisterFunction(function); generator.EnterFunctionDefination(function); var ins1 = new object[] { "push", 111L }; generator.ExpressionBucket.Add(ins1);// this is initial value expr // Act generator.ProcessLetDeclarationStatement(ast); // Assert Assert.Empty(generator.ExpressionBucket.Pop()); Assert.True(scope.FindSymbolShallow("x", out Symbol symbol)); var varx = Assert.IsType <VariableSymbol>(symbol); Assert.Contains(varx, function.Builder.LocalVariables); Assert.NotNull(varx.LocalLocation); Assert.Equal(0, varx.LocalLocation.Id); Assert.False(varx.LocalLocation.IsArgument); var funcBody = function.Builder.Bucket.InstructionList; Assert.Equal(3, funcBody.Count); AssertJsonEqual(new object[] { "loca", 0 }, funcBody[0].Parts); AssertJsonEqual(ins1, funcBody[1].Parts); AssertJsonEqual(new object[] { "store.64" }, funcBody[2].Parts); }
public SymbolImplementation BuildField(FieldSymbol fieldSymbol) { rootScope = new SymbolScope((ISymbolTable)fieldSymbol.Parent); currentScope = rootScope; Expression initializerExpression = null; FieldDeclarationNode fieldDeclarationNode = (FieldDeclarationNode)fieldSymbol.ParseContext; Debug.Assert(fieldDeclarationNode != null); VariableInitializerNode initializerNode = (VariableInitializerNode)fieldDeclarationNode.Initializers[0]; if (initializerNode.Value != null) { ExpressionBuilder expressionBuilder = new ExpressionBuilder(this, fieldSymbol, errorHandler, options); initializerExpression = expressionBuilder.BuildExpression(initializerNode.Value); if (initializerExpression is MemberExpression) { initializerExpression = expressionBuilder.TransformMemberExpression((MemberExpression)initializerExpression); } } else { TypeSymbol fieldType = fieldSymbol.AssociatedType; SymbolSet symbolSet = fieldSymbol.SymbolSet; if (GetDefaultValue(fieldType, symbolSet) is object defaultValue) { initializerExpression = new LiteralExpression(symbolSet.ResolveIntrinsicType(IntrinsicType.Object), defaultValue); fieldSymbol.SetImplementationState(hasInitializer: true); } } if (initializerExpression != null) { List <Statement> statements = new List <Statement>(); statements.Add(new ExpressionStatement(initializerExpression, /* isFragment */ true)); return(new SymbolImplementation(statements, null, "this")); } return(null); }
/// <summary> /// Adds a new <see cref="SymbolLeaf"/> to the current scope. /// </summary> /// <param name="name">The name of the leaf.</param> /// <param name="type">The type of the leaf</param> /// <param name="scope">The scope of the leaf.</param> /// <returns></returns> public bool AddLeaf(string name, SymbolType type, SymbolScope scope) { if (!Defined(name, out var overwrite)) { if (type == SymbolType.Variable) { Current.Children.Add(name, new VariableLeaf(Current, name, scope)); } else { Current.Children.Add(name, new SymbolLeaf(Current, name, type, scope)); } return(true); } return(false); }
void ProcessWhileStatement_throws_when_condition_not_bool_double_int() { var scope = new SymbolScope(); var condition = new Mock <ExpressionAst>().Object; var ast = new WhileStatementAst( new KeywordToken(Keyword.While, default), condition, new Mock <BlockStatementAst>().Object); var generator = ConfigureGenerator(scope, mock => { mock.Setup(p => p.ProcessExpression(condition)).Returns(DataType.String); }); Assert.Throws <SemanticException>(() => generator.ProcessWhileStatement(ast)); }
void ProcessCallExpression_throws_when_symbol_not_exist()// TODO: 考虑系统调用 { var scope = new SymbolScope(); var name = new IdentifierToken("print", default); var ast = new CallExpressionAst( name, new OperatorToken(Operator.LeftParen, default), null, new OperatorToken(Operator.RightParen, default)); var generator = ConfigureGenerator(scope, mock => { }); Assert.Throws <SemanticException>(() => generator.ProcessCallExpression(ast)); }
void ProcessIdentExpression_throws_when_symbol_not_var_or_const() { var scope = new SymbolScope(); var funcSymbol = new FunctionSymbol("aCounter", DataType.Void, new DataType[0]); scope.AddSymbol(funcSymbol); var name = new IdentifierToken("aCounter", default); var ast = new IdentExpressionAst(name); var generator = ConfigureGenerator(scope, mock => { }); Assert.Throws <SemanticException>(() => generator.ProcessIdentExpression(ast)); }
public void SymbolScope_Define_AddsSymbolToSymbols() { MockScope mockScope = new MockScope(); SymbolScope symbolScope = new SymbolScope(mockScope); SymbolKindEnum kind = SymbolKindEnum.FUNCTION; string name = "the-name"; ExprOp exprOp = new ExprOp(OpKindEnum.CONSTANTS); symbolScope.Define(kind, name, exprOp); Assert.Equal(1, symbolScope.Symbols.Count); Assert.Equal(kind, symbolScope.Symbols.First().Key.Kind); Assert.Equal(name, symbolScope.Symbols.First().Key.Name); Assert.Equal(exprOp, symbolScope.Symbols.First().Key.Definition); Assert.Equal(exprOp, symbolScope.Symbols[symbolScope.Symbols.First().Key]); }
void ProcessIdentExpression_returns_type_when_constvar_ok() { var scope = new SymbolScope(); var funcSymbol = new VariableSymbol("aCounter", true, false, DataType.Long); scope.AddSymbol(funcSymbol); var name = new IdentifierToken("aCounter", default); var ast = new IdentExpressionAst(name); var generator = ConfigureGenerator(scope, mock => { }); Assert.Equal(DataType.Long, generator.ProcessIdentExpression(ast)); }
private void RegisterSymbolScope(IRuntimeContextInstance provider, bool asDynamicScope) { var scope = new SymbolScope(); scope.IsDynamicScope = asDynamicScope; _symbolScopes.PushScope(scope); foreach (var item in provider.GetProperties()) { _symbolScopes.DefineVariable(item.Identifier); } foreach (var item in provider.GetMethods()) { _symbolScopes.DefineMethod(item); } }