• Stars
    star
    238
  • Rank 169,306 (Top 4 %)
  • Language
    C
  • License
    BSD 2-Clause "Sim...
  • Created over 7 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A self-hosted Ada-inspired programming language for very small systems.

Cowgol 2.0

What?

Cowgol is an experimental, Ada-inspired language for very small systems (6502, Z80, etc). It's different because it's intended to be self-hosted on these devices: the end goal is to be able to rebuild the entire compiler on an 8-bit micro, although we're not there yet.

Here's the bullet point list of features:

  • a properly type safe, modern language inspired by Ada

  • the compiler is written in itself and is fully bootstrapped

  • a table-driven, easy to port backend (the 80386 backend is 1.2kloc with no other compiler changes needed)

  • tiny: the 80386 Linux compiler binary is 70kB (including ELF overhead) The 8080 CP/M compiler 58kB (split across two executables)

  • fast: on my PC it'll compile itself in 360ms 130ms 80ms.

  • global analysis: dead code removal and static variable allocation, leading to small and efficient binaries

About the compiler

Right now it's in a state where you can build the cross-compiler on a PC, then use it to compile the compiler for your selected device, and if it's small enough to fit use that to compile and run real programs. Realistically you'll be cross-compiling on a PC.

The following targets are supported. Adding more is easy.

  • Z80 and 8080, on CP/M.

  • 6502 and 65c02, on the BBC Micro with Tube second processor.

  • 6303, on the 6303 version of Fuzix (if anyone knows about FLEX and wants to make this work, please get in touch).

  • 6502 interpreted bytecode, on the BBC Micro with Tube second processor; this works just like above, but produces a stack-based bytecode with integrated interpreter. It's much smaller, but also slower.

  • 80386, on Linux.

  • ARM Thumb2, on Linux.

  • PowerPC, on Linux.

  • 68000, on Atari ST TOS (although most of the system calls aren't hooked up yet so you can't do anything more than print stuff) and Linux m68k (if you can still find a machine which will run this).

  • 8086, on DOS (it emits small mode .exe files with 64kB of code and 64kB of data).

  • PDP11, on V7 Unix (thanks to shattered@github for contributing the PDP11 backend for this).

  • Generic and terrible C. This produces very big and slow binaries which are used for bootstrapping the compiler if you don't have a Cowgol compiler.

  • Basic. Yes, really --- there's a backend which will transpile into terrible Microsoft Basic. I wrote this mainly as a joke and only a subset of the language is supported, but it does work.

In addition, there's emulator and assembler support for these platforms, but no compiler:

  • the OBP spaceflight computer (used by, among other things, the OAO-3 Copernicus orbiting observatory)

(It used to support the Apollo Guidance Computer used in the Apollo spacecraft, but I had to remove the code generator while rewriting the compiler and I haven't reworked the AGC backend.)

In terms of machines you can run the compiler on:

  • 80386 and ARM and PowerPC and 68000 Linux, duh.

  • A BBC Micro with Tube second processor. Follow this link for a live in-browser demo courtesy of Matt Godbolt's excellent JSBeeb emulator: press SHIFT+F12 (that's SHIFT+BREAK on a BBC Micro) to start the compiler, and when it's done type OUT to run the result. This is generating full 65c02 machine code.

  • Generic CP/M (both Z80 and 8080).

Many of the other platforms have unfinished system call libraries, so while the compiler tests all pass and the compilers are being built, they won't work if you run them. This should be easy to fix if necessary --- let me know and ask. (I just haven't got round to it yet.) Other platforms have working system call libraries but Cowgol doesn't provide an assembler, so you need to source your own (for example: MS-DOS and Atari ST TOS). So the compiler technically works there; you just can't do anything useful with it.

About the language

Here's a randomly chosen example pulled from the compiler source.

# Free up the node tree rooted in the parameter. This is more exciting than it
# should be because we don't have recursion.
#
# Editorial note: actually this subroutine no longer exists in the compiler
# source code because I replaced it with something simpler and better. No
# matter, the example still stands.
sub Discard(node: [Node]) is
        var pending := node;
        while pending != (0 as [Node]) loop
                node := pending;
                pending := node.dlink;

                # Unlink and push any children.
                if node.left != (0 as [Node]) then
                        node.left.dlink := pending;
                        pending := node.left;
                end if;
                if node.right != (0 as [Node]) then
                        node.right.dlink := pending;
                        pending := node.right;
                end if;

                # Now free this node.
                Free(node as [uint8]);
        end loop;
