Module: Spitewaste

Defined in:
lib/spitewaste.rb,
lib/spitewaste/emitter.rb,
lib/spitewaste/version.rb,
lib/spitewaste/assembler.rb,
lib/spitewaste/emitters/image.rb,
lib/spitewaste/emitters/codegen.rb,
lib/spitewaste/parsers/assembly.rb,
lib/spitewaste/emitters/assembly.rb,
lib/spitewaste/parsers/fucktional.rb,
lib/spitewaste/parsers/spitewaste.rb,
lib/spitewaste/parsers/whitespace.rb,
lib/spitewaste/emitters/whitespace.rb,
lib/spitewaste/emitters/wsassembly.rb

Defined Under Namespace

Classes: Assembler, AssemblyEmitter, AssemblyParser, CodegenEmitter, Emitter, ImageEmitter, SpitewasteParser, WSAssemblyEmitter, WhitespaceEmitter, WhitespaceParser

Constant Summary collapse

OPERATORS_M2T =

mnemonic to tokens

{ # mnemonic to tokens
  push:  "  ",       copy: " \t ",   slide: " \t\n",   label: "\n  ",
  call:  "\n \t",    jump: "\n \n",  jz:    "\n\t ",   jn:    "\n\t\t",
  pop:   " \n\n",    dup:  " \n ",   swap:  " \n\t",   add:   "\t   ",
  sub:   "\t  \t",   mul:  "\t  \n", div:   "\t \t ",  mod:   "\t \t\t",
  store: "\t\t ",    load: "\t\t\t", ret:   "\n\t\n",  ichr:  "\t\n\t ",
  inum:  "\t\n\t\t", ochr: "\t\n  ", onum:  "\t\n \t", exit:  "\n\n\n",
  shell: "\t\n\n",   eval: "\n\n\t"
}
OPERATORS_T2M =

tokens to mnemonic

OPERATORS_M2T.invert
VERSION =
'0.2.5'
FUCKTIONAL =
{
  'map' => <<SPW,

  'reduce' => <<SPW,

  'times' => <<SPW,

  'find' => <<SPW,

  'maxby' => <<SPW,
push -3 swap store
maxby_loop_%1$s:
copy 1 %2$s copy 1 %2$s sub jn maxby_lesser_%1$s
maxby_resume_%1$s: pop push -3 dup call dec load push 1 call eq
jz maxby_loop_%1$s
jump maxby_done_%1$s
maxby_lesser_%1$s: swap jump maxby_resume_%1$s
maxby_done_%1$s:
SPW

  'minby'  => 'maxby (%2$s push -1 mul)',
  'each'   => 'dup times (dup call roll %2$s push 1 sub) pop',
  'all'    => 'map (%2$s) reduce (add) push -11 load call eq',
  # TODO: optimize any to stop early if possible
  'any'    => 'map (%2$s) reduce (add) push 0 call gt',
  'none'   => 'map (%2$s) reduce (add) push 0 call eq',
  'count'  => 'select (%2$s) dup call nslide',
  'select' => generate_filter_spw('select', 0, 1),
  'reject' => generate_filter_spw('reject', 1, 0),
}
LIBSPW =
File.expand_path '../libspw', __dir__

Class Method Summary collapse

Class Method Details

.generate_filter_spw(fn, a, b) ⇒ Object

select() and reject() do almost the exact same thing, differing only in whether they drop or keep the match, so this is a bit of deduplication.



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/spitewaste/parsers/fucktional.rb', line 4

def self.generate_filter_spw fn, a, b
  ops = ['push -10 dup call dec load swap store', 'pop']
  yes, no = ops[a], ops[b]
  <<SPW
push -10 dup store
#{fn}_loop_%1$s:
push 1 sub dup jn #{fn}_restore_%1$s
swap dup %2$s jz #{fn}_no_%1$s #{yes}
jump #{fn}_loop_%1$s
#{fn}_no_%1$s: #{no} jump #{fn}_loop_%1$s
#{fn}_restore_%1$s: push 9 sub load
#{fn}_restore_loop_%1$s:
dup push 10 add jz #{fn}_done_%1$s
dup load swap push 1 add
jump #{fn}_restore_loop_%1$s
#{fn}_done_%1$s: dup load sub
SPW
end

.guess_format(program) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/spitewaste.rb', line 17

def guess_format program
  white = program.count "\s\t\n"
  black = program.size - white

  return :whitespace if white > black
  program[/import|[^-\w\s]/] ? :spitewaste : :assembly
end

.strpack(s) ⇒ Object



25
26
27
# File 'lib/spitewaste.rb', line 25

def strpack s
  s.bytes.zip(0..).sum { |b, e| b * 128 ** e }
end