Giter Club home page Giter Club logo

hscript's Introduction

hscript

TravisCI Build Status AppVeyor Build Status

Parse and evalutate Haxe expressions.

In some projects it's sometimes useful to be able to interpret some code dynamically, without recompilation.

Haxe script is a complete subset of the Haxe language.

It is dynamically typed but allows all Haxe expressions apart from type (class,enum,typedef) declarations.

Usage

var expr = "var x = 4; 1 + 2 * x";
var parser = new hscript.Parser();
var ast = parser.parseString(expr);
var interp = new hscript.Interp();
trace(interp.execute(ast));

In case of a parsing error an hscript.Expr.Error is thrown. You can use parser.line to check the line number.

You can set some globaly accessible identifiers by using interp.variables.set("name",value)

Example

Here's a small example of Haxe Script usage :

var script = "
	var sum = 0;
	for( a in angles )
		sum += Math.cos(a);
	sum; 
";
var parser = new hscript.Parser();
var program = parser.parseString(script);
var interp = new hscript.Interp();
interp.variables.set("Math",Math); // share the Math class
interp.variables.set("angles",[0,1,2,3]); // set the angles list
trace( interp.execute(program) ); 

This will calculate the sum of the cosines of the angles given as input.

Haxe Script has not been really optimized, and it's not meant to be very fast. But it's entirely crossplatform since it's pure Haxe code (it doesn't use any platform-specific API).

Advanced Usage

When compiled with -D hscriptPos you will get fine error reporting at parsing time.

You can subclass hscript.Interp to override behaviors for get, set, call, fcall and cnew.

You can add more binary and unary operations to the parser by setting opPriority, opRightAssoc and unops content.

You can use parser.allowJSON to allow JSON data.

You can use parser.allowTypes to parse types for local vars, exceptions, function args and return types. Types are ignored by the interpreter.

You can use parser.allowMetadata to parse metadata before expressions on in anonymous types. Metadata are ignored by the interpreter.

You can use new hscript.Macro(pos).convert(ast) to convert an hscript AST to a Haxe macros one.

You can use hscript.Checker in order to type check and even get completion, using haxe -xml output for type information.

Limitations

Compared to Haxe, limitations are :

  • switch construct is supported but not pattern matching (no variable capture, we use strict equality to compare case values and switch value)
  • only one variable declaration is allowed in var
  • the parser supports optional types for var and function if allowTypes is set, but the interpreter ignores them
  • you can enable per-expression position tracking by compiling with -D hscriptPos
  • you can parse some type declarations (import, class, typedef, etc.) with parseModule

Install

In order to install Haxe Script, use haxelib install hscript and compile your program with -lib hscript.

These are the main required files in hscript :

  • hscript.Expr : contains enums declarations
  • hscript.Parser : a small parser that turns a string into an expression structure (AST)
  • hscript.Interp : a small interpreter that execute the AST and returns the latest evaluated value

Some other optional files :

  • hscript.Async : converts Expr into asynchronous version
  • hscript.Bytes : Expr serializer/unserializer
  • hscript.Checker : type checking and completion for hscript Expr
  • hscript.Macro : convert Haxe macro into hscript Expr
  • hscript.Printer : convert hscript Expr to String
  • hscript.Tools : utility functions (map/iter)

hscript's People

Contributors

andyli avatar back2dos avatar bubblebenj avatar ckentgeorge avatar filt3rek avatar gama11 avatar markknol avatar msghero avatar ncannasse avatar realyuniquename avatar romamik avatar sebthom avatar simn avatar starburst997 avatar tcoxon avatar tpr-evilempire avatar yanrishatum avatar zjnue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hscript's Issues

Why No Classes?

I'm mainly asking whether you didn't implement classes because you had some reason not to, or if it simply didn't seem that essential when you wrote it. At first, I assumed that it must have been challenging to implement object-oriented capabilities for a dynamically typed language, when you're writing the implementation in a statically typed language, but in about four hours, I've added support for the this keyword, added apply, and bind methods to the functions to allow users of the api to manually set the value of this, and very basic support for classes. I also added an until loop for my own amusement. :P All this to say, I'd love for you guys to check it out, and tell me how I can improve it. I'm a major fan of the idea of an interpreted language as cross-platform as this, so I'm eager to help in any way I can.

Interpreter hangs without any error reporting.

