Copyright © 2019 Eval-EXEC <execvy@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Package eval is the beginning of an interpreter for Go. It can run simple Go programs but does not implement interface values or packages.
Packages in the Plugin directory contain plugins for [goa v2](https://godoc.org/goa.design/goa). Plugins can extend the goa DSL, generate new artifacts and modify the output of existing generators. There are currently two plugins in the directory: The [goakit](https://godoc.org/goa.design/plugins/goakit) plugin generates code that integrates with the [go-kit](https://github.com/go-kit/kit) library. The [cors](https://godoc.org/goa.design/plugins/cors) plugin adds new DSL to define CORS policies. The plugin generates HTTP server code that respond to CORS requests in compliance with the policies defined in the design. Writing a plugin consists of two steps: 1. Writing the functions that gets called by the goa tool during code generation. 2. Registering the functions with the goa tool. A plugin may implement the "gen" goa command, the "example" goa command or both. In each case a plugin may register one or two functions: the first function called "Prepare" gets called prior to any code generation actually happening. The function can modify the design data structures before goa uses them to generate code. The second function called "Generate" does the actual code generation. The signature of the Generate function is: where: The function must return the entire set of generated files (even the files that the plugin does not modify). The functions must then be registered with the goa code generator tool using the "RegisterPlugin" function of the "codegen" package. This is typically done in a package "init" function, for example: The first argument of RegisterPlugin must be one of "gen" or "example" and specifies the "goa" command that triggers the call to the plugin functions. The second argument is the Prepare function if any, nil otherwise. The last argument is the code generator function if any, nil otherwise. A plugin may introduce new DSL "keywords" (typically Go package functions). The DSL functions initialize the content of a design root object (an object that implements the "eval.Root" interface), for example: The [eval](https://godoc.org/goa.design/goa/codegen/eval) package contains a number of functions that can be leveraged to implement the DSL such as error reporting functions. The plugin design root object is then given to the plugin Generate function (if there's one) which may take advantage of it to generate the code.
The expr package provides a simple evaluator for arithmetic integer expressions. The syntax and operations are the same as in Go. Operands are the native "int" type, except that unlike in Go, boolean values, which are created by comparisons, are integer 1 (true) and 0 (false). Create a parsed expression using Parse, and then evaluate it with Eval.
Package iolang implements a version of the Io programming language. Io is a dynamic, prototype-based language inspired by Smalltalk (everything is an object), Self (prototypes - *everything* is an object), Lisp (even the program code is made up of objects), NewtonScript (differential inheritance), Act1 (concurrency via actors and futures), and Lua (small and embeddable implementations). It was originally developed in C by Steve Dekorte. Currently, this implementation is focusing primarily on becoming a fully fledged interpreter. A read-eval-print loop exists, primarily for integration testing. There is no file interpreter, so written Io programs are not yet executable. The interpreter can easily be embedded in another program. To start, use the NewVM function to create and initialize the interpreter. The VM object has a number of fields that then can be used to make objects available to Io code, especially the Lobby and Addons objects. Use the VM's NewNumber, NewString, or any other object creation methods to create the object, then use SetSlot to set those objects' slots to them. Hello World in Io: Io code executes via message passing. For example, the above snippet compiles to two messages: Upon evaluation, the first message, being a literal, immediately becomes that string value. Then, the println message is sent to it, activating the slot on the string object named "println", which is a method that writes the object to standard output. Messages can also be provided with arguments, which are simply additional messages to provide more information with the message, in parentheses. We could add arguments to our program: But the program executes the same way, because neither string literals nor (the default) println use their arguments. When an object receives a message, it checks for a slot on the object with the same name as the message text. If the object has such a slot, then it is activated and produces a value. Slots can be added to objects using the := assignment operator; executing creates a slot on Object named x with the value 1. Certain objects have special behavior when activated. Methods are encapsulated messages that, when activated, send that message to the object which received the message that activated the method. The println method above is an example: it is defined (roughly) as In the Hello World example, this method is activated with the "Hello, world!" string as its receiver, so it executes in the context of the string, meaning that slot lookups are performed on the string, and the "self" slot within the method refers to the string. Methods have their own locals, so new slots created within them exist only inside the method body. They can also be defined to take arguments; for example, if the println method were instead defined as then we would pass the object to print as an argument instead of printing the receiver. If an object does not own a slot with the same name as a message passed to it, the object will instead check for that slot in its prototypes. Objects can have any number of protos, and the search proceeds in depth-first order without duplicates. If the slot is found in one of the protos, then it is activated, but still with the original object as the receiver. This implements an inheritance-like concept, but with "superclasses" being themselves objects. (If there isn't any proto with the slot, then the message is sent to the object's "forward" slot, and if that slot doesn't exist, either, an exception is raised.) Producing "subclasses" is done using the clone method. A clone of an object is a new object having empty slots and that object as its only prototype. If we say "y := x clone", then y will respond to the same messages as x via delegation; new slots can be created which will be activated in place of the proto's, providing polymorphism. The typical pattern to implement a new "type" is to say: do is an Object method which evaluates code in the context of its receiver. "Instances" of the new "class" can then be created by saying: Now instance is an object which responds to NewType's x, z, and someMethod slots, as well as all Object slots. Notice that clone is the method used both to create a new type and an instance of that type - this is prototype-based programming. An important aspect of Io lacking syntax beyond messages is that control flow is implemented as Object methods. "Object if" is a method taking one to three arguments: All three of these forms are essentially equivalent. if evaluates the condition, then if it is true (controlled by the result's asBoolean slot), it evaluates the second, otherwise it evaluates the third. If the branch to evaluate doesn't exist, if instead returns the boolean to enable the other forms, as well as to support the elseif method. Note that because message arguments are themselves messages, the wrong branches are never evaluated, so their side effects don't happen. There are also loops, including but not limited to: Each loop, being a method, produces a value, which is by default the last value encountered during evaluation of the loop. Object methods continue, break, and return also do what their equivalents in most other programming languages do, except that continue and break can be supplied an argument to change the loop result. For a more in-depth introduction to Io, check out the official guide and reference at http://iolanguage.org/ as well as the original implementation's GitHub repository at https://github.com/IoLanguage/io for code samples.
Package rod is a high-level driver directly based on DevTools Protocol. This example opens https://github.com/, searches for "git", and then gets the header element which gives the description for Git. Rod use https://golang.org/pkg/context to handle cancellations for IO blocking operations, most times it's timeout. Context will be recursively passed to all sub-methods. For example, methods like Page.Context(ctx) will return a clone of the page with the ctx, all the methods of the returned page will use the ctx if they have IO blocking operations. Page.Timeout or Page.WithCancel is just a shortcut for Page.Context. Of course, Browser or Element works the same way. Shows how we can further customize the browser with the launcher library. Usually you use launcher lib to set the browser's command line flags (switches). Doc for flags: https://peter.sh/experiments/chromium-command-line-switches Shows how to change the retry/polling options that is used to query elements. This is useful when you want to customize the element query retry logic. When rod doesn't have a feature that you need. You can easily call the cdp to achieve it. List of cdp API: https://github.com/go-rod/rod/tree/main/lib/proto Shows how to disable headless mode and debug. Rod provides a lot of debug options, you can set them with setter methods or use environment variables. Doc for environment variables: https://pkg.go.dev/github.com/go-rod/rod/lib/defaults We use "Must" prefixed functions to write example code. But in production you may want to use the no-prefix version of them. About why we use "Must" as the prefix, it's similar to https://golang.org/pkg/regexp/#MustCompile Shows how to share a remote object reference between two Eval. Shows how to listen for events. Shows how to intercept requests and modify both the request and the response. The entire process of hijacking one request: The --req-> and --res-> are the parts that can be modified. Show how to handle multiple results of an action. Such as when you login a page, the result can be success or wrong password. Example_search shows how to use Search to get element inside nested iframes or shadow DOMs. It works the same as https://developers.google.com/web/tools/chrome-devtools/dom#search Shows how to update the state of the current page. In this example we enable the network domain. Rod uses mouse cursor to simulate clicks, so if a button is moving because of animation, the click may not work as expected. We usually use WaitStable to make sure the target isn't changing anymore. When you want to wait for an ajax request to complete, this example will be useful.
Package rod is a high-level driver directly based on DevTools Protocol. This example opens https://github.com/, searches for "git", and then gets the header element which gives the description for Git. Rod use https://golang.org/pkg/context to handle cancellations for IO blocking operations, most times it's timeout. Context will be recursively passed to all sub-methods. For example, methods like Page.Context(ctx) will return a clone of the page with the ctx, all the methods of the returned page will use the ctx if they have IO blocking operations. Page.Timeout or Page.WithCancel is just a shortcut for Page.Context. Of course, Browser or Element works the same way. Shows how we can further customize the browser with the launcher library. Usually you use launcher lib to set the browser's command line flags (switches). Doc for flags: https://peter.sh/experiments/chromium-command-line-switches Shows how to change the retry/polling options that is used to query elements. This is useful when you want to customize the element query retry logic. When rod doesn't have a feature that you need. You can easily call the cdp to achieve it. List of cdp API: https://github.com/yeyu12/rod/tree/main/lib/proto Shows how to disable headless mode and debug. Rod provides a lot of debug options, you can set them with setter methods or use environment variables. Doc for environment variables: https://pkg.go.dev/github.com/yeyu12/rod/lib/defaults We use "Must" prefixed functions to write example code. But in production you may want to use the no-prefix version of them. About why we use "Must" as the prefix, it's similar to https://golang.org/pkg/regexp/#MustCompile Shows how to share a remote object reference between two Eval. Shows how to listen for events. Shows how to intercept requests and modify both the request and the response. The entire process of hijacking one request: The --req-> and --res-> are the parts that can be modified. Show how to handle multiple results of an action. Such as when you login a page, the result can be success or wrong password. Example_search shows how to use Search to get element inside nested iframes or shadow DOMs. It works the same as https://developers.google.com/web/tools/chrome-devtools/dom#search Shows how to update the state of the current page. In this example we enable the network domain. Rod uses mouse cursor to simulate clicks, so if a button is moving because of animation, the click may not work as expected. We usually use WaitStable to make sure the target isn't changing anymore. When you want to wait for an ajax request to complete, this example will be useful.
Package rod is a high-level driver directly based on DevTools Protocol. This example opens https://github.com/, searches for "git", and then gets the header element which gives the description for Git. Rod use https://golang.org/pkg/context to handle cancellations for IO blocking operations, most times it's timeout. Context will be recursively passed to all sub-methods. For example, methods like Page.Context(ctx) will return a clone of the page with the ctx, all the methods of the returned page will use the ctx if they have IO blocking operations. Page.Timeout or Page.WithCancel is just a shortcut for Page.Context. Of course, Browser or Element works the same way. Shows how we can further customize the browser with the launcher library. Usually you use launcher lib to set the browser's command line flags (switches). Doc for flags: https://peter.sh/experiments/chromium-command-line-switches Shows how to change the retry/polling options that is used to query elements. This is useful when you want to customize the element query retry logic. When rod doesn't have a feature that you need. You can easily call the cdp to achieve it. List of cdp API: https://github.com/go-rod/rod/tree/main/lib/proto Shows how to disable headless mode and debug. Rod provides a lot of debug options, you can set them with setter methods or use environment variables. Doc for environment variables: https://pkg.go.dev/github.com/go-rod/rod/lib/defaults We use "Must" prefixed functions to write example code. But in production you may want to use the no-prefix version of them. About why we use "Must" as the prefix, it's similar to https://golang.org/pkg/regexp/#MustCompile Shows how to share a remote object reference between two Eval. Shows how to listen for events. Shows how to intercept requests and modify both the request and the response. The entire process of hijacking one request: The --req-> and --res-> are the parts that can be modified. Show how to handle multiple results of an action. Such as when you login a page, the result can be success or wrong password. Example_search shows how to use Search to get element inside nested iframes or shadow DOMs. It works the same as https://developers.google.com/web/tools/chrome-devtools/dom#search Shows how to update the state of the current page. In this example we enable the network domain. Rod uses mouse cursor to simulate clicks, so if a button is moving because of animation, the click may not work as expected. We usually use WaitStable to make sure the target isn't changing anymore. When you want to wait for an ajax request to complete, this example will be useful.
Package eval implements evaluation of GoLang expression at runtime. Requirements for expression: What does supported: Supported expression: Predefined types (no need to pass it via args): Implemented built-in functions (no need to pass it via args): Simple example: Complicated example: Example with error in expression: Package eval built on top of reflection, go/ast, go/parser, go/token & go/constant. To create Expression it possible to use MakeExpression or some of Parse* functions. All of them use pkgPath to control access rights. pkgPath used when: 1. Accessing struct private field. If type of struct belong to pkgPath then all access to struct fields can modify its value (for example, it is possible to set such fields in composite literal). 2. Creating type in composite literal. All created in expression structures belong to pkgPath. When Expression is ready it may be evaluated multiple times. Evaluation done via Eval* methods: In most cases EvalToInterface should be enough and it is easy to use. Evaluation performance: If you found a bug (result of this package evaluation differs from evaluation by Go itself) - please report bug at github.com/apaxa-go/eval.