Changeset 343
- Timestamp:
- 08/22/08 09:44:18 (3 months ago)
- Files:
-
- branches/v2new/minid/api.d (modified) (2 diffs)
- branches/v2new/minid/charlib.d (modified) (3 diffs)
- branches/v2new/minid/interpreter.d (modified) (1 diff)
- branches/v2new/minid/parser.d (modified) (1 diff)
- branches/v2new/minid/vm.d (modified) (1 diff)
- branches/v2new/samples/simple.md (modified) (1 diff)
- branches/v2new/test.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/v2new/minid/api.d
r342 r343 42 42 43 43 import minid.baselib; 44 import minid.charlib; 44 45 45 46 // ================================================================================================================================================ … … 99 100 100 101 /** 102 This enumeration is used with the NewContext function to specify which standard libraries you 103 want to load into the new context. The base library is always loaded, so there is no 104 flag for it. You can choose which libraries you want to load by ORing together multiple 105 flags. 106 */ 107 public enum MDStdlib 108 { 109 /** 110 Nothing but the base library will be loaded if you specify this flag. 111 */ 112 None = 0, 113 114 /** 115 Array manipulation. 116 */ 117 Array = 1, 118 119 /** 120 Character classification. 121 */ 122 Char = 2, 123 124 /** 125 Stream-based input and output. 126 */ 127 IO = 4, 128 129 /** 130 Standard math functions. 131 */ 132 Math = 8, 133 134 /** 135 String manipulation. 136 */ 137 String = 16, 138 139 /** 140 Table manipulation. 141 */ 142 Table = 32, 143 144 /** 145 OS-specific functionality. 146 */ 147 OS = 64, 148 149 /** 150 Regular expressions. 151 */ 152 Regexp = 128, 153 154 /** 155 This flag is an OR of Array, Char, Math, String, Table, and Regexp. It represents all 156 the libraries which are "safe", i.e. malicious scripts would not be able to use the IO 157 or OS libraries to do bad things. 158 */ 159 Safe = Array | Char | Math | String | Table | Regexp, 160 161 /** 162 All available standard libraries. 163 */ 164 All = Safe | IO | OS, 165 } 166 167 /** 168 Load the standard libraries into the context of the given thread. 169 170 Params: 171 libs = An ORing together of any standard libraries you want to load (see the MDStdlib enum). 172 Defaults to MDStdlib.All. 173 */ 174 public void loadStdlibs(MDThread* t, uint libs = MDStdlib.All) 175 { 176 // if(libs & MDStdlib.Array) 177 // ArrayLib.init(ret); 178 179 if(libs & MDStdlib.Char) 180 CharLib.init(t); 181 182 // if(libs & MDStdlib.IO) 183 // IOLib.init(ret); 184 // 185 // if(libs & MDStdlib.Math) 186 // MathLib.init(ret); 187 // 188 // if(libs & MDStdlib.OS) 189 // OSLib.init(ret); 190 // 191 // if(libs & MDStdlib.Regexp) 192 // RegexpLib.init(ret); 193 // 194 // if(libs & MDStdlib.String) 195 // StringLib.init(ret); 196 // 197 // if(libs & MDStdlib.Table) 198 // TableLib.init(ret); 199 } 200 201 /** 101 202 Closes a VM object and deallocates all memory associated with it. 102 203 branches/v2new/minid/charlib.d
r278 r343 1 1 /****************************************************************************** 2 2 License: 3 Copyright (c) 200 7Jarrett Billingsley3 Copyright (c) 2008 Jarrett Billingsley 4 4 5 5 This software is provided 'as-is', without any express or implied warranty. … … 24 24 module minid.charlib; 25 25 26 import minid.ex; 27 import minid.interpreter; 26 28 import minid.types; 27 29 … … 29 31 import Uni = tango.text.Unicode; 30 32 31 final classCharLib33 struct CharLib 32 34 { 33 35 static: 34 public void init(MD Context context)36 public void init(MDThread* t) 35 37 { 36 auto methods = new MDNamespace("char"d, context.globals.ns); 37 38 methods.addList 39 ( 40 "toLower"d, new MDClosure(methods, &toLower, "char.toLower"), 41 "toUpper"d, new MDClosure(methods, &toUpper, "char.toUpper"), 42 "isAlpha"d, new MDClosure(methods, &isAlpha, "char.isAlpha"), 43 "isAlNum"d, new MDClosure(methods, &isAlNum, "char.isAlNum"), 44 "isLower"d, new MDClosure(methods, &isLower, "char.isLower"), 45 "isUpper"d, new MDClosure(methods, &isUpper, "char.isUpper"), 46 "isDigit"d, new MDClosure(methods, &isDigit, "char.isDigit"), 47 "isCtrl"d, new MDClosure(methods, &isCtrl, "char.isCtrl"), 48 "isPunct"d, new MDClosure(methods, &isPunct, "char.isPunct"), 49 "isSpace"d, new MDClosure(methods, &isSpace, "char.isSpace"), 50 "isHexDigit"d, new MDClosure(methods, &isHexDigit, "char.isHexDigit"), 51 "isAscii"d, new MDClosure(methods, &isAscii, "char.isAscii"), 52 "isValid"d, new MDClosure(methods, &isValid, "char.isValid") 53 ); 54 55 context.setMetatable(MDValue.Type.Char, methods); 38 newNamespace(t, "char"); 39 newFunction(t, &toLower, "char.toLower"); fielda(t, -2, "toLower"); 40 newFunction(t, &toLower, "char.toLower"); fielda(t, -2, "toLower"); 41 newFunction(t, &toUpper, "char.toUpper"); fielda(t, -2, "toUpper"); 42 newFunction(t, &isAlpha, "char.isAlpha"); fielda(t, -2, "isAlpha"); 43 newFunction(t, &isAlNum, "char.isAlNum"); fielda(t, -2, "isAlNum"); 44 newFunction(t, &isLower, "char.isLower"); fielda(t, -2, "isLower"); 45 newFunction(t, &isUpper, "char.isUpper"); fielda(t, -2, "isUpper"); 46 newFunction(t, &isDigit, "char.isDigit"); fielda(t, -2, "isDigit"); 47 newFunction(t, &isCtrl, "char.isCtrl"); fielda(t, -2, "isCtrl"); 48 newFunction(t, &isPunct, "char.isPunct"); fielda(t, -2, "isPunct"); 49 newFunction(t, &isSpace, "char.isSpace"); fielda(t, -2, "isSpace"); 50 newFunction(t, &isHexDigit, "char.isHexDigit"); fielda(t, -2, "isHexDigit"); 51 newFunction(t, &isAscii, "char.isAscii"); fielda(t, -2, "isAscii"); 52 newFunction(t, &isValid, "char.isValid"); fielda(t, -2, "isValid"); 53 setTypeMT(t, MDValue.Type.Char); 56 54 } 57 55 58 int toLower(MDState s, uintnumParams)56 uword toLower(MDThread* t, uword numParams) 59 57 { 60 dchar[1] buf; 61 s.push(s.safeCode(Uni.toLower([s.getContext!(dchar)], buf)[0])); 58 dchar[1] inbuf; 59 dchar[4] outbuf; 60 inbuf[0] = checkCharParam(t, 0); 61 pushChar(t, safeCode(t, Uni.toLower(inbuf, outbuf)[0])); 62 62 return 1; 63 63 } 64 64 65 int toUpper(MDState s, uintnumParams)65 uword toUpper(MDThread* t, uword numParams) 66 66 { 67 dchar[1] buf; 68 s.push(s.safeCode(Uni.toUpper([s.getContext!(dchar)], buf)[0])); 67 dchar[1] inbuf; 68 dchar[4] outbuf; 69 inbuf[0] = checkCharParam(t, 0); 70 pushChar(t, safeCode(t, Uni.toUpper(inbuf, outbuf)[0])); 69 71 return 1; 70 72 } 71 73 72 int isAlpha(MDState s, uintnumParams)74 uword isAlpha(MDThread* t, uword numParams) 73 75 { 74 s.push(Uni.isLetter(s.getContext!(dchar)));76 pushBool(t, Uni.isLetter(checkCharParam(t, 0))); 75 77 return 1; 76 78 } 77 79 78 int isAlNum(MDState s, uintnumParams)80 uword isAlNum(MDThread* t, uword numParams) 79 81 { 80 s.push(Uni.isLetterOrDigit(s.getContext!(dchar))); 81 return 1; 82 } 83 84 int isLower(MDState s, uint numParams) 85 { 86 s.push(Uni.isLower(s.getContext!(dchar))); 82 pushBool(t, Uni.isLetterOrDigit(checkCharParam(t, 0))); 87 83 return 1; 88 84 } 89 85 90 int isUpper(MDState s, uintnumParams)86 uword isLower(MDThread* t, uword numParams) 91 87 { 92 s.push(Uni.isUpper(s.getContext!(dchar)));88 pushBool(t, Uni.isLower(checkCharParam(t, 0))); 93 89 return 1; 94 90 } 95 91 96 int isDigit(MDState s, uintnumParams)92 uword isUpper(MDThread* t, uword numParams) 97 93 { 98 s.push(Uni.isDigit(s.getContext!(dchar)));94 pushBool(t, Uni.isUpper(checkCharParam(t, 0))); 99 95 return 1; 100 96 } 101 97 102 int isCtrl(MDState s, uintnumParams)98 uword isDigit(MDThread* t, uword numParams) 103 99 { 104 s.push(cast(bool)iscntrl(s.getContext!(dchar)));100 pushBool(t, Uni.isDigit(checkCharParam(t, 0))); 105 101 return 1; 106 102 } 107 108 int isPunct(MDState s, uintnumParams)103 104 uword isCtrl(MDThread* t, uword numParams) 109 105 { 110 s.push(cast(bool)ispunct(s.getContext!(dchar)));106 pushBool(t, cast(bool)iscntrl(checkCharParam(t, 0))); 111 107 return 1; 112 108 } 113 114 int isSpace(MDState s, uintnumParams)109 110 uword isPunct(MDThread* t, uword numParams) 115 111 { 116 s.push(cast(bool)isspace(s.getContext!(dchar)));112 pushBool(t, cast(bool)ispunct(checkCharParam(t, 0))); 117 113 return 1; 118 114 } 119 120 int isHexDigit(MDState s, uintnumParams)115 116 uword isSpace(MDThread* t, uword numParams) 121 117 { 122 s.push(cast(bool)isxdigit(s.getContext!(dchar)));118 pushBool(t, cast(bool)isspace(checkCharParam(t, 0))); 123 119 return 1; 124 120 } 125 126 int isAscii(MDState s, uintnumParams)121 122 uword isHexDigit(MDThread* t, uword numParams) 127 123 { 128 s.push(s.getContext!(dchar) <= 0x7f);124 pushBool(t, cast(bool)isxdigit(checkCharParam(t, 0))); 129 125 return 1; 130 126 } 131 132 int isValid(MDState s, uintnumParams)127 128 uword isAscii(MDThread* t, uword numParams) 133 129 { 134 auto c = s.getContext!(dchar); 135 s.push(c < 0xD800 || (c > 0xDFFF && c <= 0x10FFFF)); 130 pushBool(t, checkCharParam(t, 0) <= 0x7f); 131 return 1; 132 } 133 134 uword isValid(MDThread* t, uword numParams) 135 { 136 auto c = checkCharParam(t, 0); 137 pushBool(t, c < 0xD800 || (c > 0xDFFF && c <= 0x10FFFF)); 136 138 return 1; 137 139 } branches/v2new/minid/interpreter.d
r342 r343 2809 2809 2810 2810 return stackSize(t) - 1; 2811 } 2812 2813 /** 2814 An odd sort of protective function. You can use this function to wrap a call to a library function etc. which 2815 could throw an exception, but when you don't want to have to bother with catching the exception yourself. Useful 2816 for writing native MiniD libraries. 2817 2818 Say you had a function which opened a file: 2819 2820 ----- 2821 File f = OpenFile("filename"); 2822 ----- 2823 2824 Say this function could throw an exception if it failed. Since the interpreter can only catch (and make meaningful 2825 stack traces about) exceptions which derive from MDException, any exceptions that this throws would just percolate 2826 up out of the interpreter stack. You could catch the exception yourself, but that's kind of tedious, especially when 2827 you call a lot of native functions. 2828 2829 Instead, you can wrap the call to this unsafe function with a call to safeCode(). 2830 2831 ----- 2832 File f = safeCode(t, OpenFile("filename")); 2833 ----- 2834 2835 What safeCode() does is it tries to execute the code it is passed. If it succeeds, it simply returns any value that 2836 the code returns. If it throws an exception derived from MDException, it rethrows the exception. And if it throws 2837 an exception that derives from Exception, it throws a new MDException with the original exception's message as the 2838 message. 2839 2840 safeCode() is templated to allow any return value. 2841 2842 Params: 2843 code = The code to be executed. This is a lazy parameter, so it's not actually executed until inside the call to 2844 safeCode. 2845 2846 Returns: 2847 Whatever the code parameter returns. 2848 */ 2849 public T safeCode(T)(MDThread* t, lazy T code) 2850 { 2851 try 2852 return code; 2853 catch(MDException e) 2854 throw e; 2855 catch(Exception e) 2856 throwException(t, "{}", e); 2857 2858 assert(false); 2811 2859 } 2812 2860 branches/v2new/minid/parser.d
r340 r343 2146 2146 2147 2147 if(l.type == Token.True) 2148 { 2149 l.expect(Token.True); 2148 2150 return new(c) BoolExp(c, loc, true); 2151 } 2149 2152 else 2150 2153 { branches/v2new/minid/vm.d
r342 r343 192 192 // ================================================================================================================================================ 193 193 194 // 1. See if already loaded.195 196 // 2. See if that name is taken.197 198 // 3. Look for .md and .mdm. If found, create closure with new namespace env, call.199 // if it succeeds, put that namespace in the owning namespace.200 201 // 4. Look for custom loader. If found, call with name of module to get loader func.202 // call that with new namespace as env, and if it succeeds, put ns in owning ns.203 204 // 5. [Optional] Look for dynlib, same procedure as 4.205 206 194 package void openVMImpl(MDVM* vm, MemFunc memFunc, void* ctx = null) 207 195 { branches/v2new/samples/simple.md
r342 r343 1 1 module simple 2 2 3 writeln(modules.loaders) 4 5 import operator 6 7 writeln(operator.add(3, 4)) 3 8 4 9 5 /+ branches/v2new/test.d
r341 r343 34 34 auto vm = new MDVM; 35 35 auto t = openVM(vm); 36 loadStdlibs(t); 36 37 37 38 // This is all stdlib crap!
