Overview
BitScript is an esoteric language designed to simulate logic gates.
Bitr is a minimal BitScript interpreter written in Rust, it does not include any external dependencies.
(Stands for bit-runner, pronounced bitter.)
Features
- BitScript is a text based logic gate simulator.
- BitScript is Turing complete, allowing for complex designs.
- BitScript contains a file based module system (components), which declutters code.
Examples of what you can do with BitScript can be found in examples.
Roadmap
- Assigning values to a single cell, whole array and range or cells.
- Common logic gates.
- Input with base 8, 10 and 16 numbers.
- Goto, label, and if statements.
- Reusable components.
- Arrays.
- Global std library of components.
- Unicode characters from binary.
- Running system commands
- Browser interpreter with Web Assembly.
Quick start
Install bitr from crates.io using the command below, or download a prebuilt binary.
Make sure
cargo
is present in your system.
cargo install bitr
To confirm it is installed, run bitr
.
Syntax
This section is the guide to writing BitScript. It also act as the documentation of BitScript, so if you are just searching for a specific syntax, use the search button above.
Hello world
To display the text "Hello world", create a file
hello_world.bs
.
# hello_world.bs
# this is a comment
disp Hello world\n # disp [string]
Save the file and run bitr display
. Alternatively,
you can run it in the repl, start the repl with
bitr
.
Debug
dbg
display values with no formatting.
dbg 1 # 1
dbg AND(1, 0) # 0
dbg NOT(11001101) # 00110010
dbg DEN(1111) # 15, DEN for denary (base 10)
Display
disp
display strings with formatting arguments. Use
singe quotes (''
) to preserve leading/trailing
spaces, and curly braces ({}
) for values.
disp This is a string.\n # This is a string.
disp 'Enter a value: ' # Enter a value:
disp 1 and 1 is {AND(1, 1)} # 1 and 1 is 1
Variables
There are no data types in BitScript, because all data are stored in 1d array of bits.
Declare
dclr
is used declare variables, the size (length)
of variables cannot be changed once created, and variable names
can only contain alphabet and underscores.
dclr first_var 4 # creates a variable of length 4
dclr another_var 4 1 # creates a variable of length 4, initialise it with 1s
Assigning to variables
Variables can be displayed as a whole, individual cells or ranges.
first_var = another_var # sets first_var to 1111
first_var[0] = 0 # sets the least significant bit to 0, first_var is now 1110
first_var[2..4] = 00 # sets the 2-3rd least significant bit to 00, first_var is now 0010
first_var[..] = 0 # ranges can be unbounded, in this case it sets first_var to 0000
Variables can also be used as index for another variable, for example.
first_var[..DEN(11)] = another_var[1..] # denary of `11` is 3
first_var[AND(1, 0)] = 2
Displaying variables
In the same sense that it is assigned, it can be displayed the
same way with dbg
and disp
.
dbg another_var # 0000
dbg another_var[0] # 0
dbg another_var[NOT(0)..] # 000
disp another_var is {another_var}
disp the least significant bit of another_var is {another_var[0]}
disp the other 3 bits are {another_var[NOT(0)..]}
Gates
Logic gates are the only way to process variables in BitScript, and that's the entire point.
dbg NOT(0) # 1
dbg AND(1, 0) # 0
dbg OR(1, 0) # 1
dbg NOR(1, 0) # 0
dbg NAND(1, 0) # 1
dbg XOR(1, 0) # 1
dbg XNOR(1, 0) # 0
Short hand expression
dbg NOT(1101) # 0010, same as NOT(1, 1, 0, 1)
dbg AND(1101) # 0, same as AND(1, AND(1, AND(0, 1)))
dbg OR(1101) # 1, same as OR(1, OR(1, OR(0, 1)))
dbg NOR(1101) # 0, same as NOR(1, NOR(1, NOR(0, 1)))
dbg NAND(1101) # 1, same as NAND(1, NAND(1, NAND(0, 1)))
dbg XOR(1101) # 1, same as XOR(1, XOR(1, XOR(0, 1)))
dbg XNOR(1101) # 0, same as XNOR(1, XNOR(1, XNOR(0, 1)))
Single values, whole arrays, and ranges can be used in gates.
In conclusion, this is how each gate behaves.
Gate | Behavior |
---|---|
NOT |
Flips all bits to its opposite. |
AND |
Only returns 1 if all bits are
1 .
|
OR |
Returns 1 if any of the bit is
1 .
|
NOR |
NOT(OR) |
NAND |
NOT(AND) |
XOR |
Returns 1 if there is an
odd number of 1 s.
|
XNOR |
Returns 1 if there is an
even number of 1 s.
|
Input
BitScript can take input from stdin.
dclr user_input 4
disp 'Enter a 4 bit number: '
inpt user_input
disp You have entered: {user_input}
In this example, if the user enters 1011
, then the
program will tell the user that he entered 1011
.
Simple as that.
Casting
Since there is only one datatype in BitScript, casting isn't really a thing.
However, what is a possible is accepting inputs of octal, denary, and hexidecimal numbers. And opposite to that - displaying variables in that format.
Input casting
dclr store 0 # decalre a dummy variable
inpt store # now accepting only binary numbers
inpt o store # now accepting only octal numbers
inpt d store # now accepting only denary numbers
inpt h store # now accepting only hexidecimal numbers
Output casting
dbg 1100 # 1100
dbg OCT(1100) # 14
dbg DEN(1100) # 12
dbg HEX(1100) # C
Assign casting
dclr store 0
store = 1100 # 1100
store =o 14 # 1100
store =d 12 # 1100
store =h C # 1100
Functions
All BitScript files are valid functions, each file represents a single function.
Syntax
reg [component name] [file name] # registers the component
[conponent name](params) # uses the component
Parameters
The parameters are passed into the input buffer, which
can be read by the component using inpt
.
# echo.bs
dclr A 8 0
inpt A # takes 1 params
disp You entered {A}!
Use the function
# run-function.bs
reg echo echo
echo(11111111)
Return values
Values can be returned using the exit
keyword.
# add-function.bs
# just a simple 8 bit adder
dclr A 8 0
dclr B 8 0
inpt A
inpt B
dclr U 7 0
dclr C 8 0
C[0] = XOR(A[0], B[0])
U[0] = AND(A[0], B[0])
# snippet
C[7] = XOR(A[7], B[7], U[6])
exit C # returns the value of C
Use the function in an 8 bit adder program.
# run-function.bs
reg add add-function
# create two 8 bit variables
dclr A 8 0
dclr B 8 0
# assign them with values
A =d 11
B =d 23
# use the functon `add`
disp add(A, B)
Commands
Repl
Running bitr
without any arguments will start the
repl, all variables declared in the repl will be remembered
until the repl ends.
bitr # launches the repl
Run file
To run a file, put the file name (with or without
.bs
extension) as the first argument.
bitr [file name].bs # runs [file name].bs
bitr [file name] # the `.bs` extension is not required
Informational
Informational commands prints out information and does nothing else.
bitr help # displays the help message
bitr version # displays the version of bitr installed
Changelog
v0.1.1
Added
- File based module/function system
v0.1.0
Added
- Initial commit
Contributing
If you are able and like the project so far, consider contributing through one of the following ways.
Examples
Add your code to examples, for that you can either create a pull request or contact me through any ways (e.g. open an issue).
Docs
If you've noticed any undocumented behavior that seems resonable, you can either open a pull request with the docs edited, or contact me. If you think it's a bug, open an issue.
Adding features/fixing bugs
If you somehow managed to understand my code, it would be great if you can add features/fix bugs in Bitr. Open a pull request if you do.
Your code should
generate no warnings with cargo clippy
, unless there are strong reasons to write it not according to
clippy.