Last active
January 4, 2016 20:29
-
-
Save grejppi/8673986 to your computer and use it in GitHub Desktop.
Implementation for the new programming language 'Keybash'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import os | |
import keybash | |
ap = argparse.ArgumentParser(description='Brainfuck/Keybash translator') | |
ap.add_argument('file') | |
args = ap.parse_args() | |
ext = os.path.splitext(args.file)[1].lower() | |
with open(args.file) as f: | |
print({'.b': keybash.bf2kb, '.bf': keybash.bf2kb, '.kb': keybash.kb2bf}[ext](f.read())) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Keybash/Brainfuck translator | |
# | |
# This program is free software. It comes without any warranty, to | |
# the extent permitted by applicable law. You can redistribute it | |
# and/or modify it under the terms of the Do What The Fuck You Want | |
# To Public License, Version 2, as published by Sam Hocevar. See | |
# http://www.wtfpl.net/ for more details. | |
# | |
# Keybash is a language with a natural and intuitive syntax that is | |
# very easy to write and pleasant to read. It also translates directly | |
# to Brainfuck, which means it is already usable on a wide range of | |
# platforms. | |
# | |
# Hello World is just: | |
# | |
# fgdhjlkasfadhjlkasfjlkasfgdhjlfgdhasjflghdkasdkagdhjlkasdlkasdkasdahjlkasfgdhjlkasfhagdhjafdjksgjksghlafdlfgjsd | |
# | |
# This Python module provides a way to translate between the two languages. | |
bfchars = ' +-.><,[]' | |
keybash = 'sfgdhjlka' | |
def stripcomments(source): | |
return ''.join([c for c in source if c in bfchars]).replace(' ', '') | |
def bf2kb(source, keepdiffs=False): | |
source = stripcomments(source) | |
diffs = [] | |
for char in source: | |
diff = bfchars.find(char) | |
if diff != -1: | |
diffs.append(diff) | |
newsource = [] | |
index = 0 | |
for d in diffs: | |
index = (index + d) % len(keybash) | |
c = keybash[index] | |
newsource.append(c) | |
r = ''.join(newsource) | |
if keepdiffs: | |
return r, diffs | |
return r | |
def kb2bf(source): | |
diffs = [] | |
old = '' | |
for char in source: | |
diffs.append((keybash.find(char) - keybash.find(old)) % len(keybash)) | |
old = char | |
newsource = [bfchars[d] for d in diffs] | |
return ''.join(newsource) | |
if __name__ == '__main__': | |
source = ''' | |
+++++ +++++ initialize counter (cell #0) to 10 | |
[ use loop to set the next four cells to 70/100/30/10 | |
> +++++ ++ add 7 to cell #1 | |
> +++++ +++++ add 10 to cell #2 | |
> +++ add 3 to cell #3 | |
> + add 1 to cell #4 | |
<<<< - decrement counter (cell #0) | |
] | |
> ++ . print 'H' | |
> + . print 'e' | |
+++++ ++ . print 'l' | |
. print 'l' | |
+++ . print 'o' | |
> ++ . print ' ' | |
<< +++++ +++++ +++++ . print 'W' | |
> . print 'o' | |
+++ . print 'r' | |
----- - . print 'l' | |
----- --- . print 'd' | |
> + . print '!' | |
> . print '\n' | |
''' | |
source2 = ''' | |
-,+[ Read first character and start outer character reading loop | |
-[ Skip forward if character is 0 | |
>>++++[>++++++++<-] Set up divisor (32) for division loop | |
(MEMORY LAYOUT: dividend copy remainder divisor quotient zero zero) | |
<+<-[ Set up dividend (x minus 1) and enter division loop | |
>+>+>-[>>>] Increase copy and remainder / reduce divisor / Normal case: skip forward | |
<[[>+<-]>>+>] Special case: move remainder back to divisor and increase quotient | |
<<<<<- Decrement dividend | |
] End division loop | |
]>>>[-]+ End skip loop; zero former divisor and reuse space for a flag | |
>--[-[<->+++[-]]]<[ Zero that flag unless quotient was 2 or 3; zero quotient; check flag | |
++++++++++++<[ If flag then set up divisor (13) for second division loop | |
(MEMORY LAYOUT: zero copy dividend divisor remainder quotient zero zero) | |
>-[>+>>] Reduce divisor; Normal case: increase remainder | |
>[+[<+>-]>+>>] Special case: increase remainder / move it back to divisor / increase quotient | |
<<<<<- Decrease dividend | |
] End division loop | |
>>[<+>-] Add remainder back to divisor to get a useful 13 | |
>[ Skip forward if quotient was 0 | |
-[ Decrement quotient and skip forward if quotient was 1 | |
-<<[-]>> Zero quotient and divisor if quotient was 2 | |
]<<[<<->>-]>> Zero divisor and subtract 13 from copy if quotient was 1 | |
]<<[<<+>>-] Zero divisor and add 13 to copy if quotient was 0 | |
] End outer skip loop (jump to here if ((character minus 1)/32) was not 2 or 3) | |
<[-] Clear remainder from first division if second division was skipped | |
<.[-] Output ROT13ed character from copy and clear it | |
<-,+ Read next character | |
] | |
''' | |
ssource = stripcomments(source) | |
ssource2 = stripcomments(source2) | |
a, adiff = bf2kb(source, True) | |
b, bdiff = bf2kb(source2, True) | |
aback = kb2bf(a) | |
bback = kb2bf(b) | |
assert ssource == aback | |
assert ssource2 == bback | |
assert kb2bf(bf2kb(source)) == ssource | |
assert kb2bf(bf2kb(source2)) == ssource2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment