Skip to content

Commit

Permalink
Issue #66 - predefined constants refactored to be closer to gcc/clang…
Browse files Browse the repository at this point in the history
… ones

New predefineds in this commit:
__INCLUDE_LEVEL__, __BASE_FILE__, __FILE__, __LINE__, __COUNTER__
  • Loading branch information
ped7g committed Jul 10, 2020
1 parent 0efee27 commit 3688aa9
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 2 deletions.
9 changes: 8 additions & 1 deletion sjasm/sjasm.cpp
Expand Up @@ -206,7 +206,7 @@ byte* MemoryPointer=NULL;
int macronummer = 0, lijst = 0, reglenwidth = 0;
TextFilePos CurSourcePos, DefinitionPos;
uint32_t maxlin = 0;
aint CurAddress = 0, CompiledCurrentLine = 0, LastParsedLabelLine = 0;
aint CurAddress = 0, CompiledCurrentLine = 0, LastParsedLabelLine = 0, PredefinedCounter = 0;
aint destlen = 0, size = -1L,PreviousErrorLine = -1L, comlin = 0;
char* CurrentDirectory=NULL;

Expand Down Expand Up @@ -282,6 +282,13 @@ void InitPass() {
DefineTable.Replace("__ERRORS__", "0"); // migrated from _ERRORS
DefineTable.Replace("__WARNINGS__", "0"); // migrated from _WARNINGS
DefineTable.Replace("__PASS__", pass); // current pass of assembler
DefineTable.Replace("__INCLUDE_LEVEL__", "-1"); // include nesting
DefineTable.Replace("__BASE_FILE__", "<none>"); // the include-level 0 file
DefineTable.Replace("__FILE__", "<none>"); // current file
DefineTable.Replace("__LINE__", "<dynamic value>"); // current line in current file
DefineTable.Replace("__COUNTER__", "<dynamic value>"); // gcc-like, incremented upon every use
PredefinedCounter = 0;

// resurrect "global" device here
if (globalDeviceID && !SetDevice(globalDeviceID, globalDeviceZxRamTop)) {
Error("Failed to re-initialize global device", globalDeviceID, FATAL);
Expand Down
2 changes: 1 addition & 1 deletion sjasm/sjasm.h
Expand Up @@ -136,7 +136,7 @@ extern byte* MemoryPointer;
extern int macronummer, lijst, reglenwidth;
extern TextFilePos CurSourcePos, DefinitionPos;
extern uint32_t maxlin;
extern aint CurAddress, CompiledCurrentLine, LastParsedLabelLine;
extern aint CurAddress, CompiledCurrentLine, LastParsedLabelLine, PredefinedCounter;
extern aint destlen, size, PreviousErrorLine, comlin;

extern char* vorlabp, * macrolabp, * LastParsedLabel;
Expand Down
10 changes: 10 additions & 0 deletions sjasm/sjio.cpp
Expand Up @@ -610,6 +610,11 @@ void OpenFile(const char* nfilename, bool systemPathsBeforeCurrent, stdin_log_t*
fileNameFull = ofnIt->c_str(); // get const pointer into archive
CurSourcePos.newFile(Options::IsShowFullPath ? fileNameFull : FilenameBasePos(fileNameFull));

// refresh pre-defined values related to file/include
DefineTable.Replace("__INCLUDE_LEVEL__", IncludeLevel);
DefineTable.Replace("__FILE__", fileNameFull);
if (0 == IncludeLevel) DefineTable.Replace("__BASE_FILE__", fileNameFull);

// open default listing file for each new source file (if default listing is ON)
if (LASTPASS == pass && 0 == IncludeLevel && Options::IsDefaultListingName) {
OpenDefaultList(fullpath); // explicit listing file is already opened
Expand Down Expand Up @@ -665,6 +670,11 @@ void OpenFile(const char* nfilename, bool systemPathsBeforeCurrent, stdin_log_t*
}
fileNameFull = oFileNameFull;
CurSourcePos = oSourcePos;

// refresh pre-defined values related to file/include
DefineTable.Replace("__INCLUDE_LEVEL__", IncludeLevel);
DefineTable.Replace("__FILE__", fileNameFull ? fileNameFull : "<none>");
if (-1 == IncludeLevel) DefineTable.Replace("__BASE_FILE__", "<none>");
}

void IncludeFile(const char* nfilename, bool systemPathsBeforeCurrent)
Expand Down
15 changes: 15 additions & 0 deletions sjasm/tables.cpp
Expand Up @@ -654,8 +654,23 @@ void CDefineTable::Add(const char* name, const char* value, CStringsList* nss) {
defs[(*name)&127] = new CDefineTableEntry(name, value, nss, defs[(*name)&127]);
}

static char defineGet__Counter__Buffer[32] = {};
static char defineGet__Line__Buffer[32] = {};

char* CDefineTable::Get(const char* name) {
if (NULL != name) {
// the __COUNTER__ and __LINE__ have fully dynamic custom implementation here
if ('_' == name[1]) {
if (!strcmp(name, "__COUNTER__")) {
SPRINTF1(defineGet__Counter__Buffer, 30, "%d", PredefinedCounter);
++PredefinedCounter;
return defineGet__Counter__Buffer;
}
if (!strcmp(name, "__LINE__")) {
SPRINTF1(defineGet__Line__Buffer, 30, "%d", CurSourcePos.line);
return defineGet__Line__Buffer;
}
}
CDefineTableEntry* p = defs[(*name)&127];
while (p) {
if (!strcmp(name, p->name)) {
Expand Down
21 changes: 21 additions & 0 deletions tests/define/predefined_base_file.asm
@@ -0,0 +1,21 @@
; the __FILE__ and __LINE__ values are raw without quotes, so they are currently
; difficult to use with sjasmplus, the Lua script can manipulate them well
; but sjasmplus itself would need maybe some string operators... or even more?
OUTPUT "predefined_base_file.bin"

DB 0, 1, 2, 3, 255, 254, 253, 252, 10, 10, 10 ; make sure git doesn't treat this as text file
DB "Main file before INCLUDE:\n"
LUA ALLPASS
_pc("DB \"base: " .. sj.get_define("__BASE_FILE__") .. "\\n\"")
_pc("DB \"file: " .. sj.get_define("__FILE__") .. "\\n\"")
_pc("DB \"ENDLUA line: " .. sj.get_define("__LINE__") .. "\\n\"")
ENDLUA

INCLUDE "predefined_base_file.i.asm"

DB "Main file after INCLUDE:\n"
LUA ALLPASS
_pc("DB \"base: " .. sj.get_define("__BASE_FILE__") .. "\\n\"")
_pc("DB \"file: " .. sj.get_define("__FILE__") .. "\\n\"")
_pc("DB \"ENDLUA line: " .. sj.get_define("__LINE__") .. "\\n\"")
ENDLUA
Binary file added tests/define/predefined_base_file.bin
Binary file not shown.
28 changes: 28 additions & 0 deletions tests/define/predefined_base_file.i.asm
@@ -0,0 +1,28 @@
IF 1 == __INCLUDE_LEVEL__

DB "Before second INCLUDE:\n"
LUA ALLPASS
_pc("DB \"base: " .. sj.get_define("__BASE_FILE__") .. "\\n\"")
_pc("DB \"file: " .. sj.get_define("__FILE__") .. "\\n\"")
_pc("DB \"ENDLUA line: " .. sj.get_define("__LINE__") .. "\\n\"")
ENDLUA

INCLUDE "predefined_base_file.i.asm"

DB "After second INCLUDE:\n"
LUA ALLPASS
_pc("DB \"base: " .. sj.get_define("__BASE_FILE__") .. "\\n\"")
_pc("DB \"file: " .. sj.get_define("__FILE__") .. "\\n\"")
_pc("DB \"ENDLUA line: " .. sj.get_define("__LINE__") .. "\\n\"")
ENDLUA

ELSE

DB "Inside second INCLUDE:\n"
LUA ALLPASS
_pc("DB \"base: " .. sj.get_define("__BASE_FILE__") .. "\\n\"")
_pc("DB \"file: " .. sj.get_define("__FILE__") .. "\\n\"")
_pc("DB \"ENDLUA line: " .. sj.get_define("__LINE__") .. "\\n\"")
ENDLUA

ENDIF
16 changes: 16 additions & 0 deletions tests/define/predefined_counter.asm
@@ -0,0 +1,16 @@
DB __COUNTER__

TestLabel__COUNTER__:
; ^^ does NOT work, because "_" at beginning of __COUNTER__
; prevents sub-word substitution = TODO for sjasmplus v2.x

LUA ALLPASS ; as usually, lua for the rescue
sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
sj.add_byte(sj.get_define("__COUNTER__"))
sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
sj.add_byte(sj.get_define("__COUNTER__"))
sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
sj.add_byte(sj.get_define("__COUNTER__"))
ENDLUA

DB __COUNTER__
26 changes: 26 additions & 0 deletions tests/define/predefined_counter.lst
@@ -0,0 +1,26 @@
# file opened: predefined_counter.asm
1 0000 00 DB 0
2 0001
3 0001 TestLabel__COUNTER__:
4 0001 ; ^^ does NOT work, because "_" at beginning of __COUNTER__
5 0001 ; prevents sub-word substitution = TODO for sjasmplus v2.x
6 0001
7 0001 LUA ALLPASS ; as usually, lua for the rescue
8 0001 ~ sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
9 0001 ~ sj.add_byte(sj.get_define("__COUNTER__"))
10 0001 ~ sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
11 0001 ~ sj.add_byte(sj.get_define("__COUNTER__"))
12 0001 ~ sj.insert_label("lua_label_" .. sj.get_define("__COUNTER__"), sj.current_address)
13 0001 ~ sj.add_byte(sj.get_define("__COUNTER__"))
14 0001 02 04 06 ENDLUA
15 0004
16 0004 07 DB 7
17 0005
# file closed: predefined_counter.asm

Value Label
------ - -----------------------------------------------------------
0x0001 X TestLabel__COUNTER__
0x0001 X lua_label_1
0x0002 X lua_label_3
0x0003 X lua_label_5
19 changes: 19 additions & 0 deletions tests/define/predefined_include_level.asm
@@ -0,0 +1,19 @@
IFNDEF MAIN_FILE
DEFINE MAIN_FILE
OUTPUT "predefined_include_level.bin"
myIncludeLevel = 0
ENDIF

; before another INCLUDE
ASSERT __INCLUDE_LEVEL__ == myIncludeLevel
DB __INCLUDE_LEVEL__, myIncludeLevel

IF myIncludeLevel < 6
myIncludeLevel = myIncludeLevel + 1
INCLUDE "predefined_include_level.asm"
myIncludeLevel = myIncludeLevel - 1
ENDIF

; after another INCLUDE
ASSERT __INCLUDE_LEVEL__ == myIncludeLevel
DB __INCLUDE_LEVEL__, myIncludeLevel
Binary file added tests/define/predefined_include_level.bin
Binary file not shown.

0 comments on commit 3688aa9

Please sign in to comment.