implement Limbo; #line 2 "limbo.y"include "limbo.m"; Limbo: module { init: fn(argv: list of string); YYSTYPE: adt{ tok: Tok; ids: ref Decl; node: ref Node; ty: ref Type; types: ref Typelist; }; YYLEX: adt { lval: YYSTYPE; lex: fn(nil: self ref YYLEX): int; error: fn(nil: self ref YYLEX, err: string); };Landeq: con 57346;Loreq: con 57347;Lxoreq: con 57348;Llsheq: con 57349;Lrsheq: con 57350;Laddeq: con 57351;Lsubeq: con 57352;Lmuleq: con 57353;Ldiveq: con 57354;Lmodeq: con 57355;Lexpeq: con 57356;Ldeclas: con 57357;Lload: con 57358;Loror: con 57359;Landand: con 57360;Lcons: con 57361;Leq: con 57362;Lneq: con 57363;Lleq: con 57364;Lgeq: con 57365;Llsh: con 57366;Lrsh: con 57367;Lexp: con 57368;Lcomm: con 57369;Linc: con 57370;Ldec: con 57371;Lof: con 57372;Lref: con 57373;Lif: con 57374;Lelse: con 57375;Lfn: con 57376;Lexcept: con 57377;Lraises: con 57378;Lmdot: con 57379;Lto: con 57380;Lor: con 57381;Lrconst: con 57382;Lconst: con 57383;Lid: con 57384;Ltid: con 57385;Lsconst: con 57386;Llabs: con 57387;Lnil: con 57388;Llen: con 57389;Lhd: con 57390;Ltl: con 57391;Ltagof: con 57392;Limplement: con 57393;Limport: con 57394;Linclude: con 57395;Lcon: con 57396;Ltype: con 57397;Lmodule: con 57398;Lcyclic: con 57399;Ladt: con 57400;Larray: con 57401;Llist: con 57402;Lchan: con 57403;Lself: con 57404;Ldo: con 57405;Lwhile: con 57406;Lfor: con 57407;Lbreak: con 57408;Lalt: con 57409;Lcase: con 57410;Lpick: con 57411;Lcont: con 57412;Lreturn: con 57413;Lexit: con 57414;Lspawn: con 57415;Lraise: con 57416;Lfix: con 57417;Ldynamic: con 57418; }; #line 27 "limbo.y" # # lex.b # signdump: string; # name of function for sig debugging superwarn: int; debug: array of int; noline: Line; nosrc: Src; arrayz: int; oldcycles: int; emitcode: string; # emit stub routines for system module functions emitdyn: int; # emit as above but for dynamic modules emitsbl: string; # emit symbol file for sysm modules emitstub: int; # emit type and call frames for system modules emittab: string; # emit table of runtime functions for this module errors: int; mustcompile: int; dontcompile: int; asmsym: int; # generate symbols in assembly language? bout: ref Bufio->Iobuf; # output file bsym: ref Bufio->Iobuf; # symbol output file; nil => no sym out gendis: int; # generate dis or asm? fixss: int; newfnptr: int; # ISELF and -ve indices optims: int; # # decls.b # scope: int; # impmod: ref Sym; # name of implementation module impmods: ref Decl; # name of implementation module(s) nildecl: ref Decl; # declaration for limbo's nil selfdecl: ref Decl; # declaration for limbo's self # # types.b # tany: ref Type; tbig: ref Type; tbyte: ref Type; terror: ref Type; tint: ref Type; tnone: ref Type; treal: ref Type; tstring: ref Type; texception: ref Type; tunknown: ref Type; tfnptr: ref Type; rtexception: ref Type; descriptors: ref Desc; # list of all possible descriptors tattr: array of Tattr; # # nodes.b # opcommute: array of int; oprelinvert: array of int; isused: array of int; casttab: array of array of int; # instruction to cast from [1] to [2] nfns: int; # functions defined nfnexp: int; fns: array of ref Decl; # decls for fns defined tree: ref Node; # root of parse tree parset: int; # time to parse checkt: int; # time to typecheck gent: int; # time to generate code writet: int; # time to write out code symt: int; # time to write out symbolsYYEOFCODE: con 1;YYERRCODE: con 2;YYMAXDEPTH: con 200; #line 1632 "limbo.y" sys: Sys; print, fprint, sprint: import sys; bufio: Bufio; Iobuf: import bufio; str: String; math: Math; import_real, export_real, isnan: import math; yyctxt: ref YYLEX; canonnan: real; debug = array[256] of {* => 0}; noline = -1;nosrc = Src(-1, -1); infile: string; # front endinclude "arg.m";include "lex.b";include "types.b";include "nodes.b";include "decls.b"; include "typecheck.b"; # back endinclude "gen.b";include "ecom.b";include "asm.b";include "dis.b";include "sbl.b";include "stubs.b";include "com.b";include "optim.b"; init(argv: list of string){ s: string; sys = load Sys Sys->PATH; math = load Math Math->PATH; bufio = load Bufio Bufio->PATH; if(bufio == nil){ sys->print("can't load %s: %r\n", Bufio->PATH); raise("fail:bad module"); } str = load String String->PATH; if(str == nil){ sys->print("can't load %s: %r\n", String->PATH); raise("fail:bad module"); } stderr = sys->fildes(2); yyctxt = ref YYLEX; math->FPcontrol(0, Math->INVAL|Math->ZDIV|Math->OVFL|Math->UNFL|Math->INEX); na := array[1] of {0.}; import_real(array[8] of {byte 16r7f, * => byte 16rff}, na); canonnan = na[0]; if(!isnan(canonnan)) fatal("bad canonical NaN"); lexinit(); typeinit(); optabinit(); gendis = 1; asmsym = 0; maxerr = 20; ofile := ""; ext := ""; arg := Arg.init(argv); while(c := arg.opt()){ case c{ 'Y' => emitsbl = arg.arg(); if(emitsbl == nil) usage(); 'C' => dontcompile = 1; 'D' => # # debug flags: # # a alt compilation # A array constructor compilation # b boolean and branch compilation # c case compilation # d function declaration # D descriptor generation # e expression compilation # E addressable expression compilation # f print arguments for compiled functions # F constant folding # g print out globals # m module declaration and type checking # n nil references # s print sizes of output file sections # S type signing # t type checking function bodies # T timing # v global var and constant compilation # x adt verification # Y tuple compilation # z Z bug fixes # s = arg.arg(); for(i := 0; i < len s; i++){ c = s[i]; if(c < len debug) debug[c] = 1; } 'I' => s = arg.arg(); if(s == "") usage(); addinclude(s); 'G' => asmsym = 1; 'S' => gendis = 0; 'a' => emitstub = 1; 'A' => emitstub = emitdyn = 1; 'c' => mustcompile = 1; 'e' => maxerr = 1000; 'f' => fabort = 1; 'F' => newfnptr = 1; 'g' => dosym = 1; 'i' => dontinline = 1; 'o' => ofile = arg.arg(); 'O' => optims = 1; 's' => s = arg.arg(); if(s != nil) fixss = int s; 't' => emittab = arg.arg(); if(emittab == nil) usage(); 'T' => emitcode = arg.arg(); if(emitcode == nil) usage(); 'd' => emitcode = arg.arg(); if(emitcode == nil) usage(); emitdyn = 1; 'w' => superwarn = dowarn; dowarn = 1; 'x' => ext = arg.arg(); 'X' => signdump = arg.arg(); 'z' => arrayz = 1; 'y' => oldcycles = 1; * => usage(); } } addinclude("/module"); argv = arg.argv; arg = nil; if(argv == nil){ usage(); }else if(ofile != nil){ if(len argv != 1) usage(); translate(hd argv, ofile, mkfileext(ofile, ".dis", ".sbl")); }else{ pr := len argv != 1; if(ext == ""){ ext = ".s"; if(gendis) ext = ".dis"; } for(; argv != nil; argv = tl argv){ file := hd argv; (nil, s) = str->splitr(file, "/"); if(pr) print("%s:\n", s); out := mkfileext(s, ".b", ext); translate(file, out, mkfileext(out, ext, ".sbl")); } } if (toterrors > 0) raise("fail:errors");} usage(){ fprint(stderr, "usage: limbo [-GSagwe] [-I incdir] [-o outfile] [-{T|t|d} module] [-D debug] file ...\n"); raise("fail:usage");} mkfileext(file, oldext, ext: string): string{ n := len file; n2 := len oldext; if(n >= n2 && file[n-n2:] == oldext) file = file[:n-n2]; return file + ext;} translate(in, out, dbg: string){ infile = in; outfile = out; errors = 0; bins[0] = bufio->open(in, Bufio->OREAD); if(bins[0] == nil){ fprint(stderr, "can't open %s: %r\n", in); toterrors++; return; } doemit := emitcode != "" || emitstub || emittab != "" || emitsbl != ""; if(!doemit){ bout = bufio->create(out, Bufio->OWRITE, 8r666); if(bout == nil){ fprint(stderr, "can't open %s: %r\n", out); toterrors++; bins[0].close(); return; } if(dosym){ bsym = bufio->create(dbg, Bufio->OWRITE, 8r666); if(bsym == nil) fprint(stderr, "can't open %s: %r\n", dbg); } } lexstart(in); popscopes(); typestart(); declstart(); nfnexp = 0; parset = sys->millisec(); yyparse(yyctxt); parset = sys->millisec() - parset; checkt = sys->millisec(); entry := typecheck(!doemit); checkt = sys->millisec() - checkt; modcom(entry); fns = nil; nfns = 0; descriptors = nil; if(debug['T']) print("times: parse=%d type=%d: gen=%d write=%d symbols=%d\n", parset, checkt, gent, writet, symt); if(bout != nil) bout.close(); if(bsym != nil) bsym.close(); toterrors += errors; if(errors && bout != nil) sys->remove(out); if(errors && bsym != nil) sys->remove(dbg);} pwd(): string{ workdir := load Workdir Workdir->PATH; if(workdir == nil) cd := "/"; else cd = workdir->init(); # sys->print("pwd: %s\n", cd); return cd;} cleanname(s: string): string{ ls, path: list of string; if(s == nil) return nil; if(s[0] != '/' && s[0] != '\\') (nil, ls) = sys->tokenize(pwd(), "/\\"); for( ; ls != nil; ls = tl ls) path = hd ls :: path; (nil, ls) = sys->tokenize(s, "/\\"); for( ; ls != nil; ls = tl ls){ n := hd ls; if(n == ".") ; else if (n == ".."){ if(path != nil) path = tl path; } else path = n :: path; }Lines 1–500 of 3096. Load more
implement Limbo; #line 2 "limbo.y" include "limbo.m"; Limbo: module { init: fn(argv: list of string); YYSTYPE: adt{ tok: Tok; ids: ref Decl; node: ref Node; ty: ref Type; types: ref Typelist; }; YYLEX: adt { lval: YYSTYPE; lex: fn(nil: self ref YYLEX): int; error: fn(nil: self ref YYLEX, err: string); }; Landeq: con 57346; Loreq: con 57347; Lxoreq: con 57348; Llsheq: con 57349; Lrsheq: con 57350; Laddeq: con 57351; Lsubeq: con 57352; Lmuleq: con 57353; Ldiveq: con 57354; Lmodeq: con 57355; Lexpeq: con 57356; Ldeclas: con 57357; Lload: con 57358; Loror: con 57359; Landand: con 57360; Lcons: con 57361; Leq: con 57362; Lneq: con 57363; Lleq: con 57364; Lgeq: con 57365; Llsh: con 57366; Lrsh: con 57367; Lexp: con 57368; Lcomm: con 57369; Linc: con 57370; Ldec: con 57371; Lof: con 57372; Lref: con 57373; Lif: con 57374; Lelse: con 57375; Lfn: con 57376; Lexcept: con 57377; Lraises: con 57378; Lmdot: con 57379; Lto: con 57380; Lor: con 57381; Lrconst: con 57382; Lconst: con 57383; Lid: con 57384; Ltid: con 57385; Lsconst: con 57386; Llabs: con 57387; Lnil: con 57388; Llen: con 57389; Lhd: con 57390; Ltl: con 57391; Ltagof: con 57392; Limplement: con 57393; Limport: con 57394; Linclude: con 57395; Lcon: con 57396; Ltype: con 57397; Lmodule: con 57398; Lcyclic: con 57399; Ladt: con 57400; Larray: con 57401; Llist: con 57402; Lchan: con 57403; Lself: con 57404; Ldo: con 57405; Lwhile: con 57406; Lfor: con 57407; Lbreak: con 57408; Lalt: con 57409; Lcase: con 57410; Lpick: con 57411; Lcont: con 57412; Lreturn: con 57413; Lexit: con 57414; Lspawn: con 57415; Lraise: con 57416; Lfix: con 57417; Ldynamic: con 57418; }; #line 27 "limbo.y" # # lex.b # signdump: string; # name of function for sig debugging superwarn: int; debug: array of int; noline: Line; nosrc: Src; arrayz: int; oldcycles: int; emitcode: string; # emit stub routines for system module functions emitdyn: int; # emit as above but for dynamic modules emitsbl: string; # emit symbol file for sysm modules emitstub: int; # emit type and call frames for system modules emittab: string; # emit table of runtime functions for this module errors: int; mustcompile: int; dontcompile: int; asmsym: int; # generate symbols in assembly language? bout: ref Bufio->Iobuf; # output file bsym: ref Bufio->Iobuf; # symbol output file; nil => no sym out gendis: int; # generate dis or asm? fixss: int; newfnptr: int; # ISELF and -ve indices optims: int; # # decls.b # scope: int; # impmod: ref Sym; # name of implementation module impmods: ref Decl; # name of implementation module(s) nildecl: ref Decl; # declaration for limbo's nil selfdecl: ref Decl; # declaration for limbo's self # # types.b # tany: ref Type; tbig: ref Type; tbyte: ref Type; terror: ref Type; tint: ref Type; tnone: ref Type; treal: ref Type; tstring: ref Type; texception: ref Type; tunknown: ref Type; tfnptr: ref Type; rtexception: ref Type; descriptors: ref Desc; # list of all possible descriptors tattr: array of Tattr; # # nodes.b # opcommute: array of int; oprelinvert: array of int; isused: array of int; casttab: array of array of int; # instruction to cast from [1] to [2] nfns: int; # functions defined nfnexp: int; fns: array of ref Decl; # decls for fns defined tree: ref Node; # root of parse tree parset: int; # time to parse checkt: int; # time to typecheck gent: int; # time to generate code writet: int; # time to write out code symt: int; # time to write out symbols YYEOFCODE: con 1; YYERRCODE: con 2; YYMAXDEPTH: con 200; #line 1632 "limbo.y" sys: Sys; print, fprint, sprint: import sys; bufio: Bufio; Iobuf: import bufio; str: String; math: Math; import_real, export_real, isnan: import math; yyctxt: ref YYLEX; canonnan: real; debug = array[256] of {* => 0}; noline = -1; nosrc = Src(-1, -1); infile: string; # front end include "arg.m"; include "lex.b"; include "types.b"; include "nodes.b"; include "decls.b"; include "typecheck.b"; # back end include "gen.b"; include "ecom.b"; include "asm.b"; include "dis.b"; include "sbl.b"; include "stubs.b"; include "com.b"; include "optim.b"; init(argv: list of string) { s: string; sys = load Sys Sys->PATH; math = load Math Math->PATH; bufio = load Bufio Bufio->PATH; if(bufio == nil){ sys->print("can't load %s: %r\n", Bufio->PATH); raise("fail:bad module"); } str = load String String->PATH; if(str == nil){ sys->print("can't load %s: %r\n", String->PATH); raise("fail:bad module"); } stderr = sys->fildes(2); yyctxt = ref YYLEX; math->FPcontrol(0, Math->INVAL|Math->ZDIV|Math->OVFL|Math->UNFL|Math->INEX); na := array[1] of {0.}; import_real(array[8] of {byte 16r7f, * => byte 16rff}, na); canonnan = na[0]; if(!isnan(canonnan)) fatal("bad canonical NaN"); lexinit(); typeinit(); optabinit(); gendis = 1; asmsym = 0; maxerr = 20; ofile := ""; ext := ""; arg := Arg.init(argv); while(c := arg.opt()){ case c{ 'Y' => emitsbl = arg.arg(); if(emitsbl == nil) usage(); 'C' => dontcompile = 1; 'D' => # # debug flags: # # a alt compilation # A array constructor compilation # b boolean and branch compilation # c case compilation # d function declaration # D descriptor generation # e expression compilation # E addressable expression compilation # f print arguments for compiled functions # F constant folding # g print out globals # m module declaration and type checking # n nil references # s print sizes of output file sections # S type signing # t type checking function bodies # T timing # v global var and constant compilation # x adt verification # Y tuple compilation # z Z bug fixes # s = arg.arg(); for(i := 0; i < len s; i++){ c = s[i]; if(c < len debug) debug[c] = 1; } 'I' => s = arg.arg(); if(s == "") usage(); addinclude(s); 'G' => asmsym = 1; 'S' => gendis = 0; 'a' => emitstub = 1; 'A' => emitstub = emitdyn = 1; 'c' => mustcompile = 1; 'e' => maxerr = 1000; 'f' => fabort = 1; 'F' => newfnptr = 1; 'g' => dosym = 1; 'i' => dontinline = 1; 'o' => ofile = arg.arg(); 'O' => optims = 1; 's' => s = arg.arg(); if(s != nil) fixss = int s; 't' => emittab = arg.arg(); if(emittab == nil) usage(); 'T' => emitcode = arg.arg(); if(emitcode == nil) usage(); 'd' => emitcode = arg.arg(); if(emitcode == nil) usage(); emitdyn = 1; 'w' => superwarn = dowarn; dowarn = 1; 'x' => ext = arg.arg(); 'X' => signdump = arg.arg(); 'z' => arrayz = 1; 'y' => oldcycles = 1; * => usage(); } } addinclude("/module"); argv = arg.argv; arg = nil; if(argv == nil){ usage(); }else if(ofile != nil){ if(len argv != 1) usage(); translate(hd argv, ofile, mkfileext(ofile, ".dis", ".sbl")); }else{ pr := len argv != 1; if(ext == ""){ ext = ".s"; if(gendis) ext = ".dis"; } for(; argv != nil; argv = tl argv){ file := hd argv; (nil, s) = str->splitr(file, "/"); if(pr) print("%s:\n", s); out := mkfileext(s, ".b", ext); translate(file, out, mkfileext(out, ext, ".sbl")); } } if (toterrors > 0) raise("fail:errors"); } usage() { fprint(stderr, "usage: limbo [-GSagwe] [-I incdir] [-o outfile] [-{T|t|d} module] [-D debug] file ...\n"); raise("fail:usage"); } mkfileext(file, oldext, ext: string): string { n := len file; n2 := len oldext; if(n >= n2 && file[n-n2:] == oldext) file = file[:n-n2]; return file + ext; } translate(in, out, dbg: string) { infile = in; outfile = out; errors = 0; bins[0] = bufio->open(in, Bufio->OREAD); if(bins[0] == nil){ fprint(stderr, "can't open %s: %r\n", in); toterrors++; return; } doemit := emitcode != "" || emitstub || emittab != "" || emitsbl != ""; if(!doemit){ bout = bufio->create(out, Bufio->OWRITE, 8r666); if(bout == nil){ fprint(stderr, "can't open %s: %r\n", out); toterrors++; bins[0].close(); return; } if(dosym){ bsym = bufio->create(dbg, Bufio->OWRITE, 8r666); if(bsym == nil) fprint(stderr, "can't open %s: %r\n", dbg); } } lexstart(in); popscopes(); typestart(); declstart(); nfnexp = 0; parset = sys->millisec(); yyparse(yyctxt); parset = sys->millisec() - parset; checkt = sys->millisec(); entry := typecheck(!doemit); checkt = sys->millisec() - checkt; modcom(entry); fns = nil; nfns = 0; descriptors = nil; if(debug['T']) print("times: parse=%d type=%d: gen=%d write=%d symbols=%d\n", parset, checkt, gent, writet, symt); if(bout != nil) bout.close(); if(bsym != nil) bsym.close(); toterrors += errors; if(errors && bout != nil) sys->remove(out); if(errors && bsym != nil) sys->remove(dbg); } pwd(): string { workdir := load Workdir Workdir->PATH; if(workdir == nil) cd := "/"; else cd = workdir->init(); # sys->print("pwd: %s\n", cd); return cd; } cleanname(s: string): string { ls, path: list of string; if(s == nil) return nil; if(s[0] != '/' && s[0] != '\\') (nil, ls) = sys->tokenize(pwd(), "/\\"); for( ; ls != nil; ls = tl ls) path = hd ls :: path; (nil, ls) = sys->tokenize(s, "/\\"); for( ; ls != nil; ls = tl ls){ n := hd ls; if(n == ".") ; else if (n == ".."){ if(path != nil) path = tl path; } else path = n :: path; }