private Expression ParseProcExpression(ExprState state) { // Either a signature as a type def. or a signature + body, which is a full procedure definition var signature = ParseProcSignature(); if (!state.HasFlag(ExprState.TypeOnly) && Peek().Type == TokenType.OpenBrace) { var body = ParseBlockExpression(); return(new Expression.Proc(signature, body)); } return(signature); }
public override void SetupPins() { sizeX = 2; sizeY = 2; pins = new Pin[4]; pins[0] = new Pin(this, 0, SIDE_W, "C+"); pins[1] = new Pin(this, 1, SIDE_W, "C-"); pins[1].output = true; pins[2] = new Pin(this, 0, SIDE_E, "O+"); pins[2].output = true; pins[3] = new Pin(this, 1, SIDE_E, "O-"); mExprState = new ExprState(1); }
public override void SetupPins() { sizeX = 2; sizeY = mInputCount > 2 ? mInputCount : 2; pins = new Pin[mInputCount + 2]; for (int i = 0; i != mInputCount; i++) { pins[i] = new Pin(this, i, SIDE_W, char.ToString((char)('A' + i))); } pins[mInputCount] = new Pin(this, 0, SIDE_E, "C+"); pins[mInputCount + 1] = new Pin(this, 1, SIDE_E, "C-"); mLastVolts = new double[mInputCount]; mExprState = new ExprState(mInputCount); }
private Expression ParseAtomicExpression(ExprState state) { begin: var peek = Peek(); switch (peek.Type) { case TokenType.KwProc: return(ParseProcExpression(state)); case TokenType.KwIf: return(ParseIfExpression()); case TokenType.KwWhile: return(ParseWhileExpression()); case TokenType.KwStruct: return(ParseStructTypeExpression()); case TokenType.Identifier: case TokenType.IntLiteral: case TokenType.StringLiteral: case TokenType.KwTrue: case TokenType.KwFalse: return(new Expression.Literal(Next())); case TokenType.OpenParen: return(ParseParenthesized()); case TokenType.OpenBrace: // NOTE: We ignore state.HasFlag(ExprState.NoBraced) // As there's no any other sensible thing to do here return(ParseBlockExpression()); case TokenType.KwConst when Peek(1).Type == TokenType.OpenParen: return(ParseConstExpression()); default: // Error ReportSyntaxError(new UnexpectedTokenError(peek) { Context = "expression" }); Next(); // For now we just retry goto begin; } }
private Expression ParseBinaryExpression(ExprState state, int precedence = 0) { if (precedence >= PrecedenceTable.Length || state.HasFlag(ExprState.TypeOnly)) { // Out of precedence table entries or we are parsing a type return(ParsePrefixExpression(state)); } var desc = PrecedenceTable[precedence]; var result = ParseBinaryExpression(state, precedence + 1); if (desc.Associativity == Associativity.Left) { while (true) { var op = Peek(); if (!desc.Operators.Contains(op.Type)) { break; } op = Next(); var right = ParseBinaryExpression(state, precedence + 1); result = new Expression.Binary(result, op, right); } return(result); } else { var op = Peek(); if (!desc.Operators.Contains(op.Type)) { return(result); } op = Next(); var right = ParseBinaryExpression(state, precedence); return(new Expression.Binary(result, op, right)); } }
private Expression ParsePrefixExpression(ExprState state) { var peek = Peek(); if (PrefixOperators.Contains(peek.Type)) { var op = Next(); var operand = ParsePrefixExpression(state); return(new Expression.Prefix(op, operand)); } else if (peek.Type == TokenType.OpenBracket) { var openBracket = Expect(null, null, TokenType.OpenBracket); // Array type expression var length = ParseExpression(ExprState.None); var closeBracket = Expect("array type expression", openBracket, TokenType.CloseBracket); var elementType = ParsePrefixExpression(state); return(new Expression.ArrayType(openBracket, length, closeBracket, elementType)); } else { return(ParsePostfixExpression(state)); } }
private Expression ParsePostfixExpression(ExprState state) { var result = ParseAtomicExpression(state); while (true) { var peek = Peek(); if (PostfixOperators.Contains(peek.Type)) { var op = Next(); result = new Expression.Postfix(result, op); } else if (peek.Type == TokenType.OpenParen) { var openParen = Expect(null, null, TokenType.OpenParen); // Call expression var args = new List <WithComma <Expression> >(); while (Peek().Type != TokenType.CloseParen) { var arg = ParseExpression(ExprState.None); var hasComma = Match(TokenType.Comma, out var comma); args.Add(new WithComma <Expression>(arg, comma)); if (!hasComma) { break; } } var closeParen = Expect("call expression", openParen, TokenType.CloseParen); result = new Expression.Call(result, openParen, args, closeParen); } else if (peek.Type == TokenType.OpenBracket) { var openBracket = Expect(null, null, TokenType.OpenBracket); // Subscript expression var index = ParseExpression(ExprState.None); var closeBracket = Expect("subscript expression", openBracket, TokenType.CloseBracket); result = new Expression.Subscript(result, openBracket, index, closeBracket); } else if (!state.HasFlag(ExprState.TypeOnly) && !state.HasFlag(ExprState.NoBraced) && peek.Type == TokenType.OpenBrace) { // Struct instantiation var openBrace = Expect(null, null, TokenType.OpenBrace); var fields = new List <Expression.StructValue.Field>(); while (Peek().Type != TokenType.CloseBrace) { fields.Add(ParseStructValueField()); } var closeBrace = Expect("struct instantiation", openBrace, TokenType.CloseBrace); result = new Expression.StructValue(result, openBrace, fields, closeBrace); } else if (peek.Type == TokenType.Dot) { // Dot path var dot = Expect(null, null, TokenType.Dot); var ident = Expect("dot path expression", null, TokenType.Identifier); result = new Expression.DotPath(result, dot, ident); } else { break; } } return(result); }
private Expression ParseExpression(ExprState state) => ParseBinaryExpression(state);