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)); }
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); }
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); }
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"; } } }
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); }