/** * Parses the rest of a v-name, and constructs an AST to represent its phrase * structure. * * @param firstIdentifier * the {@link triangle.compiler.syntax.trees.terminals.Identifier} * that is the start of the * {@link triangle.compiler.syntax.trees.vnames.Vname} * * @return a {@link triangle.compiler.syntax.trees.vnames.Vname} * * @throws SyntaxError * a syntactic error * */ Vname ParseRestOfVname(Identifier firstIdentifier) { var startLocation = firstIdentifier.Start; Vname vname = new SimpleVname(firstIdentifier, firstIdentifier.Position); while (_currentToken.Kind == TokenKind.Dot || _currentToken.Kind == TokenKind.LeftBracket) { if (_currentToken.Kind == TokenKind.Dot) { AcceptIt(); var identifier = ParseIdentifier(); var vnamePosition = new SourcePosition(startLocation, _currentToken.Finish); vname = new DotVname(vname, identifier, vnamePosition); } else { AcceptIt(); var expression = ParseExpression(); Accept(TokenKind.RightBracket); var vnamePosition = new SourcePosition(startLocation, _currentToken.Finish); vname = new SubscriptVname(vname, expression, vnamePosition); } } return(vname); }
public IFetchableEntity VisitSubscriptVname(SubscriptVname ast, Frame frame) { var baseObject = ast.Vname.Visit(this, frame); var elemSize = ast.Type.Visit(this, null); if (!ast.Expression.IsLiteral) { // v-name is indexed by a proper expression, not a literal if (ast.Vname.IsIndexed) { frame = frame.Expand(Machine.IntegerSize); } ast.Expression.Visit(this, frame); if (elemSize != 1) { _emitter.Emit(OpCode.LOADL, elemSize); _emitter.Emit(OpCode.CALL, Register.SB, Register.PB, Primitive.MULT); } if (ast.Vname.IsIndexed) { _emitter.Emit(OpCode.CALL, Register.SB, Register.PB, Primitive.ADD); } } return(baseObject); }
public TypeDenoter VisitSubscriptVname(SubscriptVname ast, Void arg) { var vnameType = ast.Vname.Visit(this); var expressionType = ast.Expression.Visit(this); if (vnameType != StandardEnvironment.ErrorType) { if (vnameType is ArrayTypeDenoter arrayType) { CheckAndReportError(expressionType.Equals(StandardEnvironment.IntegerType), "Integer expression expected here", ast.Expression); ast.Type = arrayType.Type; } else { ReportError("array expected here", ast.Vname); } } return(ast.Type); }