Skip to content

Commit 75883a3

Browse files
committed
AbstractMacro fix & Rest
1 parent 20d366b commit 75883a3

13 files changed

Lines changed: 231 additions & 53 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- `hasErrorHandler` variable to RuleScript and RuleScriptInterp.
1717
- `errorHandler` variable to RuleScript and RuleScriptInterp.
1818
- Key => value iterator.
19+
- Rest.
1920
- `superInstance` variable to RuleScriptInterp.
2021
- `onMeta` callback in RuleScriptInterp.
2122
- Classes (MODULE mode only).
@@ -33,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3334
- rulescript.parsers.HxParser.HScriptParserPlus.moduleDeclsToExpr.
3435

3536
### Fixed
37+
- Fixed bug when AbstractMacro can't find abstracts in a module other than it's name.
3638
- Fixed `using` error on Haxe Interpreter.
3739
- Fixed compile error on non-cpp targets.
3840
- Improve `using` resolve function.

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Hscript addon with script classes, imports, usings, properties, string interpola
1515
- [Abstracts in script](#abstracts-in-script)
1616
- [Key => value iterator](#key--value-iterator)
1717
- [`??` and `??=` operators](#and--operators)
18+
- [Rest](#rest)
1819

1920
### Package
2021
```haxe
@@ -82,7 +83,6 @@ trace(a); // Hello World
8283
```
8384

8485
### String interpolation
85-
RuleScript supports [String Interpolation](https://haxe.org/manual/lf-string-interpolation.html), but you can only use identifiers, double quotes string, calls without arguments and `+` operator.
8686
```haxe
8787
var a = 'Hello';
8888
trace('RuleScript: $a World'); // RuleScript: Hello World
@@ -173,6 +173,19 @@ a = null;
173173
a ??= 'world';
174174
trace(a) // world
175175
```
176+
177+
# Rest
178+
```haxe
179+
var f = function(hello:String, ...rest:Dynamic)
180+
{
181+
return '$hello: ' + rest.join(' ');
182+
}
183+
184+
trace(f('Rulescript','Hello','World','!')); // Rulescript: Hello World !
185+
186+
trace(f('Rulescript',...['Hello','World','!'])); // Rulescript: Hello World !
187+
```
188+
176189
# Limitations
177190

178191
- Script `using` callback supports max number of arguments is 8.

rulescript/RuleScript.hx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class RuleScript
9090

9191
public var interp:RuleScriptInterp;
9292

93+
public var scriptName(get, set):String;
94+
9395
public var superInstance(get, set):Dynamic;
9496

9597
public var variables(get, set):Map<String, Dynamic>;
@@ -124,6 +126,16 @@ class RuleScript
124126
public function getParser<T:Parser>(?parserClass:Class<T>):T
125127
return cast parser;
126128

129+
function get_scriptName():String
130+
{
131+
return interp.scriptName;
132+
}
133+
134+
function set_scriptName(v:String):String
135+
{
136+
return interp.scriptName = v;
137+
}
138+
127139
function get_superInstance():Dynamic
128140
{
129141
return interp.superInstance;

rulescript/RuleScriptInterp.hx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ using rulescript.Tools;
88

99
class RuleScriptInterp extends hscript.Interp
1010
{
11+
public var scriptName:String;
12+
1113
public var scriptPackage:String = '';
1214

1315
public var imports:Map<String, Dynamic> = [];
@@ -44,6 +46,18 @@ class RuleScriptInterp extends hscript.Interp
4446
#end
4547
}
4648

49+
override public function posInfos():haxe.PosInfos
50+
{
51+
#if hscriptPos
52+
if (curExpr != null)
53+
return cast {fileName: scriptName ?? curExpr.origin, lineNumber: curExpr.line};
54+
#end
55+
return cast {
56+
fileName: scriptName ?? "hscript",
57+
lineNumber: 0
58+
};
59+
}
60+
4761
override function initOps()
4862
{
4963
super.initOps();
@@ -205,6 +219,31 @@ class RuleScriptInterp extends hscript.Interp
205219
else
206220
forLoopKeyValue(key, value, it, e);
207221
return null;
222+
case ECall(e, params):
223+
var args = new Array();
224+
for (p in params)
225+
{
226+
if (p.getExpr().match(EUnop('...', true, _)))
227+
for (arg in cast(this.expr(switch (p.getExpr())
228+
{
229+
case EUnop(op, prefix, e): e;
230+
default: null;
231+
}), Array<Dynamic>))
232+
args.push(arg);
233+
else
234+
args.push(this.expr(p));
235+
}
236+
237+
switch (hscript.Tools.expr(e))
238+
{
239+
case EField(e, f):
240+
var obj = this.expr(e);
241+
if (obj == null)
242+
error(EInvalidAccess(f));
243+
return fcall(obj, f, args);
244+
default:
245+
return call(null, this.expr(e), args);
246+
}
208247
case EFunction(params, fexpr, name, _):
209248
if (name == 'new')
210249
__constructor = expr;

rulescript/macro/AbstractMacro.hx

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,59 @@
11
package rulescript.macro;
22

3+
#if macro
34
import haxe.macro.Context;
45
import haxe.macro.Expr;
6+
import rulescript.macro.MacroTools.ClassPath;
57
import sys.FileSystem;
68
import sys.io.File;
9+
#end
710

811
using StringTools;
912

10-
#if !macro
11-
@:keep
12-
@:build(rulescript.macro.TouchMacro.touch())
13-
#end
1413
class AbstractMacro
1514
{
16-
/**
17-
* Converts abstract to class
18-
*/
19-
macro public static function buildAbstract(name:String, pack:String):Array<Field>
15+
static final targetPackage:String = "rulescript.__abstracts";
16+
17+
macro public static function build():Array<Field>
2018
{
21-
var fields = Context.getBuildFields();
22-
var pos = Context.currentPos();
19+
var type = switch (Context.getLocalType())
20+
{
21+
case TInst(t, params):
22+
switch (t.get().kind)
23+
{
24+
case KAbstractImpl(a):
25+
a.get();
26+
default:
27+
null;
28+
}
29+
case t:
30+
Context.error('Failed to build non-abstract type', Context.currentPos());
31+
null;
32+
}
2333

24-
var type = Context.getLocalClass();
34+
var classPath:ClassPath = MacroTools.parseClassPath(type.module.endsWith(type.name) ? type.module : type.module + '.' + type.name);
2535

26-
var isEnum:Bool = type.get().meta.has(':enum');
36+
var fields = Context.getBuildFields();
37+
var pos = Context.currentPos();
38+
var isEnum:Bool = type.meta.has(':enum');
2739

2840
var cl = macro class {};
2941

3042
cl.meta.push({pos: pos, name: ':keep'});
43+
cl.meta.push({pos: pos, name: ':noCompletion'});
3144

3245
var imports = Context.getLocalImports();
3346

3447
imports.push({
35-
path: name.split('.').map(s -> {
48+
path: classPath.fullPath.split('.').map(s -> {
3649
name: s,
3750
pos: pos
3851
}),
3952
mode: INormal
4053
});
4154

42-
if (name.contains('.'))
43-
{
44-
var list = name.split('.');
45-
46-
while (list.length > 1)
47-
pack += '.' + list.shift();
48-
49-
name = list[0];
50-
}
51-
52-
cl.name = '_' + name;
53-
cl.pack = pack.split('.');
55+
cl.name = '_' + classPath.name;
56+
cl.pack = classPath.pack.split('.');
5457

5558
for (f in fields)
5659
{
@@ -76,7 +79,7 @@ class AbstractMacro
7679
});
7780
}
7881

79-
Context.defineModule('$pack._$name', [cl], imports);
82+
Context.defineModule('$targetPackage.${classPath.pack}._${classPath.name}', [cl], imports);
8083

8184
return fields;
8285
}

rulescript/macro/Converter.hx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ using StringTools;
1010

1111
class Converter
1212
{
13-
// Language server shows errors...
1413
public static macro function init()
1514
{
1615
var files:Array<String> = [];
@@ -26,7 +25,11 @@ class Converter
2625
abstractsList.push(abs);
2726

2827
for (name in abstractsList)
29-
Compiler.addMetadata('@:build(rulescript.macro.AbstractMacro.buildAbstract("$name","rulescript.__abstracts"))', name);
28+
{
29+
var classPath = MacroTools.parseClassPath(name);
30+
Compiler.addMetadata('@:build(rulescript.macro.AbstractMacro.build())', '${classPath.pack}.${classPath.name}');
31+
}
32+
3033
return null;
3134
}
3235

rulescript/macro/MacroTools.hx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,34 @@ package rulescript.macro;
44
import haxe.macro.Context;
55
import haxe.macro.Expr;
66

7+
using StringTools;
8+
79
class MacroTools
810
{
11+
public static function parseClassPath(classPath:String):ClassPath
12+
{
13+
if (classPath == null || classPath.length == 0)
14+
return null;
15+
16+
var path:Array<String> = classPath.split('.');
17+
18+
var pack:Array<String> = [];
19+
20+
while (path[0].charAt(0) == path[0].charAt(0).charAt(0).toLowerCase())
21+
pack.push(path.shift());
22+
23+
var module:String = null;
24+
if (path.length > 1)
25+
module = path.shift();
26+
27+
return {
28+
fullPath: classPath,
29+
name: path[0],
30+
module: module,
31+
pack: pack.join('.')
32+
}
33+
}
34+
935
/**
1036
* Convert Expr function to function
1137
*/
@@ -21,6 +47,14 @@ class MacroTools
2147
}
2248
}
2349

50+
typedef ClassPath =
51+
{
52+
var fullPath:String;
53+
var name:String;
54+
var ?module:String;
55+
var pack:String;
56+
};
57+
2458
typedef ClassFunctionArg =
2559
{
2660
var name:String;

rulescript/macro/TouchMacro.hx

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)