Cleanup code of rgbasm

Follow Linux kernel coding style.

Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
This commit is contained in:
Antonio Niño Díaz
2018-01-02 03:04:26 +01:00
parent 2ffaf72e39
commit 72f801283d
22 changed files with 2852 additions and 2678 deletions

View File

@@ -1,9 +1,9 @@
/* asm.h /*
* asm.h
* *
* Contains some assembler-wide defines and externs * Contains some assembler-wide defines and externs
*
* Copyright 1997 Carsten Sorensen
* *
* Copyright 1997 Carsten Sorensen
*/ */
#ifndef RGBDS_ASM_ASM_H #ifndef RGBDS_ASM_ASM_H
@@ -17,9 +17,9 @@
#include "asm/localasm.h" #include "asm/localasm.h"
#include "asm/symbol.h" #include "asm/symbol.h"
#define MAXUNIONS 128 #define MAXUNIONS 128
#define MAXMACROARGS 256 #define MAXMACROARGS 256
#define MAXINCPATHS 128 #define MAXINCPATHS 128
extern int32_t nLineNo; extern int32_t nLineNo;
extern uint32_t nTotalLines; extern uint32_t nTotalLines;
@@ -36,4 +36,4 @@ extern struct sSymbol *tHashedSymbols[HASHSIZE];
extern struct sSymbol *pPCSymbol; extern struct sSymbol *pPCSymbol;
extern bool oDontExpandStrings; extern bool oDontExpandStrings;
#endif /* // ASM_H */ #endif /* RGBDS_ASM_ASM_H */

View File

@@ -13,8 +13,7 @@ struct Charmap {
}; };
int32_t readUTF8Char(char *destination, char *source); int32_t readUTF8Char(char *destination, char *source);
void charmap_Sort();
int32_t charmap_Add(char *input, uint8_t output); int32_t charmap_Add(char *input, uint8_t output);
int32_t charmap_Convert(char **input); int32_t charmap_Convert(char **input);
#endif #endif /* RGBDS_ASM_CHARMAP_H */

View File

@@ -1,8 +1,8 @@
/* fstack.h /* fstack.h
* *
* Contains some assembler-wide defines and externs * Contains some assembler-wide defines and externs
* *
* Copyright 1997 Carsten Sorensen * Copyright 1997 Carsten Sorensen
* *
*/ */
@@ -31,16 +31,16 @@ struct sContext {
uint32_t nREPTBlockSize; uint32_t nREPTBlockSize;
}; };
void fstk_RunInclude(char *); void fstk_RunInclude(char *tzFileName);
extern void fstk_RunMacroArg(int32_t s); void fstk_RunMacroArg(int32_t s);
void fstk_Init(char *); void fstk_Init(char *s);
extern void fstk_Dump(void); void fstk_Dump(void);
extern void fstk_AddIncludePath(char *s); void fstk_AddIncludePath(char *s);
extern uint32_t fstk_RunMacro(char *s); uint32_t fstk_RunMacro(char *s);
extern void fstk_RunRept(uint32_t count); void fstk_RunRept(uint32_t count);
FILE * fstk_FindFile(char *); FILE *fstk_FindFile(char *fname);
int32_t fstk_GetLine(void); int32_t fstk_GetLine(void);
extern int yywrap(void); extern int yywrap(void);
#endif #endif /* RGBDS_ASM_FSTACK_H */

View File

@@ -4,8 +4,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#define LEXHASHSIZE (1 << 11) #define LEXHASHSIZE (1 << 11)
#define MAXSTRLEN 255 #define MAXSTRLEN 255
struct sLexInitString { struct sLexInitString {
char *tzName; char *tzName;
@@ -13,14 +13,15 @@ struct sLexInitString {
}; };
struct sLexFloat { struct sLexFloat {
uint32_t(*Callback) (char *s, uint32_t size); uint32_t (*Callback)(char *s, uint32_t size);
uint32_t nToken; uint32_t nToken;
}; };
struct yy_buffer_state { struct yy_buffer_state {
char *pBufferRealStart; // actual starting address /* Actual starting address */
char *pBufferStart; // address where the data is initially written char *pBufferRealStart;
// after the "safety margin" /* Address where the data is initially written after a safety margin */
char *pBufferStart;
char *pBuffer; char *pBuffer;
uint32_t nBufferSize; uint32_t nBufferSize;
uint32_t oAtLineStart; uint32_t oAtLineStart;
@@ -30,35 +31,36 @@ enum eLexerState {
LEX_STATE_NORMAL, LEX_STATE_NORMAL,
LEX_STATE_MACROARGS LEX_STATE_MACROARGS
}; };
#define INITIAL 0
#define macroarg 3 #define INITIAL 0
#define macroarg 3
typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef struct yy_buffer_state *YY_BUFFER_STATE;
extern void yy_set_state(enum eLexerState i); void yy_set_state(enum eLexerState i);
extern YY_BUFFER_STATE yy_create_buffer(FILE * f); YY_BUFFER_STATE yy_create_buffer(FILE *f);
extern YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size); YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size);
extern void yy_delete_buffer(YY_BUFFER_STATE); void yy_delete_buffer(YY_BUFFER_STATE buf);
extern void yy_switch_to_buffer(YY_BUFFER_STATE); void yy_switch_to_buffer(YY_BUFFER_STATE buf);
extern uint32_t lex_FloatAlloc(struct sLexFloat * tok); uint32_t lex_FloatAlloc(const struct sLexFloat *tok);
extern void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end); void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end);
extern void lex_Init(void); void lex_Init(void);
extern void lex_AddStrings(struct sLexInitString * lex); void lex_AddStrings(const struct sLexInitString *lex);
extern void lex_SetBuffer(char *buffer, uint32_t len); void lex_SetBuffer(char *buffer, uint32_t len);
extern uint32_t yylex(void); uint32_t yylex(void);
extern void yyunput(char c); void yyunput(char c);
extern void yyunputstr(char *s); void yyunputstr(char *s);
extern void yyskipbytes(uint32_t count); void yyskipbytes(uint32_t count);
extern void yyunputbytes(uint32_t count); void yyunputbytes(uint32_t count);
extern YY_BUFFER_STATE pCurrentBuffer; extern YY_BUFFER_STATE pCurrentBuffer;
extern void upperstring(char *s); void upperstring(char *s);
extern void lowerstring(char *s); void lowerstring(char *s);
#endif #endif /* RGBDS_ASM_LEXER_H */

View File

@@ -1,93 +1,95 @@
/* GB Z80 instruction groups #ifndef RGBDS_ASM_LOCALASM_H
#define RGBDS_ASM_LOCALASM_H
n3 = 3-bit
n = 8-bit
nn = 16-bit
* ADC A,n : 0xCE
* ADC A,r : 0x88|r
* ADD A,n : 0xC6
* ADD A,r : 0x80|r
* ADD HL,ss : 0x09|(ss<<4)
* ADD SP,n : 0xE8
* AND A,n : 0xE6
* AND A,r : 0xA0|r
* BIT n3,r : 0xCB 0x40|(n3<<3)|r
* CALL cc,nn : 0xC4|(cc<<3)
* CALL nn : 0xCD
* CCF : 0x3F
* CP A,n : 0xFE
* CP A,r : 0xB8|r
* CPL : 0x2F
* DAA : 0x27
* DEC r : 0x05|(r<<3)
* DEC ss : 0x0B|(ss<<4)
* DI : 0xF3
* EI : 0xFB
* HALT : 0x76
* INC r : 0x04|(r<<3)
* INC ss : 0x03|(ss<<4)
* JP HL : 0xE9
* JP cc,nn : 0xC2|(cc<<3)
* JP nn : 0xC3|(cc<<3)
* JR n : 0x18
* JR cc,n : 0x20|(cc<<3)
* LD (nn),SP : 0x08
* LD ($FF00+C),A : 0xE2
* LD ($FF00+n),A : 0xE0
* LD (nn),A : 0xEA
* LD (rr),A : 0x02|(rr<<4) // HL+ and HL- included
* LD A,($FF00+C) : 0xF2
* LD A,($FF00+n) : 0xF0
* LD A,(nn) : 0xFA
* LD A,(rr) : 0x0A|(rr<<4) // HL+ and HL- included
* LD HL,SP+n : 0xF8
* LD SP,HL : 0xF9
* LD r,n : 0x06|(r<<3)
* LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
* LD ss,nn : 0x01|(ss<<4)
* NOP : 0x00
* OR A,n : 0xF6
* OR A,r : 0xB0|r
* POP tt : 0xC1|(tt<<4)
* PUSH tt : 0xC5|(tt<<4)
* RES n3,r : 0xCB 0x80|(n3<<3)|r
* RET : 0xC9
* RET cc : 0xC0|(cc<<3)
* RETI : 0xD9
* RL r : 0xCB 0x10|r
* RLA : 0x17
* RLC r : 0xCB 0x00|r
* RLCA : 0x07
* RR r : 0xCB 0x18|r
* RRA : 0x1F
* RRC r : 0xCB 0x08|r
* RRCA : 0x0F
* RST n : 0xC7|n
* SBC A,n : 0xDE
* SBC A,r : 0x98|r
* SCF : 0x37
* SET n3,r : 0xCB 0xC0|(n8<<3)|r
* SLA r : 0xCB 0x20|r
* SRA r : 0xCB 0x28|r
* SRL r : 0xCB 0x38|r
* STOP : 0x10 0x00
* SUB A,n : 0xD6
* SUB A,r : 0x90|r
* SWAP r : 0xCB 0x30|r
* XOR A,n : 0xEE
* XOR A,r : 0xA8|r
/*
* GB Z80 instruction groups
*
* n3 = 3-bit
* n = 8-bit
* nn = 16-bit
*
* ADC A,n : 0xCE
* ADC A,r : 0x88|r
* ADD A,n : 0xC6
* ADD A,r : 0x80|r
* ADD HL,ss : 0x09|(ss<<4)
* ADD SP,n : 0xE8
* AND A,n : 0xE6
* AND A,r : 0xA0|r
* BIT n3,r : 0xCB 0x40|(n3<<3)|r
* CALL cc,nn : 0xC4|(cc<<3)
* CALL nn : 0xCD
* CCF : 0x3F
* CP A,n : 0xFE
* CP A,r : 0xB8|r
* CPL : 0x2F
* DAA : 0x27
* DEC r : 0x05|(r<<3)
* DEC ss : 0x0B|(ss<<4)
* DI : 0xF3
* EI : 0xFB
* HALT : 0x76
* INC r : 0x04|(r<<3)
* INC ss : 0x03|(ss<<4)
* JP HL : 0xE9
* JP cc,nn : 0xC2|(cc<<3)
* JP nn : 0xC3|(cc<<3)
* JR n : 0x18
* JR cc,n : 0x20|(cc<<3)
* LD (nn),SP : 0x08
* LD ($FF00+C),A : 0xE2
* LD ($FF00+n),A : 0xE0
* LD (nn),A : 0xEA
* LD (rr),A : 0x02|(rr<<4) // HL+ and HL- included
* LD A,($FF00+C) : 0xF2
* LD A,($FF00+n) : 0xF0
* LD A,(nn) : 0xFA
* LD A,(rr) : 0x0A|(rr<<4) // HL+ and HL- included
* LD HL,SP+n : 0xF8
* LD SP,HL : 0xF9
* LD r,n : 0x06|(r<<3)
* LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed
* LD ss,nn : 0x01|(ss<<4)
* NOP : 0x00
* OR A,n : 0xF6
* OR A,r : 0xB0|r
* POP tt : 0xC1|(tt<<4)
* PUSH tt : 0xC5|(tt<<4)
* RES n3,r : 0xCB 0x80|(n3<<3)|r
* RET : 0xC9
* RET cc : 0xC0|(cc<<3)
* RETI : 0xD9
* RL r : 0xCB 0x10|r
* RLA : 0x17
* RLC r : 0xCB 0x00|r
* RLCA : 0x07
* RR r : 0xCB 0x18|r
* RRA : 0x1F
* RRC r : 0xCB 0x08|r
* RRCA : 0x0F
* RST n : 0xC7|n
* SBC A,n : 0xDE
* SBC A,r : 0x98|r
* SCF : 0x37
* SET n3,r : 0xCB 0xC0|(n8<<3)|r
* SLA r : 0xCB 0x20|r
* SRA r : 0xCB 0x28|r
* SRL r : 0xCB 0x38|r
* STOP : 0x10 0x00
* SUB A,n : 0xD6
* SUB A,r : 0x90|r
* SWAP r : 0xCB 0x30|r
* XOR A,n : 0xEE
* XOR A,r : 0xA8|r
*/ */
#define NAME_DB "db" #define NAME_DB "db"
#define NAME_DW "dw" #define NAME_DW "dw"
#define NAME_DL "dl" #define NAME_DL "dl"
#define NAME_RB "rb" #define NAME_RB "rb"
#define NAME_RW "rw" #define NAME_RW "rw"
/* "r" defs */ /* "r" defs */
enum { enum {
REG_B = 0, REG_B = 0,
REG_C, REG_C,
@@ -98,36 +100,30 @@ enum {
REG_HL_IND, REG_HL_IND,
REG_A REG_A
}; };
/* "rr" defs */
/* "rr" defs */
enum { enum {
REG_BC_IND = 0, REG_BC_IND = 0,
REG_DE_IND, REG_DE_IND,
REG_HL_INDINC, REG_HL_INDINC,
REG_HL_INDDEC, REG_HL_INDDEC,
}; };
/* "ss" defs */
/* "ss" defs (SP) and "tt" defs (AF) */
enum { enum {
REG_BC = 0, REG_BC = 0,
REG_DE, REG_DE = 1,
REG_HL, REG_HL = 2,
REG_SP REG_SP = 3,
REG_AF = 3
}; };
/* "tt" defs */
/*
#define REG_BC 0
#define REG_DE 1
#define REG_HL 2
*/
#define REG_AF 3
/* "cc" defs */ /* "cc" defs */
enum { enum {
CC_NZ = 0, CC_NZ = 0,
CC_Z, CC_Z,
CC_NC, CC_NC,
CC_C CC_C
}; };
#endif /* RGBDS_ASM_LOCALASM_H */

View File

@@ -1,8 +1,9 @@
#ifndef RGBDS_MAIN_H #ifndef RGBDS_MAIN_H
#define RGBDS_MAIN_H #define RGBDS_MAIN_H
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include "extern/stdnoreturn.h" #include "extern/stdnoreturn.h"
struct sOptions { struct sOptions {
@@ -12,8 +13,7 @@ struct sOptions {
bool verbose; bool verbose;
bool haltnop; bool haltnop;
bool exportall; bool exportall;
bool warnings; /* true to enable warnings, false to disable them. */ bool warnings; /* True to enable warnings, false to disable them. */
//-1 == random
}; };
extern char *tzNewMacro; extern char *tzNewMacro;
@@ -23,9 +23,10 @@ extern int32_t nBinaryID;
extern struct sOptions DefaultOptions; extern struct sOptions DefaultOptions;
extern struct sOptions CurrentOptions; extern struct sOptions CurrentOptions;
extern void opt_Push(void);
extern void opt_Pop(void); void opt_Push(void);
extern void opt_Parse(char *s); void opt_Pop(void);
void opt_Parse(char *s);
/* /*
* Used for errors that compromise the whole assembly process by affecting the * Used for errors that compromise the whole assembly process by affecting the
@@ -35,6 +36,7 @@ extern void opt_Parse(char *s);
* when it fails to allocate memory). * when it fails to allocate memory).
*/ */
noreturn void fatalerror(const char *fmt, ...); noreturn void fatalerror(const char *fmt, ...);
/* /*
* Used for errors that make it impossible to assemble correctly, but don't * Used for errors that make it impossible to assemble correctly, but don't
* affect the following code. The code will fail to assemble but the user will * affect the following code. The code will fail to assemble but the user will
@@ -42,17 +44,18 @@ noreturn void fatalerror(const char *fmt, ...);
* once. * once.
*/ */
void yyerror(const char *fmt, ...); void yyerror(const char *fmt, ...);
/* /*
* Used to warn the user about problems that don't prevent the generation of * Used to warn the user about problems that don't prevent the generation of
* valid code. * valid code.
*/ */
void warning(const char *fmt, ...); void warning(const char *fmt, ...);
#define YY_FATAL_ERROR fatalerror #define YY_FATAL_ERROR fatalerror
#ifdef YYLMAX #ifdef YYLMAX
#undef YYLMAX #undef YYLMAX
#endif #endif
#define YYLMAX 65536 #define YYLMAX 65536
#endif #endif /* RGBDS_MAIN_H */

View File

@@ -58,4 +58,5 @@ enum {
PATCH_WORD_L, PATCH_WORD_L,
PATCH_LONG_L PATCH_LONG_L
}; };
#endif
#endif /* RGBDS_ASM_LINK_H */

View File

@@ -18,4 +18,4 @@ int32_t math_Round(int32_t i);
int32_t math_Ceil(int32_t i); int32_t math_Ceil(int32_t i);
int32_t math_Floor(int32_t i); int32_t math_Floor(int32_t i);
#endif #endif /* RGBDS_ASM_MATH_H */

View File

@@ -21,21 +21,23 @@ struct Section {
void out_PrepPass2(void); void out_PrepPass2(void);
void out_SetFileName(char *s); void out_SetFileName(char *s);
void out_NewSection(char *pzName, uint32_t secttype); void out_NewSection(char *pzName, uint32_t secttype);
void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank); void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org,
void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment, int32_t bank); int32_t bank);
void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment,
int32_t bank);
void out_AbsByte(int32_t b); void out_AbsByte(int32_t b);
void out_AbsByteGroup(char *s, int32_t length); void out_AbsByteGroup(char *s, int32_t length);
void out_RelByte(struct Expression * expr); void out_RelByte(struct Expression *expr);
void out_RelWord(struct Expression * expr); void out_RelWord(struct Expression *expr);
void out_PCRelByte(struct Expression * expr); void out_PCRelByte(struct Expression *expr);
void out_WriteObject(void); void out_WriteObject(void);
void out_Skip(int32_t skip); void out_Skip(int32_t skip);
void out_BinaryFile(char *s); void out_BinaryFile(char *s);
void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length); void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length);
void out_String(char *s); void out_String(char *s);
void out_AbsLong(int32_t b); void out_AbsLong(int32_t b);
void out_RelLong(struct Expression * expr); void out_RelLong(struct Expression *expr);
void out_PushSection(void); void out_PushSection(void);
void out_PopSection(void); void out_PopSection(void);
#endif #endif /* RGBDS_ASM_OUTPUT_H */

View File

