Skip to content

Instantly share code, notes, and snippets.

@gerhardberger
Created March 28, 2017 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gerhardberger/fd768c649f97e5a60a2f6dcecc6ffa40 to your computer and use it in GitHub Desktop.
Save gerhardberger/fd768c649f97e5a60a2f6dcecc6ffa40 to your computer and use it in GitHub Desktop.
function getMajorType (tape) {
if (tape[0] === UINT) return new UInt()
if (tape[0] === ARR) return new Arr()
// other major types...
}
// Solution 1.
// Here all the major types are one class and states are handled in them, but
// some things, such as handling infinite sequences are harder to achieve.
class State {
constructor () {
this.state = 'AI'
}
}
class UInt extends State {
run (tape, handler) {
if (this.state === 'AI') {
this.n = 4
this.state = 'READ'
return [this]
} else if (this.state === 'READ') {
// read bytes
handler(1234)
return []
}
}
}
class Arr extends State {
run (tape, handler) {
if (this.state === 'AI') {
this.len = 2
this.state = 'READ'
handler('[')
return [getMajorType(tape), this]
} else if (this.state === 'READ') {
if (this.inf) {
handler(',')
return [getMajorType(tape), this]
}
if (this.len === 0) {
handler(']')
return []
}
this.len--
handler(',')
return [getMajorType(tape), this]
}
}
}
// Solution 2.
// Here all the major types are broken down into little classes, so they're are
// easier to put onto the stack, for example to be able to handle infinite
// sequences.
class MT {
run (tape, stack, handler) {
// read major type
return [ new MajorType() ] // `new UIntAI()` or `new ArrAI()`
}
}
class UIntRead {
constructor (n) {
this.n = n
}
run (tape, stack, handler) {
// read this.n byte
handler(8)
return []
}
}
class UIntAI {
run (tape, stack, handler) {
// read size
return [ new UIntRead(4) ]
}
}
class ArrRead {
constructor (n) {
this.n = n
}
run (tape, stack, handler) {
if (this.n === 0) return []
return [ new MT(), new ArrRead(this.n - 1) ]
}
}
class ArrAI {
run (tape, stack, handler) {
// read size
return [ new MT(), new ArrRead(2) ]
}
}
// Initializations
let tape = [1, [2, 3]]
let stack = [getMajorType(tape)] // or [new MT()]
let done = false
// The main loop
while (!done) {
// run the state on top of the stack. this returns a list of new states that
// should be put on top of the stack.
const toPush = stack.peek().run(tape, stack, handler)
stack.pop() // always remove the top of the stack
stack.pushN(toPush)
}
[
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment