Skip to content
/ CTBASIC Public

Cyclic Tag System BASIC (like) compiler toy project with Tektronix 401x graphical output.

Notifications You must be signed in to change notification settings

hornc/CTBASIC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CT-BASIC

CTBASIC is a compiled Sinclair BASIC inspired language targeting a "fantasy console" architecture using the cyclic tag system computational model.

It compiles a reduced dialect of BASIC into one of the following compilation targets:

This is an experimental project / work in progress. Details and usability are being worked out as features are added.

The idea is to capture something of the early days of practical programming (i.e. the BASIC era) while using low level cyclic tag systems for 'useful' programs.

The Fantasy Console

CTBASIC compiles to standard versions of the above cyclic-tag families, so any compiled program will run on all of them. However, in order to provide some user feedback, the CTBASIC architecture assumes a particular set of output conventions which distinguish a CTBASIC 'machine' from a plain cyclic-tag interpreter.

These differences only apply to I/O. The output conventions are side-effects and do not affect the underlying computation. Input conventions only affect starting (and re-starting) states, so also don't affect the fundamental computational process.

The CTBASIC machine I/O conventions are as follows:

  1. Byte strings can be encoded and recognised within the data-string:

    • 8 bit bytes are encoded within a 10 bit data-frame with start-bit 1 and end-bit 0.
    • A string is a series of 10-bit frames beginning with the ASCII C0 STX character (0x02), and terminated by the ETX character (0x03).
    • When a valid string is completed, (i.e. the stop-bit 0 of the ETX is appended to the right of the data-string) the complete string is sent to output.
  2. Output is a serial byte-stream, with flexible destinations.

    • The CTBASIC language has drawing commands which when compiled produce serial byte output that can be recognised by Tektronix 4010/4 compatible terminals.
    • Non-graphical serial terminals are also intended to be supported for character output.
    • Other byte-based output targets are also a possibility (e.g. audio, serial input to other devices).
  3. Interactive mode:

    • An optional execution mode whereby when the data-string becomes empty (the standard halt condition) the user is prompted for more input to replenish the data-string. Previous program output could perhaps give the user some guidance on how to binary-encode an appropriate input response.
    • If a new data-string input is provided, the program resumes with the next cyclic production.
    • If no new input is provided, the program halts.

General cyclic-tag input considerations

A standard feature of Cyclic Tag family of languages is that they require a non-empty, non-zero, data string to begin (and continue) execution.

If the initial data string is empty, or does not contain any 1 symbols, a program cannot possibly modify the data string, so no computation will occur.

This means that for any CT family program to perform a computation, an appropriate input data string MUST be provided. At minimum, this input data string can be a single 1. From this, a program can bootstrap any required data structure to allow it to accomplish its computation.

Specific user supplied variable input will need to be encoded in some fashion into the initial data string, the instructions for which will depend on the specific program being run. In general, there will need to be at least one 1 symbol for the program to have a chance of recognising the full range of user supplied inputs, including 'blank' input. Providing an input data-string beginning with a 0 symbol will in general prevent a program from functioning correctly (unless the expected behaviour is "do nothing").

The CTBASIC language

CTBASIC effectively provides ZX Spectrum BASIC style output macros to simplify forming output using the provided conventions.

  • PRINT, CHR$, CLS, PLOT, DRAW, and INK for output.
  • BIN, DATA, FILL, ZFILL, ASM for internal data.

All control flow is provided by the underlying cyclic tag mechanism.

Every command (output or memory writing) is conditional on there being a 1 at the leftmost bit of the current data-string.

All CLEAR commands (removing 1 or more bits from the data-string) are unconditional.

The entire program runs in an implicit loop until the data-string is empty.

The END command does not immediately end the program, but is an alias for CLEAR 10, which clears the data-string frame by frame, which if all data is correctly aligned on 0 stop-bits, can allow the program to cycle as many times as needed to clear the entire data-string without triggering any further output or effects. This however requires careful planning, and is not guaranteed to occur cleanly otherwise. It is a fragile convention.

Commands

See the Command list for implemented and aspirational commands and syntax.

See examples/ for how the commands can be used together.

Cyclic Tag Interpreter

CTBASIC comes with a simple Cyclic Tag interpreter to test CTBASIC programs behave as intended when compiled to the default Cyclic Tag dialect. It supports the input and output conventions, and will execute CTBASIC examples as intended (assuming correct mode flags and terminals are used).

Example usage

  • Compile Hello, World! example to cyclic tag:

    ./CTBASIC.py examples/HELLOWORLD.BAS
    
    • output: 1000000100101001000010110010101011011000101101100010110111101001011000100100000010101011101011011110101110010010110110001011001000100100001010000101001000000110;;;;;;;;;;
  • Use the included cyclic tag interpreter ct.py to run the above and display output (input data = 1):

    ./ct.py <(./CTBASIC.py examples/HELLOWORLD.BAS) 1
    
    • output: Hello, World!
  • Compile to arithmetic cyclic tag:

    ./CTBASIC.py -tABCT examples/HELLOWORLD.BAS
    
    • output: 2188296472577726911166636231243756842502740360147865646454687653848030097758545005123757741056578902
  • Compile to rule 110 'blocks':

    ./CTBASIC.py -t110 examples/HELLOWORLD.BAS
    
  • Compile and run a simple loop demonstration:

    ./ct.py <(./CTBASIC.py examples/LOOP10.BAS)
    
  • Compile and run a standard terminal character 'animation' example:

    ./ct.py --hold 300 <(./CTBASIC.py examples/ANIM_FRAME_TEST.BAS)
    
  • Compile and run a (unary) input example:

    ./ct.py <(./CTBASIC.py examples/1_TO_10_OUTPUT.BAS) 11111111
    
    • Vary the number of 1s as input between 1 and 1111111111 (10).
  • Using xterm, compile and run a static graphics example: 2D Utah teapot:

    xterm -hold -t -e "./ct.py <(./CTBASIC.py examples/teapot.bas  ) 1"
    
    • 2D Utah teapot output
  • Use xterm to display an animated rotating cube:

    xterm -hold -t -e "./ct.py --hold 100  <(./CTBASIC.py examples/CUBE.BAS)"
    
    • Rotating cube output
  • Use interactive mode to play a simple (cheating) coin flip game:

    ./ct.py --interactive <(./CTBASIC.py examples/coin_flip.bas) 1
    
  • Compile the {YN, NYYN, 0, 0} example from Matthew Cook, 2009, A Concrete View of Rule 110 Computation 10.4204/eptcs.1.4, p.37:

    ./CTBASIC.py -t110 examples/Cook_1_4_example.bas
    
    • output:
(
  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAABAAAAAAAAAAABAAAAAAAAAAAAB',
  'CFG',
  'HIIJKHJIIIIIJLLLLK'
)
  • Run the above example as cyclic tag in debug mode to view the current production and data-strings at each step:

    ./ct.py <(./CTBASIC.py -tCT examples/Cook_1_4_example.bas) --debug
    
    • output:
10;0110;;;;;	1
0;0110;;;;;1	11
;0110;;;;;10	110
0110;;;;;10;	10
110;;;;;10;0	100
10;;;;;10;01	1001
0;;;;;10;011	10011
;;;;;10;0110	100110
;;;;10;0110;	00110
;;;10;0110;;	0110
;;10;0110;;;	110
;10;0110;;;;	10
10;0110;;;;;	0
10;0110;;;;;	0
0;0110;;;;;1	0
;0110;;;;;10	0

About

Cyclic Tag System BASIC (like) compiler toy project with Tektronix 401x graphical output.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages