Commit Graph

167 Commits

Author SHA1 Message Date
Nicholas Wiersma
f3f9ffaea7 feat: add builtin type checking
This adds type checking for builtin functions. It also refactors builtin names into constants due to the number of times they are used.
2020-08-27 14:02:04 +02:00
mpl
896bfeb5a1 interp: new EvalPath API
The recent changes that added some redeclaration checks implicitly added more
strictness related to namespaces and scopes which, among other things, broke
some uses that "accidentally" used to work.

For example, given

const script1 = `
	import "fmt"

	// more code
`
const script2 = `
	import "fmt"

	// some other code
`
If one Evals script1, then script2, with the same interpreter, without
specifying any scope, as the two fragments would be considered part of the same
(.go file) scope by default, a redeclaration error would be triggered because
import "fmt" is seen twice.

A work-around would have been to specify (a different) i.Name before each Eval
call, so that each script is considered as coming from a different .go file, and
hence are respectively in different scopes with respect to imports.

That lead us to realize we had to make specifying things such as file-scope, and
"incremental mode" (aka REPL), more obvious in the context of an Eval call.

In addition, we want to lay down the foundations for Yaegi being able to behave
more like the go tool wrt to various inputs, i.e. it should be able to take a
package directory, or an import path, as input, instead of just a .go file.

Hence the introduction of a new kind of Eval method (whose signature is not fixed yet):

func (interp *Interpreter) EvalPath(path string) (res reflect.Value, err error)

It partially solves the problem described above because:

1. the path given to EvalPath can be used as the file-scope hint mentioned
above, for now (even though the related implementation details might change).
2. Eval always runs in incremental mode, whereas EvalPath always runs in
non-incremental mode, hence clarifying the situation in that respect.

And to avoid confusion, the Name field of Interpreter is now non-exported,
since it is somewhat redundant with the path argument of EvalPath.

Note that #731 is not fully fixed (and might never be), as a requirement of the
proposed solution is to move the input bits of code into respective files
(instead of leaving them as strings).

Finally, some related bugfixes, documention changes, and some refactoring have
been included. Notably, there is no "empty scope" anymore, i.e. name defaults
to "_.go" when it is not specified.

Updates #731
Fixes #778
Fixes #798
Fixes #789 

Co-authored-by: Marc Vertes <mvertes@free.fr>
2020-08-20 13:14:15 +02:00
Marc Vertes
b0cd93a936 fix: correct interrupt signal handling in REPL
Avoid goroutines leak, accumulation of defered functions and
spurious resets of signal handlers. Effectively catch interrupt
signal (Ctrl-C) to cancel current eval.

Fixes #713.
2020-08-12 22:22:03 +02:00
mpl
611a8c37fa interp: make REPL stricter about parsing errors
So far the REPL loop was treating any parsing error coming from
go/parser to generate the AST, as having occurred because the source
code was not yet complete (unfinished block). And it was therefore
ignoring all of them.

However, some of these errors are legitimate, and must be caught as soon
as they occur, otherwise the REPL cycle would stay in an errored state
forever (even when the block terminates), without the user getting any
feedback about it.

Therefore, this change adds an extra check when a parsing error occurs,
i.e. it verifies that it looks like an "EOF" error (unfinished block)
before it ignores it (as the user is supposed to terminate the block
eventually). Otherwise the error is treated just like a "non-parsing"
(cfg, gta, ...) error and printed out.

Fixes #637
2020-08-12 18:44:21 +02:00
Nicholas Wiersma
bd4ce37baa feat: refactor type checking
The previous type checking was off and did not do untyped type conversion. This endeavours to fix this with better type checking in its own type.
2020-07-31 14:00:03 +02:00
Nicholas Wiersma
98eacf3610 fix: execute global variables in the correct order
* fix: constant definition loop on out of order vars

* fix: do not wire global varDecl

* fix: wire and execute global vars

* chore: add tests

* fix: refactor and lint
2020-07-09 14:05:03 +02:00
Marc Vertes
b3766509cc feature: restrict symbols which can exit the interpreter process
* feature: restrict symbols which can exit the interpreter process

Some symbols such as os.Exit or log.Fatal, which make the current process
to exit, are now restricted. They are replaced by a version which panics
instead of exiting, as panics are recovered by Eval.

The restricted os.FindProcess version is identical to the original
except it errors when trying to return the self process, in order to
forbid killing or signaling the interpreter process from script.

The os/exec symbols are available only through unrestricted package.

The original symbols are stored in an unrestricted package, which
requires an explicit Use, as for unsafe and syscall packages.

The Use() interpreter method has been slightly modified to allow inplace
updating of package symbols, allowing to replace some symbols but not
the entire imported package.

A command line option -unrestricted has been added to yaegi CLI to use
the unrestricted symbols.

Fixes #486.

