Giter Site home page Giter Site logo

wduquette / molt Goto Github PK

View Code? Open in Web Editor NEW
103.0 8.0 12.0 3.72 MB

Embeddable TCL Interpreter for Rust applications

License: BSD 3-Clause "New" or "Revised" License

Rust 79.43% Tcl 10.69% JavaScript 4.07% CSS 3.30% HTML 2.51%
tcl rust interpreter extension-language interp molt

molt's Issues

Add `rename` command

Add the rename command, per standard TCL. (And update tests requiring cleanup to make use of it.)

"set a(1)" for unknown index 1 throws "no such variable"

If the variable a doesn't exist, then set a(1) should throw can't read "a(1)": no such variable. But if a exists and is an array variable but doesn't contain that element, it should throw can't read "a(1)": no such element in array. At present it throws the no such variable message in both cases.

Full TCL return/error protocol

Standard TCL's return and error methods allow TCL code to return and process any valid return code (including break and continue) which is important when implementing control structures, as well as error codes on error returns. It isn't clear that Molt needs all of this machinery, but ultimately we probably want to provide it.

Test -setup, -cleanup

The test harness' test command should support -setup and -cleanup scripts, as standard TCL's tcltest(n) package does.

Command: info locals

Implement info locals command, per Standard Tcl

  • Command in commands.rs
  • Reference in molt-book/ref/info.md
  • Tests in molt/tests/info.tcl

`info vars` should take pattern argument.

In Standard TCL, several of the info subcommands, e.g., info vars and info commands, take an optional glob-pattern argument, and return a list of names that match the pattern. Molt's version should do the same when the glob matching feature is available. This must wait on #18. Then, update all of the relevant info subcommands.

List parsing terminates on semi-colon

The list parser's parse_list method use while !ctx.at_end_of_command() to iterate through the list to be parsed. This works fine unless a list element begins with a semicolon:

% set a {a b ;c d}
a b ;c d
% foreach item $a {puts $item}
a
b
% 

Add 'error' command

Implement a minimal version of the standard TCL error command. (The full error/return syntax will wait for later).

I.e., "error message"

Fix expr floating point handling

Molt handling of floating point numbers is lacking. The expr command doesn't understand NaN, Inf, or -Inf, so floating point errors are mishandled. Also, floating point output of whole numbers loses the ".0", and so floats are magically transferred into integers. This area needs to be looked at, and fixed. Probably this issue should result in a number of more specific issues.

Add Continuous Integration

I recommend adding continuous integration and associated badges to automate testing across many platforms and to communicate project health.

I've used trust which uses TravisCI and AppVeyor to cover many targets including Windows, Linux, iOS, Android, macOS, and the BSDs.

actions-rs is another option that uses the newer GitHub Actions. I haven't used it but it looks promising.

Command: info cmdtype

Implement info cmdtype per Standard TCL. At present, there are only two kinds: native and proc.

Integer Division is incorrect

The expr command has an error. The expression M/N should always return 0 where M and N are integers and M < abs(N). This works correctly if N is positive, but if N is negative the result is -1 if M is positive, and 1 if M is negative.

% expr {1/-2}
-1
% expr {-1/-2}
1

The magnitude of the divisor doesn't matter, so long as abs(M) < abs(N).

molt-shell: Rustyline should be a feature for molt-shell.

At present, molt-shell uses rustyline always. Per the rustyline home page, though, rustyline doesn't support a couple of popular terminals, including cygwin's mintty. Use of rustyline should be a feature that can be disabled at build time.

Put molt::shell() in new crate molt-shell

The Molt interactive shell requires rustyline, which is both large and often unneeded in Molt's expected use case. It should go in a separate crate, so that clients need not include rustyline.

Consider no_std

First off, thank you for this project! I am fascinated by Tcl, and I'm including molt in a little cli to let users write some light extensions. It's already super fun and just setting/getting vars is all I need.

Have you considered supporting no_std rust? There are existing no_std compatible allocators, and many other libraries are available.
https://lib.rs/no-std

Tcl has such a great heritage in embedded programming. It would be cool if the molt interpreter could go down to bare metal.

Implement Debug for molt::Value

The derived Debug for molt::Value is ugly and unhelpful. Because the string-rep is saved in an UnsafeCell it isn't visible; and because the internal structure of a Value is complex, the output is hard to read anyway. Add a better Debug.

Questions:

  • Create the string_rep if it doesn't exist?
  • Display the debug for the data_rep if the data_rep exists?
  • If the string_rep is large, truncate it?

