Skip to content

Instantly share code, notes, and snippets.

@grejppi
Last active January 4, 2016 20:29
Show Gist options
  • Save grejppi/8673986 to your computer and use it in GitHub Desktop.
Save grejppi/8673986 to your computer and use it in GitHub Desktop.
Implementation for the new programming language 'Keybash'
#!/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()))
# 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