<commit_before>.HLL 'Arc', ''

.sub _init :anon :load :init

   ## class holding information needed by compilation
   P0 = newclass 'CompilerState'
   addattribute P0, 'code' # CodeString of code emitted so far
   addattribute P0, 'lex' # list of lexical variables (symbols)
   addattribute P0, 'nextreg' # number of next free register to use

   ## function information
   P0 = newclass 'FnInfo'
   addattribute P0, 'expr' # s-expr ($fn name (args ...) body)
   addattribute P0, 'globalp' # is this a global function (not a closure)?
   addattribute P0, 'lex' # list of lexical variables at definiton time
   addattribute P0, 'outer' # name of external function

   ## constant value information
   P0 = newclass 'ConstInfo'
   addattribute P0, 'expr'
   addattribute P0, 'name' # global name of constant
   
   ## function arg information
   P0 = newclass 'ArgInfo'
   addattribute P0, 'sym'
   addattribute P0, 'type' # only 'normal' or 'rest' for now
   addattribute P0, 'rep' # parrot representaion 
   
   .return ()
.end

.namespace [ 'CompilerState' ]

## get name of next free register
.sub _next_reg :method
   P0 = getattribute self, 'nextreg'
   P0 += 1
   setattribute self, 'nextreg', P0

   S0 = '$P'
   S1 = P0
   S0 .= S1
   .return (S0)
.end

## mark all registers as free
.sub _reset_reg :method
   P0 = getattribute self, 'nextreg'
   P0 = 0
   setattribute self, 'nextreg', P0
   .return ()
.end

## mark last allocated register as free, return freed register name
.sub _free_reg :method
   P0 = getattribute self, 'nextreg'
   S0 = '$P'
   S1 = P0
   S0 .= S1
   P0 -= 1
   setattribute self, 'nextreg', P0
   .return (S0)
.end

## simulate a push on a stack using registers, return reg name
.sub _push :method
   .return self.'_next_reg'()
.end

## simulate a pop, return register name with value
## use the value before a push is made!
.sub _pop :method
   .return self.'_free_reg'()
.end

.sub _top :method
   P0 = getattribute self, 'nextreg'
   S0 = '$P'
   S1 = P0
   S0 .= S1
   .return (S0)
.end

.namespace [ ]

## create a new empty CompilerState
.sub _empty_state
   P0 = new 'CompilerState'
   P1 = new 'CodeString'
   setattribute P0, 'code', P1
   P1 = new 'ResizablePMCArray'
   setattribute P0, 'lex', P1
   P1 = new 'Integer'
   P1 = 0
   setattribute P0, 'nextreg', P1

   .return (P0)
.end

## top level compilation
## !! destroys expr
## !! just prints the result, for the moment
.sub _tl_compile
   .param pmc expr
   .local pmc fns
   .local pmc consts
   .local pmc code

   say 'Compilation result:'
   say ''
   
   P0 = new 'ResizablePMCArray'
   P1 = new 'String'
   P1 = ""
   (fns, consts, expr) = _collect_fn_and_consts(expr, P0, P1, 0)
   P0 = _empty_state()
   code = getattribute P0, 'code'
   ## initialization stuff
   code.'emit'(<<"END")
.sub _main :anon :main
   load_bytecode 'types.pbc'
   load_bytecode 'symtable.pbc'
   load_bytecode 'arcall.pbc'
   load_bytecode 'compiler.pbc'
   load_bytecode 'read.pbc'
END
    _compile_expr(P0, expr)
    S0 = P0.'_pop'() # return register
    code.'emit'("   .return (%0)", S0)
    code.'emit'(".end")
    S0 = code
    say S0
loop:
    unless fns goto end
    P0 = shift fns
    P1 = _empty_state()
    _compile_fn(P1, P0)
    P0 = getattribute P1, 'code'
    S0 = P0
    say S0    
    goto loop
end:
    P0 = _empty_state()
    code = getattribute P0, 'code'
    code.'emit'(".sub _const_init :anon :init")
loop1:
    unless consts goto end1
    P1 = shift consts
    _compile_const(P0, P1)
    goto loop1
end1:
    code.'emit'(".return ()")
    code.'emit'(".end")
    S0 = code
    say S0
    .return ()
.end
 <commit_msg>fixed function declaration order bug<commit_after>.HLL 'Arc', ''

