execute.ha (2187B)
1 // Executes the Session's .cmd Command. 2 fn execute(s: *Session, cmd: *Command) (void | Error) = { 3 match (exec_addrs(s, cmd)) { 4 case void => void; 5 case let e: CmdError => 6 errormsg(s, e); // TODO: move up into caller? 7 return e; 8 }; 9 match (lookupcmd(cmd.name)(s, cmd)) { 10 case void => void; 11 case let e: Error => 12 errormsg(s, e); // TODO: move up into caller? 13 return e; 14 }; 15 16 if (len(s.buf.hist) > 0) { 17 let cseq = s.buf.hist[len(s.buf.hist) - 1]; 18 for (let i = 0z; i < len(cseq); i += 1) 19 match (cseq[i]) { 20 case let addn: Addition => 21 debug("cseq[{}]=Addition({}, {})", i, addn.0, addn.1); 22 case let deln: Deletion => 23 debug("cseq[{}]=Deletion({}, {})", i, deln.0, deln.1); 24 }; 25 }; 26 for (let i = 0z; i < len(s.buf.trash); i += 1) 27 debug("trash[{}]={}", i, s.buf.trash[i].text); 28 }; 29 30 fn exec_addrs(s: *Session, cmd: *Command) (void | CmdError) = { 31 for (let i = 0z; i < len(cmd.addrs); i += 1) { 32 const addr = cmd.addrs[i]; 33 let n = exec_addr(s, addr)?; 34 n = n + addr.lineoffset: size; // TODO: beware of negatives 35 append(cmd.linenums, n); 36 37 if (addr.setcurrentline) 38 s.buf.cursor = n; 39 }; 40 }; 41 42 fn exec_addr(s: *Session, addr: Address) (size | CmdError) = { 43 match (addr.addrform) { 44 case let n: size => 45 return addr_linenum(s.buf, n)?; 46 case CurrentLine => 47 return s.buf.cursor; 48 case LastLine => 49 return addr_lastline(s.buf); 50 case let mark: rune => 51 return addr_mark(s.buf, mark)?; 52 case let rad: RegexAddr => 53 return addr_regex(s.buf, rad, s.buf.cursor, s)?; 54 }; 55 }; 56 57 58 fn get_range(s: *Session, lns: *[]size, a: size, b: size) ((size, size) | InvalidAddress) = { 59 const (a, b) = 60 if (len(lns) == 0) 61 (a, b) 62 else if (len(lns) == 1) 63 (lns[0], lns[0]) 64 else 65 (lns[len(lns) - 2], lns[len(lns) - 1]); 66 67 if (a < 0 || a > b || b >= len(s.buf.lines)) 68 return InvalidAddress; 69 70 return (a, b); 71 }; 72 73 fn get_linenum(lns: []size, n: size) size = { 74 if (len(lns) == 0) 75 return n 76 else 77 return lns[len(lns)-1]; 78 }; 79 80 fn assert_noaddrs(s: *Session, lns: []size) (void | UnexpectedAddress) = { 81 if (len(lns) != 0) 82 return UnexpectedAddress; 83 }; 84 85 fn assert_nonzero(s: *Session, n: size) (void | InvalidAddress) = { 86 if (n < 1) 87 return InvalidAddress; 88 };