stackGen
by not important
CoffeeScript
# imperative stack-based programming language, like Forth
# http://docs.oracle.com/cd/E19455-01/816-1177-10/fthtools.html
class StackProg
words: {}
constructor: ->
run: (sourceCode, state, stack = []) ->
defaultOptions =
variables: {}
functions: {}
operations: []
store: []
returnStack: []
storeIndex: 0
state = state || defaultOptions
state.operations = sourceCode.replace(/(\n|\t)/g, ' ').split(' ').concat state.operations
while operation = state.operations.shift()
if operation is 'variable'
name = state.operations.shift()
state.variables[name] = null
else if state.functions[operation] isnt undefined
state.functions[operation]()
else if state.variables[operation] isnt undefined
stack.unshift operation
else
@evaluate state, stack, operation
stack.pop()
evaluate: (state, stack, operation) ->
if !isNaN(+operation)
@words['\d+'] state, stack, +operation
else if operation.charAt(0) is '"'
value = operation.match /\s*\"(.*?)\"/
value = value || []
@words['\s*\"(.*?)\"'].call this, state, stack, value[1]
else
if typeof @words[operation] is 'string'
stack.unshift @run @words[operation], state, stack
else
if @words[operation]
@words[operation].call this, state, stack
else
throw "Error: Undefined command '#{operation}'"
StackProg::words['\d+'] = (state, stack, val) ->
stack.unshift val
StackProg::words['-'] = (state, stack) ->
a = stack.shift()
b = stack.shift()
stack.unshift a - b
StackProg::words['+'] = (state, stack) ->
a = stack.shift()
b = stack.shift()
stack.unshift a + b
StackProg::words['*'] =...