[Index] [Previous] [Next]

1.17 Expression Evaluation

EvalExpression

Evaluates an expression, returning with the result in FACCUM. An expression is a combination of terms and operators.

068A 2B EvalExpression DCX H
068B 1600 MVI D,00
068D D5 PUSH D
Check we've got enough space for one floating-point number.
068E 0E01 MVI C,01
0690 CDB601 CALL CheckEnoughVarSpace
Evaluate term and store prog ptr in 015f
0693 CDC406 CALL EvalTerm
0696 225F01 SHLD 015F
0699 2A5F01 ArithParse LHLD 015F
069C C1 POP B
Get byte following sub-expression. This is where we deal with arithmetic operators. If the byte is less than KWID_+ then return.
069D 7E MOV A,M
069E 1600 MVI D,00
06A0 D698 SUI KWID_+
06A2 D8 RC
Return if A>=4, ie not an arithmetic operator, then convert A to an offset into the KW_ARITH_OP_FNS table
06A3 FE04 CPI 04
06A5 D0 RNC
06A6 5F MOV E,A
06A7 07 RLC
06A8 83 ADD E
06A9 5F MOV E,A
06AA 214B00 LXI H,KW_ARITH_OP_FNS
06AD 19 DAD D
Get first byte of table entry. This is the operator precedence indicator byte. Not entirely sure how this works yet, but it seems we basically return if we don't need to evaluate this bit yet.
06AE 78 MOV A,B
06AF 56 MOV D,M
06B0 BA CMP D
06B1 D0 RNC
06B2 23 INX H
Push counter and address of ArithParse onto the stack (the latter so we return to it after the arith fn runs)
06B3 C5 PUSH B
06B4 019906 LXI B,ArithParse
06B7 C5 PUSH B
Push FACCUM, taking care to preserve the operator precedence byte in D.
06B8 4A MOV C,D ???
06B9 CD020A CALL FPush
06BC 51 MOV D,C
Push address of arithmetic fn and jump back to
06BD F7 RST PushNextWord()
06BE 2A5F01 LHLD 015F
06C1 C38D06 JMP 068D

 

EvalTerm

Evaluates a term in an expression. This can be a numeric constant, a variable, an inline function call taking a full expression as an argument, or a bracketed expression.

Get first character of term, and if it's a digit (as indicated by the carry flag) then jump to FIn
06C4 D7 EvalTerm RST NextChar
06C5 DAB30A JC FIn
If the character is alphabetic then we have a variable, so jump ahead to get it.
06C8 CD8004 CALL CharIsAlpha
06CB D2F306 JNC EvalVarTerm
If the character is a leading '+' then simply ignore it and jump back to EvalTerm.
06CE FE98 CPI KWID_+
06D0 CAC406 JZ EvalTerm
If the character is a leading '.' then that's a decimal point, so jump to FIn
06D3 FE2E CPI '.'
06D5 CAB30A JZ FIn
If the character is a leading '-' then jump head to EvalMinusTerm
06D8 FE99 CPI KWID_-
06DA CAEA06 JZ EvalMinusTerm
If the character is the keyword ID of an inline function them jump ahead to deal with that.
06DD D69F SUI 9F
06DF D2FD06 JNC EvalInlineFn
The only possibility left is a bracketed expression. Here we check for an opening bracket, recurse into EvalExpression, and return.
06E2 CF EvalBracketed RST SyntaxCheck
06E3 28 '('
06E4 CD8A06 CALL EvalExpression
06E7 CF RST SyntaxCheck
06E8 29 ')'
06E9 C9 RET
Evaluate a negative term. This is done by simply recursing this block and negating the result.
06EA CDC406 EvalMinusTerm CALL EvalTerm
06ED E5 PUSH H
06EE CDFA09 CALL FNegate
06F1 E1 POP H
06F2 C9 RET
Evaluate a variable. The call to GetVar returns the address of the variable's value in DE, which is then moved to HL then the call to FLoadFromMem loads FACCUM with the variable's value.
06F3 CD1B07 EvalVarTerm CALL GetVar
06F6 E5 PUSH H
06F7 EB XCHG
06F8 CD0F0A CALL FLoadFromMem
06FB E1 POP H
06FC C9 RET
Evaluate an inline function. First we get the offset into the KW_INLINE_FNS table into BC and stick it on the stack.
06FD 0600 EvalInlineFn MVI B,00
06FF 07 RLC
0700 4F MOV C,A
0701 C5 PUSH B
Evaluate function argument
0702 D7 RST NextChar
0703 CDE206 CALL EvalBracketed
Preserve prog ptr on stack and simultaneously get offset into KW_INLINE_FNS into HL
0706 E3 XTHL
Set return address to somewhere that just POP H and RETs.
0707 11F106 LXI D,06F1
070A D5 PUSH D
Get function address by adding the offset in HL to KW_INLINE_FNS
070B 013D00 LXI B,KW_INLINE_FNS
070E 09 DAD B
Put function address on stack and return to it.
070F F7 RST PushNextWord
0710 C9 RET

 


[Index] [Previous] [Next]