about summary refs log tree commit diff stats
path: root/apps/crenshaw2-1
Commit message (Expand)AuthorAgeFilesLines
* support 'fake' handles allocated staticallyKartik Agaram2020-05-181-0/+0
* support 'fake' handles allocated staticallyKartik Agaram2020-05-181-0/+0
* Rebuild phases of self-hosted SubX translatorKartik Agaram2020-05-181-0/+0
* 6208Kartik Agaram2020-04-221-0/+0
* 6182 - start of support for safe handlesKartik Agaram2020-04-031-0/+0
* 6181Kartik Agaram2020-04-031-0/+0
* 6153 - switch 'main' to use Mu stringsKartik Agaram2020-03-151-0/+0
* 6085Kartik Agaram2020-03-061-0/+0
* 6083Kartik Agaram2020-03-061-0/+0
* 6070Kartik Agaram2020-02-291-0/+0
* 6064Kartik Agaram2020-02-271-0/+0
* 6000 - clean up after no-local branchesKartik Agaram2020-02-091-0/+0
* 5948 - branching to named blocksKartik Agaram2020-01-291-0/+0
* 5898 - strengthen slice-empty? checkKartik Agaram2020-01-191-0/+0
* 5887 - reorganize libraryKartik Agaram2020-01-141-0/+0
* 5847 - literal inputsKartik Agaram2019-12-311-0/+0
* 5804Kartik Agaram2019-12-081-0/+0
* 5803Kartik Agaram2019-12-071-0/+0
* 5792Kartik Agaram2019-12-051-0/+0
* 5782 - fix a widespread bug with Heap-sizeKartik Agaram2019-11-301-0/+0
* 5778Kartik Agaram2019-11-291-0/+0
* 5769 - support uppercase hex in SubXKartik Agaram2019-11-281-0/+0
* 5752Kartik Agaram2019-11-181-0/+0
* 5714Kartik Agaram2019-10-251-0/+0
* 5687Kartik Agaram2019-09-231-0/+0
* 5676Kartik Agaram2019-09-191-0/+0
* 5675 - move helpers from subx-common into layersKartik Agaram2019-09-191-0/+0
* 5673 - standardize a few knobsKartik Agaram2019-09-191-0/+0
* 5672 - move hex out of appsKartik Agaram2019-09-191-0/+0
* 5669Kartik Agaram2019-09-191-0/+0
* 5668 - start reorg to permit syntax sugar in layersKartik Agaram2019-09-191-0/+0
* 5647 - experimental support for swapping OSKartik Agaram2019-09-111-0/+0
* 5630Kartik Agaram2019-09-061-0/+0
* 5623Kartik Agaram2019-09-041-0/+0
* 5616Kartik Agaram2019-09-041-0/+0
* 5608 - write int to streamKartik Agaram2019-09-021-0/+0
* 5600Kartik Agaram2019-08-311-0/+0
* 5592 - switch register names to lowercaseKartik Agaram2019-08-261-0/+0
* 5591Kartik Agaram2019-08-261-0/+0
* build out all variants for skipping whitespaceKartik Agaram2019-08-241-0/+0
* done implementing all variants of 'get'Kartik Agaram2019-08-131-0/+0
* done with get-or-stopKartik Agaram2019-08-131-0/+0
* half-done testing get-or-stopKartik Agaram2019-08-131-0/+0
* standardize test input/output/error streamsKartik Agaram2019-08-131-0/+0
* .Kartik Agaram2019-08-131-0/+0
* .Kartik Agaram2019-08-131-0/+0
* new variant: maybe-get-sliceKartik Agaram2019-08-131-0/+0
* new variant: maybe-get returns null on failureKartik Agaram2019-08-121-0/+0
* better error message when get abortsKartik Agaram2019-08-121-0/+0
* extract table functions into their own layerKartik Agaram2019-08-111-0/+0
ld } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
## compute the factorial of 5, and return the result in the exit code
#
# Uses syntax sugar for:
#   rm32 operands
#   function calls
#
# To run:
#   $ ./translate_subx init.linux 0*.subx apps/factorial.subx -o apps/factorial
#   $ ./bootstrap run apps/factorial
# Expected result:
#   $ echo $?
#   120
#
# You can also run the automated test suite:
#   $ ./bootstrap run apps/factorial test
# Expected output:
#   ........
# Every '.' indicates a passing test. Failing tests get a 'F'.

== code

Entry:  # run tests if necessary, compute `factorial(5)` if not
    # . prologue
    89/<- %ebp 4/r32/esp

    # initialize heap
    (new-segment *Heap-size Heap)

    # - if argc > 1 and argv[1] == "test", then return run_tests()
    # if (argc <= 1) goto run-main
    81 7/subop/compare *ebp 1/imm32
    7e/jump-if-<= $run-main/disp8
    # if (!kernel-string-equal?(argv[1], "test")) goto run-main
    (kernel-string-equal? *(ebp+8) "test")  # => eax
    # . if (eax == false) goto run-main
    3d/compare-eax-and 0/imm32/false
    74/jump-if-= $run-main/disp8
    #
    (run-tests)
    # syscall(exit, *Num-test-failures)
    8b/-> *Num-test-failures 3/r32/ebx
    eb/jump $main:end/disp8
$run-main:
    # - otherwise
    (factorial 5)  # => eax
    # syscall(exit, eax)
    89/<- %ebx 0/r32/eax
$main:end:
    b8/copy-to-eax 1/imm32/exit
    cd/syscall 0x80/imm8

factorial:  # n: int -> int/eax
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # save registers
    53/push-ebx
    # if (n <= 1) return 1
    b8/copy-to-eax 1/imm32
    81 7/subop/compare *(ebp+8) 1/imm32
    7e/jump-if-<= $factorial:end/disp8
    # var ebx: int = n-1
    8b/-> *(ebp+8) 3/r32/ebx
    4b/decrement-ebx
    #
    (factorial %ebx)  # => eax
    # return n * factorial(n-1)
    f7 4/subop/multiply-into-eax *(ebp+8)
    # TODO: check for overflow
$factorial:end:
    # restore registers
    5b/pop-to-ebx
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

test-factorial:
    (factorial 5)
    (check-ints-equal %eax 0x78 "F - test-factorial")
    c3/return