@@ -12,36 +12,54 @@ struct Expression {
uint32_t isPCRel; uint32_t isPCRel;
}; };
uint32_t rpn_isReloc(struct Expression * expr); uint32_t rpn_isReloc(const struct Expression *expr);
uint32_t rpn_isPCRelative(struct Expression * expr); uint32_t rpn_isPCRelative(const struct Expression *expr);
void rpn_Symbol(struct Expression * expr, char *tzSym); void rpn_Symbol(struct Expression *expr, char *tzSym);
void rpn_Number(struct Expression * expr, uint32_t i); void rpn_Number(struct Expression *expr, uint32_t i);
void rpn_LOGNOT(struct Expression * expr, struct Expression * src1); void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
void rpn_LOGOR(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGOR(struct Expression *expr, const struct Expression *src1,
void rpn_LOGAND(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_LOGEQU(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGAND(struct Expression *expr, const struct Expression *src1,
void rpn_LOGGT(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_LOGLT(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGEQU(struct Expression *expr, const struct Expression *src1,
void rpn_LOGGE(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_LOGLE(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGGT(struct Expression *expr, const struct Expression *src1,
void rpn_LOGNE(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_ADD(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGLT(struct Expression *expr, const struct Expression *src1,
void rpn_SUB(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_XOR(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGGE(struct Expression *expr, const struct Expression *src1,
void rpn_OR(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_AND(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGLE(struct Expression *expr, const struct Expression *src1,
void rpn_SHL(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_SHR(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_LOGNE(struct Expression *expr, const struct Expression *src1,
void rpn_MUL(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_DIV(struct Expression * expr, struct Expression * src1, struct Expression * src2); void rpn_ADD(struct Expression *expr, const struct Expression *src1,
void rpn_MOD(struct Expression * expr, struct Expression * src1, struct Expression * src2); const struct Expression *src2);
void rpn_HIGH(struct Expression * expr, struct Expression * src); void rpn_SUB(struct Expression *expr, const struct Expression *src1,
void rpn_LOW(struct Expression * expr, struct Expression * src); const struct Expression *src2);
void rpn_UNNEG(struct Expression * expr, struct Expression * src); void rpn_XOR(struct Expression *expr, const struct Expression *src1,
void rpn_UNNOT(struct Expression * expr, struct Expression * src); const struct Expression *src2);
uint16_t rpn_PopByte(struct Expression * expr); void rpn_OR(struct Expression *expr, const struct Expression *src1,
void rpn_Bank(struct Expression * expr, char *tzSym); const struct Expression *src2);
void rpn_Reset(struct Expression * expr); void rpn_AND(struct Expression *expr, const struct Expression *src1,
void rpn_CheckHRAM(struct Expression * expr, struct Expression * src1); const struct Expression *src2);
void rpn_SHL(struct Expression *expr, const struct Expression *src1,
const struct Expression *src2);
void rpn_SHR(struct Expression *expr, const struct Expression *src1,
const struct Expression *src2);
void rpn_MUL(struct Expression *expr, const struct Expression *src1,
const struct Expression *src2);
void rpn_DIV(struct Expression *expr, const struct Expression *src1,
const struct Expression *src2);
void rpn_MOD(struct Expression *expr, const struct Expression *src1,
const struct Expression *src2);
void rpn_HIGH(struct Expression *expr, const struct Expression *src);
void rpn_LOW(struct Expression *expr, const struct Expression *src);
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
uint16_t rpn_PopByte(struct Expression *expr);
void rpn_Bank(struct Expression *expr, char *tzSym);
void rpn_Reset(struct Expression *expr);
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
#endif #endif /* RGBDS_ASM_RPN_H */

View File

@@ -5,8 +5,8 @@
#include "types.h" #include "types.h"
#define HASHSIZE (1 << 16) #define HASHSIZE (1 << 16)
#define MAXSYMLEN 256 #define MAXSYMLEN 256
struct sSymbol { struct sSymbol {
char tzName[MAXSYMLEN + 1]; char tzName[MAXSYMLEN + 1];
@@ -17,27 +17,31 @@ struct sSymbol {
struct Section *pSection; struct Section *pSection;
uint32_t ulMacroSize; uint32_t ulMacroSize;
char *pMacro; char *pMacro;
int32_t(*Callback) (struct sSymbol *); int32_t (*Callback)(struct sSymbol *);
char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */ char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */
uint32_t nFileLine; /* Line where the symbol was defined. */ uint32_t nFileLine; /* Line where the symbol was defined. */
}; };
#define SYMF_RELOC 0x001 /* symbol will be reloc'ed during
* linking, it's absolute value is /* Symbol will be relocated during linking, it's absolute value is unknown */
* unknown */ #define SYMF_RELOC 0x001
#define SYMF_EQU 0x002 /* symbol is defined using EQU, will /* Symbol is defined using EQU, will not be changed during linking */
* not be changed during linking */ #define SYMF_EQU 0x002
#define SYMF_SET 0x004 /* symbol is (re)defined using SET, /* Symbol is (re)defined using SET, will not be changed during linking */
* will not be changed during linking */ #define SYMF_SET 0x004
#define SYMF_EXPORT 0x008 /* symbol should be exported */ /* Symbol should be exported */
#define SYMF_IMPORT 0x010 /* symbol is imported, it's value is #define SYMF_EXPORT 0x008
* unknown */ /* Symbol is imported, it's value is unknown */
#define SYMF_LOCAL 0x020 /* symbol is a local symbol */ #define SYMF_IMPORT 0x010
#define SYMF_DEFINED 0x040 /* symbol has been defined, not only /* Symbol is a local symbol */
* referenced */ #define SYMF_LOCAL 0x020
#define SYMF_MACRO 0x080 /* symbol is a macro */ /* Symbol has been defined, not only referenced */
#define SYMF_STRING 0x100 /* symbol is a stringsymbol */ #define SYMF_DEFINED 0x040
#define SYMF_CONST 0x200 /* symbol has a constant value, will /* Symbol is a macro */
* not be changed during linking */ #define SYMF_MACRO 0x080
/* Symbol is a stringsymbol */
#define SYMF_STRING 0x100
/* Symbol has a constant value, will not be changed during linking */
#define SYMF_CONST 0x200
uint32_t calchash(char *s); uint32_t calchash(char *s);
void sym_SetExportAll(uint8_t set); void sym_SetExportAll(uint8_t set);
@@ -76,4 +80,4 @@ void sym_Purge(char *tzName);
uint32_t sym_isConstDefined(char *tzName); uint32_t sym_isConstDefined(char *tzName);
int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2); int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2);
#endif #endif /* RGBDS_SYMBOL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -24,32 +24,46 @@
#include <stdint.h> #include <stdint.h>
static const uint8_t utf8d[] = { static const uint8_t utf8d[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00..0f */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10..1f */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20..2f */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30..3f */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40..4f */
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50..5f */
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60..6f */
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70..7f */
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80..8f */
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 90..9f */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* a0..af */
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* b0..bf */
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c0..cf */
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* d0..df */
0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, /* e0..e7 */
0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, /* e8..ef */
0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, /* f0..f7 */
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, /* f8..ff */
0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, /* s0.. */
0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, /* ..s0 */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s1 */
1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, /* s1 */
1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, /* s3 */
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, /* s4 */
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, /* s5 */
1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s6 */
1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, /* s7 */
1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* s8 */
}; };
uint32_t uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte)
decode(uint32_t* state, uint32_t* codep, uint32_t byte) { {
uint32_t type = utf8d[byte]; uint32_t type = utf8d[byte];
*codep = (*state != 0) ? *codep = (*state != 0) ?
(byte & 0x3fu) | (*codep << 6) : (byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte); (0xff >> type) & (byte);
*state = utf8d[256 + *state*16 + type]; *state = utf8d[256 + *state * 16 + type];
return *state; return *state;
} }
/* /*
@@ -79,19 +93,15 @@ decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
struct Charmap globalCharmap = {0}; struct Charmap globalCharmap = {0};
extern struct Section *pCurrentSection; int32_t readUTF8Char(char *dest, char *src)
int32_t
readUTF8Char(char *dest, char *src)
{ {
uint32_t state; uint32_t state;
uint32_t codep; uint32_t codep;
int32_t i; int32_t i;
for (i = 0, state = 0;; i++) { for (i = 0, state = 0;; i++) {
if (decode(&state, &codep, (uint8_t)src[i]) == 1) { if (decode(&state, &codep, (uint8_t)src[i]) == 1)
fatalerror("invalid UTF-8 character"); fatalerror("invalid UTF-8 character");
}
dest[i] = src[i]; dest[i] = src[i];
@@ -104,13 +114,12 @@ readUTF8Char(char *dest, char *src)
} }
} }
int32_t int32_t charmap_Add(char *input, uint8_t output)
charmap_Add(char *input, uint8_t output)
{ {
int32_t i; int32_t i;
size_t input_length; size_t input_length;
char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1], temp1o = 0, char temp1i[CHARMAPLENGTH + 1], temp2i[CHARMAPLENGTH + 1];
temp2o = 0; char temp1o = 0, temp2o = 0;
struct Charmap *charmap; struct Charmap *charmap;
@@ -118,23 +127,21 @@ charmap_Add(char *input, uint8_t output)
if (pCurrentSection->charmap) { if (pCurrentSection->charmap) {
charmap = pCurrentSection->charmap; charmap = pCurrentSection->charmap;
} else { } else {
if ((charmap = calloc(1, sizeof(struct Charmap))) == charmap = calloc(1, sizeof(struct Charmap));
NULL) { if (charmap == NULL)
fatalerror("Not enough memory for charmap"); fatalerror("Not enough memory for charmap");
}
pCurrentSection->charmap = charmap; pCurrentSection->charmap = charmap;
} }
} else { } else {
charmap = &globalCharmap; charmap = &globalCharmap;
} }
if (nPass == 2) { if (nPass == 2)
return charmap->count; return charmap->count;
}
if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH) { if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH)
return -1; return -1;
}
input_length = strlen(input); input_length = strlen(input);
if (input_length > 1) { if (input_length > 1) {
@@ -142,7 +149,7 @@ charmap_Add(char *input, uint8_t output)
while (i < charmap->count + 1) { while (i < charmap->count + 1) {
if (input_length > strlen(charmap->input[i])) { if (input_length > strlen(charmap->input[i])) {
memcpy(temp1i, charmap->input[i], memcpy(temp1i, charmap->input[i],
CHARMAPLENGTH + 1); CHARMAPLENGTH + 1);
memcpy(charmap->input[i], input, input_length); memcpy(charmap->input[i], input, input_length);
temp1o = charmap->output[i]; temp1o = charmap->output[i];
charmap->output[i] = output; charmap->output[i] = output;
@@ -161,7 +168,7 @@ charmap_Add(char *input, uint8_t output)
i++; i++;
} }
memcpy(charmap->input[charmap->count + 1], temp1i, memcpy(charmap->input[charmap->count + 1], temp1i,
CHARMAPLENGTH + 1); CHARMAPLENGTH + 1);
charmap->output[charmap->count + 1] = temp1o; charmap->output[charmap->count + 1] = temp1o;
} else { } else {
memcpy(charmap->input[charmap->count], input, input_length); memcpy(charmap->input[charmap->count], input, input_length);
@@ -170,8 +177,7 @@ charmap_Add(char *input, uint8_t output)
return ++charmap->count; return ++charmap->count;
} }
int32_t int32_t charmap_Convert(char **input)
charmap_Convert(char **input)
{ {
struct Charmap *charmap; struct Charmap *charmap;
@@ -179,15 +185,14 @@ charmap_Convert(char **input)
char *buffer; char *buffer;
int32_t i, j, length; int32_t i, j, length;
if (pCurrentSection && pCurrentSection->charmap) { if (pCurrentSection && pCurrentSection->charmap)
charmap = pCurrentSection->charmap; charmap = pCurrentSection->charmap;
} else { else
charmap = &globalCharmap; charmap = &globalCharmap;
}
if ((buffer = malloc(strlen(*input))) == NULL) { buffer = malloc(strlen(*input));
if (buffer == NULL)
fatalerror("Not enough memory for buffer"); fatalerror("Not enough memory for buffer");
}
length = 0; length = 0;
while (**input) { while (**input) {
@@ -201,15 +206,15 @@ charmap_Convert(char **input)
} }
j = 0; j = 0;
} }
if (!j) {
if (!j)
j = readUTF8Char(outchar, *input); j = readUTF8Char(outchar, *input);
}
if (!outchar[0]) { if (!outchar[0]) {
buffer[length++] = 0; buffer[length++] = 0;
} else { } else {
for (i = 0; outchar[i]; i++) { for (i = 0; outchar[i]; i++)
buffer[length++] = outchar[i]; buffer[length++] = outchar[i];
}
} }
*input += j; *input += j;
} }

View File

@@ -19,19 +19,19 @@
#include "types.h" #include "types.h"
struct sContext *pFileStack; static struct sContext *pFileStack;
struct sSymbol *pCurrentMacro; static struct sSymbol *pCurrentMacro;
YY_BUFFER_STATE CurrentFlexHandle; static YY_BUFFER_STATE CurrentFlexHandle;
FILE *pCurrentFile; static FILE *pCurrentFile;
uint32_t nCurrentStatus; static uint32_t nCurrentStatus;
char tzCurrentFileName[_MAX_PATH + 1]; char tzCurrentFileName[_MAX_PATH + 1];
char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; static char IncludePaths[MAXINCPATHS][_MAX_PATH + 1];
int32_t NextIncPath = 0; static int32_t NextIncPath;
uint32_t nMacroCount; static uint32_t nMacroCount;
char *pCurrentREPTBlock; static char *pCurrentREPTBlock;
uint32_t nCurrentREPTBlockSize; static uint32_t nCurrentREPTBlockSize;
uint32_t nCurrentREPTBlockCount; static uint32_t nCurrentREPTBlockCount;
uint32_t ulMacroReturnValue; uint32_t ulMacroReturnValue;
@@ -49,8 +49,7 @@ extern FILE *dependfile;
/* /*
* Context push and pop * Context push and pop
*/ */
void static void pushcontext(void)
pushcontext(void)
{ {
struct sContext **ppFileStack; struct sContext **ppFileStack;
@@ -58,36 +57,37 @@ pushcontext(void)
while (*ppFileStack) while (*ppFileStack)
ppFileStack = &((*ppFileStack)->pNext); ppFileStack = &((*ppFileStack)->pNext);
if ((*ppFileStack = malloc(sizeof(struct sContext))) != NULL) { *ppFileStack = malloc(sizeof(struct sContext));
(*ppFileStack)->FlexHandle = CurrentFlexHandle;
(*ppFileStack)->pNext = NULL; if (*ppFileStack == NULL)
strcpy((char *) (*ppFileStack)->tzFileName,
(char *) tzCurrentFileName);
(*ppFileStack)->nLine = nLineNo;
switch ((*ppFileStack)->nStatus = nCurrentStatus) {
case STAT_isMacroArg:
case STAT_isMacro:
sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs);
(*ppFileStack)->pMacro = pCurrentMacro;
break;
case STAT_isInclude:
(*ppFileStack)->pFile = pCurrentFile;
break;
case STAT_isREPTBlock:
sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs);
(*ppFileStack)->pREPTBlock = pCurrentREPTBlock;
(*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize;
(*ppFileStack)->nREPTBlockCount =
nCurrentREPTBlockCount;
break;
}
nLineNo = 0;
} else
fatalerror("No memory for context"); fatalerror("No memory for context");
(*ppFileStack)->FlexHandle = CurrentFlexHandle;
(*ppFileStack)->pNext = NULL;
strcpy((char *)(*ppFileStack)->tzFileName, (char *)tzCurrentFileName);
(*ppFileStack)->nLine = nLineNo;
switch ((*ppFileStack)->nStatus = nCurrentStatus) {
case STAT_isMacroArg:
case STAT_isMacro:
sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs);
(*ppFileStack)->pMacro = pCurrentMacro;
break;
case STAT_isInclude:
(*ppFileStack)->pFile = pCurrentFile;
break;
case STAT_isREPTBlock:
sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs);
(*ppFileStack)->pREPTBlock = pCurrentREPTBlock;
(*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize;
(*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount;
break;
}
nLineNo = 0;
} }
static int32_t static int32_t popcontext(void)
popcontext(void)
{ {
struct sContext *pLastFile, **ppLastFile; struct sContext *pLastFile, **ppLastFile;
@@ -95,63 +95,67 @@ popcontext(void)
if (--nCurrentREPTBlockCount) { if (--nCurrentREPTBlockCount) {
yy_delete_buffer(CurrentFlexHandle); yy_delete_buffer(CurrentFlexHandle);
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pCurrentREPTBlock, yy_scan_bytes(pCurrentREPTBlock,
nCurrentREPTBlockSize); nCurrentREPTBlockSize);
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);
sym_UseCurrentMacroArgs(); sym_UseCurrentMacroArgs();
sym_SetMacroArgID(nMacroCount++); sym_SetMacroArgID(nMacroCount++);
sym_UseNewMacroArgs(); sym_UseNewMacroArgs();
return (0); return 0;
} }
} }
if ((pLastFile = pFileStack) != NULL) {
ppLastFile = &pFileStack;
while (pLastFile->pNext) {
ppLastFile = &(pLastFile->pNext);
pLastFile = *ppLastFile;
}
yy_delete_buffer(CurrentFlexHandle); pLastFile = pFileStack;
nLineNo = pLastFile->nLine; if (pLastFile == NULL)
if (nCurrentStatus == STAT_isInclude) return 1;
fclose(pCurrentFile);
if (nCurrentStatus == STAT_isMacro) {
sym_FreeCurrentMacroArgs();
nLineNo += 1;
}
if (nCurrentStatus == STAT_isREPTBlock)
nLineNo += 1;
CurrentFlexHandle = pLastFile->FlexHandle; ppLastFile = &pFileStack;
strcpy((char *) tzCurrentFileName, while (pLastFile->pNext) {
(char *) pLastFile->tzFileName); ppLastFile = &(pLastFile->pNext);
switch (nCurrentStatus = pLastFile->nStatus) { pLastFile = *ppLastFile;
case STAT_isMacroArg: }
case STAT_isMacro:
sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs);
pCurrentMacro = pLastFile->pMacro;
break;
case STAT_isInclude:
pCurrentFile = pLastFile->pFile;
break;
case STAT_isREPTBlock:
sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs);
pCurrentREPTBlock = pLastFile->pREPTBlock;
nCurrentREPTBlockSize = pLastFile->nREPTBlockSize;
nCurrentREPTBlockCount = pLastFile->nREPTBlockCount;
break;
}
free(*ppLastFile); yy_delete_buffer(CurrentFlexHandle);
*ppLastFile = NULL; nLineNo = pLastFile->nLine;
yy_switch_to_buffer(CurrentFlexHandle);
return (0); if (nCurrentStatus == STAT_isInclude)
} else fclose(pCurrentFile);
return (1);
if (nCurrentStatus == STAT_isMacro) {
sym_FreeCurrentMacroArgs();
nLineNo += 1;
}
if (nCurrentStatus == STAT_isREPTBlock)
nLineNo += 1;
CurrentFlexHandle = pLastFile->FlexHandle;
strcpy((char *)tzCurrentFileName, (char *)pLastFile->tzFileName);
switch (nCurrentStatus = pLastFile->nStatus) {
case STAT_isMacroArg:
case STAT_isMacro:
sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs);
pCurrentMacro = pLastFile->pMacro;
break;
case STAT_isInclude:
pCurrentFile = pLastFile->pFile;
break;
case STAT_isREPTBlock:
sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs);
pCurrentREPTBlock = pLastFile->pREPTBlock;
nCurrentREPTBlockSize = pLastFile->nREPTBlockSize;
nCurrentREPTBlockCount = pLastFile->nREPTBlockCount;
break;
}
free(*ppLastFile);
*ppLastFile = NULL;
yy_switch_to_buffer(CurrentFlexHandle);
return 0;
} }
int32_t int32_t fstk_GetLine(void)
fstk_GetLine(void)
{ {
struct sContext *pLastFile, **ppLastFile; struct sContext *pLastFile, **ppLastFile;
@@ -167,7 +171,9 @@ fstk_GetLine(void)
break; /* Peek top file of the stack */ break; /* Peek top file of the stack */
} }
if ((pLastFile = pFileStack) != NULL) { pLastFile = pFileStack;
if (pLastFile != NULL) {
ppLastFile = &pFileStack; ppLastFile = &pFileStack;
while (pLastFile->pNext) { while (pLastFile->pNext) {
ppLastFile = &(pLastFile->pNext); ppLastFile = &(pLastFile->pNext);
@@ -176,24 +182,24 @@ fstk_GetLine(void)
return pLastFile->nLine; return pLastFile->nLine;
} }
/* This is only reached if the lexer is in REPT or MACRO mode but there /*
* are no saved contexts with the origin of said REPT or MACRO. */ * This is only reached if the lexer is in REPT or MACRO mode but there
fatalerror("fstk_GetLine: Internal error."); * are no saved contexts with the origin of said REPT or MACRO.
*/
fatalerror("%s: Internal error.", __func__);
} }
int int yywrap(void)
yywrap(void)
{ {
return (popcontext()); return popcontext();
} }
/* /*
* Dump the context stack to stderr * Dump the context stack to stderr
*/ */
void void fstk_Dump(void)
fstk_Dump(void)
{ {
struct sContext *pLastFile; const struct sContext *pLastFile;
pLastFile = pFileStack; pLastFile = pFileStack;
@@ -209,46 +215,44 @@ fstk_Dump(void)
/* /*
* Extra includepath stuff * Extra includepath stuff
*/ */
void void fstk_AddIncludePath(char *s)
fstk_AddIncludePath(char *s)
{ {
if (NextIncPath == MAXINCPATHS) { if (NextIncPath == MAXINCPATHS)
fatalerror("Too many include directories passed from command line"); fatalerror("Too many include directories passed from command line");
return;
}
if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH) { if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH)
fatalerror("Include path too long '%s'",s); fatalerror("Include path too long '%s'", s);
return;
}
} }
FILE * FILE *fstk_FindFile(char *fname)
fstk_FindFile(char *fname)
{ {
char path[_MAX_PATH]; char path[_MAX_PATH];
int32_t i; int32_t i;
FILE *f; FILE *f;
if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) { f = fopen(fname, "rb");
if (dependfile) {
if (f != NULL || errno != ENOENT) {
if (dependfile)
fprintf(dependfile, "%s: %s\n", tzObjectname, fname); fprintf(dependfile, "%s: %s\n", tzObjectname, fname);
}
return f; return f;
} }
for (i = 0; i < NextIncPath; ++i) { for (i = 0; i < NextIncPath; ++i) {
if (strlcpy(path, IncludePaths[i], sizeof path) >= if (strlcpy(path, IncludePaths[i], sizeof(path))
sizeof path) { >= sizeof(path))
continue; continue;
}
if (strlcat(path, fname, sizeof path) >= sizeof path) {
continue;
}
if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) { if (strlcat(path, fname, sizeof(path)) >= sizeof(path))
continue;
f = fopen(path, "rb");
if (f != NULL || errno != ENOENT) {
if (dependfile) { if (dependfile) {
fprintf(dependfile, "%s: %s\n", tzObjectname, path); fprintf(dependfile, "%s: %s\n", tzObjectname,
path);
} }
return f; return f;
} }
@@ -261,17 +265,12 @@ fstk_FindFile(char *fname)
/* /*
* Set up an include file for parsing * Set up an include file for parsing
*/ */
void void fstk_RunInclude(char *tzFileName)
fstk_RunInclude(char *tzFileName)
{ {
FILE *f; FILE *f = fstk_FindFile(tzFileName);
f = fstk_FindFile(tzFileName); if (f == NULL)
err(1, "Unable to open included file '%s'", tzFileName);
if (f == NULL) {
err(1, "Unable to open included file '%s'",
tzFileName);
}
pushcontext(); pushcontext();
nLineNo = 1; nLineNo = 1;
@@ -281,7 +280,7 @@ fstk_RunInclude(char *tzFileName)
CurrentFlexHandle = yy_create_buffer(pCurrentFile); CurrentFlexHandle = yy_create_buffer(pCurrentFile);
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);
//Dirty hack to give the INCLUDE directive a linefeed /* Dirty hack to give the INCLUDE directive a linefeed */
yyunput('\n'); yyunput('\n');
nLineNo -= 1; nLineNo -= 1;
@@ -290,35 +289,35 @@ fstk_RunInclude(char *tzFileName)
/* /*
* Set up a macro for parsing * Set up a macro for parsing
*/ */
uint32_t uint32_t fstk_RunMacro(char *s)
fstk_RunMacro(char *s)
{ {
struct sSymbol *sym; struct sSymbol *sym = sym_FindMacro(s);
if ((sym = sym_FindMacro(s)) != NULL) { if (sym == NULL)
pushcontext(); return 0;
sym_SetMacroArgID(nMacroCount++);
nLineNo = -1; pushcontext();
sym_UseNewMacroArgs(); sym_SetMacroArgID(nMacroCount++);
nCurrentStatus = STAT_isMacro; nLineNo = -1;
strcpy(tzCurrentFileName, s); sym_UseNewMacroArgs();
if (sym->pMacro == NULL) nCurrentStatus = STAT_isMacro;
return 0; strcpy(tzCurrentFileName, s);
pCurrentMacro = sym;
CurrentFlexHandle = if (sym->pMacro == NULL)
yy_scan_bytes(pCurrentMacro->pMacro, return 0;
strlen(pCurrentMacro->pMacro));
yy_switch_to_buffer(CurrentFlexHandle); pCurrentMacro = sym;
return (1); CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro,
} else strlen(pCurrentMacro->pMacro));
return (0); yy_switch_to_buffer(CurrentFlexHandle);
return 1;
} }
/* /*
* Set up a macroargument for parsing * Set up a macroargument for parsing
*/ */
void void fstk_RunMacroArg(int32_t s)
fstk_RunMacroArg(int32_t s)
{ {
char *sym; char *sym;
@@ -327,40 +326,41 @@ fstk_RunMacroArg(int32_t s)
else else
s -= '0'; s -= '0';
if ((sym = sym_FindMacroArg(s)) != NULL) { sym = sym_FindMacroArg(s);
pushcontext();
nCurrentStatus = STAT_isMacroArg; if (sym == NULL)
sprintf(tzCurrentFileName, "%c", (uint8_t) s);
CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym));
yy_switch_to_buffer(CurrentFlexHandle);
} else
fatalerror("No such macroargument"); fatalerror("No such macroargument");
pushcontext();
nCurrentStatus = STAT_isMacroArg;
sprintf(tzCurrentFileName, "%c", (uint8_t)s);
CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym));
yy_switch_to_buffer(CurrentFlexHandle);
} }
/* /*
* Set up a stringequate for parsing * Set up a stringequate for parsing
*/ */
void void fstk_RunString(char *s)
fstk_RunString(char *s)
{ {
struct sSymbol *pSym; const struct sSymbol *pSym = sym_FindSymbol(s);
if ((pSym = sym_FindSymbol(s)) != NULL) { if (pSym != NULL) {
pushcontext(); pushcontext();
nCurrentStatus = STAT_isMacroArg; nCurrentStatus = STAT_isMacroArg;
strcpy(tzCurrentFileName, s); strcpy(tzCurrentFileName, s);
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro)); yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro));
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);
} else } else {
yyerror("No such string symbol '%s'", s); yyerror("No such string symbol '%s'", s);
}
} }
/* /*
* Set up a repeat block for parsing * Set up a repeat block for parsing
*/ */
void void fstk_RunRept(uint32_t count)
fstk_RunRept(uint32_t count)
{ {
if (count) { if (count) {
pushcontext(); pushcontext();
@@ -372,7 +372,7 @@ fstk_RunRept(uint32_t count)
nCurrentREPTBlockSize = ulNewMacroSize; nCurrentREPTBlockSize = ulNewMacroSize;
pCurrentREPTBlock = tzNewMacro; pCurrentREPTBlock = tzNewMacro;
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize); yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize);
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);
} }
} }
@@ -380,21 +380,19 @@ fstk_RunRept(uint32_t count)
/* /*
* Initialize the filestack routines * Initialize the filestack routines
*/ */
void void fstk_Init(char *s)
fstk_Init(char *s)
{ {
char tzFileName[_MAX_PATH + 1]; char tzFileName[_MAX_PATH + 1];
char tzSymFileName[_MAX_PATH + 1 + 2]; char tzSymFileName[_MAX_PATH + 1 + 2];
snprintf(tzSymFileName, sizeof(tzSymFileName), "\"%s\"", s); snprintf(tzSymFileName, sizeof(tzSymFileName), "\"%s\"", s);
sym_AddString("__FILE__", tzSymFileName); sym_AddString("__FILE__", tzSymFileName);
strcpy(tzFileName, s); strcpy(tzFileName, s);
pFileStack = NULL; pFileStack = NULL;
pCurrentFile = fopen(tzFileName, "rb"); pCurrentFile = fopen(tzFileName, "rb");
if (pCurrentFile == NULL) { if (pCurrentFile == NULL)
err(1, "Unable to open file '%s'", tzFileName); err(1, "Unable to open file '%s'", tzFileName);
}
nMacroCount = 0; nMacroCount = 0;
nCurrentStatus = STAT_isInclude; nCurrentStatus = STAT_isInclude;

View File

@@ -14,40 +14,35 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
bool oDontExpandStrings = false; bool oDontExpandStrings;
int32_t nGBGfxID = -1; int32_t nGBGfxID = -1;
int32_t nBinaryID = -1; int32_t nBinaryID = -1;
int32_t static int32_t gbgfx2bin(char ch)
gbgfx2bin(char ch)
{ {
int32_t i; int32_t i;
for (i = 0; i <= 3; i += 1) { for (i = 0; i <= 3; i += 1) {
if (CurrentOptions.gbgfx[i] == ch) { if (CurrentOptions.gbgfx[i] == ch)
return (i); return i;
}
} }
return (0); return 0;
} }
int32_t static int32_t binary2bin(char ch)
binary2bin(char ch)
{ {
int32_t i; int32_t i;
for (i = 0; i <= 1; i += 1) { for (i = 0; i <= 1; i += 1) {
if (CurrentOptions.binary[i] == ch) { if (CurrentOptions.binary[i] == ch)
return (i); return i;
}
} }
return (0); return 0;
} }
int32_t static int32_t char2bin(char ch)
char2bin(char ch)
{ {
if (ch >= 'a' && ch <= 'f') if (ch >= 'a' && ch <= 'f')
return (ch - 'a' + 10); return (ch - 'a' + 10);
@@ -58,13 +53,12 @@ char2bin(char ch)
if (ch >= '0' && ch <= '9') if (ch >= '0' && ch <= '9')
return (ch - '0'); return (ch - '0');
return (0); return 0;
} }
typedef int32_t(*x2bin) (char ch); typedef int32_t(*x2bin) (char ch);
int32_t static int32_t ascii2bin(char *s)
ascii2bin(char *s)
{ {
int32_t radix = 10; int32_t radix = 10;
int32_t result = 0; int32_t result = 0;
@@ -105,11 +99,10 @@ ascii2bin(char *s)
result = result * radix + convertfunc(*s++); result = result * radix + convertfunc(*s++);
} }
return (result); return result;
} }
uint32_t uint32_t ParseFixedPoint(char *s, uint32_t size)
ParseFixedPoint(char *s, uint32_t size)
{ {
uint32_t i = 0, dot = 0; uint32_t i = 0, dot = 0;
@@ -125,13 +118,12 @@ ParseFixedPoint(char *s, uint32_t size)
yyunputbytes(size); yyunputbytes(size);
yylval.nConstValue = (int32_t) (atof(s) * 65536); yylval.nConstValue = (int32_t)(atof(s) * 65536);
return (1); return 1;
} }
uint32_t uint32_t ParseNumber(char *s, uint32_t size)
ParseNumber(char *s, uint32_t size)
{ {
char dest[256]; char dest[256];
@@ -139,11 +131,10 @@ ParseNumber(char *s, uint32_t size)
dest[size] = 0; dest[size] = 0;
yylval.nConstValue = ascii2bin(dest); yylval.nConstValue = ascii2bin(dest);
return (1); return 1;
} }
uint32_t uint32_t ParseSymbol(char *src, uint32_t size)
ParseSymbol(char *src, uint32_t size)
{ {
char dest[MAXSYMLEN + 1]; char dest[MAXSYMLEN + 1];
int32_t copied = 0, size_backup = size; int32_t copied = 0, size_backup = size;
@@ -155,13 +146,13 @@ ParseSymbol(char *src, uint32_t size)
src += 1; src += 1;
size -= 1; size -= 1;
if (*src == '@') if (*src == '@') {
marg = sym_FindMacroArg(-1); marg = sym_FindMacroArg(-1);
else if (*src >= '0' && *src <= '9') } else if (*src >= '0' && *src <= '9') {
marg = sym_FindMacroArg(*src - '0'); marg = sym_FindMacroArg(*src - '0');
else { } else {
fatalerror("Malformed ID"); fatalerror("Malformed ID");
return (0); return 0;
} }
src += 1; src += 1;
@@ -189,47 +180,48 @@ ParseSymbol(char *src, uint32_t size)
yyunputstr(s = sym_GetStringValue(dest)); yyunputstr(s = sym_GetStringValue(dest));
while (*s) { while (*s) {
if (*s++ == '\n') { if (*s++ == '\n')
nLineNo -= 1; nLineNo -= 1;
}
} }
return (0); return 0;
} else {
strcpy(yylval.tzString, dest);
return (1);
} }
strcpy(yylval.tzString, dest);
return 1;
} }
uint32_t uint32_t PutMacroArg(char *src, uint32_t size)
PutMacroArg(char *src, uint32_t size)
{ {
char *s; char *s;
yyskipbytes(size); yyskipbytes(size);
if ((size == 2 && src[1] >= '1' && src[1] <= '9')) { if ((size == 2 && src[1] >= '1' && src[1] <= '9')) {
if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) { s = sym_FindMacroArg(src[1] - '0');
if (s != NULL)
yyunputstr(s); yyunputstr(s);
} else { else
yyerror("Macro argument not defined"); yyerror("Macro argument not defined");
}
} else { } else {
yyerror("Invalid macro argument"); yyerror("Invalid macro argument");
} }
return (0); return 0;
} }
uint32_t uint32_t PutUniqueArg(char *src, uint32_t size)
PutUniqueArg(char *src, uint32_t size)
{ {
char *s; char *s;
yyskipbytes(size); yyskipbytes(size);
if ((s = sym_FindMacroArg(-1)) != NULL) {
s = sym_FindMacroArg(-1);
if (s != NULL)
yyunputstr(s); yyunputstr(s);
} else { else
yyerror("Macro unique label string not defined"); yyerror("Macro unique label string not defined");
}
return (0); return 0;
} }
enum { enum {
@@ -237,9 +229,9 @@ enum {
T_LEX_MACROUNIQUE T_LEX_MACROUNIQUE
}; };
extern struct sLexInitString localstrings[]; extern const struct sLexInitString localstrings[];
struct sLexInitString staticstrings[] = { const struct sLexInitString staticstrings[] = {
{"||", T_OP_LOGICOR}, {"||", T_OP_LOGICOR},
{"&&", T_OP_LOGICAND}, {"&&", T_OP_LOGICAND},
{"==", T_OP_LOGICEQU}, {"==", T_OP_LOGICEQU},
@@ -329,7 +321,7 @@ struct sLexInitString staticstrings[] = {
{"else", T_POP_ELSE}, {"else", T_POP_ELSE},
{"elif", T_POP_ELIF}, {"elif", T_POP_ELIF},
{"endc", T_POP_ENDC}, {"endc", T_POP_ENDC},
{"union", T_POP_UNION}, {"union", T_POP_UNION},
{"nextu", T_POP_NEXTU}, {"nextu", T_POP_NEXTU},
{"endu", T_POP_ENDU}, {"endu", T_POP_ENDU},
@@ -367,27 +359,27 @@ struct sLexInitString staticstrings[] = {
{NULL, 0} {NULL, 0}
}; };
struct sLexFloat tNumberToken = { const struct sLexFloat tNumberToken = {
ParseNumber, ParseNumber,
T_NUMBER T_NUMBER
}; };
struct sLexFloat tFixedPointToken = { const struct sLexFloat tFixedPointToken = {
ParseFixedPoint, ParseFixedPoint,
T_NUMBER T_NUMBER
}; };
struct sLexFloat tIDToken = { const struct sLexFloat tIDToken = {
ParseSymbol, ParseSymbol,
T_ID T_ID
}; };
struct sLexFloat tMacroArgToken = { const struct sLexFloat tMacroArgToken = {
PutMacroArg, PutMacroArg,
T_LEX_MACROARG T_LEX_MACROARG
}; };
struct sLexFloat tMacroUniqueToken = { const struct sLexFloat tMacroUniqueToken = {
PutUniqueArg, PutUniqueArg,
T_LEX_MACROUNIQUE T_LEX_MACROUNIQUE
}; };
@@ -403,7 +395,7 @@ setuplex(void)
//Macro arguments //Macro arguments
id = lex_FloatAlloc(&tMacroArgToken); id = lex_FloatAlloc(&tMacroArgToken);
lex_FloatAddFirstRange(id, '\\', '\\'); lex_FloatAddFirstRange(id, '\\', '\\');
lex_FloatAddSecondRange(id, '1', '9'); lex_FloatAddSecondRange(id, '1', '9');
id = lex_FloatAlloc(&tMacroUniqueToken); id = lex_FloatAlloc(&tMacroUniqueToken);
@@ -412,43 +404,45 @@ setuplex(void)
//Decimal constants //Decimal constants
id = lex_FloatAlloc(&tNumberToken); id = lex_FloatAlloc(&tNumberToken);
lex_FloatAddFirstRange(id, '0', '9'); lex_FloatAddFirstRange(id, '0', '9');
lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddSecondRange(id, '0', '9');
lex_FloatAddRange(id, '0', '9'); lex_FloatAddRange(id, '0', '9');
//Binary constants //Binary constants
nBinaryID = id = lex_FloatAlloc(&tNumberToken); id = lex_FloatAlloc(&tNumberToken);
nBinaryID = id;
lex_FloatAddFirstRange(id, '%', '%'); lex_FloatAddFirstRange(id, '%', '%');
lex_FloatAddSecondRange(id, CurrentOptions.binary[0], lex_FloatAddSecondRange(id, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatAddSecondRange(id, CurrentOptions.binary[1], lex_FloatAddSecondRange(id, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
lex_FloatAddRange(id, CurrentOptions.binary[0], lex_FloatAddRange(id, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatAddRange(id, CurrentOptions.binary[1], lex_FloatAddRange(id, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
//Octal constants //Octal constants
id = lex_FloatAlloc(&tNumberToken); id = lex_FloatAlloc(&tNumberToken);
lex_FloatAddFirstRange(id, '&', '&'); lex_FloatAddFirstRange(id, '&', '&');
lex_FloatAddSecondRange(id, '0', '7'); lex_FloatAddSecondRange(id, '0', '7');
lex_FloatAddRange(id, '0', '7'); lex_FloatAddRange(id, '0', '7');
//Gameboy gfx constants //Gameboy gfx constants
nGBGfxID = id = lex_FloatAlloc(&tNumberToken); id = lex_FloatAlloc(&tNumberToken);
nGBGfxID = id;
lex_FloatAddFirstRange(id, '`', '`'); lex_FloatAddFirstRange(id, '`', '`');
lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[0], lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[0],
CurrentOptions.gbgfx[0]); CurrentOptions.gbgfx[0]);
lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[1], lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[1],
CurrentOptions.gbgfx[1]); CurrentOptions.gbgfx[1]);
lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[2], lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[2],
CurrentOptions.gbgfx[2]); CurrentOptions.gbgfx[2]);
lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[3], lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[3],
CurrentOptions.gbgfx[3]); CurrentOptions.gbgfx[3]);
lex_FloatAddRange(id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); lex_FloatAddRange(id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]);
lex_FloatAddRange(id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); lex_FloatAddRange(id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]);
lex_FloatAddRange(id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); lex_FloatAddRange(id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]);
@@ -456,7 +450,7 @@ setuplex(void)
//Hex constants //Hex constants
id = lex_FloatAlloc(&tNumberToken); id = lex_FloatAlloc(&tNumberToken);
lex_FloatAddFirstRange(id, '$', '$'); lex_FloatAddFirstRange(id, '$', '$');
lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddSecondRange(id, '0', '9');
lex_FloatAddSecondRange(id, 'A', 'F'); lex_FloatAddSecondRange(id, 'A', 'F');
@@ -467,7 +461,7 @@ setuplex(void)
//ID 's //ID 's
id = lex_FloatAlloc(&tIDToken); id = lex_FloatAlloc(&tIDToken);
lex_FloatAddFirstRange(id, 'a', 'z'); lex_FloatAddFirstRange(id, 'a', 'z');
lex_FloatAddFirstRange(id, 'A', 'Z'); lex_FloatAddFirstRange(id, 'A', 'Z');
lex_FloatAddFirstRange(id, '_', '_'); lex_FloatAddFirstRange(id, '_', '_');
@@ -489,7 +483,7 @@ setuplex(void)
//Local ID //Local ID
id = lex_FloatAlloc(&tIDToken); id = lex_FloatAlloc(&tIDToken);
lex_FloatAddFirstRange(id, '.', '.'); lex_FloatAddFirstRange(id, '.', '.');
lex_FloatAddSecondRange(id, 'a', 'z'); lex_FloatAddSecondRange(id, 'a', 'z');
lex_FloatAddSecondRange(id, 'A', 'Z'); lex_FloatAddSecondRange(id, 'A', 'Z');
@@ -504,17 +498,16 @@ setuplex(void)
//@ID //@ID
id = lex_FloatAlloc(&tIDToken); id = lex_FloatAlloc(&tIDToken);
lex_FloatAddFirstRange(id, '@', '@'); lex_FloatAddFirstRange(id, '@', '@');
//Fixed point constants //Fixed point constants
id = lex_FloatAlloc(&tFixedPointToken); id = lex_FloatAlloc(&tFixedPointToken);
lex_FloatAddFirstRange(id, '.', '.'); lex_FloatAddFirstRange(id, '.', '.');
lex_FloatAddFirstRange(id, '0', '9'); lex_FloatAddFirstRange(id, '0', '9');
lex_FloatAddSecondRange(id, '.', '.'); lex_FloatAddSecondRange(id, '.', '.');
lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddSecondRange(id, '0', '9');
lex_FloatAddRange(id, '.', '.'); lex_FloatAddRange(id, '.', '.');
lex_FloatAddRange(id, '0', '9'); lex_FloatAddRange(id, '0', '9');
} }

View File

@@ -21,11 +21,12 @@ struct sLexString {
uint32_t nNameLength; uint32_t nNameLength;
struct sLexString *pNext; struct sLexString *pNext;
}; };
#define pLexBufferRealStart (pCurrentBuffer->pBufferRealStart)
#define pLexBuffer (pCurrentBuffer->pBuffer)
#define AtLineStart (pCurrentBuffer->oAtLineStart)
#define SAFETYMARGIN 1024 #define pLexBufferRealStart (pCurrentBuffer->pBufferRealStart)
#define pLexBuffer (pCurrentBuffer->pBuffer)
#define AtLineStart (pCurrentBuffer->oAtLineStart)
#define SAFETYMARGIN 1024
extern size_t symvaluetostring(char *dest, size_t maxLength, char *sym); extern size_t symvaluetostring(char *dest, size_t maxLength, char *sym);
@@ -40,8 +41,7 @@ uint32_t tFloatingChars[256];
uint32_t nFloating; uint32_t nFloating;
enum eLexerState lexerstate = LEX_STATE_NORMAL; enum eLexerState lexerstate = LEX_STATE_NORMAL;
void void upperstring(char *s)
upperstring(char *s)
{ {
while (*s) { while (*s) {
*s = toupper(*s); *s = toupper(*s);
@@ -49,8 +49,7 @@ upperstring(char *s)
} }
} }
void void lowerstring(char *s)
lowerstring(char *s)
{ {
while (*s) { while (*s) {
*s = tolower(*s); *s = tolower(*s);
@@ -58,20 +57,17 @@ lowerstring(char *s)
} }
} }
void void yyskipbytes(uint32_t count)
yyskipbytes(uint32_t count)
{ {
pLexBuffer += count; pLexBuffer += count;
} }
void void yyunputbytes(uint32_t count)
yyunputbytes(uint32_t count)
{ {
pLexBuffer -= count; pLexBuffer -= count;
} }
void void yyunput(char c)
yyunput(char c)
{ {
if (pLexBuffer <= pLexBufferRealStart) if (pLexBuffer <= pLexBufferRealStart)
fatalerror("Buffer safety margin exceeded"); fatalerror("Buffer safety margin exceeded");
@@ -79,8 +75,7 @@ yyunput(char c)
*(--pLexBuffer) = c; *(--pLexBuffer) = c;
} }
void void yyunputstr(char *s)
yyunputstr(char *s)
{ {
int32_t i, len; int32_t i, len;
@@ -93,114 +88,109 @@ yyunputstr(char *s)
*(--pLexBuffer) = s[i]; *(--pLexBuffer) = s[i];
} }
void void yy_switch_to_buffer(YY_BUFFER_STATE buf)
yy_switch_to_buffer(YY_BUFFER_STATE buf)
{ {
pCurrentBuffer = buf; pCurrentBuffer = buf;
} }
void void yy_set_state(enum eLexerState i)
yy_set_state(enum eLexerState i)
{ {
lexerstate = i; lexerstate = i;
} }
void void yy_delete_buffer(YY_BUFFER_STATE buf)
yy_delete_buffer(YY_BUFFER_STATE buf)
{ {
free(buf->pBufferStart - SAFETYMARGIN); free(buf->pBufferStart - SAFETYMARGIN);
free(buf); free(buf);
} }
YY_BUFFER_STATE YY_BUFFER_STATE yy_scan_bytes(char *mem, uint32_t size)
yy_scan_bytes(char *mem, uint32_t size)
{ {
YY_BUFFER_STATE pBuffer; YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state));
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) { if (pBuffer == NULL)
if ((pBuffer->pBufferRealStart = fatalerror("%s: Out of memory!", __func__);
malloc(size + 1 + SAFETYMARGIN)) != NULL) {
pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN; pBuffer->pBufferRealStart = malloc(size + 1 + SAFETYMARGIN);
pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
memcpy(pBuffer->pBuffer, mem, size); if (pBuffer->pBufferRealStart == NULL)
pBuffer->nBufferSize = size; fatalerror("%s: Out of memory for buffer!", __func__);
pBuffer->oAtLineStart = 1;
pBuffer->pBuffer[size] = 0; pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
return (pBuffer); pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
} memcpy(pBuffer->pBuffer, mem, size);
} pBuffer->nBufferSize = size;
fatalerror("Out of memory!"); pBuffer->oAtLineStart = 1;
return (NULL); pBuffer->pBuffer[size] = 0;
return pBuffer;
} }
YY_BUFFER_STATE YY_BUFFER_STATE yy_create_buffer(FILE *f)
yy_create_buffer(FILE * f)
{ {
YY_BUFFER_STATE pBuffer; YY_BUFFER_STATE pBuffer = malloc(sizeof(struct yy_buffer_state));
if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) { if (pBuffer == NULL)
uint32_t size; fatalerror("%s: Out of memory!", __func__);
fseek(f, 0, SEEK_END); uint32_t size;
size = ftell(f);
fseek(f, 0, SEEK_SET);
if ((pBuffer->pBufferRealStart = fseek(f, 0, SEEK_END);
malloc(size + 2 + SAFETYMARGIN)) != NULL) { size = ftell(f);
char *mem; fseek(f, 0, SEEK_SET);
uint32_t instring = 0;
pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN; pBuffer->pBufferRealStart = malloc(size + 2 + SAFETYMARGIN);
pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f); if (pBuffer->pBufferRealStart == NULL)
fatalerror("%s: Out of memory for buffer!", __func__);
pBuffer->pBuffer[size] = '\n'; pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
pBuffer->pBuffer[size + 1] = 0; pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
pBuffer->nBufferSize = size + 1;
mem = pBuffer->pBuffer; size = fread(pBuffer->pBuffer, sizeof(uint8_t), size, f);
while (*mem) { pBuffer->pBuffer[size] = '\n';
if (*mem == '\"') pBuffer->pBuffer[size + 1] = 0;
instring = 1 - instring; pBuffer->nBufferSize = size + 1;
if (mem[0] == '\\' && char *mem = pBuffer->pBuffer;
(mem[1] == '\"' || mem[1] == '\\')) { uint32_t instring = 0;
mem += 2;
} else if (instring) { while (*mem) {
mem += 1; if (*mem == '\"')
} else { instring = 1 - instring;
if ((mem[0] == 10 && mem[1] == 13)
|| (mem[0] == 13 && mem[1] == 10)) { if ((mem[0] == '\\') && (mem[1] == '\"' || mem[1] == '\\')) {
mem[0] = ' '; mem += 2;
mem[1] = '\n'; } else if (instring) {
mem += 2; mem += 1;
} else if (mem[0] == 10 || mem[0] == 13) { } else {
mem[0] = '\n'; if ((mem[0] == 10 && mem[1] == 13)
mem += 1; || (mem[0] == 13 && mem[1] == 10)) {
} else if (mem[0] == '\n' && mem[1] == '*') { mem[0] = ' ';
mem += 1; mem[1] = '\n';
while (!(*mem == '\n' || *mem == '\0')) mem += 2;
*mem++ = ' '; } else if (mem[0] == 10 || mem[0] == 13) {
} else if (*mem == ';') { mem[0] = '\n';
while (!(*mem == '\n' || *mem == '\0')) mem += 1;
*mem++ = ' '; } else if (mem[0] == '\n' && mem[1] == '*') {
} else mem += 1;
mem += 1; while (!(*mem == '\n' || *mem == '\0'))
} *mem++ = ' ';
} else if (*mem == ';') {
while (!(*mem == '\n' || *mem == '\0'))
*mem++ = ' ';
} else {
mem += 1;
} }
pBuffer->oAtLineStart = 1;
return (pBuffer);
} }
} }
fatalerror("Out of memory!");
return (NULL); pBuffer->oAtLineStart = 1;
return pBuffer;
} }
uint32_t uint32_t lex_FloatAlloc(const struct sLexFloat *token)
lex_FloatAlloc(struct sLexFloat *token)
{ {
tLexFloat[nFloating] = *token; tLexFloat[nFloating] = *token;
@@ -211,17 +201,15 @@ lex_FloatAlloc(struct sLexFloat *token)
* Make sure that only non-zero ASCII characters are used. Also, check if the * Make sure that only non-zero ASCII characters are used. Also, check if the
* start is greater than the end of the range. * start is greater than the end of the range.
*/ */
void void lex_CheckCharacterRange(uint16_t start, uint16_t end)
lex_CheckCharacterRange(uint16_t start, uint16_t end)
{ {
if (start > end || start < 1 || end > 127) { if (start > end || start < 1 || end > 127) {
errx(1, "Invalid character range (start: %u, end: %u)", errx(1, "Invalid character range (start: %u, end: %u)",
start, end); start, end);
} }
} }
void void lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -231,8 +219,7 @@ lex_FloatDeleteRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
void void lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -242,8 +229,7 @@ lex_FloatAddRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
void void lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -253,8 +239,7 @@ lex_FloatDeleteFirstRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
void void lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -264,8 +249,7 @@ lex_FloatAddFirstRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
void void lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -275,8 +259,7 @@ lex_FloatDeleteSecondRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
void void lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
{ {
lex_CheckCharacterRange(start, end); lex_CheckCharacterRange(start, end);
@@ -286,12 +269,10 @@ lex_FloatAddSecondRange(uint32_t id, uint16_t start, uint16_t end)
} }
} }
struct sLexFloat * static struct sLexFloat *lexgetfloat(uint32_t nFloatMask)
lexgetfloat(uint32_t nFloatMask)
{ {
if (nFloatMask == 0) { if (nFloatMask == 0)
fatalerror("Internal error in lexgetfloat"); fatalerror("Internal error in %s", __func__);
}
int32_t i = 0; int32_t i = 0;
@@ -300,29 +281,25 @@ lexgetfloat(uint32_t nFloatMask)
i++; i++;
} }
return (&tLexFloat[i]); return &tLexFloat[i];
} }
uint32_t static uint32_t lexcalchash(char *s)
lexcalchash(char *s)
{ {
uint32_t hash = 0; uint32_t hash = 0;
while (*s) { while (*s)
hash = (hash * 283) ^ toupper(*s++); hash = (hash * 283) ^ toupper(*s++);
}
return (hash % LEXHASHSIZE); return hash % LEXHASHSIZE;
} }
void void lex_Init(void)
lex_Init(void)
{ {
uint32_t i; uint32_t i;
for (i = 0; i < LEXHASHSIZE; i++) { for (i = 0; i < LEXHASHSIZE; i++)
tLexHash[i] = NULL; tLexHash[i] = NULL;
}
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
tFloatingFirstChar[i] = 0; tFloatingFirstChar[i] = 0;
@@ -334,8 +311,7 @@ lex_Init(void)
nFloating = 0; nFloating = 0;
} }
void void lex_AddStrings(const struct sLexInitString *lex)
lex_AddStrings(struct sLexInitString * lex)
{ {
while (lex->tzName) { while (lex->tzName) {
struct sLexString **ppHash; struct sLexString **ppHash;
@@ -345,23 +321,23 @@ lex_AddStrings(struct sLexInitString * lex)
while (*ppHash) while (*ppHash)
ppHash = &((*ppHash)->pNext); ppHash = &((*ppHash)->pNext);
if (((*ppHash) = malloc(sizeof(struct sLexString))) != NULL) { *ppHash = malloc(sizeof(struct sLexString));
if (((*ppHash)->tzName = if (*ppHash == NULL)
(char *) strdup(lex->tzName)) != NULL) {
(*ppHash)->nNameLength = strlen(lex->tzName);
(*ppHash)->nToken = lex->nToken;
(*ppHash)->pNext = NULL;
upperstring((*ppHash)->tzName);
if ((*ppHash)->nNameLength > nLexMaxLength)
nLexMaxLength = (*ppHash)->nNameLength;
} else
fatalerror("Out of memory!");
} else
fatalerror("Out of memory!"); fatalerror("Out of memory!");
(*ppHash)->tzName = (char *)strdup(lex->tzName);
if ((*ppHash)->tzName == NULL)
fatalerror("Out of memory!");
(*ppHash)->nNameLength = strlen(lex->tzName);
(*ppHash)->nToken = lex->nToken;
(*ppHash)->pNext = NULL;
upperstring((*ppHash)->tzName);
if ((*ppHash)->nNameLength > nLexMaxLength)
nLexMaxLength = (*ppHash)->nNameLength;
lex += 1; lex += 1;
} }
} }
@@ -376,11 +352,12 @@ lex_AddStrings(struct sLexInitString * lex)
* The token types with the longest match from the current position in the * The token types with the longest match from the current position in the
* buffer will have their bits set in the float mask. * buffer will have their bits set in the float mask.
*/ */
void void yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
{ {
// Note that '\0' should always have a bit mask of 0 in the "floating" /*
// tables, so it doesn't need to be checked for separately. * Note that '\0' should always have a bit mask of 0 in the "floating"
* tables, so it doesn't need to be checked for separately.
*/
char *s = pLexBuffer; char *s = pLexBuffer;
uint32_t nOldFloatMask = 0; uint32_t nOldFloatMask = 0;
@@ -405,8 +382,7 @@ yylex_GetFloatMaskAndFloatLen(uint32_t *pnFloatMask, uint32_t *pnFloatLen)
/* /*
* Gets the longest keyword/operator from the current position in the buffer. * Gets the longest keyword/operator from the current position in the buffer.
*/ */
struct sLexString * struct sLexString *yylex_GetLongestFixed()
yylex_GetLongestFixed()
{ {
struct sLexString *pLongestFixed = NULL; struct sLexString *pLongestFixed = NULL;
char *s = pLexBuffer; char *s = pLexBuffer;
@@ -433,8 +409,7 @@ yylex_GetLongestFixed()
return pLongestFixed; return pLongestFixed;
} }
size_t size_t CopyMacroArg(char *dest, size_t maxLength, char c)
CopyMacroArg(char *dest, size_t maxLength, char c)
{ {
size_t i; size_t i;
char *s; char *s;
@@ -459,35 +434,33 @@ CopyMacroArg(char *dest, size_t maxLength, char c)
return 0; return 0;
} }
if ((s = sym_FindMacroArg(argNum)) == NULL) s = sym_FindMacroArg(argNum);
if (s == NULL)
fatalerror("Macro argument not defined"); fatalerror("Macro argument not defined");
for (i = 0; s[i] != 0; i++) { for (i = 0; s[i] != 0; i++) {
if (i >= maxLength) { if (i >= maxLength)
fatalerror("Macro argument too long to fit buffer"); fatalerror("Macro argument too long to fit buffer");
}
dest[i] = s[i]; dest[i] = s[i];
} }
return i; return i;
} }
static inline void static inline void yylex_StringWriteChar(char *s, size_t index, char c)
yylex_StringWriteChar(char *s, size_t index, char c)
{ {
if (index >= MAXSTRLEN) { if (index >= MAXSTRLEN)
fatalerror("String too long"); fatalerror("String too long");
}
s[index] = c; s[index] = c;
} }
static inline void static inline void yylex_SymbolWriteChar(char *s, size_t index, char c)
yylex_SymbolWriteChar(char *s, size_t index, char c)
{ {
if (index >= MAXSYMLEN) { if (index >= MAXSYMLEN)
fatalerror("Symbol too long"); fatalerror("Symbol too long");
}
s[index] = c; s[index] = c;
} }
@@ -498,14 +471,15 @@ yylex_SymbolWriteChar(char *s, size_t index, char c)
*/ */
void yylex_TrimEnd(char *s, size_t index) void yylex_TrimEnd(char *s, size_t index)
{ {
int32_t i; int32_t i = (int32_t)index - 1;
for (i = (int32_t)index - 1; i >= 0 && (s[i] == ' ' || s[i] == '\t'); i--) while ((i >= 0) && (s[i] == ' ' || s[i] == '\t')) {
s[i] = 0; s[i] = 0;
i--;
}
} }
size_t size_t yylex_ReadBracketedSymbol(char *dest, size_t index)
yylex_ReadBracketedSymbol(char *dest, size_t index)
{ {
char sym[MAXSYMLEN + 1]; char sym[MAXSYMLEN + 1];
char ch; char ch;
@@ -524,13 +498,15 @@ yylex_ReadBracketedSymbol(char *dest, size_t index)
i += length; i += length;
else else
fatalerror("Illegal character escape '%c'", ch); fatalerror("Illegal character escape '%c'", ch);
} else } else {
yylex_SymbolWriteChar(sym, i++, ch); yylex_SymbolWriteChar(sym, i++, ch);
}
} }
yylex_SymbolWriteChar(sym, i, 0); yylex_SymbolWriteChar(sym, i, 0);
maxLength = MAXSTRLEN - index; // it's assumed we're writing to a T_STRING /* It's assumed we're writing to a T_STRING */
maxLength = MAXSTRLEN - index;
length = symvaluetostring(&dest[index], maxLength, sym); length = symvaluetostring(&dest[index], maxLength, sym);
if (*pLexBuffer == '}') if (*pLexBuffer == '}')
@@ -541,8 +517,7 @@ yylex_ReadBracketedSymbol(char *dest, size_t index)
return length; return length;
} }
void static void yylex_ReadQuotedString(void)
yylex_ReadQuotedString()
{ {
size_t index = 0; size_t index = 0;
size_t length, maxLength; size_t length, maxLength;
@@ -577,19 +552,22 @@ yylex_ReadQuotedString()
break; break;
default: default:
maxLength = MAXSTRLEN - index; maxLength = MAXSTRLEN - index;
length = CopyMacroArg(&yylval.tzString[index], maxLength, ch); length = CopyMacroArg(&yylval.tzString[index],
maxLength, ch);
if (length != 0) if (length != 0)
index += length; index += length;
else else
fatalerror("Illegal character escape '%c'", ch); fatalerror("Illegal character escape '%c'",
ch);
ch = 0; ch = 0;
break; break;
} }
} else if (ch == '{') { } else if (ch == '{') {
// Get bracketed symbol within string. // Get bracketed symbol within string.
index += yylex_ReadBracketedSymbol(yylval.tzString, index); index += yylex_ReadBracketedSymbol(yylval.tzString,
index);
ch = 0; ch = 0;
} }
@@ -605,8 +583,7 @@ yylex_ReadQuotedString()
fatalerror("Unterminated string"); fatalerror("Unterminated string");
} }
uint32_t static uint32_t yylex_NORMAL(void)
yylex_NORMAL()
{ {
struct sLexString *pLongestFixed = NULL; struct sLexString *pLongestFixed = NULL;
uint32_t nFloatMask, nFloatLen; uint32_t nFloatMask, nFloatLen;
@@ -629,15 +606,20 @@ scanagain:
} }
} }
// Try to match an identifier, macro argument (e.g. \1), /*
// or numeric literal. * Try to match an identifier, macro argument (e.g. \1),
* or numeric literal.
*/
yylex_GetFloatMaskAndFloatLen(&nFloatMask, &nFloatLen); yylex_GetFloatMaskAndFloatLen(&nFloatMask, &nFloatLen);
// Try to match a keyword or operator. /* Try to match a keyword or operator. */
pLongestFixed = yylex_GetLongestFixed(); pLongestFixed = yylex_GetLongestFixed();
if (nFloatLen == 0 && pLongestFixed == NULL) { if (nFloatLen == 0 && pLongestFixed == NULL) {
// No keyword, identifier, operator, or numerical literal matches. /*
* No keyword, identifier, operator, or numerical literal
* matches.
*/
if (*pLexBuffer == '"') { if (*pLexBuffer == '"') {
pLexBuffer++; pLexBuffer++;
@@ -647,52 +629,55 @@ scanagain:
pLexBuffer++; pLexBuffer++;
yylex_ReadBracketedSymbol(yylval.tzString, 0); yylex_ReadBracketedSymbol(yylval.tzString, 0);
return T_STRING; return T_STRING;
} else {
// It's not a keyword, operator, identifier, macro argument,
// numeric literal, string, or bracketed symbol, so just return
// the ASCII character.
if (*pLexBuffer == '\n')
AtLineStart = 1;
return *pLexBuffer++;
} }
/*
* It's not a keyword, operator, identifier, macro argument,
* numeric literal, string, or bracketed symbol, so just return
* the ASCII character.
*/
if (*pLexBuffer == '\n')
AtLineStart = 1;
return *pLexBuffer++;
} }
if (pLongestFixed == NULL || nFloatLen > pLongestFixed->nNameLength) { if (pLongestFixed == NULL || nFloatLen > pLongestFixed->nNameLength) {
// Longest match was an identifier, macro argument, or numeric literal. /*
* Longest match was an identifier, macro argument, or numeric
* literal.
*/
struct sLexFloat *token = lexgetfloat(nFloatMask); struct sLexFloat *token = lexgetfloat(nFloatMask);
if (token->Callback) { if (token->Callback) {
int32_t done = token->Callback(pLexBuffer, nFloatLen); int32_t done = token->Callback(pLexBuffer, nFloatLen);
if (!done) if (!done)
goto scanagain; goto scanagain;
} }
pLexBuffer += nFloatLen; pLexBuffer += nFloatLen;
if (token->nToken == T_ID && linestart) { if (token->nToken == T_ID && linestart)
return T_LABEL; return T_LABEL;
} else { else
return token->nToken; return token->nToken;
}
} }
// Longest match was a keyword or operator. /* Longest match was a keyword or operator. */
pLexBuffer += pLongestFixed->nNameLength; pLexBuffer += pLongestFixed->nNameLength;
return pLongestFixed->nToken; return pLongestFixed->nToken;
} }
uint32_t static uint32_t yylex_MACROARGS(void)
yylex_MACROARGS()
{ {
size_t index = 0; size_t index = 0;
size_t length, maxLength; size_t length, maxLength;
while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { while ((*pLexBuffer == ' ') || (*pLexBuffer == '\t'))
pLexBuffer++; pLexBuffer++;
}
while (*pLexBuffer != ',' && (*pLexBuffer != '\n')) { while ((*pLexBuffer != ',') && (*pLexBuffer != '\n')) {
char ch = *pLexBuffer++; char ch = *pLexBuffer++;
if (ch == '\\') { if (ch == '\\') {
@@ -719,18 +704,21 @@ yylex_MACROARGS()
break; break;
default: default:
maxLength = MAXSTRLEN - index; maxLength = MAXSTRLEN - index;
length = CopyMacroArg(&yylval.tzString[index], maxLength, ch); length = CopyMacroArg(&yylval.tzString[index],
maxLength, ch);
if (length != 0) if (length != 0)
index += length; index += length;
else else
fatalerror("Illegal character escape '%c'", ch); fatalerror("Illegal character escape '%c'",
ch);
ch = 0; ch = 0;
break; break;
} }
} else if (ch == '{') { } else if (ch == '{') {
index += yylex_ReadBracketedSymbol(yylval.tzString, index); index += yylex_ReadBracketedSymbol(yylval.tzString,
index);
ch = 0; ch = 0;
} }
if (ch) if (ch)
@@ -740,7 +728,7 @@ yylex_MACROARGS()
if (index) { if (index) {
yylex_StringWriteChar(yylval.tzString, index, 0); yylex_StringWriteChar(yylval.tzString, index, 0);
// trim trailing white space at the end of the line /* trim trailing white space at the end of the line */
if (*pLexBuffer == '\n') if (*pLexBuffer == '\n')
yylex_TrimEnd(yylval.tzString, index); yylex_TrimEnd(yylval.tzString, index);
@@ -754,12 +742,10 @@ yylex_MACROARGS()
return ','; return ',';
} }
fatalerror("Internal error in yylex_MACROARGS"); fatalerror("Internal error in %s", __func__);
return 0;
} }
uint32_t uint32_t yylex(void)
yylex(void)
{ {
switch (lexerstate) { switch (lexerstate) {
case LEX_STATE_NORMAL: case LEX_STATE_NORMAL:
@@ -768,6 +754,5 @@ yylex(void)
return yylex_MACROARGS(); return yylex_MACROARGS();
} }
fatalerror("Internal error in yylex"); fatalerror("Internal error in %s", __func__);
return 0;
} }

