An esoteric program language is one that's supposed to be impractical and stupid, but still fun and usually an absurd challenge to use. I've made several in the past but didn't think they were unique enough to make public. I'm in the mood again, and making them is extremely fast, so I need suggestions for something interesting.
It's finished, but I need to do some bugtesting and think of a good name for it.
Its command library:
Push, pop for the A, B, C registers
> <
} {
) (
Handle the string in memory by printing it, getting it from input, and swapping it with a second memory string
; \ ~
Clear the string in memory
s
Read characters from the memory string and put them in the A, B, C registers
^ ` '
Write characters to the end of the memory string from the A, B, C registers
: . ,
Output the numerical value onto the end of the memory string
1 2 3
Copy a byte in memory from one place to another
#
Increment, decrement a byte in memory
i d
increment, decrement the value in the A, B, C registers
h g
u t
e d
Jump unconditionally
j
Jump if A > B
?
Jump if A < B
!
Jump if A = B
=
Swap A and B registers
x
Swap B and C registers
y
Swap C and A registers
z
Set a register to 0
a b c
Perform a logical NOT operation on registers A, B, C
A B C
Copy the value in the A register into both B and C
\
Shift a value in memory left, right by one bit
L R
Perform an operation on A and B and place the result in C
Add: +
Subtract: -
Divide: /
Multiply: *
Modulo: %
Raise to power: v
Bit shift left: l
Bit shift right:r
Mean: m
Logical OR: O
Logical AND: A
Logical XOR: X
Kill program
_
Comment
// (...) //
It's finished, but I need to do some bugtesting and think of a good name for it.
Its command library:
Push, pop for the A, B, C registers
> <
} {
) (
Handle the string in memory by printing it, getting it from input, and swapping it with a second memory string
; \ ~
Clear the string in memory
s
Read characters from the memory string and put them in the A, B, C registers
^ ` '
Write characters to the end of the memory string from the A, B, C registers
: . ,
Output the numerical value onto the end of the memory string
1 2 3
Copy a byte in memory from one place to another
#
Increment, decrement a byte in memory
i d
increment, decrement the value in the A, B, C registers
h g
u t
e d
Jump unconditionally
j
Jump if A > B
?
Jump if A < B
!
Jump if A = B
=
Swap A and B registers
x
Swap B and C registers
y
Swap C and A registers
z
Set a register to 0
a b c
Perform a logical NOT operation on registers A, B, C
A B C
Copy the value in the A register into both B and C
\
Shift a value in memory left, right by one bit
L R
Perform an operation on A and B and place the result in C
Add: +
Subtract: -
Divide: /
Multiply: *
Modulo: %
Raise to power: v
Bit shift left: l
Bit shift right:r
Mean: m
Logical OR: O
Logical AND: A
Logical XOR: X
Kill program
_
Comment
// (...) //
I'll just put in some comments to show what they do and I'll make it available for download.
@SteGriff
The thing is, I wasn't going for a minimalistic set, but a more functional one. Many of the commands there could be just as easily done with a handful of others, but considering you've only got 256 bytes of program memory, 3 bytes of registers, and 512 bytes of sort-of RAM, compressibility is an absolute must.
Now I just need to make it so you can assign the contents of those 512 bytes at startup without consuming program memory and I'm set. I'll probably add a sort of file access to support turing-completeness.
I do believe so. I'm somewhat sure a parser could be crammed into 256 bytes of program memory :tongue.gif:
But the command set itself unquestionably is capable of turing-completeness. The reason it's limited to 256 bytes of program memory is to make keeping track of where your commands are actually located much easier, as opposed to having to manually handle shorts for memory addresses separately from everything else. I might make a second parser that does process shorts, though (so you'll get 65536 bytes of program memory, 131072 RAM, and the registers will probably become 2 bytes each.) since it's only a matter of changing a few offsets and variable types.
There are 3 variations - 8 bit, 16 bit, and 32 bit. Read the readme for the differences, read reference.txt for the complete command set. Post any questions here if it's hard to understand and I'll do my best to clarify. Please note that it's not verified to be 100% bug free.
There are 3 variations - 8 bit, 16 bit, and 32 bit. Read the readme for the differences, read reference.txt for the complete command set. Post any questions here if it's hard to understand and I'll do my best to clarify. Please note that it's not verified to be 100% bug free.
I added a N jump command that jumps if A != B. It's not it the current download, though. I just needed it for my BrainF*ck interpreter to fit in 256 bytes
Speaking of, it's not quite done yet (I just need to finish handling tape wrapping) and I doubt it's going to work, but:
// Program code //
">>>++.<<<.#
// Please use a "#" to indicate EOF. //
// BrainF*ck interptreter //
j[20]
$4
// Constants //
[62] // 04: > //
[60] // 05: < //
[91] // 06: [ //
[93] // 07: ] //
[43] // 08: + //
[45] // 09: - //
[46] // 10: . //
[48] // 11: , //
[35] // 12: # (EOF) //
// Variables //
[0] // 13: Current in-code position //
[96] // 14: Current tape position //
[0][0][0][0] // 15-18: Last 4 [ positions //
[0] // 19: Current [] nest //
// memory address 20 //
$20
^[13] // Push the command into A //
$22
}[04] // Push ">" into B //
N[30]
i[14]
j[144]
$30
}[05] // Push "<" into B //
N[38]
d[14]
j[144]
$38
}[08] // Push "+" into B //
N[49]
#[14][46]
i[ 0 ]
j[144]
$49
}[09] // Push "-" into B //
N[60]
#[14][57]
d[ 0 ]
j[144]
$60
}[10] // Push "." into B //
N[74]
#[14][68]
)[ 0 ]
~,;s~
j[144]
$76
}[11] // Push "," into B //
N[88]
~\~
#[14][87]
'[ 0 ]
$88
}[06] // Push "[" into B //
N[108]
i[19]
S[18][17]
S[17][16]
S[16][15]
#[13][15]
j[144]
$108
}[07] // Push "]" into B //
N[139]
}[0]
#[14][118]
>[ 0 ]
N[134]
d[19]
#[16][15]
#[17][16]
#[18][17]
j[144]
#[15][13]
j[144]
$139
}[12] // Push "#" (EOF) into B //
N[144]
_
$144
i[13] // increment position in code //
// keep tape address within bounds //
>[13]
}[
j[20]
It's coming along. Read some of this, it's a tutorial for NES 6052 assembly, and should give you an idea on how registers and self-modification come into play.
I don't know why you'd want to design a custom scripting language anyway when there are already languages that are rather easy to embed into a given application.
Rollback Post to RevisionRollBack
Never attribute to malice what can adequately be explained by incompetence.
I don't know why you'd want to design a custom scripting language anyway when there are already languages that are rather easy to embed into a given application.
Because it's fun.
Anyway, there's a bug with the interpreter that renders anything with comments pretty much impossible to handle. I'm uploading a fix now.
EDIT: redownload from same link if you care for the fix.
Esoteric languages wiki
EDIT:
http://esoteric.voxelperfect.net/wiki/M-code
Download
Its command library:
Interesting.
I might try learning it.
If I deserve one, give me one.
Fibonacci sequence:
I'll just put in some comments to show what they do and I'll make it available for download.
@SteGriff
The thing is, I wasn't going for a minimalistic set, but a more functional one. Many of the commands there could be just as easily done with a handful of others, but considering you've only got 256 bytes of program memory, 3 bytes of registers, and 512 bytes of sort-of RAM, compressibility is an absolute must.
Now I just need to make it so you can assign the contents of those 512 bytes at startup without consuming program memory and I'm set. I'll probably add a sort of file access to support turing-completeness.
But the command set itself unquestionably is capable of turing-completeness. The reason it's limited to 256 bytes of program memory is to make keeping track of where your commands are actually located much easier, as opposed to having to manually handle shorts for memory addresses separately from everything else. I might make a second parser that does process shorts, though (so you'll get 65536 bytes of program memory, 131072 RAM, and the registers will probably become 2 bytes each.) since it's only a matter of changing a few offsets and variable types.
There are 3 variations - 8 bit, 16 bit, and 32 bit. Read the readme for the differences, read reference.txt for the complete command set. Post any questions here if it's hard to understand and I'll do my best to clarify. Please note that it's not verified to be 100% bug free.
Download
What does the M stand for?
If I deserve one, give me one.
:biggrin.gif:
I added a N jump command that jumps if A != B. It's not it the current download, though. I just needed it for my BrainF*ck interpreter to fit in 256 bytes
Speaking of, it's not quite done yet (I just need to finish handling tape wrapping) and I doubt it's going to work, but:
I don't understand this language at ALL.
It's even more complicated than C...
If I deserve one, give me one.
You should try BrainF*ck. That'll teach you. :tongue.gif:
This is Hello, World! in BrainF*ck.
I partially based the command set on 6052 assembly. Maybe looking some of that up will help?
I know.
It's the lowest high-level language out there.
I think Gigyas has invaded the digital world now. 0_o
If I deserve one, give me one.
Anyway, some form of tutorial coming up.
If I deserve one, give me one.
It's coming along. Read some of this, it's a tutorial for NES 6052 assembly, and should give you an idea on how registers and self-modification come into play.
Thanks much, but how so?
Also, http://esoteric.voxelperfect.net/wiki/M-code
:biggrin.gif:
Because it's fun.
Anyway, there's a bug with the interpreter that renders anything with comments pretty much impossible to handle. I'm uploading a fix now.
EDIT: redownload from same link if you care for the fix.