Weird behavior when adding a value to an Object (function). No error is reported, the system just hangs.

function a(i:Int){
return i;
}
// a is now Object
a += 1;
// a is now Object1
a(1);
// hangs...

Does not compile with Haxe3 and -D hscriptPos

The readme states that you can get more debug information by compiling with -D hscriptPos. Unfortunately this doesn't seem to work with haxe3. There are many compiler errors:

hscript/Bytes.hx:133: characters 30-31 : hscript.Expr should be EnumValue
hscript/Bytes.hx:133: characters 30-31 : { pmin : Int, pmax : Int, e : hscript.ExprDef } should be EnumValue
hscript/Bytes.hx:133: characters 30-31 : For function argument 'e'
hscript/Bytes.hx:135: characters 7-16 : hscript.ExprDef should be hscript.Expr
hscript/Bytes.hx:135: characters 7-16 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Bytes.hx:227: characters 2-6 : hscript.ExprDef should be hscript.Expr
hscript/Bytes.hx:227: characters 2-6 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Bytes.hx:225: lines 225-315 : Missing return hscript.Expr
hscript/Interp.hx:240: characters 7-16 : hscript.ExprDef should be hscript.Expr
hscript/Interp.hx:240: characters 7-16 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Interp.hx:108: characters 7-17 : hscript.ExprDef should be hscript.Expr
hscript/Interp.hx:108: characters 7-17 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Interp.hx:133: characters 16-18 : hscript.ExprDef should be hscript.Expr
hscript/Interp.hx:133: characters 16-18 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Interp.hx:133: characters 16-18 : For function argument 'e'
hscript/Interp.hx:431: characters 24-44 : hscript.#Error has no field EInvalidAccess
hscript/Interp.hx:436: characters 24-44 : hscript.#Error has no field EInvalidAccess
hscript/Interp.hx:148: characters 9-25 : hscript.#Error has no field EInvalidOp
hscript/Interp.hx:125: characters 62-64 : hscript.Expr should be hscript.ExprDef
hscript/Interp.hx:125: characters 62-64 : { pmin : Int, pmax : Int, e : hscript.ExprDef } should be hscript.ExprDef
hscript/Interp.hx:125: characters 62-64 : For function argument 'e1'
hscript/Interp.hx:155: characters 7-17 : hscript.ExprDef should be hscript.Expr
hscript/Interp.hx:155: characters 7-17 : hscript.ExprDef should be { pmin : Int, pmax : Int, e : hscript.ExprDef }
hscript/Interp.hx:153: lines 153-186 : Missing return Dynamic
hscript/Interp.hx:234: characters 9-31 : hscript.#Error has no field EUnknownVariable
hscript/Interp.hx:407: characters 50-72 : hscript.#Error has no field EInvalidIterator

scene changing

What would we want it to look like?

PuzzleGame

Game.setscene("PuzzleGame");

look okay, and safe enough to split on (also, the text editor would highlight it differently) -

Ideally we'd want this to play nicely with the interpreter when it comes to spitting out errors - might be worth waiting until I'm back and we can have a look more closely at what the best way to implement it would be.

An alternaive approach would be to have an assignable update function

function mainUpdate(){}
function sceneUpdate(){}

and then let you call update = mainUpdate

another approach would be to have it intelligently deduce names from function names. So if you have

newTitle(){
}
updateTitle(){
}

you can then automatically call Game.SetScene(title) and it'll know what to call.

I don't think those are as elegant as farb's solution. Any other possible implementations?

Example crashed (seg fault) on C++ with slight modification

package ;

import hscript.Interp;
import hscript.Parser;

class Main 
{
    static public function main()
    {
        var script:String = "
            var sum = 0;
            for(a in angles)
            {
                sum += Math.cos(a * Math.PI / 180);
            }
            sum; 
        ";

        var parser = new Parser();
        var prgAST = parser.parseString(script);
        var interp = new Interp();

        interp.variables.set("Math", Math);
        interp.variables.set("angles", [ 0, 1, 2, 3 ]);

        trace(interp.execute(prgAST));
    }
}

