diff --git a/.gitignore b/.gitignore index d996ca57..316ac38a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,27 @@ # Build outputs. -bin/ -lib/ -wren +/bin +/lib +/wren # Intermediate files. -build/ -deps/ -.sass-cache/ +/build +/deps +/.sass-cache +*.pyc # I leave a temporary Wren script at the top level so that I can quickly test # stuff. -scratch.wren +/scratch.wren # The baseline file is machine-specific, so doesn't get checked in. -test/benchmark/baseline.txt +/test/benchmark/baseline.txt # XCode user-specific stuff. xcuserdata/ -*.xccheckout + +# Allow Visual Studio project files. +!wren/ +!wren_lib/ # Visual Studio cache files. ipch/ diff --git a/doc/site/classes.markdown b/doc/site/classes.markdown index 5f33a7c1..89f0d06f 100644 --- a/doc/site/classes.markdown +++ b/doc/site/classes.markdown @@ -328,7 +328,7 @@ constructors, etc. ## Fields -All state stored in instances is stored in *fields*. Each field has a named +All state stored in instances is stored in *fields*. Each field has a name that starts with an underscore. :::wren @@ -503,7 +503,7 @@ This means you can do `super` calls inside a constructor: **TODO: Integrate better into page. Should explain this before mentioning super above.** -Sometimes you want to invoke a method on yourself, but only methods defined in +Sometimes you want to invoke a method on yourself, but using methods defined in one of your [superclasses](classes.html#inheritance). You typically do this in an overridden method when you want to access the original method being overridden. diff --git a/src/module/io.c b/src/module/io.c index 1d0a80e9..9f3a836b 100644 --- a/src/module/io.c +++ b/src/module/io.c @@ -8,6 +8,13 @@ #include "wren.h" #include +#include + +typedef struct sFileRequestData +{ + WrenValue* fiber; + uv_buf_t buffer; +} FileRequestData; static const int stdinDescriptor = 0; @@ -67,8 +74,12 @@ static bool handleRequestError(uv_fs_t* request) { if (request->result >= 0) return false; - WrenValue* fiber = (WrenValue*)request->data; + FileRequestData* data = (FileRequestData*)request->data; + WrenValue* fiber = (WrenValue*)data->fiber; + schedulerResumeError(fiber, uv_strerror((int)request->result)); + + free(data); uv_fs_req_cleanup(request); free(request); return true; @@ -78,7 +89,11 @@ static bool handleRequestError(uv_fs_t* request) uv_fs_t* createRequest(WrenValue* fiber) { uv_fs_t* request = (uv_fs_t*)malloc(sizeof(uv_fs_t)); - request->data = fiber; + + FileRequestData* data = (FileRequestData*)malloc(sizeof(FileRequestData)); + data->fiber = fiber; + + request->data = data; return request; } @@ -87,8 +102,10 @@ uv_fs_t* createRequest(WrenValue* fiber) // Returns the fiber that should be resumed after [request] completes. WrenValue* freeRequest(uv_fs_t* request) { - WrenValue* fiber = (WrenValue*)request->data; - + FileRequestData* data = (FileRequestData*)request->data; + WrenValue* fiber = data->fiber; + + free(data); uv_fs_req_cleanup(request); free(request); @@ -111,7 +128,7 @@ void fileOpen(WrenVM* vm) uv_fs_t* request = createRequest(wrenGetArgumentValue(vm, 2)); // TODO: Allow controlling flags and modes. - uv_fs_open(getLoop(), request, path, O_RDONLY, S_IRUSR, openCallback); + uv_fs_open(getLoop(), request, path, O_RDONLY, 0, openCallback); } // Called by libuv when the stat call for size completes. @@ -171,7 +188,9 @@ static void fileReadBytesCallback(uv_fs_t* request) { if (handleRequestError(request)) return; - uv_buf_t buffer = request->bufs[0]; + FileRequestData* data = (FileRequestData*)request->data; + uv_buf_t buffer = data->buffer; + WrenValue* fiber = freeRequest(request); // TODO: Having to copy the bytes here is a drag. It would be good if Wren's @@ -190,12 +209,14 @@ void fileReadBytes(WrenVM* vm) int fd = *(int*)wrenGetArgumentForeign(vm, 0); // TODO: Assert fd != -1. - uv_buf_t buffer; - buffer.len = (size_t)wrenGetArgumentDouble(vm, 1); - buffer.base = (char*)malloc(buffer.len); + FileRequestData* data = (FileRequestData*)request->data; + size_t length = (size_t)wrenGetArgumentDouble(vm, 1); + + data->buffer.len = length; + data->buffer.base = (char*)malloc(length); // TODO: Allow passing in offset. - uv_fs_read(getLoop(), request, fd, &buffer, 1, 0, fileReadBytesCallback); + uv_fs_read(getLoop(), request, fd, &data->buffer, 1, 0, fileReadBytesCallback); } void fileSize(WrenVM* vm) diff --git a/util/msvc2013/wren/wren.vcxproj b/util/msvc2013/wren/wren.vcxproj new file mode 100644 index 00000000..e225b826 --- /dev/null +++ b/util/msvc2013/wren/wren.vcxproj @@ -0,0 +1,113 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {EBF43135-4A7A-400A-8F23-DF49907025AA} + Win32Proj + wren + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\..\src\include + $(SolutionDir)..\..\lib\$(Configuration)\;$(SolutionDir)..\..\util\deps\libuv\Release\lib\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) + $(SolutionDir)..\..\bin\$(Configuration)\ + $(SolutionDir)..\..\build\cli\$(Configuration)\ + + + false + $(SolutionDir)..\..\src\include;$(IncludePath) + $(SolutionDir)..\..\lib\$(Configuration)\;$(SolutionDir)..\..\util\deps\libuv\Release\lib\;$(LibraryPath) + $(SolutionDir)..\..\bin\$(Configuration)\ + $(SolutionDir)..\..\build\cli\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\..\..\src;..\..\..\src\cli;..\..\..\src\module;..\..\..\include;..\..\..\util\deps\libuv\include + + + Console + true + wren_static_d.lib;libuv.lib;ws2_32.lib;psapi.lib;iphlpapi.lib;userenv.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\..\..\src;..\..\..\src\cli;..\..\..\src\module;..\..\..\include;..\..\..\util\deps\libuv\include + + + Console + true + true + true + wren_static.lib;libuv.lib;ws2_32.lib;psapi.lib;iphlpapi.lib;userenv.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + {89cf2c43-749e-4ec4-a7c3-3f22fba9b874} + + + + + + \ No newline at end of file diff --git a/util/msvc2013/wren/wren.vcxproj.filters b/util/msvc2013/wren/wren.vcxproj.filters new file mode 100644 index 00000000..92a02def --- /dev/null +++ b/util/msvc2013/wren/wren.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/util/msvc2013/wren_lib/wren_lib.vcxproj b/util/msvc2013/wren_lib/wren_lib.vcxproj index 24bd9874..a168270e 100644 --- a/util/msvc2013/wren_lib/wren_lib.vcxproj +++ b/util/msvc2013/wren_lib/wren_lib.vcxproj @@ -39,14 +39,16 @@ - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\..\src\include; + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\..\src\include;$(SolutionDir)..\..\src\vm;$(SolutionDir)..\..\src\optional wren_static_d - $(SolutionDir)..\..\build\vs\$(Configuration)\ + $(SolutionDir)..\..\lib\$(Configuration)\ + $(SolutionDir)..\..\build\lib\$(Configuration)\ - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\..\src\include + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)..\..\src\include;$(SolutionDir)..\..\src\vm;$(SolutionDir)..\..\src\optional wren_static - $(SolutionDir)..\..\build\vs\$(Configuration)\ + $(SolutionDir)..\..\lib\$(Configuration)\ + $(SolutionDir)..\..\build\lib\$(Configuration)\ @@ -79,24 +81,26 @@ - - + + + - - + + + diff --git a/util/msvc2013/wren_lib/wren_lib.vcxproj.filters b/util/msvc2013/wren_lib/wren_lib.vcxproj.filters index ae3cc9af..a4a7df27 100644 --- a/util/msvc2013/wren_lib/wren_lib.vcxproj.filters +++ b/util/msvc2013/wren_lib/wren_lib.vcxproj.filters @@ -24,9 +24,6 @@ Source Files - - Source Files - Source Files @@ -36,14 +33,20 @@ Source Files - + Source Files - + + Source Files + + Source Files + + Header Files + Header Files @@ -56,23 +59,26 @@ Header Files - - Header Files - Header Files Header Files - + Header Files - + Header Files Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/util/pygments-lexer/wren/__init__.py b/util/pygments-lexer/wren/__init__.py new file mode 100644 index 00000000..8e14238a --- /dev/null +++ b/util/pygments-lexer/wren/__init__.py @@ -0,0 +1,82 @@ +import re +from pygments import highlight +from pygments.lexers import PythonLexer +from pygments.formatters import HtmlFormatter + +from pygments.lexer import RegexLexer +from pygments.token import * + +class WrenLexer(RegexLexer): + name = 'Wren' + aliases = ['wren'] + filenames = ['*.wren'] + + flags = re.MULTILINE | re.DOTALL + + tokens = { + 'root': [ + # Whitespace. + (r'\s+', Text), + (r'[,\\\[\]{}]', Punctuation), + + # Push a parenthesized state so that we know the corresponding ')' + # is for a parenthesized expression and not interpolation. + (r'\(', Punctuation, ('parenthesized', 'root')), + + # In this state, we don't know whether a closing ')' is for a + # parenthesized expression or the end of an interpolation. So, do + # a non-consuming match and let the parent state (either + # 'parenthesized' or 'interpolation' decide. + (r'(?=\))', Text, '#pop'), + + # Keywords. + (r'(break|class|construct|else|for|foreign|if|import|in|is|' + r'return|static|super|var|while)\b', Keyword), + + (r'(true|false|null)\b', Keyword.Constant), + + (r'this\b', Name.Builtin), + + # Comments. + (r'/\*', Comment.Multiline, 'comment'), + (r'//.*?$', Comment.Single), + + # Names and operators. + (r'[~!$%^&*\-=+\\|/?<>\.:]+', Operator), + (r'[A-Z][a-zA-Z_0-9]+', Name.Variable.Global), + (r'__[a-zA-Z_0-9]+', Name.Variable.Class), + (r'_[a-zA-Z_0-9]+', Name.Variable.Instance), + (r'[a-z][a-zA-Z_0-9]+', Name), + + # Numbers. + (r'\d+\.\d+([eE]-?\d+)?', Number.Float), + (r'0x[0-9a-fA-F]+', Number.Hex), + (r'\d+', Number.Integer), + + # Strings. + (r'L?"', String, 'string'), + ], + 'comment': [ + (r'/\*', Comment.Multiline, '#push'), + (r'\*/', Comment.Multiline, '#pop'), + (r'.', Comment.Multiline), # All other characters. + ], + 'string': [ + (r'"', String, '#pop'), + (r'\\[\\%0abfnrtv"\']', String.Escape), # Escape. + (r'\\x[a-fA-F0-9]{2}', String.Escape), # Byte escape. + (r'\\u[a-fA-F0-9]{4}', String.Escape), # Unicode escape. + (r'\\U[a-fA-F0-9]{8}', String.Escape), # Long Unicode escape. + + (r'%\(', String.Interpol, ('interpolation', 'root')), + (r'.', String), # All other characters. + ], + 'parenthesized': [ + # We only get to this state when we're at a ')'. + (r'\)', Punctuation, '#pop'), + ], + 'interpolation': [ + # We only get to this state when we're at a ')'. + (r'\)', String.Interpol, '#pop'), + ], + }