View File

@@ -4,7 +4,7 @@
#include "asmy.h" #include "asmy.h"
struct sLexInitString localstrings[] = { const struct sLexInitString localstrings[] = {
{"adc", T_Z80_ADC}, {"adc", T_Z80_ADC},
{"add", T_Z80_ADD}, {"add", T_Z80_ADD},
{"and", T_Z80_AND}, {"and", T_Z80_AND},

View File

@@ -11,6 +11,7 @@
#include "asm/fstack.h" #include "asm/fstack.h"
#include "asm/output.h" #include "asm/output.h"
#include "asm/main.h" #include "asm/main.h"
#include "extern/err.h" #include "extern/err.h"
#include "extern/reallocarray.h" #include "extern/reallocarray.h"
#include "extern/version.h" #include "extern/version.h"
@@ -28,7 +29,7 @@ uint32_t nTotalLines, nPass, nPC, nIFDepth, nUnionDepth, nErrors;
bool skipElif; bool skipElif;
uint32_t unionStart[128], unionSize[128]; uint32_t unionStart[128], unionSize[128];
extern int yydebug; /* extern int yydebug; */
FILE *dependfile; FILE *dependfile;
extern char *tzObjectname; extern char *tzObjectname;
@@ -45,73 +46,71 @@ struct sOptionStackEntry {
struct sOptionStackEntry *pNext; struct sOptionStackEntry *pNext;
}; };
struct sOptionStackEntry *pOptionStack = NULL; struct sOptionStackEntry *pOptionStack;
void void opt_SetCurrentOptions(struct sOptions *pOpt)
opt_SetCurrentOptions(struct sOptions * pOpt)
{ {
if (nGBGfxID != -1) { if (nGBGfxID != -1) {
lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[0], lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[0],
CurrentOptions.gbgfx[0]); CurrentOptions.gbgfx[0]);
lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[1], lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[1],
CurrentOptions.gbgfx[1]); CurrentOptions.gbgfx[1]);
lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[2], lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[2],
CurrentOptions.gbgfx[2]); CurrentOptions.gbgfx[2]);
lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[3], lex_FloatDeleteRange(nGBGfxID, CurrentOptions.gbgfx[3],
CurrentOptions.gbgfx[3]); CurrentOptions.gbgfx[3]);
lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[0], lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[0],
CurrentOptions.gbgfx[0]); CurrentOptions.gbgfx[0]);
lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[1], lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[1],
CurrentOptions.gbgfx[1]); CurrentOptions.gbgfx[1]);
lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[2], lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[2],
CurrentOptions.gbgfx[2]); CurrentOptions.gbgfx[2]);
lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[3], lex_FloatDeleteSecondRange(nGBGfxID, CurrentOptions.gbgfx[3],
CurrentOptions.gbgfx[3]); CurrentOptions.gbgfx[3]);
} }
if (nBinaryID != -1) { if (nBinaryID != -1) {
lex_FloatDeleteRange(nBinaryID, CurrentOptions.binary[0], lex_FloatDeleteRange(nBinaryID, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatDeleteRange(nBinaryID, CurrentOptions.binary[1], lex_FloatDeleteRange(nBinaryID, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
lex_FloatDeleteSecondRange(nBinaryID, CurrentOptions.binary[0], lex_FloatDeleteSecondRange(nBinaryID, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatDeleteSecondRange(nBinaryID, CurrentOptions.binary[1], lex_FloatDeleteSecondRange(nBinaryID, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
} }
CurrentOptions = *pOpt; CurrentOptions = *pOpt;
if (nGBGfxID != -1) { if (nGBGfxID != -1) {
lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[0], lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[0],
CurrentOptions.gbgfx[0]); CurrentOptions.gbgfx[0]);
lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[1], lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[1],
CurrentOptions.gbgfx[1]); CurrentOptions.gbgfx[1]);
lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[2], lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[2],
CurrentOptions.gbgfx[2]); CurrentOptions.gbgfx[2]);
lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[3], lex_FloatAddRange(nGBGfxID, CurrentOptions.gbgfx[3],
CurrentOptions.gbgfx[3]); CurrentOptions.gbgfx[3]);
lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[0], lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[0],
CurrentOptions.gbgfx[0]); CurrentOptions.gbgfx[0]);
lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[1], lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[1],
CurrentOptions.gbgfx[1]); CurrentOptions.gbgfx[1]);
lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[2], lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[2],
CurrentOptions.gbgfx[2]); CurrentOptions.gbgfx[2]);
lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[3], lex_FloatAddSecondRange(nGBGfxID, CurrentOptions.gbgfx[3],
CurrentOptions.gbgfx[3]); CurrentOptions.gbgfx[3]);
} }
if (nBinaryID != -1) { if (nBinaryID != -1) {
lex_FloatAddRange(nBinaryID, CurrentOptions.binary[0], lex_FloatAddRange(nBinaryID, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatAddRange(nBinaryID, CurrentOptions.binary[1], lex_FloatAddRange(nBinaryID, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
lex_FloatAddSecondRange(nBinaryID, CurrentOptions.binary[0], lex_FloatAddSecondRange(nBinaryID, CurrentOptions.binary[0],
CurrentOptions.binary[0]); CurrentOptions.binary[0]);
lex_FloatAddSecondRange(nBinaryID, CurrentOptions.binary[1], lex_FloatAddSecondRange(nBinaryID, CurrentOptions.binary[1],
CurrentOptions.binary[1]); CurrentOptions.binary[1]);
} }
} }
void void opt_Parse(char *s)
opt_Parse(char *s)
{ {
struct sOptions newopt; struct sOptions newopt;
@@ -125,8 +124,7 @@ opt_Parse(char *s)
newopt.gbgfx[2] = s[3]; newopt.gbgfx[2] = s[3];
newopt.gbgfx[3] = s[4]; newopt.gbgfx[3] = s[4];
} else { } else {
errx(1, "Must specify exactly 4 characters for " errx(1, "Must specify exactly 4 characters for option 'g'");
"option 'g'");
} }
break; break;
case 'b': case 'b':
@@ -134,8 +132,7 @@ opt_Parse(char *s)
newopt.binary[0] = s[1]; newopt.binary[0] = s[1];
newopt.binary[1] = s[2]; newopt.binary[1] = s[2];
} else { } else {
errx(1, "Must specify exactly 2 characters for option " errx(1, "Must specify exactly 2 characters for option 'b'");
"'b'");
} }
break; break;
case 'z': case 'z':
@@ -143,12 +140,10 @@ opt_Parse(char *s)
int32_t result; int32_t result;
result = sscanf(&s[1], "%x", &newopt.fillchar); result = sscanf(&s[1], "%x", &newopt.fillchar);
if (!((result == EOF) || (result == 1))) { if (!((result == EOF) || (result == 1)))
errx(1, "Invalid argument for option 'z'"); errx(1, "Invalid argument for option 'z'");
}
} else { } else {
errx(1, "Invalid argument for option 'z'"); errx(1, "Invalid argument for option 'z'");
exit(1);
} }
break; break;
default: default:
@@ -159,77 +154,67 @@ opt_Parse(char *s)
opt_SetCurrentOptions(&newopt); opt_SetCurrentOptions(&newopt);
} }
void void opt_Push(void)
opt_Push(void)
{ {
struct sOptionStackEntry *pOpt; struct sOptionStackEntry *pOpt;
if ((pOpt = malloc(sizeof(struct sOptionStackEntry))) != NULL) { pOpt = malloc(sizeof(struct sOptionStackEntry));
pOpt->Options = CurrentOptions;
pOpt->pNext = pOptionStack; if (pOpt == NULL)
pOptionStack = pOpt;
} else
fatalerror("No memory for option stack"); fatalerror("No memory for option stack");
pOpt->Options = CurrentOptions;
pOpt->pNext = pOptionStack;
pOptionStack = pOpt;
} }
void void opt_Pop(void)
opt_Pop(void)
{ {
if (pOptionStack) { if (pOptionStack == NULL)
struct sOptionStackEntry *pOpt;
pOpt = pOptionStack;
opt_SetCurrentOptions(&(pOpt->Options));
pOptionStack = pOpt->pNext;
free(pOpt);
} else
fatalerror("No entries in the option stack"); fatalerror("No entries in the option stack");
struct sOptionStackEntry *pOpt;
pOpt = pOptionStack;
opt_SetCurrentOptions(&(pOpt->Options));
pOptionStack = pOpt->pNext;
free(pOpt);
} }
void void opt_AddDefine(char *s)
opt_AddDefine(char *s)
{ {
char *value, *equals; char *value, *equals;
if(cldefines_index >= cldefines_size)
{ if (cldefines_index >= cldefines_size) {
cldefines_size *= 2; cldefines_size *= 2;
cldefines = reallocarray(cldefines, cldefines_size, cldefines = reallocarray(cldefines, cldefines_size,
2 * sizeof(void *)); 2 * sizeof(void *));
if(!cldefines) if (!cldefines)
{
fatalerror("No memory for command line defines"); fatalerror("No memory for command line defines");
}
} }
equals = strchr(s, '='); equals = strchr(s, '=');
if(equals) if (equals) {
{
*equals = '\0'; *equals = '\0';
value = equals + 1; value = equals + 1;
} } else {
else
{
value = "1"; value = "1";
} }
cldefines[cldefines_index++] = s; cldefines[cldefines_index++] = s;
cldefines[cldefines_index++] = value; cldefines[cldefines_index++] = value;
} }
void static void opt_ParseDefines(void)
opt_ParseDefines()
{ {
int32_t i; int32_t i;
for(i = 0; i < cldefines_index; i += 2) for (i = 0; i < cldefines_index; i += 2)
{
sym_AddString(cldefines[i], cldefines[i + 1]); sym_AddString(cldefines[i], cldefines[i + 1]);
}
} }
/* /*
* Error handling * Error handling
*/ */
void void verror(const char *fmt, va_list args)
verror(const char *fmt, va_list args)
{ {
fprintf(stderr, "ERROR: "); fprintf(stderr, "ERROR: ");
fstk_Dump(); fstk_Dump();
@@ -239,32 +224,33 @@ verror(const char *fmt, va_list args)
nErrors += 1; nErrors += 1;
} }
void void yyerror(const char *fmt, ...)
yyerror(const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
verror(fmt, args); verror(fmt, args);
va_end(args); va_end(args);
} }
void void fatalerror(const char *fmt, ...)
fatalerror(const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
verror(fmt, args); verror(fmt, args);
va_end(args); va_end(args);
exit(5); exit(5);
} }
void void warning(const char *fmt, ...)
warning(const char *fmt, ...)
{ {
if (!CurrentOptions.warnings) if (!CurrentOptions.warnings)
return; return;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
fprintf(stderr, "warning: "); fprintf(stderr, "warning: ");
@@ -276,17 +262,15 @@ warning(const char *fmt, ...)
va_end(args); va_end(args);
} }
static void static void print_usage(void)
usage(void)
{ {
printf( printf(
"Usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n" "usage: rgbasm [-EhVvw] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n"
" [-M dependfile] [-o outfile] [-p pad_value] file.asm\n"); " [-M dependfile] [-o outfile] [-p pad_value] file.asm\n");
exit(1); exit(1);
} }
int int main(int argc, char *argv[])
main(int argc, char *argv[])
{ {
int ch; int ch;
char *ep; char *ep;
@@ -298,15 +282,12 @@ main(int argc, char *argv[])
dependfile = NULL; dependfile = NULL;
cldefines_size = 32; cldefines_size = 32;
cldefines = reallocarray(cldefines, cldefines_size, cldefines = reallocarray(cldefines, cldefines_size, 2 * sizeof(void *));
2 * sizeof(void *)); if (!cldefines)
if(!cldefines)
{
fatalerror("No memory for command line defines"); fatalerror("No memory for command line defines");
}
if (argc == 1) if (argc == 1)
usage(); print_usage();
/* yydebug=1; */ /* yydebug=1; */
@@ -333,8 +314,7 @@ main(int argc, char *argv[])
newopt.binary[0] = optarg[1]; newopt.binary[0] = optarg[1];
newopt.binary[1] = optarg[2]; newopt.binary[1] = optarg[2];
} else { } else {
errx(1, "Must specify exactly 2 characters for " errx(1, "Must specify exactly 2 characters for option 'b'");
"option 'b'");
} }
break; break;
case 'D': case 'D':
@@ -350,8 +330,7 @@ main(int argc, char *argv[])
newopt.gbgfx[2] = optarg[3]; newopt.gbgfx[2] = optarg[3];
newopt.gbgfx[3] = optarg[4]; newopt.gbgfx[3] = optarg[4];
} else { } else {
errx(1, "Must specify exactly 4 characters for " errx(1, "Must specify exactly 4 characters for option 'g'");
"option 'g'");
} }
break; break;
case 'h': case 'h':
@@ -361,22 +340,23 @@ main(int argc, char *argv[])
fstk_AddIncludePath(optarg); fstk_AddIncludePath(optarg);
break; break;
case 'M': case 'M':
if ((dependfile = fopen(optarg, "w")) == NULL) { dependfile = fopen(optarg, "w");
if (dependfile == NULL)
err(1, "Could not open dependfile %s", optarg); err(1, "Could not open dependfile %s", optarg);
}
break; break;
case 'o': case 'o':
out_SetFileName(optarg); out_SetFileName(optarg);
break; break;
case 'p': case 'p':
newopt.fillchar = strtoul(optarg, &ep, 0); newopt.fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
if (optarg[0] == '\0' || *ep != '\0')
errx(1, "Invalid argument for option 'p'"); errx(1, "Invalid argument for option 'p'");
}
if (newopt.fillchar < 0 || newopt.fillchar > 0xFF) { if (newopt.fillchar < 0 || newopt.fillchar > 0xFF)
errx(1, "Argument for option 'p' must be " errx(1, "Argument for option 'p' must be between 0 and 0xFF");
"between 0 and 0xFF");
}
break; break;
case 'V': case 'V':
printf("rgbasm %s\n", get_package_version_string()); printf("rgbasm %s\n", get_package_version_string());
@@ -388,7 +368,7 @@ main(int argc, char *argv[])
newopt.warnings = false; newopt.warnings = false;
break; break;
default: default:
usage(); print_usage();
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@@ -400,15 +380,14 @@ main(int argc, char *argv[])
DefaultOptions = CurrentOptions; DefaultOptions = CurrentOptions;
if (argc == 0) if (argc == 0)
usage(); print_usage();
tzMainfile = argv[argc - 1]; tzMainfile = argv[argc - 1];
setuplex(); setuplex();
if (CurrentOptions.verbose) { if (CurrentOptions.verbose)
printf("Assembling %s\n", tzMainfile); printf("Assembling %s\n", tzMainfile);
}
if (dependfile) { if (dependfile) {
if (!tzObjectname) if (!tzObjectname)
@@ -432,23 +411,21 @@ main(int argc, char *argv[])
fstk_Init(tzMainfile); fstk_Init(tzMainfile);
opt_ParseDefines(); opt_ParseDefines();
if (CurrentOptions.verbose) { if (CurrentOptions.verbose)
printf("Pass 1...\n"); printf("Pass 1...\n");
}
yy_set_state(LEX_STATE_NORMAL); yy_set_state(LEX_STATE_NORMAL);
opt_SetCurrentOptions(&DefaultOptions); opt_SetCurrentOptions(&DefaultOptions);
if (yyparse() != 0 || nErrors != 0) { if (yyparse() != 0 || nErrors != 0)
errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors); errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors);
}
if (nIFDepth != 0) { if (nIFDepth != 0)
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth); errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
}
if (nUnionDepth != 0) { if (nUnionDepth != 0) {
errx(1, "Unterminated UNION construct (%ld levels)!", nUnionDepth); errx(1, "Unterminated UNION construct (%ld levels)!",
nUnionDepth);
} }
nTotalLines = 0; nTotalLines = 0;
@@ -466,27 +443,25 @@ main(int argc, char *argv[])
opt_SetCurrentOptions(&DefaultOptions); opt_SetCurrentOptions(&DefaultOptions);
opt_ParseDefines(); opt_ParseDefines();
if (CurrentOptions.verbose) { if (CurrentOptions.verbose)
printf("Pass 2...\n"); printf("Pass 2...\n");
}
if (yyparse() != 0 || nErrors != 0) { if (yyparse() != 0 || nErrors != 0)
errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors); errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors);
}
double timespent; double timespent;
nEndClock = clock(); nEndClock = clock();
timespent = ((double)(nEndClock - nStartClock)) timespent = ((double)(nEndClock - nStartClock))
/ (double)CLOCKS_PER_SEC; / (double)CLOCKS_PER_SEC;
if (CurrentOptions.verbose) { if (CurrentOptions.verbose) {
printf("Success! %u lines in %d.%02d seconds ", nTotalLines, printf("Success! %u lines in %d.%02d seconds ", nTotalLines,
(int) timespent, ((int) (timespent * 100.0)) % 100); (int)timespent, ((int)(timespent * 100.0)) % 100);
if (timespent == 0) if (timespent == 0)
printf("(INFINITY lines/minute)\n"); printf("(INFINITY lines/minute)\n");
else else
printf("(%d lines/minute)\n", printf("(%d lines/minute)\n",
(int) (60 / timespent * nTotalLines)); (int)(60 / timespent * nTotalLines));
} }
out_WriteObject(); out_WriteObject();
return 0; return 0;

