We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

MovLang

From Esolang
Jump to navigation Jump to search

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:

  1. default_seg_size - default segment size (default = `FFFF`, max = `FFFFFFFF`)
  2. address_size - address size (default = `4`, available values: `1`, `2`, `4`, `8`)
  3. 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'