Commit Graph

424 Commits

Author SHA1 Message Date
Marc Vertes
61f4704925 interp: fix CFG in case of for loop with empty init and cond
Refactor `for` variants for clarity. Ensure all possible 8 combinations
are covered.

Fixes #942.
2020-11-05 11:00:04 +01:00
Marc Vertes
98807387a4 interp: resolve type for untyped shift expressions
A non-constant shift expression can be untyped, requiring to apply a
type from inherited context. This change insures that such context is
propagated during CFG pre-order walk, to be used if necessary.
    
Fixes #927.
2020-11-02 18:08:04 +01:00
Marc Vertes
c817823ba1 interp: fix incorrect infinite loop on for statement
Add a for statement variant for the case of a "for" with an init, no
condition and no post-increment.

Fixes #933.
2020-11-02 17:52:03 +01:00
Marc Vertes
9520a92241 interp: fix type in assign of shift operations
Type checking on shift operands was failing for untyped variable values.

Fix propagation of type in assignment. Optimize assignment of arithmetic
operations on variables by skipping the assign and writing directly to
destination frame value in the operator function.

Skip some slow tests when given -short test option.

Fixes #917.
2020-10-23 10:32:03 +02:00
mpl
c0eaab0891 interp: fix assignable check
The assignable check used to be too strict as it lacked the property that
if an untyped const can be represented as a T, then it is assignable to T.

And we can now use that fixed check to add a missing check: in a return
statement, we now make sure that any of the returned elements are
assignable to what the signature tells us they should be.
2020-10-21 10:06:03 +02:00
Marc Vertes
190dade469 fix: detect a wrong number of arguments at return
Also fix error ouptut in the run command to avoid displaying twice
the same error.

Fixes #819.
2020-10-14 17:30:04 +02:00
Marc Vertes
473bc63588 fix: behavior of select and time ticker
There was several issues:
- access to field on pointer to struct from runtime: fix in
  lookupBinField
- assign operation was skipped when performed in a comm clause
- the direction of comm clause was wrong if a channel send operation was
  performed in a body of a receive comm clause

Fixes #884.
2020-10-14 15:50:04 +02:00
Marc Vertes
f362237ac5 fix: perform constant type conversion when required
Fixes #893.
2020-10-12 19:06:03 +02:00
mpl
155ca4e6ad interp: support implicit-type slice of pointers of struct composite literal
Also fix same case for implicit-type maps of etc.

Fixes #883
2020-10-09 10:32:03 +02:00
mpl
ca196a5768 interp: fix implicit type for bin composite lit case
When the type is implicit, the first element in the list of children is
not the type of the composite literal, but it is one of the actual
children, so it should not be discarded.

Fixes #862
2020-10-05 16:42:03 +02:00
mpl
3ae01a2af3 interp: refactor doComposite cases 2020-09-22 17:26:03 +02:00
mpl
535e7e1c42 interp: enable declaration errors detection at parsing time
The Go parser is able to detect some (but not all) (re-)decleration errors,
if the DeclarationErrors flag is enabled, which was not done so far.

This PR therefore enables that flag, which allows the removal of some of
the now unneeded code that was recently added to support redeclarations.

Fixes #811
2020-08-28 14:36:00 +02:00
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
Nicholas Wiersma
358a57b4b9 feat: add star expression type checking
This adds type checking to StarExpr. This also fixes a bug in assignment where the symbol type was updated but not the scope type associated with it.
2020-08-21 10:56:03 +02:00
Nicholas Wiersma
3640f2f820 feat: add type assertion expression type checking
This adds type checking to TypeAssertExpr. In order to allow for this, method types now have a receiver type in both reflect and native cases.
2020-08-20 17:06:05 +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
Nicholas Wiersma
1029d102e5 feat: add slice expression type checking
This adds type checking to SliceExpr as well as handling any required constant type conversion.

