Skip to content

Commit

Permalink
Split types up, add seq/bool/int, implement if
Browse files Browse the repository at this point in the history
This is mostly cleaning and a bit of adding features. For the most part:

  * Implement the `if` command, along with short-circuiting `and`
    and `or` commands. This doesn't cover actual expressions and
    comparisons and so on yet, I suspect that will go lisp-like instead
    of `expr`-like for ease of implementation, but haven't decided yet.

  * Implement `seq`, `int`, and `bool` types. The `int` type is a
    big.Int under the hood to ensure that all integers in a particular
    range can be represented. Literals that look like integers are
    automatically converted to integers as long as their text and
    integer-as-string representations are the same (otherwise, they
    remain strings to ensure that someone passing a flag like `+1`
    to a command doesn't result in the `+` being removed). And `int`
    command is provided for manual conversions.

    `bool` is straight-forward and just wraps Go's bool type. Literals
    are converted to booleans if their string value is `true` or `false`
    and otherwise are left alone.

    The `seq` type covers a range from one number to another with
    an arbitrary step. This is mainly intended for use with foreach
    since it doesn't require generating a whole list of numbers. You
    can expand it (`... [seq 100]`) to get a whole list of numbers,
    but it probably isn't that useful most of the time.

  * Move types into their own files, except for `Values` which
    belongs to type_value.go because it's the general purpose type
    for holding everything. This is just to get a bunch of stuff out
    of interp.go.

  * Remove `doInContext` and replace it with `Interp.Eval`. Similar
    behavior, less clunky.

  * Move the dump program to cmd/mtcldebug.
  • Loading branch information
nilium committed Aug 13, 2023
1 parent e009f1e commit 4faea5d
Show file tree
Hide file tree
Showing 13 changed files with 837 additions and 322 deletions.
83 changes: 52 additions & 31 deletions dump/main.go → cmd/mtcldebug/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ func main() {
parseOnly := flag.Bool("p", false, "parse without eval")
flag.Parse()

lexer := lexer.NewLexer(os.Stdin)
lexer.Name = "stdin"

parser := mtcl.NewParser(lexer)
if *logged {
parser.LogFunc = log.Print
}

interp := mtcl.NewInterp()
interp.SetPrelude(mtcl.Prelude())

Expand All @@ -58,34 +50,63 @@ func main() {
return results, err
}))

for {
cmd, err := parser.ParseCommand()
if err == io.EOF {
return
} else if err != nil {
log.Printf("PARSE ERR: %+v", err)
}
inputs := []string{"-"}
if flag.NArg() > 0 {
inputs = flag.Args()
}

if *dump {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(cmd)
for _, input := range inputs {
r, err := file(input)
if err != nil {
log.Fatalf("Error reading input %v: %v", input, err)
}

if *parseOnly && *dump {
return
}
lexer := lexer.NewLexer(r)
lexer.Name = "stdin"

line := cmd.Token().Start.Line
fmt.Printf("%03d: %v\n", line, cmd)
if *parseOnly {
continue
parser := mtcl.NewParser(lexer)
if *logged {
parser.LogFunc = log.Print
}
vals, err := interp.Do(cmd)
if err != nil {
fmt.Printf("ERR: %v\n", err)
} else {
fmt.Printf("=> %v\n", vals)

for {
cmd, err := parser.ParseCommand()
if err == io.EOF {
break
} else if err != nil {
log.Printf("PARSE ERR: %+v", err)
}

if *dump {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(cmd)
}

if *parseOnly && *dump {
break
}

line := cmd.Token().Start.Line
fmt.Printf("%03d: %v\n", line, cmd)
if *parseOnly {
continue
}
vals, err := interp.Do(cmd)
if err != nil {
fmt.Printf("ERR: %v\n", err)
} else {
fmt.Printf("=> %v\n", vals)
}
}

r.Close()
}
}

func file(name string) (io.ReadCloser, error) {
if name == "-" {
return io.NopCloser(os.Stdin), nil
}
return os.Open(name)
}
2 changes: 0 additions & 2 deletions dump/in.tcl

This file was deleted.

Loading

0 comments on commit 4faea5d

Please sign in to comment.