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);
            }
示例#2
0
 public FunctionEntry(Level level, Label label, Types.RECORD formals, Types.Type result)
 {
     Level = level;
     Label = label;
     Formals = formals;
     Result = result;
 }
示例#3
0
 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);
            }
示例#9
0
 public StandardFunctionEntry(Level level, Label label, Types.RECORD formals, Types.Type result)
     : base(level, label, formals, result)
 {
 }