private static Object.Object EvalHashLiteral(HashLiteral node, Object.Environment env) { var pairs = new Dictionary <HashKey, HashPair>(); foreach (KeyValuePair <Expression, Expression> pair in node.Pairs) { Object.Object key = Eval(pair.Key, env); if (IsError(key)) { return(key); } var hashKey = key as IHash; if (hashKey == null) { return(new Error { Message = $"unusable as hash key: {key.Type()}" }); } var value = Eval(pair.Value, env); if (IsError(value)) { return(value); } var hashed = hashKey.HashKey(); pairs.Add(hashed, new HashPair { Key = key, Value = value }); } return(new Hash { Pairs = pairs }); }
private IExpression ParseHashLiteral() { var hash = new HashLiteral { Token = currentToken }; hash.Pairs = new Dictionary <IExpression, IExpression>(); while (!PeekTokenIs(TokenType.RBrace)) { NextToken(); var key = ParseExpression(Precedence.Lowest); if (!ExpectPeek(TokenType.Colon)) { return(null); } NextToken(); var value = ParseExpression(Precedence.Lowest); hash.Pairs.Add(key, value); if (!PeekTokenIs(TokenType.RBrace) && !ExpectPeek(TokenType.Comma)) { return(null); } } if (!ExpectPeek(TokenType.RBrace)) { return(null); } return(hash); }
private Ast.Expression ParseHashLiteral() { var hash = new HashLiteral { Token = this._curToken }; hash.Pairs = new Dictionary <Expression, Expression>(); while (!this.PeekTokenIs(TokenType.RBRACE)) { this.NextToken(); var key = this.ParseExpression(Precedence.LOWEST); if (!this.ExpectPeek(TokenType.COLON)) { throw new ParserException($"want {TokenType.COLON} but got {this._peekToken}"); } this.NextToken(); var value = this.ParseExpression(Precedence.LOWEST); hash.Pairs[key] = value; if (!this.PeekTokenIs(TokenType.RBRACE) && !this.ExpectPeek(TokenType.COMMA)) { throw new ParserException($"want {TokenType.RBRACE} or {TokenType.COMMA} but got {this._peekToken}"); } } if (!this.ExpectPeek(TokenType.RBRACE)) { throw new ParserException($"want {TokenType.RBRACE} but got {this._peekToken}"); } return(hash); }
public void Parser_CanParseHashLiterals() { string input = @"{""one"":1, ""two"": 2, ""three"": 3}"; AST result = this.subject.ParseProgram(input); Assert.Empty(result.Errors); Assert.Equal(1, result.Program.Statements.Count); ExpressionStatement expr = this.AssertAndCast <ExpressionStatement>(result.Program.Statements[0]); HashLiteral hashExpr = this.AssertAndCast <HashLiteral>(expr.Expression); Assert.Equal(3, hashExpr.Pairs.Count); var expected = new Dictionary <string, string>() { { "one", "1" }, { "two", "2" }, { "three", "3" } }.ToImmutableDictionary(); var actual = ImmutableDictionary.CreateRange <string, string>( hashExpr.Pairs.Select(kv => new KeyValuePair <string, string>(kv.Key.StringValue, kv.Value.StringValue) ) ); }
private IExpression ParseHashLiteral() { var hash = new HashLiteral { Token = CurrentToken, Pairs = new Dictionary <IExpression, IExpression>() }; while (!PeekTokenIs(Token.Rbrace)) { NextToken(); var key = ParseExpression(Enums.Precedences.Lowest); if (!ExpectPeek(Token.Colon)) { return(null); } NextToken(); var value = ParseExpression(Enums.Precedences.Lowest); hash.Pairs.Add(key, value); if (!PeekTokenIs(Token.Rbrace) && !ExpectPeek(Token.Comma)) { return(null); } } return(!ExpectPeek(Token.Rbrace) ? null : hash); }
public void Parser_CanParseEmptyHashes() { string input = "{}"; AST result = this.subject.ParseProgram(input); Assert.Empty(result.Errors); Assert.Equal(1, result.Program.Statements.Count); ExpressionStatement expr = this.AssertAndCast <ExpressionStatement>(result.Program.Statements[0]); HashLiteral hashExpr = this.AssertAndCast <HashLiteral>(expr.Expression); Assert.Equal(0, hashExpr.Pairs.Count); }
private IExpression ParseHashLiteral() { var hash = new HashLiteral { Token = _currentToken, Pairs = new Dictionary <IExpression, IExpression>() }; while (!PeekTokenIs(TokenType.RBRACE)) { NextToken(); var key = ParseExpression(Precedences.LOWEST); if (!ExpectPeek(TokenType.COLON)) { return(null); } NextToken(); var value = ParseExpression(Precedences.LOWEST); hash.Pairs.Add(key, value); if (!PeekTokenIs(TokenType.RBRACE) && !ExpectPeek(TokenType.COMMA)) { return(null); } } if (!ExpectPeek(TokenType.RBRACE)) { return(null); } return(hash); }
private static MonkeyObject evalHashLiteral(HashLiteral hl, Object.Environment environment) { var pairs = new Dictionary <HashKey, HashPair>(); foreach (var(keyNode, valueNode) in hl.Pairs) { var key = Eval(keyNode, environment); if (key?.Type == MonkeyObjectType.ERROR) { return(key); } if (!(key is Hashable)) { return(new MonkeyError { Message = $"unusable as hash key: {key.Type}" }); } var hashKey = key as Hashable; var value = Eval(valueNode, environment); if (value?.Type == MonkeyObjectType.ERROR) { return(value); } var hashed = hashKey.HashKey(); pairs.Add(hashed, new HashPair { Key = key, Value = value }); } return(new MonkeyHash { Pairs = pairs }); }
public void Modify_Replaces_Nodes() { var token1 = new Token(Token.Int, "1"); var token2 = new Token(Token.Int, "2"); Func <IExpression> one = () => new IntegerLiteral(null) { Value = 1 }; Func <IExpression> two = () => new IntegerLiteral(null) { Value = 2 }; Func <INode, INode> turnOneIntoTwo = (node) => { if (node is IntegerLiteral integer) { if (integer.Value != 1) { return(node); } integer.Value = 2; return(integer); } return(node); }; var tests = new Dictionary <INode, INode> { { one(), two() }, { new ProgramNode() { Statements = new List <IStatement> { new ExpressionStatement(null) { Expression = one() } } }, new ProgramNode() { Statements = new List <IStatement> { new ExpressionStatement(null) { Expression = two() } } } }, { new InfixExpression(null) { Left = one(), Operator = "+", Right = two() }, new InfixExpression(null) { Left = two(), Operator = "+", Right = two() } }, { new InfixExpression(null) { Left = two(), Operator = "+", Right = one() }, new InfixExpression(null) { Left = two(), Operator = "+", Right = two() } }, { new PrefixExpression(null) { Operator = "-", Right = one() }, new PrefixExpression(null) { Operator = "-", Right = two() } }, { new IndexExpression(null) { Left = one(), Index = one() }, new IndexExpression(null) { Left = two(), Index = two() } }, { new IfExpression(null) { Condition = one(), Consequence = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = one() } } }, Alternative = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = one() } } } }, new IfExpression(null) { Condition = two(), Consequence = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = two() } } }, Alternative = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = two() } } } } }, { new ForExpression(null) { Body = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = one() } } }, Collection = new ArrayLiteral(null) { Elements = new List <IExpression>() { one() } }, KeyIdentifier = new Identifier(null) { Value = "item" } }, new ForExpression(null) { Body = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = two() } } }, Collection = new ArrayLiteral(null) { Elements = new List <IExpression>() { two() } }, KeyIdentifier = new Identifier(null) { Value = "item" } } }, { new ReturnStatement(null) { ReturnValue = one() }, new ReturnStatement(null) { ReturnValue = two() } }, { new LetStatement(null) { Value = one() }, new LetStatement(null) { Value = two() } }, { new FunctionLiteral(null) { Parameters = new List <Identifier>(), Body = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = one() } } } }, new FunctionLiteral(null) { Parameters = new List <Identifier>(), Body = new BlockStatement(null) { Statements = new List <IStatement>() { new ExpressionStatement(null) { Expression = two() } } } } }, { new ArrayLiteral(null) { Elements = new List <IExpression>() { one(), one() } }, new ArrayLiteral(null) { Elements = new List <IExpression>() { two(), two() } } }, }; foreach (var test in tests) { var modified = Parser.Modify(test.Key, turnOneIntoTwo); var jsonModified = Newtonsoft.Json.JsonConvert.SerializeObject(modified); var jsonExpected = Newtonsoft.Json.JsonConvert.SerializeObject(test.Value); Assert.Equal(jsonExpected, jsonModified); } var hashLiteral = new HashLiteral(null) { Pairs = new Dictionary <IExpression, IExpression>() { { one(), one() }, { one(), one() } } }; Parser.Modify(hashLiteral, turnOneIntoTwo); foreach (var kvp in hashLiteral.Pairs) { var key = Assert.IsType <IntegerLiteral>(kvp.Key); var val = Assert.IsType <IntegerLiteral>(kvp.Value); Assert.Equal(2, key.Value); Assert.Equal(2, val.Value); } }