Textile

From Esolang
Jump to navigation Jump to search

Textile (not to be confused with the Markup Language under the same name) is an attempt at a written form of Tile created by User:Dtp09. Its name is a portmanteau of the words "Text" and "Tile", which is exactly what it is.

Textile uses a basic assembly-like syntax and was created to allow for somewhat human readable Tile programs, and also as a somewhat easier way to plan out programs before you write them into Tile.

Comments

you use # to comment out the rest of a line

Starting a program

All programs have to have a function called "main" or "MAIN". This is where the program will start. If you have both then the program will not run. If there is a debug command in the main function, that is where execution will start.

If there is no main function then the program will refuse to run. just like C.

Opcodes

Opcodes are case insensitive. They can be written in uppercase or lowercase or even a mix of both if you're that sadistic. "NOP" and "Empty" tile states have been removed from Textile, because they do nothing. Every tile will have a three digit opcode and a full length opcode. You can use either while writing code.

Tile Opcode
▀░ psh / push
░▀ red / read
▀▀ out / output
▄░ sub / subtract
█░ add
▄▀ mul / multiply
█▀ div / divide
░▄ wrt / write
▀▄ ran / random
░█ inp / input
▀█ equ / equal
▄▄ jmp / jump
█▄ les / less
▄█ gtr / greater
██ dbg / debug

Command Repitition

Commands can be repeated multiple times in a row with the same operands. They are represented by an asterisk followed by the repetition count. For example, "push*2 $FF" would add 255, 255 to the stack.

Operands

Operands come after an opcode (of course) and are seperated by commas.

Commands

Push

Push is a pretty unique opcode. there are many ways to the same exact thing to make it easier to read. You can push both numbers and strings to the stack. Push can have no opcodes (same as push 0) or as many as you want (push many values to the stack).

Number

Numbers come in 8-bit unsigned integers. They can come in binary (prefixed %), decimal (no prefix), or hex(prefixed $). For example, to push decimal 108 you can do any of the following:

  • push $6C
  • push 108
  • push %01101100

Strings

Strings are more so just bytes that can be pushed in order. They are represented by text encased in quotes or double-quotes. For example:

push "Tile"

This would set the stack to (from bottom to top) 84, 105, 108, 101. This would output in reverse due to how the stack works.

String constants only have one method, and that is .reverse which will push every character to the stack in reverse order

greater, less, equal, jump, rand

These all have one thing in common and that is they all have functions for parameters. greater, less, equal, and jump have 1 parameter each, while rand can take 1, 2, or 3.

Functions

Functions are almost like branches, where they are called from a part of code. However, they are not subroutines and do not return to where they came from. Functions are declared by the following syntax:

label: {
#code go here
}

To refer to a function in a command's operand, simply refer to it by it's label. In my opinion I would write all the functions in all caps so they stand out and it is easier to read.

Replacements

Replacements are used when code gets too repetitive and you need to use a label to shorten it. To simplify, it's like calling a function with no parameters in a regular programming language. You can only replace with a function previous in the code, and not later in the code.

LABEL: {
#code here
}
[LABEL] #the same code will be here

Notice how it is delcared the same as a function, but CALLED different, as this isn't an opcode or an operand. it may be a good idea to seperate which are functions and which are replacements. (maybe with a really long comment i have no clue)

to make things even more of a mess to implement, you can use [LABEL]*2 or other numbers to repeat the replacement multiple times for some reason

Programs

Hello, World!

MAIN: { 
push "Hello, World".reverse
jump OUTPUT
}

OUTPUT: {
out
push
equal EXIT
add
jump OUTPUT
}

EXIT: {
}

Cat Program

MAIN: {
input
push
equal EXIT #exit if it's a null byte
add
out #output our input
push 1
add #add to input read address
push
equal OVERFLOW #if the lower byte read address overflowed
add
jump MAIN
}

OVERFLOW: {
push 1
add*3 #add 1 to input read higher byte
push
jump MAIN
}

EXIT: {
}

Brainfuck

Somehow, it was possible. The interpreter has unlimited loop depth, 8-bit unsigned cell storage and 2^16-6 (65530) cells with wraparound. Since the program is about 500 lines, it is at Textile/brainfuck.

Compiler

A compiler was written also by User:Dtp09 and is hosted here.