mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 14:18:42 +01:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99d2f0b8fc | |||
| a1112587db | |||
| e3fc56376c | |||
| 77aeb12ab8 | |||
| 415f7b24ac | |||
| 9bafddadd6 | |||
| 59a834e97c | |||
| 7c3985f8a0 | |||
| bd07122f92 | |||
| c2a75f1eaf | |||
| 5287f6cd2b | |||
| 4ffe2ed38b | |||
| 77079f2f49 | |||
| 2adb220686 | |||
| accfa598b3 | |||
| 55e8807aba | |||
| dd1e8a00db | |||
| 3c43de7485 | |||
| 59e496e26a | |||
| d78f481079 | |||
| 9903ddf76b | |||
| f09ebf6acc | |||
| 7fb7f6430d | |||
| aca7c70079 | |||
| eca90e29e9 | |||
| a346494922 | |||
| 754d5a59e9 | |||
| 8eb51d9327 | |||
| 22ff3b5549 | |||
| e4b4df2e62 | |||
| 46b06f0620 | |||
| d650b60c25 | |||
| 30c9f1ee37 |
61
.github/workflows/.githubCI.yml
vendored
Normal file
61
.github/workflows/.githubCI.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: WrenCI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: build
|
||||
run: ./.travis.sh
|
||||
shell: bash
|
||||
working-directory: ./
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wren-linux
|
||||
path: |
|
||||
bin/*
|
||||
lib/*
|
||||
mac:
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
WREN_TARGET_MAC: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: build
|
||||
run: ./.travis.sh
|
||||
shell: bash
|
||||
working-directory: ./
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wren-mac
|
||||
path: |
|
||||
bin/*
|
||||
lib/*
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- name: msbuild
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
- name: build
|
||||
working-directory: ./projects/vs2019/
|
||||
run: msbuild ./wren.sln /property:Configuration=Release /property:Platform=64bit
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wren-windows
|
||||
path: |
|
||||
bin/*
|
||||
lib/*
|
||||
1
AUTHORS
1
AUTHORS
@ -29,4 +29,5 @@ ruby0x1 <ruby0x1@pm.me>
|
||||
Kolja Kube <code@koljaku.be>
|
||||
Alexander Klingenbeck <alexander.klingenbeck@gmx.de>
|
||||
Aviv Beeri <avbeeri@gmail.com>
|
||||
Mai Lapyst <floss@lapyst.dev>
|
||||
|
||||
|
||||
183
doc/site/blog/3-0.4.0-released.markdown
Normal file
183
doc/site/blog/3-0.4.0-released.markdown
Normal file
@ -0,0 +1,183 @@
|
||||
^title 0.4.0 released!
|
||||
8 April 2021
|
||||
|
||||
---
|
||||
|
||||
This post is all about the 0.4.0 release since it's a big one!
|
||||
<small>(A separate post for 0.5.0 goals would likely come later.)</small>
|
||||
|
||||
## 0.4.0 details
|
||||
|
||||
**0.4.0 contains 145 commits from 28 contributors.**
|
||||
|
||||
The [full release notes](https://github.com/wren-lang/wren/releases/tag/0.4.0)
|
||||
link to each PR or commit, and contains a lot more details than this post.
|
||||
|
||||
**Goals**
|
||||
As usual, let's revisit the goals from the [0.3.0 post](2-0.3.0-released.html#goals-for-0.4.0).
|
||||
|
||||
Most importantly - compound operators didn't land in 0.4.0 for various reasons.
|
||||
Still working on it, it's just a fun and nuanced problem and I don't want to
|
||||
keep 0.4.0 back cos of it.
|
||||
|
||||
With that out the way, let's see what 0.4.0 contains!
|
||||
|
||||
## 0.4.0 highlights
|
||||
|
||||
Below we'll highlight some key features, fixes and improvements from the release.
|
||||
|
||||
**A lot of work came from the community, much thanks to everyone contributing!**
|
||||
|
||||
You can find all the details and the contributions in the [release notes](https://github.com/wren-lang/wren/releases/tag/0.4.0).
|
||||
|
||||
**Take note!** There are two minor breaking changes in the API on the release notes.
|
||||
|
||||
---
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Several important bugs have been fixed, sneaky stack corruptions and some user
|
||||
experience fixes that clarify confusing states.
|
||||
|
||||
### Documentation
|
||||
|
||||
A lot of work has gone into documentation this release, revising, fixing, adding
|
||||
and closing gaps that were left. For example, Wren supports multi-line strings
|
||||
but this was never mentioned anywhere!
|
||||
|
||||
### New **continue** keyword
|
||||
|
||||
Loops can now use continue, which is a welcome addition.
|
||||
|
||||
### New **as** keyword
|
||||
|
||||
You can now use `import "..." for Name as OtherName` to avoid name conflicts,
|
||||
or to use aliases/shorthand for imported variables.
|
||||
|
||||
### Raw strings
|
||||
|
||||
Wren now supports triple quotes for a string `"""`.
|
||||
|
||||
This type of string is only unique in how it's parsed, the content of the
|
||||
string is ignored (no interpolation or escapes are processed), which allows
|
||||
complex strings to be expressed without needing to escape things.
|
||||
|
||||
A common example is json or regex, where there's a lot of escaping that obscures
|
||||
the string content and makes it hard to read and maintain.
|
||||
|
||||
If they span multiple lines, the string ignores the open and closing newlines
|
||||
and whitespace and preserves anything in between.
|
||||
|
||||
<pre class="snippet">
|
||||
var json = """
|
||||
{
|
||||
"hello": "wren",
|
||||
"from" : "json"
|
||||
}
|
||||
"""
|
||||
</pre>
|
||||
|
||||
### Attributes
|
||||
|
||||
Attributes are user-defined metadata associated with a class or method that
|
||||
can be used at runtime, by external tools (and potentially by Wren itself).
|
||||
|
||||
<pre class="snippet">
|
||||
#hidden = true
|
||||
#doc = "A simple example class"
|
||||
class Example {}
|
||||
</pre>
|
||||
|
||||
They can be:
|
||||
|
||||
- a `#key` on it's own
|
||||
- a `#key = value`
|
||||
- a `#group(with, multiple = true, keys = "value")`
|
||||
|
||||
**Example**
|
||||
|
||||
Below you can one obvious use case, a wip version where attributes for docs were
|
||||
parsed and sent over to [vscode](https://code.visualstudio.com/) to display.
|
||||
|
||||
<video preload="auto" controls="" loop="loop" style="max-width:100%; width:auto; margin:auto; display:block;">
|
||||
<source src="https://i.imgur.com/W9DWysP.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
**Runtime access**
|
||||
By default, attributes are compiled out and ignored.
|
||||
For an attribute to be visible at runtime, mark it for runtime access using an
|
||||
exclamation:
|
||||
|
||||
<pre class="snippet">
|
||||
#doc = "not runtime data"
|
||||
#!runtimeAccess = true
|
||||
#!maxIterations = 16
|
||||
</pre>
|
||||
|
||||
Attributes at runtime are stored on the class itself. You can access them via
|
||||
`YourClass.attributes`. If any attributes are made available, they'll be found here:
|
||||
|
||||
- `YourClass.attributes.self` for the class attributes
|
||||
- `YourClass.attributes.methods` for the method attributes
|
||||
|
||||
All the details for [Attributes can be found here](https://wren.io/classes.html#attributes).
|
||||
|
||||
### Chained methods fixes ('fluent interfaces')
|
||||
|
||||
Mentioned in the last post, you can now use this pattern in code as intended,
|
||||
the same-line requirement for the `.` has been removed.
|
||||
|
||||
<pre class="snippet">
|
||||
example
|
||||
.some()
|
||||
.functions()
|
||||
.here()
|
||||
</pre>
|
||||
|
||||
### List additions
|
||||
|
||||
Lists are now sortable via `list.sort()` and `list.sort {|a, b| ... }`.
|
||||
You can find an index of something via `list.indexOf(value)`, and remove a value
|
||||
via `list.remove(value)`. There's also `list.swap(index0, index1)` for moving
|
||||
items around within a list.
|
||||
|
||||
For the API, `wrenSetListElement` now exists, and both set and
|
||||
`wrenGetListElement` now accept negative indices same as the language side.
|
||||
|
||||
### Num additions
|
||||
|
||||
A few new constants:
|
||||
|
||||
- `Num.tau`
|
||||
- `Num.nan`
|
||||
- `Num.infinity`
|
||||
- `Num.minSafeInteger`/`Num.maxSafeInteger`
|
||||
|
||||
And some new methods on a number:
|
||||
|
||||
- `num.min(other)`
|
||||
- `num.max(other)`
|
||||
- `num.clamp(min, max)`
|
||||
- `num.cbrt`
|
||||
- `num.exp`
|
||||
- `num.log2`
|
||||
|
||||
### Map access from the API
|
||||
|
||||
You can now create and access maps from the API:
|
||||
|
||||
- `wrenSetSlotNewMap`
|
||||
- `wrenGetMapCount`
|
||||
- `wrenGetMapContainsKey`
|
||||
- `wrenGetMapValue`
|
||||
- `wrenSetMapValue`
|
||||
- `wrenRemoveMapValue`
|
||||
|
||||
## Till next time
|
||||
|
||||
---
|
||||
|
||||
- [The Wren Blog RSS](http://wren.io/blog/rss.xml)
|
||||
- Join the [discord community](https://discord.gg/Kx6PxSX)
|
||||
- Visit the [wren-lang organization](https://github.com/wren-lang) on GitHub to get involved.
|
||||
- Follow the developers [@munificentbob](https://twitter.com/munificentbob) or [@ruby0x1](https://twitter.com/ruby0x1) on twitter
|
||||
@ -1,5 +1,8 @@
|
||||
^title Development blogs
|
||||
|
||||
[<h3>0.4.0 released!</h3>](3-0.4.0-released.html)
|
||||
> <date>8 April 2021</date> • 0.4.0 is a big release, here's all the info!
|
||||
|
||||
[<h3>0.3.0 released!</h3>](2-0.3.0-released.html)
|
||||
> <date>5 June 2020</date> • 0.3.0 release info! Plus some notes and goals for the next release, 0.4.0.
|
||||
|
||||
|
||||
@ -3,12 +3,19 @@
|
||||
<link>https://wren.io/</link>
|
||||
<description>The development blog of the Wren programming language.</description>
|
||||
<language>en-us</language>
|
||||
<item>
|
||||
<title>0.4.0 released</title>
|
||||
<link>https://wren.io/blog/3-0.4.0-released.html</link>
|
||||
<description>0.4.0 is a big release, here's all the info!</description>
|
||||
<guid>https://wren.io/blog/3-0.4.0-released.html</guid>
|
||||
<pubDate>Thu, 08 Apr 2021 00:00:00 GMT</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>0.3.0 released</title>
|
||||
<link>https://wren.io/blog/2-0.3.0-released.html</link>
|
||||
<description>0.3.0 release info! Plus some notes and goals for the next release, 0.4.0.</description>
|
||||
<guid>https://wren.io/blog/2-0.3.0-released.html</guid>
|
||||
<pubDate>Mon, 30 Sep 2019 00:00:00 GMT</pubDate>
|
||||
<pubDate>Mon, 05 Jun 2020 00:00:00 GMT</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>0.2.0 and beyond</title>
|
||||
|
||||
@ -746,15 +746,15 @@ class Example {
|
||||
#!getter
|
||||
getter {}
|
||||
|
||||
// { regular(_,_): { regular:[null] } }
|
||||
// { regular(_,_): { null: { regular:[null] } } }
|
||||
#!regular
|
||||
regular(arg0, arg1) {}
|
||||
|
||||
// { static other(): { isStatic:[true] } }
|
||||
// { static other(): { null: { isStatic:[true] } } }
|
||||
#!isStatic = true
|
||||
static other()
|
||||
static other() {}
|
||||
|
||||
// { foreign static example(): { isForeignStatic:[32] } }
|
||||
// { foreign static example(): { null: { isForeignStatic:[32] } } }
|
||||
#!isForeignStatic=32
|
||||
foreign static example()
|
||||
}
|
||||
|
||||
@ -61,6 +61,17 @@ if (ready) {
|
||||
}
|
||||
</pre>
|
||||
|
||||
You can also use `else if` branches to handle multiple possibilities. For example, what if `ready` was not a boolean value?
|
||||
<pre class="snippet">
|
||||
if (ready == true) {
|
||||
System.print("go!")
|
||||
} else if (ready == false) {
|
||||
System.print("not ready!")
|
||||
} else { // If ready isn't a boolean
|
||||
System.print("not sure if I'm ready or not!")
|
||||
}
|
||||
</pre>
|
||||
|
||||
## Logical operators
|
||||
|
||||
Unlike most other [operators][] in Wren which are just a special syntax for
|
||||
@ -187,8 +198,8 @@ loop conditions).
|
||||
|
||||
<pre class="snippet">
|
||||
for (i in [1, 2, 3, 4]) {
|
||||
System.print(i) //> 1
|
||||
if (i == 2) continue //> 3
|
||||
if (i == 2) continue //> 1
|
||||
System.print(i) //> 3
|
||||
} //> 4
|
||||
</pre>
|
||||
|
||||
|
||||
@ -48,9 +48,9 @@ method is called. That's how many dynamic languages work.
|
||||
|
||||
But, as you can imagine, that's pretty slow. So, instead, Wren does as much of
|
||||
that work at compile time as it can. When it's compiling the above code to
|
||||
bytecode, it takes that method signature a converts it to a *method symbol*, a
|
||||
number that uniquely identifes that method. That's the only part of the process
|
||||
that requires treating a signature as a string.
|
||||
bytecode, it takes that method signature and converts it to a *method symbol*,
|
||||
a number that uniquely identifes that method. That's the only part of the
|
||||
process that requires treating a signature as a string.
|
||||
|
||||
At runtime, the VM just looks for the method *symbol* in the receiver's class's
|
||||
method table. In fact, the way it's implemented today, the symbol is simply the
|
||||
|
||||
@ -208,7 +208,7 @@ You can find this file in the [example](https://github.com/wren-lang/wren/blob/m
|
||||
<pre class="snippet" data-lang="c">
|
||||
//For more details, visit https://wren.io/embedding/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
#include "wren.h"
|
||||
|
||||
static void writeFn(WrenVM* vm, const char* text)
|
||||
|
||||
@ -306,5 +306,19 @@ This sounds super hairy, but that's because cyclic dependencies are hairy in
|
||||
general. The key point here is that Wren *can* handle them in the rare cases
|
||||
where you need them.
|
||||
|
||||
## Exiting a module early
|
||||
|
||||
Although the `return` statement is normally used to exit from a [method](classes.html#methods) or a [function](functions.html), it can also be used from a module's top-level code to exit the module. For example, if the script consists of a single module, this code would exit the module (and therefore the script) early:
|
||||
|
||||
<pre class="snippet">
|
||||
for (i in 1..2) {
|
||||
if (i == 2) return
|
||||
System.print(i) //> prints 1 but not 2
|
||||
}
|
||||
System.print(3) //> not reached
|
||||
</pre>
|
||||
|
||||
Although it is not invalid to return a value, there is no way to access that value and it is therefore simply discarded.
|
||||
|
||||
<br><hr>
|
||||
<a href="error-handling.html">← Error Handling</a>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
### **same**(obj1, obj2)
|
||||
|
||||
Returns `true` if *obj1* and *obj2* are the same. For [value
|
||||
types](../values.html), this returns `true` if the objects have equivalent
|
||||
types](../../values.html), this returns `true` if the objects have equivalent
|
||||
state. In other words, numbers, strings, booleans, and ranges compare by value.
|
||||
|
||||
For all other objects, this returns `true` only if *obj1* and *obj2* refer to
|
||||
@ -26,7 +26,7 @@ Returns `false`, since most objects are considered [true][].
|
||||
### **==**(other) and **!=**(other) operators
|
||||
|
||||
Compares two objects using built-in equality. This compares [value
|
||||
types](../values.html) by value, and all other objects are compared by
|
||||
types](../../values.html) by value, and all other objects are compared by
|
||||
identity—two objects are equal only if they are the exact same object.
|
||||
|
||||
### **is**(class) operator
|
||||
|
||||
@ -148,8 +148,9 @@ It is a runtime error if `search` is not a string.
|
||||
### **indexOf**(search, start)
|
||||
|
||||
Returns the index of the first byte matching `search` in the string or `-1` if
|
||||
`search` was not found, starting a byte offset `start`. The start can be
|
||||
negative to count backwards from the end of the string.
|
||||
`search` was not found, starting at byte offset `start`. The `start` offset can
|
||||
also be negative, which will be offset relative to end of the string instead.
|
||||
Searches forward, from the offset to the end of the string.
|
||||
|
||||
It is a runtime error if `search` is not a string or `start` is not an integer
|
||||
index within the string's byte length.
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
^title Module "meta"
|
||||
|
||||
**TODO**
|
||||
This module enables Wren to do certain kinds of meta-programming.
|
||||
|
||||
It is an optional module. You can omit it from your application by setting the preprocessor constant `WREN_OPT_META` to `0`.
|
||||
|
||||
It contains a single class:
|
||||
|
||||
* [Meta](meta.html)
|
||||
|
||||
@ -1,7 +1,145 @@
|
||||
^title Meta Class
|
||||
|
||||
**TODO**
|
||||
This class contains static methods to list a module's top-level variables and to compile Wren expressions and source code into closures (i.e. [functions](functions.html)) at runtime.
|
||||
|
||||
## Methods
|
||||
It must be imported from the [meta](meta.html) module:
|
||||
|
||||
**TODO**
|
||||
<pre class="snippet">
|
||||
import "meta" for Meta
|
||||
</pre>
|
||||
|
||||
## Static Methods
|
||||
|
||||
### **getModuleVariables**(module)
|
||||
|
||||
Returns a list of all module level variables defined or visible in `module`.
|
||||
|
||||
This includes any variables explicitly imported from other modules or implicitly imported from the built-in modules. For example if we create this module:
|
||||
|
||||
<pre class="snippet">
|
||||
/* module.wren */
|
||||
var M = 1
|
||||
</pre>
|
||||
|
||||
and then import it into this module:
|
||||
|
||||
<pre class="snippet">
|
||||
/* get_mod_vars.wren */
|
||||
import "meta" for Meta
|
||||
import "./module" for M
|
||||
|
||||
var v = 42
|
||||
|
||||
var f = Fn.new {
|
||||
var g = 2
|
||||
}
|
||||
|
||||
class C {}
|
||||
|
||||
System.print(Meta.getModuleVariables("./get_mod_vars"))
|
||||
|
||||
var w = 43 // still returned even though defined later
|
||||
</pre>
|
||||
|
||||
the output when the latter module is run is:
|
||||
|
||||
<pre class="snippet">
|
||||
[Object, Class, Object metaclass, Bool, Fiber, Fn, Null, Num, Sequence, MapSequence, SkipSequence, TakeSequence, WhereSequence, List, String, StringByteSequence, StringCodePointSequence, Map, MapKeySequence, MapValueSequence, MapEntry, Range, System, Meta, M, v, f, C, w]
|
||||
</pre>
|
||||
|
||||
Notice that `g` is not included in this list as it is a local variable rather than a module variable.
|
||||
|
||||
It is a runtime error if `module` is not a string or cannot be found.
|
||||
|
||||
### **eval**(source)
|
||||
|
||||
Compiles Wren source code into a closure and then executes the closure automatically.
|
||||
|
||||
It is a runtime error if `source` is not a string.
|
||||
|
||||
It is also an error if the source code cannot be compiled though the compilation errors themselves are not printed.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="snippet">
|
||||
import "meta" for Meta
|
||||
|
||||
var a = 2
|
||||
var b = 3
|
||||
var source = """
|
||||
var c = a * b
|
||||
System.print(c)
|
||||
"""
|
||||
Meta.eval(source) //> 6
|
||||
</pre>
|
||||
|
||||
### **compileExpression**(expression)
|
||||
|
||||
Compiles a Wren expression into a closure and then returns the closure. It does not execute it.
|
||||
|
||||
The closure returns the value of the expression.
|
||||
|
||||
It is a runtime error if `expression` is not a string.
|
||||
|
||||
Prints any compilation errors - in which event the closure will be null - but does not throw an error.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="snippet">
|
||||
import "meta" for Meta
|
||||
|
||||
var d = 4
|
||||
var e = 5
|
||||
var expression = "d * e"
|
||||
var closure = Meta.compileExpression(expression)
|
||||
System.print(closure.call()) //> 20
|
||||
</pre>
|
||||
|
||||
### **compile**(source)
|
||||
|
||||
Compiles Wren source code into a closure and then returns the closure. It does not execute it.
|
||||
|
||||
It is a runtime error if `source` is not a string.
|
||||
|
||||
Prints any compilation errors - in which event the closure will be null - but does not throw an error.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="snippet">
|
||||
import "meta" for Meta
|
||||
|
||||
/* Enum creates an enum with any number of read-only static members.
|
||||
Members are assigned in order an initial integer value (often 0), incremented by 1 each time.
|
||||
The enum has:
|
||||
1. static property getters for each member,
|
||||
2. a static 'startsFrom' property, and
|
||||
3. a static 'members' property which returns a list of its members as strings.
|
||||
*/
|
||||
class Enum {
|
||||
// Creates a class for the Enum (with an underscore after the name to avoid duplicate definition)
|
||||
// and returns a reference to it.
|
||||
static create(name, members, startsFrom) {
|
||||
if (name.type != String || name == "") Fiber.abort("Name must be a non-empty string.")
|
||||
if (members.isEmpty) Fiber.abort("An enum must have at least one member.")
|
||||
if (startsFrom.type != Num || !startsFrom.isInteger) {
|
||||
Fiber.abort("Must start from an integer.")
|
||||
}
|
||||
name = name + "_"
|
||||
var s = "class %(name) {\n"
|
||||
for (i in 0...members.count) {
|
||||
var m = members[i]
|
||||
s = s + " static %(m) { %(i + startsFrom) }\n"
|
||||
}
|
||||
var mems = members.map { |m| "\"%(m)\"" }.join(", ")
|
||||
s = s + " static startsFrom { %(startsFrom) }\n"
|
||||
s = s + " static members { [%(mems)] }\n}\n"
|
||||
s = s + "return %(name)"
|
||||
return Meta.compile(s).call()
|
||||
}
|
||||
}
|
||||
|
||||
var Fruits = Enum.create("Fruits", ["orange", "apple", "banana", "lemon"], 0)
|
||||
System.print(Fruits.banana) //> 2
|
||||
System.print(Fruits.startsFrom) //> 0
|
||||
System.print(Fruits.members) //> [orange, apple, banana, lemon]
|
||||
</pre>
|
||||
|
||||
89
doc/site/static/lzstring.min.js
vendored
Normal file
89
doc/site/static/lzstring.min.js
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
// Minified from https://github.com/microsoft/TypeScript-Website/blob/e9d8f66f6b8be2dda06737d3686dcb795749dff2/packages/sandbox/src/vendor/lzstring.min.js
|
||||
|
||||
// Original license reproduced below:
|
||||
|
||||
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
// Version 2, December 2004
|
||||
//
|
||||
// Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
//
|
||||
// Everyone is permitted to copy and distribute verbatim or modified
|
||||
// copies of this license document, and changing it is allowed as long
|
||||
// as the name is changed.
|
||||
//
|
||||
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
//
|
||||
// 0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
//
|
||||
|
||||
var LZString=(function(){function o(o,r){if(!t[o]){t[o]={}
|
||||
for(var n=0;n<o.length;n++)t[o][o.charAt(n)]=n}
|
||||
return t[o][r]}
|
||||
var r=String.fromCharCode,n='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',e='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$',t={},i={compressToBase64:function(o){if(null==o)return''
|
||||
var r=i._compress(o,6,function(o){return n.charAt(o)})
|
||||
switch(r.length%4){default:case 0:return r
|
||||
case 1:return r+'==='
|
||||
case 2:return r+'=='
|
||||
case 3:return r+'='}},decompressFromBase64:function(r){return null==r?'':''==r?null:i._decompress(r.length,32,function(e){return o(n,r.charAt(e))})},compressToUTF16:function(o){return null==o?'':i._compress(o,15,function(o){return r(o+32)})+' '},decompressFromUTF16:function(o){return null==o?'':''==o?null:i._decompress(o.length,16384,function(r){return o.charCodeAt(r)-32})},compressToUint8Array:function(o){for(var r=i.compress(o),n=new Uint8Array(2*r.length),e=0,t=r.length;t>e;e++){var s=r.charCodeAt(e);(n[2*e]=s>>>8),(n[2*e+1]=s%256)}
|
||||
return n},decompressFromUint8Array:function(o){if(null===o||void 0===o)return i.decompress(o)
|
||||
for(var n=new Array(o.length / 2),e=0,t=n.length;t>e;e++)n[e]=256*o[2*e]+o[2*e+1]
|
||||
var s=[]
|
||||
return(n.forEach(function(o){s.push(r(o))}),i.decompress(s.join('')))},compressToEncodedURIComponent:function(o){return null==o?'':i._compress(o,6,function(o){return e.charAt(o)})},decompressFromEncodedURIComponent:function(r){return null==r?'':''==r?null:((r=r.replace(/ /g,'+')),i._decompress(r.length,32,function(n){return o(e,r.charAt(n))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(o,r,n){if(null==o)return''
|
||||
var e,t,i,s={},p={},u='',c='',a='',l=2,f=3,h=2,d=[],m=0,v=0
|
||||
for(i=0;i<o.length;i+=1)
|
||||
if(((u=o.charAt(i)),Object.prototype.hasOwnProperty.call(s,u)||((s[u]=f++),(p[u]=!0)),(c=a+u),Object.prototype.hasOwnProperty.call(s,c)))
|
||||
a=c
|
||||
else{if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)(m<<=1),v==r-1?((v=0),d.push(n(m)),(m=0)):v++
|
||||
for(t=a.charCodeAt(0),e=0;8>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)}else{for(t=1,e=0;h>e;e++)
|
||||
(m=(m<<1)|t),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t=0)
|
||||
for(t=a.charCodeAt(0),e=0;16>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)}
|
||||
l--,0==l&&((l=Math.pow(2,h)),h++),delete p[a]}else
|
||||
for(t=s[a],e=0;h>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)
|
||||
l--,0==l&&((l=Math.pow(2,h)),h++),(s[c]=f++),(a=String(u))}
|
||||
if(''!==a){if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)(m<<=1),v==r-1?((v=0),d.push(n(m)),(m=0)):v++
|
||||
for(t=a.charCodeAt(0),e=0;8>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)}else{for(t=1,e=0;h>e;e++)
|
||||
(m=(m<<1)|t),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t=0)
|
||||
for(t=a.charCodeAt(0),e=0;16>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)}
|
||||
l--,0==l&&((l=Math.pow(2,h)),h++),delete p[a]}else
|
||||
for(t=s[a],e=0;h>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)
|
||||
l--,0==l&&((l=Math.pow(2,h)),h++)}
|
||||
for(t=2,e=0;h>e;e++)
|
||||
(m=(m<<1)|(1&t)),v==r-1?((v=0),d.push(n(m)),(m=0)):v++,(t>>=1)
|
||||
for(;;){if(((m<<=1),v==r-1)){d.push(n(m))
|
||||
break}
|
||||
v++}
|
||||
return d.join('')},decompress:function(o){return null==o?'':''==o?null:i._decompress(o.length,32768,function(r){return o.charCodeAt(r)})},_decompress:function(o,n,e){var t,i,s,p,u,c,a,l,f=[],h=4,d=4,m=3,v='',w=[],A={val:e(0),position:n,index:1}
|
||||
for(i=0;3>i;i+=1)f[i]=i
|
||||
for(p=0,c=Math.pow(2,2),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1)
|
||||
switch((t=p)){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1)
|
||||
l=r(p)
|
||||
break
|
||||
case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1)
|
||||
l=r(p)
|
||||
break
|
||||
case 2:return''}
|
||||
for(f[3]=l,s=l,w.push(l);;){if(A.index>o)return''
|
||||
for(p=0,c=Math.pow(2,m),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1)
|
||||
switch((l=p)){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1);(f[d++]=r(p)),(l=d-1),h--
|
||||
break
|
||||
case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)
|
||||
(u=A.val&A.position),(A.position>>=1),0==A.position&&((A.position=n),(A.val=e(A.index++))),(p|=(u>0?1:0)*a),(a<<=1);(f[d++]=r(p)),(l=d-1),h--
|
||||
break
|
||||
case 2:return w.join('')}
|
||||
if((0==h&&((h=Math.pow(2,m)),m++),f[l]))v=f[l]
|
||||
else{if(l!==d)return null
|
||||
v=s+s.charAt(0)}
|
||||
w.push(v),(f[d++]=s+v.charAt(0)),h--,(s=v),0==h&&((h=Math.pow(2,m)),m++)}},}
|
||||
return i})();'function'==typeof define&&define.amd?define(function(){return LZString}):'undefined'!=typeof module&&null!=module&&(module.exports=LZString)
|
||||
@ -502,6 +502,39 @@ table.precedence td {
|
||||
border-bottom: solid 1px var(--gray-10);
|
||||
}
|
||||
|
||||
/*
|
||||
Sourced from https://github.com/microsoft/TypeScript-Website/blob/e9d8f66f6b8be2dda06737d3686dcb795749dff2/packages/typescriptlang-org/src/templates/play.scss#L916-L943.
|
||||
Licensed under the MIT license https://github.com/microsoft/TypeScript-Website/blob/e9d8f66f6b8be2dda06737d3686dcb795749dff2/LICENSE-CODE.
|
||||
*/
|
||||
#copied-popup {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#copied-popup p {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
font-size: 1.5rem;
|
||||
|
||||
border-radius: 1em;
|
||||
padding: 0.5em 1.5em;
|
||||
opacity: 0;
|
||||
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
|
||||
/* Help Safari with blurred text */
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 839px) {
|
||||
/* 36 pixel columns.*/
|
||||
.page { width: 720px; }
|
||||
|
||||
@ -22,9 +22,11 @@ window.onload = function() {
|
||||
Module.printErr = function(text) { output.innerText += text + "\n"; }
|
||||
|
||||
var run = document.querySelector("#try-run")
|
||||
var share = document.querySelector("#share")
|
||||
var hello = document.querySelector("#try-hello")
|
||||
var fractal = document.querySelector("#try-fractal")
|
||||
var loop = document.querySelector("#try-loop")
|
||||
var copiedPopup = document.querySelector("#copied-popup p")
|
||||
var compile = Module.cwrap('wren_compile', 'number', ['string'])
|
||||
|
||||
var set_input = (content) => {
|
||||
@ -34,6 +36,21 @@ window.onload = function() {
|
||||
jar.updateCode(content);
|
||||
}
|
||||
|
||||
share.onclick = (e) => {
|
||||
var code = jar.toString()
|
||||
var compressed = LZString.compressToEncodedURIComponent(code)
|
||||
var url = location.protocol + "//" + location.host + location.pathname + "?code=" + compressed
|
||||
navigator.clipboard.writeText(url).then(
|
||||
() => {
|
||||
copiedPopup.style.opacity = "1"
|
||||
setTimeout(() => {
|
||||
copiedPopup.style.opacity = ""
|
||||
}, 1000)
|
||||
},
|
||||
(e) => console.error(e)
|
||||
)
|
||||
}
|
||||
|
||||
run.onclick = (e) => {
|
||||
console.log("run")
|
||||
output.setAttribute('ready', '');
|
||||
@ -75,5 +92,11 @@ window.onload = function() {
|
||||
}`);
|
||||
} //fractal
|
||||
|
||||
var initial_code = new URLSearchParams(location.search).get("code")
|
||||
if (initial_code !== null) {
|
||||
initial_code = LZString.decompressFromEncodedURIComponent(initial_code)
|
||||
set_input(initial_code)
|
||||
}
|
||||
|
||||
} //if try_code
|
||||
}
|
||||
|
||||
@ -607,8 +607,8 @@ var wasmMemory;
|
||||
// In the wasm backend, we polyfill the WebAssembly object,
|
||||
// so this creates a (non-native-wasm) table for us.
|
||||
var wasmTable = new WebAssembly.Table({
|
||||
'initial': 203,
|
||||
'maximum': 203 + 0,
|
||||
'initial': 206,
|
||||
'maximum': 206 + 0,
|
||||
'element': 'anyfunc'
|
||||
});
|
||||
|
||||
@ -1229,11 +1229,11 @@ function updateGlobalBufferAndViews(buf) {
|
||||
}
|
||||
|
||||
var STATIC_BASE = 1024,
|
||||
STACK_BASE = 5271568,
|
||||
STACK_BASE = 5272384,
|
||||
STACKTOP = STACK_BASE,
|
||||
STACK_MAX = 28688,
|
||||
DYNAMIC_BASE = 5271568,
|
||||
DYNAMICTOP_PTR = 28528;
|
||||
STACK_MAX = 29504,
|
||||
DYNAMIC_BASE = 5272384,
|
||||
DYNAMICTOP_PTR = 29344;
|
||||
|
||||
assert(STACK_BASE % 16 === 0, 'stack must start aligned');
|
||||
assert(DYNAMIC_BASE % 16 === 0, 'heap must start aligned');
|
||||
@ -1817,7 +1817,7 @@ var ASM_CONSTS = {
|
||||
|
||||
|
||||
|
||||
// STATICTOP = STATIC_BASE + 27664;
|
||||
// STATICTOP = STATIC_BASE + 28480;
|
||||
/* global initializers */ __ATINIT__.push({ func: function() { ___wasm_call_ctors() } });
|
||||
|
||||
|
||||
@ -1875,7 +1875,7 @@ var ASM_CONSTS = {
|
||||
}
|
||||
|
||||
function _emscripten_get_sbrk_ptr() {
|
||||
return 28528;
|
||||
return 29344;
|
||||
}
|
||||
|
||||
function _emscripten_memcpy_big(dest, src, num) {
|
||||
|
||||
Binary file not shown.
@ -100,6 +100,7 @@
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="modules">API/Modules</a></li>
|
||||
<li><a href="cli">Wren CLI</a></li>
|
||||
<li><a href="embedding">Embedding</a></li>
|
||||
<li><a href="performance.html">Performance</a></li>
|
||||
<li><a href="qa.html">Q & A</a></li>
|
||||
|
||||
@ -14,6 +14,7 @@ examples:
|
||||
<p>enter code below</p>
|
||||
|
||||
<div class="buttons">
|
||||
<a class="button" id="share">share</a>•
|
||||
<a class="button" id="try-run">run</a>
|
||||
</div>
|
||||
|
||||
@ -25,3 +26,5 @@ examples:
|
||||
<pre><div id="try-output">...</div></pre>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="copied-popup"><p>URL copied to clipboard</p></div>
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="../prism.js" data-manual></script>
|
||||
<script type="application/javascript" src="../codejar.js"></script>
|
||||
<script type="application/javascript" src="../codejar-linenumbers.js"></script>
|
||||
<script type="application/javascript" src="../lzstring.min.js"></script>
|
||||
<script type="application/javascript" src="../wren.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../prism.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../style.css" />
|
||||
|
||||
@ -50,7 +50,8 @@ String literals are surrounded in double quotes:
|
||||
"hi there"
|
||||
</pre>
|
||||
|
||||
They can also span multiple lines:
|
||||
They can also span multiple lines. When they do, the newline character within
|
||||
the string will always be `\n` (`\r\n` is normalized to `\n`).
|
||||
|
||||
<pre class="snippet">
|
||||
"hi
|
||||
|
||||
@ -113,6 +113,9 @@
|
||||
// field index*.
|
||||
#define MAX_FIELDS 255
|
||||
|
||||
// The maximum number of methods the vm can handle.
|
||||
#define MAX_METHODS 65535
|
||||
|
||||
// Use the VM's allocator to allocate an object of [type].
|
||||
#define ALLOCATE(vm, type) \
|
||||
((type*)wrenReallocate(vm, NULL, 0, sizeof(type)))
|
||||
|
||||
@ -542,6 +542,7 @@ static void initCompiler(Compiler* compiler, Parser* parser, Compiler* parent,
|
||||
// the middle of initializing the compiler.
|
||||
compiler->fn = NULL;
|
||||
compiler->constants = NULL;
|
||||
compiler->attributes = NULL;
|
||||
|
||||
parser->vm->compiler = compiler;
|
||||
|
||||
@ -910,13 +911,15 @@ static void readRawString(Parser* parser)
|
||||
char c1 = peekChar(parser);
|
||||
char c2 = peekNextChar(parser);
|
||||
|
||||
if(c == '\n') {
|
||||
if (c == '\r') continue;
|
||||
|
||||
if (c == '\n') {
|
||||
lastNewline = string.count;
|
||||
skipEnd = lastNewline;
|
||||
firstNewline = firstNewline == -1 ? string.count : firstNewline;
|
||||
}
|
||||
|
||||
if(c == '"' && c1 == '"' && c2 == '"') break;
|
||||
if (c == '"' && c1 == '"' && c2 == '"') break;
|
||||
|
||||
bool isWhitespace = c == ' ' || c == '\t';
|
||||
skipEnd = c == '\n' || isWhitespace ? skipEnd : -1;
|
||||
@ -974,6 +977,7 @@ static void readString(Parser* parser)
|
||||
{
|
||||
char c = nextChar(parser);
|
||||
if (c == '"') break;
|
||||
if (c == '\r') continue;
|
||||
|
||||
if (c == '\0')
|
||||
{
|
||||
@ -1098,7 +1102,7 @@ static void nextToken(Parser* parser)
|
||||
skipLineComment(parser);
|
||||
break;
|
||||
}
|
||||
// Otherwise we treat it as a token a token
|
||||
// Otherwise we treat it as a token
|
||||
makeToken(parser, TOKEN_HASH);
|
||||
return;
|
||||
}
|
||||
@ -1848,8 +1852,14 @@ static void finishParameterList(Compiler* compiler, Signature* signature)
|
||||
// Gets the symbol for a method [name] with [length].
|
||||
static int methodSymbol(Compiler* compiler, const char* name, int length)
|
||||
{
|
||||
return wrenSymbolTableEnsure(compiler->parser->vm,
|
||||
int symbol = wrenSymbolTableEnsure(compiler->parser->vm,
|
||||
&compiler->parser->vm->methodNames, name, length);
|
||||
|
||||
if (symbol > MAX_METHODS) {
|
||||
error(compiler, "Method limit of %d reached.", MAX_METHODS);
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// Appends characters to [name] (and updates [length]) for [numParams] "_"
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
// There is one limitation, though. Methods written in C cannot call Wren ones.
|
||||
// They can only be the top of the callstack, and immediately return. This
|
||||
// makes it difficult to have primitive methods that rely on polymorphic
|
||||
// behavior. For example, `IO.write` should call `toString` on its argument,
|
||||
// behavior. For example, `System.print` should call `toString` on its argument,
|
||||
// including user-defined `toString` methods on user-defined classes.
|
||||
|
||||
void wrenInitializeCore(WrenVM* vm);
|
||||
|
||||
@ -480,4 +480,4 @@ class ClassAttributes {
|
||||
_methods = methods
|
||||
}
|
||||
toString { "attributes:%(_attributes) methods:%(_methods)" }
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,11 +238,11 @@ static const char* coreModuleSource =
|
||||
" return result\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" trim() { trim_(\"\t\r\n \", true, true) }\n"
|
||||
" trim() { trim_(\"\\t\\r\\n \", true, true) }\n"
|
||||
" trim(chars) { trim_(chars, true, true) }\n"
|
||||
" trimEnd() { trim_(\"\t\r\n \", false, true) }\n"
|
||||
" trimEnd() { trim_(\"\\t\\r\\n \", false, true) }\n"
|
||||
" trimEnd(chars) { trim_(chars, false, true) }\n"
|
||||
" trimStart() { trim_(\"\t\r\n \", true, false) }\n"
|
||||
" trimStart() { trim_(\"\\t\\r\\n \", true, false) }\n"
|
||||
" trimStart(chars) { trim_(chars, true, false) }\n"
|
||||
"\n"
|
||||
" trim_(chars, trimStart, trimEnd) {\n"
|
||||
@ -441,18 +441,18 @@ static const char* coreModuleSource =
|
||||
"\n"
|
||||
"class System {\n"
|
||||
" static print() {\n"
|
||||
" writeString_(\"\n\")\n"
|
||||
" writeString_(\"\\n\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static print(obj) {\n"
|
||||
" writeObject_(obj)\n"
|
||||
" writeString_(\"\n\")\n"
|
||||
" writeString_(\"\\n\")\n"
|
||||
" return obj\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static printAll(sequence) {\n"
|
||||
" for (object in sequence) writeObject_(object)\n"
|
||||
" writeString_(\"\n\")\n"
|
||||
" writeString_(\"\\n\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static write(obj) {\n"
|
||||
@ -483,4 +483,3 @@ static const char* coreModuleSource =
|
||||
" }\n"
|
||||
" toString { \"attributes:%(_attributes) methods:%(_methods)\" }\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ bool validateInt(WrenVM* vm, Value arg, const char* argName);
|
||||
|
||||
// Validates that [arg] is a valid object for use as a map key. Returns true if
|
||||
// it is. If not, reports an error and returns false.
|
||||
bool validateKey(WrenVM * vm, Value arg);
|
||||
bool validateKey(WrenVM* vm, Value arg);
|
||||
|
||||
// Validates that the argument at [argIndex] is an integer within `[0, count)`.
|
||||
// Also allows negative indices which map backwards from the end. Returns the
|
||||
|
||||
@ -1089,6 +1089,9 @@ static void blackenFn(WrenVM* vm, ObjFn* fn)
|
||||
// Mark the constants.
|
||||
wrenGrayBuffer(vm, &fn->constants);
|
||||
|
||||
// Mark the module it belongs to, in case it's been unloaded.
|
||||
wrenGrayObj(vm, (Obj*)fn->module);
|
||||
|
||||
// Keep track of how much memory is still in use.
|
||||
vm->bytesAllocated += sizeof(ObjFn);
|
||||
vm->bytesAllocated += sizeof(uint8_t) * fn->code.capacity;
|
||||
|
||||
@ -1418,6 +1418,7 @@ WrenHandle* wrenMakeCallHandle(WrenVM* vm, const char* signature)
|
||||
// Add the signatue to the method table.
|
||||
int method = wrenSymbolTableEnsure(vm, &vm->methodNames,
|
||||
signature, signatureLength);
|
||||
ASSERT(method <= MAX_METHODS, "Method limit reached.");
|
||||
|
||||
// Create a little stub function that assumes the arguments are on the stack
|
||||
// and calls the method.
|
||||
|
||||
4
test/language/module/returns/module_return.wren
Normal file
4
test/language/module/returns/module_return.wren
Normal file
@ -0,0 +1,4 @@
|
||||
// nontest
|
||||
System.print("foo")
|
||||
return
|
||||
System.print("bar")
|
||||
4
test/language/module/returns/module_return_value.wren
Normal file
4
test/language/module/returns/module_return_value.wren
Normal file
@ -0,0 +1,4 @@
|
||||
// nontest
|
||||
System.print("foo")
|
||||
return 42
|
||||
System.print("bar")
|
||||
3
test/language/module/returns/return.wren
Normal file
3
test/language/module/returns/return.wren
Normal file
@ -0,0 +1,3 @@
|
||||
System.print("foo") // expect: foo
|
||||
return
|
||||
System.print("bar")
|
||||
5
test/language/module/returns/return_from_import.wren
Normal file
5
test/language/module/returns/return_from_import.wren
Normal file
@ -0,0 +1,5 @@
|
||||
import "./module_return"
|
||||
|
||||
System.print("baz")
|
||||
// expect: foo
|
||||
// expect: baz
|
||||
3
test/language/module/returns/return_value.wren
Normal file
3
test/language/module/returns/return_value.wren
Normal file
@ -0,0 +1,3 @@
|
||||
System.print("foo") // expect: foo
|
||||
return 42
|
||||
System.print("bar")
|
||||
@ -0,0 +1,5 @@
|
||||
import "./module_return_value"
|
||||
|
||||
System.print("baz")
|
||||
// expect: foo
|
||||
// expect: baz
|
||||
@ -22,6 +22,7 @@ static const char* {1}ModuleSource =
|
||||
def wren_to_c_string(input_path, wren_source_lines, module):
|
||||
wren_source = ""
|
||||
for line in wren_source_lines:
|
||||
line = line.replace("\\", "\\\\")
|
||||
line = line.replace('"', "\\\"")
|
||||
line = line.replace("\n", "\\n\"")
|
||||
if wren_source: wren_source += "\n"
|
||||
|
||||
Reference in New Issue
Block a user