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