예제 #1
0
        public void GenClassItems(WalkState ws, ITypeContainer parent)
        {
            var c = parent.GetClass(ws.Assembly, ws.Namespace, Name, Public);
            foreach (var s in Statements)
            {
                var t = s.GetType();
                if (t == typeof(Class))
                {
                    (s as Class).GenClassItems(ws, c);
                }
                else if (t == typeof(FunctionDef))
                {
                    c.Functions.Add(new Function(c, s as FunctionDef, ws));
                }
                else if (t == typeof(PropertySet))
                {
                    var ps = s as PropertySet;
                    if (ps.CalcTypeList(ws))
                    {
                        ExprList el = null;
                        if (ps.Vals != null)
                        {
                            el = ps.Vals as ExprList;
                            if (ps.Props.Count != el.Expressions.Count)
                            {
                                ws.AddError("Mismatched property/value counts: " + ps.Props.Count + " != " + el.Expressions.Count);
                                el = null;
                            }
                        }

                        for (int i = 0; i < ps.Props.Count; i++)
                        {
                            var p = ps.Props[i];
                            var prop = p.Static ? new Constant(p, ws) : new Field(p, ws);
                            prop.CreateField(c);
                            if (el != null)
                            {
                                object val = el.Expressions[i].Calculate(ws);
                                if (val != null)
                                {
                                    prop.SetDefault(p.SystemType.Cast(val, ws));
                                }
                                // TODO - Do something with default values for fields.
                            }
                            c.Fields.Add(prop);
                        }
                    }
                }
                else
                {
                    ws.AddError("Unknown class statement: " + t);
                }
            }
        }
예제 #2
0
        public static bool CalcTypeList(this List<Variable> ps, WalkState ws)
        {
            Type type = null;
            for (int i = ps.Count - 1; i >= 0; i--)
            {
                if (ps[i].Type == null)
                {
                    ps[i].SystemType = type;
                }
                else
                {
                    type = ps[i].Type.ToType(ws);
                    ps[i].SystemType = type;
                }
            }

            bool retVal = true;
            foreach (var p in ps)
            {
                if (p.SystemType == null)
                {
                    ws.AddError("Type could not be determined for " + p.Name);
                    retVal = false;
                }
            }
            return retVal;
        }
예제 #3
0
        public List<Type> CalcTypes(WalkState ws)
        {
            List<Type> ltl = Left.CalcTypes(ws);
            List<Type> rtl = Right.CalcTypes(ws);

            if (ltl.Count == rtl.Count && ltl.Count == 1)
            {
                Type lt = ltl[0];
                Type rt = rtl[0];
                if (Op.IsBooleanOp()) { return new List<Type> { typeof(bool) }; }
                else if (Op == TokenType.As) { return rtl; }
                else if (lt == typeof(string) || rt == typeof(string)) { return new List<Type> { typeof(string) }; }
                else if (lt == rt) { return ltl; }
            }

            ws.AddError("Cannot apply binary operator " + Op + " with " + ltl.Count + " type(s) and " + rtl.Count + " type(s).");
            return new List<Type> { };
        }
예제 #4
0
 public void GenTypes(WalkState ws, ITypeContainer parent)
 {
     if (!string.IsNullOrEmpty(ws.Namespace))
     {
         var c = parent.GetClass(ws.Assembly, ws.Namespace, Name, Public);
         foreach(var s in Statements)
         {
             var t = s.GetType();
             if (t == typeof(Class))
             {
                 (s as Class).GenTypes(ws, c);
             }
         }
     }
     else
     {
         ws.AddError("No namespace specified for class " + Name);
     }
 }
예제 #5
0
        public static bool CalcTypeList(this PropertySet ps, WalkState ws)
        {
            Type type = null;
            for (int i = ps.Props.Count - 1; i >= 0; i--)
            {
                if (ps.Props[i].Type == null)
                {
                    ps.Props[i].SystemType = type;
                }
                else
                {
                    type = ps.Props[i].Type.ToType(ws);
                    ps.Props[i].SystemType = type;
                }
            }

            if (ps.Vals != null)
            {
                var types = (ps.Vals as ExprList).CalcTypes(ws);
                if (ps.Props.Count == types.Count)
                {
                    for (int i = 0; i < ps.Props.Count; i++)
                    {
                        if (ps.Props[i].SystemType == null)
                        {
                            ps.Props[i].SystemType = types[i];
                        }
                    }
                }
            }

            bool retVal = true;
            foreach (var p in ps.Props)
            {
                if (p.SystemType == null)
                {
                    ws.AddError("Type could not be determined for " + p.Name);
                    retVal = false;
                }
            }
            return retVal;
        }
