private dynamic Expression(Expr ast) { var lhs = ast.Left; var rhs = ast.Right; switch (ast.Token.TokenType) { case TokenType.Equals: if (lhs.AstType == AstTypes.ClassRef) { // a litle trickery here. create a copy of the class reference // with everytihng up to the second to last item. this gives you // the workign memory space that the very last item should sit in // then lets execute this as if we are asking for the memory space // and finally assign the very last symbol to the calculated memory // space we got var classRef = (lhs as ClassReference); var lastItem = classRef.Deferences.Last(); var fakeRef = new ClassReference(classRef.ClassInstance, classRef.Deferences.Take(classRef.Deferences.Count - 1) .ToList()); var space = GetValue(Exec(fakeRef)); Assign(lastItem, Exec(rhs), space); } else { ValueMemory itemSpace = Get(lhs); Assign(lhs, Exec(rhs), itemSpace != null ? itemSpace.Memory : null); } return null; case TokenType.Word: return Get(ast); case TokenType.Int: return Convert.ToInt32(ast.Token.TokenValue); case TokenType.Float: return Convert.ToDouble(ast.Token.TokenValue); case TokenType.QuotedString: return ast.Token.TokenValue; case TokenType.Nil: return TokenType.Nil; case TokenType.True: return true; case TokenType.False: return false; } if (TokenUtil.IsOperator(ast.Token)) { return ApplyOperation(ast); } return null; }
private dynamic ClassRefDo(ClassReference classReference) { var oldSpace = MemorySpaces.Current; var memorySpace = Get(classReference.ClassInstance).Value as MemorySpace; MemorySpaces.Current = memorySpace; try { if (classReference.Deferences.Count == 0) { return memorySpace; } foreach (var deref in classReference.Deferences) { // make sure that the last dereference knows how to pull // its arguments, which are from the original memory space and not // the relative class space. i.e. A.b.foo(x), x is loaded from the // space that contains A, not from the space of b. if (deref == classReference.Deferences.Last()) { deref.CallingMemory = oldSpace; } var newSpace = GetValue(Exec(deref)); if (deref == classReference.Deferences.Last()) { return newSpace; } MemorySpaces.Current = newSpace; } } finally { MemorySpaces.Current = oldSpace; } return null; }
public void Visit(ClassReference ast) { if (!ResolvingTypes) { return; } var declaredSymbol = Resolve(ast.ClassInstance); if (declaredSymbol == null) { throw new UndefinedElementException(string.Format("Class instance '{0}' does not exist in current scope", ast.ClassInstance.Token.TokenValue)); } var classScope = Resolve(declaredSymbol.Type.TypeName) as ClassSymbol; if (classScope == null) { classScope = Global.Resolve(declaredSymbol.Type.TypeName) as ClassSymbol; } var oldScope = Current; Current = classScope; foreach (var reference in ast.Deferences) { if (reference == ast.Deferences.Last()) { reference.CallingScope = oldScope; } reference.CurrentScope = Current; reference.IsPureDynamic = Current == null; reference.Visit(this); var field = Resolve(reference); if (field == null && !reference.IsPureDynamic) { throw new InvalidSyntax(String.Format("Class {0} has no field named {1}", declaredSymbol.Type.TypeName, reference.Token.TokenValue)); } if (field != null && field.Type.ExpressionType == ExpressionTypes.UserDefined) { Current = Global.Resolve(field.Type.TypeName) as ClassSymbol; } } Current = oldScope; ast.AstSymbolType = ast.Deferences.Last().AstSymbolType; if (ast.AstSymbolType.ExpressionType == ExpressionTypes.Method) { try { ast.AstSymbolType = (ast.AstSymbolType.Src as MethodDeclr).ReturnAst.AstSymbolType; } catch (Exception ex) { } } SetScope(ast); SetScope(ast.ClassInstance); }
public void Visit(ClassReference ast) { Exec(ast); }
public void Visit(ClassReference ast) { throw new NotImplementedException(); }