Merge branch 'master' into constructor-methods

This commit is contained in:
Bob Nystrom
2015-07-19 12:49:23 -07:00
18 changed files with 254 additions and 191 deletions

View File

@ -2,10 +2,11 @@ language: c
compiler:
- gcc
- clang
before_install:
# Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the
# 32-bit builds to work, we need gcc-multilib.
- sudo apt-get update -qq
- sudo apt-get install -qq gcc-multilib
script: make all && make test
# Travis VMs are 64-bit but we compile both for 32 and 64 bit. To enable the
# 32-bit builds to work, we need gcc-multilib.
addons:
apt:
packages:
- gcc-multilib
sudo: false # Enable container-based builds.
script: make all && make test

View File

@ -40,8 +40,9 @@ while (!adjectives.isDone) IO.print(adjectives.call())
and [an easy-to-use C API][embedding]. It compiles cleanly as C99, C++98
or anything later.
If you like the sound of this, [give it a try][try]! Even better, you can
[contribute to Wren itself][contribute].
If you like the sound of this, [let's get started][started]. You can even try
it [in your browser][browser]! Excited? Well, come on and [get
involved][contribute]!
[![Build Status](https://travis-ci.org/munificent/wren.svg)](https://travis-ci.org/munificent/wren)
@ -52,5 +53,6 @@ If you like the sound of this, [give it a try][try]! Even better, you can
[classes]: http://munificent.github.io/wren/classes.html
[fibers]: http://munificent.github.io/wren/fibers.html
[embedding]: http://munificent.github.io/wren/embedding-api.html
[try]: http://munificent.github.io/wren/getting-started.html
[contribute]: http://munificent.github.io/wren/contributing.html
[started]: getting-started.html
[browser]: http://ppvk.github.io/wren-nest/
[contribute]: contributing.html

View File

@ -1,101 +1,101 @@
class IO {
static print {
IO.writeString_("\n")
writeString_("\n")
}
static print(obj) {
IO.writeObject_(obj)
IO.writeString_("\n")
writeObject_(obj)
writeString_("\n")
return obj
}
static print(a1, a2) {
printList_([a1, a2])
printAll([a1, a2])
}
static print(a1, a2, a3) {
printList_([a1, a2, a3])
printAll([a1, a2, a3])
}
static print(a1, a2, a3, a4) {
printList_([a1, a2, a3, a4])
printAll([a1, a2, a3, a4])
}
static print(a1, a2, a3, a4, a5) {
printList_([a1, a2, a3, a4, a5])
printAll([a1, a2, a3, a4, a5])
}
static print(a1, a2, a3, a4, a5, a6) {
printList_([a1, a2, a3, a4, a5, a6])
printAll([a1, a2, a3, a4, a5, a6])
}
static print(a1, a2, a3, a4, a5, a6, a7) {
printList_([a1, a2, a3, a4, a5, a6, a7])
printAll([a1, a2, a3, a4, a5, a6, a7])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8])
printAll([a1, a2, a3, a4, a5, a6, a7, a8])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15])
}
static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) {
printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16])
printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16])
}
static printList_(objects) {
for (object in objects) IO.writeObject_(object)
IO.writeString_("\n")
static printAll(sequence) {
for (object in sequence) writeObject_(object)
writeString_("\n")
}
static write(obj) {
IO.writeObject_(obj)
writeObject_(obj)
return obj
}
static read(prompt) {
if (!(prompt is String)) Fiber.abort("Prompt must be a string.")
IO.write(prompt)
return IO.read
write(prompt)
return read()
}
static writeObject_(obj) {
var string = obj.toString
if (string is String) {
IO.writeString_(string)
writeString_(string)
} else {
IO.writeString_("[invalid toString]")
writeString_("[invalid toString]")
}
}
foreign static writeString_(string)
foreign static clock
foreign static time
foreign static read
foreign static read()
}

View File

