예제 #1
0
        public static IProgram Transform(IProgram p)
        {
            TypeMap globalMap = StaticTypeCheck.Typing(p.Globals());

            Functions funcs = p.functions();

            foreach (Function f in p.functions().Values.ToList())
            {
                TypeMap newMap = new TypeMap();
                newMap.PutAll(globalMap);
                newMap.PutAll(StaticTypeCheck.Typing(f.Param()));
                newMap.PutAll(StaticTypeCheck.Typing(f.Locals()));
                Block transformedBody = (Block)Transform(f.Body(), funcs, newMap);
                if (!funcs.ContainsKey(f.Id()))
                {
                    funcs.Add(f.Id(), new Function(f.type(), f.Id(), f.Param(), f.Locals(), transformedBody));
                }
                else
                {
                    funcs[f.Id()] = new Function(f.type(), f.Id(), f.Param(), f.Locals(), transformedBody);
                }
            }

            return(new IProgram(p.Globals(), funcs));
        }
예제 #2
0
        public static IStatement Transform(IStatement s, Functions funcs, TypeMap tm)
        {
            if (s is Skip || s is Return || s is Call)
            {
                return(s);
            }
            if (s is Assignment)
            {
                Assignment a = (Assignment)s;

                Variable    target = a.Target();
                IExpression src    = a.Source();

                Type targettype = (Type)tm[a.Target()];
                Type srctype    = StaticTypeCheck.TypeOf(a.Source(), funcs, tm);

                if (targettype == Type.FLOAT)
                {
                    if (srctype == Type.INT)
                    {
                        src     = new Unary(new Operator(Operator.FLOAT), src);
                        srctype = Type.FLOAT;
                    }
                }
                else if (targettype == Type.INT)
                {
                    if (srctype == Type.CHAR)
                    {
                        src     = new Unary(new Operator(Operator.INT), src);
                        srctype = Type.INT;
                    }
                    else if (srctype == Type.FLOAT)
                    {
                        src     = new Unary(new Operator(Operator.INT), src);
                        srctype = Type.INT;
                    }
                }
                StaticTypeCheck.Check(targettype == srctype, "bug in assignment to " + target);
                return(new Assignment(target, src));
            }

            if (s is Conditional)
            {
                Conditional c    = (Conditional)s;
                IExpression test = c.Test();
                IStatement  tbr  = Transform(c.ThenBranch(), funcs, tm);
                IStatement  ebr  = Transform(c.ElseBranch(), funcs, tm);
                return(new Conditional(test, tbr, ebr));
            }

            if (s is Loop)
            {
                Loop        l    = (Loop)s;
                IExpression test = l.Test();
                IStatement  body = l.Body();
                return(new Loop(test, body));
            }

            if (s is Block)
            {
                Block b    = (Block)s;
                Block @out = new Block();
                IEnumerator <IStatement> members = b.GetMembers();
                while (members.MoveNext())
                {
                    @out.AddMember(Transform(members.Current, funcs, tm));
                }
                return(@out);
            }
            throw new IException("Semantic Error", "", "Semantic", 0, 0);
        }
