]> Shamusworld >> Repos - rmac/blobdiff - expr.c
Actually implement ^^FILESIZE this time :)
[rmac] / expr.c
diff --git a/expr.c b/expr.c
index 4318aa7d6b98f871e9a93ea5e72d2bfebf7c7d52..3a23e6e3cf68d4949ef1372ca98da1defecac7f6 100644 (file)
--- a/expr.c
+++ b/expr.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for all Atari computers
 // EXPR.C - Expression Analyzer
-// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -35,8 +35,8 @@ char itokcl[] = {
        CR_DEFINED, CR_REFERENCED,              // SUNARY (special unary)
        CR_STREQ, CR_MACDEF,
        CR_DATE, CR_TIME,
-       CR_ABSCOUNT, 0,
-       '!', '~', UNMINUS, 0,                   // UNARY
+       CR_ABSCOUNT, CR_FILESIZE, 0,
+       '!', '~', UNMINUS, UNLT, UNGT, 0,       // UNARY
        '*', '/', '%', 0,                               // MULT
        '+', '-', 0,                                    // ADD
        SHL, SHR, 0,                                    // SHIFT
@@ -49,6 +49,7 @@ char itokcl[] = {
 
 const char missym_error[] = "missing symbol";
 const char str_error[] = "missing symbol or string";
+const char noflt_error[] = "operator not usable with float";
 
 // Convert expression to postfix
 static PTR evalTokenBuffer;            // Deposit tokens here (this is really a
@@ -125,23 +126,24 @@ int expr0(void)
 //
 int expr1(void)
 {
-       TOKEN t;
-       SYM * sy;
-       char * p, * p2;
+       char * p;
        WORD w;
-       int j;
 
        int class = tokenClass[*tok];
 
-       if (*tok == '-' || *tok == '+' || class == UNARY)
+       if (*tok == '-' || *tok == '+' || *tok == '<' || *tok == '>' || class == UNARY)
        {
-               t = *tok++;
+               TOKEN t = *tok++;
 
                if (expr2() != OK)
                        return ERROR;
 
                if (t == '-')
                        t = UNMINUS;
+               else if (t == '<')
+                       t = UNLT;
+               else if (t == '>')
+                       t = UNGT;
 
                // With leading + we don't have to deposit anything to the buffer
                // because there's no unary '+' nor we have to do anything about it
@@ -153,8 +155,54 @@ int expr1(void)
                switch (*tok++)
                {
                case CR_ABSCOUNT:
+                       if (cursect != ABS)
+                       {
+                               *evalTokenBuffer.u32++ = CONST;
+                               *evalTokenBuffer.u64++ = sect[ABS].sloc;
+                       }
+                       else
+                       {
+                               *evalTokenBuffer.u32++ = CONST;
+                               *evalTokenBuffer.u64++ = sloc;
+                       }
+                       break;
+               case CR_FILESIZE:
+                       if (*tok++ != STRING)
+                               return error("^^FILESIZE expects filename inside string");
+
                        *evalTokenBuffer.u32++ = CONST;
-                       *evalTokenBuffer.u64++ = (uint64_t)sect[ABS].sloc;
+                       // @@copypasted from d_incbin, maybe factor this out somehow?
+                       // Attempt to open the include file in the current directory, then (if that
+                       // failed) try list of include files passed in the enviroment string or by
+                       // the "-d" option.
+                       int fd, i;
+                       char buf1[256];
+
+                       if ((fd = open(string[*tok], _OPEN_INC)) < 0)
+                       {
+                               for(i=0; nthpath("RMACPATH", i, buf1)!= 0; i++)
+                               {
+                                       fd = strlen(buf1);
+                                       
+                                       // Append path char if necessary
+                                       if ((fd > 0) && (buf1[fd - 1] != SLASHCHAR))
+                                               strcat(buf1, SLASHSTRING);
+                                       
+                                       strcat(buf1, string[*tok]);
+                                       
+                                       if ((fd = open(buf1, _OPEN_INC)) >= 0)
+                                               goto allright;
+                               }
+                               
+                               return error("cannot open: \"%s\"", string[tok[1]]);
+                       }
+
+allright:
+                       *evalTokenBuffer.u64++ = (uint64_t)lseek(fd, 0L, SEEK_END);
+                       close(fd);
+
+                       // Advance tok because of consumed string token
+                       tok++;
                        break;
                case CR_TIME:
                        *evalTokenBuffer.u32++ = CONST;
@@ -183,8 +231,9 @@ getsym:
                                return error(missym_error);
 
                        p = string[*tok++];
-                       j = (*p == '.' ? curenv : 0);
-                       w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0);
+                       int j = (*p == '.' ? curenv : 0);
+                       SYM * sy = lookup(p, LABEL, j);
+                       w = ((sy != NULL) && (sy->sattr & w ? 1 : 0));
                        *evalTokenBuffer.u32++ = CONST;
                        *evalTokenBuffer.u64++ = (uint64_t)w;
                        break;
@@ -201,7 +250,7 @@ getsym:
                        if (*tok != SYMBOL && *tok != STRING)
                                return error(str_error);
 
-                       p2 = string[tok[1]];
+                       char * p2 = string[tok[1]];
                        tok += 2;
 
                        w = (WORD)(!strcmp(p, p2));
@@ -222,9 +271,6 @@ getsym:
 //
 int expr2(void)
 {
-       char * p;
-       SYM * sy;
-       int j;
        PTR ptk;
 
        switch (*tok++)
@@ -242,9 +288,10 @@ int expr2(void)
                tok = ptk.u32;
                break;
        case SYMBOL:
-               p = string[*tok++];
-               j = (*p == '.' ? curenv : 0);
-               sy = lookup(p, LABEL, j);
+       {
+               char * p = string[*tok++];
+               int j = (*p == '.' ? curenv : 0);
+               SYM * sy = lookup(p, LABEL, j);
 
                if (sy == NULL)
                        sy = NewSymbol(p, LABEL, j);
@@ -264,6 +311,7 @@ int expr2(void)
                symbolPtr[symbolNum] = sy;
                symbolNum++;
                break;
+       }
        case STRING:
                *evalTokenBuffer.u32++ = CONST;
                *evalTokenBuffer.u64++ = str_value(string[*tok++]);
@@ -494,10 +542,15 @@ thrown away right here. What the hell is it for?
 
                        tok += 2;
                }
+               // Holy hell... This is likely due to the fact that LSR is mistakenly set as a SUNARY type... Need to fix this... !!! FIX !!!
+               else if (m6502)
+               {
+                       *evalTokenBuffer.u32++ = *tok++;
+               }
                else
                {
                        // Unknown type here... Alert the user!,
-                       error("undefined RISC register in expression");
+                       error("undefined RISC register in expression [token=$%X]", *tok);
                        // Prevent spurious error reporting...
                        tok++;
                        return ERROR;
@@ -691,6 +744,30 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
 
                        break;
 
+               case UNLT: // Unary < (get the low byte of a word)
+//printf("evexpr(): UNLT\n");
+                       if (*sattr & TDB)
+                               return error(seg_error);
+
+                       if (*sattr & FLOAT)
+                               return error(noflt_error);
+
+                       *sval = (int64_t)((*sval) & 0x00FF);
+                       *sattr = ABS | DEFINED;                 // Expr becomes absolute
+                       break;
+
+               case UNGT: // Unary > (get the high byte of a word)
+//printf("evexpr(): UNGT\n");
+                       if (*sattr & TDB)
+                               return error(seg_error);
+
+                       if (*sattr & FLOAT)
+                               return error(noflt_error);
+
+                       *sval = (int64_t)(((*sval) >> 8) & 0x00FF);
+                       *sattr = ABS | DEFINED;                 // Expr becomes absolute
+                       break;
+
                case '!':
 //printf("evexpr(): !\n");
                        if (*sattr & TDB)