;;; -*- TI-Asm -*-
;;;
;;; Mimas - Assembly language IDE for the TI-83 Plus
;;;
;;; Copyright (C) 2010 Benjamin Moody
;;;
;;; This program is free software: you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see .
;; FormatExpr:
;;
;; Convert an expression into an ASCII string. Note that if the
;; expression is too complicated to fit in the buffer, it will
;; generally be silently truncated.
;;
;; Input:
;; - IX = expression pointer
;; - C = expression byte count + 1
;; - B = level of parenthesization for binary operators (0 = never;
;; FFh = always)
;; - formatTemplate, (iy + asm_Flag3) = 1 to allow X_ARGVAL
;; expressions to refer to template arguments
;;
;; Output:
;; - String inserted into the editTextBuffer at the current cursor
;; position
;; - IX and C updated
;; - Carry flag set if expression incomplete
;;
;; Destroys:
;; - AF, B, DE, HL
;; - OP1-OP6
FormatExprDefault:
ld b,0
FormatExpr:
dec c
scf
ret z
ld a,(ix)
inc ix
ld h,a
add a,a
jq c,FormatExpr_Dec6OrOperator
;; 0xxxxxxx
add a,a
jr c,FormatExpr_Constant
;; 00xxxxxx xxxxxxxx: symbol value
dec c
scf
ret z
ld l,(ix)
inc ix
call GetProgramSymbolInfo
call c,Error_Bytecode
call ProgramOffsetToAddress
FormatExpr_Symbol:
push bc
ld de,OP1
push de
call SymbolStringToRAM
ld e,b
ld d,0
;; check if symbol will fit in buffer -- assuming worst case
;; of 50% compression
ld hl,(editCursor)
push hl
add hl,de
add hl,de
ld de,(editTail)
sbc hl,de
pop de
pop hl
jr nc,FormatExpr_Invalid
call UnpackSymbolString
pop bc
ld (editCursor),de
or a
ret
FormatExpr_Invalid:
pop bc
ld hl,3F3Fh
jq_ FormatExpr_TwoChars
FormatExpr_Constant:
;; 01xxxxxx
add a,a
jq c,FormatExpr_WordConstant
;; 010xxxxx
add a,a
jr c,FormatExpr_ByteConstant
;; 0100xxxx: special constant
ld hl,5043h
jr z,FormatExpr_TwoChars
ld hl,LPCStr
cp low(X_LOADPC * 16)
jq z,TextBufInsertString
ld hl,5B42h
cp low(X_PREV_ANON * 16)
jr z,FormatExpr_TwoChars
cp low(X_NEXT_ANON * 16)
call nz,Error_Bytecode
ld l,46h
FormatExpr_TwoChars:
ld a,h
call TextBufInsertChar
ld a,l
jq_ TextBufInsertChar
FormatExpr_ByteConstant:
;; 0101xxxx xxxxxxxx: byte constant
dec c
scf
ret z
ld l,(ix)
inc ix
ld a,h
cp X_ENUM8
jr nc,FormatExpr_Enum8
ld h,0
and 0Fh ; X_DEC8
jr z,FormatExpr_Dec
dec a ; X_HEX8
jr z,FormatExpr_Hex8
dec a ; X_OCT8
jr z,FormatExpr_Oct8
dec a ; X_BIN8
jr z,FormatExpr_Bin8
dec a ; X_CHAR
jr z,FormatExpr_Char
jr FormatExpr_Hex8
FormatExpr_Enum8:
push bc
call EnumValueToName
pop bc
jq z,TextBufInsertSymbolString
FormatExpr_Hex8:
TextBufInsertPrefixedHex8:
ld a,'$'
call TextBufInsertChar
FormatExpr_Hex8_L:
ld a,l
jq_ TextBufInsertHex8
FormatExpr_Dec_Recurse:
ld a,h
or l
ret z
FormatExpr_Dec:
BCALL _DivHLBy10
push af
call FormatExpr_Dec_Recurse
pop af
add a,'0'
FormatExpr_SingleChar:
jq_ TextBufInsertChar
FormatExpr_Oct8:
ld a,'@'
call TextBufInsertChar
push bc
ld h,l
srl h
rr l
ld b,3
FormatExpr_Oct_Loop:
ld a,'0' / 8
add hl,hl
rla
add hl,hl
rla
add hl,hl
rla
call TextBufInsertChar
djnz FormatExpr_Oct_Loop
pop bc
ret
FormatExpr_Bin8:
ld a,'%'
call TextBufInsertChar
FormatExpr_Bin8_L:
ld a,l
jq_ TextBufInsertBin8
FormatExpr_Char:
ld a,Lapostrophe
call TextBufInsertChar
ld a,l
call TextBufInsertQuotedChar
ld a,Lapostrophe
jr FormatExpr_SingleChar
FormatExpr_Dec6:
ld a,h
and 3Fh
ld l,a
ld h,0
jr FormatExpr_Dec
FormatExpr_WordConstant:
add a,a
call c,Error_Bytecode
;; 0110xxxx xxxxxxxx xxxxxxxx: word constant
dec c
scf
ret z
dec c
ret z
ld a,h
ld l,(ix)
inc ix
ld h,(ix)
inc ix
and 0Fh ; X_DEC16
jr z,FormatExpr_Dec
dec a ; X_HEX16
jr z,FormatExpr_Hex16
dec a ; X_OCT16
jr z,FormatExpr_Oct16
dec a ; X_BIN16
jr z,FormatExpr_Bin16
dec a ; X_ROMCALL
jr z,FormatExpr_ROMCall
dec a ; X_SYSADDR
jr nz,FormatExpr_Hex16
push bc
call SysAddressToName
pop bc
jq z,TextBufInsertSymbolString
FormatExpr_Hex16:
ld a,'$'
call TextBufInsertChar
TextBufInsertHex16:
ld a,h
call TextBufInsertHex8
jq_ FormatExpr_Hex8_L
FormatExpr_Oct16:
ld a,'@'
call TextBufInsertChar
ld a,'0' / 2
add hl,hl
rla
call TextBufInsertChar
push bc
ld b,5
jr FormatExpr_Oct_Loop
FormatExpr_Bin16:
ld a,'%'
call TextBufInsertChar
ld a,h
call TextBufInsertBin8
jr FormatExpr_Bin8_L
FormatExpr_ROMCall:
push bc
call ROMCallAddressToName
pop bc
jr nz,FormatExpr_Hex16
ld a,'_'
call TextBufInsertChar
jq_ TextBufInsertSymbolString
FormatExpr_Dec6OrOperator:
;; 1xxxxxxx
add a,a
jr c,FormatExpr_Dec6
;; 10xxxxxx
add a,a
jq c,FormatExpr_Binary
;; 100xxxxx
add a,a
call nc,Error_Bytecode
;; 1001xxxx : unary operator
ld a,h
and 0Fh
ld h,'l'
jr z,FormatExpr_UnaryLSBMSB
dec a
ld h,'m'
jr z,FormatExpr_UnaryLSBMSB
dec a
ld h,Lneg
jq z,FormatExpr_UnaryOpChar
dec a
ld h,'~'
jr z,FormatExpr_UnaryOpChar
dec a
ld h,'!'
jr z,FormatExpr_UnaryOpChar
dec a
jr z,FormatExpr_UnaryParen
dec a
jr z,FormatExpr_UnaryRegValue
dec a
call nz,Error_Bytecode
bit formatTemplate,(iy + asm_Flag3)
call z,Error_Bytecode
;; template argument
dec c
scf
ret z
ld a,(ix)
inc ix
cp X_DEC6
call c,Error_Bytecode
and 3
add a,a
add a,low(formatArgPtr0)
ld l,a
ld h,high(formatArgPtr0)
; call LdHLInd
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
res formatTemplate,(iy + asm_Flag3)
push ix
push bc
call StackCheck
push hl
pop ix
ld c,64
call FormatExpr
pop bc
pop ix
set formatTemplate,(iy + asm_Flag3)
or a
ret
FormatExpr_UnaryOpChar:
ld a,h
call TextBufInsertChar
ld b,0FFh
jq_ FormatExpr
FormatExpr_UnaryLSBMSB:
ld a,h
call TextBufInsertChar
ld hl,7362h
call FormatExpr_TwoChars
ld b,-1
FormatExpr_UnaryParen:
ld a,'('
call TextBufInsertChar
ld b,0
FormatExpr_OperatorArgAndParen:
call StackCheck
call FormatExpr
ret c
ld a,')'
jq_ TextBufInsertChar
FormatExpr_UnaryRegValue:
;; register #
dec c
scf
ret z
ld a,(ix)
inc ix
cp X_DEC6
jr nc,FormatExpr_RegNameLiteral
cp X_ARGVAL
call nz,Error_Bytecode
;; FIXME: clean this up to make it more general; perhaps fix
;; EvalExpr so it can be used at all times, not just while
;; assembling. Also note this partly duplicates code above
;; (..._TemplateSubst)
bit formatTemplate,(iy + asm_Flag3)
call z,Error_Bytecode
dec c
scf
ret z
ld a,(ix)
inc ix
cp 0C0h
call c,Error_Bytecode
and 3
add a,a
add a,low(formatArgPtr0)
ld l,a
ld h,high(formatArgPtr0)
; call LdHLInd
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ld a,(hl)
cp X_DEC6
call c,Error_Bytecode
FormatExpr_RegNameLiteral:
push bc
ld hl,regNameStrings
ld bc,regNameStringsSize
cpir
pop bc
call nz,Error_Bytecode
jq_ TextBufInsertString
FormatExpr_Binary:
;; 101xxxxx : binary operator
ld a,h
add a,a
add a,low(binaryOperatorParenTable - 2 * X_BINARY)
ld e,a
ld d,high(binaryOperatorParenTable)
ld a,(de)
ld l,a ; L = this operator's paren class
and b
jr z,FormatExpr_Binary_NoParen
ld a,'('
call TextBufInsertChar
or a
FormatExpr_Binary_NoParen:
;; zero flag clear if this operator is using parentheses
push af
inc de
ld a,(de)
ld b,a ; B = paren mask for left child
or l
ld l,a ; L = paren mask for right child
push hl
call StackCheck
call FormatExpr
pop hl
jr c,FormatExpr_Binary_Error
ld a,h
cp X_OR + 1
call nc,Error_Bytecode
cp X_LSHIFT
ld d,'<'
jr z,FormatExpr_BinaryShift
cp X_RSHIFT
ld d,'>'
jr z,FormatExpr_BinaryShift
add a,low(binaryOperatorCharTable - X_BINARY)
ld e,a
ld d,high(binaryOperatorCharTable)
ld a,(de)
jr FormatExpr_BinaryFinish
FormatExpr_BinaryShift:
ld a,d
call TextBufInsertChar
FormatExpr_BinaryFinish:
call TextBufInsertChar
ld b,l
pop af
jq z,FormatExpr
jq_ FormatExpr_OperatorArgAndParen
FormatExpr_Binary_Error:
pop af
scf
ret