.namespace ['PCT::HLLCompiler'] .sub 'lolcode' :method .param pmc source .param pmc adverbs :slurpy :named $S0 = adverbs['target'] if $S0 != 'lolcode' goto null_step $P0 = compreg 'PAST' .return $P0.'to_lolcode'(source, adverbs :flat :named) null_step: .return (source) .end .namespace ['PAST::Compiler'] .sub '__onload' :load :init $P0 = new 'Hash' $P0['n_add'] = 'SUM OF %0 AN %1' $P0['n_sub'] = 'DIFF OF %0 AN %1' $P0['n_mul'] = 'PRODUKT OF %0 AN %1' $P0['n_div'] = 'QUOSHUNT OF %0 AN %1' $P0['iseq INn'] = 'BOTH SAEM %0 AN %1' $P0['isne INn'] = 'DIFFERENT %0 AN %1' $P0['isge INn'] = 'BOTH SAEM %0 AN BIGGR OF %0 AN %1' $P0['isle INn'] = 'BOTH SAEM %0 AN SMALLR OF %0 AN %1' $P0['isgt INn'] = 'DIFFERENT %0 AN SMALLR OF %0 AN %1' $P0['islt INn'] = 'DIFFERENT %0 AN BIGGR OF %0 AN %1' set_global '%lolpirop', $P0 .end .sub 'lolcode_name' :method .param string name $S0 = substr name, 0, 1 if $S0 != '$' goto done substr name, 0, 1, '' done: .return (name) .end .sub 'cat' :method .param string indent .param pmc args :slurpy .local int i i = 0 loop: $I0 = elements args if i >= $I0 goto end $P0 = args[i] $I0 = does $P0, 'array' if $I0 goto loop_array unless indent goto done_indent $S0 = args[i] $S0 = concat indent, $S0 args[i] = $S0 done_indent: inc i goto loop loop_array: splice args, $P0, i, 1 goto loop end: .return (args) .end .sub 'to_lolcode' :method .param pmc past .param pmc options :slurpy :named .local pmc symtable symtable = new 'Hash' setattribute self, '%!symtable', symtable $P0 = self.'as_lolcode'(past) $P0 = self.'cat'(' ', $P0) $P0 = self.'cat'('', "HAI 1.2", $P0, "KTHXBYE\n") $S0 = join "\n", $P0 .return ($S0) .end .sub 'lolcode_children' :method .param pmc node .local pmc iter .local pmc children children = new 'ResizablePMCArray' iter = node.'iterator'() iter_loop: unless iter goto iter_end .local pmc cpast cpast = shift iter $P0 = self.'as_lolcode'(cpast) unless $P0 goto iter_loop push children, $P0 goto iter_loop iter_end: .return (children) .end .sub 'as_lolcode' :method :multi(_, _) .param pmc past .param pmc options :slurpy :named $S0 = typeof past .return ($S0) .end .sub 'as_lolcode' :method :multi(_, ['PAST::Stmts']) .param pmc past .param pmc options :slurpy :named $P0 = self.'lolcode_children'(past, options :named :flat) .return ($P0) .end .sub 'as_lolcode' :method :multi(_, ['PAST::Block']) .param pmc past .param pmc options :slurpy :named .local pmc children children = self.'lolcode_children'(past, options :named :flat) .local string name name = past.'name'() if name goto named_block .return (children) named_block: children = self.'cat'(' ', children) $S0 = concat 'HOW DUZ I ', name .return self.'cat'('', $S0, children, 'IF YOU SAY SO') .end .sub 'as_lolcode' :method :multi(_, ['PAST::Op']) .param pmc node .param pmc options :slurpy :named ## see if we set first child's lvalue $I0 = node.'lvalue'() unless $I0 goto have_lvalue $P0 = node[0] if null $P0 goto have_lvalue $P0.'lvalue'($I0) have_lvalue: .local string pasttype pasttype = node.'pasttype'() unless pasttype goto post_pirop pasttype = concat 'lolcode_', pasttype $P0 = find_method self, pasttype .return self.$P0(node, options :flat :named) post_pirop: .local pmc pirop pirop = node.'pirop'() unless pirop goto post_inline .return self.'lolcode_pirop'(node, options :flat :named) post_inline: .local pmc inline inline = node.'inline'() unless inline goto post_call .return self.'lolcode_inline'(node, options :flat :named) post_call: .return self.'lolcode_call'(node, options :flat :named) .end .sub 'lolcode_if' :method .param pmc node .param pmc options :slurpy :named .local pmc exprnode, thennode, elsenode exprnode = node[0] thennode = node[1] elsenode = node[2] .local pmc exprcode, thencode, elsecode exprcode = self.'as_lolcode'(exprnode) $S0 = node.'pasttype'() if $S0 != 'unless' goto have_exprcode exprcode = self.'cat'('', exprcode, 'NOT IT') have_exprcode: thencode = self.'as_lolcode'(thennode) thencode = self.'cat'(' ', thencode) unless null elsenode goto have_else .return self.'cat'('', exprcode, 'O RLY?', ' YA RLY', thencode, 'OIC') have_else: elsecode = self.'as_lolcode'(elsenode) elsecode = self.'cat'(' ', elsecode) .return self.'cat'('', exprcode, 'O RLY?', ' YA RLY', thencode, ' NO WAI', elsecode, 'OIC') .end .sub 'lolcode_unless' :method .param pmc node .return self.'lolcode_if'(node) .end .sub 'lolcode_call' :method .param pmc node .param pmc options :slurpy :named .local string params $P0 = self.'lolcode_children'(node) params = join ' ', $P0 .local string name name = node.'name'() if name == 'say' goto call_say if name == 'print' goto call_print $S0 = concat name, ' ' $S0 .= params .return ($S0) call_say: $S0 = concat 'VISIBLE ', params .return ($S0) call_print: $S0 = concat 'VISIBLE ', params $S0 .= '!' .return ($S0) .end .sub 'lolcode_pirop' :method .param pmc node .param pmc options :slurpy :named .local pmc children children = self.'lolcode_children'(node) .local string pirop pirop = node.'pirop'() $P0 = get_global '%lolpirop' $S0 = $P0[pirop] $P1 = new 'CodeString' $P1.'emit'($S0, children :flat) $S1 = $P1 chopn $S1, 1 .return ($S1) .end .sub 'lolcode_bind' :method .param pmc node .param pmc options :slurpy :named .local pmc lpast, rpast .local string lcode, rcode lpast = node[0] rpast = node[1] rcode = self.'as_lolcode'(rpast) lcode = self.'as_lolcode'(lpast) $I0 = lpast.'isdecl'() if $I0 goto decl_bind $S0 = concat lcode, " R " $S0 .= rcode .return ($S0) decl_bind: $S0 = concat lcode, ' ITZ ' $S0 .= rcode .return ($S0) .end .sub 'as_lolcode' :method :multi(_, ['PAST::Val']) .param pmc node .param pmc options :slurpy :named .local pmc value, returns value = node.'value'() returns = node.'returns'() if returns goto have_returns returns = typeof value have_returns: .local string valflags $P0 = get_global '%valflags' valflags = $P0[returns] $I0 = index valflags, 'e' if $I0 < 0 goto have_value value = self.'escape'(value) have_value: $S0 = value .return ($S0) .end .sub 'as_lolcode' :method :multi(_, ['PAST::Var']) .param pmc node .param pmc options :slurpy :named ## set 'bindpost' .local pmc bindpost bindpost = options['bindpost'] unless null bindpost goto have_bindpost bindpost = new 'Undef' have_bindpost: ## determine the node's scope. First, check the node itself .local string scope scope = node.'scope'() if scope goto have_scope ## otherwise, check the current symbol table under the variable's name .local string name name = node.'name'() .local pmc symtable symtable = getattribute self, '%!symtable' $P0 = symtable[name] if null $P0 goto default_scope scope = $P0['scope'] if scope goto have_scope default_scope: ## see if an outer block has set a default scope $P0 = symtable[''] if null $P0 goto scope_error scope = $P0['scope'] unless scope goto scope_error have_scope: scope_error: .local string name name = node.'name'() name = self.'lolcode_name'(name) $I0 = node.'isdecl'() if $I0 goto var_decl .return (name) var_decl: $S0 = concat 'I HAS A ', name .return ($S0) .end