# A Longer Limbo Example # Bigfact # 1997, CSE IIT-D # # Use "limbo -g Bigfact.b" to compile (-g for debugging). # This will create a file called Bigfact.dis - bytecode # that would run on Dis. # This is an implementation file, and implements # a single module, which we call Bigfact # implement Bigfact; # The following include lines copy interface # definitions from other modules # # System functions ... # include "sys.m"; sys: Sys; stdout: ref Sys->FD; stderr: ref Sys->FD; # Math functions ... # include "math.m"; math: Math; pow: import math; # Graphics functions and types ... # include "draw.m"; # This is how we declare constants # DIGIT_UNIT: con 4; MUNITNUM: con 65535; LIMIT_N: con 15000; # Now we give the module declaration, which is the # external interface we present to the outside world. # Just like typical C programs begin with # # `main(int argc, char **argv)', # # Limbo modules that are intended to be called from # a command interpretor have a typical `init' function # that takes two arguments: the graphical context, and # the familiar `argv' # Bigfact: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; # Implementaton of the init function # init(ctxt: ref Draw->Context, argv: list of string) { # Load the math and the sys modules # math = load Math Math->PATH; sys = load Sys Sys->PATH; # Assign descriptors # stdout = sys->fildes(1); stderr = sys->fildes(2); # Chop off the head of the argument list # `tl' is the tail function on lists # argv = tl argv; # Various declarations # z := array[4] of { "", "0", "00", "000" }; carry: int; i, j, n, N: int; mmax, mmax_s: int; mmul: int; mufactor: int; zeros: int; s := array[MUNITNUM] of int; carry = mmax = mmul = 0; if (len argv != 1) { sys->fprint(stderr, "usage: Bigfact N\n"); exit; } N = int hd argv; if (N > LIMIT_N) { sys->fprint(stderr, "error: N too large (max allowed is %d)\n", LIMIT_N); exit; } s[0] = 1; mufactor = int pow(10., real DIGIT_UNIT); for (i = 2; i <= N; i++) { mmax_s = mmax; for (j = 0; j <= mmax_s; j++) { n = s[j]; mmul = n * i + carry; carry = mmul / mufactor; mmul = mmul % mufactor; s[j] = mmul; if ((carry != 0) && (j == mmax)) { mmax++; s[mmax] = carry; carry = 0; } } } for (i = mmax; i >= 0; i--) { if (i != mmax) { if (s[i] < 10) zeros = 3; else if (s[i] < 100) zeros = 2; else if (s[i] < 1000) zeros = 1; sys->print("%s", z[zeros]); } sys->print("%d", s[i]); zeros = 0; } sys->print("\n"); exit; }