Coder Social home page Coder Social logo

lunaamora / 4orth Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 0.0 239 KB

4orth is a Porth compiler with WASM, WASI and WASM-4 targets

Home Page: https://lunaamora.github.io/4orth/

License: MIT License

Makefile 100.00%
porth wasm-4 wasm compiler fantasy-console webassembly wasi

4orth's Introduction

GitHub Workflow Status GitHub release (latest by date including pre-releases) GitHub all releases GitHub

4orth

4orth is a Porth compiler with WASM, WASI and WASM-4 targets.

Most of the code in this repository was written by Tsoding and other contributors to the original Porth compiler. 4orth was created as an alternative compiler for WASM, and reuses a lot of its codebase.

Quick Start

You can download the latest release or bootstrap it yourself.

Bootstrapping

Since Porth is self-hosted you will need to bootstrap it first. Follow Porth bootstrapping instructions on how to do that. (4orth includes the original porth compiler with the -porth option, so you can use the 4orth executable instead to bootstrap/update itself)

Secondly you will need to install:

$ ./porth/porth com 4orth.porth
              <or>
$ ./4orth -porth com 4orth.porth 

Then, you are ready to compile and run your Porth programs using the runtime of your choice:

Compilation

Compilation generates WAT and converts it to a WebAssembly Binary Format .wasm file with WABT. So make sure you have it available in your $PATH.

$ ./4orth com main.porth
$ w4 run main.wasm
        <or>
$ ./4orth com -wasm main.porth
$ wasmtime main.wasm

With Wasm-4, you can use the subcommands -b and -r to bundle and run after the compilation. (As porth only supports Linux, -b creates a Linux executable. For other options, check w4 bundle --help or Wasm-4 distribution docs)

./4orth com -b -r main.porth

Tip: Add _4ORTH environment variable to automatically have the std libraries available in 4orth include path.

Running options and subcommands

$ ./4orth [OPTIONS] <SUBCOMMAND>

OPTIONS:
    -porth               Use the original porth compiler and CLI instead of 4orth
    -unsafe              Disable type checking
    -I <path>            Add <path> to the include paths list
SUBCOMMANDS:
    com [OPTIONS] <file> Compile the program
        -r               Run the program after successful compilation
        -b               Bundles the program to a linux executable. (If with -r, executes the bundle)
        -opt             Optimize the program with wasm-opt
        -wat             Transforms the stripped program back from the final `.wasm` to `.wat`
        -wasm            Target WASM instead of Wasm-4 (doesn't support -b or -r)
        -s               Silent mode. Don't print any info about compilation phases
        -o  <file>       File to write the result to
    help                 Print this help to stdout and exit with 0 code

Status

4orth currently only supports 32 bit integers.

Changes

4orth implements some temporary features not available in Porth to facilitate Wasm integration:

  • Hexadecimal numbers (as 0x format on numbers, and as \\ plus 2 digits on strings)
  • Null terminated string support in const evaluation (evaluates to a pointer to the string)

Importing and exporting procs

4orth introduces two new keywords allowing Porth to interact with the WASM module system:

  • Import
import proc trace ptr in end

This adds the ability to call the Wasm-4 trace function via the defined proc contract. Imported procs must have an empty body. (Porth's print intrinsic calls this imported proc, you can use either of them to log to the console)

  • Export
export main "start"
export update "update"

This exports the desired procs to be called by Wasm-4 or other Wasm runtimes.

Inline WASM code

4orth allows you to inline WASM code into your program by using the wasm keyword. Any string inside the code block will be inlined in the compiled program.

wasm 
  "\n;; Inlined global rng seed for a Pseudo random number generator."
  "(global $random-state (mut i32) (i32.const 69420))" 
end

When inside a procedure, inline WASM blocks have to define a contract to be used in type checking.

inline proc xor int int -- int in
  wasm int int -- int in
    " call $pop"
    " call $pop"
    " i32.xor"
    " call $push"
  end
end

This implements a xor procedure utilizing the WASM i32.xor instruction. (This proc is available at wasm-core.porth)

Importing modules (for raw WASM and WASI)

The default module imported by 4orth is dev. You can include other modules in your program by using the import keyword followed by module and the module name.

import module "my_module"

This line changes the current module context to my_module. Every imported proc defined after this line will use this context until a new module is imported.

Others

All available functions, constants and the memory map from Wasm-4 are in the wasm4.porth library.

The wasi.porth library contains a minimal WASI setup and a imported proc that prints to stdout.

Huge thanks to Tsoding for all the educational content and for (being in the process of) creating such a fun language to experiment with.
And Thanks Aduros for the fantastic fantasy console Wasm-4.

The two projects just seemed so compatible to me that I had to try a way to play with both at the same time!

4orth's People

Contributors

lunaamora avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

4orth's Issues

Cannot manually import procedures with inline WAT

Context

I am currently building a WASM layer for p5.js and, just for fun, I wanted to add Porth support. However, I am running into an issue with importing one of my functions. Since print is a Porth intrinsic, I could not import a procedure with the same name. So I resorted to this:

wasm
  "(import \"env\" \"print\" (func $print (param i32)))"
end
// -- 88 lines of "import proc <name> <signature> in end"
inline proc print-i32 int -- in
  wasm int -- in
    "(call $pop)"
    "(call $print)"
  end
end

However, I get an error from wasm2wat:

web/examples/colors.wat:127:2: error: imports must occur before all non-import definitions
(import "env" "print" (func $print (param i32))) ;; OP_INJECT_CODE 0
 ^^^^^^

I tried putting the (import "env" ...) before include "wasm-core.porth" and it still gives the same error (just different line numbers). Is there anything I can do or do I have to not include this procedure for now until you (maybe) fix it? (I already had to omit quite a few functions because of floats)

Implement the return stack

Local memories in the current version are implemented as a hack, using wasm locals instead of a return stack. This causes problems when using the pointer to a local mem to do things other than direct read or write.

A proper return stack must be implemented to fix this issue and lay the ground work to #1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.