Changeset 351
- Timestamp:
- 08/24/08 20:32:09 (3 months ago)
- Files:
-
- branches/v2new/minid/api.d (modified) (4 diffs)
- branches/v2new/minid/interpreter.d (modified) (5 diffs)
- branches/v2new/minid/timelib.d (modified) (7 diffs)
- branches/v2new/samples/simple.md (modified) (1 diff)
- branches/v2new/test.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/v2new/minid/api.d
r350 r351 46 46 import minid.mathlib; 47 47 import minid.stringlib; 48 import minid.timelib; 48 49 49 50 // ================================================================================================================================================ … … 154 155 */ 155 156 Regexp = 128, 156 157 /** 158 This flag is an OR of Array, Char, Math, String, Table, and Regexp. It represents all 159 the libraries which are "safe", i.e. malicious scripts would not be able to use the IO 157 158 /** 159 Time functions. 160 */ 161 Time = 256, 162 163 /** 164 This flag is an OR of Array, Char, Math, String, Table, Regexp, and Time. It represents 165 all the libraries which are "safe", i.e. malicious scripts would not be able to use the IO 160 166 or OS libraries to do bad things. 161 167 */ 162 Safe = Array | Char | Math | String | Table | Regexp ,168 Safe = Array | Char | Math | String | Table | Regexp | Time, 163 169 164 170 /** … … 169 175 170 176 /** 171 Load the standard libraries into the context of the given thread. 177 Load the standard libraries into the context of the given thread. 172 178 173 179 Params: … … 200 206 // if(libs & MDStdlib.Table) 201 207 // TableLib.init(ret); 208 209 if(libs & MDStdlib.Time) 210 TimeLib.init(t); 202 211 } 203 212 branches/v2new/minid/interpreter.d
r350 r351 507 507 508 508 /** 509 Push the given thread onto this thread's stack.509 Pushes the given thread onto this thread's stack. 510 510 511 511 Params: … … 521 521 522 522 /** 523 Push a reference to a native (D) object onto the stack.523 Pushes a reference to a native (D) object onto the stack. 524 524 525 525 Params: … … 536 536 537 537 /** 538 Duplicate a value at the given stack index and pushit onto the stack.538 Duplicates a value at the given stack index and pushes it onto the stack. 539 539 540 540 Params: … … 553 553 554 554 /** 555 Insert the value at the top of the stack into the given _slot, shifting up the values in that _slot 555 Swaps the two values at the given swap indices. The second index defaults to the top-of-stack. 556 557 Params: 558 first = The first stack index. 559 second = The second stack index. 560 */ 561 public void swap(MDThread* t, word first, word second = -1) 562 { 563 auto f = fakeToAbs(t, first); 564 auto s = fakeToAbs(t, second); 565 566 if(f == s) 567 return; 568 569 auto tmp = t.stack[f]; 570 t.stack[f] = t.stack[s]; 571 t.stack[s] = tmp; 572 } 573 574 /** 575 Inserts the value at the top of the stack into the given _slot, shifting up the values in that _slot 556 576 and everything after it up by a _slot. This means the stack will stay the same size. Similar to a 557 577 "rotate" operation common to many stack machines. … … 605 625 606 626 /** 607 Pop a number of items off the stack. Throws an error if you try to pop more items than there are627 Pops a number of items off the stack. Throws an error if you try to pop more items than there are 608 628 on the stack. 'this' is not counted; so if there is 'this' and one value, and you try to pop 2 609 629 values, an error is thrown. branches/v2new/minid/timelib.d
r305 r351 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.timelib; 25 25 26 import tango.text.locale.Convert; 27 import tango.text.locale.Core; 28 import tango.time.chrono.Gregorian; 29 import tango.time.Clock; 30 import tango.time.StopWatch; 31 import tango.time.Time; 32 import tango.time.WallClock; 33 import Utf = tango.text.convert.Utf; 34 35 import minid.ex; 36 import minid.interpreter; 26 37 import minid.types; 27 38 import minid.utils; 28 29 import tango.text.locale.Convert;30 import tango.text.locale.Core;31 import tango.time.Clock;32 import tango.time.Time;33 import tango.time.StopWatch;34 import tango.time.WallClock;35 import tango.time.chrono.Gregorian;36 39 37 40 version(Windows) … … 47 50 static assert(false, "No valid platform defined"); 48 51 49 final classTimeLib52 struct TimeLib 50 53 { 51 54 static: 52 private MDValue YearString; 53 private MDValue MonthString; 54 private MDValue DayString; 55 private MDValue HourString; 56 private MDValue MinString; 57 private MDValue SecString; 58 version(Windows) ulong performanceFreq; 59 60 static this() 61 { 62 YearString = new MDString("year"d); 63 MonthString = new MDString("month"d); 64 DayString = new MDString("day"d); 65 HourString = new MDString("hour"d); 66 MinString = new MDString("min"d); 67 SecString = new MDString("sec"d); 68 69 version(Windows) 55 version(Windows) 56 { 57 ulong performanceFreq; 58 59 static this() 70 60 { 71 61 if(!QueryPerformanceFrequency(&performanceFreq)) … … 74 64 } 75 65 76 public void init(MDContext context) 77 { 78 context.setModuleLoader("time", context.newClosure(function int(MDState s, uint numParams) 79 { 80 auto perfCounterClass = new MDPerfCounterClass(s.context.globals.get!(MDObject)("Object"d)); 81 82 auto lib = s.getParam!(MDNamespace)(1); 83 84 lib.addList 85 ( 86 "PerfCounter"d, perfCounterClass, 87 "microTime"d, new MDClosure(lib, µTime, "times.microTime"), 88 "dateString"d, new MDClosure(lib, &dateString, "time.dateString"), 89 "dateTime"d, new MDClosure(lib, &dateTime, "time.dateTime"), 90 "culture"d, new MDClosure(lib, &culture, "time.culture"), 91 "timestamp"d, new MDClosure(lib, ×tamp, "time.timestamp") 92 ); 66 public void init(MDThread* t) 67 { 68 pushGlobal(t, "modules"); 69 field(t, -1, "customLoaders"); 70 71 newFunction(t, function uword(MDThread* t, uword numParams) 72 { 73 Timer.init(t); 74 newFunction(t, µTime, "microTime"); newGlobal(t, "microTime"); 75 newFunction(t, &dateString, "dateString"); newGlobal(t, "dateString"); 76 newFunction(t, &dateTime, "dateTime"); newGlobal(t, "dateTime"); 77 newFunction(t, &culture, "culture"); newGlobal(t, "culture"); 78 newFunction(t, ×tamp, "timestamp"); newGlobal(t, "timestamp"); 93 79 94 80 return 0; 95 }, "time")); 96 97 context.importModule("time"); 98 } 99 100 int microTime(MDState s, uint numParams) 81 }, "time"); 82 83 fielda(t, -2, "time"); 84 pop(t); 85 86 importModule(t, "time"); 87 } 88 89 uword microTime(MDThread* t, uword numParams) 101 90 { 102 91 version(Windows) … … 104 93 ulong time; 105 94 QueryPerformanceCounter(&time); 106 95 107 96 if(time < 0x8637BD05AF6L) 108 s.push((time * 1_000_000) / performanceFreq);97 pushInt(t, cast(mdint)((time * 1_000_000) / performanceFreq)); 109 98 else 110 s.push((time / performanceFreq) * 1_000_000);99 pushInt(t, cast(mdint)((time / performanceFreq) * 1_000_000)); 111 100 } 112 101 else … … 114 103 timeval tv; 115 104 gettimeofday(&tv, null); 116 s.push(tv.tv_sec * 1_000_000L + tv.tv_usec); 117 } 118 119 return 1; 120 } 121 122 int dateString(MDState s, uint numParams) 123 { 124 Time time; 125 char[40] buffer; 126 char[] format = "G"; 127 Culture culture = null; 128 129 if(numParams > 0) 130 format = s.getParam!(char[])(0); 131 132 if(numParams > 1 && !s.isParam!("null")(1)) 133 time = TableToTime(s, s.getParam!(MDTable)(1)); 105 pushInt(t, cast(mdint)(tv.tv_sec * 1_000_000L + tv.tv_usec)); 106 } 107 108 return 1; 109 } 110 111 uword dateString(MDThread* t, uword numParams) 112 { 113 char[] format = numParams > 0 ? GetFormat(t, 1) : "G"; 114 115 Time time = void; 116 117 if(numParams > 1 && !isNull(t, 2)) 118 time = TableToTime(t, 2); 134 119 else if(format == "R") 135 120 time = Clock.now; … … 137 122 time = WallClock.now; 138 123 124 Culture culture = null; 125 139 126 if(numParams > 2) 140 culture = s.safeCode(Culture.getCulture(s.getParam!(char[])(2))); 141 142 s.push(s.safeCode(formatDateTime(buffer, time, format, culture))); 143 return 1; 144 } 145 146 int dateTime(MDState s, uint numParams) 127 { 128 char[24] buf = void; 129 auto name = StrToCulture(t, 1, buf); 130 culture = safeCode(t, Culture.getCulture(name)); 131 } 132 133 char[40] buffer; 134 auto ret = safeCode(t, formatDateTime(buffer, time, format, culture)); 135 136 dchar[40] outbuf; 137 uint ate = 0; 138 pushString(t, Utf.toString32(ret, outbuf, &ate)); 139 return 1; 140 } 141 142 uword dateTime(MDThread* t, uword numParams) 147 143 { 148 144 bool useGMT = false; 149 MDTable t = null; 150 151 if(numParams > 0) 152 { 153 if(s.isParam!("bool")(0)) 145 word tab; 146 147 if(numParams == 0) 148 tab = newTable(t); 149 else if(isBool(t, 1)) 150 { 151 useGMT = getBool(t, 1); 152 153 if(numParams > 1) 154 154 { 155 useGMT = s.getParam!(bool)(0); 156 157 if(numParams > 1) 158 t = s.getParam!(MDTable)(1); 155 checkParam(t, 2, MDValue.Type.Table); 156 tab = 2; 159 157 } 160 158 else 161 t = s.getParam!(MDTable)(0); 162 } 163 164 s.push(DateTimeToTable(s, useGMT ? Clock.toDate : WallClock.toDate, t)); 165 return 1; 166 } 167 168 int culture(MDState s, uint numParams) 169 { 170 s.push(Culture.current.name); 159 tab = newTable(t); 160 } 161 else 162 { 163 checkParam(t, 1, MDValue.Type.Table); 164 tab = 1; 165 } 166 167 DateTimeToTable(t, useGMT ? Clock.toDate : WallClock.toDate, tab); 168 dup(t, tab); 169 return 1; 170 } 171 172 uword culture(MDThread* t, uword numParams) 173 { 174 CultureToStr(t, Culture.current.name); 171 175 172 176 if(numParams > 0) 173 Culture.current = s.safeCode(Culture.getCulture(s.getParam!(char[])(0))); 174 175 return 1; 176 } 177 178 Time TableToTime(MDState s, MDTable tab) 179 { 180 MDValue table = MDValue(tab); 181 Time time; 182 183 with(s) 184 { 185 MDValue year = idx(table, YearString); 186 MDValue month = idx(table, MonthString); 187 MDValue day = idx(table, DayString); 188 MDValue hour = idx(table, HourString); 189 MDValue min = idx(table, MinString); 190 MDValue sec = idx(table, SecString); 191 192 if(!year.isInt() || !month.isInt() || !day.isInt()) 193 s.throwRuntimeException("year, month, and day fields in time table must exist and must be integers"); 194 195 if(hour.isInt() && min.isInt() && sec.isInt()) 196 time = Gregorian.generic.toTime(year.as!(int), month.as!(int), day.as!(int), hour.as!(int), min.as!(int), sec.as!(int), 0, 0); 197 else 198 time = Gregorian.generic.toTime(year.as!(int), month.as!(int), day.as!(int), 0, 0, 0, 0, 0); 199 } 177 { 178 char[24] buf = void; 179 auto name = StrToCulture(t, 1, buf); 180 Culture.current = safeCode(t, Culture.getCulture(name)); 181 } 182 183 return 1; 184 } 185 186 // longest possible is 5 chars * 4 bytes per char = 20 bytes? 187 char[] StrToCulture(MDThread* t, word slot, char[24] outbuf) 188 { 189 checkStringParam(t, slot); 190 191 if(len(t, slot) != 5) 192 throwException(t, "Culture name {} is not supported.", getString(t, slot)); 193 194 uint ate = 0; 195 return Utf.toString(getString(t, slot), outbuf, &ate); 196 } 197 198 word CultureToStr(MDThread* t, char[] culture) 199 { 200 // eh, let's be safe.. 201 dchar[8] buf; 202 uint ate = 0; 203 return pushString(t, Utf.toString32(culture, buf, &ate)); 204 } 205 206 char[] GetFormat(MDThread* t, word slot) 207 { 208 switch(checkStringParam(t, slot)) 209 { 210 case "d": return "d"; 211 case "D": return "D"; 212 case "t": return "t"; 213 case "T": return "T"; 214 case "g": return "g"; 215 case "G": return "G"; 216 case "M": return "M"; 217 case "R": return "R"; 218 case "s": return "s"; 219 case "Y": return "Y"; 220 221 default: 222 throwException(t, "invalid format string"); 223 } 224 225 assert(false); 226 } 227 228 Time TableToTime(MDThread* t, word tab) 229 { 230 auto year = field(t, tab, "year"); 231 auto month = field(t, tab, "month"); 232 auto day = field(t, tab, "day"); 233 auto hour = field(t, tab, "hour"); 234 auto min = field(t, tab, "min"); 235 auto sec = field(t, tab, "sec"); 236 237 if(!isInt(t, year) || !isInt(t, month) || !isInt(t, day)) 238 throwException(t, "year, month, and day fields in time table must exist and must be integers"); 239 240 Time time = void; 241 242 if(isInt(t, hour) && isInt(t, min) && isInt(t, sec)) 243 time = Gregorian.generic.toTime(getInt(t, year), getInt(t, month), getInt(t, day), getInt(t, hour), getInt(t, min), getInt(t, sec), 0, 0); 244 else 245 time = Gregorian.generic.toTime(getInt(t, year), getInt(t, month), getInt(t, day), 0, 0, 0, 0, 0); 246 247 pop(t, 6); 200 248 201 249 return time; 202 250 } 203 251 204 MDTable DateTimeToTable(MDState s, DateTime time, MDTable dest) 205 { 206 if(dest is null) 207 dest = new MDTable(); 208 209 MDValue table = dest; 210 211 with(s) 212 { 213 idxa(table, YearString, MDValue(time.date.year)); 214 idxa(table, MonthString, MDValue(time.date.month)); 215 idxa(table, DayString, MDValue(time.date.day)); 216 idxa(table, HourString, MDValue(time.time.hours)); 217 idxa(table, MinString, MDValue(time.time.minutes)); 218 idxa(table, SecString, MDValue(time.time.seconds)); 219 } 220 221 return dest; 222 } 223 224 int timestamp(MDState s, uint numParams) 225 { 226 s.push(cast(int)(Clock.now - Time.epoch1970).seconds); 227 return 1; 228 } 229 230 static class MDPerfCounterClass : MDObject 231 { 232 static class MDPerfCounter : MDObject 252 void DateTimeToTable(MDThread* t, DateTime time, word dest) 253 { 254 // dest = absIndex(t, dest); 255 // 256 // if(isNull(t, dest)) 257 // { 258 // newTable(t); 259 // swap(t, dest); 260 // pop(t); 261 // } 262 // 263 pushInt(t, time.date.year); fielda(t, dest, "year"); 264 pushInt(t, time.date.month); fielda(t, dest, "month"); 265 pushInt(t, time.date.day); fielda(t, dest, "day"); 266 pushInt(t, time.time.hours); fielda(t, dest, "hour"); 267 pushInt(t, time.time.minutes); fielda(t, dest, "min"); 268 pushInt(t, time.time.seconds); fielda(t, dest, "sec"); 269 } 270 271 uword timestamp(MDThread* t, uword numParams) 272 { 273 pushInt(t, cast(mdint)(Clock.now - Time.epoch1970).seconds); 274 return 1; 275 } 276 277 static struct Timer 278 { 279 static: 280 private Members* getThis(MDThread* t) 281 { 282 return checkObjParam!(Members)(t, 0, "Timer"); 283 } 284 285 void init(MDThread* t) 286 { 287 CreateObject(t, "Timer", (CreateObject* o) 288 { 289 o.method("clone", &clone); 290 o.method("start", &start); 291 o.method("stop", &stop); 292 o.method("seconds", &seconds); 293 o.method("millisecs", &millisecs); 294 o.method("microsecs", µsecs); 295 }); 296 297 newGlobal(t, "Timer"); 298 } 299 300 struct Members 233 301 { 234 302 protected StopWatch mWatch; 235 303 protected mdfloat mTime = 0; 236 237 public this(MDObject owner) 238 { 239 super("PerfCounter", owner); 240 } 241 } 242 243 public this(MDObject owner) 244 { 245 super("PerfCounter", owner); 246 247 fields.addList 248 ( 249 "clone"d, new MDClosure(fields, &clone, "PerfCounter.clone"), 250 "start"d, new MDClosure(fields, &start, "PerfCounter.start"), 251 "stop"d, new MDClosure(fields, &stop, "PerfCounter.stop"), 252 "seconds"d, new MDClosure(fields, &seconds, "PerfCounter.seconds"), 253 "millisecs"d, new MDClosure(fields, &millisecs, "PerfCounter.millisecs"), 254 "microsecs"d, new MDClosure(fields, µsecs, "PerfCounter.microsecs") 255 ); 256 } 257 258 public int clone(MDState s, uint numParams) 259 { 260 s.push(new MDPerfCounter(this)); 304 } 305 306 uword clone(MDThread* t, uword numParams) 307 { 308 newObject(t, 0, null, 0, Members.sizeof); 309 *getMembers!(Members)(t, -1) = Members.init; 261 310 return 1; 262 311 } 263 264 public int start(MDState s, uintnumParams)265 { 266 s.getContext!(MDPerfCounter).mWatch.start();312 313 uword start(MDThread* t, uword numParams) 314 { 315 getThis(t).mWatch.start(); 267 316 return 0; 268 317 } 269 270 public int stop(MDState s, uintnumParams)271 { 272 auto self = s.getContext!(MDPerfCounter);273 self.mTime = self.mWatch.stop();318 319 uword stop(MDThread* t, uword numParams) 320 { 321 auto members = getThis(t); 322 members.mTime = members.mWatch.stop(); 274 323 return 0; 275 324 } 276 277 public int seconds(MDState s, uintnumParams)278 { 279 s.push(s.getContext!(MDPerfCounter).mTime);325 326 uword seconds(MDThread* t, uword numParams) 327 { 328 pushFloat(t, getThis(t).mTime); 280 329 return 1; 281 330 } 282 283 public int millisecs(MDState s, uintnumParams)284 { 285 s.push(s.getContext!(MDPerfCounter).mTime * 1_000);331 332 uword millisecs(MDThread* t, uword numParams) 333 { 334 pushFloat(t, getThis(t).mTime * 1_000); 286 335 return 1; 287 336 } 288 289 public int microsecs(MDState s, uintnumParams)290 { 291 s.push(s.getContext!(MDPerfCounter).mTime * 1_000_000);337 338 uword microsecs(MDThread* t, uword numParams) 339 { 340 pushFloat(t, getThis(t).mTime * 1_000_000); 292 341 return 1; 293 342 } branches/v2new/samples/simple.md
r350 r351 1 1 module samples.simple 2 3 4 2 5 3 /+ branches/v2new/test.d
r349 r351 36 36 loadStdlibs(t); 37 37 38 // This is all stdlib crap! 39 newFunction(t, µTime, "microTime"); 40 newGlobal(t, "microTime"); 41 Timer.init(t); 42 43 importModule(t, "samples.simple"); 38 importModule(t, "samples.simple"); 44 39 45 40 Stdout.newline.format("MiniD using {} bytes before GC, ", bytesAllocated(vm)).flush; … … 50 45 delete vm; 51 46 } 52 53 private extern(Windows) int QueryPerformanceFrequency(ulong* frequency);54 private extern(Windows) int QueryPerformanceCounter(ulong* count);55 ulong performanceFreq;56 57 static this()58 {59 if(!QueryPerformanceFrequency(&performanceFreq))60 performanceFreq = 0x7fffffffffffffffL;61 }62 63 uword microTime(MDThread* t, uword numParams)64 {65 ulong time;66 QueryPerformanceCounter(&time);67 68 if(time < 0x8637BD05AF6L)69 pushInt(t, cast(mdint)((time * 1_000_000) / performanceFreq));70 else71 pushInt(t, cast(mdint)((time / performanceFreq) * 1_000_000));72 73 return 1;74 }75 76 import tango.time.StopWatch;77 struct Timer78 {79 static:80 private Members* getThis(MDThread* t)81 {82 return checkObjParam!(Members)(t, 0, "Timer");83 }84 85 void init(MDThread* t)86 {87 CreateObject(t, "Timer", (CreateObject* o)88 {89 o.method("clone", &clone);90 o.method("start", &start);91 o.method("stop", &stop);92 o.method("seconds", &seconds);93 o.method("millisecs", &millisecs);94 o.method("microsecs", µsecs);95 });96 97 newGlobal(t, "Timer");98 }99 100 struct Members101 {102 protected StopWatch mWatch;103 protected mdfloat mTime = 0;104 }105 106 uword clone(MDThread* t, uword numParams)107 {108 newObject(t, 0, null, 0, Members.sizeof);109 *getMembers!(Members)(t, -1) = Members.init;110 return 1;111 }112 113 uword start(MDThread* t, uword numParams)114 {115 getThis(t).mWatch.start();116 return 0;117 }118 119 uword stop(MDThread* t, uword numParams)120 {121 auto members = getThis(t);122 members.mTime = members.mWatch.stop();123 return 0;124 }125 126 uword seconds(MDThread* t, uword numParams)127 {128 pushFloat(t, getThis(t).mTime);129 return 1;130 }131 132 uword millisecs(MDThread* t, uword numParams)133 {134 pushFloat(t, getThis(t).mTime * 1_000);135 return 1;136 }137 138 uword microsecs(MDThread* t, uword numParams)139 {140 pushFloat(t, getThis(t).mTime * 1_000_000);141 return 1;142 }143 }