예제 #3
0
        public static Value Interpret(Binary b, Functions funcs, State state)
        {
            Operator op = b.Operator();
            Value    v1 = Interpret(b.Term1(), funcs, state);
            Value    v2 = Interpret(b.Term2(), funcs, state);

            StaticTypeCheck.Check(!v1.Undefined() || !v2.Undefined(), "reference to undef value in binary op");
            if (op.IsArithmeticOp())
            {
                if (v1.Type() == Type.INT && v1.Type() == Type.INT)
                {
                    if (op.val.Equals(Operator.PLUS))
                    {
                        return(new IntValue(v1.DIntValue() + v2.DIntValue()));
                    }
                    if (op.val.Equals(Operator.MINUS))
                    {
                        return(new IntValue(v1.DIntValue() - v2.DIntValue()));
                    }
                    if (op.val.Equals(Operator.TIMES))
                    {
                        return(new IntValue(v1.DIntValue() * v2.DIntValue()));
                    }
                    if (op.val.Equals(Operator.DIV))
                    {
                        return(new IntValue(v1.DIntValue() / v2.DIntValue()));
                    }
                }
                else if (v1.Type() == Type.FLOAT && v2.Type() == Type.FLOAT)
                {
                    if (op.val.Equals(Operator.PLUS))
                    {
                        return(new FloatValue(v1.DFloatValue() + v2.DFloatValue()));
                    }
                    if (op.val.Equals(Operator.MINUS))
                    {
                        return(new FloatValue(v1.DFloatValue() - v2.DFloatValue()));
                    }
                    if (op.val.Equals(Operator.TIMES))
                    {
                        return(new FloatValue(v1.DFloatValue() * v2.DFloatValue()));
                    }
                    if (op.val.Equals(Operator.DIV))
                    {
                        return(new FloatValue(v1.DFloatValue() / v2.DFloatValue()));
                    }
                }
                else if ((v1.Type() == Type.INT && v2.Type() == Type.FLOAT) || (v1.Type() == Type.FLOAT && v2.Type() == Type.INT))
                {
                    if (v1.Type() == Type.INT)
                    {
                        v1 = new FloatValue((float)v1.DIntValue());
                    }
                    else if (v2.Type() == Type.INT)
                    {
                        v2 = new FloatValue((float)v2.DIntValue());
                    }
                    return(Interpret(new Binary(op, v1, v2), funcs, state));
                }
                else
                {
                    throw new IException("Attemped arithmetic op on a " + v1.Type() + " and a " + v2.Type() + ", not allowed (v1: " + v1 + " v2: " + v2 + ")", "", "Semantic", 0, 0);
                }
            }
            else if (op.IsBooleanOp())
            {
                if (!(v1.Type() == Type.BOOL && v1.Type() == Type.BOOL))
                {
                    throw new IException("Attemped boolean op on " + v1.Type() + ", not allowed", "", "Semantic", 0, 0);
                }
                else
                {
                    if (op.val.Equals(Operator.AND))
                    {
                        return(new BoolValue(v1.DBoolValue() && v2.DBoolValue()));
                    }
                    else if (op.val.Equals(Operator.OR))
                    {
                        return(new BoolValue(v1.DBoolValue() || v2.DBoolValue()));
                    }
                }
            }
            else if (op.IsRelationalOp())
            {
                if (v1.Type() == Type.INT && v1.Type() == Type.INT)
                {
                    if (op.val.Equals(Operator.LT))
                    {
                        return(new BoolValue(v1.DIntValue() < v2.DIntValue()));
                    }
                    else if (op.val.Equals(Operator.GT))
                    {
                        return(new BoolValue(v1.DIntValue() > v2.DIntValue()));
                    }
                    else if (op.val.Equals(Operator.LE))
                    {
                        return(new BoolValue(v1.DIntValue() <= v2.DIntValue()));
                    }
                    else if (op.val.Equals(Operator.GE))
                    {
                        return(new BoolValue(v1.DIntValue() >= v2.DIntValue()));
                    }
                    else if (op.val.Equals(Operator.EQ))
                    {
                        return(new BoolValue(v1.DIntValue() == v2.DIntValue()));
                    }
                    else if (op.val.Equals(Operator.NE))
                    {
                        return(new BoolValue(v1.DIntValue() != v2.DIntValue()));
                    }
                }
                else if (v1.Type() == Type.FLOAT && v1.Type() == Type.FLOAT)
                {
                    if (op.val.Equals(Operator.LT))
                    {
                        return(new BoolValue(v1.DFloatValue() < v2.DFloatValue()));
                    }
                    else if (op.val.Equals(Operator.GT))
                    {
                        return(new BoolValue(v1.DFloatValue() > v2.DFloatValue()));
                    }
                    else if (op.val.Equals(Operator.LE))
                    {
                        return(new BoolValue(v1.DFloatValue() <= v2.DFloatValue()));
                    }
                    else if (op.val.Equals(Operator.GE))
                    {
                        return(new BoolValue(v1.DFloatValue() >= v2.DFloatValue()));
                    }
                    else if (op.val.Equals(Operator.EQ))
                    {
                        return(new BoolValue(v1.DFloatValue() == v2.DFloatValue()));
                    }
                    else if (op.val.Equals(Operator.NE))
                    {
                        return(new BoolValue(v1.DFloatValue() != v2.DFloatValue()));
                    }
                }
                else if ((v1.Type() == Type.INT && v2.Type() == Type.FLOAT) || (v1.Type() == Type.FLOAT && v2.Type() == Type.INT))
                {
                    if (v1.Type() == Type.INT)
                    {
                        v1 = new FloatValue((float)v1.DIntValue());
                    }
                    else if (v2.Type() == Type.INT)
                    {
                        v2 = new FloatValue((float)v2.DIntValue());
                    }
                    return(Interpret(new Binary(op, v1, v2), funcs, state));
                }
                else if (v1.Type() == Type.CHAR && v2.Type() == Type.CHAR)
                {
                    if (op.val.Equals(Operator.LT))
                    {
                        return(new BoolValue(v1.DCharValue() < v2.DCharValue()));
                    }
                    else if (op.val.Equals(Operator.GT))
                    {
                        return(new BoolValue(v1.DCharValue() > v2.DCharValue()));
                    }
                    else if (op.val.Equals(Operator.LE))
                    {
                        return(new BoolValue(v1.DCharValue() <= v2.DCharValue()));
                    }
                    else if (op.val.Equals(Operator.GE))
                    {
                        return(new BoolValue(v1.DCharValue() >= v2.DCharValue()));
                    }
                    else if (op.val.Equals(Operator.EQ))
                    {
                        return(new BoolValue(v1.DCharValue() == v2.DCharValue()));
                    }
                    else if (op.val.Equals(Operator.NE))
                    {
                        return(new BoolValue(v1.DCharValue() != v2.DCharValue()));
                    }
                }
                else if (v1.Type() == Type.BOOL && v2.Type() == Type.BOOL)
                {
                    if (op.val.Equals(Operator.EQ))
                    {
                        return(new BoolValue(v1.DBoolValue() == v2.DBoolValue()));
                    }
                    else if (op.val.Equals(Operator.NE))
                    {
                        return(new BoolValue(v1.DBoolValue() != v2.DBoolValue()));
                    }
                    else
                    {
                        throw new IException("Attempted illegal relational op " + op + " on two booleans (v1: " + v1 + " v2: " + v2 + ")", "", "Semantic", 0, 0);
                    }
                }
                else
                {
                    throw new IException("Attemped relational op on a " + v1.Type() + " and a " + v2.Type() + ", not allowed (v1: " + v1 + " v2: " + v2 + ")", "", "Semantic", 0, 0);
                }
            }
            throw new IException("Semantic Error: (in DynamicTyping.ApplyBinary)", "", "Semantic", 0, 0);
        }
