mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Add a !regmatch operator to do pattern matching in TableGen.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73074 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
06bfa33eef
commit
938c8ab0a0
@ -414,6 +414,9 @@ aborts with an error. </dd>
|
||||
<dt><tt>!subst(a, b, c)</tt></dt>
|
||||
<dd>If 'a' and 'b' are of string type or are symbol references, substitute
|
||||
'b' for 'a' in 'c.' This operation is analogous to $(subst) in GNU make.</dd>
|
||||
<dt><tt>!regmatch(a, b)</tt></dt>
|
||||
<dd>An integer {0,1} indicating whether string 'b' matched regular expression
|
||||
'a.'</dd>
|
||||
<dt><tt>!foreach(a, b, c)</tt></dt>
|
||||
<dd>For each member 'b' of dag or list 'a' apply operator 'c.' 'b' is a
|
||||
dummy variable that should be declared as a member variable of an instantiated
|
||||
|
11
test/TableGen/regmatch.td
Normal file
11
test/TableGen/regmatch.td
Normal file
@ -0,0 +1,11 @@
|
||||
// RUN: tblgen %s | grep {Match1 = 1} | count 1
|
||||
// RUN: tblgen %s | grep {Match2 = 1} | count 1
|
||||
|
||||
class Foo<string v> {
|
||||
string Value = v;
|
||||
int Match1 = !regmatch(".*ps$", v);
|
||||
int Match2 = !regmatch(".*pd$", v);
|
||||
}
|
||||
|
||||
def Bar : Foo<"addps">;
|
||||
def Baz : Foo<"addpd">;
|
@ -16,6 +16,8 @@
|
||||
#include "llvm/Support/Streams.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <ios>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -671,6 +673,36 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case REGMATCH: {
|
||||
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
|
||||
StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
|
||||
if (LHSs && RHSs) {
|
||||
regex_t compiled;
|
||||
int err = regcomp (&compiled, LHSs->getValue().c_str(), REG_EXTENDED);
|
||||
if (err != 0) {
|
||||
size_t length = regerror (err, &compiled, NULL, 0);
|
||||
char *buffer = new char[length];
|
||||
(void) regerror (err, &compiled, buffer, length);
|
||||
std::string errmsg = buffer;
|
||||
delete[] buffer;
|
||||
regfree(&compiled);
|
||||
throw errmsg;
|
||||
}
|
||||
int result = regexec(&compiled, RHSs->getValue().c_str(), 0, NULL, 0);
|
||||
if (result == REG_ESPACE) {
|
||||
size_t length = regerror (err, &compiled, NULL, 0);
|
||||
char *buffer = new char[length];
|
||||
(void) regerror (err, &compiled, buffer, length);
|
||||
std::string errmsg = buffer;
|
||||
delete[] buffer;
|
||||
regfree(&compiled);
|
||||
throw errmsg;
|
||||
}
|
||||
regfree(&compiled);
|
||||
return new IntInit(result == 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHL:
|
||||
case SRA:
|
||||
case SRL: {
|
||||
@ -710,6 +742,7 @@ std::string BinOpInit::getAsString() const {
|
||||
case SRA: Result = "!sra"; break;
|
||||
case SRL: Result = "!srl"; break;
|
||||
case STRCONCAT: Result = "!strconcat"; break;
|
||||
case REGMATCH: Result = "!regmatch"; break;
|
||||
case NAMECONCAT:
|
||||
Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ public:
|
||||
///
|
||||
class BinOpInit : public OpInit {
|
||||
public:
|
||||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
|
||||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT, REGMATCH };
|
||||
private:
|
||||
BinaryOp Opc;
|
||||
Init *LHS, *RHS;
|
||||
|
@ -447,6 +447,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
|
||||
if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
|
||||
if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat;
|
||||
if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
|
||||
if (Len == 8 && !memcmp(Start, "regmatch", 8)) return tgtok::XRegMatch;
|
||||
if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
|
||||
if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
|
||||
if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
|
||||
|
@ -46,7 +46,7 @@ namespace tgtok {
|
||||
|
||||
// !keywords.
|
||||
XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
|
||||
XForEach, XCar, XCdr, XNull, XIf,
|
||||
XForEach, XCar, XCdr, XNull, XIf, XRegMatch,
|
||||
|
||||
// Integer value.
|
||||
IntVal,
|
||||
|
@ -791,6 +791,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
|
||||
case tgtok::XSRL:
|
||||
case tgtok::XSHL:
|
||||
case tgtok::XStrConcat:
|
||||
case tgtok::XRegMatch:
|
||||
case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
|
||||
BinOpInit::BinaryOp Code;
|
||||
RecTy *Type = 0;
|
||||
@ -823,6 +824,11 @@ Init *TGParser::ParseOperation(Record *CurRec) {
|
||||
Code = BinOpInit::STRCONCAT;
|
||||
Type = new StringRecTy();
|
||||
break;
|
||||
case tgtok::XRegMatch:
|
||||
Lex.Lex(); // eat the operation
|
||||
Code = BinOpInit::REGMATCH;
|
||||
Type = new IntRecTy();
|
||||
break;
|
||||
case tgtok::XNameConcat:
|
||||
Lex.Lex(); // eat the operation
|
||||
Code = BinOpInit::NAMECONCAT;
|
||||
@ -1174,6 +1180,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
case tgtok::XSRL:
|
||||
case tgtok::XSHL:
|
||||
case tgtok::XStrConcat:
|
||||
case tgtok::XRegMatch:
|
||||
case tgtok::XNameConcat: // Value ::= !binop '(' Value ',' Value ')'
|
||||
case tgtok::XIf:
|
||||
case tgtok::XForEach:
|
||||
|
Loading…
Reference in New Issue
Block a user