Types.Type TranslateType(RecordType t) { Types.RECORD result = null, p = null; Types.Type type; List <SymbolTable.Symbol> list = new List <SymbolTable.Symbol>(); for (FieldList field = t.Fields; field != null; field = field.Tail) { type = Env.TypeEnvironment[field.Type] as Types.Type; if (type == null) { Error.Report(field.Pos, "Undefined type '" + field.Type.ToString() + "'"); return(null); } if (list.Contains(field.Name)) { Error.Report(field.Pos, "Redefined field name " + field.Name.ToString() + "'"); } else { list.Add(field.Name); } if (p == null) { result = p = new Types.RECORD(field.Name, type, null); } else { p = p.Tail = new Types.RECORD(field.Name, type, null); } } return(result); }
public FunctionEntry(Level level, Label label, Types.RECORD formals, Types.Type result) { Level = level; Label = label; Formals = formals; Result = result; }
ExpressionType TranslateVariable(FieldVariable field) { ExpressionType et = TranslateVariable(field.Var); if (et.Type.Actual is Types.RECORD) { int index = 0; Types.RECORD type = et.Type.Actual as Types.RECORD; for (; type != null; type = type.Tail, ++index) { if (type.FieldName == field.Field) { break; } } if (type != null) { return(new ExpressionType(Translate.TranslateFieldVar(et.Exp, index), type.FieldType.Actual)); } else { Error.Report(field.Pos, "Field '" + field.Field.ToString() + "' does not exist."); return(new ExpressionType(null, Types.Type._unknown)); } } else { Error.Report(field.Pos, "Record type required"); return(new ExpressionType(null, Types.Type._unknown)); } }
ExpressionType TranslateExpression(CallExpression e) { Entry func = Env.ValueEnvironment[e.Func] as Entry; if (func == null || !(func is FunctionEntry)) { Error.Report(e.Pos, "Undefined function '" + e.Func.ToString() + "'"); return(new ExpressionType(null, Types.Type._void)); } Types.RECORD formals = (func as FunctionEntry).Formals; List <Exp> list = new List <Exp>(); for (ExpressionList args = e.Args; args != null; args = args.Tail, formals = formals.Tail) { if (formals == null) { Error.Report(e.Pos, "Too much parameters in call '" + e.Func.ToString() + "'"); return(new ExpressionType(null, (func as FunctionEntry).Result)); } ExpressionType et = TranslateExpression(args.Head); if (!et.Type.CoerceTo(formals.FieldType)) { Error.Report(args.Head.Pos, "Type mismatch for parameter '" + formals.FieldName.ToString() + "'"); return(new ExpressionType(null, (func as FunctionEntry).Result)); } list.Add(et.Exp); } if (formals != null) { Error.Report(e.Pos, "Too few parameters in call '" + e.Func.ToString() + "'"); } return(new ExpressionType(Translate.TranslateCallExp(Level, (func as FunctionEntry).Level, (func as FunctionEntry).Label, list), (func as FunctionEntry).Result.Actual)); }
Exp TranslateDeclaration(FunctionDeclaration dec) { List <SymbolTable.Symbol> list = new List <SymbolTable.Symbol>(); for (FunctionDeclaration d = dec; d != null; d = d.Next) { if (Env.ValueEnvironment[d.Name] != null && Env.ValueEnvironment[d.Name] is StandardFunctionEntry) { Error.Report(d.Pos, "Function in standard libaray cannot be redefined"); } else if (list.Contains(d.Name)) { Error.Report(d.Pos, "Function cannot be redefined in a sequence"); } else { list.Add(d.Name); Types.Type result = d.Result == null ? Types.Type._void : TranslateType(d.Result).Actual; Types.RECORD formals = TranslateTypeFields(d.Param); Label label = new Label(d.Name + "_" + Count++.ToString()); Translate.Level level = new Translate.Level(Level, label, BoolList.BuildFromFieldList(d.Param)); Env.ValueEnvironment[d.Name] = new FunctionEntry(level, label, formals, result); } } for (FunctionDeclaration d = dec; d != null; d = d.Next) { FunctionEntry function = Env.ValueEnvironment[d.Name] as FunctionEntry; Env.ValueEnvironment.BeginScope(); Env.LoopEnvironment.BeginScope(); Translate.Level backup = Level; Level = function.Level; Translate.AccessList al = Level.Formals.Tail; for (FieldList field = d.Param; field != null; field = field.Tail, al = al.Tail) { Types.Type type = Env.TypeEnvironment[field.Type] as Types.Type; if (type == null) { Error.Report(field.Pos, "Undefined type '" + field.Name + "'"); } else { Translate.Access access = new Translate.Access(Level, al.Head.Acc); Env.ValueEnvironment[field.Name] = new VariableEntry(access, type.Actual); } } ExpressionType et = TranslateExpression(d.Body); Translate.ProcessEntryExit(Level, et.Exp, !(et.Type.CoerceTo(Types.Type._void))); if (!et.Type.CoerceTo((Env.ValueEnvironment[d.Name] as FunctionEntry).Result)) { Error.Report(d.Result != null ? d.Result.Pos : d.Body.Pos, "Type mismatched for function return value"); } Env.ValueEnvironment.EndScope(); Env.LoopEnvironment.EndScope(); Level = backup; } return(Translate.TranslateNoOp()); }
ExpressionType TranslateExpression(RecordExpression e) { Types.Type eType = Env.TypeEnvironment[e.Type] as Types.Type; if (eType == null) { Error.Report(e.Pos, "Undefined record type " + e.Type.ToString()); return(new ExpressionType(null, Types.Type._int)); } eType = eType.Actual; if (!(eType is Types.RECORD)) { Error.Report(e.Pos, "Record type required"); return(new ExpressionType(null, Types.Type._int)); } FieldExpressionList eFields = e.Fields; Types.RECORD eRecord = (Types.RECORD)eType; ExpressionType et; List <Exp> fieldList = new List <Exp>(); for (; eFields != null; eFields = eFields.Tail, eRecord = eRecord.Tail) { if (eRecord == null) { Error.Report(eFields.Pos, "Field " + eFields.Name.ToString() + " has not been declared"); break; } if (eRecord.FieldName != eFields.Name) { Error.Report(eFields.Pos, eRecord.FieldName.ToString() + " field dismatch"); break; } et = TranslateExpression(eFields.Init); fieldList.Add(et.Exp); if (!et.Type.CoerceTo(eRecord.FieldType)) { Error.Report(eFields.Pos, "Type mismatch in record field"); } } if (eRecord != null) { Error.Report(eFields.Pos, "Missing record fields"); } return(new ExpressionType(Translate.TranslateRecordExp(Level, fieldList), eType)); }
Types.RECORD TranslateTypeFields(FieldList field) { Types.RECORD type = null, result = null; for (FieldList f = field; f != null; f = f.Tail) { Types.Type t = Env.TypeEnvironment[f.Type] as Types.Type; t = t.Actual; if (t == null) { Error.Report(f.Pos, "Undefined type '" + f.Type.ToString() + "'"); } else if (type == null) { result = type = new Types.RECORD(f.Name, t, null); } else { type.Tail = new Types.RECORD(f.Name, t, null); type = type.Tail; } } return(result); }
public StandardFunctionEntry(Level level, Label label, Types.RECORD formals, Types.Type result) : base(level, label, formals, result) { }