1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-23 19:28:06 +11:00

zasm: add lineno to error reports

For now, top-level only
This commit is contained in:
Virgil Dupras 2019-05-27 20:52:40 -04:00
parent e414e600ea
commit 8def8e7c38
4 changed files with 47 additions and 12 deletions

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -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;
}