View File

@@ -9,8 +9,8 @@
#include "asm/mymath.h" #include "asm/mymath.h"
#include "asm/symbol.h" #include "asm/symbol.h"
#define fix2double(i) ((double)(i/65536.0)) #define fx2double(i) ((double)((i) / 65536.0))
#define double2fix(d) ((int32_t)(d*65536.0)) #define double2fx(d) ((int32_t)((d) * 65536.0))
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
@@ -19,131 +19,116 @@
/* /*
* Define the _PI symbol * Define the _PI symbol
*/ */
void void math_DefinePI(void)
math_DefinePI(void)
{ {
sym_AddEqu("_PI", double2fix(M_PI)); sym_AddEqu("_PI", double2fx(M_PI));
} }
/* /*
* Print a fixed point value * Print a fixed point value
*/ */
void void math_Print(int32_t i)
math_Print(int32_t i)
{ {
if (i >= 0) if (i >= 0)
printf("%d.%05d", i >> 16, printf("%d.%05d", i >> 16,
((int32_t) (fix2double(i) * 100000 + 0.5)) % 100000); ((int32_t)(fx2double(i) * 100000 + 0.5)) % 100000);
else else
printf("-%d.%05d", (-i) >> 16, printf("-%d.%05d", (-i) >> 16,
((int32_t) (fix2double(-i) * 100000 + 0.5)) % 100000); ((int32_t)(fx2double(-i) * 100000 + 0.5)) % 100000);
} }
/* /*
* Calculate sine * Calculate sine
*/ */
int32_t int32_t math_Sin(int32_t i)
math_Sin(int32_t i)
{ {
return (double2fix(sin(fix2double(i) * 2 * M_PI / 65536))); return double2fx(sin(fx2double(i) * 2 * M_PI / 65536));
} }
/* /*
* Calculate cosine * Calculate cosine
*/ */
int32_t int32_t math_Cos(int32_t i)
math_Cos(int32_t i)
{ {
return (double2fix(cos(fix2double(i) * 2 * M_PI / 65536))); return double2fx(cos(fx2double(i) * 2 * M_PI / 65536));
} }
/* /*
* Calculate tangent * Calculate tangent
*/ */
int32_t int32_t math_Tan(int32_t i)
math_Tan(int32_t i)
{ {
return (double2fix(tan(fix2double(i) * 2 * M_PI / 65536))); return double2fx(tan(fx2double(i) * 2 * M_PI / 65536));
} }
/* /*
* Calculate arcsine * Calculate arcsine
*/ */
int32_t int32_t math_ASin(int32_t i)
math_ASin(int32_t i)
{ {
return (double2fix(asin(fix2double(i)) / 2 / M_PI * 65536)); return double2fx(asin(fx2double(i)) / 2 / M_PI * 65536);
} }
/* /*
* Calculate arccosine * Calculate arccosine
*/ */
int32_t int32_t math_ACos(int32_t i)
math_ACos(int32_t i)
{ {
return (double2fix(acos(fix2double(i)) / 2 / M_PI * 65536)); return double2fx(acos(fx2double(i)) / 2 / M_PI * 65536);
} }
/* /*
* Calculate arctangent * Calculate arctangent
*/ */
int32_t int32_t math_ATan(int32_t i)
math_ATan(int32_t i)
{ {
return (double2fix(atan(fix2double(i)) / 2 / M_PI * 65536)); return double2fx(atan(fx2double(i)) / 2 / M_PI * 65536);
} }
/* /*
* Calculate atan2 * Calculate atan2
*/ */
int32_t int32_t math_ATan2(int32_t i, int32_t j)
math_ATan2(int32_t i, int32_t j)
{ {
return (double2fix return double2fx(atan2(fx2double(i), fx2double(j)) / 2 / M_PI * 65536);
(atan2(fix2double(i), fix2double(j)) / 2 / M_PI * 65536));
} }
/* /*
* Multiplication * Multiplication
*/ */
int32_t int32_t math_Mul(int32_t i, int32_t j)
math_Mul(int32_t i, int32_t j)
{ {
return (double2fix(fix2double(i) * fix2double(j))); return double2fx(fx2double(i) * fx2double(j));
} }
/* /*
* Division * Division
*/ */
int32_t int32_t math_Div(int32_t i, int32_t j)
math_Div(int32_t i, int32_t j)
{ {
return (double2fix(fix2double(i) / fix2double(j))); return double2fx(fx2double(i) / fx2double(j));
} }
/* /*
* Round * Round
*/ */
int32_t int32_t math_Round(int32_t i)
math_Round(int32_t i)
{ {
return double2fix(round(fix2double(i))); return double2fx(round(fx2double(i)));
} }
/* /*
* Ceil * Ceil
*/ */
int32_t int32_t math_Ceil(int32_t i)
math_Ceil(int32_t i)
{ {
return double2fix(ceil(fix2double(i))); return double2fx(ceil(fx2double(i)));
} }
/* /*
* Floor * Floor
*/ */
int32_t int32_t math_Floor(int32_t i)
math_Floor(int32_t i)
{ {
return double2fix(floor(fix2double(i))); return double2fx(floor(fx2double(i)));
} }