예제 #6
0
        public object Calculate(WalkState ws)
        {
            Type lt, rt;
            object left = Left.Calculate(ws);
            object right = Right.Calculate(ws);
            switch (Op)
            {
                case TokenType.As:
                    rt = Right.CalcTypes(ws)[0];
                    return rt.Cast(left, ws);
                case TokenType.Is:
                    var lts = Left.CalcTypes(ws);
                    rt = Right.CalcTypes(ws)[0];
                    return (lts.Count == 1 && lts[0] == rt);
                case TokenType.Add:
                    lt = CalcTypes(ws)[0];
                    if (lt.IsFloatingPointType())
                    {
                        return lt.Cast(Convert.ToDouble(left) + Convert.ToDouble(right), ws);
                    }
                    else if (lt.IsIntegerType())
                    {
                        return lt.Cast(Convert.ToInt64(left) + Convert.ToInt64(right), ws);
                    }
                    else if (lt == typeof(string))
                    {
                        return left.ToString() + right.ToString();
                    }
                    break;
                case TokenType.Sub:
                    lt = CalcTypes(ws)[0];
                    if (lt.IsFloatingPointType())
                    {
                        return lt.Cast(Convert.ToDouble(left) - Convert.ToDouble(right), ws);
                    }
                    else if (lt.IsIntegerType())
                    {
                        return lt.Cast(Convert.ToInt64(left) - Convert.ToInt64(right), ws);
                    }
                    break;
                case TokenType.Mul:
                    lt = CalcTypes(ws)[0];
                    if (lt.IsFloatingPointType())
                    {
                        return lt.Cast(Convert.ToDouble(left) * Convert.ToDouble(right), ws);
                    }
                    else if (lt.IsIntegerType())
                    {
                        return lt.Cast(Convert.ToInt64(left) * Convert.ToInt64(right), ws);
                    }
                    break;
                case TokenType.Div:
                    lt = CalcTypes(ws)[0];
                    if (lt.IsFloatingPointType())
                    {
                        return lt.Cast(Convert.ToDouble(left) / Convert.ToDouble(right), ws);
                    }
                    else if (lt.IsIntegerType())
                    {
                        return lt.Cast(Convert.ToInt64(left) / Convert.ToInt64(right), ws);
                    }
                    break;
                case TokenType.Mod:
                    lt = CalcTypes(ws)[0];
                    if (lt.IsIntegerType())
                    {
                        return lt.Cast(Convert.ToInt64(left) % Convert.ToInt64(right), ws);
                    }
                    break;
                case TokenType.BAnd:
                case TokenType.BOr:
                case TokenType.BXOr:
                    break;
                case TokenType.Equal:
                    return (left as IComparable).CompareTo(right) == 0;
                case TokenType.NotEqual:
                    return (left as IComparable).CompareTo(right) != 0;
                case TokenType.LeftCaret:
                    return (left as IComparable).CompareTo(right) < 0;
                case TokenType.LtEqual:
                    return (left as IComparable).CompareTo(right) < 1;
                case TokenType.RightCaret:
                    return (left as IComparable).CompareTo(right) > 0;
                case TokenType.GtEqual:
                    return (left as IComparable).CompareTo(right) > -1;
                case TokenType.And:
                    return ((bool)left) && ((bool)right);
                case TokenType.Or:
                    return ((bool)left) || ((bool)right);
            }

            ws.AddError("Could not calculate binary operator: " + Op);
            return null;
        }
예제 #7
0
        public object Calculate(WalkState ws)
        {
            var ts = Expr.CalcTypes(ws);
            if (ts.Count != 1)
            {
                ws.AddError("Cannot use a unary operator on a type with " + ts.Count + " return type(s).");
                return null;
            }
            Type type = ts[0];
            var val = Expr.Calculate(ws);
            switch (Op)
            {
                case TokenType.Sub:
                    if (type.IsFloatingPointType())
                    {
                        return type.Cast(-Convert.ToDouble(val), ws);
                    }
                    else if (type.IsIntegerType())
                    {
                        return type.Cast(-Convert.ToInt64(val), ws);
                    }
                    ws.AddError("Cannot negate a field of type " + type);
                    return null;
                case TokenType.Not:
                    if (type == typeof(bool)) { return !(bool)val; }
                    ws.AddError("Cannot use not on a field of type " + type);
                    return null;
            }

            ws.AddError("Unknown unary op encountered when calculating value: " + Op);
            return null;
        }
