cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              .container
  .row
    .col-md-12
      %form.form-inline#inputBuffer
        .input-group
          %input.form-control{:type => 'text'}
          %span.input-group-btn
            %button.btn.btn-default.btn-danger#clear
              Clear Output
  .row
    .col-md-12
      .output-buffer#outputBuffer
  .row
    .col-md-12
      %h3
        Commands to try
      %ul.list-unstyled
        %li
          %pre
            2 2 + .
        %li
          %pre
            cr 12 tower
        %li
          %pre
            "hello, world!" reverse
        %li
          %pre
            cr 52 48 19 82 38 5 20 graph

#mocha

            
          
!
            
              body {
  margin-top: 60px;
}

.output-buffer {
  margin-top: 16px;
}
            
          
!
            
              class StackProg
  constructor: (@words, state) ->
    state or= {}
    {stack, store, variables, functions, inputStack, returnStack, outputStack} = state
    @state =
      stack: stack or []
      store: store or []
      variables: variables or {}
      functions: functions or {}
      inputStack: inputStack or []
      returnStack: returnStack or []
      outputStack: outputStack or []
    @commands = []

  output: ->
    string = @state.outputStack.join ''
    @state.outputStack = []
    string

  run: (rawSource) -> # method is too long, refactor
    @commands = rawSource.replace(/(\n|\t)/g, ' ').replace(/\s+/g, ' ').split(' ')
    lookingForString = false
    while command = @commands.shift()
      # begin collect string
      if (command.charAt(0) is '"') and (command.charAt(command.length - 1) isnt '"')
        string = command
        lookingForString = true
        continue
      if lookingForString and (command.charAt(command.length - 1) is '"')
        lookingForString = false
        string = "#{string} #{command}"
      if lookingForString
        string = string || ''
        string = "#{string} #{command}"
        continue
      # end collect string
      command = if string then string else command
      matchFound = false
      if @state.variables[command] isnt undefined
        @state.stack.unshift command
        matchFound = true
      else if @state.functions[command]?
        @state.functions[command]()
        matchFound = true
      else if typeof @words[command] is 'string'
        frame = new StackProg @words, @state
        frame.run @words[command]
        matchFound = true
      else
        for word, fn of @words
          pattern = new RegExp word
          matches = command.match pattern
          if matches?
            fn.apply this, matches
            matchFound = true
            break
      unless matchFound
        throw "Error: Undefined command '#{command}'"
      string = ''
    this

words = {}

# a -- a/2
words['2/'] = ->
  [a] = @state.stack.splice 0, 2
  @state.stack.unshift +a / 2

# -- size addr
words['"(.*?)"'] = (_first, string) ->
  @state.stack.unshift string.length, @state.store.length
  @state.inputStack = @state.inputStack.concat string.split ''

# --
words['variable'] = ->
  [name] = @commands.splice 0, 1
  @state.variables[name] = null

# a b -- b a b
words['over'] = ->
  [_a, b] = @state.stack
  @state.stack.unshift b

# val --
words['>r'] = ->
  [val] = @state.stack.splice 0, 1
  @state.returnStack.unshift val

# -- val
words['r>'] = ->
  [val] = @state.returnStack.splice 0, 1
  @state.stack.unshift val

# addr -- addr+1
words['char\\+'] = ->
  [addr] = @state.stack.splice 0, 1
  @state.stack.unshift +addr + 1