* fix: lint
2020-07-08 22:35:04 +02:00
Marc Vertes
9977ef6fc6 Revert "fix: make interpreter methods discoverable by runtime (#722)" (#732)
This reverts commit a3b2737b5c.
2020-07-01 16:16:26 +02:00
Marc Vertes
a3b2737b5c fix: make interpreter methods discoverable by runtime (#722)
* fix: make interpreter methods discoverable by runtime

When generating an interface wrapper, lookup existing wrappers by method
to get the one with the biggest set of methods implemented by interpreter.

A string method is also added to wrappers, in order to provide a string
representation of the interpreter value rather than the wrapper itself
(at least for %s and %v verbs).

This allows the runtime to pickup an interpreter method automatically
even if the conversion to the interface is not specified in the script. As
in Go spec, it is enough for the type to implement the required methods.

A current limitation is that only single wrappers can be instantiated,
not allowing to compose interfaces.

This limitation can be removed when the Go reflect issue
https://github.com/golang/go/issues/15924 is fixed.

Fixes #435.

* test: add a simpler test
2020-06-29 14:25:14 +02:00
Nicholas Wiersma
9627782394 feature: add Sizeof and Alignof to unsafe 2020-06-22 15:24:04 +02:00
Ludovic Fernandez
a6c24a0d13 chore: update linter. (#706)
* chore: update linter.

* chore: remove not needed travis env var.
2020-06-22 12:55:42 +02:00
Nicholas Wiersma
f19b7563ea feature: unsafe type conversion 2020-06-18 18:14:03 +02:00
Nicholas Wiersma
36836cd4f2 fix: return correct package name for parsed package (#679)
Co-authored-by: Marc Vertes <mvertes@free.fr>
2020-06-10 12:17:10 +02:00
mpl
5d56bac8d0 interp: extend dot debugging 2020-05-26 22:38:03 +02:00
Marc Vertes
7eac6955b3 feature: pre-import used packages in REPL mode. 2020-05-04 16:18:05 +02:00
Dan Kortschak
3548c8744e interp: weaken panics to errors and return panicked values 2020-02-25 13:12:05 +01:00
Marc Vertes
27520f6dae fix: re-apply GTA until all global types/constants are defined 2020-02-20 12:44:04 +01:00
Marc Vertes
902af477b8 fix: correct behavior for rune and byte types 2020-02-09 05:18:04 +01:00
Marc Vertes
e434892b9a fix: import different source packages with same base name 2020-02-03 17:22:04 +01:00
Marc Vertes
773147ef71 fix: properly align atomic counters 2019-11-08 00:34:04 +01:00
Dan Kortschak
714253c1e6 interp: add eval cancelation by semaphore 2019-10-29 16:18:04 +01:00
Marc Vertes
de5a6e1038 feature: rename exported func Repl into REPL 2019-10-08 23:54:04 +02:00
Dan Kortschak
398b0e0255 interp: use io.Reader and io.Writer for REPL parameters 2019-10-08 17:34:05 +02:00
Marc Vertes
e03016b6d7 feature: detect import cycle 2019-09-17 01:32:03 +02:00
Marc Vertes
9e664ee8dd fix: global variable init from selector expression 2019-09-16 14:30:05 +02:00
Marc Vertes
3645904a15 fix: correct resolve of type and symbols from imported source package 2019-09-11 12:30:05 +02:00
Marc Vertes
2f0279f0f5 fix: reuse rather than re-import an already imported source package 2019-09-09 15:54:05 +02:00
Marc Vertes
869b6d2850 fix: iterate on global type analyis when necessary (#335) 2019-08-22 17:36:23 +02:00
Ludovic Fernandez
458e8e911a interp/build: support custom build constraints. 2019-07-31 09:00:05 -07:00
Ludovic Fernandez
aa98e2c2a9 feat: support yaegi in go playground 2019-07-24 17:52:03 -07:00
Ludovic Fernandez
dea1f56f38 refactor: use struct to define interpreter Options. (#236) 2019-07-03 19:46:17 +02:00
Marc Vertes
c991e09ca6 fix: correct handling of assign from multiple return func in REPL (#233) 2019-07-01 03:44:13 +02:00
Marc Vertes
274c0fc47a chore: API and code cleanup. Rename stdlib.Value into stdlib.Symbols (#231) 2019-06-27 12:40:04 +02:00
Marc Vertes
cc8e05d61b chore: cleanup API, unexport internal constants, types and variables. (#229) 2019-06-24 16:24:47 +02:00
Marc Vertes
025e4f924a fix: correct handling of equality tests (#205) 2019-06-05 09:50:44 +02:00
Marc Vertes
cc2d122cd3 fix: correct negate operator (#199) 2019-05-31 12:48:46 +02:00
Marc Vertes
557a02d616 perf: better handling of return values in func calls (#193) 2019-05-27 12:21:03 +02:00
Marc Vertes
eb705baa01 fix: implement a single interface wrapper for error type (#190) 2019-05-21 16:49:26 +02:00
Marc Vertes
16690838e3 fix: correct handling of multi-assign operations, including swap (#173) 2019-05-01 16:25:31 +02:00
Marc Vertes
37f93f0392 fix: correct embedded method handling on hybrid struct (#162) 2019-04-19 18:30:04 +02:00
Marc Vertes
8910769b77 feat: functional options to New() (#149) 2019-04-05 21:36:48 +02:00
Marc Vertes
10a8312d2c feat: check build constraints in filenames and comments (#144) 2019-04-02 15:51:44 +02:00
Marc Vertes
cac2a2c547 refactor: define fset in Interpreter rather than Node struct (#141) 2019-03-22 10:34:52 +01:00
Fernandez Ludovic
12b608b625 chore: rename to yaegi. 2019-03-20 10:15:35 +01:00
Marc Vertes
68d7890775 feat: add support for builtins complex, real and imag (#128) 2019-03-19 13:41:34 +01:00
Marc Vertes
8717f1ef4b fix: correct append with variadic parameters and spread array (#124)
* fix: correct append with variadic parameters and spread array
* feat: add print builtin
2019-03-19 12:25:04 +01:00
Marc Vertes
70fab221de feat: add support for builtin delete (#127) 2019-03-19 12:14:44 +01:00
Marc Vertes
b8927e3ca6 feat: add support for builtin copy (#126) 2019-03-19 01:19:43 +01:00
Marc Vertes
a1bfe7c989 feat: add support for builtin new (#125) 2019-03-19 01:12:25 +01:00
Marc Vertes
1ccc36a690 feat: implement support of 'for x := range channel' expression (#119) 2019-03-16 18:36:44 +01:00