예제 #8
0
        public static object Cast(this Type type, object val, WalkState ws)
        {
            if (type == typeof(bool)) { return Convert.ToBoolean(val); }
            else if (type == typeof(char)) { return Convert.ToChar(val); }
            else if (type == typeof(float)) { return Convert.ToSingle(val); }
            else if (type == typeof(double)) { return Convert.ToDouble(val); }
            else if (type == typeof(sbyte)) { return Convert.ToSByte(val); }
            else if (type == typeof(short)) { return Convert.ToInt16(val); }
            else if (type == typeof(int)) { return Convert.ToInt32(val); }
            else if (type == typeof(long)) { return Convert.ToInt64(val); }
            else if (type == typeof(byte)) { return Convert.ToByte(val); }
            else if (type == typeof(ushort)) { return Convert.ToUInt16(val); }
            else if (type == typeof(uint)) { return Convert.ToUInt32(val); }
            else if (type == typeof(ulong)) { return Convert.ToUInt64(val); }
            else if (type == typeof(string)) { return Convert.ToString(val); }

            ws.AddError("Cannot convert '" + val + "' to " + type);
            return null;
        }
예제 #9
0
 public static Type ToType(this IStatement type, WalkState ws)
 {
     var t = type.GetType();
     if (t == typeof(Array))
     {
         var ar = type as Array;
         var at = ar.Type.ToType(ws);
         if (ar.Dimensions == 1) { return at.MakeArrayType(); }
         return at.MakeArrayType(ar.Dimensions);
     }
     else if (t == typeof(Identifier))
     {
         var id = type as Identifier;
         switch (id.ToString())
         {
             case "any":
                 return typeof(object);
             case "bool":
                 return typeof(bool);
             case "char":
                 return typeof(char);
             case "f32":
                 return typeof(float);
             case "f64":
                 return typeof(double);
             case "i8":
                 return typeof(sbyte);
             case "i16":
                 return typeof(short);
             case "i32":
                 return typeof(int);
             case "i64":
                 return typeof(long);
             case "string":
                 return typeof(string);
             case "u8":
                 return typeof(byte);
             case "u16":
                 return typeof(ushort);
             case "u32":
                 return typeof(uint);
             case "u64":
                 return typeof(ulong);
             default:
                 ws.AddError("Unknown type string '" + id.ToString() + "'");
                 return null;
         }
     }
     ws.AddError("Unknown type '" + t + "' encountered.");
     return null;
 }
예제 #10
0
파일: AST.cs 프로젝트: defiant00/minet-net
        public void GenFunctionBody(WalkState ws)
        {
            var il = MethodBuilder.GetILGenerator();
            foreach (var s in Statements)
            {
                var t = s.GetType();
                if (t == typeof(ExprStmt))
                {
                    var es = s as ExprStmt;
                    var el = es.Expr as ExprList;
                    if (el.Expressions.Count > 1)
                    {
                        ws.AddError("Cannot have more than a single expression as a statement.");
                    }
                    else
                    {
                        var et = el.Expressions[0].GetType();
                        if (et == typeof(FunctionCall))
                        {
                            var fn = el.Expressions[0] as FunctionCall;
                            // TODO - Function call
                        }
                        else
                        {
                            ws.AddError(et + " is not valid for a statement.");
                        }
                    }
                }
                else if (t == typeof(Return))
                {
                    var r = s as Return;
                    if (r.Vals != null)
                    {
                        var el = r.Vals as ExprList;
                        for (int i = 1; i < el.Expressions.Count; i++)
                        {
                            // TODO - multiple return values
                        }
                        el.Expressions[0].Emit(il, ws);
                    }
                    il.Emit(OpCodes.Ret);
                }
                else
                {
                    ws.AddError("Invalid method instruction " + t);
                }
            }

            // If no commands have been emitted, emit a single return.
            if (il.ILOffset == 0) { il.Emit(OpCodes.Ret); }
        }