From 4656bf128e2bc84146a1b5f0a58f5167cf1e0fe8 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 19 Apr 2017 16:46:44 +0000 Subject: [PATCH] added a new class variable declarator 'var' or 'variable' supported | .. | style declartion at the class level. added the RDONLY flag to the object header wrote some code to support default values for class-level variables such as instance variables --- moo/kernel/Apex.moo | 14 + moo/kernel/Class.moo | 3 +- moo/kernel/Collect.moo | 6 +- moo/kernel/Console.moo | 2 +- moo/kernel/Context.moo | 10 +- moo/kernel/Except.moo | 11 +- moo/kernel/FFI.moo | 2 +- moo/kernel/Magnitu.moo | 2 +- moo/kernel/Mill.moo | 4 +- moo/kernel/Process.moo | 8 +- moo/kernel/Stdio.moo | 2 +- moo/kernel/X11.moo | 157 ++++--- moo/kernel/generr.moo | 7 +- moo/lib/comp.c | 952 ++++++++++++++++++++++++++--------------- moo/lib/err.c | 63 +-- moo/lib/exec.c | 8 + moo/lib/heap.c | 3 +- moo/lib/moo-prv.h | 33 +- moo/lib/moo.h | 17 +- moo/lib/obj.c | 32 ++ moo/lib/sym.c | 4 +- 21 files changed, 864 insertions(+), 476 deletions(-) diff --git a/moo/kernel/Apex.moo b/moo/kernel/Apex.moo index 898f781..0864934 100644 --- a/moo/kernel/Apex.moo +++ b/moo/kernel/Apex.moo @@ -133,6 +133,15 @@ class Apex(nil) method basicAt: index put: anObject { +## TODO: proper error handling +(* + if (primitiveError == error(generic)) + { + } + else + { + self index: index outOfRange: (self basicSize). + }*) self index: index outOfRange: (self basicSize). } @@ -429,6 +438,11 @@ class Apex(nil) { ^self class notImplemented: method_name } + + method messageProhibited: method_name + { + ^self class messageProhibited: method_name + } method cannotExceptionizeError { diff --git a/moo/kernel/Class.moo b/moo/kernel/Class.moo index 6e4b20f..bf04d90 100644 --- a/moo/kernel/Class.moo +++ b/moo/kernel/Class.moo @@ -4,7 +4,8 @@ ## class(#pointer) Class(Apex) { - dcl spec selfspec superclass subclasses name modname instvars classvars classinstvars pooldics instmthdic classmthdic nsdic trsize. + var spec, selfspec, superclass, subclasses, name, modname, instvars. + var classvars, classinstvars, pooldics, instmthdic, classmthdic, nsdic, cdic, trsize, initv. method(#class) basicNew { diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index 685c669..d431440 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -164,7 +164,7 @@ class(#byte) ByteArray(Collection) class Set(Collection) { - dcl tally bucket. + var tally, bucket. method(#class) new: size { @@ -550,7 +550,7 @@ extend Apex class Link(Object) { - dcl prev next value. + var prev, next, value. method(#class) new: value { @@ -570,7 +570,7 @@ class Link(Object) class LinkedList(Collection) { - dcl first last tally. + var first, last, tally. method initialize { diff --git a/moo/kernel/Console.moo b/moo/kernel/Console.moo index f22c8c0..3a86303 100644 --- a/moo/kernel/Console.moo +++ b/moo/kernel/Console.moo @@ -1,7 +1,7 @@ ## TODO: move Pointe to a separate file class Point(Object) { - dcl x y. + var x, y. method(#class) new { diff --git a/moo/kernel/Context.moo b/moo/kernel/Context.moo index b98e0ed..cc12cbe 100644 --- a/moo/kernel/Context.moo +++ b/moo/kernel/Context.moo @@ -1,6 +1,6 @@ class(#pointer) Context(Apex) { - dcl sender ip sp ntmprs. + var sender, ip, sp, ntmprs. method sender { @@ -44,7 +44,7 @@ block context... class(#pointer) MethodContext(Context) { - dcl method receiver home origin. + var method, receiver, home, origin. method pc { @@ -101,7 +101,7 @@ class(#pointer) MethodContext(Context) class(#pointer) BlockContext(Context) { - dcl nargs source home origin. + var nargs, source, home, origin. method vargCount { @@ -328,8 +328,8 @@ class(#pointer) BlockContext(Context) class(#pointer) CompiledMethod(Object) { - ## dcl owner name preamble preamble_data_1 preamble_data_2 ntmprs nargs code source. - dcl owner name preamble preamble_data_1 preamble_data_2 ntmprs nargs source. + ## var owner, name, preamble, preamble_data_1, preamble_data_2, ntmprs, nargs, code, source. + var owner, name, preamble, preamble_data_1, preamble_data_2, ntmprs, nargs, source. method preamble { diff --git a/moo/kernel/Except.moo b/moo/kernel/Except.moo index ae0481d..ddff414 100644 --- a/moo/kernel/Except.moo +++ b/moo/kernel/Except.moo @@ -6,7 +6,7 @@ ## class Exception(Apex) { - dcl signalContext handlerContext messageText. + var signalContext, handlerContext, messageText. method(#class) signal { @@ -383,6 +383,10 @@ class InvalidArgumentException(Exception) { } +class ProhibitedMessageException(Exception) +{ +} + extend Apex { method(#class) primitiveFailed @@ -428,6 +432,11 @@ ctx := thisContext. NotImplementedException signal: (method_name & ' not implemented by ' & (self name)). } + method(#class) messageProhibited: method_name + { + ProhibitedMessageException signal: (method_name & ' not allowed for ' & (self name)). + } + method(#class) cannotExceptionizeError { ## todo: accept the object diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index 93aca2d..1e45230 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -10,7 +10,7 @@ class _FFI(Object) from 'ffi' class FFI(Object) { - dcl name ffi funcs. + var name, ffi, funcs. method(#class) new: aString { diff --git a/moo/kernel/Magnitu.moo b/moo/kernel/Magnitu.moo index 27ef298..075e4da 100644 --- a/moo/kernel/Magnitu.moo +++ b/moo/kernel/Magnitu.moo @@ -4,7 +4,7 @@ class Magnitude(Object) class Association(Magnitude) { - dcl key value. + var key, value. method(#class) key: key value: value { diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index a4cfd8f..1fb0c73 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -2,8 +2,8 @@ class Mill(Object) { - dcl registrar. -dcl obj. + var registrar. + var obj. method initialize { diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 8692362..c5569fb 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -1,7 +1,7 @@ class(#pointer) Process(Object) { - dcl initial_context current_context state sp prev next sem. + var initial_context, current_context, state, sp, prev, next, sem. method new { @@ -99,7 +99,7 @@ class(#pointer) Process(Object) class Semaphore(Object) { - dcl count waiting_head waiting_tail heapIndex fireTimeSec fireTimeNsec ioIndex ioData ioMask. + var count, waiting_head, waiting_tail, heapIndex, fireTimeSec, fireTimeNsec, ioIndex, ioData, ioMask. method(#class) forMutualExclusion { @@ -176,7 +176,7 @@ class Semaphore(Object) class SemaphoreHeap(Object) { - dcl arr size. + var arr, size. method initialize { @@ -358,7 +358,7 @@ class SemaphoreHeap(Object) class ProcessScheduler(Object) { - dcl tally active runnable_head runnable_tail sem_heap. + var tally, active, runnable_head, runnable_tail, sem_heap. method new { diff --git a/moo/kernel/Stdio.moo b/moo/kernel/Stdio.moo index 97ac02c..19487a2 100644 --- a/moo/kernel/Stdio.moo +++ b/moo/kernel/Stdio.moo @@ -1,7 +1,7 @@ class Stdio(Object) from 'stdio' { - dcl(#class) in out err. + var(#class) in, out, err. method(#primitive) open(name, mode). method(#primitive) close. diff --git a/moo/kernel/X11.moo b/moo/kernel/X11.moo index 902518b..570ba63 100644 --- a/moo/kernel/X11.moo +++ b/moo/kernel/X11.moo @@ -6,18 +6,18 @@ class X11(Object) from 'x11' { (* The X11 class represents a X11 display *) - dcl(#class) default_display. + var(#class) default_display. - dcl cid. - dcl windows. ## all windows registered + var cid. + var windows. ## all windows registered - dcl event_loop_sem event_loop_proc. - dcl ll_event_blocks. + var event_loop_sem, event_loop_proc. + var ll_event_blocks. - dcl expose_event. - dcl key_event. - dcl mouse_event. - dcl mouse_wheel_event. + var expose_event. + var key_event. + var mouse_event. + var mouse_wheel_event. method(#primitive) _connect. method(#primitive) _disconnect. @@ -35,7 +35,7 @@ class X11.Exception(System.Exception) class X11.Rectangle(Object) { - dcl x y width height. + var x, y, width, height. method initialize { @@ -79,6 +79,7 @@ pooldic X11.LLEvent LEAVE_NOTIFY := 8. EXPOSE := 12. VISIBILITY_NOTIFY := 15. + DESTROY_NOTIFY := 17. CONFIGURE_NOTIFY := 22. CLIENT_MESSAGE := 33. } @@ -87,36 +88,56 @@ class X11.Event(Object) { } -class X11.InputEvent(X11.Event) + +class X11.KeyEvent(X11.Event) { } -class X11.KeyEvent(X11.InputEvent) +pooldic X11.MouseButton { + LEFT := 1. + MIDDLE := 2. + RIGHT := 3. } -class X11.MouseEvent(X11.InputEvent) +class X11.MouseEvent(X11.Event) { - dcl x y. + var x, y, button. - method x { ^self.x } - method y { ^self.y } + method x { ^self.x } + method y { ^self.y } + method button { ^self.button } ## X11.MouseButton - method x: x y: y + method initialize + { + self.x := 0. + self.y := 0. + self.button := 0. + } + + method x: x y: y button: button { self.x := x. self.y := y. + self.button := button. } } -class X11.MouseWheelEvent(X11.InputEvent) +class X11.MouseWheelEvent(X11.Event) { - dcl x y amount. + var x, y, amount. method x { ^self.x } method y { ^self.y } method amount { ^self.amount } + method initialize + { + self.x := 0. + self.y := 0. + self.amount := 0. + } + method x: x y: y amount: amount { self.x := x. @@ -127,13 +148,21 @@ class X11.MouseWheelEvent(X11.InputEvent) class X11.ExposeEvent(X11.Event) { - dcl x y width height. + var x, y, width, height. method x { ^self.x } method y { ^self.y } method width { ^self.width } method height { ^self.height } - + + method initialize + { + self.x := 0. + self.y := 0. + self.width := 0. + self.height := 0. + } + method x: x y: y width: width height: height { self.x := x. @@ -143,11 +172,6 @@ class X11.ExposeEvent(X11.Event) } } -class X11.WindowEvent(X11.Event) -{ - dcl width height. -} - ## --------------------------------------------------------------------------- ## Graphics Context ## --------------------------------------------------------------------------- @@ -163,7 +187,7 @@ pooldic X11.GCAttr class X11.GC(Object) from 'x11.gc' { - dcl window id. + var window, id. method(#primitive) _make (display, window). method(#primitive) _kill. @@ -215,7 +239,7 @@ class X11.GC(Object) from 'x11.gc' class X11.Component(Object) { - dcl parent. + var parent. method new { @@ -268,8 +292,8 @@ class X11.Canvas(Component) class X11.WindowedComponent(Component) from 'x11.win' { - dcl(#class) geom. - dcl wid bounds. + var(#class) geom. + var wid, bounds. method(#primitive) _get_window_dwatom. method(#primitive) _get_window_id. @@ -331,6 +355,11 @@ class X11.WindowedComponent(Component) from 'x11.win' } } + method cachedBounds + { + ^self.bounds + } + method bounds { self _get_window_geometry (self.bounds). @@ -374,7 +403,7 @@ class X11.WindowedComponent(Component) from 'x11.win' } method mousePressed: event { - ('MOUSE PRESSED' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString)) dump. + ('MOUSE PRESSED' & (self.wid asString) & ' ' & (event x asString) & ' ' & (event y asString) & ' ' & (event button asString)) dump. } method mouseReleased: event { @@ -388,7 +417,7 @@ class X11.WindowedComponent(Component) from 'x11.win' class X11.Container(WindowedComponent) { - dcl components. + var components. method initialize { @@ -417,7 +446,7 @@ class X11.Container(WindowedComponent) class X11.FrameWindow(Container) { - dcl display. + var display. method display { ^self.display } method display: display { self.display := display } @@ -528,6 +557,7 @@ extend X11 at: X11.LLEvent.ENTER_NOTIFY put: #__handle_notify:; at: X11.LLEvent.LEAVE_NOTIFY put: #__handle_notify:; at: X11.LLEvent.EXPOSE put: #__handle_expose:; + at: X11.LLEvent.DESTROY_NOTIFY put: #__handle_destroy_notify:; at: X11.LLEvent.CONFIGURE_NOTIFY put: #__handle_configure_notify:; at: X11.LLEvent.CLIENT_MESSAGE put: #__handle_client_message:. } @@ -583,12 +613,9 @@ extend X11 while ((event := self _get_event) notNil) { - ## XCB_EXPOSE 12 - ## XCB_DESTROY_WINDOW 4 -('EVENT================>' & event asString) dump. if (event isError) { - 'Error has occurred in ....' dump. + System logNl: ('Error while getting a event from display ' & self.cid asString). ongoing := false. break. } @@ -638,7 +665,6 @@ extend X11 } else { -('Performing ...' & mthname asString) dump. ^self perform (mthname, event). ##^self perform: mthname with: event. } @@ -698,6 +724,7 @@ extend X11 method __handle_button_event: event { (* + typedef uint8_t xcb_button_t; typedef struct xcb_button_press_event_t { uint8_t response_type; xcb_button_t detail; // uint8_t @@ -731,16 +758,10 @@ extend X11 detail := event getUint8(1). if (detail >= 1 and: [detail <= 3]) { - (* self.mouse_event - ## TODO: encode detail also.. - x: System _getUint16(event, 24) ## event_x - y: System _getUint16(event, 26). ## event_y - *) - self.mouse_event - ## TODO: encode detail also.. - x: event getUint16(24) ## event_x - y: event getUint16(26). ## event_y + x: event getUint16(24) ## event_x + y: event getUint16(26) ## event_y + button: detail. if (type == X11.LLEvent.BUTTON_PRESS) { @@ -755,12 +776,6 @@ extend X11 { if (type == X11.LLEvent.BUTTON_RELEASE) { - (* - self.mouse_wheel_event - x: System _getUint16(event, 24) ## event_x - y: System _getUint16(event, 26) ## event_y - amount: (if (detail == 4) { -1 } else { 1 }). - *) self.mouse_wheel_event x: event getUint16(24) ## event_x y: event getUint16(26) ## event_y @@ -775,6 +790,33 @@ extend X11 } } + method __handle_destroy_notify: event + { + (* + typedef struct xcb_destroy_notify_event_t { + uint8_t response_type; + uint8_t pad0; + uint16_t sequence; + xcb_window_t event; + xcb_window_t window; + } xcb_destroy_notify_event_t; + *) + + | wid window | + + wid := System _getUint32(event, 4). ## event + window := self.windows at: wid. + + if (window notError) + { + 'WINDOW DESTROYED....................' dump. + } + else + { + System logNl: ('Destroy notify event on unknown window - ' & wid asString). + } + } + method __handle_configure_notify: event { (* @@ -805,7 +847,7 @@ extend X11 { width := System _getUint16(event, 20). height := System _getUint16(event, 22). - bounds := window bounds. + bounds := window cachedBounds. ## old bounds before resizing. if (bounds width ~= width or: [bounds height ~= height]) { window windowResized }. } else @@ -844,7 +886,6 @@ extend X11 dw := event getUint32(12). ## data.data32[0] if (dw == window _get_window_dwatom) { - ## TODO: call close query callback??? window close. } @@ -914,9 +955,9 @@ class MyButton(X11.Button) class MyFrame(X11.FrameWindow) { - dcl gc. - dcl b1. - dcl b2. + var gc. + var b1. + var b2. method windowOpened { diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index d02224c..ebdf192 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -62,7 +62,7 @@ class MyObject(Object) ') expected' '] expected' '. expected' - ' expected' + ', expected' '| expected' '> expected' ':= expected' @@ -75,14 +75,15 @@ class MyObject(Object) 'contradictory class definition' 'wrong class name' 'non-pointer class inheriting superclass with trailer size set' - 'dcl not allowed' + 'variable declaration not allowed' 'modifier expected' 'wrong modifier' 'disallowed modifier' 'duplicate modifier' - 'wrong method name' + 'method name expected' 'duplicate method name' 'invalid variadic method definition' + 'variable name expected' 'duplicate argument name' 'duplicate temporary variable name' 'duplicate variable name' diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 2d0f518..66c0f47 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -56,7 +56,7 @@ enum class_mod_t enum var_type_t { /* NEVER Change the order and the value of 3 items below. - * moo->c->cls.vars and moo->c->cls.var_count relies on them. */ + * moo->c->cls.var relies on them. */ VAR_INSTANCE = 0, VAR_CLASS = 1, VAR_CLASSINST = 2, @@ -88,9 +88,10 @@ static struct voca_t { 5, { 'c','l','a','s','s' } }, { 6, { '#','c','l','a','s','s' } }, { 10, { '#','c','l','a','s','s','i','n','s','t' } }, + { 5, { 'c','o','n','s','t' } }, + { 8, { 'c','o','n','s','t','a','n','t' } }, { 8, { 'c','o','n','t','i','n','u','e' } }, { 3, { 'd','c','l' } }, - { 7, { 'd','e','c','l','a','r','e' } }, { 2, { 'd','o' } }, { 4, { 'e','l','s','e' } }, { 5, { 'e','l','s','i','f' } }, @@ -102,6 +103,7 @@ static struct voca_t { 4, { 'f','r','o','m' } }, { 9, { '#','h','a','l','f','w','o','r','d' } }, { 2, { 'i','f' } }, + { 6, { 'i','m','p','o','r','t' } }, { 8, { '#','i','n','c','l','u','d','e' } }, { 8, { '#','l','i','b','e','r','a','l' } }, { 7, { '#','l','i','w','o','r','d' } }, @@ -117,11 +119,15 @@ static struct voca_t { 11, { 't','h','i','s','C','o','n','t','e','x','t' } }, { 11, { 't','h','i','s','P','r','o','c','e','s','s' } }, { 4, { 't','r','u','e' } }, + { 3, { 'v','a','r' } }, + { 8, { 'v','a','r','i','a','b','l','e' } }, { 9, { '#','v','a','r','i','a','d','i','c' } }, { 5, { 'w','h','i','l','e' } }, { 5, { '#','w','o','r','d' } }, { 1, { '|' } }, + { 2, { '|','+' } }, + { 2, { '|','*' } }, { 1, { '>' } }, { 1, { '<' } }, @@ -136,9 +142,10 @@ enum voca_id_t VOCA_CLASS, VOCA_CLASS_S, VOCA_CLASSINST_S, + VOCA_CONST, + VOCA_CONSTANT, VOCA_CONTINUE, VOCA_DCL, - VOCA_DECLARE, VOCA_DO, VOCA_ELSE, VOCA_ELSIF, @@ -150,6 +157,7 @@ enum voca_id_t VOCA_FROM, VOCA_HALFWORD_S, VOCA_IF, + VOCA_IMPORT, VOCA_INCLUDE_S, VOCA_LIBERAL_S, VOCA_LIWORD_S, @@ -165,11 +173,15 @@ enum voca_id_t VOCA_THIS_CONTEXT, VOCA_THIS_PROCESS, VOCA_TRUE, + VOCA_VAR, + VOCA_VARIABLE, VOCA_VARIADIC_S, VOCA_WHILE, VOCA_WORD_S, VOCA_VBAR, + VOCA_VBAR_PLUS, + VOCA_VBAR_ASTER, VOCA_GT, VOCA_LT, @@ -181,6 +193,7 @@ static int compile_block_statement (moo_t* moo); static int compile_method_statement (moo_t* moo); static int compile_method_expression (moo_t* moo, int pop); static int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index); +static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly); static MOO_INLINE int is_spacechar (moo_ooci_t c) { @@ -325,11 +338,13 @@ static int is_restricted_word (const moo_oocs_t* ucs) { VOCA_CLASS, VOCA_DCL, - VOCA_DECLARE, VOCA_EXTEND, + VOCA_FROM, + VOCA_IMPORT, VOCA_METHOD, VOCA_POOLDIC, - VOCA_FROM + VOCA_VAR, + VOCA_VARIABLE }; int i; @@ -2510,20 +2525,45 @@ static MOO_INLINE int set_class_modname (moo_t* moo, const moo_oocs_t* name) return 0; } -static MOO_INLINE int add_class_level_variable (moo_t* moo, var_type_t index, const moo_oocs_t* name) +static MOO_INLINE int add_class_level_variable (moo_t* moo, var_type_t var_type, const moo_oocs_t* name) { int n; - n = copy_string_to (moo, name, &moo->c->cls.vars[index], &moo->c->cls.vars_capa[index], 1, ' '); + n = copy_string_to (moo, name, &moo->c->cls.var[var_type].str, &moo->c->cls.var[var_type].str_capa, 1, ' '); if (n >= 0) { - moo->c->cls.var_count[index]++; + moo->c->cls.var[var_type].count++; + moo->c->cls.var[var_type].total_count++; /* TODO: check if it exceeds MOO_MAX_NAMED_INSTVARS, MOO_MAX_CLASSVARS, MOO_MAX_CLASSINSTVARS */ } return n; } +static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_oow_t var_index, moo_oop_t initv) +{ + if (var_index >= moo->c->cls.var[var_type].initv_capa) + { + moo_oow_t newcapa, i; + moo_oop_t* tmp; + + newcapa = MOO_ALIGN_POW2 ((var_index + 1), 32); + tmp = moo_reallocmem (moo, moo->c->cls.var[var_type].initv, newcapa * MOO_SIZEOF(moo_oop_t)); + if (!tmp) return -1; + + for (i = moo->c->cls.var[var_type].initv_capa; i < newcapa; i++) tmp[i] = moo->_nil; + + moo->c->cls.var[var_type].initv = tmp; + moo->c->cls.var[var_type].initv_capa = newcapa; + } + + if (var_index >= moo->c->cls.var[var_type].initv_count) + moo->c->cls.var[var_type].initv_count = var_index + 1; + + moo->c->cls.var[var_type].initv[var_index] = initv; + return 0; +} + static MOO_INLINE int add_pool_dictionary (moo_t* moo, const moo_oocs_t* name, moo_oop_set_t pooldic_oop) { if (moo->c->cls.pooldic_count >= moo->c->cls.pooldic_imp_oops_capa) @@ -2593,7 +2633,7 @@ static moo_ooi_t find_class_level_variable (moo_t* moo, moo_oop_class_t self, co * find the variable in the compiler's own list */ for (index = VAR_INSTANCE; index <= VAR_CLASSINST; index++) { - if (find_word_in_string(&moo->c->cls.vars[index], name, &pos) >= 0) + if (find_word_in_string(&moo->c->cls.var[index].str, name, &pos) >= 0) { super = moo->c->cls.super_oop; var->cls = self; @@ -2736,11 +2776,7 @@ static int add_method_name_fragment (moo_t* moo, const moo_oocs_t* name) static int method_exists (moo_t* moo, const moo_oocs_t* name) { /* check if the current class contains a method of the given name */ -#ifdef MTHDIC - return moo_lookupdic (moo, moo->c->cls.mthdic_oop[moo->c->mth.type], name) != MOO_NULL; -#else return moo_lookupdic (moo, moo->c->cls.self_oop->mthdic[moo->c->mth.type], name) != MOO_NULL; -#endif } static int add_temporary_variable (moo_t* moo, const moo_oocs_t* name) @@ -3008,36 +3044,119 @@ static int import_pool_dictionary (moo_t* moo, moo_oop_set_t ns_oop, const moo_o return 0; } +static int compile_class_level_variables_vbar (moo_t* moo, var_type_t dcl_type) +{ + /* class level variable declaration using vbar. + * - no assignment of a default value is allowed + * - same syntax as local variable declaration within a method */ + do + { + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + var_info_t var; +/* +TODO: more check on variability conflict. +if it's a indexed class, check if the superclass is fixed or index. +if super is fixed and self is fixed or variable-pointer, no restriction. +if super is fixed and self is variable-nonpointer, no instance varaible in the super side and in the self side. +if super is variable-pointer, self must be a variable-pointer. can't be fixed either +if super is variable-nonpointer, self must be a variable-nonpointer of the same type. can't be fixed either +if super is variable-nonpointer, no instance variable is allowed. +*/ + if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) + { + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || + moo_lookupdic (moo, moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ + moo_lookupdic (moo, moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ + { + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (add_class_level_variable(moo, dcl_type, TOKEN_NAME(moo)) <= -1) return -1; + } + else + { + break; + } + + GET_TOKEN (moo); + } + while (1); + + if (!is_token_binary_selector(moo, VOCA_VBAR)) + { + set_syntax_error (moo, MOO_SYNERR_VBAR, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); + return 0; +} + static int compile_class_level_variables (moo_t* moo) { var_type_t dcl_type = VAR_INSTANCE; if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) { - /* process variable modifiers */ + /* process variable declaration modifiers */ GET_TOKEN (moo); - if (is_token_symbol(moo, VOCA_CLASS_S)) + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) { - /* dcl(#class) */ - dcl_type = VAR_CLASS; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_CLASSINST_S)) - { - /* dcl(#classinst) */ - dcl_type = VAR_CLASSINST; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_POOLDIC_S)) - { - /* dcl(#pooldic) - import a pool dictionary */ - dcl_type = VAR_GLOBAL; /* this is not a real type. used for branching below */ - GET_TOKEN (moo); + do + { + if (is_token_symbol(moo, VOCA_CLASS_S)) + { + /* variable(#class) */ + if (dcl_type != VAR_INSTANCE) + { + set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + dcl_type = VAR_CLASS; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_CLASSINST_S)) + { + /* variable(#classinst) */ + if (dcl_type != VAR_INSTANCE) + { + set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + dcl_type = VAR_CLASSINST; + GET_TOKEN (moo); + } + else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + /* no modifier is present */ + set_syntax_error (moo, MOO_SYNERR_MODIFIER, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else + { + /* invalid modifier */ + set_syntax_error (moo, MOO_SYNERR_MODIFIERINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully ) */ + GET_TOKEN (moo); /* get the token after , */ + } + while (1); } if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) { + /* ) expected */ set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); return -1; } @@ -3045,40 +3164,12 @@ static int compile_class_level_variables (moo_t* moo) GET_TOKEN (moo); } - if (dcl_type == VAR_GLOBAL) + /* variable declaration */ + do { - /* pool dictionary import declaration - * dcl(#pooldic) ... */ - moo_oocs_t last; - moo_oop_set_t ns_oop; - - do + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) { - if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) - { - if (preprocess_dotted_name(moo, 0, MOO_NULL, TOKEN_NAME(moo), TOKEN_LOC(moo), &last, &ns_oop) <= -1) return -1; - } - else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) - { - last = moo->c->tok.name; - /* it falls back to the name space of the class */ - ns_oop = moo->c->cls.ns_oop; - } - else break; - - if (import_pool_dictionary(moo, ns_oop, &last, TOKEN_NAME(moo), TOKEN_LOC(moo)) <= -1) return -1; - GET_TOKEN (moo); - } - while (1); - } - else - { - /* variable declaration */ - do - { - if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) - { - var_info_t var; + var_info_t var; /* TODO: more check on variability conflict. @@ -3089,31 +3180,158 @@ if super is variable-pointer, self must be a variable-pointer. can't be fixed ei if super is variable-nonpointer, self must be a variable-nonpointer of the same type. can't be fixed either if super is variable-nonpointer, no instance variable is allowed. */ - if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) - { - set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } - - if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || - moo_lookupdic (moo, moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ - moo_lookupdic (moo, moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ - { - set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } - - if (add_class_level_variable(moo, dcl_type, TOKEN_NAME(moo)) <= -1) return -1; - } - else + if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) { - break; + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; } + if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || + moo_lookupdic (moo, moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ + moo_lookupdic (moo, moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ + { + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (add_class_level_variable(moo, dcl_type, TOKEN_NAME(moo)) <= -1) return -1; + GET_TOKEN (moo); + + if (TOKEN_TYPE(moo) == MOO_IOTOK_ASSIGN) + { + moo_oop_t lit; + + GET_TOKEN (moo); + + /* default value assignment. only a literal is allowed */ + #if defined(MOO_SIMPLE_INITV) + lit = token_to_literal (moo, 1); + #else + lit = token_to_literal (moo, 0); + #endif + if (!lit) return -1; + + /* set the initial value for the variable added above */ + if (set_class_level_variable_initv (moo, dcl_type, moo->c->cls.var[dcl_type].count - 1, lit) <= -1) return -1; + + GET_TOKEN (moo); + } } - while (1); + else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD) + { + /* no variable name is present */ + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else + { + break; + } + + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + set_syntax_error (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully . */ + GET_TOKEN (moo); } + while (1); + + if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) + { + set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); + return 0; +} + +static int compile_class_level_imports (moo_t* moo) +{ + /* pool dictionary import declaration + * import ... */ + + moo_oocs_t last; + moo_oop_set_t ns_oop; + + if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) + { + /* process import declaration modifiers */ + GET_TOKEN (moo); + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + do + { + #if 0 + /* TODO: do i need any modifier for import declaration? + * import(#pooldic) - import a pool dictionary specifically? + * import(#xxxxx) - to do what??? + */ + if (is_token_symbol(moo, VOCA_POOLDIC_S)) + { + /* import(#pooldic) - import a pool dictionary */ + if (dcl_type != IMPORT_POOLDIC) + { + set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + dcl_type = IMPORT_POOLDIC; + GET_TOKEN (moo); + } + else + #endif + if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + /* no modifier is present */ + set_syntax_error (moo, MOO_SYNERR_MODIFIER, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else + { + /* invalid modifier */ + set_syntax_error (moo, MOO_SYNERR_MODIFIERINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully ) */ + GET_TOKEN (moo); /* get the token after , */ + } + while (1); + } + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + /* ) expected */ + set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); + } + + do + { + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) + { + if (preprocess_dotted_name(moo, 0, MOO_NULL, TOKEN_NAME(moo), TOKEN_LOC(moo), &last, &ns_oop) <= -1) return -1; + } + else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + last = moo->c->tok.name; + /* it falls back to the name space of the class */ + ns_oop = moo->c->cls.ns_oop; + } + else break; + + if (import_pool_dictionary(moo, ns_oop, &last, TOKEN_NAME(moo), TOKEN_LOC(moo)) <= -1) return -1; + GET_TOKEN (moo); + } + while (1); if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) { @@ -3593,7 +3811,7 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo break; case VAR_CLASS: - /* a class variable can be access by both instance methods and class methods */ + /* a class variable can be accessed by both instance methods and class methods */ MOO_ASSERT (moo, var->cls != MOO_NULL); MOO_ASSERT (moo, MOO_CLASSOF(moo, var->cls) == moo->_class); @@ -4015,70 +4233,9 @@ static int __read_array_literal (moo_t* moo, moo_oop_t* xlit) do { + /* NOTE: see token_to_literal() for analogous code */ switch (TOKEN_TYPE(moo)) { -/* TODO: floating pointer number */ - - case MOO_IOTOK_NUMLIT: - case MOO_IOTOK_RADNUMLIT: - lit = string_to_num (moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT); - break; - - case MOO_IOTOK_CHARLIT: - MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); - lit = MOO_CHAR_TO_OOP(TOKEN_NAME_PTR(moo)[0]); - break; - - case MOO_IOTOK_STRLIT: - lit = moo_instantiate (moo, moo->_string, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - break; - - case MOO_IOTOK_SYMLIT: - lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1); - break; - -/* - case MOO_IOTOK_IDENT: - case MOO_IOTOK_IDENT_DOTTED: - case MOO_IOTOK_BINSEL: - case MOO_IOTOK_KEYWORD: - case MOO_IOTOK_SELF: - case MOO_IOTOK_SUPER: - case MOO_IOTOK_THIS_CONTEXT: - case MOO_IOTOK_THIS_PROCESS: - case MOO_IOTOK_DO: - case MOO_IOTOK_WHILE: - case MOO_IOTOK_BREAK: - case MOO_IOTOK_CONTINUE: - case MOO_IOTOK_IF: - case MOO_IOTOK_ELSE: - case MOO_IOTOK_ELSIF: - lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - break; -*/ -/* -a := #(1 2 3 self 5) -a := #(1 2 3 #(1 2 3) self) - -a := #(1, 2, 3, self, 5) <---- is array constant? is array non constant? -if array constant contains a comma, produce MAKE_ARRAY -if array literal contains no comma, it's just a literal array. -what to do with a single element array? no problem if the element is still a literal. -should i allow expression or something like that here??? - -#(( abc )) - -#(1, 2) -* - -make array 10. -push 10 -put array at 1. -push 20 -put array at 2 -if index is too large, switch to at:put? (or don't care as it's too large???). -*/ - case MOO_IOTOK_NIL: lit = moo->_nil; break; @@ -4099,8 +4256,31 @@ if index is too large, switch to at:put? (or don't care as it's too large???). lit = string_to_error (moo, TOKEN_NAME(moo)); break; + case MOO_IOTOK_CHARLIT: + MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); + lit = MOO_CHAR_TO_OOP(TOKEN_NAME_PTR(moo)[0]); + break; + +/* TODO: floating pointer number */ + case MOO_IOTOK_NUMLIT: + case MOO_IOTOK_RADNUMLIT: + lit = string_to_num (moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT); + break; + + case MOO_IOTOK_SYMLIT: + lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1); + break; + + case MOO_IOTOK_STRLIT: + lit = moo_instantiate (moo, moo->_string, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); + break; + + case MOO_IOTOK_BABRACK: /* #[ */ + GET_TOKEN (moo); + if (__read_byte_array_literal (moo, &lit) <= -1) return -1; + break; + case MOO_IOTOK_APAREN: /* #( */ - /*case MOO_IOTOK_LPAREN:*/ /* ( */ saved_arlit_count = moo->c->mth.arlit_count; /* TODO: get rid of recursion?? */ GET_TOKEN (moo); @@ -4108,12 +4288,6 @@ if index is too large, switch to at:put? (or don't care as it's too large???). moo->c->mth.arlit_count = saved_arlit_count; break; - case MOO_IOTOK_BABRACK: /* #[ */ - /*case MOO_IOTOK_LBRACK:*/ /* [ */ - GET_TOKEN (moo); - if (__read_byte_array_literal (moo, &lit) <= -1) return -1; - break; - default: goto done; } @@ -4452,18 +4626,6 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons GET_TOKEN (moo); break; - case MOO_IOTOK_STRLIT: - if (add_string_literal(moo, TOKEN_NAME(moo), &index) <= -1 || - emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1; - GET_TOKEN (moo); - break; - - case MOO_IOTOK_SYMLIT: - if (add_symbol_literal(moo, TOKEN_NAME(moo), 1, &index) <= -1 || - emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1; - GET_TOKEN (moo); - break; - case MOO_IOTOK_NUMLIT: case MOO_IOTOK_RADNUMLIT: { @@ -4488,6 +4650,18 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons break; } + case MOO_IOTOK_SYMLIT: + if (add_symbol_literal(moo, TOKEN_NAME(moo), 1, &index) <= -1 || + emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1; + GET_TOKEN (moo); + break; + + case MOO_IOTOK_STRLIT: + if (add_string_literal(moo, TOKEN_NAME(moo), &index) <= -1 || + emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1; + GET_TOKEN (moo); + break; + case MOO_IOTOK_BABRACK: /* #[ */ /*GET_TOKEN (moo);*/ if (compile_byte_array_literal(moo) <= -1) return -1; @@ -5784,11 +5958,7 @@ need to write code to collect string. moo_poptmps (moo, tmp_count); tmp_count = 0; -#ifdef MTHDIC - if (!moo_putatdic(moo, moo->c->cls.mthdic_oop[moo->c->mth.type], (moo_oop_t)name, (moo_oop_t)mth)) goto oops; -#else if (!moo_putatdic(moo, moo->c->cls.self_oop->mthdic[moo->c->mth.type], (moo_oop_t)name, (moo_oop_t)mth)) goto oops; -#endif return 0; @@ -6057,12 +6227,12 @@ static int make_defined_class (moo_t* moo) moo_oow_t spec, self_spec; int just_made = 0; - spec = MOO_CLASS_SPEC_MAKE (moo->c->cls.var_count[VAR_INSTANCE], - ((moo->c->cls.flags & CLASS_INDEXED)? 1: 0), - moo->c->cls.indexed_type); + spec = MOO_CLASS_SPEC_MAKE (moo->c->cls.var[VAR_INSTANCE].total_count, + ((moo->c->cls.flags & CLASS_INDEXED)? 1: 0), + moo->c->cls.indexed_type); - self_spec = MOO_CLASS_SELFSPEC_MAKE (moo->c->cls.var_count[VAR_CLASS], - moo->c->cls.var_count[VAR_CLASSINST]); + self_spec = MOO_CLASS_SELFSPEC_MAKE (moo->c->cls.var[VAR_CLASS].total_count, + moo->c->cls.var[VAR_CLASSINST].total_count); if (moo->c->cls.self_oop) { @@ -6084,7 +6254,7 @@ static int make_defined_class (moo_t* moo) /* the class variables and class instance variables are placed * inside the class object after the fixed part. */ tmp = moo_instantiate (moo, moo->_class, MOO_NULL, - moo->c->cls.var_count[VAR_CLASSINST] + moo->c->cls.var_count[VAR_CLASS]); + moo->c->cls.var[VAR_CLASSINST].total_count + moo->c->cls.var[VAR_CLASS].total_count); if (!tmp) return -1; just_made = 1; @@ -6115,15 +6285,15 @@ static int make_defined_class (moo_t* moo) moo->c->cls.self_oop->modname = tmp; } - tmp = moo_makestring (moo, moo->c->cls.vars[VAR_INSTANCE].ptr, moo->c->cls.vars[VAR_INSTANCE].len); + tmp = moo_makestring (moo, moo->c->cls.var[VAR_INSTANCE].str.ptr, moo->c->cls.var[VAR_INSTANCE].str.len); if (!tmp) return -1; moo->c->cls.self_oop->instvars = (moo_oop_char_t)tmp; - tmp = moo_makestring (moo, moo->c->cls.vars[VAR_CLASS].ptr, moo->c->cls.vars[VAR_CLASS].len); + tmp = moo_makestring (moo, moo->c->cls.var[VAR_CLASS].str.ptr, moo->c->cls.var[VAR_CLASS].str.len); if (!tmp) return -1; moo->c->cls.self_oop->classvars = (moo_oop_char_t)tmp; - tmp = moo_makestring (moo, moo->c->cls.vars[VAR_CLASSINST].ptr, moo->c->cls.vars[VAR_CLASSINST].len); + tmp = moo_makestring (moo, moo->c->cls.var[VAR_CLASSINST].str.ptr, moo->c->cls.var[VAR_CLASSINST].str.len); if (!tmp) return -1; moo->c->cls.self_oop->classinstvars = (moo_oop_char_t)tmp; @@ -6134,22 +6304,32 @@ static int make_defined_class (moo_t* moo) /* TOOD: good dictionary size */ tmp = (moo_oop_t)moo_makedic (moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; -#ifdef MTHDIC - moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE] = (moo_oop_set_t)tmp; -#else moo->c->cls.self_oop->mthdic[MOO_METHOD_INSTANCE] = (moo_oop_set_t)tmp; -#endif /* TOOD: good dictionary size */ tmp = (moo_oop_t)moo_makedic (moo, moo->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; -#ifdef MTHDIC - moo->c->cls.mthdic_oop[MOO_METHOD_CLASS] = (moo_oop_set_t)tmp; -#else moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_set_t)tmp; + +#if 0 + if (moo->c->cls.var[VAR_INSTANCE].initv_total_count > 0) + { + moo_oow_t i; + + tmp = moo_instantiate (moo, moo->_array, MOO_NULL, moo->c->cls.var[VAR_INSTANCE].total_count); + if (!tmp) return -1; + for (i = 0; i < moo->c->cls.var[VAR_INSTANCE].initv_count; i++) + { + ((moo_oop_oop_t)tmp)->slot[i] = moo->c->cls.var[VAR_INSTANCE].initv[i]; + } + + moo->c->cls. + } #endif - /* [NOTE] don't create a dictionary on the nsdic. keep it to be nil */ + /* [NOTE] don't create a dictionary on the nsdic. keep it to be nil. + * add_nsdic_to_class() instantiates a dictionary if necessary. */ + /* [NOTE] don't set the trsize field yet here. */ /* TODO: initialize more fields??? whatelse. */ @@ -6175,7 +6355,8 @@ static int __compile_class_definition (moo_t* moo, int extend) * class-body := "{" variable-definition* method-definition* "}" * class-module-import := from "module-name-string" * - * variable-definition := (#dcl | #declare) variable-modifier? variable-list "." + * TOOD: add | |, |+ |, |* | + * variable-definition := (#var | #variable) variable-modifier? variable-list "." * variable-modifier := "(" (#class | #classinst)? ")" * variable-list := identifier* * @@ -6313,55 +6494,54 @@ static int __compile_class_definition (moo_t* moo, int extend) MOO_INFO2 (moo, "Defining a class %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr); - if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) + if (TOKEN_TYPE(moo) != MOO_IOTOK_LPAREN) { - /* superclass is specified. new class defintion. - * for example, #class Class(Stix) - */ - GET_TOKEN (moo); /* read superclass name */ - - /* TODO: multiple inheritance */ - - if (TOKEN_TYPE(moo) == MOO_IOTOK_NIL) - { - super_is_nil = 1; - } - else if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && - TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED) - { - /* superclass name expected */ - set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } - - if (set_superclass_fqn(moo, TOKEN_NAME(moo)) <= -1) return -1; - moo->c->cls.superfqn_loc = moo->c->tok.loc; - - if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) - { - if (preprocess_dotted_name(moo, PDN_DONT_ADD_NS, MOO_NULL, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, &moo->c->cls.supername, &moo->c->cls.superns_oop) <= -1) return -1; - } - else - { - /* if no fully qualified name is specified for the super class name, - * the name is searched in the name space that the class being defined - * belongs to first and in the 'moo->sysdic'. */ - moo->c->cls.superns_oop = moo->c->cls.ns_oop; - } - - GET_TOKEN (moo); - if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) - { - set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } - - GET_TOKEN (moo); + set_syntax_error (moo, MOO_SYNERR_LPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; } - else + + /* superclass is specified. new class defintion. + * for example, #class Class(Stix) + */ + GET_TOKEN (moo); /* read superclass name */ + + /* TODO: multiple inheritance */ + + if (TOKEN_TYPE(moo) == MOO_IOTOK_NIL) { super_is_nil = 1; } + else if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && + TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED) + { + /* superclass name expected */ + set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (set_superclass_fqn(moo, TOKEN_NAME(moo)) <= -1) return -1; + moo->c->cls.superfqn_loc = moo->c->tok.loc; + + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) + { + if (preprocess_dotted_name(moo, PDN_DONT_ADD_NS, MOO_NULL, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, &moo->c->cls.supername, &moo->c->cls.superns_oop) <= -1) return -1; + } + else + { + /* if no fully qualified name is specified for the super class name, + * the name is searched in the name space that the class being defined + * belongs to first and in the 'moo->sysdic'. */ + moo->c->cls.superns_oop = moo->c->cls.ns_oop; + } + + GET_TOKEN (moo); + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); /*ass = moo_lookupsysdic(moo, &moo->c->cls.name);*/ ass = moo_lookupdic (moo, moo->c->cls.ns_oop, &moo->c->cls.name); @@ -6473,8 +6653,20 @@ static int __compile_class_definition (moo_t* moo, int extend) c = (moo_oop_class_t)moo->c->cls.super_oop; spec = MOO_OOP_TO_SMOOI(c->spec); self_spec = MOO_OOP_TO_SMOOI(c->selfspec); - moo->c->cls.var_count[VAR_INSTANCE] = MOO_CLASS_SPEC_NAMED_INSTVAR(spec); - moo->c->cls.var_count[VAR_CLASSINST] = MOO_CLASS_SELFSPEC_CLASSINSTVAR(self_spec); + + /* [NOTE] class variables are not inherited. + * so no data about them are not transferred over */ + + moo->c->cls.var[VAR_INSTANCE].total_count = MOO_CLASS_SPEC_NAMED_INSTVAR(spec); + moo->c->cls.var[VAR_CLASSINST].total_count = MOO_CLASS_SELFSPEC_CLASSINSTVAR(self_spec); + + if (c->initv != moo->_nil) + { + MOO_ASSERT (moo, MOO_CLASSOF(moo, c->initv) == moo->_array); + moo->c->cls.var[VAR_INSTANCE].initv_total_count = MOO_OBJ_GET_SIZE(c->initv); + } + + /*TODO: moo->c->cls.var[VAR_CLASSINST].total_initv_count = */ } GET_TOKEN (moo); @@ -6484,18 +6676,12 @@ static int __compile_class_definition (moo_t* moo, int extend) moo_oop_char_t pds; /* when a class is extended, a new variable cannot be added */ - if (is_token_word(moo, VOCA_DCL) || is_token_word(moo, VOCA_DECLARE)) + if (is_token_word(moo, VOCA_DCL) || is_token_word(moo, VOCA_VAR) || is_token_word(moo, VOCA_VARIABLE)) { - set_syntax_error (moo, MOO_SYNERR_DCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo)); + set_syntax_error (moo, MOO_SYNERR_VARDCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo)); return -1; } -#ifdef MTHDIC - /* use the method dictionary of an existing class object */ - moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE] = moo->c->cls.self_oop->mthdic[MOO_METHOD_INSTANCE]; - moo->c->cls.mthdic_oop[MOO_METHOD_CLASS] = moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS]; -#endif - /* load the pooldic definition from the existing class object */ pds = moo->c->cls.self_oop->pooldics; if ((moo_oop_t)pds != moo->_nil) @@ -6550,12 +6736,41 @@ static int __compile_class_definition (moo_t* moo, int extend) { /* a new class including an internally defined class object */ - while (is_token_word(moo, VOCA_DCL) || is_token_word(moo, VOCA_DECLARE)) + do { - /* variable definition. dcl or declare */ - GET_TOKEN (moo); - if (compile_class_level_variables(moo) <= -1) return -1; + if (is_token_binary_selector(moo, VOCA_VBAR)) + { + /* instance variables | a b c | */ + GET_TOKEN (moo); + if (compile_class_level_variables_vbar(moo, VAR_INSTANCE) <= -1) return -1; + } + else if (is_token_binary_selector(moo, VOCA_VBAR_PLUS)) + { + /* class variables |+ a b c | */ + GET_TOKEN (moo); + if (compile_class_level_variables_vbar(moo, VAR_CLASS) <= -1) return -1; + } + else if (is_token_binary_selector(moo, VOCA_VBAR_ASTER)) + { + /* class instance variables |* a b c | */ + GET_TOKEN (moo); + if (compile_class_level_variables_vbar(moo, VAR_CLASSINST) <= -1) return -1; + } + else if (is_token_word(moo, VOCA_DCL) || is_token_word(moo, VOCA_VAR) || is_token_word(moo, VOCA_VARIABLE)) + { + /* variable declaration */ + GET_TOKEN (moo); + if (compile_class_level_variables(moo) <= -1) return -1; + } + else if (is_token_word(moo, VOCA_IMPORT)) + { + /* import declaration */ + GET_TOKEN (moo); + if (compile_class_level_imports(moo) <= -1) return -1; + } + else break; } + while (1); if (make_defined_class(moo) <= -1) return -1; @@ -6595,16 +6810,6 @@ static int __compile_class_definition (moo_t* moo, int extend) return -1; } -#ifdef MTHDIC - if (!extend) - { - /* link the method dictionaries created to the actual class object */ -/* TODO: anything else to set? */ - moo->c->cls.self_oop->mthdic[MOO_CLASS_MTHDIC_INSTANCE] = moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE]; - moo->c->cls.self_oop->mthdic[MOO_CLASS_MTHDIC_CLASS] = moo->c->cls.mthdic_oop[MOO_METHOD_CLASS]; - } -#endif - GET_TOKEN (moo); return 0; } @@ -6612,7 +6817,7 @@ static int __compile_class_definition (moo_t* moo, int extend) static int compile_class_definition (moo_t* moo, int extend) { int n; - moo_oow_t i; + moo_oow_t i, j; /* reset the structure to hold information about a class to be compiled */ moo->c->cls.flags = 0; @@ -6627,11 +6832,19 @@ static int compile_class_definition (moo_t* moo, int extend) moo->c->cls.modname.len = 0; - MOO_ASSERT (moo, MOO_COUNTOF(moo->c->cls.var_count) == MOO_COUNTOF(moo->c->cls.vars)); - for (i = 0; i < MOO_COUNTOF(moo->c->cls.var_count); i++) + for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) { - moo->c->cls.var_count[i] = 0; - moo->c->cls.vars[i].len = 0; + moo->c->cls.var[i].str.len = 0; + + moo->c->cls.var[i].count = 0; + moo->c->cls.var[i].total_count = 0; + moo->c->cls.var[i].initv_count = 0; + moo->c->cls.var[i].initv_total_count = 0; + + /* this reinitialization is needed because set_class_level_variable_initv() + * doesn't fill the gap between the last inserted item and the new item inserted */ + for (j = 0; j < moo->c->cls.var[i].initv_capa; j++) + moo->c->cls.var[i].initv[j] = moo->_nil; } moo->c->cls.pooldic_count = 0; @@ -6639,10 +6852,6 @@ static int compile_class_definition (moo_t* moo, int extend) moo->c->cls.self_oop = MOO_NULL; moo->c->cls.super_oop = MOO_NULL; -#ifdef MTHDIC - moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE] = MOO_NULL; - moo->c->cls.mthdic_oop[MOO_METHOD_CLASS] = MOO_NULL; -#endif moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; moo->c->mth.literal_count = 0; @@ -6652,24 +6861,119 @@ static int compile_class_definition (moo_t* moo, int extend) /* do main compilation work */ n = __compile_class_definition (moo, extend); - /* reset these oops plus literal pointers not to confuse gc_compiler() */ + /* reset these oops plus literal pointers to lessen load on gc_compiler(). + * it doesn't need to rescue items not needed any longer. */ moo->c->cls.self_oop = MOO_NULL; moo->c->cls.super_oop = MOO_NULL; -#ifdef MTHDIC - moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE] = MOO_NULL; - moo->c->cls.mthdic_oop[MOO_METHOD_CLASS] = MOO_NULL; -#endif moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; moo->c->mth.literal_count = 0; moo->c->mth.balit_count = 0; moo->c->mth.arlit_count = 0; + for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) + { + moo->c->cls.var[i].initv_count = 0; + } moo->c->cls.pooldic_count = 0; return n; } +static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) +{ + /* NOTE: see __read_array_literal() for analogous code */ + + switch (TOKEN_TYPE(moo)) + { + case MOO_IOTOK_NIL: + return moo->_nil; + + case MOO_IOTOK_TRUE: + return moo->_true; + + case MOO_IOTOK_FALSE: + return moo->_false; + + case MOO_IOTOK_ERROR: + return MOO_ERROR_TO_OOP(MOO_EGENERIC); + + case MOO_IOTOK_ERRLIT: + return string_to_error (moo, TOKEN_NAME(moo)); + + case MOO_IOTOK_CHARLIT: + MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); + return MOO_CHAR_TO_OOP(TOKEN_NAME_PTR(moo)[0]); + + case MOO_IOTOK_NUMLIT: + case MOO_IOTOK_RADNUMLIT: + { + moo_oop_t lit; + lit = string_to_num (moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT); + if (rdonly && lit && MOO_OOP_IS_POINTER(lit)) MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); + return lit; + } + + case MOO_IOTOK_SYMLIT: + { + moo_oop_t lit; + lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1); + if (rdonly && lit) + { + MOO_ASSERT (moo, MOO_OOP_IS_POINTER(lit)); + MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); + } + } + + case MOO_IOTOK_STRLIT: + { + moo_oop_t lit; + lit = moo_instantiate (moo, moo->_string, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); + if (rdonly && lit) + { + MOO_ASSERT (moo, MOO_OOP_IS_POINTER(lit)); + MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); + } + return lit; + } + + case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */ + { + moo_oop_t lit; + if (read_byte_array_literal(moo, &lit) <= -1) return MOO_NULL; + if (rdonly) + { + MOO_ASSERT (moo, lit && MOO_OOP_IS_POINTER(lit)); + MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); + } + return lit; + } + + case MOO_IOTOK_APAREN: /* #( - array literal parenthesis */ + { + moo_oop_t lit; + if (read_array_literal(moo, &lit) <= -1) return MOO_NULL; + if (rdonly) + { +/* TODO: set inner elements of array to RDONLY as well */ + MOO_ASSERT (moo, lit && MOO_OOP_IS_POINTER(lit)); + MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); + } + return lit; + } + +#if 0 +/* TODO: if a constant name like a pooldic element is specified */ + case MOO_IOTOK_IDENT: + case MOO_IOTOK_IDENT_DOTTED: +#endif + + default: + set_syntax_error (moo, MOO_SYNERR_LITERAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return MOO_NULL; + } +} + static int __compile_pooldic_definition (moo_t* moo) { moo_oop_t lit; @@ -6731,69 +7035,17 @@ static int __compile_pooldic_definition (moo_t* moo) GET_TOKEN (moo); - switch (TOKEN_TYPE(moo)) - { - case MOO_IOTOK_NIL: - lit = moo->_nil; - goto add_literal; + #if defined(MOO_SIMPLE_INITV) + lit = token_to_literal (moo, 1); + #else + lit = token_to_literal (moo, 0); + #endif + if (!lit) return -1; - case MOO_IOTOK_TRUE: - lit = moo->_true; - goto add_literal; - - case MOO_IOTOK_FALSE: - lit = moo->_false; - goto add_literal; - - case MOO_IOTOK_ERROR: - lit = MOO_ERROR_TO_OOP(MOO_EGENERIC); - goto add_literal; - - case MOO_IOTOK_ERRLIT: - lit = string_to_error (moo, TOKEN_NAME(moo)); - goto add_literal; - - case MOO_IOTOK_CHARLIT: - MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); - lit = MOO_CHAR_TO_OOP(TOKEN_NAME_PTR(moo)[0]); - goto add_literal; - - case MOO_IOTOK_STRLIT: - lit = moo_instantiate (moo, moo->_string, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - if (!lit) return -1; - goto add_literal; - - case MOO_IOTOK_SYMLIT: - lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1); - if (!lit) return -1; - goto add_literal; - - case MOO_IOTOK_NUMLIT: - case MOO_IOTOK_RADNUMLIT: - lit = string_to_num (moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT); - if (!lit) return -1; - goto add_literal; - - case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */ - if (read_byte_array_literal(moo, &lit) <= -1) return -1; - goto add_literal; - - case MOO_IOTOK_APAREN: /* #( - array literal parenthesis */ - if (read_array_literal(moo, &lit) <= -1) return -1; - goto add_literal; - - add_literal: - /* - * for this definition, #pooldic MyPoolDic { #a := 10. #b := 20 }, - * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ - if (add_to_array_literal_buffer(moo, lit) <= -1) return -1; - GET_TOKEN (moo); - break; - - default: - set_syntax_error (moo, MOO_SYNERR_LITERAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } + /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, + * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ + if (add_to_array_literal_buffer(moo, lit) <= -1) return -1; + GET_TOKEN (moo); /*if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) goto done; else*/ if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) @@ -6819,8 +7071,6 @@ static int __compile_pooldic_definition (moo_t* moo) /*TODO: tally and arlit_count range check */ /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ - /* i use mthdic_oop[0] when compling #pooldic. it's not a real method dictionary. - * i just use it to avoid declaring another field into the compiler */ moo->c->cls.pooldic_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); if (!moo->c->cls.pooldic_oop) return -1; @@ -6919,7 +7169,7 @@ static void gc_compiler (moo_t* moo) /* called when garbage collection is performed */ if (moo->c) { - moo_oow_t i; + moo_oow_t i, j; if (moo->c->cls.self_oop) moo->c->cls.self_oop = (moo_oop_class_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.self_oop); @@ -6927,26 +7177,37 @@ static void gc_compiler (moo_t* moo) if (moo->c->cls.super_oop) moo->c->cls.super_oop = moo_moveoop (moo, moo->c->cls.super_oop); -#ifdef MTHDIC - if (moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE]) - moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE] = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.mthdic_oop[MOO_METHOD_INSTANCE]); - - if (moo->c->cls.mthdic_oop[MOO_METHOD_CLASS]) - moo->c->cls.mthdic_oop[MOO_METHOD_CLASS] = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.mthdic_oop[MOO_METHOD_CLASS]); -#endif + for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) + { + for (j = 0; j < moo->c->cls.var[i].initv_count; j++) + { + register moo_oop_t x = moo_moveoop (moo, moo->c->cls.var[i].initv[j]); + moo->c->cls.var[i].initv[j] = x; + } + } if (moo->c->cls.pooldic_oop) - moo->c->cls.pooldic_oop = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_oop); + { + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_oop); + moo->c->cls.pooldic_oop = (moo_oop_set_t)x; + } if (moo->c->cls.ns_oop) - moo->c->cls.ns_oop = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.ns_oop); + { + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.ns_oop); + moo->c->cls.ns_oop = (moo_oop_set_t)x; + } if (moo->c->cls.superns_oop) - moo->c->cls.superns_oop = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.superns_oop); + { + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.superns_oop); + moo->c->cls.superns_oop = (moo_oop_set_t)x; + } for (i = 0; i < moo->c->cls.pooldic_count; i++) { - moo->c->cls.pooldic_imp_oops[i] = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_imp_oops[i]); + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_imp_oops[i]); + moo->c->cls.pooldic_imp_oops[i] = (moo_oop_set_t)x; } for (i = 0; i < moo->c->mth.literal_count; i++) @@ -6975,9 +7236,10 @@ static void fini_compiler (moo_t* moo) if (moo->c->cls.superfqn.ptr) moo_freemem (moo, moo->c->cls.superfqn.ptr); if (moo->c->cls.modname.ptr) moo_freemem (moo, moo->c->cls.modname.ptr); - for (i = 0; i < MOO_COUNTOF(moo->c->cls.vars); i++) + for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) { - if (moo->c->cls.vars[i].ptr) moo_freemem (moo, moo->c->cls.vars[i].ptr); + if (moo->c->cls.var[i].str.ptr) moo_freemem (moo, moo->c->cls.var[i].str.ptr); + if (moo->c->cls.var[i].initv) moo_freemem (moo, moo->c->cls.var[i].initv); } if (moo->c->cls.pooldic.ptr) moo_freemem (moo, moo->c->cls.pooldic.ptr); diff --git a/moo/lib/err.c b/moo/lib/err.c index 156ccdf..e364f72 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -88,7 +88,7 @@ static moo_ooch_t synerrstr_15[] = {'(',' ','e','x','p','e','c','t','e','d','\0' static moo_ooch_t synerrstr_16[] = {')',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_17[] = {']',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_18[] = {'.',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_19[] = {' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_19[] = {',',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_20[] = {'|',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_21[] = {'>',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_22[] = {':','=',' ','e','x','p','e','c','t','e','d','\0'}; @@ -101,41 +101,42 @@ static moo_ooch_t synerrstr_28[] = {'d','u','p','l','i','c','a','t','e',' ','c', static moo_ooch_t synerrstr_29[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'}; static moo_ooch_t synerrstr_30[] = {'w','r','o','n','g',' ','c','l','a','s','s',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_31[] = {'n','o','n','-','p','o','i','n','t','e','r',' ','c','l','a','s','s',' ','i','n','h','e','r','i','t','i','n','g',' ','s','u','p','e','r','c','l','a','s','s',' ','w','i','t','h',' ','t','r','a','i','l','e','r',' ','s','i','z','e',' ','s','e','t','\0'}; -static moo_ooch_t synerrstr_32[] = {'d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; +static moo_ooch_t synerrstr_32[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; static moo_ooch_t synerrstr_33[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_34[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'}; static moo_ooch_t synerrstr_35[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'}; static moo_ooch_t synerrstr_36[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_37[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_37[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_38[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_39[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'}; -static moo_ooch_t synerrstr_40[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_43[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_44[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_45[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'}; -static moo_ooch_t synerrstr_46[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_47[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_48[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; -static moo_ooch_t synerrstr_49[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_50[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; -static moo_ooch_t synerrstr_55[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; -static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; -static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_59[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; -static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_62[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_63[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_64[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; -static moo_ooch_t synerrstr_65[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_66[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_40[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_43[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_44[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_45[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_46[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'}; +static moo_ooch_t synerrstr_47[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_48[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_49[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; +static moo_ooch_t synerrstr_50[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; +static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; +static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; +static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_60[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; +static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_63[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_64[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_65[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; +static moo_ooch_t synerrstr_66[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_67[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -146,7 +147,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47, synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63, - synerrstr_64, synerrstr_65, synerrstr_66 + synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67 }; #endif /* END: GENERATED WITH generr.moo */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 915c6fa..99aabb2 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1638,6 +1638,14 @@ static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs) moo->errnum = MOO_EINVAL; return MOO_PF_FAILURE; } + + if (MOO_OBJ_GET_FLAGS_RDONLY(rcv)) + { +/* TODO: better error handlign */ + moo->errnum = MOO_EPERM; + return MOO_PF_FAILURE; + } + pos = MOO_STACK_GETARG(moo, nargs, 0); val = MOO_STACK_GETARG(moo, nargs, 1); diff --git a/moo/lib/heap.c b/moo/lib/heap.c index 94546c7..e35bb8e 100644 --- a/moo/lib/heap.c +++ b/moo/lib/heap.c @@ -68,7 +68,8 @@ void* moo_allocheapmem (moo_t* moo, moo_heap_t* heap, moo_oow_t size) /* check the heap size limit */ if (heap->ptr >= heap->limit || heap->limit - heap->ptr < size) { - MOO_LOG4 (moo, MOO_LOG_ERROR, "Cannot allocate %zd bytes from heap - ptr %p limit %p size %zd\n", size, heap->ptr, heap->limit, (moo_oow_t)(heap->limit - heap->ptr)); + MOO_DEBUG5 (moo, "Cannot allocate %zd bytes from heap - ptr %p limit %p size %zd free %zd\n", + size, heap->ptr, heap->limit, (moo_oow_t)(heap->limit - heap->base), (moo_oow_t)(heap->limit - heap->ptr)); moo->errnum = MOO_EOOMEM; return MOO_NULL; } diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 208f19b..680a8dd 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -44,9 +44,13 @@ * PUSH_CONTEXT, PUSH_INTLIT, PUSH_INTLIT, SEND_BLOCK_COPY */ #define MOO_USE_MAKE_BLOCK +/* define this to limit the default values for instance variables + * to simple values like numbers or characters */ +#define MOO_SIMPLE_INITV + #if !defined(NDEBUG) /* this is for gc debugging */ -/*#define MOO_DEBUG_GC*/ +#define MOO_DEBUG_GC #define MOO_DEBUG_COMPILER /*#define MOO_DEBUG_VM_PROCESSOR*/ /*#define MOO_DEBUG_VM_EXEC*/ @@ -434,9 +438,6 @@ struct moo_compiler_t moo_oop_class_t self_oop; moo_oop_t super_oop; /* this may be nil. so the type is moo_oop_t */ -#ifdef MTHDIC - moo_oop_set_t mthdic_oop[2]; /* used when compiling a method definition */ -#endif moo_oop_set_t pooldic_oop; /* used when compiling a pooldic definition */ moo_oop_set_t ns_oop; moo_oocs_t fqn; @@ -453,15 +454,23 @@ struct moo_compiler_t moo_oocs_t modname; /* module name after 'from' */ moo_oow_t modname_capa; - /* instance variable, class variable, class instance variable */ - moo_oocs_t vars[3]; - moo_oow_t vars_capa[3]; + /* instance variable, class variable, class instance variable + * var[0] - named instance variables + * var[1] - class variables + * var[2] - class instance variables */ + struct + { + moo_oocs_t str; /* long string containing all variables declared delimited by a space */ + moo_oow_t str_capa; - /* var_count, unlike vars above, includes superclass counts as well. - * var_count[0] - number of named instance variables - * var_count[1] - number of class variables - * var_count[2] - number of class instance variables */ - moo_oow_t var_count[3]; + moo_oow_t count; /* the number of variables declared in this class only */ + moo_oow_t total_count; /* the number of variables declared in this class and superclasses */ + + moo_oop_t* initv; + moo_oow_t initv_capa; + moo_oow_t initv_count; + moo_oow_t initv_total_count; + } var[3]; /* buffer to hold pooldic import declaration */ moo_oocs_t pooldic; diff --git a/moo/lib/moo.h b/moo/lib/moo.h index fe4f73b..3f7cd0e 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -326,6 +326,7 @@ typedef enum moo_obj_type_t moo_obj_type_t; * when full definition is available, it's set to 2. * moved: 0 or 1. used by GC. internal use only. * ngc: 0 or 1, used by GC. internal use only. + * rdonly: 0 or 1. indicates that an object is immutable. * trailer: 0 or 1. indicates that there are trailing bytes * after the object payload. internal use only. * @@ -360,6 +361,7 @@ typedef enum moo_obj_type_t moo_obj_type_t; #define MOO_OBJ_FLAGS_KERNEL_BITS 2 #define MOO_OBJ_FLAGS_MOVED_BITS 1 #define MOO_OBJ_FLAGS_NGC_BITS 1 +#define MOO_OBJ_FLAGS_RDONLY_BITS 1 #define MOO_OBJ_FLAGS_TRAILER_BITS 1 #define MOO_OBJ_FLAGS_TYPE_SHIFT (MOO_OBJ_FLAGS_UNIT_BITS + MOO_OBJ_FLAGS_UNIT_SHIFT) @@ -367,7 +369,8 @@ typedef enum moo_obj_type_t moo_obj_type_t; #define MOO_OBJ_FLAGS_EXTRA_SHIFT (MOO_OBJ_FLAGS_KERNEL_BITS + MOO_OBJ_FLAGS_KERNEL_SHIFT) #define MOO_OBJ_FLAGS_KERNEL_SHIFT (MOO_OBJ_FLAGS_MOVED_BITS + MOO_OBJ_FLAGS_MOVED_SHIFT) #define MOO_OBJ_FLAGS_MOVED_SHIFT (MOO_OBJ_FLAGS_NGC_BITS + MOO_OBJ_FLAGS_NGC_SHIFT) -#define MOO_OBJ_FLAGS_NGC_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT) +#define MOO_OBJ_FLAGS_NGC_SHIFT (MOO_OBJ_FLAGS_RDONLY_BITS + MOO_OBJ_FLAGS_RDONLY_SHIFT) +#define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT) #define MOO_OBJ_FLAGS_TRAILER_SHIFT (0) #define MOO_OBJ_GET_FLAGS_TYPE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS) @@ -376,6 +379,7 @@ typedef enum moo_obj_type_t moo_obj_type_t; #define MOO_OBJ_GET_FLAGS_KERNEL(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS) #define MOO_OBJ_GET_FLAGS_MOVED(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS) #define MOO_OBJ_GET_FLAGS_NGC(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_NGC_SHIFT, MOO_OBJ_FLAGS_NGC_BITS) +#define MOO_OBJ_GET_FLAGS_RDONLY(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS) #define MOO_OBJ_GET_FLAGS_TRAILER(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS) #define MOO_OBJ_SET_FLAGS_TYPE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS, v) @@ -384,6 +388,7 @@ typedef enum moo_obj_type_t moo_obj_type_t; #define MOO_OBJ_SET_FLAGS_KERNEL(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_KERNEL_SHIFT, MOO_OBJ_FLAGS_KERNEL_BITS, v) #define MOO_OBJ_SET_FLAGS_MOVED(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_MOVED_SHIFT, MOO_OBJ_FLAGS_MOVED_BITS, v) #define MOO_OBJ_SET_FLAGS_NGC(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_NGC_SHIFT, MOO_OBJ_FLAGS_NGC_BITS, v) +#define MOO_OBJ_SET_FLAGS_RDONLY(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS, v) #define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v) #define MOO_OBJ_GET_SIZE(oop) ((oop)->_size) @@ -480,7 +485,7 @@ struct moo_set_t moo_oop_oop_t bucket; /* Array */ }; -#define MOO_CLASS_NAMED_INSTVARS 14 +#define MOO_CLASS_NAMED_INSTVARS 16 typedef struct moo_class_t moo_class_t; typedef struct moo_class_t* moo_oop_class_t; struct moo_class_t @@ -509,8 +514,11 @@ struct moo_class_t moo_oop_set_t mthdic[MOO_METHOD_TYPE_COUNT]; moo_oop_set_t nsdic; /* dictionary used for namespacing */ + moo_oop_set_t cdic; /* constant dictionary */ moo_oop_t trsize; /* trailer size for new instances */ + moo_oop_t initv; /* instial values for new instances */ + /* indexed part afterwards */ moo_oop_t slot[1]; /* class instance variables and class variables. */ }; @@ -1273,14 +1281,15 @@ enum moo_synerrnum_t MOO_SYNERR_CLASSCONTRA, /* contradictory class */ MOO_SYNERR_CLASSNAMEINVAL, /* wrong class name */ MOO_SYNERR_CLASSTRSIZE, /* non-pointer class inheriting a superclass with trailer size set */ - MOO_SYNERR_DCLBANNED, /* #dcl not allowed */ + MOO_SYNERR_VARDCLBANNED, /* variable declaration not allowed */ MOO_SYNERR_MODIFIER, /* modifier expected */ MOO_SYNERR_MODIFIERINVAL, /* wrong modifier */ MOO_SYNERR_MODIFIERBANNED, /* modifier not allowed */ MOO_SYNERR_MODIFIERDUPL, /* duplicate modifier */ - MOO_SYNERR_MTHNAME, /* wrong method name */ + MOO_SYNERR_MTHNAME, /* method name expected */ MOO_SYNERR_MTHNAMEDUPL, /* duplicate method name */ MOO_SYNERR_VARIADMTHINVAL, /* invalid variadic method definition */ + MOO_SYNERR_VARNAME, /* variable name expected */ MOO_SYNERR_ARGNAMEDUPL, /* duplicate argument name */ MOO_SYNERR_TMPRNAMEDUPL, /* duplicate temporary variable name */ MOO_SYNERR_VARNAMEDUPL, /* duplicate variable name */ diff --git a/moo/lib/obj.c b/moo/lib/obj.c index 70755b7..d058861 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -38,6 +38,12 @@ void* moo_allocbytes (moo_t* moo, moo_oow_t size) if (!ptr && moo->errnum == MOO_EOOMEM && !(moo->option.trait & MOO_NOGC)) { moo_gc (moo); + MOO_LOG4 (moo, MOO_LOG_INFO, + "GC completed - current heap ptr %p limit %p size %zd free %zd\n", + moo->curheap->ptr, moo->curheap->limit, + (moo_oow_t)(moo->curheap->limit - moo->curheap->base), + (moo_oow_t)(moo->curheap->limit - moo->curheap->ptr) + ); ptr = moo_allocheapmem (moo, moo->curheap, size); /* TODO: grow heap if ptr is still null. */ } @@ -266,6 +272,32 @@ moo_oop_t moo_instantiate (moo_t* moo, moo_oop_class_t _class, const void* vptr, /* both the fixed part(named instance variables) and * the variable part(indexed instance variables) are allowed. */ oop = moo_allocoopobj (moo, alloclen); + if (oop) + { + /* initialize named instance variables with default values */ + if (_class->initv != moo->_nil) + { + + moo_oow_t i = MOO_OBJ_GET_SIZE(_class->initv); + + #if defined(MOO_SIMPLE_INITV) + while (i > 0) + { + --i; + ((moo_oop_oop_t)oop)->slot[i] = ((moo_oop_oop_t)_class->initv)->slot[i]; + } + #else + moo_pushtmp (moo, (moo_oop_t*)&oop); tmp_count++; + while (i > 0) + { + --i; +/* TODO: deep copy the object so that the items can be modified without side-effects.... */ + ((moo_oop_oop_t)oop)->slot[i] = ((moo_oop_oop_t)_class->initv)->slot[i]; + } + moo_poptmp (moo); tmp_count--; + #endif + } + } MOO_ASSERT (moo, vptr == MOO_NULL); /* diff --git a/moo/lib/sym.c b/moo/lib/sym.c index ad8bdf6..2cac124 100644 --- a/moo/lib/sym.c +++ b/moo/lib/sym.c @@ -132,8 +132,8 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow moo_oop_oop_t bucket; /* TODO: make the growth policy configurable instead of growing - it just before it gets full. The polcy can be grow it - if it's 70% full */ + it just before it gets full. The polcy can be grow it + if it's 70% full */ /* enlarge the symbol table before it gets full to * make sure that it has at least one free slot left