end sub;

The bullet list set of features is:

  • strongly typed --- no implicit casting (not even between integers of different widths of signedness)

  • records, pointers etc

  • subroutines with multiple input and output arguments

  • arbitrarily nested subroutines, with access to variables defined in an outer subroutine

  • no recursion and limited stack use (most of the platforms I'm targeting don't really support stack frames)

  • byte, word and quad arithmetic for efficient implementation on small systems

  • simple type inference of variables if they're assigned during a declaration

  • seperate compilation with global analysis

There's more about the language in the links below.

Why?

I've always been interested in compilers, and have had various other compiler projects: the Amsterdam Compiler Kit and Cowbel, to name two. (The languages section of my website contains a fair number of entries. The oldest compiler which still exists dates from about 1998.)

Cowgol is based on what I've learnt from all this. It's supposed to be useful, not just a toy. I'm pleasantly surprised by how good the generated code is; not that it's anything up to that of, say, gcc, but the main code generation binary of gcc is 23552kB, and Cowgol's is 65kB...

Where?

How?

We have documentation! Admittedly, not much of it.

Why not?

It's new, it's buggy, it's underdeveloped, and so far only one actual program is written in Cowgol, which is the Cowgol compiler. (And cowlink and cowwrap.)

Apart from actual bugs, there are some unimplemented parts of the language.

  • no null. This one's semantic, but right now you have to cast 0 to pointer types to use null. (I do know about languages which don't have null but they're all for larger machines than Cowgol's aimed at.)

  • no debugging. Well... there's print().

  • no stable standard library. I hack stuff in as I need it.

Your mileage (or kilometreage, depending) may very. You Have Been Warned.

Who?

Cowgol was written mostly by me, David Given, with additional contributions from shattered@github. Feel free to contact me by email at [email protected]. You may also like to visit my website; there may or may not be something interesting there.

License?

Cowgol is open source software available under the 2-clause BSD license. Simplified summary: do what you like with it, just don't claim you wrote it.

The exceptions are the contents of the third_party directory, which were written by other people and are not covered by this license. This directory as a whole contains GPL software, which means that if you redistribute the entire directory, you must conform to the terms of the GPL.

third_party/lib6502 contains a hacked copy of the lib6502 library, which is © 2005 Ian Plumarta and is available under the terms of the MIT license. See third_party/lib6502/COPYING.lib6502 for the full text.

third_party/zmac contains a copy of the venerable zmac 8080 and Z80 assembler. It's in the public domain.

third_party/lemon contains a copy of the lemon parser generator. It's in the public domain.

third_party/apout contains a copy of the apout PDP-11 SysV binary emulator, primarily written by Warren Toomey and Eric A. Edwards. It is distributed under the terms of the MIT license; see third_party/apout/COPYRIGHT for the full text.

third_party/rc2014emu contains a subset of the RC2014 emulator written by Alan Cox. It is distributed under the terms of the GPL 3.0 license; see third_party/rc2014emu/COPYING for the full text.

third_party/emu2 constains a copy of the emu2 DOS emulator written by dmsc@github (and others). It is distributed under the terms of the GPL 2.0 license; see third_party/emu2/LICENSE for the full text.

third_party/djlink contains a copy of the djlink 16-bit linker written by [email protected]. It is distributed under the terms of the GPL 2.0 licesne; see third_party/djlink/copying for the full text, with additional grants described in third_party/djlink/copying.dj.

third_party/musashi contains a copy of the Musashi 68000 emulation library, written by Karl Stenerud. It is distributable under the terms of the MIT license; see third_party/musashi/readme.txt for the full text. It also in turn contains a copy of John R. Hauser's softfloat library, distributable under a custom but MIT-like license; see third_party/musashi/softfloat/README.txt for the text.

More Repositories

1

wordgrinder

A word processor which gets the hell out of your way and lets you get some work done.
Lua
943
star
2