# n -- n+1
words['chars'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift +n + 1

# n -- n-1
words['cell-'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift +n - 1

# n -- n+1
words['cell\\+'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift +n + 1

# n -- n
words['cells'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift +n

# a b -- b a
words['swap'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift b, a

# val --
words['\\.'] = ->
  [val] = @state.stack.splice 0, 1
  @state.outputStack.push val

# -- true
words['true'] = ->
  @state.stack.unshift true

# -- false
words['false'] = ->
  @state.stack.unshift false

# size addr --
words['cmove'] = ->
  [size, addr] = @state.stack.splice 0, 2
  for index in [0...size]
    [val] = @state.inputStack.splice 0, 1
    if val
      @state.store[addr + index] = val

# addr byte --
words['c!'] = ->
  [addr, byte] = @state.stack.splice 0, 2
  @state.store[addr] = byte

# addr -- byte
words['c@'] = ->
  [addr] = @state.stack.splice 0, 1
  @state.stack.unshift @state.store[addr]

# addr val --
words['!'] = ->
  [addr, byte] = @state.stack.splice 0, 2
  @state.variables[addr] = byte

# addr -- val
words['@'] = ->
  [addr] = @state.stack.splice 0, 1
  val = @state.variables[addr]
  @state.stack.unshift val

# a b -- b<=a
words['<='] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift b <= a

# a b -- b>=a
words['>='] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift b >= a

# a b -- b>a
words['>'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift b > a

# a b -- b<a
words['<'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift b < a

# a b --
words['2drop'] = ->
  @state.stack.splice 0, 2

# a --
words['drop'] = ->
  @state.stack.splice 0, 1
# a b -- a b a b
words['2dup'] = ->
  [a, b] = @state.stack
  @state.stack.unshift a, b

# a b -- a b a b
words['dup'] = ->
  [a] = @state.stack
  @state.stack.unshift a

# end start --
words['do'] = ->
  [start, end] = @state.stack.splice 0, 2
  ops = []
  while op = @commands.shift()
    break if op is 'loop'
    ops.push op
  opsCommand = ops.join ' '
  frame = new StackProg @words, @state
  for index in [start...end]
    iterationOps = opsCommand.replace /\bi\b/ig, index
    frame.run iterationOps

# name, size, type --
words['create'] = ->
  return unless @commands[3] is 'allot'
  [name, size, type, allot] = @commands.splice 0, 4
  frame = new StackProg @words, @state
  frame.run [size, type, allot].join ' '
  @state.functions[name] = ((words, state, size, type, allot) ->
    addr = undefined
    ->
      unless addr?
        frame = new StackProg words, state
        frame.run [size, type, allot].join ' '
        addr = state.store.length
        state.store = state.store.concat (new Array +size)
      state.stack.unshift addr
  )(@words, @state, size, type, allot)

# size --
words['allot'] = ->
  [size] = @state.stack.splice 0, 1
  @state.store = @state.store.concat (new Array +size)

# flag --
words['if'] = ->
  [flag] = @state.stack.splice 0, 1
  trueOps = []
  hasElse = false
  while op = @commands.shift()
    break if op is 'then'
    if op is 'else'
      hasElse = true
      break
    trueOps.push op
  if hasElse
    elseOps = []
    while op = @commands.shift()
      break if op is 'then'
      elseOps.push op
  frame = new StackProg @words, @state
  if flag
    frame.run trueOps.join ' '
  else if !flag and hasElse
    frame.run elseOps.join ' '

# --
words[':'] = ->
  ops = []
  name = @commands.shift()
  while op = @commands.shift()
    break if op is ';'
    ops.push op
  @words[name] = ops.join ' '

# --
words['\\('] = ->
  while op = @commands.shift()
    break if op is ')'

# f --
words['begin'] = ->
  conditionOps = []
  while op = @commands.shift()
    break if op is 'while'
    conditionOps.unshift op
  blockOps = []
  while op = @commands.shift()
    break if op is 'repeat'
    blockOps.unshift op
  frame = new StackProg @words, @state
  frame.run conditionOps.join ' '

# addr -- byte addr+1
words['count'] = ->
  [addr] = @state.stack.splice 0, 1
  @state.stack.unshift @state.store[addr], addr + 1

# a b c -- b c a
words['rot'] = ->
  [a, b, c] = @state.stack.splice 0, 3
  @state.stack.unshift b, c, a

# size addr --
words['type'] = ->
  [size, addr] = @state.stack.splice 0, 2
  string = ''
  for index in [addr...(addr + size)]
    string += @state.store[index]
  @state.outputStack.push string

# n = n
words['negate'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift n * -1

# a b = flag
words['and'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift a && b

# ... = ???
words['recurse'] = ->

# --
words['cr'] = ->
  @state.outputStack.push '\n'

# n -- n-1
words['1-'] = ->
  [n] = @state.stack.splice 0, 1
  @state.stack.unshift n - 1

# start len -- start+len start
words['bounds'] = ->
  [start, len] = @state.stack.splice 0, 2
  @state.stack.unshift start + len, start

# a b -- a+b
words['\\+'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +a + +b

# a b -- b-a
words['-'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +b - +a

# a b -- a*b
words['\\*'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +a * +b

# a b -- b/a
words['/'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +b / +a

# a b -- flag
words['='] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +a == +b

# a b -- r
words['mod'] = ->
  [a, b] = @state.stack.splice 0, 2
  @state.stack.unshift +b % +a

# char --
words['emit'] = ->
  [charCode] = @state.stack.splice 0, 1
  @state.outputStack.push String.fromCharCode charCode

# -- val
words['(\\d+)'] = (val) ->
  @state.stack.unshift +val

mocha.setup 'bdd'
expect = chai.expect

describe 'StackProg', ->
  stackProg = undefined

  beforeEach ->
    stackProg = new StackProg words

  describe 'run method', ->
    it 'exists', ->
      expect(stackProg.run).to.not.equal undefined

  describe 'commands', ->
    it 'is an array', ->
      expect(_.isArray stackProg.commands).to.equal true

  describe 'functions', ->
    it 'is an object', ->
      expect(_.isObject stackProg.state.functions).to.equal true

  describe 'variables', ->
    it 'is an object', ->
      expect(_.isObject stackProg.state.variables).to.equal true

  describe 'store', ->
    it 'is an array', ->
      expect(_.isArray stackProg.state.store).to.equal true

  describe 'stack', ->
    it 'is an array', ->
      expect(_.isArray stackProg.state.stack).to.equal true

  describe 'inputStack', ->
    it 'is an array', ->
      expect(_.isArray stackProg.state.inputStack).to.equal true

  describe 'returnStack', ->
    it 'is an array', ->
      expect(_.isArray stackProg.state.returnStack).to.equal true

  describe 'words', ->
    it 'exists', ->
      expect(_.isObject stackProg.words).to.equal true

  describe 'output', ->
    it 'exists', ->
      expect(stackProg.output()).to.equal ''

describe 'StackProg::words', ->
  stackProg = undefined

  beforeEach ->
    stackProg = new StackProg words

  describe 'true', ->
    it '-- true', ->
      stackProg.run 'true'
      expect(stackProg.state.stack).to.deep.equal [true]

  describe 'false', ->
    it '-- false', ->
      stackProg.run 'false'
      expect(stackProg.state.stack).to.deep.equal [false]

  describe '(\\d+)', ->
    it '-- a', ->
      stackProg.run '2 5'
      expect(stackProg.state.stack).to.deep.equal [5, 2]

  describe 'cell-', ->
    it 'n -- n-1', ->
      stackProg.run '2 cell-'
      expect(stackProg.state.stack).to.deep.equal [1]

  describe 'cell+', ->
    it 'n -- n+1', ->
      stackProg.run '1 cell+'
      expect(stackProg.state.stack).to.deep.equal [2]

  describe 'cells', ->
    it 'n -- n', ->
      stackProg.run '4 cells'
      expect(stackProg.state.stack).to.deep.equal [4]

  describe '".*"', ->
    it '-- size addr', ->
      stackProg.run '"asdf"'
      expect(stackProg.state.inputStack).to.deep.equal 'asdf'.split ''
      expect(stackProg.state.stack).to.deep.equal [4, 0]

    it '-- size addr # multi part string', ->
      string = 'lorem ipsum dolor sit amet'
      stackProg.run "\"#{string}\""
      expect(stackProg.state.inputStack).to.deep.equal string.split ''
      expect(stackProg.state.stack).to.deep.equal [string.length, 0]

  describe 'do', ->
    it 'end start --', ->
      stackProg.run '3 0 do i 1 + loop'
      expect(stackProg.state.stack).to.deep.equal [3, 2, 1]

  describe 'allot', ->
    it 'size --', ->
      stackProg.run '33 allot'
      expect(stackProg.state.store.length).to.equal 33

  describe 'create', ->
    it 'create (name) (size) (type) allot', ->
      stackProg.run 'create str 10 chars allot'
      expect(stackProg.state.functions['str']).to.not.equal undefined

    it '-- addr', ->
      stackProg.run """
      create str 10 chars allot
      str
      str
      """
      expect(stackProg.state.stack).to.deep.equal [0, 0]

  describe 'if', ->
    describe 'if...then', ->
      it 'flag -- # true', ->
        stackProg.run """
        true if 1 then 3
        """
        expect(stackProg.state.stack).to.deep.equal [3, 1]

      it 'flag -- # false', ->
        stackProg.run """
        false if 1 then 3
        """
        expect(stackProg.state.stack).to.deep.equal [3]

    describe 'if...else...then', ->
      it 'flag -- # true', ->
        stackProg.run """
        true if 1 else 2 then 3
        """
        expect(stackProg.state.stack).to.deep.equal [3, 1]

      it 'flag -- # false', ->
        stackProg.run """
        false if 1 else 2 then 3
        """
        expect(stackProg.state.stack).to.deep.equal [3, 2]

  describe 'over', ->
    it 'a b -- a b a', ->
      stackProg.run '1 2 over'
      expect(stackProg.state.stack).to.deep.equal [1, 2, 1]

  describe '>r', ->
    it 'a --', ->
      stackProg.run '1 2 >r'
      expect(stackProg.state.stack).to.deep.equal [1]
      expect(stackProg.state.returnStack).to.deep.equal [2]

  describe 'r>', ->
    it '-- a ', ->
      stackProg.run '2 >r r>'
      expect(stackProg.state.stack).to.deep.equal [2]
      expect(stackProg.state.returnStack).to.deep.equal []

  describe '(', ->
    it '--', ->
      stackProg.run """
      2 3 * ( a b -- c )
      2 + ( a -- b )
      """
      expect(stackProg.state.stack).to.deep.equal [8]

  describe 'char+', ->
    it 'addr1 -- addr2', ->
      stackProg.run '0 char+'
      expect(stackProg.state.stack).to.deep.equal [1]

  describe 'chars', ->
    it 'n -- n', ->
      stackProg.run '0 chars'
      expect(stackProg.state.stack).to.deep.equal [1]

  describe 'swap', ->
    it 'a b -- b a', ->
      stackProg.run '1 2 swap'
      expect(stackProg.state.stack).to.deep.equal [1, 2]

  describe 'cmove', ->
    it 'addr size --', ->
      stackProg.run """
      "hello world" char+ cmove
      """
      expect(stackProg.state.stack).to.deep.equal []
      expect(' ' + stackProg.state.store.join('')).to.deep.equal ' hello world'

  describe 'c!', ->
    it 'byte addr --', ->
      stackProg.run """
      1 3 c!
      """
      expect(stackProg.state.store[3]).to.equal 1

  describe 'c@', ->
    it 'addr -- byte', ->
      stackProg.run """
      : place over over >r >r char+ swap chars cmove r> r> c! ;
      create str 32 chars allot
      "hello" str place
      1 c@
      """
      expect(stackProg.state.stack[0]).to.equal 'h'

  describe '>', ->
    it 'a b -- b>a', ->
      stackProg.run '3 2 >'
      expect(stackProg.state.stack[0]).to.equal true
      stackProg.run '2 3 >'
      expect(stackProg.state.stack[0]).to.equal false

  describe '<', ->
    it 'a b -- b<a', ->
      stackProg.run '3 2 <'
      expect(stackProg.state.stack[0]).to.equal false
      stackProg.run '2 3 <'
      expect(stackProg.state.stack[0]).to.equal true

  describe 'count', ->
    it 'pstr -- addr +n', ->
      stackProg.run """
      : place over over >r >r char+ swap chars cmove r> r> c! ;
      create str 32 chars allot
      "hello world" str place count
      """
      [size, addr] = stackProg.state.stack
      expect(size).to.equal 11
      expect(addr).to.equal 1

  describe 'type', ->
    it 'size addr --', ->
      stackProg.run """
      : place over over >r >r char+ swap chars cmove r> r> c! ;
      create str 32 chars allot
      "hello world" str place count type
      """
      expect(stackProg.state.stack).to.deep.equal []
      expect(stackProg.output()).to.equal 'hello world'

  describe 'variable', ->
    it '--', ->
      stackProg.run 'variable str'
      expect(stackProg.state.variables['str']).to.equal null

  describe '!', ->
    it 'val addr --', ->
      stackProg.run """
      variable var
      6 var !
      """
      expect(stackProg.state.variables['var']).to.equal 6

  describe '@', ->
    it 'addr -- byte', ->
      stackProg.run """
      variable var
      9 var ! var @
      """
      expect(stackProg.state.stack[0]).to.equal 9

    it 'addr -- byte # prints', ->
      stackProg.run """
      variable var var
      9 var !
      var @ .
      """
      expect(stackProg.output()).to.equal '9'

  describe '.', ->
    it 'val --', ->
      stackProg.run '1 .'
      expect(stackProg.state.stack).to.deep.equal []
      expect(stackProg.output()).to.equal '1'

    it 'val -- # multi element', ->
      stackProg.run '1 2 . .'
      expect(stackProg.output()).to.equal '21'

  describe ':', ->
    it '--', ->
      stackProg.run """
      : alpha 97 emit ;
      1 . alpha 2 .
      """
      expect(stackProg.output()).to.equal '1a2'

  describe 'cr', ->
    it '--', ->
      stackProg.run '1 2 . cr .'
      expect(stackProg.output()).to.equal '2\n1'

  describe 'dup', ->
    it 'a -- a a', ->
      stackProg.run '1 2 dup'
      expect(stackProg.state.stack).to.deep.equal [2, 2, 1]

  describe '2dup', ->
    it 'a b -- a b a b', ->
      stackProg.run '1 2 2dup'
      expect(stackProg.state.stack).to.deep.equal [2, 1, 2, 1]

  describe 'rot', ->
    it 'a b c -- b c a', ->
      stackProg.run '1 2 3 rot'
      expect(stackProg.state.stack).to.deep.equal [2, 1, 3]

  describe '1-', ->
    it 'n1 -- n2', ->
      stackProg.run '3 1-'
      expect(stackProg.state.stack).to.deep.equal [2]

  describe 'drop', ->
    it 'a --', ->
      stackProg.run '2 3 drop'
      expect(stackProg.state.stack).to.deep.equal [2]

  describe '2drop', ->
    it 'a b --', ->
      stackProg.run '2 3 5 2drop'
      expect(stackProg.state.stack).to.deep.equal [2]

  describe 'bounds', ->
    it 'start len -- start+len start', ->
      stackProg.run '5 2 bounds'
      expect(stackProg.state.stack).to.deep.equal [7, 2]

  describe '=', ->
    it 'a b -- flag # true', ->
      stackProg.run '6 2 ='
      expect(stackProg.state.stack).to.deep.equal [false]

    it 'a b -- flag # false', ->
      stackProg.run '2 2 ='
      expect(stackProg.state.stack).to.deep.equal [true]

  describe '+', ->
    it 'a b -- a+b', ->
      stackProg.run '6 2 +'
      expect(stackProg.state.stack).to.deep.equal [8]

  describe '-', ->
    it 'a b -- b-a', ->
      stackProg.run '6 2 -'
      expect(stackProg.state.stack).to.deep.equal [4]

  describe '\*', ->
    it 'a b -- a*b', ->
      stackProg.run '6 2 *'
      expect(stackProg.state.stack).to.deep.equal [12]

  describe '2/', ->
    it 'a -- a/2', ->
      stackProg.run '6 2/'
      expect(stackProg.state.stack).to.deep.equal [3]

  describe '/', ->
    it 'a b -- b/a', ->
      stackProg.run '6 2 /'
      expect(stackProg.state.stack).to.deep.equal [3]

  describe 'mod', ->
    it 'a b -- r', ->
      stackProg.run '12 5 mod'
      expect(stackProg.state.stack).to.deep.equal [2]

  describe 'emit', ->
    it 'char --', ->
      stackProg.run '42 emit'
      expect(stackProg.output()).to.equal '*'

  describe 'and', ->
    it 'a b -- flag # true', ->
      stackProg.run 'true true and'
      expect(stackProg.state.stack).to.deep.equal [true]

    it 'a b -- flag # false', ->
      stackProg.run 'false true and'
      expect(stackProg.state.stack).to.deep.equal [false]

  describe 'negate', ->
    it 'a -- b', ->
      stackProg.run '3 negate'
      expect(stackProg.state.stack).to.deep.equal [-3]

  describe 'strings', ->
    it 'works with multiple strings', ->
      stackProg.run """
      create str1 32 chars allot
      create str2 32 chars allot
      """
      stackProg.run '"hello" str1'
      expect(stackProg.state.stack).to.deep.equal [0, 5, 0]
      stackProg.run 'place'
      expect(stackProg.state.stack).to.deep.equal [0]
      stackProg.run 'count'
      expect(stackProg.state.stack).to.deep.equal [5, 1]
      stackProg.run 'type'
      expect(stackProg.output()).to.equal 'hello'
      stackProg.run '"goodbye" str2'
      expect(stackProg.state.stack).to.deep.equal [32, 7, 32]
      stackProg.run 'place'
      expect(stackProg.state.stack).to.deep.equal [32]
      stackProg.run 'count'
      expect(stackProg.state.stack).to.deep.equal [7, 33]
      stackProg.run 'type'
      expect(stackProg.output()).to.equal 'goodbye'

mocha.run()

$ ->
  s = new StackProg words
  s.run """
  : place over over >r >r char+ swap chars cmove r> r> c! ;
  : tower dup roof wall ; ( size -- )
  : roof 2 / dup 1 do dup i - blankRow i fillRoof i fillRoof cr loop drop ; ( size -- )
  : wall dup 0 do dup i 2 mod 1 = if floor else fillRow then cr loop drop ; ( size -- )
  : fillRoof 0 do tile loop ; ( size -- )
  : fillRow 0 do brick loop ; ( size -- )
  : floor 0 do i 2 mod 0 = if brick else window then loop ; ( size -- )
  : blankRow 0 do space loop ; ( size -- )
  : space 32 emit ; ( -- )
  : window 79 emit ; ( -- )
  : brick 72 emit ; ( -- )
  : tile 84 emit ; ( -- )
  """
  s.run """
  create arr 32 cells allot
  : setWidth arr 3 cells + ! ; ( width -- )
  : blank 0 do 45 emit loop ; ( -- )
  : bar 0 do 37 emit loop ; ( -- )
  : setArr ( -- )
    arr 0 cells + !
    arr 0 cells + @
    0 do
      arr i 4 + cells + !
    loop
    setBounds
  ;
  : setBounds ( -- )
    arr 4 cells + @
    dup
    arr 1 cells + !
    arr 2 cells + !
    arr 0 cells + @
    1 do
      arr i 4 + cells + @
      arr 1 cells + @
      > if
        arr i 4 + cells + @
        arr 1 cells + !
      then
      arr i 4 + cells + @
      arr 2 cells + @
      < if
        arr i 4 + cells + @
        arr 2 cells + !
      then
    loop
  ;
  : graphLine ( n -- )
    dup . 32 emit
    arr 2 cells + @ -
    arr 3 cells + @ *
    arr 1 cells + @
    arr 2 cells + @ - /
    dup
    bar
    arr 3 cells + @ swap -
    dup
    dup
    blank
    0 = if
      1 bar
    then
    arr 3 cells + @
    = if
      1 blank
    then
  ;
  : graph ( size width -- )
    setWidth
    setArr
    arr 0 cells + @ 0 do
      arr i 4 + cells + @
      graphLine
      cr
    loop
  ;
  """ # [items...] itemCount graphWidth graph
  s.run """
  create reverseStr 32 chars allot
  : reverse ( addr len -- )
    reverseStr place
    drop
    reverseStr count
    2dup
    swap drop
    0 do
      2dup
      swap
      dup
      rot
      -
      i -
      +
      c@ .
    loop
    drop drop
  ;
  """ # "lorem ipsum" reverse

  $('#clear').mousedown ->
    $('#outputBuffer').empty()

  output = (content) ->
    $div = $ '<pre>'
    $div.html content
    $('#outputBuffer').prepend $div

  $('#inputBuffer').submit (event) ->
    event.preventDefault()
    $input = $(this).find 'input'
    commandLine = $input.val()
    $input.val ''
    output "$ #{commandLine}"
    try
      s.run commandLine
      output "# #{s.output()}"
    catch e
      output "# #{e}"

            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console