public static object?EvalExpression(DogeNode expression, Dictionary <string, object?> locals) { switch (expression) { case DogeBinaryExpression binaryExpression: var lhs = EvalExpression(binaryExpression.LeftHandSide, locals); Func <object?> rhs = () => EvalExpression(binaryExpression.RightHandSide, locals); switch (binaryExpression.BinaryOperator) { case DogeBinaryOperator.Add: return(lhs switch { double d => (object)(d + (double)rhs() !), float d => d + (float)rhs() !, long d => d + (long)rhs() !, int d => d + (int)rhs() !, short d => d + (short)rhs() !, byte d => d + (byte)rhs() !, string d => d + rhs() !.ToString(), _ => throw new ArgumentOutOfRangeException() }); case DogeBinaryOperator.Subtract: return(lhs switch { double d => (object)(d - (double)rhs() !), float d => d - (float)rhs() !, long d => d - (long)rhs() !, int d => d - (int)rhs() !, short d => d - (short)rhs() !, byte d => d - (byte)rhs() !, _ => throw new ArgumentOutOfRangeException() });
public DogeWhileStatement(DogeNode condition, DogeNode body, DogeFile file, Range <int> range) : base(file, range) { condition.Parent = this; Condition = condition; body.Parent = this; Body = body; }
public DogeUnaryExpression(DogeUnaryOperator unaryOperator, DogeNode internalExpression, DogeFile file, Range <int> tokenRange) : base(file, tokenRange) { UnaryOperator = unaryOperator; internalExpression.Parent = this; InternalExpression = internalExpression; }
public DogeBinaryExpression(DogeBinaryOperator binaryOperator, DogeNode leftHandSide, DogeNode rightHandSide, DogeFile file) : base(file, Range<int>.ConcatOrdered(leftHandSide.TokenRange, rightHandSide.TokenRange)) { BinaryOperator = binaryOperator; leftHandSide.Parent = this; LeftHandSide = leftHandSide; rightHandSide.Parent = this; RightHandSide = rightHandSide; }
public static object?EvalStatement(DogeNode statement, Dictionary <string, object?> locals) { switch (statement) { case DogeStatementList statementList: var localsInner = locals.ToDictionary(x => x.Key, x => x.Value); foreach (var subStatement in statementList.Statements) { EvalStatement(subStatement, localsInner); } break; case DogeWhileStatement whileStatement: while ((bool)EvalExpression(whileStatement.Condition, locals) !) { EvalStatement(whileStatement.Body, locals); } break; case DogeIfStatement ifStatement: if ((bool)EvalExpression(ifStatement.Condition, locals) !) { EvalStatement(ifStatement.Body, locals); } else { if (ifStatement.Else != null) { EvalStatement(ifStatement.Else, locals); } } break; case DogeLocalDeclarationStatement localDeclarationStatement: locals.Add( localDeclarationStatement.Name, localDeclarationStatement.Value != null ? EvalExpression(localDeclarationStatement.Value, locals) : null); break; case DogeExpressionStatement expressionStatement: EvalExpression(expressionStatement.Expression, locals); break; case DogeReturnStatement returnStatement: return(returnStatement.Value == null ? null : EvalExpression(returnStatement.Value, locals)); } return(null); }
public DogeFieldDefinition(DogeIdentifier name, DogeMemberAccessExpression type, DogeAccessibilityModifier modifier, bool isReadonly, DogeNode initialValue, DogeFile file, Range <int> tokenRange) : this( name, type, modifier, isReadonly, file, tokenRange) { initialValue.Parent = this; InitialValue = initialValue; }
public DogeIfStatement( DogeNode condition, DogeNode body, DogeNode? @else, DogeFile file, Range <int> tokenRange) : base(file, tokenRange) { condition.Parent = this; Condition = condition; body.Parent = this; Body = body; if (@else != null) { @else.Parent = this; } Else = @else; }
public DogeExpressionStatement(DogeNode expression) : base(expression.File, expression.TokenRange) { expression.Parent = this; Expression = expression; }
private DogeNode ResolveExpressionSymbols(DogeNode node, DogeSymbolTable symbolTable, IDictionary <string, DogeLocalDeclarationStatement> locals, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { void resolveSymbols(ref DogeNode node) => node = ResolveExpressionSymbols( node, symbolTable, locals, usingDefinitions, fullName); switch (node) { case DogeBinaryExpression binaryExpression: resolveSymbols(ref binaryExpression.LeftHandSide); resolveSymbols(ref binaryExpression.RightHandSide); break; case DogeUnaryExpression unaryExpression: resolveSymbols(ref unaryExpression.InternalExpression); break; case DogeListExpression <DogeNode> listExpression: var nodeElements = listExpression.Elements.ToArray(); for (int i = 0; i < nodeElements.Length; i++) { resolveSymbols(ref nodeElements[i]); } break; case DogeListExpression <DogeMemberAccessorExpression> listExpression: DogeSymbolTable lastType = symbolTable.GetSymbolTable(fullName); int startSkip = 1; List <DogeMemberAccessorExpression> accumulator = new List <DogeMemberAccessorExpression>(); if (!lastType.TryGetSymbol(listExpression.Elements.First().Name, out _)) { for (; startSkip <= listExpression.Elements.Count; startSkip++) { if (symbolTable.TryResolveSymbol( listExpression.Elements.Select(x => x.Name).Take(startSkip).ToList(), s => s.SymbolType == DogeSymbolType.Field || s.SymbolType == DogeSymbolType.Local || s.SymbolType == DogeSymbolType.Property || s.SymbolType == DogeSymbolType.Method, s => s == DogeSymbolTableType.Type, usingDefinitions, out var lastTypeSymbol)) { DogeMemberAccessorExpression last = listExpression.Elements.ElementAt(startSkip - 1); if (lastTypeSymbol !.SymbolType != DogeSymbolType.Method) { if (last is DogeMethodCallStatement) { throw new InvalidCastException(); } lastType = symbolTable.GetSymbolTable(lastTypeSymbol.FullName); Range <int> range = new Range <int>(listExpression.Elements.First().TokenRange.First, last.TokenRange.Last); accumulator.Add( new DogeMemberAccessorExpression( new DogeIdentifier( new DogeToken( DogeTokenType.Identifier, string.Join('.', lastTypeSymbol.FullName), range.First), DogeFile.Console), false, false, listExpression.File, range) { NameSymbol = new DogeSymbolNode(lastTypeSymbol !, listExpression.File, range) }); }
private void ResolveSymbols(DogeNode node, DogeSymbolTable symbolTable, IDictionary <string, DogeLocalDeclarationStatement> locals, ICollection <IList <string> > usingDefinitions, IList <string> fullName) { void resolveSymbols(DogeNode node) => ResolveSymbols( node, symbolTable, locals, usingDefinitions, fullName); switch (node) { case DogeStatementList statementList: var localsOuter = locals.ToDictionary(x => x.Key, x => x.Value); foreach (var statement in statementList.Statements) { resolveSymbols(statement); } locals = localsOuter; break; case DogeWhileStatement whileStatement: resolveSymbols(whileStatement.Condition); resolveSymbols(whileStatement.Body); break; case DogeIfStatement ifStatement: resolveSymbols(ifStatement.Condition); resolveSymbols(ifStatement.Body); if (ifStatement.Else != null) { resolveSymbols(ifStatement.Else); } break; case DogeLocalDeclarationStatement localDeclarationStatement: if (localDeclarationStatement.Value != null) { resolveSymbols(localDeclarationStatement.Value); } localDeclarationStatement.TypeSymbol = new DogeSymbolNode(symbolTable.ResolveSymbol( localDeclarationStatement.Type, s => s.SymbolType == DogeSymbolType.Type, s => s == DogeSymbolTableType.Namespace || s == DogeSymbolTableType.Type, usingDefinitions), localDeclarationStatement.File, localDeclarationStatement.TokenRange); locals.Add(localDeclarationStatement.Name, localDeclarationStatement); break; case DogeExpressionStatement expressionStatement: expressionStatement.Expression = ResolveExpressionSymbols( expressionStatement.Expression, symbolTable, locals, usingDefinitions, fullName); break; } }