Complete Manual
3BC LANGUAGE
Tutorial
3BC is a low-level, easy-to-learn programming language that works in the form of a virtual machine similar to a 1960s computer, but with a very unusual architecture that has processors of only 3 bits.
Despite having an aspect to be an esoteric language, it has a good capacity for generic use to solve computational problems, and certain advantages with the implementation in embedded and microcontrollers.
It was introduced by a Brazilian at Christmas 2020 after completing a month of development, being a project for studies and also as a conceptual proof of concept about punched cards being readable and practical for both humans and machines.
How to make a “Hello world!”
These steps will guide you through running the hello world example and getting your first 3BC program running on your machine, so let’s get started.
After downloading the binary from download, simply unzip the file and use the command line to run the source code using the interpreter according to your operating system: windows, mac os, unix or linux.
MODE NILL 0d2
STRC NILL 'o'
STRC NILL 'l'
STRC NILL 'a'
STRC NILL ' '
STRC NILL 'm'
STRC NILL 'u'
STRC NILL 'n'
STRC NILL 'd'
STRC NILL 'o'
STRC NILL '!'
using ‘terminal’ or ‘cmd’ type:
C:\Users\nicod\Downloads\3bc-windows-32> 3bc.exe helloworld.3bc
hello world!
C:\Users\nicod\Downloads\3bc-windows-32>
using the shell of your choice type:
$ ./3bc helloworld.3bc
hello world!
$
Structure
A great point to facilitate the learning, is its very well organized syntax of the language. With a quick view separated in rows and columns, where these have a fixed size of parameters, even when not used.
A program line is consequently an instruction, which has three mandatory parameters. They are separated in the respectively order of register, address, constant.
The register defines the behavior of the instruction be it printing to the screen, capturing inputs, summing, etc.
You should use mnemonics like mode
, math
and nill
or some literal expressions that represent its opcode from 0 to 7. Be guided by the cheatsheet guide, which explains in detail about each instruction.
Depending on the register it is necessary to pass or not address and constant values. It can be either mandatory or restrictive, or not accept both in the same instruction, to avoid ambiguity.
Address is a space in memory used to store certain data, some instruction sets depend on it.
You must use a literal expression. It is important to note that using hash such as :my_variable in small programs is fine, but monolithic structures can have conflicts between addresses.
Constant would be a fixed, unchanging value.
Syntax
Literal Expressions
There is no typing in the language, just raw data; For ease of use, the interpreter accepts several representations of these values, such as:
Description |
Representation |
Caracter ASCII |
'Z' |
Positive decimal |
9 0d9 0i9
|
Negative decimal |
-9 -0d9 -0i9
|
Octal positive/negative |
0o7 -0o7
|
Binary positive/negative |
0b1 -0b1
|
HexaDecimal positive/negative |
0xF -0xF
|
Hash Generator |
:minha_funcao |
Zero or Null |
0 0d0 0i0 0o0 0b0 0x0 '\0' NILL
|
Known as labels are markings in the program where conditional jumps or procedure calls can happen, no label can be re-labeled. It is possible to make jumps in any direction of the algorithm.
When both the register and address columns have null values, any constant value will be considered a bookmark.
NILL NILL 0x01
The literal-expression hash generator is intended to make it easier to organize the labels in your code, so as not to rely on just numeric markup.
NILL NILL :loop start
MODE NILL 0d9
GOTO NILL :entry # Jump to the entry point
MODE NILL 0d2
STRC NILL 'h' # Not run
STRC NILL 'i' # Not run
STRC NILL ' ' # Not run
STRC NILL ' ' # Not run
NILL NILL :entry
STRC NILL 'f' # run
STRC NILL 'r' # run
STRC NILL 'i' # run
STRC NILL 'e' # run
STRC NILL 'n' # run
STRC NILL 'd' # run
Expected Outcome:
Paradigms
Unstructured
The unstructured paradigm can be used for several occasions such as elaborating selection and condition deviations, making repetition loops, and even a complete program fast and efficient. But its overuse can bring great maintenance difficulties and unexpected behavior.
name |
octal |
bit |
description |
goto |
1 |
001 |
jump to the label unconditionally |
fgto |
2 |
010 |
jump to the label if the auxiliary memory is full |
zgto |
3 |
011 |
jump to the label if the auxiliary memory is empty |
pgto |
4 |
100 |
jump to the label if the auxiliary memory is positive |
ngto |
5 |
101 |
jump to the label if the auxiliary memory is negative |
Repeating loops
Print ‘cafe’ uninterruptedly.
MODE NILL 0d2
NILL NILL :loop
STRX NILL 0xCAFE
MODE NILL 0d9
GOTO NILL :loop
Print ‘…’ using of while.
# Value of :var is 3
MODE NILL 0d6
ALOC :var 0d3
# Print '.'
MODE NILL 0d02
NILL NILL :do_while
STRC NILL '.'
# Add -1 in :var
MODE NILL 0d8
PUSH :var NILL
MODE NILL 0d11
MATH NILL -1
MODE 0 0d08
PULL :var 0
# Repeat as long as var: is not equal to 0
MODE NILL 0d9
FGTO NILL :do_while
Print ‘…’ using while.
# Valor of :var is 3
MODE NILL 0d6
ALOC :var 3
# While :var is not equal to 0
MODE NILL 0d8
NILL NILL :where_entry
PUSH :var NILL
MODE NILL 0d9
ZGTO NILL :where_exit
# Print '.'
MODE NILL 0d2
STRC NILL '.'
# Subtract 1 from :var
MODE NILL 0d8
PUSH :var NILL
MODE NILL 0d12
MATH NILL 1
MODE NILL 0d8
PULL :var NILL
# End of while
MODE NILL 0d9
GOTO NILL :where_entry
NILL NILL :where_exit
Conditional Deviation
Print ‘!=’ if the input is different from 5.
# Keyboard capture and store in :cmp
MODE NILL 0d4
STRI :cmp NILL
# Compare the negation (:cmp != 5)
MODE NILL 0d8
PUSH :cmp NILL
MODE NILL 0d12
MATH NILL 5
MODE NILL 0d9
ZGTO NILL :if_equal
# Print '!='
MODE NILL 0d2
STRC NILL '!'
STRC NILL '='
# End program.
NILL NILL :if_equal
- If Equal, Greater or Lesser
Print ‘n<5’ if less number is less, print ‘n=5’ if number is exactly 5 or print ‘n>5’ if it is greater. Where n will be the keyboard input.
# Keyboard capture and store in :cmp
MODE NILL 0d3
STRI :cmp NILL
# Compare with 5
MODE NILL 0d8
PUSH :cmp NILL
MODE NILL 0d12
MATH NILL 5
MODE NILL 0d9
NGTO NILL :if_less
ZGTO NILL :if_equal
PGTO NILL :if_greater
# Print '<'
MODE NILL 0d2
NILL NILL :if_less
STRC NILL '<'
MODE NILL 0d9
GOTO NILL :if_exit
# Print '='
MODE NILL 0d2
NILL NILL :if_equal
STRC NILL '='
MODE NILL 0d9
GOTO NILL :if_exit
# Print '>'
MODE NILL 0d2
NILL NILL :if_greater
STRC NILL '>'
MODE NILL 0d9
GOTO NILL :if_exit
# Print '5'
MODE NILL 0d2
NILL NILL :if_exit
STRI NILL 5
Procedural
The procedural paradigm (popularly called procedural), has the advantage of making a stack of processes, where there is a return point at the same place as its call. This can make it easier to write large programs.
# Jump to entry point
MODE NILL 0d9
GOTO NILL :entry
# Procedure :print_bar
MODE NILL 0d2
NILL NILL :print_bar # Label
STRC NILL 'B'
STRC NILL 'a'
STRC NILL 'r'
MODE NILL 0d41 # Return Mode
BACK NILL NILL # Return unconditionally
# Procedure :print_foo
MODE NILL 0d2
NILL NILL :print_foo # Start of the process
STRC NILL 'F'
STRC NILL 'o'
STRC NILL 'o'
MODE NILL 0d41
BACK NILL NILL # End of process
# Entry point
MODE NILL 0d42 # Call procedures and return
NILL NILL :entry # Entry point
CALL NILL :print_foo # Call :print_foo
CALL NILL :print_bar # Call :print_bar
CheatSheet
Architecture details
COMMON
name |
octal |
bit |
description |
nill |
0 |
000 |
label reference point or skip line (null) |
mode |
7 |
111 |
change cpu register bank |
NO MODE DONT USE
MODE DEBUG
name |
octal |
bit |
description |
strb |
1 |
001 |
log number as binary |
stro |
2 |
010 |
log number as octal |
stri |
3 |
011 |
log number as decimal |
strx |
4 |
100 |
log number as hexadecimal |
strc |
5 |
101 |
log ascii character |
MODE STRING
name |
octal |
bit |
description |
strb |
1 |
001 |
put number as binary |
stro |
2 |
010 |
put number as octal |
stri |
3 |
011 |
put number as decimal |
strx |
4 |
100 |
put number as hexadecimal |
strc |
5 |
101 |
put ascii character |
name |
octal |
bit |
description |
strb |
1 |
001 |
input number as binary |
stro |
2 |
010 |
input number as octal |
stri |
3 |
011 |
input number as decimal |
strx |
4 |
100 |
input number as hexadecimal |
strc |
5 |
101 |
input ascii character |
name |
octal |
bit |
description |
strb |
1 |
001 |
input number as binary |
stro |
2 |
010 |
input number as octal |
stri |
3 |
011 |
input number as decimal |
strx |
4 |
100 |
input number as hexadecimal |
strc |
5 |
101 |
input ascii character |
name |
octal |
bit |
description |
strb |
1 |
001 |
input number as binary |
stro |
2 |
010 |
input number as octal |
stri |
3 |
011 |
input number as decimal |
strx |
4 |
100 |
input number as hexadecimal |
strc |
5 |
101 |
input ascii character |
MODE MEMORY
name |
octal |
bit |
description |
free |
1 |
001 |
realese memory |
aloc |
2 |
010 |
reserve memory and set a value |
moff |
3 |
011 |
memory config remove mask |
muse |
4 |
100 |
memory config append mask |
MODE MEMORY PTR
name |
octal |
bit |
description |
free |
1 |
001 |
realese memory in pointer |
aloc |
2 |
010 |
set a value in pointer |
pull |
3 |
011 |
pull aux memory to address pointer memory (ptr <- aux) |
spin |
4 |
100 |
inverse values inner memory pointer and aux (ptr <-> aux) |
push |
5 |
101 |
push aux memory to pointer memory (ptr -> aux) |
MODE MEMORY AUX
name |
octal |
bit |
description |
free |
1 |
001 |
realese memory aux |
aloc |
2 |
010 |
set a value in aux memory |
pull |
3 |
011 |
pull aux memory to address memory (addr <- aux) |
spin |
4 |
100 |
inverse values inner memory and aux (addr <-> aux) |
push |
5 |
101 |
push aux memory to address memory (addr -> aux) |
MODE JUMP
name |
octal |
bit |
description |
goto |
1 |
001 |
jump to the label unconditionally |
fgto |
2 |
010 |
jump to the label if aux memory is fill |
zgto |
3 |
011 |
jump to the label if aux memory is empty |
pgto |
4 |
100 |
jump to the label if aux memory is positive |
ngto |
5 |
101 |
jump to the label if aux memory is negative |
MODE MATH SUM
name |
octal |
bit |
description |
math |
1 |
001 |
add value in the aux memory |
MODE MATH SUB
name |
octal |
bit |
description |
math |
1 |
001 |
subtraction in the aux memory |
MODE MATH MUL
name |
octal |
bit |
description |
math |
1 |
001 |
multiplication in the aux memory |
MODE MATH DIV
name |
octal |
bit |
description |
math |
1 |
001 |
division in the aux memory |
MODE MATH MOD
name |
octal |
bit |
description |
math |
1 |
001 |
rest of the division with aux memory |
MODE MATH POWER
name |
octal |
bit |
description |
math |
1 |
001 |
enhance aux memory value |
MODE MATH ROOT
name |
octal |
bit |
description |
math |
1 |
001 |
root aux memory value |
MODE MATH ABS
name |
octal |
bit |
description |
math |
1 |
001 |
module positive aux memory value |
MODE MATH MUL ADD
name |
octal |
bit |
description |
nb02 |
1 |
001 |
multiply by 2 and accumulate operation |
nb08 |
2 |
010 |
multiply by 8 and accumulate operation |
nb10 |
3 |
011 |
multiply by 10 and accumulate operation |
nb16 |
4 |
100 |
multiply by 16 and accumulate operation |
MODE BITWISE NOT
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean not (per bit) |
MODE BITWISE AND
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean and (per bit) |
MODE BITWISE OR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean or (per bit) |
MODE BITWISE XOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean xor (per bit) |
MODE BITWISE NAND
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean nand (per bit) |
MODE BITWISE NOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean nor (per bit) |
MODE BITWISE XNOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean xnor |
MODE BITWISE LEFT
name |
octal |
bit |
description |
math |
1 |
001 |
aux bit shift left |
MODE BITWISE LEFT
name |
octal |
bit |
description |
math |
1 |
001 |
aux bit shift right |
MODE BOOLEAN NOT
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean not |
MODE BOOLEAN AND
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean and |
MODE BOOLEAN OR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean or |
MODE BOOLEAN XOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean xor |
MODE BOOLEAN NAND
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean nand |
MODE BOOLEAN NOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean nor |
MODE BOOLEAN XNOR
name |
octal |
bit |
description |
math |
1 |
001 |
aux boolean xnor |
MODE LOG BASE
name |
octal |
bit |
description |
math |
1 |
001 |
log aux in base n |
MODE LOG NATURAL
name |
octal |
bit |
description |
math |
1 |
001 |
log aux natural |
MODE PROCEDURE_RET
name |
octal |
bit |
description |
call |
1 |
001 |
return from procedure unconditionally |
fcal |
2 |
010 |
return from procedure if aux memory is fill |
zcal |
3 |
011 |
return from procedure if aux memory is empty |
pcal |
4 |
100 |
return from procedure if aux memory is positive |
ncal |
5 |
101 |
return from procedure if aux memory is negative |
MODE PROCEDURE
name |
octal |
bit |
description |
call |
1 |
001 |
call label procedure unconditionally |
fcal |
2 |
010 |
call label procedure if aux memory is fill |
zcal |
3 |
011 |
call label procedure if aux memory is empty |
pcal |
4 |
100 |
call label procedure if aux memory is positive |
ncal |
5 |
101 |
call label procedure if aux memory is negative |
MODE SLEEP
name |
octal |
bit |
description |
real |
1 |
001 |
inactive cpu for x cycles (real hardware) |
fake |
2 |
010 |
inactive cpu for x cycles (virtual machine) |
micr |
3 |
011 |
inactive cpu for x microseconds |
mili |
4 |
100 |
inactive cpu for x milliseconds |
seco |
5 |
101 |
inactive cpu for x seconds |
description: all error codes, description and how to resolve them.
—
Errors
Code |
Description |
Solution |
|
UNKNOWN ERROR |
report the problem! click here
|
0x00000B |
SEGMENT FAULT |
report the problem! click here
|
0x3BC000 |
CPU MODE IS NOT DEFINED |
You need to set a CPU mode to use any register |
0x3BC001 |
CPU MODE IS RESERVED |
Custom register has been added or has another opcode |
0x3BC002 |
INVALID CPU REGISTER |
Enter a valid value in the first column |
0x3BC003 |
INVALID CPU ADDRESS |
Enter a valid value in the second column |
0x3BC004 |
INVALID CPU CONSTANT |
Enter a valid value in the thirdy column |
0x3BC005 |
INVALID CPU MODE |
Check cpu mode click here
|
0x3BC006 |
INVALID LABEL |
Repeat markup, conflict with a hash literal or an unexpected negative number. |
0x3BC007 |
INVALID PROCEDURE RETURN |
Check if you are calling procedures and returning correctly. |
0x3BC008 |
DUALITY ADDRES WITH VALUE IS NOT ALLOWED |
Use only an address or a constant. |
0x3BC009 |
VALUE OR ADDRESS IS REQUIRE |
Important use some constant value or address. |
0x3BC00A |
VALUE IS REQUIRED |
Set a constant value. |
0x3BC00B |
ADDRESS IS REQUIRED |
Set a memory address. |
0x3BC00C |
VALUE IS NOT ALLOWED |
Unexpected constant value. |
0x3BC00D |
ADDRESS IS NOT ALLOWED |
Not expected a memory address. |
0x3BC00E |
NUMBER WHIOUT DIGITS |
Missing numeric digits. |
0x3BC00F |
NUMBER UNDERFLOW |
Unexpected number because the value is too small. |
0x3BC010 |
NUMBER OVERFLOW |
Unexpected number because the value is too large. |
0x3BC011 |
NUMBER WRONG BASE |
Digit does not match number base |
0x3BC012 |
NUMBER NEGATIVE IS NOT EXPECTED |
Mem. Aux, Mem. Main or constant has a negative irregular number. |
0x3BC013 |
NUMBER ZERO IS NOT EXPECTED |
An irregular null value found. (example: divide by zero) |
0x3BC014 |
OUT OF MEMORY |
Check for stack or buffer overflow. |
0x3BC015 |
NONE TTY |
To use a teleprompter you must define the input or output. |
0x3BC016 |
UNSUPPORTED FEATURE |
This feature is not supported by the architecture. |
0x3BC017 |
MEMORY CONFIG |
Resolving conflicts in memory usage. |
0x3BC018 |
CANNOT OPEN FILE |
File does not exist, or system does not have permission. |
0x3BC019 |
NULL POINTER |
Point to a valid memory address. |
0x3BC01A |
INVALID CHARACTER ESCAPE |
Control character not supported by the language. |
0x3BC01B |
INVALID CHARACTER SIZE |
Control character not supported by the language. |
0x3BC01C |
WRONG NUMBER OF COLUMNS |
Every row must strictly have 3 columns. |
title: Roadmap
description: The expected future for language and community. (aka to do list)
—
Year 2020 roadmap
Year 2021 roadmap
Year 2022 roadmap
come soon roadmap
Comunity roadmap
List of early developers
Hall of fame with everyone who dedicated to just learning 3bc language, this list is open until the day that version 0.1 will be released.
|
date |
developer |
who? |
1º |
26 November 2020 |
Rodrigo Dornelles |
|
2º |
28 November 2020 |
Carlos Eduardo |
|
3º |
23 December 2020 |
Robson Soares |
|
4º |
28 December 2020 |
Guilherme Neves |
|
5º |
30 December 2020 |
Marcus Paulo |
|
6º |
30 December 2020 |
Takeshi Ishikawa |
|
7º |
31 December 2020 |
André Luis |
|
8º |
2 January 2021 |
Francisco Noble |
|
9º |
5 February 2021 |
Lucas Rangel |
|
10º |
6 February 2021 |
Otávio Burato |
|
11º |
21 July 2021 |
Github Copilot (IA)
|
|
12º |
14 August 2021 |
Moizes Sousa |
|
13º |
30 October 2021 |
Anderson Costa |
|
References
Bibliography
C Language
- Schildt. Hebert (1997) C Completo e total 3. rev. (Mayer. Roberto Carlos Trad.) Editora Pearson Education do Brasil
Data Structures
Left Leaning Red Black Tree
Tests
Compilers & Interpreters