MovLang
Paradigm(s) | imperative |
---|---|
Designed by | Sulphuris |
Appeared in | 2024 |
Memory system | Cell-based |
Dimensions | one-dimensional |
Computational class | Turing complete |
Reference implementation | Movlang JBC compiler |
Influenced by | Assembly, Movfuscator (not a language) |
File extension(s) | .movl |
Language overview
A simple language that consists of a single instruction: copy memory (MOV)
Syntax
[<label>:] <dest> <value>[size]
where:
dest
is a desination address where to put the value;
value
is the value to put;
size
is an optional hint for the compiler how much memory should be taken.
Dereferensing:
<segment>'['<value>[+<offset>|<bit_offset>]']'
Like breaks doesn't matter and play the same role as whitespace
Size specifier:
:<size_in_bytes|^size_in_bits>
Preprocessor
To make this language less painful to use, it provides a macroprocessor that allows users to somewhat customize the language syntax.
The preprocessor supports following directives:
#def
#def <alias> <name>
Defines an alias for a single token.
Examples:
#def stdout C // now every token with text "stdout" will be replaced with "C" stdout[00] 'H' // C[00] 'H' stdout[01] 'e' // C[01] 'e'
#def inc_table 00A0 0[inc_table + 0] 1 // 0[00A0 + 0] 1 0[inc_table + 1] 2 // 0[00A0 + 1] 2
#include
#include <filename>
Includes all the file content ("file.movl" = file)
.
#macro
#macro <name> [#args#{}[]<>] #unfolds [content] #end_macro
Creates a macro with a custom syntax.
Examples:
#macro inc #seg#[#addr#] #unfolds #seg#[#addr#] 0[inc_table + #seg#[#addr#]] #end_macro A[00] 1 inc A[00] // now A[00] = 2
#macro invoke2 #name#(#arg1#, #arg2#) : #argsize# #unfolds #def Label #uniq S[E[08] + 0C] @!Label S[E[0C] + 10] #arg1# :#argsize# S[E[0C] + 10 + #argsize#] #arg2# :#argsize# E[00] #name# Label: #undef Label #end_macro
#macro swap #seg1#[#addr1#] <-#size#-> #seg2#[#addr2#] #unfolds 0[600] #seg1#[#addr1#] : #size# #seg1#[#addr1#] #seg2#[#addr2#] : #size#: #seg2#[#addr2#] 0[600] : #size#: #end_macro swap F[0E] <-8-> F[00] // swap 8 bytes in F[0E] and F[00]
#segment
#segment <name> <size>
Specifies the segment size.
Example:
#segment F FA0 // now sizeof segment F = 4000 bytes
#rule
#rule <rule> <value>
Set a rule for a compiler.
Rules:
default_seg_size
- default segment size (default = `FFFF`, max = `FFFFFFFF`)address_size
- address size (default = `4`, available values: `1`, `2`, `4`, `8`)implicit_seg
- if 0, you can only use segments that you explicitly specified with `#segment` (default = `1`, available values = `0`, `1`)
#filename
#filename
Will be replaced with name of current file (without extension).
#line
#line
Will be replaced with number of current line.
#time
#time
Will be replaced with program compilation time (with :8 as object size).
#uniq
#uniq
Will be replaced with unique hex value (with :8 as object size).
#embed
#embed <segment>'['<base_address>']' <filename>
Writes a file byte by byte to the specified address.
Example:
// hello.txt Hello World // program.movl #embed C[0] "hello.txt" // will be converted to C[0+0] 'H' C[0+1] 'e' C[0+2] 'l' C[0+3] 'l' C[0+4] 'o' C[0+5] ' ' C[0+6] 'W' C[0+7] 'o' C[0+8] 'r' C[0+9] 'l' C[0+A] 'd'