Skip to content
This repository
Browse code

merge

  • Loading branch information...
commit 4ffe224c81298ae353281caa850ad2599e0f172b 2 parents 05d64ff + b08dd35
rofl0r authored

Showing 66 changed files with 1,756 additions and 1,079 deletions. Show diff stats Hide diff stats

  1. +2 0  .gitignore
  2. +3 3 CHANGELOG
  3. +1 1  Makefile
  4. +16 15 libs/headers/gc/gc.h
  5. +1 5 sdk/io/File.ooc
  6. +10 1 sdk/io/native/FileUnix.ooc
  7. +9 0 sdk/io/native/FileWin32.ooc
  8. +61 20 sdk/lang/Exception.ooc
  9. +6 1 sdk/lang/Memory.ooc
  10. +10 4 sdk/lang/Numbers.ooc
  11. +6 1 sdk/lang/types.ooc
  12. +6 6 sdk/math.ooc
  13. +138 0 sdk/os/Coro.ooc
  14. +12 7 sdk/os/Time.ooc
  15. +1 1  sdk/os/native/PipeWin32.ooc
  16. +12 2 sdk/structs/List.ooc
  17. +1 0  sdk/structs/MultiMap.ooc
  18. +0 45 sdk/structs/RangeList.ooc
  19. +11 0 sdk/text/Buffer.ooc
  20. +2 2 sdk/text/EscapeSequence.ooc
  21. +1 1  sdk/text/StringTemplate.ooc
  22. +1 1  sdk/text/StringTokenizer.ooc
  23. +1 3 sdk/text/json/Generator.ooc
  24. +2 6 sdk/text/json/Parser.ooc
  25. +1 1  sdk/threading/native/ThreadUnix.ooc
  26. +27 18 source/rock/backend/cnaughty/ControlStatementWriter.ooc
  27. +4 0 source/rock/backend/cnaughty/FunctionCallWriter.ooc
  28. +6 3 source/rock/backend/cnaughty/FunctionDeclWriter.ooc
  29. +23 18 source/rock/backend/cnaughty/ModuleWriter.ooc
  30. +34 37 source/rock/frontend/AstBuilder.ooc
  31. +4 1 source/rock/frontend/BuildParams.ooc
  32. +79 17 source/rock/frontend/CommandLine.ooc
  33. +747 647 source/rock/frontend/NagaQueen.c
  34. +5 0 source/rock/frontend/Token.ooc
  35. +4 3 source/rock/frontend/drivers/CombineDriver.ooc
  36. +8 1 source/rock/frontend/drivers/Driver.ooc
  37. +79 51 source/rock/frontend/drivers/SequenceDriver.ooc
  38. +106 0 source/rock/middle/Addon.ooc
  39. +8 0 source/rock/middle/ArrayAccess.ooc
  40. +1 1  source/rock/middle/BaseType.ooc
  41. +1 2  source/rock/middle/BoolLiteral.ooc
  42. +1 2  source/rock/middle/CharLiteral.ooc
  43. +1 20 source/rock/middle/CoverDecl.ooc
  44. +1 1  source/rock/middle/Else.ooc
  45. +55 14 source/rock/middle/EnumDecl.ooc
  46. +1 2  source/rock/middle/FloatLiteral.ooc
  47. +2 2 source/rock/middle/FuncType.ooc
  48. +29 4 source/rock/middle/FunctionCall.ooc
  49. +24 16 source/rock/middle/FunctionDecl.ooc
  50. +3 1 source/rock/middle/If.ooc
  51. +1 1  source/rock/middle/InlineContext.ooc
  52. +1 2  source/rock/middle/IntLiteral.ooc
  53. +3 1 source/rock/middle/InterfaceDecl.ooc
  54. +28 6 source/rock/middle/InterfaceImpl.ooc
  55. +69 15 source/rock/middle/Match.ooc
  56. +21 8 source/rock/middle/Module.ooc
  57. +1 0  source/rock/middle/OperatorDecl.ooc
  58. +1 2  source/rock/middle/RangeLiteral.ooc
  59. +4 4 source/rock/middle/Scope.ooc
  60. +1 2  source/rock/middle/StringLiteral.ooc
  61. +23 28 source/rock/middle/TypeDecl.ooc
  62. +3 2 source/rock/middle/UseDef.ooc
  63. +3 1 source/rock/middle/VariableAccess.ooc
  64. +1 5 source/rock/middle/Version.ooc
  65. +28 10 source/rock/middle/algo/autoReturn.ooc
  66. +1 5 source/rock/middle/tinker/Resolver.ooc
2  .gitignore
@@ -4,6 +4,8 @@ build
4 4 *~
5 5 *.swp
6 6 bin
  7 +bin-win32
  8 +bin-linux
7 9 *tmp*
8 10 .libs
9 11 callgrind.out.*
6 CHANGELOG
@@ -39,11 +39,11 @@ pre-history
39 39 github project. nagaqueen (its fancy name) is now needed to make rock compile
40 40 - 2009-10 : Made a leg frontend, builds the AST, ported a lot of Java code with itrekkie,
41 41 rock now compiles things =)
42   - - 2009-10 : Creating the AST structure, code generation works well, putting the
  42 + - 2009-10 : Creating the AST structure, code generation works well, putting the
43 43 frontend on hold for a moment
44   - - 20.9.19 : The tokenizing code is all there, and it's working simply great.
  44 + - 2009-09 : The tokenizing code is all there, and it's working simply great.
45 45 Now onto constructing AST nodes.
46   - - 20.9.16 : Basic structure, it's gonna be some time till it can do anything useful
  46 + - 2009-06 : Basic structure, it's gonna be some time till it can do anything useful
47 47
48 48
49 49
2  Makefile
@@ -32,7 +32,7 @@ grammar:
32 32
33 33 .libs/NagaQueen.o: source/rock/frontend/NagaQueen.c
34 34 mkdir -p .libs
35   - gcc -std=c99 ${NQ_PATH} -D__OOC_USE_GC__ -w -c -o .libs/NagaQueen.o
  35 + gcc -std=c99 ${NQ_PATH} -O3 -fomit-frame-pointer -D__OOC_USE_GC__ -w -c -o .libs/NagaQueen.o