@ -10,18 +10,21 @@ There's one Wren user group, and it's the [official Wren mailing
list](https://groups.google.com/forum/#!forum/wren-lang). Please join it and
say hello! There are no strangers to Wren, just friends we haven't met yet.
## Third-party libraries
## Libraries
There are some third-party libraries that are written in Wren. Here's the list:
- [wren-test](https://github.com/gsmaverick/wren-test), a testing framework
- [Please](https://github.com/EvanHahn/wren-please), an assertion library
- [wren-colors](https://github.com/gsmaverick/wren-colors) for printing colored
messages to the terminal
- [3D vectors for Wren](https://github.com/EvanHahn/wren-vector3d)
- [Please](https://github.com/EvanHahn/wren-please): An assertion library.
- [wren-colors](https://github.com/gsmaverick/wren-colors): Print colored
messages to the terminal.
- [wren-test](https://github.com/gsmaverick/wren-test): A testing framework.
- [wren-vector3d](https://github.com/EvanHahn/wren-vector3d): 3D vectors.
A few people have also added Wren bindings for other languages:
## Language bindings
Want to host a Wren VM within another language. Try these:
- [JavaScript: ppvk/wrenjs](https://github.com/ppvk/wrenjs)
- [Rust: tilpner/wren-sys](https://github.com/tilpner/wren-sys)
- [Rust: pwoolcoc/wren-sys](https://github.com/pwoolcoc/wren-sys)
- [Rust: pwoolcoc/wren-rs](https://github.com/pwoolcoc/wren-rs)
@ -30,8 +33,16 @@ A few people have also added Wren bindings for other languages:
If you want Wren syntax highlighting in your editor, look no further:
- [Vim](https://github.com/lluchs/vim-wren)
- [Emacs](https://github.com/v2e4lisp/wren-mode.el)
- [Sublime Text](https://github.com/munificent/wren-sublime)
- [Vim](https://github.com/lluchs/vim-wren)
## Tools and Utilities
Things that make life easier:
- [The Wren Nest](http://ppvk.github.io/wren-nest/): Run and share Wren in your
browser.
Do you have anything to add here? Send a [pull request][]!

View File

@ -7,38 +7,54 @@ The IO class can be used to read and write to and from the console.
### IO.**print**(objects...)
Prints any number of things to the console and then prints a newline
character. If you don't pass it a string, it will be converted to a string for
you. When passed multiple things, Wren outputs one after another.
Prints a series of objects to the console followed by a newline. Each object is
converted to a string by calling `toString` on it. This is overloaded to
support up to 16 objects. To pass more, use `printAll()`.
> IO.print("I like bananas")
I like bananas
> IO.print("Oranges", 10)
Oranges10
> IO.print("I like bananas")
I like bananas
> IO.print("Oranges", 10)
Oranges10
>
### IO.**printAll**(sequence)
Iterates over [sequence] and prints each element, then prints a single newline
at the end. Each element is converted to a string by calling `toString` on it.
> IO.printAll([1, [2, 3], 4])
1[2, 3]4
### IO.**write**(object)
Prints a single thing to the console, but does not print a newline character
afterwards. If you pass it something that isn't a string, it will convert it to
a string.
Prints a single value to the console, but does not print a newline character
afterwards. Converts the value to a string by calling `toString` on it.
> IO.write(4 + 5)
9>
> IO.write(4 + 5)
9>
In the above example, the result of `4 + 5` is printed, and then the prompt is
printed on the same line because no newline character was printed afterwards.
### IO.**read**()
Reads in a line of text from stdin. Note that the returned text includes the
trailing newline.
> var name = IO.read()
John
> IO.print("Hello " + name + "!")
Hello John
!
>
### IO.**read**(prompt)
Reads in and returns a line of text from the console. Takes a single string to
be used as a prompt. Pass an empty string for no prompt. Note that the returned
line of text includes the newline character at the end.
Displays `prompt` then reads in a line of text from stdin. Note that the
returned text includes the trailing newline.
> var name = IO.read("Enter your name: ")
Enter your name: John
> IO.print("Hello " + name + "!")
Hello John
!
>
> var name = IO.read("Enter your name: ")
Enter your name: John
> IO.print("Hello " + name + "!")
Hello John
!
>

View File

@ -113,7 +113,7 @@ of the `yield()` call:
This prints "sent". Note that the first value sent to the fiber through call is
ignored. That's because the fiber isn't waiting on a `yield()` call, so there's
no where for the sent value to go.
nowhere for the sent value to go.
Fibers can also pass values *back* when they yield. If you pass an argument to
`yield()`, that will become the return value of the `call` that was used to

View File

@ -41,8 +41,9 @@ a familiar, modern [syntax][].
and [an easy-to-use C API][embedding]. It compiles cleanly as C99, C++98
or anything later.
If you like the sound of this, [give it a try][try]! Even better, you can
[contribute to Wren itself][contribute].
If you like the sound of this, [let's get started][started]. You can even try
it [in your browser][browser]! Excited? Well, come on and [get
involved][contribute]!
[syntax]: syntax.html
[src]: https://github.com/munificent/wren/tree/master/src
@ -51,5 +52,6 @@ If you like the sound of this, [give it a try][try]! Even better, you can
[classes]: classes.html
[fibers]: fibers.html
[embedding]: embedding-api.html
[try]: getting-started.html
[started]: getting-started.html
[browser]: http://ppvk.github.io/wren-nest/
[contribute]: contributing.html

View File

@ -234,7 +234,7 @@ def color_text(text, color):
# No ANSI escapes on Windows.
if sys.platform == 'win32':
return text
return str(text)
return color + str(text) + '\033[0m'

View File

@ -26,7 +26,7 @@
//
// Defaults to on.
#ifndef WREN_NAN_TAGGING
#define WREN_NAN_TAGGING 1
#define WREN_NAN_TAGGING 1
#endif
// If true, the VM's interpreter loop uses computed gotos. See this for more:
@ -48,14 +48,14 @@
//
// Defaults to on.
#ifndef WREN_USE_LIB_IO
#define WREN_USE_LIB_IO 1
#define WREN_USE_LIB_IO 1
#endif
// If true, loads the "Meta" class in the standard library.
//
// Defaults to on.
#ifndef WREN_USE_LIB_META
#define WREN_USE_LIB_META 1
#define WREN_USE_LIB_META 1
#endif
// These flags are useful for debugging and hacking on Wren itself. They are not
@ -136,18 +136,18 @@
// The Microsoft compiler does not support the "inline" modifier when compiling
// as plain C.
#if defined( _MSC_VER ) && !defined(__cplusplus)
#define inline _inline
#define inline _inline
#endif
// This is used to clearly mark flexible-sized arrays that appear at the end of
// some dynamically-allocated structs, known as the "struct hack".
#if __STDC_VERSION__ >= 199901L
// In C99, a flexible array member is just "[]".
#define FLEXIBLE_ARRAY
// In C99, a flexible array member is just "[]".
#define FLEXIBLE_ARRAY
#else
// Elsewhere, use a zero-sized array. It's technically undefined behavior, but
// works reliably in most known compilers.
#define FLEXIBLE_ARRAY 0
// Elsewhere, use a zero-sized array. It's technically undefined behavior,
// but works reliably in most known compilers.
#define FLEXIBLE_ARRAY 0
#endif
// Assertions are used to validate program invariants. They indicate things the
@ -157,34 +157,46 @@
// Assertions add significant overhead, so are only enabled in debug builds.
#ifdef DEBUG
#include <stdio.h>
#include <stdio.h>
#define ASSERT(condition, message) \
do \
{ \
if (!(condition)) \
#define ASSERT(condition, message) \
do \
{ \
fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \
__FILE__, __LINE__, __func__, message); \
if (!(condition)) \
{ \
fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \
__FILE__, __LINE__, __func__, message); \
abort(); \
} \
} \
while(0)
// Indicates that we know execution should never reach this point in the
// program. In debug mode, we assert this fact because it's a bug to get here.
//
// In release mode, we use compiler-specific built in functions to tell the
// compiler the code can't be reached. This avoids "missing return" warnings
// in some cases and also lets it perform some optimizations by assuming the
// code is never reached.
#define UNREACHABLE() \
do \
{ \
fprintf(stderr, "[%s:%d] This code should not be reached in %s()\n", \
__FILE__, __LINE__, __func__); \
abort(); \
} \
} \
while(0)
// Assertion to indicate that the given point in the code should never be
// reached.
#define UNREACHABLE() \
do \
{ \
fprintf(stderr, "This line should not be reached.\n"); \
abort(); \
} \
while (0)
while (0)
#else
#define ASSERT(condition, message) do { } while (0)
#define UNREACHABLE() do { } while (0)
#define ASSERT(condition, message) do {} while (0)
// Tell the compiler that this part of the code will never be reached.
#if defined( _MSC_VER )
#define UNREACHABLE() __assume(0)
#else
#define UNREACHABLE() __builtin_unreachable()
#endif
#endif

View File

@ -2673,7 +2673,6 @@ static int getNumArguments(const uint8_t* bytecode, const Value* constants,
default:
UNREACHABLE();
return 0;
}
}

View File

@ -9,15 +9,7 @@ void wrenDebugPrintStackTrace(ObjFiber* fiber)
for (int i = fiber->numFrames - 1; i >= 0; i--)
{
CallFrame* frame = &fiber->frames[i];
ObjFn* fn;
if (frame->fn->type == OBJ_FN)
{
fn = (ObjFn*)frame->fn;
}
else
{
fn = ((ObjClosure*)frame->fn)->fn;
}
ObjFn* fn = wrenGetFrameFunction(frame);
// Built-in libraries and method call stubs have no source path and are
// explicitly omitted from stack traces since we don't want to highlight to
@ -70,21 +62,21 @@ void wrenDumpValue(Value value)
{
switch (GET_TAG(value))
{
case TAG_FALSE: printf("false"); break;
case TAG_NAN: printf("NaN"); break;
case TAG_NULL: printf("null"); break;
case TAG_TRUE: printf("true"); break;
case TAG_FALSE: printf("false"); break;
case TAG_NAN: printf("NaN"); break;
case TAG_NULL: printf("null"); break;
case TAG_TRUE: printf("true"); break;
case TAG_UNDEFINED: UNREACHABLE();
}
}
#else
switch (value.type)
{
case VAL_FALSE: printf("false"); break;
case VAL_NULL: printf("null"); break;
case VAL_NUM: printf("%.14g", AS_NUM(value)); break;
case VAL_TRUE: printf("true"); break;
case VAL_OBJ: printObject(AS_OBJ(value)); break;
case VAL_FALSE: printf("false"); break;
case VAL_NULL: printf("null"); break;
case VAL_NUM: printf("%.14g", AS_NUM(value)); break;
case VAL_TRUE: printf("true"); break;
case VAL_OBJ: dumpObject(AS_OBJ(value)); break;
case VAL_UNDEFINED: UNREACHABLE();
}
#endif

View File

@ -6,111 +6,111 @@
#include <string.h>
#include <time.h>
// TODO: This is an arbitrary limit Do something smarter.
// TODO: This is an arbitrary limit. Do something smarter.
#define MAX_READ_LEN 1024
// This string literal is generated automatically from io.wren. Do not edit.
static const char* ioLibSource =
"class IO {\n"
" static print {\n"
" IO.writeString_(\"\n\")\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static print(obj) {\n"
" IO.writeObject_(obj)\n"
" IO.writeString_(\"\n\")\n"
" writeObject_(obj)\n"
" writeString_(\"\n\")\n"
" return obj\n"
" }\n"
"\n"
" static print(a1, a2) {\n"
" printList_([a1, a2])\n"
" printAll([a1, a2])\n"
" }\n"
"\n"
" static print(a1, a2, a3) {\n"
" printList_([a1, a2, a3])\n"
" printAll([a1, a2, a3])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4) {\n"
" printList_([a1, a2, a3, a4])\n"
" printAll([a1, a2, a3, a4])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5) {\n"
" printList_([a1, a2, a3, a4, a5])\n"
" printAll([a1, a2, a3, a4, a5])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6) {\n"
" printList_([a1, a2, a3, a4, a5, a6])\n"
" printAll([a1, a2, a3, a4, a5, a6])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15])\n"
" }\n"
"\n"
" static print(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16) {\n"
" printList_([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16])\n"
" printAll([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16])\n"
" }\n"
"\n"
" static printList_(objects) {\n"
" for (object in objects) IO.writeObject_(object)\n"
" IO.writeString_(\"\n\")\n"
" static printAll(sequence) {\n"
" for (object in sequence) writeObject_(object)\n"
" writeString_(\"\n\")\n"
" }\n"
"\n"
" static write(obj) {\n"
" IO.writeObject_(obj)\n"
" writeObject_(obj)\n"
" return obj\n"
" }\n"
"\n"
" static read(prompt) {\n"
" if (!(prompt is String)) Fiber.abort(\"Prompt must be a string.\")\n"
" IO.write(prompt)\n"
" return IO.read\n"
" write(prompt)\n"
" return read()\n"
" }\n"
"\n"
" static writeObject_(obj) {\n"
" var string = obj.toString\n"
" if (string is String) {\n"
" IO.writeString_(string)\n"
" writeString_(string)\n"
" } else {\n"
" IO.writeString_(\"[invalid toString]\")\n"
" writeString_(\"[invalid toString]\")\n"
" }\n"
" }\n"
"\n"
" foreign static writeString_(string)\n"
" foreign static clock\n"
" foreign static time\n"
" foreign static read\n"
" foreign static read()\n"
"}\n";
static void ioWriteString(WrenVM* vm)
@ -125,7 +125,8 @@ static void ioRead(WrenVM* vm)
char buffer[MAX_READ_LEN];
char* result = fgets(buffer, MAX_READ_LEN, stdin);
if (result != NULL) {
if (result != NULL)
{
wrenReturnString(vm, buffer, (int)strlen(buffer));
}
}
@ -153,7 +154,7 @@ WrenForeignMethodFn wrenBindIOForeignMethod(WrenVM* vm, const char* className,
if (strcmp(signature, "writeString_(_)") == 0) return ioWriteString;
if (strcmp(signature, "clock") == 0) return ioClock;
if (strcmp(signature, "time") == 0) return ioTime;
if (strcmp(signature, "read") == 0) return ioRead;
if (strcmp(signature, "read()") == 0) return ioRead;
return NULL;
}

View File

@ -359,13 +359,11 @@ static uint32_t hashValue(Value value)
switch (value.type)
{
case VAL_FALSE: return 0;
case VAL_NULL: return 1;
case VAL_NUM: return hashNumber(AS_NUM(value));
case VAL_TRUE: return 2;
case VAL_OBJ: return hashObject(AS_OBJ(value));
default:
UNREACHABLE();
return 0;
case VAL_NULL: return 1;
case VAL_NUM: return hashNumber(AS_NUM(value));
case VAL_TRUE: return 2;
case VAL_OBJ: return hashObject(AS_OBJ(value));
default: UNREACHABLE();
}
#endif
}

View File

@ -586,10 +586,10 @@ typedef struct
#define IS_UNDEFINED(value) ((value).type == VAL_UNDEFINED)
// Singleton values.
#define FALSE_VAL ((Value){ VAL_FALSE })
#define NULL_VAL ((Value){ VAL_NULL })
#define TRUE_VAL ((Value){ VAL_TRUE })
#define UNDEFINED_VAL ((Value){ VAL_UNDEFINED })
#define FALSE_VAL ((Value){ VAL_FALSE, { 0 } })
#define NULL_VAL ((Value){ VAL_NULL, { 0 } })
#define TRUE_VAL ((Value){ VAL_TRUE, { 0 } })
#define UNDEFINED_VAL ((Value){ VAL_UNDEFINED, { 0 } })
#endif
@ -628,6 +628,16 @@ ObjFiber* wrenNewFiber(WrenVM* vm, Obj* fn);
// Resets [fiber] back to an initial state where it is ready to invoke [fn].
void wrenResetFiber(WrenVM* vm, ObjFiber* fiber, Obj* fn);
static inline ObjFn* wrenGetFrameFunction(CallFrame* frame)
{
switch (frame->fn->type)
{
case OBJ_FN: return (ObjFn*)frame->fn;
case OBJ_CLOSURE: return ((ObjClosure*)frame->fn)->fn;
default: UNREACHABLE();
}
}
// Adds a new [CallFrame] to [fiber] invoking [function] whose stack starts at
// [stackStart].
static inline void wrenAppendCallFrame(WrenVM* vm, ObjFiber* fiber,
@ -639,14 +649,7 @@ static inline void wrenAppendCallFrame(WrenVM* vm, ObjFiber* fiber,
CallFrame* frame = &fiber->frames[fiber->numFrames++];
frame->stackStart = stackStart;
frame->fn = function;
if (function->type == OBJ_FN)
{
frame->ip = ((ObjFn*)function)->bytecode;
}
else
{
frame->ip = ((ObjClosure*)function)->fn->bytecode;
}
frame->ip = wrenGetFrameFunction(frame)->bytecode;
}
// TODO: The argument list here is getting a bit gratuitous.

View File

@ -613,14 +613,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
frame = &fiber->frames[fiber->numFrames - 1]; \
stackStart = frame->stackStart; \
ip = frame->ip; \
if (frame->fn->type == OBJ_FN) \
{ \
fn = (ObjFn*)frame->fn; \
} \
else \
{ \
fn = ((ObjClosure*)frame->fn)->fn; \
}
fn = wrenGetFrameFunction(frame);
// Terminates the current fiber with error string [error]. If another calling
// fiber is willing to catch the error, transfers control to it, otherwise
@ -1164,7 +1157,6 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber)
// We should only exit this function from an explicit return from CODE_RETURN
// or a runtime error.
UNREACHABLE();
return WREN_RESULT_RUNTIME_ERROR;
#undef READ_BYTE
#undef READ_SHORT

View File

@ -195,26 +195,25 @@ static inline ObjClass* wrenGetClassInline(WrenVM* vm, Value value)
#if WREN_NAN_TAGGING
switch (GET_TAG(value))
{
case TAG_FALSE: return vm->boolClass; break;
case TAG_NAN: return vm->numClass; break;
case TAG_NULL: return vm->nullClass; break;
case TAG_TRUE: return vm->boolClass; break;
case TAG_FALSE: return vm->boolClass; break;
case TAG_NAN: return vm->numClass; break;
case TAG_NULL: return vm->nullClass; break;
case TAG_TRUE: return vm->boolClass; break;
case TAG_UNDEFINED: UNREACHABLE();
}
#else
switch (value.type)
{
case VAL_FALSE: return vm->boolClass;
case VAL_NULL: return vm->nullClass;
case VAL_NUM: return vm->numClass;
case VAL_TRUE: return vm->boolClass;
case VAL_OBJ: return AS_OBJ(value)->classObj;
case VAL_FALSE: return vm->boolClass;
case VAL_NULL: return vm->nullClass;
case VAL_NUM: return vm->numClass;
case VAL_TRUE: return vm->boolClass;
case VAL_OBJ: return AS_OBJ(value)->classObj;
case VAL_UNDEFINED: UNREACHABLE();
}
#endif
UNREACHABLE();
return NULL;
}
#endif

View File

@ -0,0 +1,35 @@
from __future__ import print_function
import time
start = time.clock()
count = 0
for i in range(0, 1000000):
if "abc" == "abc":
count = count + 1
if "a slightly longer string" == \
"a slightly longer string":
count = count + 1
if "a significantly longer string but still not overwhelmingly long string" == \
"a significantly longer string but still not overwhelmingly long string":
count = count + 1
if "" == "abc":
count = count + 1
if "abc" == "abcd":
count = count + 1
if "changed one character" == "changed %ne character":
count = count + 1
if "123" == 123: count = count + 1
if "a slightly longer string" == \
"a slightly longer string!":
count = count + 1
if "a slightly longer string" == \
"a slightly longer strinh":
count = count + 1
if "a significantly longer string but still not overwhelmingly long string" == \
"another":
count = count + 1
print(count)
print("elapsed: " + str(time.clock() - start))

View File

@ -1 +1 @@
IO.write(IO.read) // expect: null
IO.write(IO.read()) // expect: null