diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-20 03:35:50 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-20 03:35:50 +0300 |
| commit | afe2fc0b4826d8f8856feec59354c2235a10a1b2 (patch) | |
| tree | c87d235b0d6097d112ca0e601ef1452cd9e3bbb9 /appl/cmd/sh92.b | |
| parent | a627659d082d4bf8b95afb39d8ffcfd10ef84339 (diff) | |
Implement ref fn issue workaround
Diffstat (limited to 'appl/cmd/sh92.b')
| -rw-r--r-- | appl/cmd/sh92.b | 651 |
1 files changed, 456 insertions, 195 deletions
diff --git a/appl/cmd/sh92.b b/appl/cmd/sh92.b index 1e865b9..3776e66 100644 --- a/appl/cmd/sh92.b +++ b/appl/cmd/sh92.b @@ -4,14 +4,23 @@ include "sys.m"; include "draw.m"; include "sh9util.m"; include "sh9parser.m"; +include "sh9cmd.m"; + +Sh92: module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); + zstmt_assign: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; + zstmt_cmd_call: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; + zempty: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; + zsqstr_to_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; + zvar_sub_expr: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; + zexpr_expr_combiner: fn(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode; +}; sys: Sys; sh9u: Sh9Util; sh9p: Sh9Parser; - -Sh92: module { - init: fn(nil: ref Draw->Context, nil: list of string); -}; +sh9cmd: Sh9Cmd; GrammarNode: import sh9p; ModProc: import sh9p; @@ -26,6 +35,13 @@ parse_toks: import sh9p; reverse_list: import sh9u; to_array: import sh9u; +Async, Seq: import sh9u; +Command: import sh9u; +Pipeline: import sh9u; + +stdin: ref sys->FD; +stderr: ref sys->FD; +waitfd: ref sys->FD; S_UNKNOWN: con "UNK"; S_NONE: con "NONE"; @@ -51,215 +67,460 @@ S_STMT: con "STMT"; S_EXPR: con "EXPR"; S_CALL: con "CALL"; +S_IF: con "IF"; +S_THEN: con "THEN"; +S_FI: con "FI"; +S_ELIF: con "ELIF"; +S_ELSE: con "ELSE"; +S_WHILE: con "WHILE"; +S_DO: con "DO"; +S_DONE: con "DONE"; + +waitfor(pid: int) +{ + if (pid <= 0) + return; + buf := array[sys->WAITLEN] of byte; + status := ""; + for (;;) { + n := sys->read(waitfd, buf, len buf); + if (n < 0) { + sys->fprint(stderr, "sh9: read wait: %r\n"); + return; + } + status = string buf[0:n]; + if (status[len status-1] != ':') + sys->fprint(stderr, "%s\n", status); + who := int status; + if (who != 0) { + if (who == pid) { + return; + } + } + } +} + +runpipeline(ctx: ref Draw->Context, pipeline: ref Pipeline) +{ + if (pipeline.term == Async) + sys->pctl(sys->NEWPGRP, nil); + pid := startpipeline(ctx, pipeline); + if (pid < 0) + return; + if (pipeline.term == Seq) + waitfor(pid); +} + +startpipeline(ctx: ref Draw->Context, pipeline: ref Pipeline): int +{ + pid := 0; + cmds := pipeline.cmds; + first := 1; + inpipe, outpipe: ref Sys->FD; + while (cmds != nil) { + last := tl cmds == nil; + cmd := hd cmds; + + infd: ref Sys->FD; + if (!first) + infd = inpipe; + else if (cmd.inf != nil) { + infd = sys->open(cmd.inf, Sys->OREAD); + if (infd == nil) { + sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.inf); + return -1; + } + } + + outfd: ref Sys->FD; + if (!last) { + fds := array[2] of ref Sys->FD; + if (sys->pipe(fds) < 0) { + sys->fprint(stderr, "sh9: can't make pipe: %r\n"); + return -1; + } + outpipe = fds[0]; + outfd = fds[1]; + fds = nil; + } else if (cmd.outf != nil) { + if (cmd.append){ + outfd = sys->open(cmd.outf, Sys->OWRITE); + if (outfd != nil) + sys->seek(outfd, big 0, Sys->SEEKEND); + } + if (outfd == nil) + outfd = sys->create(cmd.outf, Sys->OWRITE, 8r666); + if (outfd == nil) { + sys->fprint(stderr, "sh9: can't open %s: %r\n", cmd.outf); + return -1; + } + } + + rpid := chan of int; + ta:=cmd.args; + + la:= len cmd.args; + #sys->print("mkprog args[%d]: ", la); + for (z:=0; z<la; z++) { + #sys->print("%s ", hd ta); + ta = tl ta; + } + #sys->print("\n"); + spawn mkprog(ctx, cmd.args, infd, outfd, rpid); + pid = <-rpid; + infd = nil; + outfd = nil; + + inpipe = outpipe; + outpipe = nil; + + first = 0; + cmds = tl cmds; + } + return pid; +} + +mkprog(ctxt: ref Draw->Context, arg: list of string, infd, outfd: ref Sys->FD, waitpid: chan of int) +{ + fds := list of {0, 1, 2}; + if(infd != nil) + fds = infd.fd :: fds; + if(outfd != nil) + fds = outfd.fd :: fds; + pid := sys->pctl(sys->NEWFD, fds); + console := sys->fildes(2); + + if(infd != nil){ + sys->dup(infd.fd, 0); + infd = nil; + } + if(outfd != nil){ + sys->dup(outfd.fd, 1); + outfd = nil; + } + + waitpid <-= pid; + + if(pid < 0 || arg == nil) + return; + + { + exec(ctxt, arg, console); + }exception{ + "fail:*" => + #sys->fprint(console, "%s:%s\n", hd arg, e.name[5:]); + exit; + "write on closed pipe" => + #sys->fprint(console, "%s: %s\n", hd arg, e.name); + exit; + } +} + +exec(ctxt: ref Draw->Context, args: list of string, console: ref Sys->FD) +{ + if (args == nil) + return; + cmd := hd args; + file := cmd; + + if (len file<4 || file[len file-4:]!=".dis") + file += ".dis"; + + cm : Sh9Cmd; + cm = load Sh9Cmd file; + if (cm == nil) { + err := sys->sprint("%r"); + if (err != "permission denied" && err != "access permission denied" && file[0]!='/' && file[0:2]!="./") { + cm = load Sh9Cmd "/dis/"+file; + if (cm == nil) { + err = sys->sprint("%r"); + } + } + if (cm == nil) { + sys->fprint(console, "%s: %s\n", cmd, err); + return; + } + } + + cm->init(ctxt, args); +} + +check_keywords(t: ref TokNode): ref TokNode { + case (t.tok) { + "if" => t.typ = S_IF; + "then" => t.typ = S_THEN; + "fi" => t.typ = S_FI; + "elif" => t.typ = S_ELIF; + "else" => t.typ = S_ELSE; + "while" => t.typ = S_WHILE; + "do" => t.typ = S_DO; + "done" => t.typ = S_DONE; + } + return t; +} + tokenize(line: string, line_n: int): array of ref TokNode { - toks : list of ref TokNode; - last_tok:= ref TokNode; - last_tok.start = -1; - last_tok.line = -1; - last_tok.tok = ""; - last_tok.typ = S_UNKNOWN; - k:=0; - - for (i := 0; i < len line; i++) { - if (last_tok.typ == S_DQSTR) { - case (line[i:i+1]) { - "\"" => { - l := len last_tok.tok; - if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) { - # end of str - last_tok.tok = last_tok.tok + line[i:i+1]; - (last_tok, toks) = set_last_tok(last_tok, toks); - } else { - # escaped dqte, just continue - last_tok.tok = last_tok.tok + line[i:i+1]; - } - }; - * => { - last_tok.tok = last_tok.tok + line[i:i+1]; - } - } - } else if (last_tok.typ == S_SQSTR) { - case (line[i:i+1]) { - "'" => { - l := len last_tok.tok; - if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) { - # end of str - last_tok.tok = last_tok.tok + line[i:i+1]; - (last_tok, toks) = set_last_tok(last_tok, toks); - } else { - # escaped sqte, just continue - last_tok.tok = last_tok.tok + line[i:i+1]; - } - }; - * => { - last_tok.tok = last_tok.tok + line[i:i+1]; - } - } - } else { - case (line[i:i+1]) { - " " or "\t" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - }; - "=" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "=", S_EQ) :: toks; - }; - ";" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, ";", S_SEMIC) :: toks; - }; - ":" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, ":", S_COLON) :: toks; - }; - "(" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "(", S_LPAR) :: toks; - }; - ")" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, ")", S_RPAR) :: toks; - }; - "{" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "{", S_LCURLY) :: toks; - }; - "}" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "}", S_RCURLY) :: toks; - }; - "$" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "$", S_DOLL) :: toks; - }; - "\"" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - last_tok.start = i; - last_tok.line = line_n; - last_tok.typ = S_DQSTR; - last_tok.tok = last_tok.tok + line[i:i+1]; - }; - "'" => { - (last_tok, toks) = set_last_tok(last_tok, toks); - last_tok.start = i; - last_tok.line = line_n; - last_tok.typ = S_SQSTR; - last_tok.tok = last_tok.tok + line[i:i+1]; - }; - * => { - if (last_tok.start == -1) { - last_tok.start = i; - last_tok.line = line_n; - last_tok.typ = S_ID; - } - last_tok.tok = last_tok.tok + line[i:i+1]; - }; - } - } - } - (last_tok, toks) = set_last_tok(last_tok, toks); - toks = mk_tok(i, line_n, "", S_EOL) :: toks; - toks = reverse_list(toks); - return to_array(toks); + toks : list of ref TokNode; + last_tok:= ref TokNode; + last_tok.start = -1; + last_tok.line = -1; + last_tok.tok = ""; + last_tok.typ = S_UNKNOWN; + k:=0; + + for (i := 0; i < len line; i++) { + if (last_tok.typ == S_DQSTR) { + case (line[i:i+1]) { + "\"" => { + l := len last_tok.tok; + if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) { + # end of str + last_tok.tok = last_tok.tok + line[i:i+1]; + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + } else { + # escaped dqte, just continue + last_tok.tok = last_tok.tok + line[i:i+1]; + } + }; + * => { + last_tok.tok = last_tok.tok + line[i:i+1]; + } + } + } else if (last_tok.typ == S_SQSTR) { + case (line[i:i+1]) { + "'" => { + l := len last_tok.tok; + if ((last_tok.tok[l-1:] != "\\") || ((last_tok.tok[l-1:] == "\\") && (last_tok.tok[l-2:l-1] == "\\"))) { + # end of str + last_tok.tok = last_tok.tok + line[i:i+1]; + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + } else { + # escaped sqte, just continue + last_tok.tok = last_tok.tok + line[i:i+1]; + } + }; + * => { + last_tok.tok = last_tok.tok + line[i:i+1]; + } + } + } else { + case (line[i:i+1]) { + " " or "\t" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + }; + "=" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "=", S_EQ) :: toks; + }; + ";" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, ";", S_SEMIC) :: toks; + }; + ":" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, ":", S_COLON) :: toks; + }; + "(" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "(", S_LPAR) :: toks; + }; + ")" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, ")", S_RPAR) :: toks; + }; + "{" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "{", S_LCURLY) :: toks; + }; + "}" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "}", S_RCURLY) :: toks; + }; + "$" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "$", S_DOLL) :: toks; + }; + "\"" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + last_tok.start = i; + last_tok.line = line_n; + last_tok.typ = S_DQSTR; + last_tok.tok = last_tok.tok + line[i:i+1]; + }; + "'" => { + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + last_tok.start = i; + last_tok.line = line_n; + last_tok.typ = S_SQSTR; + last_tok.tok = last_tok.tok + line[i:i+1]; + }; + * => { + if (last_tok.start == -1) { + last_tok.start = i; + last_tok.line = line_n; + last_tok.typ = S_ID; + } + last_tok.tok = last_tok.tok + line[i:i+1]; + }; + } + } + } + last_tok = check_keywords(last_tok); + (last_tok, toks) = set_last_tok(last_tok, toks); + toks = mk_tok(i, line_n, "", S_EOL) :: toks; + toks = reverse_list(toks); + return to_array(toks); +} + +zstmt_assign(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + sys->print("ASSIGN STMT\n"); + m:= c.get_current_module(); + v:= ref ModVar; + v.name= toks[0].tok; + v.val= toks[2].tok; + m.set_var(v); + return array[0] of ref TokNode; } -stmt_assign(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - sys->print("ASSIGN STMT\n"); - m:= c.get_current_module(); - v:= ref ModVar; - v.name= toks[0].tok; - v.val= toks[2].tok; - m.set_var(v); - return array[0] of ref TokNode; +unquote(s: string): string { + if (s == nil) { + return nil; + } + ls := len s; + if (len s > 2) { + if ((s[:1] == "\"") && (s[ls-1:] == "\"")) { + return s[1:ls-1]; + } else if ((s[:1] == "\'") && (s[ls-1:] == "\'")) { + return s[1:ls-1]; + } + } + return s; } -stmt_cmd_call(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - sys->print("CMD CALL\n"); - return array[0] of ref TokNode; +zstmt_cmd_call(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + sys->print("CMD CALL\n"); + args:= tokenize(toks[1].tok, 0); + pl:= ref Pipeline; + cmd:= ref Command; + cmd.args = unquote(toks[0].tok) :: cmd.args; + # sys->print("args: "); + # sys->print("%s ", toks[0].tok); + la:= len args; + for (i:=0; i<la; i++) { + cmd.args = unquote(args[i].tok) :: cmd.args; + #sys->print("%s ", args[i].tok); + } + cmd.args = reverse_list(cmd.args); + pl.cmds = cmd :: pl.cmds; + pl.term = Seq; + #sys->print("Call runpipeline\n"); + ret := runpipeline(c.ctxt, pl); + + return array[0] of ref TokNode; } -sqstr_to_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - tn:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_EXPR); - return array[1] of {tn}; +zempty(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + return array[0] of ref TokNode; } -empty(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - return array[0] of ref TokNode; +zsqstr_to_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + tn:= mk_tok(toks[0].start, toks[0].line, toks[0].tok, S_EXPR); + return array[1] of {tn}; } -var_sub_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - sys->print("VAR SUB\n"); - varname:=toks[1].tok; - if (varname == "{") { - varname = toks[2].tok; - } - v:= c.find_var_in_current_module(varname); - if (v == nil) { - sys->print("Var %s is nil\nAll vars:\n", varname); - c.print_all_vars(); - } - sys->print("VAR %s SUB: %s\n", v.name, v.val); - tn:= mk_tok(toks[0].start, toks[0].line, v.val, S_EXPR); - return array[1] of {tn}; +zvar_sub_expr(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + sys->print("VAR SUB\n"); + varname:=toks[1].tok; + if (varname == "{") { + varname = toks[2].tok; + } + v:= c.find_var_in_current_module(varname); + if (v == nil) { + sys->print("Var %s is nil\nAll vars:\n", varname); + c.print_all_vars(); + } + sys->print("VAR %s SUB: %s\n", v.name, v.val); + tn:= mk_tok(toks[0].start, toks[0].line, v.val, S_EXPR); + return array[1] of {tn}; } -expr_expr_combiner(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { - comb_tok:= toks[0].tok + " " + toks[1].tok; - tn:= mk_tok(toks[0].start, toks[0].line, comb_tok, S_EXPR); - return array[1] of {tn}; +zexpr_expr_combiner(c: ref ParserCtx, toks: array of ref TokNode): array of ref TokNode { + comb_tok:= toks[0].tok + " " + toks[1].tok; + tn:= mk_tok(toks[0].start, toks[0].line, comb_tok, S_EXPR); + return array[1] of {tn}; } mk_grammar(ctx: ref ParserCtx): array of ref GrammarNode { - semic_eol_g : GrammarNode = (array [] of {S_SEMIC, S_EOL}, S_EOL, empty, ctx); - assign_g_semic : GrammarNode = (array [] of {S_ID, S_EQ, S_EXPR, S_SEMIC}, S_NONE, stmt_assign, ctx); - assign_g_eol : GrammarNode = (array [] of {S_ID, S_EQ, S_EXPR, S_EOL}, S_NONE, stmt_assign, ctx); - sqstr_expr_g: GrammarNode = (array [] of {S_SQSTR}, nil, sqstr_to_expr, ctx); - str_expr_g: GrammarNode = (array [] of {S_STR}, S_EXPR, empty, ctx); - expr_combinator_g: GrammarNode = (array [] of {S_EXPR, S_EXPR}, nil, expr_expr_combiner, ctx); - cmd_call_semic_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_SEMIC}, nil, stmt_cmd_call, ctx); - cmd_call_eol_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_EOL}, nil, stmt_cmd_call, ctx); - - var_sub_g: GrammarNode = (array [] of {S_DOLL, S_ID}, nil, var_sub_expr, ctx); - var_sub_curl_g: GrammarNode = (array [] of {S_DOLL, S_LCURLY, S_ID, S_RCURLY}, nil, var_sub_expr, ctx); - dqstr_expr_g: GrammarNode = (array [] of {S_DQTE, S_EXPR, S_DQTE}, nil, empty, ctx); - - grammar: array of ref GrammarNode; - grammar = array [] of { - ref semic_eol_g, - ref assign_g_semic, - ref assign_g_eol, - ref sqstr_expr_g, - ref str_expr_g, - ref cmd_call_semic_g, - ref cmd_call_eol_g, - ref expr_combinator_g, - ref var_sub_g, - ref var_sub_curl_g, - }; - return grammar; + semic_eol_g : GrammarNode = (array [] of {S_SEMIC, S_EOL}, S_SEMIC, zempty, ctx); + assign_g_semic : GrammarNode = (array [] of {S_ID, S_EQ, S_EXPR, S_SEMIC}, S_NONE, zstmt_assign, ctx); + sqstr_expr_g: GrammarNode = (array [] of {S_SQSTR}, nil, zsqstr_to_expr, ctx); + str_expr_g: GrammarNode = (array [] of {S_STR}, S_EXPR, zempty, ctx); + expr_combinator_g: GrammarNode = (array [] of {S_EXPR, S_EXPR}, nil, zexpr_expr_combiner, ctx); + cmd_call_semic_g: GrammarNode = (array [] of {S_ID, S_EXPR, S_SEMIC}, nil, zstmt_cmd_call, ctx); + + var_sub_g: GrammarNode = (array [] of {S_DOLL, S_ID}, nil, zvar_sub_expr, ctx); + var_sub_curl_g: GrammarNode = (array [] of {S_DOLL, S_LCURLY, S_ID, S_RCURLY}, nil, zvar_sub_expr, ctx); + dqstr_expr_g: GrammarNode = (array [] of {S_DQTE, S_EXPR, S_DQTE}, nil, zempty, ctx); + + # simple_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI}) + # ifel_cond_g: GrammarNode = (array [] of {S_IF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI}) + # elifelifel_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELSE, S_STMT, S_FI}) + # elifeliffi_cond_g: GrammarNode = (array [] of {S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_ELIF, S_EXPR, S_SEMIC, S_THEN, S_STMT, S_FI}) + + #grammar:= array[0] of ref GrammarNode; + grammar: array of ref GrammarNode; + grammar = array [] of { + ref semic_eol_g, + ref assign_g_semic, + ref assign_g_eol, + ref sqstr_expr_g, + ref str_expr_g, + ref cmd_call_semic_g, + ref cmd_call_eol_g, + ref expr_combinator_g, + ref var_sub_g, + ref var_sub_curl_g, + }; + return grammar; } init(ctxt: ref Draw->Context, argv: list of string) { - sys = load Sys Sys->PATH; - sh9u = load Sh9Util Sh9Util->PATH; - sh9p = load Sh9Parser Sh9Parser->PATH; - sh9p->init(); - - pctx:= ref ParserCtx; - pctx.add_module("shell"); - - toks1 := tokenize("AB = 'smth \"test\" '; echo ${AB}; echo $AB", 0); - #print_toks(toks1); - #sys->print("Parse\n"); - grammar:= mk_grammar(pctx); - parse_toks(toks1, grammar); - #sys->print("Parse done\n"); - - # toks2 := tokenize("echo \"smth \" \"test\";", 0); - # print_toks(toks2); - # toks3 := tokenize("if test x\"a\" = x\"b\"; then echo \"1\"; fi", 0); - # print_toks(toks3); - # toks4 := tokenize("echo 'smth2' 'test';", 0); - # print_toks(toks4); + sys = load Sys Sys->PATH; + sh9u = load Sh9Util Sh9Util->PATH; + sh9p = load Sh9Parser Sh9Parser->PATH; + sh9p->init(); + sh9cmd = load Sh9Cmd Sh9Cmd->PATH; + + stderr = sys->fildes(2); + + waitfd = sys->open("#p/"+string sys->pctl(0, nil)+"/wait", sys->OREAD); + if(waitfd == nil){ + sys->fprint(stderr, "sh9: open wait: %r\n"); + return; + } + + sys->pctl(sys->FORKENV, nil); + sys->pctl(sys->FORKNS, nil); + + pctx:= ref ParserCtx; + pctx.add_module("shell"); + pctx.ctxt = ctxt; + + toks1 := tokenize("AB = 'smth \"test\" '; echo ${AB}; echo $AB", 0); + grammar:= mk_grammar(pctx); + parse_toks(toks1, grammar); } |