ack

The Amsterdam Compiler Kit
C
420
star
3

fluxengine

PSOC5 floppy disk imaging interface
C++
352
star
4

cpmish

An open source sort-of CP/M 2.2 distribution.
Assembly
346
star
5

cpm65

CP/M for the 6502
Assembly
266
star
6

clue

An experimental C to Javascript/Lua/Perl5/Lisp/Java compiler
C
144
star
7

minix2

Minix 1 and 2, Quick and Dirty editions
C
117
star
8

typetalk

A SmallTalk like live coding system running in the browser, based on TypeScript.
TypeScript
65
star
9

luje

a Java virtual machine written in pure Lua
Java
61
star
10

fforth

A small, portable Forth written in Posix C
C
44
star
11

LBW

Experimental tool for running Linux binaries on Windows
C++
39
star
12

telinkdebugger

A Raspberry Pi Pico-based debugger bridge for the Telink SWS debug protocol.
C++
22
star
13

pcemu

A software 8086 PC emulator.
PostScript
19
star
14

polf

A toy
Assembly
17
star
15

piface

Bare metal boot loader for the Raspberry Pi's VideoCore processor (no ARM!)
C
12
star
16

narcissus

A chording keyboard tool for X
C
11
star
17

cowjac

An experimental Java bytecode to C++ transpiler
Java
10
star
18

jpegfinder

A simple tool for scraping jpeg frames from files. Suitable for recovering corrupted MJPEG files. I'm looking at you, Hubsan.
C
10
star
19

glueesp

A port of the Geoworks Glue DOS linker.
C
10
star
20

ibm6770keyboard

A USB interface for the IBM 6770/6780 keyboard.
C++
9
star
21

cowbel

An experimental programming language
xBase
8
star
22

btracker

A chiptracker editor and player for the BBC Micro.
Assembly
8
star
23

calculon

A very small, fast shader language using LLVM.
C++
8
star
24

bogomandel

A silly toy Mandelbrot program for the BBC Micro.
Assembly
7
star
25

dso152-breakout

Breakout for the Fnirsi DSO152
C++
7
star
26

plmc

A compiler for PL/M targeting LLVM bitcode.
Yacc
6
star
27

dbztool

A command line tool for accessing the bootstrap protocol on Dragonball CPUs.
C++
5
star
28

gcc-vc4

An experimental port of gcc 4.8.1 to the VideoCore IV.
C
5
star
29

gruntle

A text-based CYO MMORPG engine
HTML
4
star
30

cshell

A very simple command line shell for the Commodore 64.
Assembly
4
star
31

qemu-z80

Z80 support for qemu
C
4
star
32

bterm

Firmware/hardware to use a Brother WP-1 word processor as a serial terminal
Assembly
4
star
33

vtech6502

A collection of data about the internals of various VTech 6502-based toys.
4
star
34

cparser

C
4
star
35

maxii-keyboard

PSoC5 firmware to for an ancient MAX-II industrial keyboard
C
4
star
36

libfirm

C
3
star
37

spey

A spam-filtering SMTP proxy using greylisting
Shell
3
star
38

comal65

A Comal interpreter for the 6502
Assembly
3
star
39

stellation

A web based real time space warfare RTS.
Shell
2
star
40

vimutti

Tool for decrypting Buddha Machine flash images.
C
2
star
41

pblq

Amstrad eMailer PBL boot loader client
Shell
2
star
42

objective-lua

A dialect of Lua extended with syntax borrowed from Objective C to add object orientation support.
Lua
1
star
43

ebooksyncer

A tiny tool for syncing (and decrypting) eink Kindle books from the device to a directory for backup.
1
star
44

flooded-moon

The moon, like you've never seen it before.
POV-Ray SDL
1
star
45

uboot-pw1

Customised uboot for Kindle Paperwhite gen 1 devices.
C
1
star
46

bmdkey

Python
1
star
47

sdcc

Patched sdcc for Fuzix
C
1
star
48

fluxengine-testdata

Test data for the FluxEngine project.
1
star
49

ab

Yet Another Build Generator
Python
1
star
50

fgit

Tools for using Fossil as a git client.
Shell
1
star