Beispiel #1
0
 public static void Add(string name, FunctionPrototype prototype)
 {
     if (functions_.ContainsKey(name))
     {
         throw new Exception(string.Format("Function \"{0}\" already declared!", name));
     }
     functions_.Add(name, prototype);
 }
Beispiel #2
0
        public SILFunction(string name, ISILObject[] parameters)
        {
            FunctionPrototype prototype = FunctionTable.Get(name);

            //vlaidate
            if (parameters.Length != prototype.ParameterTypes.Length)
            {
                throw new Exception(string.Format("Function \"{0}\" has incorrect number of parameters!", name));
            }
            //for (int i = 0; i < parameters.Length; i++)
            //{
            //    if (parameters[i].Type != prototype.ParameterTypes[i])
            //        throw new Exception(
            //            string.Format("Function \"{0}\" has incorrect type of parameter #{1}, {2} expected!",
            //            name, i, Enum.GetName(typeof(ObjectType), prototype.ParameterTypes[i])));
            //}

            name_       = name;
            parameters_ = parameters;
        }
Beispiel #3
0
        /// <summary>
        /// Compile the whole program. Compile does not execute the program, it only parses
        /// program text and stores it into SILple commands fastly accessible at execution time.
        /// It has to be called prior to execution.
        /// </summary>
        /// <param name="text">The full program text</param>
        public static void Compile(string text)
        {
            FunctionTable.Clear();
            FunctionPrototype prototype = new FunctionPrototype();

            prototype.Actions        = null;
            prototype.ParameterTypes = new ObjectType[] { };
            prototype.ReturnType     = ObjectType.Void;
            FunctionTable.Add("Main", prototype);

            SymbolTable.Clear();
            ArrayTable.Arrays.Clear();

            actions_ = Parser.Parse(text, action_OnAction);
            //verify that all functions were defined
            string functionName;

            if (!FunctionTable.IsDefined(out functionName))
            {
                throw new Exception(string.Format("Function \"{0}\" is not defined!", functionName));
            }
        }
Beispiel #4
0
        static ActionType CALL_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber)
        {
            string parameters = unparsedArgs.Substring(5, unparsedArgs.Length - 5);

            if (!parameters.Contains("("))
            {
                throw new Exception("\"(\" Expected!");
            }
            string[] split = parameters.Split(new char[] { '(' }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new SyntaxErrorException();
            }
            string            functionName = split[0];
            FunctionPrototype prototype    = FunctionTable.Get(functionName);

            //Parse parameters & their types
            split[1] = split[1].Trim();
            if (split[1][split[1].Length - 1] != ')')
            {
                throw new Exception("\")\" Expected!");
            }
            split[1] = split[1].Substring(0, split[1].Length - 1);
            string[] split2 = split[1].Split(',');
            if (split2.Length == 1 && split2[0].Trim() == "")
            {
                split2 = new string[] { }
            }
            ;
            if (split2.Length != prototype.ParameterTypes.Length)
            {
                throw new Exception("Incorrect number of arguments!");
            }
            List <ISILObject> functionParameters = new List <ISILObject>();

            for (int i = 0; i < split2.Length; i++)
            {
                string parameter_s = split2[i].Trim();
                if (parameter_s == "")
                {
                    throw new Exception(string.Format("Missing parameter type and name for argument #{0}!", i));
                }
                ISILObject parameter;
                if (SIL_Math.IsEquation(parameter_s))
                {
                    parameter = ExpressionParse(functionspace, parameter_s, new List <ISILObject>());
                }
                else
                {
                    parameter = Retrieve_SIL_Object(functionspace, parameter_s, null);
                }

                if ((prototype.ParameterTypes[i] == ObjectType.Array && parameter.Type != ObjectType.Array) ||
                    (prototype.ParameterTypes[i] == ObjectType.Integer && parameter.Type == ObjectType.Array))
                {
                    throw new Exception(
                              string.Format("Incorrect type of parameter #{0}, {1} expexted!",
                                            i, Enum.GetName(typeof(ObjectType), prototype.ParameterTypes[i])));
                }
                functionParameters.Add(parameter);
            }

            SILFunction function = new SILFunction(functionName, functionParameters.ToArray());

            parsedArgs = new object[] { function };
            return(ActionType.CALL);
        }
Beispiel #5
0
        static ActionType FUNCTION_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber)
        {
            Queue <SIL_Action> actions = new Queue <SIL_Action>();

            //FUNCTION MyFunction(INTEGER x, ARRAY y)
            string parameters = unparsedArgs.Substring(9, unparsedArgs.Length - 9);

            if (!parameters.Contains("("))
            {
                throw new Exception("\"(\" Expected!");
            }
            string[] split = parameters.Split(new char[] { '(' }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new SyntaxErrorException();
            }
            string            functionName = split[0];
            FunctionPrototype prototype    = FunctionTable.Get(functionName);

            //Parse parameters & their types
            split[1] = split[1].Trim();
            if (split[1][split[1].Length - 1] != ')')
            {
                throw new Exception("\")\" Expected!");
            }
            split[1] = split[1].Substring(0, split[1].Length - 1);
            string[] split2 = split[1].Split(',');
            if (split2.Length == 1 && split2[0].Trim() == "")
            {
                split2 = new string[] { }
            }
            ;
            if (split2.Length != prototype.ParameterTypes.Length)
            {
                throw new Exception("Incorrect number of arguments!");
            }
            List <string> paramNames = new List <string>();

            for (int i = 0; i < split2.Length; i++)
            {
                split2[i] = split2[i].Trim();
                if (split2[i] == "")
                {
                    throw new Exception(string.Format("Missing parameter type and name for argument #{0}!", i));
                }
                if (!split2[i].Contains(" "))
                {
                    throw new Exception(string.Format("Missing parameter type or name for argument #{0}!", i));
                }
                string[] split3 = split2[i].Split(' ');
                if (split3.Length != 2)
                {
                    throw new SyntaxErrorException();
                }
                string parameterType_s = split3[0].Trim();
                string parameterName   = split3[1].Trim();
                paramNames.Add(parameterName);
                ObjectType parameterType;
                switch (parameterType_s)
                {
                case "INTEGER":
                    parameterType = ObjectType.Integer;
                    break;

                case "ARRAY":
                    parameterType = ObjectType.Array;
                    break;

                default:
                    throw new Exception(
                              string.Format("\"{0}\" is not a supported parameter type, only INTEGER and ARRAY are supported!",
                                            parameterType_s));
                }
                if (parameterType != prototype.ParameterTypes[i])
                {
                    throw new Exception(
                              string.Format("Incorrect type of parameter #{0}, {1} expexted!",
                                            i, Enum.GetName(typeof(ObjectType), prototype.ParameterTypes[i])));
                }
            }

            SIL_Action action;

            do
            {
                lineNumber++;
                if (lineNumber >= sourceLines_.Length)
                {
                    throw new Exception("ENDFUNCTION expected!");
                }
                action = ParseNext(functionName, ref lineNumber);
                if (action.ActionType == ActionType.FUNCTION)
                {
                    throw new Exception("ENDFUNCTION expected!");
                }
                if (action != null)
                {
                    actions.Enqueue(action);
                }
            } while (action.ActionType != ActionType.ENDFUNCTION);

            prototype.Actions    = actions.ToArray();
            prototype.ParamNames = paramNames.ToArray();

            return(ActionType.FUNCTION);
        }
Beispiel #6
0
        static ActionType DECLARE_Parse(string functionspace, string unparsedArgs, ref object[] parsedArgs, ref int lineNumber)
        {
            //DECLARE FUNCTION testFunction(INTEGER x, ARRAY arr) AS INTEGER
            string parameters = unparsedArgs.Substring(8, unparsedArgs.Length - 8);

            if (parameters.Substring(0, 9) != "FUNCTION ")
            {
                throw new Exception("FUNCTION keyword expected!");
            }
            parameters = parameters.Substring(9, parameters.Length - 9);
            string functionName = "";

            for (int i = 0; i < parameters.Length; i++)
            {
                if (parameters[i] != '(')
                {
                    functionName += parameters[i];
                }
                else
                {
                    parameters = parameters.Substring(i + 1, parameters.Length - i - 1);
                    break;
                }
                if (i == parameters.Length - 1)
                {
                    throw new Exception("\"(\" expected!");
                }
            }
            if (!parameters.Contains(')'))
            {
                throw new Exception("\")\" expected!");
            }
            string[] split = parameters.Split(new char[] { ')' }, StringSplitOptions.RemoveEmptyEntries);
            if (split[split.Length - 1].Length < 4)
            {
                throw new Exception("Syntax error!");
            }
            if (split[split.Length - 1].Substring(0, 4) != " AS ")
            {
                throw new Exception("AS expected!");
            }
            //Get return type
            string returnType_s = split[split.Length - 1].Substring(4, split[split.Length - 1].Length - 4);

            if (returnType_s.Length == 0)
            {
                throw new Exception("Missing type! Must be integer, array, or void!");
            }
            ObjectType returnType = ObjectType.Void;

            switch (returnType_s)
            {
            case "INTEGER":
                returnType = ObjectType.Integer;
                break;

            case "ARRAY":
                returnType = ObjectType.Array;
                break;

            case "VOID":
                returnType = ObjectType.Void;
                break;

            default:
                throw new Exception(
                          string.Format("Incorrect return type \"{0}\"! Must be integer, array, or void!",
                                        split[1]));
            }
            //Get Parameter Types
            ObjectType[] parameterTypes = new ObjectType[] {};
            if (split.Length == 2)
            {
                string[] parameterTypes_s = split[0].Split(',');
                parameterTypes = new ObjectType[parameterTypes_s.Length];
                for (int i = 0; i < parameterTypes_s.Length; ++i)
                {
                    parameterTypes_s[i] = parameterTypes_s[i].Trim();
                    switch (parameterTypes_s[i])
                    {
                    case "INTEGER":
                        parameterTypes[i] = ObjectType.Integer;
                        break;

                    case "ARRAY":
                        parameterTypes[i] = ObjectType.Array;
                        break;

                    case "VOID":
                        parameterTypes[i] = ObjectType.Void;
                        break;

                    default:
                        throw new Exception(
                                  string.Format("Incorrect parameter type \"{0}\"! Must be integer, array, or void!",
                                                parameterTypes_s[1]));
                    }
                }
            }

            FunctionPrototype prototype = new FunctionPrototype();

            prototype.Actions        = null;
            prototype.ParameterTypes = parameterTypes;
            prototype.ReturnType     = returnType;
            FunctionTable.Add(functionName, prototype);

            return(ActionType.DECLARE);
        }