Skip to content
This repository has been archived by the owner on Jul 28, 2022. It is now read-only.

Latest commit

 

History

History

c

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

MiniForth

MiniForth is a typeless concatenative language, which can be compiled into bitcoin opcodes.

Build from source

  1. have erlang and elixir installed in your machine, recommend using asdf to install
  2. Clone this repo, cd into the directory.
  3. cd c
  4. mix deps.get
  5. MIX_ENV=prod mix escript.build

How to use

Create a new file hello.fth , and write:

: main "hello" drop ;

Run ./mini_forth hello.fth. Then the terminal will print:

[RAW SCRIPT]
"68656c6c6f OP_DROP"

[EVAL RESULT]
MainStack: []
AltStack:  []

There're some code examples in /example directory.

Data and opcodes

Constants

MiniForth code Bitcoin Sciprt ( can be read by bsv.js ) Description
0 1 2 3 OP_0 OP_1 OP_2 OP_3 Numbers
0xFF 0xff 0x1234 ff00 ff00 3412 Hex Numbers
-1 -2 -3 OP_1NEGATE 82 83 Negative Numbers
"hello world" 68656c6c6f20776f726c64 ASCII String
<<0, 1, 2, 3, 0x04>> 0001020304 Bytes

Arithmetic

MiniForth code Bitcoin Sciprt ( can be read by bsv.js ) Description
+ - * / % OP_ADD OP_SUB OP_MUL OP_DIV OP_MOD
1- OP_1SUB
num= OP_NUMEQUAL
num=verify OP_NUMEQUALVERIFY
and or not not0 OP_BOOLAND OP_BOOLOR OP_NOT OP_0NOTEQUAL
>= <= > < OP_GREATERTHANOREQUAL OP_LESSTHANOREQUAL OP_GREATERTHAN OP_LESSTHAN

Bitwise Logic

MiniForth code Bitcoin Sciprt ( can be read by bsv.js ) Description
= OP_EQUAL
=verify OP_EQUALVERIFY
& | ^ ~ OP_AND OP_OR OP_XOR OP_INVERT

Unimplemented

  • OP_CHECKSIG
  • OP_CHECKSIGVERIFY
  • OP_CHECKMULTISIG
  • OP_CHECKMULTISIGVERIFY

Other Core Opcodes

Other opcodes are expressed with downcase words, for example: drop swap stands for OP_DROP OP_SWAP.

Debug Operators

MiniForth code Bitcoin Sciprt ( can be read by bsv.js ) Description
. ignore Print the top element
cr ignore Print a new line
print_stack ignore Print two stacks

Syntax

The syntax is basically a simplified version of Forth language.

Define new word

: 3sub 3 - ;

Comment

\ a line starts with '\' is comment

\ we use ( a -- b ) to comment the arguments and returns of a word
: left ( str n -- left_str )
    split drop ;

Import other file

: import 
    "./example/binary"
;

: main
    "abcde" 1 2 binary:substr
    "bc" =verify    
;

Compile time macros

Loop

\ the loop will be unroll at compile time
: dup3times ( -- )
    3 0 do dup loop ;  
\ will be compile into `OP_DUP OP_DUP OP_DUP`

\ can use the +loop to specify the step
: countdown 
    0 10 do cr i . -1 +loop ;

literal

\ the code inside a `[ ]` is a quote
\ when the compiler see `literal`, it will execute nearest quote
\ and place the result at the position of `literal`

\ this code equal to `: two 2 ;`
: two [ 1 1 + ] literal ;

Macros

compile-time opcodes

MiniForth Code Example Description
eval [ 1 1 + ] eval ---> 2 Execute the quote
curry 1 [ 1 + ] curry ---> [ 1 1 + ] Merge the second element into the quote
call [ 1 1 + ] call ---> 1 1 + Unquote

macro_start, macro_end

The code between macro_start and macro_end will be executed at compile time.

\ we can define such a function
\ which takes 2 args, one is compile
\ time arg, and another is runtime arg

: simple_macro ( compile_time_arg runtime_arg -- a b )
    [ 3 + ]
    macro_start
        swap tas curry eval fas
    macro_end
    +
;

\ compiled code: 4 2 + ;
: main 1 2 simple_macro ;

bi, tri

These functions are borrowed from the Factor language.

\ equal to `1 1 + 1 2 *`
: main 1 [ 1 + ] [ 2 * ] bi ;

\ equal to `1 1 + 1 2 + 1 3 +`
: main 1 [ 1 + ] [ 2 + ] [ 3 + ] tri ;

Support

If you have any questions or errors during the use, please raise an issue or ask questions on the Bitcoin Script channel of Powping.