forked from CodenameCrew/hscript-improved
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPreprocessor.hx
More file actions
147 lines (130 loc) · 4.42 KB
/
Preprocessor.hx
File metadata and controls
147 lines (130 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package hscript;
import hscript.Expr;
import hscript.Error;
import hscript.Tools;
import hscript.Parser;
@:access(hscript.Parser)
class Preprocessor {
static inline function expr(e:Expr) return Tools.expr(e);
private static var importStackName:Array<String> = [];
private static var importStackMode:Array<KImportMode> = [];
private static function addImport(e:String, mode:KImportMode = INormal) {
for(i in importStackName) if(i == e) return;
importStackName.push(e);
importStackMode.push(mode);
}
private static function popImport(e:Expr) {
return mk(EImport(importStackName.pop(), importStackMode.pop()), e);
}
/**
* Preprocesses the expression, like 'a'.code => 97
* Also for transforming any abstracts into their implementations (TODO)
* Also for transforming any static extensions into their real form (TODO)
* Also to automatically add imports for stuff that is not imported
**/
public static function process(e:Expr, top:Bool = true):Expr {
importStackName = [];
importStackMode = [];
var e = _process(e, top);
// Automatically add imports for stuff
switch(expr(e)) {
case EBlock(exprs):
while(importStackName.length > 0) {
exprs.unshift(popImport(e));
}
return mk(EBlock(exprs), e);
default:
if(importStackName.length > 0) {
var exprs = [];
while(importStackName.length > 0) {
exprs.unshift(popImport(e));
}
exprs.push(e);
return mk(EBlock(exprs), e);
}
}
return e;
}
private static function _process(e:Expr, top:Bool = true):Expr {
if(e == null)
return null;
// If stuff looks wrong, add this back
//e = Tools.map(e, function(e) {
// return _process(e, false);
//});
//trace(expr(e));
switch(expr(e)) {
case EField(expr(_) => EConst(CString(s)), "code", _): // Transform string.code into charCode
if(s.length != 1) {
throw Parser.getBaseError(EPreset(INVALID_CHAR_CODE_MULTI));
}
return mk(EConst(CInt(s.charCodeAt(0))), e);
case ECall(expr(_) => EField(expr(_) => EIdent("String"), "fromCharCode", _), [e]): // Seperate this later?
switch(expr(e)) { // should this be Optimizer?
case EConst(CInt(i)):
return mk(EConst(CString(String.fromCharCode(i))), e);
default:
}
if(!Preprocessor.isStringFromCharCodeFixed) {
// __StringWorkaround__fromCharCode(i);
#if !NO_FROM_CHAR_CODE_FIX
return mk(ECall(mk(EIdent("__StringWorkaround__fromCharCode"), e), [e]), e);
#else
throw Parser.getBaseError(EPreset(FROM_CHAR_CODE_NON_INT));
#end
}
// Automatically add imports for stuff
case ENew("String", _): addImport("String");
case EIdent("String"): addImport("String");
case ENew("StringBuf", _): addImport("StringBuf");
case EIdent("StringBuf"): addImport("StringBuf");
case EIdent("Bool"): addImport("Bool");
case EIdent("Float"): addImport("Float");
case EIdent("Int"): addImport("Int");
case ENew("IntIterator", _): addImport("IntIterator");
case EIdent("IntIterator"): addImport("IntIterator");
case EIdent("Array"): addImport("Array");
case EIdent("Sys"): addImport("Sys");
case EIdent("Std"): addImport("Std");
case EIdent("Type"): addImport("Type");
case EIdent("Reflect"): addImport("Reflect");
case EIdent("StringTools"): addImport("StringTools");
case EIdent("Math"): addImport("Math");
case ENew("Date", _): addImport("Date");
case EIdent("Date"): addImport("Date");
case EIdent("DateTools"): addImport("DateTools");
case EIdent("Lambda"): addImport("Lambda");
case ENew("Xml", _): addImport("Xml");
case EIdent("Xml"): addImport("Xml");
//case EIdent("List"): addImport("haxe.ds.List");
case ENew("EReg", _): addImport("EReg");
case EIdent("EReg"): addImport("EReg");
//case EField(expr(_) => EIdent("EReg"), "escape", _):
// addImport("EReg");
default:
}
e = Tools.map(e, function(e) {
return _process(e, false);
});
return e;
}
static function mk(e:ExprDef, s:Expr):Expr {
#if hscriptPos
return new Expr(e, s.pmin, s.pmax, s.origin, s.line);
#else
return e;
#end
}
public static var isStringFromCharCodeFixed(get, null):Null<Bool> = null;
static function get_isStringFromCharCodeFixed():Null<Bool> {
if(isStringFromCharCodeFixed == null) {
try {
Reflect.callMethod(null, Reflect.field(String, "fromCharCode"), [65]);
isStringFromCharCodeFixed = true;
} catch(e:Dynamic) {
isStringFromCharCodeFixed = false;
}
}
return isStringFromCharCodeFixed;
}
}