S2 calculator engine in S2 assembly language


The engine now is working.  You can see all the details in the source.  It includes the main program (S2 simulator) in C and the shell which call the "interpreter" in S2 assembly language to run the calculator.  The package is s2cal.zip

The main function to run the calculator in C is "mainCal()" (in s2c.c) which is a simple execution loop. The interpreter file (in S2 assembly language) is "s2cal.txt".  You can inspect how I write the calculator engine.  

The first part of eval() tests the token (the main loop is already read one token and put it into r1) and jumps to the corresponding routines.  The first line "push r31 r29" saves the link register to the system stack in order to allow recursive call of eval(). Eval() calls evalnext() and evaln() which will call eval() itself.  Before return, eval() must pop the link register.  Two trap functions are introduced:
Here is the eval function of the calculator:

;; register convention
;; r31  stack pointer  (system)
;; r30  display
;; r29  link register
;; r28  return value
;; r27  evaluation stack (calculator)

:eval               ;; assume one token in r1
  push r31 r29      << -- save link register
  eq r2 r1 #tkNum
  jt r2 xNum
  eq r2 r1 #tkAdd
  jt r2 xAdd        << -- jump to action routine
  eq r2 r1 #tkSub
  jt r2 xSub
  eq r2 r1 #tkMul
  jt r2 xMul
  eq r2 r1 #tkDiv
  jt r2 xDiv
  eq r2 r1 #tkF0
  jt r2 xF0
  ...
:return
  pop r31 r29       << -- restore link register
  ret r29

The routine to handle each operator (such as add) will evaluate the next token by calling read() (trap 3) and eval it, then applies the operator. Here is the example of "add". Add is an infix operator, the calculator has already reads one argument and its value has already been on the evaluation stack (pointed by r27).  The action of xAdd is to read and evaluate next token and do "add".  The evalnxt() does the read and evaluate the next token.  The call to fAdd "jal r29 fAdd" calls the routine to perform the "add" operation.  
:xAdd               ;; get another arg then add
  jal r29 evalnxt
  jal r29 fAdd
  push r27 r28      ;; push result
  jmp return

:evalnxt        ;; read and eval next token
  push r31 r29
  trap 3           << -- read a token, return value in r28
  mv r1 r28        << -- put token to r1
  jal r29 eval     << -- recursive call to eval()
  pop r31 r29
  ret r29

:fAdd
  push r31 r1
  push r31 r2
  pop r27 r2
  pop r27 r1
  add r28 r1 r2
  pop r31 r2
  pop r31 r1
  ret r29

"fAdd" is written according to the rule of writing a module for the calculator:
1)  It does not use any global variable.
2)  It uses only the registers.
3)  It saves and restores all registers it used.
4)  The operator takes arguments from the evaluation stack (pointed by r27).
5)  It returns the result in r28.

The calculator itself takes care of scanning the input line, providing the arguments to the operator (in the evaluation stack), and pushing the result to the evaluation stack (so that the next operations can continue correctly).  The "calculation" (or user-defined) routine performs the operation.

The dynamic load the special function object (f0.obj, f1.obj ...) is now working (10 Feb 2007).  One example is included in the S2 calculator package (f1.obj).  It is implemented as an identitfy function.  It just returns its argument.

How to run the calculator

Try the following:

c:>cal
>33 + 22 - 1 =
54
>ld f1.obj
>f1 10 =

10
>20 + f1 11 =
31
>

The basic four functions (+ - * /) are working. Here is how the function f1 for demonstration is written:

;;  f1.txt -> f1.obj


.code 1000
:f1             ;; identity function
  pop r27 r28   ;; move from eval stack to r27
  ret r29
.end

Please note

You don't have to understand how the calculator work in order to submit your project.  You can write your special function without knowing the detail of the calculator. You just follow the "protocol" (or the rule) that I describe in the document (How to write assembly language for special functions, in the webpage "project2"). I explain all these details for educational purpose.

last update 10 Feb 2007