1 module demo;
2 version (qscriptdemo){
3 	import utils.misc;
4 	import qscript.qscript;
5 	import std.datetime.stopwatch;
6 	import std.stdio;
7 	/// runs the scripts using QScript
8 	class ScriptExec{
9 	private:
10 		/// where the magic happens
11 		QScript _qscript;
12 		/// writeln function
13 		NaData writeln(NaData[] args){
14 			std.stdio.writeln (args[0].strVal);
15 			return NaData(0);
16 		}
17 		/// write function
18 		NaData write(NaData[] args){
19 			std.stdio.write (args[0].strVal);
20 			return NaData(0);
21 		}
22 		/// write int
23 		NaData writeInt(NaData[] args){
24 			std.stdio.write(args[0].intVal);
25 			return NaData(0);
26 		}
27 		/// write double
28 		NaData writeDbl(NaData[] args){
29 			std.stdio.write(args[0].doubleVal);
30 			return NaData(0);
31 		}
32 		/// readln function
33 		NaData readln(NaData[] args){
34 			string s = std.stdio.readln;
35 			s.length--;
36 			return NaData(s);
37 		}
38 	public:
39 		/// constructor
40 		this (){
41 			_qscript = new QScript(
42 				[
43 					Function("writeln", DataType("void"), [DataType("char[]")]),
44 					Function("write", DataType("void"), [DataType("char[]")]),
45 					Function("write", DataType("void"), [DataType("int")]),
46 					Function("write", DataType("void"), [DataType("double")]),
47 					Function("readln", DataType("char[]"), [])
48 				],
49 				[
50 					&writeln,
51 					&write,
52 					&writeInt,
53 					&writeDbl,
54 					&this.readln
55 				]
56 			);
57 			// all functions are already loaded, so initialize can be called right away
58 			_qscript.initialize();
59 		}
60 		/// compiles & returns byte code
61 		string[] compileToByteCode(string[] script, ref CompileError[] errors){
62 			string[] byteCode;
63 			errors = _qscript.loadScript(script, byteCode);
64 			return byteCode;
65 		}
66 		/// executes the first function in script
67 		NaData execute(uinteger functionID, NaData[] args){
68 			return _qscript.execute(functionID, args);
69 		}
70 	}
71 
72 	void main (string[] args){
73 		if (args.length < 2){
74 			writeln("not enough args. Usage:");
75 			writeln("./demo script [bytecode output]");
76 		}else{
77 			StopWatch sw;
78 			ScriptExec scr = new ScriptExec();
79 			CompileError[] errors;
80 			string[] byteCode = scr.compileToByteCode(fileToArray(args[1]), errors);
81 			if (errors.length > 0){
82 				writeln("Compilation errors:");
83 				foreach (err; errors){
84 					writeln ("line#",err.lineno, ": ",err.msg);
85 				}
86 			}else{
87 				if (args.length > 2){
88 					byteCode.arrayToFile(args[2]);
89 				}
90 				// now execute main
91 				sw.start;
92 				scr.execute(0, []);
93 				sw.stop;
94 				writeln("execution took: ", sw.peek.total!"msecs", "msecs");
95 			}
96 		}
97 	}
98 }