.sub _init :anon :load :init

   ## class holding information needed by compilation
   P0 = newclass 'CompilerState'
   addattribute P0, 'code' # CodeString of code emitted so far
   addattribute P0, 'lex' # list of lexical variables (symbols)
   addattribute P0, 'nextreg' # number of next free register to use

   ## function information
   P0 = newclass 'FnInfo'
   addattribute P0, 'expr' # s-expr ($fn name (args ...) body)
   addattribute P0, 'globalp' # is this a global function (not a closure)?
   addattribute P0, 'lex' # list of lexical variables at definiton time
   addattribute P0, 'outer' # name of external function

   ## constant value information
   P0 = newclass 'ConstInfo'
   addattribute P0, 'expr'
   addattribute P0, 'name' # global name of constant
   
   ## function arg information
   P0 = newclass 'ArgInfo'
   addattribute P0, 'sym'
   addattribute P0, 'type' # only 'normal' or 'rest' for now
   addattribute P0, 'rep' # parrot representaion 
   
   .return ()
.end

.namespace [ 'CompilerState' ]

## get name of next free register
.sub _next_reg :method
   P0 = getattribute self, 'nextreg'
   P0 += 1
   setattribute self, 'nextreg', P0

   S0 = '$P'
   S1 = P0
   S0 .= S1
   .return (S0)
.end

## mark all registers as free
.sub _reset_reg :method
   P0 = getattribute self, 'nextreg'
   P0 = 0
   setattribute self, 'nextreg', P0
   .return ()
.end

## mark last allocated register as free, return freed register name
.sub _free_reg :method
   P0 = getattribute self, 'nextreg'
   S0 = '$P'
   S1 = P0
   S0 .= S1
   P0 -= 1
   setattribute self, 'nextreg', P0
   .return (S0)
.end

## simulate a push on a stack using registers, return reg name
.sub _push :method
   .return self.'_next_reg'()
.end

## simulate a pop, return register name with value
## use the value before a push is made!
.sub _pop :method
   .return self.'_free_reg'()
.end

.sub _top :method
   P0 = getattribute self, 'nextreg'
   S0 = '$P'
   S1 = P0
   S0 .= S1
   .return (S0)
.end

.namespace [ ]

## create a new empty CompilerState
.sub _empty_state
   P0 = new 'CompilerState'
   P1 = new 'CodeString'
   setattribute P0, 'code', P1
   P1 = new 'ResizablePMCArray'
   setattribute P0, 'lex', P1
   P1 = new 'Integer'
   P1 = 0
   setattribute P0, 'nextreg', P1

   .return (P0)
.end

## top level compilation
## !! destroys expr
## !! just prints the result, for the moment
.sub _tl_compile
   .param pmc expr
   .local pmc fns
   .local pmc consts
   .local pmc code

   say 'Compilation result:'
   say ''
   
   P0 = new 'ResizablePMCArray'
   P1 = new 'String'
   P1 = ""
   (fns, consts, expr) = _collect_fn_and_consts(expr, P0, P1, 0)
   P0 = _empty_state()
   code = getattribute P0, 'code'
   ## initialization stuff
   code.'emit'(<<"END")
.sub _main :anon :main
   load_bytecode 'types.pbc'
   load_bytecode 'symtable.pbc'
   load_bytecode 'arcall.pbc'
   load_bytecode 'compiler.pbc'
   load_bytecode 'read.pbc'
END
    _compile_expr(P0, expr)
    S0 = P0.'_pop'() # return register
    code.'emit'("   .return (%0)", S0)
    code.'emit'(".end")
    S0 = code
    say S0
loop:
    unless fns goto end
    P0 = pop fns
    P1 = _empty_state()
    _compile_fn(P1, P0)
    P0 = getattribute P1, 'code'
    S0 = P0
    say S0    
    goto loop
end:
    P0 = _empty_state()
    code = getattribute P0, 'code'
    code.'emit'(".sub _const_init :anon :init")
loop1:
    unless consts goto end1
    P1 = shift consts
    _compile_const(P0, P1)
    goto loop1
end1:
    code.'emit'(".return ()")
    code.'emit'(".end")
    S0 = code
    say S0
    .return ()
.end
 
{'fraction_non_alphanumeric': 0.11536876802637, 'fraction_numerical': 0.026095316577393217, 'mean_word_length': 2.8549497088406564, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5847112', 'n_tokens_mistral': 2656, 'n_tokens_neox': 2616, 'n_words': 876}