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