Skip to content

kisom/kam

Repository files navigation

kam: kyle’s arithmetic machine

Nothing to see here, just goofing around with virtual machines.

What is this?

Just a silly dual-stack arithmetic machine.

A compiler? and a VM? for an arithmetic calculator?

Yep. Like I said, just goofing around with some of the concepts.

The virtual machine

The virtual machine has an 8-bit stack for operators, and a 16-bit stack for values. The instructions may be grouped into two segments: control and operators. The control instructions are

STOP
end execution
IMM
push a 16-bit integer onto the stack
DO
pop the top two values from the stack, pop an operator off the operator stack, and apply the operator to the two values. The result is pushed back onto the value stack.

The operators are

  • ADD
  • SUB
  • MUL
  • DIV

These operators all act on 16-bit unsigned integers.

The VM accepts a single binary file on the command line, and will run it. A typical run looks something like

$ ./kamvm compiled/prog1.bin 
Loading 13 byte program.
Starting VM.
> 20
OK

The program size is reported. If the program is loaded successfully, the VM is started, executes the program, and reports the result after the > prompt. If no error occurred, an “OK” is printed, and the VM exits. Typically, if the VM runs into errors, it will dump core with a call to abort(2) to facilitate debugging.

The KAM compiler

The syntax is extremely simple: everything should be enclosed in parenthesis, and normal numbers are used. The simplest program is

(2 + 2)

As a consequence of the way this is implemented, Lisp-style notation is also possible.

  • source/notlispy.sm
((2 * 3) + (10 / 2))
  • source/lispy.sm
(+ (* 2 3) (/ 10 2))

If no source file is given on the command line, the compiler will read source from standard input; the write stage happens when an EOF (for example, C-d) is encountered.

Rudimentary syntax checking is provided through use of a pair of counters, the active values and active operators counters. When a value is encountered, the active value counter is incremented; similarly, when an operator is encountered, the active operators counter is incremented. When a DO is encountered, the compiler will check to ensure that there is at least one active operator and at least two active values present. If there are, compilation continues and both of these counters are decremented. The values counter is decremented only once due to the fact that, after applying the operator to the two values, the VM pushes the result back onto the stack. Despite popping two values, one value is pushed back onto the stack, giving a net loss of only one value. When the compiler reaches EOF in the source file, it warns the user if there are any operators left on the operator stack or if a single value (including no values) are left on the value stack.

At this stage, the compiler is still in a rather primitive state, and illegal programs are likely still permitted.

TODOs

  • Convert the compiler to lex/yacc.

Down the road

Eventually, I’d like to design and build register machines, symbolic machines, and some combination of the two. I’ve got lots of ideas, and limited time for hacking, though.

Motivation

I was watching the Algorithms 1 lectures (from the Coursera class) for this week, and the professor mentioned dual-stack machines. That put a bug in my head that I needed to get out.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published