Added REGEX!!!!!

Started working on automatic imports
This commit is contained in:
NeeEoo
2024-04-25 21:29:49 +02:00
parent 238c24501b
commit ad93c1bc18
8 changed files with 222 additions and 101 deletions
+1 -12
View File
@@ -48,6 +48,7 @@ enum Error
EUnexpected( s : String );
EUnterminatedString;
EUnterminatedComment;
EUnterminatedRegex;
EInvalidPreprocessor( msg : String );
EUnknownVariable( v : String );
EInvalidIterator( v : String );
@@ -79,16 +80,4 @@ enum abstract ErrorMessage(Int) from Int to Int {
case EXPECT_KEY_VALUE_SYNTAX: "Expected a => b";
}
}
public static function fromString(s:String):ErrorMessage {
return switch(s) {
case "INVALID_CHAR_CODE_MULTI": INVALID_CHAR_CODE_MULTI;
case "FROM_CHAR_CODE_NON_INT": FROM_CHAR_CODE_NON_INT;
case "EMPTY_INTERPOLATION": EMPTY_INTERPOLATION;
case "UNKNOWN_MAP_TYPE": UNKNOWN_MAP_TYPE;
case "UNKNOWN_MAP_TYPE_RUNTIME": UNKNOWN_MAP_TYPE_RUNTIME;
case "EXPECT_KEY_VALUE_SYNTAX": EXPECT_KEY_VALUE_SYNTAX;
default: throw "Unknown ErrorMessage";
}
}
}
+78 -1
View File
@@ -46,6 +46,7 @@ enum Token {
TEof;
TConst( c : Const );
TInterpString( tkl: Array<TokenList> ); // Stores the tokens that make up the interpolation string
TRegex( r: String, opt: String );
TId( s : String );
TOp( s : String );
TPOpen;
@@ -103,7 +104,7 @@ class Parser {
/**
resume from parsing errors (when parsing incomplete code, during completion for example)
**/
public var resumeErrors : Bool;
public var resumeErrors : Bool = false;
// implementation
var input : String;
@@ -479,6 +480,9 @@ class Parser {
}
}
return parseExprNext(e);
case TRegex(r, opt):
var e = mk(EParent(mk(ENew("EReg", [mk(EConst(CString(r))), mk(EConst(CString(opt)))]), p1)), p1);
return parseExprNext(e);
case TPOpen:
tk = token();
@@ -2315,6 +2319,27 @@ class Parser {
}
invalidChar(char);
default:
if(char == '~'.code) {
var char = readChar();
if( char == "/".code ) {
var regex = getRegexBody();
var opt = "";
while( true ) {
char = readChar();
if( char != 'g'.code && char != 'i'.code && char != 'm'.code && char != 's'.code && char != 'u'.code ) {
if( char >= 'a'.code && char <= 'z'.code ) {
error(ECustom('Invalid regex expression option "' + String.fromCharCode(char) + '"'), readPos, readPos);
}
this.char = char;
return TRegex(regex, opt);
}
opt += String.fromCharCode(char);
}
}
readPos--;
//this.char = peekChar();
}
if( ops[char] ) {
var op = String.fromCharCode(char);
while( true ) {
@@ -2354,6 +2379,57 @@ class Parser {
return null;
}
function getRegexBody() {
var regex = new StringBuf();
var esc = false;
var start = readPos-2;
while( true ) {
var char = readChar();
if(StringTools.isEof(char))
error(EUnterminatedRegex, start, start);
if( char == "\n".code || char == "\r".code )
error(EUnterminatedRegex, start, readPos-1);
if( esc ) {
esc = false;
switch( char ) {
case '/'.code: regex.addChar("/".code);
case 'n'.code: regex.addChar("\n".code);
case 'r'.code: regex.addChar("\r".code);
case 't'.code: regex.addChar("\t".code);
case '\\'.code, '$'.code, '.'.code, '*'.code, '+'.code, '^'.code, '|'.code, '{'.code, '}'.code, '['.code, ']'.code, '('.code, ')'.code, '?'.code, '-'.code:
regex.addChar(char);
case '0'.code | '1'.code | '2'.code | '3'.code | '4'.code | '5'.code | '6'.code | '7'.code | '8'.code | '9'.code:
regex.addChar("\\".code);
regex.addChar(char);
case 'w'.code, 'W'.code, 'b'.code, 'B'.code, 's'.code, 'S'.code, 'd'.code, 'D'.code, 'x'.code:
regex.addChar("\\".code);
regex.addChar(char);
case 'u'.code, 'U'.code: // UNICODE
regex.addChar("\\".code);
for( i in 0...4 ) {
var c = readChar();
if( StringTools.isEof(c) )
error(EUnterminatedRegex, start, readPos-1);
var h = convertHex(c);
if( h == -1 )
invalidChar(c);
regex.addChar(c);
}
default: invalidChar(char);
}
} else if( char == "\\".code ) {
esc = true;
continue;
} else if( char == "/".code )
break;
else
regex.addChar(char);
}
return regex.toString();
}
function preprocValue( id : String ) : Dynamic {
return preprocesorValues.get(id);
}
@@ -2531,6 +2607,7 @@ class Parser {
case TEof: "<eof>";
case TConst(c): constString(c);
case TInterpString(tg): constInterpString(tg);
case TRegex(r, opt): '~/' + r + '/' + opt;
case TId(s): s;
case TOp(s): s;
case TPOpen: "(";
+43 -2
View File
@@ -9,19 +9,54 @@ import hscript.Parser;
class Preprocessor {
static inline function expr(e:Expr) return Tools.expr(e);
private static var importStack:Array<Array<String>> = [];
private static function addImport(e:String, ?as:String) {
for(i in importStack)
if(i[0] == e)
return;
importStack.push([e, as]);
}
/**
* 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, doBlock:Bool = true):Expr {
public static function process(e:Expr, top:Bool = true):Expr {
importStack = [];
var e = _process(e, top);
// Automatically add imports for stuff
switch(expr(e)) {
case EBlock(exprs):
while(importStack.length > 0) {
var im = importStack.pop();
exprs.unshift(mk(EImport(im[0], im[1]), e));
}
return mk(EBlock(exprs), e);
default:
if(importStack.length > 0) {
var exprs = [];
while(importStack.length > 0) {
var im = importStack.pop();
exprs.unshift(mk(EImport(im[0], im[1]), 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;
//trace(expr(e));
e = Tools.map(e, function(e) {
return process(e);
return _process(e, false);
});
switch(expr(e)) {
@@ -42,6 +77,12 @@ class Preprocessor {
#else
throw Parser.getBaseError(EPreset(FROM_CHAR_CODE_NON_INT));
#end
case ENew("String", _):
addImport("String");
case ENew("EReg", _):
addImport("EReg");
case EField(expr(_) => EIdent("EReg"), "escape", _):
addImport("EReg");
default:
}
+1
View File
@@ -534,6 +534,7 @@ class Printer {
case EUnexpected(s): "Unexpected token: \""+s+"\"";
case EUnterminatedString: "Unterminated string";
case EUnterminatedComment: "Unterminated comment";
case EUnterminatedRegex: "Unterminated regular expression";
case EInvalidPreprocessor(str): "Invalid preprocessor (" + str + ")";
case EUnknownVariable(v): "Unknown variable: "+v;
case EInvalidIterator(v): "Invalid iterator: "+v;