From fe80e7e136445268e4b0610f9b523ec1695b9643 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Fri, 31 Mar 2023 12:58:53 +0200 Subject: [PATCH] update documentation --- README.md | 2 +- dist/xrfragment.js | 124 +++++++++++++++-------------- doc/{url.md => RFC.md} | 25 ++++-- make | 16 +++- src/xrfragment/Parser.hx | 83 ++++++++++++++++++++ src/xrfragment/Url.hx | 73 ++--------------- test/generated/test.js | 129 ++++++++++++++++-------------- test/generated/test.py | 166 +++++++++++++++++++++------------------ 8 files changed, 348 insertions(+), 270 deletions(-) rename doc/{url.md => RFC.md} (79%) create mode 100644 src/xrfragment/Parser.hx diff --git a/README.md b/README.md index 9740903..e8b25f5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # docs -* [Url](doc/url.md) +* [RFC](doc/RFC.md) # development diff --git a/dist/xrfragment.js b/dist/xrfragment.js index ca263c4..f0610d9 100644 --- a/dist/xrfragment.js +++ b/dist/xrfragment.js @@ -110,6 +110,65 @@ haxe_iterators_ArrayIterator.prototype = { return this.array[this.current++]; } }; +var xrfragment_Parser = $hx_exports["xrfragment"]["Parser"] = function() { }; +xrfragment_Parser.parse = function(key,value,resultMap) { + var Frag_h = Object.create(null); + Frag_h["pos"] = xrfragment_Type.isVector; + Frag_h["prio"] = xrfragment_Type.isInt; + if(Object.prototype.hasOwnProperty.call(Frag_h,key)) { + if(Frag_h[key].match(value)) { + var v = new xrfragment_Value(); + xrfragment_Parser.guessType(v,value); + if(value.split("|").length > 1) { + v.args = []; + var args = value.split("|"); + var _g = 0; + var _g1 = args.length; + while(_g < _g1) { + var i = _g++; + var x = new xrfragment_Value(); + xrfragment_Parser.guessType(x,args[i]); + v.args.push(x); + } + } + resultMap[key] = v; + } else { + console.log("src/xrfragment/Parser.hx:36:","[ i ] fragment '" + key + "' has incompatible value (" + value + ")"); + return false; + } + } else { + console.log("src/xrfragment/Parser.hx:37:","[ i ] fragment '" + key + "' does not exist or has no type defined (yet)"); + return false; + } + return true; +}; +xrfragment_Parser.guessType = function(v,str) { + v.string = str; + if(str.split(",").length > 1) { + var xyz = str.split(","); + if(xyz.length > 0) { + v.x = parseFloat(xyz[0]); + } + if(xyz.length > 1) { + v.y = parseFloat(xyz[1]); + } + if(xyz.length > 2) { + v.y = parseFloat(xyz[2]); + } + } + if(xrfragment_Type.isColor.match(str)) { + v.color = str; + } + if(xrfragment_Type.isFloat.match(str)) { + v.float = parseFloat(str); + } + if(xrfragment_Type.isInt.match(str)) { + v.int = Std.parseInt(str); + } +}; +var xrfragment_Value = function() { +}; +var xrfragment_Type = function() { }; var xrfragment_Query = function(str) { this.isNumber = new EReg("^[0-9\\.]+$",""); this.isClass = new EReg("^[-]?class$",""); @@ -206,79 +265,32 @@ xrfragment_Query.prototype = { }; var xrfragment_Url = $hx_exports["xrfragment"]["Url"] = function() { }; xrfragment_Url.parse = function(qs) { - var Frag_h = Object.create(null); - Frag_h["pos"] = xrfragment_Type.isVector; - Frag_h["prio"] = xrfragment_Type.isInt; var fragment = qs.split("#"); var splitArray = fragment[1].split("&"); - var regexPlus = new EReg("\\+","g"); var resultMap = { }; var _g = 0; var _g1 = splitArray.length; while(_g < _g1) { var i = _g++; var splitByEqual = splitArray[i].split("="); + var regexPlus = new EReg("\\+","g"); var key = splitByEqual[0]; - var v = new xrfragment_Value(); if(splitByEqual.length > 1) { var s = regexPlus.split(splitByEqual[1]).join(" "); var value = decodeURIComponent(s.split("+").join(" ")); - if(Object.prototype.hasOwnProperty.call(Frag_h,key)) { - if(Frag_h[key].match(value)) { - xrfragment_Url.guessType(v,value); - if(value.split("|").length > 1) { - v.args = []; - var args = value.split("|"); - var _g2 = 0; - var _g3 = args.length; - while(_g2 < _g3) { - var i1 = _g2++; - var x = new xrfragment_Value(); - xrfragment_Url.guessType(x,args[i1]); - v.args.push(x); - } - } - resultMap[key] = v; - } else { - console.log("src/xrfragment/Url.hx:46:","[ i ] fragment '" + key + "' has incompatible value (" + value + ")"); - } - } else { - console.log("src/xrfragment/Url.hx:47:","[ i ] fragment '" + key + "' does not exist or has no type defined (yet)"); - } + var ok = xrfragment_Parser.parse(key,value,resultMap); } } return resultMap; }; -xrfragment_Url.guessType = function(v,str) { - v.string = str; - if(str.split(",").length > 1) { - var xyz = str.split(","); - if(xyz.length > 0) { - v.x = parseFloat(xyz[0]); - } - if(xyz.length > 1) { - v.y = parseFloat(xyz[1]); - } - if(xyz.length > 2) { - v.y = parseFloat(xyz[2]); - } - } - if(xrfragment_Type.isColor.match(str)) { - v.color = str; - } - if(xrfragment_Type.isFloat.match(str)) { - v.float = parseFloat(str); - } - if(xrfragment_Type.isInt.match(str)) { - v.int = Std.parseInt(str); - } -}; -var xrfragment_Value = function() { -}; -var xrfragment_Type = function() { }; if(typeof(performance) != "undefined" ? typeof(performance.now) == "function" : false) { HxOverrides.now = performance.now.bind(performance); } +xrfragment_Parser.error = ""; +xrfragment_Type.isColor = new EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",""); +xrfragment_Type.isInt = new EReg("^[0-9]+$",""); +xrfragment_Type.isFloat = new EReg("^[0-9]+\\.[0-9]+$",""); +xrfragment_Type.isVector = new EReg("([,]+|\\w)",""); var xrfragment_Query_ok = $hx_exports["xrfragment"]["Query"]["ok"] = // haxe workarounds Array.prototype.contains = Array.prototype.includes @@ -309,9 +321,5 @@ var xrfragment_Query_ok = $hx_exports["xrfragment"]["Query"]["ok"] = } ; xrfragment_Url.error = ""; -xrfragment_Type.isColor = new EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",""); -xrfragment_Type.isInt = new EReg("^[0-9]+$",""); -xrfragment_Type.isFloat = new EReg("^[0-9]+\\.[0-9]+$",""); -xrfragment_Type.isVector = new EReg("([,]+|\\w)",""); })({}); var xrfragment = $hx_exports["xrfragment"]; diff --git a/doc/url.md b/doc/RFC.md similarity index 79% rename from doc/url.md rename to doc/RFC.md index 7a07066..abb1cd8 100644 --- a/doc/url.md +++ b/doc/RFC.md @@ -1,7 +1,19 @@ > version 1.0.0 +date: 2023-03-31T12:58:19+0200 (generated by `./make doc`) -# Fragment (values) +# Url parser (the gist of it) + +1. fragment URI starts with `#` +1. fragments are split by `&` +1. `=` is used to split fragment key/values +1. fragment-values are urlencoded (space becomes `+` using `encodeUriComponent` e.g.) +1. every recognized fragment key/value-pair is added to a central map/associative array/object +> version 1.0.0 + +date: 2023-03-31T12:58:19+0200 (generated by `./make doc`) + +# XR Fragments (key/value params) | param | type | category | example | |---------|---------------|-------------------------|------------------| @@ -9,12 +21,9 @@ | prio | int (-10..1) | Asset linking | `#prio=-5` | -# Url parser (the gist of it) +# Fragment parser (the gist of it) -1. fragment URI starts with `#` -1. fragments are split by `&` -1. fragment-values are urlencoded (space becomes `+` using `encodeUriComponent` e.g.) -1. `=` is used to split fragment key/values +1. each key has a regex to validate its value-type (see regexes) 1. `|` is used to split multiple/fallback values 1. `,` assumes 1D/2D/3D vector-values like x[,y[,z]] 1. parseFloat(..) and parseInt(..) is applied to vector/float and int values @@ -42,3 +51,7 @@ 1. integers are detected using regex `/^[0-9]+$/` 1. floats are detected using regex `/^[0-9]+\.[0-9]+$/` 1. vectors are detected using regex `/[,]/` (but can also be an string referring to an entity-ID in the asset) + +# Tests + +the spec is tested with [JSON unittests](src/spec) consumed by [Test.hx](src/Test.hx) to cross-test all languages. diff --git a/make b/make index 328002e..8e54a26 100755 --- a/make +++ b/make @@ -32,8 +32,20 @@ tests(){ } doc(){ - extract(){ cat $1 | awk '/\/\/ / { gsub(".*// ","",$0); gsub("# ","\n# ",$0);print $0; }'; } - { echo "> version $VERSION\n" && extract src/xrfragment/Url.hx; } > doc/url.md + generate(){ + echo "> version $VERSION" + echo "\ndate: $(date +"%Y-%m-%dT%H:%M:%S%z") (generated by \`./make doc\`)" + cat $1 | awk '/\/\/ / { + gsub(".*// ","",$0); + gsub("# ","\n# ",$0); + if( match($0,/^#include /) ){ system("cat "$2); next; } + if( match($0,/^#code /) ){ print "```\n"; system("cat "$2); print "```\n"; next; } + if( match($0,/^#sh /) ){ $1=""; system($0); next; } + print $0; + }' + } + generate src/xrfragment/Url.hx > doc/RFC.md + generate src/xrfragment/Parser.hx >> doc/RFC.md } test -z $1 && { try rm dist/* ; haxe build.hxml; exit $?; } diff --git a/src/xrfragment/Parser.hx b/src/xrfragment/Parser.hx new file mode 100644 index 0000000..f58d347 --- /dev/null +++ b/src/xrfragment/Parser.hx @@ -0,0 +1,83 @@ +package xrfragment; + +@:expose // <- makes the class reachable from plain JavaScript +@:keep // <- avoids accidental removal by dead code elimination + +class Parser { + + public static var error:String = ""; + + @:keep + public static function parse(key:String,value:String,resultMap:haxe.DynamicAccess):Bool { + // # XR Fragments (key/value params) + // + // | param | type | category | example | + var Frag:Map = new Map(); // |---------|---------------|-------------------------|------------------| + Frag.set("pos", Type.isVector); // | pos | 3D vector | HREF navigation/portals | `#pos=1,0,1` or `#pos=foo` | + Frag.set("prio", Type.isInt); // | prio | int (-10..1) | Asset linking | `#prio=-5` | + // + + // # Fragment parser (the gist of it) + if( Frag.exists(key) ){ // + if( Frag.get(key).match(value) ){ // 1. each key has a regex to validate its value-type (see regexes) + var v:Value = new Value(); + guessType(v, value); + // multiple/fallback values + if( value.split("|").length > 1 ){ // 1. `|` is used to split multiple/fallback values + v.args = new Array(); + var args:Array = value.split("|"); + for( i in 0...args.length){ + var x:Value = new Value(); + guessType(x, args[i]); + v.args.push( x ); + } + } + resultMap.set(key, v ); + }else { trace("[ i ] fragment '"+key+"' has incompatible value ("+value+")"); return false; } + }else { trace("[ i ] fragment '"+key+"' does not exist or has no type defined (yet)"); return false; } + + return true; + } + + @:keep + public static function guessType(v:Value, str:String):Void { + v.string = str; + if( str.split(",").length > 1){ // 1. `,` assumes 1D/2D/3D vector-values like x[,y[,z]] + var xyz:Array = str.split(","); // 1. parseFloat(..) and parseInt(..) is applied to vector/float and int values + if( xyz.length > 0 ) v.x = Std.parseFloat(xyz[0]); // 1. anything else will be treated as string-value + if( xyz.length > 1 ) v.y = Std.parseFloat(xyz[1]); // 1. incompatible value-types will be dropped / not used + if( xyz.length > 2 ) v.y = Std.parseFloat(xyz[2]); // + } // > the xrfragment specification should stay simple enough + // > for anyone to write a parser using either regexes or grammar/lexers + if( Type.isColor.match(str) ) v.color = str; // > therefore expressions/comprehensions are not supported (max wildcard/comparison operators for queries e.g.) + if( Type.isFloat.match(str) ) v.float = Std.parseFloat(str); + if( Type.isInt.match(str) ) v.int = Std.parseInt(str); + } + +} + // # Value types + // + // | type | info | format | example | +class Value { // |------|------|--------|----------------------------------| + public var x:Float; // |vector| x,y,z| comma-separated | #pos=1,2,3 | + public var y:Float; // + public var z:Float; // + public var color:String; // |string| color| FFFFFF (hex) | #fog=5m,FFAACC | + public var string:String; // |string| | | #q=-sun | + public var int:Int; // |int | | [-]x[xxxxx] | #price:>=100 | + public var float:Float; // |float | | [-]x[.xxxx] (ieee)| #prio=-20 + public var args:Array; // |array | mixed| \|-separated | #pos=0,0,0|90,0,0 | + public function new(){} // + // > rule for thumb: type-limitations will piggyback JSON limitations (IEEE floatsize e.g.) +} + // Regexes: +class Type { // + static public var isColor:EReg = ~/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; // 1. hex colors are detected using regex `/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/` + static public var isInt:EReg = ~/^[0-9]+$/; // 1. integers are detected using regex `/^[0-9]+$/` + static public var isFloat:EReg = ~/^[0-9]+\.[0-9]+$/; // 1. floats are detected using regex `/^[0-9]+\.[0-9]+$/` + static public var isVector:EReg = ~/([,]+|\w)/; // 1. vectors are detected using regex `/[,]/` (but can also be an string referring to an entity-ID in the asset) +} + +// # Tests +// +// the spec is tested with [JSON unittests](src/spec) consumed by [Test.hx](src/Test.hx) to cross-test all languages. diff --git a/src/xrfragment/Url.hx b/src/xrfragment/Url.hx index fda9277..f6f755b 100644 --- a/src/xrfragment/Url.hx +++ b/src/xrfragment/Url.hx @@ -1,5 +1,7 @@ package xrfragment; +import xrfragment.Parser; + @:expose // <- makes the class reachable from plain JavaScript @:keep // <- avoids accidental removal by dead code elimination @@ -7,85 +9,22 @@ class Url { public static var error:String = ""; - @:keep - public static function parse(qs:String):haxe.DynamicAccess { - // # Fragment (values) - // - // | param | type | category | example | - var Frag:Map = new Map(); // |---------|---------------|-------------------------|------------------| - Frag.set("pos", Type.isVector); // | pos | 3D vector | HREF navigation/portals | `#pos=1,0,1` or `#pos=foo` | - Frag.set("prio", Type.isInt); // | prio | int (-10..1) | Asset linking | `#prio=-5` | - // - // # Url parser (the gist of it) - // + @:keep // # Url parser (the gist of it) + public static function parse(qs:String):haxe.DynamicAccess { // var fragment:Array = qs.split("#"); // 1. fragment URI starts with `#` var splitArray:Array = fragment[1].split('&'); // 1. fragments are split by `&` - var regexPlus = ~/\+/g; // 1. fragment-values are urlencoded (space becomes `+` using `encodeUriComponent` e.g.) var resultMap:haxe.DynamicAccess = {}; for (i in 0...splitArray.length) { var splitByEqual = splitArray[i].split('='); // 1. `=` is used to split fragment key/values + var regexPlus = ~/\+/g; // 1. fragment-values are urlencoded (space becomes `+` using `encodeUriComponent` e.g.) var key:String = splitByEqual[0]; - var v:Value = new Value(); if (splitByEqual.length > 1) { var value:String = StringTools.urlDecode(regexPlus.split(splitByEqual[1]).join(" ")); - if( Frag.exists(key) ){ - if( Frag.get(key).match(value) ){ - guessType(v, value); - // multiple/fallback values - if( value.split("|").length > 1 ){ // 1. `|` is used to split multiple/fallback values - v.args = new Array(); - var args:Array = value.split("|"); - for( i in 0...args.length){ - var x:Value = new Value(); - guessType(x, args[i]); - v.args.push( x ); - } - } - resultMap.set(key, v ); - }else trace("[ i ] fragment '"+key+"' has incompatible value ("+value+")"); - }else trace("[ i ] fragment '"+key+"' does not exist or has no type defined (yet)"); + var ok:Bool = Parser.parse(key,value,resultMap); // 1. every recognized fragment key/value-pair is added to a central map/associative array/object } } return resultMap; } - @:keep - public static function guessType(v:Value, str:String):Void { - v.string = str; - if( str.split(",").length > 1){ // 1. `,` assumes 1D/2D/3D vector-values like x[,y[,z]] - var xyz:Array = str.split(","); // 1. parseFloat(..) and parseInt(..) is applied to vector/float and int values - if( xyz.length > 0 ) v.x = Std.parseFloat(xyz[0]); // 1. anything else will be treated as string-value - if( xyz.length > 1 ) v.y = Std.parseFloat(xyz[1]); // 1. incompatible value-types will be dropped / not used - if( xyz.length > 2 ) v.y = Std.parseFloat(xyz[2]); // - } // > the xrfragment specification should stay simple enough - // > for anyone to write a parser using either regexes or grammar/lexers - if( Type.isColor.match(str) ) v.color = str; // > therefore expressions/comprehensions are not supported (max wildcard/comparison operators for queries e.g.) - if( Type.isFloat.match(str) ) v.float = Std.parseFloat(str); - if( Type.isInt.match(str) ) v.int = Std.parseInt(str); - } - } - // # Value types - // - // | type | info | format | example | -class Value { // |------|------|--------|----------------------------------| - public var x:Float; // |vector| x,y,z| comma-separated | #pos=1,2,3 | - public var y:Float; // - public var z:Float; // - public var color:String; // |string| color| FFFFFF (hex) | #fog=5m,FFAACC | - public var string:String; // |string| | | #q=-sun | - public var int:Int; // |int | | [-]x[xxxxx] | #price:>=100 | - public var float:Float; // |float | | [-]x[.xxxx] (ieee)| #prio=-20 - public var args:Array; // |array | mixed| \|-separated | #pos=0,0,0|90,0,0 | - public function new(){} // - // > rule for thumb: type-limitations will piggyback JSON limitations (IEEE floatsize e.g.) -} - // Regexes: -class Type { // - static public var isColor:EReg = ~/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; // 1. hex colors are detected using regex `/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/` - static public var isInt:EReg = ~/^[0-9]+$/; // 1. integers are detected using regex `/^[0-9]+$/` - static public var isFloat:EReg = ~/^[0-9]+\.[0-9]+$/; // 1. floats are detected using regex `/^[0-9]+\.[0-9]+$/` - static public var isVector:EReg = ~/([,]+|\w)/; // 1. vectors are detected using regex `/[,]/` (but can also be an string referring to an entity-ID in the asset) -} - diff --git a/test/generated/test.js b/test/generated/test.js index 4bbf7d4..288e0ab 100644 --- a/test/generated/test.js +++ b/test/generated/test.js @@ -279,6 +279,68 @@ js_Boot.__string_rec = function(o,s) { return String(o); } }; +var xrfragment_Parser = $hx_exports["xrfragment"]["Parser"] = function() { }; +xrfragment_Parser.__name__ = true; +xrfragment_Parser.parse = function(key,value,resultMap) { + var Frag_h = Object.create(null); + Frag_h["pos"] = xrfragment_Type.isVector; + Frag_h["prio"] = xrfragment_Type.isInt; + if(Object.prototype.hasOwnProperty.call(Frag_h,key)) { + if(Frag_h[key].match(value)) { + var v = new xrfragment_Value(); + xrfragment_Parser.guessType(v,value); + if(value.split("|").length > 1) { + v.args = []; + var args = value.split("|"); + var _g = 0; + var _g1 = args.length; + while(_g < _g1) { + var i = _g++; + var x = new xrfragment_Value(); + xrfragment_Parser.guessType(x,args[i]); + v.args.push(x); + } + } + resultMap[key] = v; + } else { + console.log("src/xrfragment/Parser.hx:36:","[ i ] fragment '" + key + "' has incompatible value (" + value + ")"); + return false; + } + } else { + console.log("src/xrfragment/Parser.hx:37:","[ i ] fragment '" + key + "' does not exist or has no type defined (yet)"); + return false; + } + return true; +}; +xrfragment_Parser.guessType = function(v,str) { + v.string = str; + if(str.split(",").length > 1) { + var xyz = str.split(","); + if(xyz.length > 0) { + v.x = parseFloat(xyz[0]); + } + if(xyz.length > 1) { + v.y = parseFloat(xyz[1]); + } + if(xyz.length > 2) { + v.y = parseFloat(xyz[2]); + } + } + if(xrfragment_Type.isColor.match(str)) { + v.color = str; + } + if(xrfragment_Type.isFloat.match(str)) { + v.float = parseFloat(str); + } + if(xrfragment_Type.isInt.match(str)) { + v.int = Std.parseInt(str); + } +}; +var xrfragment_Value = function() { +}; +xrfragment_Value.__name__ = true; +var xrfragment_Type = function() { }; +xrfragment_Type.__name__ = true; var xrfragment_Query = function(str) { this.isNumber = new EReg("^[0-9\\.]+$",""); this.isClass = new EReg("^[-]?class$",""); @@ -458,78 +520,24 @@ xrfragment_Query.prototype = { var xrfragment_Url = $hx_exports["xrfragment"]["Url"] = function() { }; xrfragment_Url.__name__ = true; xrfragment_Url.parse = function(qs) { - var Frag_h = Object.create(null); - Frag_h["pos"] = xrfragment_Type.isVector; - Frag_h["prio"] = xrfragment_Type.isInt; var fragment = qs.split("#"); var splitArray = fragment[1].split("&"); - var regexPlus = new EReg("\\+","g"); var resultMap = { }; var _g = 0; var _g1 = splitArray.length; while(_g < _g1) { var i = _g++; var splitByEqual = splitArray[i].split("="); + var regexPlus = new EReg("\\+","g"); var key = splitByEqual[0]; - var v = new xrfragment_Value(); if(splitByEqual.length > 1) { var s = regexPlus.split(splitByEqual[1]).join(" "); var value = decodeURIComponent(s.split("+").join(" ")); - if(Object.prototype.hasOwnProperty.call(Frag_h,key)) { - if(Frag_h[key].match(value)) { - xrfragment_Url.guessType(v,value); - if(value.split("|").length > 1) { - v.args = []; - var args = value.split("|"); - var _g2 = 0; - var _g3 = args.length; - while(_g2 < _g3) { - var i1 = _g2++; - var x = new xrfragment_Value(); - xrfragment_Url.guessType(x,args[i1]); - v.args.push(x); - } - } - resultMap[key] = v; - } else { - console.log("src/xrfragment/Url.hx:46:","[ i ] fragment '" + key + "' has incompatible value (" + value + ")"); - } - } else { - console.log("src/xrfragment/Url.hx:47:","[ i ] fragment '" + key + "' does not exist or has no type defined (yet)"); - } + var ok = xrfragment_Parser.parse(key,value,resultMap); } } return resultMap; }; -xrfragment_Url.guessType = function(v,str) { - v.string = str; - if(str.split(",").length > 1) { - var xyz = str.split(","); - if(xyz.length > 0) { - v.x = parseFloat(xyz[0]); - } - if(xyz.length > 1) { - v.y = parseFloat(xyz[1]); - } - if(xyz.length > 2) { - v.y = parseFloat(xyz[2]); - } - } - if(xrfragment_Type.isColor.match(str)) { - v.color = str; - } - if(xrfragment_Type.isFloat.match(str)) { - v.float = parseFloat(str); - } - if(xrfragment_Type.isInt.match(str)) { - v.int = Std.parseInt(str); - } -}; -var xrfragment_Value = function() { -}; -xrfragment_Value.__name__ = true; -var xrfragment_Type = function() { }; -xrfragment_Type.__name__ = true; if(typeof(performance) != "undefined" ? typeof(performance.now) == "function" : false) { HxOverrides.now = performance.now.bind(performance); } @@ -537,6 +545,11 @@ String.__name__ = true; Array.__name__ = true; js_Boot.__toStr = ({ }).toString; Test.errors = 0; +xrfragment_Parser.error = ""; +xrfragment_Type.isColor = new EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",""); +xrfragment_Type.isInt = new EReg("^[0-9]+$",""); +xrfragment_Type.isFloat = new EReg("^[0-9]+\\.[0-9]+$",""); +xrfragment_Type.isVector = new EReg("([,]+|\\w)",""); var xrfragment_Query_ok = $hx_exports["xrfragment"]["Query"]["ok"] = // haxe workarounds Array.prototype.contains = Array.prototype.includes @@ -567,10 +580,6 @@ var xrfragment_Query_ok = $hx_exports["xrfragment"]["Query"]["ok"] = } ; xrfragment_Url.error = ""; -xrfragment_Type.isColor = new EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",""); -xrfragment_Type.isInt = new EReg("^[0-9]+$",""); -xrfragment_Type.isFloat = new EReg("^[0-9]+\\.[0-9]+$",""); -xrfragment_Type.isVector = new EReg("([,]+|\\w)",""); Test.main(); })({}); var xrfragment = $hx_exports["xrfragment"]; diff --git a/test/generated/test.py b/test/generated/test.py index 61e2cb7..7680be8 100644 --- a/test/generated/test.py +++ b/test/generated/test.py @@ -1360,6 +1360,90 @@ class HxString: return s[startIndex:(startIndex + _hx_len)] +class xrfragment_Parser: + _hx_class_name = "xrfragment.Parser" + __slots__ = () + _hx_statics = ["error", "parse", "guessType"] + + @staticmethod + def parse(key,value,resultMap): + Frag = haxe_ds_StringMap() + Frag.h["pos"] = xrfragment_Type.isVector + Frag.h["prio"] = xrfragment_Type.isInt + if (key in Frag.h): + _this = Frag.h.get(key,None) + _this.matchObj = python_lib_Re.search(_this.pattern,value) + if (_this.matchObj is not None): + v = xrfragment_Value() + xrfragment_Parser.guessType(v,value) + if (len(value.split("|")) > 1): + v.args = list() + args = value.split("|") + _g = 0 + _g1 = len(args) + while (_g < _g1): + i = _g + _g = (_g + 1) + x = xrfragment_Value() + xrfragment_Parser.guessType(x,(args[i] if i >= 0 and i < len(args) else None)) + _this = v.args + _this.append(x) + setattr(resultMap,(("_hx_" + key) if ((key in python_Boot.keywords)) else (("_hx_" + key) if (((((len(key) > 2) and ((ord(key[0]) == 95))) and ((ord(key[1]) == 95))) and ((ord(key[(len(key) - 1)]) != 95)))) else key)),v) + else: + print(str((((("[ i ] fragment '" + ("null" if key is None else key)) + "' has incompatible value (") + ("null" if value is None else value)) + ")"))) + return False + else: + print(str((("[ i ] fragment '" + ("null" if key is None else key)) + "' does not exist or has no type defined (yet)"))) + return False + return True + + @staticmethod + def guessType(v,_hx_str): + v.string = _hx_str + if (len(_hx_str.split(",")) > 1): + xyz = _hx_str.split(",") + if (len(xyz) > 0): + v.x = Std.parseFloat((xyz[0] if 0 < len(xyz) else None)) + if (len(xyz) > 1): + v.y = Std.parseFloat((xyz[1] if 1 < len(xyz) else None)) + if (len(xyz) > 2): + v.y = Std.parseFloat((xyz[2] if 2 < len(xyz) else None)) + _this = xrfragment_Type.isColor + _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) + if (_this.matchObj is not None): + v.color = _hx_str + _this = xrfragment_Type.isFloat + _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) + if (_this.matchObj is not None): + v.float = Std.parseFloat(_hx_str) + _this = xrfragment_Type.isInt + _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) + if (_this.matchObj is not None): + v.int = Std.parseInt(_hx_str) + + +class xrfragment_Value: + _hx_class_name = "xrfragment.Value" + __slots__ = ("x", "y", "color", "string", "int", "float", "args") + _hx_fields = ["x", "y", "color", "string", "int", "float", "args"] + + def __init__(self): + self.args = None + self.float = None + self.int = None + self.string = None + self.color = None + self.y = None + self.x = None + + + +class xrfragment_Type: + _hx_class_name = "xrfragment.Type" + __slots__ = () + _hx_statics = ["isColor", "isInt", "isFloat", "isVector"] + + class xrfragment_Query: _hx_class_name = "xrfragment.Query" __slots__ = ("str", "q", "isProp", "isExclude", "isClass", "isNumber") @@ -1495,8 +1579,8 @@ class xrfragment_Query: fails = 0 qualify = 0 def _hx_local_2(expr): - nonlocal conds nonlocal fails + nonlocal conds conds = (conds + 1) fails = (fails + (0 if expr else 1)) return expr @@ -1541,17 +1625,13 @@ class xrfragment_Query: class xrfragment_Url: _hx_class_name = "xrfragment.Url" __slots__ = () - _hx_statics = ["error", "parse", "guessType"] + _hx_statics = ["error", "parse"] @staticmethod def parse(qs): - Frag = haxe_ds_StringMap() - Frag.h["pos"] = xrfragment_Type.isVector - Frag.h["prio"] = xrfragment_Type.isInt fragment = qs.split("#") _this = (fragment[1] if 1 < len(fragment) else None) splitArray = _this.split("&") - regexPlus = EReg("\\+","g") resultMap = _hx_AnonObject({}) _g = 0 _g1 = len(splitArray) @@ -1560,81 +1640,14 @@ class xrfragment_Url: _g = (_g + 1) _this = (splitArray[i] if i >= 0 and i < len(splitArray) else None) splitByEqual = _this.split("=") + regexPlus = EReg("\\+","g") key = (splitByEqual[0] if 0 < len(splitByEqual) else None) - v = xrfragment_Value() if (len(splitByEqual) > 1): _this1 = regexPlus.split((splitByEqual[1] if 1 < len(splitByEqual) else None)) value = python_lib_urllib_Parse.unquote(" ".join([python_Boot.toString1(x1,'') for x1 in _this1])) - if (key in Frag.h): - _this2 = Frag.h.get(key,None) - _this2.matchObj = python_lib_Re.search(_this2.pattern,value) - if (_this2.matchObj is not None): - xrfragment_Url.guessType(v,value) - if (len(value.split("|")) > 1): - v.args = list() - args = value.split("|") - _g2 = 0 - _g3 = len(args) - while (_g2 < _g3): - i1 = _g2 - _g2 = (_g2 + 1) - x = xrfragment_Value() - xrfragment_Url.guessType(x,(args[i1] if i1 >= 0 and i1 < len(args) else None)) - _this3 = v.args - _this3.append(x) - setattr(resultMap,(("_hx_" + key) if ((key in python_Boot.keywords)) else (("_hx_" + key) if (((((len(key) > 2) and ((ord(key[0]) == 95))) and ((ord(key[1]) == 95))) and ((ord(key[(len(key) - 1)]) != 95)))) else key)),v) - else: - print(str((((("[ i ] fragment '" + ("null" if key is None else key)) + "' has incompatible value (") + ("null" if value is None else value)) + ")"))) - else: - print(str((("[ i ] fragment '" + ("null" if key is None else key)) + "' does not exist or has no type defined (yet)"))) + ok = xrfragment_Parser.parse(key,value,resultMap) return resultMap - @staticmethod - def guessType(v,_hx_str): - v.string = _hx_str - if (len(_hx_str.split(",")) > 1): - xyz = _hx_str.split(",") - if (len(xyz) > 0): - v.x = Std.parseFloat((xyz[0] if 0 < len(xyz) else None)) - if (len(xyz) > 1): - v.y = Std.parseFloat((xyz[1] if 1 < len(xyz) else None)) - if (len(xyz) > 2): - v.y = Std.parseFloat((xyz[2] if 2 < len(xyz) else None)) - _this = xrfragment_Type.isColor - _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) - if (_this.matchObj is not None): - v.color = _hx_str - _this = xrfragment_Type.isFloat - _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) - if (_this.matchObj is not None): - v.float = Std.parseFloat(_hx_str) - _this = xrfragment_Type.isInt - _this.matchObj = python_lib_Re.search(_this.pattern,_hx_str) - if (_this.matchObj is not None): - v.int = Std.parseInt(_hx_str) - - -class xrfragment_Value: - _hx_class_name = "xrfragment.Value" - __slots__ = ("x", "y", "color", "string", "int", "float", "args") - _hx_fields = ["x", "y", "color", "string", "int", "float", "args"] - - def __init__(self): - self.args = None - self.float = None - self.int = None - self.string = None - self.color = None - self.y = None - self.x = None - - - -class xrfragment_Type: - _hx_class_name = "xrfragment.Type" - __slots__ = () - _hx_statics = ["isColor", "isInt", "isFloat", "isVector"] - Math.NEGATIVE_INFINITY = float("-inf") Math.POSITIVE_INFINITY = float("inf") Math.NaN = float("nan") @@ -1643,10 +1656,11 @@ Math.PI = python_lib_Math.pi Test.errors = 0 python_Boot.keywords = set(["and", "del", "from", "not", "with", "as", "elif", "global", "or", "yield", "assert", "else", "if", "pass", "None", "break", "except", "import", "raise", "True", "class", "exec", "in", "return", "False", "continue", "finally", "is", "try", "def", "for", "lambda", "while"]) python_Boot.prefixLength = len("_hx_") -xrfragment_Url.error = "" +xrfragment_Parser.error = "" xrfragment_Type.isColor = EReg("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$","") xrfragment_Type.isInt = EReg("^[0-9]+$","") xrfragment_Type.isFloat = EReg("^[0-9]+\\.[0-9]+$","") xrfragment_Type.isVector = EReg("([,]+|\\w)","") +xrfragment_Url.error = "" Test.main()