]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/lex.c
canvas::Layout: support for contents margins.
[simgear.git] / simgear / nasal / lex.c
index 685393ad24447b0159f5306e61789e9b4f736104..00777e97d1caff67efa2bcff55323253d31fc149 100644 (file)
@@ -8,6 +8,9 @@ static const struct Lexeme {
     {"and", TOK_AND},
     {"or",  TOK_OR},
     {"!",   TOK_NOT},
+    {"&",   TOK_BIT_AND},
+    {"|",   TOK_BIT_OR},
+    {"^",   TOK_BIT_XOR},
     {"(", TOK_LPAR},
     {")", TOK_RPAR},
     {"[", TOK_LBRA},
@@ -49,6 +52,9 @@ static const struct Lexeme {
     {"*=", TOK_MULEQ},
     {"/=", TOK_DIVEQ},
     {"~=", TOK_CATEQ},
+    {"&=", TOK_BIT_ANDEQ},
+    {"|=", TOK_BIT_OREQ},
+    {"^=", TOK_BIT_XOREQ},
     {"forindex", TOK_FORINDEX},
 };
 
@@ -134,14 +140,16 @@ static void newToken(struct Parser* p, int pos, int type,
     tok->prev = last;
     tok->children = 0;
     tok->lastChild = 0;
-
-    // Context sensitivity hack: a "-" following a binary operator of
+    tok->rule = 0;
+    
+    // Context sensitivity hack: a "-" or "~" following a binary operator of
     // equal or higher precedence must be a unary negation.  Needed to
     // get precedence right in the parser for expressiong like "a * -2"
-    if(type == TOK_MINUS && tok->prev) {
+    if((type == TOK_MINUS || type == TOK_CAT) && tok->prev) {
         int pt = tok->prev->type;
-        if(pt==TOK_PLUS||pt==TOK_MINUS||pt==TOK_CAT||pt==TOK_MUL||pt==TOK_DIV)
-            tok->type = type = TOK_NEG;
+        if( pt==TOK_PLUS||pt==TOK_MINUS||pt==TOK_CAT||pt==TOK_MUL||pt==TOK_DIV
+         || pt==TOK_BIT_AND||pt==TOK_BIT_OR||pt==TOK_BIT_XOR )
+            tok->type = type = (type == TOK_MINUS ? TOK_NEG : TOK_BIT_NEG);
     }
 
     if(!p->tree.children) p->tree.children = tok;
@@ -244,12 +252,12 @@ static int lexStringLiteral(struct Parser* p, int index, char q)
     return i+1;
 }
 
-static int lexHexLiteral(struct Parser* p, int index)
+static int lexIntLiteral(struct Parser* p, int index, int base)
 {
     int nib, i = index;
     double d = 0;
-    while(i < p->len && (nib = hex(p->buf[i])) >= 0) {
-        d = d*16 + nib;
+    while(i < p->len && (nib = hex(p->buf[i])) >= 0 && nib < base) {
+        d = d * base + nib;
         i++;
     }
     newToken(p, index, TOK_LITERAL, 0, 0, d);
@@ -257,15 +265,20 @@ static int lexHexLiteral(struct Parser* p, int index)
 }
 
 #define ISNUM(c) ((c) >= '0' && (c) <= '9')
-#define NUMSTART(c) (ISNUM(c) || (c)=='+' || (c) == '-')
+#define ISHEX(c) (ISNUM(c) || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
+#define NUMSTART(c) (ISNUM(c) || (c) == '+' || (c) == '-')
 static int lexNumLiteral(struct Parser* p, int index)
 {
     int len = p->len, i = index;
     unsigned char* buf = (unsigned char*)p->buf;
     double d;
 
-    if(buf[0] == '0' && i+1<len && buf[i+1] == 'x')
-        return lexHexLiteral(p, index+2);
+    if( buf[i] == '0' && i + 2 < len ) {
+        if( buf[i+1] == 'x' && ISHEX(buf[i+2]) )
+            return lexIntLiteral(p, index+2, 16);
+        if( buf[i+1] == 'o' && ISNUM(buf[i+2]) )
+            return lexIntLiteral(p, index+2, 8);
+    }
 
     while(i<len && ISNUM(buf[i])) i++;
     if(i<len && buf[i] == '.') {