@howerj/subleq

1.0.3 • Public • Published

An N-Bit SUBLEQ Virtual Machine with test images for node-js

This is a virtual machine that implements an 8 to 32 bit SUBLEQ One Instruction Set Computer (OISC). The default cell size is 16-bit. Images can be as large as you like, but be aware the machine cell width restricts how much the OISC can address. It's just for fun.

If you feel like supporting the project you can buy a book from Amazon, available here that describes how the project works and how to port a Forth to a new platform.

Similar projects, same author:

Example

This example program takes a string containing a SUBLEQ program and loads it into the SUBLEQ VM, it then executes it.

	const subleq = require("@howerj/subleq")

	const hello = `12 12 3 36 37 6 37 12 9 37 37 12 0 -1 15 38 36 18
	12 12 21 53 37 24 37 12 27 37 37 30 36 12 -1 37 37 0 39 0 -1 72 101 108
	108 111 44 32 87 111 114 108 100 33 10 53`;

	var cpu = new subleq({
	  putch: function (ch) { process.stdout.write(String.fromCharCode(ch)); },
	});

	cpu.loadFromString(hello, true);

This example runs the default eForth image and allows the user to interactively program in a REPL.

	const subleq = require('@howerj/subleq');

	var cpu = new subleq({
	  putch: function (ch) { process.stdout.write(String.fromCharCode(ch)); },
	  getch: function () {
		let buffer = Buffer.alloc(1)
		if (require("fs").readSync(0, buffer, 0, 1) != 1)
			return -1;
		return buffer.toString('utf8').charCodeAt(0);
	  }
	});

	cpu.load(cpu.eforth());
	cpu.eval(".( EFORTH READY ) cr");
	cpu.run()

All options width sensible default values are shown here:

	const subleq = require('@howerj/subleq');

	var cpu = new subleq({
	  putch: function (ch) { process.stdout.write(String.fromCharCode(ch)); }, // Example putch, writes to stdout
	  getch: function () { // Example getch, reads from stdin
		let buffer = Buffer.alloc(1)
		if (require("fs").readSync(0, buffer, 0, 1) != 1)
			return -1;
		return buffer.toString('utf8').charCodeAt(0);
	  },
	  debug: false, // If true debugging information is logged to the console
	  width: 16, // SUBLEQ machine width, 8-32 bit inclusive
	  timeout_ms: 0, // If non zero setTimeout will be called when cycles run out or input returns an error
	});

API

load(arr, length = 32768, run = false)

Load signed values from an array arr into the memory of the SUBLEQ CPU, enough memory will be allocated to hold all of the values in arr, however your program might require additional memory, which can be optionally specified with the length parameter. Optionally the function can be told to call run() after loading. This function will either return null or the result of run().

loadFromString(str, run = false)

Load from a string instead of an array, most SUBLEQ programs found on the internet consist of ASCII text containing a list of space delimited signed decimal values, this function can split a string containing that format into an array and then load() it. Much like load(), run() can be called if the run parameter is true. The function will return null or the result of run().

eforth()

This function returns an array containing a complete Forth image, which when used in conjunction with load() will run a the programming language, care must be taken to hook up the appropriate putch and getch functions. The eForth image will only work on the 16-bit version of the SUBLEQ VM!

get/set putch

This getter/setter combo allow the setting of the putch function used by the SUBLEQ machine for output. The function should behave like the C function "putchar", the function should accept a single value in the range 0 to 127 which should represent a single ASCII character to be output. You may return negative on failure, but it will not be used by the SUBLEQ VM (output is assumed to succeed).

The default putch callback will swallow characters, doing nothing with them.

get/set getch

This getter/setter combo allow the setting of the getch function used by the SUBLEQ machine for input. The function should behave like the C function "getchar", the function should return a negative integer on failure, and on success should return a number representing the ASCII character value to be input.

The default getch callback will return -1, indicating failure to get input.

run(cycles = 0)

Run the currently loaded program, this will be run for the number of cycles given to the program (or if the cycles is set to zero, which it is by default, it will continue to run until some other halt conditions are met).

The function currently always returns null.

step()

Single step execution of the SUBLEQ machine with the previously loaded program. step() returns the same result as run().

stop()

Prevent the machine from running.

start()

Continue a stop()'ped machine.

reset()

Reset execution so the Virtual Machine as it was when execution started (eg. The program counter is zero).

eval(s, append = "\n")

Evaluate a string, s, that is set the input to the virtual machine to the string and continue run() the VM until the input is consumed by the previously loaded program. append is appended to the input string s. The program might chose to do nothing with the string.

Package Sidebar

Install

npm i @howerj/subleq

Weekly Downloads

5

Version

1.0.3

License

MIT

Unpacked Size

49.1 kB

Total Files

6

Last publish

Collaborators

  • howerj