#include "llvm/Module.h"
#include <list>
#include "llvmAsmParser.h"
+#include <ctype.h>
+#include <stdlib.h>
#define RET_TOK(type, Enum, sym) \
llvmAsmlval.type = Instruction::Enum; return sym
// TODO: All of the static identifiers are figured out by the lexer,
-// these should be hashed.
+// these should be hashed to reduce the lexer size
// atoull - Convert an ascii string of decimal digits into the unsigned long
}
+// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
+// appropriate character. If AllowNull is set to false, a \00 value will cause
+// an exception to be thrown.
+//
+// If AllowNull is set to true, the return value of the function points to the
+// last character of the string in memory.
+//
+char *UnEscapeLexed(char *Buffer, bool AllowNull = false) {
+ char *BOut = Buffer;
+ for (char *BIn = Buffer; *BIn; ) {
+ if (BIn[0] == '\\' && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
+ char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
+ *BOut = strtol(BIn+1, 0, 16); // Convert to number
+ if (!AllowNull && !*BOut)
+ ThrowException("String literal cannot accept \\00 escape!");
+
+ BIn[3] = Tmp; // Restore character
+ BIn += 3; // Skip over handled chars
+ ++BOut;
+ } else {
+ *BOut++ = *BIn++;
+ }
+ }
+
+ return BOut;
+}
+
#define YY_NEVER_INTERACTIVE 1
%}
/* Comments start with a ; and go till end of line */
Comment ;.*
-/* Variable(Def) identifiers start with a % sign */
+/* Variable(Value) identifiers start with a % sign */
VarID %[a-zA-Z$._][a-zA-Z$._0-9]*
/* Label identifiers end with a colon */
PInteger [0-9]+
NInteger -[0-9]+
+/* FPConstant - A Floating point constant.
+ TODO: Expand lexer to support 10e50 FP constant notation */
+FPConstant [0-9]+[.][0-9]*
+
%%
{Comment} { /* Ignore comments for now */ }
true { return TRUE; }
false { return FALSE; }
declare { return DECLARE; }
+global { return GLOBAL; }
+constant { return CONSTANT; }
+const { return CONST; }
+uninitialized { return UNINIT; }
implementation { return IMPLEMENTATION; }
-
-- { cerr << "deprecated argument '-' used!\n"; return '-'; }
-bb { cerr << "deprecated type 'bb' used!\n"; llvmAsmlval.TypeVal = Type::LabelTy; return LABEL;}
-
-void { llvmAsmlval.TypeVal = Type::VoidTy ; return VOID; }
-bool { llvmAsmlval.TypeVal = Type::BoolTy ; return BOOL; }
-sbyte { llvmAsmlval.TypeVal = Type::SByteTy ; return SBYTE; }
-ubyte { llvmAsmlval.TypeVal = Type::UByteTy ; return UBYTE; }
-short { llvmAsmlval.TypeVal = Type::ShortTy ; return SHORT; }
-ushort { llvmAsmlval.TypeVal = Type::UShortTy; return USHORT; }
-int { llvmAsmlval.TypeVal = Type::IntTy ; return INT; }
-uint { llvmAsmlval.TypeVal = Type::UIntTy ; return UINT; }
-long { llvmAsmlval.TypeVal = Type::LongTy ; return LONG; }
-ulong { llvmAsmlval.TypeVal = Type::ULongTy ; return ULONG; }
-float { llvmAsmlval.TypeVal = Type::FloatTy ; return FLOAT; }
-double { llvmAsmlval.TypeVal = Type::DoubleTy; return DOUBLE; }
-
-type { llvmAsmlval.TypeVal = Type::TypeTy ; return TYPE; }
-
-label { llvmAsmlval.TypeVal = Type::LabelTy ; return LABEL; }
+\.\.\. { return DOTDOTDOT; }
+string { return STRING; }
+null { return NULL_TOK; }
+to { return TO; }
+except { return EXCEPT; }
+
+void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; }
+bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; }
+sbyte { llvmAsmlval.PrimType = Type::SByteTy ; return SBYTE; }
+ubyte { llvmAsmlval.PrimType = Type::UByteTy ; return UBYTE; }
+short { llvmAsmlval.PrimType = Type::ShortTy ; return SHORT; }
+ushort { llvmAsmlval.PrimType = Type::UShortTy; return USHORT; }
+int { llvmAsmlval.PrimType = Type::IntTy ; return INT; }
+uint { llvmAsmlval.PrimType = Type::UIntTy ; return UINT; }
+long { llvmAsmlval.PrimType = Type::LongTy ; return LONG; }
+ulong { llvmAsmlval.PrimType = Type::ULongTy ; return ULONG; }
+float { llvmAsmlval.PrimType = Type::FloatTy ; return FLOAT; }
+double { llvmAsmlval.PrimType = Type::DoubleTy; return DOUBLE; }
+
+type { llvmAsmlval.PrimType = Type::TypeTy ; return TYPE; }
+
+label { llvmAsmlval.PrimType = Type::LabelTy ; return LABEL; }
+opaque { llvmAsmlval.TypeVal =
+ new PATypeHolder<Type>(OpaqueType::get());
+ return OPAQUE;
+ }
not { RET_TOK(UnaryOpVal, Not, NOT); }
setle { RET_TOK(BinaryOpVal, SetLE, SETLE); }
setge { RET_TOK(BinaryOpVal, SetGE, SETGE); }
-to { return TO; }
phi { RET_TOK(OtherOpVal, PHINode, PHI); }
call { RET_TOK(OtherOpVal, Call, CALL); }
cast { RET_TOK(OtherOpVal, Cast, CAST); }
ret { RET_TOK(TermOpVal, Ret, RET); }
br { RET_TOK(TermOpVal, Br, BR); }
switch { RET_TOK(TermOpVal, Switch, SWITCH); }
+invoke { RET_TOK(TermOpVal, Invoke, INVOKE); }
malloc { RET_TOK(MemOpVal, Malloc, MALLOC); }
free { RET_TOK(MemOpVal, Free, FREE); }
load { RET_TOK(MemOpVal, Load, LOAD); }
store { RET_TOK(MemOpVal, Store, STORE); }
-getfield { RET_TOK(MemOpVal, GetField, GETFIELD); }
-putfield { RET_TOK(MemOpVal, PutField, PUTFIELD); }
+getelementptr { RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); }
-{VarID} { llvmAsmlval.StrVal = strdup(yytext+1); return VAR_ID; }
-{Label} {
+{VarID} {
+ UnEscapeLexed(yytext+1);
+ llvmAsmlval.StrVal = strdup(yytext+1); // Skip %
+ return VAR_ID;
+ }
+{Label} {
yytext[strlen(yytext)-1] = 0; // nuke colon
- llvmAsmlval.StrVal = strdup(yytext);
+ UnEscapeLexed(yytext);
+ llvmAsmlval.StrVal = strdup(yytext);
return LABELSTR;
}
-{StringConstant} {
+{StringConstant} { // Note that we cannot unescape a string constant here! The
+ // string constant might contain a \00 which would not be
+ // understood by the string stuff. It is valid to make a
+ // [sbyte] c"Hello World\00" constant, for example.
+ //
yytext[strlen(yytext)-1] = 0; // nuke end quote
- llvmAsmlval.StrVal = strdup(yytext+1); // Nuke start quote
+ llvmAsmlval.StrVal = strdup(yytext+1); // Nuke start quote
return STRINGCONSTANT;
- }
+ }
{PInteger} { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; }
return SINTVAL;
}
+{FPConstant} { llvmAsmlval.FPVal = atof(yytext); return FPVAL; }
[ \t\n] { /* Ignore whitespace */ }
-. { /*printf("'%s'", yytext);*/ return yytext[0]; }
+. { return yytext[0]; }
%%