Apparently accessing Math.PI (which is a property, so this might related to #10 ) causes crash on C++ target (I've tried on Linux, Windows and Android).

Make getParams not static

It should be useful to make getParams not static, since classes can extend it (and add new parameter types for elements).

Current git version does not compile on Haxe 3.2.1 for Neko platform

/home/hexen/haxelib/hscript/git/hscript/Interp.hx:630: characters 19-40 : Module haxe.Constraints does not define type Constraints
/home/hexen/haxelib/hscript/git/hscript/Interp.hx:629: lines 629-631 : Missing return Bool
/home/hexen/haxelib/hscript/git/hscript/Interp.hx:634: characters 14-17 : Module haxe.Constraints does not define type IMap
/home/hexen/haxelib/hscript/git/hscript/Interp.hx:633: lines 633-635 : Missing return Dynamic
/home/hexen/haxelib/hscript/git/hscript/Interp.hx:638: characters 7-10 : Module haxe.Constraints does not define type IMap

Is the support for Haxe 3.2.1 planned at all?

crashes on invalid input

when using dconsole, invalid input will crash on hscript 2.0.3 but not 2.0.2

targeting cpp (windows), release build

haxelib info, in case it helps:

image

Hscript tries to use =- as an operator and fails

Working on a hscript thing at the moment and noticed this weird behaviour:

var x=-2;

...causes a crash. If you space out the characters it's fine. Here's the ErrorDef:

Err.hx:109: ERRORHANDLE OBJECT :
,{
    e : EInvalidOp(=-), 
    pmin : 61, 
    pmax : 68
},
errorhandle.e = 
{ 
0: EInvalidOp
1: 6
2: =-
}

Possible to call hScript functions from within Haxe?

Ok, ideally I would be able to write some hScript code like:

var hScript:String = "

function moveLeft()
{
    // Handle player moving left
}

function moveRight()
{
    // Handle player moving right
}
";

And then from within my Haxe be able to call

    hscript.interp().moveLeft();

I can't seem to figure out how to make it work. It would be SUPER useful instead of having to write a separate script for each function...

Just a Suggestion

After creating the language GryffinScript, I've found that when functions are stored as objects, with 'call' methods, the interpreter runs a bit faster, as apposed to just creating Haxe functions. So, might I suggest implementing this into hscript? As it currently stands, the language is quite slow, so that really needs improving. Just a suggestion.

Why can I not set local variables?

I have some local variables setup in my application like this:

public var _linkColour:UInt;
public var _defaultColour:UInt;
public var _defaultFont:String;
public var _defaultFontSize:Float;
public var _linkFont:String;
public var _linkFontSize:Float;

And I've set them up in the interpreter:
_interp.variables.set("fontColour", _defaultColour);
_interp.variables.set("linkColour", _linkColour);
_interp.variables.set("fontSize", _defaultFontSize);
_interp.variables.set("fontName", _defaultFont);
_interp.variables.set("linkSize", _linkFontSize);
_interp.variables.set("linkName", _linkFont);

But for some reason, doing "linkColour = 0x000077;" doesn't work, doing "linkSize = 10;" doesn't work either. I've got them setup to change the font and colour of both the default font for my TextField and also when parsing custom links. When I change these values in the code itself, it changes as expected, but it doesn't seem to set the variables when dynamically run through the parser.

Why is this, or am I missing something?

IntIterator is stripped by dce std, leaving for loops over constants failing

If you run a script containing a for loop iterating between two int constants
e.g.

for(i in 0 ... 10) 
{
    //some more code
}

and compiling without setting -dce no then the IntIterator class from the haxe Stdlib is stripped of the hasNext and next functions (unless of course, you have explicitly used IntIterator in your code).
This in turn makes the makeIteratorfunction in Interp fail (on line 506 as of writing).

A quick fix is to set --macro keep("IntIterator") as a parameter to the haxe compiler, but I'm assuming that there is probably a more elegant way to handle this. This might or might not be hscripts "responsibility", but I thought it worth mentioning in the README at least.

Tested using haxe 3.2.1

Incremental execution of parsed code

Hi,

thanks a lot for such a tool. I was wondering if you had any plan in including some sort of incremental execution of the parsed code.
By incremental, I mean expression by expression and/or line by line. The idea is to let the users control the flow of the execution by pausing it and resuming it "whenever" they want. I would love to actually show users how their code is actually being executed and what's happening under the hood (variables being set, updated, functions being called, ...)

If no plan, would you have any idea of the complexity of adding this feature ? possible ways ?

Thanks a lot.

Build fails with `-D hscriptPos`

Tools.hx doesn't support hscriptPos.
And this is what I get when I run the test wtih hscriptPos on Neko:

Class: Test E.
* Test::test()
ERR: exception thrown : Invalid operation (<<)

Called from hscript/Bytes.hx line 113
Called from hscript/Bytes.hx line 123
Called from hscript/Bytes.hx line 263
Called from hscript/Bytes.hx line 257
Called from hscript/Bytes.hx line 296
Called from hscript/Bytes.hx line 257
Called from hscript/Bytes.hx line 274
Called from hscript/Bytes.hx line 257
Called from hscript/Bytes.hx line 384
Called from Test.hx line 12
Called from Test.hx line 87
Called from E:\HaxeToolkit\haxe\std/neko/_std/Reflect.hx line 58
Called from E:\HaxeToolkit\haxe\std/haxe/unit/TestRunner.hx line 152

[php, python] big int issue

the following test in Test.hx failed when targeting php and python:

assertScript("0xBFFFFFFF", 0xBFFFFFFF);

The same error is returned by php and python:

ERR: Test.hx:16(Test.assertScript) - expected '-1073741825' but was '3221225471'

"var" behavior for multiple execute

"var" making variable local for single execute. Is it bug or expected behavior?

    var parser = new hscript.Parser();
    var interp = new hscript.Interp();

        //version 1 broken
        interp.execute(parser.parseString("var a='qqq';")); 
        interp.execute(parser.parseString("trace(a);")); 

        //version 2 works
        interp.execute(parser.parseString("a='qqq';")); 
        interp.execute(parser.parseString("trace(a);")); 

How can we create map in hscript

I want to create a map<String, Dynamic> in hscript. But type is not supported.
How can we do that in hscript? What does "var map = {};" create?

parse error with while (...) ;

when parsing this:

while (true) ;

an exception is raised.

Uncaught exception - EUnexpected(;)

however this works:

while (true) {}

flash & cpp : the tests do no pass

It seems the tests do not pass with git version

function doEncode( e : Expr ) {

hscript/Bytes.hx:134: characters 10-11 : Unmatched patterns: ESwitch

thx !

Sys can't be schared complete:

Simple programm throws an exception:

var parser = new hscript.Parser();
var ast = parser.parseString("Sys.print(\"test\");");
var interp = new hscript.Interp();
interp.variables.set("Sys", Sys);
interp.execute(ast)

$nargs

So if i debug the Interp

Interp.hx:550: { __name__ => [Sys], prototype => { __class__ => ..., __serialize => #function:0 }, getCwd => #function:0, get_cwd => #function:0 }
Interp.hx:551: print
Interp.hx:552: null
Interp.hx:553: [test]

I see print is not defined in Sys
If i run cwd:

var parser = new hscript.Parser();
var ast = parser.parseString("Sys.getCwd();");
var interp = new hscript.Interp();
interp.variables.set("Sys", Sys);
interp.execute(ast)

it works
How to fix it?

Tests are failing on PHP

1.01s$ haxe bin/build-php.hxml          && php bin/index.php
Class: Test EE
* Test::test()
ERR: exception thrown : ErrorException: Undefined property: IntIterator::$iterator in /home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php:146
Stack trace:
#0 /home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php(146): php\Boot::php\{closure}(8, 'Undefined prope...', '/home/travis/bu...', 146, Array)
#1 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1644): php\Boot::dynamicField(Object(IntIterator), 'iterator')
#2 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1253): hscript\Interp->makeIterator(Object(IntIterator))
#3 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(617): hscript\Interp->forLoop('x', Object(hscript\Expr), Object(hscript\Expr))
#4 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(468): hscript\Interp->expr(Object(hscript\Expr))
#5 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1189): hscript\Interp->expr(Object(hscript\Expr))
#6 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(372): hscript\Interp->exprReturn(Object(hscript\Expr))
#7 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(93): hscript\Interp->execute(Object(hscript\Expr))
#8 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(212): Test->assertScript('var a = new Arr...', '0-1-2-3-4')
#9 [internal function]: Test->test()
#10 /home/travis/build/HaxeFoundation/hscript/bin/lib/php/_Boot/HxClosure.php(57): call_user_func_array(Array, Array)
#11 /home/travis/build/HaxeFoundation/hscript/bin/lib/Reflect.php(32): php\_Boot\HxClosure->callWith(Object(Test), Array)
#12 /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php(134): Reflect::callMethod(Object(Test), Object(php\_Boot\HxClosure), Object(Array_hx))
#13 /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php(83): haxe\unit\TestRunner->runCase(Object(Test))
#14 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(30): haxe\unit\TestRunner->run()
#15 /home/travis/build/HaxeFoundation/hscript/bin/index.php(13): Test::main()
#16 {main}
Called from local function (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php line 146)
Called from php.Boot.dynamicField (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php line 146)
Called from hscript.Interp.makeIterator (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1644)
Called from hscript.Interp.forLoop (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1253)
Called from hscript.Interp.expr (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 617)
Called from hscript.Interp.expr (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 468)
Called from hscript.Interp.exprReturn (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1189)
Called from hscript.Interp.execute (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 372)
Called from Test.assertScript (/home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php line 93)
Called from Test.test (/home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php line 212)
Called from php._Boot.HxClosure.callWith (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/_Boot/HxClosure.php line 57)
Called from Reflect.callMethod (/home/travis/build/HaxeFoundation/hscript/bin/lib/Reflect.php line 32)
Called from /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php line 134
* Test::testMap()
ERR: exception thrown : ErrorException: Undefined property: php\_NativeArray\NativeArrayIterator::$iterator in /home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php:146
Stack trace:
#0 /home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php(146): php\Boot::php\{closure}(8, 'Undefined prope...', '/home/travis/bu...', 146, Array)
#1 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1644): php\Boot::dynamicField(Object(php\_NativeArray\NativeArrayIterator), 'iterator')
#2 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1253): hscript\Interp->makeIterator(Object(php\_NativeArray\NativeArrayIterator))
#3 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(617): hscript\Interp->forLoop('key', Object(hscript\Expr), Object(hscript\Expr))
#4 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(468): hscript\Interp->expr(Object(hscript\Expr))
#5 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(1189): hscript\Interp->expr(Object(hscript\Expr))
#6 /home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php(372): hscript\Interp->exprReturn(Object(hscript\Expr))
#7 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(93): hscript\Interp->execute(Object(hscript\Expr))
#8 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(362): Test->assertScript('\r\n\t\t\tvar keys =...', 'foo_bar_a', Object(php\_Boot\HxAnon))
#9 [internal function]: Test->testMap()
#10 /home/travis/build/HaxeFoundation/hscript/bin/lib/php/_Boot/HxClosure.php(57): call_user_func_array(Array, Array)
#11 /home/travis/build/HaxeFoundation/hscript/bin/lib/Reflect.php(32): php\_Boot\HxClosure->callWith(Object(Test), Array)
#12 /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php(134): Reflect::callMethod(Object(Test), Object(php\_Boot\HxClosure), Object(Array_hx))
#13 /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php(83): haxe\unit\TestRunner->runCase(Object(Test))
#14 /home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php(30): haxe\unit\TestRunner->run()
#15 /home/travis/build/HaxeFoundation/hscript/bin/index.php(13): Test::main()
#16 {main}
Called from local function (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php line 146)
Called from php.Boot.dynamicField (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/Boot.php line 146)
Called from hscript.Interp.makeIterator (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1644)
Called from hscript.Interp.forLoop (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1253)
Called from hscript.Interp.expr (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 617)
Called from hscript.Interp.expr (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 468)
Called from hscript.Interp.exprReturn (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 1189)
Called from hscript.Interp.execute (/home/travis/build/HaxeFoundation/hscript/bin/lib/hscript/Interp.php line 372)
Called from Test.assertScript (/home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php line 93)
Called from Test.testMap (/home/travis/build/HaxeFoundation/hscript/bin/lib/Test.php line 362)
Called from php._Boot.HxClosure.callWith (/home/travis/build/HaxeFoundation/hscript/bin/lib/php/_Boot/HxClosure.php line 57)
Called from Reflect.callMethod (/home/travis/build/HaxeFoundation/hscript/bin/lib/Reflect.php line 32)
Called from /home/travis/build/HaxeFoundation/hscript/bin/lib/haxe/unit/TestRunner.php line 134
FAILED 2 tests, 2 failed, 0 success
The command "haxe bin/build-php.hxml          && php bin/index.php" exited with 1.

It kinda looks like a DCE issue, but we compile with -dce no, so I have -dce no idea.

@RealyUniqueName

Accesing objects properties

I wasn't able to access object properties (getters, setters) in my scripts, just object fields. I had to change Interp.get method to use Reflect.getProperty() instead of Reflect.field().
Is this on purpose because of performance differences between those two methods?

ETernary operator supported by Parser and Bytes.encode, but not Bytes.decode

The following testcase I added to Text.hx dies in the Bytes.decode stage, though it works fine when run through the parser:

test("(true ? 6 : 12)",6);

Throws:

Invalid code 22
    at hscript::Bytes/doDecode()[hscript/Bytes.hx:313]
    at hscript::Bytes/doDecode()[hscript/Bytes.hx:235]
    at hscript::Bytes$/decode()[hscript/Bytes.hx:325]
        ...

It appears Interp and Bytes.encode() support ETernary, while Bytes.decode does not.

cpp target failed on Linux with Haxe development

Somehow the cpp target failed on Linux with Haxe development:

Class: Test EF
* Test::test()
ERR: exception thrown : OutsideBounds
* Test::testMap()
ERR: Test.hx:18(Test.assertScript) - expected 'Foo' but was 'null'
FAILED 2 tests, 2 failed, 0 success
The command "haxe build-cpp.hxml          && ./bin/Test" exited with 1.

It passed on Linux build with Haxe 3.2.1. And it also passed on Mac with Haxe development...

@hughsando Would you mind to take a look?

type declaration

Hi. is it possible to create variable with type declaration?
Example

var expr = "var x:$Float = 123";   
var parser = new hscript.Parser(); 
var ast = parser.parseString(expr);

will return error Uncaught exception - EUnexpected(:)

Thanks.

test in test.hx throwing an EInvalidIterator error : var a = new Array(); for( x in 0...5 ) a[x] = x; a.join('-');

It might just be me running it incorrectly, but I'm getting a report of one of the Test.hx cases crashing (in NekoVM 2.0.0)

This one:

var a = new Array(); for( x in 0...5 ) a[x] = x; a.join('-')

I'm not sure why (when I try to test it in a live interpreter myself it seems ok). Anyway, here's the call stack:

Called from ? line 1
Called from Test.hx line 70
Called from Test.hx line 15
Called from hscript/Interp.hx line 206
Called from hscript/Interp.hx line 210
Called from hscript/Interp.hx line 211
Called from hscript/Interp.hx line 294
Called from hscript/Interp.hx line 341
Called from hscript/Interp.hx line 512
Called from hscript/Interp.hx line 505
Uncaught exception - EInvalidIterator({ max => 5, min => 0 })

request :support While loop

hi,I want to hscript support while loop

var s = "var _g = 0; var k=1;while(_g < 10) {var i = _g++; k++; } return k";

Suggestion: Implement anonymous object inheritance

Take the following example:

Settings         = {};
Settings.Message = "Hello.";
Settings.GetMessage = function()
{
    trace(Settings.Message);
}

The anonymous object Settings contains the field Message, and the only way to get that data is to write the full path. In some circumstances, this may be okay, and using variables such as var msg = Settings.Message; is the only way to shorten it if needed to use more than once without tedious copying and pasting.

What I would like is some kind of anonymous object inheritance, using the this keyword or whether implied through parent-child structure like in the above example.

So instead of writing Settings.Message in a function to get the Message from the parent object, the parent is inherited into its children, so using this to refer to the path going to the child, or omitting entirely like so:

Path.To.Child = function () { //assuming the Haxe Type/Reflect API is exposed
    trace(getPath(Child)) //Outputs: Path.To
    trace(getFullPath(Child)) //Outputs: Path.To.Child
    //or using `this.Child` refers to `Path.To.Child`
}

I am no expert in the field of interpreters or parsers, so maybe this can be accomplished? Feedback appreciated.

For loops broken

for loops appear to be broken currently: running

for (i in 0...10)
{
    trace("hey");
}

gives me: EInvalidIterator({ max => 10, min => 0 })

looping through a haxeflixel FlxTypedGroup didnt work either (that was initially what I wanted to do)

Thanks,
Nico

Accessing static inline fields in CPP target

package hxclap;

class E_CmdArgSyntax
{
    public static inline var isOPT:Int       = 0x01;  // argument is optional
    public static inline var isREQ:Int       = 0x02;  // argument is required
    public static inline var isVALOPT:Int    = 0x04;  // argument value is optional
    public static inline var isVALREQ:Int    = 0x08;  // argument value is required
    public static inline var isHIDDEN:Int    = 0x10;  // argument is not to be printed in usage    
}

On flash and neko targets, I can access these fields from hscript just fine. On CPP, however, these fields become 0. Removing the inline keyword solves the issue, but I'm wondering what's causing that.

Needs license?

I'm doing a due dilligence round on the various libraries I'm including, and I didn't notice a LICENSE.md/.txt in this repository.

Presumably it's meant to be under MIT license like the other haxe libraries? Looks like there's not many contributors so it should be fairly easy to sort this out?

switch not implemented in Macro.hx

Get this error when trying to compile anything that uses hscript.Macro:
Haxelib/hscript/2,0,4/hscript/Macro.hx:139: characters 51-52 : Unmatched patterns: ESwitch

EUnexpected returning incorrect emin/max sometimes in parseString? (compiled with hscriptPos)

SHORT VERSION

The line

"e" a

has an error at position 4, whereas the line

"é" a

has an error at position 5.

This means it's getting confused, right? Shouldn't it be giving the same for both?

(every additional é character seems to push the error further out - so '"éé" a' has an error at 7)

DETAILED VERSION

import hscript.*;
import hscript.Expr.Error;

class Test {

  static function test(expr:String){
    try {
      var parser = new hscript.Parser();
      var ast = parser.parseString(expr);
    } catch ( err : Dynamic ){
      trace(err); 
    }
  }

  static function main() {
    test('"e" a');
    test('"é" a');
  }

}

produces

Test.hx:10: { pmax => 4, pmin => 4, e => EUnexpected(a) }
Test.hx:10: { pmax => 5, pmin => 5, e => EUnexpected(a) }

(all compiled with -D hscriptPos)

"catch" could not be followed by block ?

seems that "catch" could not be followed by a block ( { ... } ) ,
but just one statement (single expression) allowed.

Is this a bug or limitation?

BTW, "hscript.Bytes" could not be compiled successfully with flag "-D hscriptPos"

hxcpp 3.2.1 tests are failing

https://travis-ci.org/HaxeFoundation/hscript/jobs/281877857#L2798

Compiling group: runtime
g++ -D_CRT_SECURE_NO_DEPRECATE -DHX_UNDEFINE_H -c -fvisibility=hidden -O2 -fpic -fPIC -Wno-overflow -DHX_LINUX -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS(haxe) -DHXCPP_API_LEVEL=321(haxe) -m64 -DHXCPP_M64 -I/home/travis/haxe/lib/hxcpp/3,4,188/include ... tags=[haxe]
 - src/hx/Boot.cpp 
 - src/hx/Anon.cpp 
 - src/hx/CFFI.cpp  [haxe,static]
 - src/hx/Date.cpp 
 - src/hx/gc/GcCommon.cpp  [haxe,gc]
 - src/hx/gc/Immix.cpp  [haxe,gc]
 - src/hx/gc/GcRegCapture.cpp  [haxe,gc]
 - src/hx/Hash.cpp 
 - src/hx/Interface.cpp 
 - src/hx/Lib.cpp  [haxe,static]
 - src/hx/Object.cpp 
 - src/hx/StdLibs.cpp  [haxe,static]
 - src/hx/Debug.cpp 
 - src/hx/Thread.cpp 
 - src/Array.cpp 
 - src/hx/Class.cpp 
 - src/Dynamic.cpp 
 - src/Enum.cpp 
 - src/Math.cpp 
 - src/String.cpp  [haxe,hxstring]
Link: Test
Error : Could not load module std@get_env__1
The command "haxe bin/build-cpp.hxml          && ./bin/Test" exited with 255.

@hughsando

type casting

Hi. Is it possible to use type-casting at haxe-expression?
For example code a = cast(v, $MyClass); will return error EUnknownVariable(cast).

Thanks.

support "for" with const iterator ?

try to exec below script but get exception
"Error #1069: Property hasNext not found on IntIterator and there is no default value."

here is the script i run:
var t = 0; for(x in 1...10) t += x; t

Sandboxing

Is it possible to sandbox your scripts? Currently, a script has access to pretty much everything that is accessible from the context it's called - how do I constrain it? How do I make it access only the things I pass using variables property (like not let it instantiate classes imported in the calling context)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.