36 36
37 37
38 38 # Prepares the build/ directory, used for bootstrapping
31 libs/headers/gc/gc.h
... ... @@ -1,4 +1,4 @@
1   -/*
  1 +/*
2 2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3 3 * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
4 4 * Copyright 1996-1999 by Silicon Graphics. All rights reserved.
@@ -26,7 +26,7 @@
26 26 * Everything else is best ignored unless you encounter performance
27 27 * problems.
28 28 */
29   -
  29 +
30 30 #ifndef _GC_H
31 31
32 32 # define _GC_H
@@ -77,7 +77,7 @@ GC_API int GC_parallel; /* GC is parallelized for performance on */
77 77 /* If GC_parallel is set, incremental */
78 78 /* collection is only partially functional, */
79 79 /* and may not be desirable. */
80   -
  80 +
81 81
82 82 /* Public R/W variables */
83 83
@@ -166,7 +166,7 @@ GC_API int GC_full_freq; /* Number of partial collections between */
166 166 /* blocks. Values in the tens are now */
167 167 /* perfectly reasonable, unlike for */
168 168 /* earlier GC versions. */
169   -
  169 +
170 170 GC_API GC_word GC_non_gc_bytes;
171 171 /* Bytes not considered candidates for collection. */
172 172 /* Used only to control scheduling of collections. */
@@ -199,7 +199,7 @@ GC_API GC_word GC_max_retries;
199 199 /* The maximum number of GCs attempted before */
200 200 /* reporting out of memory after heap */
201 201 /* expansion fails. Initially 0. */
202   -
  202 +
203 203
204 204 GC_API char *GC_stackbottom; /* Cool end of user stack. */
205 205 /* May be set in the client prior to */
@@ -211,8 +211,8 @@ GC_API char *GC_stackbottom; /* Cool end of user stack. */
211 211 /* automatically. */
212 212 /* For multithreaded code, this is the */
213 213 /* cold end of the stack for the */
214   - /* primordial thread. */
215   -
  214 + /* primordial thread. */
  215 +
216 216 GC_API int GC_dont_precollect; /* Don't collect as part of */
217 217 /* initialization. Should be set only */
218 218 /* if the client wants a chance to */
@@ -321,7 +321,7 @@ GC_API size_t GC_size(void * object_addr);
321 321 /* It is an error to have changes enabled for the original object. */
322 322 /* Follows ANSI comventions for NULL old_object. */
323 323 GC_API void * GC_realloc(void * old_object, size_t new_size_in_bytes);
324   -
  324 +
325 325 /* Explicitly increase the heap size. */
326 326 /* Returns 0 on failure, 1 on success. */
327 327 GC_API int GC_expand_hp(size_t number_of_bytes);
@@ -464,7 +464,8 @@ GC_API void * GC_malloc_atomic_ignore_off_page(size_t lb);
464 464 #endif
465 465
466 466 #if defined(__linux__) || defined(__GLIBC__)
467   -# include <features.h>
  467 +// Google Native Client doesn't have features.h, and it doesn't seem to hurt to not include it on Linux at least
  468 +//# include <features.h>
468 469 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
469 470 && !defined(__ia64__) && !defined(__UCLIBC__)
470 471 # ifndef GC_HAVE_BUILTIN_BACKTRACE
@@ -503,7 +504,7 @@ GC_API void * GC_malloc_atomic_ignore_off_page(size_t lb);
503 504 #if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \
504 505 || defined(__FreeBSD__) || defined(__DragonFly__)) & !defined(GC_CAN_SAVE_CALL_STACKS)
505 506 # define GC_ADD_CALLER
506   -# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
  507 +# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
507 508 /* gcc knows how to retrieve return address, but we don't know */
508 509 /* how to generate call stacks. */
509 510 # define GC_RETURN_ADDR (GC_word)__builtin_return_address(0)
@@ -555,7 +556,7 @@ GC_API void GC_debug_end_stubborn_change(void *);
555 556 GC_API void * GC_debug_malloc_replacement (size_t size_in_bytes);
556 557 GC_API void * GC_debug_realloc_replacement
557 558 (void * object_addr, size_t size_in_bytes);
558   -
  559 +
559 560 # ifdef GC_DEBUG
560 561 # define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
561 562 # define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
@@ -649,7 +650,7 @@ GC_API void GC_debug_register_finalizer
649 650 /* Finalizers are implicitly unregistered just before */
650 651 /* they are invoked. */
651 652 /* The old finalizer and client data are stored in */
652   - /* *ofn and *ocd. */
  653 + /* *ofn and *ocd. */
653 654 /* Fn is never invoked on an accessible object, */
654 655 /* provided hidden pointers are converted to real */
655 656 /* pointers only if the allocation lock is held, and */
@@ -742,7 +743,7 @@ GC_API int GC_register_disappearing_link(void * * link );
742 743 /* registration succeeded, 2 if it failed for lack of */
743 744 /* memory, and GC_oom_fn did not handle the problem. */
744 745 /* Only exists for backward compatibility. See below: */
745   -
  746 +
746 747 GC_API int GC_general_register_disappearing_link (void * * link, void * obj);
747 748 /* A slight generalization of the above. *link is */
748 749 /* cleared when obj first becomes inaccessible. This */
@@ -812,7 +813,7 @@ GC_API GC_warn_proc GC_set_warn_proc(GC_warn_proc p);
812 813 GC_API GC_word GC_set_free_space_divisor(GC_word value);
813 814 /* Set free_space_divisor. See above for definition. */
814 815 /* Returns old value. */
815   -
  816 +
816 817 /* The following is intended to be used by a higher level */
817 818 /* (e.g. Java-like) finalization facility. It is expected */
818 819 /* that finalization code will arrange for hidden pointers to */
@@ -1005,7 +1006,7 @@ void * GC_malloc_many(size_t lb);
1005 1006 first call a user-supplied routine with filename of the library and
1006 1007 the address and length of the memory region. This routine should
1007 1008 return nonzero if that region should be scanned. */
1008   -GC_API void
  1009 +GC_API void