View File

@@ -10,16 +10,18 @@
#include "asm/asm.h" #include "asm/asm.h"
#include "asm/charmap.h" #include "asm/charmap.h"
#include "asm/output.h"
#include "asm/symbol.h"
#include "asm/mylink.h"
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h" #include "asm/fstack.h"
#include "asm/main.h"
#include "asm/mylink.h"
#include "asm/output.h"
#include "asm/rpn.h"
#include "asm/symbol.h"
#include "common.h" #include "common.h"
#include "extern/err.h" #include "extern/err.h"
void out_SetCurrentSection(struct Section * pSect); void out_SetCurrentSection(struct Section *pSect);
struct Patch { struct Patch {
char tzFilename[_MAX_PATH + 1]; char tzFilename[_MAX_PATH + 1];
@@ -35,7 +37,7 @@ struct PatchSymbol {
uint32_t ID; uint32_t ID;
struct sSymbol *pSymbol; struct sSymbol *pSymbol;
struct PatchSymbol *pNext; struct PatchSymbol *pNext;
struct PatchSymbol *pBucketNext; // next symbol in hash table bucket struct PatchSymbol *pBucketNext; /* next symbol in hash table bucket */
}; };
struct SectionStackEntry { struct SectionStackEntry {
@@ -44,56 +46,62 @@ struct SectionStackEntry {
}; };
struct PatchSymbol *tHashedPatchSymbols[HASHSIZE]; struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
struct Section *pSectionList = NULL, *pCurrentSection = NULL; struct Section *pSectionList, *pCurrentSection;
struct PatchSymbol *pPatchSymbols = NULL; struct PatchSymbol *pPatchSymbols;
struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols; struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
char *tzObjectname; char *tzObjectname;
struct SectionStackEntry *pSectionStack = NULL; struct SectionStackEntry *pSectionStack;
/* /*
* Section stack routines * Section stack routines
*/ */
void void out_PushSection(void)
out_PushSection(void)
{ {
struct SectionStackEntry *pSect; struct SectionStackEntry *pSect;
if ((pSect = malloc(sizeof(struct SectionStackEntry))) != NULL) { pSect = malloc(sizeof(struct SectionStackEntry));
pSect->pSection = pCurrentSection; if (pSect == NULL)
pSect->pNext = pSectionStack;
pSectionStack = pSect;
} else
fatalerror("No memory for section stack"); fatalerror("No memory for section stack");
pSect->pSection = pCurrentSection;
pSect->pNext = pSectionStack;
pSectionStack = pSect;
} }
void void out_PopSection(void)
out_PopSection(void)
{ {
if (pSectionStack) { if (pSectionStack == NULL)
struct SectionStackEntry *pSect;
pSect = pSectionStack;
out_SetCurrentSection(pSect->pSection);
pSectionStack = pSect->pNext;
free(pSect);
} else
fatalerror("No entries in the section stack"); fatalerror("No entries in the section stack");
struct SectionStackEntry *pSect;
pSect = pSectionStack;
out_SetCurrentSection(pSect->pSection);
pSectionStack = pSect->pNext;
free(pSect);
} }
uint32_t static uint32_t getmaxsectionsize(uint32_t secttype, char *sectname)
getmaxsectionsize(uint32_t secttype, char * sectname)
{ {
switch (secttype) switch (secttype) {
{ case SECT_ROM0:
case SECT_ROM0: return 0x8000; /* If ROMX sections not used. */ return 0x8000; /* If ROMX sections not used */
case SECT_ROMX: return 0x4000; case SECT_ROMX:
case SECT_VRAM: return 0x2000; return 0x4000;
case SECT_SRAM: return 0x2000; case SECT_VRAM:
case SECT_WRAM0: return 0x2000; /* If WRAMX sections not used. */ return 0x2000;
case SECT_WRAMX: return 0x1000; case SECT_SRAM:
case SECT_OAM: return 0xA0; return 0x2000;
case SECT_HRAM: return 0x7F; case SECT_WRAM0:
default: break; return 0x2000; /* If WRAMX sections not used */
case SECT_WRAMX:
return 0x1000;
case SECT_OAM:
return 0xA0;
case SECT_HRAM:
return 0x7F;
default:
break;
} }
errx(1, "Section \"%s\" has an invalid section type.", sectname); errx(1, "Section \"%s\" has an invalid section type.", sectname);
} }
@@ -101,8 +109,7 @@ getmaxsectionsize(uint32_t secttype, char * sectname)
/* /*
* Count the number of symbols used in this object * Count the number of symbols used in this object
*/ */
uint32_t static uint32_t countsymbols(void)
countsymbols(void)
{ {
struct PatchSymbol *pSym; struct PatchSymbol *pSym;
uint32_t count = 0; uint32_t count = 0;
@@ -120,8 +127,7 @@ countsymbols(void)
/* /*
* Count the number of sections used in this object * Count the number of sections used in this object
*/ */
uint32_t static uint32_t countsections(void)
countsections(void)
{ {
struct Section *pSect; struct Section *pSect;
uint32_t count = 0; uint32_t count = 0;
@@ -139,8 +145,7 @@ countsections(void)
/* /*
* Count the number of patches used in this object * Count the number of patches used in this object
*/ */
uint32_t static uint32_t countpatches(struct Section *pSect)
countpatches(struct Section * pSect)
{ {
struct Patch *pPatch; struct Patch *pPatch;
uint32_t r = 0; uint32_t r = 0;
@@ -157,8 +162,7 @@ countpatches(struct Section * pSect)
/* /*
* Write a long to a file (little-endian) * Write a long to a file (little-endian)
*/ */
void static void fputlong(uint32_t i, FILE *f)
fputlong(uint32_t i, FILE * f)
{ {
fputc(i, f); fputc(i, f);
fputc(i >> 8, f); fputc(i >> 8, f);
@@ -169,8 +173,7 @@ fputlong(uint32_t i, FILE * f)
/* /*
* Write a NULL-terminated string to a file * Write a NULL-terminated string to a file
*/ */
void static void fputstring(char *s, FILE *f)
fputstring(char *s, FILE * f)
{ {
while (*s) while (*s)
fputc(*s++, f); fputc(*s++, f);
@@ -180,8 +183,7 @@ fputstring(char *s, FILE * f)
/* /*
* Return a section's ID * Return a section's ID
*/ */
uint32_t static uint32_t getsectid(struct Section *pSect)
getsectid(struct Section * pSect)
{ {
struct Section *sec; struct Section *sec;
uint32_t ID = 0; uint32_t ID = 0;
@@ -190,20 +192,19 @@ getsectid(struct Section * pSect)
while (sec) { while (sec) {
if (sec == pSect) if (sec == pSect)
return (ID); return ID;
ID += 1; ID += 1;
sec = sec->pNext; sec = sec->pNext;
} }
fatalerror("INTERNAL: Unknown section"); fatalerror("INTERNAL: Unknown section");
return ((uint32_t) - 1); return (uint32_t)(-1);
} }
/* /*
* Write a patch to a file * Write a patch to a file
*/ */
void static void writepatch(struct Patch *pPatch, FILE *f)
writepatch(struct Patch * pPatch, FILE * f)
{ {
fputstring(pPatch->tzFilename, f); fputstring(pPatch->tzFilename, f);
fputlong(pPatch->nLine, f); fputlong(pPatch->nLine, f);
@@ -216,8 +217,7 @@ writepatch(struct Patch * pPatch, FILE * f)
/* /*
* Write a section to a file * Write a section to a file
*/ */
void static void writesection(struct Section *pSect, FILE *f)
writesection(struct Section * pSect, FILE * f)
{ {
fputstring(pSect->pzName, f); fputstring(pSect->pzName, f);
@@ -229,8 +229,7 @@ writesection(struct Section * pSect, FILE * f)
fputlong(pSect->nBank, f); fputlong(pSect->nBank, f);
fputlong(pSect->nAlign, f); fputlong(pSect->nAlign, f);
if ((pSect->nType == SECT_ROM0) if ((pSect->nType == SECT_ROM0) || (pSect->nType == SECT_ROMX)) {
|| (pSect->nType == SECT_ROMX)) {
struct Patch *pPatch; struct Patch *pPatch;
fwrite(pSect->tData, 1, pSect->nPC, f); fwrite(pSect->tData, 1, pSect->nPC, f);
@@ -247,8 +246,7 @@ writesection(struct Section * pSect, FILE * f)
/* /*
* Write a symbol to a file * Write a symbol to a file
*/ */
void static void writesymbol(struct sSymbol *pSym, FILE *f)
writesymbol(struct sSymbol * pSym, FILE * f)
{ {
char symname[MAXSYMLEN * 2 + 1]; char symname[MAXSYMLEN * 2 + 1];
uint32_t type; uint32_t type;
@@ -295,11 +293,11 @@ writesymbol(struct sSymbol * pSym, FILE * f)
/* /*
* Add a symbol to the object * Add a symbol to the object
*/ */
uint32_t static uint32_t nextID;
addsymbol(struct sSymbol * pSym)
static uint32_t addsymbol(struct sSymbol *pSym)
{ {
struct PatchSymbol *pPSym, **ppPSym; struct PatchSymbol *pPSym, **ppPSym;
static uint32_t nextID = 0;
uint32_t hash; uint32_t hash;
hash = calchash(pSym->tzName); hash = calchash(pSym->tzName);
@@ -311,14 +309,17 @@ addsymbol(struct sSymbol * pSym)
ppPSym = &((*ppPSym)->pBucketNext); ppPSym = &((*ppPSym)->pBucketNext);
} }
if ((*ppPSym = pPSym = malloc(sizeof(struct PatchSymbol))) != NULL) { pPSym = malloc(sizeof(struct PatchSymbol));
pPSym->pNext = NULL; *ppPSym = pPSym;
pPSym->pBucketNext = NULL;
pPSym->pSymbol = pSym; if (pPSym == NULL)
pPSym->ID = nextID++;
} else
fatalerror("No memory for patchsymbol"); fatalerror("No memory for patchsymbol");
pPSym->pNext = NULL;
pPSym->pBucketNext = NULL;
pPSym->pSymbol = pSym;
pPSym->ID = nextID++;
*ppPatchSymbolsTail = pPSym; *ppPatchSymbolsTail = pPSym;
ppPatchSymbolsTail = &(pPSym->pNext); ppPatchSymbolsTail = &(pPSym->pNext);
@@ -328,8 +329,7 @@ addsymbol(struct sSymbol * pSym)
/* /*
* Add all exported symbols to the object * Add all exported symbols to the object
*/ */
void static void addexports(void)
addexports(void)
{ {
int32_t i; int32_t i;
@@ -348,28 +348,27 @@ addexports(void)
/* /*
* Allocate a new patchstructure and link it into the list * Allocate a new patchstructure and link it into the list
*/ */
struct Patch * struct Patch *allocpatch(void)
allocpatch(void)
{ {
struct Patch *pPatch; struct Patch *pPatch;
if ((pPatch = malloc(sizeof(struct Patch))) != NULL) { pPatch = malloc(sizeof(struct Patch));
pPatch->pNext = pCurrentSection->pPatches;
pPatch->nRPNSize = 0; if (pPatch == NULL)
pPatch->pRPN = NULL;
} else
fatalerror("No memory for patch"); fatalerror("No memory for patch");
pPatch->pNext = pCurrentSection->pPatches;
pPatch->nRPNSize = 0;
pPatch->pRPN = NULL;
pCurrentSection->pPatches = pPatch; pCurrentSection->pPatches = pPatch;
return (pPatch); return pPatch;
} }
/* /*
* Create a new patch (includes the rpn expr) * Create a new patch (includes the rpn expr)
*/ */
void void createpatch(uint32_t type, struct Expression *expr)
createpatch(uint32_t type, struct Expression * expr)
{ {
struct Patch *pPatch; struct Patch *pPatch;
uint16_t rpndata; uint16_t rpndata;
@@ -394,7 +393,9 @@ createpatch(uint32_t type, struct Expression * expr)
break; break;
case RPN_SYM: case RPN_SYM:
symptr = 0; symptr = 0;
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0); while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0)
;
if (sym_isConstant(tzSym)) { if (sym_isConstant(tzSym)) {
uint32_t value; uint32_t value;
@@ -405,9 +406,11 @@ createpatch(uint32_t type, struct Expression * expr)
rpnexpr[rpnptr++] = value >> 16; rpnexpr[rpnptr++] = value >> 16;
rpnexpr[rpnptr++] = value >> 24; rpnexpr[rpnptr++] = value >> 24;
} else { } else {
struct sSymbol *sym; struct sSymbol *sym = sym_FindSymbol(tzSym);
if ((sym = sym_FindSymbol(tzSym)) == NULL)
if (sym == NULL)
break; break;
symptr = addsymbol(sym); symptr = addsymbol(sym);
rpnexpr[rpnptr++] = RPN_SYM; rpnexpr[rpnptr++] = RPN_SYM;
rpnexpr[rpnptr++] = symptr & 0xFF; rpnexpr[rpnptr++] = symptr & 0xFF;
@@ -416,26 +419,34 @@ createpatch(uint32_t type, struct Expression * expr)
rpnexpr[rpnptr++] = symptr >> 24; rpnexpr[rpnptr++] = symptr >> 24;
} }
break; break;
case RPN_BANK: { case RPN_BANK:
{
struct sSymbol *sym; struct sSymbol *sym;
symptr = 0; symptr = 0;
while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0); while ((tzSym[symptr++] = rpn_PopByte(expr)) != 0)
if ((sym = sym_FindSymbol(tzSym)) == NULL) ;
sym = sym_FindSymbol(tzSym);
if (sym == NULL)
break; break;
symptr = addsymbol(sym); symptr = addsymbol(sym);
rpnexpr[rpnptr++] = RPN_BANK; rpnexpr[rpnptr++] = RPN_BANK;
rpnexpr[rpnptr++] = symptr & 0xFF; rpnexpr[rpnptr++] = symptr & 0xFF;
rpnexpr[rpnptr++] = symptr >> 8; rpnexpr[rpnptr++] = symptr >> 8;
rpnexpr[rpnptr++] = symptr >> 16; rpnexpr[rpnptr++] = symptr >> 16;
rpnexpr[rpnptr++] = symptr >> 24; rpnexpr[rpnptr++] = symptr >> 24;
}
break; break;
}
default: default:
rpnexpr[rpnptr++] = rpndata; rpnexpr[rpnptr++] = rpndata;
break; break;
} }
} }
if ((pPatch->pRPN = malloc(rpnptr)) != NULL) {
pPatch->pRPN = malloc(rpnptr);
if (pPatch->pRPN != NULL) {
memcpy(pPatch->pRPN, rpnexpr, rpnptr); memcpy(pPatch->pRPN, rpnexpr, rpnptr);
pPatch->nRPNSize = rpnptr; pPatch->nRPNSize = rpnptr;
} }
@@ -444,12 +455,9 @@ createpatch(uint32_t type, struct Expression * expr)
/* /*
* A quick check to see if we have an initialized section * A quick check to see if we have an initialized section
*/ */
void static void checksection(void)
checksection(void)
{ {
if (pCurrentSection) if (pCurrentSection == NULL)
return;
else
fatalerror("Code generation before SECTION directive"); fatalerror("Code generation before SECTION directive");
} }
@@ -457,14 +465,13 @@ checksection(void)
* A quick check to see if we have an initialized section that can contain * A quick check to see if we have an initialized section that can contain
* this much initialized data * this much initialized data
*/ */
void static void checkcodesection(void)
checkcodesection(void)
{ {
checksection(); checksection();
if (pCurrentSection->nType != SECT_ROM0 && if (pCurrentSection->nType != SECT_ROM0 &&
pCurrentSection->nType != SECT_ROMX) { pCurrentSection->nType != SECT_ROMX) {
fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)", fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)",
pCurrentSection->pzName); pCurrentSection->pzName);
} else if (nUnionDepth > 0) { } else if (nUnionDepth > 0) {
fatalerror("UNIONs cannot contain code or data"); fatalerror("UNIONs cannot contain code or data");
} }
@@ -473,8 +480,7 @@ checkcodesection(void)
/* /*
* Check if the section has grown too much. * Check if the section has grown too much.
*/ */
void static void checksectionoverflow(uint32_t delta_size)
checksectionoverflow(uint32_t delta_size)
{ {
uint32_t maxsize = getmaxsectionsize(pCurrentSection->nType, uint32_t maxsize = getmaxsectionsize(pCurrentSection->nType,
pCurrentSection->pzName); pCurrentSection->pzName);
@@ -488,21 +494,21 @@ checksectionoverflow(uint32_t delta_size)
* The real check must be done at the linking stage. * The real check must be done at the linking stage.
*/ */
fatalerror("Section '%s' is too big (max size = 0x%X bytes).", fatalerror("Section '%s' is too big (max size = 0x%X bytes).",
pCurrentSection->pzName, maxsize); pCurrentSection->pzName, maxsize);
} }
} }
/* /*
* Write an objectfile * Write an objectfile
*/ */
void void out_WriteObject(void)
out_WriteObject(void)
{ {
FILE *f; FILE *f;
addexports(); addexports();
if ((f = fopen(tzObjectname, "wb")) != NULL) { f = fopen(tzObjectname, "wb");
if (f != NULL) {
struct PatchSymbol *pSym; struct PatchSymbol *pSym;
struct Section *pSect; struct Section *pSect;
@@ -531,8 +537,7 @@ out_WriteObject(void)
/* /*
* Prepare for pass #2 * Prepare for pass #2
*/ */
void void out_PrepPass2(void)
out_PrepPass2(void)
{ {
struct Section *pSect; struct Section *pSect;
@@ -548,13 +553,12 @@ out_PrepPass2(void)
/* /*
* Set the objectfilename * Set the objectfilename
*/ */
void void out_SetFileName(char *s)
out_SetFileName(char *s)
{ {
tzObjectname = s; tzObjectname = s;
if (CurrentOptions.verbose) { if (CurrentOptions.verbose)
printf("Output filename %s\n", s); printf("Output filename %s\n", s);
}
pSectionList = NULL; pSectionList = NULL;
pCurrentSection = NULL; pCurrentSection = NULL;
pPatchSymbols = NULL; pPatchSymbols = NULL;
@@ -563,8 +567,8 @@ out_SetFileName(char *s)
/* /*
* Find a section by name and type. If it doesn't exist, create it * Find a section by name and type. If it doesn't exist, create it
*/ */
struct Section * struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int32_t alignment) int32_t bank, int32_t alignment)
{ {
struct Section *pSect, **ppSect; struct Section *pSect, **ppSect;
@@ -574,58 +578,61 @@ out_FindSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank, int3
while (pSect) { while (pSect) {
if (strcmp(pzName, pSect->pzName) == 0) { if (strcmp(pzName, pSect->pzName) == 0) {
if (secttype == pSect->nType if (secttype == pSect->nType
&& ((uint32_t) org) == pSect->nOrg && ((uint32_t)org) == pSect->nOrg
&& ((uint32_t) bank) == pSect->nBank && ((uint32_t)bank) == pSect->nBank
&& ((uint32_t) alignment == pSect->nAlign)) { && ((uint32_t)alignment == pSect->nAlign)) {
return (pSect); return pSect;
} else }
fatalerror
("Section already exists but with a different type"); fatalerror("Section already exists but with a different type");
} }
ppSect = &(pSect->pNext); ppSect = &(pSect->pNext);
pSect = pSect->pNext; pSect = pSect->pNext;
} }
if ((*ppSect = (pSect = malloc(sizeof(struct Section)))) != NULL) { pSect = malloc(sizeof(struct Section));
if ((pSect->pzName = malloc(strlen(pzName) + 1)) != NULL) { *ppSect = pSect;
strcpy(pSect->pzName, pzName); if (pSect == NULL)
pSect->nType = secttype;
pSect->nPC = 0;
pSect->nOrg = org;
pSect->nBank = bank;
pSect->nAlign = alignment;
pSect->pNext = NULL;
pSect->pPatches = NULL;
pSect->charmap = NULL;
pPatchSymbols = NULL;
pSect->tData = NULL;
if (secttype == SECT_ROM0 || secttype == SECT_ROMX) {
/* It is only needed to allocate memory for ROM
* sections. */
uint32_t sectsize = getmaxsectionsize(secttype, pzName);
if ((pSect->tData = malloc(sectsize)) == NULL)
fatalerror("Not enough memory for section");
}
return (pSect);
} else
fatalerror("Not enough memory for sectionname");
} else
fatalerror("Not enough memory for section"); fatalerror("Not enough memory for section");
return (NULL); pSect->pzName = malloc(strlen(pzName) + 1);
if (pSect->pzName == NULL)
fatalerror("Not enough memory for sectionname");
strcpy(pSect->pzName, pzName);
pSect->nType = secttype;
pSect->nPC = 0;
pSect->nOrg = org;
pSect->nBank = bank;
pSect->nAlign = alignment;
pSect->pNext = NULL;
pSect->pPatches = NULL;
pSect->charmap = NULL;
pPatchSymbols = NULL;
/* It is only needed to allocate memory for ROM sections. */
if (secttype == SECT_ROM0 || secttype == SECT_ROMX) {
uint32_t sectsize;
sectsize = getmaxsectionsize(secttype, pzName);
pSect->tData = malloc(sectsize);
if (pSect->tData == NULL)
fatalerror("Not enough memory for section");
} else {
pSect->tData = NULL;
}
return (pSect);
} }
/* /*
* Set the current section * Set the current section
*/ */
void void out_SetCurrentSection(struct Section *pSect)
out_SetCurrentSection(struct Section * pSect)
{ {
if (nUnionDepth > 0) { if (nUnionDepth > 0)
fatalerror("Cannot change the section within a UNION"); fatalerror("Cannot change the section within a UNION");
}
pCurrentSection = pSect; pCurrentSection = pSect;
nPC = pSect->nPC; nPC = pSect->nPC;
@@ -636,8 +643,7 @@ out_SetCurrentSection(struct Section * pSect)
/* /*
* Set the current section by name and type * Set the current section by name and type
*/ */
void void out_NewSection(char *pzName, uint32_t secttype)
out_NewSection(char *pzName, uint32_t secttype)
{ {
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1)); out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1));
} }
@@ -645,8 +651,8 @@ out_NewSection(char *pzName, uint32_t secttype)
/* /*
* Set the current section by name and type * Set the current section by name and type
*/ */
void void out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org,
out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank) int32_t bank)
{ {
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1)); out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1));
} }
@@ -654,20 +660,20 @@ out_NewAbsSection(char *pzName, uint32_t secttype, int32_t org, int32_t bank)
/* /*
* Set the current section by name and type, using a given byte alignment * Set the current section by name and type, using a given byte alignment
*/ */
void void out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment,
out_NewAlignedSection(char *pzName, uint32_t secttype, int32_t alignment, int32_t bank) int32_t bank)
{ {
if (alignment < 0 || alignment > 16) { if (alignment < 0 || alignment > 16)
yyerror("Alignment must be between 0-16 bits."); yyerror("Alignment must be between 0-16 bits.");
}
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment)); out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank,
1 << alignment));
} }
/* /*
* Output an absolute byte (bypassing ROM/union checks) * Output an absolute byte (bypassing ROM/union checks)
*/ */
void void out_AbsByteBypassCheck(int32_t b)
out_AbsByteBypassCheck(int32_t b)
{ {
checksectionoverflow(1); checksectionoverflow(1);
b &= 0xFF; b &= 0xFF;
@@ -682,15 +688,13 @@ out_AbsByteBypassCheck(int32_t b)
/* /*
* Output an absolute byte * Output an absolute byte
*/ */
void void out_AbsByte(int32_t b)
out_AbsByte(int32_t b)
{ {
checkcodesection(); checkcodesection();
out_AbsByteBypassCheck(b); out_AbsByteBypassCheck(b);
} }
void void out_AbsByteGroup(char *s, int32_t length)
out_AbsByteGroup(char *s, int32_t length)
{ {
checkcodesection(); checkcodesection();
checksectionoverflow(length); checksectionoverflow(length);
@@ -701,8 +705,7 @@ out_AbsByteGroup(char *s, int32_t length)
/* /*
* Skip this many bytes * Skip this many bytes
*/ */
void void out_Skip(int32_t skip)
out_Skip(int32_t skip)
{ {
checksection(); checksection();
checksectionoverflow(skip); checksectionoverflow(skip);
@@ -724,8 +727,7 @@ out_Skip(int32_t skip)
/* /*
* Output a NULL terminated string (excluding the NULL-character) * Output a NULL terminated string (excluding the NULL-character)
*/ */
void void out_String(char *s)
out_String(char *s)
{ {
checkcodesection(); checkcodesection();
checksectionoverflow(strlen(s)); checksectionoverflow(strlen(s));
@@ -737,9 +739,7 @@ out_String(char *s)
* Output a relocatable byte. Checking will be done to see if it * Output a relocatable byte. Checking will be done to see if it
* is an absolute value in disguise. * is an absolute value in disguise.
*/ */
void out_RelByte(struct Expression *expr)
void
out_RelByte(struct Expression * expr)
{ {
checkcodesection(); checkcodesection();
checksectionoverflow(1); checksectionoverflow(1);
@@ -751,17 +751,16 @@ out_RelByte(struct Expression * expr)
pCurrentSection->nPC += 1; pCurrentSection->nPC += 1;
nPC += 1; nPC += 1;
pPCSymbol->nValue += 1; pPCSymbol->nValue += 1;
} else } else {
out_AbsByte(expr->nVal); out_AbsByte(expr->nVal);
}
rpn_Reset(expr); rpn_Reset(expr);
} }
/* /*
* Output an absolute word * Output an absolute word
*/ */
void void out_AbsWord(int32_t b)
out_AbsWord(int32_t b)
{ {
checkcodesection(); checkcodesection();
checksectionoverflow(2); checksectionoverflow(2);
@@ -779,8 +778,7 @@ out_AbsWord(int32_t b)
* Output a relocatable word. Checking will be done to see if * Output a relocatable word. Checking will be done to see if
* it's an absolute value in disguise. * it's an absolute value in disguise.
*/ */
void void out_RelWord(struct Expression *expr)
out_RelWord(struct Expression * expr)
{ {
uint32_t b; uint32_t b;
@@ -796,16 +794,16 @@ out_RelWord(struct Expression * expr)
pCurrentSection->nPC += 2; pCurrentSection->nPC += 2;
nPC += 2; nPC += 2;
pPCSymbol->nValue += 2; pPCSymbol->nValue += 2;
} else } else {
out_AbsWord(expr->nVal); out_AbsWord(expr->nVal);
}
rpn_Reset(expr); rpn_Reset(expr);
} }
/* /*
* Output an absolute longword * Output an absolute longword
*/ */
void void out_AbsLong(int32_t b)
out_AbsLong(int32_t b)
{ {
checkcodesection(); checkcodesection();
checksectionoverflow(sizeof(int32_t)); checksectionoverflow(sizeof(int32_t));
@@ -824,8 +822,7 @@ out_AbsLong(int32_t b)
* Output a relocatable longword. Checking will be done to see if * Output a relocatable longword. Checking will be done to see if
* is an absolute value in disguise. * is an absolute value in disguise.
*/ */
void void out_RelLong(struct Expression *expr)
out_RelLong(struct Expression * expr)
{ {
int32_t b; int32_t b;
@@ -843,16 +840,16 @@ out_RelLong(struct Expression * expr)
pCurrentSection->nPC += 4; pCurrentSection->nPC += 4;
nPC += 4; nPC += 4;
pPCSymbol->nValue += 4; pPCSymbol->nValue += 4;
} else } else {
out_AbsLong(expr->nVal); out_AbsLong(expr->nVal);
}
rpn_Reset(expr); rpn_Reset(expr);
} }
/* /*
* Output a PC-relative byte * Output a PC-relative byte
*/ */
void void out_PCRelByte(struct Expression *expr)
out_PCRelByte(struct Expression * expr)
{ {
int32_t b = expr->nVal; int32_t b = expr->nVal;
@@ -869,15 +866,13 @@ out_PCRelByte(struct Expression * expr)
/* /*
* Output a binary file * Output a binary file
*/ */
void void out_BinaryFile(char *s)
out_BinaryFile(char *s)
{ {
FILE *f; FILE *f;
f = fstk_FindFile(s); f = fstk_FindFile(s);
if (f == NULL) { if (f == NULL)
err(1, "Unable to open incbin file '%s'", s); err(1, "Unable to open incbin file '%s'", s);
}
int32_t fsize; int32_t fsize;
@@ -901,8 +896,7 @@ out_BinaryFile(char *s)
fclose(f); fclose(f);
} }
void void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
{ {
FILE *f; FILE *f;
@@ -913,9 +907,8 @@ out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
fatalerror("Number of bytes to read must be greater than zero"); fatalerror("Number of bytes to read must be greater than zero");
f = fstk_FindFile(s); f = fstk_FindFile(s);
if (f == NULL) { if (f == NULL)
err(1, "Unable to open included file '%s'", s); err(1, "Unable to open included file '%s'", s);
}
int32_t fsize; int32_t fsize;

View File

@@ -12,9 +12,8 @@
#include "asm/rpn.h" #include "asm/rpn.h"
#include "asm/symbol.h" #include "asm/symbol.h"
void void mergetwoexpressions(struct Expression *expr, const struct Expression *src1,
mergetwoexpressions(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
*expr = *src1; *expr = *src1;
memcpy(&(expr->tRPN[expr->nRPNLength]), src2->tRPN, src2->nRPNLength); memcpy(&(expr->tRPN[expr->nRPNLength]), src2->tRPN, src2->nRPNLength);
@@ -23,13 +22,13 @@ mergetwoexpressions(struct Expression * expr, struct Expression * src1,
expr->isReloc |= src2->isReloc; expr->isReloc |= src2->isReloc;
expr->isPCRel |= src2->isPCRel; expr->isPCRel |= src2->isPCRel;
} }
#define joinexpr() mergetwoexpressions(expr,src1,src2)
#define joinexpr() mergetwoexpressions(expr, src1, src2)
/* /*
* Add a byte to the RPN expression * Add a byte to the RPN expression
*/ */
void void pushbyte(struct Expression *expr, int b)
pushbyte(struct Expression * expr, int b)
{ {
expr->tRPN[expr->nRPNLength++] = b & 0xFF; expr->tRPN[expr->nRPNLength++] = b & 0xFF;
} }
@@ -37,47 +36,45 @@ pushbyte(struct Expression * expr, int b)
/* /*
* Reset the RPN module * Reset the RPN module
*/ */
void void rpn_Reset(struct Expression *expr)
rpn_Reset(struct Expression * expr)
{ {
expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0; expr->nRPNLength = 0;
expr->nRPNOut = 0;
expr->isReloc = 0;
expr->isPCRel = 0;
} }
/* /*
* Returns the next rpn byte in expression * Returns the next rpn byte in expression
*/ */
uint16_t uint16_t rpn_PopByte(struct Expression *expr)
rpn_PopByte(struct Expression * expr)
{ {
if (expr->nRPNOut == expr->nRPNLength) { if (expr->nRPNOut == expr->nRPNLength)
return (0xDEAD); return 0xDEAD;
} else
return (expr->tRPN[expr->nRPNOut++]); return expr->tRPN[expr->nRPNOut++];
} }
/* /*
* Determine if the current expression is relocatable * Determine if the current expression is relocatable
*/ */
uint32_t uint32_t rpn_isReloc(const struct Expression *expr)
rpn_isReloc(struct Expression * expr)
{ {
return (expr->isReloc); return expr->isReloc;
} }
/* /*
* Determine if the current expression can be pc-relative * Determine if the current expression can be pc-relative
*/ */
uint32_t uint32_t rpn_isPCRelative(const struct Expression *expr)
rpn_isPCRelative(struct Expression * expr)
{ {
return (expr->isPCRel); return expr->isPCRel;
} }
/* /*
* Add symbols, constants and operators to expression * Add symbols, constants and operators to expression
*/ */
void void rpn_Number(struct Expression *expr, uint32_t i)
rpn_Number(struct Expression * expr, uint32_t i)
{ {
rpn_Reset(expr); rpn_Reset(expr);
pushbyte(expr, RPN_CONST); pushbyte(expr, RPN_CONST);
@@ -88,11 +85,10 @@ rpn_Number(struct Expression * expr, uint32_t i)
expr->nVal = i; expr->nVal = i;
} }
void void rpn_Symbol(struct Expression *expr, char *tzSym)
rpn_Symbol(struct Expression * expr, char *tzSym)
{ {
if (!sym_isConstant(tzSym)) { if (!sym_isConstant(tzSym)) {
struct sSymbol *psym; const struct sSymbol *psym;
rpn_Reset(expr); rpn_Reset(expr);
@@ -106,17 +102,20 @@ rpn_Symbol(struct Expression * expr, char *tzSym)
while (*tzSym) while (*tzSym)
pushbyte(expr, *tzSym++); pushbyte(expr, *tzSym++);
pushbyte(expr, 0); pushbyte(expr, 0);
} else } else {
rpn_Number(expr, sym_GetConstantValue(tzSym)); rpn_Number(expr, sym_GetConstantValue(tzSym));
}
} }
void void rpn_Bank(struct Expression *expr, char *tzSym)
rpn_Bank(struct Expression * expr, char *tzSym)
{ {
if (!sym_isConstant(tzSym)) { if (!sym_isConstant(tzSym)) {
rpn_Reset(expr); rpn_Reset(expr);
/* Check that the symbol exists by evaluating and discarding the value. */ /*
* Check that the symbol exists by evaluating and discarding the
* value.
*/
sym_GetValue(tzSym); sym_GetValue(tzSym);
expr->isReloc = 1; expr->isReloc = 1;
@@ -124,44 +123,40 @@ rpn_Bank(struct Expression * expr, char *tzSym)
while (*tzSym) while (*tzSym)
pushbyte(expr, *tzSym++); pushbyte(expr, *tzSym++);
pushbyte(expr, 0); pushbyte(expr, 0);
} else } else {
yyerror("BANK argument must be a relocatable identifier"); yyerror("BANK argument must be a relocatable identifier");
}
} }
void void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
rpn_CheckHRAM(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
pushbyte(expr, RPN_HRAM); pushbyte(expr, RPN_HRAM);
} }
void void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
rpn_LOGNOT(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
pushbyte(expr, RPN_LOGUNNOT); pushbyte(expr, RPN_LOGUNNOT);
} }
void void rpn_LOGOR(struct Expression *expr, const struct Expression *src1,
rpn_LOGOR(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal || src2->nVal); expr->nVal = (expr->nVal || src2->nVal);
pushbyte(expr, RPN_LOGOR); pushbyte(expr, RPN_LOGOR);
} }
void void rpn_LOGAND(struct Expression *expr, const struct Expression *src1,
rpn_LOGAND(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal && src2->nVal); expr->nVal = (expr->nVal && src2->nVal);
pushbyte(expr, RPN_LOGAND); pushbyte(expr, RPN_LOGAND);
} }
void void rpn_HIGH(struct Expression *expr, const struct Expression *src)
rpn_HIGH(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
@@ -184,8 +179,7 @@ rpn_HIGH(struct Expression * expr, struct Expression * src)
pushbyte(expr, RPN_AND); pushbyte(expr, RPN_AND);
} }
void void rpn_LOW(struct Expression *expr, const struct Expression *src)
rpn_LOW(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
@@ -200,166 +194,148 @@ rpn_LOW(struct Expression * expr, struct Expression * src)
pushbyte(expr, RPN_AND); pushbyte(expr, RPN_AND);
} }
void void rpn_LOGEQU(struct Expression *expr, const struct Expression *src1,
rpn_LOGEQU(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal == src2->nVal); expr->nVal = (expr->nVal == src2->nVal);
pushbyte(expr, RPN_LOGEQ); pushbyte(expr, RPN_LOGEQ);
} }
void void rpn_LOGGT(struct Expression *expr, const struct Expression *src1,
rpn_LOGGT(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal > src2->nVal); expr->nVal = (expr->nVal > src2->nVal);
pushbyte(expr, RPN_LOGGT); pushbyte(expr, RPN_LOGGT);
} }
void void rpn_LOGLT(struct Expression *expr, const struct Expression *src1,
rpn_LOGLT(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal < src2->nVal); expr->nVal = (expr->nVal < src2->nVal);
pushbyte(expr, RPN_LOGLT); pushbyte(expr, RPN_LOGLT);
} }
void void rpn_LOGGE(struct Expression *expr, const struct Expression *src1,
rpn_LOGGE(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal >= src2->nVal); expr->nVal = (expr->nVal >= src2->nVal);
pushbyte(expr, RPN_LOGGE); pushbyte(expr, RPN_LOGGE);
} }
void void rpn_LOGLE(struct Expression *expr, const struct Expression *src1,
rpn_LOGLE(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal <= src2->nVal); expr->nVal = (expr->nVal <= src2->nVal);
pushbyte(expr, RPN_LOGLE); pushbyte(expr, RPN_LOGLE);
} }
void void rpn_LOGNE(struct Expression *expr, const struct Expression *src1,
rpn_LOGNE(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal != src2->nVal); expr->nVal = (expr->nVal != src2->nVal);
pushbyte(expr, RPN_LOGNE); pushbyte(expr, RPN_LOGNE);
} }
void void rpn_ADD(struct Expression *expr, const struct Expression *src1,
rpn_ADD(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal + src2->nVal); expr->nVal = (expr->nVal + src2->nVal);
pushbyte(expr, RPN_ADD); pushbyte(expr, RPN_ADD);
} }
void void rpn_SUB(struct Expression *expr, const struct Expression *src1,
rpn_SUB(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal - src2->nVal); expr->nVal = (expr->nVal - src2->nVal);
pushbyte(expr, RPN_SUB); pushbyte(expr, RPN_SUB);
} }
void void rpn_XOR(struct Expression *expr, const struct Expression *src1,
rpn_XOR(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal ^ src2->nVal); expr->nVal = (expr->nVal ^ src2->nVal);
pushbyte(expr, RPN_XOR); pushbyte(expr, RPN_XOR);
} }
void void rpn_OR(struct Expression *expr, const struct Expression *src1,
rpn_OR(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal | src2->nVal); expr->nVal = (expr->nVal | src2->nVal);
pushbyte(expr, RPN_OR); pushbyte(expr, RPN_OR);
} }
void void rpn_AND(struct Expression *expr, const struct Expression *src1,
rpn_AND(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal & src2->nVal); expr->nVal = (expr->nVal & src2->nVal);
pushbyte(expr, RPN_AND); pushbyte(expr, RPN_AND);
} }
void void rpn_SHL(struct Expression *expr, const struct Expression *src1,
rpn_SHL(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal << src2->nVal); expr->nVal = (expr->nVal << src2->nVal);
pushbyte(expr, RPN_SHL); pushbyte(expr, RPN_SHL);
} }
void void rpn_SHR(struct Expression *expr, const struct Expression *src1,
rpn_SHR(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal >> src2->nVal); expr->nVal = (expr->nVal >> src2->nVal);
pushbyte(expr, RPN_SHR); pushbyte(expr, RPN_SHR);
} }
void void rpn_MUL(struct Expression *expr, const struct Expression *src1,
rpn_MUL(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
expr->nVal = (expr->nVal * src2->nVal); expr->nVal = (expr->nVal * src2->nVal);
pushbyte(expr, RPN_MUL); pushbyte(expr, RPN_MUL);
} }
void void rpn_DIV(struct Expression *expr, const struct Expression *src1,
rpn_DIV(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
if (src2->nVal == 0) { if (src2->nVal == 0)
fatalerror("division by zero"); fatalerror("division by zero");
}
expr->nVal = (expr->nVal / src2->nVal); expr->nVal = (expr->nVal / src2->nVal);
pushbyte(expr, RPN_DIV); pushbyte(expr, RPN_DIV);
} }
void void rpn_MOD(struct Expression *expr, const struct Expression *src1,
rpn_MOD(struct Expression * expr, struct Expression * src1, const struct Expression *src2)
struct Expression * src2)
{ {
joinexpr(); joinexpr();
if (src2->nVal == 0) { if (src2->nVal == 0)
fatalerror("division by zero"); fatalerror("division by zero");
}
expr->nVal = (expr->nVal % src2->nVal); expr->nVal = (expr->nVal % src2->nVal);
pushbyte(expr, RPN_MOD); pushbyte(expr, RPN_MOD);
} }
void void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
rpn_UNNEG(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
expr->nVal = -expr->nVal; expr->nVal = -expr->nVal;
pushbyte(expr, RPN_UNSUB); pushbyte(expr, RPN_UNSUB);
} }
void void rpn_UNNOT(struct Expression *expr, const struct Expression *src)
rpn_UNNOT(struct Expression * expr, struct Expression * src)
{ {
*expr = *src; *expr = *src;
expr->nVal = ~expr->nVal; expr->nVal = ~expr->nVal;

File diff suppressed because it is too large Load Diff