public IWasmicSyntaxTreeExpression GetExpression() { IWasmicSyntaxTreeExpression lhs; switch (_lexer.Next.TokenType) { case TokenType.Identifier: var name = _lexer.Next.Value; _lexer.Advance(); while (_lexer.Next.TokenType == TokenType.Period) { _lexer.Advance(); _lexer.AssertNext(TokenType.Identifier); name += $".{_lexer.Next.Value}"; _lexer.Advance(); } int?arrayOffset = null; if (_lexer.Next.TokenType == TokenType.L_Bracket) { _lexer.Advance(); // eat [ _lexer.AssertNext(TokenType.Int32); arrayOffset = int.Parse(_lexer.Next.Value) * 4; _lexer.Advance(); // eat offset _lexer.AssertNext(TokenType.R_Bracket); _lexer.Advance(); // eat ] } switch (_lexer.Next.TokenType) { case TokenType.Equal: _lexer.Advance(); // eat = lhs = arrayOffset.HasValue ? (IWasmicSyntaxTreeExpression)GetSetArrayLocalVariable(name, arrayOffset.Value) : GetSetLocalVariable(name, null, false); break; case TokenType.PlusEqual: _lexer.Advance(); // eat += var valueExpression = GetExpression(); var getExpr = GetGetLocalVariable(name); var expression = new BinopExpresison(valueExpression, getExpr, Operation.Add); lhs = GetSetLocalVariable(name, expression); break; case TokenType.L_Paren: lhs = _functionCallParser.Parse(_lexer, _functionMap, this, name); break; default: lhs = arrayOffset.HasValue ? (IWasmicSyntaxTreeExpression)GetGetArrayLocalVariable(name, arrayOffset.Value) : GetGetLocalVariable(name); break; } break; case TokenType.Int32: var i32 = _lexer.Next.Value; _lexer.Advance(); lhs = new Literal("i32", i32); break; case TokenType.Int64: var i64 = _lexer.Next.Value; _lexer.Advance(); lhs = new Literal("i64", i64); break; case TokenType.String: var result = _lexer.Next.Value; _lexer.Advance(); (int offset, string label) = _heap.AllocateOrGetString(result); lhs = new WasmicString(label, offset, result.Length); break; case TokenType.If: lhs = GetIf(); break; default: throw new NotImplementedException(_lexer.Next.TokenType.ToString()); } switch (_lexer.Next.TokenType) { case TokenType.Plus: case TokenType.Minus: case TokenType.Star: case TokenType.Slash: return(_binopExpressionParser.Parse(_lexer, this, lhs)); case TokenType.EqualComparer: case TokenType.GrThanComparer: case TokenType.GrThanOrEqComparer: case TokenType.LsThanComparer: case TokenType.LsThanOrEqComparer: return(_comparisonParser.Parse(_lexer, this, lhs)); } return(lhs); }