From 8def8e7c38305aa0445787f7d0f7c5ff89137b49 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Mon, 27 May 2019 20:52:40 -0400 Subject: [PATCH] zasm: add lineno to error reports For now, top-level only --- apps/zasm/io.asm | 45 +++++++++++++++++++++++++++++++++++++++------ apps/zasm/main.asm | 11 ++++++----- tools/emul/zasm/zasm.bin | Bin 4051 -> 4210 bytes tools/emul/zasm/zasm.c | 3 ++- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/apps/zasm/io.asm b/apps/zasm/io.asm index c9bee13..3fa0da0 100644 --- a/apps/zasm/io.asm +++ b/apps/zasm/io.asm @@ -7,6 +7,11 @@ ; This unit also has the responsibility of counting the number of written bytes, ; maintaining IO_PC and of properly disabling output on first pass. ; +; On top of that, this unit has the responsibility of keeping track of the +; current lineno. Whenever GetC is called, we check if the fetched char is a +; newline. If it is, we increase our lineno. This unit is the best place to +; keep track of this because we have to handle ioRecallPos. +; ; zasm doesn't buffers its reads during tokenization, which simplifies its ; process. However, it also means that it needs, in certain cases, a "putback" ; mechanism, that is, a way to say "you see that character I've just read? that @@ -50,8 +55,12 @@ ; see ioPutBack below .equ IO_PUTBACK_BUF IO_INCLUDE_HDL+FS_HANDLE_SIZE .equ IO_IN_INCLUDE IO_PUTBACK_BUF+1 -.equ IO_PC IO_IN_INCLUDE+1 -.equ IO_RAMEND IO_PC+2 +.equ IO_PC IO_IN_INCLUDE+1 +; Current lineno in top-level file +.equ IO_LINENO IO_PC+2 +; Line number (can be top-level or include) when ioSavePos was last called. +.equ IO_SAVED_LINENO IO_LINENO+2 +.equ IO_RAMEND IO_SAVED_LINENO+2 ; *** Code *** @@ -59,7 +68,7 @@ ioInit: xor a ld (IO_PUTBACK_BUF), a ld (IO_IN_INCLUDE), a - jp ioResetPC + jp ioResetCounters ioGetC: ld a, (IO_PUTBACK_BUF) @@ -89,7 +98,17 @@ ioGetC: .normalmode: ; normal mode, read from IN stream ld ix, (IO_IN_GETC) - jp (ix) + call _callIX + cp 0x0a ; newline + ret nz ; not newline? return + ; inc current lineno + push hl + ld hl, IO_LINENO + inc (hl) + pop hl + cp a ; ensure Z + ret + .getback: push af xor a @@ -97,6 +116,10 @@ ioGetC: pop af ret +_callIX: + jp (ix) + ret + ; Put back non-zero character A into the "ioGetC stack". The next ioGetC call, ; instead of reading from IO_IN_GETC, will return that character. That's the ; easiest way I found to handle the readWord/gotoNextLine problem. @@ -121,21 +144,27 @@ ioPutC: ret ioSavePos: + ld hl, (IO_LINENO) + ld (IO_SAVED_LINENO), hl call _ioTell ld (IO_SAVED_POS), hl ret ioRecallPos: + ld hl, (IO_SAVED_LINENO) + ld (IO_LINENO), hl ld hl, (IO_SAVED_POS) jr _ioSeek ioRewind: - ld hl, 0 + call ioResetCounters ; sets HL to 0 jr _ioSeek -ioResetPC: +ioResetCounters: ld hl, 0 ld (IO_PC), hl + ld (IO_LINENO), hl + ld (IO_SAVED_LINENO), hl ret ; always in absolute mode (A = 0) @@ -186,3 +215,7 @@ ioOpenInclude: cp a ; ensure Z ret +; Return current lineno in HL +ioLineNo: + ld hl, (IO_LINENO) + ret diff --git a/apps/zasm/main.asm b/apps/zasm/main.asm index 34684be..02f2763 100644 --- a/apps/zasm/main.asm +++ b/apps/zasm/main.asm @@ -16,7 +16,8 @@ .equ ZASM_RAMEND ZASM_ORG+2 ; Read file through blockdev ID in H and outputs its upcodes through blockdev -; ID in L. +; ID in L. HL is set to the last lineno to be read. +; Sets Z on success, unset on error. On error, A contains an error code (ERR_*) zasmMain: ; Init I/O ld a, h @@ -38,13 +39,13 @@ zasmMain: ld a, 1 ld (ZASM_FIRST_PASS), a call zasmParseFile - ret nz + jr nz, .end ; Second pass - call ioRewind xor a ld (ZASM_FIRST_PASS), a call zasmParseFile - ret +.end: + jp ioLineNo ; --> HL, returns ; Sets Z according to whether we're in first pass. zasmIsFirstPass: @@ -76,7 +77,7 @@ zasmGetPC: ; IO. Z is set on success, unset on error. DE contains the last line number to ; be read (first line is 1). zasmParseFile: - call ioResetPC + call ioRewind .loop: call parseLine ret nz ; error diff --git a/tools/emul/zasm/zasm.bin b/tools/emul/zasm/zasm.bin index b7b0c7692021f0d4832a881fa776dd4babbb1d58..d0d68a3fb1d70334590891978eb8c52b64c8364a 100644 GIT binary patch delta 2167 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 F{{j-KT6F*b diff --git a/tools/emul/zasm/zasm.c b/tools/emul/zasm/zasm.c index f3bc0fb..10508f0 100644 --- a/tools/emul/zasm/zasm.c +++ b/tools/emul/zasm/zasm.c @@ -190,7 +190,8 @@ int main() fflush(stdout); int res = cpu.R1.br.A; if (res != 0) { - fprintf(stderr, "Error %d\n", res); + int lineno = cpu.R1.wr.HL; + fprintf(stderr, "Error %d on line %d\n", res, lineno); } return res; }