1009 1010 GC_register_has_static_roots_callback
1010 1011 (int (*callback)(const char *, void *, size_t));
1011 1012
6 sdk/io/File.ooc
@@ -325,11 +325,7 @@ File: abstract class {
325 325 :return: the current working directory
326 326 */
327 327 getCwd: static func -> String {
328   - ret := String new(File MAX_PATH_LENGTH + 1)
329   - if(!_getcwd(ret, File MAX_PATH_LENGTH)) {
330   - Exception new("Failed to get current directory!") throw()
331   - }
332   - return ret
  328 + ooc_get_cwd()
333 329 }
334 330
335 331 }
11 sdk/io/native/FileUnix.ooc
... ... @@ -1,4 +1,4 @@
1   -import ../File, os/Time, structs/ArrayList
  1 +import ../File, structs/ArrayList
2 2
3 3 include dirent
4 4
@@ -38,6 +38,15 @@ version(unix || apple) {
38 38
39 39 _getcwd: extern (getcwd) func(buf: Char*, size: SizeT) -> Char*
40 40
  41 + ooc_get_cwd: unmangled func -> String {
  42 + ret := String new(File MAX_PATH_LENGTH + 1)
  43 + if(!_getcwd(ret, File MAX_PATH_LENGTH)) {
  44 + Exception new("Failed to get current directory!") throw()
  45 + }
  46 + return ret
  47 + }
  48 +
  49 + TimeT: cover from time_t
41 50 ModeT: cover from mode_t
42 51
43 52 FileStat: cover from struct stat {
9 sdk/io/native/FileWin32.ooc
@@ -40,6 +40,7 @@ version(windows) {
40 40 FindClose: extern func (Handle)
41 41 GetFileAttributes: extern func (Char*) -> Long
42 42 CreateDirectory:extern func (Char*, Pointer) -> Bool
  43 + GetCurrentDirectory: extern func (Long, Pointer) -> Int
43 44
44 45 /*
45 46 * remove implementation
@@ -48,6 +49,14 @@ version(windows) {
48 49 printf("Win32: should remove file %s\n", path)
49 50 }
50 51
  52 + ooc_get_cwd: unmangled func -> String {
  53 + ret := String new(File MAX_PATH_LENGTH + 1)
  54 + if(!GetCurrentDirectory(File MAX_PATH_LENGTH, ret)) {
  55 + Exception new("Failed to get current directory!") throw()
  56 + }
  57 + return ret
  58 + }
  59 +
51 60 /*
52 61 * Win32 implementation of File
53 62 */
81 sdk/lang/Exception.ooc
... ... @@ -1,37 +1,78 @@
1 1 /**
2   - * exceptions
  2 + * Base class for all exceptions that can be thrown
  3 + *
  4 + * @author Amos Wenger (nddrylliog)
3 5 */
4 6 Exception: class {
5 7
  8 + /** Class which threw the exception. May be null */
6 9 origin: Class
7   - msg : String
8 10
9   - init: func ~originMsg (=origin, =msg) {}
10   - init: func ~noOrigin (=msg) {}
  11 + /** Message associated with this exception. Printed when the exception is thrown. */
  12 + message : String
11 13
12   - crash: func {
13   - fflush(stdout)
14   - x := 0
15   - x = 1 / x
16   - "%d" format( x) println()
17   - }
18 14
19   - getMessage: func -> String {
20   - //max := const 1024
21   - max : const SizeT = 1024
22   - buffer := String new (max)
23   - if(origin) snprintf(buffer, max, "[%s in %s]: %s\n", this as Object class name, origin name, msg)
24   - else snprintf(buffer, max, "[%s]: %s\n", this as Object class name, msg)
25   - return buffer
  15 + /**
  16 + * Create an exception
  17 + *
  18 + * @param origin The class throwing this exception
  19 + * @param message A short text explaning why the exception was thrown
  20 + */
  21 + init: func (=origin, =message) {}
  22 +
  23 + /**
  24 + * Create an exception
  25 + *
  26 + * @param message A short text explaning why the exception was thrown
  27 + */
  28 + init: func ~noOrigin (=message) {}
  29 +
  30 +
  31 + /**
  32 + * @return the exception's message, nicely formatted
  33 + */
  34 + format: func -> String {
  35 + if(origin)
  36 + "[%s in %s]: %s" format(class name, origin name, message)
  37 + else
  38 + "[%s]: %s" format(class name, message)
26 39 }
27 40
  41 + /**
  42 + * Print this exception, with its origin, if specified, and its message
  43 + */
28 44 print: func {
29   - fprintf(stderr, "%s", getMessage())
  45 + fprintf(stderr, "%s", format())
30 46 }
31 47
32   - throw: func {
  48 + /**
  49 + * Throw this exception
  50 + */
  51 + throw: inline final func {
33 52 print()
34   - crash()
  53 + abort()
35 54 }
36 55
37 56 }
  57 +
  58 +/* ------ C interfacing ------ */
  59 +
  60 +include stdlib
  61 +
  62 +/** stdlib.h -
  63 + *
  64 + * The abort() first unblocks the SIGABRT signal, and then raises that
  65 + * signal for the calling process. This results in the abnormal
  66 + * termination of the process unless the SIGABRT signal is caught
  67 + * and the signal handler does not return (see longjmp(3)).
  68 + *
  69 + * If the abort() function causes process termination, all open streams
  70 + * are closed and flushed.
  71 + *
  72 + * If the SIGABRT signal is ignored, or caught by a handler that returns,
  73 + * the abort() function will still terminate the process. It does this
  74 + * by restoring the default disposition for SIGABRT and then raising
  75 + * the signal for a second time.
  76 + */
  77 +abort: extern func
  78 +
7 sdk/lang/Memory.ooc
... ... @@ -1,4 +1,7 @@
1   -include memory
  1 +
  2 +// as goofy as it sounds, memory-related routines are actually in string.h
  3 +// yay C. (Also, Google Native Client doesn't have memory.h)
  4 +include string
2 5
3 6 version(!gc) {
4 7 // GC_MALLOC zeroes the memory, so in the non-gc version, we prefer to use calloc
@@ -12,6 +15,7 @@ version(!gc) {
12 15 gc_malloc_atomic: extern(malloc) func (size: SizeT) -> Pointer
13 16 gc_realloc: extern(realloc) func (ptr: Pointer, size: SizeT) -> Pointer
14 17 gc_calloc: extern(calloc) func (nmemb: SizeT, size: SizeT) -> Pointer
  18 + gc_free: extern(free) func (ptr: Pointer)
15 19 }
16 20
17 21 version(gc) {
@@ -23,6 +27,7 @@ version(gc) {
23 27 gc_calloc: func (nmemb: SizeT, size: SizeT) -> Pointer {
24 28 gc_malloc(nmemb * size)
25 29 }
  30 + gc_free: extern(GC_FREE) func (ptr: Pointer)
26 31 }
27 32
28 33 // memory management
14 sdk/lang/Numbers.ooc
... ... @@ -1,4 +1,4 @@
1   -include stdlib, stdint, stdbool, float, ctype, sys/types
  1 +include stdlib, stdint, stddef, float, ctype, sys/types
2 2
3 3 LLong: cover from signed long long {
4 4
@@ -26,6 +26,11 @@ LLong: cover from signed long long {
26 26 }
27 27 }
28 28
  29 + times: func ~withIndex (fn: Func(This)) {
  30 + for (i in 0..this) {
  31 + fn(i)
  32 + }
  33 + }
29 34 }
30 35
31 36 Long: cover from signed long extends LLong
@@ -46,9 +51,9 @@ UInt: cover from unsigned int extends ULLong
46 51 UShort: cover from unsigned short extends ULLong
47 52
48 53 //INT_MIN, INT_MAX : extern const static Int
49   -//UINT_MAX : extern const static UInt
  54 +//UINT_MAX : extern const static UInt
50 55 //LONG_MIN, LONG_MAX : extern const static Long
51   -//ULONG_MAX : extern const static ULong
  56 +//ULONG_MAX : extern const static ULong
52 57 //LLONG_MIN, LLONG_MAX : extern const static LLong
53 58 //ULLONG_MAX : extern const static ULLong
54 59
@@ -71,6 +76,7 @@ UInt64: cover from uint64_t extends ULLong
71 76 Octet: cover from uint8_t
72 77 SizeT: cover from size_t extends ULLong
73 78 SSizeT: cover from ssize_t extends LLong
  79 +PtrDiff: cover from ptrdiff_t extends SizeT
74 80
75 81 /**
76 82 * real types
@@ -116,4 +122,4 @@ Range: cover {
116 122 acc
117 123 }
118 124
119   -}
  125 +}
7 sdk/lang/types.ooc
... ... @@ -1,4 +1,9 @@
1   -include stddef, stdlib, stdio, ctype, stdbool, ./Array
  1 +include stddef, stdlib, stdio, ctype, ./Array
  2 +
  3 +version(!_MSC_VER) {
  4 + // MSVC doesn't support C99, so no stdbool for it
  5 + include stdbool
  6 +}
2 7
3 8 /**
4 9 * objects
12 sdk/math.ooc
@@ -46,7 +46,7 @@ floor: extern(floorl) func ~Long (LDouble) -> LDouble
46 46 - Scott
47 47 */
48 48
49   -Double: cover {
  49 +extend Double {
50 50 cos: extern(cos) func -> This
51 51 sin: extern(sin) func -> This
52 52 tan: extern(tan) func -> This
@@ -66,7 +66,7 @@ Double: cover {
66 66 abs: extern(fabs) func -> This
67 67 pow: extern(pow) func (This) -> This
68 68 exp: extern(exp) func -> This
69   -
  69 +
70 70 log: extern(log) func -> This
71 71 log10: extern(log10) func -> This
72 72
@@ -80,7 +80,7 @@ Double: cover {
80 80 truncate: extern(trunc) func -> This
81 81 }
82 82
83   -Float: cover {
  83 +extend Float {
84 84 cos: extern(cosf) func -> This
85 85 sin: extern(sinf) func -> This
86 86 tan: extern(tanf) func -> This
@@ -100,7 +100,7 @@ Float: cover {
100 100 abs: extern(fabsf) func -> This
101 101 pow: extern(powf) func (This) -> This
102 102 exp: extern(expf) func -> This
103   -
  103 +
104 104 log: extern(logf) func -> This
105 105 log10: extern(log10f) func -> This
106 106
@@ -114,7 +114,7 @@ Float: cover {
114 114 truncate: extern(truncf) func -> This
115 115 }
116 116
117   -LDouble: cover {
  117 +extend LDouble {
118 118 cos: extern(cosl) func -> This
119 119 sin: extern(sinl) func -> This
120 120 tan: extern(tanl) func -> This
@@ -134,7 +134,7 @@ LDouble: cover {
134 134 abs: extern(fabsl) func -> This
135 135 pow: extern(powl) func (This) -> This
136 136 exp: extern(expl) func -> This
137   -
  137 +
138 138 log: extern(logl) func -> This
139 139 log10: extern(log10l) func -> This
140 140
138 sdk/os/Coro.ooc
... ... @@ -0,0 +1,138 @@
  1 +
  2 +/**
  3 + * Portable ucontext-based coroutines implementation for cooperative multitasking.
  4 + *
  5 + * Largely based on Steve Dekorte's libcoroutine, see authors below.
  6 + *
  7 + * @author Steve Dekorte (libcoroutine - http://github.com/stevedekorte/coroutine)
  8 + * @author Russ Cox (libcoroutine OSX10.6 fixes)
  9 + * @author Edgar Toernig (Minimalistic cooperative multitasking - http://www.goron.de/~froese/)
  10 + * @author Amos Wenger (nddrylliog)
  11 + */
  12 +Coro: class {
  13 +
  14 + // this was originally commented '128k needed on PPC due to parser'
  15 + // I have no idea what that means but 128k sounds reasonable.
  16 + DEFAULT_STACK_SIZE := static 128 * 1_024
  17 + MIN_STACK_SIZE := static 8_192
  18 +
  19 + requestedStackSize: SizeT { get set }
  20 + allocatedStackSize: SizeT
  21 + stack: Pointer { get set }
  22 + env: UContext
  23 + isMain: Bool
  24 +
  25 + init: func {
  26 + requestedStackSize = DEFAULT_STACK_SIZE
  27 + allocatedStackSize = 0
  28 + }
  29 +
  30 + allocStackIfNeeded: func {
  31 + if (stack != null && allocatedStackSize > requestedStackSize) {
  32 + gc_free(stack)
  33 + stack = gc_malloc(requestedStackSize)
  34 + allocatedStackSize = requestedStackSize
  35 + }
  36 +
  37 + if (stack == null) {
  38 + stack = gc_malloc(requestedStackSize)
  39 + allocatedStackSize = requestedStackSize
  40 + }
  41 + }
  42 +
  43 + free: func {
  44 + if(stack) {
  45 + gc_free(stack)
  46 + }
  47 + }
  48 +
  49 + currentStackPointer: func -> UInt8* {
  50 + a: UInt8
  51 + b := a& // to avoid compiler warning about unused variables
  52 + b
  53 + }
  54 +
  55 + bytesLeftOnStack: func -> SizeT {
  56 + dummy: UChar
  57 + p1: PtrDiff = dummy&
  58 + p2: PtrDiff = currentStackPointer()
  59 +
  60 + start: PtrDiff = stack
  61 + end: PtrDiff = stack + requestedStackSize
  62 +
  63 + stackMovesUp := (p2 > p1)
  64 + if(stackMovesUp) { // like x86
  65 + end - p1
  66 + } else { // like OSX on PPC
  67 + p1 - start
  68 + }
  69 + }
  70 +
  71 + stackSpaceAlmostGone: func -> Bool {
  72 + bytesLeftOnStack() < MIN_STACK_SIZE
  73 + }
  74 +
  75 + initializeMainCoro: func {
  76 + isMain = true
  77 + }
  78 +
  79 + startCoro: func (other: This, callback: Func) {
  80 + other allocStackIfNeeded()
  81 + other setup(||
  82 + callback()
  83 + "Scheduler error: returned from coro start function" println()
  84 + exit(-1)
  85 + )
  86 + switchTo(other)
  87 + }
  88 +
  89 + setup: func (callback: Func) {
  90 + getcontext(env&)
  91 +
  92 + env stack stackPointer = stack
  93 + env stack stackSize = requestedStackSize
  94 + env stack flags = 0
  95 + env link = null
  96 +
  97 + makecontext(env&, callback as Closure thunk, 1, callback as Closure context)
  98 + }
  99 +
  100 + switchTo: func (next: This) {
  101 + swapcontext(env&, next env&)
  102 + }
  103 +
  104 +}
  105 +
  106 +/* ------ C interfacing ------- */
  107 +
  108 +include ucontext
  109 +
  110 +StackT: cover from stack_t {
  111 + stackPointer: extern(ss_sp) Pointer
  112 + flags: extern(ss_flags) Int
  113 + stackSize: extern(ss_size) SizeT
  114 +}
  115 +
  116 +UContext: cover from ucontext_t {
  117 + stack: extern(uc_stack) StackT
  118 + link: extern(uc_link) Pointer
  119 +}
  120 +
  121 +getcontext: extern func (ucp: UContext*) -> Int
  122 +setcontext: extern func (ucp: UContext*) -> Int
  123 +makecontext: extern func (ucp: UContext*, _func: Pointer, argc: Int, ...)
  124 +swapcontext: extern func (oucp: UContext*, ucp: UContext*) -> Int
  125 +
  126 +
  127 +
  128 +
  129 +
  130 +
  131 +
  132 +
  133 +
  134 +
  135 +
  136 +
  137 +
  138 +
19 sdk/os/Time.ooc
... ... @@ -1,4 +1,6 @@
1 1
  2 +import native/win32/types
  3 +
2 4 /* includes */
3 5
4 6 version(linux) {
@@ -20,8 +22,9 @@ version(windows) {
20 22 wHour, wMinute, wSecond, wMilliseconds : extern UShort
21 23 }
22 24
23   - timeGetTime: extern func -> UInt32
24 25 GetLocalTime: extern func (SystemTime*)
  26 + QueryPerformanceCounter: extern func (LargeInteger*)
  27 + QueryPerformanceFrequency: extern func (LargeInteger*)
25 28 Sleep: extern func (UInt)
26 29 }
27 30
@@ -77,12 +80,14 @@ Time: class {
77 80 runTime: static UInt {
78 81 get {
79 82 version(windows) {
80   - // NOTE: timeGetTime only returns a 32-bit integer. the upside is
81   - // that it's accurate to 1ms, but unfortunately rollover is very
82   - // possible
83   -
84   - // FIXME: getting undefined reference for now :x
85   - timeGetTime() as UInt - __time_millisec_base
  83 + // NOTE: this was previously using timeGetTime, but it's
  84 + // a winmm.lib function and we can't afford the extra dep
  85 + // I believe every computer that runs ooc programs on Win32
  86 + // has a hardware high-performance counter, so it shouldn't be an issue
  87 + counter, frequency: LargeInteger
  88 + QueryPerformanceCounter(counter&)
  89 + QueryPerformanceFrequency(frequency&)
  90 + return ((counter quadPart * 1000) / frequency quadPart) - __time_millisec_base
86 91 }
87 92 version(!windows) {
88 93 tv : TimeVal
2  sdk/os/native/PipeWin32.ooc
... ... @@ -1,4 +1,4 @@
1   -import ../Pipe, native/win32/[types, errors], os/Time
  1 +import ../Pipe, native/win32/[types, errors]
2 2
3 3 version(windows) {
4 4
14 sdk/structs/List.ooc
@@ -212,10 +212,11 @@ List: abstract class <T> extends BackIterable<T> {
212 212 /**
213 213 * Reverse this list (destructive)
214 214 */
215   - reverse: func {
  215 + reverse!: func {
216 216 i := 0
217 217 j := size() - 1
218   - while (i <= j / 2) {
  218 + limit := j / 2
  219 + while (i <= limit) {
219 220 set(i, set(j, get(i)))
220 221 i += 1
221 222 j -= 1
@@ -223,6 +224,15 @@ List: abstract class <T> extends BackIterable<T> {
223 224 }
224 225
225 226 /**
  227 + * Reverse this list (non-destructive)
  228 + */
  229 + reverse: func -> This<T> {
  230 + copy := clone()
  231 + copy reverse!()
  232 + copy
  233 + }
  234 +
  235 + /**
226 236 * Convert this list to a raw C array
227 237 */
228 238 toArray: func -> Pointer {
1  sdk/structs/MultiMap.ooc
@@ -56,6 +56,7 @@ MultiMap: class <K, V> extends HashMap<K, V> {
56 56 // Only one left - turn the list into a single element
57 57 put~_super(key, list first())
58 58 }
  59 + return true
59 60 } else {
60 61 // Only one - remove it
61 62 return super(key)
45 sdk/structs/RangeList.ooc
... ... @@ -1,45 +0,0 @@
1   -import structs/List
2   -
3   -RangeList: class extends List<T> {
4   -
5   - data : List<T>
6   - range: Range
7   -
8   - init: func (=data, =range) {}
9   -
10   - iterator: func -> Iterator<T> { RangeListIterator<T> new(this) }
11   -
12   -}
13   -
14   -RangeListIterator: class extends BackIterator<T> {
15   -
16   - list: RangeList<T>
17   - remaining : Int
18   - subIter : Iterator<T>
19   -
20   - init: func(=list) {
21   - subIter := list data iter()
22   - for(i in 0..list range min) {
23   - subIter next()
24   - }
25   - remaining = list range max - list range min
26   - }
27   -
28   - next: func -> T {
29   - remaining -= 1
30   - return subIter next()
31   - }
32   -
33   - hasNext?: func -> Bool {
34   - remaining > 0
35   - }
36   -
37   - /* TODO: stub */
38   -
39   - prev: func -> T { null }
40   -
41   - hasPrev?: func -> Bool { false }
42   -
43   - remove: func -> Bool { false }
44   -
45   -}
11 sdk/text/Buffer.ooc
@@ -200,6 +200,17 @@ BufferReader: class extends Reader {
200 200 }
201 201 }
202 202
  203 +operator == (a, b: Buffer) -> Bool {
  204 + if (!a && !b) return true
  205 + if ((!a && b) || (!b && a)) return false
  206 + return ( (a size == b size) && ( memcmp ( a data as Char*, b data as Char*, a size ) == 0 ) )
  207 +}
  208 +
  209 +operator != (a, b: Buffer) -> Bool {
  210 + if (a == b) return false
  211 + else return true
  212 +}
  213 +
203 214 /* Test routines
204 215 TODO use kinda builtin assert which doesnt crash when one test fails
205 216 once unittest facility is builtin
4 sdk/text/EscapeSequence.ooc
@@ -44,7 +44,7 @@ EscapeSequence: class {
44 44 /* invalid character in hexadecimal literal. */
45 45 return This invalid
46 46 }
47   - chr@ += pow(16, i) * value
  47 + chr@ += (pow(16, i) as Int) * value
48 48 }
49 49 return This valid
50 50 } else {
@@ -66,7 +66,7 @@ EscapeSequence: class {
66 66 /* invalid character in octal literal. */
67 67 return This invalid
68 68 }
69   - chr@ += pow(8, i) * value
  69 + chr@ += (pow(8, i) as Int) * value
70 70 }
71 71 return This valid
72 72 }
2  sdk/text/StringTemplate.ooc
... ... @@ -1,3 +1,3 @@
1 1 import structs/HashMap
2 2
3   -// contents moved to String.ooc, can come back once the "extend" keyword is implemented.
  3 +// contents moved to String.ooc, can come back once the "extend" keyword is implemented.
2  sdk/text/StringTokenizer.ooc
@@ -48,4 +48,4 @@ StringTokenizerIterator: class <T> extends Iterator<T> {
48 48 prev: func -> T { null }
49 49 remove: func -> Bool { false }
50 50
51   -}
  51 +}
4 sdk/text/json/Generator.ooc
@@ -5,9 +5,7 @@ import text/[Buffer, EscapeSequence]
5 5 import Parser
6 6
7 7 GeneratorError: class extends Exception {
8   - init: func ~withMsg (.msg) {
9   - super(msg)
10   - }
  8 + init: super func ~noOrigin
11 9 }
12 10
13 11 EXCLUDE := const "'" // don't escape the '
8 sdk/text/json/Parser.ooc
@@ -37,15 +37,11 @@ check: func (this: Token@, type: TokenType) {
37 37 }*/
38 38
39 39 LexingError: class extends Exception {
40   - init: func ~withMsg (.msg) {
41   - super(msg)
42   - }
  40 + init: super func ~noOrigin
43 41 }
44 42
45 43 ParserError: class extends Exception {
46   - init: func ~withMsg (.msg) {
47   - super(msg)
48   - }
  44 + init: super func ~noOrigin
49 45 }
50 46
51 47 getToken: func (reader: Reader, token: Token*) {
2  sdk/threading/native/ThreadUnix.ooc
... ... @@ -1,5 +1,5 @@
1 1 import ../Thread
2   -include pthread, unistd, gc
  2 +include pthread, unistd
3 3
4 4 version(unix || apple) {
5 5
45 source/rock/backend/cnaughty/ControlStatementWriter.ooc
@@ -59,26 +59,35 @@ ControlStatementWriter: abstract class extends Skeleton {
59 59
60 60 write: static func ~_match (this: Skeleton, mat: Match) {
61 61 isFirst := true
62   - for(caze in mat getCases()) {
63   - if(!isFirst) current app(" else ")
  62 + writeBody := func(caze: Case) {
  63 + current app("{"). tab()
  64 + for (stat in caze getBody()) writeLine(stat)
  65 + current untab(). nl(). app("}")
  66 + }
  67 +
  68 + // ´case =>´ as only match-case
  69 + if (mat getCases() size() == 1) {
  70 + caze := mat getCases() get(0)
  71 + if (!caze getExpr()) {
  72 + writeBody(caze)
  73 + return
  74 + }
  75 + }
64 76
65   - if(caze getExpr() == null) {
66   - if(isFirst) current.app(" else ");
67   - } else {
  77 + for(caze in mat getCases()) {
  78 + if(!isFirst) current app(" else ")
  79 +
  80 + if(caze getExpr() == null) {
  81 + if(isFirst) current.app(" else ");
  82 + } else {
68 83 // FIXME: wtf? (from the j/ooc codebase)
69   - //if(case1 isFallthrough()) current app(' ')
70   - current app("if ("). app(caze getExpr()). app(")")
71   - }
72   -
73   - current app("{"). tab()
74   -
75   - for(stat in caze getBody()) {
76   - writeLine(stat)
77   - }
78   -
79   - current untab(). nl(). app("}")
80   - if(isFirst) isFirst = false;
81   - }
  84 + //if(case1 isFallthrough()) current app(' ')
  85 + current app("if ("). app(caze getExpr()). app(")")
  86 + }
  87 +
  88 + writeBody(caze)
  89 + if(isFirst) isFirst = false;
  90 + }
82 91 }
83 92
84 93 }
4 source/rock/backend/cnaughty/FunctionCallWriter.ooc
@@ -52,6 +52,10 @@ FunctionCallWriter: abstract class extends Skeleton {
52 52 // and still need casting
53 53 current app("_impl")
54 54 shouldCastThis = true
  55 + } else if(!fCall virtual) {
  56 + current app("_impl")
  57 + // and no need to cast this, it should already be of the good type
  58 + // (esp. for interfaces, since the struct-initialization is handled by the Cast node)
55 59 }
56 60 }
57 61
9 source/rock/backend/cnaughty/FunctionDeclWriter.ooc
@@ -67,7 +67,6 @@ FunctionDeclWriter: abstract class extends Skeleton {
67 67
68 68 /** Write the name of a function, with its suffix, and prefixed by its owner if any */
69 69 writeFullName: static func (this: Skeleton, fDecl: FunctionDecl) {
70   -
71 70 //printf("Writing full name of %s, owner = %s\n", fDecl name, fDecl owner ? fDecl owner toString() : "(nil)")
72 71 current app(fDecl getFullName())
73 72 }
@@ -101,8 +100,12 @@ FunctionDeclWriter: abstract class extends Skeleton {
101 100
102 101 isInterface := false
103 102 owner := fDecl getOwner()
104   - if(owner != null && owner isMeta) owner = owner getNonMeta()
105   - if(owner != null && owner instanceOf?(InterfaceDecl)) isInterface = true
  103 + if(owner != null) {
  104 + match(owner isMeta ? owner getNonMeta() : owner) {
  105 + case iDecl: InterfaceDecl =>
  106 + isInterface = true
  107 + }
  108 + }
106 109
107 110 /* Step 1 : write this, if any */
108 111 iter := fDecl args iterator() as Iterator<Argument>
41 source/rock/backend/cnaughty/ModuleWriter.ooc
@@ -58,7 +58,7 @@ ModuleWriter: abstract class extends Skeleton {
58 58
59 59 current nl(). app("#include <"). app(module getPath("-fwd.h")). app(">")
60 60
61   - // include .h-level imports (which contains types we extend)
  61 + // include .h-level imports (which contains types we extend)
62 62 for(imp in imports) {
63 63 if(!imp isTight()) continue
64 64 inc := imp getModule() getPath(".h")
@@ -113,10 +113,10 @@ ModuleWriter: abstract class extends Skeleton {
113 113 current = cw
114 114 current nl(). app("void "). app(module getLoadFuncName()). app("() {"). tab()
115 115 current nl(). app("static "). app("bool __done__ = false;"). nl(). app("if (!__done__)"). app("{"). tab()
116   - current nl(). app("__done__ = true;")
  116 + current nl(). app("__done__ = true;")
117 117 for (imp in module getAllImports()) {
118   - current nl(). app(imp getModule() getLoadFuncName()). app("();")
119   - }
  118 + current nl(). app(imp getModule() getLoadFuncName()). app("();")
  119 + }
120 120
121 121 for (type in module types) {
122 122 if(type instanceOf?(ClassDecl)) {
@@ -143,6 +143,11 @@ ModuleWriter: abstract class extends Skeleton {
143 143 current untab(). nl(). app("}")
144 144 current untab(). nl(). app("}"). nl()
145 145
  146 + // write all addons
  147 + for(addon in module addons) {
  148 + addon accept(this)
  149 + }
  150 +
146 151 // write all functions
147 152 for(fDecl in module functions) {
148 153 fDecl accept(this)
@@ -294,7 +299,7 @@ ModuleWriter: abstract class extends Skeleton {
294 299 name: String = customName ? customName : funcType toMangledString()
295 300 current nl(). nl(). app("#ifndef "). app(name). app("__DEFINE")
296 301 current nl(). app("#define "). app(name). app("__DEFINE"). nl()
297   - current nl(). app("typedef ")
  302 + current nl(). app("typedef ")
298 303 writeFuncPointer(this, funcType, name)
299 304 current app(';')
300 305 current nl(). nl(). app("#endif"). nl()
@@ -302,7 +307,7 @@ ModuleWriter: abstract class extends Skeleton {
302 307
303 308 writeFuncPointer: static func (this: Skeleton, funcType: FuncType, name: String) {
304 309 if(funcType returnType == null || funcType returnType isGeneric()) {
305   - current app("void")
  310 + current app("void")
306 311 } else {
307 312 current app(funcType returnType)
308 313 }
@@ -327,18 +332,18 @@ ModuleWriter: abstract class extends Skeleton {
327 332
328 333 /* Step 4 : write real args */
329 334 for(argType in funcType argTypes) {
330   - if(isFirst) isFirst = false
  335 + if(isFirst) isFirst = false
331 336 else current app(", ")
332   - current app(argType)
  337 + current app(argType)
333 338 }
334 339
335   - /* Step 5: write context, if any */
336   - if(funcType isClosure) {
337   - if(isFirst) isFirst = false
  340 + /* Step 5: write context, if any */
  341 + if(funcType isClosure) {
  342 + if(isFirst) isFirst = false
338 343 else current app(", ")
339   - // we don't know the type of the closure-context, so void* will do just fine. Thanks, C!
340   - current app("void*")
341   - }
  344 + // we don't know the type of the closure-context, so void* will do just fine. Thanks, C!
  345 + current app("void*")
  346 + }
342 347
343 348 current app(')')
344 349 }
@@ -414,14 +419,14 @@ ModuleWriter: abstract class extends Skeleton {
414 419 if(inc getVersion()) VersionWriter writeStart(this, inc getVersion())
415 420
416 421 for(define in inc getDefines()) {
417   - current nl(). app("#ifndef "). app(define name)
418   - current nl(). app("#define "). app(define name)
  422 + current nl(). app("#ifndef "). app(define name)
  423 + current nl(). app("#define "). app(define name)
419 424 if(define value != null) {
420 425 current app(' '). app(define value)
421 426 }
422 427 current nl(). app("#define "). app(define name). app("___defined")
423   - current nl(). app("#endif")
424   - }
  428 + current nl(). app("#endif")
  429 + }
425 430
426 431 chevron := (inc mode == IncludeModes PATHY)
427 432 current nl(). app("#include "). app(chevron ? '<' : '"').
71 source/rock/frontend/AstBuilder.ooc
@@ -14,7 +14,7 @@ import ../middle/[FunctionDecl, VariableDecl, TypeDecl, ClassDecl, CoverDecl,
14 14 Dereference, Foreach, OperatorDecl, RangeLiteral, UnaryOp, ArrayAccess,
15 15 Match, FlowControl, While, CharLiteral, InterfaceDecl, NamespaceDecl,
16 16 Version, Use, Block, ArrayLiteral, EnumDecl, BaseType, FuncType,
17   - Declaration, PropertyDecl, CallChain, Tuple]
  17 + Declaration, PropertyDecl, CallChain, Tuple, Addon]
18 18
19 19 nq_parse: extern proto func (AstBuilder, Char*) -> Int
20 20
@@ -52,8 +52,12 @@ AstBuilder: class {
52 52 tokenPos : Int*
53 53
54 54 init: func (=modulePath, =module, =params) {
  55 + first := static true
55 56
56   - if(params verbose) printf("- Parsing %s\n", modulePath)
  57 + if(params verbose) {
  58 + if(!first) " \r" print()
  59 + "Parsing %s" printf(modulePath)
  60 + }
57 61 cache put(File new(modulePath) getAbsolutePath(), module)
58 62
59 63 stack = Stack<Object> new()
@@ -64,6 +68,7 @@ AstBuilder: class {
64 68 addLangImports()
65 69 }
66 70
  71 + first = false
67 72 result := nq_parse(this, modulePath)
68 73 if(result == -1) {
69 74 Exception new(This, "File " +modulePath + " not found") throw()
@@ -170,6 +175,19 @@ AstBuilder: class {
170 175 }
171 176
172 177 /*
  178 + * Addons
  179 + */
  180 + onExtendStart: unmangled(nq_onExtendStart) func (baseType: Type, doc: String) {
  181 + addon := Addon new(baseType, token())
  182 + addon doc = doc
  183 + stack push(addon)
  184 + }
  185 +
  186 + onExtendEnd: unmangled(nq_onExtendEnd) func -> Addon {
  187 + module addAddon(pop(Addon))
  188 + }
  189 +
  190 + /*
173 191 * Covers
174 192 */
175 193
@@ -180,38 +198,6 @@ AstBuilder: class {
180 198 cDecl module = module
181 199 module addType(cDecl)
182 200 stack push(cDecl)
183   -
184   - // cover-absorbing =)
185   - absorbed := false
186   - for(imp in module getGlobalImports()) { // TODO: what about namespaced imports?
187   - depMod := imp getModule()
188   - //printf("Treating import %s, depMod = %s\n", imp path, depMod ? depMod getFullName() : "(nil)")
189   - if(depMod != null) {
190   - base := depMod getTypes() get(name)
191   - if(base != null) {
192   - //println(" >> While parsing "+cDecl getName()+" in "+module getFullName()+", found base in "+depMod getFullName())
193   - cDecl absorb(base as CoverDecl, params)
194   - absorbed = true
195   - break
196   - }
197   - }
198   - }
199   - if(!absorbed) {
200   - for(other in cache) {
201   - for(imp in other getGlobalImports()) {
202   - if(imp path == module getFullName()) {
203   - addon := other getTypes() get(name)
204   - if(addon != null) {
205   - //println(" >> [From cache] While parsing "+cDecl getName()+" in "+module getFullName() +", found addon in "+other getFullName())
206   - addon as CoverDecl absorb(cDecl, params)
207   - absorbed = true
208   - break
209   - }
210   - }
211   - }
212   - if(absorbed) break
213   - }
214   - }
215 201 }
216 202
217 203 onCoverExtern: unmangled(nq_onCoverExtern) func (externName: String) {
@@ -251,6 +237,10 @@ AstBuilder: class {
251 237 peek(EnumDecl) setExternName(externName clone())
252 238 }
253 239
  240 + onEnumFromType: unmangled(nq_onEnumFromType) func (fromType: Type) {
  241 + peek(EnumDecl) setFromType(fromType)
  242 + }
  243 +
254 244 onEnumIncrementExpr: unmangled(nq_onEnumIncrementExpr) func (oper: Char, step: IntLiteral) {
255 245 peek(EnumDecl) setIncrement(oper, step value)
256 246 }
@@ -261,8 +251,8 @@ AstBuilder: class {
261 251 stack push(element)
262 252 }
263 253