expr command should check for integer overflow.

TCL 7.6 uses the standard C library's matherr() feature to detect integer and floating point errors. This doesn't exist in Rust; consequently, the Molt expr implementation just does addition, subtraction, etc., and doesn't currently worry about it.

The Rust philosophy, as I understand it, is to check for these kinds of errors and panic in development, and recover (i.e., by wrapping integers around) in operations. Consequently, such errors will cause the Molt interpreter to crash or silently fail, which isn't ideal.

However, the Rust integer types also provide a set of "checked" numeric operations that return Option on overflow or divide by zero. They don't explicitly indicate the error; but for integers, it's either divide by zero or overflow, and we already check for divide by zero.

Set the Interp's default input and output streams

At present Molt writes directly to stdout, e.g., the puts command simply uses println!(). The molt-shell functions do the same. This makes it difficult to write Rust tests for them. It should instead be made possible to set the I/O streams for the Interp, and the Molt library code should use those streams. That would allow a test to redirect them.

Implicit Numeric Parsing fails on whitespace

In molt, this code returns an error:

$ exit " 1 "
expected integer but got " 1 "
$

In Standard Tcl the command is accepted; and a look at Tcl_GetInt in Tcl 7.6 shows that it explicitly looks for and skips leading and trailing whitespace.

Molt uses Value::as_int to try to retrieve an integer from the argument; Value::as_int (and Interp::get_int, at time of writing) does not.

Support hexadecimal integer input

Standard TCL supports integer input as decimal, octal (with leading 0), and hex (with leading 0x). Molt currently supports only decimal. Octal input has been a fruitful source of unexpected errors over the years, so Molt isn't going to support it; but it should support hex.

Command: info globals

Implement info globals command, per Standard TCL.

  • Command, in commands.rs
  • Reference in molt-book/ref/info.md
  • Tests in molt/tests/info.tcl

Floating point formatting

Molt relies on Rust's default floating point string formatting (except for special handling for Inf, -Inf, and NaN); and Rust's default formatting isn't what we need. In particular, we need to be very sure that (A) the output is pleasant for humans to read and (B) will be parsed into exactly the same number. Tcl 8 has a detailed algorithm for this.

Evaluation stack depth checking

Standard TCL maintains a count of the stack depth, and terminates execution if it gets too deep. The maximum stack depth is a configurable parameter on the Interp. This mechanism needs to be supported in the same way in Molt.

test-harness should allow skipping tests

Standard TCL's tcltest(n) package allows tests to be skipped for a variety of reasons, e.g., excluded features, platform dependencies, or just simply as a temporary exclusion. The test harness should provide the same feature.

Command: info default

Add info default command, per Standard TCL.

  • Command, in commands.rs
  • Reference in molt-book/ref/info.md
  • Tests in molt/tests/info.tcl

Implement "-e CMD" in moltsh

Jim Tcl has the command line option -e CMD that prints the result of the last command in the script CMD.

> jimsh -e 'set a $argv; lappend a baz' foo bar
foo bar baz

It makes Jim easier to use from the shell than Tcl 8.x, particularly in pipelines where you can't do echo $code | tclsh. It would be nice to see this option in the Molt shell. In general, I think Jim Tcl is worth looking at as a source of ideas for any new Tcl implementation.

Molt expr rejects std::i64::MIN

The expr command's parsing first identifies a number as a valid integer, then applies the unary minus. As it happens, abs(std::i64::MIN) == std::i64::MAX + 1; and so you can't actually enter std::i64::MIN in a Molt expression.

molt_shell::repl should support continuation lines

The molt_shell::repl should use Interp::complete to detect incomplete lines, and allow the user to enter continuation lines until the command is complete. It should use > as the completion prompt, unless the tcl_prompt2 variable is defined.

  • If tcl_prompt2 is defined, evaluate its value as a script (Interp::eval).
  • On success, the result is the continuation prompt string.
  • On failure, output the error message; then, on the next line, the default continuation prompt.

Command: info exists

Add info exists command, per Standard TCL

  • Command, in commands.rs
  • Reference in molt-book/ref/info.md
  • Tests in molt/tests/info.tcl

Provide TCL Stack Trace

Standard TCL provides a detailed stack trace when an error is caught; Molt at present does not. It should provide some form of the same thing. There is no need to replicate TCL's precise text, which is meant to be human readable; something simpler and more cognate to TCL 8.7's "info errorstack" or "info frame" will be better.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.