예제 #4
0
        private void CompileClick(object sender, EventArgs e)
        {
            ErrorCount = 0;
            Parser parser;

            error_list.Items.Clear();
            lbl_stats.Text = "";
            txt_out.Text   = "";
            if (ParentContainer.Panel2Collapsed)
            {
                ParentContainer.Panel2Collapsed = false;
                Tabs.SelectedIndex = 1;
                txt_out.Text       = "Compiling .....\n";
            }
            if (edit.Text.Length < 1)
            {
                MessageBox.Show("No Code To Compile It!!", "No Code", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                parser = new Parser(new Scanner(String2Stream(edit.Text)));
                try
                {
                    IProgram prog = parser.Program();
                    StaticTypeCheck.Validate(prog);
                    IProgram transformed = TypeTransformer.Transform(prog);
                    txt_out.Text += transformed.Display();
                    txt_out.Text += "\n-------------------------------\n";
                    txt_out.Text += "\nResults:\n";
                    State state = Interpreter.Interpret(transformed);
                    Code          = state.Display();
                    txt_out.Text += Code;
                    ParentContainer.Panel2Collapsed = true;
                    lbl_stats.Text = "Successful Compiling";
                }
                catch (IException ex)
                {
                    txt_out.Text = ex.Type + " Error :  " + ex.Message;
                    ListViewItem lvi = new ListViewItem((++ErrorCount).ToString());
                    lvi.SubItems.Add(ex.Type);
                    lvi.SubItems.Add(ex.File);
                    lvi.SubItems.Add(ex.LineNumber.ToString());
                    lvi.SubItems.Add(ex.ColmunNumber.ToString());
                    lvi.SubItems.Add(ex.Message);
                    error_list.Items.Add(lvi);
                    lbl_stats.Text     = "Failed Compiling";
                    Tabs.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    txt_out.Text = " Error :  " + ex.Message;
                    ListViewItem lvi = new ListViewItem((++ErrorCount).ToString());
                    lvi.SubItems.Add("Unkown");
                    lvi.SubItems.Add("");
                    lvi.SubItems.Add("");
                    lvi.SubItems.Add("");
                    lvi.SubItems.Add(ex.Message);
                    error_list.Items.Add(lvi);
                    lbl_stats.Text = "Failed Compiling";
                }
            }
        }
예제 #5
0
        public static Value Interpret(Unary u, Functions funcs, State state)
        {
            Operator op = u.Operator();
            Value    v  = Interpret(u.term, funcs, state);

            StaticTypeCheck.Check(!v.Undefined(), "reference to undef value in unary op");
            if (op.val.Equals(Operator.NOT))
            {
                if (v.Type() != Type.BOOL)
                {
                    throw new IException("Can only apply ! operator to bool (attempted on " + v + ")", "", "Semantic", 0, 0);
                }
                else
                {
                    return(new BoolValue(!v.DBoolValue()));
                }
            }
            else if (op.val.Equals(Operator.NEG))
            {
                if (v.Type() == Type.FLOAT)
                {
                    return(new FloatValue(-v.DFloatValue()));
                }
                else if (v.Type() == Type.INT)
                {
                    return(new IntValue(-v.DIntValue()));
                }
                else
                {
                    throw new IException("Can only apply - operator to int or float (attempted on " + v + ")", "", "Semantic", 0, 0);
                }
            }
            else if (op.val.Equals(Operator.FLOAT))
            {
                if (v.Type() != Type.INT)
                {
                    throw new IException("Can only cast int to float (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
                else
                {
                    return(new FloatValue((float)v.DIntValue()));
                }
            }
            else if (op.val.Equals(Operator.INT))
            {
                if (v.Type() == Type.FLOAT)
                {
                    return(new IntValue((int)v.DFloatValue()));
                }
                else if (v.Type() == Type.CHAR)
                {
                    return(new IntValue((int)v.DCharValue()));
                }
                else
                {
                    throw new IException("Can only cast float or char to int (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
            }
            else if (op.val.Equals(Operator.CHAR))
            {
                if (v.Type() == Type.INT)
                {
                    return(new CharValue((char)v.DIntValue()));
                }
                else
                {
                    throw new IException("Can only cast int to char (tried to cast " + v + ")", "", "Semantic", 0, 0);
                }
            }
            throw new IException("Semantic Error", "", "Semantic", 0, 0);
        }