Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
thosakwe committed Jun 12, 2018
0 parents commit cd50620
Show file tree
Hide file tree
Showing 20 changed files with 696 additions and 0 deletions.
62 changes: 62 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Created by .ignore support plugin (hsz.mobi)
### CMake template
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries

# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml

# Gradle:
.idea/**/gradle.xml
.idea/**/libraries

# CMake
cmake-build-debug/
cmake-build-release/

# Mongo Explorer plugin:
.idea/**/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
29 changes: 29 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/hello_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/if_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/interpolation_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/macro_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/times_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/runConfigurations/variables_t2b.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/t2b.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.9)
project(t2b)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

add_executable(t2b main.cc)
install(TARGETS t2b DESTINATION bin)
110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# t2b
A wicked-powerful text macro language for building binary files.
Supports comments, looping, Unicode, variables, conditionals, macros and recursion.

TLDR; Check out `example/`.

## Usage
```bash
$ t2b <filename> here
$ t2b # Read directly from stdin
```

`t2b` always writes to stdout. To output to a file, simply use a pipe (`|`).

## Language
Newlines are solely for the sake of readability; all whitespace is the same.

```t2b
# This is a comment!
#
# Comments must be on their own line.
# Emit a byte. In DECIMAL.
u8 10
# Toggle hex mode ON.
# In hex mode, numbers will be interpreted as hexadecimal.
hex
u8 10
# Toggle hex mode OFF.
hex
# Spit out a signed integer.
i64 25677
# Print a string (no line break)
str hello
# Print with a line break.
strl hello
# Wrap in quotes to capture whitespace.
strl "hello world!"
# Escapes are supported.
str "hello, world!\n"
# Unicode?
str "\u{1234}"
# Print a newline.
endl
# Do something 5 times.
# Indentation is purely for readability.
times 5
u8 23
u32 24
times 10
# We can nest loops
str "50 times!!!"
endtimes
endtimes
# Capture the output of another command.
# Oh, and store it into a variable.
set foo (u8 33)
# Access its value.
set bar (get foo)
# Emit its value 3 times.
times 3 get foo
# Create a simple macro.
macro emit_twice x
begin
times 2 (get x)
endmacro
# Call it!
emit_twice 24
```

## Why?
The need for such a program arose when I was working on writing a simple VM.
Manually hex-editing files for an ever changing bytecode spec is tedious, error-prone,
and most of all - *sucky*.

Now there's a lightweight way to do just that.

## Supported Commands
* `u8...u64` - Emit unsigned integer
* `i8...i64` - Emit signed integer
* `hex` - Toggle hex mode on/off (defaults to OFF)
* `str <expr>` - Write a string
* `strl <expr>` - Write a string AND newline
* `endl` - Write a newline
* `not <expr>` Boolean NOT a char
* `if <cond> <pred> endif` Execute `<pred>` if `<cond> == 1`
* `get <expr>` - Fetch the global variable named `expr`
* `set <expr1> <expr2>` - Assign the global variable named `expr1` to `expr2`
* `=` - Compare two values, return `0` or `1`
* `times <count> <pred> endtimes` - Execute `<pred>` `<count>` times. `i` is always set to the current iteration's index.
* `macro <name> <param-names...> begin <pred> endmacro` - Declare a custom macro named `<name>`.

# What's next?
It's now feasible to write a machine code compiler in shell. Hooray.
Not sure why you would ever do that to yourself, though.
2 changes: 2 additions & 0 deletions example/hello.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Say hello!!!
strl "Hello, T2B!!!"
20 changes: 20 additions & 0 deletions example/if.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `if` handles u8 only. Do as you will.
if (u8 1)
strl "true == true"
endif

if (not (u8 0))
strl "!false == true"
endif

if (not (u8 1))
strl "This never prints."
endif

if (= (str 2) (str 2))
strl "2 == 2"
endif

if (= (str 24) (str 2))
strl "This never prints either."
endif
10 changes: 10 additions & 0 deletions example/interpolation.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Using parentheses, we can use the outputs of commands as inputs.
#
# Let's be verbose and write out "T2B!!!".
times 5
str (u8 84)
str (u8 50)
str (u8 66)
times 10 str (u8 33) endtimes
endl
endtimes
44 changes: 44 additions & 0 deletions example/macro.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Create a simple macro.
macro emit_times value count
begin
str "Emitting value: \""
get value
str "\" "
get count
str " time(s)!"
endl
endl

times (get count)
get value
endl
endtimes
endmacro

# Call it!
#emit_times "Hello!" 34

# Yes, you can technically nest macros and create them dynamically.

# We'll even dynamically create their names.
macro create_macro_name
begin
str dyn_macro
get i
endmacro


macro create_dynamic_macros count
begin
times (get count)
macro (create_macro_name)
begin
strl "Wow! This is a dynamic macro."
endmacro
endtimes
endmacro

create_dynamic_macros 23

dyn_macro16
dyn_macro4
12 changes: 12 additions & 0 deletions example/times.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
strl "Programmers love powers of 2. How about 2^4?"
endl

times 2
times 2
times 2
times 2
str loop!
endtimes
endtimes
endtimes
endtimes
10 changes: 10 additions & 0 deletions example/variables.t2b
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Use `set` to assign a GLOBAL variable.
set foo (u8 33)

# Use `get` to retrieve the current value.
set bar (get foo)

# Loops are fun
times 10
str (get bar)
endtimes
Loading

0 comments on commit cd50620

Please sign in to comment.