Skip to content

Instantly share code, notes, and snippets.

@tangentstorm

tangentstorm/gist:10699845

Last active Aug 29, 2015
Embed
What would you like to do?
a colorforth-like thing in coffeescript
# colorforth inspired programming system
module 'colorcode'
imports ['b4', 'key'], ()->
$jq('#rhs')
.html(
'''
<div id="rhs-block" tabindex="0"/>
<div id="rhs-status" tabindex="1"/>
''')
.css
background : '#121212'
'font-family': 'consolas'
'font-size' : '12pt'
'color' : '#ccc'
'outline-style' : 'none'
rhs = $d3.select '#rhs-block'
rhs.style
height: "640px"
$d3.select('#rhs-status').style('background':'red').text '??'
kTESTBLOCK = [
# color names:
0x20000000, 0x21000001, 0x22000002, 0x23000003
0x24000004, 0x25000005, 0x26000006, 0x27000007
0x28000008, 0x29000009, 0x2A00000A, 0x2B00000B
0x2C00000C, 0x2D00000D, 0x2E00000E, 0x2F00000F
# a copy of block 38 from arrayforth
# <newline> |w "- clock" <newline>
0x20003800, 0x6F00000d, 0x2F003801, 0x68000000
# |r "sec" |w "-n" |g "utime" |y "60 60"
0x61023973, 0x6F000b8d, 0x22003802, 0xDB00003c, 0xDB00003c
# |y "* 24 *" |g "mod" ;
0x6B00000a, 0xdb000018, 0x6B00000a, 0x62024bed, 0x6200001b
# <newline> |r "minute" |w "-n" |g "sec 60 / ;"
0x68000000, 0x21003803, 0x6F000b8d, 0x62023973, 0xd200003c
0x6200000f, 0x6200001b
]
class BlockDB
constructor: ->
@db = null
@ready = false
@sname = 'blocks'
@version = 2
# callbacks:
OnInitialize: =>
OnBlockLoaded: (block)=>
init: =>
# console.log 'in BlockDB.init'
rq = window.indexedDB.open @sname, @version
rq.onupgradeneeded = (e)=>
console.log '* upgrading db to version ' + @version
@db = e.target.result
@db.createObjectStore(@sname, autoIncrement: true)
rq.onsuccess = (e)=>
@db = e.target.result
#console.log 'db loaded:', @db
tx = @db.transaction([@sname], 'readwrite')
os = tx.objectStore(@sname)
os.count()
.onsuccess = (e)=>
if e.target.result == 0
os.add(kTESTBLOCK).onsuccess = (e)=> @OnInitialize()
else @OnInitialize()
rq.onerror = (e)=>
console.log 'error!!!'
console.log e
rq.onblocked = (e)=>
console.log 'blocked!!!'
console.log e
window.rq = rq
console.log rq
loadBlock: (n)=>
rq = @db.transaction([@sname], 'readwrite')
.objectStore(@sname)
.get(n)
rq.onsuccess = (e)=>
@OnBlockLoaded(n, e.target.result)
# encoder
# hex(int(''.join(bin(ord(ch)-32)[2:].zfill(6) for ch in reversed(s)), 2))
pal =
k:0x0, r:0x1, g:0x2, y:0x3, b:0x4, m:0x5, c:0x6, w:0x7
K:0x8, R:0x9, G:0xA, Y:0xB, B:0xC, M:0xD, C:0xE, W:0xF
lex =
0x0:'k', 0x1:'r', 0x2:'g', 0x3:'y', 0x4:'b', 0x5:'m', 0x6:'c', 0x7:'w'
0x8:'K', 0x9:'R', 0xA:'G', 0xB:'Y', 0xC:'B', 0xD:'M', 0xE:'C', 0xF:'W'
0x3800: 'block 38 from arrayforth:'
0x3801: 'clock', 0x3802: "utime", 0x3803:'minute'
sixbit = (word) ->
res = ''
while (bits = word & 0x3F)
res += String.fromCharCode(bits + 32).toLowerCase()
word >>>= 6
return res
decode = (code) ->
# first byte is the meta-data, rest is the value
word = code & 0x00FFFFFF
meta = (code & 0xFF000000) >>> 24
kind = (meta & 0xF0) >>> 4
color = (meta & 0x0F)
switch kind
when 0xf then "0x#{ word.toString 16 }"
when 0xd then "#{word.toString 10}"
when 0x2 then lex[ word ]
when 0x6 then sixbit(word)
else "<0x#{ kind.toString 16 }>"
class ColorMemo
constructor: ->
@cursor = 1
@block = []
@nodes = []
showBlock: (bnum, block)=>
breakNext = false
@block = block
@nodes = rhs.selectAll('code').data(block)
@nodes.enter()
.append('code')
.style
'padding' : '2px'
'margin' : '2px'
'margin-right': '0px' # because of the cursor
'font-family' : 'consolas'
'font-size' : '14pt'
'display' : 'block'
'outline' : 'none' # to hide tabindex focus
float: (d)->
if (d>>24 & 0xF) then 'left' else 'none'
clear: (d)->
if breakNext then breakNext = false; result = 'left'
else result = switch (d>>24 & 0xF)
when 0 then breakNext = true ; 'left'
when 8 then breakNext = true ; 'none'
else 'none'
color: (d)->
switch (d >>> 24) & 0x0F
when pal.k then 'black' ; when pal.K then '#666'
when pal.r then '#c22' ; when pal.R then '#f44'
when pal.g then '#090' ; when pal.G then '#0e0'
when pal.y then '#a83' ; when pal.Y then '#fc4'
when pal.b then '#33f' ; when pal.B then '#66f'
when pal.m then '#a0a' ; when pal.M then '#d4d'
when pal.c then '#299' ; when pal.C then '#4dd'
when pal.w then '#aaa' ; when pal.W then '#fff'
else '#888'
.html (d)->
decode(d)
.on 'click', (d, i)=>
@cursor = i; @drawCursor()
# end of @nodes.enter()
@drawCursor()
$jq('#rhs-block').focus()
drawCursor: =>
@nodes.attr 'class', (d, i)=>
rev = (d>>24 & 0x0f)==0
if i == @cursor then (if rev then 'rev cur' else 'cur')
else if rev then 'rev' else 'word'
keyDown: (e)=>
switch e.which
when $key.RIGHT then @cursor++
when $key.LEFT then @cursor--
when $key.UP then @cursor -= 5
when $key.DOWN then @cursor += 5
if @cursor >= @block.length then @cursor = @block.length-1
if @cursor < 0 then @cursor = 0
@drawCursor()
db = new BlockDB
cm = new ColorMemo
db.OnBlockLoaded = cm.showBlock
db.OnInitialize = ->
$colorcode.db = db
$colorcode.cm = cm
$jq("#rhs").off 'keydown'
$jq("#rhs").on 'keydown', cm.keyDown
console.log '--- ready to load the first block. ---'
db.loadBlock(1)
$jq("#rhs-content").focus()
$d3.select('#rhs-status').style('background':'green').text 'ok'
$d3.select('#rhs-status').style('background':'gold').text '...'
console.log 'initializing the db.'
db.init()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment