SHARE
TWEET

Untitled

a guest Jul 21st, 2019 65 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package main
  2.  
  3. import (
  4.     "flag"
  5.     "fmt"
  6.     "io"
  7.     "os"
  8.     "os/exec"
  9.     "sort"
  10.     "strings"
  11.     "time"
  12. )
  13.  
  14. func init() {
  15.     sort.Strings(builtins)
  16. }
  17.  
  18. func main() {
  19.     lex := flag.Bool("lex", false, "lex")
  20.     flag.Parse()
  21.     data := []string{
  22.         "xxh -k 64 scripts/basic.go scripts/quote.go",
  23.         "find tmp/ -type f -name *txt",
  24.         "find /tmp -type f ; xxh -k 64 scripts/quote.go",
  25.         "find /tmp -type f || xxh -k 64 /tmp",
  26.         "find /tmp -type f && xxh -k 64 /tmp",
  27.         "echo foobar; find /tmp -type f && xxh -k 64 /tmp",
  28.         "echo foobar#a comment",
  29.         "find tmp/ -maxdepth 1 -type f | xxh",
  30.         "NAME=foobar",
  31.         "NAME=foobar;",
  32.         "NAME=",
  33.         "NAME=;",
  34.         "NAME=foo bar baz",
  35.         "$VAR",
  36.         "${VAR}",
  37.         "$((1+35+1))",
  38.         "$((1 + (7*5) + 1))",
  39.         "$((1 + (7 * VAR) + 1))",
  40.         "$((1 + (7 * $VAR) + 1))",
  41.     }
  42.     if *lex {
  43.         lexOnly(data)
  44.     } else {
  45.         parseOnly(data)
  46.     }
  47. }
  48.  
  49. func parseOnly(data []string) {
  50.     for i, d := range data {
  51.         if i > 0 {
  52.             fmt.Println("---")
  53.         }
  54.         fmt.Println("parsing:", d)
  55.         if c, err := NewParser(d).Parse(); err != nil {
  56.             fmt.Fprintln(os.Stderr, err)
  57.         } else {
  58.             fmt.Println(c.String())
  59.         }
  60.     }
  61. }
  62.  
  63. func lexOnly(data []string) {
  64.     for i, d := range data {
  65.         if i > 0 {
  66.             fmt.Println("---")
  67.         }
  68.         fmt.Println("lexing:", d)
  69.         x := Lex(d)
  70.         for t := x.Next(); t.Type != EOF; t = x.Next() {
  71.             fmt.Println(">", t)
  72.         }
  73.     }
  74. }
  75.  
  76. type shell struct {
  77.     globals map[string]string
  78.     locals  map[string]string
  79.  
  80.     level uint64
  81.     pwd   string // previous working directory
  82.     cwd   string // current working directory
  83.     home  string // home directory
  84.     now   time.Time
  85. }
  86.  
  87. func NewShell() *shell {
  88.     x := shell{
  89.         globals: make(map[string]string),
  90.         locals:  make(map[string]string),
  91.         now:     time.Now(),
  92.         cwd:     os.TempDir(),
  93.         pwd:     os.TempDir(),
  94.         home:    os.TempDir(),
  95.     }
  96.     x.level++
  97.     return &x
  98. }
  99.  
  100. func (s *shell) Exec() error {
  101.     return s.execCommand(nil)
  102. }
  103.  
  104. func (s *shell) execCommand(e Exec) error {
  105.     var err error
  106.     switch e.(type) {
  107.     case sequence:
  108.     case pipeline:
  109.     case logical:
  110.     case command:
  111.     default:
  112.         err = fmt.Errorf("unsupported syntax %T", e)
  113.     }
  114.     return err
  115. }
  116.  
  117. func (s *shell) Subshell() *shell {
  118.     x := NewShell()
  119.     x.level = s.level + 1
  120.     for k, v := range s.globals {
  121.         x.globals[k] = v
  122.     }
  123.     for k, v := range s.locals {
  124.         x.locals[k] = v
  125.     }
  126.     return x
  127. }
  128.  
  129. const (
  130.     bindLowest = iota
  131.     bindEqual
  132.     bindShift
  133.     bindPlus
  134.     bindMultiply
  135.     bindExponent
  136.     bindNegation
  137.     bindUnary
  138.     bindLogical
  139.     bindPipe
  140. )
  141.  
  142. var powers = map[int]int{
  143.     Background: bindLowest,
  144.     Sequence:   bindLowest,
  145.     And:        bindLogical,
  146.     Or:         bindLogical,
  147.     Pipeline:   bindPipe,
  148. }
  149.  
  150. type Exec interface {
  151.     Exec() error
  152.     Wait() error
  153.     fmt.Stringer
  154. }
  155.  
  156. type literal string
  157.  
  158. func (i literal) String() string {
  159.     return string(i)
  160. }
  161.  
  162. func (i literal) Exec() error { return nil }
  163. func (i literal) Wait() error { return nil }
  164.  
  165. type command struct {
  166.     cmd   *exec.Cmd
  167.     async bool
  168.  
  169.     stdout string
  170.     stderr string
  171.     stdin  string
  172. }
  173.  
  174. func newCommand(as []string) *command {
  175.     var c command
  176.     c.cmd = exec.Command(as[0], as[1:]...)
  177.  
  178.     return &c
  179. }
  180.  
  181. func (c command) String() string {
  182.     var b strings.Builder
  183.     b.WriteString(c.cmd.Args[0])
  184.     if len(c.cmd.Args) > 1 {
  185.         for _, a := range c.cmd.Args[1:] {
  186.             b.WriteRune(space)
  187.             b.WriteString(a)
  188.         }
  189.     }
  190.     return b.String()
  191. }
  192.  
  193. func (c command) Exec() error {
  194.     if c.cmd.Stdout == nil {
  195.         c.cmd.Stdout = os.Stdout
  196.     }
  197.     if c.cmd.Stderr == nil {
  198.         c.cmd.Stderr = os.Stderr
  199.     }
  200.     return c.cmd.Start()
  201. }
  202.  
  203. func (c command) Wait() error {
  204.     err := c.Exec()
  205.     if err == nil {
  206.         err = c.cmd.Wait()
  207.     }
  208.     return err
  209. }
  210.  
  211. type sequence []Exec
  212.  
  213. func (es sequence) String() string {
  214.     var b strings.Builder
  215.     for i, e := range es {
  216.         if i >= 1 {
  217.             b.WriteRune(space)
  218.         }
  219.         b.WriteString(e.String())
  220.         b.WriteRune(semicolon)
  221.     }
  222.     return b.String()
  223. }
  224.  
  225. func (es sequence) Exec() error {
  226.     return es.Wait()
  227. }
  228.  
  229. func (es sequence) Wait() error {
  230.     var err error
  231.     for _, e := range es {
  232.         err = e.Wait()
  233.     }
  234.     return err
  235. }
  236.  
  237. type logical struct {
  238.     op    int
  239.     left  Exec
  240.     right Exec
  241. }
  242.  
  243. func (i logical) String() string {
  244.     var op string
  245.     switch i.op {
  246.     case And:
  247.         op = "&&"
  248.     case Or:
  249.         op = "||"
  250.     default:
  251.         op = "???"
  252.     }
  253.     var b strings.Builder
  254.     b.WriteString(i.left.String())
  255.     b.WriteRune(space)
  256.     b.WriteString(op)
  257.     b.WriteRune(space)
  258.     b.WriteString(i.right.String())
  259.  
  260.     return b.String()
  261. }
  262.  
  263. func (i logical) Exec() error {
  264.     return i.Wait()
  265. }
  266.  
  267. func (i logical) Wait() error {
  268.     var fn func(Exec, Exec) error
  269.     switch i.op {
  270.     case Or:
  271.         fn = evalOr
  272.     case And:
  273.         fn = evalAnd
  274.     default:
  275.     }
  276.     if fn == nil {
  277.         return fmt.Errorf("unkown logical operator")
  278.     }
  279.     return fn(i.left, i.right)
  280. }
  281.  
  282. func evalOr(left, right Exec) error {
  283.     err := left.Wait()
  284.     if err != nil {
  285.         err = right.Wait()
  286.     }
  287.     return err
  288. }
  289.  
  290. func evalAnd(left, right Exec) error {
  291.     err := left.Wait()
  292.     if err == nil {
  293.         err = right.Wait()
  294.     }
  295.     return err
  296. }
  297.  
  298. type pipeline []Exec
  299.  
  300. func (p pipeline) Exec() error {
  301.     return p.Wait()
  302. }
  303.  
  304. func (p pipeline) Wait() error {
  305.     var pipe io.Reader = os.Stdin
  306.     for i, e := range p {
  307.         if c, ok := e.(*command); ok {
  308.             c.cmd.Stdin = pipe
  309.             pipe, _ = c.cmd.StdoutPipe()
  310.         } else {
  311.             return fmt.Errorf("invalid construct")
  312.         }
  313.  
  314.         if i < len(p)-1 {
  315.             go e.Wait()
  316.         }
  317.     }
  318.     go io.Copy(os.Stdout, pipe)
  319.     return p[len(p)-1].Wait()
  320. }
  321.  
  322. func (p pipeline) String() string {
  323.     var b strings.Builder
  324.     for i, e := range p {
  325.         if i >= 1 {
  326.             b.WriteRune(space)
  327.             b.WriteRune(pipe)
  328.             b.WriteRune(space)
  329.         }
  330.         b.WriteString(e.String())
  331.     }
  332.     return b.String()
  333. }
  334.  
  335. type assignment struct {
  336.     ident string
  337.     value Exec
  338. }
  339.  
  340. func (a assignment) Exec() error {
  341.     return nil
  342. }
  343.  
  344. func (a assignment) Wait() error {
  345.     return nil
  346. }
  347.  
  348. func (a assignment) String() string {
  349.     var b strings.Builder
  350.  
  351.     b.WriteString(a.ident)
  352.     b.WriteRune(equal)
  353.     if a.value != nil {
  354.         b.WriteString(a.value.String())
  355.     }
  356.  
  357.     return b.String()
  358. }
  359.  
  360. type arithmetic struct {
  361.     expr Expression
  362. }
  363.  
  364. func (a arithmetic) String() string {
  365.     return a.expr.String()
  366. }
  367.  
  368. func (a arithmetic) Exec() error {
  369.     return nil
  370. }
  371.  
  372. func (a arithmetic) Wait() error {
  373.     return nil
  374. }
  375.  
  376. type Expression interface {
  377.     fmt.Stringer
  378. }
  379.  
  380. type unary struct {
  381.     op    byte
  382.     right Expression
  383. }
  384.  
  385. type infix struct {
  386.     op    byte
  387.     left  Expression
  388.     right Expression
  389. }
  390.  
  391. var builtins = []string{
  392.     "echo",
  393.     "cd",
  394.     "pwd",
  395.     "now",
  396.     "export",
  397.     "true",
  398.     "false",
  399.     "wait",
  400. }
  401.  
  402. type parser struct {
  403.     lex *lexer
  404.  
  405.     // prefix infix function to parse shell construct
  406.     prefix map[int]func() (Exec, error)
  407.     infix  map[int]func(Exec) (Exec, error)
  408.  
  409.     curr Token
  410.     peek Token
  411. }
  412.  
  413. type mathparser struct {
  414.     lex *lexer
  415.  
  416.     prefix map[byte]func() (Expression, error)
  417.     infix  map[byte]func(Expression) (Expression, error)
  418.  
  419.     curr Token
  420.     peek Token
  421. }
  422.  
  423. func parseMath(lex *lexer) (Expression, error) {
  424.     var p mathparser
  425.     p.init(lex)
  426.  
  427.     return p.parseExpression(bindLowest)
  428. }
  429.  
  430. func (p *mathparser) init(lex *lexer) {
  431.     p.lex = lex
  432.     p.prefix = map[byte]func() (Expression, error){}
  433.     p.infix = map[byte]func(Expression) (Expression, error){}
  434.  
  435.     p.nextToken()
  436.     p.nextToken()
  437. }
  438.  
  439. func (p *mathparser) parseExpression(power int) (Expression, error) {
  440.     prefix, ok := p.prefix[p.curr.Type]
  441.     if !ok {
  442.         return nil, fmt.Errorf("can not parse %s as prefix operator", p.curr)
  443.     }
  444.     left, err := prefix()
  445.     if err != nil {
  446.         return nil, err
  447.     }
  448.     for power < p.peekPower() {
  449.         infix, ok := p.infix[p.peek.Type]
  450.         if !ok {
  451.             return nil, fmt.Errorf("can not parse %s as infix operator", p.curr)
  452.         }
  453.         left, err = infix(left)
  454.         if err != nil {
  455.             return nil, err
  456.         }
  457.     }
  458.     return left, nil
  459. }
  460.  
  461. func (m *mathparser) nextToken() {
  462.     m.curr = m.peek
  463.     m.peek = m.lext.nextToken()
  464. }
  465.  
  466. func NewParser(str string) *parser {
  467.     var p parser
  468.     p.prefix = map[int]func() (Exec, error){
  469.         Literal:    p.parseSimple,
  470.         Builtin:    p.parseSimple,
  471.         Identifier: p.parseAssignment,
  472.         Arithmetic: p.parseArithmetic,
  473.     }
  474.     p.infix = map[int]func(Exec) (Exec, error){
  475.         And:      p.parseLogical,
  476.         Or:       p.parseLogical,
  477.         Pipeline: p.parsePipe,
  478.     }
  479.     p.lex = Lex(str)
  480.     p.nextToken()
  481.     p.nextToken()
  482.  
  483.     return &p
  484. }
  485.  
  486. func (p *parser) Parse() (Exec, error) {
  487.     xs := make(sequence, 0, 8)
  488.     for !p.isDone() {
  489.         e, err := p.parseCommand(bindLowest)
  490.         if err != nil {
  491.             return nil, err
  492.         }
  493.         xs = append(xs, e)
  494.         p.nextToken()
  495.     }
  496.     return xs, nil
  497. }
  498.  
  499. func (p *parser) parseCommand(power int) (Exec, error) {
  500.     fmt.Println("parseCommand:", p.curr)
  501.     prefix, ok := p.prefix[p.curr.Type]
  502.     if !ok {
  503.         return nil, fmt.Errorf("can not parse %s as command prefix", p.curr)
  504.     }
  505.     e, err := prefix()
  506.     if err != nil {
  507.         return nil, err
  508.     }
  509.     for !p.isComplete() && power < p.currPower() {
  510.         infix, ok := p.infix[p.curr.Type]
  511.         if !ok {
  512.             return nil, fmt.Errorf("can not parse %s as command infix", p.peek)
  513.         }
  514.         e, err = infix(e)
  515.         if err != nil {
  516.             return nil, err
  517.         }
  518.     }
  519.     return e, nil
  520. }
  521.  
  522. func (p *parser) parseArithmetic() (Exec, error) {
  523.     fmt.Println("parseArithmetic:", p.curr)
  524.     i := literal(p.curr.Literal)
  525.     if _, err := parseMath(p.lex); err != nil {
  526.         return nil, err
  527.     }
  528.     p.nextToken()
  529.     return i, nil
  530. }
  531.  
  532. func (p *parser) parseAssignment() (Exec, error) {
  533.     fmt.Println("parseAssignment:", p.curr)
  534.     a := assignment{ident: p.curr.Literal}
  535.     p.nextToken()
  536.     if p.curr.Type != Assign {
  537.         return nil, fmt.Errorf("invalid syntax: %s", p.curr)
  538.     }
  539.     var err error
  540.     if typ := p.peek.Type; typ != EOF && typ != Sequence {
  541.         p.nextToken()
  542.         a.value, err = p.parseSimple()
  543.     } else {
  544.         p.nextToken()
  545.     }
  546.     return a, err
  547. }
  548.  
  549. func (p *parser) parsePipe(left Exec) (Exec, error) {
  550.     fmt.Println("parsePipe:", p.curr)
  551.     ps := make(pipeline, 0, 8)
  552.     ps = append(ps, left)
  553.  
  554.     for !p.isComplete() {
  555.         p.nextToken()
  556.         left, err := p.parseSimple()
  557.         if err != nil {
  558.             return nil, err
  559.         }
  560.         ps = append(ps, left)
  561.         if p.curr.Type != Pipeline && p.curr.Type != EOF {
  562.             return nil, fmt.Errorf("invalid syntax: %s", p.peek)
  563.         }
  564.     }
  565.     return ps, nil
  566. }
  567.  
  568. func (p *parser) parseLogical(left Exec) (Exec, error) {
  569.     fmt.Println("parseLogical:", p.curr)
  570.     logic := logical{
  571.         left: left,
  572.         op:   p.curr.Type,
  573.     }
  574.     p.nextToken()
  575.     right, err := p.parseSimple()
  576.     if err != nil {
  577.         return nil, err
  578.     }
  579.     logic.right = right
  580.     return logic, nil
  581. }
  582.  
  583. func (p *parser) parseSimple() (Exec, error) {
  584.     fmt.Println("parseSimple:", p.curr)
  585.     var args []string
  586.     for {
  587.         if p.isComplete() || p.isControl(p.curr) {
  588.             break
  589.         }
  590.         args = append(args, p.curr.Literal)
  591.         p.nextToken()
  592.     }
  593.     return newCommand(args), nil
  594. }
  595.  
  596. func (p *parser) isControl(tok Token) bool {
  597.     t := tok.Type
  598.     return t == And || t == Or || t == Background || t == Pipeline || t == Sequence || t == EOF
  599. }
  600.  
  601. func (p *parser) isComplete() bool {
  602.     return p.curr.Type == EOF || p.curr.Type == Sequence || p.curr.Type == Comment
  603. }
  604.  
  605. func (p *parser) isDone() bool {
  606.     return p.curr.Type == EOF
  607. }
  608.  
  609. func (p *parser) currPower() int {
  610.     return bindingPower(p.curr)
  611. }
  612.  
  613. func (p *parser) peekPower() int {
  614.     return bindingPower(p.peek)
  615. }
  616.  
  617. func (p *parser) nextToken() {
  618.     if p.isDone() {
  619.         return
  620.     }
  621.     p.curr = p.peek
  622.     p.peek = p.lex.Next()
  623.     if p.curr.Type == Comment {
  624.         for !p.isDone() {
  625.             p.nextToken()
  626.         }
  627.     }
  628. }
  629.  
  630. func bindingPower(tok Token) int {
  631.     p, ok := powers[tok.Type]
  632.     if !ok {
  633.         p = bindLowest
  634.     }
  635.     return p
  636. }
  637.  
  638. const (
  639.     eof       = 0
  640.     tab       = '\t'
  641.     space     = ' '
  642.     dollar    = '$'
  643.     semicolon = ';'
  644.     ampersand = '&'
  645.     pipe      = '|'
  646.     comment   = '#'
  647.     quote     = '\''
  648.     lparen    = '('
  649.     rparen    = ')'
  650.     lcurly    = '{'
  651.     rcurly    = '}'
  652.     langle    = '<'
  653.     rangle    = '>'
  654.     equal     = '='
  655.     question  = '?'
  656.     bang      = '!'
  657.     plus      = '+'
  658.     minus     = '-'
  659.     star      = '*'
  660.     slash     = '/'
  661. )
  662.  
  663. const (
  664.     EOF = -(iota + 1)
  665.     Literal
  666.     Builtin
  667.     Identifier
  668.     Variable
  669.     Arithmetic
  670.     Comment
  671.     And
  672.     Or
  673.     Pipeline
  674.     Background
  675.     Sequence
  676.     Assign
  677.     Unknown
  678.     Invalid
  679. )
  680.  
  681. var labels = []string{
  682.     "invalid",
  683.     "unknown",
  684.     "assignment",
  685.     "sequence",
  686.     "background",
  687.     "pipeline",
  688.     "or",
  689.     "and",
  690.     "comment",
  691.     "arithmetic",
  692.     "variable",
  693.     "identifier",
  694.     "builtin",
  695.     "literal",
  696.     "eof",
  697. }
  698.  
  699. type Token struct {
  700.     Op      byte
  701.     Type    int
  702.     Literal string
  703. }
  704.  
  705. func (t Token) String() string {
  706.     n := len(labels) + t.Type
  707.  
  708.     var str string
  709.     if n < 0 {
  710.         str = labels[0]
  711.     } else {
  712.         str = labels[n]
  713.     }
  714.     return fmt.Sprintf("<%s (%s)>", str, t.Literal)
  715. }
  716.  
  717. type lexerState uint16
  718.  
  719. const (
  720.     lexDefault lexerState = iota
  721.     lexStrict
  722.     lexWeak
  723.     lexSubshell
  724.     lexArithmetic
  725. )
  726.  
  727. type lexer struct {
  728.     input []byte
  729.  
  730.     char byte
  731.     pos  int
  732.     next int
  733.  
  734.     scan func() Token
  735. }
  736.  
  737. func Lex(str string) *lexer {
  738.     x := lexer{input: []byte(str)}
  739.     x.readByte()
  740.  
  741.     return &x
  742. }
  743.  
  744. func (x *lexer) scanArithmetic() Token {
  745.     var tok Token
  746.     if b := x.peekByte(); x.char == rparen && (b == rparen || b == eof) {
  747.         fmt.Println("all done")
  748.         x.scan = nil
  749.  
  750.         tok.Type = EOF
  751.         return tok
  752.     }
  753.     switch {
  754.     case isDigit(x.char):
  755.         x.readNumber(&tok)
  756.     case isLetter(x.char) || x.char == dollar:
  757.         if x.char == dollar {
  758.             x.readByte()
  759.         }
  760.         tok.Type = Variable
  761.         x.readLiteral(&tok)
  762.     default:
  763.         tok.Literal = string(x.char)
  764.         tok.Type, tok.Op = Arithmetic, x.char
  765.         x.readByte()
  766.     }
  767.     return tok
  768. }
  769.  
  770. func (x *lexer) Next() Token {
  771.     var tok Token
  772.     if x.char == eof {
  773.         tok.Type = EOF
  774.         return tok
  775.     }
  776.  
  777.     x.skipBlank()
  778.     if x.scan != nil {
  779.         return x.scan()
  780.     }
  781.  
  782.     switch {
  783.     case x.char == '$':
  784.         x.readByte()
  785.         if b := x.peekByte(); x.char == lcurly || isLetter(b) {
  786.             tok.Type = Variable
  787.             if x.char == lcurly {
  788.                 x.readByte()
  789.                 x.readUntil(&tok, func(b byte) bool { return b == rcurly })
  790.             } else {
  791.                 x.readLiteral(&tok)
  792.             }
  793.         } else if x.char == lparen && b == lparen {
  794.             tok.Type = Arithmetic
  795.             x.readByte()
  796.             x.scan = x.scanArithmetic
  797.         } else if x.char == question || x.char == bang {
  798.             tok.Type = Variable
  799.         }
  800.     case isControl(x.char):
  801.         x.readControl(&tok)
  802.     case isComment(x.char):
  803.         x.readByte()
  804.         x.readComment(&tok)
  805.     default:
  806.         x.readLiteral(&tok)
  807.         if b := x.peekByte(); x.char == equal && (!isBlank(b) || b == eof) {
  808.             tok.Type = Identifier
  809.         }
  810.     }
  811.     x.readByte()
  812.  
  813.     return tok
  814. }
  815.  
  816. func (x *lexer) readUntil(tok *Token, fn func(b byte) bool) {
  817.     pos := x.pos
  818.     for !fn(x.char) {
  819.         x.readByte()
  820.     }
  821.     tok.Literal = string(x.input[pos:x.pos])
  822. }
  823.  
  824. func (x *lexer) readNumber(tok *Token) {
  825.     pos := x.pos
  826.     for isDigit(x.char) {
  827.         x.readByte()
  828.     }
  829.     tok.Literal = string(x.input[pos:x.pos])
  830.     tok.Type = Literal
  831. }
  832.  
  833. func (x *lexer) readLiteral(tok *Token) {
  834.     pos := x.pos
  835.     for {
  836.         if isSeparator(x.char) || isComment(x.char) {
  837.             break
  838.         }
  839.         x.readByte()
  840.     }
  841.  
  842.     tok.Literal = string(x.input[pos:x.pos])
  843.     if tok.Type >= 0 {
  844.         tok.Type = Literal
  845.     }
  846.     if isSeparator(x.char) || isComment(x.char) {
  847.         x.unreadByte()
  848.     }
  849.     ix := sort.SearchStrings(builtins, tok.Literal)
  850.     if ix < len(builtins) && builtins[ix] == tok.Literal {
  851.         tok.Type = Builtin
  852.     }
  853. }
  854.  
  855. func (x *lexer) readComment(tok *Token) {
  856.     pos := x.pos
  857.     for x.char != eof {
  858.         x.readByte()
  859.     }
  860.     tok.Literal, tok.Type = string(x.input[pos:x.pos]), Comment
  861. }
  862.  
  863. func (x *lexer) readControl(tok *Token) {
  864.     switch x.char {
  865.     case ampersand:
  866.         x.readByte()
  867.         if x.char == ampersand {
  868.             tok.Type = And
  869.         } else {
  870.             tok.Type = Background
  871.         }
  872.     case pipe:
  873.         x.readByte()
  874.         if x.char == pipe {
  875.             tok.Type = Or
  876.         } else {
  877.             tok.Type = Pipeline
  878.         }
  879.     case semicolon:
  880.         tok.Type = Sequence
  881.     case equal:
  882.         tok.Type = Assign
  883.     default:
  884.         tok.Type = Invalid
  885.     }
  886. }
  887.  
  888. func (x *lexer) peekByte() byte {
  889.     if x.next >= len(x.input) {
  890.         return eof
  891.     }
  892.     return x.input[x.next]
  893. }
  894.  
  895. func (x *lexer) readByte() {
  896.     if x.next >= len(x.input) {
  897.         x.char = eof
  898.     } else {
  899.         x.char = x.input[x.next]
  900.     }
  901.     x.pos = x.next
  902.     x.next++
  903. }
  904.  
  905. func (x *lexer) unreadByte() {
  906.     x.next = x.pos
  907.     x.pos--
  908. }
  909.  
  910. func (x *lexer) skipBlank() {
  911.     for isBlank(x.char) {
  912.         x.readByte()
  913.     }
  914. }
  915.  
  916. func isSeparator(b byte) bool {
  917.     return isBlank(b) || isControl(b)
  918. }
  919.  
  920. func isBlank(b byte) bool {
  921.     return b == space || b == tab || b == eof
  922. }
  923.  
  924. func isMath(b byte) bool {
  925.     return b == plus || b == minus || b == slash || b == star
  926. }
  927.  
  928. func isControl(b byte) bool {
  929.     return b == ampersand || b == pipe || b == semicolon || b == equal
  930. }
  931.  
  932. func isComment(b byte) bool {
  933.     return b == comment
  934. }
  935.  
  936. func isQuote(b byte) bool {
  937.     return b == quote
  938. }
  939.  
  940. func isLetter(b byte) bool {
  941.     return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
  942. }
  943.  
  944. func isDigit(b byte) bool {
  945.     return b >= '0' && b <= '9'
  946. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top