private DesignatorNode ParseMemberAccess(SymTable symTable, DesignatorNode record) { while (true) { if (Current.SubType != Dot) { return(record); } Next(); var rt = (RecordTypeSymbol)record.Type; var c = Current; Require(Identifier); if (!rt.Fields.Contains(c.Value.ToString())) { throw new ParserException("Illegal identifier", c.Line, c.Position); } var f = new MemberAccessOperator(new List <Node> { record, new IdentNode(null, c) }, "Member access", c.Line, c.Position) { Type = ((VarSymbol)rt.Fields[c.Value.ToString()]).Type }; switch (f.Type) { case RecordTypeSymbol _: record = f; continue; case ArrayTypeSymbol _: return(ParseIndex(symTable, f)); } return(f); } }
private DesignatorNode ParseIndex(SymTable symTable, DesignatorNode array) { while (true) { if (Current.SubType != LBracket) { return(array); } var ars = (ArrayTypeSymbol)array.Type; var p = ParseIndexParam(symTable); CheckImplicitTypeCompatibility((TypeSymbol)p.Type, TypeSymbol.IntTypeSymbol); var i = new IndexOperator(new List <Node> { array, p }, "Index", p.Line, p.Position) { Type = ars.ElementType }; switch (ars.ElementType) { case RecordTypeSymbol _: return(ParseMemberAccess(symTable, i)); case ArrayTypeSymbol _: array = i; continue; } return(i); } }
private DesignatorNode ParseProcedureCall(SymTable symTable, DesignatorNode procedure) { var ps = (ProcedureSymbol)procedure.Type; var p = ParseActualParameters(symTable); CheckParameters(ps.Parameters, p); return(new CallOperator(p.Childs, "Call", p.Line, p.Position) { Subprogram = ps }); }
private DesignatorNode ParseFunctionCall(SymTable symTable, DesignatorNode function) { var fs = (FunctionSymbol)function.Type; var p = ParseActualParameters(symTable); CheckParameters(fs.Parameters, p); var f = new CallOperator(p.Childs, "Call", p.Line, p.Position) { Subprogram = fs, Type = fs.ReturnType }; switch (fs.ReturnType) { case RecordTypeSymbol _: return(ParseMemberAccess(symTable, f)); case ArrayTypeSymbol _: return(ParseIndex(symTable, f)); } return(f); }
private DesignatorNode ParseCast(SymTable symTable, DesignatorNode type) { var ts = (TypeSymbol)type.Type; var p = ParseCastParam(symTable); CheckExplicitTypeCompatibility((TypeSymbol)p.Type, ts); var c = new CastOperator(new List <Node> { p }, "Cast", p.Line, p.Position) { Type = ts }; switch (ts) { case RecordTypeSymbol _: return(ParseMemberAccess(symTable, c)); case ArrayTypeSymbol _: return(ParseIndex(symTable, c)); } return(c); }