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
You can’t perform that action at this time.