Esempio n. 1
0
        public static PebbleList AllocateListNum(ExecContext context, string debugName = "(List<num> inst)")
        {
            if (null == _listClassDef)
            {
                _listClassDef = context.GetClass("List<num>");
            }
            PebbleList listinst = (PebbleList)_listClassDef.childAllocator();

            listinst.classDef  = _listClassDef;
            listinst.debugName = debugName;
            return(listinst);
        }
Esempio n. 2
0
        public static void Register(Engine engine)
        {
            // *** Register required types.

            List <ITypeDef> genericTypes = new ArgList();

            genericTypes.Add(IntrinsicTypeDefs.STRING);

            // This code makes sure that Result<string> is a registered class and type.
            TypeDef_Class resultTypeDef  = TypeFactory.GetTypeDef_Class("Result", genericTypes, false);
            ClassDef      resultClassDef = engine.defaultContext.RegisterIfUnregisteredTemplate(resultTypeDef);

            // This does List<string>.
            ClassDef listStringClassDef = engine.defaultContext.RegisterIfUnregisteredList(IntrinsicTypeDefs.STRING);

            // ***

            //@ class File
            TypeDef_Class ourType  = TypeFactory.GetTypeDef_Class("File", null, false);
            ClassDef      classDef = engine.defaultContext.CreateClass("File", ourType, null, null, true);

            classDef.Initialize();

            //@ const string lastError;
            //   Stores the message of the last error generated by this library.
            classDef.AddMemberLiteral("lastError", IntrinsicTypeDefs.CONST_STRING, "", true);

            Variable lastErrorVar = null;

            //@ static string ClearLastError()
            //   Clears File::lastError, returning its previous value.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string lastError = (string)lastErrorVar.value;
                    lastErrorVar.value = "";
                    return(lastError);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.STRING, new ArgList {
                }, eval, false);
                classDef.AddMemberLiteral("ClearLastError", newValue.valType, newValue, true);
            }

            //@ static bool Copy(string source, string dest)
            //   Copies a file from source to dest.
            //   Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string source = (string)args[0];
                    string dest   = (string)args[1];

                    lastErrorVar.value = "";

                    try {
                        File.Copy(source, dest);
                    } catch (Exception e) {
                        lastErrorVar.value = "Copy: " + e.ToString();
                        return(false);
                    }
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING, IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Copy", newValue.valType, newValue, true);
            }

            //@ static bool CreateDir(string path)
            //   Creates directory.
            //   Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    lastErrorVar.value = "";

                    // Doesn't throw exceptions.
                    if (Directory.Exists(path))
                    {
                        lastErrorVar.value = "CreateDir: Directory already exists.";
                        return(false);
                    }

                    try {
                        Directory.CreateDirectory(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "CreateDir: " + e.ToString();
                        return(false);
                    }
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("CreateDir", newValue.valType, newValue, true);
            }

            //@ static bool Delete(string path)
            //   Returns true if file deleted.
            //   Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    // Doesn't throw exceptions.
                    if (!File.Exists(path))
                    {
                        lastErrorVar.value = "Delete: File not found.";
                        return(false);
                    }

                    try {
                        File.Delete(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "Delete: " + e.ToString();
                        return(false);
                    }

                    lastErrorVar.value = "";
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Delete", newValue.valType, newValue, true);
            }

            //@ static bool DeleteDir(string path)
            //   Returns true if file deleted.
            //   Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    // Doesn't throw exceptions.
                    if (!Directory.Exists(path))
                    {
                        lastErrorVar.value = "DeleteDir: Directory not found.";
                        return(false);
                    }

                    try {
                        Directory.Delete(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "DeleteDir: " + e.ToString();
                        return(false);
                    }

                    lastErrorVar.value = "";
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("DeleteDir", newValue.valType, newValue, true);
            }

            //@ static string GetCurrentDirectory()
            //   Returns the full path of the current directory.
            //   Returns "" and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string result;
                    try {
                        result = Directory.GetCurrentDirectory();
                    } catch (Exception e) {
                        lastErrorVar.value = "GetCurrentDirectory: " + e.ToString();
                        return("");
                    }

                    lastErrorVar.value = "";
                    return(result);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.STRING, new ArgList {
                }, eval, false);
                classDef.AddMemberLiteral("GetCurrentDirectory", newValue.valType, newValue, true);
            }

            //@ static List<string> GetDirs(string path)
            //   Returns list of subdirectories of path.
            //   Returns null and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    // Doesn't throw exceptions.
                    if (!Directory.Exists(path))
                    {
                        lastErrorVar.value = "GetDirs: Directory not found.";
                        return(null);
                    }

                    string[] files;
                    try {
                        files = Directory.GetDirectories(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "GetDirs: " + e.ToString();
                        return(null);
                    }

                    ClassValue inst = listStringClassDef.Allocate(context);
                    inst.debugName = "(GetDirs result)";

                    PebbleList list = (PebbleList)inst;
                    foreach (string file in files)
                    {
                        list.list.Add(new Variable(null, IntrinsicTypeDefs.STRING, file));
                    }

                    lastErrorVar.value = "";
                    return(inst);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.LIST_STRING, new List <ITypeDef> {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("GetDirs", newValue.valType, newValue, true);
            }

            //@ static List<string> GetFiles(string path)
            //   Returns list of all files in the given directory path.
            //   Filenames are NOT prefaced by path.
            //   Returns null and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    if (!Directory.Exists(path))
                    {
                        lastErrorVar.value = "GetFiles: Directory not found.";
                        return(null);
                    }

                    string[] files;
                    try {
                        files = Directory.GetFiles(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "GetFiles: " + e.ToString();
                        return(null);
                    }

                    ClassValue inst = listStringClassDef.Allocate(context);
                    inst.debugName = "(GetFiles result)";

                    PebbleList list    = (PebbleList)inst;
                    int        pathLen = path.Length + 1;
                    foreach (string file in files)
                    {
                        string justFile = file.Substring(pathLen);
                        list.list.Add(new Variable(null, IntrinsicTypeDefs.STRING, justFile));
                    }

                    lastErrorVar.value = "";
                    return(inst);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.LIST_STRING, new List <ITypeDef> {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("GetFiles", newValue.valType, newValue, true);
            }

            //@ static bool Exists(string path)
            //   Returns true if file exists, false if it doesn't.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    // Doesn't throw exceptions.
                    return(File.Exists(path));
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Exists", newValue.valType, newValue, true);
            }

            //@ static bool Move(string source, string dest)
            //   Move a file from source to dest.
            //   Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string source = (string)args[0];
                    string dest   = (string)args[1];

                    lastErrorVar.value = "";

                    try {
                        File.Move(source, dest);
                    } catch (Exception e) {
                        lastErrorVar.value = "Move: " + e.ToString();
                        return(false);
                    }
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING, IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Move", newValue.valType, newValue, true);
            }

            //@ static Result<string> Read(string path)
            //   Reads content of file as text. Returns an instance of Result<string>.
            //	 If succeeded, status = 0, value = file contents.
            //	 On error, status != 0, message = an error message.
            {
                // Note that this function cannot use lastError because strings cannot be null.
                // This is why ReadLines can just return a List<string>: the list can indicate error by being null.

                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    //ClassValue inst = resultClassDef.childAllocator();
                    ClassValue inst    = resultClassDef.Allocate(context);
                    Variable   status  = inst.GetByName("status");
                    Variable   value   = inst.GetByName("value");
                    Variable   message = inst.GetByName("message");

                    string result;
                    try {
                        result = File.ReadAllText(path);
                    } catch (Exception e) {
                        status.value  = -1.0;
                        message.value = "Read: " + e.ToString();
                        return(inst);
                    }

                    // The docs don't say this ever returns null, but just in case.
                    if (null == result)
                    {
                        status.value  = -1.0;
                        message.value = "Read: File.ReadAllText returned null.";
                    }

                    value.value = result;
                    return(inst);
                };

                FunctionValue newValue = new FunctionValue_Host(resultClassDef.typeDef, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Read", newValue.valType, newValue, true);
            }

            //@ static List<string> ReadLines(string path)
            //   Returns a list containing the lines of the given file.
            //	 On error, returns null and sets last error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    IEnumerable <string> result;
                    try {
                        // Note: ReadLines is a little more efficient on memory than ReadAllLines, but the .NET used by Unity 2017 doesn't support it.
                        // Shouldn't really matter. If you're processing huge files, probably Pebble isn't the way to go.
                        //result = File.ReadLines(path);
                        result = File.ReadAllLines(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "ReadLines: " + e.ToString();
                        return(null);
                    }

                    // The docs don't say this ever returns null, but just in case.
                    if (null == result)
                    {
                        lastErrorVar.value = "ReadLines: File.ReadLines returned null.";
                        return(null);
                    }

                    ClassDef   listClassDef = context.GetClass("List<string>");
                    ClassValue listinst     = listClassDef.childAllocator();
                    listinst.classDef  = listClassDef;
                    listinst.debugName = "(ReadLines result)";
                    PebbleList list = (PebbleList)listinst;

                    foreach (string line in result)
                    {
                        list.list.Add(new Variable(null, IntrinsicTypeDefs.STRING, line));
                    }

                    lastErrorVar.value = "";
                    return(listinst);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.LIST_STRING, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("ReadLines", newValue.valType, newValue, true);
            }

            //@ static bool SetCurrentDirectory(string newDir)
            //   Changes the current directory. Returns true on success.
            //	 Returns false and sets lastError on error.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path = (string)args[0];

                    try {
                        Directory.SetCurrentDirectory(path);
                    } catch (Exception e) {
                        lastErrorVar.value = "SetCurrentDirectory: " + e.ToString();
                        return(false);
                    }
                    lastErrorVar.value = "";
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("SetCurrentDirectory", newValue.valType, newValue, true);
            }

            //@ static bool Write(string path, string contents)
            //   Writes contents to file. If file exists it is overwritten.
            //	 Returns true on success.
            //	 On error returns false and sets lastError.
            {
                FunctionValue_Host.EvaluateDelegate eval = (context, args, thisScope) => {
                    string path     = (string)args[0];
                    string contents = (string)args[1];

                    try {
                        File.WriteAllText(path, contents);
                    } catch (Exception e) {
                        lastErrorVar.value = "Write: " + e.ToString();
                        return(false);
                    }
                    lastErrorVar.value = "";
                    return(true);
                };

                FunctionValue newValue = new FunctionValue_Host(IntrinsicTypeDefs.BOOL, new ArgList {
                    IntrinsicTypeDefs.STRING, IntrinsicTypeDefs.STRING
                }, eval, false);
                classDef.AddMemberLiteral("Write", newValue.valType, newValue, true);
            }

            classDef.FinalizeClass(engine.defaultContext);
            lastErrorVar = classDef.staticVars[0];

            UnitTests.testFuncDelegates.Add("FileLib", RunTests);
        }