From 8dcebe3930809c0c1404fa37fceb5f48e5e0a6ee Mon Sep 17 00:00:00 2001 From: Jaime Humberto Macias Bustamante Date: Wed, 3 Sep 2025 20:13:39 -0700 Subject: [PATCH] Regular Expression support (regex) --- hscript/Bytes.hx | 2 ++ hscript/Expr.hx | 1 + hscript/Interp.hx | 2 ++ hscript/Parser.hx | 55 +++++++++++++++++++++++++++++++++++++++++++--- hscript/Printer.hx | 3 +++ 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/hscript/Bytes.hx b/hscript/Bytes.hx index 20619bf..b423d0e 100644 --- a/hscript/Bytes.hx +++ b/hscript/Bytes.hx @@ -134,6 +134,8 @@ class Bytes { // TODO case ECast(e, _): // TODO + case ERegex(e, f): + // TODO case EConst(c): doEncodeConst(c); case EIdent(v): diff --git a/hscript/Expr.hx b/hscript/Expr.hx index f313d19..3733594 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -84,6 +84,7 @@ enum Expr { EClass( name:String, fields:Array, ?extend:String, interfaces:Array, ?isFinal:Bool, ?isPrivate:Bool ); EEnum( en:EnumDecl, ?isAbstract:Bool ); ECast(e:Expr, ?t:CType); + ERegex(e:String, flags:String); } @:structInit diff --git a/hscript/Interp.hx b/hscript/Interp.hx index b548f83..6b4ca96 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -885,6 +885,8 @@ class Interp { variables.set(en.name, enumThingy); case ECast(e, _): // TODO return expr(e); + case ERegex(e, f): + return new EReg(e, f); case EConst(c): switch (c) { case CInt(v): return v; diff --git a/hscript/Parser.hx b/hscript/Parser.hx index ff75805..38ab0c1 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -43,6 +43,7 @@ enum Token { TDoubleDot; TMeta( s : String ); TPrepro( s : String ); + TRegex( e : String, f:String ); } @:structInit @@ -72,6 +73,11 @@ class Parser { **/ public var allowJSON : Bool; + /** + activate Regular Expression parsing + **/ + public var allowRegex : Bool; + /** allow types declarations **/ @@ -115,6 +121,8 @@ class Parser { #end + static inline var regexFlags: String = "igmsu"; + public function new() { line = 1; opChars = "+*/-=!><&|^%~"; @@ -513,6 +521,8 @@ class Parser { var e = parseExpr(); isVar = false; return mk(EMeta(id, args, e),p1); + case TRegex(e, f) if(allowRegex): + return mk(ERegex(e, f), p1); default: return unexpected(tk); } @@ -1863,7 +1873,7 @@ class Parser { return StringTools.fastCodeAt(input, readPos++); } - function readString( until:Int ):String { + function readString( until:Int, regex:Bool = false ):String { var c = 0; var b = new StringBuf(); var esc = false; @@ -1911,7 +1921,7 @@ class Parser { b.addChar(k); default: invalidChar(c); } - } else if( c == 92 ) + } else if( c == 92 && !regex) esc = true; else if( c == until ) break; @@ -1923,6 +1933,39 @@ class Parser { return b.toString(); } + function readFlags():String { + if(!allowRegex) return null; + var c = 0; + var b = new StringBuf(); + var old = line; + var s = input; + #if hscriptPos + var p1 = readPos - 1; + #end + + while(true) { + var c = readChar(); + if( StringTools.isEof(c) ) { + line = old; + error(EUnterminatedString, p1, p1); + break; + } + // semicolon + if(c == 59) { + this.char = c; + break; + } + + var f = String.fromCharCode(c); + if(regexFlags.indexOf(f) != -1) + b.addChar(c); + else + invalidChar(c); + } + + return b.toString(); + } + function token():Token { //function token(?infos : Null) { //function ttrace(v:Dynamic, ?infos : Null) { @@ -2146,7 +2189,7 @@ class Parser { invalidChar(char); default: if( ops[char] ) { - var op = String.fromCharCode(char); + var op:String = String.fromCharCode(char); while( true ) { char = readChar(); if( StringTools.isEof(char) ) char = 0; @@ -2156,6 +2199,11 @@ class Parser { } var pop = op; op += String.fromCharCode(char); + if( allowRegex && op == "~/") { + var e = readString(char, true); + var f = readFlags(); + return TRegex(e, f); + } if( !opPriority.exists(op) && opPriority.exists(pop) ) { if( op == "//" || op == "/*" ) return tokenComment(op,char); @@ -2370,6 +2418,7 @@ class Parser { case TDoubleDot: ":"; case TMeta(id): "@" + id; case TPrepro(id): "#" + id; + case TRegex(e, f): '~/$e/${f == null ? '' : f}'; } } diff --git a/hscript/Printer.hx b/hscript/Printer.hx index b671779..34fb765 100644 --- a/hscript/Printer.hx +++ b/hscript/Printer.hx @@ -186,6 +186,9 @@ class Printer { addType(t); add(")"); } + case ERegex(e, f): + add('~/$e/$f'); + add(';\n'); case EConst(c): switch( c ) { case CInt(i): add(i);