It should be noted that the check that `high` and `max` are not nil in a 3-index slice has been left out as this check is handled before type checking. Tests have been included for these cases.
2020-08-19 16:04:05 +02:00
Nicholas Wiersma
da9e6a0d6c fix: composite literal type check
In the case of a pointer or alias composite literal expression, `compositeGenerator` changes the type to remove the pointer or alias. This causes a nested composite literal to have the wrong type.

Instead of changing the node type, the removal of the pointer or alias is moved to the runtime, allowing the node type to remain unchanged. This fixes potential issues in the type checking.
2020-08-14 12:14:03 +02:00
Nicholas Wiersma
913680d1ed feat: add call expression (not builtin) type checking
This adds type checking to CallExpr (excluding builtin type checking, as that is a PR in its own right) as well as handling any required constant type conversion.

This also changes constant strings and runes to be represented as `constant.Value`. Runes change `rval` type at CFG typing time to avoid having to type at AST time. There are also changes to importSpecs and `stdlib` to account for the string change. With this all `untyped` types should now be `constant.Value`s, although errors are still not returned if this is not the case to be sure we do not break things.

This also fixed a bug in `itype.methods` that would panic if the type was recursive.
2020-08-14 12:02:04 +02:00
Nicholas Wiersma
cdc352cee2 feat: add index and composite literal type checking
This adds type checking to both `IndexExpr` and `CompositeLitExpr` as well as handling any required constant type conversion.

This includes a change to the type propagation to the children of a composite literal. Previously in most cases the composite literal type was propagated to its children. This does not work with type checking as the actual child type is needed.
2020-08-11 15:58:04 +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
Marc Vertes
25c681c1e6 fix: regression on range following #787 2020-07-30 10:52:05 +02:00
Marc Vertes
68911f8b4e fix: type assertion expression was not forwarding type
The detection of special cases of interpreter functions and interfaces
is more precise. It allows at least to complete parsing of
code where type is derived from a type assertion expression.

Fixes #770.
2020-07-23 11:51:53 +02:00
Marc Vertes
0a79069dfc fix: correct control flow graph for range init expression
The range init AST execution was skipped, and range could work
only over variables or direct function calls. By setting the
start node to the start of init and not init itself, we ensure
that the init AST is always taken into account.

Fixes #775.
2020-07-13 15:35:04 +02:00
Nicholas Wiersma
ca80ada849 fix: deal with untyped in type check 2020-07-10 11:55:04 +02:00
Nicholas Wiersma
3c6df504df fix: dont allow calling init 2020-07-09 14:35:04 +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
16ff52a949 fix: avoid a panic in CFG in case of incomplete type
By returning early in case of incomplete type in CFG, we avoid
a panic, and let a chance to a new attempt after the missing
type has been parsed.

Fixes 763.
2020-07-09 13:05:04 +02:00
Nicholas Wiersma
851444453c fix: assert switch type from valueT in struct case (#747)
* fix: switch type from valueT in struct case

In a struct case in type assertion, if the source is a valueT, we still need to take the struct type to allow method and field resolution.

* fix: handle all ptr structs as well
2020-07-06 15:09:48 +02:00
Nicholas Wiersma
a8b1c2a017 fix: a const, non-const equality check must convert 2020-07-06 11:25:03 +02:00
Nicholas Wiersma
4058fd8c44 fix: do type check on assignment (#738)
* fix: do type check on assignment

* fix: check for recursive type rather than field
2020-07-03 10:28:51 +02:00
Nicholas Wiersma
a15ecb7176 feature: handle nested recursion
* fix: copy the type in recursion

In more advanced recursive cases, setting the rtype to interface may interfear with typeing. To stop this from happening, instead of setting t.val.rtype to interface in the hope it will be set correctly later, a copy if the type is made, and the rtype of the copy is set to interface{}.

* fix: detect intermediate recursive structs

In the case of a nested recussion, each symbol can have
a different perspective on the recursion. In this case,
it is impossible to move from one struct to the next.
To keep the perspectives the same, any intermediate struct
that contains a recursion should also be set to interface{}.
so that all perspectives are the same.

* fix: handle arb recursion

* chore: refactor dref to be consistent

* fix: invalid recursive struct issue

* fix: handle checkptr issue

* fix: move unsafe into function to stop ptr check

* fix: handle deref in assign
2020-07-02 23:20:03 +02:00
Marc Vertes
d4aa84f729 fix: set frame level in destination nodes to avoid memory corruption (#733)
When operations write their result to a non-local frame, the node
level field must be set accordingly, otherwise they attempt to write
in the wrong frame.

Fixes #730.
2020-07-02 10:03:32 +02:00
Marc Vertes
39430c34bb fix: untyped constant converson to default type (#729)
* fix: untyped constant cconverson to default type

In definition assign expression, the source type is propagated to
the assigned value. If the source is an untyped constant, the
destination type must be set to the default type of the constant
definition. A fixType function is provided to perform this.

In addition, the type conversion and check of constants is
refactored for simplifications.

Fixes #727.

* test: fix _test/const14.go
2020-07-01 14:39:47 +02:00
Nicholas Wiersma
d2c4a36c25 fix: dont optimize map index assigns 2020-06-29 09:40:03 +02:00
Nicholas Wiersma
f5f44f7ddd fix: rework compatibility and ordering checks 2020-06-25 09:44:04 +02:00
Julien Levesy
c11d361953 Handle Receive and Send channels 2020-06-23 09:04: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
mpl
7323d97023 interp: global scope redeclaration detection 2020-06-18 15:08:04 +02:00
Nicholas Wiersma
d252821df3 feature: constant values in bin packages 2020-06-18 13:54:04 +02:00
Nicholas Wiersma
1fe91be882 feature: refactor numeric constants and detect overflow 2020-06-18 09:20:04 +02:00
Nicholas Wiersma
8365f687e7 fix: composite map assign (#683)
* fix: composite map assign

* reword comment

Co-authored-by: Marc Vertes <mvertes@free.fr>
2020-06-10 12:29:09 +02:00
Marc Vertes
82b499a1c8 fix: detect default comm clause in select from AST (#678)
* fix: detect default comm clause in select from AST

The heuristic to distinguish a default comm clause was too weak.
Make it robust by using AST.

Fixes #646.

* rename test to avoid conflict
2020-06-10 12:06:59 +02:00
Marc Vertes
0ef7f8fb80 fix: perform send channel action for select (#665)
* fix: perform send channel action for select

The CFG was wrong for select send comm clauses. If an init operation
on channel was required (like a derefence, index operation, ...) it
was skipped. The bug was invisible in case of a local var channel.

A send channel init operation consist to prepare both the data to
send (right subtree of send AST) and the channel itself (left
subtree of send AST). All channel init operation must be performed
prior to call select.

Fixes #647.

* doc: fix comment

* invert test to continue early

please note that this also changes the logic a little bit, since the
line that was:

if pn != nil {

now implictly becomes:

if an != nil && pn != nil {

(which I think is actually more correct).

* explicit chaining of init actions in select

* explicit chaining of init actions in select

Co-authored-by: mpl <mathieu.lonjaret@gmail.com>
2020-06-10 11:37:06 +02:00
Nicholas Wiersma
def57d57c2 fix: dont assign receiver on indexExpr 2020-06-03 19:10:04 +02:00
mpl
6f878052f8 interp: detect local redeclaration (#673)
* interp: detect local redecleration

Fixes #666

* make make check happy

* fix typo in filenames, add them to the exclusion list

Co-authored-by: Marc Vertes <mvertes@free.fr>
2020-06-03 17:21:00 +02:00
Nicholas Wiersma
eb25c84797 fix: handle call ellipsis 2020-06-03 16:42:04 +02:00
Nicholas Wiersma
151a856bf2 fix: composite literal child types for call expressions 2020-06-03 09:44:03 +02:00
Nicholas Wiersma
01e4cdea70 fix: recursive struct function call 2020-06-03 00:18:04 +02:00
Nicholas Wiersma
3c88542180 fix: handle empty interface conversion 2020-05-29 13:58:04 +02:00