From fb40db7aa83dd9c52f679145ddcebb41108ddfa1 Mon Sep 17 00:00:00 2001 From: qtxie Date: Tue, 11 Oct 2016 01:48:47 -0700 Subject: [PATCH 0001/3432] FEAT: GTK3: enable libRedRT --- system/config.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/config.r b/system/config.r index 5a2732e75b..c42fec9122 100644 --- a/system/config.r +++ b/system/config.r @@ -95,7 +95,7 @@ Linux [ ; Linux default target format: 'ELF type: 'exe dynamic-linker: "/lib/ld-linux.so.2" -dev-mode?: no + ;dev-mode?: no ] Linux-Old [ OS: 'Linux From bb75f0cb1121d784c6473b75724bb030ae0924f5 Mon Sep 17 00:00:00 2001 From: Thiago Dourado de Andrade <7hi4g0@gmail.com> Date: Fri, 30 Sep 2016 16:22:08 -0400 Subject: [PATCH 0002/3432] FEAT: GTK3: added color update for base widget --- modules/view/backends/gtk3/gui.reds | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 664c1a1fc8..8ff975a8fd 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -418,7 +418,7 @@ OS-update-view: func [ int2 [red-integer!] bool [red-logic!] s [series!] - hWnd [integer!] + widget [integer!] flags [integer!] type [integer!] ][ @@ -431,49 +431,50 @@ OS-update-view: func [ type: symbol/resolve word/symbol s: GET_BUFFER(state) int: as red-integer! s/offset - hWnd: int/value + widget: int/value int: int + 1 flags: int/value ;if flags and FACET_FLAG_OFFSET <> 0 [ - ; change-offset hWnd as red-pair! values + FACE_OBJ_OFFSET type + ; change-offset widget as red-pair! values + FACE_OBJ_OFFSET type ;] ;if flags and FACET_FLAG_SIZE <> 0 [ - ; change-size hWnd as red-pair! values + FACE_OBJ_SIZE type + ; change-size widget as red-pair! values + FACE_OBJ_SIZE type ;] ;if flags and FACET_FLAG_TEXT <> 0 [ - ; change-text hWnd values type + ; change-text widget values type ;] ;if flags and FACET_FLAG_DATA <> 0 [ - ; change-data as handle! hWnd values + ; change-data as handle! widget values ;] ;if flags and FACET_FLAG_ENABLE? <> 0 [ - ; change-enabled as handle! hWnd values + ; change-enabled as handle! widget values ;] ;if flags and FACET_FLAG_VISIBLE? <> 0 [ ; bool: as red-logic! values + FACE_OBJ_VISIBLE? - ; change-visible hWnd bool/value type + ; change-visible widget bool/value type ;] ;if flags and FACET_FLAG_SELECTED <> 0 [ ; int2: as red-integer! values + FACE_OBJ_SELECTED - ; change-selection hWnd int2 values + ; change-selection widget int2 values ;] ;if flags and FACET_FLAG_FLAGS <> 0 [ ; SetWindowLong - ; as handle! hWnd + ; as handle! widget ; wc-offset + 16 ; get-flags as red-block! values + FACE_OBJ_FLAGS ;] if flags and FACET_FLAG_DRAW <> 0 [ - gtk_widget_queue_draw as handle! hWnd + gtk_widget_queue_draw as handle! widget ] - ;if flags and FACET_FLAG_COLOR <> 0 [ - ; either type = base [ - ; update-base as handle! hWnd null null values + if flags and FACET_FLAG_COLOR <> 0 [ + if type = base [ + ; update-base as handle! widget null null values + gtk_widget_queue_draw as handle! widget ; ][ - ; InvalidateRect as handle! hWnd null 1 - ; ] - ;] + ; InvalidateRect as handle! widget null 1 + ] + ] ;if flags and FACET_FLAG_PANE <> 0 [ ; if tab-panel <> type [ ;-- tab-panel/pane has custom z-order handling ; update-z-order @@ -482,22 +483,22 @@ OS-update-view: func [ ; ] ;] ;if flags and FACET_FLAG_FONT <> 0 [ - ; set-font as handle! hWnd face values - ; InvalidateRect as handle! hWnd null 1 + ; set-font as handle! widget face values + ; InvalidateRect as handle! widget null 1 ;] ;if flags and FACET_FLAG_PARA <> 0 [ ; update-para face 0 - ; InvalidateRect as handle! hWnd null 1 + ; InvalidateRect as handle! widget null 1 ;] ;if flags and FACET_FLAG_MENU <> 0 [ ; menu: as red-block! values + FACE_OBJ_MENU ; if menu-bar? menu window [ - ; DestroyMenu GetMenu as handle! hWnd - ; SetMenu as handle! hWnd build-menu menu CreateMenu + ; DestroyMenu GetMenu as handle! widget + ; SetMenu as handle! widget build-menu menu CreateMenu ; ] ;] ;if flags and FACET_FLAG_IMAGE <> 0 [ - ; change-image hWnd values type + ; change-image widget values type ;] int/value: 0 ;-- reset flags From b0dd08a98dd96ef99bce5d8c134321ef14e0cb71 Mon Sep 17 00:00:00 2001 From: Thiago Dourado de Andrade <7hi4g0@gmail.com> Date: Mon, 3 Oct 2016 14:14:43 -0400 Subject: [PATCH 0003/3432] FEAT: GTK3: added preliminary text, progress, field and area widgets --- modules/view/backends/gtk3/gtk.reds | 6 ++++++ modules/view/backends/gtk3/gui.reds | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index fabb3fad1f..5862aef4c6 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -249,6 +249,12 @@ tagSIZE: alias struct! [ range [handle!] return: [float!] ] + gtk_progress_bar_new: "gtk_progress_bar_new" [ + return: [handle!] + ] + gtk_text_view_new: "gtk_text_view_new" [ + return: [handle!] + ] ;; LIBCAIRO-file cdecl [ cairo_line_to: "cairo_line_to" [ cr [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8ff975a8fd..b1d34b32f3 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -382,6 +382,18 @@ OS-make-view: func [ ; insert value-changed handler gobj_signal_connect(widget "value-changed" :value-changed face/ctx) ] + sym = text [ + widget: gtk_label_new caption + ] + sym = field [ + widget: gtk_entry_new + ] + sym = progress [ + widget: gtk_progress_bar_new + ] + sym = area [ + widget: gtk_text_view_new + ] true [ ;-- search in user-defined classes fire [TO_ERROR(script face-type) type] From cae6e6aa6dbee4a5c24de183d8ee5a154b9f2908 Mon Sep 17 00:00:00 2001 From: Thiago Dourado de Andrade <7hi4g0@gmail.com> Date: Tue, 4 Oct 2016 14:51:35 -0400 Subject: [PATCH 0004/3432] FEAT: GTK3: preliminary font style --- modules/view/backends/gtk3/gtk.reds | 25 +++++++ modules/view/backends/gtk3/gui.reds | 5 ++ modules/view/backends/gtk3/style.reds | 94 +++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 modules/view/backends/gtk3/style.reds diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 5862aef4c6..1d4fe038bd 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -84,6 +84,9 @@ tagSIZE: alias struct! [ gdk_screen_height: "gdk_screen_height" [ return: [integer!] ] + gdk_screen_get_default: "gdk_screen_get_default" [ + return: [handle!] + ] ;; ] ;; LIBGLIB-file cdecl [ g_quark_from_string: "g_quark_from_string" [ @@ -255,6 +258,28 @@ tagSIZE: alias struct! [ gtk_text_view_new: "gtk_text_view_new" [ return: [handle!] ] + gtk_css_provider_new: "gtk_css_provider_new" [ + return: [handle!] + ] + gtk_css_provider_load_from_data: "gtk_css_provider_load_from_data" [ + provider [handle!] + data [c-string!] + length [integer!] + error [handle!] + ] + gtk_style_context_add_provider_for_screen: "gtk_style_context_add_provider_for_screen" [ + screen [handle!] + provider [handle!] + priority [integer!] + ] + gtk_style_context_add_class: "gtk_style_context_add_class" [ + context [handle!] + class [c-string!] + ] + gtk_widget_get_style_context: "gtk_widget_get_style_context" [ + widget [handle!] + return: [handle!] + ] ;; LIBCAIRO-file cdecl [ cairo_line_to: "cairo_line_to" [ cr [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b1d34b32f3..bd27def818 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -18,6 +18,7 @@ Red/System [ #include %draw.reds #include %handlers.reds +#include %style.reds GTKApp: as handle! 0 GTKApp-Ctx: 0 @@ -169,6 +170,8 @@ init: func [][ screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height + + style-init ] set-selected-focus: func [ @@ -400,6 +403,8 @@ OS-make-view: func [ ] ] + set-widget-style widget face + if all [ sym <> window parent <> 0 diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds new file mode 100644 index 0000000000..3d0de3ec7a --- /dev/null +++ b/modules/view/backends/gtk3/style.reds @@ -0,0 +1,94 @@ +Red/System [ + Title: "GTK3 widget style management" + Author: "Thiago Dourado de Andrade" + File: %style.reds + Tabs: 4 + Rights: "Copyright (C) 2016 Thiago Dourado de Andrade. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +#define GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 600 + +css-style: { + .bold { + font-weight: bold; + } + + .italic { + font-style: italic; + } + + .underline { + text-decoration-line: underline; + } + + .strike { + text-decoration-line: line-through; + } +} + +style-init: func [ + /local + provider [handle!] + screen [handle!] +][ + screen: gdk_screen_get_default + provider: gtk_css_provider_new + + gtk_css_provider_load_from_data provider css-style length? css-style as handle! 0 + + gtk_style_context_add_provider_for_screen screen provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION +] + +set-widget-style: func [ + widget [handle!] + face [red-object!] + /local + font [red-object!] + values [red-value!] + context [handle!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + class [c-string!] +][ + values: object/get-values face + + font: as red-object! values + FACE_OBJ_FONT + + if TYPE_OF(font) = TYPE_OBJECT [ + values: object/get-values font + + style: as red-word! values + FONT_OBJ_STYLE + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + context: gtk_widget_get_style_context widget + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + class: case [ + sym = _bold ["bold"] + sym = _italic ["italic"] + sym = _underline ["underline"] + sym = _strike ["strike"] + true [""] + ] + unless 0 = length? class [gtk_style_context_add_class context class] + ] + ] + ] +] From dfbcfa8354605e2604e6578f2328bbef1a5e09aa Mon Sep 17 00:00:00 2001 From: Thiago Dourado de Andrade <7hi4g0@gmail.com> Date: Fri, 7 Oct 2016 15:18:18 -0400 Subject: [PATCH 0005/3432] FEAT: GTK3: added font-size support --- modules/view/backends/gtk3/gtk.reds | 12 ++++++ modules/view/backends/gtk3/gui.reds | 4 +- modules/view/backends/gtk3/style.reds | 60 ++++++++++++++++++++++----- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 1d4fe038bd..a112d0608c 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -112,6 +112,13 @@ tagSIZE: alias struct! [ list [int-ptr!] return: [integer!] ] + g_strdup_printf: "g_strdup_printf" [ + [variadic] + return: [c-string!] + ] + g_free: "g_free" [ + pointer [handle!] + ] ;; ] ;; LIBGIO-file cdecl [ g_application_register: "g_application_register" [ @@ -267,6 +274,11 @@ tagSIZE: alias struct! [ length [integer!] error [handle!] ] + gtk_style_context_add_provider: "gtk_style_context_add_provider" [ + context [handle!] + provider [handle!] + priority [integer!] + ] gtk_style_context_add_provider_for_screen: "gtk_style_context_add_provider_for_screen" [ screen [handle!] provider [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index bd27def818..bb1f1fbbb0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -24,6 +24,7 @@ GTKApp: as handle! 0 GTKApp-Ctx: 0 exit-loop: 0 red-face-id: 0 +gtk-style-id: 0 log-pixels-x: 0 log-pixels-y: 0 @@ -167,6 +168,7 @@ init: func [][ g_application_register GTKApp null null red-face-id: g_quark_from_string "red-face-id" + gtk-style-id: g_quark_from_string "gtk-style-id" screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height @@ -403,7 +405,7 @@ OS-make-view: func [ ] ] - set-widget-style widget face + create-widget-style widget face if all [ sym <> window diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds index 3d0de3ec7a..7afd7bcb70 100644 --- a/modules/view/backends/gtk3/style.reds +++ b/modules/view/backends/gtk3/style.reds @@ -28,6 +28,10 @@ css-style: { .strike { text-decoration-line: line-through; } + + progress, trough { + min-height: 2em; + } } style-init: func [ @@ -43,18 +47,45 @@ style-init: func [ gtk_style_context_add_provider_for_screen screen provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ] +get-style-provider: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget gtk-style-id +] + +create-widget-style: func [ + widget [handle!] + face [red-object!] + /local + context [handle!] + provider [handle!] +][ + provider: gtk_css_provider_new + context: gtk_widget_get_style_context widget + + gtk_style_context_add_provider context provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + + g_object_set_qdata widget gtk-style-id provider + + set-widget-style widget face +] + set-widget-style: func [ widget [handle!] face [red-object!] /local - font [red-object!] - values [red-value!] - context [handle!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - class [c-string!] + font [red-object!] + values [red-value!] + context [handle!] + provider [handle!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + class [c-string!] + size [red-integer!] + css [c-string!] ][ values: object/get-values face @@ -63,8 +94,17 @@ set-widget-style: func [ if TYPE_OF(font) = TYPE_OBJECT [ values: object/get-values font + size: as red-integer! values + FONT_OBJ_SIZE style: as red-word! values + FONT_OBJ_STYLE + css: "" + context: gtk_widget_get_style_context widget + provider: get-style-provider widget + + if TYPE_OF(size) = TYPE_INTEGER [ + css: g_strdup_printf ["* {font-size:%dpt;}" size/value] + ] + len: switch TYPE_OF(style) [ TYPE_BLOCK [ blk: as red-block! style @@ -75,8 +115,6 @@ set-widget-style: func [ default [0] ] - context: gtk_widget_get_style_context widget - unless zero? len [ loop len [ sym: symbol/resolve style/symbol @@ -90,5 +128,7 @@ set-widget-style: func [ unless 0 = length? class [gtk_style_context_add_class context class] ] ] + + gtk_css_provider_load_from_data provider css -1 null ] ] From 3db93862b72d6ab102a230d1931153b96a654fec Mon Sep 17 00:00:00 2001 From: Thiago Dourado de Andrade <7hi4g0@gmail.com> Date: Mon, 10 Oct 2016 10:07:11 -0400 Subject: [PATCH 0006/3432] FEAT: GTK3: added font-color support --- modules/view/backends/gtk3/gtk.reds | 8 ++++ modules/view/backends/gtk3/style.reds | 68 +++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a112d0608c..408fa99993 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -18,6 +18,8 @@ Red/System [ g_signal_connect_data instance signal as-integer handler data null 0 ] +#define G_ASCII_DTOSTR_BUF_SIZE 39 + RECT_STRUCT: alias struct! [ left [integer!] top [integer!] @@ -112,6 +114,12 @@ tagSIZE: alias struct! [ list [int-ptr!] return: [integer!] ] + g_ascii_dtostr: "g_ascii_dtostr" [ + buffer [c-string!] + buf_len [integer!] + d [float!] + return: [c-string!] + ] g_strdup_printf: "g_strdup_printf" [ [variadic] return: [c-string!] diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds index 7afd7bcb70..56ae28ec99 100644 --- a/modules/view/backends/gtk3/style.reds +++ b/modules/view/backends/gtk3/style.reds @@ -42,11 +42,57 @@ style-init: func [ screen: gdk_screen_get_default provider: gtk_css_provider_new - gtk_css_provider_load_from_data provider css-style length? css-style as handle! 0 + gtk_css_provider_load_from_data provider css-style -1 null gtk_style_context_add_provider_for_screen screen provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ] +add-to-string: func [ + string [c-string!] + format [c-string!] + value [handle!] + return: [c-string!] + /local + temp [c-string!] +][ + temp: g_strdup_printf [format string value] + g_free as handle! string + temp +] + +to-css-rgba: func [ + color [red-tuple!] ;-- needs to be a valid color tuple + return: [c-string!] ;-- rgba(r, g, b, a) format - Should be cleaned with g_free + /local + size [integer!] + r [integer!] + g [integer!] + b [integer!] + a [float!] + rgba [c-string!] + alpha [c-string!] +][ + size: TUPLE_SIZE?(color) + + r: color/array1 and FFh + g: (color/array1 >> 8) and FFh + b: (color/array1 >> 16) and FFh + a: 1.0 + + if size = 4 [ + a: (as-float 255 - color/array1 >>> 24) / 255.0 + ] + + alpha: as c-string! allocate G_ASCII_DTOSTR_BUF_SIZE + g_ascii_dtostr alpha G_ASCII_DTOSTR_BUF_SIZE a + + rgba: g_strdup_printf ["rgba(%d, %d, %d, %s)" r g b alpha] + + free as byte-ptr! alpha + + rgba +] + get-style-provider: func [ widget [handle!] return: [handle!] @@ -86,6 +132,8 @@ set-widget-style: func [ class [c-string!] size [red-integer!] css [c-string!] + color [red-tuple!] + rgba [c-string!] ][ values: object/get-values face @@ -94,15 +142,19 @@ set-widget-style: func [ if TYPE_OF(font) = TYPE_OBJECT [ values: object/get-values font + ;name: size: as red-integer! values + FONT_OBJ_SIZE style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: - css: "" + css: g_strdup_printf ["* {"] context: gtk_widget_get_style_context widget provider: get-style-provider widget if TYPE_OF(size) = TYPE_INTEGER [ - css: g_strdup_printf ["* {font-size:%dpt;}" size/value] + css: add-to-string css "%s font-size: %dpt;" as handle! size/value ] len: switch TYPE_OF(style) [ @@ -129,6 +181,16 @@ set-widget-style: func [ ] ] + if TYPE_OF(color) = TYPE_TUPLE [ + rgba: to-css-rgba color + css: add-to-string css "%s color: %s;" as handle! rgba + g_free as handle! rgba + ] + + css: add-to-string css "%s}" null + gtk_css_provider_load_from_data provider css -1 null + + g_free as handle! css ] ] From 381343efb722cdbaea3e5fd0f1ac8af6478acc30 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 27 Oct 2016 19:29:10 +0800 Subject: [PATCH 0007/3432] FEAT: update code for changes in macGUI branch --- boot.red | 2 +- modules/view/backends/gtk3/comdlgs.reds | 32 +++++++++++++++++++++++++ modules/view/backends/gtk3/draw.reds | 7 +++--- modules/view/backends/gtk3/gui.reds | 1 + 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 modules/view/backends/gtk3/comdlgs.reds diff --git a/boot.red b/boot.red index 421f73abf6..34c6daa1ae 100644 --- a/boot.red +++ b/boot.red @@ -34,6 +34,6 @@ Red [ extract-boot-args ;-- temporary code -- -#if not find [Windows MacOSX] config/OS [ +#if not find [Windows MacOSX Linux] config/OS [ unset [event! image!] ] diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds new file mode 100644 index 0000000000..5d4c105959 --- /dev/null +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -0,0 +1,32 @@ +Red/System [ + Title: "Common Dialogs" + Author: "Xie Qingtian" + File: %comdlgs.reds + Tabs: 4 + Rights: "Copyright (C) 2016 Xie Qingtian. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] +OS-request-dir: func [ + title [red-string!] + dir [red-file!] + filter [red-block!] + keep? [logic!] + multi? [logic!] + return: [red-value!] +][ + as red-value! none-value +] + +OS-request-file: func [ + title [red-string!] + name [red-file!] + filter [red-block!] + save? [logic!] + multi? [logic!] + return: [red-value!] +][ + as red-value! none-value +] \ No newline at end of file diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 99ca8ec02a..99cf1eb5a2 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -533,6 +533,7 @@ OS-matrix-set: func [ ] OS-set-clip: func [ + dc [draw-ctx!] upper [red-pair!] lower [red-pair!] ][ @@ -577,8 +578,8 @@ OS-draw-shape-line: func [ OS-draw-shape-axis: func [ dc [draw-ctx!] - start [red-integer!] - end [red-integer!] + start [red-value!] + end [red-value!] rel? [logic!] hline [logic!] ][ @@ -623,7 +624,7 @@ OS-draw-shape-qcurv: func [ OS-draw-shape-arc: func [ dc [draw-ctx!] start [red-pair!] - end [red-integer!] + end [red-value!] sweep? [logic!] large? [logic!] rel? [logic!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index bb1f1fbbb0..068afeb1b4 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -19,6 +19,7 @@ Red/System [ #include %handlers.reds #include %style.reds +#include %comdlgs.reds GTKApp: as handle! 0 GTKApp-Ctx: 0 From f3cc1026e9f4abee40a1d5fe50ffdba557d4a5f8 Mon Sep 17 00:00:00 2001 From: qtxie Date: Thu, 27 Oct 2016 07:19:51 -0700 Subject: [PATCH 0008/3432] FIX: patch to enable using libRedRT in Non-GUI program (Develop only) --- environment/datatypes.red | 4 +--- environment/scalars.red | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/environment/datatypes.red b/environment/datatypes.red index 0a4c10d97b..f9263f608d 100644 --- a/environment/datatypes.red +++ b/environment/datatypes.red @@ -59,9 +59,7 @@ time!: make datatype! #get-definition TYPE_TIME tag!: make datatype! #get-definition TYPE_TAG email!: make datatype! #get-definition TYPE_EMAIL -#if find config/modules 'view [ - event!: make datatype! #get-definition TYPE_EVENT -] +event!: make datatype! #get-definition TYPE_EVENT none: make none! 0 true: make logic! 1 diff --git a/environment/scalars.red b/environment/scalars.red index ff96ec9349..7b990e5314 100644 --- a/environment/scalars.red +++ b/environment/scalars.red @@ -32,7 +32,7 @@ Rebol: false ;-- makes loading Rebol scripts easier ;-- warning: following typeset definitions are processed by the compiler, do not change them ;-- unless you know what you are doing! -internal!: make typeset! [unset! #if find config/modules 'view [event!]] +internal!: make typeset! [unset! event!] number!: make typeset! [integer! float! percent!] scalar!: union number! make typeset! [char! pair! tuple! time!] any-word!: make typeset! [word! set-word! get-word! lit-word! refinement! issue!] From 8620d1c27106660058a0b778552c438b21fcfa70 Mon Sep 17 00:00:00 2001 From: qtxie Date: Thu, 12 Jan 2017 08:20:34 +0800 Subject: [PATCH 0009/3432] FIX: GTK3: compiling error after last merge --- compiler.r | 2 +- modules/view/backends/gtk3/draw.reds | 20 ++------- modules/view/backends/gtk3/font.reds | 7 ++-- modules/view/backends/gtk3/gui.reds | 63 ++++++++++++++++++++++++++++ runtime/definitions.reds | 18 +++++++- 5 files changed, 89 insertions(+), 21 deletions(-) diff --git a/compiler.r b/compiler.r index 60ea5af067..c1c263baf3 100644 --- a/compiler.r +++ b/compiler.r @@ -100,7 +100,7 @@ red: context [ standard-modules: [ ;-- Name ------ Entry file -------------- OS availability ----- - View %modules/view/view.red [Windows MacOSX] + View %modules/view/view.red [Windows MacOSX Linux] ] func-constructors: [ diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 99cf1eb5a2..aa064bd75e 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -10,20 +10,7 @@ Red/System [ } ] -draw-ctx!: alias struct! [ - raw [handle!] - pen-join [integer!] - pen-cap [integer!] - pen-width [integer!] - pen-style [integer!] - pen-color [integer!] ;-- 00bbggrr format - brush-color [integer!] ;-- 00bbggrr format - font-color [integer!] - pen? [logic!] - brush? [logic!] - pattern [handle!] - on-image? [logic!] ;-- drawing on image? -] +#include %text-box.reds set-source-color: func [ cr [handle!] @@ -349,6 +336,7 @@ OS-draw-image: func [ end [red-pair!] key-color [red-tuple!] border? [logic!] + crop1 [red-pair!] pattern [red-word!] /local x [integer!] @@ -470,7 +458,7 @@ OS-matrix-scale: func [ ] OS-matrix-translate: func [ - ctx [handle!] + dc [draw-ctx!] x [integer!] y [integer!] ][ @@ -506,7 +494,7 @@ OS-matrix-transform: func [ center: as red-pair! either rotate + 1 = scale [rotate][rotate + 1] OS-matrix-rotate dc rotate center OS-matrix-scale dc scale scale + 1 - OS-matrix-translate dc/raw translate/x translate/y + OS-matrix-translate dc translate/x translate/y ] OS-matrix-push: func [dc [draw-ctx!] /local state [integer!]][ diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 3167713092..3610be9aaa 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -66,9 +66,10 @@ update-font: func [ ] OS-request-font: func [ - font [red-object!] - mono? [logic!] - return: [red-object!] + font [red-object!] + selected [red-object!] + mono? [logic!] + return: [red-object!] ][ font ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 068afeb1b4..efdce2b1d6 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -290,6 +290,59 @@ store-face-to-obj: func [ g_object_set_qdata obj red-face-id as int-ptr! storage ] +update-scroller: func [ + scroller [red-object!] + flag [integer!] + /local + parent [red-object!] + vertical? [red-logic!] + int [red-integer!] + values [red-value!] + hWnd [handle!] + nTrackPos [integer!] + nPos [integer!] + nPage [integer!] + nMax [integer!] + nMin [integer!] + fMask [integer!] + cbSize [integer!] +][ + ;values: object/get-values scroller + ;parent: as red-object! values + SCROLLER_OBJ_PARENT + ;vertical?: as red-logic! values + SCROLLER_OBJ_VERTICAL? + ;int: as red-integer! block/rs-head as red-block! (object/get-values parent) + FACE_OBJ_STATE + ;hWnd: as handle! int/value + + ;int: as red-integer! values + flag + + ;if flag = SCROLLER_OBJ_VISIBLE? [ + ; ShowScrollBar hWnd as-integer vertical?/value as logic! int/value + ; exit + ;] + + ;fMask: switch flag [ + ; SCROLLER_OBJ_POS [nPos: int/value SIF_POS] + ; SCROLLER_OBJ_PAGE + ; SCROLLER_OBJ_MAX [ + ; int: as red-integer! values + SCROLLER_OBJ_PAGE + ; nPage: int/value + ; int: as red-integer! values + SCROLLER_OBJ_MAX + ; nMin: 1 + ; nMax: int/value + ; SIF_RANGE or SIF_PAGE + ; ] + ; default [0] + ;] + + ;if fMask <> 0 [ + ; fMask: fMask or SIF_DISABLENOSCROLL + ; cbSize: size? tagSCROLLINFO + ; SetScrollInfo hWnd as-integer vertical?/value as tagSCROLLINFO :cbSize yes + ;] +] + +OS-redraw: func [hWnd [integer!]][gtk_widget_queue_draw as handle! hWnd] + OS-refresh-window: func [hWnd [integer!]][0] OS-show-window: func [ @@ -602,3 +655,13 @@ OS-do-draw: func [ ][ do-draw null img cmds no no no no ] + +OS-draw-face: func [ + ctx [draw-ctx!] + cmds [red-block!] +][ + if TYPE_OF(cmds) = TYPE_BLOCK [ + catch RED_THROWN_ERROR [parse-draw ctx cmds yes] + ] + if system/thrown = RED_THROWN_ERROR [system/thrown: 0] +] \ No newline at end of file diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 284fa8087b..ec8fa56526 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -152,7 +152,23 @@ Red/System [ on-image? [logic!] ;-- drawing on image? ] ] - #default [] ;-- Linux? + Linux [ + draw-ctx!: alias struct! [ + raw [int-ptr!] + pen-join [integer!] + pen-cap [integer!] + pen-width [integer!] + pen-style [integer!] + pen-color [integer!] ;-- 00bbggrr format + brush-color [integer!] ;-- 00bbggrr format + font-color [integer!] + pen? [logic!] + brush? [logic!] + pattern [int-ptr!] + on-image? [logic!] ;-- drawing on image? + ] + ] + #default [] ] #either OS = 'Windows [ From a431ff551672cfd0e64b543cf4eaf5f9c8bad455 Mon Sep 17 00:00:00 2001 From: qtxie Date: Thu, 12 Jan 2017 08:21:02 +0800 Subject: [PATCH 0010/3432] FIX: GTK3: adds missing file text-box.reds --- modules/view/backends/gtk3/text-box.reds | 230 +++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 modules/view/backends/gtk3/text-box.reds diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds new file mode 100644 index 0000000000..268da9b86d --- /dev/null +++ b/modules/view/backends/gtk3/text-box.reds @@ -0,0 +1,230 @@ +Red/System [ + Title: "Text Box Windows DirectWrite Backend" + Author: "Xie Qingtian" + File: %text-box.reds + Tabs: 4 + Dependency: %draw-d2d.reds + Rights: "Copyright (C) 2016 Xie Qingtian. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +#define TBOX_METRICS_OFFSET? 0 +#define TBOX_METRICS_INDEX? 1 +#define TBOX_METRICS_LINE_HEIGHT 2 +#define TBOX_METRICS_METRICS 3 + +max-line-cnt: 0 + +OS-text-box-color: func [ + dc [handle!] + layout [handle!] + pos [integer!] + len [integer!] + color [integer!] +][ + ;brush: select-brush dc + 1 color + ;if zero? brush [ + ; this: as this! dc/value + ; rt: as ID2D1HwndRenderTarget this/vtbl + ; rt/CreateSolidColorBrush this to-dx-color color null null :brush + ; put-brush dc + 1 color brush + ;] + + ;this: as this! layout + ;dl: as IDWriteTextLayout this/vtbl + ;dl/SetDrawingEffect this as this! brush pos len +] + +OS-text-box-background: func [ + dc [handle!] + layout [handle!] + pos [integer!] + len [integer!] + color [integer!] + /local + cache [red-vector!] + brush [integer!] +][ + ;cache: as red-vector! dc + 3 + ;if TYPE_OF(cache) <> TYPE_VECTOR [ + ; vector/make-at as red-value! cache 128 TYPE_INTEGER 4 + ;] + ;brush: select-brush dc + 1 color + ;if zero? brush [ + ; this: as this! dc/value + ; rt: as ID2D1HwndRenderTarget this/vtbl + ; rt/CreateSolidColorBrush this to-dx-color color null null :brush + ; put-brush dc + 1 color brush + ;] + ;vector/rs-append-int cache pos + ;vector/rs-append-int cache len + ;vector/rs-append-int cache brush +] + +OS-text-box-weight: func [ + layout [handle!] + pos [integer!] + len [integer!] + weight [integer!] +][ +] + +OS-text-box-italic: func [ + layout [handle!] + pos [integer!] + len [integer!] +][ +] + +OS-text-box-underline: func [ + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] ;-- options + tail [red-value!] +][ +] + +OS-text-box-strikeout: func [ + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] ;-- options +][ +] + +OS-text-box-border: func [ + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] ;-- options + tail [red-value!] +][ + 0 +] + +OS-text-box-font-name: func [ + layout [handle!] + pos [integer!] + len [integer!] + name [red-string!] +][ + ;n: -1 + ;this: as this! layout + ;dl: as IDWriteTextLayout this/vtbl + ;dl/SetFontFamilyName this unicode/to-utf16-len name :n yes pos len +] + +OS-text-box-font-size: func [ + layout [handle!] + pos [integer!] + len [integer!] + size [float!] +][ +] + +OS-text-box-metrics: func [ + layout [handle!] + arg0 [red-value!] + type [integer!] + return: [red-value!] +][ + as red-value! none-value + ;as red-value! switch type [ + ; TBOX_METRICS_OFFSET? [ + ; x: as float32! 0.0 y: as float32! 0.0 + ; ;int: as red-integer! arg0 + ; ] + ; TBOX_METRICS_INDEX? [ + ; pos: as red-pair! arg0 + ; x: as float32! pos/x + ; y: as float32! pos/y + ; ] + ; TBOX_METRICS_LINE_HEIGHT [ + ; lineCount: 0 + ; dl/GetLineMetrics this null 0 :lineCount + ; if lineCount > max-line-cnt [ + ; max-line-cnt: lineCount + 1 + ; line-metrics: as DWRITE_LINE_METRICS realloc + ; as byte-ptr! line-metrics + ; lineCount + 1 * size? DWRITE_HIT_TEST_METRICS + ; ] + ; lineCount: 0 + ; dl/GetLineMetrics this line-metrics max-line-cnt :lineCount + ; lm: line-metrics + ; hr: as-integer arg0 + ; while [ + ; hr: hr - lm/length + ; lineCount: lineCount - 1 + ; all [hr > 0 lineCount > 0] + ; ][ + ; lm: lm + 1 + ; ] + ; integer/push as-integer lm/height + ; ] + ; default [ + ; metrics: as DWRITE_TEXT_METRICS :left + ; hr: dl/GetMetrics this metrics + ; #if debug? = yes [if hr <> 0 [log-error hr]] + + ; values: object/get-values as red-object! arg0 + ; integer/make-at values + TBOX_OBJ_WIDTH as-integer metrics/width + ; integer/make-at values + TBOX_OBJ_HEIGHT as-integer metrics/height + ; integer/make-at values + TBOX_OBJ_LINE_COUNT metrics/lineCount + ; ] + ;] +] + +OS-text-box-layout: func [ + box [red-object!] + target [int-ptr!] + catch? [logic!] + return: [integer!] +][ + ;values: object/get-values box + ;if null? target [ + ; hWnd: get-face-handle as red-object! values + TBOX_OBJ_TARGET + ; target: get-hwnd-render-target hWnd + ;] + + ;state: as red-block! values + TBOX_OBJ_STATE + ;either TYPE_OF(state) = TYPE_BLOCK [ + ; int: as red-integer! block/rs-head state ;-- release previous text layout + ; layout: as this! int/value + ; COM_SAFE_RELEASE(IUnk layout) + ; int: int + 1 + ; fmt: as this! int/value + ;][ + ; fixed?: as red-logic! values + TBOX_OBJ_FIXED? + ; fmt: as this! create-text-format as red-object! values + TBOX_OBJ_FONT + ; if fixed?/value [set-line-spacing fmt] + ; block/make-at state 2 + ; none/make-in state ;-- 1: text layout + ; integer/make-in state as-integer fmt ;-- 2: text format + ;] + + ;set-text-format fmt as red-object! values + TBOX_OBJ_PARA + + ;str: as red-string! values + TBOX_OBJ_TEXT + ;size: as red-pair! values + TBOX_OBJ_SIZE + ;either TYPE_OF(size) = TYPE_PAIR [ + ; w: size/x h: size/y + ;][ + ; w: 0 h: 0 + ;] + ;layout: create-text-layout str fmt w h + ;integer/make-at block/rs-head state as-integer layout + + ;styles: as red-block! values + TBOX_OBJ_STYLES + ;if all [ + ; TYPE_OF(styles) = TYPE_BLOCK + ; 2 < block/rs-length? styles + ;][ + ; parse-text-styles target as handle! layout styles catch? + ;] + ;layout + 0 +] \ No newline at end of file From 4b183b28ab1e5800eac5f357389f03ab69b84b5f Mon Sep 17 00:00:00 2001 From: qtxie Date: Wed, 19 Jul 2017 09:55:21 +0800 Subject: [PATCH 0011/3432] FIX: compilation error after merge --- modules/view/VID.red | 4 +++- modules/view/backends/gtk3/gui.reds | 2 +- modules/view/backends/gtk3/style.reds | 12 ------------ modules/view/backends/platform.red | 12 +++++++++--- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index 8bed7a3e39..513ca40d45 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -22,6 +22,8 @@ system/view/VID: context [ #switch config/OS [ Windows [#include %backends/windows/rules.red] macOS [#include %backends/macOS/rules.red] + Linux [] + #default [] ] ] @@ -690,7 +692,7 @@ system/view/VID: context [ either only [list][ if panel/type = 'window [ panel/parent: system/view/screens/1 - system/view/VID/GUI-rules/process panel + ;system/view/VID/GUI-rules/process panel ] panel ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a1541f408e..6742b68352 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -405,7 +405,7 @@ OS-make-view: func [ offset: as red-pair! values + FACE_OBJ_OFFSET size: as red-pair! values + FACE_OBJ_SIZE show?: as red-logic! values + FACE_OBJ_VISIBLE? - open?: as red-logic! values + FACE_OBJ_ENABLE? + open?: as red-logic! values + FACE_OBJ_ENABLED? data: as red-block! values + FACE_OBJ_DATA img: as red-image! values + FACE_OBJ_IMAGE menu: as red-block! values + FACE_OBJ_MENU diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds index 56ae28ec99..6843245f87 100644 --- a/modules/view/backends/gtk3/style.reds +++ b/modules/view/backends/gtk3/style.reds @@ -20,18 +20,6 @@ css-style: { .italic { font-style: italic; } - - .underline { - text-decoration-line: underline; - } - - .strike { - text-decoration-line: line-through; - } - - progress, trough { - min-height: 2em; - } } style-init: func [ diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 9b7cfb532c..d288d0ced3 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -714,6 +714,8 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] + Linux [] + #default [] ]] extend system/view/metrics/paddings [#switch config/OS [ Windows [ @@ -731,6 +733,8 @@ system/view/platform: context [ field: [3x3 0x0] group-box: [0x8 4x18] ] + Linux [] + #default [] ]] extend system/view/metrics/def-heights [#switch config/OS [ Windows [] @@ -743,6 +747,8 @@ system/view/platform: context [ drop-list: 21 progress: 21 ] + Linux [] + #default [] ]] colors: system/view/metrics/colors @@ -752,9 +758,9 @@ system/view/platform: context [ ;colors/window ;-- set in gui/init from OS metrics ;colors/panel ;-- set in gui/init from OS metrics ] - macOS [ - - ] + macOS [] + Linux [] + #default [] ] append svs make face! [ ;-- default screen From 4eebeb00ee9991ab22a765248b3b0e605ed8cdea Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 31 Jul 2017 20:38:49 +0200 Subject: [PATCH 0012/3432] add drop-list --- modules/view/backends/gtk3/gtk.reds | 25 +++++++++ modules/view/backends/gtk3/gui.reds | 57 ++++++++++++++++++++- modules/view/backends/gtk3/handlers.reds | 64 +++++++++++++++++++++++- 3 files changed, 144 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 7927858093..a627fe080b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -271,6 +271,31 @@ tagSIZE: alias struct! [ gtk_text_view_new: "gtk_text_view_new" [ return: [handle!] ] + gtk_combo_box_text_new: "gtk_combo_box_text_new" [ + return: [handle!] + ] + gtk_combo_box_text_new_with_entry: "gtk_combo_box_text_new_with_entry" [ + return: [handle!] + ] + gtk_combo_box_text_append_text: "gtk_combo_box_text_append_text" [ + combo [handle!] + item [c-string!] + ] + gtk_combo_box_text_remove_all: "gtk_combo_box_text_remove_all" [ + combo [handle!] + ] + gtk_combo_box_get_active: "gtk_combo_box_get_active" [ + combo [handle!] + return: [integer!] + ] + gtk_combo_box_set_active: "gtk_combo_box_set_active" [ + combo [handle!] + item [integer!] + ] + gtk_combo_box_text_get_active_text: "gtk_combo_box_text_get_active_text" [ + combo [handle!] + return: [c-string!] + ] gtk_css_provider_new: "gtk_css_provider_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 6742b68352..e8173d6e38 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -305,6 +305,52 @@ store-face-to-obj: func [ g_object_set_qdata obj red-face-id as int-ptr! storage ] +init-combo-box: func [ + combo [handle!] + data [red-block!] + caption [c-string!] + drop-list? [logic!] ;to remove if unused + /local + str [red-string!] + tail [red-string!] + len [integer!] + val [c-string!] +][ + if any [ + TYPE_OF(data) = TYPE_BLOCK + TYPE_OF(data) = TYPE_HASH + TYPE_OF(data) = TYPE_MAP + ][ + str: as red-string! block/rs-head data + tail: as red-string! block/rs-tail data + + ;remove all items + gtk_combo_box_text_remove_all combo + + if str = tail [exit] + + while [str < tail][ + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + val: unicode/to-utf8 str :len + gtk_combo_box_text_append_text combo val + ] + str: str + 1 + ] + ] + + ;len: objc_msgSend [combo sel_getUid "numberOfItems"] + ;if zero? len [objc_msgSend [combo sel_getUid "setStringValue:" NSString("")]] + + ;either drop-list? [ + ; objc_msgSend [combo sel_getUid "setEditable:" false] + ;][ + ; if caption <> 0 [ + ; objc_msgSend [combo sel_getUid "setStringValue:" caption] + ; ] + ;] +] + update-scroller: func [ scroller [red-object!] flag [integer!] @@ -454,7 +500,7 @@ OS-make-view: func [ gtk_scale_set_has_origin widget no gtk_scale_set_draw_value widget no ; insert value-changed handler - gobj_signal_connect(widget "value-changed" :value-changed face/ctx) + gobj_signal_connect(widget "value-changed" :range-value-changed face/ctx) ] sym = text [ widget: gtk_label_new caption @@ -468,6 +514,15 @@ OS-make-view: func [ sym = area [ widget: gtk_text_view_new ] + any [ + sym = drop-list + sym = drop-down + ][ + widget: either sym = drop-list [gtk_combo_box_text_new][gtk_combo_box_text_new_with_entry] + init-combo-box widget data caption sym = drop-list + gtk_combo_box_set_active widget 0 + gobj_signal_connect(widget "changed" :combo-selection-changed face/ctx) + ] true [ ;-- search in user-defined classes fire [TO_ERROR(script face-type) type] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c4a4599a9d..159cefc5f5 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -20,6 +20,47 @@ gtk-app-activate: func [ probe "active" ] +set-selected: func [ + obj [handle!] + ctx [node!] + idx [integer!] + /local + int [red-integer!] +][ + int: as red-integer! get-node-facet ctx FACE_OBJ_SELECTED + int/header: TYPE_INTEGER + int/value: idx +] + +set-text: func [ + obj [handle!] + ctx [node!] + text [c-string!] + /local + size [integer!] + str [red-string!] + face [red-object!] + out [c-string!] +][ + size: length? text + if size >= 0 [ + str: as red-string! get-node-facet ctx FACE_OBJ_TEXT + if TYPE_OF(str) <> TYPE_STRING [ + str/node: unicode/load-utf8 text size + ] + if size = 0 [ + string/rs-reset str + exit + ] + + face: push-face obj + if TYPE_OF(face) = TYPE_OBJECT [ + ownership/bind as red-value! str face _text + ] + stack/pop 1 + ] +] + button-clicked: func [ [cdecl] widget [handle!] @@ -90,7 +131,7 @@ window-removed-event: func [ count/value: count/value - 1 ] -value-changed: func [ +range-value-changed: func [ [cdecl] range [handle!] ctx [node!] @@ -124,3 +165,24 @@ value-changed: func [ make-event range 0 EVT_CHANGE ;] ] + +combo-selection-changed: func [ + [cdecl] + combo [handle!] + ctx [node!] + /local + idx [integer!] + res [integer!] + text [c-string!] +][ + idx: gtk_combo_box_get_active combo + if idx >= 0 [ + res: make-event combo idx + 1 EVT_SELECT + set-selected combo ctx idx + 1 + text: gtk_combo_box_text_get_active_text combo + set-text combo ctx text + if res = EVT_DISPATCH [ + make-event combo idx + 1 EVT_CHANGE + ] + ] +] From cb8cda2b7f60e45fabc1fc773d91e02838e35e15 Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 1 Aug 2017 08:25:28 +0200 Subject: [PATCH 0013/3432] face/text not set properly --- modules/view/backends/gtk3/handlers.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 159cefc5f5..c80132fced 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -46,12 +46,13 @@ set-text: func [ if size >= 0 [ str: as red-string! get-node-facet ctx FACE_OBJ_TEXT if TYPE_OF(str) <> TYPE_STRING [ - str/node: unicode/load-utf8 text size + string/make-at as red-value! str size UCS-2 ] if size = 0 [ string/rs-reset str exit ] + str/node: unicode/load-utf8 text size face: push-face obj if TYPE_OF(face) = TYPE_OBJECT [ From 396a1e71f0f37ef5dd8c308797c20b2822c1300b Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 1 Aug 2017 09:31:21 +0200 Subject: [PATCH 0014/3432] Avoid allocate new string --- modules/view/backends/gtk3/handlers.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c80132fced..bdc5a8fcde 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -52,7 +52,7 @@ set-text: func [ string/rs-reset str exit ] - str/node: unicode/load-utf8 text size + unicode/load-utf8-buffer text size GET_BUFFER(str) null no face: push-face obj if TYPE_OF(face) = TYPE_OBJECT [ From 83e4d8eaa1abbee10ff8f1f1bb1ebf9c904fa677 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 3 Aug 2017 10:15:21 +0200 Subject: [PATCH 0015/3432] Add radio, init field and area,first attempt for group-box --- modules/view/backends/gtk3/gtk.reds | 47 ++++++++++++++++++++++++ modules/view/backends/gtk3/gui.reds | 55 +++++++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a627fe080b..9fdeeeb8e3 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -199,6 +199,25 @@ tagSIZE: alias struct! [ container [handle!] return: [int-ptr!] ] + gtk_box_new: "gtk_box_new" [ + orientation [integer!] + padding [integer!] + return: [handle!] + ] + gtk_box_pack_start: "gtk_box_pack_start" [ + box [handle!] + child [handle!] + expand [logic!] + fill [logic!] + padding [integer!] + ] + gtk_box_pack_end: "gtk_box_pack_end" [ + box [handle!] + child [handle!] + expand [logic!] + fill [logic!] + padding [integer!] + ] gtk_fixed_new: "gtk_fixed_new" [ return: [handle!] ] @@ -216,6 +235,16 @@ tagSIZE: alias struct! [ label [c-string!] return: [handle!] ] + gtk_radio_button_new_with_label: "gtk_radio_button_new_with_label" [ + group [handle!] + label [c-string!] + return: [handle!] + ] + gtk_radio_button_new_with_label_from_widget: "gtk_radio_button_new_with_label_from_widget" [ + group [handle!] + label [c-string!] + return: [handle!] + ] gtk_toggle_button_get_active: "gtk_toggle_button_get_active" [ button [handle!] return: [logic!] @@ -242,6 +271,15 @@ tagSIZE: alias struct! [ gtk_entry_new: "gtk_entry_new" [ return: [handle!] ] + gtk_entry_get_buffer: "gtk_entry_get_buffer" [ + entry [handle!] + return: [handle!] + ] + gtk_entry_buffer_set_text: "gtk_entry_buffer_set_text" [ + buffer [handle!] + text [c-string!] + len [integer!] + ] gtk_scale_new_with_range: "gtk_scale_new_with_range" [ vertical? [logic!] min [float!] @@ -271,6 +309,15 @@ tagSIZE: alias struct! [ gtk_text_view_new: "gtk_text_view_new" [ return: [handle!] ] + gtk_text_view_get_buffer: "gtk_text_view_get_buffer" [ + view [handle!] + return: [handle!] + ] + gtk_text_buffer_set_text: "gtk_text_buffer_set_text" [ + buffer [handle!] + text [c-string!] + len [integer!] + ] gtk_combo_box_text_new: "gtk_combo_box_text_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e8173d6e38..c0e7a6142e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -27,6 +27,9 @@ exit-loop: 0 red-face-id: 0 gtk-style-id: 0 +none-type: as red-word! symbol/make "none" +group-radio: as handle! 0 + log-pixels-x: 0 log-pixels-y: 0 screen-size-x: 0 @@ -100,6 +103,25 @@ get-face-handle: func [ as handle! int/value ] +parent-type?: func [ + parent [handle!] + return: [red-word!] + /local + qdata [handle!] + p-face [red-object!] + p-type [red-word!] +][ + p-type: none-type + qdata: g_object_get_qdata parent red-face-id + if qdata <> as handle! 0 [ + p-face: as red-object! qdata + if TYPE_OF(p-face) = TYPE_OBJECT [ + p-type: as red-word! get-node-facet p-face/ctx FACE_OBJ_TYPE + ] + ] + p-type +] + get-child-from-xy: func [ parent [handle!] x [integer!] @@ -432,12 +454,14 @@ OS-make-view: func [ open? [red-logic!] selected [red-integer!] para [red-object!] + p-type [red-word!] flags [integer!] bits [integer!] sym [integer!] caption [c-string!] len [integer!] widget [handle!] + buffer [handle!] container [handle!] value [integer!] vertical? [logic!] @@ -474,6 +498,16 @@ OS-make-view: func [ gobj_signal_connect(widget "clicked" :button-clicked null) gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] + sym = radio [ + widget: either group-radio = as handle! 0 [ + gtk_radio_button_new_with_label null caption + ][ + gtk_radio_button_new_with_label_from_widget group-radio caption + ] + set-logic-state widget as red-logic! data no + gobj_signal_connect(widget "clicked" :button-clicked null) + gobj_signal_connect(widget "toggled" :button-toggled face/ctx) + ] sym = button [ widget: gtk_button_new_with_label caption gobj_signal_connect(widget "clicked" :button-clicked null) @@ -507,12 +541,19 @@ OS-make-view: func [ ] sym = field [ widget: gtk_entry_new + buffer: gtk_entry_get_buffer widget + gtk_entry_buffer_set_text buffer caption -1 ] sym = progress [ widget: gtk_progress_bar_new ] sym = area [ widget: gtk_text_view_new + buffer: gtk_text_view_get_buffer widget + gtk_text_buffer_set_text buffer caption -1 + ] + sym = group-box [ + widget: gtk_box_new 0 0 ; horizontal and 0 as padding ] any [ sym = drop-list @@ -529,15 +570,23 @@ OS-make-view: func [ ] ] + ; save the previous group-radio state as a global variable + group-radio: either sym = radio [widget][as handle! 0] + create-widget-style widget face if all [ sym <> window parent <> 0 ][ - gtk_widget_set_size_request widget size/x size/y - container: gtk_container_get_children as handle! parent - gtk_fixed_put as handle! container/value widget offset/x offset/y + p-type: parent-type? as handle! parent + either group-box = symbol/resolve p-type/symbol [ + gtk_box_pack_start as handle! parent widget yes yes 0 + ][ + gtk_widget_set_size_request widget size/x size/y + container: gtk_container_get_children as handle! parent + gtk_fixed_put as handle! container/value widget offset/x offset/y + ] ] ;-- store the face value in the extra space of the window struct From 66bf9af9566ccb495e95eccb6b093253f0a6bed6 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 3 Aug 2017 14:23:41 +0200 Subject: [PATCH 0016/3432] Group-box as gtk-frame with gtk_fixed element --- modules/view/backends/gtk3/gui.reds | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index c0e7a6142e..beced62863 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -553,7 +553,9 @@ OS-make-view: func [ gtk_text_buffer_set_text buffer caption -1 ] sym = group-box [ - widget: gtk_box_new 0 0 ; horizontal and 0 as padding + widget: gtk_frame_new caption + container: gtk_fixed_new + gtk_container_add widget container ] any [ sym = drop-list @@ -579,14 +581,9 @@ OS-make-view: func [ sym <> window parent <> 0 ][ - p-type: parent-type? as handle! parent - either group-box = symbol/resolve p-type/symbol [ - gtk_box_pack_start as handle! parent widget yes yes 0 - ][ - gtk_widget_set_size_request widget size/x size/y - container: gtk_container_get_children as handle! parent - gtk_fixed_put as handle! container/value widget offset/x offset/y - ] + gtk_widget_set_size_request widget size/x size/y + container: gtk_container_get_children as handle! parent + gtk_fixed_put as handle! container/value widget offset/x offset/y ] ;-- store the face value in the extra space of the window struct From d2689ed3c7ef2e99207152b62f32738d495262f9 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 3 Aug 2017 14:27:22 +0200 Subject: [PATCH 0017/3432] gtk_frame_new added --- modules/view/backends/gtk3/gtk.reds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 9fdeeeb8e3..34a58ec6e0 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -218,6 +218,10 @@ tagSIZE: alias struct! [ fill [logic!] padding [integer!] ] + gtk_frame_new: "gtk_frame_new" [ + label [c-string!] + return: [handle!] + ] gtk_fixed_new: "gtk_fixed_new" [ return: [handle!] ] From d80096f4a74ed834c3b2cfd4777e3793a1433452 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 3 Aug 2017 14:41:59 +0200 Subject: [PATCH 0018/3432] gtk_box no more needed --- modules/view/backends/gtk3/gtk.reds | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 34a58ec6e0..df18bc8507 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -199,25 +199,6 @@ tagSIZE: alias struct! [ container [handle!] return: [int-ptr!] ] - gtk_box_new: "gtk_box_new" [ - orientation [integer!] - padding [integer!] - return: [handle!] - ] - gtk_box_pack_start: "gtk_box_pack_start" [ - box [handle!] - child [handle!] - expand [logic!] - fill [logic!] - padding [integer!] - ] - gtk_box_pack_end: "gtk_box_pack_end" [ - box [handle!] - child [handle!] - expand [logic!] - fill [logic!] - padding [integer!] - ] gtk_frame_new: "gtk_frame_new" [ label [c-string!] return: [handle!] From 8b33df9fbf7f02639e5f91cd8214980c65a210f7 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 4 Aug 2017 06:43:39 +0200 Subject: [PATCH 0019/3432] Add preliminary panel and qtxie improvement --- modules/view/backends/gtk3/gtk.reds | 22 ++++++++++++ modules/view/backends/gtk3/gui.reds | 52 ++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index df18bc8507..31e132ee90 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -203,6 +203,15 @@ tagSIZE: alias struct! [ label [c-string!] return: [handle!] ] + gtk_frame_set_label_align: "gtk_frame_set_label_align" [ + frame [handle!] + xalign [float!] + yalign [float!] + ] + gtk_frame_set_shadow_type: "gtk_frame_set_shadow_type" [ + frame [handle!] + shadow [integer!] + ] gtk_fixed_new: "gtk_fixed_new" [ return: [handle!] ] @@ -328,6 +337,19 @@ tagSIZE: alias struct! [ combo [handle!] return: [c-string!] ] + gtk_notebook_new: "gtk_notebook_new" [ + return: [handle!] + ] + gtk_notebook_append_page: "gtk_notebook_append_page" [ + nb [handle!] + pane [handle!] + label [handle!] + return: [integer!] + ] + gtk_notebook_get_n_pages: "gtk_notebook_get_n_pages" [ + nb [handle!] + return: [integer!] + ] gtk_css_provider_new: "gtk_css_provider_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index beced62863..09c0cab54a 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -27,7 +27,6 @@ exit-loop: 0 red-face-id: 0 gtk-style-id: 0 -none-type: as red-word! symbol/make "none" group-radio: as handle! 0 log-pixels-x: 0 @@ -103,23 +102,25 @@ get-face-handle: func [ as handle! int/value ] -parent-type?: func [ - parent [handle!] - return: [red-word!] +widget-face-symbol?: func [ + widget [handle!] + return: [integer!] /local qdata [handle!] - p-face [red-object!] - p-type [red-word!] + face [red-object!] + type [red-word!] + sym [integer!] ][ - p-type: none-type - qdata: g_object_get_qdata parent red-face-id + sym: -1 + qdata: g_object_get_qdata widget red-face-id if qdata <> as handle! 0 [ - p-face: as red-object! qdata - if TYPE_OF(p-face) = TYPE_OBJECT [ - p-type: as red-word! get-node-facet p-face/ctx FACE_OBJ_TYPE + face: as red-object! qdata + if TYPE_OF(face) = TYPE_OBJECT [ + type: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE + sym: symbol/resolve type/symbol ] ] - p-type + sym ] get-child-from-xy: func [ @@ -454,10 +455,10 @@ OS-make-view: func [ open? [red-logic!] selected [red-integer!] para [red-object!] - p-type [red-word!] flags [integer!] bits [integer!] sym [integer!] + p-sym [integer!] caption [c-string!] len [integer!] widget [handle!] @@ -554,9 +555,21 @@ OS-make-view: func [ ] sym = group-box [ widget: gtk_frame_new caption + gtk_frame_set_shadow_type widget 3 + gtk_frame_set_label_align widget 0.5 0.5; Todo: does not seem to work container: gtk_fixed_new gtk_container_add widget container ] + sym = panel [ + widget: gtk_fixed_new ; To be completed + unless null? caption [ + buffer: gtk_label_new caption + gtk_container_add widget buffer + ] + ] + sym = tab-panel [ + widget: gtk_notebook_new ; To be completed + ] any [ sym = drop-list sym = drop-down @@ -581,9 +594,16 @@ OS-make-view: func [ sym <> window parent <> 0 ][ - gtk_widget_set_size_request widget size/x size/y - container: gtk_container_get_children as handle! parent - gtk_fixed_put as handle! container/value widget offset/x offset/y + p-sym: widget-face-symbol? as handle! parent + either p-sym = panel [ + container: as handle! parent + gtk_widget_set_size_request widget size/x size/y + gtk_fixed_put as handle! container widget offset/x offset/y + ][ + container: gtk_container_get_children as handle! parent + gtk_widget_set_size_request widget size/x size/y + gtk_fixed_put as handle! container/value widget offset/x offset/y + ] ] ;-- store the face value in the extra space of the window struct From 27561a930566104b99b97dee204c420667ca4f8b Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 4 Aug 2017 10:41:18 +0200 Subject: [PATCH 0020/3432] Add text-list with automatic scrollview --- modules/view/backends/gtk3/gtk.reds | 25 +++++++++++++++ modules/view/backends/gtk3/gui.reds | 50 ++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 31e132ee90..0e5ec4cf17 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -221,6 +221,31 @@ tagSIZE: alias struct! [ x [integer!] y [integer!] ] + gtk_list_box_new: "gtk_list_box_new" [ + return: [handle!] + ] + gtk_list_box_select_row: "gtk_list_box_select_row" [ + listbox [handle!] + row [handle!] + ] + gtk_list_box_get_selected_row: "gtk_list_box_get_selected_row" [ + listbox [handle!] + return: [handle!] + ] + gtk_list_box_get_row_at_index: "gtk_list_box_get_row_at_index" [ + listbox [handle!] + index [integer!] + return: [handle!] + ] + gtk_list_box_row_get_index: "gtk_list_box_row_get_index" [ + row [handle!] + return: [integer!] + ] + gtk_scrolled_window_new: "gtk_scrolled_window_new" [ + hadj [handle!] + vadj [handle!] + return: [handle!] + ] gtk_button_new_with_label: "gtk_button_new_with_label" [ label [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 09c0cab54a..52abea0dd5 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -374,6 +374,37 @@ init-combo-box: func [ ;] ] + +init-text-list: func [ + widget [handle!] + data [red-block!] + /local + str [red-string!] + tail [red-string!] + val [c-string!] + len [integer!] +][ + if any [ + TYPE_OF(data) = TYPE_BLOCK + TYPE_OF(data) = TYPE_HASH + TYPE_OF(data) = TYPE_MAP + ][ + str: as red-string! block/rs-head data + tail: as red-string! block/rs-tail data + + if str = tail [exit] + + while [str < tail][ + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + val: unicode/to-utf8 str :len + gtk_container_add widget gtk_label_new val + ] + str: str + 1 + ] + ] +] + update-scroller: func [ scroller [red-object!] flag [integer!] @@ -462,6 +493,7 @@ OS-make-view: func [ caption [c-string!] len [integer!] widget [handle!] + widget2 [handle!] buffer [handle!] container [handle!] value [integer!] @@ -471,6 +503,8 @@ OS-make-view: func [ values: object/get-values face + widget2: as handle! 0; widget version with possible scrollview + type: as red-word! values + FACE_OBJ_TYPE str: as red-string! values + FACE_OBJ_TEXT offset: as red-pair! values + FACE_OBJ_OFFSET @@ -570,6 +604,13 @@ OS-make-view: func [ sym = tab-panel [ widget: gtk_notebook_new ; To be completed ] + sym = text-list [ + widget: gtk_list_box_new + init-text-list widget data + gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 + widget2: gtk_scrolled_window_new null null + gtk_container_add widget2 widget + ] any [ sym = drop-list sym = drop-down @@ -595,14 +636,15 @@ OS-make-view: func [ parent <> 0 ][ p-sym: widget-face-symbol? as handle! parent + if widget2 = as handle! 0 [widget2: widget] either p-sym = panel [ container: as handle! parent - gtk_widget_set_size_request widget size/x size/y - gtk_fixed_put as handle! container widget offset/x offset/y + gtk_widget_set_size_request widget2 size/x size/y + gtk_fixed_put as handle! container widget2 offset/x offset/y ][ container: gtk_container_get_children as handle! parent - gtk_widget_set_size_request widget size/x size/y - gtk_fixed_put as handle! container/value widget offset/x offset/y + gtk_widget_set_size_request widget2 size/x size/y + gtk_fixed_put as handle! container/value widget2 offset/x offset/y ] ] From 65b907ccd896236a99c94e4d18cc4d4612ad3282 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 4 Aug 2017 16:22:02 +0200 Subject: [PATCH 0021/3432] Add selected-rows-changed for text-list --- modules/view/backends/gtk3/gtk.reds | 8 +++++ modules/view/backends/gtk3/gui.reds | 1 + modules/view/backends/gtk3/handlers.reds | 38 +++++++++++++++++++----- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 0e5ec4cf17..18d6a9cbd0 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -221,6 +221,10 @@ tagSIZE: alias struct! [ x [integer!] y [integer!] ] + gtk_bin_get_child: "gtk_bin_get_child" [ + bin [handle!] + return: [handle!] + ] gtk_list_box_new: "gtk_list_box_new" [ return: [handle!] ] @@ -287,6 +291,10 @@ tagSIZE: alias struct! [ label [c-string!] return: [handle!] ] + gtk_label_get_text: "gtk_label_get_text" [ + label [handle!] + return: [c-string!] + ] gtk_entry_new: "gtk_entry_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 52abea0dd5..3236bb9b4d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -610,6 +610,7 @@ OS-make-view: func [ gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 widget2: gtk_scrolled_window_new null null gtk_container_add widget2 widget + gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) ] any [ sym = drop-list diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index bdc5a8fcde..59f0913efc 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -169,21 +169,45 @@ range-value-changed: func [ combo-selection-changed: func [ [cdecl] - combo [handle!] + widget [handle!] + ctx [node!] + /local + idx [integer!] + res [integer!] + text [c-string!] +][ + idx: gtk_combo_box_get_active widget + if idx >= 0 [ + res: make-event widget idx + 1 EVT_SELECT + set-selected widget ctx idx + 1 + text: gtk_combo_box_text_get_active_text widget + set-text widget ctx text + if res = EVT_DISPATCH [ + make-event widget idx + 1 EVT_CHANGE + ] + ] +] + +text-list-selected-rows-changed: func [ + [cdecl] + widget [handle!] ctx [node!] /local idx [integer!] + sel [handle!] res [integer!] text [c-string!] ][ - idx: gtk_combo_box_get_active combo + ; From now, only single-selection mode + sel: gtk_list_box_get_selected_row widget + idx: gtk_list_box_row_get_index sel if idx >= 0 [ - res: make-event combo idx + 1 EVT_SELECT - set-selected combo ctx idx + 1 - text: gtk_combo_box_text_get_active_text combo - set-text combo ctx text + res: make-event widget idx + 1 EVT_SELECT + set-selected widget ctx idx + 1 + text: gtk_label_get_text gtk_bin_get_child sel + set-text widget ctx text if res = EVT_DISPATCH [ - make-event combo idx + 1 EVT_CHANGE + make-event widget idx + 1 EVT_CHANGE ] ] ] From e3c94f54c05553ecd6361fcdcbc41a0c2edc20cd Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 4 Aug 2017 21:25:56 +0200 Subject: [PATCH 0022/3432] Add tab-panel --- modules/view/backends/gtk3/gui.reds | 46 ++++++++++++++++++++++------- modules/view/view.red | 2 +- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 3236bb9b4d..8869f82b2c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -28,6 +28,11 @@ red-face-id: 0 gtk-style-id: 0 group-radio: as handle! 0 +tabs: context [ + nb: 0 + cur: 0 + data: as red-block! 0 +] log-pixels-x: 0 log-pixels-y: 0 @@ -102,7 +107,7 @@ get-face-handle: func [ as handle! int/value ] -widget-face-symbol?: func [ +get-widget-face-symbol: func [ widget [handle!] return: [integer!] /local @@ -603,6 +608,9 @@ OS-make-view: func [ ] sym = tab-panel [ widget: gtk_notebook_new ; To be completed + tabs/data: data + tabs/cur: 0 + tabs/nb: block/rs-length? data ] sym = text-list [ widget: gtk_list_box_new @@ -636,16 +644,34 @@ OS-make-view: func [ sym <> window parent <> 0 ][ - p-sym: widget-face-symbol? as handle! parent + p-sym: get-widget-face-symbol as handle! parent if widget2 = as handle! 0 [widget2: widget] - either p-sym = panel [ - container: as handle! parent - gtk_widget_set_size_request widget2 size/x size/y - gtk_fixed_put as handle! container widget2 offset/x offset/y - ][ - container: gtk_container_get_children as handle! parent - gtk_widget_set_size_request widget2 size/x size/y - gtk_fixed_put as handle! container/value widget2 offset/x offset/y + case [ + p-sym = panel [ + container: as handle! parent + gtk_widget_set_size_request widget2 size/x size/y + gtk_fixed_put as handle! container widget2 offset/x offset/y + ] + p-sym = tab-panel [ + container: as handle! parent + ; widget is necessarily a panel and then same as widget2 + str: (as red-string! block/rs-head tabs/data) + tabs/cur + caption: either TYPE_OF(str) = TYPE_STRING [ + len: -1 + unicode/to-utf8 str :len + ][ + "Tab" + ] + buffer: gtk_label_new caption + gtk_notebook_append_page container widget buffer + tabs/cur: tabs/cur + 1 + if tabs/cur = tabs/nb [tabs/cur: 0 tabs/nb: 0] + ] + true [ + container: gtk_container_get_children as handle! parent + gtk_widget_set_size_request widget2 size/x size/y + gtk_fixed_put as handle! container/value widget2 offset/x offset/y + ] ] ] diff --git a/modules/view/view.red b/modules/view/view.red index 561f76ec65..daa01a6253 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -745,7 +745,7 @@ show: function [ ] switch face/type [ - #if config/OS = 'Windows [ ;@@ remove this system specific code + #if any [config/OS = 'Windows config/OS = 'Linux] [ ;@@ remove this system specific code tab-panel [link-tabs-to-parent face] ] window [ From 096ccb8557716acf1868adc3c7cb4867494fac62 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 5 Aug 2017 07:37:24 +0200 Subject: [PATCH 0023/3432] Links-tab-to-parent is visibly done already since this line could be avoided for Linux --- modules/view/view.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/view.red b/modules/view/view.red index daa01a6253..ae09ff0b32 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -745,7 +745,7 @@ show: function [ ] switch face/type [ - #if any [config/OS = 'Windows config/OS = 'Linux] [ ;@@ remove this system specific code + #if config/OS = 'Windows [ ;@@ remove this system specific code tab-panel [link-tabs-to-parent face] ] window [ From 4a20739f3c174a4fadbff58f54cdadc7bdbb6eea Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 5 Aug 2017 07:39:02 +0200 Subject: [PATCH 0024/3432] Bad space! --- modules/view/view.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/view.red b/modules/view/view.red index ae09ff0b32..561f76ec65 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -745,7 +745,7 @@ show: function [ ] switch face/type [ - #if config/OS = 'Windows [ ;@@ remove this system specific code + #if config/OS = 'Windows [ ;@@ remove this system specific code tab-panel [link-tabs-to-parent face] ] window [ From 8cbc5727e9361bb601479faaf15e3b445a9720c6 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 5 Aug 2017 11:42:35 +0200 Subject: [PATCH 0025/3432] get-face-values implemented and tab-panel actors --- modules/view/backends/gtk3/gtk.reds | 15 ++++++ modules/view/backends/gtk3/gui.reds | 69 ++++++++++++++---------- modules/view/backends/gtk3/handlers.reds | 21 ++++++++ 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 18d6a9cbd0..a089207100 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -379,6 +379,21 @@ tagSIZE: alias struct! [ label [handle!] return: [integer!] ] + gtk_notebook_get_current_page: "gtk_notebook_get_current_page" [ + nb [handle!] + return: [integer!] + ] + + gtk_notebook_get_nth_page: "gtk_notebook_get_nth_page" [ + nb [handle!] + index [integer!] + return: [handle!] + ] + gtk_notebook_get_tab_label_text: "gtk_notebook_get_tab_label_text" [ + nb [handle!] + page [handle!] + return: [c-string!] + ] gtk_notebook_get_n_pages: "gtk_notebook_get_n_pages" [ nb [handle!] return: [integer!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8869f82b2c..695fee16ba 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -31,7 +31,6 @@ group-radio: as handle! 0 tabs: context [ nb: 0 cur: 0 - data: as red-block! 0 ] log-pixels-x: 0 @@ -40,10 +39,20 @@ screen-size-x: 0 screen-size-y: 0 get-face-values: func [ - handle [integer!] + handle [handle!] return: [red-value!] + /local + face [red-object!] + qdata [handle!] + values [red-value!] ][ - null + values: as red-value! 0 + qdata: g_object_get_qdata handle red-face-id + if qdata <> as handle! 0 [ + face: as red-object! qdata + values: object/get-values face + ] + values ] get-node-values: func [ @@ -107,25 +116,26 @@ get-face-handle: func [ as handle! int/value ] -get-widget-face-symbol: func [ - widget [handle!] - return: [integer!] +get-widget-symbol: func [ + widget [handle!] + return: [integer!] + /local + type [red-word!] + values [red-value!] +][ + values: get-face-values widget + type: as red-word! values + FACE_OBJ_TYPE + symbol/resolve type/symbol +] + +get-widget-data: func [ + widget [handle!] + return: [red-block!] /local - qdata [handle!] - face [red-object!] - type [red-word!] - sym [integer!] + values [red-value!] ][ - sym: -1 - qdata: g_object_get_qdata widget red-face-id - if qdata <> as handle! 0 [ - face: as red-object! qdata - if TYPE_OF(face) = TYPE_OBJECT [ - type: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - ] - ] - sym + values: get-face-values widget + as red-block! values + FACE_OBJ_DATA ] get-child-from-xy: func [ @@ -172,7 +182,7 @@ to-bgr: func [ ] free-handles: func [ - hWnd [integer!] + hWnd [handle!] /local values [red-value!] type [red-word!] @@ -221,7 +231,7 @@ init: func [][ ] set-selected-focus: func [ - hWnd [integer!] + hWnd [handle!] /local face [red-object!] values [red-value!] @@ -600,17 +610,17 @@ OS-make-view: func [ gtk_container_add widget container ] sym = panel [ - widget: gtk_fixed_new ; To be completed + widget: gtk_fixed_new unless null? caption [ buffer: gtk_label_new caption gtk_container_add widget buffer ] ] sym = tab-panel [ - widget: gtk_notebook_new ; To be completed - tabs/data: data + widget: gtk_notebook_new tabs/cur: 0 tabs/nb: block/rs-length? data + gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) ] sym = text-list [ widget: gtk_list_box_new @@ -644,7 +654,7 @@ OS-make-view: func [ sym <> window parent <> 0 ][ - p-sym: get-widget-face-symbol as handle! parent + p-sym: get-widget-symbol as handle! parent if widget2 = as handle! 0 [widget2: widget] case [ p-sym = panel [ @@ -655,7 +665,8 @@ OS-make-view: func [ p-sym = tab-panel [ container: as handle! parent ; widget is necessarily a panel and then same as widget2 - str: (as red-string! block/rs-head tabs/data) + tabs/cur + data: get-widget-data container + str: (as red-string! block/rs-head data) + tabs/cur caption: either TYPE_OF(str) = TYPE_STRING [ len: -1 unicode/to-utf8 str :len @@ -786,12 +797,12 @@ OS-destroy-view: func [ face [red-object!] empty? [logic!] /local - handle [integer!] + handle [handle!] values [red-value!] obj [red-object!] flags [integer!] ][ - handle: as-integer get-face-handle face + handle: get-face-handle face values: object/get-values face flags: get-flags as red-block! values + FACE_OBJ_FLAGS if flags and FACET_FLAGS_MODAL <> 0 [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 59f0913efc..6b0c10df2e 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -211,3 +211,24 @@ text-list-selected-rows-changed: func [ ] ] ] + +tab-panel-switch-page: func [ + [cdecl] + widget [handle!] + page [handle!] + idx [integer!] + ctx [node!] + /local + res [integer!] + text [c-string!] +][ + if idx >= 0 [ + res: make-event widget idx + 1 EVT_SELECT + set-selected widget ctx idx + 1 + text: gtk_notebook_get_tab_label_text widget page + set-text widget ctx text + if res = EVT_DISPATCH [ + make-event widget idx + 1 EVT_CHANGE + ] + ] +] From b74ca4a6d49e1a2a79ef78201a980667141ab77e Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 5 Aug 2017 14:03:03 +0200 Subject: [PATCH 0026/3432] Add some temporary modified tests --- tests/gtk3/align-test.red | 53 ++ tests/gtk3/group-box-test.red | 53 ++ tests/gtk3/react-test6.red | 28 ++ tests/gtk3/vid.red | 71 +++ tests/gtk3/view-test.red | 905 ++++++++++++++++++++++++++++++++++ 5 files changed, 1110 insertions(+) create mode 100644 tests/gtk3/align-test.red create mode 100644 tests/gtk3/group-box-test.red create mode 100644 tests/gtk3/react-test6.red create mode 100644 tests/gtk3/vid.red create mode 100644 tests/gtk3/view-test.red diff --git a/tests/gtk3/align-test.red b/tests/gtk3/align-test.red new file mode 100644 index 0000000000..d9707f2360 --- /dev/null +++ b/tests/gtk3/align-test.red @@ -0,0 +1,53 @@ +Red [ + Title: "Para/align testing script" + Author: "WiseGenius" + File: %align-test.red + Needs: 'View +] + +;system/view/debug?: true +txt: {Hello, World!^/I left this right to write it left.^M^/The quick brown fox jumps over the lazy dog.^M^/Χαῖρε, κόσμε!} +sze: 144x89 +view [ + group-box "label" [ + group-box [ + a1: area txt sze + f1: field txt sze + t1: text txt sze + ] + return + group-box "label" [ + text {align: } + r1: radio {none} [];p1/align: none] + r2: radio {left} [];p1/align: 'left] + r3: radio {center} [];p1/align: 'center] + r4: radio {right} [];p1/align: 'right] + return + c1: check {wrap?} [];p1/wrap?: face/data] + ] + ] + return + group-box [ + group-box [ + a2: area txt sze + f2: field txt sze + t2: text txt sze + ] + return + group-box [ + text {align: } + r5: radio {none} [];p2/align: none] + r6: radio {left} [];p2/align: 'left] + r7: radio {center} [];p2/align: 'center] + r8: radio {right} [];p2/align: 'right] + return + c2: check {wrap?} [];p2/wrap?: face/data] + ] + ] + do [ + ;a1/para: f1/para: t1/para: p1: make para! [align: 'right] + ;a2/para: f2/para: t2/para: p2: make para! [] + ;r4/data: on + ;r5/data: on + ] +] \ No newline at end of file diff --git a/tests/gtk3/group-box-test.red b/tests/gtk3/group-box-test.red new file mode 100644 index 0000000000..ce9bc6980b --- /dev/null +++ b/tests/gtk3/group-box-test.red @@ -0,0 +1,53 @@ +Red [ + Title: "Para/align testing script" + Author: "WiseGenius" + File: %align-test.red + Needs: 'View +] + +system/view/debug?: true +txt: {Hello, World!^/I left this right to write it left.^M^/The quick brown fox jumps over the lazy dog.^M^/Χαῖρε, κόσμε!} +sze: 144x89 +view [ + panel 300x30 "panel" + panel [ + a1: area txt sze + f1: field txt sze + t1: text txt sze + ] + return + ; group-box [ + ; text {align: } + ; r1: radio {none} [];p1/align: none] + ; r2: radio {left} [];p1/align: 'left] + ; r3: radio {center} [];p1/align: 'center] + ; r4: radio {right} [];p1/align: 'right] + ; return + ; c1: check {wrap?} [];p1/wrap?: face/data] + ; ] + ; ] + ; return + ;group-box [ + group-box [ + a2: area txt sze + f2: field txt sze + t2: text txt sze + ] + ; return + ; group-box [ + ; text {align: } + ; r5: radio {none} [];p2/align: none] + ; r6: radio {left} [];p2/align: 'left] + ; r7: radio {center} [];p2/align: 'center] + ; r8: radio {right} [];p2/align: 'right] + ; return + ; c2: check {wrap?} [];p2/wrap?: face/data] + ; ] + ; ] + do [ + ;a1/para: f1/para: t1/para: p1: make para! [align: 'right] + ;a2/para: f2/para: t2/para: p2: make para! [] + ;r4/data: on + ;r5/data: on + ] +] \ No newline at end of file diff --git a/tests/gtk3/react-test6.red b/tests/gtk3/react-test6.red new file mode 100644 index 0000000000..e6c7d523dc --- /dev/null +++ b/tests/gtk3/react-test6.red @@ -0,0 +1,28 @@ +Red [ + Title: "Red VID reactive test" + Author: "Nenad Rakocevic" + File: %react-test6.red + Needs: View +] + +view [ + style txt: text right + txt "Text" f: area 200x80 + font [name: "Comic Sans MS" size: 15 color: red] + return + + txt "Size in pixels" text "0x0" + react [[f/text f/font] face/text: form size-text f] + return + + txt "Font name" drop-list 120 + data ["Arial" "Consolas" "Comic Sans MS" "Times"] + react [f/font/name: pick face/data any [face/selected 3] print ["changed:" mold face/text]] + return + + txt "Font size" s: field "15" react [f/font/size: s/data] + button "+" bold 40 [s/data: s/data + 1] + button "-" bold 40 [s/data: max 1 s/data - 1] + return +] + diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red new file mode 100644 index 0000000000..eb8f5eefa8 --- /dev/null +++ b/tests/gtk3/vid.red @@ -0,0 +1,71 @@ +Red [ + Title: "Red VID simple test script" + Author: "Nenad Rakocevic" + File: %vid.red + Needs: 'View +] +system/view/debug?: no +view [ + title "VID test" + ;below + text "Hello" + button "Hello" 100x40 [bar/data: random 100%] + button "World" + return + + button "China" + text "Red Language" 100 right + field 120 on-enter [];probe do face/text clear face/text] + return + + group-box 3 [ + ;style but: button 25 font [name: "Comic Sans MS" size: 12 color: blue] + + base 0.233.1.177 "ok" 25x25 + text "in panel" + ;but "A" but "B" but "C" + ;but "D" but "E" but "F" + ] + tab-panel [ + "tab1" [at 10x10 base 0.2.233.188 15x15 at 50x50 button "one"] + "tab2" [at 80x10 text "two"] + ] on-change [print ["selected: " face/selected face/text lf]] + + below + slider 5% + pad 10x0 bar: progress 50% 130 + base 255.0.0.138 50x50 draw [fill-pen blue circle 25x25 15] + across + return middle + + check "option 1" font-size 14 + check "option 2" font-color orange + radio "option 3" font-name "Times New Roman" + radio "option 4" + return top + + list: text-list data ["one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four"] [print [pick face/data face/selected lf face/selected face/text lf] ] + drop-list data ["one" 4 "two" 5 "three" 6 "four" 7] + drop-down data ["one" "two" "three" "four"] + + return + + ; style but1: button + ; style txt1: text 30 + ; style base1: base 10x10 + + ; but1 "1" txt1 "1" base1 "1" + ; return + ; group-box [ + ; style but1: but1 font-color red + ; style txt1: txt1 red center + ; style base1: base1 red + + ; but1 "1" txt1 "1" base1 "1" + ; ] return + ; but1 "1" txt1 "1" base1 "1" + + ; at (list/offset + 130x50) base 5x5 red + + do [];append list/data "five" win: self] +] diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red new file mode 100644 index 0000000000..1f030c2971 --- /dev/null +++ b/tests/gtk3/view-test.red @@ -0,0 +1,905 @@ +Red [ + Purpose: "Test the GUI auto-update mode" + Needs: 'View +] + +system/view/debug?: yes +live?: system/view/auto-sync?: no + +workstation?: system/view/platform/product = 1 +os-version: system/view/platform/version + +#switch config/OS [ + Windows [ + print [ + "Windows" switch os-version [ + 10.0.0 [pick ["10" "10 Server" ] workstation?] + 6.3.0 [pick ["8.1" "Server 2012 R2"] workstation?] + 6.2.0 [pick ["8" "Server 2012" ] workstation?] + 6.1.0 [pick ["7" "Server 2008 R1"] workstation?] + 6.0.0 [pick ["Vista" "Server 2008" ] workstation?] + 5.2.0 [pick ["Server 2003" "Server 2003 R2"] workstation?] + 5.1.0 ["XP"] + 5.0.0 ["2000"] + ] + "build" system/view/platform/build + ] + ] + macOS [ + print [ + "macOS" switch os-version and 255.255.0 [ + 10.11.0 ["El Capitan"] + 10.10.0 ["Yosemite"] + 10.9.0 ["Mavericks"] + 10.8.0 ["Mountain Lion"] + 10.7.0 ["Lion"] + 10.6.0 ["Snow Leopard"] + ] os-version + "build" system/view/platform/build + ] + ] + default [] +] + +smiley: make image! [23x24 #{ +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC +CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 +444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 +8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C +E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 +4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 +DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F +949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 +736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 +F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C +F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 +E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 +171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 +ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 +211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A +E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 +ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 +CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 +3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE +F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 +E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 +5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE +F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 +514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 +ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 +6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD +5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 +3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 +F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC +A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 +8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC +736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E +56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 +DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 +00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 +0000000000000000000000000000000000FFFFFFFF0000000000000000000000 +000000000000000000FFFF000000000000000000000000000000000000000000 +FFFF000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +00000000000000FF000000000000000000000000000000000000000000FFFF00 +0000000000000000000000000000000000000000FFFFFF000000000000000000 +00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 +FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 +000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 +00FFFFFFFFFFFFFF +}] + +sub-win: make face! [ + type: 'window text: "Sub 1-View" offset: 200x200 size: 200x100 + pane: reduce [ + make face! [type: 'text text: "New window" offset: 10x10 size: 80x20 color: white] + make face! [ + type: 'button text: "Close" offset: 120x10 size: 60x20 + actors: object [ + on-click: func [face [object!] event [event!]][unview/all] + ] + ] + ] +] + +sub-win2: make face! [ + type: 'window text: "Sub 2-Show" offset: 200x200 size: 200x100 + pane: reduce [ + make face! [type: 'text text: "New window" offset: 10x10 size: 80x20 color: white] + make face! [ + type: 'button text: "Close" offset: 120x10 size: 60x20 + actors: object [ + on-click: func [face [object!] event [event!]][unview] + ] + ] + ] +] + +;; requires pane cursor to be moved back in closing event handler + +win: make face! [ + type: 'window text: "Red View" size: 1100x800 + menu: [ + ;popup ;-- forces context menu for window + "File" [ + "New" new + "Open... F1" open + "Close F2" close + --- + "Save..." save + "Save as..." save-as + "Save All" save-all + --- + "Print..." print + "Preview" preview + "Page Setup..." page-setup + --- + "Exit" exit + ] + "Edit" [ + "Undo" undo + "Redo" redo + --- + "Copy Ctrl+C" copy + "Cut Ctrl+X" cut + "Paste Ctrl+V" paste + --- + "Sub1" [ + "Sub-menu1" sub-m1 + ] + "Sub2" [ + "Sub-menu2" sub-m2 + ] + ] + "Search" [ + "Find..." find + "Find Next" find-next + "Find Previous" find-prev + --- + "Replace..." replace + "Replace Next" replace-next + ] + "Deep" [ + "Item 2" item2 + "Deep 2" [ + "Item 3" item3 + "Deep 3" [ + "End" end + ] + ] + ] + ] + actors: object [ + on-menu: func [face [object!] event [event!]][ + print ["menu selected:" event/picked] + switch event/picked [ + exit [ + print "calling unview" + unview/all + ] + sub-m1 [ + ;just to test change of a button's text.. + win/pane/1/text: "Hello" + show win/pane/1 + ] + ] + ] + on-close: func [face [object!] event [event!]][ + print "closing window" + ] + on-key: func [face [object!] event [event!]][ + if event/key = 'F5 [ + print "F5 key caught by window face!" + 'stop + ] + ] + ] +] + +canvas: make face! [ + type: 'base offset: 0x0 size: 300x200 color: silver + draw: [ + image smiley 10x30 + + line-cap round + pen red + line 10x10 130x190 80x40 150x100 + + pen blue + line-width 4 + line-join round + line 15x190 50x50 190x180 + + pen green + line-join miter + box 10x120 70x160 + + line-width 1 + pen maroon + fill-pen orange + box 150x80 180x120 + + fill-pen off + pen red + triangle 170x10 170x50 195x50 + + pen yellow fill-pen orange + line-width 5 + line-join bevel + polygon 120x130 120x190 180x130 180x190 + + line-width 1 + pen purple + fill-pen purple + box 220x10 280x70 10 + pen gray + fill-pen white + ellipse 240x20 20x40 + + fill-pen red + circle 250x150 49.5 + pen gray + fill-pen white + circle 250x150 40 + fill-pen red + circle 250x150 30 + fill-pen blue + circle 250x150 20 + pen blue + fill-pen white + polygon 232x144 245x144 250x130 255x144 268x144 + 257x153 260x166 250x158 239x166 243x153 + + font font-A + text 40x6 "Scroll Me with mouse wheel :-)" + + arc 100x25 80x80 0 90 closed + pen red + arc 100x25 50x80 30 90 + + curve 20x150 60x250 200x50 + curve 224x14 220x40 280x40 276x66 + ] +] + +but-extra: make face! [ + type: 'button text: "Extra" offset: 400x500 size: 40x25 + actors: object [ + on-click: func [face [object!] event [event!]][ ;-- `function` would prevent compilation here + tab-panel/data: ["file1" "file2"] + tab-panel/pane: reduce [ + make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'text text: "Panel File 1" offset: 90x40 size: 60x30 + ] + ] + ] + make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'text text: "Panel File 2" offset: 80x80 size: 60x30 + ] + ] + ] + ] + drop-down/data: ["1" 1 "2" 2 "3" 3 "4" 4] + unless live? [show [tab-panel drop-down]] + ] + ] +] + +panel-extra: make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'text text: "Panel 4" offset: 20x80 size: 60x30 + ] + ] +] + +button: make face! [ + type: 'button + text: "Hello" + offset: 100x10 + size: 60x40 + actors: object [ + on-click: function [face [object!] event [event!]][ + ;face/color: red + face/size: face/size + (5x5 - random 10x10) + face/offset: face/offset + (5x5 - random 10x10) + win/text: "Hello World" + probe type? reflect win/pane 'owned + + either pos: find win/pane but-extra [ + remove pos + remove skip tail win/menu/4 -2 + ][ + append win/pane but-extra + append win/menu/4 ["Inserted" inserted] + ] + unless live? [show win] + ] + ] +] + +button/font: make font! [ + name: "Comic Sans MS" + size: 16 + style: [bold italic underline strike] + anti-alias?: yes + color: red +] + +font-A: make font! [ + name: "Comic Sans MS" + size: 10 + color: blue + style: [bold italic underline] + anti-alias?: yes +] + +h-modes: [left center right center] +v-modes: [middle top middle bottom] + +win/pane: reduce [ + hi: make face! [ + type: 'button text: "Hi" offset: 10x10 size: 60x40 + para: make para! [align: 'left] + actors: object [ + on-click: func [face [object!] event [event!]][ + print "Testing error handling in awake event: 1 / 0" + probe 1 / 0 + ] + ] + ] + button + make face! [ + type: 'button text: "Change" offset: 180x10 size: 60x40 + actors: object [ + on-click: func [face [object!] event [event!]][ + clear back back tail drop-list/data + check-face/data: not check-face/data + remove at text-list/data 4 + insert at text-list/data 2 random "helloworld" + insert text-list/data/1 #"o" + unless "tab 4" = last tab-panel/data [ + append tab-panel/data "tab 4" + append tab-panel/pane panel-extra + ] + button/size/x: button/size/x - 1 + simple/color/2: random 255 + simple/color/3: random 255 + + if tail? h-modes: next h-modes [h-modes: head h-modes] + hi/para/align: h-modes/1 + + if tail? v-modes: next v-modes [v-modes: head v-modes] + hi/para/v-align: v-modes/1 + + unless live? [ + show [drop-list check-face text-list button simple tab-panel hi] + ] + print [{"Hello" size:} size-text button] + print [{"Base" size:} size-text base-face] + ] + ] + ] + make face! [ + type: 'check text: "Debug?" offset: 300x270 size: 80x24 + font: font-A + data: system/view/debug? + actors: object [ + on-change: func [face [object!] event [event!]][ + system/view/debug?: face/data + ] + ] + ] + make face! [ + type: 'check text: "Big/small font" offset: 300x300 size: 80x24 + data: yes + para: make para! [wrap?: yes] + actors: object [ + on-change: func [face [object!] event [event!]][ + button/font/size: pick [12 20] face/data + unless live? [show button] + ] + ] + ] + make face! [ + type: 'check text: "Italic?" offset: 300x330 size: 80x24 + data: yes + actors: object [ + on-change: function [face [object!] event [event!]][ + alter button/font/style 'italic + unless live? [show button] + ] + ] + ] + edit: make face! [ + type: 'field text: {unicode supported: $€𐐷𤭢} offset: 10x80 size: 160x24 + color: 255.218.18 + para: make para! [align: 'left] + actors: object [ + on-change: func [face [object!] event [event!]][ + print ["field changed:" mold face/text] + ] + ] + ] + make face! [ + type: 'area text: {Multiline area widget} offset: 580x24 size: 160x100 + font: font-A + actors: object [ + on-change: func [face [object!] event [event!]][ + print ["field changed:" mold face/text] + ] + ] + ] + simple: make face! [type: 'base offset: 200x50 size: 80x24 visible?: no color: red] + make face! [ + type: 'button text: "Show/Hide" offset: 200x80 size: 70x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + simple/visible?: not simple/visible? + unless live? [show simple] + ] + ] + ] + drop-down: make face! [ + type: 'drop-down + text: "type" + offset: 100x120 + size: 80x24 + font: font-A + color: 240.230.140 + data: [ + "option 1" 11 + "option 2" 22 + "option 3" 33 + ] + actors: object [ + on-select: func [face [object!] event [event!]][ + probe face/text + ] + on-change: func [face [object!] event [event!]][ + print ["changed:" mold face/text] + ] + ] + ] + drop-list: make face! [ + type: 'drop-list + offset: 200x120 + size: 80x24 + data: [ + "option 10" 110 + "option 20" 220 + "option 30" 330 + "option 40" 440 + "option 50" 550 + ] + actors: object [ + on-create: func [face [object!]][ + face/selected: 2 + ] + on-select: func [face [object!] event [event!]][ + print ["selected:" face/selected] + ] + on-change: func [face [object!] event [event!]][ + print ["changed:" face/selected] + ] + ] + ] + make face! [ + type: 'button text: "Set option 5" offset: 300x120 size: 80x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + drop-list/selected: 5 + unless live? [show drop-list] + ] + ] + ] + group: make face! [ + type: 'group-box text: "Group box" offset: 10x150 size: 180x150 + pane: reduce [ + make face! [type: 'button text: "Inside" offset: 20x20 size: 60x40] + set 'progress make face! [ + type: 'progress offset: 10x80 size: 120x16 + menu: [ + "Set to 0%" s0 + "Set to 25%" s25 + "Set to 50%" s50 + "Set to 100%" s100 + ] + actors: object [ + on-menu: func [face [object!] event [event!]][ + print ["context menu selected:" event/picked] + face/data: load append next form event/picked #"%" + unless live? [show face] + ] + ] + ] + set 'progress-text make face! [ + type: 'text text: "0" offset: 140x80 size: 30x16 color: white + ] + make face! [ + type: 'slider offset: 10x110 size: 120x24 + data: 50% + actors: object [ + on-create: func [face [object!]][ + on-change face none + ] + on-change: func [face [object!] event [event! none!]][ + ;print ["slider changed:" face/data] + progress/data: face/data + progress-text/text: form round to-percent face/data + unless live? [show [progress progress-text]] + ] + ] + ] + ] + ] + set 'progress2 make face! [ + type: 'progress offset: 200x170 size: 16x120 + ] + make face! [ + type: 'slider offset: 230x170 size: 24x120 + data: 25% + actors: object [ + on-create: func [face [object!]][ + on-change face none + ] + on-change: func [face [object!] event [event! none!]][ + print ["slider changed:" face/data] + progress2/data: face/data + unless live? [show progress2] + ] + ] + ] + + check-face: make face! [ + type: 'check text: "check box" offset: 300x170 size: 90x24 + data: on + actors: object [ + on-change: func [face [object!] event [event!]][ + probe face/data + ] + ] + ] + make face! [ + type: 'radio text: "radio 1" offset: 300x200 size: 90x24 + font: font-A + options: [drag-on: 'down] + ;data: on + actors: object [ + on-change: func [face [object!] event [event!]][ + print "radio 1 set" + ] + ] + ] + make face! [ + type: 'radio text: "radio 2" offset: 300x230 size: 90x24 + data: on + actors: object [ + on-change: func [face [object!] event [event!]][ + print "radio 2 set" + ] + ] + ] + make face! [ + type: 'base offset: 280x10 size: 100x100 + options: [drag-on: 'down] + image: load %../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png + ] + tab-panel: make face! [ + type: 'tab-panel offset: 10x320 size: 250x130 + data: [ + "tab 1" + "tab 2" + "tab 3" + ] + pane: reduce [ + make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'button text: "Panel 1" offset: 20x20 size: 60x30 + ] + ] + menu: [ + "Context menu 1" menu1 + "Context menu 2" menu2 + "Context menu 3" [ + "sub 1" sub1 + "sub 2" sub2 + ] + ] + actors: object [ + on-menu: func [face [object!] event [event!]][ + print ["context menu selected:" event/picked] + ] + ] + ] + make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'text text: "Panel 2" offset: 80x80 size: 60x30 + ] + ] + ] + make face! [ + type: 'panel + pane: reduce [ + make face! [ + type: 'text text: "Panel 3" offset: 90x40 size: 60x30 + ] + ] + ] + ] + actors: object [ + on-change: func [face [object!] event [event!]][ + print ["Switched to:" pick face/data event/picked] + ] + ] + ] + text-list: make face! [ + type: 'text-list offset: 400x20 size: 165x100 + font: font-A + data: [ + "Book 1" + "Book 2" + "Book 3" + "Book 4" + "Book 5" + "Red Programming Language" + "Red编程语言" + "FullStack Programming Language" + "全栈编程语言" + "hahahaha~" + "哈哈哈哈~" + ] + actors: object [ + on-select: func [face [object!] event [event!]][ + print ["text-list selected:" face/selected] + face/text: pick face/data face/selected + print ["text-list selected:" mold face/text] + ] + on-change: func [face [object!] event [event!]][ + print ["text-list changed:" face/selected] + face/text: pick face/data face/selected + print ["text-list changed:" mold face/text] + ] + ] + ] + set 'cam make face! [ + type: 'camera offset: 400x140 size: 320x240 + ] + cam-list: make face! [ + type: 'drop-list offset: 480x402 size: 160x32 + actors: object [ + on-create: func [face [object!]][ + face/data: cam/data + ] + on-change: func [face [object!] event [event!]][ + print ["changed:" face/selected] + unless cam/selected = face/selected [ + cam/selected: face/selected + ] + unless live? [show cam] + ] + ] + ] + make face! [ + type: 'button text: "Start/Stop" offset: 400x400 size: 70x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + either cam/selected [ + cam/selected: none + ][ + cam/selected: cam-list/selected + ] + unless live? [show cam] + ] + ] + ] + make face! [ + type: 'button text: "Sub-window" offset: 400x440 size: 70x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + view sub-win + ] + ] + ] + make face! [ + type: 'button text: "Sub-window 2" offset: 400x470 size: 70x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + show sub-win2 + ] + ] + ] + make face! [ + type: 'button text: "Quit" offset: 500x440 size: 60x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + print "calling unview" + unview/all + ] + ] + ] + make face! [ + type: 'button offset: 570x440 size: 38x38 + image: smiley + ] + make face! [ ;-- clip view for canvas + type: 'panel offset: 10x460 size: 300x200 + pane: reduce [canvas] + actors: object [ + on-wheel: func [face [object!] event [event!]][ + print [face/type event/picked] + canvas/offset/y: canvas/offset/y + event/picked + unless live? [show canvas] + ] + ] + ] + make face! [ + type: 'check text: "anti alias" offset: 265x430 size: 90x24 + data: on + actors: object [ + on-change: func [face [object!] event [event!]][ + either face/data = off [ + insert canvas/draw [anti-alias off] + ][ + remove/part canvas/draw 2 + ] + unless live? [show canvas] + ] + ] + ] + font-test: make face! [ + type: 'text text: "The quick brown fox jumps." offset: 500x500 size: 300x25 + font: make font! [ + name: "Times New Roman" + size: 16 + style: 'italic + anti-alias?: yes + ] + actors: object [ + on-over: func [face [object!] event [event!]][ + face/font/style: pick [italic bold] event/away? + tab-panel/selected: pick [1 2] event/away? + unless live? [show [face tab-panel]] + ] + ] + ] + dropped: make face! [ + type: 'base text: "Drop here" offset: 630x540 size: 80x80 + color: silver + draw: [font font-A text 35x30 "0"] + para: make para! [v-align: 'top] + ] + base-face: make face! [ + type: 'base text: "Base face" offset: 630x630 size: 80x80 + color: beige + font: make font! [ + name: "Times New Roman" + size: 16 + style: 'italic + anti-alias?: yes + ] + ] + make face! [ + type: 'button text: "Drag me" offset: 550x540 size: 70x24 + options: [drag-on: 'down] + actors: object [ + on-drag-start: func [face [object!] event [event!]][ + print "drag starts" + ;face/state/4: face/state/4 + 4x4 + ;face/offset: face/offset - 4x4 + ;unless live? [show face] + ] + on-drag: func [face [object!] event [event!]][ + prin dot + ] + on-drop: function [face [object!] event [event!]][ + print "dropping" + ;face/offset: face/offset + 4x4 + + pos: face/offset + face/state/4 ;-- calculate mouse position + if within? pos dropped/offset dropped/size [ + face/offset: 550x540 + dropped/draw/5: form 1 + to integer! dropped/draw/5 + unless live? [show [face dropped]] + ] + ] + ] + ] + make face! [ + type: 'base offset: 750x140 size: 300x300 color: silver + text: "Pinch me" + draw: [fill-pen red polygon 100x100 250x100 250x250 100x250] + actors: object [ + angle: 0 + center: 175x175 + sz: 75 + + on-zoom: func [face [object!] event [event!] /local factor new][ + if factor: event/picked [ + new: to integer! sz * factor + if new > 10 [ + sz: new + draw/4: center - as-pair sz sz + draw/5: center + (1x-1 * sz) + draw/6: center + as-pair sz sz + draw/7: center + (-1x1 * sz) + unless live? [show face] + ] + ] + ] + on-rotate: func [face [object!] event [event!]][ + probe "rotating" + ] + ] + ] +] + +append win/pane panel: make face! [ + type: 'panel + offset: 400x550 + size: 80x80 + pane: make block! 3 +] +repeat i 3 [ + append panel/pane make face! [ + type: 'base + size: 40x40 + offset: 10x10 * i + text: form i + color: red + (i * 50) + ] +] + +append win/pane make face! [ + type: 'button + text: "Reverse" + offset: 400x640 + size: 60x24 + actors: object [ + on-click: func [face [object!] event [event!]][ + reverse panel/pane + unless live? [show panel] + ] + ] +] + +dump-face win +view/flags win [resize] +system/view/debug?: no +system/view/auto-sync?: yes \ No newline at end of file From a5875e4904a4a44975bcc56d5ea859fa8f72cde6 Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 7 Aug 2017 10:42:02 +0200 Subject: [PATCH 0027/3432] Refactoring code + scrollview for area + first attempt to signal for field --- modules/view/backends/gtk3/gtk.reds | 23 +++++++++++++++++++++++ modules/view/backends/gtk3/gui.reds | 19 ++++++++++++------- modules/view/backends/gtk3/handlers.reds | 21 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a089207100..1d13aa4127 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -35,6 +35,21 @@ tagSIZE: alias struct! [ height [integer!] ] +GdkEventKey!: alias struct! [ + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + state [integer!] + keyval [integer!] + length [integer!] + string [c-string!] + keycode [integer!] ;-- keycode & group & is_modifier + ;guint16 hardware_keycode; + ;guint8 group; + ;guint is_modifier : 1; +] + #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" ;#define LIBGLIB-file "libglib-2.0-0.dll" @@ -191,6 +206,14 @@ tagSIZE: alias struct! [ width [integer!] height [integer!] ] + gtk_widget_set_can_focus: "gtk_widget_set_can_focus" [ + widget [handle!] + focus [logic!] + ] + gtk_widget_set_focus_on_click: "gtk_widget_set_focus_on_click" [ + widget [handle!] + focus [logic!] + ] gtk_container_add: "gtk_container_add" [ container [handle!] widget [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 695fee16ba..5a9c6c87be 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -593,6 +593,12 @@ OS-make-view: func [ widget: gtk_entry_new buffer: gtk_entry_get_buffer widget gtk_entry_buffer_set_text buffer caption -1 + gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) + ;gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) + gtk_widget_set_can_focus widget yes + ;This depends on version >= 3.2 + ;gtk_widget_set_focus_on_click widget yes + gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) ] sym = progress [ widget: gtk_progress_bar_new @@ -601,6 +607,8 @@ OS-make-view: func [ widget: gtk_text_view_new buffer: gtk_text_view_get_buffer widget gtk_text_buffer_set_text buffer caption -1 + widget2: gtk_scrolled_window_new null null + gtk_container_add widget2 widget ] sym = group-box [ widget: gtk_frame_new caption @@ -656,12 +664,8 @@ OS-make-view: func [ ][ p-sym: get-widget-symbol as handle! parent if widget2 = as handle! 0 [widget2: widget] + ; TODO: case to replace with either if no more choice case [ - p-sym = panel [ - container: as handle! parent - gtk_widget_set_size_request widget2 size/x size/y - gtk_fixed_put as handle! container widget2 offset/x offset/y - ] p-sym = tab-panel [ container: as handle! parent ; widget is necessarily a panel and then same as widget2 @@ -679,9 +683,10 @@ OS-make-view: func [ if tabs/cur = tabs/nb [tabs/cur: 0 tabs/nb: 0] ] true [ - container: gtk_container_get_children as handle! parent + container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] gtk_widget_set_size_request widget2 size/x size/y - gtk_fixed_put as handle! container/value widget2 offset/x offset/y + gtk_fixed_put container widget2 offset/x offset/y + print ["x: " offset/x "y: " offset/y "w: " size/x "h: " size/y lf] ] ] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6b0c10df2e..72b2b2c7bf 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -232,3 +232,24 @@ tab-panel-switch-page: func [ ] ] ] + +; Do not use key-press-event since character would not be printed! +field-key-release-event: func [ + [cdecl] + widget [handle!] + event-key [GdkEventKey!] + ctx [node!] +][ + print "key-release: " + print-line event-key/keyval + +] + +field-move-focus: func [ + [cdecl] + widget [handle!] + event [handle!] + ctx [node!] +][ + print-line "move-focus" +] From 7886ddae46c1a0f0c7b352da58fc0e7eeb6f7e66 Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 15 Aug 2017 07:28:29 +0200 Subject: [PATCH 0028/3432] Fix critical messages + early development on request-file --- modules/view/backends/gtk3/comdlgs.reds | 62 ++++++++++++++++++++++- modules/view/backends/gtk3/gtk.reds | 64 +++++++++++++++++++++++- modules/view/backends/gtk3/gui.reds | 22 ++++---- modules/view/backends/gtk3/handlers.reds | 2 +- 4 files changed, 135 insertions(+), 15 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 5d4c105959..1514b2b29b 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -9,6 +9,56 @@ Red/System [ See https://github.com/red/red/blob/master/BSL-License.txt } ] +_request-file: func [ + title [red-string!] + path [red-file!] + filter [red-block!] + save? [logic!] + multi? [logic!] + dir? [logic!] + return: [red-value!] + /local + window [handle!] + widget [handle!] + resp [integer!] + cstr [c-string!] + size [integer!] + str [red-string!] + ret [red-value!] +][ + ret: as red-value! none-value + window: gtk_window_new GTKApp + ;print "GTKApp" + ;if GTKApp = (as handle! 0) [print " not"] + ;print [" alive" lf] + widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" 5 "Open" 2 null] + ;gtk_application_add_window GTKApp window + ;gtk_window_set_modal widget yes + ;gtk_window_set_transient_for widget window + ;gtk_window_set_destroy_with_parent widget yes + + ;gobj_signal_connect(widget "response" :dialog-response-clicked null); + resp: gtk_dialog_run widget + print ["resp: " resp lf] + if resp = 2 [ + cstr: gtk_file_chooser_get_filename widget + size: length? cstr + print ["Selected file: " cstr lf] + str: string/load cstr size UTF-8 + ;unicode/load-utf8-stream cstr size str null + ret: as red-value! str + set-type ret TYPE_FILE + ] + ;gtk_window_iconify widget + ;gtk_application_remove_window GTKApp window + ;gtk_window_close widget + ;gtk_window_close window + gtk_widget_destroy widget + ;gtk_widget_destroy window + ;as red-value! none-value + ret +] + OS-request-dir: func [ title [red-string!] dir [red-file!] @@ -17,7 +67,15 @@ OS-request-dir: func [ multi? [logic!] return: [red-value!] ][ - as red-value! none-value + _request-file title dir filter keep? multi? yes +] + +dialog-response-clicked: func [ + [cdecl] + widget [handle!] + ctx [node!] +][ + gtk_widget_destroy widget ] OS-request-file: func [ @@ -28,5 +86,5 @@ OS-request-file: func [ multi? [logic!] return: [red-value!] ][ - as red-value! none-value + _request-file title name filter save? multi? no ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 1d13aa4127..bf1e56ce31 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -49,6 +49,12 @@ GdkEventKey!: alias struct! [ ;guint8 group; ;guint is_modifier : 1; ] +#enum GtkFileChooserAction! [ + GTK_FILE_CHOOSER_ACTION_OPEN + GTK_FILE_CHOOSER_ACTION_SAVE + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER +] #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" @@ -171,6 +177,38 @@ GdkEventKey!: alias struct! [ app [handle!] return: [handle!] ] + gtk_application_add_window: "gtk_application_add_window" [ + app [handle!] + window [handle!] + ] + gtk_application_remove_window: "gtk_application_remove_window" [ + app [handle!] + window [handle!] + ] + gtk_file_chooser_dialog_new: "gtk_file_chooser_dialog_new" [ + [variadic] + return: [handle!] + ] + gtk_dialog_run: "gtk_dialog_run" [ + widget [handle!] + return: [integer!] + ] + gtk_file_chooser_get_filename: "gtk_file_chooser_get_filename" [ + widget [handle!] + return: [c-string!] + ] + ; gtk_file_chooser_native_new: "gtk_file_chooser_native_new" [ + ; [variadic] + ; return: [handle!] + ; ] + ; gtk_native_dialog_run: "gtk_native_dialog_run" [ + ; widget [handle!] + ; return: [integer!] + ; ] + gtk_window_new: "gtk_window_new" [ + type [integer!] + return: [handle!] + ] gtk_window_set_title: "gtk_window_set_title" [ window [handle!] title [c-string!] @@ -192,11 +230,32 @@ GdkEventKey!: alias struct! [ window [handle!] return: [logic!] ] + gtk_window_set_modal: "gtk_window_set_modal" [ + window [handle!] + setting [logic!] + ] + gtk_window_set_transient_for: "gtk_window_set_transient_for" [ + window [handle!] + parent [handle!] + ] + gtk_window_iconify: "gtk_window_iconify" [ + window [handle!] + ] + gtk_window_close: "gtk_window_close" [ + window [handle!] + ] + gtk_window_set_destroy_with_parent: "gtk_window_set_destroy_with_parent" [ + window [handle!] + setting [logic!] + ] gtk_widget_queue_draw: "gtk_widget_queue_draw" [ widget [handle!] ] gtk_widget_show_all: "gtk_widget_show_all" [ - window [handle!] + widget [handle!] + ] + gtk_widget_hide: "gtk_widget_hide" [ + widget [handle!] ] gtk_widget_grab_focus: "gtk_widget_grab_focus" [ widget [handle!] @@ -214,6 +273,9 @@ GdkEventKey!: alias struct! [ widget [handle!] focus [logic!] ] + gtk_widget_destroy: "gtk_widget_destroy" [ + widget [handle!] + ] gtk_container_add: "gtk_container_add" [ container [handle!] widget [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5a9c6c87be..cb4f9beb65 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -508,7 +508,7 @@ OS-make-view: func [ caption [c-string!] len [integer!] widget [handle!] - widget2 [handle!] + _widget [handle!] buffer [handle!] container [handle!] value [integer!] @@ -518,7 +518,7 @@ OS-make-view: func [ values: object/get-values face - widget2: as handle! 0; widget version with possible scrollview + _widget: as handle! 0; widget version with possible scrollview type: as red-word! values + FACE_OBJ_TYPE str: as red-string! values + FACE_OBJ_TEXT @@ -592,7 +592,7 @@ OS-make-view: func [ sym = field [ widget: gtk_entry_new buffer: gtk_entry_get_buffer widget - gtk_entry_buffer_set_text buffer caption -1 + unless null? caption [gtk_entry_buffer_set_text buffer caption -1] gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) ;gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) gtk_widget_set_can_focus widget yes @@ -607,8 +607,8 @@ OS-make-view: func [ widget: gtk_text_view_new buffer: gtk_text_view_get_buffer widget gtk_text_buffer_set_text buffer caption -1 - widget2: gtk_scrolled_window_new null null - gtk_container_add widget2 widget + _widget: gtk_scrolled_window_new null null + gtk_container_add _widget widget ] sym = group-box [ widget: gtk_frame_new caption @@ -634,8 +634,8 @@ OS-make-view: func [ widget: gtk_list_box_new init-text-list widget data gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 - widget2: gtk_scrolled_window_new null null - gtk_container_add widget2 widget + _widget: gtk_scrolled_window_new null null + gtk_container_add _widget widget gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) ] any [ @@ -663,12 +663,12 @@ OS-make-view: func [ parent <> 0 ][ p-sym: get-widget-symbol as handle! parent - if widget2 = as handle! 0 [widget2: widget] + if _widget = as handle! 0 [_widget: widget] ; TODO: case to replace with either if no more choice case [ p-sym = tab-panel [ container: as handle! parent - ; widget is necessarily a panel and then same as widget2 + ; widget is necessarily a panel and then same as _widget data: get-widget-data container str: (as red-string! block/rs-head data) + tabs/cur caption: either TYPE_OF(str) = TYPE_STRING [ @@ -684,8 +684,8 @@ OS-make-view: func [ ] true [ container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] - gtk_widget_set_size_request widget2 size/x size/y - gtk_fixed_put container widget2 offset/x offset/y + gtk_widget_set_size_request _widget size/x size/y + gtk_fixed_put container _widget offset/x offset/y print ["x: " offset/x "y: " offset/y "w: " size/x "h: " size/y lf] ] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 72b2b2c7bf..48a9dc9242 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -200,7 +200,7 @@ text-list-selected-rows-changed: func [ ][ ; From now, only single-selection mode sel: gtk_list_box_get_selected_row widget - idx: gtk_list_box_row_get_index sel + idx: either null? sel [-1][gtk_list_box_row_get_index sel] if idx >= 0 [ res: make-event widget idx + 1 EVT_SELECT set-selected widget ctx idx + 1 From 8a7135b336a65abdd659045a13fe68f3fa119b42 Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 15 Aug 2017 08:06:50 +0200 Subject: [PATCH 0029/3432] Bad line --- modules/view/backends/gtk3/comdlgs.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 1514b2b29b..907d960362 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -27,7 +27,7 @@ _request-file: func [ ret [red-value!] ][ ret: as red-value! none-value - window: gtk_window_new GTKApp + ;window: gtk_window_new GTKApp ;print "GTKApp" ;if GTKApp = (as handle! 0) [print " not"] ;print [" alive" lf] From 78f0e64f3eb7769bec630b6a1fba9ba50634929b Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 15 Aug 2017 09:16:48 +0200 Subject: [PATCH 0030/3432] First version of request-file request-dir working also inside red-console --- modules/view/backends/gtk3/comdlgs.reds | 32 ++++--------------------- modules/view/backends/gtk3/gtk.reds | 6 +++++ 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 907d960362..c05aa87ef7 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -9,6 +9,7 @@ Red/System [ See https://github.com/red/red/blob/master/BSL-License.txt } ] + _request-file: func [ title [red-string!] path [red-file!] @@ -27,35 +28,18 @@ _request-file: func [ ret [red-value!] ][ ret: as red-value! none-value - ;window: gtk_window_new GTKApp - ;print "GTKApp" - ;if GTKApp = (as handle! 0) [print " not"] - ;print [" alive" lf] widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" 5 "Open" 2 null] - ;gtk_application_add_window GTKApp window - ;gtk_window_set_modal widget yes - ;gtk_window_set_transient_for widget window - ;gtk_window_set_destroy_with_parent widget yes - - ;gobj_signal_connect(widget "response" :dialog-response-clicked null); resp: gtk_dialog_run widget - print ["resp: " resp lf] if resp = 2 [ cstr: gtk_file_chooser_get_filename widget size: length? cstr - print ["Selected file: " cstr lf] str: string/load cstr size UTF-8 - ;unicode/load-utf8-stream cstr size str null - ret: as red-value! str + ret: as red-value! str set-type ret TYPE_FILE ] - ;gtk_window_iconify widget - ;gtk_application_remove_window GTKApp window - ;gtk_window_close widget - ;gtk_window_close window gtk_widget_destroy widget - ;gtk_widget_destroy window - ;as red-value! none-value + ; This trick really matters to end the loop when in the red-console + while [gtk_events_pending][gtk_main_iteration] ret ] @@ -70,14 +54,6 @@ OS-request-dir: func [ _request-file title dir filter keep? multi? yes ] -dialog-response-clicked: func [ - [cdecl] - widget [handle!] - ctx [node!] -][ - gtk_widget_destroy widget -] - OS-request-file: func [ title [red-string!] name [red-file!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index bf1e56ce31..0ad9667930 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -205,6 +205,12 @@ GdkEventKey!: alias struct! [ ; widget [handle!] ; return: [integer!] ; ] + gtk_main_iteration: "gtk_main_iteration" [ + return: [logic!] + ] + gtk_events_pending: "gtk_events_pending" [ + return: [logic!] + ] gtk_window_new: "gtk_window_new" [ type [integer!] return: [handle!] From 5d3ab1e6ba0298bfdcb836b1e5b6506665abfe09 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 16 Aug 2017 19:23:02 +0200 Subject: [PATCH 0031/3432] font as css (first attempt) + preparation for change-* react-test.red seems to work --- modules/view/backends/gtk3/comdlgs.reds | 3 +- modules/view/backends/gtk3/font.reds | 116 +++++- modules/view/backends/gtk3/gtk.reds | 16 +- modules/view/backends/gtk3/gui.reds | 472 +++++++++++++++++++++++- modules/view/backends/gtk3/style.reds | 25 +- 5 files changed, 609 insertions(+), 23 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index c05aa87ef7..d20ca1311a 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -34,12 +34,13 @@ _request-file: func [ cstr: gtk_file_chooser_get_filename widget size: length? cstr str: string/load cstr size UTF-8 + if dir? [string/append-char GET_BUFFER(str) as-integer #"/"] ret: as red-value! str set-type ret TYPE_FILE ] gtk_widget_destroy widget ; This trick really matters to end the loop when in the red-console - while [gtk_events_pending][gtk_main_iteration] + while [gtk_events_pending][gtk_main_iteration] ret ] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 3610be9aaa..dd6c74c11f 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -10,14 +10,128 @@ Red/System [ } ] +;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget + make-font: func [ face [red-object!] font [red-object!] return: [handle!] + /local + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + css [c-string!] + color [red-tuple!] + rgba [c-string!] + hFont [handle!] + int [red-integer!] ][ - null + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + css: g_strdup_printf ["* {"] + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + css: g_strdup_printf [{%s font-family: "%s";} css name] + ] + + if TYPE_OF(size) = TYPE_INTEGER [ + css: add-to-string css "%s font-size: %dpt;" as handle! size/value + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ ;OLD -> class: case [ + sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold;" css]] + sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] + sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration-line: underline;" css]] + sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration-line: line-through;" css]] + true [""] + ] + style: style + 1 + ] + ] + + if TYPE_OF(color) = TYPE_TUPLE [ + rgba: to-css-rgba color + css: add-to-string css "%s color: %s;" as handle! rgba + g_free as handle! rgba + ] + + css: add-to-string css "%s}" null + + ;print ["css: " css lf] + + hFont: as handle! css + + blk: as red-block! values + FONT_OBJ_STATE + either TYPE_OF(blk) <> TYPE_BLOCK [ + block/make-at blk 2 + handle/make-in blk as-integer hFont + ][ + int: as red-integer! block/rs-head blk + int/header: TYPE_HANDLE + int/value: as-integer hFont + ] + + if face <> null [ + blk: block/make-at as red-block! values + FONT_OBJ_PARENT 4 + block/rs-append blk as red-value! face + ] + +; ] + hFont +] + +; Here, style provider is used as font provider +make-font-provider: func [ + widget [handle!] + /local + style [handle!] + provider [handle!] +][ + provider: gtk_css_provider_new + style: gtk_widget_get_style_context widget + + gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + + g_object_set_qdata widget gtk-style-id provider ] +get-font-provider: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget gtk-style-id +] + + + get-font-handle: func [ font [red-object!] return: [handle!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 0ad9667930..7c875439b7 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -85,6 +85,12 @@ GdkEventKey!: alias struct! [ quark [integer!] return: [int-ptr!] ] + g_object_set: "g_object_set" [ + [variadic] + ] + g_object_get: "g_object_get" [ + [variadic] + ] g_signal_connect_data: "g_signal_connect_data" [ instance [int-ptr!] signal [c-string!] @@ -383,9 +389,13 @@ GdkEventKey!: alias struct! [ return: [handle!] ] gtk_label_get_text: "gtk_label_get_text" [ - label [handle!] + widget [handle!] return: [c-string!] ] + gtk_label_set_text: "gtk_label_set_text" [ + widget [handle!] + label [c-string!] + ] gtk_entry_new: "gtk_entry_new" [ return: [handle!] ] @@ -436,6 +446,10 @@ GdkEventKey!: alias struct! [ text [c-string!] len [integer!] ] + gtk_text_buffer_create_tag: "gtk_text_buffer_create_tag" [ + [variadic] + return: [handle!] + ] gtk_combo_box_text_new: "gtk_combo_box_text_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index cb4f9beb65..596dbf1882 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -13,12 +13,12 @@ Red/System [ #include %gtk.reds #include %events.reds +#include %style.reds #include %font.reds #include %para.reds #include %draw.reds #include %handlers.reds -#include %style.reds #include %comdlgs.reds GTKApp: as handle! 0 @@ -230,6 +230,446 @@ init: func [][ style-init ] + +change-rate: func [ + hWnd [handle!] + rate [red-value!] + /local + int [red-integer!] + tm [red-time!] + timer [integer!] + ts [float!] +][ + ; timer: objc_getAssociatedObject hWnd RedTimerKey + + ; if timer <> 0 [ ;-- cancel a preexisting timer + ; objc_msgSend [timer sel_getUid "invalidate"] + ; objc_setAssociatedObject hWnd RedTimerKey 0 OBJC_ASSOCIATION_ASSIGN + ; ] + + ; switch TYPE_OF(rate) [ + ; TYPE_INTEGER [ + ; int: as red-integer! rate + ; if int/value <= 0 [fire [TO_ERROR(script invalid-facet-type) rate]] + ; ts: 1.0 / as-float int/value + ; ] + ; TYPE_TIME [ + ; tm: as red-time! rate + ; if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] + ; ts: tm/time / 1E9 + ; ] + ; TYPE_NONE [exit] + ; default [fire [TO_ERROR(script invalid-facet-type) rate]] + ; ] + + ; timer: objc_msgSend [ + ; objc_getClass "NSTimer" + ; sel_getUid "scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:" + ; ts hWnd sel-on-timer 0 yes + ; ] + ; objc_setAssociatedObject hWnd RedTimerKey timer OBJC_ASSOCIATION_ASSIGN + 0 +] + +change-size: func [ + hWnd [handle!] + size [red-pair!] + type [integer!] + /local + h [integer!] + w [integer!] + y [integer!] + x [integer!] + ;rc [NSRect!] + ;frame [NSRect!] + saved [int-ptr!] + method [integer!] +][ + ; rc: make-rect size/x size/y 0 0 + ; if all [type = button size/y > 32][ + ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" NSRegularSquareBezelStyle] + ; ] + ; either type = window [ + ; x: 0 + ; frame: as NSRect! :x + ; method: sel_getUid "frame" + ; saved: system/stack/align + ; push 0 + ; push method push hWnd push frame + ; objc_msgSend_stret 3 + ; system/stack/top: saved + ; frame/y: frame/y + frame/h - rc/y + ; objc_msgSend [hWnd sel_getUid "setFrame:display:animate:" frame/x frame/y rc/x rc/y yes yes] + ; ][ + ; objc_msgSend [hWnd sel_getUid "setFrameSize:" rc/x rc/y] + ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] + ; object_getInstanceVariable hWnd IVAR_RED_DATA :type + ; if type = caret [ + ; caret-w: rc/x + ; caret-h: rc/y + ; ] + ; ] + 0 +] + +change-image: func [ + hWnd [integer!] + image [red-image!] + type [integer!] + /local + id [integer!] +][ + ; case [ + ; type = camera [ + ; snap-camera hWnd + ; until [TYPE_OF(image) = TYPE_IMAGE] ;-- wait + ; ] + ; any [type = button type = check type = radio][ + ; if TYPE_OF(image) <> TYPE_IMAGE [ + ; objc_msgSend [hWnd sel_getUid "setImage:" 0] + ; exit + ; ] + ; id: objc_msgSend [objc_getClass "NSImage" sel_getUid "alloc"] + ; id: objc_msgSend [id sel_getUid "initWithCGImage:size:" OS-image/to-cgimage image 0 0] + ; objc_msgSend [hWnd sel_getUid "setImage:" id] + ; objc_msgSend [id sel_getUid "release"] + ; ] + ; true [ + ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] + ; ] + ; ] + 0 +] + +change-color: func [ + hWnd [integer!] + color [red-tuple!] + type [integer!] + /local + clr [integer!] + set? [logic!] + t [integer!] +][ + t: TYPE_OF(color) + if all [t <> TYPE_NONE t <> TYPE_TUPLE][exit] + ; if transparent-color? color [ + ; objc_msgSend [hWnd sel_getUid "setDrawsBackground:" no] + ; exit + ; ] + ; set?: yes + case [ + ; type = area [ + ; hWnd: objc_msgSend [hWnd sel_getUid "documentView"] + ; clr: either t = TYPE_NONE [00FFFFFFh][color/array1] + ; set-caret-color hWnd clr + ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] + ; ] + type = text [ + ; if t = TYPE_NONE [ + ; clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "controlColor"] + ; set?: no + ; ] + ; objc_msgSend [hWnd sel_getUid "setDrawsBackground:" set?] + ] + ; any [type = check type = radio][ + ; hWnd: objc_msgSend [hWnd sel_getUid "cell"] + ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "controlColor"]] + ; ] + ; type = field [ + ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] + ; ] + ; type = window [ + ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "windowBackgroundColor"]] + ; ] + ; true [ + ; set?: no + ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] + ; ] + ] + ; if set? [ + ; if t = TYPE_TUPLE [clr: to-NSColor color] + ; objc_msgSend [hWnd sel_getUid "setBackgroundColor:" clr] + ; ] + 0 +] + +update-z-order: func [ + parent [integer!] + pane [red-block!] + type [integer!] + /local + face [red-object!] + tail [red-object!] + hWnd [handle!] + parr [int-ptr!] + arr [integer!] + nb [integer!] + s [series!] +][ + ; s: GET_BUFFER(pane) + ; face: as red-object! s/offset + pane/head + ; tail: as red-object! s/tail + ; nb: (as-integer tail - face) >> 4 + + ; parr: as int-ptr! allocate nb * 4 + ; nb: 0 + ; while [face < tail][ + ; if TYPE_OF(face) = TYPE_OBJECT [ + ; hWnd: face-handle? face + ; if hWnd <> null [ + ; nb: nb + 1 + ; parr/nb: as-integer hWnd + ; ] + ; ] + ; face: face + 1 + ; ] + ; arr: objc_msgSend [ + ; objc_getClass "NSArray" + ; sel_getUid "arrayWithObjects:count:" + ; parr nb + ; ] + ; free as byte-ptr! parr + ; if type = window [parent: objc_msgSend [parent sel_getUid "contentView"]] + ; objc_msgSend [parent sel_getUid "setSubviews:" arr] +0 +] + +change-font: func [ + hWnd [handle!] + face [red-object!] + font [red-object!] + type [integer!] + return: [logic!] + /local + css [c-string!] + provider [handle!] +][ + if TYPE_OF(font) <> TYPE_OBJECT [return no] + + provider: get-font-provider hWnd + + css: as c-string! make-font face font + + gtk_css_provider_load_from_data provider css -1 null + + yes +] + +change-offset: func [ + hWnd [handle!] + pos [red-pair!] + type [integer!] + ;/local + ;rc [NSRect!] +][ + ; rc: make-rect pos/x pos/y 0 0 + ; either type = window [ + ; rc/y: as float32! screen-size-y - pos/y + ; objc_msgSend [hWnd sel_getUid "setFrameTopLeftPoint:" rc/x rc/y] + ; ][ + ; objc_msgSend [hWnd sel_getUid "setFrameOrigin:" rc/x rc/y] + ; unless in-composition? [ + ; object_getInstanceVariable hWnd IVAR_RED_DATA :type + ; if type = caret [ + ; caret-x: rc/x + ; caret-y: rc/y + ; ] + ; ] + ; ] + 0 +] + +change-visible: func [ + hWnd [integer!] + show? [logic!] + type [integer!] +][ + ; case [ + ; any [type = button type = check type = radio][ + ; objc_msgSend [hWnd sel_getUid "setEnabled:" show?] + ; objc_msgSend [hWnd sel_getUid "setTransparent:" not show?] + ; ] + ; type = window [ + ; either show? [ + ; objc_msgSend [hWnd sel_getUid "makeKeyAndOrderFront:" hWnd] + ; ][ + ; objc_msgSend [hWnd sel_getUid "orderOut:" hWnd] + ; ] + ; ] + ; true [objc_msgSend [hWnd sel_getUid "setHidden:" not show?]] + ; ] + 0 +] + +change-enabled: func [ + hWnd [integer!] + enabled? [logic!] + type [integer!] + /local + obj [integer!] +][ + ; unless any [type = base type = window type = panel][ + ; objc_msgSend [hWnd sel_getUid "setEnabled:" enabled?] + ; ] + ; either enabled? [obj: 0][obj: hWnd] + ; objc_setAssociatedObject hWnd RedEnableKey obj OBJC_ASSOCIATION_ASSIGN +0 +] + +change-text: func [ + hWnd [handle!] + values [red-value!] + face [red-object!] + type [integer!] + /local + len [integer!] + cstr [c-string!] + str [red-string!] +][ + ; if type = base [ + ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] + ; exit + ; ] + + str: as red-string! values + FACE_OBJ_TEXT + cstr: switch TYPE_OF(str) [ + TYPE_STRING [len: -1 unicode/to-utf8 str :len] + TYPE_NONE [""] + default [null] ;@@ Auto-convert? + ] + + if null? cstr [exit] + + either type = area [ + ; objc_msgSend [ + ; objc_msgSend [hWnd sel_getUid "documentView"] + ; sel_getUid "setString:" txt + 0 + ; ] + ][ + ;unless change-font hWnd face as red-object! values + FACE_OBJ_FONT type [ + case [ + type = text [ + gtk_label_set_text hWnd cstr + ;objc_msgSend [hWnd sel_getUid "setStringValue:" txt] + ] + any [type = button type = radio type = check type = window type = group-box][ + ;objc_msgSend [hWnd sel_getUid "setTitle:" txt] + ] + true [0] + ] + ;] + ] +] + +change-data: func [ + hWnd [handle!] + values [red-value!] + /local + data [red-value!] + word [red-word!] + size [red-pair!] + f [red-float!] + str [red-string!] + caption [c-string!] + type [integer!] + len [integer!] +][ + data: as red-value! values + FACE_OBJ_DATA + word: as red-word! values + FACE_OBJ_TYPE + type: word/symbol + + ; case [ + ; all [ + ; type = progress + ; TYPE_OF(data) = TYPE_PERCENT + ; ][ + ; f: as red-float! data + ; objc_msgSend [hWnd sel_getUid "setDoubleValue:" f/value * 100.0] + ; ] + ; all [ + ; type = slider + ; TYPE_OF(data) = TYPE_PERCENT + ; ][ + ; f: as red-float! data + ; size: as red-pair! values + FACE_OBJ_SIZE + ; len: either size/x > size/y [size/x][size/y] + ; objc_msgSend [hWnd sel_getUid "setDoubleValue:" f/value * (as-float len)] + ; ] + ; type = check [ + ; set-logic-state hWnd as red-logic! data yes + ; ] + ; type = radio [ + ; set-logic-state hWnd as red-logic! data no + ; ] + ; type = tab-panel [ + ; set-tabs hWnd get-face-values hWnd + ; ] + ; all [ + ; type = text-list + ; TYPE_OF(data) = TYPE_BLOCK + ; ][ + ; objc_msgSend [objc_msgSend [hWnd sel_getUid "documentView"] sel_getUid "reloadData"] + ; ] + ; any [type = drop-list type = drop-down][ + ; init-combo-box hWnd as red-block! data null type = drop-list + ; ] + ; true [0] ;-- default, do nothing + ; ] + 0 +] + +change-selection: func [ + hWnd [handle!] + int [red-integer!] ;-- can be also none! | object! + type [integer!] + /local + idx [integer!] + sz [integer!] + wnd [integer!] +][ + ; if type <> window [ + ; idx: either TYPE_OF(int) = TYPE_INTEGER [int/value - 1][-1] + ; if idx < 0 [exit] ;-- @@ should unselect the items ? + ; ] + ; case [ + ; type = camera [ + ; either TYPE_OF(int) = TYPE_NONE [ + ; toggle-preview hWnd false + ; ][ + ; select-camera hWnd idx + ; toggle-preview hWnd true + ; ] + ; ] + ; type = text-list [ + ; hWnd: objc_msgSend [hWnd sel_getUid "documentView"] + ; sz: -1 + objc_msgSend [hWnd sel_getUid "numberOfRows"] + ; if any [sz < 0 sz < idx][exit] + ; idx: objc_msgSend [objc_getClass "NSIndexSet" sel_getUid "indexSetWithIndex:" idx] + ; objc_msgSend [ + ; hWnd sel_getUid "selectRowIndexes:byExtendingSelection:" idx no + ; ] + ; objc_msgSend [idx sel_getUid "release"] + ; ] + ; any [type = drop-list type = drop-down][ + ; sz: -1 + objc_msgSend [hWnd sel_getUid "numberOfItems"] + ; if any [sz < 0 sz < idx][exit] + ; objc_msgSend [hWnd sel_getUid "selectItemAtIndex:" idx] + ; idx: objc_msgSend [hWnd sel_getUid "objectValueOfSelectedItem"] + ; objc_msgSend [hWnd sel_getUid "setObjectValue:" idx] + ; ] + ; type = tab-panel [select-tab hWnd int] + ; type = window [ + ; wnd: either TYPE_OF(int) = TYPE_OBJECT [ + ; as-integer face-handle? as red-object! int + ; ][0] + ; objc_msgSend [hWnd sel_getUid "makeFirstResponder:" wnd] + ; ] + ; true [0] ;-- default, do nothing + ; ] + 0 +] + set-selected-focus: func [ hWnd [handle!] /local @@ -500,6 +940,7 @@ OS-make-view: func [ show? [red-logic!] open? [red-logic!] selected [red-integer!] + font [red-object!] para [red-object!] flags [integer!] bits [integer!] @@ -528,6 +969,7 @@ OS-make-view: func [ open?: as red-logic! values + FACE_OBJ_ENABLED? data: as red-block! values + FACE_OBJ_DATA img: as red-image! values + FACE_OBJ_IMAGE + font: as red-object! values + FACE_OBJ_FONT menu: as red-block! values + FACE_OBJ_MENU selected: as red-integer! values + FACE_OBJ_SELECTED para: as red-object! values + FACE_OBJ_PARA @@ -656,7 +1098,10 @@ OS-make-view: func [ ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - create-widget-style widget face + ;create-widget-style widget face + make-font-provider widget + change-font widget face font sym + if all [ sym <> window @@ -686,7 +1131,7 @@ OS-make-view: func [ container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] gtk_widget_set_size_request _widget size/x size/y gtk_fixed_put container _widget offset/x offset/y - print ["x: " offset/x "y: " offset/y "w: " size/x "h: " size/y lf] + ;print ["x: " offset/x "y: " offset/y "w: " size/x "h: " size/y lf] ] ] ] @@ -712,7 +1157,7 @@ OS-update-view: func [ int2 [red-integer!] bool [red-logic!] s [series!] - widget [integer!] + widget [handle!] flags [integer!] type [integer!] ][ @@ -725,7 +1170,7 @@ OS-update-view: func [ type: symbol/resolve word/symbol s: GET_BUFFER(state) int: as red-integer! s/offset - widget: int/value + widget: as handle! int/value int: int + 1 flags: int/value @@ -735,9 +1180,10 @@ OS-update-view: func [ ;if flags and FACET_FLAG_SIZE <> 0 [ ; change-size widget as red-pair! values + FACE_OBJ_SIZE type ;] - ;if flags and FACET_FLAG_TEXT <> 0 [ - ; change-text widget values type - ;] + if flags and FACET_FLAG_TEXT <> 0 [ + change-text widget values face type + gtk_widget_queue_draw widget + ] ;if flags and FACET_FLAG_DATA <> 0 [ ; change-data as handle! widget values ;] @@ -759,12 +1205,12 @@ OS-update-view: func [ ; get-flags as red-block! values + FACE_OBJ_FLAGS ;] if flags and FACET_FLAG_DRAW <> 0 [ - gtk_widget_queue_draw as handle! widget + gtk_widget_queue_draw widget ] if flags and FACET_FLAG_COLOR <> 0 [ if type = base [ ; update-base as handle! widget null null values - gtk_widget_queue_draw as handle! widget + gtk_widget_queue_draw widget ; ][ ; InvalidateRect as handle! widget null 1 ] @@ -776,10 +1222,10 @@ OS-update-view: func [ ; null ; ] ;] - ;if flags and FACET_FLAG_FONT <> 0 [ - ; set-font as handle! widget face values + if flags and FACET_FLAG_FONT <> 0 [ + change-font widget face as red-object! values + FACE_OBJ_FONT type ; InvalidateRect as handle! widget null 1 - ;] + ] ;if flags and FACET_FLAG_PARA <> 0 [ ; update-para face 0 ; InvalidateRect as handle! widget null 1 diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds index 6843245f87..91cf07bd1b 100644 --- a/modules/view/backends/gtk3/style.reds +++ b/modules/view/backends/gtk3/style.reds @@ -117,7 +117,8 @@ set-widget-style: func [ blk [red-block!] len [integer!] sym [integer!] - class [c-string!] + str [red-string!] + name [c-string!] size [red-integer!] css [c-string!] color [red-tuple!] @@ -131,6 +132,7 @@ set-widget-style: func [ values: object/get-values font ;name: + str: as red-string! values + FONT_OBJ_NAME size: as red-integer! values + FONT_OBJ_SIZE style: as red-word! values + FONT_OBJ_STYLE ;angle: @@ -141,6 +143,12 @@ set-widget-style: func [ context: gtk_widget_get_style_context widget provider: get-style-provider widget + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + css: g_strdup_printf [{%s font-family: "%s";} css name] + ] + if TYPE_OF(size) = TYPE_INTEGER [ css: add-to-string css "%s font-size: %dpt;" as handle! size/value ] @@ -158,14 +166,15 @@ set-widget-style: func [ unless zero? len [ loop len [ sym: symbol/resolve style/symbol - class: case [ - sym = _bold ["bold"] - sym = _italic ["italic"] - sym = _underline ["underline"] - sym = _strike ["strike"] + case [ ;OLD -> class: case [ + sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold;" css]] + sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] + sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration-line: underline;" css]] + sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration-line: line-through;" css]] true [""] ] - unless 0 = length? class [gtk_style_context_add_class context class] + style: style + 1 + ;unless 0 = length? class [gtk_style_context_add_class context class] ] ] @@ -177,6 +186,8 @@ set-widget-style: func [ css: add-to-string css "%s}" null + print ["css: " css lf] + gtk_css_provider_load_from_data provider css -1 null g_free as handle! css From 884fbba3a2e924af6c4c4a68a203e09279f454ba Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 16 Aug 2017 22:36:51 +0200 Subject: [PATCH 0032/3432] View-test.red fixed and commented ... --- tests/gtk3/README.gtk3 | 7 + tests/gtk3/view-test.red | 283 ++++++++++++++++++++------------------- 2 files changed, 150 insertions(+), 140 deletions(-) create mode 100644 tests/gtk3/README.gtk3 diff --git a/tests/gtk3/README.gtk3 b/tests/gtk3/README.gtk3 new file mode 100644 index 0000000000..66788669fc --- /dev/null +++ b/tests/gtk3/README.gtk3 @@ -0,0 +1,7 @@ +sudo apt install at-spi2-core #for Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files + + +sudo apt-get install libgtk-3-bin:i386 +sudo apt-get install librsvg2-common:i386 +sudo apt install libcanberra-gtk-module:i386 libcanberra-gtk3-module:i386 +sudo apt install at-spi2-core:i386 diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red index 1f030c2971..8ec33b45f9 100644 --- a/tests/gtk3/view-test.red +++ b/tests/gtk3/view-test.red @@ -3,12 +3,15 @@ Red [ Needs: 'View ] -system/view/debug?: yes +print "ici" + +system/view/debug?: no live?: system/view/auto-sync?: no workstation?: system/view/platform/product = 1 os-version: system/view/platform/version + #switch config/OS [ Windows [ print [ @@ -38,81 +41,81 @@ os-version: system/view/platform/version "build" system/view/platform/build ] ] - default [] + Linux [0] ] -smiley: make image! [23x24 #{ -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC -CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 -444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 -8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C -E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 -4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 -DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F -949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 -736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 -F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C -F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 -E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 -171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 -ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 -211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A -E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 -ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 -CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 -3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE -F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 -E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 -5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE -F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 -514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 -ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 -6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD -5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 -3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 -F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC -A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 -8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC -736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E -56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 -DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ -FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 -00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 -0000000000000000000000000000000000FFFFFFFF0000000000000000000000 -000000000000000000FFFF000000000000000000000000000000000000000000 -FFFF000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -00000000000000FF000000000000000000000000000000000000000000FFFF00 -0000000000000000000000000000000000000000FFFFFF000000000000000000 -00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 -FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 -000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 -00FFFFFFFFFFFFFF -}] +; smiley: make image! [23x24 #{ +; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC +; CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 +; 444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 +; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 +; 8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C +; E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 +; 4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 +; DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F +; 949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +; ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 +; 736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 +; F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C +; F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 +; ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 +; E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 +; 171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 +; ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 +; 211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A +; E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 +; ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 +; CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC +; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +; ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE +; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 +; 3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +; FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 +; ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE +; F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 +; E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 +; 5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE +; F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 +; 514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 +; ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 +; 6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD +; 5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 +; 3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 +; F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 +; F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE +; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 +; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC +; A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 +; 8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC +; 736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E +; 56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +; F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 +; DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ +; FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +; 0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 +; 00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 +; 0000000000000000000000000000000000FFFFFFFF0000000000000000000000 +; 000000000000000000FFFF000000000000000000000000000000000000000000 +; FFFF000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 0000000000000000000000000000000000000000000000000000000000000000 +; 00000000000000FF000000000000000000000000000000000000000000FFFF00 +; 0000000000000000000000000000000000000000FFFFFF000000000000000000 +; 00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 +; FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 +; 000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 +; 00FFFFFFFFFFFFFF +; }] sub-win: make face! [ type: 'window text: "Sub 1-View" offset: 200x200 size: 200x100 @@ -140,60 +143,60 @@ sub-win2: make face! [ ] ] -;; requires pane cursor to be moved back in closing event handler +; ;; requires pane cursor to be moved back in closing event handler win: make face! [ type: 'window text: "Red View" size: 1100x800 - menu: [ - ;popup ;-- forces context menu for window - "File" [ - "New" new - "Open... F1" open - "Close F2" close - --- - "Save..." save - "Save as..." save-as - "Save All" save-all - --- - "Print..." print - "Preview" preview - "Page Setup..." page-setup - --- - "Exit" exit - ] - "Edit" [ - "Undo" undo - "Redo" redo - --- - "Copy Ctrl+C" copy - "Cut Ctrl+X" cut - "Paste Ctrl+V" paste - --- - "Sub1" [ - "Sub-menu1" sub-m1 - ] - "Sub2" [ - "Sub-menu2" sub-m2 - ] - ] - "Search" [ - "Find..." find - "Find Next" find-next - "Find Previous" find-prev - --- - "Replace..." replace - "Replace Next" replace-next - ] - "Deep" [ - "Item 2" item2 - "Deep 2" [ - "Item 3" item3 - "Deep 3" [ - "End" end - ] - ] - ] - ] + ; menu: [ + ; ;popup ;-- forces context menu for window + ; "File" [ + ; "New" new + ; "Open... F1" open + ; "Close F2" close + ; --- + ; "Save..." save + ; "Save as..." save-as + ; "Save All" save-all + ; --- + ; "Print..." print + ; "Preview" preview + ; "Page Setup..." page-setup + ; --- + ; "Exit" exit + ; ] + ; "Edit" [ + ; "Undo" undo + ; "Redo" redo + ; --- + ; "Copy Ctrl+C" copy + ; "Cut Ctrl+X" cut + ; "Paste Ctrl+V" paste + ; --- + ; "Sub1" [ + ; "Sub-menu1" sub-m1 + ; ] + ; "Sub2" [ + ; "Sub-menu2" sub-m2 + ; ] + ; ] + ; "Search" [ + ; "Find..." find + ; "Find Next" find-next + ; "Find Previous" find-prev + ; --- + ; "Replace..." replace + ; "Replace Next" replace-next + ; ] + ; "Deep" [ + ; "Item 2" item2 + ; "Deep 2" [ + ; "Item 3" item3 + ; "Deep 3" [ + ; "End" end + ; ] + ; ] + ; ] + ; ] actors: object [ on-menu: func [face [object!] event [event!]][ print ["menu selected:" event/picked] @@ -224,7 +227,7 @@ win: make face! [ canvas: make face! [ type: 'base offset: 0x0 size: 300x200 color: silver draw: [ - image smiley 10x30 + ;image smiley 10x30 line-cap round pen red @@ -453,7 +456,7 @@ win/pane: reduce [ ] ] ] - make face! [ + make face! [ type: 'area text: {Multiline area widget} offset: 580x24 size: 160x100 font: font-A actors: object [ @@ -603,15 +606,15 @@ win/pane: reduce [ ] ] ] - make face! [ - type: 'radio text: "radio 2" offset: 300x230 size: 90x24 - data: on - actors: object [ - on-change: func [face [object!] event [event!]][ - print "radio 2 set" - ] - ] - ] + ; make face! [ + ; type: 'radio text: "radio 2" offset: 300x230 size: 90x24 + ; data: on + ; actors: object [ + ; on-change: func [face [object!] event [event!]][ + ; print "radio 2 set" + ; ] + ; ] + ; ] make face! [ type: 'base offset: 280x10 size: 100x100 options: [drag-on: 'down] @@ -698,9 +701,9 @@ win/pane: reduce [ ] ] ] - set 'cam make face! [ - type: 'camera offset: 400x140 size: 320x240 - ] + ; set 'cam make face! [ + ; type: 'camera offset: 400x140 size: 320x240 + ; ] cam-list: make face! [ type: 'drop-list offset: 480x402 size: 160x32 actors: object [ @@ -756,7 +759,7 @@ win/pane: reduce [ ] make face! [ type: 'button offset: 570x440 size: 38x38 - image: smiley + ;image: smiley ] make face! [ ;-- clip view for canvas type: 'panel offset: 10x460 size: 300x200 From c2c6a0bd8b8cdd99bb7a40b4a7289a4d7c3c7b29 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 17 Aug 2017 03:59:52 +0200 Subject: [PATCH 0033/3432] Needs to release hFont + background-color added --- modules/view/backends/gtk3/font.reds | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index dd6c74c11f..408cc3df77 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -27,6 +27,7 @@ make-font: func [ size [red-integer!] css [c-string!] color [red-tuple!] + bgcolor [red-tuple!] rgba [c-string!] hFont [handle!] int [red-integer!] @@ -41,8 +42,21 @@ make-font: func [ color: as red-tuple! values + FONT_OBJ_COLOR ;anti-alias?: + ; release first + hFont: get-font-handle font + unless null? hFont [g_free hFont] + css: g_strdup_printf ["* {"] + unless null? face [ + bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR + if TYPE_OF(bgcolor) = TYPE_TUPLE [ + rgba: to-css-rgba bgcolor + css: add-to-string css "%s background-color: %s;" as handle! rgba + g_free as handle! rgba + ] + ] + if TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len From 3fc1e6874ab5b37ed07d61b22c3c52b8e69374d7 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 18 Aug 2017 07:59:31 +0200 Subject: [PATCH 0034/3432] First try for get-text-size and area signal react-test6.red working --- modules/view/backends/gtk3/font.reds | 135 +++++++++++++++++++++++ modules/view/backends/gtk3/gtk.reds | 114 +++++++++++++++++++ modules/view/backends/gtk3/gui.reds | 49 +++++++- modules/view/backends/gtk3/handlers.reds | 24 ++++ modules/view/backends/gtk3/style.reds | 1 + 5 files changed, 317 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 408cc3df77..68aef8e574 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -10,6 +10,64 @@ Red/System [ } ] +#enum pango-style! [ + PANGO_STYLE_NORMAL + PANGO_STYLE_OBLIQUE + PANGO_STYLE_ITALIC +] + +#enum pango-variant! [ + PANGO_VARIANT_NORMAL + PANGO_VARIANT_SMALL_CAPS +] + +#enum pango-weight! [ + PANGO_WEIGHT_THIN: 100 + PANGO_WEIGHT_ULTRALIGHT: 200 + PANGO_WEIGHT_LIGHT: 300 + PANGO_WEIGHT_SEMILIGHT: 350 + PANGO_WEIGHT_BOOK: 380 + PANGO_WEIGHT_NORMAL: 400 + PANGO_WEIGHT_MEDIUM: 500 + PANGO_WEIGHT_SEMIBOLD: 600 + PANGO_WEIGHT_BOLD: 700 + PANGO_WEIGHT_ULTRABOLD: 800 + PANGO_WEIGHT_HEAVY: 900 + PANGO_WEIGHT_ULTRAHEAVY: 1000 +] + +#enum pango-stretch! [ + PANGO_STRETCH_ULTRA_CONDENSED + PANGO_STRETCH_EXTRA_CONDENSED + PANGO_STRETCH_CONDENSED + PANGO_STRETCH_SEMI_CONDENSED + PANGO_STRETCH_NORMAL + PANGO_STRETCH_SEMI_EXPANDED + PANGO_STRETCH_EXPANDED + PANGO_STRETCH_EXTRA_EXPANDED + PANGO_STRETCH_ULTRA_EXPANDED +] + +#enum pango-font-mask! [ + PANGO_FONT_MASK_FAMILY: 1 + PANGO_FONT_MASK_STYLE: 2 + PANGO_FONT_MASK_VARIANT: 4 + PANGO_FONT_MASK_WEIGHT: 8 + PANGO_FONT_MASK_STRETCH: 16 + PANGO_FONT_MASK_SIZE: 32 + PANGO_FONT_MASK_GRAVITY: 64 +] + +#define PANGO_SCALE 1024 +#define PANGO_SCALE_XX_SMALL 0.5787037037037 +#define PANGO_SCALE_X_SMALL 0.6444444444444 +#define PANGO_SCALE_SMALL 0.8333333333333 +#define PANGO_SCALE_MEDIUM 1.0 +#define PANGO_SCALE_LARGE 1.2 +#define PANGO_SCALE_X_LARGE 1.4399999999999 +#define PANGO_SCALE_XX_LARGE 1.728 + + ;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget make-font: func [ @@ -193,6 +251,83 @@ update-font: func [ ] ] +;convert font to pango_font_description (used for get-text-size) +font-description: func [ + font [red-object!] + return: [handle!] + /local + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + css [c-string!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] + fsty [integer!] + fd [handle!] + +][ + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + + + fd: pango_font_description_new + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + pango_font_description_set_family fd name + ] + + if TYPE_OF(size) = TYPE_INTEGER [ + pango_font_description_set_size fd size/value * PANGO_SCALE + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + fsty: PANGO_STYLE_NORMAL + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold [pango_font_description_set_weight fd PANGO_WEIGHT_BOLD] + sym = _italic [fsty: PANGO_STYLE_ITALIC] + sym = _underline [] + sym = _strike [] + true [] + ] + style: style + 1 + ] + ] + + pango_font_description_set_style fd fsty + pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL + pango_font_description_set_variant fd PANGO_VARIANT_NORMAL + + fd +] + OS-request-font: func [ font [red-object!] selected [red-object!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 7c875439b7..45726bbc94 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -49,6 +49,24 @@ GdkEventKey!: alias struct! [ ;guint8 group; ;guint is_modifier : 1; ] + +GtkTextIter!: alias struct! [ + dummy1 [handle!] + dummy2 [handle!] + dummy3 [integer!] + dummy4 [integer!] + dummy5 [integer!] + dummy6 [integer!] + dummy7 [integer!] + dummy8 [integer!] + dummy9 [handle!] + dummy10 [handle!] + dummy11 [integer!] + dummy12 [integer!] + dummy13 [integer!] + dummy14 [handle!] +] + #enum GtkFileChooserAction! [ GTK_FILE_CHOOSER_ACTION_OPEN GTK_FILE_CHOOSER_ACTION_SAVE @@ -152,6 +170,18 @@ GdkEventKey!: alias struct! [ g_free: "g_free" [ pointer [handle!] ] + g_string_new: "g_string_new" [ + return: [handle!] + ] + g_string_append: "g_string_append" [ + str [handle!] + text [c-string!] + ] + g_string_free: "g_string_free" [ + str [handle!] + free [logic!] + return: [c-string!] + ] ;; ] ;; LIBGIO-file cdecl [ g_application_register: "g_application_register" [ @@ -288,6 +318,11 @@ GdkEventKey!: alias struct! [ gtk_widget_destroy: "gtk_widget_destroy" [ widget [handle!] ] + gtk_widget_create_pango_layout: "gtk_widget_create_pango_layout" [ + widget [handle!] + text [c-string!] + return: [handle!] + ] gtk_container_add: "gtk_container_add" [ container [handle!] widget [handle!] @@ -446,6 +481,18 @@ GdkEventKey!: alias struct! [ text [c-string!] len [integer!] ] + gtk_text_buffer_get_text: "gtk_text_buffer_get_text" [ + buffer [handle!] + start [handle!] + end [handle!] + exclude [logic!] + return: [c-string!] + ] + gtk_text_buffer_get_bounds: "gtk_text_buffer_get_bounds" [ + buffer [handle!] + start [handle!] + end [handle!] + ] gtk_text_buffer_create_tag: "gtk_text_buffer_create_tag" [ [variadic] return: [handle!] @@ -526,10 +573,77 @@ GdkEventKey!: alias struct! [ context [handle!] class [c-string!] ] + gtk_style_context_to_string: "gtk_style_context_to_string" [ + context [handle!] + type [integer!] + return: [c-string!] + ] + gtk_style_context_get: "gtk_style_context_get" [ + [variadic] + ] gtk_widget_get_style_context: "gtk_widget_get_style_context" [ widget [handle!] return: [handle!] ] + pango_layout_new: "pango_layout_new" [ + context [handle!] + return: [handle!] + ] + pango_layout_set_text: "pango_layout_set_text" [ + layout [handle!] + text [c-string!] + len [integer!] + ] + pango_layout_set_font_description: "pango_layout_set_font_description" [ + layout [handle!] + fontdesc [handle!] + ] + pango_layout_get_pixel_size: "pango_layout_get_pixel_size" [ + layout [handle!] + width [int-ptr!] + height [int-ptr!] + ] + pango_font_description_new: "pango_font_description_new" [ + return: [handle!] + ] + pango_font_description_free: "pango_font_description_free" [ + fontdesc [handle!] + ] + pango_font_description_from_string: "pango_font_description_from_string" [ + str [c-string!] + return: [handle!] + ] + pango_font_description_set_family: "pango_font_description_set_family" [ + fontdesc [handle!] + name [c-string!] + ] + pango_font_description_set_size: "pango_font_description_set_size" [ + fontdesc [handle!] + size [integer!] + ] + pango_font_description_set_weight: "pango_font_description_set_weight" [ + fontdesc [handle!] + weight [integer!] + ] + pango_font_description_set_style: "pango_font_description_set_style" [ + fontdesc [handle!] + style [integer!] + ] + pango_font_description_set_stretch: "pango_font_description_set_stretch" [ + fontdesc [handle!] + stretch [integer!] + ] + pango_font_description_set_variant: "pango_font_description_set_variant" [ + fontdesc [handle!] + variant [integer!] + ] + gdk_pango_context_get: "gdk_pango_context_get" [ + return: [handle!] + ] + gtk_settings_get_default: "gtk_settings_get_default" [ + return: [handle!] + ] + ;; LIBCAIRO-file cdecl [ cairo_line_to: "cairo_line_to" [ cr [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 596dbf1882..dae549efc7 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -33,6 +33,9 @@ tabs: context [ cur: 0 ] +pango-context: as handle! 0 +gtk-settings: as handle! 0 + log-pixels-x: 0 log-pixels-y: 0 screen-size-x: 0 @@ -151,14 +154,47 @@ get-child-from-xy: func [ get-text-size: func [ str [red-string!] - hFont [handle!] + font [red-object!] pair [red-pair!] return: [tagSIZE] /local - saved [handle!] - size [tagSIZE] + text [c-string!] + len [integer!] + width [integer!] + height [integer!] + pl [handle!] + size [tagSIZE] + fd [handle!] + df [c-string!] ][ + if pango-context = as handle! 0 [pango-context: gdk_pango_context_get] + if gtk-settings = as handle! 0 [gtk-settings: gtk_settings_get_default] size: declare tagSIZE + + text: either TYPE_OF(str) = TYPE_STRING [ + len: -1 + unicode/to-utf8 str :len + ][ + null + ] + + width: 0 height: 0 + fd: either TYPE_OF(font) = TYPE_NONE [ + df: "Sans" + ;g_object_get [gtk-settings "gtk-font-name" df null] + ;print ["default font: " df lf] + pango_font_description_from_string df + ][ + font-description font + ] + pl: pango_layout_new pango-context + pango_layout_set_text pl text -1 + pango_layout_set_font_description pl fd + pango_layout_get_pixel_size pl :width :height + + size/width: width + size/height: height + ;print ["text: " text " w: " width " h: " height lf] if pair <> null [ pair/x: size/width pair/y: size/height @@ -342,7 +378,7 @@ change-image: func [ ] change-color: func [ - hWnd [integer!] + hWnd [handle!] color [red-tuple!] type [integer!] /local @@ -1048,9 +1084,10 @@ OS-make-view: func [ sym = area [ widget: gtk_text_view_new buffer: gtk_text_view_get_buffer widget - gtk_text_buffer_set_text buffer caption -1 + unless null? caption [gtk_text_buffer_set_text buffer caption -1] _widget: gtk_scrolled_window_new null null gtk_container_add _widget widget + gobj_signal_connect(buffer "changed" :area-changed widget) ] sym = group-box [ widget: gtk_frame_new caption @@ -1098,7 +1135,7 @@ OS-make-view: func [ ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - ;create-widget-style widget face + ;OLD: create-widget-style widget face make-font-provider widget change-font widget face font sym diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 48a9dc9242..9a019f8269 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -253,3 +253,27 @@ field-move-focus: func [ ][ print-line "move-focus" ] + +area-changed: func [ + [cdecl] + buffer [handle!] + widget [handle!] + /local + text [c-string!] + face [red-object!] + qdata [handle!] + start [GtkTextIter!] + end [GtkTextIter!] +][ + start: as GtkTextIter! allocate (size? GtkTextIter!) + end: as GtkTextIter! allocate (size? GtkTextIter!) + gtk_text_buffer_get_bounds buffer as handle! start as handle! end + text: gtk_text_buffer_get_text buffer as handle! start as handle! end no + free as byte-ptr! start free as byte-ptr! end + qdata: g_object_get_qdata widget red-face-id + if qdata <> as handle! 0 [ + face: as red-object! qdata + set-text widget face/ctx text + make-event widget 0 EVT_CHANGE + ] +] diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds index 91cf07bd1b..e7d1b16abd 100644 --- a/modules/view/backends/gtk3/style.reds +++ b/modules/view/backends/gtk3/style.reds @@ -33,6 +33,7 @@ style-init: func [ gtk_css_provider_load_from_data provider css-style -1 null gtk_style_context_add_provider_for_screen screen provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + ] add-to-string: func [ From ad6534ca684fb2c8946f19bcea0c8196ee807071 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 18 Aug 2017 08:20:13 +0200 Subject: [PATCH 0035/3432] platform.red changed --- modules/view/backends/platform.red | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index d288d0ced3..5375474732 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -579,7 +579,10 @@ system/view/platform: context [ pair: as red-pair! stack/arguments pair/header: TYPE_PAIR - gui/get-text-size text hFont pair + #switch OS [ + Linux [gui/get-text-size text font pair] + #default [gui/get-text-size text hFont pair] + ] ] on-change-facet: routine [ From ef3132ff0d515bca07e6e0d0fd7d18d849c28e8c Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 18 Aug 2017 14:12:33 +0200 Subject: [PATCH 0036/3432] Change-data for main widgets --- modules/view/backends/gtk3/gtk.reds | 8 +++ modules/view/backends/gtk3/gui.reds | 107 ++++++++++++++++------------ 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 45726bbc94..c4976b629f 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -469,6 +469,14 @@ GtkTextIter!: alias struct! [ gtk_progress_bar_new: "gtk_progress_bar_new" [ return: [handle!] ] + gtk_progress_bar_set_fraction: "gtk_progress_bar_set_fraction" [ + progress [handle!] + val [float!] + ] + gtk_progress_bar_get_fraction: "gtk_progress_bar_get_fraction" [ + progress [handle!] + return: [float!] + ] gtk_text_view_new: "gtk_text_view_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index dae549efc7..8a8353442e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -34,7 +34,7 @@ tabs: context [ ] pango-context: as handle! 0 -gtk-settings: as handle! 0 +gtk-font: "Sans 10" log-pixels-x: 0 log-pixels-y: 0 @@ -168,7 +168,6 @@ get-text-size: func [ df [c-string!] ][ if pango-context = as handle! 0 [pango-context: gdk_pango_context_get] - if gtk-settings = as handle! 0 [gtk-settings: gtk_settings_get_default] size: declare tagSIZE text: either TYPE_OF(str) = TYPE_STRING [ @@ -179,11 +178,8 @@ get-text-size: func [ ] width: 0 height: 0 - fd: either TYPE_OF(font) = TYPE_NONE [ - df: "Sans" - ;g_object_get [gtk-settings "gtk-font-name" df null] - ;print ["default font: " df lf] - pango_font_description_from_string df + fd: either TYPE_OF(font) = TYPE_NONE [ + pango_font_description_from_string gtk-font ][ font-description font ] @@ -615,29 +611,29 @@ change-data: func [ word: as red-word! values + FACE_OBJ_TYPE type: word/symbol - ; case [ - ; all [ - ; type = progress - ; TYPE_OF(data) = TYPE_PERCENT - ; ][ - ; f: as red-float! data - ; objc_msgSend [hWnd sel_getUid "setDoubleValue:" f/value * 100.0] - ; ] - ; all [ - ; type = slider - ; TYPE_OF(data) = TYPE_PERCENT - ; ][ - ; f: as red-float! data - ; size: as red-pair! values + FACE_OBJ_SIZE - ; len: either size/x > size/y [size/x][size/y] - ; objc_msgSend [hWnd sel_getUid "setDoubleValue:" f/value * (as-float len)] - ; ] - ; type = check [ - ; set-logic-state hWnd as red-logic! data yes - ; ] - ; type = radio [ - ; set-logic-state hWnd as red-logic! data no - ; ] + case [ + all [ + type = progress + TYPE_OF(data) = TYPE_PERCENT + ][ + f: as red-float! data + gtk_progress_bar_set_fraction hWnd f/value + ] + all [ + type = slider + TYPE_OF(data) = TYPE_PERCENT + ][ + f: as red-float! data + size: as red-pair! values + FACE_OBJ_SIZE + len: either size/x > size/y [size/x][size/y] + gtk_range_set_value hWnd f/value * (as-float len) + ] + type = check [ + set-logic-state hWnd as red-logic! data yes + ] + type = radio [ + set-logic-state hWnd as red-logic! data no + ] ; type = tab-panel [ ; set-tabs hWnd get-face-values hWnd ; ] @@ -647,11 +643,11 @@ change-data: func [ ; ][ ; objc_msgSend [objc_msgSend [hWnd sel_getUid "documentView"] sel_getUid "reloadData"] ; ] - ; any [type = drop-list type = drop-down][ - ; init-combo-box hWnd as red-block! data null type = drop-list - ; ] - ; true [0] ;-- default, do nothing - ; ] + any [type = drop-list type = drop-down][ + init-combo-box hWnd as red-block! data null type = drop-list + ] + true [0] ;-- default, do nothing + ] 0 ] @@ -801,6 +797,22 @@ get-position-value: func [ as-integer f ] +get-fraction-value: func [ + pos [red-float!] + return: [float!] + /local + f [float!] +][ + f: 0.0 + if any [ + TYPE_OF(pos) = TYPE_FLOAT + TYPE_OF(pos) = TYPE_PERCENT + ][ + f: pos/value + ] + f +] + get-screen-size: func [ id [integer!] ;@@ Not used yet return: [red-pair!] @@ -989,7 +1001,9 @@ OS-make-view: func [ buffer [handle!] container [handle!] value [integer!] + fvalue [float!] vertical? [logic!] + rfvalue [red-float!] ][ stack/mark-func words/_body @@ -1080,6 +1094,8 @@ OS-make-view: func [ ] sym = progress [ widget: gtk_progress_bar_new + fvalue: get-fraction-value as red-float! data + gtk_progress_bar_set_fraction widget fvalue ] sym = area [ widget: gtk_text_view_new @@ -1221,11 +1237,11 @@ OS-update-view: func [ change-text widget values face type gtk_widget_queue_draw widget ] - ;if flags and FACET_FLAG_DATA <> 0 [ - ; change-data as handle! widget values - ;] + if flags and FACET_FLAG_DATA <> 0 [ + change-data widget values + ] ;if flags and FACET_FLAG_ENABLE? <> 0 [ - ; change-enabled as handle! widget values + ; change-enabled widget values ;] ;if flags and FACET_FLAG_VISIBLE? <> 0 [ ; bool: as red-logic! values + FACE_OBJ_VISIBLE? @@ -1237,7 +1253,7 @@ OS-update-view: func [ ;] ;if flags and FACET_FLAG_FLAGS <> 0 [ ; SetWindowLong - ; as handle! widget + ; widget ; wc-offset + 16 ; get-flags as red-block! values + FACE_OBJ_FLAGS ;] @@ -1246,10 +1262,10 @@ OS-update-view: func [ ] if flags and FACET_FLAG_COLOR <> 0 [ if type = base [ - ; update-base as handle! widget null null values + ; update-base widget null null values gtk_widget_queue_draw widget ; ][ - ; InvalidateRect as handle! widget null 1 + ; InvalidateRect widget null 1 ] ] ;if flags and FACET_FLAG_PANE <> 0 [ @@ -1261,17 +1277,16 @@ OS-update-view: func [ ;] if flags and FACET_FLAG_FONT <> 0 [ change-font widget face as red-object! values + FACE_OBJ_FONT type - ; InvalidateRect as handle! widget null 1 ] ;if flags and FACET_FLAG_PARA <> 0 [ ; update-para face 0 - ; InvalidateRect as handle! widget null 1 + ; InvalidateRect widget null 1 ;] ;if flags and FACET_FLAG_MENU <> 0 [ ; menu: as red-block! values + FACE_OBJ_MENU ; if menu-bar? menu window [ - ; DestroyMenu GetMenu as handle! widget - ; SetMenu as handle! widget build-menu menu CreateMenu + ; DestroyMenu GetMenu widget + ; SetMenu widget build-menu menu CreateMenu ; ] ;] ;if flags and FACET_FLAG_IMAGE <> 0 [ From 6e2642086dd191a8c4f1619c60ecdd4e33c341ed Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 19 Aug 2017 07:50:47 +0200 Subject: [PATCH 0037/3432] Change-text is more complete --- modules/view/backends/gtk3/gtk.reds | 14 ++++++++++++++ modules/view/backends/gtk3/gui.reds | 28 +++++++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index c4976b629f..15d751193e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -50,6 +50,12 @@ GdkEventKey!: alias struct! [ ;guint is_modifier : 1; ] +#enum GdkModifierType! [ + GDK_SHIFT_MASK: 1 + GDK_LOCK_MASK: 2 + GDK_CONTROL_MASK: 4 +] + GtkTextIter!: alias struct! [ dummy1 [handle!] dummy2 [handle!] @@ -335,6 +341,10 @@ GtkTextIter!: alias struct! [ label [c-string!] return: [handle!] ] + gtk_frame_set_label: "gtk_frame_set_label" [ + frame [handle!] + label [c-string!] + ] gtk_frame_set_label_align: "gtk_frame_set_label_align" [ frame [handle!] xalign [float!] @@ -386,6 +396,10 @@ GtkTextIter!: alias struct! [ label [c-string!] return: [handle!] ] + gtk_button_set_label: "gtk_button_set_label" [ + button [handle!] + label [c-string!] + ] gtk_check_button_new_with_label: "gtk_check_button_new_with_label" [ label [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8a8353442e..2bc6674d4e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -18,6 +18,7 @@ Red/System [ #include %para.reds #include %draw.reds +;#include %gdkkeysyms.reds #include %handlers.reds #include %comdlgs.reds @@ -554,9 +555,10 @@ change-text: func [ face [red-object!] type [integer!] /local - len [integer!] - cstr [c-string!] - str [red-string!] + len [integer!] + cstr [c-string!] + str [red-string!] + buffer [handle!] ][ ; if type = base [ ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] @@ -569,7 +571,6 @@ change-text: func [ TYPE_NONE [""] default [null] ;@@ Auto-convert? ] - if null? cstr [exit] either type = area [ @@ -583,10 +584,19 @@ change-text: func [ case [ type = text [ gtk_label_set_text hWnd cstr - ;objc_msgSend [hWnd sel_getUid "setStringValue:" txt] ] - any [type = button type = radio type = check type = window type = group-box][ - ;objc_msgSend [hWnd sel_getUid "setTitle:" txt] + type = field [ + buffer: gtk_entry_get_buffer hWnd + gtk_entry_buffer_set_text buffer cstr -1 + ] + any [type = button type = radio type = check] [ + gtk_button_set_label hWnd cstr + ] + type = window [ + gtk_window_set_title hWnd cstr + ] + type = group-box [ + gtk_frame_set_label hWnd cstr ] true [0] ] @@ -629,10 +639,10 @@ change-data: func [ gtk_range_set_value hWnd f/value * (as-float len) ] type = check [ - set-logic-state hWnd as red-logic! data yes + ;set-logic-state hWnd as red-logic! data yes ] type = radio [ - set-logic-state hWnd as red-logic! data no + ;set-logic-state hWnd as red-logic! data no ] ; type = tab-panel [ ; set-tabs hWnd get-face-values hWnd From fb3fcd4f8e5446859d5cbbf9f2ab212b0576d544 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 19 Aug 2017 08:42:06 +0200 Subject: [PATCH 0038/3432] Fix the error in vid.red when clicking radio button --- modules/view/backends/gtk3/gui.reds | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 2bc6674d4e..fed492d728 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -639,10 +639,10 @@ change-data: func [ gtk_range_set_value hWnd f/value * (as-float len) ] type = check [ - ;set-logic-state hWnd as red-logic! data yes + set-logic-state hWnd as red-logic! data yes ] type = radio [ - ;set-logic-state hWnd as red-logic! data no + set-logic-state hWnd as red-logic! data no ] ; type = tab-panel [ ; set-tabs hWnd get-face-values hWnd @@ -1047,7 +1047,8 @@ OS-make-view: func [ sym = check [ widget: gtk_check_button_new_with_label caption set-logic-state widget as red-logic! data no - gobj_signal_connect(widget "clicked" :button-clicked null) + ;@@ No click event for check + ;gobj_signal_connect(widget "clicked" :button-clicked null) gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = radio [ @@ -1057,7 +1058,8 @@ OS-make-view: func [ gtk_radio_button_new_with_label_from_widget group-radio caption ] set-logic-state widget as red-logic! data no - gobj_signal_connect(widget "clicked" :button-clicked null) + ;@@ Line below removed because it generates an error and there is no click event for radio + ;gobj_signal_connect(widget "clicked" :button-clicked null) gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = button [ From 0ae2c9cb784bd05ef21da6e317e77de95080f101 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 19 Aug 2017 08:51:23 +0200 Subject: [PATCH 0039/3432] Update tests for gtk3 --- tests/gtk3/react-test6.red | 4 +-- tests/gtk3/request.red | 12 ++++++++ tests/gtk3/vid.red | 57 ++++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 tests/gtk3/request.red diff --git a/tests/gtk3/react-test6.red b/tests/gtk3/react-test6.red index e6c7d523dc..ec013fb864 100644 --- a/tests/gtk3/react-test6.red +++ b/tests/gtk3/react-test6.red @@ -12,7 +12,7 @@ view [ return txt "Size in pixels" text "0x0" - react [[f/text f/font] face/text: form size-text f] + react [[f/text f/font] face/text: form size-text f print ["size: " form size-text f f/text lf]] return txt "Font name" drop-list 120 @@ -20,7 +20,7 @@ view [ react [f/font/name: pick face/data any [face/selected 3] print ["changed:" mold face/text]] return - txt "Font size" s: field "15" react [f/font/size: s/data] + txt "Font size" s: field "15" react [f/font/size: s/data print ["text " face/text lf]] button "+" bold 40 [s/data: s/data + 1] button "-" bold 40 [s/data: max 1 s/data - 1] return diff --git a/tests/gtk3/request.red b/tests/gtk3/request.red new file mode 100644 index 0000000000..9f5bc48e6b --- /dev/null +++ b/tests/gtk3/request.red @@ -0,0 +1,12 @@ +Red [] +a: request-file +print a + +wait 3 +a: none +view [ + button "toto" [a: request-file print a] + button "toti" [a: request-dir print a] +] + +print a \ No newline at end of file diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red index eb8f5eefa8..7065b656ee 100644 --- a/tests/gtk3/vid.red +++ b/tests/gtk3/vid.red @@ -4,27 +4,28 @@ Red [ File: %vid.red Needs: 'View ] -system/view/debug?: no +system/view/debug?: no ;yes view [ title "VID test" ;below - text "Hello" + text "Hello" font [name: "Nimbus Sans L" size: 12 color: 112.13.114] button "Hello" 100x40 [bar/data: random 100%] - button "World" + button "World" underline italic [opt4/data: yes opt1/data: no] return button "China" - text "Red Language" 100 right - field 120 on-enter [];probe do face/text clear face/text] + text "Red Language" 100 right bold font [color: red] + field 120 on-enter [probe do face/text clear face/text] return group-box 3 [ - ;style but: button 25 font [name: "Comic Sans MS" size: 12 color: blue] + style but: button 25 font [name: "Comic Sans MS" size: 12 color: blue] base 0.233.1.177 "ok" 25x25 text "in panel" - ;but "A" but "B" but "C" - ;but "D" but "E" but "F" + + but "A" but "B" but "C" + but "D" but "E" but "F" ] tab-panel [ "tab1" [at 10x10 base 0.2.233.188 15x15 at 50x50 button "one"] @@ -32,16 +33,18 @@ view [ ] on-change [print ["selected: " face/selected face/text lf]] below - slider 5% + slider 5% react [bar/data: face/data] pad 10x0 bar: progress 50% 130 base 255.0.0.138 50x50 draw [fill-pen blue circle 25x25 15] across return middle - check "option 1" font-size 14 - check "option 2" font-color orange - radio "option 3" font-name "Times New Roman" - radio "option 4" + group-box [ + opt1: check "option 1" font-size 14 + check "option 2" font-color orange + radio "option 3" font-name "Times New Roman" + opt4: radio "option 4" + ] return top list: text-list data ["one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four"] [print [pick face/data face/selected lf face/selected face/text lf] ] @@ -50,22 +53,22 @@ view [ return - ; style but1: button - ; style txt1: text 30 - ; style base1: base 10x10 + style but1: button + style txt1: text 30 + style base1: base 10x10 - ; but1 "1" txt1 "1" base1 "1" - ; return - ; group-box [ - ; style but1: but1 font-color red - ; style txt1: txt1 red center - ; style base1: base1 red + but1 "1" txt1 "1" base1 "1" + return + group-box [ + style but1: but1 font-color red + style txt1: txt1 red center + style base1: base1 red - ; but1 "1" txt1 "1" base1 "1" - ; ] return - ; but1 "1" txt1 "1" base1 "1" + but1 "1" txt1 "1" base1 "1" + ] return + but1 "1" txt1 "1" base1 "1" - ; at (list/offset + 130x50) base 5x5 red + at (list/offset + 130x50) base 5x5 red - do [];append list/data "five" win: self] + do [append list/data "three" win: self] ] From 9203177670e5537edca8151612c458de6afa93b5 Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 22 Aug 2017 19:07:01 +0200 Subject: [PATCH 0040/3432] First solution to adapt the layout gtk_fixed in the red spirit Needs a second step to move the widgets inside fixed container since some of them change size. --- modules/view/backends/gtk3/events.reds | 359 ++++++++++++++++++++++- modules/view/backends/gtk3/gtk.reds | 59 +++- modules/view/backends/gtk3/gui.reds | 100 ++++++- modules/view/backends/gtk3/handlers.reds | 52 +++- 4 files changed, 548 insertions(+), 22 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 0b2d70918d..176ca75789 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -10,6 +10,267 @@ Red/System [ } ] +keycode-table: [ + RED_VK_A ;-- 0 + RED_VK_S ;-- 1 + RED_VK_D ;-- 2 + RED_VK_F ;-- 3 + RED_VK_H ;-- 4 + RED_VK_G ;-- 5 + RED_VK_Z ;-- 6 + RED_VK_X ;-- 7 + RED_VK_C ;-- 8 + RED_VK_V ;-- 9 + RED_VK_OEM_3 ;-- 0x0A Section key. + RED_VK_B ;-- 0x0B + RED_VK_Q ;-- 0x0C + RED_VK_W ;-- 0x0D + RED_VK_E ;-- 0x0E + RED_VK_R ;-- 0x0F + RED_VK_Y ;-- 0x10 + RED_VK_T ;-- 0x11 + RED_VK_1 ;-- 0x12 + RED_VK_2 ;-- 0x13 + RED_VK_3 ;-- 0x14 + RED_VK_4 ;-- 0x15 + RED_VK_6 ;-- 0x16 + RED_VK_5 ;-- 0x17 + RED_VK_OEM_PLUS ;-- 0x18 =+ + RED_VK_9 ;-- 0x19 + RED_VK_7 ;-- 0x1A + RED_VK_OEM_MINUS ;-- 0x1B -_ + RED_VK_8 ;-- 0x1C + RED_VK_0 ;-- 0x1D + RED_VK_OEM_6 ;-- 0x1E ]} + RED_VK_O ;-- 0x1F + RED_VK_U ;-- 0x20 + RED_VK_OEM_4 ;-- 0x21 {[ + RED_VK_I ;-- 0x22 + RED_VK_P ;-- 0x23 + RED_VK_RETURN ;-- 0x24 Return + RED_VK_L ;-- 0x25 + RED_VK_J ;-- 0x26 + RED_VK_OEM_7 ;-- 0x27 '" + RED_VK_K ;-- 0x28 + RED_VK_OEM_1 ;-- 0x29 ;: + RED_VK_OEM_5 ;-- 0x2A \| + RED_VK_OEM_COMMA ;-- 0x2B < + RED_VK_OEM_2 ;-- 0x2C /? + RED_VK_N ;-- 0x2D + RED_VK_M ;-- 0x2E + RED_VK_OEM_PERIOD ;-- 0x2F .> + RED_VK_TAB ;-- 0x30 + RED_VK_SPACE ;-- 0x31 + RED_VK_OEM_3 ;-- 0x32 `~ + RED_VK_BACK ;-- 0x33 Backspace + RED_VK_UNKNOWN ;-- 0x34 n/a + RED_VK_ESCAPE ;-- 0x35 + RED_VK_APPS ;-- 0x36 Right Command + RED_VK_LWIN ;-- 0x37 Left Command + RED_VK_SHIFT ;-- 0x38 Left Shift + RED_VK_CAPITAL ;-- 0x39 Caps Lock + RED_VK_MENU ;-- 0x3A Left Option + RED_VK_CONTROL ;-- 0x3B Left Ctrl + RED_VK_SHIFT ;-- 0x3C Right Shift + RED_VK_MENU ;-- 0x3D Right Option + RED_VK_CONTROL ;-- 0x3E Right Ctrl + RED_VK_UNKNOWN ;-- 0x3F fn + RED_VK_F17 ;-- 0x40 + RED_VK_DECIMAL ;-- 0x41 Num Pad . + RED_VK_UNKNOWN ;-- 0x42 n/a + RED_VK_MULTIPLY ;-- 0x43 Num Pad * + RED_VK_UNKNOWN ;-- 0x44 n/a + RED_VK_ADD ;-- 0x45 Num Pad + + RED_VK_UNKNOWN ;-- 0x46 n/a + RED_VK_CLEAR ;-- 0x47 Num Pad Clear + RED_VK_VOLUME_UP ;-- 0x48 + RED_VK_VOLUME_DOWN ;-- 0x49 + RED_VK_VOLUME_MUTE ;-- 0x4A + RED_VK_DIVIDE ;-- 0x4B Num Pad / + RED_VK_RETURN ;-- 0x4C Num Pad Enter + RED_VK_UNKNOWN ;-- 0x4D n/a + RED_VK_SUBTRACT ;-- 0x4E Num Pad - + RED_VK_F18 ;-- 0x4F + RED_VK_F19 ;-- 0x50 + RED_VK_OEM_PLUS ;-- 0x51 Num Pad =. + RED_VK_NUMPAD0 ;-- 0x52 + RED_VK_NUMPAD1 ;-- 0x53 + RED_VK_NUMPAD2 ;-- 0x54 + RED_VK_NUMPAD3 ;-- 0x55 + RED_VK_NUMPAD4 ;-- 0x56 + RED_VK_NUMPAD5 ;-- 0x57 + RED_VK_NUMPAD6 ;-- 0x58 + RED_VK_NUMPAD7 ;-- 0x59 + RED_VK_F20 ;-- 0x5A + RED_VK_NUMPAD8 ;-- 0x5B + RED_VK_NUMPAD9 ;-- 0x5C + RED_VK_UNKNOWN ;-- 0x5D Yen (JIS Keyboard Only) + RED_VK_UNKNOWN ;-- 0x5E Underscore (JIS Keyboard Only) + RED_VK_UNKNOWN ;-- 0x5F KeypadComma (JIS Keyboard Only) + RED_VK_F5 ;-- 0x60 + RED_VK_F6 ;-- 0x61 + RED_VK_F7 ;-- 0x62 + RED_VK_F3 ;-- 0x63 + RED_VK_F8 ;-- 0x64 + RED_VK_F9 ;-- 0x65 + RED_VK_UNKNOWN ;-- 0x66 Eisu (JIS Keyboard Only) + RED_VK_F11 ;-- 0x67 + RED_VK_UNKNOWN ;-- 0x68 Kana (JIS Keyboard Only) + RED_VK_F13 ;-- 0x69 + RED_VK_F16 ;-- 0x6A + RED_VK_F14 ;-- 0x6B + RED_VK_UNKNOWN ;-- 0x6C n/a + RED_VK_F10 ;-- 0x6D + RED_VK_UNKNOWN ;-- 0x6E n/a (Windows95 key?) + RED_VK_F12 ;-- 0x6F + RED_VK_UNKNOWN ;-- 0x70 n/a + RED_VK_F15 ;-- 0x71 + RED_VK_INSERT ;-- 0x72 Help + RED_VK_HOME ;-- 0x73 Home + RED_VK_PRIOR ;-- 0x74 Page Up + RED_VK_DELETE ;-- 0x75 Forward Delete + RED_VK_F4 ;-- 0x76 + RED_VK_END ;-- 0x77 End + RED_VK_F2 ;-- 0x78 + RED_VK_NEXT ;-- 0x79 Page Down + RED_VK_F1 ;-- 0x7A + RED_VK_LEFT ;-- 0x7B Left Arrow + RED_VK_RIGHT ;-- 0x7C Right Arrow + RED_VK_DOWN ;-- 0x7D Down Arrow + RED_VK_UP ;-- 0x7E Up Arrow + RED_VK_UNKNOWN ;-- 0x7F n/a +] + +; RED_VK_UNKNOWN 1->0x1 +; RED_VK_UNKNOWN 2->0x2 +; RED_VK_UNKNOWN 3->0x3 +; RED_VK_UNKNOWN 4->0x4 +; RED_VK_UNKNOWN 5->0x5 +; RED_VK_UNKNOWN 6->0x6 +; RED_VK_UNKNOWN 7->0x7 +; RED_VK_UNKNOWN 8->0x8 +; 9->0x9 +; 10->0xa +; 11->0xb +; 12->0xc +; 13->0xd +; 14->0xe +; 15->0xf +; 16->0x10 +; 17->0x11 +; 18->0x12 +; 19->0x13 +; 20->0x14 +; 21->0x15 +; 22->0x16 +; 23->0x17 +; 24->0x18 +; 25->0x19 +; 26->0x1a +; 27->0x1b +; 28->0x1c +; 29->0x1d +; 30->0x1e +; 31->0x1f +; 32->space +; 33->exclam +; 34->quotedbl +; 35->numbersign +; 36->dollar +; 37->percent +; 38->ampersand +; 39->apostrophe +; 40->parenleft +; 41->parenright +; 42->asterisk +; 43->plus +; 44->comma +; 45->minus +; 46->period +; 47->slash +; 48->0 +; 49->1 +; 50->2 +; 51->3 +; 52->4 +; 53->5 +; 54->6 +; 55->7 +; 56->8 +; 57->9 +; 58->colon +; 59->semicolon +; 60->less +; 61->equal +; 62->greater +; 63->question +; 64->at +; 65->A +; 66->B +; 67->C +; 68->D +; 69->E +; 70->F +; 71->G +; 72->H +; 73->I +; 74->J +; 75->K +; 76->L +; 77->M +; 78->N +; 79->O +; 80->P +; 81->Q +; 82->R +; 83->S +; 84->T +; 85->U +; 86->V +; 87->W +; 88->X +; 89->Y +; 90->Z +; 91->bracketleft +; 92->backslash +; 93->bracketright +; 94->asciicircum +; 95->underscore +; 96->grave +; 97->a +; 98->b +; 99->c +; 100->d +; 101->e +; 102->f +; 103->g +; 104->h +; 105->i +; 106->j +; 107->k +; 108->l +; 109->m +; 110->n +; 111->o +; 112->p +; 113->q +; 114->r +; 115->s +; 116->t +; 117->u +; 118->v +; 119->w +; 120->x +; 121->y +; 122->z +; 123->braceleft +; 124->bar +; 125->braceright +; 126->asciitilde +; 127->0x7f +; 128->0x80 + + #enum event-action! [ EVT_NO_DISPATCH ;-- no further msg processing allowed EVT_DISPATCH ;-- allow DispatchMessage call only @@ -102,16 +363,65 @@ get-event-key: func [ evt [red-event!] return: [red-value!] /local - char [red-char!] + char [red-char!] + code [integer!] + res [red-value!] + special? [logic!] ][ as red-value! switch evt/type [ EVT_KEY EVT_KEY_UP EVT_KEY_DOWN [ - char: as red-char! stack/push* - char/header: TYPE_CHAR - char/value: evt/flags and FFFFh - as red-value! char + res: null + code: evt/flags + special?: code and 80000000h <> 0 + code: code and FFFFh + print ["code " code lf] + if special? [ + res: as red-value! switch code [ + RED_VK_PRIOR [_page-up] + RED_VK_NEXT [_page-down] + RED_VK_END [_end] + RED_VK_HOME [_home] + RED_VK_LEFT [_left] + RED_VK_UP [_up] + RED_VK_RIGHT [_right] + RED_VK_DOWN [_down] + RED_VK_INSERT [_insert] + RED_VK_DELETE [_delete] + RED_VK_F1 [_F1] + RED_VK_F2 [_F2] + RED_VK_F3 [_F3] + RED_VK_F4 [_F4] + RED_VK_F5 [_F5] + RED_VK_F6 [_F6] + RED_VK_F7 [_F7] + RED_VK_F8 [_F8] + RED_VK_F9 [_F9] + RED_VK_F10 [_F10] + RED_VK_F11 [_F11] + RED_VK_F12 [_F12] + RED_VK_LSHIFT [_left-shift] + RED_VK_RSHIFT [_right-shift] + RED_VK_LCONTROL [_left-control] + RED_VK_RCONTROL [_right-control] + RED_VK_LMENU [_left-alt] + RED_VK_RMENU [_right-alt] + RED_VK_LWIN [_left-command] + RED_VK_APPS [_right-command] + default [null] + ] + ] + either null? res [ + either all [special? evt/type = EVT_KEY][ + none-value + ][ + char: as red-char! stack/push* + char/header: TYPE_CHAR + char/value: code + as red-value! char + ] + ][res] ] default [as red-value! none-value] ] @@ -203,7 +513,7 @@ make-event: func [ ][ gui-evt/type: evt gui-evt/msg: as byte-ptr! msg - gui-evt/flags: 0 + gui-evt/flags: flags state: EVT_DISPATCH @@ -274,4 +584,41 @@ do-events: func [ ;g_main_context_release GTKApp-Ctx ;@@ release it? ;g_object_unref GTKApp msg? +] + +check-extra-keys: func [ + state [integer!] + return: [integer!] + /local + key [integer!] +][ + key: 0 + if state and GDK_SHIFT_MASK <> 0 [key: EVT_FLAG_SHIFT_DOWN] + if state and GDK_CONTROL_MASK <> 0 [key: key or EVT_FLAG_CTRL_DOWN] + if any [state and GDK_MOD1_MASK <> 0 state and GDK_MOD5_MASK <> 0][key: key or EVT_FLAG_MENU_DOWN] + key +] + +translate-key: func [ + keycode [integer!] + return: [integer!] + /local + key [integer!] + special? [logic!] +][ + print ["keycode: " keycode] + keycode: gdk_keyval_to_upper keycode + print [" keycode2: " keycode] + special?: no + key: case [ + all[keycode >= 30h keycode <= 5Ah][keycode]; RED_VK_0 to RED_VK_Z + all[keycode >= FFBEh keycode <= FFC8h][special?: yes keycode + RED_VK_F1 - FFBEh];RED_VK_F1 to RED_VK_F11 + keycode = FFBFh [special?: yes RED_VK_F12] + keycode = FF0Dh [special?: yes RED_VK_RETURN] + ;@@ To complete! + true [RED_VK_UNKNOWN] + ] + if special? [key: key or 80000000h] + print [" key: " key " F1" RED_VK_F1 lf] + key ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 15d751193e..8d13b0004b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -44,16 +44,18 @@ GdkEventKey!: alias struct! [ keyval [integer!] length [integer!] string [c-string!] - keycode [integer!] ;-- keycode & group & is_modifier - ;guint16 hardware_keycode; - ;guint8 group; - ;guint is_modifier : 1; + keycode1 [byte!] + keycode2 [byte!] + group [byte!] + is_modifier [integer!] ] #enum GdkModifierType! [ GDK_SHIFT_MASK: 1 GDK_LOCK_MASK: 2 GDK_CONTROL_MASK: 4 + GDK_MOD1_MASK: 8 + GDK_MOD5_MASK: 128 ] GtkTextIter!: alias struct! [ @@ -138,6 +140,17 @@ GtkTextIter!: alias struct! [ gdk_screen_get_default: "gdk_screen_get_default" [ return: [handle!] ] + gdk_keymap_get_default: "gdk_keymap_get_default" [ + return: [handle!] + ] + gdk_keyval_name: "gdk_keyval_name" [ + code [integer!] + return: [c-string!] + ] + gdk_keyval_to_upper: "gdk_keyval_to_upper" [ + code [integer!] + return: [integer!] + ] ;; ] ;; LIBGLIB-file cdecl [ g_quark_from_string: "g_quark_from_string" [ @@ -299,6 +312,9 @@ GtkTextIter!: alias struct! [ gtk_widget_queue_draw: "gtk_widget_queue_draw" [ widget [handle!] ] + gtk_widget_queue_resize_no_redraw: "gtk_widget_queue_resize_no_redraw" [ + widget [handle!] + ] gtk_widget_show_all: "gtk_widget_show_all" [ widget [handle!] ] @@ -313,6 +329,24 @@ GtkTextIter!: alias struct! [ width [integer!] height [integer!] ] + gtk_widget_get_size_request: "gtk_widget_get_size_request" [ + widget [handle!] + width [int-ptr!] + height [int-ptr!] + ] + gtk_widget_size_allocate: "gtk_widget_size_allocate" [ + widget [handle!] + alloc [handle!] + ] + gtk_widget_compute_expand: "gtk_widget_compute_expand" [ + widget [handle!] + direction [integer!] + return: [logic!] + ] + gtk_widget_get_allocation: "gtk_widget_get_allocation" [ + widget [handle!] + alloc [handle!] + ] gtk_widget_set_can_focus: "gtk_widget_set_can_focus" [ widget [handle!] focus [logic!] @@ -363,6 +397,23 @@ GtkTextIter!: alias struct! [ x [integer!] y [integer!] ] + gtk_fixed_move: "gtk_fixed_move" [ + fixed [handle!] + widget [handle!] + x [integer!] + y [integer!] + ] + gtk_layout_new: "gtk_layout_new" [ + hadj [handle!] + vadj [handle!] + return: [handle!] + ] + gtk_layout_put: "gtk_layout_put" [ + layout [handle!] + widget [handle!] + x [integer!] + y [integer!] + ] gtk_bin_get_child: "gtk_bin_get_child" [ bin [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index fed492d728..8ef3a51911 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,6 +10,7 @@ Red/System [ } ] +#include %../keycodes.reds #include %gtk.reds #include %events.reds @@ -26,6 +27,8 @@ GTKApp: as handle! 0 GTKApp-Ctx: 0 exit-loop: 0 red-face-id: 0 +_widget-id: 1 +gtk-fixed-id: 2 gtk-style-id: 0 group-radio: as handle! 0 @@ -37,11 +40,28 @@ tabs: context [ pango-context: as handle! 0 gtk-font: "Sans 10" +;last-widget: as handle! 0 + log-pixels-x: 0 log-pixels-y: 0 screen-size-x: 0 screen-size-y: 0 +get-face-object: func [ + handle [handle!] + return: [red-object!] + /local + face [red-object!] + qdata [handle!] +][ + face: as red-object! 0 + qdata: g_object_get_qdata handle red-face-id + if qdata <> as handle! 0 [ + face: as red-object! qdata + ] + face +] + get-face-values: func [ handle [handle!] return: [red-value!] @@ -263,6 +283,62 @@ init: func [][ style-init ] +adjust-sizes: func [ + hWnd [handle!] + return: [integer!] + /local + widget [handle!] + child [handle!] + container [handle!] + rect [RECT_STRUCT] + sx [integer!] + sy [integer!] + dx [integer!] + offset [red-pair!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] +][ + values: get-face-values hWnd + type: as red-word! values + FACE_OBJ_TYPE + pane: as red-block! values + FACE_OBJ_PANE + + sym: symbol/resolve type/symbol + + rect: as RECT_STRUCT allocate (size? RECT_STRUCT) + + widget: g_object_get_qdata hWnd _widget-id + if null? widget [widget: hWnd] + gtk_widget_get_allocation widget as handle! rect + sx: 0 sy: 0 + gtk_widget_get_size_request widget :sx :sy + ;print ["widget->rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom "," sx "x" sy lf] + if TYPE_OF(pane) = TYPE_BLOCK [ + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + container: g_object_get_qdata get-face-handle face gtk-fixed-id + dx: 0 + while [face < tail][ + child: get-face-handle face + unless null? container [ + offset: as red-pair! (object/get-values face) + FACE_OBJ_OFFSET + widget: g_object_get_qdata child _widget-id + if null? widget [widget: child] + gtk_fixed_move container widget offset/x + dx offset/y + ] + dx: dx + adjust-sizes child + + face: face + 1 + ] + ] + free as byte-ptr! rect + + ; return: difference between allocated and requested widths + either sx = -1 [0][rect/right - sx] +] change-rate: func [ hWnd [handle!] @@ -318,6 +394,7 @@ change-size: func [ saved [int-ptr!] method [integer!] ][ + print-line "change-size" ; rc: make-rect size/x size/y 0 0 ; if all [type = button size/y > 32][ ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" NSRegularSquareBezelStyle] @@ -495,6 +572,7 @@ change-offset: func [ ;/local ;rc [NSRect!] ][ + print "change offset" ; rc: make-rect pos/x pos/y 0 0 ; either type = window [ ; rc/y: as float32! screen-size-y - pos/y @@ -978,6 +1056,7 @@ OS-show-window: func [ ][ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd + adjust-sizes as handle! hWnd ] OS-make-view: func [ @@ -1014,6 +1093,7 @@ OS-make-view: func [ fvalue [float!] vertical? [logic!] rfvalue [red-float!] + rect [RECT_STRUCT] ][ stack/mark-func words/_body @@ -1103,6 +1183,8 @@ OS-make-view: func [ ;This depends on version >= 3.2 ;gtk_widget_set_focus_on_click widget yes gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) + ;gobj_signal_connect(widget "size-allocate" :field-size-allocate face/ctx) + ;last-widget: widget ] sym = progress [ widget: gtk_progress_bar_new @@ -1173,7 +1255,7 @@ OS-make-view: func [ parent <> 0 ][ p-sym: get-widget-symbol as handle! parent - if _widget = as handle! 0 [_widget: widget] + either _widget = as handle! 0 [_widget: widget][g_object_set_qdata widget _widget-id _widget ] ; TODO: case to replace with either if no more choice case [ p-sym = tab-panel [ @@ -1194,9 +1276,11 @@ OS-make-view: func [ ] true [ container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] + ;save gtk_fixed container for adjustment since size/x and size/y have to updated in a second pass + g_object_set_qdata widget gtk-fixed-id container + gtk_widget_set_size_request _widget size/x size/y gtk_fixed_put container _widget offset/x offset/y - ;print ["x: " offset/x "y: " offset/y "w: " size/x "h: " size/y lf] ] ] ] @@ -1239,12 +1323,12 @@ OS-update-view: func [ int: int + 1 flags: int/value - ;if flags and FACET_FLAG_OFFSET <> 0 [ - ; change-offset widget as red-pair! values + FACE_OBJ_OFFSET type - ;] - ;if flags and FACET_FLAG_SIZE <> 0 [ - ; change-size widget as red-pair! values + FACE_OBJ_SIZE type - ;] + if flags and FACET_FLAG_OFFSET <> 0 [ + change-offset widget as red-pair! values + FACE_OBJ_OFFSET type + ] + if flags and FACET_FLAG_SIZE <> 0 [ + change-size widget as red-pair! values + FACE_OBJ_SIZE type + ] if flags and FACET_FLAG_TEXT <> 0 [ change-text widget values face type gtk_widget_queue_draw widget diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 9a019f8269..6af9892ee9 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -236,13 +236,44 @@ tab-panel-switch-page: func [ ; Do not use key-press-event since character would not be printed! field-key-release-event: func [ [cdecl] - widget [handle!] + widget [handle!] event-key [GdkEventKey!] - ctx [node!] + ctx [node!] + /local + res [integer!] + key [integer!] + flags [integer!] ][ - print "key-release: " - print-line event-key/keyval + ;print "key-release: " + ;print [ "keyval: " event-key/keyval " -> " gdk_keyval_name event-key/keyval "(" event-key/keyval " -> " gdk_keyval_to_lower event-key/keyval ") et state: " event-key/state lf] + ;print [ "keycode: " as integer! event-key/keycode1 " " as integer! event-key/keycode2 lf] + + if event-key/keyval > FFFFh [exit] + key: translate-key event-key/keyval + flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not + flags: flags or check-extra-keys event-key/state + print ["key: " key " flags: " flags " key or flags: " key or flags lf] + + res: make-event widget key or flags EVT_KEY_DOWN + if res <> EVT_NO_DISPATCH [ + ; either flags and 80000000h <> 0 [ ;-- special key + ; make-event widget key or flags EVT_KEY + ; ][ + ; if key = 8 [ ;-- backspace + make-event widget key or flags EVT_KEY + ; exit + ; ] + ; key: objc_msgSend [event sel_getUid "characters"] + ; if all [ + ; key <> 0 + ; 0 < objc_msgSend [key sel_getUid "length"] + ; ][ + ; key: objc_msgSend [key sel_getUid "characterAtIndex:" 0] + ; make-event widget key or flags EVT_KEY + ; ] + ; ] + ] ] field-move-focus: func [ @@ -254,6 +285,19 @@ field-move-focus: func [ print-line "move-focus" ] +field-size-allocate: func [ + [cdecl] + widget [handle!] + event [handle!] + ctx [node!] + /local + rect [RECT_STRUCT] +][ + print-line "size-allocate" + rect: as RECT_STRUCT event + print [" rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom lf] +] + area-changed: func [ [cdecl] buffer [handle!] From ca250c59e1f2f1cfc7e659721b55f1b05c77cd8d Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 23 Aug 2017 00:21:50 +0200 Subject: [PATCH 0041/3432] Partial fix only for horizontally consecutive widgets --- modules/view/backends/gtk3/gui.reds | 65 +++++++++++++++++++---------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8ef3a51911..97b7f14a23 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -283,17 +283,41 @@ init: func [][ style-init ] -adjust-sizes: func [ +diff-size?: func [ hWnd [handle!] return: [integer!] /local - widget [handle!] - child [handle!] - container [handle!] rect [RECT_STRUCT] sx [integer!] sy [integer!] dx [integer!] + widget [handle!] +][ + widget: g_object_get_qdata hWnd _widget-id + if null? widget [widget: hWnd] + + rect: as RECT_STRUCT allocate (size? RECT_STRUCT) + gtk_widget_get_allocation widget as handle! rect + sx: 0 sy: 0 + gtk_widget_get_size_request widget :sx :sy + print ["widget->rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom "," sx "x" sy lf] + + ; return: difference between allocated and requested widths + dx: rect/right - sx + free as byte-ptr! rect + + dx +] + +adjust-sizes: func [ + hWnd [handle!] + /local + widget [handle!] + child [handle!] + container [handle!] + dx [integer!] + ox [integer!] + oy [integer!] offset [red-pair!] pane [red-block!] type [red-word!] @@ -307,37 +331,33 @@ adjust-sizes: func [ pane: as red-block! values + FACE_OBJ_PANE sym: symbol/resolve type/symbol - - rect: as RECT_STRUCT allocate (size? RECT_STRUCT) - - widget: g_object_get_qdata hWnd _widget-id - if null? widget [widget: hWnd] - gtk_widget_get_allocation widget as handle! rect - sx: 0 sy: 0 - gtk_widget_get_size_request widget :sx :sy - ;print ["widget->rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom "," sx "x" sy lf] + if TYPE_OF(pane) = TYPE_BLOCK [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane + print-line type/symbol container: g_object_get_qdata get-face-handle face gtk-fixed-id - dx: 0 + dx: 0 ox: 0 oy: 0 + print-line "Pane" while [face < tail][ child: get-face-handle face unless null? container [ - offset: as red-pair! (object/get-values face) + FACE_OBJ_OFFSET + offset: as red-pair! (object/get-values face) + FACE_OBJ_OFFSET + if ox > offset/x [dx: 0] widget: g_object_get_qdata child _widget-id if null? widget [widget: child] - gtk_fixed_move container widget offset/x + dx offset/y + print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf] + gtk_fixed_move container widget offset/x + dx offset/y + ox: offset/x oy: offset/y ] - dx: dx + adjust-sizes child - + + dx: dx + diff-size? child + print ["next dx: " dx lf] + adjust-sizes child face: face + 1 ] + print-line "Pane end" ] - free as byte-ptr! rect - - ; return: difference between allocated and requested widths - either sx = -1 [0][rect/right - sx] ] change-rate: func [ @@ -1057,6 +1077,7 @@ OS-show-window: func [ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd adjust-sizes as handle! hWnd + gtk_widget_queue_draw as handle! hWnd ] OS-make-view: func [ From e9b693eca22539e0d78409883065e24fd0cd65f3 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 23 Aug 2017 07:49:38 +0200 Subject: [PATCH 0042/3432] Add system/view/gtk-auto-adjust? To control whether to apply second pass gtk adjustment or not automatically --- modules/view/backends/gtk3/gtk.reds | 7 +++++++ modules/view/backends/gtk3/gui.reds | 19 ++++++++++++------- modules/view/view.red | 3 +++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 8d13b0004b..2b660714ea 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -35,6 +35,13 @@ tagSIZE: alias struct! [ height [integer!] ] +tagRECT: alias struct! [ + x [integer!] + y [integer!] + width [integer!] + height [integer!] +] + GdkEventKey!: alias struct! [ type [integer!] window [int-ptr!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 97b7f14a23..79431b2018 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -287,7 +287,7 @@ diff-size?: func [ hWnd [handle!] return: [integer!] /local - rect [RECT_STRUCT] + rect [tagRECT] sx [integer!] sy [integer!] dx [integer!] @@ -296,14 +296,14 @@ diff-size?: func [ widget: g_object_get_qdata hWnd _widget-id if null? widget [widget: hWnd] - rect: as RECT_STRUCT allocate (size? RECT_STRUCT) + rect: as tagRECT allocate (size? tagRECT) gtk_widget_get_allocation widget as handle! rect sx: 0 sy: 0 gtk_widget_get_size_request widget :sx :sy - print ["widget->rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom "," sx "x" sy lf] + print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height "," sx "x" sy lf] ; return: difference between allocated and requested widths - dx: rect/right - sx + dx: rect/width - sx free as byte-ptr! rect dx @@ -1073,11 +1073,16 @@ OS-refresh-window: func [hWnd [integer!]][0] OS-show-window: func [ hWnd [integer!] + /local + auto-adjust? [red-logic!] ][ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd - adjust-sizes as handle! hWnd - gtk_widget_queue_draw as handle! hWnd + auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? + if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ + adjust-sizes as handle! hWnd + gtk_widget_queue_draw as handle! hWnd + ] ] OS-make-view: func [ @@ -1297,7 +1302,7 @@ OS-make-view: func [ ] true [ container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] - ;save gtk_fixed container for adjustment since size/x and size/y have to updated in a second pass + ;save gtk_fixed container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass g_object_set_qdata widget gtk-fixed-id container gtk_widget_set_size_request _widget size/x size/y diff --git a/modules/view/view.red b/modules/view/view.red index 561f76ec65..4b49d08109 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -643,6 +643,9 @@ system/view: context [ auto-sync?: yes ;-- refresh faces on changes automatically debug?: no ;-- output verbose logs silent?: no ;-- do not report errors (livecoding) + #if config/OS = 'Linux [ + gtk-auto-adjust?: yes ;-- do not apply automatically gtk3 adjustment + ] ] #include %backends/platform.red From 4f0136948a3f1a7df4efa8f2d67a1d8c7bf2a876 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 23 Aug 2017 08:04:23 +0200 Subject: [PATCH 0043/3432] Revert gtk-auto-adjust? environment variable --- modules/view/view.red | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/view/view.red b/modules/view/view.red index 4b49d08109..561f76ec65 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -643,9 +643,6 @@ system/view: context [ auto-sync?: yes ;-- refresh faces on changes automatically debug?: no ;-- output verbose logs silent?: no ;-- do not report errors (livecoding) - #if config/OS = 'Linux [ - gtk-auto-adjust?: yes ;-- do not apply automatically gtk3 adjustment - ] ] #include %backends/platform.red From adf9cb6d77b5a9598235a94838f389f9eb28c819 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 23 Aug 2017 14:42:42 +0200 Subject: [PATCH 0044/3432] Improvement of adjustment 2nd pass --- modules/view/backends/gtk3/gui.reds | 106 ++++++++++++++++++---------- 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 79431b2018..b65dbd9a7f 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -283,81 +283,109 @@ init: func [][ style-init ] -diff-size?: func [ - hWnd [handle!] - return: [integer!] - /local - rect [tagRECT] - sx [integer!] - sy [integer!] - dx [integer!] - widget [handle!] +get-symbol-name: function [ + sym [integer!] + return: [c-string!] ][ - widget: g_object_get_qdata hWnd _widget-id - if null? widget [widget: hWnd] - - rect: as tagRECT allocate (size? tagRECT) - gtk_widget_get_allocation widget as handle! rect - sx: 0 sy: 0 - gtk_widget_get_size_request widget :sx :sy - print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height "," sx "x" sy lf] - - ; return: difference between allocated and requested widths - dx: rect/width - sx - free as byte-ptr! rect - - dx + case [ + sym = check ["check"] + sym = radio ["radio"] + sym = button ["button"] + sym = base ["base"] + sym = window ["window"] + sym = slider ["slider"] + sym = text ["text"] + sym = field ["field"] + sym = progress ["progress"] + sym = area ["area"] + sym = group-box ["group-box"] + sym = panel ["panel"] + sym = tab-panel ["tab-panel"] + sym = text-list ["text-list"] + sym = drop-list ["drop-list"] + sym = drop-down ["drop-down"] + true ["other widget"] + ] ] - +; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane adjust-sizes: func [ hWnd [handle!] /local widget [handle!] child [handle!] container [handle!] + rect [tagRECT] dx [integer!] + dy [integer!] ox [integer!] oy [integer!] + sx [integer!] + sy [integer!] offset [red-pair!] + size [red-pair!] pane [red-block!] type [red-word!] sym [integer!] face [red-object!] tail [red-object!] values [red-value!] + overlap? [logic!] + ; these ones would be removed + debug [logic!] + cpt [integer!] ][ + ; to remove when saitsfactory enough development + debug: no + values: get-face-values hWnd type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE sym: symbol/resolve type/symbol + + rect: as tagRECT allocate (size? tagRECT) if TYPE_OF(pane) = TYPE_BLOCK [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane - print-line type/symbol + if debug [print ["Parent type: " get-symbol-name sym lf]] container: g_object_get_qdata get-face-handle face gtk-fixed-id - dx: 0 ox: 0 oy: 0 - print-line "Pane" + dx: 0 dy: 0 + ox: 0 oy: 0 sx: 0 sy: 0 + cpt: 0 while [face < tail][ + cpt: cpt + 1 child: get-face-handle face - unless null? container [ - offset: as red-pair! (object/get-values face) + FACE_OBJ_OFFSET - if ox > offset/x [dx: 0] + values: object/get-values face + offset: as red-pair! values + FACE_OBJ_OFFSET + size: as red-pair! values + FACE_OBJ_SIZE + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] + if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] + ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 + if any [ox > offset/x not overlap?] [dx: 0] + unless null? container [ widget: g_object_get_qdata child _widget-id if null? widget [widget: child] - print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf] + if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] gtk_fixed_move container widget offset/x + dx offset/y - ox: offset/x oy: offset/y + gtk_widget_get_allocation widget as handle! rect + ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates + if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] ] - - dx: dx + diff-size? child - print ["next dx: " dx lf] + ; save previous offset and size coordinates + ox: offset/x oy: offset/y sx: size/x sy: size/y + if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] + dx: dx + rect/width - sx + dy: dy + rect/height - sy + if debug [ print ["next dx: " dx lf]] adjust-sizes child face: face + 1 ] - print-line "Pane end" + if debug [print-line "Pane end"] ] + free as byte-ptr! rect ] change-rate: func [ @@ -1078,11 +1106,11 @@ OS-show-window: func [ ][ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd - auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? - if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ + ;auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? + ;if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ adjust-sizes as handle! hWnd gtk_widget_queue_draw as handle! hWnd - ] + ;] ] OS-make-view: func [ From e0720d910d5b4573be5666cc2942a62507b771b6 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 23 Aug 2017 20:49:01 +0200 Subject: [PATCH 0045/3432] remove some unused code --- modules/view/backends/gtk3/events.reds | 261 ----------------------- modules/view/backends/gtk3/font.reds | 9 +- modules/view/backends/gtk3/gui.reds | 5 +- modules/view/backends/gtk3/handlers.reds | 30 +-- 4 files changed, 4 insertions(+), 301 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 176ca75789..030ab30f34 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -10,267 +10,6 @@ Red/System [ } ] -keycode-table: [ - RED_VK_A ;-- 0 - RED_VK_S ;-- 1 - RED_VK_D ;-- 2 - RED_VK_F ;-- 3 - RED_VK_H ;-- 4 - RED_VK_G ;-- 5 - RED_VK_Z ;-- 6 - RED_VK_X ;-- 7 - RED_VK_C ;-- 8 - RED_VK_V ;-- 9 - RED_VK_OEM_3 ;-- 0x0A Section key. - RED_VK_B ;-- 0x0B - RED_VK_Q ;-- 0x0C - RED_VK_W ;-- 0x0D - RED_VK_E ;-- 0x0E - RED_VK_R ;-- 0x0F - RED_VK_Y ;-- 0x10 - RED_VK_T ;-- 0x11 - RED_VK_1 ;-- 0x12 - RED_VK_2 ;-- 0x13 - RED_VK_3 ;-- 0x14 - RED_VK_4 ;-- 0x15 - RED_VK_6 ;-- 0x16 - RED_VK_5 ;-- 0x17 - RED_VK_OEM_PLUS ;-- 0x18 =+ - RED_VK_9 ;-- 0x19 - RED_VK_7 ;-- 0x1A - RED_VK_OEM_MINUS ;-- 0x1B -_ - RED_VK_8 ;-- 0x1C - RED_VK_0 ;-- 0x1D - RED_VK_OEM_6 ;-- 0x1E ]} - RED_VK_O ;-- 0x1F - RED_VK_U ;-- 0x20 - RED_VK_OEM_4 ;-- 0x21 {[ - RED_VK_I ;-- 0x22 - RED_VK_P ;-- 0x23 - RED_VK_RETURN ;-- 0x24 Return - RED_VK_L ;-- 0x25 - RED_VK_J ;-- 0x26 - RED_VK_OEM_7 ;-- 0x27 '" - RED_VK_K ;-- 0x28 - RED_VK_OEM_1 ;-- 0x29 ;: - RED_VK_OEM_5 ;-- 0x2A \| - RED_VK_OEM_COMMA ;-- 0x2B < - RED_VK_OEM_2 ;-- 0x2C /? - RED_VK_N ;-- 0x2D - RED_VK_M ;-- 0x2E - RED_VK_OEM_PERIOD ;-- 0x2F .> - RED_VK_TAB ;-- 0x30 - RED_VK_SPACE ;-- 0x31 - RED_VK_OEM_3 ;-- 0x32 `~ - RED_VK_BACK ;-- 0x33 Backspace - RED_VK_UNKNOWN ;-- 0x34 n/a - RED_VK_ESCAPE ;-- 0x35 - RED_VK_APPS ;-- 0x36 Right Command - RED_VK_LWIN ;-- 0x37 Left Command - RED_VK_SHIFT ;-- 0x38 Left Shift - RED_VK_CAPITAL ;-- 0x39 Caps Lock - RED_VK_MENU ;-- 0x3A Left Option - RED_VK_CONTROL ;-- 0x3B Left Ctrl - RED_VK_SHIFT ;-- 0x3C Right Shift - RED_VK_MENU ;-- 0x3D Right Option - RED_VK_CONTROL ;-- 0x3E Right Ctrl - RED_VK_UNKNOWN ;-- 0x3F fn - RED_VK_F17 ;-- 0x40 - RED_VK_DECIMAL ;-- 0x41 Num Pad . - RED_VK_UNKNOWN ;-- 0x42 n/a - RED_VK_MULTIPLY ;-- 0x43 Num Pad * - RED_VK_UNKNOWN ;-- 0x44 n/a - RED_VK_ADD ;-- 0x45 Num Pad + - RED_VK_UNKNOWN ;-- 0x46 n/a - RED_VK_CLEAR ;-- 0x47 Num Pad Clear - RED_VK_VOLUME_UP ;-- 0x48 - RED_VK_VOLUME_DOWN ;-- 0x49 - RED_VK_VOLUME_MUTE ;-- 0x4A - RED_VK_DIVIDE ;-- 0x4B Num Pad / - RED_VK_RETURN ;-- 0x4C Num Pad Enter - RED_VK_UNKNOWN ;-- 0x4D n/a - RED_VK_SUBTRACT ;-- 0x4E Num Pad - - RED_VK_F18 ;-- 0x4F - RED_VK_F19 ;-- 0x50 - RED_VK_OEM_PLUS ;-- 0x51 Num Pad =. - RED_VK_NUMPAD0 ;-- 0x52 - RED_VK_NUMPAD1 ;-- 0x53 - RED_VK_NUMPAD2 ;-- 0x54 - RED_VK_NUMPAD3 ;-- 0x55 - RED_VK_NUMPAD4 ;-- 0x56 - RED_VK_NUMPAD5 ;-- 0x57 - RED_VK_NUMPAD6 ;-- 0x58 - RED_VK_NUMPAD7 ;-- 0x59 - RED_VK_F20 ;-- 0x5A - RED_VK_NUMPAD8 ;-- 0x5B - RED_VK_NUMPAD9 ;-- 0x5C - RED_VK_UNKNOWN ;-- 0x5D Yen (JIS Keyboard Only) - RED_VK_UNKNOWN ;-- 0x5E Underscore (JIS Keyboard Only) - RED_VK_UNKNOWN ;-- 0x5F KeypadComma (JIS Keyboard Only) - RED_VK_F5 ;-- 0x60 - RED_VK_F6 ;-- 0x61 - RED_VK_F7 ;-- 0x62 - RED_VK_F3 ;-- 0x63 - RED_VK_F8 ;-- 0x64 - RED_VK_F9 ;-- 0x65 - RED_VK_UNKNOWN ;-- 0x66 Eisu (JIS Keyboard Only) - RED_VK_F11 ;-- 0x67 - RED_VK_UNKNOWN ;-- 0x68 Kana (JIS Keyboard Only) - RED_VK_F13 ;-- 0x69 - RED_VK_F16 ;-- 0x6A - RED_VK_F14 ;-- 0x6B - RED_VK_UNKNOWN ;-- 0x6C n/a - RED_VK_F10 ;-- 0x6D - RED_VK_UNKNOWN ;-- 0x6E n/a (Windows95 key?) - RED_VK_F12 ;-- 0x6F - RED_VK_UNKNOWN ;-- 0x70 n/a - RED_VK_F15 ;-- 0x71 - RED_VK_INSERT ;-- 0x72 Help - RED_VK_HOME ;-- 0x73 Home - RED_VK_PRIOR ;-- 0x74 Page Up - RED_VK_DELETE ;-- 0x75 Forward Delete - RED_VK_F4 ;-- 0x76 - RED_VK_END ;-- 0x77 End - RED_VK_F2 ;-- 0x78 - RED_VK_NEXT ;-- 0x79 Page Down - RED_VK_F1 ;-- 0x7A - RED_VK_LEFT ;-- 0x7B Left Arrow - RED_VK_RIGHT ;-- 0x7C Right Arrow - RED_VK_DOWN ;-- 0x7D Down Arrow - RED_VK_UP ;-- 0x7E Up Arrow - RED_VK_UNKNOWN ;-- 0x7F n/a -] - -; RED_VK_UNKNOWN 1->0x1 -; RED_VK_UNKNOWN 2->0x2 -; RED_VK_UNKNOWN 3->0x3 -; RED_VK_UNKNOWN 4->0x4 -; RED_VK_UNKNOWN 5->0x5 -; RED_VK_UNKNOWN 6->0x6 -; RED_VK_UNKNOWN 7->0x7 -; RED_VK_UNKNOWN 8->0x8 -; 9->0x9 -; 10->0xa -; 11->0xb -; 12->0xc -; 13->0xd -; 14->0xe -; 15->0xf -; 16->0x10 -; 17->0x11 -; 18->0x12 -; 19->0x13 -; 20->0x14 -; 21->0x15 -; 22->0x16 -; 23->0x17 -; 24->0x18 -; 25->0x19 -; 26->0x1a -; 27->0x1b -; 28->0x1c -; 29->0x1d -; 30->0x1e -; 31->0x1f -; 32->space -; 33->exclam -; 34->quotedbl -; 35->numbersign -; 36->dollar -; 37->percent -; 38->ampersand -; 39->apostrophe -; 40->parenleft -; 41->parenright -; 42->asterisk -; 43->plus -; 44->comma -; 45->minus -; 46->period -; 47->slash -; 48->0 -; 49->1 -; 50->2 -; 51->3 -; 52->4 -; 53->5 -; 54->6 -; 55->7 -; 56->8 -; 57->9 -; 58->colon -; 59->semicolon -; 60->less -; 61->equal -; 62->greater -; 63->question -; 64->at -; 65->A -; 66->B -; 67->C -; 68->D -; 69->E -; 70->F -; 71->G -; 72->H -; 73->I -; 74->J -; 75->K -; 76->L -; 77->M -; 78->N -; 79->O -; 80->P -; 81->Q -; 82->R -; 83->S -; 84->T -; 85->U -; 86->V -; 87->W -; 88->X -; 89->Y -; 90->Z -; 91->bracketleft -; 92->backslash -; 93->bracketright -; 94->asciicircum -; 95->underscore -; 96->grave -; 97->a -; 98->b -; 99->c -; 100->d -; 101->e -; 102->f -; 103->g -; 104->h -; 105->i -; 106->j -; 107->k -; 108->l -; 109->m -; 110->n -; 111->o -; 112->p -; 113->q -; 114->r -; 115->s -; 116->t -; 117->u -; 118->v -; 119->w -; 120->x -; 121->y -; 122->z -; 123->braceleft -; 124->bar -; 125->braceright -; 126->asciitilde -; 127->0x7f -; 128->0x80 - - #enum event-action! [ EVT_NO_DISPATCH ;-- no further msg processing allowed EVT_DISPATCH ;-- allow DispatchMessage call only diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 68aef8e574..7258afe9b5 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -104,7 +104,7 @@ make-font: func [ hFont: get-font-handle font unless null? hFont [g_free hFont] - css: g_strdup_printf ["* {"] + css: g_strdup_printf ["* {"] unless null? face [ bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR @@ -138,7 +138,7 @@ make-font: func [ unless zero? len [ loop len [ sym: symbol/resolve style/symbol - case [ ;OLD -> class: case [ + case [ sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold;" css]] sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration-line: underline;" css]] @@ -157,8 +157,6 @@ make-font: func [ css: add-to-string css "%s}" null - ;print ["css: " css lf] - hFont: as handle! css blk: as red-block! values + FONT_OBJ_STATE @@ -176,7 +174,6 @@ make-font: func [ block/rs-append blk as red-value! face ] -; ] hFont ] @@ -282,8 +279,6 @@ font-description: func [ color: as red-tuple! values + FONT_OBJ_COLOR ;anti-alias?: - - fd: pango_font_description_new if TYPE_OF(str) = TYPE_STRING [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b65dbd9a7f..e7116e739d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1232,13 +1232,11 @@ OS-make-view: func [ buffer: gtk_entry_get_buffer widget unless null? caption [gtk_entry_buffer_set_text buffer caption -1] gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) - ;gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) + ;Do not work: gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) gtk_widget_set_can_focus widget yes ;This depends on version >= 3.2 ;gtk_widget_set_focus_on_click widget yes gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) - ;gobj_signal_connect(widget "size-allocate" :field-size-allocate face/ctx) - ;last-widget: widget ] sym = progress [ widget: gtk_progress_bar_new @@ -1299,7 +1297,6 @@ OS-make-view: func [ ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - ;OLD: create-widget-style widget face make-font-provider widget change-font widget face font sym diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6af9892ee9..be327598f2 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -257,22 +257,7 @@ field-key-release-event: func [ res: make-event widget key or flags EVT_KEY_DOWN if res <> EVT_NO_DISPATCH [ - ; either flags and 80000000h <> 0 [ ;-- special key - ; make-event widget key or flags EVT_KEY - ; ][ - ; if key = 8 [ ;-- backspace - make-event widget key or flags EVT_KEY - ; exit - ; ] - ; key: objc_msgSend [event sel_getUid "characters"] - ; if all [ - ; key <> 0 - ; 0 < objc_msgSend [key sel_getUid "length"] - ; ][ - ; key: objc_msgSend [key sel_getUid "characterAtIndex:" 0] - ; make-event widget key or flags EVT_KEY - ; ] - ; ] + make-event widget key or flags EVT_KEY ] ] @@ -285,19 +270,6 @@ field-move-focus: func [ print-line "move-focus" ] -field-size-allocate: func [ - [cdecl] - widget [handle!] - event [handle!] - ctx [node!] - /local - rect [RECT_STRUCT] -][ - print-line "size-allocate" - rect: as RECT_STRUCT event - print [" rect:" rect/left "x" rect/top "x" rect/right "x" rect/bottom lf] -] - area-changed: func [ [cdecl] buffer [handle!] From 7456b20fe5cbcc1b83aa68dc1163be70fa784ba3 Mon Sep 17 00:00:00 2001 From: R cqls Date: Thu, 24 Aug 2017 19:43:59 +0200 Subject: [PATCH 0046/3432] rate (on-time) and rotate Eve-clock is almost there! --- modules/view/backends/gtk3/draw.reds | 17 ++- modules/view/backends/gtk3/gtk.reds | 18 +++ modules/view/backends/gtk3/gui.reds | 145 +++++++++++++---------- modules/view/backends/gtk3/handlers.reds | 9 ++ 4 files changed, 117 insertions(+), 72 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 71669ba191..dd24c94b57 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -452,16 +452,15 @@ OS-matrix-rotate: func [ angle [red-integer!] center [red-pair!] /local - m [integer!] - pts [tagPOINT] + cr [handle!] + rad [float!] ][ - if angle <> as red-integer! center [ -0 - ] - ;GdipRotateWorldTransform dc/graphics get-float32 angle GDIPLUS_MATRIXORDERAPPEND - if angle <> as red-integer! center [ -0 - ] + cr: dc/raw + rad: PI / 180.0 * get-float angle + cairo_translate cr as float! center/x as float! center/y + cairo_rotate cr rad + do-paint dc + cairo_translate cr as float! (0 - center/x) as float! (0 - center/y) ] OS-matrix-scale: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 2b660714ea..2f5b320eed 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -136,6 +136,15 @@ GtkTextIter!: alias struct! [ g_object_unref: "g_object_unref" [ object [int-ptr!] ] + g_source_remove: "g_source_remove" [ + timer [integer!] + ] + g_timeout_add: "g_timeout_add" [ + ts [integer!] + handler [integer!] + data [int-ptr!] + return: [integer!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ @@ -842,5 +851,14 @@ GtkTextIter!: alias struct! [ cairo_pattern_destroy: "cairo_pattern_destroy" [ pattern [handle!] ] + cairo_rotate: "cairo_rotate" [ + cr [handle!] + angle [float!] + ] + cairo_translate: "cairo_translate" [ + cr [handle!] + x [float!] + y [float!] + ] ] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e7116e739d..548e21c9a0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -29,6 +29,8 @@ exit-loop: 0 red-face-id: 0 _widget-id: 1 gtk-fixed-id: 2 +red-timer-id: 3 + gtk-style-id: 0 group-radio: as handle! 0 @@ -55,9 +57,11 @@ get-face-object: func [ qdata [handle!] ][ face: as red-object! 0 - qdata: g_object_get_qdata handle red-face-id - if qdata <> as handle! 0 [ - face: as red-object! qdata + unless null? handle [ + qdata: g_object_get_qdata handle red-face-id + if qdata <> as handle! 0 [ + face: as red-object! qdata + ] ] face ] @@ -71,10 +75,12 @@ get-face-values: func [ values [red-value!] ][ values: as red-value! 0 - qdata: g_object_get_qdata handle red-face-id - if qdata <> as handle! 0 [ - face: as red-object! qdata - values: object/get-values face + unless null? handle [ + qdata: g_object_get_qdata handle red-face-id + if qdata <> as handle! 0 [ + face: as red-object! qdata + values: object/get-values face + ] ] values ] @@ -241,6 +247,7 @@ free-handles: func [ type [red-word!] face [red-object!] tail [red-object!] + rate [red-value!] pane [red-block!] state [red-value!] sym [integer!] @@ -250,6 +257,9 @@ free-handles: func [ type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol + rate: values + FACE_OBJ_RATE + if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] + pane: as red-block! values + FACE_OBJ_PANE if TYPE_OF(pane) = TYPE_BLOCK [ face: as red-object! block/rs-head pane @@ -394,38 +404,38 @@ change-rate: func [ /local int [red-integer!] tm [red-time!] - timer [integer!] ts [float!] + timer [integer!] + data [handle!] ][ - ; timer: objc_getAssociatedObject hWnd RedTimerKey - - ; if timer <> 0 [ ;-- cancel a preexisting timer - ; objc_msgSend [timer sel_getUid "invalidate"] - ; objc_setAssociatedObject hWnd RedTimerKey 0 OBJC_ASSOCIATION_ASSIGN - ; ] + unless null? hWnd [ + data: g_object_get_qdata hWnd red-timer-id + timer: either data = as handle! 0 [0][as integer! data] + + print ["timer: " timer lf] + + if timer <> 0 [ ;-- cancel a preexisting timeout + g_source_remove timer + ] - ; switch TYPE_OF(rate) [ - ; TYPE_INTEGER [ - ; int: as red-integer! rate - ; if int/value <= 0 [fire [TO_ERROR(script invalid-facet-type) rate]] - ; ts: 1.0 / as-float int/value - ; ] - ; TYPE_TIME [ - ; tm: as red-time! rate - ; if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] - ; ts: tm/time / 1E9 - ; ] - ; TYPE_NONE [exit] - ; default [fire [TO_ERROR(script invalid-facet-type) rate]] - ; ] + switch TYPE_OF(rate) [ + TYPE_INTEGER [ + int: as red-integer! rate + if int/value <= 0 [fire [TO_ERROR(script invalid-facet-type) rate]] + ts: 1.0 / as-float int/value + ] + TYPE_TIME [ + tm: as red-time! rate + if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] + ts: tm/time / 1E9 + ] + TYPE_NONE [exit] + default [fire [TO_ERROR(script invalid-facet-type) rate]] + ] - ; timer: objc_msgSend [ - ; objc_getClass "NSTimer" - ; sel_getUid "scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:" - ; ts hWnd sel-on-timer 0 yes - ; ] - ; objc_setAssociatedObject hWnd RedTimerKey timer OBJC_ASSOCIATION_ASSIGN - 0 + timer: g_timeout_add as integer! ts as integer! :red-timer-action hWnd + g_object_set_qdata hWnd red-timer-id as int-ptr! timer + ] ] change-size: func [ @@ -699,35 +709,31 @@ change-text: func [ ] if null? cstr [exit] - either type = area [ - ; objc_msgSend [ - ; objc_msgSend [hWnd sel_getUid "documentView"] - ; sel_getUid "setString:" txt - 0 - ; ] - ][ - ;unless change-font hWnd face as red-object! values + FACE_OBJ_FONT type [ - case [ - type = text [ - gtk_label_set_text hWnd cstr - ] - type = field [ - buffer: gtk_entry_get_buffer hWnd - gtk_entry_buffer_set_text buffer cstr -1 - ] - any [type = button type = radio type = check] [ - gtk_button_set_label hWnd cstr - ] - type = window [ - gtk_window_set_title hWnd cstr - ] - type = group-box [ - gtk_frame_set_label hWnd cstr - ] - true [0] + ;unless change-font hWnd face as red-object! values + FACE_OBJ_FONT type [ + case [ + type = area [ + buffer: gtk_text_view_get_buffer hWnd + gtk_text_buffer_set_text buffer cstr -1 ] - ;] - ] + type = text [ + gtk_label_set_text hWnd cstr + ] + type = field [ + buffer: gtk_entry_get_buffer hWnd + gtk_entry_buffer_set_text buffer cstr -1 + ] + any [type = button type = radio type = check] [ + gtk_button_set_label hWnd cstr + ] + type = window [ + gtk_window_set_title hWnd cstr + ] + type = group-box [ + gtk_frame_set_label hWnd cstr + ] + true [0] + ] + ;] ] change-data: func [ @@ -1135,6 +1141,7 @@ OS-make-view: func [ para [red-object!] flags [integer!] bits [integer!] + rate [red-value!] sym [integer!] p-sym [integer!] caption [c-string!] @@ -1167,6 +1174,7 @@ OS-make-view: func [ menu: as red-block! values + FACE_OBJ_MENU selected: as red-integer! values + FACE_OBJ_SELECTED para: as red-object! values + FACE_OBJ_PARA + rate: as red-value! values + FACE_OBJ_RATE sym: symbol/resolve type/symbol @@ -1340,6 +1348,17 @@ OS-make-view: func [ assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events store-face-to-obj widget face + ; change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym + ; change-para widget face as red-object! values + FACE_OBJ_PARA font sym + + ; unless show?/value [change-visible widget no sym] + ; unless open?/value [change-enabled widget no sym] + + ; change-font widget face font sym + if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] + ; if sym <> base [change-color widget as red-tuple! values + FACE_OBJ_COLOR sym] + + stack/unwind as-integer widget ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index be327598f2..3ae45ed26b 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -293,3 +293,12 @@ area-changed: func [ make-event widget 0 EVT_CHANGE ] ] + +red-timer-action: func [ + [cdecl] + self [handle!] + return: [logic!] +][ + make-event self 0 EVT_TIME + yes +] From a349c3eed82ee4772e0325a7419e0cd94d91f358 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 26 Aug 2017 09:46:19 +0200 Subject: [PATCH 0047/3432] Destroy management required for live coding + Cairo render text started --- modules/view/backends/gtk3/draw.reds | 25 +++- modules/view/backends/gtk3/font.reds | 81 +++++++++++++ modules/view/backends/gtk3/gtk.reds | 49 ++++++++ modules/view/backends/gtk3/gui.reds | 148 +++++++++++++++++++---- modules/view/backends/gtk3/handlers.reds | 110 ++++++++++++++++- 5 files changed, 383 insertions(+), 30 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index dd24c94b57..2a83819a7a 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -77,9 +77,9 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ cairo_set_source cr dc/pattern ] cairo_fill_preserve cr + unless dc/pen? [set-source-color cr dc/pen-color cairo_stroke cr] cairo_restore cr ] - if dc/pen? [cairo_stroke cr] ] OS-draw-anti-alias: func [ @@ -230,7 +230,7 @@ OS-draw-circle: func [ ][ x: as-float center/x y: as-float center/y - cairo_arc dc/raw x y as-float radius/value 0.0 2.0 * pi + cairo_arc dc/raw x y as-float radius/value 0.0 2.0 * pi + 1 do-paint dc ] @@ -263,6 +263,7 @@ OS-draw-text: func [ str [c-string!] len [integer!] ][ + print-line "draw text" 0 ] @@ -468,8 +469,12 @@ OS-matrix-scale: func [ pen [integer!] sx [red-integer!] sy [red-integer!] + /local + cr [handle!] ][ -0 + cr: dc/raw + cairo_scale cr as-float sx/value as-float sy/value + do-paint dc ] OS-matrix-translate: func [ @@ -477,8 +482,12 @@ OS-matrix-translate: func [ pen [integer!] x [integer!] y [integer!] + /local + cr [handle!] ][ -0 + cr: dc/raw + cairo_translate cr as-float x as-float y + do-paint dc ] OS-matrix-skew: func [ @@ -527,7 +536,13 @@ OS-matrix-pop: func [dc [draw-ctx!]][0] OS-matrix-reset: func [ dc [draw-ctx!] pen [integer!] -][] + /local + cr [handle!] +][ + cr: dc/raw + cairo_identity_matrix cr + do-paint dc +] OS-matrix-invert: func [ dc [draw-ctx!] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 7258afe9b5..798ad8a857 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -323,6 +323,87 @@ font-description: func [ fd ] +#enum cairo_font_slant_t! [ + CAIRO_FONT_SLANT_NORMAL + CAIRO_FONT_SLANT_ITALIC + CAIRO_FONT_SLANT_OBLIQUE +] + +#enum cairo_font_weight_t! [ + CAIRO_FONT_WEIGHT_NORMAL + CAIRO_FONT_WEIGHT_BOLD +] + +select-cairo-font: func [ + cr [handle!] + font [red-object!] + /local + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + css [c-string!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] + slant [integer!] + weight [integer!] +][ + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + slant: CAIRO_FONT_SLANT_NORMAL + weight: CAIRO_FONT_WEIGHT_NORMAL + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] + sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] + sym = _underline [] + sym = _strike [] + true [] + ] + style: style + 1 + ] + ] + + ;cairo_select_font_face cr name slant weight + cairo_select_font_face cr "Arial" 0 0 + + if TYPE_OF(size) = TYPE_INTEGER [ + print ["size: " size/value lf] + cairo_set_font_size cr size/value + ] +] + OS-request-font: func [ font [red-object!] selected [red-object!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 2f5b320eed..721c334e18 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -89,6 +89,15 @@ GtkTextIter!: alias struct! [ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] +cairo_text_extents_t!: alias struct! [ + x_bearing [float!] + y_bearing [float!] + width [float!] + height [float!] + x_advance [float!] + y_advance [float!] +] + #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" ;#define LIBGLIB-file "libglib-2.0-0.dll" @@ -192,6 +201,11 @@ GtkTextIter!: alias struct! [ list [int-ptr!] return: [integer!] ] + g_list_nth_data: "g_list_nth_data" [ + list [int-ptr!] + nth [integer!] + return: [handle!] + ] g_ascii_dtostr: "g_ascii_dtostr" [ buffer [c-string!] buf_len [integer!] @@ -387,6 +401,11 @@ GtkTextIter!: alias struct! [ container [handle!] return: [int-ptr!] ] + gtk_container_foreach: "gtk_container_foreach" [ + container [handle!] + handler [integer!] + data [int-ptr!] + ] gtk_frame_new: "gtk_frame_new" [ label [c-string!] return: [handle!] @@ -860,5 +879,35 @@ GtkTextIter!: alias struct! [ x [float!] y [float!] ] + cairo_scale: "cairo_scale" [ + cr [handle!] + x [float!] + y [float!] + ] + cairo_identity_matrix: "cairo_identity_matrix" [ + cr [handle!] + ] + cairo_stroke_preserve: "cairo_stroke_preserve" [ + cr [handle!] + ] + cairo_select_font_face: "cairo_select_font_face" [ + cr [handle!] + family [c-string!] + slant [integer!] + weight [integer!] + ] + cairo_set_font_size: "cairo_set_font_size" [ + cr [handle!] + size [integer!] + ] + cairo_text_extents: "cairo_text_extents" [ + cr [handle!] + text [c-string!] + extents [handle!] + ] + cairo_show_text: "cairo_show_text" [ + cr [handle!] + text [c-string!] + ] ] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 548e21c9a0..7fff5445e5 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -42,7 +42,7 @@ tabs: context [ pango-context: as handle! 0 gtk-font: "Sans 10" -;last-widget: as handle! 0 +last-widget: as handle! 0 log-pixels-x: 0 log-pixels-y: 0 @@ -245,13 +245,9 @@ free-handles: func [ /local values [red-value!] type [red-word!] - face [red-object!] - tail [red-object!] rate [red-value!] - pane [red-block!] state [red-value!] sym [integer!] - dc [integer!] ][ values: get-face-values hWnd type: as red-word! values + FACE_OBJ_TYPE @@ -260,18 +256,108 @@ free-handles: func [ rate: values + FACE_OBJ_RATE if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] - pane: as red-block! values + FACE_OBJ_PANE + g_object_set_qdata hWnd red-face-id null + g_object_set_qdata hWnd _widget-id null + g_object_set_qdata hWnd gtk-fixed-id null + g_object_set_qdata hWnd red-timer-id null + + ;gtk_widget_destroy manages eveything for free from the gtk side! + gtk_widget_destroy hWnd + + state: values + FACE_OBJ_STATE + state/header: TYPE_NONE +] + +; Debug function to show children tree +debug-show-children: func [ + hWnd [handle!] + parent? [logic!] + /local + widget [handle!] + child [handle!] + container [handle!] + rect [tagRECT] + sx [integer!] + sy [integer!] + offset [red-pair!] + size [red-pair!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] + overlap? [logic!] + ; these ones would be removed + debug [logic!] + cpt [integer!] +][ + ; to remove when saitsfactory enough development + debug: yes + + values: get-face-values hWnd + type: as red-word! values + FACE_OBJ_TYPE + pane: as red-block! values + FACE_OBJ_PANE + + either parent? [ + face: as red-object! values + FACE_OBJ_PARENT + either TYPE_OF(face) = TYPE_NONE [ + print-line "parent face: none" + print ["parent handle: " hWnd lf] + ][ + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + pane: as red-block! values + FACE_OBJ_PANE + widget: face-handle? face + print ["from parent handle: " widget lf] + ] + ][print ["parent handle: " hWnd lf]] + + sym: symbol/resolve type/symbol + + rect: as tagRECT allocate (size? tagRECT) + if TYPE_OF(pane) = TYPE_BLOCK [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane + if debug [print ["Pane type: " get-symbol-name sym lf]] + if TYPE_OF(face) <> TYPE_OBJECT [print-line "not face object"] + widget: face-handle? face + + either null? widget [print-line "null container" container: null][container: g_object_get_qdata widget gtk-fixed-id] + print ["container handle: " container lf] + + sx: 0 sy: 0 + cpt: 0 while [face < tail][ - ;@@ TBD + cpt: cpt + 1 + print-line cpt + child: face-handle? face + print ["child handle: " child lf] + values: object/get-values face + offset: as red-pair! values + FACE_OBJ_OFFSET + size: as red-pair! values + FACE_OBJ_SIZE + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + + if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] + ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 + + unless null? container [ + widget: g_object_get_qdata child _widget-id + if null? widget [widget: child] + + gtk_widget_get_allocation widget as handle! rect + ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates + if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] + ] + if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] + either null? child [print-line "null child"][debug-show-children child no] face: face + 1 ] + if debug [print-line "Pane end"] ] - - state: values + FACE_OBJ_STATE - state/header: TYPE_NONE + free as byte-ptr! rect ] init: func [][ @@ -359,7 +445,8 @@ adjust-sizes: func [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane if debug [print ["Parent type: " get-symbol-name sym lf]] - container: g_object_get_qdata get-face-handle face gtk-fixed-id + child: get-face-handle face + container: either null? child [null][g_object_get_qdata child gtk-fixed-id] dx: 0 dy: 0 ox: 0 oy: 0 sx: 0 sy: 0 cpt: 0 @@ -412,7 +499,7 @@ change-rate: func [ data: g_object_get_qdata hWnd red-timer-id timer: either data = as handle! 0 [0][as integer! data] - print ["timer: " timer lf] + ;print ["timer: " timer lf] if timer <> 0 [ ;-- cancel a preexisting timeout g_source_remove timer @@ -696,10 +783,10 @@ change-text: func [ str [red-string!] buffer [handle!] ][ - ; if type = base [ - ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] - ; exit - ; ] + if type = base [ + gtk_widget_queue_draw hWnd + exit + ] str: as red-string! values + FACE_OBJ_TEXT cstr: switch TYPE_OF(str) [ @@ -733,6 +820,7 @@ change-text: func [ ] true [0] ] + gtk_widget_queue_draw hWnd ;] ] @@ -1103,7 +1191,12 @@ update-scroller: func [ OS-redraw: func [hWnd [integer!]][gtk_widget_queue_draw as handle! hWnd] -OS-refresh-window: func [hWnd [integer!]][0] +OS-refresh-window: func [hWnd [integer!]][ + ;print-line "REFFRREEEESSSSHHHHH" + ;debug-show-children last-widget no + ;gtk_widget_queue_draw as handle! hWnd + OS-show-window hWnd +] OS-show-window: func [ hWnd [integer!] @@ -1116,6 +1209,7 @@ OS-show-window: func [ ;if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ adjust-sizes as handle! hWnd gtk_widget_queue_draw as handle! hWnd + ;debug-show-children as handle! hWnd no ;] ] @@ -1214,6 +1308,7 @@ OS-make-view: func [ ] sym = window [ widget: gtk_application_window_new GTKApp + last-widget: widget unless null? caption [gtk_window_set_title widget caption] gtk_window_set_default_size widget size/x size/y gtk_container_add widget gtk_fixed_new @@ -1306,9 +1401,10 @@ OS-make-view: func [ group-radio: either sym = radio [widget][as handle! 0] make-font-provider widget - change-font widget face font sym - + if sym <> base [change-font widget face font sym] + ;print [ "New widget " get-symbol-name sym "->" widget lf] + if all [ sym <> window parent <> 0 @@ -1358,7 +1454,6 @@ OS-make-view: func [ if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] ; if sym <> base [change-color widget as red-tuple! values + FACE_OBJ_COLOR sym] - stack/unwind as-integer widget ] @@ -1434,13 +1529,15 @@ OS-update-view: func [ ; InvalidateRect widget null 1 ] ] - ;if flags and FACET_FLAG_PANE <> 0 [ + if flags and FACET_FLAG_PANE <> 0 [ + 0 + ;print [ "flag-pane" get-symbol-name type lf] ; if tab-panel <> type [ ;-- tab-panel/pane has custom z-order handling ; update-z-order ; as red-block! values + gui/FACE_OBJ_PANE ; null ; ] - ;] + ] if flags and FACET_FLAG_FONT <> 0 [ change-font widget face as red-object! values + FACE_OBJ_FONT type ] @@ -1480,7 +1577,10 @@ OS-destroy-view: func [ ;SetActiveWindow GetWindow handle GW_OWNER ] - free-handles handle + ;print ["DDDEEEEestroy" lf] + + + free-handles handle obj: as red-object! values + FACE_OBJ_FONT ;if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] @@ -1505,7 +1605,7 @@ OS-update-facet: func [ hWnd [handle!] ][ sym: symbol/resolve facet/symbol - + case [ sym = facets/pane [0] sym = facets/data [0] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 3ae45ed26b..05f513dca4 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -91,6 +91,98 @@ button-toggled: func [ make-event button 0 EVT_CHANGE ] + +cairo-render-text: func [ + cr [handle!] + values [red-value!] + ;sz [NSSize!] + /local + text [red-string!] + font [red-object!] + para [red-object!] + flags [integer!] + len [integer!] + str [c-string!] + attr [integer!] + nscolor [integer!] + attrs [integer!] + line [integer!] + wt [float!] + ht [float!] + temp [float!] + ;rc [NSRect!] + extents [cairo_text_extents_t!] + ;m [CGAffineTransform!] +][ + text: as red-string! values + FACE_OBJ_TEXT + if TYPE_OF(text) <> TYPE_STRING [exit] + + if TYPE_OF(text) = TYPE_STRING [ + len: -1 + str: unicode/to-utf8 text :len + extents: as cairo_text_extents_t! allocate (size? cairo_text_extents_t!) + cairo_text_extents cr str as handle! extents + wt: extents/width ht: extents/height + free as byte-ptr! extents + ] + + set-source-color cr 0 + + font: as red-object! values + FACE_OBJ_FONT + either TYPE_OF(font) = TYPE_OBJECT [ + select-cairo-font cr font + ][ + 0 + ] + + para: as red-object! values + FACE_OBJ_PARA + flags: either TYPE_OF(para) = TYPE_OBJECT [ ;@@ TBD set alignment attribute + get-para-flags base para + ][ + 2 or 4 ;-- center + ] + + ;cairo_move_to(cr, w/2 - extents.width/2, h/2); + cairo_move_to cr 20.0 20.0 +print [ "hi-str: <" str ">" lf] + cairo_show_text cr str + + ; m: make-CGMatrix 1 0 0 -1 0 0 + ; case [ + ; flags and 1 <> 0 [m/tx: sz/w - rc/x] + ; flags and 2 <> 0 [temp: sz/w - rc/x m/tx: temp / 2] + ; true [0] + ; ] + + ; case [ + ; flags and 4 <> 0 [temp: sz/h - rc/y m/ty: temp / 2] + ; flags and 8 <> 0 [m/ty: sz/h - rc/y] + ; true [0] + ; ] + ; temp: objc_msgSend_f32 [ + ; objc_msgSend [attrs sel_getUid "objectForKey:" NSFontAttributeName] + ; sel_getUid "ascender" + ; ] + ; m/ty: m/ty + temp + ; line: CTLineCreateWithAttributedString attr + ; CGContextSetTextMatrix ctx m/a m/b m/c m/d m/tx m/ty + ; CTLineDraw line ctx + ; CFRelease str + ; CFRelease attr + ; CFRelease line + + ; attr: objc_msgSend [attrs sel_getUid "objectForKey:" NSStrikethroughStyleAttributeName] + ; if as logic! objc_msgSend [attr sel_getUid "boolValue"][ + ; m/ty: m/ty - temp + (rc/y / as float32! 2.0) + ; CGContextTranslateCTM ctx m/tx m/ty + ; CGContextMoveToPoint ctx as float32! 0.0 as float32! 0.0 + ; CGContextAddLineToPoint ctx rc/x as float32! 0.0 + ; CGContextStrokePath ctx + ; ] + ; objc_msgSend [attrs sel_getUid "release"] + ; CGContextRestoreGState ctx +] + base-draw: func [ [cdecl] widget [handle!] @@ -106,10 +198,26 @@ base-draw: func [ draw: as red-block! vals + FACE_OBJ_DRAW clr: as red-tuple! vals + FACE_OBJ_COLOR if TYPE_OF(clr) = TYPE_TUPLE [ + 0 + ;print ["color" (clr/array1 and 00FFFFFFh) lf] set-source-color cr clr/array1 cairo_paint cr ;-- paint background ] - do-draw cr null draw no yes yes yes + + either TYPE_OF(draw) = TYPE_BLOCK [ + do-draw cr null draw no yes yes yes + ][ + ; system/thrown: 0 + ; DC: declare draw-ctx! ;@@ should declare it on stack + ; draw-begin DC ctx img no no + ; integer/make-at as red-value! draw as-integer DC + ; make-event self 0 EVT_DRAWING + ; draw/header: TYPE_NONE + ; draw-end DC ctx no no no + cairo-render-text cr vals + 0 + ] + ;print ["base-draw " widget lf] false ] From ec5617faf1bc37147af70d36441921d4b51eb5ed Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 26 Aug 2017 12:01:30 +0200 Subject: [PATCH 0048/3432] Adding EVT_KEY_UP to make livecode.red useable as is --- modules/view/backends/gtk3/handlers.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 05f513dca4..ec6d1a9171 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -399,6 +399,7 @@ area-changed: func [ face: as red-object! qdata set-text widget face/ctx text make-event widget 0 EVT_CHANGE + make-event widget 0 EVT_KEY_UP ] ] From 13022ed210b27dc9de98e7aca819f8f5ba1fa5c0 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 26 Aug 2017 14:55:56 +0200 Subject: [PATCH 0049/3432] Removed EVT_KEY_UP in area + some comments To make livecode.red working change `on-keyup` by `on-change` till introduction of global EVT_KEY_UP. --- modules/view/backends/gtk3/gui.reds | 1 + modules/view/backends/gtk3/handlers.reds | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7fff5445e5..17f17a299e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -42,6 +42,7 @@ tabs: context [ pango-context: as handle! 0 gtk-font: "Sans 10" +; Temporary, will be removed... last-widget: as handle! 0 log-pixels-x: 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index ec6d1a9171..868aa035f6 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -389,6 +389,7 @@ area-changed: func [ start [GtkTextIter!] end [GtkTextIter!] ][ + ; Weirdly, GtkTextIter introduced since I did not simplest solution to get the full content of a GtkTextBuffer! start: as GtkTextIter! allocate (size? GtkTextIter!) end: as GtkTextIter! allocate (size? GtkTextIter!) gtk_text_buffer_get_bounds buffer as handle! start as handle! end @@ -399,7 +400,6 @@ area-changed: func [ face: as red-object! qdata set-text widget face/ctx text make-event widget 0 EVT_CHANGE - make-event widget 0 EVT_KEY_UP ] ] From e66d99d23c3f9692761f83e3a3f2b9c19a2b77e8 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 26 Aug 2017 18:25:04 +0200 Subject: [PATCH 0050/3432] Preliminary writing of FACE_OBJ_TEXT for base widget Calculator.red is working partially (alignment and color not fully supported). BTW, base replaced by text was already working --- modules/view/backends/gtk3/font.reds | 164 ++++++++++++----------- modules/view/backends/gtk3/gtk.reds | 76 +++++++---- modules/view/backends/gtk3/handlers.reds | 125 ++++++++--------- 3 files changed, 194 insertions(+), 171 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 798ad8a857..868fc76559 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -323,86 +323,6 @@ font-description: func [ fd ] -#enum cairo_font_slant_t! [ - CAIRO_FONT_SLANT_NORMAL - CAIRO_FONT_SLANT_ITALIC - CAIRO_FONT_SLANT_OBLIQUE -] - -#enum cairo_font_weight_t! [ - CAIRO_FONT_WEIGHT_NORMAL - CAIRO_FONT_WEIGHT_BOLD -] - -select-cairo-font: func [ - cr [handle!] - font [red-object!] - /local - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - css [c-string!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - slant [integer!] - weight [integer!] -][ - values: object/get-values font - - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - name: unicode/to-utf8 str :len - ] - - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk - ] - TYPE_WORD [1] - default [0] - ] - - slant: CAIRO_FONT_SLANT_NORMAL - weight: CAIRO_FONT_WEIGHT_NORMAL - - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ - sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] - sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] - sym = _underline [] - sym = _strike [] - true [] - ] - style: style + 1 - ] - ] - - ;cairo_select_font_face cr name slant weight - cairo_select_font_face cr "Arial" 0 0 - - if TYPE_OF(size) = TYPE_INTEGER [ - print ["size: " size/value lf] - cairo_set_font_size cr size/value - ] -] OS-request-font: func [ font [red-object!] @@ -411,4 +331,86 @@ OS-request-font: func [ return: [red-object!] ][ font -] \ No newline at end of file +] + +; Stuff maybe to REMOVE related to cairo without any success +; #enum cairo_font_slant_t! [ +; CAIRO_FONT_SLANT_NORMAL +; CAIRO_FONT_SLANT_ITALIC +; CAIRO_FONT_SLANT_OBLIQUE +; ] + +; #enum cairo_font_weight_t! [ +; CAIRO_FONT_WEIGHT_NORMAL +; CAIRO_FONT_WEIGHT_BOLD +; ] + +; select-cairo-font: func [ +; cr [handle!] +; font [red-object!] +; /local +; values [red-value!] +; style [red-word!] +; blk [red-block!] +; len [integer!] +; sym [integer!] +; str [red-string!] +; name [c-string!] +; size [red-integer!] +; css [c-string!] +; color [red-tuple!] +; bgcolor [red-tuple!] +; rgba [c-string!] +; slant [integer!] +; weight [integer!] +; ][ +; values: object/get-values font + +; ;name: +; str: as red-string! values + FONT_OBJ_NAME +; size: as red-integer! values + FONT_OBJ_SIZE +; style: as red-word! values + FONT_OBJ_STYLE +; ;angle: +; color: as red-tuple! values + FONT_OBJ_COLOR +; ;anti-alias?: + +; if TYPE_OF(str) = TYPE_STRING [ +; len: -1 +; name: unicode/to-utf8 str :len +; ] + +; len: switch TYPE_OF(style) [ +; TYPE_BLOCK [ +; blk: as red-block! style +; style: as red-word! block/rs-head blk +; block/rs-length? blk +; ] +; TYPE_WORD [1] +; default [0] +; ] + +; slant: CAIRO_FONT_SLANT_NORMAL +; weight: CAIRO_FONT_WEIGHT_NORMAL + +; unless zero? len [ +; loop len [ +; sym: symbol/resolve style/symbol +; case [ +; sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] +; sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] +; sym = _underline [] +; sym = _strike [] +; true [] +; ] +; style: style + 1 +; ] +; ] + +; ;cairo_select_font_face cr name slant weight +; cairo_select_font_face cr "Arial" 0 0 + +; if TYPE_OF(size) = TYPE_INTEGER [ +; print ["size: " size/value lf] +; cairo_set_font_size cr size/value +; ] +; ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 721c334e18..82481e98cf 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -89,14 +89,23 @@ GtkTextIter!: alias struct! [ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] -cairo_text_extents_t!: alias struct! [ - x_bearing [float!] - y_bearing [float!] - width [float!] - height [float!] - x_advance [float!] - y_advance [float!] -] +; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo +; cairo_text_extents_t!: alias struct! [ +; x_bearing [float!] +; y_bearing [float!] +; width [float!] +; height [float!] +; x_advance [float!] +; y_advance [float!] +; ] + +; cairo_font_extents_t!: alias struct! [ +; ascent [float!] +; descent [float!] +; height [float!] +; max_x_advance [float!] +; max_y_advance [float!] +; ] #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" @@ -890,24 +899,45 @@ cairo_text_extents_t!: alias struct! [ cairo_stroke_preserve: "cairo_stroke_preserve" [ cr [handle!] ] - cairo_select_font_face: "cairo_select_font_face" [ - cr [handle!] - family [c-string!] - slant [integer!] - weight [integer!] + ; Related to draw text with cairo (no succes for base widget) replaced by pango_cairo + ; cairo_select_font_face: "cairo_select_font_face" [ + ; cr [handle!] + ; family [c-string!] + ; slant [integer!] + ; weight [integer!] + ; ] + ; cairo_set_font_size: "cairo_set_font_size" [ + ; cr [handle!] + ; size [integer!] + ; ] + ; cairo_text_extents: "cairo_text_extents" [ + ; cr [handle!] + ; text [c-string!] + ; extents [handle!] + ; ] + ; cairo_font_extents: "cairo_font_extents" [ + ; cr [handle!] + ; extents [handle!] + ; ] + ; cairo_show_text: "cairo_show_text" [ + ; cr [handle!] + ; text [c-string!] + ; ] + pango_cairo_create_context: "pango_cairo_create_context" [ + cr [handle!] + return: [handle!] ] - cairo_set_font_size: "cairo_set_font_size" [ - cr [handle!] - size [integer!] + pango_cairo_create_layout: "pango_cairo_create_layout" [ + cr [handle!] + return: [handle!] ] - cairo_text_extents: "cairo_text_extents" [ - cr [handle!] - text [c-string!] - extents [handle!] + pango_cairo_update_layout: "pango_cairo_update_layout" [ + cr [handle!] + layout [handle!] ] - cairo_show_text: "cairo_show_text" [ - cr [handle!] - text [c-string!] + pango_cairo_show_layout: "pango_cairo_show_layout" [ + cr [handle!] + layout [handle!] ] ] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 868aa035f6..394a703c43 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -92,7 +92,7 @@ button-toggled: func [ ] -cairo-render-text: func [ +render-text: func [ cr [handle!] values [red-value!] ;sz [NSSize!] @@ -103,38 +103,19 @@ cairo-render-text: func [ flags [integer!] len [integer!] str [c-string!] - attr [integer!] - nscolor [integer!] - attrs [integer!] line [integer!] - wt [float!] - ht [float!] + x [float!] + y [float!] temp [float!] - ;rc [NSRect!] - extents [cairo_text_extents_t!] - ;m [CGAffineTransform!] + ;te [cairo_text_extents_t!] + ;fe [cairo_font_extents_t!] + pc [handle!] + lpc [handle!] + fd [handle!] ][ text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] - if TYPE_OF(text) = TYPE_STRING [ - len: -1 - str: unicode/to-utf8 text :len - extents: as cairo_text_extents_t! allocate (size? cairo_text_extents_t!) - cairo_text_extents cr str as handle! extents - wt: extents/width ht: extents/height - free as byte-ptr! extents - ] - - set-source-color cr 0 - - font: as red-object! values + FACE_OBJ_FONT - either TYPE_OF(font) = TYPE_OBJECT [ - select-cairo-font cr font - ][ - 0 - ] - para: as red-object! values + FACE_OBJ_PARA flags: either TYPE_OF(para) = TYPE_OBJECT [ ;@@ TBD set alignment attribute get-para-flags base para @@ -142,45 +123,53 @@ cairo-render-text: func [ 2 or 4 ;-- center ] - ;cairo_move_to(cr, w/2 - extents.width/2, h/2); - cairo_move_to cr 20.0 20.0 -print [ "hi-str: <" str ">" lf] - cairo_show_text cr str - - ; m: make-CGMatrix 1 0 0 -1 0 0 - ; case [ - ; flags and 1 <> 0 [m/tx: sz/w - rc/x] - ; flags and 2 <> 0 [temp: sz/w - rc/x m/tx: temp / 2] - ; true [0] - ; ] - - ; case [ - ; flags and 4 <> 0 [temp: sz/h - rc/y m/ty: temp / 2] - ; flags and 8 <> 0 [m/ty: sz/h - rc/y] - ; true [0] - ; ] - ; temp: objc_msgSend_f32 [ - ; objc_msgSend [attrs sel_getUid "objectForKey:" NSFontAttributeName] - ; sel_getUid "ascender" - ; ] - ; m/ty: m/ty + temp - ; line: CTLineCreateWithAttributedString attr - ; CGContextSetTextMatrix ctx m/a m/b m/c m/d m/tx m/ty - ; CTLineDraw line ctx - ; CFRelease str - ; CFRelease attr - ; CFRelease line - - ; attr: objc_msgSend [attrs sel_getUid "objectForKey:" NSStrikethroughStyleAttributeName] - ; if as logic! objc_msgSend [attr sel_getUid "boolValue"][ - ; m/ty: m/ty - temp + (rc/y / as float32! 2.0) - ; CGContextTranslateCTM ctx m/tx m/ty - ; CGContextMoveToPoint ctx as float32! 0.0 as float32! 0.0 - ; CGContextAddLineToPoint ctx rc/x as float32! 0.0 - ; CGContextStrokePath ctx - ; ] - ; objc_msgSend [attrs sel_getUid "release"] - ; CGContextRestoreGState ctx + ; The pango_cairo way + + pc: pango_cairo_create_context cr + lpc: pango_cairo_create_layout cr + + font: as red-object! values + FACE_OBJ_FONT + fd: font-description font + pango_layout_set_font_description lpc fd + if TYPE_OF(text) = TYPE_STRING [ + len: -1 + str: unicode/to-utf8 text :len + ] + pango_layout_set_text lpc str -1 + cairo_set_source_rgba cr 0.0 0.0 0.0 0.5 + pango_cairo_update_layout cr lpc + pango_cairo_show_layout cr lpc + +; @@ The cairo way (alternative) does not work for me after too many attempt +; if TYPE_OF(text) = TYPE_STRING [ +; len: -1 +; str: unicode/to-utf8 text :len +; te: as cairo_text_extents_t! allocate (size? cairo_text_extents_t!) +; cairo_text_extents cr str as handle! te +; fe: as cairo_font_extents_t! allocate (size? cairo_font_extents_t!) +; cairo_font_extents cr as handle! fe +; x: 0.5 - te/x_bearing - (te/width / 2.0) +; y: 0.5 - fe/descent + (fe/height / 2.0) +; free as byte-ptr! te +; free as byte-ptr! fe +; ] + +; cairo_scale cr 170.0 40.0 +; ;set-source-color cr 0 +; cairo_set_source_rgba cr 0.0 0.0 0.0 0.5 + +; font: as red-object! values + FACE_OBJ_FONT +; either TYPE_OF(font) = TYPE_OBJECT [ +; select-cairo-font cr font +; ][ +; 0 +; ] + +; ;cairo_move_to(cr, w/2 - extents.width/2, h/2); +; cairo_move_to cr x y +; print [ "hi-str: <" str ">" lf] +; cairo_show_text cr str + ] base-draw: func [ @@ -197,12 +186,15 @@ base-draw: func [ vals: get-node-values ctx draw: as red-block! vals + FACE_OBJ_DRAW clr: as red-tuple! vals + FACE_OBJ_COLOR + if TYPE_OF(clr) = TYPE_TUPLE [ 0 ;print ["color" (clr/array1 and 00FFFFFFh) lf] set-source-color cr clr/array1 cairo_paint cr ;-- paint background ] + + render-text cr vals either TYPE_OF(draw) = TYPE_BLOCK [ do-draw cr null draw no yes yes yes @@ -214,7 +206,6 @@ base-draw: func [ ; make-event self 0 EVT_DRAWING ; draw/header: TYPE_NONE ; draw-end DC ctx no no no - cairo-render-text cr vals 0 ] ;print ["base-draw " widget lf] From 8432d22482ea45066f75b1bb6bd27e1f38aa4363 Mon Sep 17 00:00:00 2001 From: honix Date: Sun, 27 Aug 2017 23:20:34 +0300 Subject: [PATCH 0051/3432] GTK: draw commands; draw test --- modules/view/backends/gtk3/draw.reds | 270 +++++++++++++++++++++------ modules/view/backends/gtk3/gtk.reds | 28 +++ tests/draw.red | 132 +++++++++++++ 3 files changed, 375 insertions(+), 55 deletions(-) create mode 100644 tests/draw.red diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 71669ba191..c1dac1ceca 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -189,12 +189,14 @@ OS-draw-polygon: func [ dc [draw-ctx!] start [red-pair!] end [red-pair!] - /local - pair [red-pair!] - point [tagPOINT] - nb [integer!] ][ -0 + until [ + cairo_line_to dc/raw as-float start/x as-float start/y + start: start + 1 + start > end + ] + cairo_close_path dc/raw + do-paint dc ] OS-draw-spline: func [ @@ -203,21 +205,72 @@ OS-draw-spline: func [ end [red-pair!] closed? [logic!] /local - pair [red-pair!] - point [tagPOINT] - nb [integer!] + ctx [handle!] + p [red-pair!] + p0 [red-pair!] + p1 [red-pair!] + p2 [red-pair!] + p3 [red-pair!] + x [float32!] + y [float32!] + delta [float32!] + t [float32!] + t2 [float32!] + t3 [float32!] + i [integer!] + n [integer!] + count [integer!] + num [integer!] ][ -0 -] + comment { + ; this is copy from macOS/draw.reds impl + ; seems not to work now.. -do-draw-ellipse: func [ - dc [draw-ctx!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] -][ -0 + ctx: dc/raw + + count: (as-integer end - start) >> 4 + num: count + 1 + 2 + + p: start + + cairo_move_to ctx as-float p/x as-float p/y + + i: 0 + delta: (as float32! 1.0) / (as float32! 25.0) + + while [i < count][ ;-- CatmullRom Spline, tension = 0.5 + p0: p + (i % num) + p1: p + (i + 1 % num) + p2: p + (i + 2 % num) + p3: p + (i + 3 % num) + + t: as float32! 0.0 + n: 0 + until [ + t: t + delta + t2: t * t + t3: t2 * t + + x: (as float32! 2.0) * p1/x + (p2/x - p0/x * t) + + (((as float32! 2.0) * p0/x - ((as float32! 5.0) * p1/x) + ((as float32! 4.0) * p2/x) - p3/x) * t2) + + ((as float32! 3.0) * (p1/x - p2/x) + p3/x - p0/x * t3) * 0.5 + y: (as float32! 2.0) * p1/y + (p2/y - p0/y * t) + + (((as float32! 2.0) * p0/y - ((as float32! 5.0) * p1/y) + ((as float32! 4.0) * p2/y) - p3/y) * t2) + + ((as float32! 3.0) * (p1/y - p2/y) + p3/y - p0/y * t3) * 0.5 + + cairo_line_to ctx as-float x as-float y + + n: n + 1 + n = 25 + ] + i: i + 4 + ] + if closed? [ + cairo_close_path dc/raw + ] + do-paint dc + + } ; comment ] OS-draw-circle: func [ @@ -225,12 +278,49 @@ OS-draw-circle: func [ center [red-pair!] radius [red-integer!] /local - x [float!] - y [float!] -][ - x: as-float center/x - y: as-float center/y - cairo_arc dc/raw x y as-float radius/value 0.0 2.0 * pi + ctx [handle!] + rad-x [integer!] + rad-y [integer!] + w [float!] + h [float!] + f [red-float!] +][ + ctx: dc/raw + + either TYPE_OF(radius) = TYPE_INTEGER [ + either center + 1 = radius [ ;-- center, radius + rad-x: radius/value + rad-y: rad-x + ][ + rad-y: radius/value ;-- center, radius-x, radius-y + radius: radius - 1 + rad-x: radius/value + ] + w: as float! rad-x * 2 + h: as float! rad-y * 2 + ][ + f: as red-float! radius + either center + 1 = radius [ + rad-x: as-integer f/value + 0.75 + rad-y: rad-x + w: as float! f/value * 2.0 + h: w + ][ + rad-y: as-integer f/value + 0.75 + h: as float! f/value * 2.0 + f: f - 1 + rad-x: as-integer f/value + 0.75 + w: as float! f/value * 2.0 + ] + ] + + cairo_save ctx + cairo_translate ctx as-float center/x + as-float center/y + cairo_scale ctx as-float rad-x + as-float rad-y + cairo_arc ctx 0.0 0.0 1.0 0.0 2.0 * pi + cairo_restore ctx do-paint dc ] @@ -238,21 +328,48 @@ OS-draw-ellipse: func [ dc [draw-ctx!] upper [red-pair!] diameter [red-pair!] -][ -0 + /local + ctx [handle!] + rad-x [integer!] + rad-y [integer!] +][ + ctx: dc/raw + rad-x: diameter/x / 2 + rad-y: diameter/y / 2 + + cairo_save ctx + cairo_translate ctx as-float upper/x + rad-x + as-float upper/y + rad-y + cairo_scale ctx as-float rad-x + as-float rad-y + cairo_arc ctx 0.0 0.0 1.0 0.0 2.0 * pi + cairo_restore ctx + do-paint dc ] OS-draw-font: func [ dc [draw-ctx!] font [red-object!] /local - vals [red-value!] - state [red-block!] - int [red-integer!] - color [red-tuple!] - hFont [draw-ctx!] -][ -0 + ctx [handle!] + len [integer!] + face [handle!] + ; vals [red-value!] + ; state [red-block!] + ; int [red-integer!] + ; color [red-tuple!] + ; hFont [draw-ctx!] +][ + ctx: dc/raw + len: -1 + face: cairo_toy_font_face_create + ;unicode/to-utf8 font/name :len ; family string + "Impact" + 0 ; slant normal\italic + 0 ; weight normal\bold + cairo_set_font_face ctx face + ;cairo_set_font_size ctx as-float font/size + cairo_set_font_size ctx as-float 15 ] OS-draw-text: func [ @@ -260,10 +377,17 @@ OS-draw-text: func [ pos [red-pair!] text [red-string!] /local + ctx [handle!] + len [integer!] str [c-string!] - len [integer!] ][ -0 + ctx: dc/raw + len: -1 + str: unicode/to-utf8 text :len + cairo_move_to ctx as-float pos/x + as-float pos/y + cairo_show_text ctx str + do-paint dc ] OS-draw-arc: func [ @@ -271,25 +395,47 @@ OS-draw-arc: func [ center [red-pair!] end [red-value!] /local + ctx [handle!] radius [red-pair!] angle [red-integer!] - rad-x [integer!] - rad-y [integer!] - start-x [integer!] - start-y [integer!] - end-x [integer!] - end-y [integer!] + begin [red-integer!] + cx [float!] + cy [float!] + rad-x [float!] + rad-y [float!] angle-begin [float!] - angle-len [float!] - rad-x-float [float!] - rad-y-float [float!] - rad-x-2 [float!] - rad-y-2 [float!] - rad-x-y [float!] - tan-2 [float!] + angle-end [float!] + rad [float!] + sweep [integer!] + i [integer!] closed? [logic!] ][ -0 + ctx: dc/raw + cx: as float! center/x + cy: as float! center/y + rad: PI / 180.0 + + radius: center + 1 + rad-x: as float! radius/x + rad-y: as float! radius/y + begin: as red-integer! radius + 1 + angle-begin: rad * as float! begin/value + angle: begin + 1 + sweep: angle/value + i: begin/value + sweep + angle-end: rad * as float! i + + closed?: angle < end + + cairo_save ctx + cairo_translate ctx cx cy + cairo_scale ctx rad-x rad-y + cairo_arc ctx 0.0 0.0 1.0 angle-begin angle-end + if closed? [ + cairo_close_path ctx + ] + cairo_restore ctx + do-paint dc ] OS-draw-curve: func [ @@ -297,14 +443,28 @@ OS-draw-curve: func [ start [red-pair!] end [red-pair!] /local - pair [red-pair!] - point [tagPOINT] + ctx [handle!] p2 [red-pair!] p3 [red-pair!] - nb [integer!] - count [integer!] ][ -0 + ctx: dc/raw + + if (as-integer end - start) >> 4 = 3 ; four input points + [ + cairo_move_to ctx as-float start/x + as-float start/y + start: start + 1 + ] + + p2: start + 1 + p3: start + 2 + cairo_curve_to ctx as-float start/x + as-float start/y + as-float p2/x + as-float p2/y + as-float p3/x + as-float p3/y + do-paint dc ] OS-draw-line-join: func [ @@ -674,4 +834,4 @@ OS-draw-brush-pattern: func [ mode [red-word!] block [red-block!] brush? [logic!] -][] \ No newline at end of file +][] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a627fe080b..e36f644a9b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -379,6 +379,22 @@ tagSIZE: alias struct! [ cairo_save: "cairo_save" [ cr [handle!] ] + cairo_scale: "cairo_scale" [ + cr [handle!] + x [float!] + y [float!] + ] + cairo_translate: "cairo_translate" [ + cr [handle!] + x [float!] + y [float!] + ] + cairo_toy_font_face_create: "cairo_toy_font_face_create" [ + family [c-string!] + slant [integer!] + weight [integer!] + return: [handle!] + ] cairo_restore: "cairo_restore" [ cr [handle!] ] @@ -403,6 +419,18 @@ tagSIZE: alias struct! [ x [float!] y [float!] ] + cairo_set_font_face: "cairo_set_font_face" [ + cr [handle!] + font_face [handle!] + ] + cairo_set_font_size: "cairo_set_font_size" [ + cr [handle!] + size [float!] + ] + cairo_show_text: "cairo_show_text" [ + cr [handle!] + utf8 [c-string!] + ] cairo_get_source: "cairo_get_source" [ cr [handle!] return: [handle!] diff --git a/tests/draw.red b/tests/draw.red new file mode 100644 index 0000000000..0a94f18ef8 --- /dev/null +++ b/tests/draw.red @@ -0,0 +1,132 @@ +Red [ + Title: "Tests for draw dialect" +] + +view [ + title "Draw test" + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 200.50.20 + + line 10x10 40x30 + line 10x40 40x40 + + text 5x55 "line" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + triangle 10x10 40x10 25x40 + + text 5x55 "triangle" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + box 10x10 40x20 + box 20x30 30x40 + + text 5x55 "box" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + polygon 10x10 40x10 40x40 20x30 + + text 5x55 "polygon" + ] + + return + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + circle 25x25 15 + circle 25x25 10 5 + + text 5x55 "circle" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + ellipse 10x10 5x10 + ellipse 35x10 5x10 + ellipse 20x20 10x20 + + text 5x55 "ellipse" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + ;arc
closed + arc 25x25 15x15 0 180 closed + arc 25x25 5x10 90 270 + + text 5x55 "arc" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + curve 10x10 40x10 10x40 40x40 + curve 10x10 20x40 10x40 + + text 5x55 "curve" + ] + + return + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + spline 10x10 40x40 40x40 10x40 + + text 5x55 "spline" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + ;image + + text 5x55 "image" + ] + + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + text 10x20 "Red" + ;font font-A + text 10x30 "Red" + + text 5x55 "text" + ] + + + ; . . . +] + +font-A: make font! [ + name: "Comic Sans MS" + size: 10 + color: blue + style: [bold italic underline] + anti-alias?: yes +] + From 786f38c91980db53899b3e160c8d2d9e92411425 Mon Sep 17 00:00:00 2001 From: honix Date: Sun, 27 Aug 2017 23:28:07 +0300 Subject: [PATCH 0052/3432] GTK: tests/draw.red header --- tests/draw.red | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/draw.red b/tests/draw.red index 0a94f18ef8..69eccf8cfd 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -1,5 +1,8 @@ Red [ - Title: "Tests for draw dialect" + Title: "Tests for draw dialect" + Author: "Fyodor Shchukin" + File: %draw.red + Tabs: 4 ] view [ From ff08f22e30060bd89ddea162c02a87ec37f11ff3 Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 00:30:01 +0300 Subject: [PATCH 0053/3432] GTK: tests/draw.red extend --- tests/draw.red | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/draw.red b/tests/draw.red index 69eccf8cfd..2f1477a59a 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -121,8 +121,53 @@ view [ text 5x55 "text" ] + base 50x60 100.70.70 draw [ + line-width 3 + fill-pen 120.20.20 + + text 5x55 "..." + ] + + return ; . . . + + base 230x2 0.0.0 + + return + + base 50x60 70.70.100 draw [ + text 5x55 "rotate" + + line-width 3 + fill-pen 120.20.20 + + box 15x15 35x35 + rotate 45 25x25 + box 15x15 35x35 + ] + + base 50x60 70.70.100 draw [ + text 5x55 "scale" + + line-width 3 + fill-pen 120.20.20 + + box 10x10 40x40 + scale 0.5 0.5 + box 10x10 40x40 + ] + + base 50x60 70.70.100 draw [ + text 5x55 "translate" + + line-width 3 + fill-pen 120.20.20 + + box 10x10 30x30 + translate 10x10 + box 10x10 30x30 + ] ] font-A: make font! [ From 421d3c567c9b39a3800535db415dd24860661d7f Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 28 Aug 2017 00:46:45 +0200 Subject: [PATCH 0054/3432] Deactivating render-text in base-draw since it generates a bug in tests/vid.red also, bad redefinition of cairo_translate and cairo_scale in the merge with @honix pull request. --- modules/view/backends/gtk3/font.reds | 26 +++++++++++++++--------- modules/view/backends/gtk3/gtk.reds | 10 --------- modules/view/backends/gtk3/handlers.reds | 4 ++-- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 868fc76559..b3af45153a 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -261,11 +261,13 @@ font-description: func [ str [red-string!] name [c-string!] size [red-integer!] + fsize [integer!] css [c-string!] color [red-tuple!] bgcolor [red-tuple!] rgba [c-string!] - fsty [integer!] + fweight [integer!] + fstyle [integer!] fd [handle!] ][ @@ -281,15 +283,17 @@ font-description: func [ fd: pango_font_description_new + name: "Arial" ; @@ to change to default font name if TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len - pango_font_description_set_family fd name ] - if TYPE_OF(size) = TYPE_INTEGER [ - pango_font_description_set_size fd size/value * PANGO_SCALE - ] + pango_font_description_set_family fd name + + fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] + pango_font_description_set_size fd fsize * PANGO_SCALE + ;DEBUG: print ["font name: <" name "> size: " fsize lf] len: switch TYPE_OF(style) [ TYPE_BLOCK [ @@ -301,13 +305,14 @@ font-description: func [ default [0] ] - fsty: PANGO_STYLE_NORMAL + fstyle: PANGO_STYLE_NORMAL + fweight: PANGO_WEIGHT_NORMAL unless zero? len [ loop len [ sym: symbol/resolve style/symbol case [ - sym = _bold [pango_font_description_set_weight fd PANGO_WEIGHT_BOLD] - sym = _italic [fsty: PANGO_STYLE_ITALIC] + sym = _bold [fweight: PANGO_WEIGHT_BOLD] + sym = _italic [fstyle: PANGO_STYLE_ITALIC] sym = _underline [] sym = _strike [] true [] @@ -316,10 +321,11 @@ font-description: func [ ] ] - pango_font_description_set_style fd fsty + pango_font_description_set_weight fd fweight + pango_font_description_set_style fd fstyle pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL pango_font_description_set_variant fd PANGO_VARIANT_NORMAL - + ; DEBUG: print-line "HERE" fd ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 377c49e452..3878093320 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -911,16 +911,6 @@ GtkTextIter!: alias struct! [ cr [handle!] angle [float!] ] - cairo_translate: "cairo_translate" [ - cr [handle!] - x [float!] - y [float!] - ] - cairo_scale: "cairo_scale" [ - cr [handle!] - x [float!] - y [float!] - ] cairo_identity_matrix: "cairo_identity_matrix" [ cr [handle!] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 394a703c43..ada41b353b 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -124,12 +124,12 @@ render-text: func [ ] ; The pango_cairo way - pc: pango_cairo_create_context cr lpc: pango_cairo_create_layout cr font: as red-object! values + FACE_OBJ_FONT fd: font-description font + ; DEBUG: print-line "after font-description" pango_layout_set_font_description lpc fd if TYPE_OF(text) = TYPE_STRING [ len: -1 @@ -194,7 +194,7 @@ base-draw: func [ cairo_paint cr ;-- paint background ] - render-text cr vals + ;render-text cr vals either TYPE_OF(draw) = TYPE_BLOCK [ do-draw cr null draw no yes yes yes From 639bc0421645509feaeea88fb7b54b18248327c3 Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 28 Aug 2017 06:19:08 +0200 Subject: [PATCH 0055/3432] font none management inside font-description function + clean temporary Debug stuff --- modules/view/backends/gtk3/font.reds | 9 +++++---- modules/view/backends/gtk3/gui.reds | 16 +++++++++++----- modules/view/backends/gtk3/handlers.reds | 3 +-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index b3af45153a..6cae3a9936 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -271,8 +271,11 @@ font-description: func [ fd [handle!] ][ + ; default font if font is none. TODO: better than gtk-font would be to get the default font system or from red side + if TYPE_OF(font) = TYPE_NONE [ + return pango_font_description_from_string gtk-font + ] values: object/get-values font - ;name: str: as red-string! values + FONT_OBJ_NAME size: as red-integer! values + FONT_OBJ_SIZE @@ -288,12 +291,10 @@ font-description: func [ len: -1 name: unicode/to-utf8 str :len ] - pango_font_description_set_family fd name fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] pango_font_description_set_size fd fsize * PANGO_SCALE - ;DEBUG: print ["font name: <" name "> size: " fsize lf] len: switch TYPE_OF(style) [ TYPE_BLOCK [ @@ -325,7 +326,7 @@ font-description: func [ pango_font_description_set_style fd fstyle pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL pango_font_description_set_variant fd PANGO_VARIANT_NORMAL - ; DEBUG: print-line "HERE" + fd ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 17f17a299e..ec963cb623 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -206,11 +206,17 @@ get-text-size: func [ ] width: 0 height: 0 - fd: either TYPE_OF(font) = TYPE_NONE [ - pango_font_description_from_string gtk-font - ][ - font-description font - ] + + ; @@ TO REMOVE since font-description manages directly none value for font + ;fd: either TYPE_OF(font) = TYPE_NONE [ + ; pango_font_description_from_string gtk-font + ;][ + ; font-description font + ;] + + ; The lines above replaced with + fd: font-description font + pl: pango_layout_new pango-context pango_layout_set_text pl text -1 pango_layout_set_font_description pl fd diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index ada41b353b..9665d739c1 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -129,7 +129,6 @@ render-text: func [ font: as red-object! values + FACE_OBJ_FONT fd: font-description font - ; DEBUG: print-line "after font-description" pango_layout_set_font_description lpc fd if TYPE_OF(text) = TYPE_STRING [ len: -1 @@ -194,7 +193,7 @@ base-draw: func [ cairo_paint cr ;-- paint background ] - ;render-text cr vals + render-text cr vals either TYPE_OF(draw) = TYPE_BLOCK [ do-draw cr null draw no yes yes yes From 8e59d4d815156f1066fa64403582911e9db25d16 Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 28 Aug 2017 07:17:50 +0200 Subject: [PATCH 0056/3432] Deal with empty pane block (thanks to @nc-x) --- modules/view/backends/gtk3/gui.reds | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index ec963cb623..0a9871d219 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -206,7 +206,7 @@ get-text-size: func [ ] width: 0 height: 0 - + ; @@ TO REMOVE since font-description manages directly none value for font ;fd: either TYPE_OF(font) = TYPE_NONE [ ; pango_font_description_from_string gtk-font @@ -324,7 +324,7 @@ debug-show-children: func [ rect: as tagRECT allocate (size? tagRECT) - if TYPE_OF(pane) = TYPE_BLOCK [ + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane if debug [print ["Pane type: " get-symbol-name sym lf]] @@ -448,7 +448,7 @@ adjust-sizes: func [ rect: as tagRECT allocate (size? tagRECT) - if TYPE_OF(pane) = TYPE_BLOCK [ + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane if debug [print ["Parent type: " get-symbol-name sym lf]] @@ -1315,6 +1315,7 @@ OS-make-view: func [ ] sym = window [ widget: gtk_application_window_new GTKApp + ; @@ DEBUG: temporary code last-widget: widget unless null? caption [gtk_window_set_title widget caption] gtk_window_set_default_size widget size/x size/y From bac8fb5852f161b78aae8fe87f7534161b6cc8d6 Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 28 Aug 2017 08:39:08 +0200 Subject: [PATCH 0057/3432] null? Instead of comparison to "as handle! 0" --- modules/view/backends/gtk3/gui.reds | 12 ++++++------ modules/view/backends/gtk3/handlers.reds | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 0a9871d219..f653b168fe 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -60,7 +60,7 @@ get-face-object: func [ face: as red-object! 0 unless null? handle [ qdata: g_object_get_qdata handle red-face-id - if qdata <> as handle! 0 [ + unless null? qdata [ face: as red-object! qdata ] ] @@ -78,7 +78,7 @@ get-face-values: func [ values: as red-value! 0 unless null? handle [ qdata: g_object_get_qdata handle red-face-id - if qdata <> as handle! 0 [ + unless null? qdata [ face: as red-object! qdata values: object/get-values face ] @@ -195,7 +195,7 @@ get-text-size: func [ fd [handle!] df [c-string!] ][ - if pango-context = as handle! 0 [pango-context: gdk_pango_context_get] + if null? pango-context [pango-context: gdk_pango_context_get] size: declare tagSIZE text: either TYPE_OF(str) = TYPE_STRING [ @@ -504,7 +504,7 @@ change-rate: func [ ][ unless null? hWnd [ data: g_object_get_qdata hWnd red-timer-id - timer: either data = as handle! 0 [0][as integer! data] + timer: either null? data [0][as integer! data] ;print ["timer: " timer lf] @@ -1295,7 +1295,7 @@ OS-make-view: func [ gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = radio [ - widget: either group-radio = as handle! 0 [ + widget: either null? group-radio [ gtk_radio_button_new_with_label null caption ][ gtk_radio_button_new_with_label_from_widget group-radio caption @@ -1418,7 +1418,7 @@ OS-make-view: func [ parent <> 0 ][ p-sym: get-widget-symbol as handle! parent - either _widget = as handle! 0 [_widget: widget][g_object_set_qdata widget _widget-id _widget ] + either null? _widget [_widget: widget][g_object_set_qdata widget _widget-id _widget ] ; TODO: case to replace with either if no more choice case [ p-sym = tab-panel [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 9665d739c1..6d7a50c4ac 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -386,7 +386,7 @@ area-changed: func [ text: gtk_text_buffer_get_text buffer as handle! start as handle! end no free as byte-ptr! start free as byte-ptr! end qdata: g_object_get_qdata widget red-face-id - if qdata <> as handle! 0 [ + unless null? qdata [ face: as red-object! qdata set-text widget face/ctx text make-event widget 0 EVT_CHANGE From caef3f7ef173e788fe0871e4d567dc2c5ae0931f Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 17:32:10 +0300 Subject: [PATCH 0058/3432] gtk/draw: paint fix, line-joint, tests/draw.red extend --- modules/view/backends/gtk3/draw.reds | 33 +++++--- modules/view/backends/gtk3/gtk.reds | 4 + tests/draw.red | 122 +++++++++++++++++++-------- 3 files changed, 114 insertions(+), 45 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 884d317caa..09e1513b6e 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -77,9 +77,22 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ cairo_set_source cr dc/pattern ] cairo_fill_preserve cr - unless dc/pen? [set-source-color cr dc/pen-color cairo_stroke cr] + unless dc/pen? [ + set-source-color cr dc/pen-color + cairo_stroke cr + ] cairo_restore cr ] + if dc/pen? [ + cairo_set_line_join cr + case [ + dc/pen-join = miter [0] + dc/pen-join = _round [1] + dc/pen-join = bevel [2] + dc/pen-join = miter-bevel [0] + ] + cairo_stroke cr + ] ] OS-draw-anti-alias: func [ @@ -101,7 +114,7 @@ OS-draw-line: func [ cairo_line_to cr as-float point/x as-float point/y point: point + 1 ] - cairo_stroke cr + do-paint dc ] OS-draw-pen: func [ @@ -617,10 +630,11 @@ OS-matrix-rotate: func [ ][ cr: dc/raw rad: PI / 180.0 * get-float angle - cairo_translate cr as float! center/x as float! center/y + cairo_translate cr as float! center/x + as float! center/y cairo_rotate cr rad - do-paint dc - cairo_translate cr as float! (0 - center/x) as float! (0 - center/y) + cairo_translate cr as float! (0 - center/x) + as float! (0 - center/y) ] OS-matrix-scale: func [ @@ -632,8 +646,8 @@ OS-matrix-scale: func [ cr [handle!] ][ cr: dc/raw - cairo_scale cr as-float sx/value as-float sy/value - do-paint dc + cairo_scale cr as-float sx/value + as-float sy/value ] OS-matrix-translate: func [ @@ -645,8 +659,8 @@ OS-matrix-translate: func [ cr [handle!] ][ cr: dc/raw - cairo_translate cr as-float x as-float y - do-paint dc + cairo_translate cr as-float x + as-float y ] OS-matrix-skew: func [ @@ -700,7 +714,6 @@ OS-matrix-reset: func [ ][ cr: dc/raw cairo_identity_matrix cr - do-paint dc ] OS-matrix-invert: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 3878093320..e8e74568c0 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -847,6 +847,10 @@ GtkTextIter!: alias struct! [ cr [handle!] width [float!] ] + cairo_set_line_join: "cairo_set_line_join" [ + cr [handle!] + line_join [integer!] + ] cairo_set_source: "cairo_set_source" [ cr [handle!] source [handle!] diff --git a/tests/draw.red b/tests/draw.red index 2f1477a59a..2171e6a303 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -5,22 +5,22 @@ Red [ Tabs: 4 ] -view [ +l: layout [ title "Draw test" base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 200.50.20 + line-width 2 + fill-pen 170.20.20.128 - line 10x10 40x30 + line 10x10 40x30 10x30 line 10x40 40x40 text 5x55 "line" ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 triangle 10x10 40x10 25x40 @@ -28,8 +28,8 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 box 10x10 40x20 box 20x30 30x40 @@ -38,8 +38,8 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 polygon 10x10 40x10 40x40 20x30 @@ -49,8 +49,8 @@ view [ return base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 circle 25x25 15 circle 25x25 10 5 @@ -59,8 +59,8 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 ellipse 10x10 5x10 ellipse 35x10 5x10 @@ -70,8 +70,8 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 ;arc
closed arc 25x25 15x15 0 180 closed @@ -81,11 +81,11 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 + curve 10x5 45x5 45x40 curve 10x10 40x10 10x40 40x40 - curve 10x10 20x40 10x40 text 5x55 "curve" ] @@ -93,8 +93,8 @@ view [ return base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 spline 10x10 40x40 40x40 10x40 @@ -102,8 +102,8 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 ;image @@ -111,21 +111,60 @@ view [ ] base 50x60 100.70.70 draw [ - line-width 3 - fill-pen 120.20.20 + text 5x55 "text" text 10x20 "Red" - ;font font-A + font font-A text 10x30 "Red" + ] - text 5x55 "text" + base 50x60 100.70.70 draw [ + text 5x55 "pen flat" + + line 10x10 10x40 + box 15x10 20x40 + + pen off + fill-pen 20.20.170.128 + box 25x10 30x40 + + pen 255.255.255.100 + line-width 1 + triangle 35x10 40x40 35x40 + + fill-pen off + triangle 35x10 40x10 40x40 + ] + + return + + base 50x60 100.70.70 draw [ + text 5x55 "pen gradient" + + pen linear red green blue + line-width 5 + fill-pen no + box 10x10 40x40 ] base 50x60 100.70.70 draw [ + text 5x55 "fill gradient" + + fill-pen linear red green blue + box 10x10 40x40 + ] + + base 50x60 100.70.70 draw [ + text 5x55 "line join" + line-width 3 - fill-pen 120.20.20 - text 5x55 "..." + line-join miter + line 10x40 15x20 20x40 + line-join round + line 20x40 25x20 30x40 + line-join bevel + line 30x40 35x20 40x40 ] return @@ -139,8 +178,8 @@ view [ base 50x60 70.70.100 draw [ text 5x55 "rotate" - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 box 15x15 35x35 rotate 45 25x25 @@ -150,8 +189,8 @@ view [ base 50x60 70.70.100 draw [ text 5x55 "scale" - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 box 10x10 40x40 scale 0.5 0.5 @@ -161,8 +200,19 @@ view [ base 50x60 70.70.100 draw [ text 5x55 "translate" - line-width 3 - fill-pen 120.20.20 + line-width 2 + fill-pen 170.20.20.128 + + box 10x10 30x30 + translate 10x10 + box 10x10 30x30 + ] + + base 50x60 70.70.100 draw [ + text 5x55 "translate" + + line-width 2 + fill-pen 170.20.20.128 box 10x10 30x30 translate 10x10 @@ -178,3 +228,5 @@ font-A: make font! [ anti-alias?: yes ] +view l + From 540253ee6124197e406e4603a061c73cc8a4e6e7 Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 18:35:38 +0300 Subject: [PATCH 0059/3432] gtk/draw: line-cap --- modules/view/backends/gtk3/draw.reds | 22 +++++++++++++++------- modules/view/backends/gtk3/gtk.reds | 4 ++++ tests/draw.red | 15 ++++++++++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 09e1513b6e..998f10ca85 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -84,13 +84,6 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ cairo_restore cr ] if dc/pen? [ - cairo_set_line_join cr - case [ - dc/pen-join = miter [0] - dc/pen-join = _round [1] - dc/pen-join = bevel [2] - dc/pen-join = miter-bevel [0] - ] cairo_stroke cr ] ] @@ -488,6 +481,14 @@ OS-draw-line-join: func [ ][ if dc/pen-join <> style [ dc/pen-join: style + cairo_set_line_join dc/raw + case [ + style = miter [0] + style = _round [1] + style = bevel [2] + style = miter-bevel [0] + true [0] + ] ] ] @@ -499,6 +500,13 @@ OS-draw-line-cap: func [ ][ if dc/pen-cap <> style [ dc/pen-cap: style + cairo_set_line_cap dc/raw + case [ + style = flat [0] + style = _round [1] + style = square [2] + true [0] + ] ] ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index e8e74568c0..ef94abc715 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -843,6 +843,10 @@ GtkTextIter!: alias struct! [ blue [float!] alpha [float!] ] + cairo_set_line_cap: "cairo_set_line_cap" [ + cr [handle!] + line_cap [integer!] + ] cairo_set_line_width: "cairo_set_line_width" [ cr [handle!] width [float!] diff --git a/tests/draw.red b/tests/draw.red index 2171e6a303..35bfad0f00 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -157,7 +157,7 @@ l: layout [ base 50x60 100.70.70 draw [ text 5x55 "line join" - line-width 3 + line-width 5 line-join miter line 10x40 15x20 20x40 @@ -167,6 +167,19 @@ l: layout [ line 30x40 35x20 40x40 ] + base 50x60 100.70.70 draw [ + text 5x55 "line cap" + + line-width 7 + + line-cap flat + line 15x15 15x35 + line-cap square + line 25x15 25x35 + line-cap round + line 35x15 35x35 + ] + return ; . . . From 09dbe48d190072a81e459a01a7eab8fd4c476916 Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 19:37:09 +0300 Subject: [PATCH 0060/3432] gtk/draw: minors --- modules/view/backends/gtk3/draw.reds | 65 ++++++++++++++-------------- tests/draw.red | 5 ++- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 998f10ca85..5a7cbd54b2 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -217,66 +217,65 @@ OS-draw-spline: func [ p1 [red-pair!] p2 [red-pair!] p3 [red-pair!] - x [float32!] - y [float32!] - delta [float32!] - t [float32!] - t2 [float32!] - t3 [float32!] + x [float!] + y [float!] + delta [float!] + t [float!] + t2 [float!] + t3 [float!] i [integer!] - n [integer!] count [integer!] num [integer!] ][ - comment { - ; this is copy from macOS/draw.reds impl - ; seems not to work now.. + ; !!! seems there is some bug in R/S @ Linux ctx: dc/raw + x: 0.0 + y: 0.0 + count: (as-integer end - start) >> 4 - num: count + 1 + 2 + num: count + 1 p: start cairo_move_to ctx as-float p/x as-float p/y i: 0 - delta: (as float32! 1.0) / (as float32! 25.0) + delta: 1.0 / 25.0 while [i < count][ ;-- CatmullRom Spline, tension = 0.5 + ;print ["i = " i lf] + p0: p + (i % num) p1: p + (i + 1 % num) p2: p + (i + 2 % num) p3: p + (i + 3 % num) - t: as float32! 0.0 - n: 0 - until [ + t: 0.0 + loop 25 [ + ;print ["loop" lf] + t: t + delta t2: t * t t3: t2 * t - - x: (as float32! 2.0) * p1/x + (p2/x - p0/x * t) + - (((as float32! 2.0) * p0/x - ((as float32! 5.0) * p1/x) + ((as float32! 4.0) * p2/x) - p3/x) * t2) + - ((as float32! 3.0) * (p1/x - p2/x) + p3/x - p0/x * t3) * 0.5 - y: (as float32! 2.0) * p1/y + (p2/y - p0/y * t) + - (((as float32! 2.0) * p0/y - ((as float32! 5.0) * p1/y) + ((as float32! 4.0) * p2/y) - p3/y) * t2) + - ((as float32! 3.0) * (p1/y - p2/y) + p3/y - p0/y * t3) * 0.5 - - cairo_line_to ctx as-float x as-float y - - n: n + 1 - n = 25 + + comment { + x: 2.0 * p1/x + (p2/x - p0/x * t) + + ((2.0 * p0/x - (5.0 * p1/x) + (4.0 * p2/x) - p3/x) * t2) + + (3.0 * (p1/x - p2/x) + p3/x - p0/x * t3) * 0.5 + y: 2.0 * p1/y + (p2/y - p0/y * t) + + ((2.0 * p0/y - (5.0 * p1/y) + (4.0 * p2/y) - p3/y) * t2) + + (3.0 * (p1/y - p2/y) + p3/y - p0/y * t3) * 0.5 } + + cairo_line_to ctx x y ] - i: i + 4 + i: i + 1 ] if closed? [ cairo_close_path dc/raw ] do-paint dc - - } ; comment ] OS-draw-circle: func [ @@ -370,9 +369,9 @@ OS-draw-font: func [ len: -1 face: cairo_toy_font_face_create ;unicode/to-utf8 font/name :len ; family string - "Impact" - 0 ; slant normal\italic - 0 ; weight normal\bold + "sans-serif" + 1 ; slant normal\italic + 1 ; weight normal\bold cairo_set_font_face ctx face ;cairo_set_font_size ctx as-float font/size cairo_set_font_size ctx as-float 15 diff --git a/tests/draw.red b/tests/draw.red index 35bfad0f00..a567128d1b 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -96,7 +96,7 @@ l: layout [ line-width 2 fill-pen 170.20.20.128 - spline 10x10 40x40 40x40 10x40 + spline 10x10 40x10 40x40 10x40 text 5x55 "spline" ] @@ -114,6 +114,7 @@ l: layout [ text 5x55 "text" text 10x20 "Red" + pen red ; test if pen color font font-A text 10x30 "Red" ] @@ -143,7 +144,7 @@ l: layout [ pen linear red green blue line-width 5 - fill-pen no + fill-pen off box 10x10 40x40 ] From b83d28e35407a0a3cdd404dac51bd12855d870ea Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 22:10:24 +0300 Subject: [PATCH 0061/3432] gtk/draw: tests/draw.red check with windows --- tests/draw-windows.png | Bin 0 -> 17108 bytes tests/draw.red | 117 +++++++++++++++++++++++++++++------------ 2 files changed, 83 insertions(+), 34 deletions(-) create mode 100644 tests/draw-windows.png diff --git a/tests/draw-windows.png b/tests/draw-windows.png new file mode 100644 index 0000000000000000000000000000000000000000..21467468523e069d7ff4d04d036c5e6c234f5511 GIT binary patch literal 17108 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 Date: Mon, 28 Aug 2017 23:33:30 +0300 Subject: [PATCH 0062/3432] gtk/draw: text seems to work --- modules/view/backends/gtk3/draw.reds | 96 ++++++++++++++++++++++------ modules/view/backends/gtk3/gtk.reds | 23 +++++-- 2 files changed, 94 insertions(+), 25 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 5a7cbd54b2..9c89a89dbe 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -352,29 +352,82 @@ OS-draw-ellipse: func [ do-paint dc ] +; put this into draw-ctx! ? +font-size: 11 + OS-draw-font: func [ dc [draw-ctx!] font [red-object!] /local - ctx [handle!] - len [integer!] - face [handle!] - ; vals [red-value!] - ; state [red-block!] - ; int [red-integer!] - ; color [red-tuple!] - ; hFont [draw-ctx!] + cr [handle!] + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + css [c-string!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] + slant [integer!] + weight [integer!] ][ - ctx: dc/raw - len: -1 - face: cairo_toy_font_face_create - ;unicode/to-utf8 font/name :len ; family string - "sans-serif" - 1 ; slant normal\italic - 1 ; weight normal\bold - cairo_set_font_face ctx face - ;cairo_set_font_size ctx as-float font/size - cairo_set_font_size ctx as-float 15 + cr: dc/raw + + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + dc/font-color: color/array1 + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + slant: CAIRO_FONT_SLANT_NORMAL + weight: CAIRO_FONT_WEIGHT_NORMAL + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] + sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] + sym = _underline [] + sym = _strike [] + true [] + ] + style: style + 1 + ] + ] + + ;cairo_select_font_face cr name slant weight + cairo_select_font_face cr name slant weight + + if TYPE_OF(size) = TYPE_INTEGER [ + cairo_set_font_size cr as-float size/value + font-size: size/value + ] ] OS-draw-text: func [ @@ -390,9 +443,14 @@ OS-draw-text: func [ len: -1 str: unicode/to-utf8 text :len cairo_move_to ctx as-float pos/x - as-float pos/y + as-float pos/y + font-size + + set-source-color dc/raw dc/font-color cairo_show_text ctx str + do-paint dc + + set-source-color dc/raw dc/pen-color ;-- backup pen color ] OS-draw-arc: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index ef94abc715..f794d891b1 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -89,6 +89,17 @@ GtkTextIter!: alias struct! [ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] +#enum cairo_font_slant_t! [ + CAIRO_FONT_SLANT_NORMAL + CAIRO_FONT_SLANT_ITALIC + CAIRO_FONT_SLANT_OBLIQUE +] + +#enum cairo_font_weight_t! [ + CAIRO_FONT_WEIGHT_NORMAL + CAIRO_FONT_WEIGHT_BOLD +] + ; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo ; cairo_text_extents_t!: alias struct! [ ; x_bearing [float!] @@ -926,12 +937,12 @@ GtkTextIter!: alias struct! [ cr [handle!] ] ; Related to draw text with cairo (no succes for base widget) replaced by pango_cairo - ; cairo_select_font_face: "cairo_select_font_face" [ - ; cr [handle!] - ; family [c-string!] - ; slant [integer!] - ; weight [integer!] - ; ] + cairo_select_font_face: "cairo_select_font_face" [ + cr [handle!] + family [c-string!] + slant [integer!] + weight [integer!] + ] ; cairo_set_font_size: "cairo_set_font_size" [ ; cr [handle!] ; size [integer!] From 22c8594810f2ac4c301913ebe0afa1e0e8ff3e4f Mon Sep 17 00:00:00 2001 From: honix Date: Mon, 28 Aug 2017 23:48:55 +0300 Subject: [PATCH 0063/3432] gtk/draw: minors --- modules/view/backends/gtk3/draw.reds | 1 - tests/draw.red | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 9c89a89dbe..c748e9e56a 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -421,7 +421,6 @@ OS-draw-font: func [ ] ] - ;cairo_select_font_face cr name slant weight cairo_select_font_face cr name slant weight if TYPE_OF(size) = TYPE_INTEGER [ diff --git a/tests/draw.red b/tests/draw.red index f20e5ccc1d..ddfa5284b8 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -243,16 +243,16 @@ l: layout [ ] font-label: make font! [ - name: "monospace" - size: 8 + name: "Arial" + size: 11 color: white - anti-alias?: yes + anti-alias?: no ] font-A: make font! [ - name: "Comic Sans MS" - size: 10 - color: aqua + name: "Times New Roman" + size: 15 + color: red style: [bold italic underline] anti-alias?: yes ] From 23dc8ce7c6255114d19d7bd8453de35bb668bd30 Mon Sep 17 00:00:00 2001 From: honix Date: Tue, 29 Aug 2017 19:50:55 +0300 Subject: [PATCH 0064/3432] gtk/draw: spline! --- modules/view/backends/gtk3/draw.reds | 60 ++++++++++++++++++--------- tests/draw-windows.png | Bin 17108 -> 19253 bytes 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index c748e9e56a..bd0b441d2e 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -12,6 +12,9 @@ Red/System [ #include %text-box.reds +max-edges: 1000 ;-- max pre-allocated points +edges: as red-pair! allocate max-edges * (size? red-pair!) ;-- pre-allocated points + set-source-color: func [ cr [handle!] color [integer!] @@ -224,56 +227,73 @@ OS-draw-spline: func [ t2 [float!] t3 [float!] i [integer!] + n [integer!] count [integer!] num [integer!] ][ - ; !!! seems there is some bug in R/S @ Linux - ctx: dc/raw - x: 0.0 - y: 0.0 - count: (as-integer end - start) >> 4 num: count + 1 - p: start + p: edges + unless closed? [ + p/x: start/x ;-- duplicate first point + p/y: start/y + p: p + 1 + ] + while [start <= end][ + p/x: start/x + p/y: start/y + p: p + 1 + start: start + 1 + ] + unless closed? [ + p/x: end/x ;-- duplicate end point + p/y: end/y + ] + + either closed? [ + count: count + 1 + ][ + num: num + 2 + ] - cairo_move_to ctx as-float p/x as-float p/y + p: edges i: 0 delta: 1.0 / 25.0 while [i < count][ ;-- CatmullRom Spline, tension = 0.5 - ;print ["i = " i lf] - p0: p + (i % num) p1: p + (i + 1 % num) p2: p + (i + 2 % num) p3: p + (i + 3 % num) t: 0.0 - loop 25 [ - ;print ["loop" lf] - + n: 0 + until [ t: t + delta t2: t * t t3: t2 * t - comment { - x: 2.0 * p1/x + (p2/x - p0/x * t) + - ((2.0 * p0/x - (5.0 * p1/x) + (4.0 * p2/x) - p3/x) * t2) + - (3.0 * (p1/x - p2/x) + p3/x - p0/x * t3) * 0.5 - y: 2.0 * p1/y + (p2/y - p0/y * t) + - ((2.0 * p0/y - (5.0 * p1/y) + (4.0 * p2/y) - p3/y) * t2) + - (3.0 * (p1/y - p2/y) + p3/y - p0/y * t3) * 0.5 } + x: + 2.0 * (as-float p1/x) + ((as-float p2/x) - (as-float p0/x) * t) + + ((2.0 * (as-float p0/x) - (5.0 * (as-float p1/x)) + (4.0 * (as-float p2/x)) - (as-float p3/x)) * t2) + + (3.0 * ((as-float p1/x) - (as-float p2/x)) + (as-float p3/x) - (as-float p0/x) * t3) * 0.5 + y: + 2.0 * (as-float p1/y) + ((as-float p2/y) - (as-float p0/y) * t) + + ((2.0 * (as-float p0/y) - (5.0 * (as-float p1/y)) + (4.0 * (as-float p2/y)) - (as-float p3/y)) * t2) + + (3.0 * ((as-float p1/y) - (as-float p2/y)) + (as-float p3/y) - (as-float p0/y) * t3) * 0.5 cairo_line_to ctx x y + n: n + 1 + n = 25 ] i: i + 1 ] if closed? [ - cairo_close_path dc/raw + cairo_close_path ctx ] do-paint dc ] diff --git a/tests/draw-windows.png b/tests/draw-windows.png index 21467468523e069d7ff4d04d036c5e6c234f5511..24aee4aff746bbcbdf5ecaf1338f4e97741a6452 100644 GIT binary patch literal 19253 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 literal 17108 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 Date: Wed, 30 Aug 2017 14:17:09 +0300 Subject: [PATCH 0065/3432] gtk/draw: spline refactor --- modules/view/backends/gtk3/draw.reds | 136 ++++++++++++++------------- 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index bd0b441d2e..d149f98618 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -12,9 +12,6 @@ Red/System [ #include %text-box.reds -max-edges: 1000 ;-- max pre-allocated points -edges: as red-pair! allocate max-edges * (size? red-pair!) ;-- pre-allocated points - set-source-color: func [ cr [handle!] color [integer!] @@ -208,72 +205,24 @@ OS-draw-polygon: func [ do-paint dc ] -OS-draw-spline: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - closed? [logic!] +spline-delta: 1.0 / 25.0 + +do-spline-step: func [ + ctx [handle!] + p0 [red-pair!] + p1 [red-pair!] + p2 [red-pair!] + p3 [red-pair!] /local - ctx [handle!] - p [red-pair!] - p0 [red-pair!] - p1 [red-pair!] - p2 [red-pair!] - p3 [red-pair!] - x [float!] - y [float!] - delta [float!] t [float!] t2 [float!] t3 [float!] - i [integer!] - n [integer!] - count [integer!] - num [integer!] + x [float!] + y [float!] ][ - ctx: dc/raw - - count: (as-integer end - start) >> 4 - num: count + 1 - - p: edges - unless closed? [ - p/x: start/x ;-- duplicate first point - p/y: start/y - p: p + 1 - ] - while [start <= end][ - p/x: start/x - p/y: start/y - p: p + 1 - start: start + 1 - ] - unless closed? [ - p/x: end/x ;-- duplicate end point - p/y: end/y - ] - - either closed? [ - count: count + 1 - ][ - num: num + 2 - ] - - p: edges - - i: 0 - delta: 1.0 / 25.0 - - while [i < count][ ;-- CatmullRom Spline, tension = 0.5 - p0: p + (i % num) - p1: p + (i + 1 % num) - p2: p + (i + 2 % num) - p3: p + (i + 3 % num) - t: 0.0 - n: 0 - until [ - t: t + delta + loop 25 [ + t: t + spline-delta t2: t * t t3: t2 * t @@ -287,14 +236,67 @@ OS-draw-spline: func [ (3.0 * ((as-float p1/y) - (as-float p2/y)) + (as-float p3/y) - (as-float p0/y) * t3) * 0.5 cairo_line_to ctx x y - n: n + 1 - n = 25 ] - i: i + 1 +] + +OS-draw-spline: func [ + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + closed? [logic!] + /local + ctx [handle!] + point [red-pair!] + stop [red-pair!] +][ + ctx: dc/raw + + either closed? [ + do-spline-step ctx + end + start + start + 1 + start + 2 + ][ + do-spline-step ctx + start + start + start + 1 + start + 2 ] - if closed? [ + + point: start + stop: end - 3 + + while [point <= stop] [ + do-spline-step ctx + point + point + 1 + point + 2 + point + 3 + point: point + 1 + ] + + either closed? [ + do-spline-step ctx + end - 2 + end - 1 + end + start + do-spline-step ctx + end - 1 + end + start + start + 1 cairo_close_path ctx + ][ + do-spline-step ctx + end - 2 + end - 1 + end + end ] + do-paint dc ] From 59098e77cf18b5d7742e25d5d20d726c4fe89d50 Mon Sep 17 00:00:00 2001 From: honix Date: Wed, 30 Aug 2017 14:55:12 +0300 Subject: [PATCH 0066/3432] gtk/draw: spline 2 points case --- modules/view/backends/gtk3/draw.reds | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index d149f98618..82d6dbdde7 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -249,6 +249,11 @@ OS-draw-spline: func [ point [red-pair!] stop [red-pair!] ][ + if (as-integer end - start) >> 4 = 1 [ ;-- two points input + OS-draw-line dc start end ;-- draw a line + exit + ] + ctx: dc/raw either closed? [ From 200793d4c7c73e6ae40b559572135aeec4f942a0 Mon Sep 17 00:00:00 2001 From: honix Date: Wed, 30 Aug 2017 23:47:49 +0300 Subject: [PATCH 0067/3432] gtk/draw: text size seems ok --- modules/view/backends/gtk3/draw.reds | 20 +++++++++++++++----- modules/view/backends/gtk3/gtk.reds | 22 +++++++++++----------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 82d6dbdde7..0ae3ee79b6 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -379,8 +379,8 @@ OS-draw-ellipse: func [ do-paint dc ] -; put this into draw-ctx! ? -font-size: 11 +; move this to draw-ctx? +font-size: 10.0 ;-- used to find top line OS-draw-font: func [ dc [draw-ctx!] @@ -401,6 +401,7 @@ OS-draw-font: func [ rgba [c-string!] slant [integer!] weight [integer!] + extents [cairo_font_extents_t!] ][ cr: dc/raw @@ -451,8 +452,17 @@ OS-draw-font: func [ cairo_select_font_face cr name slant weight if TYPE_OF(size) = TYPE_INTEGER [ - cairo_set_font_size cr as-float size/value - font-size: size/value + extents: declare cairo_font_extents_t! + cairo_font_extents cr extents + + font-size: as-float size/value + cairo_set_font_size cr font-size * ((extents/ascent + extents/descent) / extents/ascent) + + ; This technique is little more correct for me. + ; This Red example will show the difference: + ; + ; f: make font! [name: "Arial" size: 120] + ; view [base 140x140 draw [font f text 10x10 "A" pen white box 0x10 140x130]] ] ] @@ -469,7 +479,7 @@ OS-draw-text: func [ len: -1 str: unicode/to-utf8 text :len cairo_move_to ctx as-float pos/x - as-float pos/y + font-size + (as-float pos/y) + font-size set-source-color dc/raw dc/font-color cairo_show_text ctx str diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index f794d891b1..bb44fb6b01 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -110,13 +110,13 @@ GtkTextIter!: alias struct! [ ; y_advance [float!] ; ] -; cairo_font_extents_t!: alias struct! [ -; ascent [float!] -; descent [float!] -; height [float!] -; max_x_advance [float!] -; max_y_advance [float!] -; ] +cairo_font_extents_t!: alias struct! [ + ascent [float!] + descent [float!] + height [float!] + max_x_advance [float!] + max_y_advance [float!] +] #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" @@ -952,10 +952,10 @@ GtkTextIter!: alias struct! [ ; text [c-string!] ; extents [handle!] ; ] - ; cairo_font_extents: "cairo_font_extents" [ - ; cr [handle!] - ; extents [handle!] - ; ] + cairo_font_extents: "cairo_font_extents" [ + cr [handle!] + extents [cairo_font_extents_t!] + ] ; cairo_show_text: "cairo_show_text" [ ; cr [handle!] ; text [c-string!] From 135c56bdb932f6c47e3b3a2ec882a2f3b7623dfb Mon Sep 17 00:00:00 2001 From: qtxie Date: Sat, 2 Sep 2017 10:34:34 +0800 Subject: [PATCH 0068/3432] FIX: GTK: cannot set field's width less than 166 --- modules/view/backends/gtk3/gtk.reds | 4 ++++ modules/view/backends/gtk3/gui.reds | 1 + 2 files changed, 5 insertions(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index bb44fb6b01..42b7562470 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -554,6 +554,10 @@ cairo_font_extents_t!: alias struct! [ gtk_entry_new: "gtk_entry_new" [ return: [handle!] ] + gtk_entry_set_width_chars: "gtk_entry_set_width_chars" [ + entry [handle!] + nchars [integer!] + ] gtk_entry_get_buffer: "gtk_entry_get_buffer" [ entry [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f653b168fe..3a54db50d1 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1348,6 +1348,7 @@ OS-make-view: func [ ;This depends on version >= 3.2 ;gtk_widget_set_focus_on_click widget yes gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) + gtk_entry_set_width_chars widget 0 ] sym = progress [ widget: gtk_progress_bar_new From bc946a4eefbc002cf2d22746792dd37ac45f6cea Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 2 Sep 2017 07:37:36 +0200 Subject: [PATCH 0069/3432] TEMPORARY gtk-auto-adjust? switch to direct use inside red example --- modules/view/backends/gtk3/gui.reds | 9 +++++---- modules/view/view.red | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 3a54db50d1..e2354fcf51 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1212,12 +1212,13 @@ OS-show-window: func [ ][ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd - ;auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? - ;if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ + + ; @@ TEMPORARY: TO BE REMOVED BUT USEFUL NOW FOR COMPARING THE EFFECT OF ADJUST-SIZES IN RED TEST WITHOUT RECOMPILING CONSOLE + auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? + if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ adjust-sizes as handle! hWnd gtk_widget_queue_draw as handle! hWnd - ;debug-show-children as handle! hWnd no - ;] + ] ] OS-make-view: func [ diff --git a/modules/view/view.red b/modules/view/view.red index 561f76ec65..72109c7042 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -643,6 +643,12 @@ system/view: context [ auto-sync?: yes ;-- refresh faces on changes automatically debug?: no ;-- output verbose logs silent?: no ;-- do not report errors (livecoding) + + #if config/OS = 'Linux [ + ; @@ TEMPORARY: just the time to develop para aand fix + gtk-auto-adjust?: yes + ] + ] #include %backends/platform.red From 87caf0d964633eb1c06f93d492cad878d551053f Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 2 Sep 2017 11:44:32 +0200 Subject: [PATCH 0070/3432] First version of request-font --- modules/view/backends/gtk3/comdlgs.reds | 57 ++++++++++++++++ modules/view/backends/gtk3/font.reds | 67 ------------------ modules/view/backends/gtk3/gtk.reds | 91 +++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 67 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index d20ca1311a..8576c0d414 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -64,4 +64,61 @@ OS-request-file: func [ return: [red-value!] ][ _request-file title name filter save? multi? no +] + +OS-request-font: func [ + font [red-object!] + selected [red-object!] + mono? [logic!] + return: [red-object!] + /local + widget [handle!] + fd [handle!] + values [red-value!] + style [red-block!] + size [integer!] + cstr [c-string!] + str [red-string!] + manager [integer!] + trait [integer!] + bold? [logic!] + resp [integer!] +][ + widget: gtk_font_chooser_dialog_new "Font" null + resp: gtk_dialog_run widget + ;; print ["resp: " resp lf] + either resp = -5 [ + fd: gtk_font_chooser_get_font_desc widget + cstr: pango_font_description_get_family fd + size: length? cstr + values: object/get-values font + str: string/make-at values + FONT_OBJ_NAME size Latin1 + unicode/load-utf8-stream cstr size str null + + size: pango_font_description_get_size fd + integer/make-at values + FONT_OBJ_SIZE size / PANGO_SCALE + + style: as red-block! values + FONT_OBJ_STYLE + bold?: no + if PANGO_WEIGHT_NORMAL < pango_font_description_get_weight fd [ + word/make-at _bold as red-value! style + bold?: yes + ] + if PANGO_STYLE_ITALIC = pango_font_description_get_style fd [ + either bold? [ + block/make-at style 4 + word/push-in _bold style + word/push-in _italic style + ][ + word/make-at _italic as red-value! style + ] + ] + ][ + font/header: TYPE_NONE + ] + gtk_widget_destroy widget + ; This trick really matters to end the loop when in the red-console + while [gtk_events_pending][gtk_main_iteration] + + font ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 6cae3a9936..d65303d1db 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -10,64 +10,6 @@ Red/System [ } ] -#enum pango-style! [ - PANGO_STYLE_NORMAL - PANGO_STYLE_OBLIQUE - PANGO_STYLE_ITALIC -] - -#enum pango-variant! [ - PANGO_VARIANT_NORMAL - PANGO_VARIANT_SMALL_CAPS -] - -#enum pango-weight! [ - PANGO_WEIGHT_THIN: 100 - PANGO_WEIGHT_ULTRALIGHT: 200 - PANGO_WEIGHT_LIGHT: 300 - PANGO_WEIGHT_SEMILIGHT: 350 - PANGO_WEIGHT_BOOK: 380 - PANGO_WEIGHT_NORMAL: 400 - PANGO_WEIGHT_MEDIUM: 500 - PANGO_WEIGHT_SEMIBOLD: 600 - PANGO_WEIGHT_BOLD: 700 - PANGO_WEIGHT_ULTRABOLD: 800 - PANGO_WEIGHT_HEAVY: 900 - PANGO_WEIGHT_ULTRAHEAVY: 1000 -] - -#enum pango-stretch! [ - PANGO_STRETCH_ULTRA_CONDENSED - PANGO_STRETCH_EXTRA_CONDENSED - PANGO_STRETCH_CONDENSED - PANGO_STRETCH_SEMI_CONDENSED - PANGO_STRETCH_NORMAL - PANGO_STRETCH_SEMI_EXPANDED - PANGO_STRETCH_EXPANDED - PANGO_STRETCH_EXTRA_EXPANDED - PANGO_STRETCH_ULTRA_EXPANDED -] - -#enum pango-font-mask! [ - PANGO_FONT_MASK_FAMILY: 1 - PANGO_FONT_MASK_STYLE: 2 - PANGO_FONT_MASK_VARIANT: 4 - PANGO_FONT_MASK_WEIGHT: 8 - PANGO_FONT_MASK_STRETCH: 16 - PANGO_FONT_MASK_SIZE: 32 - PANGO_FONT_MASK_GRAVITY: 64 -] - -#define PANGO_SCALE 1024 -#define PANGO_SCALE_XX_SMALL 0.5787037037037 -#define PANGO_SCALE_X_SMALL 0.6444444444444 -#define PANGO_SCALE_SMALL 0.8333333333333 -#define PANGO_SCALE_MEDIUM 1.0 -#define PANGO_SCALE_LARGE 1.2 -#define PANGO_SCALE_X_LARGE 1.4399999999999 -#define PANGO_SCALE_XX_LARGE 1.728 - - ;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget make-font: func [ @@ -331,15 +273,6 @@ font-description: func [ ] -OS-request-font: func [ - font [red-object!] - selected [red-object!] - mono? [logic!] - return: [red-object!] -][ - font -] - ; Stuff maybe to REMOVE related to cairo without any success ; #enum cairo_font_slant_t! [ ; CAIRO_FONT_SLANT_NORMAL diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 42b7562470..71a0d5675e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -89,6 +89,64 @@ GtkTextIter!: alias struct! [ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] + +#enum pango-style! [ + PANGO_STYLE_NORMAL + PANGO_STYLE_OBLIQUE + PANGO_STYLE_ITALIC +] + +#enum pango-variant! [ + PANGO_VARIANT_NORMAL + PANGO_VARIANT_SMALL_CAPS +] + +#enum pango-weight! [ + PANGO_WEIGHT_THIN: 100 + PANGO_WEIGHT_ULTRALIGHT: 200 + PANGO_WEIGHT_LIGHT: 300 + PANGO_WEIGHT_SEMILIGHT: 350 + PANGO_WEIGHT_BOOK: 380 + PANGO_WEIGHT_NORMAL: 400 + PANGO_WEIGHT_MEDIUM: 500 + PANGO_WEIGHT_SEMIBOLD: 600 + PANGO_WEIGHT_BOLD: 700 + PANGO_WEIGHT_ULTRABOLD: 800 + PANGO_WEIGHT_HEAVY: 900 + PANGO_WEIGHT_ULTRAHEAVY: 1000 +] + +#enum pango-stretch! [ + PANGO_STRETCH_ULTRA_CONDENSED + PANGO_STRETCH_EXTRA_CONDENSED + PANGO_STRETCH_CONDENSED + PANGO_STRETCH_SEMI_CONDENSED + PANGO_STRETCH_NORMAL + PANGO_STRETCH_SEMI_EXPANDED + PANGO_STRETCH_EXPANDED + PANGO_STRETCH_EXTRA_EXPANDED + PANGO_STRETCH_ULTRA_EXPANDED +] + +#enum pango-font-mask! [ + PANGO_FONT_MASK_FAMILY: 1 + PANGO_FONT_MASK_STYLE: 2 + PANGO_FONT_MASK_VARIANT: 4 + PANGO_FONT_MASK_WEIGHT: 8 + PANGO_FONT_MASK_STRETCH: 16 + PANGO_FONT_MASK_SIZE: 32 + PANGO_FONT_MASK_GRAVITY: 64 +] + +#define PANGO_SCALE 1024 +#define PANGO_SCALE_XX_SMALL 0.5787037037037 +#define PANGO_SCALE_X_SMALL 0.6444444444444 +#define PANGO_SCALE_SMALL 0.8333333333333 +#define PANGO_SCALE_MEDIUM 1.0 +#define PANGO_SCALE_LARGE 1.2 +#define PANGO_SCALE_X_LARGE 1.4399999999999 +#define PANGO_SCALE_XX_LARGE 1.728 + #enum cairo_font_slant_t! [ CAIRO_FONT_SLANT_NORMAL CAIRO_FONT_SLANT_ITALIC @@ -310,6 +368,15 @@ cairo_font_extents_t!: alias struct! [ ; widget [handle!] ; return: [integer!] ; ] + gtk_font_chooser_dialog_new: "gtk_font_chooser_dialog_new" [ + title [c-string!] + win [handle!] + return: [handle!] + ] + gtk_font_chooser_get_font_desc: "gtk_font_chooser_get_font_desc" [ + font-sel [handle!] + return: [handle!] + ] gtk_main_iteration: "gtk_main_iteration" [ return: [logic!] ] @@ -749,26 +816,50 @@ cairo_font_extents_t!: alias struct! [ fontdesc [handle!] name [c-string!] ] + pango_font_description_get_family: "pango_font_description_get_family" [ + fontdesc [handle!] + return: [c-string!] + ] pango_font_description_set_size: "pango_font_description_set_size" [ fontdesc [handle!] size [integer!] ] + pango_font_description_get_size: "pango_font_description_get_size" [ + fontdesc [handle!] + return: [integer!] + ] pango_font_description_set_weight: "pango_font_description_set_weight" [ fontdesc [handle!] weight [integer!] ] + pango_font_description_get_weight: "pango_font_description_get_weight" [ + fontdesc [handle!] + return: [integer!] + ] pango_font_description_set_style: "pango_font_description_set_style" [ fontdesc [handle!] style [integer!] ] + pango_font_description_get_style: "pango_font_description_get_style" [ + fontdesc [handle!] + return: [integer!] + ] pango_font_description_set_stretch: "pango_font_description_set_stretch" [ fontdesc [handle!] stretch [integer!] ] + pango_font_description_get_stretch: "pango_font_description_get_stretch" [ + fontdesc [handle!] + return: [integer!] + ] pango_font_description_set_variant: "pango_font_description_set_variant" [ fontdesc [handle!] variant [integer!] ] + pango_font_description_get_variant: "pango_font_description_get_variant" [ + fontdesc [handle!] + return: [integer!] + ] gdk_pango_context_get: "gdk_pango_context_get" [ return: [handle!] ] From 9e5534976c482ac84ab79bcdb365b76df80d0dc0 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 15 Sep 2017 07:20:23 +0200 Subject: [PATCH 0071/3432] Preliminary image stuff on linux --- build/includes.r | 13 + environment/codecs/bmp.red | 4 +- environment/codecs/gif.red | 4 +- environment/codecs/jpeg.red | 4 +- environment/codecs/png.red | 4 +- modules/view/backends/gtk3/draw.reds | 86 ++- modules/view/backends/gtk3/gtk.reds | 60 ++- modules/view/backends/gtk3/gui.reds | 130 +++-- modules/view/backends/gtk3/handlers.reds | 8 +- modules/view/backends/platform.red | 30 +- runtime/platform/image-gdk.reds | 643 +++++++++++++++++++++++ runtime/red.reds | 4 + tests/gtk3/react-test6-mini.red | 16 + tests/gtk3/react-test6.red | 6 +- tests/gtk3/vid.red | 7 +- tests/gtk3/view-test.red | 153 +++--- tests/gtk3/view-test2.red | 29 + 17 files changed, 1055 insertions(+), 146 deletions(-) create mode 100644 runtime/platform/image-gdk.reds create mode 100644 tests/gtk3/react-test6-mini.red create mode 100644 tests/gtk3/view-test2.red diff --git a/build/includes.r b/build/includes.r index 9d63effcee..ec353571ef 100644 --- a/build/includes.r +++ b/build/includes.r @@ -137,6 +137,7 @@ write %build/bin/sources.r set-cache [ %COM.reds %image-gdiplus.reds %image-quartz.reds + %image-gdk.reds %win32-cli.reds %win32-gui.reds %win32-ansi.reds @@ -191,6 +192,18 @@ write %build/bin/sources.r set-cache [ %tab-panel.reds %text-box.reds ] + %gtk3/ [ + %comdlgs.reds + %font.reds + %gui.reds + %draw.reds + %handlers.reds + %style.reds + %events.reds + %gtk.reds + %para.reds + %text-box.reds + ] %test/ [ %draw.reds %events.reds diff --git a/environment/codecs/bmp.red b/environment/codecs/bmp.red index fd07f28efd..28db761e6a 100644 --- a/environment/codecs/bmp.red +++ b/environment/codecs/bmp.red @@ -23,8 +23,8 @@ put system/codecs 'bmp context [ ] decode: routine [data [any-type!]][ - #if OS <> 'Linux [ + ;#if OS <> 'Linux [ stack/set-last as cell! image/decode data - ] + ;] ] ] \ No newline at end of file diff --git a/environment/codecs/gif.red b/environment/codecs/gif.red index 02d761e12f..f92011573e 100644 --- a/environment/codecs/gif.red +++ b/environment/codecs/gif.red @@ -23,8 +23,8 @@ put system/codecs 'gif context [ ] decode: routine [data [any-type!]][ - #if OS <> 'Linux [ + ;#if OS <> 'Linux [ stack/set-last as cell! image/decode data - ] + ;] ] ] \ No newline at end of file diff --git a/environment/codecs/jpeg.red b/environment/codecs/jpeg.red index f24382e734..c20ca60dc9 100644 --- a/environment/codecs/jpeg.red +++ b/environment/codecs/jpeg.red @@ -23,8 +23,8 @@ put system/codecs 'jpeg context [ ] decode: routine [data [any-type!]][ - #if OS <> 'Linux [ + ;#if OS <> 'Linux [ stack/set-last as cell! image/decode data - ] + ;] ] ] \ No newline at end of file diff --git a/environment/codecs/png.red b/environment/codecs/png.red index 1ee63257b5..e4227f865a 100644 --- a/environment/codecs/png.red +++ b/environment/codecs/png.red @@ -23,8 +23,8 @@ put system/codecs 'png context [ ] decode: routine [data [any-type!]][ - #if OS <> 'Linux [ + ;#if OS <> 'Linux [ stack/set-last as cell! image/decode data - ] + ;] ] ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 0ae3ee79b6..7b34262595 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -603,6 +603,55 @@ OS-draw-line-cap: func [ ] ] +; OS-draw-image: func [ +; dc [draw-ctx!] +; image [red-image!] +; start [red-pair!] +; end [red-pair!] +; key-color [red-tuple!] +; border? [logic!] +; crop1 [red-pair!] +; pattern [red-word!] +; /local +; x [integer!] +; y [integer!] +; width [integer!] +; height [integer!] +; ][ +; 0 +; ] + + +GDK-draw-image: func [ + dc [handle!] + image [integer!] + x [integer!] + y [integer!] + ; width [integer!] + ; height [integer!] + ;/local + ; rc [NSRect!] + ; ty [float32!] +][ + ; rc: make-rect x y width height + ; ty: rc/y + rc/h + ; ;-- flip coords + ; ;; drawing an image or PDF by calling Core Graphics functions directly, + ; ;; we must flip the CTM. + ; ;; http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage + ; CGContextTranslateCTM dc as float32! 0.0 ty + ; CGContextScaleCTM dc as float32! 1.0 as float32! -1.0 + + ; CGContextDrawImage dc rc/x as float32! 0.0 rc/w rc/h image + + ; ;-- flip back + ; CGContextScaleCTM dc as float32! 1.0 as float32! -1.0 + ; CGContextTranslateCTM dc as float32! 0.0 (as float32! 0.0) - ty + gdk_cairo_set_source_pixbuf dc as handle! image x y + cairo_paint dc + ;0 +] + OS-draw-image: func [ dc [draw-ctx!] image [red-image!] @@ -613,12 +662,47 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local + img [integer!] + sub-img [integer!] x [integer!] y [integer!] width [integer!] height [integer!] + w [float!] + h [float!] + ww [float!] + crop2 [red-pair!] ][ -0 + print ["OS-draw-image" lf] + either null? start [x: 0 y: 0][x: start/x y: start/y] + case [ + start = end [ + width: IMAGE_WIDTH(image/size) + height: IMAGE_HEIGHT(image/size) + ] + start + 1 = end [ ;-- two control points + width: end/x - x + height: end/y - y + ] + start + 2 = end [0] ;@@ TBD three control points + true [0] ;@@ TBD four control points + ] + + img: OS-image/to-pixbuf image + if crop1 <> null [ + crop2: crop1 + 1 + w: as float! crop2/x + h: as float! crop2/y + ww: w / h * (as float! height) + width: as-integer ww + ; create new pixbuf + sub-img: as-integer gdk_pixbuf_scale_simple as handle! img width height 0 ; to correct parameters!!! + ;sub-img: as-integer gdk_pixbuf_new 0 yes 8 width height + ;gdk_pixbuf_scale as handle! img as handle! sub-img 0 0 width height 0.0 0.0 1.0 1.0 0 ; to correct parameters!!! + ] + + GDK-draw-image dc/raw img x y + if crop1 <> null [g_object_unref as handle! sub-img] ] OS-draw-grad-pen-old: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 71a0d5675e..f0844c15d8 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -573,6 +573,10 @@ cairo_font_extents_t!: alias struct! [ button [handle!] label [c-string!] ] + gtk_button_set_image: "gtk_button_set_image" [ + button [handle!] + image [handle!] + ] gtk_check_button_new_with_label: "gtk_check_button_new_with_label" [ label [c-string!] return: [handle!] @@ -606,6 +610,14 @@ cairo_font_extents_t!: alias struct! [ gtk_drawing_area_new: "gtk_drawing_area_new" [ return: [handle!] ] + gtk_image_new_from_pixbuf: "gtk_image_new_from_pixbuf" [ + pixbuf [handle!] + return: [handle!] + ] + gtk_image_new_from_file: "gtk_image_new_from_file" [ + filename [c-string!] + return: [handle!] + ] gtk_label_new: "gtk_label_new" [ label [c-string!] return: [handle!] @@ -666,7 +678,15 @@ cairo_font_extents_t!: alias struct! [ ] gtk_progress_bar_get_fraction: "gtk_progress_bar_get_fraction" [ progress [handle!] - return: [float!] + return: [float!] + ] + gtk_progress_bar_set_inverted: "gtk_progress_bar_set_inverted" [ + progress [handle!] + inv [logic!] + ] + gtk_orientable_set_orientation: "gtk_orientable_set_orientation" [ + widget [handle!] + orient [integer!] ] gtk_text_view_new: "gtk_text_view_new" [ return: [handle!] @@ -1055,6 +1075,44 @@ cairo_font_extents_t!: alias struct! [ ; cr [handle!] ; text [c-string!] ; ] + gdk_cairo_set_source_pixbuf: "gdk_cairo_set_source_pixbuf" [ + cr [handle!] + pixbuf [handle!] + x [integer!] + y [integer!] + ] + gdk_pixbuf_new: "gdk_pixbuf_new" [ + colorsp [integer!] + alpha [logic!] + bits [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] + gdk_pixbuf_copy: "gdk_pixbuf_copy" [ + pixbuf [handle!] + return: [handle!] + ] + gdk_pixbuf_scale: "gdk_pixbuf_scale" [ + src [handle!] + dest [handle!] + dest_x [integer!] + dest_y [integer!] + dest_width [integer!] + dest_height [integer!] + offset_x [float!] + offset_y [float!] + scale_x [float!] + scale_y [float!] + interp_type [integer!] + ] + gdk_pixbuf_scale_simple: "gdk_pixbuf_scale_simple" [ + src [handle!] + dest_width [integer!] + dest_height [integer!] + interp_type [integer!] + return: [handle!] + ] pango_cairo_create_context: "pango_cairo_create_context" [ cr [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e2354fcf51..1ea75b26d7 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -143,8 +143,12 @@ get-face-handle: func [ state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE assert TYPE_OF(state) = TYPE_BLOCK int: as red-integer! block/rs-head state - assert TYPE_OF(int) = TYPE_INTEGER - as handle! int/value + ;assert TYPE_OF(int) = TYPE_INTEGER + either TYPE_OF(int) = TYPE_INTEGER [ + as handle! int/value + ][ + null + ] ] get-widget-symbol: func [ @@ -460,31 +464,33 @@ adjust-sizes: func [ while [face < tail][ cpt: cpt + 1 child: get-face-handle face - values: object/get-values face - offset: as red-pair! values + FACE_OBJ_OFFSET - size: as red-pair! values + FACE_OBJ_SIZE - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] - if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] - ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 - if any [ox > offset/x not overlap?] [dx: 0] - unless null? container [ - widget: g_object_get_qdata child _widget-id - if null? widget [widget: child] - if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] - gtk_fixed_move container widget offset/x + dx offset/y - gtk_widget_get_allocation widget as handle! rect - ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates - if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] + unless null? child [ + values: object/get-values face + offset: as red-pair! values + FACE_OBJ_OFFSET + size: as red-pair! values + FACE_OBJ_SIZE + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] + if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] + ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 + if any [ox > offset/x not overlap?] [dx: 0] + unless null? container [ + widget: g_object_get_qdata child _widget-id + if null? widget [widget: child] + if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] + gtk_fixed_move container widget offset/x + dx offset/y + gtk_widget_get_allocation widget as handle! rect + ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates + if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] + ] + ; save previous offset and size coordinates + ox: offset/x oy: offset/y sx: size/x sy: size/y + if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] + dx: dx + rect/width - sx + dy: dy + rect/height - sy + if debug [ print ["next dx: " dx lf]] + adjust-sizes child ] - ; save previous offset and size coordinates - ox: offset/x oy: offset/y sx: size/x sy: size/y - if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] - dx: dx + rect/width - sx - dy: dy + rect/height - sy - if debug [ print ["next dx: " dx lf]] - adjust-sizes child face: face + 1 ] if debug [print-line "Pane end"] @@ -546,7 +552,7 @@ change-size: func [ saved [int-ptr!] method [integer!] ][ - print-line "change-size" + ;; print-line "change-size" ; rc: make-rect size/x size/y 0 0 ; if all [type = button size/y > 32][ ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" NSRegularSquareBezelStyle] @@ -575,32 +581,24 @@ change-size: func [ ] change-image: func [ - hWnd [integer!] + hWnd [handle!] image [red-image!] type [integer!] /local - id [integer!] + img [handle!] ][ - ; case [ - ; type = camera [ - ; snap-camera hWnd - ; until [TYPE_OF(image) = TYPE_IMAGE] ;-- wait - ; ] - ; any [type = button type = check type = radio][ - ; if TYPE_OF(image) <> TYPE_IMAGE [ - ; objc_msgSend [hWnd sel_getUid "setImage:" 0] - ; exit - ; ] - ; id: objc_msgSend [objc_getClass "NSImage" sel_getUid "alloc"] - ; id: objc_msgSend [id sel_getUid "initWithCGImage:size:" OS-image/to-cgimage image 0 0] - ; objc_msgSend [hWnd sel_getUid "setImage:" id] - ; objc_msgSend [id sel_getUid "release"] - ; ] - ; true [ - ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] - ; ] - ; ] - 0 + case [ + ; type = camera [ + ; snap-camera hWnd + ; until [TYPE_OF(image) = TYPE_IMAGE] ;-- wait + ; ] + any [type = button type = check type = radio][ + if TYPE_OF(image) = TYPE_IMAGE [ + img: gtk_image_new_from_pixbuf as handle! OS-image/to-pixbuf image + gtk_button_set_image hWnd img + ] + ] + ] ] change-color: func [ @@ -724,7 +722,7 @@ change-offset: func [ ;/local ;rc [NSRect!] ][ - print "change offset" + ;; print "change offset" ; rc: make-rect pos/x pos/y 0 0 ; either type = window [ ; rc/y: as float32! screen-size-y - pos/y @@ -1309,6 +1307,9 @@ OS-make-view: func [ sym = button [ widget: gtk_button_new_with_label caption gobj_signal_connect(widget "clicked" :button-clicked null) + if TYPE_OF(img) = TYPE_IMAGE [ + change-image widget img sym + ] ] sym = base [ widget: gtk_drawing_area_new @@ -1353,6 +1354,10 @@ OS-make-view: func [ ] sym = progress [ widget: gtk_progress_bar_new + if size/y > size/x [ + gtk_orientable_set_orientation widget 1 + gtk_progress_bar_set_inverted widget yes + ] fvalue: get-fraction-value as red-float! data gtk_progress_bar_set_fraction widget fvalue ] @@ -1640,8 +1645,31 @@ OS-to-image: func [ type [integer!] size [red-pair!] screen? [logic!] + ret [red-image!] ][ - as red-image! none-value + word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE + screen?: screen = symbol/resolve word/symbol + either screen? [ + ; get pixbuf from screen_root_window + bmp: as handle! 0;gdk_pixbuf_get_from_window gdk_screen_get_root_window gdk_screen_get_default 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp + ][ + ;view: as-integer face-handle? face + ;either zero? view [ret: as red-image! none-value][ + ; sz: as red-pair! (object/get-values face) + FACE_OBJ_SIZE + ; rc: make-rect 0 0 sz/x sz/y + ; data: objc_msgSend [view sel_getUid "dataWithPDFInsideRect:" rc/x rc/y rc/w rc/h] + ; img: objc_msgSend [ + ; objc_msgSend [objc_getClass "NSImage" sel_alloc] + ; sel_getUid "initWithData:" data + ; ] + bmp: as handle! 0; objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp + ; objc_msgSend [bmp sel_getUid "retain"] + ; objc_msgSend [img sel_release] + ;] + ] + ret ] OS-do-draw: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6d7a50c4ac..32b86f0c89 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -181,18 +181,24 @@ base-draw: func [ vals [red-value!] draw [red-block!] clr [red-tuple!] + img [red-image!] ][ vals: get-node-values ctx draw: as red-block! vals + FACE_OBJ_DRAW clr: as red-tuple! vals + FACE_OBJ_COLOR + img: as red-image! vals + FACE_OBJ_IMAGE if TYPE_OF(clr) = TYPE_TUPLE [ - 0 + ;0 ;print ["color" (clr/array1 and 00FFFFFFh) lf] set-source-color cr clr/array1 cairo_paint cr ;-- paint background ] + if TYPE_OF(img) = TYPE_IMAGE [ + GDK-draw-image cr OS-image/to-pixbuf img 0 0 + ] + render-text cr vals either TYPE_OF(draw) = TYPE_BLOCK [ diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 5375474732..cc2d8ca79f 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -717,7 +717,16 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] - Linux [] + Linux [ + button: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] + regular: [6x6 4x7] + small: [5x5 4x6] + mini: [1x1 0x1] + group-box: [3x3 0x4] + tab-panel: [7x7 6x10] + drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] + drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] + ] #default [] ]] extend system/view/metrics/paddings [#switch config/OS [ @@ -736,7 +745,14 @@ system/view/platform: context [ field: [3x3 0x0] group-box: [0x8 4x18] ] - Linux [] + Linux [ + button: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] + check: [20x0 3x1] + radio: [20x0 1x1] + text: [3x3 0x0] + field: [3x3 0x0] + group-box: [0x8 4x18] + ] #default [] ]] extend system/view/metrics/def-heights [#switch config/OS [ @@ -750,7 +766,15 @@ system/view/platform: context [ drop-list: 21 progress: 21 ] - Linux [] + Linux [ + check: 21 + radio: 21 + text: 18 + field: 21 + drop-down: 21 + drop-list: 21 + progress: 21 + ] #default [] ]] diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds new file mode 100644 index 0000000000..851c2529e1 --- /dev/null +++ b/runtime/platform/image-gdk.reds @@ -0,0 +1,643 @@ +Red/System [ + Title: "Image routine functions using gdk" + Author: "Qingtian Xie, RCqls" + File: %image-gdk.reds + Tabs: 4 + Rights: "Copyright (C) 2014 Qingtian Xie. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/dockimbel/Red/blob/master/BSL-License.txt + } +] + +#define IMG_NODE_HAS_BUFFER 1 +#define IMG_NODE_MODIFIED 2 + + +OS-image: context [ + + img-node!: alias struct! [ + flags [integer!] ;-- bit 0: if set, has buffer | bit 1: if set, buffer has been modified + handle [int-ptr!] + buffer [int-ptr!] + size [integer!] + ] + + #either OS = 'Windows [ + #define LIBGDK-file "libgtk-3-0.dll" ;or libgdk-3-0.dll + ][ + #define LIBGDK-file "libgtk-3.so.0" ;or libgdk-3.so.0 + ] + + #import [ + LIBGDK-file cdecl [ + gdk_pixbuf_new: "gdk_pixbuf_new" [ + colorsp [integer!] + alpha [logic!] + bits [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] + gdk_pixbuf_new_from_bytes: "gdk_pixbuf_new_from_bytes" [ + data [handle!] + colorsp [integer!] + alpha [logic!] + bits [integer!] + width [integer!] + height [integer!] + rowstride [integer!] + return: [handle!] + ] + gdk_pixbuf_new_from_file: "gdk_pixbuf_new_from_file" [ + name [c-string!] + err [handle!] + return: [handle!] + ] + gdk_pixbuf_copy: "gdk_pixbuf_copy" [ + pixbuf [handle!] + return: [handle!] + ] + gdk_pixbuf_get_byte_length: "gdk_pixbuf_get_byte_length" [ + pixbuf [handle!] + return: [integer!] + ] + gdk_pixbuf_get_width: "gdk_pixbuf_get_width" [ + pixbuf [handle!] + return: [integer!] + ] + gdk_pixbuf_get_height: "gdk_pixbuf_get_height" [ + pixbuf [handle!] + return: [integer!] + ] + gdk_pixbuf_get_pixels: "gdk_pixbuf_get_pixels" [ + pixbuf [handle!] + return: [byte-ptr!] + ] + gdk_pixbuf_get_rowstride: "gdk_pixbuf_get_rowstride" [ + pixbuf [handle!] + return: [integer!] + ] + gdk_pixbuf_get_n_channels: "gdk_pixbuf_get_n_channels" [ + pixbuf [handle!] + return: [integer!] + ] + gdk_pixbuf_get_has_alpha: "gdk_pixbuf_get_has_alpha" [ + pixbuf [handle!] + return: [logic!] + ] + gdk_pixbuf_loader_new: "gdk_pixbuf_loader_new" [ + return: [handle!] + ] + gdk_pixbuf_loader_get_pixbuf: "gdk_pixbuf_loader_get_pixbuf" [ + loader [handle!] + return: [handle!] + ] + gdk_pixbuf_loader_write: "gdk_pixbuf_loader_write" [ + loader [handle!] + data [handle!] + size [integer!] + err [handle!] + return: [logic!] + ] + gdk_pixbuf_loader_close: "gdk_pixbuf_loader_close" [ + loader [handle!] + err [handle!] + return: [logic!] + ] + g_object_unref: "g_object_unref" [ + obj [handle!] + ] + ] + ] + + width?: func [ + handle [node!] + return: [integer!] + /local + inode [img-node!] + ][ + inode: as img-node! (as series! handle/value) + 1 + IMAGE_WIDTH(inode/size) + ] + + height?: func [ + handle [node!] + return: [integer!] + /local + inode [img-node!] + ][ + inode: as img-node! (as series! handle/value) + 1 + IMAGE_HEIGHT(inode/size) + ] + + lock-bitmap: func [ ;-- do nothing on Quartz backend + img [red-image!] + write? [logic!] + return: [integer!] + /local + inode [img-node!] + ][ + inode: as img-node! (as series! img/node/value) + 1 + if zero? inode/flags [ + inode/flags: IMG_NODE_HAS_BUFFER + inode/buffer: OS-image/data-to-image inode/handle -1 yes yes + ] + if write? [inode/flags: inode/flags or IMG_NODE_MODIFIED] + as integer! inode + ] + + unlock-bitmap: func [ ;-- do nothing on Quartz backend + img [red-image!] + data [integer!] + ][] + + get-data: func [ + handle [integer!] + stride [int-ptr!] + return: [int-ptr!] + /local + node [img-node!] + ][ + node: as img-node! handle + stride/value: IMAGE_WIDTH(node/size) * 4 + node/buffer + ] + + get-pixel: func [ + bitmap [node!] + index [integer!] ;-- zero-based + return: [integer!] + /local + node [img-node!] + buf [int-ptr!] + ][ + node: as img-node! (as series! bitmap/value) + 1 + buf: node/buffer + index + buf/value + ] + + set-pixel: func [ + bitmap [node!] + index [integer!] ;-- zero-based + color [integer!] + return: [integer!] + /local + node [img-node!] + buf [int-ptr!] + ][ + node: as img-node! (as series! bitmap/value) + 1 + node/flags: node/flags or IMG_NODE_MODIFIED + buf: node/buffer + index + buf/value: color + color + ] + + delete: func [img [red-image!]][ + ; GdipDisposeImage as-integer img/node + 0 + ] + + ; copied from quartz but do not think it is finished + resize: func [ + img [red-image!] + width [integer!] + height [integer!] + return: [integer!] + /local + graphic [integer!] + old-w [integer!] + old-h [integer!] + format [integer!] + bitmap [integer!] + ][ + old-w: IMAGE_WIDTH(img/size) + old-h: IMAGE_HEIGHT(img/size) + + graphic: 0 + format: 0 + bitmap: 0 + as-integer img/node + ] + + ; UNUSED in Quartz ???? Maybe for a future use???? + copy: func [ + dst [integer!] + src [integer!] + bytes [integer!] + offset [integer!] + /local + dst-buf [byte-ptr!] + src-buf [byte-ptr!] + ][ + ; dst-buf: CGBitmapContextGetData dst + ; src-buf: CGBitmapContextGetData src + ; copy-memory dst-buf src-buf + offset bytes + ] + + make-node: func [ + handle [int-ptr!] + buffer [int-ptr!] + flags [integer!] + width [integer!] + height [integer!] + return: [node!] + /local + node [node!] + inode [img-node!] + ][ + node: alloc-cells 1 ;-- 16 bytes + inode: as img-node! (as series! node/value) + 1 + inode/flags: flags + inode/handle: handle + inode/buffer: buffer + inode/size: height << 16 or width + node + ] + + alpha-channel?: func [ + pixbuf [integer!] + return: [logic!] + ][ + gdk_pixbuf_get_has_alpha as handle! pixbuf + ] + + ; In particular used to query buffer from handle in lock-bitmap + data-to-image: func [ ;-- convert Pixbuf to OS handle or internal buffer + data [int-ptr!] + len [integer!] ; @@ added for data length + image? [logic!] + edit? [logic!] + return: [int-ptr!] + /local + ; color-space [integer!] ; Only RGB + width [integer!] + height [integer!] + ctx [integer!] + ;rect [NSRect!] + bytes-row [integer!] + image-data [integer!] + image [integer!] + n [integer!] + info [integer!] + alpha? [logic!] + buf [byte-ptr!] + data-pixbuf [int-ptr!] + end [int-ptr!] + pixel [integer!] + loader [handle!] + ][ + either image? [ + image: as-integer data + ][ + loader: gdk_pixbuf_loader_new + gdk_pixbuf_loader_write loader data len null + gdk_pixbuf_loader_close loader null + image: as-integer gdk_pixbuf_loader_get_pixbuf loader + ] + + unless edit? [return as int-ptr! image] + + alpha?: alpha-channel? image + ; color-space: ONLY RGB + width: gdk_pixbuf_get_width as handle! image + height: gdk_pixbuf_get_height as handle! image + + bytes-row: width * 4 + ; ??? either alpha? [ + ; info: 2101h ;-- kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents + ; n: 4 + ; ][ + ; info: 8198 ;-- kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little + ; n: 1 + ; ] + + ; maybe better use other copy + buf: gdk_pixbuf_get_pixels gdk_pixbuf_copy as handle! image + data-pixbuf: as int-ptr! buf + end: data-pixbuf + (width * height) + ;; print ["wxh: " width "x" height lf] + while [data-pixbuf < end][ + pixel: data-pixbuf/value + ; @@debug: print ["pixel:" pixel lf] + pixel: (pixel >> 8) or (255 - (pixel << 24)) ; RGBA -> ARGB + data-pixbuf/value: pixel + data-pixbuf: data-pixbuf + 1 + ] + as int-ptr! buf + ] + + load-binary: func [ + data [byte-ptr!] + len [integer!] + return: [node!] + /local + h [int-ptr!] + ][ + ;; print ["load-binary" lf] + + h: data-to-image as int-ptr! data len no no + make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h + ] + + load-pixbuf: func [ + h [int-ptr!] + return: [node!] + ][ + ;; print ["load-pixbuf" lf] + make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h + ;as node! 0 + ] + + load-image: func [ ;-- load image from external resource: file! + src [red-string!] + return: [node!] + /local + path [c-string!] + h [int-ptr!] + ][ + path: file/to-OS-path src + ;; print [ "load-image: " path lf] + h: gdk_pixbuf_new_from_file path null + ;; print ["handle: " h ", wxh: " gdk_pixbuf_get_width h "x" gdk_pixbuf_get_height h] + make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h + ] + + ; DO NOT KNOW IF USEFUL! + ; make-image: func [ + ; width [integer!] + ; height [integer!] + ; rgb [byte-ptr!] + ; alpha [byte-ptr!] + ; color [red-tuple!] + ; return: [int-ptr!] + ; /local + ; a [integer!] + ; r [integer!] + ; b [integer!] + ; g [integer!] + ; pixbuf [handle!] + ; pixels [byte-ptr!] + ; channel [integer!] + ; cpt [integer!] + ; end [integer!] + ; ][ + ; ;print-line "make-image" + ; if any [zero? width zero? height][return null] + ; pixbuf: gdk_pixbuf_new 0 yes 8 width height + ; if null? pixbuf [ + ; fire [TO_ERROR(script invalid-arg) pair/push width height] + ; ] + ; ;print-line "ici" + ; pixels: gdk_pixbuf_get_pixels pixbuf + ; channel: gdk_pixbuf_get_n_channels pixbuf ; = 4 + ; end: width * height + + ; ; @@ TO IMPROVE since I mimicked what was in gdiplus (integer!) but gdk is directly in byte! + ; either null? color [ + ; cpt: 0 + ; while [cpt < end][ + ; either null? alpha [a: 255][a: 255 - as-integer alpha/1 alpha: alpha + 1] + ; either null? rgb [r: 255 g: 255 b: 255][ + ; r: as-integer rgb/1 + ; g: as-integer rgb/2 + ; b: as-integer rgb/3 + ; rgb: rgb + 3 + ; ] + ; pixels/1: as byte! (r << 16) + ; pixels/2: as byte! (g << 8) + ; pixels/3: as byte! b + ; pixels/4: as byte! a << 24 + ; pixels: pixels + channel + ; cpt: cpt + 1 + ; ] + ; ][ + ; r: color/array1 + ; a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] + ; r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) + ; cpt: 0 + ; while [cpt < end][ + ; pixels/1: as byte! (r >> 16 and FFh) + ; pixels/2: as byte! (r and FF00h) + ; pixels/3: as byte! (r and FFh << 16) + ; pixels/4: as byte! (a << 24) + ; pixels: pixels + channel + ; cpt: cpt + 1 + ; ] + ; ] + ; pixbuf + ; ] + + make-image: func [ + width [integer!] + height [integer!] + rgb [byte-ptr!] + alpha [byte-ptr!] + color [red-tuple!] + return: [node!] + /local + a [integer!] + r [integer!] + b [integer!] + g [integer!] + x [integer!] + y [integer!] + scan0 [int-ptr!] + pos [integer!] + ][ + ;; print ["make-image" lf] + scan0: as int-ptr! allocate width * height * 4 + y: 0 + either null? color [ + while [y < height][ + x: 0 + while [x < width][ + pos: width * y + x + 1 + either null? alpha [a: 255][a: 255 - as-integer alpha/1 alpha: alpha + 1] + either null? rgb [r: 255 g: 255 b: 255][ + r: as-integer rgb/1 + g: as-integer rgb/2 + b: as-integer rgb/3 + rgb: rgb + 3 + ] + scan0/pos: r << 16 or (g << 8) or b or (a << 24) + x: x + 1 + ] + y: y + 1 + ] + ][ + r: color/array1 + a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] + r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) + while [y < height][ + x: 0 + while [x < width][ + pos: width * y + x + 1 + scan0/pos: r + x: x + 1 + ] + y: y + 1 + ] + ] + make-node null scan0 IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height + ] + + make-pixbuf: func [ + image [red-image!] + return: [int-ptr!] + /local + w [integer!] + h [integer!] + data [int-ptr!] + end [int-ptr!] + clr [integer!] + img [int-ptr!] + node [img-node!] + ][ + node: as img-node! (as series! image/node/value) + 1 + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + ;data: CGDataProviderCreateWithData null node/buffer w * h * 4 0 + ;clr: CGColorSpaceCreateDeviceRGB + ; need to change rgba en argb + img: gdk_pixbuf_new 0 yes 8 w h;CGImageCreate w h 8 32 w * 4 clr 2004h data null true 0 ;-- kCGRenderingIntentDefault + copy-memory as byte-ptr! gdk_pixbuf_get_pixels img as byte-ptr! node/buffer w * h * 4 + ;CGDataProviderRelease data + ;CGColorSpaceRelease clr + img + ] + + to-pixbuf: func [ + img [red-image!] + return: [integer!] + /local + inode [img-node!] + pixbuf [int-ptr!] + ][ + ;; print ["to-pixbuf" lf] + inode: as img-node! (as series! img/node/value) + 1 + if inode/flags and IMG_NODE_MODIFIED <> 0 [ + pixbuf: make-pixbuf img + unless null? inode/handle [g_object_unref inode/handle] + inode/handle: pixbuf + inode/flags: IMG_NODE_HAS_BUFFER + ] + as-integer inode/handle + ] + + ; ; used in OS-image/do-draw -> to adapt to gdk + ; to-bitmap-ctx: func [ + ; img [integer!] + ; return: [int-ptr!] + ; /local + ; color-space [integer!] + ; width [integer!] + ; height [integer!] + ; ;rect [NSRect!] + ; ctx [integer!] + ; ][ + ; ; color-space: CGColorSpaceCreateDeviceRGB + ; ; width: CGImageGetWidth as int-ptr! img + ; ; height: CGImageGetHeight as int-ptr! img + + ; ; rect: make-rect 0 0 width height + ; ; ctx: CGBitmapContextCreate null width height 32 width * 16 color-space 2101h + ; ; CGContextDrawImage ctx rect/x rect/y rect/w rect/h img + ; ; CGColorSpaceRelease color-space + ; as int-ptr! 0;ctx + ; ] + + ; ; used in OS-image/do-draw -> to adapt to gdk + ; ctx-to-image: func [ + ; img [red-image!] + ; ctx [integer!] + ; /local + ; ;data [float32-ptr!] + ; buf [int-ptr!] + ; inode [img-node!] + ; ][ + ; ; inode: as img-node! (as series! img/node/value) + 1 + ; ; CGImageRelease as-integer inode/handle + ; ; inode/handle: as int-ptr! CGBitmapContextCreateImage ctx + ; ; if inode/flags <> 0 [ + ; ; data: as float32-ptr! CGBitmapContextGetData ctx + ; ; unpremultiply-data inode/buffer data IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) + ; ; inode/flags: IMG_NODE_HAS_BUFFER + ; ; ] + ; ; CGContextRelease ctx + ; ] + + encode: func [ + image [red-image!] + slot [red-value!] + format [integer!] + return: [red-value!] + /local + type [integer!] + path [integer!] + dst [integer!] + img [integer!] + ][ + print ["encode" lf] + switch format [ + IMAGE_BMP [probe "type: kUTTypeBMP"] + IMAGE_PNG [probe "type: kUTTypePNG"] + IMAGE_GIF [probe "type: kUTTypeGIF"] + IMAGE_JPEG [probe "type: kUTTypeJPEG"] + IMAGE_TIFF [probe "type: kUTTypeTIFF"] + default [probe "Cannot find image encoder" return null] + ] + + img: to-pixbuf image + ; switch TYPE_OF(slot) [ + ; TYPE_URL + ; TYPE_FILE [ + ; path: simple-io/to-NSURL as red-string! slot yes + ; dst: CGImageDestinationCreateWithURL path type 1 0 + ; ;if zero? dst [] ;-- error + ; CGImageDestinationAddImage dst img 0 + ; unless CGImageDestinationFinalize dst [ + ; 0 ;-- error + ; ] + ; CFRelease path + ; CFRelease dst + ; ] + ; default [0] + ; ] + slot + ] + + clone: func [ + src [red-image!] + dst [red-image!] + part [integer!] + size [red-pair!] + part? [logic!] + return: [red-image!] + /local + x [integer!] + y [integer!] + w [integer!] + h [integer!] + offset [integer!] + handle [integer!] + width [integer!] + height [integer!] + bmp [integer!] + format [integer!] + ][ + width: IMAGE_WIDTH(src/size) + height: IMAGE_WIDTH(src/size) + offset: src/head + x: offset % width + y: offset / width + handle: as-integer src/node + bmp: 0 + + dst/header: TYPE_IMAGE + dst/head: 0 + dst/node: as node! bmp + dst + ] + +] \ No newline at end of file diff --git a/runtime/red.reds b/runtime/red.reds index 567ef473ed..3ddafd3fa0 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -51,6 +51,7 @@ red: context [ Windows [#include %platform/image-gdiplus.reds] Syllable [] macOS [#include %platform/image-quartz.reds] + Linux [#include %platform/image-gdk.reds] FreeBSD [] #default [] ] @@ -104,6 +105,7 @@ red: context [ #include %datatypes/date.reds #if OS = 'Windows [#include %datatypes/image.reds] ;-- temporary #if OS = 'macOS [#include %datatypes/image.reds] ;-- temporary + #if OS = 'Linux [#include %datatypes/image.reds] ;-- temporary ;-- Debugging helpers -- @@ -188,6 +190,7 @@ red: context [ date/init #if OS = 'Windows [image/init] ;-- temporary #if OS = 'macOS [image/init] ;-- temporary + #if OS = 'Linux [image/init] ;-- temporary actions/init @@ -260,6 +263,7 @@ red: context [ date/verbose: verbosity #if OS = 'Windows [image/verbose: verbosity] #if OS = 'macOS [image/verbose: verbosity] + #if OS = 'Linux [image/verbose: verbosity] actions/verbose: verbosity natives/verbose: verbosity diff --git a/tests/gtk3/react-test6-mini.red b/tests/gtk3/react-test6-mini.red new file mode 100644 index 0000000000..6458d437e2 --- /dev/null +++ b/tests/gtk3/react-test6-mini.red @@ -0,0 +1,16 @@ +Red [ + Title: "Red VID reactive test" + Author: "Nenad Rakocevic" + File: %react-test6.red + Needs: View +] + +system/view/debug?: no + +view [ + text "Font size" s: field "15" 80x10 + button "+" bold 40 + button "-" bold 40 + return +] + diff --git a/tests/gtk3/react-test6.red b/tests/gtk3/react-test6.red index ec013fb864..5ec24bc7a8 100644 --- a/tests/gtk3/react-test6.red +++ b/tests/gtk3/react-test6.red @@ -5,6 +5,8 @@ Red [ Needs: View ] +system/view/debug?: no + view [ style txt: text right txt "Text" f: area 200x80 @@ -20,9 +22,9 @@ view [ react [f/font/name: pick face/data any [face/selected 3] print ["changed:" mold face/text]] return - txt "Font size" s: field "15" react [f/font/size: s/data print ["text " face/text lf]] + txt "Font size" s: field "15" 80x10 react [f/font/size: s/data print ["text " face/text lf]] button "+" bold 40 [s/data: s/data + 1] - button "-" bold 40 [s/data: max 1 s/data - 1] + button "-" bold 40 [s/data: max 1 s/data - 1 s/size/x: s/size/x - 1 "s/size: " print s/size/x ] return ] diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red index 7065b656ee..3df21fc350 100644 --- a/tests/gtk3/vid.red +++ b/tests/gtk3/vid.red @@ -5,6 +5,8 @@ Red [ Needs: 'View ] system/view/debug?: no ;yes +system/view/gtk-auto-adjust?: yes + view [ title "VID test" ;below @@ -15,7 +17,7 @@ view [ button "China" text "Red Language" 100 right bold font [color: red] - field 120 on-enter [probe do face/text clear face/text] + field 120 on-enter [probe do face/text clear face/text print "ici"] on-key [print [event/type event/key event/shift? event/ctrl? lf] ] return group-box 3 [ @@ -23,8 +25,9 @@ view [ base 0.233.1.177 "ok" 25x25 text "in panel" + text "" - but "A" but "B" but "C" + but "A" but "B" but "C" but "D" but "E" but "F" ] tab-panel [ diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red index 8ec33b45f9..e51a39c78a 100644 --- a/tests/gtk3/view-test.red +++ b/tests/gtk3/view-test.red @@ -3,10 +3,9 @@ Red [ Needs: 'View ] -print "ici" - system/view/debug?: no live?: system/view/auto-sync?: no +system/view/gtk-auto-adjust?: yes workstation?: system/view/platform/product = 1 os-version: system/view/platform/version @@ -44,78 +43,78 @@ os-version: system/view/platform/version Linux [0] ] -; smiley: make image! [23x24 #{ -; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC -; CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 -; 444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 -; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 -; 8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C -; E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 -; 4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 -; DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F -; 949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -; ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 -; 736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 -; F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C -; F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 -; ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 -; E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 -; 171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 -; ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 -; 211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A -; E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 -; ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 -; CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC -; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -; ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE -; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 -; 3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -; FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 -; ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE -; F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 -; E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 -; 5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE -; F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 -; 514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 -; ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 -; 6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD -; 5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 -; 3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 -; F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -; FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 -; F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE -; F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 -; F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC -; A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 -; 8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC -; 736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E -; 56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -; F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 -; DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ -; FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -; 0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 -; 00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 -; 0000000000000000000000000000000000FFFFFFFF0000000000000000000000 -; 000000000000000000FFFF000000000000000000000000000000000000000000 -; FFFF000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 0000000000000000000000000000000000000000000000000000000000000000 -; 00000000000000FF000000000000000000000000000000000000000000FFFF00 -; 0000000000000000000000000000000000000000FFFFFF000000000000000000 -; 00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 -; FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 -; 000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 -; 00FFFFFFFFFFFFFF -; }] +smiley: make image! [23x24 #{ +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC +CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 +444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 +8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C +E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 +4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 +DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F +949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 +736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 +F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C +F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 +E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 +171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 +ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 +211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A +E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 +ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 +CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 +3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 +ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE +F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 +E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 +5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE +F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 +514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 +ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 +6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD +5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 +3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 +F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC +FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 +F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE +F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 +F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC +A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 +8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC +736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E +56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 +F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 +DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 +00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 +0000000000000000000000000000000000FFFFFFFF0000000000000000000000 +000000000000000000FFFF000000000000000000000000000000000000000000 +FFFF000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +00000000000000FF000000000000000000000000000000000000000000FFFF00 +0000000000000000000000000000000000000000FFFFFF000000000000000000 +00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 +FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 +000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 +00FFFFFFFFFFFFFF +}] sub-win: make face! [ type: 'window text: "Sub 1-View" offset: 200x200 size: 200x100 @@ -227,7 +226,7 @@ win: make face! [ canvas: make face! [ type: 'base offset: 0x0 size: 300x200 color: silver draw: [ - ;image smiley 10x30 + image smiley 10x30 line-cap round pen red @@ -618,7 +617,7 @@ win/pane: reduce [ make face! [ type: 'base offset: 280x10 size: 100x100 options: [drag-on: 'down] - image: load %../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png + image: load %../../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png ] tab-panel: make face! [ type: 'tab-panel offset: 10x320 size: 250x130 @@ -759,7 +758,7 @@ win/pane: reduce [ ] make face! [ type: 'button offset: 570x440 size: 38x38 - ;image: smiley + image: smiley ] make face! [ ;-- clip view for canvas type: 'panel offset: 10x460 size: 300x200 diff --git a/tests/gtk3/view-test2.red b/tests/gtk3/view-test2.red new file mode 100644 index 0000000000..8c5ac8fbfc --- /dev/null +++ b/tests/gtk3/view-test2.red @@ -0,0 +1,29 @@ +Red [ + Purpose: "Test GTK auto change size of widget" + Needs: 'View +] + +system/view/debug?: no + + + +win: make face! [ + type: 'window text: "Red View" size: 600x400 +] + +field: make face! [ + type: 'field + para: make para! [align: 'left] + text: "Font size" + offset: 10x10 size: 80x20 +] + +; but1: make face! [type: 'button text: "+" offset: 100x10 size: 40x20] + +; but2: make face! [type: 'button text: "-" offset: 150x10 size: 40x20] + +; win/pane: reduce [field but1 but2] +; view/flags win [resize] + +smiley: make image! 23x24 +image: load %../../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png From c4ce3ffd208c43a27bea2220067f073dba8ce5ae Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 15 Sep 2017 07:21:10 +0200 Subject: [PATCH 0072/3432] Ignore console --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..fc89f7bb7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +console From c2ae6f9f9a5054591844dec4cfebca7a2ac1033c Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 16 Sep 2017 12:31:29 +0200 Subject: [PATCH 0073/3432] Bad get-face-handle replaced by face-handle? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don’t know when I reintroduced this bug which breaks eve-clock.red demo and was supposed to work before… --- modules/view/backends/gtk3/gui.reds | 61 +++++++++++------------------ 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 1ea75b26d7..465456afea 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -133,24 +133,6 @@ face-handle?: func [ null ] -get-face-handle: func [ - face [red-object!] - return: [handle!] - /local - state [red-block!] - int [red-integer!] -][ - state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE - assert TYPE_OF(state) = TYPE_BLOCK - int: as red-integer! block/rs-head state - ;assert TYPE_OF(int) = TYPE_INTEGER - either TYPE_OF(int) = TYPE_INTEGER [ - as handle! int/value - ][ - null - ] -] - get-widget-symbol: func [ widget [handle!] return: [integer!] @@ -253,27 +235,27 @@ to-bgr: func [ free-handles: func [ hWnd [handle!] + values [red-value!] /local - values [red-value!] type [red-word!] rate [red-value!] state [red-value!] sym [integer!] ][ - values: get-face-values hWnd - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - - rate: values + FACE_OBJ_RATE - if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] - - g_object_set_qdata hWnd red-face-id null - g_object_set_qdata hWnd _widget-id null - g_object_set_qdata hWnd gtk-fixed-id null - g_object_set_qdata hWnd red-timer-id null - - ;gtk_widget_destroy manages eveything for free from the gtk side! - gtk_widget_destroy hWnd + ;type: as red-word! values + FACE_OBJ_TYPE + ;sym: symbol/resolve type/symbol + ;print ["destroying " get-symbol-name sym lf] + ;either null? hWnd [print ["null handle" lf]][ + rate: values + FACE_OBJ_RATE + if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] + g_object_set_qdata hWnd red-face-id null + g_object_set_qdata hWnd _widget-id null + g_object_set_qdata hWnd gtk-fixed-id null + g_object_set_qdata hWnd red-timer-id null + + ;gtk_widget_destroy manages eveything for free from the gtk side! + gtk_widget_destroy hWnd + ;] state: values + FACE_OBJ_STATE state/header: TYPE_NONE @@ -441,7 +423,7 @@ adjust-sizes: func [ debug [logic!] cpt [integer!] ][ - ; to remove when saitsfactory enough development + ; to remove when satisfactory enough development debug: no values: get-face-values hWnd @@ -456,14 +438,14 @@ adjust-sizes: func [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane if debug [print ["Parent type: " get-symbol-name sym lf]] - child: get-face-handle face + child: face-handle? face container: either null? child [null][g_object_get_qdata child gtk-fixed-id] dx: 0 dy: 0 ox: 0 oy: 0 sx: 0 sy: 0 cpt: 0 while [face < tail][ cpt: cpt + 1 - child: get-face-handle face + child: face-handle? face unless null? child [ values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET @@ -1583,8 +1565,9 @@ OS-destroy-view: func [ obj [red-object!] flags [integer!] ][ - handle: get-face-handle face + handle: face-handle? face values: object/get-values face + FACE_OBJ_STATE flags: get-flags as red-block! values + FACE_OBJ_FLAGS if flags and FACET_FLAGS_MODAL <> 0 [ 0 @@ -1592,10 +1575,10 @@ OS-destroy-view: func [ ;SetActiveWindow GetWindow handle GW_OWNER ] - ;print ["DDDEEEEestroy" lf] + ;; print ["DDDEEEEestroy" lf] - free-handles handle + free-handles handle values obj: as red-object! values + FACE_OBJ_FONT ;if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] From 076a7bbbabe8bdff85c50f49a2f5d106bb8a6165 Mon Sep 17 00:00:00 2001 From: R cqls Date: Tue, 19 Sep 2017 12:39:28 +0200 Subject: [PATCH 0074/3432] First step to drag and drop --- modules/view/backends/gtk3/gtk.reds | 113 ++++++++++++++++++ modules/view/backends/gtk3/gui.reds | 141 +++++++++++++++++++---- modules/view/backends/gtk3/handlers.reds | 88 ++++++++++++++ 3 files changed, 321 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index f0844c15d8..87743c2f58 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -56,6 +56,58 @@ GdkEventKey!: alias struct! [ group [byte!] is_modifier [integer!] ] +GdkEventMotion!: alias struct! [ + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + axes [float-ptr!] + state [integer!] + is_hint1 [byte!] + is_hint2 [byte!] + device [int-ptr!] + x_root [float!] + y_root [float!] +] + +GdkEventButton!: alias struct! [ + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + axes [float-ptr!] + state [integer!] + button [integer!] + device [int-ptr!] + x_root [float!] + y_root [float!] +] + +; @@ TO REMOVE IF UNUSED +; GdkEventCrossing!: alias struct! [ +; type [integer!] +; window [int-ptr!] +; send_event [byte!] +; subwindow [int-ptr!] +; time [integer!] +; x [float!] +; y [float!] +; x_root [float!] +; y_root [float!] +; axes [float-ptr!] +; state [integer!] +; is_hint1 [byte!] +; is_hint2 [byte!] +; device [int-ptr!] +; mode [integer!] +; detail [integer!] +; focus [logic!] +; state [integer!] +; ] #enum GdkModifierType! [ GDK_SHIFT_MASK: 1 @@ -63,6 +115,49 @@ GdkEventKey!: alias struct! [ GDK_CONTROL_MASK: 4 GDK_MOD1_MASK: 8 GDK_MOD5_MASK: 128 + GDK_BUTTON1_MASK: 256 + GDK_BUTTON2_MASK: 512 + GDK_BUTTON3_MASK: 1024 + GDK_BUTTON4_MASK: 2048 + GDK_BUTTON5_MASK: 4096 +] + +#enum GdkEventMask! [ + GDK_EXPOSURE_MASK: 2 + GDK_POINTER_MOTION_MASK: 4 + GDK_POINTER_MOTION_HINT_MASK: 8 + GDK_BUTTON_MOTION_MASK: 16 + GDK_BUTTON1_MOTION_MASK: 32 + GDK_BUTTON2_MOTION_MASK: 64 + GDK_BUTTON3_MOTION_MASK: 128 + GDK_BUTTON_PRESS_MASK: 256 + GDK_BUTTON_RELEASE_MASK: 512 + GDK_KEY_PRESS_MASK: 1024 + GDK_KEY_RELEASE_MASK: 2048 + GDK_ENTER_NOTIFY_MASK: 4096 + GDK_LEAVE_NOTIFY_MASK: 8192 + GDK_FOCUS_CHANGE_MASK: 16384 + GDK_STRUCTURE_MASK: 32768 + GDK_PROPERTY_CHANGE_MASK: 65536 + GDK_VISIBILITY_NOTIFY_MASK: 131072 + GDK_PROXIMITY_IN_MASK: 262144 + GDK_PROXIMITY_OUT_MASK: 524288 + GDK_SUBSTRUCTURE_MASK: 1048576 + GDK_SCROLL_MASK: 2097152 + GDK_TOUCH_MASK: 4194304 + GDK_SMOOTH_SCROLL_MASK: 8388608 + GDK_TOUCHPAD_GESTURE_MASK: 16777216 + GDK_TABLET_PAD_MASK: 33554432 + ;;GDK_ALL_EVENTS_MASK: fffffffeh +] + +#enum GdkDragAction! [ + GDK_ACTION_DEFAULT: 1 + GDK_ACTION_COPY: 2 + GDK_ACTION_MOVE: 4 + GDK_ACTION_LINK: 8 + GDK_ACTION_PRIVATE: 16 + GDK_ACTION_ASK: 32 ] GtkTextIter!: alias struct! [ @@ -254,6 +349,10 @@ cairo_font_extents_t!: alias struct! [ code [integer!] return: [integer!] ] + gdk_atom_intern_static_string: "gdk_atom_intern_static_string" [ + name [c-string!] + return: [handle!] + ] ;; ] ;; LIBGLIB-file cdecl [ g_quark_from_string: "g_quark_from_string" [ @@ -480,6 +579,10 @@ cairo_font_extents_t!: alias struct! [ text [c-string!] return: [handle!] ] + gtk_widget_add_events: "gtk_widget_add_events" [ + widget [handle!] + mask [integer!] + ] gtk_container_add: "gtk_container_add" [ container [handle!] widget [handle!] @@ -804,6 +907,16 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] return: [handle!] ] + gtk_drag_source_set: "gtk_drag_source_set" [ + widget [handle!] + start_mask [integer!] + targets [handle!] + n_targets [integer!] + actions [integer!] + ] + gtk_drag_source_add_image_targets: "gtk_drag_source_add_image_targets" [ + widget [handle!] + ] pango_layout_new: "pango_layout_new" [ context [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 465456afea..d60b39c04c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -38,10 +38,21 @@ tabs: context [ nb: 0 cur: 0 ] +; used to save old position of pointer in widget-motion-notify-event handler +motion: context [ + state: no + x_root: 0.0 + y_root: 0.0 + offset: as red-pair! 0 ;offset + cpt: 0 + sens: 3 +] pango-context: as handle! 0 gtk-font: "Sans 10" +; Do not KNOW about this one +main-window: as handle! 0 ; Temporary, will be removed... last-widget: as handle! 0 @@ -701,25 +712,18 @@ change-offset: func [ hWnd [handle!] pos [red-pair!] type [integer!] - ;/local - ;rc [NSRect!] + /local + container [handle!] ][ - ;; print "change offset" - ; rc: make-rect pos/x pos/y 0 0 - ; either type = window [ + either type = window [ ; rc/y: as float32! screen-size-y - pos/y ; objc_msgSend [hWnd sel_getUid "setFrameTopLeftPoint:" rc/x rc/y] - ; ][ - ; objc_msgSend [hWnd sel_getUid "setFrameOrigin:" rc/x rc/y] - ; unless in-composition? [ - ; object_getInstanceVariable hWnd IVAR_RED_DATA :type - ; if type = caret [ - ; caret-x: rc/x - ; caret-y: rc/y - ; ] - ; ] - ; ] - 0 + 0 + ][ + ;OS-refresh-window as integer! main-window + container: either null? hWnd [null][g_object_get_qdata hWnd gtk-fixed-id] + unless null? container [gtk_fixed_move container hWnd pos/x pos/y] + ] ] change-visible: func [ @@ -1176,12 +1180,105 @@ update-scroller: func [ ;] ] + +parse-common-opts: func [ + hWnd [handle!] + face [red-object!] + options [red-block!] + type [integer!] + /local + word [red-word!] + w [red-word!] + img [red-image!] + bool [red-logic!] + len [integer!] + sym [integer!] + cur [c-string!] + hcur [integer!] + nsimg [integer!] + btn? [logic!] +][ + btn?: yes + if TYPE_OF(options) = TYPE_BLOCK [ + word: as red-word! block/rs-head options + len: block/rs-length? options + if len % 2 <> 0 [exit] + while [len > 0][ + sym: symbol/resolve word/symbol + case [ + sym = (symbol/make "drag-on") [ + ;gtk_drag_source_set hWnd GDK_BUTTON1_MASK null 0 GDK_ACTION_MOVE + ;gtk_drag_source_add_image_targets hWnd + gtk_widget_add_events hWnd GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK + gobj_signal_connect(hWnd "motion-notify-event" :widget-motion-notify-event face/ctx) + gobj_signal_connect(hWnd "button-press-event" :widget-button-press-event face/ctx) + gobj_signal_connect(hWnd "button-release-event" :widget-button-release-event face/ctx) + ] + ; sym = _cursor [ + ; w: word + 1 + ; either TYPE_OF(w) = TYPE_IMAGE [ + ; img: as red-image! w + ; nsimg: objc_msgSend [ + ; OBJC_ALLOC("NSImage") + ; sel_getUid "initWithCGImage:size:" OS-image/to-cgimage img 0 0 + ; ] + ; pt/x: as float32! IMAGE_WIDTH(img/size) / 2 + ; pt/y: as float32! IMAGE_HEIGHT(img/size) / 2 + ; hcur: objc_msgSend [ + ; OBJC_ALLOC("NSCursor") + ; sel_getUid "initWithImage:hotSpot:" nsimg pt/x pt/y + ; ] + ; objc_msgSend [nsimg sel_release] + ; ][ + ; sym: symbol/resolve w/symbol + ; cur: case [ + ; sym = _I-beam ["IBeamCursor"] + ; sym = _hand ["pointingHandCursor"] + ; sym = _cross ["crosshairCursor"] + ; true ["arrowCursor"] + ; ] + ; hcur: objc_msgSend [objc_getClass "NSCursor" sel_getUid cur] + ; ] + ; if hcur <> 0 [objc_setAssociatedObject hWnd RedCursorKey hcur OBJC_ASSOCIATION_ASSIGN] + ; ] + ; sym = _class [ + ; w: word + 1 + ; sym: symbol/resolve w/symbol + ; sym: case [ + ; sym = _regular [0] ;-- 32 + ; sym = _small [1] ;-- 28 + ; sym = _mini [2] ;-- 16 + ; true [0] + ; ] + ; objc_msgSend [ + ; objc_msgSend [hWnd sel_getUid "cell"] + ; sel_getUid "setControlSize:" sym + ; ] + ; btn?: no + ; ] + ; sym = _accelerated [ + ; bool: as red-logic! word + 1 + ; if bool/value [objc_msgSend [hWnd sel_getUid "setWantsLayer:" yes]] + ; ] + true [0] + ] + word: word + 2 + len: len - 2 + ] + ] + + ; if type = button [ + ; len: either btn? [NSRegularSquareBezelStyle][NSRoundedBezelStyle] + ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" len] + ; ] +] + OS-redraw: func [hWnd [integer!]][gtk_widget_queue_draw as handle! hWnd] OS-refresh-window: func [hWnd [integer!]][ ;print-line "REFFRREEEESSSSHHHHH" - ;debug-show-children last-widget no - ;gtk_widget_queue_draw as handle! hWnd + ;debug-show-children main-window no + ;gtk_widget_queue_draw main-window OS-show-window hWnd ] @@ -1300,7 +1397,7 @@ OS-make-view: func [ sym = window [ widget: gtk_application_window_new GTKApp ; @@ DEBUG: temporary code - last-widget: widget + main-window: widget unless null? caption [gtk_window_set_title widget caption] gtk_window_set_default_size widget size/x size/y gtk_container_add widget gtk_fixed_new @@ -1394,6 +1491,9 @@ OS-make-view: func [ ] ] + parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym + + ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] @@ -1576,8 +1676,7 @@ OS-destroy-view: func [ ] ;; print ["DDDEEEEestroy" lf] - - + free-handles handle values obj: as red-object! values + FACE_OBJ_FONT diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 32b86f0c89..c1acc3e8b9 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -32,6 +32,23 @@ set-selected: func [ int/value: idx ] +set-offset: func [ + obj [handle!] + ctx [node!] + x [integer!] + y [integer!] + return: [red-pair!] + /local + offset [red-pair!] + face [red-object!] +][ + offset: as red-pair! get-node-facet ctx FACE_OBJ_OFFSET + offset/header: TYPE_PAIR + offset/x: x + offset/y: y + offset +] + set-text: func [ obj [handle!] ctx [node!] @@ -406,4 +423,75 @@ red-timer-action: func [ ][ make-event self 0 EVT_TIME yes +] + +widget-motion-notify-event: func [ + [cdecl] + widget [handle!] + event [GdkEventMotion!] + ctx [node!] + return: [logic!] + /local + offset [red-pair!] + x [float!] + y [float!] +][ + ;print [ "MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + either motion/state [ + if 0 = (motion/cpt % motion/sens) [ + ;print [ "MOTION: " motion/offset/x "x" motion/offset/y ", (" motion/x_root "," motion/y_root "), x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + x: (as float! motion/offset/x) + event/x_root - motion/x_root + y: (as float! motion/offset/y) + event/y_root - motion/y_root + ;print [ x "," y lf] + offset: set-offset widget ctx as integer! x as integer! y + ;motion/x: event/x + ;motion/y: event/y + change-offset widget offset 0 ; the last 2 info are unused + ] + motion/cpt: motion/cpt + 1 + yes + ][no] +] + +widget-button-press-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [logic!] + /local + offset [red-pair!] +][ + ; print [ "BUTTON-PRESS: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + motion/state: yes + motion/cpt: 0 + motion/x_root: event/x_root + motion/y_root: event/y_root + offset: as red-pair! get-node-facet ctx FACE_OBJ_OFFSET + ; copy of current offset when button pressed + motion/offset: pair/push offset/x offset/y + yes ] + +widget-button-release-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [logic!] +][ + ; print [ "BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + motion/state: no + yes +] + +;; TO REMOVE! +; widget-enter-notify-event: func [ +; [cdecl] +; widget [handle!] +; event [GdkEventCrossing!] +; ctx [node!] +; ][ +; print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] +; motion/state: yes +; ] From e34dcff6e88bd5acd1a82b60f20808315ad6ef1a Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 20 Sep 2017 04:40:32 +0200 Subject: [PATCH 0075/3432] Drag and drop almost done --- modules/view/backends/gtk3/draw.reds | 2 +- modules/view/backends/gtk3/events.reds | 3 +++ modules/view/backends/gtk3/gui.reds | 14 +++++++------ modules/view/backends/gtk3/handlers.reds | 26 ++++++++++++++++-------- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 7b34262595..58db571867 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -673,7 +673,7 @@ OS-draw-image: func [ ww [float!] crop2 [red-pair!] ][ - print ["OS-draw-image" lf] + ;; print ["OS-draw-image" lf] either null? start [x: 0 y: 0][x: start/x y: start/y] case [ start = end [ diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 030ab30f34..803552e34e 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -80,6 +80,9 @@ get-event-offset: func [ ][ offset: as red-pair! stack/push* offset/header: TYPE_PAIR + offset/x: motion/x_new + offset/y: motion/y_new + ;;print ["event-offset: " offset/x "x" offset/y lf] as red-value! offset ] any [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index d60b39c04c..489dd14954 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -40,12 +40,14 @@ tabs: context [ ] ; used to save old position of pointer in widget-motion-notify-event handler motion: context [ - state: no - x_root: 0.0 - y_root: 0.0 - offset: as red-pair! 0 ;offset - cpt: 0 - sens: 3 + state: no + x_root: 0.0 + y_root: 0.0 + offset_old: as red-pair! 0 ;offset + x_new: 0 + y_new: 0 + cpt: 0 + sens: 3 ] pango-context: as handle! 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c1acc3e8b9..570d06f825 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -435,18 +435,24 @@ widget-motion-notify-event: func [ offset [red-pair!] x [float!] y [float!] + ; state [red-block!] + ; int [red-integer!] + ; s [series!] + ][ ;print [ "MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] either motion/state [ if 0 = (motion/cpt % motion/sens) [ ;print [ "MOTION: " motion/offset/x "x" motion/offset/y ", (" motion/x_root "," motion/y_root "), x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - x: (as float! motion/offset/x) + event/x_root - motion/x_root - y: (as float! motion/offset/y) + event/y_root - motion/y_root - ;print [ x "," y lf] - offset: set-offset widget ctx as integer! x as integer! y - ;motion/x: event/x - ;motion/y: event/y - change-offset widget offset 0 ; the last 2 info are unused + ; x: (as float! motion/offset_old/x) + event/x_root - motion/x_root + ; y: (as float! motion/offset_old/y) + event/y_root - motion/y_root + x: event/x_root - motion/x_root + y: event/y_root - motion/y_root + motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] + motion/y_new: as-integer y + either y > 0.0 [0.5][-0.5] + motion/x_root: event/x_root + motion/y_root: event/y_root + make-event widget 0 EVT_OVER ] motion/cpt: motion/cpt + 1 yes @@ -469,7 +475,10 @@ widget-button-press-event: func [ motion/y_root: event/y_root offset: as red-pair! get-node-facet ctx FACE_OBJ_OFFSET ; copy of current offset when button pressed - motion/offset: pair/push offset/x offset/y + motion/offset_old: pair/push offset/x offset/y + motion/x_new: 0 + motion/y_new: 0 + make-event widget 0 EVT_LEFT_DOWN yes ] @@ -482,6 +491,7 @@ widget-button-release-event: func [ ][ ; print [ "BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] motion/state: no + make-event widget 0 EVT_LEFT_UP yes ] From 58723f514144c41068b6ab52bb810ae94029ec4e Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 20 Sep 2017 08:19:37 +0200 Subject: [PATCH 0076/3432] Clean unused code in drag and drop --- modules/view/backends/gtk3/gtk.reds | 19 ------------------ modules/view/backends/gtk3/gui.reds | 5 +---- modules/view/backends/gtk3/handlers.reds | 25 +----------------------- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 87743c2f58..ad14ee8657 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -151,15 +151,6 @@ GdkEventButton!: alias struct! [ ;;GDK_ALL_EVENTS_MASK: fffffffeh ] -#enum GdkDragAction! [ - GDK_ACTION_DEFAULT: 1 - GDK_ACTION_COPY: 2 - GDK_ACTION_MOVE: 4 - GDK_ACTION_LINK: 8 - GDK_ACTION_PRIVATE: 16 - GDK_ACTION_ASK: 32 -] - GtkTextIter!: alias struct! [ dummy1 [handle!] dummy2 [handle!] @@ -907,16 +898,6 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] return: [handle!] ] - gtk_drag_source_set: "gtk_drag_source_set" [ - widget [handle!] - start_mask [integer!] - targets [handle!] - n_targets [integer!] - actions [integer!] - ] - gtk_drag_source_add_image_targets: "gtk_drag_source_add_image_targets" [ - widget [handle!] - ] pango_layout_new: "pango_layout_new" [ context [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 489dd14954..45bcbfa06d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -43,11 +43,10 @@ motion: context [ state: no x_root: 0.0 y_root: 0.0 - offset_old: as red-pair! 0 ;offset x_new: 0 y_new: 0 cpt: 0 - sens: 3 + sensitiv: 3 ] pango-context: as handle! 0 @@ -1209,8 +1208,6 @@ parse-common-opts: func [ sym: symbol/resolve word/symbol case [ sym = (symbol/make "drag-on") [ - ;gtk_drag_source_set hWnd GDK_BUTTON1_MASK null 0 GDK_ACTION_MOVE - ;gtk_drag_source_add_image_targets hWnd gtk_widget_add_events hWnd GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK gobj_signal_connect(hWnd "motion-notify-event" :widget-motion-notify-event face/ctx) gobj_signal_connect(hWnd "button-press-event" :widget-button-press-event face/ctx) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 570d06f825..23bd726957 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -32,23 +32,6 @@ set-selected: func [ int/value: idx ] -set-offset: func [ - obj [handle!] - ctx [node!] - x [integer!] - y [integer!] - return: [red-pair!] - /local - offset [red-pair!] - face [red-object!] -][ - offset: as red-pair! get-node-facet ctx FACE_OBJ_OFFSET - offset/header: TYPE_PAIR - offset/x: x - offset/y: y - offset -] - set-text: func [ obj [handle!] ctx [node!] @@ -442,10 +425,7 @@ widget-motion-notify-event: func [ ][ ;print [ "MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] either motion/state [ - if 0 = (motion/cpt % motion/sens) [ - ;print [ "MOTION: " motion/offset/x "x" motion/offset/y ", (" motion/x_root "," motion/y_root "), x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - ; x: (as float! motion/offset_old/x) + event/x_root - motion/x_root - ; y: (as float! motion/offset_old/y) + event/y_root - motion/y_root + if 0 = (motion/cpt % motion/sensitiv) [ x: event/x_root - motion/x_root y: event/y_root - motion/y_root motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] @@ -473,9 +453,6 @@ widget-button-press-event: func [ motion/cpt: 0 motion/x_root: event/x_root motion/y_root: event/y_root - offset: as red-pair! get-node-facet ctx FACE_OBJ_OFFSET - ; copy of current offset when button pressed - motion/offset_old: pair/push offset/x offset/y motion/x_new: 0 motion/y_new: 0 make-event widget 0 EVT_LEFT_DOWN From 5fa027dfd25ec4f999d369d2b35997d3a9bf8e56 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 20 Sep 2017 09:46:20 +0200 Subject: [PATCH 0077/3432] Visible? And enabled? started --- modules/view/backends/gtk3/gtk.reds | 11 +++ modules/view/backends/gtk3/gui.reds | 101 ++++++++++++---------------- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index ad14ee8657..89fb0a0db2 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -528,6 +528,17 @@ cairo_font_extents_t!: alias struct! [ gtk_widget_hide: "gtk_widget_hide" [ widget [handle!] ] + gtk_widget_show: "gtk_widget_show" [ + widget [handle!] + ] + gtk_widget_set_visible: "gtk_widget_set_visible" [ + widget [handle!] + state [logic!] + ] + gtk_widget_set_sensitive: "gtk_widget_set_sensitive" [ + widget [handle!] + state [logic!] + ] gtk_widget_grab_focus: "gtk_widget_grab_focus" [ widget [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 45bcbfa06d..9cbacc5992 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -648,7 +648,7 @@ change-color: func [ ] update-z-order: func [ - parent [integer!] + parent [handle!] pane [red-block!] type [integer!] /local @@ -660,23 +660,23 @@ update-z-order: func [ nb [integer!] s [series!] ][ - ; s: GET_BUFFER(pane) - ; face: as red-object! s/offset + pane/head - ; tail: as red-object! s/tail - ; nb: (as-integer tail - face) >> 4 - - ; parr: as int-ptr! allocate nb * 4 - ; nb: 0 - ; while [face < tail][ - ; if TYPE_OF(face) = TYPE_OBJECT [ - ; hWnd: face-handle? face - ; if hWnd <> null [ - ; nb: nb + 1 - ; parr/nb: as-integer hWnd - ; ] - ; ] - ; face: face + 1 - ; ] + s: GET_BUFFER(pane) + face: as red-object! s/offset + pane/head + tail: as red-object! s/tail + nb: (as-integer tail - face) >> 4 + + parr: as int-ptr! allocate nb * 4 + nb: 0 + while [face < tail][ + if TYPE_OF(face) = TYPE_OBJECT [ + hWnd: face-handle? face + if hWnd <> null [ + nb: nb + 1 + parr/nb: as-integer hWnd + ] + ] + face: face + 1 + ] ; arr: objc_msgSend [ ; objc_getClass "NSArray" ; sel_getUid "arrayWithObjects:count:" @@ -728,40 +728,31 @@ change-offset: func [ ] change-visible: func [ - hWnd [integer!] + hWnd [handle!] show? [logic!] type [integer!] ][ - ; case [ - ; any [type = button type = check type = radio][ - ; objc_msgSend [hWnd sel_getUid "setEnabled:" show?] - ; objc_msgSend [hWnd sel_getUid "setTransparent:" not show?] - ; ] - ; type = window [ - ; either show? [ - ; objc_msgSend [hWnd sel_getUid "makeKeyAndOrderFront:" hWnd] - ; ][ - ; objc_msgSend [hWnd sel_getUid "orderOut:" hWnd] - ; ] - ; ] - ; true [objc_msgSend [hWnd sel_getUid "setHidden:" not show?]] - ; ] - 0 + case [ + type = window [ + ; either show? [ + ; objc_msgSend [hWnd sel_getUid "makeKeyAndOrderFront:" hWnd] + ; ][ + ; objc_msgSend [hWnd sel_getUid "orderOut:" hWnd] + ; ] + 0 + ] + true [gtk_widget_set_visible hWnd show?] + ] ] change-enabled: func [ - hWnd [integer!] + hWnd [handle!] enabled? [logic!] type [integer!] /local obj [integer!] ][ - ; unless any [type = base type = window type = panel][ - ; objc_msgSend [hWnd sel_getUid "setEnabled:" enabled?] - ; ] - ; either enabled? [obj: 0][obj: hWnd] - ; objc_setAssociatedObject hWnd RedEnableKey obj OBJC_ASSOCIATION_ASSIGN -0 + gtk_widget_set_sensitive hWnd enabled? ] change-text: func [ @@ -1543,8 +1534,8 @@ OS-make-view: func [ ; change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym ; change-para widget face as red-object! values + FACE_OBJ_PARA font sym - ; unless show?/value [change-visible widget no sym] - ; unless open?/value [change-enabled widget no sym] + unless show?/value [change-visible widget no sym] + unless open?/value [change-enabled widget no sym] ; change-font widget face font sym if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] @@ -1597,13 +1588,14 @@ OS-update-view: func [ if flags and FACET_FLAG_DATA <> 0 [ change-data widget values ] - ;if flags and FACET_FLAG_ENABLE? <> 0 [ - ; change-enabled widget values - ;] - ;if flags and FACET_FLAG_VISIBLE? <> 0 [ - ; bool: as red-logic! values + FACE_OBJ_VISIBLE? - ; change-visible widget bool/value type - ;] + if flags and FACET_FLAG_ENABLED? <> 0 [ + bool: as red-logic! values + FACE_OBJ_ENABLED? + change-enabled widget bool/value type + ] + if flags and FACET_FLAG_VISIBLE? <> 0 [ + bool: as red-logic! values + FACE_OBJ_VISIBLE? + change-visible widget bool/value type + ] ;if flags and FACET_FLAG_SELECTED <> 0 [ ; int2: as red-integer! values + FACE_OBJ_SELECTED ; change-selection widget int2 values @@ -1625,14 +1617,9 @@ OS-update-view: func [ ; InvalidateRect widget null 1 ] ] - if flags and FACET_FLAG_PANE <> 0 [ + if all [flags and FACET_FLAG_PANE <> 0 type <> tab-panel][ + ;update-z-order hWnd as red-block! values + FACE_OBJ_PANE type 0 - ;print [ "flag-pane" get-symbol-name type lf] - ; if tab-panel <> type [ ;-- tab-panel/pane has custom z-order handling - ; update-z-order - ; as red-block! values + gui/FACE_OBJ_PANE - ; null - ; ] ] if flags and FACET_FLAG_FONT <> 0 [ change-font widget face as red-object! values + FACE_OBJ_FONT type From a1111bf74d5b77711a187e3fedcccd4709e142d0 Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 20 Sep 2017 21:50:43 +0200 Subject: [PATCH 0078/3432] On-over actor added --- modules/view/backends/gtk3/gtk.reds | 44 +++++++++++++----------- modules/view/backends/gtk3/gui.reds | 35 +++++++++++++++++-- modules/view/backends/gtk3/handlers.reds | 35 +++++++++++++------ 3 files changed, 80 insertions(+), 34 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 89fb0a0db2..104456d4e9 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -87,27 +87,26 @@ GdkEventButton!: alias struct! [ y_root [float!] ] -; @@ TO REMOVE IF UNUSED -; GdkEventCrossing!: alias struct! [ -; type [integer!] -; window [int-ptr!] -; send_event [byte!] -; subwindow [int-ptr!] -; time [integer!] -; x [float!] -; y [float!] -; x_root [float!] -; y_root [float!] -; axes [float-ptr!] -; state [integer!] -; is_hint1 [byte!] -; is_hint2 [byte!] -; device [int-ptr!] -; mode [integer!] -; detail [integer!] -; focus [logic!] -; state [integer!] -; ] +GdkEventCrossing!: alias struct! [ + type [integer!] + window [int-ptr!] + send_event [byte!] + subwindow [int-ptr!] + time [integer!] + x [float!] + y [float!] + x_root [float!] + y_root [float!] + axes [float-ptr!] + state [integer!] + is_hint1 [byte!] + is_hint2 [byte!] + device [int-ptr!] + mode [integer!] + detail [integer!] + focus [logic!] + state [integer!] +] #enum GdkModifierType! [ GDK_SHIFT_MASK: 1 @@ -735,6 +734,9 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] label [c-string!] ] + gtk_event_box_new: "gtk_event_box_new" [ + return: [handle!] + ] gtk_entry_new: "gtk_entry_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 9cbacc5992..5bc6a95f6a 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -48,6 +48,9 @@ motion: context [ cpt: 0 sensitiv: 3 ] +; to put in other place (usually platform.red) if useful +_drag-on: symbol/make "drag-on" +_on-over: word/load "on-over" pango-context: as handle! 0 gtk-font: "Sans 10" @@ -1172,6 +1175,30 @@ update-scroller: func [ ;] ] +connect-mouse-events: function [ + hWnd [handle!] + face [red-object!] + actors [red-object!] + type [integer!] + /local + widget [handle!] +][ + if all [ + not null? actors/ctx + (object/rs-find actors as red-value! _on-over) <> -1 + ][ + widget: either type = text [ + g_object_get_qdata hWnd _widget-id + ][hWnd] + + ;print [ "Mouse events " get-symbol-name type "->" widget lf] + gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK + gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) + gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) + ] +] + + parse-common-opts: func [ hWnd [handle!] @@ -1198,7 +1225,7 @@ parse-common-opts: func [ while [len > 0][ sym: symbol/resolve word/symbol case [ - sym = (symbol/make "drag-on") [ + sym = _drag-on [ gtk_widget_add_events hWnd GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK gobj_signal_connect(hWnd "motion-notify-event" :widget-motion-notify-event face/ctx) gobj_signal_connect(hWnd "button-press-event" :widget-button-press-event face/ctx) @@ -1408,6 +1435,8 @@ OS-make-view: func [ ] sym = text [ widget: gtk_label_new caption + _widget: gtk_event_box_new null null + gtk_container_add _widget widget ] sym = field [ widget: gtk_entry_new @@ -1483,7 +1512,6 @@ OS-make-view: func [ parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym - ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] @@ -1527,9 +1555,12 @@ OS-make-view: func [ ] ] + connect-mouse-events widget face as red-object! values + FACE_OBJ_ACTORS sym + ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events store-face-to-obj widget face + if sym = text [store-face-to-obj _widget face] ; change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym ; change-para widget face as red-object! values + FACE_OBJ_PARA font sym diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 23bd726957..f16af8352a 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -408,6 +408,30 @@ red-timer-action: func [ yes ] +widget-enter-notify-event: func [ + [cdecl] + widget [handle!] + event [GdkEventCrossing!] + ctx [node!] + return: [logic!] +][ + ;print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + make-event widget 0 EVT_OVER + no +] + +widget-leave-notify-event: func [ + [cdecl] + widget [handle!] + event [GdkEventCrossing!] + ctx [node!] + return: [logic!] +][ + ;print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + make-event widget EVT_FLAG_AWAY EVT_OVER + no +] + widget-motion-notify-event: func [ [cdecl] widget [handle!] @@ -471,14 +495,3 @@ widget-button-release-event: func [ make-event widget 0 EVT_LEFT_UP yes ] - -;; TO REMOVE! -; widget-enter-notify-event: func [ -; [cdecl] -; widget [handle!] -; event [GdkEventCrossing!] -; ctx [node!] -; ][ -; print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] -; motion/state: yes -; ] From d6a6dd71cd2c50c62154f78b9d24fbfbd90ef350 Mon Sep 17 00:00:00 2001 From: qtxie Date: Tue, 17 Apr 2018 09:46:12 +0800 Subject: [PATCH 0079/3432] FIX: fix some compiling errors. --- modules/view/VID.red | 4 ++-- modules/view/backends/gtk3/draw.reds | 2 ++ modules/view/backends/gtk3/gui.reds | 16 +++++++--------- modules/view/backends/gtk3/text-box.reds | 1 + runtime/platform/image-gdk.reds | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index da2ed15ec1..93850b6c59 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -22,8 +22,7 @@ system/view/VID: context [ #switch config/OS [ Windows [#include %backends/windows/rules.red] macOS [#include %backends/macOS/rules.red] - Linux [] - #default [] + Linux [] ] ] @@ -39,6 +38,7 @@ system/view/VID: context [ capitalize Cancel-OK ] + Linux [] ] user: [] diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 58db571867..cdf0303857 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -12,6 +12,8 @@ Red/System [ #include %text-box.reds +draw-state!: alias struct! [unused [integer!]] + set-source-color: func [ cr [handle!] color [integer!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5bc6a95f6a..b5b021a2af 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1308,11 +1308,11 @@ OS-show-window: func [ gtk_widget_grab_focus as handle! hWnd ; @@ TEMPORARY: TO BE REMOVED BUT USEFUL NOW FOR COMPARING THE EFFECT OF ADJUST-SIZES IN RED TEST WITHOUT RECOMPILING CONSOLE - auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? - if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ - adjust-sizes as handle! hWnd - gtk_widget_queue_draw as handle! hWnd - ] + ;auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? + ;if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ + ; adjust-sizes as handle! hWnd + ; gtk_widget_queue_draw as handle! hWnd + ;] ] OS-make-view: func [ @@ -1350,13 +1350,12 @@ OS-make-view: func [ fvalue [float!] vertical? [logic!] rfvalue [red-float!] - rect [RECT_STRUCT] ][ - stack/mark-func words/_body + stack/mark-native words/_body values: object/get-values face - _widget: as handle! 0; widget version with possible scrollview + _widget: as handle! 0 ; widget version with possible scrollview type: as red-word! values + FACE_OBJ_TYPE str: as red-string! values + FACE_OBJ_TEXT @@ -1734,7 +1733,6 @@ OS-to-image: func [ hWnd [handle!] dc [handle!] mdc [handle!] - rect [RECT_STRUCT] width [integer!] height [integer!] bmp [handle!] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index da4d07db96..5bb5ea2d14 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -183,6 +183,7 @@ OS-text-box-metrics: func [ OS-text-box-layout: func [ box [red-object!] target [int-ptr!] + ft-clr [integer!] catch? [logic!] return: [integer!] ][ diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 851c2529e1..5f56ac5332 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -501,7 +501,7 @@ OS-image: context [ ;clr: CGColorSpaceCreateDeviceRGB ; need to change rgba en argb img: gdk_pixbuf_new 0 yes 8 w h;CGImageCreate w h 8 32 w * 4 clr 2004h data null true 0 ;-- kCGRenderingIntentDefault - copy-memory as byte-ptr! gdk_pixbuf_get_pixels img as byte-ptr! node/buffer w * h * 4 + copy-memory gdk_pixbuf_get_pixels img as byte-ptr! node/buffer w * h * 4 ;CGDataProviderRelease data ;CGColorSpaceRelease clr img From c446f71e989b45cc7bd42d347c130732083720dc Mon Sep 17 00:00:00 2001 From: qtxie Date: Tue, 17 Apr 2018 18:04:10 +0800 Subject: [PATCH 0080/3432] FEAT: adds border to text-list by default on Linux. --- modules/view/backends/gtk3/gtk.reds | 8 ++++++++ modules/view/backends/gtk3/gui.reds | 17 ++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 104456d4e9..e85294d62c 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -530,6 +530,10 @@ cairo_font_extents_t!: alias struct! [ gtk_widget_show: "gtk_widget_show" [ widget [handle!] ] + gtk_widget_set_halign: "gtk_widget_set_halign" [ + widget [handle!] + type [integer!] + ] gtk_widget_set_visible: "gtk_widget_set_visible" [ widget [handle!] state [logic!] @@ -669,6 +673,10 @@ cairo_font_extents_t!: alias struct! [ vadj [handle!] return: [handle!] ] + gtk_scrolled_window_set_shadow_type: "gtk_scrolled_window_set_shadow_type" [ + hwnd [handle!] + type [integer!] + ] gtk_button_new_with_label: "gtk_button_new_with_label" [ label [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b5b021a2af..de74ca4973 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1098,10 +1098,11 @@ init-text-list: func [ widget [handle!] data [red-block!] /local - str [red-string!] - tail [red-string!] - val [c-string!] - len [integer!] + str [red-string!] + tail [red-string!] + val [c-string!] + len [integer!] + label [handle!] ][ if any [ TYPE_OF(data) = TYPE_BLOCK @@ -1117,7 +1118,9 @@ init-text-list: func [ if TYPE_OF(str) = TYPE_STRING [ len: -1 val: unicode/to-utf8 str :len - gtk_container_add widget gtk_label_new val + label: gtk_label_new val + gtk_widget_set_halign label 1 ;-- GTK_ALIGN_START + gtk_container_add widget label ] str: str + 1 ] @@ -1371,6 +1374,7 @@ OS-make-view: func [ para: as red-object! values + FACE_OBJ_PARA rate: as red-value! values + FACE_OBJ_RATE + bits: get-flags as red-block! values + FACE_OBJ_FLAGS sym: symbol/resolve type/symbol caption: either TYPE_OF(str) = TYPE_STRING [ @@ -1491,6 +1495,9 @@ OS-make-view: func [ init-text-list widget data gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 _widget: gtk_scrolled_window_new null null + if bits and FACET_FLAGS_NO_BORDER = 0 [ + gtk_scrolled_window_set_shadow_type _widget 3 + ] gtk_container_add _widget widget gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) ] From 95629b8a19e9b345aa19ae5f53241dd4ce57dc0f Mon Sep 17 00:00:00 2001 From: qtxie Date: Wed, 18 Apr 2018 16:13:38 +0800 Subject: [PATCH 0081/3432] FEAT: support for changing data in text-list. --- modules/view/backends/gtk3/gtk.reds | 5 +++ modules/view/backends/gtk3/gui.reds | 56 ++++++++++++++--------------- modules/view/backends/platform.red | 28 +++++++++++++++ 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index e85294d62c..5b98a47fa5 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -310,6 +310,7 @@ cairo_font_extents_t!: alias struct! [ ] g_source_remove: "g_source_remove" [ timer [integer!] + return: [logic!] ] g_timeout_add: "g_timeout_add" [ ts [integer!] @@ -601,6 +602,10 @@ cairo_font_extents_t!: alias struct! [ handler [integer!] data [int-ptr!] ] + gtk_container_remove: "gtk_container_remove" [ + container [handle!] + widget [handle!] + ] gtk_frame_new: "gtk_frame_new" [ label [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index de74ca4973..caf18cfdf0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -259,19 +259,10 @@ free-handles: func [ ][ ;type: as red-word! values + FACE_OBJ_TYPE ;sym: symbol/resolve type/symbol - ;print ["destroying " get-symbol-name sym lf] - ;either null? hWnd [print ["null handle" lf]][ - rate: values + FACE_OBJ_RATE - if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] - g_object_set_qdata hWnd red-face-id null - g_object_set_qdata hWnd _widget-id null - g_object_set_qdata hWnd gtk-fixed-id null - g_object_set_qdata hWnd red-timer-id null - - ;gtk_widget_destroy manages eveything for free from the gtk side! - gtk_widget_destroy hWnd - ;] + rate: values + FACE_OBJ_RATE + if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] + gtk_widget_destroy hWnd state: values + FACE_OBJ_STATE state/header: TYPE_NONE ] @@ -501,7 +492,7 @@ change-rate: func [ /local int [red-integer!] tm [red-time!] - ts [float!] + ts [integer!] timer [integer!] data [handle!] ][ @@ -509,28 +500,27 @@ change-rate: func [ data: g_object_get_qdata hWnd red-timer-id timer: either null? data [0][as integer! data] - ;print ["timer: " timer lf] - if timer <> 0 [ ;-- cancel a preexisting timeout g_source_remove timer + g_object_set_qdata hWnd red-timer-id null ] switch TYPE_OF(rate) [ TYPE_INTEGER [ int: as red-integer! rate if int/value <= 0 [fire [TO_ERROR(script invalid-facet-type) rate]] - ts: 1.0 / as-float int/value + ts: 1000 / int/value ] TYPE_TIME [ tm: as red-time! rate if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] - ts: tm/time / 1E9 + ts: as-integer tm/time * 1000.0 ] TYPE_NONE [exit] default [fire [TO_ERROR(script invalid-facet-type) rate]] ] - timer: g_timeout_add as integer! ts as integer! :red-timer-action hWnd + timer: g_timeout_add ts as integer! :red-timer-action hWnd g_object_set_qdata hWnd red-timer-id as int-ptr! timer ] ] @@ -853,12 +843,14 @@ change-data: func [ ; type = tab-panel [ ; set-tabs hWnd get-face-values hWnd ; ] - ; all [ - ; type = text-list - ; TYPE_OF(data) = TYPE_BLOCK - ; ][ - ; objc_msgSend [objc_msgSend [hWnd sel_getUid "documentView"] sel_getUid "reloadData"] - ; ] + all [ + type = text-list + TYPE_OF(data) = TYPE_BLOCK + ][ + gtk_container_foreach hWnd as-integer :remove-entry hWnd + init-text-list hWnd as red-block! data + gtk_widget_show_all hWnd + ] any [type = drop-list type = drop-down][ init-combo-box hWnd as red-block! data null type = drop-list ] @@ -1093,6 +1085,13 @@ init-combo-box: func [ ;] ] +remove-entry: func [ + [cdecl] + widget [handle!] + container [int-ptr!] +][ + gtk_container_remove container widget +] init-text-list: func [ widget [handle!] @@ -1493,7 +1492,7 @@ OS-make-view: func [ sym = text-list [ widget: gtk_list_box_new init-text-list widget data - gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 + ;gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 _widget: gtk_scrolled_window_new null null if bits and FACET_FLAGS_NO_BORDER = 0 [ gtk_scrolled_window_set_shadow_type _widget 3 @@ -1658,6 +1657,9 @@ OS-update-view: func [ ;update-z-order hWnd as red-block! values + FACE_OBJ_PANE type 0 ] + if flags and FACET_FLAG_RATE <> 0 [ + change-rate widget values + FACE_OBJ_RATE + ] if flags and FACET_FLAG_FONT <> 0 [ change-font widget face as red-object! values + FACE_OBJ_FONT type ] @@ -1694,12 +1696,8 @@ OS-destroy-view: func [ flags: get-flags as red-block! values + FACE_OBJ_FLAGS if flags and FACET_FLAGS_MODAL <> 0 [ 0 - ;;TBD - ;SetActiveWindow GetWindow handle GW_OWNER ] - ;; print ["DDDEEEEestroy" lf] - free-handles handle values obj: as red-object! values + FACE_OBJ_FONT diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 285f6d1ff5..03c50795f7 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -717,6 +717,16 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] + Linux [ + button: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] + regular: [6x6 4x7] + small: [5x5 4x6] + mini: [1x1 0x1] + group-box: [3x3 0x4] + tab-panel: [7x7 6x10] + drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] + drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] + ] #default [] ]] extend system/view/metrics/paddings [#switch config/OS [ @@ -736,6 +746,15 @@ system/view/platform: context [ group-box: [0x8 4x18] drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] ] + Linux [ + button: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] + check: [20x0 3x1] + radio: [20x0 1x1] + text: [3x3 0x0] + field: [3x3 0x0] + group-box: [0x8 4x18] + drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] + ] #default [] ]] extend system/view/metrics/def-heights [#switch config/OS [ @@ -749,6 +768,15 @@ system/view/platform: context [ drop-list: 21 progress: 21 ] + Linux [ + check: 29 + radio: 29 + text: 22 + field: 29 + drop-down: 33 + drop-list: 33 + progress: 29 + ] #default [] ]] From 4de550b00b7e1b0fa410ec93dd3e9cc3336abad8 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sun, 22 Apr 2018 15:35:43 +0200 Subject: [PATCH 0082/3432] Update face/text for field Needed for tests/react-test2.red --- modules/view/backends/gtk3/events.reds | 8 ++++---- modules/view/backends/gtk3/gtk.reds | 9 +++++++++ modules/view/backends/gtk3/handlers.reds | 13 ++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 803552e34e..6f8d2e24c2 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -118,7 +118,7 @@ get-event-key: func [ code: evt/flags special?: code and 80000000h <> 0 code: code and FFFFh - print ["code " code lf] + ;debug: print ["code " code lf] if special? [ res: as red-value! switch code [ RED_VK_PRIOR [_page-up] @@ -348,9 +348,9 @@ translate-key: func [ key [integer!] special? [logic!] ][ - print ["keycode: " keycode] + ;debug: print ["keycode: " keycode] keycode: gdk_keyval_to_upper keycode - print [" keycode2: " keycode] + ;debug: print [" keycode2: " keycode] special?: no key: case [ all[keycode >= 30h keycode <= 5Ah][keycode]; RED_VK_0 to RED_VK_Z @@ -361,6 +361,6 @@ translate-key: func [ true [RED_VK_UNKNOWN] ] if special? [key: key or 80000000h] - print [" key: " key " F1" RED_VK_F1 lf] + ;debug: print [" key: " key " F1" RED_VK_F1 lf] key ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 5b98a47fa5..2e164b7da4 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -761,11 +761,20 @@ cairo_font_extents_t!: alias struct! [ entry [handle!] return: [handle!] ] + gtk_entry_get_text: "gtk_entry_get_text" [ + buffer [handle!] + return: [c-string!] + ] + gtk_entry_set_text: "gtk_entry_set_text" [ + buffer [handle!] + text [c-string!] + ] gtk_entry_buffer_set_text: "gtk_entry_buffer_set_text" [ buffer [handle!] text [c-string!] len [integer!] ] + gtk_scale_new_with_range: "gtk_scale_new_with_range" [ vertical? [logic!] min [float!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index f16af8352a..d52cb7d68b 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -347,6 +347,9 @@ field-key-release-event: func [ res [integer!] key [integer!] flags [integer!] + text [c-string!] + face [red-object!] + qdata [handle!] ][ ;print "key-release: " ;print [ "keyval: " event-key/keyval " -> " gdk_keyval_name event-key/keyval "(" event-key/keyval " -> " gdk_keyval_to_lower event-key/keyval ") et state: " event-key/state lf] @@ -357,12 +360,20 @@ field-key-release-event: func [ flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state - print ["key: " key " flags: " flags " key or flags: " key or flags lf] + ;print ["key: " key " flags: " flags " key or flags: " key or flags lf] res: make-event widget key or flags EVT_KEY_DOWN if res <> EVT_NO_DISPATCH [ make-event widget key or flags EVT_KEY ] + + text: gtk_entry_get_text widget + qdata: g_object_get_qdata widget red-face-id + unless null? qdata [ + face: as red-object! qdata + set-text widget face/ctx text + make-event widget 0 EVT_CHANGE + ] ] field-move-focus: func [ From 6c55966463295c353e77265d2948e6c21319368b Mon Sep 17 00:00:00 2001 From: qtxie Date: Tue, 8 Jan 2019 14:31:52 +0800 Subject: [PATCH 0083/3432] FIX: compiling error. --- modules/view/backends/gtk3/draw.reds | 3 +++ modules/view/backends/platform.red | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index cdf0303857..58ed4495fb 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -472,6 +472,8 @@ OS-draw-text: func [ dc [draw-ctx!] pos [red-pair!] text [red-string!] + catch? [logic!] + return: [logic!] /local ctx [handle!] len [integer!] @@ -489,6 +491,7 @@ OS-draw-text: func [ do-paint dc set-source-color dc/raw dc/pen-color ;-- backup pen color + yes ] OS-draw-arc: func [ diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 57f588145f..db0c4f80a9 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -574,7 +574,7 @@ system/view/platform: context [ #switch OS [ Linux [gui/get-text-size text font pair] - #default [gui/get-text-size text hFont pair] + #default [gui/get-text-size face text hFont pair] ] ] @@ -791,16 +791,18 @@ system/view/platform: context [ ] ] Linux [ - check: 29 - radio: 29 - text: 22 - field: 29 - drop-down: 33 - drop-list: 33 - progress: 29 + extend system/view/metrics/def-heights [ + check: 29 + radio: 29 + text: 22 + field: 29 + drop-down: 33 + drop-list: 33 + progress: 29 + ] ] #default [] - ]] + ] colors: system/view/metrics/colors #switch config/OS [ From 8c1bad44ce0adf036d3954ec302cbffa8f5a0d39 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 11 Jan 2019 09:41:53 +0100 Subject: [PATCH 0084/3432] A few updates for Gtk backend (#3718) * Update face/text for field Needed for tests/react-test2.red * Update for red-0.6.4 * Some fixes * It seems that there is no effect from now with these sizes --- build/includes.r | 2 +- environment/console/CLI/console-view.red | 19 ++ environment/natives.red | 2 +- modules/view/VID.red | 6 +- modules/view/backends/gtk3/gui.reds | 1 + modules/view/backends/gtk3/rules.red | 47 ++++ modules/view/backends/platform.red | 32 ++- tests/gtk3/draw.red | 295 +++++++++++++++++++++++ tests/gtk3/vid.red | 1 - tests/gtk3/view-test.red | 27 ++- tests/gtk3/view-test2.red | 29 --- 11 files changed, 397 insertions(+), 64 deletions(-) create mode 100644 environment/console/CLI/console-view.red create mode 100644 modules/view/backends/gtk3/rules.red create mode 100644 tests/gtk3/draw.red delete mode 100644 tests/gtk3/view-test2.red diff --git a/build/includes.r b/build/includes.r index 67fcce4aaa..7229bced0a 100644 --- a/build/includes.r +++ b/build/includes.r @@ -157,8 +157,8 @@ write %build/bin/sources.r set-cache [ %win32.reds %COM.reds %image-gdiplus.reds - %image-quartz.reds %image-gdk.reds + %image-quartz.reds %win32-ansi.reds %win32-print.reds ] diff --git a/environment/console/CLI/console-view.red b/environment/console/CLI/console-view.red new file mode 100644 index 0000000000..4c4684f08d --- /dev/null +++ b/environment/console/CLI/console-view.red @@ -0,0 +1,19 @@ +Red [ + Title: "Red console" + Author: ["Nenad Rakocevic" "Kaj de Vos"] + File: %console.red + Tabs: 4 + Rights: "Copyright (C) 2012-2018 Red Foundation. All rights reserved." + Needs: 'View + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +#include %input.red +#include %../help.red +#include %../engine.red + +system/console/init "Red Console" +system/console/launch \ No newline at end of file diff --git a/environment/natives.red b/environment/natives.red index fd1ebe72eb..067f66db68 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -403,7 +403,7 @@ difference: make native! [[ /case "Use case-sensitive comparison" /skip "Treat the series as fixed size records" size [integer!] - return: [block! hash! string! bitset! typeset!] + return: [block! hash! string! bitset! typeset! time!] ] #get-definition NAT_DIFFERENCE ] diff --git a/modules/view/VID.red b/modules/view/VID.red index 4ab8f6d423..145463345f 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -22,7 +22,7 @@ system/view/VID: context [ #switch config/OS [ Windows [#include %backends/windows/rules.red] macOS [#include %backends/macOS/rules.red] - Linux [] + Linux [#include %backends/gtk3/rules.red] ] ] @@ -38,7 +38,9 @@ system/view/VID: context [ capitalize Cancel-OK ] - Linux [] + Linux [ + Cancel-OK + ] ] user: [] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index caf18cfdf0..407545ec21 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -182,6 +182,7 @@ get-child-from-xy: func [ ] get-text-size: func [ + face [red-object!] str [red-string!] font [red-object!] pair [red-pair!] diff --git a/modules/view/backends/gtk3/rules.red b/modules/view/backends/gtk3/rules.red new file mode 100644 index 0000000000..f7907b43ec --- /dev/null +++ b/modules/view/backends/gtk3/rules.red @@ -0,0 +1,47 @@ +Red [ + Title: "VID macOS GUI post-processing rules" + Author: "Nenad Rakocevic" + File: %rules.red + Tabs: 4 + Rights: "Copyright (C) 2017-2018 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/dockimbel/Red/blob/master/BSL-License.txt + } +] + +cancel-captions: ["cancel" "delete" "remove"] +ok-captions: ["ok" "save" "apply"] + +Cancel-OK: function [ + "Put OK buttons last" + root [object!] +][ + foreach-face/with root [ + pos-x: face/offset/x + face/offset/x: f/offset/x + f/offset/x: pos-x + ][ + either all [ + face/type = 'button + find ok-captions face/text + ][ + last-but: none + pos-x: face/offset/x + pos-y: face/offset/y + + foreach f face/parent/pane [ + all [ + f <> face + f/type = 'button + find cancel-captions f/text + 5 > absolute f/offset/y - pos-y + pos-x < f/offset/x + pos-x: f/offset/x + last-but: f + ] + ] + last-but + ][no] + ] +] \ No newline at end of file diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index db0c4f80a9..9976fd15b7 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -518,6 +518,7 @@ system/view/platform: context [ #switch OS [ Windows [#include %windows/gui.reds] macOS [#include %macOS/gui.reds] + ; GTK backend (is it in conflict with %GTK/gui.reds) Linux [#include %gtk3/gui.reds] #default [] ;-- Linux ] @@ -572,8 +573,9 @@ system/view/platform: context [ pair: as red-pair! stack/arguments pair/header: TYPE_PAIR + ;GTK branch: gui/get-text-size face text hFont pair #switch OS [ - Linux [gui/get-text-size text font pair] + Linux [gui/get-text-size face text font pair] #default [gui/get-text-size face text hFont pair] ] ] @@ -649,6 +651,8 @@ system/view/platform: context [ #switch OS [ Windows [gui/PostQuitMessage 0] macOS [gui/post-quit-msg] + ; GTK Backend + ;TODO Linux [gui/post-quit-message] #default [0] ] ] @@ -722,6 +726,7 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] + ; GTK branch (similar to macOS from now) Linux [ button: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] regular: [6x6 4x7] @@ -732,7 +737,6 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] - #default [] ]] extend system/view/metrics/paddings [#switch config/OS [ Windows [ @@ -753,6 +757,7 @@ system/view/platform: context [ group-box: [0x8 4x18] drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] ] + ; GTK backend (similar to macOS from now) Linux [ button: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] check: [20x0 3x1] @@ -762,7 +767,6 @@ system/view/platform: context [ group-box: [0x8 4x18] drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] ] - #default [] ]] #switch config/OS [ Windows [ @@ -790,18 +794,8 @@ system/view/platform: context [ progress: 21 ] ] - Linux [ - extend system/view/metrics/def-heights [ - check: 29 - radio: 29 - text: 22 - field: 29 - drop-down: 33 - drop-list: 33 - progress: 29 - ] + Linux [ ] - #default [] ] colors: system/view/metrics/colors @@ -811,9 +805,13 @@ system/view/platform: context [ ;colors/window ;-- set in gui/init from OS metrics ;colors/panel ;-- set in gui/init from OS metrics ] - macOS [] - Linux [] - #default [] + macOS [ + + ] + ; GTK Backends + Linux [ + + ] ] append svs make face! [ ;-- default screen diff --git a/tests/gtk3/draw.red b/tests/gtk3/draw.red new file mode 100644 index 0000000000..ddfa5284b8 --- /dev/null +++ b/tests/gtk3/draw.red @@ -0,0 +1,295 @@ +Red [ + Title: "Tests for draw dialect" + Author: "Fyodor Shchukin" + File: %draw.red + Tabs: 4 +] + +l: layout [ + title "Draw test" + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + line 10x10 40x30 10x30 + line 10x40 40x40 + + font font-label + text 5x45 "line" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + triangle 10x10 40x10 25x40 + + font font-label + text 5x45 "triangle" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + box 10x10 40x20 + box 20x30 30x40 + + font font-label + text 5x45 "box" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + polygon 10x10 40x10 40x40 20x30 + + font font-label + text 5x45 "polygon" + ] + + return + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + circle 25x25 15 + circle 25x25 10 5 + + font font-label + text 5x45 "circle" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + ellipse 10x10 5x10 + ellipse 35x10 5x10 + ellipse 20x20 10x20 + + font font-label + text 5x45 "ellipse" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + ;arc
closed + arc 25x25 15x15 0 180 closed + arc 25x25 5x10 90 270 + + font font-label + text 5x45 "arc" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + curve 10x5 45x5 45x40 + curve 10x10 40x10 10x40 40x40 + + font font-label + text 5x45 "curve" + ] + + return + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + spline 10x10 40x10 40x40 10x40 10x20 30x20 30x30 20x30 + + font font-label + text 5x45 "spline" + ] + + base 50x60 100.70.70 draw [ + line-width 2 + fill-pen 170.20.20.128 + + image fstk-logo 10x10 40x40 + + font font-label + text 5x45 "image" + ] + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "text" + + text 10x10 "Red" + pen red ; test if pen color + font font-A + text 10x20 "Red" + ] + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "pen flat" + + line 10x10 10x40 + box 15x10 20x40 + + pen off + fill-pen 20.20.170.128 + box 25x10 30x40 + + pen 255.255.255.100 + line-width 1 + triangle 35x10 40x40 35x40 + + fill-pen off + triangle 35x10 40x10 40x40 + ] + + return + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "pen gradient" + + pen linear red green blue + line-width 5 + fill-pen off + box 10x10 40x40 + ] + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "fill gradient" + + fill-pen linear red green blue + box 10x10 40x40 + ] + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "line join" + + line-width 5 + + line-join miter + line 10x40 15x20 20x40 + line-join round + line 20x40 25x20 30x40 + line-join bevel + line 30x40 35x20 40x40 + ] + + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "line cap" + + line-width 7 + + line-cap flat + line 15x15 15x35 + line-cap square + line 25x15 25x35 + line-cap round + line 35x15 35x35 + ] + + return + + ; . . . + + base 230x2 0.0.0 + + return + + base 50x60 70.70.100 draw [ + font font-label + text 5x45 "rotate" + + line-width 2 + fill-pen 170.20.20.128 + + box 15x15 35x35 + rotate 45 25x25 + box 15x15 35x35 + ] + + base 50x60 70.70.100 draw [ + font font-label + text 5x45 "scale" + + line-width 2 + fill-pen 170.20.20.128 + + box 10x10 40x40 + scale 0.5 0.5 + box 10x10 40x40 + ] + + base 50x60 70.70.100 draw [ + font font-label + text 5x45 "translate" + + line-width 2 + fill-pen 170.20.20.128 + + box 10x10 30x30 + translate 10x10 + box 10x10 30x30 + ] +] + +font-label: make font! [ + name: "Arial" + size: 11 + color: white + anti-alias?: no +] + +font-A: make font! [ + name: "Times New Roman" + size: 15 + color: red + style: [bold italic underline] + anti-alias?: yes +] + +fstk-logo: load/as 64#{iVBORw0KGgoAAAANSUhEUgAAAD4AAAA/CAIAAAA3/+y2AAAACXBIWXMAABJ + 0AAASdAHeZh94AAAGr0lEQVR4nNVaTW8kVxU9975XVf0xthNDBMoi4m8EwTZZsEAiG9jwM9jzE/gB + SBFIMFKEhIDFwIY9e1ggNhERYqTIMx67XR/v3XtYtO3Y3dXVXZXBnjlqtVpVr947dd+p+9UlH373e + 4nEWwUBCpH43ix+/12JSp/Ev1SI6kQKhUJl9EXC5yk++7yOp/Pih9/k6cx8/CwASkN5EiZcCAAqYb + mgqriPuEj1n5fy7N9dhAhyvnqZ5KiQ8exDys1L02WUoDh83wQUSGJ+VeuiGrVuJZ6tAnC718yX2fM + U0TDTV5lOjN82unvdThPrDXUROvJVpj04e3Ov2wmL3nnCVOBIF2maDZjcLxPNp7G3y2bsuvedgwpE + 3hblbPm1t0c5fS75AZRD9LojmttFfeC6sf+wCoh8mcMiindw23W9dKmfWy04LofX7iVIc6ZaFwvMn + yjzwOU7qAMQoWX4Yvnhx2Ex3zUq7I4mUqrGiYHWXpzb53/TYkh2u6kDMC+X7xx/9JPw7Q+mMZiM/M + W/Vr94xtPTgWg1aBUVE9JGROnXBclXMPdVy927um9DBRN8xesC3bzuduUXe6jTycdKiWX9vLmt+qP + VHuoiIo9odgBfRatN5bzRgrkFzbeV8wYL5j62lfMWCOYWG8oZ9OuAxIjJ9dvXAKsjQNYVyb3j7l43 + wAxABGl1x5whWxSz5y++XP35M1kud61RFCKqgBAicEAIiJBUFXMGESPDxikRc0SNBaRvSzWmF2dIB + G37dEM6z0U0Mns+u4JQi2LbB1lzdvabT7E7LlQBYVmpqruoOiAkVGmmIWT3QjW5FyK2dUrjLGgVNQ + bpe5y0qNCXe6u7BSc9AqCHlFKIEJVN9gIpq4Gi0+EwDWURVODEjUMKAUDUACCsvzdPxXWCrRIL6Vt + g15oUEArYtUjc2a6yOyd0Fzx7t+rolN7dvwuRjQ+duUkkCNn4DEwT4bj7mLqzq62ahw3bs2sHBONw + AA54bsqqRCgGlgxVse1qmT3T4nyPw7gLu76BuzyMzZXNlvGavVk4OTn+5McDj+ldDiIaithvegnp/ + FXzp6cqvu2RaWYNwuxQ9mvBbI6ms13lchFEBZ3F46PlR5/E979z4KQDKM6eX/7+aaGQvo6TZ2PDWM + V+n3Mfa8H0+Oy1cuCEws0ndvS2wPoKGNIws+dmZzl2F+tB/eFmrZyHzwBoZs1QUXc9DIqBRIDOZmX + ZsNtN/V/g2XKTMGi2nYK5M42zSXzwImmvcoYE8+gYVs4ewTw6PFuuU2/KfYBgHhs0z21Pn+cgwWiQ + 7YRyGmS+AHqzlUFkWrupnLVgBgNYDN3lxfkfn+rx8c36okF1fJ4jAru4LIJLGO2xPBnIcCdabeYwP + Qgxna+e//pXuPUyTg1azkIsZN3MCxjhgIony2Je9OSne9lnB+w2U+jJYTZBACLFbONYosQyCgCnjq + FuRjT5mv3IgOfZ0CJUEbtymINmcdaXuVyEoKMbBpadq65clBJGF72ezOmxiuGuYER66jsANDI1sM0 + AYUDbynwZZb4YbT9nalIxjxqEHEk/MzJxUYlIpDPVVphZ2Nx6WVnxwfvv/uBj3dXpreuL3/0WXatx + KE3vIdCaNVYdFfurky24W7YkEqIbVq/aIiUpig3zed3OT99750c/jd/4Vu8szPV/f/lp0VwVx0ej2 + zVimahmQXU4YdmE0Sy4+41KUgadGybY+3emr1akpC4Q1DDOfqpCZ0pObq576AwAqCFRm4Rps7ixfk + USY9kDyImpIzCl2aMAxA305Khb+JbtD4E7V+fmNoV9SmwbJ0ezvzc8E03HbeXshQjoqC/NfbRyAOT + MtvWxVtu800yZphwRuOHqAZXTM/BWOWOXFwEfUDn9o9bKSQfVuPfwkMrZeYOZkoxSVBJ2vu6iy5Pt + 93geTDlDOYzH+OLv/4g//1mcV70DUt15dpbVBsFb5SyOggbxkf/Zp0TSq5mqDvTdBqkzxPr5i/989 + hcRFDvsF0+Oe9P3W+XMj3QC+5yJ1stSRHrbwPuoixNS5EURBKGEaM8sA6K8Vc7yRKawTxSgrGSX7Q + 96mI2ouynR6uv7nKbe6XMO9aKPFa3MdvqcEcH3TYtW4/KGyXnO61TOzdWjE7bHV87NkSlNlteiHJm + knLb76sWuCACqRWSQcXG/NZlFrWRscQQAdmFyFGUZkMc1Yz2DmcXcRYr40vyv8ydSzWxSrbIM176e + kHVr65AfAsBFOh1bVQMIhotz0lL8skt/YBSd+l7ujdVIEeGBPwDQRCa9kghAakbk/wFTSfh53Lxjk + wAAAABJRU5ErkJggg== + } 'png + +view l + diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red index 3df21fc350..023803a930 100644 --- a/tests/gtk3/vid.red +++ b/tests/gtk3/vid.red @@ -5,7 +5,6 @@ Red [ Needs: 'View ] system/view/debug?: no ;yes -system/view/gtk-auto-adjust?: yes view [ title "VID test" diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red index e51a39c78a..4fec9133f0 100644 --- a/tests/gtk3/view-test.red +++ b/tests/gtk3/view-test.red @@ -3,13 +3,12 @@ Red [ Needs: 'View ] -system/view/debug?: no +system/view/debug?: yes live?: system/view/auto-sync?: no -system/view/gtk-auto-adjust?: yes workstation?: system/view/platform/product = 1 os-version: system/view/platform/version - +recycle/off #switch config/OS [ Windows [ @@ -605,15 +604,15 @@ win/pane: reduce [ ] ] ] - ; make face! [ - ; type: 'radio text: "radio 2" offset: 300x230 size: 90x24 - ; data: on - ; actors: object [ - ; on-change: func [face [object!] event [event!]][ - ; print "radio 2 set" - ; ] - ; ] - ; ] + make face! [ + type: 'radio text: "radio 2" offset: 300x230 size: 90x24 + data: on + actors: object [ + on-change: func [face [object!] event [event!]][ + print "radio 2 set" + ] + ] + ] make face! [ type: 'base offset: 280x10 size: 100x100 options: [drag-on: 'down] @@ -904,4 +903,6 @@ append win/pane make face! [ dump-face win view/flags win [resize] system/view/debug?: no -system/view/auto-sync?: yes \ No newline at end of file +system/view/auto-sync?: yes + +recycle/on \ No newline at end of file diff --git a/tests/gtk3/view-test2.red b/tests/gtk3/view-test2.red deleted file mode 100644 index 8c5ac8fbfc..0000000000 --- a/tests/gtk3/view-test2.red +++ /dev/null @@ -1,29 +0,0 @@ -Red [ - Purpose: "Test GTK auto change size of widget" - Needs: 'View -] - -system/view/debug?: no - - - -win: make face! [ - type: 'window text: "Red View" size: 600x400 -] - -field: make face! [ - type: 'field - para: make para! [align: 'left] - text: "Font size" - offset: 10x10 size: 80x20 -] - -; but1: make face! [type: 'button text: "+" offset: 100x10 size: 40x20] - -; but2: make face! [type: 'button text: "-" offset: 150x10 size: 40x20] - -; win/pane: reduce [field but1 but2] -; view/flags win [resize] - -smiley: make image! 23x24 -image: load %../../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png From a450c0fa1e830f88bafd5cbca3a9137859f4336c Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 12 Jan 2019 02:05:10 +0100 Subject: [PATCH 0085/3432] fix GApplicationFlags of GTKApp to have multiple instances of gtk apps --- modules/view/backends/gtk3/gtk.reds | 10 +++++++--- modules/view/backends/gtk3/gui.reds | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 2e164b7da4..499de9544b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -407,6 +407,13 @@ cairo_font_extents_t!: alias struct! [ error [int-ptr!] return: [logic!] ] + g_application_activate: "g_application_activate" [ + app [handle!] + ] + g_application_id_is_valid: "g_application_id_is_valid" [ + id [c-string!] + return: [logic!] + ] g_settings_sync: "g_settings_sync" [] ;; ] ;; LIBGTK-file cdecl [ @@ -419,9 +426,6 @@ cairo_font_extents_t!: alias struct! [ app [handle!] return: [int-ptr!] ] - g_application_activate: "g_application_activate" [ - app [handle!] - ] gtk_application_get_active_window: "gtk_application_get_active_window" [ app [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 407545ec21..d85c697125 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -56,7 +56,8 @@ pango-context: as handle! 0 gtk-font: "Sans 10" ; Do not KNOW about this one -main-window: as handle! 0 +;;;main-window: as handle! 0 + ; Temporary, will be removed... last-widget: as handle! 0 @@ -361,7 +362,8 @@ debug-show-children: func [ ] init: func [][ - GTKApp: gtk_application_new RED_GTK_APP_ID 0 + if g_application_id_is_valid RED_GTK_APP_ID [ + GTKApp: gtk_application_new RED_GTK_APP_ID 32 gobj_signal_connect(GTKApp "window-removed" :window-removed-event :exit-loop) GTKApp-Ctx: g_main_context_default @@ -377,6 +379,7 @@ init: func [][ screen-size-y: gdk_screen_height style-init + ] ] get-symbol-name: function [ @@ -1304,8 +1307,8 @@ OS-refresh-window: func [hWnd [integer!]][ OS-show-window: func [ hWnd [integer!] - /local - auto-adjust? [red-logic!] + ; /local + ; auto-adjust? [red-logic!] ][ gtk_widget_show_all as handle! hWnd gtk_widget_grab_focus as handle! hWnd @@ -1384,6 +1387,8 @@ OS-make-view: func [ null ] + print ["OS-make-view " get-symbol-name sym lf] + case [ sym = check [ widget: gtk_check_button_new_with_label caption @@ -1415,9 +1420,14 @@ OS-make-view: func [ gobj_signal_connect(widget "draw" :base-draw face/ctx) ] sym = window [ - widget: gtk_application_window_new GTKApp + ;;;print ["win " GTKApp lf] + ;widget: gtk_application_window_new GTKApp + widget: gtk_window_new 0 + ;;;print ["win1 " widget lf] + gtk_application_add_window GTKApp widget + ;;;print ["win2 " lf] ; @@ DEBUG: temporary code - main-window: widget + ;;;main-window: widget unless null? caption [gtk_window_set_title widget caption] gtk_window_set_default_size widget size/x size/y gtk_container_add widget gtk_fixed_new @@ -1524,7 +1534,8 @@ OS-make-view: func [ make-font-provider widget if sym <> base [change-font widget face font sym] - ;print [ "New widget " get-symbol-name sym "->" widget lf] + ; + print [ "New widget " get-symbol-name sym "->" widget lf] if all [ sym <> window From a30dd573fc2bb79161e78123aa5a174fb4428891 Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 12 Jan 2019 07:14:16 +0100 Subject: [PATCH 0086/3432] GApplicationFlags! introduced --- modules/view/backends/gtk3/gtk.reds | 10 ++++++++++ modules/view/backends/gtk3/gui.reds | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 499de9544b..872dd6c194 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -108,6 +108,16 @@ GdkEventCrossing!: alias struct! [ state [integer!] ] +#enum GGApplicationFlags! [ + G_APPLICATION_FLAGS_NONE: 0 + G_APPLICATION_IS_SERVICE: 1 + G_APPLICATION_IS_LAUNCHER: 2 + G_APPLICATION_HANDLES_OPEN: 4 + G_APPLICATION_HANDLES_COMMAND_LINE: 8 + G_APPLICATION_SEND_ENVIRONMENT: 16 + G_APPLICATION_NON_UNIQUE: 32 +] + #enum GdkModifierType! [ GDK_SHIFT_MASK: 1 GDK_LOCK_MASK: 2 diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index d85c697125..fea51daaae 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -362,8 +362,7 @@ debug-show-children: func [ ] init: func [][ - if g_application_id_is_valid RED_GTK_APP_ID [ - GTKApp: gtk_application_new RED_GTK_APP_ID 32 + GTKApp: gtk_application_new RED_GTK_APP_ID G_APPLICATION_NON_UNIQUE gobj_signal_connect(GTKApp "window-removed" :window-removed-event :exit-loop) GTKApp-Ctx: g_main_context_default @@ -379,7 +378,6 @@ init: func [][ screen-size-y: gdk_screen_height style-init - ] ] get-symbol-name: function [ From b4d7535e6925b6444a5c52103b65e35feb9c153a Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 14 Jan 2019 23:19:41 +0100 Subject: [PATCH 0087/3432] Fix color issue --- runtime/platform/image-gdk.reds | 2 +- system/config.r | 6 ++++++ tests/gtk3/view-test.red | 22 +++++++++++----------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 5f56ac5332..1626ac6c23 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -460,7 +460,7 @@ OS-image: context [ b: as-integer rgb/3 rgb: rgb + 3 ] - scan0/pos: r << 16 or (g << 8) or b or (a << 24) + scan0/pos: r or (g << 8) or (b << 16) or (a << 24) x: x + 1 ] y: y + 1 diff --git a/system/config.r b/system/config.r index ce99c854e9..2f948d61c9 100644 --- a/system/config.r +++ b/system/config.r @@ -96,6 +96,12 @@ Linux [ ; Linux default target type: 'exe dynamic-linker: "/lib/ld-linux.so.2" ] +Linux-Musl [ ; Linux default target + OS: 'Linux + format: 'ELF + type: 'exe + dynamic-linker: "/lib/ld-musl-i386.so.1" +] Linux-Old [ OS: 'Linux format: 'ELF diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red index 4fec9133f0..12a1bd5fb4 100644 --- a/tests/gtk3/view-test.red +++ b/tests/gtk3/view-test.red @@ -706,14 +706,14 @@ win/pane: reduce [ type: 'drop-list offset: 480x402 size: 160x32 actors: object [ on-create: func [face [object!]][ - face/data: cam/data + ;face/data: cam/data ] on-change: func [face [object!] event [event!]][ print ["changed:" face/selected] - unless cam/selected = face/selected [ - cam/selected: face/selected - ] - unless live? [show cam] + ;unless cam/selected = face/selected [ + ; cam/selected: face/selected + ;] + ;unless live? [show cam] ] ] ] @@ -721,12 +721,12 @@ win/pane: reduce [ type: 'button text: "Start/Stop" offset: 400x400 size: 70x24 actors: object [ on-click: func [face [object!] event [event!]][ - either cam/selected [ - cam/selected: none - ][ - cam/selected: cam-list/selected - ] - unless live? [show cam] + ; either cam/selected [ + ; cam/selected: none + ; ][ + ; cam/selected: cam-list/selected + ; ] + ; unless live? [show cam] ] ] ] From 7d696b65fd4e922185473fe14c17b4bda29e954f Mon Sep 17 00:00:00 2001 From: R cqls Date: Wed, 16 Jan 2019 16:45:47 +0100 Subject: [PATCH 0088/3432] fix data update --- modules/view/backends/gtk3/gui.reds | 30 +++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index fea51daaae..eb889c19a2 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -819,6 +819,8 @@ change-data: func [ word: as red-word! values + FACE_OBJ_TYPE type: word/symbol + ;;DEBUG: print ["change-data: " get-symbol-name type lf] + case [ all [ type = progress @@ -849,6 +851,7 @@ change-data: func [ type = text-list TYPE_OF(data) = TYPE_BLOCK ][ + ;;DEBUG: print ["text-list updated" lf] gtk_container_foreach hWnd as-integer :remove-entry hWnd init-text-list hWnd as red-block! data gtk_widget_show_all hWnd @@ -1385,7 +1388,7 @@ OS-make-view: func [ null ] - print ["OS-make-view " get-symbol-name sym lf] + ;;DEBUG: print ["OS-make-view " get-symbol-name sym lf] case [ sym = check [ @@ -1532,8 +1535,7 @@ OS-make-view: func [ make-font-provider widget if sym <> base [change-font widget face font sym] - ; - print [ "New widget " get-symbol-name sym "->" widget lf] + ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] if all [ sym <> window @@ -1702,7 +1704,6 @@ OS-destroy-view: func [ ][ handle: face-handle? face values: object/get-values face - FACE_OBJ_STATE flags: get-flags as red-block! values + FACE_OBJ_FLAGS if flags and FACET_FLAGS_MODAL <> 0 [ 0 @@ -1735,8 +1736,25 @@ OS-update-facet: func [ sym: symbol/resolve facet/symbol case [ - sym = facets/pane [0] - sym = facets/data [0] + ;sym = facets/pane [0] + sym = facets/data [ + word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE + type: symbol/resolve word/symbol + sym: action/symbol + case [ + ; any [ + ; type = drop-list + ; type = drop-down + ; ][ + ; if zero? part [exit] + ; update-combo-box face value sym new index part yes + ; ] + ; type = tab-panel [ + ; update-tabs face value sym new index part + ; ] + true [OS-update-view face] + ] + ] true [OS-update-view face] ] ] From f6a0d7cb0089150b8d4b439a3c7274d7f0e664a4 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 18 Jan 2019 17:31:51 +0100 Subject: [PATCH 0089/3432] Add down event to text --- modules/view/backends/gtk3/gui.reds | 1 + modules/view/backends/gtk3/handlers.reds | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index eb889c19a2..5c8ac7fb08 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1451,6 +1451,7 @@ OS-make-view: func [ widget: gtk_label_new caption _widget: gtk_event_box_new null null gtk_container_add _widget widget + gobj_signal_connect(_widget "button-press-event" :text-button-press-event widget) ] sym = field [ widget: gtk_entry_new diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index d52cb7d68b..4b93d9a6fa 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -271,6 +271,15 @@ range-value-changed: func [ ;] ] +text-button-press-event: func [ + [cdecl] + _widget [handle!] + evt [handle!] + widget [handle!] +][ + make-event widget 0 EVT_LEFT_DOWN +] + combo-selection-changed: func [ [cdecl] widget [handle!] From d18cf7171ef31ddfe360904ad1d762c69d950970 Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 18 Jan 2019 09:37:11 +0100 Subject: [PATCH 0090/3432] Some preliminary resizing stuff added GTK part of wallet is resizing properly. --- modules/view/backends/gtk3/events.reds | 22 ++++-- modules/view/backends/gtk3/gui.reds | 87 ++++++++++-------------- modules/view/backends/gtk3/handlers.reds | 17 +++++ 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 6f8d2e24c2..f321be36f2 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -67,16 +67,16 @@ get-event-offset: func [ evt [red-event!] return: [red-value!] /local - offset [red-pair!] - value [integer!] + widget [handle!] + sz [red-pair!] + offset [red-pair!] + value [integer!] ][ case [ any [ evt/type <= EVT_OVER evt/type = EVT_MOVING - evt/type = EVT_SIZING evt/type = EVT_MOVE - evt/type = EVT_SIZE ][ offset: as red-pair! stack/push* offset/header: TYPE_PAIR @@ -85,6 +85,20 @@ get-event-offset: func [ ;;print ["event-offset: " offset/x "x" offset/y lf] as red-value! offset ] + any [ + evt/type = EVT_SIZING + evt/type = EVT_SIZE + ][ + widget: as handle! evt/msg + ;;print ["event-offset type: " get-symbol-name get-widget-symbol widget lf] + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + offset: as red-pair! stack/push* + offset/header: TYPE_PAIR + offset/x: sz/x + offset/y: sz/y + ;;print ["event-offset: " offset/x "x" offset/y lf] + as red-value! offset + ] any [ evt/type = EVT_ZOOM evt/type = EVT_PAN diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5c8ac7fb08..0b610bf0e5 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -527,48 +527,6 @@ change-rate: func [ ] ] -change-size: func [ - hWnd [handle!] - size [red-pair!] - type [integer!] - /local - h [integer!] - w [integer!] - y [integer!] - x [integer!] - ;rc [NSRect!] - ;frame [NSRect!] - saved [int-ptr!] - method [integer!] -][ - ;; print-line "change-size" - ; rc: make-rect size/x size/y 0 0 - ; if all [type = button size/y > 32][ - ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" NSRegularSquareBezelStyle] - ; ] - ; either type = window [ - ; x: 0 - ; frame: as NSRect! :x - ; method: sel_getUid "frame" - ; saved: system/stack/align - ; push 0 - ; push method push hWnd push frame - ; objc_msgSend_stret 3 - ; system/stack/top: saved - ; frame/y: frame/y + frame/h - rc/y - ; objc_msgSend [hWnd sel_getUid "setFrame:display:animate:" frame/x frame/y rc/x rc/y yes yes] - ; ][ - ; objc_msgSend [hWnd sel_getUid "setFrameSize:" rc/x rc/y] - ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] - ; object_getInstanceVariable hWnd IVAR_RED_DATA :type - ; if type = caret [ - ; caret-w: rc/x - ; caret-h: rc/y - ; ] - ; ] - 0 -] - change-image: func [ hWnd [handle!] image [red-image!] @@ -710,7 +668,9 @@ change-offset: func [ type [integer!] /local container [handle!] + _widget [handle!] ][ + ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol hWnd lf] either type = window [ ; rc/y: as float32! screen-size-y - pos/y ; objc_msgSend [hWnd sel_getUid "setFrameTopLeftPoint:" rc/x rc/y] @@ -718,7 +678,30 @@ change-offset: func [ ][ ;OS-refresh-window as integer! main-window container: either null? hWnd [null][g_object_get_qdata hWnd gtk-fixed-id] - unless null? container [gtk_fixed_move container hWnd pos/x pos/y] + ;; DEBUG: print ["change-offset by" pos lf] + ; _widget: either type = text [ + ; g_object_get_qdata hWnd _widget-id + ; ][hWnd] + _widget: g_object_get_qdata hWnd _widget-id + _widget: either null? _widget [hWnd][_widget] + unless null? container [gtk_fixed_move container _widget pos/x pos/y] + ] +] + +change-size: func [ + hWnd [handle!] + size [red-pair!] + type [integer!] + /local + _widget [handle!] +][ + ;; DEBUG: print ["change-size" get-symbol-name get-widget-symbol hWnd size lf] + either type = window [ + gtk_window_set_default_size hWnd size/x size/y + ][ + _widget: g_object_get_qdata hWnd _widget-id + _widget: either null? _widget [hWnd][_widget] + gtk_widget_set_size_request _widget size/x size/y ] ] @@ -1188,20 +1171,23 @@ connect-mouse-events: function [ actors [red-object!] type [integer!] /local - widget [handle!] + _widget [handle!] ][ if all [ not null? actors/ctx (object/rs-find actors as red-value! _on-over) <> -1 ][ - widget: either type = text [ + _widget: either type = text [ g_object_get_qdata hWnd _widget-id ][hWnd] - + ; OR (NOT YET TESTED but if needed for widget with _widget) + ; _widget: g_object_get_qdata hWnd _widget-id + ; _widget: either null? _widget [hWnd][_widget] + ;print [ "Mouse events " get-symbol-name type "->" widget lf] - gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK - gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) - gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) + gtk_widget_add_events _widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK + gobj_signal_connect(_widget "enter-notify-event" :widget-enter-notify-event face/ctx) + gobj_signal_connect(_widget "leave-notify-event" :widget-leave-notify-event face/ctx) ] ] @@ -1434,6 +1420,7 @@ OS-make-view: func [ gtk_container_add widget gtk_fixed_new gtk_window_move widget offset/x offset/y gobj_signal_connect(widget "delete-event" :window-delete-event null) + gobj_signal_connect(widget "size-allocate" :window-size-allocate null) ] sym = slider [ vertical?: size/y > size/x @@ -1566,7 +1553,7 @@ OS-make-view: func [ container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] ;save gtk_fixed container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass g_object_set_qdata widget gtk-fixed-id container - + if sym = text [g_object_set_qdata _widget gtk-fixed-id container] gtk_widget_set_size_request _widget size/x size/y gtk_fixed_put container _widget offset/x offset/y ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 4b93d9a6fa..0335eada46 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -236,6 +236,23 @@ window-removed-event: func [ count/value: count/value - 1 ] +window-size-allocate: func [ + [cdecl] + widget [handle!] + rect [tagRECT] + /local + sz [red-pair!] +][ + ;;DEBUG: print [ "window-size-allocate " rect/width "x" rect/height lf] + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size + sz/x: rect/width + sz/y: rect/height + ;motion/x_new: rect/width + ;motion/y_new: rect/height + make-event widget 0 EVT_SIZING + ;; DEBUG: print [ "window-size-allocate end" lf] +] + range-value-changed: func [ [cdecl] range [handle!] From 7d3e90e957109853b1a3a3cb468cf3777a402aff Mon Sep 17 00:00:00 2001 From: R cqls Date: Sat, 19 Jan 2019 16:48:46 +0100 Subject: [PATCH 0091/3432] Fix scale and image issues on draw see tests/draw.red for testing Some additonal changes asked by @qtxie in previous PR --- modules/view/backends/gtk3/draw.reds | 63 +++++++----------------- modules/view/backends/gtk3/events.reds | 10 ++-- modules/view/backends/gtk3/font.reds | 2 + modules/view/backends/gtk3/gtk.reds | 8 +++ modules/view/backends/gtk3/gui.reds | 8 +-- modules/view/backends/gtk3/handlers.reds | 6 +-- tests/draw.red | 27 +++++----- 7 files changed, 57 insertions(+), 67 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 58ed4495fb..918d0655b5 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -608,53 +608,22 @@ OS-draw-line-cap: func [ ] ] -; OS-draw-image: func [ -; dc [draw-ctx!] -; image [red-image!] -; start [red-pair!] -; end [red-pair!] -; key-color [red-tuple!] -; border? [logic!] -; crop1 [red-pair!] -; pattern [red-word!] -; /local -; x [integer!] -; y [integer!] -; width [integer!] -; height [integer!] -; ][ -; 0 -; ] - - GDK-draw-image: func [ - dc [handle!] - image [integer!] + cr [handle!] + image [handle!] x [integer!] y [integer!] - ; width [integer!] - ; height [integer!] - ;/local - ; rc [NSRect!] - ; ty [float32!] + width [integer!] + height [integer!] + /local + img [handle!] ][ - ; rc: make-rect x y width height - ; ty: rc/y + rc/h - ; ;-- flip coords - ; ;; drawing an image or PDF by calling Core Graphics functions directly, - ; ;; we must flip the CTM. - ; ;; http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage - ; CGContextTranslateCTM dc as float32! 0.0 ty - ; CGContextScaleCTM dc as float32! 1.0 as float32! -1.0 - - ; CGContextDrawImage dc rc/x as float32! 0.0 rc/w rc/h image - - ; ;-- flip back - ; CGContextScaleCTM dc as float32! 1.0 as float32! -1.0 - ; CGContextTranslateCTM dc as float32! 0.0 (as float32! 0.0) - ty - gdk_cairo_set_source_pixbuf dc as handle! image x y - cairo_paint dc - ;0 + img: either width = 0 [image][gdk_pixbuf_scale_simple image width height 2] + ;; DEBUG: print ["GDK-draw-image: " x "x" y lf] + cairo_translate cr as-float x as-float y + gdk_cairo_set_source_pixbuf cr img 0 0 + cairo_paint cr + cairo_translate cr as-float (0 - x) as-float (0 - y) ] OS-draw-image: func [ @@ -693,6 +662,8 @@ OS-draw-image: func [ true [0] ;@@ TBD four control points ] + ;; DEBUG: print ["OS-draw-image: " x "x" y " " width "x" height lf] + img: OS-image/to-pixbuf image if crop1 <> null [ crop2: crop1 + 1 @@ -706,7 +677,7 @@ OS-draw-image: func [ ;gdk_pixbuf_scale as handle! img as handle! sub-img 0 0 width height 0.0 0.0 1.0 1.0 0 ; to correct parameters!!! ] - GDK-draw-image dc/raw img x y + GDK-draw-image dc/raw as handle! img x y width height if crop1 <> null [g_object_unref as handle! sub-img] ] @@ -836,8 +807,8 @@ OS-matrix-scale: func [ cr [handle!] ][ cr: dc/raw - cairo_scale cr as-float sx/value - as-float sy/value + cairo_scale cr as float! get-float32 sx + as float! get-float32 sy ] OS-matrix-translate: func [ diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index f321be36f2..09b245d3ba 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -91,11 +91,15 @@ get-event-offset: func [ ][ widget: as handle! evt/msg ;;print ["event-offset type: " get-symbol-name get-widget-symbol widget lf] - sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE offset: as red-pair! stack/push* offset/header: TYPE_PAIR - offset/x: sz/x - offset/y: sz/y + ; sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + ; offset/x: sz/x + ; offset/y: sz/y + + offset/x: gtk_widget_get_allocated_width widget + offset/y: gtk_widget_get_allocated_height widget + ;;print ["event-offset: " offset/x "x" offset/y lf] as red-value! offset ] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index d65303d1db..6a22982a11 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -99,6 +99,8 @@ make-font: func [ css: add-to-string css "%s}" null + ;; DEBUG: print ["make font -> css: " css lf] + hFont: as handle! css blk: as red-block! values + FONT_OBJ_STATE diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 872dd6c194..1e24cbdf43 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -583,6 +583,14 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] alloc [handle!] ] + gtk_widget_get_allocated_width: "gtk_widget_get_allocated_width" [ + widget [handle!] + return: [integer!] + ] + gtk_widget_get_allocated_height: "gtk_widget_get_allocated_height" [ + widget [handle!] + return: [integer!] + ] gtk_widget_set_can_focus: "gtk_widget_set_can_focus" [ widget [handle!] focus [logic!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 0b610bf0e5..26912b963a 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -672,8 +672,6 @@ change-offset: func [ ][ ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol hWnd lf] either type = window [ - ; rc/y: as float32! screen-size-y - pos/y - ; objc_msgSend [hWnd sel_getUid "setFrameTopLeftPoint:" rc/x rc/y] 0 ][ ;OS-refresh-window as integer! main-window @@ -684,7 +682,10 @@ change-offset: func [ ; ][hWnd] _widget: g_object_get_qdata hWnd _widget-id _widget: either null? _widget [hWnd][_widget] - unless null? container [gtk_fixed_move container _widget pos/x pos/y] + unless null? container [ + gtk_fixed_move container _widget pos/x pos/y + gtk_widget_queue_draw _widget + ] ] ] @@ -702,6 +703,7 @@ change-size: func [ _widget: g_object_get_qdata hWnd _widget-id _widget: either null? _widget [hWnd][_widget] gtk_widget_set_size_request _widget size/x size/y + gtk_widget_queue_draw _widget ] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 0335eada46..47b7e15b82 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -196,7 +196,7 @@ base-draw: func [ ] if TYPE_OF(img) = TYPE_IMAGE [ - GDK-draw-image cr OS-image/to-pixbuf img 0 0 + GDK-draw-image cr as handle! OS-image/to-pixbuf img 0 0 0 0 ] render-text cr vals @@ -244,12 +244,10 @@ window-size-allocate: func [ sz [red-pair!] ][ ;;DEBUG: print [ "window-size-allocate " rect/width "x" rect/height lf] + make-event widget 0 EVT_SIZING sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size sz/x: rect/width sz/y: rect/height - ;motion/x_new: rect/width - ;motion/y_new: rect/height - make-event widget 0 EVT_SIZING ;; DEBUG: print [ "window-size-allocate end" lf] ] diff --git a/tests/draw.red b/tests/draw.red index ddfa5284b8..28a42c1543 100644 --- a/tests/draw.red +++ b/tests/draw.red @@ -2,6 +2,7 @@ Red [ Title: "Tests for draw dialect" Author: "Fyodor Shchukin" File: %draw.red + Needs: View Tabs: 4 ] @@ -163,12 +164,18 @@ l: layout [ base 50x60 100.70.70 draw [ font font-label - text 5x45 "fill gradient" - - fill-pen linear red green blue + text 5x45 "linear gradient" + fill-pen linear 4x4 0 40 0 1.0 1.0 red green blue box 10x10 40x40 ] + base 50x60 100.70.70 draw [ + font font-label + text 5x45 "radial gradient" + fill-pen radial 25x25 0 15 0 1.0 1.0 red green blue + box 10x10 40x40 + ] + base 50x60 100.70.70 draw [ font font-label text 5x45 "line join" @@ -183,6 +190,11 @@ l: layout [ line 30x40 35x20 40x40 ] + return + + base 230x2 0.0.0 return + ; . . . + base 50x60 100.70.70 draw [ font font-label text 5x45 "line cap" @@ -197,14 +209,6 @@ l: layout [ line 35x15 35x35 ] - return - - ; . . . - - base 230x2 0.0.0 - - return - base 50x60 70.70.100 draw [ font font-label text 5x45 "rotate" @@ -240,6 +244,7 @@ l: layout [ translate 10x10 box 10x10 30x30 ] + ] font-label: make font! [ From c494addcb21b583c0b108ce33a8531df5131ca8f Mon Sep 17 00:00:00 2001 From: R cqls Date: Mon, 28 Jan 2019 03:21:05 +0100 Subject: [PATCH 0092/3432] Gtk patch issue get text size (#3754) * Removing style.reds In the process to use pango_font instead of gtk_css_provider * Forget to remove style-init * make-font splitted in many files * font is now a pango_font_description * get-text-size in gui.red has the same signature tas macOS and windows * platform.red is then as originally * More work on font and styles * Fix get-font-handle to have het-text-sze working * Remove comments These comments are good to be kept in the git history. --- build/includes.r | 1 - modules/view/backends/gtk3/comdlgs.reds | 2 +- modules/view/backends/gtk3/draw.reds | 2 +- modules/view/backends/gtk3/events.reds | 2 +- modules/view/backends/gtk3/font.reds | 318 +++++++++++++++-------- modules/view/backends/gtk3/gtk.reds | 20 +- modules/view/backends/gtk3/gui.reds | 44 ++-- modules/view/backends/gtk3/handlers.reds | 2 +- modules/view/backends/gtk3/style.reds | 196 -------------- modules/view/backends/platform.red | 7 +- 10 files changed, 251 insertions(+), 343 deletions(-) delete mode 100644 modules/view/backends/gtk3/style.reds diff --git a/build/includes.r b/build/includes.r index 7229bced0a..b4e9c2082c 100644 --- a/build/includes.r +++ b/build/includes.r @@ -219,7 +219,6 @@ write %build/bin/sources.r set-cache [ %gui.reds %draw.reds %handlers.reds - %style.reds %events.reds %gtk.reds %para.reds diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 8576c0d414..bf3d63f8cd 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -1,6 +1,6 @@ Red/System [ Title: "Common Dialogs" - Author: "Xie Qingtian" + Author: "Xie Qingtian, RCqls" File: %comdlgs.reds Tabs: 4 Rights: "Copyright (C) 2016 Xie Qingtian. All rights reserved." diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 918d0655b5..b0d0220958 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1,6 +1,6 @@ Red/System [ Title: "Cairo Draw dialect backend" - Author: "Qingtian Xie" + Author: "Qingtian Xie, Honix, RCqls" File: %draw.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 09b245d3ba..e840d26606 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 events handling" - Author: "Qingtian Xie" + Author: "Qingtian Xie, RCqls" File: %events.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 6a22982a11..7f945b6291 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 fonts management" - Author: "Qingtian Xie" + Author: "Qingtian Xie, Thiago Dourado de Andrade, RCqls" File: %font.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." @@ -10,143 +10,88 @@ Red/System [ } ] -;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget +;; First style development provided by Thiago Dourado de Andrade +#define GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 600 -make-font: func [ - face [red-object!] - font [red-object!] - return: [handle!] +add-to-string: func [ + string [c-string!] + format [c-string!] + value [handle!] + return: [c-string!] /local - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - css [c-string!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - hFont [handle!] - int [red-integer!] + temp [c-string!] ][ - values: object/get-values font - - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: + temp: g_strdup_printf [format string value] + g_free as handle! string + temp +] - ; release first - hFont: get-font-handle font - unless null? hFont [g_free hFont] +to-css-rgba: func [ + color [red-tuple!] ;-- needs to be a valid color tuple + return: [c-string!] ;-- rgba(r, g, b, a) format - Should be cleaned with g_free + /local + size [integer!] + r [integer!] + g [integer!] + b [integer!] + a [float!] + rgba [c-string!] + alpha [c-string!] +][ + size: TUPLE_SIZE?(color) - css: g_strdup_printf ["* {"] + r: color/array1 and FFh + g: (color/array1 >> 8) and FFh + b: (color/array1 >> 16) and FFh + a: 1.0 - unless null? face [ - bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR - if TYPE_OF(bgcolor) = TYPE_TUPLE [ - rgba: to-css-rgba bgcolor - css: add-to-string css "%s background-color: %s;" as handle! rgba - g_free as handle! rgba - ] + if size = 4 [ + a: (as-float 255 - color/array1 >>> 24) / 255.0 ] - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - name: unicode/to-utf8 str :len - css: g_strdup_printf [{%s font-family: "%s";} css name] - ] + alpha: as c-string! allocate G_ASCII_DTOSTR_BUF_SIZE + g_ascii_dtostr alpha G_ASCII_DTOSTR_BUF_SIZE a - if TYPE_OF(size) = TYPE_INTEGER [ - css: add-to-string css "%s font-size: %dpt;" as handle! size/value - ] + rgba: g_strdup_printf ["rgba(%d, %d, %d, %s)" r g b alpha] - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk - ] - TYPE_WORD [1] - default [0] - ] + free as byte-ptr! alpha - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ - sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold;" css]] - sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] - sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration-line: underline;" css]] - sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration-line: line-through;" css]] - true [""] - ] - style: style + 1 - ] - ] + rgba +] - if TYPE_OF(color) = TYPE_TUPLE [ - rgba: to-css-rgba color - css: add-to-string css "%s color: %s;" as handle! rgba - g_free as handle! rgba - ] - css: add-to-string css "%s}" null +;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget - ;; DEBUG: print ["make font -> css: " css lf] +make-font: func [ + face [red-object!] + font [red-object!] + return: [handle!] + /local + values [red-value!] + blk [red-block!] + css [c-string!] + hFont [handle!] +][ + ; no more deal with different styles but only font via pango_font_description (excluding color, underline, strike) + hFont: font-description font - hFont: as handle! css + set-font-handle font hFont - blk: as red-block! values + FONT_OBJ_STATE - either TYPE_OF(blk) <> TYPE_BLOCK [ - block/make-at blk 2 - handle/make-in blk as-integer hFont - ][ - int: as red-integer! block/rs-head blk - int/header: TYPE_HANDLE - int/value: as-integer hFont - ] + values: object/get-values font if face <> null [ blk: block/make-at as red-block! values + FONT_OBJ_PARENT 4 block/rs-append blk as red-value! face ] - hFont -] - -; Here, style provider is used as font provider -make-font-provider: func [ - widget [handle!] - /local - style [handle!] - provider [handle!] -][ - provider: gtk_css_provider_new - style: gtk_widget_get_style_context widget - - gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + ;; DEBUG: print ["font-description: " hFont lf] - g_object_set_qdata widget gtk-style-id provider + hFont ] -get-font-provider: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget gtk-style-id -] - - - get-font-handle: func [ font [red-object!] + idx [integer!] return: [handle!] /local state [red-block!] @@ -155,24 +100,61 @@ get-font-handle: func [ state: as red-block! (object/get-values font) + FONT_OBJ_STATE if TYPE_OF(state) = TYPE_BLOCK [ int: as red-integer! block/rs-head state - if TYPE_OF(int) = TYPE_INTEGER [ + if TYPE_OF(int) = TYPE_HANDLE [ return as handle! int/value ] ] null ] +free-font-handle: func [ + hFont [handle!] +][ + pango_font_description_free hFont +] + free-font: func [ font [red-object!] /local state [red-block!] hFont [handle!] ][ - hFont: get-font-handle font + hFont: get-font-handle font 0 if hFont <> null [ state: as red-block! (object/get-values font) + FONT_OBJ_STATE state/header: TYPE_NONE ] + free-font-handle hFont +] + +set-font-handle: func [ + font [red-object!] + hFont [handle!] + /local + values [red-value!] + blk [red-block!] + state [red-block!] + int [red-integer!] + hFontP [handle!] +][ + ; release previous hFont first + hFontP: get-font-handle font 0 + unless null? hFontP [ + free-font-handle hFontP + ] + + values: object/get-values font + + blk: as red-block! values + FONT_OBJ_STATE + either TYPE_OF(blk) <> TYPE_BLOCK [ + block/make-at blk 2 + handle/make-in blk as-integer hFont + ][ + int: as red-integer! block/rs-head blk + int/header: TYPE_HANDLE + int/value: as-integer hFont + ] + ] update-font: func [ @@ -238,6 +220,7 @@ font-description: func [ pango_font_description_set_family fd name fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] + ;; DEBUG: print ["font-description: fsize -> " fsize lf] pango_font_description_set_size fd fsize * PANGO_SCALE len: switch TYPE_OF(style) [ @@ -274,6 +257,115 @@ font-description: func [ fd ] +;; Styles initiated by Thiago Dourado de Andrade (used in change-font) +; Here, style provider is used as font provider +make-styles-provider: func [ + widget [handle!] + /local + style [handle!] + provider [handle!] +][ + provider: gtk_css_provider_new + style: gtk_widget_get_style_context widget + + gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + + g_object_set_qdata widget gtk-style-id provider +] + +get-styles-provider: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget gtk-style-id +] + +css-styles: func [ + face [red-object!] + font [red-object!] + return: [c-string!] + /local + values [red-value!] + blk [red-block!] + style [red-word!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + css [c-string!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] +][ + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + css: g_strdup_printf ["* {"] + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + css: g_strdup_printf [{%s font-family: "%s";} css name] + ] + + if TYPE_OF(size) = TYPE_INTEGER [ + css: add-to-string css "%s font-size: %dpt;" as handle! size/value + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold; " css]] + sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] + sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration: underline;" css]] + sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration: line-through;" css]] + true [""] + ] + style: style + 1 + ] + ] + + if TYPE_OF(color) = TYPE_TUPLE [ + rgba: to-css-rgba color + css: add-to-string css "%s color: %s;" as handle! rgba + g_free as handle! rgba + ] + + ;; Further styles from face + unless null? face [ + bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR + if TYPE_OF(bgcolor) = TYPE_TUPLE [ + rgba: to-css-rgba bgcolor + css: add-to-string css "%s background-color: %s;" as handle! rgba + g_free as handle! rgba + ] + ] + + css: add-to-string css "%s}" null + + ;; DEBUG: print ["css-styles -> css: " css lf] + + css +] ; Stuff maybe to REMOVE related to cairo without any success ; #enum cairo_font_slant_t! [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 1e24cbdf43..61833b7dc1 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 imports" - Author: "Qingtian Xie" + Author: "Qingtian Xie, RCqls" File: %gtk.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." @@ -611,6 +611,15 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] mask [integer!] ] + gtk_widget_override_font: "gtk_widget_override_font" [ + widget [handle!] + fd [handle!] + ] + gtk_widget_override_color: "gtk_widget_override_color" [ + widget [handle!] + state [integer!] + color [handle!] + ] gtk_container_add: "gtk_container_add" [ container [handle!] widget [handle!] @@ -951,6 +960,11 @@ cairo_font_extents_t!: alias struct! [ gtk_style_context_get: "gtk_style_context_get" [ [variadic] ] + gtk_style_context_get_font: "gtk_style_context_get_font" [ + context [handle!] + type [integer!] + return: [handle!] + ] gtk_widget_get_style_context: "gtk_widget_get_style_context" [ widget [handle!] return: [handle!] @@ -983,6 +997,10 @@ cairo_font_extents_t!: alias struct! [ str [c-string!] return: [handle!] ] + pango_font_description_to_string: "pango_font_description_from_string" [ + fontdesc [handle!] + return: [c-string!] + ] pango_font_description_set_family: "pango_font_description_set_family" [ fontdesc [handle!] name [c-string!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 26912b963a..c3167cc111 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 GUI backend" - Author: "Qingtian Xie" + Author: "Qingtian Xie, RCqls, Thiago Dourado de Andrade" File: %gui.reds Tabs: 4 Rights: "Copyright (C) 2015 Qingtian Xie. All rights reserved." @@ -14,7 +14,6 @@ Red/System [ #include %gtk.reds #include %events.reds -#include %style.reds #include %font.reds #include %para.reds #include %draw.reds @@ -30,6 +29,7 @@ red-face-id: 0 _widget-id: 1 gtk-fixed-id: 2 red-timer-id: 3 +css-id: 4 gtk-style-id: 0 @@ -54,6 +54,7 @@ _on-over: word/load "on-over" pango-context: as handle! 0 gtk-font: "Sans 10" +default-font: 0 ; Do not KNOW about this one ;;;main-window: as handle! 0 @@ -185,7 +186,7 @@ get-child-from-xy: func [ get-text-size: func [ face [red-object!] str [red-string!] - font [red-object!] + hFont [handle!] pair [red-pair!] return: [tagSIZE] /local @@ -195,7 +196,6 @@ get-text-size: func [ height [integer!] pl [handle!] size [tagSIZE] - fd [handle!] df [c-string!] ][ if null? pango-context [pango-context: gdk_pango_context_get] @@ -210,24 +210,15 @@ get-text-size: func [ width: 0 height: 0 - ; @@ TO REMOVE since font-description manages directly none value for font - ;fd: either TYPE_OF(font) = TYPE_NONE [ - ; pango_font_description_from_string gtk-font - ;][ - ; font-description font - ;] - - ; The lines above replaced with - fd: font-description font - pl: pango_layout_new pango-context pango_layout_set_text pl text -1 - pango_layout_set_font_description pl fd + pango_layout_set_font_description pl hFont pango_layout_get_pixel_size pl :width :height - + g_object_unref pl + size/width: width size/height: height - ;print ["text: " text " w: " width " h: " height lf] + if pair <> null [ pair/x: size/width pair/y: size/height @@ -377,7 +368,6 @@ init: func [][ screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height - style-init ] get-symbol-name: function [ @@ -650,15 +640,23 @@ change-font: func [ /local css [c-string!] provider [handle!] + hFont [handle!] ][ if TYPE_OF(font) <> TYPE_OBJECT [return no] - provider: get-font-provider hWnd + provider: get-styles-provider hWnd + + ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles + css: "" + css: css-styles face font - css: as c-string! make-font face font + ;; DEBUG: print ["change-font ccs: " css lf] gtk_css_provider_load_from_data provider css -1 null + ;; Update the pango_font_description hFont (directly used by get-text-size) + make-font face font + yes ] @@ -1522,8 +1520,10 @@ OS-make-view: func [ ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - make-font-provider widget - if sym <> base [change-font widget face font sym] + make-styles-provider widget + if sym <> base [ + change-font widget face font sym + ] ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 47b7e15b82..526846aba1 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 widget handlers" - Author: "Qingtian Xie" + Author: "Qingtian Xie, RCqls" File: %handlers.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." diff --git a/modules/view/backends/gtk3/style.reds b/modules/view/backends/gtk3/style.reds deleted file mode 100644 index e7d1b16abd..0000000000 --- a/modules/view/backends/gtk3/style.reds +++ /dev/null @@ -1,196 +0,0 @@ -Red/System [ - Title: "GTK3 widget style management" - Author: "Thiago Dourado de Andrade" - File: %style.reds - Tabs: 4 - Rights: "Copyright (C) 2016 Thiago Dourado de Andrade. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -#define GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 600 - -css-style: { - .bold { - font-weight: bold; - } - - .italic { - font-style: italic; - } -} - -style-init: func [ - /local - provider [handle!] - screen [handle!] -][ - screen: gdk_screen_get_default - provider: gtk_css_provider_new - - gtk_css_provider_load_from_data provider css-style -1 null - - gtk_style_context_add_provider_for_screen screen provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - -] - -add-to-string: func [ - string [c-string!] - format [c-string!] - value [handle!] - return: [c-string!] - /local - temp [c-string!] -][ - temp: g_strdup_printf [format string value] - g_free as handle! string - temp -] - -to-css-rgba: func [ - color [red-tuple!] ;-- needs to be a valid color tuple - return: [c-string!] ;-- rgba(r, g, b, a) format - Should be cleaned with g_free - /local - size [integer!] - r [integer!] - g [integer!] - b [integer!] - a [float!] - rgba [c-string!] - alpha [c-string!] -][ - size: TUPLE_SIZE?(color) - - r: color/array1 and FFh - g: (color/array1 >> 8) and FFh - b: (color/array1 >> 16) and FFh - a: 1.0 - - if size = 4 [ - a: (as-float 255 - color/array1 >>> 24) / 255.0 - ] - - alpha: as c-string! allocate G_ASCII_DTOSTR_BUF_SIZE - g_ascii_dtostr alpha G_ASCII_DTOSTR_BUF_SIZE a - - rgba: g_strdup_printf ["rgba(%d, %d, %d, %s)" r g b alpha] - - free as byte-ptr! alpha - - rgba -] - -get-style-provider: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget gtk-style-id -] - -create-widget-style: func [ - widget [handle!] - face [red-object!] - /local - context [handle!] - provider [handle!] -][ - provider: gtk_css_provider_new - context: gtk_widget_get_style_context widget - - gtk_style_context_add_provider context provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - - g_object_set_qdata widget gtk-style-id provider - - set-widget-style widget face -] - -set-widget-style: func [ - widget [handle!] - face [red-object!] - /local - font [red-object!] - values [red-value!] - context [handle!] - provider [handle!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - css [c-string!] - color [red-tuple!] - rgba [c-string!] -][ - values: object/get-values face - - font: as red-object! values + FACE_OBJ_FONT - - if TYPE_OF(font) = TYPE_OBJECT [ - values: object/get-values font - - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - css: g_strdup_printf ["* {"] - context: gtk_widget_get_style_context widget - provider: get-style-provider widget - - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - name: unicode/to-utf8 str :len - css: g_strdup_printf [{%s font-family: "%s";} css name] - ] - - if TYPE_OF(size) = TYPE_INTEGER [ - css: add-to-string css "%s font-size: %dpt;" as handle! size/value - ] - - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk - ] - TYPE_WORD [1] - default [0] - ] - - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ ;OLD -> class: case [ - sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold;" css]] - sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] - sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration-line: underline;" css]] - sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration-line: line-through;" css]] - true [""] - ] - style: style + 1 - ;unless 0 = length? class [gtk_style_context_add_class context class] - ] - ] - - if TYPE_OF(color) = TYPE_TUPLE [ - rgba: to-css-rgba color - css: add-to-string css "%s color: %s;" as handle! rgba - g_free as handle! rgba - ] - - css: add-to-string css "%s}" null - - print ["css: " css lf] - - gtk_css_provider_load_from_data provider css -1 null - - g_free as handle! css - ] -] diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 9976fd15b7..03320c6078 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -572,12 +572,7 @@ system/view/platform: context [ ] pair: as red-pair! stack/arguments pair/header: TYPE_PAIR - - ;GTK branch: gui/get-text-size face text hFont pair - #switch OS [ - Linux [gui/get-text-size face text font pair] - #default [gui/get-text-size face text hFont pair] - ] + gui/get-text-size face text hFont pair ] on-change-facet: routine [ From 172f5d76e55cc36c9d16a45fc17fdc6c6685d84e Mon Sep 17 00:00:00 2001 From: rcqls Date: Thu, 27 Jun 2019 16:17:43 +0200 Subject: [PATCH 0093/3432] A preliminary useable version of red/GTK --- build/includes.r | 8 +- modules/view/backends/gtk3/comdlgs.reds | 13 +- modules/view/backends/gtk3/draw.reds | 682 +++++++--- modules/view/backends/gtk3/events.reds | 835 ++++++++++-- modules/view/backends/gtk3/font.reds | 593 +++++++-- modules/view/backends/gtk3/gtk.reds | 1494 +++++++++++++++++++++- modules/view/backends/gtk3/gui.reds | 1373 +++++++++++++------- modules/view/backends/gtk3/handlers.reds | 670 ++++++++-- modules/view/backends/gtk3/menu.reds | 165 +++ modules/view/backends/gtk3/para.reds | 148 ++- modules/view/backends/gtk3/text-box.reds | 687 ++++++++-- runtime/collector.reds | 2 +- runtime/definitions.reds | 19 +- runtime/platform/image-gdk.reds | 689 +++++++--- 14 files changed, 6075 insertions(+), 1303 deletions(-) create mode 100644 modules/view/backends/gtk3/menu.reds diff --git a/build/includes.r b/build/includes.r index 7efbf8a7b5..5069674fac 100644 --- a/build/includes.r +++ b/build/includes.r @@ -221,13 +221,15 @@ write %build/bin/sources.r set-cache [ ] %gtk3/ [ %comdlgs.reds - %font.reds - %gui.reds %draw.reds - %handlers.reds %events.reds + %font.reds %gtk.reds + %gui.reds + %handlers.reds + %menu.reds %para.reds + %rules.red %text-box.reds ] %test/ [ diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index bf3d63f8cd..961ba36ec9 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -10,6 +10,14 @@ Red/System [ } ] +request-file-double-clicked: func [ + [cdecl] + widget [handle!] + ctx [node!] +][ + gtk_dialog_response widget GTK_RESPONSE_ACCEPT +] + _request-file: func [ title [red-string!] path [red-file!] @@ -28,9 +36,10 @@ _request-file: func [ ret [red-value!] ][ ret: as red-value! none-value - widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" 5 "Open" 2 null] + widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" GTK_RESPONSE_CANCEL "Open" GTK_RESPONSE_ACCEPT null] + gobj_signal_connect(widget "file-activated" :request-file-double-clicked null) resp: gtk_dialog_run widget - if resp = 2 [ + if resp = GTK_RESPONSE_ACCEPT [ cstr: gtk_file_chooser_get_filename widget size: length? cstr str: string/load cstr size UTF-8 diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index b0d0220958..7c0e6e4d3b 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -12,7 +12,7 @@ Red/System [ #include %text-box.reds -draw-state!: alias struct! [unused [integer!]] +draw-state!: alias struct! [mat [handle!]] set-source-color: func [ cr [handle!] @@ -29,32 +29,49 @@ set-source-color: func [ g: g / 255.0 b: as-float color >> 16 and FFh b: b / 255.0 - a: as-float 255 - (color >>> 24) - a: a / 255.0 + a: as-float color >> 24 and FFh + a: 1.0 - (a / 255.0) cairo_set_source_rgba cr r g b a ] -draw-begin: func [ - ctx [draw-ctx!] - cr [handle!] - img [red-image!] - on-graphic? [logic!] - paint? [logic!] - return: [draw-ctx!] +;; TODO: only used for rich-text that I think need much less than that +;; certainly create +init-draw-ctx: func [ + ctx [draw-ctx!] + cr [handle!] ][ ctx/raw: cr ctx/pen-width: 1.0 ctx/pen-style: 0 ctx/pen-color: 0 ;-- default: black - ctx/pen-join: miter - ctx/pen-cap: flat + ;ctx/pen-join: miter + ;ctx/pen-cap: flat ctx/brush-color: 0 ctx/font-color: 0 ctx/pen?: yes ctx/brush?: no ctx/pattern: null + + ctx/font-desc: null ;default-font + ctx/layout: null ; make-pango-cairo-layout cr ctx/font-desc + ctx/font-opts: null + ctx/font-underline?: no + ctx/font-strike?: no +] + +draw-begin: func [ + ctx [draw-ctx!] + cr [handle!] + img [red-image!] + on-graphic? [logic!] + pattern? [logic!] + return: [draw-ctx!] +][ + ;; DEBUG: print ["draw-begin : " on-graphic? " " pattern? lf] + init-draw-ctx ctx cr cairo_set_line_width cr 1.0 + ;; DEBUG: print ["draw-begin: set-source-color black" lf] set-source-color cr 0 ctx ] @@ -64,13 +81,15 @@ draw-end: func [ hWnd [handle!] on-graphic? [logic!] cache? [logic!] - paint? [logic!] + pattern? [logic!] ][ - 0 + cairo_identity_matrix dc/raw + free-pango-cairo-font dc ] do-paint: func [dc [draw-ctx!] /local cr [handle!]][ cr: dc/raw + ;; DEBUG: print ["do-paint: " dc/brush? " " dc/pen? lf] if dc/brush? [ cairo_save cr either null? dc/pattern [ @@ -86,15 +105,17 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ cairo_restore cr ] if dc/pen? [ + ;; DEBUG: print ["do-paint dc/pen? color " dc/pen-color lf] cairo_stroke cr ] + ] OS-draw-anti-alias: func [ dc [draw-ctx!] on? [logic!] ][ -0 + cairo_set_antialias dc/raw either on? [CAIRO_ANTIALIAS_GOOD][CAIRO_ANTIALIAS_NONE] ] OS-draw-line: func [ @@ -119,10 +140,13 @@ OS-draw-pen: func [ alpha? [logic!] ][ dc/pen?: not off? - if dc/pen-color <> color [ + ;; DEBUG: print ["OS-draw-pen: " not off? " with color " color lf ] + ;; THIS if DOES NOT WORK: + ;; if dc/pen-color <> color [ dc/pen-color: color + ;; DEBUG: print ["set-source-color" lf] set-source-color dc/raw color - ] + ;;] ] OS-draw-fill-pen: func [ @@ -160,25 +184,45 @@ OS-draw-box: func [ lower [red-pair!] /local radius [red-integer!] - rad [integer!] + ; t [integer!] + rad [float!] x [float!] y [float!] w [float!] h [float!] + degrees [float!] ][ - either TYPE_OF(lower) = TYPE_INTEGER [ + radius: null + if TYPE_OF(lower) = TYPE_INTEGER [ radius: as red-integer! lower lower: lower - 1 - rad: radius/value * 2 - ;;@@ TBD round box + ] + + ; if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t] + ; if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t] + + x: as-float upper/x + y: as-float upper/y + w: as-float lower/x - upper/x + h: as-float lower/y - upper/y + + either radius <> null [ + ; t: as-integer either w > h [h][w] + ; rad: as-float either radius/value * 2 > t [t / 2][radius/value] + + rad: as-float radius/value * 2 + degrees: pi / 180.0 + ;; TODO: not sure it is a the right version but it at least works! + cairo_new_sub_path dc/raw + cairo_arc dc/raw x + w - rad y + rad rad -90.0 * degrees 0.0 * degrees + cairo_arc dc/raw x + w - rad y + h - rad rad 0.0 * degrees 90.0 * degrees + cairo_arc dc/raw x + rad y + h - rad rad 90.0 * degrees 180.0 * degrees + cairo_arc dc/raw x + rad y + rad rad 180.0 * degrees 270.0 * degrees + cairo_close_path dc/raw ][ - x: as-float upper/x - y: as-float upper/y - w: as-float lower/x - upper/x - h: as-float lower/y - upper/y cairo_rectangle dc/raw x y w h - do-paint dc ] + do-paint dc ] OS-draw-triangle: func [ @@ -381,117 +425,166 @@ OS-draw-ellipse: func [ do-paint dc ] -; move this to draw-ctx? -font-size: 10.0 ;-- used to find top line +;;; TODO: Remove this when pango-cairo is the only choice! SOON! +; pango-font?: yes ; switch to yes to switch to pango-cairo instead of toy cairo OS-draw-font: func [ dc [draw-ctx!] font [red-object!] +][ + ; either pango-font? [ + make-pango-cairo-font dc font + ; ][ + ; make-cairo-draw-font dc font + ; ] +] + +draw-text-at: func [ + dc [draw-ctx!] + text [red-string!] + color [integer!] + x [integer!] + y [integer!] /local - cr [handle!] - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - css [c-string!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - slant [integer!] - weight [integer!] - extents [cairo_font_extents_t!] + len [integer!] + str [c-string!] + ctx [handle!] + pl [handle!] + width [integer!] + height [integer!] + size [integer!] ][ - cr: dc/raw + ctx: dc/raw - values: object/get-values font + len: -1 + str: unicode/to-utf8 text :len + ;; print ["draw-text-at: " str " at " x "x" y lf] + ; either pango-font? [ + ;; print ["draw-text-at: dc/layout: " dc/layout lf] + if null? dc/layout [ + dc/font-desc: pango_font_description_from_string gtk-font + dc/layout: make-pango-cairo-layout ctx dc/font-desc + ] + ;pango-cairo-set-text dc str + pango-layout-context-set-text dc/layout dc str + ;; print ["pango-cairo-set-text: " dc " " str lf] + set-source-color ctx color + ;; print ["set-source-color: " ctx " " color lf] + + pango_cairo_update_layout ctx dc/layout + + size: 0 + size: pango_font_description_get_size dc/font-desc + ;; DEBUG: print ["pango_font_description_get_size: dc/font-desc: " dc/font-desc " size: " size lf] + cairo_move_to ctx as-float x + (as-float y) + ((as-float size) / PANGO_SCALE) + pl: pango_layout_get_line_readonly dc/layout 0 + pango_cairo_show_layout_line ctx pl + + ;pango_cairo_show_layout ctx dc/layout - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: + do-paint dc - dc/font-color: color/array1 +] - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - name: unicode/to-utf8 str :len - ] +draw-text-box-lines: func [ + dc [draw-ctx!] + line [c-string!] + pos [red-pair!] + size [red-pair!] + tbox [red-object!] + /local + lc [layout-ctx!] + ctx [handle!] + clr [integer!] + pl [handle!] + width [integer!] + height [integer!] + sizef [float!] + gstr [GString!] + irect [tagRECT value] + lrect [tagRECT value] +][ + ctx: dc/raw - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk - ] - TYPE_WORD [1] - default [0] + clr: either null? dc [0][ + ;;TODO: objc_msgSend [dc/font-attrs sel_getUid "objectForKey:" NSForegroundColorAttributeName] + dc/font-color ] - slant: CAIRO_FONT_SLANT_NORMAL - weight: CAIRO_FONT_WEIGHT_NORMAL - - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ - sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] - sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] - sym = _underline [] - sym = _strike [] - true [] - ] - style: style + 1 - ] - ] + lc: either TYPE_OF(tbox) = TYPE_OBJECT [ + ;; DEBUG: print ["draw-text-box-lines: " as int-ptr! dc lf] ;-- text-box! + as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes + ][ + null + ] - cairo_select_font_face cr name slant weight + unless null? lc/layout [ - if TYPE_OF(size) = TYPE_INTEGER [ - extents: declare cairo_font_extents_t! - cairo_font_extents cr extents + pango-layout-set-text lc size - font-size: as-float size/value - cairo_set_font_size cr font-size * ((extents/ascent + extents/descent) / extents/ascent) + set-source-color ctx clr + ;; DEBUG: print ["set-source-color: " ctx " " clr lf] + + cairo_move_to ctx as-float pos/x (as-float pos/y) ; + sizef + pango_cairo_show_layout ctx lc/layout - ; This technique is little more correct for me. - ; This Red example will show the difference: - ; - ; f: make font! [name: "Arial" size: 120] - ; view [base 140x140 draw [font f text 10x10 "A" pen white box 0x10 140x130]] + free-pango-cairo-font dc + + ;; DEBUG: print ["free pango" lf] + do-paint dc ] ] -OS-draw-text: func [ + +draw-text-box: func [ dc [draw-ctx!] pos [red-pair!] - text [red-string!] + tbox [red-object!] catch? [logic!] - return: [logic!] /local - ctx [handle!] - len [integer!] + values [red-value!] + text [red-string!] + lc [layout-ctx!] + len [integer!] str [c-string!] + size [red-pair!] ][ - ctx: dc/raw + ;; DEBUG: print ["draw-text-box: " tbox lf] + values: object/get-values tbox + text: as red-string! values + FACE_OBJ_TEXT + if TYPE_OF(text) <> TYPE_STRING [exit] + + size: as red-pair! values + FACE_OBJ_SIZE + + ;; DEBUG: print ["pos : " pos/x "x" pos/y " size: " size/x "x" size/y lf] + len: -1 str: unicode/to-utf8 text :len - cairo_move_to ctx as-float pos/x - (as-float pos/y) + font-size - set-source-color dc/raw dc/font-color - cairo_show_text ctx str + dc/font-desc: pango_font_description_from_string gtk-font + ;;TORM: dc/layout: make-pango-cairo-layout dc/raw dc/font-desc + + ;; DEBUG: print ["draw-text-box text: " str " dc/font-desc: " dc/font-desc lf] + draw-text-box-lines dc str pos size tbox +] - do-paint dc +OS-draw-text: func [ + dc [draw-ctx!] + pos [red-pair!] + text [red-string!] + catch? [logic!] + return: [logic!] +][ + either TYPE_OF(text) = TYPE_STRING [ + draw-text-at dc text dc/font-color pos/x pos/y + ][ + ;; DEBUG: print ["OS-draw-text: " pos/x "x" pos/y lf] + draw-text-box dc pos as red-object! text catch? + ] - set-source-color dc/raw dc/pen-color ;-- backup pen color - yes + ;; DEBUG: print ["OS-draw-text end" lf] + true ] OS-draw-arc: func [ @@ -532,10 +625,16 @@ OS-draw-arc: func [ closed?: angle < end cairo_save ctx + unless closed? [dc/brush?: no] cairo_translate ctx cx cy cairo_scale ctx rad-x rad-y - cairo_arc ctx 0.0 0.0 1.0 angle-begin angle-end + either sweep < 0 [ + cairo_arc_negative ctx 0.0 0.0 1.0 angle-begin angle-end + ][ + cairo_arc ctx 0.0 0.0 1.0 angle-begin angle-end + ] if closed? [ + cairo_line_to ctx 0.0 0.0 cairo_close_path ctx ] cairo_restore ctx @@ -618,12 +717,14 @@ GDK-draw-image: func [ /local img [handle!] ][ + ;; DEBUG: print ["GDK-draw-image " width " handle " image lf] img: either width = 0 [image][gdk_pixbuf_scale_simple image width height 2] - ;; DEBUG: print ["GDK-draw-image: " x "x" y lf] + ;; DEBUG: print ["GDK-draw-image: " x "x" y "x" width "x" height lf] cairo_translate cr as-float x as-float y gdk_cairo_set_source_pixbuf cr img 0 0 cairo_paint cr cairo_translate cr as-float (0 - x) as-float (0 - y) + if width > 0 [g_object_unref img] ] OS-draw-image: func [ @@ -636,23 +737,37 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local - img [integer!] - sub-img [integer!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - w [float!] - h [float!] - ww [float!] - crop2 [red-pair!] + cr [handle!] + img [int-ptr!] + bitmap [integer!] + stride [integer!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + w [float!] + h [float!] + crop_x [float!] + crop_y [float!] + crop2 [red-pair!] + crop_cr [handle!] + crop_surf [handle!] + crop_xscale [float!] + crop_yscale [float!] + format [cairo_format_t!] + img_w [float!] + img_h [float!] + crop_img_sx [integer!] + crop_img_sy [integer!] ][ - ;; print ["OS-draw-image" lf] + ;; DEBUG: print ["OS-draw-image" lf] + img_w: as float! IMAGE_WIDTH(image/size) + img_h: as float! IMAGE_HEIGHT(image/size) either null? start [x: 0 y: 0][x: start/x y: start/y] case [ start = end [ - width: IMAGE_WIDTH(image/size) - height: IMAGE_HEIGHT(image/size) + width: as integer! img_w + height: as integer! img_h ] start + 1 = end [ ;-- two control points width: end/x - x @@ -661,24 +776,46 @@ OS-draw-image: func [ start + 2 = end [0] ;@@ TBD three control points true [0] ;@@ TBD four control points ] - - ;; DEBUG: print ["OS-draw-image: " x "x" y " " width "x" height lf] + cr: dc/raw + ;; DEBUG: print ["OS-draw-image: " x "x" y " " width "x" height lf "image: " image lf "original: " IMAGE_WIDTH(image/size) "x" IMAGE_HEIGHT(image/size) lf] img: OS-image/to-pixbuf image - if crop1 <> null [ + + either crop1 <> null [ + ;; DEBUG: print ["crop1: " crop1/x "x" crop1/y lf] + crop_x: as float! crop1/x + crop_y: as float! crop1/y crop2: crop1 + 1 w: as float! crop2/x h: as float! crop2/y - ww: w / h * (as float! height) - width: as-integer ww - ; create new pixbuf - sub-img: as-integer gdk_pixbuf_scale_simple as handle! img width height 0 ; to correct parameters!!! - ;sub-img: as-integer gdk_pixbuf_new 0 yes 8 width height - ;gdk_pixbuf_scale as handle! img as handle! sub-img 0 0 width height 0.0 0.0 1.0 1.0 0 ; to correct parameters!!! - ] + crop_xscale: w / (as float! width) + crop_yscale: h / (as float! height) + crop_img_sx: as integer! (img_w / crop_xscale) + crop_img_sy: as integer! (img_h / crop_yscale) + ;width: as-integer (w / h * (as float! height)) + ;; DEBUG: print ["cropping dest: " crop_x "x" crop_y "x" w "x" h " img size: " crop_img_sx "x" crop_img_sy lf] + img: gdk_pixbuf_scale_simple img crop_img_sx crop_img_sy 2 + format: CAIRO_FORMAT_RGB24 ;either 3 = gdk_pixbuf_get_n_channels img [CAIRO_FORMAT_RGB24][CAIRO_FORMAT_ARGB32] + ;; DEBÙG: print ["pixbuf format: " format lf] + crop_surf: cairo_image_surface_create format crop_img_sx crop_img_sy + crop_cr: cairo_create crop_surf + gdk_cairo_set_source_pixbuf crop_cr img 0 0 + cairo_paint crop_cr + cairo_destroy crop_cr - GDK-draw-image dc/raw as handle! img x y width height - if crop1 <> null [g_object_unref as handle! sub-img] + cairo_save cr + cairo_translate cr as-float x as-float y + cairo_set_source_surface cr crop_surf (0.0 - (crop_x / crop_xscale)) (0.0 - (crop_y / crop_yscale)) + cairo_rectangle cr 0.0 0.0 as float! width as float! height + cairo_fill cr + cairo_translate cr as-float (0 - x) as-float (0 - y) + cairo_restore cr + + cairo_surface_destroy crop_surf + g_object_unref img + ][ + GDK-draw-image cr img x y width height + ] ] OS-draw-grad-pen-old: func [ @@ -791,11 +928,15 @@ OS-matrix-rotate: func [ ][ cr: dc/raw rad: PI / 180.0 * get-float angle - cairo_translate cr as float! center/x + if angle <> as red-integer! center [ + cairo_translate cr as float! center/x as float! center/y + ] cairo_rotate cr rad - cairo_translate cr as float! (0 - center/x) - as float! (0 - center/y) + if angle <> as red-integer! center [ + cairo_translate cr as float! (0 - center/x) + as float! (0 - center/y) + ] ] OS-matrix-scale: func [ @@ -861,11 +1002,13 @@ OS-matrix-transform: func [ OS-matrix-translate dc pen translate/x translate/y ] -OS-matrix-push: func [dc [draw-ctx!] /local state [integer!]][ - state: 0 +OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ +cairo_save dc/raw ] -OS-matrix-pop: func [dc [draw-ctx!]][0] +OS-matrix-pop: func [dc [draw-ctx!] state [draw-state!]][ + cairo_restore dc/raw +] OS-matrix-reset: func [ dc [draw-ctx!] @@ -887,11 +1030,18 @@ OS-matrix-set: func [ pen [integer!] blk [red-block!] /local - m [integer!] + m [cairo_matrix_t! value] val [red-integer!] ][ - m: 0 + m: null val: as red-integer! block/rs-head blk + m/xx: get-float val + m/yx: get-float val + 1 + m/xy: get-float val + 2 + m/yy: get-float val + 3 + m/x0: get-float val + 4 + m/y0: get-float val + 5 + cairo_transform dc/raw :m ; Weirdly it is not cairo_set_matrix because it is a global change! ] OS-set-matrix-order: func [ @@ -906,25 +1056,24 @@ OS-set-clip: func [ upper [red-pair!] lower [red-pair!] ][ + print ["set-clip!" lf] + 0 ] ;-- shape sub command -- OS-draw-shape-beginpath: func [ dc [draw-ctx!] - /local - path [integer!] -][ - +][ ] OS-draw-shape-endpath: func [ dc [draw-ctx!] close? [logic!] return: [logic!] - /local - alpha [byte!] ][ + if close? [cairo_close_path dc/raw] + do-paint dc true ] @@ -932,8 +1081,18 @@ OS-draw-shape-moveto: func [ dc [draw-ctx!] coord [red-pair!] rel? [logic!] + /local + x [float!] + y [float!] ][ - + x: as-float coord/x + y: as-float coord/y + either rel? [ + cairo_rel_move_to dc/raw x y + ][ + cairo_move_to dc/raw x y + ] + dc/shape-curve?: no ] OS-draw-shape-line: func [ @@ -941,8 +1100,22 @@ OS-draw-shape-line: func [ start [red-pair!] end [red-pair!] rel? [logic!] + /local + x [float!] + y [float!] ][ - + until [ + x: as-float start/x + y: as-float start/y + either rel? [ + cairo_rel_line_to dc/raw x y + ][ + cairo_line_to dc/raw x y + ] + start: start + 1 + start > end + ] + dc/shape-curve?: no ] OS-draw-shape-axis: func [ @@ -950,17 +1123,105 @@ OS-draw-shape-axis: func [ start [red-value!] end [red-value!] rel? [logic!] - hline [logic!] + hline? [logic!] + /local + len [float!] + last-x [float!] + last-y [float!] ][ - + last-x: 0.0 last-y: 0.0 + if 1 = cairo_has_current_point dc/raw[ + cairo_get_current_point dc/raw :last-x :last-y + ] + len: get-float as red-integer! start + either hline? [ + cairo_line_to dc/raw either rel? [last-x + len][len] last-y + ][ + cairo_line_to dc/raw last-x either rel? [last-y + len][len] + ] + dc/shape-curve?: no ] +draw-curve: func [ + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + short? [logic!] + num [integer!] ;-- number of points + /local + dx [float!] + dy [float!] + p3y [float!] + p3x [float!] + p2y [float!] + p2x [float!] + p1y [float!] + p1x [float!] + pf [float-ptr!] + pt [red-pair!] +][ + pt: start + 1 + p1x: as-float start/x + p1y: as-float start/y + p2x: as-float pt/x + p2y: as-float pt/y + if num = 3 [ ;-- cubic Bézier + pt: start + 2 + p3x: as-float pt/x + p3y: as-float pt/y + ] + + ; dx: dc/last-pt-x + ; dy: dc/last-pt-y + ; if rel? [ + ; pf: :p1x + ; loop num [ + ; pf/1: pf/1 + dx ;-- x + ; pf/2: pf/2 + dy ;-- y + ; pf: pf + 2 + ; ] + ; ] + + ; if short? [ + ; either dc/shape-curve? [ + ; ;-- The control point is assumed to be the reflection of the control point + ; ;-- on the previous command relative to the current point + ; p1x: dx * 2.0 - dc/control-x + ; p1y: dy * 2.0 - dc/control-y + ; ][ + ; ;-- if previous command is not curve/curv/qcurve/qcurv, use current point + ; p1x: dx + ; p1y: dy + ; ] + ; ] + + dc/shape-curve?: yes + either num = 3 [ ;-- cubic Bézier + either rel? [cairo_rel_curve_to dc/raw p1x p1y p2x p2y p3x p3y] + [cairo_curve_to dc/raw p1x p1y p2x p2y p3x p3y] + ; dc/control-x: p2x + ; dc/control-y: p2y + ; dc/last-pt-x: p3x + ; dc/last-pt-y: p3y + ][ ;-- quadratic Bézier + ;CGPathAddQuadCurveToPoint dc/path null p1x p1y p2x p2y + ; dc/control-x: p1x + ; dc/control-y: p1y + ; dc/last-pt-x: p2x + ; dc/last-pt-y: p2y + 0 + ] +] + + OS-draw-shape-curve: func [ dc [draw-ctx!] start [red-pair!] end [red-pair!] rel? [logic!] ][ + draw-curve dc start end rel? no 3 ] OS-draw-shape-qcurve: func [ @@ -969,7 +1230,7 @@ OS-draw-shape-qcurve: func [ end [red-pair!] rel? [logic!] ][ - ;draw-curves dc start end rel? 2 + draw-curve dc start end rel? no 2 ] OS-draw-shape-curv: func [ @@ -978,7 +1239,7 @@ OS-draw-shape-curv: func [ end [red-pair!] rel? [logic!] ][ - ;draw-short-curves dc start end rel? 2 + draw-curve dc start - 1 end rel? yes 3 ] OS-draw-shape-qcurv: func [ @@ -987,7 +1248,7 @@ OS-draw-shape-qcurv: func [ end [red-pair!] rel? [logic!] ][ - ;draw-short-curves dc start end rel? 1 + draw-curve dc start - 1 end rel? yes 2 ] OS-draw-shape-arc: func [ @@ -996,13 +1257,120 @@ OS-draw-shape-arc: func [ sweep? [logic!] large? [logic!] rel? [logic!] + /local + ctx [handle!] + item [red-integer!] + last-x [float!] + last-y [float!] + center-x [float32!] + center-y [float32!] + cx [float32!] + cy [float32!] + cf [float32!] + angle-len [float32!] + radius-x [float32!] + radius-y [float32!] + theta [float32!] + X1 [float32!] + Y1 [float32!] + p1-x [float32!] + p1-y [float32!] + p2-x [float32!] + p2-y [float32!] + cos-val [float32!] + sin-val [float32!] + rx2 [float32!] + ry2 [float32!] + dx [float32!] + dy [float32!] + sqrt-val [float32!] + sign [float32!] + rad-check [float32!] + pi2 [float32!] ][ - + last-x: 0.0 last-y: 0.0 + if 1 = cairo_has_current_point dc/raw[ + cairo_get_current_point dc/raw :last-x :last-y + ] + p1-x: as float32! last-x p1-y: as float32! last-y + p2-x: either rel? [ p1-x + as float32! end/x ][ as float32! end/x ] + p2-y: either rel? [ p1-y + as float32! end/y ][ as float32! end/y ] + item: as red-integer! end + 1 + radius-x: fabsf get-float32 item + item: item + 1 + radius-y: fabsf get-float32 item + item: item + 1 + pi2: as float32! 2.0 * PI + theta: get-float32 item + theta: theta * as float32! (PI / 180.0) + theta: as-float32 fmod as-float theta as-float pi2 ; OLD: theta % pi2 + + ;-- calculate center + dx: (p1-x - p2-x) / as float32! 2.0 + dy: (p1-y - p2-y) / as float32! 2.0 + cos-val: cosf theta + sin-val: sinf theta + X1: (cos-val * dx) + (sin-val * dy) + Y1: (cos-val * dy) - (sin-val * dx) + rx2: radius-x * radius-x + ry2: radius-y * radius-y + rad-check: ((X1 * X1) / rx2) + ((Y1 * Y1) / ry2) + if rad-check > as float32! 1.0 [ + radius-x: radius-x * sqrtf rad-check + radius-y: radius-y * sqrtf rad-check + rx2: radius-x * radius-x + ry2: radius-y * radius-y + ] + either large? = sweep? [sign: as float32! -1.0 ][sign: as float32! 1.0 ] + sqrt-val: ((rx2 * ry2) - (rx2 * Y1 * Y1) - (ry2 * X1 * X1)) / ((rx2 * Y1 * Y1) + (ry2 * X1 * X1)) + either sqrt-val < as float32! 0.0 [cf: as float32! 0.0 ][ cf: sign * sqrtf sqrt-val ] + cx: cf * (radius-x * Y1 / radius-y) + cy: cf * (radius-y * X1 / radius-x) * (as float32! -1.0) + center-x: (cos-val * cx) - (sin-val * cy) + ((p1-x + p2-x) / as float32! 2.0) + center-y: (sin-val * cx) + (cos-val * cy) + ((p1-y + p2-y) / as float32! 2.0) + + + ;-- transform our ellipse into the unit circle + ; m: CGAffineTransformMakeScale (as float! 1.0) / radius-x (as float! 1.0) / radius-y + ; m: CGAffineTransformRotate m (as float! 0.0) - theta + ; m: CGAffineTransformTranslate m (as float! 0.0) - center-x (as float! 0.0) - center-y + + ; pt1/x: p1-x pt1/y: p1-y + ; pt2/x: p2-x pt2/y: p2-y + ; pt1: CGPointApplyAffineTransform pt1 m + ; pt2: CGPointApplyAffineTransform pt2 m + + ;-- calculate angles + cx: atan2f p1-y p1-x + cy: atan2f p2-y p2-x + angle-len: cy - cx + either sweep? [ + if angle-len < as float32! 0.0 [ + angle-len: angle-len + pi2 + ] + ][ + if angle-len > as float32! 0.0 [ + angle-len: angle-len - pi2 + ] + ] + + ;-- construct the inverse transform + ; m: CGAffineTransformMakeTranslation center-x center-y + ; m: CGAffineTransformRotate m theta + ; m: CGAffineTransformScale m radius-x radius-y + ; CGPathAddRelativeArc ctx/path :m as float32! 0.0 as float32! 0.0 as float32! 1.0 cx angle-len + ctx: dc/raw + cairo_save ctx + cairo_new_sub_path ctx + cairo_translate ctx as float! center-x as float! center-y + cairo_scale ctx as float! radius-x as float! radius-y + cairo_arc ctx 0.0 0.0 1.0 as float! cx as float! cy + cairo_restore ctx ] OS-draw-shape-close: func [ - ctx [draw-ctx!] -][] + dc [draw-ctx!] +][cairo_close_path dc/raw ] OS-draw-brush-bitmap: func [ ctx [draw-ctx!] diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e840d26606..6d7a9a5e62 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -10,23 +10,45 @@ Red/System [ } ] +;; In the GTK world, gboolean is a gint and the dispatching is as follows: #enum event-action! [ - EVT_NO_DISPATCH ;-- no further msg processing allowed - EVT_DISPATCH ;-- allow DispatchMessage call only + EVT_DISPATCH: 0 ;-- allow DispatchMessage call only + EVT_NO_DISPATCH ;-- no further msg processing allowed ] +#define GDK_BUTTON_PRIMARY 1 +#define GDK_BUTTON_MIDDLE 2 +#define GDK_BUTTON_SECONDARY 3 + gui-evt: declare red-event! ;-- low-level event value slot gui-evt/header: TYPE_EVENT -modal-loop-type: 0 ;-- remanence of last EVT_MOVE or EVT_SIZE -zoom-distance: 0 -special-key: -1 ;-- <> -1 if a non-displayable key is pressed +modal-loop-type: 0 ;-- remanence of last EVT_MOVE or EVT_SIZE +zoom-distance: 0 +special-key: -1 ;-- <> -1 if a non-displayable key is pressed flags-blk: declare red-block! ;-- static block value for event/flags flags-blk/header: TYPE_BLOCK flags-blk/head: 0 flags-blk/node: alloc-cells 4 +; used to save old position of pointer in widget-motion-notify-event handler +evt-motion: context [ + state: no + x_root: 0.0 + y_root: 0.0 + x_new: 0 + y_new: 0 + cpt: 0 + sensitiv: 3 +] + +evt-sizing: context [ + x_root: 0.0 + y_root: 0.0 + x_new: 0 + y_new: 0 +] make-at: func [ widget [handle!] face [red-object!] @@ -60,7 +82,9 @@ get-event-window: func [ handle [handle!] face [red-object!] ][ - none-value + ;; DEBUG: print ["get-event-windows: " evt/type " " evt/msg lf] + handle: gtk_widget_get_toplevel as handle! evt/msg + as red-value! get-face-obj handle ] get-event-offset: func [ @@ -72,6 +96,7 @@ get-event-offset: func [ offset [red-pair!] value [integer!] ][ + ;; DEBUG: print ["get-event-offset: " evt/type lf] case [ any [ evt/type <= EVT_OVER @@ -80,28 +105,35 @@ get-event-offset: func [ ][ offset: as red-pair! stack/push* offset/header: TYPE_PAIR - offset/x: motion/x_new - offset/y: motion/y_new - ;;print ["event-offset: " offset/x "x" offset/y lf] + offset/x: evt-motion/x_new + offset/y: evt-motion/y_new + ;; DEBUG: print ["event-offset: " offset/x "x" offset/y lf] as red-value! offset ] any [ evt/type = EVT_SIZING evt/type = EVT_SIZE ][ - widget: as handle! evt/msg - ;;print ["event-offset type: " get-symbol-name get-widget-symbol widget lf] + ;; DEBUG: print ["event-offset type: " get-symbol-name get-widget-symbol widget lf] offset: as red-pair! stack/push* offset/header: TYPE_PAIR - ; sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - ; offset/x: sz/x - ; offset/y: sz/y + + widget: as handle! evt/msg + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + ; sz/x: evt-sizing/x_new + ; sz/y: evt-sizing/y_new - offset/x: gtk_widget_get_allocated_width widget - offset/y: gtk_widget_get_allocated_height widget + ; print ["OFFSET is SIZE ? " sz " vs " offset lf] ; => NO! + ; alternative 1: + ; sz/x: (as integer! evt-sizing/x_root) - offset/x + ; sz/y: (as integer! evt-sizing/y_root) - offset/y - ;;print ["event-offset: " offset/x "x" offset/y lf] - as red-value! offset + ; alternative 2: + ; sz/x: gtk_widget_get_allocated_width widget + ; sz/y: gtk_widget_get_allocated_height widget + + ;; DEBUG: print ["event-size: " sz/x "x" sz/y " vs " offset/x "x" offset/y lf] + as red-value! sz ] any [ evt/type = EVT_ZOOM @@ -115,6 +147,13 @@ get-event-offset: func [ offset/header: TYPE_PAIR as red-value! offset ] + evt/type = EVT_MENU [ + offset: as red-pair! stack/push* + offset/header: TYPE_PAIR + offset/x: menu-x + offset/y: menu-y + as red-value! offset + ] true [as red-value! none-value] ] ] @@ -136,8 +175,9 @@ get-event-key: func [ code: evt/flags special?: code and 80000000h <> 0 code: code and FFFFh - ;debug: print ["code " code lf] - if special? [ + ;; DEBUG: print ["key-code=" code " flags=" evt/flags " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] + either special? [ + special-key: code res: as red-value! switch code [ RED_VK_PRIOR [_page-up] RED_VK_NEXT [_page-down] @@ -171,18 +211,45 @@ get-event-key: func [ RED_VK_APPS [_right-command] default [null] ] - ] - either null? res [ - either all [special? evt/type = EVT_KEY][ - none-value + ][special-key: -1] + if null? res [ + res: either all [special? evt/type = EVT_KEY][ + as red-value! none-value ][ - char: as red-char! stack/push* - char/header: TYPE_CHAR - char/value: code - as red-value! char + either code > 0 [ + ;; DEBUG: print ["key-code2=" code " flags=" evt/flags " special-key=" special-key " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] + char: as red-char! stack/push* + char/header: TYPE_CHAR + char/value: code + as red-value! char + ][as red-value! none-value] + ] + ] + res + ] + EVT_SCROLL [ + code: evt/flags + either code and 8 = 0 [ + switch code and 7 [ + 2 [_track] + 1 [_page-up] + 3 [_page-down] + 4 [_up] + 5 [_down] + default [_end] + ] + ][ + switch code and 7 [ + 2 [_track] + 1 [_page-left] + 3 [_page-right] + 4 [_left] + 5 [_right] + default [_end] ] - ][res] + ] ] + EVT_WHEEL [_wheel] default [as red-value! none-value] ] ] @@ -221,6 +288,7 @@ get-event-flags: func [ /local blk [red-block!] ][ + ;; DEBUG: print ["get-event-flags: " evt/flags lf] blk: flags-blk block/rs-clear blk if evt/flags and EVT_FLAG_AWAY <> 0 [block/rs-append blk as red-value! _away] @@ -241,23 +309,8 @@ get-event-flag: func [ as red-value! logic/push flags and flag <> 0 ] -decode-down-flags: func [ - wParam [integer!] - return: [integer!] - /local - flags [integer!] -][ - flags: 0 - if wParam and 0001h <> 0 [flags: flags or EVT_FLAG_DOWN] - if wParam and 0002h <> 0 [flags: flags or EVT_FLAG_ALT_DOWN] - if wParam and 0004h <> 0 [flags: flags or EVT_FLAG_SHIFT_DOWN] - if wParam and 0008h <> 0 [flags: flags or EVT_FLAG_CTRL_DOWN] - if wParam and 0010h <> 0 [flags: flags or EVT_FLAG_MID_DOWN] - if wParam and 0020h <> 0 [flags: flags or EVT_FLAG_AUX_DOWN] - if wParam and 0040h <> 0 [flags: flags or EVT_FLAG_AUX_DOWN] ;-- needs an AUX2 flag - flags -] - +;; This function is only called in handlers.red +;; No make-event: func [ msg [handle!] flags [integer!] @@ -270,51 +323,96 @@ make-event: func [ state [integer!] key [integer!] char [integer!] + type [integer!] ][ gui-evt/type: evt gui-evt/msg: as byte-ptr! msg gui-evt/flags: flags + ;; DEBUG: print ["make-event: down? " flags and EVT_FLAG_DOWN <> 0 lf] + state: EVT_DISPATCH switch evt [ - EVT_OVER [0 - ] - EVT_KEY_DOWN [0 - ] - EVT_KEY_UP [0 - ] - EVT_KEY [0 - ] - EVT_SELECT [0 - ] - EVT_CHANGE [0 - ] - EVT_LEFT_DOWN - EVT_LEFT_UP - EVT_RIGHT_DOWN - EVT_RIGHT_UP - EVT_MIDDLE_DOWN - EVT_MIDDLE_UP - EVT_DBL_CLICK [0 - ] - EVT_CLICK [0 + ; EVT_OVER [0 + ; ] + ; EVT_KEY_DOWN [0 + ; ] + ; EVT_KEY_UP [0 + ; ] + ; EVT_KEY [0 + ; ] + ; EVT_SELECT [0 + ; ] + ; EVT_CHANGE [0 + ; ] + EVT_LEFT_DOWN [ + case [ + flags and EVT_FLAG_DBL_CLICK <> 0 [ + ;; DEBUG: print ["Double click!!!!!" lf] + gui-evt/type: EVT_DBL_CLICK + ] + ; flags and EVT_FLAG_CMD_DOWN <> 0 [ + ; gui-evt/type: EVT_RIGHT_DOWN + ; ] + ; flags and EVT_FLAG_CTRL_DOWN <> 0 [ + ; gui-evt/type: EVT_MIDDLE_DOWN + ; ] + true [0] + ] ] - EVT_MENU [0] ;-- symbol ID of the menu + ; EVT_LEFT_UP [ + ; case [ + ; flags and EVT_FLAG_CMD_DOWN <> 0 [ + ; gui-evt/type: EVT_RIGHT_UP + ; ] + ; flags and EVT_FLAG_CTRL_DOWN <> 0 [ + ; gui-evt/type: EVT_MIDDLE_UP + ; ] + ; true [0] + ; ] + ; ] + ; EVT_CLICK [0 + ; ] + ; EVT_MENU [0] ;-- symbol ID of the menu default [0] ] - #call [system/view/awake gui-evt] - + stack/mark-try-all words/_anon res: as red-word! stack/arguments - if TYPE_OF(res) = TYPE_WORD [ + catch CATCH_ALL_EXCEPTIONS [ + #call [system/view/awake gui-evt] + stack/unwind + ] + stack/adjust-post-try + if system/thrown <> 0 [system/thrown: 0] + ;; DEBUG: print ["make-event result:" res lf] + type: TYPE_OF(res) + if ANY_WORD?(type) [ sym: symbol/resolve res/symbol + ;; DEBUG: print ["make-event symbol:" get-symbol-name sym lf] case [ - sym = done [state: EVT_DISPATCH] ;-- prevent other high-level events + sym = done [state: EVT_NO_DISPATCH] ;-- prevent other high-level events sym = stop [state: EVT_NO_DISPATCH] ;-- prevent all other events true [0] ;-- ignore others ] ] + + ; #call [system/view/awake gui-evt] + ; res: as red-word! stack/arguments + + ; if TYPE_OF(res) = TYPE_WORD [ + ; sym: symbol/resolve res/symbol + ; ;; DEBUG: + ; print ["make-events result:" sym lf] + + ; case [ + ; sym = done [state: EVT_DISPATCH] ;-- prevent other high-level events + ; sym = stop [state: EVT_NO_DISPATCH] ;-- prevent all other events + ; true [0] ;-- ignore others + ; ] + ; ] + state ] @@ -323,12 +421,27 @@ do-events: func [ return: [logic!] /local msg? [logic!] + event [GdkEventAny!] + widget [handle!] + ; state [GdkModifierType!] + ; source [handle!] ][ msg?: no + + set-view-no-wait last-window no-wait? + ;@@ Improve it!!! ;@@ as we cannot access gapplication->priv->use_count ;@@ we use a global value to simulate it - unless no-wait? [exit-loop: exit-loop + 1] + + ;; DEBUG: print ["do-events no-wait? " no-wait? lf] + ;; Special initialisation of hidden widgets (cf gui.reds) + hide-invisible + + ;; Initially normally uncommented: the exit-loop is also decremented in destroy for supposed no-wait view! + unless no-wait? [ + exit-loop: exit-loop + 1 + ] while [exit-loop > 0][ if g_main_context_iteration GTKApp-Ctx not no-wait? [msg?: yes] @@ -339,10 +452,7 @@ do-events: func [ msg?: yes if no-wait? [break] ] - - ;g_settings_sync - ;g_main_context_release GTKApp-Ctx ;@@ release it? - ;g_object_unref GTKApp + msg? ] @@ -359,6 +469,58 @@ check-extra-keys: func [ key ] +check-extra-buttons: func [ + state [integer!] + return: [integer!] + /local + buttons [integer!] +][ + buttons: 0 + if state and GDK_BUTTON1_MASK <> 0 [buttons: EVT_FLAG_DOWN] + if state and GDK_BUTTON2_MASK <> 0 [buttons: buttons or EVT_FLAG_DOWN] + if state and GDK_BUTTON3_MASK <> 0 [buttons: buttons or EVT_FLAG_DOWN] + buttons +] + +check-down-flags: func [ + state [integer!] + return: [integer!] + /local + flags [integer!] +][ + flags: 0 + if state and GDK_BUTTON1_MASK <> 0 [flags: flags or EVT_FLAG_DOWN] + if state and GDK_META_MASK <> 0 [flags: flags or EVT_FLAG_ALT_DOWN] + if state and GDK_SHIFT_MASK <> 0 [flags: flags or EVT_FLAG_SHIFT_DOWN] + if state and GDK_CONTROL_MASK <> 0 [flags: flags or EVT_FLAG_CTRL_DOWN] + if state and GDK_BUTTON2_MASK <> 0 [flags: flags or EVT_FLAG_MID_DOWN] + if state and GDK_BUTTON3_MASK <> 0 [flags: flags or EVT_FLAG_AUX_DOWN] + ;;if state and 0040h <> 0 [flags: flags or EVT_FLAG_AUX_DOWN] ;-- needs an AUX2 flag + flags +] + +check-flags: func [ + type [integer!] + state [integer!] + return: [integer!] + /local + flags [integer!] +][ + flags: 0 + ;;[flags: flags or EVT_FLAG_AX2_DOWN] + if state and GDK_META_MASK <> 0 [flags: flags or EVT_FLAG_AUX_DOWN] + if state and GDK_META_MASK <> 0 [flags: flags or EVT_FLAG_ALT_DOWN] + if state and GDK_BUTTON2_MASK <> 0 [flags: flags or EVT_FLAG_MID_DOWN] + if state and GDK_BUTTON1_MASK <> 0 [flags: flags or EVT_FLAG_DOWN] + ;;[flags: flags or EVT_FLAG_AWAY] + if type = GDK_DOUBLE_BUTTON_PRESS [flags: flags or EVT_FLAG_DBL_CLICK] + if state and GDK_CONTROL_MASK <> 0 [flags: flags or EVT_FLAG_CTRL_DOWN] + if state and GDK_SHIFT_MASK <> 0 [flags: flags or EVT_FLAG_SHIFT_DOWN] + if state and GDK_HYPER_MASK <> 0 [flags: flags or EVT_FLAG_MENU_DOWN] + if state and GDK_SUPER_MASK <> 0 [flags: flags or EVT_FLAG_CMD_DOWN] + flags +] + translate-key: func [ keycode [integer!] return: [integer!] @@ -366,19 +528,522 @@ translate-key: func [ key [integer!] special? [logic!] ][ - ;debug: print ["keycode: " keycode] - keycode: gdk_keyval_to_upper keycode - ;debug: print [" keycode2: " keycode] + ;; DEBUG: print ["keycode: " keycode lf] + keycode: either gdk_keyval_is_upper keycode [gdk_keyval_to_upper keycode][gdk_keyval_to_lower keycode] + ;; DEBUG: print [" translate-key: keycode: " keycode lf] special?: no key: case [ - all[keycode >= 30h keycode <= 5Ah][keycode]; RED_VK_0 to RED_VK_Z - all[keycode >= FFBEh keycode <= FFC8h][special?: yes keycode + RED_VK_F1 - FFBEh];RED_VK_F1 to RED_VK_F11 - keycode = FFBFh [special?: yes RED_VK_F12] - keycode = FF0Dh [special?: yes RED_VK_RETURN] + all[keycode >= 20h keycode <= 5Ah][keycode]; RED_VK_SPACE to RED_VK_Z + all[keycode >= 61h keycode <= 7Ah][keycode]; RED_VK_a to RED_VK_z + all[keycode >= A0h keycode <= FFh][keycode]; + all[keycode >= FFBEh keycode <= FFD5h][special?: yes keycode + RED_VK_F1 - FFBEh] ;RED_VK_F1 to RED_VK_F24 + all[keycode >= FF51h keycode <= FF54h][special?: yes keycode + RED_VK_LEFT - FF51h] ;RED_VK_LEFT to RED_VK_DOWN + all[keycode >= FF55h keycode <= FF57h][special?: yes keycode + RED_VK_PRIOR - FF51h] ;RED_VK_PRIOR to RED_VK_END + keycode = FF0Dh [special?: no RED_VK_RETURN] + keycode = FF1Bh [special?: yes RED_VK_ESCAPE] + keycode = FF50h [special?: yes RED_VK_HOME] + keycode = FFE5h [special?: yes RED_VK_NUMLOCK] + keycode = FF08h [special?: yes RED_VK_BACK] + keycode = FF09h [special?: yes RED_VK_TAB] + keycode = FFE1h [special?: yes RED_VK_LSHIFT] + keycode = FFE2h [special?: yes RED_VK_RSHIFT] + keycode = FFE3h [special?: yes RED_VK_LCONTROL] + keycode = FFE4h [special?: yes RED_VK_RCONTROL] ;@@ To complete! true [RED_VK_UNKNOWN] ] if special? [key: key or 80000000h] - ;debug: print [" key: " key " F1" RED_VK_F1 lf] + special-key: either special? [key][-1] + ;; DEBUG: print [" key: " key " special?=" special? lf] key +] + +post-quit-msg: func [ + /local + e [integer!] + tm [float!] +][ + 0 +] + +;;------------- centralize here connection handlers +;; The goal is to only connect gtk handlers only when actor is provided +;; Rmk: Specific development for rich-text with panel parent with on-over actor for rich-text +;; The panel needs to receive the event otherwise the rich-text can't receive the event with the associated actor. +;; A delegation connection is provided to do so. + +#enum DebugConnect! [ + DEBUG_CONNECT_NONE: 0 + DEBUG_CONNECT_WIDGET: 1 + DEBUG_CONNECT_COMMON: 2 + DEBUG_CONNECT_NOTIFY: 4 + DEBUG_CONNECT_RESPOND_KEY: 8 + DEBUG_CONNECT_RESPOND_MOUSE: 16 + DEBUG_CONNECT_RESPOND_WINDOW: 32 + DEBUG_CONNECT_ALL_ADD: 63 + DEBUG_CONNECT_RESPOND_EVENT: 65536 + DEBUG_CONNECT_ALL: 131071 +] + +;; DEBUG mode: NONE vs ALL vs ALL_ADD +debug-connect-level: DEBUG_CONNECT_NONE +;debug-connect-level: DEBUG_CONNECT_ALL_ADD + +debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and level <> 0] + + +respond-event?: func [ + actors [red-object!] + type [c-string!] + return: [logic!] + /local + respond? [logic!] +][ + either null? actors/ctx [ + false + ][ + respond?: -1 <> object/rs-find actors as red-value! word/load type + ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_EVENT [print ["respond-event? type " type lf]] + respond? + ] +] + +respond-mouse-id: g_quark_from_string "respond-mouse-id" +respond-key-id: g_quark_from_string "respond-key-id" +respond-window-id: g_quark_from_string "respond-window-id" + +#enum RespondMouseType! [ + ON_LEFT_DOWN: 1 + ON_LEFT_UP: 2 + ON_MIDDLE_DOWN: 4 + ON_MIDDLE_UP: 8 + ON_RIGHT_DOWN: 16 + ON_RIGHT_UP: 32 + ON_AUX_DOWN: 64 + ON_AUX_UP: 128 + ON_CLICK: 256 + ON_DBL_CLICK: 512 + ON_WHEEL: 1024 + ON_OVER: 2048 +] + +respond-mouse-add: func [ + widget [handle!] + actors [red-object!] + sym [integer!] + /local + on-type [integer!] +][ + on-type: 0 + if respond-event? actors "on-down" [on-type: on-type or ON_LEFT_DOWN] + if respond-event? actors "on-up" [on-type: on-type or ON_LEFT_UP] + if respond-event? actors "on-mid-down" [on-type: on-type or ON_MIDDLE_DOWN] + if respond-event? actors "on-mid-up" [on-type: on-type or ON_MIDDLE_UP] + if respond-event? actors "on-alt-down" [on-type: on-type or ON_RIGHT_DOWN] + if respond-event? actors "on-alt-up" [on-type: on-type or ON_RIGHT_UP] + if respond-event? actors "on-aux-down" [on-type: on-type or ON_AUX_DOWN] + if respond-event? actors "on-aux-up" [on-type: on-type or ON_AUX_UP] + if respond-event? actors "on-click" [on-type: on-type or ON_CLICK] if respond-event? actors "on-dbl-click" [on-type: on-type or ON_DBL_CLICK] + if respond-event? actors "on-wheel" [on-type: on-type or ON_WHEEL] + if respond-event? actors "on-over" [on-type: on-type or ON_OVER] + if all[on-type > 0 not null? widget][ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_MOUSE [print ["Add mouse event " on-type " for " get-symbol-name sym lf ]] + g_object_set_qdata widget respond-mouse-id as int-ptr! on-type + ] +] + +respond-mouse?: func [ + widget [handle!] + on-type [integer!] + return: [logic!] +][ + (as-integer g_object_get_qdata widget respond-mouse-id) and on-type <> 0 +] + +#enum RespondWindowType! [ + ON_CLOSE: 1 ;-- window events + ON_MOVE: 2 + ON_SIZE: 4 + ON_MOVING: 8 + ON_SIZING: 16 + ON_TIME: 32 + ON_DRAWING: 64 + ON_SCROLL: 128 + + ON_SELECT: 1024 + ON_CHANGE: 2048 + ON_MENU: 4096 +] + +respond-window-add: func [ + widget [handle!] + actors [red-object!] + sym [integer!] + /local + on-type [integer!] +][ + on-type: 0 + if respond-event? actors "on-close" [on-type: on-type or ON_CLOSE] + if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] + if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] + if respond-event? actors "on-time" [on-type: on-type or ON_TIME] + if respond-event? actors "on-drawing" [on-type: on-type or ON_DRAWING] + if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] + if respond-event? actors "on-over" [on-type: on-type or ON_OVER] + if respond-event? actors "on-select" [on-type: on-type or ON_SELECT] + if respond-event? actors "on-change" [on-type: on-type or ON_CHANGE] + if respond-event? actors "on-menu" [on-type: on-type or ON_MENU] + if all[on-type > 0 not null? widget][ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_WINDOW [print ["Add window event " on-type " for " get-symbol-name sym lf ]] + g_object_set_qdata widget respond-window-id as int-ptr! on-type + ] +] + +respond-window?: func [ + widget [handle!] + on-type [integer!] + return: [logic!] +][ + (as-integer g_object_get_qdata widget respond-window-id) and on-type <> 0 +] + +#enum RespondKeyType! [ + ON_KEY: 1 + ON_KEY_DOWN: 2 + ON_KEY_UP: 4 + ON_IME: 8 + ON_FOCUS: 16 + ON_UNFOCUS: 32 + ON_ENTER: 64 + ON_ZOOM: 128 + ON_PAN: 256 + ON_ROTATE: 512 + ON_TWO_TAP: 1024 + ON_PRESS_TAP: 2048 +] + +respond-key-add: func [ + widget [handle!] + actors [red-object!] + sym [integer!] + /local + on-type [integer!] +][ + on-type: 0 + if respond-event? actors "on-key" [on-type: on-type or ON_KEY] + if respond-event? actors "on-key-down" [on-type: on-type or ON_KEY_DOWN] + if respond-event? actors "on-key-up" [on-type: on-type or ON_KEY_UP] + if respond-event? actors "on-ime" [on-type: on-type or ON_IME] + if respond-event? actors "on-focus" [on-type: on-type or ON_FOCUS] + if respond-event? actors "on-unfocus" [on-type: on-type or ON_UNFOCUS] + if respond-event? actors "on-enter" [on-type: on-type or ON_ENTER] + if respond-event? actors "on-zoom" [on-type: on-type or ON_ZOOM] + if respond-event? actors "on-pan" [on-type: on-type or ON_PAN] + if respond-event? actors "on-rotate" [on-type: on-type or ON_ROTATE] + if respond-event? actors "on-two-tap" [on-type: on-type or ON_TWO_TAP] + if respond-event? actors "on-press-tap" [on-type: on-type or ON_PRESS_TAP] + if all[on-type > 0 not null? widget][ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_KEY [print ["Add key event " on-type " for " get-symbol-name sym lf ]] + g_object_set_qdata widget respond-key-id as int-ptr! on-type + ] +] + +respond-key?: func [ + widget [handle!] + on-type [integer!] + return: [logic!] +][ + (as-integer g_object_get_qdata widget respond-key-id) and on-type <> 0 +] + + +connect-container-events: func [ + widget [handle!] + evt-type [c-string!] + /local + container [handle!] + id [integer!] +][ + container: container? widget + unless null? container [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print ["connect-container-events " container " " evt-type lf]] + case [ + 0 = g_strcmp0 evt-type "button-press-event" [ + gtk_widget_add_events container GDK_BUTTON_PRESS_MASK + ] + 0 = g_strcmp0 evt-type "motion-notify-event" [ + gtk_widget_add_events container GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK + ] + 0 = g_strcmp0 evt-type "button-release-event" [ + gtk_widget_add_events container GDK_BUTTON_RELEASE_MASK + ] + 0 = g_strcmp0 evt-type "enter-notify-event" [ ; normally unused + gtk_widget_add_events container GDK_ENTER_NOTIFY_MASK + ] + 0 = g_strcmp0 evt-type "leave-notify-event" [ ; normally unused + gtk_widget_add_events container GDK_LEAVE_NOTIFY_MASK + ] + true [0] + ] + if null? container [print ["container null for connection with " widget " " evt-type lf]] + id: gobj_signal_connect(container evt-type :container-delegate-to-children null) + ] +] + +;; TODO: before finding better solution!!!! +;; container-type? is now only restricted to rich-text (cf gui.red) +;; since +;; 1) it is required in makedoc/easy-VID-rt.red +;; 2) it is too slow when used in ast.red for base widget (too much delegations). + +connect-common-events: function [ + widget [handle!] + face [red-object!] + sym [integer!] + parent [handle!] +][ + unless null? widget [ + + if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-DOWN: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-press-event" + ] + gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + ] + if respond-mouse? widget (ON_OVER) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-OVER: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "motion-notify-event" + ] + gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) + ] + + if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-UP: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-release-event" + ] + gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) + ] + + if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS or ON_ENTER) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-KEY: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK + gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) + ] + + if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-KEY-UP: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_KEY_RELEASE_MASK + gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) + ] + + if respond-mouse? widget ON_WHEEL [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON_WHEEL: " get-symbol-name sym "->" widget lf]] + gtk_widget_add_events widget GDK_SCROLL_MASK + gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) + ] + + ] +] + +connect-notify-events: function [ + widget [handle!] + face [red-object!] + sym [integer!] + /local + _widget [handle!] +][ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print ["connect-notify-events " widget " " get-symbol-name sym lf]] + + unless null? widget [ + _widget: either sym = text [ + g_object_get_qdata widget _widget-id + ][widget] + + if respond-mouse? widget ON_OVER [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print [ "connect-notifiy-events ON-OVER: " get-symbol-name sym "->" widget "(" _widget ")" lf]] + gtk_widget_add_events _widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK + gobj_signal_connect(_widget "enter-notify-event" :widget-enter-notify-event face/ctx) + gobj_signal_connect(_widget "leave-notify-event" :widget-leave-notify-event face/ctx) + ] + ] +] + +connect-widget-events: function [ + widget [handle!] + face [red-object!] + actors [red-object!] + sym [integer!] + _widget [handle!] + parent [handle!] + /local + buffer [handle!] +][ + ;; register red mouse, key and window on event functions + + ;; DEBUG: print ["common-widget-events for " get-symbol-name sym " " widget lf] + ;; DEBUG: if null? actors/ctx [print ["null? actors/ctx" lf]] + + respond-mouse-add widget actors sym + respond-key-add widget actors sym + respond-window-add widget actors sym + + case [ + sym = check [ + ;@@ No click event for check + ;gobj_signal_connect(widget "clicked" :button-clicked null) + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add check toggled " lf]] + gobj_signal_connect(widget "toggled" :button-toggled face/ctx) + ] + sym = radio [ + ;@@ Line below removed because it generates an error and there is no click event for radio + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add radio toggled " lf]] + gobj_signal_connect(widget "toggled" :button-toggled face/ctx) + ] + sym = button [ + if respond-mouse? widget ON_CLICK [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] + gobj_signal_connect(widget "clicked" :button-clicked null) + ] + ] + sym = base [ + gobj_signal_connect(widget "draw" :base-draw face/ctx) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + connect-common-events widget face sym parent + ] + sym = rich-text [ + gobj_signal_connect(widget "draw" :base-draw face/ctx) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_is_focus widget + gtk_widget_grab_focus widget + connect-common-events widget face sym parent + ] + sym = window [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] + gobj_signal_connect(widget "delete-event" :window-delete-event null) + ;BUG (make `vid.red` failing):gtk_widget_add_events widget GDK_STRUCTURE_MASK + ;gobj_signal_connect(widget "configure-event" :window-configure-event null) + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] + gobj_signal_connect(widget "size-allocate" :window-size-allocate null) + connect-common-events widget face sym parent + ] + sym = slider [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] + gobj_signal_connect(widget "value-changed" :range-value-changed face/ctx) + ] + sym = text [ + if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text (event-box) button-press-event " lf]] + gobj_signal_connect(_widget "button-press-event" :simple-button-press-event widget) + ] + if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text (event-box) button-release-event " lf]] + gobj_signal_connect(_widget "button-release-event" :simple-button-release-event widget) + ] + ] + sym = field [ + ;;if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS or ON_ENTER) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add field key-press-event" lf]] + gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) + ;;] + ;;if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add field key-release-event" lf]] + gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) + ;;] + ;Do not work: gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) + ;;if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add fiedl button-release-event " lf]] + gobj_signal_connect(widget "button-release-event" :field-button-release-event face/ctx) + ;;] + + gtk_widget_set_can_focus widget yes + gtk_widget_is_focus widget + ;This depends on version >= 3.2 + ;gtk_widget_set_focus_on_click widget yes + gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) + ] + sym = progress [ + 0 + ] + sym = area [ + ; _widget is here buffer + buffer: gtk_text_view_get_buffer widget + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] + gobj_signal_connect(buffer "changed" :area-changed widget) + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] + g_object_set [widget "populate-all" yes null] + if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area button-press-event " lf]] + gobj_signal_connect(widget "button-press-event" :area-button-press-event face/ctx) + ] + if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area button-release-event " lf]] + gobj_signal_connect(widget "button-release-event" :area-button-release-event face/ctx) + ] + if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area key-press-event " lf]] + gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) + ] + if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area key-release-event " lf]] + gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) + ] + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] + gobj_signal_connect(widget "populate-popup" :area-populate-popup face/ctx) + ] + sym = group-box [ + 0 + ] + sym = panel [ + gobj_signal_connect(widget "draw" :base-draw face/ctx) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + ;; value: gtk_widget_get_events widget + ;; DEBUG: print ["panel had focus: " gtk_widget_get_focus_on_click widget lf "get events: " value " GDK_BUTTON_PRESS_MASK? " GDK_BUTTON_PRESS_MASK and value lf] + ; if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ + ; gobj_signal_connect(widget "button-press-event" :panel-button-press-event face/ctx) + ;] + ; if respond-mouse? widget ON_OVER [gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx)] + + ; if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx)] + ; if respond-key? widget (ON_KEY or ON_KEY_DOWN) [gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx)] + ; if respond-key? widget ON_KEY_UP [gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx)] + connect-common-events widget face sym parent + ] + sym = tab-panel [ + if respond-window? widget (ON_SELECT or ON_CHANGE) [ + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] + gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) + ] + ] + sym = text-list [ + ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text-list selected-rows-changed " lf]] + gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) + connect-common-events widget face sym parent + ] + any [ + sym = drop-list + sym = drop-down + ][ + ;;; Mandatory! and can respond to (ON_SELECT or ON_CHANGE) + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add drop-(list|down) changed " lf]] + gobj_signal_connect(widget "changed" :combo-selection-changed face/ctx) + ] + true [0] + ] + connect-notify-events widget face sym ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 7f945b6291..cf0502ff0e 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -10,8 +10,6 @@ Red/System [ } ] -;; First style development provided by Thiago Dourado de Andrade -#define GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 600 add-to-string: func [ string [c-string!] @@ -73,10 +71,11 @@ make-font: func [ hFont [handle!] ][ ; no more deal with different styles but only font via pango_font_description (excluding color, underline, strike) + ;; DEBUG: print ["make-font face " face " " font lf] hFont: font-description font - + ;; DEBUG: print ["make-font font-description: " hFont lf] set-font-handle font hFont - + ;; DEBUG: print ["make-font set-font-handle: " font " " hFont lf] values: object/get-values font if face <> null [ @@ -84,11 +83,18 @@ make-font: func [ block/rs-append blk as red-value! face ] - ;; DEBUG: print ["font-description: " hFont lf] + ;; DEBUG: print ["make-font end font-description: " hFont lf] hFont ] +face-font?: func [ + face [red-object!] + return: [red-object!] +][ + as red-object! (object/get-values face) + FACE_OBJ_FONT +] + get-font-handle: func [ font [red-object!] idx [integer!] @@ -107,10 +113,25 @@ get-font-handle: func [ null ] +get-font: func [ + face [red-object!] + font [red-object!] + return: [handle!] + /local + hFont [handle!] +][ + if TYPE_OF(font) <> TYPE_OBJECT [return default-font] + hFont: get-font-handle font 0 + if null? hFont [hFont: make-font face font] + hFont +] + free-font-handle: func [ hFont [handle!] ][ + ;; DEBUG: print ["free-font-handle " hFont lf] pango_font_description_free hFont + ;; DEBUG: print ["free-font-handle end " hFont lf] ] free-font: func [ @@ -120,11 +141,11 @@ free-font: func [ hFont [handle!] ][ hFont: get-font-handle font 0 - if hFont <> null [ + unless null? hFont [ state: as red-block! (object/get-values font) + FONT_OBJ_STATE state/header: TYPE_NONE + free-font-handle hFont ] - free-font-handle hFont ] set-font-handle: func [ @@ -138,7 +159,9 @@ set-font-handle: func [ hFontP [handle!] ][ ; release previous hFont first + ;; DEBUG: print ["set-font-handle " font " " hFont lf] hFontP: get-font-handle font 0 + ;; DEBUG: print ["set-font-handle get " hFontP lf] unless null? hFontP [ free-font-handle hFontP ] @@ -161,13 +184,13 @@ update-font: func [ font [red-object!] flag [integer!] ][ + ;; DEBUG: print ["update-font " font lf] switch flag [ FONT_OBJ_NAME FONT_OBJ_SIZE FONT_OBJ_STYLE FONT_OBJ_ANGLE FONT_OBJ_ANTI-ALIAS? [ - free-font font make-font null font ] default [0] @@ -188,7 +211,6 @@ font-description: func [ name [c-string!] size [red-integer!] fsize [integer!] - css [c-string!] color [red-tuple!] bgcolor [red-tuple!] rgba [c-string!] @@ -198,9 +220,7 @@ font-description: func [ ][ ; default font if font is none. TODO: better than gtk-font would be to get the default font system or from red side - if TYPE_OF(font) = TYPE_NONE [ - return pango_font_description_from_string gtk-font - ] + if TYPE_OF(font) = TYPE_NONE [return default-font] values: object/get-values font ;name: str: as red-string! values + FONT_OBJ_NAME @@ -208,21 +228,19 @@ font-description: func [ style: as red-word! values + FONT_OBJ_STYLE ;angle: color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - fd: pango_font_description_new + ; font name name: "Arial" ; @@ to change to default font name if TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len ] - pango_font_description_set_family fd name + ; font size fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] ;; DEBUG: print ["font-description: fsize -> " fsize lf] - pango_font_description_set_size fd fsize * PANGO_SCALE + ; font style and weight len: switch TYPE_OF(style) [ TYPE_BLOCK [ blk: as red-block! style @@ -249,11 +267,35 @@ font-description: func [ ] ] + fd: font-description-create name fsize fweight fstyle + + fd +] + +font-description-create: func [ + fname [c-string!] + fsize [integer!] + fweight [integer!] + fstyle [integer!] + return: [handle!] + /local + fd [handle!] + ;css [c-string!] +][ + fd: pango_font_description_new + + pango_font_description_set_family fd fname + pango_font_description_set_size fd fsize * PANGO_SCALE + pango_font_description_set_weight fd fweight pango_font_description_set_style fd fstyle pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL pango_font_description_set_variant fd PANGO_VARIANT_NORMAL + ;; DOES NOT WORK AS EXPECTED: + ;; css: pango_font_description_to_string fd + ;; print ["font description css: " css lf] + fd ] @@ -268,7 +310,7 @@ make-styles-provider: func [ provider: gtk_css_provider_new style: gtk_widget_get_style_context widget - gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_USER g_object_set_qdata widget gtk-style-id provider ] @@ -283,6 +325,7 @@ get-styles-provider: func [ css-styles: func [ face [red-object!] font [red-object!] + type [integer!] return: [c-string!] /local values [red-value!] @@ -298,6 +341,172 @@ css-styles: func [ bgcolor [red-tuple!] rgba [c-string!] ][ + css: g_strdup_printf ["* {"] + + if TYPE_OF(font) = TYPE_OBJECT [ + values: object/get-values font + + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + name: unicode/to-utf8 str :len + css: g_strdup_printf [{%s font-family: "%s";} css name] + ] + + if TYPE_OF(size) = TYPE_INTEGER [ + css: add-to-string css "%s font-size: %dpt;" as handle! size/value + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold; " css]] + sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] + sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration: underline;" css]] + sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration: line-through;" css]] + true [""] + ] + style: style + 1 + ] + ] + + if TYPE_OF(color) = TYPE_TUPLE [ + rgba: to-css-rgba color + css: add-to-string css "%s color: %s;" as handle! rgba + g_free as handle! rgba + ] + ] + + ;; Further styles from face + ;; DEBUG: print ["css face color " face lf] + unless null? face [ + bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR + ;; DEBUG: print ["typeof(bgcolor) " TYPE_OF(bgcolor) " " TYPE_TUPLE lf] + if TYPE_OF(bgcolor) = TYPE_TUPLE [ + rgba: to-css-rgba bgcolor + css: add-to-string css "%s background: %s;" as handle! rgba + g_free as handle! rgba + ] + ] + + css: add-to-string css "%s}" null + + case [ + type = button [ + css: g_strdup_printf ["%s button {padding: 0px 0px 0px 0px;margin: 0px 0px 0px 0px;font-variant: small-caps;}" css] + ] + true [0] + ] + + ;; DEBUG: print ["css-styles -> css: " css lf] + + css +] + +apply-css-styles: func [ + widget [handle!] + face [red-object!] + font [red-object!] + type [integer!] + /local + provider [handle!] + css [c-string!] +][ + provider: get-styles-provider widget + + ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles + css: "" + css: css-styles face font type + + ;; DEBUG: print ["apply-css-styles ccs: " widget " " css lf] + + unless null? provider [gtk_css_provider_load_from_data provider css -1 null] +] + + +css-provider: func [ + path [c-string!] + priority [integer!] + /local + provider [handle!] + display [handle!] + screen [handle!] +][ + provider: gtk_css_provider_new + gtk_css_provider_load_from_path provider path null + display: gdk_display_get_default + screen: gdk_display_get_default_screen display + gtk_style_context_add_provider_for_screen screen provider priority + g_object_unref provider +] + +red-gtk-styles: func [ + /local + env strarr str + found [logic!] +][ + env: system/env-vars + ;strarr: g_strsplit "GTK_STYLES" "=" 2 + ;g_strfreev strarr + found: no + until [ + strarr: g_strsplit env/item "=" 2 + str: as c-string! (strarr/1) + if 0 = g_strcmp0 str "RED_GTK_STYLES" [ + str: as c-string! (strarr/2) + css-provider str GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + found: yes + ] + env: env + 1 + g_strfreev strarr + any[found env/item = null] + ] +] + +; move this to draw-ctx!? (used in draw-text-at) +cairo-font-size: 10.0 ;-- used to find top line + +;; Move honix stuff from draw.reds (OS-draw-font) to switch to pango-cairo +make-cairo-draw-font: func [ + dc [draw-ctx!] + font [red-object!] + /local + cr [handle!] + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + name [c-string!] + size [red-integer!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] + slant [integer!] + weight [integer!] + extents [cairo_font_extents_t!] +][ + cr: dc/raw + values: object/get-values font ;name: @@ -308,18 +517,103 @@ css-styles: func [ color: as red-tuple! values + FONT_OBJ_COLOR ;anti-alias?: - css: g_strdup_printf ["* {"] + dc/font-color: color/array1 if TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len - css: g_strdup_printf [{%s font-family: "%s";} css name] + ] + + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] + + slant: CAIRO_FONT_SLANT_NORMAL + weight: CAIRO_FONT_WEIGHT_NORMAL + + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] + sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] + sym = _underline [] + sym = _strike [] + true [] + ] + style: style + 1 + ] ] + cairo_select_font_face cr name slant weight + if TYPE_OF(size) = TYPE_INTEGER [ - css: add-to-string css "%s font-size: %dpt;" as handle! size/value + extents: declare cairo_font_extents_t! + cairo_font_extents cr extents + + cairo-font-size: as-float size/value + cairo_set_font_size cr cairo-font-size * ((extents/ascent + extents/descent) / extents/ascent) + + ; This technique is little more correct for me. + ; This Red example will show the difference: + ; + ; f: make font! [name: "Arial" size: 120] + ; view [base 140x140 draw [font f text 10x10 "A" pen white box 0x10 140x130]] ] +] + +make-pango-cairo-font: func [ + dc [draw-ctx!] + font [red-object!] + /local + cr [handle!] + values [red-value!] + style [red-word!] + blk [red-block!] + len [integer!] + sym [integer!] + str [red-string!] + size [red-integer!] + color [red-tuple!] + bgcolor [red-tuple!] + rgba [c-string!] + slant [integer!] + weight [integer!] + fname [c-string!] + fsize [integer!] + fweight [integer!] + fstyle [integer!] + value [red-value!] + bool [red-logic!] + quality [integer!] +][ + cr: dc/raw + + values: object/get-values font + ;name: + str: as red-string! values + FONT_OBJ_NAME + size: as red-integer! values + FONT_OBJ_SIZE + style: as red-word! values + FONT_OBJ_STYLE + ;angle: + color: as red-tuple! values + FONT_OBJ_COLOR + ;anti-alias?: + + ;;;;----- color + dc/font-color: color/array1 + ;;;------- font description + fname: "Arial" ; @@ to change to default font name + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + fname: unicode/to-utf8 str :len + ] + fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] len: switch TYPE_OF(style) [ TYPE_BLOCK [ blk: as red-block! style @@ -329,122 +623,173 @@ css-styles: func [ TYPE_WORD [1] default [0] ] - + fstyle: PANGO_STYLE_NORMAL + fweight: PANGO_WEIGHT_NORMAL + dc/font-underline?: no + dc/font-strike?: no unless zero? len [ loop len [ sym: symbol/resolve style/symbol - case [ - sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold; " css]] - sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] - sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration: underline;" css]] - sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration: line-through;" css]] - true [""] + case [ + sym = _bold [fweight: PANGO_WEIGHT_BOLD] + sym = _italic [fstyle: PANGO_STYLE_ITALIC] + sym = _underline [dc/font-underline?: yes] + sym = _strike [dc/font-strike?: yes] + true [] ] style: style + 1 ] ] - if TYPE_OF(color) = TYPE_TUPLE [ - rgba: to-css-rgba color - css: add-to-string css "%s color: %s;" as handle! rgba - g_free as handle! rgba + free-pango-cairo-font dc + dc/font-desc: font-description-create fname fsize fweight fstyle + dc/font-opts: cairo_font_options_create + + dc/layout: make-pango-cairo-layout cr dc/font-desc + + + ;anti-alias?: + value: values + FONT_OBJ_ANTI-ALIAS? + + switch TYPE_OF(value) [ + TYPE_LOGIC [ + bool: as red-logic! value + quality: either bool/value [CAIRO_ANTIALIAS_SUBPIXEL][CAIRO_ANTIALIAS_NONE] + ;-- ANTIALIASED_QUALITY + ] + TYPE_WORD [ + style: as red-word! value + either ClearType = symbol/resolve style/symbol [ + quality: CAIRO_ANTIALIAS_BEST + ;-- CLEARTYPE_QUALITY + ][ + quality: CAIRO_ANTIALIAS_NONE + ] + ] + default [quality: CAIRO_ANTIALIAS_DEFAULT] + ;-- DEFAULT_QUALITY ] + cairo_font_options_set_antialias dc/font-opts quality - ;; Further styles from face - unless null? face [ - bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR - if TYPE_OF(bgcolor) = TYPE_TUPLE [ - rgba: to-css-rgba bgcolor - css: add-to-string css "%s background-color: %s;" as handle! rgba - g_free as handle! rgba +] + +pango-styled-text?: func [ + text [c-string!] + underline? [logic!] + strike? [logic!] + return: [c-string!] + /local + mtext [c-string!] + tmp [c-string!] +][ + mtext: g_strdup_printf ["%s" text] + if underline? [ + tmp: g_strdup_printf ["%s" mtext] + g_free as handle! mtext + mtext: tmp + ] + if strike? [ + tmp: g_strdup_printf ["%s" mtext] + g_free as handle! mtext + mtext: tmp + ] + mtext +] + +pango-cairo-set-text: func [ + dc [draw-ctx!] + text [c-string!] + /local + status [logic!] + length [integer!] + attrs-ptr [int-ptr!] + attrs [handle!] + ptext-ptr [int-ptr!] + mtext [c-string!] + ptext [c-string!] + accel [integer!] + error [handle!] +][ + unless null? dc/layout [ + attrs-ptr: declare int-ptr! + ptext-ptr: declare int-ptr! + mtext: pango-styled-text? text dc/font-underline? dc/font-strike? + ;; DEBUG: print ["pango-cairo-set-text mtext: " mtext lf] + status: pango_parse_markup mtext -1 0 attrs-ptr ptext-ptr null null + attrs: as handle! attrs-ptr/value + ptext: as c-string! ptext-ptr/value + either status [ + pango_layout_set_text dc/layout ptext -1 + unless null? attrs [pango_layout_set_attributes dc/layout attrs] + g_free as handle! mtext + g_free as handle! ptext + ][ + pango_layout_set_text dc/layout text -1 ] ] +] - css: add-to-string css "%s}" null +pango-layout-context-set-text: func [ + layout [handle!] + dc [draw-ctx!] + text [c-string!] + /local + status [logic!] + length [integer!] + attrs-ptr [int-ptr!] + attrs [handle!] + ptext-ptr [int-ptr!] + mtext [c-string!] + ptext [c-string!] + accel [integer!] + error [handle!] +][ + unless null? layout [ + attrs-ptr: declare int-ptr! + ptext-ptr: declare int-ptr! + mtext: pango-styled-text? text dc/font-underline? dc/font-strike? + ;; DEBUG: print ["pango-cairo-set-text mtext: " mtext lf] + status: pango_parse_markup mtext -1 0 attrs-ptr ptext-ptr null null + attrs: as handle! attrs-ptr/value + ptext: as c-string! ptext-ptr/value + either status [ + pango_layout_set_text layout ptext -1 + unless null? attrs [pango_layout_set_attributes layout attrs] + g_free as handle! mtext + g_free as handle! ptext + ][ + pango_layout_set_text layout text -1 + ] + ] +] - ;; DEBUG: print ["css-styles -> css: " css lf] - - css +free-pango-cairo-font: func [ + dc [draw-ctx!] +][ + unless null? dc/font-desc [ + pango_font_description_free dc/font-desc + dc/font-desc: null + ] + unless null? dc/font-opts [ + cairo_font_options_destroy dc/font-opts + dc/font-desc: null + ] + unless null? dc/layout [ + g_object_unref dc/layout + dc/layout: null + ] ] -; Stuff maybe to REMOVE related to cairo without any success -; #enum cairo_font_slant_t! [ -; CAIRO_FONT_SLANT_NORMAL -; CAIRO_FONT_SLANT_ITALIC -; CAIRO_FONT_SLANT_OBLIQUE -; ] - -; #enum cairo_font_weight_t! [ -; CAIRO_FONT_WEIGHT_NORMAL -; CAIRO_FONT_WEIGHT_BOLD -; ] - -; select-cairo-font: func [ -; cr [handle!] -; font [red-object!] -; /local -; values [red-value!] -; style [red-word!] -; blk [red-block!] -; len [integer!] -; sym [integer!] -; str [red-string!] -; name [c-string!] -; size [red-integer!] -; css [c-string!] -; color [red-tuple!] -; bgcolor [red-tuple!] -; rgba [c-string!] -; slant [integer!] -; weight [integer!] -; ][ -; values: object/get-values font - -; ;name: -; str: as red-string! values + FONT_OBJ_NAME -; size: as red-integer! values + FONT_OBJ_SIZE -; style: as red-word! values + FONT_OBJ_STYLE -; ;angle: -; color: as red-tuple! values + FONT_OBJ_COLOR -; ;anti-alias?: - -; if TYPE_OF(str) = TYPE_STRING [ -; len: -1 -; name: unicode/to-utf8 str :len -; ] - -; len: switch TYPE_OF(style) [ -; TYPE_BLOCK [ -; blk: as red-block! style -; style: as red-word! block/rs-head blk -; block/rs-length? blk -; ] -; TYPE_WORD [1] -; default [0] -; ] - -; slant: CAIRO_FONT_SLANT_NORMAL -; weight: CAIRO_FONT_WEIGHT_NORMAL - -; unless zero? len [ -; loop len [ -; sym: symbol/resolve style/symbol -; case [ -; sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] -; sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] -; sym = _underline [] -; sym = _strike [] -; true [] -; ] -; style: style + 1 -; ] -; ] - -; ;cairo_select_font_face cr name slant weight -; cairo_select_font_face cr "Arial" 0 0 - -; if TYPE_OF(size) = TYPE_INTEGER [ -; print ["size: " size/value lf] -; cairo_set_font_size cr size/value -; ] -; ] \ No newline at end of file +make-pango-cairo-layout: func [ + cr [handle!] + fd [handle!] + return: [handle!] + /local + layout [handle!] +][ + ;; DEBUG: print ["make-pango-cairo-layout" lf] + layout: pango_cairo_create_layout cr + unless null? fd [pango_layout_set_font_description layout fd] + ;; DEBUG: print ["make-pango-cairo-layout: " dc/layout lf] + layout +] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 61833b7dc1..a42b08edd2 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -15,6 +15,9 @@ Red/System [ #define gobj_signal_connect(instance signal handler data) [ g_signal_connect_data instance signal as-integer handler data null 0 ] +#define gobj_signal_connect_after(instance signal handler data) [ + g_signal_connect_data instance signal as-integer handler data null 1 +] #define G_ASCII_DTOSTR_BUF_SIZE 39 @@ -42,6 +45,12 @@ tagRECT: alias struct! [ height [integer!] ] +GdkEventAny!: alias struct! [ + type [integer!] + window [int-ptr!] + send_event [byte!] +] + GdkEventKey!: alias struct! [ type [integer!] window [int-ptr!] @@ -108,6 +117,41 @@ GdkEventCrossing!: alias struct! [ state [integer!] ] +GdkEventConfigure!: alias struct! [ + type [integer!] + window [handle!] + send_event [byte!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] +] + +GdkEventScroll!: alias struct! [ + type [integer!] + window [handle!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + state [integer!] + direction [integer!] + device [handle!] + x_root [float!] + y_root [float!] + delta_x [float!] + delta_y [float!] + is_stop [integer!] +] + +#enum GdkScrollDirection! [ + GDK_SCROLL_UP + GDK_SCROLL_DOWN + GDK_SCROLL_LEFT + GDK_SCROLL_RIGHT + GDK_SCROLL_SMOOTH +] + #enum GGApplicationFlags! [ G_APPLICATION_FLAGS_NONE: 0 G_APPLICATION_IS_SERVICE: 1 @@ -119,16 +163,72 @@ GdkEventCrossing!: alias struct! [ ] #enum GdkModifierType! [ - GDK_SHIFT_MASK: 1 - GDK_LOCK_MASK: 2 - GDK_CONTROL_MASK: 4 - GDK_MOD1_MASK: 8 - GDK_MOD5_MASK: 128 - GDK_BUTTON1_MASK: 256 - GDK_BUTTON2_MASK: 512 - GDK_BUTTON3_MASK: 1024 - GDK_BUTTON4_MASK: 2048 - GDK_BUTTON5_MASK: 4096 + GDK_SHIFT_MASK: 1 + GDK_LOCK_MASK: 2 + GDK_CONTROL_MASK: 4 + GDK_MOD1_MASK: 8 + GDK_MOD5_MASK: 128 + GDK_BUTTON1_MASK: 256 + GDK_BUTTON2_MASK: 512 + GDK_BUTTON3_MASK: 1024 + GDK_BUTTON4_MASK: 2048 + GDK_BUTTON5_MASK: 4096 + GDK_SUPER_MASK: 67108864 + GDK_HYPER_MASK: 134217728 + GDK_META_MASK: 268435456 +] +#enum GdkEventType! [ + GDK_NOTHING: -1 + GDK_DELETE + GDK_DESTROY + GDK_EXPOSE + GDK_MOTION_NOTIFY + GDK_BUTTON_PRESS + GDK_2BUTTON_PRESS: + GDK_DOUBLE_BUTTON_PRESS: 5 + GDK_3BUTTON_PRESS: + GDK_TRIPLE_BUTTON_PRESS: 6 + GDK_BUTTON_RELEASE + GDK_KEY_PRESS + GDK_KEY_RELEASE + GDK_ENTER_NOTIFY + GDK_LEAVE_NOTIFY + GDK_FOCUS_CHANGE + GDK_CONFIGURE + GDK_MAP + GDK_UNMAP + GDK_PROPERTY_NOTIFY + GDK_SELECTION_CLEAR + GDK_SELECTION_REQUEST + GDK_SELECTION_NOTIFY + GDK_PROXIMITY_IN + GDK_PROXIMITY_OUT + GDK_DRAG_ENTER + GDK_DRAG_LEAVE + GDK_DRAG_MOTION + GDK_DRAG_STATUS + GDK_DROP_START + GDK_DROP_FINISHED + GDK_CLIENT_EVENT + GDK_VISIBILITY_NOTIFY + GDK_SCROLL: 31 + GDK_WINDOW_STATE + GDK_SETTING + GDK_OWNER_CHANGE + GDK_GRAB_BROKEN + GDK_DAMAGE + GDK_TOUCH_BEGIN + GDK_TOUCH_UPDATE + GDK_TOUCH_END + GDK_TOUCH_CANCEL + GDK_TOUCHPAD_SWIPE + GDK_TOUCHPAD_PINCH + GDK_PAD_BUTTON_PRESS + GDK_PAD_BUTTON_RELEASE + GDK_PAD_RING + GDK_PAD_STRIP + GDK_PAD_GROUP_MODE + GDK_EVENT_LAST ] #enum GdkEventMask! [ @@ -184,6 +284,88 @@ GtkTextIter!: alias struct! [ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] +#enum GtkResponseType! [ + GTK_RESPONSE_NONE + GTK_RESPONSE_REJECT + GTK_RESPONSE_ACCEPT + GTK_RESPONSE_DELETE_EVENT + GTK_RESPONSE_OK + GTK_RESPONSE_CANCEL + GTK_RESPONSE_CLOSE + GTK_RESPONSE_YES + GTK_RESPONSE_NO + GTK_RESPONSE_APPLY + GTK_RESPONSE_HELP +] + +#enum GtkJustification! [ + GTK_JUSTIFY_LEFT + GTK_JUSTIFY_RIGHT + GTK_JUSTIFY_CENTER + GTK_JUSTIFY_FILL +] + +#enum GtkWrapMode! [ + GTK_WRAP_NONE + GTK_WRAP_CHAR + GTK_WRAP_WORD + GTK_WRAP_WORD_CHAR +] + +#enum GtkAlign! [ + GTK_ALIGN_FILL + GTK_ALIGN_START + GTK_ALIGN_END + GTK_ALIGN_CENTER + GTK_ALIGN_BASELINE +] + +#enum GtkInputPurpose! [ + GTK_INPUT_PURPOSE_FREE_FORM + GTK_INPUT_PURPOSE_ALPHA + GTK_INPUT_PURPOSE_DIGITS + GTK_INPUT_PURPOSE_NUMBER + GTK_INPUT_PURPOSE_PHONE + GTK_INPUT_PURPOSE_URL + GTK_INPUT_PURPOSE_EMAIL + GTK_INPUT_PURPOSE_NAME + GTK_INPUT_PURPOSE_PASSWORD + GTK_INPUT_PURPOSE_PIN +] + +#enum GtkInputHints! [ + GTK_INPUT_HINT_NONE + GTK_INPUT_HINT_SPELLCHECK + GTK_INPUT_HINT_NO_SPELLCHECK + GTK_INPUT_HINT_WORD_COMPLETION + GTK_INPUT_HINT_LOWERCASE + GTK_INPUT_HINT_UPPERCASE_CHARS + GTK_INPUT_HINT_UPPERCASE_WORDS + GTK_INPUT_HINT_UPPERCASE_SENTENCES + GTK_INPUT_HINT_INHIBIT_OSK + GTK_INPUT_HINT_VERTICAL_WRITING + GTK_INPUT_HINT_EMOJI + GTK_INPUT_HINT_NO_EMOJI +] + +PangoAttribute!: alias struct! [ + klass [handle!] + start [integer!] + end [integer!] +] + +#enum PangoWrapMode! [ + PANGO_WRAP_WORD + PANGO_WRAP_CHAR + PANGO_WRAP_WORD_CHAR +] + +#enum PangoEllipsizeMode! [ + PANGO_ELLIPSIZE_NONE + PANGO_ELLIPSIZE_START + PANGO_ELLIPSIZE_MIDDLE + PANGO_ELLIPSIZE_END +] #enum pango-style! [ PANGO_STYLE_NORMAL @@ -196,6 +378,14 @@ GtkTextIter!: alias struct! [ PANGO_VARIANT_SMALL_CAPS ] +#enum pango-underline! [ + PANGO_UNDERLINE_NONE + PANGO_UNDERLINE_SINGLE + PANGO_UNDERLINE_DOUBLE + PANGO_UNDERLINE_LOW + PANGO_UNDERLINE_ERROR +] + #enum pango-weight! [ PANGO_WEIGHT_THIN: 100 PANGO_WEIGHT_ULTRALIGHT: 200 @@ -233,6 +423,12 @@ GtkTextIter!: alias struct! [ PANGO_FONT_MASK_GRAVITY: 64 ] +#enum PangoAlignment! [ + PANGO_ALIGN_LEFT + PANGO_ALIGN_CENTER + PANGO_ALIGN_RIGHT +] + #define PANGO_SCALE 1024 #define PANGO_SCALE_XX_SMALL 0.5787037037037 #define PANGO_SCALE_X_SMALL 0.6444444444444 @@ -253,11 +449,30 @@ GtkTextIter!: alias struct! [ CAIRO_FONT_WEIGHT_BOLD ] +#enum cairo_antialias_t! [ + CAIRO_ANTIALIAS_DEFAULT + CAIRO_ANTIALIAS_NONE + CAIRO_ANTIALIAS_GRAY + CAIRO_ANTIALIAS_SUBPIXEL + CAIRO_ANTIALIAS_FAST + CAIRO_ANTIALIAS_GOOD + CAIRO_ANTIALIAS_BEST +] + +cairo_matrix_t!: alias struct! [ + xx [float!] + yx [float!] + xy [float!] + yy [float!] + x0 [float!] + y0 [float!] +] + ; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo ; cairo_text_extents_t!: alias struct! [ ; x_bearing [float!] ; y_bearing [float!] -; width [float!] +; width [float!] ; height [float!] ; x_advance [float!] ; y_advance [float!] @@ -271,6 +486,56 @@ cairo_font_extents_t!: alias struct! [ max_y_advance [float!] ] +#enum cairo_format_t! [ + CAIRO_FORMAT_INVALID + CAIRO_FORMAT_ARGB32 + CAIRO_FORMAT_RGB24 + CAIRO_FORMAT_A8 + CAIRO_FORMAT_A1 + CAIRO_FORMAT_RGB16_565 + CAIRO_FORMAT_RGB30 +] + +GString!: alias struct! [ + str [c-string!] + len [integer!] + allocated_len [integer!] +] + +GList!: alias struct! [ + data [int-ptr!] + next [GList!] + prev [GList!] +] + +GPtrArray!: alias struct! [ + pdata [int-ptr!] + len [integer!] +] + +#enum GtkPackDirection! [ + GTK_PACK_DIRECTION_LTR + GTK_PACK_DIRECTION_RTL + GTK_PACK_DIRECTION_TTB + GTK_PACK_DIRECTION_BTT +] + +#enum GtkOrientation! [ + GTK_ORIENTATION_HORIZONTAL + GTK_ORIENTATION_VERTICAL +] + +#enum GConnectFlags! [ + G_CONNECT_AFTER + G_CONNECT_SWAPPED +] + +#define GTK_STYLE_PROVIDER_PRIORITY_FALLBACK 1 +#define GTK_STYLE_PROVIDER_PRIORITY_THEME 200 +#define GTK_STYLE_PROVIDER_PRIORITY_SETTINGS 400 +#define GTK_STYLE_PROVIDER_PRIORITY_APPLICATION 600 +#define GTK_STYLE_PROVIDER_PRIORITY_USER 800 + #either OS = 'Windows [ ;#define LIBGOBJECT-file "libgobject-2.0-0.dll" ;#define LIBGLIB-file "libglib-2.0-0.dll" @@ -290,6 +555,10 @@ cairo_font_extents_t!: alias struct! [ #import [ LIBGTK-file cdecl [ ;; LIBGOBJECT-file cdecl [ + g_object_new: "g_object_new" [ + [variadic] + return: [handle!] + ] g_object_set_qdata: "g_object_set_qdata" [ object [int-ptr!] quark [integer!] @@ -306,6 +575,9 @@ cairo_font_extents_t!: alias struct! [ g_object_get: "g_object_get" [ [variadic] ] + g_clear_object: "g_clear_object" [ + obj-ptr [integer!] + ] g_signal_connect_data: "g_signal_connect_data" [ instance [int-ptr!] signal [c-string!] @@ -315,6 +587,18 @@ cairo_font_extents_t!: alias struct! [ flags [integer!] return: [integer!] ] + g_signal_emit_by_name: "g_signal_emit_by_name" [ + instance [int-ptr!] + signal [c-string!] + ] + g_object_ref: "g_object_ref" [ + object [int-ptr!] + return: [int-ptr!] + ] + g_object_ref_sink: "g_object_ref_sink" [ + object [int-ptr!] + return: [int-ptr!] + ] g_object_unref: "g_object_unref" [ object [int-ptr!] ] @@ -328,6 +612,11 @@ cairo_font_extents_t!: alias struct! [ data [int-ptr!] return: [integer!] ] + g_idle_add: "g_idle_add" [ + handler [integer!] + data [int-ptr!] + return: [integer!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ @@ -350,10 +639,29 @@ cairo_font_extents_t!: alias struct! [ code [integer!] return: [integer!] ] + gdk_keyval_to_lower: "gdk_keyval_to_lower" [ + code [integer!] + return: [integer!] + ] + gdk_keyval_is_upper: "gdk_keyval_is_upper" [ + code [integer!] + return: [logic!] + ] + gdk_keyval_is_lower: "gdk_keyval_is_lower" [ + code [integer!] + return: [logic!] + ] gdk_atom_intern_static_string: "gdk_atom_intern_static_string" [ name [c-string!] return: [handle!] ] + gdk_display_get_default: "gdk_display_get_default" [ + return: [handle!] + ] + gdk_display_get_default_screen: "gdk_display_get_default_screen" [ + display [handle!] + return: [handle!] + ] ;; ] ;; LIBGLIB-file cdecl [ g_quark_from_string: "g_quark_from_string" [ @@ -375,15 +683,58 @@ cairo_font_extents_t!: alias struct! [ block? [logic!] return: [logic!] ] + g_main_context_pending: "g_main_context_pending" [ + context [integer!] + return: [logic!] + ] + g_main_context_is_owner: "g_main_context_is_owner" [ + context [integer!] + return: [logic!] + ] + g_main_current_source: "g_main_current_source" [ + return: [handle!] + ] g_list_length: "g_list_length" [ - list [int-ptr!] + list [int-ptr!] return: [integer!] ] + g_list_free: "g_list_free" [ + list [int-ptr!] + ] g_list_nth_data: "g_list_nth_data" [ - list [int-ptr!] + list [handle!] nth [integer!] return: [handle!] ] + g_list_append: "g_list_append" [ + list [handle!] + data [handle!] + return: [handle!] + ] + g_list_prepend: "g_list_prepend" [ + list [handle!] + data [handle!] + return: [handle!] + ] + g_list_first: "g_list_first" [ + list [handle!] + return: [handle!] + ] + g_list_last: "g_list_last" [ + list [handle!] + return: [handle!] + ] + g_list_delete_link: "g_list_delete_link" [ + list [handle!] + link [handle!] + return: [handle!] + ] + g_list_insert_sorted: "g_list_insert_sorted" [ + list [handle!] + data [handle!] + comp-func [integer!] + return: [handle!] + ] g_ascii_dtostr: "g_ascii_dtostr" [ buffer [c-string!] buf_len [integer!] @@ -394,18 +745,67 @@ cairo_font_extents_t!: alias struct! [ [variadic] return: [c-string!] ] + g_strdup: "g_strdup" [ + str [c-string!] + return: [c-string!] + ] + g_strndup: "g_strndup"[ + str [c-string!] + n [integer!] + return: [c-string!] + ] + g_strconcat: "g_strconcat" [ + [variadic] + return: [c-string!] + ] + g_strcmp0: "g_strcmp0" [ + str [c-string!] + str2 [c-string!] + return: [integer!] + ] + g_strsplit: "g_strsplit" [ + str [c-string!] + delim [c-string!] + tokens [integer!] + return: [handle!] + ] + g_strsplit_set: "g_strsplit_set" [ + str [c-string!] + delim [c-string!] + tokens [integer!] + return: [handle!] + ] g_free: "g_free" [ - pointer [handle!] + ptr [handle!] + ] + g_strfreev: "g_strfreev" [ + str_array [handle!] ] g_string_new: "g_string_new" [ - return: [handle!] + return: [GString!] + ] + g_string_sized_new: "g_string_sized_new" [ + dfl_size [integer!] + return: [GString!] ] g_string_append: "g_string_append" [ - str [handle!] + str [GString!] + text [c-string!] + return: [GString!] + ] + g_string_assign: "g_string_assign" [ + str [GString!] + text [c-string!] + return: [GString!] + ] + g_string_append_len: "g_string_append_len" [ + str [GString!] text [c-string!] + len [integer!] + return: [GString!] ] g_string_free: "g_string_free" [ - str [handle!] + str [GString!] free [logic!] return: [c-string!] ] @@ -425,8 +825,87 @@ cairo_font_extents_t!: alias struct! [ return: [logic!] ] g_settings_sync: "g_settings_sync" [] + gtk_disable_setlocale: "gtk_disable_setlocale" [] ;; ] ;; LIBGTK-file cdecl [ + gtk_get_major_version: "gtk_get_major_version" [ + return: [integer!] + ] + gtk_get_minor_version: "gtk_get_minor_version" [ + return: [integer!] + ] + gtk_get_micro_version: "gtk_get_micro_version" [ + return: [integer!] + ] + gdk_cursor_new_from_pixbuf: "gdk_cursor_new_from_pixbuf" [ + display [handle!] + pixbuf [handle!] + x [integer!] + y [integer!] + return: [handle!] + ] + gdk_cursor_new_from_name: "gdk_cursor_new_from_name" [ + display [handle!] + name [c-string!] + return: [handle!] + ] + gtk_get_current_event_time: "gtk_get_current_event_time" [ + return: [integer!] + ] + gtk_get_current_event_state: "gtk_get_current_event_state" [ + state [int-ptr!] + ] + gtk_get_current_event: "gtk_get_current_event" [ + return: [handle!] + ] + gtk_get_current_event_device: "gtk_get_current_event_device" [ + return: [handle!] + ] + gtk_get_event_widget: "gtk_get_event_widget" [ + event [handle!] + return: [handle!] + ] + gdk_event_get: "gdk_event_get" [ + return: [handle!] + ] + gdk_event_peek: "gdk_event_peek" [ + return: [handle!] + ] + gdk_event_copy: "gdk_event_copy" [ + event [handle!] + return: [handle!] + ] + gdk_event_free: " gdk_event_free" [ + event [handle!] + ] + gdk_event_get_scroll_deltas: "gdk_event_get_scroll_deltas" [ + event [handle!] + dx [float-ptr!] + dy [float-ptr!] + return: [integer!] + ] + + gdk_event_get_scroll_direction: "gdk_event_get_scroll_direction" [ + event [handle!] + direction [int-ptr!] + ] + gdk_window_get_display: "gdk_window_get_display" [ + window [handle!] + return: [handle!] + ] + gdk_window_get_device_position: "gdk_window_get_device_position" [ + window [handle!] + device [handle!] + x [int-ptr!] + y [int-ptr!] + mask [handle!] + return: [handle!] + ] + gdk_window_invalidate_rect: "gdk_window_invalidate_rect" [ + window [handle!] + rect [tagRECT] + invalidate_children [logic!] + ] gtk_application_new: "gtk_application_new" [ app-id [c-string!] flags [integer!] @@ -452,6 +931,119 @@ cairo_font_extents_t!: alias struct! [ app [handle!] window [handle!] ] + gtk_menu_bar_new: "gtk_menu_bar_new" [ + return: [handle!] + ] + gtk_menu_bar_set_pack_direction: "gtk_menu_bar_set_pack_direction" [ + menubar [handle!] + dir [GtkPackDirection!] + ] + gtk_menu_bar_set_child_pack_direction: "gtk_menu_bar_set_child_pack_direction" [ + menubar [handle!] + dir [GtkPackDirection!] + ] + gtk_menu_new: "gtk_menu_new" [ + return: [handle!] + ] + gtk_menu_popup_at_pointer: "gtk_menu_popup_at_pointer" [ + menu [handle!] + event [handle!] + ] + gtk_menu_shell_append: "gtk_menu_shell_append" [ + menu [handle!] + item [handle!] + ] + gtk_menu_shell_prepend: "gtk_menu_shell_prepend" [ + menu [handle!] + item [handle!] + ] + gtk_menu_shell_insert: "gtk_menu_shell_insert" [ + menu [handle!] + item [handle!] + pos [integer!] + ] + gtk_menu_shell_select_item: "gtk_menu_shell_select_item" [ + menu [handle!] + item [handle!] + ] + gtk_menu_shell_select_first: "gtk_menu_shell_select_first" [ + menu [handle!] + sensitive [logic!] + ] + gtk_menu_shell_deselect: "gtk_menu_shell_deselect" [ + menu [handle!] + ] + gtk_menu_shell_activate_item: "gtk_menu_shell_activate_item" [ + menu [handle!] + item [handle!] + force [integer!] + ] + gtk_menu_shell_cancel: "gtk_menu_shell_cancel" [ + menu [handle!] + ] + gtk_menu_shell_set_take_focus: "gtk_menu_shell_set_take_focus" [ + menu [handle!] + focus [integer!] + ] + gtk_menu_shell_get_take_focus: "gtk_menu_shell_get_take_focus" [ + menu [handle!] + return: [integer!] + ] + gtk_menu_shell_get_selected_item: "gtk_menu_shell_get_selected_item" [ + menu [handle!] + return: [handle!] + ] + gtk_menu_shell_get_parent_shell: "gtk_menu_shell_get_parent_shell" [ + menu [handle!] + return: [handle!] + ] + gtk_menu_item_new: "gtk_menu_item_new" [ + return: [handle!] + ] + gtk_menu_item_new_with_label: "gtk_menu_item_new_with_label" [ + label [c-string!] + return: [handle!] + ] + gtk_menu_item_new_with_mnemonic: "gtk_menu_item_new_with_mnemonic" [ + label [c-string!] + return: [handle!] + ] + gtk_menu_item_get_label: "gtk_menu_item_get_label" [ + item [handle!] + return: [c-string!] + ] + gtk_menu_item_set_label: "gtk_menu_item_set_label" [ + item [handle!] + label [c-string!] + ] + gtk_menu_item_get_use_underline: "gtk_menu_item_get_use_underline" [ + item [handle!] + return: [logic!] + ] + gtk_menu_item_set_use_underline: "gtk_menu_item_set_use_underline" [ + item [handle!] + setting [logic!] + ] + gtk_menu_item_set_submenu: "gtk_menu_item_set_submenu" [ + item [handle!] + submenu [handle!] + ] + gtk_menu_item_get_submenu: "gtk_menu_item_get_submenu" [ + item [handle!] + return: [handle!] + ] + gtk_menu_item_select: "gtk_menu_item_select" [ + item [handle!] + ] + gtk_menu_item_deselect: "gtk_menu_item_deselect" [ + item [handle!] + ] + gtk_menu_item_activate: "gtk_menu_item_activate" [ + item [handle!] + ] + gtk_separator_menu_item_new: "gtk_separator_menu_item_new" [ + return: [handle!] + ] gtk_file_chooser_dialog_new: "gtk_file_chooser_dialog_new" [ [variadic] return: [handle!] @@ -460,6 +1052,10 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] return: [integer!] ] + gtk_dialog_response: "gtk_dialog_response" [ + widget [handle!] + resp [integer!] + ] gtk_file_chooser_get_filename: "gtk_file_chooser_get_filename" [ widget [handle!] return: [c-string!] @@ -481,6 +1077,12 @@ cairo_font_extents_t!: alias struct! [ font-sel [handle!] return: [handle!] ] + gtk_init: "gtk_init" [ + argc [int-ptr!] + argv [handle!] + ] + gtk_main: "gtk_main" [] + gtk_main_quit: "gtk_main_quit" [] gtk_main_iteration: "gtk_main_iteration" [ return: [logic!] ] @@ -500,6 +1102,10 @@ cairo_font_extents_t!: alias struct! [ width [integer!] height [integer!] ] + gtk_window_set_resizable: "gtk_window_set_resizable" [ + window [handle!] + mode [logic!] + ] gtk_window_move: "gtk_window_move" [ window [handle!] x [integer!] @@ -530,12 +1136,67 @@ cairo_font_extents_t!: alias struct! [ window [handle!] setting [logic!] ] + gtk_window_get_size: "gtk_window_get_size" [ + window [handle!] + width [handle!] + height [handle!] + ] + gtk_window_propagate_key_event: "gtk_window_propagate_key_event" [ + widget [handle!] + event [handle!] + ] + gtk_window_get_focus: "gtk_window_get_focus" [ + window [handle!] + return: [handle!] + ] + gtk_window_set_focus: "gtk_window_set_focus" [ + window [handle!] + widget [handle!] + ] + gtk_window_get_default_widget: "gtk_window_get_default_widget" [ + window [handle!] + return: [handle!] + ] + gtk_window_set_default: "gtk_window_set_default" [ + window [handle!] + default_widget [handle!] + ] + gtk_propagate_event: "gtk_propagate_event" [ + widget [handle!] + event [handle!] + ] + gtk_widget_register_window: "gtk_widget_register_window" [ + widget [handle!] + window [handle!] + ] + gtk_widget_unregister_window: "gtk_widget_unregister_window" [ + widget [handle!] + window [handle!] + ] + gtk_widget_event: "gtk_widget_event" [ + widget [handle!] + event [handle!] + return: [logic!] + ] gtk_widget_queue_draw: "gtk_widget_queue_draw" [ widget [handle!] ] + gtk_widget_queue_draw_area: "gtk_widget_queue_draw_area" [ + widget [handle!] + x [integer!] + y [integer!] + w [integer!] + h [integer!] + ] + gtk_widget_queue_resize: "gtk_widget_queue_resize" [ + widget [handle!] + ] gtk_widget_queue_resize_no_redraw: "gtk_widget_queue_resize_no_redraw" [ widget [handle!] ] + gtk_widget_queue_allocate: "gtk_widget_queue_allocate" [ + widget [handle!] + ] gtk_widget_show_all: "gtk_widget_show_all" [ widget [handle!] ] @@ -545,21 +1206,67 @@ cairo_font_extents_t!: alias struct! [ gtk_widget_show: "gtk_widget_show" [ widget [handle!] ] + gtk_widget_show_now: "gtk_widget_show_now" [ + widget [handle!] + ] + gtk_widget_realize: "gtk_widget_realize" [ + widget [handle!] + ] + gtk_widget_activate: "gtk_widget_activate" [ + widget [handle!] + return: [logic!] + ] gtk_widget_set_halign: "gtk_widget_set_halign" [ widget [handle!] type [integer!] ] + gtk_widget_set_hexpand: "gtk_widget_set_hexpand" [ + widget [handle!] + type [logic!] + ] + gtk_widget_set_vexpand: "gtk_widget_set_vexpand" [ + widget [handle!] + type [logic!] + ] + gtk_widget_compute_expand: "gtk_widget_compute_expand" [ + widget [handle!] + orient [GtkOrientation!] + return: [logic!] + ] gtk_widget_set_visible: "gtk_widget_set_visible" [ widget [handle!] state [logic!] ] + gtk_widget_get_visible: "gtk_widget_get_visible" [ + widget [handle!] + return: [logic!] + ] + gtk_widget_is_visible: "gtk_widget_is_visible" [ + widget [handle!] + return: [logic!] + ] gtk_widget_set_sensitive: "gtk_widget_set_sensitive" [ widget [handle!] state [logic!] ] + gtk_widget_get_sensitive: "gtk_widget_get_sensitive" [ + widget [handle!] + return: [logic!] + ] + gtk_widget_is_sensitive: "gtk_widget_is_sensitive" [ + widget [handle!] + return: [logic!] + ] + gtk_widget_is_focus: "gtk_widget_is_focus" [ + widget [handle!] + return: [logic!] + ] gtk_widget_grab_focus: "gtk_widget_grab_focus" [ widget [handle!] ] + gtk_widget_grab_default: "gtk_widget_grab_default" [ + widget [handle!] + ] gtk_widget_set_size_request: "gtk_widget_set_size_request" [ widget [handle!] width [integer!] @@ -574,11 +1281,6 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] alloc [handle!] ] - gtk_widget_compute_expand: "gtk_widget_compute_expand" [ - widget [handle!] - direction [integer!] - return: [logic!] - ] gtk_widget_get_allocation: "gtk_widget_get_allocation" [ widget [handle!] alloc [handle!] @@ -595,21 +1297,49 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] focus [logic!] ] + gtk_widget_set_can_default: "gtk_widget_set_can_default" [ + widget [handle!] + can_default [logic!] + ] gtk_widget_set_focus_on_click: "gtk_widget_set_focus_on_click" [ widget [handle!] focus [logic!] ] - gtk_widget_destroy: "gtk_widget_destroy" [ - widget [handle!] + gtk_widget_get_can_default: "gtk_widget_get_can_default" [ + widget [handle!] + return: [logic!] ] - gtk_widget_create_pango_layout: "gtk_widget_create_pango_layout" [ - widget [handle!] + gtk_widget_get_focus_on_click: "gtk_widget_get_focus_on_click" [ + widget [handle!] + return: [logic!] + ] + gtk_widget_get_parent: "gtk_widget_get_parent" [ + widget [handle!] + return: [handle!] + ] + gtk_widget_get_toplevel: "gtk_widget_get_toplevel" [ + widget [handle!] + return: [handle!] + ] + gtk_widget_destroy: "gtk_widget_destroy" [ + widget [handle!] + ] + gtk_widget_create_pango_layout: "gtk_widget_create_pango_layout" [ + widget [handle!] text [c-string!] return: [handle!] ] + gtk_widget_create_pango_context: "gtk_widget_create_pango_context" [ + widget [handle!] + return: [handle!] + ] gtk_widget_add_events: "gtk_widget_add_events" [ widget [handle!] - mask [integer!] + mask [integer!] + ] + gtk_widget_get_events: "gtk_widget_get_events" [ + widget [handle!] + return: [integer!] ] gtk_widget_override_font: "gtk_widget_override_font" [ widget [handle!] @@ -637,6 +1367,13 @@ cairo_font_extents_t!: alias struct! [ container [handle!] widget [handle!] ] + gtk_container_get_focus_child: "gtk_container_get_focus_child" [ + container [handle!] + return: [handle!] + ] + gtk_container_child_set: "gtk_container_child_set" [ + [variadic] + ] gtk_frame_new: "gtk_frame_new" [ label [c-string!] return: [handle!] @@ -654,31 +1391,63 @@ cairo_font_extents_t!: alias struct! [ frame [handle!] shadow [integer!] ] + gtk_box_new: "gtk_box_new" [ + orient [GtkOrientation!] + spacing [integer!] + return: [handle!] + ] + gtk_box_pack_start: "gtk_box_pack_start" [ + box [handle!] + widget [handle!] + expand [logic!] + fill [logic!] + padding [integer!] + ] gtk_fixed_new: "gtk_fixed_new" [ return: [handle!] ] gtk_fixed_put: "gtk_fixed_put" [ - fixed [handle!] + fixed [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ] gtk_fixed_move: "gtk_fixed_move" [ - fixed [handle!] + fixed [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ] gtk_layout_new: "gtk_layout_new" [ - hadj [handle!] - vadj [handle!] + hadj [handle!] + vadj [handle!] return: [handle!] ] gtk_layout_put: "gtk_layout_put" [ layout [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] + ] + gtk_layout_move: "gtk_layout_move" [ + layout [handle!] + widget [handle!] + x [integer!] + y [integer!] + ] + gtk_layout_set_size: "gtk_layout_set_size" [ + layout [handle!] + w [integer!] + h [integer!] + ] + gtk_layout_get_size: "gtk_layout_get_size" [ + layout [handle!] + w [int-ptr!] + h [int-ptr!] + ] + gtk_layout_get_bin_window: "gtk_layout_get_bin_window" [ + layout [handle!] + return: [handle!] ] gtk_bin_get_child: "gtk_bin_get_child" [ bin [handle!] @@ -717,6 +1486,10 @@ cairo_font_extents_t!: alias struct! [ label [c-string!] return: [handle!] ] + gtk_button_get_label: "gtk_button_get_label" [ + button [handle!] + return: [c-string!] + ] gtk_button_set_label: "gtk_button_set_label" [ button [handle!] label [c-string!] @@ -755,9 +1528,19 @@ cairo_font_extents_t!: alias struct! [ button [handle!] active? [logic!] ] + gtk_toggle_button_toggled: "gtk_toggle_button_toggled" [ + button [handle!] + ] + gtk_radio_button_get_group: "gtk_radio_button_get_group" [ + radio [handle!] + return: [handle!] + ] gtk_drawing_area_new: "gtk_drawing_area_new" [ return: [handle!] ] + gtk_image_new: "gtk_image_new" [ + return: [handle!] + ] gtk_image_new_from_pixbuf: "gtk_image_new_from_pixbuf" [ pixbuf [handle!] return: [handle!] @@ -766,6 +1549,10 @@ cairo_font_extents_t!: alias struct! [ filename [c-string!] return: [handle!] ] + gtk_image_set_from_pixbuf: "gtk_image_set_from_pixbuf" [ + widget [handle!] + pixbuf [handle!] + ] gtk_label_new: "gtk_label_new" [ label [c-string!] return: [handle!] @@ -778,6 +1565,18 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] label [c-string!] ] + gtk_label_set_markup: "gtk_label_set_markup" [ + widget [handle!] + label [c-string!] + ] + gtk_label_set_justify: "gtk_label_set_justify" [ + widget [handle!] + justify [integer!] + ] + gtk_label_set_line_wrap: "gtk_label_set_line_wrap" [ + widget [handle!] + wrap [logic!] + ] gtk_event_box_new: "gtk_event_box_new" [ return: [handle!] ] @@ -788,10 +1587,18 @@ cairo_font_extents_t!: alias struct! [ entry [handle!] nchars [integer!] ] + gtk_entry_set_max_width_chars: "gtk_entry_set_max_width_chars" [ + entry [handle!] + nchars [integer!] + ] gtk_entry_get_buffer: "gtk_entry_get_buffer" [ entry [handle!] return: [handle!] ] + gtk_entry_get_layout: "gtk_entry_get_layout" [ + entry [handle!] + return: [handle!] + ] gtk_entry_get_text: "gtk_entry_get_text" [ buffer [handle!] return: [c-string!] @@ -800,11 +1607,30 @@ cairo_font_extents_t!: alias struct! [ buffer [handle!] text [c-string!] ] + gtk_entry_set_placeholder_text: "gtk_entry_set_placeholder_text" [ + buffer [handle!] + text [c-string!] + ] + gtk_entry_set_visibility: "gtk_entry_set_visibility" [ + entry [handle!] + visible [logic!] + ] gtk_entry_buffer_set_text: "gtk_entry_buffer_set_text" [ buffer [handle!] text [c-string!] len [integer!] ] + gtk_editable_select_region: "gtk_editable_select_region" [ + entry [handle!] + start [integer!] + end [integer!] + ] + gtk_editable_get_selection_bounds: "gtk_editable_get_selection_bounds" [ + entry [handle!] + start [int-ptr!] + end [int-ptr!] + return: [logic!] + ] gtk_scale_new_with_range: "gtk_scale_new_with_range" [ vertical? [logic!] @@ -855,6 +1681,14 @@ cairo_font_extents_t!: alias struct! [ view [handle!] return: [handle!] ] + gtk_text_view_set_justification: "gtk_text_view_set_justification" [ + view [handle!] + justify [integer!] + ] + gtk_text_view_set_wrap_mode: "gtk_text_view_set_wrap_mode" [ + view [handle!] + mode [integer!] + ] gtk_text_buffer_set_text: "gtk_text_buffer_set_text" [ buffer [handle!] text [c-string!] @@ -872,10 +1706,33 @@ cairo_font_extents_t!: alias struct! [ start [handle!] end [handle!] ] + gtk_text_buffer_get_selection_bounds: "gtk_text_buffer_get_selection_bounds" [ + buffer [handle!] + start [handle!] + end [handle!] + return: [logic!] + ] + gtk_text_buffer_select_range: "gtk_text_buffer_select_range" [ + buffer [handle!] + ins [handle!] + bound [handle!] + ] gtk_text_buffer_create_tag: "gtk_text_buffer_create_tag" [ [variadic] return: [handle!] ] + gtk_text_iter_get_offset: "gtk_text_iter_get_offset" [ + iter [handle!] + return: [integer!] + ] + gtk_text_iter_set_offset: "gtk_text_iter_set_offset" [ + iter [handle!] + offset [integer!] + ] + gtk_text_iter_get_line: "gtk_text_iter_get_line" [ + iter [handle!] + return: [integer!] + ] gtk_combo_box_text_new: "gtk_combo_box_text_new" [ return: [handle!] ] @@ -901,6 +1758,10 @@ cairo_font_extents_t!: alias struct! [ combo [handle!] return: [c-string!] ] + gtk_combo_box_set_popup_fixed_width: "gtk_combo_box_set_popup_fixed_width" [ + combo [handle!] + fixed [logic!] + ] gtk_notebook_new: "gtk_notebook_new" [ return: [handle!] ] @@ -915,6 +1776,11 @@ cairo_font_extents_t!: alias struct! [ return: [integer!] ] + gtk_notebook_set_current_page: "gtk_notebook_set_current_page" [ + nb [handle!] + index [integer!] + ] + gtk_notebook_get_nth_page: "gtk_notebook_get_nth_page" [ nb [handle!] index [integer!] @@ -938,6 +1804,16 @@ cairo_font_extents_t!: alias struct! [ length [integer!] error [handle!] ] + gtk_css_provider_load_from_file: "gtk_css_provider_load_from_file" [ + provider [handle!] + url [c-string!] + error [handle!] + ] + gtk_css_provider_load_from_path: "gtk_css_provider_load_from_path" [ + provider [handle!] + path [c-string!] + error [handle!] + ] gtk_style_context_add_provider: "gtk_style_context_add_provider" [ context [handle!] provider [handle!] @@ -969,24 +1845,211 @@ cairo_font_extents_t!: alias struct! [ widget [handle!] return: [handle!] ] + gtk_render_background: "gtk_render_background" [ + style [handle!] + cr [handle!] + x [float!] + y [float!] + w [float!] + h [float!] + ] pango_layout_new: "pango_layout_new" [ context [handle!] return: [handle!] ] - pango_layout_set_text: "pango_layout_set_text" [ + pango_layout_copy: "pango_layout_copy" [ + context [handle!] + return: [handle!] + ] + pango_layout_get_context: "pango_layout_get_context" [ + layout [handle!] + return: [handle!] + ] + pango_layout_set_text: "pango_layout_set_text" [ layout [handle!] text [c-string!] len [integer!] ] - pango_layout_set_font_description: "pango_layout_set_font_description" [ + pango_layout_set_markup: "pango_layout_set_markup" [ + layout [handle!] + markup [c-string!] + len [integer!] + ] + pango_layout_set_markup_with_accel: "pango_layout_set_markup_with_accel" [ + layout [handle!] + markup [c-string!] + len [integer!] + accel_mark [integer!] + accel_char [int-ptr!] + ] + pango_layout_set_font_description: "pango_layout_set_font_description" [ layout [handle!] fontdesc [handle!] ] - pango_layout_get_pixel_size: "pango_layout_get_pixel_size" [ + pango_layout_get_pixel_size: "pango_layout_get_pixel_size" [ layout [handle!] width [int-ptr!] height [int-ptr!] ] + pango_layout_get_line: "pango_layout_get_line" [ + layout [handle!] + line [integer!] + return: [handle!] + ] + pango_layout_get_line_readonly: "pango_layout_get_line_readonly" [ + layout [handle!] + line [integer!] + return: [handle!] + ] + pango_layout_get_character_count: "pango_layout_get_character_count" [ + layout [handle!] + return: [integer!] + ] + pango_layout_is_wrapped: "pango_layout_is_wrapped" [ + layout [handle!] + return: [logic!] + ] + pango_layout_set_wrap: "pango_layout_set_wrap" [ + layout [handle!] + mode [PangoWrapMode!] + ] + pango_layout_get_wrap: "pango_layout_get_wrap" [ + layout [handle!] + return: [PangoWrapMode!] + ] + pango_layout_is_ellipsized: "pango_layout_is_ellipsized" [ + layout [handle!] + return: [logic!] + ] + pango_layout_set_ellipsize: "pango_layout_set_ellipsize" [ + layout [handle!] + mode [PangoEllipsizeMode!] + ] + pango_layout_get_ellipsize: "pango_layout_get_ellipsize" [ + layout [handle!] + return: [PangoEllipsizeMode!] + ] + pango_layout_get_indent: "pango_layout_get_indent" [ + layout [handle!] + return: [integer!] + ] + pango_layout_set_indent: "pango_layout_set_indent" [ + layout [handle!] + indent [integer!] + ] + pango_layout_get_spacing: "pango_layout_get_spacing" [ + layout [handle!] + return: [integer!] + ] + pango_layout_set_spacing: "pango_layout_set_spacing" [ + layout [handle!] + spacing [integer!] + ] + pango_layout_get_justify: "pango_layout_get_justify" [ + layout [handle!] + return: [logic!] + ] + pango_layout_set_justify: "pango_layout_set_justify" [ + layout [handle!] + justify [logic!] + ] + pango_layout_set_alignment: "pango_layout_set_alignment" [ + layout [handle!] + align [PangoAlignment!] + ] + pango_layout_get_alignment: "pango_layout_get_alignment" [ + layout [handle!] + return: [PangoAlignment!] + ] + pango_layout_set_width: "pango_layout_set_width" [ + layout [handle!] + width [integer!] + ] + pango_layout_get_width: "pango_layout_get_width" [ + layout [handle!] + return: [integer!] + ] + pango_layout_set_height: "pango_layout_set_height" [ + layout [handle!] + height [integer!] + ] + pango_layout_get_height: "pango_layout_get_height" [ + layout [handle!] + return: [integer!] + ] + pango_layout_get_size: "pango_layout_get_size" [ + layout [handle!] + width [int-ptr!] + height [int-ptr!] + ] + pango_layout_set_attributes: "pango_layout_set_attributes" [ + layout [handle!] + attrs [handle!] + ] + pango_layout_get_iter: "pango_layout_get_iter" [ + layout [handle!] + return: [handle!] + ] + pango_layout_iter_get_baseline: "pango_layout_iter_get_baseline" [ + iter [handle!] + return: [integer!] + ] + pango_layout_get_extents: "pango_layout_get_extents" [ + layout [handle!] + irect [tagRECT] + lrect [tagRECT] + ] + pango_layout_get_pixel_extents: "pango_layout_get_pixel_extents" [ + layout [handle!] + irect [tagRECT] + lrect [tagRECT] + ] + pango_layout_index_to_pos: "pango_layout_index_to_pos" [ + layout [handle!] + index [integer!] + pos [tagRECT] + ] + pango_layout_index_to_line_x: "pango_layout_index_to_line_x" [ + layout [handle!] + index [integer!] + trailing [integer!] + line [int-ptr!] + x-pos [int-ptr!] + ] + pango_layout_xy_to_index: "pango_layout_xy_to_index" [ + layout [handle!] + x [integer!] + y [integer!] + index [int-ptr!] + trailing [int-ptr!] + return: [logic!] + ] + pango_layout_get_cursor_pos: "pango_layout_get_cursor_pos" [ + layout [handle!] + index [integer!] + spos [tagRECT] + wpos [tagRECT] + ] + pango_layout_move_cursor_visually: "pango_layout_move_cursor_visually" [ + layout [handle!] + strong [logic!] + old_ind [integer!] + old_trail [integer!] + direct [integer!] + new_ind [int-ptr!] + new_trail [int-ptr!] + ] + pango_layout_get_line_count: "pango_layout_get_line_count" [ + layout [handle!] + return: [integer!] + ] + pango_layout_line_get_pixel_extents: "pango_layout_line_get_pixel_extents" [ + line [handle!] + irect [tagRECT] + lrect [tagRECT] + ] + + pango_font_description_new: "pango_font_description_new" [ return: [handle!] ] @@ -1052,16 +2115,48 @@ cairo_font_extents_t!: alias struct! [ gdk_pango_context_get: "gdk_pango_context_get" [ return: [handle!] ] + + gdk_pango_context_get_for_screen: "gdk_pango_context_get_for_screen" [ + screen [handle!] + return: [handle!] + ] + + + + gtk_widget_get_pango_context: "gtk_widget_get_pango_context" [ + return: [handle!] + ] + gtk_settings_get_default: "gtk_settings_get_default" [ return: [handle!] ] ;; LIBCAIRO-file cdecl [ + cairo_create: "cairo_create" [ + surf [handle!] + return: [handle!] + ] + + cairo_destroy: "cairo_destroy" [ + cr [handle!] + ] + + cairo_clip: "cairo_clip" [ + cr [handle!] + ] + cairo_line_to: "cairo_line_to" [ cr [handle!] - x [float!] - y [float!] + x [float!] + y [float!] + ] + + cairo_rel_line_to: "cairo_rel_line_to" [ + cr [handle!] + dx [float!] + dy [float!] ] + cairo_curve_to: "cairo_curve_to" [ cr [handle!] x1 [float!] @@ -1071,11 +2166,29 @@ cairo_font_extents_t!: alias struct! [ x3 [float!] y3 [float!] ] + + cairo_rel_curve_to: "cairo_curve_to" [ + cr [handle!] + dx1 [float!] + dy1 [float!] + dx2 [float!] + dy2 [float!] + dx3 [float!] + dy3 [float!] + ] + cairo_move_to: "cairo_move_to" [ cr [handle!] x [float!] y [float!] ] + + cairo_rel_move_to: "cairo_rel_move_to" [ + cr [handle!] + dx [float!] + dy [float!] + ] + cairo_arc: "cairo_arc" [ cr [handle!] xc [float!] @@ -1084,6 +2197,14 @@ cairo_font_extents_t!: alias struct! [ angle1 [float!] angle2 [float!] ] + cairo_arc_negative: "cairo_arc_negative" [ + cr [handle!] + xc [float!] + yc [float!] + radius [float!] + angle1 [float!] + angle2 [float!] + ] cairo_rectangle: "cairo_rectangle" [ cr [handle!] x [float!] @@ -1091,12 +2212,24 @@ cairo_font_extents_t!: alias struct! [ w [float!] h [float!] ] + cairo_new_path: "cairo_new_path" [ + cr [handle!] + ] cairo_new_sub_path: "cairo_new_sub_path" [ cr [handle!] ] cairo_close_path: "cairo_close_path" [ cr [handle!] ] + cairo_get_current_point: "cairo_get_current_point" [ + cr [handle!] + x [float-ptr!] + y [float-ptr!] + ] + cairo_has_current_point: "cairo_has_current_point" [ + cr [handle!] + return: [integer!] + ] cairo_stroke: "cairo_stroke" [ cr [handle!] ] @@ -1180,9 +2313,6 @@ cairo_font_extents_t!: alias struct! [ cr [handle!] antialias [integer!] ] - cairo_surface_destroy: "cairo_surface_destroy" [ - surface [handle!] - ] cairo_pattern_create_linear: "cairo_pattern_create_linear" [ x0 [float!] y0 [float!] @@ -1220,6 +2350,18 @@ cairo_font_extents_t!: alias struct! [ cairo_stroke_preserve: "cairo_stroke_preserve" [ cr [handle!] ] + cairo_get_matrix: "cairo_get_matrix" [ + cr [handle!] + mat [cairo_matrix_t!] + ] + cairo_set_matrix: "cairo_set_matrix" [ + cr [handle!] + mat [cairo_matrix_t!] + ] + cairo_transform: "cairo_transform" [ + cr [handle!] + mat [cairo_matrix_t!] + ] ; Related to draw text with cairo (no succes for base widget) replaced by pango_cairo cairo_select_font_face: "cairo_select_font_face" [ cr [handle!] @@ -1231,11 +2373,7 @@ cairo_font_extents_t!: alias struct! [ ; cr [handle!] ; size [integer!] ; ] - ; cairo_text_extents: "cairo_text_extents" [ - ; cr [handle!] - ; text [c-string!] - ; extents [handle!] - ; ] + ; cairo_font_extents: "cairo_font_extents" [ cr [handle!] extents [cairo_font_extents_t!] @@ -1244,9 +2382,44 @@ cairo_font_extents_t!: alias struct! [ ; cr [handle!] ; text [c-string!] ; ] + cairo_image_surface_create: "cairo_image_surface_create" [ + format [cairo_format_t!] + width [integer!] + height [integer!] + return: [handle!] + ] + cairo_image_surface_create_for_data: "cairo_image_surface_create_for_data" [ + data [byte-ptr!] + format [cairo_format_t!] + width [integer!] + height [integer!] + stride [integer!] + return: [handle!] + ] + cairo_surface_finish: "cairo_surface_finish" [ + surf [handle!] + ] + cairo_surface_destroy: "cairo_surface_destroy" [ + surf [handle!] + ] + cairo_image_surface_get_data: "cairo_image_surface_get_data" [ + surf [handle!] + return: [byte-ptr!] + ] + cairo_surface_flush: "cairo_surface_flush" [ + surf [handle!] + ] + cairo_surface_mark_dirty: "cairo_surface_mark_dirty" [ + surf [handle!] + ] + cairo_format_stride_for_width: "cairo_format_stride_for_width" [ + format [cairo_format_t!] + width [integer!] + return: [integer!] + ] gdk_cairo_set_source_pixbuf: "gdk_cairo_set_source_pixbuf" [ cr [handle!] - pixbuf [handle!] + pixbuf [handle!] x [integer!] y [integer!] ] @@ -1258,6 +2431,14 @@ cairo_font_extents_t!: alias struct! [ height [integer!] return: [handle!] ] + gdk_pixbuf_new_subpixbuf: "gdk_pixbuf_new_subpixbuf" [ + pixbuf [handle!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] gdk_pixbuf_copy: "gdk_pixbuf_copy" [ pixbuf [handle!] return: [handle!] @@ -1282,6 +2463,32 @@ cairo_font_extents_t!: alias struct! [ interp_type [integer!] return: [handle!] ] + gdk_pixbuf_get_from_surface: "gdk_pixbuf_get_from_surface" [ + surf [handle!] + src_x [integer!] + src_y [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] + gdk_pixbuf_get_from_window: "gdk_pixbuf_get_from_window" [ + window [handle!] + src_x [integer!] + src_y [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] + gdk_pixbuf_get_n_channels: "gdk_pixbuf_get_n_channels" [ + pixbuf [handle!] + return: [integer!] + ] + + ;; Useless since already called inside pango_cairo_create_context + ; pango_cairo_font_map_get_default: "pango_cairo_font_map_get_default" [ + ; return: [handle!] + ; ] + pango_cairo_create_context: "pango_cairo_create_context" [ cr [handle!] return: [handle!] @@ -1298,5 +2505,190 @@ cairo_font_extents_t!: alias struct! [ cr [handle!] layout [handle!] ] + pango_cairo_show_layout_line: "pango_cairo_show_layout_line" [ + cr [handle!] + layout_line [handle!] + ] + pango_cairo_context_set_font_options: "pango_cairo_context_set_font_options" [ + cr [handle!] + opts [handle!] + ] + pango_context_load_font: "pango_context_load_font" [ + context [handle!] + fd [handle!] + return: [handle!] + ] + pango_font_map_create_context: "pango_font_map_create_context" [ + fontmap [handle!] + return: [handle!] + ] + pango_parse_markup: "pango_parse_markup" [ + markup_text [c-string!] + length [integer!] + accel_marker [integer!] ;gunichar=guint32 + attr_list [handle!] ;[pointer! [handle!]] + text [handle!] ;[pointer! [c-string!]] + accel_char [integer!] ;gunichar=gunit32 + error [handle!] + return: [logic!] + ] + pango_attr_list_new: "pango_attr_list_new" [ + return: [handle!] + ] + pango_attr_list_ref: "pango_attr_list_ref" [ + attrs [handle!] + return: [handle!] + ] + pango_attr_list_unref: "pango_attr_list_unref" [ + attrs [handle!] + ] + pango_attr_list_copy: "pango_attr_list_copy" [ + attrs [handle!] + return: [handle!] + ] + pango_attr_list_insert: "pango_attr_list_insert" [ + attrs [handle!] + attr [PangoAttribute!] + ] + pango_attr_list_change: "pango_attr_list_change" [ + attrs [handle!] + attr [PangoAttribute!] + ] + pango_attr_list_insert_before: "pango_attr_list_insert_before" [ + attrs [handle!] + attr [PangoAttribute!] + ] + pango_attr_list_splice: "pango_attr_list_splice" [ + attrs [handle!] + attrs2 [handle!] + pos [integer!] + len [integer!] + ] + + pango_attribute_equal: "pango_attribute_equal" [ + attr [handle!] + attr2 [handle!] + return: [logic!] + ] + pango_attribute_destroy: "pango_attribute_destroy" [ + attr [PangoAttribute!] + ] + ;; font description attributes + pango_attr_family_new: "pango_attr_family_new" [ + name [c-string!] + return: [PangoAttribute!] + ] + pango_attr_style_new: "pango_attr_style_new" [ + style [integer!] + return: [PangoAttribute!] + ] + pango_attr_variant_new: "pango_attr_variant_new" [ + variant [integer!] + return: [PangoAttribute!] + ] + pango_attr_stretch_new: "pango_attr_stretch_new" [ + stretch [integer!] + return: [PangoAttribute!] + ] + pango_attr_weight_new: "pango_attr_weight_new" [ + weight [integer!] + return: [PangoAttribute!] + ] + pango_attr_size_new: "pango_attr_size_new" [ + size [integer!] + return: [PangoAttribute!] + ] + pango_attr_size_new_absolute: "pango_attr_size_new_absolute" [ + size [integer!] + return: [PangoAttribute!] + ] + pango_attr_font_desc_new: "pango_attr_font_desc_new" [ + font-desc [handle!] + return: [PangoAttribute!] + ] + ;; Color attributes + pango_attr_foreground_new: "pango_attr_foreground_new" [ + r [integer!] + g [integer!] + b [integer!] + return: [PangoAttribute!] + ] + pango_attr_background_new: "pango_attr_background_new" [ + r [integer!] + g [integer!] + b [integer!] + return: [PangoAttribute!] + ] + ;; styles attributes + pango_attr_strikethrough_new: "pango_attr_strikethrough_new" [ + ok [logic!] + return: [PangoAttribute!] + ] + pango_attr_strikethrough_color_new: "pango_attr_strikethrough_color_new" [ + r [integer!] + g [integer!] + b [integer!] + return: [PangoAttribute!] + ] + pango_attr_underline_new: "pango_attr_underline_new" [ + ok [integer!] + return: [PangoAttribute!] + ] + pango_attr_underline_color_new: "pango_attr_underline_color_new" [ + r [integer!] + g [integer!] + b [integer!] + return: [PangoAttribute!] + ] + pango_attr_shape_new: "pango_attr_shape_new" [ + ink-rect [handle!] + logical-rect [handle!] + return: [PangoAttribute!] + ] + ;; size attributes + pango_attr_scale_new: "pango_attr_scale_new" [ + scale [float!] + return: [PangoAttribute!] + ] + pango_attr_rise_new: "pango_attr_rise_new" [ + rise [integer!] + return: [PangoAttribute!] + ] + pango_attr_letter_spacing_new: "pango_attr_letter_spacing_new" [ + spacing [integer!] + return: [PangoAttribute!] + ] + pango_attr_gravity_new: "pango_attr_gravity_new" [ + gravity [integer!] + return: [PangoAttribute!] + ] + pango_attr_gravity_hint_new: "pango_attr_gravity_hint_new" [ + hint [integer!] + return: [PangoAttribute!] + ] + pango_attr_font_features_new: "pango_attr_font_features_new" [ + features [c-string!] + return: [PangoAttribute!] + ] + pango_attr_foreground_alpha_new: "pango_attr_foreground_alpha_new" [ + alpha [integer!] + return: [PangoAttribute!] + ] + pango_attr_background_alpha_new: "pango_attr_background_alpha_new" [ + alpha [integer!] + return: [PangoAttribute!] + ] + + + cairo_font_options_create: "cairo_font_options_create" [ + return: [handle!] + ] + cairo_font_options_destroy: "cairo_font_options_destroy" [ + return: [handle!] + ] + cairo_font_options_set_antialias: "cairo_font_options_set_antialias" [ + cfo [handle!] + antialias [cairo_antialias_t!] + ] ] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index c3167cc111..53d1eae1c5 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -18,46 +18,50 @@ Red/System [ #include %para.reds #include %draw.reds -;#include %gdkkeysyms.reds +#include %menu.reds #include %handlers.reds #include %comdlgs.reds GTKApp: as handle! 0 GTKApp-Ctx: 0 exit-loop: 0 -red-face-id: 0 -_widget-id: 1 -gtk-fixed-id: 2 -red-timer-id: 3 -css-id: 4 -gtk-style-id: 0 +;;;close-window?: no +;;;win-array: declare red-vector! +win-cnt: 0 +AppMainMenu: as handle! 0 + +;; Identifiers for qdata +red-face-id: g_quark_from_string "red-face-id" +gtk-style-id: g_quark_from_string "gtk-style-id" +_widget-id: g_quark_from_string "_widget-id" +gtk-container-id: g_quark_from_string "gtk-container-id" +red-timer-id: g_quark_from_string "red-timer-id" +css-id: g_quark_from_string "css-id" +size-id: g_quark_from_string "size-id" +real-container-id: g_quark_from_string "real-container-id" +menu-id: g_quark_from_string "menu-id" +drag-id: g_quark_from_string "drag-id" +no-wait-id: g_quark_from_string "no-wait-id" group-radio: as handle! 0 tabs: context [ nb: 0 cur: 0 ] -; used to save old position of pointer in widget-motion-notify-event handler -motion: context [ - state: no - x_root: 0.0 - y_root: 0.0 - x_new: 0 - y_new: 0 - cpt: 0 - sensitiv: 3 -] + ; to put in other place (usually platform.red) if useful _drag-on: symbol/make "drag-on" -_on-over: word/load "on-over" +settings: as handle! 0 pango-context: as handle! 0 gtk-font: "Sans 10" -default-font: 0 +default-font: as handle! 0 ; Do not KNOW about this one -;;;main-window: as handle! 0 +;;; +main-window: as handle! 0 +last-window: as handle! 0 ; Temporary, will be removed... last-widget: as handle! 0 @@ -67,7 +71,8 @@ log-pixels-y: 0 screen-size-x: 0 screen-size-y: 0 -get-face-object: func [ + +get-face-obj: func [ handle [handle!] return: [red-object!] /local @@ -158,8 +163,10 @@ get-widget-symbol: func [ values [red-value!] ][ values: get-face-values widget - type: as red-word! values + FACE_OBJ_TYPE - symbol/resolve type/symbol + either null? values [symbol/resolve popup][ + type: as red-word! values + FACE_OBJ_TYPE + symbol/resolve type/symbol + ] ] get-widget-data: func [ @@ -172,13 +179,74 @@ get-widget-data: func [ as red-block! values + FACE_OBJ_DATA ] +set-container: func [ + widget [handle!] + container [handle!] +][ + g_object_set_qdata widget gtk-container-id container +] + +container?: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget gtk-container-id +] + +gtk-layout?: func [ + type [integer!] + return: [logic!] +][ + any[type = rich-text type = panel type = base] +] + +container-type?: func [ + type [integer!] + return: [logic!] +][ + ;;; See events.reds to see the comment above + ; Option I: any[type = rich-text type = panel type = base] + ; Option II: + type = rich-text +] + +set-draggable: func [ + item [handle!] + key [logic!] +][ + g_object_set_qdata item drag-id as int-ptr! either key [1][0] +] + +draggable?: func [ + item [handle!] + return: [logic!] +][ + 1 = as integer! g_object_get_qdata item drag-id +] + +set-view-no-wait: func [ + window [handle!] + key [logic!] +][ + ; usually a view/no-wait call at most twice do-events and at least one do-events with no-wait? = true + ;; DEBUG[view/no-wait]: print ["view-no-wait? window " window " => " key lf] + g_object_set_qdata window no-wait-id as int-ptr! either key [1][0] +] + +view-no-wait?: func [ + window [handle!] + return: [logic!] +][ + all[1 = as integer! g_object_get_qdata window no-wait-id window <> main-window] +] + get-child-from-xy: func [ parent [handle!] x [integer!] y [integer!] return: [integer!] /local - hWnd [handle!] + widget [handle!] ][ 0 ] @@ -197,6 +265,8 @@ get-text-size: func [ pl [handle!] size [tagSIZE] df [c-string!] + pc [handle!] + widget [handle!] ][ if null? pango-context [pango-context: gdk_pango_context_get] size: declare tagSIZE @@ -210,11 +280,25 @@ get-text-size: func [ width: 0 height: 0 - pl: pango_layout_new pango-context + ;;; get pango_context + ; from widget first + ; widget: face-handle? face + ; pc: as handle! 0 pl: as handle! 0 + ; unless null? widget [ + ; pc: gtk_widget_get_pango_context widget + ; unless null? pc [pl: pango_layout_new pc ];seems more natural than pango-context + ; ] + ; globally otherwise + ;if null? pl [ + pl: pango_layout_new pango-context + ;] + + pango_layout_set_text pl text -1 pango_layout_set_font_description pl hFont pango_layout_get_pixel_size pl :width :height g_object_unref pl +; unless null? pc [g_object_unref pc] size/width: width size/height: height @@ -242,30 +326,57 @@ to-bgr: func [ ] free-handles: func [ - hWnd [handle!] - values [red-value!] + widget [integer!] + force? [logic!] /local + values [red-value!] type [red-word!] - rate [red-value!] + face [red-object!] + tail [red-object!] + pane [red-block!] state [red-value!] + rate [red-value!] sym [integer!] + handle [handle!] ][ - ;type: as red-word! values + FACE_OBJ_TYPE - ;sym: symbol/resolve type/symbol + values: get-face-values as handle! widget + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + + ;;;if all [sym = window not force?][ + ;;; close-window?: yes + ;;; vector/rs-append-int win-array widget + ;;;] rate: values + FACE_OBJ_RATE - if TYPE_OF(rate) <> TYPE_NONE [change-rate hWnd none-value] - gtk_widget_destroy hWnd + if TYPE_OF(rate) <> TYPE_NONE [change-rate as handle! widget none-value] + + pane: as red-block! values + FACE_OBJ_PANE + if TYPE_OF(pane) = TYPE_BLOCK [ + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [face < tail][ + handle: face-handle? face + unless null? handle [free-handles as-integer handle force?] + face: face + 1 + ] + ] + + if sym = window [ + win-cnt: win-cnt - 1 + post-quit-msg + ] + state: values + FACE_OBJ_STATE state/header: TYPE_NONE ] ; Debug function to show children tree debug-show-children: func [ - hWnd [handle!] + widget [handle!] parent? [logic!] /local - widget [handle!] + widget_ [handle!] child [handle!] container [handle!] rect [tagRECT] @@ -284,10 +395,10 @@ debug-show-children: func [ debug [logic!] cpt [integer!] ][ - ; to remove when saitsfactory enough development + ; to remove when satisfactory enough development debug: yes - values: get-face-values hWnd + values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE @@ -295,15 +406,15 @@ debug-show-children: func [ face: as red-object! values + FACE_OBJ_PARENT either TYPE_OF(face) = TYPE_NONE [ print-line "parent face: none" - print ["parent handle: " hWnd lf] + print ["parent handle: " widget lf] ][ values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE - widget: face-handle? face - print ["from parent handle: " widget lf] + widget_: face-handle? face + print ["from parent handle: " widget_ lf] ] - ][print ["parent handle: " hWnd lf]] + ][print ["parent handle: " widget lf]] sym: symbol/resolve type/symbol @@ -314,9 +425,9 @@ debug-show-children: func [ tail: as red-object! block/rs-tail pane if debug [print ["Pane type: " get-symbol-name sym lf]] if TYPE_OF(face) <> TYPE_OBJECT [print-line "not face object"] - widget: face-handle? face + widget_: face-handle? face - either null? widget [print-line "null container" container: null][container: g_object_get_qdata widget gtk-fixed-id] + either null? widget_ [print-line "null container" container: null][container: container? widget_] print ["container handle: " container lf] sx: 0 sy: 0 @@ -336,10 +447,10 @@ debug-show-children: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 unless null? container [ - widget: g_object_get_qdata child _widget-id - if null? widget [widget: child] + widget_: g_object_get_qdata child _widget-id + if null? widget_ [widget_: child] - gtk_widget_get_allocation widget as handle! rect + gtk_widget_get_allocation widget_ as handle! rect ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] ] @@ -352,22 +463,34 @@ debug-show-children: func [ free as byte-ptr! rect ] +; on-gc-mark: does [ +; collector/keep flags-blk/node +; collector/keep win-array/node +; ] + +show-gtk-version: func [][ + print [ "GTK VERSION: " gtk_get_major_version "." gtk_get_minor_version "." gtk_get_micro_version lf] +] + init: func [][ + show-gtk-version + gtk_disable_setlocale GTKApp: gtk_application_new RED_GTK_APP_ID G_APPLICATION_NON_UNIQUE gobj_signal_connect(GTKApp "window-removed" :window-removed-event :exit-loop) - GTKApp-Ctx: g_main_context_default unless g_main_context_acquire GTKApp-Ctx [ probe "ERROR: GTK: Cannot acquire main context" halt ] g_application_register GTKApp null null - - red-face-id: g_quark_from_string "red-face-id" - gtk-style-id: g_quark_from_string "gtk-style-id" + ;;;vector/make-at as red-value! win-array 8 TYPE_INTEGER 4 screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height - + default-font: pango_font_description_from_string gtk-font + settings: gtk_settings_get_default + g_object_set [settings "gtk-font-name" gtk-font null ] + #if type = 'exe [red-gtk-styles] + ;;;collector/register as int-ptr! :on-gc-mark ] get-symbol-name: function [ @@ -391,14 +514,29 @@ get-symbol-name: function [ sym = text-list ["text-list"] sym = drop-list ["drop-list"] sym = drop-down ["drop-down"] - true ["other widget"] + sym = rich-text ["rich-text"] + sym = done ["done"] + sym = stop ["stop"] + sym = _image ["image"] + + sym = facets/pane ["facets/pane"] + + sym = words/_remove/symbol ["words/remove"] + sym = words/_take/symbol ["words/take"] + sym = words/_clear/symbol ["words/clear"] + sym = words/_insert/symbol ["words/insert"] + sym = words/_poke/symbol ["words/poke"] + sym = words/_moved/symbol ["words/moved"] + sym = words/_changed/symbol ["words/changed"] + + true ["undefined"] ] ] ; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane adjust-sizes: func [ - hWnd [handle!] + widget [handle!] /local - widget [handle!] + widget_ [handle!] child [handle!] container [handle!] rect [tagRECT] @@ -424,7 +562,7 @@ adjust-sizes: func [ ; to remove when satisfactory enough development debug: no - values: get-face-values hWnd + values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE @@ -437,7 +575,7 @@ adjust-sizes: func [ tail: as red-object! block/rs-tail pane if debug [print ["Parent type: " get-symbol-name sym lf]] child: face-handle? face - container: either null? child [null][g_object_get_qdata child gtk-fixed-id] + container: either null? child [null][container? child] dx: 0 dy: 0 ox: 0 oy: 0 sx: 0 sy: 0 cpt: 0 @@ -455,11 +593,11 @@ adjust-sizes: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 if any [ox > offset/x not overlap?] [dx: 0] unless null? container [ - widget: g_object_get_qdata child _widget-id - if null? widget [widget: child] + widget_: g_object_get_qdata child _widget-id + if null? widget_ [widget_: child] if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] - gtk_fixed_move container widget offset/x + dx offset/y - gtk_widget_get_allocation widget as handle! rect + gtk_layout_move container widget_ offset/x + dx offset/y + gtk_widget_get_allocation widget_ as handle! rect ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] ] @@ -478,24 +616,91 @@ adjust-sizes: func [ free as byte-ptr! rect ] -change-rate: func [ - hWnd [handle!] - rate [red-value!] + + +remove-widget-timer: func [ + widget [handle!] /local - int [red-integer!] - tm [red-time!] - ts [integer!] timer [integer!] data [handle!] ][ - unless null? hWnd [ - data: g_object_get_qdata hWnd red-timer-id + unless null? widget [ + data: g_object_get_qdata widget red-timer-id timer: either null? data [0][as integer! data] if timer <> 0 [ ;-- cancel a preexisting timeout g_source_remove timer - g_object_set_qdata hWnd red-timer-id null + timer: 0 + g_object_set_qdata widget red-timer-id as int-ptr! timer ] + ] +] + +add-widget-timer: func [ + widget [handle!] + ts [integer!] + /local + timer [integer!] + data [handle!] +][ + ;;g_object_ref_sink main-window + timer: g_timeout_add ts as integer! :red-timer-action widget + g_object_set_qdata widget red-timer-id as int-ptr! timer +] + +get-widget-timer: func [ + widget [handle!] + return: [int-ptr!] +][ + either null? widget [as int-ptr! 0][g_object_get_qdata widget red-timer-id] +] + +remove-all-timers: func [ + widget [handle!] + /local + widget_ [handle!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] + rate [red-value!] +][ + remove-widget-timer widget + values: get-face-values widget + type: as red-word! values + FACE_OBJ_TYPE + pane: as red-block! values + FACE_OBJ_PANE + rate: values + FACE_OBJ_RATE + + change-rate widget none-value + + sym: symbol/resolve type/symbol + + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + + while [face < tail][ + widget_: face-handle? face + unless null? widget [remove-all-timers widget_] + face: face + 1 + ] + ] +] + +change-rate: func [ + widget [handle!] + rate [red-value!] + /local + int [red-integer!] + tm [red-time!] + ts [integer!] + timer [integer!] + data [handle!] +][ + unless null? widget [ + remove-widget-timer widget switch TYPE_OF(rate) [ TYPE_INTEGER [ @@ -504,90 +709,80 @@ change-rate: func [ ts: 1000 / int/value ] TYPE_TIME [ - tm: as red-time! rate + tm: as red-time! rate if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] ts: as-integer tm/time * 1000.0 + if ts = 0 [ts: 1] + ] + TYPE_NONE [ + ;; DEBUG: print ["change-rate: removed timer for widget " widget lf] + exit ] - TYPE_NONE [exit] default [fire [TO_ERROR(script invalid-facet-type) rate]] ] - timer: g_timeout_add ts as integer! :red-timer-action hWnd - g_object_set_qdata hWnd red-timer-id as int-ptr! timer + add-widget-timer widget ts ] ] change-image: func [ - hWnd [handle!] + widget [handle!] image [red-image!] type [integer!] /local img [handle!] ][ + ;; DEBUG: print ["change-image " widget " type: " get-symbol-name type lf] case [ ; type = camera [ - ; snap-camera hWnd + ; snap-camera widget ; until [TYPE_OF(image) = TYPE_IMAGE] ;-- wait ; ] any [type = button type = check type = radio][ if TYPE_OF(image) = TYPE_IMAGE [ - img: gtk_image_new_from_pixbuf as handle! OS-image/to-pixbuf image - gtk_button_set_image hWnd img + img: gtk_image_new_from_pixbuf OS-image/to-pixbuf image + gtk_button_set_image widget img ] ] + true [0] + ] ] change-color: func [ - hWnd [handle!] + widget [handle!] color [red-tuple!] type [integer!] /local clr [integer!] - set? [logic!] t [integer!] + face [red-object!] + font [red-object!] ][ + ;; DEBUG: print ["change-color " widget " " get-symbol-name type lf] t: TYPE_OF(color) if all [t <> TYPE_NONE t <> TYPE_TUPLE][exit] ; if transparent-color? color [ - ; objc_msgSend [hWnd sel_getUid "setDrawsBackground:" no] + ; objc_msgSend [widget sel_getUid "setDrawsBackground:" no] ; exit ; ] - ; set?: yes case [ - ; type = area [ - ; hWnd: objc_msgSend [hWnd sel_getUid "documentView"] - ; clr: either t = TYPE_NONE [00FFFFFFh][color/array1] - ; set-caret-color hWnd clr - ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] - ; ] - type = text [ - ; if t = TYPE_NONE [ - ; clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "controlColor"] - ; set?: no - ; ] - ; objc_msgSend [hWnd sel_getUid "setDrawsBackground:" set?] + type = area [ + face: get-face-obj widget + font: face-font? face + apply-css-styles widget face font type + ; widget: objc_msgSend [widget sel_getUid "documentView"] + ; clr: either t = TYPE_NONE [00FFFFFFh][color/array1] + ; set-caret-color widget clr + ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] + ] + true [ + ;; DEBUG: print ["change-color " widget lf] + face: get-face-obj widget + font: face-font? face + apply-css-styles widget face font type ] - ; any [type = check type = radio][ - ; hWnd: objc_msgSend [hWnd sel_getUid "cell"] - ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "controlColor"]] - ; ] - ; type = field [ - ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] - ; ] - ; type = window [ - ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "windowBackgroundColor"]] - ; ] - ; true [ - ; set?: no - ; objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes] - ; ] ] - ; if set? [ - ; if t = TYPE_TUPLE [clr: to-NSColor color] - ; objc_msgSend [hWnd sel_getUid "setBackgroundColor:" clr] - ; ] - 0 ] update-z-order: func [ @@ -595,64 +790,89 @@ update-z-order: func [ pane [red-block!] type [integer!] /local - face [red-object!] - tail [red-object!] - hWnd [handle!] - parr [int-ptr!] - arr [integer!] - nb [integer!] - s [series!] + face [red-object!] + tail [red-object!] + widget [handle!] + nb [integer!] + s [series!] + values [red-value!] + offset [red-pair!] + list [GList!] child [GList!] + ][ - s: GET_BUFFER(pane) - face: as red-object! s/offset + pane/head - tail: as red-object! s/tail - nb: (as-integer tail - face) >> 4 + ;; DEBUG: print ["update-z-order" lf] + + if gtk-layout? type [ ;; this is for gtk_layout widget + list: as GList! gtk_container_get_children parent + + child: list nb: 0 + while [not null? child][ + nb: nb + 1 + g_object_ref child/data ; to avoid destruction before removing from container + gtk_container_remove parent child/data + ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] + child: child/next + ] + g_list_free as int-ptr! list - parr: as int-ptr! allocate nb * 4 - nb: 0 - while [face < tail][ - if TYPE_OF(face) = TYPE_OBJECT [ - hWnd: face-handle? face - if hWnd <> null [ - nb: nb + 1 - parr/nb: as-integer hWnd + s: GET_BUFFER(pane) + face: as red-object! s/offset + pane/head + tail: as red-object! s/tail + nb: (as-integer tail - face) >> 4 + + nb: 0 + while [face < tail][ + if TYPE_OF(face) = TYPE_OBJECT [ + widget: face-handle? face + if widget <> null [ + nb: nb + 1 + ;; DEBUG: print ["added widget" nb ": " widget " to " parent lf] + gtk_container_add parent widget + values: object/get-values face + offset: as red-pair! values + FACE_OBJ_OFFSET + gtk_layout_move parent widget offset/x offset/y + g_object_unref widget + ] ] + face: face + 1 ] - face: face + 1 + ;; OS-refresh-window as-integer main-window + + ;; DEBUG: + ; list: as GList! gtk_container_get_children parent + ; child: list nb: 0 + ; while [not null? child][ + ; nb: nb + 1 + ; print [" widget" nb ": " child/data lf] + ; child: child/next + ; ] + ; g_list_free as int-ptr! list ] - ; arr: objc_msgSend [ - ; objc_getClass "NSArray" - ; sel_getUid "arrayWithObjects:count:" - ; parr nb - ; ] - ; free as byte-ptr! parr - ; if type = window [parent: objc_msgSend [parent sel_getUid "contentView"]] - ; objc_msgSend [parent sel_getUid "setSubviews:" arr] -0 ] change-font: func [ - hWnd [handle!] + widget [handle!] face [red-object!] font [red-object!] type [integer!] return: [logic!] /local - css [c-string!] - provider [handle!] + ; css [c-string!] + ; provider [handle!] hFont [handle!] ][ + ;; DEBUG: print ["change-font" lf] if TYPE_OF(font) <> TYPE_OBJECT [return no] - provider: get-styles-provider hWnd + ; provider: get-styles-provider widget - ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles - css: "" - css: css-styles face font + ; ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles + ; css: "" + ; css: css-styles face font type - ;; DEBUG: print ["change-font ccs: " css lf] + ; unless null? provider [gtk_css_provider_load_from_data provider css -1 null] - gtk_css_provider_load_from_data provider css -1 null + apply-css-styles widget face font type ;; Update the pango_font_description hFont (directly used by get-text-size) make-font face font @@ -661,80 +881,121 @@ change-font: func [ ] change-offset: func [ - hWnd [handle!] + widget [handle!] pos [red-pair!] type [integer!] /local container [handle!] _widget [handle!] ][ - ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol hWnd lf] + ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol widget " " widget " " pos/x "x" pos/y lf] either type = window [ 0 ][ - ;OS-refresh-window as integer! main-window - container: either null? hWnd [null][g_object_get_qdata hWnd gtk-fixed-id] - ;; DEBUG: print ["change-offset by" pos lf] - ; _widget: either type = text [ - ; g_object_get_qdata hWnd _widget-id - ; ][hWnd] - _widget: g_object_get_qdata hWnd _widget-id - _widget: either null? _widget [hWnd][_widget] - unless null? container [ - gtk_fixed_move container _widget pos/x pos/y - gtk_widget_queue_draw _widget + unless null? widget [ + ;OS-refresh-window as integer! main-window + container: either null? widget [null][container? widget] + ;; DEBUG: print ["change-offset by" pos lf] + ; _widget: either type = text [ + ; g_object_get_qdata widget _widget-id + ; ][widget] + + _widget: g_object_get_qdata widget _widget-id + _widget: either null? _widget [widget][_widget] + unless null? container [ + gtk_layout_move container _widget pos/x pos/y + gtk_widget_queue_draw _widget + ] ] ] ] change-size: func [ - hWnd [handle!] + widget [handle!] size [red-pair!] type [integer!] /local _widget [handle!] ][ - ;; DEBUG: print ["change-size" get-symbol-name get-widget-symbol hWnd size lf] + ;; DEBUG: print ["change-size " get-symbol-name get-widget-symbol widget " " widget " " size/x "x" size/y lf] + either type = window [ - gtk_window_set_default_size hWnd size/x size/y - ][ - _widget: g_object_get_qdata hWnd _widget-id - _widget: either null? _widget [hWnd][_widget] - gtk_widget_set_size_request _widget size/x size/y - gtk_widget_queue_draw _widget + gtk_window_set_default_size widget size/x size/y + gtk_widget_queue_draw widget + ][ + unless null? widget [ + _widget: g_object_get_qdata widget _widget-id + _widget: either null? _widget [widget][_widget] + gtk_widget_set_size_request _widget size/x size/y + unless null? _widget [gtk_widget_queue_resize _widget] + ] ] + +] + +;; Special treatment for hidden (or invisible) widgets +;; that are hidden at the beginning of do-events as a first initialization + +list-invisible: as handle! 0 + +add-invisible: func [ + widget [handle!] +][ + ;; DEBUG: print ["add invisible " widget lf] + list-invisible: g_list_prepend list-invisible widget +] + +hide-invisible: func [ + /local + child [GList!] +][ + if 0 = g_list_length list-invisible [exit] + ;; DEBUG: print ["hide-invisible " g_list_length list-invisible lf] + child: as GList! list-invisible + while [not null? child][ + ;; DEBUG: print ["hide-invisible: " child/data lf] + gtk_widget_set_visible child/data no + child: child/next + ] + g_list_free list-invisible + list-invisible: as handle! 0 ] change-visible: func [ - hWnd [handle!] + widget [handle!] show? [logic!] type [integer!] ][ case [ type = window [ ; either show? [ - ; objc_msgSend [hWnd sel_getUid "makeKeyAndOrderFront:" hWnd] + ; objc_msgSend [widget sel_getUid "makeKeyAndOrderFront:" widget] ; ][ - ; objc_msgSend [hWnd sel_getUid "orderOut:" hWnd] + ; objc_msgSend [widget sel_getUid "orderOut:" widget] ; ] 0 ] - true [gtk_widget_set_visible hWnd show?] + true [ + ;; DEBUG: + print ["change-visible " widget " (type " get-symbol-name type "): " show? lf] + gtk_widget_set_visible widget show? + ] ] +; gtk_widget_queue_draw widget ] change-enabled: func [ - hWnd [handle!] + widget [handle!] enabled? [logic!] type [integer!] /local obj [integer!] ][ - gtk_widget_set_sensitive hWnd enabled? + gtk_widget_set_sensitive widget enabled? ] change-text: func [ - hWnd [handle!] + widget [handle!] values [red-value!] face [red-object!] type [integer!] @@ -744,8 +1005,11 @@ change-text: func [ str [red-string!] buffer [handle!] ][ - if type = base [ - gtk_widget_queue_draw hWnd + ;; DEBUG: print ["change-text: " get-symbol-name type lf] + + if null? widget [exit] + if type = base [ + gtk_widget_queue_draw widget exit ] @@ -757,36 +1021,36 @@ change-text: func [ ] if null? cstr [exit] - ;unless change-font hWnd face as red-object! values + FACE_OBJ_FONT type [ + ;unless change-font widget face as red-object! values + FACE_OBJ_FONT type [ case [ type = area [ - buffer: gtk_text_view_get_buffer hWnd + buffer: gtk_text_view_get_buffer widget gtk_text_buffer_set_text buffer cstr -1 ] type = text [ - gtk_label_set_text hWnd cstr + gtk_label_set_text widget cstr ] type = field [ - buffer: gtk_entry_get_buffer hWnd + buffer: gtk_entry_get_buffer widget gtk_entry_buffer_set_text buffer cstr -1 ] any [type = button type = radio type = check] [ - gtk_button_set_label hWnd cstr + gtk_button_set_label widget cstr ] type = window [ - gtk_window_set_title hWnd cstr + gtk_window_set_title widget cstr ] type = group-box [ - gtk_frame_set_label hWnd cstr + gtk_frame_set_label widget cstr ] true [0] ] - gtk_widget_queue_draw hWnd + gtk_widget_queue_draw widget ;] ] change-data: func [ - hWnd [handle!] + widget [handle!] values [red-value!] /local data [red-value!] @@ -810,7 +1074,7 @@ change-data: func [ TYPE_OF(data) = TYPE_PERCENT ][ f: as red-float! data - gtk_progress_bar_set_fraction hWnd f/value + gtk_progress_bar_set_fraction widget f/value ] all [ type = slider @@ -819,28 +1083,28 @@ change-data: func [ f: as red-float! data size: as red-pair! values + FACE_OBJ_SIZE len: either size/x > size/y [size/x][size/y] - gtk_range_set_value hWnd f/value * (as-float len) + gtk_range_set_value widget f/value * (as-float len) ] type = check [ - set-logic-state hWnd as red-logic! data yes + set-logic-state widget as red-logic! data yes ] type = radio [ - set-logic-state hWnd as red-logic! data no + set-logic-state widget as red-logic! data no ] ; type = tab-panel [ - ; set-tabs hWnd get-face-values hWnd + ; set-tabs widget get-face-values widget ; ] all [ type = text-list TYPE_OF(data) = TYPE_BLOCK ][ ;;DEBUG: print ["text-list updated" lf] - gtk_container_foreach hWnd as-integer :remove-entry hWnd - init-text-list hWnd as red-block! data - gtk_widget_show_all hWnd + gtk_container_foreach widget as-integer :remove-entry widget + init-text-list widget as red-block! data + gtk_widget_show_all widget ] any [type = drop-list type = drop-down][ - init-combo-box hWnd as red-block! data null type = drop-list + init-combo-box widget as red-block! data null type = drop-list ] true [0] ;-- default, do nothing ] @@ -848,74 +1112,119 @@ change-data: func [ ] change-selection: func [ - hWnd [handle!] + widget [handle!] int [red-integer!] ;-- can be also none! | object! type [integer!] /local - idx [integer!] - sz [integer!] - wnd [integer!] + idx [integer!] + sz [integer!] + wnd [integer!] + item [handle!] + sel [red-pair!] + ins [GtkTextIter!] + bound [GtkTextIter!] + buffer [handle!] ][ - ; if type <> window [ - ; idx: either TYPE_OF(int) = TYPE_INTEGER [int/value - 1][-1] - ; if idx < 0 [exit] ;-- @@ should unselect the items ? - ; ] - ; case [ + ;; DEBUG: print ["change-selection: " widget " (" get-symbol-name type ")" lf] + + if type <> window [ + idx: either TYPE_OF(int) = TYPE_INTEGER [int/value - 1][-1] + ] + case [ + any [type = field type = area][ + sel: as red-pair! int + either TYPE_OF(sel) = TYPE_NONE [ + idx: 0 + sz: 0 + ][ + idx: sel/x - 1 + sz: sel/y - idx ;-- should point past the last selected char + ] + either type = field [ + gtk_editable_select_region widget idx idx + sz + ][ + buffer: gtk_text_view_get_buffer widget + ins: as GtkTextIter! allocate (size? GtkTextIter!) + bound: as GtkTextIter! allocate (size? GtkTextIter!) + ;; Careful! GtkTextIter! needs to be initialized first (so this weird call first!) + gtk_text_buffer_get_selection_bounds buffer as handle! ins as handle! bound + ;; DEBUG: print [" pos : " idx "x" idx + sz lf] + gtk_text_iter_set_offset as handle! ins idx + gtk_text_iter_set_offset as handle! bound idx + sz + gtk_text_buffer_select_range buffer as handle! ins as handle! bound + free as byte-ptr! ins free as byte-ptr! bound + ] + ] ; type = camera [ ; either TYPE_OF(int) = TYPE_NONE [ - ; toggle-preview hWnd false + ; toggle-preview widget false ; ][ - ; select-camera hWnd idx - ; toggle-preview hWnd true - ; ] - ; ] - ; type = text-list [ - ; hWnd: objc_msgSend [hWnd sel_getUid "documentView"] - ; sz: -1 + objc_msgSend [hWnd sel_getUid "numberOfRows"] - ; if any [sz < 0 sz < idx][exit] - ; idx: objc_msgSend [objc_getClass "NSIndexSet" sel_getUid "indexSetWithIndex:" idx] - ; objc_msgSend [ - ; hWnd sel_getUid "selectRowIndexes:byExtendingSelection:" idx no + ; select-camera widget idx + ; toggle-preview widget true ; ] - ; objc_msgSend [idx sel_getUid "release"] ; ] - ; any [type = drop-list type = drop-down][ - ; sz: -1 + objc_msgSend [hWnd sel_getUid "numberOfItems"] - ; if any [sz < 0 sz < idx][exit] - ; objc_msgSend [hWnd sel_getUid "selectItemAtIndex:" idx] - ; idx: objc_msgSend [hWnd sel_getUid "objectValueOfSelectedItem"] - ; objc_msgSend [hWnd sel_getUid "setObjectValue:" idx] - ; ] - ; type = tab-panel [select-tab hWnd int] - ; type = window [ - ; wnd: either TYPE_OF(int) = TYPE_OBJECT [ - ; as-integer face-handle? as red-object! int - ; ][0] - ; objc_msgSend [hWnd sel_getUid "makeFirstResponder:" wnd] - ; ] - ; true [0] ;-- default, do nothing - ; ] - 0 + type = text-list [ + item: gtk_list_box_get_row_at_index widget idx + gtk_list_box_select_row widget item + ] + any [type = drop-list type = drop-down][ + gtk_combo_box_set_active widget idx + ] + type = tab-panel [ + gtk_notebook_set_current_page widget idx + ] + type = window [ + switch TYPE_OF(int) [ + TYPE_OBJECT [set-selected-focus widget] + TYPE_NONE [; as in windows but not sure! + ;; DEVEL: print ["DEVEL WARNING: 'change-selection windows' since not sure this is valid"] + gtk_widget_grab_focus widget + ] + default [0] + ] + ] + true [0] ;-- default, do nothing + ] ] + +set-hint-text: func [ + widget [handle!] + options [red-block!] + /local + text [red-string!] + cell [integer!] + len [integer!] + str [c-string!] +][ + if TYPE_OF(options) <> TYPE_BLOCK [exit] + text: as red-string! block/select-word options word/load "hint" no + if TYPE_OF(text) = TYPE_STRING [ + len: -1 + str: unicode/to-utf8 text :len + gtk_entry_set_placeholder_text widget str + ] +] + set-selected-focus: func [ - hWnd [handle!] + widget [handle!] /local face [red-object!] values [red-value!] handle [handle!] ][ - values: get-face-values hWnd + values: get-face-values widget if values <> null [ face: as red-object! values + FACE_OBJ_SELECTED if TYPE_OF(face) = TYPE_OBJECT [ - 0;@@ TBD + handle: face-handle? face + unless null? handle [gtk_widget_grab_focus handle] ] ] ] set-logic-state: func [ - hWnd [handle!] + widget [handle!] state [red-logic!] check? [logic!] /local @@ -928,8 +1237,8 @@ set-logic-state: func [ ][ as-integer state/value ;-- returns 0/1, matches the messages ] - gtk_toggle_button_set_active hWnd as logic! value - if value = -1 [gtk_toggle_button_set_inconsistent hWnd true] + gtk_toggle_button_set_active widget as logic! value + if value = -1 [gtk_toggle_button_set_inconsistent widget true] ] get-flags: func [ @@ -967,6 +1276,8 @@ get-flags: func [ sym = no-buttons [flags: flags or FACET_FLAGS_NO_BTNS] sym = modal [flags: flags or FACET_FLAGS_MODAL] sym = popup [flags: flags or FACET_FLAGS_POPUP] + sym = scrollable [flags: flags or FACET_FLAGS_SCROLLABLE] + sym = password [flags: flags or FACET_FLAGS_PASSWORD] true [fire [TO_ERROR(script invalid-arg) word]] ] word: word + 1 @@ -1037,6 +1348,7 @@ init-combo-box: func [ tail [red-string!] len [integer!] val [c-string!] + size [integer!] ][ if any [ TYPE_OF(data) = TYPE_BLOCK @@ -1046,6 +1358,9 @@ init-combo-box: func [ str: as red-string! block/rs-head data tail: as red-string! block/rs-tail data + size: block/rs-length? data + ;; DEBUG: print ["combo-size: " size lf] + ;remove all items gtk_combo_box_text_remove_all combo @@ -1057,7 +1372,7 @@ init-combo-box: func [ val: unicode/to-utf8 str :len gtk_combo_box_text_append_text combo val ] - str: str + 1 + str: str + 1 ] ] @@ -1090,22 +1405,27 @@ init-text-list: func [ val [c-string!] len [integer!] label [handle!] + type [integer!] ][ if any [ TYPE_OF(data) = TYPE_BLOCK TYPE_OF(data) = TYPE_HASH TYPE_OF(data) = TYPE_MAP ][ + ;; DEBUG: print ["init-text-list" lf] str: as red-string! block/rs-head data tail: as red-string! block/rs-tail data if str = tail [exit] while [str < tail][ - if TYPE_OF(str) = TYPE_STRING [ + type: TYPE_OF(str) + ;; DEBUG: print ["type " type lf] + if ANY_STRING?(type) [ len: -1 val: unicode/to-utf8 str :len label: gtk_label_new val + ;; DEBUG: print ["Add elt: " val lf] gtk_widget_set_halign label 1 ;-- GTK_ALIGN_START gtk_container_add widget label ] @@ -1122,7 +1442,7 @@ update-scroller: func [ vertical? [red-logic!] int [red-integer!] values [red-value!] - hWnd [handle!] + widget [handle!] nTrackPos [integer!] nPos [integer!] nPage [integer!] @@ -1135,12 +1455,12 @@ update-scroller: func [ ;parent: as red-object! values + SCROLLER_OBJ_PARENT ;vertical?: as red-logic! values + SCROLLER_OBJ_VERTICAL? ;int: as red-integer! block/rs-head as red-block! (object/get-values parent) + FACE_OBJ_STATE - ;hWnd: as handle! int/value + ;widget: as handle! int/value ;int: as red-integer! values + flag ;if flag = SCROLLER_OBJ_VISIBLE? [ - ; ShowScrollBar hWnd as-integer vertical?/value as logic! int/value + ; ShowScrollBar widget as-integer vertical?/value as logic! int/value ; exit ;] @@ -1161,40 +1481,27 @@ update-scroller: func [ ;if fMask <> 0 [ ; fMask: fMask or SIF_DISABLENOSCROLL ; cbSize: size? tagSCROLLINFO - ; SetScrollInfo hWnd as-integer vertical?/value as tagSCROLLINFO :cbSize yes + ; SetScrollInfo widget as-integer vertical?/value as tagSCROLLINFO :cbSize yes ;] ] -connect-mouse-events: function [ - hWnd [handle!] - face [red-object!] - actors [red-object!] - type [integer!] + +update-rich-text: func [ + state [red-block!] + handles [red-block!] + return: [logic!] /local - _widget [handle!] + redraw [red-logic!] ][ - if all [ - not null? actors/ctx - (object/rs-find actors as red-value! _on-over) <> -1 - ][ - _widget: either type = text [ - g_object_get_qdata hWnd _widget-id - ][hWnd] - ; OR (NOT YET TESTED but if needed for widget with _widget) - ; _widget: g_object_get_qdata hWnd _widget-id - ; _widget: either null? _widget [hWnd][_widget] - - ;print [ "Mouse events " get-symbol-name type "->" widget lf] - gtk_widget_add_events _widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK - gobj_signal_connect(_widget "enter-notify-event" :widget-enter-notify-event face/ctx) - gobj_signal_connect(_widget "leave-notify-event" :widget-leave-notify-event face/ctx) - ] + if TYPE_OF(handles) = TYPE_BLOCK [ + redraw: as red-logic! (block/rs-tail handles) - 1 + redraw/value: true + ] + TYPE_OF(state) <> TYPE_BLOCK ] - - parse-common-opts: func [ - hWnd [handle!] + widget [handle!] face [red-object!] options [red-block!] type [integer!] @@ -1206,11 +1513,14 @@ parse-common-opts: func [ len [integer!] sym [integer!] cur [c-string!] - hcur [integer!] - nsimg [integer!] - btn? [logic!] + hcur [handle!] + pixbuf [handle!] + display [handle!] + x [integer!] + y [integer!] + ;;;btn? [logic!] ][ - btn?: yes + ;;;btn?: yes if TYPE_OF(options) = TYPE_BLOCK [ word: as red-word! block/rs-head options len: block/rs-length? options @@ -1219,38 +1529,35 @@ parse-common-opts: func [ sym: symbol/resolve word/symbol case [ sym = _drag-on [ - gtk_widget_add_events hWnd GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK - gobj_signal_connect(hWnd "motion-notify-event" :widget-motion-notify-event face/ctx) - gobj_signal_connect(hWnd "button-press-event" :widget-button-press-event face/ctx) - gobj_signal_connect(hWnd "button-release-event" :widget-button-release-event face/ctx) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK + gobj_signal_connect(widget "motion-notify-event" :drag-widget-motion-notify-event face/ctx) + gobj_signal_connect(widget "button-press-event" :drag-widget-button-press-event face/ctx) + gobj_signal_connect(widget "button-release-event" :drag-widget-button-release-event face/ctx) + set-draggable widget yes + ] + sym = _cursor [ + ;; DEBUG: + print ["set cursor: " widget lf] + w: word + 1 + display: gdk_window_get_display widget + either TYPE_OF(w) = TYPE_IMAGE [ + img: as red-image! w + pixbuf: OS-image/to-pixbuf img 0 0 + x: IMAGE_WIDTH(img/size) / 2 + y: IMAGE_HEIGHT(img/size) / 2 + hcur: gdk_cursor_new_from_pixbuf display pixbuf x y + ;g_object_unref pixbuf + ][ + sym: symbol/resolve w/symbol + cur: case [ + sym = _I-beam ["text"] + sym = _hand ["grab"] + sym = _cross ["crosshair"] + true ["default"] + ] + hcur: gdk_cursor_new_from_name widget cur + ] ] - ; sym = _cursor [ - ; w: word + 1 - ; either TYPE_OF(w) = TYPE_IMAGE [ - ; img: as red-image! w - ; nsimg: objc_msgSend [ - ; OBJC_ALLOC("NSImage") - ; sel_getUid "initWithCGImage:size:" OS-image/to-cgimage img 0 0 - ; ] - ; pt/x: as float32! IMAGE_WIDTH(img/size) / 2 - ; pt/y: as float32! IMAGE_HEIGHT(img/size) / 2 - ; hcur: objc_msgSend [ - ; OBJC_ALLOC("NSCursor") - ; sel_getUid "initWithImage:hotSpot:" nsimg pt/x pt/y - ; ] - ; objc_msgSend [nsimg sel_release] - ; ][ - ; sym: symbol/resolve w/symbol - ; cur: case [ - ; sym = _I-beam ["IBeamCursor"] - ; sym = _hand ["pointingHandCursor"] - ; sym = _cross ["crosshairCursor"] - ; true ["arrowCursor"] - ; ] - ; hcur: objc_msgSend [objc_getClass "NSCursor" sel_getUid cur] - ; ] - ; if hcur <> 0 [objc_setAssociatedObject hWnd RedCursorKey hcur OBJC_ASSOCIATION_ASSIGN] - ; ] ; sym = _class [ ; w: word + 1 ; sym: symbol/resolve w/symbol @@ -1261,14 +1568,14 @@ parse-common-opts: func [ ; true [0] ; ] ; objc_msgSend [ - ; objc_msgSend [hWnd sel_getUid "cell"] + ; objc_msgSend [widget sel_getUid "cell"] ; sel_getUid "setControlSize:" sym ; ] ; btn?: no ; ] ; sym = _accelerated [ ; bool: as red-logic! word + 1 - ; if bool/value [objc_msgSend [hWnd sel_getUid "setWantsLayer:" yes]] + ; if bool/value [objc_msgSend [widget sel_getUid "setWantsLayer:" yes]] ; ] true [0] ] @@ -1279,33 +1586,36 @@ parse-common-opts: func [ ; if type = button [ ; len: either btn? [NSRegularSquareBezelStyle][NSRoundedBezelStyle] - ; objc_msgSend [hWnd sel_getUid "setBezelStyle:" len] + ; objc_msgSend [widget sel_getUid "setBezelStyle:" len] ; ] ] -OS-redraw: func [hWnd [integer!]][gtk_widget_queue_draw as handle! hWnd] +OS-redraw: func [ + widget [integer!] +][ + ;; DEBUG: print ["OS-redraw" lf] + unless null? as handle! widget [gtk_widget_queue_draw as handle! widget] +] -OS-refresh-window: func [hWnd [integer!]][ - ;print-line "REFFRREEEESSSSHHHHH" +OS-refresh-window: func [widget [integer!]][ + ;; DEBUG: print-line "OS-refresh-window" ;debug-show-children main-window no ;gtk_widget_queue_draw main-window - OS-show-window hWnd + OS-show-window widget ] OS-show-window: func [ - hWnd [integer!] - ; /local + widget [integer!] + /local + face [red-object!] ; auto-adjust? [red-logic!] ][ - gtk_widget_show_all as handle! hWnd - gtk_widget_grab_focus as handle! hWnd - - ; @@ TEMPORARY: TO BE REMOVED BUT USEFUL NOW FOR COMPARING THE EFFECT OF ADJUST-SIZES IN RED TEST WITHOUT RECOMPILING CONSOLE - ;auto-adjust?: as red-logic! #get system/view/gtk-auto-adjust? - ;if all [TYPE_OF(auto-adjust?) = TYPE_LOGIC auto-adjust?/value] [ - ; adjust-sizes as handle! hWnd - ; gtk_widget_queue_draw as handle! hWnd - ;] + ;; DEBUG: print ["OS-show-window" as handle! widget "(" get-symbol-name get-widget-symbol as handle! widget ")" lf] + if null? as handle! widget [exit] + gtk_widget_show_all as handle! widget + gtk_widget_grab_focus as handle! widget + face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED + if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] ] OS-make-view: func [ @@ -1324,7 +1634,7 @@ OS-make-view: func [ img [red-image!] menu [red-block!] show? [red-logic!] - open? [red-logic!] + enabled? [red-logic!] selected [red-integer!] font [red-object!] para [red-object!] @@ -1337,12 +1647,15 @@ OS-make-view: func [ len [integer!] widget [handle!] _widget [handle!] + winbox [handle!] buffer [handle!] container [handle!] + hMenu [handle!] value [integer!] fvalue [float!] vertical? [logic!] rfvalue [red-float!] + actors [red-object!] ][ stack/mark-native words/_body @@ -1355,7 +1668,7 @@ OS-make-view: func [ offset: as red-pair! values + FACE_OBJ_OFFSET size: as red-pair! values + FACE_OBJ_SIZE show?: as red-logic! values + FACE_OBJ_VISIBLE? - open?: as red-logic! values + FACE_OBJ_ENABLED? + enabled?: as red-logic! values + FACE_OBJ_ENABLED? data: as red-block! values + FACE_OBJ_DATA img: as red-image! values + FACE_OBJ_IMAGE font: as red-object! values + FACE_OBJ_FONT @@ -1367,6 +1680,12 @@ OS-make-view: func [ bits: get-flags as red-block! values + FACE_OBJ_FLAGS sym: symbol/resolve type/symbol + actors: as red-object! values + FACE_OBJ_ACTORS + + ; if bits and FACET_FLAGS_SCROLLABLE <> 0 [ + ; flags: flags or WS_HSCROLL or WS_VSCROLL + ; ] + caption: either TYPE_OF(str) = TYPE_STRING [ len: -1 unicode/to-utf8 str :len @@ -1380,47 +1699,69 @@ OS-make-view: func [ sym = check [ widget: gtk_check_button_new_with_label caption set-logic-state widget as red-logic! data no - ;@@ No click event for check - ;gobj_signal_connect(widget "clicked" :button-clicked null) - gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = radio [ widget: either null? group-radio [ + ;; DEBUG: print ["radio created: " caption lf] gtk_radio_button_new_with_label null caption ][ + ;; DEBUG: print ["radio group-radio created: " caption lf] gtk_radio_button_new_with_label_from_widget group-radio caption ] set-logic-state widget as red-logic! data no - ;@@ Line below removed because it generates an error and there is no click event for radio - ;gobj_signal_connect(widget "clicked" :button-clicked null) - gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = button [ widget: gtk_button_new_with_label caption - gobj_signal_connect(widget "clicked" :button-clicked null) if TYPE_OF(img) = TYPE_IMAGE [ change-image widget img sym ] ] sym = base [ - widget: gtk_drawing_area_new - gobj_signal_connect(widget "draw" :base-draw face/ctx) + widget: gtk_layout_new null null; + gtk_layout_set_size widget size/x size/y + ;; widget: gtk_drawing_area_new + ] + sym = rich-text [ + widget: gtk_layout_new null null;gtk_drawing_area_new + gtk_layout_set_size widget size/x size/y ] sym = window [ - ;;;print ["win " GTKApp lf] - ;widget: gtk_application_window_new GTKApp + ;; DEBUG: print ["win App " GTKApp lf] + win-cnt: win-cnt + 1 widget: gtk_window_new 0 - ;;;print ["win1 " widget lf] + last-window: widget + ;; DEBUG: print ["win number " win-cnt " at " widget lf] + if win-cnt = 1 [ + ;; DEBUG: print ["Creation of Main window" lf] + main-window: widget + ] gtk_application_add_window GTKApp widget - ;;;print ["win2 " lf] - ; @@ DEBUG: temporary code - ;;;main-window: widget + + if bits and FACET_FLAGS_MODAL <> 0 [ + ;; DEBUG: print ["Creation of Modal window" lf] + gtk_window_set_modal widget yes + ] + gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) unless null? caption [gtk_window_set_title widget caption] gtk_window_set_default_size widget size/x size/y - gtk_container_add widget gtk_fixed_new + winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 + gtk_container_add widget winbox + if all [ ;@@ application menu ? + null? AppMainMenu + menu-bar? menu window + ][ + AppMainMenu: gtk_menu_bar_new + ;; DEBUG: print ["AppMainMenu " AppMainMenu " creation for window " widget lf] + build-menu menu AppMainMenu widget + gtk_box_pack_start winbox AppMainMenu no yes 0 + ] + gtk_widget_show winbox + container: gtk_layout_new null null + gtk_layout_set_size container size/x size/y + gtk_box_pack_start winbox container yes yes 0 + g_object_set_qdata widget real-container-id container + ;; DEBUG: print ["window is " widget " real container is " container lf] gtk_window_move widget offset/x offset/y - gobj_signal_connect(widget "delete-event" :window-delete-event null) - gobj_signal_connect(widget "size-allocate" :window-size-allocate null) ] sym = slider [ vertical?: size/y > size/x @@ -1431,26 +1772,20 @@ OS-make-view: func [ gtk_range_set_value widget as float! value gtk_scale_set_has_origin widget no gtk_scale_set_draw_value widget no - ; insert value-changed handler - gobj_signal_connect(widget "value-changed" :range-value-changed face/ctx) ] sym = text [ widget: gtk_label_new caption + ;; gtk_label_set_width_chars widget ??? _widget: gtk_event_box_new null null gtk_container_add _widget widget - gobj_signal_connect(_widget "button-press-event" :text-button-press-event widget) ] sym = field [ widget: gtk_entry_new buffer: gtk_entry_get_buffer widget unless null? caption [gtk_entry_buffer_set_text buffer caption -1] - gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) - ;Do not work: gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) - gtk_widget_set_can_focus widget yes - ;This depends on version >= 3.2 - ;gtk_widget_set_focus_on_click widget yes - gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) - gtk_entry_set_width_chars widget 0 + gtk_entry_set_width_chars widget size/x / 10 + set-hint-text widget as red-block! values + FACE_OBJ_OPTIONS + if bits and FACET_FLAGS_PASSWORD <> 0 [gtk_entry_set_visibility widget no] ] sym = progress [ widget: gtk_progress_bar_new @@ -1467,27 +1802,26 @@ OS-make-view: func [ unless null? caption [gtk_text_buffer_set_text buffer caption -1] _widget: gtk_scrolled_window_new null null gtk_container_add _widget widget - gobj_signal_connect(buffer "changed" :area-changed widget) ] sym = group-box [ widget: gtk_frame_new caption gtk_frame_set_shadow_type widget 3 gtk_frame_set_label_align widget 0.5 0.5; Todo: does not seem to work - container: gtk_fixed_new + container: gtk_layout_new null null gtk_container_add widget container ] sym = panel [ - widget: gtk_fixed_new + widget: gtk_layout_new null null unless null? caption [ buffer: gtk_label_new caption gtk_container_add widget buffer ] + gtk_layout_set_size widget size/x size/y ] sym = tab-panel [ widget: gtk_notebook_new tabs/cur: 0 tabs/nb: block/rs-length? data - gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) ] sym = text-list [ widget: gtk_list_box_new @@ -1498,7 +1832,6 @@ OS-make-view: func [ gtk_scrolled_window_set_shadow_type _widget 3 ] gtk_container_add _widget widget - gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) ] any [ sym = drop-list @@ -1506,8 +1839,9 @@ OS-make-view: func [ ][ widget: either sym = drop-list [gtk_combo_box_text_new][gtk_combo_box_text_new_with_entry] init-combo-box widget data caption sym = drop-list + ;; TODO: improve it but better than nothing from now otherwise it is uggly! + if sym = drop-down[gtk_entry_set_width_chars gtk_bin_get_child widget (size/x - 20) / 10 ] ; 10 here the size of the font... TODO: to improve later! gtk_combo_box_set_active widget 0 - gobj_signal_connect(widget "changed" :combo-selection-changed face/ctx) ] true [ ;-- search in user-defined classes @@ -1516,15 +1850,9 @@ OS-make-view: func [ ] parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym - ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - make-styles-provider widget - if sym <> base [ - change-font widget face font sym - ] - ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] if all [ @@ -1534,6 +1862,7 @@ OS-make-view: func [ p-sym: get-widget-symbol as handle! parent either null? _widget [_widget: widget][g_object_set_qdata widget _widget-id _widget ] ; TODO: case to replace with either if no more choice + ;; DEBUG: print ["Parent: " get-symbol-name p-sym " _widget" _widget lf] case [ p-sym = tab-panel [ container: as handle! parent @@ -1550,34 +1879,80 @@ OS-make-view: func [ gtk_notebook_append_page container widget buffer tabs/cur: tabs/cur + 1 if tabs/cur = tabs/nb [tabs/cur: 0 tabs/nb: 0] + set-container widget container ] + ; p-sym = panel [ + ; container: as handle! parent + ; ;save gtk_fixed container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass + ; set-container widget container + ; if sym = text [set_container _widget container] + ; gtk_widget_set_size_request _widget size/x size/y + ; gtk_layout_put container _widget offset/x offset/y + ; ] true [ - container: as handle! either p-sym = panel [parent][buffer: gtk_container_get_children as handle! parent buffer/value] - ;save gtk_fixed container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass - g_object_set_qdata widget gtk-fixed-id container - if sym = text [g_object_set_qdata _widget gtk-fixed-id container] + container: as handle! case [ + p-sym = window [ + g_object_get_qdata as handle! parent real-container-id + ] + any [p-sym = panel p-sym = rich-text p-sym = base] [parent] + p-sym = group-box [ + buffer: gtk_container_get_children as handle! parent + ;; DEBUG: print ["Parent when not container : " buffer/value lf] + buffer/value + ] + true [ + ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug + ; buffer: gtk_container_get_children as handle! parent + ; ;; DEBUG: + ; print ["Parent when not container : " buffer/value lf] + ; buffer/value + + ;; redirect to the layout of the parent + ;; WARNING: (since completedly changed code) + print ["DEVEL WARNING: <> (ONLY FOR DEVELOPMENT SINCE CODE HAS FULLY CHANGED BUT IMPOSSIBLE TO TEST) " lf] + container? as handle! parent + ] + ] + ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[_widget: " _widget "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] + + ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass + set-container widget container + if sym = text [set-container _widget container] gtk_widget_set_size_request _widget size/x size/y - gtk_fixed_put container _widget offset/x offset/y + gtk_layout_put container _widget offset/x offset/y + ;; DEBUG: print ["make-view: _widget: " offset/x "x" offset/y "x" size/x "x" size/y lf] ] ] ] - connect-mouse-events widget face as red-object! values + FACE_OBJ_ACTORS sym - + ; Deal with actors + connect-widget-events widget face actors sym _widget as int-ptr! parent + + unless any[sym = window sym = area][build-context-menu widget menu] + ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events store-face-to-obj widget face if sym = text [store-face-to-obj _widget face] - ; change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym - ; change-para widget face as red-object! values + FACE_OBJ_PARA font sym + change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym + change-para widget face as red-object! values + FACE_OBJ_PARA font sym - unless show?/value [change-visible widget no sym] - unless open?/value [change-enabled widget no sym] + unless show?/value [add-invisible widget] + change-enabled widget enabled?/value sym + + make-styles-provider widget + + ;; TODO: NOT SURE the if is necessary! + if sym <> base [ + change-font widget face font sym + ] - ; change-font widget face font sym if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] - ; if sym <> base [change-color widget as red-tuple! values + FACE_OBJ_COLOR sym] + + change-color widget as red-tuple! values + FACE_OBJ_COLOR sym + + ;; USELESS: if sym <> window [gtk_widget_show widget] stack/unwind as-integer widget @@ -1600,6 +1975,7 @@ OS-update-view: func [ flags [integer!] type [integer!] ][ + ;; DEBUG: print ["OS-update-view" lf] ctx: GET_CTX(face) s: as series! ctx/values/value values: s/offset @@ -1607,9 +1983,20 @@ OS-update-view: func [ state: as red-block! values + FACE_OBJ_STATE word: as red-word! values + FACE_OBJ_TYPE type: symbol/resolve word/symbol + + if all [ + type = rich-text + update-rich-text state as red-block! values + FACE_OBJ_EXT3 + ][ + ;; DEBUG: print ["update-view rich-text" lf] + exit + ] + s: GET_BUFFER(state) int: as red-integer! s/offset widget: as handle! int/value + if null? widget [exit] + int: int + 1 flags: int/value @@ -1621,7 +2008,7 @@ OS-update-view: func [ ] if flags and FACET_FLAG_TEXT <> 0 [ change-text widget values face type - gtk_widget_queue_draw widget + ;gtk_widget_queue_draw widget ] if flags and FACET_FLAG_DATA <> 0 [ change-data widget values @@ -1634,30 +2021,34 @@ OS-update-view: func [ bool: as red-logic! values + FACE_OBJ_VISIBLE? change-visible widget bool/value type ] - ;if flags and FACET_FLAG_SELECTED <> 0 [ - ; int2: as red-integer! values + FACE_OBJ_SELECTED - ; change-selection widget int2 values - ;] - ;if flags and FACET_FLAG_FLAGS <> 0 [ - ; SetWindowLong - ; widget - ; wc-offset + 16 - ; get-flags as red-block! values + FACE_OBJ_FLAGS - ;] + if flags and FACET_FLAG_SELECTED <> 0 [ + int2: as red-integer! values + FACE_OBJ_SELECTED + change-selection widget int2 type + ] + if flags and FACET_FLAG_FLAGS <> 0 [ + flags: get-flags as red-block! values + FACE_OBJ_FLAGS + if all[ + type = field + flags and FACET_FLAGS_PASSWORD <> 0 + ][ + ;; DEBUG: print ["password flag activated for field" lf] + gtk_entry_set_visibility widget no + ] + ] if flags and FACET_FLAG_DRAW <> 0 [ gtk_widget_queue_draw widget + ; 0 ] if flags and FACET_FLAG_COLOR <> 0 [ + ;; DEBUG: print ["FACET_FLAG_COLOR " get-symbol-name type lf] if type = base [ - ; update-base widget null null values - gtk_widget_queue_draw widget - ; ][ - ; InvalidateRect widget null 1 + ;; DEBUG: print ["FACET_FLAG_COLOR " widget lf] + change-color widget as red-tuple! values + FACE_OBJ_COLOR type ] ] if all [flags and FACET_FLAG_PANE <> 0 type <> tab-panel][ - ;update-z-order hWnd as red-block! values + FACE_OBJ_PANE type - 0 + update-z-order widget as red-block! values + FACE_OBJ_PANE type + ;0 ] if flags and FACET_FLAG_RATE <> 0 [ change-rate widget values + FACE_OBJ_RATE @@ -1665,10 +2056,14 @@ OS-update-view: func [ if flags and FACET_FLAG_FONT <> 0 [ change-font widget face as red-object! values + FACE_OBJ_FONT type ] - ;if flags and FACET_FLAG_PARA <> 0 [ - ; update-para face 0 - ; InvalidateRect widget null 1 - ;] + if flags and FACET_FLAG_PARA <> 0 [ + change-para + widget + face + as red-object! values + FACE_OBJ_PARA + as red-object! values + FACE_OBJ_FONT + type + ] ;if flags and FACET_FLAG_MENU <> 0 [ ; menu: as red-block! values + FACE_OBJ_MENU ; if menu-bar? menu window [ @@ -1676,13 +2071,42 @@ OS-update-view: func [ ; SetMenu widget build-menu menu CreateMenu ; ] ;] - ;if flags and FACET_FLAG_IMAGE <> 0 [ - ; change-image widget values type + if flags and FACET_FLAG_IMAGE <> 0 [ + change-image widget as red-image! values + FACE_OBJ_IMAGE type + ] + + ;; update-view at least ask for this + ;if main-window = widget [ + gtk_widget_queue_draw widget ;] int/value: 0 ;-- reset flags ] +unlink-sub-obj: func [ + face [red-object!] + obj [red-object!] + field [integer!] + /local + values [red-value!] + parent [red-block!] + res [red-value!] +][ + values: object/get-values obj + parent: as red-block! values + field + + if TYPE_OF(parent) = TYPE_BLOCK [ + res: block/find parent as red-value! face null no no yes no null null no no no no + if TYPE_OF(res) <> TYPE_NONE [_series/remove as red-series! res null null] + if all [ + field = FONT_OBJ_PARENT + block/rs-tail? parent + ][ + free-font obj + ] + ] +] + OS-destroy-view: func [ face [red-object!] empty? [logic!] @@ -1692,21 +2116,36 @@ OS-destroy-view: func [ obj [red-object!] flags [integer!] ][ + ;; DEBUG: print ["OS-destroy-view" lf] handle: face-handle? face values: object/get-values face flags: get-flags as red-block! values + FACE_OBJ_FLAGS - if flags and FACET_FLAGS_MODAL <> 0 [ - 0 - ] + either handle <> main-window [ + ;; DEBUG: if flags and FACET_FLAGS_MODAL <> 0 [print ["modal "]] print ["window: " handle " (main-window: " main-window ") closing... win-cnt: " win-cnt " exit-loop: " exit-loop lf ] + + ;gtk_window_close handle ;; NOT ENOUGH SINCE THIS IS EQUIVALENT TO CLICKING CLOSE BUTTON + gtk_widget_destroy handle + win-cnt: win-cnt - 1 + ][ - free-handles handle values + ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] obj: as red-object! values + FACE_OBJ_FONT - ;if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] obj: as red-object! values + FACE_OBJ_PARA - ;if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] + + ;;g_main_context_release GTKApp-Ctx + ;; DEBUG: + + ;; TODO: This can be useless now! + remove-all-timers handle + ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] + + free-handles as-integer handle no + ] ] OS-update-facet: func [ @@ -1721,12 +2160,18 @@ OS-update-facet: func [ word [red-word!] sym [integer!] type [integer!] - hWnd [handle!] + pane [red-block!] + widget [handle!] ][ sym: symbol/resolve facet/symbol + ;; DEBUG: print ["update-facet " get-symbol-name sym lf] case [ - ;sym = facets/pane [0] + ; sym = facets/pane [ + ; sym: action/symbol + ; ;; DEBUG: print ["update pane action " get-symbol-name sym lf] + ; pane: as red-block! value + ; ] sym = facets/data [ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol @@ -1753,7 +2198,7 @@ OS-to-image: func [ face [red-object!] return: [red-image!] /local - hWnd [handle!] + widget [handle!] dc [handle!] mdc [handle!] width [integer!] @@ -1764,39 +2209,97 @@ OS-to-image: func [ word [red-word!] type [integer!] size [red-pair!] - screen? [logic!] ret [red-image!] ][ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE - screen?: screen = symbol/resolve word/symbol - either screen? [ - ; get pixbuf from screen_root_window - bmp: as handle! 0;gdk_pixbuf_get_from_window gdk_screen_get_root_window gdk_screen_get_default 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp - ][ - ;view: as-integer face-handle? face - ;either zero? view [ret: as red-image! none-value][ - ; sz: as red-pair! (object/get-values face) + FACE_OBJ_SIZE - ; rc: make-rect 0 0 sz/x sz/y - ; data: objc_msgSend [view sel_getUid "dataWithPDFInsideRect:" rc/x rc/y rc/w rc/h] - ; img: objc_msgSend [ - ; objc_msgSend [objc_getClass "NSImage" sel_alloc] - ; sel_getUid "initWithData:" data - ; ] - bmp: as handle! 0; objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] + type: symbol/resolve word/symbol + + ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] + + case [ + type = screen [ + ; get pixbuf from screen_root_window + bmp: as handle! 0;gdk_pixbuf_get_from_window gdk_screen_get_root_window gdk_screen_get_default 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp - ; objc_msgSend [bmp sel_getUid "retain"] - ; objc_msgSend [img sel_release] - ;] + ] + true [ + widget: face-handle? face + either null? widget [ret: as red-image! none-value][ + size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE + ; rc: make-rect 0 0 sz/x sz/y + ; data: objc_msgSend [view sel_getUid "dataWithPDFInsideRect:" rc/x rc/y rc/w rc/h] + ; img: objc_msgSend [ + ; objc_msgSend [objc_getClass "NSImage" sel_alloc] + ; sel_getUid "initWithData:" data + ; ] + bmp: as handle! 0; objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp + ; objc_msgSend [bmp sel_getUid "retain"] + ; objc_msgSend [img sel_release] + ] + ] ] ret ] OS-do-draw: func [ - img [red-image!] + image [red-image!] cmds [red-block!] + /local + cr [handle!] + surf [handle!] + w [integer!] + h [integer!] + bitmap [integer!] + data [int-ptr!] + stride [integer!] +][ + ;; DEBUG: print ["OS-do-draw " image lf] + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + stride: 0 + bitmap: OS-image/lock-bitmap image yes + data: OS-image/get-data bitmap :stride + ;; DEBUG: print ["OS-do-draw data " data " size: " w "x" h " stride: " stride lf] + ;stride: cairo_format_stride_for_width CAIRO_FORMAT_ARGB32 w + surf: cairo_image_surface_create_for_data as byte-ptr! data CAIRO_FORMAT_ARGB32 w h stride + cr: cairo_create surf + ;; OLD: do-draw cr null cmds no yes yes yes + do-draw cr null cmds yes no no no + cairo_destroy cr + cairo_surface_destroy surf + ;; USELESS NOW???: OS-image/post-transf OS-image/POST-ARGB-TO-ABGR + OS-image/unlock-bitmap image bitmap +] + +OS-do-draw-OLD: func [ + image [red-image!] + cmds [red-block!] + /local + cr [handle!] + surf [handle!] + w [integer!] + h [integer!] + bitmap [integer!] + data [int-ptr!] + stride [integer!] + pixbuf [int-ptr!] + buf [byte-ptr!] ][ - do-draw null img cmds no no no no + ;; DEBUG: print ["OS-do-draw " image lf] + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + stride: 0 + bitmap: OS-image/lock-bitmap image yes + data: OS-image/get-data bitmap :stride + ;stride: cairo_format_stride_for_width CAIRO_FORMAT_ARGB32 w + surf: cairo_image_surface_create_for_data as byte-ptr! data CAIRO_FORMAT_ARGB32 w h stride + cr: cairo_create surf + do-draw cr null cmds no yes yes yes + cairo_destroy cr + cairo_surface_destroy surf + OS-image/buffer-argb-to-abgr data w h + OS-image/unlock-bitmap image bitmap ] OS-draw-face: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 526846aba1..10c8546d18 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -42,7 +42,9 @@ set-text: func [ face [red-object!] out [c-string!] ][ + ;; DEBUG: print ["set-text: " text lf] size: length? text + ;; DEBUG: print ["length?: " size lf] if size >= 0 [ str: as red-string! get-node-facet ctx FACE_OBJ_TEXT if TYPE_OF(str) <> TYPE_STRING [ @@ -52,8 +54,8 @@ set-text: func [ string/rs-reset str exit ] + ;; TODO: bug with unicode characters just below unicode/load-utf8-buffer text size GET_BUFFER(str) null no - face: push-face obj if TYPE_OF(face) = TYPE_OBJECT [ ownership/bind as red-value! str face _text @@ -91,11 +93,10 @@ button-toggled: func [ make-event button 0 EVT_CHANGE ] - render-text: func [ cr [handle!] + size [red-pair!] values [red-value!] - ;sz [NSSize!] /local text [red-string!] font [red-object!] @@ -109,6 +110,11 @@ render-text: func [ temp [float!] ;te [cairo_text_extents_t!] ;fe [cairo_font_extents_t!] + lx [integer!] + ly [integer!] + rect [tagRECT value] + lrect [tagRECT value] + pline [handle!] pc [handle!] lpc [handle!] fd [handle!] @@ -116,13 +122,16 @@ render-text: func [ text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] + ;; DEBUG: print ["render-text: " cr lf] para: as red-object! values + FACE_OBJ_PARA flags: either TYPE_OF(para) = TYPE_OBJECT [ ;@@ TBD set alignment attribute get-para-flags base para ][ - 2 or 4 ;-- center + 0005h ;-- center or middle ] + cairo_save cr + ; The pango_cairo way pc: pango_cairo_create_context cr lpc: pango_cairo_create_layout cr @@ -134,11 +143,37 @@ render-text: func [ len: -1 str: unicode/to-utf8 text :len ] + ;; DEBUG: print ["render-text " str " size: " size/x "x" size/y " flags: " flags lf] + pango_layout_set_text lpc str -1 cairo_set_source_rgba cr 0.0 0.0 0.0 0.5 pango_cairo_update_layout cr lpc + + pline: pango_layout_get_line lpc 0 + pango_layout_line_get_pixel_extents pline rect lrect + ly: (pango_layout_get_line_count lpc) * lrect/height + lx: lrect/width + + case [ + flags and 0001h <> 0 [x: (as-float (size/x - lx)) / 2.0] ; center + flags and 0002h <> 0 [x: as-float (size/x - lx)] ; right + true [x: 0.0] ; left + ] + case [ + flags and 0004h <> 0 [y: (as-float (size/y - ly)) / 2.0] ; middle + flags and 0008h <> 0 [y: as-float (size/y - ly)] ; bottom + true [y: 0.0] ; top + ] + + ;; DEBUG: print [lx "x" ly " and (" x "," y ")" lf] + + cairo_move_to cr x y + pango_cairo_show_layout cr lpc + cairo_stroke cr + cairo_restore cr + ; @@ The cairo way (alternative) does not work for me after too many attempt ; if TYPE_OF(text) = TYPE_STRING [ ; len: -1 @@ -178,64 +213,128 @@ base-draw: func [ ctx [node!] return: [logic!] /local - vals [red-value!] - draw [red-block!] - clr [red-tuple!] - img [red-image!] + vals [red-value!] + draw [red-block!] + clr [red-tuple!] + img [red-image!] + size [red-pair!] + type [red-word!] + sym [integer!] + pos [red-pair! value] + DC [draw-ctx! value] ][ + ;; DEBUG: print ["base-draw " widget lf] + vals: get-node-values ctx + img: as red-image! vals + FACE_OBJ_IMAGE draw: as red-block! vals + FACE_OBJ_DRAW clr: as red-tuple! vals + FACE_OBJ_COLOR - img: as red-image! vals + FACE_OBJ_IMAGE + size: as red-pair! vals + FACE_OBJ_SIZE + type: as red-word! vals + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol if TYPE_OF(clr) = TYPE_TUPLE [ - ;0 - ;print ["color" (clr/array1 and 00FFFFFFh) lf] - set-source-color cr clr/array1 - cairo_paint cr ;-- paint background + ;; DEBUG: print ["base-draw color" (clr/array1 >>> 24 and FFh) "x" (clr/array1 >> 16 and FFh ) "x" (clr/array1 >> 8 and FFh ) "x" (clr/array1 and FFh ) lf] + + ;;; OLD and DOES NOT WORK + ; cairo_save cr + ; set-source-color cr clr/array1 + ; cairo_paint cr ;-- paint background + ; cairo_restore cr + ;cairo_save cr + gtk_render_background gtk_widget_get_style_context widget cr 0.0 0.0 as float! size/x as float! size/y + ;cairo_restore cr ] if TYPE_OF(img) = TYPE_IMAGE [ - GDK-draw-image cr as handle! OS-image/to-pixbuf img 0 0 0 0 + ;; DEBUG: print ["base-draw, GDK-draw-image: " 0 "x" 0 "x" size/x "x" size/y lf] + ;; ONLY WORK for Mandelbrot and raytracer: + ;; GDK-draw-image cr OS-image/to-argb-pixbuf img 0 0 size/x size/y + GDK-draw-image cr OS-image/to-pixbuf img 0 0 size/x size/y ] - render-text cr vals + case [ + sym = base [render-text cr size vals] + sym = rich-text [ + ;; DEBUG: print ["base-draw (rich-text)" widget " face " get-face-obj widget lf] + pos/x: 0 pos/y: 0 + init-draw-ctx :DC cr + draw-text-box :DC :pos get-face-obj widget yes + ] + true [] + ] either TYPE_OF(draw) = TYPE_BLOCK [ + ;; DEBUG: print ["do-draw in base-draw" lf] do-draw cr null draw no yes yes yes ][ ; system/thrown: 0 ; DC: declare draw-ctx! ;@@ should declare it on stack ; draw-begin DC ctx img no no ; integer/make-at as red-value! draw as-integer DC - ; make-event self 0 EVT_DRAWING + make-event widget 0 EVT_DRAWING ; draw/header: TYPE_NONE ; draw-end DC ctx no no no - 0 ] - ;print ["base-draw " widget lf] + ;; DEBUG: print ["base-draw " widget lf] + false ] window-delete-event: func [ [cdecl] widget [handle!] - event [handle!] - exit-lp [int-ptr!] return: [logic!] ][ - false + ;; DEBUG: print ["window-delete-event" lf] + make-event widget 0 EVT_CLOSE + no ] +; window-destroy: func [ +; [cdecl] +; widget [handle!] +; ][ +; ;; DEBUG: print ["window-destroy" lf] +; ;;remove-all-timers widget +; make-event widget 0 EVT_CLOSE +; ] + window-removed-event: func [ [cdecl] app [handle!] widget [handle!] count [int-ptr!] ][ - count/value: count/value - 1 + ;; DEBUG[view/no-wait]: print ["App " app " removed window " widget "exit-loop: " exit-loop " win-cnt: " win-cnt " main-window? " main-window = widget] + unless view-no-wait? widget [count/value: count/value - 1] + ;; DEBUG[view/no-wait]: print ["=> exit-loop: " count/value lf] ] +;; BUG: `vid.red` fails... back with window-size-allocate handler for resizing +; window-configure-event: func [ +; [cdecl] +; widget [handle!] +; event [GdkEventConfigure!] +; /local +; sz [red-pair!] +; ][ +; ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] +; sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size +; either any [event/width <> sz/x event/height <> sz/y] [ +; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ +; evt-motion/x_new: event/width +; evt-motion/y_new: event/height +; evt-motion/x_root: as float! event/x +; evt-motion/y_root: as float! event/y +; make-event widget 0 EVT_SIZING +; ;] +; ;evt-motion/cpt: evt-motion/cpt + 1 +; yes +; ][no] +; ] + + window-size-allocate: func [ [cdecl] widget [handle!] @@ -243,12 +342,18 @@ window-size-allocate: func [ /local sz [red-pair!] ][ - ;;DEBUG: print [ "window-size-allocate " rect/width "x" rect/height lf] - make-event widget 0 EVT_SIZING + ;; DEBUG: print ["window-size-allocate" lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size - sz/x: rect/width - sz/y: rect/height - ;; DEBUG: print [ "window-size-allocate end" lf] + if any [rect/width <> sz/x rect/height <> sz/y] [ + evt-sizing/x_new: rect/width + evt-sizing/y_new: rect/height + sz/x: evt-sizing/x_new + sz/y: evt-sizing/y_new + ;; DEBUG: print ["window-size-allocate: " evt-sizing/x_root "x" evt-sizing/y_root lf] + evt-sizing/x_root: as float! rect/x + evt-sizing/y_root: as float! rect/y + make-event widget 0 EVT_SIZING + ] ] range-value-changed: func [ @@ -286,7 +391,7 @@ range-value-changed: func [ ;] ] -text-button-press-event: func [ +simple-button-press-event: func [ [cdecl] _widget [handle!] evt [handle!] @@ -294,6 +399,14 @@ text-button-press-event: func [ ][ make-event widget 0 EVT_LEFT_DOWN ] +simple-button-release-event: func [ + [cdecl] + _widget [handle!] + evt [handle!] + widget [handle!] +][ + make-event widget 0 EVT_LEFT_UP +] combo-selection-changed: func [ [cdecl] @@ -362,11 +475,12 @@ tab-panel-switch-page: func [ ] ; Do not use key-press-event since character would not be printed! -field-key-release-event: func [ +field-key-press-event: func [ [cdecl] widget [handle!] event-key [GdkEventKey!] ctx [node!] + return: [integer!] /local res [integer!] key [integer!] @@ -374,30 +488,61 @@ field-key-release-event: func [ text [c-string!] face [red-object!] qdata [handle!] -][ - ;print "key-release: " - ;print [ "keyval: " event-key/keyval " -> " gdk_keyval_name event-key/keyval "(" event-key/keyval " -> " gdk_keyval_to_lower event-key/keyval ") et state: " event-key/state lf] - ;print [ "keycode: " as integer! event-key/keycode1 " " as integer! event-key/keycode2 lf] - - if event-key/keyval > FFFFh [exit] +][ + ;; DEBUG: print ["key-press-event: " event-key/keyval lf] + if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state - ;print ["key: " key " flags: " flags " key or flags: " key or flags lf] + ;; DEBUG: print ["key: " key " flags: " flags " key or flags: " key or flags lf] res: make-event widget key or flags EVT_KEY_DOWN + ;; DEBUG: print ["field press res " res lf] if res <> EVT_NO_DISPATCH [ - make-event widget key or flags EVT_KEY + ;; DEBUG: print ["special-key=" special-key " key=" key lf] + either special-key <> -1 [ + switch key and FFFFh [ + RED_VK_SHIFT RED_VK_CONTROL + RED_VK_LSHIFT RED_VK_RSHIFT + RED_VK_LCONTROL RED_VK_RCONTROL + RED_VK_LMENU RED_VK_RMENU + RED_VK_UNKNOWN [0] ;-- no KEY event + default [res: make-event widget key or flags EVT_KEY] ;-- force a KEY event + ] + ][res: make-event widget key or flags EVT_KEY] ] + ;; DEBUG: print ["key-press end" lf] + EVT_DISPATCH +] + +field-key-release-event: func [ + [cdecl] + widget [handle!] + event-key [GdkEventKey!] + ctx [node!] + return: [integer!] + /local + res [integer!] + key [integer!] + flags [integer!] + text [c-string!] + face [red-object!] + qdata [handle!] +][ + ;; DEBUG: print "key-release: " + ;; DEBUG: print [ "keyval: " event-key/keyval " -> " gdk_keyval_name event-key/keyval "(" event-key/keyval " -> " gdk_keyval_to_lower event-key/keyval ") et state: " event-key/state lf] + ;; DEBUG: print [ "keycode: " as integer! event-key/keycode1 " " as integer! event-key/keycode2 lf] text: gtk_entry_get_text widget qdata: g_object_get_qdata widget red-face-id + ;; DEBUG: print ["qdata: " qdata "text: " text lf] unless null? qdata [ face: as red-object! qdata set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] + make-event widget 0 EVT_KEY_UP ] field-move-focus: func [ @@ -409,6 +554,35 @@ field-move-focus: func [ print-line "move-focus" ] +field-button-release-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + x [integer!] + y [integer!] + sel [red-pair!] +][ + ;; DEBUG: print [ "field mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + if event/button = GDK_BUTTON_PRIMARY [ + x: -1 y: -1 + if gtk_editable_get_selection_bounds widget :x :y [ + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT + ] + ] + make-event widget 0 EVT_LEFT_UP + EVT_NO_DISPATCH +] + area-changed: func [ [cdecl] buffer [handle!] @@ -434,13 +608,94 @@ area-changed: func [ ] ] +area-button-press-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + flags [integer!] +][ + ;; DEBUG: print [ "area -> BUTTON-PRESS: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + + menu-x: as-integer event/x + menu-y: as-integer event/y + ;; DEBUG: print ["menu cursor pos: " menu-x "x" menu-y lf] + flags: check-flags event/type event/state + make-event widget flags EVT_LEFT_DOWN + 0;;no +] + +area-button-release-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + flags [integer!] + buffer [handle!] + start [GtkTextIter!]; value does not work + end [GtkTextIter!] + x [integer!] + y [integer!] + sel [red-pair!] +][ + ;; DEBUG: print [ "area mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + if event/button = GDK_BUTTON_PRIMARY [ + start: as GtkTextIter! allocate (size? GtkTextIter!) + end: as GtkTextIter! allocate (size? GtkTextIter!) + buffer: gtk_text_view_get_buffer widget + if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ + x: -1 y: -1 + x: gtk_text_iter_get_offset as handle! start + y: gtk_text_iter_get_offset as handle! end + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT + ] + free as byte-ptr! start free as byte-ptr! end + ] + 0 +] + +area-populate-popup: func [ + [cdecl] + widget [handle!] + hMenu [handle!] + ctx [node!] + /local + menu [red-block!] +][ + ;; DEBUG: print ["populate menu for " widget " and menu " hMenu lf] + menu: as red-block! get-node-facet ctx FACE_OBJ_MENU + append-context-menu menu hMenu widget +] + red-timer-action: func [ [cdecl] self [handle!] - return: [logic!] + return: [integer!] + /local + timer [int-ptr!] ][ - make-event self 0 EVT_TIME - yes + ; timer: get-widget-timer self + ; either null? timer [ + ;either null? main-window [no] + ;[ + make-event self 0 EVT_TIME + 1 + ;];[ + ; print ["timer for widget " self " will stop!" lf] + ; remove-widget-timer self + ; no ; this removes the timer + ; ] ] widget-enter-notify-event: func [ @@ -448,11 +703,15 @@ widget-enter-notify-event: func [ widget [handle!] event [GdkEventCrossing!] ctx [node!] - return: [logic!] + return: [integer!] + /local + flags [integer!] ][ - ;print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - make-event widget 0 EVT_OVER - no + ;; DEBUG: print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + + flags: check-flags event/type event/state + make-event widget flags EVT_OVER + 0;;no ] widget-leave-notify-event: func [ @@ -460,73 +719,314 @@ widget-leave-notify-event: func [ widget [handle!] event [GdkEventCrossing!] ctx [node!] - return: [logic!] + return: [integer!] + /local + flags [integer!] ][ - ;print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - make-event widget EVT_FLAG_AWAY EVT_OVER - no + ;; DEBUG: print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + flags: check-flags event/type event/state + make-event widget flags or EVT_FLAG_AWAY EVT_OVER + 0;;no ] -widget-motion-notify-event: func [ +drag-widget-motion-notify-event: func [ [cdecl] widget [handle!] event [GdkEventMotion!] ctx [node!] - return: [logic!] + return: [integer!] /local offset [red-pair!] x [float!] y [float!] - ; state [red-block!] - ; int [red-integer!] - ; s [series!] - -][ - ;print [ "MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - either motion/state [ - if 0 = (motion/cpt % motion/sensitiv) [ - x: event/x_root - motion/x_root - y: event/y_root - motion/y_root - motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] - motion/y_new: as-integer y + either y > 0.0 [0.5][-0.5] - motion/x_root: event/x_root - motion/y_root: event/y_root - make-event widget 0 EVT_OVER + flags [integer!] + state [integer!] + +][ + state: 0 + ;; DEBUG: print [ "DRAG MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + if evt-motion/state [ + if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ + x: event/x_root - evt-motion/x_root + y: event/y_root - evt-motion/y_root + evt-motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] + evt-motion/y_new: as-integer y + either y > 0.0 [0.5][-0.5] + ;; DEBUG: print ["new " evt-motion/x_new "x" evt-motion/y_new lf] + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + flags: check-flags event/type event/state + state: make-event widget flags EVT_OVER ] - motion/cpt: motion/cpt + 1 - yes - ][no] + evt-motion/cpt: evt-motion/cpt + 1 + state: 1;;yes + ] + state ] -widget-button-press-event: func [ +drag-widget-button-press-event: func [ [cdecl] widget [handle!] event [GdkEventButton!] ctx [node!] - return: [logic!] + return: [integer!] /local offset [red-pair!] + flags [integer!] ][ - ; print [ "BUTTON-PRESS: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - motion/state: yes - motion/cpt: 0 - motion/x_root: event/x_root - motion/y_root: event/y_root - motion/x_new: 0 - motion/y_new: 0 - make-event widget 0 EVT_LEFT_DOWN - yes + ;; DEBUG: print [ "DRAG BUTTON-PRESS: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + if any[ + event/button = GDK_BUTTON_PRIMARY + event/button = GDK_BUTTON_SECONDARY + ][ + evt-motion/state: yes + evt-motion/cpt: 0 + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + evt-motion/x_new: 0 + evt-motion/y_new: 0 + ] + flags: check-flags event/type event/state + make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_DOWN] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_DOWN] true [EVT_LEFT_DOWN]] + 1;;yes ] -widget-button-release-event: func [ +drag-widget-button-release-event: func [ [cdecl] widget [handle!] event [GdkEventButton!] ctx [node!] - return: [logic!] + return: [integer!] + /local + type [red-word!] + sym [integer!] + state [logic!] + flags [integer!] ][ - ; print [ "BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - motion/state: no - make-event widget 0 EVT_LEFT_UP - yes + ;; DEBUG: print [ "Drag -> BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + unless any[event/button = GDK_BUTTON_PRIMARY event/button = GDK_BUTTON_SECONDARY event/button = GDK_BUTTON_MIDDLE] [return 0] + ; Special treatment for check and radio buttons (TODO: button) + type: as red-word! get-node-facet ctx FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + + if all [ + any [sym = check sym = radio] + evt-motion/cpt = 0 ; IMPORTANT: change state only if no dragging! + ][ + state: gtk_toggle_button_get_active widget + gtk_toggle_button_set_active widget either sym = check [not state][yes] + ] + + evt-motion/state: no + flags: check-flags event/type event/state + make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] true [EVT_LEFT_UP]] + EVT_NO_DISPATCH +] + +container-emit-event: func [ + [cdecl] + widget [handle!] + event [int-ptr!] + /local + rect [tagRECT] + evt [GdkEventButton!] + x [integer!] + y [integer!] +][ + evt: as GdkEventButton! event + x: as-integer evt/x y: as-integer evt/y + rect: as tagRECT allocate (size? tagRECT) + gtk_widget_get_allocation widget as handle! rect + + ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit event " widget lf]] + if all[x >= rect/x x <= (rect/x + rect/width) y >= rect/y y <= (rect/y + rect/height)][ + ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit2 event " widget " event " evt/x "x" evt/y lf "widget size " rect/x "x" rect/y "x" rect/width "x" rect/height lf]] + gtk_widget_event widget event + ] + free as byte-ptr! rect +] + +container-delegate-to-children: func [ + [cdecl] + widget [handle!] + event [int-ptr!] + ctx [node!] + return: [integer!] +][ + ;; DEBUG: print [ "parent -> CONTAINER DELEGATE: " widget lf] + gtk_container_foreach widget as-integer :container-emit-event event + EVT_DISPATCH +] + +mouse-button-press-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + flags [integer!] + hMenu [handle!] +][ + ;; DEBUG: print [ "mouse -> BUTTON-PRESS: " widget " (" ") x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] + ; evt-motion/state: yes + ; evt-motion/cpt: 0 + + if gtk_widget_get_focus_on_click widget [ + ;; DEBUG: print ["grab focus on mouse " widget lf] + gtk_widget_grab_focus widget + ] + if draggable? widget [return 0] ; delegate to drag + + ;; DEBUG: print ["with button " event/button lf] + if event/button = GDK_BUTTON_SECONDARY [ + hMenu: context-menu? widget + ;; DEBUG: print ["widget " widget " with menu " hMenu lf] + unless null? hMenu [ + menu-x: as-integer event/x + menu-y: as-integer event/y + ;; DEBUG: print ["menu pointer : " menu-x "x" menu-y lf] + gtk_menu_popup_at_pointer hMenu as handle! event + return EVT_NO_DISPATCH + ] + + ] + + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + evt-motion/x_new: as-integer event/x + evt-motion/y_new: as-integer event/y + flags: check-flags event/type event/state + make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_DOWN] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_DOWN] true [EVT_LEFT_DOWN]] + ;; DEBUG: print ["NO DISPATCH" lf] + EVT_NO_DISPATCH +] + +mouse-button-release-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + flags [integer!] +][ + ;; DEBUG: print [ "mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] + if draggable? widget [return 0] ; delegate to drag + evt-motion/state: yes + evt-motion/cpt: 0 + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + evt-motion/x_new: as-integer event/x + evt-motion/y_new: as-integer event/y + flags: check-flags event/type event/state + make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] true [EVT_LEFT_UP]] + ;;0 ;;no +] + +mouse-motion-notify-event: func [ + [cdecl] + widget [handle!] + event [GdkEventMotion!] + ctx [node!] + return: [integer!] + /local + offset [red-pair!] + x [float!] + y [float!] + wflags [integer!] + flags [integer!] +][ + ;; DEBUG: print [ "mouse -> MOTION: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] + + if draggable? widget [return EVT_DISPATCH] ; delegate to drag + evt-motion/x_new: as-integer event/x + evt-motion/y_new: as-integer event/y + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS + if wflags and FACET_FLAGS_ALL_OVER <> 0 [ + flags: check-flags event/type event/state + make-event widget flags EVT_OVER + ] + ;; DEBUG: print ["mouse-motion-notify-event: down? " (event/state and GDK_BUTTON1_MASK <> 0) " " (flags and EVT_FLAG_DOWN <> 0) lf] + EVT_DISPATCH ;;no +] + +key-press-event: func [ + [cdecl] + widget [handle!] + event-key [GdkEventKey!] + ctx [node!] + return: [integer!] + /local + state [integer!] + key [integer!] + flags [integer!] + text [c-string!] +][ + + ;; DEBUG: print ["key-press-event: " event-key/keyval " " widget lf] + state: 0 + either event-key/keyval > FFFFh [state: 1][ + key: translate-key event-key/keyval + flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not + flags: flags or check-extra-keys event-key/state + + + state: make-event widget key or flags EVT_KEY_DOWN + unless state = EVT_NO_DISPATCH [ + state: make-event widget key or flags EVT_KEY + ] + ] + state +] + +key-release-event: func [ + [cdecl] + widget [handle!] + event-key [GdkEventKey!] + ctx [node!] + return: [integer!] + /local + state [integer!] + key [integer!] + flags [integer!] + text [c-string!] +][ + ;; DEBUG: print ["key-release-event: " event-key/keyval " " widget lf] + state: 0 + either event-key/keyval > FFFFh [state: 1][ + key: translate-key event-key/keyval + flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not + flags: flags or check-extra-keys event-key/state + + + state: make-event widget key or flags EVT_KEY_UP + unless state = EVT_NO_DISPATCH [ + state: make-event widget key or flags EVT_KEY + ] + ] + state +] + +menu-item-activate: func [ + [cdecl] + item [handle!] + widget [handle!] + /local + key [integer!] +][ + key: menu-item-key? item + ;; DEBUG: print ["menu-item activated: " item " with key: " key " on widget " widget lf] + make-event widget key EVT_MENU +] + +widget-scroll-event: func [ + [cdecl] + widget [handle!] + event [GdkEventScroll!] + ctx [node!] + return: [integer!] +][ + make-event widget check-flags event/type event/state EVT_WHEEL ] diff --git a/modules/view/backends/gtk3/menu.reds b/modules/view/backends/gtk3/menu.reds new file mode 100644 index 0000000000..bb61659877 --- /dev/null +++ b/modules/view/backends/gtk3/menu.reds @@ -0,0 +1,165 @@ +Red/System [ + Title: "GTK Menu widget" + Author: "RCqls, Nenad Rakocevic, Qingtian Xie" + File: %menu.reds + Tabs: 4 + Rights: "Copyright (C) 2016-2018 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +menu-x: 0 +menu-y: 0 + +menu-item-key: func [ + item [handle!] + key [integer!] +][ + g_object_set_qdata item menu-id as int-ptr! key +] + +menu-item-key?: func [ + item [handle!] + return: [integer!] +][ + as integer! g_object_get_qdata item menu-id +] + +build-menu: func [ + menu [red-block!] + hMenu [handle!] + target [handle!] + return: [handle!] + /local + item [handle!] + sub-menu [handle!] + value [red-value!] + tail [red-value!] + next [red-value!] + str [red-string!] + w [red-word!] + len [integer!] + title [c-string!] + key [c-string!] + action [integer!] +][ + if TYPE_OF(menu) <> TYPE_BLOCK [return null] + + ;; DEBUG: print ["Menu: " hMenu " with target: " target lf] + value: block/rs-head menu + tail: block/rs-tail menu + + key: "" + ;action: red-menu-action: + while [value < tail][ + switch TYPE_OF(value) [ + TYPE_STRING [ + str: as red-string! value + next: value + 1 + + len: -1 + title: unicode/to-utf8 str :len + + item: gtk_menu_item_new_with_label title + gtk_widget_show item + + if next < tail [ + switch TYPE_OF(next) [ + TYPE_BLOCK [ + ;; DEBUG: print ["add sub-menu" lf] + sub-menu: gtk_menu_new + gtk_widget_show sub-menu + build-menu as red-block! next sub-menu target + gtk_menu_item_set_submenu item sub-menu + value: value + 1 + ] + TYPE_WORD [ + w: as red-word! next + menu-item-key item w/symbol + ;; DEBUG: print ["item " item " connected to " target " with key " w/symbol lf] + gobj_signal_connect(item "activate" :menu-item-activate target) + value: value + 1 + ] + default [0] + ] + ] + ] + TYPE_WORD [ + w: as red-word! value + if w/symbol = --- [ + item: gtk_separator_menu_item_new + ] + ] + default [0] + ] + gtk_menu_shell_append hMenu item + value: value + 1 + ] + hMenu +] + +context-menu: func [ + widget [handle!] + hMenu [handle!] +][ + ;; DEBUG: print ["context menu " hMenu " added to " widget lf] + g_object_set_qdata widget menu-id hMenu +] + +context-menu?: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget menu-id +] + +build-context-menu: func [ + widget [handle!] + menu [red-block!] + /local + hMenu [handle!] +][ + ;; DEBUG: print ["build menu for " widget lf] + if TYPE_OF(menu) = TYPE_BLOCK [ + hMenu: gtk_menu_new + ;; DEBUG: print ["hMenu " hMenu lf] + build-menu menu hMenu widget + context-menu widget hMenu + ] +] + +append-context-menu: func [ + menu [red-block!] + hMenu [handle!] + widget [handle!] + /local + item [handle!] +][ + item: gtk_separator_menu_item_new + gtk_widget_show item + gtk_menu_shell_append hMenu item + build-menu menu hMenu widget +] + +menu-bar?: func [ + spec [red-block!] + type [integer!] + return: [logic!] + /local + w [red-word!] +][ + if all [ + TYPE_OF(spec) = TYPE_BLOCK + not block/rs-tail? spec + type = window + ][ + w: as red-word! block/rs-head spec + return not all [ + TYPE_OF(w) = TYPE_WORD + popup = symbol/resolve w/symbol + ] + ] + no +] \ No newline at end of file diff --git a/modules/view/backends/gtk3/para.reds b/modules/view/backends/gtk3/para.reds index 997a90be93..50c419f4fe 100644 --- a/modules/view/backends/gtk3/para.reds +++ b/modules/view/backends/gtk3/para.reds @@ -1,6 +1,6 @@ Red/System [ Title: "GTK3 para object management" - Author: "Qingtian Xie" + Author: "Qingtian Xie, RCqls" File: %para.reds Tabs: 4 Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." @@ -10,6 +10,66 @@ Red/System [ } ] +change-para: func [ + widget [handle!] + face [red-object!] + para [red-object!] + font [red-object!] + type [integer!] + return: [logic!] + /local + flags [integer!] + where [integer!] + lay [handle!] +][ + + if TYPE_OF(para) <> TYPE_OBJECT [return no] + flags: get-para-flags type para + ;; DEBUG: if flags <> 0 [print ["change-para " widget " " get-symbol-name type " flags: " flags lf]] + case [ + any [type = base type = panel][ + ;; nothing to do since done in render-text called by base-draw handler + ] + any [ + ; type = button + ; type = check + ; type = radio + ; type = field + type = text + ][ + if TYPE_OF(font) = TYPE_OBJECT [ + change-font widget face font type + ] + gtk_widget_set_halign widget (flags and FFFFh) + 1 + gtk_label_set_justify widget (flags and FFFFh) + gtk_label_set_line_wrap widget (flags and FFFF0000h <> 0) + ] + type = area [ + if TYPE_OF(font) = TYPE_OBJECT [ + change-font widget face font type + ] + gtk_text_view_set_justification widget (flags and FFFFh) + gtk_text_view_set_wrap_mode widget either (flags and FFFF0000h <> 0) [GTK_WRAP_WORD][GTK_WRAP_NONE] + ] + type = field [ + lay: gtk_entry_get_layout widget + pango_layout_set_alignment lay case [ + (flags and 0001h <> 0) [PANGO_ALIGN_RIGHT] + (flags and 0002h <> 0) [PANGO_ALIGN_CENTER] + true [PANGO_ALIGN_LEFT] + ] + pango_layout_set_wrap lay PANGO_WRAP_WORD + ] + true [0] + ] + if any [type = field type = text][ + ;;cell: objc_msgSend [hWnd sel_getUid "cell"] + ;;objc_msgSend [cell sel_getUid "setWraps:" flags and 20h <> 0] + 0 + ] + yes +] + update-para: func [ face [red-object!] flags [integer!] @@ -22,33 +82,36 @@ update-para: func [ hWnd [handle!] sym [integer!] style [integer!] - mask [integer!] + ;; COMMENTED SINCE UNUSED! + ;; mask [integer!] ][ values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - para: as red-object! values + FACE_OBJ_PARA + ;; COMMENTED SINCE UNUSED! + ; sym: symbol/resolve type/symbol + ; para: as red-object! values + FACE_OBJ_PARA unless TYPE_OF(type) = TYPE_WORD [exit] ;@@ make it an error message - case [ - sym = base [mask: not 002Fh] - any [ - sym = button - sym = check - sym = radio - ][ - mask: not 00000F00h - ] - any [ - sym = field - sym = area - sym = text - ][ - mask: not 00004003h - ] - true [0] - ] + ;; COMMENTED SINCE UNUSED! + ; case [ + ; sym = base [mask: not 002Fh] + ; any [ + ; sym = button + ; sym = check + ; sym = radio + ; ][ + ; mask: not 00000F00h + ; ] + ; any [ + ; sym = field + ; sym = area + ; sym = text + ; ][ + ; mask: not 00004003h + ; ] + ; true [0] + ; ] state: as red-block! values + FACE_OBJ_STATE if TYPE_OF(state) = TYPE_BLOCK [ @@ -75,7 +138,8 @@ get-para-flags: func [ top [integer!] middle [integer!] bottom [integer!] - default [integer!] + h-def [integer!] + v-def [integer!] h-sym [integer!] v-sym [integer!] ][ @@ -88,29 +152,28 @@ get-para-flags: func [ wrap?: any [ TYPE_OF(bool) = TYPE_NONE - all [TYPE_OF(bool) = TYPE_LOGIC not bool/value] + all [TYPE_OF(bool) = TYPE_LOGIC bool/value] ] - left: 0 - center: 0 - right: 0 - top: 0 - middle: 0 - bottom: 0 - default: 0 + left: 0 center: 0 right: 0 h-def: 0 + top: 0 middle: 0 bottom: 0 v-def: 0 + flags: 0 case [ - type = base [ + any [ + type = base + type = rich-text + ][ left: 0000h ;-- DT_LEFT center: 0001h ;-- DT_CENTER right: 0002h ;-- DT_RIGHT top: 0000h ;-- DT_TOP middle: 0004h ;-- DT_VCENTER bottom: 0008h ;-- DT_BOTTOM - default: center + h-def: center v-def: top - unless wrap? [flags: 00000020h] ;-- DT_SINGLELINE + unless wrap? [flags: 0010h] ;-- DT_SINGLELINE ] any [ type = button @@ -124,7 +187,7 @@ get-para-flags: func [ middle: 00000C00h ;-- BS_VCENTER bottom: 00000800h ;-- BS_BOTTOM - default: either type = button [center][left] + h-def: either type = button [center][left] ] any [ type = field @@ -132,12 +195,13 @@ get-para-flags: func [ type = text ][ left: 0000h ;-- ES_LEFT / SS_LEFT - center: 0001h ;-- ES_CENTER / SS_CENTER - right: 0002h ;-- ES_RIGHT / SS_RIGHT - default: left + right: 0001h ;-- ES_RIGHT / SS_RIGHT + center: 0002h ;-- ES_CENTER / SS_CENTER + + h-def: left - if all [not wrap? type = text][ - flags: 00004000h ;-- SS_ENDELLIPSIS + if all [wrap? type = text][ + flags: 00010000h ;-- SS_ENDELLIPSIS ] ] true [0] @@ -146,13 +210,13 @@ get-para-flags: func [ h-sym = _para/left [flags: flags or left] h-sym = _para/center [flags: flags or center] h-sym = _para/right [flags: flags or right] - true [flags: flags or default] + true [flags: flags or h-def] ] case [ v-sym = _para/top [flags: flags or top] v-sym = _para/middle [flags: flags or middle] v-sym = _para/bottom [flags: flags or bottom] - true [0] + true [flags: flags or v-def] ] flags ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 5bb5ea2d14..0bec5386c5 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -1,6 +1,6 @@ Red/System [ Title: "Text Box Windows DirectWrite Backend" - Author: "Xie Qingtian" + Author: "Xie Qingtian, RCqls" File: %text-box.reds Tabs: 4 Dependency: %draw-d2d.reds @@ -14,28 +14,335 @@ Red/System [ #define TBOX_METRICS_OFFSET? 0 #define TBOX_METRICS_INDEX? 1 #define TBOX_METRICS_LINE_HEIGHT 2 -#define TBOX_METRICS_METRICS 3 +#define TBOX_METRICS_SIZE 3 +#define TBOX_METRICS_LINE_COUNT 4 +#define TBOX_METRICS_CHAR_INDEX? 5 +#define TBOX_METRICS_OFFSET_LOWER 6 + +#define PANGO_TEXT_MARKUP_SIZED 500 max-line-cnt: 0 +pango-opt-tag!: alias struct! [ + opt [c-string!] + pos [integer!] + len [integer!] +] + +pango-compare-tag: func [ + [cdecl] + tag1 [pango-opt-tag!] + tag2 [pango-opt-tag!] + return: [integer!] + /local + comp [integer!] +][ + ;; DEBUG: print ["pango-compare-tag: (" tag1/pos "," tag1/len "," tag1/opt ") and (" tag2/pos "," tag2/len "," tag2/opt ") -> " ] + either tag1/pos = tag2/pos [ + either tag1/len = tag2/len [comp: 0][ + comp: either tag1/len > tag2/len [-1][1] + ] + ][ + comp: either tag1/pos > tag2/pos [1][-1] + ] + comp +] + +make-pango-opt-tag: func [ + opt [c-string!] + pos [integer!] + len [integer!] + return: [handle!] + /local + tag [pango-opt-tag!] +][ + tag: as pango-opt-tag! allocate size? pango-opt-tag! + tag/opt: opt tag/pos: pos tag/len: len + as handle! tag +] + +pango-insert-tag: func [ + lc [layout-ctx!] + opt [c-string!] + pos [integer!] + len [integer!] + /local + tag [handle!] + tag2 [handle!] +][ + if pos + len > lc/text-len [len: lc/text-len - pos] + tag: make-pango-opt-tag opt pos len + ;; DEBUG: print ["insert tag: " tag lf ]; " at (" tag/pos "," tag/len ")" lf ] + lc/tag-list: g_list_insert_sorted lc/tag-list tag as-integer :pango-compare-tag +] + +layout-ctx-begin: func [ + lc [layout-ctx!] + text [c-string!] + text-len [integer!] + /local + ot [c-string!] +][ + lc/closed-tags: null + lc/text: text + lc/text-len: text-len + lc/text-pos: 0 + lc/text-markup: as handle! g_string_sized_new PANGO_TEXT_MARKUP_SIZED + g_string_assign as GString! lc/text-markup "" + lc/tag-list: null + + ot: pango-open-tag-string? lc "face" gtk-font + pango-insert-tag lc ot 0 text-len +] + +pango-add-open-tag: func [ + lc [layout-ctx!] + open-tag [c-string!] + pos [integer!] + /local + gstr [GString!] +][ + gstr: as GString! lc/text-markup + if lc/text-pos < pos [ ; add text until pos + g_string_append_len gstr lc/text + lc/text-pos pos - lc/text-pos + lc/text-pos: pos + ] + g_string_append gstr "" + g_free as handle! open-tag +] + +pango-open-tag-string?: func [ + lc [layout-ctx!] + attr-key [c-string!] + attr-val [c-string!] + return: [c-string!] + /local + str [c-string!] +][ + str: "" + str: g_strdup_printf ["%s='%s'" attr-key attr-val] + str +] + +pango-open-tag-int?: func [ + lc [layout-ctx!] + attr-key [c-string!] + attr-val [integer!] + return: [c-string!] + /local + str [c-string!] +][ + str: "" + str: g_strdup_printf ["%s='%d'" attr-key attr-val] + str +] + +pango-open-tag-float?: func [ + lc [layout-ctx!] + attr-key [c-string!] + attr-val [float!] + return: [c-string!] + /local + str [c-string!] +][ + str: "" + str: g_strdup_printf ["%s='%f'" attr-key attr-val] + str +] + +pango-add-closed-tag: func [ + lc [layout-ctx!] + level [integer!] +][ + ;; DEBUG: print ["add-closed-tag: " level lf] + lc/closed-tags: g_list_prepend lc/closed-tags as int-ptr! (level + 1) +] + +pango-last-closed-tag?: func [ ; last in time not in the GList + lc [layout-ctx!] + return: [integer!] + /local + current [int-ptr!] +][ + current: g_list_nth_data lc/closed-tags 0 + either null? current [-1][(as integer! current) - 1] +] + +pango-next-closed-tag: func [ + lc [layout-ctx!] + /local + first [handle!] +][ + first: g_list_first lc/closed-tags + lc/closed-tags: g_list_delete_link lc/closed-tags first +] + +pango-close-tags: func [ + lc [layout-ctx!] + pos-last-closed-tag [integer!] + /local + text-len [integer!] + gstr [GString!] + last? [logic!] +][ + ;; DEBUG: print ["pango-close-tags: " lc " text-markup: " lc/text-markup lf] + last?: no + gstr: as GString! lc/text-markup + if pos-last-closed-tag = -1 [ + last?: yes + ;; DEBUG: print ["pos-last-closed-tag = -1" lf] + pos-last-closed-tag: pango-last-closed-tag? lc + ] + text-len: either pos-last-closed-tag > lc/text-len [lc/text-len][pos-last-closed-tag] + text-len: text-len - lc/text-pos + ;; DEBUG: print ["pango-close-tags -> append: (" text-len ")" lc/text + lc/text-pos lf] + if text-len > 0 [ + g_string_append_len gstr lc/text + lc/text-pos text-len + lc/text-pos: lc/text-pos + text-len + ] + if 0 < g_list_length lc/closed-tags [ + ; Add closed tags + ;; DEBUG: print ["close-tags: " pos-last-closed-tag " " pango-last-closed-tag? lc lf] + while [ pos-last-closed-tag = pango-last-closed-tag? lc ][ + ;; DEBUG: print ["close-tags: " lf] + g_string_append gstr "" + ;; DEBUG: print ["text-markup after close-tag: " gstr/str lf] + pango-next-closed-tag lc + + ] + ] + ;; DEBUG: print ["size? lc/closed-tags: " g_list_length lc/closed-tags lf] + if all[ last? 0 < g_list_length lc/closed-tags] [pango-close-tags lc -1] +] + +pango-process-closed-tags: func [ + lc [layout-ctx!] + pos [integer!] + len [integer!] + /local + text [c-string!] + tmp [c-string!] + pos-current-closed-tag [integer!] + pos-last-closed-tag [integer!] +][ + pos-last-closed-tag: pango-last-closed-tag? lc + pos-current-closed-tag: pos + len + ;; DEBUG: print ["process closed tags: current=" pos-current-closed-tag " last=" pos-last-closed-tag lf] + ; Close tags with text first if any + if all[ + pos-last-closed-tag <> -1 + pos-current-closed-tag > pos-last-closed-tag + ][ + pango-close-tags lc pos-last-closed-tag + ] +] + +pango-process-tag: func [ + lc [layout-ctx!] + open-tag [c-string!] + pos [integer!] + len [integer!] +][ + pango-process-closed-tags lc pos len + pango-add-open-tag lc open-tag pos + pango-add-closed-tag lc pos + len +] + +pango-markup-text: func [ + lc [layout-ctx!] + /local + gl [GList!] + last [GList!] + tag [pango-opt-tag!] + len [integer!] + pos [integer!] + opt [c-string!] + text [GString!] +][ + unless null? lc/tag-list [ + last: as GList! g_list_last lc/tag-list + gl: as GList! g_list_first lc/tag-list + + lc/text-pos: 0 lc/closed-tags: null + g_string_assign as GString! lc/text-markup "" + until [ + tag: as pango-opt-tag! gl/data + ;; DEBUG: print [" at (" tag/pos "," tag/len ")" lf] + pango-process-tag lc tag/opt tag/pos tag/len + + gl: gl/next + null? gl + ] + pango-close-tags lc -1 + ;; DEBUG: print ["Add " lf] + text: as GString! lc/text-markup + g_string_append text "" + ;; DEBUG: print ["tex-markup: " text/str lf] + ] +] + +layout-ctx-end: func [ + lc [layout-ctx!] + /local + text [GString!] +][ + ; TODO: free everything not anymore used + pango-markup-text lc +] + +int-to-rgba: func [ + color [integer!] + r [int-ptr!] + b [int-ptr!] + g [int-ptr!] + a [int-ptr!] +][ + ;; TODO: + r/value: (color >> 24 and FFh) << 8 + g/value: (color >> 16 and FFh) << 8 + b/value: (color >> 8 and FFh) << 8 + a/value: (color and FFh) << 8 + ;; DEBUG: print ["color: " color " " r/value "." g/value "." b/value "." a/value lf ] +] + +int-to-bgra-hex: func [ + color [integer!] + return: [c-string!] + /local + r [integer!] + b [integer!] + g [integer!] + a [integer!] +][ + a: (color >> 24 and FFh) + r: (color >> 16 and FFh) + g: (color >> 8 and FFh) + b: (color and FFh) + color: (b << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( r << 8 and FF00h) or ( a and FFh) + ;; DEBUG: print ["col(#" string/to-hex color no ")" lf] + g_strdup_printf ["#%s" string/to-hex color no] +] + OS-text-box-color: func [ dc [handle!] layout [handle!] pos [integer!] len [integer!] color [integer!] + /local + lc [layout-ctx!] + rgba [c-string!] + ot [c-string!] ][ - ;brush: select-brush dc + 1 color - ;if zero? brush [ - ; this: as this! dc/value - ; rt: as ID2D1HwndRenderTarget this/vtbl - ; rt/CreateSolidColorBrush this to-dx-color color null null :brush - ; put-brush dc + 1 color brush - ;] + lc: as layout-ctx! layout - ;this: as this! layout - ;dl: as IDWriteTextLayout this/vtbl - ;dl/SetDrawingEffect this as this! brush pos len + rgba: int-to-bgra-hex color + ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] + + ot: pango-open-tag-string? lc "color" rgba + pango-insert-tag lc ot pos len ] OS-text-box-background: func [ @@ -45,38 +352,50 @@ OS-text-box-background: func [ len [integer!] color [integer!] /local - cache [red-vector!] - brush [integer!] -][ - ;cache: as red-vector! dc + 3 - ;if TYPE_OF(cache) <> TYPE_VECTOR [ - ; vector/make-at as red-value! cache 128 TYPE_INTEGER 4 - ;] - ;brush: select-brush dc + 1 color - ;if zero? brush [ - ; this: as this! dc/value - ; rt: as ID2D1HwndRenderTarget this/vtbl - ; rt/CreateSolidColorBrush this to-dx-color color null null :brush - ; put-brush dc + 1 color brush - ;] - ;vector/rs-append-int cache pos - ;vector/rs-append-int cache len - ;vector/rs-append-int cache brush + lc [layout-ctx!] + rgba [c-string!] + ot [c-string!] +][ + lc: as layout-ctx! layout + + rgba: int-to-bgra-hex color + ;; DEBUG: print ["bgcol(" rgba ")[" pos "," pos + len - 1 "]" lf] + + ot: pango-open-tag-string? lc "bgcolor" rgba + pango-insert-tag lc ot pos len + ] + + OS-text-box-weight: func [ layout [handle!] pos [integer!] len [integer!] weight [integer!] + /local + lc [layout-ctx!] + ot [c-string!] ][ + lc: as layout-ctx! layout + + ot: pango-open-tag-int? lc "weight" weight pos len + pango-insert-tag lc ot pos len + ] OS-text-box-italic: func [ layout [handle!] pos [integer!] len [integer!] + /local + lc [layout-ctx!] + ot [c-string!] ][ + lc: as layout-ctx! layout + + ot: pango-open-tag-string? lc "style" "italic" + pango-insert-tag lc ot pos len ] OS-text-box-underline: func [ @@ -85,15 +404,29 @@ OS-text-box-underline: func [ len [integer!] opts [red-value!] ;-- options tail [red-value!] + /local + lc [layout-ctx!] + ot [c-string!] ][ + lc: as layout-ctx! layout + + ot: pango-open-tag-string? lc "underline" "single" + pango-insert-tag lc ot pos len ] OS-text-box-strikeout: func [ layout [handle!] pos [integer!] len [integer!] - opts [red-value!] ;-- options + opts [red-value!] + /local + lc [layout-ctx!] + ot [c-string!] ][ + lc: as layout-ctx! layout + + ot: pango-open-tag-string? lc "strikethrough" "true" + pango-insert-tag lc ot pos len ] OS-text-box-border: func [ @@ -102,21 +435,30 @@ OS-text-box-border: func [ len [integer!] opts [red-value!] ;-- options tail [red-value!] + /local + lc [layout-ctx!] ][ - 0 + lc: as layout-ctx! layout ] OS-text-box-font-name: func [ - nsfont [handle!] + dc [handle!] layout [handle!] pos [integer!] len [integer!] name [red-string!] + /local + lc [layout-ctx!] + strlen [integer!] + str [c-string!] + ot [c-string!] ][ - ;n: -1 - ;this: as this! layout - ;dl: as IDWriteTextLayout this/vtbl - ;dl/SetFontFamilyName this unicode/to-utf16-len name :n yes pos len + lc: as layout-ctx! layout + strlen: -1 + str: unicode/to-utf8 name :strlen + + ot: pango-open-tag-string? lc "face" str + pango-insert-tag lc ot pos len ] OS-text-box-font-size: func [ @@ -125,7 +467,14 @@ OS-text-box-font-size: func [ pos [integer!] len [integer!] size [float!] + /local + lc [layout-ctx!] + ot [c-string!] ][ + lc: as layout-ctx! layout + + ot: pango-open-tag-int? lc "font" as integer! size + pango-insert-tag lc ot pos len ] OS-text-box-metrics: func [ @@ -133,51 +482,72 @@ OS-text-box-metrics: func [ arg0 [red-value!] type [integer!] return: [red-value!] + /local + int [red-integer!] + rstate [red-integer!] + layout [handle!] + x [float!] + y [float!] + width [integer!] + height [integer!] + pos [red-pair!] + rect [tagRECT value] + lrect [tagRECT value] + pline [handle!] + idx [integer!] + trail [integer!] + ok? [logic!] ][ - as red-value! none-value - ;as red-value! switch type [ - ; TBOX_METRICS_OFFSET? [ - ; x: as float32! 0.0 y: as float32! 0.0 - ; ;int: as red-integer! arg0 - ; ] - ; TBOX_METRICS_INDEX? [ - ; pos: as red-pair! arg0 - ; x: as float32! pos/x - ; y: as float32! pos/y - ; ] - ; TBOX_METRICS_LINE_HEIGHT [ - ; lineCount: 0 - ; dl/GetLineMetrics this null 0 :lineCount - ; if lineCount > max-line-cnt [ - ; max-line-cnt: lineCount + 1 - ; line-metrics: as DWRITE_LINE_METRICS realloc - ; as byte-ptr! line-metrics - ; lineCount + 1 * size? DWRITE_HIT_TEST_METRICS - ; ] - ; lineCount: 0 - ; dl/GetLineMetrics this line-metrics max-line-cnt :lineCount - ; lm: line-metrics - ; hr: as-integer arg0 - ; while [ - ; hr: hr - lm/length - ; lineCount: lineCount - 1 - ; all [hr > 0 lineCount > 0] - ; ][ - ; lm: lm + 1 - ; ] - ; integer/push as-integer lm/height - ; ] - ; default [ - ; metrics: as DWRITE_TEXT_METRICS :left - ; hr: dl/GetMetrics this metrics - ; #if debug? = yes [if hr <> 0 [log-error hr]] - - ; values: object/get-values as red-object! arg0 - ; integer/make-at values + TBOX_OBJ_WIDTH as-integer metrics/width - ; integer/make-at values + TBOX_OBJ_HEIGHT as-integer metrics/height - ; integer/make-at values + TBOX_OBJ_LINE_COUNT metrics/lineCount - ; ] - ;] + ;; DEBUG: print ["OS-text-box-metrics: " type lf] + rstate: as red-integer! block/rs-head state + layout: as handle! rstate/value + if null? layout [return as red-value! none-value] + as red-value! switch type [ + TBOX_METRICS_OFFSET? + TBOX_METRICS_OFFSET_LOWER [ ; caret-to-offset + int: as red-integer! arg0 + pango_layout_index_to_pos layout int/value :rect + ;; DEBUG: print ["TBOX_METRICS_OFFSET? " rect/x "x" rect/y "x" rect/width "x" rect/height lf] + pair/push rect/x rect/y + ] + TBOX_METRICS_INDEX? + TBOX_METRICS_CHAR_INDEX? [ ; offset-to-caret + pos: as red-pair! arg0 + idx: -1 trail: -1 + ;; DEBUG: print ["TBOX_METRICS_INDEX? pos: " pos/x "x" pos/y lf] + ok?: pango_layout_xy_to_index layout (pos/x * PANGO_SCALE) (pos/y * PANGO_SCALE) :idx :trail + ;; DEBUG: print ["TBOX_METRICS_INDEX? " pos/x "x" pos/y " " ok? " index: " idx + 1 lf] + if all[type = TBOX_METRICS_INDEX? 0 <> trail] [idx: idx + 1] + integer/push idx + 1 + ] + TBOX_METRICS_SIZE [ + pline: pango_layout_get_line layout 0 + pango_layout_line_get_pixel_extents pline rect lrect + width: -1 height: -1 + ;pango_layout_get_pixel_size layout :width :height + ; width: (pango_layout_get_width layout) / PANGO_SCALE + height: (pango_layout_get_line_count layout) * lrect/height + width: lrect/width + ;; DEBUG: print ["TBOX_METRICS_SIZE: " width "x" height " " pango_layout_get_line_count layout lf] + ;print ["text: " layout/text lf] + pair/push width height + ] + TBOX_METRICS_LINE_COUNT [ + idx: pango_layout_get_line_count layout + ;; DEBUG: print ["TBOX_METRICS_LINE_COUNT: " idx lf] + integer/push idx + ] + TBOX_METRICS_LINE_HEIGHT [ + int: as red-integer! arg0 + pango_layout_index_to_pos layout int/value :rect + height: rect/height / PANGO_SCALE + ;; DEBUG: print ["TBOX_METRICS_LINE_HEIGHT " height " (" rect/x "x" rect/y "x" rect/width "x" rect/height ")" lf] + integer/push height + ] + default [ + none-value + ] + ] ] OS-text-box-layout: func [ @@ -185,49 +555,114 @@ OS-text-box-layout: func [ target [int-ptr!] ft-clr [integer!] catch? [logic!] - return: [integer!] -][ - ;values: object/get-values box - ;if null? target [ - ; hWnd: get-face-handle as red-object! values + TBOX_OBJ_TARGET - ; target: get-hwnd-render-target hWnd - ;] - - ;state: as red-block! values + TBOX_OBJ_STATE - ;either TYPE_OF(state) = TYPE_BLOCK [ - ; int: as red-integer! block/rs-head state ;-- release previous text layout - ; layout: as this! int/value - ; COM_SAFE_RELEASE(IUnk layout) - ; int: int + 1 - ; fmt: as this! int/value - ;][ - ; fixed?: as red-logic! values + TBOX_OBJ_FIXED? - ; fmt: as this! create-text-format as red-object! values + TBOX_OBJ_FONT - ; if fixed?/value [set-line-spacing fmt] - ; block/make-at state 2 - ; none/make-in state ;-- 1: text layout - ; integer/make-in state as-integer fmt ;-- 2: text format - ;] - - ;set-text-format fmt as red-object! values + TBOX_OBJ_PARA - - ;str: as red-string! values + TBOX_OBJ_TEXT - ;size: as red-pair! values + TBOX_OBJ_SIZE - ;either TYPE_OF(size) = TYPE_PAIR [ - ; w: size/x h: size/y - ;][ - ; w: 0 h: 0 - ;] - ;layout: create-text-layout str fmt w h - ;integer/make-at block/rs-head state as-integer layout - - ;styles: as red-block! values + TBOX_OBJ_STYLES - ;if all [ - ; TYPE_OF(styles) = TYPE_BLOCK - ; 2 < block/rs-length? styles - ;][ - ; parse-text-styles target as handle! layout styles catch? - ;] - ;layout - 0 -] \ No newline at end of file + return: [handle!] + /local + hWnd [handle!] + values [red-value!] + size [red-pair!] + rstate [red-integer!] + bool [red-logic!] + state [red-block!] + styles [red-block!] + pval [red-value!] + vec [red-vector!] + obj [red-object!] + w [integer!] + h [integer!] + dc [draw-ctx!] + lc [layout-ctx!] + cached? [logic!] + force? [logic!] + + font [handle!] + clr [integer!] + text [red-string!] + len [integer!] + str [c-string!] + pc [handle!] +][ + ;; DEBUG: print ["OS-text-box-layout: " box " target: " target lf] + values: object/get-values box + state: as red-block! values + FACE_OBJ_EXT3 + cached?: TYPE_OF(state) = TYPE_BLOCK + ;; DEBUG: print ["cached?: " cached? " state: " state lf] + force?: either cached? [ + rstate: as red-integer! block/rs-head state + bool: as red-logic! rstate + 1 + ;; DEBUG: print ["rstate: " rstate " -> " rstate/value " bool: " bool " -> " bool/value lf] + bool/value + ][true] + ;; DEBUG: print ["force?: " force? lf] + + lc: declare layout-ctx! ; this is not dynamic but lc/layout would change dynamically for each rich-text + text: as red-string! values + FACE_OBJ_TEXT + len: -1 + str: unicode/to-utf8 text :len + layout-ctx-begin lc str len + + size: as red-pair! values + FACE_OBJ_SIZE + + either force? [ + ;; create lc/layout + ;; DEBUG: print ["create layout: " target lf] + either null? target [ + either cached? [lc/layout: as handle! rstate/value] + [ + ; this is when OS-text-box-metrics is used before drawing + if null? pango-context [pango-context: gdk_pango_context_get] + lc/layout: pango_layout_new pango-context + ;; DEBUG: print ["rich-text layout: " lc/layout lf] + pango_layout_set_font_description lc/layout pango_font_description_from_string gtk-font ; needs to get the rich-text font + ] + ][ + dc: as draw-ctx! target + lc/layout: make-pango-cairo-layout dc/raw dc/font-desc + ;; DEBUG: print ["rich-text layout with target: " lc/layout lf] + ] + ;; DEBUG: print ["with target: " target " lc/layout: " lc/layout lf] + either cached? [ + rstate/value: as integer! lc/layout + bool/value: false + ;; DEBUG: print ["lc/layout force to be updated: " lc/layout " bool: " bool/value lf] + ][ + block/make-at state 3 ;maybe more later + ;; DEBUG: print ["lc/layout newly created: " lc/layout lf] + integer/make-in state as integer! lc/layout ; handle for lc/layout + logic/make-in state either null? target [true][false] ; force build lc/layout + logic/make-in state true ; possible use for redraw used in gui.red/update-richtext + ] + ][ + lc/layout: as handle! rstate/value + ;; DEBUG: print ["lc/layout cached: " lc/layout lf] + ] + + styles: as red-block! values + FACE_OBJ_DATA + either all [ + TYPE_OF(styles) = TYPE_BLOCK + 1 < block/rs-length? styles + ][ + parse-text-styles target as handle! lc styles 7FFFFFFFh catch? + ][ + g_string_assign as GString! lc/text-markup lc/text + ] + layout-ctx-end lc + if null? target [pango-layout-set-text lc size] + as handle! lc +] + +pango-layout-set-text: func [ + lc [layout-ctx!] + size [red-pair!] + /local + gstr [GString!] +][ + gstr: as GString! lc/text-markup + pango_layout_set_markup lc/layout gstr/str -1 + pango_layout_set_width lc/layout PANGO_SCALE * size/x + pango_layout_set_height lc/layout PANGO_SCALE * size/y + pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR +] + +; pango-layout-styled-set-text: func [ + +; ] diff --git a/runtime/collector.reds b/runtime/collector.reds index 3b3ecf84be..53fa5fbabe 100644 --- a/runtime/collector.reds +++ b/runtime/collector.reds @@ -243,7 +243,7 @@ collector: context [ mark-block-node as node! native/code ] ] - #if OS = 'macOS [ + #if any[OS = 'macOS OS = 'Linux][ TYPE_IMAGE [ image: as red-image! value keep image/node diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 3a379a7c8f..16932e5a40 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -88,7 +88,24 @@ Red/System [ pen? [logic!] brush? [logic!] pattern [int-ptr!] - on-image? [logic!] ;-- drawing on image? + on-image? [logic!] + shape-curve? [logic!] + ; pango-cairo + font-desc [handle!] + font-opts [handle!] + font-underline? [logic!] + font-strike? [logic!] + layout [handle!] ; Only for draw not for rich-text + ] + + layout-ctx!: alias struct! [ + layout [handle!] ; Only for rich-text + text [c-string!] + text-len [integer!] + text-pos [integer!] + text-markup [handle!] + closed-tags [handle!] + tag-list [handle!] ] ] diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 1626ac6c23..02cc76c440 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -13,6 +13,96 @@ Red/System [ #define IMG_NODE_HAS_BUFFER 1 #define IMG_NODE_MODIFIED 2 +#enum GdkColorspace! [ + GDK_COLORSPACE_RGB +] + +; bgra-to-rgba: func [ +; color [integer!] +; return: [integer!] +; /local +; r [integer!] +; b [integer!] +; g [integer!] +; a [integer!] +; ][ +; b: (color >>> 24 and FFh) +; g: (color >> 16 and FFh) +; r: (color >> 8 and FFh) +; a: (color and FFh) +; ;color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) +; color: (r << 24) or (g << 16) or (b << 8) or a +; color +; ] + +; bgra-to-argb: func [ +; color [integer!] +; return: [integer!] +; /local +; r [integer!] +; b [integer!] +; g [integer!] +; a [integer!] +; ][ +; b: (color >>> 24 and FFh) +; g: (color >> 16 and FFh) +; r: (color >> 8 and FFh) +; a: (color and FFh) +; ;color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) +; color: (a << 24) or (r << 16) or (g << 8) or b +; color +; ] + +; argb-to-rgba: func [ +; color [integer!] +; return: [integer!] +; /local +; r [integer!] +; b [integer!] +; g [integer!] +; a [integer!] +; ][ +; a: (color >>> 24 and FFh) +; r: (color >> 16 and FFh) +; g: (color >> 8 and FFh) +; b: (color and FFh) +; color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) +; color +; ] + +argb-to-abgr: func [ + color [integer!] + return: [integer!] + /local + r [integer!] + b [integer!] + g [integer!] + a [integer!] +][ + a: (color >>> 24 and FFh) + r: (color >> 16 and FFh) + g: (color >> 8 and FFh) + b: (color and FFh) + color: (a << 24 and FF000000h) or (b << 16 and 00FF0000h) or ( g << 8 and FF00h) or ( r and FFh) + color +] + +rgba-to-argb: func [ + color [integer!] + return: [integer!] + /local + r [integer!] + b [integer!] + g [integer!] + a [integer!] +][ + r: (color >>> 24 and FFh) + g: (color >> 16 and FFh) + b: (color >> 8 and FFh) + a: (color and FFh) + color: (a << 24) or (r << 16) or (g << 8) or b + color +] OS-image: context [ @@ -39,6 +129,14 @@ OS-image: context [ height [integer!] return: [handle!] ] + gdk_pixbuf_new_subpixbuf: "gdk_pixbuf_new_subpixbuf" [ + pixbuf [handle!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + return: [handle!] + ] gdk_pixbuf_new_from_bytes: "gdk_pixbuf_new_from_bytes" [ data [handle!] colorsp [integer!] @@ -74,6 +172,10 @@ OS-image: context [ pixbuf [handle!] return: [byte-ptr!] ] + gdk_pixbuf_read_pixels: "gdk_pixbuf_read_pixels" [ + pixbuf [handle!] + return: [byte-ptr!] + ] gdk_pixbuf_get_rowstride: "gdk_pixbuf_get_rowstride" [ pixbuf [handle!] return: [integer!] @@ -82,6 +184,10 @@ OS-image: context [ pixbuf [handle!] return: [integer!] ] + gdk_pixbuf_get_bits_per_sample: "gdk_pixbuf_get_bits_per_sample" [ + pixbuf [handle!] + return: [integer!] + ] gdk_pixbuf_get_has_alpha: "gdk_pixbuf_get_has_alpha" [ pixbuf [handle!] return: [logic!] @@ -131,37 +237,64 @@ OS-image: context [ IMAGE_HEIGHT(inode/size) ] - lock-bitmap: func [ ;-- do nothing on Quartz backend + #enum post-transf! [POST-TRANSF-NONE POST-ARGB-TO-ABGR POST-ARGB-TO-RGBA] + + post-transf?: POST-TRANSF-NONE + + post-transf: func [ mode [post-transf!]][post-transf?: mode] + + lock-bitmap: func [ img [red-image!] write? [logic!] return: [integer!] /local inode [img-node!] ][ + ;; DEBUG: print ["lock-bitmap " img lf] inode: as img-node! (as series! img/node/value) + 1 + ;; DEBUG: print ["flags: " inode/flags lf] if zero? inode/flags [ + ;; DEBUG: print ["lock-bitmap: flags" lf] inode/flags: IMG_NODE_HAS_BUFFER inode/buffer: OS-image/data-to-image inode/handle -1 yes yes + ;; DEBUG: print ["inode/buuufer " inode/buffer " handle " inode/handle lf] ] if write? [inode/flags: inode/flags or IMG_NODE_MODIFIED] + ;; post-transf POST-TRANSF-NONE ; no post-transf to apply before as integer! inode ] - unlock-bitmap: func [ ;-- do nothing on Quartz backend - img [red-image!] - data [integer!] - ][] + unlock-bitmap: func [ ;-- do nothing on GDK backend + image [red-image!] + bitmap [integer!] + /local + w [integer!] + h [integer!] + node [img-node!] + ][ + unless post-transf? = POST-TRANSF-NONE [ + ;; DEBUG: print ["unlock-bitmap" lf] + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + node: as img-node! bitmap + case [ + post-transf? = POST-ARGB-TO-ABGR [buffer-argb-to-abgr node/buffer w h] + ;; post-transf? = POST-ARGB-TO-RGBA [buffer-argb-to-rgba node/buffer w h] + ] + ] + ] get-data: func [ handle [integer!] stride [int-ptr!] return: [int-ptr!] /local - node [img-node!] + inode [img-node!] ][ - node: as img-node! handle - stride/value: IMAGE_WIDTH(node/size) * 4 - node/buffer + ;; DEBUG: print ["OS-image/get-data" lf] + inode: as img-node! handle + stride/value: IMAGE_WIDTH(inode/size) * 4 + inode/buffer ] get-pixel: func [ @@ -173,7 +306,12 @@ OS-image: context [ buf [int-ptr!] ][ node: as img-node! (as series! bitmap/value) + 1 + if zero? node/flags [ + node/flags: IMG_NODE_HAS_BUFFER + node/buffer: data-to-image node/handle -1 yes yes + ] buf: node/buffer + index + ;; DEBUG: print ["get pixel " node/buffer " at " index " is " buf/value lf] buf/value ] @@ -187,6 +325,10 @@ OS-image: context [ buf [int-ptr!] ][ node: as img-node! (as series! bitmap/value) + 1 + if zero? node/flags [ + node/flags: IMG_NODE_HAS_BUFFER + node/buffer: data-to-image node/handle -1 yes yes + ] node/flags: node/flags or IMG_NODE_MODIFIED buf: node/buffer + index buf/value: color @@ -262,6 +404,127 @@ OS-image: context [ gdk_pixbuf_get_has_alpha as handle! pixbuf ] + buffer-argb-to-abgr: func [ + buf [int-ptr!] + width [integer!] + height [integer!] + return: [int-ptr!] ; not necessary since buf is already a pointer + /local + data-pixbuf [int-ptr!] + end-data-pixbuf [int-ptr!] + pixel [integer!] + i [integer!] + ][ + data-pixbuf: buf + end-data-pixbuf: data-pixbuf + (width * height) + ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] + while [data-pixbuf < end-data-pixbuf][ + pixel: data-pixbuf/value + ;; DEBUG: print ["pixel:" pixel lf] + pixel: argb-to-abgr pixel + data-pixbuf/value: pixel + data-pixbuf: data-pixbuf + 1 + ] + buf + ] + + buffer-rgba-to-argb: func [ + buf [int-ptr!] + width [integer!] + height [integer!] + return: [int-ptr!] ; not necessary since buf is already a pointer + /local + data-pixbuf [int-ptr!] + end-data-pixbuf [int-ptr!] + pixel [integer!] + i [integer!] + ][ + data-pixbuf: buf + end-data-pixbuf: data-pixbuf + (width * height) + ;; DEBUG: print ["buffer-rgba-to-argb -> size: " width "x" height lf] + while [data-pixbuf < end-data-pixbuf][ + pixel: data-pixbuf/value + ;; DEBUG: print ["pixel:" pixel lf] + ;pixel: (pixel >> 8) or (255 - (pixel >>> 24)) ; RGBA -> ARGB + pixel: rgba-to-argb pixel + data-pixbuf/value: pixel + data-pixbuf: data-pixbuf + 1 + ] + buf + ] + + ; buffer-bgra-to-argb: func [ + ; buf [int-ptr!] + ; width [integer!] + ; height [integer!] + ; return: [int-ptr!] ; not necessary since buf is already a pointer + ; /local + ; data-pixbuf [int-ptr!] + ; end-data-pixbuf [int-ptr!] + ; pixel [integer!] + ; i [integer!] + ; ][ + ; data-pixbuf: buf + ; end-data-pixbuf: data-pixbuf + (width * height) + ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] + ; while [data-pixbuf < end-data-pixbuf][ + ; pixel: data-pixbuf/value + ; ;; DEBUG: print ["pixel:" pixel lf] + ; pixel: bgra-to-argb pixel + ; data-pixbuf/value: pixel + ; data-pixbuf: data-pixbuf + 1 + ; ] + ; buf + ; ] + + ; buffer-bgra-to-rgba: func [ + ; buf [int-ptr!] + ; width [integer!] + ; height [integer!] + ; return: [int-ptr!] ; not necessary since buf is already a pointer + ; /local + ; data-pixbuf [int-ptr!] + ; end-data-pixbuf [int-ptr!] + ; pixel [integer!] + ; i [integer!] + ; ][ + ; data-pixbuf: buf + ; end-data-pixbuf: data-pixbuf + (width * height) + ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] + ; while [data-pixbuf < end-data-pixbuf][ + ; pixel: data-pixbuf/value + ; ;; DEBUG: print ["pixel:" pixel lf] + ; pixel: bgra-to-rgba pixel + ; data-pixbuf/value: pixel + ; data-pixbuf: data-pixbuf + 1 + ; ] + ; buf + ; ] + + ; buffer-argb-to-rgba: func [ + ; buf [int-ptr!] + ; width [integer!] + ; height [integer!] + ; return: [int-ptr!] ; not necessary since buf is already a pointer + ; /local + ; data-pixbuf [int-ptr!] + ; end-data-pixbuf [int-ptr!] + ; pixel [integer!] + ; i [integer!] + ; ][ + ; data-pixbuf: buf + ; end-data-pixbuf: data-pixbuf + (width * height) + ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] + ; while [data-pixbuf < end-data-pixbuf][ + ; pixel: data-pixbuf/value + ; ;; DEBUG: print ["pixel:" pixel lf] + ; pixel: argb-to-rgba pixel + ; data-pixbuf/value: pixel + ; data-pixbuf: data-pixbuf + 1 + ; ] + ; buf + ; ] + ; In particular used to query buffer from handle in lock-bitmap data-to-image: func [ ;-- convert Pixbuf to OS handle or internal buffer data [int-ptr!] @@ -273,57 +536,52 @@ OS-image: context [ ; color-space [integer!] ; Only RGB width [integer!] height [integer!] - ctx [integer!] - ;rect [NSRect!] + i [integer!] bytes-row [integer!] - image-data [integer!] - image [integer!] + ; image-data [integer!] + pixbuf [integer!] n [integer!] - info [integer!] + channels [integer!] alpha? [logic!] buf [byte-ptr!] - data-pixbuf [int-ptr!] - end [int-ptr!] - pixel [integer!] + buf-src [byte-ptr!] loader [handle!] ][ + ;; DEBUG: print ["data-to-image data: " data " len: " len " image?: " image? " edit?: " edit? lf] either image? [ - image: as-integer data + pixbuf: as-integer data ][ loader: gdk_pixbuf_loader_new gdk_pixbuf_loader_write loader data len null gdk_pixbuf_loader_close loader null - image: as-integer gdk_pixbuf_loader_get_pixbuf loader + pixbuf: as-integer gdk_pixbuf_loader_get_pixbuf loader ] - unless edit? [return as int-ptr! image] + unless edit? [return as int-ptr! pixbuf] - alpha?: alpha-channel? image + alpha?: alpha-channel? pixbuf + ;; DEBUG: print ["alpha?: " alpha? lf] ; color-space: ONLY RGB - width: gdk_pixbuf_get_width as handle! image - height: gdk_pixbuf_get_height as handle! image - - bytes-row: width * 4 - ; ??? either alpha? [ - ; info: 2101h ;-- kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents - ; n: 4 - ; ][ - ; info: 8198 ;-- kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little - ; n: 1 - ; ] - + width: gdk_pixbuf_get_width as handle! pixbuf + height: gdk_pixbuf_get_height as handle! pixbuf + channels: gdk_pixbuf_get_n_channels as handle! pixbuf + ;; DEBUG: print ["size: " width "x" height " row-stride: " gdk_pixbuf_get_rowstride as handle! pixbuf " n_channels: " gdk_pixbuf_get_n_channels as handle! pixbuf " bits-per-sample: " gdk_pixbuf_get_bits_per_sample as handle! pixbuf " byte-length: " gdk_pixbuf_get_byte_length as handle! pixbuf lf] + if width * channels <> gdk_pixbuf_get_rowstride as handle! pixbuf [print ["WARNING rowstride: " gdk_pixbuf_get_rowstride as handle! pixbuf " <> width (" width ") * channels (" channels "): " (width * channels) lf]] ; maybe better use other copy - buf: gdk_pixbuf_get_pixels gdk_pixbuf_copy as handle! image - data-pixbuf: as int-ptr! buf - end: data-pixbuf + (width * height) - ;; print ["wxh: " width "x" height lf] - while [data-pixbuf < end][ - pixel: data-pixbuf/value - ; @@debug: print ["pixel:" pixel lf] - pixel: (pixel >> 8) or (255 - (pixel << 24)) ; RGBA -> ARGB - data-pixbuf/value: pixel - data-pixbuf: data-pixbuf + 1 + either channels = 4 [ + buf: gdk_pixbuf_get_pixels gdk_pixbuf_copy as handle! pixbuf + ][ + ;; Needs to convert in n_channels = 4 + n: height * width * 4 + buf: allocate n * 4 + buf-src: gdk_pixbuf_read_pixels as handle! pixbuf + i: 1 + while [i <= n][ + either i % 4 = 0 [buf/i: as byte! 255][buf/i: buf-src/value buf-src: buf-src + 1] + i: i + 1 + ] ] + buffer-argb-to-abgr as int-ptr! buf width height as int-ptr! buf ] @@ -334,7 +592,7 @@ OS-image: context [ /local h [int-ptr!] ][ - ;; print ["load-binary" lf] + ;; DEBUG: print ["load-binary" lf] h: data-to-image as int-ptr! data len no no make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h @@ -344,7 +602,7 @@ OS-image: context [ h [int-ptr!] return: [node!] ][ - ;; print ["load-pixbuf" lf] + ;; DEBUG: print ["load-pixbuf" lf] make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h ;as node! 0 ] @@ -354,80 +612,22 @@ OS-image: context [ return: [node!] /local path [c-string!] - h [int-ptr!] + pixbuf [int-ptr!] + h [integer!] + w [integer!] + buf [byte-ptr!] + ][ - path: file/to-OS-path src - ;; print [ "load-image: " path lf] - h: gdk_pixbuf_new_from_file path null - ;; print ["handle: " h ", wxh: " gdk_pixbuf_get_width h "x" gdk_pixbuf_get_height h] - make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h + path: file/to-OS-path src ; DOES NOT WORK as in macOS: simple-io/to-NSURL src yes + ;; DEBUG: print [ "load-image: " path lf] + pixbuf: gdk_pixbuf_new_from_file path null + w: gdk_pixbuf_get_width pixbuf h: gdk_pixbuf_get_height pixbuf + ;; DEBUG: print ["pixbuf: " pixbuf ", wxh: " w "x" h lf] + ;buf: gdk_pixbuf_get_pixels pixbuf + ;buffer-argb-to-abgr as int-ptr! buf w h + make-node pixbuf null 0 w h ] - ; DO NOT KNOW IF USEFUL! - ; make-image: func [ - ; width [integer!] - ; height [integer!] - ; rgb [byte-ptr!] - ; alpha [byte-ptr!] - ; color [red-tuple!] - ; return: [int-ptr!] - ; /local - ; a [integer!] - ; r [integer!] - ; b [integer!] - ; g [integer!] - ; pixbuf [handle!] - ; pixels [byte-ptr!] - ; channel [integer!] - ; cpt [integer!] - ; end [integer!] - ; ][ - ; ;print-line "make-image" - ; if any [zero? width zero? height][return null] - ; pixbuf: gdk_pixbuf_new 0 yes 8 width height - ; if null? pixbuf [ - ; fire [TO_ERROR(script invalid-arg) pair/push width height] - ; ] - ; ;print-line "ici" - ; pixels: gdk_pixbuf_get_pixels pixbuf - ; channel: gdk_pixbuf_get_n_channels pixbuf ; = 4 - ; end: width * height - - ; ; @@ TO IMPROVE since I mimicked what was in gdiplus (integer!) but gdk is directly in byte! - ; either null? color [ - ; cpt: 0 - ; while [cpt < end][ - ; either null? alpha [a: 255][a: 255 - as-integer alpha/1 alpha: alpha + 1] - ; either null? rgb [r: 255 g: 255 b: 255][ - ; r: as-integer rgb/1 - ; g: as-integer rgb/2 - ; b: as-integer rgb/3 - ; rgb: rgb + 3 - ; ] - ; pixels/1: as byte! (r << 16) - ; pixels/2: as byte! (g << 8) - ; pixels/3: as byte! b - ; pixels/4: as byte! a << 24 - ; pixels: pixels + channel - ; cpt: cpt + 1 - ; ] - ; ][ - ; r: color/array1 - ; a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] - ; r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) - ; cpt: 0 - ; while [cpt < end][ - ; pixels/1: as byte! (r >> 16 and FFh) - ; pixels/2: as byte! (r and FF00h) - ; pixels/3: as byte! (r and FFh << 16) - ; pixels/4: as byte! (a << 24) - ; pixels: pixels + channel - ; cpt: cpt + 1 - ; ] - ; ] - ; pixbuf - ; ] - make-image: func [ width [integer!] height [integer!] @@ -445,7 +645,7 @@ OS-image: context [ scan0 [int-ptr!] pos [integer!] ][ - ;; print ["make-image" lf] + ;; DEBUG: print ["make-image" lf] scan0: as int-ptr! allocate width * height * 4 y: 0 either null? color [ @@ -460,15 +660,25 @@ OS-image: context [ b: as-integer rgb/3 rgb: rgb + 3 ] - scan0/pos: r or (g << 8) or (b << 16) or (a << 24) + scan0/pos: b or (g << 8) or (r << 16) or (a << 24) ; In little endian mode: result is BGRA x: x + 1 ] y: y + 1 ] ][ - r: color/array1 - a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] - r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) + r: color/array1 + ; RGBA array1 reversed with little endian + ; => [R: r and FFh] [G: r >> 8 and FFh] [B: r >> 16 and FFh] [A: r >> 24 and FFh] + a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >> 24 and FFh)] + + ;;====== help for little-endian + ;; Ex -> img: make image! [1x1 1.2.3.4] ; == make image! [1x1 #{010203} #{04}] + ;; DEBUG: print ["r -> (1):" (r and FFh) " g -> (2): " (r >> 8 and FFh) " b -> (3): " (r >> 16 and FFh) " a -> (255-4): " a lf] + ;; b: to-integer img/argb ;= 50463227 + ;; print ["r -> (1):" (b and FFh) " g -> (2): " (b >> 8 and FFh) " b -> (3): " (b >> 16 and FFh) " a -> (255-4): " b >>> 24 lf] + ;; => r -> (1):251 g -> (2): 1 b -> (3): 2 a -> (255-4): 3 + + r: ((r and FFh) << 16) or ((r >> 8 and FFh) << 8) or (r >> 16 and FFh) or (a << 24) ; In little endian mode: RGBA -> BGRA while [y < height][ x: 0 while [x < width][ @@ -486,86 +696,72 @@ OS-image: context [ image [red-image!] return: [int-ptr!] /local - w [integer!] - h [integer!] - data [int-ptr!] - end [int-ptr!] - clr [integer!] - img [int-ptr!] - node [img-node!] + w [integer!] + h [integer!] + data [int-ptr!] + end [int-ptr!] + clr [integer!] + pixbuf [int-ptr!] + buf [byte-ptr!] + node [img-node!] ][ node: as img-node! (as series! image/node/value) + 1 w: IMAGE_WIDTH(image/size) h: IMAGE_HEIGHT(image/size) - ;data: CGDataProviderCreateWithData null node/buffer w * h * 4 0 - ;clr: CGColorSpaceCreateDeviceRGB - ; need to change rgba en argb - img: gdk_pixbuf_new 0 yes 8 w h;CGImageCreate w h 8 32 w * 4 clr 2004h data null true 0 ;-- kCGRenderingIntentDefault - copy-memory gdk_pixbuf_get_pixels img as byte-ptr! node/buffer w * h * 4 - ;CGDataProviderRelease data - ;CGColorSpaceRelease clr - img + pixbuf: gdk_pixbuf_new 0 yes 8 w h;CGImageCreate w h 8 32 w * 4 clr 2004h data null true 0 ;-- kCGRenderingIntentDefault + copy-memory gdk_pixbuf_get_pixels pixbuf as byte-ptr! node/buffer w * h * 4 + buf: gdk_pixbuf_get_pixels pixbuf + buffer-argb-to-abgr as int-ptr! buf w h + ;; DEBUG: print ["make-pixbuf " img lf] + pixbuf ] to-pixbuf: func [ img [red-image!] - return: [integer!] + return: [int-ptr!] /local inode [img-node!] pixbuf [int-ptr!] + width [integer!] + height [integer!] ][ - ;; print ["to-pixbuf" lf] + ;; DEBUG: print ["OS-image/to-pixbuf" lf] inode: as img-node! (as series! img/node/value) + 1 if inode/flags and IMG_NODE_MODIFIED <> 0 [ + ;; DEBUG: print ["IMG_NODE_MODIFIED " img lf] pixbuf: make-pixbuf img unless null? inode/handle [g_object_unref inode/handle] inode/handle: pixbuf - inode/flags: IMG_NODE_HAS_BUFFER + inode/flags: IMG_NODE_MODIFIED ] - as-integer inode/handle + inode/handle ] - ; ; used in OS-image/do-draw -> to adapt to gdk - ; to-bitmap-ctx: func [ - ; img [integer!] - ; return: [int-ptr!] - ; /local - ; color-space [integer!] - ; width [integer!] - ; height [integer!] - ; ;rect [NSRect!] - ; ctx [integer!] - ; ][ - ; ; color-space: CGColorSpaceCreateDeviceRGB - ; ; width: CGImageGetWidth as int-ptr! img - ; ; height: CGImageGetHeight as int-ptr! img - - ; ; rect: make-rect 0 0 width height - ; ; ctx: CGBitmapContextCreate null width height 32 width * 16 color-space 2101h - ; ; CGContextDrawImage ctx rect/x rect/y rect/w rect/h img - ; ; CGColorSpaceRelease color-space - ; as int-ptr! 0;ctx - ; ] - - ; ; used in OS-image/do-draw -> to adapt to gdk - ; ctx-to-image: func [ - ; img [red-image!] - ; ctx [integer!] - ; /local - ; ;data [float32-ptr!] - ; buf [int-ptr!] - ; inode [img-node!] - ; ][ - ; ; inode: as img-node! (as series! img/node/value) + 1 - ; ; CGImageRelease as-integer inode/handle - ; ; inode/handle: as int-ptr! CGBitmapContextCreateImage ctx - ; ; if inode/flags <> 0 [ - ; ; data: as float32-ptr! CGBitmapContextGetData ctx - ; ; unpremultiply-data inode/buffer data IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) - ; ; inode/flags: IMG_NODE_HAS_BUFFER - ; ; ] - ; ; CGContextRelease ctx - ; ] + ;; Better to not use! + to-argb-pixbuf: func [ + image [red-image!] + return: [int-ptr!] + /local + w [integer!] + h [integer!] + bitmap [integer!] + data [int-ptr!] + stride [integer!] + pixbuf [int-ptr!] + buf [byte-ptr!] + ][ + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + stride: 0 + bitmap: OS-image/lock-bitmap image yes + data: OS-image/get-data bitmap :stride + pixbuf: gdk_pixbuf_new GDK_COLORSPACE_RGB yes 8 w h + copy-memory gdk_pixbuf_get_pixels pixbuf as byte-ptr! data w * h * 4 + OS-image/unlock-bitmap image bitmap + buf: gdk_pixbuf_get_pixels pixbuf + buffer-argb-to-abgr as int-ptr! buf w h + pixbuf + ] encode: func [ image [red-image!] @@ -576,9 +772,9 @@ OS-image: context [ type [integer!] path [integer!] dst [integer!] - img [integer!] + img [int-ptr!] ][ - print ["encode" lf] + ;; DEBUG: print ["encode" lf] switch format [ IMAGE_BMP [probe "type: kUTTypeBMP"] IMAGE_PNG [probe "type: kUTTypePNG"] @@ -615,29 +811,140 @@ OS-image: context [ part? [logic!] return: [red-image!] /local + inode [img-node!] x [integer!] y [integer!] w [integer!] h [integer!] offset [integer!] - handle [integer!] + handle [handle!] + handle2 [handle!] width [integer!] height [integer!] bmp [integer!] format [integer!] + src-buf [byte-ptr!] + dst-buf [byte-ptr!] + buf [int-ptr!] ][ - width: IMAGE_WIDTH(src/size) - height: IMAGE_WIDTH(src/size) + ;; DEBUG: print ["image/clone " src " part? " part? lf] + inode: as img-node! (as series! src/node/value) + 1 + handle: inode/handle + src-buf: as byte-ptr! inode/buffer + width: IMAGE_WIDTH(inode/size) + height: IMAGE_HEIGHT(inode/size) offset: src/head x: offset % width y: offset / width - handle: as-integer src/node - bmp: 0 - dst/header: TYPE_IMAGE + ;; DEBUG: print ["handle: " handle " src-buf: " src-buf " offset: " x "x" y " size " width "x" height lf] + + dst/node: make-node handle null 0 width height + inode: as img-node! (as series! dst/node/value) + 1 + + either all [zero? offset not part?][ + either null? handle [ + unless null? src-buf [ + ;; INFO: src-inode/handle null but not src-inode/buffer + dst-buf: allocate width * height * 4 + copy-memory dst-buf src-buf width * height * 4 0 + ;; DEBUG: print ["src-buf " dst-buf " " width "x" height lf] + inode/buffer: as int-ptr! dst-buf + inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER + inode/size: height << 16 or width + dst/size: inode/size + ] + ][ + ;; INFO: src-inode/handle not null? + inode/handle: gdk_pixbuf_copy handle + dst/size: src/size + ] + ][ + either all [part? TYPE_OF(size) = TYPE_PAIR][ + w: width - x + h: height - y + if size/x < w [w: size/x] + if size/y < h [h: size/y] + handle2: gdk_pixbuf_copy gdk_pixbuf_new_subpixbuf handle x y w h + buf: as int-ptr! allocate w * h * 4 + pixbuf-to-data handle2 buf w h + g_object_unref handle2 + inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER + inode/buffer: buf + ][ + ;; TODO: This part is considered not enough stable!!!! + ;; DEBUG: print ["part: " part " size " w "x" h lf] + either part < width [h: 1 w: part][ + h: part / width + w: width + ] + if zero? part [w: 1 h: 1] + either zero? part [w: 0 h: 0][ + inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER + src-buf: as byte-ptr! data-to-image handle -1 yes yes + dst-buf: allocate w * h * 4 + copy-memory dst-buf src-buf w * h * 4 offset * 4 + inode/handle: null + inode/buffer: as int-ptr! dst-buf + ] + ] + inode/size: h << 16 or w + dst/size: inode/size + ;; DEBUG: print ["dst/size " w "x" h lf] + ] dst/head: 0 - dst/node: as node! bmp + dst/header: TYPE_IMAGE + ;; DEBUG: print ["dst " dst lf] dst ] -] \ No newline at end of file + ;; pixbuf utils (since rowstride is not necessary width * channels for a pixbuf) + pixbuf-read-pixel: func [ + pixbuf [handle!] + x [integer!]; 1-based + y [integer!]; 1-based + return: [int-ptr!] + ][ + as int-ptr! (gdk_pixbuf_get_pixels pixbuf) + ((y - 1) * (gdk_pixbuf_get_rowstride pixbuf) + (x - 1) * (gdk_pixbuf_get_n_channels pixbuf)) + ] + + pixbuf-to-data: func [ + src-pixbuf [handle!] + dst-data [int-ptr!] + width [integer!] + height [integer!] + /local + x [integer!] + y [integer!] + pixels [byte-ptr!] + pixel [byte-ptr!] + stride [integer!] + channels [integer!] + src-buf [int-ptr!] + dst-buf [int-ptr!] + + ][ + pixels: gdk_pixbuf_get_pixels src-pixbuf + stride: (gdk_pixbuf_get_rowstride src-pixbuf) + channels: gdk_pixbuf_get_n_channels src-pixbuf + if channels <> 4 [print ["ERROR: number of channels is 3 and not 4 ..." lf]] + dst-buf: dst-data + y: 0 + while [y < height][ + x: 0 + pixel: pixels + (y * stride) + while [x < width][ + ;; DEBUG: print ["pixbuf-to-data: " x "x" y " size: " width "x" height lf] + ;; BE CAREFUL with rowstride for pixbuf + src-buf: as int-ptr! pixel + dst-buf/value: argb-to-abgr src-buf/value + dst-buf: dst-buf + 1 + pixel: pixel + channels + x: x + 1 + ] + y: y + 1 + ] + ] +] + + From 4f44ff9b4779654b1f619c402359336df80a4251 Mon Sep 17 00:00:00 2001 From: qtxie Date: Wed, 3 Jul 2019 21:18:58 +0200 Subject: [PATCH 0094/3432] FEAT: use 16-bytes stack alignment on Linux. --- system/config.r | 1 + 1 file changed, 1 insertion(+) diff --git a/system/config.r b/system/config.r index da3f7f1369..6d6a781dec 100644 --- a/system/config.r +++ b/system/config.r @@ -95,6 +95,7 @@ Linux [ ; Linux default target format: 'ELF type: 'exe dynamic-linker: "/lib/ld-linux.so.2" + stack-align-16?: yes ] Linux-Musl [ ; Linux default target OS: 'Linux From 714307f5d9f88946996267acc129e9eb05aa5c6c Mon Sep 17 00:00:00 2001 From: R cqls Date: Fri, 5 Jul 2019 15:02:27 +0200 Subject: [PATCH 0095/3432] Gtk: fix cairo_font_options_destroy issue (#3933) * A preliminary useable version of red/GTK * add configure-event for window * Fix cairo_font_options_destroy declaration --- modules/view/backends/gtk3/events.reds | 6 ++- modules/view/backends/gtk3/font.reds | 10 ++++- modules/view/backends/gtk3/gtk.reds | 2 +- modules/view/backends/gtk3/handlers.reds | 52 ++++++++++++++---------- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 6d7a9a5e62..1ed86944e8 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -685,7 +685,8 @@ respond-window-add: func [ on-type: 0 if respond-event? actors "on-close" [on-type: on-type or ON_CLOSE] if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] - if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] + if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] + if respond-event? actors "on-size" [on-type: on-type or ON_SIZING] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] if respond-event? actors "on-time" [on-type: on-type or ON_TIME] if respond-event? actors "on-drawing" [on-type: on-type or ON_DRAWING] if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] @@ -933,8 +934,9 @@ connect-widget-events: function [ sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] gobj_signal_connect(widget "delete-event" :window-delete-event null) + ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK + gobj_signal_connect(widget "configure-event" :window-configure-event null) ;BUG (make `vid.red` failing):gtk_widget_add_events widget GDK_STRUCTURE_MASK - ;gobj_signal_connect(widget "configure-event" :window-configure-event null) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate null) connect-common-events widget face sym parent diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index cf0502ff0e..41751c1179 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -140,12 +140,14 @@ free-font: func [ state [red-block!] hFont [handle!] ][ + ;; DEBUG: print ["free-font begin" lf] hFont: get-font-handle font 0 unless null? hFont [ state: as red-block! (object/get-values font) + FONT_OBJ_STATE state/header: TYPE_NONE free-font-handle hFont ] + ;; DEBUG: print ["free-font end" lf] ] set-font-handle: func [ @@ -766,18 +768,22 @@ pango-layout-context-set-text: func [ free-pango-cairo-font: func [ dc [draw-ctx!] ][ + ;; DEBUG: print ["free-pango-cairo-layout begin" lf] unless null? dc/font-desc [ pango_font_description_free dc/font-desc dc/font-desc: null ] + ;; DEBUG: print ["free-pango-cairo-layout font-opts: " dc/font-opts lf] unless null? dc/font-opts [ cairo_font_options_destroy dc/font-opts - dc/font-desc: null + dc/font-opts: null ] + ;; DEBUG: print ["free-pango-cairo-layout dc/layout: " dc/layout lf] unless null? dc/layout [ g_object_unref dc/layout dc/layout: null ] + ;; DEBUG: print ["free-pango-cairo-layout end" lf] ] make-pango-cairo-layout: func [ @@ -790,6 +796,6 @@ make-pango-cairo-layout: func [ ;; DEBUG: print ["make-pango-cairo-layout" lf] layout: pango_cairo_create_layout cr unless null? fd [pango_layout_set_font_description layout fd] - ;; DEBUG: print ["make-pango-cairo-layout: " dc/layout lf] + ;; DEBUG: print ["make-pango-cairo-layout: " layout lf] layout ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a42b08edd2..9acb8e06f0 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2684,7 +2684,7 @@ GPtrArray!: alias struct! [ return: [handle!] ] cairo_font_options_destroy: "cairo_font_options_destroy" [ - return: [handle!] + fontopts [handle!] ] cairo_font_options_set_antialias: "cairo_font_options_set_antialias" [ cfo [handle!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 10c8546d18..a0f642c012 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -312,27 +312,37 @@ window-removed-event: func [ ] ;; BUG: `vid.red` fails... back with window-size-allocate handler for resizing -; window-configure-event: func [ -; [cdecl] -; widget [handle!] -; event [GdkEventConfigure!] -; /local -; sz [red-pair!] -; ][ -; ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] -; sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size -; either any [event/width <> sz/x event/height <> sz/y] [ -; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ -; evt-motion/x_new: event/width -; evt-motion/y_new: event/height -; evt-motion/x_root: as float! event/x -; evt-motion/y_root: as float! event/y -; make-event widget 0 EVT_SIZING -; ;] -; ;evt-motion/cpt: evt-motion/cpt + 1 -; yes -; ][no] -; ] +window-configure-event: func [ + [cdecl] + widget [handle!] + event [GdkEventConfigure!] + /local + sz [red-pair!] +][ + ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size + ; either any [event/width <> sz/x event/height <> sz/y] [ + ; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ + ; evt-motion/x_new: event/width + ; evt-motion/y_new: event/height + ; evt-motion/x_root: as float! event/x + ; evt-motion/y_root: as float! event/y + ; make-event widget 0 EVT_SIZE + ; ;] + ; ;evt-motion/cpt: evt-motion/cpt + 1 + ; yes + ; ][no] + if any [event/width <> sz/x event/height <> sz/y] [ + ; evt-sizing/x_new: event/width + ; evt-sizing/y_new: event/height + ; sz/x: evt-sizing/x_new + ; sz/y: evt-sizing/y_new + ; ;; DEBUG: print ["window-size-allocate: " evt-sizing/x_root "x" evt-sizing/y_root lf] + ; evt-sizing/x_root: as float! event/x + ; evt-sizing/y_root: as float! event/y + make-event widget 0 EVT_SIZE + ] +] window-size-allocate: func [ From a7172286347f967c6c5935acf587b59ad99214ae Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 5 Jul 2019 17:35:51 +0200 Subject: [PATCH 0096/3432] Fix image issue --- modules/view/backends/gtk3/draw.reds | 4 ++-- modules/view/backends/gtk3/gtk.reds | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 7c0e6e4d3b..32dd4d07c2 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -721,7 +721,7 @@ GDK-draw-image: func [ img: either width = 0 [image][gdk_pixbuf_scale_simple image width height 2] ;; DEBUG: print ["GDK-draw-image: " x "x" y "x" width "x" height lf] cairo_translate cr as-float x as-float y - gdk_cairo_set_source_pixbuf cr img 0 0 + gdk_cairo_set_source_pixbuf cr img 0.0 0.0 cairo_paint cr cairo_translate cr as-float (0 - x) as-float (0 - y) if width > 0 [g_object_unref img] @@ -799,7 +799,7 @@ OS-draw-image: func [ ;; DEBÙG: print ["pixbuf format: " format lf] crop_surf: cairo_image_surface_create format crop_img_sx crop_img_sy crop_cr: cairo_create crop_surf - gdk_cairo_set_source_pixbuf crop_cr img 0 0 + gdk_cairo_set_source_pixbuf crop_cr img 0.0 0.0 cairo_paint crop_cr cairo_destroy crop_cr diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 9acb8e06f0..3c12259c17 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2420,8 +2420,8 @@ GPtrArray!: alias struct! [ gdk_cairo_set_source_pixbuf: "gdk_cairo_set_source_pixbuf" [ cr [handle!] pixbuf [handle!] - x [integer!] - y [integer!] + x [float!] + y [float!] ] gdk_pixbuf_new: "gdk_pixbuf_new" [ colorsp [integer!] From 4a048735889d1659847847b2f015dd983b224787 Mon Sep 17 00:00:00 2001 From: qtxie Date: Mon, 8 Jul 2019 16:42:46 +0200 Subject: [PATCH 0097/3432] FIX: buf4 is null in function load-utf8-buffer. --- runtime/unicode.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/unicode.reds b/runtime/unicode.reds index 7f116349d8..5ae0bc4107 100644 --- a/runtime/unicode.reds +++ b/runtime/unicode.reds @@ -393,9 +393,9 @@ unicode: context [ s: expand-series s used * unit ] ] - + buf1: as byte-ptr! s/offset - buf4: null + buf4: buf1 end: buf1 + s/size count: size From 1d97690aa66077b20d94b071dd888441bccef44e Mon Sep 17 00:00:00 2001 From: qtxie Date: Mon, 8 Jul 2019 16:48:54 +0200 Subject: [PATCH 0098/3432] FIX: compilation error due to last commit. --- runtime/unicode.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/unicode.reds b/runtime/unicode.reds index 5ae0bc4107..a8a0a5a0b9 100644 --- a/runtime/unicode.reds +++ b/runtime/unicode.reds @@ -395,7 +395,7 @@ unicode: context [ ] buf1: as byte-ptr! s/offset - buf4: buf1 + buf4: as int-ptr! buf1 end: buf1 + s/size count: size From 869918542e4cb8e2562e5689c55043ea537fadc3 Mon Sep 17 00:00:00 2001 From: rcqls Date: Mon, 8 Jul 2019 19:16:37 +0200 Subject: [PATCH 0099/3432] minor changes --- modules/view/backends/gtk3/events.reds | 1 - tests/gtk3/view-test.red | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 1ed86944e8..7392f0f3d2 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -936,7 +936,6 @@ connect-widget-events: function [ gobj_signal_connect(widget "delete-event" :window-delete-event null) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK gobj_signal_connect(widget "configure-event" :window-configure-event null) - ;BUG (make `vid.red` failing):gtk_widget_add_events widget GDK_STRUCTURE_MASK ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate null) connect-common-events widget face sym parent diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red index 12a1bd5fb4..fa732f82f1 100644 --- a/tests/gtk3/view-test.red +++ b/tests/gtk3/view-test.red @@ -3,12 +3,12 @@ Red [ Needs: 'View ] -system/view/debug?: yes -live?: system/view/auto-sync?: no +system/view/debug?: no +live?: system/view/auto-sync?: yes workstation?: system/view/platform/product = 1 os-version: system/view/platform/version -recycle/off +;recycle/off #switch config/OS [ Windows [ @@ -901,8 +901,4 @@ append win/pane make face! [ ] dump-face win -view/flags win [resize] -system/view/debug?: no -system/view/auto-sync?: yes - -recycle/on \ No newline at end of file +view/flags win [resize] \ No newline at end of file From 407d4f32e91a648a54c5d9a81ad9a446cb518ff1 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 16 Jul 2019 13:42:15 +0200 Subject: [PATCH 0100/3432] fix gui-console.red crash --- modules/view/backends/gtk3/gui.reds | 1 + modules/view/backends/gtk3/handlers.reds | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 53d1eae1c5..f469f46c6b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1743,6 +1743,7 @@ OS-make-view: func [ ] gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) unless null? caption [gtk_window_set_title widget caption] + ;; DEBUG: print ["make-view: set_default_size " size/x "x" size/y lf] gtk_window_set_default_size widget size/x size/y winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index a0f642c012..d4bdc3bdd8 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -222,6 +222,7 @@ base-draw: func [ sym [integer!] pos [red-pair! value] DC [draw-ctx! value] + drawDC [draw-ctx!] ][ ;; DEBUG: print ["base-draw " widget lf] @@ -268,13 +269,14 @@ base-draw: func [ ;; DEBUG: print ["do-draw in base-draw" lf] do-draw cr null draw no yes yes yes ][ - ; system/thrown: 0 - ; DC: declare draw-ctx! ;@@ should declare it on stack - ; draw-begin DC ctx img no no - ; integer/make-at as red-value! draw as-integer DC + ;; DEBUG: print ["base-draw: draw not a block" lf] + system/thrown: 0 + drawDC: declare draw-ctx! ;@@ should declare it on stack + draw-begin drawDC cr null no no + integer/make-at as red-value! draw as-integer drawDC make-event widget 0 EVT_DRAWING - ; draw/header: TYPE_NONE - ; draw-end DC ctx no no no + draw/header: TYPE_NONE + draw-end drawDC cr no no no ] ;; DEBUG: print ["base-draw " widget lf] From ba93ae3f436c5b4b726346895e312b57ff04c792 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 16 Jul 2019 13:55:59 +0200 Subject: [PATCH 0101/3432] bad respond-event? --- modules/view/backends/gtk3/events.reds | 4 ++-- modules/view/backends/gtk3/gui.reds | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 7392f0f3d2..dd93b6ce05 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -685,8 +685,8 @@ respond-window-add: func [ on-type: 0 if respond-event? actors "on-close" [on-type: on-type or ON_CLOSE] if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] - if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] - if respond-event? actors "on-size" [on-type: on-type or ON_SIZING] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] + if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] + if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] if respond-event? actors "on-time" [on-type: on-type or ON_TIME] if respond-event? actors "on-drawing" [on-type: on-type or ON_DRAWING] if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f469f46c6b..d0b1cdc42b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -920,6 +920,7 @@ change-size: func [ ;; DEBUG: print ["change-size " get-symbol-name get-widget-symbol widget " " widget " " size/x "x" size/y lf] either type = window [ + ;; DEBUG: print ["change-size window: " size/x "x" size/y lf] gtk_window_set_default_size widget size/x size/y gtk_widget_queue_draw widget ][ From 4c84cd8e627e2766e781a8363f4c2716f0b593e7 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 16 Jul 2019 13:57:29 +0200 Subject: [PATCH 0102/3432] more readable --- modules/view/backends/gtk3/events.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index dd93b6ce05..60a3c507e5 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -684,7 +684,8 @@ respond-window-add: func [ ][ on-type: 0 if respond-event? actors "on-close" [on-type: on-type or ON_CLOSE] - if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] + if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] + if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] if respond-event? actors "on-time" [on-type: on-type or ON_TIME] From 6c3321cebba8868ccb5ff8e508844b68cf322859 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 16 Jul 2019 15:12:04 +0200 Subject: [PATCH 0103/3432] clean useless comments --- modules/view/backends/gtk3/font.reds | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 41751c1179..e226fa147e 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -465,9 +465,7 @@ red-gtk-styles: func [ env strarr str found [logic!] ][ - env: system/env-vars - ;strarr: g_strsplit "GTK_STYLES" "=" 2 - ;g_strfreev strarr + env: system/env-vars found: no until [ strarr: g_strsplit env/item "=" 2 From b5db0689085f8a60782590b36a9b07e66c7a25c4 Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 19 Jul 2019 17:51:10 +0200 Subject: [PATCH 0104/3432] First version for a preliminary gui-console --- environment/console/GUI/core.red | 13 +++++++++++++ environment/console/GUI/gui-console.red | 2 +- environment/console/engine.red | 1 - modules/view/backends/gtk3/events.reds | 21 +++++++++++---------- modules/view/backends/gtk3/gui.reds | 3 +-- modules/view/backends/platform.red | 1 + 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index be19f66406..7fc7258eda 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -797,6 +797,18 @@ object [ ctrl?: event/ctrl? shift?: event/shift? char: event/key + #if config/debug? [ + debug-print ["char: -" char "- " + switch/default char [ + #"^M" ["M"] #"^H" ["H"] #"^-" ["-"] + left ["left"] right ["right"] up ["up"] down ["down"] + insert ["insert"] delete ["delete"] + #"^A" home ["home"] #"^E" end ["end"] #"^C" ["C"] #"^V" ["V"] + #"^X" ["X"] #"^Z" ["Z"] #"^Y" ["Y"] #"^[" ["["] #"^~" ["~"] ;-- Ctrl + Backspace + #"^L" ["L"] #"^K" + ]["none"] + lf] + ] #if config/OS = 'macOS [ if find event/flags 'command [ char: switch char [ @@ -888,6 +900,7 @@ object [ paint: func [/local str cmds y n h cnt delta num end styles][ if empty? lines [exit] + cmds: [pen color text 0x0 text-box] cmds/2: foreground cmds/4/x: pad-left diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index 7d1bea3094..be022d99c4 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -128,7 +128,7 @@ gui-console-ctx: context [ setup-faces: does [ console/pane: reduce [caret] - append win/pane reduce [console tips] + append win/pane reduce [console]; tips] win/menu: [ "File" [ "Run..." run-file diff --git a/environment/console/engine.red b/environment/console/engine.red index f4ef4124bc..ea98428c59 100644 --- a/environment/console/engine.red +++ b/environment/console/engine.red @@ -202,7 +202,6 @@ system/console: context [ eval-command: function [line [string!] /extern cue mode][ if mode = 'mono [change/dup count 0 3] ;-- reset delimiter counters to zero - if any [not tail? line mode <> 'mono][ either all [not empty? line escape = last line][ cue: none diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 60a3c507e5..606926ceb4 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -216,13 +216,11 @@ get-event-key: func [ res: either all [special? evt/type = EVT_KEY][ as red-value! none-value ][ - either code > 0 [ - ;; DEBUG: print ["key-code2=" code " flags=" evt/flags " special-key=" special-key " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] - char: as red-char! stack/push* - char/header: TYPE_CHAR - char/value: code - as red-value! char - ][as red-value! none-value] + ;; DEBUG: print ["key-code2=" code " flags=" evt/flags " special-key=" special-key " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] + char: as red-char! stack/push* + char/header: TYPE_CHAR + char/value: code + as red-value! char ] ] res @@ -420,7 +418,7 @@ do-events: func [ no-wait? [logic!] return: [logic!] /local - msg? [logic!] + msg? [logic!] event [GdkEventAny!] widget [handle!] ; state [GdkModifierType!] @@ -534,7 +532,9 @@ translate-key: func [ special?: no key: case [ all[keycode >= 20h keycode <= 5Ah][keycode]; RED_VK_SPACE to RED_VK_Z + all[keycode >= 5Bh keycode <= 60h][keycode] all[keycode >= 61h keycode <= 7Ah][keycode]; RED_VK_a to RED_VK_z + all[keycode >= 7Bh keycode <= 7Dh][keycode]; all[keycode >= A0h keycode <= FFh][keycode]; all[keycode >= FFBEh keycode <= FFD5h][special?: yes keycode + RED_VK_F1 - FFBEh] ;RED_VK_F1 to RED_VK_F24 all[keycode >= FF51h keycode <= FF54h][special?: yes keycode + RED_VK_LEFT - FF51h] ;RED_VK_LEFT to RED_VK_DOWN @@ -543,12 +543,13 @@ translate-key: func [ keycode = FF1Bh [special?: yes RED_VK_ESCAPE] keycode = FF50h [special?: yes RED_VK_HOME] keycode = FFE5h [special?: yes RED_VK_NUMLOCK] - keycode = FF08h [special?: yes RED_VK_BACK] + keycode = FF08h [special?: no RED_VK_BACK] keycode = FF09h [special?: yes RED_VK_TAB] keycode = FFE1h [special?: yes RED_VK_LSHIFT] keycode = FFE2h [special?: yes RED_VK_RSHIFT] keycode = FFE3h [special?: yes RED_VK_LCONTROL] keycode = FFE4h [special?: yes RED_VK_RCONTROL] + keycode = FFFFh [special?: yes RED_VK_DELETE] ;@@ To complete! true [RED_VK_UNKNOWN] ] @@ -563,7 +564,7 @@ post-quit-msg: func [ e [integer!] tm [float!] ][ - 0 + exit-loop: exit-loop - 1 ] ;;------------- centralize here connection handlers diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index d0b1cdc42b..5abb0f5591 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1537,8 +1537,7 @@ parse-common-opts: func [ set-draggable widget yes ] sym = _cursor [ - ;; DEBUG: - print ["set cursor: " widget lf] + ;; DEBUG: print ["set cursor: " widget lf] w: word + 1 display: gdk_window_get_display widget either TYPE_OF(w) = TYPE_IMAGE [ diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 14e1ce023d..902c71de8a 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -648,6 +648,7 @@ system/view/platform: context [ #switch OS [ Windows [gui/PostQuitMessage 0] macOS [gui/post-quit-msg] + Linux [gui/post-quit-msg] #default [0] ] ] From ded07592a0215cc86665486240d4bba2fbd9116c Mon Sep 17 00:00:00 2001 From: rcqls Date: Mon, 22 Jul 2019 01:14:44 +0200 Subject: [PATCH 0105/3432] Fix caret issue for gui-console --- modules/view/backends/gtk3/text-box.reds | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 0bec5386c5..2250134ec8 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -506,9 +506,9 @@ OS-text-box-metrics: func [ TBOX_METRICS_OFFSET? TBOX_METRICS_OFFSET_LOWER [ ; caret-to-offset int: as red-integer! arg0 - pango_layout_index_to_pos layout int/value :rect - ;; DEBUG: print ["TBOX_METRICS_OFFSET? " rect/x "x" rect/y "x" rect/width "x" rect/height lf] - pair/push rect/x rect/y + pango_layout_index_to_pos layout int/value - 1 :rect + ;; DEBUG: print ["TBOX_METRICS_OFFSET? " rect/x / PANGO_SCALE "x" rect/y / PANGO_SCALE "x" rect/width / PANGO_SCALE "x" rect/height / PANGO_SCALE lf] + pair/push rect/x / PANGO_SCALE rect/y / PANGO_SCALE ] TBOX_METRICS_INDEX? TBOX_METRICS_CHAR_INDEX? [ ; offset-to-caret From 1a825d356dc8349994a7efb62cc59f71823aa7b3 Mon Sep 17 00:00:00 2001 From: rcqls Date: Mon, 22 Jul 2019 10:40:34 +0200 Subject: [PATCH 0106/3432] Working on scrolling/wheeling on gui-console --- environment/console/GUI/core.red | 2 ++ modules/view/backends/gtk3/events.reds | 3 +++ modules/view/backends/gtk3/gtk.reds | 10 +++++----- modules/view/backends/gtk3/gui.reds | 2 ++ modules/view/backends/gtk3/handlers.reds | 3 ++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 7fc7258eda..3a6f7f77c4 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -279,6 +279,7 @@ object [ track [scroller/position - event/picked] wheel [ delta: event/picked + ;;;debug-print ["delta: " delta lf] case [ ;-- scroll by lines all [delta > -1.0 delta < 0.0][-1] all [delta > 0.0 delta < 1.0][1] @@ -288,6 +289,7 @@ object [ ] ] ][0] + ;;;debug-print ["n: " n lf] if n <> 0 [ scroll-lines n system/view/platform/redraw console diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 606926ceb4..7112a7d120 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -275,6 +275,9 @@ get-event-picked: func [ int ] ] + EVT_WHEEL [ + float/push as-float evt/flags / 10000.0 + ] EVT_MENU [word/push* evt/flags and FFFFh] default [integer/push evt/flags and FFFFh] ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 3c12259c17..7d691689aa 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -130,18 +130,18 @@ GdkEventConfigure!: alias struct! [ GdkEventScroll!: alias struct! [ type [integer!] window [handle!] - send_event [byte!] + send_event [byte!] time [integer!] - x [float!] - y [float!] + x [float!] + y [float!] state [integer!] - direction [integer!] + direction [integer!] device [handle!] x_root [float!] y_root [float!] delta_x [float!] delta_y [float!] - is_stop [integer!] + is_stop [integer!] ] #enum GdkScrollDirection! [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5abb0f5591..ef67cbb12b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1724,6 +1724,8 @@ OS-make-view: func [ sym = rich-text [ widget: gtk_layout_new null null;gtk_drawing_area_new gtk_layout_set_size widget size/x size/y + _widget: gtk_scrolled_window_new null null + gtk_container_add _widget widget ] sym = window [ ;; DEBUG: print ["win App " GTKApp lf] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index d4bdc3bdd8..91d2354e86 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -1040,5 +1040,6 @@ widget-scroll-event: func [ ctx [node!] return: [integer!] ][ - make-event widget check-flags event/type event/state EVT_WHEEL + ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] + make-event widget as-integer (event/delta_y * 10000) EVT_WHEEL ] From cf9a5875dba18b0e02f6e0ca1e47f57e064fe4e1 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 23 Jul 2019 01:39:56 +0200 Subject: [PATCH 0107/3432] Fix input of gui-console for characters & and < by escaping it --- modules/view/backends/gtk3/gtk.reds | 5 +++++ modules/view/backends/gtk3/text-box.reds | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 7d691689aa..d8734a358b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -617,6 +617,11 @@ GPtrArray!: alias struct! [ data [int-ptr!] return: [integer!] ] + g_markup_escape_text: "g_markup_escape_text" [ + text [c-string!] + len [integer!] + return: [c-string!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 2250134ec8..9ef480f9c7 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -279,7 +279,8 @@ pango-markup-text: func [ ;; DEBUG: print ["Add " lf] text: as GString! lc/text-markup g_string_append text "" - ;; DEBUG: print ["tex-markup: " text/str lf] + ;; DEBUG: print ["text: " lc/text lf] + ;; DEBUG: print ["text-markup: " text/str lf] ] ] @@ -598,7 +599,9 @@ OS-text-box-layout: func [ text: as red-string! values + FACE_OBJ_TEXT len: -1 str: unicode/to-utf8 text :len - layout-ctx-begin lc str len + str: g_markup_escape_text str len + + layout-ctx-begin lc str length? str size: as red-pair! values + FACE_OBJ_SIZE @@ -646,7 +649,9 @@ OS-text-box-layout: func [ g_string_assign as GString! lc/text-markup lc/text ] layout-ctx-end lc - if null? target [pango-layout-set-text lc size] + if null? target [ + pango-layout-set-text lc size + ] as handle! lc ] @@ -657,6 +662,7 @@ pango-layout-set-text: func [ gstr [GString!] ][ gstr: as GString! lc/text-markup + ;; DEBUG: print ["pango-layout-set-text:<<-" gstr/str "->>" lf] pango_layout_set_markup lc/layout gstr/str -1 pango_layout_set_width lc/layout PANGO_SCALE * size/x pango_layout_set_height lc/layout PANGO_SCALE * size/y From 7aabac945b5aea17217fec27258268c385c2901f Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 23 Jul 2019 14:34:43 +0200 Subject: [PATCH 0108/3432] Add preliminary clipboard --- modules/view/backends/gtk3/gtk.reds | 157 +++++++++++++++++----------- runtime/clipboard.reds | 83 ++++++++++++++- 2 files changed, 176 insertions(+), 64 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index d8734a358b..efa7b8226c 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -667,6 +667,37 @@ GPtrArray!: alias struct! [ display [handle!] return: [handle!] ] + gtk_clipboard_get: "gtk_clipboard_get" [ + atom [handle!] + return: [handle!] + ] + gtk_clipboard_set_text: "gtk_clipboard_set_text" [ + clipboard [handle!] + text [c-string!] + len [integer!] + ] + gtk_clipboard_set_image: "gtk_clipboard_set_image" [ + clipboard [handle!] + img [handle!] + ] + gtk_clipboard_wait_for_text: "gtk_clipboard_wait_for_text" [ + clipboard [handle!] + return: [c-string!] + ] + gtk_clipboard_wait_for_image: "gtk_clipboard_wait_for_image" [ + clipboard [handle!] + return: [handle!] + ] + gtk_clipboard_request_text: "gtk_clipboard_request_text" [ + clipboard [handle!] + handler [integer!] + data [handle!] + ] + gtk_clipboard_request_image: "gtk_clipboard_request_image" [ + clipboard [handle!] + handler [integer!] + data [handle!] + ] ;; ] ;; LIBGLIB-file cdecl [ g_quark_from_string: "g_quark_from_string" [ @@ -845,20 +876,20 @@ GPtrArray!: alias struct! [ gdk_cursor_new_from_pixbuf: "gdk_cursor_new_from_pixbuf" [ display [handle!] pixbuf [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] return: [handle!] ] gdk_cursor_new_from_name: "gdk_cursor_new_from_name" [ display [handle!] - name [c-string!] + name [c-string!] return: [handle!] ] gtk_get_current_event_time: "gtk_get_current_event_time" [ return: [integer!] ] gtk_get_current_event_state: "gtk_get_current_event_state" [ - state [int-ptr!] + state [int-ptr!] ] gtk_get_current_event: "gtk_get_current_event" [ return: [handle!] @@ -878,7 +909,7 @@ GPtrArray!: alias struct! [ ] gdk_event_copy: "gdk_event_copy" [ event [handle!] - return: [handle!] + return: [handle!] ] gdk_event_free: " gdk_event_free" [ event [handle!] @@ -887,12 +918,12 @@ GPtrArray!: alias struct! [ event [handle!] dx [float-ptr!] dy [float-ptr!] - return: [integer!] + return: [integer!] ] gdk_event_get_scroll_direction: "gdk_event_get_scroll_direction" [ event [handle!] - direction [int-ptr!] + direction [int-ptr!] ] gdk_window_get_display: "gdk_window_get_display" [ window [handle!] @@ -901,14 +932,14 @@ GPtrArray!: alias struct! [ gdk_window_get_device_position: "gdk_window_get_device_position" [ window [handle!] device [handle!] - x [int-ptr!] - y [int-ptr!] - mask [handle!] + x [int-ptr!] + y [int-ptr!] + mask [handle!] return: [handle!] ] gdk_window_invalidate_rect: "gdk_window_invalidate_rect" [ - window [handle!] - rect [tagRECT] + window [handle!] + rect [tagRECT] invalidate_children [logic!] ] gtk_application_new: "gtk_application_new" [ @@ -941,110 +972,110 @@ GPtrArray!: alias struct! [ ] gtk_menu_bar_set_pack_direction: "gtk_menu_bar_set_pack_direction" [ menubar [handle!] - dir [GtkPackDirection!] + dir [GtkPackDirection!] ] gtk_menu_bar_set_child_pack_direction: "gtk_menu_bar_set_child_pack_direction" [ menubar [handle!] - dir [GtkPackDirection!] + dir [GtkPackDirection!] ] gtk_menu_new: "gtk_menu_new" [ return: [handle!] ] gtk_menu_popup_at_pointer: "gtk_menu_popup_at_pointer" [ - menu [handle!] - event [handle!] + menu [handle!] + event [handle!] ] gtk_menu_shell_append: "gtk_menu_shell_append" [ - menu [handle!] + menu [handle!] item [handle!] ] gtk_menu_shell_prepend: "gtk_menu_shell_prepend" [ - menu [handle!] - item [handle!] + menu [handle!] + item [handle!] ] gtk_menu_shell_insert: "gtk_menu_shell_insert" [ - menu [handle!] - item [handle!] - pos [integer!] + menu [handle!] + item [handle!] + pos [integer!] ] gtk_menu_shell_select_item: "gtk_menu_shell_select_item" [ - menu [handle!] - item [handle!] + menu [handle!] + item [handle!] ] gtk_menu_shell_select_first: "gtk_menu_shell_select_first" [ - menu [handle!] + menu [handle!] sensitive [logic!] ] gtk_menu_shell_deselect: "gtk_menu_shell_deselect" [ - menu [handle!] + menu [handle!] ] gtk_menu_shell_activate_item: "gtk_menu_shell_activate_item" [ - menu [handle!] - item [handle!] - force [integer!] + menu [handle!] + item [handle!] + force [integer!] ] gtk_menu_shell_cancel: "gtk_menu_shell_cancel" [ - menu [handle!] + menu [handle!] ] gtk_menu_shell_set_take_focus: "gtk_menu_shell_set_take_focus" [ - menu [handle!] - focus [integer!] + menu [handle!] + focus [integer!] ] gtk_menu_shell_get_take_focus: "gtk_menu_shell_get_take_focus" [ - menu [handle!] + menu [handle!] return: [integer!] ] gtk_menu_shell_get_selected_item: "gtk_menu_shell_get_selected_item" [ - menu [handle!] + menu [handle!] return: [handle!] ] gtk_menu_shell_get_parent_shell: "gtk_menu_shell_get_parent_shell" [ - menu [handle!] + menu [handle!] return: [handle!] ] gtk_menu_item_new: "gtk_menu_item_new" [ return: [handle!] ] gtk_menu_item_new_with_label: "gtk_menu_item_new_with_label" [ - label [c-string!] + label [c-string!] return: [handle!] ] gtk_menu_item_new_with_mnemonic: "gtk_menu_item_new_with_mnemonic" [ - label [c-string!] + label [c-string!] return: [handle!] ] gtk_menu_item_get_label: "gtk_menu_item_get_label" [ - item [handle!] + item [handle!] return: [c-string!] ] gtk_menu_item_set_label: "gtk_menu_item_set_label" [ - item [handle!] - label [c-string!] + item [handle!] + label [c-string!] ] gtk_menu_item_get_use_underline: "gtk_menu_item_get_use_underline" [ - item [handle!] + item [handle!] return: [logic!] ] gtk_menu_item_set_use_underline: "gtk_menu_item_set_use_underline" [ - item [handle!] + item [handle!] setting [logic!] ] gtk_menu_item_set_submenu: "gtk_menu_item_set_submenu" [ - item [handle!] + item [handle!] submenu [handle!] ] gtk_menu_item_get_submenu: "gtk_menu_item_get_submenu" [ - item [handle!] + item [handle!] return: [handle!] ] gtk_menu_item_select: "gtk_menu_item_select" [ - item [handle!] + item [handle!] ] gtk_menu_item_deselect: "gtk_menu_item_deselect" [ - item [handle!] + item [handle!] ] gtk_menu_item_activate: "gtk_menu_item_activate" [ - item [handle!] + item [handle!] ] gtk_separator_menu_item_new: "gtk_separator_menu_item_new" [ return: [handle!] @@ -1109,7 +1140,7 @@ GPtrArray!: alias struct! [ ] gtk_window_set_resizable: "gtk_window_set_resizable" [ window [handle!] - mode [logic!] + mode [logic!] ] gtk_window_move: "gtk_window_move" [ window [handle!] @@ -1148,7 +1179,7 @@ GPtrArray!: alias struct! [ ] gtk_window_propagate_key_event: "gtk_window_propagate_key_event" [ widget [handle!] - event [handle!] + event [handle!] ] gtk_window_get_focus: "gtk_window_get_focus" [ window [handle!] @@ -1163,12 +1194,12 @@ GPtrArray!: alias struct! [ return: [handle!] ] gtk_window_set_default: "gtk_window_set_default" [ - window [handle!] + window [handle!] default_widget [handle!] ] gtk_propagate_event: "gtk_propagate_event" [ widget [handle!] - event [handle!] + event [handle!] ] gtk_widget_register_window: "gtk_widget_register_window" [ widget [handle!] @@ -1180,7 +1211,7 @@ GPtrArray!: alias struct! [ ] gtk_widget_event: "gtk_widget_event" [ widget [handle!] - event [handle!] + event [handle!] return: [logic!] ] gtk_widget_queue_draw: "gtk_widget_queue_draw" [ @@ -1188,10 +1219,10 @@ GPtrArray!: alias struct! [ ] gtk_widget_queue_draw_area: "gtk_widget_queue_draw_area" [ widget [handle!] - x [integer!] - y [integer!] - w [integer!] - h [integer!] + x [integer!] + y [integer!] + w [integer!] + h [integer!] ] gtk_widget_queue_resize: "gtk_widget_queue_resize" [ widget [handle!] @@ -1227,11 +1258,11 @@ GPtrArray!: alias struct! [ ] gtk_widget_set_hexpand: "gtk_widget_set_hexpand" [ widget [handle!] - type [logic!] + type [logic!] ] gtk_widget_set_vexpand: "gtk_widget_set_vexpand" [ widget [handle!] - type [logic!] + type [logic!] ] gtk_widget_compute_expand: "gtk_widget_compute_expand" [ widget [handle!] @@ -1244,11 +1275,11 @@ GPtrArray!: alias struct! [ ] gtk_widget_get_visible: "gtk_widget_get_visible" [ widget [handle!] - return: [logic!] + return: [logic!] ] gtk_widget_is_visible: "gtk_widget_is_visible" [ widget [handle!] - return: [logic!] + return: [logic!] ] gtk_widget_set_sensitive: "gtk_widget_set_sensitive" [ widget [handle!] @@ -1303,8 +1334,8 @@ GPtrArray!: alias struct! [ focus [logic!] ] gtk_widget_set_can_default: "gtk_widget_set_can_default" [ - widget [handle!] - can_default [logic!] + widget [handle!] + can_default [logic!] ] gtk_widget_set_focus_on_click: "gtk_widget_set_focus_on_click" [ widget [handle!] @@ -1340,7 +1371,7 @@ GPtrArray!: alias struct! [ ] gtk_widget_add_events: "gtk_widget_add_events" [ widget [handle!] - mask [integer!] + mask [integer!] ] gtk_widget_get_events: "gtk_widget_get_events" [ widget [handle!] diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index ba7b417537..3428d207c8 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -218,6 +218,87 @@ clipboard: context [ as logic! res ] ] + Linux [ + ;; Depends on GTK + #import [ + "libgtk-3.so.0" cdecl [ + gdk_atom_intern_static_string: "gdk_atom_intern_static_string" [ + name [c-string!] + return: [handle!] + ] + gtk_clipboard_get: "gtk_clipboard_get" [ + atom [handle!] + return: [handle!] + ] + gtk_clipboard_set_text: "gtk_clipboard_set_text" [ + clipboard [handle!] + text [c-string!] + len [integer!] + ] + gtk_clipboard_set_image: "gtk_clipboard_set_image" [ + clipboard [handle!] + img [handle!] + ] + gtk_clipboard_wait_for_text: "gtk_clipboard_wait_for_text" [ + clipboard [handle!] + return: [c-string!] + ] + gtk_clipboard_wait_for_image: "gtk_clipboard_wait_for_image" [ + clipboard [handle!] + return: [handle!] + ] + ] + ] + + to-red-string: func [ + cstr [c-string!] + slot [red-value!] + return: [red-string!] + /local + str [red-string!] + size [integer!] + ][ + size: length? cstr + if null? slot [slot: stack/push*] + str: string/make-at slot size Latin1 + unicode/load-utf8-stream cstr size str null + str + ] + + read: func [ + return: [red-value!] + /local + clipboard [handle!] + str [c-string!] + ][ + clipboard: gtk_clipboard_get gdk_atom_intern_static_string "CLIPBOARD" + str: gtk_clipboard_wait_for_text clipboard + as red-value! to-red-string str null + ] + + write: func [ + data [red-value!] + return: [logic!] + /local + clipboard [handle!] + text [red-string!] + str [c-string!] + strlen [integer!] + ][ + clipboard: gtk_clipboard_get gdk_atom_intern_static_string "CLIPBOARD" + switch TYPE_OF(data) [ + TYPE_STRING [ + text: as red-string! data + strlen: -1 + str: unicode/to-utf8 text :strlen + gtk_clipboard_set_text clipboard str strlen + ] + TYPE_IMAGE [0] + default [0] + ] + true + ] + ] #default [ read: func [ return: [red-value!] @@ -231,5 +312,5 @@ clipboard: context [ ][ true ] - ] ;-- Linux... + ] ]] From cf2965cb12fe5e2cd67ef2ea326cff547857747f Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 24 Jul 2019 01:17:07 +0200 Subject: [PATCH 0109/3432] Reactivating tips fixing visible issue --- environment/console/GUI/gui-console.red | 3 ++- modules/view/backends/gtk3/gui.reds | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index be022d99c4..cb41f8b9ac 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -128,7 +128,7 @@ gui-console-ctx: context [ setup-faces: does [ console/pane: reduce [caret] - append win/pane reduce [console]; tips] + append win/pane reduce [console tips] win/menu: [ "File" [ "Run..." run-file @@ -208,6 +208,7 @@ gui-console-ctx: context [ console/init load-cfg win/visible?: yes + #if config/OS = 'Linux [tips/visible?: no] svs: system/view/screens/1 svs/pane: next svs/pane ;-- proctect itself from unview/all diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index ef67cbb12b..dfceb082f1 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -977,8 +977,7 @@ change-visible: func [ 0 ] true [ - ;; DEBUG: - print ["change-visible " widget " (type " get-symbol-name type "): " show? lf] + ;; DEBUG: print ["change-visible " widget " (type " get-symbol-name type "): " show? lf] gtk_widget_set_visible widget show? ] ] From 58a7dba1b8533eaf33e1d2e2490c2cb0813fcb36 Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 24 Jul 2019 16:29:18 +0200 Subject: [PATCH 0110/3432] Fix issue with invisible used for tips --- environment/console/GUI/gui-console.red | 1 - modules/view/backends/gtk3/events.reds | 3 +-- modules/view/backends/gtk3/gui.reds | 28 ++++++++++++++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index cb41f8b9ac..7d1bea3094 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -208,7 +208,6 @@ gui-console-ctx: context [ console/init load-cfg win/visible?: yes - #if config/OS = 'Linux [tips/visible?: no] svs: system/view/screens/1 svs/pane: next svs/pane ;-- proctect itself from unview/all diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 7112a7d120..d7accc2cc7 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -436,8 +436,6 @@ do-events: func [ ;@@ we use a global value to simulate it ;; DEBUG: print ["do-events no-wait? " no-wait? lf] - ;; Special initialisation of hidden widgets (cf gui.reds) - hide-invisible ;; Initially normally uncommented: the exit-loop is also decremented in destroy for supposed no-wait view! unless no-wait? [ @@ -568,6 +566,7 @@ post-quit-msg: func [ tm [float!] ][ exit-loop: exit-loop - 1 + if 0 = exit-loop [hide-invisible] ] ;;------------- centralize here connection handlers diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index dfceb082f1..20cb760bcc 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -616,8 +616,6 @@ adjust-sizes: func [ free as byte-ptr! rect ] - - remove-widget-timer: func [ widget [handle!] /local @@ -946,20 +944,30 @@ add-invisible: func [ list-invisible: g_list_prepend list-invisible widget ] +free-invisible: does [ + g_list_free list-invisible + list-invisible: as handle! 0 +] + hide-invisible: func [ /local - child [GList!] + child [GList!] + widget [handle!] + values [red-value!] + show? [red-logic!] ][ + ;; DEBUG: print ["hide-invisible" lf] if 0 = g_list_length list-invisible [exit] ;; DEBUG: print ["hide-invisible " g_list_length list-invisible lf] child: as GList! list-invisible while [not null? child][ - ;; DEBUG: print ["hide-invisible: " child/data lf] - gtk_widget_set_visible child/data no + widget: child/data + values: get-face-values widget + show?: as red-logic! values + FACE_OBJ_VISIBLE? + ;; DEBUG: print ["hide-invisible: " widget lf] + gtk_widget_set_visible widget show?/value child: child/next ] - g_list_free list-invisible - list-invisible: as handle! 0 ] change-visible: func [ @@ -979,6 +987,7 @@ change-visible: func [ true [ ;; DEBUG: print ["change-visible " widget " (type " get-symbol-name type "): " show? lf] gtk_widget_set_visible widget show? + gtk_widget_queue_draw widget ] ] ; gtk_widget_queue_draw widget @@ -1615,6 +1624,8 @@ OS-show-window: func [ gtk_widget_grab_focus as handle! widget face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] + ;; Deal with visible? facets + hide-invisible ] OS-make-view: func [ @@ -2079,7 +2090,8 @@ OS-update-view: func [ ;; update-view at least ask for this ;if main-window = widget [ - gtk_widget_queue_draw widget + + gtk_widget_queue_draw widget ;] int/value: 0 ;-- reset flags From 6c307db64db462a29bcaf49b444ff0ac783e9d94 Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 24 Jul 2019 16:40:56 +0200 Subject: [PATCH 0111/3432] free-invisible --- modules/view/backends/gtk3/events.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index d7accc2cc7..feee3318d2 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -565,8 +565,8 @@ post-quit-msg: func [ e [integer!] tm [float!] ][ + if 1 = exit-loop [free-invisible] exit-loop: exit-loop - 1 - if 0 = exit-loop [hide-invisible] ] ;;------------- centralize here connection handlers From ad207061054b975d0ad71d72a4db5303b3593f0a Mon Sep 17 00:00:00 2001 From: rcqls Date: Thu, 25 Jul 2019 01:29:04 +0200 Subject: [PATCH 0112/3432] Fix run-file in gui-console --- modules/view/backends/gtk3/comdlgs.reds | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 961ba36ec9..61a3b48c3a 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -48,8 +48,6 @@ _request-file: func [ set-type ret TYPE_FILE ] gtk_widget_destroy widget - ; This trick really matters to end the loop when in the red-console - while [gtk_events_pending][gtk_main_iteration] ret ] From 4c24dc43e50280094a087f556f8a823e58ed105e Mon Sep 17 00:00:00 2001 From: rcqls Date: Thu, 25 Jul 2019 08:07:08 +0200 Subject: [PATCH 0113/3432] Better implementation for dealing with visible? --- modules/view/backends/gtk3/events.reds | 1 - modules/view/backends/gtk3/gui.reds | 71 ++++++++++++++------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index feee3318d2..e7fd9b6d14 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -565,7 +565,6 @@ post-quit-msg: func [ e [integer!] tm [float!] ][ - if 1 = exit-loop [free-invisible] exit-loop: exit-loop - 1 ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 20cb760bcc..48501a3378 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -193,6 +193,13 @@ container?: func [ g_object_get_qdata widget gtk-container-id ] +real-container?: func [ + widget [handle!] + return: [handle!] +][ + g_object_get_qdata widget real-container-id +] + gtk-layout?: func [ type [integer!] return: [logic!] @@ -932,41 +939,38 @@ change-size: func [ ] -;; Special treatment for hidden (or invisible) widgets -;; that are hidden at the beginning of do-events as a first initialization - -list-invisible: as handle! 0 - -add-invisible: func [ +hide-invisible-all: func [ widget [handle!] + /local + child [handle!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] + show? [red-logic!] ][ - ;; DEBUG: print ["add invisible " widget lf] - list-invisible: g_list_prepend list-invisible widget -] + values: get-face-values widget + type: as red-word! values + FACE_OBJ_TYPE + pane: as red-block! values + FACE_OBJ_PANE + show?: as red-logic! values + FACE_OBJ_VISIBLE? -free-invisible: does [ - g_list_free list-invisible - list-invisible: as handle! 0 -] + sym: symbol/resolve type/symbol -hide-invisible: func [ - /local - child [GList!] - widget [handle!] - values [red-value!] - show? [red-logic!] -][ - ;; DEBUG: print ["hide-invisible" lf] - if 0 = g_list_length list-invisible [exit] - ;; DEBUG: print ["hide-invisible " g_list_length list-invisible lf] - child: as GList! list-invisible - while [not null? child][ - widget: child/data - values: get-face-values widget - show?: as red-logic! values + FACE_OBJ_VISIBLE? - ;; DEBUG: print ["hide-invisible: " widget lf] - gtk_widget_set_visible widget show?/value - child: child/next + gtk_widget_set_visible widget show?/value + + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + + while [face < tail][ + child: face-handle? face + unless null? child [ + hide-invisible-all child + ] + face: face + 1 + ] ] ] @@ -1621,11 +1625,11 @@ OS-show-window: func [ ;; DEBUG: print ["OS-show-window" as handle! widget "(" get-symbol-name get-widget-symbol as handle! widget ")" lf] if null? as handle! widget [exit] gtk_widget_show_all as handle! widget + ;; Deal with visible? facets + hide-invisible-all as handle! widget gtk_widget_grab_focus as handle! widget face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] - ;; Deal with visible? facets - hide-invisible ] OS-make-view: func [ @@ -1951,7 +1955,6 @@ OS-make-view: func [ change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym - unless show?/value [add-invisible widget] change-enabled widget enabled?/value sym make-styles-provider widget From d1d107b65a061054311064bd3bdf33b10b1d0d0d Mon Sep 17 00:00:00 2001 From: rcqls Date: Thu, 25 Jul 2019 12:39:38 +0200 Subject: [PATCH 0114/3432] Fix tab key for completion in gui-console --- environment/console/GUI/core.red | 2 +- modules/view/backends/gtk3/events.reds | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 3a6f7f77c4..c23b647f8f 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -803,7 +803,7 @@ object [ debug-print ["char: -" char "- " switch/default char [ #"^M" ["M"] #"^H" ["H"] #"^-" ["-"] - left ["left"] right ["right"] up ["up"] down ["down"] + left ["left"] right ["right"] up ["up"] down ["down"] insert ["insert"] delete ["delete"] #"^A" home ["home"] #"^E" end ["end"] #"^C" ["C"] #"^V" ["V"] #"^X" ["X"] #"^Z" ["Z"] #"^Y" ["Y"] #"^[" ["["] #"^~" ["~"] ;-- Ctrl + Backspace diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e7fd9b6d14..5ce049c1b5 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -545,7 +545,7 @@ translate-key: func [ keycode = FF50h [special?: yes RED_VK_HOME] keycode = FFE5h [special?: yes RED_VK_NUMLOCK] keycode = FF08h [special?: no RED_VK_BACK] - keycode = FF09h [special?: yes RED_VK_TAB] + keycode = FF09h [special?: no RED_VK_TAB] keycode = FFE1h [special?: yes RED_VK_LSHIFT] keycode = FFE2h [special?: yes RED_VK_RSHIFT] keycode = FFE3h [special?: yes RED_VK_LCONTROL] From e3f9444cc7d78084816608fc9a9cc18587d4fb1a Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 26 Jul 2019 10:54:18 +0200 Subject: [PATCH 0115/3432] Fix caret issue when first shown in gui-console --- environment/console/GUI/gui-console.red | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index 7d1bea3094..dd596743ba 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -207,6 +207,10 @@ gui-console-ctx: context [ view/flags/no-wait win [resize] ;-- create window instance console/init load-cfg + #if config/OS = 'Linux [ + ; A solution to fix the caret issue at the very beginning which did not occur after resizing (that calls the following line) + terminal/resize console/size + ] win/visible?: yes svs: system/view/screens/1 From 0d671e79cd0f850d4460300945d5b2fcf0612f13 Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 26 Jul 2019 14:17:32 +0200 Subject: [PATCH 0116/3432] Better solution for caret issue --- environment/console/GUI/core.red | 4 ++++ environment/console/GUI/gui-console.red | 4 ---- modules/view/backends/gtk3/gtk.reds | 10 ++++++++++ modules/view/backends/gtk3/gui.reds | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index c23b647f8f..42f62476b4 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -245,6 +245,10 @@ object [ caret/size/y: line-h if cfg/background [change theme/background cfg/background] if font/color [change theme/foreground font/color] + #if config/OS = 'Linux [ + ; since in Linux/GTK, no on-resizing when the window is first drawn + resize gui-console-ctx/console/size + ] adjust-console-size gui-console-ctx/console/size update-theme ] diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index dd596743ba..7d1bea3094 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -207,10 +207,6 @@ gui-console-ctx: context [ view/flags/no-wait win [resize] ;-- create window instance console/init load-cfg - #if config/OS = 'Linux [ - ; A solution to fix the caret issue at the very beginning which did not occur after resizing (that calls the following line) - terminal/resize console/size - ] win/visible?: yes svs: system/view/screens/1 diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index efa7b8226c..a15e275b93 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1142,11 +1142,21 @@ GPtrArray!: alias struct! [ window [handle!] mode [logic!] ] + gtk_window_resize: "gtk_window_resize" [ + window [handle!] + w [integer!] + h [integer!] + ] gtk_window_move: "gtk_window_move" [ window [handle!] x [integer!] y [integer!] ] + gtk_window_get_position: "gtk_window_get_position" [ + window [handle!] + x [int-ptr!] + y [int-ptr!] + ] gtk_window_present: "gtk_window_present" [ window [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 48501a3378..78d4a207c6 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -927,6 +927,7 @@ change-size: func [ either type = window [ ;; DEBUG: print ["change-size window: " size/x "x" size/y lf] gtk_window_set_default_size widget size/x size/y + gtk_window_resize widget size/x size/y gtk_widget_queue_draw widget ][ unless null? widget [ From 0b374caf1ebed64d7480a5e735d73797dad08d42 Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 26 Jul 2019 16:09:15 +0200 Subject: [PATCH 0117/3432] Fix reading offset for window --- environment/console/GUI/core.red | 1 + modules/view/backends/gtk3/gui.reds | 2 +- modules/view/backends/gtk3/handlers.reds | 11 ++++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 42f62476b4..7b4900961b 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -247,6 +247,7 @@ object [ if font/color [change theme/foreground font/color] #if config/OS = 'Linux [ ; since in Linux/GTK, no on-resizing when the window is first drawn + gui-console-ctx/console/size: cfg/win-size resize gui-console-ctx/console/size ] adjust-console-size gui-console-ctx/console/size diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 78d4a207c6..de823ffb32 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -895,7 +895,7 @@ change-offset: func [ ][ ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol widget " " widget " " pos/x "x" pos/y lf] either type = window [ - 0 + gtk_window_move widget pos/x pos/y ][ unless null? widget [ ;OS-refresh-window as integer! main-window diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 91d2354e86..899a255310 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -319,9 +319,18 @@ window-configure-event: func [ widget [handle!] event [GdkEventConfigure!] /local - sz [red-pair!] + sz [red-pair!] + offset [red-pair!] + x [integer!] + y [integer!] ][ ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] + + ; Set the offset when window is moved + offset: (as red-pair! get-face-values widget) + FACE_OBJ_OFFSET + x: 0 y: 0 gtk_window_get_position widget :x :y + offset/x: x offset/y: y + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size ; either any [event/width <> sz/x event/height <> sz/y] [ ; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ From 47be34ea2a90349209efe27b61975186963e12de Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 26 Jul 2019 20:41:56 +0200 Subject: [PATCH 0118/3432] Add in comment (OS-show-window) the attempt to fire configure-event to resize the window when first shown --- environment/console/GUI/core.red | 2 -- modules/view/backends/gtk3/gtk.reds | 3 +-- modules/view/backends/gtk3/gui.reds | 28 ++++++++++++++++++---------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 7b4900961b..20e505d0b4 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -284,7 +284,6 @@ object [ track [scroller/position - event/picked] wheel [ delta: event/picked - ;;;debug-print ["delta: " delta lf] case [ ;-- scroll by lines all [delta > -1.0 delta < 0.0][-1] all [delta > 0.0 delta < 1.0][1] @@ -294,7 +293,6 @@ object [ ] ] ][0] - ;;;debug-print ["n: " n lf] if n <> 0 [ scroll-lines n system/view/platform/redraw console diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a15e275b93..1b1bbf95ca 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -588,8 +588,7 @@ GPtrArray!: alias struct! [ return: [integer!] ] g_signal_emit_by_name: "g_signal_emit_by_name" [ - instance [int-ptr!] - signal [c-string!] + [variadic] ] g_object_ref: "g_object_ref" [ object [int-ptr!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index de823ffb32..f5b292ccee 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1621,16 +1621,24 @@ OS-show-window: func [ widget [integer!] /local face [red-object!] - ; auto-adjust? [red-logic!] -][ - ;; DEBUG: print ["OS-show-window" as handle! widget "(" get-symbol-name get-widget-symbol as handle! widget ")" lf] - if null? as handle! widget [exit] - gtk_widget_show_all as handle! widget - ;; Deal with visible? facets - hide-invisible-all as handle! widget - gtk_widget_grab_focus as handle! widget - face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED - if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] + event [GdkEventConfigure!] + type [integer!] +][ + unless null? as handle! widget [ + type: get-widget-symbol as handle! widget + ;; DEBUG: print ["OS-show-window " as handle! widget "(" get-symbol-name type ")" lf] + gtk_widget_show_all as handle! widget + ;; Deal with visible? facets + hide-invisible-all as handle! widget + gtk_widget_grab_focus as handle! widget + face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED + if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] + ; Just here as an attempt to fire a configure event + ; if type = window [ + ; event: declare GdkEventConfigure! + ; g_signal_emit_by_name [as handle! widget "configure-event" event] + ; ] + ] ] OS-make-view: func [ From 26e5d6aa25fe95b60e52c8df7480309d859c2fe1 Mon Sep 17 00:00:00 2001 From: rcqls Date: Sat, 27 Jul 2019 11:31:26 +0200 Subject: [PATCH 0119/3432] Fix selected font for request-font --- environment/console/GUI/gui-console.red | 2 +- modules/view/backends/gtk3/comdlgs.reds | 7 +++++++ modules/view/backends/gtk3/gtk.reds | 4 ++++ modules/view/backends/gtk3/gui.reds | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index 7d1bea3094..1b91574cba 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -47,7 +47,7 @@ gui-console-ctx: context [ scroller: make scroller! [] console: make face! [ - type: 'rich-text color: 0.0.128 offset: 0x0 size: 400x400 + type: 'rich-text color: 0.0.128 offset: 0x0 size: 200x200 flags: [scrollable all-over] options: [cursor: I-beam] menu: [ diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 61a3b48c3a..a8e83e5990 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -90,8 +90,14 @@ OS-request-font: func [ trait [integer!] bold? [logic!] resp [integer!] + fd-sel [handle!] ][ widget: gtk_font_chooser_dialog_new "Font" null + if all[TYPE_OF(selected) = TYPE_OBJECT][ + fd-sel: get-font-handle selected 0 + ;; DEBUG: print ["fd-sel: " pango_font_description_get_family fd-sel " " pango_font_description_get_size fd-sel lf] + gtk_font_chooser_set_font_desc widget fd-sel + ] resp: gtk_dialog_run widget ;; print ["resp: " resp lf] either resp = -5 [ @@ -120,6 +126,7 @@ OS-request-font: func [ word/make-at _italic as red-value! style ] ] + set-font-handle font fd ][ font/header: TYPE_NONE ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 1b1bbf95ca..6b0a5075f7 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1112,6 +1112,10 @@ GPtrArray!: alias struct! [ font-sel [handle!] return: [handle!] ] + gtk_font_chooser_set_font_desc: "gtk_font_chooser_set_font_desc" [ + font-sel [handle!] + font-desc [handle!] + ] gtk_init: "gtk_init" [ argc [int-ptr!] argv [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f5b292ccee..a8568e5561 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -866,7 +866,7 @@ change-font: func [ ; provider [handle!] hFont [handle!] ][ - ;; DEBUG: print ["change-font" lf] + ;; DEBUG: print ["change-font " widget " " get-symbol-name type lf] if TYPE_OF(font) <> TYPE_OBJECT [return no] ; provider: get-styles-provider widget From 8b0f671012ed08897dcd427e7016cd4c87c6f62c Mon Sep 17 00:00:00 2001 From: rcqls Date: Mon, 29 Jul 2019 10:33:12 +0200 Subject: [PATCH 0120/3432] Fix rich-text delegation event broken after scrolling addition --- modules/view/backends/gtk3/gui.reds | 22 ++++++++++++++++++++++ modules/view/backends/gtk3/handlers.reds | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a8568e5561..305147015d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -35,6 +35,7 @@ AppMainMenu: as handle! 0 red-face-id: g_quark_from_string "red-face-id" gtk-style-id: g_quark_from_string "gtk-style-id" _widget-id: g_quark_from_string "_widget-id" +real-widget-id: g_quark_from_string "real-widget-id" gtk-container-id: g_quark_from_string "gtk-container-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" @@ -179,6 +180,25 @@ get-widget-data: func [ as red-block! values + FACE_OBJ_DATA ] +;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) +set-real-widget: func [ + _widget [handle!] + widget [handle!] +][ + g_object_set_qdata _widget real-widget-id widget +] + +real-widget?: func [ + _widget [handle!] + return: [handle!] + /local + widget [handle!] +][ + widget: g_object_get_qdata _widget real-widget-id + if null? widget [widget: _widget] + return widget +] + set-container: func [ widget [handle!] container [handle!] @@ -1748,6 +1768,8 @@ OS-make-view: func [ widget: gtk_layout_new null null;gtk_drawing_area_new gtk_layout_set_size widget size/x size/y _widget: gtk_scrolled_window_new null null + set-real-widget _widget widget + ;; DEBUG: print ["rich-text _widget: " _widget lf] gtk_container_add _widget widget ] sym = window [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 899a255310..9a5b360883 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -861,7 +861,7 @@ container-emit-event: func [ ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit event " widget lf]] if all[x >= rect/x x <= (rect/x + rect/width) y >= rect/y y <= (rect/y + rect/height)][ ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit2 event " widget " event " evt/x "x" evt/y lf "widget size " rect/x "x" rect/y "x" rect/width "x" rect/height lf]] - gtk_widget_event widget event + gtk_widget_event real-widget? widget event ] free as byte-ptr! rect ] From 76552ec452c7c5a4d1e8c48814faf6f14b886611 Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 30 Jul 2019 04:23:15 +0200 Subject: [PATCH 0121/3432] Add facilit functions for super widget (_widget-id) --- modules/view/backends/gtk3/events.reds | 4 +--- modules/view/backends/gtk3/gui.reds | 33 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 5ce049c1b5..af1c7c0649 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -868,9 +868,7 @@ connect-notify-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print ["connect-notify-events " widget " " get-symbol-name sym lf]] unless null? widget [ - _widget: either sym = text [ - g_object_get_qdata widget _widget-id - ][widget] + _widget: either sym = text [_widget? widget][widget] if respond-mouse? widget ON_OVER [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print [ "connect-notifiy-events ON-OVER: " get-symbol-name sym "->" widget "(" _widget ")" lf]] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 305147015d..9a3f33e960 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -180,6 +180,25 @@ get-widget-data: func [ as red-block! values + FACE_OBJ_DATA ] +;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget +set-_widget: func [ + widget [handle!] + _widget [handle!] +][ + g_object_set_qdata widget _widget-id _widget +] + +_widget?: func [ + widget [handle!] + return: [handle!] + /local + _widget [handle!] +][ + _widget: g_object_get_qdata widget _widget-id + if null? _widget [_widget: widget] + return _widget +] + ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) set-real-widget: func [ _widget [handle!] @@ -474,8 +493,7 @@ debug-show-children: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 unless null? container [ - widget_: g_object_get_qdata child _widget-id - if null? widget_ [widget_: child] + widget_: _widget? child gtk_widget_get_allocation widget_ as handle! rect ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates @@ -620,8 +638,7 @@ adjust-sizes: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 if any [ox > offset/x not overlap?] [dx: 0] unless null? container [ - widget_: g_object_get_qdata child _widget-id - if null? widget_ [widget_: child] + widget_: _widget? child if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] gtk_layout_move container widget_ offset/x + dx offset/y gtk_widget_get_allocation widget_ as handle! rect @@ -925,8 +942,7 @@ change-offset: func [ ; g_object_get_qdata widget _widget-id ; ][widget] - _widget: g_object_get_qdata widget _widget-id - _widget: either null? _widget [widget][_widget] + _widget: _widget? widget unless null? container [ gtk_layout_move container _widget pos/x pos/y gtk_widget_queue_draw _widget @@ -951,8 +967,7 @@ change-size: func [ gtk_widget_queue_draw widget ][ unless null? widget [ - _widget: g_object_get_qdata widget _widget-id - _widget: either null? _widget [widget][_widget] + _widget: _widget? widget gtk_widget_set_size_request _widget size/x size/y unless null? _widget [gtk_widget_queue_resize _widget] ] @@ -1908,7 +1923,7 @@ OS-make-view: func [ parent <> 0 ][ p-sym: get-widget-symbol as handle! parent - either null? _widget [_widget: widget][g_object_set_qdata widget _widget-id _widget ] + either null? _widget [_widget: widget][set-_widget widget _widget ] ; TODO: case to replace with either if no more choice ;; DEBUG: print ["Parent: " get-symbol-name p-sym " _widget" _widget lf] case [ From cbb93a8e7d7459e1270b6ce07d525b32b275c93d Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 30 Jul 2019 05:15:20 +0200 Subject: [PATCH 0122/3432] update-z-order updated and renamed change-pane --- modules/view/backends/gtk3/gui.reds | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 9a3f33e960..3e7a7d700f 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -827,7 +827,7 @@ change-color: func [ ] ] -update-z-order: func [ +change-pane: func [ parent [handle!] pane [red-block!] type [integer!] @@ -835,6 +835,7 @@ update-z-order: func [ face [red-object!] tail [red-object!] widget [handle!] + _widget [handle!] nb [integer!] s [series!] values [red-value!] @@ -842,7 +843,7 @@ update-z-order: func [ list [GList!] child [GList!] ][ - ;; DEBUG: print ["update-z-order" lf] + ;; DEBUG: print ["change-pane " get-symbol-name type lf] if gtk-layout? type [ ;; this is for gtk_layout widget list: as GList! gtk_container_get_children parent @@ -867,13 +868,13 @@ update-z-order: func [ if TYPE_OF(face) = TYPE_OBJECT [ widget: face-handle? face if widget <> null [ + _widget: _widget? widget nb: nb + 1 - ;; DEBUG: print ["added widget" nb ": " widget " to " parent lf] - gtk_container_add parent widget + ;; DEBUG: print ["add widget" nb ": " widget "(" _widget ") to " parent lf] + gtk_container_add parent _widget values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - gtk_layout_move parent widget offset/x offset/y - g_object_unref widget + gtk_layout_move parent _widget offset/x offset/y ] ] face: face + 1 @@ -2109,8 +2110,7 @@ OS-update-view: func [ ] ] if all [flags and FACET_FLAG_PANE <> 0 type <> tab-panel][ - update-z-order widget as red-block! values + FACE_OBJ_PANE type - ;0 + change-pane widget as red-block! values + FACE_OBJ_PANE type ] if flags and FACET_FLAG_RATE <> 0 [ change-rate widget values + FACE_OBJ_RATE From 5c5415d4f739bc8c5cab67c71870e2577ca80d12 Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 31 Jul 2019 16:13:42 +0200 Subject: [PATCH 0123/3432] Deal with font and color for rich-text --- modules/view/backends/gtk3/draw.reds | 4 +- modules/view/backends/gtk3/font.reds | 51 ++++++++ modules/view/backends/gtk3/gtk.reds | 12 +- modules/view/backends/gtk3/gui.reds | 2 +- modules/view/backends/gtk3/text-box.reds | 146 +++++++++++++++-------- 5 files changed, 158 insertions(+), 57 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 32dd4d07c2..b2da687080 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -514,7 +514,7 @@ draw-text-box-lines: func [ lc: either TYPE_OF(tbox) = TYPE_OBJECT [ ;; DEBUG: print ["draw-text-box-lines: " as int-ptr! dc lf] ;-- text-box! - as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes + as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes ][ null ] @@ -561,7 +561,7 @@ draw-text-box: func [ len: -1 str: unicode/to-utf8 text :len - + ; default font-desc that can be overloaded in OS-text-box-layout called inside draw-text-box-lines dc/font-desc: pango_font_description_from_string gtk-font ;;TORM: dc/layout: make-pango-cairo-layout dc/raw dc/font-desc diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index e226fa147e..cc1df1174a 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -95,6 +95,7 @@ face-font?: func [ as red-object! (object/get-values face) + FACE_OBJ_FONT ] +;; IMPORTANT: Do not remove idx below (even if unused) since it is used in platform.red with this signature get-font-handle: func [ font [red-object!] idx [integer!] @@ -481,6 +482,19 @@ red-gtk-styles: func [ ] ] +font-color?: func [ + font [red-object!] + return: [integer!] + /local + values [red-value!] + color [red-tuple!] +][ + values: object/get-values font + color: as red-tuple! values + FONT_OBJ_COLOR + + color/array1 +] + ; move this to draw-ctx!? (used in draw-text-at) cairo-font-size: 10.0 ;-- used to find top line @@ -729,6 +743,43 @@ pango-cairo-set-text: func [ ] ] +;; A rewrite of pango_layout_set_markup but in red/system to control warning messages +;; with option force to avoid the warning when considering +pango-layout-set-markup: func [ + layout [handle!] + mtext [c-string!] + len [integer!] + force [logic!] + /local + status [logic!] + attrs-ptr [int-ptr!] + attrs [handle!] + ptext-ptr [int-ptr!] + ptext [c-string!] + accel [integer!] + error [handle!] +][ + unless null? layout [ + attrs-ptr: declare int-ptr! + ptext-ptr: declare int-ptr! + ;; DEBUG: print ["pango-layout-set-markup mtext: " mtext lf] + status: pango_parse_markup mtext len 0 attrs-ptr ptext-ptr null null + attrs: as handle! attrs-ptr/value + ptext: as c-string! ptext-ptr/value + ;; DEBUG: print ["pango-layout-set-markup ptext: " ptext lf] + either any[status force] [ + pango_layout_set_text layout ptext -1 + unless null? attrs [ + pango_layout_set_attributes layout attrs + pango_attr_list_unref attrs + ] + g_free as handle! ptext + ][ + pango_layout_set_text layout mtext -1 + ] + ] +] + pango-layout-context-set-text: func [ layout [handle!] dc [draw-ctx!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 6b0a5075f7..a725fdd01b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -806,8 +806,8 @@ GPtrArray!: alias struct! [ ] g_strsplit_set: "g_strsplit_set" [ str [c-string!] - delim [c-string!] - tokens [integer!] + delim [c-string!] + tokens [integer!] return: [handle!] ] g_free: "g_free" [ @@ -1931,11 +1931,15 @@ GPtrArray!: alias struct! [ accel_mark [integer!] accel_char [int-ptr!] ] - pango_layout_set_font_description: "pango_layout_set_font_description" [ + pango_layout_get_font_description: "pango_layout_get_font_description" [ + layout [handle!] + return: [handle!] + ] + pango_layout_set_font_description: "pango_layout_set_font_description" [ layout [handle!] fontdesc [handle!] ] - pango_layout_get_pixel_size: "pango_layout_get_pixel_size" [ + pango_layout_get_pixel_size: "pango_layout_get_pixel_size" [ layout [handle!] width [int-ptr!] height [int-ptr!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 3e7a7d700f..657f048824 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -56,7 +56,7 @@ _drag-on: symbol/make "drag-on" settings: as handle! 0 pango-context: as handle! 0 -gtk-font: "Sans 10" +gtk-font: "Sans 13" default-font: as handle! 0 ; Do not KNOW about this one diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 9ef480f9c7..97ed5ac434 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -76,23 +76,63 @@ pango-insert-tag: func [ lc/tag-list: g_list_insert_sorted lc/tag-list tag as-integer :pango-compare-tag ] -layout-ctx-begin: func [ +pango-append-open-tag: func [ + gstr [GString!] + ot [c-string!] +][ + g_string_append gstr "" + g_free as handle! ot +] + +layout-preamble?: func [ + gstr [GString!] + fd [handle!] + color [integer!] + /local + ot [c-string!] + rgba [c-string!] +][ + g_string_assign gstr "" + + ot: pango-open-tag-string? "face" pango_font_description_get_family fd + pango-append-open-tag gstr ot + + ot: pango-open-tag-int? "size" pango_font_description_get_size fd + pango-append-open-tag gstr ot + + rgba: int-to-bgra-hex color + ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] + + ot: pango-open-tag-string? "color" rgba + pango-append-open-tag gstr ot +] + +layout-postamble?: func [ + gstr [GString!] +][ + g_string_append gstr "" + g_string_append gstr "" + ;; DEBUG: print ["text: " lc/text lf] + ;; DEBUG: print ["text-markup: " text/str lf] +] + +layout-ctx-init: func [ lc [layout-ctx!] text [c-string!] text-len [integer!] /local - ot [c-string!] + gstr [GString!] ][ lc/closed-tags: null lc/text: text lc/text-len: text-len lc/text-pos: 0 lc/text-markup: as handle! g_string_sized_new PANGO_TEXT_MARKUP_SIZED - g_string_assign as GString! lc/text-markup "" lc/tag-list: null - - ot: pango-open-tag-string? lc "face" gtk-font - pango-insert-tag lc ot 0 text-len + gstr: as GString! lc/text-markup + g_string_assign gstr "" ] pango-add-open-tag: func [ @@ -107,14 +147,14 @@ pango-add-open-tag: func [ g_string_append_len gstr lc/text + lc/text-pos pos - lc/text-pos lc/text-pos: pos ] - g_string_append gstr "" - g_free as handle! open-tag + pango-append-open-tag gstr open-tag + ; g_string_append gstr "" + ; g_free as handle! open-tag ] pango-open-tag-string?: func [ - lc [layout-ctx!] attr-key [c-string!] attr-val [c-string!] return: [c-string!] @@ -127,7 +167,6 @@ pango-open-tag-string?: func [ ] pango-open-tag-int?: func [ - lc [layout-ctx!] attr-key [c-string!] attr-val [integer!] return: [c-string!] @@ -140,7 +179,6 @@ pango-open-tag-int?: func [ ] pango-open-tag-float?: func [ - lc [layout-ctx!] attr-key [c-string!] attr-val [float!] return: [c-string!] @@ -250,8 +288,10 @@ pango-process-tag: func [ pango-add-closed-tag lc pos + len ] -pango-markup-text: func [ +layout-ctx-do: func [ lc [layout-ctx!] + fd [handle!] + color [integer!] /local gl [GList!] last [GList!] @@ -259,14 +299,18 @@ pango-markup-text: func [ len [integer!] pos [integer!] opt [c-string!] - text [GString!] + gstr [GString!] ][ - unless null? lc/tag-list [ + gstr: as GString! lc/text-markup + ;; DEBUG: print ["layout-ctx-do layout: " lc/layout " " pango_font_description_get_family fd " " pango_font_description_get_size fd lf] + layout-preamble? gstr fd color + either null? lc/tag-list [ + g_string_append gstr lc/text + ][ last: as GList! g_list_last lc/tag-list gl: as GList! g_list_first lc/tag-list lc/text-pos: 0 lc/closed-tags: null - g_string_assign as GString! lc/text-markup "" until [ tag: as pango-opt-tag! gl/data ;; DEBUG: print [" at (" tag/pos "," tag/len ")" lf] @@ -276,21 +320,8 @@ pango-markup-text: func [ null? gl ] pango-close-tags lc -1 - ;; DEBUG: print ["Add " lf] - text: as GString! lc/text-markup - g_string_append text "" - ;; DEBUG: print ["text: " lc/text lf] - ;; DEBUG: print ["text-markup: " text/str lf] ] -] - -layout-ctx-end: func [ - lc [layout-ctx!] - /local - text [GString!] -][ - ; TODO: free everything not anymore used - pango-markup-text lc + layout-postamble? gstr ] int-to-rgba: func [ @@ -342,7 +373,7 @@ OS-text-box-color: func [ rgba: int-to-bgra-hex color ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] - ot: pango-open-tag-string? lc "color" rgba + ot: pango-open-tag-string? "color" rgba pango-insert-tag lc ot pos len ] @@ -362,7 +393,7 @@ OS-text-box-background: func [ rgba: int-to-bgra-hex color ;; DEBUG: print ["bgcol(" rgba ")[" pos "," pos + len - 1 "]" lf] - ot: pango-open-tag-string? lc "bgcolor" rgba + ot: pango-open-tag-string? "bgcolor" rgba pango-insert-tag lc ot pos len ] @@ -380,7 +411,7 @@ OS-text-box-weight: func [ ][ lc: as layout-ctx! layout - ot: pango-open-tag-int? lc "weight" weight pos len + ot: pango-open-tag-int? "weight" weight pos len pango-insert-tag lc ot pos len ] @@ -395,7 +426,7 @@ OS-text-box-italic: func [ ][ lc: as layout-ctx! layout - ot: pango-open-tag-string? lc "style" "italic" + ot: pango-open-tag-string? "style" "italic" pango-insert-tag lc ot pos len ] @@ -411,7 +442,7 @@ OS-text-box-underline: func [ ][ lc: as layout-ctx! layout - ot: pango-open-tag-string? lc "underline" "single" + ot: pango-open-tag-string? "underline" "single" pango-insert-tag lc ot pos len ] @@ -426,7 +457,7 @@ OS-text-box-strikeout: func [ ][ lc: as layout-ctx! layout - ot: pango-open-tag-string? lc "strikethrough" "true" + ot: pango-open-tag-string? "strikethrough" "true" pango-insert-tag lc ot pos len ] @@ -458,7 +489,7 @@ OS-text-box-font-name: func [ strlen: -1 str: unicode/to-utf8 name :strlen - ot: pango-open-tag-string? lc "face" str + ot: pango-open-tag-string? "face" str pango-insert-tag lc ot pos len ] @@ -474,7 +505,7 @@ OS-text-box-font-size: func [ ][ lc: as layout-ctx! layout - ot: pango-open-tag-int? lc "font" as integer! size + ot: pango-open-tag-int? "font" as integer! size pango-insert-tag lc ot pos len ] @@ -498,10 +529,13 @@ OS-text-box-metrics: func [ idx [integer!] trail [integer!] ok? [logic!] + ;; DEBUG: fd [handle!] ][ - ;; DEBUG: print ["OS-text-box-metrics: " type lf] + ;; DEBUG: print ["OS-text-box-metrics: " get-symbol-name type lf] rstate: as red-integer! block/rs-head state layout: as handle! rstate/value + ;; DEBUG: print ["layout: " layout lf] + ;; DEBUG: fd: pango_layout_get_font_description layout print ["OS-text-box-metrics layout: " layout " " pango_font_description_get_family fd " " pango_font_description_get_size fd lf] if null? layout [return as red-value! none-value] as red-value! switch type [ TBOX_METRICS_OFFSET? @@ -574,15 +608,16 @@ OS-text-box-layout: func [ lc [layout-ctx!] cached? [logic!] force? [logic!] - - font [handle!] + font [red-object!] + hFont [handle!] clr [integer!] text [red-string!] - len [integer!] + len [integer!] str [c-string!] pc [handle!] + ft-ok? [logic!] ][ - ;; DEBUG: print ["OS-text-box-layout: " box " target: " target lf] + ;; DEBUG: print ["OS-text-box-layout: " box " " face-handle? box " target: " target lf] values: object/get-values box state: as red-block! values + FACE_OBJ_EXT3 cached?: TYPE_OF(state) = TYPE_BLOCK @@ -597,11 +632,19 @@ OS-text-box-layout: func [ lc: declare layout-ctx! ; this is not dynamic but lc/layout would change dynamically for each rich-text text: as red-string! values + FACE_OBJ_TEXT + font: as red-object! values + FACE_OBJ_FONT + ft-ok?: TYPE_OF(font) = TYPE_OBJECT ;all[not null? target TYPE_OF(font) = TYPE_OBJECT] + hFont: default-font + if ft-ok? [ + hFont: get-font-handle font 0 + if null? hFont [hFont: default-font] + ] + len: -1 str: unicode/to-utf8 text :len - str: g_markup_escape_text str len + ;str: g_markup_escape_text str len - layout-ctx-begin lc str length? str + layout-ctx-init lc str length? str size: as red-pair! values + FACE_OBJ_SIZE @@ -614,11 +657,12 @@ OS-text-box-layout: func [ ; this is when OS-text-box-metrics is used before drawing if null? pango-context [pango-context: gdk_pango_context_get] lc/layout: pango_layout_new pango-context - ;; DEBUG: print ["rich-text layout: " lc/layout lf] - pango_layout_set_font_description lc/layout pango_font_description_from_string gtk-font ; needs to get the rich-text font + ;; DEBUG: print ["rich-text layout: " lc/layout " " pango_font_description_get_family hFont " " pango_font_description_get_size hFont lf] + pango_layout_set_font_description lc/layout hFont ] ][ dc: as draw-ctx! target + dc/font-desc: hFont lc/layout: make-pango-cairo-layout dc/raw dc/font-desc ;; DEBUG: print ["rich-text layout with target: " lc/layout lf] ] @@ -648,7 +692,8 @@ OS-text-box-layout: func [ ][ g_string_assign as GString! lc/text-markup lc/text ] - layout-ctx-end lc + pango_layout_set_font_description lc/layout hFont + layout-ctx-do lc hFont either ft-ok? [font-color? font][ft-clr] if null? target [ pango-layout-set-text lc size ] @@ -663,7 +708,8 @@ pango-layout-set-text: func [ ][ gstr: as GString! lc/text-markup ;; DEBUG: print ["pango-layout-set-text:<<-" gstr/str "->>" lf] - pango_layout_set_markup lc/layout gstr/str -1 + ;;pango_layout_set_markup lc/layout gstr/str -1 + pango-layout-set-markup lc/layout gstr/str -1 false pango_layout_set_width lc/layout PANGO_SCALE * size/x pango_layout_set_height lc/layout PANGO_SCALE * size/y pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR From 23b9c95837c6be34f06408d87d290e4fc14cf263 Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 31 Jul 2019 17:44:27 +0200 Subject: [PATCH 0124/3432] Forgot to escape to have & and < working --- modules/view/backends/gtk3/text-box.reds | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 97ed5ac434..7b784751ca 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -642,7 +642,7 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len - ;str: g_markup_escape_text str len + str: g_markup_escape_text str len layout-ctx-init lc str length? str @@ -714,7 +714,3 @@ pango-layout-set-text: func [ pango_layout_set_height lc/layout PANGO_SCALE * size/y pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR ] - -; pango-layout-styled-set-text: func [ - -; ] From e905a70d183e198f7bdf7a12435ff3cf1fa8aad9 Mon Sep 17 00:00:00 2001 From: rcqls Date: Thu, 1 Aug 2019 10:23:49 +0200 Subject: [PATCH 0125/3432] Fix gui-console font color --- modules/view/backends/gtk3/draw.reds | 1 + modules/view/backends/gtk3/gui.reds | 4 +- modules/view/backends/gtk3/text-box.reds | 89 ++++++++++++++++++++---- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index b2da687080..7d386b92dd 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -144,6 +144,7 @@ OS-draw-pen: func [ ;; THIS if DOES NOT WORK: ;; if dc/pen-color <> color [ dc/pen-color: color + dc/font-color: color ;; DEBUG: print ["set-source-color" lf] set-source-color dc/raw color ;;] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 657f048824..8c89c7c5cb 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -2104,10 +2104,10 @@ OS-update-view: func [ ] if flags and FACET_FLAG_COLOR <> 0 [ ;; DEBUG: print ["FACET_FLAG_COLOR " get-symbol-name type lf] - if type = base [ + ;;;if type = base [ ;; DEBUG: print ["FACET_FLAG_COLOR " widget lf] change-color widget as red-tuple! values + FACE_OBJ_COLOR type - ] + ;;;] ] if all [flags and FACET_FLAG_PANE <> 0 type <> tab-panel][ change-pane widget as red-block! values + FACE_OBJ_PANE type diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 7b784751ca..131c05599d 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -89,10 +89,8 @@ pango-append-open-tag: func [ layout-preamble?: func [ gstr [GString!] fd [handle!] - color [integer!] /local ot [c-string!] - rgba [c-string!] ][ g_string_assign gstr "" @@ -101,18 +99,12 @@ layout-preamble?: func [ ot: pango-open-tag-int? "size" pango_font_description_get_size fd pango-append-open-tag gstr ot - - rgba: int-to-bgra-hex color - ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] - - ot: pango-open-tag-string? "color" rgba - pango-append-open-tag gstr ot ] layout-postamble?: func [ gstr [GString!] ][ - g_string_append gstr "" + g_string_append gstr "" g_string_append gstr "" ;; DEBUG: print ["text: " lc/text lf] ;; DEBUG: print ["text-markup: " text/str lf] @@ -291,7 +283,6 @@ pango-process-tag: func [ layout-ctx-do: func [ lc [layout-ctx!] fd [handle!] - color [integer!] /local gl [GList!] last [GList!] @@ -303,7 +294,7 @@ layout-ctx-do: func [ ][ gstr: as GString! lc/text-markup ;; DEBUG: print ["layout-ctx-do layout: " lc/layout " " pango_font_description_get_family fd " " pango_font_description_get_size fd lf] - layout-preamble? gstr fd color + layout-preamble? gstr fd either null? lc/tag-list [ g_string_append gstr lc/text ][ @@ -693,7 +684,7 @@ OS-text-box-layout: func [ g_string_assign as GString! lc/text-markup lc/text ] pango_layout_set_font_description lc/layout hFont - layout-ctx-do lc hFont either ft-ok? [font-color? font][ft-clr] + layout-ctx-do lc hFont if null? target [ pango-layout-set-text lc size ] @@ -714,3 +705,77 @@ pango-layout-set-text: func [ pango_layout_set_height lc/layout PANGO_SCALE * size/y pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR ] + +; pango-layout-styled-set-text: func [ + +; ] + +comment { +append-text-and-seek: func [ + str + start + end + ][ + if end > start [ + g_string_append_len str start end - start + end: end + 1 + start: end + ] + ] + +g-markup-escape-text [ + text [c-string!] + leng [integer!] + /local + str [GString!] + [byte-ptr!] + pending [byte-ptr!] + end [byte-ptr!] +][ + GString *str; + + g_return_val_if_fail (text != NULL, NULL); + + if len < 0 [len: length? text] + + str: g_string_sized_new len + + p: = pending = text; + end = text + length; + + until [ + + switch (c) + { + case '&': + APPEND_TEXT_AND_SEEK (str, p, pending); + g_string_append (str, "&"); + break; + + case '<': + APPEND_TEXT_AND_SEEK (str, p, pending); + g_string_append (str, "<"); + break; + + ] + bar: bar + 1 + bar/1 = null-byte + + if (pending > p) + g_string_append_len (str, p, pending - p); + + + + + return g_string_free (str, FALSE); +} + + +until [ + print bar/1 + bar: bar + 1 + bar/1 = null-byte +] + + ] +} \ No newline at end of file From 9cfb5b7f8c7f0f5bf7cf47053d651b6ade8dbc9e Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 2 Aug 2019 06:23:40 +0200 Subject: [PATCH 0126/3432] Better escaping for rich-text --- modules/view/backends/gtk3/text-box.reds | 108 +++++++++-------------- 1 file changed, 40 insertions(+), 68 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 131c05599d..2a3629b227 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -633,7 +633,9 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len - str: g_markup_escape_text str len + str: g-markup-escape-text str len + ;;str: g_markup_escape_text str len + layout-ctx-init lc str length? str @@ -706,76 +708,46 @@ pango-layout-set-text: func [ pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR ] -; pango-layout-styled-set-text: func [ - -; ] - -comment { -append-text-and-seek: func [ - str - start - end - ][ - if end > start [ - g_string_append_len str start end - start - end: end + 1 - start: end - ] - ] - -g-markup-escape-text [ +;; g_markup_escape_text alternative to only escape & and < characters. +g-markup-escape-text: func [ text [c-string!] - leng [integer!] + len [integer!] + return: [c-string!] /local str [GString!] - [byte-ptr!] + p [byte-ptr!] pending [byte-ptr!] end [byte-ptr!] + c [byte!] ][ - GString *str; - - g_return_val_if_fail (text != NULL, NULL); - - if len < 0 [len: length? text] - - str: g_string_sized_new len - - p: = pending = text; - end = text + length; - - until [ - - switch (c) - { - case '&': - APPEND_TEXT_AND_SEEK (str, p, pending); - g_string_append (str, "&"); - break; - - case '<': - APPEND_TEXT_AND_SEEK (str, p, pending); - g_string_append (str, "<"); - break; - - ] - bar: bar + 1 - bar/1 = null-byte - - if (pending > p) - g_string_append_len (str, p, pending - p); - - - - - return g_string_free (str, FALSE); -} - - -until [ - print bar/1 - bar: bar + 1 - bar/1 = null-byte -] - - ] -} \ No newline at end of file + if len < 0 [len: length? text] + + str: g_string_sized_new len + + p: declare byte-ptr! + pending: declare byte-ptr! + end: declare byte-ptr! + + p: as byte-ptr! text + pending: as byte-ptr! text + end: p + len + + while [ all[p < end pending < end] ][ + ;; DEBUG: print ["pending: " pending/value " p: " p " pending: " pending " end: " end lf] + c: pending/value + switch c [ + #"&" #"<" [ + ; append inter text + g_string_append_len str as c-string! p as-integer pending - p + pending: pending + 1 + p: pending + ; append escaped text + g_string_append str either c = #"<" ["<"]["&"] + ] + default [pending: pending + 1] + ] + ] + if pending > p [g_string_append_len str as c-string! p as-integer pending - p] + ;; DEBUG: print ["str: " str/str lf] + g_string_free str false +] \ No newline at end of file From 7c20e5ba0b68b69a8a9ff2851e2e086d524f5cf4 Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 2 Aug 2019 14:13:58 +0200 Subject: [PATCH 0127/3432] Fix rich-text last part of text to append --- modules/view/backends/gtk3/text-box.reds | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 2a3629b227..c44136aaa6 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -243,8 +243,19 @@ pango-close-tags: func [ ] ] - ;; DEBUG: print ["size? lc/closed-tags: " g_list_length lc/closed-tags lf] - if all[ last? 0 < g_list_length lc/closed-tags] [pango-close-tags lc -1] + ;; DEBUG: print ["size? lc/closed-tags: " g_list_length lc/closed-tags " last?: " last? lf] + if last? [ + either 0 < g_list_length lc/closed-tags [ + pango-close-tags lc -1 + ][ + text-len: lc/text-len - lc/text-pos + ;; DEBUG: print ["pango-close-tags -> last append: (" text-len ")" lc/text + lc/text-pos lf] + if text-len > 0 [ + g_string_append_len gstr lc/text + lc/text-pos text-len + lc/text-pos: lc/text-pos + text-len + ] + ] + ] ] pango-process-closed-tags: func [ @@ -634,11 +645,13 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len str: g-markup-escape-text str len - ;;str: g_markup_escape_text str len + ;; OLD: str: g_markup_escape_text str len + ;; DEBUG: print ["OS-text-box-layout str: " str lf] - layout-ctx-init lc str length? str + ;; DEBUG: print ["OS-text-box-layout lc/text: " lc/text " " lc/text-len lf] + size: as red-pair! values + FACE_OBJ_SIZE either force? [ From c6c1ccd7473a6c7851f5c4621641e61ee0271dfd Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 2 Aug 2019 14:17:18 +0200 Subject: [PATCH 0128/3432] Add syntax highlighting for gui-console --- environment/console/GUI/core.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 20e505d0b4..677e1871b7 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -67,7 +67,7 @@ object [ scrolling: 0 scroll-pos: 0 - color?: no + color?: yes theme: #( foreground [0.0.0] background [252.252.252] From 48343c360e6658c138a6dc99d65a4ac59883e595 Mon Sep 17 00:00:00 2001 From: rcqls Date: Sat, 3 Aug 2019 09:05:42 +0200 Subject: [PATCH 0129/3432] Add delegator event for on-wheel --- modules/view/backends/gtk3/events.reds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index af1c7c0649..2c2ae14c3c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -852,6 +852,10 @@ connect-common-events: function [ if respond-mouse? widget ON_WHEEL [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON_WHEEL: " get-symbol-name sym "->" widget lf]] gtk_widget_add_events widget GDK_SCROLL_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "scroll-event" + ] gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) ] From b4d7091cd0c4217125240306a9b22f5e0799baaf Mon Sep 17 00:00:00 2001 From: rcqls Date: Sat, 3 Aug 2019 10:27:58 +0200 Subject: [PATCH 0130/3432] Escaping was made too early --- modules/view/backends/gtk3/gtk.reds | 5 ++ modules/view/backends/gtk3/text-box.reds | 71 ++++++++---------------- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a725fdd01b..75fb370bf2 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -819,6 +819,11 @@ GPtrArray!: alias struct! [ g_string_new: "g_string_new" [ return: [GString!] ] + g_string_new_len: "g_string_new_len" [ + text [c-string!] + len [integer!] + return: [GString!] + ] g_string_sized_new: "g_string_sized_new" [ dfl_size [integer!] return: [GString!] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index c44136aaa6..71bf6dfdc5 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -136,7 +136,7 @@ pango-add-open-tag: func [ ][ gstr: as GString! lc/text-markup if lc/text-pos < pos [ ; add text until pos - g_string_append_len gstr lc/text + lc/text-pos pos - lc/text-pos + g-string-append-len gstr lc/text + lc/text-pos pos - lc/text-pos lc/text-pos: pos ] pango-append-open-tag gstr open-tag @@ -229,7 +229,7 @@ pango-close-tags: func [ text-len: text-len - lc/text-pos ;; DEBUG: print ["pango-close-tags -> append: (" text-len ")" lc/text + lc/text-pos lf] if text-len > 0 [ - g_string_append_len gstr lc/text + lc/text-pos text-len + g-string-append-len gstr lc/text + lc/text-pos text-len lc/text-pos: lc/text-pos + text-len ] if 0 < g_list_length lc/closed-tags [ @@ -251,7 +251,7 @@ pango-close-tags: func [ text-len: lc/text-len - lc/text-pos ;; DEBUG: print ["pango-close-tags -> last append: (" text-len ")" lc/text + lc/text-pos lf] if text-len > 0 [ - g_string_append_len gstr lc/text + lc/text-pos text-len + g-string-append-len gstr lc/text + lc/text-pos text-len lc/text-pos: lc/text-pos + text-len ] ] @@ -307,7 +307,7 @@ layout-ctx-do: func [ ;; DEBUG: print ["layout-ctx-do layout: " lc/layout " " pango_font_description_get_family fd " " pango_font_description_get_size fd lf] layout-preamble? gstr fd either null? lc/tag-list [ - g_string_append gstr lc/text + g_string_append gstr g_markup_escape_text lc/text lc/text-len ][ last: as GList! g_list_last lc/tag-list gl: as GList! g_list_first lc/tag-list @@ -644,9 +644,6 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len - str: g-markup-escape-text str len - ;; OLD: str: g_markup_escape_text str len - ;; DEBUG: print ["OS-text-box-layout str: " str lf] layout-ctx-init lc str length? str @@ -721,46 +718,24 @@ pango-layout-set-text: func [ pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR ] -;; g_markup_escape_text alternative to only escape & and < characters. -g-markup-escape-text: func [ - text [c-string!] - len [integer!] - return: [c-string!] +g-markup-escape-text-len: func [ + text [c-string!] + text-len [integer!] + return: [c-string!] /local - str [GString!] - p [byte-ptr!] - pending [byte-ptr!] - end [byte-ptr!] - c [byte!] -][ - if len < 0 [len: length? text] - - str: g_string_sized_new len - - p: declare byte-ptr! - pending: declare byte-ptr! - end: declare byte-ptr! - - p: as byte-ptr! text - pending: as byte-ptr! text - end: p + len - - while [ all[p < end pending < end] ][ - ;; DEBUG: print ["pending: " pending/value " p: " p " pending: " pending " end: " end lf] - c: pending/value - switch c [ - #"&" #"<" [ - ; append inter text - g_string_append_len str as c-string! p as-integer pending - p - pending: pending + 1 - p: pending - ; append escaped text - g_string_append str either c = #"<" ["<"]["&"] - ] - default [pending: pending + 1] - ] - ] - if pending > p [g_string_append_len str as c-string! p as-integer pending - p] - ;; DEBUG: print ["str: " str/str lf] - g_string_free str false + gstr [GString!] +][ + gstr: g_string_new_len text text-len + g_markup_escape_text g_string_free gstr false text-len +] + +g-string-append-len: func [ + gstr [GString!] + text [c-string!] + text-len [integer!] + /local + str [c-string!] +][ + str: g-markup-escape-text-len text text-len + g_string_append gstr str ] \ No newline at end of file From ce116acd2a82bd253b2de5052bb346a147c29df5 Mon Sep 17 00:00:00 2001 From: rcqls Date: Mon, 5 Aug 2019 07:19:51 +0200 Subject: [PATCH 0131/3432] Fix wrap mode for are --- modules/view/backends/gtk3/para.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/para.reds b/modules/view/backends/gtk3/para.reds index 50c419f4fe..33f7bc2e68 100644 --- a/modules/view/backends/gtk3/para.reds +++ b/modules/view/backends/gtk3/para.reds @@ -200,7 +200,7 @@ get-para-flags: func [ h-def: left - if all [wrap? type = text][ + if all[wrap? type <> field][ flags: 00010000h ;-- SS_ENDELLIPSIS ] ] From 0b3224388c8eac644415652908b073b9ef01b2ef Mon Sep 17 00:00:00 2001 From: rcqls Date: Tue, 6 Aug 2019 09:34:30 +0200 Subject: [PATCH 0132/3432] Fix the issue of initial size of window --- modules/view/backends/gtk3/events.reds | 2 +- modules/view/backends/gtk3/gtk.reds | 8 ++++++ modules/view/backends/gtk3/gui.reds | 32 ++++++++++++------------ modules/view/backends/gtk3/handlers.reds | 6 +++-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 2c2ae14c3c..5b78b67fb4 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -114,12 +114,12 @@ get-event-offset: func [ evt/type = EVT_SIZING evt/type = EVT_SIZE ][ - ;; DEBUG: print ["event-offset type: " get-symbol-name get-widget-symbol widget lf] offset: as red-pair! stack/push* offset/header: TYPE_PAIR widget: as handle! evt/msg sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + ;; DEBUG: print ["event-offset type: " get-symbol-name get-widget-symbol widget " size: " sz/x "x" sz/y lf] ; sz/x: evt-sizing/x_new ; sz/y: evt-sizing/y_new diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 75fb370bf2..f8f2644091 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1155,6 +1155,14 @@ GPtrArray!: alias struct! [ w [integer!] h [integer!] ] + gtk_window_set_decorated: "gtk_window_set_decorated" [ + window [handle!] + mode [logic!] + ] + gtk_window_set_deletable: "gtk_window_set_deletable" [ + window [handle!] + mode [logic!] + ] gtk_window_move: "gtk_window_move" [ window [handle!] x [integer!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8c89c7c5cb..25dc8e06b9 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1659,21 +1659,19 @@ OS-show-window: func [ face [red-object!] event [GdkEventConfigure!] type [integer!] + size [red-pair!] + hWnd [handle!] ][ - unless null? as handle! widget [ - type: get-widget-symbol as handle! widget + hWnd: as handle! widget + unless null? hWnd [ + type: get-widget-symbol hWnd ;; DEBUG: print ["OS-show-window " as handle! widget "(" get-symbol-name type ")" lf] - gtk_widget_show_all as handle! widget + gtk_widget_show_all hWnd ;; Deal with visible? facets - hide-invisible-all as handle! widget - gtk_widget_grab_focus as handle! widget - face: (as red-object! get-face-values as handle! widget) + FACE_OBJ_SELECTED + hide-invisible-all hWnd + gtk_widget_grab_focus hWnd + face: (as red-object! get-face-values hWnd) + FACE_OBJ_SELECTED if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] - ; Just here as an attempt to fire a configure event - ; if type = window [ - ; event: declare GdkEventConfigure! - ; g_signal_emit_by_name [as handle! widget "configure-event" event] - ; ] ] ] @@ -1804,10 +1802,8 @@ OS-make-view: func [ ;; DEBUG: print ["Creation of Modal window" lf] gtk_window_set_modal widget yes ] - gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) unless null? caption [gtk_window_set_title widget caption] - ;; DEBUG: print ["make-view: set_default_size " size/x "x" size/y lf] - gtk_window_set_default_size widget size/x size/y + winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox if all [ ;@@ application menu ? @@ -1826,6 +1822,12 @@ OS-make-view: func [ g_object_set_qdata widget real-container-id container ;; DEBUG: print ["window is " widget " real container is " container lf] gtk_window_move widget offset/x offset/y + + ;; The following line really matters to fix the initial size of the window + gtk_widget_set_size_request widget size/x size/y + gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) + gtk_window_set_decorated widget (bits and FACET_FLAGS_NO_BORDER = 0) + ] sym = slider [ vertical?: size/y > size/x @@ -2001,7 +2003,6 @@ OS-make-view: func [ change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym - change-enabled widget enabled?/value sym make-styles-provider widget @@ -2016,7 +2017,6 @@ OS-make-view: func [ change-color widget as red-tuple! values + FACE_OBJ_COLOR sym ;; USELESS: if sym <> window [gtk_widget_show widget] - stack/unwind as-integer widget ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 9a5b360883..43a0e93cdf 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -224,7 +224,7 @@ base-draw: func [ DC [draw-ctx! value] drawDC [draw-ctx!] ][ - ;; DEBUG: print ["base-draw " widget lf] + ;; DEBUG: print ["base-draw " widget " " gtk_widget_get_allocated_width widget "x" gtk_widget_get_allocated_height widget lf] vals: get-node-values ctx img: as red-image! vals + FACE_OBJ_IMAGE @@ -329,6 +329,7 @@ window-configure-event: func [ ; Set the offset when window is moved offset: (as red-pair! get-face-values widget) + FACE_OBJ_OFFSET x: 0 y: 0 gtk_window_get_position widget :x :y + ;; DEBUG: print ["offset: " x "x" y lf] offset/x: x offset/y: y sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size @@ -363,11 +364,12 @@ window-size-allocate: func [ /local sz [red-pair!] ][ - ;; DEBUG: print ["window-size-allocate" lf] + ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size if any [rect/width <> sz/x rect/height <> sz/y] [ evt-sizing/x_new: rect/width evt-sizing/y_new: rect/height + ;; DEBUG: print ["sz: " sz/x "x" sz/y " -> " evt-sizing/x_new "x" evt-sizing/y_new lf] sz/x: evt-sizing/x_new sz/y: evt-sizing/y_new ;; DEBUG: print ["window-size-allocate: " evt-sizing/x_root "x" evt-sizing/y_root lf] From 9f399c4d24bfb5a18232b878eeed50e2f2d8e9cb Mon Sep 17 00:00:00 2001 From: rcqls Date: Wed, 7 Aug 2019 07:45:14 +0200 Subject: [PATCH 0133/3432] Save image for jpeg png and bmp --- environment/codecs/bmp.red | 2 +- environment/codecs/jpeg.red | 2 +- environment/codecs/png.red | 2 +- runtime/platform/image-gdk.reds | 55 +++++++++++++++++---------------- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/environment/codecs/bmp.red b/environment/codecs/bmp.red index 90cb012159..e253963892 100644 --- a/environment/codecs/bmp.red +++ b/environment/codecs/bmp.red @@ -17,7 +17,7 @@ put system/codecs 'bmp context [ suffixes: [%.bmp] encode: routine [img [image!] where [any-type!]][ - #if not find [Android Linux FreeBSD Syllabe] OS [ + #if not find [Android FreeBSD Syllabe] OS [ stack/set-last as cell! image/encode img where IMAGE_BMP ] ] diff --git a/environment/codecs/jpeg.red b/environment/codecs/jpeg.red index 851545c457..3e2298e59b 100644 --- a/environment/codecs/jpeg.red +++ b/environment/codecs/jpeg.red @@ -17,7 +17,7 @@ put system/codecs 'jpeg context [ suffixes: [%.jpg %.jpeg %.jpe %.jfif] encode: routine [img [image!] where [any-type!]][ - #if not find [Android Linux FreeBSD Syllabe] OS [ + #if not find [Android FreeBSD Syllabe] OS [ stack/set-last as cell! image/encode img where IMAGE_JPEG ] ] diff --git a/environment/codecs/png.red b/environment/codecs/png.red index 6cebe82f40..011ee310ce 100644 --- a/environment/codecs/png.red +++ b/environment/codecs/png.red @@ -17,7 +17,7 @@ put system/codecs 'png context [ suffixes: [%.png] encode: routine [img [image!] where [any-type!]][ - #if not find [Android Linux FreeBSD Syllabe] OS [ + #if not find [Android FreeBSD Syllabe] OS [ stack/set-last as cell! image/encode img where IMAGE_PNG ] ] diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 02cc76c440..5211983d9d 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -17,6 +17,11 @@ Red/System [ GDK_COLORSPACE_RGB ] +GError!: alias struct! [ + domain [integer!] + code [integer!] + message [c-string!] +] ; bgra-to-rgba: func [ ; color [integer!] ; return: [integer!] @@ -211,6 +216,10 @@ OS-image: context [ err [handle!] return: [logic!] ] + gdk_pixbuf_save: "gdk_pixbuf_save" [ + [variadic] + return: [logic!] + ] g_object_unref: "g_object_unref" [ obj [handle!] ] @@ -769,37 +778,31 @@ OS-image: context [ format [integer!] return: [red-value!] /local - type [integer!] - path [integer!] - dst [integer!] - img [int-ptr!] + type [c-string!] + path [c-string!] + pixbuf [handle!] + err [GError!] ][ - ;; DEBUG: print ["encode" lf] + err: declare GError! switch format [ - IMAGE_BMP [probe "type: kUTTypeBMP"] - IMAGE_PNG [probe "type: kUTTypePNG"] - IMAGE_GIF [probe "type: kUTTypeGIF"] - IMAGE_JPEG [probe "type: kUTTypeJPEG"] - IMAGE_TIFF [probe "type: kUTTypeTIFF"] + IMAGE_BMP [type: "bmp"] + IMAGE_PNG [type: "png"] + ;IMAGE_GIF [type: "gif"] + IMAGE_JPEG [type: "jpeg"] + IMAGE_TIFF [type: "tiff"] default [probe "Cannot find image encoder" return null] ] - img: to-pixbuf image - ; switch TYPE_OF(slot) [ - ; TYPE_URL - ; TYPE_FILE [ - ; path: simple-io/to-NSURL as red-string! slot yes - ; dst: CGImageDestinationCreateWithURL path type 1 0 - ; ;if zero? dst [] ;-- error - ; CGImageDestinationAddImage dst img 0 - ; unless CGImageDestinationFinalize dst [ - ; 0 ;-- error - ; ] - ; CFRelease path - ; CFRelease dst - ; ] - ; default [0] - ; ] + ;; DEBUG: print ["encode: " type lf] + pixbuf: to-pixbuf image + switch TYPE_OF(slot) [ + TYPE_URL + TYPE_FILE [ + path: file/to-OS-path as red-string! slot + gdk_pixbuf_save [pixbuf path type err null] + ] + default [0] + ] slot ] From 9dc4c398353fb6dd2880015a52b90975766ef884 Mon Sep 17 00:00:00 2001 From: qtxie Date: Thu, 8 Aug 2019 16:36:23 +0200 Subject: [PATCH 0134/3432] FEAT: now we can use libRedRT when developing view backend --- environment/datatypes.red | 4 ++-- system/utils/libRedRT-exports.r | 5 +++++ tests/gtk3/vid.red | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/environment/datatypes.red b/environment/datatypes.red index e7d0bce3e5..3f8eeb74bf 100644 --- a/environment/datatypes.red +++ b/environment/datatypes.red @@ -61,9 +61,9 @@ handle!: make datatype! #get-definition TYPE_HANDLE date!: make datatype! #get-definition TYPE_DATE port!: make datatype! #get-definition TYPE_PORT -#if find config/modules 'view [ +;#if find config/modules 'view [ event!: make datatype! #get-definition TYPE_EVENT -] +;] none: make none! 0 true: make logic! 1 diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index 57064ee313..87f706d106 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -14,6 +14,7 @@ red/eval-path red/select-key* red/alloc-bytes + red/alloc-cells red/get-cmdline-args red/redbin/boot-load @@ -374,7 +375,11 @@ red/natives/context?* red/natives/decompress* red/natives/recycle* + + ;-- for view backend + red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/ownership/bind red/integer/make-at red/string/load red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set ][ + red/root red-block! red/object/path-parent cell! red/object/field-parent cell! red/stack/arguments cell! diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red index 023803a930..a3c142f62e 100644 --- a/tests/gtk3/vid.red +++ b/tests/gtk3/vid.red @@ -4,6 +4,7 @@ Red [ File: %vid.red Needs: 'View ] + system/view/debug?: no ;yes view [ From 3aabd45b10d920390e567433afc2d18cbfbddef4 Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 9 Aug 2019 10:08:04 +0200 Subject: [PATCH 0135/3432] fix ctrl? for EVT_WHEEL and starting on to-image --- environment/console/GUI/core.red | 6 ++-- modules/view/backends/gtk3/events.reds | 13 +++---- modules/view/backends/gtk3/gtk.reds | 38 ++++++++++++++++++-- modules/view/backends/gtk3/gui.reds | 44 +++++++++++++----------- modules/view/backends/gtk3/handlers.reds | 9 ++++- 5 files changed, 77 insertions(+), 33 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 53e167947c..11f1cac4a3 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -252,8 +252,10 @@ object [ if font/color [change theme/foreground font/color] #if config/OS = 'Linux [ ; since in Linux/GTK, no on-resizing when the window is first drawn - gui-console-ctx/console/size: cfg/win-size - resize gui-console-ctx/console/size + if cfg [ + gui-console-ctx/console/size: cfg/win-size + resize gui-console-ctx/console/size + ] ] adjust-console-size gui-console-ctx/console/size update-theme diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 5b78b67fb4..ed19062ccc 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -256,10 +256,9 @@ get-event-picked: func [ evt [red-event!] return: [red-value!] /local - res [red-value!] - int [red-integer!] - pct [red-float!] - zd [float!] + res [red-value!] + int [red-integer!] + event [GdkEventScroll!] ][ as red-value! switch evt/type [ EVT_ZOOM @@ -276,7 +275,8 @@ get-event-picked: func [ ] ] EVT_WHEEL [ - float/push as-float evt/flags / 10000.0 + event: as GdkEventScroll! g_object_get_qdata as handle! evt/msg red-event-id + float/push event/delta_y ] EVT_MENU [word/push* evt/flags and FFFFh] default [integer/push evt/flags and FFFFh] @@ -289,7 +289,7 @@ get-event-flags: func [ /local blk [red-block!] ][ - ;; DEBUG: print ["get-event-flags: " evt/flags lf] + ;; DEBUG: print ["get-event-flags " lf] blk: flags-blk block/rs-clear blk if evt/flags and EVT_FLAG_AWAY <> 0 [block/rs-append blk as red-value! _away] @@ -307,6 +307,7 @@ get-event-flag: func [ flag [integer!] return: [red-value!] ][ + ;; DEBUG: print ["get-event-flag " flags and flag <> 0 lf] as red-value! logic/push flags and flag <> 0 ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index f8f2644091..8a937723cb 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -632,6 +632,10 @@ GPtrArray!: alias struct! [ gdk_screen_get_default: "gdk_screen_get_default" [ return: [handle!] ] + gdk_screen_get_root_window: "gdk_screen_get_root_window" [ + screen [handle!] + return: [handle!] + ] gdk_keymap_get_default: "gdk_keymap_get_default" [ return: [handle!] ] @@ -666,6 +670,15 @@ GPtrArray!: alias struct! [ display [handle!] return: [handle!] ] + gdk_x11_window_get_xid: "gdk_x11_window_get_xid" [ + win [handle!] + return: [integer!] + ] + gdk_x11_window_foreign_new_for_display: "gdk_x11_window_foreign_new_for_display" [ + display [handle!] + xwin [integer!] + return: [handle!] + ] gtk_clipboard_get: "gtk_clipboard_get" [ atom [handle!] return: [handle!] @@ -1227,6 +1240,10 @@ GPtrArray!: alias struct! [ widget [handle!] event [handle!] ] + gtk_widget_get_window: "gtk_widget_get_window" [ + widget [handle!] + return: [handle!] + ] gtk_widget_register_window: "gtk_widget_register_window" [ widget [handle!] window [handle!] @@ -1307,6 +1324,10 @@ GPtrArray!: alias struct! [ widget [handle!] return: [logic!] ] + gtk_widget_is_drawable: "gtk_widget_is_drawable" [ + widget [handle!] + return: [logic!] + ] gtk_widget_set_sensitive: "gtk_widget_set_sensitive" [ widget [handle!] state [logic!] @@ -2539,9 +2560,9 @@ GPtrArray!: alias struct! [ ] gdk_pixbuf_get_from_window: "gdk_pixbuf_get_from_window" [ window [handle!] - src_x [integer!] - src_y [integer!] - width [integer!] + src_x [integer!] + src_y [integer!] + width [integer!] height [integer!] return: [handle!] ] @@ -2549,6 +2570,17 @@ GPtrArray!: alias struct! [ pixbuf [handle!] return: [integer!] ] + gdk_get_default_root_window: "gdk_get_default_root_window" [ + return: [handle!] + ] + gdk_window_get_width: "gdk_window_get_width" [ + win [handle!] + return: [integer!] + ] + gdk_window_get_height: "gdk_window_get_height" [ + win [handle!] + return: [integer!] + ] ;; Useless since already called inside pango_cairo_create_context ; pango_cairo_font_map_get_default: "pango_cairo_font_map_get_default" [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 25dc8e06b9..7f7e3904c3 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -44,6 +44,7 @@ real-container-id: g_quark_from_string "real-container-id" menu-id: g_quark_from_string "menu-id" drag-id: g_quark_from_string "drag-id" no-wait-id: g_quark_from_string "no-wait-id" +red-event-id: g_quark_from_string "red-event-id" group-radio: as handle! 0 tabs: context [ @@ -182,7 +183,7 @@ get-widget-data: func [ ;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget set-_widget: func [ - widget [handle!] + widget [handle!] _widget [handle!] ][ g_object_set_qdata widget _widget-id _widget @@ -2262,13 +2263,11 @@ OS-to-image: func [ return: [red-image!] /local widget [handle!] - dc [handle!] - mdc [handle!] + win [handle!] + xwin [integer!] width [integer!] height [integer!] - bmp [handle!] - bitmap [integer!] - img [red-image!] + pixbuf [handle!] word [red-word!] type [integer!] size [red-pair!] @@ -2278,27 +2277,30 @@ OS-to-image: func [ type: symbol/resolve word/symbol ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] - + case [ type = screen [ - ; get pixbuf from screen_root_window - bmp: as handle! 0;gdk_pixbuf_get_from_window gdk_screen_get_root_window gdk_screen_get_default 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp + win: gdk_get_default_root_window + xwin: gdk_x11_window_get_xid win + win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin + pixbuf: gdk_pixbuf_get_from_window win 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf ] true [ widget: face-handle? face + ;; DEBUG: print ["widget: " widget lf] either null? widget [ret: as red-image! none-value][ - size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE - ; rc: make-rect 0 0 sz/x sz/y - ; data: objc_msgSend [view sel_getUid "dataWithPDFInsideRect:" rc/x rc/y rc/w rc/h] - ; img: objc_msgSend [ - ; objc_msgSend [objc_getClass "NSImage" sel_alloc] - ; sel_getUid "initWithData:" data - ; ] - bmp: as handle! 0; objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf bmp - ; objc_msgSend [bmp sel_getUid "retain"] - ; objc_msgSend [img sel_release] + either gtk_window_is_active main-window [ + size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE + win: gtk_widget_get_window widget + ;; DEBUG: print ["win: " win " size: " size/x "x" size/y lf] + pixbuf: gdk_pixbuf_get_from_window win 0 0 size/x size/y + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + ;g_object_unref pixbuf + ][ + print ["Red/GTK warning: to-image not yet implemented when window is not active!"] + ret: as red-image! none-value + ] ] ] ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 43a0e93cdf..1e9d5ea581 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -1050,7 +1050,14 @@ widget-scroll-event: func [ event [GdkEventScroll!] ctx [node!] return: [integer!] + /local + state [integer!] ][ ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] - make-event widget as-integer (event/delta_y * 10000) EVT_WHEEL + state: 0 + g_object_set_qdata widget red-event-id as handle! event + if any[event/delta_y < -0.01 event/delta_y > 0.01][ + state: make-event widget check-down-flags event/state EVT_WHEEL + ] + state ] From 8be342ed0689cc0210be00c5b04ec15a02c3922a Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 9 Aug 2019 15:05:09 +0200 Subject: [PATCH 0136/3432] Fix issue about bad caret position for gui-console when big font --- environment/console/GUI/gui-console.red | 1 + 1 file changed, 1 insertion(+) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index 07d68d2150..85ec571256 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -214,6 +214,7 @@ gui-console-ctx: context [ console/init load-cfg win/visible?: yes + #if config/OS = 'Linux [terminal/update-cfg font none] svs: system/view/screens/1 svs/pane: next svs/pane ;-- proctect itself from unview/all From 1e11dc3342350666ea004b431e2476bab9612ead Mon Sep 17 00:00:00 2001 From: rcqls Date: Fri, 9 Aug 2019 19:27:23 +0200 Subject: [PATCH 0137/3432] to-image was crashing on gui-console --- modules/view/backends/gtk3/gtk.reds | 4 +++ modules/view/backends/gtk3/gui.reds | 41 ++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 8a937723cb..28dddc0208 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1138,6 +1138,10 @@ GPtrArray!: alias struct! [ argc [int-ptr!] argv [handle!] ] + gdk_init: "gdk_init" [ + argc [int-ptr!] + argv [handle!] + ] gtk_main: "gtk_main" [] gtk_main_quit: "gtk_main_quit" [] gtk_main_iteration: "gtk_main_iteration" [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7f7e3904c3..2338e71f05 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -37,6 +37,7 @@ gtk-style-id: g_quark_from_string "gtk-style-id" _widget-id: g_quark_from_string "_widget-id" real-widget-id: g_quark_from_string "real-widget-id" gtk-container-id: g_quark_from_string "gtk-container-id" +parent-window-id: g_quark_from_string "parent-window-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" @@ -200,6 +201,22 @@ _widget?: func [ return _widget ] +set-parent-window: func [ + widget [handle!] + window [handle!] +][ + g_object_set_qdata widget parent-window-id window +] + +parent-window?: func [ + widget [handle!] + return: [handle!] + /local + window [handle!] +][ + g_object_get_qdata widget parent-window-id +] + ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) set-real-widget: func [ _widget [handle!] @@ -1926,6 +1943,7 @@ OS-make-view: func [ sym <> window parent <> 0 ][ + set-parent-window widget last-window p-sym: get-widget-symbol as handle! parent either null? _widget [_widget: widget][set-_widget widget _widget ] ; TODO: case to replace with either if no more choice @@ -2277,26 +2295,29 @@ OS-to-image: func [ type: symbol/resolve word/symbol ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] - case [ type = screen [ - win: gdk_get_default_root_window - xwin: gdk_x11_window_get_xid win - win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin - pixbuf: gdk_pixbuf_get_from_window win 0 0 screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF + win: gdk_get_default_root_window + width: gdk_window_get_width win + height: gdk_window_get_height win + ; xwin: gdk_x11_window_get_xid win + ; win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin + pixbuf: gdk_pixbuf_get_from_window win 0 0 width height ;screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf ] true [ widget: face-handle? face ;; DEBUG: print ["widget: " widget lf] either null? widget [ret: as red-image! none-value][ - either gtk_window_is_active main-window [ + either gtk_window_is_active parent-window? widget [ size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE win: gtk_widget_get_window widget - ;; DEBUG: print ["win: " win " size: " size/x "x" size/y lf] - pixbuf: gdk_pixbuf_get_from_window win 0 0 size/x size/y - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf - ;g_object_unref pixbuf + if not null? win [ + ;; DEBUG: print ["win: " win " size: " size/x "x" size/y lf] + pixbuf: gdk_pixbuf_get_from_window win 0 0 size/x size/y + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + ;g_object_unref pixbuf + ] ][ print ["Red/GTK warning: to-image not yet implemented when window is not active!"] ret: as red-image! none-value From fe8d242e86e80019faa8c88e125da7154320d804 Mon Sep 17 00:00:00 2001 From: rcqls Date: Sun, 11 Aug 2019 03:32:42 +0200 Subject: [PATCH 0138/3432] Complete work on cursor --- modules/view/backends/gtk3/comdlgs.reds | 1 + modules/view/backends/gtk3/gtk.reds | 23 ++++++ modules/view/backends/gtk3/gui.reds | 95 ++++++++++++++++++++----- 3 files changed, 102 insertions(+), 17 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index a8e83e5990..2dc0d3cc2c 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -38,6 +38,7 @@ _request-file: func [ ret: as red-value! none-value widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" GTK_RESPONSE_CANCEL "Open" GTK_RESPONSE_ACCEPT null] gobj_signal_connect(widget "file-activated" :request-file-double-clicked null) + unless null? main-window [gtk_window_set_transient_for widget main-window] resp: gtk_dialog_run widget if resp = GTK_RESPONSE_ACCEPT [ cstr: gtk_file_chooser_get_filename widget diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 28dddc0208..3db34baca2 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1101,6 +1101,10 @@ GPtrArray!: alias struct! [ [variadic] return: [handle!] ] + gtk_file_chooser_set_do_overwrite_confirmation: "gtk_file_chooser_set_do_overwrite_confirmation" [ + widget [handle!] + mode [logic!] + ] gtk_dialog_run: "gtk_dialog_run" [ widget [handle!] return: [integer!] @@ -1240,6 +1244,13 @@ GPtrArray!: alias struct! [ window [handle!] default_widget [handle!] ] + gtk_offscreen_window_new: "gtk_offscreen_window_new" [ + return: [handle!] + ] + gtk_offscreen_window_get_pixbuf: "gtk_offscreen_window_get_pixbuf" [ + window [handle!] + return: [handle!] + ] gtk_propagate_event: "gtk_propagate_event" [ widget [handle!] event [handle!] @@ -1248,6 +1259,10 @@ GPtrArray!: alias struct! [ widget [handle!] return: [handle!] ] + gtk_widget_get_display: "gtk_widget_get_display" [ + widget [handle!] + return: [handle!] + ] gtk_widget_register_window: "gtk_widget_register_window" [ widget [handle!] window [handle!] @@ -1408,6 +1423,10 @@ GPtrArray!: alias struct! [ widget [handle!] return: [handle!] ] + gtk_widget_get_parent_window: "gtk_widget_get_parent_window" [ + widget [handle!] + return: [handle!] + ] gtk_widget_destroy: "gtk_widget_destroy" [ widget [handle!] ] @@ -2585,6 +2604,10 @@ GPtrArray!: alias struct! [ win [handle!] return: [integer!] ] + gdk_window_set_cursor: "gdk_window_set_cursor" [ + win [handle!] + cursor [handle!] + ] ;; Useless since already called inside pango_cairo_create_context ; pango_cairo_font_map_get_default: "pango_cairo_font_map_get_default" [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 2338e71f05..b7dc0a614d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -44,6 +44,7 @@ size-id: g_quark_from_string "size-id" real-container-id: g_quark_from_string "real-container-id" menu-id: g_quark_from_string "menu-id" drag-id: g_quark_from_string "drag-id" +cursor-id: g_quark_from_string "cursor-id" no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" @@ -211,10 +212,24 @@ set-parent-window: func [ parent-window?: func [ widget [handle!] return: [handle!] +][ + g_object_get_qdata widget parent-window-id +] + +set-cursor: func [ + widget [handle!] + cursor [handle!] +][ + g_object_set_qdata widget cursor-id cursor +] + +cursor?: func [ + widget [handle!] + return: [handle!] /local window [handle!] ][ - g_object_get_qdata widget parent-window-id + g_object_get_qdata widget cursor-id ] ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) @@ -994,7 +1009,7 @@ change-size: func [ ] -hide-invisible-all: func [ +init-all-children: func [ widget [handle!] /local child [handle!] @@ -1005,15 +1020,21 @@ hide-invisible-all: func [ tail [red-object!] values [red-value!] show? [red-logic!] + cursor [handle!] ][ values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE - show?: as red-logic! values + FACE_OBJ_VISIBLE? - sym: symbol/resolve type/symbol + ; init invisible + show?: as red-logic! values + FACE_OBJ_VISIBLE? gtk_widget_set_visible widget show?/value + ; init cursor + cursor: cursor? widget + unless null? cursor [ + gdk_window_set_cursor gtk_widget_get_window widget cursor + ] if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane @@ -1022,7 +1043,7 @@ hide-invisible-all: func [ while [face < tail][ child: face-handle? face unless null? child [ - hide-invisible-all child + init-all-children child ] face: face + 1 ] @@ -1584,10 +1605,12 @@ parse-common-opts: func [ hcur [handle!] pixbuf [handle!] display [handle!] + win [handle!] x [integer!] y [integer!] ;;;btn? [logic!] ][ + ;; DEBUG: print ["parse-common-opts: " get-symbol-name type lf] ;;;btn?: yes if TYPE_OF(options) = TYPE_BLOCK [ word: as red-word! block/rs-head options @@ -1606,7 +1629,7 @@ parse-common-opts: func [ sym = _cursor [ ;; DEBUG: print ["set cursor: " widget lf] w: word + 1 - display: gdk_window_get_display widget + display: gtk_widget_get_display widget either TYPE_OF(w) = TYPE_IMAGE [ img: as red-image! w pixbuf: OS-image/to-pixbuf img 0 0 @@ -1622,8 +1645,9 @@ parse-common-opts: func [ sym = _cross ["crosshair"] true ["default"] ] - hcur: gdk_cursor_new_from_name widget cur + hcur: gdk_cursor_new_from_name display cur ] + set-cursor widget hcur ] ; sym = _class [ ; w: word + 1 @@ -1683,10 +1707,10 @@ OS-show-window: func [ hWnd: as handle! widget unless null? hWnd [ type: get-widget-symbol hWnd - ;; DEBUG: print ["OS-show-window " as handle! widget "(" get-symbol-name type ")" lf] gtk_widget_show_all hWnd + ;; DEBUG: print ["OS-show-window " hWnd "(" get-symbol-name type ") win: " gtk_widget_get_window hWnd lf] ;; Deal with visible? facets - hide-invisible-all hWnd + init-all-children hWnd gtk_widget_grab_focus hWnd face: (as red-object! get-face-values hWnd) + FACE_OBJ_SELECTED if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] @@ -2034,7 +2058,7 @@ OS-make-view: func [ if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] change-color widget as red-tuple! values + FACE_OBJ_COLOR sym - + ;; USELESS: if sym <> window [gtk_widget_show widget] stack/unwind as-integer widget @@ -2290,20 +2314,26 @@ OS-to-image: func [ type [integer!] size [red-pair!] ret [red-image!] + list [GList!] + child [GList!] ][ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol - ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] + ;; DEBUG: + print ["OS-to-image:" get-symbol-name type lf] case [ type = screen [ win: gdk_get_default_root_window width: gdk_window_get_width win height: gdk_window_get_height win - ; xwin: gdk_x11_window_get_xid win - ; win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin - pixbuf: gdk_pixbuf_get_from_window win 0 0 width height ;screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + xwin: gdk_x11_window_get_xid win + win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin + either null? win [ret: as red-image! none-value] + [ + pixbuf: gdk_pixbuf_get_from_window win 0 0 width height ;screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + ] ] true [ widget: face-handle? face @@ -2319,8 +2349,39 @@ OS-to-image: func [ ;g_object_unref pixbuf ] ][ - print ["Red/GTK warning: to-image not yet implemented when window is not active!"] - ret: as red-image! none-value + either type = window [ + win: gtk_offscreen_window_new + + list: as GList! gtk_container_get_children widget + child: list + while [not null? child][ + g_object_ref child/data ; to avoid destruction before removing from container + gtk_container_remove widget child/data + gtk_container_add win child/data + ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] + child: child/next + ] + g_list_free as int-ptr! list + gtk_widget_show_all win + gtk_widget_queue_draw win + pixbuf: gtk_offscreen_window_get_pixbuf win + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + + list: as GList! gtk_container_get_children win + child: list + while [not null? child][ + g_object_ref child/data ; to avoid destruction before removing from container + gtk_container_remove win child/data + gtk_container_add widget child/data + ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] + child: child/next + ] + g_list_free as int-ptr! list + + ][ + print ["Red/GTK warning: to-image not yet implemented when window is not active!"] + ret: as red-image! none-value + ] ] ] ] From 1201b479ee153f8e0a470be5731914fe199e11c5 Mon Sep 17 00:00:00 2001 From: rcqls Date: Sun, 11 Aug 2019 08:32:51 +0200 Subject: [PATCH 0139/3432] removes warning about cursor --- modules/view/backends/gtk3/gui.reds | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b7dc0a614d..b584bfd4de 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1021,20 +1021,26 @@ init-all-children: func [ values [red-value!] show? [red-logic!] cursor [handle!] + win [handle!] ][ values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE sym: symbol/resolve type/symbol + ;;;;; init begin + ;; DEBUG: print ["init-all-children: " get-symbol-name sym lf] ; init invisible show?: as red-logic! values + FACE_OBJ_VISIBLE? gtk_widget_set_visible widget show?/value ; init cursor cursor: cursor? widget unless null? cursor [ - gdk_window_set_cursor gtk_widget_get_window widget cursor + win: gtk_widget_get_window widget + ;; DEBUG: print ["win: " win lf] + unless null? win [gdk_window_set_cursor win cursor] ] + ;;;;; init end if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane From 577832b0ddfd9aaf2700205c7b45cfd95c378f2e Mon Sep 17 00:00:00 2001 From: rcqls Date: Sun, 11 Aug 2019 11:32:54 +0200 Subject: [PATCH 0140/3432] Forget to comment OS-to-image message --- modules/view/backends/gtk3/gui.reds | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b584bfd4de..46a80c0833 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -2326,8 +2326,7 @@ OS-to-image: func [ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol - ;; DEBUG: - print ["OS-to-image:" get-symbol-name type lf] + ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] case [ type = screen [ win: gdk_get_default_root_window From af30ad2f54b3a21da0cbd3cd4812d8f02fdd13e7 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 28 Aug 2019 20:02:58 +0800 Subject: [PATCH 0141/3432] Merge master to GTK (#4014) * FIX: help error info will be printed to buffer * FIX: issue #3333 (dump-reactions instabilities and regression since march) where `is` produces a wrong excessive reaction * TESTS: for PR #3884 partly fixing issue #3333 * FIX: issues #3087 (Console size is not defined when script starts), #3678 (`help` is often useless when invoked from within a CLI script) * FIX: issue #3835 (wrong rounded cornors ) * FIX: issue #3835 (capture window with title bar) * FIX: issue #3951 (parse-macros don't get substituted anymore) Extra fix for #3927. * FIX: issue #3835 (combine title bar and nsview to avoid some lost area) * FIX: issue #3545 (set the text to "", if it has no value) * TESTS: add test for #3951. * FIX: issue #3883 (Compiled code does not follow standard operator precedence rules) * FIX: issue #3961 (gui-console crashed on macOS) * TESTS: adds test for issue #3961. * FIX: macOS: issue #3980 (`layout/parent` causes access violation) * FIX: issue #3776 (update button image) * FIX: issue #3776 (free the unused image list) * FIX: issue #3795 (dpi scale issue for event/offset) * FIX: issue #3741 (over/away's event/offset not right) * FIX: issue #3619 (event/picked return none, if menu's id not be set) * FIX: use more clear value * FIX: issue #3805 ([CRASH] when reactor!/on-change* is overridden) * FIX: issue #3768 (sort with comparator function returning number sorts incorrectly) * FIX: issue #3771 (Inside a function macros expand only once) * TESTS: adds runtime preprocessor tests. This file is not included yet in the tests suite, as it crashes badly, so need preliminary investigation and fixing. * TEST: update SORT tests. * FIX: issue #3759 (`round/to/floor -2.4 1.0` should equal `round/to/floor -2.4 1` ) * FEAT: round/to support time! * FIX: issue #1957 (REFLECT not defined on string! vector! binary! and hash!) * FEAT: code refactoring in port type to remove unnecessary extra code. * FIX: issue #2554 (Fields of error value can be set, with fatal result) * FIX: issue #2688 (SAVE does not accept binary! as destination) * FIX: make SAVE preserve the formatting of a molded argument value. Example: save %src.red :append print read %src.red * FIX: issue #2659 (Programming error and strange decision in comparing pairs) * FIX: issue #395 (Console crash if break is evaluated on foreach-face loop) Note: the root cause of the crash is not fixed. * FIX: issue #3991 (Console crash if break is evaluated on foreach-face loop) Note: the root cause of the crash is not fixed. * FIX: issue #2657 (Inconsistency in comparing object with error) * FIX: issue #2792 (revert #1558 e85962, and no crashing) * FIX: issue #2658 (Strange algorithm for comparing objects) * FIX: issue #2184 (Tests float-divide 37, 38, 47, & 48 fail on Windows.) * FIX: workaround float loading issues for tests in #2184. Cross-platform float loading issues documented in #3993. * FIX: additional workaround for ARM in float tests fro #2184. * FIX: issue #2662 (comparison of time and integer is inconsistent) * FIX: Win: flickering when drag the `drag me` button in view-test.red * FIX: gui-console doesn't quit properly in some cases. * FIX: paste text not be prompted on macOS * FIX: issue #3427 (`parse/part` meets `end` = strange behavior) * TESTS: adds regression tests for #3427. * FEAT: adds thread.reds in runtime. * FIX: issue #3653 (expand-directives allows a paren argument, but this always errors out) * FIX: issue #2556 (Wrong error message when setting event component other than type) * FIX: renames a few function names in %thread.reds. * FIX: rename %thread.reds to %threads.reds. * FIX: issue #2646 (make op! allows invalid construction syntax / returned op! causes crash) * FIX: issue #2660 (Pairs are wrongly compared for greater etc) * FIX: issue #3104 (map: same date keys treated differently because of hidden timezone state) * FIX: issue #3143 (trim/lines resulting in vertical block) * FIX: issue #3187 (DOC: Red/System literal arrays may contain c-strings, contrary to what is stated in the syntax) * TESTS: adds test for issue #3636 * FIX: issue #3356 (spec block in OBJECT! and FUNCTION! is used from head rather than from index) * FIX: issue #3395 (max and min are not compatible with > and <) * FIX: issue #3522 (return spec of modify action is incorrrect) * FIX: minor comments re-indentation. * FEAT: console support history * FIX: insert line at history head in cli console * FIX: rename save-cfg like internal function * FIX: update max if insert line on history * FIX: add cli config file to include.r * FIX: red.exe create cli issue * FIX: issue #3406 (`construct` result is order-dependent) * TESTS: add tests for #3406. * FIX: same ordering issue as #3406 for `make ` pattern. * FEAT: check uncompressed data size in decompress/zlib. * FEAT: adds support for system/cpu/fence for setting a memory ordering barrier. The barrier is a sequentially consistent fence type. * FIX: removes some unused local words. * FEAT: preliminary support for atomic operations using system/atomic/* Note: system/cpu/fence was moved to system/atomic/fence. * FEAT: adds support for system/atomic/cas. * FEAT: adds get-word support for pointer argument after atomic/cas and atomic/. * TESTS: add some tests for atomic operations. * TESTS: add test for CAS operation. * TEST: add some failed cases in atomic tests. * FEAT: improved the implementation of atomic operations. The pointer argument can now be any expression returning a pointer! value. * FEAT: adds support for system/atomic//old, returning the old value. * FEAT: adds a FIFO MPMC queue in R/S. * FEAT: implements system/atomic/fence for ARM. * FEAT: the queue.reds can be compiled now. * TESTS: add tests for R/S queue. * TESTS: add more tests for atomic operations. * FIX: issue #4005 ([View] regression in Windows backend). * FIX: issue #4006 (Pen 'OFF in Draw PUSH block turns the Pen off after the PUSH block on MacOS) * FIX: issue #3077 (`insert` key work for richtext) * FEAT: implements system/atomic/load & store for ARM. * FIX: properly set the Tag_CPU_arch in ELF/ARM for newer architectures. * FEAT: implements system/atomic/cas for ARM. * FEAT: minor code reduction. * FEAT: implements atomic math operations for ARM. * FIX: gui-console's context menu shortcuts on macOS * FIX: cannot create thread on POSIX. * FIX: `quit` console can't save config * FIX: extra print when called from other app * FIX: avoid to allocate buffer foreach console input * FIX: improve `terminal initial flow` * FIX: fixes and improves returned value handling in atomic math ops on IA-32. * DOCS: replaces default font Trebuchet MS by Arial. * DOCS: adds description of system/atomic/* intrinsics. * FIX: issue #3997 (Using `#include %file.red` in context will not be compiled successfully) * FIX: Windows: CLI console cannot be compiled. * TESTS: enables the atomic tests and queue tests. (#4011) * TESTS: adds atomic tests and queue tests into the testsuite. * TESTS: adds cdecl calling convention in thread functions on non-Windows platforms. * TESTS: atomic operations are not supported on ARMv5 yet. * TESTS: makes the test framework happy. * FIX: macOS: line properties cannot be set in some cases in DRAW. --- build/includes.r | 2 + compiler.r | 6 +- docs/dark.css | 2 +- docs/light.css | 2 +- docs/red-system-specs.txt | 82 +++++- environment/actions.red | 3 +- environment/console/CLI/POSIX.reds | 34 +-- environment/console/CLI/console.red | 18 +- environment/console/CLI/input.red | 54 ++-- environment/console/CLI/settings.red | 51 ++++ environment/console/CLI/win32.reds | 21 +- environment/console/GUI/core.red | 12 +- environment/console/GUI/gui-console.red | 16 +- environment/console/GUI/settings.red | 53 ++-- environment/console/engine.red | 5 +- environment/console/help.red | 8 +- environment/functions.red | 19 +- environment/lexer.red | 7 +- environment/reactivity.red | 8 +- environment/system.red | 2 + modules/view/backends/macOS/classes.reds | 1 - modules/view/backends/macOS/cocoa.reds | 6 +- modules/view/backends/macOS/delegates.reds | 30 +-- modules/view/backends/macOS/draw.reds | 69 +++-- modules/view/backends/macOS/events.reds | 6 +- modules/view/backends/macOS/gui.reds | 69 ++++- modules/view/backends/macOS/menu.reds | 10 +- modules/view/backends/windows/button.reds | 54 ++-- modules/view/backends/windows/events.reds | 27 +- modules/view/backends/windows/gui.reds | 10 +- modules/view/backends/windows/win32.reds | 5 + modules/view/view.red | 4 +- red.r | 2 +- runtime/datatypes/binary.reds | 2 +- runtime/datatypes/block.reds | 12 +- runtime/datatypes/context.reds | 3 +- runtime/datatypes/error.reds | 38 ++- runtime/datatypes/event.reds | 2 +- runtime/datatypes/float.reds | 29 ++- runtime/datatypes/hash.reds | 2 +- runtime/datatypes/integer.reds | 6 +- runtime/datatypes/object.reds | 41 +-- runtime/datatypes/op.reds | 14 +- runtime/datatypes/pair.reds | 8 +- runtime/datatypes/port.reds | 137 ++++------ runtime/datatypes/time.reds | 14 +- runtime/datatypes/vector.reds | 2 +- runtime/inflate.reds | 6 + runtime/natives.reds | 21 +- runtime/parse.reds | 3 +- runtime/platform/image-quartz.reds | 37 +++ runtime/queue.reds | 158 ++++++++++++ runtime/red.reds | 2 +- runtime/threads.reds | 286 +++++++++++++++++++++ system/compiler.r | 79 +++++- system/formats/ELF.r | 12 +- system/targets/ARM.r | 73 ++++++ system/targets/IA-32.r | 97 ++++++- system/targets/target-class.r | 3 +- system/tests/all-tests.txt | 2 + system/tests/run-all.r | 2 + system/tests/source/units/atomic-test.reds | 236 +++++++++++++++++ system/tests/source/units/cast-test.reds | 33 +++ system/tests/source/units/queue-test.reds | 141 ++++++++++ tests/source/runtime/preprocessor-test.red | 82 ++++++ tests/source/units/convert-test.red | 2 + tests/source/units/float-test.red | 34 ++- tests/source/units/integer-test.red | 6 + tests/source/units/object-test.red | 20 ++ tests/source/units/parse-test.red | 10 + tests/source/units/reactivity-test.red | 131 +++++++--- tests/source/units/series-test.red | 6 +- tests/source/units/time-test.red | 14 +- utils/preprocessor.r | 7 +- 74 files changed, 2071 insertions(+), 440 deletions(-) create mode 100644 environment/console/CLI/settings.red create mode 100644 runtime/queue.reds create mode 100644 runtime/threads.reds create mode 100644 system/tests/source/units/atomic-test.reds create mode 100644 system/tests/source/units/queue-test.reds create mode 100644 tests/source/runtime/preprocessor-test.red diff --git a/build/includes.r b/build/includes.r index b0cb84c0fa..3cd0c0de76 100644 --- a/build/includes.r +++ b/build/includes.r @@ -55,6 +55,7 @@ write %build/bin/sources.r set-cache [ %POSIX.reds %wcwidth.reds %win32.reds + %settings.red ] %GUI/ [ %old/ [ @@ -97,6 +98,7 @@ write %build/bin/sources.r set-cache [ %simple-io.reds %sort.reds %stack.reds + %threads.reds %tokenizer.reds %tools.reds %unicode.reds diff --git a/compiler.r b/compiler.r index ffdeede4ab..0f1fc6902a 100644 --- a/compiler.r +++ b/compiler.r @@ -1938,7 +1938,7 @@ red: context [ ] ] ) - | #include (comp-include/only pos) + | #include (comp-include/only pos) :pos | skip ] ] @@ -2260,7 +2260,7 @@ red: context [ ] comp-any: does [ - either block? pc/1 [ + either all [block? pc/1 not check-infix-operators no][ comp-boolean-expressions 'any ['if 'logic/false? body] ][ emit-open-frame 'any @@ -2271,7 +2271,7 @@ red: context [ ] comp-all: does [ - either block? pc/1 [ + either all [block? pc/1 not check-infix-operators no][ comp-boolean-expressions 'all [ 'either 'logic/false? set-last-none body ] diff --git a/docs/dark.css b/docs/dark.css index d6c2b1d630..a7ca70a80e 100644 --- a/docs/dark.css +++ b/docs/dark.css @@ -1,5 +1,5 @@ body, blockquote, p { - font: normal normal 13px Trebuchet MS, sans-serif, helvetica; + font: normal normal 13px Arial, sans-serif, helvetica; color: #cccccc; background: #292929; } diff --git a/docs/light.css b/docs/light.css index 2fd3534d83..01ca154bc3 100644 --- a/docs/light.css +++ b/docs/light.css @@ -1,4 +1,4 @@ -html, body, p, td, li {font-family: Trebuchet MS, sans-serif, helvetica; font-size: 10pt;} +html, body, p, td, li {font-family: Arial, sans-serif, helvetica; font-size: 10pt;} strike {color: #888;} h1 {font-size: 16pt; Font-Weight: bold;} h2 {font-size: 14pt; color: #2030a0; Font-Weight: bold; width: 100%; diff --git a/docs/red-system-specs.txt b/docs/red-system-specs.txt index 6f7b43b4f4..f4d6ad45fd 100644 --- a/docs/red-system-specs.txt +++ b/docs/red-system-specs.txt @@ -1,8 +1,8 @@ Red/System Language Specification Author: Nenad Rakocevic - Date: 25/06/2019 - Revision: 54 + Date: 27/08/2019 + Revision: 55 Status: reference document Home: red-lang.org @@ -813,7 +813,7 @@ A pointer can also point to a one-dimensional array of values literally specifie : [] : a pointer of same type as the array items. - : is a non-empty list of integer!, byte!, float!, logic! literal values. + : is a non-empty list of integer!, byte!, float!, logic!, c-string! literal values. The array is statically allocated and can be accessed using pointer path notation or pointer arithmetic. The size of the array (in number of elements) is stored in a 32-bit slot, just preceding the beginning of the array (at index 0). Mixing the different allowed types in the same array is permitted (enumerations can also be used). In such case, the size of each array's slot is either 32-bit, or 64-bit if a float64! value is present. @@ -2823,7 +2823,7 @@ ARM target returns the value of the PC (r15) register. /note ----cpu +---cpu/<reg> Set or retrieve any of the CPU's registers value. @@ -3122,12 +3122,79 @@ where: The written value has to be consistent with the port's pointer type, otherwise a compilation error occurs. - \note Hardware vs memory-mapped I/O On some platforms (like ARM), such I/O operations are simply memory-mapped I/O. /note + +---atomic/fence + +Generate a read/write data memory barrier, using the sequentially consistent (`seq_cst`) memory order. + +Syntax + + system/atomic/fence + +---atomic/load + +Performs a thread-safe atomic read from a given memory location. + +Syntax + + system/atomic/load + + return: integer! value read from memory location. + +where: + : memory location to load from (pointer! [integer!]) + +---atomic/store + +Performs a thread-safe atomic write to a given memory location. + +Syntax + + system/atomic/store + +where: + : memory location to write to (pointer! [integer!]) + : integer value to store (integer!) + +---atomic/cas + +Performs a thread-safe atomic compare & swap to a given memory location. + +Syntax + + system/atomic/cas + + return: TRUE on success, otherwise FALSE (logic!) + +where: + : memory location to read/write to (pointer! [integer!]) + : integer value to compare to (integer!) + : integer value to write if comparison succeeded (integer!) + +The compare & swap semantics are described here. The memory location is read and the value is compared to the old value. If equal, the new value is written and it returns `true`, otherwise it aborts and returns `false`. + +---atomic/<math-op> + +Performs a thread-safe atomic math or bitwise operation to a given memory location. + +Syntax + + system/atomic/ + system/atomic//old + + return: the new value, or the old value if /old refinement is present. + +where: + : add, sub, or, xor, and + : memory location to write to (pointer! [integer!]) + : operand value (integer!) + + ---image/base Returns the base address of the executable image in memory. @@ -4080,6 +4147,11 @@ will output: ===Document History +*27/08/2019 - revision 55 + +*>Adds system/atomic/* intrinsics description. + + *25/06/2019 - revision 54 *>Adds a #INLINE directive to inline machine code. diff --git a/environment/actions.red b/environment/actions.red index d5eaebf3be..72a910cb6d 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -77,7 +77,6 @@ modify: make action! [[ field [word!] value [any-type!] /case "Perform a case-sensitive lookup" - return: [map! file!] ] #get-definition ACT_MODIFY ] @@ -149,7 +148,7 @@ round: make action! [[ "Returns the nearest integer. Halves round up (away from zero) by default" n [number! time! pair!] /to "Return the nearest multiple of the scale parameter" - scale [number!] "Must be a non-zero value" + scale [number! time!] "Must be a non-zero value" /even "Halves round toward even results" /down "Round toward zero, ignoring discarded digits. (truncate)" /half-down "Halves round toward zero" diff --git a/environment/console/CLI/POSIX.reds b/environment/console/CLI/POSIX.reds index 60b89223d5..43b905f933 100644 --- a/environment/console/CLI/POSIX.reds +++ b/environment/console/CLI/POSIX.reds @@ -186,7 +186,7 @@ winsize!: alias struct! [ old-act: declare sigaction! saved-term: declare termios! -utf-char: declare c-string! +utf-char: as-c-string allocate 10 poller: declare pollfd! relative-y: 0 init?: no @@ -373,32 +373,16 @@ query-cursor: func [ get-window-size: func [ /local ws [winsize!] - here [integer!] size [red-pair!] ][ ws: declare winsize! ioctl stdout TIOCGWINSZ ws columns: ws/rowcol >> 16 - - if zero? columns [ - columns: 80 - here: 0 - if query-cursor :here [ - emit-string "^[[999C" - - either query-cursor :columns [ - if columns > here [ ;-- reset cursor position - emit-string-int "^[[" columns - here #"D" - ] - ][ - emit cr - ] - ] - ] + rows: ws/rowcol and FFFFh size: as red-pair! #get system/console/size size/x: columns - size/y: ws/rowcol and FFFFh + size/y: rows ] reset-cursor-pos: does [ @@ -447,15 +431,20 @@ output-to-screen: does [ write stdout buffer (as-integer pbuffer - buffer) ] -init: func [ +init: func [][ + console?: 1 = isatty stdin + if console? [ + get-window-size + ] +] + +init-console: func [ /local term [termios!] cc [byte-ptr!] so [sigaction! value] ][ - console?: 1 = isatty stdin relative-y: 0 - utf-char: as-c-string allocate 10 if console? [ sigemptyset (as-integer :so) + 4 @@ -516,5 +505,4 @@ restore: does [ tcsetattr stdin TERM_TCSADRAIN saved-term #if OS <> 'Linux [sigaction SIGWINCH old-act null] free buffer - free as byte-ptr! utf-char ] diff --git a/environment/console/CLI/console.red b/environment/console/CLI/console.red index 75d524dc2f..13711bcbdb 100644 --- a/environment/console/CLI/console.red +++ b/environment/console/CLI/console.red @@ -14,5 +14,19 @@ Red [ #include %../help.red #include %../engine.red -system/console/init "Red Console" -system/console/launch \ No newline at end of file +cli-console-ctx: context [ + settings: #include %settings.red + + launch: does [ + settings/load-cfg + + system/console/init "Red Console" + system/console/launch + ] +] + +_save-cfg: function [][ + cli-console-ctx/settings/save-cfg +] + +cli-console-ctx/launch \ No newline at end of file diff --git a/environment/console/CLI/input.red b/environment/console/CLI/input.red index a8a0d5a690..b5f3088e34 100644 --- a/environment/console/CLI/input.red +++ b/environment/console/CLI/input.red @@ -18,7 +18,7 @@ Red [ unless system/console [ system/console: context [ history: make block! 200 - size: 0x0 + size: 80x50 ;-- default size for dump/help funcs ] ] ;; End patch @@ -164,8 +164,14 @@ unless system/console [ str [red-string!] ][ str/head: 0 - unless zero? string/rs-length? str [ - block/rs-append history as red-value! str ;TBD Don't add duplicated lines. + unless any [ + zero? string/rs-length? str + all [ + 0 < block/rs-length? history + zero? string/equal? str as red-string! block/rs-abs-at history 0 COMP_STRICT_EQUAL no + ] + ][ + block/insert-value history as red-value! str ] ] @@ -370,10 +376,14 @@ unless system/console [ head [integer!] c [integer!] n [integer!] + pos [integer!] + max [integer!] ][ line: input-line copy-cell as red-value! prompt-str as red-value! prompt - history/head: block/rs-length? history ;@@ set history list to tail (temporary) + history/head: 0 + pos: -1 + max: block/rs-length? history get-window-size if null? saved-line [init-globals] @@ -404,6 +414,7 @@ unless system/console [ switch c [ KEY_ENTER [ add-history line + max: max + 1 string/rs-reset saved-line exit ] @@ -433,26 +444,27 @@ unless system/console [ refresh ] ] - KEY_CTRL_P - KEY_UP [ - unless zero? history/head [ - history/head: history/head - 1 + KEY_CTRL_N + KEY_DOWN [ + either pos < 0 [ + string/rs-reset line + ][ + history/head: pos fetch-history - line/head: string/rs-abs-length? line - refresh + pos: pos - 1 ] + refresh ] - KEY_CTRL_N - KEY_DOWN [ - unless block/rs-tail? history [ - history/head: history/head + 1 - either block/rs-tail? history [ - string/rs-reset line - ][ - fetch-history - ] - refresh + KEY_CTRL_P + KEY_UP [ + either pos >= (max - 1) [ + string/rs-reset line + ][ + pos: pos + 1 + history/head: pos + fetch-history ] + refresh ] KEY_CTRL_A KEY_HOME [ @@ -564,7 +576,7 @@ unless system/console [ copy-cell as red-value! line as red-value! input-line copy-cell as red-value! hist as red-value! history - init ;-- enter raw mode + init-console ;-- enter raw mode ] ] ] diff --git a/environment/console/CLI/settings.red b/environment/console/CLI/settings.red new file mode 100644 index 0000000000..da547e816d --- /dev/null +++ b/environment/console/CLI/settings.red @@ -0,0 +1,51 @@ +Red [ + Title: "Red CLI Console Settings" + Author: "bitbegin" + File: %settings.red + Tabs: 4 + Rights: "Copyright (C) 2014-2018 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +context [ + cfg-dir: none + cfg-path: none + cfg: none + + apply-cfg: function [][ + system/console/history: cfg/history + ] + + save-cfg: function [/local saved][ + unless exists? cfg-dir [make-dir/deep cfg-dir] + clear skip cfg/history 100 + save/header cfg-path cfg [Purpose: "Red Console Configuration File"] + ] + + load-cfg: func [/local cfg-content cli-default][ + cfg-dir: append copy system/options/cache + #either config/OS = 'Windows [%Red-Console/][%.Red-Console/] + + unless exists? cfg-dir [make-dir/deep cfg-dir] + cfg-path: append copy cfg-dir %console-cfg.red + + cfg: either all [ + exists? cfg-path + attempt [select cfg-content: load cfg-path 'Red] + ][ + skip cfg-content 2 + ][ + [] + ] + unless find cfg 'buffer-lines [ + append cfg [buffer-lines: 10000] + ] + unless find cfg 'history [ + append cfg [history: []] + ] + apply-cfg + ] +] \ No newline at end of file diff --git a/environment/console/CLI/win32.reds b/environment/console/CLI/win32.reds index 77aee6a77c..e2111c3ffa 100644 --- a/environment/console/CLI/win32.reds +++ b/environment/console/CLI/win32.reds @@ -260,13 +260,17 @@ get-window-size: func [ size [red-pair!] ][ info: declare screenbuf-info! + size: as red-pair! #get system/console/size + size/x: 80 ;-- set defaults when working with stdout + size/y: 50 ; as many output funcs rely on it + columns: size/x + rows: size/y if zero? GetConsoleScreenBufferInfo stdout as-integer info [return -1] x-y: info/Size columns: FIRST_WORD(x-y) rows: SECOND_WORD(x-y) - size: as red-pair! #get system/console/size - size/x: SECOND_WORD(info/top-right) - SECOND_WORD(info/attr-left) - size/y: FIRST_WORD(info/bottom-maxWidth) - FIRST_WORD(info/top-right) + size/x: SECOND_WORD(info/top-right) - SECOND_WORD(info/attr-left) + 1 + size/y: FIRST_WORD(info/bottom-maxWidth) - FIRST_WORD(info/top-right) + 1 if columns <= 0 [size/x: 80 columns: 80 return -1] x-y: info/Position base-y: SECOND_WORD(x-y) @@ -325,12 +329,17 @@ output-to-screen: func [/local n][ WriteConsole stdout buffer (as-integer pbuffer - buffer) / 2 :n null ] -init: func [ +init: func [][ + console?: isatty as int-ptr! stdin + if console? [ + get-window-size + ] +] + +init-console: func [ /local mode [integer!] ][ - console?: isatty as int-ptr! stdin - if console? [ GetConsoleMode stdin :saved-con mode: saved-con and (not ENABLE_PROCESSED_INPUT) ;-- turn off PROCESSED_INPUT, so we can handle control-c diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 11f1cac4a3..08bf86e9b9 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -606,12 +606,18 @@ object [ unless resume [clipboard: read-clipboard] if all [clipboard not empty? clipboard][ start: clipboard - end: find clipboard #"^M" - either end [nl?: yes][nl?: no end: tail clipboard] + end: find clipboard #"^/" + either end [ + nl?: yes + if end/-1 = #"^M" [end: back end] + ][ + nl?: no + end: tail clipboard + ] insert/part skip line pos start end idx: pos pos: pos + offset? start end - clipboard: skip end either end/2 = #"^/" [2][1] + clipboard: skip end either end/1 = #"^M" [2][1] if nl? [ caret/enabled?: no insert history line diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index 85ec571256..0050755ce9 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -40,6 +40,7 @@ Red [ #include %tips.red gui-console-ctx: context [ + cfg-dir: none cfg-path: none cfg: none font: make font! [name: "Consolas" size: 11 color: 0.0.0] @@ -51,8 +52,13 @@ gui-console-ctx: context [ flags: [scrollable all-over] options: [cursor: I-beam] menu: [ - "Copy^-Ctrl+C" copy - "Paste^-Shift+Ins" paste + #either config/OS = 'macOS [ + "Copy^-Command+C" copy + "Paste^-Command+V" paste + ][ + "Copy^-Ctrl+C" copy + "Paste^-Shift+Ins" paste + ] --- "Select All" select-all ] @@ -170,7 +176,9 @@ gui-console-ctx: context [ ] on-close: func [face [object!] event [event!]][ save-cfg + system/view/platform/exit-event-loop clear head system/view/screens/1/pane + quit ] on-resizing: function [face [object!] event [event!]][ new-sz: event/offset @@ -224,6 +232,10 @@ gui-console-ctx: context [ ] ] +_save-cfg: function [][ + gui-console-ctx/save-cfg +] + ask: function [ "Prompt the user for input" question [string!] diff --git a/environment/console/GUI/settings.red b/environment/console/GUI/settings.red index dd81cb4bd8..60c9603c93 100644 --- a/environment/console/GUI/settings.red +++ b/environment/console/GUI/settings.red @@ -166,6 +166,7 @@ apply-cfg: function [][ ] save-cfg: function [][ + unless exists? cfg-dir [make-dir/deep cfg-dir] offset: win/offset ;-- offset could be negative in some cases if offset/x < 0 [offset/x: 0] if offset/y < 0 [offset/y: 0] @@ -177,32 +178,52 @@ save-cfg: function [][ save/header cfg-path cfg [Purpose: "Red Console Configuration File"] ] -load-cfg: func [/local cfg-dir cfg-content][ +check-cfg: function [gui-default][ + iter: gui-default + while [not tail? iter][ + either f: find cfg iter/1 [ + if (type? f/2) <> type? iter/2 [ + f/2: iter/2 + ] + ][ + repend cfg [iter/1 iter/2] + ] + iter: skip iter 2 + ] +] + +load-cfg: func [/local cfg-content gui-default][ system/view/auto-sync?: no cfg-dir: append copy system/options/cache #either config/OS = 'Windows [%Red-Console/][%.Red-Console/] unless exists? cfg-dir [make-dir/deep cfg-dir] - cfg-path: append cfg-dir %console-cfg.red + cfg-path: append copy cfg-dir %console-cfg.red + + gui-default: compose [ + win-pos: (win/offset) + win-size: 640x480 - cfg: either all [ + font-name: (font/name) + font-size: 11 + font-color: 0.0.0 + background: 252.252.252 + ] + + either all [ exists? cfg-path attempt [select cfg-content: load cfg-path 'Red] ][ - skip cfg-content 2 + cfg: skip cfg-content 2 + check-cfg gui-default ][ - compose [ - win-pos: (win/offset) - win-size: 640x480 - - font-name: (font/name) - font-size: 11 - font-color: 0.0.0 - background: 252.252.252 - - buffer-lines: 10000 - history: [] - ] + cfg: gui-default + ] + unless find cfg 'buffer-lines [ + append cfg [buffer-lines: 10000] + ] + unless find cfg 'history [ + append cfg [history: []] ] apply-cfg win/selected: console diff --git a/environment/console/engine.red b/environment/console/engine.red index ea98428c59..c90aeac37d 100644 --- a/environment/console/engine.red +++ b/environment/console/engine.red @@ -108,7 +108,10 @@ system/console: context [ ][ #if gui-console? = no [terminal/pasting?: no] ] - #if gui-console? = no [terminal/init-globals] + #if gui-console? = no [ + terminal/init + terminal/init-globals + ] ] count-delimiters: function [ diff --git a/environment/console/help.red b/environment/console/help.red index 68d361021c..25b810df1a 100644 --- a/environment/console/help.red +++ b/environment/console/help.red @@ -277,7 +277,7 @@ help-ctx: context [ parse reduce =val [some [datatype! | typeset!]] parse =val ['function! block!] ][ - print ["Looks like we have a bad type spec:" mold =val] + _print ["Looks like we have a bad type spec:" mold =val] ] ) ] @@ -391,15 +391,15 @@ help-ctx: context [ ][ fn: either any-function? :word [:word][get :word] if not any-function? :fn [ - print "show-function-help only works on words that refer to functions." + _print "show-function-help only works on words that refer to functions." exit ] ; Convert the func to an object with fields for spec values fn-as-obj: func-spec-ctx/parse-func-spec :fn if not object? fn-as-obj [ - print "Func spec couldn't be parsed, may be malformed." - print mold :fn + _print "Func spec couldn't be parsed, may be malformed." + _print mold :fn exit ] diff --git a/environment/functions.red b/environment/functions.red index 0ada025e8b..6c4fcbffc5 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -59,6 +59,7 @@ quit: func [ ][ if system/console [do [_terminate-console]] ] + if system/console [do [_save-cfg]] quit-return any [status 0] ] @@ -454,20 +455,22 @@ save: function [ if header [ if object? :header-data [header-data: body-of header-data] ] - suffix: suffix? where - find-encoder?: no - foreach [name codec] system/codecs [ - if (find codec/suffixes suffix) [ ;@@ temporary required until dyn-stack implemented - data: do [codec/encode value dst] - if same? data dst [exit] - find-encoder?: yes + if find [file! url!] type?/word where [ + suffix: suffix? where + find-encoder?: no + foreach [name codec] system/codecs [ + if (find codec/suffixes suffix) [ ;@@ temporary required until dyn-stack implemented + data: do [codec/encode value dst] + if same? data dst [exit] + find-encoder?: yes + ] ] ] unless find-encoder? [ data: either all [ append mold/all/only :value newline ][ - trim mold/only :value + mold/only :value ] case/all [ not binary? data [data: to binary! data] diff --git a/environment/lexer.red b/environment/lexer.red index 4aa4e1d5f9..89860a730f 100644 --- a/environment/lexer.red +++ b/environment/lexer.red @@ -533,7 +533,10 @@ system/lexer: context [ ] multiline-string: [ - #"{" s: nested-curly-braces (unless zero? cnt [throw-error [string! s]]) + #"{" s: nested-curly-braces ( + unless zero? cnt [throw-error [string! s]] + old-line: line + ) ] string-rule: [(type: string!) line-string | multiline-string] @@ -575,7 +578,7 @@ system/lexer: context [ ) ] - binary-rule: [base-16-rule | base-64-rule | base-2-rule] + binary-rule: [[base-16-rule | base-64-rule | base-2-rule] (old-line: line)] file-rule: [ s: #"%" [ diff --git a/environment/reactivity.red b/environment/reactivity.red index 235fb461ff..bea6643036 100644 --- a/environment/reactivity.red +++ b/environment/reactivity.red @@ -171,7 +171,7 @@ system/reactivity: context [ set 'dump-reactions function [ "Output all the current reactive relations for debugging purpose" ][ - limit: any [all [system/console system/console/size/x] 72] - 10 + limit: (any [all [system/console system/console/size/x] 72]) - 10 count: 0 foreach [obj field reaction target] relations [ @@ -205,13 +205,13 @@ system/reactivity: context [ 'field [set-word!] "Set-word which will get set to the result of the reaction" reaction [block!] "Reactive relation" ][ - words: words-of obj: context? field + obj: context? field parse reaction rule: [ any [ item: word! ( - if find words item/1 [add-relation obj item/1 reaction field] + if in obj item/1 [add-relation obj item/1 reaction field] ) - | set-path! | any-string! + | any-path! | any-string! | into rule | skip ] diff --git a/environment/system.red b/environment/system.red index 19b8eca33d..d187b5f8ff 100644 --- a/environment/system.red +++ b/environment/system.red @@ -161,6 +161,7 @@ system: context [ ;wrong-denom: [:arg1 "not same denomination as" :arg2] ;bad-press: ["invalid compressed data - problem:" :arg1] ;dialect: ["incorrect" :arg1 "dialect usage at:" :arg2] + invalid-obj-evt: ["invalid object event handler:" :arg1] parse-rule: ["PARSE - invalid rule or usage of rule:" :arg1] parse-end: ["PARSE - unexpected end of rule after:" :arg1] ;parse-variable: ["PARSE - expected a variable, not:" :arg1] @@ -189,6 +190,7 @@ system: context [ react-bad-obj: "REACT - target can only contain object values" react-gctx: ["REACT - word" :arg1 "is not a reactor's field"] lib-invalid-arg: ["LIBRED - invalid argument for" :arg1] + buffer-not-enough: ["Buffer size too small, should be:" :arg1] ] math: object [ code: 400 diff --git a/modules/view/backends/macOS/classes.reds b/modules/view/backends/macOS/classes.reds index 739d1faed6..77837c6db2 100644 --- a/modules/view/backends/macOS/classes.reds +++ b/modules/view/backends/macOS/classes.reds @@ -35,7 +35,6 @@ add-base-handler: func [class [integer!]][ class_replaceMethod class sel_getUid "rightMouseDown:" as-integer :mouse-events-base "v@:@" class_replaceMethod class sel_getUid "rightMouseUp:" as-integer :mouse-events-base "v@:@" - class_addMethod class sel_getUid "keyDown:" as-integer :key-down-base "v@:@" class_addMethod class sel_getUid "insertText:" as-integer :insert-text "v@:@" class_addMethod class sel_getUid "hasMarkedText" as-integer :has-marked-text "B@:" class_addMethod class sel_getUid "markedRange" as-integer :marked-range "{_NSRange=ii}@:" diff --git a/modules/view/backends/macOS/cocoa.reds b/modules/view/backends/macOS/cocoa.reds index 0172af1921..6b435adb43 100644 --- a/modules/view/backends/macOS/cocoa.reds +++ b/modules/view/backends/macOS/cocoa.reds @@ -450,11 +450,7 @@ tagSIZE: alias struct! [ return: [integer!] ] CGWindowListCreateImage: "CGWindowListCreateImage" [ - ;bounds [NSRect! value] - x [integer!] - y [integer!] - w [integer!] - h [integer!] + bounds [NSRect! value] listOption [integer!] windowID [integer!] imageOption [integer!] diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds index cb1dac17bd..039e839938 100644 --- a/modules/view/backends/macOS/delegates.reds +++ b/modules/view/backends/macOS/delegates.reds @@ -340,21 +340,6 @@ on-key-down: func [ ] ] -key-down-base: func [ - [cdecl] - self [integer!] - cmd [integer!] - event [integer!] -][ - either zero? objc_getAssociatedObject self RedRichTextKey [ - on-key-down self event - ][ - objc_msgSend [ - objc_msgSend [self sel_getUid "inputContext"] sel_getUid "handleEvent:" event - ] - ] -] - win-level: func [ [cdecl] self [integer!] @@ -846,12 +831,23 @@ win-send-event: func [ find?: yes responder: objc_msgSend [self sel_getUid "firstResponder"] object_getInstanceVariable responder IVAR_RED_DATA :type - if type <> base [ + either type <> base [ unless red-face? responder [ responder: objc_getAssociatedObject self RedFieldEditorKey unless red-face? responder [find?: no] ] - if find? [on-key-down responder event] + if find? [ + on-key-down responder event + send?: no + ] + ][ + on-key-down responder event + send?: no + unless zero? objc_getAssociatedObject self RedRichTextKey [ + objc_msgSend [ + objc_msgSend [self sel_getUid "inputContext"] sel_getUid "handleEvent:" event + ] + ] ] ] true [0] diff --git a/modules/view/backends/macOS/draw.reds b/modules/view/backends/macOS/draw.reds index 04dd70a3ca..fda20b230b 100644 --- a/modules/view/backends/macOS/draw.reds +++ b/modules/view/backends/macOS/draw.reds @@ -22,7 +22,16 @@ edges: as CGPoint! allocate max-edges * (size? CGPoint!) ;-- polygone edges buff colors: as pointer! [float32!] allocate 5 * max-colors * (size? float32!) colors-pos: colors + (4 * max-colors) -draw-state!: alias struct! [unused [integer!]] +draw-state!: alias struct! [ + pen-clr [integer!] + brush-clr [integer!] + pen-join [integer!] + pen-cap [integer!] + pen? [logic!] + brush? [logic!] + a-pen? [logic!] + a-brush? [logic!] +] draw-begin: func [ ctx [draw-ctx!] @@ -216,10 +225,8 @@ OS-draw-line-width: func [ ][ width-v: get-float32 as red-integer! width if width-v <= F32_0 [width-v: F32_1] - if dc/pen-width <> width-v [ - dc/pen-width: width-v - CGContextSetLineWidth dc/raw width-v - ] + dc/pen-width: width-v + CGContextSetLineWidth dc/raw width-v ] get-shape-center: func [ @@ -938,17 +945,15 @@ OS-draw-line-join: func [ mode [integer!] ][ mode: kCGLineJoinMiter - if dc/pen-join <> style [ - dc/pen-join: style - case [ - style = miter [mode: kCGLineJoinMiter] - style = miter-bevel [mode: kCGLineJoinMiter] - style = _round [mode: kCGLineJoinRound] - style = bevel [mode: kCGLineJoinBevel] - true [mode: kCGLineJoinMiter] - ] - CGContextSetLineJoin dc/raw mode + dc/pen-join: style + case [ + style = miter [mode: kCGLineJoinMiter] + style = miter-bevel [mode: kCGLineJoinMiter] + style = _round [mode: kCGLineJoinRound] + style = bevel [mode: kCGLineJoinBevel] + true [mode: kCGLineJoinMiter] ] + CGContextSetLineJoin dc/raw mode ] OS-draw-line-cap: func [ @@ -958,16 +963,14 @@ OS-draw-line-cap: func [ mode [integer!] ][ mode: kCGLineCapButt - if dc/pen-cap <> style [ - dc/pen-cap: style - case [ - style = flat [mode: kCGLineCapButt] - style = square [mode: kCGLineCapSquare] - style = _round [mode: kCGLineCapRound] - true [mode: kCGLineCapButt] - ] - CGContextSetLineCap dc/raw mode + dc/pen-cap: style + case [ + style = flat [mode: kCGLineCapButt] + style = square [mode: kCGLineCapSquare] + style = _round [mode: kCGLineCapRound] + true [mode: kCGLineCapButt] ] + CGContextSetLineCap dc/raw mode ] CG-draw-image: func [ ;@@ use CALayer to get very good performance? @@ -1405,12 +1408,26 @@ OS-matrix-transform: func [ OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ CGContextSaveGState dc/raw + state/pen-clr: dc/pen-color + state/brush-clr: dc/brush-color + state/pen-join: dc/pen-join + state/pen-cap: dc/pen-cap + state/pen?: dc/pen? + state/brush?: dc/brush? + state/a-pen?: dc/grad-pen? + state/a-brush?: dc/grad-brush? ] OS-matrix-pop: func [dc [draw-ctx!] state [draw-state!]][ CGContextRestoreGState dc/raw - dc/pen-color: 0 - dc/brush-color: 0 + dc/pen-color: state/pen-clr + dc/brush-color: state/brush-clr + dc/pen-join: state/pen-join + dc/pen-cap: state/pen-cap + dc/pen?: state/pen? + dc/brush?: state/brush? + dc/grad-pen?: state/a-pen? + dc/grad-brush?: state/a-brush? ] OS-matrix-reset: func [ diff --git a/modules/view/backends/macOS/events.reds b/modules/view/backends/macOS/events.reds index c973ccf6a0..1fdad66deb 100644 --- a/modules/view/backends/macOS/events.reds +++ b/modules/view/backends/macOS/events.reds @@ -392,6 +392,7 @@ get-event-picked: func [ n [integer!] d [float32!] event [integer!] + idx [integer!] ][ as red-value! switch evt/type [ EVT_ZOOM @@ -407,7 +408,10 @@ get-event-picked: func [ int ] ] - EVT_MENU [word/push* evt/flags and FFFFh] + EVT_MENU [ + idx: evt/flags and FFFFh + either idx = FFFFh [none/push][word/push* idx] + ] EVT_SCROLL [integer/push evt/flags >>> 4] EVT_WHEEL [ event: objc_getAssociatedObject as-integer evt/msg RedNSEventKey diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index 0d72d05b67..94e9590822 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -683,7 +683,7 @@ update-z-order: func [ parr nb ] free as byte-ptr! parr - if type = window [parent: objc_msgSend [parent sel_getUid "contentView"]] + if any [type = window type = group-box] [parent: objc_msgSend [parent sel_getUid "contentView"]] objc_msgSend [parent sel_getUid "setSubviews:" arr] ] @@ -1816,7 +1816,7 @@ OS-make-view: func [ len: -1 CFString((unicode/to-utf8 str :len)) ][ - 0 + CFString("") ] rc: make-rect offset/x offset/y size/x size/y case [ @@ -2183,21 +2183,31 @@ OS-to-image: func [ return: [red-image!] /local view [integer!] + cview [integer!] data [integer!] - rc [NSRect!] + rect [RECT_STRUCT value] + rc [NSRect! value] + rc2 [NSRect! value] + h [float32!] sz [red-pair!] bmp [integer!] + bmp2 [integer!] + bmp3 [integer!] img [integer!] ret [red-image!] type [integer!] word [red-word!] + rep [integer!] + id [integer!] ][ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol case [ type = screen [ - bmp: CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF + rect/left: 0 rect/top: 0 rect/right: 7F800000h rect/bottom: 7F800000h + bmp: CGWindowListCreateImage as NSRect! rect 1 0 0 ;-- INF ret: image/init-image as red-image! stack/push* OS-image/load-cgimage as int-ptr! bmp + objc_msgSend [bmp sel_getUid "retain"] ] type = camera [ view: as-integer face-handle? face @@ -2211,16 +2221,49 @@ OS-to-image: func [ view: as-integer face-handle? face either zero? view [ret: as red-image! none-value][ sz: as red-pair! (object/get-values face) + FACE_OBJ_SIZE - rc: make-rect 0 0 sz/x sz/y - data: objc_msgSend [view sel_getUid "dataWithPDFInsideRect:" rc/x rc/y rc/w rc/h] - img: objc_msgSend [ - objc_msgSend [objc_getClass "NSImage" sel_alloc] - sel_getUid "initWithData:" data + either type = window [ + rc: objc_msgSend_rect [view sel_getUid "frame"] + cview: objc_msgSend [view sel_getUid "contentView"] + rc2: objc_msgSend_rect [cview sel_getUid "frame"] + h: rc/h - rc2/h + rc/y: rc/y - h + rc/h: h + id: objc_msgSend [view sel_getUid "windowNumber"] + ;-- title + bmp: CGWindowListCreateImage rc 8 id 1 or 8 + + ;-- content + rep: objc_msgSend [cview sel_getUid "bitmapImageRepForCachingDisplayInRect:" rc2/x rc2/y rc2/w rc2/h] + objc_msgSend [cview sel_getUid "cacheDisplayInRect:toBitmapImageRep:" rc2/x rc2/y rc2/w rc2/h rep] + img: objc_msgSend [ + objc_msgSend [objc_getClass "NSImage" sel_alloc] + sel_getUid "initWithSize:" as float! rc2/w as float! rc2/h + ] + objc_msgSend [img sel_getUid "addRepresentation:" rep] + bmp2: objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] + + ;-- combine + bmp3: OS-image/combine-image bmp bmp2 0 + + ret: image/init-image as red-image! stack/push* OS-image/load-cgimage as int-ptr! bmp3 + ;CGImageRelease bmp + ;CGImageRelease bmp2 + objc_msgSend [img sel_release] + objc_msgSend [bmp3 sel_getUid "retain"] + ][ + rc: objc_msgSend_rect [view sel_getUid "bounds"] + rep: objc_msgSend [view sel_getUid "bitmapImageRepForCachingDisplayInRect:" rc/x rc/y rc/w rc/h] + objc_msgSend [view sel_getUid "cacheDisplayInRect:toBitmapImageRep:" rc/x rc/y rc/w rc/h rep] + img: objc_msgSend [ + objc_msgSend [objc_getClass "NSImage" sel_alloc] + sel_getUid "initWithSize:" as float! rc/w as float! rc/h + ] + objc_msgSend [img sel_getUid "addRepresentation:" rep] + bmp: objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] + ret: image/init-image as red-image! stack/push* OS-image/load-cgimage as int-ptr! bmp + objc_msgSend [bmp sel_getUid "retain"] + objc_msgSend [img sel_release] ] - bmp: objc_msgSend [img sel_getUid "CGImageForProposedRect:context:hints:" 0 0 0] - ret: image/init-image as red-image! stack/push* OS-image/load-cgimage as int-ptr! bmp - objc_msgSend [bmp sel_getUid "retain"] - objc_msgSend [img sel_release] ] ] ] diff --git a/modules/view/backends/macOS/menu.reds b/modules/view/backends/macOS/menu.reds index 0f4a4eb81e..ff8d4128f2 100644 --- a/modules/view/backends/macOS/menu.reds +++ b/modules/view/backends/macOS/menu.reds @@ -134,7 +134,7 @@ build-menu: func [ title 0 key ] objc_msgSend [item sel_getUid "setTarget:" target] - if next < tail [ + either next < tail [ switch TYPE_OF(next) [ TYPE_BLOCK [ sub-menu: objc_msgSend [objc_getClass "NSMenu" sel_getUid "alloc"] @@ -149,8 +149,14 @@ build-menu: func [ objc_msgSend [item sel_getUid "setAction:" action] value: value + 1 ] - default [0] + default [ + objc_msgSend [item sel_getUid "setTag:" -1] + objc_msgSend [item sel_getUid "setAction:" action] + ] ] + ][ + objc_msgSend [item sel_getUid "setTag:" -1] + objc_msgSend [item sel_getUid "setAction:" action] ] ] TYPE_WORD [ diff --git a/modules/view/backends/windows/button.reds b/modules/view/backends/windows/button.reds index 45d034d3d0..07d0f88c30 100644 --- a/modules/view/backends/windows/button.reds +++ b/modules/view/backends/windows/button.reds @@ -54,30 +54,42 @@ init-button: func [ width: size/x height: size/y ] - default [exit] + default [ + imgs: null + ] ] - - sz: either 1 < num [6][1] - hlist: ImageList_Create width height ILC_COLOR32 sz 0 - beg: as red-image! block/rs-head imgs - img-1: image/resize beg width height - i: 0 - loop sz [ - either i < num [ - img: beg + i - img: either zero? i [img-1][image/resize img width height] - ][ - img: img-1 + SendMessage hWnd BCM_GETIMAGELIST 0 as integer! BIL + if all [ + BIL/handle <> 0 + BIL/handle <> -1 + ][ + ImageList_Destroy BIL/handle + ] + either null? imgs [ + BIL/handle: -1 + ][ + sz: either 1 < num [6][1] + hlist: ImageList_Create width height ILC_COLOR32 sz 0 + beg: as red-image! block/rs-head imgs + img-1: image/resize beg width height + i: 0 + loop sz [ + either i < num [ + img: beg + i + img: either zero? i [img-1][image/resize img width height] + ][ + img: img-1 + ] + bitmap: 0 + GdipCreateHBITMAPFromBitmap as-integer img/node :bitmap 0 + ImageList_Add hlist bitmap 0 + DeleteObject as handle! bitmap + if all [i > 0 i < num][image/delete img] + i: i + 1 ] - bitmap: 0 - GdipCreateHBITMAPFromBitmap as-integer img/node :bitmap 0 - ImageList_Add hlist bitmap 0 - DeleteObject as handle! bitmap - if all [i > 0 i < num][image/delete img] - i: i + 1 + image/delete img-1 + BIL/handle: hlist ] - image/delete img-1 - BIL/handle: hlist BIL/align: 4 SendMessage hWnd BM_SETSTYLE BS_BITMAP or GetWindowLong hWnd GWL_STYLE 0 SendMessage hWnd BCM_SETIMAGELIST 0 0 diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 4c5710aa00..2c1db25a6a 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -115,8 +115,8 @@ get-event-offset: func [ y: 0 - (y or FFFF0000h) ] pt: screen-to-client msg/hWnd x y - offset/x: pt/x - offset/y: pt/y + offset/x: pt/x * 100 / dpi-factor + offset/y: pt/y * 100 / dpi-factor as red-value! offset ] any [ @@ -133,12 +133,11 @@ get-event-offset: func [ either evt/flags and EVT_FLAG_AWAY <> 0 [ msg: as tagMSG evt/msg pt: declare tagPOINT - pt/x: WIN32_LOWORD(value) - pt/y: WIN32_HIWORD(value) - ClientToScreen get-child-from-xy msg/hWnd pt/x pt/y pt + pt/x: 0 pt/y: 0 + GetCursorPos pt x: pt/x y: pt/y - pt: get-window-pos msg/hWnd + pt/x: 0 pt/y: 0 ClientToScreen msg/hWnd pt offset/x: x - pt/x * 100 / dpi-factor offset/y: y - pt/y * 100 / dpi-factor @@ -158,8 +157,8 @@ get-event-offset: func [ value: GetMessagePos pt: screen-to-client msg/hWnd WIN32_LOWORD(value) WIN32_HIWORD(value) - offset/x: pt/x - offset/y: pt/y + offset/x: pt/x * 100 / dpi-factor + offset/y: pt/y * 100 / dpi-factor as red-value! offset ] any [ @@ -175,15 +174,15 @@ get-event-offset: func [ offset/header: TYPE_PAIR value: gi/ptsLocation ;-- coordinates of center point - offset/x: WIN32_LOWORD(value) - offset/y: WIN32_HIWORD(value) + offset/x: WIN32_LOWORD(value) * 100 / dpi-factor + offset/y: WIN32_HIWORD(value) * 100 / dpi-factor as red-value! offset ] evt/type = EVT_MENU [ offset: as red-pair! stack/push* offset/header: TYPE_PAIR - offset/x: menu-x - offset/y: menu-y + offset/x: menu-x * 100 / dpi-factor + offset/y: menu-y * 100 / dpi-factor as red-value! offset ] true [as red-value! none-value] @@ -319,7 +318,7 @@ get-event-picked: func [ ] EVT_MENU [ idx: evt/flags and FFFFh - either idx = 65535 [none/push][word/push* idx] + either idx = FFFFh [none/push][word/push* idx] ] EVT_SCROLL [ integer/push get-track-pos msg/hWnd msg/msg = WM_VSCROLL @@ -749,7 +748,7 @@ paint-background: func [ values: get-face-values hWnd color: as red-tuple! values + FACE_OBJ_COLOR - either win8+? [ + either any [win8+? color/array1 and FF000000h = 0][ ;-- use plain old GDI fill when it's possible either TYPE_OF(color) = TYPE_TUPLE [ hBrush: CreateSolidBrush color/array1 and 00FFFFFFh diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 418e0bc662..557ec94da2 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1467,10 +1467,10 @@ OS-make-view: func [ AdjustWindowRectEx rc flags menu-bar? menu window ws-flags rc/right: rc/right - rc/left rc/bottom: rc/bottom - rc/top - focused: null + focused: null if bits and FACET_FLAGS_MODAL <> 0 [ parent: as-integer find-last-window - focused: get-selected-handle as handle! parent + if parent <> 0 [focused: get-selected-handle as handle! parent] ] ] true [ ;-- search in user-defined classes @@ -1540,10 +1540,7 @@ OS-make-view: func [ sym = camera [init-camera handle data selected false] sym = text-list [init-text-list handle data selected] sym = base [init-base-face handle parent values alpha?] - sym = tab-panel [ - selected/header: TYPE_NONE ;-- no selection allowed before tabs are created - set-tabs handle values - ] + sym = tab-panel [set-tabs handle values] sym = group-box [ flags: flags or WS_GROUP or BS_GROUPBOX hWnd: CreateWindowEx @@ -1926,6 +1923,7 @@ change-image: func [ type [integer!] ][ if type = base [update-base hWnd null null values] + if type = button [init-button hWnd values] ] change-selection: func [ diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 30378f7d7c..ba21b22195 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -500,6 +500,7 @@ Red/System [ #define ILC_COLOR32 20h #define BCM_SETIMAGELIST 1602h +#define BCM_GETIMAGELIST 1603h #define BCM_SETTEXTMARGIN 1604h #define ICC_LISTVIEW_CLASSES 00000001h ;-- listview, header @@ -1050,6 +1051,10 @@ XFORM!: alias struct! [ ] ] "User32.dll" stdcall [ + GetCursorPos: "GetCursorPos" [ + pt [tagPOINT] + return: [logic!] + ] TrackMouseEvent: "TrackMouseEvent" [ EventTrack [tagTRACKMOUSEEVENT] return: [logic!] diff --git a/modules/view/view.red b/modules/view/view.red index c8e635deb6..8beb550d31 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -1025,9 +1025,9 @@ foreach-face: function [ exec: [either block? :body [do body][body face]] foreach face face/pane [ - unless post? [either spec [all [do spec do exec]][do exec]] + unless post? [either spec [all [do spec try exec]][try exec]] if block? face/pane [foreach-face/with/sub face :body spec post?] - if post? [either spec [all [do spec do exec]][do exec]] + if post? [either spec [all [do spec try exec]][try exec]] ] ] diff --git a/red.r b/red.r index d442cf56c7..aaeb8a344e 100644 --- a/red.r +++ b/red.r @@ -473,7 +473,7 @@ redc: context [ ][ files2: pick [ [%core.red %highlight.red %settings.red %tips.red] - [%input.red %wcwidth.reds %win32.reds %POSIX.reds] + [%input.red %wcwidth.reds %win32.reds %POSIX.reds %settings.red] ] gui? if gui? [write/binary td/app.ico read-binary-cache console/app.ico] ] diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index 8a0ed1abb5..c9dd9b497c 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -1433,7 +1433,7 @@ binary: context [ ;-- General actions -- INHERIT_ACTION ;make INHERIT_ACTION ;random - null ;reflect + INHERIT_ACTION ;reflect :to :form :mold diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 009b4240cd..910ab96724 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1201,22 +1201,22 @@ block: context [ switch TYPE_OF(res) [ TYPE_LOGIC [ bool: as red-logic! res - either bool/value [1][-1] + either bool/value [-1][1] ] TYPE_INTEGER [ int: as red-integer! res - 0 - int/value + int/value ] TYPE_FLOAT [ d: as red-float! res case [ - d/value > 0.0 [-1] - d/value < 0.0 [1] + d/value > 0.0 [1] + d/value < 0.0 [-1] true [0] ] ] - TYPE_NONE [-1] - default [1] + TYPE_NONE [1] + default [-1] ] ] diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index f966482f0e..846bbee7f3 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -555,8 +555,9 @@ _context: context [ s [series!] ][ s: GET_BUFFER(spec) - cell: s/offset + cell: s/offset + spec/head tail: s/tail + assert cell <= tail s: as series! ctx/symbols/value base: s/tail - s/offset diff --git a/runtime/datatypes/error.reds b/runtime/datatypes/error.reds index 7408a4ddb1..8b4e497e8d 100644 --- a/runtime/datatypes/error.reds +++ b/runtime/datatypes/error.reds @@ -365,6 +365,40 @@ error: context [ string/append-char GET_BUFFER(buffer) as-integer #"]" part - 1 ] + + eval-path: func [ + parent [red-object!] ;-- implicit type casting + element [red-value!] + value [red-value!] + path [red-value!] + case? [logic!] + return: [red-value!] + ][ + #if debug? = yes [if verbose > 0 [print-line "error/eval-path"]] + + if value <> null [fire [TO_ERROR(script invalid-path-set) path]] + object/eval-path parent element value path case? + ] + + compare: func [ + obj1 [red-object!] ;-- first operand + obj2 [red-object!] ;-- second operand + op [integer!] ;-- type of comparison + return: [integer!] + /local + res [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "error/compare"]] + + either TYPE_OF(obj2) = TYPE_ERROR [ + set-type as red-value! obj2 TYPE_OBJECT + res: object/compare obj1 obj2 op + set-type as red-value! obj2 TYPE_ERROR + ][ + RETURN_COMPARE_OTHER + ] + res + ] init: does [ datatype/register [ @@ -378,9 +412,9 @@ error: context [ null ;to :form :mold - INHERIT_ACTION ;eval-path + :eval-path null ;set-path - INHERIT_ACTION ;compare + :compare ;-- Scalar actions -- null ;absolute null ;add diff --git a/runtime/datatypes/event.reds b/runtime/datatypes/event.reds index 334a374b25..ca3b00b44b 100644 --- a/runtime/datatypes/event.reds +++ b/runtime/datatypes/event.reds @@ -103,7 +103,7 @@ event: context [ sym: symbol/resolve word/symbol either value <> null [ - if sym <> words/type [fire [TO_ERROR(script invalid-path-set) path]] + if sym <> words/type [fire [TO_ERROR(script bad-path-set) path word]] if TYPE_OF(value) <> TYPE_WORD [fire [TO_ERROR(script bad-path-set) path value]] gui/set-event-type evt as red-word! value value diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index c7fe584a28..3a976d6b6d 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -856,17 +856,12 @@ float: context [ dec: f/value sc: either TYPE_OF(f) = TYPE_PERCENT [0.01][1.0] if OPTION?(scale) [ - if TYPE_OF(scale) = TYPE_INTEGER [ - int: as red-integer! value - either dec < 0.0 [ - int/value: as-integer dec - 0.5 - ][ - int/value: as-integer dec + 0.5 - ] - int/header: TYPE_INTEGER - return integer/round value as red-integer! scale _even? down? half-down? floor? ceil? half-ceil? + either TYPE_OF(scale) = TYPE_INTEGER [ + int: as red-integer! scale + sc: abs as float! int/value + ][ + sc: abs scale/value ] - sc: abs scale/value if TYPE_OF(f) = TYPE_PERCENT [sc: sc / 100.0] if sc = 0.0 [fire [TO_ERROR(math overflow)]] ] @@ -906,6 +901,20 @@ float: context [ ][ ldexp dec / sc e ] + if OPTION?(scale) [ + either TYPE_OF(scale) = TYPE_INTEGER [ + dec: f/value + int: as red-integer! value + int/header: TYPE_INTEGER + int/value: as integer! dec + ][ + value/header: either TYPE_OF(scale) = TYPE_PERCENT [ + TYPE_FLOAT + ][ + TYPE_OF(scale) + ] + ] + ] value ] diff --git a/runtime/datatypes/hash.reds b/runtime/datatypes/hash.reds index 6557abd765..27f0a1bff5 100644 --- a/runtime/datatypes/hash.reds +++ b/runtime/datatypes/hash.reds @@ -175,7 +175,7 @@ hash: context [ ;-- General actions -- :make null ;random - null ;reflect + INHERIT_ACTION ;reflect :to INHERIT_ACTION ;form :mold diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index f6a1b77d26..ca1984af56 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -492,7 +492,9 @@ integer: context [ char: as red-char! value2 ;@@ could be optimized as integer! and char! right: char/value ;@@ structures are overlapping exactly ] - TYPE_FLOAT TYPE_PERCENT [ + TYPE_FLOAT + TYPE_TIME + TYPE_PERCENT [ f: as red-float! value1 left: value1/value f/value: as-float left @@ -702,7 +704,7 @@ integer: context [ if num = 80000000h [return value] sc: 1 if OPTION?(scale) [ - if TYPE_OF(scale) = TYPE_FLOAT [ + if TYPE_OF(scale) <> TYPE_INTEGER [ f: as red-float! value f/value: as-float num f/header: TYPE_FLOAT diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index b85ba4bd44..c994b1ea34 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -412,7 +412,7 @@ object: context [ ctx: GET_CTX(obj) s: as series! ctx/values/value fun: as red-function! s/offset + index - if TYPE_OF(fun) <> TYPE_FUNCTION [fire [TO_ERROR(script invalid-arg) fun]] + if TYPE_OF(fun) <> TYPE_FUNCTION [fire [TO_ERROR(script invalid-obj-evt) fun]] stack/mark-func words/_on-change* fun/ctx stack/push as red-value! word @@ -442,7 +442,7 @@ object: context [ #if debug? = yes [if verbose > 0 [print-line "object/fire-on-deep"]] assert TYPE_OF(owner) = TYPE_OBJECT - assert owner/on-set <> null + if null? owner/on-set [fire [TO_ERROR(script invalid-obj-evt) owner]] s: as series! owner/on-set/value int: as red-integer! s/offset + 1 @@ -712,8 +712,8 @@ object: context [ base: s/tail - s/offset s: as series! ctx/values/value - node: save-self-object obj + ;-- 1st pass: fill and eventually extend the context while [syms < tail][ value: _context/add-with ctx as red-word! syms vals @@ -722,12 +722,22 @@ object: context [ value: s/offset + _context/find-word ctx word/symbol yes copy-cell vals value ] + syms: syms + 1 + vals: vals + 1 + ] + + ;-- 2nd pass: deep copy series and rebind functions + node: save-self-object obj + value: s/offset + tail: s/tail + + while [value < tail][ type: TYPE_OF(value) case [ ANY_SERIES?(type) [ actions/copy as red-series! value - value ;-- overwrite the value + value ;-- overwrite the value null yes null @@ -737,8 +747,7 @@ object: context [ ] true [0] ] - syms: syms + 1 - vals: vals + 1 + value: value + 1 ] s: as series! ctx/symbols/value ;-- refreshing pointer s/tail - s/offset > base ;-- TRUE: new words added @@ -944,16 +953,16 @@ object: context [ return: [red-object!] /local obj [red-object!] - ctx [red-context!] ][ obj: as red-object! stack/push* - make-at obj 4 ;-- arbitrary value - obj/class: get-new-id - obj/on-set: null - ctx: GET_CTX(obj) - - unless null? proto [extend ctx GET_CTX(proto) obj] - collect-couples ctx spec only? + either null? proto [ + make-at obj 4 ;-- arbitrary value + obj/class: get-new-id + obj/on-set: null + ][ + copy proto obj null yes null + ] + collect-couples GET_CTX(obj) spec only? obj ] @@ -1255,8 +1264,8 @@ object: context [ type1 = type2 all [word/any-word? type1 word/any-word? type2] all [ ;@@ replace by ANY_NUMBER? - any [type1 = TYPE_INTEGER type1 = TYPE_FLOAT] - any [type2 = TYPE_INTEGER type2 = TYPE_FLOAT] + any [type1 = TYPE_INTEGER type1 = TYPE_FLOAT type1 = TYPE_PERCENT] + any [type2 = TYPE_INTEGER type2 = TYPE_FLOAT type2 = TYPE_PERCENT] ] ][ res: actions/compare-value value1 value2 op diff --git a/runtime/datatypes/op.reds b/runtime/datatypes/op.reds index f5eb0568c7..a7d03d63ec 100644 --- a/runtime/datatypes/op.reds +++ b/runtime/datatypes/op.reds @@ -86,7 +86,7 @@ op: context [ flag: 0 type: TYPE_OF(spec) unless any [ - type = TYPE_BLOCK + ;type = TYPE_BLOCK type = TYPE_ACTION ;@@ replace with ANY_NATIVE? when available type = TYPE_NATIVE type = TYPE_OP @@ -95,12 +95,12 @@ op: context [ ][fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(spec)]] node: switch type [ - TYPE_BLOCK [ - s: GET_BUFFER(spec) - blk: as red-block! s/offset - if blk + blk/head + 2 <> s/tail [throw-make proto spec] - blk/node - ] + ;TYPE_BLOCK [ + ; s: GET_BUFFER(spec) + ; blk: as red-block! s/offset + ; if blk + blk/head + 2 <> s/tail [throw-make proto spec] + ; blk/node + ;] TYPE_ACTION TYPE_NATIVE TYPE_OP [ diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index cc7d68e039..a8dd704293 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -306,11 +306,9 @@ pair: context [ ][ #if debug? = yes [if verbose > 0 [print-line "pair/compare"]] - if TYPE_OF(right) <> TYPE_PAIR [ - return either any [op = COMP_FIND op = COMP_STRICT_EQUAL][1][RETURN_COMPARE_OTHER] - ] - diff: left/y - right/y - if zero? diff [diff: left/x - right/x] + if TYPE_OF(right) <> TYPE_PAIR [RETURN_COMPARE_OTHER] + diff: left/x - right/x + if zero? diff [diff: left/y - right/y] SIGN_COMPARE_RESULT(diff 0) ] diff --git a/runtime/datatypes/port.reds b/runtime/datatypes/port.reds index 3163e8945d..4c0ee94ac4 100644 --- a/runtime/datatypes/port.reds +++ b/runtime/datatypes/port.reds @@ -24,21 +24,24 @@ port: context [ ] call-function: func [ - actor [red-function!] - ctx [node!] + actors [red-object!] + action [red-word!] return: [red-value!] /local + actor [red-function!] count [integer!] ][ + actor: as red-function! object/rs-select actors as red-value! action + if TYPE_OF(actor) <> TYPE_FUNCTION [fire [TO_ERROR(access no-port-action) action]] + count: _function/calc-arity null actor 0 if positive? count [_function/init-locals count] - _function/call actor ctx + _function/call actor actors/ctx stack/unwind-last ] get-actors: func [ port [red-object!] - action [red-word!] return: [red-object!] /local actors [red-object!] @@ -48,18 +51,6 @@ port: context [ actors ] - get-actor: func [ - actors [red-object!] - action [red-word!] - return: [red-function!] - /local - actor [red-function!] - ][ - actor: as red-function! object/rs-select actors as red-value! action - if TYPE_OF(actor) <> TYPE_FUNCTION [fire [TO_ERROR(access no-port-action) action]] - actor - ] - do-action: func [ action [red-word!] args [integer!] @@ -67,16 +58,14 @@ port: context [ /local port [red-value!] actors [red-object!] - actor [red-function!] ][ port: stack/arguments - actors: get-actors as red-object! port action - actor: get-actor actors action + actors: get-actors as red-object! port stack/mark-func action actors/ctx stack/push port if args > 1 [stack/push port + 1] - call-function actor actors/ctx + call-function actors action ] do-action-port: func [ @@ -85,13 +74,11 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ - actors: get-actors port action - actor: get-actor actors action + actors: get-actors port stack/mark-func action actors/ctx stack/push as red-value! port - call-function actor actors/ctx + call-function actors action ] ;-- actions -- @@ -260,7 +247,6 @@ port: context [ dup [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] dup? [logic!] ][ @@ -268,8 +254,7 @@ port: context [ part?: OPTION?(part) dup?: OPTION?(dup) - actors: get-actors as red-object! port words/_change - actor: get-actor actors words/_change + actors: get-actors as red-object! port stack/mark-func words/_change actors/ctx stack/push as red-value! port stack/push value @@ -278,7 +263,7 @@ port: context [ logic/push only? logic/push dup? either dup? [stack/push dup][none/push] - call-function actor actors/ctx + call-function actors words/_change ] find: func [ @@ -298,7 +283,6 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] with? [logic!] skip? [logic!] @@ -308,8 +292,7 @@ port: context [ part?: OPTION?(part) with?: OPTION?(with-arg) skip?: OPTION?(skip) - actors: get-actors as red-object! port words/_find - actor: get-actor actors words/_find + actors: get-actors as red-object! port stack/mark-func words/_find actors/ctx stack/push as red-value! port stack/push value @@ -327,7 +310,7 @@ port: context [ logic/push reverse? logic/push tail? logic/push match? - call-function actor actors/ctx + call-function actors words/_find ] insert: func [ @@ -340,7 +323,6 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] dup? [logic!] ][ @@ -348,8 +330,7 @@ port: context [ part?: OPTION?(part) dup?: OPTION?(dup) - actors: get-actors as red-object! port words/_insert - actor: get-actor actors words/_insert + actors: get-actors as red-object! port stack/mark-func words/_insert actors/ctx stack/push as red-value! port stack/push value @@ -359,7 +340,7 @@ port: context [ logic/push dup? either dup? [stack/push dup][none/push] logic/push append? - call-function actor actors/ctx + call-function actors words/_insert ] move: func [ @@ -369,20 +350,18 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "port/move"]] part?: OPTION?(part) - actors: get-actors as red-object! port words/_move - actor: get-actor actors words/_move + actors: get-actors as red-object! port stack/mark-func words/_move actors/ctx stack/push as red-value! port stack/push target logic/push part? either part? [stack/push as red-value! part][none/push] - call-function actor actors/ctx + call-function actors words/_move ] copy: func [ @@ -394,7 +373,6 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] types? [logic!] ][ @@ -402,8 +380,7 @@ port: context [ part?: OPTION?(part) types?: OPTION?(types) - actors: get-actors as red-object! port words/_copy - actor: get-actor actors words/_copy + actors: get-actors as red-object! port stack/mark-func words/_copy actors/ctx stack/push as red-value! port logic/push part? @@ -411,7 +388,7 @@ port: context [ logic/push deep? logic/push types? either types? [stack/push types][none/push] - call-function actor actors/ctx + call-function actors words/_copy copy-cell stack/arguments new ] @@ -447,18 +424,16 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/modify"]] - actors: get-actors port words/_modify - actor: get-actor actors words/_modify + actors: get-actors port stack/mark-func words/_modify actors/ctx stack/push as red-value! port stack/push field stack/push value logic/push case? - call-function actor actors/ctx + call-function actors words/_modify ] open: func [ @@ -471,12 +446,10 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/open"]] - actors: get-actors port words/_open - actor: get-actor actors words/_open + actors: get-actors port stack/mark-func words/_open actors/ctx stack/push as red-value! port logic/push new? @@ -484,7 +457,7 @@ port: context [ logic/push write? logic/push seek? stack/push allow - call-function actor actors/ctx + call-function actors words/_open ] poke: func [ @@ -495,17 +468,15 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/poke"]] - actors: get-actors port words/_poke - actor: get-actor actors words/_poke + actors: get-actors port stack/mark-func words/_poke actors/ctx stack/push as red-value! port stack/push boxed stack/push data - call-function actor actors/ctx + call-function actors words/_poke ] put: func [ @@ -516,18 +487,16 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/put"]] - actors: get-actors port words/_put - actor: get-actor actors words/_put + actors: get-actors port stack/mark-func words/_put actors/ctx stack/push as red-value! port stack/push key stack/push value logic/push case? - call-function actor actors/ctx + call-function actors words/_put ] query: func [ @@ -567,19 +536,17 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "port/remove"]] part?: OPTION?(part) - actors: get-actors as red-object! port words/_remove - actor: get-actor actors words/_remove + actors: get-actors as red-object! port stack/mark-func words/_remove actors/ctx stack/push as red-value! port logic/push part? either part? [stack/push part][none/push] - call-function actor actors/ctx + call-function actors words/_remove ] reverse: func [ @@ -588,19 +555,17 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "port/reverse"]] part?: OPTION?(part) - actors: get-actors as red-object! port words/_reverse - actor: get-actor actors words/_reverse + actors: get-actors as red-object! port stack/mark-func words/_reverse actors/ctx stack/push as red-value! port logic/push part? either part? [stack/push part][none/push] - call-function actor actors/ctx + call-function actors words/_reverse ] rename: func [ @@ -609,16 +574,14 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/rename"]] - actors: get-actors as red-object! from words/_rename - actor: get-actor actors words/_rename + actors: get-actors as red-object! from stack/mark-func words/_rename actors/ctx stack/push from stack/push to - call-function actor actors/ctx + call-function actors words/_rename ] select: func [ @@ -636,7 +599,6 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] with? [logic!] skip? [logic!] @@ -646,8 +608,7 @@ port: context [ part?: OPTION?(part) with?: OPTION?(with-arg) skip?: OPTION?(skip) - actors: get-actors as red-object! port words/_select - actor: get-actor actors words/_select + actors: get-actors as red-object! port stack/mark-func words/_select actors/ctx stack/push as red-value! port stack/push value @@ -663,7 +624,7 @@ port: context [ either skip? [stack/push as red-value! skip][none/push] logic/push last? logic/push reverse? - call-function actor actors/ctx + call-function actors words/_select ] sort: func [ @@ -678,7 +639,6 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] comp? [logic!] skip? [logic!] @@ -688,8 +648,7 @@ port: context [ part?: OPTION?(part) comp?: OPTION?(compare) skip?: OPTION?(skip) - actors: get-actors as red-object! port words/_sort - actor: get-actor actors words/_sort + actors: get-actors as red-object! port stack/mark-func words/_sort actors/ctx stack/push as red-value! port logic/push case? @@ -702,7 +661,7 @@ port: context [ logic/push all? logic/push reverse? logic/push stable? - call-function actor actors/ctx + call-function actors words/_sort ] swap: func [ @@ -711,16 +670,14 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] ][ #if debug? = yes [if verbose > 0 [print-line "port/swap"]] - actors: get-actors as red-object! port words/_sort - actor: get-actor actors words/_sort + actors: get-actors as red-object! port stack/mark-func words/_sort actors/ctx stack/push as red-value! port stack/push series2 - call-function actor actors/ctx + call-function actors words/_sort ] take: func [ @@ -731,21 +688,19 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] part? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "port/take"]] part?: OPTION?(part) - actors: get-actors as red-object! port words/_take - actor: get-actor actors words/_take + actors: get-actors as red-object! port stack/mark-func words/_take actors/ctx stack/push as red-value! port logic/push part? either part? [stack/push part][none/push] logic/push deep? logic/push last? - call-function actor actors/ctx + call-function actors words/_take ] trim: func [ @@ -759,14 +714,12 @@ port: context [ return: [red-value!] /local actors [red-object!] - actor [red-function!] with? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "port/trim"]] with?: OPTION?(with-arg) - actors: get-actors as red-object! port words/_trim - actor: get-actor actors words/_trim + actors: get-actors as red-object! port stack/mark-func words/_trim actors/ctx stack/push as red-value! port logic/push head? @@ -776,7 +729,7 @@ port: context [ logic/push all? logic/push with? either with? [stack/push with-arg][none/push] - call-function actor actors/ctx + call-function actors words/_trim ] update: func [ diff --git a/runtime/datatypes/time.reds b/runtime/datatypes/time.reds index cf1c100a41..d4c3014c0c 100644 --- a/runtime/datatypes/time.reds +++ b/runtime/datatypes/time.reds @@ -409,9 +409,21 @@ time: context [ ceil? [logic!] half-ceil? [logic!] return: [red-value!] + /local + type [integer!] + int [red-integer!] + val [float!] + ret [red-float!] ][ float/round as red-value! tm scale _even? down? half-down? floor? ceil? half-ceil? - as red-value! tm + ret: as red-float! tm + if ret/header = TYPE_INTEGER [ + int: as red-integer! ret + val: as float! int/value + ret/value: val + ] + ret/header: TYPE_TIME + as red-value! ret ] pick: func [ diff --git a/runtime/datatypes/vector.reds b/runtime/datatypes/vector.reds index 04bfab6958..47b243d3c2 100644 --- a/runtime/datatypes/vector.reds +++ b/runtime/datatypes/vector.reds @@ -1124,7 +1124,7 @@ vector: context [ ;-- General actions -- :make INHERIT_ACTION ;random - null ;reflect + INHERIT_ACTION ;reflect null ;to :form :mold diff --git a/runtime/inflate.reds b/runtime/inflate.reds index 98d99f6e65..8a033ae802 100644 --- a/runtime/inflate.reds +++ b/runtime/inflate.reds @@ -775,6 +775,7 @@ zlib-uncompress: func[ b [integer!] c [integer!] res [integer!] + maxLen [integer!] ][ src: source dst: dest @@ -814,7 +815,12 @@ zlib-uncompress: func[ a32: 256 * a32 + a ;--inflate + maxLen: destLen/value res: deflate/uncompress dst destLen (src + 2) (sourceLen - 6) + if maxLen < destLen/value [ + fire [TO_ERROR(script buffer-not-enough) integer/push destLen/value] + ] + if res <> 0 [ return -3 ] diff --git a/runtime/natives.reds b/runtime/natives.reds index 6b7b625901..15b7d9031b 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2476,7 +2476,11 @@ natives: context [ dt: as red-date! stack/arguments dt/header: TYPE_DATE dt/date: platform/get-date utc >= 0 - if _date > -1 [dt/time: 0.0 exit] + if _date > -1 [ + dt/date: dt/date and FFFEFF80h ;-- clear time? flag and TZ data. + dt/time: 0.0 + exit + ] dt/date: DATE_SET_TIME_FLAG(dt/date) tm: platform/get-time yes precise >= 0 @@ -2741,14 +2745,13 @@ natives: context [ TYPE_TUPLE [ tp: as red-tuple! arg2 buf2: (as byte-ptr! tp) + 4 - if size <> TUPLE_SIZE?(tp) [ - fire [TO_ERROR(script out-of-range) arg2] - ] - either max? [ - until [n: n + 1 if buf/n < buf2/n [buf/n: buf2/n] n = size] - ][ - until [n: n + 1 if buf/n > buf2/n [buf/n: buf2/n] n = size] - ] + either size = TUPLE_SIZE?(tp) [ + either max? [ + until [n: n + 1 if buf/n < buf2/n [buf/n: buf2/n] n = size] + ][ + until [n: n + 1 if buf/n > buf2/n [buf/n: buf2/n] n = size] + ] + ][comp?: yes] ] TYPE_FLOAT TYPE_INTEGER [ diff --git a/runtime/parse.reds b/runtime/parse.reds index ba3b684919..a49d50264e 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -959,6 +959,7 @@ parser: context [ ] if loop? [ ;-- Reset state for a new loop + PARSE_SET_INPUT_LENGTH(len) p/input: input/head ;-- set saved pos to new position p/sub: len ;-- set it to a neutral value t/state: cnt + 1 @@ -990,7 +991,7 @@ parser: context [ before: input/head end?: _series/rs-skip as red-series! input 1 match?: before = input/head - if positive? part [match?: input/head >= part or match?] + if positive? part [match?: input/head > part or match?] either match? [ w: as red-word! (block/rs-head rule) + p/rule + 1 ;-- TO/THRU argument diff --git a/runtime/platform/image-quartz.reds b/runtime/platform/image-quartz.reds index d352bfa42f..782e9d4f49 100644 --- a/runtime/platform/image-quartz.reds +++ b/runtime/platform/image-quartz.reds @@ -716,6 +716,43 @@ OS-image: context [ slot ] + combine-image: func [ + img1 [integer!] + img2 [integer!] + mode [integer!] ;-- TBD, default w = max (w1 w2), h = h1 + h2 + return: [integer!] + /local + w1 [integer!] + h1 [integer!] + w2 [integer!] + h2 [integer!] + w [integer!] + h [integer!] + cs [integer!] + rect [NSRect!] + ctx [integer!] + handle [integer!] + ][ + w1: CGImageGetWidth as int-ptr! img1 + h1: CGImageGetHeight as int-ptr! img1 + w2: CGImageGetWidth as int-ptr! img2 + h2: CGImageGetHeight as int-ptr! img2 + + w: w1 + if w1 < w2 [w: w2] + h: h1 + h2 + cs: CGColorSpaceCreateDeviceRGB + ctx: CGBitmapContextCreate null w h 32 w * 16 cs 2101h + rect: make-rect 0 h2 w1 h1 + CGContextDrawImage ctx rect/x rect/y rect/w rect/h img1 + rect: make-rect 0 0 w2 h2 + CGContextDrawImage ctx rect/x rect/y rect/w rect/h img2 + CGColorSpaceRelease cs + handle: CGBitmapContextCreateImage ctx + CGContextRelease ctx + handle + ] + clone: func [ src [red-image!] dst [red-image!] diff --git a/runtime/queue.reds b/runtime/queue.reds new file mode 100644 index 0000000000..0039abb7ad --- /dev/null +++ b/runtime/queue.reds @@ -0,0 +1,158 @@ +Red/System [ + Title: "A Fixed Size FIFO Multi-Producer Multi-Consumer (MPMC) Queue" + Author: "Xie Qingtian" + File: %queue.reds + Tabs: 4 + Rights: "Copyright (C) 2019 Xie Qingtian. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +cacheLinePad!: alias struct! [ ;-- 64 bytes + float1 [float!] + float2 [float!] + float3 [float!] + float4 [float!] + float5 [float!] + float6 [float!] + float7 [float!] + float8 [float!] +] + +qnode!: alias struct! [ + value [int-ptr!] + status [integer!] +] + +queue!: alias struct! [ + capacity [integer!] ;-- size of the data array + capacityMask [integer!] + data [qnode!] ;-- offset to the first element in data + pad1 [cacheLinePad! value] + tail [integer!] + pad2 [cacheLinePad! value] + head [integer!] +] + +queue: context [ + + create: func [ + len [integer!] + return: [queue!] + /local + q [queue!] + ptr [qnode!] + i [integer!] + ][ + if len < 4 [len: 4] + len: 1 << (1 + log-b len) ;-- rounding up to next power of 2 + + q: as queue! allocate size? queue! + q/capacity: len + q/capacityMask: len - 1 + q/tail: 0 + q/head: 0 + ptr: as qnode! allocate len * size? qnode! + q/data: ptr + i: 0 + loop len [ + ptr/status: i + ptr: ptr + 1 + i: i + 1 + ] + q + ] + + destroy: func [ + qe [queue!] + ][ + free as byte-ptr! qe/data + free as byte-ptr! qe + ] + + push: func [ + qe [queue!] + val [int-ptr!] + return: [logic!] + /local + node [qnode!] + next [integer!] + tail [integer!] + ][ + until [ + tail: system/atomic/load :qe/tail + node: qe/data + tail + if (system/atomic/load :node/status) <> tail [return false] ;-- queue is full + next: tail + 1 and qe/capacityMask + system/atomic/cas :qe/tail tail next + ] + node/value: val + system/atomic/store :node/status -1 + true + ] + + pop: func [ + qe [queue!] + return: [int-ptr!] + /local + node [qnode!] + head [integer!] + next [integer!] + ][ + until [ + head: system/atomic/load :qe/head + node: qe/data + head + if (system/atomic/load :node/status) = head [return null] ;-- queue is empty + next: head + 1 and qe/capacityMask + system/atomic/cas :qe/head head next + ] + system/atomic/store :node/status head + node/value + ] + + s-push: func [ + "single producer push, a bit faster than push" + qe [queue!] + val [int-ptr!] + return: [logic!] + /local + tail [integer!] + node [qnode!] + ][ + tail: qe/tail + node: qe/data + tail + if tail <> node/status [return false] ;-- queue is full + qe/tail: tail + 1 and qe/capacityMask + node/value: val + system/atomic/store :node/status -1 + true + ] + + empty?: func [ + qe [queue!] + return: [logic!] + /local + tail [integer!] + ][ + tail: system/atomic/load :qe/tail + qe/head = tail + ] + + size: func [ + qe [queue!] + return: [integer!] + /local + tail [integer!] + head [integer!] + ][ + tail: system/atomic/load :qe/tail + head: system/atomic/load :qe/head + if any [ + tail < head + all [tail = head qe/data/status <> 0] + ][tail: tail + qe/capacity] + tail - head + ] +] \ No newline at end of file diff --git a/runtime/red.reds b/runtime/red.reds index 75ad958fe3..16391240b5 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -25,7 +25,7 @@ red: context [ #default [#include %platform/linux.reds] ] - ;#include %threads.reds + #include %threads.reds #include %allocator.reds #include %crush.reds diff --git a/runtime/threads.reds b/runtime/threads.reds new file mode 100644 index 0000000000..741264b754 --- /dev/null +++ b/runtime/threads.reds @@ -0,0 +1,286 @@ +Red/System [ + Title: "Thread Implementation" + Author: "Xie Qingtian" + File: %threads.reds + Tabs: 4 + Rights: "Copyright (C) 2011-2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +thread-func!: alias function! [ + udata [int-ptr!] ;-- user data + return: [integer!] +] + +thread: context [ + +#either OS = 'Windows [ + + #define WAIT_TIMEOUT 258 + #define WAIT_OBJECT_0 0 + + #import [ + LIBC-file cdecl [ + ;-- use _beginthreadex to be sure libc functions work properly + ;-- use CreateThread Win32 API instead once we get rid of libc + _beginthreadex: "_beginthreadex" [ + security [int-ptr!] + stack_size [integer!] + start [int-ptr!] + arglist [int-ptr!] + initflag [integer!] + thread_id [int-ptr!] + return: [handle!] + ] + _endthreadex: "_endthreadex" [ + retval [integer!] + ] + ] + "kernel32.dll" stdcall [ + ;CreateThread: "CreateThread" [ + ; security [int-ptr!] + ; stack_size [integer!] + ; start [int-ptr!] + ; arglist [int-ptr!] + ; initflag [integer!] + ; thread_id [int-ptr!] + ; return: [handle!] + ;] + ;ExitThread: "ExitThread" [ + ; retval [integer!] + ;] + CloseHandle: "CloseHandle" [ + hObject [handle!] + return: [logic!] + ] + WaitForSingleObject: "WaitForSingleObject" [ + hHandle [handle!] + dwMillisec [integer!] + return: [integer!] + ] + TerminateThread: "TerminateThread" [ + hThread [handle!] + retcode [integer!] + return: [logic!] + ] + GetCurrentThreadId: "GetCurrentThreadId" [ + return: [integer!] + ] + GetExitCodeThread: "GetExitCodeThread" [ + hThread [handle!] + lpExitCode [int-ptr!] + return: [logic!] + ] + ] + ] + + start: func [ + routine [int-ptr!] ;-- thread-func! + args [int-ptr!] + stack-size [integer!] ;-- stack size in bytes. 0: default stack size + return: [handle!] + /local + handle [handle!] + ][ + handle: _beginthreadex null stack-size routine args 0 null + either handle <> as handle! -1 [handle][null] + ] + + detach: func [ + thread [handle!] + ][ + CloseHandle thread + ] + + kill: func [ + thread [handle!] + return: [logic!] + ][ + TerminateThread thread -1 + ] + + stop: func [ + retcode [integer!] + ][ + _endthreadex retcode + ] + + wait: func [ + thread [handle!] + timeout [integer!] + ret [int-ptr!] + return: [integer!] ;-- 1: success, 0: timeout, -1: error + /local + r [integer!] + ][ + r: WaitForSingleObject thread timeout + case [ + r = WAIT_TIMEOUT [0] + r < WAIT_OBJECT_0 [-1] + ret <> null [ + GetExitCodeThread thread ret + 1 + ] + true [1] + ] + ] + + id?: func [ + "return current thread id" + return: [integer!] + ][ + GetCurrentThreadId + ] +][ ;-- POSIX + + #define ESRCH 3 + + pthread_attr_t: alias struct! [ ;-- 36 bytes + _pad1 [integer!] + _pad2 [integer!] + _pad3 [integer!] + _pad4 [integer!] + _pad5 [integer!] + _pad6 [integer!] + _pad7 [integer!] + _pad8 [integer!] + _pad9 [integer!] + ] + + timespec!: alias struct! [ + sec [integer!] ;Seconds + nsec [integer!] ;Nanoseconds + ] + + #either OS = 'macOS [ + #define LIBPTHREAD-file "libpthread.dylib" + ][ + #define LIBPTHREAD-file "libpthread.so.0" + ] + + #import [ + LIBPTHREAD-file cdecl [ + pthread_attr_init: "pthread_attr_init" [ + attr [pthread_attr_t] + return: [integer!] + ] + pthread_attr_destroy: "pthread_attr_destroy" [ + attr [pthread_attr_t] + return: [integer!] + ] + pthread_attr_setstacksize: "pthread_attr_setstacksize" [ + attr [pthread_attr_t] + stack_size [integer!] + return: [integer!] + ] + pthread_create: "pthread_create" [ + thread [int-ptr!] + attr [pthread_attr_t] + start [int-ptr!] + arglist [int-ptr!] + return: [integer!] + ] + ;#if OS = 'Linux [ + ;pthread_timedjoin_np: "pthread_timedjoin_np" [ + ; thread [int-ptr!] + ; retval [int-ptr!] + ; abstime [timespec!] + ; return: [integer!] + ;]] + pthread_detach: "pthread_detach" [ + thread [int-ptr!] + return: [integer!] + ] + pthread_join: "pthread_join" [ + thread [int-ptr!] + retval [int-ptr!] + return: [integer!] + ] + pthread_exit: "pthread_exit" [ + retval [integer!] + ] + pthread_cancel: "pthread_cancel" [ + thread [int-ptr!] + return: [integer!] + ] + pthread_self: "pthread_self" [ + return: [integer!] + ] + ] + ] + + start: func [ + routine [int-ptr!] + args [int-ptr!] + stack [integer!] + return: [handle!] + /local + attr [pthread_attr_t value] + a [pthread_attr_t] + t [integer!] + ret [integer!] + ][ + t: 0 + either stack > 0 [ + either zero? pthread_attr_init :attr [ + pthread_attr_setstacksize :attr stack + ][ + pthread_attr_destroy :attr + return null + ] + a: :attr + ][a: null] + + ret: pthread_create :t a routine args + if stack > 0 [pthread_attr_destroy a] + either zero? ret [as handle! t][null] + ] + + detach: func [ + thread [handle!] + ][ + pthread_detach thread + ] + + kill: func [ + thread [handle!] + return: [logic!] + ][ + zero? pthread_cancel thread + ] + + stop: func [ + retcode [integer!] + ][ + pthread_exit retcode + ] + + wait: func [ + thread [handle!] + timeout [integer!] + retval [int-ptr!] + return: [integer!] + /local + ret [integer!] + r [integer!] + ][ + ret: 0 + r: pthread_join thread :ret + either all [r = -1 r <> ESRCH][-1][ + if retval <> null [retval/value: ret] + 1 + ] + ] + + id?: func [ + "return current thread id" + return: [integer!] + ][ + pthread_self + ] +] + +] \ No newline at end of file diff --git a/system/compiler.r b/system/compiler.r index 62494618f5..ae9cc0aac7 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -414,7 +414,7 @@ system-dialect: make-profilable context [ none ] - system-action?: func [path [path!] /local expr port-type][ + system-action?: func [path [path!] /local expr port-type op ret?][ if path/1 = 'system [ switch/default path/2 [ stack [ @@ -485,6 +485,78 @@ system-dialect: make-profilable context [ ] ][false] ] + atomic [ + switch/default path/3 [ + fence [ + pc: next pc + emitter/target/emit-atomic-fence + true + ] + cas [ + pc: next pc + err: "system/atomic/cas expects " + repeat i 3 [ + if not-equal? + first get-type pc/:i + pick [pointer! integer! integer!] i + [ + throw-error join err pick [ + "a pointer! as argument" + "an integer! as check argument" + "an integer! as value argument" + ] i + ] + ] + ret?: not empty? expr-call-stack + fetch-expression/final/keep 'atomic + emitter/target/emit-atomic-cas pc/1 pc/2 ret? 'seq-cst + last-type: [logic!] + pc: skip pc 2 + true + ] + load [ + pc: next pc + if 'pointer! <> first get-type pc/1 [ + throw-error "system/atomic/load expects a pointer! as argument" + ] + fetch-expression/final/keep 'atomic + emitter/target/emit-atomic-load 'seq-cst + last-type: [integer!] + true + ] + store [ + pc: next pc + err: "system/atomic/store expects " + if 'pointer! <> first get-type pc/1 [ + throw-error join err "a pointer! as argument" + ] + if 'integer! <> first last-type: get-type pc/2 [ + throw-error join err "an integer! as value argument" + ] + fetch-expression/final/keep 'atomic + emitter/target/emit-atomic-store pc/1 'seq-cst + pc: next pc + true + ] + ][ + either find [add sub or xor and] op: path/3 [ + pc: next pc + if 'pointer! <> first get-type pc/1 [ + throw-error rejoin ["system/atomic/" op " expects a pointer! as argument"] + ] + if 'integer! <> first last-type: get-type pc/2 [ + throw-error rejoin ["system/atomic/" op " expects an integer! as value argument"] + ] + ret?: not empty? expr-call-stack + fetch-expression/final/keep 'atomic + emitter/target/emit-atomic-math op pc/1 path/4 = 'old ret? 'seq-cst + pc: next pc + true + ][ + false + ] + ] + ] ][false] ] ] @@ -1770,7 +1842,7 @@ system-dialect: make-profilable context [ ] ] - process-get: func [code [block!] /local value][ + process-get: func [code [block!]][ unless job/red-pass? [ ;-- when Red runtime is included in a R/S app pc: skip pc 2 ;-- just ignore #get directive return none @@ -1781,7 +1853,7 @@ system-dialect: make-profilable context [ fetch-expression #get ] - process-in: func [code [block!] /local value][ + process-in: func [code [block!]][ unless job/red-pass? [ ;-- when Red runtime is included in a R/S app pc: skip pc 2 ;-- just ignore #in directive return none @@ -3283,6 +3355,7 @@ system-dialect: make-profilable context [ ] boxed: expr expr: either any-float? boxed/type [cast/quiet expr][cast expr] + if object? expr [comp-expression expr keep?] ] ;-- dead expressions elimination diff --git a/system/formats/ELF.r b/system/formats/ELF.r index 6c891231fb..2e75b8db8b 100644 --- a/system/formats/ELF.r +++ b/system/formats/ELF.r @@ -383,7 +383,7 @@ context [ ".text" data (job/sections/code/2) ".stabstr" data (to-elf-strtab join ["%_"] extract natives 2) ".shstrtab" data (to-elf-strtab sections) - ".ARM.attributes" data (build-arm-attributes job/ABI) + ".ARM.attributes" data (build-arm-attributes job/ABI job/cpu-version) ] layout: layout-binary structure commands @@ -849,11 +849,17 @@ context [ build-arm-attributes: func [ ABI [word! none!] - /local section sub-section attributes attrs + cpu-version [tuple! decimal!] + /local section sub-section attributes attrs ver ][ attrs: defs/arm/attributes + ver: case [ + cpu-version < 7.0 ['v5T] + all [7.0 <= cpu-version cpu-version < 8.0]['v7] + 8.0 <= cpu-version ['v8] + ] attributes: rejoin [ - attrs/cpu-arch defs/arm/cpu-arch/v5T + attrs/cpu-arch defs/arm/cpu-arch/:ver attrs/arm-isa-use #{01} ;; yes attrs/abi-pcs-wchar_t #{04} ;; 4 bytes attrs/abi-fp-denormal #{01} ;; needed diff --git a/system/targets/ARM.r b/system/targets/ARM.r index 0110ef85f8..da8936de6f 100644 --- a/system/targets/ARM.r +++ b/system/targets/ARM.r @@ -1093,6 +1093,79 @@ make-profilable make target-class [ emit-fpu-update: emit-fpu-init: none ;-- not used for now + emit-atomic-load: func [order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-LOAD" mold ptr mold order]] + emit-atomic-fence + emit-i32 #{e5900000} ;-- LDR r0, [r0] + emit-atomic-fence + ] + + emit-atomic-store: func [value order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-STORE" mold ptr mold value mold order]] + emit-i32 #{e1a02000} ;-- MOV r2, r0 + emit-atomic-fence + emit-load value + emit-i32 #{e5820000} ;-- STR r0, [r2] + emit-atomic-fence + ] + + emit-atomic-math: func [op [word!] right-op old? [logic!] ret? [logic!] order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-MATH-OP" mold ptr mold op mold value mold order]] + emit-i32 #{e1a03000} ;-- MOV r3, r0 + emit-load right-op + emit-atomic-fence + ;-- .loop: + emit-i32 #{e1931f9f} ;-- LDREX r1, [r3] + either old? [ + emit-i32 switch op [ + add [#{e0812000}] ;-- ADD r2, r1, r0 + sub [#{e0412000}] ;-- SUB r2, r1, r0 + or [#{e1812000}] ;-- ORR r2, r1, r0 + xor [#{e0212000}] ;-- EOR r2, r1, r0 + and [#{e0012000}] ;-- AND r2, r1, r0 + ] + emit-i32 #{e183cf92} ;-- STREX ip, r2, [r3] + ][ + emit-i32 switch op [ + add [#{e0811000}] ;-- ADD r1, r0 + sub [#{e0411000}] ;-- SUB r1, r0 + or [#{e1811000}] ;-- ORR r1, r0 + xor [#{e0211000}] ;-- EOR r1, r0 + and [#{e0011000}] ;-- AND r1, r0 + ] + emit-i32 #{e183cf91} ;-- STREX ip, r1, [r3] + ] + emit-i32 #{e35c0000} ;-- CMP ip, #0 + emit-i32 #{1afffffa} ;-- BNE .loop + emit-atomic-fence + emit-i32 #{e1a00001} ;-- MOV r0, r1 + ] + + emit-atomic-cas: func [check value ret? [logic!] order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-CAS" mold ptr mold check mold value ret? mold order]] + emit-i32 #{e1a03000} ;-- MOV r3, r0 + emit-load check + emit-i32 #{e1a02000} ;-- MOV r2, r0 ; r2: check + emit-load value + emit-i32 #{e3a0c001} ;-- MOV ip, #1 ; preset fail flag + emit-atomic-fence + ;-- .loop: + emit-i32 #{e1931f9f} ;-- LDREX r1, [r3] + emit-i32 #{e1510002} ;-- CMP r1, r2 + emit-i32 #{1a000002} ;-- BNE .exit + emit-i32 #{e183cf90} ;-- STREX ip, r0, [r3] + emit-i32 #{e35c0000} ;-- CMP ip, #0 + emit-i32 #{1afffff9} ;-- BNE .loop + ;-- .exit: + emit-atomic-fence + if ret? [emit-i32 #{e22c0001}] ;-- EOR r0, ip, #1 + ] + + emit-atomic-fence: does [ + if verbose >= 3 [print ">>>emitting ATOMIC-FENCE"] + emit-i32 #{f57ff05b} ;-- DMB ish (memory fence) + ] + emit-get-overflow: does [ switch/default last-math-op [ * [ diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index b03450bdd3..850c125404 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -97,16 +97,16 @@ make-profilable make target-class [ emit-variable: func [ name [word! object!] - gcode [binary! block! none!] ;-- global opcodes - pcode [binary! block! none!] ;-- PIC opcodes - lcode [binary! block!] ;-- local opcodes + gcode [binary! block! none!] ;-- global opcodes + pcode [binary! block! none!] ;-- PIC opcodes + lcode [binary! block!] ;-- local opcodes /local offset byte code spec ][ if object? name [name: compiler/unbox name] case [ offset: emitter/local-offset? name [ - offset: stack-encode offset ;-- local variable case + offset: stack-encode offset ;-- local variable case either block? lcode: adjust-disp32 lcode offset [ emit reduce bind lcode 'offset ][ @@ -114,7 +114,7 @@ make-profilable make target-class [ emit offset ] ] - PIC? [ ;-- global variable case (PIC version) + PIC? [ ;-- global variable case (PIC version) spec: emitter/symbols/:name either spec/1 = 'import-var [ emit #{8BB3} ;-- MOV esi, [ebx+] @@ -135,7 +135,7 @@ make-profilable make target-class [ ] ] ] - 'global [ ;-- global variable case + 'global [ ;-- global variable case spec: emitter/symbols/:name either spec/1 = 'import-var [ emit #{8B3D} ;-- MOV edi, [] @@ -213,11 +213,11 @@ make-profilable make target-class [ ] ] - emit-variable-poly: func [ ;-- polymorphic variable access generation + emit-variable-poly: func [ ;-- polymorphic variable access generation name [word! object!] - g8 [binary!] g32 [binary!] ;-- opcodes for global variables - p8 [binary!] p32 [binary!] ;-- opcodes for global variables (PIC) - l8 [binary! block!] l32 [binary! block!] ;-- opcodes for local variables + g8 [binary!] g32 [binary!] ;-- opcodes for global variables + p8 [binary!] p32 [binary!] ;-- opcodes for global variables (PIC) + l8 [binary! block!] l32 [binary! block!];-- opcodes for local variables ][ with-width-of name [ switch width [ @@ -544,6 +544,83 @@ make-profilable make target-class [ emit #{9BDBE3} ;-- FINIT ; init x87 FPU ] + emit-atomic-load: func [order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-LOAD" mold ptr mold order]] + emit #{8B00} ;-- MOV eax, [eax] + ] + + emit-atomic-store: func [value order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-STORE" mold ptr mold value mold order]] + emit #{89C6} ;-- MOV esi, eax + emit-load value + emit #{8906} ;-- MOV [esi], eax + emit-atomic-fence + ] + + emit-atomic-math: func [op [word!] right-op old? [logic!] ret? [logic!] order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-MATH-OP" mold ptr mold op mold value mold ret? mold order]] + emit #{89C6} ;-- MOV esi, eax + emit-load right-op + either any [old? ret?][ + either find [add sub] op [ + emit #{89C2} ;-- MOV edx, eax + if op = 'sub [emit #{F7D8}] ;-- NEG eax + emit #{F00FC106} ;-- LOCK XADD [esi], eax + if all [ret? not old?][ + emit either op = 'add [ + #{01D0} ;-- ADD eax, edx + ][ + #{29D0} ;-- SUB eax, edx + ] + ] + ][ + emit #{89C7} ;-- MOV edi, eax ; edi: right-op + emit #{8B06} ;-- MOV eax, [esi] + ;-- .loop: + emit #{89C1} ;-- MOV ecx, eax + unless old? [emit #{89C2}] ;-- [MOV edx, eax] ; only for old? + switch op [ + or [emit #{09F9}] ;-- OR ecx, edi + xor [emit #{31F9}] ;-- XOR ecx, edi + and [emit #{21F9}] ;-- AND ecx, edi + ] + emit #{F00FB10E} ;-- LOCK CMPXCHG [esi], ecx + emit either old? [#{75F4}][#{75F6}] ;-- JNE .loop + emit either all [ret? not old?][ + #{89C8} ;-- MOV eax, ecx ; eax: newly written value + ][ + #{89D0} ;-- MOV eax, edx ; eax: last old value + ] + ] + ][ + emit switch op [ + add [#{F00106}] ;-- LOCK ADD [esi], eax + sub [#{F02906}] ;-- LOCK SUB [esi], eax + or [#{F00906}] ;-- LOCK OR [esi], eax + xor [#{F03106}] ;-- LOCK XOR [esi], eax + and [#{F02106}] ;-- LOCK AND [esi], eax + ] + ] + ] + + emit-atomic-cas: func [check value ret? [logic!] order [word!]][ + if verbose >= 3 [print [">>>emitting ATOMIC-CAS" mold ptr mold check mold value ret? mold order]] + emit #{89C6} ;-- MOV esi, eax + emit-load value + emit-move-path-alt ;-- load new value in edx + emit-load check ;-- load check value in eax + emit #{F00FB116} ;-- LOCK CMPXCHG [esi], edx + if ret? [ + emit #{0F94C0} ;-- SETE al + emit #{25FF000000} ;-- AND eax, 0xFF + ] + ] + + emit-atomic-fence: does [ + if verbose >= 3 [print ">>>emitting ATOMIC-FENCE"] + emit #{0FAEF0} ;-- MFENCE + ] + emit-get-overflow: does [ emit #{0F90C0} ;-- SETO al emit #{83E001} ;-- AND eax, 1 diff --git a/system/targets/target-class.r b/system/targets/target-class.r index 5f4801f0b1..1cdbdbb0d2 100644 --- a/system/targets/target-class.r +++ b/system/targets/target-class.r @@ -32,7 +32,8 @@ target-class: context [ emit-integer-operation: emit-float-operation: emit-throw: on-init: emit-alt-last: emit-log-b: emit-variable: emit-read-io: emit-io-write: - emit-push-all: emit-pop-all: none + emit-push-all: emit-pop-all: emit-atomic-load: emit-atomic-store: + emit-atomic-math: emit-atomic-fence: none comparison-op: [= <> < > <= >=] math-op: compose [+ - * / // (to-word "%")] diff --git a/system/tests/all-tests.txt b/system/tests/all-tests.txt index 00a7f7bde1..ca760672ac 100644 --- a/system/tests/all-tests.txt +++ b/system/tests/all-tests.txt @@ -27,4 +27,6 @@ %source/units/math-mixed-test.reds %source/units/infix-test.reds %source/units/conditional-test.reds +%source/units/atomic-test.reds +%source/units/queue-test.reds %source/units/auto-tests/dylib-auto-test.reds \ No newline at end of file diff --git a/system/tests/run-all.r b/system/tests/run-all.r index 5701042cd0..2cea16012a 100644 --- a/system/tests/run-all.r +++ b/system/tests/run-all.r @@ -108,6 +108,8 @@ print ["This test started at" start-time] ===start-group=== "System tests" --run-test-file-quiet %source/units/system-test.reds + --run-test-file-quiet %source/units/atomic-test.reds + --run-test-file-quiet %source/units/queue-test.reds ===end-group=== ===start-group=== "Auto-tests" diff --git a/system/tests/source/units/atomic-test.reds b/system/tests/source/units/atomic-test.reds new file mode 100644 index 0000000000..875ea298f6 --- /dev/null +++ b/system/tests/source/units/atomic-test.reds @@ -0,0 +1,236 @@ +Red/System [ + Title: "Red/System atomic operations test script" + Author: "Xie Qingtian" + File: %atomic-test.reds + Tabs: 4 + Rights: "Copyright (C) 2011-2019 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../../quick-test/quick-test.reds + +#either cpu-version > 5.0 [ + +#define handle! int-ptr! + +#include %../../../../runtime/threads.reds + +#define A_N_THREADS 100 +#define A_N_ITERS 100000 + +#define COND_CC [#if OS <> 'Windows [[cdecl]]] + +~~~start-file~~~ "atomic operations" + +===start-group=== "atomic operations path" + st!: alias struct! [ + a [integer!] + b [integer!] + ] + st: declare st! + st/a: 0 + st/b: 1 + + --test-- "atomic load path" + test-load: func [s [st!]][ + --assert (system/atomic/load :s/b) = 1 + ] + test-load st + + --test-- "atomic store path" + test-store: func [s [st!]][ + system/atomic/store :s/a 1 + --assert s/a = s/b + ] + test-store st + +===end-group=== + +===start-group=== "atomic operations with multi threads" + run-parallel: func [ + op-func [int-ptr!] + /local + threads [int-ptr!] + n [integer!] + ][ + threads: system/stack/allocate A_N_THREADS + n: 1 + until [ ;-- start some threads + threads/n: as-integer thread/start op-func null 0 + n: n + 1 + n > A_N_THREADS + ] + loop A_N_THREADS [ + thread/wait as int-ptr! threads/value -1 null + threads: threads + 1 + ] + ] + + run-parallel-n: func [ + op-func [int-ptr!] + n-threads [integer!] ;-- number of threads + return: [logic!] + /local + threads [int-ptr!] + n [integer!] + ret [integer!] + ][ + threads: system/stack/allocate n-threads + n: 1 + until [ ;-- start some threads + threads/n: as-integer thread/start op-func as int-ptr! n 0 + n: n + 1 + n > n-threads + ] + loop n-threads [ + ret: 0 + thread/wait as int-ptr! threads/value -1 :ret + unless as logic! ret [return false] + threads: threads + 1 + ] + true + ] + + --test-- "atomic load and store" + counter1: 0 + counter2: 0 + + atomic-load-store: func [ ;-- thread-func! + COND_CC + udata [int-ptr!] + return: [logic!] + /local + p1 [int-ptr!] + p2 [int-ptr!] + me [integer!] + n [integer!] + c1 [integer!] + c2 [integer!] + ][ + p1: :counter1 + p2: :counter2 + me: as-integer udata + loop A_N_ITERS [ + either me = 1 [ + c1: system/atomic/load p1 + n: c1 + 1 + ;-- the following 2 store instructions should be sequential + ;-- no reordering + system/atomic/store p1 n + system/atomic/store p2 n + ][ + c2: system/atomic/load p2 + c1: system/atomic/load p1 + if c1 < c2 [return false] + ] + ] + true + ] + --assert run-parallel-n as int-ptr! :atomic-load-store 10 + + --test-- "atomic add" + g-a: 0 ;-- global variable + + atomic-add-func: func [COND_CC udata [int-ptr!]][ ;-- thread-func! + loop A_N_ITERS [ + ;g-a: g-a + 1 ;-- this will fail + system/atomic/add :g-a 1 + ] + ] + run-parallel as int-ptr! :atomic-add-func + --assert A_N_THREADS * A_N_ITERS = g-a + + --test-- "atomic sub" + g-a: A_N_THREADS * A_N_ITERS + + atomic-sub-func: func [COND_CC udata [int-ptr!]][ ;-- thread-func! + loop A_N_ITERS [ + system/atomic/sub :g-a 1 + ] + ] + run-parallel as int-ptr! :atomic-sub-func + --assert 0 = g-a + + --test-- "atomic CAS" + g-a: 0 ;-- global variable + + ;fail-increment: func [val [int-ptr!] /local old [integer!] new [integer!]][ + ; until [ ;-- non-atomic compare and swap + ; old: val/value + ; new: old + 1 + ; either old = val/value [ + ; val/value: new + ; true + ; ][ + ; false + ; ] + ; ] + ;] + cas-increment: func [val [int-ptr!] /local old [integer!] new [integer!]][ + until [ + old: system/atomic/load val + new: old + 1 + system/atomic/cas val old new + ] + ] + atomic-cas-increment: func [COND_CC udata [int-ptr!]][ ;-- thread-func! + ;loop A_N_ITERS [fail-increment :g-a] ;-- this wil fail + loop A_N_ITERS [cas-increment :g-a] + ] + run-parallel as int-ptr! :atomic-cas-increment + --assert A_N_THREADS * A_N_ITERS = g-a + + run-parallel-2: func [ + op-func [int-ptr!] + init-value [integer!] + return: [integer!] + /local + threads [int-ptr!] + n [integer!] + a [integer!] + ][ + a: init-value + threads: system/stack/allocate A_N_THREADS + n: 1 + until [ ;-- start some threads + threads/n: as-integer thread/start op-func :a 0 + n: n + 1 + n > A_N_THREADS + ] + loop A_N_THREADS [ + thread/wait as int-ptr! threads/value -1 null + threads: threads + 1 + ] + a + ] + + --test-- "atomic add 2" + atomic-add-func2: func [COND_CC udata [int-ptr!]][ ;-- thread-func! + loop A_N_ITERS [ + system/atomic/add udata 1 + ] + ] + --assert A_N_THREADS * A_N_ITERS = run-parallel-2 as int-ptr! :atomic-add-func2 0 + + --test-- "atomic sub 2" + atomic-sub-func2: func [COND_CC udata [int-ptr!]][ ;-- thread-func! + loop A_N_ITERS [ + system/atomic/sub udata 1 + ] + ] + --assert 0 = run-parallel-2 as int-ptr! :atomic-sub-func2 A_N_THREADS * A_N_ITERS + +===end-group=== + +~~~end-file~~~ + +][ + +~~~start-file~~~ "Queue Test" + +===start-group=== "Queue Basic" +===end-group=== + +~~~end-file~~~ + +] \ No newline at end of file diff --git a/system/tests/source/units/cast-test.reds b/system/tests/source/units/cast-test.reds index ffa7e81008..491279a8b2 100644 --- a/system/tests/source/units/cast-test.reds +++ b/system/tests/source/units/cast-test.reds @@ -687,4 +687,37 @@ Red/System [ ===end-group=== +===start-group=== "Issues" + + --test-- "#3961" + cell-3961!: alias struct! [ + header [integer!] + data1 [integer!] + data2 [integer!] + data3 [integer!] + ] + red-object-3961!: alias struct! [ + header [integer!] + ctx [int-ptr!] + class [integer!] + on-set [int-ptr!] + ] + obj123: context [ + test1: func [ + view [integer!] + return: [red-object-3961!] + /local + t [integer!] + z [red-object-3961!] + ][ + t: 54h + z: as red-object-3961! (as cell-3961! view + t) + z + ] + ] + --assert (as red-object-3961! 01820DB4h) = obj123/test1 01820D60h + + +===end-group=== + ~~~end-file~~~ diff --git a/system/tests/source/units/queue-test.reds b/system/tests/source/units/queue-test.reds new file mode 100644 index 0000000000..a5849f94b0 --- /dev/null +++ b/system/tests/source/units/queue-test.reds @@ -0,0 +1,141 @@ +Red/System [ + Title: "Red/System atomic operations test script" + Author: "Xie Qingtian" + File: %atomic-test.reds + Tabs: 4 + Rights: "Copyright (C) 2011-2019 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../../quick-test/quick-test.reds + +#either cpu-version > 5.0 [ + +#define handle! int-ptr! + +#include %../../../../runtime/threads.reds +#include %../../../../runtime/queue.reds + +#define A_N_THREADS 100 +#define A_N_ITERS 100000 + +#define COND_CC [#if OS <> 'Windows [[cdecl]]] + +~~~start-file~~~ "Queue Test" + +===start-group=== "Queue Basic" + + --test-- "queue test 1" + producer-func: func [ + COND_CC + qe [queue!] + return: [integer!] + ][ + loop A_N_ITERS [ + until [queue/push qe as int-ptr! 1] + ] + 0 + ] + consumer-func: func [ + COND_CC + qe [queue!] + return: [integer!] + /local + n [integer!] + ret [integer!] + ][ + n: 0 + loop A_N_ITERS [ + until [ + ret: as-integer queue/pop qe + ret <> 0 + ] + n: n + ret + ] + n + ] + + run-queue-test: func [ + /local + threads [int-ptr!] + n [integer!] + ret [integer!] + qe [queue!] + ][ + qe: queue/create 1024 * 8 + threads: system/stack/allocate 64 + n: 1 + until [ ;-- start producer and consumer threads + threads/n: as-integer thread/start as int-ptr! :producer-func as int-ptr! qe 0 + n: n + 1 + threads/n: as-integer thread/start as int-ptr! :consumer-func as int-ptr! qe 0 + n: n + 1 + n = 65 + ] + n: 1 + until [ + ret: 0 + thread/wait as int-ptr! threads/n -1 :ret + if n % 2 = 0 [--assert ret = A_N_ITERS] + n: n + 1 + n = 65 + ] + ] + + run-queue-test + + --test-- "queue test 2 - single producer" + s-producer-func: func [ + COND_CC + qe [queue!] + return: [integer!] + ][ + loop A_N_ITERS * 31 [ + until [queue/s-push qe as int-ptr! 1] + ] + 0 + ] + + run-queue-test-2: func [ + /local + threads [int-ptr!] + n [integer!] + ret [integer!] + qe [queue!] + ][ + qe: queue/create 1024 * 8 + threads: system/stack/allocate 32 + n: 1 + until [ ;-- start consumer threads + threads/n: as-integer thread/start as int-ptr! :consumer-func as int-ptr! qe 0 + n: n + 1 + n = 32 + ] + ;-- start producer threads + threads/n: as-integer thread/start as int-ptr! :s-producer-func as int-ptr! qe 0 + + until [ + ret: 0 + thread/wait as int-ptr! threads/n -1 :ret + if n <> 32 [--assert ret = A_N_ITERS] + n: n - 1 + zero? n + ] + ] + + run-queue-test-2 + +===end-group=== + +~~~end-file~~~ + +][ + +~~~start-file~~~ "Queue Test" + +===start-group=== "Queue Basic" +===end-group=== + +~~~end-file~~~ + +] \ No newline at end of file diff --git a/tests/source/runtime/preprocessor-test.red b/tests/source/runtime/preprocessor-test.red new file mode 100644 index 0000000000..6bda974bf4 --- /dev/null +++ b/tests/source/runtime/preprocessor-test.red @@ -0,0 +1,82 @@ +Red [ + Title: "Red runtime preprocessor tests" + Author: "Nenad Rakocevic" + File: %preprocessor-test.red + Rights: "Copyright (C) 2016-2018 Red Foundation All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../quick-test/quick-test.red + +~~~start-file~~~ "preprocessor" + +===start-group=== "Basic Directives" + --test-- "#if" + #do [cond?: yes anti?: no level: 2] + --assert #if config/type = 'exe [true] + --assert #if cond? [true] + --assert #if not anti? [true] + --assert #if find [a b c] 'b [true] + + --test-- "#either" + --assert #either cond? [true][false] + --assert #either anti? [false][true] + + --test-- "#switch" + --assert #switch 1 [1 [true] 2 [false] #default [false]] + --assert #switch 'b [a [false] b [true] #default [false]] + --assert #switch 'c [a [false] b [false] #default [true]] + --assert #switch level [1 [false] 2 [true] #default [false]] + + --test-- "#case" + --assert #case [level = 1 [false] level >= 2 [true] 'else [false]] + + --test-- "#process" + #process off + --assert ["*test12*" #if #either #switch #case #do] + = load {["*test12*" #if #either #switch #case #do]} + #process on + +===end-group=== + +===start-group=== "Macros" + + --test-- "macro-1" + #do [a: 12] + + #macro add2: func [n][n + 2] + #macro foo: func [a b][add2 a + b] + #macro bar: func [a b][a - b] + #macro ['max some [integer!]] func [s e][ + change/part s first maximum-of copy/part next s e e + s + ] + + --test-- "macro-2" + --assert 60 = #do keep [5 * a] + + --test-- "macro-3" + --assert 12 = foo 1 foo 3 4 + + #local [ + #macro integer! func [s e][s/1: s/1 + 1 next s] + --test-- "macro-4" + --assert (load "17") = foo 1 foo 3 4 + --test-- "macro-5" + --assert 6 + 2 = (load "10") + ] + --test-- "macro-6" + --assert 12 = foo 1 foo 3 4 + --test-- "macro-7" + --assert 54546 = max 50 20 54546 40 85 30 + --test-- "macro-8" + #reset + --assert [foo 5 9] = load {foo 5 9} + + --test-- "#3771" + res: expand-directives [#macro mm: func [x][x] mm [1 2] mm [3 4] [mm [5 6] mm [7 8]] mm [9 10]] + --assert res = [1 2 3 4 [5 6 7 8] 9 10] + +===end-group=== + +~~~end-file~~~ \ No newline at end of file diff --git a/tests/source/units/convert-test.red b/tests/source/units/convert-test.red index afd5eae5eb..7c9912227c 100644 --- a/tests/source/units/convert-test.red +++ b/tests/source/units/convert-test.red @@ -454,6 +454,8 @@ Red [ --assert #{666F6F40626F6F} = to binary! foo@boo --test-- "to-binary!-bitset!" --assert #{00} = to binary! make bitset! #{00} + --test-- "issue #3636" + --assert 97 = pick to binary! append/dup a: "" "a" 1100000 1 ===end-group=== ===start-group=== "to-block!" --test-- "to-block!-char!" diff --git a/tests/source/units/float-test.red b/tests/source/units/float-test.red index f6c508a455..09371e5fff 100644 --- a/tests/source/units/float-test.red +++ b/tests/source/units/float-test.red @@ -379,6 +379,22 @@ Red [ ;-- for issue #2593 (ROUND rounds float down if scale is integer) --test-- "round18" --assert 1 = round/to 0.5 1 --test-- "round19" --assert 0 = round/to 0.499 1 + + ;-- for issue 3759 + --test-- "round20" + --assert -3.0 = round/to/floor -2.4 1.0 + --assert -3 = round/to/floor -2.4 1 + --assert -2.0 = round/to/ceiling -2.4 1.0 + --assert -2 = round/to/ceiling -2.4 1 + --assert -4.0 = round/to/floor -2.4 2.0 + --assert -4 = round/to/floor -2.4 2 + --assert -2.0 = round/to/ceiling -2.4 2.0 + --assert -2 = round/to/ceiling -2.4 2 + + --test-- "round21" + --assert 0:00:16 = round/to 15.0 0:0:2 + --assert 12.9 = round/to 13.0 30% + ===end-group=== ===start-group=== "various regression tests from bugtracker" @@ -2782,18 +2798,20 @@ Red [ --test-- "float-divide 37" i: 2.2250738585072014e-308 j: 1.1 - ;--assert strict-equal? 2.022794416824728e-308 2.2250738585072014e-308 / 1.1 - ;--assert strict-equal? 2.022794416824728e-308 divide 2.2250738585072014e-308 1.1 - ;--assert strict-equal? 2.022794416824728e-308 i / j - ;--assert strict-equal? 2.022794416824728e-308 divide i j + base: to-float #either config/target = 'ARM [#{000E8BA2E8BA2E8B}][#{000E8BA2E8BA2E8C}] ;;FIXME: workaround #3993 + --assert strict-equal? base 2.2250738585072014e-308 / 1.1 + --assert strict-equal? base divide 2.2250738585072014e-308 1.1 + --assert strict-equal? base i / j + --assert strict-equal? base divide i j --test-- "float-divide 38" i: 2.2250738585072014e-308 j: -1.1 - ;--assert strict-equal? -2.022794416824728e-308 2.2250738585072014e-308 / -1.1 - ;--assert strict-equal? -2.022794416824728e-308 divide 2.2250738585072014e-308 -1.1 - ;--assert strict-equal? -2.022794416824728e-308 i / j - ;--assert strict-equal? -2.022794416824728e-308 divide i j + base: to-float #either config/target = 'ARM [#{800E8BA2E8BA2E8B}][#{800E8BA2E8BA2E8C}] ;;FIXME: workaround #3993 + --assert strict-equal? base 2.2250738585072014e-308 / -1.1 + --assert strict-equal? base divide 2.2250738585072014e-308 -1.1 + --assert strict-equal? base i / j + --assert strict-equal? base divide i j --test-- "float-divide 39" i: 2.2250738585072014e-308 diff --git a/tests/source/units/integer-test.red b/tests/source/units/integer-test.red index 2bc4be2f0c..c85a37e7b4 100644 --- a/tests/source/units/integer-test.red +++ b/tests/source/units/integer-test.red @@ -112,6 +112,12 @@ Red [ --test-- "round13" --assert 24 = round/half-ceiling/to 23 3 --test-- "round14" --assert -24 = round/half-ceiling/to -23 3 + + --test-- "round15" + --assert 24.0 = round/to 23 3.0 + --assert 23.1 = round/to 23 30% + --assert 0:00:16 = round/to 15 0:0:2 + ===end-group=== ===start-group=== "with other datatypes" diff --git a/tests/source/units/object-test.red b/tests/source/units/object-test.red index c39cf57e8c..06a98ef690 100644 --- a/tests/source/units/object-test.red +++ b/tests/source/units/object-test.red @@ -2300,6 +2300,26 @@ Red [ ;; COMMENTED OUT ;;--assert not error? try [ iss-3516-t: iss-3516-c/f [] ] + + --test-- "issue #3406" + do [ ;-- cannot run this test using libRedRT + b3406: context [x: 2 f: does [x]] + c3406: context [f: does [x] x: 3] + d3406: construct/with [x: 4] b3406 + e3406: construct/with [x: 5] c3406 + + --assert b3406/f = 2 + --assert c3406/f = 3 + --assert d3406/f = 4 + --assert e3406/f = 5 + + ;-- alternative to 3406 merging objects using MAKE + + g3406: context [f: does [x] x: 3] + h3406: make g3406 object [x: 5] + --assert h3406/f = 5 + ] + ===end-group=== ~~~end-file~~~ diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 317ba705d1..ac2daa52cb 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2719,6 +2719,16 @@ Red [ parse x3357b: [][insert ('foo)] --assert x3357b = [foo] + --test-- "#3951" + res: none + do "res: expand-directives/clean [[] #macro word! func [s e]['OK] WTF]()" + --assert res = [[] OK] + + --test-- "#3427" + --assert parse/part %234 ["23" thru [end]] 3 + --assert parse/part %234 ["23" to [end]] 3 + --assert parse/part %234 ["23" to end] 3 + repeat i 4 [--assert parse/part "12" ["1" to [end]] i] ===end-group=== diff --git a/tests/source/units/reactivity-test.red b/tests/source/units/reactivity-test.red index 6da3a24190..a501fb8757 100644 --- a/tests/source/units/reactivity-test.red +++ b/tests/source/units/reactivity-test.red @@ -14,55 +14,88 @@ Red [ ===start-group=== "IS function" --test-- "is-1" - a: make reactor! [x: 1 y: is [x + 1]] - --assert a/x == 1 - --assert a/y == 2 - a/x: 5 - --assert a/y == 6 + is-1a: make reactor! [x: 1 y: is [x + 1]] + --assert is-1a/x == 1 + --assert is-1a/y == 2 + is-1a/x: 5 + --assert is-1a/y == 6 + unset 'is-1a --test-- "is-2" - --assert [x + 1] = react? a 'x - --assert none? react?/target a 'x - --assert [x + 1] = react?/target a 'y - --assert none? react? a 'y + is-2a: make reactor! [x: 1 y: is [x + 1]] + --assert [x + 1] = react? is-2a 'x + --assert none? react?/target is-2a 'x + --assert [x + 1] = react?/target is-2a 'y + --assert none? react? is-2a 'y + unset 'is-2a --test-- "is-3" - b: make reactor! [x: 2 y: 3 z: is [x + y]] - --assert b/x == 2 - --assert b/y == 3 - --assert b/z == 5 - b/x: 5 - --assert b/z == 8 + is-3b: make reactor! [x: 2 y: 3 z: is [x + y]] + --assert is-3b/x == 2 + --assert is-3b/y == 3 + --assert is-3b/z == 5 + is-3b/x: 5 + --assert is-3b/z == 8 + unset 'is-3b --test-- "is-4" - --assert [x + y] = react? b 'x - --assert [x + y] = react? b 'y - --assert [x + y] = react?/target b 'z + is-4b: make reactor! [x: 2 y: 3 z: is [x + y]] + --assert [x + y] = react? is-4b 'x + --assert [x + y] = react? is-4b 'y + --assert [x + y] = react?/target is-4b 'z + unset 'is-4b --test-- "is-5" - c: make reactor! [x: 1 y: is [x + 1] z: is [y + 1]] - --assert c/x == 1 - --assert c/y == 2 - --assert c/z == 3 - c/x: 4 - --assert c/y == 5 - --assert c/z == 6 + is-5c: make reactor! [x: 1 y: is [x + 1] z: is [y + 1]] + --assert is-5c/x == 1 + --assert is-5c/y == 2 + --assert is-5c/z == 3 + is-5c/x: 4 + --assert is-5c/y == 5 + --assert is-5c/z == 6 + unset 'is-5c --test-- "is-6" - --assert [x + 1] = react? c 'x - --assert none? react?/target c 'x - --assert [x + 1] = react?/target c 'y - --assert [y + 1] = react? c 'y - --assert none? react? c 'z - --assert [y + 1] = react?/target c 'z - - --test-- "is-7" - ;d: make reactor! [x: is [y + 1] y: is [x + 3]] - ;--assert none? d/x - ;--assert none? d/y - ;d/x: 1 - ;--assert d/x = 5 - ;--assert d/y = 4 + is-6c: make reactor! [x: 1 y: is [x + 1] z: is [y + 1]] + --assert [x + 1] = react? is-6c 'x + --assert none? react?/target is-6c 'x + --assert [x + 1] = react?/target is-6c 'y + --assert [y + 1] = react? is-6c 'y + --assert none? react? is-6c 'z + --assert [y + 1] = react?/target is-6c 'z + unset 'is-6c + + --test-- "is-7" + is-7d: make reactor! [x: is [attempt [y + 1]] y: is [attempt [x + 3]]] + --assert none? is-7d/x + --assert none? is-7d/y + is-7d/x: 1 + --assert is-7d/x = 1 ;-- x is fixed by the assignment + --assert is-7d/y = 4 + unset 'is-7d + + --test-- "is-8" + is-8r: make reactor! [x: is [attempt [y + 1]] y: is [attempt [z + 2]] z: is [attempt [x + 3]]] + --assert none? is-8r/x + --assert none? is-8r/y + --assert none? is-8r/z + is-8r/x: 1 + --assert is-8r/x = 1 ;-- x is fixed by the assignment + --assert is-8r/z = 4 + --assert is-8r/y = 6 + is-8r/y: 1 + --assert is-8r/y = 1 ;-- y is fixed by the assignment + --assert is-8r/x = 2 + --assert is-8r/z = 5 + is-8r/z: 1 + --assert is-8r/z = 1 ;-- z is fixed by the assignment + --assert is-8r/y = 3 + --assert is-8r/x = 4 + unset 'is-8r + + + ;-- final group cleanup + clear-reactions ===end-group=== @@ -116,6 +149,26 @@ Red [ ] unset [rf-5-r] + --test-- "rf-6" ; #3333 where `is` produced an excessive reaction with the wrong target object + clear-reactions + rf-6r: make reactor! [x: 1] + rf-6c: context [ x: is [rf-6r/x] ] + --assert 1 * 4 = length? system/reactivity/relations ;-- should only be a single reaction + --assert rf-6r = :system/reactivity/relations/1 ;-- `r` should be the source object + unset [rf-6c rf-6r] + + --test-- "rf-7" ; #3333 triple-reaction case + clear-reactions + rf-7r: make reactor! [x: 1] + rf-7x: is [rf-7r/x] + --assert 1 * 4 = length? system/reactivity/relations ;-- should only be a single reaction + --assert rf-7r = :system/reactivity/relations/1 ;-- `r` should be the source object + unset [rf-7r rf-7x] + + + ;-- final group cleanup + clear-reactions + ===end-group=== ~~~end-file~~~ \ No newline at end of file diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index d073cbbc1f..59b6a11edb 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1423,8 +1423,8 @@ Red [ --test-- "sort-blk-3" a: ["Larry" 45 "Curly" 50 "Mo" 42] --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 2 - --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a > b] - --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 > b/2] + --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a < b] + --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 < b/2] --test-- "sort-blk-4" o1: context [a: 2 i: "a"] @@ -1437,7 +1437,7 @@ Red [ o8: context [a: 3 i: "h"] a: reduce [o1 o2 o3 o8 o4 o5 o6 o7] res: reduce [o2 o3 o4 o5 o6 o1 o8 o7] - --assert res = sort/compare/stable a func [a b][a/a - b/a] + --assert res = sort/compare/stable a func [a b][b/a - a/a] ===end-group=== ===start-group=== "path access" diff --git a/tests/source/units/time-test.red b/tests/source/units/time-test.red index 80d1b2ad3a..7bf723b57b 100644 --- a/tests/source/units/time-test.red +++ b/tests/source/units/time-test.red @@ -365,8 +365,20 @@ Red [ ===end-group=== ===start-group=== "round" + --test-- "round 1" + --assert 0:00:01 = round/to 0:0:1.4 1 - round/to 0:0:1.4 1 + --test-- "round 2" + --assert 0:00:01 = round/to 0:0:1.4 0:0:1 + + --test-- "round 3" + --assert 12:35:23 = round/to 12:34:56 0:1:1 + --assert 12:35:23 = round/to 12:34:56 to integer! 0:1:1 + --assert 12:35:23 = round/to 12:34:56 to float! 0:1:1 + + --test-- "round 4" + --assert 12:34:56.1 = round/to 12:34:56 0.3 + --assert 12:34:56.1 = round/to 12:34:56 30% ===end-group=== diff --git a/utils/preprocessor.r b/utils/preprocessor.r index 1337bc8134..731c7d8683 100644 --- a/utils/preprocessor.r +++ b/utils/preprocessor.r @@ -269,14 +269,14 @@ preprocessor: context [ ] expand: func [ - code [block!] job [object! none!] + code [block! paren!] job [object! none!] /clean /local rule e pos cond value then else cases body keep? expr src saved file ][ either clean [reset job][exec/config: job] #process off - parse code rule: [ + rule: [ any [ s: macros | 'routine 2 skip ;-- avoid overlapping with R/S preprocessor @@ -370,6 +370,9 @@ preprocessor: context [ ] ] #process on + + unless Rebol [rule/1: 'while] ;-- avoid no-forward premature exit in Red (#3771) + parse code rule code ] From 01f04fbc6df80dec9e282c492c7b23fc132a7cd9 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 28 Aug 2019 20:07:41 +0800 Subject: [PATCH 0142/3432] FIX: gtk's wheel delta direction is converse --- modules/view/backends/gtk3/events.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index ed19062ccc..bed283337b 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -276,7 +276,7 @@ get-event-picked: func [ ] EVT_WHEEL [ event: as GdkEventScroll! g_object_get_qdata as handle! evt/msg red-event-id - float/push event/delta_y + float/push 0.0 - event/delta_y ] EVT_MENU [word/push* evt/flags and FFFFh] default [integer/push evt/flags and FFFFh] From 89d297784470054993fdd298ccaa09a13c805c16 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 11:00:03 +0800 Subject: [PATCH 0143/3432] FEAT: expose all active events to upper users --- modules/view/backends/gtk3/events.reds | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index bed283337b..e5e28d4d6c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -903,6 +903,9 @@ connect-widget-events: function [ respond-key-add widget actors sym respond-window-add widget actors sym + ;-- expose all active events to upper users + connect-common-events widget face sym parent + case [ sym = check [ ;@@ No click event for check @@ -926,7 +929,6 @@ connect-widget-events: function [ gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes - connect-common-events widget face sym parent ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw face/ctx) @@ -935,7 +937,6 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - connect-common-events widget face sym parent ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] @@ -944,7 +945,6 @@ connect-widget-events: function [ gobj_signal_connect(widget "configure-event" :window-configure-event null) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate null) - connect-common-events widget face sym parent ] sym = slider [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] @@ -1028,7 +1028,6 @@ connect-widget-events: function [ ; if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx)] ; if respond-key? widget (ON_KEY or ON_KEY_DOWN) [gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx)] ; if respond-key? widget ON_KEY_UP [gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx)] - connect-common-events widget face sym parent ] sym = tab-panel [ if respond-window? widget (ON_SELECT or ON_CHANGE) [ @@ -1040,7 +1039,6 @@ connect-widget-events: function [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text-list selected-rows-changed " lf]] gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) - connect-common-events widget face sym parent ] any [ sym = drop-list From c9133bd0b2b36839d396e3ddfc388e55e7618b02 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 11:04:34 +0800 Subject: [PATCH 0144/3432] FIX: trim trailing whitespace --- modules/view/backends/gtk3/comdlgs.reds | 8 +- modules/view/backends/gtk3/draw.reds | 64 ++++----- modules/view/backends/gtk3/events.reds | 68 +++++----- modules/view/backends/gtk3/font.reds | 52 ++++---- modules/view/backends/gtk3/gtk.reds | 66 +++++----- modules/view/backends/gtk3/gui.reds | 160 +++++++++++------------ modules/view/backends/gtk3/handlers.reds | 114 ++++++++-------- modules/view/backends/gtk3/menu.reds | 8 +- modules/view/backends/gtk3/para.reds | 26 ++-- modules/view/backends/gtk3/text-box.reds | 42 +++--- 10 files changed, 304 insertions(+), 304 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 2dc0d3cc2c..619ac58696 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -41,7 +41,7 @@ _request-file: func [ unless null? main-window [gtk_window_set_transient_for widget main-window] resp: gtk_dialog_run widget if resp = GTK_RESPONSE_ACCEPT [ - cstr: gtk_file_chooser_get_filename widget + cstr: gtk_file_chooser_get_filename widget size: length? cstr str: string/load cstr size UTF-8 if dir? [string/append-char GET_BUFFER(str) as-integer #"/"] @@ -81,7 +81,7 @@ OS-request-font: func [ return: [red-object!] /local widget [handle!] - fd [handle!] + fd [handle!] values [red-value!] style [red-block!] size [integer!] @@ -102,7 +102,7 @@ OS-request-font: func [ resp: gtk_dialog_run widget ;; print ["resp: " resp lf] either resp = -5 [ - fd: gtk_font_chooser_get_font_desc widget + fd: gtk_font_chooser_get_font_desc widget cstr: pango_font_description_get_family fd size: length? cstr values: object/get-values font @@ -132,7 +132,7 @@ OS-request-font: func [ font/header: TYPE_NONE ] gtk_widget_destroy widget - ; This trick really matters to end the loop when in the red-console + ; This trick really matters to end the loop when in the red-console while [gtk_events_pending][gtk_main_iteration] font diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 7d386b92dd..d644c5b616 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -51,11 +51,11 @@ init-draw-ctx: func [ ctx/pen?: yes ctx/brush?: no ctx/pattern: null - + ctx/font-desc: null ;default-font ctx/layout: null ; make-pango-cairo-layout cr ctx/font-desc ctx/font-opts: null - ctx/font-underline?: no + ctx/font-underline?: no ctx/font-strike?: no ] @@ -99,7 +99,7 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ ] cairo_fill_preserve cr unless dc/pen? [ - set-source-color cr dc/pen-color + set-source-color cr dc/pen-color cairo_stroke cr ] cairo_restore cr @@ -108,7 +108,7 @@ do-paint: func [dc [draw-ctx!] /local cr [handle!]][ ;; DEBUG: print ["do-paint dc/pen? color " dc/pen-color lf] cairo_stroke cr ] - + ] OS-draw-anti-alias: func [ @@ -141,7 +141,7 @@ OS-draw-pen: func [ ][ dc/pen?: not off? ;; DEBUG: print ["OS-draw-pen: " not off? " with color " color lf ] - ;; THIS if DOES NOT WORK: + ;; THIS if DOES NOT WORK: ;; if dc/pen-color <> color [ dc/pen-color: color dc/font-color: color @@ -272,7 +272,7 @@ do-spline-step: func [ t: t + spline-delta t2: t * t t3: t2 * t - + x: 2.0 * (as-float p1/x) + ((as-float p2/x) - (as-float p0/x) * t) + ((2.0 * (as-float p0/x) - (5.0 * (as-float p1/x)) + (4.0 * (as-float p2/x)) - (as-float p3/x)) * t2) + @@ -310,13 +310,13 @@ OS-draw-spline: func [ start + 1 start + 2 ][ - do-spline-step ctx + do-spline-step ctx start start start + 1 start + 2 ] - + point: start stop: end - 3 @@ -340,7 +340,7 @@ OS-draw-spline: func [ end start start + 1 - cairo_close_path ctx + cairo_close_path ctx ][ do-spline-step ctx end - 2 @@ -432,7 +432,7 @@ OS-draw-ellipse: func [ OS-draw-font: func [ dc [draw-ctx!] font [red-object!] -][ +][ ; either pango-font? [ make-pango-cairo-font dc font ; ][ @@ -473,7 +473,7 @@ draw-text-at: func [ ;; print ["set-source-color: " ctx " " color lf] pango_cairo_update_layout ctx dc/layout - + size: 0 size: pango_font_description_get_size dc/font-desc ;; DEBUG: print ["pango_font_description_get_size: dc/font-desc: " dc/font-desc " size: " size lf] @@ -481,7 +481,7 @@ draw-text-at: func [ (as-float y) + ((as-float size) / PANGO_SCALE) pl: pango_layout_get_line_readonly dc/layout 0 pango_cairo_show_layout_line ctx pl - + ;pango_cairo_show_layout ctx dc/layout do-paint dc @@ -513,7 +513,7 @@ draw-text-box-lines: func [ dc/font-color ] - lc: either TYPE_OF(tbox) = TYPE_OBJECT [ + lc: either TYPE_OF(tbox) = TYPE_OBJECT [ ;; DEBUG: print ["draw-text-box-lines: " as int-ptr! dc lf] ;-- text-box! as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes ][ @@ -526,7 +526,7 @@ draw-text-box-lines: func [ set-source-color ctx clr ;; DEBUG: print ["set-source-color: " ctx " " clr lf] - + cairo_move_to ctx as-float pos/x (as-float pos/y) ; + sizef pango_cairo_show_layout ctx lc/layout @@ -557,15 +557,15 @@ draw-text-box: func [ if TYPE_OF(text) <> TYPE_STRING [exit] size: as red-pair! values + FACE_OBJ_SIZE - + ;; DEBUG: print ["pos : " pos/x "x" pos/y " size: " size/x "x" size/y lf] len: -1 str: unicode/to-utf8 text :len - ; default font-desc that can be overloaded in OS-text-box-layout called inside draw-text-box-lines + ; default font-desc that can be overloaded in OS-text-box-layout called inside draw-text-box-lines dc/font-desc: pango_font_description_from_string gtk-font ;;TORM: dc/layout: make-pango-cairo-layout dc/raw dc/font-desc - + ;; DEBUG: print ["draw-text-box text: " str " dc/font-desc: " dc/font-desc lf] draw-text-box-lines dc str pos size tbox ] @@ -653,9 +653,9 @@ OS-draw-curve: func [ ][ ctx: dc/raw - if (as-integer end - start) >> 4 = 3 ; four input points + if (as-integer end - start) >> 4 = 3 ; four input points [ - cairo_move_to ctx as-float start/x + cairo_move_to ctx as-float start/x as-float start/y start: start + 1 ] @@ -679,7 +679,7 @@ OS-draw-line-join: func [ ][ if dc/pen-join <> style [ dc/pen-join: style - cairo_set_line_join dc/raw + cairo_set_line_join dc/raw case [ style = miter [0] style = _round [1] @@ -689,7 +689,7 @@ OS-draw-line-join: func [ ] ] ] - + OS-draw-line-cap: func [ dc [draw-ctx!] style [integer!] @@ -738,7 +738,7 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local - cr [handle!] + cr [handle!] img [int-ptr!] bitmap [integer!] stride [integer!] @@ -789,13 +789,13 @@ OS-draw-image: func [ crop2: crop1 + 1 w: as float! crop2/x h: as float! crop2/y - crop_xscale: w / (as float! width) + crop_xscale: w / (as float! width) crop_yscale: h / (as float! height) crop_img_sx: as integer! (img_w / crop_xscale) crop_img_sy: as integer! (img_h / crop_yscale) ;width: as-integer (w / h * (as float! height)) ;; DEBUG: print ["cropping dest: " crop_x "x" crop_y "x" w "x" h " img size: " crop_img_sx "x" crop_img_sy lf] - img: gdk_pixbuf_scale_simple img crop_img_sx crop_img_sy 2 + img: gdk_pixbuf_scale_simple img crop_img_sx crop_img_sy 2 format: CAIRO_FORMAT_RGB24 ;either 3 = gdk_pixbuf_get_n_channels img [CAIRO_FORMAT_RGB24][CAIRO_FORMAT_ARGB32] ;; DEBÙG: print ["pixbuf format: " format lf] crop_surf: cairo_image_surface_create format crop_img_sx crop_img_sy @@ -806,7 +806,7 @@ OS-draw-image: func [ cairo_save cr cairo_translate cr as-float x as-float y - cairo_set_source_surface cr crop_surf (0.0 - (crop_x / crop_xscale)) (0.0 - (crop_y / crop_yscale)) + cairo_set_source_surface cr crop_surf (0.0 - (crop_x / crop_xscale)) (0.0 - (crop_y / crop_yscale)) cairo_rectangle cr 0.0 0.0 as float! width as float! height cairo_fill cr cairo_translate cr as-float (0 - x) as-float (0 - y) @@ -915,7 +915,7 @@ OS-draw-grad-pen: func [ spread [integer!] brush? [logic!] ][ - + ] OS-matrix-rotate: func [ @@ -930,12 +930,12 @@ OS-matrix-rotate: func [ cr: dc/raw rad: PI / 180.0 * get-float angle if angle <> as red-integer! center [ - cairo_translate cr as float! center/x + cairo_translate cr as float! center/x as float! center/y ] cairo_rotate cr rad if angle <> as red-integer! center [ - cairo_translate cr as float! (0 - center/x) + cairo_translate cr as float! (0 - center/x) as float! (0 - center/y) ] ] @@ -962,7 +962,7 @@ OS-matrix-translate: func [ cr [handle!] ][ cr: dc/raw - cairo_translate cr as-float x + cairo_translate cr as-float x as-float y ] @@ -1042,7 +1042,7 @@ OS-matrix-set: func [ m/yy: get-float val + 3 m/x0: get-float val + 4 m/y0: get-float val + 5 - cairo_transform dc/raw :m ; Weirdly it is not cairo_set_matrix because it is a global change! + cairo_transform dc/raw :m ; Weirdly it is not cairo_set_matrix because it is a global change! ] OS-set-matrix-order: func [ @@ -1065,7 +1065,7 @@ OS-set-clip: func [ OS-draw-shape-beginpath: func [ dc [draw-ctx!] -][ +][ ] OS-draw-shape-endpath: func [ @@ -1199,7 +1199,7 @@ draw-curve: func [ dc/shape-curve?: yes either num = 3 [ ;-- cubic Bézier - either rel? [cairo_rel_curve_to dc/raw p1x p1y p2x p2y p3x p3y] + either rel? [cairo_rel_curve_to dc/raw p1x p1y p2x p2y p3x p3y] [cairo_curve_to dc/raw p1x p1y p2x p2y p3x p3y] ; dc/control-x: p2x ; dc/control-y: p2y diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e5e28d4d6c..5195f77806 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -122,11 +122,11 @@ get-event-offset: func [ ;; DEBUG: print ["event-offset type: " get-symbol-name get-widget-symbol widget " size: " sz/x "x" sz/y lf] ; sz/x: evt-sizing/x_new ; sz/y: evt-sizing/y_new - + ; print ["OFFSET is SIZE ? " sz " vs " offset lf] ; => NO! ; alternative 1: ; sz/x: (as integer! evt-sizing/x_root) - offset/x - ; sz/y: (as integer! evt-sizing/y_root) - offset/y + ; sz/y: (as integer! evt-sizing/y_root) - offset/y ; alternative 2: ; sz/x: gtk_widget_get_allocated_width widget @@ -291,7 +291,7 @@ get-event-flags: func [ ][ ;; DEBUG: print ["get-event-flags " lf] blk: flags-blk - block/rs-clear blk + block/rs-clear blk if evt/flags and EVT_FLAG_AWAY <> 0 [block/rs-append blk as red-value! _away] if evt/flags and EVT_FLAG_DOWN <> 0 [block/rs-append blk as red-value! _down] if evt/flags and EVT_FLAG_MID_DOWN <> 0 [block/rs-append blk as red-value! _mid-down] @@ -312,7 +312,7 @@ get-event-flag: func [ ] ;; This function is only called in handlers.red -;; No +;; No make-event: func [ msg [handle!] flags [integer!] @@ -405,7 +405,7 @@ make-event: func [ ; if TYPE_OF(res) = TYPE_WORD [ ; sym: symbol/resolve res/symbol - ; ;; DEBUG: + ; ;; DEBUG: ; print ["make-events result:" sym lf] ; case [ @@ -437,7 +437,7 @@ do-events: func [ ;@@ we use a global value to simulate it ;; DEBUG: print ["do-events no-wait? " no-wait? lf] - + ;; Initially normally uncommented: the exit-loop is also decremented in destroy for supposed no-wait view! unless no-wait? [ exit-loop: exit-loop + 1 @@ -447,7 +447,7 @@ do-events: func [ if g_main_context_iteration GTKApp-Ctx not no-wait? [msg?: yes] if no-wait? [break] ] - + while [g_main_context_iteration GTKApp-Ctx false][ ;-- consume leftover event msg?: yes if no-wait? [break] @@ -533,7 +533,7 @@ translate-key: func [ ;; DEBUG: print [" translate-key: keycode: " keycode lf] special?: no key: case [ - all[keycode >= 20h keycode <= 5Ah][keycode]; RED_VK_SPACE to RED_VK_Z + all[keycode >= 20h keycode <= 5Ah][keycode]; RED_VK_SPACE to RED_VK_Z all[keycode >= 5Bh keycode <= 60h][keycode] all[keycode >= 61h keycode <= 7Ah][keycode]; RED_VK_a to RED_VK_z all[keycode >= 7Bh keycode <= 7Dh][keycode]; @@ -571,7 +571,7 @@ post-quit-msg: func [ ;;------------- centralize here connection handlers ;; The goal is to only connect gtk handlers only when actor is provided -;; Rmk: Specific development for rich-text with panel parent with on-over actor for rich-text +;; Rmk: Specific development for rich-text with panel parent with on-over actor for rich-text ;; The panel needs to receive the event otherwise the rich-text can't receive the event with the associated actor. ;; A delegation connection is provided to do so. @@ -596,7 +596,7 @@ debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and respond-event?: func [ - actors [red-object!] + actors [red-object!] type [c-string!] return: [logic!] /local @@ -620,7 +620,7 @@ respond-window-id: g_quark_from_string "respond-window-id" ON_LEFT_UP: 2 ON_MIDDLE_DOWN: 4 ON_MIDDLE_UP: 8 - ON_RIGHT_DOWN: 16 + ON_RIGHT_DOWN: 16 ON_RIGHT_UP: 32 ON_AUX_DOWN: 64 ON_AUX_UP: 128 @@ -638,16 +638,16 @@ respond-mouse-add: func [ on-type [integer!] ][ on-type: 0 - if respond-event? actors "on-down" [on-type: on-type or ON_LEFT_DOWN] + if respond-event? actors "on-down" [on-type: on-type or ON_LEFT_DOWN] if respond-event? actors "on-up" [on-type: on-type or ON_LEFT_UP] - if respond-event? actors "on-mid-down" [on-type: on-type or ON_MIDDLE_DOWN] + if respond-event? actors "on-mid-down" [on-type: on-type or ON_MIDDLE_DOWN] if respond-event? actors "on-mid-up" [on-type: on-type or ON_MIDDLE_UP] - if respond-event? actors "on-alt-down" [on-type: on-type or ON_RIGHT_DOWN] + if respond-event? actors "on-alt-down" [on-type: on-type or ON_RIGHT_DOWN] if respond-event? actors "on-alt-up" [on-type: on-type or ON_RIGHT_UP] - if respond-event? actors "on-aux-down" [on-type: on-type or ON_AUX_DOWN] - if respond-event? actors "on-aux-up" [on-type: on-type or ON_AUX_UP] + if respond-event? actors "on-aux-down" [on-type: on-type or ON_AUX_DOWN] + if respond-event? actors "on-aux-up" [on-type: on-type or ON_AUX_UP] if respond-event? actors "on-click" [on-type: on-type or ON_CLICK] if respond-event? actors "on-dbl-click" [on-type: on-type or ON_DBL_CLICK] - if respond-event? actors "on-wheel" [on-type: on-type or ON_WHEEL] + if respond-event? actors "on-wheel" [on-type: on-type or ON_WHEEL] if respond-event? actors "on-over" [on-type: on-type or ON_OVER] if all[on-type > 0 not null? widget][ ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_MOUSE [print ["Add mouse event " on-type " for " get-symbol-name sym lf ]] @@ -691,12 +691,12 @@ respond-window-add: func [ if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] - if respond-event? actors "on-time" [on-type: on-type or ON_TIME] + if respond-event? actors "on-time" [on-type: on-type or ON_TIME] if respond-event? actors "on-drawing" [on-type: on-type or ON_DRAWING] - if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] + if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] if respond-event? actors "on-over" [on-type: on-type or ON_OVER] if respond-event? actors "on-select" [on-type: on-type or ON_SELECT] - if respond-event? actors "on-change" [on-type: on-type or ON_CHANGE] + if respond-event? actors "on-change" [on-type: on-type or ON_CHANGE] if respond-event? actors "on-menu" [on-type: on-type or ON_MENU] if all[on-type > 0 not null? widget][ ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_WINDOW [print ["Add window event " on-type " for " get-symbol-name sym lf ]] @@ -739,12 +739,12 @@ respond-key-add: func [ if respond-event? actors "on-key-down" [on-type: on-type or ON_KEY_DOWN] if respond-event? actors "on-key-up" [on-type: on-type or ON_KEY_UP] if respond-event? actors "on-ime" [on-type: on-type or ON_IME] - if respond-event? actors "on-focus" [on-type: on-type or ON_FOCUS] + if respond-event? actors "on-focus" [on-type: on-type or ON_FOCUS] if respond-event? actors "on-unfocus" [on-type: on-type or ON_UNFOCUS] - if respond-event? actors "on-enter" [on-type: on-type or ON_ENTER] + if respond-event? actors "on-enter" [on-type: on-type or ON_ENTER] if respond-event? actors "on-zoom" [on-type: on-type or ON_ZOOM] if respond-event? actors "on-pan" [on-type: on-type or ON_PAN] - if respond-event? actors "on-rotate" [on-type: on-type or ON_ROTATE] + if respond-event? actors "on-rotate" [on-type: on-type or ON_ROTATE] if respond-event? actors "on-two-tap" [on-type: on-type or ON_TWO_TAP] if respond-event? actors "on-press-tap" [on-type: on-type or ON_PRESS_TAP] if all[on-type > 0 not null? widget][ @@ -797,8 +797,8 @@ connect-container-events: func [ ;; TODO: before finding better solution!!!! ;; container-type? is now only restricted to rich-text (cf gui.red) -;; since -;; 1) it is required in makedoc/easy-VID-rt.red +;; since +;; 1) it is required in makedoc/easy-VID-rt.red ;; 2) it is too slow when used in ast.red for base widget (too much delegations). connect-common-events: function [ @@ -811,7 +811,7 @@ connect-common-events: function [ if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-DOWN: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK if container-type? sym [ ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH connect-container-events widget "button-press-event" @@ -827,7 +827,7 @@ connect-common-events: function [ ] gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) ] - + if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-UP: " get-symbol-name sym "->" widget lf]] gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK @@ -843,7 +843,7 @@ connect-common-events: function [ gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) ] - + if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-KEY-UP: " get-symbol-name sym "->" widget lf]] gtk_widget_add_events widget GDK_KEY_RELEASE_MASK @@ -895,7 +895,7 @@ connect-widget-events: function [ buffer [handle!] ][ ;; register red mouse, key and window on event functions - + ;; DEBUG: print ["common-widget-events for " get-symbol-name sym " " widget lf] ;; DEBUG: if null? actors/ctx [print ["null? actors/ctx" lf]] @@ -914,7 +914,7 @@ connect-widget-events: function [ gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = radio [ - ;@@ Line below removed because it generates an error and there is no click event for radio + ;@@ Line below removed because it generates an error and there is no click event for radio ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add radio toggled " lf]] gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] @@ -974,7 +974,7 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add fiedl button-release-event " lf]] gobj_signal_connect(widget "button-release-event" :field-button-release-event face/ctx) ;;] - + gtk_widget_set_can_focus widget yes gtk_widget_is_focus widget ;This depends on version >= 3.2 @@ -990,7 +990,7 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] gobj_signal_connect(buffer "changed" :area-changed widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] - g_object_set [widget "populate-all" yes null] + g_object_set [widget "populate-all" yes null] if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area button-press-event " lf]] gobj_signal_connect(widget "button-press-event" :area-button-press-event face/ctx) @@ -1023,8 +1023,8 @@ connect-widget-events: function [ ; if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ ; gobj_signal_connect(widget "button-press-event" :panel-button-press-event face/ctx) ;] - ; if respond-mouse? widget ON_OVER [gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx)] - + ; if respond-mouse? widget ON_OVER [gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx)] + ; if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx)] ; if respond-key? widget (ON_KEY or ON_KEY_DOWN) [gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx)] ; if respond-key? widget ON_KEY_UP [gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx)] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index cc1df1174a..160d66ed81 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -170,7 +170,7 @@ set-font-handle: func [ ] values: object/get-values font - + blk: as red-block! values + FONT_OBJ_STATE either TYPE_OF(blk) <> TYPE_BLOCK [ block/make-at blk 2 @@ -233,7 +233,7 @@ font-description: func [ color: as red-tuple! values + FONT_OBJ_COLOR ; font name - name: "Arial" ; @@ to change to default font name + name: "Arial" ; @@ to change to default font name if TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len @@ -259,7 +259,7 @@ font-description: func [ unless zero? len [ loop len [ sym: symbol/resolve style/symbol - case [ + case [ sym = _bold [fweight: PANGO_WEIGHT_BOLD] sym = _italic [fstyle: PANGO_STYLE_ITALIC] sym = _underline [] @@ -294,8 +294,8 @@ font-description-create: func [ pango_font_description_set_style fd fstyle pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL pango_font_description_set_variant fd PANGO_VARIANT_NORMAL - - ;; DOES NOT WORK AS EXPECTED: + + ;; DOES NOT WORK AS EXPECTED: ;; css: pango_font_description_to_string fd ;; print ["font description css: " css lf] @@ -345,8 +345,8 @@ css-styles: func [ rgba [c-string!] ][ css: g_strdup_printf ["* {"] - - if TYPE_OF(font) = TYPE_OBJECT [ + + if TYPE_OF(font) = TYPE_OBJECT [ values: object/get-values font ;name: @@ -420,7 +420,7 @@ css-styles: func [ ] ;; DEBUG: print ["css-styles -> css: " css lf] - + css ] @@ -456,19 +456,19 @@ css-provider: func [ provider: gtk_css_provider_new gtk_css_provider_load_from_path provider path null display: gdk_display_get_default - screen: gdk_display_get_default_screen display + screen: gdk_display_get_default_screen display gtk_style_context_add_provider_for_screen screen provider priority g_object_unref provider ] red-gtk-styles: func [ - /local + /local env strarr str found [logic!] ][ env: system/env-vars found: no - until [ + until [ strarr: g_strsplit env/item "=" 2 str: as c-string! (strarr/1) if 0 = g_strcmp0 str "RED_GTK_STYLES" [ @@ -479,7 +479,7 @@ red-gtk-styles: func [ env: env + 1 g_strfreev strarr any[found env/item = null] - ] + ] ] font-color?: func [ @@ -550,11 +550,11 @@ make-cairo-draw-font: func [ slant: CAIRO_FONT_SLANT_NORMAL weight: CAIRO_FONT_WEIGHT_NORMAL - + unless zero? len [ loop len [ sym: symbol/resolve style/symbol - case [ + case [ sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] sym = _underline [] @@ -574,10 +574,10 @@ make-cairo-draw-font: func [ cairo-font-size: as-float size/value cairo_set_font_size cr cairo-font-size * ((extents/ascent + extents/descent) / extents/ascent) - ; This technique is little more correct for me. + ; This technique is little more correct for me. ; This Red example will show the difference: ; - ; f: make font! [name: "Arial" size: 120] + ; f: make font! [name: "Arial" size: 120] ; view [base 140x140 draw [font f text 10x10 "A" pen white box 0x10 140x130]] ] ] @@ -622,7 +622,7 @@ make-pango-cairo-font: func [ dc/font-color: color/array1 ;;;------- font description - fname: "Arial" ; @@ to change to default font name + fname: "Arial" ; @@ to change to default font name if TYPE_OF(str) = TYPE_STRING [ len: -1 fname: unicode/to-utf8 str :len @@ -644,7 +644,7 @@ make-pango-cairo-font: func [ unless zero? len [ loop len [ sym: symbol/resolve style/symbol - case [ + case [ sym = _bold [fweight: PANGO_WEIGHT_BOLD] sym = _italic [fstyle: PANGO_STYLE_ITALIC] sym = _underline [dc/font-underline?: yes] @@ -658,10 +658,10 @@ make-pango-cairo-font: func [ free-pango-cairo-font dc dc/font-desc: font-description-create fname fsize fweight fstyle dc/font-opts: cairo_font_options_create - + dc/layout: make-pango-cairo-layout cr dc/font-desc - + ;anti-alias?: value: values + FONT_OBJ_ANTI-ALIAS? @@ -721,7 +721,7 @@ pango-cairo-set-text: func [ ptext-ptr [int-ptr!] mtext [c-string!] ptext [c-string!] - accel [integer!] + accel [integer!] error [handle!] ][ unless null? dc/layout [ @@ -744,7 +744,7 @@ pango-cairo-set-text: func [ ] ;; A rewrite of pango_layout_set_markup but in red/system to control warning messages -;; with option force to avoid the warning when considering +;; with option force to avoid the warning when considering pango-layout-set-markup: func [ layout [handle!] mtext [c-string!] @@ -756,7 +756,7 @@ pango-layout-set-markup: func [ attrs [handle!] ptext-ptr [int-ptr!] ptext [c-string!] - accel [integer!] + accel [integer!] error [handle!] ][ unless null? layout [ @@ -792,7 +792,7 @@ pango-layout-context-set-text: func [ ptext-ptr [int-ptr!] mtext [c-string!] ptext [c-string!] - accel [integer!] + accel [integer!] error [handle!] ][ unless null? layout [ @@ -819,7 +819,7 @@ free-pango-cairo-font: func [ ][ ;; DEBUG: print ["free-pango-cairo-layout begin" lf] unless null? dc/font-desc [ - pango_font_description_free dc/font-desc + pango_font_description_free dc/font-desc dc/font-desc: null ] ;; DEBUG: print ["free-pango-cairo-layout font-opts: " dc/font-opts lf] @@ -843,7 +843,7 @@ make-pango-cairo-layout: func [ layout [handle!] ][ ;; DEBUG: print ["make-pango-cairo-layout" lf] - layout: pango_cairo_create_layout cr + layout: pango_cairo_create_layout cr unless null? fd [pango_layout_set_font_description layout fd] ;; DEBUG: print ["make-pango-cairo-layout: " layout lf] layout diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 3db34baca2..93308af179 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -30,7 +30,7 @@ RECT_STRUCT: alias struct! [ tagPOINT: alias struct! [ x [integer!] - y [integer!] + y [integer!] ] tagSIZE: alias struct! [ @@ -40,7 +40,7 @@ tagSIZE: alias struct! [ tagRECT: alias struct! [ x [integer!] - y [integer!] + y [integer!] width [integer!] height [integer!] ] @@ -74,8 +74,8 @@ GdkEventMotion!: alias struct! [ y [float!] axes [float-ptr!] state [integer!] - is_hint1 [byte!] - is_hint2 [byte!] + is_hint1 [byte!] + is_hint2 [byte!] device [int-ptr!] x_root [float!] y_root [float!] @@ -90,7 +90,7 @@ GdkEventButton!: alias struct! [ y [float!] axes [float-ptr!] state [integer!] - button [integer!] + button [integer!] device [int-ptr!] x_root [float!] y_root [float!] @@ -108,8 +108,8 @@ GdkEventCrossing!: alias struct! [ y_root [float!] axes [float-ptr!] state [integer!] - is_hint1 [byte!] - is_hint2 [byte!] + is_hint1 [byte!] + is_hint2 [byte!] device [int-ptr!] mode [integer!] detail [integer!] @@ -122,7 +122,7 @@ GdkEventConfigure!: alias struct! [ window [handle!] send_event [byte!] x [integer!] - y [integer!] + y [integer!] width [integer!] height [integer!] ] @@ -174,7 +174,7 @@ GdkEventScroll!: alias struct! [ GDK_BUTTON4_MASK: 2048 GDK_BUTTON5_MASK: 4096 GDK_SUPER_MASK: 67108864 - GDK_HYPER_MASK: 134217728 + GDK_HYPER_MASK: 134217728 GDK_META_MASK: 268435456 ] #enum GdkEventType! [ @@ -260,7 +260,7 @@ GdkEventScroll!: alias struct! [ ;;GDK_ALL_EVENTS_MASK: fffffffeh ] -GtkTextIter!: alias struct! [ +GtkTextIter!: alias struct! [ dummy1 [handle!] dummy2 [handle!] dummy3 [integer!] @@ -285,16 +285,16 @@ GtkTextIter!: alias struct! [ ] #enum GtkResponseType! [ - GTK_RESPONSE_NONE - GTK_RESPONSE_REJECT - GTK_RESPONSE_ACCEPT - GTK_RESPONSE_DELETE_EVENT - GTK_RESPONSE_OK - GTK_RESPONSE_CANCEL - GTK_RESPONSE_CLOSE - GTK_RESPONSE_YES - GTK_RESPONSE_NO - GTK_RESPONSE_APPLY + GTK_RESPONSE_NONE + GTK_RESPONSE_REJECT + GTK_RESPONSE_ACCEPT + GTK_RESPONSE_DELETE_EVENT + GTK_RESPONSE_OK + GTK_RESPONSE_CANCEL + GTK_RESPONSE_CLOSE + GTK_RESPONSE_YES + GTK_RESPONSE_NO + GTK_RESPONSE_APPLY GTK_RESPONSE_HELP ] @@ -469,7 +469,7 @@ cairo_matrix_t!: alias struct! [ ] ; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo -; cairo_text_extents_t!: alias struct! [ +; cairo_text_extents_t!: alias struct! [ ; x_bearing [float!] ; y_bearing [float!] ; width [float!] @@ -650,7 +650,7 @@ GPtrArray!: alias struct! [ gdk_keyval_to_lower: "gdk_keyval_to_lower" [ code [integer!] return: [integer!] - ] + ] gdk_keyval_is_upper: "gdk_keyval_is_upper" [ code [integer!] return: [logic!] @@ -658,7 +658,7 @@ GPtrArray!: alias struct! [ gdk_keyval_is_lower: "gdk_keyval_is_lower" [ code [integer!] return: [logic!] - ] + ] gdk_atom_intern_static_string: "gdk_atom_intern_static_string" [ name [c-string!] return: [handle!] @@ -1234,11 +1234,11 @@ GPtrArray!: alias struct! [ ] gtk_window_set_focus: "gtk_window_set_focus" [ window [handle!] - widget [handle!] + widget [handle!] ] gtk_window_get_default_widget: "gtk_window_get_default_widget" [ window [handle!] - return: [handle!] + return: [handle!] ] gtk_window_set_default: "gtk_window_set_default" [ window [handle!] @@ -1449,12 +1449,12 @@ GPtrArray!: alias struct! [ ] gtk_widget_override_font: "gtk_widget_override_font" [ widget [handle!] - fd [handle!] + fd [handle!] ] gtk_widget_override_color: "gtk_widget_override_color" [ widget [handle!] state [integer!] - color [handle!] + color [handle!] ] gtk_container_add: "gtk_container_add" [ container [handle!] @@ -1899,7 +1899,7 @@ GPtrArray!: alias struct! [ ] gtk_notebook_get_n_pages: "gtk_notebook_get_n_pages" [ nb [handle!] - return: [integer!] + return: [integer!] ] gtk_css_provider_new: "gtk_css_provider_new" [ return: [handle!] @@ -1987,7 +1987,7 @@ GPtrArray!: alias struct! [ len [integer!] accel_mark [integer!] accel_char [int-ptr!] - ] + ] pango_layout_get_font_description: "pango_layout_get_font_description" [ layout [handle!] return: [handle!] @@ -2231,12 +2231,12 @@ GPtrArray!: alias struct! [ return: [handle!] ] - + gtk_widget_get_pango_context: "gtk_widget_get_pango_context" [ return: [handle!] ] - + gtk_settings_get_default: "gtk_settings_get_default" [ return: [handle!] ] @@ -2496,7 +2496,7 @@ GPtrArray!: alias struct! [ format [cairo_format_t!] width [integer!] height [integer!] - return: [handle!] + return: [handle!] ] cairo_image_surface_create_for_data: "cairo_image_surface_create_for_data" [ data [byte-ptr!] @@ -2682,7 +2682,7 @@ GPtrArray!: alias struct! [ pango_attr_list_insert_before: "pango_attr_list_insert_before" [ attrs [handle!] attr [PangoAttribute!] - ] + ] pango_attr_list_splice: "pango_attr_list_splice" [ attrs [handle!] attrs2 [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 46a80c0833..f7c7034e2b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -57,12 +57,12 @@ tabs: context [ ; to put in other place (usually platform.red) if useful _drag-on: symbol/make "drag-on" -settings: as handle! 0 +settings: as handle! 0 pango-context: as handle! 0 gtk-font: "Sans 13" default-font: as handle! 0 -; Do not KNOW about this one +; Do not KNOW about this one ;;; main-window: as handle! 0 last-window: as handle! 0 @@ -183,7 +183,7 @@ get-widget-data: func [ as red-block! values + FACE_OBJ_DATA ] -;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget +;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget set-_widget: func [ widget [handle!] _widget [handle!] @@ -307,7 +307,7 @@ set-view-no-wait: func [ window [handle!] key [logic!] ][ - ; usually a view/no-wait call at most twice do-events and at least one do-events with no-wait? = true + ; usually a view/no-wait call at most twice do-events and at least one do-events with no-wait? = true ;; DEBUG[view/no-wait]: print ["view-no-wait? window " window " => " key lf] g_object_set_qdata window no-wait-id as int-ptr! either key [1][0] ] @@ -371,7 +371,7 @@ get-text-size: func [ ;if null? pl [ pl: pango_layout_new pango-context ;] - + pango_layout_set_text pl text -1 pango_layout_set_font_description pl hFont @@ -381,7 +381,7 @@ get-text-size: func [ size/width: width size/height: height - + if pair <> null [ pair/x: size/width pair/y: size/height @@ -498,17 +498,17 @@ debug-show-children: func [ sym: symbol/resolve type/symbol rect: as tagRECT allocate (size? tagRECT) - + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane if debug [print ["Pane type: " get-symbol-name sym lf]] if TYPE_OF(face) <> TYPE_OBJECT [print-line "not face object"] widget_: face-handle? face - + either null? widget_ [print-line "null container" container: null][container: container? widget_] print ["container handle: " container lf] - + sx: 0 sy: 0 cpt: 0 while [face < tail][ @@ -521,17 +521,17 @@ debug-show-children: func [ size: as red-pair! values + FACE_OBJ_SIZE type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - + if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] - ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 - - unless null? container [ + ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 + + unless null? container [ widget_: _widget? child gtk_widget_get_allocation widget_ as handle! rect ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] - ] + ] if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] either null? child [print-line "null child"][debug-show-children child no] face: face + 1 @@ -577,7 +577,7 @@ get-symbol-name: function [ ][ case [ sym = check ["check"] - sym = radio ["radio"] + sym = radio ["radio"] sym = button ["button"] sym = base ["base"] sym = window ["window"] @@ -594,11 +594,11 @@ get-symbol-name: function [ sym = drop-down ["drop-down"] sym = rich-text ["rich-text"] sym = done ["done"] - sym = stop ["stop"] + sym = stop ["stop"] sym = _image ["image"] sym = facets/pane ["facets/pane"] - + sym = words/_remove/symbol ["words/remove"] sym = words/_take/symbol ["words/take"] sym = words/_clear/symbol ["words/clear"] @@ -606,11 +606,11 @@ get-symbol-name: function [ sym = words/_poke/symbol ["words/poke"] sym = words/_moved/symbol ["words/moved"] sym = words/_changed/symbol ["words/changed"] - + true ["undefined"] ] ] -; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane +; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane adjust-sizes: func [ widget [handle!] /local @@ -647,7 +647,7 @@ adjust-sizes: func [ sym: symbol/resolve type/symbol rect: as tagRECT allocate (size? tagRECT) - + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane @@ -666,11 +666,11 @@ adjust-sizes: func [ size: as red-pair! values + FACE_OBJ_SIZE type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] + overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] - ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 + ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 if any [ox > offset/x not overlap?] [dx: 0] - unless null? container [ + unless null? container [ widget_: _widget? child if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] gtk_layout_move container widget_ offset/x + dx offset/y @@ -679,7 +679,7 @@ adjust-sizes: func [ if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] ] ; save previous offset and size coordinates - ox: offset/x oy: offset/y sx: size/x sy: size/y + ox: offset/x oy: offset/y sx: size/x sy: size/y if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] dx: dx + rect/width - sx dy: dy + rect/height - sy @@ -747,17 +747,17 @@ remove-all-timers: func [ type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE rate: values + FACE_OBJ_RATE - + change-rate widget none-value sym: symbol/resolve type/symbol - + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane - + while [face < tail][ - widget_: face-handle? face + widget_: face-handle? face unless null? widget [remove-all-timers widget_] face: face + 1 ] @@ -784,7 +784,7 @@ change-rate: func [ ts: 1000 / int/value ] TYPE_TIME [ - tm: as red-time! rate + tm: as red-time! rate if tm/time <= 0.0 [fire [TO_ERROR(script invalid-facet-type) rate]] ts: as-integer tm/time * 1000.0 if ts = 0 [ts: 1] @@ -907,14 +907,14 @@ change-pane: func [ gtk_container_add parent _widget values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - gtk_layout_move parent _widget offset/x offset/y + gtk_layout_move parent _widget offset/x offset/y ] ] face: face + 1 ] ;; OS-refresh-window as-integer main-window - - ;; DEBUG: + + ;; DEBUG: ; list: as GList! gtk_container_get_children parent ; child: list nb: 0 ; while [not null? child][ @@ -952,7 +952,7 @@ change-font: func [ ;; Update the pango_font_description hFont (directly used by get-text-size) make-font face font - + yes ] @@ -975,7 +975,7 @@ change-offset: func [ ; _widget: either type = text [ ; g_object_get_qdata widget _widget-id ; ][widget] - + _widget: _widget? widget unless null? container [ gtk_layout_move container _widget pos/x pos/y @@ -993,7 +993,7 @@ change-size: func [ _widget [handle!] ][ ;; DEBUG: print ["change-size " get-symbol-name get-widget-symbol widget " " widget " " size/x "x" size/y lf] - + either type = window [ ;; DEBUG: print ["change-size window: " size/x "x" size/y lf] gtk_window_set_default_size widget size/x size/y @@ -1041,13 +1041,13 @@ init-all-children: func [ unless null? win [gdk_window_set_cursor win cursor] ] ;;;;; init end - + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane while [face < tail][ - child: face-handle? face + child: face-handle? face unless null? child [ init-all-children child ] @@ -1115,7 +1115,7 @@ change-text: func [ default [null] ;@@ Auto-convert? ] if null? cstr [exit] - + ;unless change-font widget face as red-object! values + FACE_OBJ_FONT type [ case [ type = area [ @@ -1134,7 +1134,7 @@ change-text: func [ ] type = window [ gtk_window_set_title widget cstr - ] + ] type = group-box [ gtk_frame_set_label widget cstr ] @@ -1239,7 +1239,7 @@ change-selection: func [ gtk_editable_select_region widget idx idx + sz ][ buffer: gtk_text_view_get_buffer widget - ins: as GtkTextIter! allocate (size? GtkTextIter!) + ins: as GtkTextIter! allocate (size? GtkTextIter!) bound: as GtkTextIter! allocate (size? GtkTextIter!) ;; Careful! GtkTextIter! needs to be initialized first (so this weird call first!) gtk_text_buffer_get_selection_bounds buffer as handle! ins as handle! bound @@ -1247,7 +1247,7 @@ change-selection: func [ gtk_text_iter_set_offset as handle! ins idx gtk_text_iter_set_offset as handle! bound idx + sz gtk_text_buffer_select_range buffer as handle! ins as handle! bound - free as byte-ptr! ins free as byte-ptr! bound + free as byte-ptr! ins free as byte-ptr! bound ] ] ; type = camera [ @@ -1299,7 +1299,7 @@ set-hint-text: func [ str: unicode/to-utf8 text :len gtk_entry_set_placeholder_text widget str ] -] +] set-selected-focus: func [ widget [handle!] @@ -1358,7 +1358,7 @@ get-flags: func [ default [return 0] ] flags: 0 - + until [ sym: symbol/resolve word/symbol case [ @@ -1467,7 +1467,7 @@ init-combo-box: func [ val: unicode/to-utf8 str :len gtk_combo_box_text_append_text combo val ] - str: str + 1 + str: str + 1 ] ] @@ -1626,7 +1626,7 @@ parse-common-opts: func [ sym: symbol/resolve word/symbol case [ sym = _drag-on [ - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK gobj_signal_connect(widget "motion-notify-event" :drag-widget-motion-notify-event face/ctx) gobj_signal_connect(widget "button-press-event" :drag-widget-button-press-event face/ctx) gobj_signal_connect(widget "button-release-event" :drag-widget-button-release-event face/ctx) @@ -1695,7 +1695,7 @@ OS-redraw: func [ ] OS-refresh-window: func [widget [integer!]][ - ;; DEBUG: print-line "OS-refresh-window" + ;; DEBUG: print-line "OS-refresh-window" ;debug-show-children main-window no ;gtk_widget_queue_draw main-window OS-show-window widget @@ -1786,7 +1786,7 @@ OS-make-view: func [ sym: symbol/resolve type/symbol actors: as red-object! values + FACE_OBJ_ACTORS - + ; if bits and FACET_FLAGS_SCROLLABLE <> 0 [ ; flags: flags or WS_HSCROLL or WS_VSCROLL ; ] @@ -1845,13 +1845,13 @@ OS-make-view: func [ main-window: widget ] gtk_application_add_window GTKApp widget - + if bits and FACET_FLAGS_MODAL <> 0 [ ;; DEBUG: print ["Creation of Modal window" lf] gtk_window_set_modal widget yes ] unless null? caption [gtk_window_set_title widget caption] - + winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox if all [ ;@@ application menu ? @@ -1861,21 +1861,21 @@ OS-make-view: func [ AppMainMenu: gtk_menu_bar_new ;; DEBUG: print ["AppMainMenu " AppMainMenu " creation for window " widget lf] build-menu menu AppMainMenu widget - gtk_box_pack_start winbox AppMainMenu no yes 0 + gtk_box_pack_start winbox AppMainMenu no yes 0 ] gtk_widget_show winbox container: gtk_layout_new null null gtk_layout_set_size container size/x size/y - gtk_box_pack_start winbox container yes yes 0 + gtk_box_pack_start winbox container yes yes 0 g_object_set_qdata widget real-container-id container ;; DEBUG: print ["window is " widget " real container is " container lf] gtk_window_move widget offset/x offset/y - + ;; The following line really matters to fix the initial size of the window gtk_widget_set_size_request widget size/x size/y gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) gtk_window_set_decorated widget (bits and FACET_FLAGS_NO_BORDER = 0) - + ] sym = slider [ vertical?: size/y > size/x @@ -1921,7 +1921,7 @@ OS-make-view: func [ widget: gtk_frame_new caption gtk_frame_set_shadow_type widget 3 gtk_frame_set_label_align widget 0.5 0.5; Todo: does not seem to work - container: gtk_layout_new null null + container: gtk_layout_new null null gtk_container_add widget container ] sym = panel [ @@ -1965,10 +1965,10 @@ OS-make-view: func [ parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym ; save the previous group-radio state as a global variable - group-radio: either sym = radio [widget][as handle! 0] + group-radio: either sym = radio [widget][as handle! 0] ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] - + if all [ sym <> window parent <> 0 @@ -2011,14 +2011,14 @@ OS-make-view: func [ ] any [p-sym = panel p-sym = rich-text p-sym = base] [parent] p-sym = group-box [ - buffer: gtk_container_get_children as handle! parent + buffer: gtk_container_get_children as handle! parent ;; DEBUG: print ["Parent when not container : " buffer/value lf] buffer/value ] true [ - ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug - ; buffer: gtk_container_get_children as handle! parent - ; ;; DEBUG: + ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug + ; buffer: gtk_container_get_children as handle! parent + ; ;; DEBUG: ; print ["Parent when not container : " buffer/value lf] ; buffer/value @@ -2042,9 +2042,9 @@ OS-make-view: func [ ; Deal with actors connect-widget-events widget face actors sym _widget as int-ptr! parent - + unless any[sym = window sym = area][build-context-menu widget menu] - + ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events store-face-to-obj widget face @@ -2053,7 +2053,7 @@ OS-make-view: func [ change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym change-enabled widget enabled?/value sym - + make-styles-provider widget ;; TODO: NOT SURE the if is necessary! @@ -2062,7 +2062,7 @@ OS-make-view: func [ ] if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] - + change-color widget as red-tuple! values + FACE_OBJ_COLOR sym ;; USELESS: if sym <> window [gtk_widget_show widget] @@ -2100,7 +2100,7 @@ OS-update-view: func [ type = rich-text update-rich-text state as red-block! values + FACE_OBJ_EXT3 ][ - ;; DEBUG: print ["update-view rich-text" lf] + ;; DEBUG: print ["update-view rich-text" lf] exit ] @@ -2108,7 +2108,7 @@ OS-update-view: func [ int: as red-integer! s/offset widget: as handle! int/value if null? widget [exit] - + int: int + 1 flags: int/value @@ -2140,7 +2140,7 @@ OS-update-view: func [ if flags and FACET_FLAG_FLAGS <> 0 [ flags: get-flags as red-block! values + FACE_OBJ_FLAGS if all[ - type = field + type = field flags and FACET_FLAGS_PASSWORD <> 0 ][ ;; DEBUG: print ["password flag activated for field" lf] @@ -2206,7 +2206,7 @@ unlink-sub-obj: func [ ][ values: object/get-values obj parent: as red-block! values + field - + if TYPE_OF(parent) = TYPE_BLOCK [ res: block/find parent as red-value! face null no no yes no null null no no no no if TYPE_OF(res) <> TYPE_NONE [_series/remove as red-series! res null null] @@ -2228,13 +2228,13 @@ OS-destroy-view: func [ obj [red-object!] flags [integer!] ][ - ;; DEBUG: print ["OS-destroy-view" lf] + ;; DEBUG: print ["OS-destroy-view" lf] handle: face-handle? face values: object/get-values face flags: get-flags as red-block! values + FACE_OBJ_FLAGS either handle <> main-window [ ;; DEBUG: if flags and FACET_FLAGS_MODAL <> 0 [print ["modal "]] print ["window: " handle " (main-window: " main-window ") closing... win-cnt: " win-cnt " exit-loop: " exit-loop lf ] - + ;gtk_window_close handle ;; NOT ENOUGH SINCE THIS IS EQUIVALENT TO CLICKING CLOSE BUTTON gtk_widget_destroy handle win-cnt: win-cnt - 1 @@ -2244,16 +2244,16 @@ OS-destroy-view: func [ obj: as red-object! values + FACE_OBJ_FONT if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] - + obj: as red-object! values + FACE_OBJ_PARA if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] - + ;;g_main_context_release GTKApp-Ctx - ;; DEBUG: + ;; DEBUG: - ;; TODO: This can be useless now! + ;; TODO: This can be useless now! remove-all-timers handle - + ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] free-handles as-integer handle no @@ -2280,7 +2280,7 @@ OS-update-facet: func [ case [ ; sym = facets/pane [ - ; sym: action/symbol + ; sym: action/symbol ; ;; DEBUG: print ["update pane action " get-symbol-name sym lf] ; pane: as red-block! value ; ] @@ -2327,7 +2327,7 @@ OS-to-image: func [ type: symbol/resolve word/symbol ;; DEBUG: print ["OS-to-image:" get-symbol-name type lf] - case [ + case [ type = screen [ win: gdk_get_default_root_window width: gdk_window_get_width win @@ -2347,7 +2347,7 @@ OS-to-image: func [ either gtk_window_is_active parent-window? widget [ size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE win: gtk_widget_get_window widget - if not null? win [ + if not null? win [ ;; DEBUG: print ["win: " win " size: " size/x "x" size/y lf] pixbuf: gdk_pixbuf_get_from_window win 0 0 size/x size/y ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf @@ -2358,7 +2358,7 @@ OS-to-image: func [ win: gtk_offscreen_window_new list: as GList! gtk_container_get_children widget - child: list + child: list while [not null? child][ g_object_ref child/data ; to avoid destruction before removing from container gtk_container_remove widget child/data @@ -2373,7 +2373,7 @@ OS-to-image: func [ ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf list: as GList! gtk_container_get_children win - child: list + child: list while [not null? child][ g_object_ref child/data ; to avoid destruction before removing from container gtk_container_remove win child/data diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 1e9d5ea581..42c5aff8f1 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -151,24 +151,24 @@ render-text: func [ pline: pango_layout_get_line lpc 0 pango_layout_line_get_pixel_extents pline rect lrect - ly: (pango_layout_get_line_count lpc) * lrect/height + ly: (pango_layout_get_line_count lpc) * lrect/height lx: lrect/width case [ flags and 0001h <> 0 [x: (as-float (size/x - lx)) / 2.0] ; center flags and 0002h <> 0 [x: as-float (size/x - lx)] ; right - true [x: 0.0] ; left + true [x: 0.0] ; left ] case [ flags and 0004h <> 0 [y: (as-float (size/y - ly)) / 2.0] ; middle flags and 0008h <> 0 [y: as-float (size/y - ly)] ; bottom true [y: 0.0] ; top ] - + ;; DEBUG: print [lx "x" ly " and (" x "," y ")" lf] - cairo_move_to cr x y - + cairo_move_to cr x y + pango_cairo_show_layout cr lpc cairo_stroke cr @@ -200,9 +200,9 @@ render-text: func [ ; ] ; ;cairo_move_to(cr, w/2 - extents.width/2, h/2); -; cairo_move_to cr x y +; cairo_move_to cr x y ; print [ "hi-str: <" str ">" lf] -; cairo_show_text cr str +; cairo_show_text cr str ] @@ -233,23 +233,23 @@ base-draw: func [ size: as red-pair! vals + FACE_OBJ_SIZE type: as red-word! vals + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - + if TYPE_OF(clr) = TYPE_TUPLE [ ;; DEBUG: print ["base-draw color" (clr/array1 >>> 24 and FFh) "x" (clr/array1 >> 16 and FFh ) "x" (clr/array1 >> 8 and FFh ) "x" (clr/array1 and FFh ) lf] - + ;;; OLD and DOES NOT WORK ; cairo_save cr ; set-source-color cr clr/array1 ; cairo_paint cr ;-- paint background ; cairo_restore cr ;cairo_save cr - gtk_render_background gtk_widget_get_style_context widget cr 0.0 0.0 as float! size/x as float! size/y + gtk_render_background gtk_widget_get_style_context widget cr 0.0 0.0 as float! size/x as float! size/y ;cairo_restore cr ] if TYPE_OF(img) = TYPE_IMAGE [ ;; DEBUG: print ["base-draw, GDK-draw-image: " 0 "x" 0 "x" size/x "x" size/y lf] - ;; ONLY WORK for Mandelbrot and raytracer: + ;; ONLY WORK for Mandelbrot and raytracer: ;; GDK-draw-image cr OS-image/to-argb-pixbuf img 0 0 size/x size/y GDK-draw-image cr OS-image/to-pixbuf img 0 0 size/x size/y ] @@ -264,7 +264,7 @@ base-draw: func [ ] true [] ] - + either TYPE_OF(draw) = TYPE_BLOCK [ ;; DEBUG: print ["do-draw in base-draw" lf] do-draw cr null draw no yes yes yes @@ -308,7 +308,7 @@ window-removed-event: func [ widget [handle!] count [int-ptr!] ][ - ;; DEBUG[view/no-wait]: print ["App " app " removed window " widget "exit-loop: " exit-loop " win-cnt: " win-cnt " main-window? " main-window = widget] + ;; DEBUG[view/no-wait]: print ["App " app " removed window " widget "exit-loop: " exit-loop " win-cnt: " win-cnt " main-window? " main-window = widget] unless view-no-wait? widget [count/value: count/value - 1] ;; DEBUG[view/no-wait]: print ["=> exit-loop: " count/value lf] ] @@ -325,7 +325,7 @@ window-configure-event: func [ y [integer!] ][ ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] - + ; Set the offset when window is moved offset: (as red-pair! get-face-values widget) + FACE_OBJ_OFFSET x: 0 y: 0 gtk_window_get_position widget :x :y @@ -335,17 +335,17 @@ window-configure-event: func [ sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size ; either any [event/width <> sz/x event/height <> sz/y] [ ; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ - ; evt-motion/x_new: event/width + ; evt-motion/x_new: event/width ; evt-motion/y_new: event/height ; evt-motion/x_root: as float! event/x - ; evt-motion/y_root: as float! event/y + ; evt-motion/y_root: as float! event/y ; make-event widget 0 EVT_SIZE ; ;] ; ;evt-motion/cpt: evt-motion/cpt + 1 ; yes ; ][no] if any [event/width <> sz/x event/height <> sz/y] [ - ; evt-sizing/x_new: event/width + ; evt-sizing/x_new: event/width ; evt-sizing/y_new: event/height ; sz/x: evt-sizing/x_new ; sz/y: evt-sizing/y_new @@ -367,7 +367,7 @@ window-size-allocate: func [ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size if any [rect/width <> sz/x rect/height <> sz/y] [ - evt-sizing/x_new: rect/width + evt-sizing/x_new: rect/width evt-sizing/y_new: rect/height ;; DEBUG: print ["sz: " sz/x "x" sz/y " -> " evt-sizing/x_new "x" evt-sizing/y_new lf] sz/x: evt-sizing/x_new @@ -376,7 +376,7 @@ window-size-allocate: func [ evt-sizing/x_root: as float! rect/x evt-sizing/y_root: as float! rect/y make-event widget 0 EVT_SIZING - ] + ] ] range-value-changed: func [ @@ -511,7 +511,7 @@ field-key-press-event: func [ text [c-string!] face [red-object!] qdata [handle!] -][ +][ ;; DEBUG: print ["key-press-event: " event-key/keyval lf] if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval @@ -529,7 +529,7 @@ field-key-press-event: func [ RED_VK_SHIFT RED_VK_CONTROL RED_VK_LSHIFT RED_VK_RSHIFT RED_VK_LCONTROL RED_VK_RCONTROL - RED_VK_LMENU RED_VK_RMENU + RED_VK_LMENU RED_VK_RMENU RED_VK_UNKNOWN [0] ;-- no KEY event default [res: make-event widget key or flags EVT_KEY] ;-- force a KEY event ] @@ -572,24 +572,24 @@ field-move-focus: func [ [cdecl] widget [handle!] event [handle!] - ctx [node!] + ctx [node!] ][ print-line "move-focus" ] field-button-release-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] - /local + /local x [integer!] y [integer!] sel [red-pair!] ][ ;; DEBUG: print [ "field mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - if event/button = GDK_BUTTON_PRIMARY [ + if event/button = GDK_BUTTON_PRIMARY [ x: -1 y: -1 if gtk_editable_get_selection_bounds widget :x :y [ ;; DEBUG: print ["from " x " to " y lf ] @@ -618,11 +618,11 @@ area-changed: func [ end [GtkTextIter!] ][ ; Weirdly, GtkTextIter introduced since I did not simplest solution to get the full content of a GtkTextBuffer! - start: as GtkTextIter! allocate (size? GtkTextIter!) - end: as GtkTextIter! allocate (size? GtkTextIter!) + start: as GtkTextIter! allocate (size? GtkTextIter!) + end: as GtkTextIter! allocate (size? GtkTextIter!) gtk_text_buffer_get_bounds buffer as handle! start as handle! end text: gtk_text_buffer_get_text buffer as handle! start as handle! end no - free as byte-ptr! start free as byte-ptr! end + free as byte-ptr! start free as byte-ptr! end qdata: g_object_get_qdata widget red-face-id unless null? qdata [ face: as red-object! qdata @@ -633,7 +633,7 @@ area-changed: func [ area-button-press-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -641,7 +641,7 @@ area-button-press-event: func [ flags [integer!] ][ ;; DEBUG: print [ "area -> BUTTON-PRESS: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - + menu-x: as-integer event/x menu-y: as-integer event/y ;; DEBUG: print ["menu cursor pos: " menu-x "x" menu-y lf] @@ -652,7 +652,7 @@ area-button-press-event: func [ area-button-release-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -660,16 +660,16 @@ area-button-release-event: func [ flags [integer!] buffer [handle!] start [GtkTextIter!]; value does not work - end [GtkTextIter!] + end [GtkTextIter!] x [integer!] y [integer!] sel [red-pair!] ][ ;; DEBUG: print [ "area mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] if event/button = GDK_BUTTON_PRIMARY [ - start: as GtkTextIter! allocate (size? GtkTextIter!) - end: as GtkTextIter! allocate (size? GtkTextIter!) - buffer: gtk_text_view_get_buffer widget + start: as GtkTextIter! allocate (size? GtkTextIter!) + end: as GtkTextIter! allocate (size? GtkTextIter!) + buffer: gtk_text_view_get_buffer widget if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ x: -1 y: -1 x: gtk_text_iter_get_offset as handle! start @@ -683,7 +683,7 @@ area-button-release-event: func [ ] make-event widget 0 EVT_SELECT ] - free as byte-ptr! start free as byte-ptr! end + free as byte-ptr! start free as byte-ptr! end ] 0 ] @@ -696,7 +696,7 @@ area-populate-popup: func [ /local menu [red-block!] ][ - ;; DEBUG: print ["populate menu for " widget " and menu " hMenu lf] + ;; DEBUG: print ["populate menu for " widget " and menu " hMenu lf] menu: as red-block! get-node-facet ctx FACE_OBJ_MENU append-context-menu menu hMenu widget ] @@ -719,11 +719,11 @@ red-timer-action: func [ ; remove-widget-timer self ; no ; this removes the timer ; ] -] +] widget-enter-notify-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventCrossing!] ctx [node!] return: [integer!] @@ -739,7 +739,7 @@ widget-enter-notify-event: func [ widget-leave-notify-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventCrossing!] ctx [node!] return: [integer!] @@ -754,7 +754,7 @@ widget-leave-notify-event: func [ drag-widget-motion-notify-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventMotion!] ctx [node!] return: [integer!] @@ -772,7 +772,7 @@ drag-widget-motion-notify-event: func [ if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ x: event/x_root - evt-motion/x_root y: event/y_root - evt-motion/y_root - evt-motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] + evt-motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] evt-motion/y_new: as-integer y + either y > 0.0 [0.5][-0.5] ;; DEBUG: print ["new " evt-motion/x_new "x" evt-motion/y_new lf] evt-motion/x_root: event/x_root @@ -788,7 +788,7 @@ drag-widget-motion-notify-event: func [ drag-widget-button-press-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -815,7 +815,7 @@ drag-widget-button-press-event: func [ drag-widget-button-release-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -830,10 +830,10 @@ drag-widget-button-release-event: func [ ; Special treatment for check and radio buttons (TODO: button) type: as red-word! get-node-facet ctx FACE_OBJ_TYPE sym: symbol/resolve type/symbol - + if all [ any [sym = check sym = radio] - evt-motion/cpt = 0 ; IMPORTANT: change state only if no dragging! + evt-motion/cpt = 0 ; IMPORTANT: change state only if no dragging! ][ state: gtk_toggle_button_get_active widget gtk_toggle_button_set_active widget either sym = check [not state][yes] @@ -859,7 +859,7 @@ container-emit-event: func [ x: as-integer evt/x y: as-integer evt/y rect: as tagRECT allocate (size? tagRECT) gtk_widget_get_allocation widget as handle! rect - + ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit event " widget lf]] if all[x >= rect/x x <= (rect/x + rect/width) y >= rect/y y <= (rect/y + rect/height)][ ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit2 event " widget " event " evt/x "x" evt/y lf "widget size " rect/x "x" rect/y "x" rect/width "x" rect/height lf]] @@ -870,7 +870,7 @@ container-emit-event: func [ container-delegate-to-children: func [ [cdecl] - widget [handle!] + widget [handle!] event [int-ptr!] ctx [node!] return: [integer!] @@ -882,7 +882,7 @@ container-delegate-to-children: func [ mouse-button-press-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -893,9 +893,9 @@ mouse-button-press-event: func [ ;; DEBUG: print [ "mouse -> BUTTON-PRESS: " widget " (" ") x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] ; evt-motion/state: yes ; evt-motion/cpt: 0 - + if gtk_widget_get_focus_on_click widget [ - ;; DEBUG: print ["grab focus on mouse " widget lf] + ;; DEBUG: print ["grab focus on mouse " widget lf] gtk_widget_grab_focus widget ] if draggable? widget [return 0] ; delegate to drag @@ -926,7 +926,7 @@ mouse-button-press-event: func [ mouse-button-release-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventButton!] ctx [node!] return: [integer!] @@ -941,14 +941,14 @@ mouse-button-release-event: func [ evt-motion/y_root: event/y_root evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y - flags: check-flags event/type event/state + flags: check-flags event/type event/state make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] true [EVT_LEFT_UP]] ;;0 ;;no ] mouse-motion-notify-event: func [ [cdecl] - widget [handle!] + widget [handle!] event [GdkEventMotion!] ctx [node!] return: [integer!] @@ -969,9 +969,9 @@ mouse-motion-notify-event: func [ wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS if wflags and FACET_FLAGS_ALL_OVER <> 0 [ flags: check-flags event/type event/state - make-event widget flags EVT_OVER + make-event widget flags EVT_OVER ] - ;; DEBUG: print ["mouse-motion-notify-event: down? " (event/state and GDK_BUTTON1_MASK <> 0) " " (flags and EVT_FLAG_DOWN <> 0) lf] + ;; DEBUG: print ["mouse-motion-notify-event: down? " (event/state and GDK_BUTTON1_MASK <> 0) " " (flags and EVT_FLAG_DOWN <> 0) lf] EVT_DISPATCH ;;no ] @@ -1056,7 +1056,7 @@ widget-scroll-event: func [ ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] state: 0 g_object_set_qdata widget red-event-id as handle! event - if any[event/delta_y < -0.01 event/delta_y > 0.01][ + if any[event/delta_y < -0.01 event/delta_y > 0.01][ state: make-event widget check-down-flags event/state EVT_WHEEL ] state diff --git a/modules/view/backends/gtk3/menu.reds b/modules/view/backends/gtk3/menu.reds index bb61659877..0094d2d275 100644 --- a/modules/view/backends/gtk3/menu.reds +++ b/modules/view/backends/gtk3/menu.reds @@ -45,7 +45,7 @@ build-menu: func [ key [c-string!] action [integer!] ][ - if TYPE_OF(menu) <> TYPE_BLOCK [return null] + if TYPE_OF(menu) <> TYPE_BLOCK [return null] ;; DEBUG: print ["Menu: " hMenu " with target: " target lf] value: block/rs-head menu @@ -61,10 +61,10 @@ build-menu: func [ len: -1 title: unicode/to-utf8 str :len - + item: gtk_menu_item_new_with_label title gtk_widget_show item - + if next < tail [ switch TYPE_OF(next) [ TYPE_BLOCK [ @@ -140,7 +140,7 @@ append-context-menu: func [ item: gtk_separator_menu_item_new gtk_widget_show item gtk_menu_shell_append hMenu item - build-menu menu hMenu widget + build-menu menu hMenu widget ] menu-bar?: func [ diff --git a/modules/view/backends/gtk3/para.reds b/modules/view/backends/gtk3/para.reds index 33f7bc2e68..dc5d1bef8d 100644 --- a/modules/view/backends/gtk3/para.reds +++ b/modules/view/backends/gtk3/para.reds @@ -22,7 +22,7 @@ change-para: func [ where [integer!] lay [handle!] ][ - + if TYPE_OF(para) <> TYPE_OBJECT [return no] flags: get-para-flags type para ;; DEBUG: if flags <> 0 [print ["change-para " widget " " get-symbol-name type " flags: " flags lf]] @@ -90,9 +90,9 @@ update-para: func [ ;; COMMENTED SINCE UNUSED! ; sym: symbol/resolve type/symbol ; para: as red-object! values + FACE_OBJ_PARA - + unless TYPE_OF(type) = TYPE_WORD [exit] ;@@ make it an error message - + ;; COMMENTED SINCE UNUSED! ; case [ ; sym = base [mask: not 002Fh] @@ -112,7 +112,7 @@ update-para: func [ ; ] ; true [0] ; ] - + state: as red-block! values + FACE_OBJ_STATE if TYPE_OF(state) = TYPE_BLOCK [ int: as red-integer! (block/rs-head state) + 1 @@ -149,17 +149,17 @@ get-para-flags: func [ align: as red-word! values + PARA_OBJ_V-ALIGN v-sym: symbol/resolve align/symbol bool: as red-logic! values + PARA_OBJ_WRAP? - + wrap?: any [ TYPE_OF(bool) = TYPE_NONE all [TYPE_OF(bool) = TYPE_LOGIC bool/value] ] - - left: 0 center: 0 right: 0 h-def: 0 + + left: 0 center: 0 right: 0 h-def: 0 top: 0 middle: 0 bottom: 0 v-def: 0 - + flags: 0 - + case [ any [ type = base @@ -172,7 +172,7 @@ get-para-flags: func [ middle: 0004h ;-- DT_VCENTER bottom: 0008h ;-- DT_BOTTOM h-def: center v-def: top - + unless wrap? [flags: 0010h] ;-- DT_SINGLELINE ] any [ @@ -186,7 +186,7 @@ get-para-flags: func [ top: 00000400h ;-- BS_TOP middle: 00000C00h ;-- BS_VCENTER bottom: 00000800h ;-- BS_BOTTOM - + h-def: either type = button [center][left] ] any [ @@ -197,9 +197,9 @@ get-para-flags: func [ left: 0000h ;-- ES_LEFT / SS_LEFT right: 0001h ;-- ES_RIGHT / SS_RIGHT center: 0002h ;-- ES_CENTER / SS_CENTER - + h-def: left - + if all[wrap? type <> field][ flags: 00010000h ;-- SS_ENDELLIPSIS ] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 71bf6dfdc5..aef104375d 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -30,9 +30,9 @@ pango-opt-tag!: alias struct! [ ] pango-compare-tag: func [ - [cdecl] - tag1 [pango-opt-tag!] - tag2 [pango-opt-tag!] + [cdecl] + tag1 [pango-opt-tag!] + tag2 [pango-opt-tag!] return: [integer!] /local comp [integer!] @@ -267,13 +267,13 @@ pango-process-closed-tags: func [ tmp [c-string!] pos-current-closed-tag [integer!] pos-last-closed-tag [integer!] -][ +][ pos-last-closed-tag: pango-last-closed-tag? lc pos-current-closed-tag: pos + len ;; DEBUG: print ["process closed tags: current=" pos-current-closed-tag " last=" pos-last-closed-tag lf] ; Close tags with text first if any if all[ - pos-last-closed-tag <> -1 + pos-last-closed-tag <> -1 pos-current-closed-tag > pos-last-closed-tag ][ pango-close-tags lc pos-last-closed-tag @@ -317,7 +317,7 @@ layout-ctx-do: func [ tag: as pango-opt-tag! gl/data ;; DEBUG: print [" at (" tag/pos "," tag/len ")" lf] pango-process-tag lc tag/opt tag/pos tag/len - + gl: gl/next null? gl ] @@ -350,9 +350,9 @@ int-to-bgra-hex: func [ g [integer!] a [integer!] ][ - a: (color >> 24 and FFh) - r: (color >> 16 and FFh) - g: (color >> 8 and FFh) + a: (color >> 24 and FFh) + r: (color >> 16 and FFh) + g: (color >> 8 and FFh) b: (color and FFh) color: (b << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( r << 8 and FF00h) or ( a and FFh) ;; DEBUG: print ["col(#" string/to-hex color no ")" lf] @@ -374,7 +374,7 @@ OS-text-box-color: func [ rgba: int-to-bgra-hex color ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] - + ot: pango-open-tag-string? "color" rgba pango-insert-tag lc ot pos len ] @@ -391,10 +391,10 @@ OS-text-box-background: func [ ot [c-string!] ][ lc: as layout-ctx! layout - + rgba: int-to-bgra-hex color ;; DEBUG: print ["bgcol(" rgba ")[" pos "," pos + len - 1 "]" lf] - + ot: pango-open-tag-string? "bgcolor" rgba pango-insert-tag lc ot pos len @@ -458,7 +458,7 @@ OS-text-box-strikeout: func [ ot [c-string!] ][ lc: as layout-ctx! layout - + ot: pango-open-tag-string? "strikethrough" "true" pango-insert-tag lc ot pos len ] @@ -541,13 +541,13 @@ OS-text-box-metrics: func [ if null? layout [return as red-value! none-value] as red-value! switch type [ TBOX_METRICS_OFFSET? - TBOX_METRICS_OFFSET_LOWER [ ; caret-to-offset + TBOX_METRICS_OFFSET_LOWER [ ; caret-to-offset int: as red-integer! arg0 pango_layout_index_to_pos layout int/value - 1 :rect - ;; DEBUG: print ["TBOX_METRICS_OFFSET? " rect/x / PANGO_SCALE "x" rect/y / PANGO_SCALE "x" rect/width / PANGO_SCALE "x" rect/height / PANGO_SCALE lf] + ;; DEBUG: print ["TBOX_METRICS_OFFSET? " rect/x / PANGO_SCALE "x" rect/y / PANGO_SCALE "x" rect/width / PANGO_SCALE "x" rect/height / PANGO_SCALE lf] pair/push rect/x / PANGO_SCALE rect/y / PANGO_SCALE ] - TBOX_METRICS_INDEX? + TBOX_METRICS_INDEX? TBOX_METRICS_CHAR_INDEX? [ ; offset-to-caret pos: as red-pair! arg0 idx: -1 trail: -1 @@ -563,7 +563,7 @@ OS-text-box-metrics: func [ width: -1 height: -1 ;pango_layout_get_pixel_size layout :width :height ; width: (pango_layout_get_width layout) / PANGO_SCALE - height: (pango_layout_get_line_count layout) * lrect/height + height: (pango_layout_get_line_count layout) * lrect/height width: lrect/width ;; DEBUG: print ["TBOX_METRICS_SIZE: " width "x" height " " pango_layout_get_line_count layout lf] ;print ["text: " layout/text lf] @@ -618,7 +618,7 @@ OS-text-box-layout: func [ str [c-string!] pc [handle!] ft-ok? [logic!] -][ +][ ;; DEBUG: print ["OS-text-box-layout: " box " " face-handle? box " target: " target lf] values: object/get-values box state: as red-block! values + FACE_OBJ_EXT3 @@ -636,7 +636,7 @@ OS-text-box-layout: func [ text: as red-string! values + FACE_OBJ_TEXT font: as red-object! values + FACE_OBJ_FONT ft-ok?: TYPE_OF(font) = TYPE_OBJECT ;all[not null? target TYPE_OF(font) = TYPE_OBJECT] - hFont: default-font + hFont: default-font if ft-ok? [ hFont: get-font-handle font 0 if null? hFont [hFont: default-font] @@ -644,7 +644,7 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len - + layout-ctx-init lc str length? str ;; DEBUG: print ["OS-text-box-layout lc/text: " lc/text " " lc/text-len lf] @@ -661,7 +661,7 @@ OS-text-box-layout: func [ if null? pango-context [pango-context: gdk_pango_context_get] lc/layout: pango_layout_new pango-context ;; DEBUG: print ["rich-text layout: " lc/layout " " pango_font_description_get_family hFont " " pango_font_description_get_size hFont lf] - pango_layout_set_font_description lc/layout hFont + pango_layout_set_font_description lc/layout hFont ] ][ dc: as draw-ctx! target From 1d69275bd2a8582c9cdd1943e16ebaffbb846aa6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 11:27:53 +0800 Subject: [PATCH 0145/3432] FIX: some indent improvements --- modules/view/backends/gtk3/events.reds | 3 +- modules/view/backends/gtk3/gui.reds | 623 ++++++++++++------------- modules/view/backends/platform.red | 1 + 3 files changed, 312 insertions(+), 315 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 5195f77806..5e31d7b01f 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -646,7 +646,8 @@ respond-mouse-add: func [ if respond-event? actors "on-alt-up" [on-type: on-type or ON_RIGHT_UP] if respond-event? actors "on-aux-down" [on-type: on-type or ON_AUX_DOWN] if respond-event? actors "on-aux-up" [on-type: on-type or ON_AUX_UP] - if respond-event? actors "on-click" [on-type: on-type or ON_CLICK] if respond-event? actors "on-dbl-click" [on-type: on-type or ON_DBL_CLICK] + if respond-event? actors "on-click" [on-type: on-type or ON_CLICK] + if respond-event? actors "on-dbl-click" [on-type: on-type or ON_DBL_CLICK] if respond-event? actors "on-wheel" [on-type: on-type or ON_WHEEL] if respond-event? actors "on-over" [on-type: on-type or ON_OVER] if all[on-type > 0 not null? widget][ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f7c7034e2b..b9284aed2d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -54,9 +54,6 @@ tabs: context [ cur: 0 ] -; to put in other place (usually platform.red) if useful -_drag-on: symbol/make "drag-on" - settings: as handle! 0 pango-context: as handle! 0 gtk-font: "Sans 13" @@ -67,9 +64,6 @@ default-font: as handle! 0 main-window: as handle! 0 last-window: as handle! 0 -; Temporary, will be removed... -last-widget: as handle! 0 - log-pixels-x: 0 log-pixels-y: 0 screen-size-x: 0 @@ -77,8 +71,8 @@ screen-size-y: 0 get-face-obj: func [ - handle [handle!] - return: [red-object!] + handle [handle!] + return: [red-object!] /local face [red-object!] qdata [handle!] @@ -94,8 +88,8 @@ get-face-obj: func [ ] get-face-values: func [ - handle [handle!] - return: [red-value!] + handle [handle!] + return: [red-value!] /local face [red-object!] qdata [handle!] @@ -113,11 +107,11 @@ get-face-values: func [ ] get-node-values: func [ - node [node!] - return: [red-value!] + node [node!] + return: [red-value!] /local - ctx [red-context!] - s [series!] + ctx [red-context!] + s [series!] ][ ctx: TO_CTX(node) s: as series! ctx/values/value @@ -125,12 +119,12 @@ get-node-values: func [ ] get-node-facet: func [ - node [node!] - facet [integer!] - return: [red-value!] + node [node!] + facet [integer!] + return: [red-value!] /local - ctx [red-context!] - s [series!] + ctx [red-context!] + s [series!] ][ ctx: TO_CTX(node) s: as series! ctx/values/value @@ -138,18 +132,18 @@ get-node-facet: func [ ] get-face-flags: func [ - face [handle!] - return: [integer!] + face [handle!] + return: [integer!] ][ 0 ] face-handle?: func [ - face [red-object!] - return: [handle!] ;-- returns NULL is no handle + face [red-object!] + return: [handle!] ;-- returns NULL is no handle /local - state [red-block!] - int [red-integer!] + state [red-block!] + int [red-integer!] ][ state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE if TYPE_OF(state) = TYPE_BLOCK [ @@ -160,10 +154,10 @@ face-handle?: func [ ] get-widget-symbol: func [ - widget [handle!] - return: [integer!] - /local - type [red-word!] + widget [handle!] + return: [integer!] + /local + type [red-word!] values [red-value!] ][ values: get-face-values widget @@ -174,28 +168,28 @@ get-widget-symbol: func [ ] get-widget-data: func [ - widget [handle!] - return: [red-block!] + widget [handle!] + return: [red-block!] /local values [red-value!] ][ values: get-face-values widget - as red-block! values + FACE_OBJ_DATA + as red-block! values + FACE_OBJ_DATA ] ;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget set-_widget: func [ - widget [handle!] - _widget [handle!] + widget [handle!] + _widget [handle!] ][ g_object_set_qdata widget _widget-id _widget ] _widget?: func [ widget [handle!] - return: [handle!] + return: [handle!] /local - _widget [handle!] + _widget [handle!] ][ _widget: g_object_get_qdata widget _widget-id if null? _widget [_widget: widget] @@ -203,31 +197,31 @@ _widget?: func [ ] set-parent-window: func [ - widget [handle!] - window [handle!] + widget [handle!] + window [handle!] ][ g_object_set_qdata widget parent-window-id window ] parent-window?: func [ widget [handle!] - return: [handle!] + return: [handle!] ][ g_object_get_qdata widget parent-window-id ] set-cursor: func [ - widget [handle!] - cursor [handle!] + widget [handle!] + cursor [handle!] ][ g_object_set_qdata widget cursor-id cursor ] cursor?: func [ widget [handle!] - return: [handle!] + return: [handle!] /local - window [handle!] + window [handle!] ][ g_object_get_qdata widget cursor-id ] @@ -235,16 +229,16 @@ cursor?: func [ ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) set-real-widget: func [ _widget [handle!] - widget [handle!] + widget [handle!] ][ g_object_set_qdata _widget real-widget-id widget ] real-widget?: func [ _widget [handle!] - return: [handle!] + return: [handle!] /local - widget [handle!] + widget [handle!] ][ widget: g_object_get_qdata _widget real-widget-id if null? widget [widget: _widget] @@ -260,28 +254,28 @@ set-container: func [ container?: func [ widget [handle!] - return: [handle!] + return: [handle!] ][ g_object_get_qdata widget gtk-container-id ] real-container?: func [ widget [handle!] - return: [handle!] + return: [handle!] ][ g_object_get_qdata widget real-container-id ] gtk-layout?: func [ - type [integer!] - return: [logic!] + type [integer!] + return: [logic!] ][ any[type = rich-text type = panel type = base] ] container-type?: func [ - type [integer!] - return: [logic!] + type [integer!] + return: [logic!] ][ ;;; See events.reds to see the comment above ; Option I: any[type = rich-text type = panel type = base] @@ -290,22 +284,22 @@ container-type?: func [ ] set-draggable: func [ - item [handle!] - key [logic!] + item [handle!] + key [logic!] ][ g_object_set_qdata item drag-id as int-ptr! either key [1][0] ] draggable?: func [ item [handle!] - return: [logic!] + return: [logic!] ][ 1 = as integer! g_object_get_qdata item drag-id ] set-view-no-wait: func [ - window [handle!] - key [logic!] + window [handle!] + key [logic!] ][ ; usually a view/no-wait call at most twice do-events and at least one do-events with no-wait? = true ;; DEBUG[view/no-wait]: print ["view-no-wait? window " window " => " key lf] @@ -314,28 +308,28 @@ set-view-no-wait: func [ view-no-wait?: func [ window [handle!] - return: [logic!] + return: [logic!] ][ all[1 = as integer! g_object_get_qdata window no-wait-id window <> main-window] ] get-child-from-xy: func [ - parent [handle!] - x [integer!] - y [integer!] - return: [integer!] + parent [handle!] + x [integer!] + y [integer!] + return: [integer!] /local - widget [handle!] + widget [handle!] ][ 0 ] get-text-size: func [ - face [red-object!] - str [red-string!] - hFont [handle!] - pair [red-pair!] - return: [tagSIZE] + face [red-object!] + str [red-string!] + hFont [handle!] + pair [red-pair!] + return: [tagSIZE] /local text [c-string!] len [integer!] @@ -344,7 +338,7 @@ get-text-size: func [ pl [handle!] size [tagSIZE] df [c-string!] - pc [handle!] + pc [handle!] widget [handle!] ][ if null? pango-context [pango-context: gdk_pango_context_get] @@ -390,11 +384,11 @@ get-text-size: func [ ] to-bgr: func [ - node [node!] - pos [integer!] - return: [integer!] ;-- 00bbggrr format or -1 if not found + node [node!] + pos [integer!] + return: [integer!] ;-- 00bbggrr format or -1 if not found /local - color [red-tuple!] + color [red-tuple!] ][ color: as red-tuple! get-node-facet node pos either TYPE_OF(color) = TYPE_TUPLE [ @@ -405,18 +399,18 @@ to-bgr: func [ ] free-handles: func [ - widget [integer!] - force? [logic!] + widget [integer!] + force? [logic!] /local - values [red-value!] - type [red-word!] - face [red-object!] - tail [red-object!] - pane [red-block!] - state [red-value!] - rate [red-value!] - sym [integer!] - handle [handle!] + values [red-value!] + type [red-word!] + face [red-object!] + tail [red-object!] + pane [red-block!] + state [red-value!] + rate [red-value!] + sym [integer!] + handle [handle!] ][ values: get-face-values as handle! widget type: as red-word! values + FACE_OBJ_TYPE @@ -452,27 +446,27 @@ free-handles: func [ ; Debug function to show children tree debug-show-children: func [ - widget [handle!] - parent? [logic!] + widget [handle!] + parent? [logic!] /local widget_ [handle!] child [handle!] container [handle!] - rect [tagRECT] + rect [tagRECT] sx [integer!] sy [integer!] offset [red-pair!] size [red-pair!] - pane [red-block!] + pane [red-block!] type [red-word!] sym [integer!] - face [red-object!] - tail [red-object!] + face [red-object!] + tail [red-object!] values [red-value!] overlap? [logic!] ; these ones would be removed debug [logic!] - cpt [integer!] + cpt [integer!] ][ ; to remove when satisfactory enough development debug: yes @@ -572,8 +566,8 @@ init: func [][ ] get-symbol-name: function [ - sym [integer!] - return: [c-string!] + sym [integer!] + return: [c-string!] ][ case [ sym = check ["check"] @@ -612,12 +606,12 @@ get-symbol-name: function [ ] ; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane adjust-sizes: func [ - widget [handle!] + widget [handle!] /local widget_ [handle!] child [handle!] container [handle!] - rect [tagRECT] + rect [tagRECT] dx [integer!] dy [integer!] ox [integer!] @@ -626,16 +620,16 @@ adjust-sizes: func [ sy [integer!] offset [red-pair!] size [red-pair!] - pane [red-block!] + pane [red-block!] type [red-word!] sym [integer!] - face [red-object!] - tail [red-object!] + face [red-object!] + tail [red-object!] values [red-value!] overlap? [logic!] ; these ones would be removed debug [logic!] - cpt [integer!] + cpt [integer!] ][ ; to remove when satisfactory enough development debug: no @@ -694,7 +688,7 @@ adjust-sizes: func [ ] remove-widget-timer: func [ - widget [handle!] + widget [handle!] /local timer [integer!] data [handle!] @@ -712,8 +706,8 @@ remove-widget-timer: func [ ] add-widget-timer: func [ - widget [handle!] - ts [integer!] + widget [handle!] + ts [integer!] /local timer [integer!] data [handle!] @@ -724,23 +718,23 @@ add-widget-timer: func [ ] get-widget-timer: func [ - widget [handle!] - return: [int-ptr!] + widget [handle!] + return: [int-ptr!] ][ either null? widget [as int-ptr! 0][g_object_get_qdata widget red-timer-id] ] remove-all-timers: func [ - widget [handle!] + widget [handle!] /local - widget_ [handle!] - pane [red-block!] - type [red-word!] - sym [integer!] - face [red-object!] - tail [red-object!] - values [red-value!] - rate [red-value!] + widget_ [handle!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] + rate [red-value!] ][ remove-widget-timer widget values: get-face-values widget @@ -765,8 +759,8 @@ remove-all-timers: func [ ] change-rate: func [ - widget [handle!] - rate [red-value!] + widget [handle!] + rate [red-value!] /local int [red-integer!] tm [red-time!] @@ -801,11 +795,11 @@ change-rate: func [ ] change-image: func [ - widget [handle!] - image [red-image!] - type [integer!] + widget [handle!] + image [red-image!] + type [integer!] /local - img [handle!] + img [handle!] ][ ;; DEBUG: print ["change-image " widget " type: " get-symbol-name type lf] case [ @@ -825,14 +819,14 @@ change-image: func [ ] change-color: func [ - widget [handle!] - color [red-tuple!] - type [integer!] + widget [handle!] + color [red-tuple!] + type [integer!] /local - clr [integer!] - t [integer!] - face [red-object!] - font [red-object!] + clr [integer!] + t [integer!] + face [red-object!] + font [red-object!] ][ ;; DEBUG: print ["change-color " widget " " get-symbol-name type lf] t: TYPE_OF(color) @@ -861,19 +855,20 @@ change-color: func [ ] change-pane: func [ - parent [handle!] - pane [red-block!] - type [integer!] + parent [handle!] + pane [red-block!] + type [integer!] /local face [red-object!] - tail [red-object!] - widget [handle!] - _widget [handle!] - nb [integer!] - s [series!] + tail [red-object!] + widget [handle!] + _widget [handle!] + nb [integer!] + s [series!] values [red-value!] - offset [red-pair!] - list [GList!] child [GList!] + offset [red-pair!] + list [GList!] + child [GList!] ][ ;; DEBUG: print ["change-pane " get-symbol-name type lf] @@ -927,11 +922,11 @@ change-pane: func [ ] change-font: func [ - widget [handle!] - face [red-object!] - font [red-object!] - type [integer!] - return: [logic!] + widget [handle!] + face [red-object!] + font [red-object!] + type [integer!] + return: [logic!] /local ; css [c-string!] ; provider [handle!] @@ -957,11 +952,11 @@ change-font: func [ ] change-offset: func [ - widget [handle!] - pos [red-pair!] - type [integer!] + widget [handle!] + pos [red-pair!] + type [integer!] /local - container [handle!] + container [handle!] _widget [handle!] ][ ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol widget " " widget " " pos/x "x" pos/y lf] @@ -986,9 +981,9 @@ change-offset: func [ ] change-size: func [ - widget [handle!] - size [red-pair!] - type [integer!] + widget [handle!] + size [red-pair!] + type [integer!] /local _widget [handle!] ][ @@ -1010,18 +1005,18 @@ change-size: func [ ] init-all-children: func [ - widget [handle!] + widget [handle!] /local - child [handle!] - pane [red-block!] - type [red-word!] - sym [integer!] - face [red-object!] - tail [red-object!] - values [red-value!] - show? [red-logic!] - cursor [handle!] - win [handle!] + child [handle!] + pane [red-block!] + type [red-word!] + sym [integer!] + face [red-object!] + tail [red-object!] + values [red-value!] + show? [red-logic!] + cursor [handle!] + win [handle!] ][ values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE @@ -1057,9 +1052,9 @@ init-all-children: func [ ] change-visible: func [ - widget [handle!] - show? [logic!] - type [integer!] + widget [handle!] + show? [logic!] + type [integer!] ][ case [ type = window [ @@ -1080,25 +1075,25 @@ change-visible: func [ ] change-enabled: func [ - widget [handle!] - enabled? [logic!] - type [integer!] + widget [handle!] + enabled? [logic!] + type [integer!] /local - obj [integer!] + obj [integer!] ][ gtk_widget_set_sensitive widget enabled? ] change-text: func [ - widget [handle!] - values [red-value!] - face [red-object!] - type [integer!] + widget [handle!] + values [red-value!] + face [red-object!] + type [integer!] /local - len [integer!] - cstr [c-string!] - str [red-string!] - buffer [handle!] + len [integer!] + cstr [c-string!] + str [red-string!] + buffer [handle!] ][ ;; DEBUG: print ["change-text: " get-symbol-name type lf] @@ -1145,15 +1140,15 @@ change-text: func [ ] change-data: func [ - widget [handle!] - values [red-value!] + widget [handle!] + values [red-value!] /local - data [red-value!] - word [red-word!] + data [red-value!] + word [red-word!] size [red-pair!] f [red-float!] str [red-string!] - caption [c-string!] + caption [c-string!] type [integer!] len [integer!] ][ @@ -1207,14 +1202,14 @@ change-data: func [ ] change-selection: func [ - widget [handle!] - int [red-integer!] ;-- can be also none! | object! - type [integer!] + widget [handle!] + int [red-integer!] ;-- can be also none! | object! + type [integer!] /local idx [integer!] sz [integer!] - wnd [integer!] - item [handle!] + wnd [integer!] + item [handle!] sel [red-pair!] ins [GtkTextIter!] bound [GtkTextIter!] @@ -1289,8 +1284,8 @@ set-hint-text: func [ /local text [red-string!] cell [integer!] - len [integer!] - str [c-string!] + len [integer!] + str [c-string!] ][ if TYPE_OF(options) <> TYPE_BLOCK [exit] text: as red-string! block/select-word options word/load "hint" no @@ -1302,11 +1297,11 @@ set-hint-text: func [ ] set-selected-focus: func [ - widget [handle!] + widget [handle!] /local - face [red-object!] - values [red-value!] - handle [handle!] + face [red-object!] + values [red-value!] + handle [handle!] ][ values: get-face-values widget if values <> null [ @@ -1319,11 +1314,11 @@ set-selected-focus: func [ ] set-logic-state: func [ - widget [handle!] - state [red-logic!] - check? [logic!] + widget [handle!] + state [red-logic!] + check? [logic!] /local - value [integer!] + value [integer!] ][ value: either TYPE_OF(state) <> TYPE_LOGIC [ state/header: TYPE_LOGIC @@ -1337,13 +1332,13 @@ set-logic-state: func [ ] get-flags: func [ - field [red-block!] - return: [integer!] ;-- return a bit-array of all flags + field [red-block!] + return: [integer!] ;-- return a bit-array of all flags /local - word [red-word!] - len [integer!] - sym [integer!] - flags [integer!] + word [red-word!] + len [integer!] + sym [integer!] + flags [integer!] ][ switch TYPE_OF(field) [ TYPE_BLOCK [ @@ -1383,11 +1378,11 @@ get-flags: func [ ] get-position-value: func [ - pos [red-float!] - maximun [integer!] - return: [integer!] + pos [red-float!] + maximun [integer!] + return: [integer!] /local - f [float!] + f [float!] ][ f: 0.0 if any [ @@ -1400,10 +1395,10 @@ get-position-value: func [ ] get-fraction-value: func [ - pos [red-float!] - return: [float!] + pos [red-float!] + return: [float!] /local - f [float!] + f [float!] ][ f: 0.0 if any [ @@ -1416,17 +1411,17 @@ get-fraction-value: func [ ] get-screen-size: func [ - id [integer!] ;@@ Not used yet - return: [red-pair!] + id [integer!] ;@@ Not used yet + return: [red-pair!] ][ pair/push screen-size-x screen-size-y ] store-face-to-obj: func [ - obj [handle!] - face [red-object!] + obj [handle!] + face [red-object!] /local - storage [red-value!] + storage [red-value!] ][ storage: as red-value! allocate 16 ;@@ should delete it when destory widget copy-cell as cell! face storage @@ -1439,11 +1434,11 @@ init-combo-box: func [ caption [c-string!] drop-list? [logic!] ;to remove if unused /local - str [red-string!] - tail [red-string!] - len [integer!] - val [c-string!] - size [integer!] + str [red-string!] + tail [red-string!] + len [integer!] + val [c-string!] + size [integer!] ][ if any [ TYPE_OF(data) = TYPE_BLOCK @@ -1492,8 +1487,8 @@ remove-entry: func [ ] init-text-list: func [ - widget [handle!] - data [red-block!] + widget [handle!] + data [red-block!] /local str [red-string!] tail [red-string!] @@ -1530,8 +1525,8 @@ init-text-list: func [ ] update-scroller: func [ - scroller [red-object!] - flag [integer!] + scroller [red-object!] + flag [integer!] /local parent [red-object!] vertical? [red-logic!] @@ -1582,11 +1577,11 @@ update-scroller: func [ update-rich-text: func [ - state [red-block!] - handles [red-block!] - return: [logic!] + state [red-block!] + handles [red-block!] + return: [logic!] /local - redraw [red-logic!] + redraw [red-logic!] ][ if TYPE_OF(handles) = TYPE_BLOCK [ redraw: as red-logic! (block/rs-tail handles) - 1 @@ -1596,10 +1591,10 @@ update-rich-text: func [ ] parse-common-opts: func [ - widget [handle!] - face [red-object!] - options [red-block!] - type [integer!] + widget [handle!] + face [red-object!] + options [red-block!] + type [integer!] /local word [red-word!] w [red-word!] @@ -1610,8 +1605,8 @@ parse-common-opts: func [ cur [c-string!] hcur [handle!] pixbuf [handle!] - display [handle!] - win [handle!] + display [handle!] + win [handle!] x [integer!] y [integer!] ;;;btn? [logic!] @@ -1688,7 +1683,7 @@ parse-common-opts: func [ ] OS-redraw: func [ - widget [integer!] + widget [integer!] ][ ;; DEBUG: print ["OS-redraw" lf] unless null? as handle! widget [gtk_widget_queue_draw as handle! widget] @@ -1702,13 +1697,13 @@ OS-refresh-window: func [widget [integer!]][ ] OS-show-window: func [ - widget [integer!] + widget [integer!] /local - face [red-object!] - event [GdkEventConfigure!] - type [integer!] + face [red-object!] + event [GdkEventConfigure!] + type [integer!] size [red-pair!] - hWnd [handle!] + hWnd [handle!] ][ hWnd: as handle! widget unless null? hWnd [ @@ -1724,43 +1719,43 @@ OS-show-window: func [ ] OS-make-view: func [ - face [red-object!] - parent [integer!] - return: [integer!] + face [red-object!] + parent [integer!] + return: [integer!] /local - values [red-value!] - type [red-word!] - str [red-string!] - tail [red-string!] - offset [red-pair!] - size [red-pair!] - data [red-block!] - int [red-integer!] - img [red-image!] - menu [red-block!] - show? [red-logic!] - enabled? [red-logic!] - selected [red-integer!] - font [red-object!] - para [red-object!] - flags [integer!] - bits [integer!] - rate [red-value!] - sym [integer!] - p-sym [integer!] - caption [c-string!] - len [integer!] - widget [handle!] - _widget [handle!] - winbox [handle!] - buffer [handle!] - container [handle!] - hMenu [handle!] - value [integer!] - fvalue [float!] - vertical? [logic!] - rfvalue [red-float!] - actors [red-object!] + values [red-value!] + type [red-word!] + str [red-string!] + tail [red-string!] + offset [red-pair!] + size [red-pair!] + data [red-block!] + int [red-integer!] + img [red-image!] + menu [red-block!] + show? [red-logic!] + enabled? [red-logic!] + selected [red-integer!] + font [red-object!] + para [red-object!] + flags [integer!] + bits [integer!] + rate [red-value!] + sym [integer!] + p-sym [integer!] + caption [c-string!] + len [integer!] + widget [handle!] + _widget [handle!] + winbox [handle!] + buffer [handle!] + container [handle!] + hMenu [handle!] + value [integer!] + fvalue [float!] + vertical? [logic!] + rfvalue [red-float!] + actors [red-object!] ][ stack/mark-native words/_body @@ -2071,7 +2066,7 @@ OS-make-view: func [ ] OS-update-view: func [ - face [red-object!] + face [red-object!] /local ctx [red-context!] values [red-value!] @@ -2196,13 +2191,13 @@ OS-update-view: func [ ] unlink-sub-obj: func [ - face [red-object!] - obj [red-object!] - field [integer!] + face [red-object!] + obj [red-object!] + field [integer!] /local - values [red-value!] - parent [red-block!] - res [red-value!] + values [red-value!] + parent [red-block!] + res [red-value!] ][ values: object/get-values obj parent: as red-block! values + field @@ -2220,13 +2215,13 @@ unlink-sub-obj: func [ ] OS-destroy-view: func [ - face [red-object!] - empty? [logic!] + face [red-object!] + empty? [logic!] /local - handle [handle!] - values [red-value!] - obj [red-object!] - flags [integer!] + handle [handle!] + values [red-value!] + obj [red-object!] + flags [integer!] ][ ;; DEBUG: print ["OS-destroy-view" lf] handle: face-handle? face @@ -2261,19 +2256,19 @@ OS-destroy-view: func [ ] OS-update-facet: func [ - face [red-object!] - facet [red-word!] - value [red-value!] - action [red-word!] - new [red-value!] - index [integer!] - part [integer!] + face [red-object!] + facet [red-word!] + value [red-value!] + action [red-word!] + new [red-value!] + index [integer!] + part [integer!] /local - word [red-word!] - sym [integer!] - type [integer!] - pane [red-block!] - widget [handle!] + word [red-word!] + sym [integer!] + type [integer!] + pane [red-block!] + widget [handle!] ][ sym: symbol/resolve facet/symbol ;; DEBUG: print ["update-facet " get-symbol-name sym lf] @@ -2307,12 +2302,12 @@ OS-update-facet: func [ ] OS-to-image: func [ - face [red-object!] - return: [red-image!] + face [red-object!] + return: [red-image!] /local - widget [handle!] + widget [handle!] win [handle!] - xwin [integer!] + xwin [integer!] width [integer!] height [integer!] pixbuf [handle!] @@ -2320,8 +2315,8 @@ OS-to-image: func [ type [integer!] size [red-pair!] ret [red-image!] - list [GList!] - child [GList!] + list [GList!] + child [GList!] ][ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol @@ -2395,13 +2390,13 @@ OS-to-image: func [ ] OS-do-draw: func [ - image [red-image!] - cmds [red-block!] + image [red-image!] + cmds [red-block!] /local cr [handle!] surf [handle!] - w [integer!] - h [integer!] + w [integer!] + h [integer!] bitmap [integer!] data [int-ptr!] stride [integer!] @@ -2425,13 +2420,13 @@ OS-do-draw: func [ ] OS-do-draw-OLD: func [ - image [red-image!] - cmds [red-block!] + image [red-image!] + cmds [red-block!] /local cr [handle!] surf [handle!] - w [integer!] - h [integer!] + w [integer!] + h [integer!] bitmap [integer!] data [int-ptr!] stride [integer!] @@ -2455,8 +2450,8 @@ OS-do-draw-OLD: func [ ] OS-draw-face: func [ - ctx [draw-ctx!] - cmds [red-block!] + ctx [draw-ctx!] + cmds [red-block!] ][ if TYPE_OF(cmds) = TYPE_BLOCK [ catch RED_THROWN_ERROR [parse-draw ctx cmds yes] diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 902c71de8a..95afb6c616 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -289,6 +289,7 @@ system/view/platform: context [ _cross: symbol/make "cross" on-over: symbol/make "on-over" + _drag-on: symbol/make "drag-on" _actors: word/load "actors" _scroller: word/load "scroller" _window: word/load "window" From 45931ac7890b94b8aaa18c53432d2505fa69d7dd Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 18:07:01 +0800 Subject: [PATCH 0146/3432] FEAT: merge similar event callback --- modules/view/backends/gtk3/events.reds | 367 +++++------------------ modules/view/backends/gtk3/handlers.reds | 301 ++++++------------- modules/view/backends/platform.red | 40 ++- 3 files changed, 218 insertions(+), 490 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 5e31d7b01f..7bbd56510e 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -597,172 +597,15 @@ debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and respond-event?: func [ actors [red-object!] - type [c-string!] + type [red-word!] return: [logic!] - /local - respond? [logic!] -][ - either null? actors/ctx [ - false - ][ - respond?: -1 <> object/rs-find actors as red-value! word/load type - ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_EVENT [print ["respond-event? type " type lf]] - respond? - ] -] - -respond-mouse-id: g_quark_from_string "respond-mouse-id" -respond-key-id: g_quark_from_string "respond-key-id" -respond-window-id: g_quark_from_string "respond-window-id" - -#enum RespondMouseType! [ - ON_LEFT_DOWN: 1 - ON_LEFT_UP: 2 - ON_MIDDLE_DOWN: 4 - ON_MIDDLE_UP: 8 - ON_RIGHT_DOWN: 16 - ON_RIGHT_UP: 32 - ON_AUX_DOWN: 64 - ON_AUX_UP: 128 - ON_CLICK: 256 - ON_DBL_CLICK: 512 - ON_WHEEL: 1024 - ON_OVER: 2048 -] - -respond-mouse-add: func [ - widget [handle!] - actors [red-object!] - sym [integer!] - /local - on-type [integer!] ][ - on-type: 0 - if respond-event? actors "on-down" [on-type: on-type or ON_LEFT_DOWN] - if respond-event? actors "on-up" [on-type: on-type or ON_LEFT_UP] - if respond-event? actors "on-mid-down" [on-type: on-type or ON_MIDDLE_DOWN] - if respond-event? actors "on-mid-up" [on-type: on-type or ON_MIDDLE_UP] - if respond-event? actors "on-alt-down" [on-type: on-type or ON_RIGHT_DOWN] - if respond-event? actors "on-alt-up" [on-type: on-type or ON_RIGHT_UP] - if respond-event? actors "on-aux-down" [on-type: on-type or ON_AUX_DOWN] - if respond-event? actors "on-aux-up" [on-type: on-type or ON_AUX_UP] - if respond-event? actors "on-click" [on-type: on-type or ON_CLICK] - if respond-event? actors "on-dbl-click" [on-type: on-type or ON_DBL_CLICK] - if respond-event? actors "on-wheel" [on-type: on-type or ON_WHEEL] - if respond-event? actors "on-over" [on-type: on-type or ON_OVER] - if all[on-type > 0 not null? widget][ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_MOUSE [print ["Add mouse event " on-type " for " get-symbol-name sym lf ]] - g_object_set_qdata widget respond-mouse-id as int-ptr! on-type + if null? actors/ctx [ + return false ] + -1 <> object/rs-find actors as red-value! type ] -respond-mouse?: func [ - widget [handle!] - on-type [integer!] - return: [logic!] -][ - (as-integer g_object_get_qdata widget respond-mouse-id) and on-type <> 0 -] - -#enum RespondWindowType! [ - ON_CLOSE: 1 ;-- window events - ON_MOVE: 2 - ON_SIZE: 4 - ON_MOVING: 8 - ON_SIZING: 16 - ON_TIME: 32 - ON_DRAWING: 64 - ON_SCROLL: 128 - - ON_SELECT: 1024 - ON_CHANGE: 2048 - ON_MENU: 4096 -] - -respond-window-add: func [ - widget [handle!] - actors [red-object!] - sym [integer!] - /local - on-type [integer!] -][ - on-type: 0 - if respond-event? actors "on-close" [on-type: on-type or ON_CLOSE] - if respond-event? actors "on-move" [on-type: on-type or ON_MOVE] - if respond-event? actors "on-moving" [on-type: on-type or ON_MOVING] - if respond-event? actors "on-size" [on-type: on-type or ON_SIZE] - if respond-event? actors "on-sizing" [on-type: on-type or ON_SIZING] - if respond-event? actors "on-time" [on-type: on-type or ON_TIME] - if respond-event? actors "on-drawing" [on-type: on-type or ON_DRAWING] - if respond-event? actors "on-scroll" [on-type: on-type or ON_SCROLL] - if respond-event? actors "on-over" [on-type: on-type or ON_OVER] - if respond-event? actors "on-select" [on-type: on-type or ON_SELECT] - if respond-event? actors "on-change" [on-type: on-type or ON_CHANGE] - if respond-event? actors "on-menu" [on-type: on-type or ON_MENU] - if all[on-type > 0 not null? widget][ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_WINDOW [print ["Add window event " on-type " for " get-symbol-name sym lf ]] - g_object_set_qdata widget respond-window-id as int-ptr! on-type - ] -] - -respond-window?: func [ - widget [handle!] - on-type [integer!] - return: [logic!] -][ - (as-integer g_object_get_qdata widget respond-window-id) and on-type <> 0 -] - -#enum RespondKeyType! [ - ON_KEY: 1 - ON_KEY_DOWN: 2 - ON_KEY_UP: 4 - ON_IME: 8 - ON_FOCUS: 16 - ON_UNFOCUS: 32 - ON_ENTER: 64 - ON_ZOOM: 128 - ON_PAN: 256 - ON_ROTATE: 512 - ON_TWO_TAP: 1024 - ON_PRESS_TAP: 2048 -] - -respond-key-add: func [ - widget [handle!] - actors [red-object!] - sym [integer!] - /local - on-type [integer!] -][ - on-type: 0 - if respond-event? actors "on-key" [on-type: on-type or ON_KEY] - if respond-event? actors "on-key-down" [on-type: on-type or ON_KEY_DOWN] - if respond-event? actors "on-key-up" [on-type: on-type or ON_KEY_UP] - if respond-event? actors "on-ime" [on-type: on-type or ON_IME] - if respond-event? actors "on-focus" [on-type: on-type or ON_FOCUS] - if respond-event? actors "on-unfocus" [on-type: on-type or ON_UNFOCUS] - if respond-event? actors "on-enter" [on-type: on-type or ON_ENTER] - if respond-event? actors "on-zoom" [on-type: on-type or ON_ZOOM] - if respond-event? actors "on-pan" [on-type: on-type or ON_PAN] - if respond-event? actors "on-rotate" [on-type: on-type or ON_ROTATE] - if respond-event? actors "on-two-tap" [on-type: on-type or ON_TWO_TAP] - if respond-event? actors "on-press-tap" [on-type: on-type or ON_PRESS_TAP] - if all[on-type > 0 not null? widget][ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_RESPOND_KEY [print ["Add key event " on-type " for " get-symbol-name sym lf ]] - g_object_set_qdata widget respond-key-id as int-ptr! on-type - ] -] - -respond-key?: func [ - widget [handle!] - on-type [integer!] - return: [logic!] -][ - (as-integer g_object_get_qdata widget respond-key-id) and on-type <> 0 -] - - connect-container-events: func [ widget [handle!] evt-type [c-string!] @@ -803,85 +646,91 @@ connect-container-events: func [ ;; 2) it is too slow when used in ast.red for base widget (too much delegations). connect-common-events: function [ - widget [handle!] - face [red-object!] + widget [handle!] + face [red-object!] + actors [red-object!] sym [integer!] - parent [handle!] ][ - unless null? widget [ + assert widget <> null - if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-DOWN: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-press-event" - ] - gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + if any [ + respond-event? actors on-down + respond-event? actors on-mid-down + respond-event? actors on-alt-down + respond-event? actors on-aux-down + ][ + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-press-event" ] - if respond-mouse? widget (ON_OVER) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-OVER: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "motion-notify-event" - ] - gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) + gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + ] + if respond-event? actors on-over [ + gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "motion-notify-event" ] + gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) + ] - if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-UP: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-release-event" - ] - gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) + if any [ + respond-event? actors on-up + respond-event? actors on-mid-up + respond-event? actors on-alt-up + respond-event? actors on-aux-up + ][ + gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-release-event" ] + gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) + ] - if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS or ON_ENTER) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-KEY: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK - gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) - ] + if any [ + sym = field + respond-event? actors on-key + respond-event? actors on-key-down + respond-event? actors on-focus + respond-event? actors on-enter + ][ + gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK + gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) + ] - if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON-KEY-UP: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_KEY_RELEASE_MASK - gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) - ] + if any [ + sym = field + respond-event? actors on-key-up + respond-event? actors on-unfocus + ][ + gtk_widget_add_events widget GDK_KEY_RELEASE_MASK + gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) + ] - if respond-mouse? widget ON_WHEEL [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print [ "connect-common-events ON_WHEEL: " get-symbol-name sym "->" widget lf]] - gtk_widget_add_events widget GDK_SCROLL_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "scroll-event" - ] - gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) + if respond-event? actors on-wheel [ + gtk_widget_add_events widget GDK_SCROLL_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "scroll-event" ] - + gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) ] ] connect-notify-events: function [ - widget [handle!] - face [red-object!] + widget [handle!] + face [red-object!] + actors [red-object!] sym [integer!] - /local - _widget [handle!] ][ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print ["connect-notify-events " widget " " get-symbol-name sym lf]] - - unless null? widget [ - _widget: either sym = text [_widget? widget][widget] - - if respond-mouse? widget ON_OVER [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_NOTIFY [print [ "connect-notifiy-events ON-OVER: " get-symbol-name sym "->" widget "(" _widget ")" lf]] - gtk_widget_add_events _widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK - gobj_signal_connect(_widget "enter-notify-event" :widget-enter-notify-event face/ctx) - gobj_signal_connect(_widget "leave-notify-event" :widget-leave-notify-event face/ctx) - ] + assert widget <> null + if respond-event? actors on-over [ + if sym = text [widget: _widget? widget] + gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK + gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) + gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) ] ] @@ -896,22 +745,12 @@ connect-widget-events: function [ buffer [handle!] ][ ;; register red mouse, key and window on event functions - - ;; DEBUG: print ["common-widget-events for " get-symbol-name sym " " widget lf] - ;; DEBUG: if null? actors/ctx [print ["null? actors/ctx" lf]] - - respond-mouse-add widget actors sym - respond-key-add widget actors sym - respond-window-add widget actors sym - - ;-- expose all active events to upper users - connect-common-events widget face sym parent + connect-common-events widget face actors sym case [ sym = check [ ;@@ No click event for check ;gobj_signal_connect(widget "clicked" :button-clicked null) - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add check toggled " lf]] gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = radio [ @@ -920,7 +759,7 @@ connect-widget-events: function [ gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = button [ - if respond-mouse? widget ON_CLICK [ + if respond-event? actors on-click [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] gobj_signal_connect(widget "clicked" :button-clicked null) ] @@ -951,31 +790,8 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] gobj_signal_connect(widget "value-changed" :range-value-changed face/ctx) ] - sym = text [ - if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text (event-box) button-press-event " lf]] - gobj_signal_connect(_widget "button-press-event" :simple-button-press-event widget) - ] - if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text (event-box) button-release-event " lf]] - gobj_signal_connect(_widget "button-release-event" :simple-button-release-event widget) - ] - ] + sym = text [0] sym = field [ - ;;if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS or ON_ENTER) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add field key-press-event" lf]] - gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) - ;;] - ;;if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add field key-release-event" lf]] - gobj_signal_connect(widget "key-release-event" :field-key-release-event face/ctx) - ;;] - ;Do not work: gobj_signal_connect(widget "key-press-event" :field-key-press-event face/ctx) - ;;if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add fiedl button-release-event " lf]] - gobj_signal_connect(widget "button-release-event" :field-button-release-event face/ctx) - ;;] - gtk_widget_set_can_focus widget yes gtk_widget_is_focus widget ;This depends on version >= 3.2 @@ -992,22 +808,6 @@ connect-widget-events: function [ gobj_signal_connect(buffer "changed" :area-changed widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] g_object_set [widget "populate-all" yes null] - if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area button-press-event " lf]] - gobj_signal_connect(widget "button-press-event" :area-button-press-event face/ctx) - ] - if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area button-release-event " lf]] - gobj_signal_connect(widget "button-release-event" :area-button-release-event face/ctx) - ] - if respond-key? widget (ON_KEY or ON_KEY_DOWN or ON_FOCUS) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area key-press-event " lf]] - gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) - ] - if respond-key? widget (ON_KEY_UP or ON_UNFOCUS) [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area key-release-event " lf]] - gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) - ] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup face/ctx) ] @@ -1019,19 +819,12 @@ connect-widget-events: function [ gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes - ;; value: gtk_widget_get_events widget - ;; DEBUG: print ["panel had focus: " gtk_widget_get_focus_on_click widget lf "get events: " value " GDK_BUTTON_PRESS_MASK? " GDK_BUTTON_PRESS_MASK and value lf] - ; if respond-mouse? widget (ON_LEFT_DOWN or ON_RIGHT_DOWN or ON_MIDDLE_DOWN or ON_AUX_DOWN) [ - ; gobj_signal_connect(widget "button-press-event" :panel-button-press-event face/ctx) - ;] - ; if respond-mouse? widget ON_OVER [gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx)] - - ; if respond-mouse? widget (ON_LEFT_UP or ON_RIGHT_UP or ON_MIDDLE_UP or ON_AUX_UP) [gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx)] - ; if respond-key? widget (ON_KEY or ON_KEY_DOWN) [gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx)] - ; if respond-key? widget ON_KEY_UP [gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx)] ] sym = tab-panel [ - if respond-window? widget (ON_SELECT or ON_CHANGE) [ + if any [ + respond-event? actors on-select + respond-event? actors on-change + ][ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) ] @@ -1051,5 +844,5 @@ connect-widget-events: function [ ] true [0] ] - connect-notify-events widget face sym + connect-notify-events widget face actors sym ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 42c5aff8f1..6679461b69 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -414,23 +414,6 @@ range-value-changed: func [ ;] ] -simple-button-press-event: func [ - [cdecl] - _widget [handle!] - evt [handle!] - widget [handle!] -][ - make-event widget 0 EVT_LEFT_DOWN -] -simple-button-release-event: func [ - [cdecl] - _widget [handle!] - evt [handle!] - widget [handle!] -][ - make-event widget 0 EVT_LEFT_UP -] - combo-selection-changed: func [ [cdecl] widget [handle!] @@ -498,7 +481,7 @@ tab-panel-switch-page: func [ ] ; Do not use key-press-event since character would not be printed! -field-key-press-event: func [ +key-press-event: func [ [cdecl] widget [handle!] event-key [GdkEventKey!] @@ -539,33 +522,35 @@ field-key-press-event: func [ EVT_DISPATCH ] -field-key-release-event: func [ +key-release-event: func [ [cdecl] widget [handle!] event-key [GdkEventKey!] ctx [node!] return: [integer!] /local - res [integer!] - key [integer!] - flags [integer!] + sym [integer!] text [c-string!] - face [red-object!] qdata [handle!] + face [red-object!] + key [integer!] + flags [integer!] ][ - ;; DEBUG: print "key-release: " - ;; DEBUG: print [ "keyval: " event-key/keyval " -> " gdk_keyval_name event-key/keyval "(" event-key/keyval " -> " gdk_keyval_to_lower event-key/keyval ") et state: " event-key/state lf] - ;; DEBUG: print [ "keycode: " as integer! event-key/keycode1 " " as integer! event-key/keycode2 lf] - - text: gtk_entry_get_text widget - qdata: g_object_get_qdata widget red-face-id - ;; DEBUG: print ["qdata: " qdata "text: " text lf] - unless null? qdata [ - face: as red-object! qdata - set-text widget face/ctx text - make-event widget 0 EVT_CHANGE + sym: get-widget-symbol widget + if sym = field [ + text: gtk_entry_get_text widget + qdata: g_object_get_qdata widget red-face-id + unless null? qdata [ + face: as red-object! qdata + set-text widget face/ctx text + make-event widget 0 EVT_CHANGE + ] ] - make-event widget 0 EVT_KEY_UP + if event-key/keyval > FFFFh [return EVT_DISPATCH] + key: translate-key event-key/keyval + flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not + flags: flags or check-extra-keys event-key/state + make-event widget key or flags EVT_KEY_UP ] field-move-focus: func [ @@ -577,33 +562,75 @@ field-move-focus: func [ print-line "move-focus" ] -field-button-release-event: func [ +mouse-button-release-event: func [ [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] /local - x [integer!] - y [integer!] - sel [red-pair!] + sym [integer!] + x [integer!] + y [integer!] + sel [red-pair!] + buffer [handle!] + start [GtkTextIter!] + end [GtkTextIter!] + flags [integer!] + ev [integer!] ][ - ;; DEBUG: print [ "field mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - if event/button = GDK_BUTTON_PRIMARY [ - x: -1 y: -1 - if gtk_editable_get_selection_bounds widget :x :y [ - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y + if draggable? widget [return 0] ; delegate to drag + + sym: get-widget-symbol widget + if sym = field [ + if event/button = GDK_BUTTON_PRIMARY [ + x: -1 y: -1 + if gtk_editable_get_selection_bounds widget :x :y [ + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT ] - make-event widget 0 EVT_SELECT ] ] - make-event widget 0 EVT_LEFT_UP - EVT_NO_DISPATCH + if sym = area [ + if event/button = GDK_BUTTON_PRIMARY [ + start: as GtkTextIter! allocate (size? GtkTextIter!) + end: as GtkTextIter! allocate (size? GtkTextIter!) + buffer: gtk_text_view_get_buffer widget + if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ + x: -1 y: -1 + x: gtk_text_iter_get_offset as handle! start + y: gtk_text_iter_get_offset as handle! end + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT + ] + free as byte-ptr! start free as byte-ptr! end + ] + ] + evt-motion/state: yes + evt-motion/cpt: 0 + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + evt-motion/x_new: as-integer event/x + evt-motion/y_new: as-integer event/y + flags: check-flags event/type event/state + ev: case [ + event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] + event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] + true [EVT_LEFT_UP] + ] + make-event widget flags ev ] area-changed: func [ @@ -631,63 +658,6 @@ area-changed: func [ ] ] -area-button-press-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - flags [integer!] -][ - ;; DEBUG: print [ "area -> BUTTON-PRESS: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - - menu-x: as-integer event/x - menu-y: as-integer event/y - ;; DEBUG: print ["menu cursor pos: " menu-x "x" menu-y lf] - flags: check-flags event/type event/state - make-event widget flags EVT_LEFT_DOWN - 0;;no -] - -area-button-release-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - flags [integer!] - buffer [handle!] - start [GtkTextIter!]; value does not work - end [GtkTextIter!] - x [integer!] - y [integer!] - sel [red-pair!] -][ - ;; DEBUG: print [ "area mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - if event/button = GDK_BUTTON_PRIMARY [ - start: as GtkTextIter! allocate (size? GtkTextIter!) - end: as GtkTextIter! allocate (size? GtkTextIter!) - buffer: gtk_text_view_get_buffer widget - if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ - x: -1 y: -1 - x: gtk_text_iter_get_offset as handle! start - y: gtk_text_iter_get_offset as handle! end - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y - ] - make-event widget 0 EVT_SELECT - ] - free as byte-ptr! start free as byte-ptr! end - ] - 0 -] - area-populate-popup: func [ [cdecl] widget [handle!] @@ -882,23 +852,26 @@ container-delegate-to-children: func [ mouse-button-press-event: func [ [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] /local - flags [integer!] - hMenu [handle!] + sym [integer!] + flags [integer!] + hMenu [handle!] + ev [integer!] ][ ;; DEBUG: print [ "mouse -> BUTTON-PRESS: " widget " (" ") x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] ; evt-motion/state: yes ; evt-motion/cpt: 0 + sym: get-widget-symbol widget if gtk_widget_get_focus_on_click widget [ ;; DEBUG: print ["grab focus on mouse " widget lf] gtk_widget_grab_focus widget ] - if draggable? widget [return 0] ; delegate to drag + if draggable? widget [return EVT_DISPATCH] ; delegate to drag ;; DEBUG: print ["with button " event/button lf] if event/button = GDK_BUTTON_SECONDARY [ @@ -919,31 +892,12 @@ mouse-button-press-event: func [ evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y flags: check-flags event/type event/state - make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_DOWN] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_DOWN] true [EVT_LEFT_DOWN]] - ;; DEBUG: print ["NO DISPATCH" lf] - EVT_NO_DISPATCH -] - -mouse-button-release-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - flags [integer!] -][ - ;; DEBUG: print [ "mouse -> BUTTON-RELEASE: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] - if draggable? widget [return 0] ; delegate to drag - evt-motion/state: yes - evt-motion/cpt: 0 - evt-motion/x_root: event/x_root - evt-motion/y_root: event/y_root - evt-motion/x_new: as-integer event/x - evt-motion/y_new: as-integer event/y - flags: check-flags event/type event/state - make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] true [EVT_LEFT_UP]] - ;;0 ;;no + ev: case [ + event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_DOWN] + event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_DOWN] + true [EVT_LEFT_DOWN] + ] + make-event widget flags ev ] mouse-motion-notify-event: func [ @@ -975,63 +929,6 @@ mouse-motion-notify-event: func [ EVT_DISPATCH ;;no ] -key-press-event: func [ - [cdecl] - widget [handle!] - event-key [GdkEventKey!] - ctx [node!] - return: [integer!] - /local - state [integer!] - key [integer!] - flags [integer!] - text [c-string!] -][ - - ;; DEBUG: print ["key-press-event: " event-key/keyval " " widget lf] - state: 0 - either event-key/keyval > FFFFh [state: 1][ - key: translate-key event-key/keyval - flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not - flags: flags or check-extra-keys event-key/state - - - state: make-event widget key or flags EVT_KEY_DOWN - unless state = EVT_NO_DISPATCH [ - state: make-event widget key or flags EVT_KEY - ] - ] - state -] - -key-release-event: func [ - [cdecl] - widget [handle!] - event-key [GdkEventKey!] - ctx [node!] - return: [integer!] - /local - state [integer!] - key [integer!] - flags [integer!] - text [c-string!] -][ - ;; DEBUG: print ["key-release-event: " event-key/keyval " " widget lf] - state: 0 - either event-key/keyval > FFFFh [state: 1][ - key: translate-key event-key/keyval - flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not - flags: flags or check-extra-keys event-key/state - - - state: make-event widget key or flags EVT_KEY_UP - unless state = EVT_NO_DISPATCH [ - state: make-event widget key or flags EVT_KEY - ] - ] - state -] - menu-item-activate: func [ [cdecl] item [handle!] diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 95afb6c616..d681c42c8b 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -288,7 +288,6 @@ system/view/platform: context [ _I-beam: symbol/make "I-beam" _cross: symbol/make "cross" - on-over: symbol/make "on-over" _drag-on: symbol/make "drag-on" _actors: word/load "actors" _scroller: word/load "scroller" @@ -376,6 +375,45 @@ system/view/platform: context [ _caps-lock: word/load "caps-lock" _num-lock: word/load "num-lock" + on-key: word/load "on-key" + on-key-down: word/load "on-key-down" + on-key-up: word/load "on-key-up" + on-ime: word/load "on-ime" + on-focus: word/load "on-focus" + on-unfocus: word/load "on-unfocus" + on-enter: word/load "on-enter" + on-zoom: word/load "on-zoom" + on-pan: word/load "on-pan" + on-rotate: word/load "on-rotate" + on-two-tap: word/load "on-two-tap" + on-press-tap: word/load "on-press-tap" + + on-close: word/load "on-close" + on-move: word/load "on-move" + on-moving: word/load "on-moving" + on-size: word/load "on-size" + on-sizing: word/load "on-sizing" + on-time: word/load "on-time" + on-drawing: word/load "on-drawing" + on-scroll: word/load "on-scroll" + on-over: word/load "on-over" + on-select: word/load "on-select" + on-change: word/load "on-change" + on-menu: word/load "on-menu" + + on-down: word/load "on-down" + on-up: word/load "on-up" + on-mid-down: word/load "on-mid-down" + on-mid-up: word/load "on-mid-up" + on-alt-down: word/load "on-alt-down" + on-alt-up: word/load "on-alt-up" + on-aux-down: word/load "on-aux-down" + on-aux-up: word/load "on-aux-up" + on-click: word/load "on-click" + on-dbl-click: word/load "on-dbl-click" + on-wheel: word/load "on-wheel" + on-over: word/load "on-over" + red/boot?: no red/collector/active?: yes From 2569bb80ddd3d45eab913d2911c16bf502d38207 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 18:30:40 +0800 Subject: [PATCH 0147/3432] FIX: indent improve --- modules/view/backends/gtk3/handlers.reds | 262 +++++++++++------------ 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6679461b69..3115ec1e13 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -12,20 +12,20 @@ Red/System [ gtk-app-activate: func [ [cdecl] - app [handle!] - data [int-ptr!] + app [handle!] + data [int-ptr!] /local - win [handle!] + win [handle!] ][ probe "active" ] set-selected: func [ - obj [handle!] - ctx [node!] - idx [integer!] + obj [handle!] + ctx [node!] + idx [integer!] /local - int [red-integer!] + int [red-integer!] ][ int: as red-integer! get-node-facet ctx FACE_OBJ_SELECTED int/header: TYPE_INTEGER @@ -33,14 +33,14 @@ set-selected: func [ ] set-text: func [ - obj [handle!] - ctx [node!] - text [c-string!] + obj [handle!] + ctx [node!] + text [c-string!] /local - size [integer!] - str [red-string!] - face [red-object!] - out [c-string!] + size [integer!] + str [red-string!] + face [red-object!] + out [c-string!] ][ ;; DEBUG: print ["set-text: " text lf] size: length? text @@ -66,19 +66,19 @@ set-text: func [ button-clicked: func [ [cdecl] - widget [handle!] - ctx [node!] + widget [handle!] + ctx [node!] ][ make-event widget 0 EVT_CLICK ] button-toggled: func [ [cdecl] - button [handle!] - ctx [node!] + button [handle!] + ctx [node!] /local - bool [red-logic!] - type [integer!] + bool [red-logic!] + type [integer!] undetermined? [logic!] ][ bool: as red-logic! get-node-facet ctx FACE_OBJ_DATA @@ -94,15 +94,15 @@ button-toggled: func [ ] render-text: func [ - cr [handle!] - size [red-pair!] - values [red-value!] + cr [handle!] + size [red-pair!] + values [red-value!] /local text [red-string!] font [red-object!] para [red-object!] flags [integer!] - len [integer!] + len [integer!] str [c-string!] line [integer!] x [float!] @@ -110,14 +110,14 @@ render-text: func [ temp [float!] ;te [cairo_text_extents_t!] ;fe [cairo_font_extents_t!] - lx [integer!] - ly [integer!] + lx [integer!] + ly [integer!] rect [tagRECT value] lrect [tagRECT value] pline [handle!] - pc [handle!] + pc [handle!] lpc [handle!] - fd [handle!] + fd [handle!] ][ text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] @@ -208,21 +208,21 @@ render-text: func [ base-draw: func [ [cdecl] - widget [handle!] - cr [handle!] - ctx [node!] - return: [logic!] + widget [handle!] + cr [handle!] + ctx [node!] + return: [logic!] /local - vals [red-value!] - draw [red-block!] - clr [red-tuple!] - img [red-image!] + vals [red-value!] + draw [red-block!] + clr [red-tuple!] + img [red-image!] size [red-pair!] type [red-word!] sym [integer!] pos [red-pair! value] DC [draw-ctx! value] - drawDC [draw-ctx!] + drawDC [draw-ctx!] ][ ;; DEBUG: print ["base-draw " widget " " gtk_widget_get_allocated_width widget "x" gtk_widget_get_allocated_height widget lf] @@ -285,8 +285,8 @@ base-draw: func [ window-delete-event: func [ [cdecl] - widget [handle!] - return: [logic!] + widget [handle!] + return: [logic!] ][ ;; DEBUG: print ["window-delete-event" lf] make-event widget 0 EVT_CLOSE @@ -304,9 +304,9 @@ window-delete-event: func [ window-removed-event: func [ [cdecl] - app [handle!] - widget [handle!] - count [int-ptr!] + app [handle!] + widget [handle!] + count [int-ptr!] ][ ;; DEBUG[view/no-wait]: print ["App " app " removed window " widget "exit-loop: " exit-loop " win-cnt: " win-cnt " main-window? " main-window = widget] unless view-no-wait? widget [count/value: count/value - 1] @@ -316,13 +316,13 @@ window-removed-event: func [ ;; BUG: `vid.red` fails... back with window-size-allocate handler for resizing window-configure-event: func [ [cdecl] - widget [handle!] - event [GdkEventConfigure!] + widget [handle!] + event [GdkEventConfigure!] /local - sz [red-pair!] + sz [red-pair!] offset [red-pair!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ][ ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] @@ -359,10 +359,10 @@ window-configure-event: func [ window-size-allocate: func [ [cdecl] - widget [handle!] - rect [tagRECT] + widget [handle!] + rect [tagRECT] /local - sz [red-pair!] + sz [red-pair!] ][ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size @@ -381,16 +381,16 @@ window-size-allocate: func [ range-value-changed: func [ [cdecl] - range [handle!] - ctx [node!] + range [handle!] + ctx [node!] /local - vals [red-value!] - val [float!] - size [red-pair!] - ; type [red-word!] - pos [red-float!] - ; sym [integer!] - max [float!] + vals [red-value!] + val [float!] + size [red-pair!] + ; type [red-word!] + pos [red-float!] + ; sym [integer!] + max [float!] ][ ; This event happens on GtkRange widgets including GtkScale. ; Will any other widget need this? @@ -416,12 +416,12 @@ range-value-changed: func [ combo-selection-changed: func [ [cdecl] - widget [handle!] - ctx [node!] + widget [handle!] + ctx [node!] /local - idx [integer!] - res [integer!] - text [c-string!] + idx [integer!] + res [integer!] + text [c-string!] ][ idx: gtk_combo_box_get_active widget if idx >= 0 [ @@ -437,13 +437,13 @@ combo-selection-changed: func [ text-list-selected-rows-changed: func [ [cdecl] - widget [handle!] - ctx [node!] + widget [handle!] + ctx [node!] /local - idx [integer!] - sel [handle!] - res [integer!] - text [c-string!] + idx [integer!] + sel [handle!] + res [integer!] + text [c-string!] ][ ; From now, only single-selection mode sel: gtk_list_box_get_selected_row widget @@ -461,13 +461,13 @@ text-list-selected-rows-changed: func [ tab-panel-switch-page: func [ [cdecl] - widget [handle!] - page [handle!] - idx [integer!] - ctx [node!] + widget [handle!] + page [handle!] + idx [integer!] + ctx [node!] /local - res [integer!] - text [c-string!] + res [integer!] + text [c-string!] ][ if idx >= 0 [ res: make-event widget idx + 1 EVT_SELECT @@ -555,9 +555,9 @@ key-release-event: func [ field-move-focus: func [ [cdecl] - widget [handle!] - event [handle!] - ctx [node!] + widget [handle!] + event [handle!] + ctx [node!] ][ print-line "move-focus" ] @@ -635,8 +635,8 @@ mouse-button-release-event: func [ area-changed: func [ [cdecl] - buffer [handle!] - widget [handle!] + buffer [handle!] + widget [handle!] /local text [c-string!] face [red-object!] @@ -660,9 +660,9 @@ area-changed: func [ area-populate-popup: func [ [cdecl] - widget [handle!] - hMenu [handle!] - ctx [node!] + widget [handle!] + hMenu [handle!] + ctx [node!] /local menu [red-block!] ][ @@ -693,12 +693,12 @@ red-timer-action: func [ widget-enter-notify-event: func [ [cdecl] - widget [handle!] - event [GdkEventCrossing!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventCrossing!] + ctx [node!] + return: [integer!] /local - flags [integer!] + flags [integer!] ][ ;; DEBUG: print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] @@ -709,12 +709,12 @@ widget-enter-notify-event: func [ widget-leave-notify-event: func [ [cdecl] - widget [handle!] - event [GdkEventCrossing!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventCrossing!] + ctx [node!] + return: [integer!] /local - flags [integer!] + flags [integer!] ][ ;; DEBUG: print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] flags: check-flags event/type event/state @@ -724,15 +724,15 @@ widget-leave-notify-event: func [ drag-widget-motion-notify-event: func [ [cdecl] - widget [handle!] - event [GdkEventMotion!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventMotion!] + ctx [node!] + return: [integer!] /local - offset [red-pair!] - x [float!] - y [float!] - flags [integer!] + offset [red-pair!] + x [float!] + y [float!] + flags [integer!] state [integer!] ][ @@ -758,13 +758,13 @@ drag-widget-motion-notify-event: func [ drag-widget-button-press-event: func [ [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] /local - offset [red-pair!] - flags [integer!] + offset [red-pair!] + flags [integer!] ][ ;; DEBUG: print [ "DRAG BUTTON-PRESS: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] if any[ @@ -785,15 +785,15 @@ drag-widget-button-press-event: func [ drag-widget-button-release-event: func [ [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] /local type [red-word!] sym [integer!] state [logic!] - flags [integer!] + flags [integer!] ][ ;; DEBUG: print [ "Drag -> BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] unless any[event/button = GDK_BUTTON_PRIMARY event/button = GDK_BUTTON_SECONDARY event/button = GDK_BUTTON_MIDDLE] [return 0] @@ -817,13 +817,13 @@ drag-widget-button-release-event: func [ container-emit-event: func [ [cdecl] - widget [handle!] - event [int-ptr!] + widget [handle!] + event [int-ptr!] /local - rect [tagRECT] - evt [GdkEventButton!] - x [integer!] - y [integer!] + rect [tagRECT] + evt [GdkEventButton!] + x [integer!] + y [integer!] ][ evt: as GdkEventButton! event x: as-integer evt/x y: as-integer evt/y @@ -840,10 +840,10 @@ container-emit-event: func [ container-delegate-to-children: func [ [cdecl] - widget [handle!] - event [int-ptr!] - ctx [node!] - return: [integer!] + widget [handle!] + event [int-ptr!] + ctx [node!] + return: [integer!] ][ ;; DEBUG: print [ "parent -> CONTAINER DELEGATE: " widget lf] gtk_container_foreach widget as-integer :container-emit-event event @@ -902,14 +902,14 @@ mouse-button-press-event: func [ mouse-motion-notify-event: func [ [cdecl] - widget [handle!] - event [GdkEventMotion!] - ctx [node!] - return: [integer!] + widget [handle!] + event [GdkEventMotion!] + ctx [node!] + return: [integer!] /local - offset [red-pair!] - x [float!] - y [float!] + offset [red-pair!] + x [float!] + y [float!] wflags [integer!] flags [integer!] ][ @@ -948,7 +948,7 @@ widget-scroll-event: func [ ctx [node!] return: [integer!] /local - state [integer!] + state [integer!] ][ ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] state: 0 From 85335cfd5be7bea3ca83ae63cc79ad40d24452cf Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 29 Aug 2019 19:04:34 +0800 Subject: [PATCH 0148/3432] FEAT: send focus/unfocus event --- modules/view/backends/gtk3/events.reds | 15 ++++++++++++--- modules/view/backends/gtk3/handlers.reds | 13 +++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 7bbd56510e..a45a9b2563 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -777,6 +777,8 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget + gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) + gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] @@ -793,10 +795,11 @@ connect-widget-events: function [ sym = text [0] sym = field [ gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget - ;This depends on version >= 3.2 - ;gtk_widget_set_focus_on_click widget yes - gobj_signal_connect(widget "move-focus" :field-move-focus face/ctx) + gtk_widget_grab_focus widget + gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) + gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) ] sym = progress [ 0 @@ -810,6 +813,12 @@ connect-widget-events: function [ g_object_set [widget "populate-all" yes null] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup face/ctx) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_is_focus widget + gtk_widget_grab_focus widget + gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) + gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) ] sym = group-box [ 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 3115ec1e13..c305ddc9a2 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -553,13 +553,22 @@ key-release-event: func [ make-event widget key or flags EVT_KEY_UP ] -field-move-focus: func [ +focus-in-event: func [ [cdecl] widget [handle!] event [handle!] ctx [node!] ][ - print-line "move-focus" + make-event widget 0 EVT_FOCUS +] + +focus-out-event: func [ + [cdecl] + widget [handle!] + event [handle!] + ctx [node!] +][ + make-event widget 0 EVT_UNFOCUS ] mouse-button-release-event: func [ From 902a4175918083ba09ebdfe8b1c080f42e4ff29c Mon Sep 17 00:00:00 2001 From: rcqls Date: Sat, 31 Aug 2019 18:54:07 +0200 Subject: [PATCH 0149/3432] update console-view.red after console.red change --- environment/console/CLI/console-view.red | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/environment/console/CLI/console-view.red b/environment/console/CLI/console-view.red index 4c4684f08d..0b784c4ae9 100644 --- a/environment/console/CLI/console-view.red +++ b/environment/console/CLI/console-view.red @@ -1,10 +1,10 @@ Red [ Title: "Red console" Author: ["Nenad Rakocevic" "Kaj de Vos"] - File: %console.red + File: %console-view.red Tabs: 4 + Needs: 'View Rights: "Copyright (C) 2012-2018 Red Foundation. All rights reserved." - Needs: 'View License: { Distributed under the Boost Software License, Version 1.0. See https://github.com/red/red/blob/master/BSL-License.txt @@ -15,5 +15,19 @@ Red [ #include %../help.red #include %../engine.red -system/console/init "Red Console" -system/console/launch \ No newline at end of file +cli-console-ctx: context [ + settings: #include %settings.red + + launch: does [ + settings/load-cfg + + system/console/init "Red Console" + system/console/launch + ] +] + +_save-cfg: function [][ + cli-console-ctx/settings/save-cfg +] + +cli-console-ctx/launch \ No newline at end of file From d72b55d1615db6d42da387596a5322b1f3f6c0cc Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 2 Sep 2019 14:47:00 +0800 Subject: [PATCH 0150/3432] FIX: improve area/field change/select event --- modules/view/backends/gtk3/events.reds | 5 +- modules/view/backends/gtk3/gtk.reds | 158 +++++++++++------------ modules/view/backends/gtk3/gui.reds | 7 +- modules/view/backends/gtk3/handlers.reds | 50 ++++--- 4 files changed, 108 insertions(+), 112 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index a45a9b2563..c86f68a7e1 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -676,6 +676,8 @@ connect-common-events: function [ ] if any [ + sym = field + sym = area respond-event? actors on-up respond-event? actors on-mid-up respond-event? actors on-alt-up @@ -690,7 +692,6 @@ connect-common-events: function [ ] if any [ - sym = field respond-event? actors on-key respond-event? actors on-key-down respond-event? actors on-focus @@ -701,7 +702,6 @@ connect-common-events: function [ ] if any [ - sym = field respond-event? actors on-key-up respond-event? actors on-unfocus ][ @@ -794,6 +794,7 @@ connect-widget-events: function [ ] sym = text [0] sym = field [ + gobj_signal_connect(widget "changed" :field-changed widget) gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 93308af179..211d6e048b 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -261,27 +261,27 @@ GdkEventScroll!: alias struct! [ ] GtkTextIter!: alias struct! [ - dummy1 [handle!] - dummy2 [handle!] - dummy3 [integer!] - dummy4 [integer!] - dummy5 [integer!] - dummy6 [integer!] - dummy7 [integer!] - dummy8 [integer!] - dummy9 [handle!] - dummy10 [handle!] - dummy11 [integer!] - dummy12 [integer!] - dummy13 [integer!] - dummy14 [handle!] + dummy1 [handle!] + dummy2 [handle!] + dummy3 [integer!] + dummy4 [integer!] + dummy5 [integer!] + dummy6 [integer!] + dummy7 [integer!] + dummy8 [integer!] + dummy9 [handle!] + dummy10 [handle!] + dummy11 [integer!] + dummy12 [integer!] + dummy13 [integer!] + dummy14 [handle!] ] #enum GtkFileChooserAction! [ - GTK_FILE_CHOOSER_ACTION_OPEN - GTK_FILE_CHOOSER_ACTION_SAVE - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER - GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER + GTK_FILE_CHOOSER_ACTION_OPEN + GTK_FILE_CHOOSER_ACTION_SAVE + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ] #enum GtkResponseType! [ @@ -351,7 +351,7 @@ GtkTextIter!: alias struct! [ PangoAttribute!: alias struct! [ klass [handle!] start [integer!] - end [integer!] + end [integer!] ] #enum PangoWrapMode! [ @@ -368,14 +368,14 @@ PangoAttribute!: alias struct! [ ] #enum pango-style! [ - PANGO_STYLE_NORMAL - PANGO_STYLE_OBLIQUE - PANGO_STYLE_ITALIC + PANGO_STYLE_NORMAL + PANGO_STYLE_OBLIQUE + PANGO_STYLE_ITALIC ] #enum pango-variant! [ - PANGO_VARIANT_NORMAL - PANGO_VARIANT_SMALL_CAPS + PANGO_VARIANT_NORMAL + PANGO_VARIANT_SMALL_CAPS ] #enum pango-underline! [ @@ -387,40 +387,40 @@ PangoAttribute!: alias struct! [ ] #enum pango-weight! [ - PANGO_WEIGHT_THIN: 100 - PANGO_WEIGHT_ULTRALIGHT: 200 - PANGO_WEIGHT_LIGHT: 300 - PANGO_WEIGHT_SEMILIGHT: 350 - PANGO_WEIGHT_BOOK: 380 - PANGO_WEIGHT_NORMAL: 400 - PANGO_WEIGHT_MEDIUM: 500 - PANGO_WEIGHT_SEMIBOLD: 600 - PANGO_WEIGHT_BOLD: 700 - PANGO_WEIGHT_ULTRABOLD: 800 - PANGO_WEIGHT_HEAVY: 900 - PANGO_WEIGHT_ULTRAHEAVY: 1000 + PANGO_WEIGHT_THIN: 100 + PANGO_WEIGHT_ULTRALIGHT: 200 + PANGO_WEIGHT_LIGHT: 300 + PANGO_WEIGHT_SEMILIGHT: 350 + PANGO_WEIGHT_BOOK: 380 + PANGO_WEIGHT_NORMAL: 400 + PANGO_WEIGHT_MEDIUM: 500 + PANGO_WEIGHT_SEMIBOLD: 600 + PANGO_WEIGHT_BOLD: 700 + PANGO_WEIGHT_ULTRABOLD: 800 + PANGO_WEIGHT_HEAVY: 900 + PANGO_WEIGHT_ULTRAHEAVY: 1000 ] #enum pango-stretch! [ - PANGO_STRETCH_ULTRA_CONDENSED - PANGO_STRETCH_EXTRA_CONDENSED - PANGO_STRETCH_CONDENSED - PANGO_STRETCH_SEMI_CONDENSED - PANGO_STRETCH_NORMAL - PANGO_STRETCH_SEMI_EXPANDED - PANGO_STRETCH_EXPANDED - PANGO_STRETCH_EXTRA_EXPANDED - PANGO_STRETCH_ULTRA_EXPANDED + PANGO_STRETCH_ULTRA_CONDENSED + PANGO_STRETCH_EXTRA_CONDENSED + PANGO_STRETCH_CONDENSED + PANGO_STRETCH_SEMI_CONDENSED + PANGO_STRETCH_NORMAL + PANGO_STRETCH_SEMI_EXPANDED + PANGO_STRETCH_EXPANDED + PANGO_STRETCH_EXTRA_EXPANDED + PANGO_STRETCH_ULTRA_EXPANDED ] #enum pango-font-mask! [ - PANGO_FONT_MASK_FAMILY: 1 - PANGO_FONT_MASK_STYLE: 2 - PANGO_FONT_MASK_VARIANT: 4 - PANGO_FONT_MASK_WEIGHT: 8 - PANGO_FONT_MASK_STRETCH: 16 - PANGO_FONT_MASK_SIZE: 32 - PANGO_FONT_MASK_GRAVITY: 64 + PANGO_FONT_MASK_FAMILY: 1 + PANGO_FONT_MASK_STYLE: 2 + PANGO_FONT_MASK_VARIANT: 4 + PANGO_FONT_MASK_WEIGHT: 8 + PANGO_FONT_MASK_STRETCH: 16 + PANGO_FONT_MASK_SIZE: 32 + PANGO_FONT_MASK_GRAVITY: 64 ] #enum PangoAlignment! [ @@ -450,22 +450,22 @@ PangoAttribute!: alias struct! [ ] #enum cairo_antialias_t! [ - CAIRO_ANTIALIAS_DEFAULT - CAIRO_ANTIALIAS_NONE - CAIRO_ANTIALIAS_GRAY - CAIRO_ANTIALIAS_SUBPIXEL - CAIRO_ANTIALIAS_FAST - CAIRO_ANTIALIAS_GOOD - CAIRO_ANTIALIAS_BEST + CAIRO_ANTIALIAS_DEFAULT + CAIRO_ANTIALIAS_NONE + CAIRO_ANTIALIAS_GRAY + CAIRO_ANTIALIAS_SUBPIXEL + CAIRO_ANTIALIAS_FAST + CAIRO_ANTIALIAS_GOOD + CAIRO_ANTIALIAS_BEST ] cairo_matrix_t!: alias struct! [ - xx [float!] - yx [float!] - xy [float!] - yy [float!] - x0 [float!] - y0 [float!] + xx [float!] + yx [float!] + xy [float!] + yy [float!] + x0 [float!] + y0 [float!] ] ; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo @@ -503,14 +503,14 @@ GString!: alias struct! [ ] GList!: alias struct! [ - data [int-ptr!] - next [GList!] - prev [GList!] + data [int-ptr!] + next [GList!] + prev [GList!] ] GPtrArray!: alias struct! [ - pdata [int-ptr!] - len [integer!] + pdata [int-ptr!] + len [integer!] ] #enum GtkPackDirection! [ @@ -522,7 +522,7 @@ GPtrArray!: alias struct! [ #enum GtkOrientation! [ GTK_ORIENTATION_HORIZONTAL - GTK_ORIENTATION_VERTICAL + GTK_ORIENTATION_VERTICAL ] #enum GConnectFlags! [ @@ -1816,10 +1816,10 @@ GPtrArray!: alias struct! [ buffer [handle!] start [handle!] end [handle!] - return: [logic!] + return: [logic!] ] gtk_text_buffer_select_range: "gtk_text_buffer_select_range" [ - buffer [handle!] + buffer [handle!] ins [handle!] bound [handle!] ] @@ -1829,15 +1829,15 @@ GPtrArray!: alias struct! [ ] gtk_text_iter_get_offset: "gtk_text_iter_get_offset" [ iter [handle!] - return: [integer!] + return: [integer!] ] gtk_text_iter_set_offset: "gtk_text_iter_set_offset" [ iter [handle!] - offset [integer!] + offset [integer!] ] gtk_text_iter_get_line: "gtk_text_iter_get_line" [ iter [handle!] - return: [integer!] + return: [integer!] ] gtk_combo_box_text_new: "gtk_combo_box_text_new" [ return: [handle!] @@ -1971,7 +1971,7 @@ GPtrArray!: alias struct! [ layout [handle!] return: [handle!] ] - pango_layout_set_text: "pango_layout_set_text" [ + pango_layout_set_text: "pango_layout_set_text" [ layout [handle!] text [c-string!] len [integer!] @@ -1992,7 +1992,7 @@ GPtrArray!: alias struct! [ layout [handle!] return: [handle!] ] - pango_layout_set_font_description: "pango_layout_set_font_description" [ + pango_layout_set_font_description: "pango_layout_set_font_description" [ layout [handle!] fontdesc [handle!] ] @@ -2087,7 +2087,7 @@ GPtrArray!: alias struct! [ layout [handle!] return: [integer!] ] - pango_layout_get_size: "pango_layout_get_size" [ + pango_layout_get_size: "pango_layout_get_size" [ layout [handle!] width [int-ptr!] height [int-ptr!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b9284aed2d..a1f950e7de 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1211,8 +1211,8 @@ change-selection: func [ wnd [integer!] item [handle!] sel [red-pair!] - ins [GtkTextIter!] - bound [GtkTextIter!] + ins [GtkTextIter! value] + bound [GtkTextIter! value] buffer [handle!] ][ ;; DEBUG: print ["change-selection: " widget " (" get-symbol-name type ")" lf] @@ -1234,15 +1234,12 @@ change-selection: func [ gtk_editable_select_region widget idx idx + sz ][ buffer: gtk_text_view_get_buffer widget - ins: as GtkTextIter! allocate (size? GtkTextIter!) - bound: as GtkTextIter! allocate (size? GtkTextIter!) ;; Careful! GtkTextIter! needs to be initialized first (so this weird call first!) gtk_text_buffer_get_selection_bounds buffer as handle! ins as handle! bound ;; DEBUG: print [" pos : " idx "x" idx + sz lf] gtk_text_iter_set_offset as handle! ins idx gtk_text_iter_set_offset as handle! bound idx + sz gtk_text_buffer_select_range buffer as handle! ins as handle! bound - free as byte-ptr! ins free as byte-ptr! bound ] ] ; type = camera [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c305ddc9a2..c054c3614d 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -529,23 +529,9 @@ key-release-event: func [ ctx [node!] return: [integer!] /local - sym [integer!] - text [c-string!] - qdata [handle!] - face [red-object!] key [integer!] flags [integer!] ][ - sym: get-widget-symbol widget - if sym = field [ - text: gtk_entry_get_text widget - qdata: g_object_get_qdata widget red-face-id - unless null? qdata [ - face: as red-object! qdata - set-text widget face/ctx text - make-event widget 0 EVT_CHANGE - ] - ] if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not @@ -553,6 +539,24 @@ key-release-event: func [ make-event widget key or flags EVT_KEY_UP ] +field-changed: func [ + [cdecl] + buffer [handle!] + widget [handle!] + /local + text [c-string!] + qdata [handle!] + face [red-object!] +][ + text: gtk_entry_get_text widget + qdata: g_object_get_qdata widget red-face-id + unless null? qdata [ + face: as red-object! qdata + set-text widget face/ctx text + make-event widget 0 EVT_CHANGE + ] +] + focus-in-event: func [ [cdecl] widget [handle!] @@ -583,8 +587,8 @@ mouse-button-release-event: func [ y [integer!] sel [red-pair!] buffer [handle!] - start [GtkTextIter!] - end [GtkTextIter!] + start [GtkTextIter! value] + end [GtkTextIter! value] flags [integer!] ev [integer!] ][ @@ -608,8 +612,6 @@ mouse-button-release-event: func [ ] if sym = area [ if event/button = GDK_BUTTON_PRIMARY [ - start: as GtkTextIter! allocate (size? GtkTextIter!) - end: as GtkTextIter! allocate (size? GtkTextIter!) buffer: gtk_text_view_get_buffer widget if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ x: -1 y: -1 @@ -624,7 +626,6 @@ mouse-button-release-event: func [ ] make-event widget 0 EVT_SELECT ] - free as byte-ptr! start free as byte-ptr! end ] ] evt-motion/state: yes @@ -650,18 +651,15 @@ area-changed: func [ text [c-string!] face [red-object!] qdata [handle!] - start [GtkTextIter!] - end [GtkTextIter!] + start [GtkTextIter! value] + end [GtkTextIter! value] ][ ; Weirdly, GtkTextIter introduced since I did not simplest solution to get the full content of a GtkTextBuffer! - start: as GtkTextIter! allocate (size? GtkTextIter!) - end: as GtkTextIter! allocate (size? GtkTextIter!) gtk_text_buffer_get_bounds buffer as handle! start as handle! end text: gtk_text_buffer_get_text buffer as handle! start as handle! end no - free as byte-ptr! start free as byte-ptr! end qdata: g_object_get_qdata widget red-face-id - unless null? qdata [ - face: as red-object! qdata + unless null? qdata [ + face: as red-object! qdata set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] From 0d28d02f8fd7d5030f5653aace4b1dc99e7e168b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 2 Sep 2019 17:03:31 +0800 Subject: [PATCH 0151/3432] FEAT: support window's flag `no-title` --- modules/view/backends/gtk3/gui.reds | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a1f950e7de..6a46f63507 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1845,7 +1845,7 @@ OS-make-view: func [ unless null? caption [gtk_window_set_title widget caption] winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 - gtk_container_add widget winbox + gtk_container_add widget winbox if all [ ;@@ application menu ? null? AppMainMenu menu-bar? menu window @@ -1866,8 +1866,14 @@ OS-make-view: func [ ;; The following line really matters to fix the initial size of the window gtk_widget_set_size_request widget size/x size/y gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) - gtk_window_set_decorated widget (bits and FACET_FLAGS_NO_BORDER = 0) - + either any [ + bits and FACET_FLAGS_NO_TITLE <> 0 + bits and FACET_FLAGS_NO_BORDER <> 0 + ][ + gtk_window_set_decorated widget no + ][ + gtk_window_set_decorated widget yes + ] ] sym = slider [ vertical?: size/y > size/x From 9e1bdad719141e22c0bf5375b191f63b186cb172 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 3 Sep 2019 11:10:55 +0800 Subject: [PATCH 0152/3432] FIX: memory leak for face object --- modules/view/backends/gtk3/gui.reds | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 6a46f63507..7e601767d0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -2045,8 +2045,11 @@ OS-make-view: func [ ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events - store-face-to-obj widget face - if sym = text [store-face-to-obj _widget face] + either sym = text [ + store-face-to-obj _widget face + ][ + store-face-to-obj widget face + ] change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym @@ -2237,25 +2240,25 @@ OS-destroy-view: func [ gtk_widget_destroy handle win-cnt: win-cnt - 1 ][ + ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] - ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] + obj: as red-object! values + FACE_OBJ_FONT + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] - obj: as red-object! values + FACE_OBJ_FONT - if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] + obj: as red-object! values + FACE_OBJ_PARA + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] - obj: as red-object! values + FACE_OBJ_PARA - if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] - - ;;g_main_context_release GTKApp-Ctx - ;; DEBUG: + ;;g_main_context_release GTKApp-Ctx + ;; DEBUG: - ;; TODO: This can be useless now! - remove-all-timers handle + ;; TODO: This can be useless now! + remove-all-timers handle - ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] + ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] - free-handles as-integer handle no + free-handles as-integer handle no ] + free as byte-ptr! g_object_get_qdata handle red-face-id ] OS-update-facet: func [ From 17181b53d400ec3f4d8308c8ea3f20d2c4b1dcb1 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 3 Sep 2019 11:11:28 +0800 Subject: [PATCH 0153/3432] FIX: console print warning infos --- modules/view/backends/gtk3/events.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index c86f68a7e1..14efdd8726 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -430,7 +430,7 @@ do-events: func [ ][ msg?: no - set-view-no-wait last-window no-wait? + set-view-no-wait gtk_application_get_active_window GTKApp no-wait? ;@@ Improve it!!! ;@@ as we cannot access gapplication->priv->use_count From a8ed62d1a9ddef416973ecea435d48f0f3bedc81 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 4 Sep 2019 09:54:23 +0800 Subject: [PATCH 0154/3432] FIX: remove no used code --- modules/view/backends/gtk3/events.reds | 20 ----------- modules/view/backends/gtk3/handlers.reds | 42 ++---------------------- 2 files changed, 3 insertions(+), 59 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 14efdd8726..4f00194abb 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -43,12 +43,6 @@ evt-motion: context [ sensitiv: 3 ] -evt-sizing: context [ - x_root: 0.0 - y_root: 0.0 - x_new: 0 - y_new: 0 -] make-at: func [ widget [handle!] face [red-object!] @@ -119,20 +113,6 @@ get-event-offset: func [ widget: as handle! evt/msg sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - ;; DEBUG: print ["event-offset type: " get-symbol-name get-widget-symbol widget " size: " sz/x "x" sz/y lf] - ; sz/x: evt-sizing/x_new - ; sz/y: evt-sizing/y_new - - ; print ["OFFSET is SIZE ? " sz " vs " offset lf] ; => NO! - ; alternative 1: - ; sz/x: (as integer! evt-sizing/x_root) - offset/x - ; sz/y: (as integer! evt-sizing/y_root) - offset/y - - ; alternative 2: - ; sz/x: gtk_widget_get_allocated_width widget - ; sz/y: gtk_widget_get_allocated_height widget - - ;; DEBUG: print ["event-size: " sz/x "x" sz/y " vs " offset/x "x" offset/y lf] as red-value! sz ] any [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c054c3614d..fcf11c952a 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -10,16 +10,6 @@ Red/System [ } ] -gtk-app-activate: func [ - [cdecl] - app [handle!] - data [int-ptr!] - /local - win [handle!] -][ - probe "active" -] - set-selected: func [ obj [handle!] ctx [node!] @@ -332,26 +322,8 @@ window-configure-event: func [ ;; DEBUG: print ["offset: " x "x" y lf] offset/x: x offset/y: y - sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size - ; either any [event/width <> sz/x event/height <> sz/y] [ - ; ;if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ - ; evt-motion/x_new: event/width - ; evt-motion/y_new: event/height - ; evt-motion/x_root: as float! event/x - ; evt-motion/y_root: as float! event/y - ; make-event widget 0 EVT_SIZE - ; ;] - ; ;evt-motion/cpt: evt-motion/cpt + 1 - ; yes - ; ][no] + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE if any [event/width <> sz/x event/height <> sz/y] [ - ; evt-sizing/x_new: event/width - ; evt-sizing/y_new: event/height - ; sz/x: evt-sizing/x_new - ; sz/y: evt-sizing/y_new - ; ;; DEBUG: print ["window-size-allocate: " evt-sizing/x_root "x" evt-sizing/y_root lf] - ; evt-sizing/x_root: as float! event/x - ; evt-sizing/y_root: as float! event/y make-event widget 0 EVT_SIZE ] ] @@ -365,17 +337,9 @@ window-size-allocate: func [ sz [red-pair!] ][ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] - sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE ;-- update face/size + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE if any [rect/width <> sz/x rect/height <> sz/y] [ - evt-sizing/x_new: rect/width - evt-sizing/y_new: rect/height - ;; DEBUG: print ["sz: " sz/x "x" sz/y " -> " evt-sizing/x_new "x" evt-sizing/y_new lf] - sz/x: evt-sizing/x_new - sz/y: evt-sizing/y_new - ;; DEBUG: print ["window-size-allocate: " evt-sizing/x_root "x" evt-sizing/y_root lf] - evt-sizing/x_root: as float! rect/x - evt-sizing/y_root: as float! rect/y - make-event widget 0 EVT_SIZING + make-event widget 0 EVT_SIZING ] ] From 46fafc8b969bb1af2a6f94f7125b2d2c83d578e6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 5 Sep 2019 08:51:02 +0800 Subject: [PATCH 0155/3432] FIX: window widget can get focus/unfocus event --- modules/view/backends/gtk3/events.reds | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 4f00194abb..dd93b6e35c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -699,6 +699,20 @@ connect-common-events: function [ ] ] +connect-focus-events: function [ + widget [handle!] + face [red-object!] + actors [red-object!] + sym [integer!] +][ + if respond-event? actors on-focus [ + gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) + ] + if respond-event? actors on-unfocus [ + gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) + ] +] + connect-notify-events: function [ widget [handle!] face [red-object!] @@ -757,8 +771,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) - gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) + connect-focus-events widget face actors sym ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] @@ -767,6 +780,7 @@ connect-widget-events: function [ gobj_signal_connect(widget "configure-event" :window-configure-event null) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate null) + connect-focus-events widget face actors sym ] sym = slider [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] @@ -779,8 +793,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) - gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) + connect-focus-events widget face actors sym ] sym = progress [ 0 @@ -798,8 +811,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) - gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) + connect-focus-events widget face actors sym ] sym = group-box [ 0 From 54aadf8e5b2e4d41b307c9d897932d2ab5a9e6a2 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 5 Sep 2019 09:06:12 +0800 Subject: [PATCH 0156/3432] FIX: put mouse callback together --- modules/view/backends/gtk3/handlers.reds | 136 +++++++++++------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index fcf11c952a..ccd3cae690 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -539,74 +539,6 @@ focus-out-event: func [ make-event widget 0 EVT_UNFOCUS ] -mouse-button-release-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - sym [integer!] - x [integer!] - y [integer!] - sel [red-pair!] - buffer [handle!] - start [GtkTextIter! value] - end [GtkTextIter! value] - flags [integer!] - ev [integer!] -][ - if draggable? widget [return 0] ; delegate to drag - - sym: get-widget-symbol widget - if sym = field [ - if event/button = GDK_BUTTON_PRIMARY [ - x: -1 y: -1 - if gtk_editable_get_selection_bounds widget :x :y [ - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y - ] - make-event widget 0 EVT_SELECT - ] - ] - ] - if sym = area [ - if event/button = GDK_BUTTON_PRIMARY [ - buffer: gtk_text_view_get_buffer widget - if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ - x: -1 y: -1 - x: gtk_text_iter_get_offset as handle! start - y: gtk_text_iter_get_offset as handle! end - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y - ] - make-event widget 0 EVT_SELECT - ] - ] - ] - evt-motion/state: yes - evt-motion/cpt: 0 - evt-motion/x_root: event/x_root - evt-motion/y_root: event/y_root - evt-motion/x_new: as-integer event/x - evt-motion/y_new: as-integer event/y - flags: check-flags event/type event/state - ev: case [ - event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] - event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] - true [EVT_LEFT_UP] - ] - make-event widget flags ev -] - area-changed: func [ [cdecl] buffer [handle!] @@ -821,6 +753,74 @@ container-delegate-to-children: func [ EVT_DISPATCH ] +mouse-button-release-event: func [ + [cdecl] + widget [handle!] + event [GdkEventButton!] + ctx [node!] + return: [integer!] + /local + sym [integer!] + x [integer!] + y [integer!] + sel [red-pair!] + buffer [handle!] + start [GtkTextIter! value] + end [GtkTextIter! value] + flags [integer!] + ev [integer!] +][ + if draggable? widget [return 0] ; delegate to drag + + sym: get-widget-symbol widget + if sym = field [ + if event/button = GDK_BUTTON_PRIMARY [ + x: -1 y: -1 + if gtk_editable_get_selection_bounds widget :x :y [ + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT + ] + ] + ] + if sym = area [ + if event/button = GDK_BUTTON_PRIMARY [ + buffer: gtk_text_view_get_buffer widget + if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ + x: -1 y: -1 + x: gtk_text_iter_get_offset as handle! start + y: gtk_text_iter_get_offset as handle! end + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT + ] + ] + ] + evt-motion/state: yes + evt-motion/cpt: 0 + evt-motion/x_root: event/x_root + evt-motion/y_root: event/y_root + evt-motion/x_new: as-integer event/x + evt-motion/y_new: as-integer event/y + flags: check-flags event/type event/state + ev: case [ + event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] + event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] + true [EVT_LEFT_UP] + ] + make-event widget flags ev +] + mouse-button-press-event: func [ [cdecl] widget [handle!] From 1c9748021b0e6a01a4b8cbd842889848a5347ffa Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 23 Sep 2019 20:17:39 +0300 Subject: [PATCH 0157/3432] FIX: issues #2244 (Inconsistent trigonometry with 1.#inf) and #3441 (TANGENT 90 should return infinity) --- runtime/natives.reds | 23 ++++---- tests/source/units/float-test.red | 87 +++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 15 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 257ff80f9f..d91e5ae3e4 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1662,10 +1662,15 @@ natives: context [ ][ #typecheck [tangent radians] f: degree-to-radians* radians TYPE_TANGENT - either (float/abs f/value) = (PI / 2.0) [ - fire [TO_ERROR(math overflow)] + + either f/value = (PI / 2.0) [ ;-- see #3441 on `tangent 90` handling + f/value: 1.0 / 0.0 ][ - f/value: tan f/value + either f/value = (PI / -2.0) [ + f/value: -1.0 / 0.0 + ][ + f/value: tan f/value + ] ] f ] @@ -2897,14 +2902,10 @@ natives: context [ f: argument-as-float d: f/value - either all [type <> TYPE_TANGENT any [d < -1.0 d > 1.0]] [ - fire [TO_ERROR(math overflow)] - ][ - f/value: switch type [ - TYPE_SINE [asin d] - TYPE_COSINE [acos d] - TYPE_TANGENT [atan d] - ] + f/value: switch type [ + TYPE_SINE [asin d] + TYPE_COSINE [acos d] + TYPE_TANGENT [atan d] ] if radians < 0 [f/value: f/value * 180.0 / PI] ;-- to degrees diff --git a/tests/source/units/float-test.red b/tests/source/units/float-test.red index 50b53d714b..59b63ebc59 100644 --- a/tests/source/units/float-test.red +++ b/tests/source/units/float-test.red @@ -36,7 +36,15 @@ Red [ --assert 0.0 = cosine 90 --test-- "float-cosine-3" - ;--assert 0.0 = cosine/radians pi / 2 + --assert 0.0 = cosine/radians pi / 2 + + --test-- "float-cosine-4" + --assert nan? cosine 1.#inf + --assert nan? cosine -1.#inf + + --test-- "float-cosine-5" + --assert nan? cosine 1.#nan + --test-- "float-sine-1" --assertf~= 0.0 sine/radians pi 1E-13 @@ -44,23 +52,69 @@ Red [ --test-- "float-sine-2" --assert 1 = sine 90 + --test-- "float-sine-3" + --assert nan? sine 1.#inf + --assert nan? sine -1.#inf + + --test-- "float-sine-4" + --assert nan? sine 1.#nan + + --test-- "float-tangent-1" --assert 0.0 = tangent/radians 0 --test-- "float-tangent-2" --assert -1 = tangent 135 + --test-- "float-tangent-3" + --assert nan? tangent 1.#inf + --assert nan? tangent -1.#inf + + --test-- "float-tangent-4" + --assert nan? tangent 1.#nan + + --test-- "float-tangent-5" ;-- see #3441 + --assert 1.#inf = tangent 90 + --assert -1.#inf = tangent -90 + --assert 1e10 < tangent 90.0 - 1e-10 + --assert -1e10 > tangent 90.0 + 1e-10 + --assert -1e10 > tangent -90.0 + 1e-10 + --assert 1e10 < tangent -90.0 - 1e-10 + + --test-- "float-arcsine-1" --assertf~= -1.5707963267949 arcsine/radians -1 1E-13 --test-- "float-arcsine-2" --assert 90 = arcsine 1 + --test-- "float-arcsine-3" + --assert nan? arcsine 2 + + --test-- "float-arcsine-4" + --assert nan? arcsine 1.#inf + --assert nan? arcsine -1.#inf + + --test-- "float-arcsine-5" + --assert nan? arcsine 1.#nan + + --test-- "float-arccosine-1" --assertf~= 1.5707963267949 arccosine/radians 0 1E-13 --test-- "float-arccosine-2" --assert 90 = arccosine 0 + + --test-- "float-arccosine-3" + --assert nan? arccosine 2 + + --test-- "float-arccosine-4" + --assert nan? arccosine 1.#inf + --assert nan? arccosine -1.#inf + + --test-- "float-arccosine-5" + --assert nan? arccosine 1.#nan + --test-- "float-arctangent-1" --assertf~= -0.785398163397448 arctangent/radians -1 1E-13 @@ -68,27 +122,52 @@ Red [ --test-- "float-arctangent-2" --assert 45 = arctangent 1 - --test-- "float-arctangent2" + --test-- "float-arctangent-3" + --assert 90 = arctangent 1.#inf + --assert -90 = arctangent -1.#inf + + --test-- "float-arctangent-4" + --assert nan? arctangent 1.#nan + + --test-- "float-arctangent-5" + --assert 90.0 = arctangent tangent 90 + --assert -90.0 = arctangent tangent -90 + + + --test-- "float-arctangent2-1" --assertf~= 3.1415926535898 atan2 0 -1 1E-13 --assertf~= 3.1415926535898 atan2 0.0 -1.0 1E-13 --assertf~= -1.5707963267949 atan2 -1 0 1E-13 --assertf~= -0.78539816339745 atan2 -1 1 1E-13 --assertf~= -0.78539816339745 atan2 -1.5 1.5 1E-13 - --test-- "float-arctangent3" + --test-- "float-arctangent2-2" --assertf~= 3.1415926535898 arctangent2/radians 0 -1 1E-13 --assertf~= 3.1415926535898 arctangent2/radians 0.0 -1.0 1E-13 --assertf~= -1.5707963267949 arctangent2/radians -1 0 1E-13 --assertf~= -0.78539816339745 arctangent2/radians -1 1 1E-13 --assertf~= -0.78539816339745 arctangent2/radians -1.5 1.5 1E-13 - --test-- "float-arctangent4" + --test-- "float-arctangent2-3" --assertf~= 180.0 arctangent2 0 -1 1E-13 --assertf~= 180.0 arctangent2 0.0 -1.0 1E-13 --assertf~= -90.0 arctangent2 -1 0 1E-13 --assertf~= -45.0 arctangent2 -1 1 1E-13 --assertf~= -45.0 arctangent2 -1.5 1.5 1E-13 + --test-- "float-arctangent2-4" + --assert nan? arctangent2 1 1.#nan + --assert nan? arctangent2 1.#nan 1 + + --test-- "float-arctangent2-5" + --assert nan? arctangent2 1.#inf 1.#inf + --assert 90.0 = arctangent2 1.#inf 1 + --assert 90.0 = arctangent2 1.#inf 0 + --assert 90.0 = arctangent2 1.#inf -1 + --assert -90.0 = arctangent2 -1.#inf -1 + --assert -90.0 = arctangent2 -1.#inf 0 + --assert -90.0 = arctangent2 -1.#inf 1 + ===end-group=== ===start-group=== "float function arguments" From 601b24712a983bd85677bedffceaf539d29d3294 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 25 Sep 2019 21:45:27 +0200 Subject: [PATCH 0158/3432] FEAT: preliminary work on a faster run-time lexer. --- runtime/tokenizer.reds | 170 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/runtime/tokenizer.reds b/runtime/tokenizer.reds index f1ed1d3c8c..3ed3a2f135 100644 --- a/runtime/tokenizer.reds +++ b/runtime/tokenizer.reds @@ -12,6 +12,176 @@ Red/System [ tokenizer: context [ + ;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations + + utf8d: [ ;[byte! 8] + ; The first part of the table maps bytes to character classes that + ; to reduce the size of the transition table and create bitmasks. + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 + 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 + 8 8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 10 3 3 3 3 3 3 3 3 3 3 3 3 4 3 3 11 6 6 6 5 8 8 8 8 8 8 8 8 8 8 8 + + ; The second part is a transition table that maps a combination + ; of a state of the automaton and a character class to a state. + 0 12 24 36 60 96 84 12 12 12 48 72 12 12 12 12 12 12 12 12 12 12 12 12 + 12 0 12 12 12 12 12 0 12 0 12 12 12 24 12 12 12 12 12 24 12 24 12 12 + 12 12 12 12 12 12 12 24 12 12 12 12 12 24 12 12 12 12 12 12 12 24 12 12 + 12 12 12 12 12 12 12 36 12 36 12 12 12 36 12 12 12 12 12 36 12 36 12 12 + 12 36 12 12 12 12 12 12 12 12 12 12 + ] + + decode-utf8-char: func [ + p [byte-ptr!] + cp [int-ptr!] + return: [byte-ptr!] + /local + state [integer!] + byte [integer!] + idx [integer!] + type [integer!] + ][ + state: 0 + forever [ + byte: as-integer p/value + idx: byte + 1 + type: utf8d/idx + + idx: 256 + state + type + 1 + state: utf8d/idx + + switch state [ + 0 [ ;-- ACCEPT + cp/value: FFh >> type and byte + return p + 1 + ] + 12 [ ;-- REJECT + cp/value: -1 + return p + ] + default [ + cp/value: byte and 3Fh or (cp/value << 6) + p: p + 1 + ] + ] + ] + as byte-ptr! 0 ;-- never reached, just make compiler happy + ] + + scanner!: alias function! [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!]] + + + scan-string: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-alt-string: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-block: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-paren: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-comment: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-file: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-refinement: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-money: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-lesser: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-lit: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + scan-get: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + ; /local + ][ + s + ] + + value-1st: [ + #"^"" :scan-string + #"{" :scan-alt-string + #"[" :scan-block + #"(" :scan-paren + #";" :scan-comment + #"%" :scan-file + #"/" :scan-refinement + #"$" :scan-money + #"<" :scan-lesser + #"'" :scan-lit + #":" :scan-get + ;[#"0" - #"9"] :scan-digit + ;else :scan-word + ] + + scan-token: func [ + src [byte-ptr!] + len [integer!] + /local + p [byte-ptr!] + end [byte-ptr!] + cp [integer!] + res [int-ptr!] + action [scanner!] + ][ + p: src + end: p + len + + while [p < end][ + cp: as-integer p/value + res: as int-ptr! value-1st/cp + either null? res [ + p: p + 1 + ][ + action: as scanner! res + p: action p + 1 end + ] + ] + ] + scan-integer: func [ p [byte-ptr!] len [integer!] From 1aebd9b83d669b062093585dfcadad982d5dd8b5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 26 Sep 2019 12:36:31 +0200 Subject: [PATCH 0159/3432] FEAT: adds state management and `scan` entry point function. --- runtime/tokenizer.reds | 132 +++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 38 deletions(-) diff --git a/runtime/tokenizer.reds b/runtime/tokenizer.reds index 3ed3a2f135..ad9d7abbf0 100644 --- a/runtime/tokenizer.reds +++ b/runtime/tokenizer.reds @@ -72,73 +72,103 @@ tokenizer: context [ as byte-ptr! 0 ;-- never reached, just make compiler happy ] - scanner!: alias function! [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!]] + #enum errors! [ + LEX_ERR_STRING: 1 + + LEX_ERROR ;-- keep it last + ] + + state!: alias struct! [ + parent [red-block!] ;-- any-block! accepted + head [byte-ptr!] + tail [byte-ptr!] + pos [byte-ptr!] + err [integer!] + ] + + scanner!: alias function! [state [state!] return: [byte-ptr!]] - scan-string: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] - ; /local + scan-string: func [state [state!] return: [byte-ptr!] + /local + p [byte-ptr!] + e [byte-ptr!] + c [byte!] ][ - s + p: state/pos + e: state/tail + while [c: p/value all [p < e c <> #"^""]][ + either c = #"^^" [p: p + 2][ + if c = #"^/" [state/pos: p throw LEX_ERR_STRING] + p: p + 1 + ] + ] + + e: p + p: state/pos + ;decode/converte the string + + p ] - scan-alt-string: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-alt-string: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-block: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-block: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-paren: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-paren: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-comment: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-comment: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-file: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-file: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-refinement: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-refinement: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-money: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-money: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-lesser: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-lesser: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-lit: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-lit: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] - scan-get: func [s [byte-ptr!] end [byte-ptr!] return: [byte-ptr!] + scan-get: func [state [state!] return: [byte-ptr!] ; /local ][ - s + null ] value-1st: [ @@ -157,29 +187,55 @@ tokenizer: context [ ;else :scan-word ] - scan-token: func [ - src [byte-ptr!] - len [integer!] + scan-tokens: func [ + state [state!] /local - p [byte-ptr!] - end [byte-ptr!] - cp [integer!] - res [int-ptr!] - action [scanner!] + parent [red-block!] + p [byte-ptr!] + e [byte-ptr!] + cp [integer!] + res [int-ptr!] + s [series!] + do-scan [scanner!] ][ - p: src - end: p + len + parent: state/parent + s: GET_BUFFER(parent) + p: state/pos + e: state/tail + cp: 0 - while [p < end][ - cp: as-integer p/value + while [p < e][ + p: decode-utf8-char p :cp res: as int-ptr! value-1st/cp either null? res [ p: p + 1 ][ - action: as scanner! res - p: action p + 1 end + do-scan: as scanner! res + state/pos: p + 1 + p: do-scan state ] ] + state/pos: p + ] + + scan: func [ + dst [red-block!] ;-- destination block + src [byte-ptr!] ;-- UTF-8 buffer + len [integer!] ;-- buffer size in bytes + /local + stack [red-block!] + state [state! value] + ][ + state/parent: block/make-in dst 100 + state/head: src + state/tail: src + len + state/pos: src + state/err: 0 + + catch LEX_ERROR [scan-tokens state] + if system/thrown > 0 [ + 0 ; error handling + ] ] scan-integer: func [ From 7ab5ed4f006a6803221867c29063a3c230d73b0f Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Fri, 27 Sep 2019 14:47:09 +0300 Subject: [PATCH 0160/3432] FIX: removed leftover conditions after #3649 was fixed --- tests/source/units/draw-test.red | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/source/units/draw-test.red b/tests/source/units/draw-test.red index 87eaf118a7..c963dc1b34 100644 --- a/tests/source/units/draw-test.red +++ b/tests/source/units/draw-test.red @@ -40,18 +40,11 @@ do [if all [system/view value? 'image! datatype? get 'image!] [ --test-- "dwim1" --assert i = draw i/size [image i] --test-- "dwim2" --assert i = draw i/size [matrix [1 0 0 1 0 0] image i] - ; FIXME: #3649 - unless system/platform = 'macOS [ --test-- "dwim3" --assert i' = draw i/size [matrix [0 1 -1 0 4 0] image i] ; clockwise rot 90 - ] - --test-- "dwim4" --assert i = draw i/size [matrix [0 -1 1 0 0 4] image i'] ; counter-clockwise - ; FIXME: #3649 - unless system/platform = 'macOS [ --test-- "dwim5" --assert i' = draw i/size [reset-matrix matrix [0 1 -1 0 4 0] image i] --test-- "dwim6" --assert i = draw i/size [reset-matrix matrix [0 -1 1 0 0 4] image i'] - ] --test-- "dwim7" --assert i'' = draw i/size [clip 1x1 4x4 image i'] --test-- "dwim8" --assert i'' = draw i/size [clip 1x1 4x4 matrix [0 1 -1 0 4 0] image i] From ee9e8e0b50f5794ce61cf890cd26551719b3a6b8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Sep 2019 22:06:43 +0200 Subject: [PATCH 0161/3432] FEAT: extends lexer table structure and content. --- runtime/tokenizer.reds | 137 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 17 deletions(-) diff --git a/runtime/tokenizer.reds b/runtime/tokenizer.reds index ad9d7abbf0..46bb5296bf 100644 --- a/runtime/tokenizer.reds +++ b/runtime/tokenizer.reds @@ -79,11 +79,14 @@ tokenizer: context [ ] state!: alias struct! [ - parent [red-block!] ;-- any-block! accepted - head [byte-ptr!] - tail [byte-ptr!] - pos [byte-ptr!] - err [integer!] + parent [red-block!] ;-- any-block! accepted + buffer [red-value!] ;-- special buffer for hatching any-blocks + buf-head [red-value!] + buf-tail [red-value!] + head [byte-ptr!] + tail [byte-ptr!] + pos [byte-ptr!] + err [integer!] ] scanner!: alias function! [state [state!] return: [byte-ptr!]] @@ -128,6 +131,12 @@ tokenizer: context [ ][ null ] + + scan-paren-close: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] scan-comment: func [state [state!] return: [byte-ptr!] ; /local @@ -171,21 +180,104 @@ tokenizer: context [ null ] - value-1st: [ + scan-sharp: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + #enum lexer-categories! [ + LEX_EOF + LEX_BLANK + LEX_COMMA + LEX_COLON + LEX_NUMBER + LEX_WORD + ] + + lex-table-template: [ + ;--- Code ------- 1st char ------------ Nth char --- + #"^(00)" LEX_EOF + #"^(01)" LEX_NO_OP + #"^(02)" LEX_NO_OP + #"^(03)" LEX_NO_OP + #"^(04)" LEX_NO_OP + #"^(05)" LEX_NO_OP + #"^(06)" LEX_NO_OP + #"^(07)" LEX_NO_OP + #"^(08)" LEX_NO_OP + #"^(09)" LEX_BLANK ;-- TAB + #"^(0A)" LEX_BLANK ;-- LF + #"^(0B)" LEX_NO_OP + #"^(0C)" LEX_NO_OP + #"^(0D)" LEX_BLANK ;-- CR + #"^(0E)" LEX_NO_OP + #"^(0F)" LEX_NO_OP + #"^(10)" LEX_NO_OP + #"^(11)" LEX_NO_OP + #"^(12)" LEX_NO_OP + #"^(13)" LEX_NO_OP + #"^(14)" LEX_NO_OP + #"^(15)" LEX_NO_OP + #"^(16)" LEX_NO_OP + #"^(17)" LEX_NO_OP + #"^(18)" LEX_NO_OP + #"^(19)" LEX_NO_OP + #"^(1A)" LEX_NO_OP + #"^(1B)" LEX_NO_OP + #"^(1C)" LEX_NO_OP + #"^(1D)" LEX_NO_OP + #"^(1E)" LEX_NO_OP + #"^(1F)" LEX_NO_OP + #"^(10)" LEX_NO_OP + + #" " LEX_BLANK ;-- space + #"!" LEX_WORD #"^"" :scan-string - #"{" :scan-alt-string - #"[" :scan-block - #"(" :scan-paren - #";" :scan-comment - #"%" :scan-file - #"/" :scan-refinement + #"#" :scan-sharp #"$" :scan-money - #"<" :scan-lesser + #"%" :scan-file + #"&" LEX_WORD #"'" :scan-lit + #"(" :scan-paren + #")" :scan-paren-close + #"*" LEX_WORD + #"+" LEX_WORD + #"," LEX_COMMA + #"-" LEX_WORD + #"." LEX_WORD + #"/" :scan-refinement + + #"0" LEX_NUMBER + #"1" LEX_NUMBER + #"2" LEX_NUMBER + #"3" LEX_NUMBER + #"4" LEX_NUMBER + #"5" LEX_NUMBER + #"6" LEX_NUMBER + #"7" LEX_NUMBER + #"8" LEX_NUMBER + #"9" LEX_NUMBER + #":" :scan-get + #";" :scan-comment + #"<" :scan-lesser + #"=" LEX_WORD + #">" LEX_WORD + #"?" LEX_WORD + + + + #"{" :scan-alt-string + #"[" :scan-block + + + ;[#"0" - #"9"] :scan-digit ;else :scan-word ] + + lex-table: as int-ptr! 0 ;-- table created at run-time scan-tokens: func [ state [state!] @@ -194,7 +286,7 @@ tokenizer: context [ p [byte-ptr!] e [byte-ptr!] cp [integer!] - res [int-ptr!] + res [integer!] s [series!] do-scan [scanner!] ][ @@ -205,9 +297,13 @@ tokenizer: context [ cp: 0 while [p < e][ - p: decode-utf8-char p :cp - res: as int-ptr! value-1st/cp - either null? res [ + while [ ;-- skip all head blanks + cp: as-integer p/value + lex-table/cp = LEX_BLANK + ][p: p + 1] + + res: lex-table/cp + either res < 1000 [ p: p + 1 ][ do-scan: as scanner! res @@ -227,6 +323,9 @@ tokenizer: context [ state [state! value] ][ state/parent: block/make-in dst 100 + state/buffer: as cell! alloc-big 1000 * size? cell! + state/buf-head: state/buffer + state/buf-tail: state/buffer + 1000 state/head: src state/tail: src + len state/pos: src @@ -237,6 +336,10 @@ tokenizer: context [ 0 ; error handling ] ] + + init: func [][ + + ] scan-integer: func [ p [byte-ptr!] From ae66455fe27e2bb27acb0be7aed45fd3a1c1b1fb Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 30 Sep 2019 21:26:01 +0200 Subject: [PATCH 0162/3432] FEAT: preliminary documentation of lexical scanner's states. --- docs/lexer-FSM.xlsx | Bin 0 -> 15270 bytes docs/lexer-states.txt | 246 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 docs/lexer-FSM.xlsx create mode 100644 docs/lexer-states.txt diff --git a/docs/lexer-FSM.xlsx b/docs/lexer-FSM.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..601e41afcccccd7061d799c9e9b5bc3683132fb5 GIT binary patch literal 15270 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 literal 0 HcmV?d00001 diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt new file mode 100644 index 0000000000..cea9db3ac3 --- /dev/null +++ b/docs/lexer-states.txt @@ -0,0 +1,246 @@ + +S_START +S_BLANK +S_LINE_CMT +S_LINE_STR +S_SKIP_STR +S_M_STRING +S_SKIP_MSTR +S_FILE_1ST +S_FILE +S_SKIP_FILE +S_SLASH +S_SHARP +S_BINARY +S_LINE_CMT2 +S_CHAR +S_SKIP_CHAR +S_CONSTRUCT +S_ISSUE +S_NUMBER +S_DECIMAL +S_DEC_SPECIAL +S_TUPLE +S_DATE +S_TIME_1ST +S_TIME +S_PAIR_1ST +S_PAIR +S_EMAIL +S_MONEY_1ST +S_MONEY +S_MONEY_DEC +S_LESSER +S_TAG +S_TAG_STR +S_SKIP_STR2 +S_TAG_STR2 +S_SKIP_STR3 +S_SIGN +S_WORD +S_URL +S_EMAIL + +---S_FINAL_STATES--- +T_EOF +T_ERROR +T_BLK_OP +T_BLK_CL +T_PAR_OP +T_PAR_CL +T_STRING +T_STR_ALT +T_WORD +T_FILE +T_REFINE +T_BINARY +T_CHAR +T_MAP_OP +T_CONS_MK +T_ISSUE +T_PERCENT +T_INTEGER +T_FLOAT +T_TUPLE +T_DATE +T_TIME +T_MONEY +T_TAG +T_URL +T_EMAIL +T_PATH + + +C_BLANK : space, tab, cr +C_LINE : lf +C_DIGIT : 1-9 +C_ZERO : 0 +C_BLOCK_OP : [ +C_BLOCK_CL : ] +C_PAREN_OP : [ +C_PAREN_CL : ] +C_STRING_OP : { +C_STRING_CL : } +C_DBL_QUOTE : " +C_SHARP : # +C_QUOTE : ' +C_COLON : : +C_X : x, X +C_EXP : e, E +C_ALPHAX : a-f, A-F +C_SLASH : / +C_BSLASH : \ +C_LESSER : < +C_GREATER : > +C_PERCENT : % +C_COMMA : , +C_SEMICOL : ; +C_AT : @ +C_DOT : . +C_MONEY : $ +C_SIGN : +, - +C_CARET : ^ +C_EOF : NUL +C_UCS2 : 0xC2-0xDF, 0xE0-EF +C_UCS4 : 0xF0-0xF4 +C_ILLEGAL : 0xC0-0xC1, 0xF5-0xFF +C_NO_OP : 0x01-0x08, 0x11, 0x12, 0x14-0x1F +C_WORD : all the rest + + +;":"->S_CLASS_GET => set as high-bits flag +;"'"->S_CLASS_LIT => set as high-bits flag + + + +ws: space | tab | cr | lf +dbl-quote: " + +delimit1: [ | ] | ( | ) | { | } | " | : | ws | ; | @ +delimit2: [ | ] | ( | ) | { | } | " | : | ws | ; | < +delimit3: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # +delimit4: < | > | = +delimit5: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : +delimit6: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | 0-9 +delimit7: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | \ | ^ | , +delimit8: [ | ] | ( | ) | { | } | : | ws | ; | @ +delimit9: ] | ) | } | " | : | < | > | , + +hexa: C_ZERO | C_DIGIT | C_ALPHAX + + +S_START->ws->S_BLANK->ws->S_BLANK + \->not(ws)->S_START + +S_START->";"->S_LINE_CMT->not(lf)->S_LINE_CMT + \->lf->S_START + +S_START->"["->T_BLK_OP +S_START->"]"->T_BLK_CL +S_START->"("->T_PAR_OP +S_START->")"->T_PAR_CL + +S_START->dbl-quote->S_LINE_STR->not("^"|dbl-quote)->S_LINE_STR + \->"^"->S_SKIP_STR->*->S_LINE_STR + \->dbl-quote->T_STRING + +S_START->"{"->S_M_STRING->not("^"|"}")->S_M_STRING + \->"^"->S_SKIP_MSTR->*->S_M_STRING + \->"}"->T_STR_ALT + +S_START->"/"->S_SLASH->not(delimit1)->S_SLASH + \->delimit1->T_REFINE + +S_START->"%"->S_FILE_1ST->not(delimit8)->S_FILE->not(delimit1)->S_FILE + \ \->"^"->S_SKIP_FILE->*->S_FILE + \ \->delimit1->T_FILE + \->delimit8->T_WORD + + +S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY + \ \->";"->S_LINE_CMT2->not(lf)->S_LINE_CMT2 + \ \ \->lf->S_BINARY + \ \ + \ \->"}"->T_BINARY + \ + \->dbl-quote->S_CHAR->not("^"|dbl-quote)->S_CHAR + \ \->"^"->S_SKIP_CHAR->*->S_CHAR + \ \->dbl-quote->T_CHAR + \ + \->"("->T_MAP_OP + \ + \->"["->S_CONSTRUCT->not("]")->S_CONSTRUCT + \ \->"]"->T_CONS_MK + \ + \->not(delimit9)->S_ISSUE->not(delimit1)->S_ISSUE + \ \->delimit1->T_ISSUE + \->delimit9->T_ERROR + +S_START->digit->S_NUMBER->digit->S_NUMBER + \->delimit2->T_INTEGER + \->"%"->T_PERCENT + \->"."->S_DECIMAL->digit|"e"|"E"->S_DECIMAL->"%"->T_PERCENT + \ \->delimit2->T_FLOAT + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->"#"->S_DEC_SPECIAL->not(delimit6)->S_DEC_SPECIAL + \ \ \->delimit6->T_FLOAT + \ \->"."->S_TUPLE->digit|"."->S_TUPLE + \ \ \->delimit2->T_TUPLE + \ \->else->T_ERROR + \ + \->"/"->S_DATE->not(delimit2)->S_DATE + \ \->delimit2->T_DATE + \ + \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME + \ \->else->T_ERROR \->delimit3->T_TIME + \ \->else->T_ERROR + \ + \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit2->T_PAIR + \ \->else->T_ERROR + \->"#"->S_SHARP + \ + \->"@"->S_EMAIL + \ + \->else->T_ERROR + + +S_START->"<"->S_LESSER + \->delimit1|">"->T_WORD + \->delimit4->T_ERROR + \->else->S_TAG + \->dbl-quote->S_TAG_STR->not("^"|dbl-quote)->S_TAG_STR + \ \->"^"->S_SKIP_STR2->*->S_TAG_STR + \ \->dbl-quote->S_TAG + \ + \->"'"->S_TAG_STR2->not("^"|"'")->S_TAG_STR2 + \ \->"^"->S_SKIP_STR3->*->S_TAG_STR2 + \ \->"'"->S_TAG + \ + \->">"->T_TAG + + +S_START->"+"|"-"->S_SIGN->digit->S_NUMBER + \->S_WORD + + +S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit->S_MONEY + \->else->T_ERROR \->"."->S_MONEY_DEC->digit->S_MONEY_DEC + \ \->delimit3->T_MONEY + \ \->else->T_ERROR + \ + \->delimit3->T_MONEY + \->else->T_ERROR + + +S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD + \->delimit7->T_WORD + \ + \->":"->S_URL->not(delimit7)->S_URL + \ \->delimit7->T_URL + \ + \->"@"->S_EMAIL->not(delimit5)->S_EMAIL + \ \->delimit5->T_EMAIL + \ + \->"/"->T_PATH From 8362488bfc8393c15320a3bbcb3dd30c754ba8b1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 1 Oct 2019 00:30:00 +0200 Subject: [PATCH 0163/3432] FIX: some fixes to the lexical scanner FSM. --- docs/lexer-FSM.xlsx | Bin 15270 -> 18093 bytes docs/lexer-states.txt | 29 ++++++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/lexer-FSM.xlsx b/docs/lexer-FSM.xlsx index 601e41afcccccd7061d799c9e9b5bc3683132fb5..a88acbf24810b593c92c89192f0db42c94eef942 100644 GIT binary patch literal 18093 zcmeHv1zTL%vUcMV+=9D%aCZVU?hZj32`<4cxVr>*2pZf21PLD8-7Q#f|2mmDXJ&HF zeeMtV?uPF5tloPSMXjp$t!1qw3k8h@fCaz<001%oS>$UzCkOx_5(WUk1i(Y;ird*b zgKV7*)!gktPWsGlHrAwh(2%q_07&rj|9Aa=Y=IuN0oyKCw9lFc!V>KoVeiG&)uB=J zqnR)+pyUL|aKdcdVG(^-!?e}Z8O2C1<7umRZLZ{eo8BInB0xmdHt(4c#rZL1aJeK$ zd>Zh)qr{*D)t6=l>6JtD+S~iiW|s@T>6*rIQbxZur>p*$qx^vvHCYq*5?}HG&upU1 zxYCT&GxJ+MV+K`KqDllA?4u^_bY9VxO>YM`u;^>}7O3`9;b72@cCH|D9QqWEXEGUm z?KH?b1{`E@^F1iqC~N@dyPW`|udJ}-T)|?*TS!WqpaNY@Jk8feT6i(2){pSwt&U66 z4aW&F6u8I((lB>Q$et->IzFwe*?ioi3ITff@{zPwiPikeG&h@OiD%QFt7B&jq1%*xqD-w??gHjyhC<7+>FWD{lI`N5);;H;o=0*QLVVYHbV@v8&@plH>5gO z|5i8C1J+*z_G-jqZ{h^c{X&n3zphq3K&X>xlac5F>}Jo;PynTW#A>}dE5!x)jvP1? zUw~uP&=F+q#KQdZ{r_V0|Kq^?+rM5OFR$3miWGbz{SeZBJ-r-@CMN4DD&0z^=Hn-` zgjye!Pf4)cK|_e9h93YW<@?#^VQ_I-AnKr>>}rFfJOTrYpQ6FFA~@yF;T;@3wPW&Y zhw}9vbeHMN>8n&JpgXP0=NS63rjNO@1FICTC(k6R(MFjy@ewc!34?J2Q{U@+mDgS| zzNv(m7E?W{2(D`6&N)aJP4}HmF4{*H4&{~mK9P#u?__K~U+L9vO?G*UudZsrYguKS z<;X|wZfI)Vc`lLOf%)jgq>$0CLe7D4!!|0_N0oEwt5e5uHk9e!!;R2g)_*$SA3^eQ z1x#E286>ajFzo8V0ipy80HA^`<7Um`YUgNWY-eZnlgtX##}yV?vAnbEd_y0IF%tz$&=vbq2XH+y500)>b{aDqY5YSoW zuQ^3nk|rBEoK*QSDAxeGXeMK)Xl+RYB+|u-Ku=G(Kw5Aoi2GLPWn>Jt6+QD2ti*Y| zPL3U-aym+d@yYwLk3JS}vr9^0LsMykysbs!G^?F!Vu6#|2sN`jS2OrR2wo2G$onq- zV_!6q-ss?QHcA1Atffiz`i%U}%CO2&olb=cXve(hmhfz~_qPJd_tz?);=q$g4u(SvrHsg4z(b_k; z_C9lnIW=jmv5X-yf#@<*W#7K|G!6=Wz3)7nGRcso=+ryxJQ{m3_V{chGnnxW5NO+P zy|Nk(tH5_;?P^&Mcam_1D*ec*-zD1V09A37r9e8_3uqB)~A4PF(cH5n*Y5mxv z?`wxgFTyw6#Lpm!S2;h?!g>-eiXrMPt|V04+HoYkuIoh`Y$&T^ zzEmo8KH!>2AmlH+7jAYb^YAQN_ijzAd%fpkTxV)8tT&rwfz?ZCtLf|u+uZ^7-~aS* zU`dhD9r%tE6aat^fQJBk_#aI0cR&9ZD?orVH*lQ%|9!Q^kG$<+MG8C#Y7ZFy>=6H? zG|1;k7xcMd5stMQBShZXq(s>LJ}vQ>tEwPnET59&{ME48J@3T^5yiU|I@%gS=$3`_ zZ}o@<*NU3gq@nffE!Qa6k7s1=#C#c+OF6pi}{E>?A%Zv#6j4zzs6RNE-kwYoAT(0GYeX|)$>DjG5 z9Su(Lju#X7J~{3dx-i$2Hmp5%Joz*U-&xgqwl4}9sFi+FpqEPTTRfU=?K^pybf~=> z!=04B`*?SDc;|E9)co9iPwKo4!vD*B2R5o=s5**HtTzx99sYi$~oF2xr^JPqxpavSWke z-AAn}*L_E}kJ~H5_a_JYcUOBSnYYDePlltd?&IT=-OER|_ic|2z94dvVw0VVRpJgo zgVhD;3}3Ym2m5EX=d=2b5c(e%e7On^tO&|>{HLG0-NP;RRw`47uE!8-K^!@9FW<5w?wfdU`NrK94Z(@NQY~TIA-wzJ8e`J89wF z+Hr5i{;DA&{B~%6`I_WD1-Xj5t8w|tmn(*a!fl@xPZwjnu?S+qul6q0^8O@coyIUd zmt?W}-f;JPugyAn;CSzFXYp?L(Wm9{(jfuq3)0nv`cb`hFD3G-_hWIrdpqZ?o!RBV z#XF1}7f-vq556RVOH>5&TPJrX&P2!U$G&=MEA4!rvNN(i^KvWO`U;&iqMl!{lxm;X z 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 literal 15270 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 diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt index cea9db3ac3..ec8cda13e5 100644 --- a/docs/lexer-states.txt +++ b/docs/lexer-states.txt @@ -116,15 +116,16 @@ C_WORD : all the rest ws: space | tab | cr | lf dbl-quote: " -delimit1: [ | ] | ( | ) | { | } | " | : | ws | ; | @ -delimit2: [ | ] | ( | ) | { | } | " | : | ws | ; | < -delimit3: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # -delimit4: < | > | = -delimit5: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : -delimit6: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | 0-9 -delimit7: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | \ | ^ | , -delimit8: [ | ] | ( | ) | { | } | : | ws | ; | @ -delimit9: ] | ) | } | " | : | < | > | , +delimit1: [ | ] | ( | ) | { | } | " | : | ws | ; | @ +delimit2: [ | ] | ( | ) | { | } | " | : | ws | ; | < +delimit3: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # +delimit4: < | > | = +delimit5: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : +delimit6: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | 0-9 +delimit7: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | \ | ^ | , +delimit8: [ | ] | ( | ) | { | } | : | ws | ; | @ +delimit9: ] | ) | } | " | : | < | > | , +delimit10: [ | ] | ( | ) | { | } | " | ws | ; | < hexa: C_ZERO | C_DIGIT | C_ALPHAX @@ -176,10 +177,10 @@ S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY \ \->delimit1->T_ISSUE \->delimit9->T_ERROR -S_START->digit->S_NUMBER->digit->S_NUMBER - \->delimit2->T_INTEGER +S_START->digit->S_NUMBER->digit|"'"->S_NUMBER + \->delimit10->T_INTEGER \->"%"->T_PERCENT - \->"."->S_DECIMAL->digit|"e"|"E"->S_DECIMAL->"%"->T_PERCENT + \->"."->S_DECIMAL->digit|"e"|"E"->S_DECIMAL \ \->delimit2->T_FLOAT \ \->"%"->T_PERCENT \ \->"x"|"X"->S_PAIR_1ST @@ -203,7 +204,9 @@ S_START->digit->S_NUMBER->digit->S_NUMBER \ \->"@"->S_EMAIL \ - \->else->T_ERROR + \->"e"|"E"->S_DECIMAL + \ + \->else->T_ERROR S_START->"<"->S_LESSER From f3f9c9f60bd5e535834817c7d71573aee593c9ce Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 1 Oct 2019 14:32:58 +0200 Subject: [PATCH 0164/3432] FIX: introduces missing S_DOTNUM state in lexical scanner. --- docs/lexer-FSM.xlsx | Bin 18093 -> 18216 bytes docs/lexer-states.txt | 66 +++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/docs/lexer-FSM.xlsx b/docs/lexer-FSM.xlsx index a88acbf24810b593c92c89192f0db42c94eef942..92c0135b924eea2ac600ddd41b37c5e445b638ab 100644 GIT binary patch delta 8503 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 LO?pNB?6dy^K*f-C diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt index ec8cda13e5..6382716076 100644 --- a/docs/lexer-states.txt +++ b/docs/lexer-states.txt @@ -18,6 +18,7 @@ S_SKIP_CHAR S_CONSTRUCT S_ISSUE S_NUMBER +S_DOTNUM S_DECIMAL S_DEC_SPECIAL S_TUPLE @@ -100,12 +101,12 @@ C_DOT : . C_MONEY : $ C_SIGN : +, - C_CARET : ^ -C_EOF : NUL C_UCS2 : 0xC2-0xDF, 0xE0-EF C_UCS4 : 0xF0-0xF4 -C_ILLEGAL : 0xC0-0xC1, 0xF5-0xFF C_NO_OP : 0x01-0x08, 0x11, 0x12, 0x14-0x1F C_WORD : all the rest +C_ILLEGAL : 0xC0-0xC1, 0xF5-0xFF +C_EOF : NUL ;":"->S_CLASS_GET => set as high-bits flag @@ -126,6 +127,7 @@ delimit7: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | \ | ^ | , delimit8: [ | ] | ( | ) | { | } | : | ws | ; | @ delimit9: ] | ) | } | " | : | < | > | , delimit10: [ | ] | ( | ) | { | } | " | ws | ; | < +delimit11: [ | ] | ( | ) | { | } | " | : | ws | ; | < | / hexa: C_ZERO | C_DIGIT | C_ALPHAX @@ -177,37 +179,43 @@ S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY \ \->delimit1->T_ISSUE \->delimit9->T_ERROR + S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->delimit10->T_INTEGER \->"%"->T_PERCENT - \->"."->S_DECIMAL->digit|"e"|"E"->S_DECIMAL - \ \->delimit2->T_FLOAT - \ \->"%"->T_PERCENT - \ \->"x"|"X"->S_PAIR_1ST - \ \->"#"->S_DEC_SPECIAL->not(delimit6)->S_DEC_SPECIAL - \ \ \->delimit6->T_FLOAT - \ \->"."->S_TUPLE->digit|"."->S_TUPLE - \ \ \->delimit2->T_TUPLE - \ \->else->T_ERROR - \ - \->"/"->S_DATE->not(delimit2)->S_DATE - \ \->delimit2->T_DATE - \ - \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME - \ \->else->T_ERROR \->delimit3->T_TIME - \ \->else->T_ERROR + \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"e"|"E"|"'"->S_DECIMAL + \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE + \ \ \ \->delimit11->T_TUPLE + \ \ \->"%"->T_PERCENT + \ \ \->"x"|"X"->S_PAIR_1ST + \ \ \->delimit11->T_FLOAT + \ \ \->else->T_ERROR + \ \ + \ \->"#"->S_DEC_SPECIAL->not(delimit6)->S_DEC_SPECIAL + \ \ \->delimit6->T_FLOAT + \ \ + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->"e"|"E"|"'"->S_DECIMAL + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR \ - \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR - \ \->else->T_ERROR \->delimit2->T_PAIR - \ \->else->T_ERROR - \->"#"->S_SHARP - \ - \->"@"->S_EMAIL - \ - \->"e"|"E"->S_DECIMAL - \ - \->else->T_ERROR - + \->"/"->S_DATE->not(delimit2)->S_DATE + \ \->delimit2->T_DATE + \ + \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME + \ \->else->T_ERROR \->delimit3->T_TIME + \ \->else->T_ERROR + \ + \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit2->T_PAIR + \ \->else->T_ERROR + \ + \->"#"->S_SHARP + \->"@"->S_EMAIL + \->"e"|"E"->S_DECIMAL + \->else->T_ERROR + S_START->"<"->S_LESSER \->delimit1|">"->T_WORD From d4a0fbf9dee035c1769aa5ac0fe6a5ab007bbfce Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 1 Oct 2019 21:06:15 +0200 Subject: [PATCH 0165/3432] FEAT: fills fully the lexical scanner transitions table. --- docs/lexer-FSM.xlsx | Bin 18216 -> 17897 bytes docs/lexer-states.txt | 101 +++++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/docs/lexer-FSM.xlsx b/docs/lexer-FSM.xlsx index 92c0135b924eea2ac600ddd41b37c5e445b638ab..a33557c5fba13188166410762f4274cd071f82cd 100644 GIT binary patch delta 14767 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 T`(HPeizUlGN41swbMpTKWbxxN delta 15088 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 O@06y7&zJn&`u_kBX>Qs8 diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt index 6382716076..962d07150e 100644 --- a/docs/lexer-states.txt +++ b/docs/lexer-states.txt @@ -27,7 +27,6 @@ S_TIME_1ST S_TIME S_PAIR_1ST S_PAIR -S_EMAIL S_MONEY_1ST S_MONEY S_MONEY_DEC @@ -39,6 +38,7 @@ S_TAG_STR2 S_SKIP_STR3 S_SIGN S_WORD +S_WORDSET S_URL S_EMAIL @@ -119,15 +119,17 @@ dbl-quote: " delimit1: [ | ] | ( | ) | { | } | " | : | ws | ; | @ delimit2: [ | ] | ( | ) | { | } | " | : | ws | ; | < -delimit3: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # -delimit4: < | > | = -delimit5: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : -delimit6: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | 0-9 -delimit7: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | \ | ^ | , +delimit3: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | / +delimit5: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | $ +delimit6: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | 0-9 +delimit7: [ | ] | ( | ) | { | } | " | ws | ; | < | \ delimit8: [ | ] | ( | ) | { | } | : | ws | ; | @ delimit9: ] | ) | } | " | : | < | > | , delimit10: [ | ] | ( | ) | { | } | " | ws | ; | < -delimit11: [ | ] | ( | ) | { | } | " | : | ws | ; | < | / +delimit11: [ | ] | ( | ) | { | } | " | : | ws | ; | < | / +delimit12: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | / | \ | ^ | , | : | 0-9 | ' | $ +delimit13: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | ^ +delimit14: # | ' | < | % | ^ hexa: C_ZERO | C_DIGIT | C_ALPHAX @@ -186,40 +188,42 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"e"|"E"|"'"->S_DECIMAL \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE \ \ \ \->delimit11->T_TUPLE - \ \ \->"%"->T_PERCENT - \ \ \->"x"|"X"->S_PAIR_1ST - \ \ \->delimit11->T_FLOAT - \ \ \->else->T_ERROR - \ \ - \ \->"#"->S_DEC_SPECIAL->not(delimit6)->S_DEC_SPECIAL - \ \ \->delimit6->T_FLOAT - \ \ - \ \->"%"->T_PERCENT - \ \->"x"|"X"->S_PAIR_1ST - \ \->"e"|"E"|"'"->S_DECIMAL - \ \->delimit11->T_FLOAT - \ \->else->T_ERROR - \ - \->"/"->S_DATE->not(delimit2)->S_DATE - \ \->delimit2->T_DATE - \ - \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME - \ \->else->T_ERROR \->delimit3->T_TIME - \ \->else->T_ERROR - \ - \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR - \ \->else->T_ERROR \->delimit2->T_PAIR - \ \->else->T_ERROR - \ - \->"#"->S_SHARP - \->"@"->S_EMAIL - \->"e"|"E"->S_DECIMAL - \->else->T_ERROR - + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"%"->T_PERCENT + \ \ \->"x"|"X"->S_PAIR_1ST + \ \ \->delimit11->T_FLOAT + \ \ \->else->T_ERROR + \ \ + \ \->"#"->S_DEC_SPECIAL->not(delimit12)->S_DEC_SPECIAL + \ \ \->delimit12->T_FLOAT + \ \ + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->"e"|"E"|"'"->S_DECIMAL + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR + \ + \->"/"->S_DATE->not(delimit13)->S_DATE + \ \->delimit13->T_DATE + \ + \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME + \ \->else->T_ERROR \->delimit11->T_TIME + \ \->else->T_ERROR + \ + \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR + \ + \->"#"->S_SHARP + \->"@"->S_EMAIL + \->"e"|"E"->S_DECIMAL + \->else->T_ERROR + S_START->"<"->S_LESSER \->delimit1|">"->T_WORD - \->delimit4->T_ERROR + \->"<"->T_ERROR \->else->S_TAG \->dbl-quote->S_TAG_STR->not("^"|dbl-quote)->S_TAG_STR \ \->"^"->S_SKIP_STR2->*->S_TAG_STR @@ -230,14 +234,17 @@ S_START->"<"->S_LESSER \ \->"'"->S_TAG \ \->">"->T_TAG + \->else->S_TAG S_START->"+"|"-"->S_SIGN->digit->S_NUMBER - \->S_WORD + \->"$"->S_MONEY + \->delimit14->T_ERROR + \->else->S_WORD -S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit->S_MONEY - \->else->T_ERROR \->"."->S_MONEY_DEC->digit->S_MONEY_DEC +S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY + \->else->T_ERROR \->"."->S_MONEY_DEC->digit|"'"->S_MONEY_DEC \ \->delimit3->T_MONEY \ \->else->T_ERROR \ @@ -248,10 +255,14 @@ S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit->S_MONEY S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD \->delimit7->T_WORD \ - \->":"->S_URL->not(delimit7)->S_URL - \ \->delimit7->T_URL + \->":"->S_WORDSET->not(delimit7)->S_URL->not(delimit7)->S_URL + \ \->delimit7->T_WORD \->delimit7->T_URL \ - \->"@"->S_EMAIL->not(delimit5)->S_EMAIL - \ \->delimit5->T_EMAIL + \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL + \ \->delimit7->T_EMAIL + \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR \ \->"/"->T_PATH + \->"$"->S_MONEY + \->","|"#"|"%"->T_ERROR + From 4a34c90133a911b046a9845f3ddf843844d31327 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 13:21:32 +0200 Subject: [PATCH 0166/3432] FIX: regression caused by fix for #3768. --- runtime/datatypes/block.reds | 6 +++--- tests/source/units/series-test.red | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 6aabd4bb72..faf231d520 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1190,7 +1190,7 @@ block: context [ switch TYPE_OF(res) [ TYPE_LOGIC [ bool: as red-logic! res - either bool/value [-1][1] + either bool/value [1][-1] ] TYPE_INTEGER [ int: as red-integer! res @@ -1204,8 +1204,8 @@ block: context [ true [0] ] ] - TYPE_NONE [1] - default [-1] + TYPE_NONE [-1] + default [1] ] ] diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index 597d8d61d1..6dd8bdf362 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1422,8 +1422,8 @@ Red [ --test-- "sort-blk-3" a: ["Larry" 45 "Curly" 50 "Mo" 42] --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 2 - --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a < b] - --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 < b/2] + --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare a 2 func [a b][a < b] + --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare/all a 2 func [a b][a/2 < b/2] --test-- "sort-blk-4" o1: context [a: 2 i: "a"] @@ -1437,6 +1437,17 @@ Red [ a: reduce [o1 o2 o3 o8 o4 o5 o6 o7] res: reduce [o2 o3 o4 o5 o6 o1 o8 o7] --assert res = sort/compare/stable a func [a b][b/a - a/a] + + --test-- "sort-blk-5" + --assert [1 3 2] = sort/compare [1 3 2] func [a b] [-5] + --assert [2 3 1] = sort/compare [1 3 2] func [a b] [5] + --assert [6 5 4 3 2 1] = sort/compare [1 2 3 4 5 6] func [a b] [5] + --assert [1 2 3 4 5 6] = sort/compare [1 2 3 4 5 6] func [a b] [-5] + --assert [1 2 3] = sort/compare [1 3 2] func [a b] [a < b] + --assert [3 2 1] = sort/compare [1 3 2] func [a b] [a > b] + --assert [1 2 3 4 5 6] = sort/compare [1 2 3 4 5 6] func [a b] [a < b] + --assert [6 5 4 3 2 1] = sort/compare [1 2 3 4 5 6] func [a b] [a > b] + ===end-group=== ===start-group=== "path access" From 19d90e9d3d38a2cebc3e69101f4c09dbb197c504 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 16:30:04 +0200 Subject: [PATCH 0167/3432] FIX: adds a missing terminal state. --- docs/lexer-states.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt index 962d07150e..3f914cb910 100644 --- a/docs/lexer-states.txt +++ b/docs/lexer-states.txt @@ -64,6 +64,7 @@ T_INTEGER T_FLOAT T_TUPLE T_DATE +T_PAIR T_TIME T_MONEY T_TAG From 0cbbff145bb1aa19ef0963270a3e96ae5f34a1a8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 16:37:39 +0200 Subject: [PATCH 0168/3432] FEAT: [R/S] supports binary! series as literal arrays. Pointer to a literal binary array is of [pointer [byte!]] type. --- system/compiler.r | 4 +++ system/emitter.r | 69 ++++++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index e9f9293c19..aa5994a0e0 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -882,6 +882,9 @@ system-dialect: make-profilable context [ next next reduce ['array! length? value 'pointer! type] ;-- hide array size ] ] + binary! [ + next next reduce ['array! length? value 'pointer! [byte!]] + ] issue! [ either find float-special next value [[float!]][ throw-error ["invalid special float value:" mold value] @@ -3567,6 +3570,7 @@ system-dialect: make-profilable context [ integer! [do pass] string! [do pass] decimal! [do pass] + binary! [do pass] block! [also preprocess-array pc/1 pc: next pc] issue! [either pc/1/1 = #"." [do pass][comp-directive]] ][ diff --git a/system/emitter.r b/system/emitter.r index 4d408b5f86..de3c66c370 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -329,39 +329,45 @@ emitter: make-profilable context [ store-global 0 'integer! none ] array! [ - type: first compiler/get-type value/1 - if find [float! float64!] type [pad-data-buf 8] ;-- optional 32-bit padding to ensure /0 points to the length slot - ptr: tail data-buf ;-- ensures array pointer skips size info - f64?: no - foreach item value [ ;-- mixed types, use 32/64-bit for each slot - unless word? item [ - t: first compiler/get-type item - if all [not f64? find [float! float64!] t][f64?: yes] - if type <> t [type: 'integer!] + either binary? value [ + pad-data-buf target/ptr-size + append ptr value + pad-data-buf target/ptr-size + ][ + type: first compiler/get-type value/1 + if find [float! float64!] type [pad-data-buf 8] ;-- optional 32-bit padding to ensure /0 points to the length slot + ptr: tail data-buf ;-- ensures array pointer skips size info + f64?: no + foreach item value [ ;-- mixed types, use 32/64-bit for each slot + unless word? item [ + t: first compiler/get-type item + if all [not f64? find [float! float64!] t][f64?: yes] + if type <> t [type: 'integer!] + ] ] - ] - either find value string! [ - list: collect [ - foreach item value [ ;-- store array - either decimal? item [ - store-global item 'float! none - ][ - either string? item [ - keep item - keep store-global 0 'integer! none + either find value string! [ + list: collect [ + foreach item value [ ;-- store array + either decimal? item [ + store-global item 'float! none ][ - store-global item 'integer! none + either string? item [ + keep item + keep store-global 0 'integer! none + ][ + store-global item 'integer! none + ] + if f64? [store-global to integer! #{CAFEBABE} 'integer! none] ] - if f64? [store-global to integer! #{CAFEBABE} 'integer! none] ] ] - ] - foreach [str ref] list [ ;-- store strings - store-value/ref none str [c-string!] reduce [ref + 1] - ] - ][ - foreach item value [ - store-global item any [all [get-word? item 'get-word!] type] none + foreach [str ref] list [ ;-- store strings + store-value/ref none str [c-string!] reduce [ref + 1] + ] + ][ + foreach item value [ + store-global item any [all [get-word? item 'get-word!] type] none + ] ] ] ] @@ -416,10 +422,13 @@ emitter: make-profilable context [ saved: name name: none ;-- anonymous data storing ] - if all [paren? value not word? value/1][ + if any [all [paren? value not word? value/1] binary? value][ type: [array!] ] - if any [all [not new-global? not local?] string? value paren? value][ + if any [ + all [not new-global? not local?] + find [string! paren! binary!] type?/word value + ][ if string? value [type: [c-string!]] ;-- force c-string! in case of type casting spec: store-value/ref name value type refs ;-- store it with hardcoded pointer address ] From 4ae20cf5ddf6a6cf993ca268e95306f8a9b4c687 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 18:05:57 +0200 Subject: [PATCH 0169/3432] DOC: marks a R/S feature in "Possible Evolutions" as done. --- docs/red-system-specs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/red-system-specs.txt b/docs/red-system-specs.txt index 4faf4f21ac..5e1c080a1c 100644 --- a/docs/red-system-specs.txt +++ b/docs/red-system-specs.txt @@ -4102,7 +4102,7 @@ will output: ---Logic! -*Add logic! support for OR, XOR, AND operators (if it provides any advantage over ANY/ALL). +*Add logic! support for OR, XOR, AND operators (if it provides any advantage over ANY/ALL). ---Integer! From 66eb9512adda05a32bb4337fd669c71447dc918f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 18:44:48 +0200 Subject: [PATCH 0170/3432] FEAT: introduces lexical scanner FSM tables and generator. --- docs/lexer-states.txt | 3 +- runtime/lexer-transitions.reds | 51 +++++ runtime/lexer.reds | 384 +++++++++++++++++++++++++++++++++ runtime/red.reds | 1 + runtime/tokenizer.reds | 329 ---------------------------- utils/generate-lexer-table.red | 124 +++++++++++ 6 files changed, 561 insertions(+), 331 deletions(-) create mode 100644 runtime/lexer-transitions.reds create mode 100644 runtime/lexer.reds create mode 100644 utils/generate-lexer-table.red diff --git a/docs/lexer-states.txt b/docs/lexer-states.txt index 3f914cb910..381747b7c5 100644 --- a/docs/lexer-states.txt +++ b/docs/lexer-states.txt @@ -41,8 +41,7 @@ S_WORD S_WORDSET S_URL S_EMAIL - ----S_FINAL_STATES--- +--EXIT_STATES-- T_EOF T_ERROR T_BLK_OP diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds new file mode 100644 index 0000000000..2368dc03b3 --- /dev/null +++ b/runtime/lexer-transitions.reds @@ -0,0 +1,51 @@ +Red/System [ + Note: "Auto-generated lexical scanner transitions table" +] + transitions: #{ +01010203030505333408353A0C0D0E0E103A3C3D3D3D3E3F2C412C402C424233 +2021212323263333444501010003030505333408353A0C0C0E0E103A3C3D3D3D +3E3F2C412C402C42423320212123232633334445120002030305050808080A11 +0C0D0E0E10111214143D161719191B1B1D1D1E20202121232312262828291200 +02030305050808080A110C0D0E0E10111214143D161719191B1B1D1D1E202021 +21232312262828292D00020303050533340835102C0D0E0E103A3C3D3D3D3E3F +2C412C402C424233202121232326333344452E000203030505333408352C2C0D +0E0E393A3C3D3D3D3E3F2C412C402C424233202121232326333344452F000203 +03050533340835382C0D0E0E103A3C3D3D3D3E3F2C412C402C42423320212123 +23263333444530000203030505333408352C2C0D0E0E103A3C3D3D3D3E3F2C41 +2C402C4242332021212323263333444505000203030505333408352C2C0D0E0E +103A3C3D3D3D3E3F2C412C402C424233202121232326333344452C0002030332 +05333408350C360D0E0E103A3C3D3D3D3E3F2C412C402C424233202121232326 +3333444503000231030505080808350E2C0D370E103A3C3D3D3D3E3F2C412C40 +2C424233212021232326333344450B0002030305050808080A112C0D0E0E1011 +0B151A3D2C172C2C2C2C2C42422020212123232C2C28282C2600020303050508 +08080A112C0D0E0E101112142C3D2C172C2C2C2C2C1D1E2020212123232C2628 +2C2C260002030305053334080A2C2C0D0E0E1011182C3D3D3E3F2C192C2C2C2C +2C332321212023262728282C260002030305050808080A112C0D0E0E10111A1A +2C152C172C2C2C2C2C2C2C202021212323262628282926000203030505080808 +0A112C0D0E0E1011141414152C172C2C2C1B2C2C2C2020212123232626282829 +260002030305050808080A110C0D0E0E10112C2C2C152C172C2C2C2C2C2C2C20 +202121232326262828290A0002030305050808080A112C0D0E0E1011173D3D3D +3E172C412C2C2C424220202121232326462828452C0002030305050808080A11 +2C0D0E0E10112C2C2C3D2C172C2C2C2C2C2C2C20202121232326333344451F00 +02030305050808080A2C2C0D0E0E10113C3D3D3D3E3F2C412C402C42422C2021 +2123232C262C4445260002030305050808080A2C2C0D0E0E10112C2C2C152C17 +2C2C2C2C2C2C2C3343212123232626282C2C070002030305050808080A112C0D +0E0E10113B3B3B3D2C3F2C2C2C2C2C2C2C2020212123232C2C2828292C000203 +0305050808080A2C2C0D0E0E10112C2C2C3D2C172C2C2C2C2C2C2C2020212123 +23262C28442C02000203030505333408353A0D0D0E0E103A3C3D2C3D2C3F2C41 +2C402C424233202121232326333344452C000203030505333408353A2C0D0E0E +103A292C2C3D2C3F2C2C2C2C2C2C2C332021212323262928282C260002030305 +050808080A112C0D0E0E1011132C161516172C192C1B2C1E2C20202121232326 +262828291C0002030305050808080A112C0D0E0E10112C2C2C3D2C3F2C2C2C2C +2C2C2C202021212323261D282C2C250002030305050808080A112C0D0E0E1011 +2C2C2C152C172C2C2C2C2C2C2C20202121232326262828292C00020403060508 +09080A112C0D0F0E10112C2C2C3D2C3F2C2C2C2C2C2C2C2020222123232C2628 +2C2C260002030305050808080A112C0D0E0E10112C2C2C152C172C2C2C2C2C2C +2C2020212123232626282829260002030305050808080A112C0D0E0E10112C2C +2C152C172C2C2C2C2C2C2C202021212323262628282926000203030505080808 +0A112C0D0E0E10112C2C2C152C172C2C2C2C2C2C2C2020212123232626282829 +260002030305050808080A112C0D0E0E10112C2C2C152C172C2C2C2C2C2C2C20 +202121232326262828292C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2B2B2B2B2B2B2B2B2B2B2B2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B +} diff --git a/runtime/lexer.reds b/runtime/lexer.reds new file mode 100644 index 0000000000..f57a2c5980 --- /dev/null +++ b/runtime/lexer.reds @@ -0,0 +1,384 @@ +Red/System [ + Title: "Red values low-level lexer" + Author: "Nenad Rakocevic" + File: %lexer.reds + Tabs: 4 + Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +lexer: context [ + + #include %lexer-transitions.reds + + #enum lex-states! [ + S_START + S_BLANK + S_LINE_CMT + S_LINE_STR + S_SKIP_STR + S_M_STRING + S_SKIP_MSTR + S_FILE_1ST + S_FILE + S_SKIP_FILE + S_SLASH + S_SHARP + S_BINARY + S_LINE_CMT2 + S_CHAR + S_SKIP_CHAR + S_CONSTRUCT + S_ISSUE + S_NUMBER + S_DOTNUM + S_DECIMAL + S_DEC_SPECIAL + S_TUPLE + S_DATE + S_TIME_1ST + S_TIME + S_PAIR_1ST + S_PAIR + S_MONEY_1ST + S_MONEY + S_MONEY_DEC + S_LESSER + S_TAG + S_TAG_STR + S_SKIP_STR2 + S_TAG_STR2 + S_SKIP_STR3 + S_SIGN + S_WORD + S_WORDSET + S_URL + S_EMAIL + --EXIT_STATES-- + T_EOF + T_ERROR + T_BLK_OP + T_BLK_CL + T_PAR_OP + T_PAR_CL + T_STRING + T_STR_ALT + T_WORD + T_FILE + T_REFINE + T_BINARY + T_CHAR + T_MAP_OP + T_CONS_MK + T_ISSUE + T_PERCENT + T_INTEGER + T_FLOAT + T_TUPLE + T_DATE + T_PAIR + T_TIME + T_MONEY + T_TAG + T_URL + T_EMAIL + T_PATH + ] + + #enum character-classes! [ + C_BLANK + C_LINE + C_DIGIT + C_ZERO + C_BLOCK_OP + C_BLOCK_CL + C_PAREN_OP + C_PAREN_CL + C_STRING_OP + C_STRING_CL + C_DBL_QUOTE + C_SHARP + C_QUOTE + C_COLON + C_X + C_EXP + C_ALPHAX + C_SLASH + C_BSLASH + C_LESSER + C_GREATER + C_PERCENT + C_COMMA + C_SEMICOL + C_AT + C_DOT + C_MONEY + C_SIGN + C_CARET + C_UCS2 + C_UCS4 + C_NO_OP + C_WORD + C_ILLEGAL + C_EOF + ] + + lex-classes: [ + C_EOF ;-- 00, NUL + C_NO_OP ;-- 01 + C_NO_OP ;-- 02 + C_NO_OP ;-- 03 + C_NO_OP ;-- 04 + C_NO_OP ;-- 05 + C_NO_OP ;-- 06 + C_NO_OP ;-- 07 + C_NO_OP ;-- 08 + C_BLANK ;-- 09 TAB + C_BLANK ;-- 0A LF + C_NO_OP ;-- 0B + C_NO_OP ;-- 0C + C_BLANK ;-- 0D CR + ;... + ] + + + ;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations + + utf8d: [ ;[byte! 8] + ; The first part of the table maps bytes to character classes that + ; to reduce the size of the transition table and create bitmasks. + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 + 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 + 8 8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 10 3 3 3 3 3 3 3 3 3 3 3 3 4 3 3 11 6 6 6 5 8 8 8 8 8 8 8 8 8 8 8 + + ; The second part is a transition table that maps a combination + ; of a state of the automaton and a character class to a state. + 0 12 24 36 60 96 84 12 12 12 48 72 12 12 12 12 12 12 12 12 12 12 12 12 + 12 0 12 12 12 12 12 0 12 0 12 12 12 24 12 12 12 12 12 24 12 24 12 12 + 12 12 12 12 12 12 12 24 12 12 12 12 12 24 12 12 12 12 12 12 12 24 12 12 + 12 12 12 12 12 12 12 36 12 36 12 12 12 36 12 12 12 12 12 36 12 36 12 12 + 12 36 12 12 12 12 12 12 12 12 12 12 + ] + + decode-utf8-char: func [ + p [byte-ptr!] + cp [int-ptr!] + return: [byte-ptr!] + /local + state [integer!] + byte [integer!] + idx [integer!] + type [integer!] + ][ + state: 0 + forever [ + byte: as-integer p/value + idx: byte + 1 + type: utf8d/idx + + idx: 256 + state + type + 1 + state: utf8d/idx + + switch state [ + 0 [ ;-- ACCEPT + cp/value: FFh >> type and byte + return p + 1 + ] + 12 [ ;-- REJECT + cp/value: -1 + return p + ] + default [ + cp/value: byte and 3Fh or (cp/value << 6) + p: p + 1 + ] + ] + ] + as byte-ptr! 0 ;-- never reached, just make compiler happy + ] + + #enum errors! [ + LEX_ERR_STRING: 1 + + LEX_ERROR ;-- keep it last + ] + + state!: alias struct! [ + parent [red-block!] ;-- any-block! accepted + buffer [red-value!] ;-- special buffer for hatching any-blocks + buf-head [red-value!] + buf-tail [red-value!] + head [byte-ptr!] + remain [integer!] + pos [byte-ptr!] + err [integer!] + ] + + scanner!: alias function! [state [state!] return: [byte-ptr!]] + + + scan-string: func [state [state!] return: [byte-ptr!] + /local + p [byte-ptr!] + e [byte-ptr!] + c [byte!] + ][ + p: state/pos + e: state/pos + state/remain + while [c: p/value all [p < e c <> #"^""]][ + either c = #"^^" [p: p + 2][ + if c = #"^/" [state/pos: p throw LEX_ERR_STRING] + p: p + 1 + ] + ] + + e: p + p: state/pos + ;decode/converte the string + + p + ] + + scan-alt-string: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-block: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-paren: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-paren-close: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-comment: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-file: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-refinement: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-money: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-lesser: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-lit: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-get: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-sharp: func [state [state!] return: [byte-ptr!] + ; /local + ][ + null + ] + + scan-tokens: func [ + lex [state!] + /local + parent [red-block!] + p [byte-ptr!] + e [byte-ptr!] + cp [integer!] + class [integer!] + index [integer!] + state [integer!] + line [integer!] + s [series!] + ][ + parent: lex/parent + s: GET_BUFFER(parent) + p: lex/pos + state: 0 + line: 1 + + loop lex/remain [ + cp: 1 + as-integer p/value + class: lex-classes/cp + index: state + class + 1 + state: as-integer transitions/index + ;line: line + line-table/class + p: p + 1 + if state > --EXIT_STATES-- [break] + ] + + lex/remain: as-integer p - lex/pos + lex/pos: p + + + ] + + scan: func [ + dst [red-block!] ;-- destination block + src [byte-ptr!] ;-- UTF-8 buffer + len [integer!] ;-- buffer size in bytes + /local + stack [red-block!] + state [state! value] + ][ + state/parent: block/make-in dst 100 + state/buffer: as cell! alloc-big 1000 * size? cell! + state/buf-head: state/buffer + state/buf-tail: state/buffer + 1000 + state/head: src + state/remain: len + state/pos: src + state/err: 0 + + catch LEX_ERROR [scan-tokens state] + if system/thrown > 0 [ + 0 ; error handling + ] + ] + + init: func [][ + + ] + +] \ No newline at end of file diff --git a/runtime/red.reds b/runtime/red.reds index bde151a79e..0d5647c0cf 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -119,6 +119,7 @@ red: context [ #include %crypto.reds #include %stack.reds #include %interpreter.reds + #include %lexer.reds #include %tokenizer.reds #include %simple-io.reds ;-- temporary file IO support #include %clipboard.reds diff --git a/runtime/tokenizer.reds b/runtime/tokenizer.reds index 46bb5296bf..f1ed1d3c8c 100644 --- a/runtime/tokenizer.reds +++ b/runtime/tokenizer.reds @@ -12,335 +12,6 @@ Red/System [ tokenizer: context [ - ;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations - - utf8d: [ ;[byte! 8] - ; The first part of the table maps bytes to character classes that - ; to reduce the size of the transition table and create bitmasks. - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 - 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 - 8 8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - 10 3 3 3 3 3 3 3 3 3 3 3 3 4 3 3 11 6 6 6 5 8 8 8 8 8 8 8 8 8 8 8 - - ; The second part is a transition table that maps a combination - ; of a state of the automaton and a character class to a state. - 0 12 24 36 60 96 84 12 12 12 48 72 12 12 12 12 12 12 12 12 12 12 12 12 - 12 0 12 12 12 12 12 0 12 0 12 12 12 24 12 12 12 12 12 24 12 24 12 12 - 12 12 12 12 12 12 12 24 12 12 12 12 12 24 12 12 12 12 12 12 12 24 12 12 - 12 12 12 12 12 12 12 36 12 36 12 12 12 36 12 12 12 12 12 36 12 36 12 12 - 12 36 12 12 12 12 12 12 12 12 12 12 - ] - - decode-utf8-char: func [ - p [byte-ptr!] - cp [int-ptr!] - return: [byte-ptr!] - /local - state [integer!] - byte [integer!] - idx [integer!] - type [integer!] - ][ - state: 0 - forever [ - byte: as-integer p/value - idx: byte + 1 - type: utf8d/idx - - idx: 256 + state + type + 1 - state: utf8d/idx - - switch state [ - 0 [ ;-- ACCEPT - cp/value: FFh >> type and byte - return p + 1 - ] - 12 [ ;-- REJECT - cp/value: -1 - return p - ] - default [ - cp/value: byte and 3Fh or (cp/value << 6) - p: p + 1 - ] - ] - ] - as byte-ptr! 0 ;-- never reached, just make compiler happy - ] - - #enum errors! [ - LEX_ERR_STRING: 1 - - LEX_ERROR ;-- keep it last - ] - - state!: alias struct! [ - parent [red-block!] ;-- any-block! accepted - buffer [red-value!] ;-- special buffer for hatching any-blocks - buf-head [red-value!] - buf-tail [red-value!] - head [byte-ptr!] - tail [byte-ptr!] - pos [byte-ptr!] - err [integer!] - ] - - scanner!: alias function! [state [state!] return: [byte-ptr!]] - - - scan-string: func [state [state!] return: [byte-ptr!] - /local - p [byte-ptr!] - e [byte-ptr!] - c [byte!] - ][ - p: state/pos - e: state/tail - while [c: p/value all [p < e c <> #"^""]][ - either c = #"^^" [p: p + 2][ - if c = #"^/" [state/pos: p throw LEX_ERR_STRING] - p: p + 1 - ] - ] - - e: p - p: state/pos - ;decode/converte the string - - p - ] - - scan-alt-string: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-block: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-paren: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-paren-close: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-comment: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-file: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-refinement: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-money: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-lesser: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-lit: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-get: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - scan-sharp: func [state [state!] return: [byte-ptr!] - ; /local - ][ - null - ] - - #enum lexer-categories! [ - LEX_EOF - LEX_BLANK - LEX_COMMA - LEX_COLON - LEX_NUMBER - LEX_WORD - ] - - lex-table-template: [ - ;--- Code ------- 1st char ------------ Nth char --- - #"^(00)" LEX_EOF - #"^(01)" LEX_NO_OP - #"^(02)" LEX_NO_OP - #"^(03)" LEX_NO_OP - #"^(04)" LEX_NO_OP - #"^(05)" LEX_NO_OP - #"^(06)" LEX_NO_OP - #"^(07)" LEX_NO_OP - #"^(08)" LEX_NO_OP - #"^(09)" LEX_BLANK ;-- TAB - #"^(0A)" LEX_BLANK ;-- LF - #"^(0B)" LEX_NO_OP - #"^(0C)" LEX_NO_OP - #"^(0D)" LEX_BLANK ;-- CR - #"^(0E)" LEX_NO_OP - #"^(0F)" LEX_NO_OP - #"^(10)" LEX_NO_OP - #"^(11)" LEX_NO_OP - #"^(12)" LEX_NO_OP - #"^(13)" LEX_NO_OP - #"^(14)" LEX_NO_OP - #"^(15)" LEX_NO_OP - #"^(16)" LEX_NO_OP - #"^(17)" LEX_NO_OP - #"^(18)" LEX_NO_OP - #"^(19)" LEX_NO_OP - #"^(1A)" LEX_NO_OP - #"^(1B)" LEX_NO_OP - #"^(1C)" LEX_NO_OP - #"^(1D)" LEX_NO_OP - #"^(1E)" LEX_NO_OP - #"^(1F)" LEX_NO_OP - #"^(10)" LEX_NO_OP - - #" " LEX_BLANK ;-- space - #"!" LEX_WORD - #"^"" :scan-string - #"#" :scan-sharp - #"$" :scan-money - #"%" :scan-file - #"&" LEX_WORD - #"'" :scan-lit - #"(" :scan-paren - #")" :scan-paren-close - #"*" LEX_WORD - #"+" LEX_WORD - #"," LEX_COMMA - #"-" LEX_WORD - #"." LEX_WORD - #"/" :scan-refinement - - #"0" LEX_NUMBER - #"1" LEX_NUMBER - #"2" LEX_NUMBER - #"3" LEX_NUMBER - #"4" LEX_NUMBER - #"5" LEX_NUMBER - #"6" LEX_NUMBER - #"7" LEX_NUMBER - #"8" LEX_NUMBER - #"9" LEX_NUMBER - - #":" :scan-get - #";" :scan-comment - #"<" :scan-lesser - #"=" LEX_WORD - #">" LEX_WORD - #"?" LEX_WORD - - - - #"{" :scan-alt-string - #"[" :scan-block - - - - ;[#"0" - #"9"] :scan-digit - ;else :scan-word - ] - - lex-table: as int-ptr! 0 ;-- table created at run-time - - scan-tokens: func [ - state [state!] - /local - parent [red-block!] - p [byte-ptr!] - e [byte-ptr!] - cp [integer!] - res [integer!] - s [series!] - do-scan [scanner!] - ][ - parent: state/parent - s: GET_BUFFER(parent) - p: state/pos - e: state/tail - cp: 0 - - while [p < e][ - while [ ;-- skip all head blanks - cp: as-integer p/value - lex-table/cp = LEX_BLANK - ][p: p + 1] - - res: lex-table/cp - either res < 1000 [ - p: p + 1 - ][ - do-scan: as scanner! res - state/pos: p + 1 - p: do-scan state - ] - ] - state/pos: p - ] - - scan: func [ - dst [red-block!] ;-- destination block - src [byte-ptr!] ;-- UTF-8 buffer - len [integer!] ;-- buffer size in bytes - /local - stack [red-block!] - state [state! value] - ][ - state/parent: block/make-in dst 100 - state/buffer: as cell! alloc-big 1000 * size? cell! - state/buf-head: state/buffer - state/buf-tail: state/buffer + 1000 - state/head: src - state/tail: src + len - state/pos: src - state/err: 0 - - catch LEX_ERROR [scan-tokens state] - if system/thrown > 0 [ - 0 ; error handling - ] - ] - - init: func [][ - - ] - scan-integer: func [ p [byte-ptr!] len [integer!] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red new file mode 100644 index 0000000000..ff9914550d --- /dev/null +++ b/utils/generate-lexer-table.red @@ -0,0 +1,124 @@ +Red [ + Title: "Generates low-level lexer table" + Author: "Nenad Rakocevic" + File: %generate-lexer-tables.r + Tabs: 4 + Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt" + Note: { + Outputs: %runtime/lexer-transitions.reds + } +] + +context [ + states: [ + S_START + S_BLANK + S_LINE_CMT + S_LINE_STR + S_SKIP_STR + S_M_STRING + S_SKIP_MSTR + S_FILE_1ST + S_FILE + S_SKIP_FILE + S_SLASH + S_SHARP + S_BINARY + S_LINE_CMT2 + S_CHAR + S_SKIP_CHAR + S_CONSTRUCT + S_ISSUE + S_NUMBER + S_DOTNUM + S_DECIMAL + S_DEC_SPECIAL + S_TUPLE + S_DATE + S_TIME_1ST + S_TIME + S_PAIR_1ST + S_PAIR + S_MONEY_1ST + S_MONEY + S_MONEY_DEC + S_LESSER + S_TAG + S_TAG_STR + S_SKIP_STR2 + S_TAG_STR2 + S_SKIP_STR3 + S_SIGN + S_WORD + S_WORDSET + S_URL + S_EMAIL + --EXIT_STATES-- + T_EOF + T_ERROR + T_BLK_OP + T_BLK_CL + T_PAR_OP + T_PAR_CL + T_STRING + T_STR_ALT + T_WORD + T_FILE + T_REFINE + T_BINARY + T_CHAR + T_MAP_OP + T_CONS_MK + T_ISSUE + T_PERCENT + T_INTEGER + T_FLOAT + T_TUPLE + T_DATE + T_PAIR + T_TIME + T_MONEY + T_TAG + T_URL + T_EMAIL + T_PATH + ] + + ;-- Read states from CSV file + csv: read %../docs/lexer-FSM.csv + + ;-- Determine CSV separator + sep: [#";" 0 #"," 0] + parse csv [some [#";" (sep/2: sep/2 + 1) | #"," (sep/4: sep/4 + 1) | skip]] + sort/skip/all/compare sep 2 func [a b][a/2 > b/2] + + ;-- Decode CSV + matrix: load-csv/with read %../docs/lexer-FSM.csv first sep + + table: make binary! 2000 + + ;-- Generate the table content + classes: clear [] + foreach line next matrix [ + append classes to-word line/1 + out: make block! 50 + foreach s next line [ + either pos: find states to-word s [ + append out (index? pos) - 1 + ][ + do make error! form reduce ["Error: state" s "not found"] + ] + ] + append/only table out + ] + + template: compose [Red/System [ + Note: "Auto-generated lexical scanner transitions table" + ] + transitions: (table) + ] + + write %../runtime/lexer-transitions.reds mold/only template +] +() \ No newline at end of file From d8fe77f9a32f6f2f7e725179b97cf55ac1eac6d4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 18:48:54 +0200 Subject: [PATCH 0171/3432] FEAT: minor extra tail whitespaces clean-up. --- runtime/lexer.reds | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f57a2c5980..8ca082ce97 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -85,44 +85,44 @@ lexer: context [ T_TAG T_URL T_EMAIL - T_PATH + T_PATH ] #enum character-classes! [ - C_BLANK - C_LINE - C_DIGIT - C_ZERO - C_BLOCK_OP - C_BLOCK_CL - C_PAREN_OP - C_PAREN_CL + C_BLANK + C_LINE + C_DIGIT + C_ZERO + C_BLOCK_OP + C_BLOCK_CL + C_PAREN_OP + C_PAREN_CL C_STRING_OP C_STRING_CL C_DBL_QUOTE - C_SHARP - C_QUOTE - C_COLON - C_X - C_EXP - C_ALPHAX - C_SLASH - C_BSLASH - C_LESSER - C_GREATER - C_PERCENT - C_COMMA - C_SEMICOL - C_AT - C_DOT - C_MONEY - C_SIGN - C_CARET - C_UCS2 - C_UCS4 - C_NO_OP - C_WORD - C_ILLEGAL + C_SHARP + C_QUOTE + C_COLON + C_X + C_EXP + C_ALPHAX + C_SLASH + C_BSLASH + C_LESSER + C_GREATER + C_PERCENT + C_COMMA + C_SEMICOL + C_AT + C_DOT + C_MONEY + C_SIGN + C_CARET + C_UCS2 + C_UCS4 + C_NO_OP + C_WORD + C_ILLEGAL C_EOF ] From 47834ef5bdfa52c97005e91741b08ea804b482bc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 3 Oct 2019 14:05:09 +0200 Subject: [PATCH 0172/3432] FEAT: moves the lexical scanner states list in the transition generator. Avoids copies of the states list. --- runtime/lexer-transitions.reds | 74 +++++++++++++++++++++++++++++++++- runtime/lexer.reds | 74 ---------------------------------- utils/generate-lexer-table.red | 9 ++++- 3 files changed, 80 insertions(+), 77 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 2368dc03b3..08fe617c60 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -1,7 +1,79 @@ Red/System [ Note: "Auto-generated lexical scanner transitions table" ] - transitions: #{ + #enum lex-states! [ + S_START + S_BLANK + S_LINE_CMT + S_LINE_STR + S_SKIP_STR + S_M_STRING + S_SKIP_MSTR + S_FILE_1ST + S_FILE + S_SKIP_FILE + S_SLASH + S_SHARP + S_BINARY + S_LINE_CMT2 + S_CHAR + S_SKIP_CHAR + S_CONSTRUCT + S_ISSUE + S_NUMBER + S_DOTNUM + S_DECIMAL + S_DEC_SPECIAL + S_TUPLE + S_DATE + S_TIME_1ST + S_TIME + S_PAIR_1ST + S_PAIR + S_MONEY_1ST + S_MONEY + S_MONEY_DEC + S_LESSER + S_TAG + S_TAG_STR + S_SKIP_STR2 + S_TAG_STR2 + S_SKIP_STR3 + S_SIGN + S_WORD + S_WORDSET + S_URL + S_EMAIL + --EXIT_STATES-- + T_EOF + T_ERROR + T_BLK_OP + T_BLK_CL + T_PAR_OP + T_PAR_CL + T_STRING + T_STR_ALT + T_WORD + T_FILE + T_REFINE + T_BINARY + T_CHAR + T_MAP_OP + T_CONS_MK + T_ISSUE + T_PERCENT + T_INTEGER + T_FLOAT + T_TUPLE + T_DATE + T_PAIR + T_TIME + T_MONEY + T_TAG + T_URL + T_EMAIL + T_PATH + ] transitions: #{ 01010203030505333408353A0C0D0E0E103A3C3D3D3D3E3F2C412C402C424233 2021212323263333444501010003030505333408353A0C0C0E0E103A3C3D3D3D 3E3F2C412C402C42423320212123232633334445120002030305050808080A11 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8ca082ce97..afb8b3dfdd 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -14,80 +14,6 @@ lexer: context [ #include %lexer-transitions.reds - #enum lex-states! [ - S_START - S_BLANK - S_LINE_CMT - S_LINE_STR - S_SKIP_STR - S_M_STRING - S_SKIP_MSTR - S_FILE_1ST - S_FILE - S_SKIP_FILE - S_SLASH - S_SHARP - S_BINARY - S_LINE_CMT2 - S_CHAR - S_SKIP_CHAR - S_CONSTRUCT - S_ISSUE - S_NUMBER - S_DOTNUM - S_DECIMAL - S_DEC_SPECIAL - S_TUPLE - S_DATE - S_TIME_1ST - S_TIME - S_PAIR_1ST - S_PAIR - S_MONEY_1ST - S_MONEY - S_MONEY_DEC - S_LESSER - S_TAG - S_TAG_STR - S_SKIP_STR2 - S_TAG_STR2 - S_SKIP_STR3 - S_SIGN - S_WORD - S_WORDSET - S_URL - S_EMAIL - --EXIT_STATES-- - T_EOF - T_ERROR - T_BLK_OP - T_BLK_CL - T_PAR_OP - T_PAR_CL - T_STRING - T_STR_ALT - T_WORD - T_FILE - T_REFINE - T_BINARY - T_CHAR - T_MAP_OP - T_CONS_MK - T_ISSUE - T_PERCENT - T_INTEGER - T_FLOAT - T_TUPLE - T_DATE - T_PAIR - T_TIME - T_MONEY - T_TAG - T_URL - T_EMAIL - T_PATH - ] - #enum character-classes! [ C_BLANK C_LINE diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index ff9914550d..8d6fcb21b0 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -113,10 +113,15 @@ context [ append/only table out ] - template: compose [Red/System [ + template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" ] - transitions: (table) + + #enum lex-states! [ + (states) + ] + + transitions: (table) ] write %../runtime/lexer-transitions.reds mold/only template From 877a285e0c53bde6ad895f13aafcea3668a61b98 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 3 Oct 2019 14:19:47 +0200 Subject: [PATCH 0173/3432] FEAT: converts utf8d array to a binary array. --- runtime/lexer.reds | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index afb8b3dfdd..ece779b215 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -70,29 +70,22 @@ lexer: context [ ;... ] - ;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations - utf8d: [ ;[byte! 8] - ; The first part of the table maps bytes to character classes that - ; to reduce the size of the transition table and create bitmasks. - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 - 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 - 8 8 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 - 10 3 3 3 3 3 3 3 3 3 3 3 3 4 3 3 11 6 6 6 5 8 8 8 8 8 8 8 8 8 8 8 - - ; The second part is a transition table that maps a combination - ; of a state of the automaton and a character class to a state. - 0 12 24 36 60 96 84 12 12 12 48 72 12 12 12 12 12 12 12 12 12 12 12 12 - 12 0 12 12 12 12 12 0 12 0 12 12 12 24 12 12 12 12 12 24 12 24 12 12 - 12 12 12 12 12 12 12 24 12 12 12 12 12 24 12 12 12 12 12 12 12 24 12 12 - 12 12 12 12 12 12 12 36 12 36 12 12 12 36 12 12 12 12 12 36 12 36 12 12 - 12 36 12 12 12 12 12 12 12 12 12 12 - ] + utf8d: #{ + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0101010101010101010101010101010109090909090909090909090909090909 + 0707070707070707070707070707070707070707070707070707070707070707 + 0808020202020202020202020202020202020202020202020202020202020202 + 0A0303030303030303030303030403030B060606050808080808080808080808 + 000C18243C60540C0C0C30480C0C0C0C0C0C0C0C0C0C0C0C0C000C0C0C0C0C00 + 0C000C0C0C180C0C0C0C0C180C180C0C0C0C0C0C0C0C0C180C0C0C0C0C180C0C + 0C0C0C0C0C180C0C0C0C0C0C0C0C0C240C240C0C0C240C0C0C0C0C240C240C0C + 0C240C0C0C0C0C0C0C0C0C0C + } decode-utf8-char: func [ p [byte-ptr!] @@ -108,10 +101,10 @@ lexer: context [ forever [ byte: as-integer p/value idx: byte + 1 - type: utf8d/idx + type: as-integer utf8d/idx idx: 256 + state + type + 1 - state: utf8d/idx + state: as-integer utf8d/idx switch state [ 0 [ ;-- ACCEPT From 861f7d776e5dfea6f7ecdef4e88f70500de3a167 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 3 Oct 2019 21:12:33 +0200 Subject: [PATCH 0174/3432] FEAT: removes C_UCS2 and C_UCS4 classes. They are replaced by simple flags. --- docs/lexer-FSM.csv | 1 + docs/lexer-FSM.xlsx | Bin 17897 -> 17506 bytes docs/lexer-states.txt | 4 +--- runtime/lexer-transitions.reds | 10 ++++------ 4 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 docs/lexer-FSM.csv diff --git a/docs/lexer-FSM.csv b/docs/lexer-FSM.csv new file mode 100644 index 0000000000..53794aa004 --- /dev/null +++ b/docs/lexer-FSM.csv @@ -0,0 +1 @@ +;S_START;S_BLANK;S_LINE_CMT;S_LINE_STR;S_SKIP_STR;S_M_STRING;S_SKIP_MSTR;S_FILE_1ST;S_FILE;S_SKIP_FILE;S_SLASH;S_SHARP;S_BINARY;S_LINE_CMT2;S_CHAR;S_SKIP_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DOTNUM;S_DECIMAL;S_DEC_SPECIAL;S_TUPLE;S_DATE;S_TIME_1ST;S_TIME;S_PAIR_1ST;S_PAIR;S_MONEY_1ST;S_MONEY;S_MONEY_DEC;S_LESSER;S_TAG;S_TAG_STR;S_SKIP_STR2;S_TAG_STR2;S_SKIP_STR3;S_SIGN;S_WORD;S_WORDSET;S_URL;S_EMAIL C_BLANK;S_BLANK;S_BLANK;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_LINE;S_BLANK;S_BLANK;S_START;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_BINARY;S_BINARY;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_DIGIT;S_NUMBER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;S_DECIMAL;T_FLOAT;S_TUPLE;S_DATE;S_TIME;S_TIME;S_PAIR;S_PAIR;S_MONEY;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_NUMBER;S_WORD;S_URL;S_URL;S_EMAIL C_ZERO;S_NUMBER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;S_DECIMAL;T_FLOAT;S_TUPLE;S_DATE;S_TIME;S_TIME;S_PAIR;S_PAIR;S_MONEY;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_NUMBER;S_WORD;S_URL;S_URL;S_EMAIL C_BLOCK_OP;T_BLK_OP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;S_CONSTRUCT;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_BLOCK_CL;T_BLK_CL;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;T_CONS_MK;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_PAREN_OP;T_PAR_OP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_MAP_OP;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_PAREN_CL;T_PAR_CL;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_STRING_OP;S_M_STRING;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_STRING_CL;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;T_STR_ALT;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;S_BINARY;T_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_DBL_QUOTE;S_LINE_STR;S_START;S_LINE_CMT;T_STRING;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;T_REFINE;S_CHAR;T_ERROR;S_LINE_CMT2;T_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_SHARP;S_SHARP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_SHARP;S_DEC_SPECIAL;S_PAIR_1ST;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_MONEY;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR;S_URL;S_URL;T_ERROR C_QUOTE;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;S_URL;T_ERROR;T_ERROR C_COLON;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_TIME_1ST;T_ERROR;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;S_TAG_STR2;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR2;S_WORD;S_WORDSET;S_URL;S_URL;T_ERROR C_X;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_PAIR_1ST;S_PAIR_1ST;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_EXP;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DECIMAL;S_DECIMAL;S_DECIMAL;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_ALPHAX;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_SLASH;S_SLASH;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DATE;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;S_DATE;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_MONEY;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_PATH;S_URL;S_URL;T_EMAIL C_BSLASH;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_LESSER;S_LESSER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_ERROR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;T_ERROR;T_URL;T_EMAIL C_GREATER;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;T_ERROR;T_ERROR C_PERCENT;S_FILE_1ST;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_PERCENT;T_PERCENT;T_PERCENT;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR;S_URL;S_URL;S_EMAIL C_COMMA;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_ERROR;S_URL;T_URL;T_ERROR C_SEMICOL;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_LINE_CMT2;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_AT;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;S_EMAIL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_EMAIL;S_URL;S_URL;T_ERROR C_DOT;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DOTNUM;T_ERROR;S_TUPLE;S_DEC_SPECIAL;S_TUPLE;S_DATE;T_ERROR;S_TIME;T_ERROR;S_PAIR;T_ERROR;S_MONEY_DEC;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_MONEY;S_MONEY_1ST;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_MONEY;S_URL;T_ERROR;T_ERROR C_SIGN;S_SIGN;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_CARET;T_ERROR;S_START;S_LINE_CMT;S_SKIP_STR;S_LINE_STR;S_SKIP_MSTR;S_M_STRING;S_FILE;S_SKIP_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_SKIP_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_SKIP_STR2;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;S_URL;T_ERROR;T_ERROR C_BIN;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_WORD;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_ILLEGAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR C_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF diff --git a/docs/lexer-FSM.xlsx b/docs/lexer-FSM.xlsx index a33557c5fba13188166410762f4274cd071f82cd..fc61fadc7b3cffc4d059a51990f6ec498d27a87d 100644 GIT binary patch delta 8782 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 Date: Thu, 3 Oct 2019 21:13:35 +0200 Subject: [PATCH 0175/3432] FEAT: fills the lexical classes table. --- runtime/lexer.reds | 114 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 96 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ece779b215..5191a156d9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -44,30 +44,108 @@ lexer: context [ C_MONEY C_SIGN C_CARET - C_UCS2 - C_UCS4 - C_NO_OP + C_BIN C_WORD C_ILLEGAL C_EOF ] + #enum class-flags! [ + C_FLAG_UCS4: 80000000h + C_FLAG_UCS2: 40000000h + C_FLAG_CARET: 20000000h + C_FLAG_DOT: 10000000h + C_FLAG_COMMA: 08000000h + C_FLAG_COLON: 04000000h + C_FLAG_QUOTE: 02000000h + C_FLAG_EXP: 01000000h + C_FLAG_SHARP: 00800000h + ] + lex-classes: [ - C_EOF ;-- 00, NUL - C_NO_OP ;-- 01 - C_NO_OP ;-- 02 - C_NO_OP ;-- 03 - C_NO_OP ;-- 04 - C_NO_OP ;-- 05 - C_NO_OP ;-- 06 - C_NO_OP ;-- 07 - C_NO_OP ;-- 08 - C_BLANK ;-- 09 TAB - C_BLANK ;-- 0A LF - C_NO_OP ;-- 0B - C_NO_OP ;-- 0C - C_BLANK ;-- 0D CR - ;... + C_EOF ;-- 00 NUL + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 01-08 + C_BLANK ;-- 09 TAB + C_BLANK ;-- 0A LF + C_BIN ;-- 0B + C_BIN ;-- 0C + C_BLANK ;-- 0D CR + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 0E-15 + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 16-1D + C_BIN C_BIN ;-- 1E-1F + C_BLANK ;-- 20 + C_WORD ;-- 21 ! + C_DBL_QUOTE ;-- 22 " + C_SHARP ;-- 23 # + C_MONEY ;-- 24 $ + C_PERCENT ;-- 25 % + C_WORD ;-- 26 & + C_QUOTE ;-- 27 ' + C_PAREN_OP ;-- 28 ( + C_PAREN_CL ;-- 29 ) + C_WORD ;-- 2A * + C_SIGN ;-- 2B + + C_COMMA ;-- 2C , + C_SIGN ;-- 2D - + C_DOT ;-- 2E . + C_SLASH ;-- 2F / + C_ZERO ;-- 30 0 + C_DIGIT C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 31-35 1-5 + C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 36-39 6-9 + C_COLON ;-- 3A : + C_SEMICOL ;-- 3B ; + C_LESSER ;-- 3C < + C_WORD ;-- 3D = + C_GREATER ;-- 3E > + C_WORD ;-- 3F ? + C_AT ;-- 40 @ + C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 41-44 A-D + C_EXP ;-- 45 E + C_ALPHAX ;-- 46 F + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R + C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 53-57 S-W + C_X ;-- 58 X + C_WORD C_WORD ;-- 59-5A Y-Z + C_BLOCK_OP ;-- 5B [ + C_BSLASH ;-- 5C \ + C_BLOCK_CL ;-- 5D ] + C_CARET ;-- 5E ^ + C_WORD ;-- 5F _ + C_WORD ;-- 60 ` + C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d + C_EXP ;-- 65 e + C_ALPHAX ;-- 66 f + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 67-6C g-l + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 6D-72 m-r + C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 73-77 s-w + C_X ;-- 78 x + C_WORD C_WORD ;-- 79-7A y-z + C_STRING_OP ;-- 7B { + C_WORD ;-- 7C | + C_STRING_CL ;-- 7D } + C_WORD ;-- 7E ~ + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 7F-86 + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 87-8E + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 8F-96 + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 97-9E + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 9F-A6 + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- A7-AE + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- AF-B6 + C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- B7-BE + C_BIN ;-- BF + C_ILLEGAL C_ILLEGAL ;-- C0-C1 + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- C2-C8 + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- C9-CF + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- D0-D6 + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- D7-DD + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- DE-E4 + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- E5-EB + C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- EC-F2 + C_WORD C_WORD ;-- F3-F4 + C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F5-F8 + C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F9-FC + C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- FD-FF ] ;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations From 6683e0afca003e1b42902994e78fe764f481f71c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 3 Oct 2019 21:28:44 +0200 Subject: [PATCH 0176/3432] DOC: reorganizes files in sub-folders. --- docs/conversion-matrix.xlsx | Bin 49399 -> 49486 bytes docs/{ => lexer}/lexer-FSM.csv | 0 docs/{ => lexer}/lexer-FSM.xlsx | Bin docs/{ => lexer}/lexer-states.txt | 0 docs/{ => old}/comparison-matrix.red | 0 docs/{ => old}/emit-block.r | 0 docs/{ => old}/emit-reds-api-html.r | 0 docs/{ => old}/emit-reds-api-md2.r | 0 docs/{ => old}/generate-reds-api.r | 0 docs/{ => old}/make-to-matrix-html.r | 0 docs/{ => old}/to-matrix-template.html | 0 docs/{ => old}/to-matrix.html | 0 docs/{ => old}/to-matrix.red | 0 docs/{ => red-system}/dark.css | 0 docs/{ => red-system}/light.css | 0 docs/{ => red-system}/makedoc2.r | 0 .../red-system-quick-test.txt | 0 docs/{ => red-system}/red-system-specs.txt | 0 docs/{ => red-system}/template.html | 0 19 files changed, 0 insertions(+), 0 deletions(-) rename docs/{ => lexer}/lexer-FSM.csv (100%) rename docs/{ => lexer}/lexer-FSM.xlsx (100%) rename docs/{ => lexer}/lexer-states.txt (100%) rename docs/{ => old}/comparison-matrix.red (100%) rename docs/{ => old}/emit-block.r (100%) rename docs/{ => old}/emit-reds-api-html.r (100%) rename docs/{ => old}/emit-reds-api-md2.r (100%) rename docs/{ => old}/generate-reds-api.r (100%) rename docs/{ => old}/make-to-matrix-html.r (100%) rename docs/{ => old}/to-matrix-template.html (100%) rename docs/{ => old}/to-matrix.html (100%) rename docs/{ => old}/to-matrix.red (100%) rename docs/{ => red-system}/dark.css (100%) rename docs/{ => red-system}/light.css (100%) rename docs/{ => red-system}/makedoc2.r (100%) rename docs/{ => red-system}/red-system-quick-test.txt (100%) rename docs/{ => red-system}/red-system-specs.txt (100%) rename docs/{ => red-system}/template.html (100%) diff --git a/docs/conversion-matrix.xlsx b/docs/conversion-matrix.xlsx index 90e1c9637bcfe2168283edf516d5855ebf2e9342..be47df33609407721ddc24ef5aad45850f7c8046 100644 GIT binary patch delta 24834 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 ZT?cV(bu85K5d>mKeJD{PObyrA{{Z}W)*b)= delta 24648 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 Date: Mon, 7 Oct 2019 12:54:14 +0200 Subject: [PATCH 0177/3432] FIX: cleans up some local words definition. --- system/compiler.r | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index aa5994a0e0..6564498df8 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -911,7 +911,7 @@ system-dialect: make-profilable context [ ] ] - get-enumerator: func [name [word!] /value /local pos][ + get-enumerator: func [name [word!] /local pos][ all [ pos: find/skip next enumerations name 3 ;-- SELECT/SKIP on hash! unreliable! pos/2 @@ -2928,7 +2928,7 @@ system-dialect: make-profilable context [ ] ] - resolve-ns: func [name [word!] /path /local ctx pos][ + resolve-ns: func [name [word!] /path /local ctx pos value][ unless ns-stack [return name] ;-- no current ns, pass-thru if ctx: find/skip sym-ctx-table name 2 [ ;-- fetch context candidates @@ -3539,7 +3539,7 @@ system-dialect: make-profilable context [ fetch-expression: func [ caller [any-word! issue! none! set-path!] - /final /keep /local expr pass value mark + /final /keep /local expr pass mark ][ mark: tail expr-call-stack check-infix-operators From 7dcc5064d495e878fb9df7ed9f3e189952c8ddf5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 13:07:01 +0200 Subject: [PATCH 0178/3432] FEAT: allows simple expressions in literal arrays. Resolved at compile-time, so they can rely only on literals, macros and enumerations. --- system/compiler.r | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index 6564498df8..d7410afa25 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1153,10 +1153,13 @@ system-dialect: make-profilable context [ ] ] - preprocess-array: func [list [block!]][ + preprocess-array: func [list [block!] /local p s v][ parse list [ some [ p: word! (check-enum-symbol p) :p ['true | 'false] (p/1: do p/1) + | p: paren! :p into [any [ + s: word! (check-enum-symbol s) | skip + ]] :p (change p do p/1) | string! | char! | integer! | decimal! | get-word! | p: 'null (p/1: 0) ] | (throw-error ["invalid literal array content:" mold list]) ] From b20075016836717bea92b26363053e8028c8af11 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 13:07:39 +0200 Subject: [PATCH 0179/3432] FEAT: adds flags to lexical classes. --- runtime/lexer.reds | 68 ++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5191a156d9..5fccd1fd89 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -13,7 +13,29 @@ Red/System [ lexer: context [ #include %lexer-transitions.reds + + #enum class-flags! [ + C_FLAG_UCS4: 80000000h + C_FLAG_UCS2: 40000000h + C_FLAG_CARET: 20000000h + C_FLAG_DOT: 10000000h + C_FLAG_COMMA: 08000000h + C_FLAG_COLON: 04000000h + C_FLAG_QUOTE: 02000000h + C_FLAG_EXP: 01000000h + C_FLAG_SHARP: 00800000h + ] + #define F_UCS4 [(C_WORD or C_FLAG_UCS4)] + #define F_UCS2 [(C_WORD or C_FLAG_UCS2)] + #define F_CARET [(C_CARET or C_FLAG_CARET)] + #define F_DOT [(C_DOT or C_FLAG_DOT)] + #define F_COMMA [(C_COMMA or C_FLAG_COMMA)] + #define F_COLON [(C_COLON or C_FLAG_COLON)] + #define F_QUOTE [(C_QUOTE or C_FLAG_QUOTE)] + #define F_EXP [(C_EXP or C_FLAG_EXP)] + #define F_SHARP [(C_SHARP or C_FLAG_SHARP)] + #enum character-classes! [ C_BLANK C_LINE @@ -49,19 +71,7 @@ lexer: context [ C_ILLEGAL C_EOF ] - - #enum class-flags! [ - C_FLAG_UCS4: 80000000h - C_FLAG_UCS2: 40000000h - C_FLAG_CARET: 20000000h - C_FLAG_DOT: 10000000h - C_FLAG_COMMA: 08000000h - C_FLAG_COLON: 04000000h - C_FLAG_QUOTE: 02000000h - C_FLAG_EXP: 01000000h - C_FLAG_SHARP: 00800000h - ] - + lex-classes: [ C_EOF ;-- 00 NUL C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 01-08 @@ -76,23 +86,23 @@ lexer: context [ C_BLANK ;-- 20 C_WORD ;-- 21 ! C_DBL_QUOTE ;-- 22 " - C_SHARP ;-- 23 # + F_SHARP ;-- 23 # C_MONEY ;-- 24 $ C_PERCENT ;-- 25 % C_WORD ;-- 26 & - C_QUOTE ;-- 27 ' + F_QUOTE ;-- 27 ' C_PAREN_OP ;-- 28 ( C_PAREN_CL ;-- 29 ) C_WORD ;-- 2A * C_SIGN ;-- 2B + - C_COMMA ;-- 2C , + F_COMMA ;-- 2C , C_SIGN ;-- 2D - - C_DOT ;-- 2E . + F_DOT ;-- 2E . C_SLASH ;-- 2F / C_ZERO ;-- 30 0 C_DIGIT C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 31-35 1-5 C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 36-39 6-9 - C_COLON ;-- 3A : + F_COLON ;-- 3A : C_SEMICOL ;-- 3B ; C_LESSER ;-- 3C < C_WORD ;-- 3D = @@ -100,7 +110,7 @@ lexer: context [ C_WORD ;-- 3F ? C_AT ;-- 40 @ C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 41-44 A-D - C_EXP ;-- 45 E + F_EXP ;-- 45 E C_ALPHAX ;-- 46 F C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R @@ -110,11 +120,11 @@ lexer: context [ C_BLOCK_OP ;-- 5B [ C_BSLASH ;-- 5C \ C_BLOCK_CL ;-- 5D ] - C_CARET ;-- 5E ^ + F_CARET ;-- 5E ^ C_WORD ;-- 5F _ C_WORD ;-- 60 ` C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d - C_EXP ;-- 65 e + F_EXP ;-- 65 e C_ALPHAX ;-- 66 f C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 67-6C g-l C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 6D-72 m-r @@ -135,14 +145,14 @@ lexer: context [ C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- B7-BE C_BIN ;-- BF C_ILLEGAL C_ILLEGAL ;-- C0-C1 - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- C2-C8 - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- C9-CF - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- D0-D6 - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- D7-DD - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- DE-E4 - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- E5-EB - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD;-- EC-F2 - C_WORD C_WORD ;-- F3-F4 + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- C2-C8 + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- C9-CF + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- D0-D6 + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- D7-DD + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- DE-E4 + F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- E5-EB + F_UCS2 F_UCS2 F_UCS2 F_UCS2 C_WORD C_WORD C_WORD;-- EC-F2 + F_UCS4 F_UCS4 ;-- F3-F4 C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F5-F8 C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F9-FC C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- FD-FF From d624d8aa2a7720d987a4433fc487004f69dd39a0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 16:40:57 +0200 Subject: [PATCH 0180/3432] FIX: renames lexer's macros to avoid collisions. --- runtime/lexer.reds | 52 ++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5fccd1fd89..a74dbc62b3 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -26,15 +26,15 @@ lexer: context [ C_FLAG_SHARP: 00800000h ] - #define F_UCS4 [(C_WORD or C_FLAG_UCS4)] - #define F_UCS2 [(C_WORD or C_FLAG_UCS2)] - #define F_CARET [(C_CARET or C_FLAG_CARET)] - #define F_DOT [(C_DOT or C_FLAG_DOT)] - #define F_COMMA [(C_COMMA or C_FLAG_COMMA)] - #define F_COLON [(C_COLON or C_FLAG_COLON)] - #define F_QUOTE [(C_QUOTE or C_FLAG_QUOTE)] - #define F_EXP [(C_EXP or C_FLAG_EXP)] - #define F_SHARP [(C_SHARP or C_FLAG_SHARP)] + #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] + #define FL_UCS2 [(C_WORD or C_FLAG_UCS2)] + #define FL_CARET [(C_CARET or C_FLAG_CARET)] + #define FL_DOT [(C_DOT or C_FLAG_DOT)] + #define FL_COMMA [(C_COMMA or C_FLAG_COMMA)] + #define FL_COLON [(C_COLON or C_FLAG_COLON)] + #define FL_QUOTE [(C_QUOTE or C_FLAG_QUOTE)] + #define FL_EXP [(C_EXP or C_FLAG_EXP)] + #define FL_SHARP [(C_SHARP or C_FLAG_SHARP)] #enum character-classes! [ C_BLANK @@ -86,23 +86,23 @@ lexer: context [ C_BLANK ;-- 20 C_WORD ;-- 21 ! C_DBL_QUOTE ;-- 22 " - F_SHARP ;-- 23 # + FL_SHARP ;-- 23 # C_MONEY ;-- 24 $ C_PERCENT ;-- 25 % C_WORD ;-- 26 & - F_QUOTE ;-- 27 ' + FL_QUOTE ;-- 27 ' C_PAREN_OP ;-- 28 ( C_PAREN_CL ;-- 29 ) C_WORD ;-- 2A * C_SIGN ;-- 2B + - F_COMMA ;-- 2C , + FL_COMMA ;-- 2C , C_SIGN ;-- 2D - - F_DOT ;-- 2E . + FL_DOT ;-- 2E . C_SLASH ;-- 2F / C_ZERO ;-- 30 0 C_DIGIT C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 31-35 1-5 C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 36-39 6-9 - F_COLON ;-- 3A : + FL_COLON ;-- 3A : C_SEMICOL ;-- 3B ; C_LESSER ;-- 3C < C_WORD ;-- 3D = @@ -110,7 +110,7 @@ lexer: context [ C_WORD ;-- 3F ? C_AT ;-- 40 @ C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 41-44 A-D - F_EXP ;-- 45 E + FL_EXP ;-- 45 E C_ALPHAX ;-- 46 F C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R @@ -120,11 +120,11 @@ lexer: context [ C_BLOCK_OP ;-- 5B [ C_BSLASH ;-- 5C \ C_BLOCK_CL ;-- 5D ] - F_CARET ;-- 5E ^ + FL_CARET ;-- 5E ^ C_WORD ;-- 5F _ C_WORD ;-- 60 ` C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d - F_EXP ;-- 65 e + FL_EXP ;-- 65 e C_ALPHAX ;-- 66 f C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 67-6C g-l C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 6D-72 m-r @@ -145,14 +145,16 @@ lexer: context [ C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- B7-BE C_BIN ;-- BF C_ILLEGAL C_ILLEGAL ;-- C0-C1 - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- C2-C8 - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- C9-CF - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- D0-D6 - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- D7-DD - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- DE-E4 - F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2 F_UCS2;-- E5-EB - F_UCS2 F_UCS2 F_UCS2 F_UCS2 C_WORD C_WORD C_WORD;-- EC-F2 - F_UCS4 F_UCS4 ;-- F3-F4 + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- C2-C7 + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- C8-CD + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- CE-D3 + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- D4-D9 + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- DA-DF + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- E0-E5 + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- E6-EB + FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- EC-EF + C_WORD C_WORD C_WORD ;-- F0-F2 + FL_UCS4 FL_UCS4 ;-- F3-F4 C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F5-F8 C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F9-FC C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- FD-FF From 2c2cd9c0ecc9266fb4a634c5455897497e141094 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 18:34:16 +0200 Subject: [PATCH 0181/3432] FEAT: replaces arrays of char! values with binary arrays. --- environment/schemes/GPIO.red | 32 +++++++-------- runtime/datatypes/binary.reds | 72 ++++++++++++++++----------------- runtime/datatypes/string.reds | 40 +++++++++--------- runtime/deflate.reds | 76 +++++++++++++++++------------------ 4 files changed, 110 insertions(+), 110 deletions(-) diff --git a/environment/schemes/GPIO.red b/environment/schemes/GPIO.red index aac3d0c3b9..90ea18ca70 100644 --- a/environment/schemes/GPIO.red +++ b/environment/schemes/GPIO.red @@ -129,23 +129,23 @@ gpio-scheme: context [ regions: [RPI_GPIO_OFFSET RPI_GPIO_PWM RPI_GPIO_CLOCK_BASE] - gpio-to-FSEL: [ - #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" - #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(01)" - #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" - #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(03)" - #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" - #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(05)" - ] + gpio-to-FSEL: #{ + 00 00 00 00 00 00 00 00 00 00 + 01 01 01 01 01 01 01 01 01 01 + 02 02 02 02 02 02 02 02 02 02 + 03 03 03 03 03 03 03 03 03 03 + 04 04 04 04 04 04 04 04 04 04 + 05 05 05 05 05 05 05 05 05 05 + } - gpio-to-shift: [ - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - #"^(00)" #"^(03)" #"^(06)" #"^(09)" #"^(0C)" #"^(0F)" #"^(12)" #"^(15)" #"^(18)" #"^(1B)" - ] + gpio-to-shift: #{ + 00 03 06 09 0C 0F 12 15 18 1B + 00 03 06 09 0C 0F 12 15 18 1B + 00 03 06 09 0C 0F 12 15 18 1B + 00 03 06 09 0C 0F 12 15 18 1B + 00 03 06 09 0C 0F 12 15 18 1B + 00 03 06 09 0C 0F 12 15 18 1B + } debug?: no diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index c9dd9b497c..31d31ac67f 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -25,45 +25,45 @@ binary: context [ ] ] - debase64: [ - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 07h - #"^(40)" #"^(40)" #"^(40)" #"^(80)" #"^(40)" #"^(40)" #"^(80)" #"^(80)" ;-- 0Fh - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 17h - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 1Fh - #"^(40)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(40)" ;-- 27h - #"^(80)" #"^(80)" #"^(80)" #"^(3E)" #"^(80)" #"^(80)" #"^(80)" #"^(3F)" ;-- 2Fh - #"^(34)" #"^(35)" #"^(36)" #"^(37)" #"^(38)" #"^(39)" #"^(3A)" #"^(3B)" ;-- 37h - #"^(3C)" #"^(3D)" #"^(80)" #"^(80)" #"^(80)" #"^(00)" #"^(80)" #"^(80)" ;-- 3Fh - #"^(80)" #"^(00)" #"^(01)" #"^(02)" #"^(03)" #"^(04)" #"^(05)" #"^(06)" ;-- 47h - #"^(07)" #"^(08)" #"^(09)" #"^(0A)" #"^(0B)" #"^(0C)" #"^(0D)" #"^(0E)" ;-- 4Fh - #"^(0F)" #"^(10)" #"^(11)" #"^(12)" #"^(13)" #"^(14)" #"^(15)" #"^(16)" ;-- 57h - #"^(17)" #"^(18)" #"^(19)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 5Fh - #"^(80)" #"^(1A)" #"^(1B)" #"^(1C)" #"^(1D)" #"^(1E)" #"^(1F)" #"^(20)" ;-- 67h - #"^(21)" #"^(22)" #"^(23)" #"^(24)" #"^(25)" #"^(26)" #"^(27)" #"^(28)" ;-- 6Fh - #"^(29)" #"^(2A)" #"^(2B)" #"^(2C)" #"^(2D)" #"^(2E)" #"^(2F)" #"^(30)" ;-- 77h - #"^(31)" #"^(32)" #"^(33)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 7Fh - ] + debase64: #{ + 80 80 80 80 80 80 80 80 ;-- 07h + 40 40 40 80 40 40 80 80 ;-- 0Fh + 80 80 80 80 80 80 80 80 ;-- 17h + 80 80 80 80 80 80 80 80 ;-- 1Fh + 40 80 80 80 80 80 80 40 ;-- 27h + 80 80 80 3E 80 80 80 3F ;-- 2Fh + 34 35 36 37 38 39 3A 3B ;-- 37h + 3C 3D 80 80 80 00 80 80 ;-- 3Fh + 80 00 01 02 03 04 05 06 ;-- 47h + 07 08 09 0A 0B 0C 0D 0E ;-- 4Fh + 0F 10 11 12 13 14 15 16 ;-- 57h + 17 18 19 80 80 80 80 80 ;-- 5Fh + 80 1A 1B 1C 1D 1E 1F 20 ;-- 67h + 21 22 23 24 25 26 27 28 ;-- 6Fh + 29 2A 2B 2C 2D 2E 2F 30 ;-- 77h + 31 32 33 80 80 80 80 80 ;-- 7Fh + } enbase64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - debase58: [ - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 07h - #"^(40)" #"^(40)" #"^(40)" #"^(80)" #"^(40)" #"^(40)" #"^(80)" #"^(80)" ;-- 0Fh - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 17h - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 1Fh - #"^(40)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(40)" ;-- 27h - #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 2Fh - #"^(80)" #"^(00)" #"^(01)" #"^(02)" #"^(03)" #"^(04)" #"^(05)" #"^(06)" ;-- 37h - #"^(07)" #"^(08)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 3Fh - #"^(80)" #"^(09)" #"^(0A)" #"^(0B)" #"^(0C)" #"^(0D)" #"^(0E)" #"^(0F)" ;-- 47h - #"^(10)" #"^(80)" #"^(11)" #"^(12)" #"^(13)" #"^(14)" #"^(15)" #"^(80)" ;-- 4Fh - #"^(16)" #"^(17)" #"^(18)" #"^(19)" #"^(1A)" #"^(1B)" #"^(1C)" #"^(1D)" ;-- 57h - #"^(1E)" #"^(1F)" #"^(20)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 5Fh - #"^(80)" #"^(21)" #"^(22)" #"^(23)" #"^(24)" #"^(25)" #"^(26)" #"^(27)" ;-- 67h - #"^(28)" #"^(29)" #"^(2A)" #"^(2B)" #"^(80)" #"^(2C)" #"^(2D)" #"^(2E)" ;-- 6Fh - #"^(2F)" #"^(30)" #"^(31)" #"^(32)" #"^(33)" #"^(34)" #"^(35)" #"^(36)" ;-- 77h - #"^(37)" #"^(38)" #"^(39)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" #"^(80)" ;-- 7Fh - ] + debase58: #{ + 80 80 80 80 80 80 80 80 ;-- 07h + 40 40 40 80 40 40 80 80 ;-- 0Fh + 80 80 80 80 80 80 80 80 ;-- 17h + 80 80 80 80 80 80 80 80 ;-- 1Fh + 40 80 80 80 80 80 80 40 ;-- 27h + 80 80 80 80 80 80 80 80 ;-- 2Fh + 80 00 01 02 03 04 05 06 ;-- 37h + 07 08 80 80 80 80 80 80 ;-- 3Fh + 80 09 0A 0B 0C 0D 0E 0F ;-- 47h + 10 80 11 12 13 14 15 80 ;-- 4Fh + 16 17 18 19 1A 1B 1C 1D ;-- 57h + 1E 1F 20 80 80 80 80 80 ;-- 5Fh + 80 21 22 23 24 25 26 27 ;-- 67h + 28 29 2A 2B 80 2C 2D 2E ;-- 6Fh + 2F 30 31 32 33 34 35 36 ;-- 77h + 37 38 39 80 80 80 80 80 ;-- 7Fh + } enbase58: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 4ae56c89f9..e03f173b7a 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -44,26 +44,26 @@ string: context [ #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^^" #"^(00)" ;-- 5Fh ] - escape-url-chars: [ ;-- ESC_NONE: #"^(FF)" ESC_URL: #"^(FE)" - #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" ;-- 07h - #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" ;-- 0Fh - #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" ;-- 17h - #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" #"^(FE)" ;-- 1Fh - #"^(FE)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FF)" ;-- 27h - #"^(FE)" #"^(FE)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" ;-- 2Fh - #"^(00)" #"^(01)" #"^(02)" #"^(03)" #"^(04)" #"^(05)" #"^(06)" #"^(07)" ;-- 37h - #"^(08)" #"^(09)" #"^(FF)" #"^(FE)" #"^(FE)" #"^(FF)" #"^(FE)" #"^(FF)" ;-- 3Fh - #"^(FF)" #"^(0A)" #"^(0B)" #"^(0C)" #"^(0D)" #"^(0E)" #"^(0F)" #"^(FF)" ;-- 47h - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" ;-- 4Fh - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" ;-- 57h - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FF)" ;-- 5Fh - #"^(FF)" #"^(0A)" #"^(0B)" #"^(0C)" #"^(0D)" #"^(0E)" #"^(0F)" #"^(FF)" ;-- 67h - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" ;-- 6Fh - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" #"^(FF)" ;-- 77h - #"^(FF)" #"^(FF)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FE)" #"^(FF)" #"^(FF)" ;-- 7Fh - ] - - utf8-buffer: [#"^(00)" #"^(00)" #"^(00)" #"^(00)"] + escape-url-chars: #{ ;-- ESC_NONE: #"^(FF)" ESC_URL: #"^(FE)" + FE FE FE FE FE FE FE FE ;-- 07h + FE FE FE FE FE FE FE FE ;-- 0Fh + FE FE FE FE FE FE FE FE ;-- 17h + FE FE FE FE FE FE FE FE ;-- 1Fh + FE FF FE FF FF FE FF FF ;-- 27h + FE FE FF FF FF FF FF FF ;-- 2Fh + 00 01 02 03 04 05 06 07 ;-- 37h + 08 09 FF FE FE FF FE FF ;-- 3Fh + FF 0A 0B 0C 0D 0E 0F FF ;-- 47h + FF FF FF FF FF FF FF FF ;-- 4Fh + FF FF FF FF FF FF FF FF ;-- 57h + FF FF FF FE FF FE FF FF ;-- 5Fh + FF 0A 0B 0C 0D 0E 0F FF ;-- 67h + FF FF FF FF FF FF FF FF ;-- 6Fh + FF FF FF FF FF FF FF FF ;-- 77h + FF FF FF FE FF FE FF FF ;-- 7Fh + } + + utf8-buffer: #{00000000} to-float: func [ s [byte-ptr!] diff --git a/runtime/deflate.reds b/runtime/deflate.reds index 26c1e6ab9f..bdc1e7d196 100644 --- a/runtime/deflate.reds +++ b/runtime/deflate.reds @@ -62,59 +62,59 @@ deflate: context [ INFLATE_BLK ;-- error: wrong block ] - MIRROR: [ - #"^(00)" #"^(80)" #"^(40)" #"^(C0)" #"^(20)" #"^(A0)" #"^(60)" #"^(E0)" #"^(10)" #"^(90)" #"^(50)" #"^(D0)" #"^(30)" #"^(B0)" #"^(70)" #"^(F0)" - #"^(08)" #"^(88)" #"^(48)" #"^(C8)" #"^(28)" #"^(A8)" #"^(68)" #"^(E8)" #"^(18)" #"^(98)" #"^(58)" #"^(D8)" #"^(38)" #"^(B8)" #"^(78)" #"^(F8)" - #"^(04)" #"^(84)" #"^(44)" #"^(C4)" #"^(24)" #"^(A4)" #"^(64)" #"^(E4)" #"^(14)" #"^(94)" #"^(54)" #"^(D4)" #"^(34)" #"^(B4)" #"^(74)" #"^(F4)" - #"^(0C)" #"^(8C)" #"^(4C)" #"^(CC)" #"^(2C)" #"^(AC)" #"^(6C)" #"^(EC)" #"^(1C)" #"^(9C)" #"^(5C)" #"^(DC)" #"^(3C)" #"^(BC)" #"^(7C)" #"^(FC)" - #"^(02)" #"^(82)" #"^(42)" #"^(C2)" #"^(22)" #"^(A2)" #"^(62)" #"^(E2)" #"^(12)" #"^(92)" #"^(52)" #"^(D2)" #"^(32)" #"^(B2)" #"^(72)" #"^(F2)" - #"^(0A)" #"^(8A)" #"^(4A)" #"^(CA)" #"^(2A)" #"^(AA)" #"^(6A)" #"^(EA)" #"^(1A)" #"^(9A)" #"^(5A)" #"^(DA)" #"^(3A)" #"^(BA)" #"^(7A)" #"^(FA)" - #"^(06)" #"^(86)" #"^(46)" #"^(C6)" #"^(26)" #"^(A6)" #"^(66)" #"^(E6)" #"^(16)" #"^(96)" #"^(56)" #"^(D6)" #"^(36)" #"^(B6)" #"^(76)" #"^(F6)" - #"^(0E)" #"^(8E)" #"^(4E)" #"^(CE)" #"^(2E)" #"^(AE)" #"^(6E)" #"^(EE)" #"^(1E)" #"^(9E)" #"^(5E)" #"^(DE)" #"^(3E)" #"^(BE)" #"^(7E)" #"^(FE)" - #"^(01)" #"^(81)" #"^(41)" #"^(C1)" #"^(21)" #"^(A1)" #"^(61)" #"^(E1)" #"^(11)" #"^(91)" #"^(51)" #"^(D1)" #"^(31)" #"^(B1)" #"^(71)" #"^(F1)" - #"^(09)" #"^(89)" #"^(49)" #"^(C9)" #"^(29)" #"^(A9)" #"^(69)" #"^(E9)" #"^(19)" #"^(99)" #"^(59)" #"^(D9)" #"^(39)" #"^(B9)" #"^(79)" #"^(F9)" - #"^(05)" #"^(85)" #"^(45)" #"^(C5)" #"^(25)" #"^(A5)" #"^(65)" #"^(E5)" #"^(15)" #"^(95)" #"^(55)" #"^(D5)" #"^(35)" #"^(B5)" #"^(75)" #"^(F5)" - #"^(0D)" #"^(8D)" #"^(4D)" #"^(CD)" #"^(2D)" #"^(AD)" #"^(6D)" #"^(ED)" #"^(1D)" #"^(9D)" #"^(5D)" #"^(DD)" #"^(3D)" #"^(BD)" #"^(7D)" #"^(FD)" - #"^(03)" #"^(83)" #"^(43)" #"^(C3)" #"^(23)" #"^(A3)" #"^(63)" #"^(E3)" #"^(13)" #"^(93)" #"^(53)" #"^(D3)" #"^(33)" #"^(B3)" #"^(73)" #"^(F3)" - #"^(0B)" #"^(8B)" #"^(4B)" #"^(CB)" #"^(2B)" #"^(AB)" #"^(6B)" #"^(EB)" #"^(1B)" #"^(9B)" #"^(5B)" #"^(DB)" #"^(3B)" #"^(BB)" #"^(7B)" #"^(FB)" - #"^(07)" #"^(87)" #"^(47)" #"^(C7)" #"^(27)" #"^(A7)" #"^(67)" #"^(E7)" #"^(17)" #"^(97)" #"^(57)" #"^(D7)" #"^(37)" #"^(B7)" #"^(77)" #"^(F7)" - #"^(0F)" #"^(8F)" #"^(4F)" #"^(CF)" #"^(2F)" #"^(AF)" #"^(6F)" #"^(EF)" #"^(1F)" #"^(9F)" #"^(5F)" #"^(DF)" #"^(3F)" #"^(BF)" #"^(7F)" #"^(FF)" - ] + MIRROR: #{ + 00 80 40 C0 20 A0 60 E0 10 90 50 D0 30 B0 70 F0 + 08 88 48 C8 28 A8 68 E8 18 98 58 D8 38 B8 78 F8 + 04 84 44 C4 24 A4 64 E4 14 94 54 D4 34 B4 74 F4 + 0C 8C 4C CC 2C AC 6C EC 1C 9C 5C DC 3C BC 7C FC + 02 82 42 C2 22 A2 62 E2 12 92 52 D2 32 B2 72 F2 + 0A 8A 4A CA 2A AA 6A EA 1A 9A 5A DA 3A BA 7A FA + 06 86 46 C6 26 A6 66 E6 16 96 56 D6 36 B6 76 F6 + 0E 8E 4E CE 2E AE 6E EE 1E 9E 5E DE 3E BE 7E FE + 01 81 41 C1 21 A1 61 E1 11 91 51 D1 31 B1 71 F1 + 09 89 49 C9 29 A9 69 E9 19 99 59 D9 39 B9 79 F9 + 05 85 45 C5 25 A5 65 E5 15 95 55 D5 35 B5 75 F5 + 0D 8D 4D CD 2D AD 6D ED 1D 9D 5D DD 3D BD 7D FD + 03 83 43 C3 23 A3 63 E3 13 93 53 D3 33 B3 73 F3 + 0B 8B 4B CB 2B AB 6B EB 1B 9B 5B DB 3B BB 7B FB + 07 87 47 C7 27 A7 67 E7 17 97 57 D7 37 B7 77 F7 + 0F 8F 4F CF 2F AF 6F EF 1F 9F 5F DF 3F BF 7F FF + } LXMIN: [0 11 19 35 67 131] DXMAX: [0 6 12 24 48 96 192 384 768 1536 3072 6144 12288 24576] - LMIN: [11 13 15 17 19 23 27 31 35 43 51 59 67 83 99 115 131 163 195 227] - DMIN: [1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 257 385 513 769 1025 1537 2049 3073 4097 6145 8193 12289 16385 24577] - - ORDER: [ - #"^(10)" #"^(11)" #"^(12)" #"^(00)" #"^(08)" #"^(07)" #"^(09)" #"^(06)" - #"^(0A)" #"^(05)" #"^(0B)" #"^(04)" #"^(0C)" #"^(03)" #"^(0D)" #"^(02)" - #"^(0E)" #"^(01)" #"^(0F)" - ] + LMIN: [11 13 15 17 19 23 27 31 35 43 51 59 67 83 99 115 131 163 195 227] + DMIN: [1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 257 385 513 769 1025 1537 2049 3073 4097 6145 8193 12289 16385 24577] + ORDER: #{ + 10 11 12 00 08 07 09 06 + 0A 05 0B 04 0C 03 0D 02 + 0E 01 0F + } + DBASE: [ 1 2 3 4 5 7 9 13 17 25 33 49 65 97 129 193 257 385 513 769 1025 1537 2049 3073 4097 6145 8193 12289 16385 24577 0 0 ] - DBITS: [ - #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(01)" #"^(01)" #"^(02)" #"^(02)" - #"^(03)" #"^(03)" #"^(04)" #"^(04)" #"^(05)" #"^(05)" #"^(06)" #"^(06)" - #"^(07)" #"^(07)" #"^(08)" #"^(08)" #"^(09)" #"^(09)" #"^(0A)" #"^(0A)" - #"^(0B)" #"^(0B)" #"^(0C)" #"^(0C)" #"^(0D)" #"^(0D)" #"^(00)" #"^(00)" - ] + DBITS: #{ + 00 00 00 00 01 01 02 02 + 03 03 04 04 05 05 06 06 + 07 07 08 08 09 09 0A 0A + 0B 0B 0C 0C 0D 0D 00 00 + } LBASE: [ 3 4 5 6 7 8 9 10 11 13 15 17 19 23 27 31 35 43 51 59 67 83 99 115 131 163 195 227 258 0 0 ] - LBITS: [ - #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" #"^(00)" - #"^(01)" #"^(01)" #"^(01)" #"^(01)" #"^(02)" #"^(02)" #"^(02)" #"^(02)" - #"^(03)" #"^(03)" #"^(03)" #"^(03)" #"^(04)" #"^(04)" #"^(04)" #"^(04)" - #"^(05)" #"^(05)" #"^(05)" #"^(05)" #"^(00)" #"^(00)" #"^(00)" - ] + LBITS: #{ + 00 00 00 00 00 00 00 00 + 01 01 01 01 02 02 02 02 + 03 03 03 03 04 04 04 04 + 05 05 05 05 00 00 00 + } rev16: func [ n [integer!] From 8dd3b23d30150d25519a7f748410a1f43f97cb42 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 21:51:09 +0200 Subject: [PATCH 0182/3432] FIX: source CSV file path not updated after docs/ folder reorg. --- utils/generate-lexer-table.red | 149 ++++++++++++++++----------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 8d6fcb21b0..5c726443f6 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -12,81 +12,82 @@ Red [ context [ states: [ - S_START - S_BLANK - S_LINE_CMT - S_LINE_STR - S_SKIP_STR - S_M_STRING - S_SKIP_MSTR - S_FILE_1ST - S_FILE - S_SKIP_FILE - S_SLASH - S_SHARP - S_BINARY - S_LINE_CMT2 - S_CHAR - S_SKIP_CHAR - S_CONSTRUCT - S_ISSUE - S_NUMBER - S_DOTNUM - S_DECIMAL - S_DEC_SPECIAL - S_TUPLE - S_DATE - S_TIME_1ST - S_TIME - S_PAIR_1ST - S_PAIR - S_MONEY_1ST - S_MONEY - S_MONEY_DEC - S_LESSER - S_TAG - S_TAG_STR - S_SKIP_STR2 - S_TAG_STR2 - S_SKIP_STR3 - S_SIGN - S_WORD - S_WORDSET - S_URL - S_EMAIL - --EXIT_STATES-- - T_EOF - T_ERROR - T_BLK_OP - T_BLK_CL - T_PAR_OP - T_PAR_CL - T_STRING - T_STR_ALT - T_WORD - T_FILE - T_REFINE - T_BINARY - T_CHAR - T_MAP_OP - T_CONS_MK - T_ISSUE - T_PERCENT - T_INTEGER - T_FLOAT - T_TUPLE - T_DATE - T_PAIR - T_TIME - T_MONEY - T_TAG - T_URL - T_EMAIL - T_PATH + S_START ;-- 0 + S_BLANK ;-- 1 + S_LINE_CMT ;-- 2 + S_LINE_STR ;-- 3 + S_SKIP_STR ;-- 4 + S_M_STRING ;-- 5 + S_SKIP_MSTR ;-- 6 + S_FILE_1ST ;-- 7 + S_FILE ;-- 8 + S_SKIP_FILE ;-- 9 + S_SLASH ;-- 10 + S_SHARP ;-- 11 + S_BINARY ;-- 12 + S_LINE_CMT2 ;-- 13 + S_CHAR ;-- 14 + S_SKIP_CHAR ;-- 15 + S_CONSTRUCT ;-- 16 + S_ISSUE ;-- 17 + S_NUMBER ;-- 18 + S_DOTNUM ;-- 19 + S_DECIMAL ;-- 20 + S_DEC_SPECIAL ;-- 21 + S_TUPLE ;-- 22 + S_DATE ;-- 23 + S_TIME_1ST ;-- 24 + S_TIME ;-- 25 + S_PAIR_1ST ;-- 26 + S_PAIR ;-- 27 + S_MONEY_1ST ;-- 28 + S_MONEY ;-- 29 + S_MONEY_DEC ;-- 30 + S_LESSER ;-- 31 + S_TAG ;-- 32 + S_TAG_STR ;-- 33 + S_SKIP_STR2 ;-- 34 + S_TAG_STR2 ;-- 35 + S_SKIP_STR3 ;-- 36 + S_SIGN ;-- 37 + S_WORD ;-- 38 + S_WORDSET ;-- 39 + S_URL ;-- 40 + S_EMAIL ;-- 41 + --EXIT_STATES-- ;-- 42 + T_EOF ;-- 43 + T_ERROR ;-- 44 + T_BLK_OP ;-- 45 + T_BLK_CL ;-- 46 + T_PAR_OP ;-- 47 + T_PAR_CL ;-- 48 + T_STRING ;-- 49 + T_STR_ALT ;-- 50 + T_WORD ;-- 51 + T_FILE ;-- 52 + T_REFINE ;-- 53 + T_BINARY ;-- 54 + T_CHAR ;-- 55 + T_MAP_OP ;-- 56 + T_CONS_MK ;-- 57 + T_ISSUE ;-- 58 + T_PERCENT ;-- 59 + T_INTEGER ;-- 60 + T_FLOAT ;-- 61 + T_TUPLE ;-- 62 + T_DATE ;-- 63 + T_PAIR ;-- 64 + T_TIME ;-- 65 + T_MONEY ;-- 66 + T_TAG ;-- 67 + T_URL ;-- 68 + T_EMAIL ;-- 69 + T_PATH ;-- 70 ] + CSV-table: %../docs/lexer/lexer-FSM.csv ;-- Read states from CSV file - csv: read %../docs/lexer-FSM.csv + csv: read CSV-table ;-- Determine CSV separator sep: [#";" 0 #"," 0] @@ -94,14 +95,12 @@ context [ sort/skip/all/compare sep 2 func [a b][a/2 > b/2] ;-- Decode CSV - matrix: load-csv/with read %../docs/lexer-FSM.csv first sep + matrix: load-csv/with read CSV-table first sep table: make binary! 2000 ;-- Generate the table content - classes: clear [] foreach line next matrix [ - append classes to-word line/1 out: make block! 50 foreach s next line [ either pos: find states to-word s [ From af41c8f305132b2208e010cb02c55a7843383874 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 21:52:56 +0200 Subject: [PATCH 0183/3432] FIX: transposes the lexical scanner transitions table. --- docs/lexer/lexer-FSM.csv | 44 ++++++++++++++++- docs/lexer/lexer-FSM.xlsx | Bin 17506 -> 14185 bytes runtime/lexer-transitions.reds | 88 ++++++++++++++++----------------- 3 files changed, 87 insertions(+), 45 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 53794aa004..0265272b77 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1 +1,43 @@ -;S_START;S_BLANK;S_LINE_CMT;S_LINE_STR;S_SKIP_STR;S_M_STRING;S_SKIP_MSTR;S_FILE_1ST;S_FILE;S_SKIP_FILE;S_SLASH;S_SHARP;S_BINARY;S_LINE_CMT2;S_CHAR;S_SKIP_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DOTNUM;S_DECIMAL;S_DEC_SPECIAL;S_TUPLE;S_DATE;S_TIME_1ST;S_TIME;S_PAIR_1ST;S_PAIR;S_MONEY_1ST;S_MONEY;S_MONEY_DEC;S_LESSER;S_TAG;S_TAG_STR;S_SKIP_STR2;S_TAG_STR2;S_SKIP_STR3;S_SIGN;S_WORD;S_WORDSET;S_URL;S_EMAIL C_BLANK;S_BLANK;S_BLANK;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_LINE;S_BLANK;S_BLANK;S_START;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_BINARY;S_BINARY;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_DIGIT;S_NUMBER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;S_DECIMAL;T_FLOAT;S_TUPLE;S_DATE;S_TIME;S_TIME;S_PAIR;S_PAIR;S_MONEY;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_NUMBER;S_WORD;S_URL;S_URL;S_EMAIL C_ZERO;S_NUMBER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;S_DECIMAL;T_FLOAT;S_TUPLE;S_DATE;S_TIME;S_TIME;S_PAIR;S_PAIR;S_MONEY;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_NUMBER;S_WORD;S_URL;S_URL;S_EMAIL C_BLOCK_OP;T_BLK_OP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;S_CONSTRUCT;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_BLOCK_CL;T_BLK_CL;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;T_CONS_MK;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_PAREN_OP;T_PAR_OP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_MAP_OP;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_PAREN_CL;T_PAR_CL;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_STRING_OP;S_M_STRING;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_STRING_CL;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;T_STR_ALT;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;S_BINARY;T_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_DBL_QUOTE;S_LINE_STR;S_START;S_LINE_CMT;T_STRING;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;T_REFINE;S_CHAR;T_ERROR;S_LINE_CMT2;T_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_SHARP;S_SHARP;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_SHARP;S_DEC_SPECIAL;S_PAIR_1ST;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_MONEY;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR;S_URL;S_URL;T_ERROR C_QUOTE;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_NUMBER;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_MONEY;S_MONEY_DEC;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;S_URL;T_ERROR;T_ERROR C_COLON;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_TIME_1ST;T_ERROR;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;S_TAG_STR2;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR2;S_WORD;S_WORDSET;S_URL;S_URL;T_ERROR C_X;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_PAIR_1ST;S_PAIR_1ST;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_EXP;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DECIMAL;S_DECIMAL;S_DECIMAL;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_ALPHAX;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;S_BINARY;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_SLASH;S_SLASH;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DATE;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;S_DATE;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_MONEY;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_PATH;S_URL;S_URL;T_EMAIL C_BSLASH;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_LESSER;S_LESSER;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_INTEGER;T_FLOAT;T_FLOAT;T_FLOAT;T_TUPLE;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_ERROR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;T_ERROR;T_URL;T_EMAIL C_GREATER;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;T_ERROR;T_ERROR C_PERCENT;S_FILE_1ST;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_PERCENT;T_PERCENT;T_PERCENT;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR;S_URL;S_URL;S_EMAIL C_COMMA;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;T_ERROR;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_ERROR;S_URL;T_URL;T_ERROR C_SEMICOL;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;S_LINE_CMT2;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;T_INTEGER;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_TIME;T_ERROR;T_PAIR;T_ERROR;T_MONEY;T_MONEY;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;T_WORD;T_WORD;T_URL;T_EMAIL C_AT;T_ERROR;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;T_WORD;T_FILE;S_FILE;T_REFINE;T_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;T_ISSUE;S_EMAIL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_EMAIL;S_URL;S_URL;T_ERROR C_DOT;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;S_DOTNUM;T_ERROR;S_TUPLE;S_DEC_SPECIAL;S_TUPLE;S_DATE;T_ERROR;S_TIME;T_ERROR;S_PAIR;T_ERROR;S_MONEY_DEC;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_MONEY;S_MONEY_1ST;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_MONEY;S_URL;T_ERROR;T_ERROR C_SIGN;S_SIGN;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_CARET;T_ERROR;S_START;S_LINE_CMT;S_SKIP_STR;S_LINE_STR;S_SKIP_MSTR;S_M_STRING;S_FILE;S_SKIP_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_SKIP_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_SKIP_STR2;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;T_ERROR;S_WORD;S_URL;T_ERROR;T_ERROR C_BIN;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_WORD;S_WORD;S_START;S_LINE_CMT;S_LINE_STR;S_LINE_STR;S_M_STRING;S_M_STRING;S_FILE;S_FILE;S_FILE;S_SLASH;S_ISSUE;T_ERROR;S_LINE_CMT2;S_CHAR;S_CHAR;S_CONSTRUCT;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_DEC_SPECIAL;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TAG;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR2;S_TAG_STR2;S_WORD;S_WORD;S_URL;S_URL;S_EMAIL C_ILLEGAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR C_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF;T_EOF +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_SIGN;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_BLANK;S_BLANK;S_BLANK;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STR_ALT;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_EOF +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_EOF +S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_EOF +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_EOF +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;T_ERROR;S_BINARY;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_EOF +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_EOF +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_EOF +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_EOF +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_EOF +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_EOF +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_EOF +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_EOF +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_EOF +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_EOF +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_EOF +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_EOF +S_SIGN;S_WORD;S_WORD;S_NUMBER;S_NUMBER;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_EOF +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_EOF +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_EOF +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index fc61fadc7b3cffc4d059a51990f6ec498d27a87d..a29d030e762f71a98a0ce11d2a88366798173cb7 100644 GIT binary patch delta 9082 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 a_!r+fw4x>tGd+YJ5(d7?Fd%z$_5T59wBro` delta 12394 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

3_iVSM|rQ|Avxd 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້e6J_v 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index e24881214d..402ae82410 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -74,48 +74,48 @@ Red/System [ T_EMAIL T_PATH ] transitions: #{ -01010203030505333408353A0C0D0E0E103A3C3D3D3D3E3F2C412C402C424233 -2021212323263333444501010003030505333408353A0C0C0E0E103A3C3D3D3D -3E3F2C412C402C42423320212123232633334445120002030305050808080A11 -0C0D0E0E10111214143D161719191B1B1D1D1E20202121232312262828291200 -02030305050808080A110C0D0E0E10111214143D161719191B1B1D1D1E202021 -21232312262828292D00020303050533340835102C0D0E0E103A3C3D3D3D3E3F -2C412C402C424233202121232326333344452E000203030505333408352C2C0D -0E0E393A3C3D3D3D3E3F2C412C402C424233202121232326333344452F000203 -03050533340835382C0D0E0E103A3C3D3D3D3E3F2C412C402C42423320212123 -23263333444530000203030505333408352C2C0D0E0E103A3C3D3D3D3E3F2C41 -2C402C4242332021212323263333444505000203030505333408352C2C0D0E0E -103A3C3D3D3D3E3F2C412C402C424233202121232326333344452C0002030332 -05333408350C360D0E0E103A3C3D3D3D3E3F2C412C402C424233202121232326 -3333444503000231030505080808350E2C0D370E103A3C3D3D3D3E3F2C412C40 -2C424233212021232326333344450B0002030305050808080A112C0D0E0E1011 -0B151A3D2C172C2C2C2C2C42422020212123232C2C28282C2600020303050508 -08080A112C0D0E0E101112142C3D2C172C2C2C2C2C1D1E2020212123232C2628 -2C2C260002030305053334080A2C2C0D0E0E1011182C3D3D3E3F2C192C2C2C2C -2C332321212023262728282C260002030305050808080A112C0D0E0E10111A1A -2C152C172C2C2C2C2C2C2C202021212323262628282926000203030505080808 -0A112C0D0E0E1011141414152C172C2C2C1B2C2C2C2020212123232626282829 -260002030305050808080A110C0D0E0E10112C2C2C152C172C2C2C2C2C2C2C20 -202121232326262828290A0002030305050808080A112C0D0E0E1011173D3D3D -3E172C412C2C2C424220202121232326462828452C0002030305050808080A11 -2C0D0E0E10112C2C2C3D2C172C2C2C2C2C2C2C20202121232326333344451F00 -02030305050808080A2C2C0D0E0E10113C3D3D3D3E3F2C412C402C42422C2021 -2123232C262C4445260002030305050808080A2C2C0D0E0E10112C2C2C152C17 -2C2C2C2C2C2C2C3343212123232626282C2C070002030305050808080A112C0D -0E0E10113B3B3B3D2C3F2C2C2C2C2C2C2C2020212123232C2C2828292C000203 -0305050808080A2C2C0D0E0E10112C2C2C3D2C172C2C2C2C2C2C2C2020212123 -23262C28442C02000203030505333408353A0D0D0E0E103A3C3D2C3D2C3F2C41 -2C402C424233202121232326333344452C000203030505333408353A2C0D0E0E -103A292C2C3D2C3F2C2C2C2C2C2C2C332021212323262928282C260002030305 -050808080A112C0D0E0E1011132C161516172C192C1B2C1E2C20202121232326 -262828291C0002030305050808080A112C0D0E0E10112C2C2C3D2C3F2C2C2C2C -2C2C2C202021212323261D282C2C250002030305050808080A112C0D0E0E1011 -2C2C2C152C172C2C2C2C2C2C2C20202121232326262828292C00020403060508 -09080A112C0D0F0E10112C2C2C3D2C3F2C2C2C2C2C2C2C2020222123232C2628 -2C2C260002030305050808080A112C0D0E0E10112C2C2C152C172C2C2C2C2C2C -2C2020212123232626282829260002030305050808080A112C0D0E0E10112C2C -2C152C172C2C2C2C2C2C2C20202121232326262828292C2C2C2C2C2C2C2C2C2C -2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B -2B2B2B2B2B2B2B2B2B2B +010112122D2E2F30052C030B26262626260A2C1F26072C022C261C252C26262C +2B01010000000000000000000000000000000000000000000000000000000000 +2C2B020002020202020202020202020202020202020202020202020202020202 +022C2B0303030303030303030331030303030303030303030303030303030304 +03032C2B03030303030303030303030303030303030303030303030303030303 +0303032C2B050505050505050505320505050505050505050505050505050505 +050605052C2B0505050505050505050505050505050505050505050505050505 +05050505052C2B33330808333333333333080808330808080808080808083333 +0808080808082C2B343408083434343434340808083408080808080808080834 +340808080908082C2B0808080808080808080808080808080808080808080808 +08080808080808082C2B35350A0A353535353535350A0A0A0A0A0A0A0A0A0A0A +0A35350A0A0A0A0A0A2C2B3A3A1111102C382C2C0C0E11112C11111111112C2C +112C3A3A1111111111112C2B0C0C0C0C2C2C2C2C2C362C2C2C2C2C2C0C2C2C2C +2C2C2C0D2C2C2C2C2C2C2C2C2B0D0C0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0D0D0D2C2B0E0E0E0E0E0E0E0E0E0E370E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0F0E0E2C2B0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E0E2C2B10101010103910101010101010101010 +1010101010101010101010101010102C2B3A3A11113A3A3A3A3A3A3A11111111 +11111111111111113A3A1111111111112C2B3C3C12123C3C3C3C3C3C3C0B1218 +1A142C172C3C2C3B2C3C29132C2C2C2C2C2C2B3D3D14143D3D3D3D3D3D3D1514 +2C1A142C3D2C3D2C3B2C3D2C2C2C2C2C2C2C2C2B3D3D14143D3D3D3D3D3D3D1A +2C3D2C142C3D2C3D2C3B2C2C2C162C2C2C2C2C2C2B3D3D3D3D3D3D3D3D3D3D3D +3D3D3D1515153D3D3D153D3D3D3D153D153D15152C2B3E3E16163E3E3E3E3E3E +3E2C2C3E2C2C2C3E2C3E2C2C2C2C2C162C2C2C2C2C2C2B3F3F17173F3F3F3F3F +3F3F17173F17171717173F173F173F3F173F173F17172C2B2C2C19192C2C2C2C +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2B41411919414141 +414141412C2C192C2C2C412C412C2C2C412C192C2C2C2C2C2C2B2C2C1B1B2C2C +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2B40401B1B40 +4040404040402C2C2C2C1B2C2C2C402C2C2C402C1B2C2C2C2C2C2C2B2C2C1D1D +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2B42421D +1D42424242424242421D2C2C2C2C422C422C2C2C422C1E2C2C2C2C2C2C2B4242 +1E1E42424242424242421E2C2C2C2C422C422C2C2C422C2C2C2C2C2C2C2C2B33 +3320203333333333333320203320202020202C33202033332020202020202C2B +202020202020202020202120202320202020202043202020202020202020202C +2B21212121212121212121202121212121212121212121212121212121222121 +2C2B212121212121212121212121212121212121212121212121212121212121 +212C2B2323232323232323232323232320232323232323232323232323232323 +23232C2B23232323232323232323232323232323232323232323232323232323 +2323232C2B26261212262626262626262C2C2626262626262C262C2626262626 +262C26262C2B33332626333333333333332C2627262626463326262C2C332926 +1D262626262C2B333328283333333333333328282828282828332C2828283328 +2828282828282C2B4444282844444444444444282C282828282844442C284444 +28282C282C28282C2B45452929454545454545452C2C2C2929294545452C292C +452C292C292C29292C2B } From 0ca247dd881bd11afd41c51c48dde3efcb0c79b8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 21:53:26 +0200 Subject: [PATCH 0184/3432] FEAT: adds scanners stubs and jump table. --- runtime/lexer.reds | 243 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 189 insertions(+), 54 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a74dbc62b3..40502e3020 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -37,39 +37,39 @@ lexer: context [ #define FL_SHARP [(C_SHARP or C_FLAG_SHARP)] #enum character-classes! [ - C_BLANK - C_LINE - C_DIGIT - C_ZERO - C_BLOCK_OP - C_BLOCK_CL - C_PAREN_OP - C_PAREN_CL - C_STRING_OP - C_STRING_CL - C_DBL_QUOTE - C_SHARP - C_QUOTE - C_COLON - C_X - C_EXP - C_ALPHAX - C_SLASH - C_BSLASH - C_LESSER - C_GREATER - C_PERCENT - C_COMMA - C_SEMICOL - C_AT - C_DOT - C_MONEY - C_SIGN - C_CARET - C_BIN - C_WORD - C_ILLEGAL - C_EOF + C_BLANK ;-- 0 + C_LINE ;-- 1 + C_DIGIT ;-- 2 + C_ZERO ;-- 3 + C_BLOCK_OP ;-- 4 + C_BLOCK_CL ;-- 5 + C_PAREN_OP ;-- 6 + C_PAREN_CL ;-- 7 + C_STRING_OP ;-- 8 + C_STRING_CL ;-- 9 + C_DBL_QUOTE ;-- 10 + C_SHARP ;-- 11 + C_QUOTE ;-- 12 + C_COLON ;-- 13 + C_X ;-- 14 + C_EXP ;-- 15 + C_ALPHAX ;-- 16 + C_SLASH ;-- 17 + C_BSLASH ;-- 18 + C_LESSER ;-- 19 + C_GREATER ;-- 20 + C_PERCENT ;-- 21 + C_COMMA ;-- 22 + C_SEMICOL ;-- 23 + C_AT ;-- 24 + C_DOT ;-- 25 + C_MONEY ;-- 26 + C_SIGN ;-- 27 + C_CARET ;-- 28 + C_BIN ;-- 29 + C_WORD ;-- 30 + C_ILLEGAL ;-- 31 + C_EOF ;-- 32 ] lex-classes: [ @@ -231,9 +231,9 @@ lexer: context [ err [integer!] ] - scanner!: alias function! [state [state!] return: [byte-ptr!]] - + scanner!: alias function! [state [state!]] +comment { scan-string: func [state [state!] return: [byte-ptr!] /local p [byte-ptr!] @@ -255,78 +255,205 @@ lexer: context [ p ] - - scan-alt-string: func [state [state!] return: [byte-ptr!] +} + scan-eof: func [state [state!] ; /local ][ null ] - - scan-block: func [state [state!] return: [byte-ptr!] + + scan-error: func [state [state!] + ; /local + ][ + null + ] + + scan-block-open: func [state [state!] ; /local ][ null ] - scan-paren: func [state [state!] return: [byte-ptr!] + scan-block-close: func [state [state!] ; /local ][ null ] - scan-paren-close: func [state [state!] return: [byte-ptr!] + scan-paren-open: func [state [state!] ; /local ][ null ] - scan-comment: func [state [state!] return: [byte-ptr!] + scan-paren-close: func [state [state!] ; /local ][ null ] - scan-file: func [state [state!] return: [byte-ptr!] + scan-string: func [state [state!] + ; /local + ][ + null + ] + + scan-string-multi: func [state [state!] ; /local ][ null ] - scan-refinement: func [state [state!] return: [byte-ptr!] + scan-word: func [state [state!] ; /local ][ null ] - scan-money: func [state [state!] return: [byte-ptr!] + scan-file: func [state [state!] ; /local ][ null ] - scan-lesser: func [state [state!] return: [byte-ptr!] + scan-refinement: func [state [state!] ; /local ][ null ] - scan-lit: func [state [state!] return: [byte-ptr!] + scan-binary: func [state [state!] + ; /local + ][ + null + ] + + scan-char: func [state [state!] + ; /local + ][ + null + ] + + scan-map-open: func [state [state!] + ; /local + ][ + null + ] + + scan-construct: func [state [state!] + ; /local + ][ + null + ] + + scan-issue: func [state [state!] + ; /local + ][ + null + ] + + scan-percent: func [state [state!] + ; /local + ][ + null + ] + + scan-integer: func [state [state!] ; /local ][ null ] - scan-get: func [state [state!] return: [byte-ptr!] + scan-float: func [state [state!] ; /local ][ null ] - scan-sharp: func [state [state!] return: [byte-ptr!] + scan-tuple: func [state [state!] ; /local ][ null ] + + scan-date: func [state [state!] + ; /local + ][ + null + ] + + scan-pair: func [state [state!] + ; /local + ][ + null + ] + + scan-time: func [state [state!] + ; /local + ][ + null + ] + + scan-money: func [state [state!] + ; /local + ][ + null + ] + + scan-tag: func [state [state!] + ; /local + ][ + null + ] + + scan-url: func [state [state!] + ; /local + ][ + null + ] + + scan-email: func [state [state!] + ; /local + ][ + null + ] + + scan-path: func [state [state!] + ; /local + ][ + null + ] + + scanners: [ + :scan-eof ;-- T_EOF + :scan-error ;-- T_ERROR + :scan-block-open ;-- T_BLK_OP + :scan-block-close ;-- T_BLK_CL + :scan-paren-open ;-- T_PAR_OP + :scan-paren-close ;-- T_PAR_CL + :scan-string ;-- T_STRING + :scan-string-multi ;-- T_STR_ALT + :scan-word ;-- T_WORD + :scan-file ;-- T_FILE + :scan-refinement ;-- T_REFINE + :scan-binary ;-- T_BINARY + :scan-char ;-- T_CHAR + :scan-map-open ;-- T_MAP_OP + :scan-construct ;-- T_CONS_MK + :scan-issue ;-- T_ISSUE + :scan-percent ;-- T_PERCENT + :scan-integer ;-- T_INTEGER + :scan-float ;-- T_FLOAT + :scan-tuple ;-- T_TUPLE + :scan-date ;-- T_DATE + :scan-pair ;-- T_PAIR + :scan-time ;-- T_TIME + :scan-money ;-- T_MONEY + :scan-tag ;-- T_TAG + :scan-url ;-- T_URL + :scan-email ;-- T_EMAIL + :scan-path ;-- T_PATH + ] scan-tokens: func [ lex [state!] @@ -338,19 +465,23 @@ lexer: context [ class [integer!] index [integer!] state [integer!] + flags [integer!] line [integer!] s [series!] + scanner [scanner!] ][ parent: lex/parent s: GET_BUFFER(parent) p: lex/pos state: 0 - line: 1 + flags: 0 + line: 1 loop lex/remain [ cp: 1 + as-integer p/value - class: lex-classes/cp - index: state + class + 1 + class: lex-classes/cp + flags: class and FFFFFF00h or flags + index: state * 33 + (class and FFh) + 1 state: as-integer transitions/index ;line: line + line-table/class p: p + 1 @@ -359,7 +490,9 @@ lexer: context [ lex/remain: as-integer p - lex/pos lex/pos: p - + index: state - --EXIT_STATES-- + 1 + scanner: as scanner! scanners/index + scanner lex ] @@ -372,7 +505,7 @@ lexer: context [ state [state! value] ][ state/parent: block/make-in dst 100 - state/buffer: as cell! alloc-big 1000 * size? cell! + state/buffer: as cell! allocate 1000 * size? cell! state/buf-head: state/buffer state/buf-tail: state/buffer + 1000 state/head: src @@ -384,6 +517,8 @@ lexer: context [ if system/thrown > 0 [ 0 ; error handling ] + + free as byte-ptr! state/buffer ] init: func [][ From 252adef0300e8f5f3c4151cc710eda5fd38e00c2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 7 Oct 2019 23:24:10 +0200 Subject: [PATCH 0185/3432] FEAT: improves states transition on EOF character. --- docs/lexer/lexer-FSM.csv | 58 ++++++++++++++++----------------- docs/lexer/lexer-FSM.xlsx | Bin 14185 -> 14527 bytes runtime/lexer-transitions.reds | 58 ++++++++++++++++----------------- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 0265272b77..d92e5db395 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -2,42 +2,42 @@ S_START;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_BLANK;S_BLANK;S_BLANK;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF -S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STR_ALT;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STR_ALT;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_EOF -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_EOF -S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_EOF -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_EOF -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;T_ERROR;S_BINARY;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_EOF -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;T_ERROR;S_BINARY;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_EOF -S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_EOF -S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_EOF -S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_EOF -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_EOF -S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_EOF -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_EOF -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_EOF -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_EOF -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_EOF -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_EOF -S_SIGN;S_WORD;S_WORD;S_NUMBER;S_NUMBER;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_EOF -S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_EOF -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_EOF -S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EOF +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;S_WORD;S_WORD;S_NUMBER;S_NUMBER;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index a29d030e762f71a98a0ce11d2a88366798173cb7..c4803b84651df7db9295b99cc6b3b12431d75097 100644 GIT binary patch literal 14527 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 Date: Mon, 7 Oct 2019 23:24:59 +0200 Subject: [PATCH 0186/3432] FEAT: simplify code by inlining scanner's macros used only once. --- runtime/lexer.reds | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 40502e3020..250af20fa2 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -24,17 +24,11 @@ lexer: context [ C_FLAG_QUOTE: 02000000h C_FLAG_EXP: 01000000h C_FLAG_SHARP: 00800000h + C_FLAG_EOF: 00400000h ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] #define FL_UCS2 [(C_WORD or C_FLAG_UCS2)] - #define FL_CARET [(C_CARET or C_FLAG_CARET)] - #define FL_DOT [(C_DOT or C_FLAG_DOT)] - #define FL_COMMA [(C_COMMA or C_FLAG_COMMA)] - #define FL_COLON [(C_COLON or C_FLAG_COLON)] - #define FL_QUOTE [(C_QUOTE or C_FLAG_QUOTE)] - #define FL_EXP [(C_EXP or C_FLAG_EXP)] - #define FL_SHARP [(C_SHARP or C_FLAG_SHARP)] #enum character-classes! [ C_BLANK ;-- 0 @@ -73,7 +67,7 @@ lexer: context [ ] lex-classes: [ - C_EOF ;-- 00 NUL + (C_EOF or C_FLAG_EOF) ;-- 00 NUL C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 01-08 C_BLANK ;-- 09 TAB C_BLANK ;-- 0A LF @@ -86,23 +80,23 @@ lexer: context [ C_BLANK ;-- 20 C_WORD ;-- 21 ! C_DBL_QUOTE ;-- 22 " - FL_SHARP ;-- 23 # + (C_SHARP or C_FLAG_SHARP) ;-- 23 # C_MONEY ;-- 24 $ C_PERCENT ;-- 25 % C_WORD ;-- 26 & - FL_QUOTE ;-- 27 ' + (C_QUOTE or C_FLAG_QUOTE) ;-- 27 ' C_PAREN_OP ;-- 28 ( C_PAREN_CL ;-- 29 ) C_WORD ;-- 2A * C_SIGN ;-- 2B + - FL_COMMA ;-- 2C , + (C_COMMA or C_FLAG_COMMA) ;-- 2C , C_SIGN ;-- 2D - - FL_DOT ;-- 2E . + (C_DOT or C_FLAG_DOT) ;-- 2E . C_SLASH ;-- 2F / C_ZERO ;-- 30 0 C_DIGIT C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 31-35 1-5 C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 36-39 6-9 - FL_COLON ;-- 3A : + (C_COLON or C_FLAG_COLON) ;-- 3A : C_SEMICOL ;-- 3B ; C_LESSER ;-- 3C < C_WORD ;-- 3D = @@ -110,7 +104,7 @@ lexer: context [ C_WORD ;-- 3F ? C_AT ;-- 40 @ C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 41-44 A-D - FL_EXP ;-- 45 E + (C_EXP or C_FLAG_EXP) ;-- 45 E C_ALPHAX ;-- 46 F C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R @@ -120,7 +114,7 @@ lexer: context [ C_BLOCK_OP ;-- 5B [ C_BSLASH ;-- 5C \ C_BLOCK_CL ;-- 5D ] - FL_CARET ;-- 5E ^ + (C_CARET or C_FLAG_CARET) ;-- 5E ^ C_WORD ;-- 5F _ C_WORD ;-- 60 ` C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d From b77c0945f72fb12518da39d76af6f64cf6ed7154 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 8 Oct 2019 00:48:06 +0200 Subject: [PATCH 0187/3432] FEAT: syntax for array expressions limited to math and bitwise operations. --- system/compiler.r | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index d7410afa25..95111dbf58 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -241,6 +241,11 @@ system-dialect: make-profilable context [ return catch ] + array-expr-keywords: compose [ + 'or | 'and | 'xor | '+ | '- | (to-lit-word "/") + | '* | (to-lit-word "%") | (to-lit-word "//") + ] + foreach [word action] keywords [append keywords-list word] foreach [name spec] functions [append keywords-list name] @@ -1156,11 +1161,13 @@ system-dialect: make-profilable context [ preprocess-array: func [list [block!] /local p s v][ parse list [ some [ - p: word! (check-enum-symbol p) :p ['true | 'false] (p/1: do p/1) + ['true | 'false] (p/1: do p/1) + | p: 'null (p/1: 0) + | p: word! (check-enum-symbol/strict p) :p | p: paren! :p into [any [ - s: word! (check-enum-symbol s) | skip + array-expr-keywords | s: word! (check-enum-symbol/strict s) | skip ]] :p (change p do p/1) - | string! | char! | integer! | decimal! | get-word! | p: 'null (p/1: 0) + | string! | char! | integer! | decimal! | get-word! ] | (throw-error ["invalid literal array content:" mold list]) ] to paren! list @@ -3497,13 +3504,15 @@ system-dialect: make-profilable context [ ] ] - check-enum-symbol: func [code [any-block!] /local value][ - if all [ ;-- if enum, replace it with its integer value + check-enum-symbol: func [code [any-block!] /strict /local value][ + either all [ ;-- if enum, replace it with its integer value word? code/1 not local-variable? code/1 value: get-enumerator resolve-ns code/1 ][ change code value + ][ + if strict [throw-error ["unknown identifier in literal array:" code/1]] ] ] From e9d9ad35a4d5c000c181c4fd5a9a8eff0b996da6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 8 Oct 2019 00:48:55 +0200 Subject: [PATCH 0188/3432] FIX: missing macro inlining. --- runtime/lexer.reds | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 250af20fa2..cc8aa4f388 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -15,16 +15,16 @@ lexer: context [ #include %lexer-transitions.reds #enum class-flags! [ - C_FLAG_UCS4: 80000000h - C_FLAG_UCS2: 40000000h - C_FLAG_CARET: 20000000h - C_FLAG_DOT: 10000000h - C_FLAG_COMMA: 08000000h - C_FLAG_COLON: 04000000h - C_FLAG_QUOTE: 02000000h - C_FLAG_EXP: 01000000h - C_FLAG_SHARP: 00800000h - C_FLAG_EOF: 00400000h + C_FLAG_UCS4: 80000000h + C_FLAG_UCS2: 40000000h + C_FLAG_CARET: 20000000h + C_FLAG_DOT: 10000000h + C_FLAG_COMMA: 08000000h + C_FLAG_COLON: 04000000h + C_FLAG_QUOTE: 02000000h + C_FLAG_EXP: 01000000h + C_FLAG_SHARP: 00800000h + C_FLAG_EOF: 00400000h ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] @@ -118,7 +118,7 @@ lexer: context [ C_WORD ;-- 5F _ C_WORD ;-- 60 ` C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d - FL_EXP ;-- 65 e + (C_EXP or C_FLAG_EXP) ;-- 65 e C_ALPHAX ;-- 66 f C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 67-6C g-l C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 6D-72 m-r From 2726e9aedd2857bc70269c9db4ae79dfd4afae03 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Sep 2019 10:10:22 +0800 Subject: [PATCH 0189/3432] FIX: remove `response` check --- modules/view/backends/gtk3/events.reds | 129 ++++++++----------------- modules/view/backends/platform.red | 39 -------- 2 files changed, 38 insertions(+), 130 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index dd93b6e35c..4473d2bb01 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -574,18 +574,6 @@ debug-connect-level: DEBUG_CONNECT_NONE debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and level <> 0] - -respond-event?: func [ - actors [red-object!] - type [red-word!] - return: [logic!] -][ - if null? actors/ctx [ - return false - ] - -1 <> object/rs-find actors as red-value! type -] - connect-container-events: func [ widget [handle!] evt-type [c-string!] @@ -633,70 +621,42 @@ connect-common-events: function [ ][ assert widget <> null - if any [ - respond-event? actors on-down - respond-event? actors on-mid-down - respond-event? actors on-alt-down - respond-event? actors on-aux-down - ][ - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-press-event" - ] - gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-press-event" ] - if respond-event? actors on-over [ - gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "motion-notify-event" - ] - gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) + gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + + gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "motion-notify-event" ] + gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) - if any [ - sym = field - sym = area - respond-event? actors on-up - respond-event? actors on-mid-up - respond-event? actors on-alt-up - respond-event? actors on-aux-up - ][ - gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-release-event" - ] - gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) - ] - if any [ - respond-event? actors on-key - respond-event? actors on-key-down - respond-event? actors on-focus - respond-event? actors on-enter - ][ - gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK - gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) + gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "button-release-event" ] + gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) - if any [ - respond-event? actors on-key-up - respond-event? actors on-unfocus - ][ - gtk_widget_add_events widget GDK_KEY_RELEASE_MASK - gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) - ] + gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK + gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) - if respond-event? actors on-wheel [ - gtk_widget_add_events widget GDK_SCROLL_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "scroll-event" - ] - gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) + gtk_widget_add_events widget GDK_KEY_RELEASE_MASK + gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) + + + gtk_widget_add_events widget GDK_SCROLL_MASK + if container-type? sym [ + ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH + connect-container-events widget "scroll-event" ] + gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) ] connect-focus-events: function [ @@ -705,12 +665,8 @@ connect-focus-events: function [ actors [red-object!] sym [integer!] ][ - if respond-event? actors on-focus [ - gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) - ] - if respond-event? actors on-unfocus [ - gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) - ] + gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) + gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) ] connect-notify-events: function [ @@ -720,12 +676,10 @@ connect-notify-events: function [ sym [integer!] ][ assert widget <> null - if respond-event? actors on-over [ - if sym = text [widget: _widget? widget] - gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK - gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) - gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) - ] + if sym = text [widget: _widget? widget] + gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK + gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) + gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) ] connect-widget-events: function [ @@ -753,10 +707,8 @@ connect-widget-events: function [ gobj_signal_connect(widget "toggled" :button-toggled face/ctx) ] sym = button [ - if respond-event? actors on-click [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] - gobj_signal_connect(widget "clicked" :button-clicked null) - ] + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] + gobj_signal_connect(widget "clicked" :button-clicked null) ] sym = base [ gobj_signal_connect(widget "draw" :base-draw face/ctx) @@ -823,13 +775,8 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes ] sym = tab-panel [ - if any [ - respond-event? actors on-select - respond-event? actors on-change - ][ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] - gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) - ] + ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] + gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) ] sym = text-list [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index d681c42c8b..9ab7b19a0d 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -374,45 +374,6 @@ system/view/platform: context [ _right-command: word/load "right-command" _caps-lock: word/load "caps-lock" _num-lock: word/load "num-lock" - - on-key: word/load "on-key" - on-key-down: word/load "on-key-down" - on-key-up: word/load "on-key-up" - on-ime: word/load "on-ime" - on-focus: word/load "on-focus" - on-unfocus: word/load "on-unfocus" - on-enter: word/load "on-enter" - on-zoom: word/load "on-zoom" - on-pan: word/load "on-pan" - on-rotate: word/load "on-rotate" - on-two-tap: word/load "on-two-tap" - on-press-tap: word/load "on-press-tap" - - on-close: word/load "on-close" - on-move: word/load "on-move" - on-moving: word/load "on-moving" - on-size: word/load "on-size" - on-sizing: word/load "on-sizing" - on-time: word/load "on-time" - on-drawing: word/load "on-drawing" - on-scroll: word/load "on-scroll" - on-over: word/load "on-over" - on-select: word/load "on-select" - on-change: word/load "on-change" - on-menu: word/load "on-menu" - - on-down: word/load "on-down" - on-up: word/load "on-up" - on-mid-down: word/load "on-mid-down" - on-mid-up: word/load "on-mid-up" - on-alt-down: word/load "on-alt-down" - on-alt-up: word/load "on-alt-up" - on-aux-down: word/load "on-aux-down" - on-aux-up: word/load "on-aux-up" - on-click: word/load "on-click" - on-dbl-click: word/load "on-dbl-click" - on-wheel: word/load "on-wheel" - on-over: word/load "on-over" red/boot?: no red/collector/active?: yes From 105fdc873b037ff5c997b811a2eb286c7a0b3d7e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Sep 2019 11:12:03 +0800 Subject: [PATCH 0190/3432] Revert "FIX: memory leak for face object" This reverts commit 9e1bdad719141e22c0bf5375b191f63b186cb172. --- modules/view/backends/gtk3/gui.reds | 31 +++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7e601767d0..6a46f63507 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -2045,11 +2045,8 @@ OS-make-view: func [ ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events - either sym = text [ - store-face-to-obj _widget face - ][ - store-face-to-obj widget face - ] + store-face-to-obj widget face + if sym = text [store-face-to-obj _widget face] change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym @@ -2240,25 +2237,25 @@ OS-destroy-view: func [ gtk_widget_destroy handle win-cnt: win-cnt - 1 ][ - ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] - obj: as red-object! values + FACE_OBJ_FONT - if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] + ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] - obj: as red-object! values + FACE_OBJ_PARA - if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] + obj: as red-object! values + FACE_OBJ_FONT + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] - ;;g_main_context_release GTKApp-Ctx - ;; DEBUG: + obj: as red-object! values + FACE_OBJ_PARA + if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] + + ;;g_main_context_release GTKApp-Ctx + ;; DEBUG: - ;; TODO: This can be useless now! - remove-all-timers handle + ;; TODO: This can be useless now! + remove-all-timers handle - ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] + ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] - free-handles as-integer handle no + free-handles as-integer handle no ] - free as byte-ptr! g_object_get_qdata handle red-face-id ] OS-update-facet: func [ From 23e791d80ec505a3e8e42a57cd14357e8223b7c4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 29 Sep 2019 09:26:01 +0800 Subject: [PATCH 0191/3432] FIX: remove no used argument `actors` --- modules/view/backends/gtk3/events.reds | 24 ++++++++++-------------- modules/view/backends/gtk3/gui.reds | 5 +---- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 4473d2bb01..a6d93e31aa 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -616,7 +616,6 @@ connect-container-events: func [ connect-common-events: function [ widget [handle!] face [red-object!] - actors [red-object!] sym [integer!] ][ assert widget <> null @@ -662,7 +661,6 @@ connect-common-events: function [ connect-focus-events: function [ widget [handle!] face [red-object!] - actors [red-object!] sym [integer!] ][ gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) @@ -672,7 +670,6 @@ connect-focus-events: function [ connect-notify-events: function [ widget [handle!] face [red-object!] - actors [red-object!] sym [integer!] ][ assert widget <> null @@ -683,17 +680,16 @@ connect-notify-events: function [ ] connect-widget-events: function [ - widget [handle!] - face [red-object!] - actors [red-object!] - sym [integer!] - _widget [handle!] + widget [handle!] + face [red-object!] + sym [integer!] + _widget [handle!] parent [handle!] /local buffer [handle!] ][ ;; register red mouse, key and window on event functions - connect-common-events widget face actors sym + connect-common-events widget face sym case [ sym = check [ @@ -723,7 +719,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - connect-focus-events widget face actors sym + connect-focus-events widget face sym ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] @@ -732,7 +728,7 @@ connect-widget-events: function [ gobj_signal_connect(widget "configure-event" :window-configure-event null) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate null) - connect-focus-events widget face actors sym + connect-focus-events widget face sym ] sym = slider [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] @@ -745,7 +741,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - connect-focus-events widget face actors sym + connect-focus-events widget face sym ] sym = progress [ 0 @@ -763,7 +759,7 @@ connect-widget-events: function [ gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - connect-focus-events widget face actors sym + connect-focus-events widget face sym ] sym = group-box [ 0 @@ -793,5 +789,5 @@ connect-widget-events: function [ ] true [0] ] - connect-notify-events widget face actors sym + connect-notify-events widget face sym ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 6a46f63507..967a642d38 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1752,7 +1752,6 @@ OS-make-view: func [ fvalue [float!] vertical? [logic!] rfvalue [red-float!] - actors [red-object!] ][ stack/mark-native words/_body @@ -1777,8 +1776,6 @@ OS-make-view: func [ bits: get-flags as red-block! values + FACE_OBJ_FLAGS sym: symbol/resolve type/symbol - actors: as red-object! values + FACE_OBJ_ACTORS - ; if bits and FACET_FLAGS_SCROLLABLE <> 0 [ ; flags: flags or WS_HSCROLL or WS_VSCROLL ; ] @@ -2039,7 +2036,7 @@ OS-make-view: func [ ] ; Deal with actors - connect-widget-events widget face actors sym _widget as int-ptr! parent + connect-widget-events widget face sym _widget as int-ptr! parent unless any[sym = window sym = area][build-context-menu widget menu] From b69710b2a9469ac3d2c372481e827b7b054757c4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 30 Sep 2019 09:19:54 +0800 Subject: [PATCH 0192/3432] FIX: remove no needed drag-on codes --- modules/view/backends/gtk3/gui.reds | 31 -------- modules/view/backends/gtk3/handlers.reds | 93 ------------------------ 2 files changed, 124 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 967a642d38..5e6fa60518 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1617,13 +1617,6 @@ parse-common-opts: func [ while [len > 0][ sym: symbol/resolve word/symbol case [ - sym = _drag-on [ - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK ;or GDK_ENTER_NOTIFY_MASK - gobj_signal_connect(widget "motion-notify-event" :drag-widget-motion-notify-event face/ctx) - gobj_signal_connect(widget "button-press-event" :drag-widget-button-press-event face/ctx) - gobj_signal_connect(widget "button-release-event" :drag-widget-button-release-event face/ctx) - set-draggable widget yes - ] sym = _cursor [ ;; DEBUG: print ["set cursor: " widget lf] w: word + 1 @@ -1647,36 +1640,12 @@ parse-common-opts: func [ ] set-cursor widget hcur ] - ; sym = _class [ - ; w: word + 1 - ; sym: symbol/resolve w/symbol - ; sym: case [ - ; sym = _regular [0] ;-- 32 - ; sym = _small [1] ;-- 28 - ; sym = _mini [2] ;-- 16 - ; true [0] - ; ] - ; objc_msgSend [ - ; objc_msgSend [widget sel_getUid "cell"] - ; sel_getUid "setControlSize:" sym - ; ] - ; btn?: no - ; ] - ; sym = _accelerated [ - ; bool: as red-logic! word + 1 - ; if bool/value [objc_msgSend [widget sel_getUid "setWantsLayer:" yes]] - ; ] true [0] ] word: word + 2 len: len - 2 ] ] - - ; if type = button [ - ; len: either btn? [NSRegularSquareBezelStyle][NSRoundedBezelStyle] - ; objc_msgSend [widget sel_getUid "setBezelStyle:" len] - ; ] ] OS-redraw: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index ccd3cae690..f5c8919069 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -625,99 +625,6 @@ widget-leave-notify-event: func [ 0;;no ] -drag-widget-motion-notify-event: func [ - [cdecl] - widget [handle!] - event [GdkEventMotion!] - ctx [node!] - return: [integer!] - /local - offset [red-pair!] - x [float!] - y [float!] - flags [integer!] - state [integer!] - -][ - state: 0 - ;; DEBUG: print [ "DRAG MOTION: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - if evt-motion/state [ - if 0 = (evt-motion/cpt % evt-motion/sensitiv) [ - x: event/x_root - evt-motion/x_root - y: event/y_root - evt-motion/y_root - evt-motion/x_new: as-integer x + either x > 0.0 [0.5][-0.5] - evt-motion/y_new: as-integer y + either y > 0.0 [0.5][-0.5] - ;; DEBUG: print ["new " evt-motion/x_new "x" evt-motion/y_new lf] - evt-motion/x_root: event/x_root - evt-motion/y_root: event/y_root - flags: check-flags event/type event/state - state: make-event widget flags EVT_OVER - ] - evt-motion/cpt: evt-motion/cpt + 1 - state: 1;;yes - ] - state -] - -drag-widget-button-press-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - offset [red-pair!] - flags [integer!] -][ - ;; DEBUG: print [ "DRAG BUTTON-PRESS: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - if any[ - event/button = GDK_BUTTON_PRIMARY - event/button = GDK_BUTTON_SECONDARY - ][ - evt-motion/state: yes - evt-motion/cpt: 0 - evt-motion/x_root: event/x_root - evt-motion/y_root: event/y_root - evt-motion/x_new: 0 - evt-motion/y_new: 0 - ] - flags: check-flags event/type event/state - make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_DOWN] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_DOWN] true [EVT_LEFT_DOWN]] - 1;;yes -] - -drag-widget-button-release-event: func [ - [cdecl] - widget [handle!] - event [GdkEventButton!] - ctx [node!] - return: [integer!] - /local - type [red-word!] - sym [integer!] - state [logic!] - flags [integer!] -][ - ;; DEBUG: print [ "Drag -> BUTTON-RELEASE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - unless any[event/button = GDK_BUTTON_PRIMARY event/button = GDK_BUTTON_SECONDARY event/button = GDK_BUTTON_MIDDLE] [return 0] - ; Special treatment for check and radio buttons (TODO: button) - type: as red-word! get-node-facet ctx FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - - if all [ - any [sym = check sym = radio] - evt-motion/cpt = 0 ; IMPORTANT: change state only if no dragging! - ][ - state: gtk_toggle_button_get_active widget - gtk_toggle_button_set_active widget either sym = check [not state][yes] - ] - - evt-motion/state: no - flags: check-flags event/type event/state - make-event widget flags case [event/button = GDK_BUTTON_SECONDARY [EVT_RIGHT_UP] event/button = GDK_BUTTON_MIDDLE [EVT_MIDDLE_UP] true [EVT_LEFT_UP]] - EVT_NO_DISPATCH -] - container-emit-event: func [ [cdecl] widget [handle!] From a9c14ea4789327c133c3a178d36c1f215f5a1607 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 30 Sep 2019 09:54:02 +0800 Subject: [PATCH 0193/3432] FIX: improve cursor initial --- modules/view/backends/gtk3/gui.reds | 38 ++++++----------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5e6fa60518..4dc2b428ee 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -44,7 +44,6 @@ size-id: g_quark_from_string "size-id" real-container-id: g_quark_from_string "real-container-id" menu-id: g_quark_from_string "menu-id" drag-id: g_quark_from_string "drag-id" -cursor-id: g_quark_from_string "cursor-id" no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" @@ -210,22 +209,6 @@ parent-window?: func [ g_object_get_qdata widget parent-window-id ] -set-cursor: func [ - widget [handle!] - cursor [handle!] -][ - g_object_set_qdata widget cursor-id cursor -] - -cursor?: func [ - widget [handle!] - return: [handle!] - /local - window [handle!] -][ - g_object_get_qdata widget cursor-id -] - ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) set-real-widget: func [ _widget [handle!] @@ -1015,8 +998,6 @@ init-all-children: func [ tail [red-object!] values [red-value!] show? [red-logic!] - cursor [handle!] - win [handle!] ][ values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE @@ -1028,13 +1009,7 @@ init-all-children: func [ ; init invisible show?: as red-logic! values + FACE_OBJ_VISIBLE? gtk_widget_set_visible widget show?/value - ; init cursor - cursor: cursor? widget - unless null? cursor [ - win: gtk_widget_get_window widget - ;; DEBUG: print ["win: " win lf] - unless null? win [gdk_window_set_cursor win cursor] - ] + ;;;;; init end if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ @@ -1606,10 +1581,7 @@ parse-common-opts: func [ win [handle!] x [integer!] y [integer!] - ;;;btn? [logic!] ][ - ;; DEBUG: print ["parse-common-opts: " get-symbol-name type lf] - ;;;btn?: yes if TYPE_OF(options) = TYPE_BLOCK [ word: as red-word! block/rs-head options len: block/rs-length? options @@ -1638,7 +1610,8 @@ parse-common-opts: func [ ] hcur: gdk_cursor_new_from_name display cur ] - set-cursor widget hcur + win: gtk_widget_get_window widget + gdk_window_set_cursor win hcur ] true [0] ] @@ -1927,7 +1900,6 @@ OS-make-view: func [ ] ] - parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] @@ -2029,6 +2001,10 @@ OS-make-view: func [ change-color widget as red-tuple! values + FACE_OBJ_COLOR sym + ;-- we need first realize widget to get wdk-window, then can set cursor + gtk_widget_realize widget + parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym + ;; USELESS: if sym <> window [gtk_widget_show widget] stack/unwind as-integer widget From 0d2548aa1f36bdb45b5608a20f89ebbb4f0a4760 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 30 Sep 2019 10:32:08 +0800 Subject: [PATCH 0194/3432] FIX: clean init-all-children --- modules/view/backends/gtk3/gui.reds | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 4dc2b428ee..4c576564ea 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -990,28 +990,19 @@ change-size: func [ init-all-children: func [ widget [handle!] /local - child [handle!] + values [red-value!] pane [red-block!] - type [red-word!] - sym [integer!] + show? [red-logic!] face [red-object!] tail [red-object!] - values [red-value!] - show? [red-logic!] + child [handle!] ][ values: get-face-values widget - type: as red-word! values + FACE_OBJ_TYPE pane: as red-block! values + FACE_OBJ_PANE - sym: symbol/resolve type/symbol - ;;;;; init begin - ;; DEBUG: print ["init-all-children: " get-symbol-name sym lf] - ; init invisible show?: as red-logic! values + FACE_OBJ_VISIBLE? gtk_widget_set_visible widget show?/value - ;;;;; init end - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane From 72521fdce7573a56e706acf60d0811fc4fac915c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 30 Sep 2019 14:36:18 +0800 Subject: [PATCH 0195/3432] FIX: remove capture inactive widget as win/macos also not support --- modules/view/backends/gtk3/gui.reds | 74 +++++------------------------ 1 file changed, 13 insertions(+), 61 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 4c576564ea..2aaed3c92b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -37,7 +37,6 @@ gtk-style-id: g_quark_from_string "gtk-style-id" _widget-id: g_quark_from_string "_widget-id" real-widget-id: g_quark_from_string "real-widget-id" gtk-container-id: g_quark_from_string "gtk-container-id" -parent-window-id: g_quark_from_string "parent-window-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" @@ -195,20 +194,6 @@ _widget?: func [ return _widget ] -set-parent-window: func [ - widget [handle!] - window [handle!] -][ - g_object_set_qdata widget parent-window-id window -] - -parent-window?: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget parent-window-id -] - ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) set-real-widget: func [ _widget [handle!] @@ -1900,7 +1885,6 @@ OS-make-view: func [ sym <> window parent <> 0 ][ - set-parent-window widget last-window p-sym: get-widget-symbol as handle! parent either null? _widget [_widget: widget][set-_widget widget _widget ] ; TODO: case to replace with either if no more choice @@ -2250,9 +2234,8 @@ OS-to-image: func [ word [red-word!] type [integer!] size [red-pair!] + offset [red-pair!] ret [red-image!] - list [GList!] - child [GList!] ][ word: as red-word! get-node-facet face/ctx FACE_OBJ_TYPE type: symbol/resolve word/symbol @@ -2264,7 +2247,7 @@ OS-to-image: func [ width: gdk_window_get_width win height: gdk_window_get_height win xwin: gdk_x11_window_get_xid win - win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin + win: gdk_x11_window_foreign_new_for_display gdk_window_get_display win xwin either null? win [ret: as red-image! none-value] [ pixbuf: gdk_pixbuf_get_from_window win 0 0 width height ;screen-size-x screen-size-y; CGWindowListCreateImage 0 0 7F800000h 7F800000h 1 0 0 ;-- INF @@ -2275,50 +2258,19 @@ OS-to-image: func [ widget: face-handle? face ;; DEBUG: print ["widget: " widget lf] either null? widget [ret: as red-image! none-value][ - either gtk_window_is_active parent-window? widget [ - size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE - win: gtk_widget_get_window widget - if not null? win [ - ;; DEBUG: print ["win: " win " size: " size/x "x" size/y lf] - pixbuf: gdk_pixbuf_get_from_window win 0 0 size/x size/y - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf - ;g_object_unref pixbuf - ] - ][ - either type = window [ - win: gtk_offscreen_window_new - - list: as GList! gtk_container_get_children widget - child: list - while [not null? child][ - g_object_ref child/data ; to avoid destruction before removing from container - gtk_container_remove widget child/data - gtk_container_add win child/data - ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] - child: child/next - ] - g_list_free as int-ptr! list - gtk_widget_show_all win - gtk_widget_queue_draw win - pixbuf: gtk_offscreen_window_get_pixbuf win - ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf - - list: as GList! gtk_container_get_children win - child: list - while [not null? child][ - g_object_ref child/data ; to avoid destruction before removing from container - gtk_container_remove win child/data - gtk_container_add widget child/data - ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] - child: child/next - ] - g_list_free as int-ptr! list - + size: as red-pair! (object/get-values face) + FACE_OBJ_SIZE + offset: as red-pair! (object/get-values face) + FACE_OBJ_OFFSET + win: gtk_widget_get_window widget + either not null? win [ + ;; DEBUG: print ["win: " win " size: " size/x "x" size/y " offset: " offset/x "x" offset/y lf] + pixbuf: either type = window [ + gdk_pixbuf_get_from_window win 0 0 size/x size/y ][ - print ["Red/GTK warning: to-image not yet implemented when window is not active!"] - ret: as red-image! none-value + gdk_pixbuf_get_from_window win offset/x offset/y size/x size/y ] - ] + ret: image/init-image as red-image! stack/push* OS-image/load-pixbuf pixbuf + ;g_object_unref pixbuf + ][ret: as red-image! none-value] ] ] ] From 8c7224852f823c5b883d08d4a9a11807e32a2a20 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 1 Oct 2019 16:13:47 +0800 Subject: [PATCH 0196/3432] FIX: improve `build tab-group widget` --- build/includes.r | 1 + modules/view/backends/gtk3/gtk.reds | 24 +++- modules/view/backends/gtk3/gui.reds | 145 +++++++++------------- modules/view/backends/gtk3/handlers.reds | 4 - modules/view/backends/gtk3/tab-panel.reds | 68 ++++++++++ modules/view/view.red | 2 +- 6 files changed, 149 insertions(+), 95 deletions(-) create mode 100644 modules/view/backends/gtk3/tab-panel.reds diff --git a/build/includes.r b/build/includes.r index 5a0a206e5a..8b0c435bc3 100644 --- a/build/includes.r +++ b/build/includes.r @@ -237,6 +237,7 @@ write %build/bin/sources.r set-cache [ %menu.reds %para.reds %rules.red + %tab-panel.reds %text-box.reds ] %test/ [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 211d6e048b..340936ddc9 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1866,7 +1866,7 @@ GPtrArray!: alias struct! [ ] gtk_combo_box_set_popup_fixed_width: "gtk_combo_box_set_popup_fixed_width" [ combo [handle!] - fixed [logic!] + fixed [logic!] ] gtk_notebook_new: "gtk_notebook_new" [ return: [handle!] @@ -1875,11 +1875,11 @@ GPtrArray!: alias struct! [ nb [handle!] pane [handle!] label [handle!] - return: [integer!] + return: [integer!] ] gtk_notebook_get_current_page: "gtk_notebook_get_current_page" [ nb [handle!] - return: [integer!] + return: [integer!] ] gtk_notebook_set_current_page: "gtk_notebook_set_current_page" [ @@ -1889,8 +1889,8 @@ GPtrArray!: alias struct! [ gtk_notebook_get_nth_page: "gtk_notebook_get_nth_page" [ nb [handle!] - index [integer!] - return: [handle!] + index [integer!] + return: [handle!] ] gtk_notebook_get_tab_label_text: "gtk_notebook_get_tab_label_text" [ nb [handle!] @@ -1899,7 +1899,19 @@ GPtrArray!: alias struct! [ ] gtk_notebook_get_n_pages: "gtk_notebook_get_n_pages" [ nb [handle!] - return: [integer!] + return: [integer!] + ] + gtk_notebook_remove_page: "gtk_notebook_remove_page" [ + nb [handle!] + index [integer!] + return: [integer!] + ] + gtk_notebook_insert_page: "gtk_notebook_insert_page" [ + nb [handle!] + pane [handle!] + label [handle!] + index [integer!] + return: [integer!] ] gtk_css_provider_new: "gtk_css_provider_new" [ return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 2aaed3c92b..8af550bb97 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -21,6 +21,7 @@ Red/System [ #include %menu.reds #include %handlers.reds #include %comdlgs.reds +#include %tab-panel.reds GTKApp: as handle! 0 GTKApp-Ctx: 0 @@ -42,15 +43,14 @@ css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" real-container-id: g_quark_from_string "real-container-id" menu-id: g_quark_from_string "menu-id" -drag-id: g_quark_from_string "drag-id" no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" +cursor-id: g_quark_from_string "cursor-id" + +#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] +#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] group-radio: as handle! 0 -tabs: context [ - nb: 0 - cur: 0 -] settings: as handle! 0 pango-context: as handle! 0 @@ -151,6 +151,20 @@ face-handle?: func [ null ] +get-face-handle: func [ + face [red-object!] + return: [integer!] + /local + state [red-block!] + int [red-integer!] +][ + state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE + assert TYPE_OF(state) = TYPE_BLOCK + int: as red-integer! block/rs-head state + assert TYPE_OF(int) = TYPE_HANDLE + int/value +] + get-widget-symbol: func [ widget [handle!] return: [integer!] @@ -251,20 +265,6 @@ container-type?: func [ type = rich-text ] -set-draggable: func [ - item [handle!] - key [logic!] -][ - g_object_set_qdata item drag-id as int-ptr! either key [1][0] -] - -draggable?: func [ - item [handle!] - return: [logic!] -][ - 1 = as integer! g_object_get_qdata item drag-id -] - set-view-no-wait: func [ window [handle!] key [logic!] @@ -978,6 +978,8 @@ init-all-children: func [ values [red-value!] pane [red-block!] show? [red-logic!] + cursor [handle!] + win [handle!] face [red-object!] tail [red-object!] child [handle!] @@ -988,6 +990,14 @@ init-all-children: func [ show?: as red-logic! values + FACE_OBJ_VISIBLE? gtk_widget_set_visible widget show?/value + cursor: GET-CURSOR(widget) + unless null? cursor [ + win: gtk_widget_get_window widget + unless null? win [ + gdk_window_set_cursor win cursor + ] + ] + if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane @@ -1554,7 +1564,6 @@ parse-common-opts: func [ hcur [handle!] pixbuf [handle!] display [handle!] - win [handle!] x [integer!] y [integer!] ][ @@ -1586,8 +1595,7 @@ parse-common-opts: func [ ] hcur: gdk_cursor_new_from_name display cur ] - win: gtk_widget_get_window widget - gdk_window_set_cursor win hcur + SET-CURSOR(widget hcur) ] true [0] ] @@ -1847,8 +1855,7 @@ OS-make-view: func [ ] sym = tab-panel [ widget: gtk_notebook_new - tabs/cur: 0 - tabs/nb: block/rs-length? data + set-tabs widget values ] sym = text-list [ widget: gtk_list_box_new @@ -1879,6 +1886,8 @@ OS-make-view: func [ ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] + parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym + ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] if all [ @@ -1889,66 +1898,38 @@ OS-make-view: func [ either null? _widget [_widget: widget][set-_widget widget _widget ] ; TODO: case to replace with either if no more choice ;; DEBUG: print ["Parent: " get-symbol-name p-sym " _widget" _widget lf] - case [ - p-sym = tab-panel [ - container: as handle! parent - ; widget is necessarily a panel and then same as _widget - data: get-widget-data container - str: (as red-string! block/rs-head data) + tabs/cur - caption: either TYPE_OF(str) = TYPE_STRING [ - len: -1 - unicode/to-utf8 str :len - ][ - "Tab" - ] - buffer: gtk_label_new caption - gtk_notebook_append_page container widget buffer - tabs/cur: tabs/cur + 1 - if tabs/cur = tabs/nb [tabs/cur: 0 tabs/nb: 0] - set-container widget container + + container: as handle! case [ + p-sym = window [ + g_object_get_qdata as handle! parent real-container-id + ] + any [p-sym = panel p-sym = rich-text p-sym = base] [parent] + p-sym = group-box [ + buffer: gtk_container_get_children as handle! parent + ;; DEBUG: print ["Parent when not container : " buffer/value lf] + buffer/value ] - ; p-sym = panel [ - ; container: as handle! parent - ; ;save gtk_fixed container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass - ; set-container widget container - ; if sym = text [set_container _widget container] - ; gtk_widget_set_size_request _widget size/x size/y - ; gtk_layout_put container _widget offset/x offset/y - ; ] true [ - container: as handle! case [ - p-sym = window [ - g_object_get_qdata as handle! parent real-container-id - ] - any [p-sym = panel p-sym = rich-text p-sym = base] [parent] - p-sym = group-box [ - buffer: gtk_container_get_children as handle! parent - ;; DEBUG: print ["Parent when not container : " buffer/value lf] - buffer/value - ] - true [ - ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug - ; buffer: gtk_container_get_children as handle! parent - ; ;; DEBUG: - ; print ["Parent when not container : " buffer/value lf] - ; buffer/value - - ;; redirect to the layout of the parent - ;; WARNING: (since completedly changed code) - print ["DEVEL WARNING: <> (ONLY FOR DEVELOPMENT SINCE CODE HAS FULLY CHANGED BUT IMPOSSIBLE TO TEST) " lf] - container? as handle! parent - ] - ] - ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[_widget: " _widget "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] - - ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass - set-container widget container - if sym = text [set-container _widget container] - gtk_widget_set_size_request _widget size/x size/y - gtk_layout_put container _widget offset/x offset/y - ;; DEBUG: print ["make-view: _widget: " offset/x "x" offset/y "x" size/x "x" size/y lf] + ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug + ; buffer: gtk_container_get_children as handle! parent + ; ;; DEBUG: + ; print ["Parent when not container : " buffer/value lf] + ; buffer/value + + ;; redirect to the layout of the parent + ;; WARNING: (since completedly changed code) + print ["DEVEL WARNING: <> (ONLY FOR DEVELOPMENT SINCE CODE HAS FULLY CHANGED BUT IMPOSSIBLE TO TEST) " lf] + container? as handle! parent ] ] + ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[_widget: " _widget "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] + + ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass + set-container widget container + if sym = text [set-container _widget container] + gtk_widget_set_size_request _widget size/x size/y + gtk_layout_put container _widget offset/x offset/y + ;; DEBUG: print ["make-view: _widget: " offset/x "x" offset/y "x" size/x "x" size/y lf] ] ; Deal with actors @@ -1976,10 +1957,6 @@ OS-make-view: func [ change-color widget as red-tuple! values + FACE_OBJ_COLOR sym - ;-- we need first realize widget to get wdk-window, then can set cursor - gtk_widget_realize widget - parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym - ;; USELESS: if sym <> window [gtk_widget_show widget] stack/unwind as-integer widget diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index f5c8919069..a708872f87 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -677,8 +677,6 @@ mouse-button-release-event: func [ flags [integer!] ev [integer!] ][ - if draggable? widget [return 0] ; delegate to drag - sym: get-widget-symbol widget if sym = field [ if event/button = GDK_BUTTON_PRIMARY [ @@ -749,7 +747,6 @@ mouse-button-press-event: func [ ;; DEBUG: print ["grab focus on mouse " widget lf] gtk_widget_grab_focus widget ] - if draggable? widget [return EVT_DISPATCH] ; delegate to drag ;; DEBUG: print ["with button " event/button lf] if event/button = GDK_BUTTON_SECONDARY [ @@ -793,7 +790,6 @@ mouse-motion-notify-event: func [ ][ ;; DEBUG: print [ "mouse -> MOTION: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] - if draggable? widget [return EVT_DISPATCH] ; delegate to drag evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y evt-motion/x_root: event/x_root diff --git a/modules/view/backends/gtk3/tab-panel.reds b/modules/view/backends/gtk3/tab-panel.reds new file mode 100644 index 0000000000..8b2488b514 --- /dev/null +++ b/modules/view/backends/gtk3/tab-panel.reds @@ -0,0 +1,68 @@ +Red/System [ + Title: "gtk3 Tab-panel widget" + Author: "bitbegin" + File: %tab-panel.reds + Tabs: 4 + Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +set-tabs: func [ + widget [handle!] + facets [red-value!] + /local + data [red-block!] + pane [red-block!] + str [red-string!] + tail [red-string!] + int [red-integer!] + nb [integer!] + item [integer!] + len [integer!] + title [c-string!] + label [handle!] + panel [handle!] + face [red-object!] + end [red-object!] +][ + nb: gtk_notebook_get_n_pages widget + loop nb [ + gtk_notebook_remove_page widget -1 + ] + + data: as red-block! facets + FACE_OBJ_DATA + pane: as red-block! facets + FACE_OBJ_PANE + nb: 0 + + if TYPE_OF(data) = TYPE_BLOCK [ + str: as red-string! block/rs-head data + tail: as red-string! block/rs-tail data + face: as red-object! block/rs-head pane + end: as red-object! block/rs-tail pane + nb: 0 + while [str < tail][ + if TYPE_OF(str) = TYPE_STRING [ + len: -1 + title: unicode/to-utf8 str :len + label: gtk_label_new title + if face < end [ + panel: as handle! get-face-handle face + gtk_notebook_append_page widget panel label + face: face + 1 + ] + nb: nb + 1 + ] + str: str + 1 + ] + ] + int: as red-integer! facets + FACE_OBJ_SELECTED + + if TYPE_OF(int) <> TYPE_INTEGER [ + int/header: TYPE_INTEGER ;-- force selection on first tab + int/value: 1 + ] + gtk_notebook_set_current_page widget int/value +] diff --git a/modules/view/view.red b/modules/view/view.red index a063574408..148ea57f32 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -751,7 +751,7 @@ show: function [ ] p: either with [parent/state/1][0] - #if config/OS = 'macOS [ ;@@ remove this system specific code + #if config/OS <> 'Windows [ ;@@ remove this system specific code if all [face/type = 'tab-panel face/pane][ link-tabs-to-parent face foreach f face/pane [show/force f] From 6c1b32f0dd9c666edb097f0f7312b423e3b80339 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 2 Oct 2019 16:23:44 +0800 Subject: [PATCH 0197/3432] FIX: improve names and handlers argument --- modules/view/backends/gtk3/events.reds | 168 ++++++++--------------- modules/view/backends/gtk3/gui.reds | 139 ++++++++----------- modules/view/backends/gtk3/handlers.reds | 147 ++++++++------------ 3 files changed, 171 insertions(+), 283 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index a6d93e31aa..27e3f065ce 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -78,7 +78,7 @@ get-event-window: func [ ][ ;; DEBUG: print ["get-event-windows: " evt/type " " evt/msg lf] handle: gtk_widget_get_toplevel as handle! evt/msg - as red-value! get-face-obj handle + as red-value! g_object_get_qdata handle red-face-id ] get-event-offset: func [ @@ -574,39 +574,6 @@ debug-connect-level: DEBUG_CONNECT_NONE debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and level <> 0] -connect-container-events: func [ - widget [handle!] - evt-type [c-string!] - /local - container [handle!] - id [integer!] -][ - container: container? widget - unless null? container [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_COMMON [print ["connect-container-events " container " " evt-type lf]] - case [ - 0 = g_strcmp0 evt-type "button-press-event" [ - gtk_widget_add_events container GDK_BUTTON_PRESS_MASK - ] - 0 = g_strcmp0 evt-type "motion-notify-event" [ - gtk_widget_add_events container GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK - ] - 0 = g_strcmp0 evt-type "button-release-event" [ - gtk_widget_add_events container GDK_BUTTON_RELEASE_MASK - ] - 0 = g_strcmp0 evt-type "enter-notify-event" [ ; normally unused - gtk_widget_add_events container GDK_ENTER_NOTIFY_MASK - ] - 0 = g_strcmp0 evt-type "leave-notify-event" [ ; normally unused - gtk_widget_add_events container GDK_LEAVE_NOTIFY_MASK - ] - true [0] - ] - if null? container [print ["container null for connection with " widget " " evt-type lf]] - id: gobj_signal_connect(container evt-type :container-delegate-to-children null) - ] -] - ;; TODO: before finding better solution!!!! ;; container-type? is now only restricted to rich-text (cf gui.red) ;; since @@ -615,133 +582,110 @@ connect-container-events: func [ connect-common-events: function [ widget [handle!] - face [red-object!] - sym [integer!] + data [int-ptr!] ][ assert widget <> null - - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-press-event" - ] - gobj_signal_connect(widget "button-press-event" :mouse-button-press-event face/ctx) + gobj_signal_connect(widget "button-press-event" :mouse-button-press-event data) gtk_widget_add_events widget GDK_BUTTON1_MOTION_MASK or GDK_POINTER_MOTION_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "motion-notify-event" - ] - gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event face/ctx) + gobj_signal_connect(widget "motion-notify-event" :mouse-motion-notify-event data) - gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "button-release-event" - ] - gobj_signal_connect(widget "button-release-event" :mouse-button-release-event face/ctx) + gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK + gobj_signal_connect(widget "button-release-event" :mouse-button-release-event data) - gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK - gobj_signal_connect(widget "key-press-event" :key-press-event face/ctx) + gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK + gobj_signal_connect(widget "key-press-event" :key-press-event data) gtk_widget_add_events widget GDK_KEY_RELEASE_MASK - gobj_signal_connect(widget "key-release-event" :key-release-event face/ctx) - + gobj_signal_connect(widget "key-release-event" :key-release-event data) gtk_widget_add_events widget GDK_SCROLL_MASK - if container-type? sym [ - ;; Bubbling does not work for rich-text so delegation to the parent with EVT_DISPATCH - connect-container-events widget "scroll-event" - ] - gobj_signal_connect(widget "scroll-event" :widget-scroll-event face/ctx) + gobj_signal_connect(widget "scroll-event" :widget-scroll-event data) ] connect-focus-events: function [ widget [handle!] - face [red-object!] - sym [integer!] + data [int-ptr!] ][ - gobj_signal_connect(widget "focus-in-event" :focus-in-event face/ctx) - gobj_signal_connect(widget "focus-out-event" :focus-out-event face/ctx) + assert widget <> null + gobj_signal_connect(widget "focus-in-event" :focus-in-event data) + gobj_signal_connect(widget "focus-out-event" :focus-out-event data) ] connect-notify-events: function [ widget [handle!] - face [red-object!] - sym [integer!] + data [int-ptr!] ][ assert widget <> null - if sym = text [widget: _widget? widget] gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK - gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event face/ctx) - gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event face/ctx) + gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event data) + gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event data) ] connect-widget-events: function [ widget [handle!] - face [red-object!] sym [integer!] - _widget [handle!] - parent [handle!] + evbox [handle!] /local buffer [handle!] ][ - ;; register red mouse, key and window on event functions - connect-common-events widget face sym + ;; register red mouse, key event functions + connect-common-events evbox widget case [ sym = check [ ;@@ No click event for check ;gobj_signal_connect(widget "clicked" :button-clicked null) - gobj_signal_connect(widget "toggled" :button-toggled face/ctx) + gobj_signal_connect(evbox "toggled" :button-toggled widget) ] sym = radio [ ;@@ Line below removed because it generates an error and there is no click event for radio ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add radio toggled " lf]] - gobj_signal_connect(widget "toggled" :button-toggled face/ctx) + gobj_signal_connect(evbox "toggled" :button-toggled widget) ] sym = button [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] - gobj_signal_connect(widget "clicked" :button-clicked null) + gobj_signal_connect(evbox "clicked" :button-clicked widget) ] sym = base [ - gobj_signal_connect(widget "draw" :base-draw face/ctx) - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes + gobj_signal_connect(evbox "draw" :base-draw widget) + gtk_widget_add_events evbox GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK + gtk_widget_set_can_focus evbox yes + gtk_widget_set_focus_on_click evbox yes ] sym = rich-text [ - gobj_signal_connect(widget "draw" :base-draw face/ctx) + gobj_signal_connect(widget "draw" :base-draw widget) gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes gtk_widget_is_focus widget gtk_widget_grab_focus widget - connect-focus-events widget face sym + connect-focus-events widget widget ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] - gobj_signal_connect(widget "delete-event" :window-delete-event null) + gobj_signal_connect(evbox "delete-event" :window-delete-event widget) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK - gobj_signal_connect(widget "configure-event" :window-configure-event null) + gobj_signal_connect(evbox "configure-event" :window-configure-event widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] - gobj_signal_connect(widget "size-allocate" :window-size-allocate null) - connect-focus-events widget face sym + gobj_signal_connect(evbox "size-allocate" :window-size-allocate widget) + connect-focus-events evbox widget ] sym = slider [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] - gobj_signal_connect(widget "value-changed" :range-value-changed face/ctx) + gobj_signal_connect(evbox "value-changed" :range-value-changed widget) ] sym = text [0] sym = field [ - gobj_signal_connect(widget "changed" :field-changed widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_is_focus widget - gtk_widget_grab_focus widget - connect-focus-events widget face sym + buffer: gtk_entry_get_buffer widget + gobj_signal_connect(buffer "changed" :field-changed widget) + gtk_widget_set_can_focus evbox yes + gtk_widget_set_focus_on_click evbox yes + gtk_widget_is_focus evbox + gtk_widget_grab_focus evbox + connect-focus-events evbox widget ] sym = progress [ 0 @@ -752,32 +696,32 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] gobj_signal_connect(buffer "changed" :area-changed widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] - g_object_set [widget "populate-all" yes null] + g_object_set [evbox "populate-all" yes widget] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] - gobj_signal_connect(widget "populate-popup" :area-populate-popup face/ctx) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_is_focus widget - gtk_widget_grab_focus widget - connect-focus-events widget face sym + gobj_signal_connect(evbox "populate-popup" :area-populate-popup widget) + gtk_widget_set_can_focus evbox yes + gtk_widget_set_focus_on_click evbox yes + gtk_widget_is_focus evbox + gtk_widget_grab_focus evbox + connect-focus-events evbox widget ] sym = group-box [ 0 ] sym = panel [ - gobj_signal_connect(widget "draw" :base-draw face/ctx) - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes + gobj_signal_connect(evbox "draw" :base-draw widget) + gtk_widget_add_events evbox GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK + gtk_widget_set_can_focus evbox yes + gtk_widget_set_focus_on_click evbox yes ] sym = tab-panel [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] - gobj_signal_connect(widget "switch-page" :tab-panel-switch-page face/ctx) + gobj_signal_connect(evbox "switch-page" :tab-panel-switch-page widget) ] sym = text-list [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text-list selected-rows-changed " lf]] - gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed face/ctx) + gobj_signal_connect(evbox "selected-rows-changed" :text-list-selected-rows-changed widget) ] any [ sym = drop-list @@ -785,9 +729,9 @@ connect-widget-events: function [ ][ ;;; Mandatory! and can respond to (ON_SELECT or ON_CHANGE) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add drop-(list|down) changed " lf]] - gobj_signal_connect(widget "changed" :combo-selection-changed face/ctx) + gobj_signal_connect(evbox "changed" :combo-selection-changed widget) ] true [0] ] - connect-notify-events widget face sym + connect-notify-events evbox widget ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8af550bb97..bbf2750765 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,6 +10,13 @@ Red/System [ } ] +#define SET-RED-FACE(s d) [g_object_set_qdata s red-face-id d] +#define GET-RED-FACE(s) [as red-object! g_object_get_qdata s red-face-id] +#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] +#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] +#define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] +#define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] + #include %../keycodes.reds #include %gtk.reds #include %events.reds @@ -35,7 +42,7 @@ AppMainMenu: as handle! 0 ;; Identifiers for qdata red-face-id: g_quark_from_string "red-face-id" gtk-style-id: g_quark_from_string "gtk-style-id" -_widget-id: g_quark_from_string "_widget-id" +event-box-id: g_quark_from_string "event-box-id" real-widget-id: g_quark_from_string "real-widget-id" gtk-container-id: g_quark_from_string "gtk-container-id" red-timer-id: g_quark_from_string "red-timer-id" @@ -47,9 +54,6 @@ no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" -#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] -#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] - group-radio: as handle! 0 settings: as handle! 0 @@ -71,51 +75,27 @@ screen-size-y: 0 get-face-obj: func [ handle [handle!] return: [red-object!] - /local - face [red-object!] - qdata [handle!] ][ - face: as red-object! 0 - unless null? handle [ - qdata: g_object_get_qdata handle red-face-id - unless null? qdata [ - face: as red-object! qdata - ] - ] - face + GET-RED-FACE(handle) ] get-face-values: func [ handle [handle!] return: [red-value!] /local - face [red-object!] - qdata [handle!] values [red-value!] + face [red-object!] ][ values: as red-value! 0 unless null? handle [ - qdata: g_object_get_qdata handle red-face-id - unless null? qdata [ - face: as red-object! qdata + face: GET-RED-FACE(handle) + unless null? face [ values: object/get-values face ] ] values ] -get-node-values: func [ - node [node!] - return: [red-value!] - /local - ctx [red-context!] - s [series!] -][ - ctx: TO_CTX(node) - s: as series! ctx/values/value - s/offset -] - get-node-facet: func [ node [node!] facet [integer!] @@ -190,22 +170,15 @@ get-widget-data: func [ ] ;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget -set-_widget: func [ - widget [handle!] - _widget [handle!] -][ - g_object_set_qdata widget _widget-id _widget -] - -_widget?: func [ +event-box?: func [ widget [handle!] return: [handle!] /local - _widget [handle!] + evbox [handle!] ][ - _widget: g_object_get_qdata widget _widget-id - if null? _widget [_widget: widget] - return _widget + evbox: g_object_get_qdata widget event-box-id + if null? evbox [evbox: widget] + return evbox ] ;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) @@ -488,7 +461,7 @@ debug-show-children: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 unless null? container [ - widget_: _widget? child + widget_: event-box? child gtk_widget_get_allocation widget_ as handle! rect ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates @@ -633,7 +606,7 @@ adjust-sizes: func [ ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 if any [ox > offset/x not overlap?] [dx: 0] unless null? container [ - widget_: _widget? child + widget_: event-box? child if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] gtk_layout_move container widget_ offset/x + dx offset/y gtk_widget_get_allocation widget_ as handle! rect @@ -805,7 +778,7 @@ change-color: func [ ; ] case [ type = area [ - face: get-face-obj widget + face: GET-RED-FACE(widget) font: face-font? face apply-css-styles widget face font type ; widget: objc_msgSend [widget sel_getUid "documentView"] @@ -815,7 +788,7 @@ change-color: func [ ] true [ ;; DEBUG: print ["change-color " widget lf] - face: get-face-obj widget + face: GET-RED-FACE(widget) font: face-font? face apply-css-styles widget face font type ] @@ -830,7 +803,7 @@ change-pane: func [ face [red-object!] tail [red-object!] widget [handle!] - _widget [handle!] + evbox [handle!] nb [integer!] s [series!] values [red-value!] @@ -864,13 +837,13 @@ change-pane: func [ if TYPE_OF(face) = TYPE_OBJECT [ widget: face-handle? face if widget <> null [ - _widget: _widget? widget + evbox: event-box? widget nb: nb + 1 - ;; DEBUG: print ["add widget" nb ": " widget "(" _widget ") to " parent lf] - gtk_container_add parent _widget + ;; DEBUG: print ["add widget" nb ": " widget "(" evbox ") to " parent lf] + gtk_container_add parent evbox values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - gtk_layout_move parent _widget offset/x offset/y + gtk_layout_move parent evbox offset/x offset/y ] ] face: face + 1 @@ -925,7 +898,7 @@ change-offset: func [ type [integer!] /local container [handle!] - _widget [handle!] + evbox [handle!] ][ ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol widget " " widget " " pos/x "x" pos/y lf] either type = window [ @@ -939,10 +912,10 @@ change-offset: func [ ; g_object_get_qdata widget _widget-id ; ][widget] - _widget: _widget? widget + evbox: event-box? widget unless null? container [ - gtk_layout_move container _widget pos/x pos/y - gtk_widget_queue_draw _widget + gtk_layout_move container evbox pos/x pos/y + gtk_widget_queue_draw evbox ] ] ] @@ -953,7 +926,7 @@ change-size: func [ size [red-pair!] type [integer!] /local - _widget [handle!] + evbox [handle!] ][ ;; DEBUG: print ["change-size " get-symbol-name get-widget-symbol widget " " widget " " size/x "x" size/y lf] @@ -964,9 +937,9 @@ change-size: func [ gtk_widget_queue_draw widget ][ unless null? widget [ - _widget: _widget? widget - gtk_widget_set_size_request _widget size/x size/y - unless null? _widget [gtk_widget_queue_resize _widget] + evbox: event-box? widget + gtk_widget_set_size_request evbox size/x size/y + gtk_widget_queue_resize evbox ] ] @@ -1669,7 +1642,7 @@ OS-make-view: func [ caption [c-string!] len [integer!] widget [handle!] - _widget [handle!] + evbox [handle!] winbox [handle!] buffer [handle!] container [handle!] @@ -1683,7 +1656,7 @@ OS-make-view: func [ values: object/get-values face - _widget: as handle! 0 ; widget version with possible scrollview + evbox: as handle! 0 ; widget version with possible scrollview type: as red-word! values + FACE_OBJ_TYPE str: as red-string! values + FACE_OBJ_TEXT @@ -1744,10 +1717,10 @@ OS-make-view: func [ sym = rich-text [ widget: gtk_layout_new null null;gtk_drawing_area_new gtk_layout_set_size widget size/x size/y - _widget: gtk_scrolled_window_new null null - set-real-widget _widget widget - ;; DEBUG: print ["rich-text _widget: " _widget lf] - gtk_container_add _widget widget + evbox: gtk_scrolled_window_new null null + set-real-widget evbox widget + ;; DEBUG: print ["rich-text evbox: " evbox lf] + gtk_container_add evbox widget ] sym = window [ ;; DEBUG: print ["win App " GTKApp lf] @@ -1811,8 +1784,8 @@ OS-make-view: func [ sym = text [ widget: gtk_label_new caption ;; gtk_label_set_width_chars widget ??? - _widget: gtk_event_box_new null null - gtk_container_add _widget widget + evbox: gtk_event_box_new null null + gtk_container_add evbox widget ] sym = field [ widget: gtk_entry_new @@ -1835,8 +1808,8 @@ OS-make-view: func [ widget: gtk_text_view_new buffer: gtk_text_view_get_buffer widget unless null? caption [gtk_text_buffer_set_text buffer caption -1] - _widget: gtk_scrolled_window_new null null - gtk_container_add _widget widget + evbox: gtk_scrolled_window_new null null + gtk_container_add evbox widget ] sym = group-box [ widget: gtk_frame_new caption @@ -1861,11 +1834,11 @@ OS-make-view: func [ widget: gtk_list_box_new init-text-list widget data ;gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 - _widget: gtk_scrolled_window_new null null + evbox: gtk_scrolled_window_new null null if bits and FACET_FLAGS_NO_BORDER = 0 [ - gtk_scrolled_window_set_shadow_type _widget 3 + gtk_scrolled_window_set_shadow_type evbox 3 ] - gtk_container_add _widget widget + gtk_container_add evbox widget ] any [ sym = drop-list @@ -1890,14 +1863,14 @@ OS-make-view: func [ ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] + either null? evbox [evbox: widget][SET-EVENT-BOX(widget evbox)] if all [ sym <> window parent <> 0 ][ p-sym: get-widget-symbol as handle! parent - either null? _widget [_widget: widget][set-_widget widget _widget ] ; TODO: case to replace with either if no more choice - ;; DEBUG: print ["Parent: " get-symbol-name p-sym " _widget" _widget lf] + ;; DEBUG: print ["Parent: " get-symbol-name p-sym " evbox" evbox lf] container: as handle! case [ p-sym = window [ @@ -1922,25 +1895,25 @@ OS-make-view: func [ container? as handle! parent ] ] - ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[_widget: " _widget "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] + ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[evbox: " evbox "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass set-container widget container - if sym = text [set-container _widget container] - gtk_widget_set_size_request _widget size/x size/y - gtk_layout_put container _widget offset/x offset/y - ;; DEBUG: print ["make-view: _widget: " offset/x "x" offset/y "x" size/x "x" size/y lf] + if sym = text [set-container evbox container] + gtk_widget_set_size_request evbox size/x size/y + gtk_layout_put container evbox offset/x offset/y + ;; DEBUG: print ["make-view: evbox: " offset/x "x" offset/y "x" size/x "x" size/y lf] ] ; Deal with actors - connect-widget-events widget face sym _widget as int-ptr! parent + connect-widget-events widget sym evbox unless any[sym = window sym = area][build-context-menu widget menu] ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events store-face-to-obj widget face - if sym = text [store-face-to-obj _widget face] + if sym = text [store-face-to-obj evbox face] change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym change-para widget face as red-object! values + FACE_OBJ_PARA font sym diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index a708872f87..220497a4b0 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -56,22 +56,22 @@ set-text: func [ button-clicked: func [ [cdecl] + evbox [handle!] widget [handle!] - ctx [node!] ][ make-event widget 0 EVT_CLICK ] button-toggled: func [ [cdecl] + evbox [handle!] button [handle!] - ctx [node!] /local bool [red-logic!] type [integer!] undetermined? [logic!] ][ - bool: as red-logic! get-node-facet ctx FACE_OBJ_DATA + bool: (as red-logic! get-face-values button) + FACE_OBJ_DATA undetermined?: gtk_toggle_button_get_inconsistent button either undetermined? [ @@ -198,9 +198,9 @@ render-text: func [ base-draw: func [ [cdecl] - widget [handle!] + evbox [handle!] cr [handle!] - ctx [node!] + widget [handle!] return: [logic!] /local vals [red-value!] @@ -216,7 +216,7 @@ base-draw: func [ ][ ;; DEBUG: print ["base-draw " widget " " gtk_widget_get_allocated_width widget "x" gtk_widget_get_allocated_height widget lf] - vals: get-node-values ctx + vals: get-face-values widget img: as red-image! vals + FACE_OBJ_IMAGE draw: as red-block! vals + FACE_OBJ_DRAW clr: as red-tuple! vals + FACE_OBJ_COLOR @@ -247,10 +247,10 @@ base-draw: func [ case [ sym = base [render-text cr size vals] sym = rich-text [ - ;; DEBUG: print ["base-draw (rich-text)" widget " face " get-face-obj widget lf] + ;; DEBUG: print ["base-draw (rich-text)" widget " face " GET-RED-FACE widget lf] pos/x: 0 pos/y: 0 init-draw-ctx :DC cr - draw-text-box :DC :pos get-face-obj widget yes + draw-text-box :DC :pos GET-RED-FACE(widget) yes ] true [] ] @@ -306,8 +306,9 @@ window-removed-event: func [ ;; BUG: `vid.red` fails... back with window-size-allocate handler for resizing window-configure-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventConfigure!] + widget [handle!] /local sz [red-pair!] offset [red-pair!] @@ -331,8 +332,9 @@ window-configure-event: func [ window-size-allocate: func [ [cdecl] - widget [handle!] + evbox [handle!] rect [tagRECT] + widget [handle!] /local sz [red-pair!] ][ @@ -346,7 +348,7 @@ window-size-allocate: func [ range-value-changed: func [ [cdecl] range [handle!] - ctx [node!] + widget [handle!] /local vals [red-value!] val [float!] @@ -358,7 +360,7 @@ range-value-changed: func [ ][ ; This event happens on GtkRange widgets including GtkScale. ; Will any other widget need this? - vals: get-node-values ctx + vals: get-face-values widget ;type: as red-word! vals + FACE_OBJ_TYPE size: as red-pair! vals + FACE_OBJ_SIZE pos: as red-float! vals + FACE_OBJ_DATA @@ -380,19 +382,21 @@ range-value-changed: func [ combo-selection-changed: func [ [cdecl] + evbox [handle!] widget [handle!] - ctx [node!] /local idx [integer!] res [integer!] text [c-string!] + face [red-object!] ][ idx: gtk_combo_box_get_active widget if idx >= 0 [ + face: GET-RED-FACE(widget) res: make-event widget idx + 1 EVT_SELECT - set-selected widget ctx idx + 1 + set-selected widget face/ctx idx + 1 text: gtk_combo_box_text_get_active_text widget - set-text widget ctx text + set-text widget face/ctx text if res = EVT_DISPATCH [ make-event widget idx + 1 EVT_CHANGE ] @@ -401,22 +405,24 @@ combo-selection-changed: func [ text-list-selected-rows-changed: func [ [cdecl] + evbox [handle!] widget [handle!] - ctx [node!] /local idx [integer!] sel [handle!] res [integer!] text [c-string!] + face [red-object!] ][ ; From now, only single-selection mode sel: gtk_list_box_get_selected_row widget idx: either null? sel [-1][gtk_list_box_row_get_index sel] if idx >= 0 [ + face: GET-RED-FACE(widget) res: make-event widget idx + 1 EVT_SELECT - set-selected widget ctx idx + 1 + set-selected widget face/ctx idx + 1 text: gtk_label_get_text gtk_bin_get_child sel - set-text widget ctx text + set-text widget face/ctx text if res = EVT_DISPATCH [ make-event widget idx + 1 EVT_CHANGE ] @@ -425,19 +431,21 @@ text-list-selected-rows-changed: func [ tab-panel-switch-page: func [ [cdecl] - widget [handle!] + evbox [handle!] page [handle!] idx [integer!] - ctx [node!] + widget [handle!] /local res [integer!] text [c-string!] + face [red-object!] ][ if idx >= 0 [ + face: GET-RED-FACE(widget) res: make-event widget idx + 1 EVT_SELECT - set-selected widget ctx idx + 1 + set-selected widget face/ctx idx + 1 text: gtk_notebook_get_tab_label_text widget page - set-text widget ctx text + set-text widget face/ctx text if res = EVT_DISPATCH [ make-event widget idx + 1 EVT_CHANGE ] @@ -447,9 +455,9 @@ tab-panel-switch-page: func [ ; Do not use key-press-event since character would not be printed! key-press-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event-key [GdkEventKey!] - ctx [node!] + widget [handle!] return: [integer!] /local res [integer!] @@ -488,9 +496,9 @@ key-press-event: func [ key-release-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event-key [GdkEventKey!] - ctx [node!] + widget [handle!] return: [integer!] /local key [integer!] @@ -509,13 +517,11 @@ field-changed: func [ widget [handle!] /local text [c-string!] - qdata [handle!] face [red-object!] ][ text: gtk_entry_get_text widget - qdata: g_object_get_qdata widget red-face-id - unless null? qdata [ - face: as red-object! qdata + face: GET-RED-FACE(widget) + unless null? face [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] @@ -523,18 +529,18 @@ field-changed: func [ focus-in-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [handle!] - ctx [node!] + widget [handle!] ][ make-event widget 0 EVT_FOCUS ] focus-out-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [handle!] - ctx [node!] + widget [handle!] ][ make-event widget 0 EVT_UNFOCUS ] @@ -546,16 +552,14 @@ area-changed: func [ /local text [c-string!] face [red-object!] - qdata [handle!] start [GtkTextIter! value] end [GtkTextIter! value] ][ ; Weirdly, GtkTextIter introduced since I did not simplest solution to get the full content of a GtkTextBuffer! gtk_text_buffer_get_bounds buffer as handle! start as handle! end text: gtk_text_buffer_get_text buffer as handle! start as handle! end no - qdata: g_object_get_qdata widget red-face-id - unless null? qdata [ - face: as red-object! qdata + face: GET-RED-FACE(widget) + unless null? face [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] @@ -563,14 +567,16 @@ area-changed: func [ area-populate-popup: func [ [cdecl] - widget [handle!] + evbox [handle!] hMenu [handle!] - ctx [node!] + widget [handle!] /local + values [red-value!] menu [red-block!] ][ + values: get-face-values widget + menu: as red-block! values + FACE_OBJ_MENU ;; DEBUG: print ["populate menu for " widget " and menu " hMenu lf] - menu: as red-block! get-node-facet ctx FACE_OBJ_MENU append-context-menu menu hMenu widget ] @@ -596,9 +602,9 @@ red-timer-action: func [ widget-enter-notify-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventCrossing!] - ctx [node!] + widget [handle!] return: [integer!] /local flags [integer!] @@ -612,9 +618,9 @@ widget-enter-notify-event: func [ widget-leave-notify-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventCrossing!] - ctx [node!] + widget [handle!] return: [integer!] /local flags [integer!] @@ -625,46 +631,11 @@ widget-leave-notify-event: func [ 0;;no ] -container-emit-event: func [ - [cdecl] - widget [handle!] - event [int-ptr!] - /local - rect [tagRECT] - evt [GdkEventButton!] - x [integer!] - y [integer!] -][ - evt: as GdkEventButton! event - x: as-integer evt/x y: as-integer evt/y - rect: as tagRECT allocate (size? tagRECT) - gtk_widget_get_allocation widget as handle! rect - - ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit event " widget lf]] - if all[x >= rect/x x <= (rect/x + rect/width) y >= rect/y y <= (rect/y + rect/height)][ - ;; DEBUG: if evt/type = GDK_BUTTON_PRESS [print ["emit2 event " widget " event " evt/x "x" evt/y lf "widget size " rect/x "x" rect/y "x" rect/width "x" rect/height lf]] - gtk_widget_event real-widget? widget event - ] - free as byte-ptr! rect -] - -container-delegate-to-children: func [ - [cdecl] - widget [handle!] - event [int-ptr!] - ctx [node!] - return: [integer!] -][ - ;; DEBUG: print [ "parent -> CONTAINER DELEGATE: " widget lf] - gtk_container_foreach widget as-integer :container-emit-event event - EVT_DISPATCH -] - mouse-button-release-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventButton!] - ctx [node!] + widget [handle!] return: [integer!] /local sym [integer!] @@ -728,9 +699,9 @@ mouse-button-release-event: func [ mouse-button-press-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventButton!] - ctx [node!] + widget [handle!] return: [integer!] /local sym [integer!] @@ -777,9 +748,9 @@ mouse-button-press-event: func [ mouse-motion-notify-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventMotion!] - ctx [node!] + widget [handle!] return: [integer!] /local offset [red-pair!] @@ -817,9 +788,9 @@ menu-item-activate: func [ widget-scroll-event: func [ [cdecl] - widget [handle!] + evbox [handle!] event [GdkEventScroll!] - ctx [node!] + widget [handle!] return: [integer!] /local state [integer!] From 8fe89de094b8318d684b1c10ebb709977cd161c8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 4 Oct 2019 10:53:13 +0800 Subject: [PATCH 0198/3432] FIX: remove no used data, only use `containner` data to layout child --- modules/view/backends/gtk3/gui.reds | 63 +++++------------------------ 1 file changed, 11 insertions(+), 52 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index bbf2750765..7db7b7bb2d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -16,6 +16,8 @@ Red/System [ #define GET-CURSOR(s) [g_object_get_qdata s cursor-id] #define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] #define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] +#define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] +#define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] #include %../keycodes.reds #include %gtk.reds @@ -43,12 +45,10 @@ AppMainMenu: as handle! 0 red-face-id: g_quark_from_string "red-face-id" gtk-style-id: g_quark_from_string "gtk-style-id" event-box-id: g_quark_from_string "event-box-id" -real-widget-id: g_quark_from_string "real-widget-id" gtk-container-id: g_quark_from_string "gtk-container-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" -real-container-id: g_quark_from_string "real-container-id" menu-id: g_quark_from_string "menu-id" no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" @@ -181,46 +181,6 @@ event-box?: func [ return evbox ] -;; Used to delegate event (see handlers.red) for widget that have container for scrollbar (like rich-text) -set-real-widget: func [ - _widget [handle!] - widget [handle!] -][ - g_object_set_qdata _widget real-widget-id widget -] - -real-widget?: func [ - _widget [handle!] - return: [handle!] - /local - widget [handle!] -][ - widget: g_object_get_qdata _widget real-widget-id - if null? widget [widget: _widget] - return widget -] - -set-container: func [ - widget [handle!] - container [handle!] -][ - g_object_set_qdata widget gtk-container-id container -] - -container?: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget gtk-container-id -] - -real-container?: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget real-container-id -] - gtk-layout?: func [ type [integer!] return: [logic!] @@ -441,7 +401,7 @@ debug-show-children: func [ if TYPE_OF(face) <> TYPE_OBJECT [print-line "not face object"] widget_: face-handle? face - either null? widget_ [print-line "null container" container: null][container: container? widget_] + either null? widget_ [print-line "null container" container: null][container: GET-CONTAINER(widget_)] print ["container handle: " container lf] sx: 0 sy: 0 @@ -588,7 +548,7 @@ adjust-sizes: func [ tail: as red-object! block/rs-tail pane if debug [print ["Parent type: " get-symbol-name sym lf]] child: face-handle? face - container: either null? child [null][container? child] + container: either null? child [null][GET-CONTAINER(child)] dx: 0 dy: 0 ox: 0 oy: 0 sx: 0 sy: 0 cpt: 0 @@ -906,7 +866,7 @@ change-offset: func [ ][ unless null? widget [ ;OS-refresh-window as integer! main-window - container: either null? widget [null][container? widget] + container: either null? widget [null][GET-CONTAINER(widget)] ;; DEBUG: print ["change-offset by" pos lf] ; _widget: either type = text [ ; g_object_get_qdata widget _widget-id @@ -1718,7 +1678,6 @@ OS-make-view: func [ widget: gtk_layout_new null null;gtk_drawing_area_new gtk_layout_set_size widget size/x size/y evbox: gtk_scrolled_window_new null null - set-real-widget evbox widget ;; DEBUG: print ["rich-text evbox: " evbox lf] gtk_container_add evbox widget ] @@ -1755,7 +1714,7 @@ OS-make-view: func [ container: gtk_layout_new null null gtk_layout_set_size container size/x size/y gtk_box_pack_start winbox container yes yes 0 - g_object_set_qdata widget real-container-id container + SET-CONTAINER(widget container) ;; DEBUG: print ["window is " widget " real container is " container lf] gtk_window_move widget offset/x offset/y @@ -1872,9 +1831,9 @@ OS-make-view: func [ ; TODO: case to replace with either if no more choice ;; DEBUG: print ["Parent: " get-symbol-name p-sym " evbox" evbox lf] - container: as handle! case [ + container: as handle! case [ p-sym = window [ - g_object_get_qdata as handle! parent real-container-id + g_object_get_qdata as handle! parent gtk-container-id ] any [p-sym = panel p-sym = rich-text p-sym = base] [parent] p-sym = group-box [ @@ -1892,14 +1851,14 @@ OS-make-view: func [ ;; redirect to the layout of the parent ;; WARNING: (since completedly changed code) print ["DEVEL WARNING: <> (ONLY FOR DEVELOPMENT SINCE CODE HAS FULLY CHANGED BUT IMPOSSIBLE TO TEST) " lf] - container? as handle! parent + g_object_get_qdata as handle! parent gtk-container-id ] ] ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[evbox: " evbox "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass - set-container widget container - if sym = text [set-container evbox container] + SET-CONTAINER(widget container) + if sym = text [SET-CONTAINER(evbox container)] gtk_widget_set_size_request evbox size/x size/y gtk_layout_put container evbox offset/x offset/y ;; DEBUG: print ["make-view: evbox: " offset/x "x" offset/y "x" size/x "x" size/y lf] From 5f49ecf916d12b744824996d77c8b29f66cb2293 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 4 Oct 2019 11:09:49 +0800 Subject: [PATCH 0199/3432] FIX: connect events not right --- modules/view/backends/gtk3/events.reds | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 27e3f065ce..054359b850 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -679,8 +679,7 @@ connect-widget-events: function [ ] sym = text [0] sym = field [ - buffer: gtk_entry_get_buffer widget - gobj_signal_connect(buffer "changed" :field-changed widget) + gobj_signal_connect(widget "changed" :field-changed widget) gtk_widget_set_can_focus evbox yes gtk_widget_set_focus_on_click evbox yes gtk_widget_is_focus evbox @@ -721,7 +720,7 @@ connect-widget-events: function [ sym = text-list [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text-list selected-rows-changed " lf]] - gobj_signal_connect(evbox "selected-rows-changed" :text-list-selected-rows-changed widget) + gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed widget) ] any [ sym = drop-list From d55662722bb12f75fd25d963b6e3a766e759e9db Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 4 Oct 2019 15:50:39 +0800 Subject: [PATCH 0200/3432] FIX: store face object by value --- modules/view/backends/gtk3/events.reds | 4 +-- modules/view/backends/gtk3/gui.reds | 31 +++++++++++++++--------- modules/view/backends/gtk3/handlers.reds | 14 +++++------ 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 054359b850..8065bc862c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -50,7 +50,7 @@ make-at: func [ /local f [red-value!] ][ - f: as red-value! g_object_get_qdata widget red-face-id + f: as red-value! get-face-obj widget assert f <> null as red-object! copy-cell f as cell! face ] @@ -78,7 +78,7 @@ get-event-window: func [ ][ ;; DEBUG: print ["get-event-windows: " evt/type " " evt/msg lf] handle: gtk_widget_get_toplevel as handle! evt/msg - as red-value! g_object_get_qdata handle red-face-id + as red-value! get-face-obj handle ] get-event-offset: func [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7db7b7bb2d..b45329697d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,8 +10,6 @@ Red/System [ } ] -#define SET-RED-FACE(s d) [g_object_set_qdata s red-face-id d] -#define GET-RED-FACE(s) [as red-object! g_object_get_qdata s red-face-id] #define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] #define GET-CURSOR(s) [g_object_get_qdata s cursor-id] #define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] @@ -42,7 +40,10 @@ win-cnt: 0 AppMainMenu: as handle! 0 ;; Identifiers for qdata -red-face-id: g_quark_from_string "red-face-id" +red-face-id1: g_quark_from_string "red-face-id1" +red-face-id2: g_quark_from_string "red-face-id2" +red-face-id3: g_quark_from_string "red-face-id3" +red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" event-box-id: g_quark_from_string "event-box-id" gtk-container-id: g_quark_from_string "gtk-container-id" @@ -75,8 +76,15 @@ screen-size-y: 0 get-face-obj: func [ handle [handle!] return: [red-object!] + /local + face [red-object!] ][ - GET-RED-FACE(handle) + face: declare red-object! + face/header: as integer! g_object_get_qdata handle red-face-id1 + face/ctx: g_object_get_qdata handle red-face-id2 + face/class: as integer! g_object_get_qdata handle red-face-id3 + face/on-set: g_object_get_qdata handle red-face-id4 + face ] get-face-values: func [ @@ -88,7 +96,7 @@ get-face-values: func [ ][ values: as red-value! 0 unless null? handle [ - face: GET-RED-FACE(handle) + face: get-face-obj handle unless null? face [ values: object/get-values face ] @@ -738,7 +746,7 @@ change-color: func [ ; ] case [ type = area [ - face: GET-RED-FACE(widget) + face: get-face-obj widget font: face-font? face apply-css-styles widget face font type ; widget: objc_msgSend [widget sel_getUid "documentView"] @@ -748,7 +756,7 @@ change-color: func [ ] true [ ;; DEBUG: print ["change-color " widget lf] - face: GET-RED-FACE(widget) + face: get-face-obj widget font: face-font? face apply-css-styles widget face font type ] @@ -1311,12 +1319,11 @@ get-screen-size: func [ store-face-to-obj: func [ obj [handle!] face [red-object!] - /local - storage [red-value!] ][ - storage: as red-value! allocate 16 ;@@ should delete it when destory widget - copy-cell as cell! face storage - g_object_set_qdata obj red-face-id as int-ptr! storage + g_object_set_qdata obj red-face-id1 as int-ptr! face/header + g_object_set_qdata obj red-face-id2 face/ctx + g_object_set_qdata obj red-face-id3 as int-ptr! face/class + g_object_set_qdata obj red-face-id4 face/on-set ] init-combo-box: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 220497a4b0..ae27837c71 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -247,10 +247,10 @@ base-draw: func [ case [ sym = base [render-text cr size vals] sym = rich-text [ - ;; DEBUG: print ["base-draw (rich-text)" widget " face " GET-RED-FACE widget lf] + ;; DEBUG: print ["base-draw (rich-text)" widget " face " get-face-obj widget lf] pos/x: 0 pos/y: 0 init-draw-ctx :DC cr - draw-text-box :DC :pos GET-RED-FACE(widget) yes + draw-text-box :DC :pos get-face-obj widget yes ] true [] ] @@ -392,7 +392,7 @@ combo-selection-changed: func [ ][ idx: gtk_combo_box_get_active widget if idx >= 0 [ - face: GET-RED-FACE(widget) + face: get-face-obj widget res: make-event widget idx + 1 EVT_SELECT set-selected widget face/ctx idx + 1 text: gtk_combo_box_text_get_active_text widget @@ -418,7 +418,7 @@ text-list-selected-rows-changed: func [ sel: gtk_list_box_get_selected_row widget idx: either null? sel [-1][gtk_list_box_row_get_index sel] if idx >= 0 [ - face: GET-RED-FACE(widget) + face: get-face-obj widget res: make-event widget idx + 1 EVT_SELECT set-selected widget face/ctx idx + 1 text: gtk_label_get_text gtk_bin_get_child sel @@ -441,7 +441,7 @@ tab-panel-switch-page: func [ face [red-object!] ][ if idx >= 0 [ - face: GET-RED-FACE(widget) + face: get-face-obj widget res: make-event widget idx + 1 EVT_SELECT set-selected widget face/ctx idx + 1 text: gtk_notebook_get_tab_label_text widget page @@ -520,7 +520,7 @@ field-changed: func [ face [red-object!] ][ text: gtk_entry_get_text widget - face: GET-RED-FACE(widget) + face: get-face-obj widget unless null? face [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE @@ -558,7 +558,7 @@ area-changed: func [ ; Weirdly, GtkTextIter introduced since I did not simplest solution to get the full content of a GtkTextBuffer! gtk_text_buffer_get_bounds buffer as handle! start as handle! end text: gtk_text_buffer_get_text buffer as handle! start as handle! end no - face: GET-RED-FACE(widget) + face: get-face-obj widget unless null? face [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE From 33876f95e9792c91077fbecf3ca7836859072734 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 5 Oct 2019 15:14:27 +0800 Subject: [PATCH 0201/3432] FEAT: use system font as default font --- modules/view/backends/gtk3/draw.reds | 4 +- modules/view/backends/gtk3/font.reds | 16 ++-- modules/view/backends/gtk3/gui.reds | 93 +++++++++++++++++++++++- modules/view/backends/gtk3/text-box.reds | 7 +- modules/view/backends/platform.red | 1 + 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index d644c5b616..c7cbd48a8d 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -463,7 +463,7 @@ draw-text-at: func [ ; either pango-font? [ ;; print ["draw-text-at: dc/layout: " dc/layout lf] if null? dc/layout [ - dc/font-desc: pango_font_description_from_string gtk-font + dc/font-desc: CREATE-DEFAULT-FONT dc/layout: make-pango-cairo-layout ctx dc/font-desc ] ;pango-cairo-set-text dc str @@ -563,7 +563,7 @@ draw-text-box: func [ len: -1 str: unicode/to-utf8 text :len ; default font-desc that can be overloaded in OS-text-box-layout called inside draw-text-box-lines - dc/font-desc: pango_font_description_from_string gtk-font + dc/font-desc: CREATE-DEFAULT-FONT ;;TORM: dc/layout: make-pango-cairo-layout dc/raw dc/font-desc ;; DEBUG: print ["draw-text-box text: " str " dc/font-desc: " dc/font-desc lf] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 160d66ed81..10af25048a 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -121,7 +121,7 @@ get-font: func [ /local hFont [handle!] ][ - if TYPE_OF(font) <> TYPE_OBJECT [return default-font] + if TYPE_OF(font) <> TYPE_OBJECT [return CREATE-DEFAULT-FONT] hFont: get-font-handle font 0 if null? hFont [hFont: make-font face font] hFont @@ -219,11 +219,10 @@ font-description: func [ rgba [c-string!] fweight [integer!] fstyle [integer!] - fd [handle!] ][ ; default font if font is none. TODO: better than gtk-font would be to get the default font system or from red side - if TYPE_OF(font) = TYPE_NONE [return default-font] + if TYPE_OF(font) = TYPE_NONE [return CREATE-DEFAULT-FONT] values: object/get-values font ;name: str: as red-string! values + FONT_OBJ_NAME @@ -233,14 +232,13 @@ font-description: func [ color: as red-tuple! values + FONT_OBJ_COLOR ; font name - name: "Arial" ; @@ to change to default font name - if TYPE_OF(str) = TYPE_STRING [ + either TYPE_OF(str) = TYPE_STRING [ len: -1 name: unicode/to-utf8 str :len - ] + ][name: default-font-name] ; font size - fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] + fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][10] ;; DEBUG: print ["font-description: fsize -> " fsize lf] ; font style and weight @@ -270,9 +268,7 @@ font-description: func [ ] ] - fd: font-description-create name fsize fweight fstyle - - fd + font-description-create name fsize fweight fstyle ] font-description-create: func [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b45329697d..61c05130b0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -16,6 +16,7 @@ Red/System [ #define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] #define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] +#define CREATE-DEFAULT-FONT [font-description-create default-font-name gtk-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL] #include %../keycodes.reds #include %gtk.reds @@ -59,8 +60,10 @@ group-radio: as handle! 0 settings: as handle! 0 pango-context: as handle! 0 -gtk-font: "Sans 13" default-font: as handle! 0 +default-font-name: as c-string! 0 +gtk-font-name: "Sans" +gtk-font-size: 10 ; Do not KNOW about this one ;;; @@ -453,6 +456,88 @@ show-gtk-version: func [][ print [ "GTK VERSION: " gtk_get_major_version "." gtk_get_minor_version "." gtk_get_micro_version lf] ] +parse-font-name: func [ + str [c-string!] + psize [int-ptr!] + plen [int-ptr!] + return: [c-string!] + /local + len [integer!] + len2 [integer!] + len3 [integer!] +][ + either null? str [ + len: 0 + ][ + len: length? str + ] + if any [ + len < 3 + str/len < #"0" + str/len > #"9" + ][ + psize/value: gtk-font-size + plen/value: length? gtk-font-name + return gtk-font-name + ] + len2: len - 1 + if str/len2 = #" " [ + psize/value: as integer! str/len - #"0" + plen/value: len - 2 + return str + ] + len3: len - 2 + if all [ + str/len2 >= #"0" + str/len2 <= #"9" + str/len3 = #" " + ][ + psize/value: as integer! str/len - #"0" + psize/value: psize/value + (10 * as integer! str/len2 - #"0") + plen/value: len - 3 + return str + ] + psize/value: gtk-font-size + plen/value: length? gtk-font-name + gtk-font-name +] + +set-defaults: func [ + /local + font [integer!] + str [c-string!] + size [integer!] + len [integer!] +][ + settings: gtk_settings_get_default + font: 0 + g_object_get [settings "gtk-font-name" :font null] + + str: as c-string! font + size: 0 + len: 0 + str: parse-font-name str :size :len + + string/load-at + str + len + #get system/view/fonts/system + UTF-8 + + integer/make-at + #get system/view/fonts/size + size + + unless null? default-font-name [ + free as byte-ptr! default-font-name + ] + default-font-name: as c-string! allocate len + 1 + copy-memory as byte-ptr! default-font-name as byte-ptr! str len + len: len + 1 + default-font-name/len: null-byte + default-font: CREATE-DEFAULT-FONT +] + init: func [][ show-gtk-version gtk_disable_setlocale @@ -467,9 +552,9 @@ init: func [][ screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height - default-font: pango_font_description_from_string gtk-font - settings: gtk_settings_get_default - g_object_set [settings "gtk-font-name" gtk-font null ] + + set-defaults + #if type = 'exe [red-gtk-styles] ;;;collector/register as int-ptr! :on-gc-mark ] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index aef104375d..91f833f191 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -636,10 +636,11 @@ OS-text-box-layout: func [ text: as red-string! values + FACE_OBJ_TEXT font: as red-object! values + FACE_OBJ_FONT ft-ok?: TYPE_OF(font) = TYPE_OBJECT ;all[not null? target TYPE_OF(font) = TYPE_OBJECT] - hFont: default-font - if ft-ok? [ + either ft-ok? [ hFont: get-font-handle font 0 - if null? hFont [hFont: default-font] + if null? hFont [hFont: CREATE-DEFAULT-FONT] + ][ + hFont: CREATE-DEFAULT-FONT ] len: -1 diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 9ab7b19a0d..2732ac02cb 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -833,6 +833,7 @@ system/view/platform: context [ ] ] macOS [["Menlo" "Arial" "Times"]] + Linux [["Droid Sans Mono" "DejaVu Sans" "DejaVu Serif"]] ] set [font-fixed font-sans-serif font-serif] reduce fonts From 7f0c9921f580073880b4ddc958a9a999589665cd Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 7 Oct 2019 10:55:48 +0800 Subject: [PATCH 0202/3432] FIX: connect event error --- modules/view/backends/gtk3/events.reds | 72 ++++++++++++++------------ modules/view/backends/gtk3/gui.reds | 14 +++-- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 8065bc862c..9242272866 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -632,28 +632,32 @@ connect-widget-events: function [ buffer [handle!] ][ ;; register red mouse, key event functions - connect-common-events evbox widget + either sym = text [ + connect-common-events evbox widget + ][ + connect-common-events widget widget + ] case [ sym = check [ ;@@ No click event for check ;gobj_signal_connect(widget "clicked" :button-clicked null) - gobj_signal_connect(evbox "toggled" :button-toggled widget) + gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = radio [ ;@@ Line below removed because it generates an error and there is no click event for radio ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add radio toggled " lf]] - gobj_signal_connect(evbox "toggled" :button-toggled widget) + gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = button [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] - gobj_signal_connect(evbox "clicked" :button-clicked widget) + gobj_signal_connect(widget "clicked" :button-clicked widget) ] sym = base [ - gobj_signal_connect(evbox "draw" :base-draw widget) - gtk_widget_add_events evbox GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK - gtk_widget_set_can_focus evbox yes - gtk_widget_set_focus_on_click evbox yes + gobj_signal_connect(widget "draw" :base-draw widget) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) @@ -666,25 +670,25 @@ connect-widget-events: function [ ] sym = window [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] - gobj_signal_connect(evbox "delete-event" :window-delete-event widget) + gobj_signal_connect(widget "delete-event" :window-delete-event widget) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK - gobj_signal_connect(evbox "configure-event" :window-configure-event widget) + gobj_signal_connect(widget "configure-event" :window-configure-event widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] - gobj_signal_connect(evbox "size-allocate" :window-size-allocate widget) - connect-focus-events evbox widget + gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) + connect-focus-events widget widget ] sym = slider [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] - gobj_signal_connect(evbox "value-changed" :range-value-changed widget) + gobj_signal_connect(widget "value-changed" :range-value-changed widget) ] sym = text [0] sym = field [ gobj_signal_connect(widget "changed" :field-changed widget) - gtk_widget_set_can_focus evbox yes - gtk_widget_set_focus_on_click evbox yes - gtk_widget_is_focus evbox - gtk_widget_grab_focus evbox - connect-focus-events evbox widget + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_is_focus widget + gtk_widget_grab_focus widget + connect-focus-events widget widget ] sym = progress [ 0 @@ -695,27 +699,27 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] gobj_signal_connect(buffer "changed" :area-changed widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] - g_object_set [evbox "populate-all" yes widget] + g_object_set [widget "populate-all" yes widget] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] - gobj_signal_connect(evbox "populate-popup" :area-populate-popup widget) - gtk_widget_set_can_focus evbox yes - gtk_widget_set_focus_on_click evbox yes - gtk_widget_is_focus evbox - gtk_widget_grab_focus evbox - connect-focus-events evbox widget + gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_is_focus widget + gtk_widget_grab_focus widget + connect-focus-events widget widget ] sym = group-box [ 0 ] sym = panel [ - gobj_signal_connect(evbox "draw" :base-draw widget) - gtk_widget_add_events evbox GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK - gtk_widget_set_can_focus evbox yes - gtk_widget_set_focus_on_click evbox yes + gobj_signal_connect(widget "draw" :base-draw widget) + gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes ] sym = tab-panel [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] - gobj_signal_connect(evbox "switch-page" :tab-panel-switch-page widget) + gobj_signal_connect(widget "switch-page" :tab-panel-switch-page widget) ] sym = text-list [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) @@ -728,9 +732,13 @@ connect-widget-events: function [ ][ ;;; Mandatory! and can respond to (ON_SELECT or ON_CHANGE) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add drop-(list|down) changed " lf]] - gobj_signal_connect(evbox "changed" :combo-selection-changed widget) + gobj_signal_connect(widget "changed" :combo-selection-changed widget) ] true [0] ] - connect-notify-events evbox widget + either sym = text [ + connect-notify-events evbox widget + ][ + connect-notify-events widget widget + ] ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 61c05130b0..66fe39c86e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -46,8 +46,8 @@ red-face-id2: g_quark_from_string "red-face-id2" red-face-id3: g_quark_from_string "red-face-id3" red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" -event-box-id: g_quark_from_string "event-box-id" -gtk-container-id: g_quark_from_string "gtk-container-id" +event-box-id: g_quark_from_string "event-box-id" ;-- widget's layout-widget +gtk-container-id: g_quark_from_string "gtk-container-id" ;-- widget's parent-widget red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" @@ -1803,11 +1803,9 @@ OS-make-view: func [ gtk_box_pack_start winbox AppMainMenu no yes 0 ] gtk_widget_show winbox - container: gtk_layout_new null null - gtk_layout_set_size container size/x size/y - gtk_box_pack_start winbox container yes yes 0 - SET-CONTAINER(widget container) - ;; DEBUG: print ["window is " widget " real container is " container lf] + evbox: gtk_layout_new null null + gtk_layout_set_size evbox size/x size/y + gtk_box_pack_start winbox evbox yes yes 0 gtk_window_move widget offset/x offset/y ;; The following line really matters to fix the initial size of the window @@ -1925,7 +1923,7 @@ OS-make-view: func [ container: as handle! case [ p-sym = window [ - g_object_get_qdata as handle! parent gtk-container-id + g_object_get_qdata as handle! parent event-box-id ] any [p-sym = panel p-sym = rich-text p-sym = base] [parent] p-sym = group-box [ From 04dc48ac506f6c80ffae5e9535ee9c1b875fd72f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 8 Oct 2019 11:49:36 +0800 Subject: [PATCH 0203/3432] FIX: add default-font-size --- modules/view/backends/gtk3/font.reds | 2 +- modules/view/backends/gtk3/gui.reds | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 10af25048a..72280249da 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -238,7 +238,7 @@ font-description: func [ ][name: default-font-name] ; font size - fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][10] + fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][default-font-size] ;; DEBUG: print ["font-description: fsize -> " fsize lf] ; font style and weight diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 66fe39c86e..aa812e00ca 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -16,7 +16,7 @@ Red/System [ #define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] #define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] -#define CREATE-DEFAULT-FONT [font-description-create default-font-name gtk-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL] +#define CREATE-DEFAULT-FONT [font-description-create default-font-name default-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL] #include %../keycodes.reds #include %gtk.reds @@ -62,6 +62,7 @@ settings: as handle! 0 pango-context: as handle! 0 default-font: as handle! 0 default-font-name: as c-string! 0 +default-font-size: 0 gtk-font-name: "Sans" gtk-font-size: 10 @@ -535,6 +536,7 @@ set-defaults: func [ copy-memory as byte-ptr! default-font-name as byte-ptr! str len len: len + 1 default-font-name/len: null-byte + default-font-size: size default-font: CREATE-DEFAULT-FONT ] From 833f1bd20d898652d0b26995e0ef002fbe74208f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 8 Oct 2019 14:50:12 +0800 Subject: [PATCH 0204/3432] FIX: resize widget failed --- modules/view/backends/gtk3/handlers.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index ae27837c71..982b82749a 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -341,6 +341,8 @@ window-size-allocate: func [ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE if any [rect/width <> sz/x rect/height <> sz/y] [ + sz/x: rect/width + sz/y: rect/height make-event widget 0 EVT_SIZING ] ] From 6e40275eafe2f9694ca7e63bc33d972a6c7939ce Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 8 Oct 2019 15:04:12 +0800 Subject: [PATCH 0205/3432] FIX: use stack instead of allocate on heap --- modules/view/backends/gtk3/gui.reds | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index aa812e00ca..28d5e4b95c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -365,7 +365,7 @@ debug-show-children: func [ widget_ [handle!] child [handle!] container [handle!] - rect [tagRECT] + rect [tagRECT value] sx [integer!] sy [integer!] offset [red-pair!] @@ -404,8 +404,6 @@ debug-show-children: func [ sym: symbol/resolve type/symbol - rect: as tagRECT allocate (size? tagRECT) - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane @@ -416,7 +414,7 @@ debug-show-children: func [ either null? widget_ [print-line "null container" container: null][container: GET-CONTAINER(widget_)] print ["container handle: " container lf] - sx: 0 sy: 0 + sx: 0 sy: 0 cpt: 0 while [face < tail][ cpt: cpt + 1 @@ -445,7 +443,6 @@ debug-show-children: func [ ] if debug [print-line "Pane end"] ] - free as byte-ptr! rect ] ; on-gc-mark: does [ @@ -607,7 +604,7 @@ adjust-sizes: func [ widget_ [handle!] child [handle!] container [handle!] - rect [tagRECT] + rect [tagRECT value] dx [integer!] dy [integer!] ox [integer!] @@ -636,8 +633,6 @@ adjust-sizes: func [ sym: symbol/resolve type/symbol - rect: as tagRECT allocate (size? tagRECT) - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ face: as red-object! block/rs-head pane tail: as red-object! block/rs-tail pane @@ -680,7 +675,6 @@ adjust-sizes: func [ ] if debug [print-line "Pane end"] ] - free as byte-ptr! rect ] remove-widget-timer: func [ From 6472dcdbf9950d7d5e4b0088568d572d0809b4e9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 8 Oct 2019 11:35:51 +0200 Subject: [PATCH 0206/3432] FEAT: supports bit shifting operators in literal array expressions. --- system/compiler.r | 1 + 1 file changed, 1 insertion(+) diff --git a/system/compiler.r b/system/compiler.r index 95111dbf58..1f34c8a0ae 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -244,6 +244,7 @@ system-dialect: make-profilable context [ array-expr-keywords: compose [ 'or | 'and | 'xor | '+ | '- | (to-lit-word "/") | '* | (to-lit-word "%") | (to-lit-word "//") + | (to-lit-word "<<") | (to-lit-word ">>") | (to-lit-word ">>>") ] foreach [word action] keywords [append keywords-list word] From 52a9c5f45b68e98db0f532906c89fd8f8c7abd40 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 8 Oct 2019 20:02:44 +0200 Subject: [PATCH 0207/3432] FIX: forces a terminal state when end is reached. --- runtime/lexer.reds | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cc8aa4f388..5c2ce747ca 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -301,7 +301,7 @@ comment { scan-word: func [state [state!] ; /local ][ - null + probe "word!" ] scan-file: func [state [state!] @@ -355,13 +355,13 @@ comment { scan-integer: func [state [state!] ; /local ][ - null + probe "integer!" ] scan-float: func [state [state!] ; /local ][ - null + probe "float!" ] scan-tuple: func [state [state!] @@ -462,6 +462,7 @@ comment { flags [integer!] line [integer!] s [series!] + term? [logic!] scanner [scanner!] ][ parent: lex/parent @@ -470,6 +471,7 @@ comment { state: 0 flags: 0 line: 1 + term?: no loop lex/remain [ cp: 1 + as-integer p/value @@ -479,12 +481,18 @@ comment { state: as-integer transitions/index ;line: line + line-table/class p: p + 1 - if state > --EXIT_STATES-- [break] + if state > --EXIT_STATES-- [term?: yes break] + ] + + unless term? [ + index: state * 33 + C_EOF + 1 + state: as-integer transitions/index ] lex/remain: as-integer p - lex/pos lex/pos: p - index: state - --EXIT_STATES-- + 1 + + index: state - --EXIT_STATES-- scanner: as scanner! scanners/index scanner lex From a201b34ab296f9adbaf4856d5e4e1f94879866de Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 9 Oct 2019 11:22:56 +0800 Subject: [PATCH 0208/3432] FIX: support resize and resizing event for window --- modules/view/backends/gtk3/events.reds | 2 +- modules/view/backends/gtk3/gui.reds | 5 ++- modules/view/backends/gtk3/handlers.reds | 49 ++++++++++++++---------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 9242272866..ae0840f827 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -672,7 +672,7 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] gobj_signal_connect(widget "delete-event" :window-delete-event widget) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK - gobj_signal_connect(widget "configure-event" :window-configure-event widget) + gobj_signal_connect(widget "event" :window-event widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) connect-focus-events widget widget diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 28d5e4b95c..51d2e31009 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -16,6 +16,8 @@ Red/System [ #define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] #define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] +#define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] +#define GET-RESIZING(s) [g_object_get_qdata s resizing-id] #define CREATE-DEFAULT-FONT [font-description-create default-font-name default-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL] #include %../keycodes.reds @@ -53,8 +55,9 @@ css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" menu-id: g_quark_from_string "menu-id" no-wait-id: g_quark_from_string "no-wait-id" -red-event-id: g_quark_from_string "red-event-id" +red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" +resizing-id: g_quark_from_string "resizing-id" group-radio: as handle! 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 982b82749a..c5daee8de7 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -303,33 +303,31 @@ window-removed-event: func [ ;; DEBUG[view/no-wait]: print ["=> exit-loop: " count/value lf] ] -;; BUG: `vid.red` fails... back with window-size-allocate handler for resizing -window-configure-event: func [ +window-event: func [ [cdecl] evbox [handle!] - event [GdkEventConfigure!] + event [GdkEventAny!] widget [handle!] + return: [integer!] /local - sz [red-pair!] - offset [red-pair!] - x [integer!] - y [integer!] + h [handle!] ][ - ;;DEBUG: print [ "window-resizing " event/x "x" event/y " " event/width "x" event/height lf] - - ; Set the offset when window is moved - offset: (as red-pair! get-face-values widget) + FACE_OBJ_OFFSET - x: 0 y: 0 gtk_window_get_position widget :x :y - ;; DEBUG: print ["offset: " x "x" y lf] - offset/x: x offset/y: y - - sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - if any [event/width <> sz/x event/height <> sz/y] [ - make-event widget 0 EVT_SIZE + if event/type = 13 [ ;-- GDK_PROXIMITY_OUT + h: as handle! 1 + SET-RESIZING(widget h) + ] + if event/type = 12 [ ;-- GDK_PROXIMITY_IN + h: GET-RESIZING(widget) + unless null? h [ + make-event widget 0 EVT_SIZING + make-event widget 0 EVT_SIZE + ] + h: as handle! 0 + SET-RESIZING(widget h) ] + EVT_DISPATCH ] - window-size-allocate: func [ [cdecl] evbox [handle!] @@ -337,13 +335,22 @@ window-size-allocate: func [ widget [handle!] /local sz [red-pair!] + h [handle!] ][ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - if any [rect/width <> sz/x rect/height <> sz/y] [ + if any [ + sz/x <> rect/width + sz/y <> rect/height + ][ sz/x: rect/width sz/y: rect/height - make-event widget 0 EVT_SIZING + h: GET-RESIZING(widget) + either null? h [ + make-event widget 0 EVT_SIZE + ][ + make-event widget 0 EVT_SIZING + ] ] ] From eadf759f88b83b7fe72a1c2e1c788bb7fbffd005 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 9 Oct 2019 12:04:39 +0800 Subject: [PATCH 0209/3432] FIX: improve code indent --- modules/view/backends/gtk3/gtk.reds | 250 ++++++++++++++-------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 340936ddc9..b9bc7e5f16 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -46,102 +46,102 @@ tagRECT: alias struct! [ ] GdkEventAny!: alias struct! [ - type [integer!] - window [int-ptr!] - send_event [byte!] + type [integer!] + window [int-ptr!] + send_event [byte!] ] GdkEventKey!: alias struct! [ - type [integer!] - window [int-ptr!] - send_event [byte!] - time [integer!] - state [integer!] - keyval [integer!] - length [integer!] - string [c-string!] - keycode1 [byte!] - keycode2 [byte!] - group [byte!] - is_modifier [integer!] + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + state [integer!] + keyval [integer!] + length [integer!] + string [c-string!] + keycode1 [byte!] + keycode2 [byte!] + group [byte!] + is_modifier [integer!] ] GdkEventMotion!: alias struct! [ - type [integer!] - window [int-ptr!] - send_event [byte!] - time [integer!] - x [float!] - y [float!] - axes [float-ptr!] - state [integer!] - is_hint1 [byte!] - is_hint2 [byte!] - device [int-ptr!] - x_root [float!] - y_root [float!] + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + axes [float-ptr!] + state [integer!] + is_hint1 [byte!] + is_hint2 [byte!] + device [int-ptr!] + x_root [float!] + y_root [float!] ] GdkEventButton!: alias struct! [ - type [integer!] - window [int-ptr!] - send_event [byte!] - time [integer!] - x [float!] - y [float!] - axes [float-ptr!] - state [integer!] - button [integer!] - device [int-ptr!] - x_root [float!] - y_root [float!] + type [integer!] + window [int-ptr!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + axes [float-ptr!] + state [integer!] + button [integer!] + device [int-ptr!] + x_root [float!] + y_root [float!] ] GdkEventCrossing!: alias struct! [ - type [integer!] - window [int-ptr!] - send_event [byte!] - subwindow [int-ptr!] - time [integer!] - x [float!] - y [float!] - x_root [float!] - y_root [float!] - axes [float-ptr!] - state [integer!] - is_hint1 [byte!] - is_hint2 [byte!] - device [int-ptr!] - mode [integer!] - detail [integer!] - focus [logic!] - state [integer!] + type [integer!] + window [int-ptr!] + send_event [byte!] + subwindow [int-ptr!] + time [integer!] + x [float!] + y [float!] + x_root [float!] + y_root [float!] + axes [float-ptr!] + state [integer!] + is_hint1 [byte!] + is_hint2 [byte!] + device [int-ptr!] + mode [integer!] + detail [integer!] + focus [logic!] + state [integer!] ] GdkEventConfigure!: alias struct! [ - type [integer!] - window [handle!] - send_event [byte!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] + type [integer!] + window [handle!] + send_event [byte!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] ] GdkEventScroll!: alias struct! [ - type [integer!] - window [handle!] - send_event [byte!] - time [integer!] - x [float!] - y [float!] - state [integer!] - direction [integer!] - device [handle!] - x_root [float!] - y_root [float!] - delta_x [float!] - delta_y [float!] - is_stop [integer!] + type [integer!] + window [handle!] + send_event [byte!] + time [integer!] + x [float!] + y [float!] + state [integer!] + direction [integer!] + device [handle!] + x_root [float!] + y_root [float!] + delta_x [float!] + delta_y [float!] + is_stop [integer!] ] #enum GdkScrollDirection! [ @@ -153,29 +153,29 @@ GdkEventScroll!: alias struct! [ ] #enum GGApplicationFlags! [ - G_APPLICATION_FLAGS_NONE: 0 - G_APPLICATION_IS_SERVICE: 1 - G_APPLICATION_IS_LAUNCHER: 2 - G_APPLICATION_HANDLES_OPEN: 4 - G_APPLICATION_HANDLES_COMMAND_LINE: 8 - G_APPLICATION_SEND_ENVIRONMENT: 16 - G_APPLICATION_NON_UNIQUE: 32 + G_APPLICATION_FLAGS_NONE: 0 + G_APPLICATION_IS_SERVICE: 1 + G_APPLICATION_IS_LAUNCHER: 2 + G_APPLICATION_HANDLES_OPEN: 4 + G_APPLICATION_HANDLES_COMMAND_LINE: 8 + G_APPLICATION_SEND_ENVIRONMENT: 16 + G_APPLICATION_NON_UNIQUE: 32 ] #enum GdkModifierType! [ - GDK_SHIFT_MASK: 1 - GDK_LOCK_MASK: 2 - GDK_CONTROL_MASK: 4 - GDK_MOD1_MASK: 8 - GDK_MOD5_MASK: 128 - GDK_BUTTON1_MASK: 256 - GDK_BUTTON2_MASK: 512 - GDK_BUTTON3_MASK: 1024 - GDK_BUTTON4_MASK: 2048 - GDK_BUTTON5_MASK: 4096 - GDK_SUPER_MASK: 67108864 - GDK_HYPER_MASK: 134217728 - GDK_META_MASK: 268435456 + GDK_SHIFT_MASK: 1 + GDK_LOCK_MASK: 2 + GDK_CONTROL_MASK: 4 + GDK_MOD1_MASK: 8 + GDK_MOD5_MASK: 128 + GDK_BUTTON1_MASK: 256 + GDK_BUTTON2_MASK: 512 + GDK_BUTTON3_MASK: 1024 + GDK_BUTTON4_MASK: 2048 + GDK_BUTTON5_MASK: 4096 + GDK_SUPER_MASK: 67108864 + GDK_HYPER_MASK: 134217728 + GDK_META_MASK: 268435456 ] #enum GdkEventType! [ GDK_NOTHING: -1 @@ -232,32 +232,32 @@ GdkEventScroll!: alias struct! [ ] #enum GdkEventMask! [ - GDK_EXPOSURE_MASK: 2 - GDK_POINTER_MOTION_MASK: 4 - GDK_POINTER_MOTION_HINT_MASK: 8 - GDK_BUTTON_MOTION_MASK: 16 - GDK_BUTTON1_MOTION_MASK: 32 - GDK_BUTTON2_MOTION_MASK: 64 - GDK_BUTTON3_MOTION_MASK: 128 - GDK_BUTTON_PRESS_MASK: 256 - GDK_BUTTON_RELEASE_MASK: 512 - GDK_KEY_PRESS_MASK: 1024 - GDK_KEY_RELEASE_MASK: 2048 - GDK_ENTER_NOTIFY_MASK: 4096 - GDK_LEAVE_NOTIFY_MASK: 8192 - GDK_FOCUS_CHANGE_MASK: 16384 - GDK_STRUCTURE_MASK: 32768 - GDK_PROPERTY_CHANGE_MASK: 65536 - GDK_VISIBILITY_NOTIFY_MASK: 131072 - GDK_PROXIMITY_IN_MASK: 262144 - GDK_PROXIMITY_OUT_MASK: 524288 - GDK_SUBSTRUCTURE_MASK: 1048576 - GDK_SCROLL_MASK: 2097152 - GDK_TOUCH_MASK: 4194304 - GDK_SMOOTH_SCROLL_MASK: 8388608 - GDK_TOUCHPAD_GESTURE_MASK: 16777216 - GDK_TABLET_PAD_MASK: 33554432 - ;;GDK_ALL_EVENTS_MASK: fffffffeh + GDK_EXPOSURE_MASK: 2 + GDK_POINTER_MOTION_MASK: 4 + GDK_POINTER_MOTION_HINT_MASK: 8 + GDK_BUTTON_MOTION_MASK: 16 + GDK_BUTTON1_MOTION_MASK: 32 + GDK_BUTTON2_MOTION_MASK: 64 + GDK_BUTTON3_MOTION_MASK: 128 + GDK_BUTTON_PRESS_MASK: 256 + GDK_BUTTON_RELEASE_MASK: 512 + GDK_KEY_PRESS_MASK: 1024 + GDK_KEY_RELEASE_MASK: 2048 + GDK_ENTER_NOTIFY_MASK: 4096 + GDK_LEAVE_NOTIFY_MASK: 8192 + GDK_FOCUS_CHANGE_MASK: 16384 + GDK_STRUCTURE_MASK: 32768 + GDK_PROPERTY_CHANGE_MASK: 65536 + GDK_VISIBILITY_NOTIFY_MASK: 131072 + GDK_PROXIMITY_IN_MASK: 262144 + GDK_PROXIMITY_OUT_MASK: 524288 + GDK_SUBSTRUCTURE_MASK: 1048576 + GDK_SCROLL_MASK: 2097152 + GDK_TOUCH_MASK: 4194304 + GDK_SMOOTH_SCROLL_MASK: 8388608 + GDK_TOUCHPAD_GESTURE_MASK: 16777216 + GDK_TABLET_PAD_MASK: 33554432 + ;;GDK_ALL_EVENTS_MASK: fffffffeh ] GtkTextIter!: alias struct! [ From 32a163559daba986f973774fae4d254b417523df Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 9 Oct 2019 14:48:20 +0800 Subject: [PATCH 0210/3432] FIX: add resize trigger flag --- modules/view/backends/gtk3/events.reds | 2 +- modules/view/backends/gtk3/gui.reds | 24 +++++++++++------- modules/view/backends/gtk3/handlers.reds | 31 +++++++++++++++--------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index ae0840f827..3fad003425 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -669,10 +669,10 @@ connect-widget-events: function [ connect-focus-events widget widget ] sym = window [ + gobj_signal_connect(widget "event" :window-event widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] gobj_signal_connect(widget "delete-event" :window-delete-event widget) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK - gobj_signal_connect(widget "event" :window-event widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) connect-focus-events widget widget diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 51d2e31009..49a4730acc 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,15 +10,20 @@ Red/System [ } ] -#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] -#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] -#define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] -#define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] -#define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] -#define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] -#define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] -#define GET-RESIZING(s) [g_object_get_qdata s resizing-id] -#define CREATE-DEFAULT-FONT [font-description-create default-font-name default-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL] +#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] +#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] +#define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] +#define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] +#define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] +#define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] +#define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] +#define GET-RESIZING(s) [g_object_get_qdata s resizing-id] +#define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] +#define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] + +#define CREATE-DEFAULT-FONT [ + font-description-create default-font-name default-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL +] #include %../keycodes.reds #include %gtk.reds @@ -58,6 +63,7 @@ no-wait-id: g_quark_from_string "no-wait-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" +start-resize-id: g_quark_from_string "start-resize-id" group-radio: as handle! 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index c5daee8de7..9968d78ac1 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -312,18 +312,22 @@ window-event: func [ /local h [handle!] ][ - if event/type = 13 [ ;-- GDK_PROXIMITY_OUT - h: as handle! 1 - SET-RESIZING(widget h) - ] - if event/type = 12 [ ;-- GDK_PROXIMITY_IN - h: GET-RESIZING(widget) - unless null? h [ - make-event widget 0 EVT_SIZING - make-event widget 0 EVT_SIZE + h: GET-STARTRESIZE(widget) + unless null? h [ + if event/type = 13 [ ;-- GDK_PROXIMITY_OUT + h: as handle! 1 + SET-RESIZING(widget h) + ] + if event/type = 12 [ ;-- GDK_PROXIMITY_IN + h: GET-RESIZING(widget) + unless null? h [ + make-event widget 0 EVT_SIZING + make-event widget 0 EVT_SIZE + ] + h: as handle! 0 + SET-RESIZING(widget h) + SET-STARTRESIZE(widget h) ] - h: as handle! 0 - SET-RESIZING(widget h) ] EVT_DISPATCH ] @@ -339,6 +343,11 @@ window-size-allocate: func [ ][ ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + h: GET-STARTRESIZE(widget) + if null? h [ + h: as handle! 1 + SET-STARTRESIZE(widget h) + ] if any [ sz/x <> rect/width sz/y <> rect/height From 3ff05c5ec34348c7305c487f2edbfbc41ee41609 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 9 Oct 2019 18:51:33 +0200 Subject: [PATCH 0211/3432] FIX: minor lexer transition fix on special decimal values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 14527 -> 15498 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index d92e5db395..8edff367fd 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -20,7 +20,7 @@ S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE; S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_EOF S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index c4803b84651df7db9295b99cc6b3b12431d75097..652d5dce77a70cb9589093a1f259debf4e133108 100644 GIT binary patch literal 15498 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 Date: Wed, 9 Oct 2019 18:59:27 +0200 Subject: [PATCH 0212/3432] FIX: [R/S] returned type not properly set for some call expressions with type-casting. E.g.: loop as-integer (e - s) [...] where s and e are byte-ptr! --- system/compiler.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index 1f34c8a0ae..bdefab827e 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -3463,6 +3463,7 @@ system-dialect: make-profilable context [ ][ emitter/logic-to-integer expr/1 ;-- runtime logic! conversion before storing ] + if all [not variable boxed][last-type: boxed/type] ;-- enforces type casting on calling expression if all [ variable boxed ;-- process casting if result assigned to variable find [logic! integer! float! float32! float64!] last-type/1 @@ -3489,7 +3490,7 @@ system-dialect: make-profilable context [ not find expr-call-stack set-word! not find expr-call-stack set-path! ][ - emitter/target/emit-float-trash-last ;-- avoid leaving a x86 FPU slot occupied, + emitter/target/emit-float-trash-last ;-- avoid leaving a x87 FPU slot occupied, ] ;-- if return value is not used. ;-- storing result if assignement required From 6262ccfd24b88b8c7abc1e4de2653ebc95644f75 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 9 Oct 2019 19:00:06 +0200 Subject: [PATCH 0213/3432] FEAT: adds integer! loading to new lexer. --- runtime/lexer.reds | 187 +++++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 83 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5c2ce747ca..267f7fe417 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -25,6 +25,7 @@ lexer: context [ C_FLAG_EXP: 01000000h C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h + C_FLAG_SIGN: 00200000h ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] @@ -88,9 +89,9 @@ lexer: context [ C_PAREN_OP ;-- 28 ( C_PAREN_CL ;-- 29 ) C_WORD ;-- 2A * - C_SIGN ;-- 2B + + (C_SIGN or C_FLAG_SIGN) ;-- 2B + (C_COMMA or C_FLAG_COMMA) ;-- 2C , - C_SIGN ;-- 2D - + (C_SIGN or C_FLAG_SIGN) ;-- 2D - (C_DOT or C_FLAG_DOT) ;-- 2E . C_SLASH ;-- 2F / C_ZERO ;-- 30 0 @@ -215,204 +216,225 @@ lexer: context [ ] state!: alias struct! [ - parent [red-block!] ;-- any-block! accepted + stack [red-block!] ;-- any-block! accepted buffer [red-value!] ;-- special buffer for hatching any-blocks - buf-head [red-value!] + buf-pos [red-value!] buf-tail [red-value!] - head [byte-ptr!] - remain [integer!] - pos [byte-ptr!] + input [byte-ptr!] + in-len [integer!] + in-pos [byte-ptr!] err [integer!] ] - scanner!: alias function! [state [state!]] + scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] -comment { - scan-string: func [state [state!] return: [byte-ptr!] - /local - p [byte-ptr!] - e [byte-ptr!] - c [byte!] - ][ - p: state/pos - e: state/pos + state/remain - while [c: p/value all [p < e c <> #"^""]][ - either c = #"^^" [p: p + 2][ - if c = #"^/" [state/pos: p throw LEX_ERR_STRING] - p: p + 1 - ] + + alloc-slot: func [s [state!] return: [red-value!] /local slot [red-value!]][ + if s/buf-pos >= s/buf-tail [ + 0 ;TBD: expand ] - - e: p - p: state/pos - ;decode/converte the string - - p + slot: s/buf-pos + s/buf-pos: s/buf-pos + 1 + slot ] -} - scan-eof: func [state [state!] + + scan-eof: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-error: func [state [state!] + scan-error: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-block-open: func [state [state!] + scan-block-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-block-close: func [state [state!] + scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-paren-open: func [state [state!] + scan-paren-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-paren-close: func [state [state!] + scan-paren-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-string: func [state [state!] + scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-string-multi: func [state [state!] + scan-string-multi: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-word: func [state [state!] + scan-word: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ probe "word!" ] - scan-file: func [state [state!] + scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-refinement: func [state [state!] + scan-refinement: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-binary: func [state [state!] + scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-char: func [state [state!] + scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-map-open: func [state [state!] + scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-construct: func [state [state!] + scan-construct: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-issue: func [state [state!] + scan-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-percent: func [state [state!] + scan-percent: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - - scan-integer: func [state [state!] - ; /local + + scan-integer: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + p [byte-ptr!] + len [integer!] + i [integer!] ][ - probe "integer!" + p: s + if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present + + if (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers + i: as-integer p/value - #"0" + if s/value = #"-" [i: 0 - i] + integer/make-at alloc-slot state i + exit + ] + len: as-integer e - p + if len > 10 [ + scan-float state s e flags ;-- overflow, fall back on float + exit + ] + i: 0 + either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path + loop len [ + i: 10 * i + as-integer (p/1 - #"0") + p: p + 1 + ] + ][ ;-- process with quote(s) + loop len [ + if e/1 <> #"'" [i: 10 * i + as-integer (p/1 - #"0")] + p: p + 1 + ] + ] + assert p = e + if s/value = #"-" [i: 0 - i] + + integer/make-at alloc-slot state i +probe ["integer!: " i] + state/in-pos: e ;-- reset the input position to delimiter byte ] - scan-float: func [state [state!] + scan-float: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ probe "float!" ] - scan-tuple: func [state [state!] + scan-tuple: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-date: func [state [state!] + scan-date: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-pair: func [state [state!] + scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-time: func [state [state!] + scan-time: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-money: func [state [state!] + scan-money: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-tag: func [state [state!] + scan-tag: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-url: func [state [state!] + scan-url: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-email: func [state [state!] + scan-email: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null ] - scan-path: func [state [state!] + scan-path: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ null @@ -452,9 +474,10 @@ comment { scan-tokens: func [ lex [state!] /local - parent [red-block!] + stack [red-block!] p [byte-ptr!] e [byte-ptr!] + start [byte-ptr!] cp [integer!] class [integer!] index [integer!] @@ -463,41 +486,39 @@ comment { line [integer!] s [series!] term? [logic!] - scanner [scanner!] + do-scan [scanner!] ][ - parent: lex/parent - s: GET_BUFFER(parent) - p: lex/pos + stack: lex/stack + s: GET_BUFFER(stack) + p: lex/in-pos state: 0 flags: 0 line: 1 term?: no + start: p - loop lex/remain [ + loop lex/in-len [ cp: 1 + as-integer p/value class: lex-classes/cp flags: class and FFFFFF00h or flags index: state * 33 + (class and FFh) + 1 state: as-integer transitions/index ;line: line + line-table/class - p: p + 1 if state > --EXIT_STATES-- [term?: yes break] + p: p + 1 ] - unless term? [ index: state * 33 + C_EOF + 1 state: as-integer transitions/index ] - - lex/remain: as-integer p - lex/pos - lex/pos: p - + lex/in-len: lex/in-len - as-integer (p - start) + lex/in-pos: p index: state - --EXIT_STATES-- - scanner: as scanner! scanners/index - scanner lex + do-scan: as scanner! scanners/index + do-scan lex start p flags ] - + scan: func [ dst [red-block!] ;-- destination block src [byte-ptr!] ;-- UTF-8 buffer @@ -506,14 +527,14 @@ comment { stack [red-block!] state [state! value] ][ - state/parent: block/make-in dst 100 - state/buffer: as cell! allocate 1000 * size? cell! - state/buf-head: state/buffer - state/buf-tail: state/buffer + 1000 - state/head: src - state/remain: len - state/pos: src - state/err: 0 + state/stack: block/make-in dst 100 + state/buffer: as cell! allocate 1000 * size? cell! + state/buf-pos: state/buffer + state/buf-tail: state/buffer + 1000 + state/input: src + state/in-len: len + state/in-pos: src + state/err: 0 catch LEX_ERROR [scan-tokens state] if system/thrown > 0 [ From c083f0a096f2e900fac90a55ab55854810a41e55 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 10 Oct 2019 12:54:42 +0200 Subject: [PATCH 0214/3432] FEAT: [R/S] allows cross-referenced aliased fields in structs defined in same context. Example: a!: alias struct! [next [b!] prev [b!]] b!: alias struct! [a [a!] c [integer!]] --- system/compiler.r | 1 + 1 file changed, 1 insertion(+) diff --git a/system/compiler.r b/system/compiler.r index bdefab827e..a4aec4c22c 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -197,6 +197,7 @@ system-dialect: make-profilable context [ find aliased-types value all [v: resolve-ns value v <> value enum-type? v pos/1: v] ;-- rewrite the type to prefix it all [enum-type? value pos/1: 'integer!] + find pc reduce [to-set-word value 'alias] ][throw false] ;-- stop parsing if unresolved type ) opt 'value ] From 6f0d35924162e9c6778a41b1b312094e3ba49c9f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 10 Oct 2019 12:57:02 +0200 Subject: [PATCH 0215/3432] FIX: minor extra whitespace removal. --- runtime/lexer.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 267f7fe417..9d67893b00 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -28,8 +28,8 @@ lexer: context [ C_FLAG_SIGN: 00200000h ] - #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] - #define FL_UCS2 [(C_WORD or C_FLAG_UCS2)] + #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] + #define FL_UCS2 [(C_WORD or C_FLAG_UCS2)] #enum character-classes! [ C_BLANK ;-- 0 From 6a635523be92e08ae2710cfcfd670d277f32092a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 10 Oct 2019 19:26:40 +0200 Subject: [PATCH 0216/3432] FEAT: lexer now returns a block of value(s). --- runtime/lexer.reds | 128 +++++++++++++++++++++++++++------------------ runtime/red.reds | 1 + 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9d67893b00..5809e3781a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -216,25 +216,29 @@ lexer: context [ ] state!: alias struct! [ - stack [red-block!] ;-- any-block! accepted - buffer [red-value!] ;-- special buffer for hatching any-blocks - buf-pos [red-value!] - buf-tail [red-value!] - input [byte-ptr!] - in-len [integer!] - in-pos [byte-ptr!] - err [integer!] + stack [red-block!] ;-- any-block! accepted + buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) + buf-tail [red-value!] + buf-slots [integer!] + input [byte-ptr!] + in-len [integer!] + in-pos [byte-ptr!] + err [integer!] ] scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] + stash: as cell! 0 ;-- special buffer for hatching any-blocks series + stash-size: 1000 ;-- pre-allocated cells number + depth: 0 ;-- recursive calls depth alloc-slot: func [s [state!] return: [red-value!] /local slot [red-value!]][ - if s/buf-pos >= s/buf-tail [ + if s/buffer + s/buf-slots <= s/buf-tail [ + assert false 0 ;TBD: expand ] - slot: s/buf-pos - s/buf-pos: s/buf-pos + 1 + slot: s/buf-tail + s/buf-tail: s/buf-tail + 1 slot ] @@ -287,9 +291,12 @@ lexer: context [ ] scan-word: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] ][ probe "word!" + cell: alloc-slot state + cell/header: TYPE_NONE ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -381,9 +388,12 @@ probe ["integer!: " i] ] scan-float: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] ][ probe "float!" + cell: alloc-slot state + cell/header: TYPE_NONE ] scan-tuple: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -474,7 +484,6 @@ probe ["integer!: " i] scan-tokens: func [ lex [state!] /local - stack [red-block!] p [byte-ptr!] e [byte-ptr!] start [byte-ptr!] @@ -488,64 +497,79 @@ probe ["integer!: " i] term? [logic!] do-scan [scanner!] ][ - stack: lex/stack - s: GET_BUFFER(stack) - p: lex/in-pos - state: 0 - flags: 0 + p: lex/in-pos line: 1 - term?: no - start: p - loop lex/in-len [ - cp: 1 + as-integer p/value - class: lex-classes/cp - flags: class and FFFFFF00h or flags - index: state * 33 + (class and FFh) + 1 - state: as-integer transitions/index - ;line: line + line-table/class - if state > --EXIT_STATES-- [term?: yes break] - p: p + 1 - ] - unless term? [ - index: state * 33 + C_EOF + 1 - state: as-integer transitions/index + until [ + flags: 0 + term?: no + state: S_START + start: p + + loop lex/in-len [ + cp: 1 + as-integer p/value + class: lex-classes/cp + flags: class and FFFFFF00h or flags + index: state * 33 + (class and FFh) + 1 + state: as-integer transitions/index + ;line: line + line-table/class + if state > --EXIT_STATES-- [term?: yes break] + p: p + 1 + ] + unless term? [ + index: state * 33 + C_EOF + 1 + state: as-integer transitions/index + ] + lex/in-len: lex/in-len - as-integer (p - start) + lex/in-pos: p + index: state - --EXIT_STATES-- + do-scan: as scanner! scanners/index + do-scan lex start p flags + lex/in-len <= 1 ] - lex/in-len: lex/in-len - as-integer (p - start) - lex/in-pos: p - index: state - --EXIT_STATES-- - do-scan: as scanner! scanners/index - do-scan lex start p flags ] scan: func [ - dst [red-block!] ;-- destination block + dst [red-value!] ;-- destination slot src [byte-ptr!] ;-- UTF-8 buffer len [integer!] ;-- buffer size in bytes /local - stack [red-block!] + blk [red-block!] + slots [integer!] + s [series!] state [state! value] ][ - state/stack: block/make-in dst 100 - state/buffer: as cell! allocate 1000 * size? cell! - state/buf-pos: state/buffer - state/buf-tail: state/buffer + 1000 - state/input: src - state/in-len: len - state/in-pos: src - state/err: 0 + depth: depth + 1 + + state/stack: null + state/buffer: stash ;TBD: support dyn buffer case + state/buf-tail: stash + state/buf-slots: stash-size ;TBD: support dyn buffer case + state/input: src + state/in-len: len + state/in-pos: src + state/err: 0 catch LEX_ERROR [scan-tokens state] if system/thrown > 0 [ 0 ; error handling ] - - free as byte-ptr! state/buffer + if null? state/stack [ + slots: (as-integer state/buf-tail - state/buffer) >> 4 + blk: block/make-at as red-block! dst slots + s: GET_BUFFER(blk) + copy-memory + as byte-ptr! s/offset + as byte-ptr! state/buffer + slots << 4 + s/tail: s/offset + slots + ] + depth: depth - 1 ] init: func [][ - + stash: as cell! allocate stash-size * size? cell! ] ] \ No newline at end of file diff --git a/runtime/red.reds b/runtime/red.reds index 0d5647c0cf..dce5d527a2 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -229,6 +229,7 @@ red: context [ ext-process/init stack/init + lexer/init redbin/boot-load system/boot-data no #if debug? = yes [ From 0f1eb4b14d3de84106bc86df25333812cd306fe4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 12:37:02 +0200 Subject: [PATCH 0217/3432] FEAT: properly skip head blanks and comments in tokenization. --- runtime/lexer.reds | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5809e3781a..1ee9b2c4ac 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -66,12 +66,18 @@ lexer: context [ C_ILLEGAL ;-- 31 C_EOF ;-- 32 ] + + skip-table: #{ + 0001010000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000 + } lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN C_BIN ;-- 01-08 C_BLANK ;-- 09 TAB - C_BLANK ;-- 0A LF + C_LINE ;-- 0A LF C_BIN ;-- 0B C_BIN ;-- 0C C_BLANK ;-- 0D CR @@ -353,6 +359,7 @@ lexer: context [ len [integer!] i [integer!] ][ +probe as-c-string s p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present @@ -493,6 +500,7 @@ probe ["integer!: " i] state [integer!] flags [integer!] line [integer!] + offset [integer!] s [series!] term? [logic!] do-scan [scanner!] @@ -505,13 +513,18 @@ probe ["integer!: " i] term?: no state: S_START start: p + offset: 0 loop lex/in-len [ cp: 1 + as-integer p/value class: lex-classes/cp +probe ["char: " as-integer p/value " class: " class] flags: class and FFFFFF00h or flags index: state * 33 + (class and FFh) + 1 state: as-integer transitions/index +?? state + index: state + 1 + offset: offset + as-integer skip-table/index ;line: line + line-table/class if state > --EXIT_STATES-- [term?: yes break] p: p + 1 @@ -524,7 +537,7 @@ probe ["integer!: " i] lex/in-pos: p index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index - do-scan lex start p flags + do-scan lex start + offset p flags lex/in-len <= 1 ] From b591c4ee23e7a81114f55bcb46a14e131c0ec742 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 14:02:15 +0200 Subject: [PATCH 0218/3432] FIX: removes leftover debugging code. --- runtime/lexer.reds | 3 --- 1 file changed, 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1ee9b2c4ac..9746036bad 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -359,7 +359,6 @@ lexer: context [ len [integer!] i [integer!] ][ -probe as-c-string s p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present @@ -518,11 +517,9 @@ probe ["integer!: " i] loop lex/in-len [ cp: 1 + as-integer p/value class: lex-classes/cp -probe ["char: " as-integer p/value " class: " class] flags: class and FFFFFF00h or flags index: state * 33 + (class and FFh) + 1 state: as-integer transitions/index -?? state index: state + 1 offset: offset + as-integer skip-table/index ;line: line + line-table/class From 2032e958ef0f186243dfc85f42f8e3e4dad96d63 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 14:03:06 +0200 Subject: [PATCH 0219/3432] FIX: aligns S_BLANK transitions to S_START transitions. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 15498 -> 15864 bytes runtime/lexer-transitions.reds | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 8edff367fd..ab6b676d6b 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,6 +1,6 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_SIGN;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF S_START;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_BLANK;S_BLANK;S_BLANK;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;S_START;T_ERROR;T_EOF +S_BLANK;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_OP;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 652d5dce77a70cb9589093a1f259debf4e133108..dcdf7ca4ae8f841f58504243eefcb09f3e374d44 100644 GIT binary patch literal 15864 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�A;Vz0~j+uO)N9sV(t&>te&GDsS7t@d&WLij@R8STO&eADSb0|^DWnFTu zQ|%d23T%nutBTFL>3=^c+Rl2iB<7! z&*7u62*w&tu(qbbDJsf_^~P!vpj8FEqP>M)4e0t-6^&9HE4=w5-I+ z=13o@mQC@~0rRT2Mu32jiq_q3v^RyIZEoAJ^wCJ541cVF@CRxBz88B(zD8m@u4h?q zyfNVmYz7C8&rtp?0z=amejlLRMuwgoGyE0-dnl`~Wa;SG>|MYz^AG+)v-KLQC0hdubEkUwNYU zvflIVI|u8wzU{%v%J3~#+rVAkxFbtT)MK?nifw%-gVP(fZPC^45Q5$iH~oXVLm?Os zPBsM{X>R=w2adPpp)C|7MYEv`5^CYz@D>Dwkg6$hHE1Yl6~Ne6FO=>baaN;}-!LuS3>C z^XLfzD``=vGiw7#a`F^DNCACYQ{)wNNOC!uH?RB--m}m@<3jgSl5wh_IZWzwUjDj8 zGirnq$iCTotIkHhA0#`#zpj|;pol@P1fM?3`6G9<$|Ez&xN~Y(K?jH%0p7IbOMWD6 z#1SR=IpSbFp9`MMJ#{>zmn>$-Ua+wsX#Q0S6?nY4VzNcl8L7A;uslunzC-W9s!Tv>q4)o6K zN2t53t9*>XFW@gRuzbac7aZ2}xyA-vQ{OKFR^~aqe6-8Ln1Zh?YnSSUxjyNDi4oOQgBFsFO#|!sq zCNFdJ5#CG;Qw82xd{!)MP_4rc;A_OHcobzbOTX6~gL9;M)B4t9OCySDeqI*9$oVwo zW4pI88hGSK-mapC)5i2te>&>wZI!F83tVoDps(mlD)`6L*@^X+oyK7C?#R&>@`Q&O z?@ogA1M?$dY&R><^@?(G6m#!sRB%haQL!H zdvv>ovchslELQY!(%p0|YQak9#;LHG0o{GqX4%*~yJGS(85jwL-GgD@1f%A6skR8~ zELti|bgWD?^gjS%^`?a=b^XG9Av8Xh3{)cFxr^ zsy*8#5);#`)O4q~<4n&0fhr~)?7IV1F1oX5JUa+rK0+5nIO*4w$ zkMYjY;SPLjkR3+Ehe&rR6>K%IM3k>*HzeA~oa}Cygu9&^#^AF#$g$Q+#!yN!Zm8Bf zMHklK6L#bYqs|@|3G;{$&F6|>iRcWm7IwSGEjn>0Ebm~I{(0^W1Iq%H`TxFq^^ev1 zi!t`a4dvU;xD`GejWJhUZX#U4nlVy{oZK*$Ihc)2mgI5$Dcz1 zfD)(@KYUS6P5x*Mv^%}~b z1^`Sy4g7gU<=3IVp1u7!w1f4xp}(HX{c7P?mHelLbdFzR@UNQrSA)Nb&OZ%ia{e^< zi{$)Q3HqziznAzwO+srL4*>9wg8%FAzvt<{4!?sY_Wun3J!>n=AwV$*0H8yE=%Fxf J7I=8|e*ghiI_dxb literal 15498 zcmeHuWmKHW)-LYuP9V@|a0%`NYpjs~!L@OB2$0|wT$S#N^!xvP{V(=FS>lj=CkKwqMbZ^^ zT!W^`x7-qDxJc3DCwQmuO2TwRF?L=^XfIdfJ&PoT36g-hbD2H|Zo*ViGj%{MoN>>T zNdFmp)W%MmwZRv@Dq<6sagUe^lg_Z5t6&N8zTPewHK7KeY6}g^$PgIhcjpG_8gIfs z%}l#~&ayi8d@wsAm{~&f+*_skD5hOaAv%NvYuTtGIXV7<7u(_Oa1{Q)uDkxL!C|dp#@j3Ya)PqN84LL+)&UQbaaGcVR=zhrqUl6kkWh=sfIx zee#@ZwmrT4Vr6)A2|D;tfPmW^mbCrlL3>^#OuCTFE76YReM-I?XfWR2!^5clB~JT2uH;z`_fa)BF0TPPB^QpX9!r2(LuAi0|$OvSnEn|7aZ*UM+n6 z6=?RuxT6PK!w@?0zeh=+XkyAK^iC5rO2}YPU_EWwe+v{32WJ}-2M3#nl=iQnfraKZ zX!85t{VIzeQ|RWv={*cO#M!i;te~ZZ9LT(Gwe|~mqXen8!{b`Z`q-M2yBKWVdW!eM zqW|KSD{cS4hN2r8u=7e=m5?6g6fn2!fwr8!1wqE?UeFUkh(!a?%}vj0FA`JmY$>i^ z$&TH}_(noPgiKSE*`1n^;~BvMNYT zxWB-%TO{{I+w_wjv!tav=2=G$lP$#3>4;_Hdfb0<4B=f9h((Ouu1P%6(KjiYG5dkB zEshlzOYxFE-erq+cqyG@-Bt2>kg0OwqRcj8>HeG3gJn$rD`SwQ`eu(L+2yjL{q?uyneHd{gJj7%H=A!`lo? zp)volq3Pndb@C`e-3?da2qsufYqlwxLPN-GC@K96XHVJ`nzJ{OqIS>iQuXX+i9Kai$|)+=SKpE{`C}U z`1B>6vX#aQ8Gn+_9Fw=My&OGPb3(^LM#S#@ZXo9YH@(44C;PCG#D6y-z6^8{59RIA^d)N&>OuIts^ngJUcp~?V`Iwo5jn|KC;uMVN z-ZtI)r@%~32~nN+iLO*0`jUQbvorK=8w64>0C@C~n@7^wCm#?%> zp7y@1E*&)fURaiJJ>G}?s>$BlN^iPr{R8;iaI)4wBxTXuuWm7gkW0)XbicY|tP7-j zh`r&gFP36n<0tQMb=&OP{8>ZZq0XnA?DYEbKybTN3u0LLPFUi0(Tt~vKTm=i4JY@= z=?!0=#Db)yr>%5-w&U|}6hL8fTl8I9*|cIlviNc zKjB65PF6c@KEaP5%A7(W{|rQVnmhe6(X0$$3crH(%;!nqTXj@f%lvUXfOkQ75dDqn za%*f`>-+#B`F7k_xRGFOQXBk6*rb%|_|d28R;buK3TN#}@ji4MdF^X0Gjzi(otL!m zk7%?FN}`JMU1!k9%v7~Z6%uiVDe?OP_F!@>NJJFg%pq=KZ4~gp*+r#~6F-Av*g+Ze zd4`6k#*(2P^K@DsVG6Z0KF^;`M^)HW5*aMt#1NvdvF}*RXLimhrkm&KRPKfyZ2rO( z@CYNE*?^IyVVBmE*Szm}sxMnVt5My&9dV!@7`LoHjp_^dg`3g9W^6l~;Om+q3s;5r z12>5X;=ya~zLh;FptWz}(ncPJ2=*6WjV-$Byz_i8#wPTG%)t#L(a~Nbi#BUFx8tAc zo_>Orc5?E;&!WFw0i~?At$btuM|2C>aVd5{??^&P=J9XnejpeZD|2&Km*4Z#&kN3f zXQ$V(9TA-z1Tq)!cT%1{2{XYMQXqcXM$IjFldA=!#gsP}1h+ml6z1(48;)Zee2{D5 zVsZ$Uyt1-Fc;B1ngy>blYIL_G zUH;wkRWYc=Z$vle<-@%=1}-DXKb4hO+kH1gu4PxQJ7it=(|#o=qONnd7vo1QY@gRQ zD))WtwY+|Hc+=ljoT@9C&GEbl0kB<7#woDP`y93`pWvEZvjBRbL`@t4K~2kJe{8?5VV{oFR9(FmrvV-veQ$!$iJ$~fl!<8c{ zAqAXR91Oc4Y3Wtifz1jJ1OPJ#k%Tg5cqB*7Q&3&QbQa-7P5pW3uoFW`lF_Jj z@FyRgjk-51x*j2!9gooa-Yb;qcpM`UaFMB`d|Jr4^;ZxHReHMkB-jDQH!r=Dm@zCw zxQQncHFmn>dE}8F+ZD_w@eso3xO4`yAiuCxwiwwUlMxsPyceleQXgNCO|-l@MFeUr zUUPK3!A1A3%zSyja|t@#xlC9K9gCs9bG`XCe%wX<lXvQPivu@7!1|lm(Z*QCX=#T6IpUM1qBP*S&w~j)2 zgyPB_;zZBz*y$r-7Y@i05i8IgbvqM{@=LjZg?S^EQ?!S+_%S2ALDrIo8Rct}0xQ%l za^rQFi>H>9Yzml;QYXyMJ)cIta^5u2>ZUaEecsy~Y1&uUsspFVjjqslzVzm)$pJS7 z3&opM#{8`xiEr@s57c(%++weS6h+m(QOQs$DFV6jA2YlmigX7f_@||8V^p}?)_4%R zJ!P5n4y9<4lS3I+cukGBnR+ak$wZM9N3j}4i0O}C`d+EO;oc@HKYwH%j5i3ske7??h)6l5M4*mh}vCv^T!@%x=gq zg)o)6=+qb91+7;*v9 z$C^f?wWN7&z%OOPGnM($5)HG)T9cA*)AUBdEFyBdo@nbp<}!vl)<0Ntr0U@dk|W&W zJpX{&=RZO=DwG;mRo{H3wn?-W9O)W|ah#ejI^oTJU1X7w*fSVUtBXyJakb|eF^%?F zH+_%XQ7AGYVsD3K&V1PipWPg{OtocGB)--0lb*K3b?Ot_r_I&K9u zB(gY@9M_DQgZu+`1?=p&H;A@)wj)wZkSzN+6(uv0_1@;{0Q4G} zc5qXYn%MS8Gs5^r3?y^N;D}fyIzx5z)&03qKKHwQryNNvO-9t>72;1%Qx{;z;j~*g zFeMN@rZ(Figt^JdUZ!(zV4eotMjic^hkJ|Mlq)NQ@JY%X7&_$It4sFAD6 zB(|T%SV|ur;_YyuijrerBCm^tabR}y;Sh`z4Y#yTa57SCcDZch@+IrQ*Ou#*x;-Ty zCeY&kMR$wH^Su)HR-MfKRvDSo?%a_QOC8u@G(8Cx;PouQ*9^V#^5=?VmAqVE+arg_ zx{Q`_=pEx;pHk1=7agVDe#zmVq7e&Ni1>0H3_vo5SMwX-qmm<*6M7odJAk!dG?8Bh zo}7`_d$L%@-Z(jOnaNR~yvKScT3B_mIc&bQzA8f|RQKN0MyP&b>dSlr6Pi@Q-Xl{A z(~pUSViw2aevYSDzI>^i^gxb|Lgv7nP^whnfb|B7k%{uQe@x@W*B`83!o$GuV8Xya z{~z`VF0Nj-=0DZxu=b+;;!_+y_V@RXj`YWSl5NQ2BNk!;;Py=d%>qBFu+^0zryQ zD$pud8i}&dVI`BSUmUjXvw8g6i|F~f&ca7gRBhQwQOO}Pt#w{2q1>+wiAP(gvvcX5 zsY`N>Jh^)PUfxAL>4M0C183P5kv7iY1QT3y!B@(K`(s9kl z%zcBn$eB*JNV$l#c63HolBrh~TUxW62g>7udrW2bbT77^N0YxW;e`*vt|8MFY6Q;> z^cUcES6rlz>pD)PO^~=&?F#x7e|wf{jWA7-223_}6JY)7f}eUHiz3cZ5Pm%Um_zrN z1&hx6z*Cr$o?pw&Uq+e@H^_v9c`t`d06z$>P2*+2vC*vv*|p_to?6*6)XodV078K` zb>Z&Ipiwn=%9D@4Pg$Fig8+$9>_jlLteQ|Mz$m$|25S)#z?Y&}`e}{r%L{pCU!yB` z3Z+jUZbv_oWTRc{yc`!Qej*(-y5F$5Pskco8<*$5*oldqIVv%ZaO>0R^td-`d$YGro28(e=EzJ2g9VZM(ZVI=wx2<*K;bx;kBVbGbM@ zJJ`AcyZKy=?VO#q8Q$Gij=d~5^nZChzk3@yy|%R5e0H)U ze>c`}Hng@R>wo$EcJJ)c-0i~6=hNC)&B?`KM=(VPo-+kZO z4tOo1rObcXZvDparLb_D#WdBS{D;2gl$CqWyRqA=V;zN?^P>~vld<}5+XHL2g}oPr zXG2R4VjE5OY%i9VEbAKD=2-53INn$L>%UxVNpQA2kiMwA+}zt#V)nbdIg_Y(^!7X< zWx8Q;GXIFF*w7#&)9G$cgpE~lW%PqzWRR6 z*K1oAjd!IV6;vdY&%ZArr!BiCi}~Faws^OuEV2-v9jr>}UijaFBKpNtsHi90m>aeZ z9QZM@4f(~^+m_pWUi!KCc^#__w%FgvAI^_#4>*+00;g4aZ>cLGXKTYghSSqR7iVl{ zx=Z(MULH*MaUlV9)GPdAoUgp8xer@ZR9$nYgT&OM^?Z)}RNZnLW#J=H*+tyN!<@2O|>f z)qf-sov^Ga6j+?BeZ9L_T`1qpaQiNieDA0GSU&P|rh$Wl;}!XKQ_9K@MqYar!{FP? zjn&PQ`K)Tm!&}aGe$JPobQ=`vDDw278KL>pt-#_3X1CaD`ZbtIbt(n|p{SZe%6X;M>|a=t&@YtAK>0_hlHwRec<1Oi*s@iW%x zzAKD4#^Vok`b0ZRdcCvY7?9scYQmLQX07yJ8spw}a)?%5a5czNe5t;ET0dks@^|jg zfPJ;$`U}mp1ALJuHGa7Od;6?GleYe6)7Z)GNp$ndWed~I&V6#_>TP$m+c#rU+**A=dyB9-)iJbp(3dlApDk#-%Ok*JwUMGmy-_e zAu6mx3a-%9>eU}%<<{iX?Li@1=EHqe*$rSpIgmo`+LZCmVnGN_r)~8 zJLn|pTi9LWB7h})#q;_02_e9AKJa|LT|x}7iEsPg4wyHyO$Y}T@TJY0*(U@8llkQF zjKnDtGK6<(=^w?RhMB=}rTtLtg}iNcpV(VZ`sOskCZftKbSACmN@wLBk!Y)4FW&>u zgiP70H^_GZfRI|-33s~2zMWv(zKV%D`7wYW1jClAcAy_%3Q@Ap9c^^ zH0;!ClH?6_(MJ_FDptakBq?E%67 zdR1gPF4#CFaR5H`Abj+&-?wcL>CKebQ9*|9Qn!qiHvEvwh<9b zB?U!kx%LquOz8zy0=S>~&H^PCStmGUW(h<iptIAv@1sKII%@uB5GHFoNkuTPe8l54=-cdWc39D9~mL6I@t zWa&(U1x2a3))DDUI|Wv$x!{OoriFrUskt^0nM_v&B&jA=5phht1*xef))8q;n+4BP zO~4U!RpD=&^3AlXTvFyb6!+HYMZJ-AlU@qDY?0q&h#h$Xnu%gudX6tF7pX|= z`KFyCGWV9dZO)FZP*bb<aA`UwT+M3BK`B{L7BbQ(Ea63Q> z5@pL(KhO;TL56L)8U{KOp6e#J_q(s~Og0q8A<``R*(JzuYca5=@3=gfKd^~S3g+h1 zA{zDFjT}>*yEZF{-SgXyGd=`q>$5(^`;Z+E9OQ#`YMqb{+~EVy<%1KFfeU=wbNMz2 znZPSP(m6A$gg9U?U)r3RbwV0&lTT;P42%!UTAcML_qc}xom(_GmE)V2ukyirEsPqY#Ww# zjgzPac+d%eufxqDXjh&6J9)M;erhs*^K8X3vfb93AaAjp1j{J`_rPs0d`PBf5jTtl z$}mbQCkMWR$t*9T1yXPND?xOJAo_yb8U$IgoS`oVSL5?>$|$PIQ&#kNn&1$l#?S9d z2w7r-D&nC$yKQ~1hfhVBI`p2h01^{>6~K4<3QgUmLyvO9?&| z!12T(=(Qq@4bBX9&))F=8PUdo)j7Hqq_k;y{@v%0+_S`jlO1?IOS0RMx0zR$N zz$Y6d)9gb6(%71?1!zi`se&AsM(ORf0buw^*aCDV>{L+>c%zW^r~p!UZdePnVT@D( z4s@gBb~&+HZpK@j?3Vl;l0m)K*?6d>E%GSL=1$S>Gpv=(u>_$X)%4^%bg5^tm#Fra z{EG~;2pgumunTLMU_nR)a7u)!WE^frWbHhGVA#oXi;ED$(kvlL)x!VOr zO=1WNPIw7VcZR}F9;{b+#;Yla&;$xkwG?TLZKFd)Q&P2f@OJ9mU>iML1`KqKAu+Q2_AsF7^@pH>r*L(wRoX5nAc zlU5CXtw}~(l-P47UO7aTTj~lEjLEs===Va(Rj=+ zfsz(8q%L!CG*-%QeVf!`BVr!ke5*{djm7X-B$&F^l5q%vl+>>$1~B>HD@Bu)LRU0O z^WW$-T4;A|nSU$g#?mApy)t2tsg@OZ<}&=jo8SD6DVlZP#3#s{3H8Rb+AJ@U8(_IR zd52&s4SIRPeIYAK<>%8Ne~7EI4!vD>YH^XAS-ORAS(ALxHszGJQZW=n1_57AChNar z9Lyz?(b39dM7JS;j+XXug|S#7qT^@yRWB$3V4n#Sx6bRE@iUXq8x1b+EqhXCqH$<) zX#EA{$ADC+Gi7o9u_D0q37{VCTEOj`JXcSwhYJhXGD~Shfi} zSXjdxPn&al(s3y#I1L56CL~59>5?K(PauJ_FP@c^j2MNvB_cy461=%zB?S^qqGNJkr-u>!`Tdtff^p32kxk8iNyL<%vDK5m7DB zu9*=rIkze);@jNWudk;@K^0Be-ouRE_=iCi%EO5gZ=qf>`h|%lNTzOgf&`&qVN?cX z9wXT=zP;^A0ck-eX@P<+MnvtbfpKi#;E0-!ClL1u6o?U$JBj0qq|0 z%u5m>sk*jT%Qn7e+A8c?+v7crf|St1+Ltg$pT#&Ge@>g5PliTIjS%nF&Scf!k@%na zR;pHt5fk?jp5`UQ7s^0oRlRTC)GA0Jbdh>tt~^!p2%x@r{p~zv=(45Na~4?Qd7yMO zDQOo6W!rPWGS0%+8dq{QGN^5bp0}qBI59^|3Z#_I)0oa5NK`GY=2Z+SJI0 z9|$mlJ0iz{y^c1k$!k`F$NHSy1mit6bbff2A?lf?c3(rVn)eoPSCMBia99DLENPtl_QW>3Q9? z-_bNFs3n^7Mlk2AC(l?x)0$dh%IqtZu<9SNwqe_GB{U^oYz9y9^~!!mj0E%to`7F5 zgvFunU~=;LCv*OmK)(a(dwa7-5vJ1q>RYzgRpbCnC`FZwEBwLPxxaS`B`L~zoXLkd ztGw(%w{$1oeOAX?_#oRJ6c7*dCqASLnzuQ$sHaF_xDhN6hDlPx z`K!!;t>NWcq$D<2!*Ee`|0%Qax-YKN*N`8y`=J|hQQrcS&>QSTeyGau7U%L;DKh_q zOc~|gK~`ZHE4rRWEJ!hBn>q;cj}g!|#r#7z6!SNCG^tf;SY(evgXd>HZ_4hK{4H|5 zuyHkLje&By8zR#D8RIy4j8HFALCMiPxsvx#gr)?Cs1@}fm<#Idc8!2yIMAQcsh2Eo zwsNN0MecvpN1yMt`ad)sLn)C~Eh(hYa9h$ZTrv~qVtiR34oViTNl_srGR9Jg3@wkz zO}x#1#OoM(9(SgBO4R~Mr+(^{zqt5M((@mc3T#3MifZ_ycujDa(bIS>a9BnB@3Y!G zS(a)L$6?AyAy7`~^ObabA7I{==F7B*GpT zfz~)FWjI@%NIMS-U}V)foXP0r2el_7Y!&8hdLGPu9AX9GDgymKDq5*p_y>IANzj!( zkj-Oo5(89CidUYzv=gUzP+q?NQ028a165vkbdc3xZV4$3NP}W~qD$1>$sUyBT!w=M zvwqcH8?J%dfmMGJm)(%L8>N4xlZP}KVil@NMk`KN^8NKU=AKP8GFpLK{0NUobw}y|nu=f!xmwJp` z3&`EC{|u4!kptRhHEOabmtkevdUPka-gG!_=ssv1n$VZ`3{ph5%ttTx?t#n#aw}1E zkvj+Fvnw`o3i)`bHj)$RW==~Yg{}Bw-^m~c-6*zmxaOU)KGH2pu^2+D23!$TJqOkg zY}oO+=r9Kg-@hfB@8OG;9)8ml&}|j$B(ep}Fit8ihpB_fuH!0@RTsoD^K)Tno3*%Vnuc=RTr{G(44T$w7@?9zM(2fT15hwm=osFG)Lk0P^~}BdwEz8MgQ5UJ z_P6sQapZM0`461oDdlR~^LIrWKB6)UncLY36!bItDK22S&jIyV4DCu#e~n>ej8R0@ zLD{)CKEw)HiVBx9LO+d1T9s+Yx>h~-K~m{e$rH_fbCfmc3Smr&dEiK6sj0Eu9z`f$ znS5v_Rqh71LfQ;wol z*u+{^ifNSsFYR3}Hcn2KE;P3eHmM8s-Um5#v~OClq$VB2M~sYFLc(FV?H+wiiDFF0w{%?FO!E<;rpn5rtipk)mUD> zDw^mXib;(85nhi4@Tfr{q9ahU^&M|n6wXL0OF_!p6B^We&YfRc`Bd@n!0pu z4#m2EtGuu)`j|7CcmG%&FB?&x!@18Q0rwcLALM(6``zImkvB5?BQOVwIuv9W7zXG! zpwFNkp%s#@=FT8_t3<>!y6@dr(DN#DZLJ%Otah<>H@QbZ?MHKuSiO9y^IQ%ETtuFs9HX$2 zpgCGmOj&h=7d#F3XVz?D4l)v!%`$YSR`|nS~tkorcDB#ho$_u69DlABQYmk169GG%V zj67U@$Bm%hbWJ2E4SF|H#DkLe zl_uo{z71F2c%tQ=WwCKh)g%R9@xAn%@9^Lh!F%MK-3-hdgBBHireaq5K9lO)JG5`H z6&DSL8iW*H9UvLY=1j-=-9%#kPJKQug)yQYhkQzwuoibQDp@*(5g*eNwh1)YFyrhEm@WtVl!mTmW z(xLrcOG-LdP689rAsM8O-oaou8mghT!k5w^W|HQ<7^-2E*^N^SZBtx5M0f)2QIFw> za%rrI)pPBPOdWfjjo!t8O~V#zldCG;21Be?_;BPhH!dAe^@3C-+!p*1A~>DK$5o_C zt$aj%nLVDs+qg~FFY8G8D*7GTMv&MH+BXoj#Dmm0m(cd~oNFgP#7}CKmmNEfbTsi% zNepy}F9mL=)bp_AXi+{9d`|!hIS{MdS2ANq%IRa0wv6WvBq?o(9#Op}V%pwHHK>Ap zq!Ev~=EzvM4Blru_2qDMvfYE1#UYBpReVNulw*)Cy@E4V*bU#+FSMFCfZ%#7*d~c} zvAHHnc{CQR?Q1*aX^L`=E=*OTX^N-Oa?!{j1@_XDKum z{&eQ+*M@&R`10q5 Date: Fri, 11 Oct 2019 15:09:23 +0200 Subject: [PATCH 0220/3432] FEAT: code reduction in scan-integer. --- runtime/lexer.reds | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9746036bad..4753865a28 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -68,7 +68,7 @@ lexer: context [ ] skip-table: #{ - 0001010000000000000000000000000000000000000000000000000000000000 + 0101010000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 00000000000000 } @@ -362,32 +362,29 @@ lexer: context [ p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present - if (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers - i: as-integer p/value - #"0" - if s/value = #"-" [i: 0 - i] - integer/make-at alloc-slot state i - exit - ] - len: as-integer e - p - if len > 10 [ - scan-float state s e flags ;-- overflow, fall back on float - exit - ] - i: 0 - either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path - loop len [ - i: 10 * i + as-integer (p/1 - #"0") - p: p + 1 + either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers + i: as-integer (p/value - #"0") + ][ + len: as-integer e - p + if len > 10 [ + scan-float state s e flags ;-- overflow, fall back on float + exit ] - ][ ;-- process with quote(s) - loop len [ - if e/1 <> #"'" [i: 10 * i + as-integer (p/1 - #"0")] - p: p + 1 + i: 0 + either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path + loop len [ + i: 10 * i + as-integer (p/1 - #"0") + p: p + 1 + ] + ][ ;-- process with quote(s) + loop len [ + if e/1 <> #"'" [i: 10 * i + as-integer (p/1 - #"0")] + p: p + 1 + ] ] + assert p = e ] - assert p = e if s/value = #"-" [i: 0 - i] - integer/make-at alloc-slot state i probe ["integer!: " i] state/in-pos: e ;-- reset the input position to delimiter byte From 5e22d275394b8e7cfde9f368153612717df8926d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 18:12:24 +0200 Subject: [PATCH 0221/3432] FEAT: properly allocate returned block when no token has been loaded. --- runtime/lexer.reds | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4753865a28..ec54926378 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -363,7 +363,7 @@ lexer: context [ if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers - i: as-integer (p/value - #"0") + i: as-integer (p/1 - #"0") ][ len: as-integer e - p if len > 10 [ @@ -386,7 +386,6 @@ lexer: context [ ] if s/value = #"-" [i: 0 - i] integer/make-at alloc-slot state i -probe ["integer!: " i] state/in-pos: e ;-- reset the input position to delimiter byte ] @@ -564,13 +563,17 @@ probe ["integer!: " i] ] if null? state/stack [ slots: (as-integer state/buf-tail - state/buffer) >> 4 - blk: block/make-at as red-block! dst slots - s: GET_BUFFER(blk) - copy-memory - as byte-ptr! s/offset - as byte-ptr! state/buffer - slots << 4 - s/tail: s/offset + slots + either zero? slots [ + blk: block/make-at as red-block! dst 1 + ][ + blk: block/make-at as red-block! dst slots + s: GET_BUFFER(blk) + copy-memory + as byte-ptr! s/offset + as byte-ptr! state/buffer + slots << 4 + s/tail: s/offset + slots + ] ] depth: depth - 1 ] From 5d10323cffd3394289a15ebaaeafd079c5a86982 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 18:19:25 +0200 Subject: [PATCH 0222/3432] FIX: [R/S] byte! to integer! conversion not happening in some cases. Example: i: as-integer (p/1 - #"0") --- system/compiler.r | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index a4aec4c22c..bf645f05a7 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -3467,8 +3467,8 @@ system-dialect: make-profilable context [ if all [not variable boxed][last-type: boxed/type] ;-- enforces type casting on calling expression if all [ variable boxed ;-- process casting if result assigned to variable - find [logic! integer! float! float32! float64!] last-type/1 - find [logic! integer! float! float32! float64!] boxed/type ;-- fixes #967 + find [logic! byte! integer! float! float32! float64!] last-type/1 + find [logic! byte! integer! float! float32! float64!] boxed/type ;-- fixes #967 last-type/1 <> boxed/type ][ emitter/target/emit-casting boxed no ;-- insert runtime type casting if required From c7fa52ad92ec7d8eba3bf5c120ef2f466948b07e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 21:04:50 +0200 Subject: [PATCH 0223/3432] FEAT: merges S_BLANK state into S_START. --- docs/lexer/lexer-FSM.csv | 3 +- docs/lexer/lexer-FSM.xlsx | Bin 15864 -> 15425 bytes docs/lexer/lexer-states.txt | 4 +- runtime/lexer-transitions.reds | 88 ++++++++++----------- utils/generate-lexer-table.red | 139 ++++++++++++++++----------------- 5 files changed, 114 insertions(+), 120 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index ab6b676d6b..7d47ecb45c 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,6 +1,5 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_SIGN;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_BLANK;S_BLANK;S_BLANK;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_OP;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index dcdf7ca4ae8f841f58504243eefcb09f3e374d44..1d0fe689e2dd206e2bbc903669a5e8ca2238f7e1 100644 GIT binary patch literal 15425 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�A;Vz0~j+uO)N9sV(t&>te&GDsS7t@d&WLij@R8STO&eADSb0|^DWnFTu zQ|%d23T%nutBTFL>3=^c+Rl2iB<7! z&*7u62*w&tu(qbbDJsf_^~P!vpj8FEqP>M)4e0t-6^&9HE4=w5-I+ z=13o@mQC@~0rRT2Mu32jiq_q3v^RyIZEoAJ^wCJ541cVF@CRxBz88B(zD8m@u4h?q zyfNVmYz7C8&rtp?0z=amejlLRMuwgoGyE0-dnl`~Wa;SG>|MYz^AG+)v-KLQC0hdubEkUwNYU zvflIVI|u8wzU{%v%J3~#+rVAkxFbtT)MK?nifw%-gVP(fZPC^45Q5$iH~oXVLm?Os zPBsM{X>R=w2adPpp)C|7MYEv`5^CYz@D>Dwkg6$hHE1Yl6~Ne6FO=>baaN;}-!LuS3>C z^XLfzD``=vGiw7#a`F^DNCACYQ{)wNNOC!uH?RB--m}m@<3jgSl5wh_IZWzwUjDj8 zGirnq$iCTotIkHhA0#`#zpj|;pol@P1fM?3`6G9<$|Ez&xN~Y(K?jH%0p7IbOMWD6 z#1SR=IpSbFp9`MMJ#{>zmn>$-Ua+wsX#Q0S6?nY4VzNcl8L7A;uslunzC-W9s!Tv>q4)o6K zN2t53t9*>XFW@gRuzbac7aZ2}xyA-vQ{OKFR^~aqe6-8Ln1Zh?YnSSUxjyNDi4oOQgBFsFO#|!sq zCNFdJ5#CG;Qw82xd{!)MP_4rc;A_OHcobzbOTX6~gL9;M)B4t9OCySDeqI*9$oVwo zW4pI88hGSK-mapC)5i2te>&>wZI!F83tVoDps(mlD)`6L*@^X+oyK7C?#R&>@`Q&O z?@ogA1M?$dY&R><^@?(G6m#!sRB%haQL!H zdvv>ovchslELQY!(%p0|YQak9#;LHG0o{GqX4%*~yJGS(85jwL-GgD@1f%A6skR8~ zELti|bgWD?^gjS%^`?a=b^XG9Av8Xh3{)cFxr^ zsy*8#5);#`)O4q~<4n&0fhr~)?7IV1F1oX5JUa+rK0+5nIO*4w$ zkMYjY;SPLjkR3+Ehe&rR6>K%IM3k>*HzeA~oa}Cygu9&^#^AF#$g$Q+#!yN!Zm8Bf zMHklK6L#bYqs|@|3G;{$&F6|>iRcWm7IwSGEjn>0Ebm~I{(0^W1Iq%H`TxFq^^ev1 zi!t`a4dvU;xD`GejWJhUZX#U4nlVy{oZK*$Ihc)2mgI5$Dcz1 zfD)(@KYUS6P5x*Mv^%}~b z1^`Sy4g7gU<=3IVp1u7!w1f4xp}(HX{c7P?mHelLbdFzR@UNQrSA)Nb&OZ%ia{e^< zi{$)Q3HqziznAzwO+srL4*>9wg8%FAzvt<{4!?sY_Wun3J!>n=AwV$*0H8yE=%Fxf J7I=8|e*ghiI_dxb diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 32a4a0956c..058901a4a1 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -1,6 +1,5 @@ S_START -S_BLANK S_LINE_CMT S_LINE_STR S_SKIP_STR @@ -132,8 +131,7 @@ delimit14: # | ' | < | % | ^ hexa: C_ZERO | C_DIGIT | C_ALPHAX -S_START->ws->S_BLANK->ws->S_BLANK - \->not(ws)->S_START +S_START->ws->S_START S_START->";"->S_LINE_CMT->not(lf)->S_LINE_CMT \->lf->S_START diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 9d9e31e62f..a38c285bc3 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -3,7 +3,6 @@ Red/System [ ] #enum lex-states! [ S_START - S_BLANK S_LINE_CMT S_LINE_STR S_SKIP_STR @@ -74,48 +73,47 @@ Red/System [ T_EMAIL T_PATH ] transitions: #{ -010112122D2E2F30052C030B26262626260A2C1F26072C022C261C252C26262C -2B010112122D2D2F30052C030B26262626260A2C1F26072C022C261C252C2626 -2C2B020002020202020202020202020202020202020202020202020202020202 -022C2B0303030303030303030331030303030303030303030303030303030304 -03032C2C03030303030303030303030303030303030303030303030303030303 -0303032C2B050505050505050505320505050505050505050505050505050505 -050605052C2C0505050505050505050505050505050505050505050505050505 -05050505052C2B33330808333333333333080808330808080808080808083333 -0808080808082C33343408083434343434340808083408080808080808080834 -340808080908082C340808080808080808080808080808080808080808080808 -08080808080808082C2C35350A0A353535353535350A0A0A0A0A0A0A0A0A0A0A -0A35350A0A0A0A0A0A2C353A3A1111102C382C2C0C0E11112C11111111112C2C -112C3A3A1111111111112C3A0C0C0C0C2C2C2C2C2C362C2C2C2C2C2C0C2C2C2C -2C2C2C0D2C2C2C2C2C2C2C2C2C0D0C0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0D0D0D2C2B0E0E0E0E0E0E0E0E0E0E370E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0F0E0E2C2C0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E0E2C2C10101010103910101010101010101010 -1010101010101010101010101010102C2C3A3A11113A3A3A3A3A3A3A11111111 -11111111111111113A3A1111111111112C3A3C3C12123C3C3C3C3C3C3C0B1218 -1A142C172C3C2C3B2C3C29132C2C2C2C2C2C3C3D3D14143D3D3D3D3D3D3D1514 -2C1A142C3D2C3D2C3B2C3D2C2C2C2C2C2C2C2C3D3D3D14143D3D3D3D3D3D3D1A -2C3D2C142C3D2C3D2C3B2C2C2C162C2C2C2C2C2C3D3D3D3D3D3D3D3D3D3D3D3D -153D3D1515153D3D3D153D3D3D3D153D153D15152C2B3E3E16163E3E3E3E3E3E -3E2C2C3E2C2C2C3E2C3E2C2C2C2C2C162C2C2C2C2C2C2B3F3F17173F3F3F3F3F -3F3F17173F17171717173F173F173F3F173F173F17172C2B2C2C19192C2C2C2C -2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C41411919414141 -414141412C2C192C2C2C412C412C2C2C412C192C2C2C2C2C2C2B2C2C1B1B2C2C -2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C40401B1B40 -4040404040402C2C2C2C1B2C2C2C402C2C2C402C1B2C2C2C2C2C2C2B2C2C1D1D -2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C42421D -1D42424242424242421D2C2C2C2C422C422C2C2C422C1E2C2C2C2C2C2C2B4242 -1E1E42424242424242421E2C2C2C2C422C422C2C2C422C2C2C2C2C2C2C2C2B33 -3320203333333333333320203320202020202C33202033332020202020202C33 -202020202020202020202120202320202020202043202020202020202020202C -2C21212121212121212121202121212121212121212121212121212121222121 -2C2C212121212121212121212121212121212121212121212121212121212121 -212C2C2323232323232323232323232320232323232323232323232323232323 -23232C2C23232323232323232323232323232323232323232323232323232323 -2323232C2C26261212262626262626262C2C2626262626262C262C2626262626 -262C26262C3333332626333333333333332C2627262626463326262C2C332926 -1D262626262C33333328283333333333333328282828282828332C2828283328 -2828282828282C334444282844444444444444282C282828282844442C284444 -28282C282C28282C4445452929454545454545452C2C2C2929294545452C292C -452C292C292C29292C45 +000011112C2D2E2F042B020A2525252525092B1E25062B012B251B242B25252B +2A01000101010101010101010101010101010101010101010101010101010101 +2B2A020202020202020202023002020202020202020202020202020202020302 +022B2B0202020202020202020202020202020202020202020202020202020202 +02022B2A04040404040404040431040404040404040404040404040404040404 +0504042B2B040404040404040404040404040404040404040404040404040404 +040404042B2A3232070732323232323207070732070707070707070707323207 +07070707072B3233330707333333333333070707330707070707070707073333 +0707070807072B33070707070707070707070707070707070707070707070707 +070707070707072B2B3434090934343434343434090909090909090909090909 +34340909090909092B34393910100F2B372B2B0B0D10102B10101010102B2B10 +2B39391010101010102B390B0B0B0B2B2B2B2B2B352B2B2B2B2B2B0B2B2B2B2B +2B2B0C2B2B2B2B2B2B2B2B2B0C0B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C +0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D360D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0E0D0D2B2B0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0D0D0D0D2B2B0F0F0F0F0F380F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F2B2B39391010393939393939391010101010 +1010101010101039391010101010102B393B3B11113B3B3B3B3B3B3B0A111719 +132B162B3B2B3A2B3B28122B2B2B2B2B2B3B3C3C13133C3C3C3C3C3C3C14132B +19132B3C2B3C2B3A2B3C2B2B2B2B2B2B2B2B3C3C3C13133C3C3C3C3C3C3C192B +3C2B132B3C2B3C2B3A2B2B2B152B2B2B2B2B2B3C3C3C3C3C3C3C3C3C3C3C3C14 +3C3C1414143C3C3C143C3C3C3C143C143C14142B2A3D3D15153D3D3D3D3D3D3D +2B2B3D2B2B2B3D2B3D2B2B2B2B2B152B2B2B2B2B2B2A3E3E16163E3E3E3E3E3E +3E16163E16161616163E163E163E3E163E163E16162B2A2B2B18182B2B2B2B2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B4040181840404040 +4040402B2B182B2B2B402B402B2B2B402B182B2B2B2B2B2B2A2B2B1A1A2B2B2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3F3F1A1A3F3F +3F3F3F3F3F2B2B2B2B1A2B2B2B3F2B2B2B3F2B1A2B2B2B2B2B2B2A2B2B1C1C2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B41411C1C +41414141414141411C2B2B2B2B412B412B2B2B412B1D2B2B2B2B2B2B2A41411D +1D41414141414141411D2B2B2B2B412B412B2B2B412B2B2B2B2B2B2B2B2A3232 +1F1F323232323232321F1F321F1F1F1F1F2B321F1F32321F1F1F1F1F1F2B321F +1F1F1F1F1F1F1F1F1F201F1F221F1F1F1F1F1F421F1F1F1F1F1F1F1F1F1F2B2B +202020202020202020201F20202020202020202020202020202020202120202B +2B20202020202020202020202020202020202020202020202020202020202020 +2B2B222222222222222222222222221F22222222222222222222222222222222 +222B2B2222222222222222222222222222222222222222222222222222222222 +22222B2B25251111252525252525252B2B2525252525252B252B252525252525 +2B25252B3232322525323232323232322B2526252525453225252B2B3228251C +252525252B32323227273232323232323227272727272727322B272727322727 +27272727272B324343272743434343434343272B272727272743432B27434327 +272B272B27272B4344442828444444444444442B2B2B2828284444442B282B44 +2B282B282B28282B44 } diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 5c726443f6..8a5a940f42 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -13,76 +13,75 @@ Red [ context [ states: [ S_START ;-- 0 - S_BLANK ;-- 1 - S_LINE_CMT ;-- 2 - S_LINE_STR ;-- 3 - S_SKIP_STR ;-- 4 - S_M_STRING ;-- 5 - S_SKIP_MSTR ;-- 6 - S_FILE_1ST ;-- 7 - S_FILE ;-- 8 - S_SKIP_FILE ;-- 9 - S_SLASH ;-- 10 - S_SHARP ;-- 11 - S_BINARY ;-- 12 - S_LINE_CMT2 ;-- 13 - S_CHAR ;-- 14 - S_SKIP_CHAR ;-- 15 - S_CONSTRUCT ;-- 16 - S_ISSUE ;-- 17 - S_NUMBER ;-- 18 - S_DOTNUM ;-- 19 - S_DECIMAL ;-- 20 - S_DEC_SPECIAL ;-- 21 - S_TUPLE ;-- 22 - S_DATE ;-- 23 - S_TIME_1ST ;-- 24 - S_TIME ;-- 25 - S_PAIR_1ST ;-- 26 - S_PAIR ;-- 27 - S_MONEY_1ST ;-- 28 - S_MONEY ;-- 29 - S_MONEY_DEC ;-- 30 - S_LESSER ;-- 31 - S_TAG ;-- 32 - S_TAG_STR ;-- 33 - S_SKIP_STR2 ;-- 34 - S_TAG_STR2 ;-- 35 - S_SKIP_STR3 ;-- 36 - S_SIGN ;-- 37 - S_WORD ;-- 38 - S_WORDSET ;-- 39 - S_URL ;-- 40 - S_EMAIL ;-- 41 - --EXIT_STATES-- ;-- 42 - T_EOF ;-- 43 - T_ERROR ;-- 44 - T_BLK_OP ;-- 45 - T_BLK_CL ;-- 46 - T_PAR_OP ;-- 47 - T_PAR_CL ;-- 48 - T_STRING ;-- 49 - T_STR_ALT ;-- 50 - T_WORD ;-- 51 - T_FILE ;-- 52 - T_REFINE ;-- 53 - T_BINARY ;-- 54 - T_CHAR ;-- 55 - T_MAP_OP ;-- 56 - T_CONS_MK ;-- 57 - T_ISSUE ;-- 58 - T_PERCENT ;-- 59 - T_INTEGER ;-- 60 - T_FLOAT ;-- 61 - T_TUPLE ;-- 62 - T_DATE ;-- 63 - T_PAIR ;-- 64 - T_TIME ;-- 65 - T_MONEY ;-- 66 - T_TAG ;-- 67 - T_URL ;-- 68 - T_EMAIL ;-- 69 - T_PATH ;-- 70 + S_LINE_CMT ;-- 1 + S_LINE_STR ;-- 2 + S_SKIP_STR ;-- 3 + S_M_STRING ;-- 4 + S_SKIP_MSTR ;-- 5 + S_FILE_1ST ;-- 6 + S_FILE ;-- 7 + S_SKIP_FILE ;-- 8 + S_SLASH ;-- 9 + S_SHARP ;-- 10 + S_BINARY ;-- 11 + S_LINE_CMT2 ;-- 12 + S_CHAR ;-- 13 + S_SKIP_CHAR ;-- 14 + S_CONSTRUCT ;-- 15 + S_ISSUE ;-- 16 + S_NUMBER ;-- 17 + S_DOTNUM ;-- 18 + S_DECIMAL ;-- 19 + S_DEC_SPECIAL ;-- 20 + S_TUPLE ;-- 21 + S_DATE ;-- 22 + S_TIME_1ST ;-- 23 + S_TIME ;-- 24 + S_PAIR_1ST ;-- 25 + S_PAIR ;-- 26 + S_MONEY_1ST ;-- 27 + S_MONEY ;-- 28 + S_MONEY_DEC ;-- 29 + S_LESSER ;-- 30 + S_TAG ;-- 31 + S_TAG_STR ;-- 32 + S_SKIP_STR2 ;-- 33 + S_TAG_STR2 ;-- 34 + S_SKIP_STR3 ;-- 35 + S_SIGN ;-- 36 + S_WORD ;-- 37 + S_WORDSET ;-- 38 + S_URL ;-- 39 + S_EMAIL ;-- 40 + --EXIT_STATES-- ;-- 41 + T_EOF ;-- 42 + T_ERROR ;-- 43 + T_BLK_OP ;-- 44 + T_BLK_CL ;-- 45 + T_PAR_OP ;-- 46 + T_PAR_CL ;-- 47 + T_STRING ;-- 48 + T_STR_ALT ;-- 49 + T_WORD ;-- 50 + T_FILE ;-- 51 + T_REFINE ;-- 52 + T_BINARY ;-- 53 + T_CHAR ;-- 54 + T_MAP_OP ;-- 55 + T_CONS_MK ;-- 56 + T_ISSUE ;-- 57 + T_PERCENT ;-- 58 + T_INTEGER ;-- 59 + T_FLOAT ;-- 60 + T_TUPLE ;-- 61 + T_DATE ;-- 62 + T_PAIR ;-- 63 + T_TIME ;-- 64 + T_MONEY ;-- 65 + T_TAG ;-- 66 + T_URL ;-- 67 + T_EMAIL ;-- 68 + T_PATH ;-- 69 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 4eb594d49a028483dfae57e9ba476859be54b49b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 21:28:27 +0200 Subject: [PATCH 0224/3432] FEAT: supports scanning float! values. --- runtime/lexer.reds | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ec54926378..5afa8e1cb2 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -367,16 +367,16 @@ lexer: context [ ][ len: as-integer e - p if len > 10 [ - scan-float state s e flags ;-- overflow, fall back on float + scan-float state s e flags ;-- overflow, fall back on float exit ] i: 0 - either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path + either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path loop len [ i: 10 * i + as-integer (p/1 - #"0") p: p + 1 ] - ][ ;-- process with quote(s) + ][ ;-- process with quote(s) loop len [ if e/1 <> #"'" [i: 10 * i + as-integer (p/1 - #"0")] p: p + 1 @@ -391,11 +391,15 @@ lexer: context [ scan-float: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - cell [cell!] + fl [red-float!] + err [integer!] ][ - probe "float!" - cell: alloc-slot state - cell/header: TYPE_NONE + err: 0 + fl: as red-float! alloc-slot state + fl/header: TYPE_FLOAT + fl/value: red-dtoa/string-to-float s e :err + if err <> 0 [throw LEX_ERROR] + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-tuple: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 2d22bc230751ff2e280056d118879b1433a3e428 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 11 Oct 2019 22:19:33 +0200 Subject: [PATCH 0225/3432] FEAT: preliminary support for scanning strings. --- runtime/lexer.reds | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5afa8e1cb2..43dc3461a7 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -68,7 +68,7 @@ lexer: context [ ] skip-table: #{ - 0101010000000000000000000000000000000000000000000000000000000000 + 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 00000000000000 } @@ -285,9 +285,35 @@ lexer: context [ ] scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + str [red-string!] + ser [series!] + len [integer!] ][ - null + s: s + 1 ;-- skip start delimiter + len: as-integer e - s + + case [ + flags and C_FLAG_UCS4 <> 0 [ + + ] + flags and C_FLAG_UCS2 <> 0 [ + + ] + true [ ;-- UCS1 + str: string/make-at alloc-slot state len 1 + ser: GET_BUFFER(str) + + either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + copy-memory as byte-ptr! ser/offset as byte-ptr! s len + ser/tail: as cell! (as byte-ptr! ser/offset) + len + ][ ;-- with escape sequence(s) + 0 + ] + ] + ] + state/in-pos: e + 1 ;-- skip ending delimiter + state/in-len: state/in-len - 1 ] scan-string-multi: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -504,13 +530,12 @@ lexer: context [ term? [logic!] do-scan [scanner!] ][ - p: lex/in-pos line: 1 - until [ flags: 0 term?: no state: S_START + p: lex/in-pos start: p offset: 0 @@ -532,9 +557,11 @@ lexer: context [ ] lex/in-len: lex/in-len - as-integer (p - start) lex/in-pos: p + index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags + lex/in-len <= 1 ] From 0534fff251aa7f6aadbe1a6a8288eb0d6c6f1a04 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 10 Oct 2019 15:57:02 +0800 Subject: [PATCH 0226/3432] FIX: return make-event results --- modules/view/backends/gtk3/events.reds | 3 --- modules/view/backends/gtk3/handlers.reds | 19 +++++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 3fad003425..e1df4f3e46 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -664,7 +664,6 @@ connect-widget-events: function [ gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes - gtk_widget_is_focus widget gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -686,7 +685,6 @@ connect-widget-events: function [ gobj_signal_connect(widget "changed" :field-changed widget) gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes - gtk_widget_is_focus widget gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -704,7 +702,6 @@ connect-widget-events: function [ gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes - gtk_widget_is_focus widget gtk_widget_grab_focus widget connect-focus-events widget widget ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 9968d78ac1..1ed14410b6 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -509,7 +509,7 @@ key-press-event: func [ ][res: make-event widget key or flags EVT_KEY] ] ;; DEBUG: print ["key-press end" lf] - EVT_DISPATCH + res ] key-release-event: func [ @@ -631,7 +631,6 @@ widget-enter-notify-event: func [ flags: check-flags event/type event/state make-event widget flags EVT_OVER - 0;;no ] widget-leave-notify-event: func [ @@ -646,7 +645,6 @@ widget-leave-notify-event: func [ ;; DEBUG: print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] flags: check-flags event/type event/state make-event widget flags or EVT_FLAG_AWAY EVT_OVER - 0;;no ] mouse-button-release-event: func [ @@ -771,6 +769,7 @@ mouse-motion-notify-event: func [ widget [handle!] return: [integer!] /local + res [integer!] offset [red-pair!] x [float!] y [float!] @@ -778,7 +777,7 @@ mouse-motion-notify-event: func [ flags [integer!] ][ ;; DEBUG: print [ "mouse -> MOTION: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] - + res: EVT_DISPATCH evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y evt-motion/x_root: event/x_root @@ -786,10 +785,10 @@ mouse-motion-notify-event: func [ wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS if wflags and FACET_FLAGS_ALL_OVER <> 0 [ flags: check-flags event/type event/state - make-event widget flags EVT_OVER + res: make-event widget flags EVT_OVER ] ;; DEBUG: print ["mouse-motion-notify-event: down? " (event/state and GDK_BUTTON1_MASK <> 0) " " (flags and EVT_FLAG_DOWN <> 0) lf] - EVT_DISPATCH ;;no + res ] menu-item-activate: func [ @@ -811,13 +810,13 @@ widget-scroll-event: func [ widget [handle!] return: [integer!] /local - state [integer!] + res [integer!] ][ ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] - state: 0 + res: EVT_DISPATCH g_object_set_qdata widget red-event-id as handle! event if any[event/delta_y < -0.01 event/delta_y > 0.01][ - state: make-event widget check-down-flags event/state EVT_WHEEL + res: make-event widget check-down-flags event/state EVT_WHEEL ] - state + res ] From 84c9ed38e09160fc5d41d8bb9036022a37198c2b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 10 Oct 2019 16:13:37 +0800 Subject: [PATCH 0227/3432] FIX: use right font size to set gtk_entry_set_width_chars --- modules/view/backends/gtk3/gui.reds | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 49a4730acc..0ad7549521 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1512,6 +1512,20 @@ init-text-list: func [ ] ] +font-size?: func [ + font [red-object!] + return: [integer!] + /local + values [red-value!] + size [red-integer!] +][ + if TYPE_OF(font) <> TYPE_OBJECT [return default-font-size] + values: object/get-values font + size: as red-integer! values + FONT_OBJ_SIZE + if TYPE_OF(size) <> TYPE_INTEGER [return default-font-size] + size/value +] + update-scroller: func [ scroller [red-object!] flag [integer!] @@ -1845,7 +1859,7 @@ OS-make-view: func [ widget: gtk_entry_new buffer: gtk_entry_get_buffer widget unless null? caption [gtk_entry_buffer_set_text buffer caption -1] - gtk_entry_set_width_chars widget size/x / 10 + gtk_entry_set_width_chars widget size/x / font-size? font set-hint-text widget as red-block! values + FACE_OBJ_OPTIONS if bits and FACET_FLAGS_PASSWORD <> 0 [gtk_entry_set_visibility widget no] ] @@ -1901,7 +1915,11 @@ OS-make-view: func [ widget: either sym = drop-list [gtk_combo_box_text_new][gtk_combo_box_text_new_with_entry] init-combo-box widget data caption sym = drop-list ;; TODO: improve it but better than nothing from now otherwise it is uggly! - if sym = drop-down[gtk_entry_set_width_chars gtk_bin_get_child widget (size/x - 20) / 10 ] ; 10 here the size of the font... TODO: to improve later! + if sym = drop-down [ + value: size/x / (font-size? font) + if value > 2 [value - 2] + gtk_entry_set_width_chars gtk_bin_get_child widget value + ] gtk_combo_box_set_active widget 0 ] true [ From a82cd9c2d50f3cb3a999d791ccad3a8f7f5b5c1b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 11 Oct 2019 16:48:52 +0800 Subject: [PATCH 0228/3432] FEAT: use pango attribute to set text attrs --- modules/view/backends/gtk3/draw.reds | 11 +- modules/view/backends/gtk3/font.reds | 37 -- modules/view/backends/gtk3/gtk.reds | 59 ++- modules/view/backends/gtk3/text-box.reds | 599 ++++++----------------- runtime/definitions.reds | 4 +- 5 files changed, 170 insertions(+), 540 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index c7cbd48a8d..fdb6e4402d 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -513,17 +513,10 @@ draw-text-box-lines: func [ dc/font-color ] - lc: either TYPE_OF(tbox) = TYPE_OBJECT [ - ;; DEBUG: print ["draw-text-box-lines: " as int-ptr! dc lf] ;-- text-box! - as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes - ][ - null - ] + if TYPE_OF(tbox) <> TYPE_OBJECT [exit] + lc: as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes unless null? lc/layout [ - - pango-layout-set-text lc size - set-source-color ctx clr ;; DEBUG: print ["set-source-color: " ctx " " clr lf] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 72280249da..e9fa90a048 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -739,43 +739,6 @@ pango-cairo-set-text: func [ ] ] -;; A rewrite of pango_layout_set_markup but in red/system to control warning messages -;; with option force to avoid the warning when considering -pango-layout-set-markup: func [ - layout [handle!] - mtext [c-string!] - len [integer!] - force [logic!] - /local - status [logic!] - attrs-ptr [int-ptr!] - attrs [handle!] - ptext-ptr [int-ptr!] - ptext [c-string!] - accel [integer!] - error [handle!] -][ - unless null? layout [ - attrs-ptr: declare int-ptr! - ptext-ptr: declare int-ptr! - ;; DEBUG: print ["pango-layout-set-markup mtext: " mtext lf] - status: pango_parse_markup mtext len 0 attrs-ptr ptext-ptr null null - attrs: as handle! attrs-ptr/value - ptext: as c-string! ptext-ptr/value - ;; DEBUG: print ["pango-layout-set-markup ptext: " ptext lf] - either any[status force] [ - pango_layout_set_text layout ptext -1 - unless null? attrs [ - pango_layout_set_attributes layout attrs - pango_attr_list_unref attrs - ] - g_free as handle! ptext - ][ - pango_layout_set_text layout mtext -1 - ] - ] -] - pango-layout-context-set-text: func [ layout [handle!] dc [draw-ctx!] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index b9bc7e5f16..4599ac4c2e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2703,8 +2703,8 @@ GPtrArray!: alias struct! [ ] pango_attribute_equal: "pango_attribute_equal" [ - attr [handle!] - attr2 [handle!] + attr [handle!] + attr2 [handle!] return: [logic!] ] pango_attribute_destroy: "pango_attribute_destroy" [ @@ -2713,48 +2713,48 @@ GPtrArray!: alias struct! [ ;; font description attributes pango_attr_family_new: "pango_attr_family_new" [ name [c-string!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_style_new: "pango_attr_style_new" [ style [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_variant_new: "pango_attr_variant_new" [ variant [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_stretch_new: "pango_attr_stretch_new" [ stretch [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_weight_new: "pango_attr_weight_new" [ weight [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_size_new: "pango_attr_size_new" [ size [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_size_new_absolute: "pango_attr_size_new_absolute" [ size [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_font_desc_new: "pango_attr_font_desc_new" [ font-desc [handle!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] ;; Color attributes pango_attr_foreground_new: "pango_attr_foreground_new" [ r [integer!] g [integer!] b [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_background_new: "pango_attr_background_new" [ r [integer!] g [integer!] b [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] ;; styles attributes pango_attr_strikethrough_new: "pango_attr_strikethrough_new" [ @@ -2765,67 +2765,66 @@ GPtrArray!: alias struct! [ r [integer!] g [integer!] b [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_underline_new: "pango_attr_underline_new" [ ok [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_underline_color_new: "pango_attr_underline_color_new" [ r [integer!] g [integer!] b [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_shape_new: "pango_attr_shape_new" [ - ink-rect [handle!] - logical-rect [handle!] - return: [PangoAttribute!] + ink-rect [handle!] + logic-rect [handle!] + return: [PangoAttribute!] ] ;; size attributes pango_attr_scale_new: "pango_attr_scale_new" [ scale [float!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_rise_new: "pango_attr_rise_new" [ rise [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_letter_spacing_new: "pango_attr_letter_spacing_new" [ spacing [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_gravity_new: "pango_attr_gravity_new" [ gravity [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_gravity_hint_new: "pango_attr_gravity_hint_new" [ hint [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_font_features_new: "pango_attr_font_features_new" [ features [c-string!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_foreground_alpha_new: "pango_attr_foreground_alpha_new" [ alpha [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] pango_attr_background_alpha_new: "pango_attr_background_alpha_new" [ alpha [integer!] - return: [PangoAttribute!] + return: [PangoAttribute!] ] - cairo_font_options_create: "cairo_font_options_create" [ - return: [handle!] + return: [handle!] ] cairo_font_options_destroy: "cairo_font_options_destroy" [ - fontopts [handle!] + fontopts [handle!] ] cairo_font_options_set_antialias: "cairo_font_options_set_antialias" [ cfo [handle!] - antialias [cairo_antialias_t!] + antialias [cairo_antialias_t!] ] ] ] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 91f833f191..69caf6290d 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -23,476 +23,172 @@ Red/System [ max-line-cnt: 0 -pango-opt-tag!: alias struct! [ - opt [c-string!] - pos [integer!] - len [integer!] -] - -pango-compare-tag: func [ - [cdecl] - tag1 [pango-opt-tag!] - tag2 [pango-opt-tag!] - return: [integer!] - /local - comp [integer!] -][ - ;; DEBUG: print ["pango-compare-tag: (" tag1/pos "," tag1/len "," tag1/opt ") and (" tag2/pos "," tag2/len "," tag2/opt ") -> " ] - either tag1/pos = tag2/pos [ - either tag1/len = tag2/len [comp: 0][ - comp: either tag1/len > tag2/len [-1][1] - ] - ][ - comp: either tag1/pos > tag2/pos [1][-1] - ] - comp -] - -make-pango-opt-tag: func [ - opt [c-string!] - pos [integer!] - len [integer!] - return: [handle!] - /local - tag [pango-opt-tag!] -][ - tag: as pango-opt-tag! allocate size? pango-opt-tag! - tag/opt: opt tag/pos: pos tag/len: len - as handle! tag -] - -pango-insert-tag: func [ - lc [layout-ctx!] - opt [c-string!] - pos [integer!] - len [integer!] - /local - tag [handle!] - tag2 [handle!] -][ - if pos + len > lc/text-len [len: lc/text-len - pos] - tag: make-pango-opt-tag opt pos len - ;; DEBUG: print ["insert tag: " tag lf ]; " at (" tag/pos "," tag/len ")" lf ] - lc/tag-list: g_list_insert_sorted lc/tag-list tag as-integer :pango-compare-tag -] - -pango-append-open-tag: func [ - gstr [GString!] - ot [c-string!] -][ - g_string_append gstr "" - g_free as handle! ot -] - -layout-preamble?: func [ - gstr [GString!] - fd [handle!] - /local - ot [c-string!] -][ - g_string_assign gstr "" - - ot: pango-open-tag-string? "face" pango_font_description_get_family fd - pango-append-open-tag gstr ot - - ot: pango-open-tag-int? "size" pango_font_description_get_size fd - pango-append-open-tag gstr ot -] - -layout-postamble?: func [ - gstr [GString!] -][ - g_string_append gstr "" - g_string_append gstr "" - ;; DEBUG: print ["text: " lc/text lf] - ;; DEBUG: print ["text-markup: " text/str lf] -] layout-ctx-init: func [ lc [layout-ctx!] text [c-string!] text-len [integer!] - /local - gstr [GString!] ][ - lc/closed-tags: null lc/text: text lc/text-len: text-len lc/text-pos: 0 - lc/text-markup: as handle! g_string_sized_new PANGO_TEXT_MARKUP_SIZED - lc/tag-list: null - gstr: as GString! lc/text-markup - g_string_assign gstr "" + lc/attr-list: pango_attr_list_new ] -pango-add-open-tag: func [ - lc [layout-ctx!] - open-tag [c-string!] +OS-text-box-color: func [ + dc [handle!] + layout [handle!] pos [integer!] - /local - gstr [GString!] -][ - gstr: as GString! lc/text-markup - if lc/text-pos < pos [ ; add text until pos - g-string-append-len gstr lc/text + lc/text-pos pos - lc/text-pos - lc/text-pos: pos - ] - pango-append-open-tag gstr open-tag - ; g_string_append gstr "" - ; g_free as handle! open-tag -] - -pango-open-tag-string?: func [ - attr-key [c-string!] - attr-val [c-string!] - return: [c-string!] - /local - str [c-string!] -][ - str: "" - str: g_strdup_printf ["%s='%s'" attr-key attr-val] - str -] - -pango-open-tag-int?: func [ - attr-key [c-string!] - attr-val [integer!] - return: [c-string!] - /local - str [c-string!] -][ - str: "" - str: g_strdup_printf ["%s='%d'" attr-key attr-val] - str -] - -pango-open-tag-float?: func [ - attr-key [c-string!] - attr-val [float!] - return: [c-string!] - /local - str [c-string!] -][ - str: "" - str: g_strdup_printf ["%s='%f'" attr-key attr-val] - str -] - -pango-add-closed-tag: func [ - lc [layout-ctx!] - level [integer!] -][ - ;; DEBUG: print ["add-closed-tag: " level lf] - lc/closed-tags: g_list_prepend lc/closed-tags as int-ptr! (level + 1) -] - -pango-last-closed-tag?: func [ ; last in time not in the GList - lc [layout-ctx!] - return: [integer!] - /local - current [int-ptr!] -][ - current: g_list_nth_data lc/closed-tags 0 - either null? current [-1][(as integer! current) - 1] -] - -pango-next-closed-tag: func [ - lc [layout-ctx!] - /local - first [handle!] -][ - first: g_list_first lc/closed-tags - lc/closed-tags: g_list_delete_link lc/closed-tags first -] - -pango-close-tags: func [ - lc [layout-ctx!] - pos-last-closed-tag [integer!] - /local - text-len [integer!] - gstr [GString!] - last? [logic!] -][ - ;; DEBUG: print ["pango-close-tags: " lc " text-markup: " lc/text-markup lf] - last?: no - gstr: as GString! lc/text-markup - if pos-last-closed-tag = -1 [ - last?: yes - ;; DEBUG: print ["pos-last-closed-tag = -1" lf] - pos-last-closed-tag: pango-last-closed-tag? lc - ] - text-len: either pos-last-closed-tag > lc/text-len [lc/text-len][pos-last-closed-tag] - text-len: text-len - lc/text-pos - ;; DEBUG: print ["pango-close-tags -> append: (" text-len ")" lc/text + lc/text-pos lf] - if text-len > 0 [ - g-string-append-len gstr lc/text + lc/text-pos text-len - lc/text-pos: lc/text-pos + text-len - ] - if 0 < g_list_length lc/closed-tags [ - ; Add closed tags - ;; DEBUG: print ["close-tags: " pos-last-closed-tag " " pango-last-closed-tag? lc lf] - while [ pos-last-closed-tag = pango-last-closed-tag? lc ][ - ;; DEBUG: print ["close-tags: " lf] - g_string_append gstr "" - ;; DEBUG: print ["text-markup after close-tag: " gstr/str lf] - pango-next-closed-tag lc - - ] - ] - ;; DEBUG: print ["size? lc/closed-tags: " g_list_length lc/closed-tags " last?: " last? lf] - if last? [ - either 0 < g_list_length lc/closed-tags [ - pango-close-tags lc -1 - ][ - text-len: lc/text-len - lc/text-pos - ;; DEBUG: print ["pango-close-tags -> last append: (" text-len ")" lc/text + lc/text-pos lf] - if text-len > 0 [ - g-string-append-len gstr lc/text + lc/text-pos text-len - lc/text-pos: lc/text-pos + text-len - ] - ] - ] -] - -pango-process-closed-tags: func [ - lc [layout-ctx!] - pos [integer!] - len [integer!] - /local - text [c-string!] - tmp [c-string!] - pos-current-closed-tag [integer!] - pos-last-closed-tag [integer!] -][ - pos-last-closed-tag: pango-last-closed-tag? lc - pos-current-closed-tag: pos + len - ;; DEBUG: print ["process closed tags: current=" pos-current-closed-tag " last=" pos-last-closed-tag lf] - ; Close tags with text first if any - if all[ - pos-last-closed-tag <> -1 - pos-current-closed-tag > pos-last-closed-tag - ][ - pango-close-tags lc pos-last-closed-tag - ] -] - -pango-process-tag: func [ - lc [layout-ctx!] - open-tag [c-string!] - pos [integer!] - len [integer!] -][ - pango-process-closed-tags lc pos len - pango-add-open-tag lc open-tag pos - pango-add-closed-tag lc pos + len -] - -layout-ctx-do: func [ - lc [layout-ctx!] - fd [handle!] - /local - gl [GList!] - last [GList!] - tag [pango-opt-tag!] - len [integer!] - pos [integer!] - opt [c-string!] - gstr [GString!] -][ - gstr: as GString! lc/text-markup - ;; DEBUG: print ["layout-ctx-do layout: " lc/layout " " pango_font_description_get_family fd " " pango_font_description_get_size fd lf] - layout-preamble? gstr fd - either null? lc/tag-list [ - g_string_append gstr g_markup_escape_text lc/text lc/text-len - ][ - last: as GList! g_list_last lc/tag-list - gl: as GList! g_list_first lc/tag-list - - lc/text-pos: 0 lc/closed-tags: null - until [ - tag: as pango-opt-tag! gl/data - ;; DEBUG: print [" at (" tag/pos "," tag/len ")" lf] - pango-process-tag lc tag/opt tag/pos tag/len - - gl: gl/next - null? gl - ] - pango-close-tags lc -1 - ] - layout-postamble? gstr -] - -int-to-rgba: func [ - color [integer!] - r [int-ptr!] - b [int-ptr!] - g [int-ptr!] - a [int-ptr!] -][ - ;; TODO: - r/value: (color >> 24 and FFh) << 8 - g/value: (color >> 16 and FFh) << 8 - b/value: (color >> 8 and FFh) << 8 - a/value: (color and FFh) << 8 - ;; DEBUG: print ["color: " color " " r/value "." g/value "." b/value "." a/value lf ] -] - -int-to-bgra-hex: func [ + len [integer!] color [integer!] - return: [c-string!] - /local - r [integer!] - b [integer!] - g [integer!] - a [integer!] -][ - a: (color >> 24 and FFh) - r: (color >> 16 and FFh) - g: (color >> 8 and FFh) - b: (color and FFh) - color: (b << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( r << 8 and FF00h) or ( a and FFh) - ;; DEBUG: print ["col(#" string/to-hex color no ")" lf] - g_strdup_printf ["#%s" string/to-hex color no] -] - -OS-text-box-color: func [ - dc [handle!] - layout [handle!] - pos [integer!] - len [integer!] - color [integer!] /local lc [layout-ctx!] - rgba [c-string!] - ot [c-string!] + a [integer!] + r [integer!] + g [integer!] + b [integer!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout + a: color >> 24 and FFh + r: color >> 16 and FFh + g: color >> 8 and FFh + b: color and FFh + attr: pango_attr_foreground_new r g b + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr - rgba: int-to-bgra-hex color - ;; DEBUG: print ["col(" rgba ")[" pos "," pos + len - 1 "]" lf] - - ot: pango-open-tag-string? "color" rgba - pango-insert-tag lc ot pos len + attr: pango_attr_foreground_alpha_new a + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-background: func [ - dc [handle!] - layout [handle!] - pos [integer!] - len [integer!] - color [integer!] + dc [handle!] + layout [handle!] + pos [integer!] + len [integer!] + color [integer!] /local lc [layout-ctx!] - rgba [c-string!] - ot [c-string!] + a [integer!] + r [integer!] + g [integer!] + b [integer!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout + a: color >> 24 and FFh + r: color >> 16 and FFh + g: color >> 8 and FFh + b: color and FFh + attr: pango_attr_background_new r g b + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr - rgba: int-to-bgra-hex color - ;; DEBUG: print ["bgcol(" rgba ")[" pos "," pos + len - 1 "]" lf] - - ot: pango-open-tag-string? "bgcolor" rgba - pango-insert-tag lc ot pos len - + attr: pango_attr_background_alpha_new a + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] - - OS-text-box-weight: func [ - layout [handle!] - pos [integer!] - len [integer!] - weight [integer!] + layout [handle!] + pos [integer!] + len [integer!] + weight [integer!] /local lc [layout-ctx!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - - ot: pango-open-tag-int? "weight" weight pos len - pango-insert-tag lc ot pos len - + attr: pango_attr_weight_new weight + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-italic: func [ - layout [handle!] - pos [integer!] - len [integer!] + layout [handle!] + pos [integer!] + len [integer!] /local lc [layout-ctx!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - - ot: pango-open-tag-string? "style" "italic" - pango-insert-tag lc ot pos len + attr: pango_attr_style_new PANGO_STYLE_ITALIC + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-underline: func [ - layout [handle!] - pos [integer!] - len [integer!] - opts [red-value!] ;-- options - tail [red-value!] + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] ;-- options + tail [red-value!] /local lc [layout-ctx!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - - ot: pango-open-tag-string? "underline" "single" - pango-insert-tag lc ot pos len + attr: pango_attr_underline_new PANGO_UNDERLINE_SINGLE + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-strikeout: func [ - layout [handle!] - pos [integer!] - len [integer!] - opts [red-value!] + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] /local lc [layout-ctx!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - - ot: pango-open-tag-string? "strikethrough" "true" - pango-insert-tag lc ot pos len + attr: pango_attr_strikethrough_new true + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-border: func [ - layout [handle!] - pos [integer!] - len [integer!] - opts [red-value!] ;-- options - tail [red-value!] - /local - lc [layout-ctx!] + layout [handle!] + pos [integer!] + len [integer!] + opts [red-value!] ;-- options + tail [red-value!] ][ - lc: as layout-ctx! layout + 0 ] OS-text-box-font-name: func [ - dc [handle!] - layout [handle!] - pos [integer!] - len [integer!] - name [red-string!] + dc [handle!] + layout [handle!] + pos [integer!] + len [integer!] + name [red-string!] /local lc [layout-ctx!] - strlen [integer!] + len2 [integer!] str [c-string!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - strlen: -1 - str: unicode/to-utf8 name :strlen - ot: pango-open-tag-string? "face" str - pango-insert-tag lc ot pos len + len2: -1 + str: unicode/to-utf8 name :len2 + attr: pango_attr_family_new str + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-font-size: func [ @@ -503,19 +199,20 @@ OS-text-box-font-size: func [ size [float!] /local lc [layout-ctx!] - ot [c-string!] + attr [PangoAttribute!] ][ lc: as layout-ctx! layout - - ot: pango-open-tag-int? "font" as integer! size - pango-insert-tag lc ot pos len + attr: pango_attr_size_new as integer! size + attr/start: pos + attr/end: pos + len + pango_attr_list_insert lc/attr-list attr ] OS-text-box-metrics: func [ - state [red-block!] - arg0 [red-value!] - type [integer!] - return: [red-value!] + state [red-block!] + arg0 [red-value!] + type [integer!] + return: [red-value!] /local int [red-integer!] rstate [red-integer!] @@ -588,11 +285,11 @@ OS-text-box-metrics: func [ ] OS-text-box-layout: func [ - box [red-object!] - target [int-ptr!] - ft-clr [integer!] - catch? [logic!] - return: [handle!] + box [red-object!] + target [int-ptr!] + ft-clr [integer!] + catch? [logic!] + return: [handle!] /local hWnd [handle!] values [red-value!] @@ -606,11 +303,11 @@ OS-text-box-layout: func [ obj [red-object!] w [integer!] h [integer!] - dc [draw-ctx!] - lc [layout-ctx!] - cached? [logic!] + dc [draw-ctx!] + lc [layout-ctx!] + cached? [logic!] force? [logic!] - font [red-object!] + font [red-object!] hFont [handle!] clr [integer!] text [red-string!] @@ -646,7 +343,7 @@ OS-text-box-layout: func [ len: -1 str: unicode/to-utf8 text :len - layout-ctx-init lc str length? str + layout-ctx-init lc str len ;; DEBUG: print ["OS-text-box-layout lc/text: " lc/text " " lc/text-len lf] @@ -662,7 +359,6 @@ OS-text-box-layout: func [ if null? pango-context [pango-context: gdk_pango_context_get] lc/layout: pango_layout_new pango-context ;; DEBUG: print ["rich-text layout: " lc/layout " " pango_font_description_get_family hFont " " pango_font_description_get_size hFont lf] - pango_layout_set_font_description lc/layout hFont ] ][ dc: as draw-ctx! target @@ -686,57 +382,38 @@ OS-text-box-layout: func [ lc/layout: as handle! rstate/value ;; DEBUG: print ["lc/layout cached: " lc/layout lf] ] + pango_layout_set_font_description lc/layout hFont styles: as red-block! values + FACE_OBJ_DATA - either all [ + if all [ TYPE_OF(styles) = TYPE_BLOCK 1 < block/rs-length? styles ][ parse-text-styles target as handle! lc styles 7FFFFFFFh catch? - ][ - g_string_assign as GString! lc/text-markup lc/text - ] - pango_layout_set_font_description lc/layout hFont - layout-ctx-do lc hFont - if null? target [ - pango-layout-set-text lc size ] + pango-layout-set-text lc size as handle! lc ] -pango-layout-set-text: func [ - lc [layout-ctx!] - size [red-pair!] - /local - gstr [GString!] +pango-layout-apply-attr: func [ + lc [layout-ctx!] ][ - gstr: as GString! lc/text-markup - ;; DEBUG: print ["pango-layout-set-text:<<-" gstr/str "->>" lf] - ;;pango_layout_set_markup lc/layout gstr/str -1 - pango-layout-set-markup lc/layout gstr/str -1 false - pango_layout_set_width lc/layout PANGO_SCALE * size/x - pango_layout_set_height lc/layout PANGO_SCALE * size/y - pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR + pango_layout_set_text lc/layout lc/text -1 + unless null? lc/attr-list [ + pango_layout_set_attributes lc/layout lc/attr-list + pango_attr_list_unref lc/attr-list + lc/attr-list: null + ] ] -g-markup-escape-text-len: func [ - text [c-string!] - text-len [integer!] - return: [c-string!] - /local - gstr [GString!] +pango-layout-set-text: func [ + lc [layout-ctx!] + size [red-pair!] ][ - gstr: g_string_new_len text text-len - g_markup_escape_text g_string_free gstr false text-len + unless null? lc [ + pango-layout-apply-attr lc + pango_layout_set_width lc/layout PANGO_SCALE * size/x + pango_layout_set_height lc/layout PANGO_SCALE * size/y + pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR + ] ] - -g-string-append-len: func [ - gstr [GString!] - text [c-string!] - text-len [integer!] - /local - str [c-string!] -][ - str: g-markup-escape-text-len text text-len - g_string_append gstr str -] \ No newline at end of file diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 16932e5a40..1b08eadac1 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -103,9 +103,7 @@ Red/System [ text [c-string!] text-len [integer!] text-pos [integer!] - text-markup [handle!] - closed-tags [handle!] - tag-list [handle!] + attr-list [handle!] ] ] From 5628b135d12303e7d035d693bc645db7b299b0af Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 11 Oct 2019 18:12:53 +0800 Subject: [PATCH 0229/3432] FEAT: implement utf8-next-char --- runtime/unicode.reds | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/runtime/unicode.reds b/runtime/unicode.reds index aa70cb190f..c10f7fa771 100644 --- a/runtime/unicode.reds +++ b/runtime/unicode.reds @@ -43,6 +43,27 @@ unicode: context [ 0448h 0449h 044Ah 044Bh 044Ch 044Dh 044Eh 044Fh ] + utf8-skip-data: [ + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 6 6 1 1 + ] + + utf8-next-char: func [ + p [c-string!] + return: [c-string!] + /local + t [integer!] + ][ + t: as integer! p/1 + p + utf8-skip-data/t + ] + utf8-char-size?: func [ byte-1st [integer!] return: [integer!] From be0e8ccb2a42857e013638cfd9b1316003eef592 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 11 Oct 2019 18:32:08 +0800 Subject: [PATCH 0230/3432] FIX: pango-attr need bytes position instead of utf8 --- modules/view/backends/gtk3/text-box.reds | 86 ++++++++++++++++++------ 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 69caf6290d..c7ab3ff568 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -35,6 +35,20 @@ layout-ctx-init: func [ lc/attr-list: pango_attr_list_new ] +utf8-to-bytes: func [ + text [c-string!] + len [integer!] + return: [integer!] + /local + end [c-string!] +][ + end: text + loop len [ + end: unicode/utf8-next-char end + ] + as integer! end - text +] + OS-text-box-color: func [ dc [handle!] layout [handle!] @@ -43,6 +57,8 @@ OS-text-box-color: func [ color [integer!] /local lc [layout-ctx!] + s [integer!] + e [integer!] a [integer!] r [integer!] g [integer!] @@ -50,18 +66,20 @@ OS-text-box-color: func [ attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len a: color >> 24 and FFh r: color >> 16 and FFh g: color >> 8 and FFh b: color and FFh attr: pango_attr_foreground_new r g b - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr attr: pango_attr_foreground_alpha_new a - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -73,6 +91,8 @@ OS-text-box-background: func [ color [integer!] /local lc [layout-ctx!] + s [integer!] + e [integer!] a [integer!] r [integer!] g [integer!] @@ -80,18 +100,20 @@ OS-text-box-background: func [ attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len a: color >> 24 and FFh r: color >> 16 and FFh g: color >> 8 and FFh b: color and FFh attr: pango_attr_background_new r g b - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr attr: pango_attr_background_alpha_new a - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -102,12 +124,16 @@ OS-text-box-weight: func [ weight [integer!] /local lc [layout-ctx!] + s [integer!] + e [integer!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len attr: pango_attr_weight_new weight - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -117,12 +143,16 @@ OS-text-box-italic: func [ len [integer!] /local lc [layout-ctx!] + s [integer!] + e [integer!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len attr: pango_attr_style_new PANGO_STYLE_ITALIC - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -134,12 +164,16 @@ OS-text-box-underline: func [ tail [red-value!] /local lc [layout-ctx!] + s [integer!] + e [integer!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len attr: pango_attr_underline_new PANGO_UNDERLINE_SINGLE - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -150,12 +184,16 @@ OS-text-box-strikeout: func [ opts [red-value!] /local lc [layout-ctx!] + s [integer!] + e [integer!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len attr: pango_attr_strikethrough_new true - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -177,17 +215,21 @@ OS-text-box-font-name: func [ name [red-string!] /local lc [layout-ctx!] + s [integer!] + e [integer!] len2 [integer!] str [c-string!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len len2: -1 str: unicode/to-utf8 name :len2 attr: pango_attr_family_new str - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] @@ -199,12 +241,16 @@ OS-text-box-font-size: func [ size [float!] /local lc [layout-ctx!] + s [integer!] + e [integer!] attr [PangoAttribute!] ][ lc: as layout-ctx! layout + s: utf8-to-bytes lc/text pos + e: utf8-to-bytes lc/text + s len attr: pango_attr_size_new as integer! size - attr/start: pos - attr/end: pos + len + attr/start: s + attr/end: e pango_attr_list_insert lc/attr-list attr ] From 7be2852038b8543ac379308d117920ee5c55c520 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 12 Oct 2019 14:45:13 +0800 Subject: [PATCH 0231/3432] FIX: pango attr index error --- modules/view/backends/gtk3/text-box.reds | 53 +++++++++++++++--------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index c7ab3ff568..3f5e68efc9 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -49,6 +49,25 @@ utf8-to-bytes: func [ as integer! end - text ] +color-u8-to-u16: func [ + color [integer!] + r [int-ptr!] + g [int-ptr!] + b [int-ptr!] + a [int-ptr!] + /local + t [integer!] +][ + t: color >> 24 and FFh + a/value: t << 8 + t + t: color >> 16 and FFh + b/value: t << 8 + t + t: color >> 8 and FFh + g/value: t << 8 + t + t: color and FFh + r/value: t << 8 + t +] + OS-text-box-color: func [ dc [handle!] layout [handle!] @@ -68,18 +87,16 @@ OS-text-box-color: func [ lc: as layout-ctx! layout s: utf8-to-bytes lc/text pos e: utf8-to-bytes lc/text + s len - a: color >> 24 and FFh - r: color >> 16 and FFh - g: color >> 8 and FFh - b: color and FFh + r: 0 g: 0 b: 0 a: 0 + color-u8-to-u16 color :r :g :b :a attr: pango_attr_foreground_new r g b attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr attr: pango_attr_foreground_alpha_new a attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -102,18 +119,16 @@ OS-text-box-background: func [ lc: as layout-ctx! layout s: utf8-to-bytes lc/text pos e: utf8-to-bytes lc/text + s len - a: color >> 24 and FFh - r: color >> 16 and FFh - g: color >> 8 and FFh - b: color and FFh + r: 0 g: 0 b: 0 a: 0 + color-u8-to-u16 color :r :g :b :a attr: pango_attr_background_new r g b attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr attr: pango_attr_background_alpha_new a attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -133,7 +148,7 @@ OS-text-box-weight: func [ e: utf8-to-bytes lc/text + s len attr: pango_attr_weight_new weight attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -152,7 +167,7 @@ OS-text-box-italic: func [ e: utf8-to-bytes lc/text + s len attr: pango_attr_style_new PANGO_STYLE_ITALIC attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -173,7 +188,7 @@ OS-text-box-underline: func [ e: utf8-to-bytes lc/text + s len attr: pango_attr_underline_new PANGO_UNDERLINE_SINGLE attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -193,7 +208,7 @@ OS-text-box-strikeout: func [ e: utf8-to-bytes lc/text + s len attr: pango_attr_strikethrough_new true attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -229,7 +244,7 @@ OS-text-box-font-name: func [ str: unicode/to-utf8 name :len2 attr: pango_attr_family_new str attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] @@ -248,9 +263,9 @@ OS-text-box-font-size: func [ lc: as layout-ctx! layout s: utf8-to-bytes lc/text pos e: utf8-to-bytes lc/text + s len - attr: pango_attr_size_new as integer! size + attr: pango_attr_size_new PANGO_SCALE * as integer! size attr/start: s - attr/end: e + attr/end: s + e pango_attr_list_insert lc/attr-list attr ] From 4d62785a625a0f25830de5c4e3f7f2fc550029ea Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 12 Oct 2019 12:33:41 +0200 Subject: [PATCH 0232/3432] FEAT: adds lines counting to lexical scanner. --- runtime/lexer.reds | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 43dc3461a7..1f36a95d3b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -67,6 +67,10 @@ lexer: context [ C_EOF ;-- 32 ] + line-table: #{ + 000100000000000000000000000000000000000000000000000000000000000000 + } + skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -543,11 +547,16 @@ lexer: context [ cp: 1 + as-integer p/value class: lex-classes/cp flags: class and FFFFFF00h or flags + index: state * 33 + (class and FFh) + 1 state: as-integer transitions/index + index: state + 1 offset: offset + as-integer skip-table/index - ;line: line + line-table/class + + index: class and FFh + 1 + line: line + line-table/index + if state > --EXIT_STATES-- [term?: yes break] p: p + 1 ] From 2eed09a1892618257e3259b042f455ac8d448a12 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 12 Oct 2019 19:54:42 +0200 Subject: [PATCH 0233/3432] FEAT: minor improvement in NEAR: field report on warnings. --- system/compiler.r | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index bf645f05a7..ca4bd72c88 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -304,11 +304,11 @@ system-dialect: make-profilable context [ quit-on-error ] - throw-warning: func [msg [string! block!] /near][ + throw-warning: func [msg [string! block!] /near value][ print [ "*** Warning:" reform msg "^/*** in:" mold script - "^/*** at:" mold copy/part any [all [near back pc] pc] 8 + "^/*** at:" mold copy/part any [all [near any [find/only/reverse pc value back pc]] pc] 8 ] ] From 14182b82a813229f91516bdee33f00722107d616 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 12 Oct 2019 19:55:19 +0200 Subject: [PATCH 0234/3432] FEAT: adds nested blocks scanning support. --- runtime/definitions.reds | 1 + runtime/lexer.reds | 143 ++++++++++++++++++++++++++++++--------- 2 files changed, 112 insertions(+), 32 deletions(-) diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 4f3a23281a..ec0588774a 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -63,6 +63,7 @@ Red/System [ UTF-16LE: -1 UTF-8: 0 Latin1: 1 + UCS-1: 1 UCS-2: 2 UCS-4: 4 ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1f36a95d3b..a9516e3f43 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -226,7 +226,7 @@ lexer: context [ ] state!: alias struct! [ - stack [red-block!] ;-- any-block! accepted + stack [red-block!] ;-- pairs of (offset,type) buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) buf-tail [red-value!] buf-slots [integer!] @@ -239,6 +239,7 @@ lexer: context [ scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] stash: as cell! 0 ;-- special buffer for hatching any-blocks series + stack: as red-block! 0 ;-- nested series stack stash-size: 1000 ;-- pre-allocated cells number depth: 0 ;-- recursive calls depth @@ -248,9 +249,29 @@ lexer: context [ 0 ;TBD: expand ] slot: s/buf-tail + slot/header: TYPE_UNSET s/buf-tail: s/buf-tail + 1 slot ] + + store-any-block: func [slot [cell!] src [cell!] items [integer!] type [integer!] + /local + blk [red-block!] + s [series!] + ][ + either zero? items [ + block/make-at as red-block! slot 1 + ][ + blk: block/make-at as red-block! slot items + blk/header: type + s: GET_BUFFER(blk) + copy-memory + as byte-ptr! s/offset + as byte-ptr! src + items << 4 + s/tail: s/offset + items + ] + ] scan-eof: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local @@ -265,15 +286,47 @@ lexer: context [ ] scan-block-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + p [red-pair!] ][ - null + p: as red-pair! ALLOC_TAIL(state/stack) + p/header: TYPE_PAIR + p/x: (as-integer state/buf-tail - state/buffer) >> 4 + p/y: TYPE_BLOCK + + alloc-slot state ;-- reserve slot for new block value + state/buffer: state/buf-tail + + state/in-pos: e + 1 ;-- skip delimiter + state/in-len: state/in-len - 1 ] scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + p [red-pair!] + new [red-value!] + len [integer!] + ser [series!] ][ - null + ser: GET_BUFFER(state/stack) + p: as red-pair! ser/tail - 1 + assert TYPE_OF(p) = TYPE_PAIR + if p/y <> TYPE_BLOCK [ + 0 ; error + ] + + len: (as-integer state/buf-tail - state/buffer) >> 4 + new: state/buffer - 1 + state/buf-tail: state/buffer + state/buffer: new - p/x + + store-any-block new state/buf-tail len p/y + + ser/tail: as cell! p + assert ser/offset <= ser/tail + + state/in-pos: e + 1 ;-- skip ending delimiter + state/in-len: state/in-len - 1 ] scan-paren-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -293,28 +346,61 @@ lexer: context [ str [red-string!] ser [series!] len [integer!] + unit [integer!] + cp [integer!] + p [byte-ptr!] + p4 [int-ptr!] ][ s: s + 1 ;-- skip start delimiter len: as-integer e - s + unit: 1 << (flags >>> 30) + if unit > 4 [unit: 4] + + str: string/make-at alloc-slot state len unit + ser: GET_BUFFER(str) - case [ - flags and C_FLAG_UCS4 <> 0 [ - - ] - flags and C_FLAG_UCS2 <> 0 [ - - ] - true [ ;-- UCS1 - str: string/make-at alloc-slot state len 1 - ser: GET_BUFFER(str) - + switch unit [ + UCS-1 [ either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence - copy-memory as byte-ptr! ser/offset as byte-ptr! s len + copy-memory as byte-ptr! ser/offset s len ser/tail: as cell! (as byte-ptr! ser/offset) + len ][ ;-- with escape sequence(s) 0 ] ] + UCS-2 [ + either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + cp: 0 + p: as byte-ptr! ser/offset + while [s < e][ + s: decode-utf8-char s :cp + if cp = -1 [ + 0 ; throw error + ] + p/1: as-byte cp and FFh + p/2: as-byte cp >> 8 + p: p + 2 + ] + ][ + 0 + ] + ] + UCS-4 [ + either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + cp: 0 + p4: as int-ptr! ser/offset + while [s < e][ + s: decode-utf8-char s :cp + if cp = -1 [ + 0 ; throw error + ] + p4/value: cp + p4: p4 + 1 + ] + ][ + 0 + ] + ] ] state/in-pos: e + 1 ;-- skip ending delimiter state/in-len: state/in-len - 1 @@ -588,7 +674,7 @@ lexer: context [ ][ depth: depth + 1 - state/stack: null + state/stack: stack state/buffer: stash ;TBD: support dyn buffer case state/buf-tail: stash state/buf-slots: stash-size ;TBD: support dyn buffer case @@ -601,25 +687,18 @@ lexer: context [ if system/thrown > 0 [ 0 ; error handling ] - if null? state/stack [ - slots: (as-integer state/buf-tail - state/buffer) >> 4 - either zero? slots [ - blk: block/make-at as red-block! dst 1 - ][ - blk: block/make-at as red-block! dst slots - s: GET_BUFFER(blk) - copy-memory - as byte-ptr! s/offset - as byte-ptr! state/buffer - slots << 4 - s/tail: s/offset + slots - ] - ] + assert block/rs-tail? state/stack ;-- stack should be empty + + + slots: (as-integer state/buf-tail - state/buffer) >> 4 + store-any-block dst state/buffer slots TYPE_BLOCK + depth: depth - 1 ] init: func [][ stash: as cell! allocate stash-size * size? cell! + stack: block/make-in root 20 ] ] \ No newline at end of file From 0605ac7b56bbbd96494187db755d226a4c64b8f9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 12 Oct 2019 22:39:28 +0200 Subject: [PATCH 0235/3432] FEAT: adds support for scanning paren! values. --- runtime/lexer.reds | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a9516e3f43..b6992d2475 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -292,7 +292,7 @@ lexer: context [ p: as red-pair! ALLOC_TAIL(state/stack) p/header: TYPE_PAIR p/x: (as-integer state/buf-tail - state/buffer) >> 4 - p/y: TYPE_BLOCK + p/y: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] alloc-slot state ;-- reserve slot for new block value state/buffer: state/buf-tail @@ -303,15 +303,18 @@ lexer: context [ scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - p [red-pair!] - new [red-value!] - len [integer!] - ser [series!] + p [red-pair!] + new [red-value!] + len [integer!] + type [integer!] + ser [series!] ][ ser: GET_BUFFER(state/stack) p: as red-pair! ser/tail - 1 assert TYPE_OF(p) = TYPE_PAIR - if p/y <> TYPE_BLOCK [ + + type: either s/1 = #")" [TYPE_PAREN][TYPE_BLOCK] + if p/y <> type [ 0 ; error ] @@ -320,7 +323,7 @@ lexer: context [ state/buf-tail: state/buffer state/buffer: new - p/x - store-any-block new state/buf-tail len p/y + store-any-block new state/buf-tail len type ser/tail: as cell! p assert ser/offset <= ser/tail @@ -328,18 +331,6 @@ lexer: context [ state/in-pos: e + 1 ;-- skip ending delimiter state/in-len: state/in-len - 1 ] - - scan-paren-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null - ] - - scan-paren-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null - ] scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local @@ -577,8 +568,8 @@ lexer: context [ :scan-error ;-- T_ERROR :scan-block-open ;-- T_BLK_OP :scan-block-close ;-- T_BLK_CL - :scan-paren-open ;-- T_PAR_OP - :scan-paren-close ;-- T_PAR_CL + :scan-block-open ;-- T_PAR_OP + :scan-block-close ;-- T_PAR_CL :scan-string ;-- T_STRING :scan-string-multi ;-- T_STR_ALT :scan-word ;-- T_WORD From e398185cb9d1bf3278b5546860a10d1f360d37f9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 12 Oct 2019 22:55:00 +0200 Subject: [PATCH 0236/3432] FEAT: adds support for scanning percent! values. --- runtime/lexer.reds | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b6992d2475..9beed5b710 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -455,9 +455,17 @@ lexer: context [ ] scan-percent: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + fl [red-float!] ][ - null + assert e/1 = #"%" + scan-float state s e flags + fl: as red-float! state/buf-tail - 1 + fl/header: TYPE_PERCENT + fl/value: fl/value / 100.0 + + state/in-pos: e + 1 ;-- skip ending delimiter + state/in-len: state/in-len - 1 ] scan-integer: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 70c4900b806f37f0a6f2aafecc1790eb1be6a570 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 13:19:50 +0300 Subject: [PATCH 0237/3432] FIX: issue #3361 (Interpreter Gives Correct Results, Compiler Does Not) --- compiler.r | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler.r b/compiler.r index bac332791b..3563aafac7 100644 --- a/compiler.r +++ b/compiler.r @@ -2420,13 +2420,15 @@ red: context [ insert-lf -5 insert-lf -7 emit-stack-reset - + + emit [integer/push 0] emit-open-frame 'repeat emit compose/deep [ while [ ;-- set word 1 + get word ;-- TBD: set word next get word - (set-cnt) (cnt) + 1 + (set-cnt) 1 + integer/get stack/arguments - 1 ;-- fixes #3361 + integer/make-at stack/arguments - 1 (cnt) ;-- (get word) < value ;-- TBD: not tail? get word (cnt) <= (lim) From ec971eb8a130e03d827caef9872fc9cf18200d2c Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 13:21:33 +0300 Subject: [PATCH 0238/3432] TESTS: for issue #3361 (Interpreter Gives Correct Results, Compiler Does Not) --- tests/source/units/loop-test.red | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/source/units/loop-test.red b/tests/source/units/loop-test.red index 580855e8a4..fceb9f1f0d 100644 --- a/tests/source/units/loop-test.red +++ b/tests/source/units/loop-test.red @@ -220,6 +220,18 @@ Red [ ] issue427-f --assert 15 = issue427-acc + + --test-- "issue #3361" + s3361: copy [] + f3361: func [n /local i] [ + repeat i 3 [ + repend s3361 [n i] + all [i = 1 n = 1 f3361 2] + all [i = 2 n = 2 f3361 3] + ] + ] + f3361 1 + --assert s3361 = [1 1 2 1 2 2 3 1 3 2 3 3 2 3 1 2 1 3] ===end-group=== From 5e8438ff721b6421ad9851aa2f69e5a85c7a9c78 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 13 Oct 2019 12:51:47 +0200 Subject: [PATCH 0239/3432] FEAT: preliminary support for loading word in fast lexer. --- runtime/collector.reds | 6 +- runtime/datatypes/string.reds | 6 ++ runtime/datatypes/symbol.reds | 116 +++++++------------- runtime/hashtable.reds | 192 +++++++++++++++++++++++++++++++++- runtime/lexer.reds | 6 +- runtime/platform/win32.reds | 6 ++ 6 files changed, 243 insertions(+), 89 deletions(-) diff --git a/runtime/collector.reds b/runtime/collector.reds index fb6dc143de..4478657abf 100644 --- a/runtime/collector.reds +++ b/runtime/collector.reds @@ -173,7 +173,11 @@ collector: context [ ] ] ] - TYPE_SYMBOL + TYPE_SYMBOL [ + series: as red-series! value + keep as node! series/extra + if series/node <> null [keep series/node] + ] TYPE_STRING TYPE_URL TYPE_FILE diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index e03f173b7a..d480e8c547 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -716,6 +716,9 @@ string: context [ any [op = COMP_EQUAL op = COMP_FIND op = COMP_STRICT_EQUAL op = COMP_NOT_EQUAL] ][return 0] + if TYPE_OF(str1) = TYPE_SYMBOL [symbol/make-red-string as red-symbol! str1] + if TYPE_OF(str2) = TYPE_SYMBOL [symbol/make-red-string as red-symbol! str2] + s1: GET_BUFFER(str1) s2: GET_BUFFER(str2) unit1: GET_UNIT(s1) @@ -927,6 +930,9 @@ string: context [ h2 [integer!] diff? [logic!] ][ + if TYPE_OF(str1) = TYPE_SYMBOL [symbol/make-red-string as red-symbol! str1] + if TYPE_OF(str2) = TYPE_SYMBOL [symbol/make-red-string as red-symbol! str2] + s1: GET_BUFFER(str1) s2: GET_BUFFER(str2) unit1: GET_UNIT(s1) diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index e110fcf3d7..cdd63eadd7 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -21,49 +21,35 @@ symbol: context [ assert TYPE_OF(word) = TYPE_WORD (resolve word/symbol) = resolve words/any-type! ] - - search: func [ - str [red-slice!] - return: [integer!] + + make-red-string: func [ + sym [red-symbol!] /local - s [series!] - id [integer!] - aliased? [logic!] - key [red-value!] + s [series!] ][ - aliased?: no - - key: _hashtable/get table as red-value! str 0 1 COMP_STRICT_EQUAL no no - if key = null [ - key: _hashtable/get table as red-value! str 0 1 COMP_EQUAL no no - aliased?: yes - ] - - id: either key = null [0][ - s: GET_BUFFER(symbols) - (as-integer key - s/offset) >> 4 + 1 + if sym/node = null [ + s: as series! sym/cache/value + sym/node: unicode/load-utf8 as c-string! s/offset as-integer s/tail - s/offset ] - if aliased? [id: 0 - id] - id ] - internalize: func [ - src [c-string!] - return: [node!] - /local - node [node!] - dst [c-string!] - s [series!] - len [integer!] - ][ - len: 1 + length? src - node: alloc-bytes len ;@@ TBD: mark this buffer as protected! - s: as series! node/value - dst: as c-string! s/offset + ;internalize: func [ + ; src [c-string!] + ; return: [node!] + ; /local + ; node [node!] + ; dst [c-string!] + ; s [series!] + ; len [integer!] + ;][ + ; len: 1 + length? src + ; node: alloc-bytes len ;@@ TBD: mark this buffer as protected! + ; s: as series! node/value + ; dst: as c-string! s/offset - copy-memory as byte-ptr! dst as byte-ptr! src len - node - ] + ; copy-memory as byte-ptr! dst as byte-ptr! src len + ; node + ;] make-alt: func [ str [red-string!] @@ -72,59 +58,27 @@ symbol: context [ /local sym [red-symbol!] id [integer!] - val [red-slice! value] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make-alt"]] + probe "make-alt ........................." + 1 + ] - ;-- make a slice, then search in the hashtable - val/header: TYPE_SLICE - val/head: str/head - val/node: str/node - val/length: len - id: search val - - if positive? id [return id] - - sym: as red-symbol! ALLOC_TAIL(symbols) - sym/header: TYPE_UNSET - either len < 0 [ - sym/node: str/node - ][ - sym/node: copy-part str/node str/head len - ] - sym/cache: unicode/str-to-utf8 str :len no - sym/alias: either zero? id [-1][0 - id] ;-- -1: no alias, abs(id)>0: alias id - sym/header: TYPE_SYMBOL ;-- implicit reset of all header flags - _hashtable/put table as red-value! sym - block/rs-length? symbols + make-alt-utf8: func [ + s [byte-ptr!] + len [integer!] + return: [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "symbol/make-alt-utf8"]] + _hashtable/put-symbol table s len ] - + make: func [ s [c-string!] ;-- input c-string! return: [integer!] - /local - str [red-slice! value] - sym [red-symbol!] - id [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make"]] - - str/node: unicode/load-utf8 s system/words/length? s - str/header: TYPE_SLICE - str/head: 0 - str/length: -1 - id: search str - - if positive? id [return id] - - sym: as red-symbol! ALLOC_TAIL(symbols) - sym/header: TYPE_UNSET - sym/node: str/node - sym/cache: internalize s - sym/alias: either zero? id [-1][0 - id] ;-- -1: no alias, abs(id)>0: alias id - sym/header: TYPE_SYMBOL ;-- implicit reset of all header flags - _hashtable/put table as red-value! sym - block/rs-length? symbols + _hashtable/put-symbol table as byte-ptr! s system/words/length? s ] get: func [ diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index e12f3e450c..e3f4d822b0 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -56,7 +56,7 @@ hash-string: func [ ][ s: GET_BUFFER(str) unit: GET_UNIT(s) - head: either TYPE_OF(str) = TYPE_SYMBOL [0][str/head] + head: str/head p: (as byte-ptr! s/offset) + (head << (log-b unit)) sc: as red-slice! str @@ -152,6 +152,9 @@ murmur3-x86-32: func [ ] _hashtable: context [ + str-buffer: as byte-ptr! 0 + str-buffer-sz: 256 + hashtable!: alias struct! [ size [integer!] indexes [node!] @@ -233,6 +236,20 @@ _hashtable: context [ n + 1 ] + hash-symbol: func [ + sym [red-symbol!] + return: [integer!] + /local + s [series!] + len [integer!] + ][ + s: as series! sym/cache/value + len: as-integer s/tail - s/offset + murmur3-x86-32 + to-lower as byte-ptr! s/offset len + len + ] + hash-value: func [ key [red-value!] case? [logic!] @@ -240,8 +257,7 @@ _hashtable: context [ /local sym [red-string!] s [series!] ][ switch TYPE_OF(key) [ - TYPE_SLICE - TYPE_SYMBOL + TYPE_SYMBOL [hash-symbol as red-symbol! key] TYPE_STRING TYPE_FILE TYPE_URL @@ -264,8 +280,7 @@ _hashtable: context [ TYPE_REFINEMENT TYPE_ISSUE [ s: GET_BUFFER(symbols) - sym: as red-string! s/offset + key/data2 - 1 - hash-string sym case? + hash-symbol as red-symbol! s/offset + key/data2 - 1 ] TYPE_BINARY [ sym: as red-string! key @@ -384,6 +399,10 @@ _hashtable: context [ h: as hashtable! s/offset h/type: type if type = HASH_TABLE_INTEGER [h/indexes: as node! vsize + 1 << 4] + if type = HASH_TABLE_SYMBOL [ + if null? str-buffer [str-buffer: allocate str-buffer-sz] + size: size << 4 + ] if size < 32 [size: 32] fsize: as-float size @@ -1198,4 +1217,167 @@ _hashtable: context [ copy-memory as byte-ptr! indexes + dst temp items free temp ] + + to-lower: func [ ;-- Latin1 locale only, TBD: locale support + str [byte-ptr!] + len [integer!] + return: [byte-ptr!] + /local + n [integer!] + ][ + if len > str-buffer-sz [ + free str-buffer + str-buffer: allocate len + ] + n: 1 + loop len [ + either any [ + str/n > #"Z" + str/n < #"A" + ][ + str-buffer/n: str/n + ][ + str-buffer/n: str/n or #"`" + ] + n: n + 1 + ] + str-buffer + ] + + compare-cstr: func [ + cstr1 [byte-ptr!] + cstr2 [byte-ptr!] + len [integer!] + strict? [logic!] + return: [integer!] + ][ + either strict? [ + compare-memory cstr1 cstr2 len + ][ + platform/strnicmp cstr1 cstr2 len + ] + ] + + put-symbol: func [ + node [node!] + cstr [byte-ptr!] + len [integer!] + return: [integer!] ;-- return symbol id + /local + s [series!] h [hashtable!] x [integer!] i [integer!] site [integer!] + last [integer!] mask [integer!] step [integer!] keys [int-ptr!] + hash [integer!] n-buckets [integer!] flags [int-ptr!] ii [integer!] + sh [integer!] blk [red-symbol!] idx [integer!] del? [logic!] k [red-symbol!] + vsize [integer!] blk-node [series!] find? [logic!] xx [integer!] new? [logic!] + len2 [integer!] strict? [logic!] + ][ + s: as series! node/value + h: as hashtable! s/offset + + if h/n-occupied >= h/upper-bound [ ;-- update the hash table + vsize: either h/n-buckets > (h/size << 1) [-1][1] + n-buckets: h/n-buckets + vsize + resize node n-buckets + ] + + blk-node: as series! h/blk/value + blk: as red-symbol! blk-node/offset + idx: (as-integer blk-node/tail - as cell! blk) >> 4 + + s: as series! h/keys/value + keys: as int-ptr! s/offset + s: as series! h/flags/value + flags: as int-ptr! s/offset + n-buckets: h/n-buckets + 1 + x: n-buckets + site: n-buckets + mask: n-buckets - 2 + hash: murmur3-x86-32 to-lower cstr len len + strict?: yes + loop 2 [ ;-- first try: case-sensitive comparison, second try: case-insensitive comparison + find?: yes + i: hash and mask + _HT_CAL_FLAG_INDEX(i ii sh) + i: i + 1 ;-- 1-based index + either _BUCKET_IS_EMPTY(flags ii sh) [x: i break][ + step: 0 + last: i + while [ + ;del?: _BUCKET_IS_DEL(flags ii sh) + find?: _BUCKET_IS_NOT_EMPTY(flags ii sh) + find? + ][ + k: as red-symbol! blk + keys/i + s: as series! k/cache/value + len2: as-integer (s/tail - s/offset) + either any [ + ;del? + len2 <> len + 0 <> compare-cstr as byte-ptr! s/offset cstr len strict? + ][ + ;if del? [site: i] + i: i + step and mask + _HT_CAL_FLAG_INDEX(i ii sh) + i: i + 1 + step: step + 1 + if i = last [x: site find?: no break] + ][break] + ] + x: i + ;if x = n-buckets [ + ;x: either all [ + ; _BUCKET_IS_EMPTY(flags ii sh) + ; site <> n-buckets + ;][site][i] + ;] + ] + either find? [break][xx: x strict?: no] + ] + + new?: yes + _HT_CAL_FLAG_INDEX((x - 1) ii sh) + case [ + _BUCKET_IS_EMPTY(flags ii sh) [ + k: as red-symbol! alloc-tail blk-node + keys/x: idx + _BUCKET_SET_BOTH_FALSE(flags ii sh) + h/size: h/size + 1 + h/n-occupied: h/n-occupied + 1 + len2: -1 + ] + ;_BUCKET_IS_DEL(flags ii sh) [ + ; k: as red-symbol! blk + keys/x + ; _BUCKET_SET_BOTH_FALSE(flags ii sh) + ; h/size: h/size + 1 + ;] + true [ + len2: keys/x + 1 + either strict? [ + new?: no + k: as red-symbol! blk + (len2 - 1) + ][ + k: as red-symbol! alloc-tail blk-node + _HT_CAL_FLAG_INDEX((xx - 1) ii sh) + keys/xx: idx + _BUCKET_SET_BOTH_FALSE(flags ii sh) + h/size: h/size + 1 + h/n-occupied: h/n-occupied + 1 + ] + ] + ] + + if new? [ + k/header: TYPE_UNSET + node: alloc-bytes len + s: as series! node/value + copy-memory as byte-ptr! s/offset cstr len + s/tail: as red-value! (as byte-ptr! s/offset) + len + k/cache: node + k/node: null + k/alias: len2 + k/header: TYPE_SYMBOL + ] + + (as-integer k - blk) >> 4 + 1 + ] ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9beed5b710..4237446e25 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -407,9 +407,11 @@ lexer: context [ /local cell [cell!] ][ - probe "word!" cell: alloc-slot state - cell/header: TYPE_NONE + word/make-at + symbol/make-alt-utf8 s as-integer e - s + cell + ;cell/header: TYPE_WORD ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] diff --git a/runtime/platform/win32.reds b/runtime/platform/win32.reds index caa8a39992..e8e7b4a1be 100644 --- a/runtime/platform/win32.reds +++ b/runtime/platform/win32.reds @@ -194,6 +194,12 @@ platform: context [ return: [integer!] ] __iob_func: "__iob_func" [return: [int-ptr!]] + strnicmp: "_strnicmp" [ + s1 [byte-ptr!] + s2 [byte-ptr!] + len [integer!] + return: [integer!] + ] ] "kernel32.dll" stdcall [ VirtualAlloc: "VirtualAlloc" [ From 718d551c70d1de3ce8f498214d82f7cfe5742b1a Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 15:04:45 +0300 Subject: [PATCH 0240/3432] FIX: better fix for #3361 --- compiler.r | 1 + system/utils/libRedRT-exports.r | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler.r b/compiler.r index 3563aafac7..dfb156c22c 100644 --- a/compiler.r +++ b/compiler.r @@ -2442,6 +2442,7 @@ red: context [ pop-call insert last output reduce [action name cnt] new-line last output on + emit [copy-cell stack/arguments stack/arguments - 1] ;-- override the counter with the body result emit-close-frame emit-close-frame depth: depth - 1 diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index f3f0e77986..ba5676ad3e 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -133,6 +133,7 @@ red/integer/get-any* red/integer/get* red/integer/get + red/integer/make-at red/integer/form-signed red/logic/get red/float/get From 9d843fa79bb24438cbd6c7e39327da5751c12e56 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 15:19:48 +0300 Subject: [PATCH 0241/3432] TESTS: better tests coverage for REPEAT loop --- tests/source/units/loop-test.red | 28 ++++++++++++++++++++-- tests/source/units/regression-test-red.red | 8 +++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/tests/source/units/loop-test.red b/tests/source/units/loop-test.red index fceb9f1f0d..1afc46b485 100644 --- a/tests/source/units/loop-test.red +++ b/tests/source/units/loop-test.red @@ -44,6 +44,29 @@ Red [ ===end-group=== +===start-group=== "advanced repeat tests" + + --test-- "repeat counter mess" + rcm-n: 0 + repeat rcm-i 10 [ + repeat rcm-i 5 [ + rcm-i: rcm-i + 3 + rcm-n: rcm-n + 1 + ] + ] + --assert 50 = rcm-n + unset [rcm-i rcm-n] + + --test-- "repeat return values" + ;-- see also #973, but repeat body should not return the counter itself + rrv-f: func [] [repeat rrv-i 2 [rrv-i * 10]] ;-- =20 + rrv-b: copy [] + repeat rrv-j 5 [append rrv-b rrv-f] + --assert rrv-b = [20 20 20 20 20] + unset [rrv-f rrv-b rrv-j rrv-i] + +===end-group=== + ===start-group=== "basic until tests" --test-- "bu1" @@ -221,7 +244,7 @@ Red [ issue427-f --assert 15 = issue427-acc - --test-- "issue #3361" + --test-- "issue #3361" s3361: copy [] f3361: func [n /local i] [ repeat i 3 [ @@ -232,7 +255,8 @@ Red [ ] f3361 1 --assert s3361 = [1 1 2 1 2 2 3 1 3 2 3 3 2 3 1 2 1 3] - + unset [f3361 s3361] + ===end-group=== ~~~end-file~~~ diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 76c171ad37..2922a66ae3 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -1193,12 +1193,12 @@ Red [ --test-- "#973" a973: func [] [ - repeat i 2 [i] + repeat i973 2 [i973 * 10] ;-- don't return the counter itself to better catch regressions ] b973: copy [] - repeat j 2 [append b973 a973] - --assert equal? [2 2] b973 - unset [a973 b973] + repeat j983 2 [append b973 a973] + --assert equal? [20 20] b973 + unset [a973 b973 i973 j973] --test-- "#974" --assert not error? try [random 3] From 871a7703055edbca683aaaa530197bb89b152671 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 15:22:29 +0300 Subject: [PATCH 0242/3432] FIX: removed double test code --- tests/source/units/loop-test.red | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/source/units/loop-test.red b/tests/source/units/loop-test.red index 1afc46b485..87e95c5ea3 100644 --- a/tests/source/units/loop-test.red +++ b/tests/source/units/loop-test.red @@ -57,14 +57,6 @@ Red [ --assert 50 = rcm-n unset [rcm-i rcm-n] - --test-- "repeat return values" - ;-- see also #973, but repeat body should not return the counter itself - rrv-f: func [] [repeat rrv-i 2 [rrv-i * 10]] ;-- =20 - rrv-b: copy [] - repeat rrv-j 5 [append rrv-b rrv-f] - --assert rrv-b = [20 20 20 20 20] - unset [rrv-f rrv-b rrv-j rrv-i] - ===end-group=== ===start-group=== "basic until tests" From c2613cc6c59b908ebb9b85c00a588298b0081e10 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 14:04:35 +0200 Subject: [PATCH 0243/3432] FIX: forces an exit T_PAIR state on reaching the input's end. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 15425 -> 15740 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 7d47ecb45c..3563138f20 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -25,7 +25,7 @@ S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_D S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 1d0fe689e2dd206e2bbc903669a5e8ca2238f7e1..ae1f3dadf120984dff85ac5eedd527fe77bf9b06 100644 GIT binary patch literal 15740 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 literal 15425 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 Date: Mon, 14 Oct 2019 14:05:23 +0200 Subject: [PATCH 0244/3432] FEAT: adds support for scanning pair! values. --- runtime/lexer.reds | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4237446e25..4d7dab3cc2 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -26,6 +26,7 @@ lexer: context [ C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h C_FLAG_SIGN: 00200000h + C_FLAG_NOSTORE: 00000100h ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] @@ -471,6 +472,7 @@ lexer: context [ ] scan-integer: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + return: [integer!] /local p [byte-ptr!] len [integer!] @@ -485,7 +487,7 @@ lexer: context [ len: as-integer e - p if len > 10 [ scan-float state s e flags ;-- overflow, fall back on float - exit + return 0 ] i: 0 either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path @@ -502,8 +504,11 @@ lexer: context [ assert p = e ] if s/value = #"-" [i: 0 - i] - integer/make-at alloc-slot state i + if flags and C_FLAG_NOSTORE = 0 [ + integer/make-at alloc-slot state i + ] state/in-pos: e ;-- reset the input position to delimiter byte + i ] scan-float: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -532,9 +537,24 @@ lexer: context [ ] scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + index [integer!] + class [integer!] + p [byte-ptr!] ][ - null + p: s + until [ + p: p + 1 ;-- x separator cannot be at start + index: 1 + as-integer p/1 + class: lex-classes/index + class = C_X + ] + pair/make-at + alloc-slot state + scan-integer state s p flags or C_FLAG_NOSTORE + scan-integer state p + 1 e flags or C_FLAG_NOSTORE + + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-time: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 4a7928eb40a8ba4a82d139e8bcfe484b8b0bc3aa Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 17:11:10 +0200 Subject: [PATCH 0245/3432] FIX: removes a leftover debug log. --- runtime/datatypes/symbol.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index cdd63eadd7..dd39f31ea3 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -60,7 +60,6 @@ symbol: context [ id [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make-alt"]] - probe "make-alt ........................." 1 ] From bbeb0226772c2bf1e2d8aa396e5e4f82eb6bb911 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 17:11:46 +0200 Subject: [PATCH 0246/3432] FIX: forces an exit T_TUPLE state on reaching the input's end. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 15740 -> 15418 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 3563138f20..9b37c44fda 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -20,7 +20,7 @@ S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_I S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF -S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_EOF S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index ae1f3dadf120984dff85ac5eedd527fe77bf9b06..396f2bdcaf0cddd50eca551cf4c471575d6a22e3 100644 GIT binary patch literal 15418 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

QIma%#ou`G$_tg_7K zE#6>Q6+daPVieQYg>&z0IqFFK@HD~z_5!{w&>BY=_9~9YVW;`EI+%>2tpbx3j?t5( z;GL9e+Z(TXx(8^SHPBWV`W~&Mbo&RJg4%o~Vi8V^no|5)>xSw!p^tj39#M$8%jsHY zD)pyqG7+MLzrM|!b?cumm)dreUEVdVD~_6;4=JkBmyq3kF6}S}!jg?g@2Y0$TXwRm znyTPlU;RAy0PT@B&oez;=YaOTH;U&JtMh3eEC@Xivn0b139L5_F|AIky?z8PtO!wD z@1)W1tvKS&epSRJo%Ik(Dwm=!Io*uC2Cm}_A#qQPAo@bLBqpay>~fo>YgFT1xz)+L zPe;5NGEUcByA(hieuFOzEE6zU{_p!A{|MI~pZ~HOQc3Rb0{*@$>yH!fKg)rf_{$!x zUr+q|MwP#wI1Z%Rf4yzxS2@3KUieee17HOAm#qxHp8V^${huet0R#B=gH68<-~TG% z*O}%&CD;M8QNOGI-%U9GD)844;XegBVEh#L>%j1@0)8FO`cnW0{%o3>zJ8dh;JpeEW0-*tabO4Nh@Z2B$FXq<&e*gdg literal 15740 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 838f872911..7962dd06ee 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -95,7 +95,7 @@ Red/System [ 19132B3C2B3C2B3A2B3C2B2B2B2B2B2B2B2B3C3C3C13133C3C3C3C3C3C3C192B 3C2B132B3C2B3C2B3A2B2B2B152B2B2B2B2B2B3C3C3C3C3C3C3C3C3C3C3C3C14 3C3C1414143C3C3C143C3C3C3C143C143C14142B2A3D3D15153D3D3D3D3D3D3D -2B2B3D2B2B2B3D2B3D2B2B2B2B2B152B2B2B2B2B2B2A3E3E16163E3E3E3E3E3E +2B2B3D2B2B2B3D2B3D2B2B2B2B2B152B2B2B2B2B2B3D3E3E16163E3E3E3E3E3E 3E16163E16161616163E163E163E3E163E163E16162B2A2B2B18182B2B2B2B2B 2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B4040181840404040 4040402B2B182B2B2B402B402B2B2B402B182B2B2B2B2B2B2A2B2B1A1A2B2B2B From b3e3436922841ca49afa3a2dc3f85fd1a304eff3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 17:12:05 +0200 Subject: [PATCH 0247/3432] FEAT: adds support for scanning tuple! values. --- runtime/lexer.reds | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4d7dab3cc2..c3183b0c3f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -525,9 +525,34 @@ lexer: context [ ] scan-tuple: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] + i [integer!] + pos [integer!] + tp [byte-ptr!] + p [byte-ptr!] ][ - null + cell: alloc-slot state + tp: (as byte-ptr! cell) + 4 + pos: 0 + i: 0 + p: s + + loop as-integer e - s [ + either p/1 = #"." [ + pos: pos + 1 + if any [i < 0 i > 255 pos > 12][throw LEX_ERROR] + tp/pos: as byte! i + i: 0 + ][ + i: i * 10 + as-integer (p/1 - #"0") + ] + p: p + 1 + ] + pos: pos + 1 ;-- last number + tp/pos: as byte! i + cell/header: TYPE_TUPLE or (pos << 19) + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-date: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 39753c19abf80328ab418fc811e19f642a143f93 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 14 Oct 2019 18:51:13 +0200 Subject: [PATCH 0248/3432] FEAT: code refactoring in hashtable. --- runtime/hashtable.reds | 74 +++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index e3f4d822b0..181b6e430f 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1277,7 +1277,7 @@ _hashtable: context [ if h/n-occupied >= h/upper-bound [ ;-- update the hash table vsize: either h/n-buckets > (h/size << 1) [-1][1] n-buckets: h/n-buckets + vsize - resize node n-buckets + resize node n-buckets << 4 ] blk-node: as series! h/blk/value @@ -1303,7 +1303,6 @@ _hashtable: context [ step: 0 last: i while [ - ;del?: _BUCKET_IS_DEL(flags ii sh) find?: _BUCKET_IS_NOT_EMPTY(flags ii sh) find? ][ @@ -1311,11 +1310,9 @@ _hashtable: context [ s: as series! k/cache/value len2: as-integer (s/tail - s/offset) either any [ - ;del? len2 <> len 0 <> compare-cstr as byte-ptr! s/offset cstr len strict? ][ - ;if del? [site: i] i: i + step and mask _HT_CAL_FLAG_INDEX(i ii sh) i: i + 1 @@ -1324,59 +1321,40 @@ _hashtable: context [ ][break] ] x: i - ;if x = n-buckets [ - ;x: either all [ - ; _BUCKET_IS_EMPTY(flags ii sh) - ; site <> n-buckets - ;][site][i] - ;] ] either find? [break][xx: x strict?: no] ] - new?: yes _HT_CAL_FLAG_INDEX((x - 1) ii sh) - case [ - _BUCKET_IS_EMPTY(flags ii sh) [ + either _BUCKET_IS_EMPTY(flags ii sh) [ + k: as red-symbol! alloc-tail blk-node + keys/x: idx + len2: -1 + ][ + len2: keys/x + 1 + either strict? [return len2][ k: as red-symbol! alloc-tail blk-node - keys/x: idx - _BUCKET_SET_BOTH_FALSE(flags ii sh) - h/size: h/size + 1 - h/n-occupied: h/n-occupied + 1 - len2: -1 - ] - ;_BUCKET_IS_DEL(flags ii sh) [ - ; k: as red-symbol! blk + keys/x - ; _BUCKET_SET_BOTH_FALSE(flags ii sh) - ; h/size: h/size + 1 - ;] - true [ - len2: keys/x + 1 - either strict? [ - new?: no - k: as red-symbol! blk + (len2 - 1) - ][ - k: as red-symbol! alloc-tail blk-node - _HT_CAL_FLAG_INDEX((xx - 1) ii sh) - keys/xx: idx - _BUCKET_SET_BOTH_FALSE(flags ii sh) - h/size: h/size + 1 - h/n-occupied: h/n-occupied + 1 - ] + _HT_CAL_FLAG_INDEX((xx - 1) ii sh) + keys/xx: idx ] ] - if new? [ - k/header: TYPE_UNSET - node: alloc-bytes len - s: as series! node/value - copy-memory as byte-ptr! s/offset cstr len - s/tail: as red-value! (as byte-ptr! s/offset) + len - k/cache: node - k/node: null - k/alias: len2 - k/header: TYPE_SYMBOL - ] + _BUCKET_SET_BOTH_FALSE(flags ii sh) + h/size: h/size + 1 + h/n-occupied: h/n-occupied + 1 + + blk-node: as series! h/blk/value + blk: as red-symbol! blk-node/offset + + k/header: TYPE_UNSET + node: alloc-bytes len + s: as series! node/value + copy-memory as byte-ptr! s/offset cstr len + s/tail: as red-value! (as byte-ptr! s/offset) + len + k/cache: node + k/node: null + k/alias: len2 + k/header: TYPE_SYMBOL (as-integer k - blk) >> 4 + 1 ] From 1ad90ec02711c8d197a861e26ea4f06fce30c964 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 21:29:40 +0200 Subject: [PATCH 0249/3432] FEAT: adds support for scanning char! values. --- runtime/lexer.reds | 94 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c3183b0c3f..c1af5aad79 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -433,10 +433,100 @@ lexer: context [ null ] + ;-- Bit-array for BDELNPTbdelnpt + char-names-1st: #{0000000000000000345011003450110000000000000000000000000000000000} + + ;-- Bit-array for /-~^{}" + char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} + scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + char [red-char!] + p [byte-ptr!] + src [byte-ptr!] + len [integer!] + c [integer!] + pos [integer!] + pow [integer!] + index [integer!] + class [integer!] + skip [integer!] + res [integer!] + cp [byte!] + bit [byte!] ][ - null + assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] + + len: as-integer e - s + if len = 3 [throw LEX_ERROR] ;-- #"" + + either s/3 = #"^^" [ + if len = 4 [throw LEX_ERROR] ;-- #"^" + c: as-integer s/5 + pos: c >>> 3 + 1 + bit: as-byte c and 7 + either s/4 = #"(" [ ;-- note: #"^(" not allowed + either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char + p: s + 4 + c: 0 + cp: as byte! 0 + pow: 0 + while [any [p/1 <> #")" p < e]][ + if p/1 <> #"0" [ + index: 1 + as-integer p/1 + class: lex-classes/index + switch class [ + C_DIGIT [cp: p/1 - #"0"] + C_ALPHAX [cp: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cp: cp + 10] + default [throw LEX_ERROR] + ] + c: c + ((as-integer cp) << pow) + ] + pow: pow + 4 + p: p + 1 + ] + if any [p = e p/1 <> #")"][throw LEX_ERROR] + ][ ;-- named escaped char + cp: s/5 + if cp < #"a" [cp: cp or #"^(20)"] + src: s + 5 + res: switch cp [ + #"n" [c: 00h skip: 4 platform/strnicmp src as byte-ptr! "ull" 3] + #"b" [c: 08h skip: 4 platform/strnicmp src as byte-ptr! "ack" 3] + #"t" [c: 09h skip: 3 platform/strnicmp src as byte-ptr! "ab" 2] + #"l" [c: 0Ah skip: 4 platform/strnicmp src as byte-ptr! "ine" 3] + #"p" [c: 0Ch skip: 4 platform/strnicmp src as byte-ptr! "age" 3] + #"e" [c: 1Bh skip: 3 platform/strnicmp src as byte-ptr! "sc" 2] + #"d" [c: 7Fh skip: 3 platform/strnicmp src as byte-ptr! "el" 2] + default [assert false 0] + ] + if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] + ] + ][ + either char-special/pos and bit = null-byte [ ;-- escaped special char + c: as-integer switch s/5 [ + #"/" [#"^/"] + #"-" [#"^-"] + #"^"" [#"^""] + #"{" [#"{"] + #"}" [#"}"] + #"^^" [#"^^"] + #"~" [#"^~"] + default [assert false] + ] + ][ ;-- "regular" escaped char + c: as-integer s/5 - #"@" + ] + ] + ][ ;-- simple char + c: as-integer s/3 + ] + char: as red-char! alloc-slot state + char/header: TYPE_CHAR + char/value: c + + state/in-pos: e + 1 ;-- skip ending delimiter + state/in-len: state/in-len - 1 ] scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 70ccf51c72517578e914c54f7b8579c1bc51f3e2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 22:48:05 +0200 Subject: [PATCH 0250/3432] FEAT: various fixes and improvements to scanning char! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 15418 -> 15750 bytes runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 37 +++++++++++++++++---------------- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 9b37c44fda..f7fecf78f5 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -12,7 +12,7 @@ S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_ S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;T_ERROR;S_BINARY;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 396f2bdcaf0cddd50eca551cf4c471575d6a22e3..a19d3e507c8912b38d2c1e9f0346fac16bc0cc16 100644 GIT binary patch literal 15750 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 literal 15418 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

QIma%#ou`G$_tg_7K zE#6>Q6+daPVieQYg>&z0IqFFK@HD~z_5!{w&>BY=_9~9YVW;`EI+%>2tpbx3j?t5( z;GL9e+Z(TXx(8^SHPBWV`W~&Mbo&RJg4%o~Vi8V^no|5)>xSw!p^tj39#M$8%jsHY zD)pyqG7+MLzrM|!b?cumm)dreUEVdVD~_6;4=JkBmyq3kF6}S}!jg?g@2Y0$TXwRm znyTPlU;RAy0PT@B&oez;=YaOTH;U&JtMh3eEC@Xivn0b139L5_F|AIky?z8PtO!wD z@1)W1tvKS&epSRJo%Ik(Dwm=!Io*uC2Cm}_A#qQPAo@bLBqpay>~fo>YgFT1xz)+L zPe;5NGEUcByA(hieuFOzEE6zU{_p!A{|MI~pZ~HOQc3Rb0{*@$>yH!fKg)rf_{$!x zUr+q|MwP#wI1Z%Rf4yzxS2@3KUieee17HOAm#qxHp8V^${huet0R#B=gH68<-~TG% z*O}%&CD;M8QNOGI-%U9GD)844;XegBVEh#L>%j1@0)8FO`cnW0{%o3>zJ8dh;JpeEW0-*tabO4Nh@Z2B$FXq<&e*gdg diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 7962dd06ee..2f642aa39d 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -87,7 +87,7 @@ Red/System [ 2B39391010101010102B390B0B0B0B2B2B2B2B2B352B2B2B2B2B2B0B2B2B2B2B 2B2B0C2B2B2B2B2B2B2B2B2B0C0B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C 0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D360D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0E0D0D2B2B0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0E0D0D2B360D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D 0D0D0D0D0D0D0D0D0D0D0D0D0D2B2B0F0F0F0F0F380F0F0F0F0F0F0F0F0F0F0F 0F0F0F0F0F0F0F0F0F0F0F0F0F0F2B2B39391010393939393939391010101010 1010101010101039391010101010102B393B3B11113B3B3B3B3B3B3B0A111719 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c1af5aad79..e68b49beb0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -444,6 +444,7 @@ lexer: context [ char [red-char!] p [byte-ptr!] src [byte-ptr!] + word [c-string!] len [integer!] c [integer!] pos [integer!] @@ -456,15 +457,14 @@ lexer: context [ bit [byte!] ][ assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] - len: as-integer e - s - if len = 3 [throw LEX_ERROR] ;-- #"" + if len = 2 [throw LEX_ERROR] ;-- #"" either s/3 = #"^^" [ - if len = 4 [throw LEX_ERROR] ;-- #"^" + if len = 3 [throw LEX_ERROR] ;-- #"^" c: as-integer s/5 pos: c >>> 3 + 1 - bit: as-byte c and 7 + bit: as-byte 1 << c and 7 either s/4 = #"(" [ ;-- note: #"^(" not allowed either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char p: s + 4 @@ -490,32 +490,34 @@ lexer: context [ cp: s/5 if cp < #"a" [cp: cp or #"^(20)"] src: s + 5 - res: switch cp [ - #"n" [c: 00h skip: 4 platform/strnicmp src as byte-ptr! "ull" 3] - #"b" [c: 08h skip: 4 platform/strnicmp src as byte-ptr! "ack" 3] - #"t" [c: 09h skip: 3 platform/strnicmp src as byte-ptr! "ab" 2] - #"l" [c: 0Ah skip: 4 platform/strnicmp src as byte-ptr! "ine" 3] - #"p" [c: 0Ch skip: 4 platform/strnicmp src as byte-ptr! "age" 3] - #"e" [c: 1Bh skip: 3 platform/strnicmp src as byte-ptr! "sc" 2] - #"d" [c: 7Fh skip: 3 platform/strnicmp src as byte-ptr! "el" 2] - default [assert false 0] + word: switch cp [ + #"n" [c: 00h skip: 4 "ull"] + #"b" [c: 08h skip: 4 "ack"] + #"t" [c: 09h skip: 3 "ab" ] + #"l" [c: 0Ah skip: 4 "ine"] + #"p" [c: 0Ch skip: 4 "age"] + #"e" [c: 1Bh skip: 3 "sc" ] + #"d" [c: 7Fh skip: 3 "el" ] + default [assert false null] ] + res: platform/strnicmp src as byte-ptr! word skip - 1 if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] ] ][ either char-special/pos and bit = null-byte [ ;-- escaped special char - c: as-integer switch s/5 [ + c: as-integer switch s/4 [ #"/" [#"^/"] #"-" [#"^-"] #"^"" [#"^""] - #"{" [#"{"] - #"}" [#"}"] + #"{" [#"{" ] + #"}" [#"}" ] #"^^" [#"^^"] #"~" [#"^~"] default [assert false] ] ][ ;-- "regular" escaped char - c: as-integer s/5 - #"@" + if any [s/4 < #"^(40)" #"^(5F)" < s/4][throw LEX_ERROR] + c: as-integer s/4 - #"@" ] ] ][ ;-- simple char @@ -824,7 +826,6 @@ lexer: context [ 0 ; error handling ] assert block/rs-tail? state/stack ;-- stack should be empty - slots: (as-integer state/buf-tail - state/buffer) >> 4 store-any-block dst state/buffer slots TYPE_BLOCK From 036719a6b8a243afbaf967990f6d33bd6ad8af6a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 23:21:48 +0200 Subject: [PATCH 0251/3432] FIX: more char! scanning fixes. --- runtime/lexer.reds | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e68b49beb0..f387cc9823 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -462,10 +462,10 @@ lexer: context [ either s/3 = #"^^" [ if len = 3 [throw LEX_ERROR] ;-- #"^" - c: as-integer s/5 - pos: c >>> 3 + 1 - bit: as-byte 1 << c and 7 either s/4 = #"(" [ ;-- note: #"^(" not allowed + c: as-integer s/5 + pos: c >>> 3 + 1 + bit: as-byte 1 << c and 7 either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char p: s + 4 c: 0 @@ -504,7 +504,13 @@ lexer: context [ if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] ] ][ - either char-special/pos and bit = null-byte [ ;-- escaped special char + c: as-integer s/4 + pos: c >>> 3 + 1 + bit: as-byte 1 << c and 7 + either char-special/pos and bit = null-byte [ ;-- "regular" escaped char + if any [s/4 < #"^(40)" #"^(5F)" < s/4][throw LEX_ERROR] + c: as-integer s/4 - #"@" + ][ ;-- escaped special char c: as-integer switch s/4 [ #"/" [#"^/"] #"-" [#"^-"] @@ -515,9 +521,6 @@ lexer: context [ #"~" [#"^~"] default [assert false] ] - ][ ;-- "regular" escaped char - if any [s/4 < #"^(40)" #"^(5F)" < s/4][throw LEX_ERROR] - c: as-integer s/4 - #"@" ] ] ][ ;-- simple char From 2b483ea83a413c3f17c79620cee1e534c78e89cb Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 14 Oct 2019 23:46:29 +0200 Subject: [PATCH 0252/3432] FIX: missing parens for marking priority in sub-expression in scan-char function. --- runtime/lexer.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f387cc9823..e2ec2fd05c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -465,7 +465,7 @@ lexer: context [ either s/4 = #"(" [ ;-- note: #"^(" not allowed c: as-integer s/5 pos: c >>> 3 + 1 - bit: as-byte 1 << c and 7 + bit: as-byte 1 << (c and 7) either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char p: s + 4 c: 0 @@ -506,7 +506,7 @@ lexer: context [ ][ c: as-integer s/4 pos: c >>> 3 + 1 - bit: as-byte 1 << c and 7 + bit: as-byte 1 << (c and 7) either char-special/pos and bit = null-byte [ ;-- "regular" escaped char if any [s/4 < #"^(40)" #"^(5F)" < s/4][throw LEX_ERROR] c: as-integer s/4 - #"@" From 80491dcf45d0b50f61ff7e08948c5a31e1b66fe8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 15 Oct 2019 09:50:39 +0800 Subject: [PATCH 0253/3432] FIX: remove no used code --- modules/view/backends/gtk3/events.reds | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e1df4f3e46..43dee52f4d 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -655,13 +655,11 @@ connect-widget-events: function [ ] sym = base [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget @@ -710,7 +708,6 @@ connect-widget-events: function [ ] sym = panel [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK or GDK_BUTTON1_MOTION_MASK or GDK_BUTTON_RELEASE_MASK or GDK_KEY_PRESS_MASK or GDK_KEY_RELEASE_MASK or GDK_FOCUS_CHANGE_MASK gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes ] From a0853172c0d2d4410a80b7dfde00d44f7dd249f2 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 15 Oct 2019 09:51:29 +0800 Subject: [PATCH 0254/3432] FIX: libredRT didn't work --- system/utils/libRedRT-exports.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index b257181599..f4d3beaa5b 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -376,7 +376,7 @@ red/natives/recycle* ;-- for view backend - red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/ownership/bind red/integer/make-at red/string/load red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set + red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/unicode/utf8-next-char red/ownership/bind red/integer/make-at red/string/load red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set ][ red/root red-block! red/object/path-parent cell! @@ -390,4 +390,5 @@ red/false-value cell! red/boot? logic! red/collector/active? logic! + red/natives/buffer-blk red-block! ] \ No newline at end of file From 063b8173fe6062490a8c1fde3a95a3616716cbda Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 15 Oct 2019 12:50:49 +0200 Subject: [PATCH 0255/3432] FEAT: adds support for scanning get/set/lit words. --- runtime/lexer.reds | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e2ec2fd05c..915f009143 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -407,12 +407,27 @@ lexer: context [ scan-word: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] + type [integer!] ][ + type: TYPE_WORD + if flags and C_FLAG_COLON <> 0 [ + case [ + s/1 = #":" [s: s + 1 type: TYPE_GET_WORD] + e/0 = #":" [e: e - 1 type: TYPE_SET_WORD] + true [throw LEX_ERROR] + ] + ] + if flags and C_FLAG_QUOTE <> 0 [ + if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] + ] cell: alloc-slot state - word/make-at - symbol/make-alt-utf8 s as-integer e - s - cell - ;cell/header: TYPE_WORD + word/make-at symbol/make-alt-utf8 s as-integer e - s cell + cell/header: type + + if type = TYPE_SET_WORD [ + state/in-pos: e + 1 ;-- skip ending delimiter + state/in-len: state/in-len - 1 + ] ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 9313fd4953f722dc6aae5c14c3bf43f4dd0c7b78 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 15 Oct 2019 13:56:28 +0200 Subject: [PATCH 0256/3432] FEAT: adds support for scanning issue! values. --- runtime/lexer.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 915f009143..1c91e0f177 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -562,9 +562,14 @@ lexer: context [ ] scan-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] ][ - null + assert s/1 = #"#" + s: s + 1 + cell: alloc-slot state + word/make-at symbol/make-alt-utf8 s as-integer e - s cell + cell/header: TYPE_ISSUE ] scan-percent: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From d1dab0b10ffd650dc08949f4d8469a605e3b1f92 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 15 Oct 2019 17:58:28 +0200 Subject: [PATCH 0257/3432] FEAT: adds support for scanning refinement! values. --- runtime/lexer.reds | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1c91e0f177..e6224e8473 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -436,12 +436,6 @@ lexer: context [ null ] - scan-refinement: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null - ] - scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local ][ @@ -561,15 +555,17 @@ lexer: context [ null ] - scan-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-ref-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] + type [integer!] ][ - assert s/1 = #"#" + type: either s/1 = #"#" [TYPE_ISSUE][assert s/1 = #"/" TYPE_REFINEMENT] s: s + 1 cell: alloc-slot state word/make-at symbol/make-alt-utf8 s as-integer e - s cell - cell/header: TYPE_ISSUE + cell/header: type + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-percent: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -744,12 +740,12 @@ lexer: context [ :scan-string-multi ;-- T_STR_ALT :scan-word ;-- T_WORD :scan-file ;-- T_FILE - :scan-refinement ;-- T_REFINE + :scan-ref-issue ;-- T_REFINE :scan-binary ;-- T_BINARY :scan-char ;-- T_CHAR :scan-map-open ;-- T_MAP_OP :scan-construct ;-- T_CONS_MK - :scan-issue ;-- T_ISSUE + :scan-ref-issue ;-- T_ISSUE :scan-percent ;-- T_PERCENT :scan-integer ;-- T_INTEGER :scan-float ;-- T_FLOAT @@ -818,9 +814,9 @@ lexer: context [ do-scan: as scanner! scanners/index do-scan lex start + offset p flags - lex/in-len <= 1 + lex/in-len <= 0 ] - + assert zero? lex/in-len ] scan: func [ From d5ab838deaf1cf4e31f8fb7f15cb6ee239b2b218 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 15 Oct 2019 20:52:21 +0200 Subject: [PATCH 0258/3432] FEAT: escaped char handling code refactoring. --- runtime/lexer.reds | 221 +++++++++++++++++++++++---------------------- 1 file changed, 115 insertions(+), 106 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e6224e8473..91b06459d0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -77,6 +77,12 @@ lexer: context [ 0000000000000000000000000000000000000000000000000000000000000000 00000000000000 } + + ;-- Bit-array for BDELNPTbdelnpt + char-names-1st: #{0000000000000000345011003450110000000000000000000000000000000000} + + ;-- Bit-array for /-~^{}" + char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL @@ -273,6 +279,86 @@ lexer: context [ s/tail: s/offset + items ] ] + + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] return: [integer!] + /local + p [byte-ptr!] + src [byte-ptr!] + word [c-string!] + len [integer!] + c [integer!] + pos [integer!] + pow [integer!] + index [integer!] + class [integer!] + skip [integer!] + res [integer!] + cp [byte!] + bit [byte!] + ][ + either s/1 = #"(" [ ;-- note: #"^(" not allowed + c: as-integer s/2 + pos: c >>> 3 + 1 + bit: as-byte 1 << (c and 7) + either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char + p: s + 1 + c: 0 + cp: as byte! 0 + pow: 0 + while [any [p/1 <> #")" p < e]][ + if p/1 <> #"0" [ + index: 1 + as-integer p/1 + class: lex-classes/index + switch class [ + C_DIGIT [cp: p/1 - #"0"] + C_ALPHAX [cp: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cp: cp + 10] + default [throw LEX_ERROR] + ] + c: c + ((as-integer cp) << pow) + ] + pow: pow + 4 + p: p + 1 + ] + if any [p = e p/1 <> #")"][throw LEX_ERROR] + ][ ;-- named escaped char + cp: s/2 + if cp < #"a" [cp: cp or #"^(20)"] + src: s + 2 + word: switch cp [ + #"n" [c: 00h skip: 4 "ull"] + #"b" [c: 08h skip: 4 "ack"] + #"t" [c: 09h skip: 3 "ab" ] + #"l" [c: 0Ah skip: 4 "ine"] + #"p" [c: 0Ch skip: 4 "age"] + #"e" [c: 1Bh skip: 3 "sc" ] + #"d" [c: 7Fh skip: 3 "el" ] + default [assert false null] + ] + res: platform/strnicmp src as byte-ptr! word skip - 1 + if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] + ] + c + ][ + c: as-integer s/1 + pos: c >>> 3 + 1 + bit: as-byte 1 << (c and 7) + either char-special/pos and bit = null-byte [ ;-- "regular" escaped char + if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] + as-integer s/1 - #"@" + ][ ;-- escaped special char + as-integer switch s/1 [ + #"/" [#"^/"] + #"-" [#"^-"] + #"^"" [#"^""] + #"{" [#"{" ] + #"}" [#"}" ] + #"^^" [#"^^"] + #"~" [#"^~"] + default [assert false] + ] + ] + ] + ] scan-eof: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] ; /local @@ -315,9 +401,7 @@ lexer: context [ assert TYPE_OF(p) = TYPE_PAIR type: either s/1 = #")" [TYPE_PAREN][TYPE_BLOCK] - if p/y <> type [ - 0 ; error - ] + if p/y <> type [throw LEX_ERROR] len: (as-integer state/buf-tail - state/buffer) >> 4 new: state/buffer - 1 @@ -350,50 +434,52 @@ lexer: context [ str: string/make-at alloc-slot state len unit ser: GET_BUFFER(str) - - switch unit [ - UCS-1 [ - either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + + either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + switch unit [ + UCS-1 [ copy-memory as byte-ptr! ser/offset s len ser/tail: as cell! (as byte-ptr! ser/offset) + len - ][ ;-- with escape sequence(s) - 0 ] - ] - UCS-2 [ - either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + UCS-2 [ cp: 0 p: as byte-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp - if cp = -1 [ - 0 ; throw error - ] + if cp = -1 [throw LEX_ERROR] p/1: as-byte cp and FFh p/2: as-byte cp >> 8 p: p + 2 ] - ][ - 0 ] - ] - UCS-4 [ - either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + UCS-4 [ cp: 0 p4: as int-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp - if cp = -1 [ - 0 ; throw error - ] + if cp = -1 [throw LEX_ERROR] p4/value: cp p4: p4 + 1 ] - ][ - 0 + ] + ] + ][ ;-- with escape sequence(s) + ;search the first UCS-2 or UCS-4 codepoint => unit + ;if UCS-2 string and UCS-4 char found => upgrade + switch unit [ + UCS-1 [ + p: ser/offset + while [s < e][ + c: s/1 + if c = #"^^" [c: as-byte scan-escaped-char s e] + p/value: c + ][ + 0 + ] ] ] ] + state/in-pos: e + 1 ;-- skip ending delimiter state/in-len: state/in-len - 1 ] @@ -426,7 +512,7 @@ lexer: context [ if type = TYPE_SET_WORD [ state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 + state/in-len: state/in-len - 1 ] ] @@ -442,98 +528,21 @@ lexer: context [ null ] - ;-- Bit-array for BDELNPTbdelnpt - char-names-1st: #{0000000000000000345011003450110000000000000000000000000000000000} - - ;-- Bit-array for /-~^{}" - char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} - scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local char [red-char!] - p [byte-ptr!] - src [byte-ptr!] - word [c-string!] len [integer!] c [integer!] - pos [integer!] - pow [integer!] - index [integer!] - class [integer!] - skip [integer!] - res [integer!] - cp [byte!] - bit [byte!] ][ assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] len: as-integer e - s if len = 2 [throw LEX_ERROR] ;-- #"" - either s/3 = #"^^" [ + c: either s/3 = #"^^" [ if len = 3 [throw LEX_ERROR] ;-- #"^" - either s/4 = #"(" [ ;-- note: #"^(" not allowed - c: as-integer s/5 - pos: c >>> 3 + 1 - bit: as-byte 1 << (c and 7) - either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char - p: s + 4 - c: 0 - cp: as byte! 0 - pow: 0 - while [any [p/1 <> #")" p < e]][ - if p/1 <> #"0" [ - index: 1 + as-integer p/1 - class: lex-classes/index - switch class [ - C_DIGIT [cp: p/1 - #"0"] - C_ALPHAX [cp: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cp: cp + 10] - default [throw LEX_ERROR] - ] - c: c + ((as-integer cp) << pow) - ] - pow: pow + 4 - p: p + 1 - ] - if any [p = e p/1 <> #")"][throw LEX_ERROR] - ][ ;-- named escaped char - cp: s/5 - if cp < #"a" [cp: cp or #"^(20)"] - src: s + 5 - word: switch cp [ - #"n" [c: 00h skip: 4 "ull"] - #"b" [c: 08h skip: 4 "ack"] - #"t" [c: 09h skip: 3 "ab" ] - #"l" [c: 0Ah skip: 4 "ine"] - #"p" [c: 0Ch skip: 4 "age"] - #"e" [c: 1Bh skip: 3 "sc" ] - #"d" [c: 7Fh skip: 3 "el" ] - default [assert false null] - ] - res: platform/strnicmp src as byte-ptr! word skip - 1 - if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] - ] - ][ - c: as-integer s/4 - pos: c >>> 3 + 1 - bit: as-byte 1 << (c and 7) - either char-special/pos and bit = null-byte [ ;-- "regular" escaped char - if any [s/4 < #"^(40)" #"^(5F)" < s/4][throw LEX_ERROR] - c: as-integer s/4 - #"@" - ][ ;-- escaped special char - c: as-integer switch s/4 [ - #"/" [#"^/"] - #"-" [#"^-"] - #"^"" [#"^""] - #"{" [#"{" ] - #"}" [#"}" ] - #"^^" [#"^^"] - #"~" [#"^~"] - default [assert false] - ] - ] - ] + scan-escaped-char s e ][ ;-- simple char - c: as-integer s/3 + as-integer s/3 ] char: as red-char! alloc-slot state char/header: TYPE_CHAR From e4b9bf8943b278a48366a3561772b711dd644416 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 15 Oct 2019 20:57:31 +0200 Subject: [PATCH 0259/3432] FIX: minor fixes to make the partial new code compile. --- runtime/lexer.reds | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 91b06459d0..2e699c12c3 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -421,11 +421,12 @@ lexer: context [ /local str [red-string!] ser [series!] + p [byte-ptr!] + p4 [int-ptr!] len [integer!] unit [integer!] cp [integer!] - p [byte-ptr!] - p4 [int-ptr!] + c [byte!] ][ s: s + 1 ;-- skip start delimiter len: as-integer e - s @@ -468,7 +469,7 @@ lexer: context [ ;if UCS-2 string and UCS-4 char found => upgrade switch unit [ UCS-1 [ - p: ser/offset + p: as byte-ptr! ser/offset while [s < e][ c: s/1 if c = #"^^" [c: as-byte scan-escaped-char s e] From c9696755b64f00a0274728e55ef4af160a9fd462 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 16 Oct 2019 11:41:30 +0800 Subject: [PATCH 0260/3432] FIX: libredRT can't work with `-d` flag --- system/utils/libRedRT-exports.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index f4d3beaa5b..33509d936a 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -376,7 +376,7 @@ red/natives/recycle* ;-- for view backend - red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/unicode/utf8-next-char red/ownership/bind red/integer/make-at red/string/load red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set + red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/unicode/utf8-next-char red/ownership/bind red/integer/make-at red/string/load red/string/load-at red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set ][ red/root red-block! red/object/path-parent cell! From a49aca8084dac6975dc44d96ae1ba2220d29ec31 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 16 Oct 2019 13:01:36 +0200 Subject: [PATCH 0261/3432] FEAT: supports loading escaped chars in strings. --- runtime/lexer.reds | 122 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 101 insertions(+), 21 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 2e699c12c3..402f8a4850 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -280,7 +280,7 @@ lexer: context [ ] ] - scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] return: [integer!] + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] src [byte-ptr!] @@ -293,7 +293,7 @@ lexer: context [ class [integer!] skip [integer!] res [integer!] - cp [byte!] + cb [byte!] bit [byte!] ][ either s/1 = #"(" [ ;-- note: #"^(" not allowed @@ -303,28 +303,29 @@ lexer: context [ either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char p: s + 1 c: 0 - cp: as byte! 0 + cb: as byte! 0 pow: 0 while [any [p/1 <> #")" p < e]][ if p/1 <> #"0" [ index: 1 + as-integer p/1 class: lex-classes/index switch class [ - C_DIGIT [cp: p/1 - #"0"] - C_ALPHAX [cp: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cp: cp + 10] + C_DIGIT [cb: p/1 - #"0"] + C_ALPHAX [cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cb: cb + 10] default [throw LEX_ERROR] ] - c: c + ((as-integer cp) << pow) + c: c + ((as-integer cb) << pow) ] pow: pow + 4 p: p + 1 ] if any [p = e p/1 <> #")"][throw LEX_ERROR] + p: p + 1 ;-- skip ) ][ ;-- named escaped char - cp: s/2 - if cp < #"a" [cp: cp or #"^(20)"] + cb: s/2 + if cb < #"a" [cb: cb or #"^(20)"] src: s + 2 - word: switch cp [ + word: switch cb [ #"n" [c: 00h skip: 4 "ull"] #"b" [c: 08h skip: 4 "ack"] #"t" [c: 09h skip: 3 "ab" ] @@ -336,13 +337,13 @@ lexer: context [ ] res: platform/strnicmp src as byte-ptr! word skip - 1 if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] + p: src + skip ] - c ][ c: as-integer s/1 pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) - either char-special/pos and bit = null-byte [ ;-- "regular" escaped char + c: either char-special/pos and bit = null-byte [ ;-- "regular" escaped char if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] as-integer s/1 - #"@" ][ ;-- escaped special char @@ -357,7 +358,10 @@ lexer: context [ default [assert false] ] ] + p: s + 1 ] + cp/value: c + p ] scan-eof: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -422,10 +426,14 @@ lexer: context [ str [red-string!] ser [series!] p [byte-ptr!] + pos [byte-ptr!] p4 [int-ptr!] len [integer!] unit [integer!] + index[integer!] + class[integer!] cp [integer!] + w? [logic!] c [byte!] ][ s: s + 1 ;-- skip start delimiter @@ -467,20 +475,91 @@ lexer: context [ ][ ;-- with escape sequence(s) ;search the first UCS-2 or UCS-4 codepoint => unit ;if UCS-2 string and UCS-4 char found => upgrade + if unit < UCS-4 [ + p: s + while [p < e][ + if p/1 = #"^^" [ + p: p + 1 + if all [p < e p/1 = #"("][ + p: p + 1 + pos: p + w?: no + while [all [p < e p/1 <> #")"]][ + index: 1 + p/1 + class: lex-classes/index + switch class [ + C_DIGIT C_ZERO C_ALPHAX [0] + default [w?: yes] + ] + p: p + 1 + ] + unless w? [ + len: as-integer p - pos + if unit = UCS-1 [ + if len > 2 [ + ser: unicode/Latin1-to-UCS2 ser + unit: UCS-2 + ] + if len > 4 [ + ser: unicode/Latin1-to-UCS4 ser + unit: UCS-4 + ] + ] + if all [unit = UCS-2 len > 4][ + ser: unicode/UCS2-to-UCS4 ser + unit: UCS-4 + ] + ] + ] + ] + p: p + 1 + ] + ] + switch unit [ UCS-1 [ p: as byte-ptr! ser/offset while [s < e][ - c: s/1 - if c = #"^^" [c: as-byte scan-escaped-char s e] - p/value: c - ][ - 0 + either s/1 = #"^^" [ + s: scan-escaped-char s e :cp + p/value: as-byte cp + ][ + p/value: s/1 + s: s + 1 + ] + ] + ] + UCS-2 [ + cp: 0 + p: as byte-ptr! ser/offset + while [s < e][ + s: either s/1 = #"^^" [ + scan-escaped-char s e :cp + ][ + decode-utf8-char s :cp + ] + if cp = -1 [throw LEX_ERROR] + p/1: as-byte cp and FFh + p/2: as-byte cp >> 8 + p: p + 2 + ] + ] + UCS-4 [ + cp: 0 + p4: as int-ptr! ser/offset + while [s < e][ + s: either s/1 = #"^^" [ + scan-escaped-char s e :cp + ][ + decode-utf8-char s :cp + ] + if cp = -1 [throw LEX_ERROR] + p4/value: cp + p4: p4 + 1 ] ] ] ] - state/in-pos: e + 1 ;-- skip ending delimiter state/in-len: state/in-len - 1 ] @@ -504,7 +583,7 @@ lexer: context [ true [throw LEX_ERROR] ] ] - if flags and C_FLAG_QUOTE <> 0 [ + if flags and C_FLAG_QUOTE <> 0 [ ;@@ remove this check? if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] ] cell: alloc-slot state @@ -539,11 +618,12 @@ lexer: context [ len: as-integer e - s if len = 2 [throw LEX_ERROR] ;-- #"" - c: either s/3 = #"^^" [ + either s/3 = #"^^" [ if len = 3 [throw LEX_ERROR] ;-- #"^" - scan-escaped-char s e + c: -1 + scan-escaped-char s e :c ][ ;-- simple char - as-integer s/3 + c: as-integer s/3 ] char: as red-char! alloc-slot state char/header: TYPE_CHAR From 0c42345df4f2e3130c960d5d755f6fc7db43f7ce Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 16 Oct 2019 20:23:23 +0200 Subject: [PATCH 0262/3432] FEAT: makes string/make-at function set the unit field in the series. Otherwise, passing the unit without it been set in the new series is confusing... --- runtime/allocator.reds | 12 ++++++++++++ runtime/datatypes/string.reds | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index 84370a84a3..e508bfb796 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -1041,6 +1041,18 @@ alloc-bytes: func [ alloc-series size 1 0 ;-- optimize by default for tail insertion ] +;------------------------------------------- +;-- Wrapper on alloc-series for codepoints buffer allocation +;------------------------------------------- +alloc-codepoints: func [ + size [integer!] ;-- number of codepoints slots to preallocate + unit [integer!] + return: [int-ptr!] ;-- return a new node pointer (pointing to the newly allocated series buffer) +][ + if zero? size [size: 16 >> (unit >> 1)] + alloc-series size unit 0 ;-- optimize by default for tail insertion +] + ;------------------------------------------- ;-- Wrapper on alloc-series for byte-filled buffer allocation ;------------------------------------------- diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index d480e8c547..204afb6b14 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -1123,7 +1123,7 @@ string: context [ make-at: func [ slot [red-value!] - size [integer!] ;-- number of bytes to pre-allocate + size [integer!] ;-- number of codepoints to pre-allocate unit [integer!] return: [red-string!] /local @@ -1132,7 +1132,7 @@ string: context [ str: as red-string! slot str/header: TYPE_UNSET str/head: 0 - str/node: alloc-bytes size << (unit >> 1) + str/node: alloc-codepoints size unit str/cache: null str/header: TYPE_STRING str From 0a9fe44567103e905b12de72abd19b656b33ea53 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 16 Oct 2019 20:24:26 +0200 Subject: [PATCH 0263/3432] FIX: numerous fixes and improvements for scanning string! and char! with escaped characters. --- runtime/lexer.reds | 133 +++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 65 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 402f8a4850..b20d76d5fb 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -288,7 +288,6 @@ lexer: context [ len [integer!] c [integer!] pos [integer!] - pow [integer!] index [integer!] class [integer!] skip [integer!] @@ -300,13 +299,12 @@ lexer: context [ c: as-integer s/2 pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) - either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char + either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char @@ "e" as 1st! p: s + 1 c: 0 cb: as byte! 0 - pow: 0 - while [any [p/1 <> #")" p < e]][ - if p/1 <> #"0" [ + while [all [p/1 <> #")" p < e]][ + either p/1 = #"0" [c: c << 4][ index: 1 + as-integer p/1 class: lex-classes/index switch class [ @@ -314,9 +312,8 @@ lexer: context [ C_ALPHAX [cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cb: cb + 10] default [throw LEX_ERROR] ] - c: c + ((as-integer cb) << pow) + c: c << 4 + as-integer cb ] - pow: pow + 4 p: p + 1 ] if any [p = e p/1 <> #")"][throw LEX_ERROR] @@ -347,15 +344,15 @@ lexer: context [ if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] as-integer s/1 - #"@" ][ ;-- escaped special char - as-integer switch s/1 [ - #"/" [#"^/"] - #"-" [#"^-"] - #"^"" [#"^""] - #"{" [#"{" ] - #"}" [#"}" ] - #"^^" [#"^^"] - #"~" [#"^~"] - default [assert false] + switch s/1 [ + #"/" [0Ah] + #"-" [09h] + #"^"" [22h] + #"{" [7Bh] + #"}" [7Dh] + #"^^" [5Eh] + #"~" [7Fh] + default [assert false 0] ] ] p: s + 1 @@ -423,35 +420,33 @@ lexer: context [ scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - str [red-string!] - ser [series!] - p [byte-ptr!] - pos [byte-ptr!] - p4 [int-ptr!] - len [integer!] - unit [integer!] - index[integer!] - class[integer!] - cp [integer!] - w? [logic!] - c [byte!] + str [red-string!] + ser [series!] + p [byte-ptr!] + pos [byte-ptr!] + p4 [int-ptr!] + len [integer!] + unit [integer!] + index [integer!] + class [integer!] + digits [integer!] + extra [integer!] + cp [integer!] + w? [logic!] + c [byte!] ][ s: s + 1 ;-- skip start delimiter len: as-integer e - s unit: 1 << (flags >>> 30) if unit > 4 [unit: 4] - str: string/make-at alloc-slot state len unit - ser: GET_BUFFER(str) - either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + str: string/make-at alloc-slot state len unit + ser: GET_BUFFER(str) switch unit [ - UCS-1 [ - copy-memory as byte-ptr! ser/offset s len - ser/tail: as cell! (as byte-ptr! ser/offset) + len - ] + UCS-1 [copy-memory as byte-ptr! ser/offset s len] UCS-2 [ - cp: 0 + cp: -1 p: as byte-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp @@ -462,7 +457,7 @@ lexer: context [ ] ] UCS-4 [ - cp: 0 + cp: -1 p4: as int-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp @@ -472,69 +467,72 @@ lexer: context [ ] ] ] + ser/tail: as cell! (as byte-ptr! ser/offset) + (len << (unit >> 1)) ][ ;-- with escape sequence(s) - ;search the first UCS-2 or UCS-4 codepoint => unit - ;if UCS-2 string and UCS-4 char found => upgrade + ;-- prescan the string for determining unit and accurate final codepoints count + extra: 0 ;-- count extra bytes used by escape sequences if unit < UCS-4 [ p: s + ;-- check if any escaped codepoint requires higher unit while [p < e][ - if p/1 = #"^^" [ + either p/1 = #"^^" [ p: p + 1 - if all [p < e p/1 = #"("][ + either all [p + 1 < e p/1 = #"("][ p: p + 1 pos: p w?: no - while [all [p < e p/1 <> #")"]][ - index: 1 + p/1 + while [all [not w? p < e p/1 <> #")"]][ + index: 1 + as-integer p/1 class: lex-classes/index switch class [ C_DIGIT C_ZERO C_ALPHAX [0] - default [w?: yes] + default [w?: yes] ;-- early exit if not an hex value ] p: p + 1 ] + if all [w? p < e p/1 <> #")"][ ;-- finish counting characters if early exit + while [all [p < e p/1 <> #")"]][p: p + 1] + ] + digits: as-integer p - pos + extra: extra + digits + 2 ;-- account for parens + content unless w? [ - len: as-integer p - pos if unit = UCS-1 [ - if len > 2 [ - ser: unicode/Latin1-to-UCS2 ser - unit: UCS-2 - ] - if len > 4 [ - ser: unicode/Latin1-to-UCS4 ser - unit: UCS-4 - ] - ] - if all [unit = UCS-2 len > 4][ - ser: unicode/UCS2-to-UCS4 ser - unit: UCS-4 + if digits > 2 [unit: UCS-2] + if digits > 4 [unit: UCS-4] ] + if all [unit = UCS-2 digits > 4][unit: UCS-4] ] + ][ + extra: extra + 1 + p: p + 1 ] - ] - p: p + 1 + ][p: p + 1] ] ] + str: string/make-at alloc-slot state len - extra unit + ser: GET_BUFFER(str) switch unit [ UCS-1 [ p: as byte-ptr! ser/offset while [s < e][ either s/1 = #"^^" [ - s: scan-escaped-char s e :cp + s: scan-escaped-char s + 1 e :cp p/value: as-byte cp ][ p/value: s/1 s: s + 1 ] + p: p + 1 ] + ser/tail: as cell! p ] UCS-2 [ - cp: 0 + cp: -1 p: as byte-ptr! ser/offset while [s < e][ s: either s/1 = #"^^" [ - scan-escaped-char s e :cp + scan-escaped-char s + 1 e :cp ][ decode-utf8-char s :cp ] @@ -543,13 +541,14 @@ lexer: context [ p/2: as-byte cp >> 8 p: p + 2 ] + ser/tail: as cell! p ] UCS-4 [ - cp: 0 + cp: -1 p4: as int-ptr! ser/offset while [s < e][ s: either s/1 = #"^^" [ - scan-escaped-char s e :cp + scan-escaped-char s + 1 e :cp ][ decode-utf8-char s :cp ] @@ -557,8 +556,10 @@ lexer: context [ p4/value: cp p4: p4 + 1 ] + ser/tail: as cell! p4 ] ] + assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail ] state/in-pos: e + 1 ;-- skip ending delimiter state/in-len: state/in-len - 1 @@ -621,10 +622,12 @@ lexer: context [ either s/3 = #"^^" [ if len = 3 [throw LEX_ERROR] ;-- #"^" c: -1 - scan-escaped-char s e :c + scan-escaped-char s + 3 e :c ][ ;-- simple char c: as-integer s/3 ] + if c > 0010FFFFh [throw LEX_ERROR] + char: as red-char! alloc-slot state char/header: TYPE_CHAR char/value: c From d7ad22623695d37137d656be4a4fbb2253bf5708 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 16 Oct 2019 22:44:45 +0200 Subject: [PATCH 0264/3432] FIX: fixes a regression in escaped char decoding. --- runtime/lexer.reds | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b20d76d5fb..8718a4377d 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -340,11 +340,11 @@ lexer: context [ c: as-integer s/1 pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) - c: either char-special/pos and bit = null-byte [ ;-- "regular" escaped char + either char-special/pos and bit = null-byte [ ;-- "regular" escaped char if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] - as-integer s/1 - #"@" + c: as-integer s/1 - #"@" ][ ;-- escaped special char - switch s/1 [ + c: switch s/1 [ #"/" [0Ah] #"-" [09h] #"^"" [22h] From 2c805f7e0d5e562304c3f1d1a8f2f84b819c29e4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 16 Oct 2019 23:53:30 +0200 Subject: [PATCH 0265/3432] FEAT: small simplification of scanning state tracking. --- runtime/lexer.reds | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8718a4377d..85c7ab3806 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -238,7 +238,7 @@ lexer: context [ buf-tail [red-value!] buf-slots [integer!] input [byte-ptr!] - in-len [integer!] + in-end [byte-ptr!] in-pos [byte-ptr!] err [integer!] ] @@ -386,7 +386,6 @@ lexer: context [ state/buffer: state/buf-tail state/in-pos: e + 1 ;-- skip delimiter - state/in-len: state/in-len - 1 ] scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -415,7 +414,6 @@ lexer: context [ assert ser/offset <= ser/tail state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 ] scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -562,7 +560,6 @@ lexer: context [ assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail ] state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 ] scan-string-multi: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -591,10 +588,7 @@ lexer: context [ word/make-at symbol/make-alt-utf8 s as-integer e - s cell cell/header: type - if type = TYPE_SET_WORD [ - state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 - ] + if type = TYPE_SET_WORD [state/in-pos: e + 1] ;-- skip ending delimiter ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -633,7 +627,6 @@ lexer: context [ char/value: c state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 ] scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -672,7 +665,6 @@ lexer: context [ fl/value: fl/value / 100.0 state/in-pos: e + 1 ;-- skip ending delimiter - state/in-len: state/in-len - 1 ] scan-integer: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -879,7 +871,7 @@ lexer: context [ start: p offset: 0 - loop lex/in-len [ + loop as-integer lex/in-end - p [ cp: 1 + as-integer p/value class: lex-classes/cp flags: class and FFFFFF00h or flags @@ -900,16 +892,15 @@ lexer: context [ index: state * 33 + C_EOF + 1 state: as-integer transitions/index ] - lex/in-len: lex/in-len - as-integer (p - start) lex/in-pos: p index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags - lex/in-len <= 0 + lex/in-pos >= lex/in-end ] - assert zero? lex/in-len + assert lex/in-pos = lex/in-end ] scan: func [ @@ -929,7 +920,7 @@ lexer: context [ state/buf-tail: stash state/buf-slots: stash-size ;TBD: support dyn buffer case state/input: src - state/in-len: len + state/in-end: src + len state/in-pos: src state/err: 0 From 2d01e3a5a8fd87b57b12316f0ca45fa845012296 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 17 Oct 2019 09:51:23 +0200 Subject: [PATCH 0266/3432] FEAT: merges T_STR_ALT state into T_STRING. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 15750 -> 15694 bytes docs/lexer/lexer-states.txt | 3 +- runtime/lexer-transitions.reds | 65 ++++++++++++++++----------------- runtime/lexer.reds | 7 ---- utils/generate-lexer-table.red | 41 ++++++++++----------- 6 files changed, 54 insertions(+), 64 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index f7fecf78f5..6ddee45ac4 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -3,7 +3,7 @@ S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_ S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STR_ALT;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_FILE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index a19d3e507c8912b38d2c1e9f0346fac16bc0cc16..f10fd862c97112bc87690b91de7ff65cc7e10b55 100644 GIT binary patch delta 8235 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 ZPW|00G$0WBZx7r++N+7spMW0S{C`wKdQ$)Z delta 8312 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 058901a4a1..2ea99259ff 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -48,7 +48,6 @@ T_BLK_CL T_PAR_OP T_PAR_CL T_STRING -T_STR_ALT T_WORD T_FILE T_REFINE @@ -147,7 +146,7 @@ S_START->dbl-quote->S_LINE_STR->not("^"|dbl-quote)->S_LINE_STR S_START->"{"->S_M_STRING->not("^"|"}")->S_M_STRING \->"^"->S_SKIP_MSTR->*->S_M_STRING - \->"}"->T_STR_ALT + \->"}"->T_STRING S_START->"/"->S_SLASH->not(delimit1)->S_SLASH \->delimit1->T_REFINE diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 2f642aa39d..4c107b6a15 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -51,7 +51,6 @@ Red/System [ T_PAR_OP T_PAR_CL T_STRING - T_STR_ALT T_WORD T_FILE T_REFINE @@ -77,43 +76,43 @@ Red/System [ 2A01000101010101010101010101010101010101010101010101010101010101 2B2A020202020202020202023002020202020202020202020202020202020302 022B2B0202020202020202020202020202020202020202020202020202020202 -02022B2A04040404040404040431040404040404040404040404040404040404 +02022B2A04040404040404040430040404040404040404040404040404040404 0504042B2B040404040404040404040404040404040404040404040404040404 -040404042B2A3232070732323232323207070732070707070707070707323207 -07070707072B3233330707333333333333070707330707070707070707073333 -0707070807072B33070707070707070707070707070707070707070707070707 -070707070707072B2B3434090934343434343434090909090909090909090909 -34340909090909092B34393910100F2B372B2B0B0D10102B10101010102B2B10 -2B39391010101010102B390B0B0B0B2B2B2B2B2B352B2B2B2B2B2B0B2B2B2B2B +040404042B2A3131070731313131313107070731070707070707070707313107 +07070707072B3132320707323232323232070707320707070707070707073232 +0707070807072B32070707070707070707070707070707070707070707070707 +070707070707072B2B3333090933333333333333090909090909090909090909 +33330909090909092B33383810100F2B362B2B0B0D10102B10101010102B2B10 +2B38381010101010102B380B0B0B0B2B2B2B2B2B342B2B2B2B2B2B0B2B2B2B2B 2B2B0C2B2B2B2B2B2B2B2B2B0C0B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D360D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0E0D0D2B360D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0D0D0D0D2B2B0F0F0F0F0F380F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F2B2B39391010393939393939391010101010 -1010101010101039391010101010102B393B3B11113B3B3B3B3B3B3B0A111719 -132B162B3B2B3A2B3B28122B2B2B2B2B2B3B3C3C13133C3C3C3C3C3C3C14132B -19132B3C2B3C2B3A2B3C2B2B2B2B2B2B2B2B3C3C3C13133C3C3C3C3C3C3C192B -3C2B132B3C2B3C2B3A2B2B2B152B2B2B2B2B2B3C3C3C3C3C3C3C3C3C3C3C3C14 -3C3C1414143C3C3C143C3C3C3C143C143C14142B2A3D3D15153D3D3D3D3D3D3D -2B2B3D2B2B2B3D2B3D2B2B2B2B2B152B2B2B2B2B2B3D3E3E16163E3E3E3E3E3E -3E16163E16161616163E163E163E3E163E163E16162B2A2B2B18182B2B2B2B2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B4040181840404040 -4040402B2B182B2B2B402B402B2B2B402B182B2B2B2B2B2B2A2B2B1A1A2B2B2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3F3F1A1A3F3F -3F3F3F3F3F2B2B2B2B1A2B2B2B3F2B2B2B3F2B1A2B2B2B2B2B2B3F2B2B1C1C2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B41411C1C -41414141414141411C2B2B2B2B412B412B2B2B412B1D2B2B2B2B2B2B2A41411D -1D41414141414141411D2B2B2B2B412B412B2B2B412B2B2B2B2B2B2B2B2A3232 -1F1F323232323232321F1F321F1F1F1F1F2B321F1F32321F1F1F1F1F1F2B321F -1F1F1F1F1F1F1F1F1F201F1F221F1F1F1F1F1F421F1F1F1F1F1F1F1F1F1F2B2B +0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D350D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0E0D0D2B350D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D +0D0D0D0D0D0D0D0D0D0D0D0D0D2B2B0F0F0F0F0F370F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F2B2B38381010383838383838381010101010 +1010101010101038381010101010102B383A3A11113A3A3A3A3A3A3A0A111719 +132B162B3A2B392B3A28122B2B2B2B2B2B3A3B3B13133B3B3B3B3B3B3B14132B +19132B3B2B3B2B392B3B2B2B2B2B2B2B2B2B3B3B3B13133B3B3B3B3B3B3B192B +3B2B132B3B2B3B2B392B2B2B152B2B2B2B2B2B3B3B3B3B3B3B3B3B3B3B3B3B14 +3B3B1414143B3B3B143B3B3B3B143B143B14142B2A3C3C15153C3C3C3C3C3C3C +2B2B3C2B2B2B3C2B3C2B2B2B2B2B152B2B2B2B2B2B3C3D3D16163D3D3D3D3D3D +3D16163D16161616163D163D163D3D163D163D16162B2A2B2B18182B2B2B2B2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3F3F18183F3F3F3F +3F3F3F2B2B182B2B2B3F2B3F2B2B2B3F2B182B2B2B2B2B2B2A2B2B1A1A2B2B2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3E3E1A1A3E3E +3E3E3E3E3E2B2B2B2B1A2B2B2B3E2B2B2B3E2B1A2B2B2B2B2B2B3E2B2B1C1C2B +2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B40401C1C +40404040404040401C2B2B2B2B402B402B2B2B402B1D2B2B2B2B2B2B2A40401D +1D40404040404040401D2B2B2B2B402B402B2B2B402B2B2B2B2B2B2B2B2A3131 +1F1F313131313131311F1F311F1F1F1F1F2B311F1F31311F1F1F1F1F1F2B311F +1F1F1F1F1F1F1F1F1F201F1F221F1F1F1F1F1F411F1F1F1F1F1F1F1F1F1F2B2B 202020202020202020201F20202020202020202020202020202020202120202B 2B20202020202020202020202020202020202020202020202020202020202020 2B2B222222222222222222222222221F22222222222222222222222222222222 222B2B2222222222222222222222222222222222222222222222222222222222 22222B2B25251111252525252525252B2B2525252525252B252B252525252525 -2B25252B3232322525323232323232322B2526252525453225252B2B3228251C -252525252B32323227273232323232323227272727272727322B272727322727 -27272727272B324343272743434343434343272B272727272743432B27434327 -272B272B27272B4344442828444444444444442B2B2B2828284444442B282B44 -2B282B282B28282B44 +2B25252B3131312525313131313131312B2526252525443125252B2B3128251C +252525252B31313127273131313131313127272727272727312B272727312727 +27272727272B314242272742424242424242272B272727272742422B27424227 +272B272B27272B4243432828434343434343432B2B2B2828284343432B282B43 +2B282B282B28282B43 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 85c7ab3806..df90bc3ffc 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -562,12 +562,6 @@ lexer: context [ state/in-pos: e + 1 ;-- skip ending delimiter ] - scan-string-multi: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null - ] - scan-word: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] @@ -822,7 +816,6 @@ lexer: context [ :scan-block-open ;-- T_PAR_OP :scan-block-close ;-- T_PAR_CL :scan-string ;-- T_STRING - :scan-string-multi ;-- T_STR_ALT :scan-word ;-- T_WORD :scan-file ;-- T_FILE :scan-ref-issue ;-- T_REFINE diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 8a5a940f42..7895c6ca2c 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -61,27 +61,26 @@ context [ T_PAR_OP ;-- 46 T_PAR_CL ;-- 47 T_STRING ;-- 48 - T_STR_ALT ;-- 49 - T_WORD ;-- 50 - T_FILE ;-- 51 - T_REFINE ;-- 52 - T_BINARY ;-- 53 - T_CHAR ;-- 54 - T_MAP_OP ;-- 55 - T_CONS_MK ;-- 56 - T_ISSUE ;-- 57 - T_PERCENT ;-- 58 - T_INTEGER ;-- 59 - T_FLOAT ;-- 60 - T_TUPLE ;-- 61 - T_DATE ;-- 62 - T_PAIR ;-- 63 - T_TIME ;-- 64 - T_MONEY ;-- 65 - T_TAG ;-- 66 - T_URL ;-- 67 - T_EMAIL ;-- 68 - T_PATH ;-- 69 + T_WORD ;-- 49 + T_FILE ;-- 50 + T_REFINE ;-- 51 + T_BINARY ;-- 52 + T_CHAR ;-- 53 + T_MAP_OP ;-- 54 + T_CONS_MK ;-- 55 + T_ISSUE ;-- 56 + T_PERCENT ;-- 57 + T_INTEGER ;-- 58 + T_FLOAT ;-- 59 + T_TUPLE ;-- 60 + T_DATE ;-- 61 + T_PAIR ;-- 62 + T_TIME ;-- 63 + T_MONEY ;-- 64 + T_TAG ;-- 65 + T_URL ;-- 66 + T_EMAIL ;-- 67 + T_PATH ;-- 68 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 9fbe24d6593a47c0150d9496d51f8a2a5736600b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 17 Oct 2019 15:08:14 +0800 Subject: [PATCH 0267/3432] FEAT: code refactoring for make-view --- modules/view/backends/gtk3/events.reds | 29 +- modules/view/backends/gtk3/gtk.reds | 48 +- modules/view/backends/gtk3/gui.reds | 682 +++++++++------------- modules/view/backends/gtk3/tab-panel.reds | 135 +++-- modules/view/view.red | 4 +- 5 files changed, 421 insertions(+), 477 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 43dee52f4d..be90cc471a 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -626,17 +626,19 @@ connect-notify-events: function [ connect-widget-events: function [ widget [handle!] + values [red-value!] sym [integer!] - evbox [handle!] /local + evbox [handle!] buffer [handle!] ][ + evbox: get-face-evbox widget values sym ;; register red mouse, key event functions - either sym = text [ - connect-common-events evbox widget - ][ - connect-common-events widget widget - ] + connect-common-events evbox widget + connect-notify-events evbox widget + + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes case [ sym = check [ @@ -655,13 +657,9 @@ connect-widget-events: function [ ] sym = base [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -681,8 +679,6 @@ connect-widget-events: function [ sym = text [0] sym = field [ gobj_signal_connect(widget "changed" :field-changed widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -698,8 +694,6 @@ connect-widget-events: function [ g_object_set [widget "populate-all" yes widget] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -708,8 +702,6 @@ connect-widget-events: function [ ] sym = panel [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes ] sym = tab-panel [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] @@ -730,9 +722,4 @@ connect-widget-events: function [ ] true [0] ] - either sym = text [ - connect-notify-events evbox widget - ][ - connect-notify-events widget widget - ] ] \ No newline at end of file diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 4599ac4c2e..304f2e61f9 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -621,6 +621,11 @@ GPtrArray!: alias struct! [ len [integer!] return: [c-string!] ] + g_type_check_instance_is_a: "g_type_check_instance_is_a" [ + handle [handle!] + gtype [integer!] + return: [logic!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ @@ -813,8 +818,8 @@ GPtrArray!: alias struct! [ ] g_strsplit: "g_strsplit" [ str [c-string!] - delim [c-string!] - tokens [integer!] + delim [c-string!] + tokens [integer!] return: [handle!] ] g_strsplit_set: "g_strsplit_set" [ @@ -1503,53 +1508,56 @@ GPtrArray!: alias struct! [ return: [handle!] ] gtk_box_pack_start: "gtk_box_pack_start" [ - box [handle!] + box [handle!] widget [handle!] expand [logic!] - fill [logic!] + fill [logic!] padding [integer!] ] gtk_fixed_new: "gtk_fixed_new" [ return: [handle!] ] gtk_fixed_put: "gtk_fixed_put" [ - fixed [handle!] + fixed [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ] gtk_fixed_move: "gtk_fixed_move" [ - fixed [handle!] + fixed [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] + ] + gtk_layout_get_type: "gtk_layout_get_type" [ + return: [integer!] ] gtk_layout_new: "gtk_layout_new" [ - hadj [handle!] - vadj [handle!] + hadj [handle!] + vadj [handle!] return: [handle!] ] gtk_layout_put: "gtk_layout_put" [ layout [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ] gtk_layout_move: "gtk_layout_move" [ layout [handle!] widget [handle!] - x [integer!] - y [integer!] + x [integer!] + y [integer!] ] gtk_layout_set_size: "gtk_layout_set_size" [ layout [handle!] - w [integer!] - h [integer!] + w [integer!] + h [integer!] ] gtk_layout_get_size: "gtk_layout_get_size" [ layout [handle!] - w [int-ptr!] - h [int-ptr!] + w [int-ptr!] + h [int-ptr!] ] gtk_layout_get_bin_window: "gtk_layout_get_bin_window" [ layout [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 0ad7549521..799437464d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -12,10 +12,6 @@ Red/System [ #define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] #define GET-CURSOR(s) [g_object_get_qdata s cursor-id] -#define SET-EVENT-BOX(s d) [g_object_set_qdata s event-box-id d] -#define GET-EVENT-BOX(s) [g_object_get_qdata s event-box-id] -#define SET-CONTAINER(s d) [g_object_set_qdata s gtk-container-id d] -#define GET-CONTAINER(s) [g_object_get_qdata s gtk-container-id] #define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] #define GET-RESIZING(s) [g_object_get_qdata s resizing-id] #define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] @@ -53,8 +49,7 @@ red-face-id2: g_quark_from_string "red-face-id2" red-face-id3: g_quark_from_string "red-face-id3" red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" -event-box-id: g_quark_from_string "event-box-id" ;-- widget's layout-widget -gtk-container-id: g_quark_from_string "gtk-container-id" ;-- widget's parent-widget +win-layout-id: g_quark_from_string "win-layout-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" @@ -85,7 +80,6 @@ log-pixels-y: 0 screen-size-x: 0 screen-size-y: 0 - get-face-obj: func [ handle [handle!] return: [red-object!] @@ -153,17 +147,17 @@ face-handle?: func [ ] get-face-handle: func [ - face [red-object!] - return: [integer!] + face [red-object!] + return: [handle!] /local - state [red-block!] - int [red-integer!] + state [red-block!] + int [red-integer!] ][ state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE assert TYPE_OF(state) = TYPE_BLOCK int: as red-integer! block/rs-head state assert TYPE_OF(int) = TYPE_HANDLE - int/value + as handle! int/value ] get-widget-symbol: func [ @@ -174,10 +168,8 @@ get-widget-symbol: func [ values [red-value!] ][ values: get-face-values widget - either null? values [symbol/resolve popup][ - type: as red-word! values + FACE_OBJ_TYPE - symbol/resolve type/symbol - ] + type: as red-word! values + FACE_OBJ_TYPE + symbol/resolve type/symbol ] get-widget-data: func [ @@ -190,33 +182,159 @@ get-widget-data: func [ as red-block! values + FACE_OBJ_DATA ] -;; GTK basic widget is often embedded in some super widget in order to be contained in some layout widget -event-box?: func [ +get-face-parent: func [ widget [handle!] + values [red-value!] + sym [integer!] return: [handle!] /local - evbox [handle!] + parent [red-object!] ][ - evbox: g_object_get_qdata widget event-box-id - if null? evbox [evbox: widget] - return evbox + if sym = window [return null] + parent: as red-object! values + FACE_OBJ_PARENT + get-face-handle parent ] -gtk-layout?: func [ - type [integer!] +get-face-evbox: func [ + widget [handle!] + values [red-value!] + sym [integer!] + return: [handle!] +][ + case [ + sym = text [ + gtk_widget_get_parent widget + ] + true [ + widget + ] + ] +] + +get-face-layout: func [ + widget [handle!] + values [red-value!] + sym [integer!] + return: [handle!] +][ + case [ + any [ + sym = rich-text + sym = text + sym = area + sym = text-list + ][ + gtk_widget_get_parent widget + ] + true [ + widget + ] + ] +] + +set-widget-child: func [ + parent [handle!] + widget [handle!] + offset [red-pair!] return: [logic!] + /local + sym [integer!] + x [integer!] + y [integer!] + cvalues [red-value!] + ctype [red-word!] + csym [integer!] + clayout [handle!] + playout [handle!] +][ + sym: get-widget-symbol parent + either TYPE_OF(offset) = TYPE_PAIR [ + x: offset/x + y: offset/y + ][ + x: 0 + y: 0 + ] + cvalues: get-face-values widget + ctype: as red-word! cvalues + FACE_OBJ_TYPE + csym: symbol/resolve ctype/symbol + clayout: get-face-layout widget cvalues csym + case [ + sym = window [ + playout: g_object_get_qdata parent win-layout-id + gtk_layout_put playout clayout x y + true + ] + sym = group-box [ + playout: gtk_bin_get_child parent + gtk_layout_put playout clayout x y + true + ] + any [ + sym = base + sym = rich-text + sym = panel + ][ + gtk_layout_put parent clayout x y + true + ] + sym = tab-panel [ + append-tab parent clayout + ] + true [ + false + ] + ] +] + +set-widget-size: func [ + widget [handle!] + size [red-pair!] ][ - any[type = rich-text type = panel type = base] + either g_type_check_instance_is_a widget gtk_layout_get_type [ + gtk_layout_set_size widget size/x size/y + ][ + gtk_widget_set_size_request widget size/x size/y + ] +] + +set-widget-offset: func [ + parent [handle!] + widget [handle!] + x [integer!] + y [integer!] +][ + if g_type_check_instance_is_a parent gtk_layout_get_type [ + gtk_layout_move parent widget x y + gtk_widget_queue_draw widget + ] ] -container-type?: func [ +set-widget-child-offset: func [ + parent [handle!] + widget [handle!] + pos [red-pair!] type [integer!] - return: [logic!] + /local + layout [handle!] + values [red-value!] + ntype [red-word!] + sym [integer!] ][ - ;;; See events.reds to see the comment above - ; Option I: any[type = rich-text type = panel type = base] - ; Option II: - type = rich-text + either type = window [ + gtk_window_move widget pos/x pos/y + ][ + values: get-face-values widget + ntype: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve ntype/symbol + layout: get-face-layout widget values sym + if layout <> widget [ + set-widget-offset layout widget 0 0 + ] + unless null? parent [ + set-widget-offset parent layout pos/x pos/y + ] + ] ] set-view-no-wait: func [ @@ -366,94 +484,6 @@ free-handles: func [ state/header: TYPE_NONE ] -; Debug function to show children tree -debug-show-children: func [ - widget [handle!] - parent? [logic!] - /local - widget_ [handle!] - child [handle!] - container [handle!] - rect [tagRECT value] - sx [integer!] - sy [integer!] - offset [red-pair!] - size [red-pair!] - pane [red-block!] - type [red-word!] - sym [integer!] - face [red-object!] - tail [red-object!] - values [red-value!] - overlap? [logic!] - ; these ones would be removed - debug [logic!] - cpt [integer!] -][ - ; to remove when satisfactory enough development - debug: yes - - values: get-face-values widget - type: as red-word! values + FACE_OBJ_TYPE - pane: as red-block! values + FACE_OBJ_PANE - - either parent? [ - face: as red-object! values + FACE_OBJ_PARENT - either TYPE_OF(face) = TYPE_NONE [ - print-line "parent face: none" - print ["parent handle: " widget lf] - ][ - values: object/get-values face - type: as red-word! values + FACE_OBJ_TYPE - pane: as red-block! values + FACE_OBJ_PANE - widget_: face-handle? face - print ["from parent handle: " widget_ lf] - ] - ][print ["parent handle: " widget lf]] - - sym: symbol/resolve type/symbol - - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ - face: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - if debug [print ["Pane type: " get-symbol-name sym lf]] - if TYPE_OF(face) <> TYPE_OBJECT [print-line "not face object"] - widget_: face-handle? face - - either null? widget_ [print-line "null container" container: null][container: GET-CONTAINER(widget_)] - print ["container handle: " container lf] - - sx: 0 sy: 0 - cpt: 0 - while [face < tail][ - cpt: cpt + 1 - print-line cpt - child: face-handle? face - print ["child handle: " child lf] - values: object/get-values face - offset: as red-pair! values + FACE_OBJ_OFFSET - size: as red-pair! values + FACE_OBJ_SIZE - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - - if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] - ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 - - unless null? container [ - widget_: event-box? child - - gtk_widget_get_allocation widget_ as handle! rect - ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates - if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] - ] - if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] - either null? child [print-line "null child"][debug-show-children child no] - face: face + 1 - ] - if debug [print-line "Pane end"] - ] -] - ; on-gc-mark: does [ ; collector/keep flags-blk/node ; collector/keep win-array/node @@ -606,85 +636,6 @@ get-symbol-name: function [ true ["undefined"] ] ] -; this adjustment is supposed to fix only horizontally consecutive widgets in the same pane -adjust-sizes: func [ - widget [handle!] - /local - widget_ [handle!] - child [handle!] - container [handle!] - rect [tagRECT value] - dx [integer!] - dy [integer!] - ox [integer!] - oy [integer!] - sx [integer!] - sy [integer!] - offset [red-pair!] - size [red-pair!] - pane [red-block!] - type [red-word!] - sym [integer!] - face [red-object!] - tail [red-object!] - values [red-value!] - overlap? [logic!] - ; these ones would be removed - debug [logic!] - cpt [integer!] -][ - ; to remove when satisfactory enough development - debug: no - - values: get-face-values widget - type: as red-word! values + FACE_OBJ_TYPE - pane: as red-block! values + FACE_OBJ_PANE - - sym: symbol/resolve type/symbol - - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ - face: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - if debug [print ["Parent type: " get-symbol-name sym lf]] - child: face-handle? face - container: either null? child [null][GET-CONTAINER(child)] - dx: 0 dy: 0 - ox: 0 oy: 0 sx: 0 sy: 0 - cpt: 0 - while [face < tail][ - cpt: cpt + 1 - child: face-handle? face - unless null? child [ - values: object/get-values face - offset: as red-pair! values + FACE_OBJ_OFFSET - size: as red-pair! values + FACE_OBJ_SIZE - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - overlap?: all [ox + dx + sx > offset/x oy + sy > offset/y] - if debug [print ["Child" cpt " type: " get-symbol-name sym lf]] - ; if next widget is on the right of the previous one or there is no overlapping dx becomes 0 - if any [ox > offset/x not overlap?] [dx: 0] - unless null? container [ - widget_: event-box? child - if debug [ print ["move child: " offset/x "+" dx "(" offset/x + dx ")" " " offset/y lf]] - gtk_layout_move container widget_ offset/x + dx offset/y - gtk_widget_get_allocation widget_ as handle! rect - ; rmk: rect/x and rect/y are absolute coordinates when offset/x and offset/y are relative coordinates - if debug [ print ["widget->rect:" rect/x "x" rect/y "x" rect/width "x" rect/height lf]] - ] - ; save previous offset and size coordinates - ox: offset/x oy: offset/y sx: size/x sy: size/y - if debug [print ["red->rect:" offset/x "x" offset/y "x" size/x "x" size/y lf]] - dx: dx + rect/width - sx - dy: dy + rect/height - sy - if debug [ print ["next dx: " dx lf]] - adjust-sizes child - ] - face: face + 1 - ] - if debug [print-line "Pane end"] - ] -] remove-widget-timer: func [ widget [handle!] @@ -858,65 +809,64 @@ change-pane: func [ pane [red-block!] type [integer!] /local + layout [handle!] + list [GList!] + child [GList!] + s [series!] face [red-object!] tail [red-object!] widget [handle!] - evbox [handle!] - nb [integer!] - s [series!] values [red-value!] offset [red-pair!] - list [GList!] - child [GList!] ][ ;; DEBUG: print ["change-pane " get-symbol-name type lf] - if gtk-layout? type [ ;; this is for gtk_layout widget - list: as GList! gtk_container_get_children parent + layout: case [ + type = window [ + g_object_get_qdata parent win-layout-id + ] + type = group-box [ + gtk_bin_get_child parent + ] + any [ + type = base + type = rich-text + type = panel + ][ + parent + ] + true [ + null + ] + ] - child: list nb: 0 + unless null? layout [ + list: as GList! gtk_container_get_children parent + child: list while [not null? child][ - nb: nb + 1 - g_object_ref child/data ; to avoid destruction before removing from container - gtk_container_remove parent child/data - ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] - child: child/next + g_object_ref child/data ;-- to avoid destruction before removing from container + gtk_container_remove parent child/data + ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] + child: child/next ] g_list_free as int-ptr! list s: GET_BUFFER(pane) face: as red-object! s/offset + pane/head tail: as red-object! s/tail - nb: (as-integer tail - face) >> 4 - nb: 0 while [face < tail][ if TYPE_OF(face) = TYPE_OBJECT [ widget: face-handle? face if widget <> null [ - evbox: event-box? widget - nb: nb + 1 - ;; DEBUG: print ["add widget" nb ": " widget "(" evbox ") to " parent lf] - gtk_container_add parent evbox values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - gtk_layout_move parent evbox offset/x offset/y + set-widget-child parent widget offset ] ] face: face + 1 ] - ;; OS-refresh-window as-integer main-window - - ;; DEBUG: - ; list: as GList! gtk_container_get_children parent - ; child: list nb: 0 - ; while [not null? child][ - ; nb: nb + 1 - ; print [" widget" nb ": " child/data lf] - ; child: child/next - ; ] - ; g_list_free as int-ptr! list ] ] @@ -955,26 +905,25 @@ change-offset: func [ pos [red-pair!] type [integer!] /local - container [handle!] - evbox [handle!] + parent [handle!] + layout [handle!] + values [red-value!] + ntype [red-word!] + sym [integer!] ][ - ;; DEBUG: print ["change-offset type: " get-symbol-name get-widget-symbol widget " " widget " " pos/x "x" pos/y lf] either type = window [ gtk_window_move widget pos/x pos/y ][ - unless null? widget [ - ;OS-refresh-window as integer! main-window - container: either null? widget [null][GET-CONTAINER(widget)] - ;; DEBUG: print ["change-offset by" pos lf] - ; _widget: either type = text [ - ; g_object_get_qdata widget _widget-id - ; ][widget] - - evbox: event-box? widget - unless null? container [ - gtk_layout_move container evbox pos/x pos/y - gtk_widget_queue_draw evbox - ] + values: get-face-values widget + ntype: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve ntype/symbol + parent: get-face-parent widget values sym + layout: get-face-layout widget values sym + if layout <> widget [ + set-widget-offset layout widget 0 0 + ] + unless null? parent [ + set-widget-offset parent layout pos/x pos/y ] ] ] @@ -984,23 +933,27 @@ change-size: func [ size [red-pair!] type [integer!] /local - evbox [handle!] + values [red-value!] + ntype [red-word!] + sym [integer!] + layout [handle!] ][ - ;; DEBUG: print ["change-size " get-symbol-name get-widget-symbol widget " " widget " " size/x "x" size/y lf] - either type = window [ - ;; DEBUG: print ["change-size window: " size/x "x" size/y lf] gtk_window_set_default_size widget size/x size/y gtk_window_resize widget size/x size/y gtk_widget_queue_draw widget ][ - unless null? widget [ - evbox: event-box? widget - gtk_widget_set_size_request evbox size/x size/y - gtk_widget_queue_resize evbox + values: get-face-values widget + ntype: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve ntype/symbol + layout: get-face-layout widget values sym + if layout <> widget [ + set-widget-size layout size + gtk_widget_queue_resize layout ] + set-widget-size widget size + gtk_widget_queue_resize widget ] - ] init-all-children: func [ @@ -1008,7 +961,6 @@ init-all-children: func [ /local values [red-value!] pane [red-block!] - show? [red-logic!] cursor [handle!] win [handle!] face [red-object!] @@ -1018,9 +970,6 @@ init-all-children: func [ values: get-face-values widget pane: as red-block! values + FACE_OBJ_PANE - show?: as red-logic! values + FACE_OBJ_VISIBLE? - gtk_widget_set_visible widget show?/value - cursor: GET-CURSOR(widget) unless null? cursor [ win: gtk_widget_get_window widget @@ -1047,23 +996,20 @@ change-visible: func [ widget [handle!] show? [logic!] type [integer!] + /local + values [red-value!] + ntype [red-word!] + sym [integer!] + layout [handle!] ][ - case [ - type = window [ - ; either show? [ - ; objc_msgSend [widget sel_getUid "makeKeyAndOrderFront:" widget] - ; ][ - ; objc_msgSend [widget sel_getUid "orderOut:" widget] - ; ] - 0 - ] - true [ - ;; DEBUG: print ["change-visible " widget " (type " get-symbol-name type "): " show? lf] - gtk_widget_set_visible widget show? - gtk_widget_queue_draw widget - ] + values: get-face-values widget + ntype: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve ntype/symbol + layout: get-face-layout widget values sym + if layout <> widget [ + gtk_widget_set_visible layout show? ] -; gtk_widget_queue_draw widget + gtk_widget_set_visible widget show? ] change-enabled: func [ @@ -1250,7 +1196,7 @@ change-selection: func [ gtk_combo_box_set_active widget idx ] type = tab-panel [ - gtk_notebook_set_current_page widget idx + select-tab widget int ] type = window [ switch TYPE_OF(int) [ @@ -1619,7 +1565,6 @@ parse-common-opts: func [ sym: symbol/resolve word/symbol case [ sym = _cursor [ - ;; DEBUG: print ["set cursor: " widget lf] w: word + 1 display: gtk_widget_get_display widget either TYPE_OF(w) = TYPE_IMAGE [ @@ -1652,37 +1597,38 @@ parse-common-opts: func [ OS-redraw: func [ widget [integer!] ][ - ;; DEBUG: print ["OS-redraw" lf] - unless null? as handle! widget [gtk_widget_queue_draw as handle! widget] + if widget <> 0 [ ;-- view engine should make sure a valid handle, but it not + gtk_widget_queue_draw as handle! widget + ] ] -OS-refresh-window: func [widget [integer!]][ - ;; DEBUG: print-line "OS-refresh-window" - ;debug-show-children main-window no - ;gtk_widget_queue_draw main-window - OS-show-window widget +OS-refresh-window: func [ + widget [integer!] +][ + if widget <> 0 [ ;-- view engine should make sure a valid handle, but it not + gtk_widget_queue_draw as handle! widget + OS-show-window widget + ] ] OS-show-window: func [ widget [integer!] /local - face [red-object!] - event [GdkEventConfigure!] - type [integer!] - size [red-pair!] - hWnd [handle!] + handle [handle!] + values [red-value!] + type [red-word!] + sym [integer!] + layout [handle!] ][ - hWnd: as handle! widget - unless null? hWnd [ - type: get-widget-symbol hWnd - gtk_widget_show_all hWnd - ;; DEBUG: print ["OS-show-window " hWnd "(" get-symbol-name type ") win: " gtk_widget_get_window hWnd lf] - ;; Deal with visible? facets - init-all-children hWnd - gtk_widget_grab_focus hWnd - face: (as red-object! get-face-values hWnd) + FACE_OBJ_SELECTED - if TYPE_OF(face) = TYPE_OBJECT [gtk_widget_grab_focus face-handle? face] + handle: as handle! widget + values: get-face-values handle + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + layout: get-face-layout handle values sym + if layout <> handle [ + gtk_widget_show layout ] + gtk_widget_show handle ] OS-make-view: func [ @@ -1713,7 +1659,6 @@ OS-make-view: func [ caption [c-string!] len [integer!] widget [handle!] - evbox [handle!] winbox [handle!] buffer [handle!] container [handle!] @@ -1727,8 +1672,6 @@ OS-make-view: func [ values: object/get-values face - evbox: as handle! 0 ; widget version with possible scrollview - type: as red-word! values + FACE_OBJ_TYPE str: as red-string! values + FACE_OBJ_TEXT offset: as red-pair! values + FACE_OBJ_OFFSET @@ -1746,10 +1689,6 @@ OS-make-view: func [ bits: get-flags as red-block! values + FACE_OBJ_FLAGS sym: symbol/resolve type/symbol - ; if bits and FACET_FLAGS_SCROLLABLE <> 0 [ - ; flags: flags or WS_HSCROLL or WS_VSCROLL - ; ] - caption: either TYPE_OF(str) = TYPE_STRING [ len: -1 unicode/to-utf8 str :len @@ -1757,8 +1696,6 @@ OS-make-view: func [ null ] - ;;DEBUG: print ["OS-make-view " get-symbol-name sym lf] - case [ sym = check [ widget: gtk_check_button_new_with_label caption @@ -1766,10 +1703,8 @@ OS-make-view: func [ ] sym = radio [ widget: either null? group-radio [ - ;; DEBUG: print ["radio created: " caption lf] gtk_radio_button_new_with_label null caption ][ - ;; DEBUG: print ["radio group-radio created: " caption lf] gtk_radio_button_new_with_label_from_widget group-radio caption ] set-logic-state widget as red-logic! data no @@ -1781,31 +1716,23 @@ OS-make-view: func [ ] ] sym = base [ - widget: gtk_layout_new null null; - gtk_layout_set_size widget size/x size/y - ;; widget: gtk_drawing_area_new + widget: gtk_layout_new null null ] sym = rich-text [ - widget: gtk_layout_new null null;gtk_drawing_area_new - gtk_layout_set_size widget size/x size/y - evbox: gtk_scrolled_window_new null null - ;; DEBUG: print ["rich-text evbox: " evbox lf] - gtk_container_add evbox widget + widget: gtk_layout_new null null + container: gtk_scrolled_window_new null null + gtk_container_add container widget ] sym = window [ - ;; DEBUG: print ["win App " GTKApp lf] win-cnt: win-cnt + 1 widget: gtk_window_new 0 last-window: widget - ;; DEBUG: print ["win number " win-cnt " at " widget lf] if win-cnt = 1 [ - ;; DEBUG: print ["Creation of Main window" lf] main-window: widget ] gtk_application_add_window GTKApp widget if bits and FACET_FLAGS_MODAL <> 0 [ - ;; DEBUG: print ["Creation of Modal window" lf] gtk_window_set_modal widget yes ] unless null? caption [gtk_window_set_title widget caption] @@ -1817,14 +1744,15 @@ OS-make-view: func [ menu-bar? menu window ][ AppMainMenu: gtk_menu_bar_new - ;; DEBUG: print ["AppMainMenu " AppMainMenu " creation for window " widget lf] build-menu menu AppMainMenu widget gtk_box_pack_start winbox AppMainMenu no yes 0 ] gtk_widget_show winbox - evbox: gtk_layout_new null null - gtk_layout_set_size evbox size/x size/y - gtk_box_pack_start winbox evbox yes yes 0 + container: gtk_layout_new null null + gtk_layout_set_size container size/x size/y + gtk_widget_show container + g_object_set_qdata widget win-layout-id container + gtk_box_pack_start winbox container yes yes 0 gtk_window_move widget offset/x offset/y ;; The following line really matters to fix the initial size of the window @@ -1852,13 +1780,16 @@ OS-make-view: func [ sym = text [ widget: gtk_label_new caption ;; gtk_label_set_width_chars widget ??? - evbox: gtk_event_box_new null null - gtk_container_add evbox widget + container: gtk_event_box_new null null + gtk_container_add container widget ] sym = field [ widget: gtk_entry_new buffer: gtk_entry_get_buffer widget - unless null? caption [gtk_entry_buffer_set_text buffer caption -1] + unless null? caption [ + gtk_entry_buffer_set_text buffer caption -1 + gtk_widget_show buffer + ] gtk_entry_set_width_chars widget size/x / font-size? font set-hint-text widget as red-block! values + FACE_OBJ_OPTIONS if bits and FACET_FLAGS_PASSWORD <> 0 [gtk_entry_set_visibility widget no] @@ -1875,38 +1806,36 @@ OS-make-view: func [ sym = area [ widget: gtk_text_view_new buffer: gtk_text_view_get_buffer widget - unless null? caption [gtk_text_buffer_set_text buffer caption -1] - evbox: gtk_scrolled_window_new null null - gtk_container_add evbox widget + unless null? caption [ + gtk_text_buffer_set_text buffer caption -1 + gtk_widget_show buffer + ] + container: gtk_scrolled_window_new null null + gtk_container_add container widget ] sym = group-box [ widget: gtk_frame_new caption gtk_frame_set_shadow_type widget 3 - gtk_frame_set_label_align widget 0.5 0.5; Todo: does not seem to work + gtk_frame_set_label_align widget 0.5 0.5 ; Todo: does not seem to work container: gtk_layout_new null null + gtk_widget_show container gtk_container_add widget container ] sym = panel [ widget: gtk_layout_new null null - unless null? caption [ - buffer: gtk_label_new caption - gtk_container_add widget buffer - ] - gtk_layout_set_size widget size/x size/y ] sym = tab-panel [ widget: gtk_notebook_new - set-tabs widget values ] sym = text-list [ widget: gtk_list_box_new init-text-list widget data ;gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 - evbox: gtk_scrolled_window_new null null + container: gtk_scrolled_window_new null null if bits and FACET_FLAGS_NO_BORDER = 0 [ - gtk_scrolled_window_set_shadow_type evbox 3 + gtk_scrolled_window_set_shadow_type container 3 ] - gtk_container_add evbox widget + gtk_container_add container widget ] any [ sym = drop-list @@ -1928,71 +1857,36 @@ OS-make-view: func [ ] ] - ; save the previous group-radio state as a global variable - group-radio: either sym = radio [widget][as handle! 0] - - parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym - - ;;DEBUG: print [ "New widget " get-symbol-name sym "->" widget lf] - - either null? evbox [evbox: widget][SET-EVENT-BOX(widget evbox)] - if all [ - sym <> window - parent <> 0 - ][ - p-sym: get-widget-symbol as handle! parent - ; TODO: case to replace with either if no more choice - ;; DEBUG: print ["Parent: " get-symbol-name p-sym " evbox" evbox lf] + ;-- store the face value in the extra space of the window struct + assert TYPE_OF(face) = TYPE_OBJECT + store-face-to-obj widget face - container: as handle! case [ - p-sym = window [ - g_object_get_qdata as handle! parent event-box-id - ] - any [p-sym = panel p-sym = rich-text p-sym = base] [parent] - p-sym = group-box [ - buffer: gtk_container_get_children as handle! parent - ;; DEBUG: print ["Parent when not container : " buffer/value lf] - buffer/value - ] - true [ - ; CAREFULL: NOT SURE THIS WAS USED PROPERLY -> for compilation of gui-console this clearly leads to a bug - ; buffer: gtk_container_get_children as handle! parent - ; ;; DEBUG: - ; print ["Parent when not container : " buffer/value lf] - ; buffer/value - - ;; redirect to the layout of the parent - ;; WARNING: (since completedly changed code) - print ["DEVEL WARNING: <> (ONLY FOR DEVELOPMENT SINCE CODE HAS FULLY CHANGED BUT IMPOSSIBLE TO TEST) " lf] - g_object_get_qdata as handle! parent gtk-container-id + if sym <> window [ + if parent <> 0 [ + unless set-widget-child as handle! parent widget offset [ + fire [TO_ERROR(script face-type) type] ] ] - ;; DEBUG: print ["widget (" get-symbol-name sym "):" widget "[evbox: " evbox "] with parent (" get-symbol-name p-sym ") " as handle! parent " with container (" (get-symbol-name get-widget-symbol container) ") " container lf] - - ;save gtk_layout container for adjustment since size/x and size/y are not the real sizes in gtk and need to be updated in a second pass - SET-CONTAINER(widget container) - if sym = text [SET-CONTAINER(evbox container)] - gtk_widget_set_size_request evbox size/x size/y - gtk_layout_put container evbox offset/x offset/y - ;; DEBUG: print ["make-view: evbox: " offset/x "x" offset/y "x" size/x "x" size/y lf] + set-widget-child-offset as handle! parent widget offset sym + change-visible widget show?/value sym + change-size widget size sym ] - ; Deal with actors - connect-widget-events widget sym evbox - - unless any[sym = window sym = area][build-context-menu widget menu] + unless any [sym = window sym = area][build-context-menu widget menu] - ;-- store the face value in the extra space of the window struct - assert TYPE_OF(face) = TYPE_OBJECT ;-- detect corruptions caused by CreateWindow unwanted events - store-face-to-obj widget face - if sym = text [store-face-to-obj evbox face] + ; Deal with actors + connect-widget-events widget values sym - change-selection widget as red-integer! values + FACE_OBJ_SELECTED sym - change-para widget face as red-object! values + FACE_OBJ_PARA font sym + change-selection widget selected sym + change-para widget face para font sym change-enabled widget enabled?/value sym make-styles-provider widget + parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym + ; save the previous group-radio state as a global variable + group-radio: either sym = radio [widget][as handle! 0] + ;; TODO: NOT SURE the if is necessary! if sym <> base [ change-font widget face font sym diff --git a/modules/view/backends/gtk3/tab-panel.reds b/modules/view/backends/gtk3/tab-panel.reds index 8b2488b514..608b0a4a13 100644 --- a/modules/view/backends/gtk3/tab-panel.reds +++ b/modules/view/backends/gtk3/tab-panel.reds @@ -10,59 +10,114 @@ Red/System [ } ] -set-tabs: func [ + +append-tab: func [ + parent [handle!] widget [handle!] - facets [red-value!] + return: [logic!] /local + index [integer!] data [red-block!] - pane [red-block!] str [red-string!] - tail [red-string!] - int [red-integer!] - nb [integer!] - item [integer!] len [integer!] title [c-string!] label [handle!] - panel [handle!] - face [red-object!] - end [red-object!] ][ - nb: gtk_notebook_get_n_pages widget - loop nb [ - gtk_notebook_remove_page widget -1 + index: gtk_notebook_get_n_pages parent + data: get-widget-data parent + if TYPE_OF(data) = TYPE_BLOCK [ + str: as red-string! block/rs-abs-at data index + len: -1 + title: unicode/to-utf8 str :len + label: gtk_label_new title + gtk_notebook_insert_page parent widget label index + return true ] + false +] - data: as red-block! facets + FACE_OBJ_DATA - pane: as red-block! facets + FACE_OBJ_PANE - nb: 0 +select-tab: func [ + widget [handle!] + int [red-integer!] + /local + nb [integer!] + idx [integer!] +][ + nb: gtk_notebook_get_n_pages widget + idx: int/value + if any [idx < 1 idx > nb][exit] - if TYPE_OF(data) = TYPE_BLOCK [ - str: as red-string! block/rs-head data - tail: as red-string! block/rs-tail data - face: as red-object! block/rs-head pane - end: as red-object! block/rs-tail pane - nb: 0 - while [str < tail][ - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - title: unicode/to-utf8 str :len - label: gtk_label_new title - if face < end [ - panel: as handle! get-face-handle face - gtk_notebook_append_page widget panel label - face: face + 1 + gtk_notebook_set_current_page widget idx - 1 +] + +insert-tab: func [ + parent [handle!] + str [red-string!] + index [integer!] + /local + widget [handle!] + len [integer!] + title [c-string!] + label [handle!] +][ + widget: gtk_layout_new null null + len: -1 + title: unicode/to-utf8 str :len + label: gtk_label_new title + gtk_notebook_insert_page parent widget label index +] + +update-tabs: func [ + face [red-object!] + value [red-value!] + sym [integer!] + new [red-value!] + index [integer!] + part [integer!] + /local + widget [handle!] + parent [handle!] + str [red-string!] +][ + widget: get-face-handle face + switch TYPE_OF(value) [ + TYPE_BLOCK [ + case [ + any [ + sym = words/_remove/symbol + sym = words/_take/symbol + sym = words/_clear/symbol + ][ + ownership/unbind-each as red-block! value index part + loop part [ + gtk_notebook_remove_page widget index + ] + ] + any [ + sym = words/_insert/symbol + sym = words/_poke/symbol + sym = words/_put/symbol + ][ + str: as red-string! either null? new [ + block/rs-abs-at as red-block! value index + ][ + new + ] + loop part [ + if sym <> words/_insert/symbol [ + ownership/unbind-each as red-block! value index part + gtk_notebook_remove_page widget index + ] + insert-tab widget str index + str: str + 1 + ] ] - nb: nb + 1 + true [0] ] - str: str + 1 ] + TYPE_STRING [ + insert-tab widget as red-string! value index + ] + default [assert false] ;@@ raise a runtime error ] - int: as red-integer! facets + FACE_OBJ_SELECTED - - if TYPE_OF(int) <> TYPE_INTEGER [ - int/header: TYPE_INTEGER ;-- force selection on first tab - int/value: 1 - ] - gtk_notebook_set_current_page widget int/value ] diff --git a/modules/view/view.red b/modules/view/view.red index 148ea57f32..3dde73c2e0 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -751,7 +751,7 @@ show: function [ ] p: either with [parent/state/1][0] - #if config/OS <> 'Windows [ ;@@ remove this system specific code + #if config/OS = 'macOS [ ;@@ remove this system specific code if all [face/type = 'tab-panel face/pane][ link-tabs-to-parent face foreach f face/pane [show/force f] @@ -772,7 +772,7 @@ show: function [ ] switch face/type [ - #if config/OS = 'Windows [ ;@@ remove this system specific code + #if config/OS <> 'macOS [ ;@@ remove this system specific code tab-panel [link-tabs-to-parent face] ] window [ From e0c4ab218e342fc6952706b6417f4c723f7b967f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 17 Oct 2019 17:13:12 +0800 Subject: [PATCH 0268/3432] FIX: show menubar for all window if there exist one --- modules/view/backends/gtk3/gui.reds | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 799437464d..6c38d0381f 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -41,7 +41,6 @@ exit-loop: 0 ;;;close-window?: no ;;;win-array: declare red-vector! win-cnt: 0 -AppMainMenu: as handle! 0 ;; Identifiers for qdata red-face-id1: g_quark_from_string "red-face-id1" @@ -1739,13 +1738,11 @@ OS-make-view: func [ winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox - if all [ ;@@ application menu ? - null? AppMainMenu - menu-bar? menu window - ][ - AppMainMenu: gtk_menu_bar_new - build-menu menu AppMainMenu widget - gtk_box_pack_start winbox AppMainMenu no yes 0 + if menu-bar? menu window [ + hMenu: gtk_menu_bar_new + gtk_widget_show hMenu + build-menu menu hMenu widget + gtk_box_pack_start winbox hMenu no yes 0 ] gtk_widget_show winbox container: gtk_layout_new null null From bc7dbcf05a3a056545902006a34d7e74a2a541df Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 16 Oct 2019 10:45:24 +0200 Subject: [PATCH 0269/3432] FEAT: use hashtable in context. --- runtime/collector.reds | 4 +- runtime/datatypes/context.reds | 128 +++++++++----------------- runtime/datatypes/get-word.reds | 7 +- runtime/datatypes/lit-word.reds | 7 +- runtime/datatypes/object.reds | 47 +++++----- runtime/datatypes/set-word.reds | 7 +- runtime/datatypes/word.reds | 12 +-- runtime/debug-tools.reds | 5 +- runtime/hashtable.reds | 157 ++++++++++++++++++++++++++++++-- runtime/ownership.reds | 2 +- runtime/redbin.reds | 8 +- 11 files changed, 223 insertions(+), 161 deletions(-) diff --git a/runtime/collector.reds b/runtime/collector.reds index 4478657abf..17d87422f5 100644 --- a/runtime/collector.reds +++ b/runtime/collector.reds @@ -107,7 +107,7 @@ collector: context [ ;probe "context" if keep node [ ctx: TO_CTX(node) - keep ctx/symbols + _hashtable/mark ctx/symbols unless ON_STACK?(ctx) [mark-block-node ctx/values] ] ] @@ -207,7 +207,7 @@ collector: context [ #if debug? = yes [if verbose > 1 [print "context"]] ctx: as red-context! value ;keep ctx/self - mark-block-node ctx/symbols + _hashtable/mark ctx/symbols unless ON_STACK?(ctx) [mark-block-node ctx/values] ] TYPE_HASH diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index bf160242b8..853524054c 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -17,33 +17,20 @@ _context: context [ ctx [red-context!] sym [integer!] case? [logic!] - return: [integer!] ;-- value > 0: success, value = -1: failure - /local - series [series!] - list [red-word!] - end [red-word!] + return: [integer!] ;-- value > 0: success, value = -1: failure ][ - series: as series! ctx/symbols/value - list: as red-word! series/offset - end: as red-word! series/tail - - either case? [ - sym: symbol/resolve sym - while [list < end][ - if sym = symbol/resolve list/symbol [ - return (as-integer list - as red-word! series/offset) >> 4 ;@@ log2(size? cell!) hardcoded - ] - list: list + 1 - ] - ][ - while [list < end][ - if sym = list/symbol [ - return (as-integer list - as red-word! series/offset) >> 4 ;@@ log2(size? cell!) hardcoded - ] - list: list + 1 - ] - ] - -1 ;-- search failed + _hashtable/get-ctx-symbol ctx/symbols sym case? null null + ] + + find-or-store: func [ ;-- find a symbol, if not found, store it. + ctx [red-context!] + sym [integer!] + case? [logic!] + w-ctx [node!] ;-- word/ctx + new-id [int-ptr!] + return: [integer!] ;-- word index in the context + ][ + _hashtable/get-ctx-symbol ctx/symbols sym case? w-ctx new-id ] set-global: func [ @@ -112,35 +99,26 @@ _context: context [ value [cell!] s [series!] id [integer!] + new-id [integer!] ][ + new-id: 0 ctx: TO_CTX(global-ctx) - id: find-word ctx sym case? - s: as series! ctx/symbols/value - + id: find-or-store ctx sym case? global-ctx :new-id + if id <> -1 [ - word: as red-word! s/offset + id ;-- word already defined in global context + word: _hashtable/get-ctx-word ctx id if all [case? store? word/symbol <> sym][ word: as red-word! copy-cell as red-value! word ALLOC_TAIL(root) word/symbol: sym ] return word ] - - s: as series! ctx/symbols/value - word: as red-word! alloc-tail s - word/header: TYPE_WORD ;-- implicit reset of all header flags - word/ctx: global-ctx - word/symbol: sym - s: as series! ctx/symbols/value - id: either positive? symbol/get-alias-id sym [ ;-- alias, fetch original id - find-word ctx sym yes - ][ - (as-integer s/tail - s/offset) >> 4 - 1 ;-- index is zero-base + word: _hashtable/get-ctx-word ctx new-id + if positive? symbol/get-alias-id sym [ ;-- alias, fetch original id + word/index: find-word ctx sym yes ] - word/index: id - value: alloc-tail as series! ctx/values/value value/header: TYPE_UNSET word @@ -152,23 +130,14 @@ _context: context [ value [red-value!] return: [red-value!] /local - w [red-word!] - s [series!] - id [integer!] + id [integer!] + new-id [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "_context/add-with"]] - id: find-word ctx word/symbol yes + new-id: 0 + id: find-or-store ctx word/symbol yes ctx/self :new-id if id <> -1 [return null] - - s: as series! ctx/symbols/value - id: (as-integer s/tail - s/offset) >> 4 ;-- index is zero-base - w: as red-word! alloc-tail s - copy-cell as cell! word as cell! w - w/ctx: ctx/self - w/index: id - - s: as series! ctx/symbols/value ;-- refreshing pointer after alloc-tail copy-cell value alloc-tail as series! ctx/values/value ] @@ -177,30 +146,21 @@ _context: context [ word [red-word!] return: [integer!] /local - sym [cell!] - value [cell!] - s [series!] - id [integer!] + id [integer!] + new-id [integer!] + value [red-value!] ][ #if debug? = yes [if verbose > 0 [print-line "_context/add"]] - - id: find-word ctx word/symbol yes + + new-id: 0 + id: find-or-store ctx word/symbol yes word/ctx :new-id if id <> -1 [return id] - - s: as series! ctx/symbols/value - id: (as-integer s/tail - s/offset) >> 4 ;-- index is zero-base - sym: alloc-tail s - copy-cell as cell! word sym - sym/header: TYPE_WORD ;-- force word! type - word: as red-word! sym - word/index: id - unless ON_STACK?(ctx) [ value: alloc-tail as series! ctx/values/value value/header: TYPE_UNSET ] - id + new-id ] set-integer: func [ @@ -356,7 +316,7 @@ _context: context [ obj: as red-object! slot node: obj/ctx ctx: TO_CTX(node) - src: as series! ctx/symbols/value + src: _hashtable/get-ctx-words ctx slots: (as-integer (src/tail - src/offset)) >> 4 new: create @@ -365,7 +325,7 @@ _context: context [ ctx/header and flag-self-mask <> 0 ctx: TO_CTX(new) - dst: as series! ctx/symbols/value + dst: _hashtable/get-ctx-words ctx dst/tail: dst/offset + slots sym: as red-word! dst/offset @@ -402,7 +362,7 @@ _context: context [ slot: alloc-tail as series! node/value ;-- allocate a slot for obj/func back-reference slot/header: TYPE_UNSET cell/header: TYPE_UNSET ;-- implicit reset of all header flags - symbols: alloc-cells slots ;@@ create the node! on native stack, so it can be marked by GC + symbols: _hashtable/init slots null HASH_TABLE_SYMBOL 1 ;@@ create the node! on native stack, so it can be marked by GC cell/self: node either stack? [ @@ -425,24 +385,21 @@ _context: context [ return: [node!] /local new [node!] - symbols [node!] ctx [red-context!] cell [red-value!] end [red-value!] - slot [red-word!] + w [red-word!] s [series!] type [integer!] i [integer!] ][ new: create block/rs-length? spec stack? self? ctx: TO_CTX(new) - symbols: ctx/symbols - s: GET_BUFFER(spec) cell: s/offset end: s/tail + i: 0 - while [cell < end][ type: TYPE_OF(cell) if any [ ;TBD: use typeset/any-word? @@ -451,11 +408,8 @@ _context: context [ type = TYPE_LIT_WORD type = TYPE_REFINEMENT ][ ;-- add new word to context - slot: as red-word! alloc-tail as series! symbols/value - copy-cell cell as red-value! slot - slot/header: TYPE_WORD - slot/ctx: new - slot/index: i + w: as red-word! cell + find-or-store ctx w/symbol yes new :type i: i + 1 ] cell: cell + 1 @@ -561,7 +515,7 @@ _context: context [ tail: s/tail assert cell <= tail - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx base: s/tail - s/offset while [cell < tail][ @@ -570,7 +524,7 @@ _context: context [ ] cell: cell + 1 ] - s: as series! ctx/symbols/value ;-- refresh s after possible expansion + s: _hashtable/get-ctx-words ctx ;-- refresh s after possible expansion s/tail - s/offset > base ;-- TRUE: new words added ] diff --git a/runtime/datatypes/get-word.reds b/runtime/datatypes/get-word.reds index 6d309f9a86..7458aaf3c2 100644 --- a/runtime/datatypes/get-word.reds +++ b/runtime/datatypes/get-word.reds @@ -53,15 +53,10 @@ get-word: context [ node [node!] index [integer!] return: [red-word!] - /local - ctx [red-context!] - s [series!] ][ #if debug? = yes [if verbose > 0 [print-line "get-word/push-local"]] - ctx: TO_CTX(node) - s: as series! ctx/symbols/value - push as red-word! s/offset + index + push _hashtable/get-ctx-word TO_CTX(node) index ] set: func [ diff --git a/runtime/datatypes/lit-word.reds b/runtime/datatypes/lit-word.reds index 5ddc76fcb9..790c23be3c 100644 --- a/runtime/datatypes/lit-word.reds +++ b/runtime/datatypes/lit-word.reds @@ -53,15 +53,10 @@ lit-word: context [ node [node!] index [integer!] return: [red-word!] - /local - ctx [red-context!] - s [series!] ][ #if debug? = yes [if verbose > 0 [print-line "lit-word/push-local"]] - ctx: TO_CTX(node) - s: as series! ctx/symbols/value - push as red-word! s/offset + index + push _hashtable/get-ctx-word TO_CTX(node) index ] set: func [ diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index 889d294c39..f1563f71a7 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -88,13 +88,8 @@ object: context [ obj [node!] index [integer!] return: [red-value!] - /local - ctx [red-context!] - s [series!] ][ - ctx: TO_CTX(obj) - s: as series! ctx/symbols/value - s/offset + index + as red-value! _hashtable/get-ctx-word TO_CTX(obj) index ] get-words: func [ @@ -120,11 +115,9 @@ object: context [ obj [red-object!] return: [integer!] /local - ctx [red-context!] s [series!] ][ - ctx: GET_CTX(obj) - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words GET_CTX(obj) (as-integer s/tail - s/offset) >> 4 ] @@ -158,7 +151,7 @@ object: context [ tail: s/tail type: TYPE_OF(value) on-set?: obj/on-set <> null - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx word: as red-word! s/offset if on-set? [ @@ -305,7 +298,7 @@ object: context [ sym [integer!] type [integer!] ][ - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx head: as red-word! s/offset tail: as red-word! s/tail word: head @@ -527,7 +520,7 @@ object: context [ blank [byte!] ][ ctx: GET_CTX(obj) - syms: as series! ctx/symbols/value + syms: _hashtable/get-ctx-words ctx values: as series! ctx/values/value sym: syms/offset @@ -598,7 +591,7 @@ object: context [ from: TO_CTX(src) to: TO_CTX(dst) - s: as series! from/symbols/value + s: _hashtable/get-ctx-words from symbol: s/offset tail: s/tail @@ -611,7 +604,7 @@ object: context [ while [symbol < tail][ word: as red-word! symbol idx: _context/find-word to word/symbol yes - + assert idx > -1 type: TYPE_OF(value) either ANY_SERIES?(type) [ ;-- copy series value in extended object actions/copy @@ -683,14 +676,14 @@ object: context [ type [integer!] s [series!] ][ - s: as series! spec/symbols/value + s: _hashtable/get-ctx-words spec syms: s/offset tail: s/tail s: as series! spec/values/value vals: s/offset - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx base: s/tail - s/offset s: as series! ctx/values/value @@ -731,7 +724,7 @@ object: context [ ] value: value + 1 ] - s: as series! ctx/symbols/value ;-- refreshing pointer + s: _hashtable/get-ctx-words ctx ;-- refreshing pointer s/tail - s/offset > base ;-- TRUE: new words added ] @@ -783,7 +776,7 @@ object: context [ ctx: TO_CTX(node) s: as series! ctx/values/value if s/offset = s/tail [ - ss: as series! ctx/symbols/value + ss: _hashtable/get-ctx-words ctx sz: (as-integer (ss/tail - ss/offset)) >> 4 s/tail: s/offset + sz ;-- (late) setting of 'values right tail pointer ] @@ -883,7 +876,7 @@ object: context [ cell: s/offset tail: s/tail - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx base: s/tail - s/offset while [cell < tail][ @@ -1030,7 +1023,7 @@ object: context [ return as red-block! integer/box obj/class ] field = words/words [ - blk/node: ctx/symbols + blk/node: _hashtable/get-ctx-symbols ctx blk: block/clone blk no no word: as red-word! block/rs-head blk @@ -1046,14 +1039,14 @@ object: context [ blk: block/clone blk no no ] field = words/body [ - blk/node: ctx/symbols + blk/node: _hashtable/get-ctx-symbols ctx len: block/rs-length? blk if len = 0 [len: 1] blk/header: TYPE_UNSET blk/node: alloc-cells len blk/header: TYPE_BLOCK - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx syms: s/offset tail: s/tail @@ -1214,12 +1207,12 @@ object: context [ ] ctx1: GET_CTX(obj1) - s: as series! ctx1/symbols/value + s: _hashtable/get-ctx-words ctx1 sym1: as red-word! s/offset tail: as red-word! s/tail ctx2: GET_CTX(obj2) - s: as series! ctx2/symbols/value + s: _hashtable/get-ctx-words ctx2 diff: (as-integer s/tail - s/offset) - (as-integer tail - sym1) if diff <> 0 [ @@ -1299,7 +1292,7 @@ object: context [ ] ctx: GET_CTX(obj) - src: as series! ctx/symbols/value + src: _hashtable/get-ctx-words ctx size: as-integer src/tail - src/offset slots: size >> 4 @@ -1317,7 +1310,9 @@ object: context [ if size <= 0 [return new] ;-- empty object! ;-- process SYMBOLS - dst: as series! nctx/symbols/value + _hashtable/copy-to ctx/symbols nctx/symbols + src: _hashtable/get-ctx-words ctx + dst: _hashtable/get-ctx-words nctx copy-memory as byte-ptr! dst/offset as byte-ptr! src/offset size dst/tail: dst/offset + slots _context/set-context-each dst new/ctx diff --git a/runtime/datatypes/set-word.reds b/runtime/datatypes/set-word.reds index edde3399c0..9f9b604c18 100644 --- a/runtime/datatypes/set-word.reds +++ b/runtime/datatypes/set-word.reds @@ -53,15 +53,10 @@ set-word: context [ node [node!] index [integer!] return: [red-word!] - /local - ctx [red-context!] - s [series!] ][ #if debug? = yes [if verbose > 0 [print-line "set-word/push-local"]] - ctx: TO_CTX(node) - s: as series! ctx/symbols/value - push as red-word! s/offset + index + push _hashtable/get-ctx-word TO_CTX(node) index ] set: func [ diff --git a/runtime/datatypes/word.reds b/runtime/datatypes/word.reds index 860986c170..2b56ad5bbf 100644 --- a/runtime/datatypes/word.reds +++ b/runtime/datatypes/word.reds @@ -110,10 +110,8 @@ word: context [ s [series!] ][ #if debug? = yes [if verbose > 0 [print-line "word/from"]] - - ctx: TO_CTX(node) - s: as series! ctx/symbols/value - as red-word! s/offset + index + + _hashtable/get-ctx-word TO_CTX(node) index ] at: func [ @@ -123,7 +121,6 @@ word: context [ /local ctx [red-context!] idx [integer!] - s [series!] ][ #if debug? = yes [if verbose > 0 [print-line "word/at"]] @@ -132,8 +129,7 @@ word: context [ either idx < 0 [ _context/add-global sym ][ - s: as series! ctx/symbols/value - as red-word! s/offset + idx + _hashtable/get-ctx-word ctx idx ] ] @@ -165,7 +161,7 @@ word: context [ ctx: TO_CTX(node) if null? ctx/values [ - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx fire [TO_ERROR(script not-defined) s/offset + index] ] diff --git a/runtime/debug-tools.reds b/runtime/debug-tools.reds index 8ec80d1204..1a8af16bd2 100644 --- a/runtime/debug-tools.reds +++ b/runtime/debug-tools.reds @@ -98,13 +98,12 @@ memory-info: func [ #if debug? = yes [ dump-globals: func [ - /local ctx sym-table val-table len s symbol value w sym val syms i + /local ctx val-table len s symbol value w sym val syms i ][ ctx: TO_CTX(global-ctx) - sym-table: ctx/symbols val-table: ctx/values - s: as series! sym-table/value + s: _hashtable/get-ctx-words ctx len: (as-integer s/tail - s/offset) >> 4 + 1 symbol: s/offset diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 181b6e430f..a9ffe13833 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -175,14 +175,16 @@ _hashtable: context [ val [red-value!] end [red-value!] node [node!] + type [integer!] ][ collector/keep table s: as series! table/value h: as hashtable! s/offset - if h/type = HASH_TABLE_HASH [collector/keep h/indexes] + type: h/type + if type = HASH_TABLE_HASH [collector/keep h/indexes] collector/keep h/flags collector/keep h/keys - if h/type = HASH_TABLE_INTEGER [collector/keep h/blk] + if type > 1 [collector/keep h/blk] ] sweep: func [ @@ -257,6 +259,8 @@ _hashtable: context [ /local sym [red-string!] s [series!] ][ switch TYPE_OF(key) [ + TYPE_INTEGER [key/data2] + TYPE_WORD [symbol/resolve key/data2] TYPE_SYMBOL [hash-symbol as red-symbol! key] TYPE_STRING TYPE_FILE @@ -265,23 +269,18 @@ _hashtable: context [ TYPE_EMAIL [ hash-string as red-string! key case? ] - TYPE_CHAR - TYPE_INTEGER [key/data2] + TYPE_CHAR [key/data2] TYPE_FLOAT TYPE_PAIR TYPE_PERCENT TYPE_TIME [ murmur3-x86-32 (as byte-ptr! key) + 8 8 ] - TYPE_WORD TYPE_SET_WORD TYPE_LIT_WORD TYPE_GET_WORD TYPE_REFINEMENT - TYPE_ISSUE [ - s: GET_BUFFER(symbols) - hash-symbol as red-symbol! s/offset + key/data2 - 1 - ] + TYPE_ISSUE [symbol/resolve key/data2] TYPE_BINARY [ sym: as red-string! key s: GET_BUFFER(sym) @@ -1083,6 +1082,27 @@ _hashtable: context [ new ] + copy-to: func [ + node [node!] + dst [node!] + return: [node!] + /local s [series!] h [hashtable!] ss [series!] hh [hashtable!] blk [node!] + ][ + s: as series! node/value + h: as hashtable! s/offset + + ss: as series! dst/value + hh: as hashtable! ss/offset + blk: hh/blk + + copy-memory as byte-ptr! hh as byte-ptr! h size? hashtable! + hh/blk: blk + hh/flags: copy-series as series! h/flags/value + hh/keys: copy-series as series! h/keys/value + + dst + ] + clear: func [ ;-- only for clear hash! datatype node [node!] head [integer!] @@ -1358,4 +1378,123 @@ _hashtable: context [ (as-integer k - blk) >> 4 + 1 ] + + get-ctx-symbol: func [ + node [node!] + key [integer!] ;-- symbol id + case? [logic!] ;-- YES: case insensitive + ctx [node!] ;-- if cxt <> null, create a new word in the context + new-id [int-ptr!] + return: [integer!] + /local + s [series!] + h [hashtable!] + i [integer!] + flags [int-ptr!] + last [integer!] + mask [integer!] + step [integer!] + keys [int-ptr!] + ii [integer!] + hash [integer!] + kk [integer!] + sh [integer!] + blk [red-word!] + k [red-word!] + sym [integer!] + ][ + s: as series! node/value + h: as hashtable! s/offset + + if all [ctx <> null h/n-occupied >= h/upper-bound][ ;-- update the hash table + i: either h/n-buckets > (h/size << 1) [-1][1] + kk: h/n-buckets + i + resize node kk << 4 + ] + + s: as series! h/keys/value + keys: as int-ptr! s/offset + s: as series! h/flags/value + flags: as int-ptr! s/offset + s: as series! h/blk/value + blk: as red-word! s/offset + + hash: symbol/resolve key + kk: either case? [hash][key] + mask: h/n-buckets - 1 + i: hash and mask + _HT_CAL_FLAG_INDEX(i ii sh) + i: i + 1 + last: i + step: 0 + while [_BUCKET_IS_NOT_EMPTY(flags ii sh)][ + k: blk + keys/i + sym: either case? [symbol/resolve k/symbol][k/symbol] + either kk <> sym [ + i: i + step and mask + _HT_CAL_FLAG_INDEX(i ii sh) + i: i + 1 + step: step + 1 + if i = last [assert 0 = 1 break] ;-- should not happen + ][break] + ] + + either ctx <> null [ + either _BUCKET_IS_EMPTY(flags ii sh) [ + _BUCKET_SET_BOTH_FALSE(flags ii sh) + h/size: h/size + 1 + h/n-occupied: h/n-occupied + 1 + ii: (as-integer s/tail - s/offset) >> 4 ;-- index is zero-base + keys/i: ii + + k: as red-word! alloc-tail s + k/header: TYPE_WORD ;-- force word! type + k/index: ii + k/ctx: ctx + k/symbol: key + new-id/value: ii + -1 + ][new-id/value: keys/i keys/i] + ][ + either _BUCKET_IS_EMPTY(flags ii sh) [-1][keys/i] + ] + ] + + get-ctx-word: func [ + ctx [red-context!] + idx [integer!] ;-- word index + return: [red-word!] + /local + s [series!] + h [hashtable!] + ][ + s: as series! ctx/symbols/value + h: as hashtable! s/offset + s: as series! h/blk/value + as red-word! s/offset + idx + ] + + get-ctx-words: func [ + ctx [red-context!] + return: [series!] + /local + s [series!] + h [hashtable!] + ][ + s: as series! ctx/symbols/value + h: as hashtable! s/offset + as series! h/blk/value + ] + + get-ctx-symbols: func [ + ctx [red-context!] + return: [node!] + /local + s [series!] + h [hashtable!] + ][ + s: as series! ctx/symbols/value + h: as hashtable! s/offset + h/blk + ] ] diff --git a/runtime/ownership.reds b/runtime/ownership.reds index 40971fda64..4cb5799150 100644 --- a/runtime/ownership.reds +++ b/runtime/ownership.reds @@ -152,7 +152,7 @@ ownership: context [ tail: s/tail cycles/push ctx/values - s: as series! ctx/symbols/value + s: _hashtable/get-ctx-words ctx word: as red-word! s/offset while [value < tail][ diff --git a/runtime/redbin.reds b/runtime/redbin.reds index 38c844bfa5..3139a4a8b3 100644 --- a/runtime/redbin.reds +++ b/runtime/redbin.reds @@ -162,20 +162,14 @@ redbin: context [ s/tail: s/offset + slots ] - symbols: ctx/symbols data: data + 2 i: 0 while [slots > 0][ sym: table + data/1 ;-- create the words entries in the symbol table of the context - slot: as red-word! alloc-tail as series! symbols/value - slot/header: TYPE_WORD - slot/ctx: new - slot/symbol: sym/1 - slot/index: i + _context/find-or-store ctx sym/1 yes new :i - i: i + 1 data: data + 1 slots: slots - 1 ] From 5cd978825871c6426e6c0a6ba69547e25e7a5af8 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 17 Oct 2019 11:52:45 +0200 Subject: [PATCH 0270/3432] FIX: a few wrong tests. --- environment/lexer.red | 1 + tests/source/units/load-test.red | 2 +- tests/source/units/recycle-test.red | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/environment/lexer.red b/environment/lexer.red index 80d83a383e..2ff33caebc 100644 --- a/environment/lexer.red +++ b/environment/lexer.red @@ -315,6 +315,7 @@ system/lexer: context [ end [string!] type [datatype!] ][ + if (index? start) = (index? end) [throw-error [type back start]] store stack make-word start end type ] diff --git a/tests/source/units/load-test.red b/tests/source/units/load-test.red index 795b13edf1..917f67df69 100644 --- a/tests/source/units/load-test.red +++ b/tests/source/units/load-test.red @@ -305,7 +305,7 @@ Red [ --test-- "load a<=>" --assert error? res: try [load "a<=>"] - --assert to logic! find/match form res {*** Syntax Error: invalid value at "<=>"^/*** Where:} + --assert to logic! find/match form res {*** Syntax Error: invalid word! at "a<=>"^/*** Where:} --test-- "load a" --assert not error? res: try [load "a"] diff --git a/tests/source/units/recycle-test.red b/tests/source/units/recycle-test.red index 590d5f0353..1e010ccc0f 100644 --- a/tests/source/units/recycle-test.red +++ b/tests/source/units/recycle-test.red @@ -649,6 +649,7 @@ Red [ clear ro2-o/c clear ro2-o/d clear ro2-o/e + ro2-o: none recycle ro2-mem2: stats From a3e59b924b2ccce927eeddd90411e759d21e3345 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 17 Oct 2019 11:55:55 +0200 Subject: [PATCH 0271/3432] FIX: crashes due to changes in context (use hashtable now). --- runtime/datatypes/context.reds | 4 ++-- runtime/datatypes/object.reds | 2 +- runtime/datatypes/symbol.reds | 11 +++++++---- runtime/datatypes/word.reds | 11 ++++++++--- runtime/hashtable.reds | 10 +++++----- runtime/simple-io.reds | 5 ++++- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index 853524054c..0bea6bae88 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -324,8 +324,8 @@ _context: context [ ctx/header and flag-series-stk <> 0 ctx/header and flag-self-mask <> 0 - ctx: TO_CTX(new) - dst: _hashtable/get-ctx-words ctx + _hashtable/copy-to ctx TO_CTX(new) + dst: _hashtable/get-ctx-words TO_CTX(new) dst/tail: dst/offset + slots sym: as red-word! dst/offset diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index f1563f71a7..fb84da4cf4 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -1310,7 +1310,7 @@ object: context [ if size <= 0 [return new] ;-- empty object! ;-- process SYMBOLS - _hashtable/copy-to ctx/symbols nctx/symbols + _hashtable/copy-to ctx nctx src: _hashtable/get-ctx-words ctx dst: _hashtable/get-ctx-words nctx copy-memory as byte-ptr! dst/offset as byte-ptr! src/offset size diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index dd39f31ea3..a986ef75af 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -56,11 +56,11 @@ symbol: context [ len [integer!] ;-- -1: use the whole string return: [integer!] /local - sym [red-symbol!] - id [integer!] + s [c-string!] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make-alt"]] - 1 + s: unicode/to-utf8 str :len + make-alt-utf8 as byte-ptr! s len ] make-alt-utf8: func [ @@ -85,9 +85,12 @@ symbol: context [ return: [red-symbol!] /local s [series!] + sym [red-symbol!] ][ s: GET_BUFFER(symbols) - as red-symbol! s/offset + id - 1 + sym: as red-symbol! s/offset + id - 1 + make-red-string sym + sym ] resolve: func [ diff --git a/runtime/datatypes/word.reds b/runtime/datatypes/word.reds index 2b56ad5bbf..32cd37c3e5 100644 --- a/runtime/datatypes/word.reds +++ b/runtime/datatypes/word.reds @@ -283,9 +283,12 @@ word: context [ /local s [series!] str [red-string!] + sym [red-value!] ][ s: GET_BUFFER(symbols) - str: as red-string! stack/push s/offset + w/symbol - 1 + sym: s/offset + w/symbol - 1 + symbol/make-red-string as red-symbol! sym + str: as red-string! stack/push sym str/header: TYPE_STRING str/head: 0 str/cache: null @@ -299,11 +302,13 @@ word: context [ buf [series!] s [c-string!] cp [integer!] + n [integer!] c [byte!] ][ + n: 0 sym: symbol/get w/symbol - buf: as series! sym/node/value - cp: string/get-char as byte-ptr! buf/offset GET_UNIT(buf) + buf: as series! sym/cache/value + cp: unicode/decode-utf8-char as c-string! buf/offset :n if cp > 127 [exit] c: as-byte cp diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index a9ffe13833..04477d397e 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1083,15 +1083,15 @@ _hashtable: context [ ] copy-to: func [ - node [node!] - dst [node!] - return: [node!] + node [red-context!] + dst [red-context!] + return: [red-context!] /local s [series!] h [hashtable!] ss [series!] hh [hashtable!] blk [node!] ][ - s: as series! node/value + s: as series! node/symbols/value h: as hashtable! s/offset - ss: as series! dst/value + ss: as series! dst/symbols/value hh: as hashtable! ss/offset blk: hh/blk diff --git a/runtime/simple-io.reds b/runtime/simple-io.reds index 8b05a73c47..dd2a0aa6be 100644 --- a/runtime/simple-io.reds +++ b/runtime/simple-io.reds @@ -1425,6 +1425,7 @@ simple-io: context [ parr [integer!] buf [byte-ptr!] headers [int-ptr!] + sym [red-value!] ][ res: as red-value! none-value parr: 0 @@ -1448,7 +1449,9 @@ simple-io: context [ true [ either method = words/post [action: #u16 "POST"][ s: GET_BUFFER(symbols) - copy-cell s/offset + method - 1 as cell! str1 + sym: s/offset + method - 1 + symbol/make-red-string as red-symbol! sym + copy-cell sym as cell! str1 str1/header: TYPE_STRING str1/head: 0 str1/cache: null From ec4e0f22a26f9981d3ee46a03df291b9aab24851 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 17 Oct 2019 17:38:32 +0800 Subject: [PATCH 0272/3432] FIX: add show-widget --- modules/view/backends/gtk3/gtk.reds | 29 +++++++++++++--------- modules/view/backends/gtk3/gui.reds | 37 ++++++++++++++++------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 304f2e61f9..ea552530e9 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1163,6 +1163,9 @@ GPtrArray!: alias struct! [ type [integer!] return: [handle!] ] + gtk_window_activate_focus: "gtk_window_activate_focus" [ + window [handle!] + ] gtk_window_set_title: "gtk_window_set_title" [ window [handle!] title [c-string!] @@ -1234,27 +1237,31 @@ GPtrArray!: alias struct! [ event [handle!] ] gtk_window_get_focus: "gtk_window_get_focus" [ - window [handle!] - return: [handle!] + window [handle!] + return: [handle!] ] gtk_window_set_focus: "gtk_window_set_focus" [ - window [handle!] - widget [handle!] + window [handle!] + widget [handle!] ] gtk_window_get_default_widget: "gtk_window_get_default_widget" [ - window [handle!] - return: [handle!] + window [handle!] + return: [handle!] ] gtk_window_set_default: "gtk_window_set_default" [ - window [handle!] - default_widget [handle!] + window [handle!] + default [handle!] + ] + gtk_window_set_keep_above: "gtk_window_set_keep_above" [ + window [handle!] + setting [logic!] ] gtk_offscreen_window_new: "gtk_offscreen_window_new" [ return: [handle!] ] gtk_offscreen_window_get_pixbuf: "gtk_offscreen_window_get_pixbuf" [ - window [handle!] - return: [handle!] + window [handle!] + return: [handle!] ] gtk_propagate_event: "gtk_propagate_event" [ widget [handle!] @@ -1279,7 +1286,7 @@ GPtrArray!: alias struct! [ gtk_widget_event: "gtk_widget_event" [ widget [handle!] event [handle!] - return: [logic!] + return: [logic!] ] gtk_widget_queue_draw: "gtk_widget_queue_draw" [ widget [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 6c38d0381f..6320fbadc6 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -336,6 +336,24 @@ set-widget-child-offset: func [ ] ] +show-widget: func [ + widget [handle!] + /local + values [red-value!] + type [red-word!] + sym [integer!] + layout [handle!] +][ + values: get-face-values widget + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + layout: get-face-layout widget values sym + if layout <> widget [ + gtk_widget_show layout + ] + gtk_widget_show widget +] + set-view-no-wait: func [ window [handle!] key [logic!] @@ -1606,28 +1624,15 @@ OS-refresh-window: func [ ][ if widget <> 0 [ ;-- view engine should make sure a valid handle, but it not gtk_widget_queue_draw as handle! widget - OS-show-window widget ] ] OS-show-window: func [ widget [integer!] - /local - handle [handle!] - values [red-value!] - type [red-word!] - sym [integer!] - layout [handle!] ][ - handle: as handle! widget - values: get-face-values handle - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - layout: get-face-layout handle values sym - if layout <> handle [ - gtk_widget_show layout - ] - gtk_widget_show handle + show-widget as handle! widget + set-selected-focus as handle! widget + gtk_window_set_keep_above as handle! widget true ] OS-make-view: func [ From fac05e97ca8284054ed7a5f839ce9ed349118964 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 17 Oct 2019 18:39:26 +0800 Subject: [PATCH 0273/3432] FIX: revert gtk_layout_set_size for gtk_layout --- modules/view/backends/gtk3/gui.reds | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 6320fbadc6..d1925b11d4 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -286,17 +286,6 @@ set-widget-child: func [ ] ] -set-widget-size: func [ - widget [handle!] - size [red-pair!] -][ - either g_type_check_instance_is_a widget gtk_layout_get_type [ - gtk_layout_set_size widget size/x size/y - ][ - gtk_widget_set_size_request widget size/x size/y - ] -] - set-widget-offset: func [ parent [handle!] widget [handle!] @@ -965,10 +954,10 @@ change-size: func [ sym: symbol/resolve ntype/symbol layout: get-face-layout widget values sym if layout <> widget [ - set-widget-size layout size + gtk_widget_set_size_request layout size/x size/y gtk_widget_queue_resize layout ] - set-widget-size widget size + gtk_widget_set_size_request widget size/x size/y gtk_widget_queue_resize widget ] ] @@ -1721,9 +1710,11 @@ OS-make-view: func [ ] sym = base [ widget: gtk_layout_new null null + gtk_layout_set_size widget size/x size/y ] sym = rich-text [ widget: gtk_layout_new null null + gtk_layout_set_size widget size/x size/y container: gtk_scrolled_window_new null null gtk_container_add container widget ] @@ -1825,6 +1816,7 @@ OS-make-view: func [ ] sym = panel [ widget: gtk_layout_new null null + gtk_layout_set_size widget size/x size/y ] sym = tab-panel [ widget: gtk_notebook_new From a005f572d9091b72f76d643a5a15319620542108 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 17 Oct 2019 13:11:16 +0200 Subject: [PATCH 0274/3432] FIX: a wrong test. --- tests/source/units/regression-test-red.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 76c171ad37..e2d2bfc7e7 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -1392,7 +1392,7 @@ Red [ e1116: try [sin1116] --assert true? all [ error? e1116 - not equal? ' e1116/arg3 + not equal? "" mold e1116/arg3 ] --test-- "#1119" From a0ea3a24e0072610a62f645d7212f1360dfc4649 Mon Sep 17 00:00:00 2001 From: loziniak Date: Thu, 17 Oct 2019 14:10:07 +0200 Subject: [PATCH 0275/3432] FIX: libRedRT export string/load-at --- system/utils/libRedRT-exports.r | 40 ++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index f4d3beaa5b..e1d64402d9 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -376,7 +376,45 @@ red/natives/recycle* ;-- for view backend - red/symbol/resolve red/object/get-word red/fire red/datatype/register red/block/rs-tail red/stack/push* red/word/push* red/block/rs-clear red/object/rs-find red/block/make-at red/handle/make-in red/unicode/to-utf8 red/string/to-hex red/integer/make-in red/logic/make-in red/OS-image/to-pixbuf red/string/make-at red/unicode/load-utf8-buffer red/unicode/utf8-next-char red/ownership/bind red/integer/make-at red/string/load red/set-type red/unicode/load-utf8-stream red/word/make-at red/word/push-in red/block/select-word red/block/find red/_series/remove red/OS-image/load-pixbuf red/image/init-image red/OS-image/lock-bitmap red/OS-image/get-data red/OS-image/unlock-bitmap red/OS-image/buffer-argb-to-abgr red/ownership/check red/report red/_context/set + red/symbol/resolve + red/object/get-word + red/fire + red/datatype/register + red/block/rs-tail + red/stack/push* + red/word/push* + red/block/rs-clear + red/object/rs-find + red/block/make-at + red/handle/make-in + red/unicode/to-utf8 + red/string/to-hex + red/integer/make-in + red/logic/make-in + red/OS-image/to-pixbuf + red/string/make-at + red/unicode/load-utf8-buffer + red/unicode/utf8-next-char + red/ownership/bind + red/integer/make-at + red/string/load + red/set-type + red/unicode/load-utf8-stream + red/word/make-at + red/word/push-in + red/block/select-word + red/block/find + red/_series/remove + red/OS-image/load-pixbuf + red/image/init-image + red/OS-image/lock-bitmap + red/OS-image/get-data + red/OS-image/unlock-bitmap + red/OS-image/buffer-argb-to-abgr + red/ownership/check + red/report + red/_context/set + red/string/load-at ][ red/root red-block! red/object/path-parent cell! From 302cdd3033dd3a10118c25a3b44cf1b3a51ac9fd Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 17 Oct 2019 17:26:46 +0200 Subject: [PATCH 0276/3432] FEAT: optimize object copy. --- runtime/datatypes/context.reds | 39 +++++---------------- runtime/datatypes/object.reds | 22 ++++++------ runtime/hashtable.reds | 60 +++++++++++++++++++-------------- runtime/red.reds | 4 +-- runtime/redbin.reds | 2 +- system/utils/libRedRT-exports.r | 2 +- 6 files changed, 59 insertions(+), 70 deletions(-) diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index 0bea6bae88..2a54dc5ab3 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -299,7 +299,7 @@ _context: context [ get-in word TO_CTX(node) ] - clone: func [ + clone-words: func [ ;-- clone a context. only copy words, without values slot [red-block!] return: [node!] /local @@ -323,22 +323,14 @@ _context: context [ slots ctx/header and flag-series-stk <> 0 ctx/header and flag-self-mask <> 0 - - _hashtable/copy-to ctx TO_CTX(new) - dst: _hashtable/get-ctx-words TO_CTX(new) - dst/tail: dst/offset + slots - sym: as red-word! dst/offset - - copy-memory - as byte-ptr! sym - as byte-ptr! src/offset - slots << 4 + ctx - while [slots > 0][ + sym: as red-word! _hashtable/get-ctx-word TO_CTX(new) 0 + loop slots [ sym/ctx: new sym: sym + 1 - slots: slots - 1 ] + obj/ctx: new new ] @@ -347,6 +339,7 @@ _context: context [ slots [integer!] ;-- max number of words in the context stack? [logic!] ;-- TRUE: alloc values on stack, FALSE: alloc them from heap self? [logic!] + proto [red-context!] ;-- if proto <> null, copy all the words in the proto context return: [node!] /local cell [red-context!] @@ -362,7 +355,7 @@ _context: context [ slot: alloc-tail as series! node/value ;-- allocate a slot for obj/func back-reference slot/header: TYPE_UNSET cell/header: TYPE_UNSET ;-- implicit reset of all header flags - symbols: _hashtable/init slots null HASH_TABLE_SYMBOL 1 ;@@ create the node! on native stack, so it can be marked by GC + symbols: _hashtable/init slots as red-block! proto HASH_TABLE_SYMBOL HASH_SYMBOL_CONTEXT ;@@ create the node! on native stack, so it can be marked by GC cell/self: node either stack? [ @@ -393,7 +386,7 @@ _context: context [ type [integer!] i [integer!] ][ - new: create block/rs-length? spec stack? self? + new: create block/rs-length? spec stack? self? null ctx: TO_CTX(new) s: GET_BUFFER(spec) cell: s/offset @@ -484,22 +477,6 @@ _context: context [ body ] - set-context-each: func [ - s [series!] - node [node!] - /local - p [red-word!] - tail [red-word!] - ][ - p: as red-word! s/offset - tail: as red-word! s/tail - - while [p < tail][ - p/ctx: node - p: p + 1 - ] - ] - collect-set-words: func [ ctx [red-context!] spec [red-block!] diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index fb84da4cf4..081d92f3b6 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -846,7 +846,7 @@ object: context [ s [series!] ][ obj/header: TYPE_UNSET - obj/ctx: _context/create slots no yes + obj/ctx: _context/create slots no yes null obj/class: 0 obj/on-set: null obj/header: TYPE_OBJECT @@ -1282,6 +1282,8 @@ object: context [ size [integer!] slots [integer!] type [integer!] + sym [red-word!] + w-ctx [node!] ][ #if debug? = yes [if verbose > 0 [print-line "object/copy"]] @@ -1298,24 +1300,24 @@ object: context [ copy-cell as cell! obj as cell! new new/header: TYPE_UNSET - new/ctx: _context/create slots no yes + new/ctx: _context/create slots no yes ctx new/class: obj/class new/header: TYPE_OBJECT - nctx: GET_CTX(new) + nctx: GET_CTX(new) copy-cell as red-value! new as red-value! nctx + 1 ;-- set back-reference node: save-self-object new if size <= 0 [return new] ;-- empty object! - + ;-- process SYMBOLS - _hashtable/copy-to ctx nctx - src: _hashtable/get-ctx-words ctx - dst: _hashtable/get-ctx-words nctx - copy-memory as byte-ptr! dst/offset as byte-ptr! src/offset size - dst/tail: dst/offset + slots - _context/set-context-each dst new/ctx + sym: _hashtable/get-ctx-word nctx 0 + w-ctx: new/ctx + loop slots [ + sym/ctx: w-ctx + sym: sym + 1 + ] ;-- process VALUES src: as series! ctx/values/value diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 04477d397e..8d24fae3d1 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -20,6 +20,9 @@ Red/System [ #define HASH_TABLE_SYMBOL 2 #define HASH_TABLE_INTEGER 3 +#define HASH_SYMBOL_BLOCK 1 +#define HASH_SYMBOL_CONTEXT 2 + #define _HT_HASH_UPPER 0.77 #define _BUCKET_IS_EMPTY(flags i s) [flags/i >> s and 2 = 2] @@ -375,6 +378,30 @@ _hashtable: context [ node ] + copy-context: func [ + ctx [red-context!] + node [node!] + return: [node!] + /local + s [series!] + h [hashtable!] + ss [series!] + hh [hashtable!] + ][ + s: as series! ctx/symbols/value + h: as hashtable! s/offset + + ss: as series! node/value + hh: as hashtable! s/offset + + copy-memory as byte-ptr! hh as byte-ptr! h size? hashtable! + hh/blk: copy-series as series! h/blk/value + hh/flags: copy-series as series! h/flags/value + hh/keys: copy-series as series! h/keys/value + + node + ] + init: func [ size [integer!] blk [red-block!] @@ -394,15 +421,19 @@ _hashtable: context [ skip [integer!] ][ node: _alloc-bytes-filled size? hashtable! #"^(00)" - s: as series! node/value - h: as hashtable! s/offset - h/type: type - if type = HASH_TABLE_INTEGER [h/indexes: as node! vsize + 1 << 4] if type = HASH_TABLE_SYMBOL [ if null? str-buffer [str-buffer: allocate str-buffer-sz] + if all [vsize = HASH_SYMBOL_CONTEXT blk <> null][ + return copy-context as red-context! blk node + ] size: size << 4 ] + s: as series! node/value + h: as hashtable! s/offset + h/type: type + if type = HASH_TABLE_INTEGER [h/indexes: as node! vsize + 1 << 4] + if size < 32 [size: 32] fsize: as-float size f-buckets: fsize / _HT_HASH_UPPER @@ -1082,27 +1113,6 @@ _hashtable: context [ new ] - copy-to: func [ - node [red-context!] - dst [red-context!] - return: [red-context!] - /local s [series!] h [hashtable!] ss [series!] hh [hashtable!] blk [node!] - ][ - s: as series! node/symbols/value - h: as hashtable! s/offset - - ss: as series! dst/symbols/value - hh: as hashtable! ss/offset - blk: hh/blk - - copy-memory as byte-ptr! hh as byte-ptr! h size? hashtable! - hh/blk: blk - hh/flags: copy-series as series! h/flags/value - hh/keys: copy-series as series! h/keys/value - - dst - ] - clear: func [ ;-- only for clear hash! datatype node [node!] head [integer!] diff --git a/runtime/red.reds b/runtime/red.reds index dce5d527a2..133d2154f6 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -213,10 +213,10 @@ red: context [ arg-stk: block/make-fixed root 2 * 2000 call-stk: block/make-fixed root 20 * 2000 symbols: block/make-in root 4000 - global-ctx: _context/create 4000 no no + global-ctx: _context/create 4000 no no null case-folding/init - symbol/table: _hashtable/init 4000 symbols HASH_TABLE_SYMBOL 1 + symbol/table: _hashtable/init 4000 symbols HASH_TABLE_SYMBOL HASH_SYMBOL_BLOCK datatype/make-words ;-- build datatype names as word! values words/build ;-- create symbols used internally diff --git a/runtime/redbin.reds b/runtime/redbin.reds index 3139a4a8b3..790d36779e 100644 --- a/runtime/redbin.reds +++ b/runtime/redbin.reds @@ -146,7 +146,7 @@ redbin: context [ if values? [values: data + 2 + slots] - new: _context/create slots stack? self? + new: _context/create slots stack? self? null obj: as red-object! ALLOC_TAIL(parent) ;-- use an object to store the ctx node obj/header: TYPE_OBJECT obj/ctx: new diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index f3f0e77986..b8a6e20246 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -119,7 +119,7 @@ red/set-word/push-local red/_context/get - red/_context/clone + red/_context/clone-words red/_context/set-integer red/object/duplicate From d069b18e028751edc16254e85b2ce74e729b5fd7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 17 Oct 2019 17:46:20 +0200 Subject: [PATCH 0277/3432] FIX: some errors caused by last commit. --- compiler.r | 2 +- runtime/hashtable.reds | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler.r b/compiler.r index bac332791b..3d4331bf69 100644 --- a/compiler.r +++ b/compiler.r @@ -2048,7 +2048,7 @@ red: context [ unless all [empty? locals-stack not iterator-pending?][ ;-- in a function or iteration block emit compose [ - (to set-word! ctx) _context/clone get-root (blk-idx) ;-- rebuild context + (to set-word! ctx) _context/clone-words get-root (blk-idx) ;-- rebuild context ] insert-lf -3 ] diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 8d24fae3d1..98931e8b07 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -392,7 +392,7 @@ _hashtable: context [ h: as hashtable! s/offset ss: as series! node/value - hh: as hashtable! s/offset + hh: as hashtable! ss/offset copy-memory as byte-ptr! hh as byte-ptr! h size? hashtable! hh/blk: copy-series as series! h/blk/value From 5f4c36843b9685505727ffd4782afa3c5db659c5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 17 Oct 2019 20:19:41 +0200 Subject: [PATCH 0278/3432] FEAT: adds script for generating some lexer tables and bit-arrays. --- utils/generate-misc-tables.red | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 utils/generate-misc-tables.red diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red new file mode 100644 index 0000000000..e768a42686 --- /dev/null +++ b/utils/generate-misc-tables.red @@ -0,0 +1,74 @@ +Red [ + Title: "Red runtime lexer" + Author: "Nenad Rakocevic" + File: %generate-misc-tables.red + Tabs: 4 + Rights: "Copyright (C) 2014-2018 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + + +gen-bitarray: function [list][ + append/dup out: make binary! 32 null 32 + + foreach c list [ + pos: (to-integer c) / 8 + 1 + bit: 1 << ((to-integer c) // 8) + out/:pos: out/:pos or bit + ] + ?? out +] + +bin-classes: [ + C_BIN_SKIP ;-- 0 + C_BIN_BLANK ;-- 1 + C_BIN_LINE ;-- 2 + C_BIN_HEXA ;-- 3 + C_BIN_COMMENT ;-- 4 +] + +gen-bin16-table: function [][ + out: make binary! 256 + blank: charset "^-^M " + hexa: charset [#"A" - #"F" #"a" - #"f" #"0" - #"9"] + + repeat i 256 [ + c: to-char i - 1 + append out to-char case [ + find blank c [1] + c = #"^/" [2] + find hexa c [3] + c = #";" [4] + 'else [0] + ] + ] + print "--gen-bin16-table-- (lexer/bin16-classes)" + probe out +] + +gen-hexa-table: function [][ + out: make binary! 256 + digit: charset [#"0" - #"9"] + upper: charset [#"A" - #"F"] + lower: charset [#"a" - #"f"] + + repeat i 256 [ + c: to-char i - 1 + append out to-char case [ + find digit c [c - #"0"] + find upper c [c - #"A" + 10] + find lower c [c - #"a" + 10] + 'else [0] + ] + ] + print "--gen-hexa-table-- (lexer/hexa-table)" + probe out +] + +gen-bitarray probe "BDELNPTbdelnpt" +gen-bitarray probe {/-~^^{}"} +gen-bin16-table +gen-hexa-table \ No newline at end of file From e321475078671be371160791a8d50c57f09cae36 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 17 Oct 2019 20:40:11 +0200 Subject: [PATCH 0279/3432] FEAT: adds support for scanning base 16 binary! values. --- docs/lexer/lexer-FSM.csv | 4 +- docs/lexer/lexer-FSM.xlsx | Bin 15694 -> 17552 bytes docs/lexer/lexer-states.txt | 34 ++++++++++ runtime/lexer-transitions.reds | 4 +- runtime/lexer.reds | 116 ++++++++++++++++++++++++++++++++- 5 files changed, 151 insertions(+), 7 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 6ddee45ac4..436fed6210 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -9,8 +9,8 @@ S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_FILE S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;T_ERROR;S_BINARY;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index f10fd862c97112bc87690b91de7ff65cc7e10b55..0c8b609beb424baa0f2bba986462aaa5f1a14ee1 100644 GIT binary patch literal 17552 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 fDB=0HiT3f(7^B?iSqP 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 \->"$"->S_MONEY \->","|"#"|"%"->T_ERROR + + +=== Binary16 FSM + + +S_BIN_START ;-- 0 +S_BIN_1ST ;-- 1 +S_BIN_CMT ;-- 2 +S_BIN_FINAL_STATES ;-- 3 +T_BIN_BYTE ;-- 4 +T_BIN_ERROR ;-- 5 + + +C_BIN_SKIP : all the rest ;-- 0 +C_BIN_BLANK : space, tab, cr ;-- 1 +C_BIN_LINE : lf ;-- 2 +C_BIN_HEXA : 0-9, a-f, A-F ;-- 3 +C_BIN_CMT : ; ;-- 4 + + +hexa: 0-9, a-f, A-F +blan: space, tab, cr + + +S_BIN_START->hexa->S_BIN_1ST->hexa->T_BIN_BYTE + \ \->not(hexa)->T_BIN_ERROR + \ + \->blank->S_BIN_START + \ + \->;->S_BIN_CMT->lf->S_BIN_START + \->not(lf)->S_BIN_CMT \ No newline at end of file diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 4c107b6a15..521fb4fca1 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -82,8 +82,8 @@ Red/System [ 07070707072B3132320707323232323232070707320707070707070707073232 0707070807072B32070707070707070707070707070707070707070707070707 070707070707072B2B3333090933333333333333090909090909090909090909 -33330909090909092B33383810100F2B362B2B0B0D10102B10101010102B2B10 -2B38381010101010102B380B0B0B0B2B2B2B2B2B342B2B2B2B2B2B0B2B2B2B2B +33330909090909092B33383810100F2B362B0B2B0D10102B10101010102B2B10 +2B38381010101010102B380B0B0B0B2B2B2B2B2B342B2B2B2B2B0B0B2B2B2B2B 2B2B0C2B2B2B2B2B2B2B2B2B0C0B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C 0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D350D0D0D0D0D0D0D0D 0D0D0D0D0D0D0D0D0D0E0D0D2B350D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D diff --git a/runtime/lexer.reds b/runtime/lexer.reds index df90bc3ffc..d2a173c6ee 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -68,6 +68,23 @@ lexer: context [ C_EOF ;-- 32 ] + #enum bin16-char-classes! [ + C_BIN_SKIP ;-- 0 + C_BIN_BLANK ;-- 1 + C_BIN_LINE ;-- 2 + C_BIN_HEXA ;-- 3 + C_BIN_CMT ;-- 4 + ] + + #enum bin16-states! [ + S_BIN_START ;-- 0 + S_BIN_1ST ;-- 1 + S_BIN_CMT ;-- 2 + S_BIN_FINAL_STATES ;-- 3 + T_BIN_BYTE ;-- 4 + T_BIN_ERROR ;-- 5 + ] + line-table: #{ 000100000000000000000000000000000000000000000000000000000000000000 } @@ -78,6 +95,34 @@ lexer: context [ 00000000000000 } + bin16-classes: #{ + 0000000000000000000102000001000000000000000000000000000000000000 + 0100000000000000000000000000000003030303030303030303000400000000 + 0003030303030300000000000000000000000000000000000000000000000000 + 0003030303030300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + } + + bin16-FSM: #{ + 0000000102 + 0505050405 + 0202000202 + } + + hexa-table: #{ + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000010203040506070809000000000000 + 000A0B0C0D0E0F00000000000000000000000000000000000000000000000000 + 000A0B0C0D0E0F00000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + } + ;-- Bit-array for BDELNPTbdelnpt char-names-1st: #{0000000000000000345011003450110000000000000000000000000000000000} @@ -309,6 +354,7 @@ lexer: context [ class: lex-classes/index switch class [ C_DIGIT [cb: p/1 - #"0"] + C_EXP C_ALPHAX [cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cb: cb + 10] default [throw LEX_ERROR] ] @@ -483,7 +529,7 @@ lexer: context [ index: 1 + as-integer p/1 class: lex-classes/index switch class [ - C_DIGIT C_ZERO C_ALPHAX [0] + C_DIGIT C_ZERO C_ALPHAX C_EXP [0] default [w?: yes] ;-- early exit if not an hex value ] p: p + 1 @@ -592,9 +638,73 @@ lexer: context [ ] scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + bin [red-binary!] + p [byte-ptr!] + pos [byte-ptr!] + ser [series!] + c [integer!] + len [integer!] + size [integer!] + base [integer!] + index [integer!] + class [integer!] + fstate [integer!] ][ - null + either s/1 = #"#" [base: 16][ ;-- default base + base: 0 + while [s/1 <> #"#"][ ;-- decode head base value + base: base * 10 + as-integer s/1 - #"0" + s: s + 1 + ] + ] + assert s/2 = #"{" + s: s + 2 ;-- skip #{ + len: as-integer e - s + + size: switch base [ ;-- precalc required buffer size in bytes + 16 [len / 2] + 64 [len + 3 * 3 / 4] + 2 [len / 8] + default [throw LEX_ERROR 0] + ] + bin: binary/make-at alloc-slot state size + ser: GET_BUFFER(bin) + p: as byte-ptr! ser/offset + + switch base [ + 16 [ + while [s < e][ + fstate: S_BIN_START + pos: s + until [ ;-- scans 2 hex characters, skip the rest + index: 1 + as-integer s/1 + class: as-integer bin16-classes/index + s: s + 1 + index: fstate * 5 + class + 1 + fstate: as-integer bin16-FSM/index + any [fstate - S_BIN_FINAL_STATES > 0 s >= e] + ] + if fstate = T_BIN_ERROR [throw LEX_ERROR] + index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables + c: as-integer hexa-table/index + index: 1 + as-integer pos/2 + p/value: as byte! c << 4 or as-integer hexa-table/index + p: p + 1 + ] + ser/tail: as cell! p + ] + 64 [ + 0 + ] + 2 [ + 0 + ] + default [assert false 0] + ] + assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail + + state/in-pos: e + 1 ;-- skip ending delimiter ] scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 243731955b0a279f3bf744a5f2e38ade8c64d558 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 17 Oct 2019 21:53:39 +0200 Subject: [PATCH 0280/3432] FEAT: minor generator script formatting improvements. --- utils/generate-misc-tables.red | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index e768a42686..c96b9854b3 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -1,5 +1,5 @@ Red [ - Title: "Red runtime lexer" + Title: "Binary tables and bit-arrays generator for the lexer" Author: "Nenad Rakocevic" File: %generate-misc-tables.red Tabs: 4 @@ -10,7 +10,6 @@ Red [ } ] - gen-bitarray: function [list][ append/dup out: make binary! 32 null 32 @@ -19,7 +18,8 @@ gen-bitarray: function [list][ bit: 1 << ((to-integer c) // 8) out/:pos: out/:pos or bit ] - ?? out + print ["--gen-bitarray-- for" mold list] + probe out ] bin-classes: [ @@ -68,7 +68,7 @@ gen-hexa-table: function [][ probe out ] -gen-bitarray probe "BDELNPTbdelnpt" -gen-bitarray probe {/-~^^{}"} +gen-bitarray "BDELNPTbdelnpt" +gen-bitarray {/-~^^{}"} gen-bin16-table gen-hexa-table \ No newline at end of file From 39e9e21b7a68adc32f5a38bc1536a842ad9640e9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 18 Oct 2019 10:43:26 +0200 Subject: [PATCH 0281/3432] FEAT: adds support for scanning base 2 binary! values. --- runtime/lexer.reds | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d2a173c6ee..efffd609b8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -644,6 +644,7 @@ lexer: context [ pos [byte-ptr!] ser [series!] c [integer!] + cnt [integer!] len [integer!] size [integer!] base [integer!] @@ -698,7 +699,26 @@ lexer: context [ 0 ] 2 [ - 0 + while [s < e][ + c: 0 + cnt: 8 + while [all [cnt > 0 s < e]][ + switch s/1 [ + #"0" #"1" [ + c: c << 1 + as-integer s/1 - #"0" + cnt: cnt - 1 + s: s + 1 + ] + #"^-" #"^/" #" " #"^M" [s: s + 1] + #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] + default [throw LEX_ERROR] + ] + ] + if all [cnt <> 0 cnt <> 8][throw LEX_ERROR] + p/value: as byte! c + p: p + 1 + ] + ser/tail: as cell! p ] default [assert false 0] ] From d5c203f90680c0dfc4274e0c3b1d168da11a542f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 18 Oct 2019 12:06:30 +0200 Subject: [PATCH 0282/3432] FEAT: moves binary decoders in separate functions. --- runtime/lexer.reds | 131 ++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 61 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index efffd609b8..1195db49ea 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -325,6 +325,68 @@ lexer: context [ ] ] + decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + /local + p [byte-ptr!] + c [integer!] + cnt [integer!] + ][ + p: as byte-ptr! ser/offset + + while [s < e][ + c: 0 + cnt: 8 + while [all [cnt > 0 s < e]][ + switch s/1 [ + #"0" #"1" [ + c: c << 1 + as-integer s/1 - #"0" + cnt: cnt - 1 + s: s + 1 + ] + #"^-" #"^/" #" " #"^M" [s: s + 1] + #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] + default [throw LEX_ERROR] + ] + ] + if all [cnt <> 0 cnt <> 8][throw LEX_ERROR] + p/value: as byte! c + p: p + 1 + ] + ser/tail: as cell! p + ] + + decode-16: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + /local + p [byte-ptr!] + pos [byte-ptr!] + c [integer!] + index [integer!] + class [integer!] + fstate [integer!] + ][ + p: as byte-ptr! ser/offset + + while [s < e][ + fstate: S_BIN_START + pos: s + until [ ;-- scans 2 hex characters, skip the rest + index: 1 + as-integer s/1 + class: as-integer bin16-classes/index + s: s + 1 + index: fstate * 5 + class + 1 + fstate: as-integer bin16-FSM/index + any [fstate - S_BIN_FINAL_STATES > 0 s >= e] + ] + if fstate = T_BIN_ERROR [throw LEX_ERROR] + index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables + c: as-integer hexa-table/index + index: 1 + as-integer pos/2 + p/value: as byte! c << 4 or as-integer hexa-table/index + p: p + 1 + ] + ser/tail: as cell! p + ] + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] @@ -639,18 +701,11 @@ lexer: context [ scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - bin [red-binary!] - p [byte-ptr!] - pos [byte-ptr!] - ser [series!] - c [integer!] - cnt [integer!] - len [integer!] - size [integer!] - base [integer!] - index [integer!] - class [integer!] - fstate [integer!] + bin [red-binary!] + ser [series!] + len [integer!] + size [integer!] + base [integer!] ][ either s/1 = #"#" [base: 16][ ;-- default base base: 0 @@ -671,59 +726,13 @@ lexer: context [ ] bin: binary/make-at alloc-slot state size ser: GET_BUFFER(bin) - p: as byte-ptr! ser/offset - switch base [ - 16 [ - while [s < e][ - fstate: S_BIN_START - pos: s - until [ ;-- scans 2 hex characters, skip the rest - index: 1 + as-integer s/1 - class: as-integer bin16-classes/index - s: s + 1 - index: fstate * 5 + class + 1 - fstate: as-integer bin16-FSM/index - any [fstate - S_BIN_FINAL_STATES > 0 s >= e] - ] - if fstate = T_BIN_ERROR [throw LEX_ERROR] - index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables - c: as-integer hexa-table/index - index: 1 + as-integer pos/2 - p/value: as byte! c << 4 or as-integer hexa-table/index - p: p + 1 - ] - ser/tail: as cell! p - ] - 64 [ - 0 - ] - 2 [ - while [s < e][ - c: 0 - cnt: 8 - while [all [cnt > 0 s < e]][ - switch s/1 [ - #"0" #"1" [ - c: c << 1 + as-integer s/1 - #"0" - cnt: cnt - 1 - s: s + 1 - ] - #"^-" #"^/" #" " #"^M" [s: s + 1] - #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] - default [throw LEX_ERROR] - ] - ] - if all [cnt <> 0 cnt <> 8][throw LEX_ERROR] - p/value: as byte! c - p: p + 1 - ] - ser/tail: as cell! p - ] + 16 [decode-16 s e ser] + 64 [0] + 2 [decode-2 s e ser] default [assert false 0] ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail - state/in-pos: e + 1 ;-- skip ending delimiter ] From b7d08ce23a2b29fd20de31a5923fc39a129146dc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 18 Oct 2019 12:53:20 +0200 Subject: [PATCH 0283/3432] FEAT: adds support for scanning base 64 binary! values. Note: embedded blanks characters not supported yet. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 17552 -> 17910 bytes runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 58 +++++++++++++++++++++++++++++++-- utils/generate-lexer-table.red | 2 +- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 436fed6210..9e85578595 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -10,7 +10,7 @@ S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_F S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 0c8b609beb424baa0f2bba986462aaa5f1a14ee1..3882eabfffdcd4573bff39ce0f79e18f1cb3a2dd 100644 GIT binary patch literal 17910 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 fDB=0HiT #"=" [ + accum: accum << 6 + val + flip: flip + 1 + if flip = 4 [ + p/1: as-byte accum >> 16 + p/2: as-byte accum >> 8 + p/3: as-byte accum + p: p + 3 + accum: 0 + flip: 0 + ] + ][ ;-- special padding: "=" + s: s + 1 + case [ + flip = 3 [ + p/1: as-byte accum >> 10 + p/2: as-byte accum >> 2 + p: p + 2 + flip: 0 + ] + flip = 2 [ + s: s + 1 + p/1: as-byte accum >> 4 + p: p + 1 + flip: 0 + ] + true [throw LEX_ERROR] + ] + break + ] + ][ + if val = 80h [throw LEX_ERROR] + ] + s: s + 1 + ] + ser/tail: as red-value! p + ] + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] @@ -728,8 +782,8 @@ lexer: context [ ser: GET_BUFFER(bin) switch base [ 16 [decode-16 s e ser] - 64 [0] - 2 [decode-2 s e ser] + 64 [decode-64 s e ser] + 2 [decode-2 s e ser] default [assert false 0] ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 7895c6ca2c..ab0de97e7c 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -90,7 +90,7 @@ context [ ;-- Determine CSV separator sep: [#";" 0 #"," 0] parse csv [some [#";" (sep/2: sep/2 + 1) | #"," (sep/4: sep/4 + 1) | skip]] - sort/skip/all/compare sep 2 func [a b][a/2 > b/2] + sort/skip/all/compare sep 2 func [a b][a/2 < b/2] ;-- Decode CSV matrix: load-csv/with read CSV-table first sep From 9735039f40de66fa473e25e4a18f89d64a924749 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 18 Oct 2019 16:17:25 +0200 Subject: [PATCH 0284/3432] FIX: C_X character class was not allowed in binary! values. Can be present in base64-encoded binaries. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 17910 -> 17555 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 9e85578595..d2f4eaf376 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -10,7 +10,7 @@ S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_F S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 3882eabfffdcd4573bff39ce0f79e18f1cb3a2dd..0d9cc8325a0ce2ff3ba17946ecd85eaade1bb117 100644 GIT binary patch literal 17555 zcmeHvWmH^Qw{0OI5Zr>hC1|0+-JRg>?(Xgy+#$HTgy0Z7xO)ih7A*KH(tW>lr*q|v z@&3GVzxqLqGm5=-?Y-ujbDqOq$Vxy!q5+@)&;S5{2tX7e%wobMbSn&)bperDF>VlrXZ5HCvg1)G zf@%9$qR%1F%q_y_V#g#WHjX)*UW)honPy?&NTfDIFk7=~%_`RU`Si{!oX2H`bQnqF zsOPPjU*hwGLW`-EQyLSY_#?)i-2-KjV3i~qC(xS-lMoExv(H>rrGX5%I0IgcKvF0X( z)XCL~VT@LN1}-BDF^ee?pr9Oz7=+b@7BYwV!ZntWH*i_hxdNraB2d?qle_AI5pHf>$_||7Wj`%_T15aCS!T}K7Pyzb_C#kc7t9Drp@`3s z=G;3oc|3P0KVB$=F1Ni20!%iyCRF@qC`|JOeDA*|S|&z$fspq22mz4&Te;RN0!c1F zpGbnL5f)Ug+IEH(_H?vQKmT2(|BGw$FH4Vz9hL3^!u1}Dwg_z8?pcXKXXiIdiZ&A| z;CGN75!6TKlJZ_%20-|U>o1O9ZjbV)e>vJRRUp9Cqm%Axdc{}GsOLUw=2HG%2{B8L z*w_@U4?7B1S9$r1g|49B-3{dW~uE}^DR*~US z{3cgWJH9Lp=X9qT^mF&;CEPch*EJ1HQr0eXTb_DJ(h=y=Z_y)ZHXm9$3(xLajt~f^X~8a(!Mt-{@yymxmFmkDrN9p zx3dRPLHoB=B3@jedjtAJ1OfoS20(+kSkV1ZD9+Y)=6crF=1;QrA4LNO(l(F){_lRZ z#15Nv1K|RW1Ka$^TWw<>WIwaJzYc8uu=pHUjS?(np6EjuFSmCc_`q5bkN!SqgE}ZW$aD{9C`QdGsS9Q-M(?H z&6z0~Vq4*!rTrKx6p^$hoT0D4G_i;-K4cM;Zl`gGr*Es-7&4)q1EOd@@0VWd99ZcO zMG^WsJ+o{%Hi~F0@l9+F-Q``+WBIU&FVSpRQQHw{4)7>dK@nmzZ=5>s2i88W0v&0n zT$mJB{4PaMV8h%sR+ww->(Xc6c5aU&uWDX>R$p?jd?mMZO+myJ;wN3r1aW6J*XF*H z|7q6~n=C%TILa2=0=}`>a4Ip{dt;!-*upU%Mkaq|5yOa#A z$KkyL6*3tD0093-O6(n6Ee!3Sig-wQ(Q1(u$&+r(8|iz+j^1EByqJ)s2(PbGHE#{C zwrOZ==r>|n2Q%mD$2NgIz5K{#;XRg8j2Mz{Ln%bt(P1n2toHaJW<_W)FRVN^kYWb? z!YKK?myM5b*&=&$IwW7jW|5eVEuLSLejFDOK5_~$c}^%8mz6PdF>#jaA;M~9WgrFV z@j8D^ML=0mOPi?HB#U5$BWiEpe8bsW*V_ftozF>&(qh>MlOTOwswse?0nXM1s4^s zm*2wshbTmK-cUxSRgORy>A*xM^)?#3Wy5BG=q?k|kzPPHAKFopV=U`VuhBP0i0mY< z#p!z;U=)$LI$k5TUXFE<=5gV*71VPKvumhPY?hWqt$w>j->GF@k8gOQmbFd;{H%;2 zn5any-F${U=N4a`jYMuV>Q5AzO~@=q>>o8*fBcU5zy)kUcVef0{XyR$|AZbocaVZ9 zcKlOS(aeXDpnjUT&!L9h)X>n({Z`p{l(;)8pci|Y%E!xx1q zah%Q6uyE(i5E7ee$ZClBVllOP2|wbGLTWyPk&6D}3we2QP9w0tULEd*Pw{N|td>!o zTV`_Cg)g2>_h97Yy8=QsHZn(i)ZAIb{#7&$D_X?Hxs=M6ius^vC&`ccbuZoFZaFo! zWf2fYs#5`-g{tticp9?@CI$=8HjD0kCSq!N;61P~( z4r+u#|BlRzg{6W+WO^6hgO_>T?ghue?_k*Lc^2Ye46<-8C_JMV_(^xB9(1Bcb&To~ zaL$khv~Rpzco%^NyUUH;Ro zqIOfGegb{M43;!gdaGhwga_&q!Y|K^lT_`S z%}R)+40${#*iB$vmh`Mf();E~)?T0E*LP*2-$nxl$YOQaazwfM6%Pjk^!WBgE|Z;a zaA6|$hnDS~K@|1RE#RL{4vXzs0fu~1jwz;!szSXqggVF-#3QsDax7*wtP)GzY%>U&q{bc^dUp}yPy2)c+vXjtSirM*th%Nc@Pd8!vw=c z9E#R3^*XOQaCJX;7~Nlw%*$!Ekmz3thh$u@5{23VAbaeDrPe}t?R8)ix9J~{f~pL7 zXr@{qCMr{sj*TA{Xvd91Q4(W4E80WWMS2@jg6@GQLD6*so~fL4DLFdql1CSoMG6}L zUkb{P^ISUEt~G}-6zt)r-Qj+6h)6gE=czcv!VZ;nue?|TBP+?zr6EmZ0{UUe#|_2^ zoP*D0qC20F;)>)Bcmstgpz0h6@vz$Ld(_%UQ-_S-;v!pE)l#F=i;$&*Uu_&iqfBBI zHoLDLnA*BShfBe)jQ~58YKtzrT5o|+!V&2G2xmZO;|H*pshLdSEK-%lsvk^mq=rkR z7){J(Xi|Yi%-kw+w_xE*Yr*q0G%w+_IDzYWa0ps?oF#=eA6VfzAInr7#;7?=lq^$q z88aQz$V-^v)pc&$23|5AEhLr#k21&uBpyB`iQxrbSd9zS9T2N!2u9BL4$sd#0+`Eu zQSZskhd!E{Yb`l*^qT5q(55#|P_vsPTBepRH=0dq4A(z27wE#KC%>83>%~%+46J%S zISu1%s%S9Cjoi4I&(9{&nb6^HF5L74dhKoH0M(qPsQ|vJv5#(e3$rZPH z`Ihk@3si{n^eFC!_jE8Zv^1pq@$&~k9H`1zFS4MuBhEP!I#^p$e873`7&cd(RxX9p zZ551fnv$p@pTj#L=83bg?gQ4PU3j6;2)ALKuo%6yI87O;TF=(O)$x7;_e)DFM)#}`=U>O$VGDDOSx;MVtI zB1Mc3#!P%czMwUI*YbI0`o$MX4ElOKOI^*Cy9vi#zf*_d6SU4(#%lYs>dH=bH&7i@ z3>CBcj_&p8nP56A&!x(#g;Fmbgv;Z`seKOC84j)L<;t7CgWq3}rKo2}7mkY?Rtv)S zbI&B5;7l8Nx(|2aMEAT&Jh>QgYFKnQfigH9Ci8d{FI9Cug+gP%mPs00$iDXy=L(i& zU8D)L26*JAe!_Sa62#fW6b|!lxo`|+lWqW$j9l?{o(glIgR?)}~6!9aK=_x*iyAK8he zuZYn1Xkoz|^$lpe6KDs=u#I$9<~@A{ zq4j>**#IvO)0R$*p$*1g@uW=J%aMwc6;k{5xt0en7HNFdJ z$WWd*@M4Oz(#OdwEg8-(EWQ zMO`~vdGlM(?55D`Aj)zaltuHj5e~I^7nxW35X{CK1x&3C0q`bE!F;VFxa?wHND}-m zQz>w8xEh32s{WA51ajyI{OPp(wPgEha${rskaI51%txaBgt*sDiuA z-n~0KX~G|g!ePTAQPdf!!^(A(`dT(LQ<*2o*D$NAG|8WlqCOmA6qeIPqpX@Xmp<6J z(P#!tR!3#WfxJgjX@u$X8pa;sNRFxg(0n1c^>RHh+#v?;G&zrZ!j0~>$S6I&=W{Hv z8X^wd&4EkU^ou36)B_wFj_|m!gFUJ_!!PcrbcV<+Cn&NUDN)q4KQqz~A$F~zIhUwn%$O|1)*gUJ|p20s^byCsEW6VFa&E`i?d<9dy zf-%OLyZ|;1uG|8I=X>Tnwbf1-eA7P6CefA0oK89o1|OYOMNlk@RD)cl|`V0-6wMZq`?_(AiccVro!uM+SF|$EHw`;L96mXT!w?*I&%- zzrH{6uwd|iYlX)GFJ<(o(cQwOa!}&bs+xJ&DkOB?oikiwtO_>tLYUI`wHC?^D zTtx!Al9^$(BYY6MOXmv`nN3W7GSgz4>m`L|-uyA;AukG9DUir6`%EyPem}kW=Gy30 zoc!W_gJ|UN)$x9CLc8ntGuMk6MxhU-g_}`PkB8eg7v)8lcRum%T2_zW&n|cn)3%i< zPc853zTDT+sWrNIeaF3bnYTz<$=qpqtk9w%2wS-2!Ae^=Y?qjcw+~-N-)1&w9>r$|2ue zthr`X$~SQiwhuFv5jgYgIur1Cw6r$2maNF8G%WL6GdGuNc&N7?f^%RYdbb_2jLPp@ zD#}+H?T=sIF+4sV3EVenHJ8s6;i_zWewqEaK-@rJWj6c1;tc!K*K_YH3V}yYg1dX$ zuXD3K0b?n+7|2kgblEANyX@OTg#uhBUVR%(Ap)5eJR zZmO`ZTPsRa;Mwju`24Y;c>Z34=Wcv1*-^7bntS}4cfYxdYs~HE!w2wf?{T2FtpM{8 zm38;SjavJ?-8Dw}*z?yFV#?G;Kj*A zM2JJH!>yxydfAm1P}KvZA+n$!5{GUEoS}T8?Z^qJg8e#wf>*GC+6=BGhR;(i@ihVR zTdGu*a%{gjOP7`yX(@qgcC4&cE!MgCTi0RQ0A-ZH{gv6XShpqj+*}sTnVoOOVX4=k{S$0`d2<#nqH?`kx97)%cehGj@X+ctB%Pd-*HZT>A{aueykYq$SGK>!>P%vf;Io6DY zZi7LE|^%|D`+K%<0_iqQxkQCz_e#5_b&P zZR!-k-OHY` zV^9*8BE7|~y3>6IfY=y^0N+g@ja`m#<0a-IjLjU*TRIpjeh(bUz-yJ|s+`|MbV$SF zSPw$htDFq2j7yXT&!}@m*(0406QR(|=w{#D&8v*_l}5>cbBx_1og5IQ(9e)`V3;0| zq_EGRc35-u0sFSY?92WmI)1d+XwWx75=H{lIR*C78w#!7iABq8=H@$Jt6F_$OL!85 zG(1!(#qT91#l*5g>gd^&#EK3I{OqfFS(L+HtSlOySbfna=B;1zh4?1G6gMZ7{`;-UW;dtVCRz2 z>l3^{UQodcZFCw%$P$xMVg;eRuqeu=k`Tplc_D3d2u0Eo%o1Wnp@Og&%HERXBE6EZ z6w0j{caM}sFgYQU@}>lH=Xq?A z&~H|U{FeG9`zfa*;V6`>3TY;Mmf$(S%?+FjhtHG{hp(|ZlyQBja2%@l3|swyx1qW^ z2sCS>pM|o})2yE&>J*T7y8fEDAn4kOAM3p5MXB$XMK7jgP>fKZSLzW&mscE8pnt<3 z*27PcS%|PP4|oyYT?-a3Dh8N$C(6v^9Tk?v?iZG|vRE5pjVu?}W@N3bJtWxuz~a;k zFA*?ly4O7`CPCpVy}%CRh_aiP8&@H%mvQbeF+0FZ5h@+TF6J1!YmgULEltjzvS&~b z*C_pxJ^QfDHTsx}f5xP_(#nT-!b!Uo0Z9z8pY-sOS%2VOTG*;9w=kX&N9#efVYT`S z6Gu@X-I(S>b`uQdN@`d5K#h`TxQX#)+g*&+vHo!z zb4d^`ejiOUkp*~f!EeH7NF$K~d8FdaQD#XJ|I6xvD;tmJEWPNX=OPOIGZw9{3jSm)}*W>Jq z=Wao)>_UpHhiZ zk1~h2h?p|RjTOSeQ}zrZN`0VY@$MUZud$~>+G7OR%=7CDGZlLm;Uy*sI1cmnfD;Cq z4oDx&_JQ0o$mylRg?D( zbHd$^myERRyn;}+IHYt=CAXBFm^H=bHNOdJ)aqbs-j)|Y-|)pSQ+NPrVl zzoD!|T&+#@%eCynq}_dkf2o55!^D6J1!{(*Bg5o?1_f+}>p7PJzIlm-vtYzx&aQ45#PQ;NjDgaG4eOg6DWm%?Mu<%C7hZA7hR2f3 zC4IL|ji%te&n01jU^)vktTGrD{(8_;p@2y+Nem#pj+@Uegb^Sa5-8A-=Q99c1Ruf# zqIO7vF+vRC0%1F3sip)(TakE06^e1d6QZl$@<39e+j5QXAIvgaoClW#;L7|9UC$)pk~5hna4*3aLFYu0iFDp} z82Dg;8Nnrk@a>ZVW@Ht4*6negQk98k76K)Pk%>+0lM2mWBVHNeyBby(_FSv`La>qw zJBL-qN?^!Y`u!}@aHe@7QB8w7&h)zHe1nCyHY%`r+UE$1`HLf03w-I zN3Y|&j4fT@LvFD)|93=fym+ijdZo8|W(S%%x}n82IHyzCrq#xVj&rV&KJ5DD=?`6r zdyqwpG^Jfp#zye1hmQ|yVUOnxuBv!WoUrBybf%HZak4y2Se$|l2YzxqOroi#H=X?e z${Y~-Ye48PBc`07Bqpnn<|*53t{mM9z7?rCWU$D@nPCl&XcvQiVkYy?U6Y_4ikOCy zgieMA;&nKHp+XcGM=}N<1m$WQsl;Kckd$}i<&DS*P}AR~f+!$`c>)^;%(0g@1H=$& zO2Kag&AWqCl!6V7!Eh1p?+m`ez7%?!Ung!Ok>RHGL#N?Mc;2m{f zsNm$_lFxyf9o;^=s_Pqmnw8wL#vr6(n*ZQM8%~mr2rx#lDB~AXAlx7%Khr59N<|U} zK_(|t!7K#C1f^3*zT!e^JrHzjB~0DxwH)7&P@r zI=POAdAj-M-%p*|#jOL?q4IY*D4zyhKdswwi#Oxfh36BOPH;}(5z7{fmb!cu(ntt$ z@o=IzMmpnK*k%^2ZC*4D5g{nqS?o@`Ml{IhklKv^O<$}_*Q)-{f&olE9|8bjbb@@u zz~aD+Ad~5J$bJ5@=%VKlpbCvHnrN4RQK0-p8TdtDVvor7BEF@`Ib>?=$6n7%7|rB? zR-0}N`++9w32u!g{;Z!$DE z%=&q`mQQL73}C*TXnvLqz$}GNMgk)1u>0(SlS4@&0znxD!~u-{CA$BTI0z#!OtTO- z=wc#p=upaKBJhN;D)C6)BM`VmHFgo?$~Hi`RsT3@9%6LXFo~oZXEqh}CS;}he(DKR z{qW-vWGTN+H;Qcv|0f4#Gf!NI`?CKb^y^EeHTCRZdw&oxYvwaq5Tx+op182o|L8|C zl}+(eqMM>qq1&Rz#40xsZKaJqO}*GOi8K#xHg#Tp_yfwTYzx6Ay|Mq`mgmW!J@yd; zFhWYcNQMLcQA9&%K*o+Cuv!2dvmjRhsAvNO6Q0&b14(3>e}&|`8sEYWU+s1IM)C5U z!-_yzHTiT^uj`DV`%0?MX?aYlCP-a?KRv_~%Y*C#D3hF3!fxWye@r%nZ5sK+tUqYu z*$^Di{;SJNUcAxT{>CEe0Ie8>-4Zt;1tAb$2nwkPDdd6PG=vlqXXTHHW=x4PoP$4l zlbVM-@#mkcwVV0@^v8%_Py|+B9mzBbVV;Mc{6{kXMwmaWL&qt#5Bn6-S;*ibYY`E6 zQAmlyZYyyqF$ljo#O1`4Ym_-PEtwV}b>Bz-97lZwjD7e;o;k<}>qt}urNVz= z2$WQWTaahcC*#fdm$F$z#+QXMPq<}*>kk7MpZBT(g0OR7vK>}Ia01P&0y9t&9578a zL5ZN;t=MFd8LNCn#;C|%OSJXQ06vDfSa=z8Hy*UhU{5-c%%a2JA?ULUD1c4=I8?=z z-OA8ap-ceuN0B#P;T9K{jErRdOJ1wDs))W+H-r}OX8h@xKw#oG3jy%wh&w+qWZ4gf z)Cg^}c3S0O4Z+SSb^vdLr(fyvoC&6Mti4^lmJJN7(v6%%O8IFbek$r3Ll?GeH}7Qn9LWtN*5f5(p7o;LjgJ>0E|#WkU;s4 zAy86>z=2ap7f5dfAdyfMn*<;!iFEUmhCqT>Auhm_0CHwTTkao6n+2Gf+f9qEFpeGD z=$ow~{vRw0G*^(o1SppU6QNqlOGIH$hHUHX$&h_G0vR%{O%QxQ?r3-s#0g|Uk0!UE z`w$RT`u@I=#*uY)Pi9}A>@Q9mRK1KKBJyPi-E{o0f&w5b2#*Z1g1ZRg3b9);*u+5G zSf!_(71BcFf#aAvTm$7V_X?Ch3uI9K%xNQ==qV5kR@%~@NCMmZpCkdYg8YZ-B*SM} z-AmP1U7-Da@A3!p+kfmmntLvui(-!ya?g$np)UnstQSt*2H|)HHxq+rOK9K}_c4u< zEJPc`j^xF`%9-B7ek?`=xw+z^N}$>TDFQzJdvh*l#=-d~567Ee!%o@ZW`DMs(lisit9oGe1bPJSNH&Z0eK~ z5?w4oDOgz$#9B&1KTX$0yBuFu1u+L>Ttr!Zu>vWQuvN&G%kRW+ zSY`#=)Dhl?{a@;95Lt)N=aZsBGCYdLnu!IR0i{KU8YE4?7UJTG6gd#^&{ff?>Z3uX zCm($uBoM*!PhJcA=ugXc=hSLz7*UHfKl8(LAQT3@oBqwp|3m|MwQ!TxkK2N>n3*|f zpnivBSXZT0CwW z)ei4At*$Qy_rLX(G%P)+w6|z-mbXnxl)NL@u}?X?=^I_UY98Kyu-<*RSTt%_`bkUe;ng;Py!v}1HyR{RCz<+wXyHgVg`{0=DZ4(9sEX$Wq!pESw0J8 zl1}Rset0Z0uNfS8p6lv@JRmSJ8LoXBJZ|r3;S}taC^^zQP*h@#(9nEil^Cykab(Y6 zwqWVm?8!PcO?|D&JkWD@m}WXzM^aawrfRqH;hpwGU1MYA<>J=CiOO`y9V_nD;!B=) z&ZcKBWgi-bJr(P3gU>xUAL5T1n%S|IaWnT`u6unC@qNFyJX$E;7D66pz-{StX3BB( z)!#-p^~0Gdwov7ogeKwEE4>_*ZS$})hXS27ENkTK8}43AABNR85k0~m{lYNVF^*C{ zlaBuz6b2q zLSd~+d&+yGxDp<>Z(qh8Tb2r_7ri54$8ar``VJRbvGI`#JweAjs`WV*6<1r zl^9Op9fv7cx?1%lWsM#Q^k#L@fgEgyW(7bPO|n=HhYlOFh8?`>3a-ah)|?$~PQnY5 zlQ8BKIx~@{gR(aM3TzG)!-vDRXb87Pl*+9_HYpR1T7pyQ+;V6l%BpKiVcMDI(qSZ8 zV9B-nFgGPKh(Cmh-EpNDk><*zo9=sv#T2?KAGh$fjQth(k#Z#oHg(1B^e(a!`nhki z>jCNwqUfo&)5G)M)dAP8=;YH$I7Lt`AcGF28(8bh+F9G!)9G8=89tr<0yS`e{rfCB z01yzXEzt!;>sfi$E->JpW?;X@zv%lp6Bk+iA%WRjG-tW3)wFr~GbF(=7e%}K z5!v-x*4_qedSwJH(lE3*FDwaFE6v!xTgsR0?&lR`m61WAH!-a>y)(BtMwvoS4d=J)=Yn-J4QxtHPAOC=edM%UG|$!P4BohhzvP zQX#l5Ymp+rpOsLMhR!H7$dn#P{ZfUcTYD|SaXx#?qOc-cIR1$IT5MNSf)rJFC&UFR zo~`XW^yZu267cZsci(If=%7Kcr1*n?Z9vTHU}z_A=-}`~!F0b|GtlapS{*11T21nz zahYa4BZ7SIgCxN#rXDz&7QJ1-1{LGkkfASsyl{yXqL8pr; zE8R23Oe?kbW;o1CJ+;q+jelO5<{PLaI^w zB0=4MTsi8Qa?hTyi<&oMqTLPbL+#wEfxCOwQ)pGs zv-i{C@3dNEG+!4}llAG<)I(VWZax-Gru2?@#d2z3xoLR%O2}I zJgSfuCmwuZQln9xJS_Fk3g{MvrrlDGCp{{=x*rp@O2&}M^BYr zVGG`MaQf^ZEKfgdj2gpQ=)b4JmB`aRG|_Hrii=c)F>hS@cv3la{o6Ky|9h0v{~P81 zM*06|C~w2ND-Qyhh}WRg=16}v5xO=u|Mn0dar^U?9?K`Q4nzt(raC1cUMZgR8!NGk zP^t=n2oa~T!A}>{UtNeX4pH;slFprg3{YBF9BL^n99@@7T8tc2i!kt~>vo6@hiiq& zzu4#Jtgw>y4v)a}fT4Av?nV&P*o)IPLl*Flp?RA~%!!_3WVQ7+w%8VeNvuXj9DNOn zwceISKvC6ywzI`@tTuh~I6F3p3X!slIp3RA>)pJ^p z+k{}vU)6m`>DTh9>Uu2*JMOm~Fg<@`q}?3Ey0?v_T`X+ymI3Q#wGG!TxSngawv`B7 zUms)4pHw&EW6eP{e#tYz2aMCq?CnEaRzHfxa(l?@&|AIxbK=`hX1^OhTjP5wE|yXo z_=sTUcfn?=0^JPvLwr04Q)+6_y zI_Lg48U_YV1G?$^{XZM{k6iu7`)~gBfULyd1N^=H`9B6ey;p(?;xEn6zYhF+N9bP% zPJ`6sKkpCyHO{a7fj=W5g1R4m=@$HT@UNY0KL_W$_~X9#Uwv)A4*j*2=I2liP+Q!e z^Zr+jHNOV@wK3&qKy6U={?mXz+f;rH_-miX&w#o}zXtr-_3>+zU(dk*j1mqy5)b-X zzn+NyHNdau4}S)b#s2Nr__3m2qx|~J;%5{+h96P>@dV@72!FrZ`#Bx}Fk=R_m;QS1 z_v`Rq-OSGb>mZX4+J|2p`>)qO9Q^-0=m7iwB6ma2iOk;2{u#1b24`4#7!)5Zqsrea_i? zXYX_0z3<-}_w*R79zB{_b5*UczN$HARjVk#z~Tbn0f+zqfD%9%CoSLx1pvgs0RT7v zL}-0UCr5V+M|WclA7=|ULsoAGdx|%((DeBLXvqKn=k>qX0^J$|j-5cv7VUjesaCBQ zA(EP!u;_*fEZC1%cz&Ot#9w)^HtQ1P{myOyLc zgIRKTJkw&U2mG$7v8gRSlz}4*Dxi9torC7`DuhisXYk!rv97EbYTo9nX7FRAY0DE3 zKf5KeoGdr3vZU|>j}|cJ(7b!47E1|#r%gZerg+n#r;S&>xHo3gqPDtdFycomPsCGv z#&oR*N;yN_Ea*BWd^Aa`T^Ra!JOH=HcG&Y?ApBFFNC~n{RFw^jLVax_ZRzJaM2Q&o zcZibBu1hoZhbf6vglGe@aMvnme(B|Ufz7}?0p2mCFau)6IC{HRHG<1@mm8L^j%QkG zl4gxzTUBI^^4u|3J(7-n0&uam<6H_o(7eBHBJ;(~2;zz;5MMQRwXk<%V|~2-$4CDcJLVr$uSix@?gFAl9?9ND^bmy&KDO=4|FXQ%2s0-m@i&xz`|T;uu81|& zt@&-MHO5 zJ`fs9{&octw*KlQ!+J{sO%Mk$ga-gHAeQmAXY+D$wKH{cvU?0>g_^3$i$Ki4yt)UI zD`9HSDcm>3)(+z3T(sSUpEM*KzwqF{0M9GwhhH8E(iOrrA;7EJ^)+6eczLZFMwTqT z7qhF1SK;W`q;HQN(y)-I!oIz^UJ~r>*P-Rqq94GyZATL!4Y=c2q7P_O*(ZYv=0X~+ ztTbKawHZ~gOwj0|(Mgj}AMRAE_E)zVP(Qu z!RAR*QB+DZvBMsPS>KWJ#>jLP(O)Vu8FrWL(=izqBgY|Ie$%C89>W$2E?W407bYUz zRMq=|zFpo%jOtsWr)%pp{f2@T!8vjGQir6)cv8JnD6kbT&2E4>kKRT+YAi57%dLRY zMA;P%Sw{O-nT0E=6FMNI8u*^e62)!6KEc+I+8cYU#9z4W%e;_!X(oaH(AjMS^ZawP z+bE#!{+BOD^dByq3=u2^4!gZvriAr%gkIa_z=$)qG3TBx zPI;r|vW<;6MUI|tl6VRqNPmx?x9en?IM?b2Ikdxld38I^qMR@8NIX^9Z;zh*)E&T9 zH`eM_GZ@0Q_pAkzY6xGuN}HyEyaOA#V*>P@$#*Jkh2J3eiP6M~@pn5thVS;4)K9MT zM+&hN1;cv}d@E7>Fu2H@!%ms0Mu*b%@g$(kh9wF*_39c{6nLM5TPJ2|1BK+5$yjA4N#Eu4dN{SyI-G@M{K)+ zsNqKutzi=_F3I;Qg93gG5iRwL2*4WbC`Eg-Qc<6qtXGFT?+Vk$3#hqH*oQ4|_)ou( zQhBT}(7z{vZCc14{eWzAp{#vD5&eO)=>i=uPWD|TD;v+)XFDZj^JcN9rF?28nO$M8 zH1tWhEJX4Z(tG>F-H6SY!m2Qup6PC1f#ce^^RsMXz^a&D+r-_0r~_9{4y#;-@rkX0 zPsWdlPzGM0q~s^CybraxHNw}0hV#jNZIH6w)d!<1CE`M&OtP?|?~o&iKP3GP9{}K*0{{pikoX5d zx>;LTxVy3ad}DuP%A938w}rv9-s1~(?$wT-8`3AvIed6Kuf!0$NxSbzU1TL37QKP< z^EaRouRMHP8f&@3vmFq4V00^ehULYXlo+r7?c8c220@U+Iosm$lws-ZcA0yPPt$6^ zyhuPZlOkOQ`H=zvTh!T9`dQbZjhpth)rs2mT*21Jrs!4EqG%PycKVG|I@{RI$o0@Mo3Mz1R#lZFEBV}FiJIDa zSMK!ZfV-xa)yw7^^2F>CNj38}A06`HTZrg9<4N1Zi^8Q1--n&V9nnLt#IfS;orA9P z?_)LAdtZ+4B`*(bJ{kuF0{iZ~u6zT6jxSbjt4;6Qve4ab@0Mf}7jNzkEiTT!_iD6) zwsS;p7l#&y&hDz^uQp^X2ItamMvNCPq3>BWuf~cs0&mK-w!CWggLJ-aYu8-5ABf(5 z4s2w)J4(H46CDm3I>yj$3zB{K_8^}p5;&j5L_$8(6L@k~wV5jFUHMgh@5fZ%29HziUpu>N-AOyy&WdLf__XJ@k555hAs6CZW&OH#mMp3zr;f zq{4%6|3h@(cEdPh!1zAvZf|Ug3Mt`$W69Wm-rw-Sn=j5wR6pAr+p=lSiP34qCyqRt zy!Cd&$>>lKA!EbW?T&}lzs(P*Ih;t4xY&?7Lgjtuz@q= zIlR1ZTG6boa$0HQd`41`Eh?Pgcz3&0ade{%#JYb>xlxVrRhj&vIgfyret0H;9YYwWc?-jZ`v%a+zO(Z^!0*Az zAzi2)g^a~Xk$kC-`%^=|;ojXbM_-$&Lf{6t)J5Bu{ady2%mq2y0|&;m-;LKk+$N90 ztx#j@V6rq6gO!|$7^ChaGsO(E4PMe$W~7r%X%f}uwft4fa(Co@#WZ)6{$}PqJdif( zG#iC!zBm*XOpmG+>)l>zE55d`hFG@`(awOMOHqN44^w|(a5O?!-Q%U=@$%{M@+LSM zU{Fm7=<-FuFZJ94kK}ym1xdycy;Di^7xF_gHK%G zTSBWoVG(pPSr28e&Yet}FIDGrs)CW4z69M*O2wWT4s70518|~L6vD5LxmC3z@(3(k z!qLF6NbDG?#+;2*(tIt z57dp1D&CG~e#&blX#t|I)Pp!KXmr;vvhi~QR4s~?EsVt8?|8mew$ODBky5KTWy~#6 zo@3hWjv0OtYE%&u^~$Pw;;jD^c|ldAOlUFDa=XnbaMRyjQlO7R=b|w7^~$!@UqeZxTj$Z@!pI=3>9?B==x& zN-%v6dsK*1m}=dW1zV{wfQ2$M9H+1f$CwUc9RZvD!lD!vItQ@3`=p}mc4tiXr(C0= z>XZAHY;{*?TydNJ>qhkVllL5I+_S=IKPQ?^_^XY^aUmb=kY=aKhhs$lO zs0}J=k?5S(v0bv9f1oSjwK5WyA!isitM$H78V_<;N5=>XjjCPG~)o!86qSzfbYT3#>g?z8kQ!7r(Oy z-kG0uv(n)(cBR6v?%q)5HUp0Uj~%61urgovG{<^?FOm4sB#slDCGkQ;KIzb{Bby7{kQrTyG8v%*GX4m-vkbqo-Ez}>W%IZAM5U$` zF|v3#njlSf^&SH}6iw!{lqLuUN@0BJp};o9+6>lW$LO!-#>+qByBF)K^?)r$IaB0n z-_P^9Nav9H@QigopJjF-ku>~&0Yb)y2A7MKR0AKV>xqh6iBMOJBot6l$8Ts>G*Sv{#POLa zGX+hEbAdmE!0os<1ocyR4*I>(()G+x6J%21Cl<#dwlEp_{n6YEigpH8A2hkFjzi55 z_v=u$sd9V0#4;VliH^tQF>=5nKo}sH@+~K{B`OGZ7&e1}uZjrh2AqYS*45kC&%p!I z-X@>Ben^lL4W5+t(0U5Cg~mkH{#@=V2y3HN`!JXZoJWk)7RYlMOJ|M~Y1zTK(-(A% z8C`MM@yy&#*GBpBRg+jij>md6)nH<_&SL2}9rW2kLZt)^)RzUKitaxQ6%aPLZbuC! zg65oLo717gBD8@X#?64-gb98-GYa}0_!7YrZa?F4ioA^W9#Dq!>b&$Mjrl->PTuc~ z%V8@)ce0%JE(al9vCW(2JJDV`Gl__zsLxB=;}SqL!IQ#Lf((QEJqu!!w}1>%s4Rf-zcRn+n=w7 z$rtL5APfe}+cYzdg{H`xugmcpG5bp+(%Qu;OR5N6l#w!7IzhQrUvFt^?ub}R(Vzw7 zi_s~9>)f&T3oBC+l$z4a9Wl3*{98cAbTD94501$J9lDoFv;vv?=EW(EO85f0`{qSB zIG(oI85L8Cq=aqlueM5}gNwPuOO)vy6livS2$HU}{m`Y_@)kZO;!kH56&d08srXh~&Ao(YmEmy*KsRk@PMILN@Pr#-r zLIszSI+BU|N>G33YG&-}!qa18QQ+{x^W^K$)=e8!hVq|WD8%hEf+b)WGXo1~X7bd8 zwjC6b3B`$E2{nvuFa?1v+*vP>0Z|1^Fy+sXFNI%U7xh{(2{S~L=v|`wGcJC{50|;)m+oV@a|(5kNz&uusY zdWk~?sGJr1@|9q>IUyFvA4Q$cB$yc}GWnt70p6h@w1bP2>j>>l%A41qO5KOOg5^ep zC@d#_r{OE#W~mM|A{xoV)J~3=&ZO&hrK{#X#AVh=0xO6wbG7S00ToU3+QZxHLiPYt zaK%=N+s4UDE%|}D2qqPjgm$pQgc*p#RzLY7V~k{47f=gp`Exon{2wWBwuNe7jURGF zb-IQa(kCBqO}^MPH|1dw4DWpybEwXc-zhX1?%5$8!Wb4z1GT!d-MQB2A788dM1fq2 zen1FPyUw5IkN>(p2|?XYogZn#LcH-*8f`>*mYm%|tK=*w9aDOfs#22SO2+ zBY{vd{^eQiSC6h`h9(aF7t%XiMj$i3tp#|b<&Q$#EA&bc_r0nj^7e&HztY)$q1r-u zRW9$U3jFpf&+_uGEp>*ee&Ve+8l)2oz z!N2N@03y$T0!o@lx5tIN2+jm>!db!(lVrdF6->0+GjOM~#|tUM3N=UOxI*P^Y6WUz z-OJ^~fjN`a^L`yC=aCx7=aK!2&a>wChDpW|P;pN2f^a8ahlfl>e$}zUMU={uwMI0s z=o(-U`_Cs!asxY^87jc3V)c`jAsC)!XL!pS3Bk@_wx4+Lq>*MWR+zlaN5-*e@uD|@ z0cRc^C-n&$KlEib{SvtCmM%g^EtdO6PaMEgxE0Y>vuGyJz`Q@X(0?5SkoVCn)iCn~ z#BHh>84x3>mTeE=#A%9*YcE1~97szyKPL2>m+7W765z&yzqVig<~fF=bO1B%5F02Q z=qdPO7!W~5F885d$0kYBFkl)I<)G)>QTKlaoKQDD7?16C=3w2>s|qpFlu%zYh*7IQ zH4?zmA869Ri5J!BLmr%p+}@l$a_&cu!sJx}wU_!b6)vkN`$PQ!`gAFwjha(e)mU#4 zae}Y7{x~NYFu(-99W{gqiW8m|+VT$}HAEN6Obzqf)LSeKx}VbwtYC4F*l5=pjq@AO z!jv(EnB^w}{`CK!#J^n& z?IBdX`(}F4+@G5>BB;py=(XAZ40%v<>Zk3zHnpaY9l#)D z(9ZECmL0EOz7lzcct~l?otUJG)lX{6Kmw|pSk9W~E=FsI zZ0C>uBR4_bSF~2cq?jxt+tW-5HQ}4Aq=ie7mq!**eI#;0wUHyz(te0Z&DB%_U9f>7 zKnU(lvfAr{kwR=>rl5-T&AZ!Vg;h%atNaJTB{u!i+>a47ztafstEVDz=(_C3EL;#H z1H-P=Jg(4Dwq)5=3l(0Y?EIy&F3j%uH!QwR^Kbc1*G_O8TJtFX73;M^? zt9&JxjQ>%x_%EI))E;S}AWV3q!S`O>@$VVDS5{uy1|G?31|CFnLvkBGnc!m-kZ$0b z$X|HA!lfnnx8MTdh<|0{=R|Kg5j^noN3k;=lbRFA{l4+}X)%cJS`?xFYqB@mvt{Q0 zvYL;p-E4#Q;AR_+SXJ?{1F3cv4}{(Q{{R9M(AeW+yIAeF6QJiC`}o68ru_rqBU>=? zo$EtvvUUsV(BU-MUK3)25EOqk^0xXwz!73bot${UPO3Its%&+ZpZHyfWiA%XtNQXE zhtZs791Pw85RIwEs$RWZR;lgH425t91crzCFtmRm#qFL=hi}SH%(HoD?m4 z;t9(kK>c$9DQuTB7X8x^=1hNj0wlO)FaSB7zqtW-;NI54p6G@M(88gdC-j$$aI2L* zYFbuEk)gg&Syjc$kfEWb1{AN}R7nm^XItgX4r>#s5DoA*3R*m!y>VJBNso;h(LUMS z+mH7luxz_K7rwiCe&K&>=vH#=XaZ|ZrR%H^4S0Q zQ{c+Cf`c|*FPankfRC$=x#(ZJJTKg}eOC@JZqCk4dT-v{xoR&&84uE&q_YJbo(GZ9 zUF|*m?GYlGVL}iqEG^_;i&XmzyIK-TDtGv z=ou$h0VuAo1(mn@B`S8pM%KH(fvvs0vVYjQ%otc^7^{H6OFn)ooqO;!7C)S>;&b=z z(9VoW9CNAj%e6QHE@@?rH_dyCyeU)!f{jHQx?=R^arN@4FE?c07xAa@u-QNTI_HIB+e*tYau&B&U6FKnph z^T80*x(`w`_fUo}hl=?YweM$KgEbHM6A>RtP(?~`HAY*u0`K;HY_6*`Y`TypPZHR6 zn5~3d;B}asqA&l05uwvAqOXZS@EHArhvW}w?xCQ_56UrC2L}Fj} z!UUa#0~)SxC8p#$DLQ?%((-NM4qL3bB}Uy%f9x<7$oP0T?ztPdwN7D>lH)%n22!eH+ z8o;7aMqxxUr#W@R7|}r*3x<|qvhwv2*IG}pNn}=CB#b{8#|S%S5u4R0!<$kuf7zlT z^q^%kjA;ko-2==Q=9E}O3w`}$_vLB0m=LPDH{5aO_{F^ybq5i&gK%;yW{GR>WotXK zGF>P+iw=|k56$dZcPzl4hd;Qql!dC9s2X+O*&h~*j@YG|$fPo%qLIDaaS57A8rwXo zbjKHG2QWcvHS$SegO@v&bwp9U_S+{lf@aK zFw50id6+&?yKP~vSh6gObj#@(Q{5dYg-`eRwK`Pk?%kdIF78kc>hDR3A4k^inuZ(h$_R zYvR5``@2)9mi)FB1q1+q^yy>W+0RobcWVm=3$~xvp9fIi^c0+)@M5+S>;_Ss=jyzt z>En2ckjC62cNi4jET5)(H7@R&s(z4Ei+rp7vd5?%5uVl*hEWueh)3#-kLqsl!&|PjWJ)vD>Ukx-cd+;$8CA!zQkQQYm|K#s*lBT z3M&HDilnc@oSH^}4VnTJ@j=x$--)0h?OUgHEJXXnb~uz324Zr!8R9%G)%)Z{1x(>;F=&ekpI(GH>Ad9p3zSNd59We!;b;=ZVU& zwJ%r1EV{!-w?i}8yjn#zf4DWKA`%gCajv)m1-6Nu(kwhXB$3TGXaF>GoeA91=hD}F z;q;DQ3YqB9RU*|{*TrpWrde4!9+42e?e_)Y7m+Q-@DLQ2(@*pQ4{_t$R_?YnOw)@QsHc_cI;fMXRsj*vc-R_6m zWf{@C%TjX0EAEMhnVqpfpW|;c1mq9bBkCCbhHH*kE3c7WT1VyN2jm7j_5!Om3z@bH zcDpkKaQWa@$Yxpa1lz%smLdjW4ZVI8`E{4U9}%JwDiCT2>GyT7jB@ze9Y%G-P^zI0 z_dX!wAEHk7w>1#ry4(YT-wHik5EHJfR6*%fNb$S_`uszGi`)3V3c{O?OpSHdzgD-dnAWpQ&m=W`8Mt47%y+F>s47% zqpeMq9`UNoXXD99P!plGGc67o=aHOcg5UM48W?VKbA_xIiQyR8Mo-AHR9|JvB=iO8 zqNeMS>$G<~gMLCx-EbXTc1h7ogc>zy=}k0{<3X+3OEVldY{n@~W96OQK_BrlDbq#k z>~v^B8B%NFcYdtqGRSXfRv0r(?NK+LZ0S7Fljito(bR%z22|TvmKtweZ04--q`X2= z=>5G8w>Mustv@@}uSG+!&w=skGn-|GtW38ojR9f^p0%EQ{z*l zYdDIcXS?9Ta&>Yy3Oa4MN6tyLnxj)=%ZP@vBW0dyA zE1PuCRHAEr$D^QF3}}hG4fl^ohoACoA*Q~29^}Z8?F{y=-NqQ=7+$JeF2VKO7o#m) zXy>SZ{oH7avR#c+iRTBKR!2p8QE&;dAt7V$5&2!gSG~!j6cs$Mp||Pw9(+=| znuv-NNp}m*v;|B}V#l3;hIk%XDo~CWPkgogby9u3&ldiU&|ZuTJG@n%Sy~St+ed+C zGMV=4#T4-tKrbylDze?})Ma|!Hb&YlHn~(&!iO=9i5sN2`gGp~7|I+u}ZS7=;ok zTIC-eyjro)eV_C407&~~a5!d}rZ3#X9nE0Y&o9^%(L-JF2ZxEX)y7!M80Xt3d$c=w z3s;}bb3Y1ad@D=44{ebxQaMG@7awW9$jr4hKwo)ZGuAk>5W`(`Y&#k8 zK`X&1LCBRgOYmuF{YFI}D<^C599dk$xHcYP5^gfBkCjX5{52Zw$e^c@kC)$`18z>` zHu%unuzyl?YH!r$n~U2v>(1tv#pbcAII#Zb8jqT(vkcj5Q)FGW8pVmci$+07rGgrI z_LR`VT`}TQk(;yh!U+WFL(gz)1PZB?H{jW`&XX)t89qlxb4A!srG;N~x>OuminUGaWNBS(gP0gljn4%&@42_nekn{Yc3n`)Yj2p${aA)J8i;B zk-=JM**agnZk+Y#=lkVX0abM6G5DK)O>Rzy>tDiQ`{yX(YIdR${hek~WnY%`!*K6O z>Z-}Teo~U;_geiFJvs}MxfSs$y?=zM-&vGNA**^6#?k~SDV-+5T#cVt4dG=iehB}b zWd*R{$+M96xmxm2GYJfEL%+h`7%KV^GMFQ+hwt4I|q^3;A|Fu68pZ9}>Y zJKWFu0`t3|dKys8MoiPane#z!))J$XJ6b>O6|PfJ`>^}|yDv-fn1SP$xO=45rxaKZ zmev>EpL*UUq$D3+^`w&Kow)lNtyzc@HggJzXv=8FM}J7AIv3ixrjkNYVxi*iq6#k! z`nI$W-@DAN7bP6of<9+cz5$=EqZqvAqt!QqUS;PAw`O=Y{R^g`!&0_8fYU{#N7k%jr0>TfL%Ct!#fwSbN;Y0c^;4yE319yF8HgW+K19Nf|z0cv}RctV<(I_jD3T5hLqCqyp3anWWb>c*(F`SM{G9@z%NtF4*!4!loSi@`J(h8LGK zii_DdzHJU;=!qVZ{fS*JZ3nw2-s$y;eZGE+D{~$ngJj40Hk9`Qo9&V(M%GLB=ntb3 zaW6~f@BGWQYHc{=wx>LK^E}-MatLOXryNBT3-)^aOBFhqWqw%C_GD2pflGldYxU8n z-Gsp$>pbmdRQ3ZSD29lBBL~R|7~wrhTyS{Waw?&oRnXkHnyo4n{c3XH*f<$TB9^QI zdtD|KuZN5w;RnX36MQP<%23xchJzJov?UP+?W+FP&R-b=s`r#kgD;9>i^MjMAlTTv z`<45cx$q8DZUErN*q*RSv=PD5^~h(Mk6LMG(PRyINhXBa#uP}O(qftYD^Y{&i10J% zS&b3WDW~B4tclWmD~ZA^E~_fmwV64n*q#^D!P4jbucr-6+C+hArBjD?Qr0{>kVUalH& zsAAc}Ij&ng>%Y+-EPD|4e)e6Yw<)FR;J~QQ7noz%_nX~$lo*a)!V_V`9YzUM!5<|O zlQ6Oa$`UX7F$VS8=w0(80`vW3C;i{q!j)*6Z%G3O)zx3Wy$XIc6lL%#f5trvmu1u5 z;}UQdHyojDCxUvK=1pio@iYaowKxZ(eAs#A20$~4K<(mAh^SkLm(ChnPsR5KE^m9F_TEH=MvCG`|JYdUeenyWi|p;Ql0l{gXRv5>GcBqVtUdA?wwyPiADR?mh;#a zPxg&a=@U!zm(0^m&=H$v1lI4q`z^4viP!M$FX1Aw2qitAVr|WWQBsnB(U+uyhf))v zN_|Jz71%vrlYms3B(gm(_reD_a25MxyrRt3;fFCo9h=gJBj(Kj?JxmhHQoDf2?69n zjsH1J`s#cgA+$ibaQv$N@#YbQix;u!dSCc0wPqyjpW_cW z^*U#`oK>hxmzjes&eY5@LFem>%GREWwY*!^FiT){Qh1atU|qh_oI!eC^Auli@Damp z#iI!ZXp&9%-^dF0YaR@RLrfrZp5b*(f)w|4c-hShlDquX1S4~oA#Wf&hzQwLp!*F3 z&JY50w{TUraCd)XLbhK%v$LAoIDXR@a-0&w6}HKTqlC>1##9iK(@&k$#96dayPEl| zI>bo)MUJCP*et%UXkA^W#zI@`7B#P3wB19N!WJu4<)w~^O|KW3z(o$HS8*(6;#%ly zKvXZ~S)`?q`!*99Pfe^9*NQ~Swxmv-prn+`*^J}!JI>rH{XAPc?xmh)zeO+X>F)qK zt}0dIlGccWtHbO)Ta=9bHfe{j(CSk|>5qQ*YwWE1#*RlD8>4p^ZA15klddc+@lQ04 z$@h)jOwMlE_Qf`PqVW2nyp50UkAvnMa-4=-mi_L;s6osMmiKJsXL;}n>F+vj?SVhdh#iM(H&)|D8Tplu!c)VK-E>bHhr$+2GJG~;BgTrv|^mrS=C80DvA)lr5VSX2vk{v}} zk}(0%D1*qqh%>EItAJx;@-i&PC~7OZkQOhzni}aTxGs$7b)n)L8O`9<43MHeQ2__@ z?sdpfJ_{`mCu)eYoLd#uaaxzhm(P1tz(EjHT22>BuYZKVPiB{VW+*z84) z?*-#EzTjN5uGw#j`kL6Wjk}I~>BO?8?D0~au}9lQoUo+6H~1n_>O~`OxeyE1q0$Xf zY>^8lURiy!DtlgAGeg4jBIv2Th^2)s^5?K|4<-0OwiPNZc}9hSnv9BuHt6fHvz6^w z#xSZe@3LKcHnxUu9)qz=Q=~i`@?-b|)y#rgm_C((LUH}Wxj|yw^>wB4pXH~bv-j6x zYbLwCPyU#Us0R`a#cFcCeWhmkHp#zCLPl$oqI(@*nc11n{jHF~ zLvPC}oeJA~<*J~rAn@Jahx`9I%sKu8^Z&s7|2LS!$15L5Lc+Nwgwe4e{VnEBW-6{u z&TedGPOcV@>r_a`%SyiD6h#RpA_aHgomu>FxKB68bRhS>Mg1$9k(~-$; zGD)iW&Tqt&HChTG!_n!t{s9YvbZeJX$W~^37e5u`sJp zxmd2Tc;2jyI}I?smeg-J)nc%0MC_Mg3fon}pbtokk$OapFti#)$xjEnOBsVWo|m{S zG3dvLlPp7)mc8{3DLe;e;kUSL4rF;Znj7+7AF+dDK*+Sr&a0m#$T)-;nx|%#t`r-7 z)IqF;>jqCzIuv{Hc);PczK+K4rt)^c4b&(~o*awXf>d;tEg@7v45L=-+`xdp<(!wL-Sp|8)gOepyX`1k|=B$0H-DsjJ^@yCkGebS# z5>y7pLYl;P)9PWL$d#uNun?oOQ{AM^^5D#KVtVpLSX1hK&v_@Hze-{|hbeQ1`vqkt z8YE9EDJt|z^5|WC+u1i0*`Cjz;Z7;!2&t-A1PgC$kzNKp6#<@p5=NK#Zr<#XK#|xm zHmkfd&s&8xElT)twryOp7G1mjvS#~OrP4N9r+A2D%$ekEcHR1JQ_>LeE&LG1nD*-% z+{C-Fxv4Aahtv{33`_aIdzU-N-ra9GFcdTkWZnPwzvuAJXZ6qbzxj0s6@@( z0)Nefe-}8&^Hbn2%e}u{{{8ob*6{y#g#Jvne---YWajt#1OPIG0D!-wHop%4b42>% gaBR^(4F5-bQc-||_}gRiI|cw7762F(fBf`+0K Date: Fri, 18 Oct 2019 16:18:01 +0200 Subject: [PATCH 0285/3432] FEAT: support comments in base 64 binaries. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 94ddffa70d..9e2d24e74e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -400,6 +400,7 @@ lexer: context [ accum: 0 flip: 0 while [s < e][ + if s/1 = #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] ;-- skip comments index: 1 + as-integer s/1 val: as-integer binary/debase64/index either val < 40h [ From bfd177508084f6ce9520dece3fae4fba4086043e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 18 Oct 2019 19:22:51 +0200 Subject: [PATCH 0286/3432] FEAT: preliminary support for scanning file! values. --- docs/lexer/lexer-FSM.csv | 8 ++- docs/lexer/lexer-FSM.xlsx | Bin 17555 -> 17807 bytes docs/lexer/lexer-states.txt | 15 ++-- runtime/lexer-transitions.reds | 92 ++++++++++++------------ runtime/lexer.reds | 16 ++++- utils/generate-lexer-table.red | 124 +++++++++++++++++---------------- 6 files changed, 141 insertions(+), 114 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index d2f4eaf376..b7accbbb22 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -5,9 +5,11 @@ S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_L S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_SKIP_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_SKIP_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 0d9cc8325a0ce2ff3ba17946ecd85eaade1bb117..4005c3d68e01908fb274657ac6eb4719a291db96 100644 GIT binary patch delta 7957 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 yAkqhQ>Fi&BJAJ-7tg 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 KI!}$mPyH{0b`l-{ diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 441de693aa..d6d14ce3dc 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -155,9 +155,16 @@ S_START->"/"->S_SLASH->not(delimit1)->S_SLASH \->delimit1->T_REFINE S_START->"%"->S_FILE_1ST->not(delimit8)->S_FILE->not(delimit1)->S_FILE - \ \->"^"->S_SKIP_FILE->*->S_FILE - \ \->delimit1->T_FILE - \->delimit8->T_WORD + \ \->"%"->S_FILE_HEX1->hexa->S_FILE_HEX2->hexa->S_FILE + \ \ \ \->not(hexa)->T_ERROR + \ \ \->not(hexa)->T_ERROR + \ \ + \ \->delimit1->T_FILE + \ + \->dbl-quote->S_FILE_STR->not(dbl-quote)->S_FILE_STR + \ \->dbl-quote->T_FILE + \ + \->delimit8->T_WORD S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY @@ -285,7 +292,7 @@ C_BIN_CMT : ; ;-- 4 hexa: 0-9, a-f, A-F -blan: space, tab, cr +blank: space, tab, cr S_BIN_START->hexa->S_BIN_1ST->hexa->T_BIN_BYTE diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index f3e7381605..1f8cad7c99 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -10,7 +10,9 @@ Red/System [ S_SKIP_MSTR S_FILE_1ST S_FILE - S_SKIP_FILE + S_FILE_HEX1 + S_FILE_HEX2 + S_FILE_STR S_SLASH S_SHARP S_BINARY @@ -72,47 +74,49 @@ Red/System [ T_EMAIL T_PATH ] transitions: #{ -000011112C2D2E2F042B020A2525252525092B1E25062B012B251B242B25252B -2A01000101010101010101010101010101010101010101010101010101010101 -2B2A020202020202020202023002020202020202020202020202020202020302 -022B2B0202020202020202020202020202020202020202020202020202020202 -02022B2A04040404040404040430040404040404040404040404040404040404 -0504042B2B040404040404040404040404040404040404040404040404040404 -040404042B2A3131070731313131313107070731070707070707070707313107 -07070707072B3132320707323232323232070707320707070707070707073232 -0707070807072B32070707070707070707070707070707070707070707070707 -070707070707072B2B3333090933333333333333090909090909090909090909 -33330909090909092B33383810100F2B362B0B2B0D10102B10101010102B2B10 -2B38381010101010102B380B0B0B0B2B2B2B2B2B342B2B2B2B0B0B0B2B2B2B2B -2B2B0C2B2B2B2B2B2B0B2B2B0C0B0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -0C0C0C0C0C0C0C0C0C0C0C2B2A0D0D0D0D0D0D0D0D0D0D350D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0E0D0D2B350D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D -0D0D0D0D0D0D0D0D0D0D0D0D0D2B2B0F0F0F0F0F370F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F2B2B38381010383838383838381010101010 -1010101010101038381010101010102B383A3A11113A3A3A3A3A3A3A0A111719 -132B162B3A2B392B3A28122B2B2B2B2B2B3A3B3B13133B3B3B3B3B3B3B14132B -19132B3B2B3B2B392B3B2B2B2B2B2B2B2B2B3B3B3B13133B3B3B3B3B3B3B192B -3B2B132B3B2B3B2B392B2B2B152B2B2B2B2B2B3B3B3B3B3B3B3B3B3B3B3B3B14 -3B3B1414143B3B3B143B3B3B3B143B143B14142B2A3C3C15153C3C3C3C3C3C3C -2B2B3C2B2B2B3C2B3C2B2B2B2B2B152B2B2B2B2B2B3C3D3D16163D3D3D3D3D3D -3D16163D16161616163D163D163D3D163D163D16162B2A2B2B18182B2B2B2B2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3F3F18183F3F3F3F -3F3F3F2B2B182B2B2B3F2B3F2B2B2B3F2B182B2B2B2B2B2B2A2B2B1A1A2B2B2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B3E3E1A1A3E3E -3E3E3E3E3E2B2B2B2B1A2B2B2B3E2B2B2B3E2B1A2B2B2B2B2B2B3E2B2B1C1C2B -2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B40401C1C -40404040404040401C2B2B2B2B402B402B2B2B402B1D2B2B2B2B2B2B2A40401D -1D40404040404040401D2B2B2B2B402B402B2B2B402B2B2B2B2B2B2B2B2A3131 -1F1F313131313131311F1F311F1F1F1F1F2B311F1F31311F1F1F1F1F1F2B311F -1F1F1F1F1F1F1F1F1F201F1F221F1F1F1F1F1F411F1F1F1F1F1F1F1F1F1F2B2B -202020202020202020201F20202020202020202020202020202020202120202B -2B20202020202020202020202020202020202020202020202020202020202020 -2B2B222222222222222222222222221F22222222222222222222222222222222 -222B2B2222222222222222222222222222222222222222222222222222222222 -22222B2B25251111252525252525252B2B2525252525252B252B252525252525 -2B25252B3131312525313131313131312B2526252525443125252B2B3128251C -252525252B31313127273131313131313127272727272727312B272727312727 -27272727272B314242272742424242424242272B272727272742422B27424227 -272B272B27272B4243432828434343434343432B2B2B2828284343432B282B43 -2B282B282B28282B43 +000013132E2F3031042D020C27272727270B2D2027062D012D271D262D27272D +2C01000101010101010101010101010101010101010101010101010101010101 +2D2C020202020202020202023202020202020202020202020202020202020302 +022D2D0202020202020202020202020202020202020202020202020202020202 +02022D2C04040404040404040432040404040404040404040404040404040404 +0504042D2D040404040404040404040404040404040404040404040404040404 +040404042D2C333307073333333333330A070733070707070707070707333307 +07070707072D33343407073434343434342D0707340707070707070708073434 +0707070707072D34070709092D2D2D2D2D2D2D2D2D2D2D2D092D2D2D2D2D2D2D +2D2D2D2D2D2D2D2D2D070707072D2D2D2D2D2D2D2D2D2D2D2D072D2D2D2D2D2D +2D2D2D2D2D2D2D2D2D340A0A0A0A0A0A0A0A0A0A340A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A2D2D35350B0B353535353535350B0B0B0B0B0B0B0B0B0B +0B0B35350B0B0B0B0B0B2D353A3A1212112D382D0D2D0F12122D12121212122D +2D122D3A3A1212121212122D3A0D0D0D0D2D2D2D2D2D362D2D2D2D0D0D0D2D2D +2D2D2D2D0E2D2D2D2D2D2D0D2D2D0E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E2D2C0F0F0F0F0F0F0F0F0F0F370F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F2D370F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F2D2D111111111139111111111111111111 +111111111111111111111111111111112D2D3A3A12123A3A3A3A3A3A3A121212 +1212121212121212123A3A1212121212122D3A3C3C13133C3C3C3C3C3C3C0C13 +191B152D182D3C2D3B2D3C2A142D2D2D2D2D2D3C3D3D15153D3D3D3D3D3D3D16 +152D1B152D3D2D3D2D3B2D3D2D2D2D2D2D2D2D2D3D3D3D15153D3D3D3D3D3D3D +1B2D3D2D152D3D2D3D2D3B2D2D2D172D2D2D2D2D2D3D3D3D3D3D3D3D3D3D3D3D +3D163D3D1616163D3D3D163D3D3D3D163D163D16162D2C3E3E17173E3E3E3E3E +3E3E2D2D3E2D2D2D3E2D3E2D2D2D2D2D172D2D2D2D2D2D3E3F3F18183F3F3F3F +3F3F3F18183F18181818183F183F183F3F183F183F18182D2C2D2D1A1A2D2D2D +2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D41411A1A4141 +41414141412D2D1A2D2D2D412D412D2D2D412D1A2D2D2D2D2D2D2C2D2D1C1C2D +2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D40401C1C +404040404040402D2D2D2D1C2D2D2D402D2D2D402D1C2D2D2D2D2D2D402D2D1E +1E2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4242 +1E1E42424242424242421E2D2D2D2D422D422D2D2D422D1F2D2D2D2D2D2D2C42 +421F1F42424242424242421F2D2D2D2D422D422D2D2D422D2D2D2D2D2D2D2D2C +333321213333333333333321213321212121212D33212133332121212121212D +3321212121212121212121222121242121212121214321212121212121212121 +2D2D222222222222222222222122222222222222222222222222222222222322 +222D2D2222222222222222222222222222222222222222222222222222222222 +22222D2D24242424242424242424242424212424242424242424242424242424 +2424242D2D242424242424242424242424242424242424242424242424242424 +242424242D2D27271313272727272727272D2D2727272727272D272D27272727 +27272D27272D3333332727333333333333332D2728272727463327272D2D332A +271E272727272D33333329293333333333333329292929292929332D29292933 +292929292929292D334444292944444444444444292D292929292944442D2944 +4429292D292D29292D4445452A2A454545454545452D2D2D2A2A2A4545452D2A +2D452D2A2D2A2D2A2A2D45 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9e2d24e74e..ec8112f9d1 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -8,6 +8,11 @@ Red/System [ Distributed under the Boost Software License, Version 1.0. See https://github.com/red/red/blob/master/BSL-License.txt } + Notes: { + See %docs/lexer/ for FSM descriptions. + See %utils/generate-lexer-table.red for include file generation. + See %utils/generate-misc-tables.red for various tables and bit-arrays generation. + } ] lexer: context [ @@ -749,9 +754,16 @@ lexer: context [ ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + file [red-file!] ][ - null + if s/2 = #"^"" [s: s + 1] + flags: flags and not C_FLAG_CARET ;-- ensures that caret flag is not set + scan-string state s e flags + file: as red-file! state/buf-tail - 1 + file/header: TYPE_FILE + if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index ab0de97e7c..01e7f5a226 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -20,67 +20,69 @@ context [ S_SKIP_MSTR ;-- 5 S_FILE_1ST ;-- 6 S_FILE ;-- 7 - S_SKIP_FILE ;-- 8 - S_SLASH ;-- 9 - S_SHARP ;-- 10 - S_BINARY ;-- 11 - S_LINE_CMT2 ;-- 12 - S_CHAR ;-- 13 - S_SKIP_CHAR ;-- 14 - S_CONSTRUCT ;-- 15 - S_ISSUE ;-- 16 - S_NUMBER ;-- 17 - S_DOTNUM ;-- 18 - S_DECIMAL ;-- 19 - S_DEC_SPECIAL ;-- 20 - S_TUPLE ;-- 21 - S_DATE ;-- 22 - S_TIME_1ST ;-- 23 - S_TIME ;-- 24 - S_PAIR_1ST ;-- 25 - S_PAIR ;-- 26 - S_MONEY_1ST ;-- 27 - S_MONEY ;-- 28 - S_MONEY_DEC ;-- 29 - S_LESSER ;-- 30 - S_TAG ;-- 31 - S_TAG_STR ;-- 32 - S_SKIP_STR2 ;-- 33 - S_TAG_STR2 ;-- 34 - S_SKIP_STR3 ;-- 35 - S_SIGN ;-- 36 - S_WORD ;-- 37 - S_WORDSET ;-- 38 - S_URL ;-- 39 - S_EMAIL ;-- 40 - --EXIT_STATES-- ;-- 41 - T_EOF ;-- 42 - T_ERROR ;-- 43 - T_BLK_OP ;-- 44 - T_BLK_CL ;-- 45 - T_PAR_OP ;-- 46 - T_PAR_CL ;-- 47 - T_STRING ;-- 48 - T_WORD ;-- 49 - T_FILE ;-- 50 - T_REFINE ;-- 51 - T_BINARY ;-- 52 - T_CHAR ;-- 53 - T_MAP_OP ;-- 54 - T_CONS_MK ;-- 55 - T_ISSUE ;-- 56 - T_PERCENT ;-- 57 - T_INTEGER ;-- 58 - T_FLOAT ;-- 59 - T_TUPLE ;-- 60 - T_DATE ;-- 61 - T_PAIR ;-- 62 - T_TIME ;-- 63 - T_MONEY ;-- 64 - T_TAG ;-- 65 - T_URL ;-- 66 - T_EMAIL ;-- 67 - T_PATH ;-- 68 + S_FILE_HEX1 ;-- 8 + S_FILE_HEX2 ;-- 9 + S_FILE_STR ;-- 10 + S_SLASH ;-- 11 + S_SHARP ;-- 12 + S_BINARY ;-- 13 + S_LINE_CMT2 ;-- 14 + S_CHAR ;-- 15 + S_SKIP_CHAR ;-- 16 + S_CONSTRUCT ;-- 17 + S_ISSUE ;-- 18 + S_NUMBER ;-- 19 + S_DOTNUM ;-- 20 + S_DECIMAL ;-- 21 + S_DEC_SPECIAL ;-- 22 + S_TUPLE ;-- 23 + S_DATE ;-- 24 + S_TIME_1ST ;-- 25 + S_TIME ;-- 26 + S_PAIR_1ST ;-- 27 + S_PAIR ;-- 28 + S_MONEY_1ST ;-- 29 + S_MONEY ;-- 30 + S_MONEY_DEC ;-- 31 + S_LESSER ;-- 32 + S_TAG ;-- 33 + S_TAG_STR ;-- 34 + S_SKIP_STR2 ;-- 35 + S_TAG_STR2 ;-- 36 + S_SKIP_STR3 ;-- 37 + S_SIGN ;-- 38 + S_WORD ;-- 39 + S_WORDSET ;-- 40 + S_URL ;-- 41 + S_EMAIL ;-- 42 + --EXIT_STATES-- ;-- 43 + T_EOF ;-- 44 + T_ERROR ;-- 45 + T_BLK_OP ;-- 46 + T_BLK_CL ;-- 47 + T_PAR_OP ;-- 48 + T_PAR_CL ;-- 49 + T_STRING ;-- 50 + T_WORD ;-- 51 + T_FILE ;-- 52 + T_REFINE ;-- 53 + T_BINARY ;-- 54 + T_CHAR ;-- 55 + T_MAP_OP ;-- 56 + T_CONS_MK ;-- 57 + T_ISSUE ;-- 58 + T_PERCENT ;-- 59 + T_INTEGER ;-- 60 + T_FLOAT ;-- 61 + T_TUPLE ;-- 62 + T_DATE ;-- 63 + T_PAIR ;-- 64 + T_TIME ;-- 65 + T_MONEY ;-- 66 + T_TAG ;-- 67 + T_URL ;-- 68 + T_EMAIL ;-- 69 + T_PATH ;-- 70 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 62d8cdd16cf336db55793a4505a9c2cfbde51045 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 19 Oct 2019 12:06:47 +0200 Subject: [PATCH 0287/3432] FEAT: supports percent-encoded sequences in file! scanner. --- runtime/lexer.reds | 86 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ec8112f9d1..1c89d856ce 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -20,8 +20,8 @@ lexer: context [ #include %lexer-transitions.reds #enum class-flags! [ - C_FLAG_UCS4: 80000000h - C_FLAG_UCS2: 40000000h + C_FLAG_UCS4: 80000000h ;-- at least one UCS-4 char detected + C_FLAG_UCS2: 40000000h ;-- at least one UCS-2 char detected C_FLAG_CARET: 20000000h C_FLAG_DOT: 10000000h C_FLAG_COMMA: 08000000h @@ -31,7 +31,8 @@ lexer: context [ C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h C_FLAG_SIGN: 00200000h - C_FLAG_NOSTORE: 00000100h + C_FLAG_ESC_HEX: 00000200h ;-- percent-escaped mode + C_FLAG_NOSTORE: 00000100h ;-- do not store decoded value ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] @@ -447,6 +448,38 @@ lexer: context [ ser/tail: as red-value! p ] + scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] + /local + p [byte-ptr!] + c [integer!] + index [integer!] + class [integer!] + cb [byte!] + ][ + c: 0 + cb: as byte! 0 + loop 2 [ + either s/1 = #"0" [c: c << 4][ + index: 1 + as-integer s/1 + class: lex-classes/index + switch class [ + C_DIGIT [cb: s/1 - #"0"] + C_EXP + C_ALPHAX [ + cb: either s/1 < #"a" [s/1 - #"a"][s/1 - #"A"] + cb: cb + 10 + ] + default [throw LEX_ERROR] + ] + c: c << 4 + as-integer cb + ] + s: s + 1 + if s = e [throw LEX_ERROR] + ] + cp/value: c + s + ] + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] @@ -477,7 +510,10 @@ lexer: context [ switch class [ C_DIGIT [cb: p/1 - #"0"] C_EXP - C_ALPHAX [cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] cb: cb + 10] + C_ALPHAX [ + cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] + cb: cb + 10 + ] default [throw LEX_ERROR] ] c: c << 4 + as-integer cb @@ -598,6 +634,7 @@ lexer: context [ digits [integer!] extra [integer!] cp [integer!] + esc [byte!] w? [logic!] c [byte!] ][ @@ -637,7 +674,7 @@ lexer: context [ ][ ;-- with escape sequence(s) ;-- prescan the string for determining unit and accurate final codepoints count extra: 0 ;-- count extra bytes used by escape sequences - if unit < UCS-4 [ + if all [unit < UCS-4 flags and C_FLAG_ESC_HEX = 0][ p: s ;-- check if any escaped codepoint requires higher unit while [p < e][ @@ -675,6 +712,7 @@ lexer: context [ ][p: p + 1] ] ] + esc: either flags and C_FLAG_ESC_HEX = 0 [#"^^"][#"%"] str: string/make-at alloc-slot state len - extra unit ser: GET_BUFFER(str) @@ -682,8 +720,12 @@ lexer: context [ UCS-1 [ p: as byte-ptr! ser/offset while [s < e][ - either s/1 = #"^^" [ - s: scan-escaped-char s + 1 e :cp + either s/1 = esc [ + s: either esc = #"^^" [ + scan-escaped-char s + 1 e :cp + ][ + scan-percent-char s + 1 e :cp + ] p/value: as-byte cp ][ p/value: s/1 @@ -697,8 +739,12 @@ lexer: context [ cp: -1 p: as byte-ptr! ser/offset while [s < e][ - s: either s/1 = #"^^" [ - scan-escaped-char s + 1 e :cp + s: either s/1 = esc [ + either esc = #"^^" [ + scan-escaped-char s + 1 e :cp + ][ + scan-percent-char s + 1 e :cp + ] ][ decode-utf8-char s :cp ] @@ -713,8 +759,12 @@ lexer: context [ cp: -1 p4: as int-ptr! ser/offset while [s < e][ - s: either s/1 = #"^^" [ - scan-escaped-char s + 1 e :cp + s: either s/1 = esc [ + either esc = #"^^" [ + scan-escaped-char s + 1 e :cp + ][ + scan-percent-char s + 1 e :cp + ] ][ decode-utf8-char s :cp ] @@ -755,13 +805,17 @@ lexer: context [ scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - file [red-file!] + cell [cell!] + p [byte-ptr!] ][ - if s/2 = #"^"" [s: s + 1] - flags: flags and not C_FLAG_CARET ;-- ensures that caret flag is not set + flags: flags and not C_FLAG_CARET ;-- clears caret flag + either s/2 = #"^"" [s: s + 1][ ;-- skip " + p: s until [p: p + 1 any [p/1 = #"%" p = e]] ;-- check if any %xx + if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] + ] scan-string state s e flags - file: as red-file! state/buf-tail - 1 - file/header: TYPE_FILE + cell: state/buf-tail - 1 + set-type cell TYPE_FILE ;-- preserve header's flags if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] state/in-pos: e ;-- reset the input position to delimiter byte ] From 795e99ba1dab40da28d23ee5c70905016255f480 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 19 Oct 2019 15:28:00 +0200 Subject: [PATCH 0288/3432] FEAT: adds support for scanning tag! values. --- runtime/lexer.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1c89d856ce..d90fe026ed 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1045,9 +1045,14 @@ lexer: context [ ] scan-tag: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] ][ - null + flags: flags and not C_FLAG_CARET ;-- clears caret flag + scan-string state s e flags + cell: state/buf-tail - 1 + set-type cell TYPE_TAG ;-- preserve header's flags + state/in-pos: e + 1 ;-- skip ending delimiter ] scan-url: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From a29fa45e6be8b9c92600e3fe4e7af465333f603f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 19 Oct 2019 15:41:09 +0200 Subject: [PATCH 0289/3432] FEAT: adds support for scanning url! values. --- runtime/lexer.reds | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d90fe026ed..4ec0e1601c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1056,9 +1056,17 @@ lexer: context [ ] scan-url: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] + p [byte-ptr!] ][ - null + flags: flags and not C_FLAG_CARET ;-- clears caret flag + p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx + if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] + scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter + cell: state/buf-tail - 1 + set-type cell TYPE_URL ;-- preserve header's flags + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-email: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From d462049638c08b5f0f68f4cdcf17a68909958e89 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 19 Oct 2019 15:45:06 +0200 Subject: [PATCH 0290/3432] FEAT: adds support for scanning email! values. --- runtime/lexer.reds | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4ec0e1601c..bc79918d84 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1070,9 +1070,15 @@ lexer: context [ ] scan-email: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + cell [cell!] + p [byte-ptr!] ][ - null + flags: flags and not C_FLAG_CARET ;-- clears caret flag + scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter + cell: state/buf-tail - 1 + set-type cell TYPE_EMAIL ;-- preserve header's flags + state/in-pos: e ;-- reset the input position to delimiter byte ] scan-path: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 1d698e9e5436ee44f3ed85cb4812cbff5b58ee52 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 20 Oct 2019 22:05:57 +0200 Subject: [PATCH 0291/3432] FEAT: preliminary support for scanning path! values. --- docs/lexer/lexer-FSM.csv | 9 +- docs/lexer/lexer-FSM.xlsx | Bin 17807 -> 18343 bytes docs/lexer/lexer-states.txt | 8 +- runtime/lexer-transitions.reds | 96 ++++++++++---------- runtime/lexer.reds | 160 +++++++++++++++++++++++---------- utils/generate-lexer-table.red | 59 ++++++------ 6 files changed, 205 insertions(+), 127 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index b7accbbb22..82f31b2328 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -27,10 +27,10 @@ S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_D S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR @@ -42,3 +42,6 @@ S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_W S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;S_WORDSET;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 4005c3d68e01908fb274657ac6eb4719a291db96..8f364a055188ca4f4ef5488e824945e136c7228a 100644 GIT binary patch delta 9234 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 AmH+?% diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index d6d14ce3dc..0e66004e2c 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -266,10 +266,10 @@ S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL \ \->delimit7->T_EMAIL \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR - \ - \->"/"->T_PATH - \->"$"->S_MONEY - \->","|"#"|"%"->T_ERROR + \ + \->"/"->T_PATH + \->"$"->S_MONEY + \->","|"#"|"%"->T_ERROR diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 1f8cad7c99..d1d8b10e7a 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -45,6 +45,9 @@ Red/System [ S_WORDSET S_URL S_EMAIL + S_PATH + S_PATH_NUM + S_PATH_WORD --EXIT_STATES-- T_EOF T_ERROR @@ -74,49 +77,52 @@ Red/System [ T_EMAIL T_PATH ] transitions: #{ -000013132E2F3031042D020C27272727270B2D2027062D012D271D262D27272D -2C01000101010101010101010101010101010101010101010101010101010101 -2D2C020202020202020202023202020202020202020202020202020202020302 -022D2D0202020202020202020202020202020202020202020202020202020202 -02022D2C04040404040404040432040404040404040404040404040404040404 -0504042D2D040404040404040404040404040404040404040404040404040404 -040404042D2C333307073333333333330A070733070707070707070707333307 -07070707072D33343407073434343434342D0707340707070707070708073434 -0707070707072D34070709092D2D2D2D2D2D2D2D2D2D2D2D092D2D2D2D2D2D2D -2D2D2D2D2D2D2D2D2D070707072D2D2D2D2D2D2D2D2D2D2D2D072D2D2D2D2D2D -2D2D2D2D2D2D2D2D2D340A0A0A0A0A0A0A0A0A0A340A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A2D2D35350B0B353535353535350B0B0B0B0B0B0B0B0B0B -0B0B35350B0B0B0B0B0B2D353A3A1212112D382D0D2D0F12122D12121212122D -2D122D3A3A1212121212122D3A0D0D0D0D2D2D2D2D2D362D2D2D2D0D0D0D2D2D -2D2D2D2D0E2D2D2D2D2D2D0D2D2D0E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E2D2C0F0F0F0F0F0F0F0F0F0F370F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F2D370F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F2D2D111111111139111111111111111111 -111111111111111111111111111111112D2D3A3A12123A3A3A3A3A3A3A121212 -1212121212121212123A3A1212121212122D3A3C3C13133C3C3C3C3C3C3C0C13 -191B152D182D3C2D3B2D3C2A142D2D2D2D2D2D3C3D3D15153D3D3D3D3D3D3D16 -152D1B152D3D2D3D2D3B2D3D2D2D2D2D2D2D2D2D3D3D3D15153D3D3D3D3D3D3D -1B2D3D2D152D3D2D3D2D3B2D2D2D172D2D2D2D2D2D3D3D3D3D3D3D3D3D3D3D3D -3D163D3D1616163D3D3D163D3D3D3D163D163D16162D2C3E3E17173E3E3E3E3E -3E3E2D2D3E2D2D2D3E2D3E2D2D2D2D2D172D2D2D2D2D2D3E3F3F18183F3F3F3F -3F3F3F18183F18181818183F183F183F3F183F183F18182D2C2D2D1A1A2D2D2D -2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D41411A1A4141 -41414141412D2D1A2D2D2D412D412D2D2D412D1A2D2D2D2D2D2D2C2D2D1C1C2D -2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D40401C1C -404040404040402D2D2D2D1C2D2D2D402D2D2D402D1C2D2D2D2D2D2D402D2D1E -1E2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D4242 -1E1E42424242424242421E2D2D2D2D422D422D2D2D422D1F2D2D2D2D2D2D2C42 -421F1F42424242424242421F2D2D2D2D422D422D2D2D422D2D2D2D2D2D2D2D2C -333321213333333333333321213321212121212D33212133332121212121212D -3321212121212121212121222121242121212121214321212121212121212121 -2D2D222222222222222222222122222222222222222222222222222222222322 -222D2D2222222222222222222222222222222222222222222222222222222222 -22222D2D24242424242424242424242424212424242424242424242424242424 -2424242D2D242424242424242424242424242424242424242424242424242424 -242424242D2D27271313272727272727272D2D2727272727272D272D27272727 -27272D27272D3333332727333333333333332D2728272727463327272D2D332A -271E272727272D33333329293333333333333329292929292929332D29292933 -292929292929292D334444292944444444444444292D292929292944442D2944 -4429292D292D29292D4445452A2A454545454545452D2D2D2A2A2A4545452D2A -2D452D2A2D2A2D2A2A2D45 +00001313313233340430020C27272727270B30202706300130271D2630272730 +2F01000101010101010101010101010101010101010101010101010101010101 +302F020202020202020202023502020202020202020202020202020202020302 +0230300202020202020202020202020202020202020202020202020202020202 +0202302F04040404040404040435040404040404040404040404040404040404 +0504043030040404040404040404040404040404040404040404040404040404 +04040404302F363607073636363636360A070736070707070707070707363607 +0707070707303637370707373737373737300707370707070707070708073737 +0707070707073037070709093030303030303030303030300930303030303030 +3030303030303030300707070730303030303030303030303007303030303030 +303030303030303030370A0A0A0A0A0A0A0A0A0A370A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A303038380B0B383838383838380B0B0B0B0B0B0B0B0B0B +0B0B38380B0B0B0B0B0B30383D3D121211303B300D300F121230121212121230 +3012303D3D121212121212303D0D0D0D0D303030303039303030300D0D0D3030 +303030300E3030303030300D30300E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E302F0F0F0F0F0F0F0F0F0F0F3A0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F303A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F303011111111113C111111111111111111 +1111111111111111111111111111111130303D3D12123D3D3D3D3D3D3D121212 +1212121212121212123D3D121212121212303D3F3F13133F3F3F3F3F3F3F0C13 +191B153018303F303E303F2A143030303030303F404015154040404040404016 +15301B1530403040303E30403030303030303030404040151540404040404040 +1B3040301530403040303E303030173030303030304040404040404040404040 +401640401616164040401640404040164016401616302F414117174141414141 +4141303041303030413041303030303017303030303030414242181842424242 +4242421818421818181818421842184242184218421818302F30301A1A303030 +303030303030303030303030303030303030303030303030303044441A1A4444 +444444444430301A30303044304430303044301A3030303030302F30301C1C30 +3030303030303030303030303030303030303030303030303030303043431C1C +43434343434343303043301C3030304330303043301C3030303030304330301E +1E30303030303030303030303030303030303030303030303030303030304545 +1E1E45454545454545451E4530303045304530303045301F3030303030302F45 +451F1F45454545454545451F453030304530453030304530303030303030302F +3636212136363636363636212136212121212130362121363621212121212130 +3621212121212121212121222121242121212121214621212121212121212121 +3030222222222222222222222122222222222222222222222222222222222322 +2230302222222222222222222222222222222222222222222222222222222222 +2222303024242424242424242424242424212424242424242424242424242424 +2424243030242424242424242424242424242424242424242424242424242424 +2424242430302727131327272727272727303027272727272730273027272727 +272730272730363636272736363636363636302728272727493627273030362A +271E272727273036363629293636363636363629292929292929363029292936 +2929292929292930364747292947474747474747293029292929294747302947 +4729293029302929304748482A2A484848484848483030302A2A2A484848302A +3048302A302A302A2A304830302C2C303033343030020C2D2D2D2D2D3030202D +3030302A2D3026302D2D30303F3F2C2C3F3F3F3F3F3F3F0C133F1B15303F303F +303E303F2A143030303030303F36362D2D36363636363636302D282D2D2D3636 +2D2D3030362A2D302D2D2D2D3036 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index bc79918d84..55d06f9755 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -98,7 +98,7 @@ lexer: context [ skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000 + 00000000000000000000 } bin16-classes: #{ @@ -284,14 +284,16 @@ lexer: context [ ] state!: alias struct! [ - stack [red-block!] ;-- pairs of (offset,type) - buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) + stack [red-block!] ;-- pairs of (offset,type) + buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) buf-tail [red-value!] buf-slots [integer!] - input [byte-ptr!] - in-end [byte-ptr!] - in-pos [byte-ptr!] - err [integer!] + input [byte-ptr!] + in-end [byte-ptr!] + in-pos [byte-ptr!] + err [integer!] + entry [integer!] ;-- entry state for the FSM + path? [logic!] ;-- TRUE: loading an any-path! ] scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] @@ -331,6 +333,50 @@ lexer: context [ ] ] + open-block: func [state [state!] type [integer!] /local p [red-pair!]][ + p: as red-pair! ALLOC_TAIL(state/stack) + p/header: TYPE_PAIR + p/x: (as-integer state/buf-tail - state/buffer) >> 4 + p/y: type + alloc-slot state ;-- reserve slot for new block value + state/buffer: state/buf-tail + state/entry: S_START + state/path?: no + ] + + close-block: func [state [state!] type [integer!] force? [logic!] + /local + p [red-pair!] + new [red-value!] + len [integer!] + ser [series!] + ][ + ser: GET_BUFFER(state/stack) + p: as red-pair! ser/tail - 1 + assert TYPE_OF(p) = TYPE_PAIR + if all [not force? p/y <> type][throw LEX_ERROR] + len: (as-integer state/buf-tail - state/buffer) >> 4 + new: state/buffer - 1 + state/buf-tail: state/buffer + state/buffer: new - p/x + + store-any-block new state/buf-tail len type + + ser/tail: as cell! p + assert ser/offset <= ser/tail + p: as red-pair! ser/tail - 1 ;-- get parent series + either all [ + ser/offset <= p + not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] + ][ ;-- any-path! case + state/path?: yes + state/entry: S_PATH + ][ + state/path?: no + state/entry: S_START + ] + ] + decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] /local p [byte-ptr!] @@ -579,45 +625,21 @@ lexer: context [ scan-block-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - p [red-pair!] + type [integer!] ][ - p: as red-pair! ALLOC_TAIL(state/stack) - p/header: TYPE_PAIR - p/x: (as-integer state/buf-tail - state/buffer) >> 4 - p/y: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] - - alloc-slot state ;-- reserve slot for new block value - state/buffer: state/buf-tail - + type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] + open-block state type state/in-pos: e + 1 ;-- skip delimiter ] scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - /local - p [red-pair!] - new [red-value!] - len [integer!] + /local type [integer!] - ser [series!] ][ - ser: GET_BUFFER(state/stack) - p: as red-pair! ser/tail - 1 - assert TYPE_OF(p) = TYPE_PAIR - type: either s/1 = #")" [TYPE_PAREN][TYPE_BLOCK] - if p/y <> type [throw LEX_ERROR] - - len: (as-integer state/buf-tail - state/buffer) >> 4 - new: state/buffer - 1 - state/buf-tail: state/buffer - state/buffer: new - p/x - - store-any-block new state/buf-tail len type - - ser/tail: as cell! p - assert ser/offset <= ser/tail - - state/in-pos: e + 1 ;-- skip ending delimiter + close-block state type no + e: either all [state/path? e/2 = #"/"][e + 2][e + 1] + state/in-pos: e ;-- skip ending delimiter and eventual / ] scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -671,7 +693,7 @@ lexer: context [ ] ] ser/tail: as cell! (as byte-ptr! ser/offset) + (len << (unit >> 1)) - ][ ;-- with escape sequence(s) + ][ ;-- prescan the string for determining unit and accurate final codepoints count extra: 0 ;-- count extra bytes used by escape sequences if all [unit < UCS-4 flags and C_FLAG_ESC_HEX = 0][ @@ -793,9 +815,8 @@ lexer: context [ true [throw LEX_ERROR] ] ] - if flags and C_FLAG_QUOTE <> 0 [ ;@@ remove this check? - if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] - ] + if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] + cell: alloc-slot state word/make-at symbol/make-alt-utf8 s as-integer e - s cell cell/header: type @@ -1081,10 +1102,53 @@ lexer: context [ state/in-pos: e ;-- reset the input position to delimiter byte ] - scan-path: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + scan-path-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + type [integer!] ][ - null + type: switch s/1 [ + #"'" [s: s + 1 TYPE_LIT_PATH] + #":" [s: s + 1 TYPE_GET_PATH] + default [TYPE_PATH] + ] + open-block state type ;-- open a new path series + scan-word state s e flags ;-- load the head word + state/entry: S_PATH ;-- overwrites the S_START set by open-block + state/path?: yes ;-- overwrites the no value set by open-block + state/in-pos: e + 1 ;-- skip / + ] + + scan-path-item: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + slot [cell!] + p [red-pair!] + ser [series!] + type [integer!] + cp [integer!] + close? [logic!] + force? [logic!] + ][ + close?: either e >= state/in-end [yes][ ;-- EOF reached + cp: 1 + as-integer e/1 + switch lex-classes/cp and FFh [ + C_BLANK C_LINE C_BLOCK_OP C_BLOCK_CL + C_PAREN_OP C_PAREN_CL C_STRING_OP C_DBL_QUOTE [yes] + default [no] + ] + ] + either close? [ + ser: GET_BUFFER(state/stack) + p: as red-pair! ser/tail - 1 + type: p/y + if all [e < state/in-end e/1 = #":"][ + slot: state/buf-tail - 1 + if TYPE_OF(slot) = TYPE_SET_WORD [set-type slot TYPE_WORD] + type: TYPE_SET_PATH + ] + close-block state type yes + ][ + state/in-pos: e + 1 ;-- skip / + ] ] scanners: [ @@ -1114,7 +1178,7 @@ lexer: context [ :scan-tag ;-- T_TAG :scan-url ;-- T_URL :scan-email ;-- T_EMAIL - :scan-path ;-- T_PATH + :scan-path-open ;-- T_PATH ] scan-tokens: func [ @@ -1138,7 +1202,7 @@ lexer: context [ until [ flags: 0 term?: no - state: S_START + state: lex/entry p: lex/in-pos start: p offset: 0 @@ -1169,6 +1233,7 @@ lexer: context [ index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags + if lex/path? [scan-path-item lex start + offset p flags] lex/in-pos >= lex/in-end ] @@ -1195,6 +1260,7 @@ lexer: context [ state/in-end: src + len state/in-pos: src state/err: 0 + state/entry: S_START catch LEX_ERROR [scan-tokens state] if system/thrown > 0 [ diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 01e7f5a226..1ce10bc896 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -55,34 +55,37 @@ context [ S_WORDSET ;-- 40 S_URL ;-- 41 S_EMAIL ;-- 42 - --EXIT_STATES-- ;-- 43 - T_EOF ;-- 44 - T_ERROR ;-- 45 - T_BLK_OP ;-- 46 - T_BLK_CL ;-- 47 - T_PAR_OP ;-- 48 - T_PAR_CL ;-- 49 - T_STRING ;-- 50 - T_WORD ;-- 51 - T_FILE ;-- 52 - T_REFINE ;-- 53 - T_BINARY ;-- 54 - T_CHAR ;-- 55 - T_MAP_OP ;-- 56 - T_CONS_MK ;-- 57 - T_ISSUE ;-- 58 - T_PERCENT ;-- 59 - T_INTEGER ;-- 60 - T_FLOAT ;-- 61 - T_TUPLE ;-- 62 - T_DATE ;-- 63 - T_PAIR ;-- 64 - T_TIME ;-- 65 - T_MONEY ;-- 66 - T_TAG ;-- 67 - T_URL ;-- 68 - T_EMAIL ;-- 69 - T_PATH ;-- 70 + S_PATH ;-- 43 + S_PATH_NUM ;-- 44 + S_PATH_WORD ;-- 45 + --EXIT_STATES-- ;-- 46 + T_EOF ;-- 47 + T_ERROR ;-- 48 + T_BLK_OP ;-- 49 + T_BLK_CL ;-- 50 + T_PAR_OP ;-- 51 + T_PAR_CL ;-- 52 + T_STRING ;-- 53 + T_WORD ;-- 54 + T_FILE ;-- 55 + T_REFINE ;-- 56 + T_BINARY ;-- 57 + T_CHAR ;-- 58 + T_MAP_OP ;-- 59 + T_CONS_MK ;-- 60 + T_ISSUE ;-- 61 + T_PERCENT ;-- 62 + T_INTEGER ;-- 63 + T_FLOAT ;-- 64 + T_TUPLE ;-- 65 + T_DATE ;-- 66 + T_PAIR ;-- 67 + T_TIME ;-- 68 + T_MONEY ;-- 69 + T_TAG ;-- 70 + T_URL ;-- 71 + T_EMAIL ;-- 72 + T_PATH ;-- 73 ] CSV-table: %../docs/lexer/lexer-FSM.csv From f3788805e3edeb9c4526042b66fa2b305643dde5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 20 Oct 2019 22:58:58 +0200 Subject: [PATCH 0292/3432] FIX: C_SIGN lexical class was not leading to terminal states on reaching delimiters. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 18343 -> 18647 bytes runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 82f31b2328..3a26f7aeb1 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -37,7 +37,7 @@ S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR; S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;S_WORD;S_WORD;S_NUMBER;S_NUMBER;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 8f364a055188ca4f4ef5488e824945e136c7228a..db3ea4a634dfdcce3373322425b529235200ae54 100644 GIT binary patch literal 18647 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index d1d8b10e7a..7dc51f8c1f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -116,7 +116,7 @@ Red/System [ 2230302222222222222222222222222222222222222222222222222222222222 2222303024242424242424242424242424212424242424242424242424242424 2424243030242424242424242424242424242424242424242424242424242424 -2424242430302727131327272727272727303027272727272730273027272727 +2424242430303636131336363636363636303027272727273630273027362727 272730272730363636272736363636363636302728272727493627273030362A 271E272727273036363629293636363636363629292929292929363029292936 2929292929292930364747292947474747474747293029292929294747302947 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 55d06f9755..fb8858fc24 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1147,7 +1147,7 @@ lexer: context [ ] close-block state type yes ][ - state/in-pos: e + 1 ;-- skip / + state/in-pos: e + 1 ;-- skip / ] ] From e1d4f0e4636c0db9b6e3df1edd673e5287cd5aa9 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 20 Oct 2019 09:35:37 +0800 Subject: [PATCH 0293/3432] FIX: key focus widget need `grab` --- modules/view/backends/gtk3/events.reds | 16 +++++++++++++--- modules/view/backends/gtk3/gui.reds | 4 ---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index be90cc471a..e8d3876a77 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -637,9 +637,6 @@ connect-widget-events: function [ connect-common-events evbox widget connect-notify-events evbox widget - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - case [ sym = check [ ;@@ No click event for check @@ -657,9 +654,15 @@ connect-widget-events: function [ ] sym = base [ gobj_signal_connect(widget "draw" :base-draw widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_grab_focus widget + connect-focus-events widget widget ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -670,6 +673,9 @@ connect-widget-events: function [ ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gtk_widget_grab_focus widget connect-focus-events widget widget ] sym = slider [ @@ -679,6 +685,8 @@ connect-widget-events: function [ sym = text [0] sym = field [ gobj_signal_connect(widget "changed" :field-changed widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] @@ -694,6 +702,8 @@ connect-widget-events: function [ g_object_set [widget "populate-all" yes widget] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes gtk_widget_grab_focus widget connect-focus-events widget widget ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index d1925b11d4..cd8985ec3e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1207,10 +1207,6 @@ change-selection: func [ type = window [ switch TYPE_OF(int) [ TYPE_OBJECT [set-selected-focus widget] - TYPE_NONE [; as in windows but not sure! - ;; DEVEL: print ["DEVEL WARNING: 'change-selection windows' since not sure this is valid"] - gtk_widget_grab_focus widget - ] default [0] ] ] From 1530ec533272a2e0159d390952c500b7888d0194 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 21 Oct 2019 14:26:24 +0800 Subject: [PATCH 0294/3432] FIX: add text-list file --- build/includes.r | 1 + modules/view/backends/gtk3/events.reds | 2 +- modules/view/backends/gtk3/gui.reds | 67 +++++------------------ modules/view/backends/gtk3/text-list.reds | 55 +++++++++++++++++++ 4 files changed, 72 insertions(+), 53 deletions(-) create mode 100644 modules/view/backends/gtk3/text-list.reds diff --git a/build/includes.r b/build/includes.r index 8b0c435bc3..9335c8c7c5 100644 --- a/build/includes.r +++ b/build/includes.r @@ -239,6 +239,7 @@ write %build/bin/sources.r set-cache [ %rules.red %tab-panel.reds %text-box.reds + %text-list.reds ] %test/ [ %draw.reds diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e8d3876a77..f8c73c800d 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -699,7 +699,7 @@ connect-widget-events: function [ ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] gobj_signal_connect(buffer "changed" :area-changed widget) ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] - g_object_set [widget "populate-all" yes widget] + g_object_set [widget "populate-all" yes null] ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) gtk_widget_set_can_focus widget yes diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index cd8985ec3e..0e864e9730 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -33,6 +33,7 @@ Red/System [ #include %handlers.reds #include %comdlgs.reds #include %tab-panel.reds +#include %text-list.reds GTKApp: as handle! 0 GTKApp-Ctx: 0 @@ -1084,20 +1085,22 @@ change-text: func [ ] change-data: func [ - widget [handle!] - values [red-value!] + widget [handle!] + values [red-value!] /local - data [red-value!] - word [red-word!] - size [red-pair!] - f [red-float!] - str [red-string!] - caption [c-string!] - type [integer!] - len [integer!] + data [red-value!] + word [red-word!] + selected [red-integer!] + size [red-pair!] + f [red-float!] + str [red-string!] + caption [c-string!] + type [integer!] + len [integer!] ][ data: as red-value! values + FACE_OBJ_DATA word: as red-word! values + FACE_OBJ_TYPE + selected: as red-integer! values + FACE_OBJ_SELECTED type: word/symbol ;;DEBUG: print ["change-data: " get-symbol-name type lf] @@ -1134,7 +1137,7 @@ change-data: func [ ][ ;;DEBUG: print ["text-list updated" lf] gtk_container_foreach widget as-integer :remove-entry widget - init-text-list widget as red-block! data + init-text-list widget as red-block! data selected gtk_widget_show_all widget ] any [type = drop-list type = drop-down][ @@ -1422,44 +1425,6 @@ remove-entry: func [ gtk_container_remove container widget ] -init-text-list: func [ - widget [handle!] - data [red-block!] - /local - str [red-string!] - tail [red-string!] - val [c-string!] - len [integer!] - label [handle!] - type [integer!] -][ - if any [ - TYPE_OF(data) = TYPE_BLOCK - TYPE_OF(data) = TYPE_HASH - TYPE_OF(data) = TYPE_MAP - ][ - ;; DEBUG: print ["init-text-list" lf] - str: as red-string! block/rs-head data - tail: as red-string! block/rs-tail data - - if str = tail [exit] - - while [str < tail][ - type: TYPE_OF(str) - ;; DEBUG: print ["type " type lf] - if ANY_STRING?(type) [ - len: -1 - val: unicode/to-utf8 str :len - label: gtk_label_new val - ;; DEBUG: print ["Add elt: " val lf] - gtk_widget_set_halign label 1 ;-- GTK_ALIGN_START - gtk_container_add widget label - ] - str: str + 1 - ] - ] -] - font-size?: func [ font [red-object!] return: [integer!] @@ -1777,7 +1742,6 @@ OS-make-view: func [ buffer: gtk_entry_get_buffer widget unless null? caption [ gtk_entry_buffer_set_text buffer caption -1 - gtk_widget_show buffer ] gtk_entry_set_width_chars widget size/x / font-size? font set-hint-text widget as red-block! values + FACE_OBJ_OPTIONS @@ -1797,7 +1761,6 @@ OS-make-view: func [ buffer: gtk_text_view_get_buffer widget unless null? caption [ gtk_text_buffer_set_text buffer caption -1 - gtk_widget_show buffer ] container: gtk_scrolled_window_new null null gtk_container_add container widget @@ -1819,7 +1782,7 @@ OS-make-view: func [ ] sym = text-list [ widget: gtk_list_box_new - init-text-list widget data + init-text-list widget data selected ;gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 container: gtk_scrolled_window_new null null if bits and FACET_FLAGS_NO_BORDER = 0 [ diff --git a/modules/view/backends/gtk3/text-list.reds b/modules/view/backends/gtk3/text-list.reds new file mode 100644 index 0000000000..2775af1999 --- /dev/null +++ b/modules/view/backends/gtk3/text-list.reds @@ -0,0 +1,55 @@ +Red/System [ + Title: "gtk3 text-list widget" + Author: "bitbegin" + File: %text-list.reds + Tabs: 4 + Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +init-text-list: func [ + widget [handle!] + data [red-block!] + selected [red-integer!] + /local + str [red-string!] + tail [red-string!] + val [c-string!] + len [integer!] + label [handle!] + type [integer!] + item [handle!] +][ + if any [ + TYPE_OF(data) = TYPE_BLOCK + TYPE_OF(data) = TYPE_HASH + TYPE_OF(data) = TYPE_MAP + ][ + str: as red-string! block/rs-head data + tail: as red-string! block/rs-tail data + + while [str < tail][ + type: TYPE_OF(str) + if ANY_STRING?(type) [ + len: -1 + val: unicode/to-utf8 str :len + label: gtk_label_new val + gtk_widget_set_halign label 1 ;-- GTK_ALIGN_START + gtk_container_add widget label + ] + str: str + 1 + ] + ] + + either TYPE_OF(selected) <> TYPE_INTEGER [ + selected/header: TYPE_INTEGER + selected/value: -1 + ][ + item: gtk_list_box_get_row_at_index widget selected/value + gtk_list_box_select_row widget item + ] +] + From af8dc45a14805dc521185c8c62a673f1e03d5aaf Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 21 Oct 2019 14:39:48 +0800 Subject: [PATCH 0295/3432] FIX: gtk_widget_get_parent failed for text-list --- modules/view/backends/gtk3/gui.reds | 25 +++++++++++++---------- modules/view/backends/gtk3/tab-panel.reds | 1 - 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 0e864e9730..284934b8c3 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,6 +10,8 @@ Red/System [ } ] +#define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] +#define GET-CONTAINER(s) [g_object_get_qdata s container-id] #define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] #define GET-CURSOR(s) [g_object_get_qdata s cursor-id] #define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] @@ -49,7 +51,7 @@ red-face-id2: g_quark_from_string "red-face-id2" red-face-id3: g_quark_from_string "red-face-id3" red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" -win-layout-id: g_quark_from_string "win-layout-id" +container-id: g_quark_from_string "container-id" red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" @@ -224,7 +226,7 @@ get-face-layout: func [ sym = area sym = text-list ][ - gtk_widget_get_parent widget + GET-CONTAINER(widget) ] true [ widget @@ -261,7 +263,7 @@ set-widget-child: func [ clayout: get-face-layout widget cvalues csym case [ sym = window [ - playout: g_object_get_qdata parent win-layout-id + playout: GET-CONTAINER(parent) gtk_layout_put playout clayout x y true ] @@ -831,7 +833,7 @@ change-pane: func [ layout: case [ type = window [ - g_object_get_qdata parent win-layout-id + GET-CONTAINER(parent) ] type = group-box [ gtk_bin_get_child parent @@ -1138,7 +1140,7 @@ change-data: func [ ;;DEBUG: print ["text-list updated" lf] gtk_container_foreach widget as-integer :remove-entry widget init-text-list widget as red-block! data selected - gtk_widget_show_all widget + gtk_widget_show widget ] any [type = drop-list type = drop-down][ init-combo-box widget as red-block! data null type = drop-list @@ -1265,7 +1267,7 @@ set-logic-state: func [ state/value: check? either check? [-1][0] ][ - as-integer state/value ;-- returns 0/1, matches the messages + as-integer state/value ;-- returns 0/1, matches the messages ] gtk_toggle_button_set_active widget as logic! value if value = -1 [gtk_toggle_button_set_inconsistent widget true] @@ -1650,6 +1652,8 @@ OS-make-view: func [ null ] + container: null + case [ sym = check [ widget: gtk_check_button_new_with_label caption @@ -1705,7 +1709,6 @@ OS-make-view: func [ container: gtk_layout_new null null gtk_layout_set_size container size/x size/y gtk_widget_show container - g_object_set_qdata widget win-layout-id container gtk_box_pack_start winbox container yes yes 0 gtk_window_move widget offset/x offset/y @@ -1769,9 +1772,9 @@ OS-make-view: func [ widget: gtk_frame_new caption gtk_frame_set_shadow_type widget 3 gtk_frame_set_label_align widget 0.5 0.5 ; Todo: does not seem to work - container: gtk_layout_new null null - gtk_widget_show container - gtk_container_add widget container + buffer: gtk_layout_new null null + gtk_widget_show buffer + gtk_container_add widget buffer ] sym = panel [ widget: gtk_layout_new null null @@ -1783,7 +1786,6 @@ OS-make-view: func [ sym = text-list [ widget: gtk_list_box_new init-text-list widget data selected - ;gtk_list_box_select_row widget gtk_list_box_get_row_at_index widget 0 container: gtk_scrolled_window_new null null if bits and FACET_FLAGS_NO_BORDER = 0 [ gtk_scrolled_window_set_shadow_type container 3 @@ -1810,6 +1812,7 @@ OS-make-view: func [ ] ] + unless null? container [SET-CONTAINER(widget container)] ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT store-face-to-obj widget face diff --git a/modules/view/backends/gtk3/tab-panel.reds b/modules/view/backends/gtk3/tab-panel.reds index 608b0a4a13..55cd87523e 100644 --- a/modules/view/backends/gtk3/tab-panel.reds +++ b/modules/view/backends/gtk3/tab-panel.reds @@ -76,7 +76,6 @@ update-tabs: func [ part [integer!] /local widget [handle!] - parent [handle!] str [red-string!] ][ widget: get-face-handle face From bbfff48f7bc5c0f26dfb8fbedead4968f2427525 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 21 Oct 2019 16:18:16 +0800 Subject: [PATCH 0296/3432] FIX: set parent's children failed --- modules/view/backends/gtk3/gui.reds | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 284934b8c3..48d0eebede 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -829,8 +829,6 @@ change-pane: func [ offset [red-pair!] ][ - ;; DEBUG: print ["change-pane " get-symbol-name type lf] - layout: case [ type = window [ GET-CONTAINER(parent) @@ -851,12 +849,11 @@ change-pane: func [ ] unless null? layout [ - list: as GList! gtk_container_get_children parent + list: as GList! gtk_container_get_children layout child: list while [not null? child][ - g_object_ref child/data ;-- to avoid destruction before removing from container - gtk_container_remove parent child/data - ;; DEBUG: print ["removed widget" nb ": " child/data " to " parent lf] + g_object_ref child/data ;-- to avoid destruction before removing from container + gtk_container_remove layout child/data child: child/next ] g_list_free as int-ptr! list @@ -1852,7 +1849,6 @@ OS-make-view: func [ change-color widget as red-tuple! values + FACE_OBJ_COLOR sym - ;; USELESS: if sym <> window [gtk_widget_show widget] stack/unwind as-integer widget ] From 253b76541723e6d1acd1ed7307bee3605528081f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 21 Oct 2019 16:42:57 +0800 Subject: [PATCH 0297/3432] FIX: now can run `tests/view-test.red` --- modules/view/backends/gtk3/gui.reds | 17 +++++++++-------- modules/view/backends/gtk3/tab-panel.reds | 4 ++-- modules/view/backends/gtk3/text-list.reds | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 48d0eebede..fabc5e42da 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -493,10 +493,9 @@ free-handles: func [ state/header: TYPE_NONE ] -; on-gc-mark: does [ -; collector/keep flags-blk/node -; collector/keep win-array/node -; ] +on-gc-mark: does [ + collector/keep flags-blk/node +] show-gtk-version: func [][ print [ "GTK VERSION: " gtk_get_major_version "." gtk_get_minor_version "." gtk_get_micro_version lf] @@ -595,7 +594,6 @@ init: func [][ probe "ERROR: GTK: Cannot acquire main context" halt ] g_application_register GTKApp null null - ;;;vector/make-at as red-value! win-array 8 TYPE_INTEGER 4 screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height @@ -603,7 +601,7 @@ init: func [][ set-defaults #if type = 'exe [red-gtk-styles] - ;;;collector/register as int-ptr! :on-gc-mark + collector/register as int-ptr! :on-gc-mark ] get-symbol-name: function [ @@ -1197,8 +1195,7 @@ change-selection: func [ ; ] ; ] type = text-list [ - item: gtk_list_box_get_row_at_index widget idx - gtk_list_box_select_row widget item + select-text-list widget idx ] any [type = drop-list type = drop-down][ gtk_combo_box_set_active widget idx @@ -1721,6 +1718,10 @@ OS-make-view: func [ gtk_window_set_decorated widget yes ] ] + sym = camera [ + widget: gtk_layout_new null null + gtk_layout_set_size widget size/x size/y + ] sym = slider [ vertical?: size/y > size/x value: either vertical? [size/y][size/x] diff --git a/modules/view/backends/gtk3/tab-panel.reds b/modules/view/backends/gtk3/tab-panel.reds index 55cd87523e..18f2fbb41f 100644 --- a/modules/view/backends/gtk3/tab-panel.reds +++ b/modules/view/backends/gtk3/tab-panel.reds @@ -40,8 +40,8 @@ select-tab: func [ widget [handle!] int [red-integer!] /local - nb [integer!] - idx [integer!] + nb [integer!] + idx [integer!] ][ nb: gtk_notebook_get_n_pages widget idx: int/value diff --git a/modules/view/backends/gtk3/text-list.reds b/modules/view/backends/gtk3/text-list.reds index 2775af1999..236adb7c56 100644 --- a/modules/view/backends/gtk3/text-list.reds +++ b/modules/view/backends/gtk3/text-list.reds @@ -10,6 +10,18 @@ Red/System [ } ] +select-text-list: func [ + widget [handle!] + int [integer!] + /local + item [handle!] +][ + item: gtk_list_box_get_row_at_index widget int + unless null? item [ + gtk_list_box_select_row widget item + ] +] + init-text-list: func [ widget [handle!] data [red-block!] @@ -21,7 +33,6 @@ init-text-list: func [ len [integer!] label [handle!] type [integer!] - item [handle!] ][ if any [ TYPE_OF(data) = TYPE_BLOCK @@ -37,6 +48,7 @@ init-text-list: func [ len: -1 val: unicode/to-utf8 str :len label: gtk_label_new val + gtk_widget_show label gtk_widget_set_halign label 1 ;-- GTK_ALIGN_START gtk_container_add widget label ] @@ -48,8 +60,7 @@ init-text-list: func [ selected/header: TYPE_INTEGER selected/value: -1 ][ - item: gtk_list_box_get_row_at_index widget selected/value - gtk_list_box_select_row widget item + select-text-list widget selected/value ] ] From c67bf9eb0be3bc20668721796fa37acaf2a7ffb1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 14:04:40 +0200 Subject: [PATCH 0298/3432] FEAT: simplifies lexer's stack management. Now the stack is implicitly managed in the accumulating buffer. --- runtime/lexer.reds | 79 ++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fb8858fc24..672ac853f0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -284,9 +284,9 @@ lexer: context [ ] state!: alias struct! [ - stack [red-block!] ;-- pairs of (offset,type) buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) - buf-tail [red-value!] + head [red-value!] + tail [red-value!] buf-slots [integer!] input [byte-ptr!] in-end [byte-ptr!] @@ -299,18 +299,17 @@ lexer: context [ scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] stash: as cell! 0 ;-- special buffer for hatching any-blocks series - stack: as red-block! 0 ;-- nested series stack stash-size: 1000 ;-- pre-allocated cells number depth: 0 ;-- recursive calls depth - alloc-slot: func [s [state!] return: [red-value!] /local slot [red-value!]][ - if s/buffer + s/buf-slots <= s/buf-tail [ + alloc-slot: func [state [state!] return: [red-value!] /local slot [red-value!]][ + if state/head + state/buf-slots <= state/tail [ assert false 0 ;TBD: expand ] - slot: s/buf-tail + slot: state/tail slot/header: TYPE_UNSET - s/buf-tail: s/buf-tail + 1 + state/tail: state/tail + 1 slot ] @@ -333,40 +332,35 @@ lexer: context [ ] ] - open-block: func [state [state!] type [integer!] /local p [red-pair!]][ - p: as red-pair! ALLOC_TAIL(state/stack) - p/header: TYPE_PAIR - p/x: (as-integer state/buf-tail - state/buffer) >> 4 + open-block: func [state [state!] type [integer!] /local p [red-pair!] len [integer!]][ + len: (as-integer state/tail - state/head) >> 4 + p: as red-pair! alloc-slot state + p/header: TYPE_PAIR ;-- use the slot for stack info + p/x: len p/y: type - alloc-slot state ;-- reserve slot for new block value - state/buffer: state/buf-tail + + state/head: state/tail state/entry: S_START state/path?: no ] close-block: func [state [state!] type [integer!] force? [logic!] /local - p [red-pair!] - new [red-value!] - len [integer!] - ser [series!] + p [red-pair!] + len [integer!] ][ - ser: GET_BUFFER(state/stack) - p: as red-pair! ser/tail - 1 - assert TYPE_OF(p) = TYPE_PAIR + p: as red-pair! state/head - 1 + assert all [state/buffer <= p TYPE_OF(p) = TYPE_PAIR] if all [not force? p/y <> type][throw LEX_ERROR] - len: (as-integer state/buf-tail - state/buffer) >> 4 - new: state/buffer - 1 - state/buf-tail: state/buffer - state/buffer: new - p/x + len: (as-integer state/tail - state/head) >> 4 + state/tail: state/head + state/head: as cell! p - p/x - store-any-block new state/buf-tail len type + store-any-block as cell! p state/tail len type - ser/tail: as cell! p - assert ser/offset <= ser/tail - p: as red-pair! ser/tail - 1 ;-- get parent series + p: as red-pair! state/head - 1 ;-- get parent series either all [ - ser/offset <= p + state/buffer <= p not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] ][ ;-- any-path! case state/path?: yes @@ -835,7 +829,7 @@ lexer: context [ if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] scan-string state s e flags - cell: state/buf-tail - 1 + cell: state/tail - 1 set-type cell TYPE_FILE ;-- preserve header's flags if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] state/in-pos: e ;-- reset the input position to delimiter byte @@ -935,7 +929,7 @@ lexer: context [ ][ assert e/1 = #"%" scan-float state s e flags - fl: as red-float! state/buf-tail - 1 + fl: as red-float! state/tail - 1 fl/header: TYPE_PERCENT fl/value: fl/value / 100.0 @@ -1071,7 +1065,7 @@ lexer: context [ ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag scan-string state s e flags - cell: state/buf-tail - 1 + cell: state/tail - 1 set-type cell TYPE_TAG ;-- preserve header's flags state/in-pos: e + 1 ;-- skip ending delimiter ] @@ -1085,7 +1079,7 @@ lexer: context [ p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter - cell: state/buf-tail - 1 + cell: state/tail - 1 set-type cell TYPE_URL ;-- preserve header's flags state/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1097,7 +1091,7 @@ lexer: context [ ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter - cell: state/buf-tail - 1 + cell: state/tail - 1 set-type cell TYPE_EMAIL ;-- preserve header's flags state/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1122,7 +1116,6 @@ lexer: context [ /local slot [cell!] p [red-pair!] - ser [series!] type [integer!] cp [integer!] close? [logic!] @@ -1137,11 +1130,10 @@ lexer: context [ ] ] either close? [ - ser: GET_BUFFER(state/stack) - p: as red-pair! ser/tail - 1 + p: as red-pair! state/head - 1 type: p/y if all [e < state/in-end e/1 = #":"][ - slot: state/buf-tail - 1 + slot: state/tail - 1 if TYPE_OF(slot) = TYPE_SET_WORD [set-type slot TYPE_WORD] type: TYPE_SET_PATH ] @@ -1252,9 +1244,9 @@ lexer: context [ ][ depth: depth + 1 - state/stack: stack state/buffer: stash ;TBD: support dyn buffer case - state/buf-tail: stash + state/head: stash + state/tail: stash state/buf-slots: stash-size ;TBD: support dyn buffer case state/input: src state/in-end: src + len @@ -1266,17 +1258,14 @@ lexer: context [ if system/thrown > 0 [ 0 ; error handling ] - assert block/rs-tail? state/stack ;-- stack should be empty - - slots: (as-integer state/buf-tail - state/buffer) >> 4 - store-any-block dst state/buffer slots TYPE_BLOCK + slots: (as-integer state/tail - state/head) >> 4 + store-any-block dst state/head slots TYPE_BLOCK depth: depth - 1 ] init: func [][ stash: as cell! allocate stash-size * size? cell! - stack: block/make-in root 20 ] ] \ No newline at end of file From cc79fda03e509c047c46e28a94a2a3d9e663dca6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 17:31:00 +0200 Subject: [PATCH 0299/3432] FEAT: completes any-path! support in lexer. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 18647 -> 18380 bytes runtime/lexer-transitions.reds | 4 ++-- runtime/lexer.reds | 26 +++++++++++++------------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 3a26f7aeb1..b7cd322791 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -27,7 +27,7 @@ S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_D S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF @@ -44,4 +44,4 @@ S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;S_WORDSET;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index db3ea4a634dfdcce3373322425b529235200ae54..a2832a83f4608ec1b026f61e0866ae9ec0190246 100644 GIT binary patch literal 18380 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 literal 18647 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 state/in-end [yes][ ;-- EOF reached cp: 1 + as-integer e/1 switch lex-classes/cp and FFh [ - C_BLANK C_LINE C_BLOCK_OP C_BLOCK_CL + C_BLANK C_LINE C_BLOCK_OP C_BLOCK_CL C_COLON C_PAREN_OP C_PAREN_CL C_STRING_OP C_DBL_QUOTE [yes] default [no] ] @@ -1133,12 +1131,12 @@ lexer: context [ p: as red-pair! state/head - 1 type: p/y if all [e < state/in-end e/1 = #":"][ - slot: state/tail - 1 - if TYPE_OF(slot) = TYPE_SET_WORD [set-type slot TYPE_WORD] type: TYPE_SET_PATH + state/in-pos: e + 1 ;-- skip : ] close-block state type yes ][ + if all [e < state/in-end e/1 = #":"][throw LEX_ERROR] ;-- set-words not allowed inside paths state/in-pos: e + 1 ;-- skip / ] ] @@ -1225,8 +1223,10 @@ lexer: context [ index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags - if lex/path? [scan-path-item lex start + offset p flags] + if all [lex/path? state <> T_PATH][ + scan-path-item lex start + offset lex/in-pos flags + ] lex/in-pos >= lex/in-end ] assert lex/in-pos = lex/in-end @@ -1256,7 +1256,7 @@ lexer: context [ catch LEX_ERROR [scan-tokens state] if system/thrown > 0 [ - 0 ; error handling + probe "Syntax error" ;TBD: error handling ] slots: (as-integer state/tail - state/head) >> 4 store-any-block dst state/head slots TYPE_BLOCK From 234c613c542072b275900f81a43613fe87ae7d07 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 17:33:28 +0200 Subject: [PATCH 0300/3432] FEAT: renames lexer's `buf-slots` field to `slots`. --- runtime/lexer.reds | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3e0704d0cd..61bb6f6998 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -284,16 +284,16 @@ lexer: context [ ] state!: alias struct! [ - buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) - head [red-value!] - tail [red-value!] - buf-slots [integer!] - input [byte-ptr!] - in-end [byte-ptr!] - in-pos [byte-ptr!] - err [integer!] - entry [integer!] ;-- entry state for the FSM - path? [logic!] ;-- TRUE: loading an any-path! + buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) + head [red-value!] + tail [red-value!] + slots [integer!] + input [byte-ptr!] + in-end [byte-ptr!] + in-pos [byte-ptr!] + err [integer!] + entry [integer!] ;-- entry state for the FSM + path? [logic!] ;-- TRUE: loading an any-path! ] scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] @@ -303,7 +303,7 @@ lexer: context [ depth: 0 ;-- recursive calls depth alloc-slot: func [state [state!] return: [red-value!] /local slot [red-value!]][ - if state/head + state/buf-slots <= state/tail [ + if state/head + state/slots <= state/tail [ assert false 0 ;TBD: expand ] @@ -1244,15 +1244,15 @@ lexer: context [ ][ depth: depth + 1 - state/buffer: stash ;TBD: support dyn buffer case - state/head: stash - state/tail: stash - state/buf-slots: stash-size ;TBD: support dyn buffer case - state/input: src - state/in-end: src + len - state/in-pos: src - state/err: 0 - state/entry: S_START + state/buffer: stash ;TBD: support dyn buffer case + state/head: stash + state/tail: stash + state/slots: stash-size ;TBD: support dyn buffer case + state/input: src + state/in-end: src + len + state/in-pos: src + state/err: 0 + state/entry: S_START catch LEX_ERROR [scan-tokens state] if system/thrown > 0 [ From 837cdb965c52814739a8db994f8d78fccb82caf0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 17:38:22 +0200 Subject: [PATCH 0301/3432] FEAT: removes `path?` field in lexer.reds Redundant information with `entry` field. --- runtime/lexer.reds | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 61bb6f6998..da924f903b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -293,7 +293,6 @@ lexer: context [ in-pos [byte-ptr!] err [integer!] entry [integer!] ;-- entry state for the FSM - path? [logic!] ;-- TRUE: loading an any-path! ] scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] @@ -341,7 +340,6 @@ lexer: context [ state/head: state/tail ;-- points just after p state/entry: S_START - state/path?: no ] close-block: func [state [state!] type [integer!] force? [logic!] @@ -363,10 +361,8 @@ lexer: context [ state/buffer <= p not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] ][ ;-- any-path! case - state/path?: yes state/entry: S_PATH ][ - state/path?: no state/entry: S_START ] ] @@ -805,7 +801,7 @@ lexer: context [ case [ s/1 = #":" [s: s + 1 type: TYPE_GET_WORD] e/0 = #":" [e: e - 1 type: TYPE_SET_WORD] - all [e/1 = #":" state/path?][0] ;-- do nothing if in a path + all [e/1 = #":" state/entry = S_PATH][0] ;-- do nothing if in a path true [throw LEX_ERROR] ] ] @@ -1108,7 +1104,6 @@ lexer: context [ open-block state type ;-- open a new path series scan-word state s e flags ;-- load the head word state/entry: S_PATH ;-- overwrites the S_START set by open-block - state/path?: yes ;-- overwrites the no value set by open-block state/in-pos: e + 1 ;-- skip / ] @@ -1224,8 +1219,8 @@ lexer: context [ do-scan: as scanner! scanners/index do-scan lex start + offset p flags - if all [lex/path? state <> T_PATH][ - scan-path-item lex start + offset lex/in-pos flags + if all [lex/entry = S_PATH state <> T_PATH][ + scan-path-item lex start + offset lex/in-pos flags ;-- lex/in-pos could have changed ] lex/in-pos >= lex/in-end ] From 1c7f7cb49e53fc6fee79b30519b4223a152e5338 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 17:47:54 +0200 Subject: [PATCH 0302/3432] FEAT: uses a lookup table to detect paths ending. --- runtime/lexer.reds | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index da924f903b..0733cbe707 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -100,6 +100,10 @@ lexer: context [ 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000 } + + path-ending: #{ + 010100000101010101000100000100000000000000010001000000000000000001 + } bin16-classes: #{ 0000000000000000000102000001000000000000000000000000000000000000 @@ -1112,15 +1116,13 @@ lexer: context [ p [red-pair!] type [integer!] cp [integer!] + index [integer!] close? [logic!] ][ close?: either e >= state/in-end [yes][ ;-- EOF reached cp: 1 + as-integer e/1 - switch lex-classes/cp and FFh [ - C_BLANK C_LINE C_BLOCK_OP C_BLOCK_CL C_COLON - C_PAREN_OP C_PAREN_CL C_STRING_OP C_DBL_QUOTE [yes] - default [no] - ] + index: lex-classes/cp and FFh + 1 ;-- query the class of ending character + as-logic path-ending/index ;-- lookup if the character class is ending path ] either close? [ p: as red-pair! state/head - 1 From aa701459f7c05b903f3ffa4df12d612ed86cfe49 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 20:12:36 +0200 Subject: [PATCH 0303/3432] FEAT: optimizes all hexa decoding routines in lexer using tables. --- runtime/lexer.reds | 76 +++++++++++----------------------- utils/generate-misc-tables.red | 10 ++--- 2 files changed, 30 insertions(+), 56 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 0733cbe707..c049e257b9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -123,14 +123,14 @@ lexer: context [ } hexa-table: #{ - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000010203040506070809000000000000 - 000A0B0C0D0E0F00000000000000000000000000000000000000000000000000 - 000A0B0C0D0E0F00000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00010203040506070809FFFFFFFFFFFF + FF0A0B0C0D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF0A0B0C0D0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF } ;-- Bit-array for BDELNPTbdelnpt @@ -490,34 +490,19 @@ lexer: context [ scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] /local - p [byte-ptr!] c [integer!] + c2 [integer!] index [integer!] - class [integer!] - cb [byte!] ][ + if s + 1 >= e [throw LEX_ERROR] c: 0 - cb: as byte! 0 - loop 2 [ - either s/1 = #"0" [c: c << 4][ - index: 1 + as-integer s/1 - class: lex-classes/index - switch class [ - C_DIGIT [cb: s/1 - #"0"] - C_EXP - C_ALPHAX [ - cb: either s/1 < #"a" [s/1 - #"a"][s/1 - #"A"] - cb: cb + 10 - ] - default [throw LEX_ERROR] - ] - c: c << 4 + as-integer cb - ] - s: s + 1 - if s = e [throw LEX_ERROR] - ] - cp/value: c - s + index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table + c: as-integer hexa-table/index ;-- decode high nibble + index: 1 + as-integer s/2 + c2: as-integer hexa-table/index ;-- decode low nibble + if any [c = -1 c2 = -1][throw LEX_ERROR] + cp/value: c c << 4 or c2 + s + 2 ] scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] @@ -529,13 +514,12 @@ lexer: context [ c [integer!] pos [integer!] index [integer!] - class [integer!] skip [integer!] res [integer!] cb [byte!] bit [byte!] ][ - either s/1 = #"(" [ ;-- note: #"^(" not allowed + either s/1 = #"(" [ ;-- note: #"^(" not allowed c: as-integer s/2 pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) @@ -544,25 +528,15 @@ lexer: context [ c: 0 cb: as byte! 0 while [all [p/1 <> #")" p < e]][ - either p/1 = #"0" [c: c << 4][ - index: 1 + as-integer p/1 - class: lex-classes/index - switch class [ - C_DIGIT [cb: p/1 - #"0"] - C_EXP - C_ALPHAX [ - cb: either p/1 < #"a" [p/1 - #"a"][p/1 - #"A"] - cb: cb + 10 - ] - default [throw LEX_ERROR] - ] - c: c << 4 + as-integer cb - ] + index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table + cb: hexa-table/index ;-- decode nibble + if cb = #"^(FF)" [throw LEX_ERROR] + c: c << 4 + as-integer cb p: p + 1 ] if any [p = e p/1 <> #")"][throw LEX_ERROR] - p: p + 1 ;-- skip ) - ][ ;-- named escaped char + p: p + 1 ;-- skip ) + ][ ;-- named escaped char cb: s/2 if cb < #"a" [cb: cb or #"^(20)"] src: s + 2 @@ -587,7 +561,7 @@ lexer: context [ either char-special/pos and bit = null-byte [ ;-- "regular" escaped char if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] c: as-integer s/1 - #"@" - ][ ;-- escaped special char + ][ ;-- escaped special char c: switch s/1 [ #"/" [0Ah] #"-" [09h] diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index c96b9854b3..d73e8dddc0 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -57,11 +57,11 @@ gen-hexa-table: function [][ repeat i 256 [ c: to-char i - 1 - append out to-char case [ - find digit c [c - #"0"] - find upper c [c - #"A" + 10] - find lower c [c - #"a" + 10] - 'else [0] + append out case [ + find digit c [to-char c - #"0"] + find upper c [to-char c - #"A" + 10] + find lower c [to-char c - #"a" + 10] + 'else [#{FF}] ] ] print "--gen-hexa-table-- (lexer/hexa-table)" From 056039ddebfbe50927c77bd4deafda1975ea4966 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 20:19:49 +0200 Subject: [PATCH 0304/3432] FEAT: checks if hex values in escaped sequence are 6 characters long max. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c049e257b9..2184b547a1 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -534,7 +534,7 @@ lexer: context [ c: c << 4 + as-integer cb p: p + 1 ] - if any [p = e p/1 <> #")"][throw LEX_ERROR] + if any [p = e p/1 <> #")" (as-integer p - s) > 7][throw LEX_ERROR] ;-- limit of 6 hexa characters. p: p + 1 ;-- skip ) ][ ;-- named escaped char cb: s/2 From 261d258d84454efb8dc3218854ba655d731bce26 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 21:35:05 +0200 Subject: [PATCH 0305/3432] FEAT: replaces a switch statement by an array for escape character names. --- runtime/lexer.reds | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 2184b547a1..9ab3ff26d9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -138,6 +138,16 @@ lexer: context [ ;-- Bit-array for /-~^{}" char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} + + escape-names: [ + "null" 4 00h + "back" 4 08h + "tab" 3 09h + "line" 4 0Ah + "page" 4 0Ch + "esc" 3 1Bh + "del" 3 7Fh + ] lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL @@ -509,13 +519,11 @@ lexer: context [ /local p [byte-ptr!] src [byte-ptr!] - word [c-string!] len [integer!] c [integer!] pos [integer!] index [integer!] - skip [integer!] - res [integer!] + entry [int-ptr!] cb [byte!] bit [byte!] ][ @@ -537,22 +545,17 @@ lexer: context [ if any [p = e p/1 <> #")" (as-integer p - s) > 7][throw LEX_ERROR] ;-- limit of 6 hexa characters. p: p + 1 ;-- skip ) ][ ;-- named escaped char - cb: s/2 - if cb < #"a" [cb: cb or #"^(20)"] - src: s + 2 - word: switch cb [ - #"n" [c: 00h skip: 4 "ull"] - #"b" [c: 08h skip: 4 "ack"] - #"t" [c: 09h skip: 3 "ab" ] - #"l" [c: 0Ah skip: 4 "ine"] - #"p" [c: 0Ch skip: 4 "age"] - #"e" [c: 1Bh skip: 3 "sc" ] - #"d" [c: 7Fh skip: 3 "el" ] - default [assert false null] + src: s + 1 ;-- skip ( + entry: escape-names + loop 7 [ + if zero? platform/strnicmp src as byte-ptr! entry/1 entry/2 [break] + entry: entry + 3 ] - res: platform/strnicmp src as byte-ptr! word skip - 1 - if any [res <> 0 src/skip <> #")"][throw LEX_ERROR] - p: src + skip + assert escape-names + (7 * 3) > entry + len: entry/2 + 1 + if src/len <> #")" [throw LEX_ERROR] + c: entry/3 + p: src + len ] ][ c: as-integer s/1 From 60c021125a7c1264242afa5dd8b68ab95e91c3c5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 21:37:34 +0200 Subject: [PATCH 0306/3432] FIX: typo in percent-decoding routine causing a regression. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9ab3ff26d9..752c0315a8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -511,7 +511,7 @@ lexer: context [ index: 1 + as-integer s/2 c2: as-integer hexa-table/index ;-- decode low nibble if any [c = -1 c2 = -1][throw LEX_ERROR] - cp/value: c c << 4 or c2 + cp/value: c << 4 or c2 s + 2 ] From 22234a97996ea63bcb7817af2a0f8eb968e435e3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 21 Oct 2019 22:51:21 +0200 Subject: [PATCH 0307/3432] FEAT: adds support for scanning map! values. --- runtime/lexer.reds | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 752c0315a8..5e1432c194 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -537,7 +537,7 @@ lexer: context [ cb: as byte! 0 while [all [p/1 <> #")" p < e]][ index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table - cb: hexa-table/index ;-- decode nibble + cb: hexa-table/index ;-- decode one nibble at a time if cb = #"^(FF)" [throw LEX_ERROR] c: c << 4 + as-integer cb p: p + 1 @@ -603,13 +603,28 @@ lexer: context [ state/in-pos: e + 1 ;-- skip delimiter ] - scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + close-block state TYPE_BLOCK no + state/in-pos: e + 1 ;-- skip ] + ] + + scan-paren-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local + p [red-pair!] + blk [red-block!] type [integer!] ][ - type: either s/1 = #")" [TYPE_PAREN][TYPE_BLOCK] - close-block state type no - state/in-pos: e + 1 ;-- skip ending delimiter + p: as red-pair! state/head - 1 + assert p >= state/buffer + type: p/y + close-block state type yes + + if type = TYPE_MAP [ + blk: as red-block! p + blk/header: TYPE_BLOCK ;-- forces a block type + map/make-at as cell! blk blk block/rs-length? blk + ] + state/in-pos: e + 1 ;-- skip ) ] scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -875,10 +890,9 @@ lexer: context [ state/in-pos: e + 1 ;-- skip ending delimiter ] - scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null + scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + open-block state TYPE_MAP + state/in-pos: e + 1 ;-- skip ( ] scan-construct: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1121,7 +1135,7 @@ lexer: context [ :scan-block-open ;-- T_BLK_OP :scan-block-close ;-- T_BLK_CL :scan-block-open ;-- T_PAR_OP - :scan-block-close ;-- T_PAR_CL + :scan-paren-close ;-- T_PAR_CL :scan-string ;-- T_STRING :scan-word ;-- T_WORD :scan-file ;-- T_FILE From 20383ecb94532746905e54139c628200b9c3efd5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 22 Oct 2019 13:20:20 +0200 Subject: [PATCH 0308/3432] FEAT: refactors open-block/close-block API to better isolate stack management. --- runtime/lexer.reds | 62 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5e1432c194..60bff0ec29 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -345,32 +345,42 @@ lexer: context [ ] ] - open-block: func [state [state!] type [integer!] /local p [red-pair!] len [integer!]][ + open-block: func [state [state!] type [integer!] hint [integer!] + /local p [red-point!] len [integer!] + ][ len: (as-integer state/tail - state/head) >> 4 - p: as red-pair! alloc-slot state - p/header: TYPE_PAIR ;-- use the slot for stack info + p: as red-point! alloc-slot state + p/header: TYPE_POINT ;-- use the slot for stack info p/x: len p/y: type + p/z: hint state/head: state/tail ;-- points just after p state/entry: S_START ] - close-block: func [state [state!] type [integer!] force? [logic!] + close-block: func [state [state!] type [integer!] final [integer!] + return: [integer!] /local - p [red-pair!] - len [integer!] + p [red-point!] + len [integer!] + hint [integer!] ][ - p: as red-pair! state/head - 1 - assert all [state/buffer <= p TYPE_OF(p) = TYPE_PAIR] - if all [not force? p/y <> type][throw LEX_ERROR] + p: as red-point! state/head - 1 + assert all [state/buffer <= p TYPE_OF(p) = TYPE_POINT] + either type = -1 [ + type: either final = -1 [p/y][final] + ][ + if p/y <> type [throw LEX_ERROR] + ] len: (as-integer state/tail - state/head) >> 4 state/tail: state/head state/head: as cell! p - p/x + hint: p/z store-any-block as cell! p state/tail len type ;-- p slot gets overwritten here - p: as red-pair! state/head - 1 ;-- get parent series + p: as red-point! state/head - 1 ;-- get parent series either all [ state/buffer <= p not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] @@ -379,6 +389,7 @@ lexer: context [ ][ state/entry: S_START ] + hint ] decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] @@ -599,29 +610,21 @@ lexer: context [ type [integer!] ][ type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] - open-block state type + open-block state type -1 state/in-pos: e + 1 ;-- skip delimiter ] scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - close-block state TYPE_BLOCK no + close-block state TYPE_BLOCK -1 state/in-pos: e + 1 ;-- skip ] ] scan-paren-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - p [red-pair!] blk [red-block!] - type [integer!] ][ - p: as red-pair! state/head - 1 - assert p >= state/buffer - type: p/y - close-block state type yes - - if type = TYPE_MAP [ - blk: as red-block! p - blk/header: TYPE_BLOCK ;-- forces a block type + if TYPE_MAP = close-block state TYPE_PAREN -1 [ + blk: as red-block! state/tail - 1 map/make-at as cell! blk blk block/rs-length? blk ] state/in-pos: e + 1 ;-- skip ) @@ -891,7 +894,7 @@ lexer: context [ ] scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - open-block state TYPE_MAP + open-block state TYPE_PAREN TYPE_MAP state/in-pos: e + 1 ;-- skip ( ] @@ -1096,7 +1099,7 @@ lexer: context [ #":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH] default [TYPE_PATH] ] - open-block state type ;-- open a new path series + open-block state type -1 ;-- open a new path series scan-word state s e flags ;-- load the head word state/entry: S_PATH ;-- overwrites the S_START set by open-block state/in-pos: e + 1 ;-- skip / @@ -1104,7 +1107,6 @@ lexer: context [ scan-path-item: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - p [red-pair!] type [integer!] cp [integer!] index [integer!] @@ -1116,13 +1118,11 @@ lexer: context [ as-logic path-ending/index ;-- lookup if the character class is ending path ] either close? [ - p: as red-pair! state/head - 1 - type: p/y - if all [e < state/in-end e/1 = #":"][ - type: TYPE_SET_PATH + type: either all [e < state/in-end e/1 = #":"][ state/in-pos: e + 1 ;-- skip : - ] - close-block state type yes + TYPE_SET_PATH + ][-1] + close-block state -1 type ][ if all [e < state/in-end e/1 = #":"][throw LEX_ERROR] ;-- set-words not allowed inside paths state/in-pos: e + 1 ;-- skip / From c68feb87110b2e425e4adb89b24dfe2c62cb3dff Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 22 Oct 2019 16:25:35 +0200 Subject: [PATCH 0309/3432] FEAT: adds support for scanning construction syntax. Note: only a small subset of Rebol-style construction syntax is currently supported. --- runtime/lexer.reds | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 60bff0ec29..3a8271d18e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -148,6 +148,15 @@ lexer: context [ "esc" 3 1Bh "del" 3 7Fh ] + + cons-syntax: [ + ;--- word --- length -- value --- + "true" 4 true + "false" 5 false + "none!" 5 TYPE_NONE + "none" 4 TYPE_NONE + ;... to be eventually completed + ] lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL @@ -864,7 +873,7 @@ lexer: context [ default [assert false 0] ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail - state/in-pos: e + 1 ;-- skip ending delimiter + state/in-pos: e + 1 ;-- skip } ] scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -890,7 +899,7 @@ lexer: context [ char/header: TYPE_CHAR char/value: c - state/in-pos: e + 1 ;-- skip ending delimiter + state/in-pos: e + 1 ;-- skip " ] scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ @@ -899,9 +908,33 @@ lexer: context [ ] scan-construct: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + dt [red-datatype!] + p [int-ptr!] + dtypes [int-ptr!] + end [int-ptr!] + len [integer!] ][ - null + s: s + 2 ;-- skip #[ + p: cons-syntax + dtypes: p + (3 * 2) + end: p + (3 * 4) ;-- point to end of array + loop 4 [ + if zero? platform/strnicmp s as byte-ptr! p/1 p/2 [break] + p: p + 3 + ] + if p = end [throw LEX_ERROR] ;-- no match, error case + len: p/2 + 1 + if s/len <> #"]" [throw LEX_ERROR] + + dt: as red-datatype! alloc-slot state + either p < dtypes [ + dt/header: TYPE_LOGIC + dt/value: p/3 + ][ + dt/header: p/3 + ] + state/in-pos: e + 1 ;-- skip ] ] scan-ref-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From bc09b74cbfda6dc1fe4601c90ad86ee22a927353 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 22 Oct 2019 17:20:50 +0200 Subject: [PATCH 0310/3432] FEAT: adds extra path states for accurate handling of supported element types. --- docs/lexer/lexer-FSM.csv | 6 +- docs/lexer/lexer-FSM.xlsx | Bin 18380 -> 18647 bytes runtime/lexer-transitions.reds | 100 +++++++++++++++++---------------- utils/generate-lexer-table.red | 58 ++++++++++--------- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index b7cd322791..953ac6f221 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -42,6 +42,8 @@ S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_W S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index a2832a83f4608ec1b026f61e0866ae9ec0190246..777ca1d160c3dca183e040efc51677b8936ec339 100644 GIT binary patch delta 8413 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 E4>cOUJpcdz delta 8109 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 X2ZO1DA1z_in)o7p5r#~yy?^jO7ct+) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 4904f6b1e2..6a3b09bc79 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -48,6 +48,8 @@ Red/System [ S_PATH S_PATH_NUM S_PATH_WORD + S_PATH_SHARP + S_PATH_SIGN --EXIT_STATES-- T_EOF T_ERROR @@ -77,52 +79,54 @@ Red/System [ T_EMAIL T_PATH ] transitions: #{ -00001313313233340430020C27272727270B30202706300130271D2630272730 -2F01000101010101010101010101010101010101010101010101010101010101 -302F020202020202020202023502020202020202020202020202020202020302 -0230300202020202020202020202020202020202020202020202020202020202 -0202302F04040404040404040435040404040404040404040404040404040404 -0504043030040404040404040404040404040404040404040404040404040404 -04040404302F363607073636363636360A070736070707070707070707363607 -0707070707303637370707373737373737300707370707070707070708073737 -0707070707073037070709093030303030303030303030300930303030303030 -3030303030303030300707070730303030303030303030303007303030303030 -303030303030303030370A0A0A0A0A0A0A0A0A0A370A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A303038380B0B383838383838380B0B0B0B0B0B0B0B0B0B -0B0B38380B0B0B0B0B0B30383D3D121211303B300D300F121230121212121230 -3012303D3D121212121212303D0D0D0D0D303030303039303030300D0D0D3030 -303030300E3030303030300D30300E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E302F0F0F0F0F0F0F0F0F0F0F3A0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F303A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F303011111111113C111111111111111111 -1111111111111111111111111111111130303D3D12123D3D3D3D3D3D3D121212 -1212121212121212123D3D121212121212303D3F3F13133F3F3F3F3F3F3F0C13 -191B153018303F303E303F2A143030303030303F404015154040404040404016 -15301B1530403040303E30403030303030303030404040151540404040404040 -1B3040301530403040303E303030173030303030304040404040404040404040 -401640401616164040401640404040164016401616302F414117174141414141 -4141303041303030413041303030303017303030303030414242181842424242 -4242421818421818181818421842184242184218421818302F30301A1A303030 -303030303030303030303030303030303030303030303030303044441A1A4444 -444444444430301A30303044304430303044301A3030303030302F30301C1C30 -3030303030303030303030303030303030303030303030303030303043431C1C -43434343434343303043301C3043304330303043301C3030303030304330301E -1E30303030303030303030303030303030303030303030303030303030304545 -1E1E45454545454545451E4530303045304530303045301F3030303030302F45 -451F1F45454545454545451F453030304530453030304530303030303030302F -3636212136363636363636212136212121212130362121363621212121212130 -3621212121212121212121222121242121212121214621212121212121212121 -3030222222222222222222222122222222222222222222222222222222222322 -2230302222222222222222222222222222222222222222222222222222222222 -2222303024242424242424242424242424212424242424242424242424242424 -2424243030242424242424242424242424242424242424242424242424242424 -2424242430303636131336363636363636303027272727273630273027362727 -272730272730363636272736363636363636302728272727493627273030362A -271E272727273036363629293636363636363629292929292929363029292936 -2929292929292930364747292947474747474747293029292929294747302947 -4729293029302929304748482A2A484848484848483030302A2A2A484848302A -3048302A302A302A2A304830302C2C303033343030020C2D2D2D2D2D3030202D -3030302A2D3026302D2D30303F3F2C2C3F3F3F3F3F3F3F0C133F1B15303F303F -303E303F2A143030303030303F36362D2D36363636363636302D362D2D2D3636 -2D2D3030362A2D302D2D2D2D3036 +00001313333435360432020C27272727270B32202706320132271D2632272732 +3101000101010101010101010101010101010101010101010101010101010101 +3231020202020202020202023702020202020202020202020202020202020302 +0232320202020202020202020202020202020202020202020202020202020202 +0202323104040404040404040437040404040404040404040404040404040404 +0504043232040404040404040404040404040404040404040404040404040404 +040404043231383807073838383838380A070738070707070707070707383807 +0707070707323839390707393939393939320707390707070707070708073939 +0707070707073239070709093232323232323232323232320932323232323232 +3232323232323232320707070732323232323232323232323207323232323232 +323232323232323232390A0A0A0A0A0A0A0A0A0A390A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A32323A3A0B0B3A3A3A3A3A3A3A0B0B0B0B0B0B0B0B0B0B +0B0B3A3A0B0B0B0B0B0B323A3F3F121211323D320D320F121232121212121232 +3212323F3F121212121212323F0D0D0D0D32323232323B323232320D0D0D3232 +323232320E3232323232320D32320E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F323C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111113E111111111111111111 +1111111111111111111111111111111132323F3F12123F3F3F3F3F3F3F121212 +1212121212121212123F3F121212121212323F41411313414141414141410C13 +191B1532183241324032412A1432323232323241424215154242424242424216 +15321B1532423242324032423232323232323232424242151542424242424242 +1B32423215324232423240323232173232323232324242424242424242424242 +4216424216161642424216424242421642164216163231434317174343434343 +4343323243323232433243323232323217323232323232434444181844444444 +4444441818441818181818441844184444184418441818323132321A1A323232 +323232323232323232323232323232323232323232323232323246461A1A4646 +464646464632321A32323246324632323246321A3232323232323132321C1C32 +3232323232323232323232323232323232323232323232323232323245451C1C +45454545454545323245321C3245324532323245321C3232323232324532321E +1E32323232323232323232323232323232323232323232323232323232324747 +1E1E47474747474747471E4732323247324732323247321F3232323232323147 +471F1F47474747474747471F4732323247324732323247323232323232323231 +3838212138383838383838212138212121212132382121383821212121212132 +3821212121212121212121222121242121212121214821212121212121212121 +3232222222222222222222222122222222222222222222222222222222222322 +2232322222222222222222222222222222222222222222222222222222222222 +2222323224242424242424242424242424212424242424242424242424242424 +2424243232242424242424242424242424242424242424242424242424242424 +2424242432323838131338383838383838323227272727273832273227382727 +2727322727323838382727383838383838383227282727274B3827273232382A +271E272727273238383829293838383838383829292929292929383229292938 +2929292929292932384949292949494949494949293229292929294949322949 +492929322932292932494A4A2A2A4A4A4A4A4A4A4A3232322A2A2A4A4A4A322A +324A322A322A322A2A324A32322C2C323235363232022E2D2D2D2D2D3232202D +3232322A2D322F322D2D323241412C2C414141414141413213411B1532413241 +324032412A143232323232324138382D2D38383838383838322D382D2D2D3838 +2D2D3232382A2D322D2D2D2D32383F3F12121132323232320F12123212121212 +12323212323F3F121212121212323F38382C2C38383838383838323227272727 +27383227322738272727273227273238 } diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 1ce10bc896..e18195f101 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -58,34 +58,36 @@ context [ S_PATH ;-- 43 S_PATH_NUM ;-- 44 S_PATH_WORD ;-- 45 - --EXIT_STATES-- ;-- 46 - T_EOF ;-- 47 - T_ERROR ;-- 48 - T_BLK_OP ;-- 49 - T_BLK_CL ;-- 50 - T_PAR_OP ;-- 51 - T_PAR_CL ;-- 52 - T_STRING ;-- 53 - T_WORD ;-- 54 - T_FILE ;-- 55 - T_REFINE ;-- 56 - T_BINARY ;-- 57 - T_CHAR ;-- 58 - T_MAP_OP ;-- 59 - T_CONS_MK ;-- 60 - T_ISSUE ;-- 61 - T_PERCENT ;-- 62 - T_INTEGER ;-- 63 - T_FLOAT ;-- 64 - T_TUPLE ;-- 65 - T_DATE ;-- 66 - T_PAIR ;-- 67 - T_TIME ;-- 68 - T_MONEY ;-- 69 - T_TAG ;-- 70 - T_URL ;-- 71 - T_EMAIL ;-- 72 - T_PATH ;-- 73 + S_PATH_SHARP ;-- 46 + S_PATH_SIGN ;-- 47 + --EXIT_STATES-- ;-- 48 + T_EOF ;-- 49 + T_ERROR ;-- 50 + T_BLK_OP ;-- 51 + T_BLK_CL ;-- 52 + T_PAR_OP ;-- 53 + T_PAR_CL ;-- 54 + T_STRING ;-- 55 + T_WORD ;-- 56 + T_FILE ;-- 57 + T_REFINE ;-- 58 + T_BINARY ;-- 59 + T_CHAR ;-- 60 + T_MAP_OP ;-- 61 + T_CONS_MK ;-- 62 + T_ISSUE ;-- 63 + T_PERCENT ;-- 64 + T_INTEGER ;-- 65 + T_FLOAT ;-- 66 + T_TUPLE ;-- 67 + T_DATE ;-- 68 + T_PAIR ;-- 69 + T_TIME ;-- 70 + T_MONEY ;-- 71 + T_TAG ;-- 72 + T_URL ;-- 73 + T_EMAIL ;-- 74 + T_PATH ;-- 75 ] CSV-table: %../docs/lexer/lexer-FSM.csv From ed4aacb01ef259f6e2c627e873366438c838d6db Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 22 Oct 2019 17:22:58 +0200 Subject: [PATCH 0311/3432] DOCS: describes state transitions from S_PATH entry state. --- docs/lexer/lexer-states.txt | 57 ++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 0e66004e2c..10faedf7cc 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -1,6 +1,5 @@ -=== Lexical Scanner FSM - +=== Lexical Scanner FSM === S_START S_LINE_CMT @@ -43,6 +42,11 @@ S_WORD S_WORDSET S_URL S_EMAIL +S_PATH +S_PATH_NUM +S_PATH_WORD +S_PATH_SHARP +S_PATH_SIGN --EXIT_STATES-- T_EOF T_ERROR @@ -273,7 +277,51 @@ S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD -=== Binary16 FSM +S_PATH->ws|";"|"["|"]"|"{"|"/"|"%"->T_ERROR +S_PATH->"("->T_PAR_OP +S_PATH->")"->T_PAR_CL +S_PATH->dbl-quote->S_LINE_STR + +S_PATH->"#"->S_PATH_SHARP->dbl-quote->S_CHAR + \->not(delimit9)->S_ISSUE->not(delimit1)->S_ISSUE + \ \->delimit1->T_ISSUE + \->delimit9->T_ERROR + +S_PATH->digit->S_PATH_NUM->digit|"'"->S_PATH_NUM + \->delimit10->T_INTEGER + \->"%"->T_PERCENT + \->"."->S_DOTNUM + \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR + \ + \->"e"|"E"->S_DECIMAL + \->else->T_ERROR + +S_PATH->"<"->S_LESSER + +S_PATH->"+"|"-"->S_PATH_SIGN->digit->S_PATH_NUM + \->"$"->S_MONEY + \->delimit14->T_ERROR + \->else->S_WORD + +S_PATH->"$"->S_MONEY_1ST + +S_PATH->not(delimit6)->S_PATH_WORD->not(delimit5)->S_PATH_WORD + \->delimit7->T_WORD + \ + \->":"->T_WORD + \ + \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL + \ \->delimit7->T_EMAIL + \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR + \ + \->"/"->T_WORD + \->"$"->S_MONEY + \->","|"#"|"%"->T_ERROR + + +=== Binary16 FSM === S_BIN_START ;-- 0 @@ -301,4 +349,5 @@ S_BIN_START->hexa->S_BIN_1ST->hexa->T_BIN_BYTE \->blank->S_BIN_START \ \->;->S_BIN_CMT->lf->S_BIN_START - \->not(lf)->S_BIN_CMT \ No newline at end of file + \->not(lf)->S_BIN_CMT + \ No newline at end of file From 5f62f321b836f3aeeeb7c9039dce1201e0203cfc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 22 Oct 2019 18:22:54 +0200 Subject: [PATCH 0312/3432] FEAT: supports new-line flag detection and setting in lexer. --- runtime/datatypes/binary.reds | 4 ++-- runtime/datatypes/block.reds | 4 ++-- runtime/datatypes/integer.reds | 2 +- runtime/datatypes/map.reds | 2 +- runtime/datatypes/pair.reds | 2 +- runtime/datatypes/string.reds | 4 ++-- runtime/datatypes/word.reds | 2 +- runtime/lexer.reds | 27 +++++++++++++++++---------- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index 31d31ac67f..262b35617c 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -894,10 +894,10 @@ binary: context [ bin [red-binary!] ][ bin: as red-binary! slot - bin/header: TYPE_UNSET + set-type slot TYPE_UNSET bin/head: 0 bin/node: alloc-bytes size - bin/header: TYPE_BINARY + set-type slot TYPE_BINARY bin ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index faf231d520..ff36b9b5d7 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -362,11 +362,11 @@ block: context [ ][ if size < 0 [size: 1] - blk/header: TYPE_UNSET + set-type as cell! blk TYPE_UNSET ;-- preserve eventual newline flag blk/head: 0 blk/node: alloc-cells size blk/extra: 0 - blk/header: TYPE_BLOCK ;-- implicit reset of all header flags + set-type as cell! blk TYPE_BLOCK blk ] diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index ca1984af56..b9d91fbcd7 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -285,7 +285,7 @@ integer: context [ int [red-integer!] ][ int: as red-integer! slot - int/header: TYPE_INTEGER + set-type slot TYPE_INTEGER int/value: value int ] diff --git a/runtime/datatypes/map.reds b/runtime/datatypes/map.reds index 2b4992fee4..6c6e5627ef 100644 --- a/runtime/datatypes/map.reds +++ b/runtime/datatypes/map.reds @@ -187,7 +187,7 @@ map: context [ if blk = null [blk: block/make-at as red-block! slot size] table: _hashtable/init size blk HASH_TABLE_MAP 1 map: as red-hash! slot - map/header: TYPE_MAP ;-- implicit reset of all header flags + set-type slot TYPE_MAP map/table: table map ] diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index a8dd704293..666beed694 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -80,7 +80,7 @@ pair: context [ #if debug? = yes [if verbose > 0 [print-line "pair/make-at"]] pair: as red-pair! slot - pair/header: TYPE_PAIR + set-type slot TYPE_PAIR pair/x: x pair/y: y pair diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 204afb6b14..3cf8af4bff 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -1130,11 +1130,11 @@ string: context [ str [red-string!] ][ str: as red-string! slot - str/header: TYPE_UNSET + set-type slot TYPE_UNSET str/head: 0 str/node: alloc-codepoints size unit str/cache: null - str/header: TYPE_STRING + set-type slot TYPE_STRING str ] diff --git a/runtime/datatypes/word.reds b/runtime/datatypes/word.reds index 32cd37c3e5..4e136ce1df 100644 --- a/runtime/datatypes/word.reds +++ b/runtime/datatypes/word.reds @@ -49,7 +49,7 @@ word: context [ cell [red-word!] ][ cell: as red-word! pos - cell/header: TYPE_WORD ;-- implicit reset of all header flags + set-type pos TYPE_WORD cell/ctx: global-ctx cell/symbol: id cell/index: _context/add TO_CTX(global-ctx) cell diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3a8271d18e..735cb77c8d 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -314,6 +314,8 @@ lexer: context [ input [byte-ptr!] in-end [byte-ptr!] in-pos [byte-ptr!] + line [integer!] ;-- current line number + nline [integer!] ;-- new lines count for new token err [integer!] entry [integer!] ;-- entry state for the FSM ] @@ -331,6 +333,7 @@ lexer: context [ ] slot: state/tail slot/header: TYPE_UNSET + if state/nline > 0 [slot/header: slot/header or flag-new-line] state/tail: state/tail + 1 slot ] @@ -344,7 +347,7 @@ lexer: context [ block/make-at as red-block! slot 1 ][ blk: block/make-at as red-block! slot items - blk/header: type + blk/header: blk/header and type-mask or type s: GET_BUFFER(blk) copy-memory as byte-ptr! s/offset @@ -359,7 +362,7 @@ lexer: context [ ][ len: (as-integer state/tail - state/head) >> 4 p: as red-point! alloc-slot state - p/header: TYPE_POINT ;-- use the slot for stack info + set-type as cell! p TYPE_POINT ;-- use the slot for stack info p/x: len p/y: type p/z: hint @@ -817,7 +820,7 @@ lexer: context [ cell: alloc-slot state word/make-at symbol/make-alt-utf8 s as-integer e - s cell - cell/header: type + set-type cell type if type = TYPE_SET_WORD [state/in-pos: e + 1] ;-- skip ending delimiter ] @@ -896,7 +899,7 @@ lexer: context [ if c > 0010FFFFh [throw LEX_ERROR] char: as red-char! alloc-slot state - char/header: TYPE_CHAR + set-type as cell! char TYPE_CHAR char/value: c state/in-pos: e + 1 ;-- skip " @@ -929,10 +932,10 @@ lexer: context [ dt: as red-datatype! alloc-slot state either p < dtypes [ - dt/header: TYPE_LOGIC + set-type as cell! dt TYPE_LOGIC dt/value: p/3 ][ - dt/header: p/3 + set-type as cell! dt p/3 ] state/in-pos: e + 1 ;-- skip ] ] @@ -946,7 +949,7 @@ lexer: context [ s: s + 1 cell: alloc-slot state word/make-at symbol/make-alt-utf8 s as-integer e - s cell - cell/header: type + set-type cell type state/in-pos: e ;-- reset the input position to delimiter byte ] @@ -957,7 +960,7 @@ lexer: context [ assert e/1 = #"%" scan-float state s e flags fl: as red-float! state/tail - 1 - fl/header: TYPE_PERCENT + set-type as cell! fl TYPE_PERCENT fl/value: fl/value / 100.0 state/in-pos: e + 1 ;-- skip ending delimiter @@ -1010,7 +1013,7 @@ lexer: context [ ][ err: 0 fl: as red-float! alloc-slot state - fl/header: TYPE_FLOAT + set-type as cell! fl TYPE_FLOAT fl/value: red-dtoa/string-to-float s e :err if err <> 0 [throw LEX_ERROR] state/in-pos: e ;-- reset the input position to delimiter byte @@ -1043,7 +1046,7 @@ lexer: context [ ] pos: pos + 1 ;-- last number tp/pos: as byte! i - cell/header: TYPE_TUPLE or (pos << 19) + cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) state/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1204,6 +1207,7 @@ lexer: context [ state [integer!] flags [integer!] line [integer!] + mark [integer!] offset [integer!] s [series!] term? [logic!] @@ -1216,6 +1220,7 @@ lexer: context [ state: lex/entry p: lex/in-pos start: p + mark: line offset: 0 loop as-integer lex/in-end - p [ @@ -1240,6 +1245,8 @@ lexer: context [ state: as-integer transitions/index ] lex/in-pos: p + lex/line: line + lex/nline: line - mark index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index From d90ee67e268b4d853b34b2d6e6b51f9b9be2d60f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 23 Oct 2019 20:55:07 +0200 Subject: [PATCH 0313/3432] FEAT: preliminary work on a date loading FSM definition. --- docs/lexer/lexer-states.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 10faedf7cc..be654a6b10 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -321,6 +321,38 @@ S_PATH->not(delimit6)->S_PATH_WORD->not(delimit5)->S_PATH_WORD \->","|"#"|"%"->T_ERROR +=== Date FSM === + +sep: / | - +letter: a-z, A-Z + +S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->sep->F_DT_YEARL + \ \ \->sep->F_DT_YEARL + \ \->sep->F_DT_DAYL + \->sep->F_DT_DAYL + +F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH + \ \->sep->F_DT_YMONTH + \->letter->S_DT_YMON->letter->S_DT_YMON + \->sep->F_DT_YMONTH + +F_DT_YMONTH->digit->S_DT_YMD->digit->S_DT_YMDD->sep|eof->F_DT_YMDAY + \->sep|eof->F_DT_YMDAY + +F_DT_DAYL-->digit->S_DT_DM->digit->S_DT_DMM->sep->F_DT_DMONTH + \ \->sep->F_DT_DMONTH + \->letter->S_DT_DMON->letter->S_DT_DMON + \->sep->F_DT_DMONTH + +F_DT_DMONTH->digit->S_DT_DMY->digit->S_DT_DMYY->digit->S_DT_DMYYY->digit->S_DT_DMYYYY->sep|eof->F_DT_DMYEAR + \ \ \->sep|eof->F_DT_DMYEAR + \ \->sep|eof->F_DT_DMYEAR + \->sep|eof->F_DT_DMYEAR + + +F_DT_YMDAY->"/"|"T"->S_TM_ + + === Binary16 FSM === From 84e24c519a2b3f9a2077dba31769d4ddaa9b5cd4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 23 Oct 2019 22:46:02 +0200 Subject: [PATCH 0314/3432] FEAT: almost completed date! parsing FSM. --- docs/lexer/lexer-states.txt | 87 +++++++++++++++++++++++++++++++++---- runtime/datatypes/date.reds | 2 +- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index be654a6b10..16932df351 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -323,18 +323,71 @@ S_PATH->not(delimit6)->S_PATH_WORD->not(delimit5)->S_PATH_WORD === Date FSM === +S_DT_START +S_DT_D +S_DT_DD +S_DT_YYY +F_DT_YEARL +F_DT_DAYL +S_DT_YM +S_DT_YMM +F_DT_YMONTH +F_DT_YMONTH +S_DT_YMON +S_DT_YMD +S_DT_YMDD +F_DT_YMDAY +S_DT_DM +S_DT_DMM +F_DT_DMONTH +S_DT_DMON +S_DT_DMY +S_DT_DMYY +S_DT_DMYYY +S_DT_DMYYYY +F_DT_DMYEAR +F_DT_YMDAY +S_TM_START +S_TM_H +F_TM_HH +F_TM_HH +S_TM_M +F_TM_MM +S_TM_S +F_TM_SS +S_TM_N +F_TM_NNN +S_TZ_START +S_TZ_H +F_TZ_HH +S_TZ_M +F_TZ_MM + + sep: / | - letter: a-z, A-Z +sign: + | - -S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->sep->F_DT_YEARL - \ \ \->sep->F_DT_YEARL - \ \->sep->F_DT_DAYL - \->sep->F_DT_DAYL +S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->"/"->F_DT_YEARL + \ \ \ \->"-"->F_DT_YEAR2 + \ \ \->sep->F_DT_YEARL + \ \->sep->F_DT_DAYL + \->sep->F_DT_DAYL F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH - \ \->sep->F_DT_YMONTH - \->letter->S_DT_YMON->letter->S_DT_YMON - \->sep->F_DT_YMONTH + \ \ \->digit->F_DT_DDD + \ \->sep->F_DT_YMONTH + \->letter->S_DT_YMON->letter->S_DT_YMON + \->sep->F_DT_YMONTH + +F_DT_YEARL2->digit->S_DT_YM + \->letter->S_DT_YMON + \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->F_DT_WEEK + +F_DT_WEEK + +F_DT_DDD + F_DT_YMONTH->digit->S_DT_YMD->digit->S_DT_YMDD->sep|eof->F_DT_YMDAY \->sep|eof->F_DT_YMDAY @@ -350,7 +403,25 @@ F_DT_DMONTH->digit->S_DT_DMY->digit->S_DT_DMYY->digit->S_DT_DMYYY->digit->S_DT_D \->sep|eof->F_DT_DMYEAR -F_DT_YMDAY->"/"|"T"->S_TM_ +F_DT_YMDAY->"/"|"T"->S_TM_START + +S_TM_START->digit->S_TM_H->digit->F_TM_HH->":"->F_TM_HH +F_TM_HH->digit->S_TM_M->digit->F_TM_MM->":"->F_TM_MM +F_TM_MM->digit->S_TM_S->digit->F_TM_SS->":"->F_TM_SS + +F_TM_SS->"."->S_TM_N->digit->S_TM_N + \ \->"Z"|eof->F_TM_NNN + \ + \->sign->S_TZ_START + +F_TM_NNN->sign->S_TZ_START + +S_TZ_START->digit->S_TZ_H->digit->F_TZ_HH->":"->F_TZ_HH + \->":"|eof->F_TZ_HH + +F_TZ_HH->digit->S_TZ_M->digit->F_TZ_MM + \->eof->F_TZ_MM + === Binary16 FSM === diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 803e6bbf73..a54f97691d 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -481,7 +481,7 @@ date: context [ ] ] - set-all: func[ + set-all: func [ dt [red-date!] year [integer!] month [integer!] From bfbcb5035e4d78f4ebe27816977ae126e2c32823 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 22 Oct 2019 12:12:00 +0800 Subject: [PATCH 0315/3432] FEAT: code refactoring for font and draw --- modules/view/backends/gtk3/comdlgs.reds | 36 +- modules/view/backends/gtk3/draw.reds | 235 ++--- modules/view/backends/gtk3/font.reds | 1128 +++++++++------------- modules/view/backends/gtk3/gtk.reds | 103 +- modules/view/backends/gtk3/gui.reds | 142 +-- modules/view/backends/gtk3/handlers.reds | 79 +- modules/view/backends/gtk3/para.reds | 4 +- modules/view/backends/gtk3/text-box.reds | 191 ++-- runtime/definitions.reds | 17 +- 9 files changed, 805 insertions(+), 1130 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 619ac58696..068a6e6a12 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -36,7 +36,16 @@ _request-file: func [ ret [red-value!] ][ ret: as red-value! none-value - widget: gtk_file_chooser_dialog_new ["FileChooserDialog" null either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] "Cancel" GTK_RESPONSE_CANCEL "Open" GTK_RESPONSE_ACCEPT null] + widget: gtk_file_chooser_dialog_new [ + "FileChooserDialog" + null + either dir? [GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER][GTK_FILE_CHOOSER_ACTION_OPEN] + "Cancel" + GTK_RESPONSE_CANCEL + "Open" + GTK_RESPONSE_ACCEPT + null + ] gobj_signal_connect(widget "file-activated" :request-file-double-clicked null) unless null? main-window [gtk_window_set_transient_for widget main-window] resp: gtk_dialog_run widget @@ -81,33 +90,29 @@ OS-request-font: func [ return: [red-object!] /local widget [handle!] - fd [handle!] + fd [handle!] + resp [integer!] + cstr [c-string!] + size [integer!] values [red-value!] + str [red-string!] style [red-block!] - size [integer!] - cstr [c-string!] - str [red-string!] - manager [integer!] - trait [integer!] bold? [logic!] - resp [integer!] - fd-sel [handle!] ][ widget: gtk_font_chooser_dialog_new "Font" null - if all[TYPE_OF(selected) = TYPE_OBJECT][ - fd-sel: get-font-handle selected 0 - ;; DEBUG: print ["fd-sel: " pango_font_description_get_family fd-sel " " pango_font_description_get_size fd-sel lf] - gtk_font_chooser_set_font_desc widget fd-sel + if TYPE_OF(selected) = TYPE_OBJECT [ + fd: create-pango-font selected + gtk_font_chooser_set_font_desc widget fd + free-pango-font fd ] resp: gtk_dialog_run widget - ;; print ["resp: " resp lf] either resp = -5 [ fd: gtk_font_chooser_get_font_desc widget cstr: pango_font_description_get_family fd size: length? cstr values: object/get-values font str: string/make-at values + FONT_OBJ_NAME size Latin1 - unicode/load-utf8-stream cstr size str null + unicode/load-utf8-stream cstr size str null size: pango_font_description_get_size fd integer/make-at values + FONT_OBJ_SIZE size / PANGO_SCALE @@ -127,7 +132,6 @@ OS-request-font: func [ word/make-at _italic as red-value! style ] ] - set-font-handle font fd ][ font/header: TYPE_NONE ] diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index fdb6e4402d..da1e98c671 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -14,6 +14,80 @@ Red/System [ draw-state!: alias struct! [mat [handle!]] +make-pango-cairo-font: func [ + dc [draw-ctx!] + font [red-object!] + /local + values [red-value!] + value [red-value!] + quality [integer!] + bool [red-logic!] + word [red-word!] +][ + free-pango-cairo-font dc + dc/font-attrs: create-pango-attrs null font + dc/font-opts: cairo_font_options_create + dc/layout: pango_cairo_create_layout dc/raw + pango_layout_set_attributes dc/layout dc/font-attrs + + values: object/get-values font + value: values + FONT_OBJ_ANTI-ALIAS? + quality: switch TYPE_OF(value) [ + TYPE_LOGIC [ + bool: as red-logic! value + either bool/value [ + CAIRO_ANTIALIAS_SUBPIXEL + ][ + CAIRO_ANTIALIAS_NONE + ] + ] + TYPE_WORD [ + word: as red-word! value + either ClearType = symbol/resolve word/symbol [ + CAIRO_ANTIALIAS_BEST + ][ + CAIRO_ANTIALIAS_NONE + ] + ] + default [CAIRO_ANTIALIAS_DEFAULT] + ] + cairo_font_options_set_antialias dc/font-opts quality +] + +free-pango-cairo-font: func [ + dc [draw-ctx!] +][ + unless null? dc/font-attrs [ + pango_attr_list_unref dc/font-attrs + dc/font-attrs: null + ] + unless null? dc/font-opts [ + cairo_font_options_destroy dc/font-opts + dc/font-opts: null + ] + unless null? dc/layout [ + g_object_unref dc/layout + dc/layout: null + ] +] + + +pango-cairo-set-text: func [ + dc [draw-ctx!] + text [c-string!] +][ + pango-layout-set-text dc/layout text dc/font-attrs +] + +pango-layout-set-text: func [ + layout [handle!] + text [c-string!] + attrs [handle!] +][ + pango_layout_set_text layout text -1 + pango_layout_set_attributes layout attrs +] + set-source-color: func [ cr [handle!] color [integer!] @@ -52,11 +126,9 @@ init-draw-ctx: func [ ctx/brush?: no ctx/pattern: null - ctx/font-desc: null ;default-font - ctx/layout: null ; make-pango-cairo-layout cr ctx/font-desc + ctx/font-attrs: null + ctx/layout: null ctx/font-opts: null - ctx/font-underline?: no - ctx/font-strike?: no ] draw-begin: func [ @@ -433,134 +505,69 @@ OS-draw-font: func [ dc [draw-ctx!] font [red-object!] ][ - ; either pango-font? [ - make-pango-cairo-font dc font - ; ][ - ; make-cairo-draw-font dc font - ; ] + make-pango-cairo-font dc font ] draw-text-at: func [ - dc [draw-ctx!] - text [red-string!] - color [integer!] - x [integer!] - y [integer!] + cr [handle!] + text [red-string!] + attrs [handle!] + opts [handle!] + x [integer!] + y [integer!] /local - len [integer!] + len [integer!] str [c-string!] - ctx [handle!] - pl [handle!] - width [integer!] - height [integer!] - size [integer!] + layout [handle!] ][ - ctx: dc/raw - + cairo_save cr + cairo_move_to cr as-float x as-float y len: -1 str: unicode/to-utf8 text :len - ;; print ["draw-text-at: " str " at " x "x" y lf] - ; either pango-font? [ - ;; print ["draw-text-at: dc/layout: " dc/layout lf] - if null? dc/layout [ - dc/font-desc: CREATE-DEFAULT-FONT - dc/layout: make-pango-cairo-layout ctx dc/font-desc - ] - ;pango-cairo-set-text dc str - pango-layout-context-set-text dc/layout dc str - ;; print ["pango-cairo-set-text: " dc " " str lf] - set-source-color ctx color - ;; print ["set-source-color: " ctx " " color lf] - - pango_cairo_update_layout ctx dc/layout - - size: 0 - size: pango_font_description_get_size dc/font-desc - ;; DEBUG: print ["pango_font_description_get_size: dc/font-desc: " dc/font-desc " size: " size lf] - cairo_move_to ctx as-float x - (as-float y) + ((as-float size) / PANGO_SCALE) - pl: pango_layout_get_line_readonly dc/layout 0 - pango_cairo_show_layout_line ctx pl - - ;pango_cairo_show_layout ctx dc/layout - - do-paint dc - + layout: pango_cairo_create_layout cr + pango_layout_set_text layout str -1 + pango_layout_set_attributes layout attrs + pango_cairo_context_set_font_options layout opts + pango_cairo_update_layout cr layout + pango_cairo_show_layout cr layout + g_object_unref layout + cairo_restore cr ] -draw-text-box-lines: func [ - dc [draw-ctx!] - line [c-string!] - pos [red-pair!] - size [red-pair!] - tbox [red-object!] - /local - lc [layout-ctx!] - ctx [handle!] - clr [integer!] - pl [handle!] - width [integer!] - height [integer!] - sizef [float!] - gstr [GString!] - irect [tagRECT value] - lrect [tagRECT value] -][ - ctx: dc/raw - - clr: either null? dc [0][ - ;;TODO: objc_msgSend [dc/font-attrs sel_getUid "objectForKey:" NSForegroundColorAttributeName] - dc/font-color - ] - - if TYPE_OF(tbox) <> TYPE_OBJECT [exit] - - lc: as layout-ctx! OS-text-box-layout tbox as int-ptr! dc clr yes - unless null? lc/layout [ - set-source-color ctx clr - ;; DEBUG: print ["set-source-color: " ctx " " clr lf] - - cairo_move_to ctx as-float pos/x (as-float pos/y) ; + sizef - pango_cairo_show_layout ctx lc/layout - - free-pango-cairo-font dc - - ;; DEBUG: print ["free pango" lf] - do-paint dc - ] -] - - draw-text-box: func [ - dc [draw-ctx!] - pos [red-pair!] - tbox [red-object!] - catch? [logic!] + dc [draw-ctx!] + pos [red-pair!] + tbox [red-object!] + catch? [logic!] /local values [red-value!] text [red-string!] - lc [layout-ctx!] - len [integer!] - str [c-string!] - size [red-pair!] + state [red-block!] + layout? [logic!] + bool [red-logic!] + clr [integer!] + int [red-integer!] + layout [handle!] ][ - ;; DEBUG: print ["draw-text-box: " tbox lf] values: object/get-values tbox text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] - size: as red-pair! values + FACE_OBJ_SIZE - - ;; DEBUG: print ["pos : " pos/x "x" pos/y " size: " size/x "x" size/y lf] - - len: -1 - str: unicode/to-utf8 text :len - ; default font-desc that can be overloaded in OS-text-box-layout called inside draw-text-box-lines - dc/font-desc: CREATE-DEFAULT-FONT - ;;TORM: dc/layout: make-pango-cairo-layout dc/raw dc/font-desc + state: as red-block! values + FACE_OBJ_EXT3 + layout?: yes + if TYPE_OF(state) = TYPE_BLOCK [ + bool: as red-logic! (block/rs-tail state) - 1 + layout?: bool/value + ] + if layout? [ + clr: 0 ;-- TBD + OS-text-box-layout tbox null clr catch? + ] - ;; DEBUG: print ["draw-text-box text: " str " dc/font-desc: " dc/font-desc lf] - draw-text-box-lines dc str pos size tbox + int: as red-integer! block/rs-head state + layout: as handle! int/value + cairo_move_to dc/raw as-float pos/x as-float pos/y + pango_cairo_show_layout dc/raw layout ] OS-draw-text: func [ @@ -571,13 +578,11 @@ OS-draw-text: func [ return: [logic!] ][ either TYPE_OF(text) = TYPE_STRING [ - draw-text-at dc text dc/font-color pos/x pos/y + draw-text-at dc/raw text dc/font-attrs dc/font-opts pos/x pos/y ][ - ;; DEBUG: print ["OS-draw-text: " pos/x "x" pos/y lf] draw-text-box dc pos as red-object! text catch? ] - ;; DEBUG: print ["OS-draw-text end" lf] true ] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index e9fa90a048..fbcbd6bd21 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -1,809 +1,645 @@ Red/System [ Title: "GTK3 fonts management" - Author: "Qingtian Xie, Thiago Dourado de Andrade, RCqls" + Author: "Qingtian Xie, Thiago Dourado de Andrade, RCqls, bitbegin" File: %font.reds Tabs: 4 - Rights: "Copyright (C) 2016 Qingtian Xie. All rights reserved." + Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." License: { Distributed under the Boost Software License, Version 1.0. See https://github.com/red/red/blob/master/BSL-License.txt } ] +default-attrs: as handle! 0 +default-css: as GString! 0 -add-to-string: func [ - string [c-string!] - format [c-string!] - value [handle!] - return: [c-string!] +set-default-font: func [ + name [c-string!] + size [integer!] /local - temp [c-string!] + attr [PangoAttribute!] ][ - temp: g_strdup_printf [format string value] - g_free as handle! string - temp + unless null? default-attrs [ + pango_attr_list_unref default-attrs + ] + default-attrs: pango_attr_list_new + attr: pango_attr_family_new name + pango_attr_list_insert default-attrs attr + attr: pango_attr_size_new PANGO_SCALE * size + pango_attr_list_insert default-attrs attr + + unless null? default-css [ + g_string_free default-css true + ] + default-css: g_string_sized_new 64 + g_string_append default-css "* {" + g_string_append_printf [default-css { font-family: "%s";} name] + g_string_append_printf [default-css { font-size: %dpt;} size] + g_string_append default-css "}" ] -to-css-rgba: func [ - color [red-tuple!] ;-- needs to be a valid color tuple - return: [c-string!] ;-- rgba(r, g, b, a) format - Should be cleaned with g_free +set-label-attrs: func [ + label [handle!] + font [red-object!] + hfont [handle!] /local - size [integer!] - r [integer!] - g [integer!] - b [integer!] - a [float!] - rgba [c-string!] - alpha [c-string!] + values [red-value!] + int [red-integer!] + angle [integer!] ][ - size: TUPLE_SIZE?(color) - - r: color/array1 and FFh - g: (color/array1 >> 8) and FFh - b: (color/array1 >> 16) and FFh - a: 1.0 + unless null? font [ + values: object/get-values font - if size = 4 [ - a: (as-float 255 - color/array1 >>> 24) / 255.0 + int: as red-integer! values + FONT_OBJ_ANGLE + angle: either TYPE_OF(int) = TYPE_INTEGER [int/value][0] + gtk_label_set_angle label as float! angle ] - alpha: as c-string! allocate G_ASCII_DTOSTR_BUF_SIZE - g_ascii_dtostr alpha G_ASCII_DTOSTR_BUF_SIZE a - - rgba: g_strdup_printf ["rgba(%d, %d, %d, %s)" r g b alpha] - - free as byte-ptr! alpha - - rgba + gtk_label_set_attributes label hfont ] - -;; The idea: font-handle (which is required in view.red) is the css string which is (the only object) not related to the widget - -make-font: func [ - face [red-object!] - font [red-object!] - return: [handle!] +;-- create pango attributes +;-- `angle` need to be set on label +;-- `anti-alias` need to be set by cairo +create-pango-attrs: func [ + face [red-object!] + font [red-object!] + return: [handle!] /local + list [handle!] + attr [PangoAttribute!] values [red-value!] + str [red-string!] + name [c-string!] + len [integer!] + int [red-integer!] + size [integer!] + color [red-tuple!] + rgb [integer!] + alpha? [integer!] + r [integer!] + g [integer!] + b [integer!] + a [integer!] + style [red-word!] blk [red-block!] - css [c-string!] - hFont [handle!] + sym [integer!] ][ - ; no more deal with different styles but only font via pango_font_description (excluding color, underline, strike) - ;; DEBUG: print ["make-font face " face " " font lf] - hFont: font-description font - ;; DEBUG: print ["make-font font-description: " hFont lf] - set-font-handle font hFont - ;; DEBUG: print ["make-font set-font-handle: " font " " hFont lf] + list: pango_attr_list_new + values: object/get-values font - if face <> null [ - blk: block/make-at as red-block! values + FONT_OBJ_PARENT 4 - block/rs-append blk as red-value! face + str: as red-string! values + FONT_OBJ_NAME + name: either TYPE_OF(str) = TYPE_STRING [ + len: -1 + unicode/to-utf8 str :len + ][default-font-name] + attr: pango_attr_family_new name + pango_attr_list_insert list attr + + int: as red-integer! values + FONT_OBJ_SIZE + size: either TYPE_OF(int) <> TYPE_INTEGER [default-font-size][ + int/value + ] + attr: pango_attr_size_new PANGO_SCALE * size + pango_attr_list_insert list attr + + color: as red-tuple! values + FONT_OBJ_COLOR + if TYPE_OF(color) = TYPE_TUPLE [ + alpha?: 0 + rgb: get-color-int color :alpha? + r: 0 g: 0 b: 0 a: 0 + color-u8-to-u16 rgb :r :g :b :a + attr: pango_attr_foreground_new r g b + pango_attr_list_insert list attr + attr: pango_attr_foreground_alpha_new a + pango_attr_list_insert list attr ] - ;; DEBUG: print ["make-font end font-description: " hFont lf] - - hFont -] - -face-font?: func [ - face [red-object!] - return: [red-object!] -][ - as red-object! (object/get-values face) + FACE_OBJ_FONT -] - -;; IMPORTANT: Do not remove idx below (even if unused) since it is used in platform.red with this signature -get-font-handle: func [ - font [red-object!] - idx [integer!] - return: [handle!] - /local - state [red-block!] - int [red-integer!] -][ - state: as red-block! (object/get-values font) + FONT_OBJ_STATE - if TYPE_OF(state) = TYPE_BLOCK [ - int: as red-integer! block/rs-head state - if TYPE_OF(int) = TYPE_HANDLE [ - return as handle! int/value + unless null? face [ + color: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR + if TYPE_OF(color) = TYPE_TUPLE [ + alpha?: 0 + rgb: get-color-int color :alpha? + r: 0 g: 0 b: 0 a: 0 + color-u8-to-u16 rgb :r :g :b :a + attr: pango_attr_background_new r g b + pango_attr_list_insert list attr + attr: pango_attr_background_alpha_new a + pango_attr_list_insert list attr ] ] - null -] -get-font: func [ - face [red-object!] - font [red-object!] - return: [handle!] - /local - hFont [handle!] -][ - if TYPE_OF(font) <> TYPE_OBJECT [return CREATE-DEFAULT-FONT] - hFont: get-font-handle font 0 - if null? hFont [hFont: make-font face font] - hFont -] + style: as red-word! values + FONT_OBJ_STYLE + len: switch TYPE_OF(style) [ + TYPE_BLOCK [ + blk: as red-block! style + style: as red-word! block/rs-head blk + len: block/rs-length? blk + ] + TYPE_WORD [1] + default [0] + ] -free-font-handle: func [ - hFont [handle!] -][ - ;; DEBUG: print ["free-font-handle " hFont lf] - pango_font_description_free hFont - ;; DEBUG: print ["free-font-handle end " hFont lf] + unless zero? len [ + loop len [ + sym: symbol/resolve style/symbol + case [ + sym = _bold [ + attr: pango_attr_weight_new PANGO_WEIGHT_BOLD + pango_attr_list_insert list attr + ] + sym = _italic [ + attr: pango_attr_style_new PANGO_STYLE_ITALIC + pango_attr_list_insert list attr + ] + sym = _underline [ + attr: pango_attr_underline_new PANGO_UNDERLINE_SINGLE + pango_attr_list_insert list attr + ] + sym = _strike [ + attr: pango_attr_strikethrough_new true + pango_attr_list_insert list attr + ] + true [0] + ] + style: style + 1 + ] + ] + list ] -free-font: func [ - font [red-object!] - /local - state [red-block!] - hFont [handle!] +free-pango-attrs: func [ + attrs [handle!] ][ - ;; DEBUG: print ["free-font begin" lf] - hFont: get-font-handle font 0 - unless null? hFont [ - state: as red-block! (object/get-values font) + FONT_OBJ_STATE - state/header: TYPE_NONE - free-font-handle hFont - ] - ;; DEBUG: print ["free-font end" lf] + pango_attr_list_unref attrs ] -set-font-handle: func [ - font [red-object!] - hFont [handle!] +make-attrs: func [ + face [red-object!] + font [red-object!] + return: [handle!] /local + list [handle!] values [red-value!] blk [red-block!] - state [red-block!] int [red-integer!] - hFontP [handle!] ][ - ; release previous hFont first - ;; DEBUG: print ["set-font-handle " font " " hFont lf] - hFontP: get-font-handle font 0 - ;; DEBUG: print ["set-font-handle get " hFontP lf] - unless null? hFontP [ - free-font-handle hFontP - ] - + list: create-pango-attrs face font values: object/get-values font - blk: as red-block! values + FONT_OBJ_STATE either TYPE_OF(blk) <> TYPE_BLOCK [ - block/make-at blk 2 - handle/make-in blk as-integer hFont + block/make-at blk 3 + handle/make-in blk as-integer list + none/make-in blk + none/make-in blk ][ int: as red-integer! block/rs-head blk int/header: TYPE_HANDLE - int/value: as-integer hFont + int/value: as-integer list ] -] - -update-font: func [ - font [red-object!] - flag [integer!] -][ - ;; DEBUG: print ["update-font " font lf] - switch flag [ - FONT_OBJ_NAME - FONT_OBJ_SIZE - FONT_OBJ_STYLE - FONT_OBJ_ANGLE - FONT_OBJ_ANTI-ALIAS? [ - make-font null font - ] - default [0] + blk: as red-block! values + FONT_OBJ_PARENT + if all [face <> null TYPE_OF(blk) <> TYPE_BLOCK][ + blk: block/make-at as red-block! values + FONT_OBJ_PARENT 4 + block/rs-append blk as red-value! face ] + list ] -;convert font to pango_font_description (used for get-text-size) -font-description: func [ - font [red-object!] - return: [handle!] +;-- create css styles +;-- TBD: support `angle` +;-- `anti-alias` need to be set by cairo +create-css: func [ + face [red-object!] + font [red-object!] + return: [GString!] /local - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - fsize [integer!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - fweight [integer!] - fstyle [integer!] - + css [GString!] + values [red-value!] + str [red-string!] + name [c-string!] + len [integer!] + int [red-integer!] + size [integer!] + color [red-tuple!] + rgb [integer!] + alpha? [integer!] + r [integer!] + g [integer!] + b [integer!] + a [float!] + style [red-word!] + blk [red-block!] + sym [integer!] ][ - ; default font if font is none. TODO: better than gtk-font would be to get the default font system or from red side - if TYPE_OF(font) = TYPE_NONE [return CREATE-DEFAULT-FONT] + css: g_string_sized_new 64 + g_string_append css "* {" + values: object/get-values font - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - - ; font name - either TYPE_OF(str) = TYPE_STRING [ + + str: as red-string! values + FONT_OBJ_NAME + name: either TYPE_OF(str) = TYPE_STRING [ len: -1 - name: unicode/to-utf8 str :len - ][name: default-font-name] + unicode/to-utf8 str :len + ][default-font-name] + g_string_append_printf [css { font-family: "%s";} name] - ; font size - fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][default-font-size] - ;; DEBUG: print ["font-description: fsize -> " fsize lf] + int: as red-integer! values + FONT_OBJ_SIZE + size: either TYPE_OF(int) <> TYPE_INTEGER [default-font-size][ + int/value + ] + g_string_append_printf [css { font-size: %dpt;} size] + + color: as red-tuple! values + FONT_OBJ_COLOR + if TYPE_OF(color) = TYPE_TUPLE [ + alpha?: 0 + rgb: get-color-int color :alpha? + b: rgb >> 18 and FFh + g: rgb >> 16 and FFh + r: rgb and FFh + a: 1.0 + if alpha? = 1 [ + a: (as float! 255 - (rgb >>> 24)) / 255.0 + ] + g_string_append_printf [css { color: rgba(%d, %d, %d, %.1f);} r g b a] + ] + + ;-- ? GTK3 warnings + ;int: as red-integer! values + FONT_OBJ_ANGLE + ;if TYPE_OF(int) = TYPE_INTEGER [ + ; g_string_append_printf [css { font-style: oblique %ddeg;} int/value] + ;] - ; font style and weight + style: as red-word! values + FONT_OBJ_STYLE len: switch TYPE_OF(style) [ TYPE_BLOCK [ blk: as red-block! style style: as red-word! block/rs-head blk - block/rs-length? blk + len: block/rs-length? blk ] - TYPE_WORD [1] - default [0] + TYPE_WORD [1] + default [0] ] - fstyle: PANGO_STYLE_NORMAL - fweight: PANGO_WEIGHT_NORMAL unless zero? len [ loop len [ sym: symbol/resolve style/symbol case [ - sym = _bold [fweight: PANGO_WEIGHT_BOLD] - sym = _italic [fstyle: PANGO_STYLE_ITALIC] - sym = _underline [] - sym = _strike [] - true [] + sym = _bold [ + g_string_append css " font-weight: bold;" + ] + sym = _italic [ + g_string_append css " font-style: italic;" + ] + sym = _underline [ + g_string_append css " text-decoration: underline;" + ] + sym = _strike [ + g_string_append css " text-decoration: line-through;" + ] + true [0] ] style: style + 1 ] ] - font-description-create name fsize fweight fstyle + unless null? face [ + color: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR + if TYPE_OF(color) = TYPE_TUPLE [ + alpha?: 0 + rgb: get-color-int color :alpha? + b: rgb >> 18 and FFh + g: rgb >> 16 and FFh + r: rgb and FFh + a: 1.0 + if alpha? = 1 [ + a: (as float! 255 - (rgb >>> 24)) / 255.0 + ] + g_string_append_printf [css { background-color: rgba(%d, %d, %d, %.1f);} r g b a] + ] + ] + + g_string_append css "}" + css ] -font-description-create: func [ - fname [c-string!] - fsize [integer!] - fweight [integer!] - fstyle [integer!] - return: [handle!] - /local - fd [handle!] - ;css [c-string!] +free-css: func [ + css [GString!] ][ - fd: pango_font_description_new - - pango_font_description_set_family fd fname - pango_font_description_set_size fd fsize * PANGO_SCALE - - pango_font_description_set_weight fd fweight - pango_font_description_set_style fd fstyle - pango_font_description_set_stretch fd PANGO_STRETCH_NORMAL - pango_font_description_set_variant fd PANGO_VARIANT_NORMAL - - ;; DOES NOT WORK AS EXPECTED: - ;; css: pango_font_description_to_string fd - ;; print ["font description css: " css lf] - - fd + g_string_free css true ] -;; Styles initiated by Thiago Dourado de Andrade (used in change-font) -; Here, style provider is used as font provider -make-styles-provider: func [ - widget [handle!] +make-css: func [ + face [red-object!] + font [red-object!] + return: [GString!] /local - style [handle!] - provider [handle!] + css [GString!] + values [red-value!] + blk [red-block!] + int [red-integer!] ][ - provider: gtk_css_provider_new - style: gtk_widget_get_style_context widget - - gtk_style_context_add_provider style provider GTK_STYLE_PROVIDER_PRIORITY_USER + css: create-css face font + values: object/get-values font - g_object_set_qdata widget gtk-style-id provider -] + blk: as red-block! values + FONT_OBJ_STATE + either TYPE_OF(blk) <> TYPE_BLOCK [ + block/make-at blk 3 + none/make-in blk + handle/make-in blk as-integer css + none/make-in blk + ][ + int: (as red-integer! block/rs-head blk) + 1 + int/header: TYPE_HANDLE + int/value: as-integer css + ] -get-styles-provider: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget gtk-style-id + blk: as red-block! values + FONT_OBJ_PARENT + if all [face <> null TYPE_OF(blk) <> TYPE_BLOCK][ + blk: block/make-at as red-block! values + FONT_OBJ_PARENT 4 + block/rs-append blk as red-value! face + ] + css ] -css-styles: func [ - face [red-object!] - font [red-object!] - type [integer!] - return: [c-string!] +create-pango-font: func [ + font [red-object!] + return: [handle!] /local - values [red-value!] - blk [red-block!] - style [red-word!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - css [c-string!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] + hFont [handle!] + values [red-value!] + str [red-string!] + name [c-string!] + len [integer!] + int [red-integer!] + size [integer!] + style [red-word!] + blk [red-block!] + sym [integer!] ][ - css: g_strdup_printf ["* {"] + hFont: pango_font_description_new - if TYPE_OF(font) = TYPE_OBJECT [ + either TYPE_OF(font) <> TYPE_OBJECT [ + pango_font_description_set_family hFont default-font-name + pango_font_description_set_size hFont PANGO_SCALE * default-font-size + ][ values: object/get-values font - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - if TYPE_OF(str) = TYPE_STRING [ + str: as red-string! values + FONT_OBJ_NAME + name: either TYPE_OF(str) = TYPE_STRING [ len: -1 - name: unicode/to-utf8 str :len - css: g_strdup_printf [{%s font-family: "%s";} css name] - ] + unicode/to-utf8 str :len + ][default-font-name] + pango_font_description_set_family hFont name - if TYPE_OF(size) = TYPE_INTEGER [ - css: add-to-string css "%s font-size: %dpt;" as handle! size/value + int: as red-integer! values + FONT_OBJ_SIZE + size: either TYPE_OF(int) <> TYPE_INTEGER [default-font-size][ + int/value ] + pango_font_description_set_size hFont PANGO_SCALE * size + style: as red-word! values + FONT_OBJ_STYLE len: switch TYPE_OF(style) [ TYPE_BLOCK [ blk: as red-block! style style: as red-word! block/rs-head blk - block/rs-length? blk + len: block/rs-length? blk ] - TYPE_WORD [1] - default [0] + TYPE_WORD [1] + default [0] ] unless zero? len [ loop len [ sym: symbol/resolve style/symbol case [ - sym = _bold ["bold" css: g_strdup_printf ["%s font-weight: bold; " css]] - sym = _italic ["italic" css: g_strdup_printf ["%s font-style: italic;" css]] - sym = _underline ["underline" css: g_strdup_printf ["%s text-decoration: underline;" css]] - sym = _strike ["strike" css: g_strdup_printf ["%s text-decoration: line-through;" css]] - true [""] + sym = _bold [ + pango_font_description_set_weight hFont PANGO_WEIGHT_BOLD + ] + sym = _italic [ + pango_font_description_set_style hFont PANGO_STYLE_ITALIC + ] + sym = _underline [ + 0 + ] + sym = _strike [ + 0 + ] + true [0] ] style: style + 1 ] ] - - if TYPE_OF(color) = TYPE_TUPLE [ - rgba: to-css-rgba color - css: add-to-string css "%s color: %s;" as handle! rgba - g_free as handle! rgba - ] - ] - - ;; Further styles from face - ;; DEBUG: print ["css face color " face lf] - unless null? face [ - bgcolor: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR - ;; DEBUG: print ["typeof(bgcolor) " TYPE_OF(bgcolor) " " TYPE_TUPLE lf] - if TYPE_OF(bgcolor) = TYPE_TUPLE [ - rgba: to-css-rgba bgcolor - css: add-to-string css "%s background: %s;" as handle! rgba - g_free as handle! rgba - ] ] - - css: add-to-string css "%s}" null - - case [ - type = button [ - css: g_strdup_printf ["%s button {padding: 0px 0px 0px 0px;margin: 0px 0px 0px 0px;font-variant: small-caps;}" css] - ] - true [0] - ] - - ;; DEBUG: print ["css-styles -> css: " css lf] - - css + hFont ] -apply-css-styles: func [ - widget [handle!] - face [red-object!] - font [red-object!] - type [integer!] - /local - provider [handle!] - css [c-string!] +free-pango-font: func [ + hFont [handle!] ][ - provider: get-styles-provider widget - - ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles - css: "" - css: css-styles face font type - - ;; DEBUG: print ["apply-css-styles ccs: " widget " " css lf] - - unless null? provider [gtk_css_provider_load_from_data provider css -1 null] + pango_font_description_free hFont ] - -css-provider: func [ - path [c-string!] - priority [integer!] - /local - provider [handle!] - display [handle!] - screen [handle!] +make-font: func [ + face [red-object!] + font [red-object!] + return: [handle!] ][ - provider: gtk_css_provider_new - gtk_css_provider_load_from_path provider path null - display: gdk_display_get_default - screen: gdk_display_get_default_screen display - gtk_style_context_add_provider_for_screen screen provider priority - g_object_unref provider + make-css face font + make-attrs face font ] -red-gtk-styles: func [ +get-font-handle: func [ + font [red-object!] + idx [integer!] + return: [handle!] /local - env strarr str - found [logic!] + state [red-block!] + handle [red-handle!] ][ - env: system/env-vars - found: no - until [ - strarr: g_strsplit env/item "=" 2 - str: as c-string! (strarr/1) - if 0 = g_strcmp0 str "RED_GTK_STYLES" [ - str: as c-string! (strarr/2) - css-provider str GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - found: yes + state: as red-block! (object/get-values font) + FONT_OBJ_STATE + if TYPE_OF(state) = TYPE_BLOCK [ + handle: (as red-handle! block/rs-head state) + idx + if TYPE_OF(handle) = TYPE_HANDLE [ + return as handle! handle/value ] - env: env + 1 - g_strfreev strarr - any[found env/item = null] ] + null ] -font-color?: func [ - font [red-object!] - return: [integer!] +get-attrs: func [ + face [red-object!] + font [red-object!] + return: [handle!] /local - values [red-value!] - color [red-tuple!] + hFont [handle!] ][ - values: object/get-values font - color: as red-tuple! values + FONT_OBJ_COLOR - - color/array1 + if TYPE_OF(font) <> TYPE_OBJECT [return default-attrs] + hFont: get-font-handle font 0 + if null? hFont [hFont: make-attrs face font] + hFont ] -; move this to draw-ctx!? (used in draw-text-at) -cairo-font-size: 10.0 ;-- used to find top line - -;; Move honix stuff from draw.reds (OS-draw-font) to switch to pango-cairo -make-cairo-draw-font: func [ - dc [draw-ctx!] - font [red-object!] +get-css: func [ + face [red-object!] + font [red-object!] + return: [GString!] /local - cr [handle!] - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - name [c-string!] - size [red-integer!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - slant [integer!] - weight [integer!] - extents [cairo_font_extents_t!] + css [GString!] ][ - cr: dc/raw - - values: object/get-values font - - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - dc/font-color: color/array1 - - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - name: unicode/to-utf8 str :len - ] - - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk - ] - TYPE_WORD [1] - default [0] - ] - - slant: CAIRO_FONT_SLANT_NORMAL - weight: CAIRO_FONT_WEIGHT_NORMAL + if TYPE_OF(font) <> TYPE_OBJECT [return default-css] + css: as GString! get-font-handle font 1 + if null? css [css: make-css face font] + css +] - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ - sym = _bold [weight: CAIRO_FONT_WEIGHT_BOLD] - sym = _italic [slant: CAIRO_FONT_SLANT_ITALIC] - sym = _underline [] - sym = _strike [] - true [] - ] - style: style + 1 - ] +free-font: func [ + font [red-object!] + /local + state [red-block!] + hFont [handle!] + css [GString!] +][ + if TYPE_OF(font) <> TYPE_OBJECT [exit] + hFont: get-font-handle font 0 + unless null? hFont [ + pango_attr_list_unref hFont ] - - cairo_select_font_face cr name slant weight - - if TYPE_OF(size) = TYPE_INTEGER [ - extents: declare cairo_font_extents_t! - cairo_font_extents cr extents - - cairo-font-size: as-float size/value - cairo_set_font_size cr cairo-font-size * ((extents/ascent + extents/descent) / extents/ascent) - - ; This technique is little more correct for me. - ; This Red example will show the difference: - ; - ; f: make font! [name: "Arial" size: 120] - ; view [base 140x140 draw [font f text 10x10 "A" pen white box 0x10 140x130]] + css: as GString! get-font-handle font 1 + unless null? css [ + g_string_free css true ] + state: as red-block! (object/get-values font) + FONT_OBJ_STATE + state/header: TYPE_NONE ] -make-pango-cairo-font: func [ - dc [draw-ctx!] - font [red-object!] +set-font: func [ + widget [handle!] + face [red-object!] + values [red-value!] /local - cr [handle!] - values [red-value!] - style [red-word!] - blk [red-block!] - len [integer!] - sym [integer!] - str [red-string!] - size [red-integer!] - color [red-tuple!] - bgcolor [red-tuple!] - rgba [c-string!] - slant [integer!] - weight [integer!] - fname [c-string!] - fsize [integer!] - fweight [integer!] - fstyle [integer!] - value [red-value!] - bool [red-logic!] - quality [integer!] + font [red-object!] + hFont [handle!] + css [GString!] + state [red-block!] + handle [red-handle!] + type [red-word!] + sym [integer!] + label [handle!] ][ - cr: dc/raw - - values: object/get-values font - ;name: - str: as red-string! values + FONT_OBJ_NAME - size: as red-integer! values + FONT_OBJ_SIZE - style: as red-word! values + FONT_OBJ_STYLE - ;angle: - color: as red-tuple! values + FONT_OBJ_COLOR - ;anti-alias?: - - ;;;;----- color - dc/font-color: color/array1 - - ;;;------- font description - fname: "Arial" ; @@ to change to default font name - if TYPE_OF(str) = TYPE_STRING [ - len: -1 - fname: unicode/to-utf8 str :len - ] - fsize: either TYPE_OF(size) = TYPE_INTEGER [size/value][16] - len: switch TYPE_OF(style) [ - TYPE_BLOCK [ - blk: as red-block! style - style: as red-word! block/rs-head blk - block/rs-length? blk + font: as red-object! values + FACE_OBJ_FONT + hFont: get-attrs face font + css: get-css face font + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + case [ + sym = text [ + set-label-attrs widget font hFont ] - TYPE_WORD [1] - default [0] - ] - fstyle: PANGO_STYLE_NORMAL - fweight: PANGO_WEIGHT_NORMAL - dc/font-underline?: no - dc/font-strike?: no - unless zero? len [ - loop len [ - sym: symbol/resolve style/symbol - case [ - sym = _bold [fweight: PANGO_WEIGHT_BOLD] - sym = _italic [fstyle: PANGO_STYLE_ITALIC] - sym = _underline [dc/font-underline?: yes] - sym = _strike [dc/font-strike?: yes] - true [] - ] - style: style + 1 + any [ + sym = button + sym = check + sym = radio + ][ + label: gtk_bin_get_child widget + set-label-attrs label font hFont + ] + sym = field [ + gtk_entry_set_attributes widget hFont + ] + sym = group-box [ + label: gtk_frame_get_label_widget widget + set-label-attrs label font hFont + ] + true [ + apply-css-styles widget css ] ] +] - free-pango-cairo-font dc - dc/font-desc: font-description-create fname fsize fweight fstyle - dc/font-opts: cairo_font_options_create - - dc/layout: make-pango-cairo-layout cr dc/font-desc - - - ;anti-alias?: - value: values + FONT_OBJ_ANTI-ALIAS? - - switch TYPE_OF(value) [ - TYPE_LOGIC [ - bool: as red-logic! value - quality: either bool/value [CAIRO_ANTIALIAS_SUBPIXEL][CAIRO_ANTIALIAS_NONE] - ;-- ANTIALIASED_QUALITY - ] - TYPE_WORD [ - style: as red-word! value - either ClearType = symbol/resolve style/symbol [ - quality: CAIRO_ANTIALIAS_BEST - ;-- CLEARTYPE_QUALITY - ][ - quality: CAIRO_ANTIALIAS_NONE - ] - ] - default [quality: CAIRO_ANTIALIAS_DEFAULT] - ;-- DEFAULT_QUALITY +update-font: func [ + font [red-object!] + flag [integer!] +][ + switch flag [ + FONT_OBJ_NAME + FONT_OBJ_SIZE + FONT_OBJ_STYLE + FONT_OBJ_ANGLE + FONT_OBJ_ANTI-ALIAS? [ + free-font font + make-font null font + ] + default [0] ] - cairo_font_options_set_antialias dc/font-opts quality - ] -pango-styled-text?: func [ - text [c-string!] - underline? [logic!] - strike? [logic!] - return: [c-string!] +make-styles-provider: func [ + widget [handle!] /local - mtext [c-string!] - tmp [c-string!] + style [handle!] + prov [handle!] ][ - mtext: g_strdup_printf ["%s" text] - if underline? [ - tmp: g_strdup_printf ["%s" mtext] - g_free as handle! mtext - mtext: tmp - ] - if strike? [ - tmp: g_strdup_printf ["%s" mtext] - g_free as handle! mtext - mtext: tmp - ] - mtext + prov: gtk_css_provider_new + style: gtk_widget_get_style_context widget + + gtk_style_context_add_provider style prov GTK_STYLE_PROVIDER_PRIORITY_USER + g_object_set_qdata widget gtk-style-id prov ] -pango-cairo-set-text: func [ - dc [draw-ctx!] - text [c-string!] - /local - status [logic!] - length [integer!] - attrs-ptr [int-ptr!] - attrs [handle!] - ptext-ptr [int-ptr!] - mtext [c-string!] - ptext [c-string!] - accel [integer!] - error [handle!] +get-styles-provider: func [ + widget [handle!] + return: [handle!] ][ - unless null? dc/layout [ - attrs-ptr: declare int-ptr! - ptext-ptr: declare int-ptr! - mtext: pango-styled-text? text dc/font-underline? dc/font-strike? - ;; DEBUG: print ["pango-cairo-set-text mtext: " mtext lf] - status: pango_parse_markup mtext -1 0 attrs-ptr ptext-ptr null null - attrs: as handle! attrs-ptr/value - ptext: as c-string! ptext-ptr/value - either status [ - pango_layout_set_text dc/layout ptext -1 - unless null? attrs [pango_layout_set_attributes dc/layout attrs] - g_free as handle! mtext - g_free as handle! ptext - ][ - pango_layout_set_text dc/layout text -1 - ] - ] + g_object_get_qdata widget gtk-style-id ] -pango-layout-context-set-text: func [ - layout [handle!] - dc [draw-ctx!] - text [c-string!] +apply-css-styles: func [ + widget [handle!] + css [GString!] /local - status [logic!] - length [integer!] - attrs-ptr [int-ptr!] - attrs [handle!] - ptext-ptr [int-ptr!] - mtext [c-string!] - ptext [c-string!] - accel [integer!] - error [handle!] + prov [handle!] ][ - unless null? layout [ - attrs-ptr: declare int-ptr! - ptext-ptr: declare int-ptr! - mtext: pango-styled-text? text dc/font-underline? dc/font-strike? - ;; DEBUG: print ["pango-cairo-set-text mtext: " mtext lf] - status: pango_parse_markup mtext -1 0 attrs-ptr ptext-ptr null null - attrs: as handle! attrs-ptr/value - ptext: as c-string! ptext-ptr/value - either status [ - pango_layout_set_text layout ptext -1 - unless null? attrs [pango_layout_set_attributes layout attrs] - g_free as handle! mtext - g_free as handle! ptext - ][ - pango_layout_set_text layout text -1 - ] - ] + prov: get-styles-provider widget + gtk_css_provider_load_from_data prov css/str -1 null ] -free-pango-cairo-font: func [ - dc [draw-ctx!] +css-provider: func [ + path [c-string!] + priority [integer!] + /local + prov [handle!] + disp [handle!] + screen [handle!] ][ - ;; DEBUG: print ["free-pango-cairo-layout begin" lf] - unless null? dc/font-desc [ - pango_font_description_free dc/font-desc - dc/font-desc: null - ] - ;; DEBUG: print ["free-pango-cairo-layout font-opts: " dc/font-opts lf] - unless null? dc/font-opts [ - cairo_font_options_destroy dc/font-opts - dc/font-opts: null - ] - ;; DEBUG: print ["free-pango-cairo-layout dc/layout: " dc/layout lf] - unless null? dc/layout [ - g_object_unref dc/layout - dc/layout: null - ] - ;; DEBUG: print ["free-pango-cairo-layout end" lf] + prov: gtk_css_provider_new + gtk_css_provider_load_from_path prov path null + disp: gdk_display_get_default + screen: gdk_display_get_default_screen disp + gtk_style_context_add_provider_for_screen screen prov priority + g_object_unref prov ] -make-pango-cairo-layout: func [ - cr [handle!] - fd [handle!] - return: [handle!] +red-gtk-styles: func [ /local - layout [handle!] + env [str-array!] + strarr [handle!] + str [c-string!] + found [logic!] ][ - ;; DEBUG: print ["make-pango-cairo-layout" lf] - layout: pango_cairo_create_layout cr - unless null? fd [pango_layout_set_font_description layout fd] - ;; DEBUG: print ["make-pango-cairo-layout: " layout lf] - layout -] \ No newline at end of file + env: system/env-vars + found: no + until [ + strarr: g_strsplit env/item "=" 2 + str: as c-string! strarr/1 + if 0 = g_strcmp0 str "RED_GTK_STYLES" [ + str: as c-string! strarr/2 + css-provider str GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + found: yes + ] + env: env + 1 + g_strfreev strarr + any [found env/item = null] + ] +] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index ea552530e9..9cb89abe36 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -21,6 +21,7 @@ Red/System [ #define G_ASCII_DTOSTR_BUF_SIZE 39 + RECT_STRUCT: alias struct! [ left [integer!] top [integer!] @@ -738,21 +739,21 @@ GPtrArray!: alias struct! [ ] g_main_context_pending: "g_main_context_pending" [ context [integer!] - return: [logic!] + return: [logic!] ] g_main_context_is_owner: "g_main_context_is_owner" [ context [integer!] - return: [logic!] + return: [logic!] ] g_main_current_source: "g_main_current_source" [ return: [handle!] ] g_list_length: "g_list_length" [ - list [int-ptr!] + list [int-ptr!] return: [integer!] ] g_list_free: "g_list_free" [ - list [int-ptr!] + list [int-ptr!] ] g_list_nth_data: "g_list_nth_data" [ list [handle!] @@ -762,20 +763,20 @@ GPtrArray!: alias struct! [ g_list_append: "g_list_append" [ list [handle!] data [handle!] - return: [handle!] + return: [handle!] ] g_list_prepend: "g_list_prepend" [ list [handle!] data [handle!] - return: [handle!] + return: [handle!] ] g_list_first: "g_list_first" [ list [handle!] - return: [handle!] + return: [handle!] ] g_list_last: "g_list_last" [ list [handle!] - return: [handle!] + return: [handle!] ] g_list_delete_link: "g_list_delete_link" [ list [handle!] @@ -783,10 +784,10 @@ GPtrArray!: alias struct! [ return: [handle!] ] g_list_insert_sorted: "g_list_insert_sorted" [ - list [handle!] - data [handle!] + list [handle!] + data [handle!] comp-func [integer!] - return: [handle!] + return: [handle!] ] g_ascii_dtostr: "g_ascii_dtostr" [ buffer [c-string!] @@ -799,37 +800,37 @@ GPtrArray!: alias struct! [ return: [c-string!] ] g_strdup: "g_strdup" [ - str [c-string!] - return: [c-string!] + str [c-string!] + return: [c-string!] ] g_strndup: "g_strndup"[ - str [c-string!] - n [integer!] - return: [c-string!] + str [c-string!] + n [integer!] + return: [c-string!] ] g_strconcat: "g_strconcat" [ [variadic] - return: [c-string!] + return: [c-string!] ] g_strcmp0: "g_strcmp0" [ str [c-string!] str2 [c-string!] - return: [integer!] + return: [integer!] ] g_strsplit: "g_strsplit" [ - str [c-string!] + str [c-string!] delim [c-string!] - tokens [integer!] - return: [handle!] + tokens [integer!] + return: [handle!] ] g_strsplit_set: "g_strsplit_set" [ str [c-string!] delim [c-string!] - tokens [integer!] - return: [handle!] + tokens [integer!] + return: [handle!] ] g_free: "g_free" [ - ptr [handle!] + ptr [handle!] ] g_strfreev: "g_strfreev" [ str_array [handle!] @@ -862,6 +863,9 @@ GPtrArray!: alias struct! [ len [integer!] return: [GString!] ] + g_string_append_printf: "g_string_append_printf" [ + [variadic] + ] g_string_free: "g_string_free" [ str [GString!] free [logic!] @@ -1509,6 +1513,10 @@ GPtrArray!: alias struct! [ frame [handle!] shadow [integer!] ] + gtk_frame_get_label_widget: "gtk_frame_get_label_widget" [ + frame [handle!] + return: [handle!] + ] gtk_box_new: "gtk_box_new" [ orient [GtkOrientation!] spacing [integer!] @@ -1696,7 +1704,15 @@ GPtrArray!: alias struct! [ ] gtk_label_set_line_wrap: "gtk_label_set_line_wrap" [ widget [handle!] - wrap [logic!] + wrap [logic!] + ] + gtk_label_set_angle: "gtk_label_set_angle" [ + widget [handle!] + angle [float!] + ] + gtk_label_set_attributes: "gtk_label_set_attributes" [ + widget [handle!] + list [handle!] ] gtk_event_box_new: "gtk_event_box_new" [ return: [handle!] @@ -1730,10 +1746,10 @@ GPtrArray!: alias struct! [ ] gtk_entry_set_placeholder_text: "gtk_entry_set_placeholder_text" [ buffer [handle!] - text [c-string!] + text [c-string!] ] gtk_entry_set_visibility: "gtk_entry_set_visibility" [ - entry [handle!] + entry [handle!] visible [logic!] ] gtk_entry_buffer_set_text: "gtk_entry_buffer_set_text" [ @@ -1741,6 +1757,10 @@ GPtrArray!: alias struct! [ text [c-string!] len [integer!] ] + gtk_entry_set_attributes: "gtk_entry_set_attributes" [ + entry [handle!] + list [handle!] + ] gtk_editable_select_region: "gtk_editable_select_region" [ entry [handle!] start [integer!] @@ -2843,3 +2863,32 @@ GPtrArray!: alias struct! [ ] ] ] + +;; Identifiers for qdata +red-face-id1: g_quark_from_string "red-face-id1" +red-face-id2: g_quark_from_string "red-face-id2" +red-face-id3: g_quark_from_string "red-face-id3" +red-face-id4: g_quark_from_string "red-face-id4" +gtk-style-id: g_quark_from_string "gtk-style-id" +container-id: g_quark_from_string "container-id" +red-timer-id: g_quark_from_string "red-timer-id" +css-id: g_quark_from_string "css-id" +size-id: g_quark_from_string "size-id" +menu-id: g_quark_from_string "menu-id" +no-wait-id: g_quark_from_string "no-wait-id" +red-event-id: g_quark_from_string "red-event-id" +cursor-id: g_quark_from_string "cursor-id" +resizing-id: g_quark_from_string "resizing-id" +start-resize-id: g_quark_from_string "start-resize-id" + + +#define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] +#define GET-CONTAINER(s) [g_object_get_qdata s container-id] +#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] +#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] +#define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] +#define GET-RESIZING(s) [g_object_get_qdata s resizing-id] +#define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] +#define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] +#define SET-CSS(s d) [g_object_set_qdata s css-id d] +#define GET-CSS(s) [g_object_get_qdata s css-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index fabc5e42da..159682fa86 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -10,19 +10,6 @@ Red/System [ } ] -#define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] -#define GET-CONTAINER(s) [g_object_get_qdata s container-id] -#define SET-CURSOR(s d) [g_object_set_qdata s cursor-id d] -#define GET-CURSOR(s) [g_object_get_qdata s cursor-id] -#define SET-RESIZING(s d) [g_object_set_qdata s resizing-id d] -#define GET-RESIZING(s) [g_object_get_qdata s resizing-id] -#define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] -#define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] - -#define CREATE-DEFAULT-FONT [ - font-description-create default-font-name default-font-size PANGO_WEIGHT_NORMAL PANGO_STYLE_NORMAL -] - #include %../keycodes.reds #include %gtk.reds #include %events.reds @@ -45,28 +32,10 @@ exit-loop: 0 ;;;win-array: declare red-vector! win-cnt: 0 -;; Identifiers for qdata -red-face-id1: g_quark_from_string "red-face-id1" -red-face-id2: g_quark_from_string "red-face-id2" -red-face-id3: g_quark_from_string "red-face-id3" -red-face-id4: g_quark_from_string "red-face-id4" -gtk-style-id: g_quark_from_string "gtk-style-id" -container-id: g_quark_from_string "container-id" -red-timer-id: g_quark_from_string "red-timer-id" -css-id: g_quark_from_string "css-id" -size-id: g_quark_from_string "size-id" -menu-id: g_quark_from_string "menu-id" -no-wait-id: g_quark_from_string "no-wait-id" -red-event-id: g_quark_from_string "red-event-id" -cursor-id: g_quark_from_string "cursor-id" -resizing-id: g_quark_from_string "resizing-id" -start-resize-id: g_quark_from_string "start-resize-id" - group-radio: as handle! 0 settings: as handle! 0 pango-context: as handle! 0 -default-font: as handle! 0 default-font-name: as c-string! 0 default-font-size: 0 gtk-font-name: "Sans" @@ -392,35 +361,17 @@ get-text-size: func [ ][ if null? pango-context [pango-context: gdk_pango_context_get] size: declare tagSIZE + if null? hFont [hFont: default-attrs] - text: either TYPE_OF(str) = TYPE_STRING [ - len: -1 - unicode/to-utf8 str :len - ][ - null - ] - - width: 0 height: 0 - - ;;; get pango_context - ; from widget first - ; widget: face-handle? face - ; pc: as handle! 0 pl: as handle! 0 - ; unless null? widget [ - ; pc: gtk_widget_get_pango_context widget - ; unless null? pc [pl: pango_layout_new pc ];seems more natural than pango-context - ; ] - ; globally otherwise - ;if null? pl [ - pl: pango_layout_new pango-context - ;] - + len: -1 + text: unicode/to-utf8 str :len + pl: pango_layout_new pango-context pango_layout_set_text pl text -1 - pango_layout_set_font_description pl hFont + pango_layout_set_attributes pl hFont + width: 0 height: 0 pango_layout_get_pixel_size pl :width :height g_object_unref pl -; unless null? pc [g_object_unref pc] size/width: width size/height: height @@ -432,21 +383,6 @@ get-text-size: func [ size ] -to-bgr: func [ - node [node!] - pos [integer!] - return: [integer!] ;-- 00bbggrr format or -1 if not found - /local - color [red-tuple!] -][ - color: as red-tuple! get-node-facet node pos - either TYPE_OF(color) = TYPE_TUPLE [ - color/array1 and 00FFFFFFh - ][ - -1 - ] -] - free-handles: func [ widget [integer!] force? [logic!] @@ -581,7 +517,7 @@ set-defaults: func [ len: len + 1 default-font-name/len: null-byte default-font-size: size - default-font: CREATE-DEFAULT-FONT + set-default-font default-font-name default-font-size ] init: func [][ @@ -780,35 +716,20 @@ change-color: func [ color [red-tuple!] type [integer!] /local - clr [integer!] t [integer!] face [red-object!] + values [red-value!] font [red-object!] ][ - ;; DEBUG: print ["change-color " widget " " get-symbol-name type lf] t: TYPE_OF(color) if all [t <> TYPE_NONE t <> TYPE_TUPLE][exit] - ; if transparent-color? color [ - ; objc_msgSend [widget sel_getUid "setDrawsBackground:" no] - ; exit - ; ] - case [ - type = area [ - face: get-face-obj widget - font: face-font? face - apply-css-styles widget face font type - ; widget: objc_msgSend [widget sel_getUid "documentView"] - ; clr: either t = TYPE_NONE [00FFFFFFh][color/array1] - ; set-caret-color widget clr - ; if t = TYPE_NONE [clr: objc_msgSend [objc_getClass "NSColor" sel_getUid "textBackgroundColor"]] - ] - true [ - ;; DEBUG: print ["change-color " widget lf] - face: get-face-obj widget - font: face-font? face - apply-css-styles widget face font type - ] - ] + ;-- TBD: need to be improved + face: get-face-obj widget + values: object/get-values face + font: as red-object! values + FACE_OBJ_FONT + free-font font + make-font null font + set-font widget face values ] change-pane: func [ @@ -877,31 +798,9 @@ change-pane: func [ change-font: func [ widget [handle!] face [red-object!] - font [red-object!] - type [integer!] - return: [logic!] - /local - ; css [c-string!] - ; provider [handle!] - hFont [handle!] + values [red-value!] ][ - ;; DEBUG: print ["change-font " widget " " get-symbol-name type lf] - if TYPE_OF(font) <> TYPE_OBJECT [return no] - - ; provider: get-styles-provider widget - - ; ;; update the style (including font color) gtk_css_provider is much more easier to apply than older interface to manage all the styles - ; css: "" - ; css: css-styles face font type - - ; unless null? provider [gtk_css_provider_load_from_data provider css -1 null] - - apply-css-styles widget face font type - - ;; Update the pango_font_description hFont (directly used by get-text-size) - make-font face font - - yes + set-font widget face values ] change-offset: func [ @@ -1814,6 +1713,7 @@ OS-make-view: func [ ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT store-face-to-obj widget face + change-font widget face values if sym <> window [ if parent <> 0 [ @@ -1843,13 +1743,11 @@ OS-make-view: func [ ;; TODO: NOT SURE the if is necessary! if sym <> base [ - change-font widget face font sym + change-font widget face values ] if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] - change-color widget as red-tuple! values + FACE_OBJ_COLOR sym - stack/unwind as-integer widget ] @@ -1949,7 +1847,7 @@ OS-update-view: func [ change-rate widget values + FACE_OBJ_RATE ] if flags and FACET_FLAG_FONT <> 0 [ - change-font widget face as red-object! values + FACE_OBJ_FONT type + change-font widget face values ] if flags and FACET_FLAG_PARA <> 0 [ change-para diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 1ed14410b6..1917db5c82 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -90,28 +90,27 @@ render-text: func [ /local text [red-string!] font [red-object!] + attrs [handle!] para [red-object!] flags [integer!] + layout [handle!] len [integer!] str [c-string!] - line [integer!] - x [float!] - y [float!] - temp [float!] - ;te [cairo_text_extents_t!] - ;fe [cairo_font_extents_t!] + pline [handle!] lx [integer!] ly [integer!] + x [float!] + y [float!] rect [tagRECT value] lrect [tagRECT value] - pline [handle!] - pc [handle!] - lpc [handle!] - fd [handle!] ][ text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] + + font: as red-object! values + FACE_OBJ_FONT + attrs: get-attrs null font + ;; DEBUG: print ["render-text: " cr lf] para: as red-object! values + FACE_OBJ_PARA flags: either TYPE_OF(para) = TYPE_OBJECT [ ;@@ TBD set alignment attribute @@ -120,28 +119,19 @@ render-text: func [ 0005h ;-- center or middle ] + layout: pango_cairo_create_layout cr cairo_save cr - ; The pango_cairo way - pc: pango_cairo_create_context cr - lpc: pango_cairo_create_layout cr - - font: as red-object! values + FACE_OBJ_FONT - fd: font-description font - pango_layout_set_font_description lpc fd - if TYPE_OF(text) = TYPE_STRING [ - len: -1 - str: unicode/to-utf8 text :len - ] - ;; DEBUG: print ["render-text " str " size: " size/x "x" size/y " flags: " flags lf] + len: -1 + str: unicode/to-utf8 text :len + pango_layout_set_text layout str -1 + pango_layout_set_attributes layout attrs - pango_layout_set_text lpc str -1 - cairo_set_source_rgba cr 0.0 0.0 0.0 0.5 - pango_cairo_update_layout cr lpc + pango_cairo_update_layout cr layout - pline: pango_layout_get_line lpc 0 + pline: pango_layout_get_line layout 0 pango_layout_line_get_pixel_extents pline rect lrect - ly: (pango_layout_get_line_count lpc) * lrect/height + ly: (pango_layout_get_line_count layout) * lrect/height lx: lrect/width case [ @@ -158,42 +148,9 @@ render-text: func [ ;; DEBUG: print [lx "x" ly " and (" x "," y ")" lf] cairo_move_to cr x y - - pango_cairo_show_layout cr lpc - + pango_cairo_show_layout cr layout cairo_stroke cr cairo_restore cr - -; @@ The cairo way (alternative) does not work for me after too many attempt -; if TYPE_OF(text) = TYPE_STRING [ -; len: -1 -; str: unicode/to-utf8 text :len -; te: as cairo_text_extents_t! allocate (size? cairo_text_extents_t!) -; cairo_text_extents cr str as handle! te -; fe: as cairo_font_extents_t! allocate (size? cairo_font_extents_t!) -; cairo_font_extents cr as handle! fe -; x: 0.5 - te/x_bearing - (te/width / 2.0) -; y: 0.5 - fe/descent + (fe/height / 2.0) -; free as byte-ptr! te -; free as byte-ptr! fe -; ] - -; cairo_scale cr 170.0 40.0 -; ;set-source-color cr 0 -; cairo_set_source_rgba cr 0.0 0.0 0.0 0.5 - -; font: as red-object! values + FACE_OBJ_FONT -; either TYPE_OF(font) = TYPE_OBJECT [ -; select-cairo-font cr font -; ][ -; 0 -; ] - -; ;cairo_move_to(cr, w/2 - extents.width/2, h/2); -; cairo_move_to cr x y -; print [ "hi-str: <" str ">" lf] -; cairo_show_text cr str - ] base-draw: func [ diff --git a/modules/view/backends/gtk3/para.reds b/modules/view/backends/gtk3/para.reds index dc5d1bef8d..d1481ab697 100644 --- a/modules/view/backends/gtk3/para.reds +++ b/modules/view/backends/gtk3/para.reds @@ -38,7 +38,7 @@ change-para: func [ type = text ][ if TYPE_OF(font) = TYPE_OBJECT [ - change-font widget face font type + change-font widget face object/get-values face ] gtk_widget_set_halign widget (flags and FFFFh) + 1 gtk_label_set_justify widget (flags and FFFFh) @@ -46,7 +46,7 @@ change-para: func [ ] type = area [ if TYPE_OF(font) = TYPE_OBJECT [ - change-font widget face font type + change-font widget face object/get-values face ] gtk_text_view_set_justification widget (flags and FFFFh) gtk_text_view_set_wrap_mode widget either (flags and FFFF0000h <> 0) [GTK_WRAP_WORD][GTK_WRAP_NONE] diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 3f5e68efc9..1f44d73e27 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -24,17 +24,6 @@ Red/System [ max-line-cnt: 0 -layout-ctx-init: func [ - lc [layout-ctx!] - text [c-string!] - text-len [integer!] -][ - lc/text: text - lc/text-len: text-len - lc/text-pos: 0 - lc/attr-list: pango_attr_list_new -] - utf8-to-bytes: func [ text [c-string!] len [integer!] @@ -58,7 +47,7 @@ color-u8-to-u16: func [ /local t [integer!] ][ - t: color >> 24 and FFh + t: color >>> 24 and FFh a/value: t << 8 + t t: color >> 16 and FFh b/value: t << 8 + t @@ -92,12 +81,12 @@ OS-text-box-color: func [ attr: pango_attr_foreground_new r g b attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr attr: pango_attr_foreground_alpha_new a attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-background: func [ @@ -124,12 +113,12 @@ OS-text-box-background: func [ attr: pango_attr_background_new r g b attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr attr: pango_attr_background_alpha_new a attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-weight: func [ @@ -149,7 +138,7 @@ OS-text-box-weight: func [ attr: pango_attr_weight_new weight attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-italic: func [ @@ -168,7 +157,7 @@ OS-text-box-italic: func [ attr: pango_attr_style_new PANGO_STYLE_ITALIC attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-underline: func [ @@ -189,7 +178,7 @@ OS-text-box-underline: func [ attr: pango_attr_underline_new PANGO_UNDERLINE_SINGLE attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-strikeout: func [ @@ -209,7 +198,7 @@ OS-text-box-strikeout: func [ attr: pango_attr_strikethrough_new true attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-border: func [ @@ -245,15 +234,15 @@ OS-text-box-font-name: func [ attr: pango_attr_family_new str attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-font-size: func [ - nsfont [handle!] - layout [handle!] - pos [integer!] - len [integer!] - size [float!] + dc [handle!] + layout [handle!] + pos [integer!] + len [integer!] + size [float!] /local lc [layout-ctx!] s [integer!] @@ -266,7 +255,7 @@ OS-text-box-font-size: func [ attr: pango_attr_size_new PANGO_SCALE * as integer! size attr/start: s attr/end: s + e - pango_attr_list_insert lc/attr-list attr + pango_attr_list_change lc/attrs attr ] OS-text-box-metrics: func [ @@ -348,133 +337,75 @@ OS-text-box-metrics: func [ OS-text-box-layout: func [ box [red-object!] target [int-ptr!] - ft-clr [integer!] + ft-clr [integer!] ;-- TBD: to replace font color catch? [logic!] return: [handle!] /local - hWnd [handle!] values [red-value!] + text [red-string!] + state [red-block!] size [red-pair!] - rstate [red-integer!] + font [red-object!] + cached? [logic!] + attrs [handle!] + int [red-integer!] + layout [handle!] + para [handle!] bool [red-logic!] - state [red-block!] - styles [red-block!] - pval [red-value!] - vec [red-vector!] - obj [red-object!] - w [integer!] - h [integer!] - dc [draw-ctx!] lc [layout-ctx!] - cached? [logic!] - force? [logic!] - font [red-object!] - hFont [handle!] - clr [integer!] - text [red-string!] - len [integer!] str [c-string!] - pc [handle!] - ft-ok? [logic!] + len [integer!] + styles [red-block!] ][ - ;; DEBUG: print ["OS-text-box-layout: " box " " face-handle? box " target: " target lf] values: object/get-values box - state: as red-block! values + FACE_OBJ_EXT3 - cached?: TYPE_OF(state) = TYPE_BLOCK - ;; DEBUG: print ["cached?: " cached? " state: " state lf] - force?: either cached? [ - rstate: as red-integer! block/rs-head state - bool: as red-logic! rstate + 1 - ;; DEBUG: print ["rstate: " rstate " -> " rstate/value " bool: " bool " -> " bool/value lf] - bool/value - ][true] - ;; DEBUG: print ["force?: " force? lf] - lc: declare layout-ctx! ; this is not dynamic but lc/layout would change dynamically for each rich-text text: as red-string! values + FACE_OBJ_TEXT + state: as red-block! values + FACE_OBJ_EXT3 + size: as red-pair! values + FACE_OBJ_SIZE font: as red-object! values + FACE_OBJ_FONT - ft-ok?: TYPE_OF(font) = TYPE_OBJECT ;all[not null? target TYPE_OF(font) = TYPE_OBJECT] - either ft-ok? [ - hFont: get-font-handle font 0 - if null? hFont [hFont: CREATE-DEFAULT-FONT] + attrs: create-pango-attrs box font + cached?: TYPE_OF(state) = TYPE_BLOCK + + either cached? [ + int: as red-integer! block/rs-head state + layout: as handle! int/value + int: int + 1 para: as handle! int/value + bool: as red-logic! int + 2 + bool/value: false ][ - hFont: CREATE-DEFAULT-FONT + para: null + if null? pango-context [ + pango-context: gdk_pango_context_get + ] + layout: pango_layout_new pango-context + + block/make-at state 4 + integer/make-in state as integer! layout + integer/make-in state as integer! para + none/make-in state + logic/make-in state false ] len: -1 str: unicode/to-utf8 text :len - - layout-ctx-init lc str len - - ;; DEBUG: print ["OS-text-box-layout lc/text: " lc/text " " lc/text-len lf] - - size: as red-pair! values + FACE_OBJ_SIZE - - either force? [ - ;; create lc/layout - ;; DEBUG: print ["create layout: " target lf] - either null? target [ - either cached? [lc/layout: as handle! rstate/value] - [ - ; this is when OS-text-box-metrics is used before drawing - if null? pango-context [pango-context: gdk_pango_context_get] - lc/layout: pango_layout_new pango-context - ;; DEBUG: print ["rich-text layout: " lc/layout " " pango_font_description_get_family hFont " " pango_font_description_get_size hFont lf] - ] - ][ - dc: as draw-ctx! target - dc/font-desc: hFont - lc/layout: make-pango-cairo-layout dc/raw dc/font-desc - ;; DEBUG: print ["rich-text layout with target: " lc/layout lf] - ] - ;; DEBUG: print ["with target: " target " lc/layout: " lc/layout lf] - either cached? [ - rstate/value: as integer! lc/layout - bool/value: false - ;; DEBUG: print ["lc/layout force to be updated: " lc/layout " bool: " bool/value lf] - ][ - block/make-at state 3 ;maybe more later - ;; DEBUG: print ["lc/layout newly created: " lc/layout lf] - integer/make-in state as integer! lc/layout ; handle for lc/layout - logic/make-in state either null? target [true][false] ; force build lc/layout - logic/make-in state true ; possible use for redraw used in gui.red/update-richtext - ] - ][ - lc/layout: as handle! rstate/value - ;; DEBUG: print ["lc/layout cached: " lc/layout lf] - ] - pango_layout_set_font_description lc/layout hFont + pango_layout_set_width layout PANGO_SCALE * size/x + pango_layout_set_height layout PANGO_SCALE * size/y + pango_layout_set_wrap layout PANGO_WRAP_WORD_CHAR ;-- TBD: apply para + pango_layout_set_text layout str -1 styles: as red-block! values + FACE_OBJ_DATA if all [ TYPE_OF(styles) = TYPE_BLOCK 1 < block/rs-length? styles ][ + ;-- this is not dynamic but lc/layout would change dynamically for each rich-text + lc: declare layout-ctx! + lc/layout: layout + lc/text: str + lc/attrs: attrs parse-text-styles target as handle! lc styles 7FFFFFFFh catch? ] - pango-layout-set-text lc size - as handle! lc -] - -pango-layout-apply-attr: func [ - lc [layout-ctx!] -][ - pango_layout_set_text lc/layout lc/text -1 - unless null? lc/attr-list [ - pango_layout_set_attributes lc/layout lc/attr-list - pango_attr_list_unref lc/attr-list - lc/attr-list: null - ] -] - -pango-layout-set-text: func [ - lc [layout-ctx!] - size [red-pair!] -][ - unless null? lc [ - pango-layout-apply-attr lc - pango_layout_set_width lc/layout PANGO_SCALE * size/x - pango_layout_set_height lc/layout PANGO_SCALE * size/y - pango_layout_set_wrap lc/layout PANGO_WRAP_WORD_CHAR - ] + pango_layout_set_attributes layout attrs + free-pango-attrs attrs + layout ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 1b08eadac1..b2ea36676b 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -90,20 +90,15 @@ Red/System [ pattern [int-ptr!] on-image? [logic!] shape-curve? [logic!] - ; pango-cairo - font-desc [handle!] - font-opts [handle!] - font-underline? [logic!] - font-strike? [logic!] - layout [handle!] ; Only for draw not for rich-text + font-attrs [handle!] ;-- pango attrs for fonts + font-opts [handle!] ;-- cairo opts for fonts + layout [handle!] ;-- Only for draw not for rich-text ] layout-ctx!: alias struct! [ - layout [handle!] ; Only for rich-text + layout [handle!] ;-- Only for rich-text text [c-string!] - text-len [integer!] - text-pos [integer!] - attr-list [handle!] + attrs [handle!] ] ] @@ -119,7 +114,7 @@ Red/System [ draw-ctx!: alias struct! [ raw [int-ptr!] ;-- OS drawing object: CGContext - matrix [CGAffineTransform! value] + matrix [CGAffineTransform! value] pen-join [integer!] pen-cap [integer!] pen-width [float32!] From 9c4903bb07235410f6f1557eade4ddf9581ad911 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 24 Oct 2019 13:02:26 +0200 Subject: [PATCH 0316/3432] FEAT: completes the date! parsing FSM. --- docs/lexer/lexer-states.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 16932df351..d455da541c 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -328,11 +328,21 @@ S_DT_D S_DT_DD S_DT_YYY F_DT_YEARL +F_DT_YEAR2 F_DT_DAYL S_DT_YM S_DT_YMM F_DT_YMONTH -F_DT_YMONTH +F_DT_DDD +S_DT_YV +S_DT_YW +S_DT_YWW +F_DT_WEEK +S_DT_W +S_DT_WW +F_DT_YWW +S_DT_WD +F_DT_YWWD S_DT_YMON S_DT_YMD S_DT_YMDD @@ -384,9 +394,11 @@ F_DT_YEARL2->digit->S_DT_YM \->letter->S_DT_YMON \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->F_DT_WEEK -F_DT_WEEK +F_DT_WEEK->digit->S_DT_W->digit->S_DT_WW->eof->F_DT_YWW + \->digit->S_DT_WD->eof->F_DT_YWWD + \->"T"->S_TM_START -F_DT_DDD +F_DT_DDD->"T"->S_TM_START F_DT_YMONTH->digit->S_DT_YMD->digit->S_DT_YMDD->sep|eof->F_DT_YMDAY From 1b8f24f525b7bcfb5114f24bcde1fb6461bfbc86 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 24 Oct 2019 18:57:48 +0200 Subject: [PATCH 0317/3432] FEAT: defines character classes for the date! lexer. --- docs/lexer/lexer-FSM.xlsx | Bin 18647 -> 24085 bytes docs/lexer/lexer-states.txt | 15 +++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 777ca1d160c3dca183e040efc51677b8936ec339..62fc3bb5d890ffecf2dcef842af75599b8ee7ca9 100644 GIT binary patch delta 16259 zcmcJ0bzD^K);5iFOLs{RAt>F_9fHJ2hk%ljn-EY0iJ?1(1`!l#6r?1iq#RJXQBwNb z=yTNP(R1GO{oe26A7*Cn`(D?&)>_wEd(Z5#SmcC8WC|@+R5Vf~45Uj)NJxxGB?mY2 zeUOomNHMA?7*Pm&^|~F}AcRfiM+Ayv#9YcSWfVG~X?%RB(K^gKWUz!Yj}=X*pDmZ% zO94&TV{%-aC~LU3Kks2o{Ah{$W#TFf(!5U_ebD;-KqA9iYVtDkS^4cXfhxDx#cxV> zn-r0LvF$1_TrpW-I7V!SsAaG|9m%1R!^Px_DOOM(T#Eo);(H^>26qpn!=4OcYEj`JmGq2bwng4Xk-vi*D&9kx-R_xx%aGqt`1Ml= z-PZUKR@l*eO{o(CGn$zKZ}29%k0F_FQmIZr9VF|zNc2ERjg$It?n|AHP4}!%F1&en z%$m4xichb$@_6i?KYDU3H6+vM#*ntObz`X2M2P}vs2;8H*%aO~>!K|BJCa$a{z~4D z?EBYgY53&; zlu=y-l@6A>2h;*>8g3`@@I98?2v+p4iLLznA!sGXJvyiK5#HTYOG>I055W69UXQqX zt-#4>paq=cNkZ`5GGPXdkm&w%$A)@mRlj=+w$X`|H@jTO`>hDCN36bM;7T@T>Fj2E z)Xq@ZHZKy^odkVG-Daf%WOzEl;tLKE(m9MpoCr&+X)eJZq@)zahQ$bUc%>RrXFEhZKzfDFs5iMI zJS}8EEB4G(=PWa-G>j>zy?dfF(zYW7u}S?#@|~!?`zx4sFXigcrD73uz+BwS%xzKJ z4!OsU`zyO>fS8n2nn#E8SjQboB0Iy+lgFM^3KeBl$RYwf4yk$_!XJxk(z>2smU&4v zD8i{ScP*LRStofQuNVZ`(;G`#o2KqKhq%TWxh|co)nG^&R&~MijL7 z`-dFGZ5Zm{3=cZQX}!pjqtqP@olwCxCl^;AD$O}?e&DL>D{Jkos7|m}JI%b(-EnyH%W=ZK*v)48_3Z{CNNP!M*Tb$$_RlNF zoOJ_7h2Kn$svp$O!1jioe3g3M@Fb1sWKrv5r}eeM!tj&N2U3}I(E;X?E#hU(fOuw; zn1rNpK#RG5z}K_Axi7#;!|_z#m%+D3o5xEHoudZ}opVx2e4W7g?!fsj@M&rFa4gB? z?ZQ!)*{9>TopUa0d(j8%?0g3^iJD$~TLw~zGaD_3&wK*vZ%uh+wPZG)+&7!{pFYVh z?1WVh50}CU8^X6brws3(pCpdm^grCb+p=zO&?3RpQd!Hl-RReNYpU{mVX7@U>9kY= z(Xz0RxtR%^ZgkFU8fr?d1FQkw_x*03*Le@l(;R6KwL~0Y!nMvl7bmx})k^}wDPc$X{ z$4QR{!WRaTW~XkfHJG0{9lmTd=aZUZU;S!#gm&`G_*4`RBTv`2FA3;t-A(m6SPP#? zdb}_<*E#3xX_M7{K7ArIT)R(4i=n|zKc5$`q&JozkIjy6iiMFO1Joo6yk5oVbK z{bw^t*C)>6gy~(pYMYODKY8!%bWJ<%!S1a48|dQrizXDb+qU*M!{62ENJ(lJBX3FO3G;&5yw;dTkUEc6YcYw3_^QCadfi#;I^xGw>=ui2TsT|at!ZchXfm5!q&d6r-WS>$eDhMf%yC+ z4Njzy3vTCe?Xb_OD(jFdUAFQgDF%8aA!+XGq8L(FWPRXeDg5rR&}-%RLr=SE%{u|- z##h{Zue5wz&_6oul`Pk#AZ?V@dWfATtJ8(9_i0^oC(P@EP}JS+&X0a#dJlA$e|6@Y zFP!SOucyv0Wx%zSF9#iZ78T{c`^^jedZ!X0^;@jR5diO5W4yjyGc6}4hdXvt@Zaqv z*myn=ZcGuLTV`4N=qIB8AlN;IZk7SHT@HmsR#7QUJZE6Jf zVvuJUk%<|ZS!7%}!1Gd^>|P-J3sNeM_oHcRQdGiIegjH3_3lo?zKS4XxA5F}+Ln{n z#^)grf=ft%6?2J_5i3r$I8B}Fj$HLdhgj2xwSaq!YlnUY>u;ub=!ax{9{%G*94GL^ zGp;`OmMpSc+ZBH_=yPEZPgM}HZ~Lad(Gfm$8y)fbHW-GP$H`W|H-+N-->8Q$Dp?#Xh>4~R=`A=HGS$$h|!C)eF37pYU6Mi`EOVkL&Mf?-qNt0?s9O z;7KySN9(`Avd>pb^L6sOQ*E??zeW6i+9Nfi7C<1U-D^VS-2tmqJ|3`o>m<#y9 z+`ln$2$H7qpGaE*N#pt>X~0EUT*QyQ9<|~>#SeO3KOJN$_aCh^h_yD4n4KR4atRHW z169ZOD#^r@{#hv?_a`9t1+~M@tIyv7D8J`680GJPGyYAK|H3=2R(tklv$M%yok5~q z2IFBkn$m;F7_{yJy*}Q_&A`5w)5wNCE}L*O9G*WDdv6&Zcsb}8R-KVc`SFai$+87m@Lj;RSf*1jz92vPJ(!M1(qSh zax_+f_mu+WyDllmn5c}dKij|`k6fd@Tkh5BTw;f@@(+n_lx`Un~HA&D)XxX2stZn0XCW_nA-Z z0cR5GJAX7b=RxkTi?^O@$oZSNbgc0LM{uffg-X4@1?5{z#!PqBuReWjR{T4^l?}^j z4p8zYoqxKlceTRYYp`}?Jkqe?%J1yoM<~qbp*Ac(SNYLGfWKOE#h3cW&BYj=gN_Nm zMfzVJjQ!Dr?+)ny?!XIE_oFrEwH9x*-z3JdW+Qj3-WyB<;Gcr4IK}Hzp0@OdRQ$2# zzh2_-0bG;z#eqEZcMhEzmZO|Aae&{tX~p1+$J5J;b$>|1zt;R;F2VEE{__ebhzt1V zJVgZ>`Hw69+XW@}rd~XD?kF`S{UiOg;|h#mLIQuEM=scZ{GV6+zg+orc4h-O7!C6%EbQ2Z3hpre=v8v`-*~fE7#T95j6H-ZpGbj(gfcI-u6~=K# zY5aEh+nUs17WJuqQL#5eD$j&Ot$$hl%a+)2LQXjA>!j4&-N4Xt{P*2|IsVP$H$>GS zqU!$v(Ikjy>VH6#DJJ$NSM?8wfWO?hfTX&$PI`;4`#&RU1rfFW2SnMTeT&6jQ!Qv` zJm;$uWqvBtn{`(heD9i8SvbSjyFFC)mql59Ju~7Y8a28z&45Cy=t|vZOJf`psO$0T zSf1$0srHn2ly$kIk3q`+Ny@i4fFF{w*u$-#vZ_~!Zw~(+sDG`}jmb|*e3dBlX8Wb) z-y-?16Y{J8Fhc4waW=*nw}wdH&Po0&)<4hq5yJm3$bf$j?f*G4y}}9c<8nsz!?KsA zR5229FK_aT0J{5X7OcKks^TOPZg$hDmRSw38a%@!;hKOwN?0FkSJ}Ta8_d#IgZm<% zBeB!}pC$1NO<)EM3yjCXZ_*w7pzQYmf?2Kh7OI+R;r*fTBACFRLkyOhAWsO7eZ<1O ztY2*Wti^91g2nc~MF#w=@qa@5-ywTpuVL2AleD(!?0>M*7Tr+!*6-kC54^)QIJf=y zbhNi{t88JXZA{SR*rn1?O4z|Xxuxv=+UW3^?@XdsR?@)m!MfKGU+JjNc?L|AUL&9) z6F{7ZXPwfO?%R(=uo z>6o_a9QD;H1rCHF{EPgGpJdjS9ru(xbvuTKuTQ|KSwT;`eyK{G8KQUh(@KI-%5zB- z9c;_Z2Mb~-vShiDtN*ZDMzQ(Serzws$R7cqUl_tJZkRl!VH zYRgmLe2ku8pt5;#PJ-j${=xQ=`M`PojHIOMBPqH7$@Q}datT1fyYYPF=&Z)S?s%@y z?%mg>^)+@C*`G+<6Yk3DNGmebtj++es;uS_F3x1l++wBc;w@IWac0~BjKcRmLmSP#(GCX({pNR zb8)KT+2NrsXC{!9`2n#-cQ%b1ipV^xLTtQ<{?anzvZ8S|Sevu~h-e=3i%5xBSPS3l zAKga}$|9b8x0>K7Ux~d$<|G zZP!?l)qJLlXq*|<{n!1L+v9{@~IihXS@yc1P4H3ZMT!@U6@G^ z0-z^KmrHcV>C#W!-JaLM8{uPc$d*CY zM#aNg4h@<6e1h?(qHIQ>hqDZybz!x-CbxdBY$GFE)+!xo?Mrjq-lr>d_C+mGkl!xGgeg;&P&9buU; z5qdh{5ffBeOcDLGsDTHCmNF%h3T( zPPTA}Na0w7-%Pf!k4WHn4}Zv%Hf~C;zs?C-@|;ufTvDjm!$*tvB~@KaJ6s9)sLd^@ z*C9n1^&Gou#^b;;iB`F3#;aTsRyv-a8skn}QV0WW?n8cI5^yJpGfRj&%YT_9;;;Z3 zAJ?T!RZxUeq*+)*6m!_XlhZ72M-*@vJnGubcZdX|*F|&1l_$AbeT0Xw?lLY>13Gg9 zCiB>XoFEgDFjStG0x5+8*YDq#&wgW!o@!kBjCn;`mz{}IxR{OQDgIU6k&W9_!uFH- z*02}qqQWa|087nY(*v~26)q7$60jU2tH1N>t<6~+y^-XdCu*7SP%XE(|K=1+L~jt& zSV&MBgR2AulP7_qCy8POjvQ(oFD~M}_Dej$M+R{&C^SU&z7+yIwGGyVC`sB?%FhGi zRaSSxsboCDWgXum!LihEl7%6(P@ukbH*f`25Xt6J@1^7_!Ifk7+8q)tJM3QEzj{NxBSizLCD8H7d>dFjb54N^(l8nvU5z>!A7TpiY26K?L=r>;Y|whgQ(Bt@ zk*(pay@4sH)krp2z1YcDA;dw-=b@Y4kE8?r(lEFV74ev6N@V0y^_d9OKGc@Js}*z| zYoX7tCc1Jk$xlSFV}e#Pp!oI+C6p|v?jV5^O&_a-NRPcpMhljGS;i??6wQNH^yyr; z7qwE3qzr0s7+TaNDiR?^8#|SEk=fT}aDo%j$}bs{upC}W)kTTBGSara!K;Jgaqq$8 zO&tMB{^Z)`XoBoJD%hfItdK`ThZ=P?pHcW_g2K#j(a9u zXM+c0+x+pRN-g0pvpa82+&+A*#aM3FrB_U7Qda+BxtUN^N&?Y0WN)H5ti1#iWz^*> z$(ycrzD8pF-e%CFn0@wg(J*iFz*hMFDYFS?{L1BcZ7D+^boojseKInT+)p?{i7bd= zgVIZyoFbTGngz0L$s?1IAh@zSoKcOTI5gml^GGU?6D?LF0S&Em&ahUEt|6)sKqtFGvOsmZ|e`hs{cz8#fXh7eh_dCHX)HPVX9S# zsYdURj0};pMX7z$#b%kN)@t=jyn9l5QA+5aI%?gR(ARU@fGO0Cvf|{UI-E#}bj&m7W6 zsHr-c`*EU*{jAH-fk)S?$5trsii#BsaC97i7N>3y|9tfi+a@&0AExNc{x9`dUOq--(L-e5zts_D9*Ik237b%$$!VK+bRSQf(5k$4Y??p*wg>cylNIe-He0UYI?HdJiQFQ%#=Z|U8s;rU|o>CKHC@A_rmEsmy#f#OB)h0k#+RD~`%`bXVU%^o%=*9*U zT{XxE5q+F1>L96VJOBC3)Wju!Nhf{18$h4!hMJG+!02#LK6I$aeplNmIUgD<%f-_& zL(4Ez0*ahrNSBBsA&8bK&$OE3%9^_xc85tpwi#l(POf<4tZ3#06~3zG!>(Fl4Tj~_ zO+097YfYd%>M$}KM{OXbm#QTEaX_s0n)qEd_Zhs$tMe9+IuU^#ZOf=vH%S0nfiDG{ zRUk@KkHzf%+#(HL445N9C)7fA>^a6xEQK0&sIZy^VK%l52&C=M22{Xunfa-!4SGx?FPIpHvM+1vP4ut~kQHD|Acxsr*ybuXn0mq`; z;;qQ_t|`&A!gyo~$4jd~WW*xu@vHgiOMSK|i-PDoDM6xcTDIDH?BpT)9_6h!9ic23 zuvY@qm2_OJ7#oz`!wk~RhM{zg;qzDdi{=}y-s}cD0Oe_F)T^(4Lgx?WKhPHTmsR-G zU-6AMjyoC7<|2jYYZYRs(I)@UgYSZ9*K(BIj|3z$QaGaZQY2#~50EBPLfjx(=tb3N zHt4-n6pvozzmlcq&_b|xrzi|E}i9@Btn+0P-BcTwi)B^`Q+6DV>4AfgP&r~SlE>>=S9ESSE z96h9PU#bv<>CsCk3~Z2m_*OF=IxZn&U=CElEtLL8gct_Ta}NM%L#qrR~WYW zq^s6}koV9GFPAFi<<@(!8-0ttFvf!Q8zRjRa{e*?BBqLUExRY*SohS);4g*wbMXP+ z5{NCH0_|aq!@Td+Yw0fU8JG}Mv7S-i3im-TKR<;VZ3t&-4>^887RKnr>x+zi&7T}e zCg1@vKuug53A7UKWuY(!*+;L?LOs=h zKeD|${W0{rWLRpIJA0e!YC$kea{`O&MN{_m{v;XDBT(YKkyddtun=kAG``gjp52c- zk`f~NZ7yu}d!PLT^c9-Z7ej$oBpb6e`tfeFQ3%lG1#0H^7*m9NQFc5d>JAl4&akKS z$gf-1=A5k@SD~xWvVY10-tk{?`lb#LU8qg}gCqM*wWH4Z<}7k(8Q5YV z@4wZFh;YCDjuI}){H?3*INgsev>pjL0-!X3oR7VG0e(Pk@aB5Fzcx+Q*+r(c&8BEZ z?5!s95tG(m$i(+%`m?VgnDYAX?ngwfhDky~nDR6(;XaO}`mRwIC|Y|nlsi90`7qld zuW|<&A%hdskLpsv4OYoFV#SbQ1uhDd4Q#4+a68z`qaVt6LBvSzmF)G9AGXad_2>l_ zqv(PyP3@OBU#27zYhudV&;55D75cta33pQc3jZZSd;LeRf>l<ZC9v6z5w^unJpmKn=<^V^pb8hD`{Qf%mm>LpAj zf>=V?TGfJ5kOeVqzSS?}Li#tpr*O%I0E4DL`Pp!2hw7{#^>je}|L%B5yva6-dkHFsi>XTmsM!4Y7RqBvuA8&x-)M3(@?GXO##w!Zep4d-|?J^;;R<1iKaC&sn9$i8!Qtly?054z5apr3GY>6T{RAO+&+JLcW1GNy}cGnSX9G`ZQDI)8{@!*|&D^k1_eknzO&=4?U z^sVXnmg)`7aIzKQD>@<#yR#wu4Oe-d8N_NYDNaJmz-wmPAujiF=Y6vvj+L3tX+HT? zq5$c4G1){imceZJp_|V+Al1RI`bYN$aMYB~mBn!&<6tL-tOaAOgcD=6=Ti?KC^^56 zd+0f!!gM)7=b)ug^ODLafUR1Lo}|W2rNuQ=w@rNgTIroD9pTl{_l4E^U2UHX%)6HO zt>~?O`kYrEccIzOrc!X;SUqJZ2^pkn6$-LP9>##9s*xvW3g(P2i@}WK_pXm4MPB7D z$qQhJjEMBvaa~ul>nDL^{Ty?j9O2roM2ep^Hm&8+1LOt@9(o658OmFRGE|FVa_3lc z#9>(29{nC4}=JLjFu-talxy70@S-4%GTYUQ7#lY|)nWwit5WE2I zZ$ONH5muC8H#YaTyBSy&yGXdgETM{MQCO*g9O^+Sv9A`oWYF;Ez7Wv3)T8SXF+7Ui-XGAg=dix=6bqu~SbcUg`~x`Ni_L`;|o!C4s>!XFP#;UF&l3tap~)8bdmMH3=qPTk5cRwd z({KhbjcM~y%|~R{yYiPJ(;)L_?+54A0h-9?NFIsV{XHq~(#Nu&u-qOB%fW-Opn;b~ zPr}nF)Qbkh{@^(xx(_kdr+VTgQ0OwX(SP1&q~rB$;&jh% z+wY*!J4O7&%gvWlwaVXnTzq5GlVGZFYItem?dHPfZT2~TpReGT9YaUPq6z0;*T?o3 z22NR8PFlWy2?gAKL>G&RhJ?fk{+=8UeD37_9X>aA?>p9Ry!V~%^xnMXl6Q?Xz})^E zbz2Nw2O4*YLOqTtN~poO*wo&P7V_w7v;0SQn9&9>W9inX27^0I;`5DT9;a`a_}|^V z*O}s>*%P5c#Jts`aG5BjxA^9p<*kMhI_6THoAb%aG8Q!eJK0h4$=NNvVhQG2N7;CE zZh5l2=Q?S{b9xi0cTG&Y@rXVb#ISZ^!xwsrg;`&D7l_VYUzD(-mV69UKIale?$k0xZ4KAzT$!`w(#wiFoh?`!B%#H>p3(l$TGq7Z>2tdfu3db9SA@=JoBKWy zsC-U*!&cI__?J!bMUyHpt9H!|BF{#~2=72^77_)P#~a|eTgHL5&1=UDJE%Fk3BfBd zq8!=&8rY52s};u-c>yQk_D>i$QuTpB-(uXy0L9)MUwz1dEW$V@<4ETfAkkRvq-?pn z)wkYebr1Gry-JLF>g+1kx-#U}c#u>U&*hbN+Pa-{X?Fi}fzY=P$v?Ox`%+xl$doFl z_z)Z)^$hRpROaQpSNUNsRLp@A?UIzCn}w}z8@rQxccj`aeQC@vJ*n>JDJ%~-2MbX^ z3D`2j5pJ{trF^kMU!f&e*drs}8D?t()4cMjCi8B|W*pZc{l)jy*rVrjdS6hH zkc^37X~NV1s137<6#kVp=g5ctNmdOT24uIbJ5XRZBat_}Im7Zi`tM^73WHgt8%?kPDsMk za=koRb(!AS$Z+QECkFS*agI8kBJ0a(7YlGP4)!2&la3M#;&`yS$xP|uxF;QZcpP|k z&{4BZ3LFb?;*|9ly(2ZKG75=_iTMX(J&g0=T2B@H z1)wqJfrV8y6k4Y1Lv!3NxVJ;gB>mxmq8DfQUCqeeDevAb7wA5#WN$2Oqv>t! z`Su62U36mh??-(!3a|E;SmW~WDHq)68+vPPN@vJ2%EUw7xA0W7Ebl<=sUn;j*k3zXcf=rB^Wl`a`J+VjNbS?$$l88Qx6gt81EGp;)mP0jGIL6^ zMdTN&2p$r4glbBEIocM-+9Fk3eZ*94i_x?2cv(qmf7>0ZNh)DlNn_gjsD?-C`RfN& zfFyywbM-o9z>7xV?Lq2Hy@?)B#mGn2EDjXz-pqN`iZ|Mvv;2{VXv3;1Hzj4-x&lc&t6Smh5F*XT}MNmz7<0o@;Fa~pR^-OX!)vM zj)))X{dWO*SJ(GGBenaIew_9nnSLyXZU(#wT5gIL`dqY~gPEK$Ezet!Q$k!M4at}f z#8kj4?_KE*tW}n@qPn$}|43*-40Tc?^YFhlBHTRHT1BqzdB`$H3xv zW8oDGJ{qW5jV;RnJ}o(@IRzo?n2Ft&vI;2F;E*kHjbx*k4SJ-)vp#VxspIu?<{6^r z$7^*$4rx!-Vf&t5GlhID=}sQih_7X#4|v05)!6I07{+hbKjm%TSv@;3wo+n?@90Dd z9Y>C!K3!1b(YeDAi`sjQ3Cie@Ys1SrNhOTI&W&kMk}MqdQXO!lEbTFR`FP(SHE3QT z(_DF+_yKXx&LYK?qjqoAb82J7sV|@2I*dV{8qB12h&ety*Ezo{tPn|NJyUzRF-}gK zA3?nC>sm8h7uROMQ~u@d+gJ4hbTZw;(h`9yi7z0$IR-p^x1N&fhHa8pZpd0yV&t@O z$UDXf22qq&@AWkU`*=D-QkFh#RDoK`!n{L)sCe0-c z(ivIT+Jvk2O1X&UCi{lb9yIzb3HBD>P1cp|qMl`(GA_;x##BPmpvwu|yS#FhY5L+f zVs}hb%?zjn+)=_44>!~~aY+(FZEsONZAKzTkMmSZ#@%QV!L?-H&wi;IEQfjTmeCu3 z;K~L*H7~v&=6(4tT&~Y1t^@Z_Bh@wKZSzSbhWsX!d_2_aWKW+85cJo&H zl6^4|Mvx4brT zHH=z;j{3&~#bD>80&D2!-vmrgfrt9X)3qo_NCZC*g0HAy=?YA+E)qiApC7-$hMg+1 z!VVRvP$Gz6B?Q#Sf-rtXL6j(B@C_^Mu_7VO&!Kn-W@l~f?#B1+pWwyRuci8TxBmX)v|l$2;sk%H#!2(fYlxqx$ScAo73gVxP7dJX z>_3l!uRK*?S;CiLsW%9De`pCv6ye`aO3^?^wAtfmSO2n!Jo4R)sHHG-8v%Wg)VD9F{J`hIf+deS^?`4^{2tL6{-NVV@}<@gB!D}jqj`}4jHHZGcd;p# z@jJ^**%PZPPMavYD{^pu#QyBz;a6sMug~0E^-Q>J3t3}L#O5cOh9`HTn}pj=$Y|n} z>Z%0<#m48HH8gEevTWrKbSyJ^!&CI0GKttp=c}f@@0asnu;C4_A&0d+HeSc%#C3`0 zXFA5_XjAyCGxP=D7{owbmqpCt6FY+$Cw|hC491Ya^Aq^%!yM1eX^pY*{BjFS;VZrU zIK~RnFPIGPma4Ym>YfXaSPQi{zkNM(bCjfCPa0Ap{8aFsM+47|#31x3l2>F@=Gfif z3QYn6U0vaTe)l5Wl#>Ydtiher9_T|`Y!HYXNR6+HpbymD*%}IU7Vvd-iPIU@0Q$0> z{U>?q_h~;-*_mQWYz0BWf=AiCb4~?@D5aNMvn6OtDwq(TSlDm z0?#C4xUkIVS&y3YSt>WOBvi6DOrG0`P#=O41ctUNF_t@SFq@HtJE7iquI=CL<60|1 zQ&BNnva7{n&1<(+QFb*A-4V{9z)B;^#}A!brw<3f4Oc5*FMeKM5&h+`<0q6Pu>q#b zqV*n)*|R!58y{}2n4Jtg{S;8krTq!R$to2crhyc}Id_`t4A?AryA{N6FXfE`9GXg4 z=2v@8yqhz3A69!;HCeL#hIXI|-6wLc6x*&;lXR@S_xJ4s9;Dqg=zZ{1btNl|&iSX&spPjep3x_@s$g&Qdxa|=cN zBER*eOL2n7zBm{KO6aMBKYOPivGtOjtIt?W9kCi&%2JGdjt|%7q=q4xM(R3oKp;h+ z2BiNggNLV|i=D@H5k?Fb6BflNf&?dE6u)X_-X*isCx^|MV_{7ecDsePPg2@Ztvr6c zS)EgO^_kTRDQ3($_A#s4Tp?jV*unmRu=W0NcgB%yW~xdO+xPd6X>UgGmCqqI$Im_` zyq@9VQyD3~1LKAy({_voU)*z?NlHR7vkqYsen31c)$4ek-8^?QVUf|83d@3L{&|(< zf=f=b8==6{ju_#7pQYB``!r?pMnAq%QY2()o-GL6twk0x4wXR|_-ub#{|x4}4Hv&r zcDo&P3#U0F5O3V^!+?PS8vhHEv3}zni-x$IIjmy7@?w})wf;bd7Pmjngh}sL_-j~< zDGZz7xU#!TV!}~*DO3&so~c{j*f&1dz7+vZmsFXGn-nP>L<6`X*UlE)y`)alQw3B z-)6VdCftVExv0IA&GVzMCAwS87C&HReYARJL&|9`yF20L+2*xu+~NA;!$I$`cw_Ph zorbv@wcPkr=S9&G#Fgx0WwK(m50cz`yShYp@*ZYBhdHlw>#)6hC=Bdf>K9n0sOv>9rI$K) zkX?B~A^1$SZIe{~f#pS=aAnprkJ4w%$J7R>AN?#ECq1@VwK?0J z73Z_nj3@4n6=SNt-G-YWGnWX^qvRE&Ac{Z%hV{{ zJRzA|Di-2u1dL6xKU8&Aq;yYK`>Au@cV)aM(yy>MA_#gtBwM^Ga+!}piO-hgF-=F& zUSd{UcNsGayP#>%uSc$Xi%F=s9ZSVW5@c!45;qKnk06O=%VrnCtrzD}sKnMHIkaDo zX`$V7c_)9HfPEiM<5&)OLZ_ptY`~Dz@x~r%!ecjZ-QOGBpTs=sP>>Uq+m%Z&ya*=e z{M5Vg;>5K7pp68!h26h*ca*4K)fa!2be&II69_qe&|yVldfO~RE4@>g+4}L3EV9?R8fN#oJlrW zpX$2myz<-MSl`09o&CTx9^To$moH9!W$UB5?yc=XbAzu|e_FIGo;~6Id9=5&1l!9?D=g(aX<>QVCFPRm)_Iw- zdWrJ%^T?VB#`KzF&QOb`y9dW-d+{j}9#l&*>)Q?6!sUl+Q!Nq?!#w9TbH$cr@;FKo zl@In$4|j%3(`Yi6T`&E|E-r0-4!r6yt*uM0or8)wxy6h>yigZX5&W3S7M+8i>sB87 zGKFn_d+@@{zh;Pb>3lc!>)zsC z)VapDnRl3|$<`FV&lm8$tdYI#bw9%s68E$I2Bw3z0Twee@EN~yA6C`v%PX%MCO-GA zR|Bx1By#BIJc|yLN+~tH>E-v~FZ;{0Jr*nk{hdR!3JJDdO13|end+Yoog*!}f-*#4 zOzkPmn0K}ET?x#m8H;0S9wq(_D9rwryZq2DLI{e+jmt$;}ugUD`Gt)S8fO~g}p3p(yW=j*>p1a&d#VrSN3y6@l)BFN0W=3 zX-@gUSlT$G#L*1TjAW-Z5{aWt(tb+&)q4BaYYNb0?7@A|w&^q!UP2=z(GYrCJcXPa z!`Ovlmin^O_*Ep)3n6_`f_Y6oP6WwelAXFwUsL1m=a_sczLR9=6af!YGT(;aWx(2X zNYbfa?yKy|>%1PSv{>}x;NNQ+S56Z^du&lXmUBj(&n!+7sCcC0`0m=FUk@h?)J7@1 zqn-)U)_L-@L3t_Z+_ZL@dxq-{I>m{W!b`DjY9lvTfBr;jlPd@ZF3FGSO%;ooQQG&@(Ah9Sy%ND4?%Q zX(`JD50gYU-n)}T6m5$wl<`Yz=tGA${Y6UNFTHg^Ycf#@zYc%X233}_%p89*E(uBz ziN`!*zpn7eyV0S~ciCG4*C!*mlurQXb{-$`WyzY*ZfRaLw{`nQT%X z=YZFWGQ;i?f$tN|7yy!VpBzH}HuojJT=hm;ZlG2|BQd9A(DmSL~NF}~}6 z1gA=acN|Vbh7PHM&kBm1mRAD^d>Lv3~GSzQf~^3ZEa(b+#HDXOl$ktR&H8^QKt2p0w0}o*4>zgT3^}IWz?s+U;iR} zAI;p;H)i=&o{n)K3jBGYkeAA|yhPmSHf&~Lk|45Lz1jo_PcRciLzAV)98;wqWkpsi1De!u^F2c{3ajP-$Nu$^J^cKyZbNK<)3p`=bru5 z;+#nJXKtCvA(pH@IB7U!ZiEik8yWFvzhMTWyB% z;oC2WKq5n)xENY zeU8*vpb!MRMoR3sWsfM7D-IulO|1-O7Tw+NZSuTpRu66qktg^lv=h0tJJ;_e@5A2m zN#)l^Q#pX{S)O)?8Y5UG)*i-DP;VL^IJC=&Ex$QBUa9=54|X{?+> z`noZ7HPZ$bREq3D46bZFxC!dw@A+%HQL}TmA@Odek zNw>l+KPwvaN~eFO3^HZ$6xSsP(%Lm_{igO@VMs4l&3Af+t#D{Mq#S4J-#f5u>;5x1 z;Rqot{XUq=^1s`UZ1;wW1a29)oF{UhgS8CkJm}3Z6`;Z6MTea){l89Va&eWM=&{U_ zFD=apZOv{!I$EeY*O5GbZkz;=h*9k;1OGvk8=$0SV(_Z*%2|8GNjGY5%+&Q2934h$&`(bh$ ze4q&jE6yeD!KSGnH~Sj?xV`Ds$$Gj%R%JIwfye9<;hQV1BdTyj>o}if$%e-7A_nV2 z!%DPmW%+%(V1J-h*WWWh6h5 z;z)Rq4ovR}^DOmrh98xL{zm>-VOc`v_#|U%#Ol$7M^M*dMOi}Z*h1EMYHnpqXbDSO z_WB2cCaXzu=Gf}Sb5H+}`Z9pFi~-uJ(oQK6jg9*w@c4A^83L&dA3;3VyB$sZiv_++opJE96cZny{9Ht{`1R8Z@U zIbegK5DzT}Z9Rut);60&aRmqK{wDl`q{vO;cVcP`Y_c?A^;L>d!*2n4HYwtI5D{fcft1-vTfM9>&^|}Sxi9TwHmUoIH z8=OJ!8Nwh%g_!HDT=uOCV;y9KVMb(g9+ow5RW!^}?5>)GB0qL3$$N(5G1dx*mar}e zC-W+V)K?J)jaGD?zA+rh*Gc^dz_>=+_M50n^j6O7lOTlq-rhW!w63-xlO6Oc>4%vZ zSO!m-E)IfB4JVxg%x}5S?HRI#J$1k_5V24zT?P;b;d=%wVSIb+bzwYv{1K)R2Q2iT z;>1u$V&t+41m;eOB;-k|Qjy1fQ{Sk_nfq?$S@hWxpH1nvhn$tS=P8z$Kg-GMX-cl8 zp;rv!Wy&g(|85!Bf7Jsh2U56{d;}CHitDA=9T%Drf>D#pp)V6A@cOqb0+F5gBqu3) zPDJa=-fOU8I0fWN_^Ljr{GIz+ijo56d5Wng6=@^r5;@GLjPsf0rqlOEct9)koa4*?5K)kzo1|cl&0!XEk08`aoq1NmP!52|gd6Bynzf@ZG}ivYzh01jSW>(# zqHuI+3B;ar;qBJz7>xR1+HqI|H6q`+d+{+$dG=c@a6?^XlrMGEgTn6jF0 z3Raw(wY9fi{MyY!uVcIq?$kyuceeWaoUXx9YiAKrP$u-4-Z6*okb$_iVMw_@)o$3o z3iF?JiJ2v^{|yOtsC57Y-;2XiT35>fAFVPXmxBjZwKTAlcGlulmW<{1Oui@T?S0o+ zuZU~diF#(Bub~m3h!^o}?6p?6QtZ7x*{wW2RhpsDZ{Q7}%5wd)9T;bv;6W0CKqc@* zX&*U8gObWPj17u<0nf#j{PAU<=>2^LF$G7VCt`hvNfoRW9QvKl6=~0orc#}~dY@h| z@-uSteQd^m(=6812}g4zj+Vow`c5FrUqJG*&mUu&HU>4|+T*P^;CmIb(&EZTXfYJR z`s|H%yw5W`$HtO?(_SY(ZMfVcu(j$jTe}YEWXjC~G1m)Z*bE;wh zdx7)t!RnSK-HoAJpeZ~Af!cD`9E4mprvP9SPuvl@bfWa}zo-mrgfg8beVkz$;4p03 z#T&qx^$B4^^$g4cB+k@!jsU0DXzQiShLhg!cyU&ysUz@-e;K2xGd9CKX$RdO-Ro#` ztOG1r)}68njsLALKo^2PQcTnTKK2N8dWJaCcC;fVXPgB55eQD_Od2QBcTpRbUHL;v z9+&Ht(+-R}Ic+4LlE^u^L=<95J3H4rsA?}>igQNWX{!O{kO6?OH~|3RV=G@?PqASV zQoaJDi-!QHH2ohZ=NCdNPM9ZYpUn{1YuQfo$YSBe0@epUH_!mI>`%O!epA_3q}_8C=snz#EA!T^^cu+?bN zfrMNBL+)Az%J8Rog`5Q8E|N@7{>DY5k(TmOO7`nI6?wk0;xQwP*1H0nj?)5vzZGZ8K)N+bLqyu)Vo z8^V7dduwT_A5b3)-%eKZvf8*5!R#1u1^A|nFpQy)8T`9n*o=YCfSHslOi{C zlOM*0Mf#R^Gb#<2S?+^Tt>LWQ?`&KWG5idBAw!5|`ok(<^ zg9RW!|1XPWU$fYLz>5O60TygwZ2KD{xasBM$b;vwb#<4Zb;~NevIbl)gU@~I?f72F zFZ21zk!I>V#X6}oa}bWlRx_O1*IiV~SMy;du04`eoA&$<-oD}A@U=|oh;enghApzB z97~tLMl{3`dkPytsz#750G5JUJ81ld4)I8ne`SD?3`^I{& zab>;T06H)ZLmG5f^%zZ3>{kL4x&qV)KmAQvv*XHCCpx*-R zG0bO_)5f8gDmiAyXgmvMZRjyj17H`w^I!Qv=nv_4hB zfH+_rsfRKlhN+rXIy70(>r7y#s`Mr;95~9z6rDj+ha9k9hUgAhqd}5(OI~A-5wm66 z=Wm9a9gyzuLxDt<4S%NQ0ru{;>-%PXdcUuB# z)m=rxQCv%3EZ!!vKAzNJtm@Gy%sYxKOMzU$`I?dZN#fM6RLYxDj+LmDYudvSZd=Z= ztc3|~CgSCZ42#2@>hofJGxmSj9hhhF1f+atVwqksxE9a7b#qNm;n+e5UG;yteTm0s zpK)K6NeeOp_6E3fJ?H^Uc#Bv+fF8+fZwV3Bav($V#iGkfb4$eCSv`L+$Leb{zsYS9 z$6W9{i#!{gxbkf~d=zEP%Ma_I$iJ2*Q5|ko=SCgcSuPb!|g9OSun4bYR%mZD*3%f^3DH6CI^eJ5@!fXZwOi_S%fIG&J!N(4(c z6I+-)e3Zz8L7mw?xZn?d$95A$P{Sz|>Eh z-{LnTrS5lRopo)-?5%&VP4>wpCYP~2;V2|}4W)cPg_VmFRhg}eE zhJUaT`Pp~tCCE-W-T?4H(u9$`H!2}EYr-^!+|920l=B5R&h*|rhqQZFg(PhfoxK8O zpC52pKvGzOuZAYX^es3|VKW-exHCO*|B#dGyC)dTKU?Q?RE`%OO7|R~5 z4%<=7z6Rq%I_KZE^o=<3VJ*<@F9ocTq;TN&Jpw2X(kn%gFmm{}E1lhZu4rz?E*Wr% zoZqPsM`a1--G&A)9=hcQqXK-TF|8PZ+Ti8RB-Oc6)beC)W&3$>OHd#tr=0}jg<5p| z-XL=^_bG5uvILg=FlgCL(Py4z%yenc{-l3(aCLNb-O>FdZ*)V~ICgg`=X{D!9EIBL z-I(g%o!Z-4cjH_QYCi+MlPEu`_T(X#K65@hJR82-b>0QnQgi}FX+B6@xu7=w8#Q5P4@{^|G;7Qt;d6ulbC_rx{NDzfom!;n8R zgU-R_+xC6U`ckB~v(_=rbRT^Z*W7erpJ6g-H0&}bQA>!G@m_f&8J3~ZpbMka(LHWS z83`1jPnIi9+}^REes8d#!2Gys)5Vbvy69OT{RqdAx0s`SLbhRR-pf%J%H~4xpG~85 z!}lm#th1`_);A^CQpw*T#PmHEc2H7*6JH8JO-DR|(*oP12f`&GV1i9&xo;>8_p8YL zmR~t!$>c}0*?+ubTV>+OGYnDS>ucYJ48=>NktK+M{6tUL;6}W9-qJDoR;c*t zi`xw@8q=U~kvfwR_EUr6`q|9&B$XPNW{z{L3mZeVqm`in*l3CzUb-LSmx6Ytb4<*a z6@HV2yYN6H-=B*&N3oo%5y41b(kfS?pc>|kmqu`l#9e)gM_kgv8YE)JG0TDVX4;X7 zm%dmSxt4M_znk$DHQ@^Az5|Fw)Nv2nx3^f8J~W=KA(`b5e56o~Ts+ z@w^Gqkcak)_Q4N#zgT^ImC=R34_vgBy;SWEd>ZY>gH~V6zgj)-Q&?yBH3`-n=6ch9 zf~%R$>G{=&o~b_7VBZv3BS~)xOFcFkoa>%+%RAcE)t_ye8+>R(R&X$|*dG@E{*jZT z=V@T6bmOO|?CoEk+Pb>+5xZCW1ZJWLC$3DNh-5AgRZg)#r#VdMmOLiH>efCX8PHDD zeD#AYMp^2S%n6_#!m^xw^?@E3!AgkD`H=-HmjnqSmY_86TZ*IKKldly}7Xee=ABS*RzDsc~ zOPwSK`ssNc5`EN<7oboljFo+*Xy9*{pEk91iuB^T33xNnkDZ{e^te&g)(Hwl$e9>`SP63ZFfm-)YQx;jMpFg&DefEXy&w~?oD>` zJFm5+2zw$2mWQ0Zuj-5ogzkCXgg?$sBJHpeerx~g#BH{}xNZIri^wwcWIZ8Y1-?u^Zg9*RhE@na`^ufmtH%hB}Qqz<8CM<|>#X z;ydq87PjT`sj!I(_c(*PXq;#j{^z%|m2FlQk{qHnUEB=F~7yK}JedF-io_5!XhU_&=L?3^VAX3s*8s~A|11JV2KWqt+ z_BYwh#I2giL%jG1Dm6q0I9umyy*T!9p5T5+tzY=G(C<~M55&-YuA&4h%8=X0@C)G^ zNwR7FM=gzbb4n&nlF$#&qv_{Q8k;i)%tPvWxfMu0gl)W>nLo9+Kt;kHpf@Ni$`x&O zgy>IKI+^^VnxtkMI#_9JY;H}2-?fVSqkiZ0?Fu}F%UeHl3pRFNJP6}ltoFdg#GF}Q z9I~DDh=!epy>PhTl@hCbP8t^_ni%C|EZ-+|F(M~JHto9b+|z78pENjrt>?gOGvRA_ zSD=(s-Zuxo)9*cMgRAk|*yJF1fiW%d-;;*$9%F4tEr16LcRLpkL4oVvTB=ys{Gh+* z68}9S2fU2|7)1K}F#}gK;b;8sd9lB*lfzR?*qHu%km>L1g~aeEQx;$lg5t*Ce|$v- zFQ;V05`tTr(8IGR|9L5a9Jq83?r1^*Uw+Df{h9(UXG(KDH~}AjN&(DGFkrV)!B>cB z;2S0sOn*;LfIxJAFAqF}F#wQ!2@ll13rCsJ{C-I)1H9yhJDX7`{2K~D8Y%u` iwF9|-tY-E6`SqNKmMR|p^_$3nA4*&hs8-?n)&Bt~;r)XE diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index d455da541c..af16c31403 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -374,9 +374,24 @@ S_TZ_M F_TZ_MM +C_DT_DIGIT 0-9 +C_DT_ALPHA a-z, A-Z +C_DT_SLASH / +C_DT_DASH - +C_DT_PLUS + +C_DT_COLON : +C_DT_DOT . +C_DT_T T +C_DT_W W +C_DT_Z Z +C_DT_ILLEGAL all the rest +C_DT_EOF EOF + sep: / | - +digit: 0-9 letter: a-z, A-Z sign: + | - +eof: EOF S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->"/"->F_DT_YEARL \ \ \ \->"-"->F_DT_YEAR2 From 07c82c0aea37490495bab29e51fb9dff5e11fa3a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 24 Oct 2019 16:47:06 +0800 Subject: [PATCH 0318/3432] FIX: set widget color --- modules/view/backends/gtk3/draw.reds | 9 +- modules/view/backends/gtk3/font.reds | 165 +++++++++++++++++++---- modules/view/backends/gtk3/gui.reds | 15 +-- modules/view/backends/gtk3/handlers.reds | 67 ++++----- 4 files changed, 182 insertions(+), 74 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index da1e98c671..e8f712aa33 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -535,7 +535,7 @@ draw-text-at: func [ ] draw-text-box: func [ - dc [draw-ctx!] + cr [handle!] pos [red-pair!] tbox [red-object!] catch? [logic!] @@ -566,8 +566,8 @@ draw-text-box: func [ int: as red-integer! block/rs-head state layout: as handle! int/value - cairo_move_to dc/raw as-float pos/x as-float pos/y - pango_cairo_show_layout dc/raw layout + cairo_move_to cr as-float pos/x as-float pos/y + pango_cairo_show_layout cr layout ] OS-draw-text: func [ @@ -580,9 +580,8 @@ OS-draw-text: func [ either TYPE_OF(text) = TYPE_STRING [ draw-text-at dc/raw text dc/font-attrs dc/font-opts pos/x pos/y ][ - draw-text-box dc pos as red-object! text catch? + draw-text-box dc/raw pos as red-object! text catch? ] - true ] diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index fbcbd6bd21..6730e5f8e5 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -22,20 +22,87 @@ set-default-font: func [ unless null? default-attrs [ pango_attr_list_unref default-attrs ] - default-attrs: pango_attr_list_new - attr: pango_attr_family_new name - pango_attr_list_insert default-attrs attr - attr: pango_attr_size_new PANGO_SCALE * size - pango_attr_list_insert default-attrs attr + default-attrs: create-simple-attrs name size null unless null? default-css [ g_string_free default-css true ] - default-css: g_string_sized_new 64 - g_string_append default-css "* {" - g_string_append_printf [default-css { font-family: "%s";} name] - g_string_append_printf [default-css { font-size: %dpt;} size] - g_string_append default-css "}" + default-css: create-simple-css name size null +] + +create-simple-attrs: func [ + name [c-string!] + size [integer!] + color [red-tuple!] + return: [handle!] + /local + list [handle!] + attr [PangoAttribute!] + rgb [integer!] + alpha? [integer!] + r [integer!] + g [integer!] + b [integer!] + a [integer!] +][ + list: pango_attr_list_new + attr: pango_attr_family_new name + pango_attr_list_insert list attr + attr: pango_attr_size_new PANGO_SCALE * size + pango_attr_list_insert list attr + + if all [ + not null? color + TYPE_OF(color) = TYPE_TUPLE + ][ + alpha?: 0 + rgb: get-color-int color :alpha? + r: 0 g: 0 b: 0 a: 0 + color-u8-to-u16 rgb :r :g :b :a + attr: pango_attr_foreground_new r g b + pango_attr_list_insert list attr + attr: pango_attr_foreground_alpha_new a + pango_attr_list_insert list attr + ] + list +] + +create-simple-css: func [ + name [c-string!] + size [integer!] + color [red-tuple!] + return: [GString!] + /local + css [GString!] + rgb [integer!] + alpha? [integer!] + r [integer!] + g [integer!] + b [integer!] + a [float!] +][ + css: g_string_sized_new 64 + g_string_append css "* {" + g_string_append_printf [css { font-family: "%s";} name] + g_string_append_printf [css { font-size: %dpt;} size] + + if all [ + not null? color + TYPE_OF(color) = TYPE_TUPLE + ][ + alpha?: 0 + rgb: get-color-int color :alpha? + b: rgb >> 16 and FFh + g: rgb >> 8 and FFh + r: rgb and FFh + a: 1.0 + if alpha? = 1 [ + a: (as float! 255 - (rgb >>> 24)) / 255.0 + ] + g_string_append_printf [css { background-color: rgba(%d, %d, %d, %.3f);} r g b a] + ] + g_string_append css "}" + css ] set-label-attrs: func [ @@ -255,14 +322,14 @@ create-css: func [ if TYPE_OF(color) = TYPE_TUPLE [ alpha?: 0 rgb: get-color-int color :alpha? - b: rgb >> 18 and FFh - g: rgb >> 16 and FFh + b: rgb >> 16 and FFh + g: rgb >> 8 and FFh r: rgb and FFh a: 1.0 if alpha? = 1 [ a: (as float! 255 - (rgb >>> 24)) / 255.0 ] - g_string_append_printf [css { color: rgba(%d, %d, %d, %.1f);} r g b a] + g_string_append_printf [css { color: rgba(%d, %d, %d, %.3f);} r g b a] ] ;-- ? GTK3 warnings @@ -309,14 +376,14 @@ create-css: func [ if TYPE_OF(color) = TYPE_TUPLE [ alpha?: 0 rgb: get-color-int color :alpha? - b: rgb >> 18 and FFh - g: rgb >> 16 and FFh + b: rgb >> 16 and FFh + g: rgb >> 8 and FFh r: rgb and FFh a: 1.0 if alpha? = 1 [ a: (as float! 255 - (rgb >>> 24)) / 255.0 ] - g_string_append_printf [css { background-color: rgba(%d, %d, %d, %.1f);} r g b a] + g_string_append_printf [css { background-color: rgba(%d, %d, %d, %.3f);} r g b a] ] ] @@ -446,6 +513,9 @@ make-font: func [ font [red-object!] return: [handle!] ][ + if TYPE_OF(font) <> TYPE_OBJECT [ + return null + ] make-css face font make-attrs face font ] @@ -475,7 +545,7 @@ get-attrs: func [ /local hFont [handle!] ][ - if TYPE_OF(font) <> TYPE_OBJECT [return default-attrs] + if TYPE_OF(font) <> TYPE_OBJECT [return null] hFont: get-font-handle font 0 if null? hFont [hFont: make-attrs face font] hFont @@ -488,7 +558,7 @@ get-css: func [ /local css [GString!] ][ - if TYPE_OF(font) <> TYPE_OBJECT [return default-css] + if TYPE_OF(font) <> TYPE_OBJECT [return null] css: as GString! get-font-handle font 1 if null? css [css: make-css face font] css @@ -520,17 +590,29 @@ set-font: func [ values [red-value!] /local font [red-object!] + color [red-tuple!] hFont [handle!] + newF? [logic!] css [GString!] - state [red-block!] - handle [red-handle!] + newC? [logic!] type [red-word!] sym [integer!] label [handle!] ][ font: as red-object! values + FACE_OBJ_FONT + color: as red-tuple! values + FACE_OBJ_COLOR hFont: get-attrs face font + newF?: false + if null? hFont [ + newF?: true + hFont: create-simple-attrs default-font-name default-font-size color + ] css: get-css face font + newC?: false + if null? css [ + newC?: true + css: create-simple-css default-font-name default-font-size color + ] type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol case [ @@ -556,6 +638,40 @@ set-font: func [ apply-css-styles widget css ] ] + if newF? [ + free-pango-attrs hFont + ] + if newC? [ + free-css css + ] +] + +set-css: func [ + widget [handle!] + face [red-object!] + values [red-value!] + /local + font [red-object!] + color [red-tuple!] + css [GString!] + newC? [logic!] + handle [red-handle!] + type [red-word!] + sym [integer!] + label [handle!] +][ + font: as red-object! values + FACE_OBJ_FONT + color: as red-tuple! values + FACE_OBJ_COLOR + css: get-css face font + newC?: false + if null? css [ + newC?: true + css: create-simple-css default-font-name default-font-size color + ] + apply-css-styles widget css + if newC? [ + free-css css + ] ] update-font: func [ @@ -588,20 +704,13 @@ make-styles-provider: func [ g_object_set_qdata widget gtk-style-id prov ] -get-styles-provider: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget gtk-style-id -] - apply-css-styles: func [ widget [handle!] css [GString!] /local prov [handle!] ][ - prov: get-styles-provider widget + prov: g_object_get_qdata widget gtk-style-id gtk_css_provider_load_from_data prov css/str -1 null ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 159682fa86..e32d291535 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -723,13 +723,12 @@ change-color: func [ ][ t: TYPE_OF(color) if all [t <> TYPE_NONE t <> TYPE_TUPLE][exit] - ;-- TBD: need to be improved face: get-face-obj widget values: object/get-values face font: as red-object! values + FACE_OBJ_FONT free-font font - make-font null font - set-font widget face values + make-font face font + set-css widget face values ] change-pane: func [ @@ -800,7 +799,7 @@ change-font: func [ face [red-object!] values [red-value!] ][ - set-font widget face values + set-css widget face values ] change-offset: func [ @@ -1713,6 +1712,7 @@ OS-make-view: func [ ;-- store the face value in the extra space of the window struct assert TYPE_OF(face) = TYPE_OBJECT store-face-to-obj widget face + make-styles-provider widget change-font widget face values if sym <> window [ @@ -1735,17 +1735,10 @@ OS-make-view: func [ change-para widget face para font sym change-enabled widget enabled?/value sym - make-styles-provider widget - parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym ; save the previous group-radio state as a global variable group-radio: either sym = radio [widget][as handle! 0] - ;; TODO: NOT SURE the if is necessary! - if sym <> base [ - change-font widget face values - ] - if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] stack/unwind diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 1917db5c82..0f636a0554 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -85,12 +85,15 @@ button-toggled: func [ render-text: func [ cr [handle!] + face [red-object!] size [red-pair!] values [red-value!] /local text [red-string!] + color [red-tuple!] font [red-object!] attrs [handle!] + new? [logic!] para [red-object!] flags [integer!] layout [handle!] @@ -107,9 +110,14 @@ render-text: func [ text: as red-string! values + FACE_OBJ_TEXT if TYPE_OF(text) <> TYPE_STRING [exit] - + color: as red-tuple! values + FACE_OBJ_COLOR font: as red-object! values + FACE_OBJ_FONT - attrs: get-attrs null font + attrs: get-attrs face font + new?: false + if null? attrs [ + new?: true + attrs: create-simple-attrs default-font-name default-font-size color + ] ;; DEBUG: print ["render-text: " cr lf] para: as red-object! values + FACE_OBJ_PARA @@ -151,6 +159,10 @@ render-text: func [ pango_cairo_show_layout cr layout cairo_stroke cr cairo_restore cr + + if new? [ + free-pango-attrs attrs + ] ] base-draw: func [ @@ -160,38 +172,38 @@ base-draw: func [ widget [handle!] return: [logic!] /local - vals [red-value!] + face [red-object!] + values [red-value!] draw [red-block!] - clr [red-tuple!] img [red-image!] size [red-pair!] type [red-word!] + font [red-object!] + color [red-tuple!] sym [integer!] pos [red-pair! value] DC [draw-ctx! value] drawDC [draw-ctx!] ][ - ;; DEBUG: print ["base-draw " widget " " gtk_widget_get_allocated_width widget "x" gtk_widget_get_allocated_height widget lf] - - vals: get-face-values widget - img: as red-image! vals + FACE_OBJ_IMAGE - draw: as red-block! vals + FACE_OBJ_DRAW - clr: as red-tuple! vals + FACE_OBJ_COLOR - size: as red-pair! vals + FACE_OBJ_SIZE - type: as red-word! vals + FACE_OBJ_TYPE + face: get-face-obj widget + values: object/get-values face + img: as red-image! values + FACE_OBJ_IMAGE + draw: as red-block! values + FACE_OBJ_DRAW + size: as red-pair! values + FACE_OBJ_SIZE + type: as red-word! values + FACE_OBJ_TYPE + font: as red-object! values + FACE_OBJ_FONT + color: as red-tuple! values + FACE_OBJ_COLOR sym: symbol/resolve type/symbol - if TYPE_OF(clr) = TYPE_TUPLE [ - ;; DEBUG: print ["base-draw color" (clr/array1 >>> 24 and FFh) "x" (clr/array1 >> 16 and FFh ) "x" (clr/array1 >> 8 and FFh ) "x" (clr/array1 and FFh ) lf] - - ;;; OLD and DOES NOT WORK - ; cairo_save cr - ; set-source-color cr clr/array1 - ; cairo_paint cr ;-- paint background - ; cairo_restore cr - ;cairo_save cr - gtk_render_background gtk_widget_get_style_context widget cr 0.0 0.0 as float! size/x as float! size/y - ;cairo_restore cr + if TYPE_OF(color) = TYPE_TUPLE [ + free-font font + make-font face font + set-css widget face values + gtk_render_background + gtk_widget_get_style_context widget + cr + 0.0 0.0 + as float! size/x as float! size/y ] if TYPE_OF(img) = TYPE_IMAGE [ @@ -202,21 +214,17 @@ base-draw: func [ ] case [ - sym = base [render-text cr size vals] + sym = base [render-text cr face size values] sym = rich-text [ - ;; DEBUG: print ["base-draw (rich-text)" widget " face " get-face-obj widget lf] pos/x: 0 pos/y: 0 - init-draw-ctx :DC cr - draw-text-box :DC :pos get-face-obj widget yes + draw-text-box cr :pos get-face-obj widget yes ] true [] ] either TYPE_OF(draw) = TYPE_BLOCK [ - ;; DEBUG: print ["do-draw in base-draw" lf] do-draw cr null draw no yes yes yes ][ - ;; DEBUG: print ["base-draw: draw not a block" lf] system/thrown: 0 drawDC: declare draw-ctx! ;@@ should declare it on stack draw-begin drawDC cr null no no @@ -225,7 +233,6 @@ base-draw: func [ draw/header: TYPE_NONE draw-end drawDC cr no no no ] - ;; DEBUG: print ["base-draw " widget lf] false ] From d82dedde4379ea43a481f75c1891eb44b7d09b5b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 25 Oct 2019 11:02:15 +0800 Subject: [PATCH 0319/3432] FIX: widget focus issues --- modules/view/backends/gtk3/gtk.reds | 4 +++ modules/view/backends/gtk3/handlers.reds | 33 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 9cb89abe36..e783aeb6b7 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1385,6 +1385,10 @@ GPtrArray!: alias struct! [ gtk_widget_grab_default: "gtk_widget_grab_default" [ widget [handle!] ] + gtk_widget_has_grab: "gtk_widget_has_grab" [ + widget [handle!] + return: [logic!] + ] gtk_widget_set_size_request: "gtk_widget_set_size_request" [ widget [handle!] width [integer!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 0f636a0554..79b3b5a163 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -234,6 +234,10 @@ base-draw: func [ draw-end drawDC cr no no no ] + if null? gtk_container_get_children widget [ + return true + ] + false ] @@ -514,8 +518,24 @@ focus-in-event: func [ evbox [handle!] event [handle!] widget [handle!] + return: [logic!] + /local + face [red-object!] + values [red-value!] + type [red-word!] + int [red-integer!] + sym [integer!] ][ + face: get-face-obj widget + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + int: as red-integer! values + FACE_OBJ_SELECTED + sym: symbol/resolve type/symbol + change-selection widget int sym make-event widget 0 EVT_FOCUS + + if sym = window [return false] + true ] focus-out-event: func [ @@ -523,8 +543,21 @@ focus-out-event: func [ evbox [handle!] event [handle!] widget [handle!] + return: [logic!] + /local + face [red-object!] + values [red-value!] + type [red-word!] + sym [integer!] ][ + face: get-face-obj widget + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol make-event widget 0 EVT_UNFOCUS + + if sym = window [return false] + true ] area-changed: func [ From 9d25dd7e31bb4f07df1f18bcb76ddd50c486467b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 25 Oct 2019 11:40:22 +0800 Subject: [PATCH 0320/3432] FIX: some css style can't work for text for example: `text-decoration: underline;` and `text-decoration: line-through;` --- modules/view/backends/gtk3/draw.reds | 5 +---- modules/view/backends/gtk3/font.reds | 12 ++++++++++-- modules/view/backends/gtk3/gtk.reds | 5 +++-- modules/view/backends/gtk3/gui.reds | 4 ++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index e8f712aa33..db53fabc7d 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -498,9 +498,6 @@ OS-draw-ellipse: func [ do-paint dc ] -;;; TODO: Remove this when pango-cairo is the only choice! SOON! -; pango-font?: yes ; switch to yes to switch to pango-cairo instead of toy cairo - OS-draw-font: func [ dc [draw-ctx!] font [red-object!] @@ -527,7 +524,7 @@ draw-text-at: func [ layout: pango_cairo_create_layout cr pango_layout_set_text layout str -1 pango_layout_set_attributes layout attrs - pango_cairo_context_set_font_options layout opts + pango_cairo_context_set_font_options pango_layout_get_context layout opts pango_cairo_update_layout cr layout pango_cairo_show_layout cr layout g_object_unref layout diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 6730e5f8e5..f6e71e9675 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -114,7 +114,10 @@ set-label-attrs: func [ int [red-integer!] angle [integer!] ][ - unless null? font [ + if all [ + not null? font + TYPE_OF(font) = TYPE_OBJECT + ][ values: object/get-values font int: as red-integer! values + FONT_OBJ_ANGLE @@ -625,7 +628,12 @@ set-font: func [ sym = radio ][ label: gtk_bin_get_child widget - set-label-attrs label font hFont + ;-- some button maybe have empty label + either g_type_check_instance_is_a label gtk_label_get_type [ + set-label-attrs label font hFont + ][ + apply-css-styles widget css + ] ] sym = field [ gtk_entry_set_attributes widget hFont diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index e783aeb6b7..aa9b2aa425 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1690,6 +1690,9 @@ GPtrArray!: alias struct! [ label [c-string!] return: [handle!] ] + gtk_label_get_type: "gtk_label_get_type" [ + return: [integer!] + ] gtk_label_get_text: "gtk_label_get_text" [ widget [handle!] return: [c-string!] @@ -2894,5 +2897,3 @@ start-resize-id: g_quark_from_string "start-resize-id" #define GET-RESIZING(s) [g_object_get_qdata s resizing-id] #define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] #define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] -#define SET-CSS(s d) [g_object_set_qdata s css-id d] -#define GET-CSS(s) [g_object_get_qdata s css-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e32d291535..b271b7b84f 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -728,7 +728,7 @@ change-color: func [ font: as red-object! values + FACE_OBJ_FONT free-font font make-font face font - set-css widget face values + set-font widget face values ] change-pane: func [ @@ -799,7 +799,7 @@ change-font: func [ face [red-object!] values [red-value!] ][ - set-css widget face values + set-font widget face values ] change-offset: func [ From c24d0f483c67a13b3908a835edc1188ba709c147 Mon Sep 17 00:00:00 2001 From: loziniak Date: Fri, 25 Oct 2019 14:49:10 +0200 Subject: [PATCH 0321/3432] FEAT: field's no-border flag --- modules/view/backends/gtk3/gtk.reds | 4 ++++ modules/view/backends/gtk3/gui.reds | 16 +++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 4599ac4c2e..9cc3fbdd09 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1726,6 +1726,10 @@ GPtrArray!: alias struct! [ text [c-string!] len [integer!] ] + gtk_entry_set_has_frame: "gtk_entry_set_has_frame" [ + entry [handle!] + has-frame [logic!] + ] gtk_editable_select_region: "gtk_editable_select_region" [ entry [handle!] start [integer!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 0ad7549521..5594a6bb41 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1862,6 +1862,7 @@ OS-make-view: func [ gtk_entry_set_width_chars widget size/x / font-size? font set-hint-text widget as red-block! values + FACE_OBJ_OPTIONS if bits and FACET_FLAGS_PASSWORD <> 0 [gtk_entry_set_visibility widget no] + gtk_entry_set_has_frame widget (bits and FACET_FLAGS_NO_BORDER = 0) ] sym = progress [ widget: gtk_progress_bar_new @@ -2022,6 +2023,7 @@ OS-update-view: func [ s [series!] widget [handle!] flags [integer!] + flags-flags [integer!] type [integer!] ][ ;; DEBUG: print ["OS-update-view" lf] @@ -2075,13 +2077,13 @@ OS-update-view: func [ change-selection widget int2 type ] if flags and FACET_FLAG_FLAGS <> 0 [ - flags: get-flags as red-block! values + FACE_OBJ_FLAGS - if all[ - type = field - flags and FACET_FLAGS_PASSWORD <> 0 - ][ - ;; DEBUG: print ["password flag activated for field" lf] - gtk_entry_set_visibility widget no + flags-flags: get-flags as red-block! values + FACE_OBJ_FLAGS + if type = field [ + if flags-flags and FACET_FLAGS_PASSWORD <> 0 [ + ;; DEBUG: print ["password flag activated for field" lf] + gtk_entry_set_visibility widget no + ] + gtk_entry_set_has_frame widget (flags-flags and FACET_FLAGS_NO_BORDER = 0) ] ] if flags and FACET_FLAG_DRAW <> 0 [ From 2228bdbd0edd250ff0ecb73f98f859ca78db74d1 Mon Sep 17 00:00:00 2001 From: loziniak Date: Fri, 25 Oct 2019 14:50:25 +0200 Subject: [PATCH 0322/3432] CHORE: whitespace cleaning --- modules/view/backends/gtk3/gtk.reds | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 9cc3fbdd09..54287a266e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -948,10 +948,10 @@ GPtrArray!: alias struct! [ ] gdk_window_get_device_position: "gdk_window_get_device_position" [ window [handle!] - device [handle!] - x [int-ptr!] + device [handle!] + x [int-ptr!] y [int-ptr!] - mask [handle!] + mask [handle!] return: [handle!] ] gdk_window_invalidate_rect: "gdk_window_invalidate_rect" [ @@ -2665,12 +2665,12 @@ GPtrArray!: alias struct! [ ] pango_parse_markup: "pango_parse_markup" [ markup_text [c-string!] - length [integer!] - accel_marker [integer!] ;gunichar=guint32 - attr_list [handle!] ;[pointer! [handle!]] - text [handle!] ;[pointer! [c-string!]] - accel_char [integer!] ;gunichar=gunit32 - error [handle!] + length [integer!] + accel_marker [integer!] ;gunichar=guint32 + attr_list [handle!] ;[pointer! [handle!]] + text [handle!] ;[pointer! [c-string!]] + accel_char [integer!] ;gunichar=gunit32 + error [handle!] return: [logic!] ] pango_attr_list_new: "pango_attr_list_new" [ @@ -2679,14 +2679,14 @@ GPtrArray!: alias struct! [ pango_attr_list_ref: "pango_attr_list_ref" [ attrs [handle!] return: [handle!] - ] + ] pango_attr_list_unref: "pango_attr_list_unref" [ attrs [handle!] - ] + ] pango_attr_list_copy: "pango_attr_list_copy" [ attrs [handle!] return: [handle!] - ] + ] pango_attr_list_insert: "pango_attr_list_insert" [ attrs [handle!] attr [PangoAttribute!] From 068b27438b7621b722851c231a84058a95d4c9a5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 25 Oct 2019 14:56:50 +0200 Subject: [PATCH 0323/3432] FEAT: various fixes and improvements to date! parsing FSM. --- docs/lexer/lexer-FSM.xlsx | Bin 24085 -> 26363 bytes docs/lexer/lexer-states.txt | 28 +++++++++++----------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 62fc3bb5d890ffecf2dcef842af75599b8ee7ca9..99449a22eedca1b11271c005c8b370161d5e00bd 100644 GIT binary patch literal 26363 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 literal 24085 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 Nr~{k!g&L2q{y(1f4v_!= diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index af16c31403..cd04a511d5 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -338,9 +338,6 @@ S_DT_YV S_DT_YW S_DT_YWW F_DT_WEEK -S_DT_W -S_DT_WW -F_DT_YWW S_DT_WD F_DT_YWWD S_DT_YMON @@ -375,7 +372,7 @@ F_TZ_MM C_DT_DIGIT 0-9 -C_DT_ALPHA a-z, A-Z +C_DT_LETTER abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY C_DT_SLASH / C_DT_DASH - C_DT_PLUS + @@ -388,13 +385,14 @@ C_DT_ILLEGAL all the rest C_DT_EOF EOF sep: / | - +dtsep: / | T digit: 0-9 -letter: a-z, A-Z +letter: abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY sign: + | - eof: EOF S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->"/"->F_DT_YEARL - \ \ \ \->"-"->F_DT_YEAR2 + \ \ \ \->"-"->F_DT_YEARL2 \ \ \->sep->F_DT_YEARL \ \->sep->F_DT_DAYL \->sep->F_DT_DAYL @@ -408,10 +406,8 @@ F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH F_DT_YEARL2->digit->S_DT_YM \->letter->S_DT_YMON \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->F_DT_WEEK - -F_DT_WEEK->digit->S_DT_W->digit->S_DT_WW->eof->F_DT_YWW - \->digit->S_DT_WD->eof->F_DT_YWWD - \->"T"->S_TM_START + \->digit->S_DT_WD->eof->F_DT_YWWD + \->"T"->S_TM_START F_DT_DDD->"T"->S_TM_START @@ -419,19 +415,17 @@ F_DT_DDD->"T"->S_TM_START F_DT_YMONTH->digit->S_DT_YMD->digit->S_DT_YMDD->sep|eof->F_DT_YMDAY \->sep|eof->F_DT_YMDAY -F_DT_DAYL-->digit->S_DT_DM->digit->S_DT_DMM->sep->F_DT_DMONTH +F_DT_DAYL->digit->S_DT_DM->digit->S_DT_DMM->sep->F_DT_DMONTH \ \->sep->F_DT_DMONTH \->letter->S_DT_DMON->letter->S_DT_DMON \->sep->F_DT_DMONTH -F_DT_DMONTH->digit->S_DT_DMY->digit->S_DT_DMYY->digit->S_DT_DMYYY->digit->S_DT_DMYYYY->sep|eof->F_DT_DMYEAR - \ \ \->sep|eof->F_DT_DMYEAR - \ \->sep|eof->F_DT_DMYEAR - \->sep|eof->F_DT_DMYEAR +F_DT_DMONTH->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR + \ \ \->sep->S_TM_START + \ \->sep->S_TM_START + \->sep->S_TM_START -F_DT_YMDAY->"/"|"T"->S_TM_START - S_TM_START->digit->S_TM_H->digit->F_TM_HH->":"->F_TM_HH F_TM_HH->digit->S_TM_M->digit->F_TM_MM->":"->F_TM_MM F_TM_MM->digit->S_TM_S->digit->F_TM_SS->":"->F_TM_SS From 5199b1bd40a27a9f84e684193e6e81a4c3f9a86a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 25 Oct 2019 20:31:13 +0200 Subject: [PATCH 0324/3432] FEAT: more fixes and improvements to date! parsing FSM. --- docs/lexer/lexer-FSM.xlsx | Bin 26363 -> 25871 bytes docs/lexer/lexer-states.txt | 86 +++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 99449a22eedca1b11271c005c8b370161d5e00bd..6a40e003d1a916eee0f2dfaabc2286e82cb613d6 100644 GIT binary patch literal 25871 zcmeFYWmKHo(k+Y!65JhvbZ~d~;O_1&A-F?um&V;)g1ZHRyGwuscY+81nw+!u*^>R9 z_m1)XyO$rNM_A9Zs%F)kRZCi43K9w(3Hp zCogXSb_t2u-r`vUV;t^1?lR^mm1am@F3U)zrJwBJpA}4NVYt=#`t~h~)U6kWbQQ|t zam)11@3x=PkdT?w4`l?3l!J>_dHBrZRPgHe&SIj)qTFCnGLB};V{;=VssZTG!+tPJ z7pUz?%Lq24jlN0YlF}~`BoEqkzGYB2PtR?{cv_{v!K2QdAMJ>vLK(XIk{_mCtgY@P zF!c@?Dk0eFsLS9O!RI@b3@#tr&xdUaFHCG`M6szb2F9r?cDq5fJtT>3+P49z#osMo zneOb=Vr$<}*@36MhGaRoDrJzxbE3~80*SFJjPXUgd1z}YaB-no!&BFUciH=-45v4c z$$2@M`F_?kezwfX=ygHo%O64nM?Se5r_qkcM3ynL=eM!S46Kj>nmfMi&aL1TMq|og zykt?~d!x|zeU+23ExFQ+Z5?ZOX7=G8QJJKU$mwro_rQ{n4DdotoO+m%p_o3t`fOz8 z(?5XX!}(3{yRciZ`NZ2M6DKpLP7raQo*=>G|3v9}6$a8vP@YPI82buDX}$L*)(-S^ z&%gg4mH#j1?;l)`h#QyfVSw*D5pNUTyxX@Ghs`Nyl@@P(txVWOc1%@@i+CUu*Sv+d`QL-;iFmr-eeWn%U4}-qN)qOBE^Gki^Uay&pFU-#~3;)mqOr zKR(TH{;s$tJRG+r{+`s3g+LDd)#>5;f>;KHAp`SCAWpH#m-sE-piV-0TAtZ%OV}44 zFG~4td2VVNS!C>7>9@TMlVl?VGSRq)owtNdUzLn67pDphOZa1)r%$5{-jNtVW&)P9 z!lCmDi@xQZV74Cro z0>qygNH8#5Fj#O`Yx;i?#l`Num7$%T)pP0ljWpn(`Ue{OfA>!taNP1|()hRgPkPzM z*_y<2wMPh6X

6xJtt*%Ghb*zp5}TLcE_au@hpcuAHUMh+dcc#@w#rC&v9PiT`q zLwAvCgoC^1qg%u$0ch0uTf*D1yNJr^2zN8`?E3j@{&N*T8CX3DTJ&}xJKOHm6x2>-NT8s!*{t8HZ3#(1mdGE@XU8ah|?@JeRxWCTr=Kp z4Hf*}+*BsCZ-l#%VssqiGw$BK-4(x9wJ+?t(R$4r7A9B10{O`CG40Wv6vK)Bjl~%7 zv-#N|lOKY0yk1;8FZWggmYZ(SAoAz3-fk~{p}___#aGM|=9=;iSw<-eti7vg=p7ZV znOi#>i@ZZl2XL&EkRv_&oUUXmCfztQy53(=Raubfa+?Oyk6U2LW`6{b){T^DG4vUr43*3o)&{7@YW*+Yw8JzR>v%WR&WL6 zEyk6&WDWMP)D#Tf+-$H2iI3;g+6Jl9<&u9$jxY(?mi=;>PNjQDFCWn~hq;GK(1R2n zVcg4pqY+o>rPXxtlcl-46P?d#RAeZEANdl~nvMb`$t5HeEgt> zqTB~T1iliYGFLilO8$xENpT&&60oE@d*3!RH~Vr`8jG>s(8fS#?S9H>@58C%=y&vP z3Ny`vc`Y^P_qQ-zGfb892TmUK>6zgAYcFIfXhc&lAH^zwlQh1E8%#&G^$HcOKOi11 z$y2m4WQ!&xO{zr@2KeTZzT?fBdU=d?sqzTbJ(nU?+lmb#WYsJNwAi%KD9Bv2CU=!?`!;FAV65*ZjIhDFAN4Wp{Z9~;w z0)0>QzSeM~{`z(e2o>g6lKodJF&u`+%=py!G07D9J3r!MP>+rk_7|L@Z$C)!DeMx8 z5=cwQFy)iJiNOqawt(_ZN!o+2bhfT_!E)lDo^}t$ZxI)V9gz$mLfuY2<;tYQPl&}| z55Yk2Ml1U$Jbs)=_S<&G*c$6m8}M7qbZxJg)g{&fcI0ccqO6suM}Z@;AVLzq6rm} znG%Ysr~Bqh=vsHW3|1I1)`HJowu~*Ra`_Uo=w>@!oNV1H%sYsTWLEJ<#Y)P};tu%5$eg z(a-_jgik6gTd~gJ5}w&lT>;)H2lZ2cS4pi%8)9~O0jmNK?v#Lw#y6kRDx?|N;Vj?X z860)we^h#b`g#^IF$V#GIUxuvob?U$lP2VdyTZ$O<-A&n>JISk?^P1u&W<`#0JQb8 z+}c;9OU_rUv<04pA=m*Mq%4Na_P*T@T*`u3j0x{H45&VM`yFuF*f4Kl?y&5IB^kn) z^)pHdr6+1-;K)8l2vLOsu4D~sf+Kked=f&fjR8Rr+GS?DlQ{UcbCgr6C!aN)Y!)0LCi^2% zi9B)*lF6XR8fCBL-l~a2O?*sf@rNd+YQyM(*9O8mkZJCA*YdDAwxtr9F!0C5_su63 zFp&@|o9O4GCB`?aRt{gYjyq0%EQ+j_L3VcY6oaQjju>w*pUgJQCeCdbwAz^t(3fo; z`wU-cl67Z2KK4&<44#xF%?Dqe?@SK{pHBm4&sT0AzuheFOh4V&-8H671LqsJ&L7U~ zAKGp`Z+G@DFHZCxAJ+IDv^(!_Z@uc>xnnUh_4u>AeLU_?PY(|-kMH&^Zf*@8j4o+9 z&z&C5>O6sZ9iH4C52rPnt9FR)?mVp={8<^iv_zS5jntl=oTibN^HoSL)U_RVM;4d& z4LX}9mrb6)bDxLD?;EUDSN#tP2P>U4K121}=ajOO);?zHc1)jdczM6Hm+Q^zt?_-S z$Qo-X>MLvGZLO$0-$Q&w0DE9@b9P|I{|I>X6cc{8_3iZA(fH_AW+u;y*Tq`qJpHg9 z;a1c=V+!3#SgrQ^n~iZL)!VbZN5PsS_TIta{ezupA8EeA!Oi`P!{MUQ_Pe#<+41@H z17PD8{ZqZW_DXxjvB|59%nPlJq|4j+j)_+p!>LtiAG}AmR+f8C%0BO(o}OEHP`4gD zu}72W4MCflvO@Z-B?&ePV*JQ|WGUN`sM>*j!_dn1n;q-(pit+I0@;KB0ZXnpzF@c!i}-$i(4 z=9h=7+XnC3P8|iGupW}>6_WS8<81?zFXZUXC#`fy2{48J3za%h$oJdOHV4tOVi~RE@ipdS8hiUcSF@ zbSP;bX?#x`?#bts(6ZJk4Peh2^G@P+Y~;4I&o*^dm`{de1unM~a>_f{>&`C-vre}Z z@+v#1%r^D^MzUOJnR9j`U@{>s!A)~eXSgJ zAYHra(6nu}PI=JjkascbppAPvwxXL|(b!CVOqsGH%FCJ5XRX6chpEb$MrIK~DDkD@ z7}OVe=T#5&Cj7yP;@n0-C$C|NWFEfTgaS*|qlq)OZ#%W^U0JuqcU&$6LE)L0m&NM| zNuwyISF<5%qU>v!v!|tIdnEIl=+Z&g>%6}lj&=8^;aE+gm4lSY@Fs2h+1nwwX;x>S zDqxDbt#(S5mNR%2!>l*4|9PtSj`HIn^_m^v){?ApwPkxbm+Ew{BVq9ZF&vUr&9XIB8|Yxp zqK@z&`ne`RW?Qpa~xt=$m2Wj#HIYNRRW57aVlqCs_ z__ZQJ?772=u~mc|ZlX|)l!1MQ6ifZdNW)XveL|Wc{;uLL;9_7U{NwM8o-T@kNBvjyod>%zHF;VXR)pR^Oi(bBa=G#tGSbi^==18TVprLw?j|4mb%PAgGc*MGt_-%k z5Bjzo)}5D*GQp`J^I630g{B|mmEJ60Ka$3+M7?~7q>5XqYG020EKn__8lGZqL5w*i zgx@R7CGIOCPE{~gZnyi^xZ&t&)^^5!GCvvBImLuBPc=B@+sE8p#rl#_M$s#Il)i@? z3Omhz2O>_gE{@b2ginv%O+`Zg7IWXi(7R{L216DY9q}T>5OQSau8F zKD*soYKb?l%v^&V_Wn7m{+b-!_-pPLKK#OcA6hOa){-($N{0|ycq?D35}5||tS&}9 zBc>mVJG`7jvG(>qke#0tm7?6(1%GVOnd5f!uC6GZ$}ADH12JQm-9P@OtotJl2rTCq z7euSzT+ihHWqlpUH4FIeBZ_~$d&;q^~MmZb>r#;)->jf?9?z1tL9%1of7;z zk#O_dqB>#k-hWANrc7ej+MBvs!<)o=-%(bocc?Pl1cH*}uTWm5dU4une~CZHG$}+) zJt-~4u9}f<#tyq;+)t?#jQkJrLHTABZ$)rA<*}G_aN@oj0E!S*pVh1zCFRzm>Y}0&q2}I;7xv!#uVxc$G@*bp{K5}Kj+|vpMTJqftnuWtd|fo- zxSs~@jJh}|ulU7pc-A_R>~MQ*DTa`Uh*3Z;014RJbO>=*D`z>!TvVP&7J0sHy<+S! z(DrAtv6`rICc6QI;jfHQ*gu<~C_n=Ncx5;8D#VY) zKmJ=8_z0pX=RM{+jGNhOe)O%t7QwKdN)=`-klv~P6y5$&nWWZc3Eju5iZ;GH5U0HN z%hXms%g4(tgOue@*c+xtrG>CE}R4U=&If3`=t^XgrmV$Fh8F8{>j` zCaj=a>>nT)7Fao3rimYRCS(!Q6Fl2!{Kb)V1ySI#tQye*ln%Co3AYX1Ag$Q3A^t1= zL-kRvN@-VH?q&ziG3F9u9i;nri0RjV5AhfEeVi!-(VKvu`mi;1XI0Td$o@{o1yb!& zr@ZW8Y59cYxb&)o_IL6U<+pi~mG!qX;3w8bfh4l|;&D*@4Yw^!8ew|(jK#Q%$}C%E zNs1?k7SxO}Fov)HSf8-_NA;(LnUiJBLDn0#2}ZcDGxZp7F8pbjU>Jg?wtB{4F^)Cg ztp7BG;a`2Th`=q_p5`Ijs`%)OEe=^7gSk#jIQ1-Xij+>cd4Sv-<)_K9Up#mCHZgou zPTcicuV%F9c3c+|8S*a*F1caJ?}iWTD{Q;PBLCZ8WsTM@h!TPxm7+f7p*U~igcaIM7*7K$o*m^%B+ZTNPYtl?FT-U!X$Vr?0 z)vQKq;e-h=?vvECe{BH@z(s!B5yyEt=qxn?j+ zbu8o_hyJxQ6X8OCot`T405pGL+rH@Qza!nGdx858!06^-1^zu5K)6`_0_0~{+#_|- z|DGWrRPKn{b)V`8e(8R@82!s%dOyGW|AW0Mxa=T) z`VY`H{u8vA{{-zXoKV39p4*S^HgxQZNt}hsJd~QK2*=48O{tvOOQ&w0C$kK`V6upl zGoB(N8qAmA14;lrDU<}MQtdPLHt{PcC2}WKP$L1MVnC5R&}Xtq^Eh)B36@kcTp3iE z=V3PcoA_Q-|8*Ge!6v>8^?x0PaJY$2K=WURt$>Cd{r6!NN1OQVwEy*OUdNmGk#zrc zn9Rv0z7G9=9Y*kd6Q7phe;($r0Ghej(sST1Mt9 zCpC3biIsJ*-_kN}e0GM6sJujiPeTdlSqBBZUi zBag>hn+K!3nlbu=#>Pvf$Jy)IGw;i(CrP&L`O90{Cn0a!>5cv6vtzmQn){pY_eYys z8$Ay@(^x+Id;I?QhdZ}h^P`-eH$|Ww!(VJFa@#OTb%XvQ1Ukng{oAJEzYfHIZY};i zB>QDt*G%#sefcWAyoQ#W@E=kIsAz1rJ=VGOfH2p$ctAhR?6yeuY3=864vr$n&QEhQQCw z)t?BI#|&FSGQx{q2R`~w^36$O=ES?!zy(?h--3Ud?AA+`q{yZEpgmM8C zBST_bCd%iiLkUM|e9Ni+!;%>`q~w8)$*v~bRD|s{_+3nCr*|-C-4%ivl_k25X#{uP zHEq#XD-IMcve}W3m=Y$6giY8Jw;l`o`!8Mf@*darjxl}Ytk-qx2ENAX4Q_H?p1^FdIi2&x+ z7DHXO?7VhTR_ioJpYI9fefe`{43fv`bLNWk4yYUr2Y@o;?NzeNEk0bt!N`h(3+N8W z-#6UjfO*sxptJoJ&`rsI*l_>pe0t)b?J@&$&V#l=D>4NlYEau!0sVmO{Lbclu3pgju7UXcVF}72Obau&yr(b&0rZbL44b)j=AZ zm?V(tbu)!VL{`eD#`EhF)3>i(sEnjZiQ}pIQs!o7t}#Z{1>@gPseYm_iGiM+NYK(# ziHq$;qK^)Ex2i`w<52g z?7Q$i{lM(i=i=i!Z#m$&&B@W_?k%kPlA0Lz`sYp(;==mPhe4} zaf(_!z8zZFd%%XvAgqrubg9-BU-h)#F~EpLU<@FhGr*cYf@7v;vV^nAEX>d>v$PkQ z&KB;mvmUU?C|h}c%)NrdZ2pW?tEEYU-R7#__Zb_%P25dg?whqeuIr;l?QXV)^F;X) zi@zz)0o!Q)9E-Kz(H%f*q{&LF@>7#bDl*;8E4@A^{JB<9tjU^ib0<_*Q#@8PttZHt zk1(k{U$&&T!Q@9LLO>5#tk~ zwA!051uC($cOsjKNiVl(pw%FdDslE+`g_gi*68`wqTn81IMDkujel+Vz~!ev6~O1B z59skScGt@ZQyx;-y z-c|8Ssj|l=ZtAX`4NKDzRoT|pc_$vR-Q1r%@jUX}c$}Zze)MYLrET}{aj$V}S@ZUC zz4i9sN}GGSJiXX-a=E^^Jl?soaPYVt-@d$9(|f%3;d@%@xWBnIs$I+w4=kEro+fHt zIWMZMoxdYW>u;TRS>721-j6mO4R5T-df%Nr9A4g-I9xkDW%p;9?VPOXW$>=@@?-!o z_}XJ|m+jUFkJ)FB9`vHqigXk=P0r74-+)e~PQTypm+`Iw-$%R9`#fIWSKS?L)W-kV z__ot?oaHq+4eY;@t2mKcPHN@%9XV1y?kV$e2dOXZznt6;kjBhac^*bz?ZJxw{PytzNl&)J zwqxbt(t&;T(bAT%<0+)bE}_TW<@9x>N9O~j=w|1eXr$8w z$~T+G{C7`J?mt@YUU#CpIoUr}JJOlxx;*uo?QLIdMvop;9w%-*R;h8W2cB12D#{@m z>7A@!^v0Qc>7d+nQlFi!T;9wEm$^#%b#K{S`wu^@!T5OKwSD;R zv??b&u9GFfZ<5JpA>ISY>v@_zv&b(Y6o=x(z&Xd`Ou?H6;#4!WOGqtu20xoLNEZ2e z4#e4lHxI?>W@?xE-9n2Xuuu?NW*dMjn7Jzp%(O(DZ)#@jNn~nMF^vL|_6?IUkewJo zdw4C_n9w3R@WT+fvR$RV#b_Vti1(pHDsQIRuLLvvinEFMi3qYzy#7LxV<^RS zn8|72u4r>v$uC%hoDvmzwvD1BuVOJjGv-3OYKDB4f_Oj95);`;wEkrX*WgjWfX|w$ zD1rPNlrx$ifJ)_P$8*t2pRBJBKskE3nbV8&bs-rOePE7^7#q&Aaon4Id|5OU%_fbG zf#y=CakO@taELgsT#Y3qjjeF)GDOW~mE0e;nz#y&ch2>@dt%TTu9ahs$`j#O`*C5~ z>_M0uRObC(Jhk~@b`EiwI8;GyK8+1ak4a=~yr=Wd-qd!lyk$v1LnBGxQP^oo#d1$i zmDy*rSje{kCdw?a?JeY60W)Q8*>Dz&&4IBpeQYTU#+JYonQbz(C3*ldX?5094HEr;l>lSenwFb`MV0?LCBInq>%0$9$~FXkQ4s=CVwG=t zERyhV!GX<bt0-bw-1n2#jVK}&;44G24lEr*mV315Io5f7#!-wx;} z6U2tIXlxA(l__LPSv0l<2FfI|X)GGs04X3~E{v4Hodn*BWs{Rm0AsC&ASDt#6~DGH zo!9w%O(^&5dau0%x*}^)vhAhKbQdwGoRdf{HNr^>zl0|eF-A2g~HI~zE-?_pH zb1x;=F3gWIs1Q5F&^j!Xvam2Y#n3h^kTS7QJ;l%_jG`uV#W{AxML}>wr>v2UwDppt z^_pbf^P7Ma;+^l{myW@=Ed9`$_W~H^w;{u!aOA0!rG>>Qxwc_Jl&OX0DY-UbQIsu( zyZ?)6oD@D+8eZ!dv+EkW=x%DB2&gvW)fsoByt##BH$NS#%i~jwBq}~TyhgsWh$oO} zmvOD&n=M<&PmOV;DD_B8rQE+_KuBY;nW~Xk1`wn@-4CJP(!BboR23nzZh zi%sH;B<74JR{2U8vY8HEXHKCBf%%(i96b(xlI`8wQrF>(-5Mo7($a-|O#w;r%WBcc z>=xmiEi15Ts6uFIyktZM9eww%3qKq%W++prk%g3tOCa|-n!NeT5%^?IhFAKDUFE(S zkfe7XHt0He5p*tV7_o`h%DW{ybo>Vzt&n4#6IQzQ*Ts5FnH4gfqDFdu#5PMS3#vr1 zBZo`sP46#O83IdXEZIu9QMq0r=%;qo`C33ugBQM%MoQ*mfYcA_itxqZMr(2gWRIXH z<1jerV|LN_X@J+lh)prrI6ZMZ(Zy*_ec zL)g;fWSDz4Kp6U)no!J`TOJo*Jy^=u`tQ+>gM&TW0pfEj0ylVV8hQqa|Z9 z*ywY0Ir{B!qN#Ux$iT4SEEyXEt7QOeDNDwtz-AdtHjO3YE%9Qlxh`>JfDIPMBC3DG zX$4Lxq^44bhE?=d8Z%3xoovY!CgcshL4XLN&j__uYr zTDicLoSdepfj-=fC1^~Sxm^1d$3e_F7`B)MNiA}=eq2W%ZtgqE*47rB1X64TaW2uP zsfpd8@4Dc-9D}mQV3Qdc(DVztM$+LjE-~=KHt#DfDlffP}#E?N13nA|* z!wEBJ8&s9LY;Wo^l%R9joB?4_9rbBz?XgdW`REXV1S_Ybds<9ox^zh|oxRLDfjZR^ zvjEn#83MQpZOCK*1Fim2mt*>1x;Vy~j(pJzX`*Cs24ORZq|XBYqcrI*V~`ELDUh{b zrf?%eDI*Z2J4>v^q!P)Fdb?psWKaX_79Zp6risrYaYZ^*n5knT5#WRv?DEuV1+h;e z`RHJQIE86cLVNt~qRIbQ7h=B-`&0?Drfp{02)vct-#REJY5>p&pNoyZ zU@73*B_E%C3$?PBq>0H1~_ zgp|fg&ScJEJ%nTiGld=bJ%Rs_Jj}IA+SM>(-dql6UJ(fql|C7-4{_l0VeWFzR6wMede{asm+W!tNy-zIShl0 z{_n2tNV_AbynN;vMbBwvgETen<~1{UZD^t21KTc5zWE@1*GN83$|X&L4xE? zeel{6`NkB1WUWHbxXy|V*(4(h9wf0;$d^J%;{=i!H_^9|Li(j+`Er&LPI90u$1eM` z^Z+%4orWjrnJhD2j0Mnj8z^LGlK|$$O!+L!8L_R_r2&I8tZdLurrBdZ4ICsle1G^& zL|S^cX-=OnE<_?{0uCqw;(pA@?ALc48vX+=R>(Kb2qbxWwV@OVQPR)Gpg2h;j1#;B z2K zIXBW>o`w2+%<^W4`!r$uo2Zj~l^EDo2oYq4OzPXcWoa@JA|7JzqhVuCRB~Qay>^>~ zr@FC4P(3@s6%p$+MPpq3;5GAtddK$M*)(UC_bn)W_BT&ZbaH%4K5&7e*Tv#%0Wl3x zh#>tUnT~Gf=R@_+T=l(?_Dcb0esQkh3;K@X&ukTu#-(vwCr3G=ix&YY zK$RrP2T4%Qpj{tXk{LekA|Aboc)A=SMPppt&sfygQIzA|@^WjAl`hI?p)Ubbast${ zS(f86I5DXH1qR1GP`UN3{!MlnvM7t0A)U6f#~_l)8L0I^#ef8mfon-9A@Y3`VXZVr zO8jw4N`8>t>SNr=9Pz&$K0(>AS?OOP1>k+E4K3CshzDf@`FiB-nL2cGDRT<2w67Fg z>4g#NU%a+jcwq|Ghx>txRKKrF+BXG)*#YoySWz|0SzHU|l$bsCat2iFLzACCrzfn@ zWVtIPAjqk1bP+1@zK}lqFRW(0xjZZ0dp}9g_BP_$k|-&}Hp#`bW1qDAthrsU4MKW0 zWkh{{<^1oSLlz>9fF-|X_U z*RU<=u1Q4N+0X0*MddlyB-cnwSHM9^G!}ryh(m4scXIBMfRy1Kpl(c9-VAC4J2{j& z#RJtT62wQGV&)f4Kbs7{n{q({36WMtG88oQ7OqV~6ymkAZb??fK^G9#cJstk`}6+S zA*Yq!H&7WDhoF2zX`*CN$a@D&Fbg` zDw+NRAVHZO==ExZq5hr5^lVYBZ`(qMO3)MvbQW_a9I3mMGX~R@>s>1TkG+#93QCnn zMFEL??7tNw#L-G*iIwS=H7x{{=`FzUUOXd&s$d8UvET${HuLkdzJCf$j=*60D^nl~ zPo&KeUSy9=q)b5bLzu#kK#iEa+#eChcurPOgYa_13}IiK1d}DmQb?i~DsU|M3n|2= z2djFC*zejP`ry9n)%&W%(U_z!dM30Ov!#umo+3G2V&PM)SMnF6NayXPG2k z$%2*orI#u{YYL4@(ciI6hpR9EHAL7}u=}8{_+Nd=NQ%7GXoduT&%uEkc%LRjErd~p zU#!T85C5h%h@m6`9V)^}F>RJGpe9A^Uo{OOgUxOB@KY&Aa7|U}2EukfxnT_}@3}^; z?(UiB2cdpt@WPjW?TECDXI3Y4V-+GNUzmcb8KFO@ni)m@W(0h4GxMHEo5Be?tw6?a zBJ~?#B}C*ySwLJZ{wWOkQ{eG3y{^pH_My8Cer8j$P6jt5ovaVqDWFK}gTVH)_|Mv7 zg(MHPSj~8*dG~)s8Pw|RxTPZeSknX%n&SLQ^&4Yy!55##9$b4Fh5&|b8_yzf6$TQC z+1Mm{RCLMFUrhO@~Hb@WP$Wg#aDyTwXsh(#7sZlF# zXtMHiKZJcE#7~C;d^lJXQLf4y!h#zj%Vqk#A^MvNP%!O#JE|McxDkOf!NX8?X$8 ztKT^~u>|Ti{crwSzmsIwQYN^NUXDb%cY3JnU;IlUdQ%+Ve<@ZworVC)^=@*(6WrmC zn0=Er&q(Sj?@FJCJ|BGIriK>JiWqRQyxkq2E!vF>xk44qSNjQm#UAGt;CPv}?n~@s z)uKrJx8M33vv_)fm-#wBOKZKtPT4Q08|wvY$A9!7^pn91f50Ro^+rUxau&qmZuOtb zX^K61|(di0Mz(B$5T72E#jFQe?$oODb4V z$2HH{{<$EK_B(w{`(QV#{%Zez_)9mj4FIJ{Hw`O zfB^Um*Jt63lKxqYK(#MlV@rh@d#usw9mjKrhi$jbw+~E^YDC~^pSX=`KUAO^w4FiB zcouCTqhEI9Qbo^IK8HEyob_3yj z5Z$WsT!K4BB*`B}O+W1G*MXXIv#Chef>l{744itn0))POuxTeiyU_f8%Lztu+#~q; zgHXQh;R`4PI9wDKfcd)ou4WnpGd1?1Ho;R{SNugMQyrK;?epFPU2;qZf2_513!_)$ zrYY?=^Xu{eBLzyQhhdMfY~_lN@tW^K`*XqTNiwLba{OzDwvF1J?wYv!jCWj3>1F9^ zhLU6pY;pKY{Y#(wKo3)gn`C%Q5hn)CzjT7}#9n4h;l+G>c%XI=v|MoLDIO?h=jsP> zh6nsS!#-lFOhZoWm*TcM}l4P z=QRUbi~H>ul$tvj3|^cN>4!cjnXY)yx_m(2;R7aOpsL67()?l=ZAJLt1005k(NsjY z67^zo@kAXto&@Dg{h1(3$<`ekkK0;v_aI(H+GxLP)wTUi@*%3)O>rjfFbJHp)4Z1X zvS)Bwxw6I|AJ1+MABT4yI{I-LE=ls7GuT0u(Ej%wlnjZgX!o)TH37+e6&Fx_Oddm? z!TC*5Q7C{C+-G*?p!_B=zVD}{fh(+2S6R41H&A|jK;GeLJqqAT&Q6ZctNts0iYtS;h*5y z7&NCKgaW_Q%F2;$H~;mWSSKLI_3HUxO6A1aMURhv&1>!AShs_pr#v_S z1t2}Ge90VAwALeJlWT2V>ABjwx^TOz@o4r~7{!k0sOw0S-Rd^$Y@qi!esi<+ z1pUk7y?a6vAu-S`fg8}b&k#T(KworsaCEaaado!1XTAepm1autKO~cEND+#C@yV(dUe(Pcz^T7^ZUg)ThS64o#ZEt z;$`;4N`u7j@gGf!pU$!IIw}(&s?in3-W8v`EAffqdtjvf9JL;d(I*56s~U7G8FJan zGHe{^puGB>)$}|0hG-O&V|al^<*SG(McJVe&KjEW5flUWK!!o!Yhq5S4!b$APv@+t z#)1?m+<^sFZcH~V#%%(xUMe>>_{YI$IeGh!ODKMiGh2uGDxGOU*40bY6aiCg);c&j#36+-d{A`i@B|gM{Ks?1S@29cpXDMwOfG5!xIH!zv*h1PDh?WQ zs%hlZ1MA`gG-il23*4iGPEZnu@Pv+UG@W419A%JGddu=%?GHNPzemoukL`H0v$D-z_ONIaOMba|zfjrfXQ+5!*&r!R6?#xxypF(k-#qx3zL7cDD;V=17|}4lKRb7($ffNc)9w z-!$2&=S#V!wrn@L}w$DxzIlHlNY*hi8Yz#~!VsxR}k zS4_`Az=%HTmp@tZDP1C{5#rsqJL?Vn0DD>aAoHldkXi2eUDcENTPn=zQXz59}w*(5-z92qtn%g zx!1DZ1j}OXx66v^&DsdGj`L!>&0)@Z(^+E_};?S?5FN{f^=tH4BM+}=E?Vdm3*e87k-Er^WO8B7D*>Gp%fTrWq6ei|${?79Y`@Xl#}S=m}&@JdIh7*c=ZHkmWO&nb`YO3Q>mnJeHb~>(Q!Z6r|Gt)n&i1Y^VR#DS zWrcPeo#L+k*0GaHZkUE@sn)(lKf_x!`+`@ueILP9gcVAds9#SGt>h%#Mis=-!VO~R z5XR9gSq;%r(Vjy?W`B`Xlf)temX4fbXRvU|k&}@b=8{sviN6qc54y;EFIg(!xcfee zFkhn(tI0mzNX90kvJ@57u;7(Okt4@dsMFM&I;oaN9CyDaxX5E=#BZ56DUIGEYinJH zQl81A+^(&katA`;xMO&or^?GN(q*mED-s#&+QQ-qcS-T7DCYs-VbR- zY&{H5l{fTv0PyyXbYDf5 z60-3?KOAFpaG`T>2R-orF#jk0_yNVsI(m(2doR>!l@0UNGBtyH%5W zT=;$M=|#d8x^cX=5&!xjZU7qQf(Bj`mVCn;oSg)=#~^_>sTJZX30A7P3nkW664KaO9Q`{q)l>o0XFLNFlz19T ze{&WqJ2#&=Iqx>Pbw9!NZCG-CYTQz(;j2M-Evn_@Y+|PuGs!nS@daC%5>cMa_qR_2 zlU^mX^t+kx0aeC%6+EB7HQqQzbIuQaMMkvGvs`QoVIWu7=Gi*;GkpAzH_##;+AqeO z_uhN{%|&yMXwBDhDDwpNXs(^`3nq!e9(uFh$%#>LVUubx!-R8pOQW_(b-ZZZ=+Bcf z3!ijrJs8F|CQ+?y5>l$ScIg`}U(Hn~OG40%Bn%MK)@{>^+v%n# z@9oD(NnmSz`I%`Unt3DsSdm>W>mNAiXI>YyM^t$Pe zNQ|4Ju|pVQll5w7EF0gop-qpfXQ7Sh8rya6qr*aAmG4GSbvc$^_H-w_s+CPeG{TE( zq@{0aU*;>zvm*nm!zrbJv+-WAJMpwd)}jE;DYCTdbT zJ|lzl^LO1Sr~!?>-*RKX)Jvh$zQc3_%x%fg3rt^2i6! z#9A+n8%ywrplILVeJcoT-tP@M<(phQCgDWc=co2u>Uyd6l(X=edG}KD7@A1JO+soT zx}E8-8cnE7ggPs*HF1lRV!SntTWPZ@%y2a0l6Y2Kay^HGeA{%dRZS-cKKwy*P4cp!cV)_xjx;E(3789SjhN=-1GQ2I{E*SAUpmKma8| zg0AJIPkH)|SvL5RwK+6A)9D51(n48`v<)00o2}TpJYh?%?dA;>WFgHC#dLF| z9Q@AU=tg!&UNim=J}0YPiX=Dg#a| zv#o?xu|(KOb!eIs8Zo6U3XiteKQusxc#w6`D*8$ztA+bf&lu9qN+yNyM*%e!?I=q( zIM1JPFgzOEZbKJy%VGsY(}&H)ee-R^l)S?d*!EsT`OV%d5(pH?fFVrviV-p zDU&Z^DKKUsjNBF7s@Tc?y9#uO;^loubYXX2-&5R?*(Y!V&h90j*_7ly=APsH*q=3r9Xf#%K!jiesrMLOe%Oxb{@Roi)axYY!I+oheGV0{1-CimK%Jzga{e8g5GS*!e2bNOjcUY2{D9q#wnryjK| z0g`T818h3~$6j6_z%By^%U3T)`uX?(n#N}+A0g+NZ;UAbS$}>HbU|-;_g$vb=Q?O2 znFEJT+Q^vSe%rn~nX};hYLW=|m?rXa>TI5<*5GneAS%7$K@g9!0plh3$I-UGl}h;< zO8CUC*0kbht}2GG63YlL>JIx!6}>d%QE7Wy-R>R(S8`z%EfW>Jp17w?7uR>Wn?YXb z58bA~vuSvTr+AFnz$XP|%_$y^IpJDWn>-u`CuuPGgNzx@gy%qEy4zYtTbyC7er8vo?W;}TcLLp~Y-YL75Bn%0t}ZcSeEJKWz7M1-w7 zDNZ^S6c6m8DKH+v@?)xUMx%dcD!{eA{ZbN}Oo0KAn%?+%Etd<~CgR8L`Ck^{>c?F) zlp5<$xlvQ~>`*W3v*pnuMbzzl z&y1|C*t_V9B-PYHBHOoJ+Q0hogp`Fhe?09g6~U7Ns5@@b!ks+I+eIZAtaEQFM-hy@ zxbN575n|`h)8Yp7Qk@Li*&^8LXFhR>eW?yMTHkLE?V9duK)sXAx9cKR+p|V*1z|lIgwnpf1@^e|~3~Q;^4*49g zs0q$Tv|<9;JEHTnR{I}&ur1Gg*->(2{kiNo+X}Fo!#vfl;e)28U`;(*Id(F$dyU#?vUtR-Q;_W^p$ zlL1{*9{a#ha9vG>HrrC5o2qQE_2ycVY72qz+W)YkZXXHis12^Q3DlGD&oN*cO!oeLhLc?&h?21uO}GG&{Ib@j@+RDNc;%t=Um4p6do~JB_JMR zYxL6k zpEmEOq2*QX$io4Gn@#4ja3mBiqI#F|pri*oCrCEW zqA5!oi@r(?t`mt)p9@zZj?=1QK_lnm1flVy_-XXXsITeYRRGTlDxQ=FeQRLLK8znv z^O;X9IDqF1;gCL_N`=+01&q?T}YiQYdDV)}U{On01 zn?9gG$c%KyI4;&tl6~!?QOkTjoZ;5P2Hjmc@N>{V9It2%(Aa)25;4#F{wY9#0b?E{_%CCWf3yvYxu6vI3}7oxM{& z#;D_1G6n4XZR-FH1$v`M$gC#)w*8jd@l+EP$$28EBDqVE`eCK*UTQWKwzbOwYlGJIX68So7PC=d{ zkCSZozPCge->?$*D_uxk#yM3h-p?q@`Jhq@NwgL`2_;@SDG3*RD_d*ZKic2j6^DM@ zoIsnSd>xR;st7I$KD$f36=Vc`+O1%{@FEZrTT*H_3j6J$eNSxR!|Ar?SNXogTG|m* zsHTA6p`V}~UdVwAlyHjvSgf(%ecxqmJ{0W+fp%tYBcVjmE}o@QL3{>(@K^hkXC{sQ z;Gc>!TO$6GI8$!X-FvXwjZ~3`ZXvPwo=JVG8|x0?)6`66cuVfgTF1K&$;FMx>z_YD zosJi-;{)>@U`+u_K-$aHWp=y8ua%1{OIza!+9SFBusn8E9Cz^FaNUgLlzD zAQ7hKcd6Qw;H`R~7c@s;9eP|=i(?!1$3OkcA0w=%)%~2Ah$fW+J}Q~6Ig0IX)n6}B zUuA>ox5RRehrmBHNkKHf_`jT*S`<25>2lFF;!pD75X@y5R8A`Qv*wGyh?o?L;tL=? ze7Y39{fznYkLkY#{Y(x5_{|KUgJ1zc0Rz(ik2dk=BKWVC0Sp-Y0J8sgf3(Jrn*%7b z?<}A#VA9Jj&f4e;XIq3orRFUV>Br599@fMgG8?{lp=SO;+OOyV#7|y)6NS$|3eS4b zAVYZWgVV`3$BTC!bre_7SHnX zrt~T)>~O8pXK1fd4KT3|oZRN%hqz@L7@uZ+^$RGX68vq;Sn*{8qQ_n>TAHn;JneQ& zq7y6C25ivB3=uiP4kz%bk~N6?2T4PF@GHBw*@6a>^s2GD4W;OpSw0Qy`_6I&Ckr;0 zna}C?yJ?^X1=9w3!@xye$31VQ-r&eV)14Yn^t&ttr?2Xt!~PS29wU}Scwhkmtvvt% zVf;6NI+z+6IXck&`o{3ar0J`g4$F;ko#(gZOJ^Gwk3F&53wD%a6p|<;hqNDW*`jla zD?({1%SLuAPh526!H}zJ)FHh+|4`R_769V8v7U% za<{Ey`YfMi@o8zbuJ|l-ueG%<^4esMta~n=;-1~?>bmIC>14X3wTuV9?w>!3T%RnL zhWEDw7hY0-5B?BZ^?b4O!yDQ9%!k`L^F}>pb@y>~?do-Bx%*NI_vAb?(4%$v`F!iX z;qhdv2KxN5`!@KQFF1S8B>EO_vr=w(b@gn0)b3TgskMdg(Zl3LmE~1;IE~}UtvJ6w z_;K~d=+Wr4Pq=;HL5ue(Ej%r}!)v}SzS{F~L8U}8MJdAdFE?(mX+eX$)p8^!Zlw0doG^VoHpybsJ@xinm#g=wV?)sG$X{*qRP-|G zqiOre>-j>q(z=pHwT3gFHtb@y@p$5b-23Eya~D%k(WHO&!uxbt89e@Iv+H8BK4U)H zP$!ACYxFATj=7$m_1x~ZDCW$4>eHGmq@!k&YkWRphqIZYXtK46^Ep6()(Y`b4tx7K z?PzIvxb$|uKrVA`bRAcN?e%H#q4E{6-a7#ylmkr+MeY*SVP?@37w<*pn)Ha>vLg=9 z`(*xn-8K4^kgGUYinMik-Rq%o`Nhc?CV-=bZudKrQT+u$q%mC#6%+5H4Z^L@Ov57h zX`{wk3U{NN0hn3L^5t#tboz?`&trfE^485$?>9ca*$O_LCo|d^kH>XpoNcezz<2hF z#G{N&o|?q50ZL(cJNUDNW?bUs;+u?3NMbW~IFm*UlJf#6=8X2`xU098~8b2 zzXpT^iM}HoyIK(FX_Ow?)<{3-c`p)UmePuh-aR7F(@XDyXvaW}Bdi4{1^J##ZwG%9 ztn7nux^E}xx?M#ZvI)NJ_7;~N42YOuJ2EH^JL839gzbj-AU0-yY`m&I5U7}fPUs~f zd-cWP{6Q-{$*D<(l#e^^JjbnEM{9Qel9Djf6CZ3c`&f7M*0KYrE^;Jwh*+S}$M?Yt zGZKbe9y9S&b|2~h>cy-e-zR-M#@`%q9$H0(oEZ(gKe%;RsSwt`8WN}wiMtsV#u?A1 zHqW6F%7}1eoEsD-lSm11V4sDw-o@~GZ&cx8^aH;)i&mIa79@%TUx+Xg^LjJAe(=?8uhaQu=GtYpt5v|LxJ(x1?hypxA) zJ}S~krkB}bo~y8D1ag`k5>H7;ky&N*a31XEmBwevK5%008y3aK%Jy-l>=RE8Dv>c| zj5t+K3@VUOWt2G~fpyOKnE`<^G6GRx`liEKDm+MO&6zNUGa<;z0z5$@kzHAsXR_DY z3^XkwR1#4{jiuBmF)bxj5fMYx<|@hzRhNUGQtjnO6;h5+Vo>Q7Mh&GbC`m5XuL%20 znOLG$tY036KM|Vg?3d}{M|57%+n?Z<>F$^5;U~lEgF5^!O?qaeCK0(rtz@UIh<(J} z*waWF^($p+Nr=*& z*(cE`s;_qoMa5y_HU)nQPNnAv>U~~gWz;ahr#31gmH{2VP#2t(%!<#^N8YRYXj0h}f`wl?za;JYUmTbbDqAI$OaY=@)re*gib~Lg2+r_Dmsy#4K5(% zuL4#M&3OHuxR4@7_$v-;ON%)5mtJ5=14WV=v}d*vZ>6$0(kTjM#+@9=A+ef+sMQ%9 zA2{-xF&1Cwa*j-?u!2<1P<|;Iy`|2cPDkGZkZI6@N`&$MSj~QyjSziG9n>e>2m0n& z))zBZy}-q0&UJ@YJA(%nRC2QUn{F1eRh#)o;c|^EV~IqCB-iux5u2y&?hhv*Ih$?h zoG1X&H#31k$5&`8J#6(E|@SzK3K{dC~iW z>IG$U5h0qujesSCB~#Ed*=jlHp=Fnogw#~;x>n#bnZQRBd%J5SUqH%d7PS*IBl95^ zOT;j#?%cq}l^I)fG{B%*=rse~2V$AdQ{hF2if_30R=v~o_6wC13B&|uoR<|=B}>XF!EaK~IpUiFS_5PZJu>99zX^Ga z)x)qO*P$SD4_YK3pII;@7LeV#yz;KdvXC)#J((;G;A^}Jp=s*z2?p<-vdx4AY-TzsAL9uWIZIkKPiMsW}z>D zIvg|z!{;B9PFRmYiW4VR9~JY-mUC;SyzQ!2`QUSNGo+fWG?g$;rXl>Z zgP1er(6AuBNfwP${m?K!zD`!UPI0;ig=>}B7y5&!x6p?H3B~=Zmu>apnWl^S$lFTK zXl)X0L@&XNnxn$#qjdJU2ZB6>y`k`NDW`wX$$4;Om>vIBR+JO-$S@~fm`pKa#F24+ zP>@V2qs*~-E|kK-JTaNEFb#s9fF7SjCT03Do-AKsx0=5)dsD`$S@I!}(F9!?op<-k zx|ymSwKsYJur!o3axzqMBFks>xCPgF2s?c}&Q3?a1K?>$W1tbl2T5C0)4szFj$;J|Mo+E)?Wmz-x-Q<2O8J)Su$1>T?Mtt6<-3 zEWjUwgZqKgqu#g~@PWk}B%_HRy}E|Fi!Wk4-F(bo`bSwQUiHqvGJ)4{GxU^Yki(>X$FYmd5R2#DzqoPn0divtK-OL-`p7ijl0AJERhp_T05ygnwk)t1<7)p;&q$2q0g z8solN5=|C(0K1GHp`J!(tzW3$0njvf0i^VL>i6i-DNA`ibfJkks9F{XV-RVO2PSZ1 zh!LDC6W~p1KXu@mH+B8SaCVykoS`%Lv4Thxaw_Y+rbGDqu9+2*nAE!Sm2K$zKVdeJ zb&mHJ9zVuvdLuA|YkIGTV~T?&Po#b?8szEd6wWUHi^mOpE^UCs^RE}hAHzt7rib1i zN9jrNV|PF_`L8x8jY(}&85e3kgue(XD4$t6WEpb|Ofb50Q1YegBAg}aP~MK!b%`{l z!~j`bMEd23gEJL=ZQz>mEy_dLrlru*U`ytIX}k2iZ_Hf&J_OKs0iKSaBxABy0N@3( zOT-_8=}`wY7}9fN`Yf%a2r>LfY*>&gMhs|zrTs^vlCk2|sf+lgv~sHXa2MM6v(wIg zIE_!1^48$>1M~e5^j}#%Gm=}Ur~T&W|6ItJBhKQkup$}waV5LT8vrI&Z}TEt#ENl* z|KdqA1|hdhtl(scR6MY1%fXomKXkhTf~>Jc7qEl6SIzhLN-jTNNAW;k#%njTg&OPq zuW&|r{Z|sb^#GVF6Zp+!#v-zy6!=4vwGjy5AqV9q3W(SX%WKi0Y2_67C4KN4Fjcu_ zVfzhxR&uss_3bS9!%AQ%tMn~KHB`2FKob2edH)w4f}JfEAp=H*ab-YZ@WxuQ)CgRl zz2~DGfv_mFBIK~WU(#+$q800}5xC#g))Ta7H9|~=s+|QXfR~1ohD@fV=h1tZb2SO* zgcHzw>#1Y&U_BE2K5rz^lM=uVtC!eW#_uzSFN^5w_wJBbAt0Mu_1P#!c&KKU51Tj^ zfMa6UG;8b(PMUa$J#whX+9LiR(Mpm7MfR)zOF`fz1JeuXiFQW#r2xeP{ZR*S?~|A$nQ0%0}kvh+w}^J(VHG66#-lWa3yjQkcNO_ zpCiZ$<=6bnxPmYO6mf~zgQ>nH_4!xNoXDaGVFI<=#UJ}MkWFNmbLPVpXsw|P?@R|L_c{fzlg&TC%AAe+S5e2R!B5St?c>A$?p=CeTT|03X(Ju1WS zHVgu|1(5RqzW>!-)G8P%0a!W%uxtTfdG8n%l{FD^?F|oz8jO*A1vVHdh*h1h87MO7 zG;jf|G(s{jMiu~20JrpDf-(V<0vp4Oj9}^Vj&@bi@oNH5%`OK_2ylsP21+6q$&66) znI-MaaN-pZGE-Wapi2AKxvEBI40 zqa~WNy%9(UXiR!f1@>RWLa(T2+&NNCK@E?V^^uN0{a+(5quQFtCV2o*tP+b6qA=kg zR*WS}7JQs)=-tOExXk+Syxj#6g@oZk8pmF*zymj{M3PJz>L91urL%MuECg$5VIi!h*f1U!A1dPW`t;|F?e~M zprKA3P$Z}Do!i6EMmW*-z6<`j9#%faGQq#=rCIf6dk%9ztg>i z=ln2G@>hd&3;o5Xf6u3Sp2iysd)ejSAvIujD%s-}h-6SuLrmA~-P`K$Si}Ine*tF# zd@En$1vFH;fR`%j6%<`SMr?N)VSZ^5x8J4-*trGM3QsGW=sSlO2Mlmmg@4Mz&a3kC zq^^q=aYIJ94_lr@>mndyy>CGa-CD5OZV~Ui8{yXkfU1|C1R$=g`KXsK01?g)Gup8| zOtyeP4in)wVZ|82UswXFZy`Eo+oB4t0Ji0xHg4GRgX@o8N5&6_92bcK*aHTF*oE}? z_DmmsD|JnSIrJw_czKzKA3(_j^hA1nozlJ%zA66aDe7C=Y*0%YzcS~c6~b=Bl3t2_ zJ(TTN_PABJr&+{_yVV1Rse_Uch&Gl2HHhhiIkGPTE%eK(sfS5Bv&(E3y^jB4x5V+k zH+Dz^_HTVIGVlWF{~lhu?f_?yfOB=<7is}bz<^Yi6do+UwYoowwx`e{IJTz9wukqmZUM)}zy3bMz4bqn zyu@y!A|S}4qqV8>H+KpaGb0m0}ZZo0B#LM`E??ZVfbT~ zxtja>HawvZ=C6v_uXyJZ>dKfTRK~yYThx)BNIOu8gglrA;3z*9{aWO%8yY>JpY;Cd zGiP==piA|4>4t~5o#Ei$SLl-=Dc%tX5c&6k$v{bVk^|2799Z!!!h3l_uoDZv4*9Bu zQa042ZLG*b7aB+=H|@qV-PSe9>xN zlU8v5s9g~y+5b4jV}D-t!y3Z^=g74WRqh7FjCrQFx+qI zC&ixGKzhmksduX4-1o^^jO6WH-!=rilzlMRcQsbvE#3kAM8q^M-H8^(t(l+!MYywg z82P2Jl#%C3B}Jcv+e&jV-#}BMxMbd8$IDco$PF*`OVZaQEQ_VSRz3m3iQK=9db-eE z;s^o;ME0z|0O3yp91_J19Q@JrYTs(0az5%E#~}fGov}02jT!R*P;%iwp1_y--Nclh zAtqIdur+^0>aap9#wN$MlDwno0bp3prH%}w@)Bk-??X(;9Q}?Y041YtZTQ+X4bP9lj`ThRH zc}d)bSTGQaIB{HwF%P`ySV~#-7P022w*9>_iI~9~p}rYo$yltktxC5&#Kl${+v?DL z;qK56SSFG!_LqKd6X|1J)ba2M(3dlRCZMS$$pvYBWrwi)b+7}}27nL*G+_} z06(fY@L`ZXUeFf{?DNK*3<=mM0R5J!ks8D2IF^J7O`~c_*YgXjn#Ew3#}+xfth09O z2bY#g1UWjBbvE4*F-)8FWR9KFA4d&Ow~r^6KjcQmvN~)4FAZL7)>&P$*jldErAxdP zt#9u;v<&UyM_>9c7cW;Yjgz>aJRCf%AL>_mEHiIh9)nM&Pwp?B8`f8Oj%7UXaCz4= z&o;*s94_&6pXyeh?e@0|Um^eLg4IGk6mkv<5YS-af4pGD_{Rk+3q@@8xW4mS?5cIY z4KM5-5#R2c9{$;4hscG6BMVH!G*f;Z`Gyt){f@_iJV8#fSICAj$C0}WhmsgvR6@ni z8F()@{af8#XP0|PkG+5l7;M?<4!EB_**twYIO^|yeUQ5x-uclrY=7g(=Ap(t%7^>H z;luH?TaW75B_03!N^UZrG(EygzqT zdn>nBwf?Cl=Hv3G(*-<%jqE-op=ET<*1Y7u_th@tSdji-;!% zjhaw>c{ulC&P&oR%pKEYYME33mz4em;i(!E}y@4KIzIg+9oIk?rl4n1|Ky|qy}zZ!7t z4mayLjVzvAyxiW8KK=Ny^@+17My}&k+b4Opaz_Zqicj?AXg=CxF3bA$#?zMVmGSZ9 z)BRaEp0oGs^|Au*&qc1Lc*vvao#)l8)u$a5-hl1g4ld30+vVN>91(AB*H+y&lmR!^ zM*|0+v$MqYZPorWQdL#5_+eO%k-hujsg=ri9C)qcrTv$eT=unYN=GBji}p7M-ItsFe(B@(4Z7{) zDwUe?x5ymOeSrn`Jv$AL%es~5Y5gjpM_QQ`%d-qG?VJOY3)ezAgV&OG{xpzJuGmcyuXUH1b3Pl0*!lHE-IAr%XH zNnh(+D{n#oL}}NF-EC|8$3M&>`!vhH8#y-KQCnVePFzH{30R%Q2c3Y$4PD7n`QsWZ zBIwPqo4d|-mE3k#NUx0|0wa0i_SEECIZx%to>_~d>w+TjCoMMQIxMGVXMmACEEw=_ zYRrCO`3Jp88@kPY*(uSe*1G<=eDkQ}b*KvfphmSW>dht9{iR4H-SxAN23LNN@G1e* z8!TY(ABBdpLtF@LZkf|dkLcXfsq0OJ9mDn!Wh7@*LYFH)FW z=4gwr*G?=}KfzVxEDUC8qp`&y4+tO_`Kf!XNIX_KRb3{xjDe8|F8XF3epKSAVHzy& z*QYw4FS!@ALuf}U?<^JtH&{)cTF!uejK%`R#7Eo2$3?<_A7@WtV2M4s-IgO6;Vz0@ zI)rf@Q%|$hTLhVf%kpb`0d8V`LSkjSg$fCZc&oHA72Rt$|HE_3GRk=6=abQT)1P-%9pOUqSuTxbOq;`j$c$u=05Fy! ziLs`h!<_M*f(Vs+0c3F%<+!vQ<_B~45I?woqoq06?w)Z%n#|Z&|HD)vEvnj}a-F3O zxAX$z+IRA6LGWLIN>N`%WGNQ_Wk!iwIUj9x&)$~^GKBc68t3DfsC63fE1 zwDZWZryZ63B^RYp?bNk2OWN>itAKW}GkT?*eORR&+f@Y_@|is(7)(4cucI;C=*3EC zYLJ~cp|ZwZ9ILcC{=<|Ni4UsKLZ!j9To_yw4b^3<4-xXY(Tg{^e-wmRP=VH{+G=`M!m4@d?B`p+mVMoum(Wgh zL@CkR$CM3LRHMuPvj2`k&?;*{#*Fbd2cCdP<$DVV+Hfn2i)oBO721e{J9yruKRKIX zxeQnT;0-4Y^H8M&*xanlote(ddG#;vs8+i&jwGzgD96>E5_XL>Yq?D9LSg@uK!%s_#wGpS zK1VHvOF<3scCJ)%23}?sWe?$o4C7Wd^=)6k|CAWT51nh0^;SJx#gVRi4}$Y*%A}=q ziGcFhD{FV3$?bbX?q4xE1oa?VoUV7X){asI_4;g4Hl*WDu&Qz~ug*iUW&EcMe(uen z)iIG2$HLR|r!BRHMwTEdrrRI@{*OyX>-{Yuo4%yf zMJg0-k(2P9v_tcEtmZh%M>!RFM4|u!?hyz7An}c(Tw6ll*uA0=(YPNW~I+n z5X)RUjRN8|Zc76FyE~-O(@RFV#kkr1CEQFAm_@(up_o2r99Ene@Fu`R>-cvGL+3eG znzCUhIj&jcQ?&#mhy(oJFx&O5Swc-K&eVR}V+8o`TL27&OrPELEzXqup9E-&rLPmZ z0La5R0R5E--hdwkHksw%*WJJdR5v|j_V4A7gYV;(IL}Rcb<7Ni%BOey|G+pKWzK$E zAU=xl4xO$omhXJ85dT7mOcrUNV|^Uicg{ayc_1T{@7;npfPTX?b=UWZX?1*^pHuvA zoEE7a>{Ii585M$(nCEs%VF6Ydz4GsZ`LfiPdZ%X#Jv04hT;ZGbKw=k;W{W&0)OAG_Bu!L zAC^exmZN9npnv{5&_-BRZTl!~@=tDvZ&jD0 zYbT-qhiK6OlIx$safS4M_5#AlQb0~=>-?v{3jT+{QvIL3AdJ~?_}IC4kau0WwV1B? zqk`C>L^aLcbykY^b3284Qm(|!j%nOyj#NW~C{p#5TnXo0)3|&N%wp3e&gnr04aGR& z+)`pJ8Kg+kP|nH(mcWAwD*&pgb)DCpUvcg1K4p&-VOV z24Lo(xXAR}l5EuEavU+1Hp#zj{<93g6~nw7vm*zxep5#Yq{xbY`Smv$fV+$eleH{u z@dl1<#G#_9Z@&L71AycgY#RXB^!{hqhD@vLzIZrwt9^H6Dn3pE8ypi_4H=pea_&wz ziA}hUO?Zw?0FO(6k4r#}<69(HT!1&I$`Q`h9El>H{DxgY6KKe$r3pP~-B^zjw`yxe zvz@m3(|z`bF~hdE34F_sp{f3%x&EQ0{-L%0q0RoGU9p(5VZf5bD>e1&yPJys>xb`& zrVH?@^{oEeWuMrz)K}CNSJc#3)fQLP)YsG&*VNS4?`~fDt|kAFV`cCs#sU~;6p>&R zk>C`O;1!YZIU*r4A|WAyqd4hDpEU**)J~mfL-K`2w{>H+bXB!XRkdtYwcLB+EcxRg zsz+ohSd{g(?8Y_Z1^c;g*nJlQp+T#*MgsaqLi$D``bJ{6GI+Rd#r;s_`r_n;$NS6&xXu3eCz-A!zdq3c z9^6kN! z;Rwr2jG$Bd_SeEyh_~TGB05{wD;hTwu%EG}4Ib=Je8Zo%< zxy4Ma!z*QhP8Fxj@1eg8<^2@~Ed%G{MQwH*zlz}5 z%|t}PPdIYhTKj?|bVF3$l$!yhy2#0echB?~>mY_Q`5FxHB4~?Jy_Yr#eQ;IA{916J zOH4$ytN0krez+2HP(9uJL8^#!a9(FVqDbik6LUlduy&Lt5ofSvKOG70CjC*f4HWgY zX>Fg;V&%>1d`t}|>20qU|2Z#Bg^r4g+k%CaSOuW0eMY^w8oJk+<9R74UY_9I8pM`w|X# z#Y;&lp;DB%iwLgeP_ez>0X*HUojpa{g3u!rYecuQFCR44Nq@R%xGLgDh;>o`} zZy;9VV@qw*Fu26xWVv`0I1GwRxDL$KoX{jIKgd z>ZAmUCrPuW>h}E&_<_w*#XCuZwnZ)HpAdjsF%|D_BA4uYd$Hw5Ox>A3&%Lv1a5yy( z&#IB3^90|Z%E#dq5MYkTm7<&6D^5kVfacxKfd_&&RGUO8{v`Uq9!PGznMXzbPCiJH z_J@F3)eJ37*Xx6Bua@%Fg=@kFNQM{6P_dW>60wi~lQP07$b2@C+vUYF8(mf|;4_2Q z+wS2mc$!R37SG4VjUzCPJu)n?vg2j@mX1%jgXi_|dV2iHRlVo+X;qBx`K}lb>Yiot zb#`yu+wJ^#79H>PVN?;pQ+vbu{n}UPSkvJ2Y_CjT>puF5?L4a8-2I+pP84>CHQYHG zRIbhp0%KmSfW|%#{OsC0-v-Fws4~bZ4Dv(ud!2OlPOCBX0N6_4(}Ow~v{SgLfsRHD z6uUf!&oLSGUQDD>$sTZpFk-|cFb6JAA&3ZzLXsa^tf%E|2OnX0 z@{0V5=ZQZoIf0l7)=D7%9G)P7Pn>FA(ss%kTBO2n6+-a0B4P%J9ADc+pt{K##h{vf`iTSrOrl1~1lJ?K zmRKU`>H)53l^s5Q5#Nt=WMaxF&{X0i@Zcxp70NvMk@B6X$IQQ%dW>tsiOlhn&1K@0 zHX1If9~X){ZwPwjM`x0s=rp&d)grU;vu!hTK+CMpozug-W%3%MUg`MOve+5m7~L7fsNGzVnpV0?dNV`Eb6RIaavm*n*8Mm=uM z73_vMj1BU_Mu?qiC*q84CwmjETbK2XsAi>Wno1HPO$!Wcm9R_8WVowe)L2~E>q$Ks zi0;N9sOY-CsSm$%U^cDvSUQ~(BWl>sr<)aF46^yYBBpU>hL;c-FIvTzA2Qbs5s;~t zxt06foMrUpgGx(CeAuwEF*V!8T8pb0b3uly#NJ7YqoElChkBUop+I@F8oYc+jr&9} zFpU-|rmObh*@qEA_8q8%Z=Zau8PjYtTx)g_h8agz%2x|foDca)^Oiap>%V@|*&*mu zV3K9Mpi}88OUm~x#L|`y%SVL@>X3o?mV2Zzbrvs=nxXBgzk2`?lcc~aFO1XEhCE{g zS{2>(%&8=hg_}Sx!G!M=?7$XMwWsrA< z(kH&AegPtY>r~)mxw{Sc{SOVJ9K+ptEYjq&ypb{4-|&jn5UU}L28Gu-MuzU!jMS^s zV^8QwH-|>TR!RB;ogCq{<~%%n^`V>;WiA-?Y)!Vt+s2uSun$Q0vX<@_3^N;el8;Lg zU;Nv|^X0E#H3ddnZc{SNwcf2&SB*E#E`_n=pX*P`93{$`36QnNw+2vateGZv7eS%_U0=*>FAKNj+=|effY)6`EJIktMK?};f?7PfdP)e3vccn8A_`MRMeVp_aU(2 z6s{1T{}%b((6|28n5Vg>Ajgxp2l0RJy)-c1>#|@#K&hxeK=6O`UI#}vOCyK3sdhwd z-6oeE(VOq!1#48OSkrv^NoYTX2Ut2SX5MQfz!_c)Zdw672BmJ)?E(B1y%Ct#~F~*iA|*_ugq>9 zZKfryFq^dB=TOUcm4cOj(U7xj8B)pXnfyOr;p|FIC!0 z5S&5+^l5@#iozEt5Gs$J4cbE9_T;_ryi8{)i&CKt73eq}*+>z)SiKiRN}oT-rBaj| zPqr^`uv|sn0PAUkMFHPVsA&2L8d8*mCp*0F`H3xNx8ECkbQilg@JRI211t#$-@cnX zOyB4Dp`F5$PC!o!n42zeAD9$#(_1e ziQ(E5i)=g52O+E>iqSG#^|O58a~ki%(f7?XMw(f4^3M~1lSH#epraLD+Jrd-=XTH% z)~ZllQstDzZ0}enfsz5x9ec^DIc(*;Woa7rYCUuAcm%DR1lFV_%&HVqt%~3j9=&n{ z59bf*$&&DH>+>;qpppqU9(o|4F${>lc$9snBOWN|v6E=kpzRf- zFxU_1jsrcA`+OLpAg?vKMbA^k)9nc9fN=B=AA=ab;-9#N(C`aLL5jL--o3 zkrHu{&r1m({ffK`Z=Q-SRbzplj|GvL|4UnnZr?mxFgCZ9 zvorVJVMmw95_ZMpNE=={cLiTDhF1Nca}CYivQA=lSGJ$c1FJ7j53a}8OAgzNkDSgc zv3Q%ND4)0VzCcvCe0aD_!-t1h2vF5&;HW=hMR&pSr2kk;9B~m<8uj%nin#v|Q10Re6tdix(C4yK>%jSLkX?ai!Be({f^nzr0BJ&IRW z?W_Eb7fN#d*J6~WC{4nPx&>_s-7*-)B4I_*@3qg5+FYN_R<^{(LeG-M+vbhz&pmGG zA7;6omc2Z1GjKkLR97r?Q!AZEEtuwd@{Z#iknTBm2;4{EKByRq-iB=M7rh8iOIE(+Ab-%NjYZtPWA%a zWLKi(I22+I2h=l9P#5G*L5U>TM1r;?bt{e+p(mO`efvw7fqzi=(lEKv{+;H9P^&I&>#-Z>DL8?x#1Y!$Ux_-dv>Adp-gONbv5K|RFb#PR#!kPqsWc>y{eMm*pRqUF$ zWHao)URPTKxXaBZLn@7wqs7#0%P^K6T&hJyxl3kbN>Hau91;RtBTRCKoognW@k;{r zls~G*k_B#lvuM7skiU68LsT8b~ zjGzvSbwHUgnO~X8ZYlV5h>%ybz2yz{ex&eUPe?M=D>y8a6VlLu$8)2i(y|y#?lQ6> zlaRA`$zYEfTRLLE-ePt&eS}?ub4+T)tR*3sM)IWMFxWHeaV8Y~T8=;LA@FPh9mdj3uB)H4oidxu_eiIlc-txSJg!EhB3g*w+{CpV@>7-Puz>v;N$NC900vs9~EY*nztemb$ zfw```JdO=g@~5ti&F!R9dANBNi^V1;U8*iT%}O}rXcPU9xnk^?21LV!@+NS2+!Mrr zTd-{3OKx#VHybz5v+FRdXzEh*7BujE)9=Lw(YD)+!Su2C5YowF$Xz8wQ&e&%X!mi8 z|D%DL65f|w5L&^CCi8cRzL_r!YUXykJ$<0`r)0D!91NBoBjrL}3IrGfBVV(9$M%-R zTa8BbPH?K5@1rkqW~R#m4$3}p2Ie@<(SHyG9o@!Cxh~D}D`tFc>+Qdyi$2i($7#gf zaDUSX1PCY&Fp*&YK?;WUpIqMffX>;}DU6ky>}?*tCxwO8&ii)* z8eh3a8dV@39S5+L2OpG!C_)*xn0QYJ3M%O@Y9nJ@%UGBww_LOZv$)d99L8XLMcpoo zn0T{j;tf}P97Hi#R&mUWXjG)AnRFtpM%b$6`cw;pclSvx^(q&6F!s((q3aln(iSjt zRX`AzSrjl&z7@heMi?}H1KM-+`#K)MR?B(rCa^KGOM=WNwF^78*@aNK-%BdW;u-*v z9)pc=$r*WnH=CkqS$Z3v+6kzMo0A`mBD`P~WsbypyfsE8R}4DVmZ0(P&-Z@LcUnuc>l`EJEZ->;uHDSmZC!Nxvy_S4cEE%9dY6$mw@k@w5?XPy zJ878Xt*JjU#13!_i$WBn{{iFH~|=_uhWSxG3kQlgff z>}ja#c)sCX@F?El?!sdsNfn+Ja$SvH5ma^DSsmygLXqbQau_dlRt zAFDZ4EIB#ANOep$+N?{kI*}ZSR10m2HejMI#+*I0&RXx&@TxeHDkoZg{1qbfnsCbs zmV=O=YhyQOvb$6W`EXWX^pEp_(sDY68`F`09FVog)!Q?CB8Z)cX>^R`cmfZ+Y>YT-#9l}Hcp%`5(C1hzK&ZjC^Gbej#i2#v}TW+Sje zzDI*O{if#wDvYht>W;b|*@Z0@%TGqJ@VvjuyBu5oxaY)S@|*0t?ZI)^qW1p zmj5L)THrCJQW>gp&3ZF!K|p4lSxoR)<)jLqdOqmlv8{&tqIcOp1E}1TfR20k>$Tws z%;Q`woOLZ+UAGE2=vYM1+}eKnT$_ED0;8OD8U^>xR6nS?0>bE4ryfJUwa!X+-`O@k zb|OMFR}K}?lsT+xP;7Bte~l)!_GGP_>OmX2TiQ1aOsyL|xTKfvhyE(7*fuIV@gy z)+DNBERD=X#@ znNot2Q8B~vdwx#0`~7~II+=NgC>v4pD{Q?Kw61k-_b}p$NJ58NqQS#g6O7y<)M`q6 zk(8Gb*t|2v;_CEqq9dKlfp;#2j9tIW%M?^}h>9n|R*u4cv=J-_M%4NW69oT$LW zs{d@-FOCjuIT)i8y?@t)PoGM6oqG?@Ui1$54txakiiE~2k<Qfsbr>^Yav6h2v$VIcj}sUDuN)-(rh9 z>pyhPbz;hd+1jvrV)t(9Sl)~F&Q(04KgyZa^-83RP4Ag_s-`lLlQtK%V6d?!tG?M- zHFQ{8=z&(DZ@q8w`j_d)uUEQ2?kq(NQ2hFVREK^|bCiRf9bo6{vel=^*LfP&FAS|> zS*2CQjTbOX0qF$)wLwnk_AsLoGYvJR8+XwU&?8_N|lZ||`=@4c*ILl&;=S6b8QM6WmOdp~bleWUj1*+P%zQajU~0fTl~ zJUw`zPp#sPZ#J?z+)=Mn{V38{k2*@z*Nl%m^3+uOJP?`2B#cbWQKrvBf`RCgM_R|zOndO(?? z0~{zXJD{|k9UNVRP!7%(UzAHFGttp(8 z`iw)0&gHj`TdQUaZd6%UcDL?4Fe`U>NNy>{_L{caJVlRQ1fEWlGE4z`THh-P*XztQ zl-_);5MIQwS4uiSsg1bG#}FLaSXW|4V_@QsB}2&YYDBuf;Rr5fkkKB1KTQv;u+AsS z-*m_BWkFX{+@W{IGI{@sA2H7x)?KH z<*DPIo%iU|l;fBt#oR`pj9{gI#~Ch#gE(lw-W%<${nNw6#_2q8SGrggSs1*^%%yG| z8)ZLHv~=-adO8xf3Dcp^{uGlH4vouVAhKy+UM9jAhqk>z$~I?f-2gIA3z#KBf6P2H zN5|iZ2MpP_*PU2Rtr20s>Yabam$F(nn^7;XRpi1)?tN(mFUhP%G}x(oBW0Cd&P{oA zUXPi6a3Qqc`-#`OXQMt#WkLG|)d}+>4X!a*nt+H*>Lf+kddL9o}p@JS#ZHqs&aCV+=Q}VNlgy6yjH`Cuthg&|53w~cK9@< zBGs6+i#TJ|NJeH+VqAy2_j1LX6EykV?O7l3>_nqUw3Tjy!CCjJlDD@wC78MjYO8tA zpp*HfG`d^aY2$74`A6t(t{u5&Bs@rnYlOed%~YX|GjAnSeeA<4FWN$-?qv;y^V#gwZbNT}V_;g|-Jb z><&&TZ%V&R_SpUotQlr+O^JN42|RI-fZxnyPv6{uepg2=FFxh@?A;R~l<~Q|*N2W= z^KG)&Pdyp86zy&0Y?yT4f9~QZ4;)%LYJHQ?wQ?wRY>jW%arjA}fDNGQ^>v=NgX|cf zL~sAM4c~vZ@9*3EiG#NK&w!tu;=c!edB+3S#t**n;6Si@HYxNI;HM4p(gp|r>^)2h zg+S(j75!g35ra8k2U-$IoaVnL@lE+4X&zt-__1ITWsG-Q%9d^brhqr$ktkI%+fufc z*8;MND209Hmx1Ocrr z!e8m6U=UcuB7s`ZZh`(u(gFj)nh**2T<33qB!vhJ1gj||;E3+u07=>k7zm#9lYryr zwtygILI`xcrBr~S;FTZ=`r`Z+^rv+pIQp+oDZ=pIoYK~+1PuLo)<-%a2*lMG0{LYQ n2oC@G*8OAn`%6EBf4h-ut5X2g=*xyZ28b{P1oF`A%h7)Tc93T{ diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index cd04a511d5..f47b7dbe36 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -341,45 +341,48 @@ F_DT_WEEK S_DT_WD F_DT_YWWD S_DT_YMON -S_DT_YMD -S_DT_YMDD -F_DT_YMDAY +F_DT_YMD +F_DT_YMDD S_DT_DM S_DT_DMM F_DT_DMONTH S_DT_DMON -S_DT_DMY -S_DT_DMYY -S_DT_DMYYY -S_DT_DMYYYY -F_DT_DMYEAR -F_DT_YMDAY +F_DT_DMY +F_DT_DMYY +F_DT_DMYYY +F_DT_DMYYYY S_TM_START -S_TM_H +F_TM_H F_TM_HH -F_TM_HH -S_TM_M +S_TM_HM +F_TM_M F_TM_MM -S_TM_S +S_TM_HMS +F_TM_S F_TM_SS -S_TM_N -F_TM_NNN +F_TM_N1 +F_TM_N S_TZ_START S_TZ_H F_TZ_HH +F_TZ_HM S_TZ_M -F_TZ_MM - +---FINAL-STATES-- +T_TM_NZ +T_TZ_H +T_TZ_HH +T_TZ_M +T_TZ_MM C_DT_DIGIT 0-9 C_DT_LETTER abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY C_DT_SLASH / C_DT_DASH - +C_DT_T T +C_DT_W W C_DT_PLUS + C_DT_COLON : C_DT_DOT . -C_DT_T T -C_DT_W W C_DT_Z Z C_DT_ILLEGAL all the rest C_DT_EOF EOF @@ -407,41 +410,42 @@ F_DT_YEARL2->digit->S_DT_YM \->letter->S_DT_YMON \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->F_DT_WEEK \->digit->S_DT_WD->eof->F_DT_YWWD - \->"T"->S_TM_START + \ \->"T"->S_TM_START + \->"T"->S_TM_START F_DT_DDD->"T"->S_TM_START - -F_DT_YMONTH->digit->S_DT_YMD->digit->S_DT_YMDD->sep|eof->F_DT_YMDAY - \->sep|eof->F_DT_YMDAY +F_DT_YMONTH->digit->F_DT_YMD->digit->F_DT_YMDD->dtsep->S_TM_START + \->dtsep->S_TM_START F_DT_DAYL->digit->S_DT_DM->digit->S_DT_DMM->sep->F_DT_DMONTH \ \->sep->F_DT_DMONTH \->letter->S_DT_DMON->letter->S_DT_DMON \->sep->F_DT_DMONTH -F_DT_DMONTH->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR->digit->F_DT_DMYEAR - \ \ \->sep->S_TM_START - \ \->sep->S_TM_START - \->sep->S_TM_START - +F_DT_DMONTH->digit->F_DT_DMY->digit->F_DT_DMYY->digit->F_DT_DMYYY->digit->F_DT_DMYYYY->dtsep->S_TM_START + \ \ \->dtsep->S_TM_START + \ \->dtsep->S_TM_START + \->dtsep->S_TM_START + +S_TM_START->digit->F_TM_H->digit->F_TM_HH->":"->S_TM_HM + \->digit->F_TM_M -S_TM_START->digit->S_TM_H->digit->F_TM_HH->":"->F_TM_HH -F_TM_HH->digit->S_TM_M->digit->F_TM_MM->":"->F_TM_MM -F_TM_MM->digit->S_TM_S->digit->F_TM_SS->":"->F_TM_SS +S_TM_HM->digit->F_TM_M->digit->F_TM_MM->":"->S_TM_HMS + \->digit->F_TM_S -F_TM_SS->"."->S_TM_N->digit->S_TM_N - \ \->"Z"|eof->F_TM_NNN - \ - \->sign->S_TZ_START - -F_TM_NNN->sign->S_TZ_START +S_TM_HMS->digit->F_TM_S->digit->F_TM_SS->"."->F_TM_N1->digit->F_TM_N->digit->F_TM_N + \ \->"Z"|eof->T_TM_NZ + \ \->sign->S_TZ_START + \->sign->S_TZ_START -S_TZ_START->digit->S_TZ_H->digit->F_TZ_HH->":"->F_TZ_HH - \->":"|eof->F_TZ_HH +S_TZ_START->digit->S_TZ_H->digit->F_TZ_HH->":"->F_TZ_HM + \ \->eof->T_TZ_HH + \->":"->F_TZ_HM + \->eof->T_TZ_H -F_TZ_HH->digit->S_TZ_M->digit->F_TZ_MM - \->eof->F_TZ_MM +F_TZ_HM->digit->S_TZ_M->digit->T_TZ_MM + \->eof->T_TZ_M From 57959874d0975d9c2f550aa7ed85f0cf2d32344e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 26 Oct 2019 12:59:21 +0200 Subject: [PATCH 0325/3432] FEAT: adds pipeline for generating date! transitions table. --- docs/lexer/date-FSM.csv | 45 ++++++++++++++++ docs/lexer/lexer-FSM.xlsx | Bin 25871 -> 26291 bytes docs/lexer/lexer-states.txt | 4 +- runtime/lexer-transitions.reds | 74 +++++++++++++++++++++++++- utils/generate-lexer-table.red | 94 ++++++++++++++++++++++++++++++++- 5 files changed, 213 insertions(+), 4 deletions(-) create mode 100644 docs/lexer/date-FSM.csv diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv new file mode 100644 index 0000000000..5fd0c6977d --- /dev/null +++ b/docs/lexer/date-FSM.csv @@ -0,0 +1,45 @@ +;C_DT_DIGIT;C_DT_LETTER;C_DT_SLASH;C_DT_DASH;C_DT_T;C_DT_W;C_DT_PLUS;C_DT_COLON;C_DT_DOT;C_DT_Z;C_DT_ILLEGAL;C_DT_EOF +S_DT_START;S_DT_D;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_D;S_DT_DD;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YYY;F_DT_YEARL;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YEARL;S_DT_YM;S_DT_YMON;F_DT_YEARL;F_DT_YEARL2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YEARL2;S_DT_YM;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_DAYL;S_DT_DM;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YM;S_DT_YMM;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YMM;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YV;S_DT_YW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_DT_WEEK +S_DT_YWW;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_WEEK;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_DT_YWWD +F_DT_YWWD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YMON;T_DT_ERROR;S_DT_YMON;F_DT_YMONTH;F_DT_YMONTH;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YMD;F_DT_YMDD;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY +F_DT_YMDD;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY +S_DT_DM;S_DT_DMM;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_DMM;T_DT_ERROR;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_DMONTH;F_DT_DMY;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_DMON;T_DT_ERROR;S_DT_DMON;F_DT_DMONTH;F_DT_DMONTH;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;F_TM_N1;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_N1;F_TM_N;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ +S_TZ_START;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TZ_H;F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_H +F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH +F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TZ_M;T_TZ_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 6a40e003d1a916eee0f2dfaabc2286e82cb613d6..e8972e11005b1311554408205d25584b16602e9b 100644 GIT binary patch literal 26291 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 E2l7lCumAu6 literal 25871 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 Date: Sat, 26 Oct 2019 22:58:26 +0200 Subject: [PATCH 0326/3432] FEAT: preliminary work for scanning date! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26291 -> 25954 bytes runtime/lexer-transitions.reds | 11 ++- runtime/lexer.reds | 81 +++++++++++++++++++- utils/generate-lexer-table.red | 133 +++++++++++++++++++-------------- utils/generate-misc-tables.red | 64 +++++++++++++++- 6 files changed, 227 insertions(+), 64 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 953ac6f221..35aaf0851c 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -23,7 +23,7 @@ S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_F S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_EOF +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index e8972e11005b1311554408205d25584b16602e9b..d31b72f4e78648d0efcba57184d97c130852341d 100644 GIT binary patch literal 25954 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 literal 26291 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 E2l7lCumAu6 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a313db09e4..341d276eb3 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -132,7 +132,14 @@ Red/System [ T_TZ_HH T_TZ_M T_TZ_MM - ] date-transitions: #{ + ] + fields-table: #{ +0104040202020403030304090909090A0A030404030303030202020201050505 +06060607070808010B0B0C0C +} reset-table: #{ +000000001F1F1F00001F1F0000001F001F00001F00001F000000001F1F00001F +00001F001F00001F00001F00 +} date-transitions: #{ 012D2D2D2D2D2D2D2D2D2D2D022D06062D2D2D2D2D2D2D2D032D06062D2D2D2D 2D2D2D2D042D04042D2D2D2D2D2D2D2D07110405112D2D2D2D2D2D2D07112D2D 110B2D2D2D2D2D2D14172D2D2D2D2D2D2D2D2D2D082D09092D2D2D2D2D2D2D2D @@ -176,7 +183,7 @@ Red/System [ 1B32423215324232423240323232173232323232324242424242424242424242 4216424216161642424216424242421642164216163231434317174343434343 4343323243323232433243323232323217323232323232434444181844444444 -4444441818441818181818441844184444184418441818323132321A1A323232 +4444441818441818181818441844184444184418441818324432321A1A323232 323232323232323232323232323232323232323232323232323246461A1A4646 464646464632321A32323246324632323246321A3232323232323132321C1C32 3232323232323232323232323232323232323232323232323232323245451C1C diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 735cb77c8d..8aab4bdb21 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -157,6 +157,28 @@ lexer: context [ "none" 4 TYPE_NONE ;... to be eventually completed ] + + date-cumul: #{ + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000010203040506070809000000000000 + 004142434445464748494A004C4D4E4F5000525300555600000D000000000000 + 006162636465666768696A006C6D6E6F70007273747576000003000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + } + + date-classes: #{ + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A060A03080200000000000000000000070A0A0A0A0A + 0A010101010101010101010A01010101010A0101040101050A01090A0A0A0A0A + 0A010101010101010101010A01010101010A01010101010A0A010A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + } lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL @@ -1049,11 +1071,62 @@ lexer: context [ cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) state/in-pos: e ;-- reset the input position to delimiter byte ] - - scan-date: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + + scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + cell [cell!] + field [int-ptr!] + state [integer!] + class [integer!] + index [integer!] + cp [integer!] + c [integer!] + pos [integer!] + shift [integer!] ][ - null +probe "scan-date" +probe as-c-string s +probe as-c-string e + field: system/stack/allocate 12 + c: 0 + state: S_DT_START + loop as-integer e - s [ +probe ["--- " s/1 " ---"] + cp: 1 + as-integer s/1 + class: as-integer date-classes/cp +?? class + index: state * 12 + class + 1 + state: as-integer date-transitions/index +?? state +?? cp + c: c * 10 + as-integer date-cumul/cp +?? c + index: state + 1 + pos: as-integer fields-table/index + field/pos: c +?? index + shift: as-integer reset-table/index + c: c >>> shift + s: s + 1 +?? c + ] + probe [ + "trash: " field/1 + "^/year : " field/2 + "^/month: " field/3 + "^/day : " field/4 + "^/hour : " field/5 + "^/min : " field/6 + "^/sec : " field/7 + "^/nano : " field/8 + "^/week : " field/9 + "^/wday : " field/10 + "^/TZ-h : " field/11 + "^/TZ-m : " field/12 + ] + system/stack/free 12 + cell: alloc-slot lex + cell/header: TYPE_NONE ] scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index dd4f29e47c..2a24032ea4 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -89,61 +89,74 @@ context [ T_EMAIL ;-- 74 T_PATH ;-- 75 ] - +;trash 1 +;year 2 +;month 3 +;day 4 +;hour 5 +;minute 6 +;second 7 +;nsec 8 +;week 9 +;weekday 10 +;tz-hour 11 +;tz-min 12 + date-states: [ - S_DT_START ;-- 0 - S_DT_D ;-- 1 - S_DT_DD ;-- 2 - S_DT_YYY ;-- 3 - F_DT_YEARL ;-- 4 - F_DT_YEARL2 ;-- 5 - F_DT_DAYL ;-- 6 - S_DT_YM ;-- 7 - S_DT_YMM ;-- 8 - F_DT_YMONTH ;-- 9 - F_DT_DDD ;-- 10 - S_DT_YV ;-- 11 - S_DT_YW ;-- 12 - S_DT_YWW ;-- 13 - F_DT_WEEK ;-- 14 - S_DT_WD ;-- 15 - F_DT_YWWD ;-- 16 - S_DT_YMON ;-- 17 - F_DT_YMD ;-- 18 - F_DT_YMDD ;-- 19 - S_DT_DM ;-- 20 - S_DT_DMM ;-- 21 - F_DT_DMONTH ;-- 22 - S_DT_DMON ;-- 23 - F_DT_DMY ;-- 24 - F_DT_DMYY ;-- 25 - F_DT_DMYYY ;-- 26 - F_DT_DMYYYY ;-- 27 - S_TM_START ;-- 28 - F_TM_H ;-- 29 - F_TM_HH ;-- 30 - S_TM_HM ;-- 31 - F_TM_M ;-- 32 - F_TM_MM ;-- 33 - S_TM_HMS ;-- 34 - F_TM_S ;-- 35 - F_TM_SS ;-- 36 - F_TM_N1 ;-- 37 - F_TM_N ;-- 38 - S_TZ_START ;-- 39 - S_TZ_H ;-- 40 - F_TZ_HH ;-- 41 - F_TZ_HM ;-- 42 - S_TZ_M ;-- 43 - --FINAL-STATES-- ;-- 44 - T_DT_ERROR ;-- 45 - T_DT_YMDAY ;-- 46 - T_DT_DMYEAR ;-- 47 - T_TM_NZ ;-- 48 - T_TZ_H ;-- 49 - T_TZ_HH ;-- 50 - T_TZ_M ;-- 51 - T_TZ_MM ;-- 52 + ;-- state ----------- reset? -- field -- + S_DT_START 1 1 ;-- 0 + S_DT_D 1 4 ;-- 1 + S_DT_DD 1 4 ;-- 2 + S_DT_YYY 1 2 ;-- 3 + F_DT_YEARL 0 2 ;-- 4 + F_DT_YEARL2 0 2 ;-- 5 + F_DT_DAYL 0 4 ;-- 6 + S_DT_YM 1 3 ;-- 7 + S_DT_YMM 1 3 ;-- 8 + F_DT_YMONTH 0 3 ;-- 9 + F_DT_DDD 0 4 ;-- 10 + S_DT_YV 1 9 ;-- 11 + S_DT_YW 1 9 ;-- 12 + S_DT_YWW 1 9 ;-- 13 + F_DT_WEEK 0 9 ;-- 14 + S_DT_WD 1 10 ;-- 15 + F_DT_YWWD 0 10 ;-- 16 + S_DT_YMON 1 3 ;-- 17 + F_DT_YMD 1 4 ;-- 18 + F_DT_YMDD 0 4 ;-- 19 + S_DT_DM 1 3 ;-- 20 + S_DT_DMM 1 3 ;-- 21 + F_DT_DMONTH 0 3 ;-- 22 + S_DT_DMON 1 3 ;-- 23 + F_DT_DMY 1 2 ;-- 24 + F_DT_DMYY 1 2 ;-- 25 + F_DT_DMYYY 1 2 ;-- 26 + F_DT_DMYYYY 0 2 ;-- 27 + S_TM_START 0 1 ;-- 28 + F_TM_H 1 5 ;-- 29 + F_TM_HH 1 5 ;-- 30 + S_TM_HM 0 5 ;-- 31 + F_TM_M 1 6 ;-- 32 + F_TM_MM 1 6 ;-- 33 + S_TM_HMS 0 6 ;-- 34 + F_TM_S 1 7 ;-- 35 + F_TM_SS 0 7 ;-- 36 + F_TM_N1 1 8 ;-- 37 + F_TM_N 1 8 ;-- 38 + S_TZ_START 0 1 ;-- 39 + S_TZ_H 1 11 ;-- 40 + F_TZ_HH 1 11 ;-- 41 + F_TZ_HM 0 12 ;-- 42 + S_TZ_M 1 12 ;-- 43 + --FINAL-STATES-- 0 1 ;-- 44 + T_DT_ERROR 0 1 ;-- 45 + T_DT_YMDAY 0 1 ;-- 46 + T_DT_DMYEAR 0 1 ;-- 47 + T_TM_NZ 0 1 ;-- 48 + T_TZ_H 0 1 ;-- 49 + T_TZ_HH 0 1 ;-- 50 + T_TZ_M 0 1 ;-- 51 + T_TZ_MM 0 1 ;-- 52 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -188,16 +201,20 @@ context [ ;-- Generate the date table content dt-table: make binary! 2000 + reset-table: make binary! 100 + fields-table: make binary! 100 foreach line next matrix [ out: make block! 50 foreach s next line [ either pos: find date-states to-word s [ - append out (index? pos) - 1 + append out ((2 + index? pos) / 3) - 1 ][ do make error! form reduce ["Error: state" s "not found"] ] ] + append reset-table to-char pick 0x31 (select date-states to-word line/1) = 1 + append fields-table to-char third find date-states to-word line/1 append/only dt-table out ] @@ -210,9 +227,13 @@ context [ ] #enum date-states! [ - (date-states) + (extract date-states 3) ] + fields-table: (fields-table) + + reset-table: (reset-table) + date-transitions: (dt-table) transitions: (table) diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index d73e8dddc0..ecff17344f 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -68,7 +68,69 @@ gen-hexa-table: function [][ probe out ] +bin-classes: [ + C_DT_DIGIT ;-- 0 0-9 + C_DT_LETTER ;-- 1 abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY + C_DT_SLASH ;-- 2 / + C_DT_DASH ;-- 3 - + C_DT_T ;-- 4 T + C_DT_W ;-- 5 W + C_DT_PLUS ;-- 6 + + C_DT_COLON ;-- 7 : + C_DT_DOT ;-- 8 . + C_DT_Z ;-- 9 Z + C_DT_ILLEGAL ;-- 10 all the rest + C_DT_EOF ;-- 11 EOF +] + +gen-date-table: function [][ + out: make binary! 256 + digit: charset "0123456789" + letter: charset "abcdefghijlmnoprstuvyABCDEFGHIJLMNOPRSUVY" + + repeat i 256 [ + c: to-char i - 1 + append out to-char case [ + find digit c [0] + find letter c [1] + c = #"/" [2] + c = #"-" [3] + c = #"T" [4] + c = #"W" [5] + c = #"+" [6] + c = #":" [7] + c = #"." [8] + c = #"Z" [9] + 'else [10] + ] + ] + print "--gen-date-classes-table-- (lexer/date-classes)" + probe out +] + +gen-date-calc-table: function [][ + out: make binary! 256 + digit: charset "0123456789" + letter: charset "abcdefghijlmnoprstuvABCDEFGHIJLMNOPRSUV" + yY: charset "yY" + + repeat i 256 [ + c: to-char i - 1 + append out to-char case [ + find digit c [to-char c - #"0"] + find letter c [to-char c] + c = #"y" [3] + c = #"Y" [13] + 'else [0] + ] + ] + print "--gen-date-cumul-table-- (lexer/date-cumul)" + probe out +] + gen-bitarray "BDELNPTbdelnpt" gen-bitarray {/-~^^{}"} gen-bin16-table -gen-hexa-table \ No newline at end of file +gen-hexa-table +gen-date-table +gen-date-calc-table \ No newline at end of file From 7998b349feef5f716ea518d79093de8cdb214c65 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 13:19:13 +0100 Subject: [PATCH 0327/3432] FEAT: numerous fixes and improvements to the date! parsing FSM. --- docs/lexer/date-FSM.csv | 10 ++-- docs/lexer/lexer-FSM.xlsx | Bin 25954 -> 26202 bytes docs/lexer/lexer-states.txt | 9 ++-- runtime/lexer-transitions.reds | 45 ++++++++-------- runtime/lexer.reds | 35 +++++++++++-- utils/generate-lexer-table.red | 91 +++++++++++++++++---------------- 6 files changed, 108 insertions(+), 82 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index 5fd0c6977d..1ff08c3a6e 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -11,11 +11,9 @@ S_DT_YMM;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YV;S_DT_YW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_DT_WEEK +S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK S_DT_YWW;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_WEEK;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_DT_YWWD -F_DT_YWWD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YWWD S_DT_YMON;T_DT_ERROR;S_DT_YMON;F_DT_YMONTH;F_DT_YMONTH;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YMD;F_DT_YMDD;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY F_DT_YMDD;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY @@ -24,8 +22,8 @@ S_DT_DMM;T_DT_ERROR;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_D F_DT_DMONTH;F_DT_DMY;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DMON;T_DT_ERROR;S_DT_DMON;F_DT_DMONTH;F_DT_DMONTH;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index d31b72f4e78648d0efcba57184d97c130852341d..5f331b14d1eb6525e5e4b6eb9b71cf4832cd21c1 100644 GIT binary patch literal 26202 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 Q{xA{*lM)ahEPfpQ3+odM9RL6T literal 25954 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index e3a29f7246..fa3f5214db 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -337,9 +337,7 @@ F_DT_DDD S_DT_YV S_DT_YW S_DT_YWW -F_DT_WEEK S_DT_WD -F_DT_YWWD S_DT_YMON F_DT_YMD F_DT_YMDD @@ -368,8 +366,11 @@ F_TZ_HH F_TZ_HM S_TZ_M --FINAL-STATES-- +T_DT_ERROR T_DT_YMDAY T_DT_DMYEAR +T_DT_WEEK +T_DT_YWWD T_TM_NZ T_TZ_H T_TZ_HH @@ -410,8 +411,8 @@ F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH F_DT_YEARL2->digit->S_DT_YM \->letter->S_DT_YMON - \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->F_DT_WEEK - \->digit->S_DT_WD->eof->F_DT_YWWD + \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->T_DT_WEEK + \->digit->S_DT_WD->eof->T_DT_YWWD \ \->"T"->S_TM_START \->"T"->S_TM_START diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 341d276eb3..0f29d1118d 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -93,9 +93,7 @@ Red/System [ S_DT_YV S_DT_YW S_DT_YWW - F_DT_WEEK S_DT_WD - F_DT_YWWD S_DT_YMON F_DT_YMD F_DT_YMDD @@ -127,6 +125,8 @@ Red/System [ T_DT_ERROR T_DT_YMDAY T_DT_DMYEAR + T_DT_YWWD + T_DT_WEEK T_TM_NZ T_TZ_H T_TZ_HH @@ -134,29 +134,28 @@ Red/System [ T_TZ_MM ] fields-table: #{ -0104040202020403030304090909090A0A030404030303030202020201050505 -06060607070808010B0B0C0C +01040402020204030303040909090A0304040303030302020202010505050606 +0607070808010B0B0C0C010104020A09080B0B0C0C } reset-table: #{ -000000001F1F1F00001F1F0000001F001F00001F00001F000000001F1F00001F -00001F001F00001F00001F00 +000000001F1F1F00001F000000000000000000001F00000000001F00001F0000 +1F00001F001F00001F001F1F1F1F1F1F1F1F1F1F1F } date-transitions: #{ -012D2D2D2D2D2D2D2D2D2D2D022D06062D2D2D2D2D2D2D2D032D06062D2D2D2D -2D2D2D2D042D04042D2D2D2D2D2D2D2D07110405112D2D2D2D2D2D2D07112D2D -110B2D2D2D2D2D2D14172D2D2D2D2D2D2D2D2D2D082D09092D2D2D2D2D2D2D2D -0A2D09092D2D2D2D2D2D2D2D122D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1C2D2D2D -2D2D2D2D0C2D2D2D2D2D2D2D2D2D2D2D0D2D2D2D2D2D2D2D2D2D2D0E0F2D2D2D -1C2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1C2D2D2D2D2D2D10 -2D2D2D2D2D2D2D2D2D2D2D2D2D110909112D2D2D2D2D2D2D132D1C2D1C2D2D2D -2D2D2D2E2D2D1C2D1C2D2D2D2D2D2D2E152D16162D2D2D2D2D2D2D2D2D2D1616 -2D2D2D2D2D2D2D2D182D2D2D2D2D2D2D2D2D2D2D2D171616172D2D2D2D2D2D2D -192D1C2D1C2D2D2D2D2D2D2F192D1C2D1C2D2D2D2D2D2D2F1A2D1C2D1C2D2D2D -2D2D2D2F2D2D1C2D1C2D2D2D2D2D2D2F1D2D2D2D2D2D2D2D2D2D2D2D1E2D2D2D -2D2D2D2D2D2D2D2D202D2D2D2D2D2D1F2D2D2D2D202D2D2D2D2D2D2D2D2D2D2D -212D2D2D2D2D2D2D2D2D2D2D232D2D2D2D2D2D222D2D2D2D232D2D2D2D2D2D2D -2D2D2D2D242D2D2D2D2D2D2D2D2D2D2D2D2D2D272D2D272D252D2D2D262D2D2D -2D2D2D2D2D2D2D2D262D2D272D2D272D2D302D30282D2D2D2D2D2D2D2D2D2D2D -292D2D2D2D2D2D2A2D2D2D312D2D2D2D2D2D2D2A2D2D2D322B2D2D2D2D2D2D2D -2D2D2D2D342D2D2D2D2D2D2D2D2D2D34 +012B2B2B2B2B2B2B2B2B2B2B022B06062B2B2B2B2B2B2B2B032B06062B2B2B2B +2B2B2B2B042B04042B2B2B2B2B2B2B2B070F04050F2B2B2B2B2B2B2B070F2B2B +0F0B2B2B2B2B2B2B12152B2B2B2B2B2B2B2B2B2B082B09092B2B2B2B2B2B2B2B +0A2B09092B2B2B2B2B2B2B2B102B2B2B2B2B2B2B2B2B2B2B2B2B2B2B1A2B2B2B +2B2B2B2B0C2B2B2B2B2B2B2B2B2B2B2B0D2B2B2B2B2B2B2B2B2B2B2F0E2B2B2B +1A2B2B2B2B2B2B2B2B2B2B2B1A2B2B2B2B2B2B2E2B0F09090F2B2B2B2B2B2B2B +112B1A2B1A2B2B2B2B2B2B2C2B2B1A2B1A2B2B2B2B2B2B2C132B14142B2B2B2B +2B2B2B2B2B2B14142B2B2B2B2B2B2B2B162B2B2B2B2B2B2B2B2B2B2B2B151414 +152B2B2B2B2B2B2B172B1A2B1A2B2B2B2B2B2B2D182B1A2B1A2B2B2B2B2B2B2D +192B1A2B1A2B2B2B2B2B2B2D2B2B1A2B1A2B2B2B2B2B2B2D1B2B2B2B2B2B2B2B +2B2B2B2B1C2B2B2B2B2B2B2B2B2B2B2B1E2B2B2B2B2B2B1D2B2B2B2B1E2B2B2B +2B2B2B2B2B2B2B2B1F2B2B2B2B2B2B2B2B2B2B2B212B2B2B2B2B2B202B2B2B2B +212B2B2B2B2B2B2B2B2B2B2B222B2B2B2B2B2B2B2B2B2B2B2B2B2B252B2B252B +232B2B2B242B2B2B2B2B2B2B2B2B2B2B242B2B252B2B252B2B302B30262B2B2B +2B2B2B2B2B2B2B2B272B2B2B2B2B2B282B2B2B312B2B2B2B2B2B2B282B2B2B32 +292B2B2B2B2B2B2B2B2B2B2B342B2B2B2B2B2B2B2B2B2B34 } transitions: #{ 00001313333435360432020C27272727270B32202706320132271D2632272732 3101000101010101010101010101010101010101010101010101010101010101 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8aab4bdb21..851e46d76b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -74,6 +74,21 @@ lexer: context [ C_EOF ;-- 32 ] + #enum date-char-classes! [ + C_DT_DIGIT ;-- 0 + C_DT_LETTER ;-- 1 + C_DT_SLASH ;-- 2 + C_DT_DASH ;-- 3 + C_DT_T ;-- 4 + C_DT_W ;-- 5 + C_DT_PLUS ;-- 6 + C_DT_COLON ;-- 7 + C_DT_DOT ;-- 8 + C_DT_Z ;-- 9 + C_DT_ILLEGAL ;-- 10 + C_DT_EOF ;-- 11 + ] + #enum bin16-char-classes! [ C_BIN_SKIP ;-- 0 C_BIN_BLANK ;-- 1 @@ -1097,21 +1112,31 @@ probe ["--- " s/1 " ---"] ?? class index: state * 12 + class + 1 state: as-integer date-transitions/index + + index: state + 1 + pos: as-integer fields-table/index + field/pos: c ?? state ?? cp c: c * 10 + as-integer date-cumul/cp ?? c - index: state + 1 - pos: as-integer fields-table/index - field/pos: c -?? index shift: as-integer reset-table/index c: c >>> shift s: s + 1 ?? c ] + + index: state * 12 + C_DT_EOF + 1 + state: as-integer date-transitions/index +?? state + index: state + 1 + pos: as-integer fields-table/index +?? pos + field/pos: c + probe [ - "trash: " field/1 + "-----------------" + "^/trash: " field/1 "^/year : " field/2 "^/month: " field/3 "^/day : " field/4 diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 2a24032ea4..51242f2088 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -103,7 +103,7 @@ context [ ;tz-min 12 date-states: [ - ;-- state ----------- reset? -- field -- + ;-- state ----------- reset -- field -- S_DT_START 1 1 ;-- 0 S_DT_D 1 4 ;-- 1 S_DT_DD 1 4 ;-- 2 @@ -114,49 +114,49 @@ context [ S_DT_YM 1 3 ;-- 7 S_DT_YMM 1 3 ;-- 8 F_DT_YMONTH 0 3 ;-- 9 - F_DT_DDD 0 4 ;-- 10 + F_DT_DDD 1 4 ;-- 10 S_DT_YV 1 9 ;-- 11 S_DT_YW 1 9 ;-- 12 S_DT_YWW 1 9 ;-- 13 - F_DT_WEEK 0 9 ;-- 14 - S_DT_WD 1 10 ;-- 15 - F_DT_YWWD 0 10 ;-- 16 - S_DT_YMON 1 3 ;-- 17 - F_DT_YMD 1 4 ;-- 18 - F_DT_YMDD 0 4 ;-- 19 - S_DT_DM 1 3 ;-- 20 - S_DT_DMM 1 3 ;-- 21 - F_DT_DMONTH 0 3 ;-- 22 - S_DT_DMON 1 3 ;-- 23 - F_DT_DMY 1 2 ;-- 24 - F_DT_DMYY 1 2 ;-- 25 - F_DT_DMYYY 1 2 ;-- 26 - F_DT_DMYYYY 0 2 ;-- 27 - S_TM_START 0 1 ;-- 28 - F_TM_H 1 5 ;-- 29 - F_TM_HH 1 5 ;-- 30 - S_TM_HM 0 5 ;-- 31 - F_TM_M 1 6 ;-- 32 - F_TM_MM 1 6 ;-- 33 - S_TM_HMS 0 6 ;-- 34 - F_TM_S 1 7 ;-- 35 - F_TM_SS 0 7 ;-- 36 - F_TM_N1 1 8 ;-- 37 - F_TM_N 1 8 ;-- 38 - S_TZ_START 0 1 ;-- 39 - S_TZ_H 1 11 ;-- 40 - F_TZ_HH 1 11 ;-- 41 - F_TZ_HM 0 12 ;-- 42 - S_TZ_M 1 12 ;-- 43 - --FINAL-STATES-- 0 1 ;-- 44 - T_DT_ERROR 0 1 ;-- 45 - T_DT_YMDAY 0 1 ;-- 46 - T_DT_DMYEAR 0 1 ;-- 47 - T_TM_NZ 0 1 ;-- 48 - T_TZ_H 0 1 ;-- 49 - T_TZ_HH 0 1 ;-- 50 - T_TZ_M 0 1 ;-- 51 - T_TZ_MM 0 1 ;-- 52 + S_DT_WD 1 10 ;-- 14 + S_DT_YMON 1 3 ;-- 15 + F_DT_YMD 1 4 ;-- 16 + F_DT_YMDD 1 4 ;-- 17 + S_DT_DM 1 3 ;-- 18 + S_DT_DMM 1 3 ;-- 19 + F_DT_DMONTH 0 3 ;-- 20 + S_DT_DMON 1 3 ;-- 21 + F_DT_DMY 1 2 ;-- 22 + F_DT_DMYY 1 2 ;-- 23 + F_DT_DMYYY 1 2 ;-- 24 + F_DT_DMYYYY 1 2 ;-- 25 + S_TM_START 0 1 ;-- 26 + F_TM_H 1 5 ;-- 27 + F_TM_HH 1 5 ;-- 28 + S_TM_HM 0 5 ;-- 29 + F_TM_M 1 6 ;-- 30 + F_TM_MM 1 6 ;-- 31 + S_TM_HMS 0 6 ;-- 32 + F_TM_S 1 7 ;-- 33 + F_TM_SS 1 7 ;-- 34 + F_TM_N1 0 8 ;-- 35 + F_TM_N 1 8 ;-- 36 + S_TZ_START 0 1 ;-- 37 + S_TZ_H 1 11 ;-- 38 + F_TZ_HH 1 11 ;-- 39 + F_TZ_HM 0 12 ;-- 40 + S_TZ_M 1 12 ;-- 41 + --FINAL-STATES-- 0 1 ;-- 42 + T_DT_ERROR 0 1 ;-- 43 + T_DT_YMDAY 0 4 ;-- 44 + T_DT_DMYEAR 0 2 ;-- 45 + T_DT_YWWD 0 10 ;-- 46 + T_DT_WEEK 0 9 ;-- 47 + T_TM_NZ 0 8 ;-- 48 + T_TZ_H 0 11 ;-- 49 + T_TZ_HH 0 11 ;-- 50 + T_TZ_M 0 12 ;-- 51 + T_TZ_MM 0 12 ;-- 52 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -199,10 +199,15 @@ context [ ;-- Decode CSV matrix: load-csv/with read date-table first sep - ;-- Generate the date table content + ;-- Generate the date tables dt-table: make binary! 2000 reset-table: make binary! 100 fields-table: make binary! 100 + + foreach [state reset pos] date-states [ + append reset-table to-char pick 0x31 reset = 1 + append fields-table to-char pos + ] foreach line next matrix [ out: make block! 50 @@ -213,8 +218,6 @@ context [ do make error! form reduce ["Error: state" s "not found"] ] ] - append reset-table to-char pick 0x31 (select date-states to-word line/1) = 1 - append fields-table to-char third find date-states to-word line/1 append/only dt-table out ] From bd874e1626f62d55b854f31435fb84c80f44ee30 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 13:54:18 +0100 Subject: [PATCH 0328/3432] FIX: adds S_DT_YYYY state to date! FSM to fix head yyyy conversion issue. --- docs/lexer/date-FSM.csv | 1 + docs/lexer/lexer-FSM.xlsx | Bin 26202 -> 26255 bytes docs/lexer/lexer-states.txt | 3 +- runtime/lexer-transitions.reds | 42 +++++++------- utils/generate-lexer-table.red | 99 +++++++++++++++++---------------- 5 files changed, 75 insertions(+), 70 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index 1ff08c3a6e..580edac65c 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -2,6 +2,7 @@ S_DT_START;S_DT_D;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_D;S_DT_DD;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YYY;F_DT_YEARL;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL;S_DT_YM;S_DT_YMON;F_DT_YEARL;F_DT_YEARL2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL2;S_DT_YM;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 5f331b14d1eb6525e5e4b6eb9b71cf4832cd21c1..79da87d773aace0219570be30fc73e78628c3a70 100644 GIT binary patch delta 6100 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index fa3f5214db..39c50781f9 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -327,6 +327,7 @@ S_DT_START S_DT_D S_DT_DD S_DT_YYY +S_DT_YYYY F_DT_YEARL F_DT_YEAR2 F_DT_DAYL @@ -397,7 +398,7 @@ letter: abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY sign: + | - eof: EOF -S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->F_DT_YEARL->"/"->F_DT_YEARL +S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->S_DT_YYYY->"/"->F_DT_YEARL \ \ \ \->"-"->F_DT_YEARL2 \ \ \->sep->F_DT_YEARL \ \->sep->F_DT_DAYL diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 0f29d1118d..39fe2359c7 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -83,6 +83,7 @@ Red/System [ S_DT_D S_DT_DD S_DT_YYY + S_DT_YYYY F_DT_YEARL F_DT_YEARL2 F_DT_DAYL @@ -134,28 +135,29 @@ Red/System [ T_TZ_MM ] fields-table: #{ -01040402020204030303040909090A0304040303030302020202010505050606 -0607070808010B0B0C0C010104020A09080B0B0C0C +0104040202020204030303040909090A03040403030303020202020105050506 +060607070808010B0B0C0C010104020A09080B0B0C0C } reset-table: #{ -000000001F1F1F00001F000000000000000000001F00000000001F00001F0000 -1F00001F001F00001F001F1F1F1F1F1F1F1F1F1F1F +00000000001F1F1F00001F000000000000000000001F00000000001F00001F00 +001F00001F001F00001F001F1F1F1F1F1F1F1F1F1F1F } date-transitions: #{ -012B2B2B2B2B2B2B2B2B2B2B022B06062B2B2B2B2B2B2B2B032B06062B2B2B2B -2B2B2B2B042B04042B2B2B2B2B2B2B2B070F04050F2B2B2B2B2B2B2B070F2B2B -0F0B2B2B2B2B2B2B12152B2B2B2B2B2B2B2B2B2B082B09092B2B2B2B2B2B2B2B -0A2B09092B2B2B2B2B2B2B2B102B2B2B2B2B2B2B2B2B2B2B2B2B2B2B1A2B2B2B -2B2B2B2B0C2B2B2B2B2B2B2B2B2B2B2B0D2B2B2B2B2B2B2B2B2B2B2F0E2B2B2B -1A2B2B2B2B2B2B2B2B2B2B2B1A2B2B2B2B2B2B2E2B0F09090F2B2B2B2B2B2B2B -112B1A2B1A2B2B2B2B2B2B2C2B2B1A2B1A2B2B2B2B2B2B2C132B14142B2B2B2B -2B2B2B2B2B2B14142B2B2B2B2B2B2B2B162B2B2B2B2B2B2B2B2B2B2B2B151414 -152B2B2B2B2B2B2B172B1A2B1A2B2B2B2B2B2B2D182B1A2B1A2B2B2B2B2B2B2D -192B1A2B1A2B2B2B2B2B2B2D2B2B1A2B1A2B2B2B2B2B2B2D1B2B2B2B2B2B2B2B -2B2B2B2B1C2B2B2B2B2B2B2B2B2B2B2B1E2B2B2B2B2B2B1D2B2B2B2B1E2B2B2B -2B2B2B2B2B2B2B2B1F2B2B2B2B2B2B2B2B2B2B2B212B2B2B2B2B2B202B2B2B2B -212B2B2B2B2B2B2B2B2B2B2B222B2B2B2B2B2B2B2B2B2B2B2B2B2B252B2B252B -232B2B2B242B2B2B2B2B2B2B2B2B2B2B242B2B252B2B252B2B302B30262B2B2B -2B2B2B2B2B2B2B2B272B2B2B2B2B2B282B2B2B312B2B2B2B2B2B2B282B2B2B32 -292B2B2B2B2B2B2B2B2B2B2B342B2B2B2B2B2B2B2B2B2B34 +012C2C2C2C2C2C2C2C2C2C2C022C07072C2C2C2C2C2C2C2C032C07072C2C2C2C +2C2C2C2C042C05052C2C2C2C2C2C2C2C052C05052C2C2C2C2C2C2C2C08100506 +102C2C2C2C2C2C2C08102C2C100C2C2C2C2C2C2C13162C2C2C2C2C2C2C2C2C2C +092C0A0A2C2C2C2C2C2C2C2C0B2C0A0A2C2C2C2C2C2C2C2C112C2C2C2C2C2C2C +2C2C2C2C2C2C2C2C1B2C2C2C2C2C2C2C0D2C2C2C2C2C2C2C2C2C2C2C0E2C2C2C +2C2C2C2C2C2C2C300F2C2C2C1B2C2C2C2C2C2C2C2C2C2C2C1B2C2C2C2C2C2C2F +2C100A0A102C2C2C2C2C2C2C122C1B2C1B2C2C2C2C2C2C2D2C2C1B2C1B2C2C2C +2C2C2C2D142C15152C2C2C2C2C2C2C2C2C2C15152C2C2C2C2C2C2C2C172C2C2C +2C2C2C2C2C2C2C2C2C161515162C2C2C2C2C2C2C182C1B2C1B2C2C2C2C2C2C2E +192C1B2C1B2C2C2C2C2C2C2E1A2C1B2C1B2C2C2C2C2C2C2E2C2C1B2C1B2C2C2C +2C2C2C2E1C2C2C2C2C2C2C2C2C2C2C2C1D2C2C2C2C2C2C2C2C2C2C2C1F2C2C2C +2C2C2C1E2C2C2C2C1F2C2C2C2C2C2C2C2C2C2C2C202C2C2C2C2C2C2C2C2C2C2C +222C2C2C2C2C2C212C2C2C2C222C2C2C2C2C2C2C2C2C2C2C232C2C2C2C2C2C2C +2C2C2C2C2C2C2C262C2C262C242C2C2C252C2C2C2C2C2C2C2C2C2C2C252C2C26 +2C2C262C2C312C31272C2C2C2C2C2C2C2C2C2C2C282C2C2C2C2C2C292C2C2C32 +2C2C2C2C2C2C2C292C2C2C332A2C2C2C2C2C2C2C2C2C2C2C352C2C2C2C2C2C2C +2C2C2C35 } transitions: #{ 00001313333435360432020C27272727270B32202706320132271D2632272732 3101000101010101010101010101010101010101010101010101010101010101 diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 51242f2088..93c812bb53 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -108,55 +108,56 @@ context [ S_DT_D 1 4 ;-- 1 S_DT_DD 1 4 ;-- 2 S_DT_YYY 1 2 ;-- 3 - F_DT_YEARL 0 2 ;-- 4 - F_DT_YEARL2 0 2 ;-- 5 - F_DT_DAYL 0 4 ;-- 6 - S_DT_YM 1 3 ;-- 7 - S_DT_YMM 1 3 ;-- 8 - F_DT_YMONTH 0 3 ;-- 9 - F_DT_DDD 1 4 ;-- 10 - S_DT_YV 1 9 ;-- 11 - S_DT_YW 1 9 ;-- 12 - S_DT_YWW 1 9 ;-- 13 - S_DT_WD 1 10 ;-- 14 - S_DT_YMON 1 3 ;-- 15 - F_DT_YMD 1 4 ;-- 16 - F_DT_YMDD 1 4 ;-- 17 - S_DT_DM 1 3 ;-- 18 - S_DT_DMM 1 3 ;-- 19 - F_DT_DMONTH 0 3 ;-- 20 - S_DT_DMON 1 3 ;-- 21 - F_DT_DMY 1 2 ;-- 22 - F_DT_DMYY 1 2 ;-- 23 - F_DT_DMYYY 1 2 ;-- 24 - F_DT_DMYYYY 1 2 ;-- 25 - S_TM_START 0 1 ;-- 26 - F_TM_H 1 5 ;-- 27 - F_TM_HH 1 5 ;-- 28 - S_TM_HM 0 5 ;-- 29 - F_TM_M 1 6 ;-- 30 - F_TM_MM 1 6 ;-- 31 - S_TM_HMS 0 6 ;-- 32 - F_TM_S 1 7 ;-- 33 - F_TM_SS 1 7 ;-- 34 - F_TM_N1 0 8 ;-- 35 - F_TM_N 1 8 ;-- 36 - S_TZ_START 0 1 ;-- 37 - S_TZ_H 1 11 ;-- 38 - F_TZ_HH 1 11 ;-- 39 - F_TZ_HM 0 12 ;-- 40 - S_TZ_M 1 12 ;-- 41 - --FINAL-STATES-- 0 1 ;-- 42 - T_DT_ERROR 0 1 ;-- 43 - T_DT_YMDAY 0 4 ;-- 44 - T_DT_DMYEAR 0 2 ;-- 45 - T_DT_YWWD 0 10 ;-- 46 - T_DT_WEEK 0 9 ;-- 47 - T_TM_NZ 0 8 ;-- 48 - T_TZ_H 0 11 ;-- 49 - T_TZ_HH 0 11 ;-- 50 - T_TZ_M 0 12 ;-- 51 - T_TZ_MM 0 12 ;-- 52 + S_DT_YYYY 1 2 ;-- 4 + F_DT_YEARL 0 2 ;-- 5 + F_DT_YEARL2 0 2 ;-- 6 + F_DT_DAYL 0 4 ;-- 7 + S_DT_YM 1 3 ;-- 8 + S_DT_YMM 1 3 ;-- 9 + F_DT_YMONTH 0 3 ;-- 10 + F_DT_DDD 1 4 ;-- 11 + S_DT_YV 1 9 ;-- 12 + S_DT_YW 1 9 ;-- 13 + S_DT_YWW 1 9 ;-- 14 + S_DT_WD 1 10 ;-- 15 + S_DT_YMON 1 3 ;-- 16 + F_DT_YMD 1 4 ;-- 17 + F_DT_YMDD 1 4 ;-- 18 + S_DT_DM 1 3 ;-- 19 + S_DT_DMM 1 3 ;-- 20 + F_DT_DMONTH 0 3 ;-- 21 + S_DT_DMON 1 3 ;-- 22 + F_DT_DMY 1 2 ;-- 23 + F_DT_DMYY 1 2 ;-- 24 + F_DT_DMYYY 1 2 ;-- 25 + F_DT_DMYYYY 1 2 ;-- 26 + S_TM_START 0 1 ;-- 27 + F_TM_H 1 5 ;-- 28 + F_TM_HH 1 5 ;-- 29 + S_TM_HM 0 5 ;-- 30 + F_TM_M 1 6 ;-- 31 + F_TM_MM 1 6 ;-- 32 + S_TM_HMS 0 6 ;-- 33 + F_TM_S 1 7 ;-- 34 + F_TM_SS 1 7 ;-- 35 + F_TM_N1 0 8 ;-- 36 + F_TM_N 1 8 ;-- 37 + S_TZ_START 0 1 ;-- 38 + S_TZ_H 1 11 ;-- 39 + F_TZ_HH 1 11 ;-- 40 + F_TZ_HM 0 12 ;-- 41 + S_TZ_M 1 12 ;-- 42 + --FINAL-STATES-- 0 1 ;-- 43 + T_DT_ERROR 0 1 ;-- 44 + T_DT_YMDAY 0 4 ;-- 45 + T_DT_DMYEAR 0 2 ;-- 46 + T_DT_YWWD 0 10 ;-- 47 + T_DT_WEEK 0 9 ;-- 48 + T_TM_NZ 0 8 ;-- 49 + T_TZ_H 0 11 ;-- 50 + T_TZ_HH 0 11 ;-- 51 + T_TZ_M 0 12 ;-- 52 + T_TZ_MM 0 12 ;-- 53 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 28df5b5ef7f681f698ed4f994891be04be3cd3a1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 17:20:48 +0100 Subject: [PATCH 0329/3432] FEAT: `size?` now supports an enumeration name as argument. It will return the number of elements in the enumeration. --- system/compiler.r | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/system/compiler.r b/system/compiler.r index ca4bd72c88..234394f700 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -904,6 +904,11 @@ system-dialect: make-profilable context [ ] ] + enum-name?: func [name [word!]][ + if ns-path [name: ns-prefix name] + to-logic find/skip enumerations name 3 ;-- SELECT/SKIP on hash! unreliable! + ] + enum-type?: func [name [word!] /local type][ all [ type: find/skip enumerations name 3 ;-- SELECT/SKIP on hash! unreliable! @@ -925,6 +930,13 @@ system-dialect: make-profilable context [ ] ] + count-enum: func [name [word!] /local c][ + if ns-path [name: ns-prefix name] + c: 0 + foreach [id n v] enumerations [if name = id [c: c + 1]] + c + ] + set-enumerator: func [ identifier [word!] name [word! block!] value [integer! word!] /local list v ][ @@ -2266,6 +2278,10 @@ system-dialect: make-profilable context [ pc: next pc if path? expr: pc/1 [expr: to word! form expr] + if all [word? expr enum-name? expr][ + pc: next pc + return count-enum expr + ] either all [ word? expr type: any [ From b17acc088d7f30473ff12af3de13d052329ba36b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 17:21:13 +0100 Subject: [PATCH 0330/3432] FEAT: minor code refactoring. --- system/emitter.r | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/system/emitter.r b/system/emitter.r index de3c66c370..bf971862d2 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -684,19 +684,12 @@ emitter: make-profilable context [ ] get-size: func [type [block! word!] value][ - either word? type [ - datatypes/:type - ][ - either 'array! = first head type [ - second head type - ][ - switch/default type/1 [ - c-string! [reduce ['+ 1 reduce ['length? value]]] - struct! [member-offset? type/2 none] - ][ - select datatypes type/1 - ] - ] + case [ + word? type [datatypes/:type] + 'array! = first head type [second head type] + type/1 = 'c-string! [reduce ['+ 1 reduce ['length? value]]] + type/1 = 'struct! [member-offset? type/2 none] + 'else [select datatypes type/1] ] ] From 27f0b26b57c3b3c51f7c1a1e08b5eefe98b08bee Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 17:22:46 +0100 Subject: [PATCH 0331/3432] FEAT: splits the lexical class C_SIGN into C_PLUS and C_MINUS. Date! detection needs a separate C_MINUS class. --- docs/lexer/lexer-FSM.csv | 98 ++++++++++++++++---------------- docs/lexer/lexer-FSM.xlsx | Bin 26255 -> 26004 bytes docs/lexer/lexer-states.txt | 3 +- runtime/lexer-transitions.reds | 101 +++++++++++++++++---------------- runtime/lexer.reds | 21 +++---- 5 files changed, 113 insertions(+), 110 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 35aaf0851c..2cc4865651 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,49 +1,49 @@ -;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_SIGN;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF -S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR -S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR -S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE -S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR -S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR -S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR -S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR -S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF -S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE -S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR -S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL -S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD -S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 79da87d773aace0219570be30fc73e78628c3a70..f9f12717b9d127d7f62d5d36fc0c230524d9588a 100644 GIT binary patch literal 26004 zcmeFYWmKF?+BS*@hY;Ke?(XjH?(Pqx6@?L%)4jyo^!tQ z`~6s}n`Y5ZSJhpYRXx=T(%=xNAW$ICARr(_AZ_ok$5TN;K(3%bKt6y#gJ}!f+c}xq zIq9poe=>E{rE{~jALc7h{3DZ9`pE=*&MHo)=@ z*)M!THgO!A_!!40&&O|bl*%(7VV7m4)6!4(a4+(wwb9(`{QUYBMd~&SzH}DI;c(0L z%>QaTr};=?T0itHSfmV8w9?ae9;=+!pl25SL+tx|3`)k)ECoz%q$G7RI@ItxW|@5T zeHmH7?`fmtDO}P9#e$?Ezg!*|6fe_r8qi+XD6nv-bLL0eWMvUQSA;%VVd=Afot=3DO9Ap zI5*ole6MK7(OE~b8eEe$%;Y&WU=aaF`z4IFqSG|AGZnnJ(4^_5XUeLrH0aC`x zlQ(BQTwsK;u@;2uG#3j!Ba#5<#uw)?GW%~5{!N-rr;2C5~I`UVq z-#HvUN{3BI{Ji8@4|fzeJoKl_v?#u78{^q54BC)2xijqQMN-iR4*ahyS%Z0|00Z)8 z1{?$g8w48E&4&IDqPW_Bwl=c2w|=v}f070i=zqZX{_p;2jUTuA4Vu8Vz)5e1I6Kn> zuC_?QO6^+^GR4h_9=4<#a(n)G;bwtBx@?R~~!XO3iI;28(Y4hj0r#6^TPMG|0Tf^Rp;~3kwV{J*k zE{$we!T4nWibCS9kS**(wHtmUW%XCeu{dMN3Hn!#ZIqd+5A@n+jiZqef za%_u~wpl!i^qHl)5kpJ1*kgDGI~eD>o zvMvwLt)74lcIYUNT=o9K!)lAjPVNYOBpq9bjDsUb7;MNl!=dmPI3GcR2izzGO2!ZV z7|eTNg-t=9c7KLEA@;P6bs~?Fexg-jdH@ILf`kgX3FIt=55fjshbAYPXlCqg^zN@y zbpWT}uQY!&%C}7bX4^uXw|x71lAJ6|ZB6NaKQq3O{76&Yewhum18KpP(8=DG{5#G& z=kSHItwGr%W>K&~oqxv>OSj z8q8toDJYz|*-(*>zFx2ETg1-SOMzdqg+G$)I4qayR(O2r;Uk#lu<&#Zd6ve(kAv+u z9&wXdT1%HWU7CA5)$L8AB6%-Z#g~-UcpNN6nwA)TWr#UE%tORDBHQ?-DnR|cN*@>j z=;{~Mxsq8k(jP203X#Nwo}NtEe1gKVQ_DkNZZTW?qz*tc!~Dr))6t-~Gv-)?#!Qo8 zoW5u-gYy~tu#g}ngkmPak}c`YKD7?b&BCt9U@+Dj*&6DuKTSFB2b?>No}qS8m}?!* zYpc6_et_znVXBxvboQ)I&j2-8eFj#UrD56W49etul+^20s#MeU914{QTRwSW zDf`(+iZ@h-W0^MC9>gm*^#=yUmk^$2mI#>W*%FP2GjF;FkO_ehw5Zrra+3h>FPn5< z#R7~*LF`d<0M)|nI@nXKF;|eXD$9=yT`}+BJSsDMUk~n;uMY0xw?fCi61+G){hB=Q zCZMG?-=O;%xcMV_-REX+o*{r)umMkma;)VMJKioCtMgcy|L6UBoC=jew3X+FhY_@a0+(y~l> z#N;vP5iXVxJ}Jrj@D(mLwXPV>9Msbup}5Tw63`=3K?EqffOD=4O5DU)+|4g&2tFT5 zt7HbcbnZlT69qAXmi~^IO>U zC@O{EO>oc{@y94bD@NWlQ3aklunS*t-+}g1uX-n=^sg3T1aPx_648SAl93XIqOV83 z61LuzF3Z5E3MJL7TuhAps=H{0dhmVctiq{x9#6zAj7jeW z`gMg+N9n|xwtlwy&PDJ1jwodaRXGmIvUS=Rx7MPYJcThhtNC^TOIt$_g2hUxVA~ij zm!uD}w2<3O3Oqcn4q=sMAcQ)BA{wGly1=^LB}=S8K^}M*3f)GlMToSeHP6+{PzD>$ z1FjKuXpdEN^zm6U{@7O>PAp`o8rHMS(lzD-9hPdBmjR zvNh`*HvWaf)D77um5_c4&`Rl586)&g@A%3fgh%E0MU(p@ZfJ9u1G%^Qx5J zp%Bd?CS@ZaFeiq9M6i-mziNSxcqqaqsN~j4R=0z8omEPLx;W`dlYQ7M&8dYWUUIo% zrOo#$_<|XkWD+7Wcr0dLX2Vv+#$0(^u>x`plIftx zI%SX5{+g*|O+rjqQ9vV8wNdl{k)g0Ic$$a(tpaqmU5TU?6#R+FQ`4y>R210iHtOYQ zvB~|Kwd2ps6E7R4KqWgoHUwF-SDl_#UX7y?mp09e<2F&ztDc`GRqjn0T+>~4cKWYSNuL01F|uSI7m&p)%-XNdUymcoBN29rSZo)T6#{)o^R*SI|ajo<8i()-gDq8A&0kyMtUtB}e+I}{(l3{!XdULY$)n&V7E_A4$kD$AF@av}>eC&d8 zQIjcg(D1u%$4gR1GvArMFV)%e=ZT8yN=M!av)dwOqEntX(9piS>CWVj4xNnN^jb_V z>_5NSb>X3sTmIa@-^TOx^||s_H2v0O{!+S2ny@<+et$>!@ZES}$IH$}8;@^GE4nDF z5}I6c|GBkl+p0WS^0BqUijLh-!)Bh(rA|h4nv}PvPm0dkSg)Du>Mu9Ih@HK9{Fa$7 z_B`6jxJ1;&y?Y03z~{$jjr5Y{fhGKzp= z-1vA6x0^dE8SMH zQ_tr5t@=KX9(nO+^)wy(`d?PJ?$i<+QA3SN=S}JqU!N(SHb1%HdQzhmyy`}j(5rS0 ziubN}*p-OSA3Z(uETN63orWF|?0702>FZIW&Ge2c9oMd1Kdx40HQK0R&rGmi=2x`P zB9(l3aCKTa)F?Ine((PL>fKSQH>=*jK7GA;YWu{pzTVb3?kk`533n!E+OSnSrux2L9O2qr{H(=-tKl$>{d| zXD2@V6yaJWw9@(Kn>6*g7E?|I>3S(`-7Wj(FI1m&HxA`nAIPm$w;j9`Px_~wntcFI z3K4az+V|+SI*K1OMy}vkvqx7HKWL8F$jRC;!HRX#fj3lJan3>I(u+`>~HDI~G z=a1G|Gb#$+Nd$%`(IRl^CxOr`LHt5c1yk``g3PQAzOc%Bc^<6_zK|t~OJ`j^1Q8?( z_z2MpErm>iobZuCSm7(-z5oeN)j?H77c7F-LKv+ThS(}vVN)1UxoEE+L| z07CyPR6(qO&k&ODKJF`w6Ln8zvmfOJmba=C$9<)LS}}yZF6>sa7|Tcz?i3j?U<^Qk zfPu(|9zsqamf%8`3~jGy&mmg$aELolXrw>)wGZSqgUC4QPR-`TMZ_knoe5r zL**)?&$sk{`vf*8Ps@oEVf%sFuK6FOioR?#A(iR|P|Dml_a4E};eL}w5h=AT)eu-R ze`=QFBqRiQNjIapdYE361PA)a9b5Ow1UR#XF9$Lz5ygL$;T%w6c3l>M@C zm$i4K+07hIVlpOo>!V!adJk?*iJpfn_?|@%z8FFYOo=j&Nn$4^j!v{T=g}fC!=k|X z-B;7#-cIIlv;5;}-NzCi<)PR_4*{)`cr*~v2{*<(6bTrK{FouaL}96B)X{LREAZN! zh9jQys`^VOVp+=&|*|2th~<>lF2!ild_G5mW;>Tsp#ks^7=Dp<~fk| zt=QXA5m;5XENDXYAOF2umZ+SA70ar5hLgNahK7u*JSgZH;PST{T!x0=u?NzQSrLx``GH zOO~GsY%#nNXI`G-wm{i(DGWCHY8{S?8RIdZhnZoytNnomY--D%RxFk)SA7AhprZ>o z`bUZyB0e4XQ6B$n#fdKuEO)@ixdtpT zJVuF8h3ZdDDsBUOQWLw5ms85UhxPZ)BR@K7R?UMy6{y%}fmu_|(ILJ^72NudS-xt` zQFB;Oo{+I$Y^pP51h#<#PN3wk$m05~YG(RC^sfNyW@_~0u64G@usP<*9ay4W#<_d& z$ful5D*{m>%KMM`dV^75O9Qj^t;?hymTurr))IE;c1059RuuzLnr}c2qBdfVMmXq@ zllwR9Q8g2A{SuRSoz3$>&tVrjO5eZ|6{^}SUj_~)15CU4q_;dp)xH>-5>2@FPpGv- z)y!~SPRvuB933=NWVDqYHMCFTVfZognE{L z`8HkW9rd#(CcP9SyA{2LZ3J|Dh;fRzB*@cq_WXxwuwrDT_jyJV zf9jJHWolAa`ErxxYTO>tA8$r$nY>O@`dSA7^;CtP4JSks24aUH93OhFRVMqNbTm|~ zC2;ZPp4WDfqqVu^&HcrA5Y(G+5G6PPzfdY9AsQ1-lqeu2KozV4Rg9}Nm2aU1#csd% zeV3Ns+D$CBjz)vH&tB?!m+)`eRi z##DmI3sSris0wj_P5g&&Aq@Y#Dff6sC7m05+-{D_EB395kas={YvMh6o*KmLU;5)j z@2K$3RnJxMdj0IlOEo zTzBzKws=k8zsMZcO8>VsJ~~-AxB&A6V%h@W;|r`UI2|`RdY;P4k>P0_iirSdA`pp- zP&&1RH@H-!c=-}a=z*S%^R(`{!Ifd=sFFi*Z9&`Y`5wt6|E<3GCqL>`2Hk_-buot* z1b6Vw0Lu$`u<rpNH&ruWp`h^W1u+x3#D3T0Mbpvr~JL_ild{YSga{3+_KHVn3R6V)$+mY<8oV z-z3Xt{i$J8nuvWb`FWp-3w69?$Hg-@Xu(`m+zCn{Ij{Dw=YiOUfTmjz~P=E&)4-KN9VO8YStgmKDQiv5vwY` zMV;Ahi#EO~@&F58_7)$qAN}OkJkJDwx5>qA%Ou?eTo(udcO!}avOf4@Tl@Da;rD*m z?@jHX=&o?!?xg4~_=~WcXZ&0+ys$F+$41pXaHEGMsO99CThwRIT3pl4ot;nPJ8Wr> zJjFO>h_N&?&0xXX#uye=XP!&69fH*y2P>#Bv^+6}({$~r;Bsnw|qkt_$3Y{eP{% z?{(7e3Y5i-OMx>Yhn@zUBJbLnxkA3T{GR;rs^l8f$i;=-=`xf=?eRwLy-kBk>s3+; z!Tqi=p!Z@})<~Rk`6t>;4Vd6s(Aa}u*YfWD$$JsHC07sF4Adja?wYnX&DM!LINzb% zC{2c5b4X*#a~Q_7*z_?bk&E;zB2L{#8E`S%?;eCUB?q9>l;BHP%4OV;maD6Q3rEEA zFPV4`YuH+lmm34gaKsZ3u3wm#ow183VlEmqrClIf%O-V{jrR&vr!rf&QY3Dthuuc3 z2TwcF53IR*O}w+Or1Gogy@buNGG?Q^8eRy)YI80A{w^U)HcZ@){}aqG|LaBw5Hr9V z0LUVz{!f7mo+RYKN&!1MLWJ{d&mgLL!yj*?EE@9f9}hIrgrd8R*BFlXJu_x7(7%S! z965u-4i@q$Rh{{?9O(%FL9?0w4Ft``j4k^ywVa$)SU*5h^*3k;q73;rk2DG+RR&{* zj`I3YWL#cOz*2>$dD1SHL05kiSF{CxKEBPei`GegbuBdff(4?fxB?5 zM@;Eb;u~mKwfD%M-^0kvr}kc+y!$)Qh?)QTaRUTQ6Ywa+e_2-l9(;PzpxrV9a>yy< z10uxf1x=yy#a% z87jIV%uqeQ_teD_ZcS0=4V8y!Fk({iOhio-nvt0)KN>D?PtC-MT&av@hzS#@`cmd* zXKv9(H3SpLsnmYZ7so(OP9$pUtH#ClAX0tqzMg*tuhDU)yVg6>UROk zlnD~`?>N>WAGr1gqP+-5&0#{}BabC&So&NyoOpX)yv&~O#}*ZJTZxTt#lC#I-yjNe z0DBT2?E#9EBTl%ND^G}+(BOkF>f%XpG{d>0r0pr_dTCW&|F4E8!z0QiD{j;Za5S@8!!3Z{p7f>P7$X)tT`zCCFmL6?L6Se{Ze}!pk7V@z|)U*T4 zoR~#te@_oeHKWTG(iALL1={3p3BK zohIJ|%d z-WtP_l=l)@=2V|P`iLvX^j4AlimBqw(D$vGRCRLANx9$b`+g*@Ijj0iiX+hF@p}5| z_2_ZFcXGaO`1;&!x>Km0jL~v>`zVjJ?)&(u3Bdk(eRHw7|LOL5dUgK!b~SXk!&N@{ z_2sVP_41|idFxbO-=(EHSmo~JYU5&f<7_Lrw6yS%zQx{Ep8weQsD0S?zSZ~1#WhBs z@5SZ%YRkd(cK*R1% zaQF3UXQN-a?B+Nl;nC&x?va51#ku44Mp)|U;p}?j?6&&XPH)4bK39kLI{(`9gKEVi zf8uh>qsHT1MEu1%{t3aY{Ns3NX5NY_+vK#hkL&e`6qUEv>%L$Gq3%sY|LPu6vgA&3 zp5x=m#lhC&7A!4+i!bla%l+o3+e4dMXII|^@3^SuRtff>^Up80s4m<3ZE>mmC+(+n zFB#7v=7Cw?A$j8aBU{ zwt3ziOLOfkXXY(AxclB;xq9C^(WlWQ-%O8IpFF>mqQ-XUd3j2lsx9WVyqZLupY5NC zzDRB#rX4mUZsj5R7INR7Tx`y-PG@5!ZNEg5Hyx;+?b~D?4nE)>t`2OPy*}$!;L?1? z2_IM&jsc+{|WB;>0#uTK9e&%*Xe1_6JDXmK@^Y&>dJ<@H5`t4%5 z?&tUwDX^1iFiEYA?w#eWlY-Zr)aM9xrLFFr_$q$>wN`iE>%x_c+l|{9se$E>#mOSQPY6vVe zL{?dfFpA(&(qEc?Nx~>{^YW6~qo#a|({^SakslmCFw;mtc4npl{u@h;RAd$Y5G9Ar zKv`%8%0~Ljk{?MBeP(^;EFuZ1`;%t5y%Ng6khb%Nq$CNo{VW(6Y4($*t*TPokgJCn zX|-25xk}vdya%6Y*VA5mV;tSx3T%EXhL)k^d^{r7vR+BPB@qJUf8oNnpP!UdzuFwp^A|;WPc?(u-2VZ4)bCw?2cHvg7TRF-c zKkbEB`OD9QqCrIY-l)`}0dnI^884>m!J~vCgjDk%T8+JyvDT`l?owAZWl|F7<`YYq zL%VeY*0Yq~eG*B$r;-SV^fOPWJU$_xpAg{$|`IxsAUm@?o zxBqDJGd^2hj1TM4WHY{4-i$Bh(PSe&UtWz*^U-80zFa;I0u#AEk0hGQ7DmDZ>|=_b z3>jg9q(pvM=Vdg=b7xGD#x8-so>kz*(nBO0z-kuiI#+^~`JSyva+KUTlf`T5N^+Ro zHq*&#>RNJ~{5cZUMU9sZ@rg<}Gt!IcX0V4`IdjB|>2~l3xpZckSIx~}AGvlW2@C^a zGz_!}7)nZlh!VeQfCL#~yd-q~Dpc)`dlza3)Q)T?^O8Y{Dvrv$=IED2NN=TE$!>Dl z%sQ{B8_9lh-OMYmsoTL$^8fEvBoSsn!(;?VKEw<{1Tn!Bdu8{UW@-j$pl4v|xhc|Q zUZzh%DVHz(dC(P4D%9YJ$cr_rf)>K#I}R=3fqb{37h%RBhM?;1wXnn&VpKjV2Emf6;Wq>nOX z&fa`fqt6h$$9s>wA1Rh>HT&zzRE^o#nM-{}ck+|yG#agXo$jQA=sX&)`jsx@r``!P zV)aN}Mu*-RG-mY?-Re)hQ)txcWxCZ4y>n=in;-a{B}Xea_vp?8lkWzlpMH@NdD351 zoe3oCDs5nGWcHT`WlAG0?#Q<;5L^~$U2|R^DI$>Eo^0V<$7+p|Uq^1ISa3BF1=(Q zf@Mk!Y`o)0P6Q;s7`(74HVB}6w0O@S5SH0R5;TEL5j63UD9B};8KZLIa$9E?iLten84N24*DTI@xp&n`BMx}XBkWONc9Or2Dr@hyCa z+L_SQ+e(FrEro)GH!%{3;2t~*7%UdM01}glk3LWz_=6-RvRM@*vPFep%enchjWsMh z(C&SDv2;%dRF}D%KuZL%k`*r{+k#Z64pyWCv&;nMQtSOJ!KXnB;AD^hd<@_QA)S$a zSm4Z{X4o<>FPw|_SQISp%s@v_0B8)>25g-+{;|g6mUa9(TCQ#Bo=_Aavt_7TRymmJ zA7UHHNGf4qY&J>0FVOCY&vC9Y?KEp2psUG7i$@HtA0OL8Be}pQ852UlYA*VtYkMW{Rmh7372>nd1#JVk zAe>tkfhD8xsZa+sP z8-5t$Sb{de=)MB4IQTQoc)BKSt#dzNhhKP`$^>T{%T7sh34226enY8p{OR@qPAsdz zLDv8z|Eq|CFss)T1o6MsInW>y4fnxhJHA?;j4$QEWH-J^9-U9~!DJ`CUY^Zg!*UUf zn3pNyTlL};k@tsO%URIL1bd=K z9$7LSd65q{msvr-&~U++!KSeSxjq;abdLC?fY(CzEnSl`P&3S7&n!YHH+HLh{@y7O z%JXa#zUF2b3(}jVMU)^ep%5mbicct*kE!M;$5=kMHY9y+(};oIxHGkbj0BK zfc&^pq&ifZ7zcjZYyW-T>$kFv3Y6_wflfmefXiS2^ce0}J#+blj{~{>fy8&lE9f6G zWxScd>71ohFPEwYFS!63D>?!S-#b_5>4 z$pB}N)LG`I30@0o1{dih#UD6D2}&hf5}wT?8z4necEJKe727CPIzp8a#R>KOjOXG< z)0vb<&{L!umR$Ot??Ew!=dAJIX8(Hl%pZgPcR5EQ>1eQ@O@jvS7?~g^&W!YCIv<=N zXU-h)t~nc=BB#zQ^R77`oFkt?k?)wz`9X#^$xawMh4jp2nxaw}l!x=+EI^fyVdk8! z2gt^_Q1Y^oiB8I#gzJ{P@}gIn*8+}rOMO}SQgW3XA(O>>>Oyjv952(!d+Jhhog6$9 z-ka%SaDn`HkuL{V$l)?+ylXB7m&kE4ZM;90PmHG439b7HNKs!M`bqqLR*<3|Ip8Rt z5b0F|Wc2XoqJ?xn->bQK&|F+Ob+FZk+aGkY_*sHY!xo%PZ)KA2Z}rRADiprWFFu2} z0aPcvKNcu6lo{9vDgcYY(Ez=Z#$OY(7Rn5K1Rc{d&Zjd^8cZaI${R)HqhX>P3{`KV zmaT+`soLOvA{o`y(BWmfgX8uAPxOmS8Mfkya9VtHg@5roWewzOK5=jW8D=S@3=RO1 zLD#^e^U5C!!nl0nU+UtY0{UlZ=|c4}J4CAVkA3ZTxlzTo-rDi4K~RVyjGGM#QhgC$ zHjrbi*q!ZdU20>3zx@$_;hCSsoIzcwT;ZAT@lqm|0F0N9Y@IWKlr&$kOF?BmM9zX0 zAjrG}&@u2DJaobb3|3}yC9={GJs`PaCSo~T80whKEYrs`>4pCeA9(v%Ygi z??R2sv703=s--H;MLehoj143m-{ZRiZIji+W6iW>xTkGXi$6MZ&1HLd58{$^oc-=xt0L7__cd9Wu(8rc$oZ%3ljOa29Ct+$9G1)22^Wx*7@&)OhXpDlOX^IG6b`#EaD_#)sN*Gls($%sO{yco85{T@>!Kp zVp^liWcL?)+8`d#2z>k9N5?7ZTI&W+Q?s(erGR^h$`M#i9I`f)EKJo}rIC^_BMn*9 z>ED*n+nPE6V^ggzmG9_bI;2`T^IYnI7qdw1t&HSs!k_7jcvy|y$ z6!kOKpd+aOW2umSYv?v9M-i|$YT*v7iX)|A>7D4FrXDltzIBdxas?RQ1$YZph=|sOaNR((;x*fGH?Jk20Vl2&MUutaAu(VRT333gPFnirGhX+nnCUUfuIp{$b&Nf zMUYxZF%MI82J5YS^#{rXJs@1mQoCcThL#fz8Zp%!8v*Kt>KSxh(!LaG59C&v)6}(& zN5O&HXxCdM9%YnBnfH7};}AfZE~p~3DuZH>Wl;N%=9~3_mfWdftYH3|Fo1E~8BISf zX$5o05o`bggSJ7QdWH|R=sQ&p(mO4ws4Rf$Az%ES6oZaTsU~ILtO#Qz*=I0quL>FY zg3NQB6g(698>wr2yKAm2uS%85N2@pdUP-a4{a5PzuD@Rj7&EvT;>bt9k8x+`N;<)B zXhpS9&TLs@=$QM7n$YD@$$I%v!&)c)dX~xO(Q&@~=&UFhiI@j9>y_7?cgnI!F99L24n){%61sM8HZT zhgqT2THOFG=R<5A8A%1qp!Fui_XX-{I*S@Z|c-aH3~A(OU0Vw9SpVB zO3f-pim}`*9~gjuXfL9vqHotv$>aDSw|co z<~3*ymO7pM_Q9sX3y?-Y07MML27R5s+kPuE7yxLw26LS@e!w6AY!kSt>nEYI(}bcD zZpfO3Az8|!9=7pzPnG z7ILJsC!#-=e|2Bh7zw7ed|}qu8=?NeZ7?&05vUP!xC0VNfjJ>^#^Slv*q)+P3bR=e z1g3L5d#?G0qWNFJFITMEOtgq?yz}yrF_LIN95Kp_}R$ z^oP0s$>~hRzB%J1V4(KC=FwXhq4DltM8} z*}aEL8b_DQoIIba@F;l#c(+;HGdNrV*}rhzuLdz)Q9|=TJiwA_<4^L7u&3MEMfYzerM&~ zR!HaVCZ?9($>WX7YT=r!its>r){=c&k-t$H2t4VtAF@hEiAwwFdMTf0shw|18bEh0 z?&ZAK3!r3pF`EDwj%&co)Az3>*l!(s6HxfR=0dTou|LgBzrcDZa4FQKaaap>sTo)e z+zsf`0H!izEgbqbCgHh6VC*Uqsi7MGv;DJHj=e>|g8sRCbMA(X1W%v1hx-m}#fttm zW%Gx(^ilm=N&j8M1A#fz^bL~^40ArRza6z`L_(IPz+4-!Yl=(@^&a3(nnqM;^%B$!3vc;sISyu@9AiIK6Z`UZ zV6ZIT_8}$lyQZ4d>g&ZCsUiZC!ALppEkH-R_eje%yp@DKIeUR?TKUMF$IL8r4Nm-v zT(jmiThWT+uC{aNEYQ@Ibx^K%wF9%rFw6gAowLf+Z2(JM&ew$lbazwdtFU3FTsCLy zNY*{9{|Sw%YT~Tx&I}ig*H3iuK1B-&vx@tRQ1R=PaTzJS4AE-`e8BZYd0pK|S=?_V z0fYP>3yU{P1TyTHiFd$9tYu`Zt<;@fK-FJ|BM{N z@PUl#9uQDC@j@R03Lr*16Lvdk1`MPF)Ic>$+n~%o$h@#djZJ(v5h9gkhRbcLzsO3V zv|gHGm84A2au1fX>Rnlij~=X79jR~+lXHtGXXc&v5j!0D+EqGN?31BpA2?J$)^MPi z1H?37Gp@Dc;d1M-^fCH0y6_z^Z4F0yP%gvvX)XLK*T0L`C%Crj%nDMOdDH@O&4BBl z`T7s%Ty6)(%|5L_t~7%SJY{inxX4zPaV9_q`&FNGHv|RQY#GqJj#1#%vDKXWhj3D} zP{K-Esm7_=s(!v%iS?V6^#4??REd6=UC#R4ru6!y>@DOsN|)@jL0bh({>PF>jT;k; z8J4UA=fPymjvVAwnk}s!4>ikp2d<$l(WkyE&);!YcwcVLp7%EoPik8` zE)K}uEquIy_i~>0x?lRw*N2vKJ5G>7pBwH<>04UlTl%lmnF_}rpNU>JsYlKNHN&5`x=$WAPR^=cUp6lKU(V0mZa>AG`?%i$@4QuC7JsJfxIcKi zBiAqK^W+OWnesPx6=h*Bag-rIK=#l;KoEfM0Dgte(aGJ$)bZ`iL63&EeJ%&8kG|zA z_~th-7!yJ;vG_a*;?W8MM=4(e4+9wkd|ucp|CK zDqib$kwJSnBm;2@z#|aJ6+44hhvDa7w3Gs?i-=O#t0k8a59uV3^zLLQ0^bH}BT4Sm z6WaIFvM6Dh#zcxqy@nw^L8?%ePoGA<4jbJgNuo*a;@{!xktY zf!}GwW)x4Lf%_P0N>zrSo>dX_i$)(*qs?=+R zb>P6$uuaVFNoS46;6|74jq&ST)&ApG`g)iSNAMp?t=*PIp5y6{@5|l4&UCU;Nl9R+ zsz?kf^7EB$f)7y_wt+BP(UU@uX4j3ruNZ+M`~o(h3Wh-w@>Q*Y;1*{95`N06HyHbN z=$ESh&CLKFU-ouF9!jrO1(QOH<35_wXwAz6_NPsXW8Tgw1>sI!{n9a)54s;j%w!J7 zt~aneUre?=zwfwN5hsiPbb{ss1sTt9%h=;KUUpE4^M(Txgr0zz|!)M$;L#}V)=kCZqw?VuS+22uoh^iT2iCuGBs zx&_s?_Q)$@Or!!mLn!^to2%))uwd zo|+PaD8&cf*(SZ8b;5E$sPaon%iRTiIu$gH2CEb$t&{NzO`WVkVuJ041&}~uCS4=r z$-Z>iBr|;RwB}pek7G`}r|%kI6hMZT4QfLr#v_D2Gd_RErFYfd)jW=q$j}Sf5CboXzKa$kL zm)rPw44&+Gfb#w;-*QS4YQyNUB<>x1j=J3&L?F`eabLwg>8vwGrSBUE*kPf8gb)oS#qbaI! zRIZkOY~!EY<6&z-&%_cSLz5-RhQhbvdN{3GUjcFMV()E8&zKp_;BZI3dldV{Y7B}* zBxsZWND0soS+e!7c@GCCvn&$5J;S{6nJ5lrzLQx;&ob5z#3`c~_7DbDeWoL;lQWUZ zSmB`zL{^0Gq(woIY6Xq`lMgtcL45uxR&owY+|?b+(Mh`oSJA&4voZbpfSa_d)Gei% zemQ+!tJ##QCN0}xe~QF7IEhYf4(8Bc|3oFl5p9?ynSEk9L+~qljtZ8S@r2({b&*NN zF3sfB>Sy{{S}9U3lmzNV9tz;m^E~b3@ZAUmKc`@-{2>7{(~A0^a@hGFV8cFu{rchv z@&hzZPO06$Zb*GaEv~?7)HTAX$h%zGG^KWe_8R9P41W*L5YHLnD70OAKc~{d9RA$-$Wd!Gx}0GZw!Fq+rOD;meWl$X<+!#n*JW&m$7MzWFPCIb?E{cV zB6uei!7shSUX{_N)q)kCs$kT;7wG|wC$z*2v!DyXwJs)nE$C$v^(gL^=xLT~w^+lt z#>Mxe3;b#a9eb3P+DG35sv=+w8PLy1D1eE48cWTP~W3gBf{qSF_7_fVZ2 z3hr6(GuC6PbH6Y`$~GdJijjD)uLG2zT2M3AZj^!3AG7I;9!4`pP^~D|)lt?B_m{7F z@KcC$h3AWy_m)4OahISk7(+_KqmG73D-(WZs``hC_9EI;DOC45gJ*Uz|4C_#6%2)E&n;4wM4lYAZMo>_>7y zb^!pJqVz5#Qw3*v+P=mE~IUPZq%z_B598 z>j6(CV|T%^|4JWTsoAVQ&MDV|DEmdq_NZk%^Yrm#s;rVWxAHP)_`bsVM{;6Ce&%d} zO;VwavHyeuN2(Vm5wYR}bMD3e=<1a3^qPtE-@&#_%XU6KjU zhm-hgh#ev(RRk+aY5Ke}&ZTY7(%r9X4cyfrS{@4*q(1i*ZKHC812(n3q6C4S@8v3D z+_-r^gvS_lGy)u(dlbyaw6*ZA(xEv@I8`^NO{%wP@V#z@^k|Hx{MaozVVZ6XT#M)f zinP9KZ<(ptE6~JULecj@3lWbcpC+Tav%pfvl9|_4)Gew}BvEVek47ptW9)a%VA;?0 zVXs6CQRJ@%*+$lrYFIehtw8Y&Ul=a`7^A#-H2yrS>0~9s@hNq4|JZ=-dci%4m4Zp= z1o`U?l#&%zHJx4|9vR`C%p8?l{GHJV6~{dDGAe zIV&V)Q=#~Q*_1j8p>OdFzLBOwPVWpj#NBJ1Ki=_B)^M7>(_uU9k-)iaYpgM(X`kSz zwLkPUdgX-gM)=8LM041y{_Bc9a5nM#oOl<}Q((wl;#od5wS}?aQFj8V^7r(b1pHFN zOG=v>cX~O05m!l%iougjEv?FTokS?2H=Eo%=%q0*5yEHTyQMC@nqQ(1W3a!AJA>kF zBhiCs3i*ok0*{6N4LV2X@BFiY=!6Cye|@t+AUZz*oz2Pgv$Cm^({GUe$KT9!MwWI* zD#Lcu0;s%}S&&2!nSRL90+QOnQ>q`9EtT(Q7Ziu7us0={N_dT<`tvuGHL6Y3)t=xp zJNY}EB?x8J2^R=y+`R~L9ZxwOdBvg6q3JMTKUv^TTTyIgbC0_%^xx-DYZ9!2u3h1W(bi^!GKz z8$4frGFBYu+Y$UUK70wiekyqlN+&(BdTMTSUVT1&R)#IhcvZ#w(t6kU@ecX)u;Voo zgf}I*fS4qee$w^hvNL0h&}B}IjSrF7is@&i8W?elCQS%=Ql4wgzV}!KaJa#E`D4m< zh|AOQrWOH-;qs3L+85v7T6 z5D{sHCWxUorAP;lNDoNw0#ZWXBw^1aUOy z4E6Q8&7)^E4Rf%0(sZcLypPS99ZsWq6Kv;f^Q|h&aZuU(UCn;)*O>P#Wd}27Q@~pm z4e;y2`KS21Zd7FL&`(8|tkzgwVTF3N7@o7OPjeoaO<Ml@tFzxPv zan~}G!rC&&%I5~nm?$TypkKd3yVyY?d29o=g}bEE_v>UMkH5CT|9g~6{S)Q?MEU<& zlpCwsI{TB`@f4}Q+m@f+i*hq~Bs|?EH&9PJ&%HuIdOA;aKc@Mbdd4n}S zXfV>bs5TRkD|1SShLJ})@Xq%^O?Sla6S(8{9?)kLl4h-%*abte43*4dAH^C!Jt8?lAn$(KMZ-BJ5ON# z{Jd@@aal&LdSa4yT!E!Y%Pc=R!oJO{s`q}3IM&bORXt8VYE-yn$I{ZpYXCv>n^%h2z{UG?y|#pPeI)v(C~VyZ)}_`rky;zT>O9`IZ8RZPc>Liimt(G zoE9b%SZ0gNrg3OXBcZek85gaozj8U#^7HWeJKyeid={`RV~2NF9L|Gi8oWi72Z0+6 zvH}Nt=eh+N)k25aGN)mJc}5jQm*bb;KH}ulK$u~@Kk#+r=9u4MelpYQ;&ef?(CS#u zjVg07J8Cx2fiCG71Ea%KW5=dpDO1TMCumPpH;8?$Z{+i4`ebn^{=mGH zmmA2EAd|kXH6aqHTWW_N!^T>axs?^jm0+o*#kOpFGpR8gI*34Ro$+V)qx5Du-iK!V zVofieu_Z_2X&R*gVVoxFo-!t>_)AcA&2KZV$q_L2 zps8Re0-Dl+-WT+O^7RhMX2OS%%(t5&C19n*oeL?4nLjm)_YeyaYVgl=&8$V4#cdZ>BFN`GeOiNHGHlL4XN<}Gst>(S+ z{92w*D5dv(A&z?topP30v{iZ0@$&x9f|wPvbDht494D%;nhE0_d}ii^KaPXzM2YAy z3yyi(#ir}+ZW=3wT{S^Xj;9y4p^(qAv0CtNlBwrtit9;rAoS{N2c_kR{HhXEIrCOga$;f;?y{?Ga)@N>dB3ZLW`eb~o#KV0>QMWyWVvR^Y^NJuAp! z&^2}0hI$U0tdwIrKvz`%@YKCmJp<*PW?vTapQe;;uEso&<8tnpT-f>KJ>%7FB{JWi z?mjZ>>T%DtBzq~8D8;RxFP&!Gk_C2R8_MlPUd5Y3j{~lyXI(=+}kP4rHSrqcG;lFXR^J&Xd9s zu&_t8Lyvt&5v*@r2n%Z3b223u<}mo?(3+b))K3YWJM1J7xf`9qsPYCUOu}w55rgoE z@XelA<%cEf)T0Q=DOkCY$Bs}fsO^~KOO0x7*M3&5%|*sqiS0|9tu1DZ0&ipjmfmy- z6SKzWhC*oNd?Ol!k@B}E)vFoqsbKnA^lI5FGtSU5uv101^7#5)YmM$RtyAD2pwpd2 zqE!|)l|I_I1(|9eS!&sJiqDA*`0?4uPQYK3w-vS~Xh~h_lCXgJdXC~{b8~(@i%PiT zhG#6f6auHBpn#A~CvPIGFS#O|-6X7>oxhhn$o{Mc{;`@QcXHx;;p7>Yo%q-lm7Bh~ z`oijYu8{)lqXA($VsiuXk2_ndPT-lUHfL+4?VpzE#jkjH;&Ua?DNc7Qhu4Zig2hAC zFACOnAMZD*D-&;Dn%UVhyQwXZ(Ah;1(tjYFbNkChvCEFfW2s)t^ZmwapLI)||I;y9 zTESBXjS7C34Sk{Kz)^@XeG#$ZLlrQ7F3s{n|B>J$n57AJp^bJg-Ca&It-*!Quk1fc zmKoubI~5%s?q1$?mOU5AYJ;yi+7PEVdz)3(s}iprL>uC!kP|oX9Cy@E5BizR=}6vsaW4{JLZ4sg6wje zkHRv8gJ-@il8VjRn(b{+nWUDv!lFO?L+i;6ss%^w2HPnwBveNrW42ErP-!$Nl;E%; z@v#tuD@507O{M?FbNyc1n&N{tcE%4CvWIkF=pf%?c?V$+#_MASKLyJq9PA;g zd)~F!Sk26R9Pgd9RLuT5L8*~?n;fivz2o8n$)46Ae{z+aTVVPzjI9x_HvhyiIn(m* zM{t~hZkr@a2%ctF<0bOxO}82K!2nDel+Ht_DP;VPsKdJ$&H8O5&Z98#5Nrgg--P_i zKRudJFa;_Sbx7q+hOh)2tvdBhR%7-C2Oib!Rl;9t59T-z2rwJ6iAITc{HQ3&+_lFA6p2;U6wGF! zdguMAfJ&R3AENoBc#%2WuYtSB)ekn65NnvYbGubP_l0#eOQZY?#u8|x9_}Rec?8p< z;a1aq-+7})y2B$n6c|I{-^-ePoZM>R3we%kW0y(e&zPr2#@ou>%sr@35ko<$TD;V= zC(;vZrpFA+HP?gRdR?4YNMKnG#nL^+s(i{skJMytgr0r06RmwgsaA9<(f~up#nj`k z)WOEXyZg&~{fGLEJWz7vZIWLQ@Wh_OsPc=MZ)a}&*Tb}B9aP(@%t(~U6 z7@aO{R7~KUu>!2Dd;J>t8ID9jDS}_mFf+z!yIR*jiOXCTf0G?#*C4}o%bF4w*YuY3 z?ldOGG>R`U9>cec=Zml9SbcV6vP1cqB;?^{!4Mj)WJ8~ucrt9O>n!~ncvpwm6Jj(% zbaa$_*Z9Xde1KAnT

_5YtC`{(i(e*|zz_h-P*M&o}9zb|p*>)Q{u<3Qoh-pfA< zzh`*Jzv+K)Vg_=64!rv$MY2l-ne(F`FHj70hTRtv==a1xpI9IO=*qVb$RQUL|NZTI zwi`cs^Z_YA?~Z*+2N#g?OD7K?5NL(55A5RpFTj0c3?LBb6tNFnC#Ri%-p?PlaL+nn z&uIe)1o|%Q1GkO?fqTbq4+W$EXQb~_giijFve!TWDZmjZ`xIZ*J<9%g6rdDXKHisZ zY5pMv7L)%%0923m2`U%%2>+>;1Ox$7p!=X<-8~Q>%?~UC?4|wxKD15$??CsmtUxF* zjkUj}`38Rnx|h@fLVxa7?;|NF?wC?g06W=0_0PSTAJsDEKdArg+W_UjOVU1|)M9Us be!4(i(xo9cao@)quuz21P*AK}et-8b!A`}A_x_(- ztx;4#&Dj}!eA4?IbD$^#296GZ1V94-0AfI%j`e0L2mo*m2>_r0ph0y+?Co4k?OgO# zJsnJ)^%y*CZHS7%L8%G=puo@nzsLXL3{0f1TY)kohn>UuhLg7r#%fcQe)dvYA6K8@ z7yKGy=fDY*d2xN48w(|U5kS?%*%F5zCOKxM#sinB2^RI??zN6p+q*ZUnBJ_2=#o*{=!0M>lj}RWX<6M0^b7M0>H5pe ztRNfCYy}qgv|i<4D}>q8Yr~>_a&mjxcbi-|c(h5&lkK>vFnhk1PGUBy3^lJ1mY+ul zb_?|Q>os}A2n8+a02MSUgz#wn$Prx3=$AySf|2P$ty-n{II)I?y!;Nw63}pYZ4|U| z=TObN_;CQMYscQD70TuJ*a)M75RZx&_I0|cPDfvCetf0lqjx&m9L6n4WpQg|ro4A# z9=o^NSdq-tNAI4Ic*?)`cqSzr2*)+?`JkUf_dkYS zlO(6m&jcTKF8Lfja<{mVfGjNIE+pAOtm+pa^%bc(wwMfWqlXe7Srs=JOv1m*?|E!} zgE#hgg!p!wttJ{3{XJ=mdu>?yqoXSn4TV#hxMR)t0Tj2zo5kBq329F%x2|}a>dzI0 zGNW6h;`0}x4an0B8n`fMrTAf(e3^mTLvmW1M)!3fi^3|WwP7DyISY=Hr?dT+)5?wz z1R}U)f6QfKj5r&auh#jD*bv`5;Hs%ua9e&f%5&l&@zgi5>Ae!o?m>I;p_k7YQ6^zS zy=R%07$z^c@z-u*yBN>)9N>iMuO9h18Wc@fu?aM`zmtRqt|o68NRV=%a(0%ip-o8EX?H0>{Dye|K%+T1P8Nq*`AzpUGiyoM=DW?~H zzSE;DfoPY4FItN8J>79W=Uc|fu^R`i&79MXLVuEYCoZd)>DVBBQD0r@9Fxc)YEqIA zRC=Fh>BIB8uHLVVX}=y{EN=MYTct;Qm{|6o>Ml^L<QoweNXsw-b>L$nI;6|}?y>|sCqCeoD!stLWz=t3mzj!g2J0S{z7R(15YEU+wVGtG z*o5EgdBo`0bNKX1I?l5+2)H@Zxj}s-2Bn*~z)hXkP`^G@C z`%Ko2fMRNX9b;34|PK zow{yid?y4V{O=stgn6L?1+rrSXd}1)Xb>O={_u+bWWqmv0|Z$80YCe{`_Y*^Z3WcL zq4VIb;8|bCBs}O!>?A^78>K zNUL161afNVrqXKdb*g)=E`Hu%qNSF(+{Ow6!5|Sw|5pEgdFN-*vKz9ZC~}Cf)$@{) zIfHs?$9J|l3k=s;#yGe~uAWN>W4v;$EYFJpMrG7-sX-1k97OWL@l$Ws9qo29K8}0l z@oDv%BlcKRCdk}T$1_B<8QNsSqZE+?MD_i~&)G1#fctLFaAI_H0hw^%cR<8eodwcy!EJSw|TWkWE^JP>=;)PtJ$W&He4%7?IY?*RRI1 zTMx{$%b!jU!prMh4;n46*PpH$(_c2`4?51*%O_7C1hUhw{CywK-yZLm-R_3RTPMx@ z%}98=zUKL_pXUqc>UMthU+3NI>Rjcw&zs2iSv`Aqe!DN=uFv=(&po?iI=tul{-x;g z_H=P@XQO}K6Z3n2+`x+8!=*zHOzWM%J5Gfsx)Hmp7d!jMx69M-59IN;9tvOhHcwyg zFP_(5ZZB3t?q9w?^}pte%v?1NKOtQ#m!F=U-JS1$eyh{n+{l0FVtuR5daK`?#P{o2 znA_=pv3vUT^2y(rMBl`hf$(*5aB^_tWmW|Jmc-$NRO%{`Bp|>{Uz3-}C7t{dxNJ{CR$O8fhQCT*9?w-KUKY ziH0!fc5m`wuslAT*5dW!!^z&^*7O|Q<=yFR{56u%{EQCT&cm6d^R2?AjeK?6=jrL& z^@Gj*@$QC)*9}p&a1Zw$|9fXvmLIpzcc*?mzOrx64x{Ij_P(pOZ(W`|O>Ga|%uCl4 zv04LK$aqb9T`c}D{-5~E-wb(tE*gi2-}3JGc}hks+;2Uv_RfayUQC`eysv)V=&bFH zb1u4@{g{hB??3SWGCAJWc0Ae8)#j59*}dh*sWee<9*<=Cm{omycHS@W=5^osX7+k| znyp>?*rG1g-}&QBig7Rds&R{x@o6M(^d%n4c?Isoc7ZMrr$B_)`O&5`yV!wgq!hvE z)iSu#-&xPw+w+{b63@WIta(=j{f|@MPb_M8qg=5M^-QXAs}@RwEwit;{Rg z6~9G)6shO-*gr9Mp`RRW^YonG_p9w259?rG&IXqAMW(XOLxOlC)<`N&{!454 zlfd!%4-$7>`g2)^ujR}^Y$K-+PyLqi{>6DOL(P$n-mgY0`T17Mgp99jSjSy2?-8Ip z^~nl@zoJVu$}((WO6?M*l2~#}HcPG{D$^!?maQ8=amAN#(TbUKO>h^Rb55uxIeOnt zi;K$@VPSDdR8*K49Kp)xhRn>6%+iKw&f_SGVxmoPJ}}7SjO@rfK_IFN4+n*U)juaR z0Hetr!3AOsg+fX6anwD>`g{Nf8vo&5J}0O*G2wgw02LS0iAsvkrF!~tbs$^Hu)uw%(9>B^x~3}1`YZsK!8PS2K2cvE8AkKvQ$>V` z%`w@hT)yMc)X#C+h$MBzEx{4vRBp(QX7BgTqQH*LzC2$)aocH-FnjG0Et5z+nUchr zD`K+GrWVSJ^WdDA6eX9)4shojgK;{?bVsl(cYJb4*j7j{-Aqm0!HJ|Ba}KccFy>fJAHo#r6!vgKyEeAGy!L+3<02-!}v zQu!M9-h;kc$IPchiGoD30?P83Y)(ps(l&R1=jgDcIyq1Nkq76{q#`*{euyXYkZg8T zm6A1g!u8Y4s4^vOZjCD{c<(}><8JZ9F~GzGpv(f`##t$0TauEX)XTkgnOhzeq!h`GabZ~+6{U=n zFXPEPGO0@rl~3c*Ix?wECIXZp%7S4hB!Wne0(MOdlIQfdKk+AP={}-Ir+-$BMy0g- zae~9m;3&+dic(cn86}B9uhyi7Qe9LWRY#yYJy25)c~osw5LHMcUWHw4R1_tOp`tdS z%B(Rcj3J{|quQV@hI}Zh&>=Y8(VOV8yuC9fsL&-i-PKEx-xFmTE=OUtuQd*%Mz?tR zK^5POkF}enEJ_hWPEEARqOzzqN)v-X%|&fiMNA(9ObuR*S$R+s15J&rDx=D%EUJwL zvr4nds5GjXCPWp8F5B{`q&8WTk|5W`b&i(MS&X0hta^tzVA&zvVK%6ba9Qpqu!Q-U z7!j1{O{&pB6tHr@xIq+H4M$`X5%mR?e+fAralUZ3Xoyo`RB>lg0*UjdEEdtxU|g*D zRf=mJ_5U*}R2PO^e9?iy%tG-B-L-lXT~tqzr$m|JEREUL01WwQ?;a_Lr`w6TCt`77 z@{ADh1kZ(1iYAHn6WYB^fsuhnfO&{AC|SY`5GD}=@!pug%!K5u06`T4v)+k7EkGl< z8N>uGcB2KS-08Zred&nGV)UiSO%bnN7nOnrBgv6f+F4Ms3Tlfc^t|iLvl+WytBw~3 zO|{AfjXm)MsHbFw1dv~!2K2!jr|xC(2L4;X!*Vtd!?NCqfK0GPfEmmLYz8}18Tj#X zzsK@{NR;BqioC~TA#LNiGP z7(&)TvcBM>mat?>RN<3n45)CXjsbHks-rbxZwQTq7}X__F4C#8Z52tEvo`I3BLlu8k$DRC;V?snmEJJ#M4f z#WwDZSW3M#(-(j4sL%832&nKlA8bs7WGZAImP-{Np{s{ar*IlX$=7PFx!A&gA15;r zVT@e9a~SWzumEA`700xFAWaza4Uj>6I0Zd`1I7wM0b&L_0gu0op8;WE4YOTS!<|Pv zGNA=#T$P`PS@sN)LRrNKGdX}HYK6Kxq1N^iL{`1Jc3vwyh?~J6$X^J#b~83?OoICP zgJVs9n!Z6%l4AVaf|N<*TYp~->+55AHg?k@NSU=9F`DS)Ss<6M0c0gm!zPMjt^1HGlSkiVhka^HD1X*}ls0;=sK7+?z z_y8PGR!}qe3GfW?jQ)A%(wgVf(Dw4_fQ_GII{ffA8jdDPx0*l!`sopG|{26sPDpjgoKT z|0c0$DyIu<%!BfrK&s0>6F8eURLW&iqhSE@3ljc$gv!b2syE{VTz zVpVK0G@g6UeN7ENdMnftfCf4bP61kGDrcBR#Z?I-?Gr<|8_15%q z>wy_}FLRBno*S?72q6SX)@7Y@K>Cg~F0Nnj>b;oG2*?kzc&xp~S6RP>`wS!&@32r| z?y?8K)KbGs9?5(if0Eq2eSvOT{1aT_nCX0TJNQFHmMf8wZY3B<`H^utVlrG5YA*D) zBWdHf>Zl`F!9=*A95L&-iUee=C$^(CdRp8e9vj{8z10}NVek)qk2WyAjRf(kbYV~` zsJ%IVnA6Rx*_8Bbp;4PzqH)KeQ5RA%mj6sySEfs6msYGZJ?nUNNel(#aVQOyav99u zvaozVl71V&jIX`ZaVB2JRmzf~C)n-G17b`5ZKa%O3Vt9nmq82OO9jHR@oZq@?;m7K^O+rSN6CXCcX3dTPxhI*_ht zYh14^8G{#@(AVVU^G-OJUm&_n8R%CO;Z8}{? zX;Y>Sb>E#%P}|x-X49EO?8_&?6EbC>U~8nZR3HU-en%4YZ1>7mxop;iR9L@Pa*|VL-^y9Np>|M{Xq9cdL8bw0? z$*w65dh(lBT-?~VSY1XiVAMkRsFti=(Sq7PjTUN$6<`Lvh8xIbY(UXV)(aeG;7%5B zUXjg#!Yr5r^g;MEP8HQ%+Fq%$ED16q;FJ!ZOqxt(Lk$97*LK$+UAm}^8F*riDCI|) z{%q1CQX6JSi24d^lUN`B%b#GuNbGX5{~p*3FoB$b!t}4O!1S7dOrU09Fj*VO;!LnC z>QEhnC#tg7gF;R2jUJz(jjF3a3OP%6V~&5b%oeSRlOw@s!()&bZWMax)&&N7HvQPS zt$RxeYTF!O35EtX4^jpvil_)EO6#t+I$*PrE@Gd=xpK1oelKk%|%^gmRdU0{)!IzUAy&+2; z<3vm-7S(^ENbSWGWFSsZi#X8~c1}G^#4n)!byzt>05F0DsS-#b&$`EPqR15UYJUz% z66yzSy5MqKl1grlMAbbC)acGepqNJN%5B)@-zKUdKdt7?J**cMe*E%Ujb-L zk*_07tOe)T6@PJVes9I6PnKS%OK(M4H+8(+*@YJ`WeXcY)*`kC-i+Wf^RGJC3*XCy zB$SiL-mQxLyHNNy-G8|?=!;e`R~bAHYH^cYf+*0d52}55$0JEtgp@p*w{I8l2C^67k;v0EhV10l(g{!3*DIwbuNgf7bNn>ZsD@a>Tki*;H@ z+=+msGXN63x9Q(3m^K~2o#KxGQvHy{D75!KtFVkV_R!M4?cf54h{iuEZ57Dz4oQ5| zUrt&EA0$bp1(sC1-zaoRgCana);I5#xPV`eS~<2ikBKo>!1UjvAwB<&20a0t!OVna zfNJp9;u=29-DX6TopTTXq`2t}ic}3HN2AaT{x6a@N{-pgME@3(f2Pwmu?IeFi;`$s z8G4&7FfzdMPj>xBeFwq{X$C3_I)R>n!{lu6o7NzWkV7d#e0{Pw;1xp1qiVkdgiJ>c zhpa>Lx#E{4h$%b&Ao=H5o~_F#oNb3*OTsV^Na(OAzoUrAr@Q z(=kmT&rX3n`yi%FOP|lsBP*B}7>2M*n@Y?iXFy``KQ%#sWB@CK8RP`8NM`z{=O`)& zt3ZN~R9e|Z36Uk$0B7Y_iL+Oh(G#_M2?QS$1LnlSfZunoI3I1 z>yUdFut4P*YNJS-jQ>}eGh_}K=Zm%WeKFiS|I+r)`Om zBpV)LAK*POpgJ)820#9=AL*7DC@}t77O(@`=>#J2vD59k{FwoD=BVH-iYzZMo25ek z9mwcn0GV}yIS~DQe(2=-(WXp#E0gYtx@IT6a2=8+JPXdd^uZhn!yz2T!{lLpwwgJA3wpM{E*v+t|o^6qFyt>tXH~I)z>0PAv)zIhvo$w9@vFBO1L0tdx zgrJLGRmDyt;6*E_1z1)H>6F1AM;eY9gmo^K{7QJ$SM*?hV8X`_iGG)|CyEX5c`ebq zbIs8u*Q*AeH@C4qta|SbJy>&nup-%q!AL0IfS~$YY0*PHHI?22e{2RmHTb)F=DPje zlNi8b6-@u0>_%V@gyZsqB+>q&CRq{zm6|M3@>5o}(G0MvO=UT(75P=wG9<}#MDKon zkrwl74N~it=Kv0tyDk{x0kncb2*sinLiWADYw@u!IX_9Xo_Gz`aX<^O8O4Y4r)RkB zb`IF>h{~0e{T>b;3yq7$Moa}#%m!h$Zy|eznwyMBFKGN5=6bmdT@4x6YqId8)>1iz zyX)~+O=@Ogd$yFRbK}aFo%HH}2WgC?Hle)s`s*r9bcJ;lr=t}Wv6C>`0ka=~e%JNkJ=+rZ|776ttMYXJRYv@?wfgoM*dYt*0I^{@dC|(-iB$>IQXiK?4>hTW zVvzt`VArbFm%k~dF=dIJ>TkM3suiYExt?>{3zUyCoH-F5%u~gogc5EEH zIVKLuaXb-Dn@_t>XX{=5JfA#mJ6d-Xa&djL78*p*|?<=3qu{o~afGb)6xgc3pP-gmnndb)8EgN7>nHb@HYJN~bv&zG*eJWCJXiMLY2x9y&*x#Ijg-cI!G zw#JU1F50M$6P3B}&xfX6Uz}Jo@j0gl`2{|tFb)d&?lsihde-vSYCre(v^BemH!c2VuZdtqk3NHy$rWbo@PPM+L;w|m}_xjKk`+?uy%=+X6hoD3Iu!`s^8 zw@JObR*J3KzOZ}la3?*uy4ZcaH97USjc(luzmsr%J&iZgusIgSxELb!-SeRxKgUHs zR!Nt>^Z;!#>8@-Qh*E1<--vxFZNGnYrYYJ~gP=Ia;P2j2hf`Qy+p3xsxya}_JMKxh zcWm(Ws#9Bi7<4H_RP)~3|GwPLWw)?bY^6VerR|||mJ;Rle$D=dt3WpG%|^S!w<3Sh zI~{BD=4Ro^tJI_$W0>cw)#`=Cl~>L9OAmr+6K-molG4`2QdRHPk4ihcwSrCNEk9po zJ%+SL!ABh?OT+`;R>o;5qc-sG!{>%_o{WlOex5;^(rrUNEzY`i zl&Q7SF6VfAj(H8+6W!cSOlY3h#2`0}W4vEr2Zew}Cs7O$WCn!+mqw-%D}WCy0V63> ze0krCo~2%Pc2gMDwrbPg6t-14)~48Ah$?c!4BIyC0K)AziSC ziJpnsumuZ%Ni;$M9fT%BrV=VZ4`cyPLX6N9o?aA~qJJ_+%W~5$3OuCh^Kvo`d87w{ zh5(?E43dCHp-2)b1_@GwnnIHiAUA{@rvL*qeF~xZX?Qu(zHU!s1;b&hua&_)ueI)S zPh@C_X_JQw+DzhX(1jWMr(>Bz5a)j~3(tQ=?gV>=Jmw4uJ;MHiesWp@2ox^RHnC>+ zrpF*11P3LDP9aeY6PyDt3Y7@aQ9uMGFUA)nYzq0$PN9emn^)yH9n|+>MPLwklNz^}u`r1I zVMHwb^xIcaV?R>>MHL2Y7DF=PyplzgwL}X zg0Y$=Q(jxktXk|#iqSu*76kM9NhBx!%Q0&_hbL`Vl_Ft#MLe%_cR0t$ulECr3&hV4 zQnY&x&`FOF3F;QM>IWQPd&P=EAWATzrO2s5DK1J2#5_WHOko+lu{NKjaR$T=xw1>Mf$M<1Sk81l0&hu|MV7@;ypE zu8C#=PcuZ-GfuQU)mr7VmM!hx&v0_u+(rQB$EBTV>q0LS(LrSLe~pPDDvk&kqEbre z2tGt0$+Gel2U@fiL2Po#QF6ZK169cJU+3pI!O-(~A+7vUW{ng5=%cAQA9Isi6a5Nd zn}{m3(qGT6ZK9dS)4W&d{Hj`3iXR+dia?dFjYmCu%wl=D80nWj(;jKrvdmf`=%ZVTE)rBK*jg$f#L)iU8hX!tYDHG&uva`(IDR3~_%nIu(7+K`IB zvUtCu5jYl@gLvn3pTSRshpyAbx9U|}B*++o|2@MQJgkN^ZIct8Yj#vTQ9t*_Yg773 zMsSw^bN^s($c^Yn6Xw8@e^3lKg_g$?X=MzaSyoixA~7lb#LyT`lgEqymF&?f<}F;V zqv@aVqBKqVb{5pf3{l8j5Qu7#i%24(h@}NpL6xXQO_9m<(3?j-a=DsCt9YJ2g%uS; z>+fz#bJKy+D}*))M??|Pgi#stq0srr6IK4^6GIfwFSs^BR`EJ;0{@1Q_IX#GkINDu zqM^tbe^n{5Fw-j5^~(kFH)d#&*(X`^VJxyP-Bt(!%s^o^N!q__RJ59Ti>7Oz@m<<+ z{3MYTf>K~%1+~^1p0F|yqmn`(Qsf+!6@OEzzRUoKQi>6@FrQ>XyB*xEf*~=@ zU(Rt9d-`4=+TZo8V2F3J<$6;7gz-Uz`0Ciwn=8(3aK|#yHW*m+kl{d|F!>_=tV!7QP{pMu6qNc^_{Bhpi=QCbUikjZu zy0+Tq+3b6b?Y?=u#`CChpR4g_#PF--vU0uaEr0jHmp9;@jDPP6uB8i~8G-jgHp2Xm zT>ANi=2%WzEXK;rPL#K@44`L*lm>EH-fk)uN80 zbRkXQVkBC<8f0rf~d*)p8_uhDr<;^67LY8(l#X zWDOl|Myr$V%2HDJce8k~-LoFt>%E znh!QtnYny`^*UDaQ^Js(ZSYCfcYF9Q#kK`@X?*5Zf{8O1U+J=`AW2YN`22PzCiN#g zl|z$LSvr;p27l)52x@ce>R9!ET6J3#tIOJC6FD9Q0}romX1fV@EVVY=$VYjgxoT`>fSpdBHKDGO?0q*P-#4z zyO*2%B;!24P}9z4SnJpuwT1+J)l9gN>6ZB!a~RsDBkQ1I^{!^F_hLHB6KS$2+-$WJ zr=|07E~cX^pyu>E6tlI<;)bu9?cEPg4YRK;sKxOXvl30b(YRd@^zUCmtac%5HedZL z9M|K`^Q&EzEwkEY=O(-@F!i$3-!XVQsQWLobq0XWZo$zneK?%6$JA*CQ4OsazLeUPjs87`H6g(g#;>%ZcyqusJ3JzQCq2_ zscjrWYIU|&G7bV3T`u|q?Ddk!EQcWIb@g{N|fqxvwp`pz`;oa2y3GK5SH+uiD;kUD+OL zgJi_ehbnDRCqgxfD#z1BN^nr6F5qcpb>_qVZYPJ@GZiW3%IY@thtwyn-*#*+Dsa*RF@ z-)Kwm`GthoVv1!LXAdf~FsxztcZ(1J2qv1d=#_@zk6a;CcH1SiREUaUDh%I+EE^UW z==h_MY4!*<7(vA@x14yLXHNqCI?X$2arS&mLL>Z_gVN0x$QKgwPM{vu}$B(|(>8 zKNhhF-ySDbkbLyM*`aI}!X#RR=M?zn1=tNS)$Nwh?iU{pWbmMKL2kZVqQ`jOn@eoQ zuN(Y%$eXC3={}$pDm<QnGc4vA{M<;-XKZxGCv3u} zCA;kfM_cOzA-T|m+!kL}int7K_;OeYGIH1>_vZ*?q*W1Vf)2ZRMTgNRSiX{qz{+JZ zf;CrAOW`Idw4dWMltiD`8YXYS7QRiC-#~J^B_<$ec!r!K?`K?ayrasw*K~9E5(T;S zh2|Enm}L!#{UGoJCyttZr@?>E;m#_$6-?;BGrxgE<@nXtkNC3!sYHoXz#%8t_lrH- zFB?AipZF=dX&M<&%RknMAl!*b7$b8Rc8NjvQ+}3!ZucK16$&}F(XpnB|{Wn)i7eo82v^hP@cNl^1 z(Y^R1uv~jm2R`loQWZSVV z94OG5jX6w1)r`>sM*^m28xGE_W3cO z>Yiu_2R?kv%mZgM$CXTJh!!cSIydjjNf_ab9kAcv!NP<$6dRoMyV1STb{KMadrv)wXLQC`L4T&4h!{>r&u& z=pCOEOptKxL8pE+^tWTlcF6T;+(#N`nfO|}QI76*EJ#tZ*2~gTX!v1|xL27~p5u~H zy{{&{G@u+;Pd2I)13Iin4)$a5iT2!ivLZ&Vo`=!?5oAKTGQXlI{y-Pnf+<)-eBTR? zs!;yBR3<4-456*w!i1I<&ppfo-lHf9W=QjVaa za>MrqvV881b;sxj z-DzV=L1;8_vT3Q8NylmCF&Gp*`Bx%)7w?scW98Yo##6&Mpj|*2Wb^`s5n`#kjam45bn*{se zQg<`pL-YZ+)J44mDeWi4HA~RR`uW}aw9~WGF4X#kT`f=nWU+j1oP(UvImw4GDI&Db z3mpW$#?S9%7Tzat%v0=Kh6DF9OXAOG#i+=)F_Aey)y<=Z!Rk(D5KChQRakPv@{(Nb1Ay6@Dipd^(fYV`5UI>CIy|G z%*kkiz`*k6J3w`iGwkQ#mMkl*j4-k)qcu)H@E${K2s?D17Odk~-FJb@#P`quVM^$J zrpvIngCmkBRPZ&7-m9Q!_^F#)HbvRxqS1_P-5_%at-6JtUF$t_2J#%=WJmFtBvw&1 z0(%X7Z5UsWCO`wVhC@gz)QE9fQ>-uAX*;O7i3+}+){ZB4j`@OHfcyZ+rf0CTy!aI+ z2p=O=WO>$sGr(oS0>U@gC%ggE~ zXVnP$rOOqUxq-$NVSt}ZRU1}dwaYHmxYUazi^bC^bXtMdvnKGl%6x3k$A|Gp>9yV1TJZsG(%^3f2?Uko)D^VOkNVD%v-4UMF~DGLdYG8Tc9&7lO1^EaK%-{AZO99VU#$-igxs>>dx-o%BJt-Tyx+9p z$)`*_U2A;vUJkSW%(l>)<8aNrSyAH9OqDgs@$H;P%jOo6-DiUf^aua#2*Qu)ZeygR z!c+K8Kxi-%_G9pX`&Z9za`rC+=Z1Iso^2L7aVq*MG(TS@lR#CzXxC|nJt`Bygelm3 zvC90|PP;p*@Lwh9nSOc>8Yn^YC;$NZKP1S)(8<(9#l^|e&iuC$`Dpgpt#cuFF@AhA zIP7-a9>m=E;wGfhL@%16n)pGY4OzU%7Jk49ms;%UjzC!|(CwY~1h1nR*VR5k?n8Ke zdH87hZKXh7hnUmDK1pWN#_7Y^imx`=`;ONWJ(i+{)KS!( zMZKNXZMZ&7IqfkZ{M<)DCdD#?o6u3x_}V!JtHk-0;pj^86+6jPh;v0M!Q5;Dkxcu? zwR9j+Wl|<4cf5Q6D@Gx7QwOXXDF$XpOJ>}{0x7Q(`6t}FUeagpQZYz|f^lK?6@>r* z{TG;au5c$)c$$2S08x{HPFBX4oC^S>IpEUk(7rdpM#bTzyGF%sW3fhj;TscVor&%X zh?E13-rm_x-ELQ!U2639@$$F1J*_@mdc7=LmLY>9J5@a=tm@7b4W@Y%p-A;2b%<^P zTt%FYRJyAq4DEL7ywY~@Qc)72W|oz>Hj0fhbvAt)KuNVKy&4D&wM;F9!W>oZY$_K~ zKztLpIG5l6POrofnJdV>;$D_{!d}~&!(bv};u??IGC6GoIVMS2jN262Nd#pAIjO%9 z<>w9XqW6`73{NP%RmjLZ{bu=R!`3Fn9kkG)kZ{xDRpIJcuFcy0mKdJR7%`Wss-G8X zM6$)++!A={oW1yP0*BKIG}aD^<9Rw_WE$Hq*}Lys^Lqd4A$f9&-( zsjkZe#~~!B-%kMXnuaK9Q|oV?iV&p61`G6rzZ(w5%?n7mA>S&jM_!o&35u8d%3$vr z5KqyBh4=%`XPlo+rKNJ<6YgQGAps+K*WELi#P7Aa$TVi2 z5Sqj}Aw8ikrFgz!puZaY^t>$drsd#7z*}v0-=gXx)B%wa3(i|}34u|OY?__m7boia zM#2;pLH=2jQ`c{f;&-Jjodw=3$lXb?Elx=9O>$@W_H}84MR;~&t4yy* z`cp(RuTrL=q8{MlNKQz|&+sN=#vb(YXATgtMuQqr3)D7wk8&92)RJVw^`|0=3$ww( z#*AVIXbx@`hJ5fEI2gL#MHgp(427CJ>*I>|mZ@nL+87$cPDPDaX-OTk2oF~E7~u|s zlW~ww$3C9$lu>}7=BHB(3ETGbHXVUcytpCx-0ri@iu#%jE&8}~5L8ilrla&7N!O1UPHSU? zGcnVYIlC_$Lu;sXP28MzVEHBwA8ic}(4StI+xFgN%Qk>M%hF?hvorWBsxm%6_;XF(dVJ+9>SXroN!;6|_|S|3*anAwy% zH7t`o#9V!!j44*(j0&09Ae(sxfIpzJZ;=P@rxfET{}C|0pNnm|(~Y&vF)?hOWqoVw ztMEf0yz(BFYYKPV>jHx3W!%8Ew)RHJ0s5`L(vRF{Zwz)#6Z?tDbToy&oUYWA-G<={ zMfTk`cfw(vjYb*UfwnP81xBlOoqJQtK4~g%K`oe@Rb_ez< z;^CdV6bdh*!b$R3?EuW^aSd`kJ>d@h#k&#Tw0CdMVS0}v`-!&_&kQkjFqH}X`>Rrs zo=l?;(Red8RaUl_`cO@b^3CUTyS^I1JbcPpuRr2^33=^`d!{5Wr$eN;6Abu^B)Lb# zPA>zDgihRV^Q?Ul!OLtX#;xl(w9VX(+l9p^?*eEzh>a~?KQtMP?Iz*4aSTd zejWt8AYy0c4uN9Xl1_46bpvAL=EmuA6;7u9bSsZy)2iBeot8=Xuy33(csVX-BtgCY z4P)UGsL*D})T2<}`u@WiiYUXHyBBO8`VZ>+%U9>K!uid#XIaM`LQ;|9@LGpnm&d{Cw~m*2UQDS0Di5Fm@52R;X{c#~0v zDhKW93KK1Jya3cbjFa3-TeOxwJRNIh3&-~xZ!(=8dFL%)Va7$${cr_?9WCcq{`k|c zJJ3XaL6cml7Xj4qE|xoTIw&*uvdigcwzC;<_qigXp}(j%c40Z~ADFNzdtp^0?qN=HFJKzfl7YN$Ec z?7c7B9QV2Be!Oe#=ng6`=#w{uu!lV_ITy{qtElxx--kM}Sv=^If zulJqsyfm_j#Vz_)*Zg&32s*}0U3o~HwA!TN5ENLtW2RE$dpdJXXw}>iJ~!8QLf+JS znm6Ps*bvQl8^OA2?sjkY7_fSCzCDblGtA2zeu|LA_5lL4Ow>fpbKpwVYnE&wi^??P z$C^>Kz4Lk2RL=%nD+w|{UaOT+>_AQ0U`ZG(yxe(W0N~mP0rg5QYUjFW zld^zuQzw9%xdY`s=^0jSpVzfa^e;u$EjvmiGN@Tzi&kolgfHfc;4=FhU6xbQ%l}j$ zN{~B?ooE{OkSKRB-frEl(4w+@lu0}Sdi9Z|8jS!fV2UHcZr`&RM*E0=uNR|*c;Fo zXgEA|btbZWsBLp-Ybc~zn7%hsU!)-ZmTkdvNTGtN!93He;qhz3^!n|hnOaKUnaB&R zb`4LDWi(J74b$8@fC}(iXd5*BGngULd!H~YTR`wja~ zn)cyEAZZu~KV&`@Oi38OxXkua=ejCQ#T)Lm1O#*TE08kpn;|Qh8syWYa6L-nkS7k+ z|FMxiB^&NY=;-0x6r>G;xK0b`D1RmYnrM4xS4;%9cqF%n9b)b*`0|r?l|_lEz06HJ zJ7_H;PO;Rp&ot@t3QqmbGS{1?Oy8zM|Dnr!xH$Fn-IbL}wxhm=x14Cv! zY`Uzu<#*DNWWqavUK2+F1}dU3LeaGul|H*>G1Z* zn!cXX$TnUft!Bxs>`-`UPG>%7ph8w2ujxl!gEm#5nuL}}1^Zww_hQw68SND!YnAM^ z8ei|y=}4ud>_PHe&R!`T+mQ3${=%9FRJO9S8+ZeCG!22l+V8}9bD}Xk5l5mBeAI6jh z9H?QDx-Yf&oI#fIvoc`w@C76CHgT)i1iRq<-7mqcqYP%xS=pW8{vtdF1lYlfZMGt$ z>os{#rW`zTOevIG7)Y6mSE?>7Ojg^fim!+P*WVIo?R(3=478zH%?op!q@eeiDzxjp z%qu5o4P->>=u5m6jJQ9dnfn|-+lv=HV<|L)){lE)E$*4JPlZu254$TlH7C?`Ke?V5 z3{aThzjx`8)ZVKhTRr4jEAhJ=$)*AW-#y;h-I0`>si%R?dQ|)#(~-9+7r|FbQ_)v~ zK1?BaYiiQU<5VAw*c2uoe=)sxI8T9?EbXvAXu1J`Y|7PcF8)x0cAgX*ZHK{cARP{> zhAj8iHX9Pfbx=2o7Z};3OKN-eOfQxf#~`q05)l!IHl9q~ve2y}A`cxuX4c2@05TgV zzAeFcRCvety+&*~EQ+=1$gL+tec8v=fzkquDiby5?niHK8 z*GiFo{9(tohSgNu)qlb1MEwCdQbu?!vt!A_*;l@0ABVNcldUrvD8OpD=Shi-ydsBv z0Gzu)zO&@dJcBcarLB9p&LKR?gQ^OZg$1?ep|9N!O$O*jGmNyWGu<41kqnRPiem1P z9%wM_@h$=Xh;Y@i9bisIJ==MDU-tQd2g|&huK?2z(9UjgmTl!e5!$xXjm*G(lQ`&i6^;QYRgxlkT zg;>1G7QALTm_+WXi;Z^0eqE2+02$;GblN|QaosGYy~1wRR-i)Xjf1GBT$%Usv~znf zUtign7G%9AJ)UG+>3f$57H}ZMVgA;1l(bCj9;vs?Vjt|3&rt0B(fSCJYz+6(jpR=p zr*TH$Md-T|uhY(P%_V4>vg>K5Q4F$1*fu+DZE&ng*6i(;l-c%>+0*Iz&Bp%MZLyQ; zb2S_gGMKKDmEX=RV}@e&9rjFtl;Gv`dDrp9!6 z!{w0eESkC)EnAp?9Zx2g@)$68c#dTybu;1#72(o?L~nYf3%y+C*SoyI#ZF}!o%Uh$ zJc@GnaxSj8wWU!wJ$ZiJ#gDFqzYn4!&ft9KFv62&V3x!cU@C)yJdkhjYOo1~c7`H4 zt*#5z)ET%up6%pg#+iQ4ijYH2+;u@2NhV;c-07lx)IARQ@kG7TqS-}?Oxj!Riz0q~ z>pk-3xJ_kCV z(0h>xZEjCo@PlcWqQLmb6GHR$S@UC=e)pBhF-h(u@>8eO9T2_RU!F-Huu!(Gndo(uJaf1(&jU~f`{1(ZB#FPD=xI7)7@wTT~Y875^BZE3- zGeDoebx`TNRBt|(lY-Srd2Bzpezb&|y2|M>tIX{!QZ>gl);sxxeE~5Xbj^C4^>kqh zyg+6NEhD<-ZFR@4$xFkLyBq$@~eJ_tohWJ#`ilcOQRAmU0OrAyl`W2?82t+Sv1@n{$qB z+}wc5!urBI{Ca&*p@t8w-PD~eZC6VLRvp9XW&#r5dTr%NJl5B*xTo-51Jct~0_z|T z^k}=fXazv+9DL;;l~Ac1vQOlL#E zanfxP+e+lpASG{mxM*he2KKFc1@ZxVWW&MVSxYY#O=gn&*nGeJ@U(|EW7;%Lxt7PPY-JB)^@t0>ZiX&TVolMZk6Oi{lCte)} zwDl$Z#%jx!JRcs%Mv??Z=M$$Y$P_ziL&HhBgNKlGSrooEU9y{?dcD+)YV%kk)dYs& zDFsGq5!In3Erc~Vo`p%(p%Pk*^hG^JwNLlli38@1GWt2!2^0ty9=M58H_YYam!>2P zdO(o1->#DskM_Sp^f7!lS@pHk`(UW+(NH<_l1ZFqxTLv}OVu}>Us7|lhk-otQ8E7< zW&ANufr;?cKtc!SNMXJ*ae`&fKm%f|PigNFg;bgXj7yR#yj;pClgV zjt>a5D^PDT%#!+0`3%`8Y~Q6;VmZ+@ulA+)04vkmMPE61yrG>o%*3k+`_CbEu12Y4 z0b6FFRW0+WJyCG9x{!SzeZS>Yd(g4ub0PPr)ZOUhX>9Fv0CT6|7< zBz{K0Y&6CMVD?9y1D0ja0O#FOn5LM04dm@b09?HKLF1a5KJIu(0>kuYMucx^aB9K z@tK~03B|0}o6GC4IV}gbCZ-FJI`OopdU(E&Y{>A){=s-sU552|x*84+^6@rJp<;=a`j{XHB CgCDs7 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 39c50781f9..6fa1e45f05 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -104,7 +104,8 @@ C_SEMICOL : ; C_AT : @ C_DOT : . C_MONEY : $ -C_SIGN : +, - +C_PLUS : + +C_MINUS : - C_CARET : ^ C_BIN : 0x01-0x08, 0x11, 0x12, 0x14-0x1F C_WORD : all the rest diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 39fe2359c7..e09334ca7a 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -159,54 +159,55 @@ Red/System [ 2C2C2C2C2C2C2C292C2C2C332A2C2C2C2C2C2C2C2C2C2C2C352C2C2C2C2C2C2C 2C2C2C35 } transitions: #{ -00001313333435360432020C27272727270B32202706320132271D2632272732 -3101000101010101010101010101010101010101010101010101010101010101 -3231020202020202020202023702020202020202020202020202020202020302 -0232320202020202020202020202020202020202020202020202020202020202 -0202323104040404040404040437040404040404040404040404040404040404 -0504043232040404040404040404040404040404040404040404040404040404 -040404043231383807073838383838380A070738070707070707070707383807 -0707070707323839390707393939393939320707390707070707070708073939 -0707070707073239070709093232323232323232323232320932323232323232 -3232323232323232320707070732323232323232323232323207323232323232 -323232323232323232390A0A0A0A0A0A0A0A0A0A390A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A32323A3A0B0B3A3A3A3A3A3A3A0B0B0B0B0B0B0B0B0B0B -0B0B3A3A0B0B0B0B0B0B323A3F3F121211323D320D320F121232121212121232 -3212323F3F121212121212323F0D0D0D0D32323232323B323232320D0D0D3232 -323232320E3232323232320D32320E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F323C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111113E111111111111111111 -1111111111111111111111111111111132323F3F12123F3F3F3F3F3F3F121212 -1212121212121212123F3F121212121212323F41411313414141414141410C13 -191B1532183241324032412A1432323232323241424215154242424242424216 -15321B1532423242324032423232323232323232424242151542424242424242 -1B32423215324232423240323232173232323232324242424242424242424242 -4216424216161642424216424242421642164216163231434317174343434343 -4343323243323232433243323232323217323232323232434444181844444444 -4444441818441818181818441844184444184418441818324432321A1A323232 -323232323232323232323232323232323232323232323232323246461A1A4646 -464646464632321A32323246324632323246321A3232323232323132321C1C32 -3232323232323232323232323232323232323232323232323232323245451C1C -45454545454545323245321C3245324532323245321C3232323232324532321E -1E32323232323232323232323232323232323232323232323232323232324747 -1E1E47474747474747471E4732323247324732323247321F3232323232323147 -471F1F47474747474747471F4732323247324732323247323232323232323231 -3838212138383838383838212138212121212132382121383821212121212132 -3821212121212121212121222121242121212121214821212121212121212121 -3232222222222222222222222122222222222222222222222222222222222322 -2232322222222222222222222222222222222222222222222222222222222222 -2222323224242424242424242424242424212424242424242424242424242424 -2424243232242424242424242424242424242424242424242424242424242424 -2424242432323838131338383838383838323227272727273832273227382727 -2727322727323838382727383838383838383227282727274B3827273232382A -271E272727273238383829293838383838383829292929292929383229292938 -2929292929292932384949292949494949494949293229292929294949322949 -492929322932292932494A4A2A2A4A4A4A4A4A4A4A3232322A2A2A4A4A4A322A -324A322A322A322A2A324A32322C2C323235363232022E2D2D2D2D2D3232202D -3232322A2D322F322D2D323241412C2C414141414141413213411B1532413241 -324032412A143232323232324138382D2D38383838383838322D382D2D2D3838 -2D2D3232382A2D322D2D2D2D32383F3F12121132323232320F12123212121212 -12323212323F3F121212121212323F38382C2C38383838383838323227272727 -27383227322738272727273227273238 +00001313333435360432020C27272727270B32202706320132271D2626322727 +3231010001010101010101010101010101010101010101010101010101010101 +0101323102020202020202020202370202020202020202020202020202020202 +0203020232320202020202020202020202020202020202020202020202020202 +0202020202023231040404040404040404370404040404040404040404040404 +0404040404050404323204040404040404040404040404040404040404040404 +040404040404040404043231383807073838383838380A070738070707070707 +0707073838070707070707073238393907073939393939393207073907070707 +0707070807393907070707070707323907070909323232323232323232323232 +0932323232323232323232323232323232320707070732323232323232323232 +32320732323232323232323232323232323232390A0A0A0A0A0A0A0A0A0A390A +0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32323A3A0B0B3A3A3A3A3A3A +3A0B0B0B0B0B0B0B0B0B0B0B0B3A3A0B0B0B0B0B0B0B323A3F3F121211323D32 +0D320F1212321212121212323212323F3F12121212121212323F0D0D0D0D3232 +3232323B323232320D0D0D3232323232320E323232323232320D32320E0D0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E32310F0F +0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F0F323C +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +323211111111113E111111111111111111111111111111111111111111111111 +111132323F3F12123F3F3F3F3F3F3F1212121212121212121212123F3F121212 +12121212323F41411313414141414141410C13191B1532183241324032412A14 +323218323232324142421515424242424242421615321B153242324232403242 +3232323232323232324242421515424242424242421B32423215324232423240 +3232321732323232323232424242424242424242424242164242161616424242 +1642424242164216164216163231434317174343434343434332324332323243 +3243323232323217323232323232324344441818444444444444441818441818 +18181844184418444418441818441818324432321A1A32323232323232323232 +323232323232323232323232323232323232323246461A1A4646464646464632 +321A32323246324632323246321A323232323232323132321C1C323232323232 +32323232323232323232323232323232323232323232323245451C1C45454545 +454545323245321C3245324532323245321C323232323232324532321E1E3232 +3232323232323232323232323232323232323232323232323232323247471E1E +47474747474747471E4732323247324732323247321F32323232323232314747 +1F1F47474747474747471F473232324732473232324732323232323232323231 +3838212138383838383838212138212121212132382121383821212121212121 +3238212121212121212121212221212421212121212148212121212121212121 +2121323222222222222222222222212222222222222222222222222222222222 +2223222232322222222222222222222222222222222222222222222222222222 +2222222222223232242424242424242424242424242124242424242424242424 +2424242424242424323224242424242424242424242424242424242424242424 +2424242424242424242432323838131338383838383838323227272727273832 +273227382727272727322727323838382727383838383838383227282727274B +3827273232382A271E2727272727323838382929383838383838382929292929 +2929383229292938292929292929292932384949292949494949494949293229 +29292929494932294949292932292932292932494A4A2A2A4A4A4A4A4A4A4A32 +32322A2A2A4A4A4A322A324A322A322A2A322A2A324A32322C2C323235363232 +022E2D2D2D2D2D3232202D3232322A2D322F2F322D2D323241412C2C41414141 +4141413213411B1532413241324032412A14323232323232324138382D2D3838 +3838383838322D382D2D2D38382D2D3232382A2D322D2D2D2D2D32383F3F1212 +1132323232320F1212321212121212323212323F3F12121212121212323F3838 +2C2C383838383838383232272727272738322732273827272727273227273238 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 851e46d76b..90b64cbedd 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -66,12 +66,13 @@ lexer: context [ C_AT ;-- 24 C_DOT ;-- 25 C_MONEY ;-- 26 - C_SIGN ;-- 27 - C_CARET ;-- 28 - C_BIN ;-- 29 - C_WORD ;-- 30 - C_ILLEGAL ;-- 31 - C_EOF ;-- 32 + C_PLUS ;-- 27 + C_MINUS ;-- 28 + C_CARET ;-- 29 + C_BIN ;-- 30 + C_WORD ;-- 31 + C_ILLEGAL ;-- 32 + C_EOF ;-- 33 ] #enum date-char-classes! [ @@ -217,9 +218,9 @@ lexer: context [ C_PAREN_OP ;-- 28 ( C_PAREN_CL ;-- 29 ) C_WORD ;-- 2A * - (C_SIGN or C_FLAG_SIGN) ;-- 2B + + (C_PLUS or C_FLAG_SIGN) ;-- 2B + (C_COMMA or C_FLAG_COMMA) ;-- 2C , - (C_SIGN or C_FLAG_SIGN) ;-- 2D - + (C_MINUS or C_FLAG_SIGN) ;-- 2D - (C_DOT or C_FLAG_DOT) ;-- 2E . C_SLASH ;-- 2F / C_ZERO ;-- 30 0 @@ -1326,7 +1327,7 @@ probe ["--- " s/1 " ---"] class: lex-classes/cp flags: class and FFFFFF00h or flags - index: state * 33 + (class and FFh) + 1 + index: state * (size? character-classes!) + (class and FFh) + 1 state: as-integer transitions/index index: state + 1 @@ -1339,7 +1340,7 @@ probe ["--- " s/1 " ---"] p: p + 1 ] unless term? [ - index: state * 33 + C_EOF + 1 + index: state * (size? character-classes!) + C_EOF + 1 state: as-integer transitions/index ] lex/in-pos: p From fb159ca3ac1f5d8ac29eb499eb03e09b144a8937 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 19:04:06 +0100 Subject: [PATCH 0332/3432] FEAT: adds support for decoding month names in scan-date. --- runtime/lexer.reds | 48 ++++++++++++++++++++++++---------- utils/generate-misc-tables.red | 9 ++++--- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 90b64cbedd..e1eb6c45ca 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -177,8 +177,8 @@ lexer: context [ date-cumul: #{ 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000010203040506070809000000000000 - 004142434445464748494A004C4D4E4F5000525300555600000D000000000000 - 006162636465666768696A006C6D6E6F70007273747576000003000000000000 + 004142434445464748494A004C4D4E4F50005253005556000003000000000000 + 004142434445464748494A004C4D4E4F50005253005556000003000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -1099,42 +1099,61 @@ lexer: context [ c [integer!] pos [integer!] shift [integer!] + month [integer!] ][ probe "scan-date" -probe as-c-string s -probe as-c-string e field: system/stack/allocate 12 c: 0 state: S_DT_START loop as-integer e - s [ -probe ["--- " s/1 " ---"] +;probe ["--- " s/1 " ---"] cp: 1 + as-integer s/1 class: as-integer date-classes/cp -?? class - index: state * 12 + class + 1 +;?? class + index: state * (size? date-char-classes!) + class + 1 state: as-integer date-transitions/index index: state + 1 pos: as-integer fields-table/index field/pos: c -?? state -?? cp +;?? state +;?? cp c: c * 10 + as-integer date-cumul/cp -?? c +;?? c shift: as-integer reset-table/index c: c >>> shift s: s + 1 -?? c +;?? c ] - index: state * 12 + C_DT_EOF + 1 + index: state * (size? date-char-classes!) + C_DT_EOF + 1 state: as-integer date-transitions/index -?? state +;?? state index: state + 1 pos: as-integer fields-table/index -?? pos +;?? pos field/pos: c + month: field/3 + if any [month > 12 month < 1][ ;-- month as a word + month: switch month [ ;-- convert hashed word to correct value + 8128 81372323 [1] + 7756 776512323 [2] + 8432 843942 [3] + 7382 739006 [4] + 8353 [5] ;-- "May" has no longer form + 8328 83349 [6] + 8326 83263 [7] + 7421 7430330 [8] + 9070 480839780 [9] + 8570 85786372 [10] + 8676 868374372 [11] + 7557 756474372 [12] + default [throw LEX_ERROR 0] + ] + field/3: month + ] +;comment { probe [ "-----------------" "^/trash: " field/1 @@ -1150,6 +1169,7 @@ probe ["--- " s/1 " ---"] "^/TZ-h : " field/11 "^/TZ-m : " field/12 ] +;} system/stack/free 12 cell: alloc-slot lex cell/header: TYPE_NONE diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index ecff17344f..78fccfa522 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -111,16 +111,17 @@ gen-date-table: function [][ gen-date-calc-table: function [][ out: make binary! 256 digit: charset "0123456789" - letter: charset "abcdefghijlmnoprstuvABCDEFGHIJLMNOPRSUV" + lower: charset "abcdefghijlmnoprsuv" ;-- forces t and T to be zero (separator) + upper: charset "ABCDEFGHIJLMNOPRSUV" yY: charset "yY" repeat i 256 [ c: to-char i - 1 append out to-char case [ find digit c [to-char c - #"0"] - find letter c [to-char c] - c = #"y" [3] - c = #"Y" [13] + find lower c [to-char c - 32] + find upper c [to-char c] + find yY c [3] 'else [0] ] ] From 144aaf29bc45a6ba850c099d29d47c58b781df2b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 22:33:56 +0100 Subject: [PATCH 0333/3432] FEAT: [R/S] adds /zero refinement to system/stack/allocate. This refinement will fill the allocated stack space with zeros. --- system/compiler.r | 6 +++--- system/targets/ARM.r | 10 +++++++++- system/targets/IA-32.r | 8 +++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 234394f700..8eade0b543 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -423,7 +423,7 @@ system-dialect: make-profilable context [ none ] - system-action?: func [path [path!] /local expr port-type op ret?][ + system-action?: func [path [path!] /local expr port-type op ret? z?][ if path/1 = 'system [ switch/default path/2 [ stack [ @@ -434,10 +434,10 @@ system-dialect: make-profilable context [ if any [none? last-type last-type/1 <> 'integer!][ throw-error "system/stack/allocate expects an integer! argument" ] - emitter/target/emit-alloc-stack + emitter/target/emit-alloc-stack z?: path/4 = 'zero emitter/target/emit-get-stack last-type: [pointer! [integer!]] - true + any [z? none? path/4] ] free [ pc: next pc diff --git a/system/targets/ARM.r b/system/targets/ARM.r index 192722a2e6..54a996447f 100644 --- a/system/targets/ARM.r +++ b/system/targets/ARM.r @@ -871,9 +871,17 @@ make-profilable make target-class [ ] ] - emit-alloc-stack: does [ + emit-alloc-stack: func [zeroed? [logic!]][ emit-i32 #{e04dd100} ;-- SUB sp, r0, LSL #2 ;emit-i32 #{e3cdd003} ;-- BIC sp, sp #3 ; align to lower 32-bit bound + if zeroed? [ + emit-i32 #{e1a03000} ;-- MOV r3, r0 ; count + emit-i32 #{e1a02000} ;-- MOV r2, sp ; dst + emit-i32 #{e3a01000} ;-- MOV r1, 0 ; zero + emit-i32 #{e4821004} ;-- .loop: STR r1, [r2!], #4 + emit-i32 #{e2555001} ;-- SUBS r5, r5, 1 + emit-i32 #{1afffffc} ;-- BNE .loop + ] ] emit-free-stack: does [ diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index 5b329cc326..e573a2c5a0 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -239,10 +239,16 @@ make-profilable make target-class [ ] ] - emit-alloc-stack: does [ + emit-alloc-stack: func [zeroed? [logic!]][ + if zeroed? [emit #{89C1}] ;-- MOV ecx, eax emit #{C1E002} ;-- SHL eax, 2 emit #{29C4} ;-- SUB esp, eax emit #{83E4FC} ;-- AND esp, -4 ; align to lower bound + if zeroed? [ + emit #{89E7} ;-- MOV edi, esp + emit #{31C0} ;-- XOR eax, eax + emit #{F3AB} ;-- REP STOSD + ] ] emit-free-stack: does [ From 85175636ef140a9ade0d2a4afe3aedd1d0cfd968 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 27 Oct 2019 22:35:04 +0100 Subject: [PATCH 0334/3432] FEAT: assembles the date! value from loaded fields in scan-date. --- runtime/lexer.reds | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e1eb6c45ca..382071df74 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1102,7 +1102,7 @@ lexer: context [ month [integer!] ][ probe "scan-date" - field: system/stack/allocate 12 + field: system/stack/allocate/zero 12 c: 0 state: S_DT_START loop as-integer e - s [ @@ -1153,7 +1153,7 @@ probe "scan-date" ] field/3: month ] -;comment { +comment { probe [ "-----------------" "^/trash: " field/1 @@ -1169,10 +1169,16 @@ probe "scan-date" "^/TZ-h : " field/11 "^/TZ-m : " field/12 ] -;} - system/stack/free 12 - cell: alloc-slot lex - cell/header: TYPE_NONE +} + date/set-all + as red-date! alloc-slot lex + field/2 ;-- year + field/3 ;-- month + field/4 ;-- day + field/5 ;-- hour + field/6 ;-- min + field/7 ;-- sec + field/8 ;-- nano ] scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 4915e8ff1a991825f1e0ad8ee8fe32ca8edc140a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 25 Oct 2019 17:11:48 +0800 Subject: [PATCH 0335/3432] FIX: slider data --- modules/view/backends/gtk3/gtk.reds | 11 ++++++-- modules/view/backends/gtk3/gui.reds | 17 ++++++------- modules/view/backends/gtk3/handlers.reds | 32 ++++++------------------ 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index aa9b2aa425..83b5ce3a22 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1292,6 +1292,10 @@ GPtrArray!: alias struct! [ event [handle!] return: [logic!] ] + gtk_widget_draw: "gtk_widget_draw" [ + widget [handle!] + cr [handle!] + ] gtk_widget_queue_draw: "gtk_widget_queue_draw" [ widget [handle!] ] @@ -1803,6 +1807,10 @@ GPtrArray!: alias struct! [ range [handle!] return: [float!] ] + gtk_range_set_inverted: "gtk_range_set_inverted" [ + range [handle!] + bool [logic!] + ] gtk_progress_bar_new: "gtk_progress_bar_new" [ return: [handle!] ] @@ -2285,9 +2293,8 @@ GPtrArray!: alias struct! [ return: [handle!] ] - - gtk_widget_get_pango_context: "gtk_widget_get_pango_context" [ + widget [handle!] return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b271b7b84f..35eddd4cda 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1006,16 +1006,14 @@ change-data: func [ TYPE_OF(data) = TYPE_PERCENT ][ f: as red-float! data - gtk_progress_bar_set_fraction widget f/value + gtk_progress_bar_set_fraction widget f/value ] all [ type = slider TYPE_OF(data) = TYPE_PERCENT ][ f: as red-float! data - size: as red-pair! values + FACE_OBJ_SIZE - len: either size/x > size/y [size/x][size/y] - gtk_range_set_value widget f/value * (as-float len) + gtk_range_set_value widget f/value * 100.0 ] type = check [ set-logic-state widget as red-logic! data yes @@ -1622,11 +1620,12 @@ OS-make-view: func [ ] sym = slider [ vertical?: size/y > size/x - value: either vertical? [size/y][size/x] - widget: gtk_scale_new_with_range vertical? 0.0 as float! value 1.0 - value: get-position-value as red-float! data value - if vertical? [value: size/y - value] - gtk_range_set_value widget as float! value + widget: gtk_scale_new_with_range vertical? 0.0 100.0 1.0 + if vertical? [ + gtk_range_set_inverted widget yes + ] + fvalue: get-fraction-value as red-float! data + gtk_range_set_value widget fvalue * 100.0 gtk_scale_set_has_origin widget no gtk_scale_set_draw_value widget no ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 79b3b5a163..5f7323ae90 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -336,34 +336,16 @@ range-value-changed: func [ range [handle!] widget [handle!] /local - vals [red-value!] - val [float!] - size [red-pair!] - ; type [red-word!] + values [red-value!] pos [red-float!] - ; sym [integer!] - max [float!] + value [float!] ][ - ; This event happens on GtkRange widgets including GtkScale. - ; Will any other widget need this? - vals: get-face-values widget - ;type: as red-word! vals + FACE_OBJ_TYPE - size: as red-pair! vals + FACE_OBJ_SIZE - pos: as red-float! vals + FACE_OBJ_DATA - - ;sym: symbol/resolve type/symbol - - ;if type = slider [ - val: gtk_range_get_value range - either size/y > size/x [ - max: as-float size/y - val: max - val - ][ - max: as-float size/x - ] - pos/value: val / max + values: get-face-values widget + pos: as red-float! values + FACE_OBJ_DATA + + value: gtk_range_get_value range + pos/value: value / 100.0 make-event range 0 EVT_CHANGE - ;] ] combo-selection-changed: func [ From 95178e734213f56ee062dd93a4fe506afec35db8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 28 Oct 2019 14:46:04 +0800 Subject: [PATCH 0336/3432] FIX: change face offset issues --- modules/view/backends/gtk3/gui.reds | 49 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 35eddd4cda..ed69c57d9b 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -203,6 +203,24 @@ get-face-layout: func [ ] ] +get-face-child-layout: func [ + widget [handle!] + sym [integer!] + return: [handle!] +][ + case [ + sym = window [ + GET-CONTAINER(widget) + ] + sym = group-box [ + gtk_bin_get_child widget + ] + true [ + widget + ] + ] +] + set-widget-child: func [ parent [handle!] widget [handle!] @@ -280,6 +298,7 @@ set-widget-child-offset: func [ values [red-value!] ntype [red-word!] sym [integer!] + cparent [handle!] ][ either type = window [ gtk_window_move widget pos/x pos/y @@ -292,7 +311,11 @@ set-widget-child-offset: func [ set-widget-offset layout widget 0 0 ] unless null? parent [ - set-widget-offset parent layout pos/x pos/y + values: get-face-values parent + ntype: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve ntype/symbol + cparent: get-face-child-layout parent sym + set-widget-offset cparent layout pos/x pos/y ] ] ] @@ -804,30 +827,14 @@ change-font: func [ change-offset: func [ widget [handle!] + values [red-value!] pos [red-pair!] type [integer!] /local parent [handle!] - layout [handle!] - values [red-value!] - ntype [red-word!] - sym [integer!] ][ - either type = window [ - gtk_window_move widget pos/x pos/y - ][ - values: get-face-values widget - ntype: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve ntype/symbol - parent: get-face-parent widget values sym - layout: get-face-layout widget values sym - if layout <> widget [ - set-widget-offset layout widget 0 0 - ] - unless null? parent [ - set-widget-offset parent layout pos/x pos/y - ] - ] + parent: get-face-parent widget values type + set-widget-child-offset parent widget pos type ] change-size: func [ @@ -1787,7 +1794,7 @@ OS-update-view: func [ flags: int/value if flags and FACET_FLAG_OFFSET <> 0 [ - change-offset widget as red-pair! values + FACE_OBJ_OFFSET type + change-offset widget values as red-pair! values + FACE_OBJ_OFFSET type ] if flags and FACET_FLAG_SIZE <> 0 [ change-size widget as red-pair! values + FACE_OBJ_SIZE type From 704353eeaf79c61d1fff30eb05b6f79550eeb348 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 28 Oct 2019 15:47:23 +0800 Subject: [PATCH 0337/3432] FIX: window no need connect `key event` as it be done by `view` --- modules/view/backends/gtk3/events.reds | 80 +++++------------------- modules/view/backends/gtk3/handlers.reds | 8 +-- 2 files changed, 19 insertions(+), 69 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index f8c73c800d..5a32db0769 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -549,31 +549,6 @@ post-quit-msg: func [ exit-loop: exit-loop - 1 ] -;;------------- centralize here connection handlers -;; The goal is to only connect gtk handlers only when actor is provided -;; Rmk: Specific development for rich-text with panel parent with on-over actor for rich-text -;; The panel needs to receive the event otherwise the rich-text can't receive the event with the associated actor. -;; A delegation connection is provided to do so. - -#enum DebugConnect! [ - DEBUG_CONNECT_NONE: 0 - DEBUG_CONNECT_WIDGET: 1 - DEBUG_CONNECT_COMMON: 2 - DEBUG_CONNECT_NOTIFY: 4 - DEBUG_CONNECT_RESPOND_KEY: 8 - DEBUG_CONNECT_RESPOND_MOUSE: 16 - DEBUG_CONNECT_RESPOND_WINDOW: 32 - DEBUG_CONNECT_ALL_ADD: 63 - DEBUG_CONNECT_RESPOND_EVENT: 65536 - DEBUG_CONNECT_ALL: 131071 -] - -;; DEBUG mode: NONE vs ALL vs ALL_ADD -debug-connect-level: DEBUG_CONNECT_NONE -;debug-connect-level: DEBUG_CONNECT_ALL_ADD - -debug-connect?: func [level [integer!] return: [logic!]][debug-connect-level and level <> 0] - ;; TODO: before finding better solution!!!! ;; container-type? is now only restricted to rich-text (cf gui.red) ;; since @@ -606,12 +581,21 @@ connect-common-events: function [ ] connect-focus-events: function [ + evbox [handle!] widget [handle!] - data [int-ptr!] + sym [integer!] ][ - assert widget <> null - gobj_signal_connect(widget "focus-in-event" :focus-in-event data) - gobj_signal_connect(widget "focus-out-event" :focus-out-event data) + if any [ + sym = base + sym = rich-text + sym = field + sym = area + ][ + gtk_widget_set_can_focus widget yes + gtk_widget_set_focus_on_click widget yes + gobj_signal_connect(evbox "focus-in-event" :focus-in-event widget) + gobj_signal_connect(evbox "focus-out-event" :focus-out-event widget) + ] ] connect-notify-events: function [ @@ -634,61 +618,41 @@ connect-widget-events: function [ ][ evbox: get-face-evbox widget values sym ;; register red mouse, key event functions - connect-common-events evbox widget + if sym <> window [ + connect-common-events evbox widget + ] connect-notify-events evbox widget + connect-focus-events evbox widget sym case [ sym = check [ ;@@ No click event for check - ;gobj_signal_connect(widget "clicked" :button-clicked null) gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = radio [ - ;@@ Line below removed because it generates an error and there is no click event for radio - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add radio toggled " lf]] gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = button [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add button clicked " lf]] gobj_signal_connect(widget "clicked" :button-clicked widget) ] sym = base [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_grab_focus widget - connect-focus-events widget widget ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_grab_focus widget - connect-focus-events widget widget ] sym = window [ gobj_signal_connect(widget "event" :window-event widget) - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window delete-event " lf]] gobj_signal_connect(widget "delete-event" :window-delete-event widget) ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add window size-allocate " lf]] gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_grab_focus widget - connect-focus-events widget widget ] sym = slider [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add slider value-changed " lf]] gobj_signal_connect(widget "value-changed" :range-value-changed widget) ] sym = text [0] sym = field [ gobj_signal_connect(widget "changed" :field-changed widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_grab_focus widget - connect-focus-events widget widget ] sym = progress [ 0 @@ -696,16 +660,9 @@ connect-widget-events: function [ sym = area [ ; _widget is here buffer buffer: gtk_text_view_get_buffer widget - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area changed " lf]] gobj_signal_connect(buffer "changed" :area-changed widget) - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-all " lf]] g_object_set [widget "populate-all" yes null] - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add area populate-popup" lf]] gobj_signal_connect(widget "populate-popup" :area-populate-popup widget) - gtk_widget_set_can_focus widget yes - gtk_widget_set_focus_on_click widget yes - gtk_widget_grab_focus widget - connect-focus-events widget widget ] sym = group-box [ 0 @@ -714,12 +671,10 @@ connect-widget-events: function [ gobj_signal_connect(widget "draw" :base-draw widget) ] sym = tab-panel [ - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add tab-panel switch-page " lf]] gobj_signal_connect(widget "switch-page" :tab-panel-switch-page widget) ] sym = text-list [ ;;; Mandatory and can respond to (ON_SELECT or ON_CHANGE) - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add text-list selected-rows-changed " lf]] gobj_signal_connect(widget "selected-rows-changed" :text-list-selected-rows-changed widget) ] any [ @@ -727,7 +682,6 @@ connect-widget-events: function [ sym = drop-down ][ ;;; Mandatory! and can respond to (ON_SELECT or ON_CHANGE) - ;; DEBUG: if debug-connect? DEBUG_CONNECT_WIDGET [print ["Add drop-(list|down) changed " lf]] gobj_signal_connect(widget "changed" :combo-selection-changed widget) ] true [0] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 5f7323ae90..8c49683f73 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -435,18 +435,14 @@ key-press-event: func [ face [red-object!] qdata [handle!] ][ - ;; DEBUG: print ["key-press-event: " event-key/keyval lf] if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state - ;; DEBUG: print ["key: " key " flags: " flags " key or flags: " key or flags lf] res: make-event widget key or flags EVT_KEY_DOWN - ;; DEBUG: print ["field press res " res lf] if res <> EVT_NO_DISPATCH [ - ;; DEBUG: print ["special-key=" special-key " key=" key lf] either special-key <> -1 [ switch key and FFFFh [ RED_VK_SHIFT RED_VK_CONTROL @@ -458,8 +454,7 @@ key-press-event: func [ ] ][res: make-event widget key or flags EVT_KEY] ] - ;; DEBUG: print ["key-press end" lf] - res + EVT_NO_DISPATCH ] key-release-event: func [ @@ -477,6 +472,7 @@ key-release-event: func [ flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state make-event widget key or flags EVT_KEY_UP + EVT_NO_DISPATCH ] field-changed: func [ From 2fbd3a7fcd696f54ace5560a0f83c83da8d9c7a6 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 28 Oct 2019 09:24:16 +0100 Subject: [PATCH 0338/3432] FIX: GTK: compiling error. --- modules/view/backends/gtk3/gtk.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 5eaa0816ff..845e623b79 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1771,6 +1771,7 @@ GPtrArray!: alias struct! [ gtk_entry_set_has_frame: "gtk_entry_set_has_frame" [ entry [handle!] has-frame [logic!] + ] gtk_entry_set_attributes: "gtk_entry_set_attributes" [ entry [handle!] list [handle!] From 5ceb2cbcc14601a033f92ef7851a88f440f2327e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 28 Oct 2019 20:16:38 +0100 Subject: [PATCH 0339/3432] FEAT: various fixes and improvements in parsing date/time. --- docs/lexer/date-FSM.csv | 17 ++++++------ docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26004 -> 24963 bytes runtime/datatypes/date.reds | 2 +- runtime/lexer-transitions.reds | 32 ++++++++++++----------- runtime/lexer.reds | 15 +++++------ utils/generate-lexer-table.red | 46 +++++++++++++++++---------------- 7 files changed, 59 insertions(+), 55 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index 580edac65c..c2042507f5 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -22,19 +22,20 @@ S_DT_DM;S_DT_DMM;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_E S_DT_DMM;T_DT_ERROR;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DMONTH;F_DT_DMY;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DMON;T_DT_ERROR;S_DT_DMON;F_DT_DMONTH;F_DT_DMONTH;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TM_START2;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM +F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;F_TM_N1;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS +F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;F_TM_N1;T_DT_ERROR;T_DT_ERROR;T_TM_HMS F_TM_N1;F_TM_N;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ S_TZ_START;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 2cc4865651..d627435635 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -23,7 +23,7 @@ S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_F S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index f9f12717b9d127d7f62d5d36fc0c230524d9588a..17df29cd9f5d964185df0e9f8390a3a0bb7daed4 100644 GIT binary patch delta 13066 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 z z^}WSVBmw`Z7G|I4Hd~T)SZ~D!W;&G{Ng&xgNLVEBv0teD0fR5GGkQ%gNLSmlUbDoC z9p4DgTDk`7$>E)LJ~)C4q67c)x0PgdMd`UU^Q%=^F120`V^M!3&mSxNMFrqaIwFXj zb}t+vB|1O16og-w0TxhK?BXN{T|s=1>i79z;kqNa5IB%Yf#Si`7P{`lYCjPt-F)XW z=~0%1D!S~W(&lqOzx^Y-^e1{bt9=G-Iu1b~Q7zj!ztpZd=}KOoS0#Ow9VV$@kW|#| zH49-_#Qc}23QS#-peQ(bAqJ%|k7e?(YJ4HJMf%R1;D(ZlAEH2_M-(QpPaC2z?K%j6+s-QPppzi}8@YcJk zT@5|p^P(1m#bt$Q5q6(uCDm`QX;w>Lg^YPAZ5}5QoP`aed>9s+&uL$-&$$j0jJc1M zlNWAe{TZ!3fI^8o8X(+FOilX$R?{Gal9AnHv z{_pz~VPOApLMHHpu?(EQIGEIgn&Pij8Vn4r#RKp#$rh5>outxxv6N{_W@z_1|BrFy(-A(gQD>KB4#xBk0p^+R&%naR2sQ XK0`2tnFw5!G1$QD3DT9x>> shift s: s + 1 ;?? c ] @@ -1352,14 +1350,15 @@ comment { cp: 1 + as-integer p/value class: lex-classes/cp flags: class and FFFFFF00h or flags + class: class and FFh - index: state * (size? character-classes!) + (class and FFh) + 1 + index: state * (size? character-classes!) + class + 1 state: as-integer transitions/index index: state + 1 offset: offset + as-integer skip-table/index - index: class and FFh + 1 + index: class + 1 line: line + line-table/index if state > --EXIT_STATES-- [term?: yes break] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 93c812bb53..fc44c9c59f 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -131,33 +131,35 @@ context [ F_DT_DMYY 1 2 ;-- 24 F_DT_DMYYY 1 2 ;-- 25 F_DT_DMYYYY 1 2 ;-- 26 - S_TM_START 0 1 ;-- 27 - F_TM_H 1 5 ;-- 28 - F_TM_HH 1 5 ;-- 29 - S_TM_HM 0 5 ;-- 30 - F_TM_M 1 6 ;-- 31 - F_TM_MM 1 6 ;-- 32 - S_TM_HMS 0 6 ;-- 33 - F_TM_S 1 7 ;-- 34 - F_TM_SS 1 7 ;-- 35 - F_TM_N1 0 8 ;-- 36 - F_TM_N 1 8 ;-- 37 - S_TZ_START 0 1 ;-- 38 - S_TZ_H 1 11 ;-- 39 - F_TZ_HH 1 11 ;-- 40 - F_TZ_HM 0 12 ;-- 41 - S_TZ_M 1 12 ;-- 42 - --FINAL-STATES-- 0 1 ;-- 43 + S_TM_START 0 4 ;-- 27 + S_TM_START2 0 2 ;-- 28 + F_TM_H 1 5 ;-- 29 + F_TM_HH 1 5 ;-- 30 + S_TM_HM 0 5 ;-- 31 + F_TM_M 1 6 ;-- 32 + F_TM_MM 1 6 ;-- 33 + S_TM_HMS 0 6 ;-- 34 + F_TM_S 1 7 ;-- 35 + F_TM_SS 1 7 ;-- 36 + F_TM_N1 0 8 ;-- 37 + F_TM_N 1 8 ;-- 38 + S_TZ_START 0 4 ;-- 39 + S_TZ_H 1 11 ;-- 40 + F_TZ_HH 1 11 ;-- 41 + F_TZ_HM 0 12 ;-- 42 + S_TZ_M 1 12 ;-- 43 T_DT_ERROR 0 1 ;-- 44 T_DT_YMDAY 0 4 ;-- 45 T_DT_DMYEAR 0 2 ;-- 46 T_DT_YWWD 0 10 ;-- 47 T_DT_WEEK 0 9 ;-- 48 - T_TM_NZ 0 8 ;-- 49 - T_TZ_H 0 11 ;-- 50 - T_TZ_HH 0 11 ;-- 51 - T_TZ_M 0 12 ;-- 52 - T_TZ_MM 0 12 ;-- 53 + T_TM_HM 0 6 ;-- 49 + T_TM_HMS 0 7 ;-- 50 + T_TM_NZ 0 8 ;-- 51 + T_TZ_H 0 11 ;-- 52 + T_TZ_HH 0 11 ;-- 53 + T_TZ_M 0 12 ;-- 54 + T_TZ_MM 0 12 ;-- 55 ] CSV-table: %../docs/lexer/lexer-FSM.csv From bebae5beac6e00749e3c20f707c172881062ef58 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 28 Oct 2019 21:17:55 +0100 Subject: [PATCH 0340/3432] FEAT: some performance improvements in lexical scanners. --- runtime/lexer.reds | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9b3b6d1db9..01d20dd1aa 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -745,7 +745,7 @@ lexer: context [ pos: p w?: no while [all [not w? p < e p/1 <> #")"]][ - index: 1 + as-integer p/1 + index: as-integer p/1 class: lex-classes/index switch class [ C_DIGIT C_ZERO C_ALPHAX C_EXP [0] @@ -1105,18 +1105,17 @@ lexer: context [ state: S_DT_START loop as-integer e - s [ ;probe ["--- " s/1 " ---"] - cp: 1 + as-integer s/1 + cp: as-integer s/1 class: as-integer date-classes/cp ;?? class - index: state * (size? date-char-classes!) + class + 1 + index: state * (size? date-char-classes!) + class state: as-integer date-transitions/index - index: state + 1 - pos: as-integer fields-table/index + pos: as-integer fields-table/state field/pos: c ;?? state ;?? cp - c: either null-byte = reset-table/index [ + c: either null-byte = reset-table/state [ c * 10 + as-integer date-cumul/cp ][0] ;?? c @@ -1124,11 +1123,10 @@ lexer: context [ ;?? c ] - index: state * (size? date-char-classes!) + C_DT_EOF + 1 + index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index ;?? state - index: state + 1 - pos: as-integer fields-table/index + pos: as-integer fields-table/state ;?? pos field/pos: c @@ -1188,7 +1186,7 @@ comment { p: s until [ p: p + 1 ;-- x separator cannot be at start - index: 1 + as-integer p/1 + index: as-integer p/1 class: lex-classes/index class = C_X ] @@ -1272,7 +1270,7 @@ comment { close? [logic!] ][ close?: either e >= state/in-end [yes][ ;-- EOF reached - cp: 1 + as-integer e/1 + cp: as-integer e/1 index: lex-classes/cp and FFh + 1 ;-- query the class of ending character as-logic path-ending/index ;-- lookup if the character class is ending path ] @@ -1347,25 +1345,22 @@ comment { offset: 0 loop as-integer lex/in-end - p [ - cp: 1 + as-integer p/value + cp: as-integer p/value class: lex-classes/cp flags: class and FFFFFF00h or flags class: class and FFh - index: state * (size? character-classes!) + class + 1 + index: state * (size? character-classes!) + class state: as-integer transitions/index - index: state + 1 - offset: offset + as-integer skip-table/index - - index: class + 1 - line: line + line-table/index + offset: offset + as-integer skip-table/state + line: line + line-table/class if state > --EXIT_STATES-- [term?: yes break] p: p + 1 ] unless term? [ - index: state * (size? character-classes!) + C_EOF + 1 + index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index ] lex/in-pos: p @@ -1418,6 +1413,18 @@ comment { init: func [][ stash: as cell! allocate stash-size * size? cell! + + ;-- switch following tables to zero-based indexing + lex-classes: lex-classes + 1 + transitions: transitions + 1 + skip-table: skip-table + 1 + line-table: line-table + 1 + + date-classes: date-classes + 1 + date-transitions: date-transitions + 1 + date-cumul: date-cumul + 1 + fields-table: fields-table + 1 + reset-table: reset-table + 1 ] ] \ No newline at end of file From ffc5e7e85e337976586636884b215ca76b46dd4a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 28 Oct 2019 21:26:16 +0100 Subject: [PATCH 0341/3432] FEAT: minor performance improvement in lexical scanner. --- runtime/lexer.reds | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 01d20dd1aa..d495d30187 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1346,9 +1346,8 @@ comment { loop as-integer lex/in-end - p [ cp: as-integer p/value - class: lex-classes/cp - flags: class and FFFFFF00h or flags - class: class and FFh + flags: lex-classes/cp and FFFFFF00h or flags + class: lex-classes/cp and FFh index: state * (size? character-classes!) + class state: as-integer transitions/index From 8aef0b1271fc142854ae7f4cc274de1fcdb9d2be Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 28 Oct 2019 21:27:01 +0100 Subject: [PATCH 0342/3432] FIX: missing flags masking in string! pre-scanning. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d495d30187..61d48c724c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -746,7 +746,7 @@ lexer: context [ w?: no while [all [not w? p < e p/1 <> #")"]][ index: as-integer p/1 - class: lex-classes/index + class: lex-classes/index and FFh ;-- mask the flags switch class [ C_DIGIT C_ZERO C_ALPHAX C_EXP [0] default [w?: yes] ;-- early exit if not an hex value From e5284358a090391366fd7a4c90743966cf0093c0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 28 Oct 2019 21:35:06 +0100 Subject: [PATCH 0343/3432] FIX: line counting not always correct in lexical scanner. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 61d48c724c..cd3e968776 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1353,7 +1353,7 @@ comment { state: as-integer transitions/index offset: offset + as-integer skip-table/state - line: line + line-table/class + line: line + as-integer line-table/class if state > --EXIT_STATES-- [term?: yes break] p: p + 1 From c6d1b28d2cbee2a656eaf8782c38645d475e3504 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 29 Oct 2019 17:31:06 +0100 Subject: [PATCH 0344/3432] FEAT: adds support for scanning time! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 24963 -> 24945 bytes runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 86 ++++++++++++++++++++------------- utils/generate-lexer-table.red | 4 +- 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index d627435635..0c7bc58add 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -25,7 +25,7 @@ S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 17df29cd9f5d964185df0e9f8390a3a0bb7daed4..33efd79f0824f7087afb4db29be41d7c4af40034 100644 GIT binary patch delta 11134 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%0DJ4M##3cz0}jwbQb$`xT>@wiWU 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 EA6)baSO5S3 delta 11057 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 D3r*6o diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a51331a2c6..73661cb11d 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -189,7 +189,7 @@ Red/System [ 3243323232323217323232323232324344441818444444444444441818181818 18181844184418444418441818441818324432321A1A32323232323232323232 323232323232323232323232323232323232323246461A1A4646464646464632 -321A32323246324632323246321A323232323232323132321C1C323232323232 +321A32323246324632323246321A323232323232324632321C1C323232323232 32323232323232323232323232323232323232323232323245451C1C45454545 454545323245321C3245324532323245321C323232323232324532321E1E3232 3232323232323232323232323232323232323232323232323232323247471E1E diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cd3e968776..833380e030 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -31,6 +31,7 @@ lexer: context [ C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h C_FLAG_SIGN: 00200000h + C_FLAG_TM_ONLY: 00000400h ;-- only scan a time! value C_FLAG_ESC_HEX: 00000200h ;-- percent-escaped mode C_FLAG_NOSTORE: 00000100h ;-- do not store decoded value ] @@ -1089,6 +1090,7 @@ lexer: context [ ] scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + return: [int-ptr!] /local field [int-ptr!] state [integer!] @@ -1098,11 +1100,13 @@ lexer: context [ c [integer!] pos [integer!] month [integer!] + time? [logic!] ][ -;probe "scan-date" + time?: flags and C_FLAG_TM_ONLY <> 0 field: system/stack/allocate/zero 12 c: 0 - state: S_DT_START + state: either time? [S_TM_START][S_DT_START] + loop as-integer e - s [ ;probe ["--- " s/1 " ---"] cp: as-integer s/1 @@ -1120,36 +1124,46 @@ lexer: context [ ][0] ;?? c s: s + 1 -;?? c ] - index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index ;?? state pos: as-integer fields-table/state ;?? pos field/pos: c + ;; TBD: add error state processing - month: field/3 - if any [month > 12 month < 1][ ;-- month as a word - month: switch month [ ;-- convert hashed word to correct value - 8128 81372323 [1] - 7756 776512323 [2] - 8432 843942 [3] - 7382 739006 [4] - 8353 [5] ;-- "May" has no longer form - 8328 83349 [6] - 8326 83263 [7] - 7421 7430330 [8] - 9070 480839780 [9] - 8570 85786372 [10] - 8676 868374372 [11] - 7557 756474372 [12] - default [throw LEX_ERROR 0] + unless time? [ + month: field/3 + if any [month > 12 month < 1][ ;-- month as a word + month: switch month [ ;-- convert hashed word to correct value + 8128 81372323 [1] + 7756 776512323 [2] + 8432 843942 [3] + 7382 739006 [4] + 8353 [5] ;-- "May" has no longer form + 8328 83349 [6] + 8326 83263 [7] + 7421 7430330 [8] + 9070 480839780 [9] + 8570 85786372 [10] + 8676 868374372 [11] + 7557 756474372 [12] + default [throw LEX_ERROR 0] + ] + field/3: month ] - field/3: month + date/set-all + as red-date! alloc-slot lex + field/2 ;-- year + field/3 ;-- month + field/4 ;-- day + field/5 ;-- hour + field/6 ;-- min + field/7 ;-- sec + field/8 ;-- nano ] -comment { +;comment { probe [ "-----------------" "^/trash: " field/1 @@ -1165,16 +1179,9 @@ comment { "^/TZ-h : " field/11 "^/TZ-m : " field/12 ] -} - date/set-all - as red-date! alloc-slot lex - field/2 ;-- year - field/3 ;-- month - field/4 ;-- day - field/5 ;-- hour - field/6 ;-- min - field/7 ;-- sec - field/8 ;-- nano +;} + lex/in-pos: e ;-- reset the input position to delimiter byte + field ;-- return field pointer for scan-time ] scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1199,9 +1206,20 @@ comment { ] scan-time: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local + /local + field [int-ptr!] + tm [float!] ][ - null + field: scan-date state s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame + + if any [field/11 <> 0 field/12 <> 0][throw LEX_ERROR] ;-- TZ info rejection + + tm: (3600.0 * as float! field/5) + + (60.0 * as float! field/6) + + ( as float! field/7) + + (1e-9 * as float! field/8) + + time/make-at tm alloc-slot state ;-- field array is not usable after this call ] scan-money: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index fc44c9c59f..c18c1c7212 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -170,7 +170,7 @@ context [ ;-- Determine CSV separator sep: [#";" 0 #"," 0] parse csv [some [#";" (sep/2: sep/2 + 1) | #"," (sep/4: sep/4 + 1) | skip]] - sort/skip/all/compare sep 2 func [a b][a/2 < b/2] + sort/skip/all/compare sep 2 func [a b][a/2 > b/2] ;-- Decode CSV matrix: load-csv/with read CSV-table first sep @@ -197,7 +197,7 @@ context [ ;-- Determine CSV separator sep: [#";" 0 #"," 0] parse csv [some [#";" (sep/2: sep/2 + 1) | #"," (sep/4: sep/4 + 1) | skip]] - sort/skip/all/compare sep 2 func [a b][a/2 < b/2] + sort/skip/all/compare sep 2 func [a b][a/2 > b/2] ;-- Decode CSV matrix: load-csv/with read date-table first sep From 5d75a509f04082211a449ba3de09d56cb62c906e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 29 Oct 2019 21:39:53 +0100 Subject: [PATCH 0345/3432] FIX: [R/S] avoids generating double code for loading logic! values. Typical case: if state > --EXIT_STATES-- [term?: yes break] for `term?: yes` expression, it was generating both `emit-load true` and `emit-store ... true`. --- system/compiler.r | 1 + 1 file changed, 1 insertion(+) diff --git a/system/compiler.r b/system/compiler.r index 8eade0b543..fed71da25d 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -3439,6 +3439,7 @@ system-dialect: make-profilable context [ all [new? literal? unbox expr] ;-- if new variable, value will be store in data segment all [set-path? variable not path? expr] ;-- value loaded at lower level tag? unbox expr + all [not new? not boxed set-word? variable store? logic? expr] ][ either boxed [ emitter/target/emit-load/with expr boxed ;-- emit code for single value From 23c14fd193b6385c5d0307b6ba9752e99e68a27d Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 30 Oct 2019 08:49:35 +0800 Subject: [PATCH 0346/3432] FIX: none font crash the app --- modules/view/backends/gtk3/text-box.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 1f44d73e27..322b7e9196 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -346,6 +346,7 @@ OS-text-box-layout: func [ state [red-block!] size [red-pair!] font [red-object!] + color [red-tuple!] cached? [logic!] attrs [handle!] int [red-integer!] @@ -363,7 +364,7 @@ OS-text-box-layout: func [ state: as red-block! values + FACE_OBJ_EXT3 size: as red-pair! values + FACE_OBJ_SIZE font: as red-object! values + FACE_OBJ_FONT - attrs: create-pango-attrs box font + color: as red-tuple! values + FACE_OBJ_COLOR cached?: TYPE_OF(state) = TYPE_BLOCK either cached? [ @@ -385,7 +386,11 @@ OS-text-box-layout: func [ none/make-in state logic/make-in state false ] - + attrs: either TYPE_OF(font) = TYPE_BLOCK [ + create-pango-attrs box font + ][ + create-simple-attrs default-font-name default-font-size color + ] len: -1 str: unicode/to-utf8 text :len pango_layout_set_width layout PANGO_SCALE * size/x From 92e606a6a985186efa837d4c807b22ebf79a7266 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 30 Oct 2019 14:24:53 +0100 Subject: [PATCH 0347/3432] FEAT: adds specific date! constructor for the lexer. --- runtime/datatypes/date.reds | 61 +++++++++++++++++++++++++++++++++++++ runtime/lexer.reds | 5 +-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 3d490a1e14..dfcea045f6 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -480,6 +480,67 @@ date: context [ dt/time: to-utc-time t v ] ] + + make-at: func [ + slot [red-value!] + year [integer!] + month [integer!] + day [integer!] + hour [integer!] + min [integer!] + sec [integer!] + nsec [integer!] + tz-h [integer!] + tz-m [integer!] + time? [logic!] + return: [red-date!] + /local + dt [red-date!] + t [float!] + d [integer!] + h [integer!] + i [integer!] + zone[integer!] + neg?[logic!] + ][ + if all [day >= 100 day > year][i: year year: day day: i] ;-- allow year to be first + + set-type slot TYPE_DATE ;-- preserve eventual flags in the header + dt: as red-date! slot + dt/date: DATE_SET_YEAR(0 year) + set-month dt month + dt/date: days-to-date day + date-to-days dt/date 0 time? + + t: (3600.0 * as float! hour) + + (60.0 * as float! min) + + ( as float! sec) + + (1e-9 * as float! nsec) + + set-time dt t no + + d: dt/date + h: time/get-hours t + if any [ + year <> DATE_GET_YEAR(d) + month <> DATE_GET_MONTH(d) + day <> DATE_GET_DAY(d) + all [t <> 0.0 any [ + h < 0 h > 23 + min <> time/get-minutes dt/time + ]] + all [t = 0.0 any [ + hour <> time/get-hours dt/time + min <> time/get-minutes dt/time + ]] + ][return null] + + neg?: either tz-h < 0 [tz-h: 0 - tz-h yes][no] + zone: tz-h << 2 and 7Fh or tz-m + if neg? [zone: DATE_SET_ZONE_NEG(zone)] + dt/date: DATE_SET_ZONE(dt/date zone) + set-time dt dt/time yes + dt + ] set-all: func [ dt [red-date!] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 833380e030..5a9c08fabc 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1102,6 +1102,7 @@ lexer: context [ month [integer!] time? [logic!] ][ +probe "scan-date" time?: flags and C_FLAG_TM_ONLY <> 0 field: system/stack/allocate/zero 12 c: 0 @@ -1163,7 +1164,7 @@ lexer: context [ field/7 ;-- sec field/8 ;-- nano ] -;comment { +comment { probe [ "-----------------" "^/trash: " field/1 @@ -1179,7 +1180,7 @@ lexer: context [ "^/TZ-h : " field/11 "^/TZ-m : " field/12 ] -;} +} lex/in-pos: e ;-- reset the input position to delimiter byte field ;-- return field pointer for scan-time ] From 31c20044b5d6e02724c5cf040c6bea3847e199de Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 30 Oct 2019 21:38:57 +0100 Subject: [PATCH 0348/3432] FEAT: adds C_T character class and fixes multiple issues in date! scanning. --- docs/lexer/date-FSM.csv | 28 +++--- docs/lexer/lexer-FSM.csv | 98 ++++++++++----------- docs/lexer/lexer-FSM.xlsx | Bin 24945 -> 25476 bytes docs/lexer/lexer-states.txt | 26 +++--- runtime/datatypes/date.reds | 8 +- runtime/lexer-transitions.reds | 154 +++++++++++++++++---------------- runtime/lexer.reds | 120 ++++++++++++++----------- utils/generate-lexer-table.red | 99 +++++++++++---------- utils/generate-misc-tables.red | 26 +++--- 9 files changed, 298 insertions(+), 261 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index c2042507f5..38c251aca4 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -5,12 +5,14 @@ S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YYY;F_DT_YEARL;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL;S_DT_YM;S_DT_YMON;F_DT_YEARL;F_DT_YEARL2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YEARL2;S_DT_YM;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YEARL2;S_DT_YM2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DAYL;S_DT_DM;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YM;S_DT_YMM;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YMM;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YMM;F_DT_YMONTH;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YM2;S_DT_YMM2;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YMM2;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YDDD S_DT_YV;S_DT_YW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK S_DT_YWW;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR @@ -28,18 +30,20 @@ F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR; F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_START2;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM -F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM +F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM +F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS -F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;F_TM_N1;T_DT_ERROR;T_DT_ERROR;T_TM_HMS +F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS +F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;F_TM_N1;T_TM_HMS;T_DT_ERROR;T_TM_HMS F_TM_N1;F_TM_N;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;S_TZ_START;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ -S_TZ_START;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TM_HMSNZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSNZ;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ +S_TM_HMZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TM_HMSZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_TM_HMSNZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TZ_H;F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_H -F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH -F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_TZ_HH;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH +F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM S_TZ_M;T_TZ_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 0c7bc58add..43c70abde1 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,49 +1,49 @@ -;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF -S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR -S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR -S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE -S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR -S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR -S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR -S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR -S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF -S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE -S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR -S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL -S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD -S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 33efd79f0824f7087afb4db29be41d7c4af40034..8be73a31ba26f032b92015317d344e69004558db 100644 GIT binary patch delta 13552 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 delta 12919 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"'"->S_NUMBER \ \->delimit11->T_FLOAT \ \->else->T_ERROR \ - \->"/"->S_DATE->not(delimit13)->S_DATE + \->"/"|"T"->S_DATE->not(delimit13)->S_DATE \ \->delimit13->T_DATE \ \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME @@ -406,17 +407,18 @@ S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->S_DT_YYYY->"/ \->sep->F_DT_DAYL F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH - \ \ \->digit->F_DT_DDD - \ \->sep->F_DT_YMONTH - \->letter->S_DT_YMON->letter->S_DT_YMON - \->sep->F_DT_YMONTH - -F_DT_YEARL2->digit->S_DT_YM - \->letter->S_DT_YMON - \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->T_DT_WEEK - \->digit->S_DT_WD->eof->T_DT_YWWD - \ \->"T"->S_TM_START - \->"T"->S_TM_START + \ \->sep->F_DT_YMONTH + \->letter->S_DT_YMON->letter->S_DT_YMON + \->sep->F_DT_YMONTH + +F_DT_YEARL2->digit->S_DT_YM2->digit->S_DT_YMM2->sep->F_DT_YMONTH + \ \ \->digit->F_DT_DDD + \ \->sep->F_DT_YMONTH + \->letter->S_DT_YMON + \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->T_DT_WEEK + \->digit->S_DT_WD->eof->T_DT_YWWD + \ \->"T"->S_TM_START + \->"T"->S_TM_START F_DT_DDD->"T"->S_TM_START diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index dfcea045f6..44c466265b 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -503,9 +503,11 @@ date: context [ zone[integer!] neg?[logic!] ][ - if all [day >= 100 day > year][i: year year: day day: i] ;-- allow year to be first - - set-type slot TYPE_DATE ;-- preserve eventual flags in the header + if year < 100 [ ;-- expand short yy forms + d: either year < 50 [2000][1900] + year: year + d + ] + set-type slot TYPE_DATE ;-- preserve eventual flags in the header dt: as red-date! slot dt/date: DATE_SET_YEAR(0 year) set-month dt month diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 73661cb11d..81987dc123 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -89,6 +89,8 @@ Red/System [ F_DT_DAYL S_DT_YM S_DT_YMM + S_DT_YM2 + S_DT_YMM2 F_DT_YMONTH F_DT_DDD S_DT_YV @@ -118,7 +120,9 @@ Red/System [ F_TM_SS F_TM_N1 F_TM_N - S_TZ_START + S_TM_HMZ + S_TM_HMSZ + S_TM_HMSNZ S_TZ_H F_TZ_HH F_TZ_HM @@ -126,6 +130,7 @@ Red/System [ T_DT_ERROR T_DT_YMDAY T_DT_DMYEAR + T_DT_YDDD T_DT_YWWD T_DT_WEEK T_TM_HM @@ -137,79 +142,82 @@ Red/System [ T_TZ_MM ] fields-table: #{ -0104040202020204030303040909090A03040403030303020202020402050505 -06060607070808040B0B0C0C0104020A090607080B0B0C0C +01040402020202040303030303040909090A0304040303030302020202040205 +0505060606070708080607080B0B0B0C010402040A090607080B0B0C0C } reset-table: #{ -00000000001F1F1F00001F000000000000000000001F00000000001F1F00001F -00001F00001F001F00001F001F1F1F1F1F1F1F1F1F1F1F1F +0101010101000000010101010001010101010101010101000101010101000001 +0100010100010100010000000101000100000000000000000000000000 } date-transitions: #{ -012C2C2C2C2C2C2C2C2C2C2C022C07072C2C2C2C2C2C2C2C032C07072C2C2C2C -2C2C2C2C042C05052C2C2C2C2C2C2C2C052C05052C2C2C2C2C2C2C2C08100506 -102C2C2C2C2C2C2C08102C2C100C2C2C2C2C2C2C13162C2C2C2C2C2C2C2C2C2C -092C0A0A2C2C2C2C2C2C2C2C0B2C0A0A2C2C2C2C2C2C2C2C112C2C2C2C2C2C2C -2C2C2C2C2C2C2C2C1B2C2C2C2C2C2C2C0D2C2C2C2C2C2C2C2C2C2C2C0E2C2C2C -2C2C2C2C2C2C2C300F2C2C2C1B2C2C2C2C2C2C2C2C2C2C2C1B2C2C2C2C2C2C2F -2C100A0A102C2C2C2C2C2C2C122C1B2C1B2C2C2C2C2C2C2D2C2C1B2C1B2C2C2C -2C2C2C2D142C15152C2C2C2C2C2C2C2C2C2C15152C2C2C2C2C2C2C2C172C2C2C -2C2C2C2C2C2C2C2C2C161515162C2C2C2C2C2C2C182C1C2C1C2C2C2C2C2C2C2E -192C1C2C1C2C2C2C2C2C2C2E1A2C1C2C1C2C2C2C2C2C2C2E2C2C1C2C1C2C2C2C -2C2C2C2E1D2C2C2C2C2C2C2C2C2C2C2C1D2C2C2C2C2C2C2C2C2C2C2C1E2C2C2C -2C2C2C2C2C2C2C2C202C2C2C2C2C2C1F2C2C2C2C202C2C2C2C2C2C2C2C2C2C2C -212C2C2C2C2C2C2C2C2C2C31232C2C2C2C2C2C222C2C2C31232C2C2C2C2C2C2C -2C2C2C2C242C2C2C2C2C2C2C2C2C2C322C2C2C272C2C272C252C2C32262C2C2C -2C2C2C2C2C2C2C2C262C2C272C2C272C2C332C33282C2C2C2C2C2C2C2C2C2C2C -292C2C2C2C2C2C2A2C2C2C342C2C2C2C2C2C2C2A2C2C2C352B2C2C2C2C2C2C2C -2C2C2C2C372C2C2C2C2C2C2C2C2C2C37 +0130303030303030303030300230070730303030303030300330070730303030 +3030303004300505303030303030303005300505303030303030303008120506 +12303030303030300A123030120E303030303030151830303030303030303030 +09300C0C30303030303030300C300C0C30303030303030300B300C0C30303030 +303030300D300C0C303030303030303013303030303030303030303030303030 +1D303030303030330F3030303030303030303030103030303030303030303035 +113030301D30303030303030303030301D3030303030303430120C0C12303030 +3030303014301D301D3030303030303130301D301D3030303030303116301717 +3030303030303030303017173030303030303030193030303030303030303030 +3018171718303030303030301A301E301E303030303030321B301E301E303030 +303030321C301E301E3030303030303230301E301E303030303030321F303030 +30303030303030301F3030303030303030303030203030303030302130303030 +2230303030303021303030302230303030303030303030302330302930302924 +303030362530302930302924303030362530303030303030303030302630302A +30302A30303030373030302A30302A3027373037283030303030303030303030 +2830302B30302B30303830382C30303030303030303030302C30303030303030 +303030302C30303030303030303030302D3030303030302E303030392E303030 +3030302E3030303A2F303030303030303030303C3C303030303030303030303C } transitions: #{ -00001313333435360432020C27272727270B32202706320132271D2626322727 -3231010001010101010101010101010101010101010101010101010101010101 -0101323102020202020202020202370202020202020202020202020202020202 -0203020232320202020202020202020202020202020202020202020202020202 -0202020202023231040404040404040404370404040404040404040404040404 -0404040404050404323204040404040404040404040404040404040404040404 -040404040404040404043231383807073838383838380A070738070707070707 -0707073838070707070707073238393907073939393939393207073907070707 -0707070807393907070707070707323907070909323232323232323232323232 -0932323232323232323232323232323232320707070732323232323232323232 -32320732323232323232323232323232323232390A0A0A0A0A0A0A0A0A0A390A -0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32323A3A0B0B3A3A3A3A3A3A -3A0B0B0B0B0B0B0B0B0B0B0B0B3A3A0B0B0B0B0B0B0B323A3F3F121211323D32 -0D320F1212321212121212323212323F3F12121212121212323F0D0D0D0D3232 -3232323B323232320D0D0D3232323232320E323232323232320D32320E0D0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E32310F0F -0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F0F323C -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -323211111111113E111111111111111111111111111111111111111111111111 -111132323F3F12123F3F3F3F3F3F3F1212121212121212121212123F3F121212 -12121212323F41411313414141414141410C13191B1532183241324032412A14 -323218323232324142421515424242424242421615321B153242324232403242 -3232323232323232324242421515424242424242421B32423215324232423240 -3232321732323232323232424242424242424242424242164242161616424242 -1642424242164216164216163231434317174343434343434332324332323243 -3243323232323217323232323232324344441818444444444444441818181818 -18181844184418444418441818441818324432321A1A32323232323232323232 -323232323232323232323232323232323232323246461A1A4646464646464632 -321A32323246324632323246321A323232323232324632321C1C323232323232 -32323232323232323232323232323232323232323232323245451C1C45454545 -454545323245321C3245324532323245321C323232323232324532321E1E3232 -3232323232323232323232323232323232323232323232323232323247471E1E -47474747474747471E4732323247324732323247321F32323232323232314747 -1F1F47474747474747471F473232324732473232324732323232323232323231 -3838212138383838383838212138212121212132382121383821212121212121 -3238212121212121212121212221212421212121212148212121212121212121 -2121323222222222222222222222212222222222222222222222222222222222 -2223222232322222222222222222222222222222222222222222222222222222 -2222222222223232242424242424242424242424242124242424242424242424 -2424242424242424323224242424242424242424242424242424242424242424 -2424242424242424242432323838131338383838383838323227272727273832 -273227382727272727322727323838382727383838383838383227282727274B -3827273232382A271E2727272727323838382929383838383838382929292929 -2929383229292938292929292929292932384949292949494949494949293229 -29292929494932294949292932292932292932494A4A2A2A4A4A4A4A4A4A4A32 -32322A2A2A4A4A4A322A324A322A322A2A322A2A324A32322C2C323235363232 -022E2D2D2D2D2D3232202D3232322A2D322F2F322D2D323241412C2C41414141 -4141413213411B1532413241324032412A14323232323232324138382D2D3838 -3838383838322D382D2D2D38382D2D3232382A2D322D2D2D2D2D32383F3F1212 -1132323232320F1212321212121212323212323F3F12121212121212323F3838 -2C2C383838383838383232272727272738322732273827272727273227273238 +00001313333435360432020C2727272727270B32202706320132271D26263227 +2732310100010101010101010101010101010101010101010101010101010101 +0101010132310202020202020202020237020202020202020202020202020202 +0202020203020232320202020202020202020202020202020202020202020202 +0202020202020202020232310404040404040404043704040404040404040404 +0404040404040404040405040432320404040404040404040404040404040404 +040404040404040404040404040404043231383807073838383838380A070738 +0707070707070707070738380707070707070732383939070739393939393932 +0707390707070707070707080739390707070707070732390707090932323232 +3232323232323232320932323232323232323232323232323232320707070732 +3232323232323232323232320732323232323232323232323232323232390A0A +0A0A0A0A0A0A0A0A390A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32 +323A3A0B0B3A3A3A3A3A3A3A0B0B0B0B0B0B0B0B0B0B0B0B0B3A3A0B0B0B0B0B +0B0B323A3F3F121211323D320D320F121232121212121212323212323F3F1212 +1212121212323F0D0D0D0D32323232323B323232320D0D0D0D3232323232320E +323232323232320D32320E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F323C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111113E11111111111111 +111111111111111111111111111111111111111132323F3F12123F3F3F3F3F3F +3F121212121212121212121212123F3F12121212121212323F41411313414141 +414141410C13191B181532183241324032412A14323218323232324142421515 +424242424242421615321B321532423242324032423232323232323232324242 +421515424242424242421B324232321532423242324032323217323232323232 +3242424242424242424242424216424216161616424242164242424216421616 +4216163231434317174343434343434332324332323232433243323232323217 +3232323232323243444418184444444444444418181818181818181844184418 +444418441818441818324432321A1A3232323232323232323232323232323232 +323232323232323232323232323246461A1A4646464646464632321A32323232 +46324632323246321A323232323232324632321C1C3232323232323232323232 +323232323232323232323232323232323232323245451C1C4545454545454532 +324532321C3245324532323245321C323232323232324532321E1E3232323232 +323232323232323232323232323232323232323232323232323247471E1E4747 +4747474747471E473232323247324732323247321F323232323232323147471F +1F47474747474747471F47323232324732473232324732323232323232323231 +3838212138383838383838212138212121212121323821213838212121212121 +2132382121212121212121212122212124212121212121214821212121212121 +2121212132322222222222222222222221222222222222222222222222222222 +2222222223222232322222222222222222222222222222222222222222222222 +2222222222222222222232322424242424242424242424242421242424242424 +2424242424242424242424242432322424242424242424242424242424242424 +2424242424242424242424242424242432323838131338383838383838323227 +2727272727383227322738272727272732272732383838272738383838383838 +322728272727274B3827273232382A271E272727272732383838292938383838 +3838382929292929292929383229292938292929292929292932384949292949 +4949494949492932292929292929494932294949292932292932292932494A4A +2A2A4A4A4A4A4A4A4A3232322A2A2A2A4A4A4A322A324A322A322A2A322A2A32 +4A32322C2C323235363232022E2D2D2D2D2D2D3232202D3232322A2D322F2F32 +2D2D323241412C2C414141414141413213411B321532413241324032412A1432 +3232323232324138382D2D38383838383838322D382D2D2D2D38382D2D323238 +2A2D322D2D2D2D2D32383F3F12121132323232320F1212321212121212123232 +12323F3F12121212121212323F38382C2C383838383838383232272727272727 +38322732273827272727273227273238 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5a9c08fabc..341de4ea7e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -55,25 +55,26 @@ lexer: context [ C_QUOTE ;-- 12 C_COLON ;-- 13 C_X ;-- 14 - C_EXP ;-- 15 - C_ALPHAX ;-- 16 - C_SLASH ;-- 17 - C_BSLASH ;-- 18 - C_LESSER ;-- 19 - C_GREATER ;-- 20 - C_PERCENT ;-- 21 - C_COMMA ;-- 22 - C_SEMICOL ;-- 23 - C_AT ;-- 24 - C_DOT ;-- 25 - C_MONEY ;-- 26 - C_PLUS ;-- 27 - C_MINUS ;-- 28 - C_CARET ;-- 29 - C_BIN ;-- 30 - C_WORD ;-- 31 - C_ILLEGAL ;-- 32 - C_EOF ;-- 33 + C_T ;-- 15 + C_EXP ;-- 16 + C_ALPHAX ;-- 17 + C_SLASH ;-- 18 + C_BSLASH ;-- 19 + C_LESSER ;-- 20 + C_GREATER ;-- 21 + C_PERCENT ;-- 22 + C_COMMA ;-- 23 + C_SEMICOL ;-- 24 + C_AT ;-- 25 + C_DOT ;-- 26 + C_MONEY ;-- 27 + C_PLUS ;-- 28 + C_MINUS ;-- 29 + C_CARET ;-- 30 + C_BIN ;-- 31 + C_WORD ;-- 32 + C_ILLEGAL ;-- 33 + C_EOF ;-- 34 ] #enum date-char-classes! [ @@ -239,7 +240,9 @@ lexer: context [ C_ALPHAX ;-- 46 F C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R - C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 53-57 S-W + C_WORD ;-- 53 S + C_T ;-- 54 T + C_WORD C_WORD C_WORD ;-- 55-57 U-W C_X ;-- 58 X C_WORD C_WORD ;-- 59-5A Y-Z C_BLOCK_OP ;-- 5B [ @@ -1092,6 +1095,7 @@ lexer: context [ scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] return: [int-ptr!] /local + dt [red-date!] field [int-ptr!] state [integer!] class [integer!] @@ -1102,7 +1106,9 @@ lexer: context [ month [integer!] time? [logic!] ][ -probe "scan-date" +;probe "scan-date" +;probe as-c-string s +;probe as-c-string e time?: flags and C_FLAG_TM_ONLY <> 0 field: system/stack/allocate/zero 12 c: 0 @@ -1115,25 +1121,46 @@ probe "scan-date" ;?? class index: state * (size? date-char-classes!) + class state: as-integer date-transitions/index - + pos: as-integer fields-table/state field/pos: c +;probe ["field: " c] +;?? pos ;?? state ;?? cp - c: either null-byte = reset-table/state [ - c * 10 + as-integer date-cumul/cp - ][0] + if null-byte = reset-table/state [c: 0] + c: c * 10 + as-integer date-cumul/cp ;?? c s: s + 1 ] - index: state * (size? date-char-classes!) + C_DT_EOF - state: as-integer date-transitions/index + if state <= T_DT_ERROR [ + if state = T_DT_ERROR [throw LEX_ERROR] ;-- check here for performance reason + + index: state * (size? date-char-classes!) + C_DT_EOF + state: as-integer date-transitions/index ;?? state - pos: as-integer fields-table/state + pos: as-integer fields-table/state ;?? pos - field/pos: c - ;; TBD: add error state processing - + field/pos: c + ] + +comment { + probe [ + "-----------------" + "^/trash: " field/1 + "^/year : " field/2 + "^/month: " field/3 + "^/day : " field/4 + "^/hour : " field/5 + "^/min : " field/6 + "^/sec : " field/7 + "^/nano : " field/8 + "^/week : " field/9 + "^/wday : " field/10 + "^/TZ-h : " field/11 + "^/TZ-m : " field/12 + ] +} unless time? [ month: field/3 if any [month > 12 month < 1][ ;-- month as a word @@ -1152,10 +1179,10 @@ probe "scan-date" 7557 756474372 [12] default [throw LEX_ERROR 0] ] - field/3: month - ] - date/set-all - as red-date! alloc-slot lex + field/3: month ;;TBD: add accurate spelling check + ] + dt: date/make-at + alloc-slot lex field/2 ;-- year field/3 ;-- month field/4 ;-- day @@ -1163,24 +1190,13 @@ probe "scan-date" field/6 ;-- min field/7 ;-- sec field/8 ;-- nano + field/11 ;-- TZ hour + field/12 ;-- TZ min + state >= T_TM_HM ;-- time was provided + + if null? dt [throw LEX_ERROR] ] -comment { - probe [ - "-----------------" - "^/trash: " field/1 - "^/year : " field/2 - "^/month: " field/3 - "^/day : " field/4 - "^/hour : " field/5 - "^/min : " field/6 - "^/sec : " field/7 - "^/nano : " field/8 - "^/week : " field/9 - "^/wday : " field/10 - "^/TZ-h : " field/11 - "^/TZ-m : " field/12 - ] -} + lex/in-pos: e ;-- reset the input position to delimiter byte field ;-- return field pointer for scan-time ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index c18c1c7212..0403527b17 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -114,52 +114,57 @@ context [ F_DT_DAYL 0 4 ;-- 7 S_DT_YM 1 3 ;-- 8 S_DT_YMM 1 3 ;-- 9 - F_DT_YMONTH 0 3 ;-- 10 - F_DT_DDD 1 4 ;-- 11 - S_DT_YV 1 9 ;-- 12 - S_DT_YW 1 9 ;-- 13 - S_DT_YWW 1 9 ;-- 14 - S_DT_WD 1 10 ;-- 15 - S_DT_YMON 1 3 ;-- 16 - F_DT_YMD 1 4 ;-- 17 - F_DT_YMDD 1 4 ;-- 18 - S_DT_DM 1 3 ;-- 19 - S_DT_DMM 1 3 ;-- 20 - F_DT_DMONTH 0 3 ;-- 21 - S_DT_DMON 1 3 ;-- 22 - F_DT_DMY 1 2 ;-- 23 - F_DT_DMYY 1 2 ;-- 24 - F_DT_DMYYY 1 2 ;-- 25 - F_DT_DMYYYY 1 2 ;-- 26 - S_TM_START 0 4 ;-- 27 - S_TM_START2 0 2 ;-- 28 - F_TM_H 1 5 ;-- 29 - F_TM_HH 1 5 ;-- 30 - S_TM_HM 0 5 ;-- 31 - F_TM_M 1 6 ;-- 32 - F_TM_MM 1 6 ;-- 33 - S_TM_HMS 0 6 ;-- 34 - F_TM_S 1 7 ;-- 35 - F_TM_SS 1 7 ;-- 36 - F_TM_N1 0 8 ;-- 37 - F_TM_N 1 8 ;-- 38 - S_TZ_START 0 4 ;-- 39 - S_TZ_H 1 11 ;-- 40 - F_TZ_HH 1 11 ;-- 41 - F_TZ_HM 0 12 ;-- 42 - S_TZ_M 1 12 ;-- 43 - T_DT_ERROR 0 1 ;-- 44 - T_DT_YMDAY 0 4 ;-- 45 - T_DT_DMYEAR 0 2 ;-- 46 - T_DT_YWWD 0 10 ;-- 47 - T_DT_WEEK 0 9 ;-- 48 - T_TM_HM 0 6 ;-- 49 - T_TM_HMS 0 7 ;-- 50 - T_TM_NZ 0 8 ;-- 51 - T_TZ_H 0 11 ;-- 52 - T_TZ_HH 0 11 ;-- 53 - T_TZ_M 0 12 ;-- 54 - T_TZ_MM 0 12 ;-- 55 + S_DT_YM2 1 3 ;-- 10 + S_DT_YMM2 1 3 ;-- 11 + F_DT_YMONTH 0 3 ;-- 12 + F_DT_DDD 1 4 ;-- 13 + S_DT_YV 1 9 ;-- 14 + S_DT_YW 1 9 ;-- 15 + S_DT_YWW 1 9 ;-- 16 + S_DT_WD 1 10 ;-- 17 + S_DT_YMON 1 3 ;-- 18 + F_DT_YMD 1 4 ;-- 19 + F_DT_YMDD 1 4 ;-- 20 + S_DT_DM 1 3 ;-- 21 + S_DT_DMM 1 3 ;-- 22 + F_DT_DMONTH 0 3 ;-- 23 + S_DT_DMON 1 3 ;-- 24 + F_DT_DMY 1 2 ;-- 25 + F_DT_DMYY 1 2 ;-- 26 + F_DT_DMYYY 1 2 ;-- 27 + F_DT_DMYYYY 1 2 ;-- 28 + S_TM_START 0 4 ;-- 29 + S_TM_START2 0 2 ;-- 30 + F_TM_H 1 5 ;-- 31 + F_TM_HH 1 5 ;-- 32 + S_TM_HM 0 5 ;-- 33 + F_TM_M 1 6 ;-- 34 + F_TM_MM 1 6 ;-- 35 + S_TM_HMS 0 6 ;-- 36 + F_TM_S 1 7 ;-- 37 + F_TM_SS 1 7 ;-- 38 + F_TM_N1 0 8 ;-- 39 + F_TM_N 1 8 ;-- 40 + S_TM_HMZ 0 6 ;-- 41 + S_TM_HMSZ 0 7 ;-- 42 + S_TM_HMSNZ 0 8 ;-- 43 + S_TZ_H 1 11 ;-- 44 + F_TZ_HH 1 11 ;-- 45 + F_TZ_HM 0 11 ;-- 46 + S_TZ_M 1 12 ;-- 47 + T_DT_ERROR 0 1 ;-- 48 + T_DT_YMDAY 0 4 ;-- 49 + T_DT_DMYEAR 0 2 ;-- 50 + T_DT_YDDD 0 4 ;-- 51 + T_DT_YWWD 0 10 ;-- 52 + T_DT_WEEK 0 9 ;-- 53 + T_TM_HM 0 6 ;-- 54 + T_TM_HMS 0 7 ;-- 55 + T_TM_NZ 0 8 ;-- 56 + T_TZ_H 0 11 ;-- 57 + T_TZ_HH 0 11 ;-- 58 + T_TZ_M 0 12 ;-- 59 + T_TZ_MM 0 12 ;-- 60 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -208,7 +213,7 @@ context [ fields-table: make binary! 100 foreach [state reset pos] date-states [ - append reset-table to-char pick 0x31 reset = 1 + append reset-table to-char reset append fields-table to-char pos ] diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index 78fccfa522..75224607f6 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -68,19 +68,19 @@ gen-hexa-table: function [][ probe out ] -bin-classes: [ - C_DT_DIGIT ;-- 0 0-9 - C_DT_LETTER ;-- 1 abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY - C_DT_SLASH ;-- 2 / - C_DT_DASH ;-- 3 - - C_DT_T ;-- 4 T - C_DT_W ;-- 5 W - C_DT_PLUS ;-- 6 + - C_DT_COLON ;-- 7 : - C_DT_DOT ;-- 8 . - C_DT_Z ;-- 9 Z - C_DT_ILLEGAL ;-- 10 all the rest - C_DT_EOF ;-- 11 EOF +date-classes: [ + C_DT_DIGIT ;-- 0 0-9 + C_DT_LETTER ;-- 1 abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY + C_DT_SLASH ;-- 2 / + C_DT_DASH ;-- 3 - + C_DT_T ;-- 4 T + C_DT_W ;-- 5 W + C_DT_PLUS ;-- 6 + + C_DT_COLON ;-- 7 : + C_DT_DOT ;-- 8 . + C_DT_Z ;-- 9 Z + C_DT_ILLEGAL ;-- 10 all the rest + C_DT_EOF ;-- 11 EOF ] gen-date-table: function [][ From 760d288f4d263a36bbf94cd0d591cc33404a8f63 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 30 Oct 2019 18:07:17 +0800 Subject: [PATCH 0349/3432] FEAT: refactor gtk event loop --- modules/view/backends/gtk3/comdlgs.reds | 3 +- modules/view/backends/gtk3/events.reds | 103 +++++----- modules/view/backends/gtk3/gtk.reds | 143 +++++++------ modules/view/backends/gtk3/gui.reds | 244 +++++++++++++++-------- modules/view/backends/gtk3/handlers.reds | 48 +++-- 5 files changed, 324 insertions(+), 217 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 068a6e6a12..3dcbbb082c 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -47,7 +47,8 @@ _request-file: func [ null ] gobj_signal_connect(widget "file-activated" :request-file-double-clicked null) - unless null? main-window [gtk_window_set_transient_for widget main-window] + window: find-active-window + unless null? window [gtk_window_set_transient_for widget window] resp: gtk_dialog_run widget if resp = GTK_RESPONSE_ACCEPT [ cstr: gtk_file_chooser_get_filename widget diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 5a32db0769..4a8799ca5f 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -399,46 +399,53 @@ make-event: func [ ] do-events: func [ - no-wait? [logic!] - return: [logic!] + no-wait? [logic!] + return: [logic!] /local - msg? [logic!] - event [GdkEventAny!] - widget [handle!] - ; state [GdkModifierType!] - ; source [handle!] + msg? [logic!] + list [GList!] + win [handle!] + v [handle!] + c1 [integer!] + c2 [integer!] ][ - msg?: no - - set-view-no-wait gtk_application_get_active_window GTKApp no-wait? - - ;@@ Improve it!!! - ;@@ as we cannot access gapplication->priv->use_count - ;@@ we use a global value to simulate it - - ;; DEBUG: print ["do-events no-wait? " no-wait? lf] - - ;; Initially normally uncommented: the exit-loop is also decremented in destroy for supposed no-wait view! - unless no-wait? [ - exit-loop: exit-loop + 1 - ] + win: find-active-window + if null? win [return no] + v: as handle! 0 + SET-POST-QUIT(win v) - while [exit-loop > 0][ - if g_main_context_iteration GTKApp-Ctx not no-wait? [msg?: yes] - if no-wait? [break] - ] - - while [g_main_context_iteration GTKApp-Ctx false][ ;-- consume leftover event - msg?: yes - if no-wait? [break] + msg?: no + until [ + if gtk_events_pending [ + msg?: yes + c1: get-window-count + gtk_main_iteration_do not no-wait? + if check-quit-msg [ + break + ] + c2: get-window-count + if c2 < c1 [break] + ] + no-wait? ] - msg? ] +post-quit-msg: func [ + /local + win [handle!] + v [handle!] +][ + win: find-active-window + v: as handle! 1 + SET-POST-QUIT(win v) + gtk_widget_queue_draw win +] + + check-extra-keys: func [ - state [integer!] - return: [integer!] + state [integer!] + return: [integer!] /local key [integer!] ][ @@ -450,8 +457,8 @@ check-extra-keys: func [ ] check-extra-buttons: func [ - state [integer!] - return: [integer!] + state [integer!] + return: [integer!] /local buttons [integer!] ][ @@ -463,10 +470,10 @@ check-extra-buttons: func [ ] check-down-flags: func [ - state [integer!] - return: [integer!] + state [integer!] + return: [integer!] /local - flags [integer!] + flags [integer!] ][ flags: 0 if state and GDK_BUTTON1_MASK <> 0 [flags: flags or EVT_FLAG_DOWN] @@ -480,11 +487,11 @@ check-down-flags: func [ ] check-flags: func [ - type [integer!] - state [integer!] - return: [integer!] + type [integer!] + state [integer!] + return: [integer!] /local - flags [integer!] + flags [integer!] ][ flags: 0 ;;[flags: flags or EVT_FLAG_AX2_DOWN] @@ -502,10 +509,10 @@ check-flags: func [ ] translate-key: func [ - keycode [integer!] - return: [integer!] + keycode [integer!] + return: [integer!] /local - key [integer!] + key [integer!] special? [logic!] ][ ;; DEBUG: print ["keycode: " keycode lf] @@ -541,14 +548,6 @@ translate-key: func [ key ] -post-quit-msg: func [ - /local - e [integer!] - tm [float!] -][ - exit-loop: exit-loop - 1 -] - ;; TODO: before finding better solution!!!! ;; container-type? is now only restricted to rich-text (cf gui.red) ;; since diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 845e623b79..cf21b034c0 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -627,6 +627,12 @@ GPtrArray!: alias struct! [ gtype [integer!] return: [logic!] ] + g_application_run: "g_application_run" [ + app [handle!] + argc [integer!] + argv [int-ptr!] + return: [integer!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ @@ -749,45 +755,55 @@ GPtrArray!: alias struct! [ return: [handle!] ] g_list_length: "g_list_length" [ - list [int-ptr!] + list [GList!] return: [integer!] ] g_list_free: "g_list_free" [ - list [int-ptr!] + list [GList!] ] g_list_nth_data: "g_list_nth_data" [ - list [handle!] + list [GList!] nth [integer!] return: [handle!] ] g_list_append: "g_list_append" [ - list [handle!] + list [GList!] data [handle!] - return: [handle!] + return: [GList!] ] g_list_prepend: "g_list_prepend" [ - list [handle!] + list [GList!] data [handle!] - return: [handle!] + return: [GList!] ] g_list_first: "g_list_first" [ - list [handle!] - return: [handle!] + list [GList!] + return: [GList!] ] g_list_last: "g_list_last" [ - list [handle!] - return: [handle!] + list [GList!] + return: [GList!] ] g_list_delete_link: "g_list_delete_link" [ - list [handle!] - link [handle!] - return: [handle!] + list [GList!] + link [GList!] + return: [GList!] ] g_list_insert_sorted: "g_list_insert_sorted" [ - list [handle!] + list [GList!] data [handle!] comp-func [integer!] - return: [handle!] + return: [GList!] + ] + g_list_remove: "g_list_remove" [ + list [GList!] + data [handle!] + return: [GList!] + ] + g_list_find: "g_list_find" [ + list [GList!] + data [handle!] + return: [GList!] ] g_ascii_dtostr: "g_ascii_dtostr" [ buffer [c-string!] @@ -891,82 +907,82 @@ GPtrArray!: alias struct! [ ;; ] ;; LIBGTK-file cdecl [ gtk_get_major_version: "gtk_get_major_version" [ - return: [integer!] + return: [integer!] ] gtk_get_minor_version: "gtk_get_minor_version" [ - return: [integer!] + return: [integer!] ] gtk_get_micro_version: "gtk_get_micro_version" [ - return: [integer!] + return: [integer!] ] gdk_cursor_new_from_pixbuf: "gdk_cursor_new_from_pixbuf" [ - display [handle!] - pixbuf [handle!] - x [integer!] - y [integer!] - return: [handle!] + display [handle!] + pixbuf [handle!] + x [integer!] + y [integer!] + return: [handle!] ] gdk_cursor_new_from_name: "gdk_cursor_new_from_name" [ - display [handle!] - name [c-string!] - return: [handle!] + display [handle!] + name [c-string!] + return: [handle!] ] gtk_get_current_event_time: "gtk_get_current_event_time" [ - return: [integer!] + return: [integer!] ] gtk_get_current_event_state: "gtk_get_current_event_state" [ - state [int-ptr!] + state [int-ptr!] ] gtk_get_current_event: "gtk_get_current_event" [ - return: [handle!] + return: [handle!] ] gtk_get_current_event_device: "gtk_get_current_event_device" [ - return: [handle!] + return: [handle!] ] gtk_get_event_widget: "gtk_get_event_widget" [ - event [handle!] - return: [handle!] + event [handle!] + return: [handle!] ] gdk_event_get: "gdk_event_get" [ - return: [handle!] + return: [handle!] ] gdk_event_peek: "gdk_event_peek" [ - return: [handle!] + return: [handle!] ] gdk_event_copy: "gdk_event_copy" [ - event [handle!] - return: [handle!] + event [handle!] + return: [handle!] ] gdk_event_free: " gdk_event_free" [ - event [handle!] + event [handle!] ] gdk_event_get_scroll_deltas: "gdk_event_get_scroll_deltas" [ - event [handle!] - dx [float-ptr!] - dy [float-ptr!] - return: [integer!] + event [handle!] + dx [float-ptr!] + dy [float-ptr!] + return: [integer!] ] gdk_event_get_scroll_direction: "gdk_event_get_scroll_direction" [ - event [handle!] - direction [int-ptr!] + event [handle!] + direction [int-ptr!] ] gdk_window_get_display: "gdk_window_get_display" [ - window [handle!] - return: [handle!] + window [handle!] + return: [handle!] ] gdk_window_get_device_position: "gdk_window_get_device_position" [ - window [handle!] - device [handle!] - x [int-ptr!] - y [int-ptr!] - mask [handle!] - return: [handle!] + window [handle!] + device [handle!] + x [int-ptr!] + y [int-ptr!] + mask [handle!] + return: [handle!] ] gdk_window_invalidate_rect: "gdk_window_invalidate_rect" [ - window [handle!] - rect [tagRECT] - invalidate_children [logic!] + window [handle!] + rect [tagRECT] + invalid [logic!] ] gtk_application_new: "gtk_application_new" [ app-id [c-string!] @@ -975,7 +991,7 @@ GPtrArray!: alias struct! [ ] gtk_application_get_windows: "gtk_application_get_windows" [ app [handle!] - return: [int-ptr!] + return: [GList!] ] gtk_application_get_active_window: "gtk_application_get_active_window" [ app [handle!] @@ -993,6 +1009,9 @@ GPtrArray!: alias struct! [ app [handle!] window [handle!] ] + g_application_quit: "g_application_quit" [ + app [handle!] + ] gtk_menu_bar_new: "gtk_menu_bar_new" [ return: [handle!] ] @@ -1158,10 +1177,14 @@ GPtrArray!: alias struct! [ gtk_main: "gtk_main" [] gtk_main_quit: "gtk_main_quit" [] gtk_main_iteration: "gtk_main_iteration" [ - return: [logic!] + return: [logic!] + ] + gtk_main_iteration_do: "gtk_main_iteration_do" [ + block? [logic!] + return: [logic!] ] gtk_events_pending: "gtk_events_pending" [ - return: [logic!] + return: [logic!] ] gtk_window_new: "gtk_window_new" [ type [integer!] @@ -2893,7 +2916,7 @@ red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" menu-id: g_quark_from_string "menu-id" -no-wait-id: g_quark_from_string "no-wait-id" +post-quit-id: g_quark_from_string "post-quit-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" @@ -2908,3 +2931,5 @@ start-resize-id: g_quark_from_string "start-resize-id" #define GET-RESIZING(s) [g_object_get_qdata s resizing-id] #define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] #define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] +#define SET-POST-QUIT(s d) [g_object_set_qdata s post-quit-id d] +#define GET-POST-QUIT(s) [g_object_get_qdata s post-quit-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index b2a2827cda..70097af969 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -24,32 +24,18 @@ Red/System [ #include %tab-panel.reds #include %text-list.reds -GTKApp: as handle! 0 -GTKApp-Ctx: 0 -exit-loop: 0 - -;;;close-window?: no -;;;win-array: declare red-vector! -win-cnt: 0 - -group-radio: as handle! 0 - -settings: as handle! 0 -pango-context: as handle! 0 -default-font-name: as c-string! 0 -default-font-size: 0 -gtk-font-name: "Sans" -gtk-font-size: 10 - -; Do not KNOW about this one -;;; -main-window: as handle! 0 -last-window: as handle! 0 - -log-pixels-x: 0 -log-pixels-y: 0 -screen-size-x: 0 -screen-size-y: 0 +settings: as handle! 0 +pango-context: as handle! 0 +default-font-name: as c-string! 0 +default-font-size: 0 +gtk-font-name: "Sans" +gtk-font-size: 10 +group-radio: as handle! 0 + +log-pixels-x: 0 +log-pixels-y: 0 +screen-size-x: 0 +screen-size-y: 0 get-face-obj: func [ handle [handle!] @@ -338,22 +324,6 @@ show-widget: func [ gtk_widget_show widget ] -set-view-no-wait: func [ - window [handle!] - key [logic!] -][ - ; usually a view/no-wait call at most twice do-events and at least one do-events with no-wait? = true - ;; DEBUG[view/no-wait]: print ["view-no-wait? window " window " => " key lf] - g_object_set_qdata window no-wait-id as int-ptr! either key [1][0] -] - -view-no-wait?: func [ - window [handle!] - return: [logic!] -][ - all[1 = as integer! g_object_get_qdata window no-wait-id window <> main-window] -] - get-child-from-xy: func [ parent [handle!] x [integer!] @@ -407,7 +377,7 @@ get-text-size: func [ ] free-handles: func [ - widget [integer!] + widget [handle!] force? [logic!] /local values [red-value!] @@ -420,17 +390,12 @@ free-handles: func [ sym [integer!] handle [handle!] ][ - values: get-face-values as handle! widget + values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - ;;;if all [sym = window not force?][ - ;;; close-window?: yes - ;;; vector/rs-append-int win-array widget - ;;;] - rate: values + FACE_OBJ_RATE - if TYPE_OF(rate) <> TYPE_NONE [change-rate as handle! widget none-value] + if TYPE_OF(rate) <> TYPE_NONE [change-rate widget none-value] pane: as red-block! values + FACE_OBJ_PANE if TYPE_OF(pane) = TYPE_BLOCK [ @@ -438,14 +403,13 @@ free-handles: func [ tail: as red-object! block/rs-tail pane while [face < tail][ handle: face-handle? face - unless null? handle [free-handles as-integer handle force?] + unless null? handle [free-handles handle force?] face: face + 1 ] ] if sym = window [ - win-cnt: win-cnt - 1 - post-quit-msg + gtk_widget_destroy widget ] state: values + FACE_OBJ_STATE @@ -543,16 +507,151 @@ set-defaults: func [ set-default-font default-font-name default-font-size ] +get-window-count: func [ + return: [integer!] + /local + pane [red-block!] + face [red-object!] + num [integer!] + count [integer!] + win [handle!] + ret [integer!] +][ + pane: as red-block! #get system/view/screens ;-- screens list + if null? pane [return null] + + face: as red-object! block/rs-head pane ;-- 1st screen + if null? face [return null] + + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + + ret: 0 + num: pane/head + block/rs-length? pane + if all [ + TYPE_OF(pane) = TYPE_BLOCK + 0 < num + ][ + count: num - 1 + loop num [ + win: face-handle? as red-object! block/rs-abs-at pane count + unless null? win [ + ret: ret + 1 + ] + count: count - 1 + ] + ] + ret +] + +check-quit-msg: func [ + return: [logic!] + /local + pane [red-block!] + face [red-object!] + num [integer!] + count [integer!] + win [handle!] + v [handle!] +][ + pane: as red-block! #get system/view/screens ;-- screens list + if null? pane [return null] + + face: as red-object! block/rs-head pane ;-- 1st screen + if null? face [return null] + + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + + num: pane/head + block/rs-length? pane + either all [ + TYPE_OF(pane) = TYPE_BLOCK + 0 < num + ][ + count: num - 1 + loop num [ + win: face-handle? as red-object! block/rs-abs-at pane count + unless null? win [ + if as logic! GET-POST-QUIT(win) [ + v: as handle! 0 + SET-POST-QUIT(win v) + return true + ] + ] + count: count - 1 + ] + false + ][ + true + ] +] + +find-active-window: func [ + return: [handle!] + /local + pane [red-block!] + face [red-object!] + num [integer!] + count [integer!] + win [handle!] + ret [handle!] +][ + pane: as red-block! #get system/view/screens ;-- screens list + if null? pane [return null] + + face: as red-object! block/rs-head pane ;-- 1st screen + if null? face [return null] + + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + + num: pane/head + block/rs-length? pane + either all [ + TYPE_OF(pane) = TYPE_BLOCK + 0 < num + ][ + ret: face-handle? as red-object! (block/rs-tail pane) - 1 + count: num - 1 + loop num [ + win: face-handle? as red-object! block/rs-abs-at pane count + unless null? win [ + if gtk_window_is_active win [ + return win + ] + ] + count: count - 1 + ] + ret + ][ + null + ] +] + +find-last-window: func [ + return: [handle!] + /local + pane [red-block!] + face [red-object!] +][ + pane: as red-block! #get system/view/screens ;-- screens list + if null? pane [return null] + + face: as red-object! block/rs-head pane ;-- 1st screen + if null? face [return null] + + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + + either all [ + TYPE_OF(pane) = TYPE_BLOCK + 0 < (pane/head + block/rs-length? pane) + ][ + face-handle? as red-object! (block/rs-tail pane) - 1 + ][ + null + ] +] + init: func [][ show-gtk-version gtk_disable_setlocale - GTKApp: gtk_application_new RED_GTK_APP_ID G_APPLICATION_NON_UNIQUE - gobj_signal_connect(GTKApp "window-removed" :window-removed-event :exit-loop) - GTKApp-Ctx: g_main_context_default - unless g_main_context_acquire GTKApp-Ctx [ - probe "ERROR: GTK: Cannot acquire main context" halt - ] - g_application_register GTKApp null null + gtk_init null null screen-size-x: gdk_screen_width screen-size-y: gdk_screen_height @@ -797,7 +896,7 @@ change-pane: func [ gtk_container_remove layout child/data child: child/next ] - g_list_free as int-ptr! list + g_list_free list s: GET_BUFFER(pane) face: as red-object! s/offset + pane/head @@ -1581,13 +1680,7 @@ OS-make-view: func [ gtk_container_add container widget ] sym = window [ - win-cnt: win-cnt + 1 widget: gtk_window_new 0 - last-window: widget - if win-cnt = 1 [ - main-window: widget - ] - gtk_application_add_window GTKApp widget if bits and FACET_FLAGS_MODAL <> 0 [ gtk_window_set_modal widget yes @@ -1915,15 +2008,6 @@ OS-destroy-view: func [ handle: face-handle? face values: object/get-values face flags: get-flags as red-block! values + FACE_OBJ_FLAGS - either handle <> main-window [ - ;; DEBUG: if flags and FACET_FLAGS_MODAL <> 0 [print ["modal "]] print ["window: " handle " (main-window: " main-window ") closing... win-cnt: " win-cnt " exit-loop: " exit-loop lf ] - - ;gtk_window_close handle ;; NOT ENOUGH SINCE THIS IS EQUIVALENT TO CLICKING CLOSE BUTTON - gtk_widget_destroy handle - win-cnt: win-cnt - 1 - ][ - - ;; DEBUG: print ["closing main window win-cnt: " win-cnt " exit-loop: " exit-loop lf] obj: as red-object! values + FACE_OBJ_FONT if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj FONT_OBJ_PARENT] @@ -1931,16 +2015,10 @@ OS-destroy-view: func [ obj: as red-object! values + FACE_OBJ_PARA if TYPE_OF(obj) = TYPE_OBJECT [unlink-sub-obj face obj PARA_OBJ_PARENT] - ;;g_main_context_release GTKApp-Ctx - ;; DEBUG: - ;; TODO: This can be useless now! remove-all-timers handle - ;; DEBUG: print ["BYE! win: " win-cnt " (" handle ")" lf] - - free-handles as-integer handle no - ] + free-handles handle no ] OS-update-facet: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 8c49683f73..f61af2ef32 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -251,27 +251,7 @@ window-delete-event: func [ no ] -; window-destroy: func [ -; [cdecl] -; widget [handle!] -; ][ -; ;; DEBUG: print ["window-destroy" lf] -; ;;remove-all-timers widget -; make-event widget 0 EVT_CLOSE -; ] - -window-removed-event: func [ - [cdecl] - app [handle!] - widget [handle!] - count [int-ptr!] -][ - ;; DEBUG[view/no-wait]: print ["App " app " removed window " widget "exit-loop: " exit-loop " win-cnt: " win-cnt " main-window? " main-window = widget] - unless view-no-wait? widget [count/value: count/value - 1] - ;; DEBUG[view/no-wait]: print ["=> exit-loop: " count/value lf] -] - -window-event: func [ +window-event: func [ [cdecl] evbox [handle!] event [GdkEventAny!] @@ -428,13 +408,21 @@ key-press-event: func [ widget [handle!] return: [integer!] /local + face [red-object!] + values [red-value!] + type [red-word!] + sym [integer!] res [integer!] key [integer!] flags [integer!] text [c-string!] - face [red-object!] qdata [handle!] ][ + face: get-face-obj widget + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not @@ -454,6 +442,9 @@ key-press-event: func [ ] ][res: make-event widget key or flags EVT_KEY] ] + if sym = field [ + return EVT_DISPATCH + ] EVT_NO_DISPATCH ] @@ -464,14 +455,26 @@ key-release-event: func [ widget [handle!] return: [integer!] /local + face [red-object!] + values [red-value!] + type [red-word!] + sym [integer!] key [integer!] flags [integer!] ][ + face: get-face-obj widget + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state make-event widget key or flags EVT_KEY_UP + if sym = field [ + return EVT_DISPATCH + ] EVT_NO_DISPATCH ] @@ -489,6 +492,7 @@ field-changed: func [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] + EVT_NO_DISPATCH ] focus-in-event: func [ From 557b42ce17f46d45dfe2483ada0c7de80c954eb1 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 31 Oct 2019 16:56:35 +0800 Subject: [PATCH 0350/3432] FIX: when widget has been destroyed, still need do some event loop --- modules/view/backends/gtk3/gtk.reds | 32 +++++++++++++++++++++++++---- modules/view/backends/gtk3/gui.reds | 14 ++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index cf21b034c0..35247b3222 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -610,16 +610,36 @@ GPtrArray!: alias struct! [ ts [integer!] handler [integer!] data [int-ptr!] - return: [integer!] + return: [integer!] + ] + g_timer_new: "g_timer_new" [ + return: [handle!] + ] + g_timer_start: "g_timer_start" [ + timer [handle!] + ] + g_timer_stop: "g_timer_stop" [ + timer [handle!] + ] + g_timer_continue: "g_timer_continue" [ + timer [handle!] + ] + g_timer_elapsed: "g_timer_elapsed" [ + timer [handle!] + ms [int-ptr!] + return: [float!] + ] + g_timer_destroy: "g_timer_destroy" [ + timer [handle!] ] g_idle_add: "g_idle_add" [ handler [integer!] data [int-ptr!] - return: [integer!] + return: [integer!] ] g_markup_escape_text: "g_markup_escape_text" [ - text [c-string!] - len [integer!] + text [c-string!] + len [integer!] return: [c-string!] ] g_type_check_instance_is_a: "g_type_check_instance_is_a" [ @@ -1294,6 +1314,10 @@ GPtrArray!: alias struct! [ widget [handle!] event [handle!] ] + gtk_widget_destroyed: "gtk_widget_destroyed" [ + widget [handle!] + pointer [int-ptr!] + ] gtk_widget_get_window: "gtk_widget_get_window" [ widget [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 70097af969..ea1b57856c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -389,6 +389,8 @@ free-handles: func [ rate [red-value!] sym [integer!] handle [handle!] + timer [handle!] + sec [float!] ][ values: get-face-values widget type: as red-word! values + FACE_OBJ_TYPE @@ -410,6 +412,17 @@ free-handles: func [ if sym = window [ gtk_widget_destroy widget + ;-- TBD: don't know why widget has been destroyed, but still need do event loop + ;-- otherwise the window can't be closed + timer: g_timer_new + g_timer_start timer + forever [ + gtk_main_iteration_do no + sec: g_timer_elapsed timer null + if sec > 0.001 [break] + ] + g_timer_stop timer + g_timer_destroy timer ] state: values + FACE_OBJ_STATE @@ -2004,7 +2017,6 @@ OS-destroy-view: func [ obj [red-object!] flags [integer!] ][ - ;; DEBUG: print ["OS-destroy-view" lf] handle: face-handle? face values: object/get-values face flags: get-flags as red-block! values + FACE_OBJ_FLAGS From 91af73766bba1567cd581d4c20d7cb8537996d6b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 31 Oct 2019 20:54:39 +0100 Subject: [PATCH 0351/3432] FEAT: completes support for basic date! formats. Some ISO formats still need more work. --- docs/lexer/date-FSM.csv | 11 ++-- docs/lexer/lexer-FSM.xlsx | Bin 25476 -> 25538 bytes runtime/datatypes/date.reds | 2 +- runtime/lexer-transitions.reds | 19 +++---- runtime/lexer.reds | 8 +-- utils/generate-lexer-table.red | 96 ++++++++++++++++----------------- 6 files changed, 70 insertions(+), 66 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index 38c251aca4..64f4b88c2e 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -3,12 +3,12 @@ S_DT_START;S_DT_D;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ER S_DT_D;S_DT_DD;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YYY;F_DT_YEARL;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YYYY;S_DT_YM;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL;S_DT_YM;S_DT_YMON;F_DT_YEARL;F_DT_YEARL2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL2;S_DT_YM2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DAYL;S_DT_DM;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YM;S_DT_YMM;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YMM;F_DT_YMONTH;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YMM;F_DT_YMD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YM2;S_DT_YMM2;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YMM2;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR @@ -34,7 +34,7 @@ F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM -F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM +F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_TM_HM;T_DT_ERROR;T_TM_HM S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;F_TM_N1;T_TM_HMS;T_DT_ERROR;T_TM_HMS @@ -44,6 +44,7 @@ S_TM_HMZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERRO S_TM_HMSZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_HMSNZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TZ_H;F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_H -F_TZ_HH;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH -F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM +F_TZ_HH;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH +F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_M S_TZ_M;T_TZ_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM +T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 8be73a31ba26f032b92015317d344e69004558db..9aa6fbe326377b5601de717e83901e580e7fa06c 100644 GIT binary patch delta 5204 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 delta 5156 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 Date: Thu, 31 Oct 2019 22:25:09 +0100 Subject: [PATCH 0352/3432] FEAT: now all date! formats are recognized properly. --- docs/lexer/date-FSM.csv | 9 ++-- docs/lexer/lexer-FSM.xlsx | Bin 25538 -> 24297 bytes docs/lexer/lexer-states.txt | 4 +- runtime/datatypes/date.reds | 40 ++++++++++++++ runtime/lexer-transitions.reds | 47 +++++++++-------- runtime/lexer.reds | 58 +++++++------------- utils/generate-lexer-table.red | 94 +++++++++++++++++---------------- 7 files changed, 138 insertions(+), 114 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index 64f4b88c2e..b284bc44dc 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -2,9 +2,9 @@ S_DT_START;S_DT_D;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_D;S_DT_DD;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YYYY;S_DT_YM;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YEARL;S_DT_YM;S_DT_YMON;F_DT_YEARL;F_DT_YEARL2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YYYY;S_DT_YM;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +F_DT_YEARL;S_DT_YM;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YEARL2;S_DT_YM2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DAYL;S_DT_DM;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YM;S_DT_YMM;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR @@ -15,7 +15,8 @@ F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YDDD S_DT_YV;S_DT_YW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK -S_DT_YWW;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR +S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_DT_YWD;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK +S_DT_YWD;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YWWD S_DT_YMON;T_DT_ERROR;S_DT_YMON;F_DT_YMONTH;F_DT_YMONTH;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_YMD;F_DT_YMDD;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 9aa6fbe326377b5601de717e83901e580e7fa06c..73ec317d8ca8973fbfb5ff9fcd161ad975e5ec0b 100644 GIT binary patch delta 13698 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 IgWJFU4@+k^+W-In delta 14809 zcmaKT1yozx)-@KaxVyV+DXyhJkr0Brh2q7FH57MCaVYLytT>e7T3iYgFJ7R~;(zG9 z@4b8Pd;b>(Atd``uf5isbIpCmIlJwMANvtWfzOdqh!9W_&=C+2=n>k{D8|zf5fFaV zk}@JewU_Na@)32=9#E?|g~f=GS?aZ?E^V=VqoI5JjM4!X?{?#Roi)p@HO+vzr1m@` z^LU5qv~bFh*tv$i<3)ZRR^WfDz4q&%5(EO){;xFkITtFg$Q^qr3&86K;F)jdsxyJc4GdLqdtV@ZJflp z(QM;pno4%^g2`zc5{B0ep*ETLuzOnBZ z-SIM?sqZ4B;F?oLSbOvc;-LuCJnFTyA%XS};6p{%WWURMhrO71_QBf2#-kGvw#G~Z zV==&~8%G|+eiY!BT)B>ofME3!A(4d))`<^*RxB^ME~=2Ae!VVD_saRO+859j7FlP% zKLOeY3Jd$<%%KcFCg!7|D{fj{eqrv--7wQx+N_-U%d!D@Z>Ri-_3Fp<_^8kK_LW23 zrJdHbU+b<cmn4Z7>b-mMhe>fF)c(i|4 z3a!FL)>`w1iuj39nK(VmzdbEo;kqDQO1WC_+c9rl;=&H>lOL)Bd;jh?e=$# zJEJUpqh2QaF+pP&jyl83o}K^-fyGI@6H<1d00#0jgqr+!vznnABvZP|8vCG<|LXqUFN+yA!aSEJO8+cjgkZkz_1 z;LDf%g1+5H(M#8+F72l2eyQEOMS_N2&BhrF+jHFz>ma9#^>v%N=JM+v*yY}-g`bCD zXNQ1x$MkiO!9re7_vzAI&GJnOUJ}$UQne)f^7h%;ZAR4oiNuFYjqePI#QfDc43=(K zfrflij)Ax99+WI+84K<=Zyd=qG+KN7P7EMYSw_g(ilbGMV}@-{xTK(qj!>+TZX3^) zJ8Scl(348)HxOH=mEASlh8qf}49SDky0nOq$=P2$B>aHDjo2nA;bW*}pe59#UF7I` z=j7Mk)VJ2b;Y1T+(GiC}wFABldnbaF<~2pp5vw7!Jpn|Kv|%IHd}GLn+K~XE6J`qj zb+LPzXth?esyHblVep(#YCy}Rnbsb<%mhnU#{^RsN=erDh}4oA+3h(IMOCmuh@NZJ zC$3NEDtHBWZyDI+;}wCiIY>}h=0FZyi%Y&UUlXZ=M`}_dddK7b^K_7+^{`DmdF4ja)yHR#76W_+uY|#hujC!a4A1c(I?M@W1biHXe$*V z^I?*6Jq3o+#pF=Q0s>V~v}ry~nvc=%6!vt~z;O7_%;ASuZ8nEsoyWG%Ki5{7NDn;IDv`G3#Avenkm(=k!d6Fp<% zHP9pK0ECKBvEUKXibqp%x}>Hl<++lH>MW+#URL^Bo{EXWa{zrv!XG(UsA=czr>?kv z*V_Sv$d5gpr%R5p_cn1M6E)?>hOEqApC!>LA?6q22oif)k_)8%&fg!0u6+;{p}GhW zpweO70RyGi7$WCKE3Q{Kvw2dpu9Z3?*W#g%F|qb59NtxvSabKwR`% zpL-(I3w?^EJ(CG!;dRP60V!F>PsR_?Ys-`cgSWIKI2+?GE)+Jtg{M8fu-B-!ZH)*B zZ^rG9u|Q0V(2qes&pxo!EiGk(2P(T!7(YZ;NS`EM768U59V&h$Gs5+ni7t7VSi!_F zxX~Iy^k^W)0UC*a3iza1Mu~^O{-TWtL|!0N;HpF%&q1$!NrW5jSmbX8$X%fn?;U8y zbsRTFwOVZa8Am&z5bTHOlC)PrhX9&*#aGuc?F*og

2Mu|JK>xhsYSU zMkb*H5ZM>vFS6>Q4}$Ra;xw^JQ9ziWf5wLImQxo#q2d3_7vkyEYKsq*MOQxAXmtCm zQs_gP^-IXCT7|BVE=lfhGdToSEuzxnMjbY_8*6;80T#z{8@?Hked0v4l$>L{^bKit z>PP-Qp#rl|&N7)1JQqwWIkc zL^{@T5w`-1y#ndBO@R$*TNirjmhePCtTlAZ_w8;^6gaJkg`>iWtYbicFRB zZFbM3L=kQbunK)4s00c|Wydb10s#tCl(Y-xe;75iyVDTokBI}+4md~4KISuk@ZN!) zF&UJ43+Au)AR&*-y<|e(s^nJw1zeFtOU1{K-p7LDEkd^iBxO`R~e=q>4%ia$F>3 z?d#P-f?{I2xSv&bxx*m5hTLj z%bq0z!KqO2Tl5O%W8srmy_GNgQz2Lt9-FU?BNk7`S*KLP*{2kF%;>^OnWf@AOGr_p z%M9fHGd%VVMlo~Q6$?acz29;~vJltXBX_Y5LJ~vi5}Tb&QHXB{Y_i5krLmQlf(9beV=fv-X!(!Tla%UvvhzlSJL%deKvwZ!88=^O5Ta zp9px@@QMFx!!KKQ0Cp-=j>D~8UNk3EtKMlEUD+*8|(j znnnll7Z89P^i$3Xa~^cnN(MV=$hdHu;R_)5=XSm5g3N|CJXD(Z3z*psNPDgCxs#na znR>S!d5+%ZYn84%>5czyZG~p9+wz|c@Tf^dMQojZ)E;|HCNxBd&#@JOo<}ejFvkFk z1l})jhk!$|N^;@-0&_0F&81vVu8>26ohB~s+z45BTzkbVv_MY+a;o)Ji(NzFMVCp^ z|4InM``tZ#*%HnHb%E11TGSXgL~Z$?ec-bD8jb(b{Oomne%NgSEPCsdi81AD;^ux` z$D2W}&}S|zRppW)a2f=x{4a4is9x8toVF9Ln`&&_+-1U|s+`sL4Vt;h5z4)z`t+aG zv-IL*aDGM~$OQp@^KWd_ZYRv9mui$&UmXrMgrKsVKQo3PYV_Akb?P$l7q+T}SC(&ORAf0q{>As- zbk}?7yx5b;`pJ`397=sz>VF43tIwIUArQ@Ww2%^$xYdY7^pL;YeYVNK)Z2KdlJgB* z=CvG7pY-3~w30zbLUYDcd9U>PC+Tt~N#r@sa;MdcmfgnwNhiBbP;LH0X0W znnODm%|6tw*4Ie#7;XQm+o;*ZBvtn~oi&%bQ_8_K7HY4P%)1oi9k{Top|Oqc*WewS z?9I3M@_WrPjXIPMSGmsPz5;jE1a)b7NJ8rH7r4E3ZP?Rmo?8b^@Z;g$ozsV@pO)7W zRUWq=^zQO@HXBwm=8t1cvT=W1^1}D;_xH#Mz~`_lIV_mHAs%d&o*cGEyMTF{z-)a2 z|JWD_HbGAdJD|gaRwRzAAoJse9S0ucZ974{0Qk0zDGWc#&Jis@t0gFho7b4)>l{2ah{5_w2=bt^9L;s1(-B`N`Xmznh8iYr3P0sLOxx$9}o4kDeC=Ai?1B zdA;t6c>xin?m783Y>pL*G~*4^V>5*MwPah3E2EX(CX)CrlE3Ha=k;ppoI9?IF|Jjv zvc6v}0wmUd3_EMmuo1b%JwK3cOQ4_~qYb&eJlPw)j*_0^2we%>mxVO!)%MI>^u%&Txts zAlYe|Da-IBnY zr&;ebpYoZOYbAi0wKQ57(xKJ&X=fqzLp!h8mpdkSISumLUiYn}+U-`jGGzO%Nqb~3 z+DI~0cGgA>bc?+296VtEA&5k4KtPf2)ZoRl~wUlmfSKc#xkviUjF4ZVPB z*$q?04JSfKExbTfXTYjMy6tjj{*fAJFLQ!Pi(5@VTGk(FKdn|NUllx`VV&D=ds%P@ zi`8h6+Py3|hP}}Um4aRJ)9S&P5K%wzmk#8s8zK>;1t_u5!7$LRkw9s|dP5wNO-BA} z3Bg8*I_%Dy8ZVMcbt*xolhcAQ=cIHYzsVoU!>o?k?tYW!%Hyp5*;sx8BT8!{Wy50$ zrq-|jT8EWtK%~;Ht=3?L8ah(?*H#;_ zN)1n`g=;3|07P$9iX0pzDt=@dys4pglUx{>BWb<-N?TaKOM3@!7bq0J5Nlgt7^>e z*87F{kuH~Ut!wWhF{Q49ajjb~9P;b17LA)P%&)%_NP8y(bGkf_(atwhM!MHiVbf<9TJ@qOZ!5BqQ>^M+OWsao2PbM3S&PMHWGyF4 zRcedHc4RXrNtIrU#a3hk=i{pR7K@$8cFx34tgrVHLrr_fjn~n5Phcs(K0m)XV5axu zt#5v*pGxhqrm~S8RVT-(ddxDidSD6l&Vt&_V9pS$O2&V&$#tG?3c$`55==ZU-U}&& z&n~Un&uX0g!*BBEU>9po^rmj1j#jo=^pIlZ7xC-y+g$Ix(-IQ z9=&74*Q!LI@;n$*S1|f^Q^X>Ya(K?u8+4Y}s4zS^`y4#Es9-z;rr-&usO@!P=wjZN z1|K;?)dssLyWagbn@f2ul?7`sh+?$Ii{`vT+^G}gIabN+AN~U02l*IhOKGh?>3x7_ z;ZC*4DItw>yGrka#cpI0=WNyd2Ma@zhU}S`C#~-_7Zz;tCP=kC6H!v*Wi1Jr=z~a3 z1XF*}tIAf6sE7ClnMO_kz9HVf^F4j@MsM1)|DV5N%kMVX!YR@93p=S*Ox3iDB#HFg~Y zEFd#B#T0+Oa0+K)3!NE?`yz@H8s#F)nebt#a>MKifnKvW71))*(4q7c`q5M6xmvSR zY0LP`)b;Swt)^BVZO2~)yRc-9#W#AawaBWZsWg24W~g0QZ^#h^Q6WepM5*L_Ze}Fi zWY_i>Llpt~$aRR2MQ9&eKt8XN1U6u;(T_bW~`o5K<-uDlh(-TMjX}`cf$igyoRPItGfNcwp?|PqV&| znc&MI9s4yE_JtAjLUkfIhh0`Ma2tgi-GHE;;f2~nXb!imc;E$!axq}-tu2$Vo3O_=jZ8gl#!Z}EdfT$v zqSmeGXY<+d%2el9sJz!0v?{R9S0H~-?WFQ5umc`Q>W%9+-gLvR`ts;2rAET&hKgmg zQ%b#iVPr{Qu_-_8`9}c+>ri6r>8ZVZ%skzfSR*K^Hkf-O0cpr}2oQ`B%v2A)*|B+q zI)LS&OqM@ih;hjzv!l?b>F}KT&sh4GiBgz&%4O~#V5tDKd@rk}?F=o+!eBI?(M8R| z#8mIZLPU)g`AKdDL<74(w`Y9Ws3Fj&a(ysxef8Ox!eo%ysm*cB z)rA-O-k;Erf%cBP6NReAi}}_7&o4NSMmBqXc%9@t_}?0TwEw zD*VMP49ZDTnA=2k271L7_X$mBIq`(E7L;nodD6Kt5Rqllr4q4}bA!vY5RoCFGSw5k z3~hxZTf`~UqJKaXh9ypEw)uW~Jf~hOfCE-$!Iqs6sKQiniosr@u+EVk7pTHt1Br@@ z;5M3XdkOXDZYRDEeob-oW&Ee#`Rw~U@cUoO9Sm?G@}E3aUSg%rcK4q=Q(k37&c;F> z%r?ADA&$KffSL1BLVdH9R=K2Q3O=$pPKnSZObXqK(ZMDKhCQa2c$yKoDgBM;l3j1p zW?ZhULrn(2Cs%^)&)`#$JME7DeC|9?dcmtVkL0Qf~o%I@-QTdtIghdAu+ zT@#JwQF+m1(`lDb5PL=X)n*|;l`?wfU*PyHSb?>(4RfB_x8`9pYR*TCGD1P*r%J9$&-4U%CB~zltT&TUZn8;8DAP5ZISL z3R_!!m>pYqt0lLLv-!$e<}$R5))}dYT-985T94ao(X0Z8&)CeT>&F{%1VI!Ck?L#g z8DrZG%seRBV8KwyHGh$|qW?VXR;YeGY(rQ$+gqD@hL@xps>iRVGoxu)DU;>F7jjqF zc!oN?0DnV7;y5s2>D4=D-_IiaN9B7ZmrTksmuIg_c@#HyY^-EQ^PB8K3bG*s26mSi z6bRZ7ZCuhGI~>v}xccc5_O_)DU^vuf4_UmM)X=KBDwP794+pqrtXE>1BBw(5E~kvO zy6xaFwuE{F>>^De7vYW|q|)={!--PzQKU-1E{nBW@7l>gyLcK{*KR(OraPl~rXO(0 z6~rzi*MO^=Ge$AJ5FoZxCRP}lUKzIx6ttvH5duSV3v-c(^6jz&Y)f)LSmpZcMKcQj zN@Ybv<|h)$GO$=-Zjq5NczJU#1u+eZJtHy-e5O8gR^C8U4lm+J@!yyQ(9)Bi+3f2c zAon)0@z)kYv{aMLBIi3Z!*t^jo_4s`b2AAPt?u%h%^CZhICf$1{f7%PF58mV^tL7B z92NEH2}Zea@|DY(evv9d!%x7=**i6b0 zXoEIFLk16_s~{ILut+@#lr2ovu7f8eLdgI|rdtOZDUYx)%L+9xVG2xn?FqTc-`B7$ zSztu$4J|X7+S3r;5_r4{JU7;SfHzk->`;mlN@o9Wu_cfGPYDdoJi89wB!ptptVAd` z5U^kqgCq4DF4BH4x)K5>(*qjVP-hj?EuwTwc3}vtM!67N93slHE2HMu)q)^OI zM%yG#FpzzFMxupGuQ)gTIS`&|>^oMW>F*LU=81bjcUOh?R45^(?a(a~dn5_J7 z<^NCbhY^WW^ZT&_IC^W+N23a~DLBYtH-+ins6Bwn?h3sN16$bFBIi{|S-R1!K+YH9 zJ@NAtewdjQH551QO&W@2{zhe|a|YiC~ylDr|Q&!qT%Q?Q6oaO zXJD=E4dqxm4Cb6Jf4d)AMq^TjW;I&-;1)ja>ilGE46qHV73*?;1A_>#LG6;koWYYo zL~q-K!p&FOGMAiSYYI5RYbos>CtLqh zK~YAYklACi=8OrEaq|AD;HZq6(2j+hti}ITJE$J3JcZp;pK0SE*AV#p73n<VviV^}auYNEL&$%Jk@Y(ad*`t~%+7!DuiFn!bf|KJ zdZ-XMzyb_+7Ue9F=E9n)@I)G^5uL$BS&vYg`Jy*8T?)CY^KA=e92U{XVyDLHXK(FG zoZs3aOkoxAC3oNw{}%%QmX&K{sThA@{~uOMXZvyYW=7M>nIYdS+y#?8r;xSl?UCew z7eLVJ5C@Lna4TWk1QmEQ%lvl?`t&N`X|a>g&to)!|x@Ykrzk8-pJ zJj}5PpCer|7uY7J9cI`$6hGrm`9G$3*iXRC8W)h`!IwR#t)pcj`fd?3CMbS=6n56$(a?Qg5l)g^N{YYGfse_!#!Us1HUGA_<5h3XR{~P4w+ocYb zOIfR&GFm_y+0%^gJGRi^2Bd?3pLX;!yi4`%Axr^^&{Szt5&7iJ6uaAMh~Hfdlcg&2 zUAnmxcDSb@2_i#qMvzjO`O3{sO<8uGcjmhF>^~q{I?85Im(=0*rMt-|2FNL^mU-yF zP)or{+U?SbWi`n_)$)c#<>+$JlT>&&=}PYrjo^L^7UhO_5|d&h5ioIuj{-y&~&8A-eq{Ol{ST4GsyNss*Zib@1$14yPDp90TaBTVQYtq z|6wPnE3Q0b6zd!wm{dcz2UY#IHtix#p+OKv@KQDTT$lRKrsQ<(u=~4I1OAo{rtI;#^V2n(1_XM2o360Lg2c5;{UiB z>Irxl&1zRrb;-49gd+0jWnf(`*Z)xIb8<9B&dV=g6=^NZ>A!_?imiP-Bg~g!Rw4W) z@baKb&)2LV_o_QS6cZR-=JDb|+Zxc}E+#C>rJ>P-;J3KA!TZF&#RVr0YZJ;^x~e?Q zI0X2S)uLSS&@AjL;0~Nm=kHFYZ;{v1jHOF8sCI1bVPg+(Pu)c6g>Zc}o9%LdJ7{mp z=msfqpbhReBewAKGT{eP^&Z0Hd@0MEsO>$B8yaOR%u2Iir!Mi^Pi?>aT@;>hDBRDm zr*KZ+{1U!Z)4Uba@-E=@eh~Y?YNg5_ZWLrb`kK|vaAU5*@IQ41weUavaIcsVF5l01J-9CRZ1Mw z5WTVoA?vYoq~9&qXZ{VaqJP+CU%RV-ZVX9bUmDqSu*c*5IoU1Gkh|}lzx$Tl`93r% z=P_C3U#t`K4LQKlG0lZzg;^PxG8GPCS(pyT$5 z3D{N=kK>hQ&~BwSM3+_R3tEpF`f##`SY&+ql70>1F>zZ}qH9H95n}`b9$NaFq)8 zTaSIqWQ6t3-y6a+HfOe4_B{5%21PzUy;~oL#vSuINq0b7zQDH`RRVkMZmeYX=B-^n z0(OxF5g=r$ul=X{aq}@jTDuhR^GZ``zwOGuc4^en4Z@GR9J=-3$fH&5sN8#{YHT22@*c@8Mi~oQ?_Nwr`5%?J{v--d9*rI1};Y}}aFdN%Hf9=oHO`3JIgOxP^@UvYN;3S=P>4M_GH4B5vndEnv98kFFCX9O{ z9Og!laXuZ@&l}cL>+RNd`RlHK)H&?)XpghkD(!d&jnpujnDjjp=`5~Sr+-AJ)XM#< ztLoFV!|I>?8@ElrT6x1VG{VAucnK7b|NPniD5a$z_vAOzYcR3Oa zHOw7K3Q_J|WWw7F+bG){>XsV!oG=%gZ z$p7Y2oRpTzZ)FSY`|+vrlSdxcW0S%o1n&qMG0!_`EqkUKKy=9rL*zK;l04_*pN~5M zh4WfBHGO(7asrcbJ4h@9g+~SSH>i@l{DR2+245vGA}(84Cqpxk^6THiT@Bv# z`PwJ>Mq%_Su3*1ar|94vN~VECAj5@9O4ZijkNwCKByM(@c+P9s*q|>o!UI3ejICkjkU5A>BhF zVqMIzWfatFN51DG(X`1Z;>%-C&G(9@(4X|%iMBICEN=rwryKG|P+N~}iSKykHGZXc z>~xnfhl&!ZHdtv;Q(CHg9eIeexE(>zj+YsQIk$ckA6hknN*9happ8Vz6&kD4MEjF+ z0Dv`V*Be6dbLgA)n~RG9YN_1Kw*>^fc2xqvR<~VZ(CGWS35u8NY=@FvlR)_{Nz?K% zPeNlt1&HeY*!dc{@151AZ{yZ0JI0h}U)|BA5D~`Ty?VDJZn@+FPV|3-^b|1fJs3q4 zJGw0tpA4;1(3Eju30MfMm_6nGrFc3L5+KNe2@2H7q{mdNOZ(h*Ex0xxLil*PmqLAj zWl5?j(O~0c1jHm(>-}ilSjG1?>M>3`aT#P61aVqA8@}{7y|0H+SYNK$DW^LS-zA%= z&=&CCz#5KNhNF#(Y8`2I);SA|*%YlbCxqyY_94(M1MO!mMy7^^t<|%>DJG674Ueeg zg;4`|^X+WxU)1IL>MIQrlwX`B^Zu|RfL$aj%<&H;vYC~9Wg&~2#+A~!?}_cp*eG4Mm8 z;9`$*+_jIU|a7|T~i{Y?QW+6NTP~@2R%yp04sTof>!u~5cPj$VL41(A=IOH59 zl5@`#_%%}{iJ#41CxC?k@27DI8}U&j<&#dtk)?e5y8)*C==|2UXwepK{n(N&b1b7V zpK~MI46MrQR`$`xJgundl0p9;6X7nN6|-?0^b-6>GMO z3O=4$uf@Dqk3uR)FWB`I9Ze4Q`0k3Iso${esL}Ar(V41&E34J~s?xAf^!VleSN=L2 zYC!^2*5M{7v9v1Fa2#@BZ#MH0rQWzn|vh zzFWq&A;~(;CWi$wXKLEDuZUN!k7Blyi92~Ek#%LA(MK$4@#vx-(fV$lZ}DLq6J<;b z0wCkjZ-+@gzj=MIwbu2H{Z+xrlb2V!d7!2Be3g*_X!D74*E0v8PJyAIsydw_Pu^U} z5n#L)O>QoPqL}!l-z`e0*y>csYAU~^tRw$8k$ft;L78A z9z|){TZ##xBO_vdFunnPe3_@;r@*W%(7}EQt)zBMXu*_nXtI#OGQCRin9>supwhKL0h7KeY(EnMkcy+)xR_nKzj*F@QbAE4GRJ=0yD0uFY;4Q%6~OCAjA?Ym6}QTo zklZ%n43Zbyj487|W9WISkaqTV94+$lQ7pqg0~~#$(LkYerLah}+|*K;Mo?eL}NCE>U2q7?cX zY~))bKAj>9=3c6F5iA#BBN_A#O0h)A#ornJ`8-mBA|y!(Cb+1(=)g%dOnjIP>0@7x zayQ$H7O{s~Vjn%Vemm*(@p0cG0av}Kh!b+Q)n$#N`3}*wf5I16k}L{*oXnzEKH{lr zlAb1(*pbok;=%dtZ{8XxRz%I&hGC#f!5T1W7$5JjzDBh-Ju*;ph@N|kTq}|#*m@q*=2pE9$kOZ zOgi^Cy4Qxn=EBim<3Kvh{1@hvSh8WC6M)$5u$f0?<+QMR8TaNN5{Pg)3C*TT+CU_T7t*>ctinnqvF)8maYt~b*6zx(QOo_3%o{>}1zQT^Y%G}80oRx`;T6Y^hAuW-4 zh8_1a2Xfaj8?Vx@lph~>perg>GjM5$T{QI_0f}SvGRHu7O3Br-H7zms2hUhRkZqeV zDZ~$s#_y@awWKot+Zan8is<5jXu} zm}46Kz1(TXan79U>u9iXeG-g+-@OMr(gz_|Y=K{#yl;F?@>DM+^H*M+v{G5EE8mh)4CG zD+>`282>hWfDS&88Fp*PfpkUx`

TOqjY62huGAOxBPX7H33E_4|4}Dg=Z9G{k?* z#?JD4(2Nl=>%TXx#0UuR``rHWkd^YVANbfaa-Nsr-sbKiKOt2bF0DKT0To5SmvUK71 z<2hRbU7cUL@tVJU`4Ah`Z-IcLS{vTf@c%P0{FRjftjmNLMrw$o@K5;vXWX*U?*RWs X2Hca>k_)iD`0fE)z;lKX}(E1=i diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 1db7ba5ee5..1026f9cb19 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -416,8 +416,8 @@ F_DT_YEARL2->digit->S_DT_YM2->digit->S_DT_YMM2->sep->F_DT_YMONTH \ \->sep->F_DT_YMONTH \->letter->S_DT_YMON \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->T_DT_WEEK - \->digit->S_DT_WD->eof->T_DT_YWWD - \ \->"T"->S_TM_START + \->"-"->S_DT_YWD->digit->S_DT_WD->eof->T_DT_YWWD + \ \->"T"->S_TM_START \->"T"->S_TM_START F_DT_DDD->"T"->S_TM_START diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 12c5b1b633..1b7f72df8a 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -398,6 +398,46 @@ date: context [ left ] + set-isoweek: func [ + dt [red-date!] + v [integer!] + /local + d [integer!] + wd [integer!] + t? [logic!] + ][ + wd: 0 + d: dt/date + t?: DATE_GET_TIME_FLAG(d) + dt/date: days-to-date v - 1 * 7 + W1-1-of d :wd DATE_GET_ZONE(d) t? + ] + + set-weekday: func [ + dt [red-date!] + v [integer!] + /local + days [integer!] + d [integer!] + t? [logic!] + ][ + d: dt/date + days: date-to-days d + t?: DATE_GET_TIME_FLAG(d) + dt/date: days-to-date days + (v - 1) - (days + 2 % 7) DATE_GET_ZONE(d) t? + ] + + set-yearday: func [ + dt [red-date!] + v [integer!] + /local + d [integer!] + t? [logic!] + ][ + d: dt/date + t?: DATE_GET_TIME_FLAG(d) + dt/date: days-to-date v + (Jan-1st-of d) - 1 DATE_GET_ZONE(d) t? + ] + set-month: func [ dt [red-date!] v [integer!] diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 129caa04bb..c6a37b5fa5 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -96,6 +96,7 @@ Red/System [ S_DT_YV S_DT_YW S_DT_YWW + S_DT_YWD S_DT_WD S_DT_YMON F_DT_YMD @@ -142,31 +143,31 @@ Red/System [ T_TZ_MM ] fields-table: #{ -04040402020101010303030301040909090A0304040303010302020202010105 -0501060601070701080101010B0B010C0101010101010101080B0B0C0C +040404020201010103030303010D090909010A03040403030103020202020101 +050501060601070701080101010B0B010C0101010101010101080B0B0C0C } reset-table: #{ -0101010100000000010001000000000101010101000100000101010100000001 -0000010000010000010000000100000100000000000000000000000000 +0101010100000000010001010000000101000101010001000001010101000000 +010000010000010000010000000100000100000000000000000000000000 } date-transitions: #{ -0130303030303030303030300230070730303030303030300330070730303030 -3030303004300505303030303030303008300505303030303030303008120506 -12303030303030300A123030120E303030303030151830303030303030303030 -09300C0C303030303030303013300C0C30303030303030300B300C0C30303030 -303030300D300C0C303030303030303013303030303030303030303030303030 -1D303030303030330F3030303030303030303030103030303030303030303035 -113030301D30303030303030303030301D3030303030303430120C0C12303030 -3030303014301D301D3030303030303130301D301D3030303030303116301717 -3030303030303030303017173030303030303030193030303030303030303030 -3018171718303030303030301A301E301E303030303030321B301E301E303030 -303030321C301E301E3030303030303230301E301E303030303030321F303030 -30303030303030301F3030303030303030303030203030303030302130303030 -2230303030303021303030302230303030303030303030302330302930302924 -303030362530302930302924303630362530303030303030303030302630302A -30302A30303030373030302A30302A3027373037283030303030303030303030 -2830302B30302B30303830382C30303030303030303030302C30303030303030 -303030302C30303030303030303030302D3030303030302E303030392F303030 -3030302E3030303A2F303030303030303030303B3C303030303030303030303C -303030303030303030303030 +0131313131313131313131310231070731313131313131310331070731313131 +3131313104310506313131313131313108310506313131313131313108133131 +13313131313131310A133131130E313131313131161931313131313131313131 +09310C0C313131313131313114310C0C31313131313131310B310C0C31313131 +313131310D310C0C313131313131313114313131313131313131313131313131 +1E313131313131340F3131313131313131313131103131313131313131313136 +313131111E31313131313136123131311E31313131313131313131311E313131 +3131313531130C0C133131313131313115311E311E3131313131313231311E31 +1E31313131313132173118183131313131313131313118183131313131313131 +1A31313131313131313131313119181819313131313131311B311F311F313131 +313131331C311F311F313131313131331D311F311F3131313131313331311F31 +1F31313131313133203131313131313131313131203131313131313131313131 +2131313131313122313131312331313131313122313131312331313131313131 +313131312431312A31312A25313131372631312A31312A253137313726313131 +31313131313131312731312B31312B31313131383131312B31312B3128383138 +2931313131313131313131312931312C31312C31313931392D31313131313131 +313131312D31313131313131313131312D31313131313131313131312E313131 +3131312F3131313A303131313131312F3131313B30313131313131313131313C +3D313131313131313131313D313131313131313131313131 } transitions: #{ 00001313333435360432020C2727272727270B32202706320132271D26263227 2732310100010101010101010101010101010101010101010101010101010101 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index deeb4ff1b0..83e817eb7e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1105,66 +1105,39 @@ lexer: context [ pos [integer!] month [integer!] time? [logic!] + week? [logic!] + wday? [logic!] + yday? [logic!] ][ -;probe "scan-date" -;probe as-c-string s -;probe as-c-string e time?: flags and C_FLAG_TM_ONLY <> 0 - field: system/stack/allocate/zero 12 + field: system/stack/allocate/zero 13 c: 0 state: either time? [S_TM_START][S_DT_START] loop as-integer e - s [ -;probe ["--- " s/1 " ---"] cp: as-integer s/1 class: as-integer date-classes/cp -;?? class index: state * (size? date-char-classes!) + class state: as-integer date-transitions/index - c: c * 10 + as-integer date-cumul/cp - pos: as-integer fields-table/state field/pos: c -;probe ["field: " c] -;?? pos -;?? state -;?? cp if null-byte = reset-table/state [c: 0] - -;?? c s: s + 1 ] if state <= T_DT_ERROR [ if state = T_DT_ERROR [throw LEX_ERROR] ;-- check here for performance reason - index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index -;?? state pos: as-integer fields-table/state -;?? pos field/pos: c - ] - -comment { - probe [ - "-----------------" - "^/trash: " field/1 - "^/year : " field/2 - "^/month: " field/3 - "^/day : " field/4 - "^/hour : " field/5 - "^/min : " field/6 - "^/sec : " field/7 - "^/nano : " field/8 - "^/week : " field/9 - "^/wday : " field/10 - "^/TZ-h : " field/11 - "^/TZ-m : " field/12 - ] -} + ] unless time? [ - month: field/3 + week?: any [state = T_DT_WEEK field/9 <> 0] + wday?: any [state = T_DT_YWWD field/10 <> 0] + yday?: any [state = T_DT_YDDD field/13 <> 0] + month: either any [week? wday? yday?][1][field/3] + if any [month > 12 month < 1][ ;-- month as a word month: switch month [ ;-- convert hashed word to correct value 8128 81372323 [1] @@ -1181,8 +1154,9 @@ comment { 7557 756474372 [12] default [throw LEX_ERROR 0] ] - field/3: month ;;TBD: add accurate spelling check ] + field/3: month ;;TBD: add accurate spelling check + dt: date/make-at alloc-slot lex field/2 ;-- year @@ -1197,8 +1171,14 @@ comment { state >= T_TM_HM ;-- time was provided if null? dt [throw LEX_ERROR] + if any [week? wday?][date/set-isoweek dt field/9] ;-- yyyy-Www + if wday? [ + c: field/10 + if any [c < 1 c > 7][throw LEX_ERROR] ;-- yyyy-Www-d + date/set-weekday dt c + ] + if yday? [date/set-yearday dt field/13] ;-- yyyy-ddd ] - lex/in-pos: e ;-- reset the input position to delimiter byte field ;-- return field pointer for scan-time ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index f26fec5999..851d55a856 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -103,6 +103,7 @@ context [ ;weekday 10 ;tz-hour 11 ;tz-min 12 + ;yearday 13 ;-- state ----------- reset -- field -- S_DT_START 1 4 ;-- 0 S_DT_D 1 4 ;-- 1 @@ -115,56 +116,57 @@ context [ S_DT_YM 1 3 ;-- 8 S_DT_YMM 0 3 ;-- 9 S_DT_YM2 1 3 ;-- 10 - S_DT_YMM2 0 3 ;-- 11 + S_DT_YMM2 1 3 ;-- 11 F_DT_YMONTH 0 1 ;-- 12 - F_DT_DDD 0 4 ;-- 13 + F_DT_DDD 0 13 ;-- 13 S_DT_YV 0 9 ;-- 14 S_DT_YW 1 9 ;-- 15 S_DT_YWW 1 9 ;-- 16 - S_DT_WD 1 10 ;-- 17 - S_DT_YMON 1 3 ;-- 18 - F_DT_YMD 1 4 ;-- 19 - F_DT_YMDD 0 4 ;-- 20 - S_DT_DM 1 3 ;-- 21 - S_DT_DMM 0 3 ;-- 22 - F_DT_DMONTH 0 1 ;-- 23 - S_DT_DMON 1 3 ;-- 24 - F_DT_DMY 1 2 ;-- 25 - F_DT_DMYY 1 2 ;-- 26 - F_DT_DMYYY 1 2 ;-- 27 - F_DT_DMYYYY 0 2 ;-- 28 - S_TM_START 0 1 ;-- 29 - S_TM_START2 0 1 ;-- 30 - F_TM_H 1 5 ;-- 31 - F_TM_HH 0 5 ;-- 32 - S_TM_HM 0 1 ;-- 33 - F_TM_M 1 6 ;-- 34 - F_TM_MM 0 6 ;-- 35 - S_TM_HMS 0 1 ;-- 36 - F_TM_S 1 7 ;-- 37 - F_TM_SS 0 7 ;-- 38 - F_TM_N1 0 1 ;-- 39 - F_TM_N 1 8 ;-- 40 - S_TM_HMZ 0 1 ;-- 41 - S_TM_HMSZ 0 1 ;-- 42 - S_TM_HMSNZ 0 1 ;-- 43 - S_TZ_H 1 11 ;-- 44 - F_TZ_HH 0 11 ;-- 45 - F_TZ_HM 0 1 ;-- 46 - S_TZ_M 1 12 ;-- 47 - T_DT_ERROR 0 1 ;-- 48 - T_DT_YMDAY 0 1 ;-- 49 - T_DT_DMYEAR 0 1 ;-- 50 - T_DT_YDDD 0 1 ;-- 51 - T_DT_YWWD 0 1 ;-- 52 - T_DT_WEEK 0 1 ;-- 53 - T_TM_HM 0 1 ;-- 54 - T_TM_HMS 0 1 ;-- 55 - T_TM_NZ 0 8 ;-- 56 - T_TZ_H 0 11 ;-- 57 - T_TZ_HH 0 11 ;-- 58 - T_TZ_M 0 12 ;-- 59 - T_TZ_MM 0 12 ;-- 60 + S_DT_YWD 0 1 ;-- 17 + S_DT_WD 1 10 ;-- 18 + S_DT_YMON 1 3 ;-- 19 + F_DT_YMD 1 4 ;-- 20 + F_DT_YMDD 0 4 ;-- 21 + S_DT_DM 1 3 ;-- 22 + S_DT_DMM 0 3 ;-- 23 + F_DT_DMONTH 0 1 ;-- 24 + S_DT_DMON 1 3 ;-- 25 + F_DT_DMY 1 2 ;-- 26 + F_DT_DMYY 1 2 ;-- 27 + F_DT_DMYYY 1 2 ;-- 28 + F_DT_DMYYYY 0 2 ;-- 29 + S_TM_START 0 1 ;-- 30 + S_TM_START2 0 1 ;-- 31 + F_TM_H 1 5 ;-- 32 + F_TM_HH 0 5 ;-- 33 + S_TM_HM 0 1 ;-- 34 + F_TM_M 1 6 ;-- 35 + F_TM_MM 0 6 ;-- 36 + S_TM_HMS 0 1 ;-- 37 + F_TM_S 1 7 ;-- 38 + F_TM_SS 0 7 ;-- 39 + F_TM_N1 0 1 ;-- 40 + F_TM_N 1 8 ;-- 41 + S_TM_HMZ 0 1 ;-- 42 + S_TM_HMSZ 0 1 ;-- 43 + S_TM_HMSNZ 0 1 ;-- 44 + S_TZ_H 1 11 ;-- 45 + F_TZ_HH 0 11 ;-- 46 + F_TZ_HM 0 1 ;-- 47 + S_TZ_M 1 12 ;-- 48 + T_DT_ERROR 0 1 ;-- 49 + T_DT_YMDAY 0 1 ;-- 50 + T_DT_DMYEAR 0 1 ;-- 51 + T_DT_YDDD 0 1 ;-- 52 + T_DT_YWWD 0 1 ;-- 53 + T_DT_WEEK 0 1 ;-- 54 + T_TM_HM 0 1 ;-- 55 + T_TM_HMS 0 1 ;-- 56 + T_TM_NZ 0 8 ;-- 57 + T_TZ_H 0 11 ;-- 58 + T_TZ_HH 0 11 ;-- 59 + T_TZ_M 0 12 ;-- 60 + T_TZ_MM 0 12 ;-- 61 ] CSV-table: %../docs/lexer/lexer-FSM.csv From bd0d05888bcf6b6b85839c91aca44a53c632a8c7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 31 Oct 2019 22:37:48 +0100 Subject: [PATCH 0353/3432] FEAT: minor code improvements. --- runtime/lexer.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 83e817eb7e..38040fd517 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1109,9 +1109,9 @@ lexer: context [ wday? [logic!] yday? [logic!] ][ - time?: flags and C_FLAG_TM_ONLY <> 0 - field: system/stack/allocate/zero 13 - c: 0 + c: 0 ;-- accumulator (numbers decoding) + time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? + field: system/stack/allocate/zero 13 ;-- date/time fields array state: either time? [S_TM_START][S_DT_START] loop as-integer e - s [ @@ -1125,7 +1125,7 @@ lexer: context [ if null-byte = reset-table/state [c: 0] s: s + 1 ] - if state <= T_DT_ERROR [ + if state <= T_DT_ERROR [ ;-- if no terminal state reached, forces EOF input if state = T_DT_ERROR [throw LEX_ERROR] ;-- check here for performance reason index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index From 0329306b9ab330953330fee33aab6fff5bb8ebc0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 31 Oct 2019 23:10:55 +0100 Subject: [PATCH 0354/3432] FIX: removes unnecessary states in date! FSM. --- docs/lexer/date-FSM.csv | 17 ++++------ docs/lexer/lexer-FSM.xlsx | Bin 24297 -> 24138 bytes runtime/lexer-transitions.reds | 48 ++++++++++++--------------- utils/generate-lexer-table.red | 59 ++++++++++++++++----------------- 4 files changed, 57 insertions(+), 67 deletions(-) diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv index b284bc44dc..fdb39c5b19 100644 --- a/docs/lexer/date-FSM.csv +++ b/docs/lexer/date-FSM.csv @@ -25,25 +25,22 @@ S_DT_DM;S_DT_DMM;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_E S_DT_DMM;T_DT_ERROR;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_DT_DMONTH;F_DT_DMY;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_DT_DMON;T_DT_ERROR;S_DT_DMON;F_DT_DMONTH;F_DT_DMONTH;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START2;T_DT_ERROR;S_TM_START2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR +F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_TM_START2;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_TM_HM;T_DT_ERROR;T_TM_HM S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS -F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSZ;T_DT_ERROR;F_TM_N1;T_TM_HMS;T_DT_ERROR;T_TM_HMS +F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS +F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;F_TM_N1;T_TM_HMS;T_DT_ERROR;T_TM_HMS F_TM_N1;F_TM_N;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TM_HMSNZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMSNZ;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ +F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ S_TM_HMZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_TM_HMSZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_TM_HMSNZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR S_TZ_H;F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_H F_TZ_HH;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_M diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 73ec317d8ca8973fbfb5ff9fcd161ad975e5ec0b..d25696cb63a1fba69c47d27f5670c895f7ce35b7 100644 GIT binary patch delta 11447 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 delta 11537 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 U{UN~0SRcuL{~E!l;l Date: Thu, 31 Oct 2019 14:49:05 +0100 Subject: [PATCH 0355/3432] FIX: window shouldn't be always-on-top by deffault. --- modules/view/backends/gtk3/gui.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index ea1b57856c..73487c9504 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1593,7 +1593,6 @@ OS-show-window: func [ ][ show-widget as handle! widget set-selected-focus as handle! widget - gtk_window_set_keep_above as handle! widget true ] OS-make-view: func [ From 1f64df7635d16a698e267553a20de3488460e80b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 1 Nov 2019 10:14:46 +0800 Subject: [PATCH 0356/3432] FIX: issue #4113 (base has no text) --- modules/view/backends/gtk3/font.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index f6e71e9675..a3475b976e 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -59,9 +59,9 @@ create-simple-attrs: func [ rgb: get-color-int color :alpha? r: 0 g: 0 b: 0 a: 0 color-u8-to-u16 rgb :r :g :b :a - attr: pango_attr_foreground_new r g b + attr: pango_attr_background_new r g b pango_attr_list_insert list attr - attr: pango_attr_foreground_alpha_new a + attr: pango_attr_background_alpha_new a pango_attr_list_insert list attr ] list From 268a9454107e3ecfadc2bd014062457c455e470d Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 1 Nov 2019 11:13:39 +0800 Subject: [PATCH 0357/3432] FIX: issue #4113 (panel has no text) --- modules/view/backends/gtk3/gtk.reds | 36 +++++++++++--------- modules/view/backends/gtk3/gui.reds | 53 ++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 35247b3222..53d595fde4 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1499,33 +1499,33 @@ GPtrArray!: alias struct! [ return: [handle!] ] gtk_widget_destroy: "gtk_widget_destroy" [ - widget [handle!] + widget [handle!] ] gtk_widget_create_pango_layout: "gtk_widget_create_pango_layout" [ - widget [handle!] - text [c-string!] - return: [handle!] + widget [handle!] + text [c-string!] + return: [handle!] ] gtk_widget_create_pango_context: "gtk_widget_create_pango_context" [ - widget [handle!] - return: [handle!] + widget [handle!] + return: [handle!] ] gtk_widget_add_events: "gtk_widget_add_events" [ - widget [handle!] - mask [integer!] + widget [handle!] + mask [integer!] ] gtk_widget_get_events: "gtk_widget_get_events" [ - widget [handle!] - return: [integer!] + widget [handle!] + return: [integer!] ] gtk_widget_override_font: "gtk_widget_override_font" [ - widget [handle!] - fd [handle!] + widget [handle!] + fd [handle!] ] gtk_widget_override_color: "gtk_widget_override_color" [ - widget [handle!] - state [integer!] - color [handle!] + widget [handle!] + state [integer!] + color [handle!] ] gtk_container_add: "gtk_container_add" [ container [handle!] @@ -1533,7 +1533,7 @@ GPtrArray!: alias struct! [ ] gtk_container_get_children: "gtk_container_get_children" [ container [handle!] - return: [int-ptr!] + return: [GList!] ] gtk_container_foreach: "gtk_container_foreach" [ container [handle!] @@ -1772,6 +1772,10 @@ GPtrArray!: alias struct! [ widget [handle!] list [handle!] ] + gtk_label_get_layout: "gtk_label_get_layout" [ + label [handle!] + return: [handle!] + ] gtk_event_box_new: "gtk_event_box_new" [ return: [handle!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 73487c9504..f7a43f6383 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -902,7 +902,7 @@ change-pane: func [ ] unless null? layout [ - list: as GList! gtk_container_get_children layout + list: gtk_container_get_children layout child: list while [not null? child][ g_object_ref child/data ;-- to avoid destruction before removing from container @@ -958,6 +958,12 @@ change-size: func [ ntype [red-word!] sym [integer!] layout [handle!] + str [red-string!] + list [GList!] + label [handle!] + pl [handle!] + x [integer!] + y [integer!] ][ either type = window [ gtk_window_set_default_size widget size/x size/y @@ -974,6 +980,20 @@ change-size: func [ ] gtk_widget_set_size_request widget size/x size/y gtk_widget_queue_resize widget + + if type = panel [ + str: as red-string! values + FACE_OBJ_TEXT + if TYPE_OF(str) = TYPE_STRING [ + list: gtk_container_get_children widget + label: list/data + pl: gtk_label_get_layout label + x: 0 y: 0 + pango_layout_get_pixel_size pl :x :y + x: either size/x > x [size/x - x / 2][0] + y: either size/y > y [size/y - y / 2][0] + gtk_layout_move widget label x y + ] + ] ] ] @@ -1618,6 +1638,7 @@ OS-make-view: func [ flags [integer!] bits [integer!] rate [red-value!] + color [red-tuple!] sym [integer!] p-sym [integer!] caption [c-string!] @@ -1631,6 +1652,11 @@ OS-make-view: func [ fvalue [float!] vertical? [logic!] rfvalue [red-float!] + attrs [handle!] + newF? [logic!] + layout [handle!] + x [integer!] + y [integer!] ][ stack/mark-native words/_body @@ -1649,6 +1675,7 @@ OS-make-view: func [ selected: as red-integer! values + FACE_OBJ_SELECTED para: as red-object! values + FACE_OBJ_PARA rate: as red-value! values + FACE_OBJ_RATE + color: as red-tuple! values + FACE_OBJ_COLOR bits: get-flags as red-block! values + FACE_OBJ_FLAGS sym: symbol/resolve type/symbol @@ -1827,6 +1854,30 @@ OS-make-view: func [ make-styles-provider widget change-font widget face values + if all [ + sym = panel + not null? caption + ][ + attrs: get-attrs face font + newF?: false + if null? attrs [ + newF?: true + attrs: create-simple-attrs default-font-name default-font-size color + ] + buffer: gtk_label_new caption + gtk_widget_show buffer + set-label-attrs buffer font attrs + layout: gtk_label_get_layout buffer + x: 0 y: 0 + pango_layout_get_pixel_size layout :x :y + x: either size/x > x [size/x - x / 2][0] + y: either size/y > y [size/y - y / 2][0] + gtk_layout_put widget buffer x y + if newF? [ + free-pango-attrs attrs + ] + ] + if sym <> window [ if parent <> 0 [ unless set-widget-child as handle! parent widget offset [ From 86e99c3390cc3b36552500da6253b853058cac0d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 12:14:24 +0100 Subject: [PATCH 0358/3432] FEAT: experimental date! special fields positions detection during scanning. --- runtime/lexer-transitions.reds | 41 +++++----- runtime/lexer.reds | 6 +- utils/generate-lexer-table.red | 133 +++++++++++++++++---------------- 3 files changed, 96 insertions(+), 84 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 47708947d4..f80c938552 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -139,31 +139,34 @@ Red/System [ T_TZ_M T_TZ_MM ] - fields-table: #{ + fields-ptr-table: #{ +01010101010E0E0E01010101010101010101010F010101010101010101010101 +010101010101010101100101010101010101010101010101010101 +} fields-table: #{ 040404020201010103030303010D090909010A03040403030103020202020105 050106060107070108010B0B010C0101010101010101080B0B0C0C } reset-table: #{ 0101010100000000010001010000000101000101010001000001010101000001 000001000001000001000100000100000000000000000000000000 } date-transitions: #{ -012E2E2E2E2E2E2E2E2E2E2E022E07072E2E2E2E2E2E2E2E032E07072E2E2E2E -2E2E2E2E042E05062E2E2E2E2E2E2E2E082E05062E2E2E2E2E2E2E2E08132E2E -132E2E2E2E2E2E2E0A132E2E130E2E2E2E2E2E2E16192E2E2E2E2E2E2E2E2E2E -092E0C0C2E2E2E2E2E2E2E2E142E0C0C2E2E2E2E2E2E2E2E0B2E0C0C2E2E2E2E -2E2E2E2E0D2E0C0C2E2E2E2E2E2E2E2E142E2E2E2E2E2E2E2E2E2E2E2E2E2E2E -1E2E2E2E2E2E2E310F2E2E2E2E2E2E2E2E2E2E2E102E2E2E2E2E2E2E2E2E2E33 -2E2E2E111E2E2E2E2E2E2E33122E2E2E1E2E2E2E2E2E2E2E2E2E2E2E1E2E2E2E -2E2E2E322E130C0C132E2E2E2E2E2E2E152E1E2E1E2E2E2E2E2E2E2F2E2E1E2E -1E2E2E2E2E2E2E2F172E18182E2E2E2E2E2E2E2E2E2E18182E2E2E2E2E2E2E2E -1A2E2E2E2E2E2E2E2E2E2E2E2E191818192E2E2E2E2E2E2E1B2E1E2E1E2E2E2E -2E2E2E301C2E1E2E1E2E2E2E2E2E2E301D2E1E2E1E2E2E2E2E2E2E302E2E1E2E -1E2E2E2E2E2E2E301F2E2E2E2E2E2E2E2E2E2E2E202E2E2E2E2E2E212E2E2E2E -222E2E2E2E2E2E212E2E2E2E222E2E2E2E2E2E2E2E2E2E2E232E2E292E2E2924 -2E2E2E34252E2E292E2E29242E342E34252E2E2E2E2E2E2E2E2E2E2E262E2E29 -2E2E292E2E2E2E352E2E2E292E2E292E27352E35282E2E2E2E2E2E2E2E2E2E2E -282E2E292E2E292E2E362E362A2E2E2E2E2E2E2E2E2E2E2E2B2E2E2E2E2E2E2C -2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E -2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E +002D2D2D2D2D2D2D2D2D2D2D012D06062D2D2D2D2D2D2D2D022D06062D2D2D2D +2D2D2D2D032D04052D2D2D2D2D2D2D2D072D04052D2D2D2D2D2D2D2D07122D2D +122D2D2D2D2D2D2D09122D2D120D2D2D2D2D2D2D15182D2D2D2D2D2D2D2D2D2D +082D0B0B2D2D2D2D2D2D2D2D132D0B0B2D2D2D2D2D2D2D2D0A2D0B0B2D2D2D2D +2D2D2D2D0C2D0B0B2D2D2D2D2D2D2D2D132D2D2D2D2D2D2D2D2D2D2D2D2D2D2D +1D2D2D2D2D2D2D300E2D2D2D2D2D2D2D2D2D2D2D0F2D2D2D2D2D2D2D2D2D2D32 +2D2D2D101D2D2D2D2D2D2D32112D2D2D1D2D2D2D2D2D2D2D2D2D2D2D1D2D2D2D +2D2D2D312D120B0B122D2D2D2D2D2D2D142D1D2D1D2D2D2D2D2D2D2E2D2D1D2D +1D2D2D2D2D2D2D2E162D17172D2D2D2D2D2D2D2D2D2D17172D2D2D2D2D2D2D2D +192D2D2D2D2D2D2D2D2D2D2D2D181717182D2D2D2D2D2D2D1A2D1D2D1D2D2D2D +2D2D2D2F1B2D1D2D1D2D2D2D2D2D2D2F1C2D1D2D1D2D2D2D2D2D2D2F2D2D1D2D +1D2D2D2D2D2D2D2F1E2D2D2D2D2D2D2D2D2D2D2D1F2D2D2D2D2D2D202D2D2D2D +212D2D2D2D2D2D202D2D2D2D212D2D2D2D2D2D2D2D2D2D2D222D2D282D2D2823 +2D2D2D33242D2D282D2D28232D332D33242D2D2D2D2D2D2D2D2D2D2D252D2D28 +2D2D282D2D2D2D342D2D2D282D2D282D26342D34272D2D2D2D2D2D2D2D2D2D2D +272D2D282D2D282D2D352D35292D2D2D2D2D2D2D2D2D2D2D2A2D2D2D2D2D2D2B +2D2D2D362C2D2D2D2D2D2D2B2D2D2D372C2D2D2D2D2D2D2D2D2D2D38392D2D2D +2D2D2D2D2D2D2D392D2D2D2D2D2D2D2D2D2D2D2D } transitions: #{ 00001313333435360432020C2727272727270B32202706320132271D26263227 2732310100010101010101010101010101010101010101010101010101010101 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 38040fd517..7588373343 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1111,9 +1111,9 @@ lexer: context [ ][ c: 0 ;-- accumulator (numbers decoding) time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? - field: system/stack/allocate/zero 13 ;-- date/time fields array + field: system/stack/allocate/zero 16 ;-- date/time fields array state: either time? [S_TM_START][S_DT_START] - + loop as-integer e - s [ cp: as-integer s/1 class: as-integer date-classes/cp @@ -1122,6 +1122,8 @@ lexer: context [ c: c * 10 + as-integer date-cumul/cp pos: as-integer fields-table/state field/pos: c + pos: as-integer fields-ptr-table/state + field/pos: as-integer s if null-byte = reset-table/state [c: 0] s: s + 1 ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index f671466d60..2fd29499eb 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -104,66 +104,69 @@ context [ ;tz-hour 11 ;tz-min 12 ;yearday 13 - ;-- state ----------- reset -- field -- - S_DT_START 1 4 ;-- 0 - S_DT_D 1 4 ;-- 1 - S_DT_DD 1 4 ;-- 2 - S_DT_YYY 1 2 ;-- 3 - S_DT_YYYY 0 2 ;-- 4 - F_DT_YEARL 0 1 ;-- 5 - F_DT_YEARL2 0 1 ;-- 6 - F_DT_DAYL 0 1 ;-- 7 - S_DT_YM 1 3 ;-- 8 - S_DT_YMM 0 3 ;-- 9 - S_DT_YM2 1 3 ;-- 10 - S_DT_YMM2 1 3 ;-- 11 - F_DT_YMONTH 0 1 ;-- 12 - F_DT_DDD 0 13 ;-- 13 - S_DT_YV 0 9 ;-- 14 - S_DT_YW 1 9 ;-- 15 - S_DT_YWW 1 9 ;-- 16 - S_DT_YWD 0 1 ;-- 17 - S_DT_WD 1 10 ;-- 18 - S_DT_YMON 1 3 ;-- 19 - F_DT_YMD 1 4 ;-- 20 - F_DT_YMDD 0 4 ;-- 21 - S_DT_DM 1 3 ;-- 22 - S_DT_DMM 0 3 ;-- 23 - F_DT_DMONTH 0 1 ;-- 24 - S_DT_DMON 1 3 ;-- 25 - F_DT_DMY 1 2 ;-- 26 - F_DT_DMYY 1 2 ;-- 27 - F_DT_DMYYY 1 2 ;-- 28 - F_DT_DMYYYY 0 2 ;-- 29 - S_TM_START 0 1 ;-- 30 - F_TM_H 1 5 ;-- 31 - F_TM_HH 0 5 ;-- 32 - S_TM_HM 0 1 ;-- 33 - F_TM_M 1 6 ;-- 34 - F_TM_MM 0 6 ;-- 35 - S_TM_HMS 0 1 ;-- 36 - F_TM_S 1 7 ;-- 37 - F_TM_SS 0 7 ;-- 38 - F_TM_N1 0 1 ;-- 39 - F_TM_N 1 8 ;-- 40 - S_TM_HMZ 0 1 ;-- 41 - S_TZ_H 1 11 ;-- 42 - F_TZ_HH 0 11 ;-- 43 - F_TZ_HM 0 1 ;-- 44 - S_TZ_M 1 12 ;-- 45 - T_DT_ERROR 0 1 ;-- 46 - T_DT_YMDAY 0 1 ;-- 47 - T_DT_DMYEAR 0 1 ;-- 48 - T_DT_YDDD 0 1 ;-- 49 - T_DT_YWWD 0 1 ;-- 50 - T_DT_WEEK 0 1 ;-- 51 - T_TM_HM 0 1 ;-- 52 - T_TM_HMS 0 1 ;-- 53 - T_TM_NZ 0 8 ;-- 54 - T_TZ_H 0 11 ;-- 55 - T_TZ_HH 0 11 ;-- 56 - T_TZ_M 0 12 ;-- 57 - T_TZ_MM 0 12 ;-- 58 + ;word-start 14 + ;word-end 15 + ;TZ-sign 16 + ;-- state ----------- reset -- field -- ptr -- + S_DT_START 1 4 1 ;-- 0 + S_DT_D 1 4 1 ;-- 1 + S_DT_DD 1 4 1 ;-- 2 + S_DT_YYY 1 2 1 ;-- 3 + S_DT_YYYY 0 2 1 ;-- 4 + F_DT_YEARL 0 1 14 ;-- 5 + F_DT_YEARL2 0 1 14 ;-- 6 + F_DT_DAYL 0 1 14 ;-- 7 + S_DT_YM 1 3 1 ;-- 8 + S_DT_YMM 0 3 1 ;-- 9 + S_DT_YM2 1 3 1 ;-- 10 + S_DT_YMM2 1 3 1 ;-- 11 + F_DT_YMONTH 0 1 1 ;-- 12 + F_DT_DDD 0 13 1 ;-- 13 + S_DT_YV 0 9 1 ;-- 14 + S_DT_YW 1 9 1 ;-- 15 + S_DT_YWW 1 9 1 ;-- 16 + S_DT_YWD 0 1 1 ;-- 17 + S_DT_WD 1 10 1 ;-- 18 + S_DT_YMON 1 3 15 ;-- 19 + F_DT_YMD 1 4 1 ;-- 20 + F_DT_YMDD 0 4 1 ;-- 21 + S_DT_DM 1 3 1 ;-- 22 + S_DT_DMM 0 3 1 ;-- 23 + F_DT_DMONTH 0 1 1 ;-- 24 + S_DT_DMON 1 3 1 ;-- 25 + F_DT_DMY 1 2 1 ;-- 26 + F_DT_DMYY 1 2 1 ;-- 27 + F_DT_DMYYY 1 2 1 ;-- 28 + F_DT_DMYYYY 0 2 1 ;-- 29 + S_TM_START 0 1 1 ;-- 30 + F_TM_H 1 5 1 ;-- 31 + F_TM_HH 0 5 1 ;-- 32 + S_TM_HM 0 1 1 ;-- 33 + F_TM_M 1 6 1 ;-- 34 + F_TM_MM 0 6 1 ;-- 35 + S_TM_HMS 0 1 1 ;-- 36 + F_TM_S 1 7 1 ;-- 37 + F_TM_SS 0 7 1 ;-- 38 + F_TM_N1 0 1 1 ;-- 39 + F_TM_N 1 8 1 ;-- 40 + S_TM_HMZ 0 1 16 ;-- 41 + S_TZ_H 1 11 1 ;-- 42 + F_TZ_HH 0 11 1 ;-- 43 + F_TZ_HM 0 1 1 ;-- 44 + S_TZ_M 1 12 1 ;-- 45 + T_DT_ERROR 0 1 1 ;-- 46 + T_DT_YMDAY 0 1 1 ;-- 47 + T_DT_DMYEAR 0 1 1 ;-- 48 + T_DT_YDDD 0 1 1 ;-- 49 + T_DT_YWWD 0 1 1 ;-- 50 + T_DT_WEEK 0 1 1 ;-- 51 + T_TM_HM 0 1 1 ;-- 52 + T_TM_HMS 0 1 1 ;-- 53 + T_TM_NZ 0 8 1 ;-- 54 + T_TZ_H 0 11 1 ;-- 55 + T_TZ_HH 0 11 1 ;-- 56 + T_TZ_M 0 12 1 ;-- 57 + T_TZ_MM 0 12 1 ;-- 58 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -210,17 +213,19 @@ context [ dt-table: make binary! 2000 reset-table: make binary! 100 fields-table: make binary! 100 + fields-ptr-table: make binary! 100 - foreach [state reset pos] date-states [ + foreach [state reset pos ptr] date-states [ append reset-table to-char reset append fields-table to-char pos + append fields-ptr-table to-char ptr ] foreach line next matrix [ out: make block! 50 foreach s next line [ either pos: find date-states to-word s [ - append out ((2 + index? pos) / 3) - 1 + append out ((2 + index? pos) / 4) - 1 ][ do make error! form reduce ["Error: state" s "not found"] ] @@ -237,9 +242,11 @@ context [ ] #enum date-states! [ - (extract date-states 3) + (extract date-states 4) ] + fields-ptr-table: (fields-ptr-table) + fields-table: (fields-table) reset-table: (reset-table) From f8dd8f035c1ee12d0f359ad9cfa12db0f4c79fb2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 13:03:27 +0100 Subject: [PATCH 0359/3432] FIX: excludes C_BIN class from date! literals detection. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 24138 -> 24291 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 43c70abde1..a0353efd14 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -23,7 +23,7 @@ S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_F S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_DATE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index d25696cb63a1fba69c47d27f5670c895f7ce35b7..f4dc8339cece1b5bda290b0f0679c68badae00ea 100644 GIT binary patch literal 24291 zcmeFZbyQs0w=Il2!8N!;aCdiicXubayGwBQ;O+zo?hrJ1aCi5wNcX+ByMO)Oc<=A` z)fiPZYScNk_L4d0+UM+D@=~B+s6Y@vP(VOHgg|9?>V@vWKtQMvKtL!!P#{`DcDBwY zw$6IW?)D~5I<#&!)&%)rAQZVkAb{il|HuEs5g1b*w(X%u>`*)86Yf;)<1Z>JgTiUU z(IVN0Om!2aMqa*zLw)T;sV^y058}6^3pey!V?^m%)7MZN1_8k~WBMVnOaz?4Wpm7o zlC#x3UmzZrI9KL~&R7eA8u)r5WB2XS4_ZxYOju$&r?Br^kfy;QxB42Tb_v>rS*m39 zWm4 zB6_xSb$F|>I7RUJEvSJ@suc0zm_m>cYZ*`->CF6KCW%*DBwHC_dZ*pK8681lrf2n5 zvAW=M$LKSY2%+uk%pL2{etOvHvEE#v=K0`gYh@TYt%=n>=N-g{CyJ$)^$FJES>zX! zi}PD}%oE?VfY%=Xz}^mVI6XOpUqcyC^~*=mDW$O@m|U^GW_J%4V7}VegI{4-5PR`T z)ZGs{KSf2ARxjbe{NauTjn;RT863fMS3a9Fss^t0(ij!rbpdes_67V)YzNtexm+-(UZKr2an)&%d}{ksu@2OAi-vCjJ~cbT_vehbSoJDj?oY zsO;k>v4YSTT|n}2wTm1FQ5icBRLr--=Xqp#l{@-yi12okxgru7m5aE^wK62-(ZL0h zip()t)S+Ud59#yV&D?F8n4~+!=Z;va@|Kc3so`~E(U}Y3TEt0OHEd{V*xovWRrm7$%T)w`q>s@T|N&?CO`TD*O~a)k*A zGNv%LTx*bAR(8>OB30bMBv%K|SR|8Bx#>ESmYinIm~Et}W!Up{J3ZxKy04>wZP;Cc zB2|)>1&L}grb2N{+SE&7s*a7XRW@yqPxyKt^YPi_{-RgE;QBQhB}G1G`L9jp?Eselx%M$IT#;8;5bED{F{*YwH5uWBPC`Ig=&iS5^mTo zcq9M%c0MDG=CCfPnxeOs8lI8~I3lb9l;?t

o}}HEB|DBuLL%0_~FJeg8Q*Fr2{? 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 P1|cB)2OMuViv;lijC(Yj diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index f80c938552..1fed893d79 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -195,7 +195,7 @@ Red/System [ 3242424242424242424242424216424216161616424242164242424216421616 4216163231434317174343434343434332324332323232433243323232323217 3232323232323243444418184444444444444418181818181818181844184418 -444418441818441818324432321A1A3232323232323232323232323232323232 +444418441818443218324432321A1A3232323232323232323232323232323232 323232323232323232323232323246461A1A4646464646464632321A32323232 46324632323246321A323232323232324632321C1C3232323232323232323232 323232323232323232323232323232323232323245451C1C4545454545454532 From a77825698a060a20226dc6bf48e155f42bc6840a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 13:28:38 +0100 Subject: [PATCH 0360/3432] FIX: date-transitions table generated values off by one. --- runtime/lexer-transitions.reds | 36 +++++++++++++++++----------------- runtime/lexer.reds | 2 ++ utils/generate-lexer-table.red | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 1fed893d79..3310b1953e 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -149,24 +149,24 @@ Red/System [ 0101010100000000010001010000000101000101010001000001010101000001 000001000001000001000100000100000000000000000000000000 } date-transitions: #{ -002D2D2D2D2D2D2D2D2D2D2D012D06062D2D2D2D2D2D2D2D022D06062D2D2D2D -2D2D2D2D032D04052D2D2D2D2D2D2D2D072D04052D2D2D2D2D2D2D2D07122D2D -122D2D2D2D2D2D2D09122D2D120D2D2D2D2D2D2D15182D2D2D2D2D2D2D2D2D2D -082D0B0B2D2D2D2D2D2D2D2D132D0B0B2D2D2D2D2D2D2D2D0A2D0B0B2D2D2D2D -2D2D2D2D0C2D0B0B2D2D2D2D2D2D2D2D132D2D2D2D2D2D2D2D2D2D2D2D2D2D2D -1D2D2D2D2D2D2D300E2D2D2D2D2D2D2D2D2D2D2D0F2D2D2D2D2D2D2D2D2D2D32 -2D2D2D101D2D2D2D2D2D2D32112D2D2D1D2D2D2D2D2D2D2D2D2D2D2D1D2D2D2D -2D2D2D312D120B0B122D2D2D2D2D2D2D142D1D2D1D2D2D2D2D2D2D2E2D2D1D2D -1D2D2D2D2D2D2D2E162D17172D2D2D2D2D2D2D2D2D2D17172D2D2D2D2D2D2D2D -192D2D2D2D2D2D2D2D2D2D2D2D181717182D2D2D2D2D2D2D1A2D1D2D1D2D2D2D -2D2D2D2F1B2D1D2D1D2D2D2D2D2D2D2F1C2D1D2D1D2D2D2D2D2D2D2F2D2D1D2D -1D2D2D2D2D2D2D2F1E2D2D2D2D2D2D2D2D2D2D2D1F2D2D2D2D2D2D202D2D2D2D -212D2D2D2D2D2D202D2D2D2D212D2D2D2D2D2D2D2D2D2D2D222D2D282D2D2823 -2D2D2D33242D2D282D2D28232D332D33242D2D2D2D2D2D2D2D2D2D2D252D2D28 -2D2D282D2D2D2D342D2D2D282D2D282D26342D34272D2D2D2D2D2D2D2D2D2D2D -272D2D282D2D282D2D352D35292D2D2D2D2D2D2D2D2D2D2D2A2D2D2D2D2D2D2B -2D2D2D362C2D2D2D2D2D2D2B2D2D2D372C2D2D2D2D2D2D2D2D2D2D38392D2D2D -2D2D2D2D2D2D2D392D2D2D2D2D2D2D2D2D2D2D2D +012E2E2E2E2E2E2E2E2E2E2E022E07072E2E2E2E2E2E2E2E032E07072E2E2E2E +2E2E2E2E042E05062E2E2E2E2E2E2E2E082E05062E2E2E2E2E2E2E2E08132E2E +132E2E2E2E2E2E2E0A132E2E130E2E2E2E2E2E2E16192E2E2E2E2E2E2E2E2E2E +092E0C0C2E2E2E2E2E2E2E2E142E0C0C2E2E2E2E2E2E2E2E0B2E0C0C2E2E2E2E +2E2E2E2E0D2E0C0C2E2E2E2E2E2E2E2E142E2E2E2E2E2E2E2E2E2E2E2E2E2E2E +1E2E2E2E2E2E2E310F2E2E2E2E2E2E2E2E2E2E2E102E2E2E2E2E2E2E2E2E2E33 +2E2E2E111E2E2E2E2E2E2E33122E2E2E1E2E2E2E2E2E2E2E2E2E2E2E1E2E2E2E +2E2E2E322E130C0C132E2E2E2E2E2E2E152E1E2E1E2E2E2E2E2E2E2F2E2E1E2E +1E2E2E2E2E2E2E2F172E18182E2E2E2E2E2E2E2E2E2E18182E2E2E2E2E2E2E2E +1A2E2E2E2E2E2E2E2E2E2E2E2E191818192E2E2E2E2E2E2E1B2E1E2E1E2E2E2E +2E2E2E301C2E1E2E1E2E2E2E2E2E2E301D2E1E2E1E2E2E2E2E2E2E302E2E1E2E +1E2E2E2E2E2E2E301F2E2E2E2E2E2E2E2E2E2E2E202E2E2E2E2E2E212E2E2E2E +222E2E2E2E2E2E212E2E2E2E222E2E2E2E2E2E2E2E2E2E2E232E2E292E2E2924 +2E2E2E34252E2E292E2E29242E342E34252E2E2E2E2E2E2E2E2E2E2E262E2E29 +2E2E292E2E2E2E352E2E2E292E2E292E27352E35282E2E2E2E2E2E2E2E2E2E2E +282E2E292E2E292E2E362E362A2E2E2E2E2E2E2E2E2E2E2E2B2E2E2E2E2E2E2C +2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E +2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ 00001313333435360432020C2727272727270B32202706320132271D26263227 2732310100010101010101010101010101010101010101010101010101010101 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7588373343..ee2dbda3b6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1385,6 +1385,7 @@ lexer: context [ lex/line: line lex/nline: line - mark + assert start + offset <= p index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags @@ -1442,6 +1443,7 @@ lexer: context [ date-transitions: date-transitions + 1 date-cumul: date-cumul + 1 fields-table: fields-table + 1 + fields-ptr-table: fields-ptr-table + 1 reset-table: reset-table + 1 ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 2fd29499eb..d951e6d352 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -225,7 +225,7 @@ context [ out: make block! 50 foreach s next line [ either pos: find date-states to-word s [ - append out ((2 + index? pos) / 4) - 1 + append out ((3 + index? pos) / 4) - 1 ][ do make error! form reduce ["Error: state" s "not found"] ] From 0a3435835c7f77968da946f9d322785d289deb16 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 17:20:41 +0100 Subject: [PATCH 0361/3432] FEAT: accurate parsing of month names in dates. --- runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 39 +++++++++++++++++++--------------- utils/generate-lexer-table.red | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 3310b1953e..fbd3bf3a73 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -140,7 +140,7 @@ Red/System [ T_TZ_MM ] fields-ptr-table: #{ -01010101010E0E0E01010101010101010101010F010101010101010101010101 +01010101010E0E0E01010101010101010101010F01010101010F010101010101 010101010101010101100101010101010101010101010101010101 } fields-table: #{ 040404020201010103030303010D090909010A03040403030103020202020105 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ee2dbda3b6..adfd0a571a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -176,6 +176,11 @@ lexer: context [ ;... to be eventually completed ] + months: [ + "January" "February" "March" "April" "May" "June" "July" + "August" "September" "October" "November" "December" + ] + date-cumul: #{ 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000010203040506070809000000000000 @@ -1096,6 +1101,9 @@ lexer: context [ return: [int-ptr!] /local dt [red-date!] + ms [byte-ptr!] + me [byte-ptr!] + m [int-ptr!] field [int-ptr!] state [integer!] class [integer!] @@ -1103,6 +1111,7 @@ lexer: context [ cp [integer!] c [integer!] pos [integer!] + len [integer!] month [integer!] time? [logic!] week? [logic!] @@ -1138,23 +1147,19 @@ lexer: context [ week?: any [state = T_DT_WEEK field/9 <> 0] wday?: any [state = T_DT_YWWD field/10 <> 0] yday?: any [state = T_DT_YDDD field/13 <> 0] - month: either any [week? wday? yday?][1][field/3] - - if any [month > 12 month < 1][ ;-- month as a word - month: switch month [ ;-- convert hashed word to correct value - 8128 81372323 [1] - 7756 776512323 [2] - 8432 843942 [3] - 7382 739006 [4] - 8353 [5] ;-- "May" has no longer form - 8328 83349 [6] - 8326 83263 [7] - 7421 7430330 [8] - 9070 480839780 [9] - 8570 85786372 [10] - 8676 868374372 [11] - 7557 756474372 [12] - default [throw LEX_ERROR 0] + month: either any [week? wday? yday?][1][ + ms: as byte-ptr! field/14 + 1 + me: as byte-ptr! field/15 + either null? me [field/3][ ;-- month is numeric + len: as-integer me - ms + 1 + if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name + m: months + loop 12 [ + if zero? platform/strnicmp ms as byte-ptr! m/1 len [break] + m: m + 1 + ] + if months + 12 = m [throw LEX_ERROR] ;-- invalid month name + (as-integer m - months) >> 2 + 1 ] ] field/3: month ;;TBD: add accurate spelling check diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index d951e6d352..df220789ac 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -133,7 +133,7 @@ context [ S_DT_DM 1 3 1 ;-- 22 S_DT_DMM 0 3 1 ;-- 23 F_DT_DMONTH 0 1 1 ;-- 24 - S_DT_DMON 1 3 1 ;-- 25 + S_DT_DMON 1 3 15 ;-- 25 F_DT_DMY 1 2 1 ;-- 26 F_DT_DMYY 1 2 1 ;-- 27 F_DT_DMYYY 1 2 1 ;-- 28 From 2de077115bf3f11e6be41470de46b817b82123ec Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 18:29:44 +0100 Subject: [PATCH 0362/3432] FEAT: stricter and faster date! creation code for the lexical scanner. --- runtime/datatypes/date.reds | 48 +++++++++++-------------------------- runtime/lexer.reds | 16 ++++++++----- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 1b7f72df8a..c355a8480c 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -533,6 +533,7 @@ date: context [ tz-h [integer!] tz-m [integer!] time? [logic!] + neg-TZ? [logic!] return: [red-date!] /local dt [red-date!] @@ -540,47 +541,26 @@ date: context [ d [integer!] h [integer!] i [integer!] - zone[integer!] - neg?[logic!] + z [integer!] ][ if year < 100 [ ;-- expand short yy forms d: either year < 50 [2000][1900] year: year + d ] - set-type slot TYPE_DATE ;-- preserve eventual flags in the header - dt: as red-date! slot - dt/date: DATE_SET_YEAR(0 year) - set-month dt month - dt/date: days-to-date day + date-to-days dt/date 0 time? - - t: (3600.0 * as float! hour) - + (60.0 * as float! min) - + ( as float! sec) - + (1e-9 * as float! nsec) - - set-time dt t no - - d: dt/date - h: time/get-hours t if any [ - year <> DATE_GET_YEAR(d) - month <> DATE_GET_MONTH(d) - day <> DATE_GET_DAY(d) - all [t <> 0.0 any [ - h < 0 h > 23 - min <> time/get-minutes dt/time - ]] - all [t = 0.0 any [ - hour <> time/get-hours dt/time - min <> time/get-minutes dt/time - ]] + day > 31 month > 12 year > 9999 + tz-h > 15 tz-h < -15 ;-- out of range TZ + hour > 23 min > 59 sec > 59 + all [day = 29 month = 2 not leap-year? year] ][return null] - - neg?: either tz-h < 0 [tz-h: 0 - tz-h yes][no] - zone: tz-h << 2 and 7Fh or (tz-m / 15) - if neg? [zone: DATE_SET_ZONE_NEG(zone)] - dt/date: DATE_SET_ZONE(dt/date zone) - set-time dt dt/time yes + + dt: as red-date! slot + set-all dt year month day hour min sec nsec + + z: tz-h << 2 and 7Fh or (tz-m / 15) + if neg-TZ? [z: DATE_SET_ZONE_NEG(z)] + dt/date: DATE_SET_ZONE(dt/date z) + unless time? [dt/date: DATE_CLEAR_TIME_FLAG(dt/date)] dt ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index adfd0a571a..f4e454542a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1101,7 +1101,7 @@ lexer: context [ return: [int-ptr!] /local dt [red-date!] - ms [byte-ptr!] + p [byte-ptr!] me [byte-ptr!] m [int-ptr!] field [int-ptr!] @@ -1117,6 +1117,7 @@ lexer: context [ week? [logic!] wday? [logic!] yday? [logic!] + neg? [logic!] ][ c: 0 ;-- accumulator (numbers decoding) time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? @@ -1148,21 +1149,23 @@ lexer: context [ wday?: any [state = T_DT_YWWD field/10 <> 0] yday?: any [state = T_DT_YDDD field/13 <> 0] month: either any [week? wday? yday?][1][ - ms: as byte-ptr! field/14 + 1 + p: as byte-ptr! field/14 + 1 me: as byte-ptr! field/15 either null? me [field/3][ ;-- month is numeric - len: as-integer me - ms + 1 + len: as-integer me - p + 1 if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name m: months loop 12 [ - if zero? platform/strnicmp ms as byte-ptr! m/1 len [break] + if zero? platform/strnicmp p as byte-ptr! m/1 len [break] m: m + 1 ] if months + 12 = m [throw LEX_ERROR] ;-- invalid month name (as-integer m - months) >> 2 + 1 ] ] - field/3: month ;;TBD: add accurate spelling check + field/3: month + p: as byte-ptr! field/16 + neg?: all [p <> null p/1 = #"-"] dt: date/make-at alloc-slot lex @@ -1175,7 +1178,8 @@ lexer: context [ field/8 ;-- nano field/11 ;-- TZ hour field/12 ;-- TZ min - state >= T_TM_HM ;-- time was provided + state >= T_TM_HM ;-- date/time input + neg? ;-- negative TZ flag if null? dt [throw LEX_ERROR] if any [week? wday?][date/set-isoweek dt field/9] ;-- yyyy-Www From 970438ad45155da5e99f6762bb7f0bf49466c428 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 19:36:07 +0100 Subject: [PATCH 0363/3432] FEAT: refactors scan-date for setting a fast-path for most common date formats. --- runtime/lexer.reds | 85 ++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f4e454542a..f807a54cb8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1114,9 +1114,6 @@ lexer: context [ len [integer!] month [integer!] time? [logic!] - week? [logic!] - wday? [logic!] - yday? [logic!] neg? [logic!] ][ c: 0 ;-- accumulator (numbers decoding) @@ -1145,13 +1142,38 @@ lexer: context [ field/pos: c ] unless time? [ - week?: any [state = T_DT_WEEK field/9 <> 0] - wday?: any [state = T_DT_YWWD field/10 <> 0] - yday?: any [state = T_DT_YDDD field/13 <> 0] - month: either any [week? wday? yday?][1][ - p: as byte-ptr! field/14 + 1 - me: as byte-ptr! field/15 - either null? me [field/3][ ;-- month is numeric + p: as byte-ptr! field/16 + neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ + + either any [field/9 <> 0 field/10 <> 0 field/13 <> 0][ ;-- special ISO formats + dt: date/make-at + alloc-slot lex + field/2 ;-- year + 1 ;-- month + 1 ;-- day + field/5 ;-- hour + field/6 ;-- min + field/7 ;-- sec + field/8 ;-- nano + field/11 ;-- TZ hour + field/12 ;-- TZ min + state >= T_TM_HM ;-- date/time input + neg? ;-- negative TZ flag + + if null? dt [throw LEX_ERROR] + if any [field/9 <> 0 field/10 <> 0][ ;-- yyyy-Www + date/set-isoweek dt field/9 + ] + c: field/10 + if c <> 0 [ ;-- yyyy-Www-d + if any [c < 1 c > 7][throw LEX_ERROR] + date/set-weekday dt c + ] + if field/13 <> 0 [date/set-yearday dt field/13] ;-- yyyy-ddd + ][ + if field/15 <> 0 [ ;-- month is named + me: as byte-ptr! field/15 ;-- name end + p: as byte-ptr! field/14 + 1 ;-- name start len: as-integer me - p + 1 if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name m: months @@ -1160,35 +1182,24 @@ lexer: context [ m: m + 1 ] if months + 12 = m [throw LEX_ERROR] ;-- invalid month name - (as-integer m - months) >> 2 + 1 + field/3: (as-integer m - months) >> 2 + 1 ] + dt: date/make-at + alloc-slot lex + field/2 ;-- year + field/3 ;-- month + field/4 ;-- day + field/5 ;-- hour + field/6 ;-- min + field/7 ;-- sec + field/8 ;-- nano + field/11 ;-- TZ hour + field/12 ;-- TZ min + state >= T_TM_HM ;-- date/time input + neg? ;-- negative TZ flag + + if null? dt [throw LEX_ERROR] ] - field/3: month - p: as byte-ptr! field/16 - neg?: all [p <> null p/1 = #"-"] - - dt: date/make-at - alloc-slot lex - field/2 ;-- year - field/3 ;-- month - field/4 ;-- day - field/5 ;-- hour - field/6 ;-- min - field/7 ;-- sec - field/8 ;-- nano - field/11 ;-- TZ hour - field/12 ;-- TZ min - state >= T_TM_HM ;-- date/time input - neg? ;-- negative TZ flag - - if null? dt [throw LEX_ERROR] - if any [week? wday?][date/set-isoweek dt field/9] ;-- yyyy-Www - if wday? [ - c: field/10 - if any [c < 1 c > 7][throw LEX_ERROR] ;-- yyyy-Www-d - date/set-weekday dt c - ] - if yday? [date/set-yearday dt field/13] ;-- yyyy-ddd ] lex/in-pos: e ;-- reset the input position to delimiter byte field ;-- return field pointer for scan-time From 0c8113d8498a533f3f837e189b09cc4d5d140e94 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 20:14:19 +0100 Subject: [PATCH 0364/3432] FIX: time in loaded dates not converted to UTC internally. --- runtime/datatypes/date.reds | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index c355a8480c..f668ecc014 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -560,7 +560,11 @@ date: context [ z: tz-h << 2 and 7Fh or (tz-m / 15) if neg-TZ? [z: DATE_SET_ZONE_NEG(z)] dt/date: DATE_SET_ZONE(dt/date z) - unless time? [dt/date: DATE_CLEAR_TIME_FLAG(dt/date)] + either time? [ + dt/time: to-utc-time dt/time DATE_GET_ZONE(dt/date) + ][ + dt/date: DATE_CLEAR_TIME_FLAG(dt/date) + ] dt ] @@ -573,7 +577,9 @@ date: context [ minute [integer!] second [integer!] nsec [integer!] - /local d t + /local + d [integer!] + t [float!] ][ d: 0 t: 0.0 d: DATE_SET_YEAR(d year) @@ -586,7 +592,7 @@ date: context [ + (1e-9 * as float! nsec) set-type as red-value! dt TYPE_DATE ;-- preserve eventual flags in the header dt/date: d - dt/time: t + dt/time: t ;-- !! not converted to UTC !! ] create: func [ From 3d36326c364dc4779851e29e8028aba3a1a35c2a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 20:51:12 +0100 Subject: [PATCH 0365/3432] FEAT: refactors date! scanning code for better readability. --- runtime/datatypes/date.reds | 33 ++++++++----------- runtime/definitions.reds | 20 ++++++++++++ runtime/lexer-transitions.reds | 4 +-- runtime/lexer.reds | 60 ++++++++++++---------------------- utils/generate-lexer-table.red | 30 ++++++++--------- 5 files changed, 70 insertions(+), 77 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index f668ecc014..f79ec46b00 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -523,41 +523,34 @@ date: context [ make-at: func [ slot [red-value!] - year [integer!] - month [integer!] - day [integer!] - hour [integer!] - min [integer!] - sec [integer!] - nsec [integer!] - tz-h [integer!] - tz-m [integer!] + date [lexer-dt-array!] time? [logic!] neg-TZ? [logic!] return: [red-date!] /local - dt [red-date!] - t [float!] - d [integer!] - h [integer!] - i [integer!] - z [integer!] + year [integer!] + tz-h [integer!] + dt [red-date!] + d [integer!] + z [integer!] ][ + year: date/year + tz-h: date/tz-h if year < 100 [ ;-- expand short yy forms d: either year < 50 [2000][1900] year: year + d ] if any [ - day > 31 month > 12 year > 9999 + date/day > 31 date/month > 12 year > 9999 tz-h > 15 tz-h < -15 ;-- out of range TZ - hour > 23 min > 59 sec > 59 - all [day = 29 month = 2 not leap-year? year] + date/hour > 23 date/min > 59 date/sec > 59 + all [date/day = 29 date/month = 2 not leap-year? year] ][return null] dt: as red-date! slot - set-all dt year month day hour min sec nsec + set-all dt year date/month date/day date/hour date/min date/sec date/nsec - z: tz-h << 2 and 7Fh or (tz-m / 15) + z: tz-h << 2 and 7Fh or (date/tz-m / 15) if neg-TZ? [z: DATE_SET_ZONE_NEG(z)] dt/date: DATE_SET_ZONE(dt/date z) either time? [ diff --git a/runtime/definitions.reds b/runtime/definitions.reds index ec0588774a..a0e0f51721 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -337,4 +337,24 @@ Red/System [ IMAGE_GIF IMAGE_JPEG IMAGE_TIFF +] + +;=== Misc definitions === + +lexer-dt-array!: alias struct! [ + year [integer!] + month [integer!] + day [integer!] + hour [integer!] + min [integer!] + sec [integer!] + nsec [integer!] + tz-h [integer!] + tz-m [integer!] + week [integer!] + wday [integer!] + yday [integer!] + month-begin [integer!] + month-end [integer!] + TZ-sign [integer!] ] \ No newline at end of file diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index fbd3bf3a73..960f67b20d 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -143,8 +143,8 @@ Red/System [ 01010101010E0E0E01010101010101010101010F01010101010F010101010101 010101010101010101100101010101010101010101010101010101 } fields-table: #{ -040404020201010103030303010D090909010A03040403030103020202020105 -050106060107070108010B0B010C0101010101010101080B0B0C0C +040404020201010103030303010D0B0B0B010C03040403030103020202020105 +050106060107070108010909010A01010101010101010809090A0A } reset-table: #{ 0101010100000000010001010000000101000101010001000001010101000001 000001000001000001000100000100000000000000000000000000 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f807a54cb8..9d0b6943d9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1100,7 +1100,9 @@ lexer: context [ scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] return: [int-ptr!] /local + cell [cell!] dt [red-date!] + df [lexer-dt-array!] p [byte-ptr!] me [byte-ptr!] m [int-ptr!] @@ -1112,7 +1114,6 @@ lexer: context [ c [integer!] pos [integer!] len [integer!] - month [integer!] time? [logic!] neg? [logic!] ][ @@ -1142,38 +1143,30 @@ lexer: context [ field/pos: c ] unless time? [ - p: as byte-ptr! field/16 + df: as lexer-dt-array! field + 1 + p: as byte-ptr! df/TZ-sign neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ + cell: alloc-slot lex - either any [field/9 <> 0 field/10 <> 0 field/13 <> 0][ ;-- special ISO formats - dt: date/make-at - alloc-slot lex - field/2 ;-- year - 1 ;-- month - 1 ;-- day - field/5 ;-- hour - field/6 ;-- min - field/7 ;-- sec - field/8 ;-- nano - field/11 ;-- TZ hour - field/12 ;-- TZ min - state >= T_TM_HM ;-- date/time input - neg? ;-- negative TZ flag - + either df/week or df/wday or df/yday <> 0 [ ;-- special ISO formats + df/month: 1 ;-- ensures valid month (will be changed later) + df/day: 1 ;-- ensures valid day (will be changed later) + dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! if null? dt [throw LEX_ERROR] - if any [field/9 <> 0 field/10 <> 0][ ;-- yyyy-Www - date/set-isoweek dt field/9 + + if df/week or df/wday <> 0 [ ;-- yyyy-Www + date/set-isoweek dt df/week ] - c: field/10 + c: df/wday if c <> 0 [ ;-- yyyy-Www-d if any [c < 1 c > 7][throw LEX_ERROR] date/set-weekday dt c ] - if field/13 <> 0 [date/set-yearday dt field/13] ;-- yyyy-ddd + if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd ][ - if field/15 <> 0 [ ;-- month is named - me: as byte-ptr! field/15 ;-- name end - p: as byte-ptr! field/14 + 1 ;-- name start + if df/month-end <> 0 [ ;-- if month is named + p: as byte-ptr! df/month-begin + 1 ;-- name start + me: as byte-ptr! df/month-end ;-- name end len: as-integer me - p + 1 if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name m: months @@ -1182,22 +1175,9 @@ lexer: context [ m: m + 1 ] if months + 12 = m [throw LEX_ERROR] ;-- invalid month name - field/3: (as-integer m - months) >> 2 + 1 + df/month: (as-integer m - months) >> 2 + 1 ] - dt: date/make-at - alloc-slot lex - field/2 ;-- year - field/3 ;-- month - field/4 ;-- day - field/5 ;-- hour - field/6 ;-- min - field/7 ;-- sec - field/8 ;-- nano - field/11 ;-- TZ hour - field/12 ;-- TZ min - state >= T_TM_HM ;-- date/time input - neg? ;-- negative TZ flag - + dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! if null? dt [throw LEX_ERROR] ] ] @@ -1233,7 +1213,7 @@ lexer: context [ ][ field: scan-date state s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame - if any [field/11 <> 0 field/12 <> 0][throw LEX_ERROR] ;-- TZ info rejection + if any [field/9 <> 0 field/10 <> 0][throw LEX_ERROR] ;-- TZ info rejection tm: (3600.0 * as float! field/5) + (60.0 * as float! field/6) diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index df220789ac..21ef709b17 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -99,10 +99,10 @@ context [ ;minute 6 ;second 7 ;nsec 8 - ;week 9 - ;weekday 10 - ;tz-hour 11 - ;tz-min 12 + ;tz-hour 9 + ;tz-min 10 + ;week 11 + ;weekday 12 ;yearday 13 ;word-start 14 ;word-end 15 @@ -122,11 +122,11 @@ context [ S_DT_YMM2 1 3 1 ;-- 11 F_DT_YMONTH 0 1 1 ;-- 12 F_DT_DDD 0 13 1 ;-- 13 - S_DT_YV 0 9 1 ;-- 14 - S_DT_YW 1 9 1 ;-- 15 - S_DT_YWW 1 9 1 ;-- 16 + S_DT_YV 0 11 1 ;-- 14 + S_DT_YW 1 11 1 ;-- 15 + S_DT_YWW 1 11 1 ;-- 16 S_DT_YWD 0 1 1 ;-- 17 - S_DT_WD 1 10 1 ;-- 18 + S_DT_WD 1 12 1 ;-- 18 S_DT_YMON 1 3 15 ;-- 19 F_DT_YMD 1 4 1 ;-- 20 F_DT_YMDD 0 4 1 ;-- 21 @@ -150,10 +150,10 @@ context [ F_TM_N1 0 1 1 ;-- 39 F_TM_N 1 8 1 ;-- 40 S_TM_HMZ 0 1 16 ;-- 41 - S_TZ_H 1 11 1 ;-- 42 - F_TZ_HH 0 11 1 ;-- 43 + S_TZ_H 1 9 1 ;-- 42 + F_TZ_HH 0 9 1 ;-- 43 F_TZ_HM 0 1 1 ;-- 44 - S_TZ_M 1 12 1 ;-- 45 + S_TZ_M 1 10 1 ;-- 45 T_DT_ERROR 0 1 1 ;-- 46 T_DT_YMDAY 0 1 1 ;-- 47 T_DT_DMYEAR 0 1 1 ;-- 48 @@ -163,10 +163,10 @@ context [ T_TM_HM 0 1 1 ;-- 52 T_TM_HMS 0 1 1 ;-- 53 T_TM_NZ 0 8 1 ;-- 54 - T_TZ_H 0 11 1 ;-- 55 - T_TZ_HH 0 11 1 ;-- 56 - T_TZ_M 0 12 1 ;-- 57 - T_TZ_MM 0 12 1 ;-- 58 + T_TZ_H 0 9 1 ;-- 55 + T_TZ_HH 0 9 1 ;-- 56 + T_TZ_M 0 10 1 ;-- 57 + T_TZ_MM 0 10 1 ;-- 58 ] CSV-table: %../docs/lexer/lexer-FSM.csv From da296b92be5aa1a71afb5f84cd2409727a64373d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 1 Nov 2019 20:56:54 +0100 Subject: [PATCH 0366/3432] FEAT: improves readability of scan-time. --- runtime/lexer.reds | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9d0b6943d9..fd589ba4c2 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1098,7 +1098,7 @@ lexer: context [ ] scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - return: [int-ptr!] + return: [lexer-dt-array!] /local cell [cell!] dt [red-date!] @@ -1141,9 +1141,9 @@ lexer: context [ state: as-integer date-transitions/index pos: as-integer fields-table/state field/pos: c - ] + ] + df: as lexer-dt-array! field + 1 unless time? [ - df: as lexer-dt-array! field + 1 p: as byte-ptr! df/TZ-sign neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ cell: alloc-slot lex @@ -1182,7 +1182,7 @@ lexer: context [ ] ] lex/in-pos: e ;-- reset the input position to delimiter byte - field ;-- return field pointer for scan-time + df ;-- return field pointer for scan-time ] scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1208,17 +1208,17 @@ lexer: context [ scan-time: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - field [int-ptr!] + field [lexer-dt-array!] tm [float!] ][ - field: scan-date state s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame + field: as lexer-dt-array! scan-date state s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame - if any [field/9 <> 0 field/10 <> 0][throw LEX_ERROR] ;-- TZ info rejection + if any [field/tz-h <> 0 field/tz-m <> 0][throw LEX_ERROR] ;-- TZ info rejection - tm: (3600.0 * as float! field/5) - + (60.0 * as float! field/6) - + ( as float! field/7) - + (1e-9 * as float! field/8) + tm: (3600.0 * as float! field/hour) + + (60.0 * as float! field/min) + + ( as float! field/sec) + + (1e-9 * as float! field/nsec) time/make-at tm alloc-slot state ;-- field array is not usable after this call ] From c17709b0fe4690c76ec571964d11eeeaa35fbad0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 2 Nov 2019 00:10:44 +0100 Subject: [PATCH 0367/3432] FEAT: adds separators consistency check in scan-date. --- runtime/definitions.reds | 1 + runtime/lexer-transitions.reds | 4 ++-- runtime/lexer.reds | 15 ++++++++++----- utils/generate-lexer-table.red | 9 +++++---- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/runtime/definitions.reds b/runtime/definitions.reds index a0e0f51721..34765ba4de 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -356,5 +356,6 @@ lexer-dt-array!: alias struct! [ yday [integer!] month-begin [integer!] month-end [integer!] + sep2 [integer!] TZ-sign [integer!] ] \ No newline at end of file diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 960f67b20d..246c4ae681 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -140,8 +140,8 @@ Red/System [ T_TZ_MM ] fields-ptr-table: #{ -01010101010E0E0E01010101010101010101010F01010101010F010101010101 -010101010101010101100101010101010101010101010101010101 +01010101010E0E0E01010101100101010101010F01010101100F010101010101 +010101010101010101110101010101010101010101010101010101 } fields-table: #{ 040404020201010103030303010D0B0B0B010C03040403030103020202020105 050106060107070108010909010A01010101010101010809090A0A diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fd589ba4c2..96e4f16982 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1098,7 +1098,7 @@ lexer: context [ ] scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - return: [lexer-dt-array!] + return: [lexer-dt-array!] ;-- return field pointer for scan-time /local cell [cell!] dt [red-date!] @@ -1117,9 +1117,9 @@ lexer: context [ time? [logic!] neg? [logic!] ][ - c: 0 ;-- accumulator (numbers decoding) + c: 0 ;-- accumulator (fields decoding) time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? - field: system/stack/allocate/zero 16 ;-- date/time fields array + field: system/stack/allocate/zero 17 ;-- date/time fields array state: either time? [S_TM_START][S_DT_START] loop as-integer e - s [ @@ -1164,8 +1164,13 @@ lexer: context [ ] if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd ][ + p: as byte-ptr! df/month-begin + me: as byte-ptr! df/sep2 + if df/month-begin or df/sep2 <> 0 [ + if any [null? p null? me p/1 <> me/1][throw LEX_ERROR] ;-- inconsistent separator + ] if df/month-end <> 0 [ ;-- if month is named - p: as byte-ptr! df/month-begin + 1 ;-- name start + p: p + 1 ;-- name start me: as byte-ptr! df/month-end ;-- name end len: as-integer me - p + 1 if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name @@ -1353,7 +1358,7 @@ lexer: context [ term? [logic!] do-scan [scanner!] ][ - line: 1 + line: 1 until [ flags: 0 term?: no diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 21ef709b17..59b9961a93 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -106,7 +106,8 @@ context [ ;yearday 13 ;word-start 14 ;word-end 15 - ;TZ-sign 16 + ;sep2 16 + ;TZ-sign 17 ;-- state ----------- reset -- field -- ptr -- S_DT_START 1 4 1 ;-- 0 S_DT_D 1 4 1 ;-- 1 @@ -120,7 +121,7 @@ context [ S_DT_YMM 0 3 1 ;-- 9 S_DT_YM2 1 3 1 ;-- 10 S_DT_YMM2 1 3 1 ;-- 11 - F_DT_YMONTH 0 1 1 ;-- 12 + F_DT_YMONTH 0 1 16 ;-- 12 F_DT_DDD 0 13 1 ;-- 13 S_DT_YV 0 11 1 ;-- 14 S_DT_YW 1 11 1 ;-- 15 @@ -132,7 +133,7 @@ context [ F_DT_YMDD 0 4 1 ;-- 21 S_DT_DM 1 3 1 ;-- 22 S_DT_DMM 0 3 1 ;-- 23 - F_DT_DMONTH 0 1 1 ;-- 24 + F_DT_DMONTH 0 1 16 ;-- 24 S_DT_DMON 1 3 15 ;-- 25 F_DT_DMY 1 2 1 ;-- 26 F_DT_DMYY 1 2 1 ;-- 27 @@ -149,7 +150,7 @@ context [ F_TM_SS 0 7 1 ;-- 38 F_TM_N1 0 1 1 ;-- 39 F_TM_N 1 8 1 ;-- 40 - S_TM_HMZ 0 1 16 ;-- 41 + S_TM_HMZ 0 1 17 ;-- 41 S_TZ_H 1 9 1 ;-- 42 F_TZ_HH 0 9 1 ;-- 43 F_TZ_HM 0 1 1 ;-- 44 From df38c72cd5b16c0a94969bb05f66ee9a158c8d43 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 2 Nov 2019 11:27:20 +0800 Subject: [PATCH 0368/3432] FIX: improve event dispatch --- modules/view/backends/gtk3/events.reds | 19 ---- modules/view/backends/gtk3/handlers.reds | 108 +++++++++-------------- 2 files changed, 40 insertions(+), 87 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 4a8799ca5f..83a57cb944 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -368,11 +368,9 @@ make-event: func [ ] stack/adjust-post-try if system/thrown <> 0 [system/thrown: 0] - ;; DEBUG: print ["make-event result:" res lf] type: TYPE_OF(res) if ANY_WORD?(type) [ sym: symbol/resolve res/symbol - ;; DEBUG: print ["make-event symbol:" get-symbol-name sym lf] case [ sym = done [state: EVT_NO_DISPATCH] ;-- prevent other high-level events sym = stop [state: EVT_NO_DISPATCH] ;-- prevent all other events @@ -380,21 +378,6 @@ make-event: func [ ] ] - ; #call [system/view/awake gui-evt] - ; res: as red-word! stack/arguments - - ; if TYPE_OF(res) = TYPE_WORD [ - ; sym: symbol/resolve res/symbol - ; ;; DEBUG: - ; print ["make-events result:" sym lf] - - ; case [ - ; sym = done [state: EVT_DISPATCH] ;-- prevent other high-level events - ; sym = stop [state: EVT_NO_DISPATCH] ;-- prevent all other events - ; true [0] ;-- ignore others - ; ] - ; ] - state ] @@ -558,7 +541,6 @@ connect-common-events: function [ widget [handle!] data [int-ptr!] ][ - assert widget <> null gtk_widget_add_events widget GDK_BUTTON_PRESS_MASK gobj_signal_connect(widget "button-press-event" :mouse-button-press-event data) @@ -601,7 +583,6 @@ connect-notify-events: function [ widget [handle!] data [int-ptr!] ][ - assert widget <> null gtk_widget_add_events widget GDK_ENTER_NOTIFY_MASK or GDK_LEAVE_NOTIFY_MASK gobj_signal_connect(widget "enter-notify-event" :widget-enter-notify-event data) gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event data) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index f61af2ef32..6264259b74 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -170,7 +170,7 @@ base-draw: func [ evbox [handle!] cr [handle!] widget [handle!] - return: [logic!] + return: [integer!] /local face [red-object!] values [red-value!] @@ -234,21 +234,21 @@ base-draw: func [ draw-end drawDC cr no no no ] - if null? gtk_container_get_children widget [ - return true - ] + ;if null? gtk_container_get_children widget [ + ; return EVT_NO_DISPATCH + ;] - false + EVT_DISPATCH ] window-delete-event: func [ [cdecl] widget [handle!] - return: [logic!] + return: [integer!] ][ ;; DEBUG: print ["window-delete-event" lf] make-event widget 0 EVT_CLOSE - no + EVT_DISPATCH ] window-event: func [ @@ -418,6 +418,7 @@ key-press-event: func [ text [c-string!] qdata [handle!] ][ + if evbox <> gtk_get_event_widget as handle! event-key [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -442,10 +443,7 @@ key-press-event: func [ ] ][res: make-event widget key or flags EVT_KEY] ] - if sym = field [ - return EVT_DISPATCH - ] - EVT_NO_DISPATCH + res ] key-release-event: func [ @@ -462,6 +460,7 @@ key-release-event: func [ key [integer!] flags [integer!] ][ + if evbox <> gtk_get_event_widget as handle! event-key [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -472,10 +471,6 @@ key-release-event: func [ flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not flags: flags or check-extra-keys event-key/state make-event widget key or flags EVT_KEY_UP - if sym = field [ - return EVT_DISPATCH - ] - EVT_NO_DISPATCH ] field-changed: func [ @@ -492,7 +487,6 @@ field-changed: func [ set-text widget face/ctx text make-event widget 0 EVT_CHANGE ] - EVT_NO_DISPATCH ] focus-in-event: func [ @@ -500,7 +494,7 @@ focus-in-event: func [ evbox [handle!] event [handle!] widget [handle!] - return: [logic!] + return: [integer!] /local face [red-object!] values [red-value!] @@ -508,6 +502,7 @@ focus-in-event: func [ int [red-integer!] sym [integer!] ][ + if evbox <> gtk_get_event_widget event [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -515,9 +510,6 @@ focus-in-event: func [ sym: symbol/resolve type/symbol change-selection widget int sym make-event widget 0 EVT_FOCUS - - if sym = window [return false] - true ] focus-out-event: func [ @@ -525,21 +517,19 @@ focus-out-event: func [ evbox [handle!] event [handle!] widget [handle!] - return: [logic!] + return: [integer!] /local face [red-object!] values [red-value!] type [red-word!] sym [integer!] ][ + if evbox <> gtk_get_event_widget event [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol make-event widget 0 EVT_UNFOCUS - - if sym = window [return false] - true ] area-changed: func [ @@ -579,22 +569,13 @@ area-populate-popup: func [ red-timer-action: func [ [cdecl] - self [handle!] - return: [integer!] + self [handle!] + return: [logic!] /local timer [int-ptr!] ][ - ; timer: get-widget-timer self - ; either null? timer [ - ;either null? main-window [no] - ;[ - make-event self 0 EVT_TIME - 1 - ;];[ - ; print ["timer for widget " self " will stop!" lf] - ; remove-widget-timer self - ; no ; this removes the timer - ; ] + make-event self 0 EVT_TIME + true ] widget-enter-notify-event: func [ @@ -606,8 +587,7 @@ widget-enter-notify-event: func [ /local flags [integer!] ][ - ;; DEBUG: print [ "ENTER: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] - + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags EVT_OVER ] @@ -621,7 +601,7 @@ widget-leave-notify-event: func [ /local flags [integer!] ][ - ;; DEBUG: print [ "LEAVE: x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root lf] + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags or EVT_FLAG_AWAY EVT_OVER ] @@ -643,6 +623,7 @@ mouse-button-release-event: func [ flags [integer!] ev [integer!] ][ + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] sym: get-widget-symbol widget if sym = field [ if event/button = GDK_BUTTON_PRIMARY [ @@ -704,9 +685,7 @@ mouse-button-press-event: func [ hMenu [handle!] ev [integer!] ][ - ;; DEBUG: print [ "mouse -> BUTTON-PRESS: " widget " (" ") x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] - ; evt-motion/state: yes - ; evt-motion/cpt: 0 + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] sym: get-widget-symbol widget if gtk_widget_get_focus_on_click widget [ @@ -748,15 +727,13 @@ mouse-motion-notify-event: func [ widget [handle!] return: [integer!] /local - res [integer!] offset [red-pair!] x [float!] y [float!] wflags [integer!] flags [integer!] ][ - ;; DEBUG: print [ "mouse -> MOTION: " widget " x: " event/x " y: " event/y " x_root: " event/x_root " y_root: " event/y_root " drag? " draggable? widget lf] - res: EVT_DISPATCH + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y evt-motion/x_root: event/x_root @@ -764,22 +741,9 @@ mouse-motion-notify-event: func [ wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS if wflags and FACET_FLAGS_ALL_OVER <> 0 [ flags: check-flags event/type event/state - res: make-event widget flags EVT_OVER + return make-event widget flags EVT_OVER ] - ;; DEBUG: print ["mouse-motion-notify-event: down? " (event/state and GDK_BUTTON1_MASK <> 0) " " (flags and EVT_FLAG_DOWN <> 0) lf] - res -] - -menu-item-activate: func [ - [cdecl] - item [handle!] - widget [handle!] - /local - key [integer!] -][ - key: menu-item-key? item - ;; DEBUG: print ["menu-item activated: " item " with key: " key " on widget " widget lf] - make-event widget key EVT_MENU + EVT_DISPATCH ] widget-scroll-event: func [ @@ -788,14 +752,22 @@ widget-scroll-event: func [ event [GdkEventScroll!] widget [handle!] return: [integer!] - /local - res [integer!] ][ - ;; DEBUG: print ["scroll-event: " event/direction " " event/delta_x " " event/delta_y lf] - res: EVT_DISPATCH + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] g_object_set_qdata widget red-event-id as handle! event - if any[event/delta_y < -0.01 event/delta_y > 0.01][ - res: make-event widget check-down-flags event/state EVT_WHEEL + if any [event/delta_y < -0.01 event/delta_y > 0.01][ + return make-event widget check-down-flags event/state EVT_WHEEL ] - res + EVT_DISPATCH +] + +menu-item-activate: func [ + [cdecl] + item [handle!] + widget [handle!] + /local + key [integer!] +][ + key: menu-item-key? item + make-event widget key EVT_MENU ] From c9dd27600a1fe2d760540867d012cde6ce0d8832 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 2 Nov 2019 14:34:51 +0100 Subject: [PATCH 0369/3432] FEAT: preliminary work on proper error raising in lexer. --- runtime/lexer.reds | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 96e4f16982..64257a6c39 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -373,6 +373,18 @@ lexer: context [ stash-size: 1000 ;-- pre-allocated cells number depth: 0 ;-- recursive calls depth + throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] + /local + pos [red-string!] + len [integer!] + ][ + e: either s + 40 < e [s + 40][e] + len: as-integer e - s + pos: string/load as-c-string s len UTF-8 + lex/tail: lex/buffer ;-- clear accumulated values + fire [TO_ERROR(syntax invalid) datatype/push type pos] + ] + alloc-slot: func [state [state!] return: [red-value!] /local slot [red-value!]][ if state/head + state/slots <= state/tail [ assert false @@ -451,13 +463,15 @@ lexer: context [ hint ] - decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-2: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] /local + b [byte-ptr!] p [byte-ptr!] c [integer!] cnt [integer!] ][ p: as byte-ptr! ser/offset + b: s while [s < e][ c: 0 @@ -471,17 +485,17 @@ lexer: context [ ] #"^-" #"^/" #" " #"^M" [s: s + 1] #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] - default [throw LEX_ERROR] + default [throw-error lex b e TYPE_BINARY] ] ] - if all [cnt <> 0 cnt <> 8][throw LEX_ERROR] + if all [cnt <> 0 cnt <> 8][throw-error lex b e TYPE_BINARY] p/value: as byte! c p: p + 1 ] ser/tail: as cell! p ] - decode-16: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-16: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] /local p [byte-ptr!] pos [byte-ptr!] @@ -513,7 +527,7 @@ lexer: context [ ser/tail: as cell! p ] - decode-64: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-64: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] /local p [byte-ptr!] c [integer!] @@ -889,7 +903,7 @@ lexer: context [ state/in-pos: e ;-- reset the input position to delimiter byte ] - scan-binary: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-binary: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local bin [red-binary!] ser [series!] @@ -914,16 +928,16 @@ lexer: context [ 2 [len / 8] default [throw LEX_ERROR 0] ] - bin: binary/make-at alloc-slot state size + bin: binary/make-at alloc-slot lex size ser: GET_BUFFER(bin) switch base [ - 16 [decode-16 s e ser] - 64 [decode-64 s e ser] - 2 [decode-2 s e ser] + 16 [decode-16 lex s e ser] + 64 [decode-64 lex s e ser] + 2 [decode-2 lex s e ser] default [assert false 0] ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail - state/in-pos: e + 1 ;-- skip } + lex/in-pos: e + 1 ;-- skip } ] scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1103,6 +1117,7 @@ lexer: context [ cell [cell!] dt [red-date!] df [lexer-dt-array!] + b [byte-ptr!] p [byte-ptr!] me [byte-ptr!] m [int-ptr!] @@ -1118,6 +1133,7 @@ lexer: context [ neg? [logic!] ][ c: 0 ;-- accumulator (fields decoding) + b: s time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? field: system/stack/allocate/zero 17 ;-- date/time fields array state: either time? [S_TM_START][S_DT_START] @@ -1136,7 +1152,7 @@ lexer: context [ s: s + 1 ] if state <= T_DT_ERROR [ ;-- if no terminal state reached, forces EOF input - if state = T_DT_ERROR [throw LEX_ERROR] ;-- check here for performance reason + if state = T_DT_ERROR [throw-error lex b e TYPE_DATE] ;-- check here for performance reason index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index pos: as-integer fields-table/state @@ -1152,14 +1168,14 @@ lexer: context [ df/month: 1 ;-- ensures valid month (will be changed later) df/day: 1 ;-- ensures valid day (will be changed later) dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw LEX_ERROR] + if null? dt [throw-error lex b e TYPE_DATE] if df/week or df/wday <> 0 [ ;-- yyyy-Www date/set-isoweek dt df/week ] c: df/wday if c <> 0 [ ;-- yyyy-Www-d - if any [c < 1 c > 7][throw LEX_ERROR] + if any [c < 1 c > 7][throw-error lex b e TYPE_DATE] date/set-weekday dt c ] if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd @@ -1167,23 +1183,25 @@ lexer: context [ p: as byte-ptr! df/month-begin me: as byte-ptr! df/sep2 if df/month-begin or df/sep2 <> 0 [ - if any [null? p null? me p/1 <> me/1][throw LEX_ERROR] ;-- inconsistent separator + if any [null? p null? me p/1 <> me/1][ + throw-error lex b e TYPE_DATE ;-- inconsistent separator + ] ] if df/month-end <> 0 [ ;-- if month is named p: p + 1 ;-- name start me: as byte-ptr! df/month-end ;-- name end len: as-integer me - p + 1 - if any [len < 3 len > 9][throw LEX_ERROR] ;-- invalid month name + if any [len < 3 len > 9][throw-error lex b e TYPE_DATE] ;-- invalid month name m: months loop 12 [ if zero? platform/strnicmp p as byte-ptr! m/1 len [break] m: m + 1 ] - if months + 12 = m [throw LEX_ERROR] ;-- invalid month name + if months + 12 = m [throw-error lex b e TYPE_DATE] ;-- invalid month name df/month: (as-integer m - months) >> 2 + 1 ] dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw LEX_ERROR] + if null? dt [throw-error lex b e TYPE_DATE] ] ] lex/in-pos: e ;-- reset the input position to delimiter byte From 6b1d565488c627da826b9fdf3a4a9ffa2deba643 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 2 Nov 2019 20:14:07 +0100 Subject: [PATCH 0370/3432] FEAT: completes proper error handling in lexer. --- runtime/lexer.reds | 255 +++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 114 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 64257a6c39..7b8ad11d60 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -348,9 +348,9 @@ lexer: context [ ] #enum errors! [ - LEX_ERR_STRING: 1 - - LEX_ERROR ;-- keep it last + ERR_BAD_CHAR: -1 + ERR_MALCONSTRUCT: -2 + ERR_MISSING: -3 ] state!: alias struct! [ @@ -363,8 +363,9 @@ lexer: context [ in-pos [byte-ptr!] line [integer!] ;-- current line number nline [integer!] ;-- new lines count for new token - err [integer!] entry [integer!] ;-- entry state for the FSM + exit [integer!] ;-- exit state for the FSM + closing [integer!] ;-- any-block! expected closing delimiter type ] scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] @@ -378,11 +379,24 @@ lexer: context [ pos [red-string!] len [integer!] ][ - e: either s + 40 < e [s + 40][e] + e: either s + 40 < e [s + 40][e] ;FIXME: accurately find the 40th codepoint position len: as-integer e - s pos: string/load as-c-string s len UTF-8 lex/tail: lex/buffer ;-- clear accumulated values - fire [TO_ERROR(syntax invalid) datatype/push type pos] + switch type [ + ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) pos]] + ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) pos]] + ERR_MISSING [ + type: switch lex/closing [ + TYPE_BLOCK [as-integer #"]"] + TYPE_MAP + TYPE_PAREN [as-integer #")"] + default [assert false 0] ;-- should not happen + ] + fire [TO_ERROR(syntax missing) char/push type pos] + ] + default [fire [TO_ERROR(syntax invalid) datatype/push type pos]] + ] ] alloc-slot: func [state [state!] return: [red-value!] /local slot [red-value!]][ @@ -416,63 +430,66 @@ lexer: context [ ] ] - open-block: func [state [state!] type [integer!] hint [integer!] - /local p [red-point!] len [integer!] + open-block: func [lex [state!] type [integer!] hint [integer!] + /local + p [red-point!] + len [integer!] ][ - len: (as-integer state/tail - state/head) >> 4 - p: as red-point! alloc-slot state + len: (as-integer lex/tail - lex/head) >> 4 + p: as red-point! alloc-slot lex set-type as cell! p TYPE_POINT ;-- use the slot for stack info p/x: len p/y: type p/z: hint - state/head: state/tail ;-- points just after p - state/entry: S_START + lex/head: lex/tail ;-- points just after p + lex/entry: S_START ] - close-block: func [state [state!] type [integer!] final [integer!] + close-block: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] final [integer!] return: [integer!] /local p [red-point!] len [integer!] hint [integer!] ][ - p: as red-point! state/head - 1 - assert all [state/buffer <= p TYPE_OF(p) = TYPE_POINT] + p: as red-point! lex/head - 1 + assert all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] either type = -1 [ type: either final = -1 [p/y][final] ][ - if p/y <> type [throw LEX_ERROR] + if p/y <> type [ + lex/closing: type + throw-error lex s e ERR_MISSING + ] ] - len: (as-integer state/tail - state/head) >> 4 - state/tail: state/head - state/head: as cell! p - p/x + len: (as-integer lex/tail - lex/head) >> 4 + lex/tail: lex/head + lex/head: as cell! p - p/x hint: p/z - store-any-block as cell! p state/tail len type ;-- p slot gets overwritten here + store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here - p: as red-point! state/head - 1 ;-- get parent series + p: as red-point! lex/head - 1 ;-- get parent series either all [ - state/buffer <= p + lex/buffer <= p not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] ][ ;-- any-path! case - state/entry: S_PATH + lex/entry: S_PATH ][ - state/entry: S_START + lex/entry: S_START ] hint ] - decode-2: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + return: [byte-ptr!] ;-- null: ok, not null: error position /local - b [byte-ptr!] p [byte-ptr!] c [integer!] cnt [integer!] ][ p: as byte-ptr! ser/offset - b: s - while [s < e][ c: 0 cnt: 8 @@ -485,17 +502,19 @@ lexer: context [ ] #"^-" #"^/" #" " #"^M" [s: s + 1] #";" [until [s: s + 1 any [s/1 = #"^/" s = e]]] - default [throw-error lex b e TYPE_BINARY] + default [return s] ] ] - if all [cnt <> 0 cnt <> 8][throw-error lex b e TYPE_BINARY] + if all [cnt <> 0 cnt <> 8][return s] p/value: as byte! c p: p + 1 ] ser/tail: as cell! p + null ] - decode-16: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-16: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] pos [byte-ptr!] @@ -505,11 +524,10 @@ lexer: context [ fstate [integer!] ][ p: as byte-ptr! ser/offset - while [s < e][ fstate: S_BIN_START pos: s - until [ ;-- scans 2 hex characters, skip the rest + until [ ;-- scans 2 hex characters, skip the rest index: 1 + as-integer s/1 class: as-integer bin16-classes/index s: s + 1 @@ -517,17 +535,19 @@ lexer: context [ fstate: as-integer bin16-FSM/index any [fstate - S_BIN_FINAL_STATES > 0 s >= e] ] - if fstate = T_BIN_ERROR [throw LEX_ERROR] - index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables + if fstate = T_BIN_ERROR [return s] + index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables c: as-integer hexa-table/index index: 1 + as-integer pos/2 p/value: as byte! c << 4 or as-integer hexa-table/index p: p + 1 ] ser/tail: as cell! p + null ] - decode-64: func [lex [state!] s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-64: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] c [integer!] @@ -570,36 +590,37 @@ lexer: context [ p: p + 1 flip: 0 ] - true [throw LEX_ERROR] + true [return s] ] break ] - ][ - if val = 80h [throw LEX_ERROR] - ] + ][if val = 80h [return s]] s: s + 1 ] ser/tail: as red-value! p + null ] - scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] + scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] + return: [byte-ptr!] ;-- -1 if error /local c [integer!] c2 [integer!] index [integer!] ][ - if s + 1 >= e [throw LEX_ERROR] + if s + 1 >= e [cp/value: -1 return s] c: 0 index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table c: as-integer hexa-table/index ;-- decode high nibble index: 1 + as-integer s/2 c2: as-integer hexa-table/index ;-- decode low nibble - if any [c = -1 c2 = -1][throw LEX_ERROR] + if any [c = -1 c2 = -1][cp/value: -1 return s] cp/value: c << 4 or c2 s + 2 ] - scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] + scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] + return: [byte-ptr!] ;-- -1 if error /local p [byte-ptr!] src [byte-ptr!] @@ -622,11 +643,13 @@ lexer: context [ while [all [p/1 <> #")" p < e]][ index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table cb: hexa-table/index ;-- decode one nibble at a time - if cb = #"^(FF)" [throw LEX_ERROR] + if cb = #"^(FF)" [cp/value: -1 return p] c: c << 4 + as-integer cb p: p + 1 ] - if any [p = e p/1 <> #")" (as-integer p - s) > 7][throw LEX_ERROR] ;-- limit of 6 hexa characters. + if any [p = e p/1 <> #")" (as-integer p - s) > 7][ ;-- limit of 6 hexa characters + cp/value: -1 return s + ] p: p + 1 ;-- skip ) ][ ;-- named escaped char src: s + 1 ;-- skip ( @@ -637,7 +660,7 @@ lexer: context [ ] assert escape-names + (7 * 3) > entry len: entry/2 + 1 - if src/len <> #")" [throw LEX_ERROR] + if src/len <> #")" [cp/value: -1 return src] c: entry/3 p: src + len ] @@ -646,7 +669,7 @@ lexer: context [ pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) either char-special/pos and bit = null-byte [ ;-- "regular" escaped char - if any [s/1 < #"^(40)" #"^(5F)" < s/1][throw LEX_ERROR] + if any [s/1 < #"^(40)" #"^(5F)" < s/1][cp/value: -1 return s] c: as-integer s/1 - #"@" ][ ;-- escaped special char c: switch s/1 [ @@ -666,16 +689,13 @@ lexer: context [ p ] - scan-eof: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ + scan-eof: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + assert false ;-- should not happen (for now) null ] - scan-error: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null + scan-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + throw-error lex s e ERR_BAD_CHAR ] scan-block-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -688,7 +708,7 @@ lexer: context [ ] scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - close-block state TYPE_BLOCK -1 + close-block state s e TYPE_BLOCK -1 state/in-pos: e + 1 ;-- skip ] ] @@ -696,14 +716,14 @@ lexer: context [ /local blk [red-block!] ][ - if TYPE_MAP = close-block state TYPE_PAREN -1 [ + if TYPE_MAP = close-block state s e TYPE_PAREN -1 [ blk: as red-block! state/tail - 1 map/make-at as cell! blk blk block/rs-length? blk ] state/in-pos: e + 1 ;-- skip ) ] - scan-string: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-string: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local str [red-string!] ser [series!] @@ -717,6 +737,7 @@ lexer: context [ digits [integer!] extra [integer!] cp [integer!] + type [integer!] esc [byte!] w? [logic!] c [byte!] @@ -725,9 +746,10 @@ lexer: context [ len: as-integer e - s unit: 1 << (flags >>> 30) if unit > 4 [unit: 4] + type: TYPE_STRING either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence - str: string/make-at alloc-slot state len unit + str: string/make-at alloc-slot lex len unit ser: GET_BUFFER(str) switch unit [ UCS-1 [copy-memory as byte-ptr! ser/offset s len] @@ -736,7 +758,7 @@ lexer: context [ p: as byte-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp - if cp = -1 [throw LEX_ERROR] + if cp = -1 [throw-error lex s e type] p/1: as-byte cp and FFh p/2: as-byte cp >> 8 p: p + 2 @@ -747,7 +769,7 @@ lexer: context [ p4: as int-ptr! ser/offset while [s < e][ s: decode-utf8-char s :cp - if cp = -1 [throw LEX_ERROR] + if cp = -1 [throw-error lex s e type] p4/value: cp p4: p4 + 1 ] @@ -797,7 +819,7 @@ lexer: context [ ] esc: either flags and C_FLAG_ESC_HEX = 0 [#"^^"][#"%"] - str: string/make-at alloc-slot state len - extra unit + str: string/make-at alloc-slot lex len - extra unit ser: GET_BUFFER(str) switch unit [ UCS-1 [ @@ -809,6 +831,7 @@ lexer: context [ ][ scan-percent-char s + 1 e :cp ] + if cp = -1 [throw-error lex s e type] p/value: as-byte cp ][ p/value: s/1 @@ -831,7 +854,7 @@ lexer: context [ ][ decode-utf8-char s :cp ] - if cp = -1 [throw LEX_ERROR] + if cp = -1 [throw-error lex s e type] p/1: as-byte cp and FFh p/2: as-byte cp >> 8 p: p + 2 @@ -851,7 +874,7 @@ lexer: context [ ][ decode-utf8-char s :cp ] - if cp = -1 [throw LEX_ERROR] + if cp = -1 [throw-error lex s e type] p4/value: cp p4: p4 + 1 ] @@ -860,10 +883,10 @@ lexer: context [ ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail ] - state/in-pos: e + 1 ;-- skip ending delimiter + lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-word: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-word: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] type [integer!] @@ -873,17 +896,17 @@ lexer: context [ case [ s/1 = #":" [s: s + 1 type: TYPE_GET_WORD] e/0 = #":" [e: e - 1 type: TYPE_SET_WORD] - all [e/1 = #":" state/entry = S_PATH][0] ;-- do nothing if in a path - true [throw LEX_ERROR] + all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path + true [throw-error lex s e type] ] ] if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] - cell: alloc-slot state + cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type - if type = TYPE_SET_WORD [state/in-pos: e + 1] ;-- skip ending delimiter + if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -906,6 +929,7 @@ lexer: context [ scan-binary: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local bin [red-binary!] + err [byte-ptr!] ser [series!] len [integer!] size [integer!] @@ -926,21 +950,22 @@ lexer: context [ 16 [len / 2] 64 [len + 3 * 3 / 4] 2 [len / 8] - default [throw LEX_ERROR 0] + default [throw-error lex s e TYPE_BINARY 0] ] bin: binary/make-at alloc-slot lex size ser: GET_BUFFER(bin) - switch base [ - 16 [decode-16 lex s e ser] - 64 [decode-64 lex s e ser] - 2 [decode-2 lex s e ser] - default [assert false 0] + err: switch base [ + 16 [decode-16 s e ser] + 64 [decode-64 s e ser] + 2 [decode-2 s e ser] + default [assert false null] ] + if err <> null [throw-error lex err e TYPE_BINARY] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail lex/in-pos: e + 1 ;-- skip } ] - scan-char: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-char: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local char [red-char!] len [integer!] @@ -948,22 +973,22 @@ lexer: context [ ][ assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] len: as-integer e - s - if len = 2 [throw LEX_ERROR] ;-- #"" + if len = 2 [throw-error lex s e TYPE_CHAR] ;-- #"" either s/3 = #"^^" [ - if len = 3 [throw LEX_ERROR] ;-- #"^" + if len = 3 [throw-error lex s e TYPE_CHAR] ;-- #"^" c: -1 scan-escaped-char s + 3 e :c ][ ;-- simple char c: as-integer s/3 ] - if c > 0010FFFFh [throw LEX_ERROR] + if any [c > 0010FFFFh c = -1][throw-error lex s e TYPE_CHAR] - char: as red-char! alloc-slot state + char: as red-char! alloc-slot lex set-type as cell! char TYPE_CHAR char/value: c - state/in-pos: e + 1 ;-- skip " + lex/in-pos: e + 1 ;-- skip " ] scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ @@ -971,7 +996,7 @@ lexer: context [ state/in-pos: e + 1 ;-- skip ( ] - scan-construct: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-construct: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local dt [red-datatype!] p [int-ptr!] @@ -987,18 +1012,18 @@ lexer: context [ if zero? platform/strnicmp s as byte-ptr! p/1 p/2 [break] p: p + 3 ] - if p = end [throw LEX_ERROR] ;-- no match, error case + if p = end [throw-error lex s e ERR_MALCONSTRUCT] ;-- no match, error case len: p/2 + 1 - if s/len <> #"]" [throw LEX_ERROR] + if s/len <> #"]" [throw-error lex s e ERR_MALCONSTRUCT] - dt: as red-datatype! alloc-slot state + dt: as red-datatype! alloc-slot lex either p < dtypes [ set-type as cell! dt TYPE_LOGIC dt/value: p/3 ][ set-type as cell! dt p/3 ] - state/in-pos: e + 1 ;-- skip ] + lex/in-pos: e + 1 ;-- skip ] ] scan-ref-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1067,20 +1092,20 @@ lexer: context [ i ] - scan-float: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-float: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local fl [red-float!] err [integer!] ][ err: 0 - fl: as red-float! alloc-slot state + fl: as red-float! alloc-slot lex set-type as cell! fl TYPE_FLOAT fl/value: red-dtoa/string-to-float s e :err - if err <> 0 [throw LEX_ERROR] - state/in-pos: e ;-- reset the input position to delimiter byte + if err <> 0 [throw-error lex s e TYPE_FLOAT] + lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-tuple: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-tuple: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] i [integer!] @@ -1088,7 +1113,7 @@ lexer: context [ tp [byte-ptr!] p [byte-ptr!] ][ - cell: alloc-slot state + cell: alloc-slot lex tp: (as byte-ptr! cell) + 4 pos: 0 i: 0 @@ -1097,7 +1122,7 @@ lexer: context [ loop as-integer e - s [ either p/1 = #"." [ pos: pos + 1 - if any [i < 0 i > 255 pos > 12][throw LEX_ERROR] + if any [i < 0 i > 255 pos > 12][throw-error lex s e TYPE_TUPLE] tp/pos: as byte! i i: 0 ][ @@ -1108,7 +1133,7 @@ lexer: context [ pos: pos + 1 ;-- last number tp/pos: as byte! i cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1229,21 +1254,21 @@ lexer: context [ state/in-pos: e ;-- reset the input position to delimiter byte ] - scan-time: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-time: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local field [lexer-dt-array!] tm [float!] ][ - field: as lexer-dt-array! scan-date state s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame + field: as lexer-dt-array! scan-date lex s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame - if any [field/tz-h <> 0 field/tz-m <> 0][throw LEX_ERROR] ;-- TZ info rejection + if any [field/tz-h <> 0 field/tz-m <> 0][throw-error lex s e TYPE_TIME] ;-- TZ info rejection tm: (3600.0 * as float! field/hour) + (60.0 * as float! field/min) + ( as float! field/sec) + (1e-9 * as float! field/nsec) - time/make-at tm alloc-slot state ;-- field array is not usable after this call + time/make-at tm alloc-slot lex ;-- field array is not usable after this call ] scan-money: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1304,27 +1329,29 @@ lexer: context [ state/in-pos: e + 1 ;-- skip / ] - scan-path-item: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-path-item: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local type [integer!] cp [integer!] index [integer!] close? [logic!] ][ - close?: either e >= state/in-end [yes][ ;-- EOF reached + close?: either e >= lex/in-end [yes][ ;-- EOF reached cp: as-integer e/1 index: lex-classes/cp and FFh + 1 ;-- query the class of ending character as-logic path-ending/index ;-- lookup if the character class is ending path ] either close? [ - type: either all [e < state/in-end e/1 = #":"][ - state/in-pos: e + 1 ;-- skip : + type: either all [e < lex/in-end e/1 = #":"][ + lex/in-pos: e + 1 ;-- skip : TYPE_SET_PATH ][-1] - close-block state -1 type + close-block lex s e -1 type ][ - if all [e < state/in-end e/1 = #":"][throw LEX_ERROR] ;-- set-words not allowed inside paths - state/in-pos: e + 1 ;-- skip / + if all [e < lex/in-end e/1 = #":"][ + throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths + ] + lex/in-pos: e + 1 ;-- skip / ] ] @@ -1404,11 +1431,14 @@ lexer: context [ index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index ] + assert state <= T_PATH + assert start + offset <= p + lex/in-pos: p - lex/line: line - lex/nline: line - mark + lex/line: line + lex/nline: line - mark + lex/exit: state - assert start + offset <= p index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index do-scan lex start + offset p flags @@ -1440,13 +1470,10 @@ lexer: context [ state/input: src state/in-end: src + len state/in-pos: src - state/err: 0 state/entry: S_START - catch LEX_ERROR [scan-tokens state] - if system/thrown > 0 [ - probe "Syntax error" ;TBD: error handling - ] + scan-tokens state + slots: (as-integer state/tail - state/head) >> 4 store-any-block dst state/head slots TYPE_BLOCK From 7b429676b9b4cdfe5b657058bc5ba93b56d95045 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 2 Nov 2019 20:30:36 +0100 Subject: [PATCH 0371/3432] FEAT: adds line number in syntax error reporting from lexer. Line value is wrong though, as the counting is doubled in scan-tokens (to be fixed). --- environment/system.red | 8 ++++---- runtime/lexer.reds | 15 +++++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/environment/system.red b/environment/system.red index d187b5f8ff..49568726e2 100644 --- a/environment/system.red +++ b/environment/system.red @@ -86,13 +86,13 @@ system: context [ syntax: object [ code: 200 type: "Syntax Error" - invalid: ["invalid" :arg1 "at" :arg2] - missing: ["missing" :arg1 "at" :arg2] + invalid: ["(line" :arg1 ") invalid" :arg2 "at" :arg3] + missing: ["(line" :arg1 ") missing" :arg2 "at" :arg3] no-header: ["script is missing a Red header:" :arg1] no-rs-header: ["script is missing a Red/System header:" :arg1] bad-header: ["script header is not valid:" :arg1] - malconstruct: ["invalid construction spec:" :arg1] - bad-char: ["invalid character in:" :arg1] + malconstruct: ["(line" :arg1 ") invalid construction spec:" :arg2] + bad-char: ["(line" :arg1 ") invalid character in:" :arg2] ] script: object [ code: 300 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7b8ad11d60..b219a62046 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -376,16 +376,19 @@ lexer: context [ throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] /local - pos [red-string!] - len [integer!] + pos [red-string!] + line [red-integer!] + len [integer!] ][ e: either s + 40 < e [s + 40][e] ;FIXME: accurately find the 40th codepoint position len: as-integer e - s pos: string/load as-c-string s len UTF-8 + line: integer/push lex/line lex/tail: lex/buffer ;-- clear accumulated values + switch type [ - ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) pos]] - ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) pos]] + ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] + ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) line pos]] ERR_MISSING [ type: switch lex/closing [ TYPE_BLOCK [as-integer #"]"] @@ -393,9 +396,9 @@ lexer: context [ TYPE_PAREN [as-integer #")"] default [assert false 0] ;-- should not happen ] - fire [TO_ERROR(syntax missing) char/push type pos] + fire [TO_ERROR(syntax missing) line char/push type pos] ] - default [fire [TO_ERROR(syntax invalid) datatype/push type pos]] + default [fire [TO_ERROR(syntax invalid) line datatype/push type pos]] ] ] From 4f3742b85c76e73f51db8875105cbaed6a4914c0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 2 Nov 2019 22:20:52 +0100 Subject: [PATCH 0372/3432] FEAT: consistent naming of scanner's state argument. --- runtime/lexer.reds | 136 ++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b219a62046..aab7e204a0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -368,7 +368,7 @@ lexer: context [ closing [integer!] ;-- any-block! expected closing delimiter type ] - scanner!: alias function! [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] + scanner!: alias function! [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number @@ -402,15 +402,15 @@ lexer: context [ ] ] - alloc-slot: func [state [state!] return: [red-value!] /local slot [red-value!]][ - if state/head + state/slots <= state/tail [ + alloc-slot: func [lex [state!] return: [red-value!] /local slot [red-value!]][ + if lex/head + lex/slots <= lex/tail [ assert false 0 ;TBD: expand ] - slot: state/tail + slot: lex/tail slot/header: TYPE_UNSET - if state/nline > 0 [slot/header: slot/header or flag-new-line] - state/tail: state/tail + 1 + if lex/nline > 0 [slot/header: slot/header or flag-new-line] + lex/tail: lex/tail + 1 slot ] @@ -701,29 +701,29 @@ lexer: context [ throw-error lex s e ERR_BAD_CHAR ] - scan-block-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-block-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local type [integer!] ][ type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] - open-block state type -1 - state/in-pos: e + 1 ;-- skip delimiter + open-block lex type -1 + lex/in-pos: e + 1 ;-- skip delimiter ] - scan-block-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - close-block state s e TYPE_BLOCK -1 - state/in-pos: e + 1 ;-- skip ] + scan-block-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + close-block lex s e TYPE_BLOCK -1 + lex/in-pos: e + 1 ;-- skip ] ] - scan-paren-close: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-paren-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local blk [red-block!] ][ - if TYPE_MAP = close-block state s e TYPE_PAREN -1 [ - blk: as red-block! state/tail - 1 + if TYPE_MAP = close-block lex s e TYPE_PAREN -1 [ + blk: as red-block! lex/tail - 1 map/make-at as cell! blk blk block/rs-length? blk ] - state/in-pos: e + 1 ;-- skip ) + lex/in-pos: e + 1 ;-- skip ) ] scan-string: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -912,7 +912,7 @@ lexer: context [ if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] - scan-file: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-file: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] p [byte-ptr!] @@ -922,11 +922,11 @@ lexer: context [ p: s until [p: p + 1 any [p/1 = #"%" p = e]] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] - scan-string state s e flags - cell: state/tail - 1 + scan-string lex s e flags + cell: lex/tail - 1 set-type cell TYPE_FILE ;-- preserve header's flags if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] scan-binary: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -994,9 +994,9 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip " ] - scan-map-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - open-block state TYPE_PAREN TYPE_MAP - state/in-pos: e + 1 ;-- skip ( + scan-map-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + open-block lex TYPE_PAREN TYPE_MAP + lex/in-pos: e + 1 ;-- skip ( ] scan-construct: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1029,33 +1029,33 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ] ] - scan-ref-issue: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-ref-issue: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] type [integer!] ][ type: either s/1 = #"#" [TYPE_ISSUE][assert s/1 = #"/" TYPE_REFINEMENT] s: s + 1 - cell: alloc-slot state + cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-percent: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-percent: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local fl [red-float!] ][ assert e/1 = #"%" - scan-float state s e flags - fl: as red-float! state/tail - 1 + scan-float lex s e flags + fl: as red-float! lex/tail - 1 set-type as cell! fl TYPE_PERCENT fl/value: fl/value / 100.0 - state/in-pos: e + 1 ;-- skip ending delimiter + lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-integer: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-integer: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] return: [integer!] /local p [byte-ptr!] @@ -1070,7 +1070,7 @@ lexer: context [ ][ len: as-integer e - p if len > 10 [ - scan-float state s e flags ;-- overflow, fall back on float + scan-float lex s e flags ;-- overflow, fall back on float return 0 ] i: 0 @@ -1089,9 +1089,9 @@ lexer: context [ ] if s/value = #"-" [i: 0 - i] if flags and C_FLAG_NOSTORE = 0 [ - integer/make-at alloc-slot state i + integer/make-at alloc-slot lex i ] - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte i ] @@ -1236,7 +1236,7 @@ lexer: context [ df ;-- return field pointer for scan-time ] - scan-pair: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-pair: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local index [integer!] class [integer!] @@ -1250,11 +1250,11 @@ lexer: context [ class = C_X ] pair/make-at - alloc-slot state - scan-integer state s p flags or C_FLAG_NOSTORE - scan-integer state p + 1 e flags or C_FLAG_NOSTORE + alloc-slot lex + scan-integer lex s p flags or C_FLAG_NOSTORE + scan-integer lex p + 1 e flags or C_FLAG_NOSTORE - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] scan-time: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1280,18 +1280,18 @@ lexer: context [ null ] - scan-tag: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-tag: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag - scan-string state s e flags - cell: state/tail - 1 + scan-string lex s e flags + cell: lex/tail - 1 set-type cell TYPE_TAG ;-- preserve header's flags - state/in-pos: e + 1 ;-- skip ending delimiter + lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-url: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-url: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] p [byte-ptr!] @@ -1299,25 +1299,25 @@ lexer: context [ flags: flags and not C_FLAG_CARET ;-- clears caret flag p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] - scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter - cell: state/tail - 1 + scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + cell: lex/tail - 1 set-type cell TYPE_URL ;-- preserve header's flags - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-email: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-email: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag - scan-string state s - 1 e flags ;-- compensate for lack of starting delimiter - cell: state/tail - 1 + scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + cell: lex/tail - 1 set-type cell TYPE_EMAIL ;-- preserve header's flags - state/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-path-open: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-path-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local type [integer!] ][ @@ -1326,10 +1326,10 @@ lexer: context [ #":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH] default [TYPE_PATH] ] - open-block state type -1 ;-- open a new path series - scan-word state s e flags ;-- load the head word - state/entry: S_PATH ;-- overwrites the S_START set by open-block - state/in-pos: e + 1 ;-- skip / + open-block lex type -1 ;-- open a new path series + scan-word lex s e flags ;-- load the head word + lex/entry: S_PATH ;-- overwrites the S_START set by open-block + lex/in-pos: e + 1 ;-- skip / ] scan-path-item: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -1462,23 +1462,23 @@ lexer: context [ blk [red-block!] slots [integer!] s [series!] - state [state! value] + lex [state! value] ][ depth: depth + 1 - state/buffer: stash ;TBD: support dyn buffer case - state/head: stash - state/tail: stash - state/slots: stash-size ;TBD: support dyn buffer case - state/input: src - state/in-end: src + len - state/in-pos: src - state/entry: S_START + lex/buffer: stash ;TBD: support dyn buffer case + lex/head: stash + lex/tail: stash + lex/slots: stash-size ;TBD: support dyn buffer case + lex/input: src + lex/in-end: src + len + lex/in-pos: src + lex/entry: S_START - scan-tokens state + scan-tokens lex - slots: (as-integer state/tail - state/head) >> 4 - store-any-block dst state/head slots TYPE_BLOCK + slots: (as-integer lex/tail - lex/head) >> 4 + store-any-block dst lex/head slots TYPE_BLOCK depth: depth - 1 ] From 0df03fc268d0a3e8c4a033e4fa4a66be13d43916 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 3 Nov 2019 00:35:49 +0100 Subject: [PATCH 0373/3432] FIX: reports the right line number on syntax errors. --- runtime/lexer.reds | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index aab7e204a0..154f5e4960 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1425,9 +1425,8 @@ lexer: context [ state: as-integer transitions/index offset: offset + as-integer skip-table/state - line: line + as-integer line-table/class - if state > --EXIT_STATES-- [term?: yes break] + line: line + as-integer line-table/class p: p + 1 ] unless term? [ From 7bd042d3eb371d4596f160e8c4d0ee010b9b2d4a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 3 Nov 2019 12:47:41 +0100 Subject: [PATCH 0374/3432] FEAT: improves syntax error messages formatting. --- environment/system.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/environment/system.red b/environment/system.red index 49568726e2..19a4eeafd9 100644 --- a/environment/system.red +++ b/environment/system.red @@ -86,13 +86,13 @@ system: context [ syntax: object [ code: 200 type: "Syntax Error" - invalid: ["(line" :arg1 ") invalid" :arg2 "at" :arg3] - missing: ["(line" :arg1 ") missing" :arg2 "at" :arg3] + invalid: ["invalid" :arg2 "at line" :arg1 "in" :arg3] + missing: ["missing" :arg2 "at line" :arg1 "in" :arg3] no-header: ["script is missing a Red header:" :arg1] no-rs-header: ["script is missing a Red/System header:" :arg1] bad-header: ["script header is not valid:" :arg1] - malconstruct: ["(line" :arg1 ") invalid construction spec:" :arg2] - bad-char: ["(line" :arg1 ") invalid character in:" :arg2] + malconstruct: ["invalid construction spec at line" :arg1 "in" :arg2] + bad-char: ["invalid character at line" :arg1 "in" :arg2] ] script: object [ code: 300 From 03fab1a8dddbc9f1af62d567372e2ac94e502195 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 3 Nov 2019 13:49:02 +0100 Subject: [PATCH 0375/3432] FEAT: extends the lexer's buffer when needed. --- runtime/lexer.reds | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 154f5e4960..c364036c99 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -385,6 +385,7 @@ lexer: context [ pos: string/load as-c-string s len UTF-8 line: integer/push lex/line lex/tail: lex/buffer ;-- clear accumulated values + depth: depth - 1 switch type [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] @@ -402,10 +403,26 @@ lexer: context [ ] ] - alloc-slot: func [lex [state!] return: [red-value!] /local slot [red-value!]][ - if lex/head + lex/slots <= lex/tail [ - assert false - 0 ;TBD: expand + alloc-slot: func [lex [state!] return: [red-value!] + /local + slot [red-value!] + size [integer!] + deltaH [integer!] + deltaT [integer!] + ][ + size: lex/slots + if lex/head + size <= lex/tail [ + deltaH: (as-integer lex/head - lex/buffer) >> 4 + deltaT: (as-integer lex/tail - lex/buffer) >> 4 + lex/slots: size * 2 + lex/buffer: as cell! realloc as byte-ptr! lex/buffer lex/slots << 4 + if null? lex/buffer [fire [TO_ERROR(internal no-memory)]] + lex/head: lex/buffer + deltaH + lex/tail: lex/buffer + deltaT + if depth = 1 [ + stash: lex/buffer + stash-size: lex/slots + ] ] slot: lex/tail slot/header: TYPE_UNSET From a3c7cf0fa2f392cc3c06844419698e949dd1f87a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 3 Nov 2019 17:19:43 +0100 Subject: [PATCH 0376/3432] FEAT: mark lexer values during GC. --- runtime/collector.reds | 1 + runtime/lexer.reds | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/runtime/collector.reds b/runtime/collector.reds index 17d87422f5..bf689ac1be 100644 --- a/runtime/collector.reds +++ b/runtime/collector.reds @@ -330,6 +330,7 @@ collector: context [ #if debug? = yes [if verbose > 1 [probe "marking globals"]] keep case-folding/upper-to-lower/node keep case-folding/lower-to-upper/node + lexer/mark-buffers #if debug? = yes [if verbose > 1 [probe "marking path parent"]] obj: object/path-parent diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c364036c99..cf3dc3bf63 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -354,7 +354,8 @@ lexer: context [ ] state!: alias struct! [ - buffer [red-value!] ;-- static or dynamic stash buffer (for recursive calls) + next [state!] ;-- link to next state! structure (recursive calls) + buffer [red-value!] ;-- static or dynamic stash buffer (recursive calls) head [red-value!] tail [red-value!] slots [integer!] @@ -372,6 +373,7 @@ lexer: context [ stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number + root-state: as state! 0 ;-- global entry point to state struct list depth: 0 ;-- recursive calls depth throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] @@ -403,6 +405,15 @@ lexer: context [ ] ] + mark-buffers: func [/local s [state!]][ + s: root-state + until [ + collector/mark-values s/buffer s/tail + s: s/next + null? s + ] + ] + alloc-slot: func [lex [state!] return: [red-value!] /local slot [red-value!] @@ -1480,8 +1491,10 @@ lexer: context [ s [series!] lex [state! value] ][ + if zero? depth [root-state: lex] depth: depth + 1 + lex/next: null ;-- last element of the states linked list lex/buffer: stash ;TBD: support dyn buffer case lex/head: stash lex/tail: stash @@ -1497,6 +1510,7 @@ lexer: context [ store-any-block dst lex/head slots TYPE_BLOCK depth: depth - 1 + if zero? depth [root-state: null] ] init: func [][ From eabcf0c887097a32f942d85ab7f071d1d87e572c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 3 Nov 2019 17:58:11 +0100 Subject: [PATCH 0377/3432] FEAT: error out on detected money! literals, until money! gets officially supported. --- runtime/lexer.reds | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cf3dc3bf63..6112b571bd 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1302,10 +1302,9 @@ lexer: context [ time/make-at tm alloc-slot lex ;-- field array is not usable after this call ] - scan-money: func [state [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - ; /local - ][ - null + scan-money: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + ;;TBD: implement this function once money! type is done + throw-error lex s e ERR_BAD_CHAR ] scan-tag: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 0f3c321967cf5953050cc973291e07bfc3d571ac Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 4 Nov 2019 16:38:11 +0800 Subject: [PATCH 0378/3432] FIX: if `face/color = none`, the face will be transparent --- modules/view/backends/gtk3/gtk.reds | 17 ++++++++ modules/view/backends/gtk3/gui.reds | 61 ++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 53d595fde4..ea9e2be9bd 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -21,6 +21,8 @@ Red/System [ #define G_ASCII_DTOSTR_BUF_SIZE 39 +#define G_TYPE_MAKE_FUNDAMENTAL(x) [x << 2] +#define G_TYPE_INT 24 ;[G_TYPE_MAKE_FUNDAMENTAL(6)] RECT_STRUCT: alias struct! [ left [integer!] @@ -653,6 +655,15 @@ GPtrArray!: alias struct! [ argv [int-ptr!] return: [integer!] ] + g_value_init: "g_value_init" [ + value [handle!] + type [integer!] + return: [handle!] + ] + g_value_get_int: "g_value_get_int" [ + value [handle!] + return: [integer!] + ] ;; ] ;; LIBGDK-file cdecl [ gdk_screen_width: "gdk_screen_width" [ @@ -1551,6 +1562,12 @@ GPtrArray!: alias struct! [ gtk_container_child_set: "gtk_container_child_set" [ [variadic] ] + gtk_container_child_get_property: "gtk_container_child_get_property" [ + container [handle!] + widget [handle!] + prop [c-string!] + value [int-ptr!] + ] gtk_frame_new: "gtk_frame_new" [ label [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f7a43f6383..2968852858 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -51,6 +51,13 @@ get-face-obj: func [ face ] +is-face?: func [ + handle [handle!] + return: [logic!] +][ + TYPE_OBJECT = (get-type-mask and as integer! g_object_get_qdata handle red-face-id1) +] + get-face-values: func [ handle [handle!] return: [red-value!] @@ -211,6 +218,7 @@ set-widget-child: func [ parent [handle!] widget [handle!] offset [red-pair!] + trans? [logic!] return: [logic!] /local sym [integer!] @@ -237,12 +245,12 @@ set-widget-child: func [ case [ sym = window [ playout: GET-CONTAINER(parent) - gtk_layout_put playout clayout x y + insert-widget playout clayout x y trans? true ] sym = group-box [ playout: gtk_bin_get_child parent - gtk_layout_put playout clayout x y + insert-widget playout clayout x y trans? true ] any [ @@ -250,7 +258,7 @@ set-widget-child: func [ sym = rich-text sym = panel ][ - gtk_layout_put parent clayout x y + insert-widget parent clayout x y trans? true ] sym = tab-panel [ @@ -306,6 +314,45 @@ set-widget-child-offset: func [ ] ] +insert-widget: func [ + layout [handle!] + widget [handle!] + x [integer!] + y [integer!] + trans? [logic!] + /local + list [GList!] + last [GList!] + sibling [handle!] + gvalue [handle!] + nx [integer!] + ny [integer!] +][ + list: gtk_container_get_children layout + either any [ + null? list + not trans? + ][ + gtk_layout_put layout widget x y + ][ + last: g_list_last list + sibling: last/data + gvalue: system/stack/allocate 5 + set-memory as byte-ptr! gvalue null-byte 20 + g_value_init gvalue G_TYPE_INT + gtk_container_child_get_property layout sibling "x" gvalue + nx: g_value_get_int gvalue + gtk_container_child_get_property layout sibling "y" gvalue + ny: g_value_get_int gvalue + g_object_ref sibling + gtk_container_remove layout sibling + gtk_layout_put layout widget x y + gtk_layout_put layout sibling nx ny + g_object_unref sibling + g_list_free list + ] +] + show-widget: func [ widget [handle!] /local @@ -880,7 +927,7 @@ change-pane: func [ widget [handle!] values [red-value!] offset [red-pair!] - + color [red-tuple!] ][ layout: case [ type = window [ @@ -921,7 +968,8 @@ change-pane: func [ if widget <> null [ values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - set-widget-child parent widget offset + color: as red-tuple! values + FACE_OBJ_COLOR + set-widget-child parent widget offset TYPE_OF(color) <> TYPE_TUPLE ] ] face: face + 1 @@ -992,6 +1040,7 @@ change-size: func [ x: either size/x > x [size/x - x / 2][0] y: either size/y > y [size/y - y / 2][0] gtk_layout_move widget label x y + g_list_free list ] ] ] @@ -1880,7 +1929,7 @@ OS-make-view: func [ if sym <> window [ if parent <> 0 [ - unless set-widget-child as handle! parent widget offset [ + unless set-widget-child as handle! parent widget offset TYPE_OF(color) <> TYPE_TUPLE [ fire [TO_ERROR(script face-type) type] ] ] From 941e40ef838944265379775848926f474c8eca1b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 4 Nov 2019 16:42:46 +0800 Subject: [PATCH 0379/3432] FIX: better find panel's label --- modules/view/backends/gtk3/gtk.reds | 3 +++ modules/view/backends/gtk3/gui.reds | 10 +++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index ea9e2be9bd..6818870d81 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2966,6 +2966,7 @@ red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" start-resize-id: g_quark_from_string "start-resize-id" +caption-id: g_quark_from_string "caption-id" #define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] @@ -2978,3 +2979,5 @@ start-resize-id: g_quark_from_string "start-resize-id" #define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] #define SET-POST-QUIT(s d) [g_object_set_qdata s post-quit-id d] #define GET-POST-QUIT(s) [g_object_get_qdata s post-quit-id] +#define SET-CAPTION(s d) [g_object_set_qdata s caption-id d] +#define GET-CAPTION(s) [g_object_get_qdata s caption-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 2968852858..a510ef716d 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1006,8 +1006,6 @@ change-size: func [ ntype [red-word!] sym [integer!] layout [handle!] - str [red-string!] - list [GList!] label [handle!] pl [handle!] x [integer!] @@ -1030,17 +1028,14 @@ change-size: func [ gtk_widget_queue_resize widget if type = panel [ - str: as red-string! values + FACE_OBJ_TEXT - if TYPE_OF(str) = TYPE_STRING [ - list: gtk_container_get_children widget - label: list/data + label: GET-CAPTION(widget) + unless null? label [ pl: gtk_label_get_layout label x: 0 y: 0 pango_layout_get_pixel_size pl :x :y x: either size/x > x [size/x - x / 2][0] y: either size/y > y [size/y - y / 2][0] gtk_layout_move widget label x y - g_list_free list ] ] ] @@ -1925,6 +1920,7 @@ OS-make-view: func [ if newF? [ free-pango-attrs attrs ] + SET-CAPTION(widget buffer) ] if sym <> window [ From 27da542121525f6b80d1d815bd44a9850c528cfa Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 4 Nov 2019 16:57:28 +0800 Subject: [PATCH 0380/3432] FIX: if only left one window, do not break the loop --- modules/view/backends/gtk3/events.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 83a57cb944..2a9364dd1e 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -407,7 +407,10 @@ do-events: func [ break ] c2: get-window-count - if c2 < c1 [break] + if all [ + c2 > 1 + c2 < c1 + ][break] ] no-wait? ] From a782bc1c1c47883a60da80593f6fed7233d2b43a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 4 Nov 2019 17:02:28 +0800 Subject: [PATCH 0381/3432] FIX: free glist not correctly --- modules/view/backends/gtk3/gui.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a510ef716d..2e039e8b20 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -349,6 +349,8 @@ insert-widget: func [ gtk_layout_put layout widget x y gtk_layout_put layout sibling nx ny g_object_unref sibling + ] + unless null? list [ g_list_free list ] ] From 725f6881ace79d905ab00ceb5318d40355a1034e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 4 Nov 2019 22:09:19 +0100 Subject: [PATCH 0382/3432] FEAT: minor refactoring to properly report any-string! types in errors. --- runtime/lexer.reds | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 6112b571bd..641ed5d8b4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -364,6 +364,7 @@ lexer: context [ in-pos [byte-ptr!] line [integer!] ;-- current line number nline [integer!] ;-- new lines count for new token + type [integer!] ;-- sub-type in a typeclass entry [integer!] ;-- entry state for the FSM exit [integer!] ;-- exit state for the FSM closing [integer!] ;-- any-block! expected closing delimiter type @@ -777,7 +778,7 @@ lexer: context [ len: as-integer e - s unit: 1 << (flags >>> 30) if unit > 4 [unit: 4] - type: TYPE_STRING + type: either lex/type = -1 [TYPE_STRING][lex/type] either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence str: string/make-at alloc-slot lex len unit @@ -914,6 +915,7 @@ lexer: context [ ] assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail ] + if type <> TYPE_STRING [set-type as cell! str type] lex/in-pos: e + 1 ;-- skip ending delimiter ] @@ -942,7 +944,6 @@ lexer: context [ scan-file: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - cell [cell!] p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag @@ -950,9 +951,8 @@ lexer: context [ p: s until [p: p + 1 any [p/1 = #"%" p = e]] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] + lex/type: TYPE_FILE scan-string lex s e flags - cell: lex/tail - 1 - set-type cell TYPE_FILE ;-- preserve header's flags if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1178,6 +1178,7 @@ lexer: context [ me [byte-ptr!] m [int-ptr!] field [int-ptr!] + type [integer!] state [integer!] class [integer!] index [integer!] @@ -1208,7 +1209,10 @@ lexer: context [ s: s + 1 ] if state <= T_DT_ERROR [ ;-- if no terminal state reached, forces EOF input - if state = T_DT_ERROR [throw-error lex b e TYPE_DATE] ;-- check here for performance reason + if state = T_DT_ERROR [ ;-- check here for performance reason + type: either time? [TYPE_TIME][TYPE_DATE] + throw-error lex b e type + ] index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index pos: as-integer fields-table/state @@ -1307,40 +1311,32 @@ lexer: context [ throw-error lex s e ERR_BAD_CHAR ] - scan-tag: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - /local - cell [cell!] - ][ + scan-tag: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ flags: flags and not C_FLAG_CARET ;-- clears caret flag + lex/type: TYPE_TAG scan-string lex s e flags - cell: lex/tail - 1 - set-type cell TYPE_TAG ;-- preserve header's flags lex/in-pos: e + 1 ;-- skip ending delimiter ] scan-url: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - cell [cell!] - p [byte-ptr!] + p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] + lex/type: TYPE_URL scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter - cell: lex/tail - 1 - set-type cell TYPE_URL ;-- preserve header's flags lex/in-pos: e ;-- reset the input position to delimiter byte ] scan-email: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - cell [cell!] - p [byte-ptr!] + p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag + lex/type: TYPE_EMAIL scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter - cell: lex/tail - 1 - set-type cell TYPE_EMAIL ;-- preserve header's flags lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1467,6 +1463,7 @@ lexer: context [ lex/line: line lex/nline: line - mark lex/exit: state + lex/type: -1 index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index @@ -1502,6 +1499,7 @@ lexer: context [ lex/in-end: src + len lex/in-pos: src lex/entry: S_START + lex/type: -1 scan-tokens lex From 3a3a96b5dc7b37bed751732a04b68ab34d0ee3de Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 09:48:16 +0800 Subject: [PATCH 0383/3432] FIX: key event delivered from top window --- modules/view/backends/gtk3/handlers.reds | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6264259b74..4cd85df524 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -400,7 +400,6 @@ tab-panel-switch-page: func [ ] ] -; Do not use key-press-event since character would not be printed! key-press-event: func [ [cdecl] evbox [handle!] @@ -408,6 +407,7 @@ key-press-event: func [ widget [handle!] return: [integer!] /local + win [handle!] face [red-object!] values [red-value!] type [red-word!] @@ -418,7 +418,8 @@ key-press-event: func [ text [c-string!] qdata [handle!] ][ - if evbox <> gtk_get_event_widget as handle! event-key [return EVT_NO_DISPATCH] + win: gtk_get_event_widget as handle! event-key + if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -453,6 +454,7 @@ key-release-event: func [ widget [handle!] return: [integer!] /local + win [handle!] face [red-object!] values [red-value!] type [red-word!] @@ -460,7 +462,8 @@ key-release-event: func [ key [integer!] flags [integer!] ][ - if evbox <> gtk_get_event_widget as handle! event-key [return EVT_NO_DISPATCH] + win: gtk_get_event_widget as handle! event-key + if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE From 1221d23a51d06054b14cd10c45f9d29275e68b58 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 10:36:56 +0800 Subject: [PATCH 0384/3432] FIX: small improve for focus event --- modules/view/backends/gtk3/events.reds | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 2a9364dd1e..a74ddd8f27 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -554,7 +554,7 @@ connect-common-events: function [ gtk_widget_add_events widget GDK_BUTTON_RELEASE_MASK gobj_signal_connect(widget "button-release-event" :mouse-button-release-event data) - gtk_widget_add_events widget GDK_KEY_PRESS_MASK or GDK_FOCUS_CHANGE_MASK + gtk_widget_add_events widget GDK_KEY_PRESS_MASK gobj_signal_connect(widget "key-press-event" :key-press-event data) gtk_widget_add_events widget GDK_KEY_RELEASE_MASK @@ -570,13 +570,14 @@ connect-focus-events: function [ sym [integer!] ][ if any [ - sym = base sym = rich-text sym = field sym = area ][ gtk_widget_set_can_focus widget yes gtk_widget_set_focus_on_click widget yes + gtk_widget_grab_focus widget + gtk_widget_add_events widget GDK_FOCUS_CHANGE_MASK gobj_signal_connect(evbox "focus-in-event" :focus-in-event widget) gobj_signal_connect(evbox "focus-out-event" :focus-out-event widget) ] @@ -600,7 +601,7 @@ connect-widget-events: function [ buffer [handle!] ][ evbox: get-face-evbox widget values sym - ;; register red mouse, key event functions + ;-- register red mouse, key event functions if sym <> window [ connect-common-events evbox widget ] @@ -609,7 +610,6 @@ connect-widget-events: function [ case [ sym = check [ - ;@@ No click event for check gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = radio [ @@ -641,7 +641,6 @@ connect-widget-events: function [ 0 ] sym = area [ - ; _widget is here buffer buffer: gtk_text_view_get_buffer widget gobj_signal_connect(buffer "changed" :area-changed widget) g_object_set [widget "populate-all" yes null] From 0b46218f18555ae5938eea1602da6f191bdf9dc3 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 10:38:01 +0800 Subject: [PATCH 0385/3432] FIX: cpu load is too high --- modules/view/backends/gtk3/events.reds | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index a74ddd8f27..21dbc175f8 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -398,20 +398,24 @@ do-events: func [ SET-POST-QUIT(win v) msg?: no - until [ + either no-wait? [ if gtk_events_pending [ msg?: yes - c1: get-window-count - gtk_main_iteration_do not no-wait? - if check-quit-msg [ - break - ] - c2: get-window-count - if all [ - c2 > 1 - c2 < c1 - ][break] ] + ][ + msg?: yes + ] + until [ + c1: get-window-count + gtk_main_iteration_do not no-wait? + if check-quit-msg [ + break + ] + c2: get-window-count + if all [ + c2 > 1 + c2 < c1 + ][break] no-wait? ] msg? From bf016e2af4fd93715169913b9132241963c30348 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 14:02:15 +0800 Subject: [PATCH 0386/3432] FIX: better check if the window was destroyed --- modules/view/backends/gtk3/events.reds | 23 +++---- modules/view/backends/gtk3/gtk.reds | 10 +-- modules/view/backends/gtk3/gui.reds | 89 ++------------------------ 3 files changed, 20 insertions(+), 102 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 21dbc175f8..4baf7da7fb 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -389,13 +389,11 @@ do-events: func [ list [GList!] win [handle!] v [handle!] - c1 [integer!] - c2 [integer!] ][ - win: find-active-window + win: find-last-window if null? win [return no] - v: as handle! 0 - SET-POST-QUIT(win v) + v: as handle! 1 + SET-IN-LOOP(win v) msg?: no either no-wait? [ @@ -406,16 +404,11 @@ do-events: func [ msg?: yes ] until [ - c1: get-window-count gtk_main_iteration_do not no-wait? - if check-quit-msg [ + unless g_type_check_instance_is_a win gtk_window_get_type [ break ] - c2: get-window-count - if all [ - c2 > 1 - c2 < c1 - ][break] + unless as logic! GET-IN-LOOP(win) [break] no-wait? ] msg? @@ -426,9 +419,9 @@ post-quit-msg: func [ win [handle!] v [handle!] ][ - win: find-active-window - v: as handle! 1 - SET-POST-QUIT(win v) + win: find-last-window + v: as handle! 0 + SET-IN-LOOP(win v) gtk_widget_queue_draw win ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 6818870d81..98177aca2a 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1221,6 +1221,9 @@ GPtrArray!: alias struct! [ type [integer!] return: [handle!] ] + gtk_window_get_type: "gtk_window_get_type" [ + return: [integer!] + ] gtk_window_activate_focus: "gtk_window_activate_focus" [ window [handle!] ] @@ -2961,13 +2964,12 @@ red-timer-id: g_quark_from_string "red-timer-id" css-id: g_quark_from_string "css-id" size-id: g_quark_from_string "size-id" menu-id: g_quark_from_string "menu-id" -post-quit-id: g_quark_from_string "post-quit-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" start-resize-id: g_quark_from_string "start-resize-id" caption-id: g_quark_from_string "caption-id" - +in-loop-id: g_quark_from_string "in-loop-id" #define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s container-id] @@ -2977,7 +2979,7 @@ caption-id: g_quark_from_string "caption-id" #define GET-RESIZING(s) [g_object_get_qdata s resizing-id] #define SET-STARTRESIZE(s d) [g_object_set_qdata s start-resize-id d] #define GET-STARTRESIZE(s) [g_object_get_qdata s start-resize-id] -#define SET-POST-QUIT(s d) [g_object_set_qdata s post-quit-id d] -#define GET-POST-QUIT(s) [g_object_get_qdata s post-quit-id] #define SET-CAPTION(s d) [g_object_set_qdata s caption-id d] #define GET-CAPTION(s) [g_object_get_qdata s caption-id] +#define SET-IN-LOOP(s d) [g_object_set_qdata s in-loop-id d] +#define GET-IN-LOOP(s) [g_object_get_qdata s in-loop-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 2e039e8b20..faaab61e6c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -569,83 +569,6 @@ set-defaults: func [ set-default-font default-font-name default-font-size ] -get-window-count: func [ - return: [integer!] - /local - pane [red-block!] - face [red-object!] - num [integer!] - count [integer!] - win [handle!] - ret [integer!] -][ - pane: as red-block! #get system/view/screens ;-- screens list - if null? pane [return null] - - face: as red-object! block/rs-head pane ;-- 1st screen - if null? face [return null] - - pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list - - ret: 0 - num: pane/head + block/rs-length? pane - if all [ - TYPE_OF(pane) = TYPE_BLOCK - 0 < num - ][ - count: num - 1 - loop num [ - win: face-handle? as red-object! block/rs-abs-at pane count - unless null? win [ - ret: ret + 1 - ] - count: count - 1 - ] - ] - ret -] - -check-quit-msg: func [ - return: [logic!] - /local - pane [red-block!] - face [red-object!] - num [integer!] - count [integer!] - win [handle!] - v [handle!] -][ - pane: as red-block! #get system/view/screens ;-- screens list - if null? pane [return null] - - face: as red-object! block/rs-head pane ;-- 1st screen - if null? face [return null] - - pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list - - num: pane/head + block/rs-length? pane - either all [ - TYPE_OF(pane) = TYPE_BLOCK - 0 < num - ][ - count: num - 1 - loop num [ - win: face-handle? as red-object! block/rs-abs-at pane count - unless null? win [ - if as logic! GET-POST-QUIT(win) [ - v: as handle! 0 - SET-POST-QUIT(win v) - return true - ] - ] - count: count - 1 - ] - false - ][ - true - ] -] - find-active-window: func [ return: [handle!] /local @@ -656,13 +579,13 @@ find-active-window: func [ win [handle!] ret [handle!] ][ - pane: as red-block! #get system/view/screens ;-- screens list + pane: as red-block! #get system/view/screens ;-- screens list if null? pane [return null] - face: as red-object! block/rs-head pane ;-- 1st screen + face: as red-object! block/rs-head pane ;-- 1st screen if null? face [return null] - pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list num: pane/head + block/rs-length? pane either all [ @@ -692,13 +615,13 @@ find-last-window: func [ pane [red-block!] face [red-object!] ][ - pane: as red-block! #get system/view/screens ;-- screens list + pane: as red-block! #get system/view/screens ;-- screens list if null? pane [return null] - face: as red-object! block/rs-head pane ;-- 1st screen + face: as red-object! block/rs-head pane ;-- 1st screen if null? face [return null] - pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list + pane: as red-block! (object/get-values face) + FACE_OBJ_PANE ;-- windows list either all [ TYPE_OF(pane) = TYPE_BLOCK From 801105607d5cef5e86bd04fd567d42b0edc9db42 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 5 Nov 2019 17:08:24 +0100 Subject: [PATCH 0387/3432] FEAT: adds support for handling nested brace strings. --- docs/lexer/lexer-FSM.csv | 4 +- docs/lexer/lexer-FSM.xlsx | Bin 24291 -> 24130 bytes docs/lexer/lexer-states.txt | 9 +++- runtime/lexer-transitions.reds | 88 +++++++++++++++++---------------- runtime/lexer.reds | 77 +++++++++++++++++++---------- utils/generate-lexer-table.red | 42 ++++++++-------- 6 files changed, 126 insertions(+), 94 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index a0353efd14..5c5f4fd3de 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,9 +1,9 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;S_M_STRING;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index f4dc8339cece1b5bda290b0f0679c68badae00ea..9dc8d922cd1b8da212930ac126547e254a5e8cf9 100644 GIT binary patch literal 24130 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

o}}HEB|DBuLL%0_~FJeg8Q*Fr2{? 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"^"|dbl-quote)->S_LINE_STR \->"^"->S_SKIP_STR->*->S_LINE_STR \->dbl-quote->T_STRING -S_START->"{"->S_M_STRING->not("^"|"}")->S_M_STRING +S_START->"{"->T_MSTR_OP + +S_M_STRING->not("^"|"}")->S_M_STRING \->"^"->S_SKIP_MSTR->*->S_M_STRING - \->"}"->T_STRING + \->"{"->T_MSTR_OP + \->"}"->T_MSTR_CL S_START->"/"->S_SLASH->not(delimit1)->S_SLASH \->delimit1->T_REFINE diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 246c4ae681..e6257225a5 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -58,6 +58,8 @@ Red/System [ T_PAR_OP T_PAR_CL T_STRING + T_MSTR_OP + T_MSTR_CL T_WORD T_FILE T_REFINE @@ -168,57 +170,57 @@ Red/System [ 2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E 2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ -00001313333435360432020C2727272727270B32202706320132271D26263227 +00001313333435363832020C2727272727270B32202706320132271D26263227 2732310100010101010101010101010101010101010101010101010101010101 0101010132310202020202020202020237020202020202020202020202020202 0202020203020232320202020202020202020202020202020202020202020202 -0202020202020202020232310404040404040404043704040404040404040404 +0202020202020202020232310404040404040404383904040404040404040404 0404040404040404040405040432320404040404040404040404040404040404 -040404040404040404040404040404043231383807073838383838380A070738 -0707070707070707070738380707070707070732383939070739393939393932 -0707390707070707070707080739390707070707070732390707090932323232 +0404040404040404040404040404040432313A3A07073A3A3A3A3A3A0A07073A +070707070707070707073A3A07070707070707323A3B3B07073B3B3B3B3B3B32 +07073B070707070707070708073B3B07070707070707323B0707090932323232 3232323232323232320932323232323232323232323232323232320707070732 -3232323232323232323232320732323232323232323232323232323232390A0A -0A0A0A0A0A0A0A0A390A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32 -323A3A0B0B3A3A3A3A3A3A3A0B0B0B0B0B0B0B0B0B0B0B0B0B3A3A0B0B0B0B0B -0B0B323A3F3F121211323D320D320F121232121212121212323212323F3F1212 -1212121212323F0D0D0D0D32323232323B323232320D0D0D0D3232323232320E +32323232323232323232323207323232323232323232323232323232323B0A0A +0A0A0A0A0A0A0A0A3B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32 +323C3C0B0B3C3C3C3C3C3C3C0B0B0B0B0B0B0B0B0B0B0B0B0B3C3C0B0B0B0B0B +0B0B323C4141121211323F320D320F1212321212121212123232123241411212 +121212121232410D0D0D0D32323232323D323232320D0D0D0D3232323232320E 323232323232320D32320E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3C0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F323C0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111113E11111111111111 -111111111111111111111111111111111111111132323F3F12123F3F3F3F3F3F -3F121212121212121212121212123F3F12121212121212323F41411313414141 -414141410C13191B181532183241324032412A14323218323232324142421515 -424242424242421615321B321532423242324032423232323232323232324242 -421515424242424242421B324232321532423242324032323217323232323232 -3242424242424242424242424216424216161616424242164242424216421616 -4216163231434317174343434343434332324332323232433243323232323217 -3232323232323243444418184444444444444418181818181818181844184418 -444418441818443218324432321A1A3232323232323232323232323232323232 -323232323232323232323232323246461A1A4646464646464632321A32323232 -46324632323246321A323232323232324632321C1C3232323232323232323232 -323232323232323232323232323232323232323245451C1C4545454545454532 -324532321C3245324532323245321C323232323232324532321E1E3232323232 -323232323232323232323232323232323232323232323232323247471E1E4747 -4747474747471E473232323247324732323247321F323232323232323147471F -1F47474747474747471F47323232324732473232324732323232323232323231 -3838212138383838383838212138212121212121323821213838212121212121 -2132382121212121212121212122212124212121212121214821212121212121 +0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3E0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F323E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111114011111111111111 +1111111111111111111111111111111111111111323241411212414141414141 +4112121212121212121212121212414112121212121212324143431313434343 +434343430C13191B181532183243324232432A14323218323232324344441515 +444444444444441615321B321532443244324232443232323232323232324444 +441515444444444444441B324432321532443244324232323217323232323232 +3244444444444444444444444416444416161616444444164444444416441616 +4416163231454517174545454545454532324532323232453245323232323217 +3232323232323245464618184646464646464618181818181818181846184618 +464618461818463218324632321A1A3232323232323232323232323232323232 +323232323232323232323232323248481A1A4848484848484832321A32323232 +48324832323248321A323232323232324832321C1C3232323232323232323232 +323232323232323232323232323232323232323247471C1C4747474747474732 +324732321C3247324732323247321C323232323232324732321E1E3232323232 +323232323232323232323232323232323232323232323232323249491E1E4949 +4949494949491E493232323249324932323249321F323232323232323149491F +1F49494949494949491F49323232324932493232324932323232323232323231 +3A3A21213A3A3A3A3A3A3A21213A212121212121323A21213A3A212121212121 +21323A2121212121212121212122212124212121212121214A21212121212121 2121212132322222222222222222222221222222222222222222222222222222 2222222223222232322222222222222222222222222222222222222222222222 2222222222222222222232322424242424242424242424242421242424242424 2424242424242424242424242432322424242424242424242424242424242424 -2424242424242424242424242424242432323838131338383838383838323227 -2727272727383227322738272727272732272732383838272738383838383838 -322728272727274B3827273232382A271E272727272732383838292938383838 -3838382929292929292929383229292938292929292929292932384949292949 -4949494949492932292929292929494932294949292932292932292932494A4A -2A2A4A4A4A4A4A4A4A3232322A2A2A2A4A4A4A322A324A322A322A2A322A2A32 -4A32322C2C323235363232022E2D2D2D2D2D2D3232202D3232322A2D322F2F32 -2D2D323241412C2C414141414141413213411B321532413241324032412A1432 -3232323232324138382D2D38383838383838322D382D2D2D2D38382D2D323238 -2A2D322D2D2D2D2D32383F3F12121132323232320F1212321212121212123232 -12323F3F12121212121212323F38382C2C383838383838383232272727272727 -38322732273827272727273227273238 +2424242424242424242424242424242432323A3A13133A3A3A3A3A3A3A323227 +27272727273A322732273A2727272727322727323A3A3A27273A3A3A3A3A3A3A +322728272727274D3A272732323A2A271E2727272727323A3A3A29293A3A3A3A +3A3A3A29292929292929293A322929293A2929292929292929323A4B4B29294B +4B4B4B4B4B4B29322929292929294B4B32294B4B2929322929322929324B4C4C +2A2A4C4C4C4C4C4C4C3232322A2A2A2A4C4C4C322A324C322A322A2A322A2A32 +4C32322C2C323235363232022E2D2D2D2D2D2D3232202D3232322A2D322F2F32 +2D2D323243432C2C434343434343433213431B321532433243324232432A1432 +323232323232433A3A2D2D3A3A3A3A3A3A3A322D3A2D2D2D2D3A3A2D2D32323A +2A2D322D2D2D2D2D323A414112121132323232320F1212321212121212123232 +123241411212121212121232413A3A2C2C3A3A3A3A3A3A3A3232272727272727 +3A322732273A2727272727322727323A } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 641ed5d8b4..1f660f8d29 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -116,7 +116,7 @@ lexer: context [ skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000 + 00000000000000000000000000 } path-ending: #{ @@ -354,20 +354,23 @@ lexer: context [ ] state!: alias struct! [ - next [state!] ;-- link to next state! structure (recursive calls) - buffer [red-value!] ;-- static or dynamic stash buffer (recursive calls) - head [red-value!] - tail [red-value!] - slots [integer!] - input [byte-ptr!] - in-end [byte-ptr!] - in-pos [byte-ptr!] - line [integer!] ;-- current line number - nline [integer!] ;-- new lines count for new token - type [integer!] ;-- sub-type in a typeclass - entry [integer!] ;-- entry state for the FSM - exit [integer!] ;-- exit state for the FSM - closing [integer!] ;-- any-block! expected closing delimiter type + next [state!] ;-- link to next state! structure (recursive calls) + buffer [red-value!] ;-- static or dynamic stash buffer (recursive calls) + head [red-value!] + tail [red-value!] + slots [integer!] + input [byte-ptr!] + in-end [byte-ptr!] + in-pos [byte-ptr!] + line [integer!] ;-- current line number + nline [integer!] ;-- new lines count for new token + type [integer!] ;-- sub-type in a typeclass + entry [integer!] ;-- entry state for the FSM + exit [integer!] ;-- exit state for the FSM + closing [integer!] ;-- any-block! expected closing delimiter type + mstr-s [byte-ptr!] ;-- multiline string saved start position + mstr-nest [integer!] ;-- multiline string nested {} counting + mstr-flags [integer!] ;-- multiline string accumulated flags ] scanner!: alias function! [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] @@ -741,7 +744,7 @@ lexer: context [ scan-block-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ close-block lex s e TYPE_BLOCK -1 - lex/in-pos: e + 1 ;-- skip ] + lex/in-pos: e + 1 ;-- skip ] ] scan-paren-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -752,7 +755,7 @@ lexer: context [ blk: as red-block! lex/tail - 1 map/make-at as cell! blk blk block/rs-length? blk ] - lex/in-pos: e + 1 ;-- skip ) + lex/in-pos: e + 1 ;-- skip ) ] scan-string: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] @@ -918,6 +921,23 @@ lexer: context [ if type <> TYPE_STRING [set-type as cell! str type] lex/in-pos: e + 1 ;-- skip ending delimiter ] + + scan-mstring-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + if zero? lex/mstr-nest [lex/mstr-s: s] + lex/mstr-nest: lex/mstr-nest + 1 + lex/mstr-flags: lex/mstr-flags or flags + lex/entry: S_M_STRING + lex/in-pos: e + 1 ;-- skip { + ] + + scan-mstring-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + lex/mstr-nest: lex/mstr-nest - 1 + if zero? lex/mstr-nest [ + scan-string lex lex/mstr-s e lex/mstr-flags or flags + lex/entry: S_START + ] + lex/in-pos: e + 1 ;-- skip } + ] scan-word: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local @@ -1389,6 +1409,8 @@ lexer: context [ :scan-block-open ;-- T_PAR_OP :scan-paren-close ;-- T_PAR_CL :scan-string ;-- T_STRING + :scan-mstring-open ;-- T_MSTR_OP (multiline string) + :scan-mstring-close ;-- T_MSTR_CL (multiline string) :scan-word ;-- T_WORD :scan-file ;-- T_FILE :scan-ref-issue ;-- T_REFINE @@ -1490,16 +1512,17 @@ lexer: context [ if zero? depth [root-state: lex] depth: depth + 1 - lex/next: null ;-- last element of the states linked list - lex/buffer: stash ;TBD: support dyn buffer case - lex/head: stash - lex/tail: stash - lex/slots: stash-size ;TBD: support dyn buffer case - lex/input: src - lex/in-end: src + len - lex/in-pos: src - lex/entry: S_START - lex/type: -1 + lex/next: null ;-- last element of the states linked list + lex/buffer: stash ;TBD: support dyn buffer case + lex/head: stash + lex/tail: stash + lex/slots: stash-size ;TBD: support dyn buffer case + lex/input: src + lex/in-end: src + len + lex/in-pos: src + lex/entry: S_START + lex/type: -1 + lex/mstr-nest: 0 scan-tokens lex diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 59b9961a93..bc690e4a45 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -68,26 +68,28 @@ context [ T_PAR_OP ;-- 53 T_PAR_CL ;-- 54 T_STRING ;-- 55 - T_WORD ;-- 56 - T_FILE ;-- 57 - T_REFINE ;-- 58 - T_BINARY ;-- 59 - T_CHAR ;-- 60 - T_MAP_OP ;-- 61 - T_CONS_MK ;-- 62 - T_ISSUE ;-- 63 - T_PERCENT ;-- 64 - T_INTEGER ;-- 65 - T_FLOAT ;-- 66 - T_TUPLE ;-- 67 - T_DATE ;-- 68 - T_PAIR ;-- 69 - T_TIME ;-- 70 - T_MONEY ;-- 71 - T_TAG ;-- 72 - T_URL ;-- 73 - T_EMAIL ;-- 74 - T_PATH ;-- 75 + T_MSTR_OP ;-- 56 + T_MSTR_CL ;-- 57 + T_WORD ;-- 58 + T_FILE ;-- 59 + T_REFINE ;-- 60 + T_BINARY ;-- 61 + T_CHAR ;-- 62 + T_MAP_OP ;-- 63 + T_CONS_MK ;-- 64 + T_ISSUE ;-- 65 + T_PERCENT ;-- 66 + T_INTEGER ;-- 67 + T_FLOAT ;-- 68 + T_TUPLE ;-- 69 + T_DATE ;-- 70 + T_PAIR ;-- 71 + T_TIME ;-- 72 + T_MONEY ;-- 73 + T_TAG ;-- 74 + T_URL ;-- 75 + T_EMAIL ;-- 76 + T_PATH ;-- 77 ] date-states: [ From 9c8d608416434e9e308c278765c3cb0deaf7e16d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 5 Nov 2019 21:04:13 +0100 Subject: [PATCH 0388/3432] FEAT: supports implicit leading 0 in floats. --- docs/lexer/lexer-FSM.csv | 8 ++- docs/lexer/lexer-FSM.xlsx | Bin 24130 -> 24485 bytes docs/lexer/lexer-states.txt | 44 ++++++++----- runtime/lexer-transitions.reds | 110 +++++++++++++++++---------------- runtime/lexer.reds | 2 +- utils/generate-lexer-table.red | 80 ++++++++++++------------ 6 files changed, 134 insertions(+), 110 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 5c5f4fd3de..7d3ef1d6aa 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,5 +1,5 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_WORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF @@ -20,7 +20,7 @@ S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_M S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_PAIR_1ST;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE @@ -37,7 +37,9 @@ S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR; S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_DOTDEC;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;S_DOTDEC;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 9dc8d922cd1b8da212930ac126547e254a5e8cf9..fa46f610806b6819c9ee4eafb1c57d47a86e5aff 100644 GIT binary patch delta 8642 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 881d49b382..ac46b6f8ab 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -38,6 +38,8 @@ S_SKIP_STR2 S_TAG_STR2 S_SKIP_STR3 S_SIGN +S_DOTWORD +S_DOTDEC S_WORD S_WORDSET S_URL @@ -201,15 +203,15 @@ S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->delimit10->T_INTEGER \->"%"->T_PERCENT - \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"e"|"E"|"'"->S_DECIMAL - \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE - \ \ \ \->delimit11->T_TUPLE - \ \ \ \->else->T_ERROR - \ \ \ - \ \ \->"%"->T_PERCENT - \ \ \->"x"|"X"->S_PAIR_1ST - \ \ \->delimit11->T_FLOAT - \ \ \->else->T_ERROR + \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"e"|"E"|"+"|"-"|"'"->S_DECIMAL + \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE + \ \ \ \->delimit11->T_TUPLE + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"%"->T_PERCENT + \ \ \->"x"|"X"->S_PAIR_1ST + \ \ \->delimit11->T_FLOAT + \ \ \->else->T_ERROR \ \ \ \->"#"->S_DEC_SPECIAL->not(delimit12)->S_DEC_SPECIAL \ \ \->delimit12->T_FLOAT @@ -221,15 +223,15 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \ \->else->T_ERROR \ \->"/"|"T"->S_DATE->not(delimit13)->S_DATE - \ \->delimit13->T_DATE + \ \->delimit13->T_DATE \ \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME \ \->else->T_ERROR \->delimit11->T_TIME \ \->else->T_ERROR \ \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR - \ \->else->T_ERROR \->delimit10->T_PAIR - \ \->else->T_ERROR + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR \ \->"#"->S_SHARP \->"@"->S_EMAIL @@ -237,6 +239,19 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->else->T_ERROR +S_START->"."->S_DOTWORD->digit->S_DOTDEC->digit|"e"|"E"|"+"|"-"|"'"->S_DOTDEC + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR + \ + \->not(delimit5)->S_WORD + \->":"->S_WORDSET + \->"@"->S_EMAIL + \->"/"->T_PATH + \->","|"#"|"%"|"$"->T_ERROR + + S_START->"<"->S_LESSER \->delimit1|">"->T_WORD \->"<"->T_ERROR @@ -255,8 +270,9 @@ S_START->"<"->S_LESSER S_START->"+"|"-"->S_SIGN->digit->S_NUMBER \->"$"->S_MONEY - \->delimit14->T_ERROR - \->else->S_WORD + \"."->S_DOTWORD + \->delimit14->T_ERROR + \->else->S_WORD S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index e6257225a5..25d5ef438a 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -41,6 +41,8 @@ Red/System [ S_TAG_STR2 S_SKIP_STR3 S_SIGN + S_DOTWORD + S_DOTDEC S_WORD S_WORDSET S_URL @@ -170,57 +172,59 @@ Red/System [ 2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E 2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ -00001313333435363832020C2727272727270B32202706320132271D26263227 -2732310100010101010101010101010101010101010101010101010101010101 -0101010132310202020202020202020237020202020202020202020202020202 -0202020203020232320202020202020202020202020202020202020202020202 -0202020202020202020232310404040404040404383904040404040404040404 -0404040404040404040405040432320404040404040404040404040404040404 -0404040404040404040404040404040432313A3A07073A3A3A3A3A3A0A07073A -070707070707070707073A3A07070707070707323A3B3B07073B3B3B3B3B3B32 -07073B070707070707070708073B3B07070707070707323B0707090932323232 -3232323232323232320932323232323232323232323232323232320707070732 -32323232323232323232323207323232323232323232323232323232323B0A0A -0A0A0A0A0A0A0A0A3B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A32 -323C3C0B0B3C3C3C3C3C3C3C0B0B0B0B0B0B0B0B0B0B0B0B0B3C3C0B0B0B0B0B -0B0B323C4141121211323F320D320F1212321212121212123232123241411212 -121212121232410D0D0D0D32323232323D323232320D0D0D0D3232323232320E -323232323232320D32320E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E32310F0F0F0F0F0F0F0F0F0F3E0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F323E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F323211111111114011111111111111 -1111111111111111111111111111111111111111323241411212414141414141 -4112121212121212121212121212414112121212121212324143431313434343 -434343430C13191B181532183243324232432A14323218323232324344441515 -444444444444441615321B321532443244324232443232323232323232324444 -441515444444444444441B324432321532443244324232323217323232323232 -3244444444444444444444444416444416161616444444164444444416441616 -4416163231454517174545454545454532324532323232453245323232323217 -3232323232323245464618184646464646464618181818181818181846184618 -464618461818463218324632321A1A3232323232323232323232323232323232 -323232323232323232323232323248481A1A4848484848484832321A32323232 -48324832323248321A323232323232324832321C1C3232323232323232323232 -323232323232323232323232323232323232323247471C1C4747474747474732 -324732321C3247324732323247321C323232323232324732321E1E3232323232 -323232323232323232323232323232323232323232323232323249491E1E4949 -4949494949491E493232323249324932323249321F323232323232323149491F -1F49494949494949491F49323232324932493232324932323232323232323231 -3A3A21213A3A3A3A3A3A3A21213A212121212121323A21213A3A212121212121 -21323A2121212121212121212122212124212121212121214A21212121212121 -2121212132322222222222222222222221222222222222222222222222222222 -2222222223222232322222222222222222222222222222222222222222222222 -2222222222222222222232322424242424242424242424242421242424242424 -2424242424242424242424242432322424242424242424242424242424242424 -2424242424242424242424242424242432323A3A13133A3A3A3A3A3A3A323227 -27272727273A322732273A2727272727322727323A3A3A27273A3A3A3A3A3A3A -322728272727274D3A272732323A2A271E2727272727323A3A3A29293A3A3A3A -3A3A3A29292929292929293A322929293A2929292929292929323A4B4B29294B -4B4B4B4B4B4B29322929292929294B4B32294B4B2929322929322929324B4C4C -2A2A4C4C4C4C4C4C4C3232322A2A2A2A4C4C4C322A324C322A322A2A322A2A32 -4C32322C2C323235363232022E2D2D2D2D2D2D3232202D3232322A2D322F2F32 -2D2D323243432C2C434343434343433213431B321532433243324232432A1432 -323232323232433A3A2D2D3A3A3A3A3A3A3A322D3A2D2D2D2D3A3A2D2D32323A -2A2D322D2D2D2D2D323A414112121132323232320F1212321212121212123232 -123241411212121212121232413A3A2C2C3A3A3A3A3A3A3A3232272727272727 -3A322732273A2727272727322727323A +00001313353637383A34020C2929292929290B34202906340134271D26263429 +2934330100010101010101010101010101010101010101010101010101010101 +0101010134330202020202020202020239020202020202020202020202020202 +0202020203020234340202020202020202020202020202020202020202020202 +02020202020202020202343304040404040404043A3B04040404040404040404 +0404040404040404040405040434340404040404040404040404040404040404 +0404040404040404040404040404040434333C3C07073C3C3C3C3C3C0A07073C +070707070707070707073C3C07070707070707343C3D3D07073D3D3D3D3D3D34 +07073D070707070707070708073D3D07070707070707343D0707090934343434 +3434343434343434340934343434343434343434343434343434340707070734 +34343434343434343434343407343434343434343434343434343434343D0A0A +0A0A0A0A0A0A0A0A3D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A34 +343E3E0B0B3E3E3E3E3E3E3E0B0B0B0B0B0B0B0B0B0B0B0B0B3E3E0B0B0B0B0B +0B0B343E43431212113441340D340F1212341212121212123434123443431212 +121212121234430D0D0D0D34343434343F343434340D0D0D0D3434343434340E +343434343434340D34340E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E34330F0F0F0F0F0F0F0F0F0F400F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F34400F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F343411111111114211111111111111 +1111111111111111111111111111111111111111343443431212434343434343 +4312121212121212121212121212434312121212121212344345451313454545 +454545450C13191B181534183445344434452C14343418343434344546461515 +464646464646461615341B341534463446344434463434343434343434344646 +4615154646464646464634344634341534463446344434343417341515343434 +3446464646464646464646464616464616161616464646164646464616461616 +4616163433474717174747474747474734344734343434473447343434343417 +3434343434343447484818184848484848484818181818181818181848184818 +484818481818483418344834341A1A3434343434343434343434343434343434 +34343434343434343434343434344A4A1A1A4A4A4A4A4A4A4A34341A34343434 +4A344A3434344A341A343434343434344A34341C1C3434343434343434343434 +343434343434343434343434343434343434343449491C1C4949494949494934 +344934341C3449344934343449341C343434343434344934341E1E3434343434 +34343434343434343434343434343434343434343434343434344B4B1E1E4B4B +4B4B4B4B4B4B1E4B343434344B344B3434344B341F34343434343434334B4B1F +1F4B4B4B4B4B4B4B4B1F4B343434344B344B3434344B34343434343434343433 +3C3C21213C3C3C3C3C3C3C21213C212121212121343C21213C3C212121212121 +21343C2121212121212121212122212124212121212121214C21212121212121 +2121212134342222222222222222222221222222222222222222222222222222 +2222222223222234342222222222222222222222222222222222222222222222 +2222222222222222222234342424242424242424242424242421242424242424 +2424242424242424242424242434342424242424242424242424242424242424 +2424242424242424242424242424242434343C3C13133C3C3C3C3C3C3C343429 +29292929293C342934293C2927292929342929343C3C3C28283C3C3C3C3C3C3C +34292A292928294F3C292934343C2C29342828292929343C4646282846464646 +4646463434461B34283446344634443434343434282834343434463C3C29293C +3C3C3C3C3C3C34292A292929294F3C292934343C2C291E2929292929343C3C3C +2B2B3C3C3C3C3C3C3C2B2B2B2B2B2B2B2B3C342B2B2B3C2B2B2B2B2B2B2B2B34 +3C4D4D2B2B4D4D4D4D4D4D4D2B342B2B2B2B2B2B4D4D342B4D4D2B2B342B2B34 +2B2B344D4E4E2C2C4E4E4E4E4E4E4E3434342C2C2C2C4E4E4E342C344E342C34 +2C2C342C2C344E34342E2E34343738343402302F2F2F2F2F2F3434202F343434 +2C2F343131342F2F343445452E2E454545454545453413451B34153445344534 +4434452C1434343434343434453C3C2F2F3C3C3C3C3C3C3C342F3C2F2F2F2F3C +3C2F2F34343C2C2F342F2F2F2F2F343C434312121134343434340F1212341212 +121212123434123443431212121212121234433C3C2E2E3C3C3C3C3C3C3C3434 +2929292929293C342934293C2929292929342929343C } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1f660f8d29..a28a624547 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -116,7 +116,7 @@ lexer: context [ skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000 + 00000000000000000000000000000000 } path-ending: #{ diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index bc690e4a45..1424ce36b3 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -51,45 +51,47 @@ context [ S_TAG_STR2 ;-- 36 S_SKIP_STR3 ;-- 37 S_SIGN ;-- 38 - S_WORD ;-- 39 - S_WORDSET ;-- 40 - S_URL ;-- 41 - S_EMAIL ;-- 42 - S_PATH ;-- 43 - S_PATH_NUM ;-- 44 - S_PATH_WORD ;-- 45 - S_PATH_SHARP ;-- 46 - S_PATH_SIGN ;-- 47 - --EXIT_STATES-- ;-- 48 - T_EOF ;-- 49 - T_ERROR ;-- 50 - T_BLK_OP ;-- 51 - T_BLK_CL ;-- 52 - T_PAR_OP ;-- 53 - T_PAR_CL ;-- 54 - T_STRING ;-- 55 - T_MSTR_OP ;-- 56 - T_MSTR_CL ;-- 57 - T_WORD ;-- 58 - T_FILE ;-- 59 - T_REFINE ;-- 60 - T_BINARY ;-- 61 - T_CHAR ;-- 62 - T_MAP_OP ;-- 63 - T_CONS_MK ;-- 64 - T_ISSUE ;-- 65 - T_PERCENT ;-- 66 - T_INTEGER ;-- 67 - T_FLOAT ;-- 68 - T_TUPLE ;-- 69 - T_DATE ;-- 70 - T_PAIR ;-- 71 - T_TIME ;-- 72 - T_MONEY ;-- 73 - T_TAG ;-- 74 - T_URL ;-- 75 - T_EMAIL ;-- 76 - T_PATH ;-- 77 + S_DOTWORD ;-- 39 + S_DOTDEC ;-- 40 + S_WORD ;-- 41 + S_WORDSET ;-- 42 + S_URL ;-- 43 + S_EMAIL ;-- 44 + S_PATH ;-- 45 + S_PATH_NUM ;-- 46 + S_PATH_WORD ;-- 47 + S_PATH_SHARP ;-- 48 + S_PATH_SIGN ;-- 49 + --EXIT_STATES-- ;-- 50 + T_EOF ;-- 51 + T_ERROR ;-- 52 + T_BLK_OP ;-- 53 + T_BLK_CL ;-- 54 + T_PAR_OP ;-- 55 + T_PAR_CL ;-- 56 + T_STRING ;-- 57 + T_MSTR_OP ;-- 58 + T_MSTR_CL ;-- 59 + T_WORD ;-- 60 + T_FILE ;-- 61 + T_REFINE ;-- 62 + T_BINARY ;-- 63 + T_CHAR ;-- 64 + T_MAP_OP ;-- 65 + T_CONS_MK ;-- 66 + T_ISSUE ;-- 67 + T_PERCENT ;-- 68 + T_INTEGER ;-- 69 + T_FLOAT ;-- 70 + T_TUPLE ;-- 71 + T_DATE ;-- 72 + T_PAIR ;-- 73 + T_TIME ;-- 74 + T_MONEY ;-- 75 + T_TAG ;-- 76 + T_URL ;-- 77 + T_EMAIL ;-- 78 + T_PATH ;-- 79 ] date-states: [ From fe403714342f0dbcf57723651d6f17f439b1d47c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 5 Nov 2019 21:26:33 +0100 Subject: [PATCH 0389/3432] FEAT: adds support for special float values to lexer. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 24485 -> 24520 bytes docs/lexer/lexer-states.txt | 3 ++- runtime/lexer-transitions.reds | 35 +++++++++++++++++---------------- runtime/lexer.reds | 27 ++++++++++++++++++++++++- utils/generate-lexer-table.red | 19 +++++++++--------- 6 files changed, 57 insertions(+), 29 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 7d3ef1d6aa..da026336f2 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -21,7 +21,7 @@ S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE; S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_EOF +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index fa46f610806b6819c9ee4eafb1c57d47a86e5aff..62ffc18bbd6df22c50756c1b3b3083e1daac6cf3 100644 GIT binary patch delta 8503 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 A#{d8T delta 8536 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index ac46b6f8ab..e843a888e2 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -70,6 +70,7 @@ T_ISSUE T_PERCENT T_INTEGER T_FLOAT +T_FLOAT_SP T_TUPLE T_DATE T_PAIR @@ -214,7 +215,7 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \ \ \->else->T_ERROR \ \ \ \->"#"->S_DEC_SPECIAL->not(delimit12)->S_DEC_SPECIAL - \ \ \->delimit12->T_FLOAT + \ \ \->delimit12->T_FLOAT_SP \ \ \ \->"%"->T_PERCENT \ \->"x"|"X"->S_PAIR_1ST diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 25d5ef438a..7f5ac08376 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -73,6 +73,7 @@ Red/System [ T_PERCENT T_INTEGER T_FLOAT + T_FLOAT_SP T_TUPLE T_DATE T_PAIR @@ -196,32 +197,32 @@ Red/System [ 454545450C13191B181534183445344434452C14343418343434344546461515 464646464646461615341B341534463446344434463434343434343434344646 4615154646464646464634344634341534463446344434343417341515343434 -3446464646464646464646464616464616161616464646164646464616461616 -4616163433474717174747474747474734344734343434473447343434343417 -3434343434343447484818184848484848484818181818181818181848184818 -484818481818483418344834341A1A3434343434343434343434343434343434 -34343434343434343434343434344A4A1A1A4A4A4A4A4A4A4A34341A34343434 -4A344A3434344A341A343434343434344A34341C1C3434343434343434343434 -343434343434343434343434343434343434343449491C1C4949494949494934 -344934341C3449344934343449341C343434343434344934341E1E3434343434 -34343434343434343434343434343434343434343434343434344B4B1E1E4B4B -4B4B4B4B4B4B1E4B343434344B344B3434344B341F34343434343434334B4B1F -1F4B4B4B4B4B4B4B4B1F4B343434344B344B3434344B34343434343434343433 +3446464646474747474747474716474716161616474747164747474716471616 +4716163447484817174848484848484834344834343434483448343434343417 +3434343434343448494918184949494949494918181818181818181849184918 +494918491818493418344934341A1A3434343434343434343434343434343434 +34343434343434343434343434344B4B1A1A4B4B4B4B4B4B4B34341A34343434 +4B344B3434344B341A343434343434344B34341C1C3434343434343434343434 +34343434343434343434343434343434343434344A4A1C1C4A4A4A4A4A4A4A34 +344A34341C344A344A3434344A341C343434343434344A34341E1E3434343434 +34343434343434343434343434343434343434343434343434344C4C1E1E4C4C +4C4C4C4C4C4C1E4C343434344C344C3434344C341F34343434343434334C4C1F +1F4C4C4C4C4C4C4C4C1F4C343434344C344C3434344C34343434343434343433 3C3C21213C3C3C3C3C3C3C21213C212121212121343C21213C3C212121212121 -21343C2121212121212121212122212124212121212121214C21212121212121 +21343C2121212121212121212122212124212121212121214D21212121212121 2121212134342222222222222222222221222222222222222222222222222222 2222222223222234342222222222222222222222222222222222222222222222 2222222222222222222234342424242424242424242424242421242424242424 2424242424242424242424242434342424242424242424242424242424242424 2424242424242424242424242424242434343C3C13133C3C3C3C3C3C3C343429 29292929293C342934293C2927292929342929343C3C3C28283C3C3C3C3C3C3C -34292A292928294F3C292934343C2C29342828292929343C4646282846464646 +34292A29292829503C292934343C2C29342828292929343C4646282846464646 4646463434461B34283446344634443434343434282834343434463C3C29293C -3C3C3C3C3C3C34292A292929294F3C292934343C2C291E2929292929343C3C3C +3C3C3C3C3C3C34292A29292929503C292934343C2C291E2929292929343C3C3C 2B2B3C3C3C3C3C3C3C2B2B2B2B2B2B2B2B3C342B2B2B3C2B2B2B2B2B2B2B2B34 -3C4D4D2B2B4D4D4D4D4D4D4D2B342B2B2B2B2B2B4D4D342B4D4D2B2B342B2B34 -2B2B344D4E4E2C2C4E4E4E4E4E4E4E3434342C2C2C2C4E4E4E342C344E342C34 -2C2C342C2C344E34342E2E34343738343402302F2F2F2F2F2F3434202F343434 +3C4E4E2B2B4E4E4E4E4E4E4E2B342B2B2B2B2B2B4E4E342B4E4E2B2B342B2B34 +2B2B344E4F4F2C2C4F4F4F4F4F4F4F3434342C2C2C2C4F4F4F342C344F342C34 +2C2C342C2C344F34342E2E34343738343402302F2F2F2F2F2F3434202F343434 2C2F343131342F2F343445452E2E454545454545453413451B34153445344534 4434452C1434343434343434453C3C2F2F3C3C3C3C3C3C3C342F3C2F2F2F2F3C 3C2F2F34343C2C2F342F2F2F2F2F343C434312121134343434340F1212341212 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a28a624547..a65f1a2820 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -116,7 +116,7 @@ lexer: context [ skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000 + 0000000000000000000000000000000000 } path-ending: #{ @@ -1156,6 +1156,30 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] + scan-float-special: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + fl [red-float!] + p [byte-ptr!] + f [float!] + neg? [logic!] + ][ + p: s + neg?: either p/1 = #"-" [p: p + 1 yes][no] + if any [p/1 <> #"1" p/2 <> #"." p/3 <> #"#"][throw-error lex s e TYPE_FLOAT] + p: p + 3 + either zero? platform/strnicmp p as byte-ptr! "NAN" 3 [f: 1.#NAN][ + either zero? platform/strnicmp p as byte-ptr! "INF" 3 [ + f: either neg? [-1.#INF][1.#INF] + ][ + throw-error lex s e TYPE_FLOAT + ] + ] + fl: as red-float! alloc-slot lex + set-type as cell! fl TYPE_FLOAT + fl/value: f + lex/in-pos: e ;-- reset the input position to delimiter byte + ] + scan-tuple: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] @@ -1422,6 +1446,7 @@ lexer: context [ :scan-percent ;-- T_PERCENT :scan-integer ;-- T_INTEGER :scan-float ;-- T_FLOAT + :scan-float-special ;-- T_FLOAT_SP :scan-tuple ;-- T_TUPLE :scan-date ;-- T_DATE :scan-pair ;-- T_PAIR diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 1424ce36b3..b18e176c2d 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -83,15 +83,16 @@ context [ T_PERCENT ;-- 68 T_INTEGER ;-- 69 T_FLOAT ;-- 70 - T_TUPLE ;-- 71 - T_DATE ;-- 72 - T_PAIR ;-- 73 - T_TIME ;-- 74 - T_MONEY ;-- 75 - T_TAG ;-- 76 - T_URL ;-- 77 - T_EMAIL ;-- 78 - T_PATH ;-- 79 + T_FLOAT_SP ;-- 71 + T_TUPLE ;-- 72 + T_DATE ;-- 73 + T_PAIR ;-- 74 + T_TIME ;-- 75 + T_MONEY ;-- 76 + T_TAG ;-- 77 + T_URL ;-- 78 + T_EMAIL ;-- 79 + T_PATH ;-- 80 ] date-states: [ From ed3c7b96a0e283d7d00a89062996aa936fa0566c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 5 Nov 2019 21:45:11 +0100 Subject: [PATCH 0390/3432] FEAT: allows comma as decimal delimiter. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 24520 -> 24507 bytes runtime/lexer-transitions.reds | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index da026336f2..4fb781b85d 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -18,7 +18,7 @@ S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_C S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP @@ -45,7 +45,7 @@ S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;T_ERROR;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 62ffc18bbd6df22c50756c1b3b3083e1daac6cf3..c5fd5014cab9aa428ddb018c003782bfa0ca57fb 100644 GIT binary patch delta 13485 zcmb7rby$>J*FFu>2!nJeAp=OOptJ!ijp=PHmD4{8F%H!@U$aH z#SorTih<5V&PXFmNk=u5QPLT8bHF;3cP_8xxqj1(#?qDeVddS*0`?b<{rkhfso2?? zmy~46O~*Iy#*YeWk!QKDhv(SOj^gXscfYP|qI1=00n@K*9)U-{`2E@{4#o?MMl2YB;Yf*x#sajh|Ur-&rwnm6~*P9Njkdo$&D- zEjnKE0cs{IEBb*Sh`Ei*&?5ucuVs=Nr?7G7AzC1DoBp}kW8bWS^Pj-#$`)U&G zcH%d5TY~r-UY$!*Wi*W{_R6#$Z11mmYpEwWU8k*(r z7z*=#-`mtTV6E~3?F?L*?H-vKE2@2Uw)C_~?D>$@^X=`E-H!Fmo%E)<`UL1qeo>Jt zLTGf8ZbNl&`RVbRNACVP=RI`NRWfjTlXlFzh?PSx&lqBP9(CMnve@am)9BdC?Br+r zAXV3BMc>P7(!S})%_T(8wsI(7GKmRDxLWJ~LS}Q(@nq4_wR>mq;aa0??~?wDvJELA zV<~WP!f5!r0odaB=X*C@TGZ@B$lknbwTuHkqi(u%MU^H>-b(BfsP3|V@E-Zma;#q6 zT5QIs*OgjkC>7u4QIK*DH%`wD+(o%$oKv*%&tQY=P4b^#1(Rk|Kl+3)2&R^&34{@F zlc><3sNZs4f2bLdIuu|avqL0ugB?4EinUF4K{3B!jzb#x$>UoeNHguL&je}M3vU7- zfq_v#UNf8{IF(#pGLV!2LD@Q#Ruubv=rQHnG3-?_$@r&P zW^bP_3j@U6uAPW|=GLLFVT5Ga(Pu-ZeqJxwDiuUo>4zT?iy8!`(#ey`GX^>nfJnfs zuh1<%I2ArB&*$Qk@ZF?bFW22iI9fHyw=5SYpbZY9iH3#pnN@kND`=8O#&HB|6YvpO zkaW{PII>+i;wXooFd-;iQdL8J@{TBA%hmMkB>-N;GCGKeS)Di#W?tS3ySwQraGywr zq?`KfwQM=fWjO(sTTfcBzWDmH)i-^PgZ?#IIH2zpPO$id(`{{K(sO`CHfx^?^7hld}OM6#_o2by4wh;NZ7`5P&F$MVk<%693Im zB)MGc3e)g`@ViU>;jaQT!YwSg>2E)KBw0E{-l^i54tdI~kdZj6#bzJ3iX|GLNY{StOQ=Odar=D`gZ3qqwi2I`MRYf(u3WAw zUkd$jAagvu&Fto6;n+I*GSdoL(!o`l@_AG9J;YX z8?Ea^UuswIe-{7HWnrXuLDgHttP#zj?l}mitPavLsl&~$FaVi~w;XKKX4%Nl4Td%ZGY8G8VG*~1TTk9n^c<-<*WpX1}m2k)*ji}im=u_f1GB< zPS&G6-;BH?6}a=9M2i!`f3+>s?OG;?7M7I_Fe+Fg6w0)tyEzbwx&9F4@Z?t-Ww5Ci z-%Ayunm*j$1eT&;E{5Ukyu>d}m?JWVm6*xWVJqccRRT&mbV>Drkbg%Qrk~dKV{h$H z$+Q2e%a+zDFFgD)SbO!Ji5qWVsD5}+1@Y}Xb!yn#99zMU47A&b+vRx^MAW4@L_)jvTCbmr69GTca!|z$HfNX5HvR~2ta!CID9%+vG@NhIl7A&6k z!Bn8KPbE$z)es&18?FTVt+X~DRN41G?4AZC;vwnY^%(6POlt?NFi)v;?M9_)i)e!b zRQ@(63(#VmDc{Yu?s3OX`b)@?#=iJpOu^#!&z$Gxb61z`3)lNzD3>Cs?Z|J(P~$4Y z7c%y(36E^*Vkrf1AcQ=J;P*tVrK^K(KDg!3{}5ANOcX&Ls1c5~;FA@rLbF)Q8v&(% zrdK%K9U9xg+TPTEb5jdUDlfyqp&^sk){nLb8)=s>@NY{>?he!1uZsu#gTR3{ZPCA? z9P^Dg{R;g&_u_#6FE)HUXe%u$u-G~K>8e>{(Yd4HgH4waGBN~Hq`VS3L{{j2bT}vC z7li`<37hpGzqqI%c2X!O4Z)l(-J>3DpK3}HiY1Phkb5dk59=s4jCNLG*%w^Es7V9M zdMs#(kpKQKw)w`J=iRc6id>)e8fz>d!SXLMy>NQi^$=^TZ!i%Hgl6=ckXgPmIYojT z_&yQj<$*PIS$FCt;Jo57gGuRshKm5RqCGSpys(!x9@lGB^U*#b-wg~bH)?U0d#D+0 zBm&|88;K6Xn3BJ*+vnWxo^7_pT3qI8tY7;4QKuWOf>&vbee)S12_HgkSS1D*1o?xr zx%nzX#!dBu?psLKKKGWI#d?{}SeW$r4lqMq=dbX5H+>CqHRg7(f)j3gDmHvpuZ}p-4ha1a_OGZi8 zypaj_seQCxmuvDpG@=Gg60JJ&E9IbkgM)xS?Q>vu5|q)R)65yt3g@+O9d}n&gH#rE zN^B~Zpz`P6P-3C{=<+|}OC!Q;HRd>6QhS|Wl;o^b>#pETgU)tXV)XYh`it_Q#2u}| ziB>A1ea^kUDVF`O>g8rMbM!Mm5?G(YoYQzUQB`3=Bs-dU+tdeDcJKl#-#)RD_p18~ zHc#_8ghWD#1UPh!vPRcV?(%#2K3L~pR63MYYV-moue*mI8K!9;JsN+ub~?TRvGLds z;{Yjw{}MIS1fJ=O7qWK+#wrV}*n)@d0@d^1H?J3V2ng8QnD1b(4gVs9e_t`N<1R&^CM|N2QLV4c zZ}wKdZjI#KjoH_5{ZqQ@+pXM2r+c#ER2EV|5t7R7%(#KqH%H^>vC10KY)7mLe5%BL z8kxB~pHrx@#=f(iq&fpYvK%+yN5#V$&Qh`uR{W04*wsV()=>|uXRxxJ3iI60&u*kc zv5D=B82*8s4z6NC4gbNxSa!lTheye*%q_o%hl5i=@<#&&f}e4U0{9YF!rlUYEN5av z9`47G`5(=wZ|RZGe-JX1#D>3&pJq5eXlzV0M~U;%#zw@p9VGJk+&MpZ>`v#LCE6~I zr;r1CZ*8jP3muFE-SbR`ai7GJ8d6i})a>eVGb*p9U)}eX7v3WK_-K_xXEK;`=&epA zoh!6h`_8MUl7rMu-GB%BQ+c5K2hhFsy-^C#eZp51{WX4-nvtYZz7uf@v1*h{ex$@N zQzqTFNTE*P;LACCI7@YMP^9G6HFl+K!;fDH+TFPfnZDOK)w00=nX4u-Ah@`(ua2fgO($QXBwRL%B!VcKGg}T7K>zfqo%zU ziA&l$)ug75j&@y7vMdRFls$|T))nRAhV)l4Sicv6UT z0yxq;D~zc!5+j`N7D1V0LEP7EoyvAYTi9;B!tdR1F`?Pwi%Hm+>GamO`aJrq02b4i zUT8zt0fA|8eMF7Tu*q75pYg@8po?LQ#;PvGLTFo>b#L7m!DEH_xOmb90YZH|$H*90 z=?|}!DzaB~zSzAC=|A+0lMl7}i4LR>&;q}d(J<$2@qOwAO$&#p%52FF7^E=;&kyL? zk-d4&jf#6|JK@+3XXpuS-7P+%>NpX?xd8kn-jA5$7&aUnH8?dlCt&FE`9W#O*JIk} zXF-AcPimEIT$GaJHjW$T1|dB#gUfE6dpDcTxL$!tmHZPocA^9)HLO6SyWAff{C)N} znwtDPH`jS~N~2JL4g>0<-Cy*n$!yN=P7nCRS;OYD?~$vw%d^>;lg-_qYYCtl zS)Ur2?h|&IIX~dlXya_OGqh*}IRAd!j z^hG6k75f|Hg2q*-sabuFsZwI-ciCl0_~faV$L-1%*yoc?r~2dCOEQo?3>Me%rTLTR zz&n282$SHeTN|45eHukVW(__F^)3dJvyJZ`I-8J0fEO#vv91ZVWUMpIlb=Z}&XsQu zp8&_(z<1QwFBKm1@uC!>N1pCd?E5O)M;@nNXHI9JLR{z0X6#QplyBvn#?q7B`Hm3i z+uUC3+t{tMgX*us<4aE+hnSR&=1(VAI%waYg?jC=qu$pa$WI{IZ$O*woa?y%Q1ejB z2(0IewIuX3<|+`aIjT{b0-^M{l1ZJlxMoP50Yk0^QBO2wEtDr-zYQEjx>c$a0-D#2 ziR_+Np%5?Rut_cV?egqHw)0C2lm})9r682oqLO;+?FvU64BmFx-jB0zM&InsRW-|{ zD8mkKu>-%F5}qbazu8+DnC&*HPwf^P8{K$f=#}$HTbrgc9wW{T3iHXKzn$~y=~@(E z^d5EfZN)8{7!m_F2*jE|@vTI1U6;Q|@vH|QFJb6$N9o}yH~ z&mlCrt_HqrD9RZ-X04>av+y%zui9*$>*bI*Ct}e6RN`~`eS*wa8$);WwE9-LYEd7* z(c>Y3Bdp~KrSQok|**BI<}WR?$5EASMJBN@hnr$68^8gLUZ zC%^&^zl$m7=7_oU>M5RRqQ52&2SWK3I)6xK-xu8kdug(GXUfG?r?E`7z&29|VyXjO z9ub3YBqfRa4DBfQ@Y*9?eTH_G`+0qll4h*u3+?lZKf+`(&#-0>OO?`q~%L`M3E!uy0-0OeR5 z{H+9WIo9Y-f_tL4iK=qfX`{QjTDKB!CivpfIvZB+c`QylduALoJwxQg=_NY8l*L#& zLM>aVDfGon2c7RvgIM)lO$S}>%hDd|X!(6F?ap>%t-TgyBI4fG3ewTyw`#|P7Cx&@UkI<{mn!^Go4yp@$WK(rPz#$6FX87YOsIt|hS%`Z z7aG*U7Q!p|Zx&9}!j{4t_+wjn{V=g1(6)ZlZ^S~I@c4tlM<=V?oId^KK#h|{0;}7Z z^L$Me+pu>Jc%5)dwpbaOU7POpJ&#RkU2O00=g@~8bMqDok)}t4{fo{;xrA%=SU&*D+p>JYSYE;af)?|{g zwrn+sjpLs>6J|xa`VMU?&++0T$;Du6fm#nDgPH4K-};|o=o4#T>*2xtafJpou(j|g z{z?n2W5b!15`JbxvM&#*ptc3Cvi~JU@tg9OMP;7R$OeV6f8;_9FkMFtT;&X=zr8Z8YNRa63?5}W3!kp2OHF?3nDO|&zarlfBBP_yv%R9gP zPF(5$X@Z0>vw3Cns{bVZwf*;5d;nm%=2f%IlFFc0rX86V1~XB+_YJ(C925p`?oM7x zjisH0y+9N_=XD?7LDbe^;`B8fYv~YkhZtM?mVe=vvQ-KRU%kZykhD)gA8A?=_A(_< z2pgNbH?Ic7G$t+dPi+tBW2k}iv1d!`Ny1g3J!^9PO**pp0MF2D9nBU;>)T79|pUK)ANleZ{(m6E$k$~I{% zyw^L2e9CD0gh)iX`cq-sAXnJ78rFwJUXJxCGLFck6Mfv>Ra^W7OJV0#4XE0PrXaHX zgA%KGZS#)*GQJp&B}wmfh9`s_GKs%2;xgP8OaTNK1jMFbveb=iLLwP9~xo!rOR~W(9zuto>yw+CjCQ4hv`ZH&)^`lZ{&J zo45R}iQrJiQ!O{L1b2j%4SG z4Fn|mFRRKYGYY$y(>DtQ7~+;uwofr)LvEhWnq5YfSxlx|i^>Q|V4`{ZI*F4XI;4$z zRT+^<3f8sM^#ueRDg0GL3Kj=rs(D0;`tvu7tWZ43xu9>$ttNJGr!ROj-jC*}V_q#sw z_Q>VCG~!uO^b#cq3g0o``#?8la4VUBE;cTSd&G#-ItQoiZ4v^eu68dLEC}l5v#cmq zZ#%m-w-KbEZVhvTt;Io)MmLjCl{o>R6gD;Y zYTgN8#1SK~Bf=elZOutDGCY+|QQO}ie}LJlZS2VwRD>)MY-MC`NUv0E(b9$gQ>_3*$x%*tBi>Bc zntCUAX_2bFqT5}cdC8ChzNK4TQ@qSbJKxgnu36q8g_&Yy;#~?Q)Q(0IWhctD-de|m*w(L`2%8!;L1-sBL2fhRv!Kwvf)yzUV>tWD|T)p6i9L3p)KWU z-rtGF7ZBa*`rp@;oXJ;S+MyspxvDo&zWVi-1dY8`k3B*0m2 zGN@?m;`6A1I4smE!*sMz?NB``qW#8NB4oRnQVb5MljV7 zp|zc;&p0YX|G_}SKyOs*Nr7Cln{e&iB~s0<0n50<#FjX{)CpR`!4eQj7JbHw zPjK^m!P^D7I+%h?2A?&W$x0hBSW2;t6;+%92g zMtGme4MeAE$pzEpY~SPw<{?n~@J!5nv01?1kO;m}iZ(61`b=$rNY(lg=^DutEmuP& zOZU)arLw-a6>6x-SZ$F8%NzzMZQ4P%5FVkie#}XB2SPMCNq!wU~ue2 zh{=~vrpPWMv?T6jV^}WwBA=E3;eR}2CXY_gwMBMS2xQX@+vtV=8`5g?T$K~X!w)Ic zR|+N-N!w;~XX6W@1i;&k0t`hp(FLHb%%Vo|GAY_IIKzaQ#H#EGxWbC&4?Y;!-X^ld z>!nNhy+C9RWQ_XF`b!yWS`lMb?$UqYjH` zknnB)Qa+m`ovc~!pnF<)5&qiU0q(#l;c+sFrz*dkwTtuPYEsZ{IGxR zyZj?|-`=0nCX7e-AMQqw8xGs!43m)aAeYESGmPOsZVAIT?vMZrwHL`$!4zatg#~w^ z^9|0nUvr{n z@&HD{C-zGs!nDF;bR&tlVpQ!?8)TYRjH+L2b=O)z*=0m-H&Z{+C$I{83nRI3gJTmQ zwrDtmt}Q^uEt1D$6C;UDW&~E*(QVtLGZ@fHh6(QJO*&+mR+(iMjWp;=i|JBzCOKT_ zonWydhZx)c-?)tlXY~MXWw%HuuQ% zR5bO(El>1fvl9&x%sry^!g|CBH-vwyB`lE@A+(xSOp%~}OPQdU5!o5nGrhlWn0>jx zP&gmX*-&v+8l(QK#(@w4)9d?cgwj^c0}Qc+2TNfW45p)ICzDZ?bK54LUicpk`Si<>3N@>LsR;7+^@2&Wip6@Y*Ue>q$=nY>x5gj-x1Pf{ z57B)vV|zDO6yp;WkO*OP13JsQvrGOWsMLfHXOH$eUPQf-&2k{a{Aw*4Myb+v^ZCYiO0%RYQ^V-O+g9S?4Z6OL22BF8YtPfLLI0l?%#EylkfO)vHv0$W z{-#|2Yp)k1xr3EiM0<&qjNZ0-%Z!lKg5@UwQP%F*DsHfXV*{jLWmHHEQthD2Xp1vU z@JlTJe`w|Z%Zfh=^p9!;jzgcyI=g)zMSC@)0k#-77aVLk+KMtf&y4x+{32aUEcjUs z#R>+jT8enIi`(~GWg>*156A%_jg;+1Effs4SY*j1`wEY}hZE4Lz_homDl#{Y)tFEa zU4vaB<=i171(CurXI_z_!^HRt`F@>e3}E>bW>=EY?a60SAjK-NkedGcc^DV`h_=J3Lwx*uAzeRK#*YOn&!O ztWxi5GDnX6mXytrfhCm}%?*Pslj>$9wlCUlsoQ=>wZT>tVP&50X~A02N1r+Xh%$7| z=@^e1KmWJFD9Fv2I-wlFHvje#J!x)>a0WeE2_eSy zYII_@S9#0ZD#3`eca=%bqk6knULEPm)fD769sO!fWpTa!fiy|mr-Z(n=ewmqC=#~N zHtw?pQf1*%NAKZ+GK_!=)w(7!n7OrMD`#e2zwa;ptkB}E zz&3%Aqkr{O%~V3XIs6iI+) zJ&l}2g&#=Mf#;}U@Ir;H&L%}!B>rB^fqzx=g8thKw%%%T$$Y|p$Wgp9QXV8zgZ_B4 zU0}(W6WL-J{*$$Um{|<5B9_%ea>vrTu!>~l>h;V~mK*J(Q)5_$U&IpZb|*57PqL{P)1_0`vh{_vAUk|5_wN4uMFE1pnTj3!EN

wk`uvapZV&EnKdQR2hzwS>ZJM%7Asm3V+{%?+!?t8Em7fSAA*X#v@iEb%3}t9vbVV?#2=AB9{~c{t zv29OEl8i?5Mh#tE#)lQdSdA&V zTng&vLhHcr>Y3CG*d~?`4KQ`=L z^z!*bw^DYqog4O|YN@SphRHLlL)w_H8#kBdMFK~!YiT1Z+W$PHA?In5!Kj645$5Ei zVim?e99}W~d3eP$_t>pI_GK!=$O+L<-L)`f37Rk)h0-KQi0;}1SLWz@9c+#&nZdD# z40`nw#)Qf4tjD6h7CBY9jxdbYf>&On6Y%VpJ-2g}t4M5u2LIMU>)A5ki(TRYZtfIB z{dQ^uQkA*wRaJ=12PgdYsX(banpRl6T3Htv8WhmRwdN;X4;j6uYdw0bIK`i!qncMS z^{aE!cljn#yy&D3E8Fur`+4Ye`)1J_V4Qu{x9Mz6xVG_pZEw0ILMT*Y>%oV9*{-^( z{i-JPmC`qW%&aeP0P3 zcL*=1Qsd^S8KDq+>bw=aYkBxQC1Vpbw;P^n?9VvbaSY64qV1FBIVXaox8F6fvG`6Q zdObLF)d=6jxL8~Z`l&kqwg|Sf?`uQUna#Z@X&DG-SOb)!WVoBo=|`RWJ7XHDckV6F2hW0=h~A`$N=HP3^N3RdVv+$ns?qV5 zB~Ld+oU1Y;!n==*(c9_QckBBs1ypAY)U6pe3u@Pm+ZKKu6Z*CQqp2~O#vUnCu z@1&Bh05};kCr&ssUK5VAlsf*@CVN-6sM&ulmn#=wpi01Plh?a!5g67TZO(|3$;T3p zGAwD1yuqIv2dYNd%|-Kur$$W{^7Cb9zKZ)en5vwPHge-JOnxtycKeM=JdJKaoQTSB zaDku7q>krG453DwD+3oeC#;KKqdaP(0xS9 z)ehjGq}-~+`Jo$RS}>{;PH`d>{8m#5em%>B`?jTUc`fUVOEv8$`r8j+T;opUt`ZAY z%+`!=?z^M-?K+v6PvbL%;pcBtevf>x%|=yk)~Pgu+?Ho%rnY8$ysF;z zvFaPO14eiTL^Ky?&DSLNNzNtxb)y4G&KxE1Zoq~IJRkCzX;!gv-0_?3YIuy+H&YP;)nJo7%95#=vP~x4XFUf=h*Ss5Wewge@#p!4o2{{yv z-~MT`$JBa-{9(s<%@Zf|LK-RR2(|d66Of(u}rIGRX(YelA-Kv zMtWIdB;m|+$#Y&gx0=@*DC(XVzaIXa$M2x&>`_tzVP=N{Vf0;X9G}bb9Gx(@x%^&FJb#E1=b7Z; z7Dz6$li~Ek?`DDeyxbxyD>Tx>CH(br4*ZgdG2Sp6{3{zbJi-KwH_DE^WQL!ylfpk^ zZzni@-Ci?gV)^T%Xjsnv^E1tfeX|DycQ6I9{P`>o9WM5TpWi>k+`k5un}T@$PX7NH z_DS(Sr2sBs27(iqG2zm|+0Eo}5%9-m(zqsYq!|QHK^yL*%LRXvA*i}kx$Ed2&7D0n5+So$vy{dLln<{Em zt*R}te$nr}xA$}Jef<29$4O4kdB4W<^?W^F?;Q2b_+8ET?_XY|2!X%2Pfdk~C*_I< z=eW)Uh~DsZbA3JC?K!1!iR9~%3R(v2>#onO=uFnj_Pp`EiVoU8hrbJIMla6o=F@y) zgin?wrmu7ouC46}bP*H=Lp6Ika%}*GCUme-?oL*45JI@5c)5Jl+eYE4b+bJBY;WN3 z)f8quaI#VUhxO|C>b+BS?>A>yObLM5Etdy^WE4zC?Q;Yg-mrfgc-1>~0`-_tFzuYi z6a*Jq@16M-Ksu*Y&wR0Ux0=%nrtg;zZrPXCHO<_3QQx-KfO-fhIgdafkwFY&N1L6i zdqa#;#=`Y6GiN(Ha~ofbWq!nac22KM9aP)w?``S6I`s6Fx_jyv-S5zO(ul=cWIP6J ztasN=gH|^7tv0?zDqLZGGF~bXr%>-f_<%WB^;4?Qr z8~^H^_GL&P(aDkCiR{_R(PVb8KtZmyUSk7OL;3)kJTQOF{b@mGB&PC)f3bBzV@k~A z9RQel&V(4Sj{GAKiT)xoyQFCDa$HBL?fwqMubHFF4vY~crX68G{ zreNo~JmT%nv^louSI_WJHV)9X53XqnmbHvKbf`opyS0cJS=RBG6rSJ z2cK%3lHSuyRz>14EmA1v)0&JBJ4`v9MsBRrWwZKON~P~3Vk1Xc_9{SWe)=jtj~aBXKSq4^cs$k7n;=ecbr8aaeu5mB?SOnOCf zMdmP1B8CefwrAPO8Ok}?ZLYU8BF+4oRR!53x4$SwbPV6)uV8fe)&;#e&&qHu{Q3p0 zi%8l;PCj+L(9EGwGwEG`s{8jU&=s>7Vv4*^zS6D{cG7~dIBL81M2h@j^kJezOBX=2 zM$)v}k=BV$D`1vYukWSUHEPV`eM|8-)G=EhKSYWnPKRiCO02FCwYNBu8T@YuR={#R zy>dlI#qF+q!<@4P!7*mi588!H09%o8uTQqvi04Q`MG>$CRK&$YA(<WjUKaP{(R>Ss+oE3==r z3qJ6+Un*m?dYvgCQFokGnRvnANhZ@3;ZP%Tetc`JkbKhyYC6 z?{2&)Ym-y9Q#<2f)#mEWAWX=op?C&ue&+D5n{QM^#H|VP=?%yYn30|u3~?ZlOyifSyyfjEro z=m(;mYIS?bCDslb-v&zL1_9$E0VNI9xMmG&=$E^?2U4a-~$iHA9g1n^hw`*1mWQDMD3L-+VUPTKP+CVs73L_-= zicVJ&;}tz%Wpjk|xp|%mW&Uq}0GvY!(9Vgpm()Tz_a!$zDK*MJCW1@-eD&f5$22u3 z=!vr`a^k^slyAqA33@7sa+h`XCu@EU`?wxX|*|HSftcU4W`V{f< ze_dc8`%zR#@9)XdERCvJ;SGzl_dI)Szc$+gIXu22^#SVC*JHq$1QphTgvw{MOVFYJpA;SB^QR z^-y&dzktu5%nwNSqZtq}@|-sm-{ z_!3?`@;!^UBI$}6u~SutMn2K!!oL-xCQ!PB;RCI8yG_BgC#~c8e`=NnP4-*`Or2#x zRR-aCx3i&0BZ8!VtVM%c$f-UjM@Xii>wok0>A`bqrfb=k983NdL+O2076LxVFy{P}CW`TVqiIg&F<5M1Cc#-r5}U;LAuq6~WN z7~aj4dV?1g972;93jPSXYP9Z0lVhQLO3<$Y#ucL=T&CJ(^-I}s92ysgfq2JBVk>@i zGshNv2E|IK#`QRyKN?$6OizdbzbGkj+h341)5(1_q+5RK^Zw}x1IBtwb4%*V6XMk` zj|rtegpEXJS^NVRZy1B@5C}#bmS7r0tv1!s+3j?aZoN==!?tsk(J*i6IJDDsR}_}aroYhCKAyxo?j zKJvCZIMUK1N3Y<_4*O5Dle?c!NmOb~viJ&weFfl9r^&7kH&bVEQcfh-R7e{g?a+*F zCcdHFZQ`WAC=oU1Halvozr`c@AWdkgGFm5eHh++wD2|+yAs#x%YDWyh5w9wVkzPL9 z#91I15ait*+^)*yaBLXTkLI=aoE>{d!asE%Qx<68I$c#(Ka_Okx#2mH0{_9J{%pBc zlm58IVlNQ>74C_Q(2^Po%j>%N_2>JrM6Ej0TXmNFqM2b@I4*P}e9-P@kDml$%l0+k z@o|%Lep|K>eU}c0lpeKUuZg59RtdkT?f-KAH-fU@sm6U<1SqTM;y6V5T3}sr_g~Zs zENM^-4aa6${9zVyLgmXdm*YQ>gq21y!6LqS?drmn2^r%+sQOWMjGqb5fvcS5fJu{o27TIF;GRj|$angP z>5zB-hJON-!fVRryju)m!5M~69px?`+TC^G1$s?%CSpK3kt z;94hPHU4YyKV3~2QK$IWcHeF34mr)9p7*-^gYF|Nr;_eRHB;FTqYJ>lnpvVBdiXne z<(5;%;E4R%vfDu=$S1cXa(ri9Re`ui)1CCKzFGFkBw| z%_N(BW++=r97t$V=+ z6fb+fmFjQOoM4X?60S3p&t1JhNTKHN{lh*19$xK*U$YXNl1mh@l(?*)2n4^z)W$kg zLsVZ->ws?bFhyF2TolOH@U4BmRb8@{My93(7v-$wGmp(k`B1%cunAM=^a0)1xyF$Q z>PQ(I9XVj=GgD0D1(|#h&W|G={FG#AW1JBGks9RLe3|H4Ge^V67vLl-CN5nmdu_!7 zVu8wVjbu8it-@HqbX7;d@$y~8#RoRidiq8o6F*8q>SCrC=>7Sne&qScp3;h!Sqk+TQyv}f1vg( z9W%!n<$*`k?y06b|Lpc7TZ-gmkyF~I@9h+XMj8l*N>W~J0uHC2Zwxv_T}n;}DsFzZ zpx#lP^7I7!^J!c~cTlRVaLQX-X`LT?Zh1zFc%i(Ynn^j^D}H4g@x0PFjT#fCPeaR+ zvzyAorRG&q!54fh;&}^_mZkhoT2ZdUbo-2hmPm!!g*gN?cA zQM*MGcPiS!0ARi7`k-8pK}7xfYl4Ht%?p=?nRDv{=GL7&0xrbpQqA{+TTIIH_S+hd zz$9w13|-Vae5n{xGY9_!L2K;~9FES(ZmI9{%`2V!b^Gdc#quTOZ|P6ryL^F0P6`T9 zQ(6mx7oe0RW6Y7QnQuPS&Wry%E{6>&mak{xF2VNs0%LBe9w?^?g8Bp9Dul;))!hh> zO>xdITbG++S8o;h#N2pme|d0~+Zlb+wZH0=H18f2>vu`>`yE!6JM&FbB6kSayynnJ z=eKknzPr(Hoc7JRcyCsM%JS>ShHgf&{s}1g6FEe&PK`_cy(|%>)kD#P6;wTay^SX>}vECwOOcA?Qbo&eNl=-6kc5d_>@4b7qYi6Ipjw z#f0e91uYFBvT^WiBCkj?O;q9iy^I$acO1saE_22_O}>hUXAi%6ofDXRG}TeoxpiRa zeMb6f212j3om>_~{^cMDFtn34X|D>r4wC^++%AZTehR5;juehc51bHVMVF8zgzWy9 z1%Q+7`GK~RwvFlP1Bc3tVEF)#!^e*fw)UsoHwR35_nT*4H~QYP29A7BmVQjlolGi3 zMwSD>;p~~;!T9vaCP0%x6S+W<|8oO(Zh2wrNO*afMlyrOri4AX?kM<>=WKa+`ec0V z-SOUO^-kpGLFC%Ymo!-H(((LqhD|!q*mUwZ+4ykj%}CAB?#lkRPYv~$g|)dU5dlx& z&@(6zqY&71a!Okm)X2HiWIcO!+Iav>e+fFdaXq;4#53R+ST6lO8B-$Jyc>M<*atXS zyX-duj29QXLpM5`6MKNh#@gn9nj^1c&7O1zIw6JS>SgzV?4d{>cK0P_Wbf(x>CcrD zbAzMnE6qje>45J+jndjwn+;8^Lh~)_v$|V>QeRkU*q3gnH)_zdl=%2G=f3AXTXD$8 zoM5Ns+Gk^c&290keOo_{e*RpUxD|-mK6T}yscVv&IrT%32LL>0kAjb;mKPTA<$Hib zFW?}ft-6z0mO8Ot2!+Ts4=u7CYOYBjJ+rxawks@(*~y(;K4Z<$Jo1py*|Z6i4Xis| z==BIbFg=L7qm&b{H>_>`)hivq971+}KDO+lk~AcK0DrNAD{Bd?ZK}* zm9cy_^|Etdn>W7XhVabD4J5j4D`PjWQ7&L>ZEkLYy4Pc;vu*3g8qcAgM4`{cRjZy4 zu(LC_Vpc(}!mV5U7$3gvZ@J@_ORSr;a_uN@oE>a=Y;WeaW?Uuh3}(2j@}mxYd*_B z4|OBiODCf^N!6hu4)++OF^{RjWzBk=Izbu&iZ`N>mWnrGkfuB(Bk&)ux|fVgdosfs z1QYHN`x$fNl%@gUbAe}9_}pwg@9soyX;F!zI94?WdXW2Sx-jdTrp}UrJ&ToGy|^#3 zz>Il>N1vLT(pKKP$)Mtfa3j`dftf0f)U69Vlh)AGusP*xG*ai!zp$w7jYx=AX)*#R zUK^>D?W+mhF}T?CnWeHzQ&rHW;C_FE43sTjk#O5WZ0Yd z)W$J|0i|!Pbl+X4QruK34$}BjeY$hsd;ph3slkV;<$})6%og%a4%`akrq1e*LC-$N zPm{mBX;%`KcWp`-{@K!dgd`E9V0qhA6=lTFo^u zHz$01_sxEd^&_TEenHA{cyL+ug z4jo+2MfF?VlOwL?E&=c=h_w6)7P$;>f{@5FW9=5smr9jnJ~s3 z@RA!WfV}1<+uK*^XuF8GMe*ZxK%)5r=88OYv_0I&p&zM}m*nr0FQBCo zSj;y;8OROztD*0#z;htDTpS@6;KdMs`IRHPukb90nmqH7-8?)W0+UZUvYUfvLrmn& zkL(uUD9B^^$s=yf5PUzKE1A@Pcm(|E5=Msw-4sezEBHDH!N;nd3|6MQcLxVlPW2KMYKlaiN1y)CxMmt_CF0RO!XRdf zwkmztKExnkT4Yt~(LTl?W4dk?&n=&S^zo(jyo2yo+bbjFW+ir&Lw0ND)giu)62T5z z{&BF3Wr~B&99q9g@<{mey@Jt{cfqN9XtR?~|5(?jy@f&9G#0KUzzKYWSPlIwJgn6| z{(3!l`;vlxR7NBBlg*Tym-{Kp9nuxp{C>Ra+#PCz%lqrF=heN%el5JJ@k4oNe6{ey zQ%EXvceTmhm0?fSDfXPd1@fNScA-IG{(zX8{X3Hf>(NmPN%@v`-=b>;7>mv7pi9w} z0ym2%>Y&R&bPx|YzR4gijY>p2Qz~wu+$x{Af{Ex9!Zj~sN$6e3QdPPjbV;{Sc>;_*OyTN4t z(X6Iafag>v=Rtgmz_((v8t6)NlE7H;L=DuEu`&Y~jgYA?)1RDlc>9UV_;CUeB2Mu> z9XDq<)rK*|hZ>iP2XO zRA9i;_HoO4XuM1RaALDU`QygBUetP&h35PnqbefBJX{`0YyG&*W!t5mM|#~+uBG)o zE?=UiC4!JYitCm}hu20_mwcN1QErFG6?ih_bEsKoIib#F#8q&RElCSyC^Nno35)~703q{=3Xu@Y_h<{7Axw(agMu%NfUXK ztzI1Ab-euvoasP)y5O*I&A?IT)00eoMX|7NL_!xVE>&VA5fDWoV9wojxv3=q#H z7HiY@y#J!6>6}I1`#cfJ*y9lvCfFy*G8m}%Of#5-A+02nF3laQF&a4Pu&}rLIeTQ$ zhIpj0gvvIxwd)b!FQKno88}38%{yd;V3;t6291Z{1i!P5WnlgPlrkxlSj)d41CVyg zXBNHru%mkYc! z)u}`zxcJy4lueqD*#s&HAYBHd0(5~tAjnP?q9ua*R({Px7iyhhz6HIn>n?B$RSJ{j zM&|ZHghPkR|f|1E5qL6O3XR=%BKn-J-N> zh?3th2?9q*jOp^?MEbn!?nZQ@7K=0Zh=rDt77L3&+eE~W2s zOqVmp^vl<J%a1PhSB!HGE7FWrlAQ2|Npk)KDe!NUwg`rrhE!2+KK>IV7^OOY`^;>uVDr{Q1qbt1Fv>QQDE7A zcL%R!#(H4cK~#mFr0bAk5aA{Mli?CVQU2-jyXuY1@Zq5{eO(p*TzBY=^sy8Me;&j3 zv6LB-hZbv;lC+DKx&EK`EMVIza%(t}ly|})H{dTIb@D41HG~W48{Eg5&`5 zDHyvS@CZn%~ky$ECoXc*cS0{e!)y^;<*X2qxd-#Iy4A*Frn?!me{b;v4`*$kt;weeLtbr z>^dDi+&OCYOs~9f6HztGoBa`j9w?0YV`Vp1@gB*L=Unj zPe3{cSCUu63q_sfcR=p|i%u>kfs4Hb(#}N;dF9kOpL#|f&xA-%6-citty+OSbw3S9 zh+*fuf{fWDGPue3fG@%$eo@E$F9q}bcGXaE6=Rg<+Ct5{gqb}>t8-AZzB#CcE-p-O z5vFufp+Z$A=4d)g7aUtz><#AG5G78ryBkrn;3Ct_j!Eq?11JzTnF{}e|1b0t8=5I6 zwRt4zugQ{id=48fkj|b--JmM$Zzy(P}oNccL_;CuU^kBymm3oH$9tWa&{z^xTMm{iR{hF8?0Z%PLrt4Pl7J zbuyAMl{?TFDv8E}uN4Dk<@Jo@~UJkVQTmc2FMpv2>Mi7apHGcpqz0*h6NWcdK;%|+f|X~Z@wbUcj_xIXHB>d zACcWztDa21&>md)*%FXDG4@*_b1zP67#z32AEwNCf6KXu5$pywAw}E(%h_UEC_|VD z#K=27%iOo+u`S}y6C;FCqX`i9;4%5Te?}>E62F{O4J%ONz{fMHg{UyqgQzZ6i2#Vf|w5kq{4H@y$n z6Qc*luDtjyAc(=*wk9n_;rzRfl^K$m{fr}%q0#|*>i&i7N>bi^ag{R2Y8*ut4q3K7 zLV5 z0vN7pSpoMwWxhrRj!VWE0}7+)dzDwh14$@A@ijc$C1hl-^W0Svmcvt2ch*po&&k_& zOhz|Xajx`R&K6``9>sOX*lEl1Qo&)8`~T?CMH{jtuuHL({l8GhiXaB}+HNnW`Lh?_ zPM63l$M>#kSr3^E$3QgP`@-(A`L3XX{TCY;jH1mYB3UiQL88VCtS*7UcZWO8KboK{V(_6l_I>qeUfq~PJ)`DIyjb5nU|spU!Mo? zz2}Ux321k$7rr^*ABe2Gp?y&AuY%bz@jme+M8Lo>cj6qXj@3W==`W$zYBuFZi6)Ab zAohl}pu{H_fd01BPk^J zRdGDNwkNAKDsap zYO8CMG%>Ew&ll5Z3`)nrM16Ip;Dy?WD93$>WQY@qVOPVI!hiRRUxw`bGQ@58mwIgx z3@;6EsWL@LmEaXZ)0e0s43l`5Y9#ejLB(g9ql$%n(6dg~~C_~;9ZT>S zHGq&~()M@3SaZp7uArF99!I{eCQvC$t>iv#=jA z`N%=4%;*wKFbxcp>f4}qdqkm=x>KNx;|Qylo)E&h3jPnIRSLFW53-NB2i9}2a-!?oqO*5>hW!_Fd0 z`Kj);|ByUrG0QoRX55%b1Xo~uwMvo75B>`%lPG7R{{ z;G(xyL~q&i?GJnl>g@5i+#fJEP2n>WOK^^84pg^I~V6 z5ozVWNjEG$CM~1tg>{<C)^yJI=wQcby=h5+&w$Fgt{*U#4sRC2{rR^dG7B?L2cKkq1nk74hmrA#I zg|6Talfv-OvE>5fYWS?B))`U)?3VeF;8pU zFXrDHIadYF7jcb;`tpLan+uNo9^t?n`RJ16I%*||C^x+t=EFgMqio1sVijjZKw+K0 z+jEt5Ot4ytW8PLXHru+E-H;VRF+A7>G#``88t`k|hN?r_`j1*7G5nt9%wBvx7vtvp zWjCCq>$lV85HEL4cC543=d%z-E^6B;czG&ipo}tD5*jxdppp_di*IKmOdr)SnLWC7 z9*@+S_=o4LWS_T`YcPCSakNA-6pb+^Fs2!c>g(Wi#a~0$ zA2Uv4PBr7}G3)ZQOGW|4q*cKTMi0Uhn`gIi6vh96xy~I?>}~97RN7NkYwoU?3n9m zU)+jcT`L|6_~dU?Ykj1a{!IK_1KmxZuT1>4dDK|@gXliW1Gj|-{NEm4cz4N5Y#`J~ z(Ro#90jEb0{q!R#_+q3meDoy*19;802vv&P&FlCaDt%D zxFJDN=-q;BB%p6|HYw05oM9ibZha_%8gteTz^QKQzNpTY)HbQ8zRzozw&k|Di3WLV z-0yWK*lM8dJNC4C%AH2IiB-P4du>3Wo3!?zx;dM->?I&S69gQ?Uk{%8`^e4&JqL~g zYfgP@AZI*}uwFhsv4GUT>J92ng{J1i;FFVw%{35Onboq!BUi~mm302vQ66{r;0C?w=5?U=ZD zYue7_Xm)wxuGlcLqA%j|dU#O3PqF;1!;0Sg{n(gDexb>$2Bf8CC&>_NTcn z*|!B%6UA6p1Ax1$8E%Q~b$n};M~hY4F;>I6CM zJ%WA6nFhCMN~b|eraY@v_HVl@@`_AJ3(aj}eY>B$d)ZH-HbB5U4K z_@mr|iMK%F`tK79i@6Kq7c}X|^;d4bjUE*pS@3<(tquyf;m&6E^RCVj=cjU0lnSej zQ51;s28TAF>PL3(4xbymKM6zpgfC?Aa*eHsPKEz*#q90JB6)^G_OQwyNuz}X8yoR5 zfy&+dn%AR8?=E>2)>f3;l@}?{CeO3oQ4X5t`ytn&+R?vDUvg#~g5K zw-`{hmIp7K1KcMHmhwq4U+>n^`-CE4JDG*;2u(M*W1YJh#_@miZeU6n(pv`S5B^J zowbJq<^aX>I9XU4XJU%KS%is1Jm>hb$<~kZy_t5?DSK4N{k#smpY}!@52)O3dI?+7 zO?nxX4bHF(2rbUX)QdEC_mzTOVE9a+JT?Q^*g4ImdEFM(#RK2 zN`3A=CVcl&HsrP%ClL!*Mp8AV?S8FNJ2>`}IFFMo@Abxe6dxE@)FpSvk8X^7(#st@ zyU72%`|azCY6fcEPkc$}nVSwTv`gZZXIYrw6aV`E8ThfKB|-aD_!c`0oSdB;9()%> z(8-Q_dmTQ2JM7{3b%utM9L`}y%ksC!$ncnObpHFV53X$`!1~v7IQ01cIFI3mCs=`4 z{@D+H-=G~nZY52?sR0LTFv9t*LHKXsM%Ho!P7t`Y0XMwbT9^Q0fIH-eU$g-c7#aWi k^qvg^%Q*^^@$vACaZk5h{Czvzku*HshMT0q;{3z^2Y1$IKL7v# diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 7f5ac08376..6ce5174733 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -194,7 +194,7 @@ Red/System [ 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F343411111111114211111111111111 1111111111111111111111111111111111111111343443431212434343434343 4312121212121212121212121212434312121212121212344345451313454545 -454545450C13191B181534183445344434452C14343418343434344546461515 +454545450C13191B181534183445344414452C14343418343434344546461515 464646464646461615341B341534463446344434463434343434343434344646 4615154646464646464634344634341534463446344434343417341515343434 3446464646474747474747474716474716161616474747164747474716471616 @@ -224,7 +224,7 @@ Red/System [ 2B2B344E4F4F2C2C4F4F4F4F4F4F4F3434342C2C2C2C4F4F4F342C344F342C34 2C2C342C2C344F34342E2E34343738343402302F2F2F2F2F2F3434202F343434 2C2F343131342F2F343445452E2E454545454545453413451B34153445344534 -4434452C1434343434343434453C3C2F2F3C3C3C3C3C3C3C342F3C2F2F2F2F3C +4414452C1434343434343434453C3C2F2F3C3C3C3C3C3C3C342F3C2F2F2F2F3C 3C2F2F34343C2C2F342F2F2F2F2F343C434312121134343434340F1212341212 121212123434123443431212121212121234433C3C2E2E3C3C3C3C3C3C3C3434 2929292929293C342934293C2929292929342929343C From 70f24cfc71203351a78dec8e367d00a6c9deff71 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 00:03:53 +0100 Subject: [PATCH 0391/3432] FIX: typo in lexical class name. --- docs/lexer/lexer-states.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index e843a888e2..d748219c92 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -97,7 +97,7 @@ C_SHARP : # C_QUOTE : ' C_COLON : : C_X : x, X -C_X : T +C_T : T C_EXP : e, E C_ALPHAX : a-f, A-F C_SLASH : / From 799a41c318778e113f6c36c27846be62e80af4d6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 14:29:27 +0800 Subject: [PATCH 0392/3432] FIX: after change panes, no need to hold widget references --- modules/view/backends/gtk3/gui.reds | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index faaab61e6c..8cccba43ca 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -881,7 +881,6 @@ change-pane: func [ gtk_container_remove layout child/data child: child/next ] - g_list_free list s: GET_BUFFER(pane) face: as red-object! s/offset + pane/head @@ -899,6 +898,15 @@ change-pane: func [ ] face: face + 1 ] + + child: list + while [not null? child][ + g_object_unref child/data + child: child/next + ] + unless null? list [ + g_list_free list + ] ] ] From 62ee4e2c9617a0a454c3386a132524706e06ca35 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 22:50:22 +0800 Subject: [PATCH 0393/3432] FIX: full keyboard keys support --- modules/view/backends/gtk3/events.reds | 471 ++++++++++++++++++++--- modules/view/backends/gtk3/gtk.reds | 4 + modules/view/backends/gtk3/handlers.reds | 54 +-- 3 files changed, 459 insertions(+), 70 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 4baf7da7fb..8e7dfe5356 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -43,6 +43,392 @@ evt-motion: context [ sensitiv: 3 ] +char-keys: [ + 1000C400h C0FF0080h E0FFFF7Fh 0000F7FFh 00000000h 3F000000h 1F000080h 00FC7F38h +] + +keycode-special: [ + ;-- FF00h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_BACK ;-- FF08h + RED_VK_TAB ;-- FF09h + RED_VK_BACKTAB ;-- FF0Ah + RED_VK_CLEAR ;-- FF0Bh + RED_VK_UNKNOWN + RED_VK_RETURN ;-- FF0Dh + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF10h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_PAUSE ;-- FF13h + RED_VK_SCROLL ;-- FF14h + RED_VK_UNKNOWN ;-- GDK_KEY_Sys_Req + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_ESCAPE ;-- FF1Bh + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF20h + RED_VK_UNKNOWN ;-- GDK_KEY_Multi_key + RED_VK_KANJI ;-- FF21h + RED_VK_UNKNOWN ;-- GDK_KEY_Muhenkan + RED_VK_UNKNOWN ;-- GDK_KEY_Henkan_Mode + RED_VK_UNKNOWN ;-- GDK_KEY_Romaji + RED_VK_UNKNOWN ;-- GDK_KEY_Hiragana + RED_VK_UNKNOWN ;-- GDK_KEY_Katakana + RED_VK_UNKNOWN ;-- GDK_KEY_Hiragana_Katakana + RED_VK_UNKNOWN ;-- GDK_KEY_Zenkaku + RED_VK_UNKNOWN ;-- GDK_KEY_Hankaku + RED_VK_UNKNOWN ;-- GDK_KEY_Zenkaku_Hankaku + RED_VK_UNKNOWN ;-- GDK_KEY_Touroku + RED_VK_UNKNOWN ;-- GDK_KEY_Massyo + RED_VK_UNKNOWN ;-- GDK_KEY_Kana_Lock + RED_VK_UNKNOWN ;-- GDK_KEY_Kana_Shift + RED_VK_UNKNOWN ;-- GDK_KEY_Eisu_Shift + ;-- FF30h + RED_VK_UNKNOWN ;-- GDK_KEY_Eisu_toggle + RED_VK_HANGUL ;-- GDK_KEY_Hangul + RED_VK_UNKNOWN ;-- GDK_KEY_Hangul (FF31h ~ FF3Fh) + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF40h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF50h + RED_VK_HOME ;-- FF50h + RED_VK_LEFT ;-- FF51h + RED_VK_UP ;-- FF52h + RED_VK_RIGHT ;-- FF53h + RED_VK_DOWN ;-- FF54h + RED_VK_PRIOR ;-- FF55h + RED_VK_NEXT ;-- FF56h + RED_VK_END ;-- FF57h + RED_VK_UNKNOWN ;-- GDK_KEY_Begin + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF60h + RED_VK_SELECT ;-- FF60h + RED_VK_PRINT ;-- FF61h + RED_VK_EXECUTE ;-- FF62h + RED_VK_INSERT ;-- FF63h + RED_VK_UNKNOWN + RED_VK_UNKNOWN ;-- GDK_KEY_Undo + RED_VK_UNKNOWN ;-- GDK_KEY_Redo + RED_VK_MENU ;-- FF67h + RED_VK_UNKNOWN ;-- GDK_KEY_Find + RED_VK_UNKNOWN ;-- GDK_KEY_Cancel + RED_VK_HELP ;-- FF6Ah + RED_VK_UNKNOWN ;-- GDK_KEY_Break + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF70h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_MODECHANGE ;-- FF7Eh (GDK_KEY_Mode_switch) + RED_VK_NUMLOCK ;-- FF7Fh + ;-- FF80h + RED_VK_SPACE ;-- FF80h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_TAB ;-- FF89h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_RETURN ;-- FF8Dh + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FF90h + RED_VK_UNKNOWN + RED_VK_F1 ;-- FF91h + RED_VK_F2 ;-- FF92h + RED_VK_F3 ;-- FF93h + RED_VK_F4 ;-- FF94h + RED_VK_HOME ;-- FF95h + RED_VK_LEFT ;-- FF96h + RED_VK_UP ;-- FF97h + RED_VK_RIGHT ;-- FF98h + RED_VK_DOWN ;-- FF99h + RED_VK_PRIOR ;-- FF9Ah + RED_VK_NEXT ;-- FF9Bh + RED_VK_END ;-- FF9Ch + RED_VK_UNKNOWN ;-- GDK_KEY_KP_Begin + RED_VK_INSERT ;-- FF9Eh + RED_VK_DELETE ;-- FF9Fh + ;-- FFA0h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_MULTIPLY ;-- FFAAh + RED_VK_ADD ;-- FFABh + RED_VK_SEPARATOR ;-- FFACh + RED_VK_SUBTRACT ;-- FFADh + RED_VK_DECIMAL ;-- FFAEh + RED_VK_DIVIDE ;-- FFAFh + ;-- FFB0h + RED_VK_NUMPAD0 ;-- FFB0h + RED_VK_NUMPAD1 ;-- FFB1h + RED_VK_NUMPAD2 ;-- FFB2h + RED_VK_NUMPAD3 ;-- FFB3h + RED_VK_NUMPAD4 ;-- FFB4h + RED_VK_NUMPAD5 ;-- FFB5h + RED_VK_NUMPAD6 ;-- FFB6h + RED_VK_NUMPAD7 ;-- FFB7h + RED_VK_NUMPAD8 ;-- FFB8h + RED_VK_NUMPAD9 ;-- FFB9h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN ;-- GDK_KEY_KP_Equal + RED_VK_F1 ;-- FFBEh + RED_VK_F2 ;-- FFBFh + ;-- FFC0h + RED_VK_F3 ;-- FFC0h + RED_VK_F4 ;-- FFC1h + RED_VK_F5 ;-- FFC2h + RED_VK_F6 ;-- FFC3h + RED_VK_F7 ;-- FFC4h + RED_VK_F8 ;-- FFC5h + RED_VK_F9 ;-- FFC6h + RED_VK_F10 ;-- FFC7h + RED_VK_F11 ;-- FFC8h + RED_VK_F12 ;-- FFC9h + RED_VK_F13 ;-- FFCAh + RED_VK_F14 ;-- FFCBh + RED_VK_F15 ;-- FFCCh + RED_VK_F16 ;-- FFCDh + RED_VK_F17 ;-- FFCEh + RED_VK_F18 ;-- FFCFh + ;-- FFD0h + RED_VK_F19 ;-- FFD0h + RED_VK_F20 ;-- FFD1h + RED_VK_F21 ;-- FFD2h + RED_VK_F22 ;-- FFD3h + RED_VK_F23 ;-- FFD4h + RED_VK_F24 ;-- FFD5h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + ;-- FFE0h + RED_VK_UNKNOWN ;-- GDK_KEY_F35 + RED_VK_LSHIFT ;-- FFE1h + RED_VK_RSHIFT ;-- FFE2h + RED_VK_LCONTROL ;-- FFE3h + RED_VK_RCONTROL ;-- FFE4h + RED_VK_CAPITAL ;-- FFE5h + RED_VK_SHIFT ;-- FFE6h + RED_VK_LWIN ;-- FFE7h + RED_VK_RWIN ;-- FFE8h + RED_VK_LMENU ;-- FFE9h + RED_VK_RMENU ;-- FFEAh + RED_VK_UNKNOWN ;-- GDK_KEY_Super_L + RED_VK_UNKNOWN ;-- GDK_KEY_Super_R + RED_VK_UNKNOWN ;-- GDK_KEY_Hyper_L + RED_VK_UNKNOWN ;-- GDK_KEY_Hyper_R + RED_VK_UNKNOWN ;-- FFEFh + ;-- FFF0h + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_UNKNOWN + RED_VK_DELETE ;-- FFFFh +] + +keycode-ascii: [ + ;-- 20h + RED_VK_SPACE ;-- 20h + RED_VK_UNKNOWN ;-- GDK_KEY_exclam + RED_VK_OEM_7 ;-- 22h (GDK_KEY_quotedbl) + RED_VK_OEM_MINUS ;-- 23h (GDK_KEY_numbersign) + RED_VK_UNKNOWN ;-- GDK_KEY_dollar + RED_VK_UNKNOWN ;-- GDK_KEY_percent + RED_VK_UNKNOWN ;-- GDK_KEY_ampersand + RED_VK_UNKNOWN ;-- GDK_KEY_apostrophe + RED_VK_UNKNOWN ;-- GDK_KEY_quoteright + RED_VK_UNKNOWN ;-- GDK_KEY_parenleft + RED_VK_UNKNOWN ;-- GDK_KEY_parenright + RED_VK_UNKNOWN ;-- GDK_KEY_asterisk + RED_VK_OEM_PLUS ;-- 2Bh + RED_VK_OEM_COMMA ;-- 2Ch + RED_VK_OEM_MINUS ;-- 2Dh + RED_VK_OEM_PERIOD ;-- 2Eh + RED_VK_OEM_2 ;-- 2Fh (GDK_KEY_slash) + ;-- 30h + RED_VK_0 ;-- 30h + RED_VK_1 ;-- 31h + RED_VK_2 ;-- 32h + RED_VK_3 ;-- 33h + RED_VK_4 ;-- 34h + RED_VK_5 ;-- 35h + RED_VK_6 ;-- 36h + RED_VK_7 ;-- 37h + RED_VK_8 ;-- 38h + RED_VK_9 ;-- 39h + RED_VK_OEM_1 ;-- 3Ah (GDK_KEY_colon) + RED_VK_OEM_1 ;-- 3Bh (GDK_KEY_semicolon) + RED_VK_UNKNOWN ;-- GDK_KEY_less + RED_VK_UNKNOWN ;-- GDK_KEY_equal + RED_VK_UNKNOWN ;-- GDK_KEY_greater + RED_VK_UNKNOWN ;-- GDK_KEY_question + ;-- 40h + RED_VK_UNKNOWN ;-- GDK_KEY_at + RED_VK_A ;-- 41h + RED_VK_B ;-- 42h + RED_VK_C ;-- 43h + RED_VK_D ;-- 44h + RED_VK_E ;-- 45h + RED_VK_F ;-- 46h + RED_VK_G ;-- 47h + RED_VK_H ;-- 48h + RED_VK_I ;-- 49h + RED_VK_J ;-- 4Ah + RED_VK_K ;-- 4Bh + RED_VK_L ;-- 4Ch + RED_VK_M ;-- 4Dh + RED_VK_N ;-- 4Eh + RED_VK_O ;-- 4Fh + ;-- 50h + RED_VK_P ;-- 50h + RED_VK_Q ;-- 51h + RED_VK_R ;-- 52h + RED_VK_S ;-- 53h + RED_VK_T ;-- 54h + RED_VK_U ;-- 55h + RED_VK_V ;-- 56h + RED_VK_W ;-- 57h + RED_VK_X ;-- 58h + RED_VK_Y ;-- 59h + RED_VK_Z ;-- 5Ah + RED_VK_UNKNOWN ;-- GDK_KEY_bracketleft + RED_VK_UNKNOWN ;-- GDK_KEY_backslash + RED_VK_UNKNOWN ;-- GDK_KEY_bracketright + RED_VK_UNKNOWN ;-- GDK_KEY_asciicircum + RED_VK_UNKNOWN ;-- GDK_KEY_underscore + ;-- 60h + RED_VK_UNKNOWN ;-- GDK_KEY_quoteleft + RED_VK_A ;-- 61h + RED_VK_B ;-- 62h + RED_VK_C ;-- 63h + RED_VK_D ;-- 64h + RED_VK_E ;-- 65h + RED_VK_F ;-- 66h + RED_VK_G ;-- 67h + RED_VK_H ;-- 68h + RED_VK_I ;-- 69h + RED_VK_J ;-- 6Ah + RED_VK_K ;-- 6Bh + RED_VK_L ;-- 6Ch + RED_VK_M ;-- 6Dh + RED_VK_N ;-- 6Eh + RED_VK_O ;-- 6Fh + ;-- 70h + RED_VK_P ;-- 70h + RED_VK_Q ;-- 71h + RED_VK_R ;-- 72h + RED_VK_S ;-- 73h + RED_VK_T ;-- 74h + RED_VK_U ;-- 75h + RED_VK_V ;-- 76h + RED_VK_W ;-- 77h + RED_VK_X ;-- 78h + RED_VK_Y ;-- 79h + RED_VK_Z ;-- 7Ah + RED_VK_UNKNOWN ;-- GDK_KEY_braceleft + RED_VK_UNKNOWN ;-- GDK_KEY_bar + RED_VK_UNKNOWN ;-- GDK_KEY_braceright + RED_VK_UNKNOWN ;-- GDK_KEY_asciitilde + RED_VK_UNKNOWN + ;-- 80h +] + make-at: func [ widget [handle!] face [red-object!] @@ -142,10 +528,9 @@ get-event-key: func [ evt [red-event!] return: [red-value!] /local - char [red-char!] - code [integer!] - res [red-value!] - special? [logic!] + code [integer!] + char [red-char!] + res [red-value!] ][ as red-value! switch evt/type [ EVT_KEY @@ -153,11 +538,8 @@ get-event-key: func [ EVT_KEY_DOWN [ res: null code: evt/flags - special?: code and 80000000h <> 0 code: code and FFFFh - ;; DEBUG: print ["key-code=" code " flags=" evt/flags " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] - either special? [ - special-key: code + if special-key = -1 [ res: as red-value! switch code [ RED_VK_PRIOR [_page-up] RED_VK_NEXT [_page-down] @@ -191,19 +573,17 @@ get-event-key: func [ RED_VK_APPS [_right-command] default [null] ] - ][special-key: -1] - if null? res [ - res: either all [special? evt/type = EVT_KEY][ - as red-value! none-value + ] + either null? res [ + either all [special-key = -1 evt/type = EVT_KEY][ + none-value ][ - ;; DEBUG: print ["key-code2=" code " flags=" evt/flags " special-key=" special-key " special?=" special? " shift=" (evt/flags and EVT_FLAG_SHIFT_DOWN <> 0) lf] char: as red-char! stack/push* char/header: TYPE_CHAR char/value: code as red-value! char ] - ] - res + ][res] ] EVT_SCROLL [ code: evt/flags @@ -425,6 +805,15 @@ post-quit-msg: func [ gtk_widget_queue_draw win ] +char-key?: func [ + key [byte!] ;-- virtual key code + return: [logic!] + /local + slot [byte-ptr!] +][ + slot: (as byte-ptr! char-keys) + as-integer (key >>> 3) + slot/value and (as-byte (80h >> as-integer (key and as-byte 7))) <> null-byte +] check-extra-keys: func [ state [integer!] @@ -495,40 +884,28 @@ translate-key: func [ keycode [integer!] return: [integer!] /local - key [integer!] - special? [logic!] + pos [integer!] ][ - ;; DEBUG: print ["keycode: " keycode lf] - keycode: either gdk_keyval_is_upper keycode [gdk_keyval_to_upper keycode][gdk_keyval_to_lower keycode] - ;; DEBUG: print [" translate-key: keycode: " keycode lf] - special?: no - key: case [ - all[keycode >= 20h keycode <= 5Ah][keycode]; RED_VK_SPACE to RED_VK_Z - all[keycode >= 5Bh keycode <= 60h][keycode] - all[keycode >= 61h keycode <= 7Ah][keycode]; RED_VK_a to RED_VK_z - all[keycode >= 7Bh keycode <= 7Dh][keycode]; - all[keycode >= A0h keycode <= FFh][keycode]; - all[keycode >= FFBEh keycode <= FFD5h][special?: yes keycode + RED_VK_F1 - FFBEh] ;RED_VK_F1 to RED_VK_F24 - all[keycode >= FF51h keycode <= FF54h][special?: yes keycode + RED_VK_LEFT - FF51h] ;RED_VK_LEFT to RED_VK_DOWN - all[keycode >= FF55h keycode <= FF57h][special?: yes keycode + RED_VK_PRIOR - FF51h] ;RED_VK_PRIOR to RED_VK_END - keycode = FF0Dh [special?: no RED_VK_RETURN] - keycode = FF1Bh [special?: yes RED_VK_ESCAPE] - keycode = FF50h [special?: yes RED_VK_HOME] - keycode = FFE5h [special?: yes RED_VK_NUMLOCK] - keycode = FF08h [special?: no RED_VK_BACK] - keycode = FF09h [special?: no RED_VK_TAB] - keycode = FFE1h [special?: yes RED_VK_LSHIFT] - keycode = FFE2h [special?: yes RED_VK_RSHIFT] - keycode = FFE3h [special?: yes RED_VK_LCONTROL] - keycode = FFE4h [special?: yes RED_VK_RCONTROL] - keycode = FFFFh [special?: yes RED_VK_DELETE] - ;@@ To complete! - true [RED_VK_UNKNOWN] + keycode: either gdk_keyval_is_upper keycode [ + gdk_keyval_to_upper keycode + ][ + gdk_keyval_to_lower keycode ] - if special? [key: key or 80000000h] - special-key: either special? [key][-1] - ;; DEBUG: print [" key: " key " special?=" special? lf] - key + if all [ + keycode >= 20h + keycode <= 7Fh + ][ + pos: keycode - 20h + 1 + return keycode-ascii/pos + ] + if all [ + keycode >= FF00h + keycode <= FFFFh + ][ + pos: keycode - FF00h + 1 + return keycode-special/pos + ] + RED_VK_UNKNOWN ] ;; TODO: before finding better solution!!!! diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 98177aca2a..68adf64b97 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -702,6 +702,10 @@ GPtrArray!: alias struct! [ code [integer!] return: [logic!] ] + gdk_keyval_to_unicode: "gdk_keyval_to_unicode" [ + code [integer!] + return: [integer!] + ] gdk_atom_intern_static_string: "gdk_atom_intern_static_string" [ name [c-string!] return: [handle!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 4cd85df524..315944bb7e 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -415,8 +415,7 @@ key-press-event: func [ res [integer!] key [integer!] flags [integer!] - text [c-string!] - qdata [handle!] + key2 [integer!] ][ win: gtk_get_event_widget as handle! event-key if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] @@ -425,24 +424,24 @@ key-press-event: func [ type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval - flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not - flags: flags or check-extra-keys event-key/state - - - res: make-event widget key or flags EVT_KEY_DOWN - if res <> EVT_NO_DISPATCH [ - either special-key <> -1 [ - switch key and FFFFh [ - RED_VK_SHIFT RED_VK_CONTROL - RED_VK_LSHIFT RED_VK_RSHIFT - RED_VK_LCONTROL RED_VK_RCONTROL - RED_VK_LMENU RED_VK_RMENU - RED_VK_UNKNOWN [0] ;-- no KEY event - default [res: make-event widget key or flags EVT_KEY] ;-- force a KEY event - ] - ][res: make-event widget key or flags EVT_KEY] + key2: gdk_keyval_to_unicode event-key/keyval + flags: check-extra-keys event-key/state + either all [ + key2 > 0 + key2 <= FFFFh + ][ + special-key: 0 + res: make-event widget key2 or flags EVT_KEY_DOWN + if res <> EVT_NO_DISPATCH [ + return make-event widget key2 or flags EVT_KEY + ] + ][ + special-key: either char-key? as-byte key [0][-1] ;-- special key or not + res: make-event widget key or flags EVT_KEY_DOWN + if res <> EVT_NO_DISPATCH [ + return make-event widget key or flags EVT_KEY + ] ] res ] @@ -461,6 +460,7 @@ key-release-event: func [ sym [integer!] key [integer!] flags [integer!] + key2 [integer!] ][ win: gtk_get_event_widget as handle! event-key if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] @@ -469,11 +469,19 @@ key-release-event: func [ type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol - if event-key/keyval > FFFFh [return EVT_DISPATCH] key: translate-key event-key/keyval - flags: 0 ;either char-key? as-byte key [0][80000000h] ;-- special key or not - flags: flags or check-extra-keys event-key/state - make-event widget key or flags EVT_KEY_UP + key2: gdk_keyval_to_unicode event-key/keyval + flags: check-extra-keys event-key/state + either all [ + key2 > 0 + key2 <= FFFFh + ][ + special-key: 0 + make-event widget key2 or flags EVT_KEY_DOWN + ][ + special-key: either char-key? as-byte key [0][-1] ;-- special key or not + make-event widget key or flags EVT_KEY_DOWN + ] ] field-changed: func [ From 9e00edd9b3e492a73940e49ed94241c499d8c842 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 5 Nov 2019 22:55:38 +0800 Subject: [PATCH 0394/3432] FIX: remove no-used debug info for key event --- environment/console/GUI/core.red | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index b0ec29472a..6712b6a1cb 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -847,18 +847,6 @@ object [ ctrl?: event/ctrl? shift?: event/shift? char: event/key - #if config/debug? [ - debug-print ["char: -" char "- " - switch/default char [ - #"^M" ["M"] #"^H" ["H"] #"^-" ["-"] - left ["left"] right ["right"] up ["up"] down ["down"] - insert ["insert"] delete ["delete"] - #"^A" home ["home"] #"^E" end ["end"] #"^C" ["C"] #"^V" ["V"] - #"^X" ["X"] #"^Z" ["Z"] #"^Y" ["Y"] #"^[" ["["] #"^~" ["~"] ;-- Ctrl + Backspace - #"^L" ["L"] #"^K" - ]["none"] - lf] - ] #if config/OS = 'macOS [ if find event/flags 'command [ char: switch char [ From 4a769ec912490119cb12465b5d4e70b6c4bc1a86 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 6 Nov 2019 11:18:49 +0800 Subject: [PATCH 0395/3432] FIX: small code improve --- modules/view/backends/gtk3/events.reds | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 8e7dfe5356..2a9babe5b1 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -775,14 +775,7 @@ do-events: func [ v: as handle! 1 SET-IN-LOOP(win v) - msg?: no - either no-wait? [ - if gtk_events_pending [ - msg?: yes - ] - ][ - msg?: yes - ] + msg?: any [not no-wait? gtk_events_pending] until [ gtk_main_iteration_do not no-wait? unless g_type_check_instance_is_a win gtk_window_get_type [ From 9d740ddcb5e19f148a1cb9e55e7d67bc80a3c19d Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 6 Nov 2019 11:38:18 +0800 Subject: [PATCH 0396/3432] FIX: improve keys processing --- modules/view/backends/gtk3/handlers.reds | 38 ++++++++---------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 315944bb7e..abc6a89215 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -425,22 +425,20 @@ key-press-event: func [ sym: symbol/resolve type/symbol key: translate-key event-key/keyval - key2: gdk_keyval_to_unicode event-key/keyval flags: check-extra-keys event-key/state - either all [ - key2 > 0 - key2 <= FFFFh - ][ - special-key: 0 - res: make-event widget key2 or flags EVT_KEY_DOWN - if res <> EVT_NO_DISPATCH [ + special-key: either char-key? as-byte key [0][-1] ;-- special key or not + res: make-event widget key or flags EVT_KEY_DOWN + if res <> EVT_NO_DISPATCH [ + key2: gdk_keyval_to_unicode event-key/keyval + if all [ + key2 > 0 + key2 <= FFFFh + ][ + special-key: 0 return make-event widget key2 or flags EVT_KEY ] - ][ - special-key: either char-key? as-byte key [0][-1] ;-- special key or not - res: make-event widget key or flags EVT_KEY_DOWN - if res <> EVT_NO_DISPATCH [ - return make-event widget key or flags EVT_KEY + if key <> 0 [ + res: make-event widget key or flags EVT_KEY ] ] res @@ -460,7 +458,6 @@ key-release-event: func [ sym [integer!] key [integer!] flags [integer!] - key2 [integer!] ][ win: gtk_get_event_widget as handle! event-key if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] @@ -470,18 +467,9 @@ key-release-event: func [ sym: symbol/resolve type/symbol key: translate-key event-key/keyval - key2: gdk_keyval_to_unicode event-key/keyval flags: check-extra-keys event-key/state - either all [ - key2 > 0 - key2 <= FFFFh - ][ - special-key: 0 - make-event widget key2 or flags EVT_KEY_DOWN - ][ - special-key: either char-key? as-byte key [0][-1] ;-- special key or not - make-event widget key or flags EVT_KEY_DOWN - ] + special-key: either char-key? as-byte key [0][-1] ;-- special key or not + make-event widget key or flags EVT_KEY_UP ] field-changed: func [ From 81c112b1bfa37910b5a597f99af2ef4d695b573f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 6 Nov 2019 15:09:02 +0800 Subject: [PATCH 0397/3432] FIX: one level menu not responsed --- modules/view/backends/gtk3/gtk.reds | 6 ++-- modules/view/backends/gtk3/handlers.reds | 6 ++-- modules/view/backends/gtk3/menu.reds | 44 +++--------------------- 3 files changed, 11 insertions(+), 45 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 68adf64b97..b6fe558bb7 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2965,9 +2965,7 @@ red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" container-id: g_quark_from_string "container-id" red-timer-id: g_quark_from_string "red-timer-id" -css-id: g_quark_from_string "css-id" -size-id: g_quark_from_string "size-id" -menu-id: g_quark_from_string "menu-id" +menu-key-id: g_quark_from_string "menu-key-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" @@ -2987,3 +2985,5 @@ in-loop-id: g_quark_from_string "in-loop-id" #define GET-CAPTION(s) [g_object_get_qdata s caption-id] #define SET-IN-LOOP(s d) [g_object_set_qdata s in-loop-id d] #define GET-IN-LOOP(s) [g_object_get_qdata s in-loop-id] +#define SET-MENU-KEY(s d) [g_object_set_qdata s menu-key-id d] +#define GET-MENU-KEY(s) [g_object_get_qdata s menu-key-id] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index abc6a89215..161a63ee41 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -694,13 +694,13 @@ mouse-button-press-event: func [ ;; DEBUG: print ["with button " event/button lf] if event/button = GDK_BUTTON_SECONDARY [ - hMenu: context-menu? widget + hMenu: GET-MENU-KEY(widget) ;; DEBUG: print ["widget " widget " with menu " hMenu lf] unless null? hMenu [ menu-x: as-integer event/x menu-y: as-integer event/y ;; DEBUG: print ["menu pointer : " menu-x "x" menu-y lf] - gtk_menu_popup_at_pointer hMenu as handle! event + gtk_menu_popup_at_pointer hMenu as handle! event return EVT_NO_DISPATCH ] @@ -767,6 +767,6 @@ menu-item-activate: func [ /local key [integer!] ][ - key: menu-item-key? item + key: as integer! GET-MENU-KEY(item) make-event widget key EVT_MENU ] diff --git a/modules/view/backends/gtk3/menu.reds b/modules/view/backends/gtk3/menu.reds index 0094d2d275..0914cb10ca 100644 --- a/modules/view/backends/gtk3/menu.reds +++ b/modules/view/backends/gtk3/menu.reds @@ -13,20 +13,6 @@ Red/System [ menu-x: 0 menu-y: 0 -menu-item-key: func [ - item [handle!] - key [integer!] -][ - g_object_set_qdata item menu-id as int-ptr! key -] - -menu-item-key?: func [ - item [handle!] - return: [integer!] -][ - as integer! g_object_get_qdata item menu-id -] - build-menu: func [ menu [red-block!] hMenu [handle!] @@ -40,19 +26,15 @@ build-menu: func [ next [red-value!] str [red-string!] w [red-word!] + v [handle!] len [integer!] title [c-string!] - key [c-string!] - action [integer!] ][ if TYPE_OF(menu) <> TYPE_BLOCK [return null] - ;; DEBUG: print ["Menu: " hMenu " with target: " target lf] value: block/rs-head menu tail: block/rs-tail menu - key: "" - ;action: red-menu-action: while [value < tail][ switch TYPE_OF(value) [ TYPE_STRING [ @@ -64,11 +46,11 @@ build-menu: func [ item: gtk_menu_item_new_with_label title gtk_widget_show item + gobj_signal_connect(item "activate" :menu-item-activate target) if next < tail [ switch TYPE_OF(next) [ TYPE_BLOCK [ - ;; DEBUG: print ["add sub-menu" lf] sub-menu: gtk_menu_new gtk_widget_show sub-menu build-menu as red-block! next sub-menu target @@ -77,9 +59,8 @@ build-menu: func [ ] TYPE_WORD [ w: as red-word! next - menu-item-key item w/symbol - ;; DEBUG: print ["item " item " connected to " target " with key " w/symbol lf] - gobj_signal_connect(item "activate" :menu-item-activate target) + v: as handle! w/symbol + SET-MENU-KEY(item v) value: value + 1 ] default [0] @@ -100,21 +81,6 @@ build-menu: func [ hMenu ] -context-menu: func [ - widget [handle!] - hMenu [handle!] -][ - ;; DEBUG: print ["context menu " hMenu " added to " widget lf] - g_object_set_qdata widget menu-id hMenu -] - -context-menu?: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget menu-id -] - build-context-menu: func [ widget [handle!] menu [red-block!] @@ -126,7 +92,7 @@ build-context-menu: func [ hMenu: gtk_menu_new ;; DEBUG: print ["hMenu " hMenu lf] build-menu menu hMenu widget - context-menu widget hMenu + SET-MENU-KEY(widget hMenu) ] ] From 71a3edaa50e400ecf026e3244a1a6109059f289c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 16:20:37 +0100 Subject: [PATCH 0398/3432] FEAT: adds integer! fallback to float! in lexer. --- runtime/lexer.reds | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a65f1a2820..a34479ed7a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1109,6 +1109,7 @@ lexer: context [ p [byte-ptr!] len [integer!] i [integer!] + o? [logic!] ][ p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present @@ -1122,18 +1123,27 @@ lexer: context [ return 0 ] i: 0 + o?: no either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path loop len [ i: 10 * i + as-integer (p/1 - #"0") + o?: o? or system/cpu/overflow? p: p + 1 ] ][ ;-- process with quote(s) loop len [ - if e/1 <> #"'" [i: 10 * i + as-integer (p/1 - #"0")] + if e/1 <> #"'" [ + i: 10 * i + as-integer (p/1 - #"0") + o?: o? or system/cpu/overflow? + ] p: p + 1 ] ] assert p = e + if o? [ + scan-float lex s e flags ;-- overflow, fall back on float + return 0 + ] ] if s/value = #"-" [i: 0 - i] if flags and C_FLAG_NOSTORE = 0 [ From 8684c4c6c5f94f79fa1262f7d9a59049f77fa2ea Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 16:59:48 +0100 Subject: [PATCH 0399/3432] FEAT: adds support for loading -2147483648 as integer. --- runtime/lexer.reds | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a34479ed7a..db7202a41d 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -379,6 +379,9 @@ lexer: context [ stash-size: 1000 ;-- pre-allocated cells number root-state: as state! 0 ;-- global entry point to state struct list depth: 0 ;-- recursive calls depth + + min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer + throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] /local @@ -1141,8 +1144,14 @@ lexer: context [ ] assert p = e if o? [ - scan-float lex s e flags ;-- overflow, fall back on float - return 0 + len: as-integer e - s ;-- include sign in len now + either all [len = 11 zero? compare-memory s min-integer len][ + i: 80000000h + s: s + 1 ;-- ensure that the 0 subtraction does not occur + ][ + scan-float lex s e flags ;-- overflow, fall back on float + return 0 + ] ] ] if s/value = #"-" [i: 0 - i] From 80f2f230f27c4b199f3915dadc028a01a7a6455a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 17:14:07 +0100 Subject: [PATCH 0400/3432] FIX: non-passing "load-bin-3" test. --- runtime/lexer.reds | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index db7202a41d..c3aeaa0ad4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -543,9 +543,12 @@ lexer: context [ default [return s] ] ] - if all [cnt <> 0 cnt <> 8][return s] - p/value: as byte! c - p: p + 1 + either zero? cnt [ + p/value: as byte! c + p: p + 1 + ][ + if cnt <> 8 [return s] + ] ] ser/tail: as cell! p null @@ -1144,7 +1147,7 @@ lexer: context [ ] assert p = e if o? [ - len: as-integer e - s ;-- include sign in len now + len: as-integer e - s ;-- account for sign in len now either all [len = 11 zero? compare-memory s min-integer len][ i: 80000000h s: s + 1 ;-- ensure that the 0 subtraction does not occur From 809db6c1495f14753284297fb83a36f270ca6e53 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 17:25:21 +0100 Subject: [PATCH 0401/3432] FIX: non-passing test "load-code-1". --- runtime/lexer.reds | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c3aeaa0ad4..02e181997b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -455,7 +455,8 @@ lexer: context [ s [series!] ][ either zero? items [ - block/make-at as red-block! slot 1 + blk: block/make-at as red-block! slot 1 + blk/header: blk/header and type-mask or type ][ blk: block/make-at as red-block! slot items blk/header: blk/header and type-mask or type @@ -505,7 +506,7 @@ lexer: context [ lex/tail: lex/head lex/head: as cell! p - p/x hint: p/z - + store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here p: as red-point! lex/head - 1 ;-- get parent series From 6ec4f6ce26ede753dbe84ed384c97e81ee544345 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 6 Nov 2019 18:36:00 +0100 Subject: [PATCH 0402/3432] FIX: non-passing test "load-date-1". --- runtime/datatypes/date.reds | 4 ---- runtime/lexer.reds | 7 +++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index f79ec46b00..c95c62764e 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -536,10 +536,6 @@ date: context [ ][ year: date/year tz-h: date/tz-h - if year < 100 [ ;-- expand short yy forms - d: either year < 50 [2000][1900] - year: year + d - ] if any [ date/day > 31 date/month > 12 year > 9999 tz-h > 15 tz-h < -15 ;-- out of range TZ diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 02e181997b..4055450df6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1314,6 +1314,13 @@ lexer: context [ throw-error lex b e TYPE_DATE ;-- inconsistent separator ] ] + if df/year < 100 [ ;-- expand short yy forms + me: (as byte-ptr! df/sep2) + 3 + unless all [me < e (as-integer me/1 - #"0") <= 9][ ;-- check if year field has 2 digits + c: either df/year < 50 [2000][1900] + df/year: df/year + c + ] + ] if df/month-end <> 0 [ ;-- if month is named p: p + 1 ;-- name start me: as byte-ptr! df/month-end ;-- name end From f480aaf900e3402f17cc27698267ef6d057a54a9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 7 Nov 2019 00:44:28 +0100 Subject: [PATCH 0403/3432] FEAT: attempt at supporting the hex literal format in the lexer's FSM. --- docs/lexer/lexer-states.txt | 54 +++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index d748219c92..c4ed3a8e03 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -237,14 +237,20 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->"#"->S_SHARP \->"@"->S_EMAIL \->"e"|"E"->S_DECIMAL - \->else->T_ERROR + \->"E"->S_DECX->digit->S_DECX + \ \->alphaU->S_HEX + \ \->"h"->T_HEX + \ \->delimit11->T_FLOAT + \->alphaU->S_HEX + \->"h"->T_HEX + \->else->T_ERROR S_START->"."->S_DOTWORD->digit->S_DOTDEC->digit|"e"|"E"|"+"|"-"|"'"->S_DOTDEC - \ \->"%"->T_PERCENT - \ \->"x"|"X"->S_PAIR_1ST - \ \->delimit11->T_FLOAT - \ \->else->T_ERROR + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR \ \->not(delimit5)->S_WORD \->":"->S_WORDSET @@ -284,21 +290,29 @@ S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY \->delimit3->T_MONEY \->else->T_ERROR - -S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD - \->delimit7->T_WORD - \ - \->":"->S_WORDSET->not(delimit7)->S_URL->not(delimit7)->S_URL - \ \->delimit7->T_WORD \->delimit7->T_URL - \ - \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL - \ \->delimit7->T_EMAIL - \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR - \ - \->"/"->T_PATH - \->"$"->S_MONEY - \->","|"#"|"%"->T_ERROR - + +S_START->not(delimit6)->S_WORD->not(delimit5|alphaU|digit|"E")->S_WORD + \->alphaU|digit|"E"->S_HEX->alphaU|digit|"E"->S_HEX + \ \->delimit7->T_WORD + \ \->":"->S_WORDSET + \ \->"@"->S_EMAIL + \ \->"/"->T_PATH + \ \->"$"->S_MONEY + \ \->","|"#"|"%"->T_ERROR + \ \->"h"->T_HEX + \ + \->delimit7->T_WORD + \ + \->":"->S_WORDSET->not(delimit7)->S_URL->not(delimit7)->S_URL + \ \->delimit7->T_WORD \->delimit7->T_URL + \ + \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL + \ \->delimit7->T_EMAIL + \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR + \ + \->"/"->T_PATH + \->"$"->S_MONEY + \->","|"#"|"%"->T_ERROR S_PATH->ws|";"|"["|"]"|"{"|"/"|"%"->T_ERROR From c22473089f3b6081f20cc58a42e0b86a1c649467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boleslav=20B=C5=99ezovsk=C3=BD?= Date: Thu, 7 Nov 2019 07:50:49 +0100 Subject: [PATCH 0404/3432] FIX: Don't eat STYLE keyword in style definition --- modules/view/VID.red | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/VID.red b/modules/view/VID.red index fa0e150511..7c85bd1aba 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -322,6 +322,7 @@ system/view/VID: context [ if later?: spec/2 = 'later [spec: next spec] repend reactors [face fetch-argument block! spec later?] ) + | 'style to end (opt?: no) ] to end ] unless match? [ From 85c9664100abc87083360960d2e3a5bb36db7ca3 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 7 Nov 2019 10:52:31 +0800 Subject: [PATCH 0405/3432] FIX: `drag` not response smoothly --- modules/view/backends/gtk3/events.reds | 4 +- modules/view/backends/gtk3/gtk.reds | 5 ++ modules/view/backends/gtk3/handlers.reds | 85 ++++++++++++------------ 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 2a9babe5b1..66d32084c1 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -34,13 +34,11 @@ flags-blk/node: alloc-cells 4 ; used to save old position of pointer in widget-motion-notify-event handler evt-motion: context [ - state: no + pressed: no x_root: 0.0 y_root: 0.0 x_new: 0 y_new: 0 - cpt: 0 - sensitiv: 3 ] char-keys: [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index b6fe558bb7..6783f8ba08 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1002,6 +1002,11 @@ GPtrArray!: alias struct! [ event [handle!] direction [int-ptr!] ] + gdk_window_get_position: "gdk_window_get_position" [ + window [handle!] + x [int-ptr!] + y [int-ptr!] + ] gdk_window_get_display: "gdk_window_get_display" [ window [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 161a63ee41..11dcb88462 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -587,6 +587,7 @@ widget-enter-notify-event: func [ flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + if evt-motion/pressed [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags EVT_OVER ] @@ -601,6 +602,7 @@ widget-leave-notify-event: func [ flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + if evt-motion/pressed [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags or EVT_FLAG_AWAY EVT_OVER ] @@ -624,41 +626,43 @@ mouse-button-release-event: func [ ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] sym: get-widget-symbol widget - if sym = field [ - if event/button = GDK_BUTTON_PRIMARY [ - x: -1 y: -1 - if gtk_editable_get_selection_bounds widget :x :y [ - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y + + if event/button = GDK_BUTTON_PRIMARY [ + case [ + sym = field [ + x: -1 y: -1 + if gtk_editable_get_selection_bounds widget :x :y [ + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT ] - make-event widget 0 EVT_SELECT ] - ] - ] - if sym = area [ - if event/button = GDK_BUTTON_PRIMARY [ - buffer: gtk_text_view_get_buffer widget - if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ - x: -1 y: -1 - x: gtk_text_iter_get_offset as handle! start - y: gtk_text_iter_get_offset as handle! end - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y + sym = area [ + buffer: gtk_text_view_get_buffer widget + if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ + x: -1 y: -1 + x: gtk_text_iter_get_offset as handle! start + y: gtk_text_iter_get_offset as handle! end + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT ] - make-event widget 0 EVT_SELECT ] + true [0] ] + evt-motion/pressed: no ] - evt-motion/state: yes - evt-motion/cpt: 0 + evt-motion/x_root: event/x_root evt-motion/y_root: event/y_root evt-motion/x_new: as-integer event/x @@ -692,18 +696,18 @@ mouse-button-press-event: func [ gtk_widget_grab_focus widget ] - ;; DEBUG: print ["with button " event/button lf] - if event/button = GDK_BUTTON_SECONDARY [ + if event/button = GDK_BUTTON_PRIMARY [ + evt-motion/pressed: yes + ] + + if event/button = GDK_BUTTON_SECONDARY [ hMenu: GET-MENU-KEY(widget) - ;; DEBUG: print ["widget " widget " with menu " hMenu lf] unless null? hMenu [ menu-x: as-integer event/x menu-y: as-integer event/y - ;; DEBUG: print ["menu pointer : " menu-x "x" menu-y lf] gtk_menu_popup_at_pointer hMenu as handle! event return EVT_NO_DISPATCH ] - ] evt-motion/x_root: event/x_root @@ -726,23 +730,20 @@ mouse-motion-notify-event: func [ widget [handle!] return: [integer!] /local - offset [red-pair!] + wflags [integer!] x [float!] y [float!] - wflags [integer!] flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS + if wflags and FACET_FLAGS_ALL_OVER = 0 [return EVT_DISPATCH] evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y evt-motion/x_root: event/x_root evt-motion/y_root: event/y_root - wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS - if wflags and FACET_FLAGS_ALL_OVER <> 0 [ - flags: check-flags event/type event/state - return make-event widget flags EVT_OVER - ] - EVT_DISPATCH + flags: check-flags event/type event/state + make-event widget flags EVT_OVER ] widget-scroll-event: func [ From 3773d8283678b43fab83faec31bb72043c4ba1f6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 6 Nov 2019 15:09:02 +0800 Subject: [PATCH 0406/3432] FIX: one level menu not responsed --- modules/view/backends/gtk3/gtk.reds | 6 ++-- modules/view/backends/gtk3/handlers.reds | 6 ++-- modules/view/backends/gtk3/menu.reds | 44 +++--------------------- 3 files changed, 11 insertions(+), 45 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 68adf64b97..b6fe558bb7 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2965,9 +2965,7 @@ red-face-id4: g_quark_from_string "red-face-id4" gtk-style-id: g_quark_from_string "gtk-style-id" container-id: g_quark_from_string "container-id" red-timer-id: g_quark_from_string "red-timer-id" -css-id: g_quark_from_string "css-id" -size-id: g_quark_from_string "size-id" -menu-id: g_quark_from_string "menu-id" +menu-key-id: g_quark_from_string "menu-key-id" red-event-id: g_quark_from_string "red-event-id" cursor-id: g_quark_from_string "cursor-id" resizing-id: g_quark_from_string "resizing-id" @@ -2987,3 +2985,5 @@ in-loop-id: g_quark_from_string "in-loop-id" #define GET-CAPTION(s) [g_object_get_qdata s caption-id] #define SET-IN-LOOP(s d) [g_object_set_qdata s in-loop-id d] #define GET-IN-LOOP(s) [g_object_get_qdata s in-loop-id] +#define SET-MENU-KEY(s d) [g_object_set_qdata s menu-key-id d] +#define GET-MENU-KEY(s) [g_object_get_qdata s menu-key-id] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index abc6a89215..161a63ee41 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -694,13 +694,13 @@ mouse-button-press-event: func [ ;; DEBUG: print ["with button " event/button lf] if event/button = GDK_BUTTON_SECONDARY [ - hMenu: context-menu? widget + hMenu: GET-MENU-KEY(widget) ;; DEBUG: print ["widget " widget " with menu " hMenu lf] unless null? hMenu [ menu-x: as-integer event/x menu-y: as-integer event/y ;; DEBUG: print ["menu pointer : " menu-x "x" menu-y lf] - gtk_menu_popup_at_pointer hMenu as handle! event + gtk_menu_popup_at_pointer hMenu as handle! event return EVT_NO_DISPATCH ] @@ -767,6 +767,6 @@ menu-item-activate: func [ /local key [integer!] ][ - key: menu-item-key? item + key: as integer! GET-MENU-KEY(item) make-event widget key EVT_MENU ] diff --git a/modules/view/backends/gtk3/menu.reds b/modules/view/backends/gtk3/menu.reds index 0094d2d275..0914cb10ca 100644 --- a/modules/view/backends/gtk3/menu.reds +++ b/modules/view/backends/gtk3/menu.reds @@ -13,20 +13,6 @@ Red/System [ menu-x: 0 menu-y: 0 -menu-item-key: func [ - item [handle!] - key [integer!] -][ - g_object_set_qdata item menu-id as int-ptr! key -] - -menu-item-key?: func [ - item [handle!] - return: [integer!] -][ - as integer! g_object_get_qdata item menu-id -] - build-menu: func [ menu [red-block!] hMenu [handle!] @@ -40,19 +26,15 @@ build-menu: func [ next [red-value!] str [red-string!] w [red-word!] + v [handle!] len [integer!] title [c-string!] - key [c-string!] - action [integer!] ][ if TYPE_OF(menu) <> TYPE_BLOCK [return null] - ;; DEBUG: print ["Menu: " hMenu " with target: " target lf] value: block/rs-head menu tail: block/rs-tail menu - key: "" - ;action: red-menu-action: while [value < tail][ switch TYPE_OF(value) [ TYPE_STRING [ @@ -64,11 +46,11 @@ build-menu: func [ item: gtk_menu_item_new_with_label title gtk_widget_show item + gobj_signal_connect(item "activate" :menu-item-activate target) if next < tail [ switch TYPE_OF(next) [ TYPE_BLOCK [ - ;; DEBUG: print ["add sub-menu" lf] sub-menu: gtk_menu_new gtk_widget_show sub-menu build-menu as red-block! next sub-menu target @@ -77,9 +59,8 @@ build-menu: func [ ] TYPE_WORD [ w: as red-word! next - menu-item-key item w/symbol - ;; DEBUG: print ["item " item " connected to " target " with key " w/symbol lf] - gobj_signal_connect(item "activate" :menu-item-activate target) + v: as handle! w/symbol + SET-MENU-KEY(item v) value: value + 1 ] default [0] @@ -100,21 +81,6 @@ build-menu: func [ hMenu ] -context-menu: func [ - widget [handle!] - hMenu [handle!] -][ - ;; DEBUG: print ["context menu " hMenu " added to " widget lf] - g_object_set_qdata widget menu-id hMenu -] - -context-menu?: func [ - widget [handle!] - return: [handle!] -][ - g_object_get_qdata widget menu-id -] - build-context-menu: func [ widget [handle!] menu [red-block!] @@ -126,7 +92,7 @@ build-context-menu: func [ hMenu: gtk_menu_new ;; DEBUG: print ["hMenu " hMenu lf] build-menu menu hMenu widget - context-menu widget hMenu + SET-MENU-KEY(widget hMenu) ] ] From 85a5a4626285e617f40bfe15673e7112e2dcd433 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 7 Nov 2019 10:52:31 +0800 Subject: [PATCH 0407/3432] FIX: `drag` not response smoothly --- modules/view/backends/gtk3/events.reds | 4 +- modules/view/backends/gtk3/gtk.reds | 5 ++ modules/view/backends/gtk3/handlers.reds | 85 ++++++++++++------------ 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 2a9babe5b1..66d32084c1 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -34,13 +34,11 @@ flags-blk/node: alloc-cells 4 ; used to save old position of pointer in widget-motion-notify-event handler evt-motion: context [ - state: no + pressed: no x_root: 0.0 y_root: 0.0 x_new: 0 y_new: 0 - cpt: 0 - sensitiv: 3 ] char-keys: [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index b6fe558bb7..6783f8ba08 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1002,6 +1002,11 @@ GPtrArray!: alias struct! [ event [handle!] direction [int-ptr!] ] + gdk_window_get_position: "gdk_window_get_position" [ + window [handle!] + x [int-ptr!] + y [int-ptr!] + ] gdk_window_get_display: "gdk_window_get_display" [ window [handle!] return: [handle!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 161a63ee41..11dcb88462 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -587,6 +587,7 @@ widget-enter-notify-event: func [ flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + if evt-motion/pressed [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags EVT_OVER ] @@ -601,6 +602,7 @@ widget-leave-notify-event: func [ flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + if evt-motion/pressed [return EVT_NO_DISPATCH] flags: check-flags event/type event/state make-event widget flags or EVT_FLAG_AWAY EVT_OVER ] @@ -624,41 +626,43 @@ mouse-button-release-event: func [ ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] sym: get-widget-symbol widget - if sym = field [ - if event/button = GDK_BUTTON_PRIMARY [ - x: -1 y: -1 - if gtk_editable_get_selection_bounds widget :x :y [ - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y + + if event/button = GDK_BUTTON_PRIMARY [ + case [ + sym = field [ + x: -1 y: -1 + if gtk_editable_get_selection_bounds widget :x :y [ + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT ] - make-event widget 0 EVT_SELECT ] - ] - ] - if sym = area [ - if event/button = GDK_BUTTON_PRIMARY [ - buffer: gtk_text_view_get_buffer widget - if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ - x: -1 y: -1 - x: gtk_text_iter_get_offset as handle! start - y: gtk_text_iter_get_offset as handle! end - ;; DEBUG: print ["from " x " to " y lf ] - sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED - either x = y [sel/header: TYPE_NONE][ - sel/header: TYPE_PAIR - sel/x: x + 1 - sel/y: y + sym = area [ + buffer: gtk_text_view_get_buffer widget + if gtk_text_buffer_get_selection_bounds buffer as handle! start as handle! end [ + x: -1 y: -1 + x: gtk_text_iter_get_offset as handle! start + y: gtk_text_iter_get_offset as handle! end + ;; DEBUG: print ["from " x " to " y lf ] + sel: as red-pair! (get-face-values widget) + FACE_OBJ_SELECTED + either x = y [sel/header: TYPE_NONE][ + sel/header: TYPE_PAIR + sel/x: x + 1 + sel/y: y + ] + make-event widget 0 EVT_SELECT ] - make-event widget 0 EVT_SELECT ] + true [0] ] + evt-motion/pressed: no ] - evt-motion/state: yes - evt-motion/cpt: 0 + evt-motion/x_root: event/x_root evt-motion/y_root: event/y_root evt-motion/x_new: as-integer event/x @@ -692,18 +696,18 @@ mouse-button-press-event: func [ gtk_widget_grab_focus widget ] - ;; DEBUG: print ["with button " event/button lf] - if event/button = GDK_BUTTON_SECONDARY [ + if event/button = GDK_BUTTON_PRIMARY [ + evt-motion/pressed: yes + ] + + if event/button = GDK_BUTTON_SECONDARY [ hMenu: GET-MENU-KEY(widget) - ;; DEBUG: print ["widget " widget " with menu " hMenu lf] unless null? hMenu [ menu-x: as-integer event/x menu-y: as-integer event/y - ;; DEBUG: print ["menu pointer : " menu-x "x" menu-y lf] gtk_menu_popup_at_pointer hMenu as handle! event return EVT_NO_DISPATCH ] - ] evt-motion/x_root: event/x_root @@ -726,23 +730,20 @@ mouse-motion-notify-event: func [ widget [handle!] return: [integer!] /local - offset [red-pair!] + wflags [integer!] x [float!] y [float!] - wflags [integer!] flags [integer!] ][ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS + if wflags and FACET_FLAGS_ALL_OVER = 0 [return EVT_DISPATCH] evt-motion/x_new: as-integer event/x evt-motion/y_new: as-integer event/y evt-motion/x_root: event/x_root evt-motion/y_root: event/y_root - wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS - if wflags and FACET_FLAGS_ALL_OVER <> 0 [ - flags: check-flags event/type event/state - return make-event widget flags EVT_OVER - ] - EVT_DISPATCH + flags: check-flags event/type event/state + make-event widget flags EVT_OVER ] widget-scroll-event: func [ From b1ed64293b047a072e4e6f69e9d463dcdca63fa5 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 7 Nov 2019 16:57:19 +0800 Subject: [PATCH 0408/3432] FIX: focus event need propagate to avoid gtk warning --- modules/view/backends/gtk3/handlers.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 11dcb88462..def1b2a0e9 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -501,7 +501,7 @@ focus-in-event: func [ int [red-integer!] sym [integer!] ][ - if evbox <> gtk_get_event_widget event [return EVT_NO_DISPATCH] + if evbox <> gtk_get_event_widget event [return EVT_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -509,6 +509,7 @@ focus-in-event: func [ sym: symbol/resolve type/symbol change-selection widget int sym make-event widget 0 EVT_FOCUS + EVT_DISPATCH ] focus-out-event: func [ @@ -523,12 +524,13 @@ focus-out-event: func [ type [red-word!] sym [integer!] ][ - if evbox <> gtk_get_event_widget event [return EVT_NO_DISPATCH] + if evbox <> gtk_get_event_widget event [return EVT_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol make-event widget 0 EVT_UNFOCUS + EVT_DISPATCH ] area-changed: func [ From 6d8b1874ae1704511b875a6495054f322dc724dc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 7 Nov 2019 18:42:47 +0100 Subject: [PATCH 0409/3432] FEAT: improves the hex literal support in the lexer's FSM. --- docs/lexer/lexer-states.txt | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index c4ed3a8e03..fd6db712d3 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -21,6 +21,7 @@ S_ISSUE S_NUMBER S_DOTNUM S_DECIMAL +S_DECX S_DEC_SPECIAL S_TUPLE S_DATE @@ -31,6 +32,7 @@ S_PAIR S_MONEY_1ST S_MONEY S_MONEY_DEC +S_HEX S_LESSER S_TAG S_TAG_STR @@ -80,6 +82,7 @@ T_TAG T_URL T_EMAIL T_PATH +T_HEX C_BLANK : space, tab, cr @@ -99,7 +102,7 @@ C_COLON : : C_X : x, X C_T : T C_EXP : e, E -C_ALPHAX : a-f, A-F +C_ALPHAX : a-d,f, A-D,F C_SLASH : / C_BSLASH : \ C_LESSER : < @@ -119,11 +122,6 @@ C_ILLEGAL : 0xC0-0xC1, 0xF5-0xFF C_EOF : NUL -;":"->S_CLASS_GET => set as high-bits flag -;"'"->S_CLASS_LIT => set as high-bits flag - - - ws: space | tab | cr | lf dbl-quote: " @@ -142,7 +140,7 @@ delimit13: [ | ] | ( | ) | { | } | " | % | ws | ; | < | # | @ | ^ delimit14: # | ' | < | % | ^ hexa: C_ZERO | C_DIGIT | C_ALPHAX - +alphaU: A, B, C, D, F S_START->ws->S_START @@ -291,28 +289,30 @@ S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY \->else->T_ERROR -S_START->not(delimit6)->S_WORD->not(delimit5|alphaU|digit|"E")->S_WORD - \->alphaU|digit|"E"->S_HEX->alphaU|digit|"E"->S_HEX - \ \->delimit7->T_WORD - \ \->":"->S_WORDSET - \ \->"@"->S_EMAIL - \ \->"/"->T_PATH - \ \->"$"->S_MONEY - \ \->","|"#"|"%"->T_ERROR - \ \->"h"->T_HEX - \ - \->delimit7->T_WORD - \ - \->":"->S_WORDSET->not(delimit7)->S_URL->not(delimit7)->S_URL - \ \->delimit7->T_WORD \->delimit7->T_URL - \ - \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL - \ \->delimit7->T_EMAIL - \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR - \ - \->"/"->T_PATH - \->"$"->S_MONEY - \->","|"#"|"%"->T_ERROR +S_START->alphaU|"E"->S_HEX->alphaU|digit|"E"->S_HEX + \->delimit7->T_WORD + \->":"->S_WORDSET + \->"@"->S_EMAIL + \->"/"->T_PATH + \->"$"->S_MONEY + \->"h"->T_HEX + \->","|"#"|"%"->T_ERROR + \->not(delimit5)->S_WORD + + +S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD + \->delimit7->T_WORD + \ + \->":"->S_WORDSET->not(delimit7)->S_URL->not(delimit7)->S_URL + \ \->delimit7->T_WORD \->delimit7->T_URL + \ + \->"@"->S_EMAIL->not(delimit7|"@"|"/"|">"|","|"^"|"$"|":"|"'"|"#")->S_EMAIL + \ \->delimit7->T_EMAIL + \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR + \ + \->"/"->T_PATH + \->"$"->S_MONEY + \->","|"#"|"%"->T_ERROR S_PATH->ws|";"|"["|"]"|"{"|"/"|"%"->T_ERROR From fa868190e5da342d87c74e36ae4b10050bbd8396 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 7 Nov 2019 18:48:13 +0100 Subject: [PATCH 0410/3432] FEAT: adds hex states to the Excel table and generator script. --- docs/lexer/lexer-FSM.xlsx | Bin 24507 -> 24806 bytes utils/generate-lexer-table.red | 121 +++++++++++++++++---------------- 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index c5fd5014cab9aa428ddb018c003782bfa0ca57fb..14c5fb69d6f452d943af841450feb53f41a94dda 100644 GIT binary patch delta 9230 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 BqVoU% delta 8873 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 YMnyq!?)PI*NSmVSk(cOl%uhc3f8VJmW&i*H diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index b18e176c2d..56130d8074 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -34,65 +34,68 @@ context [ S_NUMBER ;-- 19 S_DOTNUM ;-- 20 S_DECIMAL ;-- 21 - S_DEC_SPECIAL ;-- 22 - S_TUPLE ;-- 23 - S_DATE ;-- 24 - S_TIME_1ST ;-- 25 - S_TIME ;-- 26 - S_PAIR_1ST ;-- 27 - S_PAIR ;-- 28 - S_MONEY_1ST ;-- 29 - S_MONEY ;-- 30 - S_MONEY_DEC ;-- 31 - S_LESSER ;-- 32 - S_TAG ;-- 33 - S_TAG_STR ;-- 34 - S_SKIP_STR2 ;-- 35 - S_TAG_STR2 ;-- 36 - S_SKIP_STR3 ;-- 37 - S_SIGN ;-- 38 - S_DOTWORD ;-- 39 - S_DOTDEC ;-- 40 - S_WORD ;-- 41 - S_WORDSET ;-- 42 - S_URL ;-- 43 - S_EMAIL ;-- 44 - S_PATH ;-- 45 - S_PATH_NUM ;-- 46 - S_PATH_WORD ;-- 47 - S_PATH_SHARP ;-- 48 - S_PATH_SIGN ;-- 49 - --EXIT_STATES-- ;-- 50 - T_EOF ;-- 51 - T_ERROR ;-- 52 - T_BLK_OP ;-- 53 - T_BLK_CL ;-- 54 - T_PAR_OP ;-- 55 - T_PAR_CL ;-- 56 - T_STRING ;-- 57 - T_MSTR_OP ;-- 58 - T_MSTR_CL ;-- 59 - T_WORD ;-- 60 - T_FILE ;-- 61 - T_REFINE ;-- 62 - T_BINARY ;-- 63 - T_CHAR ;-- 64 - T_MAP_OP ;-- 65 - T_CONS_MK ;-- 66 - T_ISSUE ;-- 67 - T_PERCENT ;-- 68 - T_INTEGER ;-- 69 - T_FLOAT ;-- 70 - T_FLOAT_SP ;-- 71 - T_TUPLE ;-- 72 - T_DATE ;-- 73 - T_PAIR ;-- 74 - T_TIME ;-- 75 - T_MONEY ;-- 76 - T_TAG ;-- 77 - T_URL ;-- 78 - T_EMAIL ;-- 79 - T_PATH ;-- 80 + S_DECX ;-- 22 + S_DEC_SPECIAL ;-- 23 + S_TUPLE ;-- 24 + S_DATE ;-- 25 + S_TIME_1ST ;-- 26 + S_TIME ;-- 27 + S_PAIR_1ST ;-- 28 + S_PAIR ;-- 29 + S_MONEY_1ST ;-- 30 + S_MONEY ;-- 31 + S_MONEY_DEC ;-- 32 + S_HEX ;-- 33 + S_LESSER ;-- 34 + S_TAG ;-- 35 + S_TAG_STR ;-- 36 + S_SKIP_STR2 ;-- 37 + S_TAG_STR2 ;-- 38 + S_SKIP_STR3 ;-- 39 + S_SIGN ;-- 40 + S_DOTWORD ;-- 41 + S_DOTDEC ;-- 42 + S_WORD ;-- 43 + S_WORDSET ;-- 44 + S_URL ;-- 45 + S_EMAIL ;-- 46 + S_PATH ;-- 47 + S_PATH_NUM ;-- 48 + S_PATH_WORD ;-- 49 + S_PATH_SHARP ;-- 50 + S_PATH_SIGN ;-- 51 + --EXIT_STATES-- ;-- 52 + T_EOF ;-- 53 + T_ERROR ;-- 54 + T_BLK_OP ;-- 55 + T_BLK_CL ;-- 56 + T_PAR_OP ;-- 57 + T_PAR_CL ;-- 58 + T_STRING ;-- 59 + T_MSTR_OP ;-- 60 + T_MSTR_CL ;-- 61 + T_WORD ;-- 62 + T_FILE ;-- 63 + T_REFINE ;-- 64 + T_BINARY ;-- 65 + T_CHAR ;-- 66 + T_MAP_OP ;-- 67 + T_CONS_MK ;-- 68 + T_ISSUE ;-- 69 + T_PERCENT ;-- 70 + T_INTEGER ;-- 71 + T_FLOAT ;-- 72 + T_FLOAT_SP ;-- 73 + T_TUPLE ;-- 74 + T_DATE ;-- 75 + T_PAIR ;-- 76 + T_TIME ;-- 77 + T_MONEY ;-- 78 + T_TAG ;-- 79 + T_URL ;-- 80 + T_EMAIL ;-- 81 + T_PATH ;-- 82 + T_HEX ;-- 83 ] date-states: [ From dcc97d711ae174c38ac4838cb6f2cb9880bb8930 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 8 Nov 2019 15:07:41 +0800 Subject: [PATCH 0411/3432] FIX: save gtk version to system/view/platform/version --- modules/view/backends/gtk3/gui.reds | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8cccba43ca..f0b04b108c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -482,10 +482,6 @@ on-gc-mark: does [ collector/keep flags-blk/node ] -show-gtk-version: func [][ - print [ "GTK VERSION: " gtk_get_major_version "." gtk_get_minor_version "." gtk_get_micro_version lf] -] - parse-font-name: func [ str [c-string!] psize [int-ptr!] @@ -633,8 +629,23 @@ find-last-window: func [ ] ] +get-os-version: func [ + /local + major [integer!] + minor [integer!] + micro [integer!] + ver [red-tuple!] +][ + major: gtk_get_major_version + minor: gtk_get_minor_version + micro: gtk_get_micro_version + ver: as red-tuple! #get system/view/platform/version + ver/header: TYPE_TUPLE or (3 << 19) + ver/array1: micro << 16 or (minor << 8) or major +] + init: func [][ - show-gtk-version + get-os-version gtk_disable_setlocale gtk_init null null From 1549acb28bc6d3afbc5056a3d53b24ae424e8b6f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 8 Nov 2019 15:45:53 +0800 Subject: [PATCH 0412/3432] FIX: support `get c-string! from symbol` --- modules/view/backends/gtk3/gui.reds | 35 +---------------------------- runtime/datatypes/symbol.reds | 12 ++++++++++ 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index f0b04b108c..e703f1124a 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -662,40 +662,7 @@ get-symbol-name: function [ sym [integer!] return: [c-string!] ][ - case [ - sym = check ["check"] - sym = radio ["radio"] - sym = button ["button"] - sym = base ["base"] - sym = window ["window"] - sym = slider ["slider"] - sym = text ["text"] - sym = field ["field"] - sym = progress ["progress"] - sym = area ["area"] - sym = group-box ["group-box"] - sym = panel ["panel"] - sym = tab-panel ["tab-panel"] - sym = text-list ["text-list"] - sym = drop-list ["drop-list"] - sym = drop-down ["drop-down"] - sym = rich-text ["rich-text"] - sym = done ["done"] - sym = stop ["stop"] - sym = _image ["image"] - - sym = facets/pane ["facets/pane"] - - sym = words/_remove/symbol ["words/remove"] - sym = words/_take/symbol ["words/take"] - sym = words/_clear/symbol ["words/clear"] - sym = words/_insert/symbol ["words/insert"] - sym = words/_poke/symbol ["words/poke"] - sym = words/_moved/symbol ["words/moved"] - sym = words/_changed/symbol ["words/changed"] - - true ["undefined"] - ] + symbol/get-c-string sym ] remove-widget-timer: func [ diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index e110fcf3d7..0889833ce4 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -137,6 +137,18 @@ symbol: context [ as red-symbol! s/offset + id - 1 ] + get-c-string: func [ + id [integer!] + return: [c-string!] + /local + sym [red-symbol!] + s [series!] + ][ + sym: get id + s: as series! sym/node/value + as c-string! s/offset + ] + resolve: func [ id [integer!] return: [integer!] From 0460fc1fe55cc5cee8a8cc4fee3325322c0462f4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 8 Nov 2019 16:30:01 +0800 Subject: [PATCH 0413/3432] FIX: cursor didn't work --- modules/view/backends/gtk3/events.reds | 4 ++- modules/view/backends/gtk3/gui.reds | 36 ------------------------ modules/view/backends/gtk3/handlers.reds | 15 ++++++++++ 3 files changed, 18 insertions(+), 37 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 66d32084c1..6f6360715c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -971,7 +971,9 @@ connect-widget-events: function [ connect-common-events evbox widget ] connect-notify-events evbox widget - connect-focus-events evbox widget sym + connect-focus-events evbox widget sym + + gobj_signal_connect(evbox "realize" :widget-realize widget) case [ sym = check [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e703f1124a..5afc0b51d0 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -952,42 +952,6 @@ change-size: func [ ] ] -init-all-children: func [ - widget [handle!] - /local - values [red-value!] - pane [red-block!] - cursor [handle!] - win [handle!] - face [red-object!] - tail [red-object!] - child [handle!] -][ - values: get-face-values widget - pane: as red-block! values + FACE_OBJ_PANE - - cursor: GET-CURSOR(widget) - unless null? cursor [ - win: gtk_widget_get_window widget - unless null? win [ - gdk_window_set_cursor win cursor - ] - ] - - if all [TYPE_OF(pane) = TYPE_BLOCK 0 <> block/rs-length? pane] [ - face: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - - while [face < tail][ - child: face-handle? face - unless null? child [ - init-all-children child - ] - face: face + 1 - ] - ] -] - change-visible: func [ widget [handle!] show? [logic!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index def1b2a0e9..1d0330e396 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -311,6 +311,21 @@ window-size-allocate: func [ ] ] +widget-realize: func [ + [cdecl] + evbox [handle!] + widget [handle!] + /local + cursor [handle!] + win [handle!] +][ + cursor: GET-CURSOR(widget) + unless null? cursor [ + win: gtk_widget_get_window widget + gdk_window_set_cursor win cursor + ] +] + range-value-changed: func [ [cdecl] range [handle!] From 1fb77e3c4953ff3bbccb20a1f5b4cab3275c4cc7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 8 Nov 2019 10:17:33 +0100 Subject: [PATCH 0414/3432] FEAT: completes support for scanning hex literals in lexer. --- docs/lexer/lexer-FSM.csv | 104 ++++++++++++++-------------- docs/lexer/lexer-FSM.xlsx | Bin 24806 -> 26673 bytes docs/lexer/lexer-states.txt | 11 +-- runtime/lexer-transitions.reds | 122 ++++++++++++++++++--------------- runtime/lexer.reds | 95 ++++++++++++++++--------- 5 files changed, 189 insertions(+), 143 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 4fb781b85d..a854ffbcac 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,51 +1,53 @@ -;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_EXP;C_ALPHAX;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF -S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR -S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR -S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE -S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR -S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR -S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR -S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR -S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_DECIMAL;T_ERROR;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_DECIMAL;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP -S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE -S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;S_PAIR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR -S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD -S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_DOTDEC;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;S_DOTDEC;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL -S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;S_DECIMAL;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD -S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;T_HEX;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;T_HEX;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 14c5fb69d6f452d943af841450feb53f41a94dda..a2d985c88db093a410091bebb0d3634171a7674b 100644 GIT binary patch literal 26673 zcmeFYWl&vRvo(slOOW6$!JXjl?(V^z;O-lDcM0z9?h>3}8z+zef#7;~^2&Ma-1_eC z?^4ACs@B@8XLpa$qno*uWFeujz+k}Oz`(#r!76UGiao)>z_4Jzz%aq!Aaq3?>|M?6 zT@BSd9nD?z89nT5NeZDLX!5}zK-d5OU;h_-U`lP=et;RRTk}LvtVd%=sHCC-j-Z1; zm*OjIx`)U+jP*+-td}0l#x)994V( z7}(F(7pTSK6(<(5dIw%sqe6_t7KV;i&w}O5^dSIYmVC2KrkxdGaNeWK^cyU0X3k&@ zryDU}tPwkfDE3$VrSJNT^!En?w!0he_)(ngZA_x(b?`cud_x3@B=8J#=n<`+#JAbp zTwfz&9|h-yeU5}ijty_4INB7p#vv-j2Y7IZ9A{ z*LSbKDj}h|d5HuSi1b~=6nL=C;tXZ5@zIi1BY10&!L;%zqNYyJO``hPJz|FHF{M0v$QW~8ulsi*L<+ojETG!a>MVX011 zHNODq4b5QM$q&j{2R zk=NcbxvK$R5>Y*^4y$YB%0Ee(&GKJKEj>mSjNp;`KA(X-=3?^UOO4N%E$Q_=zPhR< zk5!#Xt}`#0r=gi`-%qiuUd(4728HY~6*6{=JJwmrQOf*lf1M`wi^&|%AujmA%CR5g zK~cnITmJ|WjRS}5aS%WqC(KI0>CuPaq@Tm|vPCNaM`%mG0VqYv%I zA?Wi~rFDN3tF=8U*cvc?Ye5krFaCpM-IieR3h8jqq3n)xn|a9sSA$He)-g&n)VTz? zQS}Tx9>LbzxkQFmw7A&A!d=a`-^kY31uaim)s5AZO$BiVF3Cp2nbqlgbfuW*?OfIX z2!+N{gZw>(3YLO!%x%dF=19Kq?YOIi{aN@p37Inc z%`P`w7dOJ_7KxN%_r)=3Q@DgyqoyWw^M5A%V1WZ!E-av&kUvQz7D-xTFL0cfS?;x9VXnR z|2Q#R2sJ~2*CsCe0jI|BfLq%16Pc@;%Tx5Ondk+g4<8p_(O1Ep)n?W0HT{I|GJV!` zF<*7a*d10JHs>U_AE&yd^00?!eLG6P*!)HOfnO0yfw(;z+?a{Qud8q;EpLlv6d%DbP3I8$$^9R!m^JA}p=3vhxd zo_qyAe|p~ebUuUwW1XWOPe}{cR8pz4PIJfIEx;E{vfMJC(^zIC6eQ~8-|9c8;PNC^ zdQDLXpo9+la$a0KZ&XX`L}Zt}$as}$iidyf=DCbK!6)C!`m_{aQc4?}669FLNum%O zH}h)K*DrAWZQtU18Ja6zf@Z{BpVG&gs3Vfy`pCsLXO|NfWT$)EX=fKn2{QJGb+M^K31=x=Gr-Eu*ac_qhzVvWL-W9KKjx<`dTM9 z0DUfe^I~6l&J2Bt3wIX2gint?3JRQ$toLSSjRFPC*L|LMFGq+szhC-1?&O^u-uE93 zoNq*Z%c}Y@c+*(B`|5Rbz=GJ;TXX)p_4-^pirT68l4sD<*3sePsXj5mcm6WY_%ZL^ zkZZQni<<`3pYL(g0E)PR=;R)+a&$JBX}27zy7Yt=wrKb3dxR z{lxPa`h4x>eukR#Iz5~FeE)KC-5DkL9QuIfr+Dzg+j(C;R}FKYQ_))7`I%Mm1YTtV zGw+k_V_fUO1FK>tymJb5HJRr%o#I*~f5%LcLeR#(G?(y@Q1{RwAn*a63}%8ipO4Wb z-#93Ojh`-Y{;iY8D7*`OSY~lFu1zNEZbN2CbX(1#_}&rG{X(78_YPd^3=)%K^@NRx zz-4%{8Y3Js4hWW-8^+mKIXBu6Xm>& z6J|M;Hs;MqPHRT%3!uHOoS$k(0B9@3l`(Mirm3#$>LqnAW%LqbpwKnV*o23mzsR6D zRX0Z!UrFd$=LBB}cJ>mtYns${4tM)eR$O6F0CgY4ohV1}R?RGv668lXGgi$q+i>lN zr8B>nALdULS`G=xKC;&U#2Lj?n!DR)DCJ(%I^!iyGo2&(dJ?DUDO9SH0Q=S74M>yy zCVLI{(=I~QwS36q1+m$6-1CH+x#3Yr zO|}&j{x_#zcs)|6dC-S|8eeO8s-E&(%1EMvl`i6M+>pcHSsG_1(65FKGe31qt~Njf9N z0&z*+Ou1eJmDS|S@)*1w&q4!3)EAw5BWFA9cz}EbXZe?6`=l`WOirsW#db-t@*O)! z1h0MAf*al+Q+niKIPuoZ%#!NmsW>y%%q)`H<==2>ubG)AHOps1!tBol3h~BE!IB*d zQ4zwGK$g2kYE5W!{eC!Ux|gm%c1>RThAq!y@%EiSqaP~yLLo!c^E={*wG=y*X6b1v zw=8zs`6lT}D!VLK+xcecSt{QwBwN;|@i8jXEIC`&=J6>im#lZT4Nc<{R5n@Mut;M? zl>xjY2`FOofpWZPGO#MgLhlI2N+A1PNi#qXB>2Fpdqa$y{W+EGblv%EM(M>~<6a0$ znMHgFi$ir$evVmu0gFMkX^`}N=GGerI_jzFw(12A$&-vi2S6ZgSSfCXi7gO5@p}>bvvtKS;KECLY1=Jo$W|9WU$T|}~{s;p* z@x4_FlM6S@TXbh*C>?a>nuIOlFi=&KS7sC6#6nhOm!D%5U&kU;b(NoE69-~Jsv^m= zunwv#(b4zsJnwyG6!IGP zjznIra=p2`%xbduQ>Pq+&2+BxE|N+J#xAO5FU&-Ssg@vl>^BOfrm@_-)BhOTVPD4X zqZP%8e4O${={=@mQf ztD3C}KU(!`W}!Xm!XI+_R;Wo8$c8El+P}AKm_R2Ns!*sCFP8w(p*)m&)h(5)!Jpeg;LluryfxKFSp;E?a)F~rXuoiGiM-s|7^n)6f zX(gcXLy+RvK5s_B(4-Y19vX8+dd_kxspArlfqDrgev)bzjsPo&1&C5)IoNbYW`3iG zKBNFV2sQ`{q$#L$T4pw9@M(CRfVtGZssL@sy%m46FFo%ykE~fL=>S&h%2Sm969aXz z%M;DOfNt{0>q;RZ%0%s66eu;a@@snGMVb3Ixz*u2Tr3SoF^H%tV?8=3GIl%RA_(Pc z>eig)u!XJXgCmxu@Fz_HR*(zerHFE<=>p7f7#^*Ce8pl8-O!7K9JQ0dI}INL41P#6@z7TFI|cruaD^pH!GUXaq_gE)#>D z+*09lP(GzFeb6%0{Rqmy@%#76G=qNToaLb^-!(rZ>ClY&1%m!a{H~Pj8%0e%!u-v> zO_cUhOY+7mPSwk2L_7|Mt7qad@$uI6Nh^UyV_q|$9LD7-Nd!r~QJOG%5v&wm4l$jR znb4@C@9O*DLhE=Rm1tJ9Eo;m85S41ylr3xP_yCn`R+Vi-OXT@RxDlQ4h3`5iMS71_ zIHMz9c=GuK*q1B9^{ql&1-n@jZVt@B@(f&s=^;mJs<4Hx^C!wvvqO#M^wb+-JXOx) zr4ND{G=S0EMlM$KoTrE`bb1ZCKDFTS=_BzReCF$9^f)Z8pgD&ktXtV0zY^$^Cd_qm z0lAX^)=e?I3sPZJf*eqI>UczzK0r<3ro%I<8d>yB1!{veLRmn^{=~-xHb&XN$~rsg zWvGz}U+b?cbonD8tG6xlxs;%BeI;^P@e#+!|AKJFS;Ok61%4z*D(L41<3U;{A8J zu6;83Gb3;Jy$jR^Z-g1SwSAE4sP2EHOUM9hXmn$tZu&mRnz`Zg*z6OkU*2XWnJF_drWw6vZf#V?%ZzN4 z+4sLEEK)iTGosPI)3vjekOiFh8)S-JR~?$7lBnSzU$X@iO- zP9I2QWt3DPFTshoZf25HE^on^v2JFZR3fjzsl7hbYV}j?k>4t~}-481%BT;WT+qtyjJq@ zigj53zt^a{W!uuBR*QAD0Px7G+se~=A*$yb)J_zs694_#8c643-9~+Css+pGa1lY_ z`{nHFbDjc@@KBY}>UOoZZwWdnDS5h@GA-p0s*t59a^&e7#IQqt9KtzonC*;s`&YaAP+k^g(xcgWRU3+>K>#y%CPn_ zAC(lh0HmJR({GU^F}|&Hm0_{jT%C(j&i67Y>N2z+U3%Kx&(B9Rjf#QbS|mUPAx9X! z^e3$LT^vKQfmy&!!KJe>V;YtAO$B5?HiB8ePa&jpFu%}iqfDMIj=q_IQiqt&eQ*X5 zW<|n|iOv#ooYN997U|${-w7%pUWTRNA(*TnajW;5Jok0E%GL@c57dsN@U`E!dSLqU z6z;t+$U&!DGq*#k+}%_S!dR7}j97y$K$Swvy-i19);IEsG^NSSJPjV?lft`*ykj;W zvTIbHh&aWg{`l>(B%NGNC3Gljv~(O9qjod{x)|Cz_Z`JD^t-+qhJGV@M~#*I*z;}D z%2Af&+UIC({+Zdg_d3)V8o>T2>8@nduS*zZ%z9ImYkMX}>R6ar-%u_KE^xJ*Ri>%{ zCYI`0sy41ahT0$J9xe$t&NpcZ`Swg;7!`%@S@ZW~C41Nrei^>U#MqC|?8dACnNG#b zV6@if8gLA;AWKMm&(OS$ixM8_fZ}&IfG)Gm;5%=8*~fNtI9z zN7>$^J6Xu^i(MY_Yj?!QY~NRy6ceqbL+l0XD~Dh9>CnO~e+3$~;c6H82g|TDwF}NX zS?1rroQA(I@&BN=C7f`s*Nr4~3T!D4$=*{-sJK-GcvPKv;pH~H_s?}apDLWo)R=ueTo$^#((o4!9mTHOD7SnSRgXXPm z6Qh_HCyBHa}?Z^Y6T|EuaoDKN+;3c?~ckS({6~@%X6TVJ~5Y3${lOyefm>@Ov^VAYPV^3)<2bwAa;1jcs#b^YP*a?x*BTgiKkfVCv3PXpuA!i-3^GSqJCP|9@U;zR5=S0f6`9Ii zY(J|spgg!9zmGl83VZ>k6jBZ+-GKR_N$^rodyc1?W=P zSViJ=aAr}XKRbk3)<|PJyGEE0*c&B#yM@)m5w2DNf_!CrDtS1$@%8gtTaW0iNf-g)_{epsk8@s=B3#vpE%L!w=iP|4RIDw#) z&GO99$)feL1~Jfms~$J190zW}+{uliHWq3*VTcz)Taxu#^ykAvpysFQ=?#~;UUNkTNmsttH~c*i|Jt=iNF!U4B{tkMVQld4~FN9|X7Yb{p+kW$m1 zs+j9Nt?NkFXa?*VE%)8M*uhSv z!2iztD~CFHifTWQ>l3;j?zzguFusA@k1<}A=U=y`b>dN%!~% z@BFE5%=M0E$~CyNG)TNs*|1_tK79fiz>%R@&XM6<;>=UAS9^sX(+Wz1^o^q>=Q>c& zz^wDvs!{V08SFu6ABBt|(Q{}7cLM5MsBbFU8i=qm6Dv(&5T>OI#7!CxAa*FZ&FSle zL6QWA+R#QCZM^b)H+;vLt!Cg6emrcn&)UD{#$6dOI9|Ez4}e#i`hMXU3MyrEfO2)^ z=xP>3CdOjl=c1^?4?CZ#2fAdc2D*|fnaNeMJa#+R#foafc-z@%H7~$aVb>S_L8zD_ z3+MbzAgMF!^sH>_-M#4RU3kzM*62``iTu*TFWaYO2LwdCwZ9Zg^Wx(R^37i(1}eAK zE>j?S(l9ol)G(fyEF_3;A;&hV=vxdZhy0@jwB#CU*FvDaAvhUb@y$P(fzABQDAxO+ z`pF9)7U5ozB?=K1Q9f5}X}0&5WPZg$C==T~`IW5jRsH}pHL`?jMRX!Myk}kU`xoCe zx~a+`x+&Rq1h#y=*VM|df&W&De~43Qbh^oJ6aLg${z<4G0f%dCl7&H>oR1((Q5hQo z;zST&YCtI?Gu{U<5BT*9MFVIR&tqv4w7UHBqe;5`aWt>TCo2(7{<{CZtAPJErP$-Y z4*v7sPyLmjQaaBd3XI%e5)_A{OBj0i1SedQu5J2K&A2pmef|yP@3VFvfKtr>63t5Q z0Ugmlc>G^al)}4zBl1su+7v$S5gZ++8fk>tQbHYXqK4$|iIf2$d=+`58$|=7g~mB> zCnD+o_S&kF`Bv}hocLy9Ltq zV0#&w90N`Y5^sD||KtipiSwP|U@Z?MJ||9uxIpUYs^6oO5IsWGAPb`=9_FZ_FEo76 zC^M@F(akU;?iYhr939+3*mYleqHt;pcUu>ekmEenx%gl->`-4g5x%1O5!u7`0VTm{ zMwTu2w$n$qUy7{`*6*w;S!yvWS!5d;Q;X(%s4+oGTjH&v&uQ*PAun$ApL79qQLB@8 z!YWuahg@#GJC1*kzx&0Hm(3TaZS>V#Q19aGCI_DxIQL65q3irtG#Tjqd@B9Hkx{G? znxC%Oe7`JJlCD`46TJV(si1~b&1)oA4KT4)$8xDG#NF7Ct@gWgyI%RkFtOp{`Chzd zk&eubwWfx9?Wi07#8Pm@8Wg@8_CJoAx{a=g?3r}mQpCDA(b=!y1^(ptgKmg)QO=H7 zUwQhMmmC`ilJXJSrk=#I-;GkdC0g*xevrK{q8?dl%MwX7O|%0SO78u|%br{Sol)bjKExVoxT)eT(OyMix+eB;Uj+@7hB!+D9Uz0_ zfy*$~(|65zia+hA!@bHtM697T<>6NlNA`bx?rc+%x%u>02^VO(iYn1r3X?zc_jWeB z7Szu=_V~QE1n)e$U##OC5K2iFf-r?!BcUW$=>!W>jXx`{QT^W%RK-O{s?-0jtRS8~ zu^I=$2-@)+x>@sB>}O;0)x%t%Q{0atbks{B+_yUZm9)p2!QhYz`Thfk1}GM`x$96#1N-k0`bmt)t@(9?gI*J^AE~m^W+k4)qc$ZT3v%qjGF!={c)ms=@kjZ zzI^W28dM{^Ah&>O`G7Pf(Vg-y*9VyS-KaDXV2ueY!kaaba1UR*%?jNq%mkM7IfP6d6 zSFcykOe?8N6l~+_;&|PWuHT&1mTsUw{B%M`rKQO-C?PBOoy^nVX(Y~lpdpW+smb+T z`h(hNqx1c>&9C7hapKd$C`gghlG~$j1kIt?{ zP3Z#nx_;5%yH)oiosXcYVFgsOx2-nkS6p@MgsKiRtpi7v>XWVEwhEd+;%?Rp7(6Nwj6H?KHuD3-+%vkSma-EcYyfXHo36p zkhd#%-U7VoJ;@V!b?aQW>mBlcY-)e4^PG5@MtyMV+#L3A=U&XQ{pj!W{_*3h-A{JU zr`yA`4PX;cfZx97?94rGz1IB**rM3^>2WlN`22J)yz}R$_5K# zdw01|(lF%f7_^CfCbhHn zlG4$!MOCLg#&xg0(ouj%0u~c1e74B<&m|}fsZtdbvaP+(tKC;U*pGuPKHc9?nHV3t zcimJ4Yz_0y9$p_lJRDa5-xI9VqJB%eY;ODZ`VQq8c=q~`wtjx_GP%=E6U$%u!>jF^ zAaR@nS8%`aPrdKU;Zc{>9?h?pT4(Oxik`o{SUGyE<9rKWU^+E`DVm)8V${0Tb3-4R z#b2l_AYjim+_2%ZiCsG?V`kV@71#0{essECps{X;*1qZWdhl)ilYF~(BSu~;)B4_Q zl4Wn}`o`F&73bcUCllap+>TlI@$>5XtHjN#lm6k=Pl=MvkBv;I2YVL-bf^`aT)>y> zZLhkmE_x22AO%}C(#>#d^|!vp#jmp*R@}ZT_&LKP{wlU0#mu?#a`^3Lr{;CE z(Y-o>EJS|L#Ei?)KD=J9`VIN4wMZ$$P$Xa7S|8);YG^5&W4`svMjdzxgG zdm=(1(zl#Y9I}rYjq<%>`PdL8aLJ_cLL`wwJP@={^KfQlXe^b1QEItU zV~a8LOH7C2ShtD^l^MeaNGF)!LBK;L!X=Z(i;%k$uKJv z1{?)CjU-8^5PqN>6j`bxY+^5weG?Nip&i3ctoRlx`CV+5no=hv#8k-j%{-1x^E5)B zO1@4Q++WOV14C{NDQc&@Q^-(5s~^ICPp1Qw9!BX?|527i2|;ZVVk(_b9=z$ zY>GriC^@8zpb$&UDuR^-fM2Zp`FJLk9eLnE-~#KkE=)MTij8K8S&HV=Oi71}-vo{3 zJfw+2>;SEVL`F0@QhAYN(?pT0m0h#6iU~teycCz_z6!CWR)Lf*v<#^bN=!Opf>cI0 zIgAFgs7$MC{L+y<8_LSfgheD&sB0`}`#Kd3rp;N3Y z!+T}*wi!6xDE0T?0WW2!7!J4%no%EQr!R|80y|H-`~ zZ%zCJY($>t7!(Qb+Y%mvKag@@;|b;qE!i~BAkdc?{r!er(O}m}RY?IT$|yCzH-ez- zQ1gq_V!*}|st8g8e`BEuJuyf7<6dyZCFAX_DjwP8O=Ea>sGn`n-hdimt^JO&5;D;Urd640lD|bSy70|$YH6&9 z)k#QRb7lD$2}TD-vZ2ah37M&sR5{Be*a2(V0Yu>+GnRO>VKG4w|CqJ;qP(?lID27a zbSwU|^D&}?M)_y;vIsSe-hK@m#6Li=iS+P@FzKO4H<|ZRnEV=6@a-Ng@9>XCmS#0G zKskcM6S#g7zO_2Jbg0fBH~%^8Zj5-(UibvwL9c&icGv^(5G;Axtkx+gq7s7(l_-N= zj+FSvRJ0WJ`5I@>a@DA1D@bB}Tz&)o&lg+9+w+{P9+g!;r+5H_*lrR& ziT{d+PydZ6t`z;>062zkw!t97zw=~9c>X-3x+wX?-1-X@-)1P7Y@4$&#okSm<<`ym>#feyh!Us`O zZV+WKIn>BnW(4|lS{l(T;}M+{(d*v?)!&jQ$!Q&DFMYzDUd(9^jRnW>;fefXv)T~R zXSZ?#dJ|MJy5LO8_@H@FR}#BbNUIctWz(dTuuOY0l|{l$=S3$P$%FS|yR;qJ_-6sm ziycO0et|)1QuM(ze}a>Bg1zzyx2rlG@mmbVx%(0)HWrFky=7?fH}Ft3nlbm#wCTdo z;$I0bgD?{R&2ONL*vJir+l`ZMrMV9IN#i!(R-fMM+{{l`*}V1vH$uk~z};YsCPf!a z6Nr@@uSS%ZSszuG94>IOuplqYp*Aa4T*lu)S)TM6y8Njd#3^h@io(|A5${3K+<}~z zAqCy|R~xlYh9t9w#@UF1J?Ko(DJb=SSyHZshOVO!S07H23@9-2@ObhB1f1Ff4^*x1juQK(`^8nz70Q0L-0k}}o zQh&^{Id-_qH`r=QqRH@_-@4Kk(2I2eyzr%EF-7SB(8c4DX>R>v6v37y@fyF9?7#TE zz|wEb(PUpF<&)y)cQf`ew$tYy*?o4xBj%?o>VbZxNUm47-$dmXU*mL$W|V4ct3s5R z`uoR3x}tHQ&T7AQd5W|`Z*xIOe-|}Zz|^7;3}n@kvVm5n75fv9wU53u-6)yoon-JY z4H|AOD~4*H=e5*^Z$75&jn$*ZoTm;2g9@+Qs?3U&mh&@1zdjB$TRA5U`(9e_x)6r12EDwmNh!{XgpPh0I=Kc05K2!miuh$suGR(p zc|XHEY`go6K`+psKMN;04Ui0YsmJDj!{vu6GAH&-svplgk0v@02hJV0?fQIj;2U5T zK%3IYn)I1t>(dFMpkJ|Vqk5g8 zmwhX$&B8c~Ozx2y#+VH5=4nPdMlJ+&tis6EO;FVU^#YN0VG9d>hcXvJIAlOonVM{A z!5FD`xyQ|*^%NF8%+N4%K0h1T3hH1k@kvHgh!7uAu{$_?VcFZKS-Al=s5NUUJJMXY zkvoA=1jUgcV!~B$UQX!cYYJTOJ6mTsSyf$$kE-^_){b4M=+yWZ`FJe&U&k^LRlUI- ze|&&%7^J|D?uLZQ%BF0D8ULZf>JTrsk~myV@#EQMx3;-I3L zTVk!uIUx|(P2_FO;rP^Qu`I&oP@v6j6_kl1pXt|#6W?&!{duroKZNxPya9LYG_^20>5 z;O34o#A&*nPSJ>B+PBc!kQVM-^Y2$0TrJJ*%$a_#zu#u~t|RO4mJ6*1=c_--O|Di0 z8GIT;;{rB<<6$|NoeUWbJbF@&j@=zb9Acgy?+79?8T&331QAZ-`5q;p6n}D@--7ZxZq>IjQ z1tkF91Fx&~E+rKQLv8`Agd4o2^H~5H{=_o1e=Wi@s^6}n*bj}>DPJ2ie89+C(mWSzlMnPZeF=epurPacku1~PQF$h|4ZOg9Au<@UnbsUuxv|6p zcLy+l#7aJx z=g-S^E~dO9(07i2pVPx#_yV<}07Eu0j;p%u~o43xHKo)_XgSAeReb2!HBis zXUEN;;|WOfW4&#-SWb_)#E;ANyNgbCHu1vpq47B_zHC&n>E1}65F{xm5suxTBG6F3 zh{_Ol+Ak;^V{2pR;adgvM%F+SDRh$7#LOPZqb6m*Nj4N|vB!gctM zk_!iah@GYu0mc+m*kTwOZ4TR4ojfK>eT{KtW6LSkRpTY~79tZ6%{|@87+@Q+3L1Vl z^M2cn+SSGn37Xj0-`{GI&drshpf489VB) zjg+QCtku^q4)GSBqU|A|;*Mkl4=H@Y!UJzS+l@kbgmNl+%9Krl@`FcKKTT*te1?<8 z_0{B>qDk|#_sxZh(*%!&X)$1m!ma6ZqJ`t!aH@URx`{dcl3ZhZMM{iisi~vd+sZ0= zzJ?bq4iD}YDjyc|yBQdIrolSxNfZ}$%UbWXvt>#0)~_W@OX93y4g(vKI_FlzDKSYB z^{gck%Y!h%xmvkH_~oe@cZNp*{NT$fv&9#-t7IUdqSrx~thRxCW)0EH9b z>JBYrrHDqa&*9(o1bo8Rmjjew!-e(ABh(dr)0sa{Qo_#B_b@p;hKWy8 z5l|8%80yAcG>5E@>wo4|6V4+_VV35?76$ee#J99~9=ti?I|fLyzO)J?tv@}On(eG2bjRQsmfon8aaO0o9&)uD|>rPb(FVu zziO7-%AfwdBK0MxTdG9q3Q<>hy7M+8*IEx{tD%0jeQ6EAQF38&J)mm`1B>OzSWZGE zLMMXDp1F+EwXyT4q>G-NxqgEntY+9413M2rpE}COu5eR;Of^06(ZJK)``8XEyZSKa z%tL={UU1=f#_GG1%OT^@{_c9`?0s~O?rObT{laxRe&UTS;N-^giqw?A^hKcPjvA}W z8!mP$VDJQ7b)HC6FldkFZlZ2Sb&D2qb!w9CLz#?U1ZbVhtHjA?Zff;&kWcH*f9^ImznX5)Qh>4*j)s9KXIHEWKRQ###53{5T*aqceKkazV#HF~Q{G8oyK zUdrRPvrZzNL&-%F18q~W=qe`nZr%81g?h%~N6E^~EDiDM7JG__j1;+S0Xm%mGgWKI zB_Ea=)J-J(Kda8m0c5aFVD{GvX)GoDLf$t>a?bEdliagQ+Z(;#YV2OQ6qD{@7{^>X z6CE!`(^J==TGkteRLkNCHBD7LJ#wk8|kaAn_>NeBgREG?r&a~r}Q)a8$Wj<|5NQ}B* zpLQhfyXq6^ecATp&&C=07!W%IzU&$76f5!b4QiLcIG#`40Sq$(c{INzqYv#z*M)E^ zeJvmT(vk-#7RaR}frm9JsL7TuN|nc!6W1ji4UZ-ciitK$!wUVRYNB9m#7p+gp_=q9 za|c0;P?=kj5;$EH(@Ly?Uirs5vZTjc=@p3ZgpO3^i^Il^9xE_l+Fv`~z||mci=oKL zSNNhT5I{hEx1sHhOC}_VC=(5V#q-|uZTjv48=!zLDZYJgf)e}kO{M3^DB_h7N95=O z%5sV7XzS!pR3qZiUKf}B_-+F*S6XjE0IgKDW-CsJ=4h?qkO9BD$j`K3ckl8mqY9!j z7q8*PMipyKEbWIuHVOZeO7dm$B_DY_pP}!xMM4$^?x7j?6dDisW68Gf8Tw+gu{@?1 z_s-0tJ8p#?-eC9Y4~_Y1n3vYfc# z-<7IBuKIo_XL1#QsbP}}kA43`lmNNV5f^E`@A^!{-;20d7}eWxHzmci)86I2q#xE) zTy}uQ!FS24Ob|gK=uDB*xHY$~GirSQpIc_GLOTL|5T6u+ggl5+e!ZUTVrlGbZl>z$ zY-Ru9H?8<+$vf;xAa#SpJhSULuTx+PjV;su-0GXc1hr|)?uk%l3^!Af)CDQpHGjjI zG41@xPyCq<0^Iw1E58C;;sk2^pNzlU4o2U8e5Uil4@(0c{e0Oe=O=zdO-pMr-JhNOcF+A|c7^HZ z%Rw{0z>T8a`|P}I%K} zu`eU!HOk(9J&queoNSxt@gt;D;<%<$Hw%SpDx95{jk*dLWHlabQfaDWPfOhHC{)pu zIU=#FV5Wk3u}o^X#fa#~lLn8j)4-xdVbH3Ms_vqnX6;U5ErerPN~oz2;oD?sR(g=^ zlu;G4H3+_bx{ zp7h`XYw-qJ>6&A^{mcZG!dypG<4wc9i3yP{ySD-D>;xJX%_&GbgqZR(d7%#w>&l46 z+CiUyqTkFuY%c`LHK2Huge>&js#0z0*0)=UjoUw8#KayHW5rY0f6kuL4Pl0sd`td) z54j3Q1!{!8H2WDUZ#hCM4u`nznHe4a238WKmp;Qo69S0McNyO`aDUDmKgGb(fWwM6 z_0`@#cDsqvUGXbY3k3AxFy@y_AGAz#8QKLDB&!vID6QUgmUvt_$reROpfK2eFhWut zEYs02$>R$gxdC`pL`cd zM#g+DX6E|VTJKzWW6z`5g#1Jr>7&8$=k4f+)5gEu68^N_xb#f8Fy07^YI@$xO(c7O zc?NQazW5Bo2dN9v*J>_enjKAGPbNkm5S>CRsVqM(EI7g!1X7NH1(a6TW7vn^W5DLk zNv+>(K_@sGrOJg?{vg8R07jb*aW*7lg24)*9nm_(fO42B<0)B-ck6h0Bwj(Z__y%~ zp&r~_hhdZh#f7%^JH|LwT;R8x?DJmQ0U}~*x@T*VUbH}m?8bii9eCga;b;@_SMtK0 zvgTwe`{|Fou3vd=-`lghk5noDzQDWH%6_Z)pJd?T+{VugAT2itWj0|a0b@`` z(O{M5OvVayqs*shvPP4y_7$vam=2GZ#sZ}yTg<1p4SjS;_rhT2^nelvNjeyxOftJ? zns{|trVj9$_k%!^($0apKE;F3utdFCVJoc>X**MruE*_;Nltsk>h}vRlq~nu%wH<) zf1QL_yDC=-E|g*Zk)}?K4Orl=$^?%ZBxckN3AOuf-Z?4$k%BI!SQFt_@?xEu>pg+U z6v*u-xgAmAg|GI0dFqA~YyX}CzAU`hf0Tj?G56OL_+6xc1*Yb|U?6>aRNxd%)2N63 zM+$Nek5_b3q@#YMV0{^yK1@my8Opxqf_b$oPh9QImUrEnktDJTzQo}otKjRfz2G_< z7;GEbk)*46Q3bRSrV_JjI(gw5UD4fZIqf%o2mL-oR5DO>W!W`0cr!E}wg;=EzS{ z@1dcw{5cLBk@K;$kdRu( zuL?4R2DOAvbSv+;3c7lfVhgZ4$g2wT3*Dyb59*=tV=boZB{5QT@8;EIFbaexKuq&} zsxZ5i?hlrKFwAQdurg`B&maknda3x(%}XxBawntTfCr>KD5?!N{yKnfC>MnZpAip( zCVb1?mw1{&PSgTd9K&HeYcAIikSqMu{kA>L*>iuir=j*BV!vE{$hPrmaH&(hOkM51 z4|hdXKA`I(SZ@cx9;5pHEnw*`uv8REsY1psCalX z#sIw~3&c0|p>*A5d@T#WzrRrfE=j@;G1bYuz4-`wwcI zckv@m)fiHSD77jr_;%lK%hZ3+sMuHUVm*Fz>R(b4iFV(m!92Ks*>kWpX!0iUr1AQA zk$kxfY|I_=D;v~~*i5u^zK+&ocCYxL}E0Gj- z)2w7j`A$LZDi`?rI5l$(xST~vDjj50voc;G`&vX_~&@M_0fCcKDb8={>Bvv-*{ z{^-G?f@t5@;lZ!6$vJk+w0|GDwEuFax_0VY?3S!G6wBF{qhm^~+wQ6l$X!Z~Z;^Dw z4lYjrp)^^&N?(=G!N#m@!z1Rd^z@y1m&)W4edS6M-GzypdWfn?YXE^)H1**@6xRmR z#_@h$yP>sR~f zPD}kK**naLCL8;oVEJHpVhC|=lFl3udGZdrfyjCYFdA_P6Bpl5$+RMbwrFN_&J}0s zubxpOys+R>PMek>C;<7g5$^=u(O_y+-j2?MGlJ9G78ni1yU0vHYa4A$6O|Q`mX$O+!m~8Tsr(UjjCS zy@_%YEqbEwIPFxgCzgTgeB-_QEa8U|Av)KvXtAn&&5!M8I*1Ps!pmqUro(kIFsx1~ zooqfr2)MOxV#qx|!)q7BUvI>o(%8!Q$i<2fcXT02>VZps#`cztp~abMkiA2IVB}t< zZFAwM70aCw^(FW+kvJzsor~hT$6b)wmtia*NXULddgBGr zjDcMD$4b$$!+WKVxNKnZAt+ zNzrr9OQO-e$-!UBc$BTGTuIjMT>W|ch7y%5B75;C-u``AV`M_z09 z?ksK!tn&Et7pn;jx(mK2nq=e%01B%E3VL``!E8eBYVPN>^S*n%Y#DxEX*Uoo z!h>OSNB>EDx)lTW27Sd0heTcn#Uo;zq76rwnA1QV z_T-r^FuSINwZ6sa#473|s=RgXZjcBKPZIIb?hY(9k#qQiqf-Qqx;Lh^skc#6oAKS@ z`X$-&&eM+6+A*YBL$&1@7a8DOoQI!-Z{Uu-5ezsvtM;WW8JauqLi3UMnk^(Wci_>l zc-(HCVIq#07FdqqiT=yQ9g2R|7g+XPo?OTnUt>EgF={#uQPbztF^!ys|Gre2BysC* z#y~^EMb6d#Y@X)1n5Q**9EK!`#BBWN8Lwpc5(1*HD(K167BN>3> zfHG4=DYlHhvDDT&!8i6r;M5A-(cnn;<(CYrwB(7dxJqwA$+V6fE#vuWr1=Bk z%XLzFd*;#(GgzO?LDlMdlw7YyhF{ z*N?y!b)490*6E3{eUR3qIwdebU;&pyFl?qEFi*Tkh`z-+(qT+%MQFjQkvr&-ouFWf z#hPP!YnU+0r@NN!N+j%W!#uhniC5PKq&w`}z%zARPGe23)CmgloG)%CDGe;L7%Tz@ z@J6#p262UD<=AY@My%${12uG2$jqGNx0=~!*wV_0swqgx6WeKfmyN|oLu}Qg5ehfy zW*^+>#bvUm7vseG-sWsI(M=X_s#{8nxISTK%iBVTh;#0DVVrWT1yhN7UC~R$q{BaQ zY8(kG*f+?Pg^d@FLTsAmLQORFvAu~zw91B_+KnaGI~2v58O3Y_5syf!5m(AH0?$8x zaQ4dtJ)Eu}_@rdR%ZcA?T?Jg(4W$BW_?wR@=r1QfUuy2@&)*+M>O zNzlj+_og>OcwMJn^O&+JGdOfdz*!WcniV&8Ijdk@W5C8Se2UySatg+b*8?$@PS=N) zXG505Uz-USE6L7MUF){r8#@`dNjQtRWfmn_-$`TS6Lbzd*8c4<=o>}&z50I*1KwYT zK_(X6k71xF`9ME@Q1jNLjoRVJm}<{mirEJ|g<|Fr9l2lCb;>V>LB>akk1q1JZEwV@ z#ORpVw7b!W9HjEPy$&Ocn(@y<3vQ>|3$g+_e`BK&C=YwcHzobz8%U>06eQ!cH{xJ= z%9~!QpJDrm|Btph=%m}t;Vm>4zEV}=yaw3%;YP}`Eg)&7@xFb4f7y4#`!&$BnR}co z#txfvbN#0TjXh^MgHJf>BPcbtX;+M&n(Uo$tw_$d1rv7!yBlwwZHu8l_m#?U1|B8Sr6BuUu)4!_1@qeWjsDNq zm0g7(v%39vstUQ{;0aNG^{szu=0$-znTuGVa*~%U$f0mYR-tu`(Szq&J*t;bMp+pLKvwIOT&0(A0 za(S;%KRYH7mr>8{%jd(*{)(Px@WS?L_NTaqYYz)eE6Ycy1VVl2?ZmAtZLf|647h-? zy}70sv=r_tc9ka;*EV7t1?)|I3%eV@0Cz83vg6{aU32LUV;iCt;8B2+bd|A-Y7u&r zcmu;bd((X+`Kzl66vh;WLQ+;{!pa9*wgz_wVb$E^Jz<)>`EhDi`O%(*(sEk!RIi7| z?+uY_w((^s%gj;{6q@hpoSgs_&)e&#SyZ?xAf-MnK53_vzb*44Tqjc*q%xt2EcF{m zH&Bbm<|$L}gzuh;PnPoms2s55jT!qSNNZ zx{giB>FSB;F5StYHS=yheU5}I#V-Ube+N6~u*wA|8Uu9gYL#0OGts%bn9jnP=fE9? zyuy=DfoWi;4!b+goE&Kl_{k2Ay(%DeWONd3n?-qv4kNXL>m^q*>0kKc0sauIj;_Ox z>fU$eck?DL{ZJ}7MJw82Daif4Qw-OFNcxTVj;@CyElm&8UFN`kbDk)5wLwY&COeUH z>)^9z(?KhgD||;1^ttz5#=nTmRlom`VU}FQ0x`=#^!tSdurm)5gDgD=QZXU?Yw4Lf zI{vTnkR|u;N9qe@$lS%zzI7km2K785&7$smdfRl@GfRds9?mII07fH$py8cWx51Fu zwFN`QE%MS96H8HDhlR-B;p znvN_BjQ0+y44n)PHn`x5^MZ84r2g|V=wdTKoNv{=ZSez_xq(K}1S6}5PlqKn zU?t%o+VkNP-IOGyw+ z@$+l@`TUzd%TQ7L74WND|Iff5&lSkA@fYuY)Id}R^UF|V-|?p}?@vE-)Zkx@pf5ww z(E5-v?tiw0M&+Q|0bh~`kU!J=Pv*d=6x5&fT~Z?0e@nR#i%}`4$7L@mP~qQFF7#GZ z3hHUVOUf+pf`WQB5EX!Wq~Q`^By$0{Jm7#DirT%r3@w%aGZeL#iAq3iI9w9Mlu>i= z+x7!05LLgw1WJJa3-D6SM+Ks);g>*Z$bSJ|YU8LtRBibZD64V-L{XN1t2CoRQ8&Vu z&~@aN0a@4o2lQfFj0#2FR$M~A>-`hx#U=w4`s*U@5{ZU3X^4jQwvd=ze+r8iY zpYP>i@zVWO)tqCFF=kbFE6PAXVt_$|!GeK-k%E<6Yv#FwgMnc{gMp!g!M@TFv$J(F zwRJL3{b+CMsK@ALV@;9+`HDIV>=o$x|NHx29DxzlLCbDtls4=;WQln+I;re==rM-5x9d{8xXWZ#NxX6E(O`A8cb@M{VV>K0*~nh)e_ z?CNfj+^-z@%cfIQ&1B<=A;2(27mG_x?uU8X#g9Z_PM&Y;%O${Wd0Hro)2lL;3zFlbTTO8knDwN|n8unKOB~qQ?E}Y~-eMnw0yFoHEz#7;~-l+vwnnA2~W1 zoG+e3BkzT#M7}tZr0yKQo9fiX0h?-p{8F=w_>*E=6lwzfhs{_e<9Dhn9zp_^jqm&p zVNmba0`*L0W(miIQ3g5%*&`X&GGg9T39O4Si>6oOU7*@7n%te>gMmFiLx3s%sbuTb znBQE2a3~9^NO(}m8aS9*J2El8{Qh65{x7c2KP){Wc3i%j8KLi3@{8E!{hqBPY<7OD ztYj;xDp4o-5pn(JTyo*-s{jZ;Y2)R|tDSKnozB!>lx9^nNl9 zx5)Hc{FXpa2azHJ|7@2fEX*gE62UwE+nPppIXgF|ZBIawe1vcYI^VF%mY5lQ@%VC4 zis-PEKjwMbH0t0znK48L<&v(##d8Dq2Qrz^3CZv0{A*#3!u$KajG6C?Z`#KAe-s9+ z%bDC5b@d{v8h{r5_bOR^{Yd=^By2MfU|@J)u;6aiOurS1tDS=tz|PL?iiYyV1K_-tpmW z!6kW47zI?&;&EQylwl>!2O^ua8ODngV_dvl=Z|xUL;P}$tPit3fC8Gx1V8&SP7-m%Q=0&kJ^|)!Hhv(a0s6-V;?tCt_T!fGaVVz^t&zvr>y`^;r|Ii za!?I>P9RjIfp``f1Pu^^{)n9jN*zKSUk6 z!Ec$Yc+tbm@w`6a%s}flGusZeB~K1b?nu4HnNwSrHY@sdZ!@H-;*%-Eo}i>OdF@ds zJj|D@H}uZPLU?9t0tbOTyX2qI@e;7(?1Joz7WG>wmiTIo^`#QYo4t2)HDCWcZTfz_{Js;8}tM3v;Mo%!zt*;71 z+=O$M!Uo|~E`yUeM{1N<;h4sR)Ni5wDM9yue4BWXZ!HALB>Ha&a(ZuSW6JdFm*u6v z5405QmN_vxkQZD@oa}6<8t`G9!xpMj%jNKUY=em`k`pyma)hU(Jn@${e89U~jFP}x z51Fm$CSJ8VWm4({mqXlPUP(&V;0()5LF3QO2EQfq_IO^~c;kGza#WEj!Nk<2!$4_@)P%4L zBb?!3eo~eZxu%dRKMhpXzE{NHDQ;60wgrKn(J2`TEFis*I<&ysF!K8+2}T#Sx%U3Nj)sfF9dzdmYsLJ&^QZc>3~<9W7`bwK@s!IaiSoEf zdY^+0)I4}TpsTcR0$ z;>maiHX$5@`8g(q%EZqzfwA9+w%-;+*;Gi5$p9Snw73O+uz_EVhL_`VariI#Yqqq7N1cmnIh7W9FF>dl9C z%x)AFb0{QVm)E-)aD?B>dCW|kkUo5N)et_VhS1MkaWx?f02I7`y@PMG33knGPRJ;Y zXfJk7tLera?(eV-Q12l$^w8{U4L9zuZ_|3E#s)9lf3*_L4LD*Wpd*L|Qs?d5#7CnY z9x3fDI7i+2$p|X_BoZf-m62o3dqWkC74BjI>6M(ci%{WWUF(YN%uP4#9!$_8DG56w z9YBn>4Ls$|pdm(G2vdzJ;!JrO7d~s6k7&s1(1!d)8Yt!`N%sI;pU3Y_nPD z8HzQ(ep{^{c#oX;laN3B`n5^#8P;WmXh-S9s*XXn#@1Qy{FXRP5N$a=+Ok#Z7@zi{ zn*y~l1c&)%0ef3x0OI>^!6I#A1iVsSC^DjMGsy@D1iBlC ztIT^V(l~FVJ}sJ_tTP&77M9b^prMtzkT%@4*=)%S)IsOPhkQiQY<}JEHHtUJ2aKt1 zXuVY0#@YxBcZxwc1?CA(xij4tnWe?|4#kpbBjY379k_+f!hO?DIl#B)3y%vs*rQu8 zUHyd4WQzLb1Wl1IIg*}{k}7;sY1xWn4v*;U!_*a}y=qWDHF%}WiYx%D(=)Cz0P$WW zZqelSYihYH3)gE)`+K9q_Pi<;7&OvZq{M7QM7D$=uy774x@T>O5qBlHc-7omsp@v{ zu9HeBa2F>%8A|jYr8%|mZRj2?tk z#E+@$p{fPvh)&jBG!66E@(({`iz2B}zb;1^BC)CI_2e>GI*67tm~cO!+70>t0)xqF##9E3(rL- z$&cT&xn@X(e3rt#-v?4c8$l>}4ssGnVoUOI`}GYXEg4Sbm03*BN$D^wmoYU>kKSf5 zHzXd=KM59ApKp(t?ri=L$K$K7GPdGtn40;%7)Jvq7I#2mOkms|k11q!I_YVDf#ksn zWTB8_?kc49%?>64^80Ky5{yojcYq}7?>_alYAqH4A{ZEtH5eGqe_V#+ds9;uK*twx>gPUY-n2 zyQtLpyYiOIr;^C&HR7kcq*mg~_5IWQ5_xpJ^+PuyPoDHuJM-F&tNbOqNbJi`mj%zG zDxM2=@^?|eJBz1}iZ(>!Foy=_;lsn1)*Xv&a;b2QFnJP>7j?_(Ms1G`m8vq`$rf1x=y@{c6PJpI-Uz2A7?A?cRZRG z8|ufseGKVC%L+BAR37$Z6w zqx!kly4QcIu%;k?`AJD2-EZ%5_WPw1K>fRno;Qc8z^Ve1^Q7^mw#{fW(E1|jSgqTi zt}WzQ06Di~R%}GD@8DD*Z;P|^kR^&-EIWm-pfiNOHF%U!`*$+ zrsK}pF^IvcVaj(g1iP*1h=WTnq8LUJn1vw1 z;|B+sfYdXUT^YMEWrP&J8%=l26;dc>T?&qgCm&oMEem4^FsXtRq4C4;V};y;rA1NY zMUe?^4~mcp=BY|Tsy_4b*W|6}c|rpX;G_xn@y8H>)`+xj?myk7AOB&O8D_|7AmJLn zXKFnZ3ce`%X-dz_-Ib_8l$8)`S_Xzy(=Q7{1Wp9k&jAt>mX-b4DsT2cyx zGp`d`t9XK)d51{%ZWS zVWy@OSlsVrcxt8)2BbgcsG8s_^W?!vCNTEa<|sT4lmXwEs&5ho z+i90;S3|WQwY2QCdk7Ca)DnIeqG?IgVyBLKj-bD{>_ePX{Zu2s#d6I1 zVj6P@y_WaZmLcO{5*<%o6}A{wnI#WRGCx{5dWa-Jti(rkSDBxoK#a@QDtna(J|DqP z$PU9BemD~vofZA~Y^9^inH_z+krP#wE=cuNF@`dnGH#xOBxW?NR5et~owXGUVe1E@ zY<*(*Vdc%vOg>(}ix03$q^fjey#>y13NX@x=|zg zxuZ+`bmud`Q7ep?3MN1oKRkC@5+6PXuwUoiNH1B8k@Dp~83$-&_x`*(yp{YoPUiT% z(emUKx-e~kDr7Mb1G!ojUiFXgP(FC8>rCYrZ0hvvVzj?DlzDPn?hw#Bm6DJzO53Zi zUP%?4wGgyv|C;^$4~xK!s`{SiWR~jWB)>%U9S4PjkVj*Cs_=cqV|Wv z%v(6qb+*GJ!kkVcz{a$+Ix7mn_!W*a@nHdy&9Jb1RUumT(k?yvhEeH6=`5{3fLJPw zVccBlRHD&l{N2zpX7Z~{jMQQ6tD9wI|9$)=>A}m-S;{QRw7$}Rxu;MGcct#K$YR(9 zbkCpCl`{9;=j9F%a{pca6f`dKLZe~o8x_JCJj!--);P^hf;2&MKRRB)FTIQ;O6#YJ zPz?FUs%*h%H8_>vvK@c7S62lcj^L*dmTyWU#MYQkU?HMi^Y6L}!{9@;nrs=#`kke^ z0lcNTwzh2rR90T-m7pv;evkXHBk5whtQ=W2;p0#1XW1M5E5k8AsB*BeHYv6ze17qw z(WI3CEB*Gs>KK`Rd*!p8mc*&!3_N@SUWABbevlB8cyt(P!e6-5Vv>%Xl>u~5FexhJ zniYo3u(C%J5-j2lNr38G>5g};h{xI&2Y{j%4!~7J1r!=Fm?em8{6;)Ks7gO|pXWs! zExXUPm&1aHI5VeWdD`g~G*!<)XaZH#*&j^$Wl{);Kw(;OXw`rl3zXWStW$@5x0St& z@%P{fw1oL?iW06i0y^{R?Q$N<4+xijes$X2F2e5=qqSL7>Hfl|(*V5mjU$_4@uAgD zE6{{%opdy6KFAC>gNwS?#MpE`LBY}_2v1ALfMcrui@Pak8iMBaH2lR)d0IYv5>#F- z9l*FL$NPr(N-{7yOtQMXED7^p%M;0G)hVvOVfdOhVLrU9>z8#Z{f;Ihe$sQ9fNM{nC8yd@Ilyr$Rh?J18HEG_u?*TjLQ5fB z{~+c*j7Ry1jurN)Mv0$crA_5LG&y=>4(mlGBq^e$N%JME(LYceow61EreV(7D|aVl z5l2gVMl$c=kJJpG+iz4DXN7q9#p;*HHk+*|(y%f~VjCYE4mdJ;A5!r8+IemZwg zi6gpg$y*-Dc6aYZYL~D(t!(8xnfdpJkMqZ>mTuRfB$#5fe@a>2!Ye&jS0R4-xrTCc zqQEKsrp=90>WY4PdK(+vWOz`yF00w)is025@qIV!`CCLOipQ}+g8P?-2r-HFvTN=Q zn)Pn(NJV!ZE$n+CUh?St>Ztf^SY^6Eos=kO@Al2# zI;!6e0ecJ9p2XZf#mxmGh^cUqHL2}D0PdEcmy@EeF&;nF z5}0;wZP|}+ai-q$7vq~D#n8{Ryb9bj#(rOQ@@a{oL!_E}?;FNz2L5QHX~y;x2zhzw z(EeymO!(?RCGtm{Zm*uj>d4o{(SqBHQlTH22XDjiC(24JZO#l}>X_u~kLfo(HT-!6 zl(n7?B0Y)uZF4)uB+teJqTr&FSivY4P<|tLhq3-*if0J$&ctI6@XPSFwr_Ha~&Fe5lTrJmDCB(OM6+&qEE#|r``FY)>%+_h{ zKA&Tnhq9Lt3{u1z^5jSg45%Fr2Y^EG?h5F7NANmge`Lkc6?DM!_qLin`*rO9CWdO z0&cKSP`T>FtMx!%7=(hAcvuh$)@N+E4(a6OEkpZ(T57*gK>XQA=*NL(VT9^n^w2?G zADXPo)6uIGv1$I)vt{s=uf-K@fewe)S+-HSNzbl@Mj=GwgWez%^#2OMN3j_9=+dQx z7Zh;l>`*fnrSeYE@DVM3jF-?9g~`FM=nwDL0pU)y=9hC}izpez53C|=- z$B6s7v|fet64-$ai|c)@n)|E#RxcF&xJ(MSUIE}FF2Thj766-I0JjyK(yj3 zu$@+6gG`>YH^h?XT3^>8`&`Ji@HSfQTZjPOg0)W%n+HXVeFF<^r~q>>H%R~im`HV+ zlB50G?=FV$i90M$7(vlBYgm?jJ{MNoTQ?&H%NU*s)J8OmJ9nwvUS=Mt7Dd6nTmfRK zwF+@N6e<|9!J}>MhzVf?B=+J^T(b}bF;t&~&fc1{WVk6Y?|}olHq3=d}=^Yh=0m|khKzp85z2ryCcZ(@tUiIP)3^#61XW?!Z0d%zr(lkDxo zKOJXss*MIMqEc%;9UwPaA~$ViIcJk1RestPx`Z_FA)K&4Q=0(ii>BdR??RJ{;0GLp zJ%%(od5C#$D=b3xVWbqb)Pl7L^OXYJ`II0A#kS*`-m=z)E!v1rg`s#25qr#K&f!QY zrZA&J7Fk4$%FNbB^UFr*#kO zy>wnK^MAPvS4Y;diYea;_2`pY48y(XW?~ZD7Cn^4E4zpoCxNcW`l17s@74i9Ei{zp9mAYLT|0<@imaCTRU0{lk;L-?edzlr$M( zEak*~`>`wgYzW!Ib44n+}Sw2XDTd2=E_7is3i7kx%axEeBPN}d7R(ReYkpRoDM#| z4&IN7V!FHAx;WU$Tubw6Ykzc!RlC{Bm}$Dd*uC1G_|kg2vA@2|Lg(Opw{q^omTs+?>Qk}<`MxjQb@@{u)RHFm*Ze2%?2MPxUFEof zywI0VY1x;D>y^RZDh&uLz4Zv%32Y;Sqa3p3_4Bd6&$qU&sVu}jU)0V#cs(AT>>c;I z@_c^h_~l-Z--DME$)Np4E$?jbgQ~&LX!HSqW ztV0#HP+Q`zocV21)UyQUq60muEbMzcfJfH*bT zGm?#}Dtk-7Vhs(hlDex^h(gNl5~2&0y2K-W?7;tZ$K)5+^Yz9gbHeKdVpqo<|m2FT=qjB~ERXWEmS5rrEAO zPg^{&l^~cCX4tNjL{=rBv)vcRDyj#g;kZS#vU2BRiv}Yx*^1*|~Wj zxuk{$UBGb}PT7NN`8K$Q3HxL2veb_xDcTy%R%IF5;*gDGZ6weF$7lECXwkG-Nn__s zB}FN>E;8ntGB(Krrr1dnwly)UJ?=NY!Fww2VceNC)yp1_(rIt^MkOYQXNdt>r5E=HkGF!{!0FD_YOTTtu9WH&BB zVNP)I#$-P(UExYl3e8ZMATEr5ua1Hw=5>h4E7oKmMM{zcsgV4UDV1x_+%*l~g~KUgm|z)b(H|l~`tk2kX^f z50y&hhzINS;8!Y{%rcLftHC}hoy-G|nro?8Fo-iCyD(w&0OVU%@MKwGYV_zK@}9F~ zPM{|Qx`S5JwcB>T!)?|Laov!rOz8;MS7PVdC?+;QNDy60#rx)*!>~xYmWrRvIhmmk z`PAO_TBb8!kXB+ODsWl>Kf;RX%qoDbfc3C^I`s<8R=`GBIh{+zLMxe+hw^nOaa+&0 z{*Pd$V#zg~%UO{hJ4~k#zyQdlL*~?EbJ_K=(?cQ4;9_;x$UFA^llgl4H>JgV`Jz6#*YJ67lL5nUG7-mjQ4 z8fCiGF1>x2%QZ!hWf_+X37?0?Ky$z3_!pOCwYxq7n0f4gKUJR{2mcQ`F%{Z zXm|jI_PXQ&4wkmbUEap<5gD;Taf*or%ZxwkSP>`+P{p$|8zKyTOW<15^WX*WvdBO| zW(dQe&Ilh|2sUstxDf;(4|BNTnN?XGZ(`O29FT(<->{+cz-JNS&3IZNjkhHZK@z6n(0A{10Ly+^diAD9j*cIlj5XBjFp1f6JTJI-c5 z*>wK~Z={}<3_`<}&I_Mi2sSV?*b!JD3p2W5LFb51GDIzGpQeF~q8Zc(9uSdP$Izwo zz&EBnWoumfd`bg6jD>@)H!Fo&V)iY0*_1|?Z(NhK0aOCOFi=n+`Sz+m3aYoAmhLRj zlf%=rxUwW_ZEqL*XGvwEV6GL)40(~bVrmwWh@PK2Gm8i#H({cmU7<=4Zd5buECWRj{^QVye zv6$H(#Dyvp2qxc}9K{7HBnoQXnjFS`R%j4hyfq;X!KB_T_S(zKHyhAIsi9lpB1x&C zS*b+twjfkMC^Q9dGoW|Vyt|x{A6gDN(4yy@yfC`O_WYFjWJJ~y`qU&hmT?+E=~|bx zNB0EHJZgBxmfKNc3qD=Jy0@_`&pe0V>OWX%`nZF8A)M~jds=i21gB;zqt0#UjiL?7 z=mO=$o?AuH9D0NR2*oU8sNPxTU#;E;4P?Nvg4sLprzsOnVB9StEs%iB&ovtuN~%-! zkyOqv_LEM~QWGK`eg~1IEL-}~g}g#)WS@;q-@0tK!7qtp&RR_LPODcXN<%MOzjUEa z@nISnPtf8nZ!6A)M4g_u)5&)id>Y0KMb;>6_PSq8(HwFF2l$$K+VE^xlOg)mL^K9h^8v(|q7Swl$U5POO2X({kdXP4;ilQ_c$Sm84{cltfI73#Pnx{! z%!0NER2G@}e$p&eW{pvy4Bs{$7U(st%Xg=rn5@c;GKIY`E^E!()K^8aCI3|yf1>?v zVK{7I&jOaS;r~`@$QWi2Q=JsoeBMewU+nwHN?+5@D+xsm+E^?WQIfSybFn1J?~lL< z#1#YfWgEf2lsN|>Lf$IPSj<}`53ZS)*4p0W?Z*9oD{IWyu9+Nfp`9>EzT=&X%;tefn53raLqypLt9D57Tru>!AVHu`{+}+@VH!8$6CRcHdv&MVEd0!sz|2M#!sh z4$9fR^THPwj1AK4w_K|jnstu&YJt^4{+S0d_F!aFXobm3rqo3!(9|u;vOp9x3&^W~ z3G;Z}XcdK!Drji;eXSPX@8WHjrwMzD)Q@r>1aiJ{spcPF`dUD%0EI7U<^VO&dpiZE zImPViscIK=wrVikOCJk^GV*n~RGn2cqNvvtFOg^sQ@SuH-+rEbRe;#H2R02=03%Bb z1ZNgAl<3;rQ52ZxtRT5NmP=N}z4Uyn8!C$OF;kNu9RD&@AC; z-c{NJxVG754Y_8^qL#tg@mH+)C3Y#$O)MxrutMf`}lKeK#w;tPS{Si$Xq1P(@}>5SGLUeO#k zVnwBP)^c?GB}5yG>a$9O)*xE-jmg-{1YXP_V47(Y#$2c>7PFS`rAR51 ziD%7YpHCBwluBcjEE!CZ4{#qtqP$4IqqsU%r5xh*VP zj0^yDs2!GjVJWt+?NO=yDmelU^?$0k@^p~KFwbGkB!jcTn1PS50zH!2RQK&c02fI| zEc(UlL^!*ZTCnBtOotp|>R9h`FGHy*kZeB*&*U1p6%DG-??Q0xcu%Y zb3bgSnlT5`RrXneSl!s!XZO`KL;>;$7?6}X*RYI-;6JVh-Y~JV%ts3*&fq-BQov3) zouQ}}!ucvI@NBC4_eXl=MJ2OUo+!_}OV zSl6(-RRd4W6fkq`wdX>~;z!K>2_1j5UH_T@L@l@({0I_I zfO$&i5k=Y#D&(zN1`=2TKyy@3Vv4p66XD%iN^~csJRrP{V;GOEZa@?Lan5eRN$r4Wv^(z_w2oK3L+ z8ghw}A6$CT7-li1lZP0?NC_y}MP|ljnbWjd5w{~i&3i~^_HAs!%vTVSw2^! zPM1A-rNbH=?F**Vd0Mfr<}MOi8cV!1gpjGd*Ggm|fM(1NX9}%MW2)&`%zw@AD>H%! zj&XEFbG!)5^nW=PkbpIoT-LsFexbpc#aFcuX2_B6+^w)g_W_`VE3OZfQe|(oW2%N} zaRi4OaVW|Dvi2C~mN__@=xP*Khf#b(06V!xuFa0&8ZNVR^Hx$g1H<%U8O12-dDzMs zQCm>T`&zz%xcM(BfE?k*vC5#z8e_+?vKf1^_#n7NtSCMn3Ro$cLqwYY!a6sRMbT5J zlo%Aq+qaZC)WXsBR;45WwB;~<*VdFG+Ujx687Idsq4z~bOrl;fa}^gG>N{J6@OHBs zk1q_o8Rzx1@p=8Uy8Q1^0im9G!?5gQhAK|muA8>e#bwIxtn&bv<-1bHl&GBLz_EfD z;l$b32K75IaY9U)&i>?t^%2qulA2rn-ikDR9NsSZ z>%WPY9>(nwEnk7T*%!C)6x)&;7($L^f2A+tYNIt?M2bgPY6d62oH)8e!8J74f5k_} zaw5Oy?Zs&#^$mTa1e%jw-)wh486WyA`d8;=-;u`a%pho$is6C$Q0W-~*ozS%Qu()x z>gie(ZJS`>Teet{t|^{o%$--kyy*yX>L`UVNmqdYQZj=w)#>yfIy6d965@_1iE#JE zgJ3IW-CJz2NKi5!{ViX=6=|yBS#y)Jkfx1D`it+)YfQZ6-p%@rplp9RvSux)1WDa3 zTslP>=(*i;t$a{x)L77pr9Y=r`-s$gub!}T_b~{rO)VLkSl#l{iKH^1BR(B4JA{89OLy=&R%g+$U&X#a&!g zP?^eyC4syNvP5-b30q}mlB;7{F}fYtG-LsYih+NkivQkvuI>dZy3@T_Pn{R*`62|N zrJyO${2K3*l{#p+pXJz0tFD(f(vJ}dcZ*d-itFwFxKNPW>jW7URb1yN{&Lp6mhnFZ z`S))7cP4y2Xes(NCAyB1yyEqs6&l37>@q?dhwL_65y)g3XD6*R>gQFewq5ETvX#S_ zT+fw7o2F#RgXEU^PoC|+W!*Pzv&fpFu^?$tCDTe+g`Cdkr0?1>LKi>akT?4xQS!@ThPn$x9$>-;}BTFre^gb{M!L;XZl;~yAMjTsGC zC`WZClIYAlM_}8jsiSEA(oj}MYT;QXs_y$qi817+c+KeYT59cDF}aq4spZ$Jf+Q!! zcDKl|2}d(q0lSf1SGJ5N4Sf;tETOanNTV4zAOumEx)*E9m%Ack`$`SyIOpI(n+*yyPwG1I7A*c~gs*es!}JF!5UsKRM-Q!t?jXW=0`DUz0Q?k!6V zWmq!D`1os^>hc17@-qW{9iNZ`pm|!A=68U@gNXbVmj-c;tO!wJ|39Vh z(hq3Lm?4ZnMsOe&xb?24Ki#gc?2ZPzMhU$e?bJLU;@v}Z28UztA8aIU!}x>I-lI7o zECMOZ679kx$XhcYTa;#@g_YLLmZ^RSEs~+jEcXL928@bD#c(K%l!c~EU@cp=M13c& zo2@z|>5#o_m3;jAE%gLg{)?xug`@tdRRJaTMPlOMRNB=>D_Yge)s@~EO!F{<3{2PN zyydO@tU;+2^BgqLhIy`j0lXHO(pw+XwPY(?=|iEm#GR$248xnp9fyH*OWXw7m?~*8 zkhjn+&!;p{_XRa_bK+8IJul1^MFL{3ZJ+Qe2vTo7=RT0yA8B6JgQ^$grhF~o_5Q(A zzTpBB64Y0A}2q4+} zgXU;sYq-;`xjDxiy#ZOvQ5O;nK_qSst#YBnq$q&n$GObUoIV!N#@BOa+i;%$V6;-Y zKQPaorTFmvp{>M>s8^rwwDzmswug^2hv{2_cqzZ23w0lWYPm|>y}DwtxT0(+k8VV1 zeHloS2~-e3NRM0i;c3WU_~bR34e*lP%7VQxfr3_-JxlqvZ+}w? z4ACzu;K=>bo~8UAj+wK5ooQr|S*8(BxOE7PHFmM|ABKC3&7dxbKnVtD%Y56^t~5Sy zT@taBItOEn=z|L#mzmwT_wk2PAZRC2gK9%MuU!|2!cOsCVj?XIN@Uol46NKoO9R2B zz|29#$dZF2PKSBnmlrmxE!x5kZGRWTsUwl!ohZ0psD5NrDqS2enM)A{sX^3ULYrTp zYik@Dwp*VV<{=TC@Uj(fXw`-~>?Qv_X1~AEvSepAcW9+ezvTRvLG56*bg#k^v0>K! zvp?QWo;|s7;X*24p58;ocxforoG+m1?fK73cr6ncUJT?d*V{Ietx39L45pbrJz>G*As@lfQJ_<$rHkGH8bnO|L5}r!^9nN?WQfiyRKsyp<+i zT5qrHgjE$C$oj7Lf1+_}9IML+e-?B1SJ0`kqHKQKkPNWe(DBFB?mQJfT5(;RkTwuC zjDs(9HJ2=vG|HOV(SWJf5FxD;$C*mA-;_TZt4!S>HDdF$FdU2-XH^Q+)9JlPDg4>f zxL{@a1^a60A|YSDbTwkX(tqf3Nyhoj)XQu>xP&1qHuzX*;9jCTQ{h-ew*J0*izDmh zH4}`M3#Y8|X}1sLwAW?-VqUcIK$2!y24W>-3GJn6Hd0>wDWgXON|vHqs635e_Jy+8 zP)SwvST&1E!zQ5mIq+pm`7EWUQ;=-~v=cDA8QAu+o7-4I4A=urO3%Y{<5z?}IH<Be1~87+n(}Emq82ku)na>g8}XHKu6R=IlE+y3F7Pn^V`f=>KK7_ z8a|-*N?Ofgc3*6X4hOVFl5$AiH_Kn}Yg;F!n-GUw2p&Lse|t?TpeUH zkB%ZwxeB#bde?9IuQk>xJBW|48=nQf2*pGN9v|5uuSL%HFSmlu%G=jgh>t7nqF7g% z8j063zg-K?$#3=+datZJKef>=0vKRmpx16*-s*L9`e<$H z`0^Z3kEVfLE;ov|&~7`#86Ol{77BQ&oOWKql{{5F)nO?FW%b+wDtDWS!u5)sHOa(E zLB37OCh3B|z4U`lWl|4cBZYm)qJ!l29LnU08T_4Li6Gl=N z8tf8)4m0+^ghd?CRqb|MW|TvSiB3|u37m4Q}tjSR1iY|ME0+McIH zVW~7gXJ{UplZAVWY5G18%U(K1)LsiedBFkq4ReGU@BLV>5WiYwr_W&td5Jd;G7!91 zL>+@m-9ZgX|NaEMYEUBD)ZD&fY z^fcjY?kMRbRJHO%7U}80axdvcm5=)|Pzt?HIIkc+)l28?2GdRkbioWvDd~#=Rr-*m zc1j*ziK2;|$ta&8Z~q>TuPb0Xv~`U8?H zndc(-_$U^*MhEh}UmJg**zPf}U_!4YTF`U|j|n^GM7G<)7Ox?tPFPaXZU%kBTNP`V zxBFpr5a#b=TvPydVxbzm0=;UzpkEJPg8JSp6IbsvmOYQ$&nqh#&q`^MxJs1+jn>9# zZ~?P_l(m^1tVlGe-pADf%r3&WnX#T26}=x!Z zC{BWJ;V=*PU4Q69Q64cj&RIugAoItuE}DhnsK(WmLYF}>BDca|n2Vk7=};4IKDB}U z)V<%m5N*FWF>s0 zpJj7Cf*=4%Pkv1TeB5K6%j_;rvqT4LrG_w1*l9DbQ-|^xnaOx2>Um;?cT=}@kLivi z&kQx!>p{&^nY(?@c|hK)e7yuBqpu-{-iK{U z#KX|G8)PSC4P~~b%#ZyEQSB*yx#J(qIsC)3OVk>myyvF@>_GMt=R)YJ;Dzo`JMSxk zW!b_8;}$`rk2ORtFlwE%tL$z&O~_1T~f@R z60b|o1JsC*9%G+DPm%upd7*b$5mV|Q7Lf+McMc+wUo7(8$idV^#mT|K*8CTlcxVpW zE^}k7AWwKR*JbibO^TQswnoz|VUbCfNJiya!@g0%hp0{qP0M+_ZzfNGo)FlZ+KIk? z%;LX)*tp@oUFCNTR^f|cTr+qZSJ1|{LcC;m{@zO6+bfK6<>T7wF|mRTTa*{4-o?k$ zqbRNUbSkID!|loL+lPyBr==AE_I}Unr;C}o9uENl;%oD}+XtH^0RgW2`=e}&vHt$u z+1_4*>5ZoeiMZBjnNJz-G>C<~LMWLI*E^CVAb*}6D@+3B2(fCiG`D5H>>=LA{3)IjIAOawp0dyYSBOuCV_^ZwUlQ`UJ$vSGR$3Wk3`TtE`wRv z39hzT)91k73l)gJ$z8}=%mJ4fDuRj{vOi`XkLKEodEp9n?!F7rkvHu;HmRpXL9n7u zFA;CJ2Hjv-e;1DSUA<=HAjzi7k>P+f{Cq##!KjwqJQRylYM!Rl(8$hI%^r2Q3}t>| zs*^-)xG9$BORkcC7)#~b7)<(!udDWSTZnKJcxV`O-2Bvf{z+mwuHAPOL3r(wkv`o>*SqbU{h;Lbym6iB4+ZL@V%0Z@S z1XQb{RuPHjN348rx}vZN1RPx^7#0@3V*6&kyfVyWL z8S=3CL);gsW~&Q2v13|}tc*Jf|uhoR<<%>9$AQQO~K7Cy)1gXlxkAwWUS4o1|=UL}_ z{3U_Hth+BSIL4MLc($%#dyWh@fOUbmPyg24kWH*fc`y$=s!_0?ey)<65-o5z=H$Z< zE`%&y#g7?;aQsxjYzzulVBiuJbS@8m&l7Vg7arx%wzcGhku)}2fP5}JwA;^|cOMrg zns7Y*T3E7*R+^~+)Nk0yNYswq!aoY|(Jby$*U{pLeJx>sCx-XgmY6#_j)*vg=4Rrk zb_hUxpi*}6DGhyfns@yTy@}y_>1h8~+ZkOa>ASBl910Nw+gT*VjXL|ipKbGm#C(*L zzuCuUVAy?+e}dO}0DXew?>t1)3vi7AF_Z%6A!roPS8hz~j1?X1>>Zhm?CoC+4d{bV z|MzVh5I?8IO)7w%aqe4-xe_w*DwL-YEpmvU#QEVHD$Q`P$eq;pwf@Z-YW@9wGrMJK zm0aAFi|bk;Q%9PObM4AaSzrKTkfe=QuIHo7GrqRO^6C1p<^2C^=RBjD%C_cPpLX1oduQZvMpl<$1JmzzSF)~N}h!g2YDvRhqD(wUGHkxptI=LfM3OM zhM5^Ee85~&`f$QCu)q~{j13NF>y0csqi3hI7G^rwEVO-W)ytsXbuJjiWhCPke5y`K_>f)nQ#$n~9*m8_&Z;bfieDj#Z_K4k%!K0O9mr{vpC9)8o{+vDP|NT_EGY3W@8?kXs4%RoimN z$4qMvn)?fNS~yk?hk0xLYSiAO?2`ot1n(q#aW8g#rw|{NF1+lqQ~MlA_>OlMOkMmC zZ^?b5ezQhklODH-#%GeKrKRQz3jHF}7bq}_luginpIzY<%C9%(;%iYsrSJC4n#@#K zb=|s+fg_)WE1Em68;m$%46kXk_k5(=Bt2`W`a&rU>Vkn+Tr7aS6-V3sSf)b*tL9b- z$2Bw?vZ3g#BrIzsA{~lT{f6&g*)7mNI9GKh=)OQ!b}3*>%aa z!0Bl@mP?@k4;l`6**U;mMv=9cPPb!UZweDHkQ8oruE^e_p1bqpW3>Z>g)6uTtm|6$ z(0gPtnN6`7rXXk3!`gZ!m;3aM`Tz|cJ)uiI8o3;{oe&nUNA4{q$dy*Bd8e8b`@&uZ z5qNO91bMtgCoNr)DR}PpLZ#Sw|A0<^J+N$-D^uc+k0KYW)KWCiFZYOe}a!Cxw01xKDEEhOUrX& zz?CfzE?S}#ZAy)svEF|`&)3tMh6PcuKOpP>K*q=xRq`7;4R&3AVyW1aewxAV%*X&J1)bke;G8+>)VDy(Ftt|rx;dj~xE_A3uw>8-lZskEXyYj6ECa4w z&XBBjKG)JSUx!#<2RkDsSrp1m8^q(KmKeudjGH-L_Y_hp^8WU$D5SJ+m~SQi$>6}HK09<#7hu^V;kIIaS(JYIv?tKKW1mc-!)mFa_5-Nje<$4l{BN~EuR zE$-(hxGm+p0aYz#pN@VT9Oo4(PEK$ENEyRn7w}7uGRc#+K-{JwxWIV##t9|cbkS9> zW-1%unD&cJ7IpV?LzERAV_9vM&6mg;{^WF(S{igJfXvHLMoiIjhjt*lk7amsd+^66 z2v$}mi9k&hYBUYfjz{yexPoL}(l+#S7&{edCHlDUEJt;(H479N8cv-yj4%)_anuuY zzdNTz)yt4m?k)j`#01xdPO7;5oY+OHGYRgc8cGampHlW&@~3wz=hJ5QpYAqS$shB( z$I3E${<(S{=^fDsOPBd=^Es<`(9v=y&yA`Aqqtzs$%h74FZp=Jk4)!oU^W0oFy;DNj`>iuYWpvGsCHe%KW`aX+A#Z|%0Sk4Cn0)h>LY zTsN&VOy8Z;2aE_&ht%>u`AMd*mstdUH{==nfRVWTfPp$POYp@ES3Y(`3Cn?O4U#(* z*P?_=8C@vvxapp<7oXY2pLjL#wXHe^%`~e*2;|>7!M_jn^4~-K_fY?T7U~TIeUw0i zt&Sxj+%tT=FNa_8b@{$ACq#zNzo;Y!W6T-m)`{b2oetE4i`QXpDrO^hk2S?j+Zrra zRfy0TR*qIHUaq!Dn|$+pb|$drxe$!UlH*!9Qa4W?#1tXWo1GLr?lOmb`ZLaKMs+AD z^X_dc2^`DR$04qJ=WJ$`7paA#m{$1432f9fZz)C5SmsF^mq|#pMp_wG zX*oekS9D`J=k!%LY{*az0gu{YMwe#Vzp{Lztys+%wg#aVk@R*LvE#8&6?=faH@1bW zS*s!mzV5+2^t#baFpw|7oU*C*ceXz+@2u2VXN7>~1VnBI{iNXEoF8Sv#@p5FfO}vD z)5*}s>*t;oc~6(|v?IN5BrJ$@M!aF0a!Zjgho1s0=?_wbGStzU-d|?=%k>C_Z!_b= zfWr#IUkvxJPYLJDuk?n2hKEI0zcw5p?1=tef)&UCN^cTLrw9$t03lAGF;EtgXk1Ty zU~>#rv7OC~ilK2C@&BqWT4{~ndigit->S_NUMBER->digit|"'"->S_NUMBER \ \->"#"->S_SHARP \->"@"->S_EMAIL - \->"e"|"E"->S_DECIMAL + \->"e"->S_DECIMAL \->"E"->S_DECX->digit->S_DECX - \ \->alphaU->S_HEX + \ \->alphaU|"E"->S_HEX \ \->"h"->T_HEX \ \->delimit11->T_FLOAT \->alphaU->S_HEX diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 6ce5174733..66fb9ab032 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -24,6 +24,7 @@ Red/System [ S_NUMBER S_DOTNUM S_DECIMAL + S_DECX S_DEC_SPECIAL S_TUPLE S_DATE @@ -34,6 +35,7 @@ Red/System [ S_MONEY_1ST S_MONEY S_MONEY_DEC + S_HEX S_LESSER S_TAG S_TAG_STR @@ -82,7 +84,8 @@ Red/System [ T_TAG T_URL T_EMAIL - T_PATH + T_PATH + T_HEX ] #enum date-states! [ S_DT_START S_DT_D @@ -173,59 +176,66 @@ Red/System [ 2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E 2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ -00001313353637383A34020C2929292929290B34202906340134271D26263429 -2934330100010101010101010101010101010101010101010101010101010101 -0101010134330202020202020202020239020202020202020202020202020202 -0202020203020234340202020202020202020202020202020202020202020202 -02020202020202020202343304040404040404043A3B04040404040404040404 -0404040404040404040405040434340404040404040404040404040404040404 -0404040404040404040404040404040434333C3C07073C3C3C3C3C3C0A07073C -070707070707070707073C3C07070707070707343C3D3D07073D3D3D3D3D3D34 -07073D070707070707070708073D3D07070707070707343D0707090934343434 -3434343434343434340934343434343434343434343434343434340707070734 -34343434343434343434343407343434343434343434343434343434343D0A0A -0A0A0A0A0A0A0A0A3D0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A34 -343E3E0B0B3E3E3E3E3E3E3E0B0B0B0B0B0B0B0B0B0B0B0B0B3E3E0B0B0B0B0B -0B0B343E43431212113441340D340F1212341212121212123434123443431212 -121212121234430D0D0D0D34343434343F343434340D0D0D0D3434343434340E -343434343434340D34340E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E34330F0F0F0F0F0F0F0F0F0F400F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F34400F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F343411111111114211111111111111 -1111111111111111111111111111111111111111343443431212434343434343 -4312121212121212121212121212434312121212121212344345451313454545 -454545450C13191B181534183445344414452C14343418343434344546461515 -464646464646461615341B341534463446344434463434343434343434344646 -4615154646464646464634344634341534463446344434343417341515343434 -3446464646474747474747474716474716161616474747164747474716471616 -4716163447484817174848484848484834344834343434483448343434343417 -3434343434343448494918184949494949494918181818181818181849184918 -494918491818493418344934341A1A3434343434343434343434343434343434 -34343434343434343434343434344B4B1A1A4B4B4B4B4B4B4B34341A34343434 -4B344B3434344B341A343434343434344B34341C1C3434343434343434343434 -34343434343434343434343434343434343434344A4A1C1C4A4A4A4A4A4A4A34 -344A34341C344A344A3434344A341C343434343434344A34341E1E3434343434 -34343434343434343434343434343434343434343434343434344C4C1E1E4C4C -4C4C4C4C4C4C1E4C343434344C344C3434344C341F34343434343434334C4C1F -1F4C4C4C4C4C4C4C4C1F4C343434344C344C3434344C34343434343434343433 -3C3C21213C3C3C3C3C3C3C21213C212121212121343C21213C3C212121212121 -21343C2121212121212121212122212124212121212121214D21212121212121 -2121212134342222222222222222222221222222222222222222222222222222 -2222222223222234342222222222222222222222222222222222222222222222 -2222222222222222222234342424242424242424242424242421242424242424 -2424242424242424242424242434342424242424242424242424242424242424 -2424242424242424242424242424242434343C3C13133C3C3C3C3C3C3C343429 -29292929293C342934293C2927292929342929343C3C3C28283C3C3C3C3C3C3C -34292A29292829503C292934343C2C29342828292929343C4646282846464646 -4646463434461B34283446344634443434343434282834343434463C3C29293C -3C3C3C3C3C3C34292A29292929503C292934343C2C291E2929292929343C3C3C -2B2B3C3C3C3C3C3C3C2B2B2B2B2B2B2B2B3C342B2B2B3C2B2B2B2B2B2B2B2B34 -3C4E4E2B2B4E4E4E4E4E4E4E2B342B2B2B2B2B2B4E4E342B4E4E2B2B342B2B34 -2B2B344E4F4F2C2C4F4F4F4F4F4F4F3434342C2C2C2C4F4F4F342C344F342C34 -2C2C342C2C344F34342E2E34343738343402302F2F2F2F2F2F3434202F343434 -2C2F343131342F2F343445452E2E454545454545453413451B34153445344534 -4414452C1434343434343434453C3C2F2F3C3C3C3C3C3C3C342F3C2F2F2F2F3C -3C2F2F34343C2C2F342F2F2F2F2F343C434312121134343434340F1212341212 -121212123434123443431212121212121234433C3C2E2E3C3C3C3C3C3C3C3434 -2929292929293C342934293C2929292929342929343C +000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B06360136291E28 +28362B2B36350100010101010101010101010101010101010101010101010101 +010101010101010101013635020202020202020202023B020202020202020202 +0202020202020202020202020203020236360202020202020202020202020202 +0202020202020202020202020202020202020202020236350404040404040404 +3C3D040404040404040404040404040404040404040404040405040436360404 +0404040404040404040404040404040404040404040404040404040404040404 +040436353E3E07073E3E3E3E3E3E0A07073E070707070707070707070707073E +3E07070707070707363E3F3F07073F3F3F3F3F3F3607073F0707070707070707 +07070708073F3F07070707070707363F07070909363636363636363636363636 +3636360909363636363636363636363636363636363607070707363636363636 +3636363636363636360707363636363636363636363636363636363F0A0A0A0A +0A0A0A0A0A0A3F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +363640400B0B404040404040400B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B40400B +0B0B0B0B0B0B364045451212113643360D360F12123612121212121212121236 +36123645451212121212121236450D0D0D0D363636363641363636360D0D0D0D +0D0D0D3636363636360E363636363636360D36360E0D0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E36350F0F0F0F0F0F +0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F0F3642 +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F36361111111111441111111111111111111111111111111111111111 +1111111111111111111136364545121245454545454545121212121212121212 +12121212121212454512121212121212364547471313474747474747470C131A +1C195315163621193647364614472E1436361936363636474848151548484848 +4848481715361C36361515363648364836463648363636363636363636484848 +1515484848484848483636483636361515363648364836463636361836151536 +3636364848481616484848484848483636483636531521362148364836463636 +3618361515363636364848484849494949494949491749491717171717171749 +494917494949491749171749171736494A4A18184A4A4A4A4A4A4A36364A3636 +36363636364A364A363636363618363636363636364A4B4B19194B4B4B4B4B4B +4B1919191919191919191919194B194B194B4B194B19194B3619364B36361B1B +3636363636363636363636363636363636363636363636363636363636363636 +36364D4D1B1B4D4D4D4D4D4D4D36361B363636363636364D364D3636364D361B +363636363636364D36361D1D3636363636363636363636363636363636363636 +36363636363636363636363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D +1D36364C364C3636364C361D363636363636364C36361F1F3636363636363636 +36363636363636363636363636363636363636363636363636364E4E1F1F4E4E +4E4E4E4E4E4E1F4E363636363636364E364E3636364E36203636363636363635 +4E4E20204E4E4E4E4E4E4E4E204E363636363636364E364E3636364E36363636 +3636363636353E3E21213E3E3E3E3E3E3E362B2C2B2B532B212B21523E2B2B36 +363E2E2B1F2B2B2B2B2B363E3E3E23233E3E3E3E3E3E3E23233E232323232323 +232323363E23233E3E23232323232323363E2323232323232323232324232326 +232323232323232323234F232323232323232323232336362424242424242424 +2424232424242424242424242424242424242424242424242425242436362424 +2424242424242424242424242424242424242424242424242424242424242424 +2424363626262626262626262626262626232626262626262626262626262626 +2626262626262626363626262626262626262626262626262626262626262626 +262626262626262626262626262636363E3E13133E3E3E3E3E3E3E36362B2B2B +2B2B2B2B2B2B3E362B362B3E2B292B2B2B362B2B363E3E3E2A2A3E3E3E3E3E3E +3E362B2C2B2B2B2A2A2B2B523E2B2B36363E2E2B362A2A2B2B2B363E48482A2A +484848484848483636481C36362A2A3636483648364636363636362A2A363636 +36483E3E2B2B3E3E3E3E3E3E3E362B2C2B2B2B2B2B2B2B523E2B2B36363E2E2B +1F2B2B2B2B2B363E3E3E2D2D3E3E3E3E3E3E3E2D2D2D2D2D2D2D2D2D2D2D3E36 +2D2D2D3E2D2D2D2D2D2D2D2D363E50502D2D505050505050502D362D2D2D2D2D +2D2D2D2D5050362D50502D2D362D2D362D2D365051512E2E5151515151515136 +36362E2E2E2E2E2E2E515151362E3651362E362E2E362E2E3651363630303636 +393A36360232313131313131313131363622313636362E313633333631313636 +47473030474747474747473613471C363615153636473647364614472E143636 +3636363636473E3E31313E3E3E3E3E3E3E36313E313131313131313E3E313136 +363E2E31363131313131363E454512121136363636360F121236121212121212 +1212123636123645451212121212121236453E3E30303E3E3E3E3E3E3E36362B +2B2B2B2B2B2B2B2B3E362B362B3E2B2B2B2B2B362B2B363E } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4055450df6..9d3b7bc2fa 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -56,25 +56,28 @@ lexer: context [ C_COLON ;-- 13 C_X ;-- 14 C_T ;-- 15 - C_EXP ;-- 16 - C_ALPHAX ;-- 17 - C_SLASH ;-- 18 - C_BSLASH ;-- 19 - C_LESSER ;-- 20 - C_GREATER ;-- 21 - C_PERCENT ;-- 22 - C_COMMA ;-- 23 - C_SEMICOL ;-- 24 - C_AT ;-- 25 - C_DOT ;-- 26 - C_MONEY ;-- 27 - C_PLUS ;-- 28 - C_MINUS ;-- 29 - C_CARET ;-- 30 - C_BIN ;-- 31 - C_WORD ;-- 32 - C_ILLEGAL ;-- 33 - C_EOF ;-- 34 + C_H ;-- 16 + C_E_LOW ;-- 17 + C_E_UP ;-- 18 + C_ALPHAL ;-- 19 + C_ALPHAU ;-- 20 + C_SLASH ;-- 21 + C_BSLASH ;-- 22 + C_LESSER ;-- 23 + C_GREATER ;-- 24 + C_PERCENT ;-- 25 + C_COMMA ;-- 26 + C_SEMICOL ;-- 27 + C_AT ;-- 28 + C_DOT ;-- 29 + C_MONEY ;-- 30 + C_PLUS ;-- 31 + C_MINUS ;-- 32 + C_CARET ;-- 33 + C_BIN ;-- 34 + C_WORD ;-- 35 + C_ILLEGAL ;-- 36 + C_EOF ;-- 37 ] #enum date-char-classes! [ @@ -110,17 +113,19 @@ lexer: context [ ] line-table: #{ - 000100000000000000000000000000000000000000000000000000000000000000 + 0001000000000000000000000000000000000000000000000000000000000000 + 000000000000 } skip-table: #{ 0101000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000 + 0000000000000000000000000000000000000000 } path-ending: #{ - 010100000101010101000100000100000000000000010001000000000000000001 + 0101000001010101010001000001000000000000000000010000000100000000 + 000000000101 } bin16-classes: #{ @@ -240,9 +245,9 @@ lexer: context [ C_GREATER ;-- 3E > C_WORD ;-- 3F ? C_AT ;-- 40 @ - C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 41-44 A-D - (C_EXP or C_FLAG_EXP) ;-- 45 E - C_ALPHAX ;-- 46 F + C_ALPHAU C_ALPHAU C_ALPHAU C_ALPHAU ;-- 41-44 A-D + (C_E_UP or C_FLAG_EXP) ;-- 45 E + C_ALPHAU ;-- 46 F C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 47-4C G-L C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 4D-52 M-R C_WORD ;-- 53 S @@ -256,10 +261,12 @@ lexer: context [ (C_CARET or C_FLAG_CARET) ;-- 5E ^ C_WORD ;-- 5F _ C_WORD ;-- 60 ` - C_ALPHAX C_ALPHAX C_ALPHAX C_ALPHAX ;-- 61-64 a-d - (C_EXP or C_FLAG_EXP) ;-- 65 e - C_ALPHAX ;-- 66 f - C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 67-6C g-l + C_ALPHAL C_ALPHAL C_ALPHAL C_ALPHAL ;-- 61-64 a-d + (C_E_LOW or C_FLAG_EXP) ;-- 65 e + C_ALPHAL ;-- 66 f + C_WORD ;-- 67 g + C_H ;-- 68 h + C_WORD C_WORD C_WORD C_WORD ;-- 69-6C i-l C_WORD C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 6D-72 m-r C_WORD C_WORD C_WORD C_WORD C_WORD ;-- 73-77 s-w C_X ;-- 78 x @@ -681,7 +688,7 @@ lexer: context [ either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char @@ "e" as 1st! p: s + 1 c: 0 - cb: as byte! 0 + cb: null-byte while [all [p/1 <> #")" p < e]][ index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table cb: hexa-table/index ;-- decode one nibble at a time @@ -835,7 +842,7 @@ lexer: context [ index: as-integer p/1 class: lex-classes/index and FFh ;-- mask the flags switch class [ - C_DIGIT C_ZERO C_ALPHAX C_EXP [0] + C_DIGIT C_ZERO C_ALPHAU C_ALPHAL C_E_UP C_E_LOW [0] default [w?: yes] ;-- early exit if not an hex value ] p: p + 1 @@ -1455,6 +1462,29 @@ lexer: context [ ] ] + scan-hex: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + int [red-integer!] + index [integer!] + i [integer!] + cb [byte!] + ][ + i: 0 + cb: null-byte + while [s < e][ + index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table + cb: hexa-table/index ;-- decode one nibble at a time + assert cb <> #"^(FF)" + i: i << 4 + as-integer cb + s: s + 1 + ] + assert all [s = e s/1 = #"h"] + int: as red-integer! alloc-slot lex + set-type as cell! int TYPE_INTEGER + int/value: i + lex/in-pos: e + 1 ;-- skip h + ] + scanners: [ :scan-eof ;-- T_EOF :scan-error ;-- T_ERROR @@ -1486,6 +1516,7 @@ lexer: context [ :scan-url ;-- T_URL :scan-email ;-- T_EMAIL :scan-path-open ;-- T_PATH + :scan-hex ;-- T_HEX ] scan-tokens: func [ @@ -1533,7 +1564,7 @@ lexer: context [ index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index ] - assert state <= T_PATH + assert state <= T_HEX assert start + offset <= p lex/in-pos: p From 192d8de103a37ec9f469773109517a9319242ac5 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 8 Nov 2019 17:13:22 +0800 Subject: [PATCH 0415/3432] FIX: `livecode` focus issue, for example input `field` --- modules/view/backends/gtk3/gui.reds | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 5afc0b51d0..ec68c241e4 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -822,6 +822,8 @@ change-pane: func [ type [integer!] /local layout [handle!] + win [handle!] + focus [handle!] list [GList!] child [GList!] s [series!] @@ -852,6 +854,8 @@ change-pane: func [ ] unless null? layout [ + win: gtk_widget_get_toplevel parent + focus: gtk_window_get_focus win list: gtk_container_get_children layout child: list while [not null? child][ @@ -885,6 +889,7 @@ change-pane: func [ unless null? list [ g_list_free list ] + gtk_widget_grab_focus focus ] ] @@ -1321,7 +1326,7 @@ init-combo-box: func [ combo [handle!] data [red-block!] caption [c-string!] - drop-list? [logic!] ;to remove if unused + drop-list? [logic!] /local str [red-string!] tail [red-string!] @@ -1338,13 +1343,11 @@ init-combo-box: func [ tail: as red-string! block/rs-tail data size: block/rs-length? data - ;; DEBUG: print ["combo-size: " size lf] ;remove all items gtk_combo_box_text_remove_all combo if str = tail [exit] - while [str < tail][ if TYPE_OF(str) = TYPE_STRING [ len: -1 @@ -1354,17 +1357,6 @@ init-combo-box: func [ str: str + 1 ] ] - - ;len: objc_msgSend [combo sel_getUid "numberOfItems"] - ;if zero? len [objc_msgSend [combo sel_getUid "setStringValue:" NSString("")]] - - ;either drop-list? [ - ; objc_msgSend [combo sel_getUid "setEditable:" false] - ;][ - ; if caption <> 0 [ - ; objc_msgSend [combo sel_getUid "setStringValue:" caption] - ; ] - ;] ] remove-entry: func [ From 3cf8fdbda739a81d6b9b100792c095c84f64e14e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 8 Nov 2019 17:53:42 +0800 Subject: [PATCH 0416/3432] FIX: group-box didn't work --- modules/view/backends/gtk3/font.reds | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index a3475b976e..5c3012993c 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -640,7 +640,11 @@ set-font: func [ ] sym = group-box [ label: gtk_frame_get_label_widget widget - set-label-attrs label font hFont + either null? label [ + apply-css-styles widget css + ][ + set-label-attrs label font hFont + ] ] true [ apply-css-styles widget css From 4aef5378b529e7c194c0e5995100c2d761816b19 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 8 Nov 2019 15:12:13 +0100 Subject: [PATCH 0417/3432] FEAT: minor code refactoring. --- runtime/lexer.reds | 48 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9d3b7bc2fa..489cbfd6df 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1436,6 +1436,29 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip / ] + scan-hex: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + int [red-integer!] + index [integer!] + i [integer!] + cb [byte!] + ][ + i: 0 + cb: null-byte + while [s < e][ + index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table + cb: hexa-table/index ;-- decode one nibble at a time + assert cb <> #"^(FF)" + i: i << 4 + as-integer cb + s: s + 1 + ] + assert all [s = e s/1 = #"h"] + int: as red-integer! alloc-slot lex + set-type as cell! int TYPE_INTEGER + int/value: i + lex/in-pos: e + 1 ;-- skip h + ] + scan-path-item: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local type [integer!] @@ -1461,30 +1484,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip / ] ] - - scan-hex: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - /local - int [red-integer!] - index [integer!] - i [integer!] - cb [byte!] - ][ - i: 0 - cb: null-byte - while [s < e][ - index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table - cb: hexa-table/index ;-- decode one nibble at a time - assert cb <> #"^(FF)" - i: i << 4 + as-integer cb - s: s + 1 - ] - assert all [s = e s/1 = #"h"] - int: as red-integer! alloc-slot lex - set-type as cell! int TYPE_INTEGER - int/value: i - lex/in-pos: e + 1 ;-- skip h - ] - + scanners: [ :scan-eof ;-- T_EOF :scan-error ;-- T_ERROR From 3823eef4666a2245123003864750f7c75a4ee1a1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 8 Nov 2019 18:08:42 +0100 Subject: [PATCH 0418/3432] FEAT: make comments first-class in lexer. Will allow extracting comments from input. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26673 -> 26658 bytes docs/lexer/lexer-states.txt | 3 ++- runtime/lexer-transitions.reds | 5 +++-- runtime/lexer.reds | 11 +++++++++-- utils/generate-lexer-table.red | 1 + 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index a854ffbcac..a6aea6fdb9 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,6 +1,6 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_LINE_CMT;S_LINE_CMT;S_START;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;T_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index a2d985c88db093a410091bebb0d3634171a7674b..d9a76aeca41db96941324812306aba7a31bcda66 100644 GIT binary patch literal 26658 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 S_START->";"->S_LINE_CMT->not(lf)->S_LINE_CMT - \->lf->S_START + \->lf->T_CMT S_START->"["->T_BLK_OP S_START->"]"->T_BLK_CL diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 66fb9ab032..68e5bbd9e5 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -85,7 +85,8 @@ Red/System [ T_URL T_EMAIL T_PATH - T_HEX + T_HEX + T_CMT ] #enum date-states! [ S_DT_START S_DT_D @@ -177,7 +178,7 @@ Red/System [ 2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ 000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B06360136291E28 -28362B2B36350100010101010101010101010101010101010101010101010101 +28362B2B36350154010101010101010101010101010101010101010101010101 010101010101010101013635020202020202020202023B020202020202020202 0202020202020202020202020203020236360202020202020202020202020202 0202020202020202020202020202020202020202020236350404040404040404 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 489cbfd6df..c76d622c9e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -118,9 +118,9 @@ lexer: context [ } skip-table: #{ - 0101000000000000000000000000000000000000000000000000000000000000 + 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000 } path-ending: #{ @@ -1459,6 +1459,12 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip h ] + scan-comment: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + ;TBD: trigger an event + lex/in-pos: e + 1 ;-- skip lf + ] + + scan-path-item: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local type [integer!] @@ -1517,6 +1523,7 @@ lexer: context [ :scan-email ;-- T_EMAIL :scan-path-open ;-- T_PATH :scan-hex ;-- T_HEX + :scan-comment ;-- T_CMT ] scan-tokens: func [ diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 56130d8074..1c8f91c093 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -96,6 +96,7 @@ context [ T_EMAIL ;-- 81 T_PATH ;-- 82 T_HEX ;-- 83 + T_CMT ;-- 84 ] date-states: [ From b7351a25ccc2cc3715f39c512ab3d99af0187ab2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 02:12:58 +0100 Subject: [PATCH 0419/3432] FIX: state bound checking assertion not updated. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c76d622c9e..9df255f357 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1571,7 +1571,7 @@ lexer: context [ index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index ] - assert state <= T_HEX + assert state <= T_CMT assert start + offset <= p lex/in-pos: p From d0aa0ed845a83bb995bafa7e3a0af7786d7db8ff Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 9 Nov 2019 14:02:20 +0100 Subject: [PATCH 0420/3432] FEAT: VALUE? native supports ANY-WORD! argument. --- runtime/natives.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 257ff80f9f..20e6dd0649 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1861,11 +1861,13 @@ natives: context [ check? [logic!] /local value [red-value!] + type [integer!] result [red-logic!] ][ #typecheck value? value: stack/arguments - if TYPE_OF(value) = TYPE_WORD [ + type: TYPE_OF(value) + if ANY_WORD?(type) [ value: _context/get as red-word! stack/arguments ] result: as red-logic! stack/arguments From 12c0086dc388e7f675e8f6202e9824b99c492b62 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 14:56:18 +0100 Subject: [PATCH 0421/3432] FEAT: raises an error on unbalanced string braces on reaching input end. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9df255f357..cea1cfdfbe 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -946,9 +946,12 @@ lexer: context [ scan-mstring-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ lex/mstr-nest: lex/mstr-nest - 1 - if zero? lex/mstr-nest [ + + either zero? lex/mstr-nest [ scan-string lex lex/mstr-s e lex/mstr-flags or flags lex/entry: S_START + ][ + if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING] ] lex/in-pos: e + 1 ;-- skip } ] From 294b442dc2a1696686e1c9f63457bcd6608ad253 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 19:35:31 +0100 Subject: [PATCH 0422/3432] FIX: renames dtoa API call after merging from master. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cea1cfdfbe..8a7df8bdb3 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1184,7 +1184,7 @@ lexer: context [ err: 0 fl: as red-float! alloc-slot lex set-type as cell! fl TYPE_FLOAT - fl/value: red-dtoa/string-to-float s e :err + fl/value: dtoa/to-float s e :err if err <> 0 [throw-error lex s e TYPE_FLOAT] lex/in-pos: e ;-- reset the input position to delimiter byte ] From 11d6dc673c28ab75b2d4fc922e9efcce2bc5a3d8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 19:42:29 +0100 Subject: [PATCH 0423/3432] FIX: lexer's buffer not expanding when it should. --- runtime/lexer.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8a7df8bdb3..c0dd762ead 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -436,7 +436,7 @@ lexer: context [ deltaT [integer!] ][ size: lex/slots - if lex/head + size <= lex/tail [ + if lex/buffer + size <= lex/tail [ deltaH: (as-integer lex/head - lex/buffer) >> 4 deltaT: (as-integer lex/tail - lex/buffer) >> 4 lex/slots: size * 2 @@ -452,7 +452,7 @@ lexer: context [ slot: lex/tail slot/header: TYPE_UNSET if lex/nline > 0 [slot/header: slot/header or flag-new-line] - lex/tail: lex/tail + 1 + lex/tail: slot + 1 slot ] From 7d8ddb2d208c5412e240ebcfc5b711bc294a9563 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 20:04:07 +0100 Subject: [PATCH 0424/3432] FIX: eE lexical classes were excluded from encoded hexa values in files. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 26658 -> 26668 bytes docs/lexer/lexer-states.txt | 3 +++ runtime/lexer-transitions.reds | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index a6aea6fdb9..689eb47bbf 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -7,8 +7,8 @@ S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index d9a76aeca41db96941324812306aba7a31bcda66..ec4824ca0f64956ae552ecc35ad6ad575ae85fd0 100644 GIT binary patch delta 7975 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×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 Date: Sat, 9 Nov 2019 21:54:50 +0100 Subject: [PATCH 0425/3432] FIX: typo in scan-integer. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c0dd762ead..3e8728fcb2 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1149,7 +1149,7 @@ lexer: context [ ] ][ ;-- process with quote(s) loop len [ - if e/1 <> #"'" [ + if p/1 <> #"'" [ i: 10 * i + as-integer (p/1 - #"0") o?: o? or system/cpu/overflow? ] From 1280a2f8e2b7d246754e99779b4939bcad1e5174 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 9 Nov 2019 22:48:20 +0100 Subject: [PATCH 0426/3432] FIX: let scan-eof be a pass-thru. Needed for cases where the input ends with whitespaces not followed by a token. --- runtime/lexer.reds | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3e8728fcb2..34f6feba85 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -738,10 +738,7 @@ lexer: context [ p ] - scan-eof: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ - assert false ;-- should not happen (for now) - null - ] + scan-eof: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][] scan-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ throw-error lex s e ERR_BAD_CHAR From fa22cd7f3709f06bb620803e433b1348c5f2976f Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 10 Nov 2019 09:36:46 +0100 Subject: [PATCH 0427/3432] FIX: potential GC issue in hashtable. --- runtime/hashtable.reds | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 98931e8b07..63300d46ed 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -387,17 +387,21 @@ _hashtable: context [ h [hashtable!] ss [series!] hh [hashtable!] + b [node!] + k [node!] + a [logic!] ][ s: as series! ctx/symbols/value h: as hashtable! s/offset ss: as series! node/value hh: as hashtable! ss/offset - copy-memory as byte-ptr! hh as byte-ptr! h size? hashtable! - hh/blk: copy-series as series! h/blk/value + b: copy-series as series! h/blk/value + hh/blk: b + k: copy-series as series! h/keys/value + hh/keys: k hh/flags: copy-series as series! h/flags/value - hh/keys: copy-series as series! h/keys/value node ] From fe43f399d68fb923a359ef83e498bd690c928ca6 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 10 Nov 2019 09:47:45 +0100 Subject: [PATCH 0428/3432] FEAT: minor code refactoring. --- runtime/datatypes/symbol.reds | 18 ------------------ runtime/hashtable.reds | 11 +++++++---- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index a986ef75af..56b9cf002a 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -32,24 +32,6 @@ symbol: context [ sym/node: unicode/load-utf8 as c-string! s/offset as-integer s/tail - s/offset ] ] - - ;internalize: func [ - ; src [c-string!] - ; return: [node!] - ; /local - ; node [node!] - ; dst [c-string!] - ; s [series!] - ; len [integer!] - ;][ - ; len: 1 + length? src - ; node: alloc-bytes len ;@@ TBD: mark this buffer as protected! - ; s: as series! node/value - ; dst: as c-string! s/offset - - ; copy-memory as byte-ptr! dst as byte-ptr! src len - ; node - ;] make-alt: func [ str [red-string!] diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 63300d46ed..9b80bba81c 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1303,7 +1303,7 @@ _hashtable: context [ hash [integer!] n-buckets [integer!] flags [int-ptr!] ii [integer!] sh [integer!] blk [red-symbol!] idx [integer!] del? [logic!] k [red-symbol!] vsize [integer!] blk-node [series!] find? [logic!] xx [integer!] new? [logic!] - len2 [integer!] strict? [logic!] + len2 [integer!] strict? [logic!] p [byte-ptr!] ][ s: as series! node/value h: as hashtable! s/offset @@ -1381,10 +1381,13 @@ _hashtable: context [ blk: as red-symbol! blk-node/offset k/header: TYPE_UNSET - node: alloc-bytes len + node: alloc-bytes len + 1 ;-- add NUL bytes to make it compatible with C string s: as series! node/value - copy-memory as byte-ptr! s/offset cstr len - s/tail: as red-value! (as byte-ptr! s/offset) + len + p: as byte-ptr! s/offset + copy-memory p cstr len + p: p + len + p/1: null-byte + s/tail: as red-value! p k/cache: node k/node: null k/alias: len2 From 53e767905288f9ba8edc003f7d9f9ab2a96da00f Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 10 Nov 2019 10:13:04 +0100 Subject: [PATCH 0429/3432] FEAT: import strnicmp on POSIX system. --- runtime/platform/POSIX.reds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/platform/POSIX.reds b/runtime/platform/POSIX.reds index 2160db3926..496a2bf63c 100644 --- a/runtime/platform/POSIX.reds +++ b/runtime/platform/POSIX.reds @@ -227,6 +227,12 @@ pollfd!: alias struct! [ timeout [integer!] return: [integer!] ] + strnicmp: "strnicmp" [ + s1 [byte-ptr!] + s2 [byte-ptr!] + len [integer!] + return: [integer!] + ] ] ] From d1ac40baeb780ffae800e27a274e579aaa1a2654 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 10 Nov 2019 10:44:39 +0100 Subject: [PATCH 0430/3432] FIX: lexer crashing on loading / as a word. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 34f6feba85..68f0b6cb06 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1096,7 +1096,10 @@ lexer: context [ cell [cell!] type [integer!] ][ - type: either s/1 = #"#" [TYPE_ISSUE][assert s/1 = #"/" TYPE_REFINEMENT] + type: either s/1 = #"#" [TYPE_ISSUE][ + assert s/1 = #"/" + either s + 1 = e [s: s - 1 TYPE_WORD][TYPE_REFINEMENT] + ] s: s + 1 cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell From fc0f2be23c198951ddd5b918df0194e881098c48 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 10 Nov 2019 12:08:54 +0100 Subject: [PATCH 0431/3432] FEAT: proper support for words starting with <, like << and <= --- docs/lexer/lexer-FSM.csv | 106 +++++++++++++-------------- docs/lexer/lexer-FSM.xlsx | Bin 26668 -> 26923 bytes docs/lexer/lexer-states.txt | 5 +- runtime/lexer-transitions.reds | 126 +++++++++++++++++---------------- runtime/lexer.reds | 39 +++++----- 5 files changed, 140 insertions(+), 136 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 689eb47bbf..c6e669047f 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,53 +1,53 @@ -;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF -S_LINE_CMT;S_LINE_CMT;T_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF -S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR -S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF -S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR -S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD -S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE -S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE -S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR -S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF -S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR -S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR -S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR -S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;T_HEX;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP -S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE -S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR -S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;T_HEX;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD -S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD -S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL -S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD -S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_EQUAL;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_LINE_CMT;S_LINE_CMT;T_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF +S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR +S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF +S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR +S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE +S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF +S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR +S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR +S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR +S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;T_HEX;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP +S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE +S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;T_HEX;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD +S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE +S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index ec4824ca0f64956ae552ecc35ad6ad575ae85fd0..34a76c9af88fb328bd5d955f9f9c46c69b86d89e 100644 GIT binary patch literal 26923 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

STbn#XXp!)bBs3!kFFcV6JG!g+I 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 U{Mv$qbPIl5!29i_7C*lIAM8Rz%K!iX diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 33fa5a67d0..fd03b2ba49 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -193,7 +193,7 @@ Red/System [ 0A0A0A0A0A0A0A0A0A0A0A363640400B0B404040404040400B0B0B0B0B0B0B0B 0B0B0B0B0B0B0B0B0B40400B0B0B0B0B0B0B364045451212113643360D360F12 1236121212121212121212363636123645451212121212121236450D0D0D0D36 -3636363641363636360D0D0D0D0D0D0D363636363636360E363636363636360D +3636363641363636360D0D0D0D0D0D0D363636360D36360E363636363636360D 36360E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E 0E0E0E0E0E0E0E36350F0F0F0F0F0F0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F 0F0F0F0F0F0F0F0F0F0F0F100F0F36420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F From ab870b477c7fecb07608b3ab5f762bcd6d2fda17 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 11 Nov 2019 18:57:35 +0100 Subject: [PATCH 0435/3432] FIX: accepts / and + in binary! scanning (for base64). --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26916 -> 26926 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 396a6f56e8..021f85f3bc 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -12,7 +12,7 @@ S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR; S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index f47b928a25b968c0cd22034f7ce9b50fe6d0ad50..e405293f61d5a8cd0f060ce1becbb1b339250eb2 100644 GIT binary patch delta 8607 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

|8H0`7kn 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index fd03b2ba49..8869b3b8af 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -193,7 +193,7 @@ Red/System [ 0A0A0A0A0A0A0A0A0A0A0A363640400B0B404040404040400B0B0B0B0B0B0B0B 0B0B0B0B0B0B0B0B0B40400B0B0B0B0B0B0B364045451212113643360D360F12 1236121212121212121212363636123645451212121212121236450D0D0D0D36 -3636363641363636360D0D0D0D0D0D0D363636360D36360E363636363636360D +3636363641363636360D0D0D0D0D0D0D0D3636360D36360E3636360D3636360D 36360E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E 0E0E0E0E0E0E0E36350F0F0F0F0F0F0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F 0F0F0F0F0F0F0F0F0F0F0F100F0F36420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F From b54970e7d57c33e8089201d019be4424d594a78e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 11 Nov 2019 19:02:41 +0100 Subject: [PATCH 0436/3432] FIX: invalid Red values in file header. --- quick-test/tests/overwrite-test.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quick-test/tests/overwrite-test.reds b/quick-test/tests/overwrite-test.reds index 1365560215..0b0fb00c91 100644 --- a/quick-test/tests/overwrite-test.reds +++ b/quick-test/tests/overwrite-test.reds @@ -3,7 +3,7 @@ Red/System [ Author: "Peter W A Wood" File: %overwrite-test.reds Tabs: 4 - Rights: copyright (c) 2011-2015 Peter W A Wood + Rights: "copyright (c) 2011-2015 Peter W A Wood" License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt" ] From d6f11bff446a4bbf6cb24d9a69426a4ddcbd9c26 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 11 Nov 2019 11:31:38 +0800 Subject: [PATCH 0437/3432] FIX: no need to grap focus twice to avoid field selection issue --- modules/view/backends/gtk3/handlers.reds | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 1d0330e396..76c5f8eb82 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -708,11 +708,6 @@ mouse-button-press-event: func [ if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] sym: get-widget-symbol widget - if gtk_widget_get_focus_on_click widget [ - ;; DEBUG: print ["grab focus on mouse " widget lf] - gtk_widget_grab_focus widget - ] - if event/button = GDK_BUTTON_PRIMARY [ evt-motion/pressed: yes ] From 3675c43e82d02fa9a76c90590cb1d94b4724f6ce Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 11 Nov 2019 19:02:33 +0800 Subject: [PATCH 0438/3432] FIX: refactor change-para --- modules/view/backends/gtk3/font.reds | 127 +++++++++++++ modules/view/backends/gtk3/gui.reds | 10 +- modules/view/backends/gtk3/handlers.reds | 28 +-- modules/view/backends/gtk3/para.reds | 218 ++++------------------- 4 files changed, 183 insertions(+), 200 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 5c3012993c..3965585a0e 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -128,6 +128,107 @@ set-label-attrs: func [ gtk_label_set_attributes label hfont ] + +set-label-para: func [ + label [handle!] + hsym [integer!] + vsym [integer!] + wrap? [logic!] +][ + case [ + hsym = _para/left [ + gtk_label_set_justify label GTK_JUSTIFY_LEFT + ] + hsym = _para/right [ + gtk_label_set_justify label GTK_JUSTIFY_RIGHT + ] + true [ + gtk_label_set_justify label GTK_JUSTIFY_CENTER + ] + ] + case [ + vsym = _para/top [ + gtk_widget_set_halign label GTK_ALIGN_START + ] + vsym = _para/bottom [ + gtk_widget_set_halign label GTK_ALIGN_END + ] + true [ + gtk_widget_set_halign label GTK_ALIGN_CENTER + ] + ] + gtk_label_set_line_wrap label wrap? +] + +set-entry-para: func [ + entry [handle!] + hsym [integer!] + vsym [integer!] + wrap? [logic!] + /local + layout [handle!] +][ + layout: gtk_entry_get_layout entry + case [ + hsym = _para/left [ + pango_layout_set_alignment layout PANGO_ALIGN_LEFT + ] + hsym = _para/right [ + pango_layout_set_alignment layout PANGO_ALIGN_RIGHT + ] + true [ + pango_layout_set_alignment layout PANGO_ALIGN_CENTER + ] + ] + case [ + vsym = _para/top [ + gtk_widget_set_halign entry GTK_ALIGN_START + ] + vsym = _para/bottom [ + gtk_widget_set_halign entry GTK_ALIGN_END + ] + true [ + gtk_widget_set_halign entry GTK_ALIGN_CENTER + ] + ] + if wrap? [ + pango_layout_set_wrap layout PANGO_WRAP_WORD + ] +] + +set-textview-para: func [ + widget [handle!] + hsym [integer!] + vsym [integer!] + wrap? [logic!] +][ + case [ + hsym = _para/left [ + gtk_text_view_set_justification widget GTK_JUSTIFY_LEFT + ] + hsym = _para/right [ + gtk_text_view_set_justification widget GTK_JUSTIFY_RIGHT + ] + true [ + gtk_text_view_set_justification widget GTK_JUSTIFY_CENTER + ] + ] + case [ + vsym = _para/top [ + gtk_widget_set_halign widget GTK_ALIGN_START + ] + vsym = _para/bottom [ + gtk_widget_set_halign widget GTK_ALIGN_END + ] + true [ + gtk_widget_set_halign widget GTK_ALIGN_CENTER + ] + ] + + gtk_text_view_set_wrap_mode widget + either wrap? [GTK_WRAP_WORD][GTK_WRAP_NONE] +] + ;-- create pango attributes ;-- `angle` need to be set on label ;-- `anti-alias` need to be set by cairo @@ -594,16 +695,24 @@ set-font: func [ /local font [red-object!] color [red-tuple!] + para [red-object!] hFont [handle!] newF? [logic!] css [GString!] newC? [logic!] type [red-word!] sym [integer!] + pvalues [red-value!] + wrap? [logic!] + hsym [integer!] + vsym [integer!] label [handle!] ][ font: as red-object! values + FACE_OBJ_FONT color: as red-tuple! values + FACE_OBJ_COLOR + para: as red-object! values + FACE_OBJ_PARA + + hFont: get-attrs face font newF?: false if null? hFont [ @@ -618,8 +727,19 @@ set-font: func [ ] type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol + either TYPE_OF(para) = TYPE_OBJECT [ + pvalues: object/get-values para + wrap?: get-para-wrap pvalues + hsym: get-para-hsym pvalues + vsym: get-para-vsym pvalues + ][ + wrap?: no + hsym: _para/left + vsym: _para/middle + ] case [ sym = text [ + set-label-para widget hsym vsym wrap? set-label-attrs widget font hFont ] any [ @@ -630,12 +750,14 @@ set-font: func [ label: gtk_bin_get_child widget ;-- some button maybe have empty label either g_type_check_instance_is_a label gtk_label_get_type [ + set-label-para label hsym vsym wrap? set-label-attrs label font hFont ][ apply-css-styles widget css ] ] sym = field [ + set-entry-para widget hsym vsym wrap? gtk_entry_set_attributes widget hFont ] sym = group-box [ @@ -643,9 +765,14 @@ set-font: func [ either null? label [ apply-css-styles widget css ][ + set-label-para label hsym vsym wrap? set-label-attrs label font hFont ] ] + sym = area [ + set-textview-para widget hsym vsym wrap? + apply-css-styles widget css + ] true [ apply-css-styles widget css ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index ec68c241e4..8507314e7c 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1763,7 +1763,6 @@ OS-make-view: func [ assert TYPE_OF(face) = TYPE_OBJECT store-face-to-obj widget face make-styles-provider widget - change-font widget face values if all [ sym = panel @@ -1807,7 +1806,7 @@ OS-make-view: func [ connect-widget-events widget values sym change-selection widget selected sym - change-para widget face para font sym + change-font widget face values change-enabled widget enabled?/value sym parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym @@ -1919,12 +1918,7 @@ OS-update-view: func [ change-font widget face values ] if flags and FACET_FLAG_PARA <> 0 [ - change-para - widget - face - as red-object! values + FACE_OBJ_PARA - as red-object! values + FACE_OBJ_FONT - type + change-para widget face values ] ;if flags and FACET_FLAG_MENU <> 0 [ ; menu: as red-block! values + FACE_OBJ_MENU diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 76c5f8eb82..d60452ad06 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -95,7 +95,9 @@ render-text: func [ attrs [handle!] new? [logic!] para [red-object!] - flags [integer!] + pvalues [red-value!] + hsym [integer!] + vsym [integer!] layout [handle!] len [integer!] str [c-string!] @@ -119,12 +121,14 @@ render-text: func [ attrs: create-simple-attrs default-font-name default-font-size color ] - ;; DEBUG: print ["render-text: " cr lf] para: as red-object! values + FACE_OBJ_PARA - flags: either TYPE_OF(para) = TYPE_OBJECT [ ;@@ TBD set alignment attribute - get-para-flags base para + either TYPE_OF(para) = TYPE_OBJECT [ + pvalues: object/get-values para + hsym: get-para-hsym pvalues + vsym: get-para-vsym pvalues ][ - 0005h ;-- center or middle + hsym: _para/center + vsym: _para/middle ] layout: pango_cairo_create_layout cr @@ -143,18 +147,16 @@ render-text: func [ lx: lrect/width case [ - flags and 0001h <> 0 [x: (as-float (size/x - lx)) / 2.0] ; center - flags and 0002h <> 0 [x: as-float (size/x - lx)] ; right - true [x: 0.0] ; left + hsym = _para/center [x: (as-float (size/x - lx)) / 2.0] + hsym = _para/right [x: as-float (size/x - lx)] + true [x: 0.0] ] case [ - flags and 0004h <> 0 [y: (as-float (size/y - ly)) / 2.0] ; middle - flags and 0008h <> 0 [y: as-float (size/y - ly)] ; bottom - true [y: 0.0] ; top + vsym = _para/middle [y: (as-float (size/y - ly)) / 2.0] + vsym = _para/bottom [y: as-float (size/y - ly)] + true [y: 0.0] ] - ;; DEBUG: print [lx "x" ly " and (" x "," y ")" lf] - cairo_move_to cr x y pango_cairo_show_layout cr layout cairo_stroke cr diff --git a/modules/view/backends/gtk3/para.reds b/modules/view/backends/gtk3/para.reds index d1481ab697..a94b3da0ae 100644 --- a/modules/view/backends/gtk3/para.reds +++ b/modules/view/backends/gtk3/para.reds @@ -11,108 +11,32 @@ Red/System [ ] change-para: func [ - widget [handle!] - face [red-object!] - para [red-object!] - font [red-object!] - type [integer!] - return: [logic!] + widget [handle!] + face [red-object!] + values [red-value!] + return: [logic!] /local - flags [integer!] - where [integer!] - lay [handle!] + para [red-object!] ][ - + para: as red-object! values + FACE_OBJ_PARA if TYPE_OF(para) <> TYPE_OBJECT [return no] - flags: get-para-flags type para - ;; DEBUG: if flags <> 0 [print ["change-para " widget " " get-symbol-name type " flags: " flags lf]] - case [ - any [type = base type = panel][ - ;; nothing to do since done in render-text called by base-draw handler - ] - any [ - ; type = button - ; type = check - ; type = radio - ; type = field - type = text - ][ - if TYPE_OF(font) = TYPE_OBJECT [ - change-font widget face object/get-values face - ] - gtk_widget_set_halign widget (flags and FFFFh) + 1 - gtk_label_set_justify widget (flags and FFFFh) - gtk_label_set_line_wrap widget (flags and FFFF0000h <> 0) - ] - type = area [ - if TYPE_OF(font) = TYPE_OBJECT [ - change-font widget face object/get-values face - ] - gtk_text_view_set_justification widget (flags and FFFFh) - gtk_text_view_set_wrap_mode widget either (flags and FFFF0000h <> 0) [GTK_WRAP_WORD][GTK_WRAP_NONE] - ] - type = field [ - lay: gtk_entry_get_layout widget - pango_layout_set_alignment lay case [ - (flags and 0001h <> 0) [PANGO_ALIGN_RIGHT] - (flags and 0002h <> 0) [PANGO_ALIGN_CENTER] - true [PANGO_ALIGN_LEFT] - ] - pango_layout_set_wrap lay PANGO_WRAP_WORD - ] - true [0] - ] - if any [type = field type = text][ - ;;cell: objc_msgSend [hWnd sel_getUid "cell"] - ;;objc_msgSend [cell sel_getUid "setWraps:" flags and 20h <> 0] - 0 - ] + set-font widget face values yes ] update-para: func [ - face [red-object!] - flags [integer!] + face [red-object!] + fields [integer!] /local - para [red-object!] - type [red-word!] - state [red-block!] - int [red-integer!] - values [red-value!] - hWnd [handle!] - sym [integer!] - style [integer!] - ;; COMMENTED SINCE UNUSED! - ;; mask [integer!] + values [red-value!] + type [red-word!] + state [red-block!] + int [red-integer!] ][ values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE - ;; COMMENTED SINCE UNUSED! - ; sym: symbol/resolve type/symbol - ; para: as red-object! values + FACE_OBJ_PARA unless TYPE_OF(type) = TYPE_WORD [exit] ;@@ make it an error message - - ;; COMMENTED SINCE UNUSED! - ; case [ - ; sym = base [mask: not 002Fh] - ; any [ - ; sym = button - ; sym = check - ; sym = radio - ; ][ - ; mask: not 00000F00h - ; ] - ; any [ - ; sym = field - ; sym = area - ; sym = text - ; ][ - ; mask: not 00004003h - ; ] - ; true [0] - ; ] - state: as red-block! values + FACE_OBJ_STATE if TYPE_OF(state) = TYPE_BLOCK [ int: as red-integer! (block/rs-head state) + 1 @@ -122,101 +46,37 @@ update-para: func [ ] ] -get-para-flags: func [ - type [integer!] - para [red-object!] - return: [integer!] +get-para-wrap: func [ + values [red-value!] + return: [logic!] /local - values [red-value!] - align [red-word!] bool [red-logic!] - wrap? [logic!] - flags [integer!] - left [integer!] - center [integer!] - right [integer!] - top [integer!] - middle [integer!] - bottom [integer!] - h-def [integer!] - v-def [integer!] - h-sym [integer!] - v-sym [integer!] ][ - values: object/get-values para - align: as red-word! values + PARA_OBJ_ALIGN - h-sym: symbol/resolve align/symbol - align: as red-word! values + PARA_OBJ_V-ALIGN - v-sym: symbol/resolve align/symbol - bool: as red-logic! values + PARA_OBJ_WRAP? - - wrap?: any [ + bool: as red-logic! values + PARA_OBJ_WRAP? + any [ TYPE_OF(bool) = TYPE_NONE all [TYPE_OF(bool) = TYPE_LOGIC bool/value] ] +] - left: 0 center: 0 right: 0 h-def: 0 - top: 0 middle: 0 bottom: 0 v-def: 0 - - flags: 0 - - case [ - any [ - type = base - type = rich-text - ][ - left: 0000h ;-- DT_LEFT - center: 0001h ;-- DT_CENTER - right: 0002h ;-- DT_RIGHT - top: 0000h ;-- DT_TOP - middle: 0004h ;-- DT_VCENTER - bottom: 0008h ;-- DT_BOTTOM - h-def: center v-def: top - - unless wrap? [flags: 0010h] ;-- DT_SINGLELINE - ] - any [ - type = button - type = check - type = radio - ][ - left: 00000100h ;-- BS_LEFT - center: 00000300h ;-- BS_CENTER - right: 00000200h ;-- BS_RIGHT - top: 00000400h ;-- BS_TOP - middle: 00000C00h ;-- BS_VCENTER - bottom: 00000800h ;-- BS_BOTTOM - - h-def: either type = button [center][left] - ] - any [ - type = field - type = area - type = text - ][ - left: 0000h ;-- ES_LEFT / SS_LEFT - right: 0001h ;-- ES_RIGHT / SS_RIGHT - center: 0002h ;-- ES_CENTER / SS_CENTER - - h-def: left +get-para-hsym: func [ + values [red-value!] + return: [integer!] + /local + align [red-word!] +][ + align: as red-word! values + PARA_OBJ_ALIGN + if TYPE_OF(align) = TYPE_NONE [return _para/left] + symbol/resolve align/symbol +] - if all[wrap? type <> field][ - flags: 00010000h ;-- SS_ENDELLIPSIS - ] - ] - true [0] - ] - case [ - h-sym = _para/left [flags: flags or left] - h-sym = _para/center [flags: flags or center] - h-sym = _para/right [flags: flags or right] - true [flags: flags or h-def] - ] - case [ - v-sym = _para/top [flags: flags or top] - v-sym = _para/middle [flags: flags or middle] - v-sym = _para/bottom [flags: flags or bottom] - true [flags: flags or v-def] - ] - flags -] \ No newline at end of file +get-para-vsym: func [ + values [red-value!] + return: [integer!] + /local + align [red-word!] +][ + align: as red-word! values + PARA_OBJ_V-ALIGN + if TYPE_OF(align) = TYPE_NONE [return _para/middle] + symbol/resolve align/symbol +] From 82c1752ee40a5f336ea772fa6961f7b03aadb685 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 12 Nov 2019 14:34:54 +0800 Subject: [PATCH 0439/3432] FIX: better group radio --- modules/view/backends/gtk3/gtk.reds | 3 +++ modules/view/backends/gtk3/gui.reds | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 6783f8ba08..b2728ce27a 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2977,6 +2977,7 @@ resizing-id: g_quark_from_string "resizing-id" start-resize-id: g_quark_from_string "start-resize-id" caption-id: g_quark_from_string "caption-id" in-loop-id: g_quark_from_string "in-loop-id" +first-radio-id: g_quark_from_string "first-radio-id" #define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s container-id] @@ -2992,3 +2993,5 @@ in-loop-id: g_quark_from_string "in-loop-id" #define GET-IN-LOOP(s) [g_object_get_qdata s in-loop-id] #define SET-MENU-KEY(s d) [g_object_set_qdata s menu-key-id d] #define GET-MENU-KEY(s) [g_object_get_qdata s menu-key-id] +#define SET-FIRST-RADIO(s d) [g_object_set_qdata s first-radio-id d] +#define GET-FIRST-RADIO(s) [g_object_get_qdata s first-radio-id] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8507314e7c..71a4457b6e 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -30,7 +30,6 @@ default-font-name: as c-string! 0 default-font-size: 0 gtk-font-name: "Sans" gtk-font-size: 10 -group-radio: as handle! 0 log-pixels-x: 0 log-pixels-y: 0 @@ -1565,7 +1564,8 @@ OS-make-view: func [ rfvalue [red-float!] attrs [handle!] newF? [logic!] - layout [handle!] + handle [handle!] + fradio [handle!] x [integer!] y [integer!] ][ @@ -1606,10 +1606,13 @@ OS-make-view: func [ set-logic-state widget as red-logic! data no ] sym = radio [ - widget: either null? group-radio [ - gtk_radio_button_new_with_label null caption + handle: as handle! parent + fradio: GET-FIRST-RADIO(handle) + either null? fradio [ + widget: gtk_radio_button_new_with_label null caption + SET-FIRST-RADIO(handle widget) ][ - gtk_radio_button_new_with_label_from_widget group-radio caption + widget: gtk_radio_button_new_with_label_from_widget fradio caption ] set-logic-state widget as red-logic! data no ] @@ -1777,9 +1780,9 @@ OS-make-view: func [ buffer: gtk_label_new caption gtk_widget_show buffer set-label-attrs buffer font attrs - layout: gtk_label_get_layout buffer + handle: gtk_label_get_layout buffer x: 0 y: 0 - pango_layout_get_pixel_size layout :x :y + pango_layout_get_pixel_size handle :x :y x: either size/x > x [size/x - x / 2][0] y: either size/y > y [size/y - y / 2][0] gtk_layout_put widget buffer x y @@ -1810,8 +1813,6 @@ OS-make-view: func [ change-enabled widget enabled?/value sym parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym - ; save the previous group-radio state as a global variable - group-radio: either sym = radio [widget][as handle! 0] if TYPE_OF(rate) <> TYPE_NONE [change-rate widget rate] From 0c4be34816b847e47ce1a6f8c893dd8093803ea4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 12 Nov 2019 14:36:10 +0800 Subject: [PATCH 0440/3432] FIX: fix radio change-event issue For example: ``` view [ r1: radio "1" [print 1] r2: radio "2" [print 2] do [ r2/data: on ] ] ``` --- modules/view/backends/gtk3/events.reds | 38 ++++++++++++++++++++++---- modules/view/backends/gtk3/gui.reds | 33 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 6f6360715c..3bd6cd3768 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -905,7 +905,7 @@ translate-key: func [ ;; 1) it is required in makedoc/easy-VID-rt.red ;; 2) it is too slow when used in ast.red for base widget (too much delegations). -connect-common-events: function [ +connect-common-events: func [ widget [handle!] data [int-ptr!] ][ @@ -929,7 +929,7 @@ connect-common-events: function [ gobj_signal_connect(widget "scroll-event" :widget-scroll-event data) ] -connect-focus-events: function [ +connect-focus-events: func [ evbox [handle!] widget [handle!] sym [integer!] @@ -948,7 +948,7 @@ connect-focus-events: function [ ] ] -connect-notify-events: function [ +connect-notify-events: func [ widget [handle!] data [int-ptr!] ][ @@ -957,7 +957,35 @@ connect-notify-events: function [ gobj_signal_connect(widget "leave-notify-event" :widget-leave-notify-event data) ] -connect-widget-events: function [ +connect-radio-toggled-events: func [ + face [red-object!] + last [handle!] + parent [handle!] + /local + pface [red-object!] + pane [red-block!] + head [red-object!] + tail [red-object!] + handle [handle!] +][ + gobj_signal_connect(last "toggled" :button-toggled last) + pface: get-face-obj parent + ;if TYPE_OF(pface) <> TYPE_OBJECT [exit] + pane: as red-block! (object/get-values pface) + FACE_OBJ_PANE + head: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [head < tail][ + handle: face-handle? head + unless null? handle [ + if radio = get-widget-symbol handle [ + gobj_signal_connect(handle "toggled" :button-toggled handle) + ] + ] + head: head + 1 + ] +] + +connect-widget-events: func [ widget [handle!] values [red-value!] sym [integer!] @@ -980,7 +1008,7 @@ connect-widget-events: function [ gobj_signal_connect(widget "toggled" :button-toggled widget) ] sym = radio [ - gobj_signal_connect(widget "toggled" :button-toggled widget) + 0 ] sym = button [ gobj_signal_connect(widget "clicked" :button-clicked widget) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 71a4457b6e..7ad8a07b37 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -628,6 +628,34 @@ find-last-window: func [ ] ] +last-face-type?: func [ + face [red-object!] + parent [handle!] + sym [integer!] + return: [logic!] + /local + pface [red-object!] + pane [red-block!] + head [red-object!] + tail [red-object!] + type [red-word!] +][ + pface: get-face-obj parent + ;if TYPE_OF(pface) <> TYPE_OBJECT [return true] + pane: as red-block! (object/get-values pface) + FACE_OBJ_PANE + head: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [tail > head][ + tail: tail - 1 + if tail/ctx = face/ctx [return true] + type: as red-word! get-node-facet tail/ctx FACE_OBJ_TYPE + if sym = symbol/resolve type/symbol [ + return false + ] + ] + true +] + get-os-version: func [ /local major [integer!] @@ -1807,6 +1835,11 @@ OS-make-view: func [ ; Deal with actors connect-widget-events widget values sym + if sym = radio [ + if last-face-type? face as handle! parent sym [ + connect-radio-toggled-events face widget as handle! parent + ] + ] change-selection widget selected sym change-font widget face values From 7df97ec8a94fadca087c47554b280599dc18f4a1 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 12 Nov 2019 14:56:44 +0800 Subject: [PATCH 0441/3432] FIX: simple fix `request file/dir` issue --- modules/view/backends/gtk3/comdlgs.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index 3dcbbb082c..a3784544ad 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -59,6 +59,7 @@ _request-file: func [ set-type ret TYPE_FILE ] gtk_widget_destroy widget + while [gtk_events_pending][gtk_main_iteration] ret ] From 299f70b2c37ff3373b202f5a01483c18c317fbe6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 12 Nov 2019 15:45:15 +0800 Subject: [PATCH 0442/3432] FIX: avoid warning in cli-console --- modules/view/backends/gtk3/comdlgs.reds | 53 ++++++++++++++++++------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/modules/view/backends/gtk3/comdlgs.reds b/modules/view/backends/gtk3/comdlgs.reds index a3784544ad..ffd8e1d905 100644 --- a/modules/view/backends/gtk3/comdlgs.reds +++ b/modules/view/backends/gtk3/comdlgs.reds @@ -27,8 +27,9 @@ _request-file: func [ dir? [logic!] return: [red-value!] /local - window [handle!] widget [handle!] + window [handle!] + new? [logic!] resp [integer!] cstr [c-string!] size [integer!] @@ -48,7 +49,13 @@ _request-file: func [ ] gobj_signal_connect(widget "file-activated" :request-file-double-clicked null) window: find-active-window - unless null? window [gtk_window_set_transient_for widget window] + new?: false + if null? window [ + window: gtk_window_new 0 + gtk_widget_hide window + new?: true + ] + gtk_window_set_transient_for widget window resp: gtk_dialog_run widget if resp = GTK_RESPONSE_ACCEPT [ cstr: gtk_file_chooser_get_filename widget @@ -59,6 +66,9 @@ _request-file: func [ set-type ret TYPE_FILE ] gtk_widget_destroy widget + if new? [ + gtk_widget_destroy window + ] while [gtk_events_pending][gtk_main_iteration] ret ] @@ -86,20 +96,22 @@ OS-request-file: func [ ] OS-request-font: func [ - font [red-object!] - selected [red-object!] - mono? [logic!] - return: [red-object!] + font [red-object!] + selected [red-object!] + mono? [logic!] + return: [red-object!] /local - widget [handle!] - fd [handle!] - resp [integer!] - cstr [c-string!] - size [integer!] - values [red-value!] - str [red-string!] - style [red-block!] - bold? [logic!] + widget [handle!] + window [handle!] + new? [logic!] + fd [handle!] + resp [integer!] + cstr [c-string!] + size [integer!] + values [red-value!] + str [red-string!] + style [red-block!] + bold? [logic!] ][ widget: gtk_font_chooser_dialog_new "Font" null if TYPE_OF(selected) = TYPE_OBJECT [ @@ -107,6 +119,14 @@ OS-request-font: func [ gtk_font_chooser_set_font_desc widget fd free-pango-font fd ] + window: find-active-window + new?: false + if null? window [ + window: gtk_window_new 0 + gtk_widget_hide window + new?: true + ] + gtk_window_set_transient_for widget window resp: gtk_dialog_run widget either resp = -5 [ fd: gtk_font_chooser_get_font_desc widget @@ -138,6 +158,9 @@ OS-request-font: func [ font/header: TYPE_NONE ] gtk_widget_destroy widget + if new? [ + gtk_widget_destroy window + ] ; This trick really matters to end the loop when in the red-console while [gtk_events_pending][gtk_main_iteration] From 85e59428383a6832f023506912f00e77e9109c40 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 19:42:41 +0100 Subject: [PATCH 0443/3432] FIX: non-accurate decoding of escaped characters. --- runtime/lexer.reds | 78 ++++++++++++++++++++-------------- utils/generate-misc-tables.red | 1 - 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b22016dbf1..af6058ca9e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -157,9 +157,6 @@ lexer: context [ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF } - ;-- Bit-array for BDELNPTbdelnpt - char-names-1st: #{0000000000000000345011003450110000000000000000000000000000000000} - ;-- Bit-array for /-~^{}" char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} @@ -686,36 +683,54 @@ lexer: context [ bit [byte!] ][ either s/1 = #"(" [ ;-- note: #"^(" not allowed - c: as-integer s/2 - pos: c >>> 3 + 1 - bit: as-byte 1 << (c and 7) - either char-names-1st/pos and bit = null-byte [ ;-- hex escaped char @@ "e" as 1st! - p: s + 1 - c: 0 - cb: null-byte - while [all [p/1 <> #")" p < e]][ - index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table - cb: hexa-table/index ;-- decode one nibble at a time - if cb = #"^(FF)" [cp/value: -1 return p] - c: c << 4 + as-integer cb - p: p + 1 + case [ + s/3 = #")" [ ;-- fast-paths for 1 or 2 hex chars + index: 1 + as-integer s/2 + cb: hexa-table/index + if cb = #"^(FF)" [cp/value: -1 return s] + c: as-integer cb + p: s + 3 ] - if any [p = e p/1 <> #")" (as-integer p - s) > 7][ ;-- limit of 6 hexa characters - cp/value: -1 return s + s/4 = #")" [ + index: 1 + as-integer s/2 + cb: hexa-table/index + if cb = #"^(FF)" [cp/value: -1 return s] + c: as-integer cb + index: 1 + as-integer s/3 + cb: hexa-table/index + if cb = #"^(FF)" [cp/value: -1 return s] + c: c << 4 + as-integer cb + p: s + 4 ] - p: p + 1 ;-- skip ) - ][ ;-- named escaped char - src: s + 1 ;-- skip ( - entry: escape-names - loop 7 [ - if zero? platform/strnicmp src as byte-ptr! entry/1 entry/2 [break] - entry: entry + 3 + true [ + src: s + 1 ;-- skip ( + entry: escape-names + loop 7 [ ;-- try to match an escape name + if zero? platform/strnicmp src as byte-ptr! entry/1 entry/2 [break] + entry: entry + 3 + ] + either escape-names + (size? escape-names) > entry [ + len: entry/2 + 1 + if src/len <> #")" [cp/value: -1 return src] + c: entry/3 + p: src + len + ][ ;-- not a name, fall back on hex value decoding + p: s + 1 ;-- skip ( + c: 0 + cb: null-byte + while [all [p/1 <> #")" p < e]][ + index: 1 + as-integer p/1 ;-- converts the 2 hex chars using a lookup table + cb: hexa-table/index ;-- decode one nibble at a time + if cb = #"^(FF)" [cp/value: -1 return p] + c: c << 4 + as-integer cb + p: p + 1 + ] + if any [p = e p/1 <> #")" (as-integer p - s) > 7][ ;-- limit of 6 hexa characters + cp/value: -1 return s + ] + p: p + 1 ;-- skip ) + ] ] - assert escape-names + (7 * 3) > entry - len: entry/2 + 1 - if src/len <> #")" [cp/value: -1 return src] - c: entry/3 - p: src + len ] ][ c: as-integer s/1 @@ -931,7 +946,7 @@ lexer: context [ ser/tail: as cell! p4 ] ] - assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail + assert (as byte-ptr! ser/offset) + ser/size >= as byte-ptr! ser/tail ] if type <> TYPE_STRING [set-type as cell! str type] lex/in-pos: e + 1 ;-- skip ending delimiter @@ -950,6 +965,7 @@ lexer: context [ either zero? lex/mstr-nest [ scan-string lex lex/mstr-s e lex/mstr-flags or flags + lex/mstr-s: null lex/entry: S_START ][ if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING] diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index 75224607f6..58ef0fd761 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -129,7 +129,6 @@ gen-date-calc-table: function [][ probe out ] -gen-bitarray "BDELNPTbdelnpt" gen-bitarray {/-~^^{}"} gen-bin16-table gen-hexa-table From 0d3dec98d42f2907b05baa714b553d9b3947a6e0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 20:04:53 +0100 Subject: [PATCH 0444/3432] FIX: various fixes for scanning binary!, time! and pair! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26926 -> 26940 bytes docs/lexer/lexer-states.txt | 6 +++--- runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 5 ++++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 021f85f3bc..6d87dfc031 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -27,7 +27,7 @@ S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE; S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index e405293f61d5a8cd0f060ce1becbb1b339250eb2..561e8b6067c8f651b15c12b65a52124ad1246f4c 100644 GIT binary patch delta 8487 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 delta 8399 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index bd4a3a5f8d..6526ecc43b 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -236,9 +236,9 @@ S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \ \->else->T_ERROR \->delimit11->T_TIME \ \->else->T_ERROR \ - \->"x"|"X"->S_PAIR_1ST->digit->S_PAIR->digit|"."|"e"|"E"->S_PAIR - \ \->else->T_ERROR \->delimit10->T_PAIR - \ \->else->T_ERROR + \->"x"|"X"->S_PAIR_1ST->digit|sign->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR \ \->"#"->S_SHARP \->"@"->S_EMAIL diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 8869b3b8af..fe249fae7b 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -212,7 +212,7 @@ Red/System [ 36363636363636363636363636363636363636363636363636363636364D4D1B 1B4D4D4D4D4D4D4D36361B363636363636364D364D363636364D361B36363636 3636364D36361D1D363636363636363636363636363636363636363636363636 -36363636363636363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D1D3636 +363636361D1D36363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D1D3636 4C364C363636364C361D363636363636364C36361F1F36363636363636363636 363636363636363636363636363636363636363636363636364E4E1F1F4E4E4E 4E4E4E4E4E1F4E363636363636364E364E363636364E36203636363636363635 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index af6058ca9e..9d0758998e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1046,7 +1046,7 @@ lexer: context [ default [assert false null] ] if err <> null [throw-error lex err e TYPE_BINARY] - assert (as byte-ptr! ser/offset) + ser/size > as byte-ptr! ser/tail + assert (as byte-ptr! ser/offset) + ser/size >= as byte-ptr! ser/tail lex/in-pos: e + 1 ;-- skip } ] @@ -1397,7 +1397,9 @@ lexer: context [ /local field [lexer-dt-array!] tm [float!] + neg? [logic!] ][ + if s/1 = #"-" [neg?: yes s: s + 1] field: as lexer-dt-array! scan-date lex s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame if any [field/tz-h <> 0 field/tz-m <> 0][throw-error lex s e TYPE_TIME] ;-- TZ info rejection @@ -1407,6 +1409,7 @@ lexer: context [ + ( as float! field/sec) + (1e-9 * as float! field/nsec) + if neg? [tm: 0.0 - tm] time/make-at tm alloc-slot lex ;-- field array is not usable after this call ] From c0c9c315a2572beae55a357cdbcc96c997f504ae Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 20:24:44 +0100 Subject: [PATCH 0445/3432] FIX: extra characters not shown in lexer error reports. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9d0758998e..7b1eb6e3c0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -394,6 +394,7 @@ lexer: context [ line [red-integer!] len [integer!] ][ + e: lex/in-end e: either s + 40 < e [s + 40][e] ;FIXME: accurately find the 40th codepoint position len: as-integer e - s pos: string/load as-c-string s len UTF-8 From 011ecef5da297a1bf2213c2741aab2a77b87fe30 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 21:02:50 +0100 Subject: [PATCH 0446/3432] FIX: more compliant escaped char handling. --- runtime/lexer.reds | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7b1eb6e3c0..38988cc094 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -738,8 +738,7 @@ lexer: context [ pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) either char-special/pos and bit = null-byte [ ;-- "regular" escaped char - if any [s/1 < #"^(40)" #"^(5F)" < s/1][cp/value: -1 return s] - c: as-integer s/1 - #"@" + if any [s/1 < #"^(40)" #"^(5F)" < s/1][c: as-integer s/1 - #"@"] ][ ;-- escaped special char c: switch s/1 [ #"/" [0Ah] From 578402db282ba8a4c172ed901922715bee907a7c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 21:03:56 +0100 Subject: [PATCH 0447/3432] FIX: some compliant email! forms not accepted by the lexer. --- docs/lexer/lexer-FSM.csv | 8 ++++---- docs/lexer/lexer-FSM.xlsx | Bin 26940 -> 26960 bytes runtime/lexer-transitions.reds | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 6d87dfc031..beb30179e9 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -20,15 +20,15 @@ S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_M S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;T_HEX;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME -S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR +S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;S_EMAIL;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 561e8b6067c8f651b15c12b65a52124ad1246f4c..4c138bcd0a521a85105f4f93949685b3bdc4d6b7 100644 GIT binary patch delta 9000 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 I`<;9L2R=2Ji~s-t delta 8921 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 cANAp)-tV Date: Tue, 12 Nov 2019 21:14:27 +0100 Subject: [PATCH 0448/3432] FIX: allows C_EQUAL class in url! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26960 -> 26946 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index beb30179e9..39460d0e9f 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -44,7 +44,7 @@ S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_W S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD -S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;T_ERROR;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL +S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 4c138bcd0a521a85105f4f93949685b3bdc4d6b7..0b3639a9b020d11490dfcd73b656ddf763298654 100644 GIT binary patch delta 8551 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 F{{Z`2?h60_ diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a56d1aa84a..2c1313aede 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -232,7 +232,7 @@ Red/System [ 4636363636362A2A36363636483E3E2B2B3E3E3E3E3E3E3E362B2C2B2B2B2B2B 2B2B523E2B2B2B36363E2E2B1F2B2B2B2B2B363E3E3E2D2D3E3E3E3E3E3E3E2D 2D2D2D2D2D2D2D2D2D2D3E362D2D2D2D3E2D2D2D2D2D2D2D2D363E50502D2D50 -5050505050502D362D2D2D2D2D2D2D2D2D505036362D50502D2D362D2D362D2D +5050505050502D362D2D2D2D2D2D2D2D2D5050362D2D50502D2D362D2D362D2D 365051512E2E515151515151513636362E2E2E2E2E2E2E51515136362E365136 2E362E2E362E2E3651363630303636393A363602323131313131313131313636 2231313636362E31363333363131363647473030474747474747473613471C36 From 5c92d85b91b5319501cf7fc0fac8d9585731e227 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 21:17:01 +0100 Subject: [PATCH 0449/3432] TESTS: invalid syntax in checksum-test.red --- tests/source/units/checksum-test.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/source/units/checksum-test.red b/tests/source/units/checksum-test.red index 524730205c..36bb3a89bb 100644 --- a/tests/source/units/checksum-test.red +++ b/tests/source/units/checksum-test.red @@ -519,7 +519,7 @@ Red [ --assert expected = checksum/with data 'sha512 key ; "Test Using Larger Than Block-Size Key - Hash Key First" - data: copy#{ + data: copy #{ 54657374205573696E67204C6172676572205468616E20426C6F636B2D53697A 65204B6579202D2048617368204B6579204669727374 } @@ -533,7 +533,7 @@ Red [ --test-- "PRF-6-HMAC-SHA-256" ; "Test Using Larger Than Block-Size Key - Hash Key First" - data: copy#{ + data: copy #{ 54657374205573696E67204C6172676572205468616E20426C6F636B2D53697A 65204B6579202D2048617368204B6579204669727374 } @@ -549,7 +549,7 @@ Red [ --test-- "PRF-6-HMAC-SHA-384" ; "Test Using Larger Than Block-Size Key - Hash Key First" - data: copy#{ + data: copy #{ 54657374205573696E67204C6172676572205468616E20426C6F636B2D53697A 65204B6579202D2048617368204B6579204669727374 } @@ -568,7 +568,7 @@ Red [ --test-- "PRF-6-HMAC-SHA-512" ; "Test Using Larger Than Block-Size Key - Hash Key First" - data: copy#{ + data: copy #{ 54657374205573696E67204C6172676572205468616E20426C6F636B2D53697A 65204B6579202D2048617368204B6579204669727374 } From fdd8f7e5c4da6ed969a09baa7b4f34466fc379ee Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 12 Nov 2019 21:25:12 +0100 Subject: [PATCH 0450/3432] FEAT: minor code improvement. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 38988cc094..3aea443826 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1092,7 +1092,7 @@ lexer: context [ s: s + 2 ;-- skip #[ p: cons-syntax dtypes: p + (3 * 2) - end: p + (3 * 4) ;-- point to end of array + end: p + size? cons-syntax ;-- point to end of array loop 4 [ if zero? platform/strnicmp s as byte-ptr! p/1 p/2 [break] p: p + 3 From efe4136b79f778c01e66b5bd2d4054ee637ffc59 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 01:06:43 +0100 Subject: [PATCH 0451/3432] FIX: negative time! values handling was not correct. --- runtime/lexer.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3aea443826..bb46a2963a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1399,7 +1399,9 @@ lexer: context [ tm [float!] neg? [logic!] ][ - if s/1 = #"-" [neg?: yes s: s + 1] + neg?: s/1 = #"-" + if neg? [s: s + 1] + field: as lexer-dt-array! scan-date lex s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame if any [field/tz-h <> 0 field/tz-m <> 0][throw-error lex s e TYPE_TIME] ;-- TZ info rejection From e9221432f2ced93e8efdc463859861d9761e6859 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 19:43:00 +0100 Subject: [PATCH 0452/3432] FEAT: rewrites scan-time to fix bugs and remove some limitations. --- runtime/lexer.reds | 84 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index bb46a2963a..057212bdef 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -356,6 +356,7 @@ lexer: context [ ERR_BAD_CHAR: -1 ERR_MALCONSTRUCT: -2 ERR_MISSING: -3 + LEX_INT_OVERFLOW: -4 ] state!: alias struct! [ @@ -652,6 +653,48 @@ lexer: context [ null ] + grab-integer: func [s [byte-ptr!] e [byte-ptr!] flags [integer!] dst [int-ptr!] err [int-ptr!] + return: [byte-ptr!] + /local + p [byte-ptr!] + len [integer!] + i [integer!] + c [integer!] + neg? [logic!] + o? [logic!] + ][ + p: s + neg?: p/1 = #"-" + if neg? [p: p + 1] + + i: 0 + o?: no + while [p < e][ + c: as-integer (p/1 - #"0") + either all [c >= 0 c <= 9][ + i: 10 * i + c + o?: o? or system/cpu/overflow? + ][ + if p/1 <> #"'" [break] ;-- allow ' in integers + ] + p: p + 1 + ] + if o? [ + len: as-integer p - s ;-- account for sign in len now + either all [len = 11 zero? compare-memory s min-integer len][ + i: 80000000h + neg?: no ;-- ensure that the 0 subtraction does not occur + ][ + err/value: LEX_INT_OVERFLOW + return p + ] + ] + if neg? [i: 0 - i] + dst/value: i + p + ] + + scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] ;-- -1 if error /local @@ -1395,24 +1438,35 @@ lexer: context [ scan-time: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local - field [lexer-dt-array!] - tm [float!] - neg? [logic!] + p [byte-ptr!] + err [integer!] + hour [integer!] + min [integer!] + len [integer!] + tm [float!] ][ - neg?: s/1 = #"-" - if neg? [s: s + 1] + p: s + err: 0 + hour: 0 + + p: grab-integer p e flags :hour :err + if any [err <> 0 p/1 <> #":"][throw-error lex s e TYPE_TIME] + p: p + 1 - field: as lexer-dt-array! scan-date lex s e flags or C_FLAG_TM_ONLY ;-- field is on freed stack frame + min: 0 + p: grab-integer p e flags :min :err + if any [err <> 0 all [p + 1 < e p/1 <> #":"]][throw-error lex s e TYPE_TIME] + p: p + 1 + + if p < e [ + if flags and C_FLAG_EXP <> 0 [throw-error lex s e TYPE_TIME] + tm: dtoa/to-float p e :err + if err <> 0 [throw-error lex s e TYPE_TIME] + ] - if any [field/tz-h <> 0 field/tz-m <> 0][throw-error lex s e TYPE_TIME] ;-- TZ info rejection - - tm: (3600.0 * as float! field/hour) - + (60.0 * as float! field/min) - + ( as float! field/sec) - + (1e-9 * as float! field/nsec) - - if neg? [tm: 0.0 - tm] - time/make-at tm alloc-slot lex ;-- field array is not usable after this call + tm: (3600.0 * as-float hour) + (60.0 * as-float min) + tm + if hour < 0 [tm: 0.0 - tm] + time/make-at tm alloc-slot lex ] scan-money: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ From 5236a6b9cd17c8ecb2e0929b290e470b5a0fadfa Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 20:03:46 +0100 Subject: [PATCH 0453/3432] FEAT: more accurate handling of special short time! forms. hh:mm => hh:mm:00 mm:ss.nnn => 0:mm:ss.nnn --- runtime/lexer.reds | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 057212bdef..b5783a6961 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1439,6 +1439,7 @@ lexer: context [ scan-time: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local p [byte-ptr!] + mark [byte-ptr!] err [integer!] hour [integer!] min [integer!] @@ -1454,14 +1455,20 @@ lexer: context [ p: p + 1 min: 0 + mark: p p: grab-integer p e flags :min :err - if any [err <> 0 all [p + 1 < e p/1 <> #":"]][throw-error lex s e TYPE_TIME] + if any [err <> 0 min < 0][throw-error lex s e TYPE_TIME] p: p + 1 if p < e [ - if flags and C_FLAG_EXP <> 0 [throw-error lex s e TYPE_TIME] + if any [all [p/0 <> #"." p/0 <> #":"] flags and C_FLAG_EXP <> 0][throw-error lex s e TYPE_TIME] + if p/0 = #"." [ + min: hour + hour: 0 + p: mark + ] tm: dtoa/to-float p e :err - if err <> 0 [throw-error lex s e TYPE_TIME] + if any [err <> 0 tm < 0.0][throw-error lex s e TYPE_TIME] ] tm: (3600.0 * as-float hour) + (60.0 * as-float min) + tm From a808afd24c6845e06e226852b164ccb093850243 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 20:04:57 +0100 Subject: [PATCH 0454/3432] TESTS: remove exponents in time! decimals from tests. Exponent in time! is not supported by new lexer. --- tests/source/units/time-test.red | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/source/units/time-test.red b/tests/source/units/time-test.red index 7bf723b57b..47ef95c9a9 100644 --- a/tests/source/units/time-test.red +++ b/tests/source/units/time-test.red @@ -201,7 +201,7 @@ Red [ --test-- "time-func-args-2" ; quick empirical min/max values - --assert 1 = tf 170144881:00:05.620492334958379e19 0:00:09.99999e-16 + --assert 1 = tf 170144881:00:05.620492334958379 0:00:09.99999 ===end-group=== @@ -214,16 +214,16 @@ Red [ ][ switch tfi [ 1 [1:1:1] - 2 [170144881:00:05.620492334958379e19] - 3 [0:00:09.99999e-16] + 2 [170144881:00:05.620492334958379] + 3 [0:00:09.99999] ] ] --test-- "time return 1" --assert 1:1:1 = tf1 1 --test-- "time return 2" - --assert 170144881:00:05.620492334958379e19 = tf1 2 + --assert 170144881:00:05.620492334958379 = tf1 2 --test-- "time return 3" - --assert 0:00:09.99999e-16 = tf1 3 + --assert 0:00:09.99999 = tf1 3 ===end-group=== From e0428141aa0475c2a138cf60888fea6a4fb68993 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 20:24:00 +0100 Subject: [PATCH 0455/3432] FEAT: removes scan-time dependencies from scan-date. --- runtime/lexer.reds | 105 +++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b5783a6961..f0626de26f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -31,7 +31,6 @@ lexer: context [ C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h C_FLAG_SIGN: 00200000h - C_FLAG_TM_ONLY: 00000400h ;-- only scan a time! value C_FLAG_ESC_HEX: 00000200h ;-- percent-escaped mode C_FLAG_NOSTORE: 00000100h ;-- do not store decoded value ] @@ -1308,7 +1307,6 @@ lexer: context [ ] scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] - return: [lexer-dt-array!] ;-- return field pointer for scan-time /local cell [cell!] dt [red-date!] @@ -1326,14 +1324,12 @@ lexer: context [ c [integer!] pos [integer!] len [integer!] - time? [logic!] neg? [logic!] ][ c: 0 ;-- accumulator (fields decoding) b: s - time?: flags and C_FLAG_TM_ONLY <> 0 ;-- called from scan-time? field: system/stack/allocate/zero 17 ;-- date/time fields array - state: either time? [S_TM_START][S_DT_START] + state: S_DT_START loop as-integer e - s [ cp: as-integer s/1 @@ -1349,70 +1345,65 @@ lexer: context [ s: s + 1 ] if state <= T_DT_ERROR [ ;-- if no terminal state reached, forces EOF input - if state = T_DT_ERROR [ ;-- check here for performance reason - type: either time? [TYPE_TIME][TYPE_DATE] - throw-error lex b e type - ] + if state = T_DT_ERROR [throw-error lex b e TYPE_DATE] index: state * (size? date-char-classes!) + C_DT_EOF state: as-integer date-transitions/index pos: as-integer fields-table/state field/pos: c ] df: as lexer-dt-array! field + 1 - unless time? [ - p: as byte-ptr! df/TZ-sign - neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ - cell: alloc-slot lex - - either df/week or df/wday or df/yday <> 0 [ ;-- special ISO formats - df/month: 1 ;-- ensures valid month (will be changed later) - df/day: 1 ;-- ensures valid day (will be changed later) - dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw-error lex b e TYPE_DATE] - - if df/week or df/wday <> 0 [ ;-- yyyy-Www - date/set-isoweek dt df/week - ] - c: df/wday - if c <> 0 [ ;-- yyyy-Www-d - if any [c < 1 c > 7][throw-error lex b e TYPE_DATE] - date/set-weekday dt c - ] - if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd - ][ - p: as byte-ptr! df/month-begin - me: as byte-ptr! df/sep2 - if df/month-begin or df/sep2 <> 0 [ - if any [null? p null? me p/1 <> me/1][ - throw-error lex b e TYPE_DATE ;-- inconsistent separator - ] + + p: as byte-ptr! df/TZ-sign + neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ + cell: alloc-slot lex + + either df/week or df/wday or df/yday <> 0 [ ;-- special ISO formats + df/month: 1 ;-- ensures valid month (will be changed later) + df/day: 1 ;-- ensures valid day (will be changed later) + dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! + if null? dt [throw-error lex b e TYPE_DATE] + + if df/week or df/wday <> 0 [ ;-- yyyy-Www + date/set-isoweek dt df/week + ] + c: df/wday + if c <> 0 [ ;-- yyyy-Www-d + if any [c < 1 c > 7][throw-error lex b e TYPE_DATE] + date/set-weekday dt c + ] + if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd + ][ + p: as byte-ptr! df/month-begin + me: as byte-ptr! df/sep2 + if df/month-begin or df/sep2 <> 0 [ + if any [null? p null? me p/1 <> me/1][ + throw-error lex b e TYPE_DATE ;-- inconsistent separator ] - if df/year < 100 [ ;-- expand short yy forms - me: (as byte-ptr! df/sep2) + 3 - unless all [me < e (as-integer me/1 - #"0") <= 9][ ;-- check if year field has 2 digits - c: either df/year < 50 [2000][1900] - df/year: df/year + c - ] + ] + if df/year < 100 [ ;-- expand short yy forms + me: (as byte-ptr! df/sep2) + 3 + unless all [me < e (as-integer me/1 - #"0") <= 9][ ;-- check if year field has 2 digits + c: either df/year < 50 [2000][1900] + df/year: df/year + c ] - if df/month-end <> 0 [ ;-- if month is named - p: p + 1 ;-- name start - me: as byte-ptr! df/month-end ;-- name end - len: as-integer me - p + 1 - if any [len < 3 len > 9][throw-error lex b e TYPE_DATE] ;-- invalid month name - m: months - loop 12 [ - if zero? platform/strnicmp p as byte-ptr! m/1 len [break] - m: m + 1 - ] - if months + 12 = m [throw-error lex b e TYPE_DATE] ;-- invalid month name - df/month: (as-integer m - months) >> 2 + 1 + ] + if df/month-end <> 0 [ ;-- if month is named + p: p + 1 ;-- name start + me: as byte-ptr! df/month-end ;-- name end + len: as-integer me - p + 1 + if any [len < 3 len > 9][throw-error lex b e TYPE_DATE] ;-- invalid month name + m: months + loop 12 [ + if zero? platform/strnicmp p as byte-ptr! m/1 len [break] + m: m + 1 ] - dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw-error lex b e TYPE_DATE] + if months + 12 = m [throw-error lex b e TYPE_DATE] ;-- invalid month name + df/month: (as-integer m - months) >> 2 + 1 ] + dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! + if null? dt [throw-error lex b e TYPE_DATE] ] lex/in-pos: e ;-- reset the input position to delimiter byte - df ;-- return field pointer for scan-time ] scan-pair: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From c2a79998e6cf4b4bc86fc457b9039b545546c19e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 20:32:07 +0100 Subject: [PATCH 0456/3432] FIX: loading a time! value from lexer was resetting the new-line flag. --- runtime/datatypes/time.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/time.reds b/runtime/datatypes/time.reds index 33e32d209f..88596ffdda 100644 --- a/runtime/datatypes/time.reds +++ b/runtime/datatypes/time.reds @@ -76,8 +76,8 @@ time: context [ t [red-time!] ][ t: as red-time! cell - t/header: TYPE_TIME - t/time: time + set-type cell TYPE_TIME + t/time: time t ] From 19215f982358edf58cd01f28ca63ca4ebed7fd4d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 13 Nov 2019 20:36:47 +0100 Subject: [PATCH 0457/3432] FIX: do not eat the LF ending character in scan-comment. --- runtime/lexer.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f0626de26f..7ce1d0ed85 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1541,7 +1541,6 @@ lexer: context [ scan-comment: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ ;TBD: trigger an event - lex/in-pos: e + 1 ;-- skip lf ] From d1483e23f3a936d510623d75cc458aa395c4f152 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 14 Nov 2019 12:23:41 +0100 Subject: [PATCH 0458/3432] FEAT: exploratory work on rewriting scan-date using regular code. --- runtime/lexer.reds | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7ce1d0ed85..99b3b371ce 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -693,6 +693,30 @@ lexer: context [ p ] + grab-digits: func [s [byte-ptr!] e [byte-ptr!] max [integer!] dst [int-ptr!] err [int-ptr!] + return: [byte-ptr!] + /local + p [byte-ptr!] + i [integer!] + c [integer!] + ][ + i: 0 + if s = e [err/value: -2 return s] ;-- buffer end's reached + + while [all [s < e max > 0]][ + c: as-integer (s/1 - #"0") + either all [c >= 0 c <= 9][ + i: 10 * i + c + ][ + err/value: -1 + return s + ] + s: s + 1 + max: max - 1 + ] + dst/value: i + s + ] scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] ;-- -1 if error @@ -1306,7 +1330,51 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] + scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + /local + ][ + p: s + err: 0 + year: 0 + month: 0 + day: 0 + + cp: as-integer s/1 + class: as-integer date-classes/cp + + p: grab-digits p e 4 :year :err + sep: p/1 + if err <> 0 [throw-error lex s e TYPE_TIME] + if all [sep >= #"0" sep <= #"9"][ + p: grab-digits p e 2 :month :err + p: grab-digits p e 2 :day :err + if any [err <> 0 p/1 <> #"T"][throw-error lex s e TYPE_TIME] + p: grab-digits p e 2 :hour :err + p: grab-digits p e 2 :min :err + if p/1 <> #"Z" [ + p: grab-digits p e 2 :min :err + ] + ] + + + sep?: any [sep = #"-" sep = #"/"] + if sep? [p: p + 1] + + p: grab-digits p e 2 :month :err + if err <> 0 [ + unless sep? [throw-error lex s e TYPE_TIME] + ;named month + 0 + ] + if p/1 <> sep [throw-error lex s e TYPE_TIME] + p: p + 1 + + + + ] + + scan-date2: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local cell [cell!] dt [red-date!] From bbde7522cf6cb2a75e74a77e4da095a74a78dcd0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 15 Nov 2019 10:58:41 +0100 Subject: [PATCH 0459/3432] FEAT: adds partial ISO dates support in new scan-date. --- runtime/lexer.reds | 60 +++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 99b3b371ce..a47d2ced15 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1339,38 +1339,50 @@ lexer: context [ year: 0 month: 0 day: 0 - - cp: as-integer s/1 - class: as-integer date-classes/cp p: grab-digits p e 4 :year :err sep: p/1 - if err <> 0 [throw-error lex s e TYPE_TIME] - if all [sep >= #"0" sep <= #"9"][ - p: grab-digits p e 2 :month :err + if err <> 0 [throw-error lex s e TYPE_DATE] + either all [sep >= #"0" sep <= #"9"][ ;-- ISO dates + p: grab-digits p e 2 :month :err ;@@ should be 2 digits exactly! p: grab-digits p e 2 :day :err - if any [err <> 0 p/1 <> #"T"][throw-error lex s e TYPE_TIME] + if any [err <> 0 p/1 <> #"T"][throw-error lex s e TYPE_DATE] p: grab-digits p e 2 :hour :err p: grab-digits p e 2 :min :err - if p/1 <> #"Z" [ - p: grab-digits p e 2 :min :err + if err <> 0 [throw-error lex s e TYPE_DATE] + either p/1 = #"Z" [ + store-date + ][ + p: grab-digits p e 2 :sec :err + either p/1 = #"Z" [ + store-date + ][ + either any [p/1 = #"+" p/1 = #"-"][ + negZ?: p/1 = #"-" + p: p + 1 + p: grab-digits p e 2 :TZ-h :err + if err <> 0 [throw-error lex s e TYPE_DATE] + p: p + 1 + p: grab-digits p e 2 :TZ-m :err + ][ + throw-error lex s e TYPE_DATE + ] + ] ] + ][ + sep?: any [sep = #"-" sep = #"/"] + if sep? [p: p + 1] + + p: grab-digits p e 2 :month :err + if err <> 0 [ + unless sep? [throw-error lex s e TYPE_DATE] + ;named month + 0 + ] + if p/1 <> sep [throw-error lex s e TYPE_DATE] + p: p + 1 + p: grab-digits p e 2 :day :err ] - - - sep?: any [sep = #"-" sep = #"/"] - if sep? [p: p + 1] - - p: grab-digits p e 2 :month :err - if err <> 0 [ - unless sep? [throw-error lex s e TYPE_TIME] - ;named month - 0 - ] - if p/1 <> sep [throw-error lex s e TYPE_TIME] - p: p + 1 - - ] From 174cbc8583f54897017af5116f5906f06e58751c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 15 Nov 2019 19:44:29 +0100 Subject: [PATCH 0460/3432] FEAT: adds support for most date! formats in new scan-date. --- runtime/datatypes/date.reds | 39 ++++++++ runtime/lexer.reds | 173 ++++++++++++++++++++++++++++-------- 2 files changed, 175 insertions(+), 37 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index c95c62764e..e3db274c29 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -557,6 +557,45 @@ date: context [ dt ] + make-at2: func [ + slot [red-value!] + year [integer!] + month [integer!] + day [integer!] + tm [float!] + TZ-h [integer!] + TZ-m [integer!] + time? [logic!] + TZ? [logic!] + return: [red-date!] + /local + dt [red-date!] + d [integer!] + z [integer!] + -TZ? [logic!] + ][ + dt: as red-date! slot + d: 0 + d: DATE_SET_YEAR(d year) + d: DATE_SET_MONTH(d month) + d: DATE_SET_DAY(d day) + d: DATE_SET_TIME_FLAG(d) + set-type as red-value! dt TYPE_DATE ;-- preserve eventual flags in the header + dt/date: d + + -TZ?: no + if tz-h < 0 [-TZ?: yes tz-h: 0 - tz-h] + z: tz-h << 2 and 7Fh or (tz-m / 15) + if -TZ? [z: DATE_SET_ZONE_NEG(z)] + dt/date: DATE_SET_ZONE(dt/date z) + either time? [ + dt/time: to-utc-time tm DATE_GET_ZONE(dt/date) + ][ + dt/date: DATE_CLEAR_TIME_FLAG(dt/date) + ] + dt + ] + set-all: func [ dt [red-date!] year [integer!] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a47d2ced15..ebe22eeeec 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -693,29 +693,41 @@ lexer: context [ p ] - grab-digits: func [s [byte-ptr!] e [byte-ptr!] max [integer!] dst [int-ptr!] err [int-ptr!] + grab-digits: func [s [byte-ptr!] e [byte-ptr!] exact [integer!] max [integer!] dst [int-ptr!] err [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] i [integer!] c [integer!] ][ - i: 0 if s = e [err/value: -2 return s] ;-- buffer end's reached + p: s + i: 0 - while [all [s < e max > 0]][ - c: as-integer (s/1 - #"0") + while [all [p < e max > 0]][ + c: as-integer (p/1 - #"0") either all [c >= 0 c <= 9][ i: 10 * i + c ][ - err/value: -1 - return s + break ] - s: s + 1 + p: p + 1 max: max - 1 ] + if any [p = s all [exact > 0 exact <> as-integer p - s]][err/value: -1] dst/value: i - s + p + ] + + grab-float: func [s [byte-ptr!] e [byte-ptr!] dst [float-ptr!] err [int-ptr!] + return: [byte-ptr!] + /local + p [byte-ptr!] + ][ + p: s + while [all [p < e any [all [p/1 >= #"0" p/1 <= #"9"] p/1 = #"."]]][p: p + 1] + dst/value: dtoa/to-float s p err + p ] scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] @@ -1333,57 +1345,144 @@ lexer: context [ scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] /local + p [byte-ptr!] + me [byte-ptr!] + m [int-ptr!] + err [integer!] + year [integer!] + month [integer!] + day [integer!] + hour [integer!] + min [integer!] + tz-h [integer!] + tz-m [integer!] + len [integer!] + ylen [integer!] + dlen [integer!] + sec [float!] + tm [float!] + sep [byte!] + time? [logic!] + TZ? [logic!] + neg? [logic!] ][ p: s err: 0 year: 0 month: 0 day: 0 + hour: 0 + min: 0 + tz-h: 0 + tz-m: 0 + sec: 0.0 + tm: 0.0 + time?: no + TZ?: no - p: grab-digits p e 4 :year :err - sep: p/1 + me: p + p: grab-digits p e 0 4 :year :err + ylen: as-integer p - me if err <> 0 [throw-error lex s e TYPE_DATE] + sep: p/1 either all [sep >= #"0" sep <= #"9"][ ;-- ISO dates - p: grab-digits p e 2 :month :err ;@@ should be 2 digits exactly! - p: grab-digits p e 2 :day :err - if any [err <> 0 p/1 <> #"T"][throw-error lex s e TYPE_DATE] - p: grab-digits p e 2 :hour :err - p: grab-digits p e 2 :min :err - if err <> 0 [throw-error lex s e TYPE_DATE] - either p/1 = #"Z" [ - store-date - ][ - p: grab-digits p e 2 :sec :err - either p/1 = #"Z" [ - store-date - ][ - either any [p/1 = #"+" p/1 = #"-"][ - negZ?: p/1 = #"-" + p: grab-digits p e 2 2 :month :err + if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] + p: grab-digits p e 2 2 :day :err + if any [err <> 0 p = e p/1 <> #"T"][throw-error lex s e TYPE_DATE] + time?: yes + p: p + 1 + p: grab-digits p e 2 2 :hour :err + if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] + p: grab-digits p e 2 2 :min :err + if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] + if p/1 <> #"Z" [ + p: grab-float p e :sec :err + if all [p < e p/1 <> #"Z"][ + TZ?: yes + neg?: p/1 = #"-" + either any [p/1 = #"+" neg?][ p: p + 1 - p: grab-digits p e 2 :TZ-h :err + p: grab-digits p e 2 2 :TZ-h :err + if err <> 0 [throw-error lex s e TYPE_DATE] + if neg? [TZ-h: 0 - TZ-h] + p: grab-digits p e 2 2 :TZ-m :err if err <> 0 [throw-error lex s e TYPE_DATE] - p: p + 1 - p: grab-digits p e 2 :TZ-m :err ][ throw-error lex s e TYPE_DATE ] ] ] ][ - sep?: any [sep = #"-" sep = #"/"] - if sep? [p: p + 1] - - p: grab-digits p e 2 :month :err + if all [sep <> #"-" sep <> #"/"][throw-error lex s e TYPE_DATE] + p: p + 1 + p: grab-digits p e 0 2 :month :err if err <> 0 [ - unless sep? [throw-error lex s e TYPE_DATE] - ;named month - 0 + me: p + while [all [me < e me/1 <> sep]][me: me + 1] + len: as-integer me - p + if any [len < 3 len > 9][throw-error lex s e TYPE_DATE] ;-- invalid month name + m: months + loop 12 [ + if zero? platform/strnicmp p as byte-ptr! m/1 len [break] + m: m + 1 + ] + if months + 12 = m [throw-error lex s e TYPE_DATE] ;-- invalid month name + month: (as-integer m - months) >> 2 + 1 + err: 0 + p: me ] if p/1 <> sep [throw-error lex s e TYPE_DATE] p: p + 1 - p: grab-digits p e 2 :day :err + me: p + p: grab-digits p e 0 4 :day :err ;-- could be year also + dlen: as-integer p - me + if err <> 0 [throw-error lex s e TYPE_DATE] + if day > year [len: day day: year year: len ylen: dlen] + if all [year < 100 ylen <= 2][ ;-- expand short yy forms + ylen: either year < 50 [2000][1900] + year: year + ylen + ] + if all [p < e any [p/1 = #"/" p/1 = #"T"]][ + time?: yes + p: p + 1 + p: grab-digits p e 0 2 :hour :err + if any [err <> 0 p = e p/1 <> #":"][throw-error lex s e TYPE_DATE] + p: p + 1 + p: grab-digits p e 0 2 :min :err + if err <> 0 [throw-error lex s e TYPE_DATE] + if p < e [ + if p/1 = #":" [p: grab-float p + 1 e :sec :err] + if all [p < e p/1 <> #"Z"][ + neg?: p/1 = #"-" + either any [p/1 = #"+" neg?][ + p: p + 1 + p: grab-digits p e 0 2 :TZ-h :err + if neg? [TZ-h: 0 - TZ-h] + if err <> 0 [throw-error lex s e TYPE_DATE] + if p < e [ + if p/1 = #":" [p: p + 1] + p: grab-digits p e 0 2 :TZ-m :err + ] + ][ + throw-error lex s e TYPE_DATE + ] + ] + ] + ] ] - + if time? [tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec] + + if any [ + day > 31 month > 12 year > 9999 year < -9999 + tz-h > 15 tz-h < -15 ;-- out of range TZ + hour > 23 min > 59 sec >= 60.0 + all [day = 29 month = 2 not date/leap-year? year] + ][ + throw-error lex s e TYPE_DATE + ] + date/make-at2 alloc-slot lex year month day tm tz-h tz-m time? TZ? + lex/in-pos: e ;-- reset the input position to delimiter byte ] scan-date2: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] From 695caf5c34fd1fb87c866775a827fd9826e75b24 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 16 Nov 2019 12:27:38 +0100 Subject: [PATCH 0461/3432] FEAT: preliminary support for dates with weeks in new scan-date. --- runtime/lexer.reds | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ebe22eeeec..fab5fa226c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1391,8 +1391,7 @@ lexer: context [ p: grab-digits p e 2 2 :day :err if any [err <> 0 p = e p/1 <> #"T"][throw-error lex s e TYPE_DATE] time?: yes - p: p + 1 - p: grab-digits p e 2 2 :hour :err + p: grab-digits p + 1 e 2 2 :hour :err if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] p: grab-digits p e 2 2 :min :err if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] @@ -1402,8 +1401,7 @@ lexer: context [ TZ?: yes neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ - p: p + 1 - p: grab-digits p e 2 2 :TZ-h :err + p: grab-digits p + 1 e 2 2 :TZ-h :err if err <> 0 [throw-error lex s e TYPE_DATE] if neg? [TZ-h: 0 - TZ-h] p: grab-digits p e 2 2 :TZ-m :err @@ -1415,8 +1413,16 @@ lexer: context [ ] ][ if all [sep <> #"-" sep <> #"/"][throw-error lex s e TYPE_DATE] - p: p + 1 - p: grab-digits p e 0 2 :month :err + + either all [sep = #"-" ylen = 4 p/2 = #"W"][ + p: grab-digits p + 2 e 2 2 :week :err + if err <> 0 [throw-error lex s e TYPE_DATE] + if all [p < e p/1 = #"-"][ + p: grab-digits p + 2 e 1 1 :wday :err + ] + ] + + p: grab-digits p + 1 e 0 2 :month :err if err <> 0 [ me: p while [all [me < e me/1 <> sep]][me: me + 1] @@ -1445,19 +1451,16 @@ lexer: context [ ] if all [p < e any [p/1 = #"/" p/1 = #"T"]][ time?: yes - p: p + 1 - p: grab-digits p e 0 2 :hour :err + p: grab-digits p + 1 e 0 2 :hour :err if any [err <> 0 p = e p/1 <> #":"][throw-error lex s e TYPE_DATE] - p: p + 1 - p: grab-digits p e 0 2 :min :err + p: grab-digits p + 1 e 0 2 :min :err if err <> 0 [throw-error lex s e TYPE_DATE] if p < e [ if p/1 = #":" [p: grab-float p + 1 e :sec :err] if all [p < e p/1 <> #"Z"][ neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ - p: p + 1 - p: grab-digits p e 0 2 :TZ-h :err + p: grab-digits p + 1 e 0 2 :TZ-h :err if neg? [TZ-h: 0 - TZ-h] if err <> 0 [throw-error lex s e TYPE_DATE] if p < e [ From b06d0abc06d88058f0b652722d2a0080011c2f13 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 16 Nov 2019 17:00:18 +0100 Subject: [PATCH 0462/3432] FEAT: [R/S] support multiple variable assignments. Example: a: b: c: 0 --- system/compiler.r | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 7711dd1e55..c6d1ed6475 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1953,6 +1953,24 @@ system-dialect: make-profilable context [ append emitter/code-buf code ] + expand-setwords: has [list p lit? value out][ + list: [] + ;-- collect all set-words except last one + p: pc + while [set-word? p/2][append list p/1 p: next p] + ;-- set each one to a literal value or to the pointer variable (the last one) + lit?: find [integer! decimal! char! logic!] type?/word p/2 + value: either any [lit? find [true false] p/2][p/2][to-word p/1] + + remove/part pc p ;-- remove all the extra set-words + p: skip pc 2 ;-- skip the last set-word/value + out: [] + foreach w list [repend out [w value]] ;-- construct the extra set-word/value pairs + insert p out ;-- inject them + clear out + clear list + ] + comp-chunked: func [body [block!]][ emitter/chunks/start do body @@ -2727,6 +2745,7 @@ system-dialect: make-profilable context [ ] comp-assignment: has [name value n enum ns local?][ + if all [set-word? pc/1 set-word? pc/2][expand-setwords] push-call name: pc/1 pc: next pc if set-word? name [ @@ -2742,9 +2761,9 @@ system-dialect: make-profilable context [ local?: local-variable? n unless any [locals local?][store-ns-symbol n] - if find [set-word! set-path!] type?/word pc/1 [ + if set-path? pc/1 [ backtrack name - throw-error "cascading assignments not supported" + throw-error "cascading path assignments not supported" ] unless all [local? n = 'context][ ;-- explicitly allow 'context name for local variables check-keywords n ;-- forbid keywords redefinition From 49cc2724ee8832357d82a9b85d39fb30bda62681 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 16 Nov 2019 17:00:53 +0100 Subject: [PATCH 0463/3432] FEAT: minor code improvement. --- system/compiler.r | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index c6d1ed6475..08a2ac9acd 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -2009,9 +2009,9 @@ system-dialect: make-profilable context [ throw-error "?? needs a word as argument" ] out: next next compose/deep [ - 2 (to pair! reduce [calc-line 1]) ;-- hidden line offset header + 2 (as-pair calc-line 1) ;-- hidden line offset header print-line [ - 2 (to pair! reduce [calc-line 1]) ;-- hidden line offset header + 2 (as-pair calc-line 1) ;-- hidden line offset header (join name ": ") (name) ] ] From ea0a59b54933372791c9d2707337118b85e434cb Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 16 Nov 2019 17:02:12 +0100 Subject: [PATCH 0464/3432] FEAT: refactor scan-date to use multiple variable assignments. --- runtime/lexer.reds | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fab5fa226c..6b6aa379b8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1367,18 +1367,9 @@ lexer: context [ neg? [logic!] ][ p: s - err: 0 - year: 0 - month: 0 - day: 0 - hour: 0 - min: 0 - tz-h: 0 - tz-m: 0 - sec: 0.0 - tm: 0.0 - time?: no - TZ?: no + err: year: month: day: hour: min: tz-h: tz-m: 0 + sec: tm: 0.0 + time?: TZ?: no me: p p: grab-digits p e 0 4 :year :err @@ -1414,13 +1405,13 @@ lexer: context [ ][ if all [sep <> #"-" sep <> #"/"][throw-error lex s e TYPE_DATE] - either all [sep = #"-" ylen = 4 p/2 = #"W"][ - p: grab-digits p + 2 e 2 2 :week :err - if err <> 0 [throw-error lex s e TYPE_DATE] - if all [p < e p/1 = #"-"][ - p: grab-digits p + 2 e 1 1 :wday :err - ] - ] + ;either all [sep = #"-" ylen = 4 p/2 = #"W"][ + ; p: grab-digits p + 2 e 2 2 :week :err + ; if err <> 0 [throw-error lex s e TYPE_DATE] + ; if all [p < e p/1 = #"-"][ + ; p: grab-digits p + 2 e 1 1 :wday :err + ; ] + ;] p: grab-digits p + 1 e 0 2 :month :err if err <> 0 [ From a81649235cf09555de3b2ba4271f9e4fdf8fd292 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 17 Nov 2019 14:14:30 +0100 Subject: [PATCH 0465/3432] FEAT: [R/S] allows grouping arguments and local variables type specification. Example: foo: func [a b [integer!] /local c d [byte!] e f g [float!] h j [byte-ptr!] ] is now allowed. --- system/compiler.r | 13 ++++++++++++- system/runtime/debug.reds | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 08a2ac9acd..54b02d72b5 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1652,13 +1652,24 @@ system-dialect: make-profilable context [ ] ] + expand-func-specs: func [spec /local pos p type][ + unless block? spec [exit] ;-- let check-specs report it + parse spec [any [ + pos: word! some word! p: block! ( + type: p/1 + while [not block? pos/2][pos: insert/only next pos type] + ) | skip + ]] + ] + fetch-func: func [name /local specs type cc attribs][ name: to word! name store-ns-symbol name if ns-path [add-ns-symbol pc/-1] if ns-path [name: ns-prefix name] check-func-name name - check-specs name specs: pc/2 + expand-func-specs specs: pc/2 + check-specs name specs specs: copy specs clear-docstrings specs diff --git a/system/runtime/debug.reds b/system/runtime/debug.reds index a3400a4784..a6c6edee1d 100644 --- a/system/runtime/debug.reds +++ b/system/runtime/debug.reds @@ -68,8 +68,9 @@ __print-debug-line: func [ ;------------------------------------------- __print-debug-stack: func [ address [byte-ptr!] ;-- memory address where the runtime error happened - /local - ret funcs records nb next end top frame s value lines pf [float-ptr!] + /local + pf [float-ptr!] + ret funcs records nb next end top frame s value lines unused base ][ funcs: as byte-ptr! __debug-funcs From ce344923c307bd38c148f04375d5f8826bbd8e0f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 17 Nov 2019 14:47:49 +0100 Subject: [PATCH 0466/3432] FIX: invalid local variable specification. Such pattern is now considered local variable specification grouping after previous commit, and untyped variables now need to be specified last. --- runtime/simple-io.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/simple-io.reds b/runtime/simple-io.reds index dd2a0aa6be..894c2de7b5 100644 --- a/runtime/simple-io.reds +++ b/runtime/simple-io.reds @@ -1032,7 +1032,6 @@ simple-io: context [ filename [red-file!] return: [red-block!] /local - info buf [byte-ptr!] p [byte-ptr!] name [byte-ptr!] @@ -1043,6 +1042,7 @@ simple-io: context [ i [integer!] cp [byte!] s [series!] + info ][ len: string/rs-length? as red-string! filename len: filename/head + len - 1 From b61510b45649c38b39c2810088e9d4bf7a18ce02 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 17 Nov 2019 23:25:36 +0100 Subject: [PATCH 0467/3432] FIX: invalid do-mark-sweep function spec in debug mode. --- runtime/collector.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/collector.reds b/runtime/collector.reds index bf689ac1be..4ab3162b20 100644 --- a/runtime/collector.reds +++ b/runtime/collector.reds @@ -288,13 +288,13 @@ collector: context [ p [int-ptr!] obj [red-object!] w [red-word!] - cb #if debug? = yes [ file [c-string!] saved [integer!] buf [c-string!] tm tm1 ] + cb ][ #if debug? = yes [if verbose > 1 [ #if OS = 'Windows [platform/dos-console?: no] From fdf7a3ace7a623eabd214712d0a1d9b2a847bcae Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 17 Nov 2019 23:26:46 +0100 Subject: [PATCH 0468/3432] FEAT: improves syntax error report formatting. --- environment/system.red | 8 ++++---- runtime/datatypes/error.reds | 2 +- runtime/lexer.reds | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/environment/system.red b/environment/system.red index 19a4eeafd9..f4ca842167 100644 --- a/environment/system.red +++ b/environment/system.red @@ -86,13 +86,13 @@ system: context [ syntax: object [ code: 200 type: "Syntax Error" - invalid: ["invalid" :arg2 "at line" :arg1 "in" :arg3] - missing: ["missing" :arg2 "at line" :arg1 "in" :arg3] + invalid: [:arg1 "invalid" :arg2 "in:" :arg3] + missing: [:arg1 "missing" :arg2 "in:" :arg3] no-header: ["script is missing a Red header:" :arg1] no-rs-header: ["script is missing a Red/System header:" :arg1] bad-header: ["script header is not valid:" :arg1] - malconstruct: ["invalid construction spec at line" :arg1 "in" :arg2] - bad-char: ["invalid character at line" :arg1 "in" :arg2] + malconstruct: [:arg1 "invalid construction spec in:" :arg2] + bad-char: [:arg1 "invalid character in:" :arg2] ] script: object [ code: 300 diff --git a/runtime/datatypes/error.reds b/runtime/datatypes/error.reds index 8b4e497e8d..d57a858f18 100644 --- a/runtime/datatypes/error.reds +++ b/runtime/datatypes/error.reds @@ -146,7 +146,7 @@ error: context [ ][ buffer: string/rs-make-at stack/push* 16 stack/mark-native words/_body - actions/mold object/rs-select obj value buffer no no yes null 0 0 + actions/form object/rs-select obj value buffer null 0 stack/unwind copy-cell as red-value! buffer value stack/pop 1 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 6b6aa379b8..95fc66a566 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -391,14 +391,23 @@ lexer: context [ throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] /local pos [red-string!] - line [red-integer!] + line [red-string!] + p [byte-ptr!] len [integer!] ][ e: lex/in-end - e: either s + 40 < e [s + 40][e] ;FIXME: accurately find the 40th codepoint position - len: as-integer e - s + len: 0 + p: s + while [all [p < e p/1 <> #"^/" s + 30 > p]][p: decode-utf8-char p :len] + if p > e [p: e] + len: as-integer p - s pos: string/load as-c-string s len UTF-8 - line: integer/push lex/line + + line: string/rs-make-at stack/push* 20 + string/concatenate-literal line "(line " + string/concatenate-literal line integer/form-signed lex/line + string/append-char GET_BUFFER(line) as-integer #")" + lex/tail: lex/buffer ;-- clear accumulated values depth: depth - 1 From 6b2b38ecc9046a3c5f78c51f13983187559ea4b2 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 18 Nov 2019 10:45:02 +0100 Subject: [PATCH 0469/3432] FIX: minor bit layout correction --- runtime/allocator.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index efb6ed9b99..080c7a3c53 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -55,7 +55,7 @@ cell!: alias struct! [ ; 19: complement ;-- complement flag for bitsets ; 18: UTF-16 cache ;-- signifies that the string cache is UTF-16 encoded (UTF-8 by default) ; 17: owned ;-- series is owned by an object -; 16-3: +; 16-5: ; 4-0: unit ;-- size in bytes of atomic element stored in buffer ;-- 0: UTF-8, 1: Latin1/binary, 2: UCS-2, 4: UCS-4, 16: block! cell series-buffer!: alias struct! [ From 142451e0c4a24a90242da6feb3a5b1a1662d3b78 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 12 Nov 2019 18:03:17 +0800 Subject: [PATCH 0470/3432] FIX: draw arc issues in `view-test.red` --- modules/view/backends/gtk3/draw.reds | 1 + modules/view/backends/gtk3/handlers.reds | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index db53fabc7d..bf6ee043cc 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -579,6 +579,7 @@ OS-draw-text: func [ ][ draw-text-box dc/raw pos as red-object! text catch? ] + do-paint dc true ] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index d60452ad06..ceee6f7725 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -161,6 +161,7 @@ render-text: func [ pango_cairo_show_layout cr layout cairo_stroke cr cairo_restore cr + g_object_unref layout if new? [ free-pango-attrs attrs From 30819941b8b3052a29c42a7557fd01573bac09f6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 18 Nov 2019 16:01:41 +0800 Subject: [PATCH 0471/3432] FIX: box text no need face background, as the background be set by draw --- modules/view/backends/gtk3/text-box.reds | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 322b7e9196..b1270740d5 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -346,7 +346,6 @@ OS-text-box-layout: func [ state [red-block!] size [red-pair!] font [red-object!] - color [red-tuple!] cached? [logic!] attrs [handle!] int [red-integer!] @@ -364,7 +363,6 @@ OS-text-box-layout: func [ state: as red-block! values + FACE_OBJ_EXT3 size: as red-pair! values + FACE_OBJ_SIZE font: as red-object! values + FACE_OBJ_FONT - color: as red-tuple! values + FACE_OBJ_COLOR cached?: TYPE_OF(state) = TYPE_BLOCK either cached? [ @@ -387,9 +385,9 @@ OS-text-box-layout: func [ logic/make-in state false ] attrs: either TYPE_OF(font) = TYPE_BLOCK [ - create-pango-attrs box font + create-pango-attrs null font ][ - create-simple-attrs default-font-name default-font-size color + create-simple-attrs default-font-name default-font-size null ] len: -1 str: unicode/to-utf8 text :len From a399518adb7eac5e4ed0e2ec41654a38f746ad07 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 18 Nov 2019 16:44:47 +0800 Subject: [PATCH 0472/3432] Revert "FIX: if `face/color = none`, the face will be transparent" This reverts commit 0f3c321967cf5953050cc973291e07bfc3d571ac. --- modules/view/backends/gtk3/gui.reds | 62 +++-------------------------- 1 file changed, 6 insertions(+), 56 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7ad8a07b37..20538cd242 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -50,13 +50,6 @@ get-face-obj: func [ face ] -is-face?: func [ - handle [handle!] - return: [logic!] -][ - TYPE_OBJECT = (get-type-mask and as integer! g_object_get_qdata handle red-face-id1) -] - get-face-values: func [ handle [handle!] return: [red-value!] @@ -217,7 +210,6 @@ set-widget-child: func [ parent [handle!] widget [handle!] offset [red-pair!] - trans? [logic!] return: [logic!] /local sym [integer!] @@ -244,12 +236,12 @@ set-widget-child: func [ case [ sym = window [ playout: GET-CONTAINER(parent) - insert-widget playout clayout x y trans? + gtk_layout_put playout clayout x y true ] sym = group-box [ playout: gtk_bin_get_child parent - insert-widget playout clayout x y trans? + gtk_layout_put playout clayout x y true ] any [ @@ -257,7 +249,7 @@ set-widget-child: func [ sym = rich-text sym = panel ][ - insert-widget parent clayout x y trans? + gtk_layout_put parent clayout x y true ] sym = tab-panel [ @@ -313,47 +305,6 @@ set-widget-child-offset: func [ ] ] -insert-widget: func [ - layout [handle!] - widget [handle!] - x [integer!] - y [integer!] - trans? [logic!] - /local - list [GList!] - last [GList!] - sibling [handle!] - gvalue [handle!] - nx [integer!] - ny [integer!] -][ - list: gtk_container_get_children layout - either any [ - null? list - not trans? - ][ - gtk_layout_put layout widget x y - ][ - last: g_list_last list - sibling: last/data - gvalue: system/stack/allocate 5 - set-memory as byte-ptr! gvalue null-byte 20 - g_value_init gvalue G_TYPE_INT - gtk_container_child_get_property layout sibling "x" gvalue - nx: g_value_get_int gvalue - gtk_container_child_get_property layout sibling "y" gvalue - ny: g_value_get_int gvalue - g_object_ref sibling - gtk_container_remove layout sibling - gtk_layout_put layout widget x y - gtk_layout_put layout sibling nx ny - g_object_unref sibling - ] - unless null? list [ - g_list_free list - ] -] - show-widget: func [ widget [handle!] /local @@ -859,7 +810,7 @@ change-pane: func [ widget [handle!] values [red-value!] offset [red-pair!] - color [red-tuple!] + ][ layout: case [ type = window [ @@ -901,8 +852,7 @@ change-pane: func [ if widget <> null [ values: object/get-values face offset: as red-pair! values + FACE_OBJ_OFFSET - color: as red-tuple! values + FACE_OBJ_COLOR - set-widget-child parent widget offset TYPE_OF(color) <> TYPE_TUPLE + set-widget-child parent widget offset ] ] face: face + 1 @@ -1822,7 +1772,7 @@ OS-make-view: func [ if sym <> window [ if parent <> 0 [ - unless set-widget-child as handle! parent widget offset TYPE_OF(color) <> TYPE_TUPLE [ + unless set-widget-child as handle! parent widget offset [ fire [TO_ERROR(script face-type) type] ] ] From c8096f396c2128ca810dc9f32d5b944d6d0657aa Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 18 Nov 2019 20:56:38 +0800 Subject: [PATCH 0473/3432] FIX: support transparent widget in a better way --- modules/view/backends/gtk3/events.reds | 2 + modules/view/backends/gtk3/gtk.reds | 7 ++ modules/view/backends/gtk3/handlers.reds | 149 +++++++++++++++++++++-- 3 files changed, 151 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 3bd6cd3768..cb345a2136 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1015,6 +1015,8 @@ connect-widget-events: func [ ] sym = base [ gobj_signal_connect(widget "draw" :base-draw widget) + ;-- transparent widget need propagate events to sibling + gobj_signal_connect(widget "event-after" :base-event-after widget) ] sym = rich-text [ gobj_signal_connect(widget "draw" :base-draw widget) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index b2728ce27a..57328775be 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1489,6 +1489,10 @@ GPtrArray!: alias struct! [ widget [handle!] return: [integer!] ] + gtk_widget_get_can_focus: "gtk_widget_get_can_focus" [ + widget [handle!] + return: [logic!] + ] gtk_widget_set_can_focus: "gtk_widget_set_can_focus" [ widget [handle!] focus [logic!] @@ -2978,6 +2982,7 @@ start-resize-id: g_quark_from_string "start-resize-id" caption-id: g_quark_from_string "caption-id" in-loop-id: g_quark_from_string "in-loop-id" first-radio-id: g_quark_from_string "first-radio-id" +resend-event-id: g_quark_from_string "resend-event-id" #define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s container-id] @@ -2995,3 +3000,5 @@ first-radio-id: g_quark_from_string "first-radio-id" #define GET-MENU-KEY(s) [g_object_get_qdata s menu-key-id] #define SET-FIRST-RADIO(s d) [g_object_set_qdata s first-radio-id d] #define GET-FIRST-RADIO(s) [g_object_get_qdata s first-radio-id] +#define SET-RESEND-EVENT(s d) [g_object_set_qdata s resend-event-id d] +#define GET-RESEND-EVENT(s) [g_object_get_qdata s resend-event-id] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index ceee6f7725..a625737f93 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -254,6 +254,120 @@ window-delete-event: func [ EVT_DISPATCH ] +base-event-after: func [ + [cdecl] + evbox [handle!] + event [GdkEventAny!] + widget [handle!] + /local + etype [integer!] + face [red-object!] + values [red-value!] + type [red-word!] + color [red-tuple!] + offset [red-pair!] + parent [red-object!] + sym [integer!] + hparent [handle!] + pane [red-block!] + head [red-object!] + tail [red-object!] + target [handle!] + offset2 [red-pair!] + dx [float!] + dy [float!] + motion [GdkEventMotion!] + button [GdkEventButton!] + key [GdkEventKey!] + win [handle!] +][ + etype: event/type + unless any [ + etype = GDK_MOTION_NOTIFY + etype = GDK_BUTTON_PRESS + etype = GDK_2BUTTON_PRESS + etype = GDK_3BUTTON_PRESS + etype = GDK_BUTTON_RELEASE + etype = GDK_KEY_PRESS + etype = GDK_KEY_RELEASE + ][exit] + face: get-face-obj widget + values: object/get-values face + type: as red-word! values + FACE_OBJ_TYPE + color: as red-tuple! values + FACE_OBJ_COLOR + offset: as red-pair! values + FACE_OBJ_OFFSET + parent: as red-object! values + FACE_OBJ_PARENT + sym: symbol/resolve type/symbol + + if all [ + sym = base + TYPE_OF(color) = TYPE_NONE + ][ + hparent: get-face-handle parent + pane: as red-block! (object/get-values parent) + FACE_OBJ_PANE + head: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [tail > head][ + tail: tail - 1 + if tail/ctx = face/ctx [ + while [tail > head][ + tail: tail - 1 + target: face-handle? tail + if null? target [ + continue + ] + offset2: as red-pair! (object/get-values tail) + FACE_OBJ_OFFSET + case [ + etype = GDK_MOTION_NOTIFY [ + motion: as GdkEventMotion! event + dx: as float! offset/x - offset2/x + dy: as float! offset/y - offset2/y + motion/x: motion/x + dx + motion/y: motion/y + dy + motion/x_root: motion/x_root + dx + motion/y_root: motion/y_root + dy + gtk_widget_event target as handle! event + SET-RESEND-EVENT(target target) + ] + any [ + etype = GDK_BUTTON_PRESS + etype = GDK_2BUTTON_PRESS + etype = GDK_3BUTTON_PRESS + etype = GDK_BUTTON_RELEASE + ][ + button: as GdkEventButton! event + dx: as float! offset/x - offset2/x + dy: as float! offset/y - offset2/y + button/x: button/x + dx + button/y: button/y + dy + button/x_root: button/x_root + dx + button/y_root: button/y_root + dy + gtk_widget_event target as handle! event + SET-RESEND-EVENT(target target) + ] + any [ + etype = GDK_KEY_PRESS + etype = GDK_KEY_RELEASE + ][ + win: gtk_get_event_widget as handle! event + if all [ + evbox = gtk_window_get_focus win + gtk_widget_get_can_focus target + ][ + gtk_widget_grab_focus target + gtk_widget_event target as handle! event + SET-RESEND-EVENT(target target) + ] + ] + ] + exit + ] + exit + ] + ] + ] +] + window-event: func [ [cdecl] evbox [handle!] @@ -435,8 +549,13 @@ key-press-event: func [ flags [integer!] key2 [integer!] ][ - win: gtk_get_event_widget as handle! event-key - if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] + either null? GET-RESEND-EVENT(evbox) [ + win: gtk_get_event_widget as handle! event-key + if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] + ][ + SET-RESEND-EVENT(evbox null) + ] + face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -477,8 +596,12 @@ key-release-event: func [ key [integer!] flags [integer!] ][ - win: gtk_get_event_widget as handle! event-key - if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] + either null? GET-RESEND-EVENT(evbox) [ + win: gtk_get_event_widget as handle! event-key + if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] + ][ + SET-RESEND-EVENT(evbox null) + ] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE @@ -644,7 +767,11 @@ mouse-button-release-event: func [ flags [integer!] ev [integer!] ][ - if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + either null? GET-RESEND-EVENT(evbox) [ + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + ][ + SET-RESEND-EVENT(evbox null) + ] sym: get-widget-symbol widget if event/button = GDK_BUTTON_PRIMARY [ @@ -708,7 +835,11 @@ mouse-button-press-event: func [ hMenu [handle!] ev [integer!] ][ - if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + either null? GET-RESEND-EVENT(evbox) [ + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + ][ + SET-RESEND-EVENT(evbox null) + ] sym: get-widget-symbol widget if event/button = GDK_BUTTON_PRIMARY [ @@ -750,7 +881,11 @@ mouse-motion-notify-event: func [ y [float!] flags [integer!] ][ - if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + either null? GET-RESEND-EVENT(evbox) [ + if evbox <> gtk_get_event_widget as handle! event [return EVT_NO_DISPATCH] + ][ + SET-RESEND-EVENT(evbox null) + ] wflags: get-flags (as red-block! get-face-values widget) + FACE_OBJ_FLAGS if wflags and FACET_FLAGS_ALL_OVER = 0 [return EVT_DISPATCH] evt-motion/x_new: as-integer event/x From 02a006e5c47f0063d3da307ce3aedddb3ad2e052 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 18 Nov 2019 19:27:43 +0100 Subject: [PATCH 0474/3432] FEAT: [R/S] preliminary work on supporting subroutines in R/S functions. Example: bar: func [ /local i [integer!] codeA [subroutine!] codeB [subroutine!] ][ codeA: [print ["hello" 23 + i]] codeB: [probe " world"] i: 100 if true [codeA] codeB ] --- system/compiler.r | 74 ++++++++++++++++++++++++++++++++++++++---- system/emitter.r | 1 + system/targets/IA-32.r | 11 +++++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 54b02d72b5..7777177149 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -90,6 +90,8 @@ system-dialect: make-profilable context [ expr-call-stack: make block! 1 ;-- simple stack of nested calls for a given expression loop-stack: make block! 1 ;-- keep track of in-loop state locals-init: [] ;-- currently compiler function locals variable init list + subroutines: make block! 20 ;-- subroutines definitions: [name [offset ret-type] ...] + in-subroutine?: no ;-- YES: current code is in a subroutine func-name: none ;-- currently compiled function name func-locals-sz: none ;-- currently compiled function locals size on stack user-code?: no @@ -367,6 +369,7 @@ system-dialect: make-profilable context [ pos: find locals /local pos: find next pos name not find locals-init name + not in-subroutine? ] ] @@ -833,6 +836,7 @@ system-dialect: make-profilable context [ path! [resolve-path-type value] block! [ if value/1 = 'not [return get-type value/2] ;-- special case for NOT multitype native + if all [subroutines type: select subroutines value/1][return type/1] either 'op = second get-function-spec value/1 [ either base-type? type: get-return-type/check value/1 [ @@ -1430,7 +1434,7 @@ system-dialect: make-profilable context [ ) rule opt string! ] - pos: opt [/local copy locs some [pos: word! opt [into type-spec]]] ;-- local variables definition + pos: opt [/local copy locs some [pos: word! opt [into ['subroutine! | type-spec]]]] ;-- local variables definition ] ][ throw-error rejoin ["invalid definition for function " name ": " mold pos] @@ -1963,6 +1967,48 @@ system-dialect: make-profilable context [ unless binary? code [throw-error "#inline directive requires a binary! argument"] append emitter/code-buf code ] + + preprocess-subroutines: func [spec [block!] body [block!] + /local rule p type name code expr chunks chunk ret offset pos + ][ + clear subroutines + subs: clear [] + parse body rule: [ + any [ + p: set-word! block! ( + all [ + block? type: select spec to-word p/1 + 'subroutine! = type/1 + repend subroutines [to-word p/1 p/2] + remove/part p 2 + ] + ) :p + | p: block! :p into rule + | skip + ] + ] + unless empty? subroutines [ + subs: subroutines + chunks: none + pos: emitter/tail-ptr + until [ + set [name code] subs + in-subroutine?: yes + fetch-into reduce [code][ + set [expr chunk] comp-block-chunked + ret: comp-chunked [emitter/target/emit-return] + subs/2: reduce [pos get-type expr] + emitter/chunks/join chunk ret + pos: pos + length? chunk/1 + either chunks [emitter/chunks/join chunks chunk][chunks: chunk] ;-- accumulate chunks + ] + in-subroutine?: no + tail? subs: skip subs 2 + ] + offset: emitter/branch/over chunks ;-- prepend the jump at beginning + emitter/merge chunks ;-- commit all the subroutines to code buffer + ] + ] expand-setwords: has [list p lit? value out][ list: [] @@ -3057,7 +3103,7 @@ system-dialect: make-profilable context [ all [ ;-- block local function pointers block? type: select locals name type: resolve-aliased type - 'function! <> type/1 + not find [subroutine! function!] type/1 ] not block? type ;-- pass-thru ] @@ -3073,6 +3119,13 @@ system-dialect: make-profilable context [ last-type: resolve-type name unless check [also name pc: next pc] ] + all [ + locals + block? type: select locals name + type/1 = 'subroutine! + ][ + also reduce [name] pc: next pc ;-- mimic a function call + ] type: enum-type? name [ last-type: type if verbose >= 3 [print ["ENUMERATOR" name "=" last-type]] @@ -3288,6 +3341,12 @@ system-dialect: make-profilable context [ if slots [emitter/target/emit-release-stack slots] res ] + + comp-call-sub: func [expr [block!]][ + spec: select subroutines expr/1 + emitter/target/emit-call-sub expr/1 spec/1 + spec/2 + ] comp-path-assign: func [ set-path [set-path!] expr casted [block! none!] store? [logic!] @@ -3326,7 +3385,7 @@ system-dialect: make-profilable context [ throw-error [ "type mismatch on setting path:" to path! set-path "^/*** expected:" mold type - "^/*** found:" mold any [casted new] + "^/*** found:" mold any [casted new] ] ] if store? [ @@ -3413,7 +3472,7 @@ system-dialect: make-profilable context [ ] ] - comp-expression: func [expr keep? [logic!] /local variable boxed casting new? type spec store?][ + comp-expression: func [expr keep? [logic!] /local variable boxed casting new? type spec store? subrc?][ store?: no ;-- preprocessing expression @@ -3436,6 +3495,7 @@ system-dialect: make-profilable context [ expr: either any-float? boxed/type [cast/quiet expr][cast expr] if object? expr [comp-expression expr keep?] ] + subrc?: all [subroutines block? expr word? expr/1 find subroutines expr/1] ;-- subroutine call detection ;-- dead expressions elimination if all [ @@ -3464,7 +3524,7 @@ system-dialect: make-profilable context [ ;-- emitting expression code either block? expr [ - type: comp-call expr/1 next expr ;-- function call case (recursive) + type: either subrc? [comp-call-sub expr][comp-call expr/1 next expr] ;-- function call case (recursive) if type [last-type: type] ;-- set last-type if not already set ][ last-type: either not any [ @@ -3490,7 +3550,7 @@ system-dialect: make-profilable context [ ] ;-- postprocessing result - if block? expr [ ;-- if expr is a function call + if all [block? expr not subrc?][ ;-- if expr is a function call all [ variable 'value = last last-type ;-- for a struct passed by value @@ -3529,6 +3589,7 @@ system-dialect: make-profilable context [ not variable block? expr word? expr/1 + not subrc? any-float? get-return-type/check expr/1 any [ not find functions/(expr/1)/4 return-def ;-- clean if no return value @@ -3713,6 +3774,7 @@ system-dialect: make-profilable context [ func-name: name set [args-sz local-sz] emitter/enter name locals ;-- build function prolog func-locals-sz: local-sz + preprocess-subroutines spec body pc: body expr: comp-dialect ;-- compile function's body diff --git a/system/emitter.r b/system/emitter.r index bf971862d2..b4f13d40fd 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -48,6 +48,7 @@ emitter: make-profilable context [ c-string! 4 - ;-- 32-bit, 8 for 64-bit struct! 4 - ;-- 32-bit, 8 for 64-bit ; struct! passed by reference function! 4 - ;-- 32-bit, 8 for 64-bit + subroutine! 4 - ;-- 32-bit, 8 for 64-bit ] datatype-ID: [ diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index e573a2c5a0..ad2027eaf2 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -2041,6 +2041,17 @@ make-profilable make target-class [ ] ] + emit-return: does [ + if verbose >= 3 [print ">>>emitting RET from subroutine"] + emit #{C3} ;-- RET + ] + + emit-call-sub: func [name [word!] offset [integer!]][ + if verbose >= 3 [print [">>>emitting CALL subroutine" name]] + emit #{E8} ;-- CALL NEAR disp + emit to-bin32 offset - emitter/tail-ptr ;-- 32-bit relative displacement + ] + emit-cdecl-pop: func [spec [block!] args [block!] /local size slots][ size: emitter/arguments-size? spec/4 if all [ From e2fc9d22f31230a62282d5c5111e5d36d82877a0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 19 Nov 2019 16:52:40 +0100 Subject: [PATCH 0475/3432] FEAT: [R/S] completes subroutines support. --- system/compiler.r | 15 +++++++++------ system/emitter.r | 7 +++++++ system/targets/ARM.r | 25 ++++++++++++++++++++++++- system/targets/IA-32.r | 10 +++++++--- system/targets/target-class.r | 5 +++-- 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 7777177149..985931c376 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -836,7 +836,7 @@ system-dialect: make-profilable context [ path! [resolve-path-type value] block! [ if value/1 = 'not [return get-type value/2] ;-- special case for NOT multitype native - if all [subroutines type: select subroutines value/1][return type/1] + if all [subroutines type: select subroutines value/1][return type/2] either 'op = second get-function-spec value/1 [ either base-type? type: get-return-type/check value/1 [ @@ -1995,9 +1995,11 @@ system-dialect: make-profilable context [ set [name code] subs in-subroutine?: yes fetch-into reduce [code][ - set [expr chunk] comp-block-chunked - ret: comp-chunked [emitter/target/emit-return] - subs/2: reduce [pos get-type expr] + chunk: comp-chunked [emitter/target/emit-init-sub] + set [expr body] comp-block-chunked ;-- compiles subroutine's body + emitter/chunks/join chunk body + ret: comp-chunked [emitter/target/emit-return-sub] + subs/2: reduce [pos get-type expr make block! 4] ;-- [start-ptr type [call-sites]] emitter/chunks/join chunk ret pos: pos + length? chunk/1 either chunks [emitter/chunks/join chunks chunk][chunks: chunk] ;-- accumulate chunks @@ -3344,7 +3346,7 @@ system-dialect: make-profilable context [ comp-call-sub: func [expr [block!]][ spec: select subroutines expr/1 - emitter/target/emit-call-sub expr/1 spec/1 + emitter/target/emit-call-sub expr/1 spec spec/2 ] @@ -3798,11 +3800,12 @@ system-dialect: make-profilable context [ ] emitter/leave name locals args-sz local-sz ret ;-- build function epilog remove-func-pointers + unless empty? subroutines [emitter/resolve-subrc-points subroutines] clear locals-init locals: func-name: func-locals-sz: none ] - comp-natives: does [ + comp-natives: does [ foreach [name spec body origin ns nss user?] natives [ if verbose >= 2 [ print [ diff --git a/system/emitter.r b/system/emitter.r index b4f13d40fd..a7d0cdabe0 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -785,6 +785,13 @@ emitter: make-profilable context [ foreach ptr exits [target/patch-jump-point code-buf ptr end] ] + resolve-subrc-points: func [subs [block!]][ + foreach [name spec] subs [ + foreach ptr spec/3 [target/patch-sub-call code-buf ptr ptr - spec/1] + ] + clear subs + ] + calc-locals-offsets: func [spec [block!] /local total var sz extra][ total: negate extra: target/locals-offset while [not tail? spec: next spec][ diff --git a/system/targets/ARM.r b/system/targets/ARM.r index 54a996447f..5187dddc7e 100644 --- a/system/targets/ARM.r +++ b/system/targets/ARM.r @@ -1838,6 +1838,12 @@ make-profilable make target-class [ emit-i32 #{e2500001} ;-- SUBS r0, r0, #1 ; update Z flag ] + patch-sub-call: func [buffer [binary!] ptr [integer!] offset [integer!]][ + change + at buffer ptr + reverse to-bin24 shift negate offset + 4 2 + ] + patch-jump-back: func [buffer [binary!] offset [integer!]][ change at buffer offset @@ -2584,6 +2590,23 @@ make-profilable make target-class [ ] ] ] + + emit-init-sub: does [ + if verbose >= 3 [print ">>>emitting INIT subroutine"] + emit-i32 #{e92d4000} ;-- PUSH {lr} + ] + + emit-return-sub: does [ + if verbose >= 3 [print ">>>emitting RET from subroutine"] + emit-i32 #{e8bd4000} ;-- POP {lr} + emit-i32 #{e1a0f00e} ;-- MOV pc, lr + ] + + emit-call-sub: func [name [word!] spec [block!]][ + if verbose >= 3 [print [">>>emitting CALL subroutine" name]] + emit-reloc-addr spec/3 + emit-i32 #{eb000000} ;-- BL + ] emit-AAPCS-header: func [ args [block!] fspec [block!] attribs [block! none!] @@ -2783,7 +2806,7 @@ make-profilable make target-class [ ] ] - patch-call: func [code-buf rel-ptr dst-ptr] [ + patch-call: func [code-buf rel-ptr dst-ptr][ ;; @@ to-bin24 change at code-buf rel-ptr diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index ad2027eaf2..9aa07a4194 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -1298,6 +1298,10 @@ make-profilable make target-class [ emit #{58} ;-- POP eax emit #{83E801} ;-- SUB eax, 1 ] + + patch-sub-call: func [buffer [binary!] ptr [integer!] offset [integer!]][ + change at buffer ptr to-bin32 negate offset + 4 - 2 + ] patch-jump-back: func [buffer [binary!] offset [integer!]][ change at buffer offset to-bin32 negate offset + 4 - 1 @@ -2041,15 +2045,15 @@ make-profilable make target-class [ ] ] - emit-return: does [ + emit-return-sub: does [ if verbose >= 3 [print ">>>emitting RET from subroutine"] emit #{C3} ;-- RET ] - emit-call-sub: func [name [word!] offset [integer!]][ + emit-call-sub: func [name [word!] spec [block!]][ if verbose >= 3 [print [">>>emitting CALL subroutine" name]] emit #{E8} ;-- CALL NEAR disp - emit to-bin32 offset - emitter/tail-ptr ;-- 32-bit relative displacement + emit-reloc-addr spec ;-- 32-bit relative displacement ] emit-cdecl-pop: func [spec [block!] args [block!] /local size slots][ diff --git a/system/targets/target-class.r b/system/targets/target-class.r index c7453b973a..b26a5f8a00 100644 --- a/system/targets/target-class.r +++ b/system/targets/target-class.r @@ -32,8 +32,9 @@ target-class: context [ emit-integer-operation: emit-float-operation: emit-throw: on-init: emit-alt-last: emit-log-b: emit-variable: emit-read-io: emit-io-write: - emit-push-all: emit-pop-all: emit-atomic-load: emit-atomic-store: - emit-atomic-math: emit-atomic-fence: none + emit-push-all: emit-pop-all: emit-atomic-load: + emit-atomic-store: emit-atomic-math: emit-atomic-fence: + emit-init-sub: emit-return-sub: emit-call-sub: none comparison-op: [= <> < > <= >=] math-op: compose [+ - * / // (to-word "%")] From 6e81e1ab014ffdf2ee0daef4ab3a5e5980103f5b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 20 Nov 2019 00:24:19 +0100 Subject: [PATCH 0476/3432] FIX: avoids infinite loop when encountering a locally defined literal array. The occurrence causing that issue is in string/trim-with. --- system/compiler.r | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 985931c376..8606bdf5ba 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1976,11 +1976,14 @@ system-dialect: make-profilable context [ parse body rule: [ any [ p: set-word! block! ( - all [ - block? type: select spec to-word p/1 - 'subroutine! = type/1 - repend subroutines [to-word p/1 p/2] - remove/part p 2 + any [ + all [ + block? type: select spec to-word p/1 + 'subroutine! = type/1 + repend subroutines [to-word p/1 p/2] + remove/part p 2 + ] + p: skip p 2 ] ) :p | p: block! :p into rule From 6a61f82bb3f18eadc4fc963777f98ad1dba0f466 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 20 Nov 2019 00:27:48 +0100 Subject: [PATCH 0477/3432] FEAT: expands grouped arguments specifications in function aliases. --- system/compiler.r | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index 8606bdf5ba..d8c9a94d32 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -2348,7 +2348,10 @@ system-dialect: make-profilable context [ throw-error ["invalid struct syntax:" mold pos] ] ] - function! [check-specs 'pointer pc/3] + function! [ + expand-func-specs pc/3 + check-specs 'pointer pc/3 + ] ] pc: skip pc 3 none From b9422d28889fc40d3395830429e6eb6185bbf05a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 20 Nov 2019 00:28:39 +0100 Subject: [PATCH 0478/3432] FEAT: reduces code by grouping arguments and locals declaration. --- runtime/lexer.reds | 147 +++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 86 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 95fc66a566..9485925cff 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -319,10 +319,7 @@ lexer: context [ cp [int-ptr!] return: [byte-ptr!] /local - state [integer!] - byte [integer!] - idx [integer!] - type [integer!] + state byte idx type [integer!] ][ state: 0 forever [ @@ -378,7 +375,7 @@ lexer: context [ mstr-flags [integer!] ;-- multiline string accumulated flags ] - scanner!: alias function! [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]] + scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number @@ -388,7 +385,7 @@ lexer: context [ min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer - throw-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] + throw-error: func [lex [state!] s e [byte-ptr!] type [integer!] /local pos [red-string!] line [red-string!] @@ -441,10 +438,8 @@ lexer: context [ alloc-slot: func [lex [state!] return: [red-value!] /local - slot [red-value!] - size [integer!] - deltaH [integer!] - deltaT [integer!] + slot [red-value!] + size deltaH deltaT [integer!] ][ size: lex/slots if lex/buffer + size <= lex/tail [ @@ -503,12 +498,11 @@ lexer: context [ lex/entry: S_START ] - close-block: func [lex [state!] s [byte-ptr!] e [byte-ptr!] type [integer!] final [integer!] + close-block: func [lex [state!] s e [byte-ptr!] type [integer!] final [integer!] return: [integer!] /local - p [red-point!] - len [integer!] - hint [integer!] + p [red-point!] + len hint [integer!] ][ p: as red-point! lex/head - 1 assert all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] @@ -539,7 +533,7 @@ lexer: context [ hint ] - decode-2: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-2: func [s e [byte-ptr!] ser [series!] return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] @@ -573,15 +567,11 @@ lexer: context [ null ] - decode-16: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-16: func [s e [byte-ptr!] ser [series!] return: [byte-ptr!] ;-- null: ok, not null: error position /local - p [byte-ptr!] - pos [byte-ptr!] - c [integer!] - index [integer!] - class [integer!] - fstate [integer!] + p pos [byte-ptr!] + c index class fstate [integer!] ][ p: as byte-ptr! ser/offset while [s < e][ @@ -606,15 +596,11 @@ lexer: context [ null ] - decode-64: func [s [byte-ptr!] e [byte-ptr!] ser [series!] + decode-64: func [s e [byte-ptr!] ser [series!] return: [byte-ptr!] ;-- null: ok, not null: error position /local - p [byte-ptr!] - c [integer!] - val [integer!] - accum [integer!] - flip [integer!] - index [integer!] + p [byte-ptr!] + val accum flip index [integer!] ][ p: as byte-ptr! ser/offset accum: 0 @@ -661,15 +647,12 @@ lexer: context [ null ] - grab-integer: func [s [byte-ptr!] e [byte-ptr!] flags [integer!] dst [int-ptr!] err [int-ptr!] + grab-integer: func [s e [byte-ptr!] flags [integer!] dst err [int-ptr!] return: [byte-ptr!] /local - p [byte-ptr!] - len [integer!] - i [integer!] - c [integer!] - neg? [logic!] - o? [logic!] + p [byte-ptr!] + len i c [integer!] + neg? o? [logic!] ][ p: s neg?: p/1 = #"-" @@ -702,12 +685,11 @@ lexer: context [ p ] - grab-digits: func [s [byte-ptr!] e [byte-ptr!] exact [integer!] max [integer!] dst [int-ptr!] err [int-ptr!] + grab-digits: func [s e [byte-ptr!] exact max [integer!] dst err [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] - i [integer!] - c [integer!] + i c [integer!] ][ if s = e [err/value: -2 return s] ;-- buffer end's reached p: s @@ -728,7 +710,7 @@ lexer: context [ p ] - grab-float: func [s [byte-ptr!] e [byte-ptr!] dst [float-ptr!] err [int-ptr!] + grab-float: func [s e [byte-ptr!] dst [float-ptr!] err [int-ptr!] return: [byte-ptr!] /local p [byte-ptr!] @@ -739,12 +721,10 @@ lexer: context [ p ] - scan-percent-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] + scan-percent-char: func [s e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] ;-- -1 if error /local - c [integer!] - c2 [integer!] - index [integer!] + c c2 index [integer!] ][ if s + 1 >= e [cp/value: -1 return s] c: 0 @@ -757,18 +737,13 @@ lexer: context [ s + 2 ] - scan-escaped-char: func [s [byte-ptr!] e [byte-ptr!] cp [int-ptr!] + scan-escaped-char: func [s e [byte-ptr!] cp [int-ptr!] return: [byte-ptr!] ;-- -1 if error /local - p [byte-ptr!] - src [byte-ptr!] - len [integer!] - c [integer!] - pos [integer!] - index [integer!] - entry [int-ptr!] - cb [byte!] - bit [byte!] + p src [byte-ptr!] + len c pos index [integer!] + entry [int-ptr!] + cb bit [byte!] ][ either s/1 = #"(" [ ;-- note: #"^(" not allowed case [ @@ -844,13 +819,13 @@ lexer: context [ p ] - scan-eof: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][] + scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][] - scan-error: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!]][ throw-error lex s e ERR_BAD_CHAR ] - scan-block-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!] ][ @@ -859,12 +834,12 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip delimiter ] - scan-block-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ close-block lex s e TYPE_BLOCK -1 lex/in-pos: e + 1 ;-- skip ] ] - scan-paren-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-paren-close: func [lex [state!] s e [byte-ptr!] flags [integer!] /local blk [red-block!] ][ @@ -875,7 +850,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ) ] - scan-string: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] /local str [red-string!] ser [series!] @@ -1039,7 +1014,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-mstring-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ if zero? lex/mstr-nest [lex/mstr-s: s] lex/mstr-nest: lex/mstr-nest + 1 lex/mstr-flags: lex/mstr-flags or flags @@ -1047,7 +1022,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip { ] - scan-mstring-close: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ lex/mstr-nest: lex/mstr-nest - 1 either zero? lex/mstr-nest [ @@ -1060,7 +1035,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip } ] - scan-word: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] type [integer!] @@ -1083,7 +1058,7 @@ lexer: context [ if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] - scan-file: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-file: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ @@ -1098,7 +1073,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-binary: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] /local bin [red-binary!] err [byte-ptr!] @@ -1137,7 +1112,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip } ] - scan-char: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] /local char [red-char!] len [integer!] @@ -1163,12 +1138,12 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip " ] - scan-map-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ open-block lex TYPE_PAREN TYPE_MAP lex/in-pos: e + 1 ;-- skip ( ] - scan-construct: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!] /local dt [red-datatype!] p [int-ptr!] @@ -1198,7 +1173,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ] ] - scan-ref-issue: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-ref-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] type [integer!] @@ -1214,7 +1189,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-percent: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] ][ @@ -1227,7 +1202,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-integer: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] return: [integer!] /local p [byte-ptr!] @@ -1283,7 +1258,7 @@ lexer: context [ i ] - scan-float: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-float: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] err [integer!] @@ -1296,7 +1271,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-float-special: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-float-special: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] p [byte-ptr!] @@ -1320,7 +1295,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-tuple: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] i [integer!] @@ -1352,7 +1327,7 @@ lexer: context [ ] - scan-date: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-date: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] me [byte-ptr!] @@ -1488,7 +1463,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-date2: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-date2: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] dt [red-date!] @@ -1588,7 +1563,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-pair: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] /local index [integer!] class [integer!] @@ -1609,7 +1584,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-time: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-time: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] mark [byte-ptr!] @@ -1649,19 +1624,19 @@ lexer: context [ time/make-at tm alloc-slot lex ] - scan-money: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-money: func [lex [state!] s e [byte-ptr!] flags [integer!]][ ;;TBD: implement this function once money! type is done throw-error lex s e ERR_BAD_CHAR ] - scan-tag: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-tag: func [lex [state!] s e [byte-ptr!] flags [integer!]][ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_TAG scan-string lex s e flags lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-url: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-url: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ @@ -1673,7 +1648,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-email: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-email: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ @@ -1683,7 +1658,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-path-open: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!] ][ @@ -1698,7 +1673,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip / ] - scan-hex: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] /local int [red-integer!] index [integer!] @@ -1721,12 +1696,12 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip h ] - scan-comment: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!]][ + scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][ ;TBD: trigger an event ] - scan-path-item: func [lex [state!] s [byte-ptr!] e [byte-ptr!] flags [integer!] + scan-path-item: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!] cp [integer!] From fe62be92768f3dea9e573e4819fedf51fa43f200 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 20 Nov 2019 18:09:25 +0100 Subject: [PATCH 0479/3432] FEAT: infinite self-recursion detection in subroutines. --- system/compiler.r | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index d8c9a94d32..09cf439045 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -91,7 +91,7 @@ system-dialect: make-profilable context [ loop-stack: make block! 1 ;-- keep track of in-loop state locals-init: [] ;-- currently compiler function locals variable init list subroutines: make block! 20 ;-- subroutines definitions: [name [offset ret-type] ...] - in-subroutine?: no ;-- YES: current code is in a subroutine + in-subroutine?: no ;-- YES|subroutine name: current code is in a subroutine func-name: none ;-- currently compiled function name func-locals-sz: none ;-- currently compiled function locals size on stack user-code?: no @@ -1996,7 +1996,7 @@ system-dialect: make-profilable context [ pos: emitter/tail-ptr until [ set [name code] subs - in-subroutine?: yes + in-subroutine?: name fetch-into reduce [code][ chunk: comp-chunked [emitter/target/emit-init-sub] set [expr body] comp-block-chunked ;-- compiles subroutine's body @@ -3132,6 +3132,9 @@ system-dialect: make-profilable context [ block? type: select locals name type/1 = 'subroutine! ][ + if name = in-subroutine? [ + throw-error ["infinite recursion in subroutine:" name] + ] also reduce [name] pc: next pc ;-- mimic a function call ] type: enum-type? name [ From 200d9121e841d302253c759f66f411ddb20e869a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 20 Nov 2019 19:12:06 +0100 Subject: [PATCH 0480/3432] FEAT: avoids compiler error on dead code processing over a subroutine call. --- system/compiler.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index 09cf439045..f0ed3f3fbe 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -3523,7 +3523,8 @@ system-dialect: make-profilable context [ 'logic! <> first get-type expr ] all [ - block? expr + block? expr + not subrc? functions/(decorate-fun expr/1)/2 = 'op ;-- math expression any [ ;-- no return value, or return value type <> logic! not type: find functions/(expr/1)/4 return-def From b074b28a3e7cd96f0be4687cbcc662f8e5e31be4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 19 Nov 2019 14:22:54 +0800 Subject: [PATCH 0481/3432] FIX: improve on-size and on-sizing view/options/flags [button][actors: context [on-resize: function [f e][print 1] on-resizing: function [f e][print 2]]][resize] --- modules/view/backends/gtk3/events.reds | 6 ++- modules/view/backends/gtk3/handlers.reds | 66 ++++++++++-------------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index cb345a2136..e838478d72 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1022,10 +1022,12 @@ connect-widget-events: func [ gobj_signal_connect(widget "draw" :base-draw widget) ] sym = window [ - gobj_signal_connect(widget "event" :window-event widget) gobj_signal_connect(widget "delete-event" :window-delete-event widget) - ;BUG (make `vid.red` failing): gtk_widget_add_events widget GDK_STRUCTURE_MASK gobj_signal_connect(widget "size-allocate" :window-size-allocate widget) + gtk_widget_add_events widget GDK_FOCUS_CHANGE_MASK + gobj_signal_connect(widget "focus-in-event" :focus-in-event widget) + gobj_signal_connect(widget "focus-out-event" :focus-out-event widget) + gobj_signal_connect(widget "configure-event" :window-configure-event widget) ] sym = slider [ gobj_signal_connect(widget "value-changed" :range-value-changed widget) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index a625737f93..deffb17e32 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -244,16 +244,6 @@ base-draw: func [ EVT_DISPATCH ] -window-delete-event: func [ - [cdecl] - widget [handle!] - return: [integer!] -][ - ;; DEBUG: print ["window-delete-event" lf] - make-event widget 0 EVT_CLOSE - EVT_DISPATCH -] - base-event-after: func [ [cdecl] evbox [handle!] @@ -368,31 +358,24 @@ base-event-after: func [ ] ] -window-event: func [ +window-delete-event: func [ + [cdecl] + widget [handle!] + return: [integer!] +][ + make-event widget 0 EVT_CLOSE + EVT_DISPATCH +] + +window-configure-event: func [ [cdecl] evbox [handle!] - event [GdkEventAny!] + event [GdkEventConfigure!] widget [handle!] return: [integer!] - /local - h [handle!] ][ - h: GET-STARTRESIZE(widget) - unless null? h [ - if event/type = 13 [ ;-- GDK_PROXIMITY_OUT - h: as handle! 1 - SET-RESIZING(widget h) - ] - if event/type = 12 [ ;-- GDK_PROXIMITY_IN - h: GET-RESIZING(widget) - unless null? h [ - make-event widget 0 EVT_SIZING - make-event widget 0 EVT_SIZE - ] - h: as handle! 0 - SET-RESIZING(widget h) - SET-STARTRESIZE(widget h) - ] + unless null? GET-STARTRESIZE(widget) [ + SET-RESIZING(widget widget) ] EVT_DISPATCH ] @@ -404,14 +387,10 @@ window-size-allocate: func [ widget [handle!] /local sz [red-pair!] - h [handle!] ][ - ;; DEBUG: print ["window-size-allocate rect: " rect/x "x" rect/y "x" rect/width "x" rect/height lf] sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - h: GET-STARTRESIZE(widget) - if null? h [ - h: as handle! 1 - SET-STARTRESIZE(widget h) + if null? GET-STARTRESIZE(widget) [ + SET-STARTRESIZE(widget widget) ] if any [ sz/x <> rect/width @@ -419,8 +398,7 @@ window-size-allocate: func [ ][ sz/x: rect/width sz/y: rect/height - h: GET-RESIZING(widget) - either null? h [ + either null? GET-RESIZING(widget) [ make-event widget 0 EVT_SIZE ][ make-event widget 0 EVT_SIZING @@ -648,6 +626,15 @@ focus-in-event: func [ type: as red-word! values + FACE_OBJ_TYPE int: as red-integer! values + FACE_OBJ_SELECTED sym: symbol/resolve type/symbol + if sym = window [ + unless null? GET-RESIZING(widget) [ + make-event widget 0 EVT_SIZING + make-event widget 0 EVT_SIZE + ] + SET-RESIZING(widget null) + SET-STARTRESIZE(widget null) + return EVT_DISPATCH + ] change-selection widget int sym make-event widget 0 EVT_FOCUS EVT_DISPATCH @@ -670,6 +657,9 @@ focus-out-event: func [ values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve type/symbol + if sym = window [ + return EVT_DISPATCH + ] make-event widget 0 EVT_UNFOCUS EVT_DISPATCH ] From d3c24cd836cf0af5849d61d5cc8317245d77d74b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 19 Nov 2019 14:29:49 +0800 Subject: [PATCH 0482/3432] FIX: small code improve --- modules/view/backends/gtk3/events.reds | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e838478d72..0e2753a74f 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -766,12 +766,10 @@ do-events: func [ msg? [logic!] list [GList!] win [handle!] - v [handle!] ][ win: find-last-window if null? win [return no] - v: as handle! 1 - SET-IN-LOOP(win v) + SET-IN-LOOP(win win) msg?: any [not no-wait? gtk_events_pending] until [ @@ -779,7 +777,7 @@ do-events: func [ unless g_type_check_instance_is_a win gtk_window_get_type [ break ] - unless as logic! GET-IN-LOOP(win) [break] + if null? GET-IN-LOOP(win) [break] no-wait? ] msg? @@ -788,11 +786,9 @@ do-events: func [ post-quit-msg: func [ /local win [handle!] - v [handle!] ][ win: find-last-window - v: as handle! 0 - SET-IN-LOOP(win v) + SET-IN-LOOP(win null) gtk_widget_queue_draw win ] From fe9b0212560787fa1445982f6e4315af8b93b20d Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 21 Nov 2019 10:34:08 +0800 Subject: [PATCH 0483/3432] FIX: support foreign input --- modules/view/backends/gtk3/handlers.reds | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index deffb17e32..7acfbbd837 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -529,6 +529,9 @@ key-press-event: func [ ][ either null? GET-RESEND-EVENT(evbox) [ win: gtk_get_event_widget as handle! event-key + unless g_type_check_instance_is_a win gtk_window_get_type [ + return EVT_DISPATCH + ] if evbox <> gtk_window_get_focus win [return EVT_NO_DISPATCH] ][ SET-RESEND-EVENT(evbox null) From cba1483d4c55a0cf0e322baac120df1a8a80fbae Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 21 Nov 2019 14:54:34 +0100 Subject: [PATCH 0484/3432] FIX: [R/S] wrong subroutines relative calling offset. --- system/compiler.r | 5 ++++- system/targets/IA-32.r | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index f0ed3f3fbe..bbbb6ef3c0 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1994,6 +1994,7 @@ system-dialect: make-profilable context [ subs: subroutines chunks: none pos: emitter/tail-ptr + chunks: emitter/chunks/empty until [ set [name code] subs in-subroutine?: name @@ -2002,16 +2003,18 @@ system-dialect: make-profilable context [ set [expr body] comp-block-chunked ;-- compiles subroutine's body emitter/chunks/join chunk body ret: comp-chunked [emitter/target/emit-return-sub] + subs/2: reduce [pos get-type expr make block! 4] ;-- [start-ptr type [call-sites]] emitter/chunks/join chunk ret pos: pos + length? chunk/1 - either chunks [emitter/chunks/join chunks chunk][chunks: chunk] ;-- accumulate chunks + emitter/chunks/join chunks chunk ;-- accumulate chunks ] in-subroutine?: no tail? subs: skip subs 2 ] offset: emitter/branch/over chunks ;-- prepend the jump at beginning emitter/merge chunks ;-- commit all the subroutines to code buffer + foreach [name spec] head subs [spec/1: spec/1 + offset] ] ] diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index 9aa07a4194..2a2b3fccbf 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -1300,7 +1300,7 @@ make-profilable make target-class [ ] patch-sub-call: func [buffer [binary!] ptr [integer!] offset [integer!]][ - change at buffer ptr to-bin32 negate offset + 4 - 2 + change at buffer ptr to-bin32 negate offset + 5 - 1 ] patch-jump-back: func [buffer [binary!] offset [integer!]][ From 425e87893dd2b53b66dc197824b76125a0308e7e Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Thu, 21 Nov 2019 21:27:18 +0300 Subject: [PATCH 0485/3432] FIX: issue #3385 (NOW silently ignores some refinements) --- runtime/natives.reds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/natives.reds b/runtime/natives.reds index 257ff80f9f..cf2bf3d872 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2472,6 +2472,12 @@ natives: context [ n [integer!] ][ #typecheck [now year month day time zone _date weekday yearday precise utc] + if all [ + any [time = -1 precise = -1] ;-- not /time/precise both + year + month + day + time + zone + _date + weekday + yearday + precise >= -7 ;-- (-9 + 2) - 2 refs at once + ][ + fire [TO_ERROR(script bad-refines)] + ] dt: as red-date! stack/arguments dt/header: TYPE_DATE From ffc1dde748ae776509337c7a6c59d7788657600a Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Thu, 21 Nov 2019 21:27:39 +0300 Subject: [PATCH 0486/3432] TESTS: for issue #3385 (NOW silently ignores some refinements) --- tests/source/units/regression-test-red.red | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..816d581238 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2781,6 +2781,30 @@ b} --assert not error? try [3151391351465.995 // 1.0] unset 'true? + --test-- "#3385" + refs3385: [utc precise time year month day yearday weekday zone date] + types3385: reduce [ + date! ;21-Nov-2019/18:14:33.1411 + time! ;18:14:33 + integer! ;2019 + integer! ;11 + integer! ;21 + integer! ;325 + integer! ;4 + time! ;0:00:00 + date! ;21-Nov-2019 + time! ;21:14:33.1411 + ] ; rest is none! + i3385: 1 + forall refs3385 [ + foreach ref3385 next refs3385 [ + path3385: as path! reduce ['now refs3385/1 ref3385] + --assert types3385/:i3385 = attempt [type? do path3385] + i3385: i3385 + 1 + ] + ] + + --test-- "#3603" bu3603: reduce [()] rest3603: none From fc36644fe78fb9bfa1993e19c847d270196e9629 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Thu, 21 Nov 2019 22:17:49 +0300 Subject: [PATCH 0487/3432] TESTS: for issue #2134 (funny time! values) --- tests/source/units/regression-test-red.red | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..7e17b16234 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2634,6 +2634,12 @@ b} ; --test-- "#2133" ; OPEN + --test-- "#2145" + --assert "0:09:00" = probe form 00:09:00 + --assert "0:01:00" = probe form 00:00:01 * 60 + t2145: 0:00:00 loop 60 [t2145: t2145 + 1] + --assert "0:01:00" = probe form t2145 + --test-- "#2136" blk2136: copy [] insert/dup blk2136 0 3 From bc5d470a12aae3e5e99eaafc39fe5b08a88cd6a0 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Thu, 21 Nov 2019 22:22:02 +0300 Subject: [PATCH 0488/3432] TESTS: partial tests for issue #3407 (time! accuracy and formatting issues) --- tests/source/units/regression-test-red.red | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 7e17b16234..26627b8ea9 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2635,10 +2635,10 @@ b} ; OPEN --test-- "#2145" - --assert "0:09:00" = probe form 00:09:00 - --assert "0:01:00" = probe form 00:00:01 * 60 + --assert "0:09:00" = form 00:09:00 + --assert "0:01:00" = form 00:00:01 * 60 t2145: 0:00:00 loop 60 [t2145: t2145 + 1] - --assert "0:01:00" = probe form t2145 + --assert "0:01:00" = form t2145 --test-- "#2136" blk2136: copy [] @@ -2787,11 +2787,6 @@ b} --assert not error? try [3151391351465.995 // 1.0] unset 'true? - --test-- "#3603" - bu3603: reduce [()] - rest3603: none - --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 - --test-- "#3362" do [ ;-- FIXME: compiler doesn't like this spec3362-1: [return 100] @@ -2803,6 +2798,20 @@ b} unset [spec3362-1 spec3362-2] ] + --test-- "#3407" + --assert "0:00:00.1" = form 0:00:01 / 10 + --assert "0:00:00.01" = form 0:00:01 / 100 + --assert "0:00:00.001" = form 0:00:01 / 1000 + --assert "0:00:00.0001" = form 0:00:01 / 10000 + --assert "0:00:00.00001" = form 0:00:01 / 100000 + --assert "0:00:00.000001" = form 0:00:01 / 1000000 + --assert "0:00:00" = form 0:00:01 / 10000000 + + --test-- "#3603" + bu3603: reduce [()] + rest3603: none + --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + --test-- "#3739" reactor3739: func [spec] [make deep-reactor! spec] s3739: reactor3739 [started: no] From 4655cb9365e2872ece01b28af6404686ecdac259 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Fri, 22 Nov 2019 16:47:40 +0300 Subject: [PATCH 0489/3432] FIX: issue #3561 (DO ANY-PATH! misbehaves) --- runtime/interpreter.reds | 2 +- runtime/natives.reds | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/interpreter.reds b/runtime/interpreter.reds index 07ef25b227..879f4377a5 100644 --- a/runtime/interpreter.reds +++ b/runtime/interpreter.reds @@ -958,7 +958,7 @@ interpreter: context [ pc: eval-path value pc end no yes sub? no ] TYPE_LIT_PATH [ - value: stack/push pc + value: either sub? [stack/push pc][stack/set-last pc] value/header: TYPE_PATH value/data3: 0 ;-- ensures args field is null pc: pc + 1 diff --git a/runtime/natives.reds b/runtime/natives.reds index 257ff80f9f..485aa7008a 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -553,7 +553,6 @@ natives: context [ TYPE_BLOCK [DO_EVAL_BLOCK] TYPE_PATH [ interpreter/eval-path arg arg arg + 1 no no no no - stack/set-last arg + 1 ] TYPE_STRING [ str: as red-string! arg From bab6b15922d4895861a7a6d55c6625a66d6ea338 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Fri, 22 Nov 2019 17:09:29 +0300 Subject: [PATCH 0490/3432] TESTS: for issue #3561 (DO ANY-PATH! misbehaves) --- tests/source/units/regression-test-red.red | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..328b42548a 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2781,11 +2781,6 @@ b} --assert not error? try [3151391351465.995 // 1.0] unset 'true? - --test-- "#3603" - bu3603: reduce [()] - rest3603: none - --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 - --test-- "#3362" do [ ;-- FIXME: compiler doesn't like this spec3362-1: [return 100] @@ -2797,6 +2792,21 @@ b} unset [spec3362-1 spec3362-2] ] + --test-- "#3561" + a: reduce ['b does [1 + 2] 'x 'y] + --assert do [3 = a/b] ;-- do[] else compiler will not eval `does [1 + 2]` + --assert 3 = do 'a/b + --assert 3 = do quote a/b + --assert 'a/b = do quote 'a/b + --assert 'y = a/x + --assert 'y = do 'a/x + --assert 'y = do quote a/x + + --test-- "#3603" + bu3603: reduce [()] + rest3603: none + --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + --test-- "#3739" reactor3739: func [spec] [make deep-reactor! spec] s3739: reactor3739 [started: no] From 6335a9d3343a909fc61679292e1446d750b3b6df Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Fri, 22 Nov 2019 17:17:41 +0300 Subject: [PATCH 0491/3432] TESTS: for issue #497 (DO doesn't evaluate path!) --- tests/source/units/regression-test-red.red | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 328b42548a..8b503aa14d 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -462,10 +462,9 @@ Red [ ; TODO: example throws strange compiler error --test-- "#497" - ; FIXME: still unsolved - ;b: [1] - ;p: 'b/1 - ;--assert equal? 1 do p + b: [1] + p: 'b/1 + --assert equal? 1 do p --test-- "#498" --assert equal? {{""}} mold mold {} From 05c2584cddd030b91422fadc1c809a815a1ab517 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 22 Nov 2019 16:11:36 +0100 Subject: [PATCH 0492/3432] FEAT: refactors partially scan-date using subroutines. --- runtime/lexer.reds | 99 ++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9485925cff..500edae4a6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1297,11 +1297,9 @@ lexer: context [ scan-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - cell [cell!] - i [integer!] - pos [integer!] - tp [byte-ptr!] - p [byte-ptr!] + cell [cell!] + i pos [integer!] + tp p [byte-ptr!] ][ cell: alloc-slot lex tp: (as byte-ptr! cell) + 4 @@ -1329,69 +1327,65 @@ lexer: context [ scan-date: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - p [byte-ptr!] - me [byte-ptr!] - m [int-ptr!] - err [integer!] - year [integer!] - month [integer!] - day [integer!] - hour [integer!] - min [integer!] - tz-h [integer!] - tz-m [integer!] - len [integer!] - ylen [integer!] - dlen [integer!] - sec [float!] - tm [float!] - sep [byte!] - time? [logic!] - TZ? [logic!] - neg? [logic!] + err year month day hour min tz-h tz-m len ylen dlen value [integer!] + do-error check-err check-all grab2 grab2r [subroutine!] + p me [byte-ptr!] + m [int-ptr!] + sec tm [float!] + time? TZ? neg? [logic!] + sep [byte!] ][ p: s err: year: month: day: hour: min: tz-h: tz-m: 0 sec: tm: 0.0 time?: TZ?: no + do-error: [throw-error lex s e TYPE_DATE] + check-err: [if err <> 0 [do-error]] + check-all: [if any [err <> 0 p = e][do-error]] + grab2: [ + p: grab-digits p e 2 2 :value :err + check-all + value + ] + grab2r: [ + p: grab-digits p e 2 2 :value :err + check-err + value + ] me: p p: grab-digits p e 0 4 :year :err + check-err ylen: as-integer p - me - if err <> 0 [throw-error lex s e TYPE_DATE] sep: p/1 either all [sep >= #"0" sep <= #"9"][ ;-- ISO dates - p: grab-digits p e 2 2 :month :err - if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] - p: grab-digits p e 2 2 :day :err - if any [err <> 0 p = e p/1 <> #"T"][throw-error lex s e TYPE_DATE] + month: grab2 + day: grab2 + if p/1 <> #"T" [do-error] time?: yes - p: grab-digits p + 1 e 2 2 :hour :err - if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] - p: grab-digits p e 2 2 :min :err - if any [err <> 0 p = e][throw-error lex s e TYPE_DATE] + p: p + 1 + hour: grab2 + min: grab2 if p/1 <> #"Z" [ p: grab-float p e :sec :err if all [p < e p/1 <> #"Z"][ TZ?: yes neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ - p: grab-digits p + 1 e 2 2 :TZ-h :err - if err <> 0 [throw-error lex s e TYPE_DATE] + TZ-h: grab2r if neg? [TZ-h: 0 - TZ-h] - p: grab-digits p e 2 2 :TZ-m :err - if err <> 0 [throw-error lex s e TYPE_DATE] + TZ-m: grab2r ][ - throw-error lex s e TYPE_DATE + do-error ] ] ] ][ - if all [sep <> #"-" sep <> #"/"][throw-error lex s e TYPE_DATE] + if all [sep <> #"-" sep <> #"/"][do-error] - ;either all [sep = #"-" ylen = 4 p/2 = #"W"][ + ;if all [sep = #"-" ylen = 4 p/2 = #"W"][ ; p: grab-digits p + 2 e 2 2 :week :err - ; if err <> 0 [throw-error lex s e TYPE_DATE] + ; if err <> 0 [do-error] ; if all [p < e p/1 = #"-"][ ; p: grab-digits p + 2 e 1 1 :wday :err ; ] @@ -1402,23 +1396,23 @@ lexer: context [ me: p while [all [me < e me/1 <> sep]][me: me + 1] len: as-integer me - p - if any [len < 3 len > 9][throw-error lex s e TYPE_DATE] ;-- invalid month name + if any [len < 3 len > 9][do-error] ;-- invalid month name m: months loop 12 [ if zero? platform/strnicmp p as byte-ptr! m/1 len [break] m: m + 1 ] - if months + 12 = m [throw-error lex s e TYPE_DATE] ;-- invalid month name + if months + 12 = m [do-error] ;-- invalid month name month: (as-integer m - months) >> 2 + 1 err: 0 p: me ] - if p/1 <> sep [throw-error lex s e TYPE_DATE] + if p/1 <> sep [do-error] p: p + 1 me: p p: grab-digits p e 0 4 :day :err ;-- could be year also + check-err dlen: as-integer p - me - if err <> 0 [throw-error lex s e TYPE_DATE] if day > year [len: day day: year year: len ylen: dlen] if all [year < 100 ylen <= 2][ ;-- expand short yy forms ylen: either year < 50 [2000][1900] @@ -1427,9 +1421,10 @@ lexer: context [ if all [p < e any [p/1 = #"/" p/1 = #"T"]][ time?: yes p: grab-digits p + 1 e 0 2 :hour :err - if any [err <> 0 p = e p/1 <> #":"][throw-error lex s e TYPE_DATE] + check-err + if p/1 <> #":" [do-error] p: grab-digits p + 1 e 0 2 :min :err - if err <> 0 [throw-error lex s e TYPE_DATE] + check-err if p < e [ if p/1 = #":" [p: grab-float p + 1 e :sec :err] if all [p < e p/1 <> #"Z"][ @@ -1437,13 +1432,13 @@ lexer: context [ either any [p/1 = #"+" neg?][ p: grab-digits p + 1 e 0 2 :TZ-h :err if neg? [TZ-h: 0 - TZ-h] - if err <> 0 [throw-error lex s e TYPE_DATE] + check-err if p < e [ if p/1 = #":" [p: p + 1] p: grab-digits p e 0 2 :TZ-m :err ] ][ - throw-error lex s e TYPE_DATE + do-error ] ] ] @@ -1457,8 +1452,8 @@ lexer: context [ hour > 23 min > 59 sec >= 60.0 all [day = 29 month = 2 not date/leap-year? year] ][ - throw-error lex s e TYPE_DATE - ] + do-error + ] date/make-at2 alloc-slot lex year month day tm tz-h tz-m time? TZ? lex/in-pos: e ;-- reset the input position to delimiter byte ] From c3a6e43e8416685b022b6dd0bd51323753c50231 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 22 Nov 2019 18:13:45 +0100 Subject: [PATCH 0493/3432] FEAT: more code refactoring in scan-date using subroutines. --- runtime/lexer.reds | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 500edae4a6..1ab28f3503 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1328,7 +1328,7 @@ lexer: context [ scan-date: func [lex [state!] s e [byte-ptr!] flags [integer!] /local err year month day hour min tz-h tz-m len ylen dlen value [integer!] - do-error check-err check-all grab2 grab2r [subroutine!] + do-error check-err check-all grab2 grab2r grab2-max [subroutine!] p me [byte-ptr!] m [int-ptr!] sec tm [float!] @@ -1353,6 +1353,12 @@ lexer: context [ check-err value ] + grab2-max: [ + p: grab-digits p + 1 e 0 2 :value :err + check-err + value + ] + me: p p: grab-digits p e 0 4 :year :err check-err @@ -1372,6 +1378,7 @@ lexer: context [ TZ?: yes neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ + p: p + 1 TZ-h: grab2r if neg? [TZ-h: 0 - TZ-h] TZ-m: grab2r @@ -1420,19 +1427,16 @@ lexer: context [ ] if all [p < e any [p/1 = #"/" p/1 = #"T"]][ time?: yes - p: grab-digits p + 1 e 0 2 :hour :err - check-err + hour: grab2-max if p/1 <> #":" [do-error] - p: grab-digits p + 1 e 0 2 :min :err - check-err + min: grab2-max if p < e [ if p/1 = #":" [p: grab-float p + 1 e :sec :err] if all [p < e p/1 <> #"Z"][ neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ - p: grab-digits p + 1 e 0 2 :TZ-h :err + TZ-h: grab2-max if neg? [TZ-h: 0 - TZ-h] - check-err if p < e [ if p/1 = #":" [p: p + 1] p: grab-digits p e 0 2 :TZ-m :err From 4deab61f61d444e9200683c6d396924b9602772b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 22 Nov 2019 18:48:20 +0100 Subject: [PATCH 0494/3432] FEAT: minor code reduction. --- system/compiler.r | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index bbbb6ef3c0..4b6495e69d 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -1969,7 +1969,7 @@ system-dialect: make-profilable context [ ] preprocess-subroutines: func [spec [block!] body [block!] - /local rule p type name code expr chunks chunk ret offset pos + /local rule p type name code expr chunks chunk ret offset base ][ clear subroutines subs: clear [] @@ -1993,7 +1993,7 @@ system-dialect: make-profilable context [ unless empty? subroutines [ subs: subroutines chunks: none - pos: emitter/tail-ptr + base: emitter/tail-ptr chunks: emitter/chunks/empty until [ set [name code] subs @@ -2001,12 +2001,10 @@ system-dialect: make-profilable context [ fetch-into reduce [code][ chunk: comp-chunked [emitter/target/emit-init-sub] set [expr body] comp-block-chunked ;-- compiles subroutine's body + subs/2: reduce [base + length? chunks/1 get-type expr make block! 4] ;-- [start-ptr type [call-sites]] emitter/chunks/join chunk body ret: comp-chunked [emitter/target/emit-return-sub] - - subs/2: reduce [pos get-type expr make block! 4] ;-- [start-ptr type [call-sites]] emitter/chunks/join chunk ret - pos: pos + length? chunk/1 emitter/chunks/join chunks chunk ;-- accumulate chunks ] in-subroutine?: no From 9943f140a202207abf01f82e08c358c6a2af4e3d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 22 Nov 2019 18:51:16 +0100 Subject: [PATCH 0495/3432] FIX: adjust the offset on subroutines calls on ARM. --- system/targets/ARM.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/targets/ARM.r b/system/targets/ARM.r index 5187dddc7e..08975ae96e 100644 --- a/system/targets/ARM.r +++ b/system/targets/ARM.r @@ -1841,7 +1841,7 @@ make-profilable make target-class [ patch-sub-call: func [buffer [binary!] ptr [integer!] offset [integer!]][ change at buffer ptr - reverse to-bin24 shift negate offset + 4 2 + reverse to-bin24 shift negate offset + 8 2 ] patch-jump-back: func [buffer [binary!] offset [integer!]][ From 8a69802a05c7ce10a12b71603b4794b2d5bec397 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 22 Nov 2019 18:52:58 +0100 Subject: [PATCH 0496/3432] FEAT: minor comments re-indenting. --- runtime/lexer.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1ab28f3503..beec2280d8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1403,13 +1403,13 @@ lexer: context [ me: p while [all [me < e me/1 <> sep]][me: me + 1] len: as-integer me - p - if any [len < 3 len > 9][do-error] ;-- invalid month name + if any [len < 3 len > 9][do-error] ;-- invalid month name m: months loop 12 [ if zero? platform/strnicmp p as byte-ptr! m/1 len [break] m: m + 1 ] - if months + 12 = m [do-error] ;-- invalid month name + if months + 12 = m [do-error] ;-- invalid month name month: (as-integer m - months) >> 2 + 1 err: 0 p: me From 372790383a6d754b414c80213efdeefd8c1e3376 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 00:06:07 +0100 Subject: [PATCH 0497/3432] FIX: [R/S] compiler now properly resolve the type of assignment expressions. Such feature is needed to determine the return type of a block of expressions in subroutines. --- system/compiler.r | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 4b6495e69d..dc960b6cc8 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -835,17 +835,18 @@ system-dialect: make-profilable context [ integer! [[integer!]] path! [resolve-path-type value] block! [ - if value/1 = 'not [return get-type value/2] ;-- special case for NOT multitype native - if all [subroutines type: select subroutines value/1][return type/2] - - either 'op = second get-function-spec value/1 [ - either base-type? type: get-return-type/check value/1 [ - type ;-- unique returned type, stop here - ][ - get-type value/2 ;-- recursively search for left operand base type + case [ + find [set-word! set-path!] type?/word value/1 [none-type] + value/1 = 'not [get-type value/2] ;-- special case for NOT multitype native + all [subroutines type: select subroutines value/1][type/2] + 'op = second get-function-spec value/1 [ + either base-type? type: get-return-type/check value/1 [ + type ;-- unique returned type, stop here + ][ + get-type value/2 ;-- recursively search for left operand base type + ] ] - ][ - get-return-type/check value/1 + 'else [get-return-type/check value/1] ] ] object! [value/type] From 23ac7c3ceefc4072aed0d6bc7369190637edac49 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 00:09:25 +0100 Subject: [PATCH 0498/3432] FEAT: completes date! support in scan-date. --- runtime/lexer.reds | 167 +++++++++++++++++++++++++-------------------- 1 file changed, 92 insertions(+), 75 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index beec2280d8..889cce90ee 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -852,22 +852,13 @@ lexer: context [ scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] /local + len unit index class digits extra cp type [integer!] str [red-string!] ser [series!] - p [byte-ptr!] - pos [byte-ptr!] + p pos [byte-ptr!] p4 [int-ptr!] - len [integer!] - unit [integer!] - index [integer!] - class [integer!] - digits [integer!] - extra [integer!] - cp [integer!] - type [integer!] - esc [byte!] + esc c [byte!] w? [logic!] - c [byte!] ][ s: s + 1 ;-- skip start delimiter len: as-integer e - s @@ -1060,7 +1051,7 @@ lexer: context [ scan-file: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - p [byte-ptr!] + p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag either s/2 = #"^"" [s: s + 1][ ;-- skip " @@ -1078,9 +1069,7 @@ lexer: context [ bin [red-binary!] err [byte-ptr!] ser [series!] - len [integer!] - size [integer!] - base [integer!] + len size base [integer!] ][ either s/1 = #"#" [base: 16][ ;-- default base base: 0 @@ -1115,8 +1104,7 @@ lexer: context [ scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] /local char [red-char!] - len [integer!] - c [integer!] + len c [integer!] ][ assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] len: as-integer e - s @@ -1146,10 +1134,8 @@ lexer: context [ scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!] /local dt [red-datatype!] - p [int-ptr!] - dtypes [int-ptr!] - end [int-ptr!] len [integer!] + p dtypes end [int-ptr!] ][ s: s + 2 ;-- skip #[ p: cons-syntax @@ -1205,10 +1191,9 @@ lexer: context [ scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] return: [integer!] /local - p [byte-ptr!] - len [integer!] - i [integer!] - o? [logic!] + p [byte-ptr!] + len i [integer!] + o? [logic!] ][ p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present @@ -1327,16 +1312,21 @@ lexer: context [ scan-date: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - err year month day hour min tz-h tz-m len ylen dlen value [integer!] - do-error check-err check-all grab2 grab2r grab2-max [subroutine!] - p me [byte-ptr!] - m [int-ptr!] - sec tm [float!] - time? TZ? neg? [logic!] - sep [byte!] + err year month day hour min tz-h tz-m len ylen dlen value + week wday yday [integer!] + do-error check-err check-all grab2 grab2r grab2-max grab-time-TZ + store-date grab4 [subroutine!] + dt [red-date!] + p me [byte-ptr!] + m [int-ptr!] + sec tm [float!] + time? TZ? neg? [logic!] + sep [byte!] ][ p: s - err: year: month: day: hour: min: tz-h: tz-m: 0 + dt: null + me: null + err: year: month: day: hour: min: tz-h: tz-m: week: wday: yday: 0 sec: tm: 0.0 time?: TZ?: no @@ -1358,10 +1348,41 @@ lexer: context [ check-err value ] + grab4: [ + me: p + p: grab-digits p e 0 4 :value :err + check-err + value + ] + grab-time-TZ: [ + time?: yes + hour: grab2-max + if p/1 <> #":" [do-error] + min: grab2-max + if p < e [ + if p/1 = #":" [p: grab-float p + 1 e :sec :err] + if all [p < e p/1 <> #"Z"][ + neg?: p/1 = #"-" + either any [p/1 = #"+" neg?][ + TZ-h: grab2-max + if neg? [TZ-h: 0 - TZ-h] + if p < e [ + if p/1 = #":" [p: p + 1] + p: grab-digits p e 0 2 :TZ-m :err + ] + ][ + do-error + ] + ] + ] + tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec + ] + store-date: [ + dt: date/make-at2 alloc-slot lex year month day tm tz-h tz-m time? TZ? + lex/in-pos: e ;-- reset the input position to delimiter byte + ] - me: p - p: grab-digits p e 0 4 :year :err - check-err + year: grab4 ylen: as-integer p - me sep: p/1 either all [sep >= #"0" sep <= #"9"][ ;-- ISO dates @@ -1388,17 +1409,39 @@ lexer: context [ ] ] ][ - if all [sep <> #"-" sep <> #"/"][do-error] - - ;if all [sep = #"-" ylen = 4 p/2 = #"W"][ - ; p: grab-digits p + 2 e 2 2 :week :err - ; if err <> 0 [do-error] - ; if all [p < e p/1 = #"-"][ - ; p: grab-digits p + 2 e 1 1 :wday :err - ; ] - ;] + either sep = #"-" [ + if all [ylen = 4 p/2 = #"W"][ + day: month: 1 + p: p + 2 + week: grab2r + if all [p < e p/1 = #"-"][ + p: grab-digits p + 1 e 1 1 :wday :err + ] + if all [p < e p/1 = #"T"][grab-time-TZ] + store-date + if week or wday <> 0 [date/set-isoweek dt week] ;-- yyyy-Www + if wday <> 0 [ + if any [wday < 1 wday > 7][do-error] + date/set-weekday dt wday ;-- yyyy-Www-d + ] + exit + ] + me: p + 1 + p: grab-digits me e 0 3 :month :err + if all [zero? err 3 = as-integer p - me][ + if zero? month [do-error] + yday: month + day: month: 1 + if all [p < e p/1 = #"T"][grab-time-TZ] + store-date + date/set-yearday dt yday ;-- yyyy-ddd + exit + ] + ][ + if sep <> #"/" [do-error] + p: grab-digits p + 1 e 0 2 :month :err + ] - p: grab-digits p + 1 e 0 2 :month :err if err <> 0 [ me: p while [all [me < e me/1 <> sep]][me: me + 1] @@ -1416,40 +1459,15 @@ lexer: context [ ] if p/1 <> sep [do-error] p: p + 1 - me: p - p: grab-digits p e 0 4 :day :err ;-- could be year also - check-err + day: grab4 ;-- could be year also dlen: as-integer p - me if day > year [len: day day: year year: len ylen: dlen] if all [year < 100 ylen <= 2][ ;-- expand short yy forms ylen: either year < 50 [2000][1900] year: year + ylen ] - if all [p < e any [p/1 = #"/" p/1 = #"T"]][ - time?: yes - hour: grab2-max - if p/1 <> #":" [do-error] - min: grab2-max - if p < e [ - if p/1 = #":" [p: grab-float p + 1 e :sec :err] - if all [p < e p/1 <> #"Z"][ - neg?: p/1 = #"-" - either any [p/1 = #"+" neg?][ - TZ-h: grab2-max - if neg? [TZ-h: 0 - TZ-h] - if p < e [ - if p/1 = #":" [p: p + 1] - p: grab-digits p e 0 2 :TZ-m :err - ] - ][ - do-error - ] - ] - ] - ] + if all [p < e any [p/1 = #"/" p/1 = #"T"]][grab-time-TZ] ] - if time? [tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec] - if any [ day > 31 month > 12 year > 9999 year < -9999 tz-h > 15 tz-h < -15 ;-- out of range TZ @@ -1458,8 +1476,7 @@ lexer: context [ ][ do-error ] - date/make-at2 alloc-slot lex year month day tm tz-h tz-m time? TZ? - lex/in-pos: e ;-- reset the input position to delimiter byte + store-date ] scan-date2: func [lex [state!] s e [byte-ptr!] flags [integer!] From abbe54c48fcf9c04c5989ee461f95486257197c8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 10:51:46 +0100 Subject: [PATCH 0499/3432] FEAT: adding some comments to scan-date. --- runtime/lexer.reds | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 889cce90ee..34fd46fe3b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1333,22 +1333,22 @@ lexer: context [ do-error: [throw-error lex s e TYPE_DATE] check-err: [if err <> 0 [do-error]] check-all: [if any [err <> 0 p = e][do-error]] - grab2: [ + grab2: [ ;-- grab int from 2 digits exactly p: grab-digits p e 2 2 :value :err - check-all + check-all ;-- bound error check value ] - grab2r: [ + grab2r: [ ;-- grab int from 2 digits exactly p: grab-digits p e 2 2 :value :err - check-err + check-err ;-- just check int err value ] - grab2-max: [ + grab2-max: [ ;-- grab int from 2 digits max p: grab-digits p + 1 e 0 2 :value :err check-err value ] - grab4: [ + grab4: [ ;-- grab int from 4 digits max me: p p: grab-digits p e 0 4 :value :err check-err @@ -1382,23 +1382,23 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - year: grab4 + year: grab4 ;-- year or day ylen: as-integer p - me sep: p/1 either all [sep >= #"0" sep <= #"9"][ ;-- ISO dates month: grab2 day: grab2 - if p/1 <> #"T" [do-error] + if p/1 <> #"T" [do-error] ;-- yyyymmddT... time?: yes p: p + 1 hour: grab2 min: grab2 - if p/1 <> #"Z" [ + if p/1 <> #"Z" [ ;-- yyymmddThhmmZ p: grab-float p e :sec :err if all [p < e p/1 <> #"Z"][ TZ?: yes neg?: p/1 = #"-" - either any [p/1 = #"+" neg?][ + either any [p/1 = #"+" neg?][ ;-- yyymmddThhmm+-hhmm p: p + 1 TZ-h: grab2r if neg? [TZ-h: 0 - TZ-h] @@ -1410,19 +1410,19 @@ lexer: context [ ] ][ either sep = #"-" [ - if all [ylen = 4 p/2 = #"W"][ + if all [ylen = 4 p/2 = #"W"][ ;-- yyyy-Www day: month: 1 p: p + 2 week: grab2r - if all [p < e p/1 = #"-"][ + if all [p < e p/1 = #"-"][ ;-- yyyy-Www-d p: grab-digits p + 1 e 1 1 :wday :err ] if all [p < e p/1 = #"T"][grab-time-TZ] store-date - if week or wday <> 0 [date/set-isoweek dt week] ;-- yyyy-Www + if week or wday <> 0 [date/set-isoweek dt week] if wday <> 0 [ if any [wday < 1 wday > 7][do-error] - date/set-weekday dt wday ;-- yyyy-Www-d + date/set-weekday dt wday ] exit ] @@ -1439,10 +1439,10 @@ lexer: context [ ] ][ if sep <> #"/" [do-error] - p: grab-digits p + 1 e 0 2 :month :err + p: grab-digits p + 1 e 0 2 :month :err ;-- yy/mm or dd/mm ] - if err <> 0 [ + if err <> 0 [ ;-- try to match a month name me: p while [all [me < e me/1 <> sep]][me: me + 1] len: as-integer me - p @@ -1454,14 +1454,14 @@ lexer: context [ ] if months + 12 = m [do-error] ;-- invalid month name month: (as-integer m - months) >> 2 + 1 - err: 0 + err: 0 ;-- reset eventual error from int month grabing p: me ] if p/1 <> sep [do-error] p: p + 1 day: grab4 ;-- could be year also dlen: as-integer p - me - if day > year [len: day day: year year: len ylen: dlen] + if day > year [len: day day: year year: len ylen: dlen] ;-- swap day<=>year if all [year < 100 ylen <= 2][ ;-- expand short yy forms ylen: either year < 50 [2000][1900] year: year + ylen From 637413faf7c669e9a55359b37580b89e6d6cd1a9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 11:01:13 +0100 Subject: [PATCH 0500/3432] FEAT: minor code reduction in scan-time. --- runtime/lexer.reds | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 34fd46fe3b..4e0cb7b0ab 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1602,37 +1602,34 @@ lexer: context [ scan-time: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - p [byte-ptr!] - mark [byte-ptr!] - err [integer!] - hour [integer!] - min [integer!] - len [integer!] - tm [float!] + err hour min len [integer!] + p mark [byte-ptr!] + tm [float!] + do-error [subroutine!] ][ p: s - err: 0 - hour: 0 + err: hour: 0 + do-error: [throw-error lex s e TYPE_TIME] p: grab-integer p e flags :hour :err - if any [err <> 0 p/1 <> #":"][throw-error lex s e TYPE_TIME] + if any [err <> 0 p/1 <> #":"][do-error] p: p + 1 min: 0 mark: p p: grab-integer p e flags :min :err - if any [err <> 0 min < 0][throw-error lex s e TYPE_TIME] + if any [err <> 0 min < 0][do-error] p: p + 1 if p < e [ - if any [all [p/0 <> #"." p/0 <> #":"] flags and C_FLAG_EXP <> 0][throw-error lex s e TYPE_TIME] + if any [all [p/0 <> #"." p/0 <> #":"] flags and C_FLAG_EXP <> 0][do-error] if p/0 = #"." [ min: hour hour: 0 p: mark ] tm: dtoa/to-float p e :err - if any [err <> 0 tm < 0.0][throw-error lex s e TYPE_TIME] + if any [err <> 0 tm < 0.0][do-error] ] tm: (3600.0 * as-float hour) + (60.0 * as-float min) + tm @@ -1886,13 +1883,6 @@ lexer: context [ transitions: transitions + 1 skip-table: skip-table + 1 line-table: line-table + 1 - - date-classes: date-classes + 1 - date-transitions: date-transitions + 1 - date-cumul: date-cumul + 1 - fields-table: fields-table + 1 - fields-ptr-table: fields-ptr-table + 1 - reset-table: reset-table + 1 ] ] \ No newline at end of file From 31a7df85dbb51959f1748d7dea37a296f82e3f05 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 11:05:44 +0100 Subject: [PATCH 0501/3432] FEAT: removes date! scanning FSM. It's replaced by regular code scan-date, which provides faster performance. --- docs/lexer/date-FSM.csv | 48 ------------ docs/lexer/lexer-FSM.xlsx | Bin 26946 -> 21955 bytes docs/lexer/lexer-states.txt | 133 ------------------------------- runtime/lexer-transitions.reds | 91 +-------------------- runtime/lexer.reds | 139 +-------------------------------- utils/generate-lexer-table.red | 132 +------------------------------ utils/generate-misc-tables.red | 63 --------------- 7 files changed, 3 insertions(+), 603 deletions(-) delete mode 100644 docs/lexer/date-FSM.csv diff --git a/docs/lexer/date-FSM.csv b/docs/lexer/date-FSM.csv deleted file mode 100644 index fdb39c5b19..0000000000 --- a/docs/lexer/date-FSM.csv +++ /dev/null @@ -1,48 +0,0 @@ -;C_DT_DIGIT;C_DT_LETTER;C_DT_SLASH;C_DT_DASH;C_DT_T;C_DT_W;C_DT_PLUS;C_DT_COLON;C_DT_DOT;C_DT_Z;C_DT_ILLEGAL;C_DT_EOF -S_DT_START;S_DT_D;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_D;S_DT_DD;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_DD;S_DT_YYY;T_DT_ERROR;F_DT_DAYL;F_DT_DAYL;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YYY;S_DT_YYYY;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YYYY;S_DT_YM;T_DT_ERROR;F_DT_YEARL;F_DT_YEARL2;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YEARL;S_DT_YM;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YEARL2;S_DT_YM2;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;S_DT_YMON;S_DT_YV;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DAYL;S_DT_DM;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YM;S_DT_YMM;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YMM;F_DT_YMD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YM2;S_DT_YMM2;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YMM2;F_DT_DDD;T_DT_ERROR;F_DT_YMONTH;F_DT_YMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YMONTH;F_DT_YMD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DDD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YDDD -S_DT_YV;S_DT_YW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_YW;S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK -S_DT_YWW;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_DT_YWD;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_WEEK -S_DT_YWD;S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_WD;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YWWD -S_DT_YMON;T_DT_ERROR;S_DT_YMON;F_DT_YMONTH;F_DT_YMONTH;S_DT_YMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_YMD;F_DT_YMDD;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY -F_DT_YMDD;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_YMDAY -S_DT_DM;S_DT_DMM;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_DMM;T_DT_ERROR;T_DT_ERROR;F_DT_DMONTH;F_DT_DMONTH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DMONTH;F_DT_DMY;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_DT_DMON;T_DT_ERROR;S_DT_DMON;F_DT_DMONTH;F_DT_DMONTH;S_DT_DMON;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_DT_DMY;F_DT_DMYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYY;F_DT_DMYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYY;F_DT_DMYYYY;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -F_DT_DMYYYY;T_DT_ERROR;T_DT_ERROR;S_TM_START;T_DT_ERROR;S_TM_START;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_DMYEAR -S_TM_START;F_TM_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_H;F_TM_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_HH;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_TM_HM;F_TM_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_M;F_TM_MM;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HM -F_TM_MM;F_TM_S;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;S_TM_HMS;T_DT_ERROR;T_TM_HM;T_DT_ERROR;T_TM_HM -S_TM_HMS;F_TM_S;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_S;F_TM_SS;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TM_HMS -F_TM_SS;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;F_TM_N1;T_TM_HMS;T_DT_ERROR;T_TM_HMS -F_TM_N1;F_TM_N;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -F_TM_N;F_TM_N;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;S_TM_HMZ;T_DT_ERROR;T_DT_ERROR;T_TM_NZ;T_DT_ERROR;T_TM_NZ -S_TM_HMZ;S_TZ_H;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR -S_TZ_H;F_TZ_HH;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_H -F_TZ_HH;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;F_TZ_HM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_HH -F_TZ_HM;S_TZ_M;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_M -S_TZ_M;T_TZ_MM;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_TZ_MM -T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR;T_DT_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 0b3639a9b020d11490dfcd73b656ddf763298654..32291137860f8501c2617eb352d9fc02e959aaea 100644 GIT binary patch literal 21955 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

72)b;gl0CF=_{^- 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 literal 26946 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 \->","|"#"|"%"->T_ERROR -=== Date FSM === - -S_DT_START -S_DT_D -S_DT_DD -S_DT_YYY -S_DT_YYYY -F_DT_YEARL -F_DT_YEAR2 -F_DT_DAYL -S_DT_YM -S_DT_YMM -F_DT_YMONTH -F_DT_DDD -S_DT_YV -S_DT_YW -S_DT_YWW -S_DT_WD -S_DT_YMON -F_DT_YMD -F_DT_YMDD -S_DT_DM -S_DT_DMM -F_DT_DMONTH -S_DT_DMON -F_DT_DMY -F_DT_DMYY -F_DT_DMYYY -F_DT_DMYYYY -S_TM_START -F_TM_H -F_TM_HH -S_TM_HM -F_TM_M -F_TM_MM -S_TM_HMS -F_TM_S -F_TM_SS -F_TM_N1 -F_TM_N -S_TZ_START -S_TZ_H -F_TZ_HH -F_TZ_HM -S_TZ_M ---FINAL-STATES-- -T_DT_ERROR -T_DT_YMDAY -T_DT_DMYEAR -T_DT_WEEK -T_DT_YWWD -T_TM_NZ -T_TZ_H -T_TZ_HH -T_TZ_M -T_TZ_MM - -C_DT_DIGIT 0-9 -C_DT_LETTER abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY -C_DT_SLASH / -C_DT_DASH - -C_DT_T T -C_DT_W W -C_DT_PLUS + -C_DT_COLON : -C_DT_DOT . -C_DT_Z Z -C_DT_ILLEGAL all the rest -C_DT_EOF EOF - -sep: / | - -dtsep: / | T -digit: 0-9 -letter: abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY -sign: + | - -eof: EOF - -S_DT_START->digit->S_DT_D->digit->S_DT_DD->digit->S_DT_YYY->digit->S_DT_YYYY->"/"->F_DT_YEARL - \ \ \ \->"-"->F_DT_YEARL2 - \ \ \->sep->F_DT_YEARL - \ \->sep->F_DT_DAYL - \->sep->F_DT_DAYL - -F_DT_YEARL->digit->S_DT_YM->digit->S_DT_YMM->sep->F_DT_YMONTH - \ \->sep->F_DT_YMONTH - \->letter->S_DT_YMON->letter->S_DT_YMON - \->sep->F_DT_YMONTH - -F_DT_YEARL2->digit->S_DT_YM2->digit->S_DT_YMM2->sep->F_DT_YMONTH - \ \ \->digit->F_DT_DDD - \ \->sep->F_DT_YMONTH - \->letter->S_DT_YMON - \->"W"->S_DT_YV->digit->S_DT_YW->digit->S_DT_YWW->eof->T_DT_WEEK - \->"-"->S_DT_YWD->digit->S_DT_WD->eof->T_DT_YWWD - \ \->"T"->S_TM_START - \->"T"->S_TM_START - -F_DT_DDD->"T"->S_TM_START - -F_DT_YMONTH->digit->F_DT_YMD->digit->F_DT_YMDD->dtsep->S_TM_START - \->dtsep->S_TM_START - -F_DT_DAYL->digit->S_DT_DM->digit->S_DT_DMM->sep->F_DT_DMONTH - \ \->sep->F_DT_DMONTH - \->letter->S_DT_DMON->letter->S_DT_DMON - \->sep->F_DT_DMONTH - -F_DT_DMONTH->digit->F_DT_DMY->digit->F_DT_DMYY->digit->F_DT_DMYYY->digit->F_DT_DMYYYY->dtsep->S_TM_START - \ \ \->dtsep->S_TM_START - \ \->dtsep->S_TM_START - \->dtsep->S_TM_START - -S_TM_START->digit->F_TM_H->digit->F_TM_HH->":"->S_TM_HM - \->digit->F_TM_M - -S_TM_HM->digit->F_TM_M->digit->F_TM_MM->":"->S_TM_HMS - \->digit->F_TM_S - -S_TM_HMS->digit->F_TM_S->digit->F_TM_SS->"."->F_TM_N1->digit->F_TM_N->digit->F_TM_N - \ \->"Z"|eof->T_TM_NZ - \ \->sign->S_TZ_START - \->sign->S_TZ_START - -S_TZ_START->digit->S_TZ_H->digit->F_TZ_HH->":"->F_TZ_HM - \ \->eof->T_TZ_HH - \->":"->F_TZ_HM - \->eof->T_TZ_H - -F_TZ_HM->digit->S_TZ_M->digit->T_TZ_MM - \->eof->T_TZ_M - - - === Binary16 FSM === diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 2c1313aede..c7c8cd28d9 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -87,96 +87,7 @@ Red/System [ T_PATH T_HEX T_CMT - ] #enum date-states! [ - S_DT_START - S_DT_D - S_DT_DD - S_DT_YYY - S_DT_YYYY - F_DT_YEARL - F_DT_YEARL2 - F_DT_DAYL - S_DT_YM - S_DT_YMM - S_DT_YM2 - S_DT_YMM2 - F_DT_YMONTH - F_DT_DDD - S_DT_YV - S_DT_YW - S_DT_YWW - S_DT_YWD - S_DT_WD - S_DT_YMON - F_DT_YMD - F_DT_YMDD - S_DT_DM - S_DT_DMM - F_DT_DMONTH - S_DT_DMON - F_DT_DMY - F_DT_DMYY - F_DT_DMYYY - F_DT_DMYYYY - S_TM_START - F_TM_H - F_TM_HH - S_TM_HM - F_TM_M - F_TM_MM - S_TM_HMS - F_TM_S - F_TM_SS - F_TM_N1 - F_TM_N - S_TM_HMZ - S_TZ_H - F_TZ_HH - F_TZ_HM - S_TZ_M - T_DT_ERROR - T_DT_YMDAY - T_DT_DMYEAR - T_DT_YDDD - T_DT_YWWD - T_DT_WEEK - T_TM_HM - T_TM_HMS - T_TM_NZ - T_TZ_H - T_TZ_HH - T_TZ_M - T_TZ_MM - ] - fields-ptr-table: #{ -01010101010E0E0E01010101100101010101010F01010101100F010101010101 -010101010101010101110101010101010101010101010101010101 -} fields-table: #{ -040404020201010103030303010D0B0B0B010C03040403030103020202020105 -050106060107070108010909010A01010101010101010809090A0A -} reset-table: #{ -0101010100000000010001010000000101000101010001000001010101000001 -000001000001000001000100000100000000000000000000000000 -} date-transitions: #{ -012E2E2E2E2E2E2E2E2E2E2E022E07072E2E2E2E2E2E2E2E032E07072E2E2E2E -2E2E2E2E042E05062E2E2E2E2E2E2E2E082E05062E2E2E2E2E2E2E2E08132E2E -132E2E2E2E2E2E2E0A132E2E130E2E2E2E2E2E2E16192E2E2E2E2E2E2E2E2E2E -092E0C0C2E2E2E2E2E2E2E2E142E0C0C2E2E2E2E2E2E2E2E0B2E0C0C2E2E2E2E -2E2E2E2E0D2E0C0C2E2E2E2E2E2E2E2E142E2E2E2E2E2E2E2E2E2E2E2E2E2E2E -1E2E2E2E2E2E2E310F2E2E2E2E2E2E2E2E2E2E2E102E2E2E2E2E2E2E2E2E2E33 -2E2E2E111E2E2E2E2E2E2E33122E2E2E1E2E2E2E2E2E2E2E2E2E2E2E1E2E2E2E -2E2E2E322E130C0C132E2E2E2E2E2E2E152E1E2E1E2E2E2E2E2E2E2F2E2E1E2E -1E2E2E2E2E2E2E2F172E18182E2E2E2E2E2E2E2E2E2E18182E2E2E2E2E2E2E2E -1A2E2E2E2E2E2E2E2E2E2E2E2E191818192E2E2E2E2E2E2E1B2E1E2E1E2E2E2E -2E2E2E301C2E1E2E1E2E2E2E2E2E2E301D2E1E2E1E2E2E2E2E2E2E302E2E1E2E -1E2E2E2E2E2E2E301F2E2E2E2E2E2E2E2E2E2E2E202E2E2E2E2E2E212E2E2E2E -222E2E2E2E2E2E212E2E2E2E222E2E2E2E2E2E2E2E2E2E2E232E2E292E2E2924 -2E2E2E34252E2E292E2E29242E342E34252E2E2E2E2E2E2E2E2E2E2E262E2E29 -2E2E292E2E2E2E352E2E2E292E2E292E27352E35282E2E2E2E2E2E2E2E2E2E2E -282E2E292E2E292E2E362E362A2E2E2E2E2E2E2E2E2E2E2E2B2E2E2E2E2E2E2C -2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E -2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E -} transitions: #{ + ] transitions: #{ 000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B2B06360136291E 2828362B2B363501540101010101010101010101010101010101010101010101 0101010101010101010101013635020202020202020202023B02020202020202 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4e0cb7b0ab..8cb671536b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -79,22 +79,7 @@ lexer: context [ C_ILLEGAL ;-- 37 C_EOF ;-- 38 ] - - #enum date-char-classes! [ - C_DT_DIGIT ;-- 0 - C_DT_LETTER ;-- 1 - C_DT_SLASH ;-- 2 - C_DT_DASH ;-- 3 - C_DT_T ;-- 4 - C_DT_W ;-- 5 - C_DT_PLUS ;-- 6 - C_DT_COLON ;-- 7 - C_DT_DOT ;-- 8 - C_DT_Z ;-- 9 - C_DT_ILLEGAL ;-- 10 - C_DT_EOF ;-- 11 - ] - + #enum bin16-char-classes! [ C_BIN_SKIP ;-- 0 C_BIN_BLANK ;-- 1 @@ -182,28 +167,6 @@ lexer: context [ "January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December" ] - - date-cumul: #{ - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000010203040506070809000000000000 - 004142434445464748494A004C4D4E4F50005253005556000003000000000000 - 004142434445464748494A004C4D4E4F50005253005556000003000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - } - - date-classes: #{ - 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A - 0A0A0A0A0A0A0A0A0A0A0A060A03080200000000000000000000070A0A0A0A0A - 0A010101010101010101010A01010101010A0101040101050A01090A0A0A0A0A - 0A010101010101010101010A01010101010A01010101010A0A010A0A0A0A0A0A - 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A - 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A - 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A - 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A - } lex-classes: [ (C_EOF or C_FLAG_EOF) ;-- 00 NUL @@ -1478,106 +1441,6 @@ lexer: context [ ] store-date ] - - scan-date2: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - cell [cell!] - dt [red-date!] - df [lexer-dt-array!] - b [byte-ptr!] - p [byte-ptr!] - me [byte-ptr!] - m [int-ptr!] - field [int-ptr!] - type [integer!] - state [integer!] - class [integer!] - index [integer!] - cp [integer!] - c [integer!] - pos [integer!] - len [integer!] - neg? [logic!] - ][ - c: 0 ;-- accumulator (fields decoding) - b: s - field: system/stack/allocate/zero 17 ;-- date/time fields array - state: S_DT_START - - loop as-integer e - s [ - cp: as-integer s/1 - class: as-integer date-classes/cp - index: state * (size? date-char-classes!) + class - state: as-integer date-transitions/index - c: c * 10 + as-integer date-cumul/cp - pos: as-integer fields-table/state - field/pos: c - pos: as-integer fields-ptr-table/state - field/pos: as-integer s - if null-byte = reset-table/state [c: 0] - s: s + 1 - ] - if state <= T_DT_ERROR [ ;-- if no terminal state reached, forces EOF input - if state = T_DT_ERROR [throw-error lex b e TYPE_DATE] - index: state * (size? date-char-classes!) + C_DT_EOF - state: as-integer date-transitions/index - pos: as-integer fields-table/state - field/pos: c - ] - df: as lexer-dt-array! field + 1 - - p: as byte-ptr! df/TZ-sign - neg?: all [p <> null p/1 = #"-"] ;-- detect negative TZ - cell: alloc-slot lex - - either df/week or df/wday or df/yday <> 0 [ ;-- special ISO formats - df/month: 1 ;-- ensures valid month (will be changed later) - df/day: 1 ;-- ensures valid day (will be changed later) - dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw-error lex b e TYPE_DATE] - - if df/week or df/wday <> 0 [ ;-- yyyy-Www - date/set-isoweek dt df/week - ] - c: df/wday - if c <> 0 [ ;-- yyyy-Www-d - if any [c < 1 c > 7][throw-error lex b e TYPE_DATE] - date/set-weekday dt c - ] - if df/yday <> 0 [date/set-yearday dt df/yday] ;-- yyyy-ddd - ][ - p: as byte-ptr! df/month-begin - me: as byte-ptr! df/sep2 - if df/month-begin or df/sep2 <> 0 [ - if any [null? p null? me p/1 <> me/1][ - throw-error lex b e TYPE_DATE ;-- inconsistent separator - ] - ] - if df/year < 100 [ ;-- expand short yy forms - me: (as byte-ptr! df/sep2) + 3 - unless all [me < e (as-integer me/1 - #"0") <= 9][ ;-- check if year field has 2 digits - c: either df/year < 50 [2000][1900] - df/year: df/year + c - ] - ] - if df/month-end <> 0 [ ;-- if month is named - p: p + 1 ;-- name start - me: as byte-ptr! df/month-end ;-- name end - len: as-integer me - p + 1 - if any [len < 3 len > 9][throw-error lex b e TYPE_DATE] ;-- invalid month name - m: months - loop 12 [ - if zero? platform/strnicmp p as byte-ptr! m/1 len [break] - m: m + 1 - ] - if months + 12 = m [throw-error lex b e TYPE_DATE] ;-- invalid month name - df/month: (as-integer m - months) >> 2 + 1 - ] - dt: date/make-at cell df state >= T_TM_HM neg? ;-- create red-date! - if null? dt [throw-error lex b e TYPE_DATE] - ] - lex/in-pos: e ;-- reset the input position to delimiter byte - ] scan-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] /local diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 1c8f91c093..bfee445c45 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -98,89 +98,8 @@ context [ T_HEX ;-- 83 T_CMT ;-- 84 ] - - date-states: [ - ;trash 1 - ;year 2 - ;month 3 - ;day 4 - ;hour 5 - ;minute 6 - ;second 7 - ;nsec 8 - ;tz-hour 9 - ;tz-min 10 - ;week 11 - ;weekday 12 - ;yearday 13 - ;word-start 14 - ;word-end 15 - ;sep2 16 - ;TZ-sign 17 - ;-- state ----------- reset -- field -- ptr -- - S_DT_START 1 4 1 ;-- 0 - S_DT_D 1 4 1 ;-- 1 - S_DT_DD 1 4 1 ;-- 2 - S_DT_YYY 1 2 1 ;-- 3 - S_DT_YYYY 0 2 1 ;-- 4 - F_DT_YEARL 0 1 14 ;-- 5 - F_DT_YEARL2 0 1 14 ;-- 6 - F_DT_DAYL 0 1 14 ;-- 7 - S_DT_YM 1 3 1 ;-- 8 - S_DT_YMM 0 3 1 ;-- 9 - S_DT_YM2 1 3 1 ;-- 10 - S_DT_YMM2 1 3 1 ;-- 11 - F_DT_YMONTH 0 1 16 ;-- 12 - F_DT_DDD 0 13 1 ;-- 13 - S_DT_YV 0 11 1 ;-- 14 - S_DT_YW 1 11 1 ;-- 15 - S_DT_YWW 1 11 1 ;-- 16 - S_DT_YWD 0 1 1 ;-- 17 - S_DT_WD 1 12 1 ;-- 18 - S_DT_YMON 1 3 15 ;-- 19 - F_DT_YMD 1 4 1 ;-- 20 - F_DT_YMDD 0 4 1 ;-- 21 - S_DT_DM 1 3 1 ;-- 22 - S_DT_DMM 0 3 1 ;-- 23 - F_DT_DMONTH 0 1 16 ;-- 24 - S_DT_DMON 1 3 15 ;-- 25 - F_DT_DMY 1 2 1 ;-- 26 - F_DT_DMYY 1 2 1 ;-- 27 - F_DT_DMYYY 1 2 1 ;-- 28 - F_DT_DMYYYY 0 2 1 ;-- 29 - S_TM_START 0 1 1 ;-- 30 - F_TM_H 1 5 1 ;-- 31 - F_TM_HH 0 5 1 ;-- 32 - S_TM_HM 0 1 1 ;-- 33 - F_TM_M 1 6 1 ;-- 34 - F_TM_MM 0 6 1 ;-- 35 - S_TM_HMS 0 1 1 ;-- 36 - F_TM_S 1 7 1 ;-- 37 - F_TM_SS 0 7 1 ;-- 38 - F_TM_N1 0 1 1 ;-- 39 - F_TM_N 1 8 1 ;-- 40 - S_TM_HMZ 0 1 17 ;-- 41 - S_TZ_H 1 9 1 ;-- 42 - F_TZ_HH 0 9 1 ;-- 43 - F_TZ_HM 0 1 1 ;-- 44 - S_TZ_M 1 10 1 ;-- 45 - T_DT_ERROR 0 1 1 ;-- 46 - T_DT_YMDAY 0 1 1 ;-- 47 - T_DT_DMYEAR 0 1 1 ;-- 48 - T_DT_YDDD 0 1 1 ;-- 49 - T_DT_YWWD 0 1 1 ;-- 50 - T_DT_WEEK 0 1 1 ;-- 51 - T_TM_HM 0 1 1 ;-- 52 - T_TM_HMS 0 1 1 ;-- 53 - T_TM_NZ 0 8 1 ;-- 54 - T_TZ_H 0 9 1 ;-- 55 - T_TZ_HH 0 9 1 ;-- 56 - T_TZ_M 0 10 1 ;-- 57 - T_TZ_MM 0 10 1 ;-- 58 - ] CSV-table: %../docs/lexer/lexer-FSM.csv - date-table: %../docs/lexer/lexer-FSM.csv ;-- Read states from CSV file csv: read CSV-table @@ -206,43 +125,6 @@ context [ ] append/only table out ] - - date-table: %../docs/lexer/date-FSM.csv - ;-- Read states from CSV file - csv: read date-table - - ;-- Determine CSV separator - sep: [#";" 0 #"," 0] - parse csv [some [#";" (sep/2: sep/2 + 1) | #"," (sep/4: sep/4 + 1) | skip]] - sort/skip/all/compare sep 2 func [a b][a/2 > b/2] - - ;-- Decode CSV - matrix: load-csv/with read date-table first sep - - ;-- Generate the date tables - dt-table: make binary! 2000 - reset-table: make binary! 100 - fields-table: make binary! 100 - fields-ptr-table: make binary! 100 - - foreach [state reset pos ptr] date-states [ - append reset-table to-char reset - append fields-table to-char pos - append fields-ptr-table to-char ptr - ] - - foreach line next matrix [ - out: make block! 50 - foreach s next line [ - either pos: find date-states to-word s [ - append out ((3 + index? pos) / 4) - 1 - ][ - do make error! form reduce ["Error: state" s "not found"] - ] - ] - append/only dt-table out - ] - template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" ] @@ -250,19 +132,7 @@ context [ #enum lex-states! [ (states) ] - - #enum date-states! [ - (extract date-states 4) - ] - - fields-ptr-table: (fields-ptr-table) - - fields-table: (fields-table) - - reset-table: (reset-table) - - date-transitions: (dt-table) - + transitions: (table) ] diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index 58ef0fd761..0c8f1d075d 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -68,69 +68,6 @@ gen-hexa-table: function [][ probe out ] -date-classes: [ - C_DT_DIGIT ;-- 0 0-9 - C_DT_LETTER ;-- 1 abcdefghijlmnoprstuvy, ABCDEFGHIJLMNOPRSUVY - C_DT_SLASH ;-- 2 / - C_DT_DASH ;-- 3 - - C_DT_T ;-- 4 T - C_DT_W ;-- 5 W - C_DT_PLUS ;-- 6 + - C_DT_COLON ;-- 7 : - C_DT_DOT ;-- 8 . - C_DT_Z ;-- 9 Z - C_DT_ILLEGAL ;-- 10 all the rest - C_DT_EOF ;-- 11 EOF -] - -gen-date-table: function [][ - out: make binary! 256 - digit: charset "0123456789" - letter: charset "abcdefghijlmnoprstuvyABCDEFGHIJLMNOPRSUVY" - - repeat i 256 [ - c: to-char i - 1 - append out to-char case [ - find digit c [0] - find letter c [1] - c = #"/" [2] - c = #"-" [3] - c = #"T" [4] - c = #"W" [5] - c = #"+" [6] - c = #":" [7] - c = #"." [8] - c = #"Z" [9] - 'else [10] - ] - ] - print "--gen-date-classes-table-- (lexer/date-classes)" - probe out -] - -gen-date-calc-table: function [][ - out: make binary! 256 - digit: charset "0123456789" - lower: charset "abcdefghijlmnoprsuv" ;-- forces t and T to be zero (separator) - upper: charset "ABCDEFGHIJLMNOPRSUV" - yY: charset "yY" - - repeat i 256 [ - c: to-char i - 1 - append out to-char case [ - find digit c [to-char c - #"0"] - find lower c [to-char c - 32] - find upper c [to-char c] - find yY c [3] - 'else [0] - ] - ] - print "--gen-date-cumul-table-- (lexer/date-cumul)" - probe out -] - gen-bitarray {/-~^^{}"} gen-bin16-table gen-hexa-table -gen-date-table -gen-date-calc-table \ No newline at end of file From 73058bf16060a839f46ebe2e1456d074274d2383 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 12:42:36 +0100 Subject: [PATCH 0502/3432] FIX: reports a proper syntax missing error instead of crashing on unmatched closing paren/block. --- environment/system.red | 8 ++++---- runtime/lexer.reds | 18 +++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/environment/system.red b/environment/system.red index f4ca842167..e47d1147be 100644 --- a/environment/system.red +++ b/environment/system.red @@ -86,13 +86,13 @@ system: context [ syntax: object [ code: 200 type: "Syntax Error" - invalid: [:arg1 "invalid" :arg2 "in:" :arg3] - missing: [:arg1 "missing" :arg2 "in:" :arg3] + invalid: [:arg1 "invalid" :arg2 "at:" :arg3] + missing: [:arg1 "missing" :arg2 "at:" :arg3] no-header: ["script is missing a Red header:" :arg1] no-rs-header: ["script is missing a Red/System header:" :arg1] bad-header: ["script header is not valid:" :arg1] - malconstruct: [:arg1 "invalid construction spec in:" :arg2] - bad-char: [:arg1 "invalid character in:" :arg2] + malconstruct: [:arg1 "invalid construction spec at:" :arg2] + bad-char: [:arg1 "invalid character at:" :arg2] ] script: object [ code: 300 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8cb671536b..93ff86199a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -354,6 +354,7 @@ lexer: context [ line [red-string!] p [byte-ptr!] len [integer!] + c [byte!] ][ e: lex/in-end len: 0 @@ -375,10 +376,11 @@ lexer: context [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) line pos]] ERR_MISSING [ + c: either lex/in-pos < lex/in-end [lex/in-pos/1][lex/in-pos/0] type: switch lex/closing [ - TYPE_BLOCK [as-integer #"]"] + TYPE_BLOCK [as-integer either c = #"]" [#"["][#"]"]] TYPE_MAP - TYPE_PAREN [as-integer #")"] + TYPE_PAREN [as-integer either c = #")" [#"("][#")"]] default [assert false 0] ;-- should not happen ] fire [TO_ERROR(syntax missing) line char/push type pos] @@ -466,16 +468,18 @@ lexer: context [ /local p [red-point!] len hint [integer!] + do-error [subroutine!] ][ + do-error: [ + lex/closing: type + throw-error lex s e ERR_MISSING + ] p: as red-point! lex/head - 1 - assert all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] + unless all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][do-error] either type = -1 [ type: either final = -1 [p/y][final] ][ - if p/y <> type [ - lex/closing: type - throw-error lex s e ERR_MISSING - ] + if p/y <> type [do-error] ] len: (as-integer lex/tail - lex/head) >> 4 lex/tail: lex/head From c4acd091785f50edf14de17a2a00bc9f4d82fe6b Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 23 Nov 2019 15:15:28 +0100 Subject: [PATCH 0503/3432] FIX: scientific notation output is not correct in dtoa library. --- runtime/dtoa.reds | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 999a039c53..f6a9d5ed60 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -872,7 +872,7 @@ dtoa: context [ ds: f - 1.5 * 0.289529654602168 + 0.1760912590558 + ((as-float i) * 0.301029995663981) f: fsave - k: as-integer ds + k: as-integer floor ds ;@@ Optimize it k_check: yes if all [k >= 0 k <= TEN_PMAX] [ @@ -910,7 +910,7 @@ dtoa: context [ ds: DTOA_TENS/ki forever [ i: 1 - L: as-integer (f / ds) + L: as-integer f / ds f: f - (ds * uint-to-float L) s/1: #"0" + as byte! L s: s + 1 @@ -1388,21 +1388,15 @@ dtoa: context [ ret [int-ptr!] return: [float!] /local - rv [float!] - rv0 [float!] - aadj2 [float!] - bbe [integer!] - bb [big-int!] - bb1 [big-int!] - bd [big-int!] - bd0 [big-int!] - bs [big-int!] - delta [big-int!] - bc [cmp-info! value] - bb2 bb5 bd2 bd5 bs2 c dsign e e1 - i j k nd nd0 odd neg? s s0 s1 - aadj aadj1 adj y z next? - L d d0 d2 w0 w1 ndigits fraclen + rv rv0 aadj2 aadj aadj1 adj [float!] + bb bb1 bd bd0 bs delta [big-int!] + bbe bb2 bb5 bd2 bd5 bs2 dsign e e1 w0 w1 ndigits fraclen + i j k nd nd0 odd y z L [integer!] + neg? next? [logic!] + s s0 s1 [byte-ptr!] + d d0 d2 [int64!] + c [byte!] + bc [cmp-info! value] ][ bb: null bb1: null @@ -1489,7 +1483,7 @@ dtoa: context [ if nd0 <= 0 [nd0: nd] ;-- finish parsing - ;if ret <> null [ret/value: s] + if ret <> null [ret/value: -1] if zero? nd [return either neg? [d/int2: 80000000h rv][0.0]] From d044e2aedae1d937739ee65defc085942f13e171 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 15:18:27 +0100 Subject: [PATCH 0504/3432] FIX: removes redundant date! creation functions. --- runtime/datatypes/date.reds | 36 ------------------------------------ runtime/lexer.reds | 2 +- 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index e3db274c29..596c8b5299 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -522,42 +522,6 @@ date: context [ ] make-at: func [ - slot [red-value!] - date [lexer-dt-array!] - time? [logic!] - neg-TZ? [logic!] - return: [red-date!] - /local - year [integer!] - tz-h [integer!] - dt [red-date!] - d [integer!] - z [integer!] - ][ - year: date/year - tz-h: date/tz-h - if any [ - date/day > 31 date/month > 12 year > 9999 - tz-h > 15 tz-h < -15 ;-- out of range TZ - date/hour > 23 date/min > 59 date/sec > 59 - all [date/day = 29 date/month = 2 not leap-year? year] - ][return null] - - dt: as red-date! slot - set-all dt year date/month date/day date/hour date/min date/sec date/nsec - - z: tz-h << 2 and 7Fh or (date/tz-m / 15) - if neg-TZ? [z: DATE_SET_ZONE_NEG(z)] - dt/date: DATE_SET_ZONE(dt/date z) - either time? [ - dt/time: to-utc-time dt/time DATE_GET_ZONE(dt/date) - ][ - dt/date: DATE_CLEAR_TIME_FLAG(dt/date) - ] - dt - ] - - make-at2: func [ slot [red-value!] year [integer!] month [integer!] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 93ff86199a..823b9ff84a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1345,7 +1345,7 @@ lexer: context [ tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec ] store-date: [ - dt: date/make-at2 alloc-slot lex year month day tm tz-h tz-m time? TZ? + dt: date/make-at alloc-slot lex year month day tm tz-h tz-m time? TZ? lex/in-pos: e ;-- reset the input position to delimiter byte ] From d4144aebec7949e5016e85593f99a814f9ce1228 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 15:49:06 +0300 Subject: [PATCH 0505/3432] FIX: issues #3670, #3588, partly #2431 --- environment/console/engine.red | 2 +- environment/functions.red | 8 +++++--- lexer.r | 12 +++++++++--- red.r | 3 +-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/environment/console/engine.red b/environment/console/engine.red index 47fdb2d3a2..c31c930740 100644 --- a/environment/console/engine.red +++ b/environment/console/engine.red @@ -283,7 +283,7 @@ system/console: context [ launch: function [/local result][ either script: src: read-argument [ - parse script [some [[to "Red" pos: 3 skip any ws #"[" to end] | skip]] + parse/case script [to [pos: "Red" opt "/System" any ws #"[" to end]] either script: pos [ either error? script: try-do [load script][ diff --git a/environment/functions.red b/environment/functions.red index ff457720b5..bb8c62f4ac 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -855,13 +855,15 @@ split-path: func [ reduce [dir pos] ] -do-file: func ["Internal Use Only" file [file! url!] /local saved code new-path src][ +do-file: func ["Internal Use Only" file [file! url!] /local saved code new-path src ws][ + ws: charset " ^-^M^/" saved: system/options/path - unless src: find/case read file "Red" [ + unless parse/case read file [to [src: "Red" opt "/System" any ws #"["] to end] [ cause-error 'syntax 'no-header reduce [file] ] - code: expand-directives load/all src + code: load/all src ;-- don't expand before we check the header if code/1 = 'Red/System [cause-error 'internal 'red-system []] + code: next expand-directives next code ;-- skip the Red[/System] part and [block] if file? file [ new-path: first split-path clean-path file change-dir new-path diff --git a/lexer.r b/lexer.r index 393df559ce..30ddda8308 100644 --- a/lexer.r +++ b/lexer.r @@ -880,9 +880,15 @@ lexer: context [ rs?: no pos: src until [ - unless pos: find/tail pos "Red" [throw-error/with "Invalid Red program"] - if all [pos find/match pos "/System"][rs?: yes pos: skip pos 7] - while [find/match ws pos/1][pos: next pos] + pos: any [ + find/tail pos "Red" ;-- don't set pos to none before throw-error + throw-error/with "Invalid Red program" + ] + if find/match pos "/System" [rs?: yes pos: skip pos 7] + pos: any [ + find pos negate ws + pos + ] found?: pos/1 = #"[" ] unless found? [throw-error/with "Invalid Red program"] diff --git a/red.r b/red.r index 1a6d8e4c69..21672c5dc1 100644 --- a/red.r +++ b/red.r @@ -249,14 +249,13 @@ redc: context [ ] red-system?: func [file [file!] /local ws rs?][ - ws: charset " ^-^/^M" + ws: charset " ^-^M^/" parse/all/case read file [ some [ thru "Red" opt ["/System" (rs?: yes)] any ws #"[" (return to logic! rs?) - to end ] ] no From 24876f3cbdcd4c8ea7a4f0a0716e24addb0fc9bf Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 23 Nov 2019 16:55:01 +0100 Subject: [PATCH 0506/3432] FEAT: use subroutine! in dtoa.reds --- runtime/dtoa.reds | 64 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index f6a9d5ed60..6bdc3d5e3a 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -748,15 +748,6 @@ dtoa: context [ f - 6755399441055744.0 ] - #define DTOA_RETERN_1 [ - Bfree b - s/1: #"^@" - decpt/value: k + 1 - sign/value: as-integer sign? - length/value: as-integer s - s0 - return s0 - ] - #define DTOA_RETERN [ Bfree SS if mhi <> null [ @@ -765,7 +756,7 @@ dtoa: context [ ] Bfree mhi ] - DTOA_RETERN_1 + DTOA_RETURN_1 ] #define DTOA_ROUND_OFF [ @@ -793,13 +784,14 @@ dtoa: context [ add-0? [logic!] return: [c-string!] /local - mlo [big-int!] - mhi [big-int!] - SS [big-int!] - fsave bbits b2 b5 be dig i j j1 - k k0 ki k_check m2 m5 s2 s5 kf - spec_case L denorm x d d2 sign? - b b1 delta ds s s0 w0 w1 ww0 ilim + b b1 mlo mhi SS delta [big-int!] + s s0 [c-string!] + DTOA_RETURN_1 [subroutine!] + fsave ds kf [float!] + bbits b2 b5 be i j j1 k k0 ki m2 m5 s2 s5 L x w0 w1 ww0 ilim [integer!] + sign? spec_case denorm k_check [logic!] + d d2 [int64!] + dig [byte!] ][ s0: "-000000000000000000000000000000" ;-- 32 bits including ending null char s: s0 + 1 @@ -814,6 +806,15 @@ dtoa: context [ w0: WORD_0(d) w1: WORD_1(d) + DTOA_RETURN_1: [ + Bfree b + s/1: #"^@" + decpt/value: k + 1 + sign/value: as-integer sign? + length/value: as-integer s - s0 + return s0 + ] + either zero? (w0 and DTOA_SIGN_BIT) [ sign?: no ][ @@ -940,7 +941,7 @@ dtoa: context [ i: i + 1 f: f * 10.0 ] - DTOA_RETERN_1 + DTOA_RETURN_1 ] m2: b2 @@ -1224,18 +1225,6 @@ dtoa: context [ ] ] - #define BIGCOMP_BREAK [ - Bfree b - Bfree d - if any [ - dd > 0 - all [zero? dd odd <> 0] - ][ - f/value: f/value + sulp f/value bc - ] - exit - ] - bigcomp: func [ rv [int64!] s0 [byte-ptr!] @@ -1254,7 +1243,20 @@ dtoa: context [ p2 [integer!] p5 [integer!] dd [integer!] + BIGCOMP_BREAK [subroutine!] ][ + BIGCOMP_BREAK: [ + Bfree b + Bfree d + if any [ + dd > 0 + all [zero? dd odd <> 0] + ][ + f/value: f/value + sulp f/value bc + ] + exit + ] + f: as pointer! [float!] rv nd: bc/nd nd0: bc/nd0 @@ -1483,7 +1485,7 @@ dtoa: context [ if nd0 <= 0 [nd0: nd] ;-- finish parsing - if ret <> null [ret/value: -1] + if ret <> null [ret/value: 0] if zero? nd [return either neg? [d/int2: 80000000h rv][0.0]] From 40ff946b2a461e000dad714c2e8a0602c18b4694 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 18:59:05 +0300 Subject: [PATCH 0507/3432] FEAT: qt-tmp-file for writing during tests --- quick-test/quick-test.r | 4 +++- quick-test/quick-test.red | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/quick-test/quick-test.r b/quick-test/quick-test.r index 173e81843c..fcf2eedcd1 100644 --- a/quick-test/quick-test.r +++ b/quick-test/quick-test.r @@ -62,6 +62,7 @@ qt: make object! [ comp-echo: runnable-dir/comp-echo.txt comp-r: runnable-dir/comp.r test-src-file: runnable-dir/qt-test-comp.red + qt-temp-file: qt-tmp-file: runnable-dir/testfile.txt ;; set log file log-file: join system/script/path "quick-test.log" @@ -688,7 +689,8 @@ qt: make object! [ delete-temp-files: does [ if exists? comp-echo [delete comp-echo] if exists? comp-r [delete comp-r] - if exists? test-src-file [delete test-src-file] + if exists? test-src-file [delete test-src-file] + if exists? qt-tmp-file [delete qt-tmp-file] ] seperate-log-file: func [ diff --git a/quick-test/quick-test.red b/quick-test/quick-test.red index 935b192d52..91207b12d9 100644 --- a/quick-test/quick-test.red +++ b/quick-test/quick-test.red @@ -35,6 +35,17 @@ Red [ qt-file-name: none qt-verbose: false +;; temp file for tests involving `write` and `save` +qt-temp-file: qt-tmp-file: append copy tmp: dirize to-red-file any [get-env 'tmp %.] %testfile.txt +change-dir also what-dir + unless attempt [ + write qt-tmp-file "test" ;-- test if can write into it + change-dir tmp ;-- test if can CD into %TMP% (needed by do-file) + ][ + append clear qt-tmp-file %./testfile.txt ;-- fallback to local dir if %TMP% is closed + ] +unset 'tmp + ;; group switches qt-group-name-not-printed: true qt-group?: false From 2b7a697387d037db926653d3a352665cc1bafd4b Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 18:59:35 +0300 Subject: [PATCH 0508/3432] TESTS: for issues #3670, #3588, partly #2431 --- .../source/compiler/regression-test-redc-5.r | 8 +++++++- tests/source/units/regression-test-red.red | 20 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/tests/source/compiler/regression-test-redc-5.r b/tests/source/compiler/regression-test-redc-5.r index f01fd93308..47a85f1c60 100644 --- a/tests/source/compiler/regression-test-redc-5.r +++ b/tests/source/compiler/regression-test-redc-5.r @@ -108,7 +108,13 @@ test ; ===end-group=== ===start-group=== "Red regressions #3501 - #4000" - + + --test-- "#3670" + write qt-tmp-file "1 + 2" + --compile-and-run qt-temp-file + --assert not compiler-error? + --assert syntax-error? + ;; for this test it doesn't matter if it errors out or outputs a result --test-- "#3714" diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..cb5ea29a4e 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2781,10 +2781,11 @@ b} --assert not error? try [3151391351465.995 // 1.0] unset 'true? - --test-- "#3603" - bu3603: reduce [()] - rest3603: none - --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + --test-- "#2431" ;-- FIXME: add `load` tests when it's fixed + write qt-tmp-file {Red []} + --assert unset? do qt-tmp-file ;-- should skip the header + write qt-tmp-file {Red [] Red []} + --assert [] = do qt-tmp-file ;-- should skip the 1st header only --test-- "#3362" do [ ;-- FIXME: compiler doesn't like this @@ -2797,6 +2798,17 @@ b} unset [spec3362-1 spec3362-2] ] + --test-- "#3588" + x3588: [] + write qt-tmp-file {Hello Red append x3588 "try"^/Red [] append x3588 "Hoi!"} + do qt-tmp-file + --assert x3588 = ["Hoi!"] + + --test-- "#3603" + bu3603: reduce [()] + rest3603: none + --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + --test-- "#3739" reactor3739: func [spec] [make deep-reactor! spec] s3739: reactor3739 [started: no] From 776d9e23b4a869b51a5d8a0475fc8f53645af0b1 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 19:00:15 +0300 Subject: [PATCH 0509/3432] FIX: unwanted leftover macro cleanup --- tests/source/units/parse-test.red | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index ac2daa52cb..b45886cc77 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2707,11 +2707,6 @@ Red [ ] --assert [[1 2] [3 4] [5 6] [7 8] [9]] = partition3108 [1 2 3 4 5 6 7 8 9] 2 - --test-- "#3927" - parse "bx" [some [not "b" | skip]] - --assert true ;-- just check that parse finishes - - --test-- "#3357" parse x3357: [][insert ('foo)] --assert x3357 = [foo] @@ -2719,17 +2714,22 @@ Red [ parse x3357b: [][insert ('foo)] --assert x3357b = [foo] - --test-- "#3951" - res: none - do "res: expand-directives/clean [[] #macro word! func [s e]['OK] WTF]()" - --assert res = [[] OK] - --test-- "#3427" --assert parse/part %234 ["23" thru [end]] 3 --assert parse/part %234 ["23" to [end]] 3 --assert parse/part %234 ["23" to end] 3 repeat i 4 [--assert parse/part "12" ["1" to [end]] i] + --test-- "#3927" + parse "bx" [some [not "b" | skip]] + --assert true ;-- just check that parse finishes + + --test-- "#3951" + res: none + do "res: expand-directives/clean [[] #macro word! func [s e]['OK] WTF]()" + --assert res = [[] OK] + expand-directives/clean [] ;-- remove the macro just loaded + ===end-group=== ~~~end-file~~~ From 70abe172dd2455849670e71beba0afee9e6b4b23 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 23 Nov 2019 17:04:28 +0100 Subject: [PATCH 0510/3432] FEAT: use more subroutines in dtoa library. --- runtime/dtoa.reds | 145 +++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 6bdc3d5e3a..0a6163d705 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -748,33 +748,6 @@ dtoa: context [ f - 6755399441055744.0 ] - #define DTOA_RETERN [ - Bfree SS - if mhi <> null [ - if all [mlo <> null mlo <> mhi][ - Bfree mlo - ] - Bfree mhi - ] - DTOA_RETURN_1 - ] - - #define DTOA_ROUND_OFF [ - while [ - s: s - 1 - s/1 = #"9" - ][ - if s = s0 [ - k: k + 1 - s/1: #"1" - s: s + 1 - DTOA_RETERN - ] - ] - s/1: s/1 + 1 - s: s + 1 - ] - float-to-ascii: func [ f [float!] ndigits [integer!] ;-- ndigits <= 0: mode 0 ndigits > 0: mode 4 @@ -786,7 +759,7 @@ dtoa: context [ /local b b1 mlo mhi SS delta [big-int!] s s0 [c-string!] - DTOA_RETURN_1 [subroutine!] + DTOA_RETURN_1 DTOA_RETURN DTOA_ROUND_OFF [subroutine!] fsave ds kf [float!] bbits b2 b5 be i j j1 k k0 ki m2 m5 s2 s5 L x w0 w1 ww0 ilim [integer!] sign? spec_case denorm k_check [logic!] @@ -814,6 +787,33 @@ dtoa: context [ length/value: as-integer s - s0 return s0 ] + + DTOA_RETURN: [ + Bfree SS + if mhi <> null [ + if all [mlo <> null mlo <> mhi][ + Bfree mlo + ] + Bfree mhi + ] + DTOA_RETURN_1 + ] + + DTOA_ROUND_OFF: [ + while [ + s: s - 1 + s/1 = #"9" + ][ + if s = s0 [ + k: k + 1 + s/1: #"1" + s: s + 1 + DTOA_RETURN + ] + ] + s/1: s/1 + 1 + s: s + 1 + ] either zero? (w0 and DTOA_SIGN_BIT) [ sign?: no @@ -1027,7 +1027,7 @@ dtoa: context [ if j > 0 [dig: dig + 1] s/1: dig s: s + 1 - DTOA_RETERN + DTOA_RETURN ] if any [ @@ -1055,7 +1055,7 @@ dtoa: context [ ] s/1: dig s: s + 1 - DTOA_RETERN + DTOA_RETURN ] if j1 > 0 [ @@ -1066,7 +1066,7 @@ dtoa: context [ ] s/1: dig + 1 s: s + 1 - DTOA_RETERN + DTOA_RETURN ] s/1: dig @@ -1099,7 +1099,7 @@ dtoa: context [ ] s: s + 1 ] - DTOA_RETERN + DTOA_RETURN ] string-to-big: func [ @@ -1342,54 +1342,15 @@ dtoa: context [ either neg? [0 - n][n] ] - #define STRTOD_RETURN [return either neg? [0.0 - rv][rv]] - - #define STRTOD_OVERFLOW [ - d/int2: DTOA_EXP_MASK - d/int1: 0 - STRTOD_RETURN - ] - #define STRTOD_UNDERFLOW [return 0.0] - #define STRTOD_BREAK [ - Bfree bb - Bfree bd - Bfree bs - Bfree bd0 - Bfree delta - if bc/nd > nd [ - bigcomp d s0 bc - ] - if bc/scale <> 0 [ - d0/int2: DTOA_EXP_1 - (2 * 53 * DTOA_EXP_MSK1) - d0/int1: 0 - rv: rv * rv0 - ] - STRTOD_RETURN - ] - - #define STRTOD_DROP_DOWN [ - if bc/scale <> 0 [ - L: d/int2 and DTOA_EXP_MASK - if L <= (2 * 53 + 1 * DTOA_EXP_MSK1) [ - if L > (53 + 2 * DTOA_EXP_MSK1) [STRTOD_BREAK] - if bc/nd > nd [STRTOD_BREAK] - STRTOD_UNDERFLOW - ] - ] - L: d/int2 and DTOA_EXP_MASK - DTOA_EXP_MSK1 - d/int2: L or BNDRY_MASK1 - d/int1: FFFFFFFFh - STRTOD_BREAK - ] - to-float: func [ start [byte-ptr!] end [byte-ptr!] ret [int-ptr!] return: [float!] /local + STRTOD_RETURN STRTOD_OVERFLOW STRTOD_BREAK STRTOD_DROP_DOWN [subroutine!] rv rv0 aadj2 aadj aadj1 adj [float!] bb bb1 bd bd0 bs delta [big-int!] bbe bb2 bb5 bd2 bd5 bs2 dsign e e1 w0 w1 ndigits fraclen @@ -1418,6 +1379,46 @@ dtoa: context [ c: s/1 ret/value: 0 + STRTOD_RETURN: [return either neg? [0.0 - rv][rv]] + + STRTOD_OVERFLOW: [ + d/int2: DTOA_EXP_MASK + d/int1: 0 + STRTOD_RETURN + ] + + STRTOD_BREAK: [ + Bfree bb + Bfree bd + Bfree bs + Bfree bd0 + Bfree delta + if bc/nd > nd [ + bigcomp d s0 bc + ] + if bc/scale <> 0 [ + d0/int2: DTOA_EXP_1 - (2 * 53 * DTOA_EXP_MSK1) + d0/int1: 0 + rv: rv * rv0 + ] + STRTOD_RETURN + ] + + STRTOD_DROP_DOWN: [ + if bc/scale <> 0 [ + L: d/int2 and DTOA_EXP_MASK + if L <= (2 * 53 + 1 * DTOA_EXP_MSK1) [ + if L > (53 + 2 * DTOA_EXP_MSK1) [STRTOD_BREAK] + if bc/nd > nd [STRTOD_BREAK] + STRTOD_UNDERFLOW + ] + ] + L: d/int2 and DTOA_EXP_MASK - DTOA_EXP_MSK1 + d/int2: L or BNDRY_MASK1 + d/int1: FFFFFFFFh + STRTOD_BREAK + ] + if any [ c = #"+" c = #"-" From 389a3b4644da73630d476b2ee64a680ab42cab3c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 17:12:12 +0100 Subject: [PATCH 0511/3432] FIX: [R/S] stricter compiler check on untyped local variables. Subroutines can use local variables which type is not yet inferred, leading to wrong code generation or compiler crashes. This new check prevents that. --- system/compiler.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/compiler.r b/system/compiler.r index dc960b6cc8..2b5e5084f8 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -751,6 +751,8 @@ system-dialect: make-profilable context [ local?: all [locals select locals name] select-globals name ] + if all [local? not block? type][throw-error ["unknown type for local variable" name]] + if all [not type pos: select functions decorate-fun name][ if mark: find pos: pos/4 /local [ pos: copy/part pos mark ;-- remove locals From 9321e4470aa920a662a4861b3cd4cccdbcf054e2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 17:24:37 +0100 Subject: [PATCH 0512/3432] FEAT: adds support for negative year in dates. --- runtime/lexer.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 823b9ff84a..ad0921c722 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1316,10 +1316,12 @@ lexer: context [ value ] grab4: [ ;-- grab int from 4 digits max + neg?: p/1 = #"-" + if neg? [p: p + 1] me: p p: grab-digits p e 0 4 :value :err check-err - value + either neg? [0 - value][value] ] grab-time-TZ: [ time?: yes From 16b508ac61508e4be2f336cc2897e9bbadbdb64a Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 19:26:03 +0300 Subject: [PATCH 0513/3432] TESTS: uncommented many file-related tests --- tests/source/units/regression-test-red.red | 84 ++++++++++------------ 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index cb5ea29a4e..f6fc971254 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -1699,14 +1699,10 @@ Red [ --assert logic? false --test-- "#1477" - ; not sure if spawning lots of files is a good idea for a general test script - ; FIXME: perhaps there should be a dedicated script for this - ; commenting this out for now -- hiiamboris - - ; write %test.txt "" - ; write/append %test.txt "hi" - ; write/append %test.txt "there" - ; --assert equal? "hithere" read %test.txt + write qt-tmp-file "" + write/append qt-tmp-file "hi" + write/append qt-tmp-file "there" + --assert equal? "hithere" read qt-tmp-file ; --test-- "#1479" ; GUI @@ -2476,12 +2472,8 @@ b} --assert error? try [set 'vv2021 first reduce [()]] --test-- "#2024" - ; not sure if spawning lots of files is a good idea for a general test script - ; FIXME: perhaps there should be a dedicated script for this - ; commenting this out for now -- hiiamboris - - ; write %test.txt "abcdef" - ; --assert equal? "bcdef" read/seek %test.txt 1 + write qt-tmp-file "abcdef" + --assert equal? "bcdef" read/seek qt-tmp-file 1 --test-- "#2031" --assert equal? ["1" "3" "" "3" "" ""] split "1,3,.3,," charset ".," @@ -2520,17 +2512,13 @@ b} ; GUI ; --test-- "#2072" - ; not sure if spawning lots of files is a good idea for a general test script - ; FIXME: perhaps there should be a dedicated script for this - ; commenting this out for now -- hiiamboris - - ; m: make map! 10 - ; a: [1 2 3] - ; m/a: a - ; save %file m - ; n: load %file - ; --assert equal? m n - ; unset [a m n] + m2072: make map! 10 + a2072: [1 2 3] + m2072/a: a2072 + save qt-tmp-file m2072 + n2072: load qt-tmp-file + --assert equal? m2072 n2072 + unset [a2072 m2072 n2072] --test-- "#2077" ; NOTE: shouldn't override the `sum` func, or next tests using it may fail @@ -2569,31 +2557,33 @@ b} ; TODO --test-- "#2097" - ; not sure if spawning lots of files is a good idea for a general test script - ; FIXME: perhaps there should be a dedicated script for this - ; commenting this out for now -- hiiamboris - - ; write %test.bin #{00000000} - ; write/seek %test.bin #{AAAA} 2 - ; --assert equal? #{0000AAAA} read/binary %test.bin - ; write/seek %test.bin #{BBBB} 0 - ; --assert equal? #{BBBBAAAA} read/binary %test.bin + write qt-tmp-file #{00000000} + write/seek qt-tmp-file #{AAAA} 2 + --assert equal? #{0000AAAA} read/binary qt-tmp-file + write/seek qt-tmp-file #{BBBB} 0 + --assert equal? #{BBBBAAAA} read/binary qt-tmp-file ; --test-- "#2098" ; GUI --test-- "#2099" - ; not sure if spawning lots of files is a good idea for a general test script - ; FIXME: perhaps there should be a dedicated script for this - ; moreover, rebol.com was down for some time when I tested this - ; so `original` better be defined as a binary - ; commenting this out for now -- hiiamboris - - ; original: read/binary http://www.rebol.com/how-to/graphics/button.gif - ; write/binary %button.gif original - ; saved: read/binary %button.gif - ; --assert equal? saved original - ; unset [original saved] + ;-- rebol.com can be down - shouldn't affect tests + ; original2072: read/binary http://www.rebol.com/how-to/graphics/button.gif + ;-- this is just the fragment of the original binary: + original2072: #{ + 47494638396146002600F700000000000E0E0E0F00041700061C1C1C1F00071F + 090F2700092F000B33333336091437000D3E000F3E091641414144383B470011 + 4E0013510E1E55001459333C5D00166338426500186F001B712A3B73172D7500 + 1C773343786B6E7A09247C4A567F001F81747782052383001F833C4D84465585 + 3C4E860E2B87002087616A89253D8982848A0E2B8D00228E17338E747A93384E + 940023949494957D83958B8E96616D976F799A0E2F9A5D6C9E00269E9E9EA005 + 2AA48B91A49498A60027A70028A7A2A3A86F7DA87D87A89499AA9EA1AB0029AB + 6A7AACACACAD052DADA2A5B09EA2B0B0B0B3A2A6B3ACAEB47483B4A7AAB5002B + } + write/binary qt-tmp-file original2072 + saved2072: read/binary qt-tmp-file + --assert equal? saved2072 original2072 + unset [original2072 saved2072] ; --test-- "#2104" ; console behaviour - #1995 @@ -2803,11 +2793,13 @@ b} write qt-tmp-file {Hello Red append x3588 "try"^/Red [] append x3588 "Hoi!"} do qt-tmp-file --assert x3588 = ["Hoi!"] - + unset 'x3588 + --test-- "#3603" bu3603: reduce [()] rest3603: none --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + unset [bu3603 rest3603 block3603] --test-- "#3739" reactor3739: func [spec] [make deep-reactor! spec] From c146f473adf7f9d76e8c69d574ae36d3c1913404 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 17:31:44 +0100 Subject: [PATCH 0514/3432] TESTS: comment some tests using invalid syntax for emails. New lexer has stricter rules for emails (might be relaxed later though). --- tests/source/units/convert-test.red | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/source/units/convert-test.red b/tests/source/units/convert-test.red index 7c9912227c..204011be06 100644 --- a/tests/source/units/convert-test.red +++ b/tests/source/units/convert-test.red @@ -704,15 +704,15 @@ Red [ --test-- "to-email!-word!" --assert equal? head remove back tail word@ to email! 'word - --test-- "to-email!-refinement!" - --assert equal? head remove back tail /refinement@ - to email! /refinement - --test-- "to-email!-path!" - --assert equal? head remove back tail path/foo@ - to email! first [path/foo] - --test-- "to-email!-url!" - --assert equal? head remove back tail http://red-lang.org@ - to email! http://red-lang.org + ;--test-- "to-email!-refinement!" + ; --assert equal? head remove back tail /refinement@ + ; to email! /refinement + ;--test-- "to-email!-path!" + ; --assert equal? head remove back tail path/foo@ + ; to email! first [path/foo] + ;--test-- "to-email!-url!" + ; --assert equal? head remove back tail http://red-lang.org@ + ; to email! http://red-lang.org --test-- "to-email!-file!" tef-email: append %/file/ #"@" --assert equal? head remove back tail tef-email @@ -723,7 +723,7 @@ Red [ --test-- "to-email!-binary!-1" --assert 0 = length? to email! #{} --test-- "to-email!-binary!-2" - teb2-mail: load append #{616263} @ + teb2-mail: load append #{616263} #"@" --assert equal? head remove back tail teb2-mail to email! #{616263} --test-- "to-email!-block!-1" @@ -739,7 +739,7 @@ Red [ to email! ["a" "b"] --test-- "to-email!-block-5" --assert equal? testing@red-lang.org - to email! [testing @ red-lang.org] + to email! [testing #"@" red-lang.org] --test-- "to-email!-tuple!" --assert equal? to email! "1.1.1" to email! 1.1.1 --test-- "to-email!-paren!-1" @@ -758,9 +758,9 @@ Red [ to email! 16-Jun-2014/14:34:59+2:00 --test-- "to-email!-email!" --assert equal? foo@boo to email! foo@boo - --test-- "to-email!-bitset!" - --assert equal? head remove back tail make%20bitset!%20#%7B00%7D@ - to email! make bitset! #{00} + ;--test-- "to-email!-bitset!" + ; --assert equal? head remove back tail make%20bitset!%20%23%7B00%7D@ + ; to email! make bitset! #{00} ===end-group=== ===start-group=== "to-bitset!" --test-- "to-bitset!-char!" From 80baa5d8a8d8b8a2a3c5e648db6dcc71d9549eaa Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 23 Nov 2019 17:42:31 +0100 Subject: [PATCH 0515/3432] FEAT: return error code in dtoa/to-float --- runtime/dtoa.reds | 58 +++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 0a6163d705..25c1ba28ce 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1311,37 +1311,6 @@ dtoa: context [ BIGCOMP_BREAK ] - parse-exponent: func [ - s [byte-ptr!] - end [byte-ptr!] - return: [integer!] - /local - c [byte!] - n [integer!] - neg? [logic!] - ][ - neg?: no - - c: s/1 - if any [ - c = #"+" - c = #"-" - ][ - neg?: c = #"-" - s: s + 1 - ] - - n: 0 - until [ - c: s/1 - #"0" - n: n * 10 - n: n + c - s: s + 1 - s = end - ] - either neg? [0 - n][n] - ] - #define STRTOD_UNDERFLOW [return 0.0] to-float: func [ @@ -1354,8 +1323,8 @@ dtoa: context [ rv rv0 aadj2 aadj aadj1 adj [float!] bb bb1 bd bd0 bs delta [big-int!] bbe bb2 bb5 bd2 bd5 bs2 dsign e e1 w0 w1 ndigits fraclen - i j k nd nd0 odd y z L [integer!] - neg? next? [logic!] + i j k nd nd0 odd y z L n [integer!] + neg? next? e-neg? [logic!] s s0 s1 [byte-ptr!] d d0 d2 [int64!] c [byte!] @@ -1479,14 +1448,33 @@ dtoa: context [ e: 0 if any [c = #"e" c = #"E"][ s: s + 1 - e: parse-exponent s end + e-neg?: no + + c: s/1 + if any [ + c = #"+" + c = #"-" + ][ + e-neg?: c = #"-" + s: s + 1 + ] + + n: 0 + until [ + c: s/1 - #"0" + n: n * 10 + n: n + c + s: s + 1 + s = end + ] + e: either e-neg? [0 - n][n] ] e: e - (nd - nd0) if nd0 <= 0 [nd0: nd] ;-- finish parsing - if ret <> null [ret/value: 0] + if ret <> null [ret/value: as-integer s <> end] if zero? nd [return either neg? [d/int2: 80000000h rv][0.0]] From 82ad970c114e94b83237546651ee1e02d2d576b6 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 20:56:26 +0300 Subject: [PATCH 0516/3432] FIX: problems with quick-test in PR #4147 --- quick-test/quick-test.r | 2 +- tests/source/compiler/regression-test-redc-5.r | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/quick-test/quick-test.r b/quick-test/quick-test.r index fcf2eedcd1..ac790dfe19 100644 --- a/quick-test/quick-test.r +++ b/quick-test/quick-test.r @@ -62,7 +62,7 @@ qt: make object! [ comp-echo: runnable-dir/comp-echo.txt comp-r: runnable-dir/comp.r test-src-file: runnable-dir/qt-test-comp.red - qt-temp-file: qt-tmp-file: runnable-dir/testfile.txt + set 'qt-temp-file set 'qt-tmp-file: runnable-dir/testfile.txt ;; set log file log-file: join system/script/path "quick-test.log" diff --git a/tests/source/compiler/regression-test-redc-5.r b/tests/source/compiler/regression-test-redc-5.r index 47a85f1c60..2418d530a6 100644 --- a/tests/source/compiler/regression-test-redc-5.r +++ b/tests/source/compiler/regression-test-redc-5.r @@ -111,9 +111,11 @@ test --test-- "#3670" write qt-tmp-file "1 + 2" - --compile-and-run qt-temp-file - --assert not compiler-error? - --assert syntax-error? + qt/source-file?: yes + qt/compile qt-temp-file + qt/run/pgm qt-temp-file + --assert probe not compiler-error? + --assert probe syntax-error "Invalid Red program" ;; for this test it doesn't matter if it errors out or outputs a result --test-- "#3714" From 2d261b231018c29a1cb93055d7de2e2a05f32084 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 23 Nov 2019 20:56:55 +0300 Subject: [PATCH 0517/3432] FIX: removed forgotten debug output from R/S regression tests --- system/tests/source/compiler/regression-test-rsc.r | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/tests/source/compiler/regression-test-rsc.r b/system/tests/source/compiler/regression-test-rsc.r index d4ffd50fc9..87e76fff24 100644 --- a/system/tests/source/compiler/regression-test-rsc.r +++ b/system/tests/source/compiler/regression-test-rsc.r @@ -22,8 +22,8 @@ compilation-error?: does [true? find qt/comp-output "*** Compilation Error"] loading-error: func [value] [found? find qt/comp-output join "*** Loading Error: " value] compilation-error: func [value] [found? find qt/comp-output join "*** Compilation Error: " value] syntax-error: func [value] [found? find qt/comp-output join "*** Syntax Error: " value] --test-: :--test-- ---test--: func [value] [probe value -test- value] +; -test-: :--test-- +; --test--: func [value] [probe value -test- value] ===start-group=== "Red/System regressions #1 - #1000" From 39f2944a4f0d6788378f8870bb28e698988826a2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 23 Nov 2019 19:31:01 +0100 Subject: [PATCH 0518/3432] FIX: various fixes in date! scanning. All date! unit tests are now passing. --- runtime/datatypes/date.reds | 1 + runtime/lexer.reds | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 596c8b5299..133c81cce1 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -556,6 +556,7 @@ date: context [ dt/time: to-utc-time tm DATE_GET_ZONE(dt/date) ][ dt/date: DATE_CLEAR_TIME_FLAG(dt/date) + dt/time: 0.0 ] dt ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ad0921c722..d8b6ed66f6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1282,7 +1282,7 @@ lexer: context [ err year month day hour min tz-h tz-m len ylen dlen value week wday yday [integer!] do-error check-err check-all grab2 grab2r grab2-max grab-time-TZ - store-date grab4 [subroutine!] + store-date grab4 calc-time [subroutine!] dt [red-date!] p me [byte-ptr!] m [int-ptr!] @@ -1300,6 +1300,7 @@ lexer: context [ do-error: [throw-error lex s e TYPE_DATE] check-err: [if err <> 0 [do-error]] check-all: [if any [err <> 0 p = e][do-error]] + calc-time: [tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec] grab2: [ ;-- grab int from 2 digits exactly p: grab-digits p e 2 2 :value :err check-all ;-- bound error check @@ -1329,7 +1330,7 @@ lexer: context [ if p/1 <> #":" [do-error] min: grab2-max if p < e [ - if p/1 = #":" [p: grab-float p + 1 e :sec :err] + if p/1 = #":" [p: grab-float p + 1 e :sec :err check-err] if all [p < e p/1 <> #"Z"][ neg?: p/1 = #"-" either any [p/1 = #"+" neg?][ @@ -1344,7 +1345,7 @@ lexer: context [ ] ] ] - tm: (3600.0 * as-float hour) + (60.0 * as-float min) + sec + calc-time ] store-date: [ dt: date/make-at alloc-slot lex year month day tm tz-h tz-m time? TZ? @@ -1364,6 +1365,7 @@ lexer: context [ min: grab2 if p/1 <> #"Z" [ ;-- yyymmddThhmmZ p: grab-float p e :sec :err + check-err if all [p < e p/1 <> #"Z"][ TZ?: yes neg?: p/1 = #"-" @@ -1377,6 +1379,7 @@ lexer: context [ ] ] ] + calc-time ][ either sep = #"-" [ if all [ylen = 4 p/2 = #"W"][ ;-- yyyy-Www @@ -1430,7 +1433,9 @@ lexer: context [ p: p + 1 day: grab4 ;-- could be year also dlen: as-integer p - me - if day > year [len: day day: year year: len ylen: dlen] ;-- swap day<=>year + if any [dlen > ylen day > year][ + len: day day: year year: len ylen: dlen ;-- swap day <=> year + ] if all [year < 100 ylen <= 2][ ;-- expand short yy forms ylen: either year < 50 [2000][1900] year: year + ylen From 7951cdbcbc20263165e97324be9058b0f2850f51 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 24 Nov 2019 01:23:40 +0300 Subject: [PATCH 0519/3432] FIX: issue #3624 (Difference in how compiler and interpreter evaluate...) --- compiler.r | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler.r b/compiler.r index bac332791b..1f644b80ca 100644 --- a/compiler.r +++ b/compiler.r @@ -1798,15 +1798,15 @@ red: context [ insert-lf -3 ] path! set-path! [ + type: either get-word? pc/1/1 [ + change pc/1 to word! pc/1/1 + 'get-path + ][to word! form type? pc/1] idx: do make-block case [ inactive [ - either get-word? pc/1/1 [ - emit 'get-path/push - ][ - emit to path! reduce [to word! form type? pc/1 'push] - if path? pc/1 [emit [as red-path!]] - ] + emit to path! reduce [type 'push] + if type = 'path [emit [as red-path!]] ] lit-path? pc/1 [ emit 'path/push From 80efd9396c58d9476b516e82c835596bf76b8e12 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 24 Nov 2019 01:34:04 +0300 Subject: [PATCH 0520/3432] TESTS: for issue #3624 (Difference in how compiler and interpreter evaluate...) --- tests/source/compiler/regression-test-redc-5.r | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/source/compiler/regression-test-redc-5.r b/tests/source/compiler/regression-test-redc-5.r index f01fd93308..6b31e7e9be 100644 --- a/tests/source/compiler/regression-test-redc-5.r +++ b/tests/source/compiler/regression-test-redc-5.r @@ -108,6 +108,10 @@ test ; ===end-group=== ===start-group=== "Red regressions #3501 - #4000" + + --test-- "#3624" + --compile-and-run-this-red {probe replace/case/all quote :a/b/A/a/B [a] 'x} + --assert qt/output = ":x/b/A/x/B^/" ;; for this test it doesn't matter if it errors out or outputs a result --test-- "#3714" From 528e04b8295cd5aa2499457ad50781aa3bedeb0f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 25 Nov 2019 17:45:34 +0100 Subject: [PATCH 0521/3432] FEAT: preliminary work on switching to native `transcode` function. --- environment/functions.red | 13 ++++++------ environment/natives.red | 11 +++++----- runtime/lexer.reds | 43 +++++++++++++++++++++------------------ runtime/natives.reds | 17 +++++++++------- 4 files changed, 45 insertions(+), 39 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index ff457720b5..4e3407d356 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -409,7 +409,7 @@ load: function [ return do [codec/decode source] ] ] - source: read source + source: read/binary source ] url! [ source: read/info/binary source @@ -422,15 +422,16 @@ load: function [ ] ] ][return none] - source: to string! source/3 + source: source/3 ] - binary! [source: to string! source] ;-- For text: UTF-8 encoding TBD: load image in binary form + string! [source: to binary! source] ][source] result: case [ - part [system/lexer/transcode/part source out trap length] - next [set position system/lexer/transcode/one source out trap] - 'else [system/lexer/transcode source out trap] + part [system/lexer/transcode/part to-string source out trap length] + next [set position system/lexer/transcode/one to-string source out trap] + trap [system/lexer/transcode to-string source out trap] + 'else [out: transcode source] ] either trap [result][ unless :all [if 1 = length? out [out: out/1]] diff --git a/environment/natives.red b/environment/natives.red index d480878c75..e9cce7fd45 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -910,14 +910,13 @@ recycle: make native! [[ transcode: make native! [[ "Translates UTF-8 binary source to values. Returns one or several values in a block" - src [binary!] "UTF-8 input buffer" - /one "Translates and returns the first value only" - /only "Returns the position after the next value" - /trap "Traps errors, returns [[values] position error]" - /part "Translates only part of the input buffer" + src [binary!] "UTF-8 input buffer" + /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" - /into "Optionally provides an output block" + /into "Optionally provides an output block" dst [block! none!] + ;/trace + ; callback [function! [...]] ] #get-definition NAT_TRANSCODE ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d8b6ed66f6..b03b65bd51 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1650,22 +1650,15 @@ lexer: context [ ] scan-tokens: func [ - lex [state!] + lex [state!] + one? [logic!] /local - p [byte-ptr!] - e [byte-ptr!] - start [byte-ptr!] - cp [integer!] - class [integer!] - index [integer!] - state [integer!] - flags [integer!] - line [integer!] - mark [integer!] - offset [integer!] - s [series!] - term? [logic!] - do-scan [scanner!] + cp class index state flags line mark offset [integer!] + slot [red-value!] + p e start [byte-ptr!] + s [series!] + term? [logic!] + do-scan [scanner!] ][ line: 1 until [ @@ -1710,15 +1703,20 @@ lexer: context [ if all [lex/entry = S_PATH state <> T_PATH][ scan-path-item lex start + offset lex/in-pos flags ;-- lex/in-pos could have changed ] + if one? [ + slot: lex/tail - 1 + if any [slot <= lex/head TYPE_OF(slot) <> TYPE_POINT][exit] + ] lex/in-pos >= lex/in-end ] assert lex/in-pos = lex/in-end ] scan: func [ - dst [red-value!] ;-- destination slot - src [byte-ptr!] ;-- UTF-8 buffer - len [integer!] ;-- buffer size in bytes + dst [red-value!] ;-- destination slot + src [byte-ptr!] ;-- UTF-8 buffer + len [integer!] ;-- buffer size in bytes + one? [logic!] ;-- scan only one value /local blk [red-block!] slots [integer!] @@ -1740,10 +1738,15 @@ lexer: context [ lex/type: -1 lex/mstr-nest: 0 - scan-tokens lex + scan-tokens lex one? slots: (as-integer lex/tail - lex/buffer) >> 4 - store-any-block dst lex/buffer slots TYPE_BLOCK + + either all [one? slots > 0][ + copy-cell lex/buffer dst ;-- copy first loaded value only + ][ + store-any-block dst lex/buffer slots TYPE_BLOCK + ] depth: depth - 1 if zero? depth [root-state: null] diff --git a/runtime/natives.reds b/runtime/natives.reds index 374f005bd7..237221a80c 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2731,20 +2731,23 @@ natives: context [ transcode*: func [ check? [logic!] - one? [logic!] - only? [logic!] - trap? [logic!] - part? [logic!] - into? [logic!] + part [integer!] + into [integer!] /local bin [red-binary!] slot [red-value!] + len [integer!] ][ - #typecheck [one? only? part?] + #typecheck [part into] bin: as red-binary! stack/arguments slot: stack/push* - lexer/scan slot binary/rs-head bin binary/rs-length? bin + len: binary/rs-length? bin + ;if OPTION?(part) [ + ; + ;] + + lexer/scan slot binary/rs-head bin len no stack/set-last slot ] From 9c7631780679feff151428c6670a31e36de74a3b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 25 Nov 2019 18:50:16 +0100 Subject: [PATCH 0522/3432] FIX: lexer not erroring out on unmatched { string opening. --- runtime/lexer.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b03b65bd51..7d3427e26e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1709,6 +1709,8 @@ lexer: context [ ] lex/in-pos >= lex/in-end ] + + if lex/entry = S_M_STRING [throw-error lex start lex/in-end TYPE_STRING] assert lex/in-pos = lex/in-end ] From d996d24763ba7c720d904be4ac21d161e5e994a1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 25 Nov 2019 18:51:30 +0100 Subject: [PATCH 0523/3432] TESTS: obsoletes tests in "load issue #2438" group. New lexer accepts such forms. --- tests/source/units/load-test.red | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/source/units/load-test.red b/tests/source/units/load-test.red index 917f67df69..cdeef6577f 100644 --- a/tests/source/units/load-test.red +++ b/tests/source/units/load-test.red @@ -300,19 +300,19 @@ Red [ ===end-group=== - -===start-group=== "load issue #2438" - - --test-- "load a<=>" - --assert error? res: try [load "a<=>"] - --assert to logic! find/match form res {*** Syntax Error: invalid word! at "a<=>"^/*** Where:} - - --test-- "load a" - --assert not error? res: try [load "a"] - --assert word? :res/1 - --assert tag? :res/2 - -===end-group=== +;; OBSOLETE test related to a specific lexer implementation. +;===start-group=== "load issue #2438" +; +; --test-- "load a<=>" +; --assert error? res: try [load "a<=>"] +; --assert to logic! find/match form res {*** Syntax Error: invalid word! at "a<=>"^/*** Where:} +; +; --test-- "load a" +; --assert not error? res: try [load "a"] +; --assert word? :res/1 +; --assert tag? :res/2 +; +;===end-group=== ===start-group=== "load issue #3717" --test-- "load ) 1" From 1282d73b088cf18a3fcae8f9e9d57e467fd238d8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 25 Nov 2019 18:52:41 +0100 Subject: [PATCH 0524/3432] FIX: more accurate detection of any-words starting with a digit. Examples: a/'1 => error :1/b => error --- docs/lexer/lexer-FSM.csv | 6 +- docs/lexer/lexer-FSM.xlsx | Bin 21955 -> 22140 bytes docs/lexer/lexer-states.txt | 7 +- runtime/lexer-transitions.reds | 130 +++++++++++++++++---------------- utils/generate-lexer-table.red | 86 +++++++++++----------- 5 files changed, 121 insertions(+), 108 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 39460d0e9f..76b191b9c3 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -1,5 +1,5 @@ ;C_BLANK;C_LINE;C_DIGIT;C_ZERO;C_BLOCK_OP;C_BLOCK_CL;C_PAREN_OP;C_PAREN_CL;C_STRING_OP;C_STRING_CL;C_DBL_QUOTE;C_SHARP;C_QUOTE;C_COLON;C_X;C_T;C_H;C_E_LOW;C_E_UP;C_ALPHAL;C_ALPHAU;C_SLASH;C_BSLASH;C_LESSER;C_GREATER;C_EQUAL;C_PERCENT;C_COMMA;C_SEMICOL;C_AT;C_DOT;C_MONEY;C_PLUS;C_MINUS;C_CARET;C_BIN;C_WORD;C_ILLEGAL;C_EOF -S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF +S_START;S_START;S_START;S_NUMBER;S_NUMBER;T_BLK_OP;T_BLK_CL;T_PAR_OP;T_PAR_CL;T_MSTR_OP;T_ERROR;S_LINE_STR;S_SHARP;S_WORD_1ST;S_WORD_1ST;S_WORD;S_WORD;S_WORD;S_WORD;S_HEX;S_WORD;S_HEX;S_SLASH;T_ERROR;S_LESSER;S_WORD;S_WORD;S_FILE_1ST;T_ERROR;S_LINE_CMT;T_ERROR;S_DOTWORD;S_MONEY_1ST;S_SIGN;S_SIGN;T_ERROR;S_WORD;S_WORD;T_ERROR;T_EOF S_LINE_CMT;S_LINE_CMT;T_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;S_LINE_CMT;T_ERROR;T_EOF S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_STRING;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_SKIP_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_ERROR S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF @@ -42,12 +42,14 @@ S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_ S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL -S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR +S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_W1ST;S_PATH_W1ST;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_W1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_PATH_SIGN;T_WORD;T_WORD;S_PATH_NUM;S_PATH_NUM;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 32291137860f8501c2617eb352d9fc02e959aaea..09abe3a24c9527cdbf23dab21ccc8ed376cd3827 100644 GIT binary patch literal 22140 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

72)b;gl0CF=_{^- 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index ca25d87f15..5204b6157f 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -45,12 +45,14 @@ S_SKIP_STR3 S_SIGN S_DOTWORD S_DOTDEC +S_WORD_1ST S_WORD S_WORDSET S_URL S_EMAIL S_PATH S_PATH_NUM +S_PATH_W1ST S_PATH_WORD S_PATH_SHARP S_PATH_SIGN @@ -306,7 +308,8 @@ S_START->alphaU|"E"->S_HEX->alphaU|digit|"E"->S_HEX \->"h"->T_HEX \->","|"#"|"%"->T_ERROR \->not(delimit5)->S_WORD - + +S_START->"'"|":"->S_WORD_1ST->not(delimit6)->S_WORD S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD \->delimit7->T_WORD @@ -353,6 +356,8 @@ S_PATH->"+"|"-"->S_PATH_SIGN->digit->S_PATH_NUM S_PATH->"$"->S_MONEY_1ST +S_PATH->"'"|":"->S_PATH_W1ST->not(delimit6)->S_PATH_WORD + S_PATH->not(delimit6)->S_PATH_WORD->not(delimit5)->S_PATH_WORD \->delimit7->T_WORD \ diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index c7c8cd28d9..27d5bd77a4 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -45,12 +45,14 @@ Red/System [ S_SIGN S_DOTWORD S_DOTDEC + S_WORD_1ST S_WORD S_WORDSET S_URL S_EMAIL S_PATH S_PATH_NUM + S_PATH_W1ST S_PATH_WORD S_PATH_SHARP S_PATH_SIGN @@ -88,68 +90,70 @@ Red/System [ T_HEX T_CMT ] transitions: #{ -000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B2B06360136291E -2828362B2B363501540101010101010101010101010101010101010101010101 -0101010101010101010101013635020202020202020202023B02020202020202 -0202020202020202020202020202020203020236360202020202020202020202 -0202020202020202020202020202020202020202020202020202363504040404 -040404043C3D0404040404040404040404040404040404040404040404040504 -0436360404040404040404040404040404040404040404040404040404040404 -040404040404040436353E3E07073E3E3E3E3E3E0A07073E0707070707070707 -0707070707073E3E07070707070707363E3F3F07073F3F3F3F3F3F3607073F07 -070707070707070707070708073F3F07070707070707363F0707090936363636 -3636363636363636360909090936363636363636363636363636363636363607 -0707073636363636363636363636363609090707363636363636363636363636 -36363636363F0A0A0A0A0A0A0A0A0A0A3F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A363640400B0B404040404040400B0B0B0B0B0B0B0B -0B0B0B0B0B0B0B0B0B40400B0B0B0B0B0B0B364045451212113643360D360F12 -1236121212121212121212363636123645451212121212121236450D0D0D0D36 -3636363641363636360D0D0D0D0D0D0D0D3636360D36360E3636360D3636360D -36360E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E36350F0F0F0F0F0F0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F36420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3636111111111144111111 -1111111111111111111111111111111111111111111111111111111136364545 -1212454545454545451212121212121212121212121212121212454512121212 -121212364547471313474747474747470C131A1C195315163621193647363646 -14472E14363619363636364748481515484848484848481715361C3636151536 -3648364836364636483636363636363636364848481515484848484848483636 -483636361515363648364836364636362E183615153636363648484816164848 -48484848483636483636531521362148364836364636362E1836151536363636 -4848484849494949494949491749491717171717171749494917174949494917 -49171749171736494A4A18184A4A4A4A4A4A4A36364A363636363636364A364A -36363636363618363636363636364A4B4B19194B4B4B4B4B4B4B191919191919 -1919191919194B19194B194B4B194B19194B3619364B36361B1B363636363636 -36363636363636363636363636363636363636363636363636363636364D4D1B -1B4D4D4D4D4D4D4D36361B363636363636364D364D363636364D361B36363636 -3636364D36361D1D363636363636363636363636363636363636363636363636 -362E36361D1D36363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D1D3636 -4C364C363636364C2E1D363636363636364C36361F1F36363636363636363636 -363636363636363636363636363636363636363636363636364E4E1F1F4E4E4E -4E4E4E4E4E1F4E363636363636364E364E363636364E36203636363636363635 -4E4E20204E4E4E4E4E4E4E4E204E363636363636364E364E363636364E363636 -363636363636353E3E21213E3E3E3E3E3E3E362B2C2B2B532B212B21523E2B2B -2B36363E2E2B1F2B2B2B2B2B363E3E3E23233E3E3E3E3E3E3E23233E23232323 -23232323232B2B2B23233E3E23232323232323363E2323232323232323232324 -232326232323232323232323234F232323232323232323232323363624242424 +00001313393A3B3C3E38020C2B2B2C2C2C2C212C210B38222C2C06380138291E +2828382C2C383701560101010101010101010101010101010101010101010101 +0101010101010101010101013837020202020202020202023D02020202020202 +0202020202020202020202020202020203020238380202020202020202020202 +0202020202020202020202020202020202020202020202020202383704040404 +040404043E3F0404040404040404040404040404040404040404040404040504 +0438380404040404040404040404040404040404040404040404040404040404 +04040404040404043837404007074040404040400A0707400707070707070707 +0707070707074040070707070707073840414107074141414141413807074107 +0707070707070707070707080741410707070707070738410707090938383838 +3838383838383838380909090938383838383838383838383838383838383807 +0707073838383838383838383838383809090707383838383838383838383838 +3838383838410A0A0A0A0A0A0A0A0A0A410A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A383842420B0B424242424242420B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B42420B0B0B0B0B0B0B384247471212113845380D380F12 +1238121212121212121212383838123847471212121212121238470D0D0D0D38 +3838383843383838380D0D0D0D0D0D0D0D3838380D38380E3838380D3838380D +38380E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E38370F0F0F0F0F0F0F0F0F0F440F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F38440F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3838111111111146111111 +1111111111111111111111111111111111111111111111111111111138384747 +1212474747474747471212121212121212121212121212121212474712121212 +121212384749491313494949494949490C131A1C195515163821193849383848 +14492F1438381938383838494A4A15154A4A4A4A4A4A4A1715381C3838151538 +384A384A383848384A3838383838383838384A4A4A15154A4A4A4A4A4A4A3838 +4A383838151538384A384A38384838382F18381515383838384A4A4A16164A4A +4A4A4A4A4A38384A383855152138214A384A38384838382F1838151538383838 +4A4A4A4A4B4B4B4B4B4B4B4B174B4B171717171717174B4B4B17174B4B4B4B17 +4B17174B1717384B4C4C18184C4C4C4C4C4C4C38384C383838383838384C384C +38383838383818383838383838384C4D4D19194D4D4D4D4D4D4D191919191919 +1919191919194D19194D194D4D194D19194D3819384D38381B1B383838383838 +38383838383838383838383838383838383838383838383838383838384F4F1B +1B4F4F4F4F4F4F4F38381B383838383838384F384F383838384F381B38383838 +3838384F38381D1D383838383838383838383838383838383838383838383838 +382F38381D1D38383838384E4E1D1D4E4E4E4E4E4E4E38384E3838381D1D3838 +4E384E383838384E2F1D383838383838384E38381F1F38383838383838383838 +3838383838383838383838383838383838383838383838383850501F1F505050 +50505050501F5038383838383838503850383838385038203838383838383837 +5050202050505050505050502050383838383838385038503838383850383838 +383838383838374040212140404040404040382C2D2C2C552C212C2154402C2C +2C3838402F2C1F2C2C2C2C2C3840404023234040404040404023234023232323 +23232323232C2C2C232340402323232323232338402323232323232323232324 +2323262323232323232323232351232323232323232323232323383824242424 2424242424242324242424242424242424242424242424242424242424242524 -2436362424242424242424242424242424242424242424242424242424242424 -2424242424242424363626262626262626262626262626232626262626262626 -2626262626262626262626262626263636262626262626262626262626262626 -2626262626262626262626262626262626262626262636363E3E13133E3E3E3E -3E3E3E36362B2B2B2B2B2B2B2B2B3E362B2B362B3E2B292B2B2B362B2B363E3E -3E2A2A3E3E3E3E3E3E3E362B2C2B2B2B2A2A2B2B523E2B2B2B36363E2E2B362A -2A2B2B2B363E48482A2A484848484848483636481C36362A2A36364836483636 -4636363636362A2A36363636483E3E2B2B3E3E3E3E3E3E3E362B2C2B2B2B2B2B -2B2B523E2B2B2B36363E2E2B1F2B2B2B2B2B363E3E3E2D2D3E3E3E3E3E3E3E2D -2D2D2D2D2D2D2D2D2D2D3E362D2D2D2D3E2D2D2D2D2D2D2D2D363E50502D2D50 -5050505050502D362D2D2D2D2D2D2D2D2D5050362D2D50502D2D362D2D362D2D -365051512E2E515151515151513636362E2E2E2E2E2E2E51515136362E365136 -2E362E2E362E2E3651363630303636393A363602323131313131313131313636 -2231313636362E31363333363131363647473030474747474747473613471C36 -361515363647364736364614472E1436363636363636473E3E31313E3E3E3E3E -3E3E36313E313131313131313E3E31313136363E2E31363131313131363E4545 -12121136363636360F1212361212121212121212123636361236454512121212 -12121236453E3E30303E3E3E3E3E3E3E36362B2B2B2B2B2B2B2B2B3E362B2B36 -2B3E2B2B2B2B2B362B2B363E +2438382424242424242424242424242424242424242424242424242424242424 +2424242424242424383826262626262626262626262626232626262626262626 +2626262626262626262626262626263838262626262626262626262626262626 +2626262626262626262626262626262626262626262638384040131340404040 +40404038382C2C2C2C2C2C2C2C2C40382C2C382C402C292C2C2C382C2C384040 +402A2A40404040404040382C2D2C2C2C2A2A2C2C54402C2C2C3838402F2C382A +2A2C2C2C38404A4A2A2A4A4A4A4A4A4A4A38384A1C38382A2A38384A384A3838 +4838383838382A2A383838384A38383838383838383838383838382C2C2C2C2C +2C2C2C382C2C2C383838382C382C2C382C2C383840402C2C4040404040404038 +2C2D2C2C2C2C2C2C2C54402C2C2C3838402F2C1F2C2C2C2C2C384040402E2E40 +4040404040402E2E2E2E2E2E2E2E2E2E2E40382E2E2E2E402E2E2E2E2E2E2E2E +384052522E2E525252525252522E382E2E2E2E2E2E2E2E2E5252382E2E52522E +2E382E2E382E2E385253532F2F535353535353533838382F2F2F2F2F2F2F5353 +5338382F3853382F382F2F382F2F38533838313138383B3C3838023432323333 +333333333338382233333838382F333835353833333838494931314949494949 +49493813491C38381515383849384938384814492F1438383838383838493838 +3838383838383838383838383333333333333338383333333838383833383333 +3833333838404033334040404040404038334033333333333333404033333338 +38402F333833333333333840474712121138383838380F121238121212121212 +1212123838381238474712121212121212384740403131404040404040403838 +2C2C2C2C2C2C2C2C2C40382C2C382C402C2C2C2C2C382C2C3840 } diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index bfee445c45..512548c973 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -55,48 +55,50 @@ context [ S_SIGN ;-- 40 S_DOTWORD ;-- 41 S_DOTDEC ;-- 42 - S_WORD ;-- 43 - S_WORDSET ;-- 44 - S_URL ;-- 45 - S_EMAIL ;-- 46 - S_PATH ;-- 47 - S_PATH_NUM ;-- 48 - S_PATH_WORD ;-- 49 - S_PATH_SHARP ;-- 50 - S_PATH_SIGN ;-- 51 - --EXIT_STATES-- ;-- 52 - T_EOF ;-- 53 - T_ERROR ;-- 54 - T_BLK_OP ;-- 55 - T_BLK_CL ;-- 56 - T_PAR_OP ;-- 57 - T_PAR_CL ;-- 58 - T_STRING ;-- 59 - T_MSTR_OP ;-- 60 - T_MSTR_CL ;-- 61 - T_WORD ;-- 62 - T_FILE ;-- 63 - T_REFINE ;-- 64 - T_BINARY ;-- 65 - T_CHAR ;-- 66 - T_MAP_OP ;-- 67 - T_CONS_MK ;-- 68 - T_ISSUE ;-- 69 - T_PERCENT ;-- 70 - T_INTEGER ;-- 71 - T_FLOAT ;-- 72 - T_FLOAT_SP ;-- 73 - T_TUPLE ;-- 74 - T_DATE ;-- 75 - T_PAIR ;-- 76 - T_TIME ;-- 77 - T_MONEY ;-- 78 - T_TAG ;-- 79 - T_URL ;-- 80 - T_EMAIL ;-- 81 - T_PATH ;-- 82 - T_HEX ;-- 83 - T_CMT ;-- 84 + S_WORD_1ST ;-- 43 + S_WORD ;-- 44 + S_WORDSET ;-- 45 + S_URL ;-- 46 + S_EMAIL ;-- 47 + S_PATH ;-- 48 + S_PATH_NUM ;-- 49 + S_PATH_W1ST ;-- 50 + S_PATH_WORD ;-- 51 + S_PATH_SHARP ;-- 52 + S_PATH_SIGN ;-- 53 + --EXIT_STATES-- ;-- 54 + T_EOF ;-- 55 + T_ERROR ;-- 56 + T_BLK_OP ;-- 57 + T_BLK_CL ;-- 58 + T_PAR_OP ;-- 59 + T_PAR_CL ;-- 60 + T_STRING ;-- 61 + T_MSTR_OP ;-- 62 + T_MSTR_CL ;-- 63 + T_WORD ;-- 64 + T_FILE ;-- 65 + T_REFINE ;-- 66 + T_BINARY ;-- 67 + T_CHAR ;-- 68 + T_MAP_OP ;-- 69 + T_CONS_MK ;-- 70 + T_ISSUE ;-- 71 + T_PERCENT ;-- 72 + T_INTEGER ;-- 73 + T_FLOAT ;-- 74 + T_FLOAT_SP ;-- 75 + T_TUPLE ;-- 76 + T_DATE ;-- 77 + T_PAIR ;-- 78 + T_TIME ;-- 79 + T_MONEY ;-- 80 + T_TAG ;-- 81 + T_URL ;-- 82 + T_EMAIL ;-- 83 + T_PATH ;-- 84 + T_HEX ;-- 85 + T_CMT ;-- 86 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 30c117152d28d7bce150d127c5d150abb572a0e6 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 26 Nov 2019 16:16:02 +0100 Subject: [PATCH 0525/3432] FEAT: enable view module in the console on Linux. --- red.r | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/red.r b/red.r index 1a6d8e4c69..0fb97a0d6e 100644 --- a/red.r +++ b/red.r @@ -23,6 +23,7 @@ redc: context [ win-version: none ;-- Windows version extracted from "ver" command SSE3?: yes + Linux?: system/version/4 = 4 Windows?: system/version/4 = 3 macOS?: system/version/4 = 2 load-lib?: any [encap? find system/components 'Library] @@ -459,7 +460,7 @@ redc: context [ ] source: copy read-cache console/:con-ui - if all [any [Windows? macOS?] not gui?][insert find/tail source #"[" "Needs: 'View^/"] + if all [any [Windows? macOS? Linux?] not gui?][insert find/tail source #"[" "Needs: 'View^/"] files: [%auto-complete.red %engine.red %help.red] foreach f files [write temp-dir/:f read-cache console-root/:f] @@ -533,7 +534,7 @@ redc: context [ ] script: switch/default opts/OS [ ;-- empty script for the lib - Windows macOS [ [[Needs: View]] ] + Windows macOS Linux [ [[Needs: View]] ] ][ [[]] ] result: red/compile script opts From 13bfb4f906a1b41200087b0e107f3a555b03a638 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 26 Nov 2019 22:04:54 +0100 Subject: [PATCH 0526/3432] FIX: more accurate detection of set-words inside paths. --- runtime/lexer.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7d3427e26e..48fba0bf76 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -105,7 +105,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000 } path-ending: #{ @@ -1595,6 +1595,9 @@ lexer: context [ index [integer!] close? [logic!] ][ + if all [e < lex/in-end e/1 = #":"][ + throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths + ] close?: either e >= lex/in-end [yes][ ;-- EOF reached cp: as-integer e/1 index: lex-classes/cp and FFh + 1 ;-- query the class of ending character @@ -1607,9 +1610,6 @@ lexer: context [ ][-1] close-block lex s e -1 type ][ - if all [e < lex/in-end e/1 = #":"][ - throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths - ] lex/in-pos: e + 1 ;-- skip / ] ] From c25a604a8982401b37aa163ef392af83e25119e3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 26 Nov 2019 22:12:11 +0100 Subject: [PATCH 0527/3432] FIX: detects empty issue! values and report a syntax error. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 48fba0bf76..b44da448a1 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1131,7 +1131,10 @@ lexer: context [ cell [cell!] type [integer!] ][ - type: either s/1 = #"#" [TYPE_ISSUE][ + type: either s/1 = #"#" [ + if s + 1 = e [throw-error lex s e TYPE_ISSUE] + TYPE_ISSUE + ][ assert s/1 = #"/" either s + 1 = e [s: s - 1 TYPE_WORD][TYPE_REFINEMENT] ] From cbfdef47c51a99c858f2e927b3aafa05c1f4c7bc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 26 Nov 2019 22:22:30 +0100 Subject: [PATCH 0528/3432] FIX: avoids consecutive dots in tuples. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b44da448a1..56e89c160e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1265,7 +1265,7 @@ lexer: context [ loop as-integer e - s [ either p/1 = #"." [ pos: pos + 1 - if any [i < 0 i > 255 pos > 12][throw-error lex s e TYPE_TUPLE] + if any [i < 0 i > 255 pos > 12 p/2 = #"."][throw-error lex s e TYPE_TUPLE] tp/pos: as byte! i i: 0 ][ From 7a0039c097a35f6e333bcb68d0d97a10bc33b913 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 26 Nov 2019 22:43:53 +0100 Subject: [PATCH 0529/3432] FIX: error out on 'word: invalid form. --- runtime/lexer.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 56e89c160e..cb31cfe938 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1007,8 +1007,10 @@ lexer: context [ true [throw-error lex s e type] ] ] - if s/1 = #"'" [s: s + 1 type: TYPE_LIT_WORD] - + if s/1 = #"'" [ + if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] + s: s + 1 type: TYPE_LIT_WORD + ] cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type From 8c30f70efc51e71d6af371119edd80b42c742f0a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 22 Nov 2019 17:31:39 +0800 Subject: [PATCH 0530/3432] FIX: add `do-draw-path` and improve `draw` codes --- modules/view/backends/gtk3/draw.reds | 763 +++++++++++++-------------- modules/view/backends/gtk3/gtk.reds | 69 ++- runtime/definitions.reds | 5 +- 3 files changed, 445 insertions(+), 392 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index bf6ee043cc..62d50dd37b 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -14,46 +14,6 @@ Red/System [ draw-state!: alias struct! [mat [handle!]] -make-pango-cairo-font: func [ - dc [draw-ctx!] - font [red-object!] - /local - values [red-value!] - value [red-value!] - quality [integer!] - bool [red-logic!] - word [red-word!] -][ - free-pango-cairo-font dc - dc/font-attrs: create-pango-attrs null font - dc/font-opts: cairo_font_options_create - dc/layout: pango_cairo_create_layout dc/raw - pango_layout_set_attributes dc/layout dc/font-attrs - - values: object/get-values font - value: values + FONT_OBJ_ANTI-ALIAS? - quality: switch TYPE_OF(value) [ - TYPE_LOGIC [ - bool: as red-logic! value - either bool/value [ - CAIRO_ANTIALIAS_SUBPIXEL - ][ - CAIRO_ANTIALIAS_NONE - ] - ] - TYPE_WORD [ - word: as red-word! value - either ClearType = symbol/resolve word/symbol [ - CAIRO_ANTIALIAS_BEST - ][ - CAIRO_ANTIALIAS_NONE - ] - ] - default [CAIRO_ANTIALIAS_DEFAULT] - ] - cairo_font_options_set_antialias dc/font-opts quality -] - free-pango-cairo-font: func [ dc [draw-ctx!] ][ @@ -65,27 +25,6 @@ free-pango-cairo-font: func [ cairo_font_options_destroy dc/font-opts dc/font-opts: null ] - unless null? dc/layout [ - g_object_unref dc/layout - dc/layout: null - ] -] - - -pango-cairo-set-text: func [ - dc [draw-ctx!] - text [c-string!] -][ - pango-layout-set-text dc/layout text dc/font-attrs -] - -pango-layout-set-text: func [ - layout [handle!] - text [c-string!] - attrs [handle!] -][ - pango_layout_set_text layout text -1 - pango_layout_set_attributes layout attrs ] set-source-color: func [ @@ -114,20 +53,19 @@ init-draw-ctx: func [ ctx [draw-ctx!] cr [handle!] ][ - ctx/raw: cr + ctx/cr: cr ctx/pen-width: 1.0 ctx/pen-style: 0 ctx/pen-color: 0 ;-- default: black - ;ctx/pen-join: miter - ;ctx/pen-cap: flat + ctx/pen-join: miter + ctx/pen-cap: flat ctx/brush-color: 0 ctx/font-color: 0 ctx/pen?: yes ctx/brush?: no - ctx/pattern: null + ctx/grad-pen: null ctx/font-attrs: null - ctx/layout: null ctx/font-opts: null ] @@ -155,83 +93,100 @@ draw-end: func [ cache? [logic!] pattern? [logic!] ][ - cairo_identity_matrix dc/raw + cairo_identity_matrix dc/cr free-pango-cairo-font dc ] -do-paint: func [dc [draw-ctx!] /local cr [handle!]][ - cr: dc/raw - ;; DEBUG: print ["do-paint: " dc/brush? " " dc/pen? lf] +do-draw-path: func [ + dc [draw-ctx!] + /local + cr [handle!] +][ + cr: dc/cr if dc/brush? [ cairo_save cr - either null? dc/pattern [ + either null? dc/grad-pen [ set-source-color cr dc/brush-color ][ - cairo_set_source cr dc/pattern + cairo_set_source cr dc/grad-pen ] cairo_fill_preserve cr - unless dc/pen? [ - set-source-color cr dc/pen-color - cairo_stroke cr - ] cairo_restore cr ] - if dc/pen? [ - ;; DEBUG: print ["do-paint dc/pen? color " dc/pen-color lf] + either dc/pen? [ cairo_stroke cr + ][ + cairo_new_path cr ] +] +do-draw-pen: func [ + dc [draw-ctx!] + /local + cr [handle!] +][ + cr: dc/cr + either dc/pen? [ + cairo_save cr + unless null? dc/grad-pen [ + cairo_set_source cr dc/grad-pen + ] + cairo_stroke cr + cairo_restore cr + ][ + cairo_new_path cr + ] ] OS-draw-anti-alias: func [ - dc [draw-ctx!] - on? [logic!] + dc [draw-ctx!] + on? [logic!] ][ - cairo_set_antialias dc/raw either on? [CAIRO_ANTIALIAS_GOOD][CAIRO_ANTIALIAS_NONE] + cairo_set_antialias dc/cr either on? [CAIRO_ANTIALIAS_GOOD][CAIRO_ANTIALIAS_NONE] ] OS-draw-line: func [ - dc [draw-ctx!] - point [red-pair!] - end [red-pair!] + dc [draw-ctx!] + point [red-pair!] + end [red-pair!] /local - cr [handle!] + cr [handle!] ][ - cr: dc/raw + cr: dc/cr + cairo_move_to cr as-float point/x as-float point/y + point: point + 1 + while [point <= end][ cairo_line_to cr as-float point/x as-float point/y point: point + 1 ] - do-paint dc + do-draw-pen dc ] OS-draw-pen: func [ - dc [draw-ctx!] - color [integer!] ;-- 00bbggrr format - off? [logic!] - alpha? [logic!] + dc [draw-ctx!] + color [integer!] ;-- 00bbggrr format + off? [logic!] + alpha? [logic!] ][ dc/pen?: not off? - ;; DEBUG: print ["OS-draw-pen: " not off? " with color " color lf ] - ;; THIS if DOES NOT WORK: - ;; if dc/pen-color <> color [ + if all [not off? dc/pen-color <> color][ dc/pen-color: color dc/font-color: color - ;; DEBUG: print ["set-source-color" lf] - set-source-color dc/raw color - ;;] + set-source-color dc/cr color + ] ] OS-draw-fill-pen: func [ - dc [draw-ctx!] - color [integer!] ;-- 00bbggrr format - off? [logic!] - alpha? [logic!] + dc [draw-ctx!] + color [integer!] ;-- 00bbggrr format + off? [logic!] + alpha? [logic!] ][ dc/brush?: not off? - unless null? dc/pattern [ - cairo_pattern_destroy dc/pattern - dc/pattern: null + unless null? dc/grad-pen [ + cairo_pattern_destroy dc/grad-pen + dc/grad-pen: null ] if dc/brush-color <> color [ dc/brush-color: color @@ -239,25 +194,25 @@ OS-draw-fill-pen: func [ ] OS-draw-line-width: func [ - dc [draw-ctx!] - width [red-value!] + dc [draw-ctx!] + width [red-value!] /local - w [float!] + w [float!] ][ w: get-float as red-integer! width - if dc/pen-width <> w [ - dc/pen-width: w - cairo_set_line_width dc/raw w - ] + if w <= 0.0 [w: 1.0] + dc/pen-width: w + cairo_set_line_width dc/cr w ] OS-draw-box: func [ - dc [draw-ctx!] - upper [red-pair!] - lower [red-pair!] + dc [draw-ctx!] + upper [red-pair!] + lower [red-pair!] /local + cr [handle!] radius [red-integer!] - ; t [integer!] + t [integer!] rad [float!] x [float!] y [float!] @@ -265,14 +220,15 @@ OS-draw-box: func [ h [float!] degrees [float!] ][ + cr: dc/cr radius: null if TYPE_OF(lower) = TYPE_INTEGER [ radius: as red-integer! lower lower: lower - 1 ] - ; if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t] - ; if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t] + if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t] + if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t] x: as-float upper/x y: as-float upper/y @@ -280,58 +236,57 @@ OS-draw-box: func [ h: as-float lower/y - upper/y either radius <> null [ - ; t: as-integer either w > h [h][w] - ; rad: as-float either radius/value * 2 > t [t / 2][radius/value] - + t: as-integer either w > h [h][w] rad: as-float radius/value * 2 + if rad > as float! t [rad: as float! t] + degrees: pi / 180.0 - ;; TODO: not sure it is a the right version but it at least works! - cairo_new_sub_path dc/raw - cairo_arc dc/raw x + w - rad y + rad rad -90.0 * degrees 0.0 * degrees - cairo_arc dc/raw x + w - rad y + h - rad rad 0.0 * degrees 90.0 * degrees - cairo_arc dc/raw x + rad y + h - rad rad 90.0 * degrees 180.0 * degrees - cairo_arc dc/raw x + rad y + rad rad 180.0 * degrees 270.0 * degrees - cairo_close_path dc/raw + cairo_new_sub_path cr + cairo_arc cr x + w - rad y + rad rad -90.0 * degrees 0.0 * degrees + cairo_arc cr x + w - rad y + h - rad rad 0.0 * degrees 90.0 * degrees + cairo_arc cr x + rad y + h - rad rad 90.0 * degrees 180.0 * degrees + cairo_arc cr x + rad y + rad rad 180.0 * degrees 270.0 * degrees + cairo_close_path cr ][ - cairo_rectangle dc/raw x y w h + cairo_rectangle cr x y w h ] - do-paint dc + do-draw-path dc ] OS-draw-triangle: func [ - dc [draw-ctx!] - start [red-pair!] + dc [draw-ctx!] + start [red-pair!] ][ loop 3 [ - cairo_line_to dc/raw as-float start/x as-float start/y + cairo_line_to dc/cr as-float start/x as-float start/y start: start + 1 ] - cairo_close_path dc/raw ;-- close the triangle - do-paint dc + cairo_close_path dc/cr ;-- close the triangle + do-draw-path dc ] OS-draw-polygon: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] ][ until [ - cairo_line_to dc/raw as-float start/x as-float start/y + cairo_line_to dc/cr as-float start/x as-float start/y start: start + 1 start > end ] - cairo_close_path dc/raw - do-paint dc + cairo_close_path dc/cr + do-draw-path dc ] spline-delta: 1.0 / 25.0 do-spline-step: func [ - ctx [handle!] - p0 [red-pair!] - p1 [red-pair!] - p2 [red-pair!] - p3 [red-pair!] + ctx [handle!] + p0 [red-pair!] + p1 [red-pair!] + p2 [red-pair!] + p3 [red-pair!] /local t [float!] t2 [float!] @@ -359,12 +314,12 @@ do-spline-step: func [ ] OS-draw-spline: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - closed? [logic!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + closed? [logic!] /local - ctx [handle!] + cr [handle!] point [red-pair!] stop [red-pair!] ][ @@ -373,16 +328,16 @@ OS-draw-spline: func [ exit ] - ctx: dc/raw + cr: dc/cr either closed? [ - do-spline-step ctx + do-spline-step cr end start start + 1 start + 2 ][ - do-spline-step ctx + do-spline-step cr start start start + 1 @@ -393,7 +348,7 @@ OS-draw-spline: func [ stop: end - 3 while [point <= stop] [ - do-spline-step ctx + do-spline-step cr point point + 1 point + 2 @@ -402,41 +357,41 @@ OS-draw-spline: func [ ] either closed? [ - do-spline-step ctx + do-spline-step cr end - 2 end - 1 end start - do-spline-step ctx + do-spline-step cr end - 1 end start start + 1 - cairo_close_path ctx + cairo_close_path cr ][ - do-spline-step ctx + do-spline-step cr end - 2 end - 1 end end ] - do-paint dc + do-draw-path dc ] OS-draw-circle: func [ - dc [draw-ctx!] - center [red-pair!] - radius [red-integer!] + dc [draw-ctx!] + center [red-pair!] + radius [red-integer!] /local - ctx [handle!] - rad-x [integer!] - rad-y [integer!] - w [float!] - h [float!] - f [red-float!] + cr [handle!] + rad-x [integer!] + rad-y [integer!] + w [float!] + h [float!] + f [red-float!] ][ - ctx: dc/raw + cr: dc/cr either TYPE_OF(radius) = TYPE_INTEGER [ either center + 1 = radius [ ;-- center, radius @@ -465,44 +420,75 @@ OS-draw-circle: func [ ] ] - cairo_save ctx - cairo_translate ctx as-float center/x + cairo_save cr + cairo_translate cr as-float center/x as-float center/y - cairo_scale ctx as-float rad-x + cairo_scale cr as-float rad-x as-float rad-y - cairo_arc ctx 0.0 0.0 1.0 0.0 2.0 * pi - cairo_restore ctx - do-paint dc + cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi + cairo_restore cr + do-draw-path dc ] OS-draw-ellipse: func [ - dc [draw-ctx!] - upper [red-pair!] - diameter [red-pair!] + dc [draw-ctx!] + upper [red-pair!] + diameter [red-pair!] /local - ctx [handle!] - rad-x [integer!] - rad-y [integer!] + cr [handle!] + rad-x [integer!] + rad-y [integer!] ][ - ctx: dc/raw + cr: dc/cr rad-x: diameter/x / 2 rad-y: diameter/y / 2 - cairo_save ctx - cairo_translate ctx as-float upper/x + rad-x + cairo_save cr + cairo_translate cr as-float upper/x + rad-x as-float upper/y + rad-y - cairo_scale ctx as-float rad-x + cairo_scale cr as-float rad-x as-float rad-y - cairo_arc ctx 0.0 0.0 1.0 0.0 2.0 * pi - cairo_restore ctx - do-paint dc + cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi + cairo_restore cr + do-draw-path dc ] OS-draw-font: func [ - dc [draw-ctx!] - font [red-object!] + dc [draw-ctx!] + font [red-object!] + /local + values [red-value!] + value [red-value!] + quality [integer!] + bool [red-logic!] + word [red-word!] ][ - make-pango-cairo-font dc font + free-pango-cairo-font dc + dc/font-attrs: create-pango-attrs null font + dc/font-opts: cairo_font_options_create + + values: object/get-values font + value: values + FONT_OBJ_ANTI-ALIAS? + quality: switch TYPE_OF(value) [ + TYPE_LOGIC [ + bool: as red-logic! value + either bool/value [ + CAIRO_ANTIALIAS_SUBPIXEL + ][ + CAIRO_ANTIALIAS_NONE + ] + ] + TYPE_WORD [ + word: as red-word! value + either ClearType = symbol/resolve word/symbol [ + CAIRO_ANTIALIAS_BEST + ][ + CAIRO_ANTIALIAS_NONE + ] + ] + default [CAIRO_ANTIALIAS_DEFAULT] + ] + cairo_font_options_set_antialias dc/font-opts quality ] draw-text-at: func [ @@ -564,31 +550,31 @@ draw-text-box: func [ int: as red-integer! block/rs-head state layout: as handle! int/value cairo_move_to cr as-float pos/x as-float pos/y + pango_cairo_update_layout cr layout pango_cairo_show_layout cr layout ] OS-draw-text: func [ - dc [draw-ctx!] - pos [red-pair!] - text [red-string!] - catch? [logic!] - return: [logic!] + dc [draw-ctx!] + pos [red-pair!] + text [red-string!] + catch? [logic!] + return: [logic!] ][ either TYPE_OF(text) = TYPE_STRING [ - draw-text-at dc/raw text dc/font-attrs dc/font-opts pos/x pos/y + draw-text-at dc/cr text dc/font-attrs dc/font-opts pos/x pos/y ][ - draw-text-box dc/raw pos as red-object! text catch? + draw-text-box dc/cr pos as red-object! text catch? ] - do-paint dc true ] OS-draw-arc: func [ - dc [draw-ctx!] - center [red-pair!] - end [red-value!] + dc [draw-ctx!] + center [red-pair!] + end [red-value!] /local - ctx [handle!] + cr [handle!] radius [red-pair!] angle [red-integer!] begin [red-integer!] @@ -603,7 +589,7 @@ OS-draw-arc: func [ i [integer!] closed? [logic!] ][ - ctx: dc/raw + cr: dc/cr cx: as float! center/x cy: as float! center/y rad: PI / 180.0 @@ -620,87 +606,82 @@ OS-draw-arc: func [ closed?: angle < end - cairo_save ctx + cairo_save cr unless closed? [dc/brush?: no] - cairo_translate ctx cx cy - cairo_scale ctx rad-x rad-y + cairo_translate cr cx cy + cairo_scale cr rad-x rad-y either sweep < 0 [ - cairo_arc_negative ctx 0.0 0.0 1.0 angle-begin angle-end + cairo_arc_negative cr 0.0 0.0 1.0 angle-begin angle-end ][ - cairo_arc ctx 0.0 0.0 1.0 angle-begin angle-end + cairo_arc cr 0.0 0.0 1.0 angle-begin angle-end ] if closed? [ - cairo_line_to ctx 0.0 0.0 - cairo_close_path ctx + cairo_close_path cr + ] + cairo_restore cr + either closed? [ + do-draw-path dc + ][ + do-draw-pen dc ] - cairo_restore ctx - do-paint dc ] OS-draw-curve: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] /local - ctx [handle!] - p2 [red-pair!] - p3 [red-pair!] + cr [handle!] + p2 [red-pair!] + p3 [red-pair!] ][ - ctx: dc/raw + cr: dc/cr if (as-integer end - start) >> 4 = 3 ; four input points [ - cairo_move_to ctx as-float start/x + cairo_move_to cr as-float start/x as-float start/y start: start + 1 ] p2: start + 1 p3: start + 2 - cairo_curve_to ctx as-float start/x + cairo_curve_to cr as-float start/x as-float start/y as-float p2/x as-float p2/y as-float p3/x as-float p3/y - do-paint dc + do-draw-pen dc ] OS-draw-line-join: func [ - dc [draw-ctx!] - style [integer!] - /local - mode [integer!] + dc [draw-ctx!] + style [integer!] ][ - if dc/pen-join <> style [ - dc/pen-join: style - cairo_set_line_join dc/raw - case [ - style = miter [0] - style = _round [1] - style = bevel [2] - style = miter-bevel [0] - true [0] - ] - ] + dc/pen-join: style + cairo_set_line_join dc/cr + case [ + style = miter [0] + style = _round [1] + style = bevel [2] + style = miter-bevel [0] + true [0] + ] ] OS-draw-line-cap: func [ - dc [draw-ctx!] - style [integer!] - /local - mode [integer!] + dc [draw-ctx!] + style [integer!] ][ - if dc/pen-cap <> style [ - dc/pen-cap: style - cairo_set_line_cap dc/raw - case [ - style = flat [0] - style = _round [1] - style = square [2] - true [0] - ] - ] + dc/pen-cap: style + cairo_set_line_cap dc/cr + case [ + style = flat [0] + style = _round [1] + style = square [2] + true [0] + ] ] GDK-draw-image: func [ @@ -772,7 +753,7 @@ OS-draw-image: func [ start + 2 = end [0] ;@@ TBD three control points true [0] ;@@ TBD four control points ] - cr: dc/raw + cr: dc/cr ;; DEBUG: print ["OS-draw-image: " x "x" y " " width "x" height lf "image: " image lf "original: " IMAGE_WIDTH(image/size) "x" IMAGE_HEIGHT(image/size) lf] img: OS-image/to-pixbuf image @@ -835,7 +816,10 @@ OS-draw-grad-pen-old: func [ n [integer!] delta [float!] p [float!] + angle [float!] + rotate? [logic!] scale? [logic!] + matrix [cairo_matrix_t! value] ][ x: as-float offset/x y: as-float offset/y @@ -852,6 +836,7 @@ OS-draw-grad-pen-old: func [ ] n: 0 + rotate?: no scale?: no y: 1.0 while [ @@ -864,16 +849,23 @@ OS-draw-grad-pen-old: func [ default [break] ] switch n [ - 0 [0] ;-- rotation + 0 [angle: p rotate?: yes] 1 [x: p scale?: yes] 2 [y: p] ] n: n + 1 ] + cairo_matrix_init matrix 1.0 0.0 0.0 1.0 0.0 0.0 + cairo_pattern_set_matrix pattern matrix + if rotate? [ + cairo_matrix_rotate matrix angle + ] + if scale? [ + cairo_matrix_scale matrix x y + ] - if scale? [0] - - delta: 1.0 / as-float count - 1 + delta: as-float count - 1 + delta: 1.0 / delta p: 0.0 head: as red-value! int loop count [ @@ -895,8 +887,8 @@ OS-draw-grad-pen-old: func [ ] if brush? [dc/brush?: yes] ;-- set brush, or set pen - unless null? dc/pattern [cairo_pattern_destroy dc/pattern] - dc/pattern: pattern + unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] + dc/grad-pen: pattern ] OS-draw-grad-pen: func [ @@ -914,15 +906,15 @@ OS-draw-grad-pen: func [ ] OS-matrix-rotate: func [ - dc [draw-ctx!] - pen [integer!] - angle [red-integer!] - center [red-pair!] + dc [draw-ctx!] + pen [integer!] + angle [red-integer!] + center [red-pair!] /local - cr [handle!] - rad [float!] + cr [handle!] + rad [float!] ][ - cr: dc/raw + cr: dc/cr rad: PI / 180.0 * get-float angle if angle <> as red-integer! center [ cairo_translate cr as float! center/x @@ -936,42 +928,36 @@ OS-matrix-rotate: func [ ] OS-matrix-scale: func [ - dc [draw-ctx!] - pen [integer!] - sx [red-integer!] - sy [red-integer!] - /local - cr [handle!] + dc [draw-ctx!] + pen [integer!] + sx [red-integer!] + sy [red-integer!] ][ - cr: dc/raw - cairo_scale cr as float! get-float32 sx - as float! get-float32 sy + cairo_scale dc/cr as float! get-float32 sx + as float! get-float32 sy ] OS-matrix-translate: func [ - dc [draw-ctx!] - pen [integer!] - x [integer!] - y [integer!] - /local - cr [handle!] + dc [draw-ctx!] + pen [integer!] + x [integer!] + y [integer!] ][ - cr: dc/raw - cairo_translate cr as-float x - as-float y + cairo_translate dc/cr as-float x + as-float y ] OS-matrix-skew: func [ - dc [draw-ctx!] - pen [integer!] - sx [red-integer!] - sy [red-integer!] + dc [draw-ctx!] + pen [integer!] + sx [red-integer!] + sy [red-integer!] /local - m [integer!] - x [float32!] - y [float32!] - u [float32!] - z [float32!] + m [integer!] + x [float32!] + y [float32!] + u [float32!] + z [float32!] ][ m: 0 u: as float32! 1.0 @@ -988,7 +974,7 @@ OS-matrix-transform: func [ translate [red-pair!] /local rotate [red-integer!] - center? [logic!] + center? [logic!] ][ rotate: as red-integer! either center + 1 = scale [center][center + 1] center?: rotate <> center @@ -998,36 +984,39 @@ OS-matrix-transform: func [ OS-matrix-translate dc pen translate/x translate/y ] -OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ -cairo_save dc/raw +OS-matrix-push: func [ + dc [draw-ctx!] + state [draw-state!] +][ + cairo_save dc/cr ] -OS-matrix-pop: func [dc [draw-ctx!] state [draw-state!]][ - cairo_restore dc/raw +OS-matrix-pop: func [ + dc [draw-ctx!] + state [draw-state!] +][ + cairo_restore dc/cr ] OS-matrix-reset: func [ - dc [draw-ctx!] - pen [integer!] - /local - cr [handle!] + dc [draw-ctx!] + pen [integer!] ][ - cr: dc/raw - cairo_identity_matrix cr + cairo_identity_matrix dc/cr ] OS-matrix-invert: func [ - dc [draw-ctx!] - pen [integer!] + dc [draw-ctx!] + pen [integer!] ][] OS-matrix-set: func [ - dc [draw-ctx!] - pen [integer!] - blk [red-block!] + dc [draw-ctx!] + pen [integer!] + blk [red-block!] /local - m [cairo_matrix_t! value] - val [red-integer!] + m [cairo_matrix_t! value] + val [red-integer!] ][ m: null val: as red-integer! block/rs-head blk @@ -1037,20 +1026,20 @@ OS-matrix-set: func [ m/yy: get-float val + 3 m/x0: get-float val + 4 m/y0: get-float val + 5 - cairo_transform dc/raw :m ; Weirdly it is not cairo_set_matrix because it is a global change! + cairo_transform dc/cr :m ; Weirdly it is not cairo_set_matrix because it is a global change! ] OS-set-matrix-order: func [ - ctx [draw-ctx!] - order [integer!] + ctx [draw-ctx!] + order [integer!] ][ 0 ] OS-set-clip: func [ - dc [draw-ctx!] - upper [red-pair!] - lower [red-pair!] + dc [draw-ctx!] + upper [red-pair!] + lower [red-pair!] ][ print ["set-clip!" lf] 0 @@ -1068,15 +1057,15 @@ OS-draw-shape-endpath: func [ close? [logic!] return: [logic!] ][ - if close? [cairo_close_path dc/raw] - do-paint dc + if close? [cairo_close_path dc/cr] + do-draw-path dc true ] OS-draw-shape-moveto: func [ - dc [draw-ctx!] - coord [red-pair!] - rel? [logic!] + dc [draw-ctx!] + coord [red-pair!] + rel? [logic!] /local x [float!] y [float!] @@ -1084,9 +1073,9 @@ OS-draw-shape-moveto: func [ x: as-float coord/x y: as-float coord/y either rel? [ - cairo_rel_move_to dc/raw x y + cairo_rel_move_to dc/cr x y ][ - cairo_move_to dc/raw x y + cairo_move_to dc/cr x y ] dc/shape-curve?: no ] @@ -1104,9 +1093,9 @@ OS-draw-shape-line: func [ x: as-float start/x y: as-float start/y either rel? [ - cairo_rel_line_to dc/raw x y + cairo_rel_line_to dc/cr x y ][ - cairo_line_to dc/raw x y + cairo_line_to dc/cr x y ] start: start + 1 start > end @@ -1121,30 +1110,30 @@ OS-draw-shape-axis: func [ rel? [logic!] hline? [logic!] /local - len [float!] + len [float!] last-x [float!] last-y [float!] ][ last-x: 0.0 last-y: 0.0 - if 1 = cairo_has_current_point dc/raw[ - cairo_get_current_point dc/raw :last-x :last-y + if 1 = cairo_has_current_point dc/cr [ + cairo_get_current_point dc/cr :last-x :last-y ] len: get-float as red-integer! start either hline? [ - cairo_line_to dc/raw either rel? [last-x + len][len] last-y + cairo_line_to dc/cr either rel? [last-x + len][len] last-y ][ - cairo_line_to dc/raw last-x either rel? [last-y + len][len] + cairo_line_to dc/cr last-x either rel? [last-y + len][len] ] dc/shape-curve?: no ] draw-curve: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] - short? [logic!] - num [integer!] ;-- number of points + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + short? [logic!] + num [integer!] ;-- number of points /local dx [float!] dy [float!] @@ -1194,8 +1183,8 @@ draw-curve: func [ dc/shape-curve?: yes either num = 3 [ ;-- cubic Bézier - either rel? [cairo_rel_curve_to dc/raw p1x p1y p2x p2y p3x p3y] - [cairo_curve_to dc/raw p1x p1y p2x p2y p3x p3y] + either rel? [cairo_rel_curve_to dc/cr p1x p1y p2x p2y p3x p3y] + [cairo_curve_to dc/cr p1x p1y p2x p2y p3x p3y] ; dc/control-x: p2x ; dc/control-y: p2y ; dc/last-pt-x: p3x @@ -1212,49 +1201,49 @@ draw-curve: func [ OS-draw-shape-curve: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve dc start end rel? no 3 ] OS-draw-shape-qcurve: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve dc start end rel? no 2 ] OS-draw-shape-curv: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve dc start - 1 end rel? yes 3 ] OS-draw-shape-qcurv: func [ - dc [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + dc [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ - draw-curve dc start - 1 end rel? yes 2 + draw-curve dc start - 1 end rel? yes 2 ] OS-draw-shape-arc: func [ - dc [draw-ctx!] - end [red-pair!] - sweep? [logic!] - large? [logic!] - rel? [logic!] + dc [draw-ctx!] + end [red-pair!] + sweep? [logic!] + large? [logic!] + rel? [logic!] /local - ctx [handle!] + cr [handle!] item [red-integer!] last-x [float!] last-y [float!] @@ -1284,9 +1273,10 @@ OS-draw-shape-arc: func [ rad-check [float32!] pi2 [float32!] ][ + cr: dc/cr last-x: 0.0 last-y: 0.0 - if 1 = cairo_has_current_point dc/raw[ - cairo_get_current_point dc/raw :last-x :last-y + if 1 = cairo_has_current_point cr[ + cairo_get_current_point cr :last-x :last-y ] p1-x: as float32! last-x p1-y: as float32! last-y p2-x: either rel? [ p1-x + as float32! end/x ][ as float32! end/x ] @@ -1355,34 +1345,35 @@ OS-draw-shape-arc: func [ ; m: CGAffineTransformRotate m theta ; m: CGAffineTransformScale m radius-x radius-y ; CGPathAddRelativeArc ctx/path :m as float32! 0.0 as float32! 0.0 as float32! 1.0 cx angle-len - ctx: dc/raw - cairo_save ctx - cairo_new_sub_path ctx - cairo_translate ctx as float! center-x as float! center-y - cairo_scale ctx as float! radius-x as float! radius-y - cairo_arc ctx 0.0 0.0 1.0 as float! cx as float! cy - cairo_restore ctx + cairo_save cr + cairo_new_sub_path cr + cairo_translate cr as float! center-x as float! center-y + cairo_scale cr as float! radius-x as float! radius-y + cairo_arc cr 0.0 0.0 1.0 as float! cx as float! cy + cairo_restore cr ] OS-draw-shape-close: func [ - dc [draw-ctx!] -][cairo_close_path dc/raw ] + dc [draw-ctx!] +][ + cairo_close_path dc/cr +] OS-draw-brush-bitmap: func [ - ctx [draw-ctx!] - img [red-image!] - crop-1 [red-pair!] - crop-2 [red-pair!] - mode [red-word!] - brush? [logic!] + ctx [draw-ctx!] + img [red-image!] + crop-1 [red-pair!] + crop-2 [red-pair!] + mode [red-word!] + brush? [logic!] ][] OS-draw-brush-pattern: func [ - dc [draw-ctx!] - size [red-pair!] - crop-1 [red-pair!] - crop-2 [red-pair!] - mode [red-word!] - block [red-block!] - brush? [logic!] + dc [draw-ctx!] + size [red-pair!] + crop-1 [red-pair!] + crop-2 [red-pair!] + mode [red-word!] + block [red-block!] + brush? [logic!] ][] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 57328775be..20ed757f13 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2523,6 +2523,9 @@ GPtrArray!: alias struct! [ cairo_restore: "cairo_restore" [ cr [handle!] ] + cairo_stroke_preserve: "cairo_stroke_preserve" [ + cr [handle!] + ] cairo_set_source_rgba: "cairo_set_source_rgba" [ cr [handle!] red [float!] @@ -2572,6 +2575,10 @@ GPtrArray!: alias struct! [ cr [handle!] antialias [integer!] ] + cairo_pattern_set_matrix: "cairo_pattern_set_matrix" [ + pattern [handle!] + matrix [cairo_matrix_t!] + ] cairo_pattern_create_linear: "cairo_pattern_create_linear" [ x0 [float!] y0 [float!] @@ -2606,9 +2613,6 @@ GPtrArray!: alias struct! [ cairo_identity_matrix: "cairo_identity_matrix" [ cr [handle!] ] - cairo_stroke_preserve: "cairo_stroke_preserve" [ - cr [handle!] - ] cairo_get_matrix: "cairo_get_matrix" [ cr [handle!] mat [cairo_matrix_t!] @@ -2621,6 +2625,65 @@ GPtrArray!: alias struct! [ cr [handle!] mat [cairo_matrix_t!] ] + cairo_matrix_init: "cairo_matrix_init" [ + matrix [cairo_matrix_t!] + xx [float!] + yx [float!] + xy [float!] + yy [float!] + x0 [float!] + y0 [float!] + ] + cairo_matrix_init_identity: "cairo_matrix_init_identity" [ + matrix [cairo_matrix_t!] + ] + cairo_matrix_init_translate: "cairo_matrix_init_translate" [ + matrix [cairo_matrix_t!] + tx [float!] + ty [float!] + ] + cairo_matrix_init_scale: "cairo_matrix_init_scale" [ + matrix [cairo_matrix_t!] + sx [float!] + sy [float!] + ] + cairo_matrix_init_rotate: "cairo_matrix_init_rotate" [ + matrix [cairo_matrix_t!] + rad [float!] + ] + cairo_matrix_translate: "cairo_matrix_translate" [ + matrix [cairo_matrix_t!] + tx [float!] + ty [float!] + ] + cairo_matrix_scale: "cairo_matrix_scale" [ + matrix [cairo_matrix_t!] + sx [float!] + sy [float!] + ] + cairo_matrix_rotate: "cairo_matrix_rotate" [ + matrix [cairo_matrix_t!] + rad [float!] + ] + cairo_matrix_invert: "cairo_matrix_invert" [ + matrix [cairo_matrix_t!] + return: [integer!] + ] + cairo_matrix_multiply: "cairo_matrix_multiply" [ + res [cairo_matrix_t!] + a [cairo_matrix_t!] + b [cairo_matrix_t!] + ] + cairo_matrix_transform_distance: "cairo_matrix_transform_distance" [ + matrix [cairo_matrix_t!] + dx [int-ptr!] + dy [int-ptr!] + ] + cairo_matrix_transform_point: "cairo_matrix_transform_point" [ + matrix [cairo_matrix_t!] + dx [int-ptr!] + dy [int-ptr!] + ] ; Related to draw text with cairo (no succes for base widget) replaced by pango_cairo cairo_select_font_face: "cairo_select_font_face" [ cr [handle!] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index b2ea36676b..6191d9e1de 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -77,7 +77,7 @@ Red/System [ #if OS = 'Linux [ draw-ctx!: alias struct! [ - raw [int-ptr!] + cr [handle!] pen-join [integer!] pen-cap [integer!] pen-width [float!] @@ -87,12 +87,11 @@ Red/System [ font-color [integer!] pen? [logic!] brush? [logic!] - pattern [int-ptr!] + grad-pen [handle!] on-image? [logic!] shape-curve? [logic!] font-attrs [handle!] ;-- pango attrs for fonts font-opts [handle!] ;-- cairo opts for fonts - layout [handle!] ;-- Only for draw not for rich-text ] layout-ctx!: alias struct! [ From d566daf0cdecfbd5b2eb6d5fae3a5dce4eaf362c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 24 Nov 2019 11:56:55 +0800 Subject: [PATCH 0531/3432] FIX: crash when click on menu --- modules/view/backends/gtk3/handlers.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 7acfbbd837..6bca39359c 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -912,5 +912,7 @@ menu-item-activate: func [ key [integer!] ][ key: as integer! GET-MENU-KEY(item) - make-event widget key EVT_MENU + if key <> 0 [ + make-event widget key EVT_MENU + ] ] From 428dc3441efff66495846208deab5f92749610fc Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 24 Nov 2019 15:11:48 +0800 Subject: [PATCH 0532/3432] FIX: draw `arc` issues --- modules/view/backends/gtk3/draw.reds | 14 ++++++++++---- modules/view/backends/gtk3/gtk.reds | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 62d50dd37b..75cbe12f82 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -218,6 +218,7 @@ OS-draw-box: func [ y [float!] w [float!] h [float!] + tf [float!] degrees [float!] ][ cr: dc/cr @@ -236,9 +237,10 @@ OS-draw-box: func [ h: as-float lower/y - upper/y either radius <> null [ - t: as-integer either w > h [h][w] - rad: as-float radius/value * 2 - if rad > as float! t [rad: as float! t] + tf: either w > h [h][w] + tf: tf / 2.0 + rad: as-float radius/value + if rad > tf [rad: tf] degrees: pi / 180.0 cairo_new_sub_path cr @@ -607,7 +609,11 @@ OS-draw-arc: func [ closed?: angle < end cairo_save cr - unless closed? [dc/brush?: no] + either closed? [ + cairo_move_to cr cx cy + ][ + cairo_new_sub_path cr + ] cairo_translate cr cx cy cairo_scale cr rad-x rad-y either sweep < 0 [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 20ed757f13..22342b0dc4 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2070,6 +2070,10 @@ GPtrArray!: alias struct! [ path [c-string!] error [handle!] ] + gtk_css_provider_to_string: "gtk_css_provider_to_string" [ + provider [handle!] + return: [c-string!] + ] gtk_style_context_add_provider: "gtk_style_context_add_provider" [ context [handle!] provider [handle!] From 8f4099ce8a1cb1b767611126ba5eefe650cb92e3 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 24 Nov 2019 15:45:50 +0800 Subject: [PATCH 0533/3432] fix: old grad pen need invert matrix --- modules/view/backends/gtk3/draw.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 75cbe12f82..773e7856cb 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -862,13 +862,15 @@ OS-draw-grad-pen-old: func [ n: n + 1 ] cairo_matrix_init matrix 1.0 0.0 0.0 1.0 0.0 0.0 - cairo_pattern_set_matrix pattern matrix if rotate? [ - cairo_matrix_rotate matrix angle + p: PI / 180.0 + cairo_matrix_rotate matrix p * angle ] if scale? [ cairo_matrix_scale matrix x y ] + cairo_matrix_invert matrix + cairo_pattern_set_matrix pattern matrix delta: as-float count - 1 delta: 1.0 / delta From c5ec46176acf8ff143d69f8c34d67ae88bc75534 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 24 Nov 2019 17:14:01 +0800 Subject: [PATCH 0534/3432] FIX: first support grad pen --- modules/view/backends/gtk3/draw.reds | 82 +++++++++++++++++++++++++++- modules/view/backends/gtk3/gtk.reds | 11 ++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 773e7856cb..6f8fcc3653 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -900,7 +900,7 @@ OS-draw-grad-pen-old: func [ ] OS-draw-grad-pen: func [ - ctx [draw-ctx!] + dc [draw-ctx!] type [integer!] stops [red-value!] count [integer!] @@ -909,8 +909,88 @@ OS-draw-grad-pen: func [ focal? [logic!] spread [integer!] brush? [logic!] + /local + point [red-pair!] + x [float!] + y [float!] + pattern [handle!] + delta [float!] + p [float!] + head [red-value!] + next [red-value!] + clr [red-tuple!] + n [integer!] + r [float!] + g [float!] + b [float!] + a [float!] + f [red-float!] ][ + pattern: case [ + type = linear [ + either skip-pos? [ + cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + ][ + point: as red-pair! positions + x: as float! point/x + y: as float! point/y + point: point + 1 + cairo_pattern_create_linear x y as float! point/x as float! point/y + ] + ] + any [ type = radial type = diamond ][ + either skip-pos? [ + cairo_pattern_create_radial 0.0 0.0 0.0 0.0 0.0 1.0 + ][ + either type = radial [ + point: as red-pair! positions + x: as float! point/x + y: as float! point/y + p: get-float as red-integer! point + 1 + cairo_pattern_create_radial x y 0.0 x y p + ][ + cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + ] + ] + ] + true [ + cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + ] + ] + + delta: as-float count - 1 + delta: 1.0 / delta + p: 0.0 + head: as red-value! stops + loop count [ + clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] + n: clr/array1 + r: as-float n and FFh + r: r / 255.0 + g: as-float n >> 8 and FFh + g: g / 255.0 + b: as-float n >> 16 and FFh + b: b / 255.0 + a: as-float 255 - (n >>> 24) + a: a / 255.0 + next: head + 1 + if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] + cairo_pattern_add_color_stop_rgba pattern p r g b a + p: p + delta + head: head + 1 + ] + cairo_pattern_set_extend pattern + case [ + spread = _pad [CAIRO_EXTEND_PAD] + spread = _repeat [CAIRO_EXTEND_REPEAT] + spread = _reflect [CAIRO_EXTEND_REFLECT] + true [CAIRO_EXTEND_NONE] + ] + + if brush? [dc/brush?: yes] ;-- set brush, or set pen + unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] + dc/grad-pen: pattern ] OS-matrix-rotate: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 22342b0dc4..6ec3f9b259 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -471,6 +471,13 @@ cairo_matrix_t!: alias struct! [ y0 [float!] ] +#enum cairo_extend_t! [ + CAIRO_EXTEND_NONE + CAIRO_EXTEND_REPEAT + CAIRO_EXTEND_REFLECT + CAIRO_EXTEND_PAD +] + ; @@ cairo structures to remove if pango_cairo is enough to draw text on cairo ; cairo_text_extents_t!: alias struct! [ ; x_bearing [float!] @@ -2583,6 +2590,10 @@ GPtrArray!: alias struct! [ pattern [handle!] matrix [cairo_matrix_t!] ] + cairo_pattern_set_extend: "cairo_pattern_set_extend" [ + pattern [handle!] + extend [cairo_extend_t!] + ] cairo_pattern_create_linear: "cairo_pattern_create_linear" [ x0 [float!] y0 [float!] From d243388ab503f305dc6473775576eb6339fed5b3 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 25 Nov 2019 10:43:39 +0800 Subject: [PATCH 0535/3432] FIX: improve matrix functions --- modules/view/backends/gtk3/draw.reds | 133 +++++++++++++++++++-------- modules/view/backends/gtk3/gtk.reds | 4 + 2 files changed, 98 insertions(+), 39 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 6f8fcc3653..4e438dfb81 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -995,68 +995,95 @@ OS-draw-grad-pen: func [ OS-matrix-rotate: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] angle [red-integer!] center [red-pair!] /local cr [handle!] rad [float!] + matrix [cairo_matrix_t! value] ][ cr: dc/cr rad: PI / 180.0 * get-float angle - if angle <> as red-integer! center [ - cairo_translate cr as float! center/x - as float! center/y - ] - cairo_rotate cr rad - if angle <> as red-integer! center [ - cairo_translate cr as float! (0 - center/x) - as float! (0 - center/y) + either pen-fill = -1 [ + if angle <> as red-integer! center [ + cairo_translate cr as float! center/x + as float! center/y + ] + cairo_rotate cr rad + if angle <> as red-integer! center [ + cairo_translate cr as float! (0 - center/x) + as float! (0 - center/y) + ] + ][ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_rotate matrix rad + cairo_pattern_set_matrix dc/grad-pen matrix ] ] OS-matrix-scale: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] sx [red-integer!] sy [red-integer!] + /local + matrix [cairo_matrix_t! value] ][ - cairo_scale dc/cr as float! get-float32 sx - as float! get-float32 sy + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_scale matrix get-float sx get-float sy + cairo_pattern_set_matrix dc/grad-pen matrix + ][ + cairo_scale dc/cr get-float sx get-float sy + ] ] OS-matrix-translate: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] x [integer!] y [integer!] + /local + matrix [cairo_matrix_t! value] ][ - cairo_translate dc/cr as-float x - as-float y + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_translate matrix as-float x as-float y + cairo_pattern_set_matrix dc/grad-pen matrix + ][ + cairo_translate dc/cr as-float x as-float y + ] ] OS-matrix-skew: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] sx [red-integer!] sy [red-integer!] /local - m [integer!] - x [float32!] - y [float32!] - u [float32!] - z [float32!] + m [cairo_matrix_t! value] + matrix [cairo_matrix_t! value] + res [cairo_matrix_t! value] ][ - m: 0 - u: as float32! 1.0 - z: as float32! 0.0 - x: as float32! tan degree-to-radians get-float sx TYPE_TANGENT - y: as float32! either sx = sy [0.0][tan degree-to-radians get-float sy TYPE_TANGENT] + m/xx: 1.0 + m/yx: either sx = sy [0.0][tan degree-to-radians get-float sy TYPE_TANGENT] + m/xy: tan degree-to-radians get-float sx TYPE_TANGENT + m/yy: 1.0 + m/x0: 0.0 + m/y0: 0.0 + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_multiply res matrix m + cairo_pattern_set_matrix dc/grad-pen res + ][ + cairo_transform dc/cr m + ] ] OS-matrix-transform: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] center [red-pair!] scale [red-integer!] translate [red-pair!] @@ -1088,33 +1115,61 @@ OS-matrix-pop: func [ OS-matrix-reset: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] + /local + matrix [cairo_matrix_t! value] ][ - cairo_identity_matrix dc/cr + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_init_identity matrix + cairo_pattern_set_matrix dc/grad-pen matrix + ][ + cairo_identity_matrix dc/cr + ] ] OS-matrix-invert: func [ dc [draw-ctx!] - pen [integer!] -][] + pen-fill [integer!] + /local + matrix [cairo_matrix_t! value] +][ + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_invert matrix + cairo_pattern_set_matrix dc/grad-pen matrix + ][ + cairo_get_matrix dc/cr matrix + cairo_matrix_invert matrix + cairo_set_matrix dc/cr matrix + ] +] OS-matrix-set: func [ dc [draw-ctx!] - pen [integer!] + pen-fill [integer!] blk [red-block!] /local m [cairo_matrix_t! value] val [red-integer!] + matrix [cairo_matrix_t! value] + res [cairo_matrix_t! value] ][ m: null val: as red-integer! block/rs-head blk - m/xx: get-float val - m/yx: get-float val + 1 - m/xy: get-float val + 2 - m/yy: get-float val + 3 - m/x0: get-float val + 4 - m/y0: get-float val + 5 - cairo_transform dc/cr :m ; Weirdly it is not cairo_set_matrix because it is a global change! + m/xx: get-float val + m/yx: get-float val + 1 + m/xy: get-float val + 2 + m/yy: get-float val + 3 + m/x0: get-float val + 4 + m/y0: get-float val + 5 + either pen-fill <> -1 [ + cairo_pattern_get_matrix dc/grad-pen matrix + cairo_matrix_multiply res matrix m + cairo_pattern_set_matrix dc/grad-pen res + ][ + cairo_transform dc/cr m + ] ] OS-set-matrix-order: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 6ec3f9b259..2d1d56546e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2590,6 +2590,10 @@ GPtrArray!: alias struct! [ pattern [handle!] matrix [cairo_matrix_t!] ] + cairo_pattern_get_matrix: "cairo_pattern_get_matrix" [ + pattern [handle!] + matrix [cairo_matrix_t!] + ] cairo_pattern_set_extend: "cairo_pattern_set_extend" [ pattern [handle!] extend [cairo_extend_t!] From 41b4095c9e9dd05fc6beb9d31e31d8f9e3319eb0 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 25 Nov 2019 16:40:40 +0800 Subject: [PATCH 0536/3432] FIX: draw shape-arc issues --- modules/view/backends/gtk3/draw.reds | 51 ++++++++++++---------------- modules/view/backends/gtk3/gtk.reds | 8 ++--- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 4e438dfb81..70f56eeb2b 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1395,7 +1395,6 @@ OS-draw-shape-arc: func [ cx [float32!] cy [float32!] cf [float32!] - angle-len [float32!] radius-x [float32!] radius-y [float32!] theta [float32!] @@ -1415,10 +1414,11 @@ OS-draw-shape-arc: func [ sign [float32!] rad-check [float32!] pi2 [float32!] + matrix [cairo_matrix_t! value] ][ cr: dc/cr last-x: 0.0 last-y: 0.0 - if 1 = cairo_has_current_point cr[ + if 1 = cairo_has_current_point cr [ cairo_get_current_point cr :last-x :last-y ] p1-x: as float32! last-x p1-y: as float32! last-y @@ -1458,48 +1458,41 @@ OS-draw-shape-arc: func [ center-x: (cos-val * cx) - (sin-val * cy) + ((p1-x + p2-x) / as float32! 2.0) center-y: (sin-val * cx) + (cos-val * cy) + ((p1-y + p2-y) / as float32! 2.0) - - ;-- transform our ellipse into the unit circle - ; m: CGAffineTransformMakeScale (as float! 1.0) / radius-x (as float! 1.0) / radius-y - ; m: CGAffineTransformRotate m (as float! 0.0) - theta - ; m: CGAffineTransformTranslate m (as float! 0.0) - center-x (as float! 0.0) - center-y - - ; pt1/x: p1-x pt1/y: p1-y - ; pt2/x: p2-x pt2/y: p2-y - ; pt1: CGPointApplyAffineTransform pt1 m - ; pt2: CGPointApplyAffineTransform pt2 m + cairo_matrix_init_scale matrix 1.0 / as float! radius-x 1.0 / as float! radius-y + cairo_matrix_rotate matrix 0.0 - as float! theta + cairo_matrix_translate matrix 0.0 - as float! center-x 0.0 - as float! center-y + last-x: as float! p1-x + last-y: as float! p1-y + cairo_matrix_transform_point matrix :last-x :last-y + p1-x: as float32! last-x + p1-y: as float32! last-y + last-x: as float! p2-x + last-y: as float! p2-y + cairo_matrix_transform_point matrix :last-x :last-y + p2-x: as float32! last-x + p2-y: as float32! last-y ;-- calculate angles cx: atan2f p1-y p1-x cy: atan2f p2-y p2-x - angle-len: cy - cx - either sweep? [ - if angle-len < as float32! 0.0 [ - angle-len: angle-len + pi2 - ] - ][ - if angle-len > as float32! 0.0 [ - angle-len: angle-len - pi2 - ] - ] - ;-- construct the inverse transform - ; m: CGAffineTransformMakeTranslation center-x center-y - ; m: CGAffineTransformRotate m theta - ; m: CGAffineTransformScale m radius-x radius-y - ; CGPathAddRelativeArc ctx/path :m as float32! 0.0 as float32! 0.0 as float32! 1.0 cx angle-len cairo_save cr cairo_new_sub_path cr cairo_translate cr as float! center-x as float! center-y + cairo_rotate cr as float! theta cairo_scale cr as float! radius-x as float! radius-y - cairo_arc cr 0.0 0.0 1.0 as float! cx as float! cy + either sweep? [ + cairo_arc cr 0.0 0.0 1.0 as float! cx as float! cy + ][ + cairo_arc_negative cr 0.0 0.0 1.0 as float! cx as float! cy + ] cairo_restore cr ] OS-draw-shape-close: func [ dc [draw-ctx!] ][ - cairo_close_path dc/cr + ;cairo_close_path dc/cr ] OS-draw-brush-bitmap: func [ diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 2d1d56546e..7f87d477fd 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2695,13 +2695,13 @@ GPtrArray!: alias struct! [ ] cairo_matrix_transform_distance: "cairo_matrix_transform_distance" [ matrix [cairo_matrix_t!] - dx [int-ptr!] - dy [int-ptr!] + dx [float-ptr!] + dy [float-ptr!] ] cairo_matrix_transform_point: "cairo_matrix_transform_point" [ matrix [cairo_matrix_t!] - dx [int-ptr!] - dy [int-ptr!] + dx [float-ptr!] + dy [float-ptr!] ] ; Related to draw text with cairo (no succes for base widget) replaced by pango_cairo cairo_select_font_face: "cairo_select_font_face" [ From 59892de28fb95afdf618aacabea63033c9bcb601 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 25 Nov 2019 17:49:15 +0800 Subject: [PATCH 0537/3432] FIX: now shape-test.red can work --- modules/view/backends/gtk3/draw.reds | 109 +++++++++++++++------------ runtime/definitions.reds | 2 + 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 70f56eeb2b..79447dc819 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1193,6 +1193,7 @@ OS-set-clip: func [ OS-draw-shape-beginpath: func [ dc [draw-ctx!] ][ + cairo_move_to dc/cr 0.0 0.0 ] OS-draw-shape-endpath: func [ @@ -1278,67 +1279,75 @@ draw-curve: func [ short? [logic!] num [integer!] ;-- number of points /local - dx [float!] - dy [float!] - p3y [float!] - p3x [float!] - p2y [float!] - p2x [float!] - p1y [float!] - p1x [float!] - pf [float-ptr!] + dx [float32!] + dy [float32!] + p3y [float32!] + p3x [float32!] + p2y [float32!] + p2x [float32!] + p1y [float32!] + p1x [float32!] + pf [float32-ptr!] pt [red-pair!] + last-x [float!] + last-y [float!] ][ pt: start + 1 - p1x: as-float start/x - p1y: as-float start/y - p2x: as-float pt/x - p2y: as-float pt/y + p1x: as float32! start/x + p1y: as float32! start/y + p2x: as float32! pt/x + p2y: as float32! pt/y if num = 3 [ ;-- cubic Bézier pt: start + 2 - p3x: as-float pt/x - p3y: as-float pt/y + p3x: as float32! pt/x + p3y: as float32! pt/y + ] + + last-x: 0.0 last-y: 0.0 + if 1 = cairo_has_current_point dc/cr [ + cairo_get_current_point dc/cr :last-x :last-y + ] + dx: as float32! last-x + dy: as float32! last-y + if rel? [ + pf: :p1x + loop num [ + pf/1: pf/1 + dx ;-- x + pf/2: pf/2 + dy ;-- y + pf: pf + 2 + ] ] - ; dx: dc/last-pt-x - ; dy: dc/last-pt-y - ; if rel? [ - ; pf: :p1x - ; loop num [ - ; pf/1: pf/1 + dx ;-- x - ; pf/2: pf/2 + dy ;-- y - ; pf: pf + 2 - ; ] - ; ] - - ; if short? [ - ; either dc/shape-curve? [ - ; ;-- The control point is assumed to be the reflection of the control point - ; ;-- on the previous command relative to the current point - ; p1x: dx * 2.0 - dc/control-x - ; p1y: dy * 2.0 - dc/control-y - ; ][ - ; ;-- if previous command is not curve/curv/qcurve/qcurv, use current point - ; p1x: dx - ; p1y: dy - ; ] - ; ] + if short? [ + either dc/shape-curve? [ + ;-- The control point is assumed to be the reflection of the control point + ;-- on the previous command relative to the current point + p1x: dx * 2.0 - dc/control-x + p1y: dy * 2.0 - dc/control-y + ][ + ;-- if previous command is not curve/curv/qcurve/qcurv, use current point + p1x: dx + p1y: dy + ] + ] dc/shape-curve?: yes either num = 3 [ ;-- cubic Bézier - either rel? [cairo_rel_curve_to dc/cr p1x p1y p2x p2y p3x p3y] - [cairo_curve_to dc/cr p1x p1y p2x p2y p3x p3y] - ; dc/control-x: p2x - ; dc/control-y: p2y - ; dc/last-pt-x: p3x - ; dc/last-pt-y: p3y + cairo_curve_to dc/cr + as float! p1x as float! p1y + as float! p2x as float! p2y + as float! p3x as float! p3y + dc/control-x: p2x + dc/control-y: p2y ][ ;-- quadratic Bézier - ;CGPathAddQuadCurveToPoint dc/path null p1x p1y p2x p2y - ; dc/control-x: p1x - ; dc/control-y: p1y - ; dc/last-pt-x: p2x - ; dc/last-pt-y: p2y - 0 + cairo_curve_to dc/cr + (2.0 / 3.0 * as float! p1x) + (1.0 / 3.0 * as float! dx) + (2.0 / 3.0 * as float! p1y) + (1.0 / 3.0 * as float! dy) + (2.0 / 3.0 * as float! p2x) + (1.0 / 3.0 * as float! p1x) + (2.0 / 3.0 * as float! p2y) + (1.0 / 3.0 * as float! p1y) + as float! p2x as float! p2y + dc/control-x: p1x + dc/control-y: p1y ] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 6191d9e1de..88fb67e165 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -89,6 +89,8 @@ Red/System [ brush? [logic!] grad-pen [handle!] on-image? [logic!] + control-x [float32!] + control-y [float32!] shape-curve? [logic!] font-attrs [handle!] ;-- pango attrs for fonts font-opts [handle!] ;-- cairo opts for fonts From 3a60938fb541169d64ca926cf3f596dfe732cb8b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 26 Nov 2019 10:11:25 +0800 Subject: [PATCH 0538/3432] FEAT: implement OS-set-clip command --- modules/view/backends/gtk3/draw.reds | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 79447dc819..3553117892 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1183,9 +1183,30 @@ OS-set-clip: func [ dc [draw-ctx!] upper [red-pair!] lower [red-pair!] + rect? [logic!] + mode [integer!] + /local + cr [handle!] + t [integer!] + x1 [integer!] + x2 [integer!] + y1 [integer!] + y2 [integer!] ][ - print ["set-clip!" lf] - 0 + cr: dc/cr + if rect? [ + if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t] + if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t] + + x1: upper/x + y1: upper/y + x2: lower/x + y2: lower/y + cairo_rectangle cr + as float! x1 as float! y1 + as float! x2 - x1 as float! y2 - y1 + ] + cairo_clip cr ] ;-- shape sub command -- From 1c5be80f05a610d67a62fe6cc0c86576399f542e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 26 Nov 2019 14:09:12 +0800 Subject: [PATCH 0539/3432] FIX: first add grad pattern --- modules/view/backends/gtk3/draw.reds | 106 ++++++++++++++++++++++----- modules/view/backends/gtk3/gtk.reds | 21 +++++- runtime/definitions.reds | 1 + 3 files changed, 107 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 3553117892..2129404505 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -64,6 +64,7 @@ init-draw-ctx: func [ ctx/pen?: yes ctx/brush?: no ctx/grad-pen: null + ctx/grad-brush: null ctx/font-attrs: null ctx/font-opts: null @@ -105,19 +106,15 @@ do-draw-path: func [ cr: dc/cr if dc/brush? [ cairo_save cr - either null? dc/grad-pen [ + either null? dc/grad-brush [ set-source-color cr dc/brush-color ][ - cairo_set_source cr dc/grad-pen + cairo_set_source cr dc/grad-brush ] cairo_fill_preserve cr cairo_restore cr ] - either dc/pen? [ - cairo_stroke cr - ][ - cairo_new_path cr - ] + do-draw-pen dc ] do-draw-pen: func [ @@ -170,6 +167,10 @@ OS-draw-pen: func [ alpha? [logic!] ][ dc/pen?: not off? + unless null? dc/grad-pen [ + cairo_pattern_destroy dc/grad-pen + dc/grad-pen: null + ] if all [not off? dc/pen-color <> color][ dc/pen-color: color dc/font-color: color @@ -184,9 +185,9 @@ OS-draw-fill-pen: func [ alpha? [logic!] ][ dc/brush?: not off? - unless null? dc/grad-pen [ - cairo_pattern_destroy dc/grad-pen - dc/grad-pen: null + unless null? dc/grad-brush [ + cairo_pattern_destroy dc/grad-brush + dc/grad-brush: null ] if dc/brush-color <> color [ dc/brush-color: color @@ -894,9 +895,15 @@ OS-draw-grad-pen-old: func [ head: head + 1 ] - if brush? [dc/brush?: yes] ;-- set brush, or set pen - unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] - dc/grad-pen: pattern + dc/brush?: brush? + dc/pen?: not brush? + either brush? [ + unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] + dc/grad-brush: pattern + ][ + unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] + dc/grad-pen: pattern + ] ] OS-draw-grad-pen: func [ @@ -988,9 +995,15 @@ OS-draw-grad-pen: func [ true [CAIRO_EXTEND_NONE] ] - if brush? [dc/brush?: yes] ;-- set brush, or set pen - unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] - dc/grad-pen: pattern + dc/brush?: brush? + dc/pen?: not brush? + either brush? [ + unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] + dc/grad-brush: pattern + ][ + unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] + dc/grad-pen: pattern + ] ] OS-matrix-rotate: func [ @@ -1542,4 +1555,63 @@ OS-draw-brush-pattern: func [ mode [red-word!] block [red-block!] brush? [logic!] -][] + /local + cr [handle!] + x [integer!] + y [integer!] + w [integer!] + h [integer!] + wrap [integer!] + pattern [handle!] + matrix [cairo_matrix_t! value] +][ + cr: dc/cr + w: size/x + h: size/y + either crop-1 = null [ + x: 0 + y: 0 + ][ + x: crop-1/x + y: crop-1/y + ] + either crop-2 = null [ + w: w - x + h: h - y + ][ + w: either ( x + crop-2/x ) > w [ w - x ][ crop-2/x ] + h: either ( y + crop-2/y ) > h [ h - y ][ crop-2/y ] + ] + wrap: tile + unless mode = null [wrap: symbol/resolve mode/symbol] + case [ + any [wrap = flip-x wrap = flip-y] [w: w * 2] + wrap = flip-xy [w: w * 2 h: h * 2] + true [] + ] + cairo_push_group cr + do-draw cr null block no no yes yes + if wrap = flip-x [ + cairo_scale cr -1.0 1.0 + do-draw cr null block no no yes yes + ] + if wrap = flip-y [ + cairo_matrix_init matrix 1.0 0.0 0.0 -1.0 as float! w as float! h + cairo_transform cr matrix + do-draw cr null block no no yes yes + ] + pattern: cairo_pop_group cr + ;pattern: cairo_pattern_create_mesh + ;-- TBD: wrap mode + cairo_pattern_set_extend pattern CAIRO_EXTEND_PAD;CAIRO_EXTEND_REPEAT + + dc/brush?: brush? + dc/pen?: not brush? + either brush? [ + unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] + dc/grad-brush: pattern + ][ + unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] + dc/grad-pen: pattern + ] +] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 7f87d477fd..3554f6d17c 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -2403,22 +2403,28 @@ GPtrArray!: alias struct! [ ;; LIBCAIRO-file cdecl [ cairo_create: "cairo_create" [ - surf [handle!] + surf [handle!] return: [handle!] ] cairo_destroy: "cairo_destroy" [ cr [handle!] ] - + cairo_push_group: "cairo_push_group" [ + cr [handle!] + ] + cairo_pop_group: "cairo_pop_group" [ + cr [handle!] + return: [handle!] + ] cairo_clip: "cairo_clip" [ cr [handle!] ] cairo_line_to: "cairo_line_to" [ cr [handle!] - x [float!] - y [float!] + x [float!] + y [float!] ] cairo_rel_line_to: "cairo_rel_line_to" [ @@ -2586,6 +2592,10 @@ GPtrArray!: alias struct! [ cr [handle!] antialias [integer!] ] + cairo_pattern_get_type: "cairo_pattern_get_type" [ + pattern [handle!] + return: [integer!] + ] cairo_pattern_set_matrix: "cairo_pattern_set_matrix" [ pattern [handle!] matrix [cairo_matrix_t!] @@ -2622,6 +2632,9 @@ GPtrArray!: alias struct! [ blue [float!] alpha [float!] ] + cairo_pattern_create_mesh: "cairo_pattern_create_mesh" [ + return: [handle!] + ] cairo_pattern_destroy: "cairo_pattern_destroy" [ pattern [handle!] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 88fb67e165..3e9c63d269 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -88,6 +88,7 @@ Red/System [ pen? [logic!] brush? [logic!] grad-pen [handle!] + grad-brush [handle!] on-image? [logic!] control-x [float32!] control-y [float32!] From c8b310b9907abe282a4e4b0b4aaa796a1897cc5c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 26 Nov 2019 14:29:05 +0800 Subject: [PATCH 0540/3432] FIX: grap pen crash --- modules/view/backends/gtk3/draw.reds | 76 +++++++++++++++++++--------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 2129404505..39b579de27 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1014,6 +1014,7 @@ OS-matrix-rotate: func [ /local cr [handle!] rad [float!] + pattern [handle!] matrix [cairo_matrix_t! value] ][ cr: dc/cr @@ -1029,9 +1030,12 @@ OS-matrix-rotate: func [ as float! (0 - center/y) ] ][ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_rotate matrix rad - cairo_pattern_set_matrix dc/grad-pen matrix + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_rotate matrix rad + cairo_pattern_set_matrix pattern matrix + ] ] ] @@ -1041,12 +1045,16 @@ OS-matrix-scale: func [ sx [red-integer!] sy [red-integer!] /local + pattern [handle!] matrix [cairo_matrix_t! value] ][ either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_scale matrix get-float sx get-float sy - cairo_pattern_set_matrix dc/grad-pen matrix + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_scale matrix get-float sx get-float sy + cairo_pattern_set_matrix pattern matrix + ] ][ cairo_scale dc/cr get-float sx get-float sy ] @@ -1058,12 +1066,16 @@ OS-matrix-translate: func [ x [integer!] y [integer!] /local + pattern [handle!] matrix [cairo_matrix_t! value] ][ either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_translate matrix as-float x as-float y - cairo_pattern_set_matrix dc/grad-pen matrix + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_translate matrix as-float x as-float y + cairo_pattern_set_matrix pattern matrix + ] ][ cairo_translate dc/cr as-float x as-float y ] @@ -1075,6 +1087,7 @@ OS-matrix-skew: func [ sx [red-integer!] sy [red-integer!] /local + pattern [handle!] m [cairo_matrix_t! value] matrix [cairo_matrix_t! value] res [cairo_matrix_t! value] @@ -1086,9 +1099,12 @@ OS-matrix-skew: func [ m/x0: 0.0 m/y0: 0.0 either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_multiply res matrix m - cairo_pattern_set_matrix dc/grad-pen res + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_multiply res matrix m + cairo_pattern_set_matrix pattern res + ] ][ cairo_transform dc/cr m ] @@ -1107,9 +1123,9 @@ OS-matrix-transform: func [ rotate: as red-integer! either center + 1 = scale [center][center + 1] center?: rotate <> center - OS-matrix-rotate dc pen rotate center - OS-matrix-scale dc pen scale scale + 1 - OS-matrix-translate dc pen translate/x translate/y + OS-matrix-rotate dc pen-fill rotate center + OS-matrix-scale dc pen-fill scale scale + 1 + OS-matrix-translate dc pen-fill translate/x translate/y ] OS-matrix-push: func [ @@ -1130,12 +1146,16 @@ OS-matrix-reset: func [ dc [draw-ctx!] pen-fill [integer!] /local + pattern [handle!] matrix [cairo_matrix_t! value] ][ either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_init_identity matrix - cairo_pattern_set_matrix dc/grad-pen matrix + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_init_identity matrix + cairo_pattern_set_matrix pattern matrix + ] ][ cairo_identity_matrix dc/cr ] @@ -1145,12 +1165,16 @@ OS-matrix-invert: func [ dc [draw-ctx!] pen-fill [integer!] /local + pattern [handle!] matrix [cairo_matrix_t! value] ][ either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_invert matrix - cairo_pattern_set_matrix dc/grad-pen matrix + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_invert matrix + cairo_pattern_set_matrix pattern matrix + ] ][ cairo_get_matrix dc/cr matrix cairo_matrix_invert matrix @@ -1163,6 +1187,7 @@ OS-matrix-set: func [ pen-fill [integer!] blk [red-block!] /local + pattern [handle!] m [cairo_matrix_t! value] val [red-integer!] matrix [cairo_matrix_t! value] @@ -1177,9 +1202,12 @@ OS-matrix-set: func [ m/x0: get-float val + 4 m/y0: get-float val + 5 either pen-fill <> -1 [ - cairo_pattern_get_matrix dc/grad-pen matrix - cairo_matrix_multiply res matrix m - cairo_pattern_set_matrix dc/grad-pen res + pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + unless null? pattern [ + cairo_pattern_get_matrix pattern matrix + cairo_matrix_multiply res matrix m + cairo_pattern_set_matrix pattern res + ] ][ cairo_transform dc/cr m ] From 536e300592ae326dd7fe238d46f56ae6b41adb73 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 27 Nov 2019 11:05:39 +0800 Subject: [PATCH 0541/3432] FIX: set gradiant pen/fill-pen issue --- modules/view/backends/gtk3/draw.reds | 363 ++++++++++++++++++++++++++- modules/view/backends/gtk3/gtk.reds | 28 +++ runtime/definitions.reds | 2 + 3 files changed, 381 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 39b579de27..0139da9801 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -135,6 +135,309 @@ do-draw-pen: func [ ] ] +copy-gradiant-props: func [ + grad [handle!] + ngrad [handle!] + /local + cnt [integer!] + index [integer!] + offset [float!] + r [float!] + g [float!] + b [float!] + a [float!] + mode [integer!] +][ + cnt: 0 + cairo_pattern_get_color_stop_count grad :cnt + index: 0 + loop cnt [ + offset: 0.0 r: 0.0 g: 0.0 b: 0.0 a: 0.0 + cairo_pattern_get_color_stop_rgba grad index + :offset :r :g :b :a + cairo_pattern_add_color_stop_rgba ngrad offset r g b a + index: index + 1 + ] + mode: cairo_pattern_get_extend grad + cairo_pattern_set_extend ngrad mode +] + +check-grad-line: func [ + grad [handle!] + point [red-pair!] + end [red-pair!] + return: [handle!] + /local + type [integer!] + ngrad [handle!] + x [float32!] + y [float32!] + px [float32!] + py [float32!] + delta [float32!] +][ + type: cairo_pattern_get_type grad + case [ + type = CAIRO_PATTERN_TYPE_LINEAR [ + ngrad: cairo_pattern_create_linear + as float! point/x as float! point/y + as float! end/x as float! point/y + ] + type = CAIRO_PATTERN_TYPE_RADIAL [ + x: as float32! point/x + y: as float32! point/y + px: (as float32! end/x) - x + py: (as float32! end/y) - y + delta: (px * px) + (py * py) + delta: sqrtf delta + px: (as float32! end/x) + x + py: (as float32! end/y) + y + px: px / 2.0 py: py / 2.0 + ngrad: cairo_pattern_create_radial + as float! px as float! py 0.0 + as float! px as float! py as float! delta + ] + true [return null] + ] + + copy-gradiant-props grad ngrad + ngrad +] + +check-grad-pen-line: func [ + dc [draw-ctx!] + point [red-pair!] + end [red-pair!] + /local + ngrad [handle!] +][ + if all [ + dc/pen? + not null? dc/grad-pen + dc/gpen-resize? + ][ + ngrad: check-grad-line dc/grad-pen point end + unless null? ngrad [ + cairo_pattern_destroy dc/grad-pen + dc/grad-pen: ngrad + dc/gpen-resize?: false + ] + ] +] + +check-grad-brush-line: func [ + dc [draw-ctx!] + point [red-pair!] + end [red-pair!] + /local + ngrad [handle!] +][ + if all [ + dc/brush? + not null? dc/grad-brush + dc/gbrush-resize? + ][ + ngrad: check-grad-line dc/grad-brush point end + unless null? ngrad [ + cairo_pattern_destroy dc/grad-brush + dc/grad-brush: ngrad + dc/gbrush-resize?: false + ] + ] +] + +get-shape-center: func [ + start [red-pair!] + end [red-pair!] + cx [int-ptr!] + cy [int-ptr!] + d [int-ptr!] + /local + point [red-pair!] + dx [integer!] + dy [integer!] + x0 [integer!] + y0 [integer!] + x1 [integer!] + y1 [integer!] + a [integer!] + r [integer!] + signedArea [float!] + centroid-x [float!] + centroid-y [float!] +][ + ;-- implementation taken from http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon + x0: 0 y0: 0 x1: 0 y1: 0 + a: 0 signedArea: 0.0 + centroid-x: 0.0 centroid-y: 0.0 + point: start + while [point <= end] [ + x0: point/x + y0: point/y + point: point + 1 + x1: point/x + y1: point/y + a: x0 * y1 - (x1 * y0) + signedArea: signedArea + as-float a + centroid-x: centroid-x + as-float ((x0 + x1) * a) + centroid-y: centroid-y + as-float ((y0 + y1) * a) + ] + x0: point/x + y0: point/y + x1: start/x + y1: start/y + a: x0 * y1 - (x1 * y0) + signedArea: signedArea + as-float a + centroid-x: centroid-x + as-float ((x0 + x1) * a) + centroid-y: centroid-y + as-float ((y0 + y1) * a) + + signedArea: signedArea * 0.5 + centroid-x: centroid-x / (signedArea * 6.0) + centroid-y: centroid-y / (signedArea * 6.0) + + cx/value: as-integer centroid-x + cy/value: as-integer centroid-y + ;-- take biggest distance + d/value: 0 + point: start + while [point <= end] [ + dx: cx/value - point/x + dy: cy/value - point/y + r: as-integer sqrt as-float ( dx * dx + ( dy * dy ) ) + if r > d/value [ d/value: r ] + point: point + 1 + ] +] + +check-grad-brush-box: func [ + dc [draw-ctx!] + point [red-pair!] + end [red-pair!] + /local + type [integer!] + cx [integer!] + cy [integer!] + d [integer!] + ngrad [handle!] +][ + if all [ + dc/brush? + not null? dc/grad-brush + dc/gbrush-resize? + ][ + type: cairo_pattern_get_type dc/grad-brush + case [ + type = CAIRO_PATTERN_TYPE_LINEAR [ + ngrad: check-grad-line dc/grad-brush point end + ] + type = CAIRO_PATTERN_TYPE_RADIAL [ + cx: 0 cy: 0 d: 0 + get-shape-center point end :cx :cy :d + ngrad: cairo_pattern_create_radial + as float! cx as float! cy 0.0 + as float! cx as float! cy as float! d + + copy-gradiant-props dc/grad-brush ngrad + ] + true [exit] + ] + + unless null? ngrad [ + cairo_pattern_destroy dc/grad-brush + dc/grad-brush: ngrad + dc/gbrush-resize?: false + ] + ] +] + +check-grad-pen-arc: func [ + dc [draw-ctx!] + x [float!] + y [float!] + radius [float!] + /local + type [integer!] + ngrad [handle!] + ex [float!] + ey [float!] +][ + if all [ + dc/pen? + not null? dc/grad-pen + dc/gpen-resize? + ][ + type: cairo_pattern_get_type dc/grad-pen + case [ + type = CAIRO_PATTERN_TYPE_LINEAR [ + ex: x + radius + ex: ex * pi + ey: y + radius + ey: ey * pi + ngrad: cairo_pattern_create_linear + x y ex ey + copy-gradiant-props dc/grad-pen ngrad + ] + type = CAIRO_PATTERN_TYPE_RADIAL [ + ngrad: cairo_pattern_create_radial + x y 0.0 + x y radius + copy-gradiant-props dc/grad-pen ngrad + ] + true [exit] + ] + + unless null? ngrad [ + cairo_pattern_destroy dc/grad-pen + dc/grad-pen: ngrad + dc/gpen-resize?: false + ] + ] +] + +check-grad-brush-arc: func [ + dc [draw-ctx!] + x [float!] + y [float!] + radius [float!] + /local + type [integer!] + ngrad [handle!] + ex [float!] + ey [float!] +][ + if all [ + dc/brush? + not null? dc/grad-brush + dc/gbrush-resize? + ][ + type: cairo_pattern_get_type dc/grad-brush + case [ + type = CAIRO_PATTERN_TYPE_LINEAR [ + ex: x + radius + ex: ex * pi + ey: y + radius + ey: ey * pi + ngrad: cairo_pattern_create_linear + x y ex ey + copy-gradiant-props dc/grad-brush ngrad + ] + type = CAIRO_PATTERN_TYPE_RADIAL [ + ngrad: cairo_pattern_create_radial + x y 0.0 + x y radius + copy-gradiant-props dc/grad-brush ngrad + ] + true [exit] + ] + + unless null? ngrad [ + cairo_pattern_destroy dc/grad-brush + dc/grad-brush: ngrad + dc/gbrush-resize?: false + ] + ] +] + OS-draw-anti-alias: func [ dc [draw-ctx!] on? [logic!] @@ -147,16 +450,18 @@ OS-draw-line: func [ point [red-pair!] end [red-pair!] /local + iter [red-pair!] cr [handle!] ][ cr: dc/cr cairo_move_to cr as-float point/x as-float point/y - point: point + 1 + iter: point + 1 - while [point <= end][ - cairo_line_to cr as-float point/x as-float point/y - point: point + 1 + while [iter <= end][ + cairo_line_to cr as-float iter/x as-float iter/y + iter: iter + 1 ] + check-grad-pen-line dc point end do-draw-pen dc ] @@ -253,6 +558,8 @@ OS-draw-box: func [ ][ cairo_rectangle cr x y w h ] + check-grad-pen-line dc upper lower + check-grad-brush-box dc upper lower do-draw-path dc ] @@ -265,6 +572,8 @@ OS-draw-triangle: func [ start: start + 1 ] cairo_close_path dc/cr ;-- close the triangle + check-grad-pen-line dc start start + 2 + check-grad-brush-box dc start start + 2 do-draw-path dc ] @@ -279,6 +588,8 @@ OS-draw-polygon: func [ start > end ] cairo_close_path dc/cr + check-grad-pen-line dc start end + check-grad-brush-box dc start end do-draw-path dc ] @@ -379,6 +690,8 @@ OS-draw-spline: func [ end ] + check-grad-pen-line dc start end + check-grad-brush-box dc start end do-draw-path dc ] @@ -430,6 +743,9 @@ OS-draw-circle: func [ as-float rad-y cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi cairo_restore cr + if rad-x < rad-y [rad-x: rad-y] + check-grad-pen-arc dc as float! center/x as float! center/y as float! rad-x + check-grad-brush-arc dc as float! center/x as float! center/y as float! rad-x do-draw-path dc ] @@ -441,18 +757,25 @@ OS-draw-ellipse: func [ cr [handle!] rad-x [integer!] rad-y [integer!] + cx [integer!] + cy [integer!] ][ cr: dc/cr rad-x: diameter/x / 2 rad-y: diameter/y / 2 + cx: upper/x + rad-x + cy: upper/y + rad-y cairo_save cr - cairo_translate cr as-float upper/x + rad-x - as-float upper/y + rad-y + cairo_translate cr as-float cx + as-float cy cairo_scale cr as-float rad-x as-float rad-y cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi cairo_restore cr + if rad-x < rad-y [rad-x: rad-y] + check-grad-pen-arc dc as float! cx as float! cy as float! rad-x + check-grad-brush-arc dc as float! cx as float! cy as float! rad-x do-draw-path dc ] @@ -625,6 +948,9 @@ OS-draw-arc: func [ if closed? [ cairo_close_path cr ] + if rad-x < rad-y [rad-x: rad-y] + check-grad-pen-arc dc cx cy rad-x + check-grad-brush-arc dc cx cy rad-x cairo_restore cr either closed? [ do-draw-path dc @@ -659,6 +985,7 @@ OS-draw-curve: func [ as-float p2/y as-float p3/x as-float p3/y + check-grad-pen-line dc start start + 2 do-draw-pen dc ] @@ -895,14 +1222,16 @@ OS-draw-grad-pen-old: func [ head: head + 1 ] - dc/brush?: brush? - dc/pen?: not brush? either brush? [ + dc/brush?: yes unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] dc/grad-brush: pattern + dc/gbrush-resize?: no ][ + dc/pen?: yes unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] dc/grad-pen: pattern + dc/gpen-resize?: no ] ] @@ -917,6 +1246,7 @@ OS-draw-grad-pen: func [ spread [integer!] brush? [logic!] /local + resize? [logic!] point [red-pair!] x [float!] y [float!] @@ -933,9 +1263,11 @@ OS-draw-grad-pen: func [ a [float!] f [red-float!] ][ + resize?: false pattern: case [ type = linear [ either skip-pos? [ + resize?: true cairo_pattern_create_linear 0.0 0.0 1.0 1.0 ][ point: as red-pair! positions @@ -947,6 +1279,7 @@ OS-draw-grad-pen: func [ ] any [ type = radial type = diamond ][ either skip-pos? [ + resize?: true cairo_pattern_create_radial 0.0 0.0 0.0 0.0 0.0 1.0 ][ either type = radial [ @@ -956,11 +1289,13 @@ OS-draw-grad-pen: func [ p: get-float as red-integer! point + 1 cairo_pattern_create_radial x y 0.0 x y p ][ + resize?: true cairo_pattern_create_linear 0.0 0.0 1.0 1.0 ] ] ] true [ + resize?: true cairo_pattern_create_linear 0.0 0.0 1.0 1.0 ] ] @@ -995,14 +1330,16 @@ OS-draw-grad-pen: func [ true [CAIRO_EXTEND_NONE] ] - dc/brush?: brush? - dc/pen?: not brush? either brush? [ + dc/brush?: yes unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] dc/grad-brush: pattern + dc/gbrush-resize?: resize? ][ + dc/pen?: yes unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] dc/grad-pen: pattern + dc/gpen-resize?: resize? ] ] @@ -1633,13 +1970,15 @@ OS-draw-brush-pattern: func [ ;-- TBD: wrap mode cairo_pattern_set_extend pattern CAIRO_EXTEND_PAD;CAIRO_EXTEND_REPEAT - dc/brush?: brush? - dc/pen?: not brush? either brush? [ + dc/brush?: yes unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] dc/grad-brush: pattern + dc/gbrush-resize?: no ][ + dc/pen?: yes unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] dc/grad-pen: pattern + dc/gpen-resize?: no ] ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 3554f6d17c..89d232ea0f 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -462,6 +462,15 @@ PangoAttribute!: alias struct! [ CAIRO_ANTIALIAS_BEST ] +#enum cairo_pattern_type_t! [ + CAIRO_PATTERN_TYPE_SOLID + CAIRO_PATTERN_TYPE_SURFACE + CAIRO_PATTERN_TYPE_LINEAR + CAIRO_PATTERN_TYPE_RADIAL + CAIRO_PATTERN_TYPE_MESH + CAIRO_PATTERN_TYPE_RASTER_SOURCE +] + cairo_matrix_t!: alias struct! [ xx [float!] yx [float!] @@ -2608,6 +2617,10 @@ GPtrArray!: alias struct! [ pattern [handle!] extend [cairo_extend_t!] ] + cairo_pattern_get_extend: "cairo_pattern_get_extend" [ + pattern [handle!] + return: [cairo_extend_t!] + ] cairo_pattern_create_linear: "cairo_pattern_create_linear" [ x0 [float!] y0 [float!] @@ -2632,6 +2645,21 @@ GPtrArray!: alias struct! [ blue [float!] alpha [float!] ] + cairo_pattern_get_color_stop_count: "cairo_pattern_get_color_stop_count" [ + pattern [handle!] + cnt [int-ptr!] + return: [integer!] + ] + cairo_pattern_get_color_stop_rgba: "cairo_pattern_get_color_stop_rgba" [ + pattern [handle!] + index [integer!] + offset [float-ptr!] + r [float-ptr!] + g [float-ptr!] + b [float-ptr!] + a [float-ptr!] + return: [integer!] + ] cairo_pattern_create_mesh: "cairo_pattern_create_mesh" [ return: [handle!] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 3e9c63d269..7b35268c19 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -88,7 +88,9 @@ Red/System [ pen? [logic!] brush? [logic!] grad-pen [handle!] + gpen-resize? [logic!] grad-brush [handle!] + gbrush-resize? [logic!] on-image? [logic!] control-x [float32!] control-y [float32!] From 89224de676db23bbaff2cf301625dfb70d5f62fc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 27 Nov 2019 18:17:13 +0100 Subject: [PATCH 0542/3432] FIX: error out on :/ sequence inside a path. --- runtime/lexer.reds | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cb31cfe938..549c1151da 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1600,9 +1600,6 @@ lexer: context [ index [integer!] close? [logic!] ][ - if all [e < lex/in-end e/1 = #":"][ - throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths - ] close?: either e >= lex/in-end [yes][ ;-- EOF reached cp: as-integer e/1 index: lex-classes/cp and FFh + 1 ;-- query the class of ending character @@ -1610,11 +1607,17 @@ lexer: context [ ] either close? [ type: either all [e < lex/in-end e/1 = #":"][ + if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence + throw-error lex s e TYPE_PATH + ] lex/in-pos: e + 1 ;-- skip : TYPE_SET_PATH ][-1] close-block lex s e -1 type ][ + if all [e < lex/in-end e/1 = #":"][ + throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths + ] lex/in-pos: e + 1 ;-- skip / ] ] From c692bc0987cc98a6c10af50fceac20491c2e964b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 25 Sep 2019 21:36:30 +0200 Subject: [PATCH 0543/3432] FIX: removes unnecessary parens in `load` code. Red compiler improvements and fixes allow such code pattern to compile without workarounds. --- environment/functions.red | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 6c4fcbffc5..7845ee471f 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -400,7 +400,7 @@ load: function [ file! [ suffix: suffix? source foreach [name codec] system/codecs [ - if (find codec/suffixes suffix) [ ;@@ temporary required until dyn-stack implemented + if find codec/suffixes suffix [ return do [codec/decode source] ] ] @@ -411,7 +411,7 @@ load: function [ either source/1 = 200 [ foreach [name codec] system/codecs [ foreach mime codec/mime-type [ - if (find source/2/Content-Type mold mime) [ + if find source/2/Content-Type mold mime [ return do [codec/decode source/3] ] ] From d1c73e40937e712537b846d67453532234d0249e Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 27 Sep 2019 18:45:45 +0200 Subject: [PATCH 0544/3432] FIX: macOS: Transform command in DRAW does not work properly. --- modules/view/backends/macOS/draw.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/draw.reds b/modules/view/backends/macOS/draw.reds index fda20b230b..5590ba0f0e 100644 --- a/modules/view/backends/macOS/draw.reds +++ b/modules/view/backends/macOS/draw.reds @@ -1401,9 +1401,9 @@ OS-matrix-transform: func [ rotate: as red-integer! either center + 1 = scale [center][center + 1] center?: rotate <> center - OS-matrix-rotate dc pen rotate center - OS-matrix-scale dc pen scale scale + 1 _OS-matrix-translate dc/raw translate/x translate/y + OS-matrix-scale dc pen scale scale + 1 + OS-matrix-rotate dc pen rotate center ] OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ From 390714af32711e8027fa7d0d8baddc11e3dfe82d Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 27 Sep 2019 18:46:20 +0200 Subject: [PATCH 0545/3432] FIX: macOS: handling leftover events when starting a new window. --- modules/view/backends/macOS/events.reds | 29 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/macOS/events.reds b/modules/view/backends/macOS/events.reds index 1fdad66deb..723561c112 100644 --- a/modules/view/backends/macOS/events.reds +++ b/modules/view/backends/macOS/events.reds @@ -604,13 +604,32 @@ do-events: func [ event [int-ptr!] ][ msg?: no - timeout: either no-wait? [0][ - loop-started?: yes - objc_msgSend [NSApp sel_getUid "activateIgnoringOtherApps:" 1] - objc_msgSend [NSApp sel_getUid "finishLaunching"] - objc_msgSend [objc_getClass "NSDate" sel_getUid "distantFuture"] + timeout: objc_msgSend [ + objc_getClass "NSDate" + sel_getUid "dateWithTimeIntervalSinceNow:" + 0.05 ] + loop 10 [ ;; FIXME Consume some leftover events. Find a better solution !!! + pool: objc_msgSend [objc_getClass "NSAutoreleasePool" sel_getUid "alloc"] + objc_msgSend [pool sel_getUid "init"] + + event: as int-ptr! objc_msgSend [ + NSApp sel_getUid "nextEventMatchingMask:untilDate:inMode:dequeue:" + NSAnyEventMask + timeout + NSDefaultRunLoopMode + true + ] + objc_msgSend [pool sel_getUid "drain"] + ] + + unless no-wait? [ + loop-started?: yes + objc_msgSend [NSApp sel_getUid "activateIgnoringOtherApps:" 1] + objc_msgSend [NSApp sel_getUid "finishLaunching"] + timeout: objc_msgSend [objc_getClass "NSDate" sel_getUid "distantFuture"] + ] until [ pool: objc_msgSend [objc_getClass "NSAutoreleasePool" sel_getUid "alloc"] objc_msgSend [pool sel_getUid "init"] From ac64ae03590128aadf7cfa7570b8070ea4612adb Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 15:29:06 +0300 Subject: [PATCH 0546/3432] FEAT: clipboard extension to support images and file lists, Windows only; FIX: for issue #4055 --- environment/console/GUI/core.red | 7 +- environment/functions.red | 31 +++ environment/routines.red | 8 - runtime/clipboard.reds | 350 ++++++++++++++++++++++++++-- runtime/platform/image-gdiplus.reds | 6 + 5 files changed, 367 insertions(+), 35 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 6712b6a1cb..5fe361836b 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -625,7 +625,10 @@ object [ paste: func [/resume /local nl? start end idx][ delete-selected - unless resume [clipboard: read-clipboard] + unless resume [ + clipboard: read-clipboard + if image? clipboard [clipboard: none] + ] if all [clipboard not empty? clipboard][ start: clipboard end: find clipboard #"^/" @@ -658,7 +661,7 @@ object [ paste-cnt: 0 ] ] - not empty? clipboard + all [clipboard not empty? clipboard] ] cut: func [][ diff --git a/environment/functions.red b/environment/functions.red index 7845ee471f..e627529e06 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -1069,6 +1069,37 @@ last?: func [ 1 = length? series ] +clipboard-internal: context [ + read-clipboard*: routine ["Return the contents of the system clipboard"][ + stack/set-last clipboard/read + ] + + write-clipboard*: routine ["Write content to the system clipboard" data [any-type!]][ + logic/box clipboard/write as red-value! data + ] +] + +read-clipboard: func ["Return the contents of the system clipboard" return: [string! block! image!] /local r] [ + also r: clipboard-internal/read-clipboard* + if block? r [forall r [change r to-red-file r/1]] +] + +write-clipboard: func ["Write content to the system clipboard" data [string! block! image! none!]] [ + either block? data [ + data: copy data + forall data [change data to-local-file :data/1] + ][ + all [ + image? data + empty? data + data: none + ] + ] + clipboard-internal/write-clipboard* data +] + +unset 'clipboard-internal + ;------------------------------------------ ;- Aliases - ;------------------------------------------ diff --git a/environment/routines.red b/environment/routines.red index 8f990d9e32..f07c850f55 100644 --- a/environment/routines.red +++ b/environment/routines.red @@ -116,14 +116,6 @@ as-rgba: :as-ipv4 ;-- Temporary definition -- -read-clipboard: routine ["Return the contents of the system clipboard"][ - stack/set-last clipboard/read -] - -write-clipboard: routine ["Write content to the system clipboard" data [string!]][ - logic/box clipboard/write as red-value! data -] - write-stdout: routine ["Write data to STDOUT" data [any-type!]][ ;-- internal use only simple-io/write null as red-value! data null null no no no ] \ No newline at end of file diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index 6813af8f90..4ae137ecc1 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -13,6 +13,7 @@ Red/System [ clipboard: context [ #switch OS [ Windows [ + #import [ "User32.dll" stdcall [ OpenClipboard: "OpenClipboard" [ @@ -41,6 +42,10 @@ clipboard: context [ GetForegroundWindow: "GetForegroundWindow" [ return: [integer!] ] + RegisterClipboardFormat: "RegisterClipboardFormatA" [ + lpszFormat [c-string!] + return: [integer!] + ] ] "kernel32.dll" stdcall [ GlobalAlloc: "GlobalAlloc" [ @@ -60,6 +65,10 @@ clipboard: context [ hMem [integer!] return: [integer!] ] + GlobalSize: "GlobalSize" [ + hMem [integer!] + return: [integer!] ;-- valid for 32bit exe only + ] lstrlen: "lstrlenW" [ str [byte-ptr!] return: [integer!] @@ -68,13 +77,76 @@ clipboard: context [ dwMilliseconds [integer!] ] ] + "Shell32.dll" stdcall [ + DragQueryFile: "DragQueryFileW" [ + hDrop [integer!] + iFile [integer!] + lpszFile [byte-ptr!] + cch [integer!] + return: [integer!] + ] + ] + ] + + DROPFILES!: alias struct! [ + pFiles [integer!] + pt [tagPOINT value] + fNC [logic!] + fWide [logic!] + ] + + BitmapData!: alias struct! [ + width [integer!] + height [integer!] + stride [integer!] + pixelFormat [integer!] + scan0 [byte-ptr!] + reserved [integer!] + ] + + BITMAPV5HEADER!: alias struct! [ + Size [integer!] + Width [integer!] + Height [integer!] + PlanesBitCount [integer!] + Compression [integer!] + SizeImage [integer!] + XPelsPerMeter [integer!] + YPelsPerMeter [integer!] + ClrUsed [integer!] + ClrImportant [integer!] + RedMask [integer!] + GreenMask [integer!] + BlueMask [integer!] + AlphaMask [integer!] + CSType [integer!] + EndpointsRedX [integer!] + EndpointsRedY [integer!] + EndpointsRedZ [integer!] + EndpointsGreenX [integer!] + EndpointsGreenY [integer!] + EndpointsGreenZ [integer!] + EndpointsBlueX [integer!] + EndpointsBlueY [integer!] + EndpointsBlueZ [integer!] + GammaRed [integer!] + GammaGreen [integer!] + GammaBlue [integer!] + Intent [integer!] + ProfileData [integer!] + ProfileSize [integer!] + Reserved [integer!] ] #define CF_TEXT 1 #define CF_BITMAP 2 + #define CF_TIFF 6 ;; TBD #define CF_OEMTEXT 7 #define CF_DIB 8 + #define CF_RIFF 11 ;; TBD + #define CF_WAVE 12 ;; TBD #define CF_UNICODETEXT 13 + #define CF_HDROP 15 #define CF_DIBV5 17 main-hWnd: as int-ptr! 0 @@ -84,11 +156,23 @@ clipboard: context [ /local hMem [integer!] p [byte-ptr!] + p1 [byte-ptr!] + p2 [byte-ptr!] + bufsz [integer!] ok [logic!] val [red-value!] + blk [red-block!] + str [red-string!] + bmp [integer!] + fmts [int-ptr!] + count [integer!] + i [integer!] + len [integer!] + hdr [BITMAPV5HEADER!] ][ + val: none-value p: null - val: as red-value! none-value + i: 0 ;-- OpenClipboard often fails on W7 after an EmptyClipboard call, so be persistent ok: yes @@ -99,15 +183,114 @@ clipboard: context [ ] unless ok [return as red-value! false-value] - hMem: GetClipboardData CF_UNICODETEXT - if hMem <> 0 [ - p: GlobalLock hMem - if p <> null [ - val: as red-value! string/load as-c-string p lstrlen p UTF-16LE + loop 1 [ ;-- trick for `break` to work + + ;-- test text first + hMem: GetClipboardData CF_UNICODETEXT + if hMem <> 0 [ + p: GlobalLock hMem + unless null? p [ + str: as red-string! stack/push* + str/header: TYPE_UNSET + str/head: 0 + str/cache: null + str/node: unicode/load-utf16 as-c-string p lstrlen p null yes + str/header: TYPE_STRING + val: as red-value! str + GlobalUnlock hMem + ] + break ] - GlobalUnlock hMem - ] + + ;-- test for a list of files + hMem: GetClipboardData CF_HDROP + if hMem <> 0 [ + p: GlobalLock hMem + unless null? p [ + ;-- files can be in ANSI codepage; DragQueryFileW func deals with that + count: DragQueryFile hMem FFFFFFFFh null 0 + assert count >= 0 + blk: block/push-only* count + i: 0 bufsz: 0 p1: null + loop count [ + len: DragQueryFile hMem i null 0 + if len > bufsz [ + bufsz: either len > 260 [len][260] + p2: realloc p1 bufsz * 2 + if null? p2 [free p1 p1: null break] + p1: p2 + ] + DragQueryFile hMem i p1 bufsz + string/load-at as-c-string p1 lstrlen p1 ALLOC_TAIL(blk) UTF-16LE + i: i + 1 + ] + unless null? p1 [free p1 p1: null] + val: as red-value! blk + GlobalUnlock hMem + ] + break + ] + + ;-- test for images: first for raw data; then for standard DIB + + ;-- these formats are supported by *some* programs + ;; see https://stackoverflow.com/a/6565158 + fmts: [0 0 0] + fmts/1: RegisterClipboardFormat "PNG" + fmts/2: RegisterClipboardFormat "JFIF" + fmts/3: RegisterClipboardFormat "GIF" + assert all [fmts/1 <> 0 fmts/2 <> 0 fmts/3 <> 0] + + loop size? fmts [ + hMem: GetClipboardData fmts/1 + if hMem <> 0 [break] + fmts: fmts + 1 + ] + if hMem <> 0 [ + p: GlobalLock hMem + unless null? p [ + val: as red-value! image/load-binary binary/load p GlobalSize hMem + GlobalUnlock hMem + ] + break + ] + + ;-- finally try the standard DIB: supports the alpha-channel unless it's messed with + ;; see on the transparency support: https://stackoverflow.com/a/46400011 + hMem: GetClipboardData CF_DIBV5 + if hMem <> 0 [ + p: GlobalLock hMem + unless null? p [ + hdr: as BITMAPV5HEADER! p + bmp: 0 + either all [ ;-- is format compatible with Red GDI+ image? + hdr/PlanesBitCount >> 16 = 32 + hdr/Compression = 3 ;-- BI_BITFIELDS + hdr/AlphaMask = FF000000h + hdr/RedMask = 00FF0000h + hdr/GreenMask = 0000FF00h + hdr/BlueMask = 000000FFh + ][ ;-- can copy the data directly + if hdr/Height < 0 [hdr/Height: 0 - hdr/Height] + assert all [0 = OS-image/GdipGetImagePixelFormat bmp :i i = PixelFormat32bppARGB] + OS-image/GdipCreateBitmapFromScan0 hdr/Width hdr/Height 0 PixelFormat32bppARGB p :bmp + ][ ;-- will have to convert, losing the alpha data if any + OS-image/GdipCreateBitmapFromGdiDib + p p + hdr/Size + (hdr/ClrUsed * 4) + hdr/ProfileSize :bmp + ] + val: as red-value! image/init-image as red-image! stack/push* as int-ptr! bmp + GlobalUnlock hMem + ] + break + ] + + ];; loop 1 + CloseClipboard + + ;-- none = general success but empty or unsupported data + ;-- false = failure during data retrieval + if all [hMem <> 0 null? p] [return as red-value! false-value] val ] @@ -115,28 +298,131 @@ clipboard: context [ data [red-value!] return: [logic!] /local - res [integer!] + res [int-ptr!] + fmts [int-ptr!] + hMem [int-ptr!] ok [logic!] len [integer!] - hMem [integer!] p [byte-ptr!] p1 [byte-ptr!] + value [red-value!] + tail [red-value!] + bin [red-binary!] + df [DROPFILES!] + bmdata [BitmapData!] + hdr [BITMAPV5HEADER!] ][ - hMem: 0 + hMem: [0 0] hMem/1: 0 hMem/2: 0 + fmts: [0 0] fmts/1: 0 fmts/2: 0 ;-- let the memory stuff come before OpenClipboard - ;-- this delays OpenClipboard an extra bit, resulting in lesser failure rate + ;; this delays OpenClipboard an extra bit, resulting in lesser failure rate + ;; plus, it can throw an error from this block switch TYPE_OF(data) [ + + TYPE_NONE [0] ;-- allow `none` to empty the clipboard + TYPE_STRING [ + fmts/1: CF_UNICODETEXT len: -1 p1: as byte-ptr! unicode/to-utf16-len as red-string! data :len yes - hMem: GlobalAlloc 2 len * 2 + 2 - p: GlobalLock hMem - copy-memory p p1 len * 2 + 2 - GlobalUnlock hMem + hMem/1: GlobalAlloc 2 len * 2 + 2 + if hMem/1 <> 0 [ + p: GlobalLock hMem/1 + unless null? p [ + copy-memory p p1 len * 2 + 2 + GlobalUnlock hMem/1 + ] + ] ] - TYPE_IMAGE [0] - default [0] + + TYPE_BLOCK [ ;-- block of files in native format + fmts/1: CF_HDROP + + ;-- count the total characters for the DROPFILES data + len: 2 ;-- always have 2 trailing null chars, even for an empty block + value: block/rs-head as red-block! data + tail: block/rs-tail as red-block! data + while [value < tail] [ + assert any [TYPE_OF(value) = TYPE_FILE TYPE_OF(value) = TYPE_STRING] + len: len + 1 + string/rs-length? as red-string! value + value: value + 1 + ] + + ;-- conservatively allocate 4 bytes for each char + hMem/1: GlobalAlloc 2 len * 4 + size? DROPFILES! + if hMem/1 <> 0 [ + p: GlobalLock hMem/1 + unless null? p [ + ;-- construct the DROPFILES data + set-memory p #"^@" size? DROPFILES! + df: as DROPFILES! p + df/pFiles: size? DROPFILES! + df/fWide: yes + p: p + df/pFiles + value: block/rs-head as red-block! data + while [value < tail] [ + len: -1 + p1: as byte-ptr! unicode/to-utf16-len as red-string! value :len yes + len: len * 2 + 2 + copy-memory p p1 len + p: p + len + value: value + 1 + ] + p/1: #"^@" p/2: #"^@" + GlobalUnlock hMem/1 + ] + ] + ];; TYPE_BLOCK + + TYPE_IMAGE [ + ;-- put image in the "PNG" format for it's better portability + ;; see https://stackoverflow.com/a/15691001 on rationale + fmts/1: RegisterClipboardFormat "PNG" + assert fmts/1 <> 0 + bin: as red-binary! image/encode as red-image! data none-value IMAGE_PNG + len: binary/rs-length? bin + hMem/1: GlobalAlloc 2 len + if hMem/1 <> 0 [ + p1: GlobalLock hMem/1 + unless null? p1 [ + copy-memory p1 binary/rs-head bin len + GlobalUnlock hMem/1 + ] + ] + + ;-- also put the image in DIB format for compatibility + fmts/2: CF_DIBV5 + bmdata: as BitmapData! OS-image/lock-bitmap as red-image! data no + assert not null? bmdata + len: bmdata/width * bmdata/height * 4 + hMem/2: GlobalAlloc 2 len + size? BITMAPV5HEADER! + if hMem/2 <> 0 [ + p: GlobalLock hMem/2 + unless null? p [ + set-memory p #"^@" size? BITMAPV5HEADER! + hdr: as BITMAPV5HEADER! p + hdr/Size: size? BITMAPV5HEADER! + hdr/Width: bmdata/width + hdr/Height: 0 - bmdata/height ;-- top-down image + hdr/PlanesBitCount: 00200001h ;-- 32 bpp, 1 plane + hdr/Compression: 3 ;-- BI_BITFIELDS + hdr/SizeImage: len + hdr/AlphaMask: FF000000h + hdr/RedMask: 00FF0000h + hdr/GreenMask: 0000FF00h + hdr/BlueMask: 000000FFh + hdr/CSType: 57696E20h ;-- "Win " = LCS_WINDOWS_COLOR_SPACE + hdr/Intent: 4 ;-- 4 = LCS_GM_IMAGES + assert bmdata/pixelFormat = PixelFormat32bppARGB + copy-memory p + hdr/Size bmdata/scan0 len + GlobalUnlock hMem/2 + ] + ] + OS-image/unlock-bitmap as red-image! data as integer! bmdata + ];; TYPE_IMAGE + + default [fire [TO_ERROR(script invalid-arg) data]] ] ;-- OpenClipboard often fails on W7 after an EmptyClipboard call, so be persistent @@ -147,17 +433,31 @@ clipboard: context [ if ok [break] ] unless ok [ ;-- clean up after a (rare) failure - unless hMem = 0 [ - GlobalLock hMem - GlobalFree hMem - GlobalUnlock hMem + unless hMem/1 = 0 [ + GlobalLock hMem/1 + GlobalFree hMem/1 + GlobalUnlock hMem/1 + ] + unless hMem/2 = 0 [ + GlobalLock hMem/2 + GlobalFree hMem/2 + GlobalUnlock hMem/2 ] return false ] - EmptyClipboard - res: SetClipboardData CF_UNICODETEXT hMem + + res: [1 1] res/1: 1 res/2: 1 + if TYPE_OF(data) = TYPE_NONE [p: as byte-ptr! 1] ;-- empty clipboard in case of `none` argument + unless null? p [ ;-- but not in case of a failed allocation/lock + EmptyClipboard + if fmts/1 <> 0 [res/1: SetClipboardData fmts/1 hMem/1] + if fmts/2 <> 0 [res/2: SetClipboardData fmts/2 hMem/2] + ] CloseClipboard - as logic! res + ;-- false if: + ;; - failed to prepare or set text or file list + ;; - failed to prepare image in DIB format, or set it in either format + all [res/1 <> 0 res/2 <> 0 not null? p] ] ] macOS [ diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 9251845ac1..9b6448edee 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -160,6 +160,12 @@ OS-image: context [ height [int-ptr!] return: [integer!] ] + GdipCreateBitmapFromGdiDib: "GdipCreateBitmapFromGdiDib" [ + bmi [byte-ptr!] + data [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ] GdipCreateBitmapFromScan0: "GdipCreateBitmapFromScan0" [ width [integer!] height [integer!] From f068896d0109536b18c5ca817798aab2ad473542 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 19:26:58 +0300 Subject: [PATCH 0547/3432] TESTS: for PR #4057 --- tests/source/units/all-tests.txt | 1 + tests/source/units/clipboard-test.red | 90 +++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/source/units/clipboard-test.red diff --git a/tests/source/units/all-tests.txt b/tests/source/units/all-tests.txt index a7fa0d9106..c281864797 100644 --- a/tests/source/units/all-tests.txt +++ b/tests/source/units/all-tests.txt @@ -56,3 +56,4 @@ power-test.red stress-test.red regression-test-red.red recycle-test.red +clipboard-test.red diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red new file mode 100644 index 0000000000..7f21fcb7c4 --- /dev/null +++ b/tests/source/units/clipboard-test.red @@ -0,0 +1,90 @@ +Red [ + Title: "Red Clipboard test" + Author: "hiiamboris" + File: %clipboard-test.red + Tabs: 4 + Rights: "Copyright (C) 2011-2019 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../quick-test/quick-test.red + +~~~start-file~~~ "clipboard" + +===start-group=== "text IO" + + --test-- "text-io-1" + --assert false <> write-clipboard "" + --assert "" = read-clipboard + + --test-- "text-io-2" + --assert false <> write-clipboard "text" + --assert "text" = read-clipboard + + --test-- "text-io-3" + --assert false <> write-clipboard "1^/2^/3^/" + --assert "1^/2^/3^/" = read-clipboard + + --test-- "text-io-long-1" + til1: append/dup copy "" "data " 1000 + --assert false <> write-clipboard til1 + --assert til1 = read-clipboard + unset 'til1 + + + do [if system/platform = 'Windows [ + + --test-- "emptying" + --assert false <> write-clipboard none + --assert none? read-clipboard + + + --test-- "list-io-1" + --assert false <> write-clipboard [] + --assert [] = read-clipboard + + --test-- "list-io-2" + li2: [%/dir1/file1 %/dir2/file2] + --assert false <> write-clipboard li2 + --assert li2 = read-clipboard + unset 'li2 + + --test-- "list-io-long-1" + lil1: reduce [%/dir1/file1 %/dir2/file2 + to-red-file %"C:\So many autumn, ay, and winter days, spent outside the town, trying to hear what was in the wind, to hear and carry it express!.txt" + ] + --assert false <> write-clipboard lil1 + --assert lil1 = read-clipboard + unset 'lil1 + + + --test-- "image-io-1" + --assert false <> write-clipboard make image! 0x0 + --assert none? read-clipboard + + ;-- FIXME: #4056 + ; --test-- "image-io-2" + ; ii2: make image! 1x1 + ; --assert false <> write-clipboard ii2 + ; --assert ii2 = read-clipboard + ; unset 'ii2 + + --test-- "image-io-3" + ii3: draw make image! [100x100 0.200.200.200] [pen purple line-width 5 circle 50x50 40] + --assert false <> write-clipboard ii3 + --assert ii3 = read-clipboard + unset 'ii3 + + --test-- "image-io-long-1" + iil1: draw make image! [3000x3000 0.200.200.200] [pen purple line-width 50 circle 1500x1500 1300] + --assert false <> write-clipboard iil1 + --assert iil1 = read-clipboard + unset 'iil1 + + ]];; do [if system/platform = 'Windows [ + + write-clipboard none ;-- clean it up + +===end-group=== + +~~~end-file~~~ From ab4da3a006125e66711aafd06db25c90bb33b77b Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 20:01:15 +0300 Subject: [PATCH 0548/3432] FIX: GUI console can paste file lists --- environment/console/GUI/core.red | 1 + 1 file changed, 1 insertion(+) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 5fe361836b..b4c2704663 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -628,6 +628,7 @@ object [ unless resume [ clipboard: read-clipboard if image? clipboard [clipboard: none] + if block? clipboard [clipboard: mold clipboard] ] if all [clipboard not empty? clipboard][ start: clipboard From dff0603740cceda99a54104964cceab4c700756d Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 20:47:10 +0300 Subject: [PATCH 0549/3432] FIX: minor compatibility fix for PR #4057 --- environment/functions.red | 38 +++++++++++++++++---------- tests/source/units/clipboard-test.red | 37 ++++++++++++++------------ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index e627529e06..d9603fc78e 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -1079,23 +1079,33 @@ clipboard-internal: context [ ] ] -read-clipboard: func ["Return the contents of the system clipboard" return: [string! block! image!] /local r] [ - also r: clipboard-internal/read-clipboard* - if block? r [forall r [change r to-red-file r/1]] -] +#either config/OS = 'Windows [ + read-clipboard: func ["Return the contents of the system clipboard" return: [string! block! image! none! logic!] /local r] [ + also r: clipboard-internal/read-clipboard* + if block? r [forall r [change r to-red-file r/1]] + ] -write-clipboard: func ["Write content to the system clipboard" data [string! block! image! none!]] [ - either block? data [ - data: copy data - forall data [change data to-local-file :data/1] - ][ - all [ - image? data - empty? data - data: none + write-clipboard: func ["Write content to the system clipboard" data [string! block! image! none!] return: [none! logic!]] [ + either block? data [ + data: copy data + forall data [change data to-local-file :data/1] + ][ + all [ + image? data + empty? data + data: none + ] ] + clipboard-internal/write-clipboard* data + ] +][ + read-clipboard: func ["Return the contents of the system clipboard" return: [string! none! logic!] /local r] [ + clipboard-internal/read-clipboard* + ] + + write-clipboard: func ["Write content to the system clipboard" data [string!] return: [none! logic!]] [ + clipboard-internal/write-clipboard* data ] - clipboard-internal/write-clipboard* data ] unset 'clipboard-internal diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red index 7f21fcb7c4..24c374dc15 100644 --- a/tests/source/units/clipboard-test.red +++ b/tests/source/units/clipboard-test.red @@ -13,23 +13,26 @@ Red [ ===start-group=== "text IO" - --test-- "text-io-1" - --assert false <> write-clipboard "" - --assert "" = read-clipboard - - --test-- "text-io-2" - --assert false <> write-clipboard "text" - --assert "text" = read-clipboard - - --test-- "text-io-3" - --assert false <> write-clipboard "1^/2^/3^/" - --assert "1^/2^/3^/" = read-clipboard - - --test-- "text-io-long-1" - til1: append/dup copy "" "data " 1000 - --assert false <> write-clipboard til1 - --assert til1 = read-clipboard - unset 'til1 + do [if system/platform <> 'Linux [ + + --test-- "text-io-1" + --assert false <> write-clipboard "" + --assert "" = read-clipboard + + --test-- "text-io-2" + --assert false <> write-clipboard "text" + --assert "text" = read-clipboard + + --test-- "text-io-3" + --assert false <> write-clipboard "1^/2^/3^/" + --assert "1^/2^/3^/" = read-clipboard + + --test-- "text-io-long-1" + til1: append/dup copy "" "data " 1000 + --assert false <> write-clipboard til1 + --assert til1 = read-clipboard + unset 'til1 + ]] do [if system/platform = 'Windows [ From d067fa000fb771e3054034558cd5fd2c87d60680 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 21:32:24 +0300 Subject: [PATCH 0550/3432] FIX: typo in PR #4057 --- tests/source/units/clipboard-test.red | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red index 24c374dc15..3ebfa1424c 100644 --- a/tests/source/units/clipboard-test.red +++ b/tests/source/units/clipboard-test.red @@ -14,7 +14,7 @@ Red [ ===start-group=== "text IO" do [if system/platform <> 'Linux [ - + --test-- "text-io-1" --assert false <> write-clipboard "" --assert "" = read-clipboard @@ -86,7 +86,9 @@ Red [ ]];; do [if system/platform = 'Windows [ - write-clipboard none ;-- clean it up + do [if system/platform <> 'Linux [ + write-clipboard none ;-- clean it up + ]] ===end-group=== From ffdb866d172354d667c89c6e4d5405346dee4e9d Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 30 Sep 2019 22:15:20 +0300 Subject: [PATCH 0551/3432] FIX: another typo in PR #4057 --- tests/source/units/clipboard-test.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red index 3ebfa1424c..6dba7619a3 100644 --- a/tests/source/units/clipboard-test.red +++ b/tests/source/units/clipboard-test.red @@ -87,7 +87,7 @@ Red [ ]];; do [if system/platform = 'Windows [ do [if system/platform <> 'Linux [ - write-clipboard none ;-- clean it up + write-clipboard "" ;-- clean it up ]] ===end-group=== From e947815d86affebf0633577a01739625a141136e Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Tue, 1 Oct 2019 18:46:23 +0300 Subject: [PATCH 0552/3432] FIX: brought back routines to PR #4057 --- environment/functions.red | 41 --------- environment/routines.red | 15 ++++ runtime/clipboard.reds | 118 +++++++++++++++----------- tests/source/units/clipboard-test.red | 11 ++- 4 files changed, 88 insertions(+), 97 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index d9603fc78e..7845ee471f 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -1069,47 +1069,6 @@ last?: func [ 1 = length? series ] -clipboard-internal: context [ - read-clipboard*: routine ["Return the contents of the system clipboard"][ - stack/set-last clipboard/read - ] - - write-clipboard*: routine ["Write content to the system clipboard" data [any-type!]][ - logic/box clipboard/write as red-value! data - ] -] - -#either config/OS = 'Windows [ - read-clipboard: func ["Return the contents of the system clipboard" return: [string! block! image! none! logic!] /local r] [ - also r: clipboard-internal/read-clipboard* - if block? r [forall r [change r to-red-file r/1]] - ] - - write-clipboard: func ["Write content to the system clipboard" data [string! block! image! none!] return: [none! logic!]] [ - either block? data [ - data: copy data - forall data [change data to-local-file :data/1] - ][ - all [ - image? data - empty? data - data: none - ] - ] - clipboard-internal/write-clipboard* data - ] -][ - read-clipboard: func ["Return the contents of the system clipboard" return: [string! none! logic!] /local r] [ - clipboard-internal/read-clipboard* - ] - - write-clipboard: func ["Write content to the system clipboard" data [string!] return: [none! logic!]] [ - clipboard-internal/write-clipboard* data - ] -] - -unset 'clipboard-internal - ;------------------------------------------ ;- Aliases - ;------------------------------------------ diff --git a/environment/routines.red b/environment/routines.red index f07c850f55..51bdf47926 100644 --- a/environment/routines.red +++ b/environment/routines.red @@ -116,6 +116,21 @@ as-rgba: :as-ipv4 ;-- Temporary definition -- +read-clipboard: routine [ + "Return the contents of the system clipboard" + return: [any-type!] "false on failure, none if empty, otherwise: string!, block! of files!, or an image!" +][ + stack/set-last clipboard/read +] + +write-clipboard: routine [ + "Write content to the system clipboard" + data [any-type!] "string!, block! of files!, an image! or none!" + return: [logic!] "indicates success" +][ + logic/box clipboard/write as red-value! data +] + write-stdout: routine ["Write data to STDOUT" data [any-type!]][ ;-- internal use only simple-io/write null as red-value! data null null no no no ] \ No newline at end of file diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index 4ae137ecc1..75dbf78e18 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -211,6 +211,7 @@ clipboard: context [ count: DragQueryFile hMem FFFFFFFFh null 0 assert count >= 0 blk: block/push-only* count + str: string/make-at stack/push* 64 Latin1 i: 0 bufsz: 0 p1: null loop count [ len: DragQueryFile hMem i null 0 @@ -221,9 +222,15 @@ clipboard: context [ p1: p2 ] DragQueryFile hMem i p1 bufsz - string/load-at as-c-string p1 lstrlen p1 ALLOC_TAIL(blk) UTF-16LE + string/load-at as-c-string p1 lstrlen p1 as red-value! str UTF-16LE + stack/mark-native words/_body + #call [to-red-file str] + block/rs-append blk stack/arguments + stack/unwind + string/rs-reset str i: i + 1 ] + stack/pop 1 ;-- get rid of `str` unless null? p1 [free p1 p1: null] val: as red-value! blk GlobalUnlock hMem @@ -292,7 +299,7 @@ clipboard: context [ ;-- false = failure during data retrieval if all [hMem <> 0 null? p] [return as red-value! false-value] val - ] + ];; read write: func [ data [red-value!] @@ -307,7 +314,10 @@ clipboard: context [ p1 [byte-ptr!] value [red-value!] tail [red-value!] + str [red-string!] bin [red-binary!] + blk [red-block!] + img [red-image!] df [DROPFILES!] bmdata [BitmapData!] hdr [BITMAPV5HEADER!] @@ -339,13 +349,16 @@ clipboard: context [ TYPE_BLOCK [ ;-- block of files in native format fmts/1: CF_HDROP - ;-- count the total characters for the DROPFILES data + ;-- count the total characters for the DROPFILES data, also convert files to OS format len: 2 ;-- always have 2 trailing null chars, even for an empty block value: block/rs-head as red-block! data tail: block/rs-tail as red-block! data + blk: block/push-only* (as-integer tail - value) / size? cell! while [value < tail] [ assert any [TYPE_OF(value) = TYPE_FILE TYPE_OF(value) = TYPE_STRING] - len: len + 1 + string/rs-length? as red-string! value + str: string/make-at ALLOC_TAIL(blk) 64 Latin1 + file/to-local-path as red-file! value str no + len: len + 1 + string/rs-length? str value: value + 1 ] @@ -360,66 +373,71 @@ clipboard: context [ df/pFiles: size? DROPFILES! df/fWide: yes p: p + df/pFiles - value: block/rs-head as red-block! data - while [value < tail] [ + str: as red-string! block/rs-head blk + tail: block/rs-tail blk + while [str < as red-string! tail] [ len: -1 - p1: as byte-ptr! unicode/to-utf16-len as red-string! value :len yes + p1: as byte-ptr! unicode/to-utf16-len str :len yes len: len * 2 + 2 copy-memory p p1 len p: p + len - value: value + 1 + str: str + 1 ] p/1: #"^@" p/2: #"^@" GlobalUnlock hMem/1 ] ] + stack/pop 1 ;-- get rid of `blk` ];; TYPE_BLOCK TYPE_IMAGE [ - ;-- put image in the "PNG" format for it's better portability - ;; see https://stackoverflow.com/a/15691001 on rationale - fmts/1: RegisterClipboardFormat "PNG" - assert fmts/1 <> 0 - bin: as red-binary! image/encode as red-image! data none-value IMAGE_PNG - len: binary/rs-length? bin - hMem/1: GlobalAlloc 2 len - if hMem/1 <> 0 [ - p1: GlobalLock hMem/1 - unless null? p1 [ - copy-memory p1 binary/rs-head bin len - GlobalUnlock hMem/1 + img: as red-image! data + if IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) > 0 [ + ;-- put image in the "PNG" format for it's better portability + ;; see https://stackoverflow.com/a/15691001 on rationale + fmts/1: RegisterClipboardFormat "PNG" + assert fmts/1 <> 0 + bin: as red-binary! image/encode img none-value IMAGE_PNG + len: binary/rs-length? bin + hMem/1: GlobalAlloc 2 len + if hMem/1 <> 0 [ + p1: GlobalLock hMem/1 + unless null? p1 [ + copy-memory p1 binary/rs-head bin len + GlobalUnlock hMem/1 + ] ] - ] - ;-- also put the image in DIB format for compatibility - fmts/2: CF_DIBV5 - bmdata: as BitmapData! OS-image/lock-bitmap as red-image! data no - assert not null? bmdata - len: bmdata/width * bmdata/height * 4 - hMem/2: GlobalAlloc 2 len + size? BITMAPV5HEADER! - if hMem/2 <> 0 [ - p: GlobalLock hMem/2 - unless null? p [ - set-memory p #"^@" size? BITMAPV5HEADER! - hdr: as BITMAPV5HEADER! p - hdr/Size: size? BITMAPV5HEADER! - hdr/Width: bmdata/width - hdr/Height: 0 - bmdata/height ;-- top-down image - hdr/PlanesBitCount: 00200001h ;-- 32 bpp, 1 plane - hdr/Compression: 3 ;-- BI_BITFIELDS - hdr/SizeImage: len - hdr/AlphaMask: FF000000h - hdr/RedMask: 00FF0000h - hdr/GreenMask: 0000FF00h - hdr/BlueMask: 000000FFh - hdr/CSType: 57696E20h ;-- "Win " = LCS_WINDOWS_COLOR_SPACE - hdr/Intent: 4 ;-- 4 = LCS_GM_IMAGES - assert bmdata/pixelFormat = PixelFormat32bppARGB - copy-memory p + hdr/Size bmdata/scan0 len - GlobalUnlock hMem/2 + ;-- also put the image in DIB format for compatibility + fmts/2: CF_DIBV5 + bmdata: as BitmapData! OS-image/lock-bitmap img no + assert not null? bmdata + len: bmdata/width * bmdata/height * 4 + hMem/2: GlobalAlloc 2 len + size? BITMAPV5HEADER! + if hMem/2 <> 0 [ + p: GlobalLock hMem/2 + unless null? p [ + set-memory p #"^@" size? BITMAPV5HEADER! + hdr: as BITMAPV5HEADER! p + hdr/Size: size? BITMAPV5HEADER! + hdr/Width: bmdata/width + hdr/Height: 0 - bmdata/height ;-- top-down image + hdr/PlanesBitCount: 00200001h ;-- 32 bpp, 1 plane + hdr/Compression: 3 ;-- BI_BITFIELDS + hdr/SizeImage: len + hdr/AlphaMask: FF000000h + hdr/RedMask: 00FF0000h + hdr/GreenMask: 0000FF00h + hdr/BlueMask: 000000FFh + hdr/CSType: 57696E20h ;-- "Win " = LCS_WINDOWS_COLOR_SPACE + hdr/Intent: 4 ;-- 4 = LCS_GM_IMAGES + assert bmdata/pixelFormat = PixelFormat32bppARGB + copy-memory p + hdr/Size bmdata/scan0 len + GlobalUnlock hMem/2 + ] ] - ] - OS-image/unlock-bitmap as red-image! data as integer! bmdata + OS-image/unlock-bitmap img as integer! bmdata + ];; if IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) > 0 ];; TYPE_IMAGE default [fire [TO_ERROR(script invalid-arg) data]] @@ -458,7 +476,7 @@ clipboard: context [ ;; - failed to prepare or set text or file list ;; - failed to prepare image in DIB format, or set it in either format all [res/1 <> 0 res/2 <> 0 not null? p] - ] + ];; write ] macOS [ #import [ diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red index 6dba7619a3..15757d3abd 100644 --- a/tests/source/units/clipboard-test.red +++ b/tests/source/units/clipboard-test.red @@ -65,12 +65,11 @@ Red [ --assert false <> write-clipboard make image! 0x0 --assert none? read-clipboard - ;-- FIXME: #4056 - ; --test-- "image-io-2" - ; ii2: make image! 1x1 - ; --assert false <> write-clipboard ii2 - ; --assert ii2 = read-clipboard - ; unset 'ii2 + --test-- "image-io-2" + ii2: make image! 1x1 + --assert false <> write-clipboard ii2 + --assert ii2 = read-clipboard + unset 'ii2 --test-- "image-io-3" ii3: draw make image! [100x100 0.200.200.200] [pen purple line-width 5 circle 50x50 40] From fbc6d3ff0192b32dbf4f9c304b76d2e8d09dfacc Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Tue, 1 Oct 2019 19:41:56 +0300 Subject: [PATCH 0553/3432] FIX: fought back the return-logic side effects --- environment/routines.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/routines.red b/environment/routines.red index 51bdf47926..1a19a4bb7e 100644 --- a/environment/routines.red +++ b/environment/routines.red @@ -128,7 +128,7 @@ write-clipboard: routine [ data [any-type!] "string!, block! of files!, an image! or none!" return: [logic!] "indicates success" ][ - logic/box clipboard/write as red-value! data + clipboard/write as red-value! data ] write-stdout: routine ["Write data to STDOUT" data [any-type!]][ ;-- internal use only From b54712d66528738a396fefbaf51430337e4dfbc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boleslav=20B=C5=99ezovsk=C3=BD?= Date: Thu, 3 Oct 2019 10:56:56 +0200 Subject: [PATCH 0554/3432] FEAT: JSON coddec is now encapped and merged into one file --- build/includes.r | 5 - environment/codecs/json.red | 399 +++++++++++++++++++++++++- environment/codecs/json/common.red | 107 ------- environment/codecs/json/load-json.red | 241 ---------------- environment/codecs/json/to-json.red | 175 ----------- 5 files changed, 397 insertions(+), 530 deletions(-) delete mode 100644 environment/codecs/json/common.red delete mode 100644 environment/codecs/json/load-json.red delete mode 100644 environment/codecs/json/to-json.red diff --git a/build/includes.r b/build/includes.r index 9335c8c7c5..05aa00426f 100644 --- a/build/includes.r +++ b/build/includes.r @@ -40,11 +40,6 @@ write %build/bin/sources.r set-cache [ %png.red %csv.red %json.red - %json/ [ - %common.red - %load-json.red - %to-json.red - ] ] %console/ [ %auto-complete.red diff --git a/environment/codecs/json.red b/environment/codecs/json.red index 3254425544..809750d459 100644 --- a/environment/codecs/json.red +++ b/environment/codecs/json.red @@ -10,8 +10,402 @@ Red [ } ] -#include %environment/codecs/json/load-json.red -#include %environment/codecs/json/to-json.red +do [ + +; -- load-json + +context [ + ;----------------------------------------------------------- + ;-- Generic support funcs + + BOM: [ + UTF-8 #{EFBBBF} + UTF-16-BE #{FEFF} + UTF-16-LE #{FFFE} + UTF-32-BE #{0000FEFF} + UTF-32-LE #{FFFE0000} + ] + + BOM-UTF-16?: func [data [string! binary!]][ + any [find/match data BOM/UTF-16-BE find/match data BOM/UTF-16-LE] + ] + + BOM-UTF-32?: func [data [string! binary!]][ + any [find/match data BOM/UTF-32-BE find/match data BOM/UTF-32-LE] + ] + + + ; MOLD adds quotes string!, but not all any-string! values. + enquote: func [str [string!] "(modified)"][append insert str {"} {"}] + + high-surrogate?: func [codepoint [integer!]][ + all [codepoint >= D800h codepoint <= DBFFh] + ] + + low-surrogate?: func [codepoint [integer!]][ + all [codepoint >= DC00h codepoint <= DFFFh] + ] + + translit: func [ + "Transliterate sub-strings in a string" + string [string!] "Input (modified)" + rule [block! bitset!] "What to change" + xlat [block! function!] "Translation table or function. MUST map a string! to a string!." + /local val + ][ + parse string [ + some [ + change copy val rule (val either block? :xlat [xlat/:val][xlat val]) + | skip + ] + ] + string + ] + + ;----------------------------------------------------------- + ;-- JSON backslash escaping + + ;TBD: I think this can be improved. --Gregg + + json-to-red-escape-table: [ + ; JSON Red + {\"} "^"" + {\\} "\" + {\/} "/" + {\b} "^H" ; #"^(back)" + {\f} "^L" ; #"^(page)" + {\n} "^/" + {\r} "^M" + {\t} "^-" + ] + red-to-json-escape-table: reverse copy json-to-red-escape-table + + json-esc-ch: charset {"t\/nrbf} ; Backslash escaped JSON chars + json-escaped: [#"\" json-esc-ch] ; Backslash escape rule + red-esc-ch: charset {^"^-\/^/^M^H^L} ; Red chars requiring JSON backslash escapes + + decode-backslash-escapes: func [string [string!] "(modified)"][ + translit string json-escaped json-to-red-escape-table + ] + + encode-backslash-escapes: func [string [string!] "(modified)"][ + translit string red-esc-ch red-to-json-escape-table + ] + + ctrl-char: charset [#"^@" - #"^_"] ; Control chars 0-31 + ;----------------------------------------------------------- + ;-- JSON decoder + ;----------------------------------------------------------- + + ;# Basic rules + ws: charset " ^-^/^M" ; Whitespace + ws*: [any ws] + ws+: [some ws] + sep: [ws* #"," ws*] ; JSON value separator + digit: charset "0123456789" + non-zero-digit: charset "123456789" + hex-char: charset "0123456789ABCDEFabcdef" + chars: charset [not {\"} #"^@" - #"^_"] ; Unescaped chars (NOT creates a virtual bitset) + + ; chars allowed in Red word! values - note that we don't allow < and > at all even though they are somewhat valid in word! + not-word-char: charset {/\^^,[](){}"#%$@:;^/^(00A0) ^-^M<>} + word-1st: complement append union not-word-char digit #"'" + word-char: complement not-word-char + + ;----------------------------------------------------------- + ;-- JSON value rules + ;----------------------------------------------------------- + + ;----------------------------------------------------------- + ;-- Number + sign: [#"-"] + ; Integers can't have leading zeros, but zero by itself is valid. + int: [[non-zero-digit any digit] | digit] + frac: [#"." some digit] + exp: [[#"e" | #"E"] opt [#"+" | #"-"] some digit] + number: [opt sign int opt frac opt exp] + numeric-literal: :number + + ;----------------------------------------------------------- + ;-- String + string-literal: [ + #"^"" copy _str [ + any [some chars | #"\" [#"u" 4 hex-char | json-esc-ch]] + ] #"^"" ( + if not empty? _str: any [_str copy ""] [ + ;!! If we reverse the decode-backslash-escapes and replace-unicode-escapes + ;!! calls, the string gets munged (extra U+ chars). Need to investigate. + decode-backslash-escapes _str ; _str is modified + replace-unicode-escapes _str ; _str is modified + ;replace-unicode-escapes decode-backslash-escapes _str + ] + ) + ] + + decode-unicode-char: func [ + "Convert \uxxxx format (NOT simple JSON backslash escapes) to a Unicode char" + ch [string!] "4 hex digits" + ][ + buf: {#"^^(0000)"} ; Don't COPY buffer, reuse it + if not parse ch [4 hex-char] [return none] ; Validate input data + attempt [load head change at buf 5 ch] ; Replace 0000 section in buf + ] + + replace-unicode-escapes: func [ + s [string!] "(modified)" + /local c + ][ + parse s [ + any [ + some chars ; Pass over unescaped chars + | json-escaped ; Pass over simple backslash escapes + | change ["\u" copy c 4 hex-char] (decode-unicode-char c) () + ;| "\u" followed by anything else is an invalid \uXXXX escape + ] + ] + s + ] + ;str: {\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%&*()_+-=[]{}|;:',./<>?} + ;mod-str: decode-backslash-escapes json-ctx/replace-unicode-escapes copy str + ;mod-str: json-ctx/replace-unicode-escapes decode-backslash-escapes copy str + + ;----------------------------------------------------------- + ;-- Object + json-object: [ + ; Emit a new block to our output target, and push it on our + ; working stack, to handle nested structures. Emit returns + ; the insertion point for another value to go out into '_res, + ; but we want the target to be the block we just added, so + ; we reset '_res to that after 'emit is done. + #"{" (push emit _tmp: copy [] _res: _tmp) + ws* opt property-list + ; This is a little confusing. We're at the tail of our current + ; output target, which is on our stack. We pop that, then need + ; to back up one, which puts us AT the block of values we + ; collected for this object in our output target. i.e., the + ; values are in a sub-block at the first position now. We use + ; that (FIRST) to make a map! and replace the block of values + ; with the map! we just made. Note that a map is treated as a + ; single value, like an object. Using a block as the new value + ; requires using `change/only`. + #"}" ( + _res: back pop + _res: change _res make map! first _res + ) + ] + + property-list: [property any [sep property]] + property: [json-name (emit either parse _str [word-1st any word-char] [to word! _str] [_str]) json-value] + json-name: [ws* string-literal ws* #":"] + + ;----------------------------------------------------------- + ;-- List + array-list: [json-value any [sep json-value]] + json-array: [ + ; Emit a new block to our output target, and push it on our + ; working stack, to handle nested structures. Emit returns + ; the insertion point for another value to go out into '_res, + ; but we want the target to be the block we just added, so + ; we reset '_res to that after 'emit is done. + #"[" (push emit _tmp: copy [] _res: _tmp) + ws* opt array-list + #"]" (_res: pop) + ] + + ;----------------------------------------------------------- + ;-- Any JSON Value (top level JSON parse rule) + json-value: [ + ws* + [ + "true" (emit true) ; Literals must be lowercase + | "false" (emit false) + | "null" (emit none) + | json-object + | json-array + | string-literal (emit _str) + | copy _str numeric-literal (emit load _str) ; Number + mark: ; Set mark for failure location + ] + ws* + ] + + ;----------------------------------------------------------- + ;-- Decoder data structures + + ; The stack is used to handle nested structures (objects and lists) + stack: copy [] + push: func [val][append/only stack val] + pop: does [take/last stack] + + _out: none ; Our overall output target/result + _res: none ; The current output position where new values are inserted + _tmp: none ; Temporary + _str: none ; Where string value parse results go + mark: none ; Current parse position + + ; Add a new value to our output target, and set the position for + ; the next emit to the tail of the insertion. + ;!! I really don't like how this updates _res as a side effect. --Gregg + emit: func [value][_res: insert/only _res value] + + ;----------------------------------------------------------- + ;-- Main decoder func + + set 'load-json func [ + "Convert a JSON string to Red data" + input [string!] "The JSON string" + ] [ + _out: _res: copy [] ; These point to the same position to start with + mark: input + either parse/case input json-value [pick _out 1] [ + make error! form reduce [ + "Invalid json string. Near:" + either tail? mark [""] [mold copy/part mark 40] + ] + ] + ] +] +; -- to-json + +context [ + indent: none + indent-level: 0 + normal-chars: none + escapes: #( + #"^"" {\"} + #"\" "\\" + #"^H" "\b" + #"^L" "\f" + #"^/" "\n" + #"^M" "\r" + #"^-" "\t" + ) + + init-state: func [ind ascii?] [ + indent: ind + indent-level: 0 + ; 34 is double quote " + ; 92 is backslash \ + normal-chars: either ascii? [ + charset [32 33 35 - 91 93 - 127] + ] [ + complement charset [0 - 31 34 92] + ] + ] + + emit-indent: func [output level] [ + indent-level: indent-level + level + append/dup output indent indent-level + ] + + emit-key-value: function [output sep map key] [ + value: select/case map :key + if any-word? :key [key: form key] + unless string? :key [key: mold :key] + red-to-json-value output key + append output sep + red-to-json-value output :value + ] + + red-to-json-value: function [output value] [ + special-char: none + switch/default type?/word :value [ + none! [append output "null"] + logic! [append output pick ["true" "false"] value] + integer! float! [append output value] + percent! [append output to float! value] + string! [ + append output #"^"" + parse value [ + any [ + mark1: some normal-chars mark2: (append/part output mark1 mark2) + | + set special-char skip ( + either escape: select escapes special-char [ + append output escape + ] [ + insert insert tail output "\u" to-hex/size to integer! special-char 4 + ] + ) + ] + ] + append output #"^"" + ] + block! [ + either empty? value [ + append output "[]" + ] [ + either indent [ + append output "[^/" + emit-indent output +1 + red-to-json-value output first value + foreach v next value [ + append output ",^/" + append/dup output indent indent-level + red-to-json-value output :v + ] + append output #"^/" + emit-indent output -1 + ] [ + append output #"[" + red-to-json-value output first value + foreach v next value [ + append output #"," + red-to-json-value output :v + ] + ] + append output #"]" + ] + ] + map! object! [ + keys: words-of value + either empty? keys [ + append output "{}" + ] [ + either indent [ + append output "{^/" ; } + emit-indent output +1 + emit-key-value output ": " value first keys + foreach k next keys [ + append output ",^/" + append/dup output indent indent-level + emit-key-value output ": " value :k + ] + append output #"^/" + emit-indent output -1 + ] [ + append output #"{" ; } + emit-key-value output #":" value first keys + foreach k next keys [ + append output #"," + emit-key-value output #":" value :k + ] + ] + append output #"}" + ] + ] + ] [ + red-to-json-value output either any-block? :value [ + to block! :value + ] [ + either any-string? :value [form value] [mold :value] + ] + ] + output + ] + + set 'to-json function [ + "Convert Red data to a JSON string" + data + /pretty indent [string!] "Pretty format the output, using given indentation" + /ascii "Force ASCII output (instead of UTF-8)" + ] [ + result: make string! 4000 + init-state indent ascii + red-to-json-value result data + ] +] + put system/codecs 'json context [ Title: "JSON codec" @@ -27,3 +421,4 @@ put system/codecs 'json context [ load-json text ] ] +] diff --git a/environment/codecs/json/common.red b/environment/codecs/json/common.red deleted file mode 100644 index cfc3d298a6..0000000000 --- a/environment/codecs/json/common.red +++ /dev/null @@ -1,107 +0,0 @@ -Red [ - File: %common.red - Title: "JSON codec common code" - Date: 9-Aug-2018 - Version: 0.0.2 - Author: [ - "Gregg Irwin" { - Ported from %json.r by Romano Paolo Tenca, Douglas Crockford, - and Gregg Irwin. - Further research: json libs by Chris Ross-Gill, Kaj de Vos, and - @WiseGenius. - } - "Gabriele Santilli" { - Refactoring and minor improvements. - } - ] - History: [ - 0.0.1 10-Sep-2016 "First release. Based on %json.r" Gregg - 0.0.2 9-Aug-2018 "Refactoring and minor improvements" Gabriele - ] - Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -json-common: context [ - ;----------------------------------------------------------- - ;-- Generic support funcs - - BOM: [ - UTF-8 #{EFBBBF} - UTF-16-BE #{FEFF} - UTF-16-LE #{FFFE} - UTF-32-BE #{0000FEFF} - UTF-32-LE #{FFFE0000} - ] - - BOM-UTF-16?: func [data [string! binary!]][ - any [find/match data BOM/UTF-16-BE find/match data BOM/UTF-16-LE] - ] - - BOM-UTF-32?: func [data [string! binary!]][ - any [find/match data BOM/UTF-32-BE find/match data BOM/UTF-32-LE] - ] - - - ; MOLD adds quotes string!, but not all any-string! values. - enquote: func [str [string!] "(modified)"][append insert str {"} {"}] - - high-surrogate?: func [codepoint [integer!]][ - all [codepoint >= D800h codepoint <= DBFFh] - ] - - low-surrogate?: func [codepoint [integer!]][ - all [codepoint >= DC00h codepoint <= DFFFh] - ] - - translit: func [ - "Transliterate sub-strings in a string" - string [string!] "Input (modified)" - rule [block! bitset!] "What to change" - xlat [block! function!] "Translation table or function. MUST map a string! to a string!." - /local val - ][ - parse string [ - some [ - change copy val rule (val either block? :xlat [xlat/:val][xlat val]) - | skip - ] - ] - string - ] - - ;----------------------------------------------------------- - ;-- JSON backslash escaping - - ;TBD: I think this can be improved. --Gregg - - json-to-red-escape-table: [ - ; JSON Red - {\"} "^"" - {\\} "\" - {\/} "/" - {\b} "^H" ; #"^(back)" - {\f} "^L" ; #"^(page)" - {\n} "^/" - {\r} "^M" - {\t} "^-" - ] - red-to-json-escape-table: reverse copy json-to-red-escape-table - - json-esc-ch: charset {"t\/nrbf} ; Backslash escaped JSON chars - json-escaped: [#"\" json-esc-ch] ; Backslash escape rule - red-esc-ch: charset {^"^-\/^/^M^H^L} ; Red chars requiring JSON backslash escapes - - decode-backslash-escapes: func [string [string!] "(modified)"][ - translit string json-escaped json-to-red-escape-table - ] - - encode-backslash-escapes: func [string [string!] "(modified)"][ - translit string red-esc-ch red-to-json-escape-table - ] - - ctrl-char: charset [#"^@" - #"^_"] ; Control chars 0-31 -] diff --git a/environment/codecs/json/load-json.red b/environment/codecs/json/load-json.red deleted file mode 100644 index 66a572e6c4..0000000000 --- a/environment/codecs/json/load-json.red +++ /dev/null @@ -1,241 +0,0 @@ -Red [ - File: %load-json.red - Title: "JSON parser" - Purpose: "Convert JSON to Red." - Date: 9-Aug-2018 - Version: 0.0.2 - Author: [ - "Gregg Irwin" { - Ported from %json.r by Romano Paolo Tenca, Douglas Crockford, - and Gregg Irwin. - Further research: json libs by Chris Ross-Gill, Kaj de Vos, and - @WiseGenius. - } - "Gabriele Santilli" { - Refactoring and minor improvements. - } - ] - History: [ - 0.0.1 10-Sep-2016 "First release. Based on %json.r" Gregg - 0.0.2 9-Aug-2018 "Refactoring and minor improvements" Gabriele - ] - References: [ - http://www.json.org/ - https://www.ietf.org/rfc/rfc4627.txt - http://www.rfc-editor.org/rfc/rfc7159.txt - http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf - https://github.com/rebolek/red-tools/blob/master/json.red - ] - Notes: { - - Ported from %json.r, by Romano Paolo Tenca, Douglas Crockford, and Gregg Irwin. - - Further research: JSON libs by Chris Ross-Gill, Kaj de Vos, and @WiseGenius. - - ? Do we want to have a single context or separate encode/decode contexts? - - Split into two files (Gab) - ? Do we want to use a stack with parse, or recursive load-json/decode calls? - - - Unicode support is in the works. - - Pretty formatting from %json.r removed. Determine what formatting options we want. - - - Would like to add more detailed decode error info. - - JSON document is empty. - - Invalid value. - - Missing name for object member. - - Missing colon after name of object member. - - Missing comma or right curly brace after object member. - - Missing comma or ] after array element. - - Invalid \uXXXX escape. - - Invalid surrogate pair. - - Invalid backslash escape. - - Missing closing quotation mark in string. - - Numeric overflow. - - Missing fraction in number. - - Missing exponent in number. - } - Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -#include %environment/codecs/json/common.red - -context [ - decode-backslash-escapes: :json-common/decode-backslash-escapes - json-esc-ch: :json-common/json-esc-ch - json-escaped: :json-common/json-escaped - ctrl-char: :json-common/ctrl-char - - ;----------------------------------------------------------- - ;-- JSON decoder - ;----------------------------------------------------------- - - ;# Basic rules - ws: charset " ^-^/^M" ; Whitespace - ws*: [any ws] - ws+: [some ws] - sep: [ws* #"," ws*] ; JSON value separator - digit: charset "0123456789" - non-zero-digit: charset "123456789" - hex-char: charset "0123456789ABCDEFabcdef" - chars: charset [not {\"} #"^@" - #"^_"] ; Unescaped chars (NOT creates a virtual bitset) - - ; chars allowed in Red word! values - note that we don't allow < and > at all even though they are somewhat valid in word! - not-word-char: charset {/\^^,[](){}"#%$@:;^/^(00A0) ^-^M<>} - word-1st: complement append union not-word-char digit #"'" - word-char: complement not-word-char - - ;----------------------------------------------------------- - ;-- JSON value rules - ;----------------------------------------------------------- - - ;----------------------------------------------------------- - ;-- Number - sign: [#"-"] - ; Integers can't have leading zeros, but zero by itself is valid. - int: [[non-zero-digit any digit] | digit] - frac: [#"." some digit] - exp: [[#"e" | #"E"] opt [#"+" | #"-"] some digit] - number: [opt sign int opt frac opt exp] - numeric-literal: :number - - ;----------------------------------------------------------- - ;-- String - string-literal: [ - #"^"" copy _str [ - any [some chars | #"\" [#"u" 4 hex-char | json-esc-ch]] - ] #"^"" ( - if not empty? _str: any [_str copy ""] [ - ;!! If we reverse the decode-backslash-escapes and replace-unicode-escapes - ;!! calls, the string gets munged (extra U+ chars). Need to investigate. - decode-backslash-escapes _str ; _str is modified - replace-unicode-escapes _str ; _str is modified - ;replace-unicode-escapes decode-backslash-escapes _str - ] - ) - ] - - decode-unicode-char: func [ - "Convert \uxxxx format (NOT simple JSON backslash escapes) to a Unicode char" - ch [string!] "4 hex digits" - ][ - buf: {#"^^(0000)"} ; Don't COPY buffer, reuse it - if not parse ch [4 hex-char] [return none] ; Validate input data - attempt [load head change at buf 5 ch] ; Replace 0000 section in buf - ] - - replace-unicode-escapes: func [ - s [string!] "(modified)" - /local c - ][ - parse s [ - any [ - some chars ; Pass over unescaped chars - | json-escaped ; Pass over simple backslash escapes - | change ["\u" copy c 4 hex-char] (decode-unicode-char c) () - ;| "\u" followed by anything else is an invalid \uXXXX escape - ] - ] - s - ] - ;str: {\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%&*()_+-=[]{}|;:',./<>?} - ;mod-str: decode-backslash-escapes json-ctx/replace-unicode-escapes copy str - ;mod-str: json-ctx/replace-unicode-escapes decode-backslash-escapes copy str - - ;----------------------------------------------------------- - ;-- Object - json-object: [ - ; Emit a new block to our output target, and push it on our - ; working stack, to handle nested structures. Emit returns - ; the insertion point for another value to go out into '_res, - ; but we want the target to be the block we just added, so - ; we reset '_res to that after 'emit is done. - #"{" (push emit _tmp: copy [] _res: _tmp) - ws* opt property-list - ; This is a little confusing. We're at the tail of our current - ; output target, which is on our stack. We pop that, then need - ; to back up one, which puts us AT the block of values we - ; collected for this object in our output target. i.e., the - ; values are in a sub-block at the first position now. We use - ; that (FIRST) to make a map! and replace the block of values - ; with the map! we just made. Note that a map is treated as a - ; single value, like an object. Using a block as the new value - ; requires using `change/only`. - #"}" ( - _res: back pop - _res: change _res make map! first _res - ) - ] - - property-list: [property any [sep property]] - property: [json-name (emit either parse _str [word-1st any word-char] [to word! _str] [_str]) json-value] - json-name: [ws* string-literal ws* #":"] - - ;----------------------------------------------------------- - ;-- List - array-list: [json-value any [sep json-value]] - json-array: [ - ; Emit a new block to our output target, and push it on our - ; working stack, to handle nested structures. Emit returns - ; the insertion point for another value to go out into '_res, - ; but we want the target to be the block we just added, so - ; we reset '_res to that after 'emit is done. - #"[" (push emit _tmp: copy [] _res: _tmp) - ws* opt array-list - #"]" (_res: pop) - ] - - ;----------------------------------------------------------- - ;-- Any JSON Value (top level JSON parse rule) - json-value: [ - ws* - [ - "true" (emit true) ; Literals must be lowercase - | "false" (emit false) - | "null" (emit none) - | json-object - | json-array - | string-literal (emit _str) - | copy _str numeric-literal (emit load _str) ; Number - mark: ; Set mark for failure location - ] - ws* - ] - - ;----------------------------------------------------------- - ;-- Decoder data structures - - ; The stack is used to handle nested structures (objects and lists) - stack: copy [] - push: func [val][append/only stack val] - pop: does [take/last stack] - - _out: none ; Our overall output target/result - _res: none ; The current output position where new values are inserted - _tmp: none ; Temporary - _str: none ; Where string value parse results go - mark: none ; Current parse position - - ; Add a new value to our output target, and set the position for - ; the next emit to the tail of the insertion. - ;!! I really don't like how this updates _res as a side effect. --Gregg - emit: func [value][_res: insert/only _res value] - - ;----------------------------------------------------------- - ;-- Main decoder func - - set 'load-json func [ - "Convert a JSON string to Red data" - input [string!] "The JSON string" - ] [ - _out: _res: copy [] ; These point to the same position to start with - mark: input - either parse/case input json-value [pick _out 1] [ - make error! form reduce [ - "Invalid json string. Near:" - either tail? mark [""] [mold copy/part mark 40] - ] - ] - ] -] diff --git a/environment/codecs/json/to-json.red b/environment/codecs/json/to-json.red deleted file mode 100644 index 5375d41570..0000000000 --- a/environment/codecs/json/to-json.red +++ /dev/null @@ -1,175 +0,0 @@ -Red [ - File: %to-json.red - Title: "JSON formatter" - Purpose: "Convert Red to JSON." - Date: 9-Oct-2018 - Version: 0.0.4 - Author: [ - "Gregg Irwin" { - Ported from %json.r by Romano Paolo Tenca, Douglas Crockford, - and Gregg Irwin. - Further research: json libs by Chris Ross-Gill, Kaj de Vos, and - @WiseGenius. - } - "Gabriele Santilli" { - See History. - } - ] - History: [ - 0.0.1 10-Sep-2016 "First release. Based on %json.r" Gregg - 0.0.2 9-Aug-2018 "Refactoring and minor improvements" Gabriele - 0.0.3 31-Aug-2018 "Converted to non-recursive version" Gabriele - 0.0.4 9-Oct-2018 "Back to an easier to read recursive version" Gabriele - ] - References: [ - http://www.json.org/ - https://www.ietf.org/rfc/rfc4627.txt - http://www.rfc-editor.org/rfc/rfc7159.txt - http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf - https://github.com/rebolek/red-tools/blob/master/json.red - ] - Rights: "Copyright (C) 2019 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -context [ - indent: none - indent-level: 0 - normal-chars: none - escapes: #( - #"^"" {\"} - #"\" "\\" - #"^H" "\b" - #"^L" "\f" - #"^/" "\n" - #"^M" "\r" - #"^-" "\t" - ) - - init-state: func [ind ascii?] [ - indent: ind - indent-level: 0 - ; 34 is double quote " - ; 92 is backslash \ - normal-chars: either ascii? [ - charset [32 33 35 - 91 93 - 127] - ] [ - complement charset [0 - 31 34 92] - ] - ] - - emit-indent: func [output level] [ - indent-level: indent-level + level - append/dup output indent indent-level - ] - - emit-key-value: function [output sep map key] [ - value: select/case map :key - if any-word? :key [key: form key] - unless string? :key [key: mold :key] - red-to-json-value output key - append output sep - red-to-json-value output :value - ] - - red-to-json-value: function [output value] [ - special-char: none - switch/default type?/word :value [ - none! [append output "null"] - logic! [append output pick ["true" "false"] value] - integer! float! [append output value] - percent! [append output to float! value] - string! [ - append output #"^"" - parse value [ - any [ - mark1: some normal-chars mark2: (append/part output mark1 mark2) - | - set special-char skip ( - either escape: select escapes special-char [ - append output escape - ] [ - insert insert tail output "\u" to-hex/size to integer! special-char 4 - ] - ) - ] - ] - append output #"^"" - ] - block! [ - either empty? value [ - append output "[]" - ] [ - either indent [ - append output "[^/" - emit-indent output +1 - red-to-json-value output first value - foreach v next value [ - append output ",^/" - append/dup output indent indent-level - red-to-json-value output :v - ] - append output #"^/" - emit-indent output -1 - ] [ - append output #"[" - red-to-json-value output first value - foreach v next value [ - append output #"," - red-to-json-value output :v - ] - ] - append output #"]" - ] - ] - map! object! [ - keys: words-of value - either empty? keys [ - append output "{}" - ] [ - either indent [ - append output "{^/" ; } - emit-indent output +1 - emit-key-value output ": " value first keys - foreach k next keys [ - append output ",^/" - append/dup output indent indent-level - emit-key-value output ": " value :k - ] - append output #"^/" - emit-indent output -1 - ] [ - append output #"{" ; } - emit-key-value output #":" value first keys - foreach k next keys [ - append output #"," - emit-key-value output #":" value :k - ] - ] - append output #"}" - ] - ] - ] [ - red-to-json-value output either any-block? :value [ - to block! :value - ] [ - either any-string? :value [form value] [mold :value] - ] - ] - output - ] - - set 'to-json function [ - "Convert Red data to a JSON string" - data - /pretty indent [string!] "Pretty format the output, using given indentation" - /ascii "Force ASCII output (instead of UTF-8)" - ] [ - result: make string! 4000 - init-state indent ascii - red-to-json-value result data - ] -] From be842f4b99a684d363ff4c9a41f26553cc02a5d8 Mon Sep 17 00:00:00 2001 From: Alvydas Vitkauskas Date: Sat, 5 Oct 2019 20:05:21 +0300 Subject: [PATCH 0555/3432] Add --catch CLI usage documentation --- README.md | 2 ++ usage.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index ea038eaa35..dce5acb4b8 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win --config [...] : Provides compilation settings as a block of `name: value` pairs. + --catch : Stay in the REPL after the script finishes. + --cli : Run the command-line REPL instead of the graphical console. diff --git a/usage.txt b/usage.txt index 86361de561..1c8160adc0 100644 --- a/usage.txt +++ b/usage.txt @@ -44,6 +44,8 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win -V, --version : Output Red's executable version in x.y.z format. + --catch : Stay in the REPL after the script finishes. + --cli : Run the command-line REPL instead of the graphical console. From c427cd0e17fadf5dfd039823e5ea08feef7dab34 Mon Sep 17 00:00:00 2001 From: Alvydas Vitkauskas Date: Sat, 5 Oct 2019 20:29:29 +0300 Subject: [PATCH 0556/3432] Document --no-compress and --show-func-map --- README.md | 5 +++++ usage.txt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index dce5acb4b8..b65f4b95d3 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win --config [...] : Provides compilation settings as a block of `name: value` pairs. + --no-compress : Omit Redbin format compression. + --catch : Stay in the REPL after the script finishes. --cli : Run the command-line REPL instead of the @@ -113,6 +115,9 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win --red-only : Stop just after Red-level compilation. Use higher verbose level to see compiler output. (internal debugging purpose) + + --show-func-map : Output an address/name map of Red/System + functions, for debugging purposes. `[command]` diff --git a/usage.txt b/usage.txt index 1c8160adc0..ebde77098a 100644 --- a/usage.txt +++ b/usage.txt @@ -52,12 +52,17 @@ Note: On Non-Windows platforms, the REPL runs by default in CLI mode. But on Win --config [...] : Provides compilation settings as a block of `name: value` pairs. + --no-compress : Omit Redbin format compression. + --no-runtime : Do not include runtime during Red/System source compilation. --red-only : Stop just after Red-level compilation. Use higher verbose level to see compiler output. (internal debugging purpose) + + --show-func-map : Output an address/name map of Red/System + functions, for debugging purposes. [command]: From 67e185859ac45f68dca35a099616cc2f3d166a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boleslav=20B=C5=99ezovsk=C3=BD?= Date: Sun, 6 Oct 2019 09:28:58 +0200 Subject: [PATCH 0557/3432] FIX: Added missing ===end-group=== --- tests/source/units/binding-test.red | 2 ++ tests/source/units/find-test.red | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/source/units/binding-test.red b/tests/source/units/binding-test.red index a458a5f22b..6451c6d7c6 100644 --- a/tests/source/units/binding-test.red +++ b/tests/source/units/binding-test.red @@ -101,5 +101,7 @@ --test-- "#581" --assert 1 = do load {S: 1 S} +===end-group=== + ~~~end-file~~~ diff --git a/tests/source/units/find-test.red b/tests/source/units/find-test.red index 331ea3281f..8c9adeba95 100644 --- a/tests/source/units/find-test.red +++ b/tests/source/units/find-test.red @@ -398,4 +398,6 @@ Red [ --test-- "issue-3687-12" --assert "87bcdef64" = find/tail/skip/reverse skip s 6 pattern 3 +===end-group=== + ~~~end-file~~~ From 8f86946b3b2014e94615390bc1f0acb874cc03b2 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Wed, 9 Oct 2019 19:18:41 +0300 Subject: [PATCH 0558/3432] FIX: issue #3165 (Cannot drag face when display is scaled) --- modules/view/backends/windows/draw.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index e13bbefb47..a7dcd7a82c 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -165,7 +165,7 @@ update-gdiplus-brush: func [ctx [draw-ctx!] /local handle [integer!]][ ctx/gp-brush: 0 ] if ctx/brush? [ - GdipCreateSolidFill to-gdiplus-color ctx/brush-color :handle + GdipCreateSolidFill to-gdiplus-color-fixed ctx/brush-color :handle ctx/gp-brush: handle ] ] From 7a100c2bb1d0f875ccaa2ea57eebe7e14ed85071 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 2 Oct 2019 13:21:32 +0200 Subject: [PATCH 0559/3432] FIX: regression caused by fix for #3768. --- runtime/datatypes/block.reds | 6 +++--- tests/source/units/series-test.red | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 6aabd4bb72..faf231d520 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1190,7 +1190,7 @@ block: context [ switch TYPE_OF(res) [ TYPE_LOGIC [ bool: as red-logic! res - either bool/value [-1][1] + either bool/value [1][-1] ] TYPE_INTEGER [ int: as red-integer! res @@ -1204,8 +1204,8 @@ block: context [ true [0] ] ] - TYPE_NONE [1] - default [-1] + TYPE_NONE [-1] + default [1] ] ] diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index 597d8d61d1..6dd8bdf362 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1422,8 +1422,8 @@ Red [ --test-- "sort-blk-3" a: ["Larry" 45 "Curly" 50 "Mo" 42] --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 2 - --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a < b] - --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 < b/2] + --assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare a 2 func [a b][a < b] + --assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare/all a 2 func [a b][a/2 < b/2] --test-- "sort-blk-4" o1: context [a: 2 i: "a"] @@ -1437,6 +1437,17 @@ Red [ a: reduce [o1 o2 o3 o8 o4 o5 o6 o7] res: reduce [o2 o3 o4 o5 o6 o1 o8 o7] --assert res = sort/compare/stable a func [a b][b/a - a/a] + + --test-- "sort-blk-5" + --assert [1 3 2] = sort/compare [1 3 2] func [a b] [-5] + --assert [2 3 1] = sort/compare [1 3 2] func [a b] [5] + --assert [6 5 4 3 2 1] = sort/compare [1 2 3 4 5 6] func [a b] [5] + --assert [1 2 3 4 5 6] = sort/compare [1 2 3 4 5 6] func [a b] [-5] + --assert [1 2 3] = sort/compare [1 3 2] func [a b] [a < b] + --assert [3 2 1] = sort/compare [1 3 2] func [a b] [a > b] + --assert [1 2 3 4 5 6] = sort/compare [1 2 3 4 5 6] func [a b] [a < b] + --assert [6 5 4 3 2 1] = sort/compare [1 2 3 4 5 6] func [a b] [a > b] + ===end-group=== ===start-group=== "path access" From 51fbfe691168b441e6ba4811c015dc58655194de Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Wed, 9 Oct 2019 21:08:38 +0300 Subject: [PATCH 0560/3432] FIX: issue #3225 (TEXT in DRAW does not honour TRANSLATE command) --- modules/view/backends/windows/draw.reds | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index a7dcd7a82c..59fc6be4a4 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -372,6 +372,9 @@ draw-begin: func [ graphics: 0 GdipCreateFromHDC dc :graphics SelectObject dc GetStockObject NULL_BRUSH + SelectObject dc default-font + + update-gdiplus-font-color ctx ctx/pen-color ] ] @@ -1660,7 +1663,10 @@ OS-draw-text: func [ len: -1 str: unicode/to-utf16-len text :len no - either ctx/on-image? [ + either any [ + ctx/on-image? + ctx/other/GDI+? + ][ x: 0 rect: as RECT_STRUCT_FLOAT32 :x rect/x: as float32! pos/x From 5bd6f8565a71b17351e33eccaa95c7f717051563 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Fri, 11 Oct 2019 20:22:47 +0300 Subject: [PATCH 0561/3432] FIX: issue #3270 (Panel face with set text facet fills with black) --- modules/view/backends/windows/base.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 7036ee9db5..3e886f50e4 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -132,6 +132,7 @@ render-base: func [ if all [ group-box <> type window <> type + panel <> type render-text values hWnd hDC :rc null null ][ res: true From c4e6724597ceadaaf1138e080fcf76af487d640e Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 15:48:58 +0300 Subject: [PATCH 0562/3432] FIX: issue #3362 (Strange behaviour of CONTEXT and OBJECT with exit in spec-block) --- runtime/datatypes/function.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/datatypes/function.reds b/runtime/datatypes/function.reds index 2b5b9c6cf1..58adaf8cb3 100644 --- a/runtime/datatypes/function.reds +++ b/runtime/datatypes/function.reds @@ -249,6 +249,7 @@ _function: context [ RED_THROWN_BREAK RED_THROWN_CONTINUE RED_THROWN_THROW [re-throw] ;-- let exception pass through + RED_THROWN_EXIT RED_THROWN_RETURN [stack/unwind-last] default [0] ;-- else, do nothing ] From f974c99af416cc6e984e497fb457da09ee4234c4 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sun, 13 Oct 2019 15:54:18 +0300 Subject: [PATCH 0563/3432] TESTS: for issue #3362 (Strange behaviour of CONTEXT and OBJECT with exit in spec-block) --- tests/source/units/regression-test-red.red | 55 +++++++++++++--------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 76c171ad37..fcfa1ca011 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2742,6 +2742,28 @@ b} --assert equal? ["1" ""] split "1^/" #"^/" --assert equal? ["1" "2" ""] split "1^/2^/" #"^/" + --test-- "#2232" + --assert 'ok = (a: 'ok 1 :a) + --assert 'ok = (a: 'ok 1 + 1 :a) + --assert 'ok = (a: 'ok 1 + 1 probe :a) + --assert equal? 'ok (a: 'ok 1 + 1 :a) + --assert equal? 'ok (a: 'ok 1 + 1 :a) + + n: func [/a][100] + res: n - (1 n/a) + --assert zero? res + --assert n - (1 n/a) = 0 + --assert (n - (1 n/a)) = 0 + + --assert zero? n - (x: 0 n) + --assert zero? n - (x: 0 n/a) + --assert zero? n - (x: 123 n/a) + --assert zero? n - (1 + 2 n/a) + --assert equal? [100] reduce [(1 + 2 n/a)] + + --assert equal? [3 100] reduce [1 + 2 n/a] + --assert equal? [100 100 123 3] reduce [(123 n/a) (1 + 2 n/a) (n/a 123) (n/a 1 + 2)] + --test-- "#2234" m2234: #(a 1 b 2) remove/key m2234 'a @@ -2764,6 +2786,17 @@ b} rest3603: none --assert bu3603 = back change block3603: [] do/next block3603 'rest3603 + --test-- "#3362" + do [ ;-- FIXME: compiler doesn't like this + spec3362-1: [return 100] + spec3362-2: [exit] + --assert 100 = context spec3362-1 + --assert unset? context spec3362-2 + --assert 100 = context [return 100] + --assert unset? context [exit] + unset [spec3362-1 spec3362-2] + ] + --test-- "#3739" reactor3739: func [spec] [make deep-reactor! spec] s3739: reactor3739 [started: no] @@ -2808,28 +2841,6 @@ comment { ] } - --test-- "#2232" - --assert 'ok = (a: 'ok 1 :a) - --assert 'ok = (a: 'ok 1 + 1 :a) - --assert 'ok = (a: 'ok 1 + 1 probe :a) - --assert equal? 'ok (a: 'ok 1 + 1 :a) - --assert equal? 'ok (a: 'ok 1 + 1 :a) - - n: func [/a][100] - res: n - (1 n/a) - --assert zero? res - --assert n - (1 n/a) = 0 - --assert (n - (1 n/a)) = 0 - - --assert zero? n - (x: 0 n) - --assert zero? n - (x: 0 n/a) - --assert zero? n - (x: 123 n/a) - --assert zero? n - (1 + 2 n/a) - --assert equal? [100] reduce [(1 + 2 n/a)] - - --assert equal? [3 100] reduce [1 + 2 n/a] - --assert equal? [100 100 123 3] reduce [(123 n/a) (1 + 2 n/a) (n/a 123) (n/a 1 + 2)] - ===end-group=== ~~~end-file~~~ From 7fbe7a4a7d2b925fca17ed1351017599baf21851 Mon Sep 17 00:00:00 2001 From: semseddin Date: Mon, 14 Oct 2019 22:48:55 +0300 Subject: [PATCH 0564/3432] FIX: #4079 replace on strings should work with non-formed arguments --- environment/functions.red | 6 +++++- tests/source/units/replace-test.red | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/environment/functions.red b/environment/functions.red index 7845ee471f..685ed54117 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -233,7 +233,11 @@ replace: function [ ] return series ] - if system/words/all [any [char? :pattern tag? :pattern] any-string? series] [ + if system/words/all [ + any [not any-string? :pattern tag? :pattern] + any-string? series + not block? :pattern + ] [ pattern: form pattern ] either system/words/all [any-string? :series block? :pattern] [ diff --git a/tests/source/units/replace-test.red b/tests/source/units/replace-test.red index 3962b9003a..00cfb81838 100644 --- a/tests/source/units/replace-test.red +++ b/tests/source/units/replace-test.red @@ -26,6 +26,8 @@ Red [ --test-- "replace-11" --assert %file.ext = replace %file.sub.ext ".sub." #"." --test-- "replace-12" --assert "abra-abra" = replace "abracadabra" "cad" #"-" --test-- "replace-13" --assert "abra-c-adabra" = replace "abracadabra" #"c" "-c-" + --test-- "replace-14" --assert "x23" = replace "123" 1 "x" + --test-- "replace-15" --assert "xbc" = replace "abc" quote a: "x" ===end-group=== From a297be84ef0795a5d34ef4aabd63504663553aa9 Mon Sep 17 00:00:00 2001 From: semseddin Date: Wed, 16 Oct 2019 01:46:00 +0300 Subject: [PATCH 0565/3432] FIX: Fix for failed replace tests (test: replace-bitset-issue-#3132) --- environment/functions.red | 1 + 1 file changed, 1 insertion(+) diff --git a/environment/functions.red b/environment/functions.red index 685ed54117..ff457720b5 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -237,6 +237,7 @@ replace: function [ any [not any-string? :pattern tag? :pattern] any-string? series not block? :pattern + not bitset? :pattern ] [ pattern: form pattern ] From 044e56b10a48db378b866c50dde6b3bb73f01844 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 18 Oct 2019 14:33:41 +0200 Subject: [PATCH 0566/3432] FEAT: form float will try to give user friendly output. mold float will give precise result. --- runtime/datatypes/float.reds | 124 ++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 18 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index e819d4b929..1165cd48d0 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -88,12 +88,16 @@ float: context [ /local s [c-string!] s0 [c-string!] + p0 [c-string!] + p [c-string!] + p1 [c-string!] + dot? [logic!] d [int64!] w0 [integer!] - n [integer!] temp [float!] + tried? [logic!] + pretty? [logic!] percent? [logic!] - add-0? [logic!] ][ d: as int64! :f w0: d/int2 ;@@ Use little endian. Watch out big endian ! @@ -109,35 +113,115 @@ float: context [ ] percent?: any [type = FORM_PERCENT type = FORM_PERCENT_32] - add-0?: any [type = FORM_FLOAT_64 type = FORM_FLOAT_32] - if pretty-print? [ temp: abs f if temp < DBL_EPSILON [return either percent? ["0%"]["0.0"]] ] - n: case [ - any [ - type = FORM_FLOAT_32 - type = FORM_PERCENT_32 - type = FORM_TIME - ][7] - type = FORM_PERCENT [13] - true [0] + s: "0000000000000000000000000000000" ;-- 32 bytes wide, big enough. + case [ + any [type = FORM_FLOAT_32 type = FORM_PERCENT_32][ + sprintf [s "%.7g" f] + ] + type = FORM_TIME [ ;-- microsecond precision + either f < 10.0 [s0: "%.7g"][s0: "%.8g"] + sprintf [s s0 f] + ] + type = FORM_PERCENT [ + sprintf [s "%.13g" f] + ] + true [ + s/17: #"0" + s/18: #"0" + sprintf [s "%.16g" f] + ] ] - s: red-dtoa/form-float f n add-0? - if percent? [ - s0: s + tried?: no + s0: s + until [ + p: null + p1: null + dot?: no + until [ + if s/1 = #"." [dot?: yes] + if s/1 = #"e" [ + p: s + until [ + s: s + 1 + s/1 > #"0" + ] + p1: s + ] s: s + 1 s/1 = #"^@" ] + + if pretty-print? [ ;-- prettify output if needed + pretty?: no + either p = null [ ;-- No "E" notation + w0: as-integer s - s0 + if w0 > 16 [ + p0: either s0/1 = #"-" [s0 + 1][s0] + if any [ + p0/1 <> #"0" + all [p0/1 = #"0" w0 > 17] + ][ + p0: s - 2 + pretty?: yes + ] + ] + ][ + if (as-integer p - s0) > 16 [ ;-- the number of digits = 16 + p0: p - 2 + pretty?: yes + ] + ] + + if all [pretty? not tried?][ + if any [ ;-- correct '01' or '99' pattern + all [p0/2 = #"1" p0/1 = #"0"] + all [p0/2 = #"9" p0/1 = #"9"] + ][ + tried?: yes + s: case [ + type = FORM_FLOAT_32 ["%.5g"] + type = FORM_TIME ["%.6g"] + true ["%.14g"] + ] + sprintf [s0 s f] + s: s0 + ] + ] + ] + s0 <> s + ] + + if p1 <> null [ ;-- remove #"+" and leading zero + p0: p + either p/2 = #"-" [p: p + 2][p: p + 1] + move-memory as byte-ptr! p as byte-ptr! p1 as-integer s - p1 + s: p + as-integer s - p1 + s/1: #"^@" + p: p0 + ] + either percent? [ s/1: #"%" s/2: #"^@" - s: s0 + ][ + if all [not dot? type <> FORM_TIME][ ;-- added tailing ".0" + either p = null [ + p: s + ][ + move-memory as byte-ptr! p + 2 as byte-ptr! p as-integer s - p + ] + p/1: #"." + p/2: #"0" + s/3: #"^@" + ] ] - s + s0 ] do-math-op: func [ @@ -516,10 +600,14 @@ float: context [ part [integer!] indent [integer!] return: [integer!] + /local + s [c-string!] ][ #if debug? = yes [if verbose > 0 [print-line "float/mold"]] - form fl buffer arg part + s: red-dtoa/form-float fl/value 0 yes + string/concatenate-literal buffer s + part - length? s ;@@ optimize by removing length? ] NaN?: func [ From c8446687c872f232998fcc048783daec7edbbc14 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 18 Oct 2019 17:01:14 +0200 Subject: [PATCH 0567/3432] FIX: regression on molding time!. --- runtime/datatypes/float.reds | 7 +++---- runtime/datatypes/string.reds | 2 +- runtime/dtoa.reds | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 1165cd48d0..e243040084 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -124,8 +124,7 @@ float: context [ sprintf [s "%.7g" f] ] type = FORM_TIME [ ;-- microsecond precision - either f < 10.0 [s0: "%.7g"][s0: "%.8g"] - sprintf [s s0 f] + s: dtoa/form-float f 6 no ] type = FORM_PERCENT [ sprintf [s "%.13g" f] @@ -187,7 +186,7 @@ float: context [ tried?: yes s: case [ type = FORM_FLOAT_32 ["%.5g"] - type = FORM_TIME ["%.6g"] + type = FORM_TIME ["%.5g"] true ["%.14g"] ] sprintf [s0 s f] @@ -605,7 +604,7 @@ float: context [ ][ #if debug? = yes [if verbose > 0 [print-line "float/mold"]] - s: red-dtoa/form-float fl/value 0 yes + s: dtoa/form-float fl/value 0 yes string/concatenate-literal buffer s part - length? s ;@@ optimize by removing length? ] diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 4ae56c89f9..2e4f4cbb5f 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -71,7 +71,7 @@ string: context [ e [int-ptr!] return: [float!] ][ - red-dtoa/string-to-float s s + len e + dtoa/to-float s s + len e ] byte-to-hex: func [ diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index a1813589da..999a039c53 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -64,7 +64,7 @@ Red/System [ #define DTOA_BIG_0 [(FRAC_MASK1 or (DBL_MAX_EXP + DTOA_BIAS - 1 * DTOA_EXP_MSK1))] #define DTOA_BIG_1 FFFFFFFFh -red-dtoa: context [ +dtoa: context [ P05: [5 25 125] DTOA_TENS: [ 1e0 1e1 1e2 1e3 1e4 1e5 1e6 1e7 1e8 1e9 @@ -1382,7 +1382,7 @@ red-dtoa: context [ STRTOD_BREAK ] - string-to-float: func [ + to-float: func [ start [byte-ptr!] end [byte-ptr!] ret [int-ptr!] From c4d7888dc194e5707191387c1599314dec5067ce Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 18 Oct 2019 23:16:36 +0200 Subject: [PATCH 0568/3432] FIX: pretty printing for float in the console. --- environment/console/engine.red | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/environment/console/engine.red b/environment/console/engine.red index 43815ff8bd..47fdb2d3a2 100644 --- a/environment/console/engine.red +++ b/environment/console/engine.red @@ -217,7 +217,10 @@ system/console: context [ not unset? :result [ if error? set/any 'err try [ ;-- catch eventual MOLD errors limit: size/x - 13 - if limit <= length? result: mold/part :result limit [ ;-- optimized for width = 72 + result: either float? :result [form/part :result limit][ + mold/part :result limit + ] + if limit <= length? result [ ;-- optimized for width = 72 clear back tail result append result "..." ] From e6c852e601a5928b36441e46bbccba14d4ea4a03 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 19 Oct 2019 10:36:05 +0200 Subject: [PATCH 0569/3432] FIX: GC: direct pointer on stack is updated incorrectly in some cases. The tail of a series is the same as the beginning of the next series it adjacent to. If a direct pointer point to the tail of a series, the GC may think it's the beginning of a series and updated it to wrong value. --- runtime/allocator.reds | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index 84370a84a3..efb6ed9b99 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -15,6 +15,8 @@ Red/System [ COLLECTOR_RELEASE ;-- will release empty frames to OS ] +#define SERIES_BUFFER_PADDING 4 + int-array!: alias struct! [ptr [int-ptr!]] ;-- cell header bits layout -- @@ -455,7 +457,7 @@ update-series: func [ s/node/value: as-integer s ;-- update the node pointer to the new series address s/offset: as cell! (as byte-ptr! s/offset) - offset ;-- update offset and tail pointers s/tail: as cell! (as byte-ptr! s/tail) - offset - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING tail <= as byte-ptr! s ] ] @@ -495,7 +497,7 @@ compact-series-frame: func [ ;probe ["search live from: " s] free-node s/node while [ ;-- search for a live series - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING tail?: s >= heap mark?: s/flags and flag-gc-mark <> 0 not any [mark? tail?] @@ -509,7 +511,7 @@ compact-series-frame: func [ ;probe ["search gap from: " s] until [ ;-- search for a gap s/flags: s/flags and not flag-gc-mark ;-- clear mark flag - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING tail?: s >= heap any [s/flags and flag-gc-mark = 0 tail?] ] @@ -526,7 +528,7 @@ compact-series-frame: func [ if refs < tail [ ;-- update pointers on native stack while [all [refs < tail (as byte-ptr! refs/1) < src]][refs: refs + 2] - while [all [refs < tail (as byte-ptr! refs/1) <= (src + size)]][ + while [all [refs < tail (as byte-ptr! refs/1) < (src + size)]][ ptr: as int-ptr! refs/2 ptr/value: ptr/value - delta refs: refs + 2 @@ -594,7 +596,7 @@ cross-compact-frame: func [ if dst = null [dst: as byte-ptr! s] free-node s/node while [ ;-- search for a live series - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING tail?: s >= heap mark?: s/flags and flag-gc-mark <> 0 not any [mark? tail?] @@ -608,9 +610,9 @@ cross-compact-frame: func [ until [ ;-- search for a gap s/flags: s/flags and not flag-gc-mark ;-- clear mark flag size2: size - size: size + s/size + size? series-buffer! + size: SERIES_BUFFER_PADDING + size + s/size + size? series-buffer! ss: s ;-- save previous series pointer - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING tail?: s >= heap any [ all [cross? size >= free-sz] @@ -657,7 +659,7 @@ cross-compact-frame: func [ update-series as series! dst2 delta size if refs < tail [ ;-- update pointers on native stack while [all [refs < tail (as byte-ptr! refs/1) < src]][refs: refs + 2] - while [all [refs < tail (as byte-ptr! refs/1) <= (src + size)]][ + while [all [refs < tail (as byte-ptr! refs/1) < (src + size)]][ ptr: as int-ptr! refs/2 ptr/value: ptr/value - delta refs: refs + 2 @@ -687,7 +689,7 @@ in-range?: func [ ][ frm: memory/s-head until [ - if all [(as int-ptr! frm + 1) <= p p <= as int-ptr! frm/tail][return yes] + if all [(as int-ptr! frm + 1) <= p p < as int-ptr! frm/tail][return yes] frm: frm/next frm = null ] @@ -824,7 +826,7 @@ collect-frames: func [ until [ either s/flags and flag-gc-mark = 0 [prin "x "][prin "o "] probe [s ": unit=" GET_UNIT(s) " size=" s/size] - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING s >= heap ] @@ -861,7 +863,7 @@ collect-frames: func [ dump4 s halt ] - s: as series! (as byte-ptr! s + 1) + s/size + s: as series! (as byte-ptr! s + 1) + s/size + SERIES_BUFFER_PADDING ] ] @@ -899,7 +901,9 @@ alloc-series-buffer: func [ size: round-to usize * unit size? cell! ;-- size aligned to cell! size frame: memory/s-active - sz: size + size? series-buffer! ;-- add series header size + ;-- add series header size + (extra padding 4 bytes) + ;-- extra space between two adjacent series-buffer!s (ensure s1/tail <> s2) + sz: SERIES_BUFFER_PADDING + size + size? series-buffer! flag-big: 0 either sz >= memory/s-max [ ;-- alloc a big frame if too big for series frames @@ -1090,7 +1094,7 @@ free-series: func [ series/flags: series/flags and series-free-mask ;-- clear 'used bit (enough to free the series) if frame/heap = as series-buffer! ( ;-- test if series is on top of heap - (as byte-ptr! node/value) + series/size + size? series-buffer! + (as byte-ptr! series) + SERIES_BUFFER_PADDING + series/size + size? series-buffer! ) [ frame/heap: series ;-- cheap collecting of last allocated series ] From 8c45989bfe88b3bb46311a0c84d6c5deedebaf56 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 19 Oct 2019 10:38:00 +0200 Subject: [PATCH 0570/3432] FIX: TEST: clipboard-test failed when it's compiled in release mode. --- tests/source/units/clipboard-test.red | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/source/units/clipboard-test.red b/tests/source/units/clipboard-test.red index 15757d3abd..b2667b25d6 100644 --- a/tests/source/units/clipboard-test.red +++ b/tests/source/units/clipboard-test.red @@ -71,6 +71,7 @@ Red [ --assert ii2 = read-clipboard unset 'ii2 + unless unset? :draw [ --test-- "image-io-3" ii3: draw make image! [100x100 0.200.200.200] [pen purple line-width 5 circle 50x50 40] --assert false <> write-clipboard ii3 @@ -82,6 +83,7 @@ Red [ --assert false <> write-clipboard iil1 --assert iil1 = read-clipboard unset 'iil1 + ] ]];; do [if system/platform = 'Windows [ From 7fdb6b8eed1c02133f2a0bdb5e85e1742c78a8ac Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 19 Oct 2019 18:57:16 +0800 Subject: [PATCH 0571/3432] FIX: add `Exception handling` to low level `make-event` on macOS --- modules/view/backends/macOS/events.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/events.reds b/modules/view/backends/macOS/events.reds index 723561c112..51ce9edd2c 100644 --- a/modules/view/backends/macOS/events.reds +++ b/modules/view/backends/macOS/events.reds @@ -486,8 +486,13 @@ make-event: func [ ] state: EVT_DISPATCH - - #call [system/view/awake gui-evt] + stack/mark-try-all words/_anon + catch CATCH_ALL_EXCEPTIONS [ + #call [system/view/awake gui-evt] + stack/unwind + ] + stack/adjust-post-try + if system/thrown <> 0 [system/thrown: 0] res: as red-word! stack/arguments if TYPE_OF(res) = TYPE_WORD [ From 39a008542ffafcd1232ea1ab860c31bf02a7ae80 Mon Sep 17 00:00:00 2001 From: loziniak Date: Mon, 21 Oct 2019 17:08:44 +0200 Subject: [PATCH 0572/3432] remove object! from find's docstring; see commit 7b1eeb76 --- environment/actions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index 830f30040f..d758c38ba0 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -290,7 +290,7 @@ copy: make action! [[ find: make action! [[ "Returns the series where a value is found, or NONE" - series [series! bitset! typeset! any-object! map! none!] + series [series! bitset! typeset! map! none!] value [any-type!] /part "Limit the length of the search" length [number! series!] From 4c4e184e0a3946a41a87f4fe934b40eeb10ef808 Mon Sep 17 00:00:00 2001 From: loziniak Date: Mon, 21 Oct 2019 22:10:40 +0200 Subject: [PATCH 0573/3432] FIX: port! supports find action --- environment/actions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index d758c38ba0..8694f4f741 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -290,7 +290,7 @@ copy: make action! [[ find: make action! [[ "Returns the series where a value is found, or NONE" - series [series! bitset! typeset! map! none!] + series [series! bitset! typeset! port! map! none!] value [any-type!] /part "Limit the length of the search" length [number! series!] From 3a893d35ac0a092c0b4ed7e754bab2acc789c910 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 25 Oct 2019 17:07:30 +0200 Subject: [PATCH 0574/3432] FIX: issue #4102 ([R/S] ASSERT false doesn't work) After this change, beware of unwanted assertion crashes from Core and View when compiling in debug mode. --- system/compiler.r | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index e9f9293c19..4b1a3b375c 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -2350,7 +2350,9 @@ system-dialect: make-profilable context [ process-logic-encoding: func [expr invert? [logic!]][ ;-- preprocess logic values case [ - logic? expr [ [#[true]] ] + logic? expr [ + reduce [not invert?] + ] find [word! path!] type?/word expr [ emitter/target/emit-integer-operation '= [ 0] reduce [not invert?] From 672e9b42e302713af5f22f7cc3fccbc4718a4cc2 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 16 Nov 2019 08:48:59 +0100 Subject: [PATCH 0575/3432] FIX: cannot decompresss double compressed data (quick temporary fix). --- runtime/compress.reds | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/runtime/compress.reds b/runtime/compress.reds index 9211d4d577..9dc4be4204 100644 --- a/runtime/compress.reds +++ b/runtime/compress.reds @@ -157,9 +157,9 @@ gzip-uncompress: func [ res: deflate/uncompress dest dest-len start c if res <> 0 [return res] - if dlen <> dest-len/1 [ + either dlen > dest-len/1 [ return INFLATE-GZIP-HDR - ] + ][dest-len/1: dlen] ;--check CRC32 checksum c: crypto/CRC32 dest dlen @@ -188,16 +188,17 @@ gzip-compress: func [ ] dstart: dest dend: dest + dest-len/1 - dest/1: #"^(1F)" - dest/2: #"^(8B)" - dest/3: #"^(08)" - dest/4: #"^(00)" - dest/5: #"^(00)" + ;-- header + dest/1: #"^(1F)" ;-- ID1 + dest/2: #"^(8B)" ;-- ID2 + dest/3: #"^(08)" ;-- CM (compression method) + dest/4: #"^(00)" ;-- FLG + dest/5: #"^(00)" ;-- MTIME (4 bytes) dest/6: #"^(00)" dest/7: #"^(00)" dest/8: #"^(00)" - dest/9: #"^(04)" - dest/10: #"^(04)" + dest/9: #"^(04)" ;-- XFL + dest/10: #"^(04)" ;-- OS dest: dest + 10 dest-len/1: dest-len/1 - 10 res: deflate/compress dest dest-len src src-len From 7eaeb467941781ba00ee203d43aef50acaa7d250 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 16 Nov 2019 09:02:29 +0100 Subject: [PATCH 0576/3432] FEAT: avoid to compress already compressed data. --- runtime/compress.reds | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/runtime/compress.reds b/runtime/compress.reds index 9dc4be4204..aa4e0474b5 100644 --- a/runtime/compress.reds +++ b/runtime/compress.reds @@ -182,6 +182,17 @@ gzip-compress: func [ res [integer!] crc [integer!] ][ + ;-- check if data is already compressed + if all [src-len > 2 src/1 = #"^(1F)" src/2 = #"^(8B)" src/3 = #"^(08)"][ + dest-len/value: src-len + either dest-len/value < src-len [ + return DEFLATE-GZIP-LEN + ][ + copy-memory dest src src-len + return DEFLATE-GZIP-OK + ] + ] + if dest-len/1 < 18 [ dest-len/1: 18 + src-len return DEFLATE-GZIP-BUFF From ba2b6ea2bef285cd236ccd12d5d0485d3022afd1 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 16 Nov 2019 17:22:27 +0100 Subject: [PATCH 0577/3432] FIX: issue #4132 (PicoSheets demo crash) and issue #3357. --- runtime/parse.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index 5d0c6f47cb..14c1e2ed2a 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -1671,7 +1671,9 @@ parser: context [ ] PARSE_SAVE_SERIES before: input/head - if word? [value: _context/get as red-word! value] + if all [word? TYPE_OF(value) = TYPE_WORD][ + value: _context/get as red-word! value + ] actions/insert input value null as-logic max null no input/head: saved + (input/head - before) if s-top <> null [stack/top: s-top] From dcabf0e7064f8475ce09341f8d804e003f2070cd Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 19 Nov 2019 14:08:45 +0100 Subject: [PATCH 0578/3432] FEAT: use struct value on stack instead of static variables in camera.reds. --- modules/view/backends/windows/camera.reds | 35 +++++++---------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/modules/view/backends/windows/camera.reds b/modules/view/backends/windows/camera.reds index ec7d7817b4..a3dd378cef 100644 --- a/modules/view/backends/windows/camera.reds +++ b/modules/view/backends/windows/camera.reds @@ -186,9 +186,9 @@ init-graph: func [ cam [camera!] idx [integer!] /local - IB [interface!] - IG [interface!] - ICap [interface!] + IB [interface! value] + IG [interface! value] + ICap [interface! value] graph [IGraphBuilder] moniker [IMoniker] builder [ICaptureGraphBuilder2] @@ -196,10 +196,6 @@ init-graph: func [ dev-ptr [int-ptr!] dev [this!] ][ - IB: declare interface! - IG: declare interface! - ICap: declare interface! - hr: CoCreateInstance CLSID_CaptureGraphBuilder2 0 1 IID_ICaptureGraphBuilder2 IB builder: as ICaptureGraphBuilder2 IB/ptr/vtbl cam/builder: IB/ptr @@ -229,17 +225,16 @@ build-preview-graph: func [ return: [integer!] /local filter [this!] - IVM [interface!] + IVM [interface! value] graph [IGraphBuilder] builder [ICaptureGraphBuilder2] video [IVideoWindow] hr [integer!] - rect [RECT_STRUCT] + rect [RECT_STRUCT value] ][ builder: as ICaptureGraphBuilder2 cam/builder/vtbl graph: as IGraphBuilder cam/graph/vtbl filter: as this! cam/v-filter - IVM: declare interface! hr: builder/RenderStream cam/builder PIN_CATEGORY_PREVIEW MEDIATYPE_Interleaved filter null null case [ @@ -256,7 +251,6 @@ build-preview-graph: func [ ] hr: graph/QueryInterface cam/graph IID_IVideoWindow IVM either zero? hr [ - rect: declare RECT_STRUCT GetClientRect hWnd rect video: as IVideoWindow IVM/ptr/vtbl video/put_Owner IVM/ptr hWnd @@ -276,13 +270,12 @@ toggle-preview: func [ handle [handle!] enabled? [logic!] /local - this [interface!] + this [interface! value] cam [camera!] graph [IGraphBuilder] mc [IMediaControl] hr [integer!] ][ - this: declare interface! cam: as camera! GetWindowLong handle wc-offset - 4 if cam = null [exit] graph: as IGraphBuilder cam/graph/vtbl @@ -327,11 +320,11 @@ collect-camera: func [ return: [integer!] /local hr [integer!] - var [tagVARIANT] - IDev [interface!] - IEnum [interface!] - IM [interface!] - IBag [interface!] + var [tagVARIANT value] + IDev [interface! value] + IEnum [interface! value] + IM [interface! value] + IBag [interface! value] dev [ICreateDevEnum] em [IEnumMoniker] moniker [IMoniker] @@ -343,11 +336,6 @@ collect-camera: func [ fetched [integer!] cnt [integer!] ][ - IDev: declare interface! - IEnum: declare interface! - IM: declare interface! - IBag: declare interface! - hr: CoCreateInstance CLSID_SystemDeviceEnum 0 1 IID_ICreateDevEnum IDev if hr <> 0 [probe "Error Creating Device Enumerator" return 0] @@ -361,7 +349,6 @@ collect-camera: func [ dev/Release IDev/ptr em: as IEnumMoniker IEnum/ptr/vtbl - var: declare tagVARIANT var/data1: 8 << 16 ;-- var.vt = VT_BSTR dev-ptr: (as int-ptr! cam) + 4 fetched: 0 From 402386b13d8106bdd784d0f338259d874e85d867 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 20 Nov 2019 18:58:36 +0100 Subject: [PATCH 0579/3432] FIX: issue #4133 (random values in VECTOR! for 8-16 bit INTEGER! or CHAR!) --- runtime/allocator.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index efb6ed9b99..fd1863c3d1 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -155,7 +155,7 @@ fill: func [ unless aligned? [ ;-- postprocess unaligned ending cnt: (as-integer end) and 3 - while [cnt > 0][end/cnt: byte cnt: cnt - 1] + while [cnt > 0][p/cnt: byte cnt: cnt - 1] ] ] From 53f9dd14589e7d7e8fac22b80f67ff35cbec0de8 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 20 Nov 2019 19:01:43 +0100 Subject: [PATCH 0580/3432] FIX: additional fix for issue #4133 --- runtime/allocator.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index fd1863c3d1..138c56d917 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -154,7 +154,8 @@ fill: func [ ] unless aligned? [ ;-- postprocess unaligned ending - cnt: (as-integer end) and 3 + cnt: (as-integer end) and 3 + p: as byte-ptr! p4 while [cnt > 0][p/cnt: byte cnt: cnt - 1] ] ] From 55ef757e7a86ba2bc8b69c9af7e9cb43a693b9e9 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 17 Nov 2019 12:36:01 +0800 Subject: [PATCH 0581/3432] FIX: compress twice will get error data format --- runtime/deflate.reds | 74 ++++++++++++++++---------- tests/source/units/decompress-test.red | 10 ++++ 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/runtime/deflate.reds b/runtime/deflate.reds index 26c1e6ab9f..f7db5cd419 100644 --- a/runtime/deflate.reds +++ b/runtime/deflate.reds @@ -292,6 +292,7 @@ deflate: context [ st [DEFLATE! value] dst [byte-ptr!] dend [byte-ptr!] + istart [byte-ptr!] iend [byte-ptr!] dict [int-ptr!] ptr [byte-ptr!] @@ -309,6 +310,7 @@ deflate: context [ st/bits: 0 st/cnt: 0 dst: out dend: dst + out-size/1 + istart: in iend: in + in-size dst: write dst dend st 1 1 @@ -317,47 +319,61 @@ deflate: context [ ptr: in h: hash in ents: dict + (h and DICT_MASK * CACHE_SIZE) - i: 0 - while [i < CACHE_SIZE][ - pos: i + 1 - sub: as byte-ptr! ents/pos - if all [ - sub <> null - in > sub - in < (sub + MAX_OFF) - 0 = compare-memory in sub MIN_MATCH - ][ - s: sub + MIN_MATCH - dist: as integer! in - sub - len: MIN_MATCH - in: in + len - while [ - all [ - s/1 = in/1 - len < MAX_MATCH - ] + either all [ + MIN_MATCH <= as integer! in - istart + MIN_MATCH <= as integer! iend - in + ][ + i: 0 + while [i < CACHE_SIZE][ + pos: i + 1 + sub: as byte-ptr! ents/pos + if all [ + sub <> null + in > sub + in < (sub + MAX_OFF) + 0 = compare-memory in sub MIN_MATCH ][ - len: len + 1 - s: s + 1 - in: in + 1 + s: sub + MIN_MATCH + dist: as integer! in - sub + len: MIN_MATCH + in: in + len + while [ + all [ + s/1 = in/1 + len < MAX_MATCH + in < iend + ] + ][ + len: len + 1 + s: s + 1 + in: in + 1 + ] + dst: match dst dend st dist len + break ] - dst: match dst dend st dist len - break + i: i + 1 ] - i: i + 1 - ] - if i = CACHE_SIZE [ + if i = CACHE_SIZE [ + dst: lit dst dend st as integer! in/1 + in: in + 1 + ] + ][ dst: lit dst dend st as integer! in/1 in: in + 1 ] + c: hash2 in pos: c and CACHE_MASK + 1 ents/pos: as integer! ptr ] + ;-- block end dst: write dst dend st 0 7 - dst: write dst dend st 2 10 - dst: write dst dend st 2 3 + ;dst: write dst dend st 2 10 + ;dst: write dst dend st 2 3 + if st/bits < 8 [ + dst: write dst dend st 0 8 - st/bits + ] out-size/value: as integer! dst - out if dst > dend [ return DEFLATE-NO-MEM diff --git a/tests/source/units/decompress-test.red b/tests/source/units/decompress-test.red index 54938da12e..971ff919b2 100644 --- a/tests/source/units/decompress-test.red +++ b/tests/source/units/decompress-test.red @@ -51,6 +51,16 @@ Red [ --test-- "zlib" --assert data = to string! decompress/zlib compress/zlib to binary! data 0 + --test-- "cascaded" + ;-- gzip format only compressed once + --assert data = to string! decompress compress compress data + --assert data = to string! decompress compress compress compress data + ;-- deflate/zlib format support nested call + --assert data = to string! decompress/deflate decompress/deflate compress/deflate compress/deflate data 0 0 + --assert data = to string! decompress/deflate decompress/deflate decompress/deflate compress/deflate compress/deflate compress/deflate data 0 0 0 + --assert data = to string! decompress/zlib decompress/zlib compress/zlib compress/zlib data 0 0 + --assert data = to string! decompress/zlib decompress/zlib decompress/zlib compress/zlib compress/zlib compress/zlib data 0 0 0 + ===end-group=== ~~~end-file~~~ From a7f914d5ff0c1882b4efdf95528bb4b5145ab1e5 Mon Sep 17 00:00:00 2001 From: x8x Date: Tue, 26 Nov 2019 01:35:24 +0700 Subject: [PATCH 0582/3432] Feat: 'about' command, use commit date, not author date. --- build/git-version.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/git-version.r b/build/git-version.r index 1b77bc18db..412ee28361 100644 --- a/build/git-version.r +++ b/build/git-version.r @@ -32,7 +32,7 @@ context [ tag: (to issue! temp/1) ahead: (to integer! temp/2) date: to-local-date to date! ( - to integer! git {log -1 --pretty=format:"%at"} + to integer! git {log -1 --pretty=format:"%ct"} ) commit: (to issue! git "rev-parse HEAD") message: (git "log -1 --pretty=%B") From 5fdc74bb4b03eb60bbe1c6489bdd5f2c2d989946 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 26 Nov 2019 13:34:30 +0100 Subject: [PATCH 0583/3432] FIX: $SHELL environment variable is not defined in some docker images. --- runtime/call.reds | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/call.reds b/runtime/call.reds index 36e324549f..32e5109332 100644 --- a/runtime/call.reds +++ b/runtime/call.reds @@ -395,6 +395,9 @@ ext-process: context [ init: does [ shell-name: platform/getenv "SHELL" + if null? shell-name [ ;-- if $SHELL is not defined + shell-name: "/bin/bash" + ] init-global ] From 0af96ecced4af7aba678d937b6254b40ca77a7a8 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Wed, 27 Nov 2019 02:04:50 +0300 Subject: [PATCH 0584/3432] FIX: issue 4156 (Bugs in GUI Console keyboard shortcuts) --- environment/console/GUI/core.red | 69 +++++++++++++++----------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index b4c2704663..edd55284a1 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -451,18 +451,17 @@ object [ ] ] - jump-word: func [left? [logic!] return: [integer!] /local start n][ + jump-word: func [left? [logic!] return: [integer!] /local n dlm wc here p][ + dlm: charset {/\^^[](){}"@:; ^-} ;-- word delimiters + wc: negate dlm + here: skip line pos either left? [ - start: find/reverse/tail skip line pos #" " - either start [ - n: (index? start) - pos - index? line - if all [zero? n pos <> 0][n: -1] - ][n: pos] + rev: reverse copy/part head line here + parse rev [any dlm any wc p:] + n: offset? p rev ][ - start: find skip line pos #" " - unless start [start: tail line] - n: (index? start) - pos - index? line - if all [zero? n pos <> length? line][n: 1] + parse here [any dlm any wc p:] + n: offset? here p ] n ] @@ -784,38 +783,36 @@ object [ delete-text: func [ ctrl? [logic!] /backward - /local n idx s del? + /local n idx s del? rev dlm wc p here ][ if delete-selected [exit] + dlm: charset {/\^^[](){}"@:; ^-} ;-- word delimiters + wc: negate dlm del?: no - if all [not backward pos <> 0][ - if #" " = pick line pos [ctrl?: no] - either ctrl? [ - idx: index? line - start-idx: find/reverse/tail skip line pos #" " - either all [start-idx (index? start-idx) > idx][ - n: pos + idx - index? start-idx - ][ - start-idx: line - n: pos - ] - pos: pos - n - s: take/part start-idx n - reduce/into [pos s] undo-stack - ][ - pos: pos - 1 - s: take skip line pos - reduce/into [pos s] undo-stack + here: skip line pos + n: 1 + if all [backward pos <> 0][ + if ctrl? [ + rev: reverse copy/part head line here + parse rev [any dlm any wc p:] + n: offset? rev p ] + pos: pos - n del?: yes ] - if all [backward pos < length? line][ - s: take skip line pos - reduce/into [pos s] undo-stack + if all [not backward pos < length? line][ + if ctrl? [ + parse here [any dlm any wc p:] + n: offset? here p + ] del?: yes ] - if del? [clear selects clear redo-stack] + if del? [ + s: take/part skip line pos n + reduce/into [pos s] undo-stack + clear selects clear redo-stack + ] ] clean: func [][ @@ -863,14 +860,15 @@ object [ ]] switch/default char [ #"^M" [exit-ask-loop] ;-- ENTER key - #"^H" [delete-text ctrl?] + #"^H" [delete-text/backward ctrl?] ;-- both Backspace and Ctrl+H + #"^~" [delete-text/backward yes] ;-- Ctrl + Backspace #"^-" [unless empty? line [do-completion line char]] left [move-caret/event -1 event] right [move-caret/event 1 event] up [either ctrl? [scroll-lines 1][fetch-history 'prev]] down [either ctrl? [scroll-lines -1][fetch-history 'next]] insert [if event/shift? [paste exit]] - delete [delete-text/backward ctrl?] + delete [either event/shift? [cut][delete-text ctrl?]] #"^A" home [if shift? [select-text 0 - pos] pos: 0] #"^E" end [ if shift? [select-text (length? line) - pos] @@ -882,7 +880,6 @@ object [ #"^Z" [undo undo-stack redo-stack] #"^Y" [undo redo-stack undo-stack] #"^[" [exit-ask-loop/escape] - #"^~" [delete-text yes] ;-- Ctrl + Backspace #"^L" [clean] #"^K" [clear line pos: 0] ;-- delete the whole line ][ From a0c344e8b2107f33cf09a507c6429278d99a025b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 28 Nov 2019 15:34:21 +0800 Subject: [PATCH 0585/3432] FIX: set metrics for gtk3 --- modules/view/backends/platform.red | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 2732ac02cb..91233934d7 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -726,16 +726,10 @@ system/view/platform: context [ drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] ] - ; GTK branch (similar to macOS from now) Linux [ - button: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] - regular: [6x6 4x7] - small: [5x5 4x6] - mini: [1x1 0x1] - group-box: [3x3 0x4] - tab-panel: [7x7 6x10] - drop-down: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] - drop-list: [0x3 2x3 regular 0x3 2x3 small 0x3 1x3 mini 0x2 1x3] + button: [1x1 1x1] + tab-panel: [0x2 0x1] + group-box: [0x0 0x1] ] ]] extend system/view/metrics/paddings [#switch config/OS [ @@ -757,15 +751,14 @@ system/view/platform: context [ group-box: [0x8 4x18] drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] ] - ; GTK backend (similar to macOS from now) Linux [ - button: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] + button: [11x11 0x0] check: [20x0 3x1] radio: [20x0 1x1] text: [3x3 0x0] field: [3x3 0x0] group-box: [0x8 4x18] - drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] + drop-list: [54x54 0x0] ] ]] #switch config/OS [ @@ -795,6 +788,16 @@ system/view/platform: context [ ] ] Linux [ + extend system/view/metrics/def-heights [ + button: 29 + check: 20 + radio: 19 + text: 17 + field: 35 + drop-down: 35 + drop-list: 33 + progress: 14 + ] ] ] @@ -808,9 +811,8 @@ system/view/platform: context [ macOS [ ] - ; GTK Backends Linux [ - + colors/area: white ] ] From f8d2a3629ae7d7e0ab5ee4098ea38669dd1d0e92 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 28 Nov 2019 16:05:21 +0800 Subject: [PATCH 0586/3432] FIX: set cursor not worked for gtk label --- modules/view/backends/gtk3/handlers.reds | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 6bca39359c..0be4938750 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -413,10 +413,15 @@ widget-realize: func [ /local cursor [handle!] win [handle!] + parent [handle!] ][ cursor: GET-CURSOR(widget) unless null? cursor [ win: gtk_widget_get_window widget + if null? win [ + parent: gtk_widget_get_parent widget + win: gtk_widget_get_window parent + ] gdk_window_set_cursor win cursor ] ] From c41dff7f30c7adbb78cf369e32a774892110bf97 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 28 Nov 2019 16:34:47 +0800 Subject: [PATCH 0587/3432] FIX: remove no used files --- environment/console/CLI/console-view.red | 33 - tests/gtk3/align-test.red | 53 -- tests/gtk3/draw.red | 295 -------- tests/gtk3/group-box-test.red | 53 -- tests/gtk3/react-test6-mini.red | 16 - tests/gtk3/react-test6.red | 30 - tests/gtk3/request.red | 12 - tests/gtk3/vid.red | 77 -- tests/gtk3/view-test.red | 904 ----------------------- 9 files changed, 1473 deletions(-) delete mode 100644 environment/console/CLI/console-view.red delete mode 100644 tests/gtk3/align-test.red delete mode 100644 tests/gtk3/draw.red delete mode 100644 tests/gtk3/group-box-test.red delete mode 100644 tests/gtk3/react-test6-mini.red delete mode 100644 tests/gtk3/react-test6.red delete mode 100644 tests/gtk3/request.red delete mode 100644 tests/gtk3/vid.red delete mode 100644 tests/gtk3/view-test.red diff --git a/environment/console/CLI/console-view.red b/environment/console/CLI/console-view.red deleted file mode 100644 index 0b784c4ae9..0000000000 --- a/environment/console/CLI/console-view.red +++ /dev/null @@ -1,33 +0,0 @@ -Red [ - Title: "Red console" - Author: ["Nenad Rakocevic" "Kaj de Vos"] - File: %console-view.red - Tabs: 4 - Needs: 'View - Rights: "Copyright (C) 2012-2018 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -#include %input.red -#include %../help.red -#include %../engine.red - -cli-console-ctx: context [ - settings: #include %settings.red - - launch: does [ - settings/load-cfg - - system/console/init "Red Console" - system/console/launch - ] -] - -_save-cfg: function [][ - cli-console-ctx/settings/save-cfg -] - -cli-console-ctx/launch \ No newline at end of file diff --git a/tests/gtk3/align-test.red b/tests/gtk3/align-test.red deleted file mode 100644 index d9707f2360..0000000000 --- a/tests/gtk3/align-test.red +++ /dev/null @@ -1,53 +0,0 @@ -Red [ - Title: "Para/align testing script" - Author: "WiseGenius" - File: %align-test.red - Needs: 'View -] - -;system/view/debug?: true -txt: {Hello, World!^/I left this right to write it left.^M^/The quick brown fox jumps over the lazy dog.^M^/Χαῖρε, κόσμε!} -sze: 144x89 -view [ - group-box "label" [ - group-box [ - a1: area txt sze - f1: field txt sze - t1: text txt sze - ] - return - group-box "label" [ - text {align: } - r1: radio {none} [];p1/align: none] - r2: radio {left} [];p1/align: 'left] - r3: radio {center} [];p1/align: 'center] - r4: radio {right} [];p1/align: 'right] - return - c1: check {wrap?} [];p1/wrap?: face/data] - ] - ] - return - group-box [ - group-box [ - a2: area txt sze - f2: field txt sze - t2: text txt sze - ] - return - group-box [ - text {align: } - r5: radio {none} [];p2/align: none] - r6: radio {left} [];p2/align: 'left] - r7: radio {center} [];p2/align: 'center] - r8: radio {right} [];p2/align: 'right] - return - c2: check {wrap?} [];p2/wrap?: face/data] - ] - ] - do [ - ;a1/para: f1/para: t1/para: p1: make para! [align: 'right] - ;a2/para: f2/para: t2/para: p2: make para! [] - ;r4/data: on - ;r5/data: on - ] -] \ No newline at end of file diff --git a/tests/gtk3/draw.red b/tests/gtk3/draw.red deleted file mode 100644 index ddfa5284b8..0000000000 --- a/tests/gtk3/draw.red +++ /dev/null @@ -1,295 +0,0 @@ -Red [ - Title: "Tests for draw dialect" - Author: "Fyodor Shchukin" - File: %draw.red - Tabs: 4 -] - -l: layout [ - title "Draw test" - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - line 10x10 40x30 10x30 - line 10x40 40x40 - - font font-label - text 5x45 "line" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - triangle 10x10 40x10 25x40 - - font font-label - text 5x45 "triangle" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - box 10x10 40x20 - box 20x30 30x40 - - font font-label - text 5x45 "box" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - polygon 10x10 40x10 40x40 20x30 - - font font-label - text 5x45 "polygon" - ] - - return - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - circle 25x25 15 - circle 25x25 10 5 - - font font-label - text 5x45 "circle" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - ellipse 10x10 5x10 - ellipse 35x10 5x10 - ellipse 20x20 10x20 - - font font-label - text 5x45 "ellipse" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - ;arc
closed - arc 25x25 15x15 0 180 closed - arc 25x25 5x10 90 270 - - font font-label - text 5x45 "arc" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - curve 10x5 45x5 45x40 - curve 10x10 40x10 10x40 40x40 - - font font-label - text 5x45 "curve" - ] - - return - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - spline 10x10 40x10 40x40 10x40 10x20 30x20 30x30 20x30 - - font font-label - text 5x45 "spline" - ] - - base 50x60 100.70.70 draw [ - line-width 2 - fill-pen 170.20.20.128 - - image fstk-logo 10x10 40x40 - - font font-label - text 5x45 "image" - ] - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "text" - - text 10x10 "Red" - pen red ; test if pen color - font font-A - text 10x20 "Red" - ] - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "pen flat" - - line 10x10 10x40 - box 15x10 20x40 - - pen off - fill-pen 20.20.170.128 - box 25x10 30x40 - - pen 255.255.255.100 - line-width 1 - triangle 35x10 40x40 35x40 - - fill-pen off - triangle 35x10 40x10 40x40 - ] - - return - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "pen gradient" - - pen linear red green blue - line-width 5 - fill-pen off - box 10x10 40x40 - ] - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "fill gradient" - - fill-pen linear red green blue - box 10x10 40x40 - ] - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "line join" - - line-width 5 - - line-join miter - line 10x40 15x20 20x40 - line-join round - line 20x40 25x20 30x40 - line-join bevel - line 30x40 35x20 40x40 - ] - - base 50x60 100.70.70 draw [ - font font-label - text 5x45 "line cap" - - line-width 7 - - line-cap flat - line 15x15 15x35 - line-cap square - line 25x15 25x35 - line-cap round - line 35x15 35x35 - ] - - return - - ; . . . - - base 230x2 0.0.0 - - return - - base 50x60 70.70.100 draw [ - font font-label - text 5x45 "rotate" - - line-width 2 - fill-pen 170.20.20.128 - - box 15x15 35x35 - rotate 45 25x25 - box 15x15 35x35 - ] - - base 50x60 70.70.100 draw [ - font font-label - text 5x45 "scale" - - line-width 2 - fill-pen 170.20.20.128 - - box 10x10 40x40 - scale 0.5 0.5 - box 10x10 40x40 - ] - - base 50x60 70.70.100 draw [ - font font-label - text 5x45 "translate" - - line-width 2 - fill-pen 170.20.20.128 - - box 10x10 30x30 - translate 10x10 - box 10x10 30x30 - ] -] - -font-label: make font! [ - name: "Arial" - size: 11 - color: white - anti-alias?: no -] - -font-A: make font! [ - name: "Times New Roman" - size: 15 - color: red - style: [bold italic underline] - anti-alias?: yes -] - -fstk-logo: load/as 64#{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 - wAAAABJRU5ErkJggg== - } 'png - -view l - diff --git a/tests/gtk3/group-box-test.red b/tests/gtk3/group-box-test.red deleted file mode 100644 index ce9bc6980b..0000000000 --- a/tests/gtk3/group-box-test.red +++ /dev/null @@ -1,53 +0,0 @@ -Red [ - Title: "Para/align testing script" - Author: "WiseGenius" - File: %align-test.red - Needs: 'View -] - -system/view/debug?: true -txt: {Hello, World!^/I left this right to write it left.^M^/The quick brown fox jumps over the lazy dog.^M^/Χαῖρε, κόσμε!} -sze: 144x89 -view [ - panel 300x30 "panel" - panel [ - a1: area txt sze - f1: field txt sze - t1: text txt sze - ] - return - ; group-box [ - ; text {align: } - ; r1: radio {none} [];p1/align: none] - ; r2: radio {left} [];p1/align: 'left] - ; r3: radio {center} [];p1/align: 'center] - ; r4: radio {right} [];p1/align: 'right] - ; return - ; c1: check {wrap?} [];p1/wrap?: face/data] - ; ] - ; ] - ; return - ;group-box [ - group-box [ - a2: area txt sze - f2: field txt sze - t2: text txt sze - ] - ; return - ; group-box [ - ; text {align: } - ; r5: radio {none} [];p2/align: none] - ; r6: radio {left} [];p2/align: 'left] - ; r7: radio {center} [];p2/align: 'center] - ; r8: radio {right} [];p2/align: 'right] - ; return - ; c2: check {wrap?} [];p2/wrap?: face/data] - ; ] - ; ] - do [ - ;a1/para: f1/para: t1/para: p1: make para! [align: 'right] - ;a2/para: f2/para: t2/para: p2: make para! [] - ;r4/data: on - ;r5/data: on - ] -] \ No newline at end of file diff --git a/tests/gtk3/react-test6-mini.red b/tests/gtk3/react-test6-mini.red deleted file mode 100644 index 6458d437e2..0000000000 --- a/tests/gtk3/react-test6-mini.red +++ /dev/null @@ -1,16 +0,0 @@ -Red [ - Title: "Red VID reactive test" - Author: "Nenad Rakocevic" - File: %react-test6.red - Needs: View -] - -system/view/debug?: no - -view [ - text "Font size" s: field "15" 80x10 - button "+" bold 40 - button "-" bold 40 - return -] - diff --git a/tests/gtk3/react-test6.red b/tests/gtk3/react-test6.red deleted file mode 100644 index 5ec24bc7a8..0000000000 --- a/tests/gtk3/react-test6.red +++ /dev/null @@ -1,30 +0,0 @@ -Red [ - Title: "Red VID reactive test" - Author: "Nenad Rakocevic" - File: %react-test6.red - Needs: View -] - -system/view/debug?: no - -view [ - style txt: text right - txt "Text" f: area 200x80 - font [name: "Comic Sans MS" size: 15 color: red] - return - - txt "Size in pixels" text "0x0" - react [[f/text f/font] face/text: form size-text f print ["size: " form size-text f f/text lf]] - return - - txt "Font name" drop-list 120 - data ["Arial" "Consolas" "Comic Sans MS" "Times"] - react [f/font/name: pick face/data any [face/selected 3] print ["changed:" mold face/text]] - return - - txt "Font size" s: field "15" 80x10 react [f/font/size: s/data print ["text " face/text lf]] - button "+" bold 40 [s/data: s/data + 1] - button "-" bold 40 [s/data: max 1 s/data - 1 s/size/x: s/size/x - 1 "s/size: " print s/size/x ] - return -] - diff --git a/tests/gtk3/request.red b/tests/gtk3/request.red deleted file mode 100644 index 9f5bc48e6b..0000000000 --- a/tests/gtk3/request.red +++ /dev/null @@ -1,12 +0,0 @@ -Red [] -a: request-file -print a - -wait 3 -a: none -view [ - button "toto" [a: request-file print a] - button "toti" [a: request-dir print a] -] - -print a \ No newline at end of file diff --git a/tests/gtk3/vid.red b/tests/gtk3/vid.red deleted file mode 100644 index a3c142f62e..0000000000 --- a/tests/gtk3/vid.red +++ /dev/null @@ -1,77 +0,0 @@ -Red [ - Title: "Red VID simple test script" - Author: "Nenad Rakocevic" - File: %vid.red - Needs: 'View -] - -system/view/debug?: no ;yes - -view [ - title "VID test" - ;below - text "Hello" font [name: "Nimbus Sans L" size: 12 color: 112.13.114] - button "Hello" 100x40 [bar/data: random 100%] - button "World" underline italic [opt4/data: yes opt1/data: no] - return - - button "China" - text "Red Language" 100 right bold font [color: red] - field 120 on-enter [probe do face/text clear face/text print "ici"] on-key [print [event/type event/key event/shift? event/ctrl? lf] ] - return - - group-box 3 [ - style but: button 25 font [name: "Comic Sans MS" size: 12 color: blue] - - base 0.233.1.177 "ok" 25x25 - text "in panel" - text "" - - but "A" but "B" but "C" - but "D" but "E" but "F" - ] - tab-panel [ - "tab1" [at 10x10 base 0.2.233.188 15x15 at 50x50 button "one"] - "tab2" [at 80x10 text "two"] - ] on-change [print ["selected: " face/selected face/text lf]] - - below - slider 5% react [bar/data: face/data] - pad 10x0 bar: progress 50% 130 - base 255.0.0.138 50x50 draw [fill-pen blue circle 25x25 15] - across - return middle - - group-box [ - opt1: check "option 1" font-size 14 - check "option 2" font-color orange - radio "option 3" font-name "Times New Roman" - opt4: radio "option 4" - ] - return top - - list: text-list data ["one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four" "one" "two" "three" "four"] [print [pick face/data face/selected lf face/selected face/text lf] ] - drop-list data ["one" 4 "two" 5 "three" 6 "four" 7] - drop-down data ["one" "two" "three" "four"] - - return - - style but1: button - style txt1: text 30 - style base1: base 10x10 - - but1 "1" txt1 "1" base1 "1" - return - group-box [ - style but1: but1 font-color red - style txt1: txt1 red center - style base1: base1 red - - but1 "1" txt1 "1" base1 "1" - ] return - but1 "1" txt1 "1" base1 "1" - - at (list/offset + 130x50) base 5x5 red - - do [append list/data "three" win: self] -] diff --git a/tests/gtk3/view-test.red b/tests/gtk3/view-test.red deleted file mode 100644 index fa732f82f1..0000000000 --- a/tests/gtk3/view-test.red +++ /dev/null @@ -1,904 +0,0 @@ -Red [ - Purpose: "Test the GUI auto-update mode" - Needs: 'View -] - -system/view/debug?: no -live?: system/view/auto-sync?: yes - -workstation?: system/view/platform/product = 1 -os-version: system/view/platform/version -;recycle/off - -#switch config/OS [ - Windows [ - print [ - "Windows" switch os-version [ - 10.0.0 [pick ["10" "10 Server" ] workstation?] - 6.3.0 [pick ["8.1" "Server 2012 R2"] workstation?] - 6.2.0 [pick ["8" "Server 2012" ] workstation?] - 6.1.0 [pick ["7" "Server 2008 R1"] workstation?] - 6.0.0 [pick ["Vista" "Server 2008" ] workstation?] - 5.2.0 [pick ["Server 2003" "Server 2003 R2"] workstation?] - 5.1.0 ["XP"] - 5.0.0 ["2000"] - ] - "build" system/view/platform/build - ] - ] - macOS [ - print [ - "macOS" switch os-version and 255.255.0 [ - 10.11.0 ["El Capitan"] - 10.10.0 ["Yosemite"] - 10.9.0 ["Mavericks"] - 10.8.0 ["Mountain Lion"] - 10.7.0 ["Lion"] - 10.6.0 ["Snow Leopard"] - ] os-version - "build" system/view/platform/build - ] - ] - Linux [0] -] - -smiley: make image! [23x24 #{ -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCC -CCCCCCCCDEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F292908F5C5951 -444238615E496965515C594B4B494258554C8F8E8CDEDEDDF2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2999999312D2788 -8462D0CB8DFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6D0CB8D949068646253918F8C -E7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F6664 -4EE8E39DFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE1 -DC9984805A6B695FE7E7E7F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2E7E7E76B695F -949068F5F0A6FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACA29D6E312D27DEDEDDF2F2F2F2F2F2F2F2F2F2F2F275 -736B8A865EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACB2AE796B695FE7E7E7F2F2F2F2F2 -F2B8B7B65A5743F0ECA3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC84805A8F8E8C -F2F2F2F2F2F249463ECBC78AFEF9ACFEF9ACFEF9AC6E6A4B1714118A865EFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACA7A37217141144412FF0ECA3FEF9ACFEF9ACE5 -E09B5C594BDEDEDDB8B7B6615E49FEF9ACFEF9ACFEF9ACC2BE84171411171411 -171411FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC514D38171411171411999966FEF9 -ACFEF9ACFEF9AC84805AA2A1A07E7C78A29D6EFEF9ACFEF9ACFEF9ACF0ECA325 -211A171411514D38FEF9ACFEF9ACFEF9ACFEF9ACFEF9AC7C795517141125211A -E1DC99FEF9ACFEF9ACFEF9ACC2BE845C59516B695FD0CB8DFEF9ACFEF9ACFEF9 -ACFEF9ACF0ECA3C2BE84FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACD3 -CF8FE1DC99FEF9ACFEF9ACFEF9ACFEF9ACF5F0A6312D27444238F0ECA3FEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC3C393225211AFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC4743 -3A4B4942E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9AC312D27636159CBC78AFEF9ACFEF9ACFEF9AC25211ADCD896FEF9ACFEF9 -ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC333024F0ECA3FE -F9ACFEF9ACE5E09B47433A888685949068FEF9ACFEF9ACFEF9ACBFBA815A5743 -E5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFAF5AA706C4D8480 -5AFEF9ACFEF9ACFEF9ACAFAB7775736BD7D6D63C3932FAF5AAFEF9ACFEF9ACFE -F9AC99996644412FE5E09BFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC949068 -514D38FEF9ACFEF9ACFEF9ACFEF9AC54503EBBBAB9F2F2F2636159A29D6EFEF9 -ACFEF9ACFEF9ACFEF9ACA7A3724C4935928E64DEDA97F0ECA3E8E39DBDB88069 -6648706D4FE5E09BFEF9ACFEF9ACFEF9ACCBC78A3C3932F2F2F2F2F2F2DEDEDD -5A5743DEDA97FEF9ACFEF9ACFEF9ACFEF9ACE5E09B8E8A61615E4356523B5652 -3B696648B7B37DFAF5AAFEF9ACFEF9ACFEF9ACEEE9A166644EB8B7B6F2F2F2F2 -F2F2F2F2F2A6A5A454503EFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC -FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9AC747051817F79F2F2 -F2F2F2F2F2F2F2F2F2F2F2F2F286858154503EDCD896FEF9ACFEF9ACFEF9ACFE -F9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACE8E39D706D4F807E76 -F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2ABAAA9646253A29D6EF0EC -A3FEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACFEF9ACF5F0A6ACA87569655188 -8685F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2CCCCCC -736B6B514D387A7656AFAB77D3CF8FE1DC99D3CF8FB7B37D837F59312D27615E -56CCCCCCF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2 -F2F2F2F2F2F2F2F2E7E7E7A2A1A06361594B4942403C334B4942636159999999 -DEDEDDF2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2} #{ -FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 -0000000000000000FFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000 -00FFFFFFFFFFFFFF0000000000000000000000000000000000FFFFFFFFFF0000 -0000000000000000000000000000000000FFFFFFFF0000000000000000000000 -000000000000000000FFFF000000000000000000000000000000000000000000 -FFFF000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -00000000000000FF000000000000000000000000000000000000000000FFFF00 -0000000000000000000000000000000000000000FFFFFF000000000000000000 -00000000000000000000FFFFFFFFFF0000000000000000000000000000000000 -FFFFFFFFFFFFFF000000000000000000000000000000FFFFFFFFFFFFFFFFFF00 -000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 -00FFFFFFFFFFFFFF -}] - -sub-win: make face! [ - type: 'window text: "Sub 1-View" offset: 200x200 size: 200x100 - pane: reduce [ - make face! [type: 'text text: "New window" offset: 10x10 size: 80x20 color: white] - make face! [ - type: 'button text: "Close" offset: 120x10 size: 60x20 - actors: object [ - on-click: func [face [object!] event [event!]][unview/all] - ] - ] - ] -] - -sub-win2: make face! [ - type: 'window text: "Sub 2-Show" offset: 200x200 size: 200x100 - pane: reduce [ - make face! [type: 'text text: "New window" offset: 10x10 size: 80x20 color: white] - make face! [ - type: 'button text: "Close" offset: 120x10 size: 60x20 - actors: object [ - on-click: func [face [object!] event [event!]][unview] - ] - ] - ] -] - -; ;; requires pane cursor to be moved back in closing event handler - -win: make face! [ - type: 'window text: "Red View" size: 1100x800 - ; menu: [ - ; ;popup ;-- forces context menu for window - ; "File" [ - ; "New" new - ; "Open... F1" open - ; "Close F2" close - ; --- - ; "Save..." save - ; "Save as..." save-as - ; "Save All" save-all - ; --- - ; "Print..." print - ; "Preview" preview - ; "Page Setup..." page-setup - ; --- - ; "Exit" exit - ; ] - ; "Edit" [ - ; "Undo" undo - ; "Redo" redo - ; --- - ; "Copy Ctrl+C" copy - ; "Cut Ctrl+X" cut - ; "Paste Ctrl+V" paste - ; --- - ; "Sub1" [ - ; "Sub-menu1" sub-m1 - ; ] - ; "Sub2" [ - ; "Sub-menu2" sub-m2 - ; ] - ; ] - ; "Search" [ - ; "Find..." find - ; "Find Next" find-next - ; "Find Previous" find-prev - ; --- - ; "Replace..." replace - ; "Replace Next" replace-next - ; ] - ; "Deep" [ - ; "Item 2" item2 - ; "Deep 2" [ - ; "Item 3" item3 - ; "Deep 3" [ - ; "End" end - ; ] - ; ] - ; ] - ; ] - actors: object [ - on-menu: func [face [object!] event [event!]][ - print ["menu selected:" event/picked] - switch event/picked [ - exit [ - print "calling unview" - unview/all - ] - sub-m1 [ - ;just to test change of a button's text.. - win/pane/1/text: "Hello" - show win/pane/1 - ] - ] - ] - on-close: func [face [object!] event [event!]][ - print "closing window" - ] - on-key: func [face [object!] event [event!]][ - if event/key = 'F5 [ - print "F5 key caught by window face!" - 'stop - ] - ] - ] -] - -canvas: make face! [ - type: 'base offset: 0x0 size: 300x200 color: silver - draw: [ - image smiley 10x30 - - line-cap round - pen red - line 10x10 130x190 80x40 150x100 - - pen blue - line-width 4 - line-join round - line 15x190 50x50 190x180 - - pen green - line-join miter - box 10x120 70x160 - - line-width 1 - pen maroon - fill-pen orange - box 150x80 180x120 - - fill-pen off - pen red - triangle 170x10 170x50 195x50 - - pen yellow fill-pen orange - line-width 5 - line-join bevel - polygon 120x130 120x190 180x130 180x190 - - line-width 1 - pen purple - fill-pen purple - box 220x10 280x70 10 - pen gray - fill-pen white - ellipse 240x20 20x40 - - fill-pen red - circle 250x150 49.5 - pen gray - fill-pen white - circle 250x150 40 - fill-pen red - circle 250x150 30 - fill-pen blue - circle 250x150 20 - pen blue - fill-pen white - polygon 232x144 245x144 250x130 255x144 268x144 - 257x153 260x166 250x158 239x166 243x153 - - font font-A - text 40x6 "Scroll Me with mouse wheel :-)" - - arc 100x25 80x80 0 90 closed - pen red - arc 100x25 50x80 30 90 - - curve 20x150 60x250 200x50 - curve 224x14 220x40 280x40 276x66 - ] -] - -but-extra: make face! [ - type: 'button text: "Extra" offset: 400x500 size: 40x25 - actors: object [ - on-click: func [face [object!] event [event!]][ ;-- `function` would prevent compilation here - tab-panel/data: ["file1" "file2"] - tab-panel/pane: reduce [ - make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'text text: "Panel File 1" offset: 90x40 size: 60x30 - ] - ] - ] - make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'text text: "Panel File 2" offset: 80x80 size: 60x30 - ] - ] - ] - ] - drop-down/data: ["1" 1 "2" 2 "3" 3 "4" 4] - unless live? [show [tab-panel drop-down]] - ] - ] -] - -panel-extra: make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'text text: "Panel 4" offset: 20x80 size: 60x30 - ] - ] -] - -button: make face! [ - type: 'button - text: "Hello" - offset: 100x10 - size: 60x40 - actors: object [ - on-click: function [face [object!] event [event!]][ - ;face/color: red - face/size: face/size + (5x5 - random 10x10) - face/offset: face/offset + (5x5 - random 10x10) - win/text: "Hello World" - probe type? reflect win/pane 'owned - - either pos: find win/pane but-extra [ - remove pos - remove skip tail win/menu/4 -2 - ][ - append win/pane but-extra - append win/menu/4 ["Inserted" inserted] - ] - unless live? [show win] - ] - ] -] - -button/font: make font! [ - name: "Comic Sans MS" - size: 16 - style: [bold italic underline strike] - anti-alias?: yes - color: red -] - -font-A: make font! [ - name: "Comic Sans MS" - size: 10 - color: blue - style: [bold italic underline] - anti-alias?: yes -] - -h-modes: [left center right center] -v-modes: [middle top middle bottom] - -win/pane: reduce [ - hi: make face! [ - type: 'button text: "Hi" offset: 10x10 size: 60x40 - para: make para! [align: 'left] - actors: object [ - on-click: func [face [object!] event [event!]][ - print "Testing error handling in awake event: 1 / 0" - probe 1 / 0 - ] - ] - ] - button - make face! [ - type: 'button text: "Change" offset: 180x10 size: 60x40 - actors: object [ - on-click: func [face [object!] event [event!]][ - clear back back tail drop-list/data - check-face/data: not check-face/data - remove at text-list/data 4 - insert at text-list/data 2 random "helloworld" - insert text-list/data/1 #"o" - unless "tab 4" = last tab-panel/data [ - append tab-panel/data "tab 4" - append tab-panel/pane panel-extra - ] - button/size/x: button/size/x - 1 - simple/color/2: random 255 - simple/color/3: random 255 - - if tail? h-modes: next h-modes [h-modes: head h-modes] - hi/para/align: h-modes/1 - - if tail? v-modes: next v-modes [v-modes: head v-modes] - hi/para/v-align: v-modes/1 - - unless live? [ - show [drop-list check-face text-list button simple tab-panel hi] - ] - print [{"Hello" size:} size-text button] - print [{"Base" size:} size-text base-face] - ] - ] - ] - make face! [ - type: 'check text: "Debug?" offset: 300x270 size: 80x24 - font: font-A - data: system/view/debug? - actors: object [ - on-change: func [face [object!] event [event!]][ - system/view/debug?: face/data - ] - ] - ] - make face! [ - type: 'check text: "Big/small font" offset: 300x300 size: 80x24 - data: yes - para: make para! [wrap?: yes] - actors: object [ - on-change: func [face [object!] event [event!]][ - button/font/size: pick [12 20] face/data - unless live? [show button] - ] - ] - ] - make face! [ - type: 'check text: "Italic?" offset: 300x330 size: 80x24 - data: yes - actors: object [ - on-change: function [face [object!] event [event!]][ - alter button/font/style 'italic - unless live? [show button] - ] - ] - ] - edit: make face! [ - type: 'field text: {unicode supported: $€𐐷𤭢} offset: 10x80 size: 160x24 - color: 255.218.18 - para: make para! [align: 'left] - actors: object [ - on-change: func [face [object!] event [event!]][ - print ["field changed:" mold face/text] - ] - ] - ] - make face! [ - type: 'area text: {Multiline area widget} offset: 580x24 size: 160x100 - font: font-A - actors: object [ - on-change: func [face [object!] event [event!]][ - print ["field changed:" mold face/text] - ] - ] - ] - simple: make face! [type: 'base offset: 200x50 size: 80x24 visible?: no color: red] - make face! [ - type: 'button text: "Show/Hide" offset: 200x80 size: 70x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - simple/visible?: not simple/visible? - unless live? [show simple] - ] - ] - ] - drop-down: make face! [ - type: 'drop-down - text: "type" - offset: 100x120 - size: 80x24 - font: font-A - color: 240.230.140 - data: [ - "option 1" 11 - "option 2" 22 - "option 3" 33 - ] - actors: object [ - on-select: func [face [object!] event [event!]][ - probe face/text - ] - on-change: func [face [object!] event [event!]][ - print ["changed:" mold face/text] - ] - ] - ] - drop-list: make face! [ - type: 'drop-list - offset: 200x120 - size: 80x24 - data: [ - "option 10" 110 - "option 20" 220 - "option 30" 330 - "option 40" 440 - "option 50" 550 - ] - actors: object [ - on-create: func [face [object!]][ - face/selected: 2 - ] - on-select: func [face [object!] event [event!]][ - print ["selected:" face/selected] - ] - on-change: func [face [object!] event [event!]][ - print ["changed:" face/selected] - ] - ] - ] - make face! [ - type: 'button text: "Set option 5" offset: 300x120 size: 80x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - drop-list/selected: 5 - unless live? [show drop-list] - ] - ] - ] - group: make face! [ - type: 'group-box text: "Group box" offset: 10x150 size: 180x150 - pane: reduce [ - make face! [type: 'button text: "Inside" offset: 20x20 size: 60x40] - set 'progress make face! [ - type: 'progress offset: 10x80 size: 120x16 - menu: [ - "Set to 0%" s0 - "Set to 25%" s25 - "Set to 50%" s50 - "Set to 100%" s100 - ] - actors: object [ - on-menu: func [face [object!] event [event!]][ - print ["context menu selected:" event/picked] - face/data: load append next form event/picked #"%" - unless live? [show face] - ] - ] - ] - set 'progress-text make face! [ - type: 'text text: "0" offset: 140x80 size: 30x16 color: white - ] - make face! [ - type: 'slider offset: 10x110 size: 120x24 - data: 50% - actors: object [ - on-create: func [face [object!]][ - on-change face none - ] - on-change: func [face [object!] event [event! none!]][ - ;print ["slider changed:" face/data] - progress/data: face/data - progress-text/text: form round to-percent face/data - unless live? [show [progress progress-text]] - ] - ] - ] - ] - ] - set 'progress2 make face! [ - type: 'progress offset: 200x170 size: 16x120 - ] - make face! [ - type: 'slider offset: 230x170 size: 24x120 - data: 25% - actors: object [ - on-create: func [face [object!]][ - on-change face none - ] - on-change: func [face [object!] event [event! none!]][ - print ["slider changed:" face/data] - progress2/data: face/data - unless live? [show progress2] - ] - ] - ] - - check-face: make face! [ - type: 'check text: "check box" offset: 300x170 size: 90x24 - data: on - actors: object [ - on-change: func [face [object!] event [event!]][ - probe face/data - ] - ] - ] - make face! [ - type: 'radio text: "radio 1" offset: 300x200 size: 90x24 - font: font-A - options: [drag-on: 'down] - ;data: on - actors: object [ - on-change: func [face [object!] event [event!]][ - print "radio 1 set" - ] - ] - ] - make face! [ - type: 'radio text: "radio 2" offset: 300x230 size: 90x24 - data: on - actors: object [ - on-change: func [face [object!] event [event!]][ - print "radio 2 set" - ] - ] - ] - make face! [ - type: 'base offset: 280x10 size: 100x100 - options: [drag-on: 'down] - image: load %../../bridges/android/samples/eval/res/drawable-xxhdpi/ic_launcher.png - ] - tab-panel: make face! [ - type: 'tab-panel offset: 10x320 size: 250x130 - data: [ - "tab 1" - "tab 2" - "tab 3" - ] - pane: reduce [ - make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'button text: "Panel 1" offset: 20x20 size: 60x30 - ] - ] - menu: [ - "Context menu 1" menu1 - "Context menu 2" menu2 - "Context menu 3" [ - "sub 1" sub1 - "sub 2" sub2 - ] - ] - actors: object [ - on-menu: func [face [object!] event [event!]][ - print ["context menu selected:" event/picked] - ] - ] - ] - make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'text text: "Panel 2" offset: 80x80 size: 60x30 - ] - ] - ] - make face! [ - type: 'panel - pane: reduce [ - make face! [ - type: 'text text: "Panel 3" offset: 90x40 size: 60x30 - ] - ] - ] - ] - actors: object [ - on-change: func [face [object!] event [event!]][ - print ["Switched to:" pick face/data event/picked] - ] - ] - ] - text-list: make face! [ - type: 'text-list offset: 400x20 size: 165x100 - font: font-A - data: [ - "Book 1" - "Book 2" - "Book 3" - "Book 4" - "Book 5" - "Red Programming Language" - "Red编程语言" - "FullStack Programming Language" - "全栈编程语言" - "hahahaha~" - "哈哈哈哈~" - ] - actors: object [ - on-select: func [face [object!] event [event!]][ - print ["text-list selected:" face/selected] - face/text: pick face/data face/selected - print ["text-list selected:" mold face/text] - ] - on-change: func [face [object!] event [event!]][ - print ["text-list changed:" face/selected] - face/text: pick face/data face/selected - print ["text-list changed:" mold face/text] - ] - ] - ] - ; set 'cam make face! [ - ; type: 'camera offset: 400x140 size: 320x240 - ; ] - cam-list: make face! [ - type: 'drop-list offset: 480x402 size: 160x32 - actors: object [ - on-create: func [face [object!]][ - ;face/data: cam/data - ] - on-change: func [face [object!] event [event!]][ - print ["changed:" face/selected] - ;unless cam/selected = face/selected [ - ; cam/selected: face/selected - ;] - ;unless live? [show cam] - ] - ] - ] - make face! [ - type: 'button text: "Start/Stop" offset: 400x400 size: 70x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - ; either cam/selected [ - ; cam/selected: none - ; ][ - ; cam/selected: cam-list/selected - ; ] - ; unless live? [show cam] - ] - ] - ] - make face! [ - type: 'button text: "Sub-window" offset: 400x440 size: 70x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - view sub-win - ] - ] - ] - make face! [ - type: 'button text: "Sub-window 2" offset: 400x470 size: 70x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - show sub-win2 - ] - ] - ] - make face! [ - type: 'button text: "Quit" offset: 500x440 size: 60x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - print "calling unview" - unview/all - ] - ] - ] - make face! [ - type: 'button offset: 570x440 size: 38x38 - image: smiley - ] - make face! [ ;-- clip view for canvas - type: 'panel offset: 10x460 size: 300x200 - pane: reduce [canvas] - actors: object [ - on-wheel: func [face [object!] event [event!]][ - print [face/type event/picked] - canvas/offset/y: canvas/offset/y + event/picked - unless live? [show canvas] - ] - ] - ] - make face! [ - type: 'check text: "anti alias" offset: 265x430 size: 90x24 - data: on - actors: object [ - on-change: func [face [object!] event [event!]][ - either face/data = off [ - insert canvas/draw [anti-alias off] - ][ - remove/part canvas/draw 2 - ] - unless live? [show canvas] - ] - ] - ] - font-test: make face! [ - type: 'text text: "The quick brown fox jumps." offset: 500x500 size: 300x25 - font: make font! [ - name: "Times New Roman" - size: 16 - style: 'italic - anti-alias?: yes - ] - actors: object [ - on-over: func [face [object!] event [event!]][ - face/font/style: pick [italic bold] event/away? - tab-panel/selected: pick [1 2] event/away? - unless live? [show [face tab-panel]] - ] - ] - ] - dropped: make face! [ - type: 'base text: "Drop here" offset: 630x540 size: 80x80 - color: silver - draw: [font font-A text 35x30 "0"] - para: make para! [v-align: 'top] - ] - base-face: make face! [ - type: 'base text: "Base face" offset: 630x630 size: 80x80 - color: beige - font: make font! [ - name: "Times New Roman" - size: 16 - style: 'italic - anti-alias?: yes - ] - ] - make face! [ - type: 'button text: "Drag me" offset: 550x540 size: 70x24 - options: [drag-on: 'down] - actors: object [ - on-drag-start: func [face [object!] event [event!]][ - print "drag starts" - ;face/state/4: face/state/4 + 4x4 - ;face/offset: face/offset - 4x4 - ;unless live? [show face] - ] - on-drag: func [face [object!] event [event!]][ - prin dot - ] - on-drop: function [face [object!] event [event!]][ - print "dropping" - ;face/offset: face/offset + 4x4 - - pos: face/offset + face/state/4 ;-- calculate mouse position - if within? pos dropped/offset dropped/size [ - face/offset: 550x540 - dropped/draw/5: form 1 + to integer! dropped/draw/5 - unless live? [show [face dropped]] - ] - ] - ] - ] - make face! [ - type: 'base offset: 750x140 size: 300x300 color: silver - text: "Pinch me" - draw: [fill-pen red polygon 100x100 250x100 250x250 100x250] - actors: object [ - angle: 0 - center: 175x175 - sz: 75 - - on-zoom: func [face [object!] event [event!] /local factor new][ - if factor: event/picked [ - new: to integer! sz * factor - if new > 10 [ - sz: new - draw/4: center - as-pair sz sz - draw/5: center + (1x-1 * sz) - draw/6: center + as-pair sz sz - draw/7: center + (-1x1 * sz) - unless live? [show face] - ] - ] - ] - on-rotate: func [face [object!] event [event!]][ - probe "rotating" - ] - ] - ] -] - -append win/pane panel: make face! [ - type: 'panel - offset: 400x550 - size: 80x80 - pane: make block! 3 -] -repeat i 3 [ - append panel/pane make face! [ - type: 'base - size: 40x40 - offset: 10x10 * i - text: form i - color: red + (i * 50) - ] -] - -append win/pane make face! [ - type: 'button - text: "Reverse" - offset: 400x640 - size: 60x24 - actors: object [ - on-click: func [face [object!] event [event!]][ - reverse panel/pane - unless live? [show panel] - ] - ] -] - -dump-face win -view/flags win [resize] \ No newline at end of file From 8eb630b3b1e7f6fe11f795e8aa65507ca6409c3f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 28 Nov 2019 17:11:27 +0800 Subject: [PATCH 0588/3432] FIX: change-font not work when font color changed --- modules/view/backends/gtk3/gui.reds | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 20538cd242..844cd0ce59 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -874,7 +874,12 @@ change-font: func [ widget [handle!] face [red-object!] values [red-value!] + /local + font [red-object!] ][ + font: as red-object! values + FACE_OBJ_FONT + free-font font + make-font face font set-font widget face values ] From 627c1e2035a9c103e517ac0fac08b557bdc7902b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 29 Nov 2019 10:13:58 +0800 Subject: [PATCH 0589/3432] FIX: load image issues --- runtime/platform/image-gdk.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 5211983d9d..9adde58fec 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -630,6 +630,7 @@ OS-image: context [ path: file/to-OS-path src ; DOES NOT WORK as in macOS: simple-io/to-NSURL src yes ;; DEBUG: print [ "load-image: " path lf] pixbuf: gdk_pixbuf_new_from_file path null + if null? pixbuf [return null] w: gdk_pixbuf_get_width pixbuf h: gdk_pixbuf_get_height pixbuf ;; DEBUG: print ["pixbuf: " pixbuf ", wxh: " w "x" h lf] ;buf: gdk_pixbuf_get_pixels pixbuf From 2573c4568c863c4ad227642927df04621b6729ad Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 29 Nov 2019 19:30:52 +0800 Subject: [PATCH 0590/3432] FIX: resize image with negative width or height bug --- modules/view/backends/gtk3/draw.reds | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 0139da9801..6dd05a697a 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1027,15 +1027,32 @@ GDK-draw-image: func [ height [integer!] /local img [handle!] + absw [integer!] + absh [integer!] ][ - ;; DEBUG: print ["GDK-draw-image " width " handle " image lf] - img: either width = 0 [image][gdk_pixbuf_scale_simple image width height 2] - ;; DEBUG: print ["GDK-draw-image: " x "x" y "x" width "x" height lf] + if any [ + width = 0 + height = 0 + ][exit] + + absw: width + if width < 0 [absw: 0 - width] + absh: height + if height < 0 [absh: 0 - height] + img: gdk_pixbuf_scale_simple image absw absh 2 + + cairo_save cr cairo_translate cr as-float x as-float y + if width < 0 [ + cairo_scale cr -1.0 1.0 + ] + if height < 0 [ + cairo_scale cr 1.0 -1.0 + ] gdk_cairo_set_source_pixbuf cr img 0.0 0.0 cairo_paint cr - cairo_translate cr as-float (0 - x) as-float (0 - y) - if width > 0 [g_object_unref img] + cairo_restore cr + g_object_unref img ] OS-draw-image: func [ From 5478fe9b0c4b45abeb583f2132227b086cd7a6a8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 29 Nov 2019 19:48:40 +0800 Subject: [PATCH 0591/3432] FIX: remove ok-cancel button rule for gtk3 --- modules/view/VID.red | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index 00443ebb49..6de0d51a30 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -39,7 +39,6 @@ system/view/VID: context [ Cancel-OK ] Linux [ - Cancel-OK ] ] user: [] From 820ac1ebb2d1af5bccfec381e29f7e64b99915fe Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 1 Dec 2019 18:25:02 +0100 Subject: [PATCH 0592/3432] FEAT: initial Direct2D backend --- build/includes.r | 2 +- modules/view/backends/macOS/text-box.reds | 2 +- modules/view/backends/windows/draw-d2d.reds | 262 -- modules/view/backends/windows/draw-gdi.reds | 3560 +++++++++++++++++++ modules/view/backends/windows/draw.reds | 3410 ++---------------- modules/view/backends/windows/gui.reds | 7 +- modules/view/backends/windows/text-box.reds | 2 +- modules/view/backends/windows/win32.reds | 30 + modules/view/draw.red | 8 - 9 files changed, 3812 insertions(+), 3471 deletions(-) delete mode 100644 modules/view/backends/windows/draw-d2d.reds create mode 100644 modules/view/backends/windows/draw-gdi.reds diff --git a/build/includes.r b/build/includes.r index 20d72188f7..feb000b9c1 100644 --- a/build/includes.r +++ b/build/includes.r @@ -189,7 +189,7 @@ write %build/bin/sources.r set-cache [ %classes.reds %comdlgs.reds %direct2d.reds - %draw-d2d.reds + %draw-gdi.reds %draw.reds %events.reds %font.reds diff --git a/modules/view/backends/macOS/text-box.reds b/modules/view/backends/macOS/text-box.reds index a6bfed460a..f89a587d40 100644 --- a/modules/view/backends/macOS/text-box.reds +++ b/modules/view/backends/macOS/text-box.reds @@ -3,7 +3,7 @@ Red/System [ Author: "Xie Qingtian" File: %text-box.reds Tabs: 4 - Dependency: %draw-d2d.reds + Dependency: %draw.reds Rights: "Copyright (C) 2016 Xie Qingtian. All rights reserved." License: { Distributed under the Boost Software License, Version 1.0. diff --git a/modules/view/backends/windows/draw-d2d.reds b/modules/view/backends/windows/draw-d2d.reds deleted file mode 100644 index f1bd3c27b5..0000000000 --- a/modules/view/backends/windows/draw-d2d.reds +++ /dev/null @@ -1,262 +0,0 @@ -Red/System [ - Title: "DRAW Direct2D Backend" - Author: "Xie Qingtian" - File: %draw-d2d.reds - Tabs: 4 - Rights: "Copyright (C) 2016-2018 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -#include %text-box.reds - -draw-begin-d2d: func [ - ctx [draw-ctx!] - hWnd [handle!] - /local - this [this!] - rt [ID2D1HwndRenderTarget] - _11 [integer!] - _12 [integer!] - _21 [integer!] - _22 [integer!] - _31 [integer!] - _32 [integer!] - m [D2D_MATRIX_3X2_F] - bg-clr [integer!] - brush [integer!] - target [int-ptr!] - brushes [int-ptr!] - pbrush [ID2D1SolidColorBrush] - d3d-clr [D3DCOLORVALUE] - values [red-value!] - clr [red-tuple!] - text [red-string!] - pos [red-pair! value] -][ - target: get-hwnd-render-target hWnd - - this: as this! target/value - ctx/dc: as handle! this - ctx/brushes: target - - rt: as ID2D1HwndRenderTarget this/vtbl - rt/SetTextAntialiasMode this 1 ;-- ClearType - - rt/BeginDraw this - _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 - m: as D2D_MATRIX_3X2_F :_32 - m/_11: as float32! 1.0 - m/_22: as float32! 1.0 - rt/SetTransform this m ;-- set to identity matrix - - values: get-face-values hWnd - clr: as red-tuple! values + FACE_OBJ_COLOR - bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1] - if bg-clr <> -1 [ ;-- paint background - rt/Clear this to-dx-color bg-clr null - ] - - d3d-clr: to-dx-color ctx/pen-color null - brush: 0 - rt/CreateSolidColorBrush this d3d-clr null :brush - ctx/pen: brush - - brush: 0 - rt/CreateSolidColorBrush this d3d-clr null :brush - ctx/brush: brush - - text: as red-string! values + FACE_OBJ_TEXT - if TYPE_OF(text) = TYPE_STRING [ - pos/x: 0 pos/y: 0 - OS-draw-text-d2d ctx pos as red-string! get-face-obj hWnd yes - ] -] - -clean-draw-d2d: func [ - ctx [draw-ctx!] - /local - IUnk [IUnknown] - this [this!] -][ - COM_SAFE_RELEASE_OBJ(IUnk ctx/pen) - COM_SAFE_RELEASE_OBJ(IUnk ctx/brush) -] - -draw-end-d2d: func [ - ctx [draw-ctx!] - hWnd [handle!] - /local - this [this!] - rt [ID2D1HwndRenderTarget] - hr [integer!] -][ - this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - hr: rt/EndDraw this null null - - clean-draw-d2d ctx - - switch hr [ - COM_S_OK [ValidateRect hWnd null] - D2DERR_RECREATE_TARGET [ - d2d-release-target ctx/brushes - ctx/dc: null - SetWindowLong hWnd wc-offset - 24 0 - InvalidateRect hWnd null 0 - ] - default [ - 0 ;@@ TBD log error!!! - ] - ] -] - -OS-draw-pen-d2d: func [ - ctx [draw-ctx!] - color [integer!] - off? [logic!] - /local - this [this!] - brush [ID2D1SolidColorBrush] -][ - if any [ctx/pen-color <> color ctx/pen? = off?][ - ctx/pen?: not off? - ctx/pen-color: color - if ctx/pen? [ - this: as this! ctx/pen - brush: as ID2D1SolidColorBrush this/vtbl - brush/SetColor this to-dx-color color null - ] - ] -] - -OS-draw-line-width-d2d: func [ - ctx [draw-ctx!] - width [red-value!] - /local - width-v [float32!] -][ - width-v: (get-float32 as red-integer! width) - if ctx/pen-width <> width-v [ - ctx/pen-width: width-v - ] -] - -OS-draw-line-d2d: func [ - ctx [draw-ctx!] - point [red-pair!] - end [red-pair!] - /local - pt0 [red-pair!] - pt1 [red-pair!] - this [this!] - rt [ID2D1HwndRenderTarget] -][ - this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - pt0: point - - while [pt1: pt0 + 1 pt1 <= end][ - rt/DrawLine - this - as float32! pt0/x as float32! pt0/y - as float32! pt1/x as float32! pt1/y - ctx/pen - ctx/pen-width - 0 - pt0: pt0 + 1 - ] -] - -OS-draw-fill-pen-d2d: func [ - ctx [draw-ctx!] - color [integer!] - off? [logic!] - /local - this [this!] - brush [ID2D1SolidColorBrush] -][ - if any [ctx/brush-color <> color ctx/brush? = off?][ - ctx/brush?: not off? - ctx/brush-color: color - if ctx/brush? [ - this: as this! ctx/brush - brush: as ID2D1SolidColorBrush this/vtbl - brush/SetColor this to-dx-color color null - ] - ] -] - -OS-draw-circle-d2d: func [ - ctx [draw-ctx!] - center [red-pair!] - radius [red-integer!] - /local - this [this!] - rt [ID2D1HwndRenderTarget] - ellipse [D2D1_ELLIPSE value] -][ - this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - - ellipse/x: as float32! center/x - ellipse/y: as float32! center/y - ellipse/radiusX: get-float32 radius - ellipse/radiusY: ellipse/radiusX - if ctx/brush? [ - rt/FillEllipse this ellipse ctx/brush - ] - if ctx/pen? [ - rt/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style - ] -] - -OS-draw-box-d2d: func [ - ctx [draw-ctx!] - upper [red-pair!] - lower [red-pair!] - /local - this [this!] - rt [ID2D1HwndRenderTarget] - rc [D2D_RECT_F value] -][ - this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - - rc/right: as float32! lower/x - rc/bottom: as float32! lower/y - rc/left: as float32! upper/x - rc/top: as float32! upper/y - if ctx/brush? [ - rt/FillRectangle this rc ctx/brush - ] - if ctx/pen? [ - rt/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style - ] -] - -OS-draw-text-d2d: func [ - ctx [draw-ctx!] - pos [red-pair!] - text [red-string!] - catch? [logic!] - /local - this [this!] - rt [ID2D1HwndRenderTarget] - layout [this!] - fmt [this!] -][ - this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - - layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! - OS-text-box-layout as red-object! text ctx/brushes 0 yes - ][ - fmt: as this! create-text-format as red-object! text null - create-text-layout text fmt 0 0 - ] - txt-box-draw-background ctx/brushes pos layout - rt/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 -] \ No newline at end of file diff --git a/modules/view/backends/windows/draw-gdi.reds b/modules/view/backends/windows/draw-gdi.reds new file mode 100644 index 0000000000..e351c1a6ab --- /dev/null +++ b/modules/view/backends/windows/draw-gdi.reds @@ -0,0 +1,3560 @@ +Red/System [ + Title: "Windows Draw dialect backend" + Author: "Nenad Rakocevic" + File: %draw.reds + Tabs: 4 + Rights: "Copyright (C) 2015-2018 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +xform: declare XFORM! + +#define SHAPE_OTHER 0 +#define SHAPE_CURVE 1 +#define SHAPE_QCURVE 2 + +#define GRADIENT_NONE 0 +#define GRADIENT_LINEAR 1 +#define GRADIENT_RADIAL 2 +#define GRADIENT_DIAMOND 3 + +#define INVALID_RADIUS -1 +#define INDEX_UPPER 0 +#define INDEX_LOWER 1 +#define INDEX_OTHER 2 + +#define INIT_GRADIENT_DATA(upper lower other) [ + upper: gradient/data + INDEX_UPPER + lower: gradient/data + INDEX_LOWER + other: gradient/data + INDEX_OTHER +] + +#define MAX_GRADIENT_DATA 5 +#define MAX_EDGES 1000 ;-- max number of edges for a polygone +#define MAX_COLORS 256 ;-- max number of colors for gradient + +#define ALLOC_REENTRANT(type) [ + as type allocate size? type +] +#define ALLOC_REENTRANT_ELEMS(type1 type2 count) [ + as type1 allocate count * (size? type2) +] +#define ALLOC_REENTRANT_BYTES(count) [ + allocate count +] +#define FREE_REENTRANT(word) [ + free as byte-ptr! word +] +#define FREE_REENTRANT_BYTES(word) [ + free word +] + +draw-state!: alias struct! [ + gstate [integer!] + pen-clr [integer!] + brush-clr [integer!] + pen-join [integer!] + pen-cap [integer!] + pen? [logic!] + brush? [logic!] + a-pen? [logic!] + a-brush? [logic!] +] + +alloc-context: func [ + ctx [draw-ctx!] + /local + max-colors [integer!] +][ + max-colors: 2 * MAX_COLORS + ctx/other: ALLOC_REENTRANT(other!) + ctx/other/gradient-pen: ALLOC_REENTRANT(gradient!) + ctx/other/gradient-pen/path-data: ALLOC_REENTRANT(PATHDATA) + ctx/other/gradient-pen/data: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_GRADIENT_DATA) + ctx/other/gradient-pen/colors: ALLOC_REENTRANT_ELEMS(int-ptr! integer! max-colors) + ctx/other/gradient-pen/colors-pos: as float32-ptr! ctx/other/gradient-pen/colors + MAX_COLORS + ctx/other/gradient-fill: ALLOC_REENTRANT(gradient!) + ctx/other/gradient-fill/path-data: ALLOC_REENTRANT(PATHDATA) + ctx/other/gradient-fill/data: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_GRADIENT_DATA) + ctx/other/gradient-fill/colors: ALLOC_REENTRANT_ELEMS(int-ptr! integer! max-colors) + ctx/other/gradient-fill/colors-pos: as float32-ptr! ctx/other/gradient-fill/colors + MAX_COLORS + ctx/other/matrix-elems: ALLOC_REENTRANT_ELEMS(float32-ptr! float32! 6) + ctx/other/paint: ALLOC_REENTRANT(tagPAINTSTRUCT) + ctx/other/edges: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_EDGES) + ctx/other/types: ALLOC_REENTRANT_BYTES(MAX_EDGES) + ctx/other/path-last-point: ALLOC_REENTRANT(tagPOINT) + ctx/other/prev-shape: ALLOC_REENTRANT(curve-info!) + ctx/other/prev-shape/control: ALLOC_REENTRANT(tagPOINT) + ctx/other/pattern-image-fill: ALLOC_REENTRANT_ELEMS(integer! red-image! 1) + ctx/other/pattern-image-pen: ALLOC_REENTRANT_ELEMS(integer! red-image! 1) +] + +free-context: func [ + ctx [draw-ctx!] +][ + FREE_REENTRANT(ctx/other/pattern-image-pen) + FREE_REENTRANT(ctx/other/pattern-image-fill) + FREE_REENTRANT(ctx/other/prev-shape/control) + FREE_REENTRANT(ctx/other/prev-shape) + FREE_REENTRANT(ctx/other/path-last-point) + FREE_REENTRANT_BYTES(ctx/other/types) + FREE_REENTRANT(ctx/other/edges) + FREE_REENTRANT(ctx/other/paint) + FREE_REENTRANT(ctx/other/matrix-elems) + FREE_REENTRANT(ctx/other/gradient-fill/colors) + FREE_REENTRANT(ctx/other/gradient-fill/data) + FREE_REENTRANT(ctx/other/gradient-fill/path-data) + FREE_REENTRANT(ctx/other/gradient-fill) + FREE_REENTRANT(ctx/other/gradient-pen/colors) + FREE_REENTRANT(ctx/other/gradient-pen/data) + FREE_REENTRANT(ctx/other/gradient-pen/path-data) + FREE_REENTRANT(ctx/other/gradient-pen) + FREE_REENTRANT(ctx/other) +] + +clip-replace: func [ ctx [draw-ctx!] return: [integer!] ][ + either ctx/other/GDI+? [GDIPLUS_COMBINEMODEREPLACE][RGN_COPY] +] +clip-intersect: func [ ctx [draw-ctx!] return: [integer!] ][ + either ctx/other/GDI+? [GDIPLUS_COMBINEMODEINTERSECT][RGN_AND] +] +clip-union: func [ ctx [draw-ctx!] return: [integer!] ][ + either ctx/other/GDI+? [GDIPLUS_COMBINEMODEUNION][RGN_OR] +] +clip-xor: func [ ctx [draw-ctx!] return: [integer!] ][ + either ctx/other/GDI+? [GDIPLUS_COMBINEMODEXOR][RGN_XOR] +] +clip-diff: func [ ctx [draw-ctx!] return: [integer!] ][ + either ctx/other/GDI+? [GDIPLUS_COMBINEMODEEXCLUDE][RGN_DIFF] +] + +update-gdiplus-font-color: func [ctx [draw-ctx!] color [integer!] /local brush [integer!]][ + if ctx/font-color <> color [ + unless zero? ctx/gp-font-brush [ + GdipDeleteBrush ctx/gp-font-brush + ctx/gp-font-brush: 0 + ] + ctx/font-color: color + brush: 0 + GdipCreateSolidFill to-gdiplus-color-fixed color :brush + ctx/gp-font-brush: brush + ] +] + +update-gdiplus-font: func [ctx [draw-ctx!] /local font [integer!]][ + font: 0 + unless zero? ctx/gp-font [GdipDeleteFont ctx/gp-font] + GdipCreateFontFromDC as-integer ctx/dc :font + ctx/gp-font: font +] + +update-gdiplus-modes: func [ctx [draw-ctx!] ][ + update-gdiplus-pen ctx + update-gdiplus-brush ctx +] + +update-gdiplus-brush: func [ctx [draw-ctx!] /local handle [integer!]][ + handle: 0 + ctx/gp-brush-type: BRUSH_TYPE_NORMAL + ctx/other/gradient-fill?: false + unless zero? ctx/gp-brush [ + GdipDeleteBrush ctx/gp-brush + ctx/gp-brush: 0 + ] + if ctx/brush? [ + GdipCreateSolidFill to-gdiplus-color-fixed ctx/brush-color :handle + ctx/gp-brush: handle + ] +] + +update-gdiplus-pen: func [ctx [draw-ctx!] /local handle [integer!]][ + ctx/gp-pen-type: BRUSH_TYPE_NORMAL + ctx/other/gradient-pen?: false + either ctx/pen? [ + if ctx/gp-pen-saved <> 0 [ + ctx/gp-pen: ctx/gp-pen-saved + ctx/gp-pen-saved: 0 + ] + handle: ctx/gp-pen + GdipSetPenColor handle to-gdiplus-color ctx/pen-color + GdipSetPenWidth handle ctx/pen-width + if ctx/pen-join <> 0 [ + OS-draw-line-join ctx ctx/pen-join + ] + if ctx/pen-cap <> 0 [ + OS-draw-line-cap ctx ctx/pen-cap + ] + ][ + ctx/gp-pen-saved: ctx/gp-pen + ctx/gp-pen: 0 + ] +] + +update-brush: func [ctx [draw-ctx!] /local handle [handle!]][ + if 0 <> ctx/brush [DeleteObject as handle! ctx/brush] + handle: either ctx/brush? [ + CreateSolidBrush ctx/brush-color + ][ + GetStockObject NULL_BRUSH + ] + ctx/brush: as-integer handle + SelectObject ctx/dc handle +] + +update-pen: func [ + ctx [draw-ctx!] + /local + mode [integer!] + cap [integer!] + join [integer!] + pen [handle!] + brush [tagLOGBRUSH] +][ + mode: 0 + if 0 <> ctx/pen [DeleteObject as handle! ctx/pen] + either ctx/pen? [ + cap: ctx/pen-cap + join: ctx/pen-join + pen: either all [join = -1 cap = -1] [ + CreatePen ctx/pen-style as integer! ctx/pen-width ctx/pen-color + ][ + if join <> -1 [ + mode: case [ + join = miter [PS_JOIN_MITER] + join = miter-bevel [PS_JOIN_MITER] + join = _round [PS_JOIN_ROUND] + join = bevel [PS_JOIN_BEVEL] + true [PS_JOIN_MITER] + ] + ] + if cap <> -1 [ + mode: mode or case [ + cap = flat [PS_ENDCAP_FLAT] + cap = square [PS_ENDCAP_SQUARE] + cap = _round [PS_ENDCAP_ROUND] + true [PS_ENDCAP_FLAT] + ] + ] + brush: declare tagLOGBRUSH + brush/lbStyle: BS_SOLID + brush/lbColor: ctx/pen-color + ExtCreatePen + PS_GEOMETRIC or ctx/pen-style or mode + as integer! ctx/pen-width + brush + 0 + null + ] + ctx/pen: as-integer pen + ][ + pen: GetStockObject NULL_PEN + ctx/pen: 0 + ] + SelectObject ctx/dc pen +] + +update-modes: func [ + ctx [draw-ctx!] +][ + either ctx/other/GDI+? [ + update-gdiplus-modes ctx + ][ + update-pen ctx + update-brush ctx + ] +] + +draw-begin: func [ + ctx [draw-ctx!] + hWnd [handle!] + img [red-image!] + on-graphic? [logic!] + paint? [logic!] + return: [draw-ctx!] + /local + dc [handle!] + rect [RECT_STRUCT value] + width [integer!] + height [integer!] + hBitmap [handle!] + hBackDC [handle!] + graphics [integer!] + ptrn [red-image!] + ratio [float32!] +][ + zero-memory as byte-ptr! ctx size? draw-ctx! + alloc-context ctx + + ctx/pen-width: as float32! 1.0 + ctx/pen?: yes + ctx/hwnd: hWnd + ctx/font-color: -1 + ctx/gp-brush-type: BRUSH_TYPE_NORMAL + ctx/gp-pen-type: BRUSH_TYPE_NORMAL + dc: null + + ctx/other/gradient-pen/extra: 0 + ctx/other/gradient-pen/matrix: 0 + ctx/other/gradient-pen/spread: WRAP_MODE_TILE + ctx/other/gradient-pen/type: GRADIENT_NONE + ctx/other/gradient-pen/count: 0 + ctx/other/gradient-pen/positions?: false + ctx/other/gradient-pen/created?: false + ctx/other/gradient-pen/transformed?: false + ctx/other/gradient-fill/extra: 0 + ctx/other/gradient-fill/matrix: 0 + ctx/other/gradient-fill/spread: WRAP_MODE_TILE + ctx/other/gradient-fill/type: GRADIENT_NONE + ctx/other/gradient-fill/count: 0 + ctx/other/gradient-fill/positions?: false + ctx/other/gradient-fill/created?: false + ctx/other/gradient-fill/transformed?: false + ctx/other/gradient-pen?: false + ctx/other/gradient-fill?: false + ctx/other/D2D?: (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 + ctx/other/GDI+?: no + ctx/other/last-point?: no + ctx/other/prev-shape/type: SHAPE_OTHER + ctx/other/path-last-point/x: 0 + ctx/other/path-last-point/y: 0 + ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND + ctx/other/connect-subpath: 0 + ctx/other/anti-alias?: no + ptrn: as red-image! ctx/other/pattern-image-fill + ptrn/node: null + ptrn: as red-image! ctx/other/pattern-image-pen + ptrn/node: null + + either null? hWnd [ + ctx/on-image?: yes + either on-graphic? [ + graphics: as-integer img + ][ + graphics: 0 + OS-image/GdipGetImageGraphicsContext as-integer img/node :graphics + ] + dc: CreateCompatibleDC hScreen + SelectObject dc default-font + SetTextColor dc ctx/pen-color + ctx/dc: dc + update-gdiplus-font-color ctx ctx/pen-color + ][ + either ctx/other/D2D? [ + draw-begin-d2d ctx hWnd + return ctx + ][ + either null? img [ + dc: either paint? [BeginPaint hWnd ctx/other/paint][hScreen] + GetClientRect hWnd rect + width: rect/right - rect/left + height: rect/bottom - rect/top + hBitmap: CreateCompatibleBitmap dc width height + hBackDC: CreateCompatibleDC dc + SelectObject hBackDC hBitmap + ctx/bitmap: hBitmap + ][ + hBackDC: as handle! img + ] + + dc: hBackDC + ctx/dc: dc + + SetGraphicsMode dc GM_ADVANCED + SetArcDirection dc AD_CLOCKWISE + SetBkMode dc BK_TRANSPARENT + SelectObject dc GetStockObject NULL_BRUSH + + render-base hWnd dc + + graphics: 0 + GdipCreateFromHDC dc :graphics + SelectObject dc GetStockObject NULL_BRUSH + SelectObject dc default-font + + update-gdiplus-font-color ctx ctx/pen-color + ] + ] + + if any [hWnd <> null on-graphic?][ + if dpi-factor <> 100 [ + ratio: (as float32! dpi-factor) / (as float32! 100.0) + GdipScaleWorldTransform graphics ratio ratio GDIPLUS_MATRIX_PREPEND + ctx/scale-ratio: ratio + ] + ] + + ctx/graphics: graphics + GdipCreatePen1 + to-gdiplus-color ctx/pen-color + ctx/pen-width + GDIPLUS_UNIT_WORLD + :graphics + ctx/gp-pen: graphics + OS-draw-anti-alias ctx yes + update-gdiplus-font ctx + ctx +] + +draw-end: func [ + ctx [draw-ctx!] + hWnd [handle!] + on-graphic? [logic!] + cache? [logic!] + paint? [logic!] + /local + hr [integer!] + IUnk [IUnknown] + this [this!] + pad4 [integer!] + rect [RECT_STRUCT] + width [integer!] + height [integer!] + bitmap [integer!] + old-dc [integer!] + dc [handle!] + ptrn [red-image!] +][ + if ctx/other/D2D? [ + draw-end-d2d ctx hWnd + free-context ctx + exit + ] + + dc: ctx/dc + pad4: 0 + rect: as RECT_STRUCT :pad4 + if paint? [ + GetClientRect hWnd rect + width: rect/right - rect/left + height: rect/bottom - rect/top + BitBlt ctx/other/paint/hdc 0 0 width height dc 0 0 SRCCOPY + ] + + unless any [on-graphic? zero? ctx/graphics][GdipDeleteGraphics ctx/graphics] + unless zero? ctx/gp-pen [GdipDeletePen ctx/gp-pen] + unless zero? ctx/gp-pen-saved [GdipDeletePen ctx/gp-pen-saved] + unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] + unless zero? ctx/gp-font-brush [GdipDeleteBrush ctx/gp-font-brush] + unless zero? ctx/gp-font [GdipDeleteFont ctx/gp-font] + unless zero? ctx/image-attr [GdipDisposeImageAttributes ctx/image-attr] + unless zero? ctx/gp-matrix [GdipDeleteMatrix ctx/gp-matrix] + unless zero? ctx/pen [DeleteObject as handle! ctx/pen] + unless zero? ctx/brush [DeleteObject as handle! ctx/brush] + unless zero? ctx/other/gradient-pen/matrix [ GdipDeleteMatrix ctx/other/gradient-pen/matrix ] + unless zero? ctx/other/gradient-fill/matrix [ GdipDeleteMatrix ctx/other/gradient-fill/matrix ] + ptrn: as red-image! ctx/other/pattern-image-fill + unless null? ptrn/node [ + OS-image/delete as red-image! ctx/other/pattern-image-fill + ] + ptrn: as red-image! ctx/other/pattern-image-pen + unless null? ptrn/node [ + OS-image/delete as red-image! ctx/other/pattern-image-pen + ] + + if ctx/bitmap <> null [DeleteObject ctx/bitmap] + either cache? [ + old-dc: GetWindowLong hWnd wc-offset - 4 + unless zero? old-dc [DeleteDC as handle! old-dc] + SetWindowLong hWnd wc-offset - 4 as-integer dc + ][ + DeleteDC dc + ] + if all [hWnd <> null paint?][EndPaint hWnd ctx/other/paint] + + free-context ctx +] + +radian-to-degrees: func [ + radians [float!] + return: [float!] +][ + (radians * 180.0) / PI +] + +adjust-angle: func [ + x [float!] + y [float!] + angle [float!] + return: [float!] +][ + case [ + all [ x >= 0.0 y <= 0.0 ] [ either angle = 0.0 [0.0 - angle][360.0 - angle] ] + all [ x <= 0.0 y >= 0.0 ] [ 180.0 - angle ] + all [ x <= 0.0 y <= 0.0 ] [ 180.0 + angle ] + true [ angle ] + ] +] + +set-matrix: func [ + xform [XFORM!] + eM11 [float!] + eM12 [float!] + eM21 [float!] + eM22 [float!] + eDx [float!] + eDy [float!] +][ + xform/eM11: as float32! eM11 + xform/eM12: as float32! eM12 + xform/eM21: as float32! eM21 + xform/eM22: as float32! eM22 + xform/eDx: as float32! eDx + xform/eDy: as float32! eDy +] + +gdi-calc-arc: func [ + center-x [float!] + center-y [float!] + rad-x [float!] + rad-y [float!] + angle-begin [float!] + angle-len [float!] + return: [arcPOINTS!] + /local + radius [red-pair!] + angle [red-integer!] + start-x [float!] + start-y [float!] + end-x [float!] + end-y [float!] + rad-x-float [float32!] + rad-y-float [float32!] + rad-x-2 [float32!] + rad-y-2 [float32!] + rad-x-y [float32!] + tan-2 [float32!] + rad-beg [float!] + rad-end [float!] + points [arcPOINTS!] +][ + points: declare arcPOINTS! + rad-x-float: as float32! rad-x + rad-y-float: as float32! rad-y + + either rad-x = rad-y [ ;-- circle + rad-beg: degree-to-radians angle-begin TYPE_SINE + rad-end: degree-to-radians angle-begin + angle-len TYPE_SINE + start-y: center-y + (rad-y-float * sin rad-beg) + end-y: center-y + (rad-y-float * sin rad-end) + rad-beg: degree-to-radians angle-begin TYPE_COSINE + rad-end: degree-to-radians angle-begin + angle-len TYPE_COSINE + start-x: center-x + (rad-x-float * cos rad-beg) + end-x: center-x + (rad-x-float * cos rad-end) + ][ + rad-beg: degree-to-radians angle-begin TYPE_TANGENT + rad-end: degree-to-radians angle-begin + angle-len TYPE_TANGENT + rad-x-y: rad-x-float * rad-y-float + rad-x-2: rad-x-float * rad-x-float + rad-y-2: rad-y-float * rad-y-float + tan-2: as float32! tan rad-beg + tan-2: tan-2 * tan-2 + start-x: as float! rad-x-y / (sqrt as-float rad-x-2 * tan-2 + rad-y-2) + start-y: as float! rad-x-y / (sqrt as-float rad-y-2 / tan-2 + rad-x-2) + if all [angle-begin > 90.0 angle-begin < 270.0][start-x: 0.0 - start-x] + if all [angle-begin > 180.0 angle-begin < 360.0][start-y: 0.0 - start-y] + start-x: center-x + start-x + start-y: center-y + start-y + angle-begin: angle-begin + angle-len + tan-2: as float32! tan rad-end + tan-2: tan-2 * tan-2 + end-x: as float! rad-x-y / (sqrt as-float rad-x-2 * tan-2 + rad-y-2) + end-y: as float! rad-x-y / (sqrt as-float rad-y-2 / tan-2 + rad-x-2) + if angle-begin < 0.0 [ angle-begin: 360.0 + angle-begin] + if all [angle-begin > 90.0 angle-begin < 270.0][end-x: 0.0 - end-x] + if all [angle-begin > 180.0 angle-begin < 360.0][end-y: 0.0 - end-y] + end-x: center-x + end-x + end-y: center-y + end-y + ] + points/start-x: start-x + points/start-y: start-y + points/end-x: end-x + points/end-y: end-y + points +] + +draw-curves: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + nr-points [integer!] + /local + point [tagPOINT] + pair [red-pair!] + pt [tagPOINT] + nb [integer!] + count [integer!] +][ + pt: ctx/other/edges + pair: start + nb: 0 + count: (as-integer end - pair) >> 4 + 1 + while [ all [ pair <= end nb < MAX_EDGES count >= nr-points ] ][ + pt/x: ctx/other/path-last-point/x + pt/y: ctx/other/path-last-point/y + while [ nb < 3 ][ + nb: nb + 1 + pt: pt + 1 + pt/x: either rel? [ pair/x + ctx/other/path-last-point/x ][ pair/x ] + pt/y: either rel? [ pair/y + ctx/other/path-last-point/y ][ pair/y ] + if nb < nr-points [ pair: pair + 1 ] + ] + ctx/other/path-last-point/x: pt/x + ctx/other/path-last-point/y: pt/y + either ctx/other/GDI+? [ + GdipAddPathBeziersI ctx/gp-path ctx/other/edges nb + 1 + ][ + PolyBezier ctx/dc ctx/other/edges nb + 1 + ] + + count: (as-integer end - pair) >> 4 + nb: 0 + pt: ctx/other/edges + pair: pair + 1 + ] + ctx/other/last-point?: yes + point: ctx/other/edges + nr-points - 1 + ctx/other/prev-shape/type: SHAPE_CURVE + ctx/other/prev-shape/control/x: point/x + ctx/other/prev-shape/control/y: point/y + ctx/other/connect-subpath: 1 +] + +draw-short-curves: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + nr-points [integer!] + /local + pair [red-pair!] + pt [tagPOINT] + nb [integer!] + control [tagPOINT value] + count [integer!] +][ + pt: ctx/other/edges + nb: 0 + pair: start + either ctx/other/prev-shape/type = SHAPE_CURVE [ + control/x: ctx/other/prev-shape/control/x + control/y: ctx/other/prev-shape/control/y + ][ + control/x: ctx/other/path-last-point/x + control/y: ctx/other/path-last-point/y + ] + while [ pair <= end ][ + pt/x: ctx/other/path-last-point/x + pt/y: ctx/other/path-last-point/y + pt: pt + 1 + pt/x: ( 2 * ctx/other/path-last-point/x ) - control/x + pt/y: ( 2 * ctx/other/path-last-point/y ) - control/y + control/x: pt/x + control/y: pt/y + pt: pt + 1 + pt/x: either rel? [ ctx/other/path-last-point/x + pair/x ][ pair/x ] + pt/y: either rel? [ ctx/other/path-last-point/y + pair/y ][ pair/y ] + pt: pt + 1 + loop nr-points - 1 [ pair: pair + 1 ] + if pair <= end [ + pt/x: either rel? [ ctx/other/path-last-point/x + pair/x ][ pair/x ] + pt/y: either rel? [ ctx/other/path-last-point/y + pair/y ][ pair/y ] + ctx/other/last-point?: yes + ctx/other/path-last-point/x: pt/x + ctx/other/path-last-point/y: pt/y + pair: pair + 1 + nb: nb + 4 + ] + either ctx/other/GDI+? [ + GdipAddPathBeziersI ctx/gp-path ctx/other/edges nb + ][ + PolyBezier ctx/dc ctx/other/edges nb + ] + ctx/other/prev-shape/type: SHAPE_CURVE + ctx/other/prev-shape/control/x: control/x + ctx/other/prev-shape/control/y: control/y + + pt: ctx/other/edges + nb: 0 + ] + ctx/other/connect-subpath: 1 +] + +OS-draw-shape-beginpath: func [ + ctx [draw-ctx!] + /local + path [integer!] +][ + ctx/other/connect-subpath: 0 + either ctx/other/GDI+? [ + path: 0 + GdipCreatePath 0 :path ; alternate fill + ctx/gp-path: path + GdipStartPathFigure ctx/gp-path + ][ + update-modes ctx + BeginPath ctx/dc + ] +] + +OS-draw-shape-endpath: func [ + ctx [draw-ctx!] + close? [logic!] + return: [logic!] + /local + alpha [byte!] + width [integer!] + height [integer!] + ftn [integer!] + bf [tagBLENDFUNCTION] + count [integer!] + result [logic!] + point [tagPOINT] + dc [handle!] +][ + result: true + + either ctx/other/GDI+? [ + count: 0 + GdipGetPointCount ctx/gp-path :count + if count > 0 [ + check-gradient-shape ctx ;-- check for gradient + check-texture-shape ctx + if close? [ GdipClosePathFigure ctx/gp-path ] + GdipDrawPath ctx/graphics ctx/gp-pen ctx/gp-path + GdipFillPath ctx/graphics ctx/gp-brush ctx/gp-path + GdipDeletePath ctx/gp-path + ] + ][ + dc: ctx/dc + if close? [ CloseFigure dc ] + EndPath dc + count: GetPath dc ctx/other/edges ctx/other/types 0 + if count > 0 [ + count: GetPath dc ctx/other/edges ctx/other/types count + FillPath dc + PolyDraw dc ctx/other/edges ctx/other/types count + ] + ] + result +] + +OS-draw-shape-close: func [ + ctx [draw-ctx!] +][ + either ctx/other/GDI+? [ + GdipClosePathFigure ctx/gp-path + ][ + CloseFigure ctx/dc + ] +] + +OS-draw-shape-moveto: func [ + ctx [draw-ctx!] + coord [red-pair!] + rel? [logic!] + /local + pt [tagPOINT] +][ + either all [ rel? ctx/other/last-point? ][ + ctx/other/path-last-point/x: ctx/other/path-last-point/x + coord/x + ctx/other/path-last-point/y: ctx/other/path-last-point/y + coord/y + ][ + ctx/other/path-last-point/x: coord/x + ctx/other/path-last-point/y: coord/y + ] + ctx/other/connect-subpath: 0 + ctx/other/last-point?: yes + ctx/other/prev-shape/type: SHAPE_OTHER + either ctx/other/GDI+? [ + GdipStartPathFigure ctx/gp-path + ][ + pt: declare tagPOINT + MoveToEx ctx/dc ctx/other/path-last-point/x ctx/other/path-last-point/y pt + ] +] + +OS-draw-shape-line: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + /local + pt [tagPOINT] + nb [integer!] + pair [red-pair!] +][ + pt: ctx/other/edges + pair: start + nb: 0 + + if ctx/other/last-point? [ + pt/x: ctx/other/path-last-point/x + pt/y: ctx/other/path-last-point/y + pt: pt + 1 + nb: nb + 1 + ] + + while [all [pair <= end nb < MAX_EDGES]][ + pt/x: pair/x + pt/y: pair/y + if rel? [ + pt/x: pt/x + ctx/other/path-last-point/x + pt/y: pt/y + ctx/other/path-last-point/y + ] + ctx/other/path-last-point/x: pt/x + ctx/other/path-last-point/y: pt/y + nb: nb + 1 + pt: pt + 1 + pair: pair + 1 + ] + either ctx/other/GDI+? [ + GdipAddPathLine2I ctx/gp-path ctx/other/edges nb + ][ + Polyline ctx/dc ctx/other/edges nb + ] + ctx/other/last-point?: yes + ctx/other/prev-shape/type: SHAPE_OTHER + ctx/other/connect-subpath: 1 +] + +OS-draw-shape-axis: func [ + ctx [draw-ctx!] + start [red-value!] + end [red-value!] + rel? [logic!] + hline [logic!] + /local + pt [tagPOINT] + nb [integer!] + coord [red-value!] + coord-v [integer!] + coord-f [red-float!] + coord-i [red-integer!] +][ + if ctx/other/last-point? [ + pt: ctx/other/edges + nb: 0 + coord: start + + pt/x: ctx/other/path-last-point/x + pt/y: ctx/other/path-last-point/y + pt: pt + 1 + nb: nb + 1 + coord-v: 0 + until [ + either TYPE_OF(coord) = TYPE_INTEGER [ + coord-i: as red-integer! coord + coord-v: coord-i/value + ][ + coord-f: as red-float! coord + coord-v: as integer! coord-f/value + ] + case [ + hline [ + either rel? [ + pt/x: ctx/other/path-last-point/x + coord-v + ][ pt/x: coord-v ] + pt/y: ctx/other/path-last-point/y + ctx/other/path-last-point/x: pt/x + ] + true [ + either rel? [ + pt/y: ctx/other/path-last-point/y + coord-v + ][ pt/y: coord-v ] + pt/x: ctx/other/path-last-point/x + ctx/other/path-last-point/y: pt/y + ] + ] + coord: coord + 1 + nb: nb + 1 + pt: pt + 1 + any [ coord > end nb >= MAX_EDGES ] + ] + ctx/other/last-point?: yes + either ctx/other/GDI+? [ + GdipAddPathLine2I ctx/gp-path ctx/other/edges nb + ][ + Polyline ctx/dc ctx/other/edges nb + ] + ctx/other/prev-shape/type: SHAPE_OTHER + ctx/other/connect-subpath: 1 + ] +] + +OS-draw-shape-curve: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] +][ + draw-curves ctx start end rel? 3 +] + +OS-draw-shape-qcurve: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] +][ + draw-curves ctx start end rel? 2 +] + +OS-draw-shape-curv: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] +][ + draw-short-curves ctx start end rel? 2 +] + +OS-draw-shape-qcurv: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] +][ + draw-short-curves ctx start end rel? 1 +] + +OS-draw-shape-arc: func [ + ctx [draw-ctx!] + end [red-pair!] + sweep? [logic!] + large? [logic!] + rel? [logic!] + /local + item [red-integer!] + center-x [float!] + center-y [float!] + cx [float!] + cy [float!] + cf [float!] + angle-1 [float!] + angle-2 [float!] + angle-len [float!] + radius-x [float!] + radius-y [float!] + theta [float!] + X1 [float!] + Y1 [float!] + p1-x [float!] + p1-y [float!] + p2-x [float!] + p2-y [float!] + cos-val [float!] + sin-val [float!] + rx2 [float!] + ry2 [float!] + dx [float!] + dy [float!] + sqrt-val [float!] + sign [float!] + rad-check [float!] + angle [red-integer!] + center [red-pair!] + m [integer!] + path [integer!] + arc-dir [integer!] + prev-dir [integer!] + pt [tagPOINT] + arc-points [arcPOINTS!] + dc [handle!] +][ + if ctx/other/last-point? [ + ;-- parse arguments + p1-x: as float! ctx/other/path-last-point/x + p1-y: as float! ctx/other/path-last-point/y + p2-x: either rel? [ p1-x + as float! end/x ][ as float! end/x ] + p2-y: either rel? [ p1-y + as float! end/y ][ as float! end/y ] + item: as red-integer! end + 1 + radius-x: get-float item + item: item + 1 + radius-y: get-float item + item: item + 1 + theta: get-float item + if radius-x < 0.0 [ radius-x: radius-x * -1.0] + if radius-y < 0.0 [ radius-x: radius-x * -1.0] + + ;-- calculate center + dx: (p1-x - p2-x) / 2.0 + dy: (p1-y - p2-y) / 2.0 + cos-val: cos degree-to-radians theta TYPE_COSINE + sin-val: sin degree-to-radians theta TYPE_SINE + X1: (cos-val * dx) + (sin-val * dy) + Y1: (cos-val * dy) - (sin-val * dx) + rx2: radius-x * radius-x + ry2: radius-y * radius-y + rad-check: ((X1 * X1) / rx2) + ((Y1 * Y1) / ry2) + if rad-check > 1.0 [ + radius-x: radius-x * sqrt rad-check + radius-y: radius-y * sqrt rad-check + rx2: radius-x * radius-x + ry2: radius-y * radius-y + ] + sign: either large? = sweep? [ -1.0 ][ 1.0 ] + sqrt-val: ((rx2 * ry2) - (rx2 * Y1 * Y1) - (ry2 * X1 * X1)) / ((rx2 * Y1 * Y1) + (ry2 * X1 * X1)) + cf: either sqrt-val < 0.0 [ 0.0 ][ sign * sqrt sqrt-val ] + cx: cf * (radius-x * Y1 / radius-y) + cy: cf * (radius-y * X1 / radius-x) * -1.0 + center-x: (cos-val * cx) - (sin-val * cy) + ((p1-x + p2-x) / 2.0) + center-y: (sin-val * cx) + (cos-val * cy) + ((p1-y + p2-y) / 2.0) + + ;-- calculate angles + angle-1: radian-to-degrees atan (float/abs ((p1-y - center-y) / (p1-x - center-x))) + angle-1: adjust-angle (p1-x - center-x) (p1-y - center-y) angle-1 + angle-2: radian-to-degrees atan (float/abs ((p2-y - center-y) / (p2-x - center-x))) + angle-2: adjust-angle (p2-x - center-x) (p2-y - center-y) angle-2 + angle-len: angle-2 - angle-1 + either sweep? [ + if angle-len < 0.0 [angle-len: 360.0 + angle-len] + ][ + if angle-len > 0.0 [angle-len: angle-len - 360.0] + ] + angle-1: angle-1 - theta + + ;--draw arc + either ctx/other/GDI+? [ + path: 0 + GdipCreatePath 0 :path ; alternate fill + GdipAddPathArc + path + as float32! center-x - radius-x + as float32! center-y - radius-y + as float32! (radius-x * 2.0) + as float32! (radius-y * 2.0) + as float32! angle-1 + as float32! angle-len + m: 0 + + GdipCreateMatrix :m + GdipTranslateMatrix m as float32! (center-x * -1.0) as float32! (center-y * -1.0) GDIPLUS_MATRIX_APPEND + GdipRotateMatrix m as float32! theta GDIPLUS_MATRIX_APPEND + GdipTranslateMatrix m as float32! center-x as float32! center-y GDIPLUS_MATRIX_APPEND + GdipTransformPath path m + GdipDeleteMatrix m + + GdipAddPathPath ctx/gp-path path ctx/other/connect-subpath + GdipDeletePath path + ][ + dc: ctx/dc + either theta <> 0.0 [ + arc-points: gdi-calc-arc + center-x + center-y + radius-x + radius-y + angle-1 + angle-len + ][ + arc-points: declare arcPOINTS! + arc-points/start-x: p1-x + arc-points/start-y: p1-y + arc-points/end-x: p2-x + arc-points/end-y: p2-y + ] + + set-matrix xform 1.0 0.0 0.0 1.0 center-x * -1.0 center-y * -1.0 + SetWorldTransform dc xform + set-matrix xform cos-val sin-val sin-val * -1.0 cos-val center-x center-y + ModifyWorldTransform dc xform MWT_RIGHTMULTIPLY + + prev-dir: GetArcDirection dc + arc-dir: either sweep? [ AD_CLOCKWISE ][ AD_COUNTERCLOCKWISE ] + SetArcDirection dc arc-dir + Arc + dc + as integer! center-x - radius-x + as integer! center-y - radius-y + as integer! center-x + radius-x + as integer! center-y + radius-y + as integer! arc-points/start-x + as integer! arc-points/start-y + as integer! arc-points/end-x + as integer! arc-points/end-y + SetArcDirection dc prev-dir + + set-matrix xform 1.0 0.0 0.0 1.0 0.0 0.0 + SetWorldTransform dc xform + ] + + ;-- set last point + ctx/other/last-point?: yes + ctx/other/path-last-point/x: as integer! p2-x + ctx/other/path-last-point/y: as integer! p2-y + ctx/other/prev-shape/type: SHAPE_OTHER + ctx/other/connect-subpath: 1 + ] +] + +OS-draw-anti-alias: func [ + ctx [draw-ctx!] + on? [logic!] +][ + ctx/other/anti-alias?: on? + either on? [ + ctx/other/GDI+?: yes + GdipSetSmoothingMode ctx/graphics GDIPLUS_ANTIALIAS + GdipSetTextRenderingHint ctx/graphics TextRenderingHintAntiAliasGridFit + ][ + ctx/other/GDI+?: no + if any [ctx/on-image? dpi-factor <> 100][ ;-- always use GDI+ to draw on image + ctx/other/anti-alias?: yes + ctx/other/GDI+?: yes + ] + GdipSetSmoothingMode ctx/graphics GDIPLUS_HIGHSPPED + GdipSetTextRenderingHint ctx/graphics TextRenderingHintSystemDefault + ] + update-modes ctx +] + +OS-draw-line: func [ + ctx [draw-ctx!] + point [red-pair!] + end [red-pair!] + /local + start [tagPOINT] + pt [tagPOINT] + nb [integer!] + pair [red-pair!] +][ + if ctx/other/D2D? [OS-draw-line-d2d ctx point end exit] + + pt: ctx/other/edges + start: pt + pair: point + nb: 0 + + while [all [pair <= end nb < MAX_EDGES]][ + pt/x: pair/x + pt/y: pair/y + nb: nb + 1 + pt: pt + 1 + pair: pair + 1 + ] + either ctx/other/GDI+? [ + check-gradient-poly ctx start 2 + GdipDrawLinesI ctx/graphics ctx/gp-pen start nb + ][ + Polyline ctx/dc start nb + ] +] + +OS-draw-pen: func [ + ctx [draw-ctx!] + color [integer!] ;-- 00bbggrr format + off? [logic!] + alpha? [logic!] +][ + if all [off? ctx/pen? <> off?][exit] + + if ctx/other/D2D? [OS-draw-pen-d2d ctx color off? exit] + + ctx/alpha-pen?: alpha? + ctx/other/GDI+?: any [alpha? ctx/other/anti-alias? ctx/alpha-brush?] + + if any [ctx/pen-color <> color ctx/pen? = off? ctx/other/gradient-pen?][ + ctx/pen?: not off? + ctx/pen-color: color + either ctx/other/GDI+? [update-gdiplus-pen ctx][update-pen ctx] + ] + + unless ctx/font-color? [ + if ctx/other/GDI+? [update-gdiplus-font-color ctx color] + unless ctx/on-image? [SetTextColor ctx/dc color] + ] +] + +OS-draw-fill-pen: func [ + ctx [draw-ctx!] + color [integer!] ;-- 00bbggrr format + off? [logic!] + alpha? [logic!] +][ + if all [off? ctx/brush? <> off?][exit] + + if ctx/other/D2D? [OS-draw-fill-pen-d2d ctx color off? exit] + + ctx/alpha-brush?: alpha? + ctx/other/GDI+?: any [alpha? ctx/other/anti-alias? ctx/alpha-pen?] + + if any [ctx/brush-color <> color ctx/brush? = off? ctx/other/gradient-fill?][ + ctx/brush?: not off? + ctx/brush-color: color + either ctx/other/GDI+? [update-gdiplus-brush ctx][update-brush ctx] + ] +] + +OS-draw-line-width: func [ + ctx [draw-ctx!] + width [red-value!] + /local + width-v [float32!] +][ + if ctx/other/D2D? [OS-draw-line-width-d2d ctx width exit] + + width-v: get-float32 as red-integer! width + if ctx/pen-width <> width-v [ + ctx/pen-width: width-v + either ctx/other/GDI+? [ + GdipSetPenWidth ctx/gp-pen ctx/pen-width + ][ + update-pen ctx + ] + ] +] + +gdiplus-roundrect-path: func [ + path [integer!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + diameter [integer!] + /local + angle90 [float32!] +][ + angle90: as float32! 90 + GdipAddPathArcI path x y diameter diameter as float32! 180 angle90 + x: x + (width - diameter) + GdipAddPathArcI path x y diameter diameter as float32! 270 angle90 + y: y + (height - diameter) + GdipAddPathArcI path x y diameter diameter as float32! 0 angle90 + x: x - (width - diameter) + GdipAddPathArcI path x y diameter diameter angle90 angle90 + GdipClosePathFigure path +] + +gdiplus-draw-roundbox: func [ + graphics [integer!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + radius [integer!] + pen [integer!] + brush [integer!] + /local + path [integer!] +][ + path: 0 + GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :path + gdiplus-roundrect-path path x y width height radius + if brush <> 0 [ + GdipFillPath graphics brush path + ] + GdipDrawPath graphics pen path + GdipDeletePath path +] + +gdiplus-draw-box: func [ + graphics [integer!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + radius [integer!] + pen [integer!] + brush [integer!] +][ + if radius > 0 [ + gdiplus-draw-roundbox + graphics + x + y + width + height + radius + pen + brush + exit + ] + if brush <> 0 [ ;-- fill rect + GdipFillRectangleI + graphics + brush + x + y + width + height + ] + + GdipDrawRectangleI + graphics + pen + x + y + width + height +] + +OS-draw-box: func [ + ctx [draw-ctx!] + upper [red-pair!] + lower [red-pair!] + /local + t [integer!] + radius [red-integer!] + rad [integer!] + up-x [integer!] + up-y [integer!] + low-x [integer!] + low-y [integer!] + width [integer!] + height [integer!] +][ + if ctx/other/D2D? [ + OS-draw-box-d2d ctx upper lower + exit + ] + rad: either TYPE_OF(lower) = TYPE_INTEGER [ + radius: as red-integer! lower + lower: lower - 1 + radius/value + ][0] + up-x: upper/x up-y: upper/y low-x: lower/x low-y: lower/y + either positive? rad [ + rad: rad * 2 + width: low-x - up-x + height: low-y - up-y + t: either width > height [height][width] + rad: either rad > t [t][rad] + either ctx/other/GDI+? [ + check-gradient-box ctx upper lower + check-texture-box ctx upper + gdiplus-draw-box + ctx/graphics + up-x + up-y + width + height + rad + ctx/gp-pen + either ctx/brush? [ctx/gp-brush][0] + ][ + RoundRect ctx/dc up-x up-y low-x low-y rad rad + ] + ][ + either ctx/other/GDI+? [ + if up-x > low-x [t: up-x up-x: low-x low-x: t] + if up-y > low-y [t: up-y up-y: low-y low-y: t] + check-gradient-box ctx upper lower + check-texture-box ctx upper + gdiplus-draw-box + ctx/graphics + up-x + up-y + low-x - up-x + low-y - up-y + rad + ctx/gp-pen + either ctx/brush? [ctx/gp-brush][0] + ][ + Rectangle ctx/dc up-x up-y low-x low-y + ] + ] +] + +OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon + ctx [draw-ctx!] + start [red-pair!] + /local + pair [red-pair!] + point [tagPOINT] +][ + point: ctx/other/edges + + point/x: start/x ;-- 1st point + point/y: start/y + point: point + 1 + + pair: start + 1 + point/x: pair/x ;-- 2nd point + point/y: pair/y + point: point + 1 + + pair: pair + 1 + point/x: pair/x ;-- 3rd point + point/y: pair/y + point: point + 1 + + point/x: start/x ;-- close the triangle + point/y: start/y + + either ctx/other/GDI+? [ + check-gradient-poly ctx ctx/other/edges 3 + check-texture-poly ctx ctx/other/edges 3 + if ctx/brush? [ + GdipFillPolygonI + ctx/graphics + ctx/gp-brush + ctx/other/edges + 4 + GDIPLUS_FILLMODE_ALTERNATE + ] + GdipDrawPolygonI ctx/graphics ctx/gp-pen ctx/other/edges 4 + ][ + either ctx/brush? [ + Polygon ctx/dc ctx/other/edges 4 + ][ + Polyline ctx/dc ctx/other/edges 4 + ] + ] +] + +OS-draw-polygon: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + /local + pair [red-pair!] + point [tagPOINT] + nb [integer!] +][ + point: ctx/other/edges + pair: start + nb: 0 + + while [all [pair <= end nb < MAX_EDGES]][ + point/x: pair/x + point/y: pair/y + nb: nb + 1 + point: point + 1 + pair: pair + 1 + ] + ;if nb = max-edges [fire error] + + point/x: start/x ;-- close the polygon + point/y: start/y + + either ctx/other/GDI+? [ + check-gradient-poly ctx ctx/other/edges nb + check-texture-poly ctx ctx/other/edges nb + if ctx/brush? [ + GdipFillPolygonI + ctx/graphics + ctx/gp-brush + ctx/other/edges + nb + 1 + GDIPLUS_FILLMODE_ALTERNATE + ] + GdipDrawPolygonI ctx/graphics ctx/gp-pen ctx/other/edges nb + 1 + ][ + either ctx/brush? [ + Polygon ctx/dc ctx/other/edges nb + 1 + ][ + Polyline ctx/dc ctx/other/edges nb + 1 + ] + ] +] + +OS-draw-spline: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + closed? [logic!] + /local + pair [red-pair!] + point [tagPOINT] + nb [integer!] +][ + point: ctx/other/edges + pair: start + nb: 0 + + while [all [pair <= end nb < MAX_EDGES]][ + point/x: pair/x + point/y: pair/y + nb: nb + 1 + point: point + 1 + pair: pair + 1 + ] + ;if nb = max-edges [fire error] + + unless ctx/other/GDI+? [update-gdiplus-modes ctx] ;-- force to use GDI+ + + if ctx/brush? [ + GdipFillClosedCurveI + ctx/graphics + ctx/gp-brush + ctx/other/edges + nb + GDIPLUS_FILLMODE_ALTERNATE + ] + either closed? [ + GdipDrawClosedCurveI ctx/graphics ctx/gp-pen ctx/other/edges nb + ][ + GdipDrawCurveI ctx/graphics ctx/gp-pen ctx/other/edges nb + ] +] + +do-draw-ellipse: func [ + ctx [draw-ctx!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] +][ + either ctx/other/GDI+? [ + check-gradient-ellipse ctx x y width height + if ctx/brush? [ + GdipFillEllipseI + ctx/graphics + ctx/gp-brush + x + y + width + height + ] + GdipDrawEllipseI + ctx/graphics + ctx/gp-pen + x + y + width + height + ][ + Ellipse ctx/dc x y x + width y + height + ] +] + +OS-draw-circle: func [ + ctx [draw-ctx!] + center [red-pair!] + radius [red-integer!] + /local + rad-x [integer!] + rad-y [integer!] + w [integer!] + h [integer!] + f [red-float!] +][ + if ctx/other/D2D? [ + OS-draw-circle-d2d ctx center radius + exit + ] + either TYPE_OF(radius) = TYPE_INTEGER [ + either center + 1 = radius [ ;-- center, radius + rad-x: radius/value + rad-y: rad-x + ][ + rad-y: radius/value ;-- center, radius-x, radius-y + radius: radius - 1 + rad-x: radius/value + ] + w: rad-x * 2 + h: rad-y * 2 + ][ + f: as red-float! radius + either center + 1 = radius [ + rad-x: as-integer f/value + 0.75 + rad-y: rad-x + w: as-integer f/value * 2.0 + h: w + ][ + rad-y: as-integer f/value + 0.75 + h: as-integer f/value * 2.0 + f: f - 1 + rad-x: as-integer f/value + 0.75 + w: as-integer f/value * 2.0 + ] + ] + do-draw-ellipse ctx center/x - rad-x center/y - rad-y w h +] + +OS-draw-ellipse: func [ + ctx [draw-ctx!] + upper [red-pair!] + diameter [red-pair!] +][ + do-draw-ellipse ctx upper/x upper/y diameter/x diameter/y +] + +OS-draw-font: func [ + ctx [draw-ctx!] + font [red-object!] + /local + vals [red-value!] + state [red-block!] + handle [red-handle!] + color [red-tuple!] + hFont [handle!] +][ + vals: object/get-values font + state: as red-block! vals + FONT_OBJ_STATE + color: as red-tuple! vals + FONT_OBJ_COLOR + + hFont: as handle! either TYPE_OF(state) = TYPE_BLOCK [ + handle: as red-handle! block/rs-head state + handle/value + ][ + make-font get-face-obj ctx/hwnd font + ] + + SelectObject ctx/dc hFont + ctx/font-color?: either TYPE_OF(color) = TYPE_TUPLE [ + SetTextColor ctx/dc color/array1 + if ctx/on-image? [update-gdiplus-font-color ctx color/array1] + yes + ][ + no + ] + if ctx/on-image? [update-gdiplus-font ctx] +] + +OS-draw-text: func [ + ctx [draw-ctx!] + pos [red-pair!] + text [red-string!] + catch? [logic!] + return: [logic!] + /local + str [c-string!] + p [c-string!] + len [integer!] + h [integer!] + w [integer!] + sz [tagSIZE] + y [integer!] + x [integer!] + rect [RECT_STRUCT_FLOAT32] + tm [tagTEXTMETRIC] +][ + if ctx/other/D2D? [ + OS-draw-text-d2d ctx pos text catch? + return true + ] + + if TYPE_OF(text) = TYPE_OBJECT [return false] + + len: -1 + str: unicode/to-utf16-len text :len no + either any [ + ctx/on-image? + ctx/other/GDI+? + ][ + x: 0 + rect: as RECT_STRUCT_FLOAT32 :x + rect/x: as float32! pos/x + rect/y: as float32! pos/y + rect/width: as float32! 0 + rect/height: as float32! 0 + GdipDrawString ctx/graphics str len ctx/gp-font rect 0 ctx/gp-font-brush + ][ + tm: as tagTEXTMETRIC ctx/other/gradient-pen/colors + GetTextMetrics ctx/dc tm + x: dpi-scale pos/x + y: dpi-scale pos/y + p: str + while [len > 0][ + if all [p/1 = #"^/" p/2 = #"^@"][ + ExtTextOut ctx/dc x y ETO_CLIPPED null str (as-integer p - str) / 2 null + y: y + tm/tmHeight + str: p + 2 + ] + p: p + 2 + len: len - 1 + ] + if p > str [ExtTextOut ctx/dc x y ETO_CLIPPED null str (as-integer p - str) / 2 null] + ] + true +] + +OS-draw-arc: func [ + ctx [draw-ctx!] + center [red-pair!] + end [red-value!] + /local + radius [red-pair!] + angle [red-integer!] + rad-x [integer!] + rad-y [integer!] + start-x [integer!] + start-y [integer!] + end-x [integer!] + end-y [integer!] + angle-begin [float32!] + angle-len [float32!] + rad-x-float [float32!] + rad-y-float [float32!] + rad-x-2 [float32!] + rad-y-2 [float32!] + rad-x-y [float32!] + tan-2 [float32!] + rad-beg [float!] + rad-end [float!] + closed? [logic!] + prev-dir [integer!] + arc-dir [integer!] + arc-points [arcPOINTS!] + dc [handle!] +][ + radius: center + 1 + rad-x: radius/x + rad-y: radius/y + angle: as red-integer! radius + 1 + angle-begin: as float32! angle/value + angle: angle + 1 + angle-len: as float32! angle/value + + closed?: angle < end + + either ctx/other/GDI+? [ + either closed? [ + if ctx/brush? [ + GdipFillPieI + ctx/graphics + ctx/gp-brush + center/x - rad-x + center/y - rad-y + rad-x << 1 + rad-y << 1 + angle-begin + angle-len + ] + GdipDrawPieI + ctx/graphics + ctx/gp-pen + center/x - rad-x + center/y - rad-y + rad-x << 1 + rad-y << 1 + angle-begin + angle-len + ][ + GdipDrawArcI + ctx/graphics + ctx/gp-pen + center/x - rad-x + center/y - rad-y + rad-x << 1 + rad-y << 1 + angle-begin + angle-len + ] + ][ + dc: ctx/dc + rad-x-float: as float32! rad-x + rad-y-float: as float32! rad-y + + arc-points: gdi-calc-arc + as float! center/x + as float! center/y + as float! rad-x + as float! rad-y + as float! angle-begin + as float! angle-len + prev-dir: GetArcDirection dc + arc-dir: either angle-len > as float32! 0.0 [ AD_CLOCKWISE ][ AD_COUNTERCLOCKWISE ] + SetArcDirection dc arc-dir + either closed? [ + Pie + dc + center/x - rad-x + center/y - rad-y + center/x + rad-x + center/y + rad-y + as integer! arc-points/start-x + as integer! arc-points/start-y + as integer! arc-points/end-x + as integer! arc-points/end-y + ][ + Arc + dc + center/x - rad-x + center/y - rad-y + center/x + rad-x + center/y + rad-y + as integer! arc-points/start-x + as integer! arc-points/start-y + as integer! arc-points/end-x + as integer! arc-points/end-y + ] + SetArcDirection dc prev-dir + ] +] + +OS-draw-curve: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + /local + pair [red-pair!] + point [tagPOINT] + p2 [red-pair!] + p3 [red-pair!] + nb [integer!] + count [integer!] +][ + point: ctx/other/edges + pair: start + nb: 0 + count: (as-integer end - pair) >> 4 + 1 + + either count = 3 [ ;-- p0, p1, p2 -> p0, (p0 + 2p1) / 3, (2p1 + p2) / 3, p2 + point/x: pair/x + point/y: pair/y + point: point + 1 + p2: pair + 1 + p3: pair + 2 + point/x: p2/x << 1 + pair/x / 3 + point/y: p2/y << 1 + pair/y / 3 + point: point + 1 + point/x: p2/x << 1 + p3/x / 3 + point/y: p2/y << 1 + p3/y / 3 + point: point + 1 + point/x: end/x + point/y: end/y + ][ + until [ + point/x: pair/x + point/y: pair/y + nb: nb + 1 + point: point + 1 + pair: pair + 1 + nb = 4 + ] + ] + + either ctx/other/GDI+? [ + GdipDrawBeziersI ctx/graphics ctx/gp-pen ctx/other/edges 4 + ][ + PolyBezier ctx/dc ctx/other/edges 4 + ] +] + +OS-draw-line-join: func [ + ctx [draw-ctx!] + style [integer!] + /local + mode [integer!] +][ + mode: 0 + ctx/pen-join: style + either ctx/other/GDI+? [ + case [ + style = miter [mode: GDIPLUS_MITER] + style = miter-bevel [mode: GDIPLUS_MITERCLIPPED] + style = _round [mode: GDIPLUS_ROUND] + style = bevel [mode: GDIPLUS_BEVEL] + true [mode: GDIPLUS_MITER] + ] + GdipSetPenLineJoin ctx/gp-pen mode + ][ + update-pen ctx PEN_LINE_JOIN + ] +] + +OS-draw-line-cap: func [ + ctx [draw-ctx!] + style [integer!] + /local + mode [integer!] +][ + mode: 0 + ctx/pen-cap: style + either ctx/other/GDI+? [ + case [ + style = flat [mode: GDIPLUS_LINECAPFLAT] + style = square [mode: GDIPLUS_LINECAPSQUARE] + style = _round [mode: GDIPLUS_LINECAPROUND] + true [mode: GDIPLUS_LINECAPFLAT] + ] + GdipSetPenStartCap ctx/gp-pen mode + GdipSetPenEndCap ctx/gp-pen mode + ][ + update-pen ctx PEN_LINE_CAP + ] +] + +OS-draw-image: func [ + ctx [draw-ctx!] + image [red-image!] + start [red-pair!] + end [red-pair!] + key-color [red-tuple!] + border? [logic!] + crop1 [red-pair!] + pattern [red-word!] + /local + x [integer!] + y [integer!] + width [integer!] + height [integer!] + src-x [integer!] + src-y [integer!] + w [integer!] + h [integer!] + attr [integer!] + color [integer!] + crop2 [red-pair!] + pts [tagPOINT] +][ + attr: 0 + if key-color <> null [ + attr: ctx/image-attr + if zero? attr [GdipCreateImageAttributes :attr] + color: to-gdiplus-color key-color/array1 + GdipSetImageAttributesColorKeys attr 0 true color color + ] + either crop1 = null [ + src-x: 0 src-y: 0 + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + ][ + crop2: crop1 + 1 + src-x: crop1/x + src-y: crop1/y + w: crop2/x + h: crop2/y + ] + either null? start [x: 0 y: 0][x: start/x y: start/y] + case [ + start = end [ + width: w + height: h + ] + start + 1 = end [ ;-- two control points + width: end/x - x + height: end/y - y + ] + start + 2 = end [ ;-- three control points + pts: ctx/other/edges + loop 3 [ + pts/x: start/x + pts/y: start/y + pts: pts + 1 + start: start + 1 + ] + GdipDrawImagePointsRectI + ctx/graphics as-integer image/node ctx/other/edges 3 + 0 0 w h GDIPLUS_UNIT_PIXEL attr 0 0 + exit + ] + true [exit] ;@@ TBD four control points + ] + GdipDrawImageRectRectI + ctx/graphics as-integer image/node + x y width height src-x src-y w h + GDIPLUS_UNIT_PIXEL attr 0 0 +] + +check-texture: func [ + ctx [draw-ctx!] + pen? [logic!] + return: [integer!] + /local + brush [integer!] +][ + brush: 0 + either pen? [ + if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ + GdipGetPenBrushFill ctx/gp-pen :brush + ] + ][ + if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ + brush: ctx/gp-brush + ] + ] + brush +] + +check-texture-box: func [ + ctx [draw-ctx!] + upper [red-pair!] + /local + brush [integer!] +][ + brush: 0 + if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx true + texture-translate as-float upper/x as-float upper/y brush + ] + if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx false + texture-translate as-float upper/x as-float upper/y brush + ] +] + +check-texture-ellipse: func [ + ctx [draw-ctx!] + x [integer!] + y [integer!] + /local + brush [integer!] +][ + brush: 0 + if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx true + texture-translate as-float x as-float y brush + ] + if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx false + texture-translate as-float x as-float y brush + ] +] + +check-texture-poly: func [ + ctx [draw-ctx!] + start [tagPOINT] + count [integer!] + /local + cx [integer!] + cy [integer!] + d [integer!] + brush [integer!] +][ + brush: 0 + cx: 0 cy: 0 d: 0 + if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx true + get-shape-center start count :cx :cy :d + texture-translate as-float cx as-float cy brush + ] + if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ + brush: check-texture ctx false + get-shape-center start count :cx :cy :d + texture-translate as-float cx as-float cy brush + ] +] + +check-texture-shape: func [ + ctx [draw-ctx!] + /local + new-path [integer!] + count [integer!] + result [integer!] + points [tagPOINT] + point [tagPOINT] + path-data [PATHDATA] + pt2F [POINT_2F] +][ + ;-- flatten path to get a polygon aproximation + new-path: 0 + GdipClonePath ctx/gp-path :new-path + GdipFlattenPath new-path 0 as float32! 1.0 + count: 0 + GdipGetPointCount new-path :count + path-data: ALLOC_REENTRANT(PATHDATA) + path-data/count: count + path-data/points: as POINT_2F allocate count * (size? POINT_2F) + path-data/types: allocate count + GdipGetPathData new-path path-data + ;-- translate call to check-texture-poly (it will start drawing texture in the center of aproximated polygon) + points: as tagPOINT allocate count * (size? tagPOINT) + point: points + pt2F: path-data/points + loop count [ + point/x: as-integer pt2F/x + point/y: as-integer pt2F/y + point: point + 1 + pt2F: pt2F + 1 + ] + check-texture-poly ctx points count + ;-- free allocated resources + free as byte-ptr! points + free as byte-ptr! path-data/points + free path-data/types + FREE_REENTRANT(path-data) +] + +texture-rotate: func [ + angle [float!] + brush [integer!] +][ + unless zero? brush [ GdipRotateTextureTransform brush as-float32 angle GDIPLUS_MATRIX_PREPEND ] +] + +texture-scale: func [ + sx [float!] + sy [float!] + brush [integer!] +][ + unless zero? brush [ GdipScaleTextureTransform brush as-float32 sx as-float32 sy GDIPLUS_MATRIX_PREPEND ] +] + +texture-translate: func [ + x [float!] + y [float!] + brush [integer!] +][ + unless zero? brush [ GdipTranslateTextureTransform brush as-float32 x as-float32 y GDIPLUS_MATRIX_PREPEND ] +] + +texture-set-matrix: func [ + matrix [integer!] + brush [integer!] +][ + unless zero? brush [ GdipSetTextureTransform brush matrix ] +] + +texture-reset-matrix: func [ + brush [integer!] +][ + unless zero? brush [ GdipResetTextureTransform brush ] +] + +texture-invert-matrix: func [ + ctx [draw-ctx!] + brush [integer!] + /local + m [integer!] +][ + unless zero? brush [ + m: ctx/gp-matrix + if zero? m [ + GdipCreateMatrix :m + ctx/gp-matrix: m + ] + GdipGetTextureTransform brush :m + GdipInvertMatrix m + GdipSetTextureTransform brush m + ] +] + +OS-draw-brush-bitmap: func [ + ctx [draw-ctx!] + img [red-image!] + crop-1 [red-pair!] + crop-2 [red-pair!] + mode [red-word!] + brush? [logic!] + /local + x [integer!] + y [integer!] + width [integer!] + height [integer!] + texture [integer!] + wrap [integer!] + result [integer!] +][ + width: OS-image/width? img/node + height: OS-image/height? img/node + either crop-1 = null [ + x: 0 + y: 0 + ][ + x: crop-1/x + y: crop-1/y + ] + either crop-2 = null [ + width: width - x + height: height - y + ][ + width: either ( x + crop-2/x ) > width [ width - x ][ crop-2/x ] + height: either ( y + crop-2/y ) > height [ height - y ][ crop-2/y ] + ] + wrap: WRAP_MODE_TILE + unless mode = null [ + wrap: symbol/resolve mode/symbol + case [ + wrap = flip-x [ wrap: WRAP_MODE_TILE_FLIP_X ] + wrap = flip-y [ wrap: WRAP_MODE_TILE_FLIP_Y ] + wrap = flip-xy [ wrap: WRAP_MODE_TILE_FLIP_XY ] + wrap = clamp [ wrap: WRAP_MODE_CLAMP] + true [ wrap: WRAP_MODE_TILE ] + ] + ] + texture: 0 + result: GdipCreateTexture2I as-integer img/node wrap x y width height :texture + either brush? [ + ctx/brush?: yes + ctx/gp-brush: texture + ctx/gp-brush-type: BRUSH_TYPE_TEXTURE + ][ + GdipSetPenBrushFill ctx/gp-pen texture + ctx/gp-pen-type: BRUSH_TYPE_TEXTURE + ] +] + +OS-draw-brush-pattern: func [ + ctx [draw-ctx!] + size [red-pair!] + crop-1 [red-pair!] + crop-2 [red-pair!] + mode [red-word!] + block [red-block!] + brush? [logic!] + /local + pat-image [red-image!] + bkg-alpha [byte!] + p-alpha [byte-ptr!] + p [byte-ptr!] +][ + pat-image: either brush? + [ as red-image! ctx/other/pattern-image-fill ] + [ as red-image! ctx/other/pattern-image-pen ] + unless null? pat-image/node [ + OS-image/delete pat-image + ] + pat-image/header: TYPE_IMAGE + pat-image/head: 0 + pat-image/size: size/y << 16 or size/x + bkg-alpha: as byte! 0 + p-alpha: allocate pat-image/size + p: p-alpha + loop pat-image/size [ + p/value: as-byte 255 + p: p + 1 + ] + pat-image/node: OS-image/make-image size/x size/y null p-alpha null + free p-alpha + do-draw null pat-image block no no no no + OS-draw-brush-bitmap ctx pat-image crop-1 crop-2 mode brush? +] + +get-shape-center: func [ + start [tagPOINT] + count [integer!] + cx [int-ptr!] + cy [int-ptr!] + d [int-ptr!] + /local + point [tagPOINT] + dx [integer!] + dy [integer!] + x0 [integer!] + y0 [integer!] + x1 [integer!] + y1 [integer!] + a [integer!] + r [integer!] + signedArea [float!] + centroid-x [float!] + centroid-y [float!] +][ + ;-- implementation taken from http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon + x0: 0 y0: 0 x1: 0 y1: 0 + a: 0 signedArea: 0.0 + centroid-x: 0.0 centroid-y: 0.0 + point: start + loop count - 1 [ + x0: point/x + y0: point/y + point: point + 1 + x1: point/x + y1: point/y + a: x0 * y1 - (x1 * y0) + signedArea: signedArea + as-float a + centroid-x: centroid-x + as-float ((x0 + x1) * a) + centroid-y: centroid-y + as-float ((y0 + y1) * a) + ] + x0: point/x + y0: point/y + x1: start/x + y1: start/y + a: x0 * y1 - (x1 * y0) + signedArea: signedArea + as-float a + centroid-x: centroid-x + as-float ((x0 + x1) * a) + centroid-y: centroid-y + as-float ((y0 + y1) * a) + + signedArea: signedArea * 0.5 + centroid-x: centroid-x / (signedArea * 6.0) + centroid-y: centroid-y / (signedArea * 6.0) + + cx/value: as-integer centroid-x + cy/value: as-integer centroid-y + ;-- take biggest distance + d/value: 0 + point: start + loop count [ + dx: cx/value - point/x + dy: cy/value - point/y + r: as-integer sqrt as-float ( dx * dx + ( dy * dy ) ) + if r > d/value [ d/value: r ] + point: point + 1 + ] +] + +get-shape-bounding-box: func [ + start [tagPOINT] + count [integer!] + upper [tagPOINT] + lower [tagPOINT] + /local + point [tagPOINT] +][ + upper/x: 1000000 + upper/y: 1000000 + lower/x: 0 + lower/y: 0 + point: start + loop count [ + if point/x > lower/x [ lower/x: point/x ] + if point/y > lower/y [ lower/y: point/y ] + if point/x < upper/x [ upper/x: point/x ] + if point/y < upper/y [ upper/y: point/y ] + point: point + 1 + ] +] + +gradient-deviation: func [ + p1 [tagPOINT] + p2 [tagPOINT] + return: [float32!] + /local + d [float!] + d1 [float!] + d2 [float!] +][ + d1: as-float p1/x - p2/x + d2: as-float p1/y - p2/y + d: sqrt ( ( d1 * d1 ) + ( d2 * d2 ) ) + as-float32 radian-to-degrees asin ( d2 / d ) +] + +gradient-transform: func [ + ctx [draw-ctx!] + gradient [gradient!] + /local + brush [integer!] +][ + if gradient/transformed? [ + either gradient = ctx/other/gradient-pen [ + brush: 0 + GdipGetPenBrushFill ctx/gp-pen :brush + ][ + brush: ctx/gp-brush + ] + either gradient/type = GRADIENT_LINEAR [ + GdipRotateMatrix + gradient/matrix + as-float32 0 - gradient-deviation gradient/data gradient/data + 1 + GDIPLUS_MATRIX_PREPEND + GdipSetLineTransform brush gradient/matrix ;-- this function resets angle of position points + ][ + GdipSetPathGradientTransform brush gradient/matrix + ] + gradient/transformed?: false + ] +] + +gradient-rotate: func [ + ctx [draw-ctx!] + gradient [gradient!] + angle [float!] +][ + gradient/transformed?: true + GdipRotateMatrix gradient/matrix as float32! angle GDIPLUS_MATRIX_PREPEND + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-skew: func [ + ctx [draw-ctx!] + gradient [gradient!] + sx [float!] + sy [float!] + /local + m [integer!] + x [float32!] + y [float32!] + u [float32!] + z [float32!] +][ + m: 0 + u: as float32! 1.0 + z: as float32! 0.0 + x: as float32! tan degree-to-radians sx TYPE_TANGENT + y: as float32! either sx = sy [0.0][tan degree-to-radians sy TYPE_TANGENT] + gradient/transformed?: true + GdipCreateMatrix2 u y x u z z :m + GdipMultiplyMatrix gradient/matrix m GDIPLUS_MATRIX_PREPEND + GdipDeleteMatrix m + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-scale: func [ + ctx [draw-ctx!] + gradient [gradient!] + sx [float!] + sy [float!] +][ + gradient/transformed?: true + GdipScaleMatrix gradient/matrix as-float32 sx as-float32 sy GDIPLUS_MATRIX_PREPEND + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-translate: func [ + ctx [draw-ctx!] + gradient [gradient!] + x [float!] + y [float!] +][ + gradient/transformed?: true + GdipTranslateMatrix gradient/matrix as-float32 x as-float32 y GDIPLUS_MATRIX_PREPEND + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-transf-reset: func [ + ctx [draw-ctx!] + gradient [gradient!] + /local + m [integer!] +][ + m: gradient/matrix + either zero? m [ + GdipCreateMatrix :m + gradient/matrix: m + ][ + GdipSetMatrixElements + m + as-float32 1 + as-float32 0 + as-float32 0 + as-float32 1 + as-float32 0 + as-float32 0 + ] +] + +gradient-set-matrix: func [ + ctx [draw-ctx!] + gradient [gradient!] + m [integer!] + /local + m11 [float32-ptr!] + m12 [float32-ptr!] + m21 [float32-ptr!] + m22 [float32-ptr!] + dx [float32-ptr!] + dy [float32-ptr!] +][ + gradient/transformed?: true + GdipGetMatrixElements m ctx/other/matrix-elems + m11: ctx/other/matrix-elems + m12: ctx/other/matrix-elems + 1 + m21: ctx/other/matrix-elems + 2 + m22: ctx/other/matrix-elems + 3 + dx: ctx/other/matrix-elems + 4 + dy: ctx/other/matrix-elems + 5 + GdipSetMatrixElements + gradient/matrix + m11/value + m12/value + m21/value + m22/value + dx/value + dy/value + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-reset-matrix: func [ + ctx [draw-ctx!] + gradient [gradient!] +][ + gradient/transformed?: true + gradient-transf-reset ctx gradient + if gradient/created? [ gradient-transform ctx gradient ] +] + +gradient-invert-matrix: func [ + ctx [draw-ctx!] + gradient [gradient!] +][ + gradient/transformed?: true + GdipInvertMatrix gradient/matrix + if gradient/created? [ gradient-transform ctx gradient ] +] + +save-brush: func [ + ctx [draw-ctx!] + gradient [gradient!] + brush [integer!] +][ + ctx/other/GDI+?: yes + gradient/created?: true + either gradient = ctx/other/gradient-fill [ + unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] + ctx/gp-brush: brush + ctx/gp-brush-type: BRUSH_TYPE_NORMAL + ][ + GdipSetPenBrushFill ctx/gp-pen brush + ctx/gp-pen-type: BRUSH_TYPE_NORMAL + ] +] + +gradient-linear: func [ + ctx [draw-ctx!] + gradient [gradient!] + point-1 [tagPOINT] + point-2 [tagPOINT] + /local + brush [integer!] + count [integer!] +][ + brush: 0 + count: gradient/count + unless gradient/extra = 0 [ + point-1/x: point-1/x - gradient/extra - 1 + point-2/x: point-2/x + gradient/extra + 1 + gradient/extra: 0 + ] + GdipCreateLineBrushI point-1 point-2 gradient/colors/1 gradient/colors/count 0 :brush + if gradient/transformed? [ + GdipRotateMatrix + gradient/matrix + as-float32 0 - gradient-deviation point-1 point-2 + GDIPLUS_MATRIX_PREPEND + GdipSetLineTransform brush gradient/matrix ;-- this function resets angle of position points + gradient/transformed?: false + ] + GdipSetLinePresetBlend brush gradient/colors gradient/colors-pos count + GdipSetLineWrapMode brush gradient/spread + + save-brush ctx gradient brush +] + +gradient-radial-diamond: func [ + ctx [draw-ctx!] + gradient [gradient!] + center [tagPOINT] + focal [tagPOINT] + radius [integer!] + /local + brush [integer!] + count [integer!] + color [int-ptr!] + size [integer!] + n [integer!] + width [integer!] + height [integer!] + x [integer!] + y [integer!] + other [tagPOINT] +][ + brush: 0 + + count: gradient/count + GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :brush + + other: gradient/data + INDEX_OTHER + either gradient/type = GRADIENT_RADIAL [ + size: radius * 2 + x: center/x - radius + y: center/y - radius + unless gradient/extra = 0 [ + x: x - gradient/extra - 1 + y: y - gradient/extra - 1 + size: 2 * gradient/extra + size + gradient/extra: 0 + ] + GdipAddPathEllipseI brush x y size size + other/x: focal/x + other/y: focal/y + ][ + x: center/x + y: center/y + width: focal/x - center/x + 1 + height: focal/y - center/y + 1 + unless gradient/extra = 0 [ + x: x - gradient/extra - 1 + y: y - gradient/extra - 1 + width: 2 * gradient/extra + height + height: 2 * gradient/extra + height + gradient/extra: 0 + ] + GdipAddPathRectangleI brush x y width height + ] + + n: brush + GdipCreatePathGradientFromPath n :brush + GdipDeletePath n + GdipSetPathGradientCenterColor brush gradient/colors/value + either gradient/type = GRADIENT_RADIAL [ + GdipSetPathGradientCenterPointI brush focal + ][ + unless radius = INVALID_RADIUS [ GdipSetPathGradientCenterPointI brush other ] + ] + reverse-int-array gradient/colors count + reverse-float32-array gradient/colors-pos count + GdipSetPathGradientPresetBlend brush gradient/colors gradient/colors-pos count + reverse-int-array gradient/colors count + reverse-float32-array gradient/colors-pos count + + if gradient/transformed? [ + GdipSetPathGradientTransform brush gradient/matrix + gradient/transformed?: false + ] + GdipSetPathGradientWrapMode brush gradient/spread + + save-brush ctx gradient brush +] + +check-gradient: func [ + ctx [draw-ctx!] + gradient [gradient!] + /local + upper [tagPOINT] + lower [tagPOINT] + radius [tagPOINT] +][ + INIT_GRADIENT_DATA(upper lower radius) + if all [ gradient = ctx/other/gradient-pen ctx/pen-width > as float32! 1.0 ] [ + gradient/extra: as-integer ctx/pen-width / 2 + ] + case [ + gradient/type = GRADIENT_LINEAR [ + gradient-linear ctx gradient upper lower + ] + any [ + gradient/type = GRADIENT_RADIAL + gradient/type = GRADIENT_DIAMOND + ][ + gradient-radial-diamond ctx gradient upper lower radius/x + ] + true [] + ] +] + +_check-gradient-box: func [ + ctx [draw-ctx!] + gradient [gradient!] + upper [red-pair!] + lower [red-pair!] + /local + dx [integer!] + dy [integer!] + _upper [tagPOINT] + _lower [tagPOINT] + _other [tagPOINT] +][ + INIT_GRADIENT_DATA(_upper _lower _other) + case [ + any [ + gradient/type = GRADIENT_LINEAR + gradient/type = GRADIENT_DIAMOND + ][ + _upper/x: upper/x + _lower/x: lower/x + either gradient/type = GRADIENT_LINEAR [ + _upper/y: 0 + _lower/y: 0 + ][ + _upper/y: upper/y + _lower/y: lower/y + ] + _other/x: INVALID_RADIUS + ] + gradient/type = GRADIENT_RADIAL [ + dx: ( lower/x - upper/x + 1 ) / 2 + dy: ( lower/y - upper/y + 1 ) / 2 + _upper/x: upper/x + dx + _upper/y: upper/y + dy + _lower/x: _upper/x + _lower/y: _upper/y + _other/x: as-integer sqrt as-float (dx * dx + ( dy * dy ) ) + ] + true [] + ] + check-gradient ctx gradient _upper _lower _other +] +check-gradient-box: func [ + ctx [draw-ctx!] + upper [red-pair!] + lower [red-pair!] +][ + if all [ + ctx/other/gradient-pen? + not ctx/other/gradient-pen/positions? + ][ + _check-gradient-box + ctx + ctx/other/gradient-pen + upper + lower + ] + if all [ + ctx/other/gradient-fill? + not ctx/other/gradient-fill/positions? + ][ + ctx/brush?: true + _check-gradient-box + ctx + ctx/other/gradient-fill + upper + lower + ] +] + +_check-gradient-ellipse: func [ + ctx [draw-ctx!] + gradient [gradient!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + /local + dx [integer!] + dy [integer!] + upper [tagPOINT] + lower [tagPOINT] + other [tagPOINT] +][ + INIT_GRADIENT_DATA(upper lower other) + case [ + any [ + gradient/type = GRADIENT_LINEAR + gradient/type = GRADIENT_DIAMOND + ][ + upper/x: x + lower/x: x + width + either gradient/type = GRADIENT_LINEAR [ + upper/y: 0 + lower/y: 0 + ][ + upper/y: y + lower/y: y + height + ] + other/x: INVALID_RADIUS + ] + gradient/type = GRADIENT_RADIAL [ + dx: width / 2 + dy: height / 2 + upper/x: x + dx + upper/y: y + dy + lower/x: upper/x + lower/y: upper/y + other/x: either dx > dy [dx][dy] + ] + true [] + ] + check-gradient ctx gradient upper lower other +] +check-gradient-ellipse: func [ + ctx [draw-ctx!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] +][ + if all [ + ctx/other/gradient-pen? + not ctx/other/gradient-pen/positions? + ][ + _check-gradient-ellipse + ctx + ctx/other/gradient-pen + x + y + width + height + ] + if all [ + ctx/other/gradient-fill? + not ctx/other/gradient-fill/positions? + ][ + ctx/brush?: true + _check-gradient-ellipse + ctx + ctx/other/gradient-fill + x + y + width + height + ] +] + +_check-gradient-poly: func [ + ctx [draw-ctx!] + gradient [gradient!] + start [tagPOINT] + count [integer!] + /local + cx [integer!] + cy [integer!] + d [integer!] + upper [tagPOINT] + lower [tagPOINT] + other [tagPOINT] +][ + INIT_GRADIENT_DATA(upper lower other) + cx: 0 cy: 0 d: 0 + case [ + any [ + gradient/type = GRADIENT_LINEAR + gradient/type = GRADIENT_DIAMOND + ][ + get-shape-bounding-box start count upper lower + either gradient/type = GRADIENT_LINEAR [ + upper/y: 0 + lower/y: 0 + other/x: INVALID_RADIUS + ][ + get-shape-center start count :cx :cy :d + other/x: cx + other/y: cy + ] + ] + gradient/type = GRADIENT_RADIAL [ + get-shape-center start count :cx :cy :d + upper/x: cx + upper/y: cy + lower/x: cx + lower/y: cy + other/x: d + ] + ] + check-gradient ctx gradient upper lower other +] +check-gradient-poly: func [ + ctx [draw-ctx!] + start [tagPOINT] + count [integer!] +][ + if all [ + ctx/other/gradient-pen? + not ctx/other/gradient-pen/positions? + ][ + _check-gradient-poly + ctx + ctx/other/gradient-pen + start + count + ] + if all [ + ctx/other/gradient-fill? + not ctx/other/gradient-fill/positions? + ][ + ctx/brush?: true + _check-gradient-poly + ctx + ctx/other/gradient-fill + start + count + ] +] + +_check-gradient-shape: func [ + ctx [draw-ctx!] + gradient [gradient!] + /local + new-path [integer!] + count [integer!] + result [integer!] + points [tagPOINT] + point [tagPOINT] + pt2F [POINT_2F] +][ + ;-- flatten path to get a polygon aproximation + new-path: 0 + GdipClonePath ctx/gp-path :new-path + GdipFlattenPath new-path 0 as float32! 1.0 + count: 0 + GdipGetPointCount new-path :count + gradient/path-data/count: count + gradient/path-data/points: as POINT_2F allocate count * (size? POINT_2F) + gradient/path-data/types: allocate count + GdipGetPathData new-path gradient/path-data + ;-- translate call to check-gradient-poly (it will draw gradient in the center of aproximated polygon) + points: as tagPOINT allocate count * (size? tagPOINT) + point: points + pt2F: gradient/path-data/points + loop count [ + point/x: as-integer pt2F/x + point/y: as-integer pt2F/y + point: point + 1 + pt2F: pt2F + 1 + ] + _check-gradient-poly ctx gradient points count + ;-- free allocated resources + free as byte-ptr! points + free as byte-ptr! gradient/path-data/points + free gradient/path-data/types +] +check-gradient-shape: func [ + ctx [draw-ctx!] +][ + if all [ + ctx/other/gradient-pen? + not ctx/other/gradient-pen/positions? + ][ + _check-gradient-shape + ctx + ctx/other/gradient-pen + ] + if all [ + ctx/other/gradient-fill? + not ctx/other/gradient-fill/positions? + ][ + ctx/brush?: true + _check-gradient-shape + ctx + ctx/other/gradient-fill + ] +] + +OS-draw-grad-pen-old: func [ + ctx [draw-ctx!] + type [integer!] + mode [integer!] + offset [red-pair!] + count [integer!] ;-- number of the colors + brush? [logic!] + /local + x [integer!] + y [integer!] + start [integer!] + stop [integer!] + brush [integer!] + angle [float32!] + sx [float32!] + sy [float32!] + int [red-integer!] + f [red-float!] + head [red-value!] + next [red-value!] + clr [red-tuple!] + pt [tagPOINT] + color [int-ptr!] + last-c [int-ptr!] + pos [float32-ptr!] + last-p [float32-ptr!] + n [integer!] + delta [float!] + p [float!] + rotate? [logic!] + scale? [logic!] + _colors [int-ptr!] + _colors-pos [float32-ptr!] +][ + _colors: ctx/other/gradient-pen/colors + _colors-pos: ctx/other/gradient-pen/colors-pos + x: offset/x + y: offset/y + + int: as red-integer! offset + 1 + start: int/value + int: int + 1 + stop: int/value + + n: 0 + rotate?: no + scale?: no + sy: as float32! 1.0 + while [ + int: int + 1 + n < 3 + ][ ;-- fetch angle, scale-x and scale-y (optional) + switch TYPE_OF(int) [ + TYPE_INTEGER [p: as-float int/value] + TYPE_FLOAT [f: as red-float! int p: f/value] + default [break] + ] + switch n [ + 0 [if p <> 0.0 [angle: as float32! p rotate?: yes]] + 1 [if p <> 1.0 [sx: as float32! p scale?: yes]] + 2 [if p <> 1.0 [sy: as float32! p scale?: yes]] + ] + n: n + 1 + ] + + pt: ctx/other/edges + color: _colors + 1 + pos: _colors-pos + 1 + delta: as-float count - 1 + delta: 1.0 / delta + p: 0.0 + head: as red-value! int + loop count [ + clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] + color/value: to-gdiplus-color clr/array1 + next: head + 1 + if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] + pos/value: as float32! p + if next <> head [p: p + delta] + head: head + 1 + color: color + 1 + pos: pos + 1 + ] + + last-p: pos - 1 + last-c: color - 1 + pos: pos - count + color: color - count + if pos/value > as float32! 0.0 [ ;-- first one should be always 0.0 + _colors-pos/value: as float32! 0.0 + _colors/value: color/value + color: _colors + pos: _colors-pos + count: count + 1 + ] + if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 + last-c/2: last-c/value + last-p/2: as float32! 1.0 + count: count + 1 + ] + + brush: 0 + either type = linear [ + pt/x: x + start + pt/y: y + pt: pt + 1 + pt/x: x + stop + pt/y: y + GdipCreateLineBrushI ctx/other/edges pt color/1 color/count 0 :brush + GdipSetLinePresetBlend brush color pos count + if rotate? [GdipRotateLineTransform brush angle GDIPLUS_MATRIX_APPEND] + if scale? [GdipScaleLineTransform brush sx sy GDIPLUS_MATRIX_APPEND] + ][ + GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :brush + n: stop - start + stop: n * 2 + case [ + type = radial [GdipAddPathEllipseI brush x - n y - n stop stop] + type = diamond [GdipAddPathRectangleI brush x - n y - n stop stop] + ] + + GdipCreateMatrix :n + if rotate? [GdipRotateMatrix n angle GDIPLUS_MATRIX_APPEND] + if scale? [GdipScaleMatrix n sx sy GDIPLUS_MATRIX_APPEND] + scale?: any [rotate? scale?] + if scale? [ ;@@ transform path will move it + GdipTransformPath brush n + GdipDeleteMatrix n + ] + + n: brush + GdipCreatePathGradientFromPath n :brush + GdipDeletePath n + GdipSetPathGradientCenterColor brush color/value + GdipSetPathGradientCenterPointI brush as tagPOINT :offset/x + reverse-int-array color count + n: count - 1 + start: 2 + while [start < n][ ;-- reverse position + sx: pos/start + pos/start: (as float32! 1.0) - pos/n + pos/n: (as float32! 1.0) - sx + n: n - 1 + start: start + 1 + ] + GdipSetPathGradientPresetBlend brush color pos count + + if any [ ;@@ move the shape back to the right position + all [type = radial scale?] + all [type = diamond rotate?] + ][ + GdipGetPathGradientCenterPointI brush pt + sx: as float32! x - pt/x + sy: as float32! y - pt/y + GdipTranslatePathGradientTransform brush sx sy GDIPLUS_MATRIX_APPEND + ] + ] + + ctx/other/GDI+?: yes + either brush? [ + unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] + ctx/brush?: yes + ctx/gp-brush: brush + ][ + GdipSetPenBrushFill ctx/gp-pen brush + ] +] + +OS-draw-grad-pen: func [ + ctx [draw-ctx!] + mode [integer!] + stops [red-value!] + count [integer!] + skip-pos [logic!] + positions [red-value!] + focal? [logic!] + spread [integer!] + brush? [logic!] + /local + x [integer!] + y [integer!] + start [integer!] + stop [integer!] + brush [integer!] + angle [float32!] + sx [float32!] + sy [float32!] + int [red-integer!] + f [red-float!] + head [red-value!] + next [red-value!] + clr [red-tuple!] + pt [tagPOINT] + color [int-ptr!] + last-c [int-ptr!] + pos [float32-ptr!] + last-p [float32-ptr!] + n [integer!] + delta [float!] + p [float!] + radius [integer!] + first-point [logic!] + last-point [logic!] + point [red-pair!] + value [red-value!] + _colors [int-ptr!] + _colors-pos [float32-ptr!] + gradient [gradient!] + gm [integer!] +][ + either brush? [ + ctx/other/gradient-fill?: true + _colors: ctx/other/gradient-fill/colors + _colors-pos: ctx/other/gradient-fill/colors-pos + ][ + ctx/other/gradient-pen?: true + _colors: ctx/other/gradient-pen/colors + _colors-pos: ctx/other/gradient-pen/colors-pos + ] + ;-- stops + pt: ctx/other/edges + color: _colors + 1 + pos: _colors-pos + 1 + delta: as-float count - 1 + delta: 1.0 / delta + p: 0.0 + head: stops + loop count [ + clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] + color/value: to-gdiplus-color clr/array1 + next: head + 1 + if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] + pos/value: either mode = linear [ as float32! p ][ as float32! ( 1.0 - p ) ] + if next <> head [p: p + delta] + head: head + 1 + color: color + 1 + pos: pos + 1 + ] + ;-- patch first and last point + last-p: pos - 1 + last-c: color - 1 + pos: pos - count + color: color - count + first-point: false + last-point: false + either mode = linear [ + _colors-pos/value: as float32! 0.0 ;-- first one should be always 0.0 + if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 + last-point: true + last-p: last-p + 1 + last-p/value: as float32! 1.0 + ] + ][ + _colors-pos/value: as float32! 1.0 ;-- first one should be always 1.0 + if last-p/value > as float32! 0.0 [ ;-- last one should be always 0.0 + last-point: true + last-p: last-p + 1 + last-p/value: as float32! 0.0 + ] + ] + _colors/value: color/value + count: count + 1 + if last-point [ + color: last-c + last-c: last-c + 1 + last-c/value: color/value + count: count + 1 + ] + gradient: either brush? [ctx/brush?: yes ctx/other/gradient-fill ][ ctx/other/gradient-pen ] + gradient/count: count + gradient/created?: false + gradient/positions?: false + gradient-transf-reset ctx gradient + + ;-- spread + case [ + spread = _pad [ gradient/spread: WRAP_MODE_TILE ] ;-- currently pad not supported by GDI+, fallback to repeat + spread = _repeat [ gradient/spread: WRAP_MODE_TILE ] + spread = _reflect [ gradient/spread: WRAP_MODE_TILE_FLIP_X ] + true [ gradient/spread: WRAP_MODE_TILE ] + ] + + ;-- positions + case [ + mode = linear [ + gradient/type: GRADIENT_LINEAR + unless skip-pos [ + gradient/positions?: true + pt: gradient/data + point: as red-pair! positions + pt/x: point/x pt/y: point/y + pt: pt + 1 + point: as red-pair! (positions + 1) + pt/x: point/x pt/y: point/y + gradient-linear ctx gradient gradient/data gradient/data + 1 + ] + ] + any [ mode = radial mode = diamond ][ + gradient/type: either mode = radial [ GRADIENT_RADIAL ][ GRADIENT_DIAMOND ] + unless skip-pos [ + gradient/positions?: true + pt: gradient/data + point: as red-pair! positions + pt/x: point/x pt/y: point/y + either mode = radial [ + value: positions + 1 + radius: as-integer get-float as red-integer! value + pt: pt + 1 + if focal? [ + point: as red-pair! ( positions + 2 ) + ] + pt/x: point/x pt/y: point/y + pt: pt + 1 + pt/x: radius + ][ + pt: pt + 1 + point: as red-pair! (positions + 1) + pt/x: point/x pt/y: point/y + pt: pt + 1 + either focal? [ + point: as red-pair! ( positions + 2 ) + pt/x: point/x + pt/y: point/y + ][ + pt/x: INVALID_RADIUS + ] + ] + gradient-radial-diamond ctx gradient gradient/data gradient/data + 1 pt/x + ] + ] + true [ gradient/type: GRADIENT_NONE ] + ] +] + +OS-set-clip: func [ + ctx [draw-ctx!] + u [red-pair!] + l [red-pair!] + rect? [logic!] + mode [integer!] + /local + dc [handle!] + clip-mode [integer!] +][ + case [ + mode = replace [clip-mode: clip-replace ctx] + mode = intersect [clip-mode: clip-intersect ctx] + mode = union [clip-mode: clip-union ctx] + mode = _xor [clip-mode: clip-xor ctx] + mode = exclude [clip-mode: clip-diff ctx] + true [clip-mode: clip-replace ctx] + ] + either ctx/other/GDI+? [ + either rect? [ + GdipSetClipRectI + ctx/graphics + u/x + u/y + l/x - u/x + l/y - u/y + clip-mode + ][ + GdipSetClipPath + ctx/graphics + ctx/gp-path + clip-mode + GdipDeletePath ctx/gp-path + ] + ][ + dc: ctx/dc + if rect? [ + BeginPath dc + Rectangle dc u/x u/y l/x l/y + ] + EndPath dc ;-- a path has already been started + SelectClipPath dc clip-mode + ] +] + +OS-matrix-rotate: func [ + ctx [draw-ctx!] + pen-fill [integer!] + angle [red-integer!] + center [red-pair!] + /local + brush [integer!] + gradient [gradient!] + pen? [logic!] + g [integer!] +][ + ctx/other/GDI+?: yes + either pen-fill <> -1 [ + ;-- rotate pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-rotate ctx gradient as-float angle/value + ;-- texture + brush: check-texture ctx pen? + texture-rotate as-float angle/value brush + ][ + ;-- rotate figure + g: ctx/graphics + if angle <> as red-integer! center [ + GdipTranslateWorldTransform g as float32! center/x as float32! center/y GDIPLUS_MATRIX_PREPEND + ] + GdipRotateWorldTransform g get-float32 angle GDIPLUS_MATRIX_PREPEND + if angle <> as red-integer! center [ + GdipTranslateWorldTransform g as float32! 0 - center/x as float32! 0 - center/y GDIPLUS_MATRIX_PREPEND + ] + ] +] + +OS-matrix-scale: func [ + ctx [draw-ctx!] + pen-fill [integer!] + sx [red-integer!] + sy [red-integer!] + /local + gradient [gradient!] + pen? [logic!] + brush [integer!] +][ + ctx/other/GDI+?: yes + either pen-fill <> -1 [ + ;-- scale pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-scale ctx gradient as-float sx/value as-float sy/value + ;-- texture + brush: check-texture ctx pen? + texture-scale as-float sx/value as-float sy/value brush + ][ + ;-- scale figure + GdipScaleWorldTransform ctx/graphics get-float32 sx get-float32 sy ctx/other/matrix-order + ] +] + +OS-matrix-translate: func [ + ctx [draw-ctx!] + pen-fill [integer!] + x [integer!] + y [integer!] + /local + gradient [gradient!] + pen? [logic!] + brush [integer!] +][ + ctx/other/GDI+?: yes + either pen-fill <> -1 [ + ;-- translate pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-translate ctx gradient as-float x as-float y + ;-- texture + brush: check-texture ctx pen? + texture-translate as-float x as-float y brush + ][ + ;-- translate figure + GdipTranslateWorldTransform + ctx/graphics + as float32! x + as float32! y + ctx/other/matrix-order + ] +] + +OS-matrix-skew: func [ + ctx [draw-ctx!] + pen-fill [integer!] + sx [red-integer!] + sy [red-integer!] + /local + m [integer!] + x [float32!] + y [float32!] + u [float32!] + z [float32!] + gradient [gradient!] +][ + either pen-fill <> -1 [ + ;-- skew pen or fill + gradient: either pen-fill = pen [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-skew ctx gradient as-float sx/value as-float sy/value + ][ + ;-- skew figure + m: 0 + u: as float32! 1.0 + z: as float32! 0.0 + x: as float32! tan degree-to-radians get-float sx TYPE_TANGENT + y: as float32! either sx = sy [0.0][tan degree-to-radians get-float sy TYPE_TANGENT] + GdipCreateMatrix2 u y x u z z :m + GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order + GdipDeleteMatrix m + ] +] + +OS-matrix-transform: func [ + ctx [draw-ctx!] + pen-fill [integer!] + center [red-pair!] + scale [red-integer!] + translate [red-pair!] + /local + rotate [red-integer!] + m [integer!] + gradient [gradient!] + pen? [logic!] + brush [integer!] + center? [logic!] +][ + rotate: as red-integer! either center + 1 = scale [center][center + 1] + center?: rotate <> center + + either pen-fill <> -1 [ + ;-- transform pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-translate ctx gradient as-float translate/x as-float translate/y + gradient-scale ctx gradient get-float scale get-float scale + 1 + gradient-rotate ctx gradient as-float rotate/value + ;-- texture + brush: check-texture ctx pen? + texture-translate as-float translate/x as-float translate/y brush + texture-scale get-float scale get-float scale + 1 brush + texture-rotate as-float rotate/value brush + ][ + ;-- transform figure + m: 0 + GdipCreateMatrix :m + + if center? [GdipTranslateMatrix m as float32! center/x as float32! center/y GDIPLUS_MATRIX_PREPEND] + GdipTranslateMatrix m as float32! translate/x as float32! translate/y GDIPLUS_MATRIX_PREPEND + GdipScaleMatrix m get-float32 scale get-float32 scale + 1 GDIPLUS_MATRIX_PREPEND + GdipRotateMatrix m get-float32 rotate GDIPLUS_MATRIX_PREPEND + if center? [GdipTranslateMatrix m as float32! 0 - center/x as float32! 0 - center/y GDIPLUS_MATRIX_PREPEND] + + GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order + GdipDeleteMatrix m + ] +] + +OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!] /local s][ + s: 0 + GdipSaveGraphics ctx/graphics :s + state/gstate: s + state/pen-clr: ctx/pen-color + state/brush-clr: ctx/brush-color + state/pen-join: ctx/pen-join + state/pen-cap: ctx/pen-cap + state/pen?: ctx/pen? + state/brush?: ctx/brush? + state/a-pen?: ctx/alpha-pen? + state/a-brush?: ctx/alpha-brush? +] + +OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][ + GdipRestoreGraphics ctx/graphics state/gstate + ctx/pen-join: state/pen-join + ctx/pen-cap: state/pen-cap + OS-draw-pen ctx state/pen-clr not state/pen? state/a-pen? + OS-draw-fill-pen ctx state/brush-clr not state/brush? state/a-brush? +] + +OS-matrix-reset: func [ + ctx [draw-ctx!] + pen-fill [integer!] + /local + gradient [gradient!] + pen? [logic!] + brush [integer!] +][ + either pen-fill <> -1 [ + ;-- reset matrix for pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-transf-reset ctx gradient + ;-- texture + brush: check-texture ctx pen? + texture-reset-matrix brush + ][ + ;-- reset matrix for figure + GdipResetWorldTransform ctx/graphics + ] + if ctx/scale-ratio <> as float32! 0.0 [ + GdipScaleWorldTransform ctx/graphics ctx/scale-ratio ctx/scale-ratio GDIPLUS_MATRIX_PREPEND + ] +] + +OS-matrix-invert: func [ + ctx [draw-ctx!] + pen-fill [integer!] + /local + m [integer!] + gradient [gradient!] + pen? [logic!] + brush [integer!] +][ + m: ctx/gp-matrix + if zero? m [ + GdipCreateMatrix :m + ctx/gp-matrix: m + ] + either pen-fill <> -1 [ + ;-- invert matrix for pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-invert-matrix ctx gradient + ;-- texture + brush: check-texture ctx pen? + texture-invert-matrix ctx brush + ][ + ;-- invert matrix for figure + GdipGetWorldTransform ctx/graphics m + GdipInvertMatrix m + GdipSetWorldTransform ctx/graphics m + ] +] + +OS-matrix-set: func [ + ctx [draw-ctx!] + pen-fill [integer!] + blk [red-block!] + /local + m [integer!] + val [red-integer!] + gradient [gradient!] + pen? [logic!] + brush [integer!] +][ + m: 0 + val: as red-integer! block/rs-head blk + GdipCreateMatrix2 + get-float32 val + get-float32 val + 1 + get-float32 val + 2 + get-float32 val + 3 + get-float32 val + 4 + get-float32 val + 5 + :m + either pen-fill <> -1 [ + ;-- set matrix for pen or fill + pen?: either pen-fill = pen [ true ][ false ] + ;-- gradient + gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] + gradient-set-matrix ctx gradient m + ;-- texture + brush: check-texture ctx pen? + texture-set-matrix m brush + ][ + ;-- set matrix for figure + GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order + ] + GdipDeleteMatrix m +] + +OS-set-matrix-order: func [ + ctx [draw-ctx!] + order [integer!] +][ + case [ + order = _append [ ctx/other/matrix-order: GDIPLUS_MATRIX_APPEND ] + order = prepend [ ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND ] + true [ ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND ] + ] +] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 59fc6be4a4..f2225673dd 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1,810 +1,197 @@ Red/System [ - Title: "Windows Draw dialect backend" - Author: "Nenad Rakocevic" - File: %draw.reds - Tabs: 4 - Rights: "Copyright (C) 2015-2018 Red Foundation. All rights reserved." + Title: "DRAW Direct2D Backend" + Author: "Xie Qingtian" + File: %draw.reds + Tabs: 4 + Rights: "Copyright (C) 2016-2018 Red Foundation. All rights reserved." License: { Distributed under the Boost Software License, Version 1.0. See https://github.com/red/red/blob/master/BSL-License.txt } ] -xform: declare XFORM! +#include %text-box.reds -#define SHAPE_OTHER 0 -#define SHAPE_CURVE 1 -#define SHAPE_QCURVE 2 - -#define GRADIENT_NONE 0 -#define GRADIENT_LINEAR 1 -#define GRADIENT_RADIAL 2 -#define GRADIENT_DIAMOND 3 - -#define INVALID_RADIUS -1 -#define INDEX_UPPER 0 -#define INDEX_LOWER 1 -#define INDEX_OTHER 2 - -#define INIT_GRADIENT_DATA(upper lower other) [ - upper: gradient/data + INDEX_UPPER - lower: gradient/data + INDEX_LOWER - other: gradient/data + INDEX_OTHER -] - -#define MAX_GRADIENT_DATA 5 -#define MAX_EDGES 1000 ;-- max number of edges for a polygone -#define MAX_COLORS 256 ;-- max number of colors for gradient - -#define ALLOC_REENTRANT(type) [ - as type allocate size? type -] -#define ALLOC_REENTRANT_ELEMS(type1 type2 count) [ - as type1 allocate count * (size? type2) -] -#define ALLOC_REENTRANT_BYTES(count) [ - allocate count -] -#define FREE_REENTRANT(word) [ - free as byte-ptr! word -] -#define FREE_REENTRANT_BYTES(word) [ - free word -] - -draw-state!: alias struct! [ - gstate [integer!] - pen-clr [integer!] - brush-clr [integer!] - pen-join [integer!] - pen-cap [integer!] - pen? [logic!] - brush? [logic!] - a-pen? [logic!] - a-brush? [logic!] -] - -alloc-context: func [ - ctx [draw-ctx!] - /local - max-colors [integer!] -][ - max-colors: 2 * MAX_COLORS - ctx/other: ALLOC_REENTRANT(other!) - ctx/other/gradient-pen: ALLOC_REENTRANT(gradient!) - ctx/other/gradient-pen/path-data: ALLOC_REENTRANT(PATHDATA) - ctx/other/gradient-pen/data: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_GRADIENT_DATA) - ctx/other/gradient-pen/colors: ALLOC_REENTRANT_ELEMS(int-ptr! integer! max-colors) - ctx/other/gradient-pen/colors-pos: as float32-ptr! ctx/other/gradient-pen/colors + MAX_COLORS - ctx/other/gradient-fill: ALLOC_REENTRANT(gradient!) - ctx/other/gradient-fill/path-data: ALLOC_REENTRANT(PATHDATA) - ctx/other/gradient-fill/data: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_GRADIENT_DATA) - ctx/other/gradient-fill/colors: ALLOC_REENTRANT_ELEMS(int-ptr! integer! max-colors) - ctx/other/gradient-fill/colors-pos: as float32-ptr! ctx/other/gradient-fill/colors + MAX_COLORS - ctx/other/matrix-elems: ALLOC_REENTRANT_ELEMS(float32-ptr! float32! 6) - ctx/other/paint: ALLOC_REENTRANT(tagPAINTSTRUCT) - ctx/other/edges: ALLOC_REENTRANT_ELEMS(tagPOINT tagPOINT MAX_EDGES) - ctx/other/types: ALLOC_REENTRANT_BYTES(MAX_EDGES) - ctx/other/path-last-point: ALLOC_REENTRANT(tagPOINT) - ctx/other/prev-shape: ALLOC_REENTRANT(curve-info!) - ctx/other/prev-shape/control: ALLOC_REENTRANT(tagPOINT) - ctx/other/pattern-image-fill: ALLOC_REENTRANT_ELEMS(integer! red-image! 1) - ctx/other/pattern-image-pen: ALLOC_REENTRANT_ELEMS(integer! red-image! 1) -] - -free-context: func [ - ctx [draw-ctx!] -][ - FREE_REENTRANT(ctx/other/pattern-image-pen) - FREE_REENTRANT(ctx/other/pattern-image-fill) - FREE_REENTRANT(ctx/other/prev-shape/control) - FREE_REENTRANT(ctx/other/prev-shape) - FREE_REENTRANT(ctx/other/path-last-point) - FREE_REENTRANT_BYTES(ctx/other/types) - FREE_REENTRANT(ctx/other/edges) - FREE_REENTRANT(ctx/other/paint) - FREE_REENTRANT(ctx/other/matrix-elems) - FREE_REENTRANT(ctx/other/gradient-fill/colors) - FREE_REENTRANT(ctx/other/gradient-fill/data) - FREE_REENTRANT(ctx/other/gradient-fill/path-data) - FREE_REENTRANT(ctx/other/gradient-fill) - FREE_REENTRANT(ctx/other/gradient-pen/colors) - FREE_REENTRANT(ctx/other/gradient-pen/data) - FREE_REENTRANT(ctx/other/gradient-pen/path-data) - FREE_REENTRANT(ctx/other/gradient-pen) - FREE_REENTRANT(ctx/other) -] - -clip-replace: func [ ctx [draw-ctx!] return: [integer!] ][ - either ctx/other/GDI+? [GDIPLUS_COMBINEMODEREPLACE][RGN_COPY] -] -clip-intersect: func [ ctx [draw-ctx!] return: [integer!] ][ - either ctx/other/GDI+? [GDIPLUS_COMBINEMODEINTERSECT][RGN_AND] -] -clip-union: func [ ctx [draw-ctx!] return: [integer!] ][ - either ctx/other/GDI+? [GDIPLUS_COMBINEMODEUNION][RGN_OR] -] -clip-xor: func [ ctx [draw-ctx!] return: [integer!] ][ - either ctx/other/GDI+? [GDIPLUS_COMBINEMODEXOR][RGN_XOR] -] -clip-diff: func [ ctx [draw-ctx!] return: [integer!] ][ - either ctx/other/GDI+? [GDIPLUS_COMBINEMODEEXCLUDE][RGN_DIFF] -] - -update-gdiplus-font-color: func [ctx [draw-ctx!] color [integer!] /local brush [integer!]][ - if ctx/font-color <> color [ - unless zero? ctx/gp-font-brush [ - GdipDeleteBrush ctx/gp-font-brush - ctx/gp-font-brush: 0 - ] - ctx/font-color: color - brush: 0 - GdipCreateSolidFill to-gdiplus-color-fixed color :brush - ctx/gp-font-brush: brush - ] -] - -update-gdiplus-font: func [ctx [draw-ctx!] /local font [integer!]][ - font: 0 - unless zero? ctx/gp-font [GdipDeleteFont ctx/gp-font] - GdipCreateFontFromDC as-integer ctx/dc :font - ctx/gp-font: font -] - -update-gdiplus-modes: func [ctx [draw-ctx!] ][ - update-gdiplus-pen ctx - update-gdiplus-brush ctx -] - -update-gdiplus-brush: func [ctx [draw-ctx!] /local handle [integer!]][ - handle: 0 - ctx/gp-brush-type: BRUSH_TYPE_NORMAL - ctx/other/gradient-fill?: false - unless zero? ctx/gp-brush [ - GdipDeleteBrush ctx/gp-brush - ctx/gp-brush: 0 - ] - if ctx/brush? [ - GdipCreateSolidFill to-gdiplus-color-fixed ctx/brush-color :handle - ctx/gp-brush: handle - ] -] - -update-gdiplus-pen: func [ctx [draw-ctx!] /local handle [integer!]][ - ctx/gp-pen-type: BRUSH_TYPE_NORMAL - ctx/other/gradient-pen?: false - either ctx/pen? [ - if ctx/gp-pen-saved <> 0 [ - ctx/gp-pen: ctx/gp-pen-saved - ctx/gp-pen-saved: 0 - ] - handle: ctx/gp-pen - GdipSetPenColor handle to-gdiplus-color ctx/pen-color - GdipSetPenWidth handle ctx/pen-width - if ctx/pen-join <> 0 [ - OS-draw-line-join ctx ctx/pen-join - ] - if ctx/pen-cap <> 0 [ - OS-draw-line-cap ctx ctx/pen-cap - ] - ][ - ctx/gp-pen-saved: ctx/gp-pen - ctx/gp-pen: 0 - ] -] - -update-brush: func [ctx [draw-ctx!] /local handle [handle!]][ - if 0 <> ctx/brush [DeleteObject as handle! ctx/brush] - handle: either ctx/brush? [ - CreateSolidBrush ctx/brush-color - ][ - GetStockObject NULL_BRUSH - ] - ctx/brush: as-integer handle - SelectObject ctx/dc handle -] - -update-pen: func [ - ctx [draw-ctx!] - /local - mode [integer!] - cap [integer!] - join [integer!] - pen [handle!] - brush [tagLOGBRUSH] -][ - mode: 0 - if 0 <> ctx/pen [DeleteObject as handle! ctx/pen] - either ctx/pen? [ - cap: ctx/pen-cap - join: ctx/pen-join - pen: either all [join = -1 cap = -1] [ - CreatePen ctx/pen-style as integer! ctx/pen-width ctx/pen-color - ][ - if join <> -1 [ - mode: case [ - join = miter [PS_JOIN_MITER] - join = miter-bevel [PS_JOIN_MITER] - join = _round [PS_JOIN_ROUND] - join = bevel [PS_JOIN_BEVEL] - true [PS_JOIN_MITER] - ] - ] - if cap <> -1 [ - mode: mode or case [ - cap = flat [PS_ENDCAP_FLAT] - cap = square [PS_ENDCAP_SQUARE] - cap = _round [PS_ENDCAP_ROUND] - true [PS_ENDCAP_FLAT] - ] - ] - brush: declare tagLOGBRUSH - brush/lbStyle: BS_SOLID - brush/lbColor: ctx/pen-color - ExtCreatePen - PS_GEOMETRIC or ctx/pen-style or mode - as integer! ctx/pen-width - brush - 0 - null - ] - ctx/pen: as-integer pen - ][ - pen: GetStockObject NULL_PEN - ctx/pen: 0 - ] - SelectObject ctx/dc pen -] - -update-modes: func [ - ctx [draw-ctx!] -][ - either ctx/other/GDI+? [ - update-gdiplus-modes ctx - ][ - update-pen ctx - update-brush ctx - ] -] +draw-state!: alias struct! [unused [integer!]] draw-begin: func [ ctx [draw-ctx!] hWnd [handle!] - img [red-image!] - on-graphic? [logic!] - paint? [logic!] - return: [draw-ctx!] - /local - dc [handle!] - rect [RECT_STRUCT value] - width [integer!] - height [integer!] - hBitmap [handle!] - hBackDC [handle!] - graphics [integer!] - ptrn [red-image!] - ratio [float32!] -][ - zero-memory as byte-ptr! ctx size? draw-ctx! - alloc-context ctx - - ctx/pen-width: as float32! 1.0 - ctx/pen?: yes - ctx/hwnd: hWnd - ctx/font-color: -1 - ctx/gp-brush-type: BRUSH_TYPE_NORMAL - ctx/gp-pen-type: BRUSH_TYPE_NORMAL - dc: null - - ctx/other/gradient-pen/extra: 0 - ctx/other/gradient-pen/matrix: 0 - ctx/other/gradient-pen/spread: WRAP_MODE_TILE - ctx/other/gradient-pen/type: GRADIENT_NONE - ctx/other/gradient-pen/count: 0 - ctx/other/gradient-pen/positions?: false - ctx/other/gradient-pen/created?: false - ctx/other/gradient-pen/transformed?: false - ctx/other/gradient-fill/extra: 0 - ctx/other/gradient-fill/matrix: 0 - ctx/other/gradient-fill/spread: WRAP_MODE_TILE - ctx/other/gradient-fill/type: GRADIENT_NONE - ctx/other/gradient-fill/count: 0 - ctx/other/gradient-fill/positions?: false - ctx/other/gradient-fill/created?: false - ctx/other/gradient-fill/transformed?: false - ctx/other/gradient-pen?: false - ctx/other/gradient-fill?: false - ctx/other/D2D?: (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 - ctx/other/GDI+?: no - ctx/other/last-point?: no - ctx/other/prev-shape/type: SHAPE_OTHER - ctx/other/path-last-point/x: 0 - ctx/other/path-last-point/y: 0 - ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND - ctx/other/connect-subpath: 0 - ctx/other/anti-alias?: no - ptrn: as red-image! ctx/other/pattern-image-fill - ptrn/node: null - ptrn: as red-image! ctx/other/pattern-image-pen - ptrn/node: null - - either null? hWnd [ - ctx/on-image?: yes - either on-graphic? [ - graphics: as-integer img - ][ - graphics: 0 - OS-image/GdipGetImageGraphicsContext as-integer img/node :graphics - ] - dc: CreateCompatibleDC hScreen - SelectObject dc default-font - SetTextColor dc ctx/pen-color - ctx/dc: dc - update-gdiplus-font-color ctx ctx/pen-color - ][ - either ctx/other/D2D? [ - draw-begin-d2d ctx hWnd - return ctx - ][ - either null? img [ - dc: either paint? [BeginPaint hWnd ctx/other/paint][hScreen] - GetClientRect hWnd rect - width: rect/right - rect/left - height: rect/bottom - rect/top - hBitmap: CreateCompatibleBitmap dc width height - hBackDC: CreateCompatibleDC dc - SelectObject hBackDC hBitmap - ctx/bitmap: hBitmap - ][ - hBackDC: as handle! img - ] - - dc: hBackDC - ctx/dc: dc - - SetGraphicsMode dc GM_ADVANCED - SetArcDirection dc AD_CLOCKWISE - SetBkMode dc BK_TRANSPARENT - SelectObject dc GetStockObject NULL_BRUSH - - render-base hWnd dc - - graphics: 0 - GdipCreateFromHDC dc :graphics - SelectObject dc GetStockObject NULL_BRUSH - SelectObject dc default-font - - update-gdiplus-font-color ctx ctx/pen-color - ] - ] - - if any [hWnd <> null on-graphic?][ - if dpi-factor <> 100 [ - ratio: (as float32! dpi-factor) / (as float32! 100.0) - GdipScaleWorldTransform graphics ratio ratio GDIPLUS_MATRIX_PREPEND - ctx/scale-ratio: ratio - ] - ] - - ctx/graphics: graphics - GdipCreatePen1 - to-gdiplus-color ctx/pen-color - ctx/pen-width - GDIPLUS_UNIT_WORLD - :graphics - ctx/gp-pen: graphics - OS-draw-anti-alias ctx yes - update-gdiplus-font ctx - ctx -] - -draw-end: func [ - ctx [draw-ctx!] - hWnd [handle!] - on-graphic? [logic!] - cache? [logic!] - paint? [logic!] /local - hr [integer!] - IUnk [IUnknown] this [this!] - pad4 [integer!] - rect [RECT_STRUCT] - width [integer!] - height [integer!] - bitmap [integer!] - old-dc [integer!] - dc [handle!] - ptrn [red-image!] + rt [ID2D1HwndRenderTarget] + _11 [integer!] + _12 [integer!] + _21 [integer!] + _22 [integer!] + _31 [integer!] + _32 [integer!] + m [D2D_MATRIX_3X2_F] + bg-clr [integer!] + brush [integer!] + target [int-ptr!] + brushes [int-ptr!] + pbrush [ID2D1SolidColorBrush] + d3d-clr [D3DCOLORVALUE] + values [red-value!] + clr [red-tuple!] + text [red-string!] + pos [red-pair! value] ][ - if ctx/other/D2D? [ - draw-end-d2d ctx hWnd - free-context ctx - exit - ] - - dc: ctx/dc - pad4: 0 - rect: as RECT_STRUCT :pad4 - if paint? [ - GetClientRect hWnd rect - width: rect/right - rect/left - height: rect/bottom - rect/top - BitBlt ctx/other/paint/hdc 0 0 width height dc 0 0 SRCCOPY - ] + zero-memory as byte-ptr! ctx size? draw-ctx! + ctx/pen-width: as float32! 1.0 + ctx/pen?: yes + ctx/hwnd: hWnd + ctx/font-color: -1 + + target: get-hwnd-render-target hWnd + this: as this! target/value + ctx/dc: as handle! this + ctx/brushes: target + + rt: as ID2D1HwndRenderTarget this/vtbl + rt/SetTextAntialiasMode this 1 ;-- ClearType + + rt/BeginDraw this + _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 + m: as D2D_MATRIX_3X2_F :_32 + m/_11: as float32! 1.0 + m/_22: as float32! 1.0 + rt/SetTransform this m ;-- set to identity matrix + + values: get-face-values hWnd + clr: as red-tuple! values + FACE_OBJ_COLOR + bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1] + if bg-clr <> -1 [ ;-- paint background + rt/Clear this to-dx-color bg-clr null + ] + + d3d-clr: to-dx-color ctx/pen-color null + brush: 0 + rt/CreateSolidColorBrush this d3d-clr null :brush + ctx/pen: brush - unless any [on-graphic? zero? ctx/graphics][GdipDeleteGraphics ctx/graphics] - unless zero? ctx/gp-pen [GdipDeletePen ctx/gp-pen] - unless zero? ctx/gp-pen-saved [GdipDeletePen ctx/gp-pen-saved] - unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] - unless zero? ctx/gp-font-brush [GdipDeleteBrush ctx/gp-font-brush] - unless zero? ctx/gp-font [GdipDeleteFont ctx/gp-font] - unless zero? ctx/image-attr [GdipDisposeImageAttributes ctx/image-attr] - unless zero? ctx/gp-matrix [GdipDeleteMatrix ctx/gp-matrix] - unless zero? ctx/pen [DeleteObject as handle! ctx/pen] - unless zero? ctx/brush [DeleteObject as handle! ctx/brush] - unless zero? ctx/other/gradient-pen/matrix [ GdipDeleteMatrix ctx/other/gradient-pen/matrix ] - unless zero? ctx/other/gradient-fill/matrix [ GdipDeleteMatrix ctx/other/gradient-fill/matrix ] - ptrn: as red-image! ctx/other/pattern-image-fill - unless null? ptrn/node [ - OS-image/delete as red-image! ctx/other/pattern-image-fill - ] - ptrn: as red-image! ctx/other/pattern-image-pen - unless null? ptrn/node [ - OS-image/delete as red-image! ctx/other/pattern-image-pen - ] + brush: 0 + rt/CreateSolidColorBrush this d3d-clr null :brush + ctx/brush: brush - if ctx/bitmap <> null [DeleteObject ctx/bitmap] - either cache? [ - old-dc: GetWindowLong hWnd wc-offset - 4 - unless zero? old-dc [DeleteDC as handle! old-dc] - SetWindowLong hWnd wc-offset - 4 as-integer dc - ][ - DeleteDC dc + text: as red-string! values + FACE_OBJ_TEXT + if TYPE_OF(text) = TYPE_STRING [ + pos/x: 0 pos/y: 0 + OS-draw-text ctx pos as red-string! get-face-obj hWnd yes ] - if all [hWnd <> null paint?][EndPaint hWnd ctx/other/paint] - - free-context ctx ] -to-gdiplus-color: func [ - color [integer!] - return: [integer!] +release-d2d: func [ + ctx [draw-ctx!] /local - red [integer!] - green [integer!] - blue [integer!] - alpha [integer!] + IUnk [IUnknown] + this [this!] ][ - red: color and FFh << 16 - green: color and FF00h - blue: color >> 16 and FFh - alpha: FF000000h and not color - red or green or blue or alpha + ;;TBD release all brushes when D2DERR_RECREATE_TARGET or exit the process + COM_SAFE_RELEASE_OBJ(IUnk ctx/pen) + COM_SAFE_RELEASE_OBJ(IUnk ctx/brush) ] -;-- see https://stackoverflow.com/questions/4258295/aero-how-to-draw-solid-opaque-colors-on-glass -; and https://stackoverflow.com/questions/5647322/gdi-font-rendering-especially-in-layered-windows -; GDI+ is often buggy when alpha=255 (fully opaque) -to-gdiplus-color-fixed: func [ - color [integer!] - return: [integer!] +draw-end: func [ + ctx [draw-ctx!] + hWnd [handle!] /local - r [integer!] -][ - r: to-gdiplus-color color - if r >>> 24 = FFh [r: r xor 01000000h] - r -] - -radian-to-degrees: func [ - radians [float!] - return: [float!] -][ - (radians * 180.0) / PI -] - -adjust-angle: func [ - x [float!] - y [float!] - angle [float!] - return: [float!] + this [this!] + rt [ID2D1HwndRenderTarget] + hr [integer!] ][ - case [ - all [ x >= 0.0 y <= 0.0 ] [ either angle = 0.0 [0.0 - angle][360.0 - angle] ] - all [ x <= 0.0 y >= 0.0 ] [ 180.0 - angle ] - all [ x <= 0.0 y <= 0.0 ] [ 180.0 + angle ] - true [ angle ] - ] -] + this: as this! ctx/dc + rt: as ID2D1HwndRenderTarget this/vtbl + hr: rt/EndDraw this null null -set-matrix: func [ - xform [XFORM!] - eM11 [float!] - eM12 [float!] - eM21 [float!] - eM22 [float!] - eDx [float!] - eDy [float!] -][ - xform/eM11: as float32! eM11 - xform/eM12: as float32! eM12 - xform/eM21: as float32! eM21 - xform/eM22: as float32! eM22 - xform/eDx: as float32! eDx - xform/eDy: as float32! eDy -] + release-d2d ctx -gdi-calc-arc: func [ - center-x [float!] - center-y [float!] - rad-x [float!] - rad-y [float!] - angle-begin [float!] - angle-len [float!] - return: [arcPOINTS!] - /local - radius [red-pair!] - angle [red-integer!] - start-x [float!] - start-y [float!] - end-x [float!] - end-y [float!] - rad-x-float [float32!] - rad-y-float [float32!] - rad-x-2 [float32!] - rad-y-2 [float32!] - rad-x-y [float32!] - tan-2 [float32!] - rad-beg [float!] - rad-end [float!] - points [arcPOINTS!] -][ - points: declare arcPOINTS! - rad-x-float: as float32! rad-x - rad-y-float: as float32! rad-y - - either rad-x = rad-y [ ;-- circle - rad-beg: degree-to-radians angle-begin TYPE_SINE - rad-end: degree-to-radians angle-begin + angle-len TYPE_SINE - start-y: center-y + (rad-y-float * sin rad-beg) - end-y: center-y + (rad-y-float * sin rad-end) - rad-beg: degree-to-radians angle-begin TYPE_COSINE - rad-end: degree-to-radians angle-begin + angle-len TYPE_COSINE - start-x: center-x + (rad-x-float * cos rad-beg) - end-x: center-x + (rad-x-float * cos rad-end) - ][ - rad-beg: degree-to-radians angle-begin TYPE_TANGENT - rad-end: degree-to-radians angle-begin + angle-len TYPE_TANGENT - rad-x-y: rad-x-float * rad-y-float - rad-x-2: rad-x-float * rad-x-float - rad-y-2: rad-y-float * rad-y-float - tan-2: as float32! tan rad-beg - tan-2: tan-2 * tan-2 - start-x: as float! rad-x-y / (sqrt as-float rad-x-2 * tan-2 + rad-y-2) - start-y: as float! rad-x-y / (sqrt as-float rad-y-2 / tan-2 + rad-x-2) - if all [angle-begin > 90.0 angle-begin < 270.0][start-x: 0.0 - start-x] - if all [angle-begin > 180.0 angle-begin < 360.0][start-y: 0.0 - start-y] - start-x: center-x + start-x - start-y: center-y + start-y - angle-begin: angle-begin + angle-len - tan-2: as float32! tan rad-end - tan-2: tan-2 * tan-2 - end-x: as float! rad-x-y / (sqrt as-float rad-x-2 * tan-2 + rad-y-2) - end-y: as float! rad-x-y / (sqrt as-float rad-y-2 / tan-2 + rad-x-2) - if angle-begin < 0.0 [ angle-begin: 360.0 + angle-begin] - if all [angle-begin > 90.0 angle-begin < 270.0][end-x: 0.0 - end-x] - if all [angle-begin > 180.0 angle-begin < 360.0][end-y: 0.0 - end-y] - end-x: center-x + end-x - end-y: center-y + end-y + switch hr [ + COM_S_OK [ValidateRect hWnd null] + D2DERR_RECREATE_TARGET [ + d2d-release-target ctx/brushes + ctx/dc: null + SetWindowLong hWnd wc-offset - 24 0 + InvalidateRect hWnd null 0 + ] + default [ + 0 ;@@ TBD log error!!! + ] ] - points/start-x: start-x - points/start-y: start-y - points/end-x: end-x - points/end-y: end-y - points ] -draw-curves: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] - nr-points [integer!] +OS-draw-pen: func [ + ctx [draw-ctx!] + color [integer!] + off? [logic!] /local - point [tagPOINT] - pair [red-pair!] - pt [tagPOINT] - nb [integer!] - count [integer!] + this [this!] + brush [ID2D1SolidColorBrush] ][ - pt: ctx/other/edges - pair: start - nb: 0 - count: (as-integer end - pair) >> 4 + 1 - while [ all [ pair <= end nb < MAX_EDGES count >= nr-points ] ][ - pt/x: ctx/other/path-last-point/x - pt/y: ctx/other/path-last-point/y - while [ nb < 3 ][ - nb: nb + 1 - pt: pt + 1 - pt/x: either rel? [ pair/x + ctx/other/path-last-point/x ][ pair/x ] - pt/y: either rel? [ pair/y + ctx/other/path-last-point/y ][ pair/y ] - if nb < nr-points [ pair: pair + 1 ] - ] - ctx/other/path-last-point/x: pt/x - ctx/other/path-last-point/y: pt/y - either ctx/other/GDI+? [ - GdipAddPathBeziersI ctx/gp-path ctx/other/edges nb + 1 - ][ - PolyBezier ctx/dc ctx/other/edges nb + 1 + if any [ctx/pen-color <> color ctx/pen? = off?][ + ctx/pen?: not off? + ctx/pen-color: color + if ctx/pen? [ + this: as this! ctx/pen + brush: as ID2D1SolidColorBrush this/vtbl + brush/SetColor this to-dx-color color null ] - - count: (as-integer end - pair) >> 4 - nb: 0 - pt: ctx/other/edges - pair: pair + 1 ] - ctx/other/last-point?: yes - point: ctx/other/edges + nr-points - 1 - ctx/other/prev-shape/type: SHAPE_CURVE - ctx/other/prev-shape/control/x: point/x - ctx/other/prev-shape/control/y: point/y - ctx/other/connect-subpath: 1 ] -draw-short-curves: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] - nr-points [integer!] +OS-draw-text: func [ + ctx [draw-ctx!] + pos [red-pair!] + text [red-string!] + catch? [logic!] + return: [logic!] /local - pair [red-pair!] - pt [tagPOINT] - nb [integer!] - control [tagPOINT value] - count [integer!] + this [this!] + rt [ID2D1HwndRenderTarget] + layout [this!] + fmt [this!] ][ - pt: ctx/other/edges - nb: 0 - pair: start - either ctx/other/prev-shape/type = SHAPE_CURVE [ - control/x: ctx/other/prev-shape/control/x - control/y: ctx/other/prev-shape/control/y - ][ - control/x: ctx/other/path-last-point/x - control/y: ctx/other/path-last-point/y - ] - while [ pair <= end ][ - pt/x: ctx/other/path-last-point/x - pt/y: ctx/other/path-last-point/y - pt: pt + 1 - pt/x: ( 2 * ctx/other/path-last-point/x ) - control/x - pt/y: ( 2 * ctx/other/path-last-point/y ) - control/y - control/x: pt/x - control/y: pt/y - pt: pt + 1 - pt/x: either rel? [ ctx/other/path-last-point/x + pair/x ][ pair/x ] - pt/y: either rel? [ ctx/other/path-last-point/y + pair/y ][ pair/y ] - pt: pt + 1 - loop nr-points - 1 [ pair: pair + 1 ] - if pair <= end [ - pt/x: either rel? [ ctx/other/path-last-point/x + pair/x ][ pair/x ] - pt/y: either rel? [ ctx/other/path-last-point/y + pair/y ][ pair/y ] - ctx/other/last-point?: yes - ctx/other/path-last-point/x: pt/x - ctx/other/path-last-point/y: pt/y - pair: pair + 1 - nb: nb + 4 - ] - either ctx/other/GDI+? [ - GdipAddPathBeziersI ctx/gp-path ctx/other/edges nb - ][ - PolyBezier ctx/dc ctx/other/edges nb - ] - ctx/other/prev-shape/type: SHAPE_CURVE - ctx/other/prev-shape/control/x: control/x - ctx/other/prev-shape/control/y: control/y + this: as this! ctx/dc + rt: as ID2D1HwndRenderTarget this/vtbl - pt: ctx/other/edges - nb: 0 + layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! + OS-text-box-layout as red-object! text ctx/brushes 0 yes + ][ + fmt: as this! create-text-format as red-object! text null + create-text-layout text fmt 0 0 ] - ctx/other/connect-subpath: 1 + txt-box-draw-background ctx/brushes pos layout + rt/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 + true ] OS-draw-shape-beginpath: func [ ctx [draw-ctx!] - /local - path [integer!] ][ - ctx/other/connect-subpath: 0 - either ctx/other/GDI+? [ - path: 0 - GdipCreatePath 0 :path ; alternate fill - ctx/gp-path: path - GdipStartPathFigure ctx/gp-path - ][ - update-modes ctx - BeginPath ctx/dc - ] + ] OS-draw-shape-endpath: func [ ctx [draw-ctx!] close? [logic!] return: [logic!] - /local - alpha [byte!] - width [integer!] - height [integer!] - ftn [integer!] - bf [tagBLENDFUNCTION] - count [integer!] - result [logic!] - point [tagPOINT] - dc [handle!] ][ - result: true - - either ctx/other/GDI+? [ - count: 0 - GdipGetPointCount ctx/gp-path :count - if count > 0 [ - check-gradient-shape ctx ;-- check for gradient - check-texture-shape ctx - if close? [ GdipClosePathFigure ctx/gp-path ] - GdipDrawPath ctx/graphics ctx/gp-pen ctx/gp-path - GdipFillPath ctx/graphics ctx/gp-brush ctx/gp-path - GdipDeletePath ctx/gp-path - ] - ][ - dc: ctx/dc - if close? [ CloseFigure dc ] - EndPath dc - count: GetPath dc ctx/other/edges ctx/other/types 0 - if count > 0 [ - count: GetPath dc ctx/other/edges ctx/other/types count - FillPath dc - PolyDraw dc ctx/other/edges ctx/other/types count - ] - ] - result + ] OS-draw-shape-close: func [ ctx [draw-ctx!] ][ - either ctx/other/GDI+? [ - GdipClosePathFigure ctx/gp-path - ][ - CloseFigure ctx/dc - ] + ] OS-draw-shape-moveto: func [ ctx [draw-ctx!] coord [red-pair!] rel? [logic!] - /local - pt [tagPOINT] ][ - either all [ rel? ctx/other/last-point? ][ - ctx/other/path-last-point/x: ctx/other/path-last-point/x + coord/x - ctx/other/path-last-point/y: ctx/other/path-last-point/y + coord/y - ][ - ctx/other/path-last-point/x: coord/x - ctx/other/path-last-point/y: coord/y - ] - ctx/other/connect-subpath: 0 - ctx/other/last-point?: yes - ctx/other/prev-shape/type: SHAPE_OTHER - either ctx/other/GDI+? [ - GdipStartPathFigure ctx/gp-path - ][ - pt: declare tagPOINT - MoveToEx ctx/dc ctx/other/path-last-point/x ctx/other/path-last-point/y pt - ] + ] OS-draw-shape-line: func [ @@ -812,43 +199,8 @@ OS-draw-shape-line: func [ start [red-pair!] end [red-pair!] rel? [logic!] - /local - pt [tagPOINT] - nb [integer!] - pair [red-pair!] ][ - pt: ctx/other/edges - pair: start - nb: 0 - - if ctx/other/last-point? [ - pt/x: ctx/other/path-last-point/x - pt/y: ctx/other/path-last-point/y - pt: pt + 1 - nb: nb + 1 - ] - while [all [pair <= end nb < MAX_EDGES]][ - pt/x: pair/x - pt/y: pair/y - if rel? [ - pt/x: pt/x + ctx/other/path-last-point/x - pt/y: pt/y + ctx/other/path-last-point/y - ] - ctx/other/path-last-point/x: pt/x - ctx/other/path-last-point/y: pt/y - nb: nb + 1 - pt: pt + 1 - pair: pair + 1 - ] - either ctx/other/GDI+? [ - GdipAddPathLine2I ctx/gp-path ctx/other/edges nb - ][ - Polyline ctx/dc ctx/other/edges nb - ] - ctx/other/last-point?: yes - ctx/other/prev-shape/type: SHAPE_OTHER - ctx/other/connect-subpath: 1 ] OS-draw-shape-axis: func [ @@ -857,62 +209,8 @@ OS-draw-shape-axis: func [ end [red-value!] rel? [logic!] hline [logic!] - /local - pt [tagPOINT] - nb [integer!] - coord [red-value!] - coord-v [integer!] - coord-f [red-float!] - coord-i [red-integer!] ][ - if ctx/other/last-point? [ - pt: ctx/other/edges - nb: 0 - coord: start - - pt/x: ctx/other/path-last-point/x - pt/y: ctx/other/path-last-point/y - pt: pt + 1 - nb: nb + 1 - coord-v: 0 - until [ - either TYPE_OF(coord) = TYPE_INTEGER [ - coord-i: as red-integer! coord - coord-v: coord-i/value - ][ - coord-f: as red-float! coord - coord-v: as integer! coord-f/value - ] - case [ - hline [ - either rel? [ - pt/x: ctx/other/path-last-point/x + coord-v - ][ pt/x: coord-v ] - pt/y: ctx/other/path-last-point/y - ctx/other/path-last-point/x: pt/x - ] - true [ - either rel? [ - pt/y: ctx/other/path-last-point/y + coord-v - ][ pt/y: coord-v ] - pt/x: ctx/other/path-last-point/x - ctx/other/path-last-point/y: pt/y - ] - ] - coord: coord + 1 - nb: nb + 1 - pt: pt + 1 - any [ coord > end nb >= MAX_EDGES ] - ] - ctx/other/last-point?: yes - either ctx/other/GDI+? [ - GdipAddPathLine2I ctx/gp-path ctx/other/edges nb - ][ - Polyline ctx/dc ctx/other/edges nb - ] - ctx/other/prev-shape/type: SHAPE_OTHER - ctx/other/connect-subpath: 1 - ] + ] OS-draw-shape-curve: func [ @@ -921,7 +219,7 @@ OS-draw-shape-curve: func [ end [red-pair!] rel? [logic!] ][ - draw-curves ctx start end rel? 3 + ] OS-draw-shape-qcurve: func [ @@ -930,7 +228,7 @@ OS-draw-shape-qcurve: func [ end [red-pair!] rel? [logic!] ][ - draw-curves ctx start end rel? 2 + ] OS-draw-shape-curv: func [ @@ -939,7 +237,7 @@ OS-draw-shape-curv: func [ end [red-pair!] rel? [logic!] ][ - draw-short-curves ctx start end rel? 2 + ] OS-draw-shape-qcurv: func [ @@ -948,7 +246,7 @@ OS-draw-shape-qcurv: func [ end [red-pair!] rel? [logic!] ][ - draw-short-curves ctx start end rel? 1 + ] OS-draw-shape-arc: func [ @@ -957,189 +255,15 @@ OS-draw-shape-arc: func [ sweep? [logic!] large? [logic!] rel? [logic!] - /local - item [red-integer!] - center-x [float!] - center-y [float!] - cx [float!] - cy [float!] - cf [float!] - angle-1 [float!] - angle-2 [float!] - angle-len [float!] - radius-x [float!] - radius-y [float!] - theta [float!] - X1 [float!] - Y1 [float!] - p1-x [float!] - p1-y [float!] - p2-x [float!] - p2-y [float!] - cos-val [float!] - sin-val [float!] - rx2 [float!] - ry2 [float!] - dx [float!] - dy [float!] - sqrt-val [float!] - sign [float!] - rad-check [float!] - angle [red-integer!] - center [red-pair!] - m [integer!] - path [integer!] - arc-dir [integer!] - prev-dir [integer!] - pt [tagPOINT] - arc-points [arcPOINTS!] - dc [handle!] ][ - if ctx/other/last-point? [ - ;-- parse arguments - p1-x: as float! ctx/other/path-last-point/x - p1-y: as float! ctx/other/path-last-point/y - p2-x: either rel? [ p1-x + as float! end/x ][ as float! end/x ] - p2-y: either rel? [ p1-y + as float! end/y ][ as float! end/y ] - item: as red-integer! end + 1 - radius-x: get-float item - item: item + 1 - radius-y: get-float item - item: item + 1 - theta: get-float item - if radius-x < 0.0 [ radius-x: radius-x * -1.0] - if radius-y < 0.0 [ radius-x: radius-x * -1.0] - - ;-- calculate center - dx: (p1-x - p2-x) / 2.0 - dy: (p1-y - p2-y) / 2.0 - cos-val: cos degree-to-radians theta TYPE_COSINE - sin-val: sin degree-to-radians theta TYPE_SINE - X1: (cos-val * dx) + (sin-val * dy) - Y1: (cos-val * dy) - (sin-val * dx) - rx2: radius-x * radius-x - ry2: radius-y * radius-y - rad-check: ((X1 * X1) / rx2) + ((Y1 * Y1) / ry2) - if rad-check > 1.0 [ - radius-x: radius-x * sqrt rad-check - radius-y: radius-y * sqrt rad-check - rx2: radius-x * radius-x - ry2: radius-y * radius-y - ] - sign: either large? = sweep? [ -1.0 ][ 1.0 ] - sqrt-val: ((rx2 * ry2) - (rx2 * Y1 * Y1) - (ry2 * X1 * X1)) / ((rx2 * Y1 * Y1) + (ry2 * X1 * X1)) - cf: either sqrt-val < 0.0 [ 0.0 ][ sign * sqrt sqrt-val ] - cx: cf * (radius-x * Y1 / radius-y) - cy: cf * (radius-y * X1 / radius-x) * -1.0 - center-x: (cos-val * cx) - (sin-val * cy) + ((p1-x + p2-x) / 2.0) - center-y: (sin-val * cx) + (cos-val * cy) + ((p1-y + p2-y) / 2.0) - - ;-- calculate angles - angle-1: radian-to-degrees atan (float/abs ((p1-y - center-y) / (p1-x - center-x))) - angle-1: adjust-angle (p1-x - center-x) (p1-y - center-y) angle-1 - angle-2: radian-to-degrees atan (float/abs ((p2-y - center-y) / (p2-x - center-x))) - angle-2: adjust-angle (p2-x - center-x) (p2-y - center-y) angle-2 - angle-len: angle-2 - angle-1 - either sweep? [ - if angle-len < 0.0 [angle-len: 360.0 + angle-len] - ][ - if angle-len > 0.0 [angle-len: angle-len - 360.0] - ] - angle-1: angle-1 - theta - - ;--draw arc - either ctx/other/GDI+? [ - path: 0 - GdipCreatePath 0 :path ; alternate fill - GdipAddPathArc - path - as float32! center-x - radius-x - as float32! center-y - radius-y - as float32! (radius-x * 2.0) - as float32! (radius-y * 2.0) - as float32! angle-1 - as float32! angle-len - m: 0 - - GdipCreateMatrix :m - GdipTranslateMatrix m as float32! (center-x * -1.0) as float32! (center-y * -1.0) GDIPLUS_MATRIX_APPEND - GdipRotateMatrix m as float32! theta GDIPLUS_MATRIX_APPEND - GdipTranslateMatrix m as float32! center-x as float32! center-y GDIPLUS_MATRIX_APPEND - GdipTransformPath path m - GdipDeleteMatrix m - - GdipAddPathPath ctx/gp-path path ctx/other/connect-subpath - GdipDeletePath path - ][ - dc: ctx/dc - either theta <> 0.0 [ - arc-points: gdi-calc-arc - center-x - center-y - radius-x - radius-y - angle-1 - angle-len - ][ - arc-points: declare arcPOINTS! - arc-points/start-x: p1-x - arc-points/start-y: p1-y - arc-points/end-x: p2-x - arc-points/end-y: p2-y - ] - - set-matrix xform 1.0 0.0 0.0 1.0 center-x * -1.0 center-y * -1.0 - SetWorldTransform dc xform - set-matrix xform cos-val sin-val sin-val * -1.0 cos-val center-x center-y - ModifyWorldTransform dc xform MWT_RIGHTMULTIPLY - - prev-dir: GetArcDirection dc - arc-dir: either sweep? [ AD_CLOCKWISE ][ AD_COUNTERCLOCKWISE ] - SetArcDirection dc arc-dir - Arc - dc - as integer! center-x - radius-x - as integer! center-y - radius-y - as integer! center-x + radius-x - as integer! center-y + radius-y - as integer! arc-points/start-x - as integer! arc-points/start-y - as integer! arc-points/end-x - as integer! arc-points/end-y - SetArcDirection dc prev-dir - - set-matrix xform 1.0 0.0 0.0 1.0 0.0 0.0 - SetWorldTransform dc xform - ] - ;-- set last point - ctx/other/last-point?: yes - ctx/other/path-last-point/x: as integer! p2-x - ctx/other/path-last-point/y: as integer! p2-y - ctx/other/prev-shape/type: SHAPE_OTHER - ctx/other/connect-subpath: 1 - ] ] OS-draw-anti-alias: func [ ctx [draw-ctx!] on? [logic!] ][ - ctx/other/anti-alias?: on? - either on? [ - ctx/other/GDI+?: yes - GdipSetSmoothingMode ctx/graphics GDIPLUS_ANTIALIAS - GdipSetTextRenderingHint ctx/graphics TextRenderingHintAntiAliasGridFit - ][ - ctx/other/GDI+?: no - if any [ctx/on-image? dpi-factor <> 100][ ;-- always use GDI+ to draw on image - ctx/other/anti-alias?: yes - ctx/other/GDI+?: yes - ] - GdipSetSmoothingMode ctx/graphics GDIPLUS_HIGHSPPED - GdipSetTextRenderingHint ctx/graphics TextRenderingHintSystemDefault - ] - update-modes ctx + ] OS-draw-line: func [ @@ -1147,55 +271,24 @@ OS-draw-line: func [ point [red-pair!] end [red-pair!] /local - start [tagPOINT] - pt [tagPOINT] - nb [integer!] - pair [red-pair!] -][ - if ctx/other/D2D? [OS-draw-line-d2d ctx point end exit] - - pt: ctx/other/edges - start: pt - pair: point - nb: 0 - - while [all [pair <= end nb < MAX_EDGES]][ - pt/x: pair/x - pt/y: pair/y - nb: nb + 1 - pt: pt + 1 - pair: pair + 1 - ] - either ctx/other/GDI+? [ - check-gradient-poly ctx start 2 - GdipDrawLinesI ctx/graphics ctx/gp-pen start nb - ][ - Polyline ctx/dc start nb - ] -] - -OS-draw-pen: func [ - ctx [draw-ctx!] - color [integer!] ;-- 00bbggrr format - off? [logic!] - alpha? [logic!] + pt0 [red-pair!] + pt1 [red-pair!] + this [this!] + rt [ID2D1HwndRenderTarget] ][ - if all [off? ctx/pen? <> off?][exit] - - if ctx/other/D2D? [OS-draw-pen-d2d ctx color off? exit] - - ctx/alpha-pen?: alpha? - ctx/other/GDI+?: any [alpha? ctx/other/anti-alias? ctx/alpha-brush?] - - if any [ctx/pen-color <> color ctx/pen? = off? ctx/other/gradient-pen?][ - ctx/pen?: not off? - ctx/pen-color: color - either ctx/other/GDI+? [update-gdiplus-pen ctx][update-pen ctx] - ] + this: as this! ctx/dc + rt: as ID2D1HwndRenderTarget this/vtbl + pt0: point - unless ctx/font-color? [ - if ctx/other/GDI+? [update-gdiplus-font-color ctx color] - unless ctx/on-image? [SetTextColor ctx/dc color] + while [pt1: pt0 + 1 pt1 <= end][ + rt/DrawLine + this + as float32! pt0/x as float32! pt0/y + as float32! pt1/x as float32! pt1/y + ctx/pen + ctx/pen-width + 0 + pt0: pt0 + 1 ] ] @@ -1204,18 +297,18 @@ OS-draw-fill-pen: func [ color [integer!] ;-- 00bbggrr format off? [logic!] alpha? [logic!] + /local + this [this!] + brush [ID2D1SolidColorBrush] ][ - if all [off? ctx/brush? <> off?][exit] - - if ctx/other/D2D? [OS-draw-fill-pen-d2d ctx color off? exit] - - ctx/alpha-brush?: alpha? - ctx/other/GDI+?: any [alpha? ctx/other/anti-alias? ctx/alpha-pen?] - - if any [ctx/brush-color <> color ctx/brush? = off? ctx/other/gradient-fill?][ + if any [ctx/brush-color <> color ctx/brush? = off?][ ctx/brush?: not off? ctx/brush-color: color - either ctx/other/GDI+? [update-gdiplus-brush ctx][update-brush ctx] + if ctx/brush? [ + this: as this! ctx/brush + brush: as ID2D1SolidColorBrush this/vtbl + brush/SetColor this to-dx-color color null + ] ] ] @@ -1225,101 +318,10 @@ OS-draw-line-width: func [ /local width-v [float32!] ][ - if ctx/other/D2D? [OS-draw-line-width-d2d ctx width exit] - - width-v: get-float32 as red-integer! width + width-v: (get-float32 as red-integer! width) if ctx/pen-width <> width-v [ ctx/pen-width: width-v - either ctx/other/GDI+? [ - GdipSetPenWidth ctx/gp-pen ctx/pen-width - ][ - update-pen ctx - ] - ] -] - -gdiplus-roundrect-path: func [ - path [integer!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - diameter [integer!] - /local - angle90 [float32!] -][ - angle90: as float32! 90 - GdipAddPathArcI path x y diameter diameter as float32! 180 angle90 - x: x + (width - diameter) - GdipAddPathArcI path x y diameter diameter as float32! 270 angle90 - y: y + (height - diameter) - GdipAddPathArcI path x y diameter diameter as float32! 0 angle90 - x: x - (width - diameter) - GdipAddPathArcI path x y diameter diameter angle90 angle90 - GdipClosePathFigure path -] - -gdiplus-draw-roundbox: func [ - graphics [integer!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - radius [integer!] - pen [integer!] - brush [integer!] - /local - path [integer!] -][ - path: 0 - GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :path - gdiplus-roundrect-path path x y width height radius - if brush <> 0 [ - GdipFillPath graphics brush path - ] - GdipDrawPath graphics pen path - GdipDeletePath path -] - -gdiplus-draw-box: func [ - graphics [integer!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - radius [integer!] - pen [integer!] - brush [integer!] -][ - if radius > 0 [ - gdiplus-draw-roundbox - graphics - x - y - width - height - radius - pen - brush - exit - ] - if brush <> 0 [ ;-- fill rect - GdipFillRectangleI - graphics - brush - x - y - width - height ] - - GdipDrawRectangleI - graphics - pen - x - y - width - height ] OS-draw-box: func [ @@ -1327,199 +329,47 @@ OS-draw-box: func [ upper [red-pair!] lower [red-pair!] /local - t [integer!] - radius [red-integer!] - rad [integer!] - up-x [integer!] - up-y [integer!] - low-x [integer!] - low-y [integer!] - width [integer!] - height [integer!] + this [this!] + rt [ID2D1HwndRenderTarget] + rc [D2D_RECT_F value] ][ - if ctx/other/D2D? [ - OS-draw-box-d2d ctx upper lower - exit + this: as this! ctx/dc + rt: as ID2D1HwndRenderTarget this/vtbl + + rc/right: as float32! lower/x + rc/bottom: as float32! lower/y + rc/left: as float32! upper/x + rc/top: as float32! upper/y + if ctx/brush? [ + rt/FillRectangle this rc ctx/brush ] - rad: either TYPE_OF(lower) = TYPE_INTEGER [ - radius: as red-integer! lower - lower: lower - 1 - radius/value - ][0] - up-x: upper/x up-y: upper/y low-x: lower/x low-y: lower/y - either positive? rad [ - rad: rad * 2 - width: low-x - up-x - height: low-y - up-y - t: either width > height [height][width] - rad: either rad > t [t][rad] - either ctx/other/GDI+? [ - check-gradient-box ctx upper lower - check-texture-box ctx upper - gdiplus-draw-box - ctx/graphics - up-x - up-y - width - height - rad - ctx/gp-pen - either ctx/brush? [ctx/gp-brush][0] - ][ - RoundRect ctx/dc up-x up-y low-x low-y rad rad - ] - ][ - either ctx/other/GDI+? [ - if up-x > low-x [t: up-x up-x: low-x low-x: t] - if up-y > low-y [t: up-y up-y: low-y low-y: t] - check-gradient-box ctx upper lower - check-texture-box ctx upper - gdiplus-draw-box - ctx/graphics - up-x - up-y - low-x - up-x - low-y - up-y - rad - ctx/gp-pen - either ctx/brush? [ctx/gp-brush][0] - ][ - Rectangle ctx/dc up-x up-y low-x low-y - ] + if ctx/pen? [ + rt/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon ctx [draw-ctx!] start [red-pair!] - /local - pair [red-pair!] - point [tagPOINT] ][ - point: ctx/other/edges - point/x: start/x ;-- 1st point - point/y: start/y - point: point + 1 - - pair: start + 1 - point/x: pair/x ;-- 2nd point - point/y: pair/y - point: point + 1 - - pair: pair + 1 - point/x: pair/x ;-- 3rd point - point/y: pair/y - point: point + 1 - - point/x: start/x ;-- close the triangle - point/y: start/y - - either ctx/other/GDI+? [ - check-gradient-poly ctx ctx/other/edges 3 - check-texture-poly ctx ctx/other/edges 3 - if ctx/brush? [ - GdipFillPolygonI - ctx/graphics - ctx/gp-brush - ctx/other/edges - 4 - GDIPLUS_FILLMODE_ALTERNATE - ] - GdipDrawPolygonI ctx/graphics ctx/gp-pen ctx/other/edges 4 - ][ - either ctx/brush? [ - Polygon ctx/dc ctx/other/edges 4 - ][ - Polyline ctx/dc ctx/other/edges 4 - ] - ] ] OS-draw-polygon: func [ ctx [draw-ctx!] start [red-pair!] end [red-pair!] - /local - pair [red-pair!] - point [tagPOINT] - nb [integer!] ][ - point: ctx/other/edges - pair: start - nb: 0 - - while [all [pair <= end nb < MAX_EDGES]][ - point/x: pair/x - point/y: pair/y - nb: nb + 1 - point: point + 1 - pair: pair + 1 - ] - ;if nb = max-edges [fire error] - point/x: start/x ;-- close the polygon - point/y: start/y - - either ctx/other/GDI+? [ - check-gradient-poly ctx ctx/other/edges nb - check-texture-poly ctx ctx/other/edges nb - if ctx/brush? [ - GdipFillPolygonI - ctx/graphics - ctx/gp-brush - ctx/other/edges - nb + 1 - GDIPLUS_FILLMODE_ALTERNATE - ] - GdipDrawPolygonI ctx/graphics ctx/gp-pen ctx/other/edges nb + 1 - ][ - either ctx/brush? [ - Polygon ctx/dc ctx/other/edges nb + 1 - ][ - Polyline ctx/dc ctx/other/edges nb + 1 - ] - ] -] +] OS-draw-spline: func [ ctx [draw-ctx!] start [red-pair!] end [red-pair!] closed? [logic!] - /local - pair [red-pair!] - point [tagPOINT] - nb [integer!] ][ - point: ctx/other/edges - pair: start - nb: 0 - - while [all [pair <= end nb < MAX_EDGES]][ - point/x: pair/x - point/y: pair/y - nb: nb + 1 - point: point + 1 - pair: pair + 1 - ] - ;if nb = max-edges [fire error] - - unless ctx/other/GDI+? [update-gdiplus-modes ctx] ;-- force to use GDI+ - if ctx/brush? [ - GdipFillClosedCurveI - ctx/graphics - ctx/gp-brush - ctx/other/edges - nb - GDIPLUS_FILLMODE_ALTERNATE - ] - either closed? [ - GdipDrawClosedCurveI ctx/graphics ctx/gp-pen ctx/other/edges nb - ][ - GdipDrawCurveI ctx/graphics ctx/gp-pen ctx/other/edges nb - ] ] do-draw-ellipse: func [ @@ -1529,71 +379,32 @@ do-draw-ellipse: func [ width [integer!] height [integer!] ][ - either ctx/other/GDI+? [ - check-gradient-ellipse ctx x y width height - if ctx/brush? [ - GdipFillEllipseI - ctx/graphics - ctx/gp-brush - x - y - width - height - ] - GdipDrawEllipseI - ctx/graphics - ctx/gp-pen - x - y - width - height - ][ - Ellipse ctx/dc x y x + width y + height - ] + ] OS-draw-circle: func [ - ctx [draw-ctx!] - center [red-pair!] - radius [red-integer!] + ctx [draw-ctx!] + center [red-pair!] + radius [red-integer!] /local - rad-x [integer!] - rad-y [integer!] - w [integer!] - h [integer!] - f [red-float!] + this [this!] + rt [ID2D1HwndRenderTarget] + ellipse [D2D1_ELLIPSE] ][ - if ctx/other/D2D? [ - OS-draw-circle-d2d ctx center radius - exit + this: as this! ctx/dc + rt: as ID2D1HwndRenderTarget this/vtbl + + ellipse: declare D2D1_ELLIPSE + ellipse/x: as float32! center/x + ellipse/y: as float32! center/y + ellipse/radiusX: get-float32 radius + ellipse/radiusY: ellipse/radiusX + if ctx/brush? [ + rt/FillEllipse this ellipse ctx/brush ] - either TYPE_OF(radius) = TYPE_INTEGER [ - either center + 1 = radius [ ;-- center, radius - rad-x: radius/value - rad-y: rad-x - ][ - rad-y: radius/value ;-- center, radius-x, radius-y - radius: radius - 1 - rad-x: radius/value - ] - w: rad-x * 2 - h: rad-y * 2 - ][ - f: as red-float! radius - either center + 1 = radius [ - rad-x: as-integer f/value + 0.75 - rad-y: rad-x - w: as-integer f/value * 2.0 - h: w - ][ - rad-y: as-integer f/value + 0.75 - h: as-integer f/value * 2.0 - f: f - 1 - rad-x: as-integer f/value + 0.75 - w: as-integer f/value * 2.0 - ] + if ctx/pen? [ + rt/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style ] - do-draw-ellipse ctx center/x - rad-x center/y - rad-y w h ] OS-draw-ellipse: func [ @@ -1601,304 +412,44 @@ OS-draw-ellipse: func [ upper [red-pair!] diameter [red-pair!] ][ - do-draw-ellipse ctx upper/x upper/y diameter/x diameter/y + ] OS-draw-font: func [ ctx [draw-ctx!] font [red-object!] - /local - vals [red-value!] - state [red-block!] - handle [red-handle!] - color [red-tuple!] - hFont [handle!] ][ - vals: object/get-values font - state: as red-block! vals + FONT_OBJ_STATE - color: as red-tuple! vals + FONT_OBJ_COLOR - hFont: as handle! either TYPE_OF(state) = TYPE_BLOCK [ - handle: as red-handle! block/rs-head state - handle/value - ][ - make-font get-face-obj ctx/hwnd font - ] - - SelectObject ctx/dc hFont - ctx/font-color?: either TYPE_OF(color) = TYPE_TUPLE [ - SetTextColor ctx/dc color/array1 - if ctx/on-image? [update-gdiplus-font-color ctx color/array1] - yes - ][ - no - ] - if ctx/on-image? [update-gdiplus-font ctx] -] - -OS-draw-text: func [ - ctx [draw-ctx!] - pos [red-pair!] - text [red-string!] - catch? [logic!] - return: [logic!] - /local - str [c-string!] - p [c-string!] - len [integer!] - h [integer!] - w [integer!] - sz [tagSIZE] - y [integer!] - x [integer!] - rect [RECT_STRUCT_FLOAT32] - tm [tagTEXTMETRIC] -][ - if ctx/other/D2D? [ - OS-draw-text-d2d ctx pos text catch? - return true - ] - - if TYPE_OF(text) = TYPE_OBJECT [return false] - - len: -1 - str: unicode/to-utf16-len text :len no - either any [ - ctx/on-image? - ctx/other/GDI+? - ][ - x: 0 - rect: as RECT_STRUCT_FLOAT32 :x - rect/x: as float32! pos/x - rect/y: as float32! pos/y - rect/width: as float32! 0 - rect/height: as float32! 0 - GdipDrawString ctx/graphics str len ctx/gp-font rect 0 ctx/gp-font-brush - ][ - tm: as tagTEXTMETRIC ctx/other/gradient-pen/colors - GetTextMetrics ctx/dc tm - x: dpi-scale pos/x - y: dpi-scale pos/y - p: str - while [len > 0][ - if all [p/1 = #"^/" p/2 = #"^@"][ - ExtTextOut ctx/dc x y ETO_CLIPPED null str (as-integer p - str) / 2 null - y: y + tm/tmHeight - str: p + 2 - ] - p: p + 2 - len: len - 1 - ] - if p > str [ExtTextOut ctx/dc x y ETO_CLIPPED null str (as-integer p - str) / 2 null] - ] - true ] OS-draw-arc: func [ ctx [draw-ctx!] center [red-pair!] end [red-value!] - /local - radius [red-pair!] - angle [red-integer!] - rad-x [integer!] - rad-y [integer!] - start-x [integer!] - start-y [integer!] - end-x [integer!] - end-y [integer!] - angle-begin [float32!] - angle-len [float32!] - rad-x-float [float32!] - rad-y-float [float32!] - rad-x-2 [float32!] - rad-y-2 [float32!] - rad-x-y [float32!] - tan-2 [float32!] - rad-beg [float!] - rad-end [float!] - closed? [logic!] - prev-dir [integer!] - arc-dir [integer!] - arc-points [arcPOINTS!] - dc [handle!] ][ - radius: center + 1 - rad-x: radius/x - rad-y: radius/y - angle: as red-integer! radius + 1 - angle-begin: as float32! angle/value - angle: angle + 1 - angle-len: as float32! angle/value - - closed?: angle < end - - either ctx/other/GDI+? [ - either closed? [ - if ctx/brush? [ - GdipFillPieI - ctx/graphics - ctx/gp-brush - center/x - rad-x - center/y - rad-y - rad-x << 1 - rad-y << 1 - angle-begin - angle-len - ] - GdipDrawPieI - ctx/graphics - ctx/gp-pen - center/x - rad-x - center/y - rad-y - rad-x << 1 - rad-y << 1 - angle-begin - angle-len - ][ - GdipDrawArcI - ctx/graphics - ctx/gp-pen - center/x - rad-x - center/y - rad-y - rad-x << 1 - rad-y << 1 - angle-begin - angle-len - ] - ][ - dc: ctx/dc - rad-x-float: as float32! rad-x - rad-y-float: as float32! rad-y - - arc-points: gdi-calc-arc - as float! center/x - as float! center/y - as float! rad-x - as float! rad-y - as float! angle-begin - as float! angle-len - prev-dir: GetArcDirection dc - arc-dir: either angle-len > as float32! 0.0 [ AD_CLOCKWISE ][ AD_COUNTERCLOCKWISE ] - SetArcDirection dc arc-dir - either closed? [ - Pie - dc - center/x - rad-x - center/y - rad-y - center/x + rad-x - center/y + rad-y - as integer! arc-points/start-x - as integer! arc-points/start-y - as integer! arc-points/end-x - as integer! arc-points/end-y - ][ - Arc - dc - center/x - rad-x - center/y - rad-y - center/x + rad-x - center/y + rad-y - as integer! arc-points/start-x - as integer! arc-points/start-y - as integer! arc-points/end-x - as integer! arc-points/end-y - ] - SetArcDirection dc prev-dir - ] + ] OS-draw-curve: func [ ctx [draw-ctx!] start [red-pair!] end [red-pair!] - /local - pair [red-pair!] - point [tagPOINT] - p2 [red-pair!] - p3 [red-pair!] - nb [integer!] - count [integer!] ][ - point: ctx/other/edges - pair: start - nb: 0 - count: (as-integer end - pair) >> 4 + 1 - - either count = 3 [ ;-- p0, p1, p2 -> p0, (p0 + 2p1) / 3, (2p1 + p2) / 3, p2 - point/x: pair/x - point/y: pair/y - point: point + 1 - p2: pair + 1 - p3: pair + 2 - point/x: p2/x << 1 + pair/x / 3 - point/y: p2/y << 1 + pair/y / 3 - point: point + 1 - point/x: p2/x << 1 + p3/x / 3 - point/y: p2/y << 1 + p3/y / 3 - point: point + 1 - point/x: end/x - point/y: end/y - ][ - until [ - point/x: pair/x - point/y: pair/y - nb: nb + 1 - point: point + 1 - pair: pair + 1 - nb = 4 - ] - ] - either ctx/other/GDI+? [ - GdipDrawBeziersI ctx/graphics ctx/gp-pen ctx/other/edges 4 - ][ - PolyBezier ctx/dc ctx/other/edges 4 - ] ] OS-draw-line-join: func [ ctx [draw-ctx!] style [integer!] - /local - mode [integer!] ][ - mode: 0 - ctx/pen-join: style - either ctx/other/GDI+? [ - case [ - style = miter [mode: GDIPLUS_MITER] - style = miter-bevel [mode: GDIPLUS_MITERCLIPPED] - style = _round [mode: GDIPLUS_ROUND] - style = bevel [mode: GDIPLUS_BEVEL] - true [mode: GDIPLUS_MITER] - ] - GdipSetPenLineJoin ctx/gp-pen mode - ][ - update-pen ctx PEN_LINE_JOIN - ] + ] OS-draw-line-cap: func [ ctx [draw-ctx!] style [integer!] - /local - mode [integer!] ][ - mode: 0 - ctx/pen-cap: style - either ctx/other/GDI+? [ - case [ - style = flat [mode: GDIPLUS_LINECAPFLAT] - style = square [mode: GDIPLUS_LINECAPSQUARE] - style = _round [mode: GDIPLUS_LINECAPROUND] - true [mode: GDIPLUS_LINECAPFLAT] - ] - GdipSetPenStartCap ctx/gp-pen mode - GdipSetPenEndCap ctx/gp-pen mode - ][ - update-pen ctx PEN_LINE_CAP - ] + ] OS-draw-image: func [ @@ -1910,241 +461,10 @@ OS-draw-image: func [ border? [logic!] crop1 [red-pair!] pattern [red-word!] - /local - x [integer!] - y [integer!] - width [integer!] - height [integer!] - src-x [integer!] - src-y [integer!] - w [integer!] - h [integer!] - attr [integer!] - color [integer!] - crop2 [red-pair!] - pts [tagPOINT] -][ - attr: 0 - if key-color <> null [ - attr: ctx/image-attr - if zero? attr [GdipCreateImageAttributes :attr] - color: to-gdiplus-color key-color/array1 - GdipSetImageAttributesColorKeys attr 0 true color color - ] - either crop1 = null [ - src-x: 0 src-y: 0 - w: IMAGE_WIDTH(image/size) - h: IMAGE_HEIGHT(image/size) - ][ - crop2: crop1 + 1 - src-x: crop1/x - src-y: crop1/y - w: crop2/x - h: crop2/y - ] - either null? start [x: 0 y: 0][x: start/x y: start/y] - case [ - start = end [ - width: w - height: h - ] - start + 1 = end [ ;-- two control points - width: end/x - x - height: end/y - y - ] - start + 2 = end [ ;-- three control points - pts: ctx/other/edges - loop 3 [ - pts/x: start/x - pts/y: start/y - pts: pts + 1 - start: start + 1 - ] - GdipDrawImagePointsRectI - ctx/graphics as-integer image/node ctx/other/edges 3 - 0 0 w h GDIPLUS_UNIT_PIXEL attr 0 0 - exit - ] - true [exit] ;@@ TBD four control points - ] - GdipDrawImageRectRectI - ctx/graphics as-integer image/node - x y width height src-x src-y w h - GDIPLUS_UNIT_PIXEL attr 0 0 -] - -check-texture: func [ - ctx [draw-ctx!] - pen? [logic!] - return: [integer!] - /local - brush [integer!] -][ - brush: 0 - either pen? [ - if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ - GdipGetPenBrushFill ctx/gp-pen :brush - ] - ][ - if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ - brush: ctx/gp-brush - ] - ] - brush -] - -check-texture-box: func [ - ctx [draw-ctx!] - upper [red-pair!] - /local - brush [integer!] -][ - brush: 0 - if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx true - texture-translate as-float upper/x as-float upper/y brush - ] - if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx false - texture-translate as-float upper/x as-float upper/y brush - ] -] - -check-texture-ellipse: func [ - ctx [draw-ctx!] - x [integer!] - y [integer!] - /local - brush [integer!] -][ - brush: 0 - if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx true - texture-translate as-float x as-float y brush - ] - if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx false - texture-translate as-float x as-float y brush - ] -] - -check-texture-poly: func [ - ctx [draw-ctx!] - start [tagPOINT] - count [integer!] - /local - cx [integer!] - cy [integer!] - d [integer!] - brush [integer!] -][ - brush: 0 - cx: 0 cy: 0 d: 0 - if ctx/gp-pen-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx true - get-shape-center start count :cx :cy :d - texture-translate as-float cx as-float cy brush - ] - if ctx/gp-brush-type = BRUSH_TYPE_TEXTURE [ - brush: check-texture ctx false - get-shape-center start count :cx :cy :d - texture-translate as-float cx as-float cy brush - ] -] - -check-texture-shape: func [ - ctx [draw-ctx!] - /local - new-path [integer!] - count [integer!] - result [integer!] - points [tagPOINT] - point [tagPOINT] - path-data [PATHDATA] - pt2F [POINT_2F] ][ - ;-- flatten path to get a polygon aproximation - new-path: 0 - GdipClonePath ctx/gp-path :new-path - GdipFlattenPath new-path 0 as float32! 1.0 - count: 0 - GdipGetPointCount new-path :count - path-data: ALLOC_REENTRANT(PATHDATA) - path-data/count: count - path-data/points: as POINT_2F allocate count * (size? POINT_2F) - path-data/types: allocate count - GdipGetPathData new-path path-data - ;-- translate call to check-texture-poly (it will start drawing texture in the center of aproximated polygon) - points: as tagPOINT allocate count * (size? tagPOINT) - point: points - pt2F: path-data/points - loop count [ - point/x: as-integer pt2F/x - point/y: as-integer pt2F/y - point: point + 1 - pt2F: pt2F + 1 - ] - check-texture-poly ctx points count - ;-- free allocated resources - free as byte-ptr! points - free as byte-ptr! path-data/points - free path-data/types - FREE_REENTRANT(path-data) -] -texture-rotate: func [ - angle [float!] - brush [integer!] -][ - unless zero? brush [ GdipRotateTextureTransform brush as-float32 angle GDIPLUS_MATRIX_PREPEND ] ] -texture-scale: func [ - sx [float!] - sy [float!] - brush [integer!] -][ - unless zero? brush [ GdipScaleTextureTransform brush as-float32 sx as-float32 sy GDIPLUS_MATRIX_PREPEND ] -] - -texture-translate: func [ - x [float!] - y [float!] - brush [integer!] -][ - unless zero? brush [ GdipTranslateTextureTransform brush as-float32 x as-float32 y GDIPLUS_MATRIX_PREPEND ] -] - -texture-set-matrix: func [ - matrix [integer!] - brush [integer!] -][ - unless zero? brush [ GdipSetTextureTransform brush matrix ] -] - -texture-reset-matrix: func [ - brush [integer!] -][ - unless zero? brush [ GdipResetTextureTransform brush ] -] - -texture-invert-matrix: func [ - ctx [draw-ctx!] - brush [integer!] - /local - m [integer!] -][ - unless zero? brush [ - m: ctx/gp-matrix - if zero? m [ - GdipCreateMatrix :m - ctx/gp-matrix: m - ] - GdipGetTextureTransform brush :m - GdipInvertMatrix m - GdipSetTextureTransform brush m - ] -] OS-draw-brush-bitmap: func [ ctx [draw-ctx!] @@ -2153,52 +473,8 @@ OS-draw-brush-bitmap: func [ crop-2 [red-pair!] mode [red-word!] brush? [logic!] - /local - x [integer!] - y [integer!] - width [integer!] - height [integer!] - texture [integer!] - wrap [integer!] - result [integer!] ][ - width: OS-image/width? img/node - height: OS-image/height? img/node - either crop-1 = null [ - x: 0 - y: 0 - ][ - x: crop-1/x - y: crop-1/y - ] - either crop-2 = null [ - width: width - x - height: height - y - ][ - width: either ( x + crop-2/x ) > width [ width - x ][ crop-2/x ] - height: either ( y + crop-2/y ) > height [ height - y ][ crop-2/y ] - ] - wrap: WRAP_MODE_TILE - unless mode = null [ - wrap: symbol/resolve mode/symbol - case [ - wrap = flip-x [ wrap: WRAP_MODE_TILE_FLIP_X ] - wrap = flip-y [ wrap: WRAP_MODE_TILE_FLIP_Y ] - wrap = flip-xy [ wrap: WRAP_MODE_TILE_FLIP_XY ] - wrap = clamp [ wrap: WRAP_MODE_CLAMP] - true [ wrap: WRAP_MODE_TILE ] - ] - ] - texture: 0 - result: GdipCreateTexture2I as-integer img/node wrap x y width height :texture - either brush? [ - ctx/brush?: yes - ctx/gp-brush: texture - ctx/gp-brush-type: BRUSH_TYPE_TEXTURE - ][ - GdipSetPenBrushFill ctx/gp-pen texture - ctx/gp-pen-type: BRUSH_TYPE_TEXTURE - ] + ] OS-draw-brush-pattern: func [ @@ -2209,713 +485,10 @@ OS-draw-brush-pattern: func [ mode [red-word!] block [red-block!] brush? [logic!] - /local - pat-image [red-image!] - bkg-alpha [byte!] - p-alpha [byte-ptr!] - p [byte-ptr!] ][ - pat-image: either brush? - [ as red-image! ctx/other/pattern-image-fill ] - [ as red-image! ctx/other/pattern-image-pen ] - unless null? pat-image/node [ - OS-image/delete pat-image - ] - pat-image/header: TYPE_IMAGE - pat-image/head: 0 - pat-image/size: size/y << 16 or size/x - bkg-alpha: as byte! 0 - p-alpha: allocate pat-image/size - p: p-alpha - loop pat-image/size [ - p/value: as-byte 255 - p: p + 1 - ] - pat-image/node: OS-image/make-image size/x size/y null p-alpha null - free p-alpha - do-draw null pat-image block no no no no - OS-draw-brush-bitmap ctx pat-image crop-1 crop-2 mode brush? -] - -get-shape-center: func [ - start [tagPOINT] - count [integer!] - cx [int-ptr!] - cy [int-ptr!] - d [int-ptr!] - /local - point [tagPOINT] - dx [integer!] - dy [integer!] - x0 [integer!] - y0 [integer!] - x1 [integer!] - y1 [integer!] - a [integer!] - r [integer!] - signedArea [float!] - centroid-x [float!] - centroid-y [float!] -][ - ;-- implementation taken from http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon - x0: 0 y0: 0 x1: 0 y1: 0 - a: 0 signedArea: 0.0 - centroid-x: 0.0 centroid-y: 0.0 - point: start - loop count - 1 [ - x0: point/x - y0: point/y - point: point + 1 - x1: point/x - y1: point/y - a: x0 * y1 - (x1 * y0) - signedArea: signedArea + as-float a - centroid-x: centroid-x + as-float ((x0 + x1) * a) - centroid-y: centroid-y + as-float ((y0 + y1) * a) - ] - x0: point/x - y0: point/y - x1: start/x - y1: start/y - a: x0 * y1 - (x1 * y0) - signedArea: signedArea + as-float a - centroid-x: centroid-x + as-float ((x0 + x1) * a) - centroid-y: centroid-y + as-float ((y0 + y1) * a) - - signedArea: signedArea * 0.5 - centroid-x: centroid-x / (signedArea * 6.0) - centroid-y: centroid-y / (signedArea * 6.0) - - cx/value: as-integer centroid-x - cy/value: as-integer centroid-y - ;-- take biggest distance - d/value: 0 - point: start - loop count [ - dx: cx/value - point/x - dy: cy/value - point/y - r: as-integer sqrt as-float ( dx * dx + ( dy * dy ) ) - if r > d/value [ d/value: r ] - point: point + 1 - ] -] - -get-shape-bounding-box: func [ - start [tagPOINT] - count [integer!] - upper [tagPOINT] - lower [tagPOINT] - /local - point [tagPOINT] -][ - upper/x: 1000000 - upper/y: 1000000 - lower/x: 0 - lower/y: 0 - point: start - loop count [ - if point/x > lower/x [ lower/x: point/x ] - if point/y > lower/y [ lower/y: point/y ] - if point/x < upper/x [ upper/x: point/x ] - if point/y < upper/y [ upper/y: point/y ] - point: point + 1 - ] -] - -gradient-deviation: func [ - p1 [tagPOINT] - p2 [tagPOINT] - return: [float32!] - /local - d [float!] - d1 [float!] - d2 [float!] -][ - d1: as-float p1/x - p2/x - d2: as-float p1/y - p2/y - d: sqrt ( ( d1 * d1 ) + ( d2 * d2 ) ) - as-float32 radian-to-degrees asin ( d2 / d ) -] - -gradient-transform: func [ - ctx [draw-ctx!] - gradient [gradient!] - /local - brush [integer!] -][ - if gradient/transformed? [ - either gradient = ctx/other/gradient-pen [ - brush: 0 - GdipGetPenBrushFill ctx/gp-pen :brush - ][ - brush: ctx/gp-brush - ] - either gradient/type = GRADIENT_LINEAR [ - GdipRotateMatrix - gradient/matrix - as-float32 0 - gradient-deviation gradient/data gradient/data + 1 - GDIPLUS_MATRIX_PREPEND - GdipSetLineTransform brush gradient/matrix ;-- this function resets angle of position points - ][ - GdipSetPathGradientTransform brush gradient/matrix - ] - gradient/transformed?: false - ] -] -gradient-rotate: func [ - ctx [draw-ctx!] - gradient [gradient!] - angle [float!] -][ - gradient/transformed?: true - GdipRotateMatrix gradient/matrix as float32! angle GDIPLUS_MATRIX_PREPEND - if gradient/created? [ gradient-transform ctx gradient ] ] -gradient-skew: func [ - ctx [draw-ctx!] - gradient [gradient!] - sx [float!] - sy [float!] - /local - m [integer!] - x [float32!] - y [float32!] - u [float32!] - z [float32!] -][ - m: 0 - u: as float32! 1.0 - z: as float32! 0.0 - x: as float32! tan degree-to-radians sx TYPE_TANGENT - y: as float32! either sx = sy [0.0][tan degree-to-radians sy TYPE_TANGENT] - gradient/transformed?: true - GdipCreateMatrix2 u y x u z z :m - GdipMultiplyMatrix gradient/matrix m GDIPLUS_MATRIX_PREPEND - GdipDeleteMatrix m - if gradient/created? [ gradient-transform ctx gradient ] -] - -gradient-scale: func [ - ctx [draw-ctx!] - gradient [gradient!] - sx [float!] - sy [float!] -][ - gradient/transformed?: true - GdipScaleMatrix gradient/matrix as-float32 sx as-float32 sy GDIPLUS_MATRIX_PREPEND - if gradient/created? [ gradient-transform ctx gradient ] -] - -gradient-translate: func [ - ctx [draw-ctx!] - gradient [gradient!] - x [float!] - y [float!] -][ - gradient/transformed?: true - GdipTranslateMatrix gradient/matrix as-float32 x as-float32 y GDIPLUS_MATRIX_PREPEND - if gradient/created? [ gradient-transform ctx gradient ] -] - -gradient-transf-reset: func [ - ctx [draw-ctx!] - gradient [gradient!] - /local - m [integer!] -][ - m: gradient/matrix - either zero? m [ - GdipCreateMatrix :m - gradient/matrix: m - ][ - GdipSetMatrixElements - m - as-float32 1 - as-float32 0 - as-float32 0 - as-float32 1 - as-float32 0 - as-float32 0 - ] -] - -gradient-set-matrix: func [ - ctx [draw-ctx!] - gradient [gradient!] - m [integer!] - /local - m11 [float32-ptr!] - m12 [float32-ptr!] - m21 [float32-ptr!] - m22 [float32-ptr!] - dx [float32-ptr!] - dy [float32-ptr!] -][ - gradient/transformed?: true - GdipGetMatrixElements m ctx/other/matrix-elems - m11: ctx/other/matrix-elems - m12: ctx/other/matrix-elems + 1 - m21: ctx/other/matrix-elems + 2 - m22: ctx/other/matrix-elems + 3 - dx: ctx/other/matrix-elems + 4 - dy: ctx/other/matrix-elems + 5 - GdipSetMatrixElements - gradient/matrix - m11/value - m12/value - m21/value - m22/value - dx/value - dy/value - if gradient/created? [ gradient-transform ctx gradient ] -] - -gradient-reset-matrix: func [ - ctx [draw-ctx!] - gradient [gradient!] -][ - gradient/transformed?: true - gradient-transf-reset ctx gradient - if gradient/created? [ gradient-transform ctx gradient ] -] - -gradient-invert-matrix: func [ - ctx [draw-ctx!] - gradient [gradient!] -][ - gradient/transformed?: true - GdipInvertMatrix gradient/matrix - if gradient/created? [ gradient-transform ctx gradient ] -] - -save-brush: func [ - ctx [draw-ctx!] - gradient [gradient!] - brush [integer!] -][ - ctx/other/GDI+?: yes - gradient/created?: true - either gradient = ctx/other/gradient-fill [ - unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] - ctx/gp-brush: brush - ctx/gp-brush-type: BRUSH_TYPE_NORMAL - ][ - GdipSetPenBrushFill ctx/gp-pen brush - ctx/gp-pen-type: BRUSH_TYPE_NORMAL - ] -] - -gradient-linear: func [ - ctx [draw-ctx!] - gradient [gradient!] - point-1 [tagPOINT] - point-2 [tagPOINT] - /local - brush [integer!] - count [integer!] -][ - brush: 0 - count: gradient/count - unless gradient/extra = 0 [ - point-1/x: point-1/x - gradient/extra - 1 - point-2/x: point-2/x + gradient/extra + 1 - gradient/extra: 0 - ] - GdipCreateLineBrushI point-1 point-2 gradient/colors/1 gradient/colors/count 0 :brush - if gradient/transformed? [ - GdipRotateMatrix - gradient/matrix - as-float32 0 - gradient-deviation point-1 point-2 - GDIPLUS_MATRIX_PREPEND - GdipSetLineTransform brush gradient/matrix ;-- this function resets angle of position points - gradient/transformed?: false - ] - GdipSetLinePresetBlend brush gradient/colors gradient/colors-pos count - GdipSetLineWrapMode brush gradient/spread - - save-brush ctx gradient brush -] - -gradient-radial-diamond: func [ - ctx [draw-ctx!] - gradient [gradient!] - center [tagPOINT] - focal [tagPOINT] - radius [integer!] - /local - brush [integer!] - count [integer!] - color [int-ptr!] - size [integer!] - n [integer!] - width [integer!] - height [integer!] - x [integer!] - y [integer!] - other [tagPOINT] -][ - brush: 0 - - count: gradient/count - GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :brush - - other: gradient/data + INDEX_OTHER - either gradient/type = GRADIENT_RADIAL [ - size: radius * 2 - x: center/x - radius - y: center/y - radius - unless gradient/extra = 0 [ - x: x - gradient/extra - 1 - y: y - gradient/extra - 1 - size: 2 * gradient/extra + size - gradient/extra: 0 - ] - GdipAddPathEllipseI brush x y size size - other/x: focal/x - other/y: focal/y - ][ - x: center/x - y: center/y - width: focal/x - center/x + 1 - height: focal/y - center/y + 1 - unless gradient/extra = 0 [ - x: x - gradient/extra - 1 - y: y - gradient/extra - 1 - width: 2 * gradient/extra + height - height: 2 * gradient/extra + height - gradient/extra: 0 - ] - GdipAddPathRectangleI brush x y width height - ] - - n: brush - GdipCreatePathGradientFromPath n :brush - GdipDeletePath n - GdipSetPathGradientCenterColor brush gradient/colors/value - either gradient/type = GRADIENT_RADIAL [ - GdipSetPathGradientCenterPointI brush focal - ][ - unless radius = INVALID_RADIUS [ GdipSetPathGradientCenterPointI brush other ] - ] - reverse-int-array gradient/colors count - reverse-float32-array gradient/colors-pos count - GdipSetPathGradientPresetBlend brush gradient/colors gradient/colors-pos count - reverse-int-array gradient/colors count - reverse-float32-array gradient/colors-pos count - - if gradient/transformed? [ - GdipSetPathGradientTransform brush gradient/matrix - gradient/transformed?: false - ] - GdipSetPathGradientWrapMode brush gradient/spread - - save-brush ctx gradient brush -] - -check-gradient: func [ - ctx [draw-ctx!] - gradient [gradient!] - /local - upper [tagPOINT] - lower [tagPOINT] - radius [tagPOINT] -][ - INIT_GRADIENT_DATA(upper lower radius) - if all [ gradient = ctx/other/gradient-pen ctx/pen-width > as float32! 1.0 ] [ - gradient/extra: as-integer ctx/pen-width / 2 - ] - case [ - gradient/type = GRADIENT_LINEAR [ - gradient-linear ctx gradient upper lower - ] - any [ - gradient/type = GRADIENT_RADIAL - gradient/type = GRADIENT_DIAMOND - ][ - gradient-radial-diamond ctx gradient upper lower radius/x - ] - true [] - ] -] - -_check-gradient-box: func [ - ctx [draw-ctx!] - gradient [gradient!] - upper [red-pair!] - lower [red-pair!] - /local - dx [integer!] - dy [integer!] - _upper [tagPOINT] - _lower [tagPOINT] - _other [tagPOINT] -][ - INIT_GRADIENT_DATA(_upper _lower _other) - case [ - any [ - gradient/type = GRADIENT_LINEAR - gradient/type = GRADIENT_DIAMOND - ][ - _upper/x: upper/x - _lower/x: lower/x - either gradient/type = GRADIENT_LINEAR [ - _upper/y: 0 - _lower/y: 0 - ][ - _upper/y: upper/y - _lower/y: lower/y - ] - _other/x: INVALID_RADIUS - ] - gradient/type = GRADIENT_RADIAL [ - dx: ( lower/x - upper/x + 1 ) / 2 - dy: ( lower/y - upper/y + 1 ) / 2 - _upper/x: upper/x + dx - _upper/y: upper/y + dy - _lower/x: _upper/x - _lower/y: _upper/y - _other/x: as-integer sqrt as-float (dx * dx + ( dy * dy ) ) - ] - true [] - ] - check-gradient ctx gradient _upper _lower _other -] -check-gradient-box: func [ - ctx [draw-ctx!] - upper [red-pair!] - lower [red-pair!] -][ - if all [ - ctx/other/gradient-pen? - not ctx/other/gradient-pen/positions? - ][ - _check-gradient-box - ctx - ctx/other/gradient-pen - upper - lower - ] - if all [ - ctx/other/gradient-fill? - not ctx/other/gradient-fill/positions? - ][ - ctx/brush?: true - _check-gradient-box - ctx - ctx/other/gradient-fill - upper - lower - ] -] - -_check-gradient-ellipse: func [ - ctx [draw-ctx!] - gradient [gradient!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - /local - dx [integer!] - dy [integer!] - upper [tagPOINT] - lower [tagPOINT] - other [tagPOINT] -][ - INIT_GRADIENT_DATA(upper lower other) - case [ - any [ - gradient/type = GRADIENT_LINEAR - gradient/type = GRADIENT_DIAMOND - ][ - upper/x: x - lower/x: x + width - either gradient/type = GRADIENT_LINEAR [ - upper/y: 0 - lower/y: 0 - ][ - upper/y: y - lower/y: y + height - ] - other/x: INVALID_RADIUS - ] - gradient/type = GRADIENT_RADIAL [ - dx: width / 2 - dy: height / 2 - upper/x: x + dx - upper/y: y + dy - lower/x: upper/x - lower/y: upper/y - other/x: either dx > dy [dx][dy] - ] - true [] - ] - check-gradient ctx gradient upper lower other -] -check-gradient-ellipse: func [ - ctx [draw-ctx!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] -][ - if all [ - ctx/other/gradient-pen? - not ctx/other/gradient-pen/positions? - ][ - _check-gradient-ellipse - ctx - ctx/other/gradient-pen - x - y - width - height - ] - if all [ - ctx/other/gradient-fill? - not ctx/other/gradient-fill/positions? - ][ - ctx/brush?: true - _check-gradient-ellipse - ctx - ctx/other/gradient-fill - x - y - width - height - ] -] - -_check-gradient-poly: func [ - ctx [draw-ctx!] - gradient [gradient!] - start [tagPOINT] - count [integer!] - /local - cx [integer!] - cy [integer!] - d [integer!] - upper [tagPOINT] - lower [tagPOINT] - other [tagPOINT] -][ - INIT_GRADIENT_DATA(upper lower other) - cx: 0 cy: 0 d: 0 - case [ - any [ - gradient/type = GRADIENT_LINEAR - gradient/type = GRADIENT_DIAMOND - ][ - get-shape-bounding-box start count upper lower - either gradient/type = GRADIENT_LINEAR [ - upper/y: 0 - lower/y: 0 - other/x: INVALID_RADIUS - ][ - get-shape-center start count :cx :cy :d - other/x: cx - other/y: cy - ] - ] - gradient/type = GRADIENT_RADIAL [ - get-shape-center start count :cx :cy :d - upper/x: cx - upper/y: cy - lower/x: cx - lower/y: cy - other/x: d - ] - ] - check-gradient ctx gradient upper lower other -] -check-gradient-poly: func [ - ctx [draw-ctx!] - start [tagPOINT] - count [integer!] -][ - if all [ - ctx/other/gradient-pen? - not ctx/other/gradient-pen/positions? - ][ - _check-gradient-poly - ctx - ctx/other/gradient-pen - start - count - ] - if all [ - ctx/other/gradient-fill? - not ctx/other/gradient-fill/positions? - ][ - ctx/brush?: true - _check-gradient-poly - ctx - ctx/other/gradient-fill - start - count - ] -] - -_check-gradient-shape: func [ - ctx [draw-ctx!] - gradient [gradient!] - /local - new-path [integer!] - count [integer!] - result [integer!] - points [tagPOINT] - point [tagPOINT] - pt2F [POINT_2F] -][ - ;-- flatten path to get a polygon aproximation - new-path: 0 - GdipClonePath ctx/gp-path :new-path - GdipFlattenPath new-path 0 as float32! 1.0 - count: 0 - GdipGetPointCount new-path :count - gradient/path-data/count: count - gradient/path-data/points: as POINT_2F allocate count * (size? POINT_2F) - gradient/path-data/types: allocate count - GdipGetPathData new-path gradient/path-data - ;-- translate call to check-gradient-poly (it will draw gradient in the center of aproximated polygon) - points: as tagPOINT allocate count * (size? tagPOINT) - point: points - pt2F: gradient/path-data/points - loop count [ - point/x: as-integer pt2F/x - point/y: as-integer pt2F/y - point: point + 1 - pt2F: pt2F + 1 - ] - _check-gradient-poly ctx gradient points count - ;-- free allocated resources - free as byte-ptr! points - free as byte-ptr! gradient/path-data/points - free gradient/path-data/types -] -check-gradient-shape: func [ - ctx [draw-ctx!] -][ - if all [ - ctx/other/gradient-pen? - not ctx/other/gradient-pen/positions? - ][ - _check-gradient-shape - ctx - ctx/other/gradient-pen - ] - if all [ - ctx/other/gradient-fill? - not ctx/other/gradient-fill/positions? - ][ - ctx/brush?: true - _check-gradient-shape - ctx - ctx/other/gradient-fill - ] -] OS-draw-grad-pen-old: func [ ctx [draw-ctx!] @@ -2924,165 +497,8 @@ OS-draw-grad-pen-old: func [ offset [red-pair!] count [integer!] ;-- number of the colors brush? [logic!] - /local - x [integer!] - y [integer!] - start [integer!] - stop [integer!] - brush [integer!] - angle [float32!] - sx [float32!] - sy [float32!] - int [red-integer!] - f [red-float!] - head [red-value!] - next [red-value!] - clr [red-tuple!] - pt [tagPOINT] - color [int-ptr!] - last-c [int-ptr!] - pos [float32-ptr!] - last-p [float32-ptr!] - n [integer!] - delta [float!] - p [float!] - rotate? [logic!] - scale? [logic!] - _colors [int-ptr!] - _colors-pos [float32-ptr!] ][ - _colors: ctx/other/gradient-pen/colors - _colors-pos: ctx/other/gradient-pen/colors-pos - x: offset/x - y: offset/y - - int: as red-integer! offset + 1 - start: int/value - int: int + 1 - stop: int/value - - n: 0 - rotate?: no - scale?: no - sy: as float32! 1.0 - while [ - int: int + 1 - n < 3 - ][ ;-- fetch angle, scale-x and scale-y (optional) - switch TYPE_OF(int) [ - TYPE_INTEGER [p: as-float int/value] - TYPE_FLOAT [f: as red-float! int p: f/value] - default [break] - ] - switch n [ - 0 [if p <> 0.0 [angle: as float32! p rotate?: yes]] - 1 [if p <> 1.0 [sx: as float32! p scale?: yes]] - 2 [if p <> 1.0 [sy: as float32! p scale?: yes]] - ] - n: n + 1 - ] - - pt: ctx/other/edges - color: _colors + 1 - pos: _colors-pos + 1 - delta: as-float count - 1 - delta: 1.0 / delta - p: 0.0 - head: as red-value! int - loop count [ - clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] - color/value: to-gdiplus-color clr/array1 - next: head + 1 - if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] - pos/value: as float32! p - if next <> head [p: p + delta] - head: head + 1 - color: color + 1 - pos: pos + 1 - ] - last-p: pos - 1 - last-c: color - 1 - pos: pos - count - color: color - count - if pos/value > as float32! 0.0 [ ;-- first one should be always 0.0 - _colors-pos/value: as float32! 0.0 - _colors/value: color/value - color: _colors - pos: _colors-pos - count: count + 1 - ] - if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 - last-c/2: last-c/value - last-p/2: as float32! 1.0 - count: count + 1 - ] - - brush: 0 - either type = linear [ - pt/x: x + start - pt/y: y - pt: pt + 1 - pt/x: x + stop - pt/y: y - GdipCreateLineBrushI ctx/other/edges pt color/1 color/count 0 :brush - GdipSetLinePresetBlend brush color pos count - if rotate? [GdipRotateLineTransform brush angle GDIPLUS_MATRIX_APPEND] - if scale? [GdipScaleLineTransform brush sx sy GDIPLUS_MATRIX_APPEND] - ][ - GdipCreatePath GDIPLUS_FILLMODE_ALTERNATE :brush - n: stop - start - stop: n * 2 - case [ - type = radial [GdipAddPathEllipseI brush x - n y - n stop stop] - type = diamond [GdipAddPathRectangleI brush x - n y - n stop stop] - ] - - GdipCreateMatrix :n - if rotate? [GdipRotateMatrix n angle GDIPLUS_MATRIX_APPEND] - if scale? [GdipScaleMatrix n sx sy GDIPLUS_MATRIX_APPEND] - scale?: any [rotate? scale?] - if scale? [ ;@@ transform path will move it - GdipTransformPath brush n - GdipDeleteMatrix n - ] - - n: brush - GdipCreatePathGradientFromPath n :brush - GdipDeletePath n - GdipSetPathGradientCenterColor brush color/value - GdipSetPathGradientCenterPointI brush as tagPOINT :offset/x - reverse-int-array color count - n: count - 1 - start: 2 - while [start < n][ ;-- reverse position - sx: pos/start - pos/start: (as float32! 1.0) - pos/n - pos/n: (as float32! 1.0) - sx - n: n - 1 - start: start + 1 - ] - GdipSetPathGradientPresetBlend brush color pos count - - if any [ ;@@ move the shape back to the right position - all [type = radial scale?] - all [type = diamond rotate?] - ][ - GdipGetPathGradientCenterPointI brush pt - sx: as float32! x - pt/x - sy: as float32! y - pt/y - GdipTranslatePathGradientTransform brush sx sy GDIPLUS_MATRIX_APPEND - ] - ] - - ctx/other/GDI+?: yes - either brush? [ - unless zero? ctx/gp-brush [GdipDeleteBrush ctx/gp-brush] - ctx/brush?: yes - ctx/gp-brush: brush - ][ - GdipSetPenBrushFill ctx/gp-pen brush - ] ] OS-draw-grad-pen: func [ @@ -3095,160 +511,8 @@ OS-draw-grad-pen: func [ focal? [logic!] spread [integer!] brush? [logic!] - /local - x [integer!] - y [integer!] - start [integer!] - stop [integer!] - brush [integer!] - angle [float32!] - sx [float32!] - sy [float32!] - int [red-integer!] - f [red-float!] - head [red-value!] - next [red-value!] - clr [red-tuple!] - pt [tagPOINT] - color [int-ptr!] - last-c [int-ptr!] - pos [float32-ptr!] - last-p [float32-ptr!] - n [integer!] - delta [float!] - p [float!] - radius [integer!] - first-point [logic!] - last-point [logic!] - point [red-pair!] - value [red-value!] - _colors [int-ptr!] - _colors-pos [float32-ptr!] - gradient [gradient!] - gm [integer!] ][ - either brush? [ - ctx/other/gradient-fill?: true - _colors: ctx/other/gradient-fill/colors - _colors-pos: ctx/other/gradient-fill/colors-pos - ][ - ctx/other/gradient-pen?: true - _colors: ctx/other/gradient-pen/colors - _colors-pos: ctx/other/gradient-pen/colors-pos - ] - ;-- stops - pt: ctx/other/edges - color: _colors + 1 - pos: _colors-pos + 1 - delta: as-float count - 1 - delta: 1.0 / delta - p: 0.0 - head: stops - loop count [ - clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] - color/value: to-gdiplus-color clr/array1 - next: head + 1 - if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] - pos/value: either mode = linear [ as float32! p ][ as float32! ( 1.0 - p ) ] - if next <> head [p: p + delta] - head: head + 1 - color: color + 1 - pos: pos + 1 - ] - ;-- patch first and last point - last-p: pos - 1 - last-c: color - 1 - pos: pos - count - color: color - count - first-point: false - last-point: false - either mode = linear [ - _colors-pos/value: as float32! 0.0 ;-- first one should be always 0.0 - if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 - last-point: true - last-p: last-p + 1 - last-p/value: as float32! 1.0 - ] - ][ - _colors-pos/value: as float32! 1.0 ;-- first one should be always 1.0 - if last-p/value > as float32! 0.0 [ ;-- last one should be always 0.0 - last-point: true - last-p: last-p + 1 - last-p/value: as float32! 0.0 - ] - ] - _colors/value: color/value - count: count + 1 - if last-point [ - color: last-c - last-c: last-c + 1 - last-c/value: color/value - count: count + 1 - ] - gradient: either brush? [ctx/brush?: yes ctx/other/gradient-fill ][ ctx/other/gradient-pen ] - gradient/count: count - gradient/created?: false - gradient/positions?: false - gradient-transf-reset ctx gradient - - ;-- spread - case [ - spread = _pad [ gradient/spread: WRAP_MODE_TILE ] ;-- currently pad not supported by GDI+, fallback to repeat - spread = _repeat [ gradient/spread: WRAP_MODE_TILE ] - spread = _reflect [ gradient/spread: WRAP_MODE_TILE_FLIP_X ] - true [ gradient/spread: WRAP_MODE_TILE ] - ] - ;-- positions - case [ - mode = linear [ - gradient/type: GRADIENT_LINEAR - unless skip-pos [ - gradient/positions?: true - pt: gradient/data - point: as red-pair! positions - pt/x: point/x pt/y: point/y - pt: pt + 1 - point: as red-pair! (positions + 1) - pt/x: point/x pt/y: point/y - gradient-linear ctx gradient gradient/data gradient/data + 1 - ] - ] - any [ mode = radial mode = diamond ][ - gradient/type: either mode = radial [ GRADIENT_RADIAL ][ GRADIENT_DIAMOND ] - unless skip-pos [ - gradient/positions?: true - pt: gradient/data - point: as red-pair! positions - pt/x: point/x pt/y: point/y - either mode = radial [ - value: positions + 1 - radius: as-integer get-float as red-integer! value - pt: pt + 1 - if focal? [ - point: as red-pair! ( positions + 2 ) - ] - pt/x: point/x pt/y: point/y - pt: pt + 1 - pt/x: radius - ][ - pt: pt + 1 - point: as red-pair! (positions + 1) - pt/x: point/x pt/y: point/y - pt: pt + 1 - either focal? [ - point: as red-pair! ( positions + 2 ) - pt/x: point/x - pt/y: point/y - ][ - pt/x: INVALID_RADIUS - ] - ] - gradient-radial-diamond ctx gradient gradient/data gradient/data + 1 pt/x - ] - ] - true [ gradient/type: GRADIENT_NONE ] - ] ] OS-set-clip: func [ @@ -3257,43 +521,8 @@ OS-set-clip: func [ l [red-pair!] rect? [logic!] mode [integer!] - /local - dc [handle!] - clip-mode [integer!] ][ - case [ - mode = replace [clip-mode: clip-replace ctx] - mode = intersect [clip-mode: clip-intersect ctx] - mode = union [clip-mode: clip-union ctx] - mode = _xor [clip-mode: clip-xor ctx] - mode = exclude [clip-mode: clip-diff ctx] - true [clip-mode: clip-replace ctx] - ] - either ctx/other/GDI+? [ - either rect? [ - GdipSetClipRectI - ctx/graphics - u/x - u/y - l/x - u/x - l/y - u/y - clip-mode - ][ - GdipSetClipPath - ctx/graphics - ctx/gp-path - clip-mode - GdipDeletePath ctx/gp-path - ] - ][ - dc: ctx/dc - if rect? [ - BeginPath dc - Rectangle dc u/x u/y l/x l/y - ] - EndPath dc ;-- a path has already been started - SelectClipPath dc clip-mode - ] + ] OS-matrix-rotate: func [ @@ -3301,33 +530,8 @@ OS-matrix-rotate: func [ pen-fill [integer!] angle [red-integer!] center [red-pair!] - /local - brush [integer!] - gradient [gradient!] - pen? [logic!] - g [integer!] ][ - ctx/other/GDI+?: yes - either pen-fill <> -1 [ - ;-- rotate pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-rotate ctx gradient as-float angle/value - ;-- texture - brush: check-texture ctx pen? - texture-rotate as-float angle/value brush - ][ - ;-- rotate figure - g: ctx/graphics - if angle <> as red-integer! center [ - GdipTranslateWorldTransform g as float32! center/x as float32! center/y GDIPLUS_MATRIX_PREPEND - ] - GdipRotateWorldTransform g get-float32 angle GDIPLUS_MATRIX_PREPEND - if angle <> as red-integer! center [ - GdipTranslateWorldTransform g as float32! 0 - center/x as float32! 0 - center/y GDIPLUS_MATRIX_PREPEND - ] - ] + ] OS-matrix-scale: func [ @@ -3335,25 +539,8 @@ OS-matrix-scale: func [ pen-fill [integer!] sx [red-integer!] sy [red-integer!] - /local - gradient [gradient!] - pen? [logic!] - brush [integer!] ][ - ctx/other/GDI+?: yes - either pen-fill <> -1 [ - ;-- scale pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-scale ctx gradient as-float sx/value as-float sy/value - ;-- texture - brush: check-texture ctx pen? - texture-scale as-float sx/value as-float sy/value brush - ][ - ;-- scale figure - GdipScaleWorldTransform ctx/graphics get-float32 sx get-float32 sy ctx/other/matrix-order - ] + ] OS-matrix-translate: func [ @@ -3361,29 +548,8 @@ OS-matrix-translate: func [ pen-fill [integer!] x [integer!] y [integer!] - /local - gradient [gradient!] - pen? [logic!] - brush [integer!] ][ - ctx/other/GDI+?: yes - either pen-fill <> -1 [ - ;-- translate pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-translate ctx gradient as-float x as-float y - ;-- texture - brush: check-texture ctx pen? - texture-translate as-float x as-float y brush - ][ - ;-- translate figure - GdipTranslateWorldTransform - ctx/graphics - as float32! x - as float32! y - ctx/other/matrix-order - ] + ] OS-matrix-skew: func [ @@ -3391,29 +557,8 @@ OS-matrix-skew: func [ pen-fill [integer!] sx [red-integer!] sy [red-integer!] - /local - m [integer!] - x [float32!] - y [float32!] - u [float32!] - z [float32!] - gradient [gradient!] ][ - either pen-fill <> -1 [ - ;-- skew pen or fill - gradient: either pen-fill = pen [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-skew ctx gradient as-float sx/value as-float sy/value - ][ - ;-- skew figure - m: 0 - u: as float32! 1.0 - z: as float32! 0.0 - x: as float32! tan degree-to-radians get-float sx TYPE_TANGENT - y: as float32! either sx = sy [0.0][tan degree-to-radians get-float sy TYPE_TANGENT] - GdipCreateMatrix2 u y x u z z :m - GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order - GdipDeleteMatrix m - ] + ] OS-matrix-transform: func [ @@ -3422,169 +567,42 @@ OS-matrix-transform: func [ center [red-pair!] scale [red-integer!] translate [red-pair!] - /local - rotate [red-integer!] - m [integer!] - gradient [gradient!] - pen? [logic!] - brush [integer!] - center? [logic!] ][ - rotate: as red-integer! either center + 1 = scale [center][center + 1] - center?: rotate <> center - - either pen-fill <> -1 [ - ;-- transform pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-translate ctx gradient as-float translate/x as-float translate/y - gradient-scale ctx gradient get-float scale get-float scale + 1 - gradient-rotate ctx gradient as-float rotate/value - ;-- texture - brush: check-texture ctx pen? - texture-translate as-float translate/x as-float translate/y brush - texture-scale get-float scale get-float scale + 1 brush - texture-rotate as-float rotate/value brush - ][ - ;-- transform figure - m: 0 - GdipCreateMatrix :m - - if center? [GdipTranslateMatrix m as float32! center/x as float32! center/y GDIPLUS_MATRIX_PREPEND] - GdipTranslateMatrix m as float32! translate/x as float32! translate/y GDIPLUS_MATRIX_PREPEND - GdipScaleMatrix m get-float32 scale get-float32 scale + 1 GDIPLUS_MATRIX_PREPEND - GdipRotateMatrix m get-float32 rotate GDIPLUS_MATRIX_PREPEND - if center? [GdipTranslateMatrix m as float32! 0 - center/x as float32! 0 - center/y GDIPLUS_MATRIX_PREPEND] - - GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order - GdipDeleteMatrix m - ] + ] -OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!] /local s][ - s: 0 - GdipSaveGraphics ctx/graphics :s - state/gstate: s - state/pen-clr: ctx/pen-color - state/brush-clr: ctx/brush-color - state/pen-join: ctx/pen-join - state/pen-cap: ctx/pen-cap - state/pen?: ctx/pen? - state/brush?: ctx/brush? - state/a-pen?: ctx/alpha-pen? - state/a-brush?: ctx/alpha-brush? -] +OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!]][ -OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][ - GdipRestoreGraphics ctx/graphics state/gstate - ctx/pen-join: state/pen-join - ctx/pen-cap: state/pen-cap - OS-draw-pen ctx state/pen-clr not state/pen? state/a-pen? - OS-draw-fill-pen ctx state/brush-clr not state/brush? state/a-brush? ] +OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][] + OS-matrix-reset: func [ ctx [draw-ctx!] pen-fill [integer!] - /local - gradient [gradient!] - pen? [logic!] - brush [integer!] ][ - either pen-fill <> -1 [ - ;-- reset matrix for pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-transf-reset ctx gradient - ;-- texture - brush: check-texture ctx pen? - texture-reset-matrix brush - ][ - ;-- reset matrix for figure - GdipResetWorldTransform ctx/graphics - ] - if ctx/scale-ratio <> as float32! 0.0 [ - GdipScaleWorldTransform ctx/graphics ctx/scale-ratio ctx/scale-ratio GDIPLUS_MATRIX_PREPEND - ] + ] OS-matrix-invert: func [ ctx [draw-ctx!] pen-fill [integer!] - /local - m [integer!] - gradient [gradient!] - pen? [logic!] - brush [integer!] + ][ - m: ctx/gp-matrix - if zero? m [ - GdipCreateMatrix :m - ctx/gp-matrix: m - ] - either pen-fill <> -1 [ - ;-- invert matrix for pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-invert-matrix ctx gradient - ;-- texture - brush: check-texture ctx pen? - texture-invert-matrix ctx brush - ][ - ;-- invert matrix for figure - GdipGetWorldTransform ctx/graphics m - GdipInvertMatrix m - GdipSetWorldTransform ctx/graphics m - ] + ] OS-matrix-set: func [ ctx [draw-ctx!] pen-fill [integer!] blk [red-block!] - /local - m [integer!] - val [red-integer!] - gradient [gradient!] - pen? [logic!] - brush [integer!] ][ - m: 0 - val: as red-integer! block/rs-head blk - GdipCreateMatrix2 - get-float32 val - get-float32 val + 1 - get-float32 val + 2 - get-float32 val + 3 - get-float32 val + 4 - get-float32 val + 5 - :m - either pen-fill <> -1 [ - ;-- set matrix for pen or fill - pen?: either pen-fill = pen [ true ][ false ] - ;-- gradient - gradient: either pen? [ ctx/other/gradient-pen ][ ctx/other/gradient-fill ] - gradient-set-matrix ctx gradient m - ;-- texture - brush: check-texture ctx pen? - texture-set-matrix m brush - ][ - ;-- set matrix for figure - GdipMultiplyWorldTransform ctx/graphics m ctx/other/matrix-order - ] - GdipDeleteMatrix m + ] OS-set-matrix-order: func [ ctx [draw-ctx!] order [integer!] ][ - case [ - order = _append [ ctx/other/matrix-order: GDIPLUS_MATRIX_APPEND ] - order = prepend [ ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND ] - true [ ctx/other/matrix-order: GDIPLUS_MATRIX_PREPEND ] - ] + ] diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index d759929d8d..084a677a24 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -46,8 +46,11 @@ Red/System [ #include %tab-panel.reds #include %text-list.reds #include %button.reds -#include %draw-d2d.reds -#include %draw.reds +#either legacy = none [ + #include %draw.reds +][ + #include %draw-gdi.reds ;-- for WinXP +] #include %comdlgs.reds exit-loop: 0 diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index dab2aa60fd..2c2d403bd1 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -3,7 +3,7 @@ Red/System [ Author: "Xie Qingtian" File: %text-box.reds Tabs: 4 - Dependency: %draw-d2d.reds + Dependency: %draw.reds Rights: "Copyright (C) 2016 Xie Qingtian. All rights reserved." License: { Distributed under the Boost Software License, Version 1.0. diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 6e79cc5e80..10e233af8d 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -2896,4 +2896,34 @@ utf16-length?: func [ base: s while [any [s/1 <> null-byte s/2 <> null-byte]][s: s + 2] (as-integer s - base) >>> 1 ;-- do not count the terminal zero +] + +to-gdiplus-color: func [ + color [integer!] + return: [integer!] + /local + red [integer!] + green [integer!] + blue [integer!] + alpha [integer!] +][ + red: color and FFh << 16 + green: color and FF00h + blue: color >> 16 and FFh + alpha: FF000000h and not color + red or green or blue or alpha +] + +;-- see https://stackoverflow.com/questions/4258295/aero-how-to-draw-solid-opaque-colors-on-glass +; and https://stackoverflow.com/questions/5647322/gdi-font-rendering-especially-in-layered-windows +; GDI+ is often buggy when alpha=255 (fully opaque) +to-gdiplus-color-fixed: func [ + color [integer!] + return: [integer!] + /local + r [integer!] +][ + r: to-gdiplus-color color + if r >>> 24 = FFh [r: r xor 01000000h] + r ] \ No newline at end of file diff --git a/modules/view/draw.red b/modules/view/draw.red index 393a27e65f..1d6a2b841a 100644 --- a/modules/view/draw.red +++ b/modules/view/draw.red @@ -702,14 +702,6 @@ Red/System [ state [draw-state! value] clip-mode [integer!] m-order [integer!] - pen-clr [integer!] - brush-clr [integer!] - pen-join [integer!] - pen-cap [integer!] - pen? [logic!] - brush? [logic!] - a-pen? [logic!] - a-brush? [logic!] ][ cmd: block/rs-head cmds tail: block/rs-tail cmds From 77f5884785b64b021760a061ece9a032e192813d Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 1 Dec 2019 22:44:29 +0100 Subject: [PATCH 0593/3432] FEAT: adds macro definition for pointer to pointer!. --- system/runtime/common.reds | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/system/runtime/common.reds b/system/runtime/common.reds index 7ebcd96eb1..6beb179152 100644 --- a/system/runtime/common.reds +++ b/system/runtime/common.reds @@ -42,6 +42,15 @@ Red/System [ #define float-ptr! [pointer! [float!]] #define float32-ptr! [pointer! [float32!]] +;#define int16! integer! +;#define uint16! integer! +#define uint! integer! +#define long! integer! ;-- 32bit in 32bit OS, 64bit in 64bit OS +#define ulong! integer! + +ptr-ptr!: alias struct! [value [int-ptr!]] +#define ptr-value! [ptr-ptr! value] + #define make-c-string [as c-string! allocate] #define read-io8 [system/io/read as byte-ptr!] From d765da1686d998c0aaa32402cac11a78b0ea9f40 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 2 Dec 2019 12:43:27 +0100 Subject: [PATCH 0594/3432] FEAT: minor code refactoring to use ptr-ptr! and ptr-value! --- modules/view/backends/windows/base.reds | 4 +- modules/view/backends/windows/direct2d.reds | 50 ++++++++++++--------- modules/view/backends/windows/draw.reds | 6 +-- modules/view/backends/windows/events.reds | 8 ++-- modules/view/backends/windows/gui.reds | 2 +- modules/view/backends/windows/text-box.reds | 2 +- runtime/platform/COM.reds | 2 +- 7 files changed, 40 insertions(+), 34 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 3e886f50e4..931e64a360 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -436,7 +436,7 @@ BaseWndProc: func [ lParam [integer!] return: [integer!] /local - target [int-ptr!] + target [ptr-ptr!] this [this!] rt [ID2D1HwndRenderTarget] flags [integer!] @@ -464,7 +464,7 @@ BaseWndProc: func [ update-base hWnd null null get-face-values hWnd ] ][ - target: as int-ptr! GetWindowLong hWnd wc-offset - 24 + target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 if target <> null [ this: as this! target/value rt: as ID2D1HwndRenderTarget this/vtbl diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 46fa13322b..556db61cd2 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -247,7 +247,7 @@ ID2D1Factory: alias struct! [ CreateStrokeStyle [integer!] CreateDrawingStateBlock [integer!] CreateWicBitmapRenderTarget [integer!] - CreateHwndRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [int-ptr!] return: [integer!]]] + CreateHwndRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [ptr-ptr!] return: [integer!]]] CreateDxgiSurfaceRenderTarget [integer!] CreateDCRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] target [int-ptr!] return: [integer!]]] ] @@ -653,14 +653,14 @@ D2D1CreateFactory!: alias function! [ type [integer!] riid [int-ptr!] options [int-ptr!] ;-- opt - factory [int-ptr!] + factory [ptr-ptr!] return: [integer!] ] DWriteCreateFactory!: alias function! [ type [integer!] iid [int-ptr!] - factory [int-ptr!] + factory [ptr-ptr!] return: [integer!] ] @@ -711,7 +711,7 @@ DX-init: func [ /local str [red-string!] hr [integer!] - factory [integer!] + factory [ptr-value!] dll [handle!] options [integer!] D2D1CreateFactory [D2D1CreateFactory!] @@ -729,14 +729,13 @@ DX-init: func [ dw-locale-name: as c-string! allocate 85 GetUserDefaultLocaleName dw-locale-name 85 - factory: 0 options: 0 ;-- debugLevel hr: D2D1CreateFactory 0 IID_ID2D1Factory :options :factory ;-- D2D1_FACTORY_TYPE_SINGLE_THREADED: 0 assert zero? hr - d2d-factory: as this! factory + d2d-factory: as this! factory/value hr: DWriteCreateFactory 0 IID_IDWriteFactory :factory ;-- DWRITE_FACTORY_TYPE_SHARED: 0 assert zero? hr - dwrite-factory: as this! factory + dwrite-factory: as this! factory/value str: string/rs-make-at ALLOC_TAIL(root) 1024 dwrite-str-cache: str/node ] @@ -767,21 +766,24 @@ to-dx-color: func [ ] d2d-release-target: func [ - target [int-ptr!] + target [ptr-ptr!] /local rt [ID2D1HwndRenderTarget] brushes [int-ptr!] cnt [integer!] this [this!] obj [IUnknown] + pp [ptr-ptr!] ][ - brushes: as int-ptr! target/2 - cnt: target/3 + pp: target + 1 + brushes: pp/value + pp: target + 2 + cnt: as-integer pp/value loop cnt [ COM_SAFE_RELEASE_OBJ(obj brushes/2) brushes: brushes + 2 ] - this: as this! target/1 + this: as this! target/value rt: as ID2D1HwndRenderTarget this/vtbl rt/Release this free as byte-ptr! target @@ -803,7 +805,7 @@ create-hwnd-render-target: func [ left [integer!] factory [ID2D1Factory] rt [ID2D1HwndRenderTarget] - target [integer!] + target [ptr-value!] hr [integer!] ][ left: 0 top: 0 right: 0 bottom: 0 @@ -818,26 +820,30 @@ create-hwnd-render-target: func [ props/dpiX: as float32! log-pixels-x props/dpiY: as float32! log-pixels-y - target: 0 factory: as ID2D1Factory d2d-factory/vtbl hr: factory/CreateHwndRenderTarget d2d-factory :props hprops :target if hr <> 0 [return null] - as this! target + as this! target/value ] get-hwnd-render-target: func [ hWnd [handle!] - return: [int-ptr!] + return: [ptr-ptr!] /local - target [int-ptr!] + target [ptr-ptr!] + pp [ptr-ptr!] ][ - target: as int-ptr! GetWindowLong hWnd wc-offset - 24 + target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 if null? target [ - target: as int-ptr! allocate 4 * size? int-ptr! - target/1: as-integer create-hwnd-render-target hWnd - target/2: as-integer allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! - target/3: 0 - target/4: 0 ;-- for text-box! background color + pp: as ptr-ptr! allocate 4 * size? int-ptr! + target: pp + pp/value: as int-ptr! create-hwnd-render-target hWnd + pp: pp + 1 + pp/value: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! + pp: pp + 1 + pp/value: null + pp: pp + 1 + pp/value: null ;-- for text-box! background color SetWindowLong hWnd wc-offset - 24 as-integer target ] target diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index f2225673dd..5ed754169e 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -29,7 +29,7 @@ draw-begin: func [ m [D2D_MATRIX_3X2_F] bg-clr [integer!] brush [integer!] - target [int-ptr!] + target [ptr-ptr!] brushes [int-ptr!] pbrush [ID2D1SolidColorBrush] d3d-clr [D3DCOLORVALUE] @@ -47,7 +47,7 @@ draw-begin: func [ target: get-hwnd-render-target hWnd this: as this! target/value ctx/dc: as handle! this - ctx/brushes: target + ctx/brushes: as int-ptr! target rt: as ID2D1HwndRenderTarget this/vtbl rt/SetTextAntialiasMode this 1 ;-- ClearType @@ -110,7 +110,7 @@ draw-end: func [ switch hr [ COM_S_OK [ValidateRect hWnd null] D2DERR_RECREATE_TARGET [ - d2d-release-target ctx/brushes + d2d-release-target as ptr-ptr! ctx/brushes ctx/dc: null SetWindowLong hWnd wc-offset - 24 0 InvalidateRect hWnd null 0 diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index ebbf78bf1e..e1f174df19 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -980,7 +980,7 @@ update-window: func [ ][ len: GetWindowLong hWnd wc-offset - 24 if len <> 0 [ - d2d-release-target as int-ptr! len + d2d-release-target as ptr-ptr! len SetWindowLong hWnd wc-offset - 24 0 ] ] @@ -1034,7 +1034,7 @@ WndProc: func [ lParam [integer!] return: [integer!] /local - target [int-ptr!] + target [ptr-ptr!] this [this!] rt [ID2D1HwndRenderTarget] res [integer!] @@ -1089,7 +1089,7 @@ WndProc: func [ WM_MOVE WM_SIZE [ if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [ - target: as int-ptr! GetWindowLong hWnd wc-offset - 24 + target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 if target <> null [ this: as this! target/value rt: as ID2D1HwndRenderTarget this/vtbl @@ -1416,7 +1416,7 @@ WndProc: func [ if hidden-hwnd <> null [ values: (get-face-values hidden-hwnd) + FACE_OBJ_EXT3 values/header: TYPE_NONE - target: as int-ptr! GetWindowLong hidden-hwnd wc-offset - 24 + target: as ptr-ptr! GetWindowLong hidden-hwnd wc-offset - 24 if target <> null [d2d-release-target target] SetWindowLong hidden-hwnd wc-offset - 24 0 ] diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 084a677a24..11fb55b634 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -632,7 +632,7 @@ free-faces: func [ dc: GetWindowLong handle wc-offset - 24 if dc <> 0 [ either (GetWindowLong handle wc-offset - 12) and BASE_FACE_IME <> 0 [ - d2d-release-target as int-ptr! dc + d2d-release-target as ptr-ptr! dc ][ ;-- caret DestroyCaret ] diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index 2c2d403bd1..3d13b69e62 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -315,7 +315,7 @@ OS-text-box-layout: func [ ] hWnd: hidden-hwnd ] - target: get-hwnd-render-target hWnd + target: as int-ptr! get-hwnd-render-target hWnd ] either TYPE_OF(state) = TYPE_BLOCK [ diff --git a/runtime/platform/COM.reds b/runtime/platform/COM.reds index 294668e3b1..63a614bf7e 100644 --- a/runtime/platform/COM.reds +++ b/runtime/platform/COM.reds @@ -101,7 +101,7 @@ tagSTATSTG: alias struct! [ reserved [integer!] ] -this!: alias struct! [vtbl [integer!]] +this!: alias struct! [vtbl [int-ptr!]] interface!: alias struct! [ ptr [this!] From 3c0c63b7b69f3ca779ca4e8c27c7b9e4e8adb755 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 4 Dec 2019 11:16:39 +0800 Subject: [PATCH 0595/3432] FIX: *base transparent* not right --- modules/view/backends/gtk3/font.reds | 36 +++++++++++++++++- modules/view/backends/gtk3/gui.reds | 2 +- modules/view/backends/gtk3/handlers.reds | 47 ++++++++++++++++++++---- modules/view/backends/gtk3/text-box.reds | 1 + 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index 3965585a0e..61186f14a2 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -54,6 +54,10 @@ create-simple-attrs: func [ if all [ not null? color TYPE_OF(color) = TYPE_TUPLE + not all [ + TUPLE_SIZE?(color) = 4 + color/array1 and FF000000h = FF000000h + ] ][ alpha?: 0 rgb: get-color-int color :alpha? @@ -89,6 +93,10 @@ create-simple-css: func [ if all [ not null? color TYPE_OF(color) = TYPE_TUPLE + not all [ + TUPLE_SIZE?(color) = 4 + color/array1 and FF000000h = FF000000h + ] ][ alpha?: 0 rgb: get-color-int color :alpha? @@ -105,6 +113,18 @@ create-simple-css: func [ css ] +create-trans-css: func [ + return: [GString!] + /local + css [GString!] +][ + css: g_string_sized_new 64 + g_string_append css "* {" + g_string_append css { background-color: transparent;} + g_string_append css "}" + css +] + set-label-attrs: func [ label [handle!] font [red-object!] @@ -289,7 +309,13 @@ create-pango-attrs: func [ unless null? face [ color: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR - if TYPE_OF(color) = TYPE_TUPLE [ + if all [ + TYPE_OF(color) = TYPE_TUPLE + not all [ + TUPLE_SIZE?(color) = 4 + color/array1 and FF000000h = FF000000h + ] + ][ alpha?: 0 rgb: get-color-int color :alpha? r: 0 g: 0 b: 0 a: 0 @@ -477,7 +503,13 @@ create-css: func [ unless null? face [ color: as red-tuple! (object/get-values face) + FACE_OBJ_COLOR - if TYPE_OF(color) = TYPE_TUPLE [ + if all [ + TYPE_OF(color) = TYPE_TUPLE + not all [ + TUPLE_SIZE?(color) = 4 + color/array1 and FF000000h = FF000000h + ] + ][ alpha?: 0 rgb: get-color-int color :alpha? b: rgb >> 16 and FFh diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 844cd0ce59..98530610b5 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1797,7 +1797,7 @@ OS-make-view: func [ ] change-selection widget selected sym - change-font widget face values + if sym <> base [change-font widget face values] change-enabled widget enabled?/value sym parse-common-opts widget face as red-block! values + FACE_OBJ_OPTIONS sym diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 0be4938750..df66243a73 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -187,6 +187,7 @@ base-draw: func [ pos [red-pair! value] DC [draw-ctx! value] drawDC [draw-ctx!] + css [GString!] ][ face: get-face-obj widget values: object/get-values face @@ -198,17 +199,28 @@ base-draw: func [ color: as red-tuple! values + FACE_OBJ_COLOR sym: symbol/resolve type/symbol - if TYPE_OF(color) = TYPE_TUPLE [ + either all [ + TYPE_OF(color) = TYPE_TUPLE + not all [ + TUPLE_SIZE?(color) = 4 + color/array1 and FF000000h = FF000000h + ] + ][ free-font font make-font face font set-css widget face values - gtk_render_background - gtk_widget_get_style_context widget - cr - 0.0 0.0 - as float! size/x as float! size/y + ][ + css: create-trans-css + apply-css-styles widget css + free-css css ] + gtk_render_background + gtk_widget_get_style_context widget + cr + 0.0 0.0 + as float! size/x as float! size/y + if TYPE_OF(img) = TYPE_IMAGE [ ;; DEBUG: print ["base-draw, GDK-draw-image: " 0 "x" 0 "x" size/x "x" size/y lf] ;; ONLY WORK for Mandelbrot and raytracer: @@ -244,6 +256,19 @@ base-draw: func [ EVT_DISPATCH ] +transparent-base?: func [ + color [red-tuple!] + return: [logic!] +][ + either all [ + TYPE_OF(color) = TYPE_TUPLE + any [ + TUPLE_SIZE?(color) = 3 + color/array1 and FF000000h = 0 + ] + ][false][true] +] + base-event-after: func [ [cdecl] evbox [handle!] @@ -264,6 +289,7 @@ base-event-after: func [ tail [red-object!] target [handle!] offset2 [red-pair!] + size2 [red-pair!] dx [float!] dy [float!] motion [GdkEventMotion!] @@ -291,7 +317,7 @@ base-event-after: func [ if all [ sym = base - TYPE_OF(color) = TYPE_NONE + transparent-base? color ][ hparent: get-face-handle parent pane: as red-block! (object/get-values parent) + FACE_OBJ_PANE @@ -307,6 +333,13 @@ base-event-after: func [ continue ] offset2: as red-pair! (object/get-values tail) + FACE_OBJ_OFFSET + size2: as red-pair! (object/get-values tail) + FACE_OBJ_SIZE + unless all [ + offset/x >= offset2/x + offset/x <= (offset2/x + size2/x) + offset/y >= offset2/y + offset/y <= (offset2/y + size2/y) + ][continue] case [ etype = GDK_MOTION_NOTIFY [ motion: as GdkEventMotion! event diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index b1270740d5..05306be5ea 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -48,6 +48,7 @@ color-u8-to-u16: func [ t [integer!] ][ t: color >>> 24 and FFh + t: FFh - t a/value: t << 8 + t t: color >> 16 and FFh b/value: t << 8 + t From 49340568cba2ffe29018993757bc9d9a1307aca0 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 5 Dec 2019 11:18:55 +0800 Subject: [PATCH 0596/3432] FIX: check font type not right --- modules/view/backends/gtk3/gui.reds | 10 +++++----- modules/view/backends/gtk3/handlers.reds | 17 ++++++++--------- modules/view/backends/gtk3/text-box.reds | 12 ++++++++++-- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 98530610b5..058dd5ba59 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1891,11 +1891,9 @@ OS-update-view: func [ ; 0 ] if flags and FACET_FLAG_COLOR <> 0 [ - ;; DEBUG: print ["FACET_FLAG_COLOR " get-symbol-name type lf] - ;;;if type = base [ - ;; DEBUG: print ["FACET_FLAG_COLOR " widget lf] + if type <> base [ change-color widget as red-tuple! values + FACE_OBJ_COLOR type - ;;;] + ] ] if all [flags and FACET_FLAG_PANE <> 0 type <> tab-panel][ change-pane widget as red-block! values + FACE_OBJ_PANE type @@ -1904,7 +1902,9 @@ OS-update-view: func [ change-rate widget values + FACE_OBJ_RATE ] if flags and FACET_FLAG_FONT <> 0 [ - change-font widget face values + if type <> base [ + change-font widget face values + ] ] if flags and FACET_FLAG_PARA <> 0 [ change-para widget face values diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index df66243a73..a991184301 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -209,18 +209,17 @@ base-draw: func [ free-font font make-font face font set-css widget face values + gtk_render_background + gtk_widget_get_style_context widget + cr + 0.0 0.0 + as float! size/x as float! size/y ][ - css: create-trans-css - apply-css-styles widget css - free-css css + free-font font + make-font null font + set-css widget face values ] - gtk_render_background - gtk_widget_get_style_context widget - cr - 0.0 0.0 - as float! size/x as float! size/y - if TYPE_OF(img) = TYPE_IMAGE [ ;; DEBUG: print ["base-draw, GDK-draw-image: " 0 "x" 0 "x" size/x "x" size/y lf] ;; ONLY WORK for Mandelbrot and raytracer: diff --git a/modules/view/backends/gtk3/text-box.reds b/modules/view/backends/gtk3/text-box.reds index 05306be5ea..9f137d2553 100644 --- a/modules/view/backends/gtk3/text-box.reds +++ b/modules/view/backends/gtk3/text-box.reds @@ -347,6 +347,7 @@ OS-text-box-layout: func [ state [red-block!] size [red-pair!] font [red-object!] + parent [red-object!] cached? [logic!] attrs [handle!] int [red-integer!] @@ -364,6 +365,8 @@ OS-text-box-layout: func [ state: as red-block! values + FACE_OBJ_EXT3 size: as red-pair! values + FACE_OBJ_SIZE font: as red-object! values + FACE_OBJ_FONT + parent: as red-object! values + FACE_OBJ_PARENT + styles: as red-block! values + FACE_OBJ_DATA cached?: TYPE_OF(state) = TYPE_BLOCK either cached? [ @@ -385,7 +388,13 @@ OS-text-box-layout: func [ none/make-in state logic/make-in state false ] - attrs: either TYPE_OF(font) = TYPE_BLOCK [ + if all [ + TYPE_OF(font) <> TYPE_OBJECT + TYPE_OF(parent) = TYPE_OBJECT + ][ + font: as red-object! (object/get-values parent) + FACE_OBJ_FONT + ] + attrs: either TYPE_OF(font) = TYPE_OBJECT [ create-pango-attrs null font ][ create-simple-attrs default-font-name default-font-size null @@ -397,7 +406,6 @@ OS-text-box-layout: func [ pango_layout_set_wrap layout PANGO_WRAP_WORD_CHAR ;-- TBD: apply para pango_layout_set_text layout str -1 - styles: as red-block! values + FACE_OBJ_DATA if all [ TYPE_OF(styles) = TYPE_BLOCK 1 < block/rs-length? styles From 83a74bb8cdab174782a1ccc306d8bc5a595b5a04 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 6 Dec 2019 09:38:01 +0100 Subject: [PATCH 0597/3432] FEAT: extends libRedRT API with lexer-related functions. --- system/utils/libRedRT-exports.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index b8a6e20246..2a0614b7c7 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -47,6 +47,7 @@ red/stack/set-last red/interpreter/eval-path + red/lexer/scan red/none/push-last @@ -373,6 +374,7 @@ red/natives/compress* red/natives/decompress* red/natives/recycle* + red/natives/transcode* ][ red/object/path-parent cell! red/object/field-parent cell! From 818fc7ae16d800699651005c807a11f87506f69b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 6 Dec 2019 09:40:05 +0100 Subject: [PATCH 0598/3432] FEAT: ensures native reference is created for func references in arrays. --- system/emitter.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/emitter.r b/system/emitter.r index a7d0cdabe0..3d59c8cb3c 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -323,7 +323,7 @@ emitter: make-profilable context [ get-word! [ spec: any [ select symbols to word! value - all [compiler/ns-path select symbols compiler/ns-prefix to word! value] + all [compiler/ns-path get-func-ref compiler/ns-prefix to word! value] ] unless spec/4 [append/only spec make block! 1] append spec/4 index? tail data-buf From ee52ea6458ba136a46019885a634605c2cfa1e31 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 6 Dec 2019 12:27:15 +0100 Subject: [PATCH 0599/3432] FEAT: preliminary migrate to Direct2D 1.1 --- modules/view/backends/windows/direct2d.reds | 607 +++++++++++++++++++- modules/view/backends/windows/draw.reds | 49 +- modules/view/backends/windows/text-box.reds | 4 +- modules/view/backends/windows/win32.reds | 15 + 4 files changed, 647 insertions(+), 28 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 556db61cd2..8db3c30ed7 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -10,10 +10,21 @@ Red/System [ } ] +d3d-device: as this! 0 +d3d-ctx: as this! 0 +d2d-ctx: as this! 0 d2d-factory: as this! 0 dwrite-factory: as this! 0 +dxgi-device: as this! 0 +dxgi-adapter: as this! 0 +dxgi-factory: as this! 0 dw-locale-name: as c-string! 0 +pfnDCompositionCreateDevice2: as int-ptr! 0 + +dpi-value: as float32! 96.0 +dpi-x: as float32! 0.0 +dpi-y: as float32! 0.0 dwrite-str-cache: as node! 0 #define D2D_MAX_BRUSHES 64 @@ -21,8 +32,13 @@ dwrite-str-cache: as node! 0 #define D2DERR_RECREATE_TARGET 8899000Ch #define FLT_MAX [as float32! 3.402823466e38] -IID_ID2D1Factory: [06152247h 465A6F50h 8B114592h 07603BFDh] -IID_IDWriteFactory: [B859EE5Ah 4B5BD838h DC1AE8A2h 48DB937Dh] +IID_IDXGISurface: [CAFCB56Ch 48896AC3h 239E47BFh EC60D2BBh] +IID_IDXGIDevice1: [77DB970Fh 48BA6276h 010728BAh 2C39B443h] +;IID_ID2D1Factory: [06152247h 465A6F50h 8B114592h 07603BFDh] +IID_ID2D1Factory1: [BB12D362h 4B9ADAEEh BA141DAAh 1FFA1C40h] +IID_IDWriteFactory: [B859EE5Ah 4B5BD838h DC1AE8A2h 48DB937Dh] +IID_IDXGIFactory2: [50C83A1Ch 4C48E072h 3036B087h D0A636FAh] +IID_IDCompositionDevice: [C37EA93Ah 450DE7AAh 46976FB1h F30704CBh] D2D1_FACTORY_OPTIONS: alias struct! [ debugLevel [integer!] @@ -35,7 +51,7 @@ D3DCOLORVALUE: alias struct! [ a [float32!] ] -D2D_RECT_F: alias struct! [ +RECT32!: alias struct! [ left [float32!] top [float32!] right [float32!] @@ -102,6 +118,37 @@ D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES: alias struct! [ radius.y [float32!] ] +DXGI_SWAP_CHAIN_DESC1: alias struct! [ + Width [integer!] + Height [integer!] + Format [integer!] + Stereo [integer!] + SampleCount [integer!] + SampleQuality [integer!] + BufferUsage [integer!] + BufferCount [integer!] + Scaling [integer!] + SwapEffect [integer!] + AlphaMode [integer!] + Flags [integer!] +] + +D2D1_BITMAP_PROPERTIES1: alias struct! [ + format [integer!] + alphaMode [integer!] + dpiX [float32!] + dpiY [float32!] + options [integer!] + colorContext [int-ptr!] +] + +DXGI_PRESENT_PARAMETERS: alias struct! [ + DirtyRectsCount [integer!] + pDirtyRects [RECT_STRUCT] + pScrollRect [RECT_STRUCT] + pScrollOffset [tagPOINT] +] + CreateSolidColorBrush*: alias function! [ this [this!] color [D3DCOLORVALUE] @@ -142,7 +189,7 @@ DrawLine*: alias function! [ DrawRectangle*: alias function! [ this [this!] - rect [D2D_RECT_F] + rect [RECT32!] brush [integer!] strokeWidth [float32!] strokeStyle [integer!] @@ -150,7 +197,7 @@ DrawRectangle*: alias function! [ FillRectangle*: alias function! [ this [this!] - rect [D2D_RECT_F] + rect [RECT32!] brush [integer!] ] @@ -188,6 +235,26 @@ Resize*: alias function! [ return: [integer!] ] +CreateSwapChainForHwnd*: alias function! [ + this [this!] + pDevice [this!] + hwnd [handle!] + desc [DXGI_SWAP_CHAIN_DESC1] + pFullscreenDesc [int-ptr!] + pRestrictToOutput [int-ptr!] + ppSwapChain [int-ptr!] + return: [integer!] +] + +CreateSwapChainForComposition*: alias function! [ + this [this!] + pDevice [this!] + desc [DXGI_SWAP_CHAIN_DESC1] + pRestrictToOutput [int-ptr!] + ppSwapChain [int-ptr!] + return: [integer!] +] + ID2D1SolidColorBrush: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -232,6 +299,131 @@ ID2D1GradientStopCollection: alias struct! [ GetExtendMode [integer!] ] +IDXGIDevice1: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetPrivateData [integer!] + SetPrivateDataInterface [integer!] + GetPrivateData [integer!] + GetParent [function! [this [this!] riid [int-ptr!] parent [int-ptr!] return: [integer!]]] + GetAdapter [function! [this [this!] adapter [ptr-ptr!] return: [integer!]]] + CreateSurface [integer!] + QueryResourceResidency [integer!] + SetGPUThreadPriority [integer!] + GetGPUThreadPriority [integer!] + SetMaximumFrameLatency [integer!] + GetMaximumFrameLatency [integer!] +] + +IDXGIAdapter: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetPrivateData [integer!] + SetPrivateDataInterface [integer!] + GetPrivateData [integer!] + GetParent [function! [this [this!] riid [int-ptr!] parent [ptr-ptr!] return: [integer!]]] + EnumOutputs [integer!] + GetDesc [integer!] + CheckInterfaceSupport [integer!] +] + +IDXGISwapChain1: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetPrivateData [integer!] + SetPrivateDataInterface [integer!] + GetPrivateData [integer!] + GetParent [function! [this [this!] riid [int-ptr!] parent [int-ptr!] return: [integer!]]] + GetDevice [function! [this [this!] riid [int-ptr!] device [int-ptr!] return: [integer!]]] + Present [function! [this [this!] SyncInterval [integer!] PresentFlags [integer!] return: [integer!]]] + GetBuffer [function! [this [this!] idx [integer!] riid [int-ptr!] buffer [int-ptr!] return: [integer!]]] + SetFullscreenState [integer!] + GetFullscreenState [integer!] + GetDesc [integer!] + ResizeBuffers [integer!] + ResizeTarget [integer!] + GetContainingOutput [integer!] + GetFrameStatistics [integer!] + GetLastPresentCount [integer!] + GetDesc1 [integer!] + GetFullscreenDesc [integer!] + GetHwnd [integer!] + GetCoreWindow [integer!] + Present1 [function! [this [this!] SyncInterval [integer!] PresentFlags [integer!] pPresentParameters [DXGI_PRESENT_PARAMETERS] return: [integer!]]] + IsTemporaryMonoSupported [integer!] + GetRestrictToOutput [integer!] + SetBackgroundColor [integer!] + GetBackgroundColor [integer!] + SetRotation [integer!] + GetRotation [integer!] +] + +IDCompositionDevice: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + Commit [function! [this [this!] return: [integer!]]] + WaitForCommitCompletion [integer!] + GetFrameStatistics [integer!] + CreateTargetForHwnd [function! [this [this!] hwnd [handle!] topmost [logic!] target [int-ptr!] return: [integer!]]] + CreateVisual [function! [this [this!] visual [int-ptr!] return: [integer!]]] + CreateSurface [integer!] + CreateVirtualSurface [integer!] + CreateSurfaceFromHandle [integer!] + CreateSurfaceFromHwnd [integer!] + CreateTranslateTransform [integer!] + CreateScaleTransform [integer!] + CreateRotateTransform [integer!] + CreateSkewTransform [integer!] + CreateMatrixTransform [integer!] + CreateTransformGroup [integer!] + CreateTranslateTransform3D [integer!] + CreateScaleTransform3D [integer!] + CreateRotateTransform3D [integer!] + CreateMatrixTransform3D [integer!] + CreateTransform3DGroup [integer!] + CreateEffectGroup [integer!] + CreateRectangleClip [integer!] + CreateAnimation [integer!] + CreateTransformGroup [integer!] + CheckDeviceState [integer!] +] + +IDCompositionVisual: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetOffsetX [function! [this [this!] x [float32!] return: [integer!]]] + SetOffsetX1 [integer!] + SetOffsetY [function! [this [this!] y [float32!] return: [integer!]]] + SetOffsetY1 [integer!] + SetTransform [integer!] + SetTransform1 [integer!] + SetTransformParent [integer!] + SetEffect [integer!] + SetBitmapInterpolationMode [integer!] + SetBorderMode [integer!] + SetClip [integer!] + SetClip1 [integer!] + SetContent [function! [this [this!] p [this!] return: [integer!]]] + AddVisual [function! [this [this!] v [this!] above [logic!] vv [this!] return: [integer!]]] + RemoveVisual [integer!] + RemoveAllVisuals [integer!] + SetCompositeMode [integer!] + +] + + +IDCompositionTarget: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetRoot [function! [this [this!] visual [this!] return: [integer!]]] +] + ID2D1Factory: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -250,6 +442,189 @@ ID2D1Factory: alias struct! [ CreateHwndRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [ptr-ptr!] return: [integer!]]] CreateDxgiSurfaceRenderTarget [integer!] CreateDCRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] target [int-ptr!] return: [integer!]]] + CreateDevice [function! [this [this!] dxgiDevice [int-ptr!] d2dDevice [ptr-ptr!] return: [integer!]]] +] + +IDXGIFactory2: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetPrivateData [integer!] + SetPrivateDataInterface [integer!] + GetPrivateData [integer!] + GetParent [function! [this [this!] riid [int-ptr!] parent [int-ptr!] return: [integer!]]] + EnumAdapters [function! [this [this!] n [integer!] adapter [int-ptr!] return: [integer!]]] + MakeWindowAssociation [integer!] + GetWindowAssociation [integer!] + CreateSwapChain [integer!] + CreateSoftwareAdapter [integer!] + EnumAdapters1 [integer!] + IsCurrent [integer!] + IsWindowedStereoEnabled [integer!] + CreateSwapChainForHwnd [CreateSwapChainForHwnd*] + CreateSwapChainForCoreWindow [integer!] + GetSharedResourceAdapterLuid [integer!] + RegisterStereoStatusWindow [integer!] + RegisterStereoStatusEvent [integer!] + UnregisterStereoStatus [integer!] + RegisterOcclusionStatusWindow [integer!] + RegisterOcclusionStatusEvent [integer!] + UnregisterOcclusionStatus [integer!] + CreateSwapChainForComposition [CreateSwapChainForComposition*] +] + +ID2D1Device: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetFactory [integer!] + CreateDeviceContext [function! [this [this!] options [integer!] ctx [ptr-ptr!] return: [integer!]]] + CreatePrintControl [integer!] + SetMaximumTextureMemory [integer!] + GetMaximumTextureMemory [integer!] + ClearResources [integer!] + CreatePrintControl2 [integer!] +] + +ID3D11Device: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + CreateBuffer [integer!] + CreateTexture1D [integer!] + CreateTexture2D [integer!] + CreateTexture3D [integer!] + CreateShaderResourceView [integer!] + CreateUnorderedAccessView [integer!] + CreateRenderTargetView [integer!] + CreateDepthStencilView [integer!] + CreateInputLayout [integer!] + CreateVertexShader [integer!] + CreateGeometryShader [integer!] + CreateGeometryShaderWithStreamOutput [integer!] + CreatePixelShader [integer!] + CreateHullShader [integer!] + CreateDomainShader [integer!] + CreateComputeShader [integer!] + CreateClassLinkage [integer!] + CreateBlendState [integer!] + CreateDepthStencilState [integer!] + CreateRasterizerState [integer!] + CreateSamplerState [integer!] + CreateQuery [integer!] + CreatePredicate [integer!] + CreateCounter [integer!] + CreateDeferredContext [integer!] + OpenSharedResource [integer!] + CheckFormatSupport [integer!] + CheckMultisampleQualityLevels [integer!] + CheckCounterInfo [integer!] + CheckCounter [integer!] + CheckFeatureSupport [integer!] + GetPrivateData [integer!] + SetPrivateData [integer!] + SetPrivateDataInterface [integer!] + GetFeatureLevel [integer!] + GetCreationFlags [integer!] + GetDeviceRemovedReason [integer!] + GetImmediateContext [integer!] + SetExceptionMode [integer!] + GetExceptionMode [integer!] +] + +ID2D1DeviceContext: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetFactory [integer!] + CreateBitmap [integer!] + CreateBitmapFromWicBitmap [integer!] + CreateSharedBitmap [integer!] + CreateBitmapBrush [integer!] + CreateSolidColorBrush [CreateSolidColorBrush*] + CreateGradientStopCollection [CreateGradientStopCollection*] + CreateLinearGradientBrush [integer!] + CreateRadialGradientBrush [CreateRadialGradientBrush*] + CreateCompatibleRenderTarget [integer!] + CreateLayer [integer!] + CreateMesh [integer!] + DrawLine [DrawLine*] + DrawRectangle [DrawRectangle*] + FillRectangle [FillRectangle*] + DrawRoundedRectangle [integer!] + FillRoundedRectangle [integer!] + DrawEllipse [DrawEllipse*] + FillEllipse [FillEllipse*] + DrawGeometry [integer!] + FillGeometry [integer!] + FillMesh [integer!] + FillOpacityMask [integer!] + DrawBitmap [integer!] + DrawText [integer!] + DrawTextLayout [DrawTextLayout*] + DrawGlyphRun [integer!] + SetTransform [SetTransform*] + GetTransform [integer!] + SetAntialiasMode [integer!] + GetAntialiasMode [integer!] + SetTextAntialiasMode [function! [this [this!] mode [integer!]]] + GetTextAntialiasMode [integer!] + SetTextRenderingParams [integer!] + GetTextRenderingParams [integer!] + SetTags [integer!] + GetTags [integer!] + PushLayer [integer!] + PopLayer [integer!] + Flush [integer!] + SaveDrawingState [integer!] + RestoreDrawingState [integer!] + PushAxisAlignedClip [function! [this [this!] rc [RECT32!] mode [integer!]]] + PopAxisAlignedClip [function! [this [this!]]] + Clear [function! [this [this!] color [D3DCOLORVALUE]]] + BeginDraw [function! [this [this!]]] + EndDraw [function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!] return: [integer!]]] + GetPixelFormat [integer!] + SetDpi [function! [this [this!] x [float32!] y [float32!]]] + GetDpi [integer!] + GetSize [integer!] + GetPixelSize [integer!] + GetMaximumBitmapSize [integer!] + IsSupported [integer!] + CtxCreateBitmap [integer!] + CtxCreateBitmapFromWicBitmap [integer!] + CreateColorContext [integer!] + CreateColorContextFromFilename [integer!] + CreateColorContextFromWicColorContext [integer!] + CreateBitmapFromDxgiSurface [function! [this [this!] surface [int-ptr!] props [D2D1_BITMAP_PROPERTIES1] bitmap [int-ptr!] return: [integer!]]] + CreateEffect [integer!] + CtxCreateGradientStopCollection [integer!] + CreateImageBrush [integer!] + CtxCreateBitmapBrush [integer!] + CreateCommandList [integer!] + IsDxgiFormatSupported [integer!] + IsBufferPrecisionSupported [integer!] + GetImageLocalBounds [integer!] + GetImageWorldBounds [integer!] + GetGlyphRunWorldBounds [integer!] + GetDevice [function! [this [this!] dev [int-ptr!]]] + SetTarget [function! [this [this!] bmp [this!]]] + GetTarget [integer!] + SetRenderingControls [integer!] + GetRenderingControls [integer!] + SetPrimitiveBlend [integer!] + GetPrimitiveBlend [integer!] + SetUnitMode [integer!] + GetUnitMode [integer!] + CtxDrawGlyphRun [integer!] + DrawImage [integer!] + DrawGdiMetafile [integer!] + CtxDrawBitmap [integer!] + CtxPushLayer [integer!] + InvalidateEffectInputRectangle [integer!] + GetEffectInvalidRectangleCount [integer!] + GetEffectInvalidRectangles [integer!] + GetEffectRequiredInputRectangles [integer!] + CtxFillOpacityMask [integer!] ] ID2D1HwndRenderTarget: alias struct! [ @@ -649,6 +1024,13 @@ IDWriteFontFace: alias struct! [ GetGdiCompatibleGlyphMetrics [integer!] ] +DCompositionCreateDevice2!: alias function! [ + render-dev [this!] + iid [int-ptr!] + device [int-ptr!] + return: [integer!] +] + D2D1CreateFactory!: alias function! [ type [integer!] riid [int-ptr!] @@ -670,6 +1052,14 @@ GetUserDefaultLocaleName!: alias function! [ return: [integer!] ] +render-target!: alias struct! [ + bitmap [this!] + swapchain [this!] + dcomp-device [this!] + dcomp-target [this!] + dcomp-visual [this!] +] + #define ConvertPointSizeToDIP(size) (as float32! 96 * size / 72) select-brush: func [ @@ -717,6 +1107,14 @@ DX-init: func [ D2D1CreateFactory [D2D1CreateFactory!] DWriteCreateFactory [DWriteCreateFactory!] GetUserDefaultLocaleName [GetUserDefaultLocaleName!] + d2d [ID2D1Factory] + d3d [ID3D11Device] + d2d-dev [ID2D1Device] + dxgi [IDXGIDevice1] + adapter [IDXGIAdapter] + ctx [ptr-value!] + unk [IUnknown] + d2d-device [this!] ][ dll: LoadLibraryA "d2d1.dll" if null? dll [winxp?: yes exit] @@ -729,15 +1127,79 @@ DX-init: func [ dw-locale-name: as c-string! allocate 85 GetUserDefaultLocaleName dw-locale-name 85 + if win8+? [ + dll: LoadLibraryA "dcomp.dll" + pfnDCompositionCreateDevice2: GetProcAddress dll "DCompositionCreateDevice2" + ] + options: 0 ;-- debugLevel - hr: D2D1CreateFactory 0 IID_ID2D1Factory :options :factory ;-- D2D1_FACTORY_TYPE_SINGLE_THREADED: 0 + + hr: D3D11CreateDevice + null + 1 ;-- D3D_DRIVER_TYPE_HARDWARE + null + 33 ;-- D3D11_CREATE_DEVICE_BGRA_SUPPORT or D3D11_CREATE_DEVICE_SINGLETHREADED + null + 0 + 7 ;-- D3D11_SDK_VERSION + :factory + null + :ctx + assert zero? hr + + d3d-device: as this! factory/value + d3d-ctx: as this! ctx/value + + d3d: as ID3D11Device d3d-device/vtbl + ;-- create DXGI device + hr: d3d/QueryInterface d3d-device IID_IDXGIDevice1 as interface! :factory + assert zero? hr + dxgi-device: as this! factory/value + + hr: D2D1CreateFactory 0 IID_ID2D1Factory1 :options :factory ;-- D2D1_FACTORY_TYPE_SINGLE_THREADED: 0 assert zero? hr d2d-factory: as this! factory/value + + ;-- get system DPI + d2d: as ID2D1Factory d2d-factory/vtbl + ;d2d/GetDesktopDpi d2d-factory :dpi-x :dpi-y + + dpi-x: as float32! log-pixels-x + dpi-y: as float32! log-pixels-y + dpi-value: dpi-y + + ;-- create D2D Device + hr: d2d/CreateDevice d2d-factory as int-ptr! dxgi-device :factory + d2d-device: as this! factory/value + assert zero? hr + + ;-- create D2D context + d2d-dev: as ID2D1Device d2d-device/vtbl + hr: d2d-dev/CreateDeviceContext d2d-device 0 :factory + assert zero? hr + d2d-ctx: as this! factory/value + + ;-- get dxgi adapter + dxgi: as IDXGIDevice1 dxgi-device/vtbl + hr: dxgi/GetAdapter dxgi-device :factory + assert zero? hr + + ;-- get Dxgi factory + dxgi-adapter: as this! factory/value + adapter: as IDXGIAdapter dxgi-adapter/vtbl + hr: adapter/GetParent dxgi-adapter IID_IDXGIFactory2 :factory + assert zero? hr + dxgi-factory: as this! factory/value + hr: DWriteCreateFactory 0 IID_IDWriteFactory :factory ;-- DWRITE_FACTORY_TYPE_SHARED: 0 assert zero? hr dwrite-factory: as this! factory/value str: string/rs-make-at ALLOC_TAIL(root) 1024 dwrite-str-cache: str/node + + COM_SAFE_RELEASE(unk dxgi-device) + COM_SAFE_RELEASE(unk d2d-device) + COM_SAFE_RELEASE(unk dxgi-adapter) ] DX-cleanup: func [/local unk [IUnknown]][ @@ -746,6 +1208,137 @@ DX-cleanup: func [/local unk [IUnknown]][ free as byte-ptr! dw-locale-name ] +logical-to-pixel: func [ + num [float32!] + return: [integer!] +][ + as-integer (num * dpi-value / as-float32 96.0) +] + +pixel-to-logical: func [ + num [integer!] + return: [float32!] +][ + (as-float32 num * 96) / dpi-value +] + +create-dcomp: func [ + target [render-target!] + hWnd [handle!] + d2d-dc [ID2D1DeviceContext] + /local + dev [integer!] + d2d-device [this!] + hr [integer!] + unk [IUnknown] + dcomp-dev [IDCompositionDevice] + dcomp [IDCompositionTarget] + this [this!] + tg [this!] + visual [IDCompositionVisual] + DCompositionCreateDevice2 [DCompositionCreateDevice2!] +][ + dev: 0 + d2d-dc/GetDevice d2d-ctx :dev + d2d-device: as this! dev + DCompositionCreateDevice2: as DCompositionCreateDevice2! pfnDCompositionCreateDevice2 + hr: DCompositionCreateDevice2 d2d-device IID_IDCompositionDevice :dev + COM_SAFE_RELEASE(unk d2d-device) + assert hr = 0 + + this: as this! dev + target/dcomp-device: this + + dcomp-dev: as IDCompositionDevice this/vtbl + hr: dcomp-dev/CreateTargetForHwnd this hWnd yes :dev + assert zero? hr + tg: as this! dev + target/dcomp-target: tg + + hr: dcomp-dev/CreateVisual this :dev + assert zero? hr + this: as this! dev + target/dcomp-visual: this + + visual: as IDCompositionVisual this/vtbl + visual/SetContent this target/swapchain + + dcomp: as IDCompositionTarget tg/vtbl + hr: dcomp/SetRoot tg this + assert zero? hr + hr: dcomp-dev/Commit target/dcomp-device + assert zero? hr +] + +create-render-target: func [ + hWnd [handle!] + return: [render-target!] + /local + rt [render-target!] + rc [RECT_STRUCT value] + desc [DXGI_SWAP_CHAIN_DESC1 value] + dxgi [IDXGIFactory2] + int [integer!] + sc [IDXGISwapChain1] + this [this!] + hr [integer!] + buf [integer!] + props [D2D1_BITMAP_PROPERTIES1 value] + bmp [integer!] + d2d [ID2D1DeviceContext] + unk [IUnknown] +][ + GetClientRect hWnd :rc + zero-memory as byte-ptr! :desc size? DXGI_SWAP_CHAIN_DESC1 + + desc/Width: rc/right - rc/left + desc/Height: rc/bottom - rc/top + desc/Format: 87 ;-- DXGI_FORMAT_B8G8R8A8_UNORM + desc/SampleCount: 1 + desc/BufferUsage: 20h ;-- DXGI_USAGE_RENDER_TARGET_OUTPUT + desc/BufferCount: 2 + desc/AlphaMode: 1 ;-- DXGI_ALPHA_MODE_PREMULTIPLIED + desc/SwapEffect: 3 ;-- DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + + int: 0 + buf: 0 + dxgi: as IDXGIFactory2 dxgi-factory/vtbl + either win8+? [ ;-- use direct composition + hr: dxgi/CreateSwapChainForComposition dxgi-factory d3d-device desc null :int + ][ + desc/AlphaMode: 0 + hr: dxgi/CreateSwapChainForHwnd dxgi-factory d3d-device hWnd desc null null :int + ] + assert zero? hr + + ;-- get back buffer from the swap chain + this: as this! int + sc: as IDXGISwapChain1 this/vtbl + hr: sc/GetBuffer this 0 IID_IDXGISurface :buf + assert zero? hr + + ;-- create a bitmap from the buffer + props/format: 87 ;-- DXGI_FORMAT_B8G8R8A8_UNORM + props/alphaMode: 1 ;-- D2D1_ALPHA_MODE_PREMULTIPLIED + props/dpiX: dpi-x + props/dpiY: dpi-y + props/options: 3 ;-- D2D1_BITMAP_OPTIONS_TARGET or D2D1_BITMAP_OPTIONS_CANNOT_DRAW + props/colorContext: null + bmp: 0 + d2d: as ID2D1DeviceContext d2d-ctx/vtbl + d2d/setDpi d2d-ctx dpi-x dpi-y + hr: d2d/CreateBitmapFromDxgiSurface d2d-ctx as int-ptr! buf props :bmp + assert hr = 0 + + rt: as render-target! allocate size? render-target! + rt/swapchain: as this! int + rt/bitmap: as this! bmp + + COM_SAFE_RELEASE_OBJ(unk buf) + if win8+? [create-dcomp rt hWnd d2d] + rt +] + to-dx-color: func [ color [integer!] clr-ptr [D3DCOLORVALUE] @@ -837,7 +1430,7 @@ get-hwnd-render-target: func [ if null? target [ pp: as ptr-ptr! allocate 4 * size? int-ptr! target: pp - pp/value: as int-ptr! create-hwnd-render-target hWnd + pp/value: as int-ptr! create-render-target hWnd pp: pp + 1 pp/value: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! pp: pp + 1 diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 5ed754169e..d67010c9ba 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -19,7 +19,7 @@ draw-begin: func [ hWnd [handle!] /local this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] _11 [integer!] _12 [integer!] _21 [integer!] @@ -37,6 +37,7 @@ draw-begin: func [ clr [red-tuple!] text [red-string!] pos [red-pair! value] + render [render-target!] ][ zero-memory as byte-ptr! ctx size? draw-ctx! ctx/pen-width: as float32! 1.0 @@ -45,34 +46,36 @@ draw-begin: func [ ctx/font-color: -1 target: get-hwnd-render-target hWnd - this: as this! target/value - ctx/dc: as handle! this + ctx/dc: as int-ptr! d2d-ctx ctx/brushes: as int-ptr! target - rt: as ID2D1HwndRenderTarget this/vtbl - rt/SetTextAntialiasMode this 1 ;-- ClearType + this: d2d-ctx + render: as render-target! target/value + dc: as ID2D1DeviceContext this/vtbl + dc/SetTextAntialiasMode this 1 ;-- ClearType + dc/SetTarget this render/bitmap - rt/BeginDraw this + dc/BeginDraw this _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 m: as D2D_MATRIX_3X2_F :_32 m/_11: as float32! 1.0 m/_22: as float32! 1.0 - rt/SetTransform this m ;-- set to identity matrix + dc/SetTransform this m ;-- set to identity matrix values: get-face-values hWnd clr: as red-tuple! values + FACE_OBJ_COLOR bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1] if bg-clr <> -1 [ ;-- paint background - rt/Clear this to-dx-color bg-clr null + dc/Clear this to-dx-color bg-clr null ] d3d-clr: to-dx-color ctx/pen-color null brush: 0 - rt/CreateSolidColorBrush this d3d-clr null :brush + dc/CreateSolidColorBrush this d3d-clr null :brush ctx/pen: brush brush: 0 - rt/CreateSolidColorBrush this d3d-clr null :brush + dc/CreateSolidColorBrush this d3d-clr null :brush ctx/brush: brush text: as red-string! values + FACE_OBJ_TEXT @@ -97,13 +100,21 @@ draw-end: func [ ctx [draw-ctx!] hWnd [handle!] /local - this [this!] - rt [ID2D1HwndRenderTarget] - hr [integer!] + this [this!] + dc [ID2D1DeviceContext] + sc [IDXGISwapChain1] + rt [render-target!] + hr [integer!] ][ this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl - hr: rt/EndDraw this null null + dc: as ID2D1DeviceContext this/vtbl + hr: dc/EndDraw this null null + dc/SetTarget this null + + rt: as render-target! ctx/brushes/value + this: rt/swapchain + sc: as IDXGISwapChain1 this/vtbl + sc/Present this 0 0 release-d2d ctx @@ -274,14 +285,14 @@ OS-draw-line: func [ pt0 [red-pair!] pt1 [red-pair!] this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] ][ this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl + dc: as ID2D1DeviceContext this/vtbl pt0: point while [pt1: pt0 + 1 pt1 <= end][ - rt/DrawLine + dc/DrawLine this as float32! pt0/x as float32! pt0/y as float32! pt1/x as float32! pt1/y @@ -331,7 +342,7 @@ OS-draw-box: func [ /local this [this!] rt [ID2D1HwndRenderTarget] - rc [D2D_RECT_F value] + rc [RECT32! value] ][ this: as this! ctx/dc rt: as ID2D1HwndRenderTarget this/vtbl diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index 3d13b69e62..ba8abc3558 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -385,7 +385,7 @@ txt-box-draw-background: func [ width [integer!] top [integer!] left [integer!] - rc [D2D_RECT_F] + rc [RECT32!] ][ styles: as red-vector! target/4 if any [ @@ -408,7 +408,7 @@ txt-box-draw-background: func [ hits: as DWRITE_HIT_TEST_METRICS line-metrics left: 0 - rc: as D2D_RECT_F :left + rc: as RECT32! :left x: as float32! pos/x y: as float32! pos/y s: GET_BUFFER(styles) diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 10e233af8d..9a3bcbc90b 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -2800,6 +2800,21 @@ XFORM!: alias struct! [ return: [logic!] ] ] + "d3d11.dll" stdcall [ + D3D11CreateDevice: "D3D11CreateDevice" [ + adapter [int-ptr!] + DriverType [integer!] + Software [int-ptr!] + Flags [integer!] + pFeatures [int-ptr!] + Features [integer!] + SDKVersion [integer!] + ppDevice [ptr-ptr!] + pFeatLevel [int-ptr!] + ppContext [ptr-ptr!] + return: [integer!] + ] + ] "ole32.dll" stdcall [ CoTaskMemFree: "CoTaskMemFree" [ pv [integer!] From 9d0596ac072c13e48f8499900ce7b8a499fad443 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 6 Dec 2019 15:06:28 +0100 Subject: [PATCH 0600/3432] FIX: rich-text does not work properly using Direct2D 1.1 --- modules/view/backends/windows/direct2d.reds | 9 +++-- modules/view/backends/windows/draw.reds | 18 ++++++--- modules/view/backends/windows/text-box.reds | 44 +++++++++++---------- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 8db3c30ed7..9783030466 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -1053,6 +1053,7 @@ GetUserDefaultLocaleName!: alias function! [ ] render-target!: alias struct! [ + dc [this!] bitmap [this!] swapchain [this!] dcomp-device [this!] @@ -1331,6 +1332,7 @@ create-render-target: func [ assert hr = 0 rt: as render-target! allocate size? render-target! + rt/dc: d2d-ctx rt/swapchain: as this! int rt/bitmap: as this! bmp @@ -1376,9 +1378,10 @@ d2d-release-target: func [ COM_SAFE_RELEASE_OBJ(obj brushes/2) brushes: brushes + 2 ] - this: as this! target/value - rt: as ID2D1HwndRenderTarget this/vtbl - rt/Release this + ;TBD + ;this: as this! target/value + ;rt: as ID2D1HwndRenderTarget this/vtbl + ;rt/Release this free as byte-ptr! target ] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index d67010c9ba..71a2127182 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -17,6 +17,10 @@ draw-state!: alias struct! [unused [integer!]] draw-begin: func [ ctx [draw-ctx!] hWnd [handle!] + img [red-image!] + on-graphic? [logic!] + paint? [logic!] + return: [draw-ctx!] /local this [this!] dc [ID2D1DeviceContext] @@ -83,6 +87,7 @@ draw-begin: func [ pos/x: 0 pos/y: 0 OS-draw-text ctx pos as red-string! get-face-obj hWnd yes ] + ctx ] release-d2d: func [ @@ -97,8 +102,11 @@ release-d2d: func [ ] draw-end: func [ - ctx [draw-ctx!] - hWnd [handle!] + ctx [draw-ctx!] + hWnd [handle!] + on-graphic? [logic!] + cache? [logic!] + paint? [logic!] /local this [this!] dc [ID2D1DeviceContext] @@ -159,12 +167,12 @@ OS-draw-text: func [ return: [logic!] /local this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] layout [this!] fmt [this!] ][ this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl + dc: as ID2D1DeviceContext this/vtbl layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! OS-text-box-layout as red-object! text ctx/brushes 0 yes @@ -173,7 +181,7 @@ OS-draw-text: func [ create-text-layout text fmt 0 0 ] txt-box-draw-background ctx/brushes pos layout - rt/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 + dc/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 true ] diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index ba8abc3558..06f513eac7 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -24,23 +24,25 @@ line-metrics: as DWRITE_LINE_METRICS 0 max-line-cnt: 0 OS-text-box-color: func [ - dc [handle!] + target [handle!] layout [handle!] pos [integer!] len [integer!] color [integer!] /local this [this!] - rt [ID2D1HwndRenderTarget] + rt [render-target!] + dc [ID2D1DeviceContext] dl [IDWriteTextLayout] brush [integer!] ][ - brush: select-brush dc + 1 color + brush: select-brush target + 1 color if zero? brush [ - this: as this! dc/value - rt: as ID2D1HwndRenderTarget this/vtbl - rt/CreateSolidColorBrush this to-dx-color color null null :brush - put-brush dc + 1 color brush + rt: as render-target! target/value + this: rt/dc + dc: as ID2D1DeviceContext this/vtbl + dc/CreateSolidColorBrush this to-dx-color color null null :brush + put-brush target + 1 color brush ] this: as this! layout @@ -49,28 +51,30 @@ OS-text-box-color: func [ ] OS-text-box-background: func [ - dc [handle!] + target [handle!] layout [handle!] pos [integer!] len [integer!] color [integer!] /local this [this!] - rt [ID2D1HwndRenderTarget] + rt [render-target!] + dc [ID2D1DeviceContext] cache [red-vector!] brush [integer!] ][ - cache: as red-vector! dc/4 + cache: as red-vector! target/4 if null? cache [ cache: vector/make-at ALLOC_TAIL(root) 128 TYPE_INTEGER 4 - dc/4: as-integer cache + target/4: as-integer cache ] - brush: select-brush dc + 1 color + brush: select-brush target + 1 color if zero? brush [ - this: as this! dc/value - rt: as ID2D1HwndRenderTarget this/vtbl - rt/CreateSolidColorBrush this to-dx-color color null null :brush - put-brush dc + 1 color brush + rt: as render-target! target/value + this: rt/dc + dc: as ID2D1DeviceContext this/vtbl + dc/CreateSolidColorBrush this to-dx-color color null null :brush + put-brush target + 1 color brush ] vector/rs-append-int cache pos vector/rs-append-int cache len @@ -370,7 +374,7 @@ txt-box-draw-background: func [ layout [this!] /local this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] styles [red-vector!] line-cnt [integer!] dl [IDWriteTextLayout] @@ -393,8 +397,8 @@ txt-box-draw-background: func [ zero? vector/rs-length? styles ][exit] - this: as this! target/value - rt: as ID2D1HwndRenderTarget this/vtbl + this: d2d-ctx + dc: as ID2D1DeviceContext this/vtbl dl: as IDWriteTextLayout layout/vtbl line-cnt: 0 @@ -426,7 +430,7 @@ txt-box-draw-background: func [ rc/bottom: as float32! top + height rc/top: as float32! top rc/left: as float32! left - rt/FillRectangle this rc p/3 + dc/FillRectangle this rc p/3 hit: hit + 1 ] p: p + 3 From bf63def14ab42af915597b286f0912198d3e60d9 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 7 Dec 2019 18:10:45 +0100 Subject: [PATCH 0601/3432] FEAT: code refactoring for Direct2D DRAW backend. --- environment/console/GUI/gui-console.red | 4 +- modules/view/backends/windows/direct2d.reds | 29 +++---- modules/view/backends/windows/draw.reds | 24 +++--- modules/view/backends/windows/text-box.reds | 16 ++-- runtime/definitions.reds | 93 +++++++++++++-------- 5 files changed, 92 insertions(+), 74 deletions(-) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index a5346401b8..0233a12e76 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -139,8 +139,8 @@ gui-console-ctx: context [ show-caret: func [][unless caret/enabled? [caret/enabled?: yes]] setup-faces: does [ - console/pane: reduce [caret] - append win/pane reduce [console tips] + ;console/pane: reduce [caret] + append win/pane reduce [console caret tips] win/menu: [ "File" [ "Run..." run-file diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 9783030466..81cbcc77d2 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -1054,6 +1054,9 @@ GetUserDefaultLocaleName!: alias function! [ render-target!: alias struct! [ dc [this!] + brushes [int-ptr!] + brushes-cnt [uint!] + styles [red-vector!] bitmap [this!] swapchain [this!] dcomp-device [this!] @@ -1273,9 +1276,8 @@ create-dcomp: func [ create-render-target: func [ hWnd [handle!] - return: [render-target!] + rt [render-target!] /local - rt [render-target!] rc [RECT_STRUCT value] desc [DXGI_SWAP_CHAIN_DESC1 value] dxgi [IDXGIFactory2] @@ -1331,7 +1333,6 @@ create-render-target: func [ hr: d2d/CreateBitmapFromDxgiSurface d2d-ctx as int-ptr! buf props :bmp assert hr = 0 - rt: as render-target! allocate size? render-target! rt/dc: d2d-ctx rt/swapchain: as this! int rt/bitmap: as this! bmp @@ -1424,22 +1425,16 @@ create-hwnd-render-target: func [ get-hwnd-render-target: func [ hWnd [handle!] - return: [ptr-ptr!] + return: [render-target!] /local - target [ptr-ptr!] - pp [ptr-ptr!] + target [render-target!] ][ - target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 + target: as render-target! GetWindowLong hWnd wc-offset - 24 if null? target [ - pp: as ptr-ptr! allocate 4 * size? int-ptr! - target: pp - pp/value: as int-ptr! create-render-target hWnd - pp: pp + 1 - pp/value: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! - pp: pp + 1 - pp/value: null - pp: pp + 1 - pp/value: null ;-- for text-box! background color + target: as render-target! allocate size? render-target! + zero-memory as byte-ptr! target size? render-target! + create-render-target hWnd target + target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! SetWindowLong hWnd wc-offset - 24 as-integer target ] target @@ -1712,7 +1707,7 @@ draw-text-d2d: func [ this: create-dc-render-target dc rc rt: as ID2D1DCRenderTarget this/vtbl - rt/SetTextAntialiasMode this 1 ;-- ClearType + ;rt/SetTextAntialiasMode this 1 ;-- ClearType rt/BeginDraw this _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 71a2127182..f1d3c86500 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -33,7 +33,7 @@ draw-begin: func [ m [D2D_MATRIX_3X2_F] bg-clr [integer!] brush [integer!] - target [ptr-ptr!] + target [render-target!] brushes [int-ptr!] pbrush [ID2D1SolidColorBrush] d3d-clr [D3DCOLORVALUE] @@ -41,7 +41,6 @@ draw-begin: func [ clr [red-tuple!] text [red-string!] pos [red-pair! value] - render [render-target!] ][ zero-memory as byte-ptr! ctx size? draw-ctx! ctx/pen-width: as float32! 1.0 @@ -49,15 +48,14 @@ draw-begin: func [ ctx/hwnd: hWnd ctx/font-color: -1 + this: d2d-ctx target: get-hwnd-render-target hWnd - ctx/dc: as int-ptr! d2d-ctx - ctx/brushes: as int-ptr! target + ctx/dc: as ptr-ptr! this + ctx/target: as int-ptr! target - this: d2d-ctx - render: as render-target! target/value dc: as ID2D1DeviceContext this/vtbl - dc/SetTextAntialiasMode this 1 ;-- ClearType - dc/SetTarget this render/bitmap + ;dc/SetTextAntialiasMode this 1 ;-- ClearType + dc/SetTarget this target/bitmap dc/BeginDraw this _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 @@ -114,12 +112,12 @@ draw-end: func [ rt [render-target!] hr [integer!] ][ - this: as this! ctx/dc + rt: as render-target! ctx/target + this: rt/dc dc: as ID2D1DeviceContext this/vtbl hr: dc/EndDraw this null null dc/SetTarget this null - rt: as render-target! ctx/brushes/value this: rt/swapchain sc: as IDXGISwapChain1 this/vtbl sc/Present this 0 0 @@ -129,7 +127,7 @@ draw-end: func [ switch hr [ COM_S_OK [ValidateRect hWnd null] D2DERR_RECREATE_TARGET [ - d2d-release-target as ptr-ptr! ctx/brushes + d2d-release-target as ptr-ptr! rt ctx/dc: null SetWindowLong hWnd wc-offset - 24 0 InvalidateRect hWnd null 0 @@ -175,12 +173,12 @@ OS-draw-text: func [ dc: as ID2D1DeviceContext this/vtbl layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! - OS-text-box-layout as red-object! text ctx/brushes 0 yes + OS-text-box-layout as red-object! text as render-target! ctx/target 0 yes ][ fmt: as this! create-text-format as red-object! text null create-text-layout text fmt 0 0 ] - txt-box-draw-background ctx/brushes pos layout + txt-box-draw-background ctx/target pos layout dc/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 true ] diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index 06f513eac7..8bc0ef7af1 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -38,7 +38,7 @@ OS-text-box-color: func [ ][ brush: select-brush target + 1 color if zero? brush [ - rt: as render-target! target/value + rt: as render-target! target this: rt/dc dc: as ID2D1DeviceContext this/vtbl dc/CreateSolidColorBrush this to-dx-color color null null :brush @@ -63,14 +63,14 @@ OS-text-box-background: func [ cache [red-vector!] brush [integer!] ][ - cache: as red-vector! target/4 + rt: as render-target! target + cache: rt/styles if null? cache [ cache: vector/make-at ALLOC_TAIL(root) 128 TYPE_INTEGER 4 - target/4: as-integer cache + rt/styles: cache ] brush: select-brush target + 1 color if zero? brush [ - rt: as render-target! target/value this: rt/dc dc: as ID2D1DeviceContext this/vtbl dc/CreateSolidColorBrush this to-dx-color color null null :brush @@ -284,7 +284,7 @@ OS-text-box-metrics: func [ OS-text-box-layout: func [ box [red-object!] - target [int-ptr!] + target [render-target!] ft-clr [integer!] catch? [logic!] return: [this!] @@ -319,7 +319,7 @@ OS-text-box-layout: func [ ] hWnd: hidden-hwnd ] - target: as int-ptr! get-hwnd-render-target hWnd + target: get-hwnd-render-target hWnd ] either TYPE_OF(state) = TYPE_BLOCK [ @@ -339,7 +339,7 @@ OS-text-box-layout: func [ ] handle/make-at pval + 1 as-integer target - vec: as red-vector! target/4 + vec: target/styles if vec <> null [vector/rs-clear vec] set-text-format fmt as red-object! values + FACE_OBJ_PARA @@ -363,7 +363,7 @@ OS-text-box-layout: func [ TYPE_OF(styles) = TYPE_BLOCK 1 < block/rs-length? styles ][ - parse-text-styles target as handle! layout styles 7FFFFFFFh catch? + parse-text-styles as int-ptr! target as handle! layout styles 7FFFFFFFh catch? ] layout ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 4f3a23281a..68fbc4e297 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -255,40 +255,65 @@ Red/System [ pattern-image-pen [integer!] ] - draw-ctx!: alias struct! [ - dc [int-ptr!] ;-- OS drawing object - hwnd [int-ptr!] ;-- Window's handle - pen [integer!] - brush [integer!] - pen-join [integer!] - pen-cap [integer!] - pen-width [float32!] - pen-style [integer!] - pen-color [integer!] ;-- 00bbggrr format - brush-color [integer!] ;-- 00bbggrr format - font-color [integer!] - bitmap [int-ptr!] - brushes [int-ptr!] - graphics [integer!] ;-- gdiplus graphics - gp-state [integer!] - gp-pen [integer!] ;-- gdiplus pen - gp-pen-type [brush-type!] ;-- gdiplus pen type (for texture, another set of transformation functions must be applied) - gp-pen-saved [integer!] - gp-brush [integer!] ;-- gdiplus brush - gp-brush-type [brush-type!] ;-- gdiplus brush type (for texture, another set of transformation functions must be applied) - gp-font [integer!] ;-- gdiplus font - gp-font-brush [integer!] - gp-matrix [integer!] - gp-path [integer!] - image-attr [integer!] ;-- gdiplus image attributes - scale-ratio [float32!] - pen? [logic!] - brush? [logic!] - on-image? [logic!] ;-- drawing on image? - alpha-pen? [logic!] - alpha-brush? [logic!] - font-color? [logic!] - other [other!] + #either legacy = none [ + draw-ctx!: alias struct! [ + dc [ptr-ptr!] + target [int-ptr!] + hwnd [int-ptr!] ;-- Window's handle + pen [integer!] + brush [integer!] + pen-join [integer!] + pen-cap [integer!] + pen-width [float32!] + pen-style [integer!] + pen-color [integer!] + brush-color [integer!] + font-color [integer!] + bitmap [int-ptr!] + scale-ratio [float32!] + pen? [logic!] + brush? [logic!] + on-image? [logic!] ;-- drawing on image? + alpha-pen? [logic!] + alpha-brush? [logic!] + font-color? [logic!] + ] + ][ + draw-ctx!: alias struct! [ + dc [int-ptr!] ;-- OS drawing object + hwnd [int-ptr!] ;-- Window's handle + pen [integer!] + brush [integer!] + pen-join [integer!] + pen-cap [integer!] + pen-width [float32!] + pen-style [integer!] + pen-color [integer!] ;-- 00bbggrr format + brush-color [integer!] ;-- 00bbggrr format + font-color [integer!] + bitmap [int-ptr!] + brushes [int-ptr!] + graphics [integer!] ;-- gdiplus graphics + gp-state [integer!] + gp-pen [integer!] ;-- gdiplus pen + gp-pen-type [brush-type!] ;-- gdiplus pen type (for texture, another set of transformation functions must be applied) + gp-pen-saved [integer!] + gp-brush [integer!] ;-- gdiplus brush + gp-brush-type [brush-type!] ;-- gdiplus brush type (for texture, another set of transformation functions must be applied) + gp-font [integer!] ;-- gdiplus font + gp-font-brush [integer!] + gp-matrix [integer!] + gp-path [integer!] + image-attr [integer!] ;-- gdiplus image attributes + scale-ratio [float32!] + pen? [logic!] + brush? [logic!] + on-image? [logic!] ;-- drawing on image? + alpha-pen? [logic!] + alpha-brush? [logic!] + font-color? [logic!] + other [other!] + ] ] ][ #define O_RDONLY 0 From d9a278b1e8f326e175388cd8f5a7c888fefd835e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 8 Dec 2019 22:41:50 +0100 Subject: [PATCH 0602/3432] FIX: [R/S] ensures that function pointers in arrays are relocatable (Windows). --- system/emitter.r | 2 +- system/formats/PE.r | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/emitter.r b/system/emitter.r index 3d59c8cb3c..a7d0cdabe0 100644 --- a/system/emitter.r +++ b/system/emitter.r @@ -323,7 +323,7 @@ emitter: make-profilable context [ get-word! [ spec: any [ select symbols to word! value - all [compiler/ns-path get-func-ref compiler/ns-prefix to word! value] + all [compiler/ns-path select symbols compiler/ns-prefix to word! value] ] unless spec/4 [append/only spec make block! 1] append spec/4 index? tail data-buf diff --git a/system/formats/PE.r b/system/formats/PE.r index 74b903a5db..3802c7164f 100644 --- a/system/formats/PE.r +++ b/system/formats/PE.r @@ -677,7 +677,7 @@ context [ code-refs: make block! 1000 data-refs: make block! 100 foreach [name spec] job/symbols [ - either all [spec/1 = 'global block? spec/4][ + either all [find [global native] spec/1 block? spec/4][ foreach ref spec/4 [append data-refs ref] ][ foreach ref spec/3 [append code-refs ref] From fb1ed95dc1da729152761f6a8cb54c8e2355f108 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 8 Dec 2019 22:44:14 +0100 Subject: [PATCH 0603/3432] FEAT: minor update for year in "About" menu. --- environment/console/GUI/settings.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/console/GUI/settings.red b/environment/console/GUI/settings.red index 60c9603c93..841a709f2a 100644 --- a/environment/console/GUI/settings.red +++ b/environment/console/GUI/settings.red @@ -80,7 +80,7 @@ display-about: function [][ txt bold "Red Programming Language" font [size: 15 color: white] ver: txt font [size: 9 color: white] at 153x86 image fstk-logo - at 0x160 small 360x20 "Copyright 2011-2018 - Red Foundation" + at 0x160 small 360x20 "Copyright 2011-2019 - Red Foundation" at 0x180 small 360x20 "and contributors." at 0x230 link red-lang font-size 10 font-color white at 0x260 link github font-size 10 font-color white From a35fbc1af41b4328816cd93af2536ac9ce89901f Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 9 Dec 2019 12:27:09 +0100 Subject: [PATCH 0604/3432] FEAT: recreate DX resources when them got lost. --- modules/view/backends/windows/base.reds | 11 +-- modules/view/backends/windows/direct2d.reds | 96 +++++++++++++-------- modules/view/backends/windows/draw.reds | 17 ++-- modules/view/backends/windows/events.reds | 18 ++-- modules/view/backends/windows/gui.reds | 3 +- system/runtime/libc.reds | 7 ++ 6 files changed, 91 insertions(+), 61 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 931e64a360..f78697f2f5 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -466,11 +466,12 @@ BaseWndProc: func [ ][ target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 if target <> null [ - this: as this! target/value - rt: as ID2D1HwndRenderTarget this/vtbl - w: WIN32_LOWORD(lParam) - flags: WIN32_HIWORD(lParam) - rt/Resize this as tagSIZE :w + ;TBD resize + ;this: as this! target/value + ;rt: as ID2D1HwndRenderTarget this/vtbl + ;w: WIN32_LOWORD(lParam) + ;flags: WIN32_HIWORD(lParam) + ;rt/Resize this as tagSIZE :w InvalidateRect hWnd null 1 ] ] diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 81cbcc77d2..453f1c1925 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -30,6 +30,8 @@ dwrite-str-cache: as node! 0 #define D2D_MAX_BRUSHES 64 #define D2DERR_RECREATE_TARGET 8899000Ch +#define DXGI_ERROR_DEVICE_REMOVED 887A0005h +#define DXGI_ERROR_DEVICE_RESET 887A0007h #define FLT_MAX [as float32! 3.402823466e38] IID_IDXGISurface: [CAFCB56Ch 48896AC3h 239E47BFh EC60D2BBh] @@ -1095,10 +1097,12 @@ put-brush: func [ cnt [integer!] ][ cnt: target/2 - brushes: (as int-ptr! target/1) + (cnt * 2) - brushes/1: color - brushes/2: brush - target/2: cnt + 1 % D2D_MAX_BRUSHES + if cnt < D2D_MAX_BRUSHES [ + brushes: (as int-ptr! target/1) + (cnt * 2) + brushes/1: color + brushes/2: brush + target/2: cnt + 1 + ] ] DX-init: func [ @@ -1111,14 +1115,6 @@ DX-init: func [ D2D1CreateFactory [D2D1CreateFactory!] DWriteCreateFactory [DWriteCreateFactory!] GetUserDefaultLocaleName [GetUserDefaultLocaleName!] - d2d [ID2D1Factory] - d3d [ID3D11Device] - d2d-dev [ID2D1Device] - dxgi [IDXGIDevice1] - adapter [IDXGIAdapter] - ctx [ptr-value!] - unk [IUnknown] - d2d-device [this!] ][ dll: LoadLibraryA "d2d1.dll" if null? dll [winxp?: yes exit] @@ -1131,13 +1127,41 @@ DX-init: func [ dw-locale-name: as c-string! allocate 85 GetUserDefaultLocaleName dw-locale-name 85 + ;-- create D2D factory + options: 0 ;-- debugLevel + hr: D2D1CreateFactory 0 IID_ID2D1Factory1 :options :factory ;-- D2D1_FACTORY_TYPE_SINGLE_THREADED: 0 + assert zero? hr + d2d-factory: as this! factory/value + + ;-- create DWrite factory + hr: DWriteCreateFactory 0 IID_IDWriteFactory :factory ;-- DWRITE_FACTORY_TYPE_SHARED: 0 + assert zero? hr + dwrite-factory: as this! factory/value + str: string/rs-make-at ALLOC_TAIL(root) 1024 + dwrite-str-cache: str/node + + DX-create-dev +] + +DX-create-dev: func [ + /local + factory [ptr-value!] + d2d [ID2D1Factory] + d3d [ID3D11Device] + d2d-dev [ID2D1Device] + dxgi [IDXGIDevice1] + adapter [IDXGIAdapter] + ctx [ptr-value!] + unk [IUnknown] + d2d-device [this!] + hr [integer!] + dll [handle!] +][ if win8+? [ dll: LoadLibraryA "dcomp.dll" pfnDCompositionCreateDevice2: GetProcAddress dll "DCompositionCreateDevice2" ] - options: 0 ;-- debugLevel - hr: D3D11CreateDevice null 1 ;-- D3D_DRIVER_TYPE_HARDWARE @@ -1160,10 +1184,6 @@ DX-init: func [ assert zero? hr dxgi-device: as this! factory/value - hr: D2D1CreateFactory 0 IID_ID2D1Factory1 :options :factory ;-- D2D1_FACTORY_TYPE_SINGLE_THREADED: 0 - assert zero? hr - d2d-factory: as this! factory/value - ;-- get system DPI d2d: as ID2D1Factory d2d-factory/vtbl ;d2d/GetDesktopDpi d2d-factory :dpi-x :dpi-y @@ -1195,15 +1215,19 @@ DX-init: func [ assert zero? hr dxgi-factory: as this! factory/value - hr: DWriteCreateFactory 0 IID_IDWriteFactory :factory ;-- DWRITE_FACTORY_TYPE_SHARED: 0 - assert zero? hr - dwrite-factory: as this! factory/value - str: string/rs-make-at ALLOC_TAIL(root) 1024 - dwrite-str-cache: str/node - COM_SAFE_RELEASE(unk dxgi-device) COM_SAFE_RELEASE(unk d2d-device) - COM_SAFE_RELEASE(unk dxgi-adapter) + COM_SAFE_RELEASE(unk dxgi-adapter) +] + +DX-release-dev: func [ + /local + unk [IUnknown] +][ + COM_SAFE_RELEASE(unk d2d-ctx) + COM_SAFE_RELEASE(unk d3d-ctx) + COM_SAFE_RELEASE(unk d3d-device) + COM_SAFE_RELEASE(unk dxgi-factory) ] DX-cleanup: func [/local unk [IUnknown]][ @@ -1362,27 +1386,26 @@ to-dx-color: func [ ] d2d-release-target: func [ - target [ptr-ptr!] + target [render-target!] /local rt [ID2D1HwndRenderTarget] brushes [int-ptr!] cnt [integer!] this [this!] obj [IUnknown] - pp [ptr-ptr!] ][ - pp: target + 1 - brushes: pp/value - pp: target + 2 - cnt: as-integer pp/value + brushes: target/brushes + cnt: target/brushes-cnt + target/brushes-cnt: 0 loop cnt [ COM_SAFE_RELEASE_OBJ(obj brushes/2) brushes: brushes + 2 ] - ;TBD - ;this: as this! target/value - ;rt: as ID2D1HwndRenderTarget this/vtbl - ;rt/Release this + COM_SAFE_RELEASE(obj target/bitmap) + COM_SAFE_RELEASE(obj target/swapchain) + COM_SAFE_RELEASE(obj target/dcomp-visual) + COM_SAFE_RELEASE(obj target/dcomp-target) + COM_SAFE_RELEASE(obj target/dcomp-device) free as byte-ptr! target ] @@ -1431,8 +1454,7 @@ get-hwnd-render-target: func [ ][ target: as render-target! GetWindowLong hWnd wc-offset - 24 if null? target [ - target: as render-target! allocate size? render-target! - zero-memory as byte-ptr! target size? render-target! + target: as render-target! alloc0 size? render-target! create-render-target hWnd target target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! SetWindowLong hWnd wc-offset - 24 as-integer target diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index f1d3c86500..53b0172f3f 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -88,13 +88,12 @@ draw-begin: func [ ctx ] -release-d2d: func [ - ctx [draw-ctx!] +release-ctx: func [ + ctx [draw-ctx!] /local IUnk [IUnknown] this [this!] ][ - ;;TBD release all brushes when D2DERR_RECREATE_TARGET or exit the process COM_SAFE_RELEASE_OBJ(IUnk ctx/pen) COM_SAFE_RELEASE_OBJ(IUnk ctx/brush) ] @@ -115,19 +114,19 @@ draw-end: func [ rt: as render-target! ctx/target this: rt/dc dc: as ID2D1DeviceContext this/vtbl - hr: dc/EndDraw this null null + dc/EndDraw this null null dc/SetTarget this null this: rt/swapchain sc: as IDXGISwapChain1 this/vtbl - sc/Present this 0 0 - - release-d2d ctx + hr: sc/Present this 0 0 switch hr [ COM_S_OK [ValidateRect hWnd null] - D2DERR_RECREATE_TARGET [ - d2d-release-target as ptr-ptr! rt + DXGI_ERROR_DEVICE_REMOVED + DXGI_ERROR_DEVICE_RESET [ + release-ctx ctx + d2d-release-target rt ctx/dc: null SetWindowLong hWnd wc-offset - 24 0 InvalidateRect hWnd null 0 diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index e1f174df19..938fddf790 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -980,7 +980,7 @@ update-window: func [ ][ len: GetWindowLong hWnd wc-offset - 24 if len <> 0 [ - d2d-release-target as ptr-ptr! len + d2d-release-target as render-target! len SetWindowLong hWnd wc-offset - 24 0 ] ] @@ -1034,7 +1034,7 @@ WndProc: func [ lParam [integer!] return: [integer!] /local - target [ptr-ptr!] + target [render-target!] this [this!] rt [ID2D1HwndRenderTarget] res [integer!] @@ -1089,13 +1089,13 @@ WndProc: func [ WM_MOVE WM_SIZE [ if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [ - target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 + target: as render-target! GetWindowLong hWnd wc-offset - 24 if target <> null [ - this: as this! target/value - rt: as ID2D1HwndRenderTarget this/vtbl - color: WIN32_LOWORD(lParam) - res: WIN32_HIWORD(lParam) - rt/Resize this as tagSIZE :color + ;; TBD resize render target + ;rt: as ID2D1HwndRenderTarget this/vtbl + ;color: WIN32_LOWORD(lParam) + ;res: WIN32_HIWORD(lParam) + ;rt/Resize this as tagSIZE :color InvalidateRect hWnd null 1 ] ] @@ -1416,7 +1416,7 @@ WndProc: func [ if hidden-hwnd <> null [ values: (get-face-values hidden-hwnd) + FACE_OBJ_EXT3 values/header: TYPE_NONE - target: as ptr-ptr! GetWindowLong hidden-hwnd wc-offset - 24 + target: as render-target! GetWindowLong hidden-hwnd wc-offset - 24 if target <> null [d2d-release-target target] SetWindowLong hidden-hwnd wc-offset - 24 0 ] diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 11fb55b634..f9a840f79b 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -632,7 +632,7 @@ free-faces: func [ dc: GetWindowLong handle wc-offset - 24 if dc <> 0 [ either (GetWindowLong handle wc-offset - 12) and BASE_FACE_IME <> 0 [ - d2d-release-target as ptr-ptr! dc + d2d-release-target as render-target! dc ][ ;-- caret DestroyCaret ] @@ -847,6 +847,7 @@ init: func [ cleanup: does [ unregister-classes hInstance + DX-release-dev DX-cleanup ] diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds index bd33977270..12403de942 100644 --- a/system/runtime/libc.reds +++ b/system/runtime/libc.reds @@ -167,6 +167,13 @@ Red/System [ ] ] +alloc0: func [ + size [integer!] + return: [byte-ptr!] +][ + set-memory allocate size null-byte size +] + #either unicode? = yes [ #define prin [red/platform/prin*] From 8613cd2c61774a270e32de25411251f35d925784 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 9 Dec 2019 15:42:33 +0100 Subject: [PATCH 0605/3432] FEAT: resize Direct2D buffer. --- modules/view/backends/windows/base.reds | 11 +- modules/view/backends/windows/direct2d.reds | 133 +++++++++++++------- modules/view/backends/windows/draw.reds | 1 + modules/view/backends/windows/events.reds | 6 +- 4 files changed, 90 insertions(+), 61 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index f78697f2f5..72ff0e2219 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -436,7 +436,7 @@ BaseWndProc: func [ lParam [integer!] return: [integer!] /local - target [ptr-ptr!] + target [render-target!] this [this!] rt [ID2D1HwndRenderTarget] flags [integer!] @@ -464,14 +464,9 @@ BaseWndProc: func [ update-base hWnd null null get-face-values hWnd ] ][ - target: as ptr-ptr! GetWindowLong hWnd wc-offset - 24 + target: as render-target! GetWindowLong hWnd wc-offset - 24 if target <> null [ - ;TBD resize - ;this: as this! target/value - ;rt: as ID2D1HwndRenderTarget this/vtbl - ;w: WIN32_LOWORD(lParam) - ;flags: WIN32_HIWORD(lParam) - ;rt/Resize this as tagSIZE :w + DX-resize-buffer target WIN32_LOWORD(lParam) WIN32_HIWORD(lParam) InvalidateRect hWnd null 1 ] ] diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 453f1c1925..58d90b06df 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -335,32 +335,32 @@ IDXGISwapChain1: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] Release [Release!] - SetPrivateData [integer!] - SetPrivateDataInterface [integer!] - GetPrivateData [integer!] + SetPrivateData [int-ptr!] + SetPrivateDataInterface [int-ptr!] + GetPrivateData [int-ptr!] GetParent [function! [this [this!] riid [int-ptr!] parent [int-ptr!] return: [integer!]]] GetDevice [function! [this [this!] riid [int-ptr!] device [int-ptr!] return: [integer!]]] Present [function! [this [this!] SyncInterval [integer!] PresentFlags [integer!] return: [integer!]]] GetBuffer [function! [this [this!] idx [integer!] riid [int-ptr!] buffer [int-ptr!] return: [integer!]]] - SetFullscreenState [integer!] - GetFullscreenState [integer!] - GetDesc [integer!] - ResizeBuffers [integer!] - ResizeTarget [integer!] - GetContainingOutput [integer!] - GetFrameStatistics [integer!] - GetLastPresentCount [integer!] - GetDesc1 [integer!] - GetFullscreenDesc [integer!] - GetHwnd [integer!] - GetCoreWindow [integer!] + SetFullscreenState [int-ptr!] + GetFullscreenState [int-ptr!] + GetDesc [int-ptr!] + ResizeBuffers [function! [this [this!] count [uint!] width [uint!] height [uint!] format [integer!] flags [uint!] return: [integer!]]] + ResizeTarget [int-ptr!] + GetContainingOutput [int-ptr!] + GetFrameStatistics [int-ptr!] + GetLastPresentCount [int-ptr!] + GetDesc1 [int-ptr!] + GetFullscreenDesc [int-ptr!] + GetHwnd [int-ptr!] + GetCoreWindow [int-ptr!] Present1 [function! [this [this!] SyncInterval [integer!] PresentFlags [integer!] pPresentParameters [DXGI_PRESENT_PARAMETERS] return: [integer!]]] - IsTemporaryMonoSupported [integer!] - GetRestrictToOutput [integer!] - SetBackgroundColor [integer!] - GetBackgroundColor [integer!] - SetRotation [integer!] - GetRotation [integer!] + IsTemporaryMonoSupported [int-ptr!] + GetRestrictToOutput [int-ptr!] + SetBackgroundColor [int-ptr!] + GetBackgroundColor [int-ptr!] + SetRotation [int-ptr!] + GetRotation [int-ptr!] ] IDCompositionDevice: alias struct! [ @@ -418,7 +418,6 @@ IDCompositionVisual: alias struct! [ ] - IDCompositionTarget: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -1143,6 +1142,66 @@ DX-init: func [ DX-create-dev ] +DX-create-buffer: func [ + rt [render-target!] + swapchain [this!] + /local + sc [IDXGISwapChain1] + this [this!] + hr [integer!] + buf [integer!] + props [D2D1_BITMAP_PROPERTIES1 value] + bmp [integer!] + d2d [ID2D1DeviceContext] + unk [IUnknown] +][ + ;-- get back buffer from the swap chain + this: as this! swapchain + sc: as IDXGISwapChain1 this/vtbl + buf: 0 + hr: sc/GetBuffer this 0 IID_IDXGISurface :buf + assert zero? hr + + ;-- create a bitmap from the buffer + props/format: 87 ;-- DXGI_FORMAT_B8G8R8A8_UNORM + props/alphaMode: 1 ;-- D2D1_ALPHA_MODE_PREMULTIPLIED + props/dpiX: dpi-x + props/dpiY: dpi-y + props/options: 3 ;-- D2D1_BITMAP_OPTIONS_TARGET or D2D1_BITMAP_OPTIONS_CANNOT_DRAW + props/colorContext: null + bmp: 0 + d2d: as ID2D1DeviceContext d2d-ctx/vtbl + d2d/setDpi d2d-ctx dpi-x dpi-y + hr: d2d/CreateBitmapFromDxgiSurface d2d-ctx as int-ptr! buf props :bmp + assert hr = 0 + + rt/dc: d2d-ctx + rt/swapchain: swapchain + rt/bitmap: as this! bmp + + COM_SAFE_RELEASE_OBJ(unk buf) +] + +DX-resize-buffer: func [ + rt [render-target!] + width [uint!] + height [uint!] + /local + unk [IUnknown] + this [this!] + sc [IDXGISwapChain1] + hr [integer!] +][ + COM_SAFE_RELEASE(unk rt/bitmap) + + this: rt/swapchain + sc: as IDXGISwapChain1 this/vtbl + hr: sc/ResizeBuffers this 0 width height 87 0 + if hr <> 0 [probe "resizing failed" exit] + + DX-create-buffer rt this +] + DX-create-dev: func [ /local factory [ptr-value!] @@ -1253,7 +1312,6 @@ pixel-to-logical: func [ create-dcomp: func [ target [render-target!] hWnd [handle!] - d2d-dc [ID2D1DeviceContext] /local dev [integer!] d2d-device [this!] @@ -1264,9 +1322,11 @@ create-dcomp: func [ this [this!] tg [this!] visual [IDCompositionVisual] + d2d-dc [ID2D1DeviceContext] DCompositionCreateDevice2 [DCompositionCreateDevice2!] ][ dev: 0 + d2d-dc: as ID2D1DeviceContext d2d-ctx/vtbl d2d-dc/GetDevice d2d-ctx :dev d2d-device: as this! dev DCompositionCreateDevice2: as DCompositionCreateDevice2! pfnDCompositionCreateDevice2 @@ -1312,7 +1372,6 @@ create-render-target: func [ buf [integer!] props [D2D1_BITMAP_PROPERTIES1 value] bmp [integer!] - d2d [ID2D1DeviceContext] unk [IUnknown] ][ GetClientRect hWnd :rc @@ -1338,31 +1397,9 @@ create-render-target: func [ ] assert zero? hr - ;-- get back buffer from the swap chain - this: as this! int - sc: as IDXGISwapChain1 this/vtbl - hr: sc/GetBuffer this 0 IID_IDXGISurface :buf - assert zero? hr - - ;-- create a bitmap from the buffer - props/format: 87 ;-- DXGI_FORMAT_B8G8R8A8_UNORM - props/alphaMode: 1 ;-- D2D1_ALPHA_MODE_PREMULTIPLIED - props/dpiX: dpi-x - props/dpiY: dpi-y - props/options: 3 ;-- D2D1_BITMAP_OPTIONS_TARGET or D2D1_BITMAP_OPTIONS_CANNOT_DRAW - props/colorContext: null - bmp: 0 - d2d: as ID2D1DeviceContext d2d-ctx/vtbl - d2d/setDpi d2d-ctx dpi-x dpi-y - hr: d2d/CreateBitmapFromDxgiSurface d2d-ctx as int-ptr! buf props :bmp - assert hr = 0 - - rt/dc: d2d-ctx - rt/swapchain: as this! int - rt/bitmap: as this! bmp + DX-create-buffer rt as this! int - COM_SAFE_RELEASE_OBJ(unk buf) - if win8+? [create-dcomp rt hWnd d2d] + if win8+? [create-dcomp rt hWnd] rt ] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 53b0172f3f..932015aca0 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -129,6 +129,7 @@ draw-end: func [ d2d-release-target rt ctx/dc: null SetWindowLong hWnd wc-offset - 24 0 + DX-create-dev InvalidateRect hWnd null 0 ] default [ diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 938fddf790..0ae3599a68 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -1091,11 +1091,7 @@ WndProc: func [ if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [ target: as render-target! GetWindowLong hWnd wc-offset - 24 if target <> null [ - ;; TBD resize render target - ;rt: as ID2D1HwndRenderTarget this/vtbl - ;color: WIN32_LOWORD(lParam) - ;res: WIN32_HIWORD(lParam) - ;rt/Resize this as tagSIZE :color + DX-resize-buffer target WIN32_LOWORD(lParam) WIN32_HIWORD(lParam) InvalidateRect hWnd null 1 ] ] From e9dec31469e0cc8d11840b5103ee13a50ff9e5f4 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 3 Dec 2019 16:56:09 +0800 Subject: [PATCH 0606/3432] FEAT: implement image! using wic --- build/includes.r | 1 + modules/view/backends/windows/win32.reds | 6 +- runtime/clipboard.reds | 6 +- runtime/platform/COM.reds | 12 ++ runtime/platform/image-gdiplus.reds | 29 ++++ runtime/platform/image-wic.reds | 202 +++++++++++++++++++++++ runtime/red.reds | 8 +- 7 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 runtime/platform/image-wic.reds diff --git a/build/includes.r b/build/includes.r index feb000b9c1..9b0a2b5b91 100644 --- a/build/includes.r +++ b/build/includes.r @@ -164,6 +164,7 @@ write %build/bin/sources.r set-cache [ %syllable.reds %win32.reds %COM.reds + %image-wic.reds %image-gdiplus.reds %image-quartz.reds %win32-ansi.reds diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 9a3bcbc90b..702ab57a7b 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -12,7 +12,11 @@ Red/System [ #if dev-mode? = yes [ #include %../../../../runtime/platform/COM.reds - #include %../../../../runtime/platform/image-gdiplus.reds + #ether legacy = none [ + #include %../../../../runtime/platform/image-wic.reds + ][ + #include %../../../../runtime/platform/image-gdiplus.reds + ] ] #define NM_CUSTOMDRAW -12 diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index 3b65140839..bc74bf7b87 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -279,10 +279,10 @@ clipboard: context [ hdr/BlueMask = 000000FFh ][ ;-- can copy the data directly if hdr/Height < 0 [hdr/Height: 0 - hdr/Height] - assert all [0 = OS-image/GdipGetImagePixelFormat bmp :i i = PixelFormat32bppARGB] - OS-image/GdipCreateBitmapFromScan0 hdr/Width hdr/Height 0 PixelFormat32bppARGB p :bmp + assert all [0 = OS-image/get-pixel-format bmp :i i = PixelFormat32bppARGB] + OS-image/create-bitmap-from-scan0 hdr/Width hdr/Height 0 PixelFormat32bppARGB p :bmp ][ ;-- will have to convert, losing the alpha data if any - OS-image/GdipCreateBitmapFromGdiDib + OS-image/create-bitmap-from-gdidib p p + hdr/Size + (hdr/ClrUsed * 4) + hdr/ProfileSize :bmp ] val: as red-value! image/init-image as red-image! stack/push* as int-ptr! bmp diff --git a/runtime/platform/COM.reds b/runtime/platform/COM.reds index 63a614bf7e..8ce402627b 100644 --- a/runtime/platform/COM.reds +++ b/runtime/platform/COM.reds @@ -341,6 +341,18 @@ IPropertyBag: alias struct! [ return: [integer!] ] ] + "rpcrt4.dll" stdcall [ + UuidFromString: "UuidFromStringA" [ + StringUuid [c-string!] + Uuid [tagGUID] + return: [integer!] + ] + UuidToString: "UuidToStringA" [ + Uuid [tagGUID] + StringUuid [int-ptr!] + return: [integer!] + ] + ] ] init-variant: func [ diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 9b6448edee..22442418ff 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -241,6 +241,35 @@ OS-image: context [ ] ] + get-pixel-format: func [ + image [integer!] + format [int-ptr!] + return: [integer!] + ][ + GdipGetImagePixelFormat image format + ] + + create-bitmap-from-scan0: func [ + width [integer!] + height [integer!] + stride [integer!] + format [integer!] + scan0 [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ][ + GdipCreateBitmapFromScan0 width height stride format scan0 bitmap + ] + + create-bitmap-from-gdidib: func [ + bmi [byte-ptr!] + data [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ][ + GdipCreateBitmapFromGdiDib bmi data bitmap + ] + width?: func [ handle [int-ptr!] return: [integer!] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds new file mode 100644 index 0000000000..e17eee22d0 --- /dev/null +++ b/runtime/platform/image-wic.reds @@ -0,0 +1,202 @@ +Red/System [ + Title: "Image routine functions using wic" + Author: "bitbegin" + File: %image-wic.reds + Tabs: 4 + Rights: "Copyright (C) 2014-2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/dockimbel/Red/blob/master/BSL-License.txt + } +] + + +#define PixelFormatIndexed 00010000h ;-- Indexes into a palette +#define PixelFormatGDI 00020000h ;-- Is a GDI-supported format +#define PixelFormatAlpha 00040000h ;-- Has an alpha component +#define PixelFormatPAlpha 00080000h ;-- Pre-multiplied alpha +#define PixelFormatExtended 00100000h ;-- Extended color 16 bits/channel +#define PixelFormatCanonical 00200000h + +#define PixelFormatUndefined 0 +#define PixelFormatDontCare 0 + +#define PixelFormat32bppARGB 2498570 ;-- [10 or (32 << 8) or PixelFormatAlpha or PixelFormatGDI or PixelFormatCanonical] +#define PixelFormat32bppPARGB 925707 ;-- [11 or (32 << 8) or PixelFormatAlpha or PixelFormatPAlpha or PixelFormatGDI] +#define PixelFormat32bppCMYK 8207 ;-- [15 or (32 << 8)] +#define PixelFormatMax 16 + +OS-image: context [ + + IWICImagingFactory: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + CreateDecoderFromFilename [function! [this [this!] file [c-string!] vendor [int-ptr!] access [integer!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] + CreateDecoderFromStream [function! [this [this!] pIStread [int-ptr!] vendor [int-ptr!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] + CreateDecoderFromFileHandle [function! [this [this!] hFile [int-ptr!] vendor [int-ptr!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] + CreateComponentInfo [function! [this [this!] clsid [int-ptr!] ppIInfo [ptr-ptr!] return: [integer!]]] + CreateDecoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [ptr-ptr!] return: [integer!]]] + CreateEncoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [ptr-ptr!] return: [integer!]]] + CreatePalette [function! [this [this!] ppIPal [ptr-ptr!] return: [integer!]]] + CreateFormatConverter [function! [this [this!] ppIFormat [ptr-ptr!] return: [integer!]]] + CreateBitmapScaler [function! [this [this!] ppIScaler [ptr-ptr!] return: [integer!]]] + CreateBitmapClipper [function! [this [this!] ppIClipper [ptr-ptr!] return: [integer!]]] + CreateBitmapFlipRotator [function! [this [this!] ppIFlip [ptr-ptr!] return: [integer!]]] + CreateStream [function! [this [this!] ppIStream [ptr-ptr!] return: [integer!]]] + CreateColorContext [function! [this [this!] ppIColorCtx [ptr-ptr!] return: [integer!]]] + CreateColorTransformer [function! [this [this!] ppIColorTrans [ptr-ptr!] return: [integer!]]] + CreateBitmap [function! [this [this!] width [integer!] height [integer!] format [integer!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateBitmapFromSource [function! [this [this!] piBitmapSource [int-ptr!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateBitmapFromSourceRect [function! [this [this!] piBitmapSource [int-ptr!] x [integer!] y [integer!] w [integer!] h [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateBitmapFromMemory [function! [this [this!] w [integer!] h [integer!] format [integer!] stride [integer!] buffer-size [integer!] buffer [byte-ptr!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateBitmapFromHBITMAP [function! [this [this!] hBitmap [int-ptr!] hPalette [int-ptr!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateBitmapFromHICON [function! [this [this!] hIcon [int-ptr!] ppIBitmap [ptr-ptr!] return: [integer!]]] + CreateComponentEnumerator [function! [this [this!] types [integer!] opts [integer!] ppIEnum [ptr-ptr!] return: [integer!]]] + CreateFastMetadataEncoderFromDecoder [integer!] + CreateFastMetadataEncoderFromFrameDecode [integer!] + CreateQueryWriter [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIQueryWriter [ptr-ptr!] return: [integer!]]] + CreateQueryWriterFromReader [function! [this [this!] pIQueryReader [int-ptr!] vendor [int-ptr!] ppIQueryWriter [ptr-ptr!] return: [integer!]]] + ] + + init: func [ + /local + CLSID_WICImagingFactory [tagGUID value] + IID_IWICImagingFactory [tagGUID value] + hr [integer!] + II [interface! value] + ][ + CLSID_WICImagingFactory/data1: 0 + IID_IWICImagingFactory/data1: 0 + UuidFromString "CACAF262-9370-4615-A13B-9F5539DA4C0A" :CLSID_WICImagingFactory + UuidFromString "EC5EC8A9-C395-4314-9C77-54D7A935FF70" :IID_IWICImagingFactory + hr: CoCreateInstance as int-ptr! CLSID_WICImagingFactory 0 CLSCTX_INPROC_SERVER as int-ptr! IID_IWICImagingFactory :II + if hr <> 0 [0] + ] + + get-pixel-format: func [ + image [integer!] + format [int-ptr!] + return: [integer!] + ][ + 0 + ] + + create-bitmap-from-scan0: func [ + width [integer!] + height [integer!] + stride [integer!] + format [integer!] + scan0 [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ][ + 0 + ] + + create-bitmap-from-gdidib: func [ + bmi [byte-ptr!] + data [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ][ + 0 + ] + + width?: func [ + handle [int-ptr!] + return: [integer!] + ][0] + + height?: func [ + handle [int-ptr!] + return: [integer!] + ][0] + + lock-bitmap-fmt: func [ + handle [integer!] + pixelformat [integer!] + write? [logic!] + return: [integer!] + ][0] + + unlock-bitmap-fmt: func [ + img [integer!] + data [integer!] + ][] + + lock-bitmap: func [ + img [red-image!] + write? [logic!] + return: [integer!] + ][0] + + unlock-bitmap: func [ + img [red-image!] + data [integer!] + ][] + + get-data: func [ + handle [integer!] + stride [int-ptr!] + return: [int-ptr!] + ][null] + + get-pixel: func [ + bitmap [node!] + index [integer!] ;-- zero-based + return: [integer!] + ][0] + + set-pixel: func [ + bitmap [node!] + index [integer!] ;-- zero-based + color [integer!] + return: [integer!] + ][0] + + delete: func [img [red-image!]][] + + resize: func [ + img [red-image!] + width [integer!] + height [integer!] + return: [integer!] + ][0] + + load-image: func [ + src [red-string!] + return: [int-ptr!] + ][null] + + make-image: func [ + width [integer!] + height [integer!] + rgb [byte-ptr!] + alpha [byte-ptr!] + color [red-tuple!] + return: [int-ptr!] + ][null] + + load-binary: func [ + data [byte-ptr!] + len [integer!] + return: [node!] + ][null] + + encode: func [ + image [red-image!] + slot [red-value!] + format [integer!] + return: [red-value!] + ][null] + + clone: func [ + src [red-image!] + dst [red-image!] + part [integer!] + size [red-pair!] + part? [logic!] + return: [red-image!] + ][null] +] diff --git a/runtime/red.reds b/runtime/red.reds index bde151a79e..5b7175e89b 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -49,7 +49,13 @@ red: context [ ;-- ] ;-------------------------------------------- #switch OS [ - Windows [#include %platform/image-gdiplus.reds] + Windows [ + #either legacy = none [ + #include %platform/image-wic.reds + ][ + #include %platform/image-gdiplus.reds + ] + ] Syllable [] macOS [#include %platform/image-quartz.reds] FreeBSD [] From 7114e37289571ccc244eda61a8911e5b95af0185 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 5 Dec 2019 16:09:42 +0800 Subject: [PATCH 0607/3432] FEAT: implement load/make image using WIC --- runtime/platform/image-wic.reds | 376 +++++++++++++++++++++++++++----- 1 file changed, 327 insertions(+), 49 deletions(-) diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index e17eee22d0..27d7800264 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -26,37 +26,169 @@ Red/System [ #define PixelFormat32bppCMYK 8207 ;-- [15 or (32 << 8)] #define PixelFormatMax 16 +#define WICBitmapLockRead 00000001h +#define WICBitmapLockWrite 00000002h + +#define WICBitmapNoCache 0 +#define WICBitmapCacheOnDemand 1 +#define WICBitmapCacheOnLoad 2 +#define WICBITMAPCREATECACHEOPTION_FORCE_DWORD 7FFFFFFFh + OS-image: context [ + wic-factory: as this! 0 + GUID_WICPixelFormat32bppBGRA: declare tagGUID + GUID_WICPixelFormat32bppPBGRA: declare tagGUID + + RECT!: alias struct! [ + x [integer!] + y [integer!] + w [integer!] + h [integer!] + ] + IWICImagingFactory: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] Release [Release!] - CreateDecoderFromFilename [function! [this [this!] file [c-string!] vendor [int-ptr!] access [integer!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] - CreateDecoderFromStream [function! [this [this!] pIStread [int-ptr!] vendor [int-ptr!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] - CreateDecoderFromFileHandle [function! [this [this!] hFile [int-ptr!] vendor [int-ptr!] opts [integer!] dec [ptr-ptr!] return: [integer!]]] - CreateComponentInfo [function! [this [this!] clsid [int-ptr!] ppIInfo [ptr-ptr!] return: [integer!]]] - CreateDecoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [ptr-ptr!] return: [integer!]]] - CreateEncoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [ptr-ptr!] return: [integer!]]] - CreatePalette [function! [this [this!] ppIPal [ptr-ptr!] return: [integer!]]] - CreateFormatConverter [function! [this [this!] ppIFormat [ptr-ptr!] return: [integer!]]] - CreateBitmapScaler [function! [this [this!] ppIScaler [ptr-ptr!] return: [integer!]]] - CreateBitmapClipper [function! [this [this!] ppIClipper [ptr-ptr!] return: [integer!]]] - CreateBitmapFlipRotator [function! [this [this!] ppIFlip [ptr-ptr!] return: [integer!]]] - CreateStream [function! [this [this!] ppIStream [ptr-ptr!] return: [integer!]]] - CreateColorContext [function! [this [this!] ppIColorCtx [ptr-ptr!] return: [integer!]]] - CreateColorTransformer [function! [this [this!] ppIColorTrans [ptr-ptr!] return: [integer!]]] - CreateBitmap [function! [this [this!] width [integer!] height [integer!] format [integer!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateBitmapFromSource [function! [this [this!] piBitmapSource [int-ptr!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateBitmapFromSourceRect [function! [this [this!] piBitmapSource [int-ptr!] x [integer!] y [integer!] w [integer!] h [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateBitmapFromMemory [function! [this [this!] w [integer!] h [integer!] format [integer!] stride [integer!] buffer-size [integer!] buffer [byte-ptr!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateBitmapFromHBITMAP [function! [this [this!] hBitmap [int-ptr!] hPalette [int-ptr!] opts [integer!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateBitmapFromHICON [function! [this [this!] hIcon [int-ptr!] ppIBitmap [ptr-ptr!] return: [integer!]]] - CreateComponentEnumerator [function! [this [this!] types [integer!] opts [integer!] ppIEnum [ptr-ptr!] return: [integer!]]] + CreateDecoderFromFilename [function! [this [this!] file [c-string!] vendor [int-ptr!] access [integer!] opts [integer!] dec [interface!] return: [integer!]]] + CreateDecoderFromStream [function! [this [this!] pIStread [int-ptr!] vendor [int-ptr!] opts [integer!] dec [interface!] return: [integer!]]] + CreateDecoderFromFileHandle [function! [this [this!] hFile [int-ptr!] vendor [int-ptr!] opts [integer!] dec [interface!] return: [integer!]]] + CreateComponentInfo [function! [this [this!] clsid [int-ptr!] ppIInfo [interface!] return: [integer!]]] + CreateDecoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [interface!] return: [integer!]]] + CreateEncoder [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [interface!] return: [integer!]]] + CreatePalette [function! [this [this!] ppIPal [interface!] return: [integer!]]] + CreateFormatConverter [function! [this [this!] ppIFormat [interface!] return: [integer!]]] + CreateBitmapScaler [function! [this [this!] ppIScaler [interface!] return: [integer!]]] + CreateBitmapClipper [function! [this [this!] ppIClipper [interface!] return: [integer!]]] + CreateBitmapFlipRotator [function! [this [this!] ppIFlip [interface!] return: [integer!]]] + CreateStream [function! [this [this!] ppIStream [interface!] return: [integer!]]] + CreateColorContext [function! [this [this!] ppIColorCtx [interface!] return: [integer!]]] + CreateColorTransformer [function! [this [this!] ppIColorTrans [interface!] return: [integer!]]] + CreateBitmap [function! [this [this!] width [integer!] height [integer!] format [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]] + CreateBitmapFromSource [function! [this [this!] piBitmapSource [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]] + CreateBitmapFromSourceRect [function! [this [this!] piBitmapSource [int-ptr!] x [integer!] y [integer!] w [integer!] h [integer!] ppIBitmap [interface!] return: [integer!]]] + CreateBitmapFromMemory [function! [this [this!] w [integer!] h [integer!] format [integer!] stride [integer!] buffer-size [integer!] buffer [byte-ptr!] ppIBitmap [interface!] return: [integer!]]] + CreateBitmapFromHBITMAP [function! [this [this!] hBitmap [int-ptr!] hPalette [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]] + CreateBitmapFromHICON [function! [this [this!] hIcon [int-ptr!] ppIBitmap [interface!] return: [integer!]]] + CreateComponentEnumerator [function! [this [this!] types [integer!] opts [integer!] ppIEnum [interface!] return: [integer!]]] CreateFastMetadataEncoderFromDecoder [integer!] CreateFastMetadataEncoderFromFrameDecode [integer!] - CreateQueryWriter [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIQueryWriter [ptr-ptr!] return: [integer!]]] - CreateQueryWriterFromReader [function! [this [this!] pIQueryReader [int-ptr!] vendor [int-ptr!] ppIQueryWriter [ptr-ptr!] return: [integer!]]] + CreateQueryWriter [function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIQueryWriter [interface!] return: [integer!]]] + CreateQueryWriterFromReader [function! [this [this!] pIQueryReader [int-ptr!] vendor [int-ptr!] ppIQueryWriter [interface!] return: [integer!]]] + ] + + IWICBitmapDecoder: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + QueryCapability [function! [this [this!] pIStream [int-ptr!] pCap [integer!] return: [integer!]]] + Initialize [function! [this [this!] opts [integer!] return: [integer!]]] + GetContainerFormat [function! [this [this!] format [int-ptr!] return: [integer!]]] + GetDecoderInfo [function! [this [this!] ppIDecInfo [ptr-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + GetMetadataQueryReader [function! [this [this!] ppIMetaReader [ptr-ptr!] return: [integer!]]] + GetPreview [function! [this [this!] ppIBitmap [ptr-ptr!] return: [integer!]]] + GetColorContexts [function! [this [this!] count [integer!] ppIColorCtx [ptr-ptr!] pCount [int-ptr!] return: [integer!]]] + GetThumbnail [function! [this [this!] ppIThumbnail [ptr-ptr!] return: [integer!]]] + GetFrameCount [function! [this [this!] pCount [int-ptr!] return: [integer!]]] + GetFrame [function! [this [this!] index [integer!] ppIBitmapFrame [interface!] return: [integer!]]] + ] + + IWICBitmapFrameDecode: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pW [int-ptr!] pH [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + GetMetadataQueryReader [function! [this [this!] ppIMetaReader [interface!] return: [integer!]]] + GetColorContexts [function! [this [this!] count [integer!] ppIColorCtx [interface!] pCount [int-ptr!] return: [integer!]]] + GetThumbnail [function! [this [this!] ppIThumbnail [interface!] return: [integer!]]] + ] + + IWICBitmapFrameEncode: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + Initialize [function! [this [this!] pIEncOpts [int-ptr!] return: [integer!]]] + SetSize [function! [this [this!] w [integer!] h [integer!] return: [integer!]]] + SetResolution [function! [this [this!] x [float!] y [float!] return: [integer!]]] + SetPixelFormat [function! [this [this!] format [int-ptr!] return: [integer!]]] + SetColorContexts [function! [this [this!] count [integer!] ppIColorCtx [ptr-ptr!] return: [integer!]]] + SetPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + SetThumbnail [function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]] + WritePixels [function! [this [this!] count [integer!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + WriteSource [function! [this [this!] piBitmapSource [int-ptr!] prc [int-ptr!] return: [integer!]]] + Commit [function! [this [this!] return: [integer!]]] + GetMetadataQueryWriter [function! [this [this!] ppIMetaReader [ptr-ptr!] return: [integer!]]] + ] + + IWICBitmapEncoder: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + Initialize [function! [this [this!] pIStream [int-ptr!] opts [integer!] return: [integer!]]] + GetContainerFormat [function! [this [this!] format [int-ptr!] return: [integer!]]] + GetEncoderInfo [function! [this [this!] ppIEncInfo [ptr-ptr!] return: [integer!]]] + SetColorContexts [function! [this [this!] count [integer!] ppIColorCtx [ptr-ptr!] return: [integer!]]] + SetPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + SetThumbnail [function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]] + SetPreview [function! [this [this!] pIPreview [int-ptr!] return: [integer!]]] + CreateNewFrame [function! [this [this!] ppIFrameEnc [ptr-ptr!] ppIEncOpts [ptr-ptr!] return: [integer!]]] + Commit [function! [this [this!] return: [integer!]]] + GetMetadataQueryWriter [function! [this [this!] ppIMetaWriter [ptr-ptr!] return: [integer!]]] + ] + + IWICFormatConverter: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pW [int-ptr!] pH [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + Initialize [function! [this [this!] pISource [int-ptr!] format [int-ptr!] dither [integer!] pIPalette [int-ptr!] percent [float!] trans [integer!] return: [integer!]]] + CanConvert [function! [this [this!] srcFormat [int-ptr!] dstFormat [int-ptr!] return: [integer!]]] + ] + + IWICBitmapSource: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pWidth [int-ptr!] pHeight [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + Initialize [function! [this [this!] pISource [int-ptr!] w [integer!] h [integer!] mode [integer!] return: [integer!]]] + ] + + IWICBitmap: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pWidth [int-ptr!] pHeight [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + Lock [function! [this [this!] prcLock [RECT!] flags [integer!] ppILock [interface!] return: [integer!]]] + SetPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + SetResolution [function! [this [this!] x [float!] y [float!] return: [integer!]]] + ] + + IWICBitmapLock: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pWidth [int-ptr!] pHeight [int-ptr!] return: [integer!]]] + GetStride [function! [this [this!] stride [int-ptr!] return: [integer!]]] + GetDataPointer [function! [this [this!] size [int-ptr!] data [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] ] init: func [ @@ -70,8 +202,12 @@ OS-image: context [ IID_IWICImagingFactory/data1: 0 UuidFromString "CACAF262-9370-4615-A13B-9F5539DA4C0A" :CLSID_WICImagingFactory UuidFromString "EC5EC8A9-C395-4314-9C77-54D7A935FF70" :IID_IWICImagingFactory + UuidFromString "6FDDC324-4E03-4BFE-B185-3D77768DC90F" GUID_WICPixelFormat32bppBGRA + UuidFromString "6FDDC324-4E03-4BFE-B185-3D77768DC910" GUID_WICPixelFormat32bppPBGRA hr: CoCreateInstance as int-ptr! CLSID_WICImagingFactory 0 CLSCTX_INPROC_SERVER as int-ptr! IID_IWICImagingFactory :II - if hr <> 0 [0] + if hr = 0 [ + wic-factory: as this! II/ptr + ] ] get-pixel-format: func [ @@ -106,41 +242,86 @@ OS-image: context [ width?: func [ handle [int-ptr!] return: [integer!] - ][0] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + ][ + this: as this! handle + IB: as IWICBitmap this/vtbl + w: 0 h: 0 + IB/GetSize this :w :h + w + ] height?: func [ handle [int-ptr!] return: [integer!] - ][0] - - lock-bitmap-fmt: func [ - handle [integer!] - pixelformat [integer!] - write? [logic!] - return: [integer!] - ][0] - - unlock-bitmap-fmt: func [ - img [integer!] - data [integer!] - ][] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + ][ + this: as this! handle + IB: as IWICBitmap this/vtbl + w: 0 h: 0 + IB/GetSize this :w :h + h + ] lock-bitmap: func [ img [red-image!] write? [logic!] return: [integer!] - ][0] + /local + this [this!] + IB [IWICBitmap] + flag [integer!] + rect [RECT! value] + ilock [interface! value] + ][ + this: as this! img/node + IB: as IWICBitmap this/vtbl + flag: either write? [WICBitmapLockWrite][WICBitmapLockRead] + rect/x: 0 + rect/y: 0 + rect/w: IMAGE_WIDTH(img/size) + rect/h: IMAGE_HEIGHT(img/size) + IB/Lock this rect flag :ilock + as integer! ilock/ptr + ] unlock-bitmap: func [ img [red-image!] data [integer!] - ][] + /local + this [this!] + lock [IWICBitmapLock] + ][ + this: as this! data + lock: as IWICBitmapLock this/vtbl + lock/Release this + ] get-data: func [ handle [integer!] stride [int-ptr!] return: [int-ptr!] - ][null] + /local + this [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + ][ + this: as this! handle + lock: as IWICBitmapLock this/vtbl + + size: 0 data: 0 + lock/GetDataPointer this :size :data + as int-ptr! data + ] get-pixel: func [ bitmap [node!] @@ -167,16 +348,113 @@ OS-image: context [ load-image: func [ src [red-string!] return: [int-ptr!] - ][null] + /local + IFAC [IWICImagingFactory] + II [interface! value] + this [this!] + dec [IWICBitmapDecoder] + count [integer!] + iframe [interface! value] + fthis [this!] + frame [IWICBitmapFrameDecode] + w [integer!] + h [integer!] + iconv [interface! value] + cthis [this!] + conv [IWICFormatConverter] + bitmap [interface! value] + ][ + if null? wic-factory [init] + IFAC: as IWICImagingFactory wic-factory/vtbl + IFAC/CreateDecoderFromFilename wic-factory file/to-OS-path src null GENERIC_READ 0 :II + this: as this! II/ptr + dec: as IWICBitmapDecoder this/vtbl + count: 0 + dec/GetFrameCount this :count + if count < 1 [return null] + dec/GetFrame this 0 :iframe + fthis: as this! iframe/ptr + frame: as IWICBitmapFrameDecode fthis/vtbl + w: 0 h: 0 + frame/GetSize fthis :w :h + IFAC/CreateFormatConverter wic-factory :iconv + cthis: as this! iconv/ptr + conv: as IWICFormatConverter cthis/vtbl + conv/Initialize cthis as int-ptr! fthis as int-ptr! GUID_WICPixelFormat32bppBGRA 0 null 0.0 0 + IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap + conv/Release cthis + frame/Release fthis + dec/Release this + as int-ptr! bitmap/ptr + ] make-image: func [ - width [integer!] - height [integer!] - rgb [byte-ptr!] - alpha [byte-ptr!] - color [red-tuple!] - return: [int-ptr!] - ][null] + width [integer!] + height [integer!] + rgb [byte-ptr!] + alpha [byte-ptr!] + color [red-tuple!] + return: [int-ptr!] + /local + IFAC [IWICImagingFactory] + bitmap [interface! value] + bthis [this!] + bmp [IWICBitmap] + rect [RECT! value] + ilock [interface! value] + lthis [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + scan0 [int-ptr!] + end [int-ptr!] + a [integer!] + r [integer!] + b [integer!] + g [integer!] + ][ + if any [zero? width zero? height][return null] + if null? wic-factory [init] + IFAC: as IWICImagingFactory wic-factory/vtbl + IFAC/CreateBitmap wic-factory width height as int-ptr! GUID_WICPixelFormat32bppBGRA WICBitmapCacheOnLoad :bitmap + bthis: as this! bitmap/ptr + bmp: as IWICBitmap bthis/vtbl + rect/x: 0 rect/y: 0 rect/w: width rect/h: height + bmp/Lock bthis rect WICBitmapLockWrite :ilock + lthis: as this! ilock/ptr + lock: as IWICBitmapLock lthis/vtbl + + size: 0 data: 0 + lock/GetDataPointer lthis :size :data + + scan0: as int-ptr! data + end: scan0 + (width * height) + + either null? color [ + while [scan0 < end][ + either null? alpha [a: 255][a: 255 - as-integer alpha/1 alpha: alpha + 1] + either null? rgb [r: 255 g: 255 b: 255][ + r: as-integer rgb/1 + g: as-integer rgb/2 + b: as-integer rgb/3 + rgb: rgb + 3 + ] + scan0/value: r << 16 or (g << 8) or b or (a << 24) + scan0: scan0 + 1 + ] + ][ + r: color/array1 + a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] + r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) + while [scan0 < end][ + scan0/value: r + scan0: scan0 + 1 + ] + ] + + lock/Release lthis + as int-ptr! bthis + ] load-binary: func [ data [byte-ptr!] From c9d6a9cabf8a264f0dd927249b06a5bbe0529584 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 6 Dec 2019 11:58:13 +0800 Subject: [PATCH 0608/3432] FEAT: implement set-pixel/get-pixel/resize/clone image! --- runtime/platform/image-wic.reds | 224 +++++++++++++++++++++++++++++--- 1 file changed, 209 insertions(+), 15 deletions(-) diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 27d7800264..85b279ba2d 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -191,6 +191,30 @@ OS-image: context [ GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] ] + IWICBitmapScaler: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pWidth [int-ptr!] pHeight [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + Initialize [function! [this [this!] pISource [int-ptr!] w [integer!] h [integer!] mode [integer!] return: [integer!]]] + ] + + IWICBitmapClipper: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetSize [function! [this [this!] pWidth [int-ptr!] pHeight [int-ptr!] return: [integer!]]] + GetPixelFormat [function! [this [this!] pPixelFormat [int-ptr!] return: [integer!]]] + GetResolution [function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]] + CopyPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] + CopyPixels [function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] + Initialize [function! [this [this!] pISource [int-ptr!] rec [RECT!] return: [integer!]]] + ] + init: func [ /local CLSID_WICImagingFactory [tagGUID value] @@ -327,23 +351,109 @@ OS-image: context [ bitmap [node!] index [integer!] ;-- zero-based return: [integer!] - ][0] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + rect [RECT! value] + ilock [interface! value] + lthis [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + scan0 [int-ptr!] + ret [integer!] + ][ + this: as this! bitmap + IB: as IWICBitmap this/vtbl + w: 0 h: 0 + IB/GetSize this :w :h + rect/x: 0 rect/y: 0 rect/w: w rect/h: h + IB/Lock this rect WICBitmapLockRead :ilock + lthis: as this! ilock/ptr + lock: as IWICBitmapLock lthis/vtbl + size: 0 data: 0 + lock/GetDataPointer lthis :size :data + scan0: as int-ptr! data + scan0: scan0 + index + ret: scan0/1 + lock/Release lthis + ret + ] set-pixel: func [ bitmap [node!] index [integer!] ;-- zero-based color [integer!] return: [integer!] - ][0] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + rect [RECT! value] + ilock [interface! value] + lthis [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + scan0 [int-ptr!] + ][ + this: as this! bitmap + IB: as IWICBitmap this/vtbl + w: 0 h: 0 + IB/GetSize this :w :h + rect/x: 0 rect/y: 0 rect/w: w rect/h: h + IB/Lock this rect WICBitmapLockRead :ilock + lthis: as this! ilock/ptr + lock: as IWICBitmapLock lthis/vtbl + size: 0 data: 0 + lock/GetDataPointer lthis :size :data + scan0: as int-ptr! data + scan0: scan0 + index + scan0/1: color + lock/Release lthis + 0 + ] - delete: func [img [red-image!]][] + delete: func [ + img [red-image!] + /local + this [this!] + IB [IWICBitmap] + ][ + this: as this! img/node + IB: as IWICBitmap this/vtbl + IB/Release this + ] resize: func [ - img [red-image!] - width [integer!] - height [integer!] - return: [integer!] - ][0] + img [red-image!] + width [integer!] + height [integer!] + return: [integer!] + /local + this [this!] + IB [IWICBitmap] + IFAC [IWICImagingFactory] + iscale [interface! value] + sthis [this!] + scale [IWICBitmapScaler] + bitmap [interface! value] + ][ + this: as this! img/node + IB: as IWICBitmap this/vtbl + if null? wic-factory [init] + IFAC: as IWICImagingFactory wic-factory/vtbl + IFAC/CreateBitmapScaler wic-factory :iscale + sthis: as this! iscale/ptr + scale: as IWICBitmapScaler sthis/vtbl + scale/Initialize sthis as int-ptr! this width height 0 ;-- NearestNeighbor + IFAC/CreateBitmapFromSource wic-factory as int-ptr! sthis 0 :bitmap + scale/Release sthis + as integer! bitmap/ptr + ] load-image: func [ src [red-string!] @@ -470,11 +580,95 @@ OS-image: context [ ][null] clone: func [ - src [red-image!] - dst [red-image!] - part [integer!] - size [red-pair!] - part? [logic!] - return: [red-image!] - ][null] + src [red-image!] + dst [red-image!] + part [integer!] + size [red-pair!] + part? [logic!] + return: [red-image!] + /local + width [integer!] + height [integer!] + offset [integer!] + this [this!] + IB [IWICBitmap] + IFAC [IWICImagingFactory] + bitmap [interface! value] + x [integer!] + y [integer!] + w [integer!] + h [integer!] + handle [node!] + iclip [interface! value] + cthis [this!] + clip [IWICBitmapClipper] + rect [RECT! value] + ][ + width: IMAGE_WIDTH(src/size) + height: IMAGE_HEIGHT(src/size) + + if any [ + width <= 0 + height <= 0 + ][ + dst/size: 0 + dst/header: TYPE_IMAGE + dst/head: 0 + dst/node: as node! 0 + return dst + ] + + offset: src/head + this: as this! src/node + IB: as IWICBitmap this/vtbl + if null? wic-factory [init] + IFAC: as IWICImagingFactory wic-factory/vtbl + if all [zero? offset not part?][ + IFAC/CreateBitmapFromSource wic-factory as int-ptr! this 0 :bitmap + dst/size: src/size + dst/header: TYPE_IMAGE + dst/head: 0 + dst/node: as node! bitmap/ptr + return dst + ] + + x: offset % width + y: offset / width + either all [part? TYPE_OF(size) = TYPE_PAIR][ + w: width - x + h: height - y + if size/x < w [w: size/x] + if size/y < h [h: size/y] + ][ + either zero? part [ + w: 0 h: 0 + ][ + either part < width [h: 1 w: part][ + h: part / width + w: width + ] + ] + ] + either any [ + w <= 0 + h <= 0 + ][ + dst/size: 0 + dst/node: null + ][ + IFAC/CreateBitmapClipper wic-factory :iclip + cthis: as this! iclip/ptr + clip: as IWICBitmapClipper cthis/vtbl + rect/x: x rect/y: y + rect/w: w rect/h: h + clip/Initialize cthis as int-ptr! this rect + IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap + clip/Release cthis + dst/node: as node! bitmap/ptr + dst/size: h << 16 or w + ] + dst/header: TYPE_IMAGE + dst/head: 0 + dst + ] ] From a55bb0f50abc421e09b07f27a0883d98282002a8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 6 Dec 2019 16:57:46 +0800 Subject: [PATCH 0609/3432] FEAT: support write/read image! to clipboard using wic --- libRed/libRed.red | 5 +- runtime/clipboard.reds | 40 ++-- runtime/datatypes/image.reds | 27 ++- runtime/platform/COM.reds | 12 ++ runtime/platform/image-gdiplus.reds | 43 +++-- runtime/platform/image-quartz.reds | 6 +- runtime/platform/image-wic.reds | 282 ++++++++++++++++++++++++---- runtime/red.reds | 7 +- 8 files changed, 343 insertions(+), 79 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index cb7267139a..a83d329899 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -513,6 +513,8 @@ Red [ img [red-image!] rgb [byte-ptr!] sz [integer!] + w [integer!] + h [integer!] stride [integer!] bitmap [integer!] data [int-ptr!] @@ -535,9 +537,10 @@ Red [ img/node: OS-image/make-image width height rgb null null if format = RGBA_BUFFER [ + w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img yes - data: OS-image/get-data bitmap :stride + data: OS-image/get-data bitmap :w :h :stride copy-memory as byte-ptr! data src sz * 4 OS-image/unlock-bitmap img bitmap ] diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index bc74bf7b87..0f15217d0c 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -95,15 +95,6 @@ clipboard: context [ fWide [logic!] ] - BitmapData!: alias struct! [ - width [integer!] - height [integer!] - stride [integer!] - pixelFormat [integer!] - scan0 [byte-ptr!] - reserved [integer!] - ] - BITMAPV5HEADER!: alias struct! [ Size [integer!] Width [integer!] @@ -279,8 +270,8 @@ clipboard: context [ hdr/BlueMask = 000000FFh ][ ;-- can copy the data directly if hdr/Height < 0 [hdr/Height: 0 - hdr/Height] - assert all [0 = OS-image/get-pixel-format bmp :i i = PixelFormat32bppARGB] - OS-image/create-bitmap-from-scan0 hdr/Width hdr/Height 0 PixelFormat32bppARGB p :bmp + assert all [0 = OS-image/get-pixel-format bmp :i OS-image/fixed-format? i] + OS-image/create-bitmap-from-scan0 hdr/Width hdr/Height 0 OS-image/fixed-format p :bmp ][ ;-- will have to convert, losing the alpha data if any OS-image/create-bitmap-from-gdidib p p + hdr/Size + (hdr/ClrUsed * 4) + hdr/ProfileSize :bmp @@ -319,7 +310,12 @@ clipboard: context [ blk [red-block!] img [red-image!] df [DROPFILES!] - bmdata [BitmapData!] + bmdata [integer!] + w [integer!] + h [integer!] + s [integer!] + scan0 [byte-ptr!] + format [integer!] hdr [BITMAPV5HEADER!] ][ hMem: [0 0] hMem/1: 0 hMem/2: 0 @@ -410,9 +406,13 @@ clipboard: context [ ;-- also put the image in DIB format for compatibility fmts/2: CF_DIBV5 - bmdata: as BitmapData! OS-image/lock-bitmap img no - assert not null? bmdata - len: bmdata/width * bmdata/height * 4 + bmdata: OS-image/lock-bitmap img no + assert 0 <> bmdata + w: 0 h: 0 s: 0 + scan0: as byte-ptr! OS-image/get-data bmdata :w :h :s + len: w * h * 4 + format: 0 + OS-image/get-data-pixel-format bmdata :format hMem/2: GlobalAlloc 2 len + size? BITMAPV5HEADER! if hMem/2 <> 0 [ p: GlobalLock hMem/2 @@ -420,8 +420,8 @@ clipboard: context [ set-memory p #"^@" size? BITMAPV5HEADER! hdr: as BITMAPV5HEADER! p hdr/Size: size? BITMAPV5HEADER! - hdr/Width: bmdata/width - hdr/Height: 0 - bmdata/height ;-- top-down image + hdr/Width: w + hdr/Height: 0 - h ;-- top-down image hdr/PlanesBitCount: 00200001h ;-- 32 bpp, 1 plane hdr/Compression: 3 ;-- BI_BITFIELDS hdr/SizeImage: len @@ -431,12 +431,12 @@ clipboard: context [ hdr/BlueMask: 000000FFh hdr/CSType: 57696E20h ;-- "Win " = LCS_WINDOWS_COLOR_SPACE hdr/Intent: 4 ;-- 4 = LCS_GM_IMAGES - assert bmdata/pixelFormat = PixelFormat32bppARGB - copy-memory p + hdr/Size bmdata/scan0 len + assert OS-image/fixed-format? format + copy-memory p + hdr/Size scan0 len GlobalUnlock hMem/2 ] ] - OS-image/unlock-bitmap img as integer! bmdata + OS-image/unlock-bitmap img bmdata ];; if IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) > 0 ];; TYPE_IMAGE diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 2008eca972..89895636a0 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -18,12 +18,15 @@ image: context [ bitmap [int-ptr!] return: [int-ptr!] /local + w [integer!] + h [integer!] stride [integer!] data [int-ptr!] ][ + w: 0 h: 0 stride: 0 bitmap/value: OS-image/lock-bitmap img yes - OS-image/get-data bitmap/value :stride + OS-image/get-data bitmap/value :w :h :stride ] release-buffer: func [ @@ -178,6 +181,8 @@ image: context [ bin [red-binary!] s [series!] p [byte-ptr!] + w [integer!] + h [integer!] stride [integer!] bitmap [integer!] i [integer!] @@ -197,9 +202,10 @@ image: context [ s/tail: as cell! (as byte-ptr! s/tail) + bytes p: as byte-ptr! s/offset + w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img no - data: OS-image/get-data bitmap :stride + data: OS-image/get-data bitmap :w :h :stride either type = EXTRACT_ARGB [ copy-memory p as byte-ptr! data bytes @@ -233,6 +239,8 @@ image: context [ sz [integer!] s [series!] p [byte-ptr!] + w [integer!] + h [integer!] stride [integer!] bitmap [integer!] pixel [integer!] @@ -248,9 +256,10 @@ image: context [ if zero? sz [return bin] offset: img/head + w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img yes - data: OS-image/get-data bitmap :stride + data: OS-image/get-data bitmap :w :h :stride end: data + sz type: TYPE_OF(bin) @@ -486,6 +495,8 @@ image: context [ count [integer!] bitmap [integer!] data [int-ptr!] + w [integer!] + h [integer!] stride [integer!] size [integer!] end [int-ptr!] @@ -512,9 +523,10 @@ image: context [ return part - 5 ] + w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img no - data: OS-image/get-data bitmap :stride + data: OS-image/get-data bitmap :w :h :stride end: data + (width * height) data: data + img/head size: as-integer end - data @@ -746,6 +758,8 @@ image: context [ /local type [integer!] res [integer!] + w [integer!] + h [integer!] bmp1 [integer!] bmp2 [integer!] same? [logic!] @@ -778,12 +792,13 @@ image: context [ ][ res: 1 ][ + w: 0 h: 0 type: 0 bmp1: OS-image/lock-bitmap arg1 no bmp2: OS-image/lock-bitmap arg2 no res: compare-memory - as byte-ptr! OS-image/get-data bmp1 :type - as byte-ptr! OS-image/get-data bmp2 :type + as byte-ptr! OS-image/get-data bmp1 :w :h :type + as byte-ptr! OS-image/get-data bmp2 :w :h :type IMAGE_WIDTH(arg1/size) * IMAGE_HEIGHT(arg2/size) * 4 OS-image/unlock-bitmap arg1 bmp1 OS-image/unlock-bitmap arg2 bmp2 diff --git a/runtime/platform/COM.reds b/runtime/platform/COM.reds index 8ce402627b..d0fa3501b1 100644 --- a/runtime/platform/COM.reds +++ b/runtime/platform/COM.reds @@ -290,6 +290,12 @@ IPropertyBag: alias struct! [ ppstgOpen [interface!] return: [integer!] ] + CreateStreamOnHGlobal: "CreateStreamOnHGlobal" [ + hMem [integer!] + fAutoDel [logic!] + ppstm [int-ptr!] + return: [integer!] + ] ] "oleaut32.dll" stdcall [ SysAllocString: "SysAllocString" [ @@ -355,6 +361,12 @@ IPropertyBag: alias struct! [ ] ] +CLSID_BMP_ENCODER: [557CF400h 11D31A04h 0000739Ah 2EF31EF8h] +CLSID_JPEG_ENCODER: [557CF401h 11D31A04h 0000739Ah 2EF31EF8h] +CLSID_GIF_ENCODER: [557CF402h 11D31A04h 0000739Ah 2EF31EF8h] +CLSID_TIFF_ENCODER: [557CF405h 11D31A04h 0000739Ah 2EF31EF8h] +CLSID_PNG_ENCODER: [557CF406h 11D31A04h 0000739Ah 2EF31EF8h] + init-variant: func [ var [tagVARIANT] ][ diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 22442418ff..4218146638 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -52,12 +52,6 @@ Red/System [ OS-image: context [ - CLSID_BMP_ENCODER: [557CF400h 11D31A04h 0000739Ah 2EF31EF8h] - CLSID_JPEG_ENCODER: [557CF401h 11D31A04h 0000739Ah 2EF31EF8h] - CLSID_GIF_ENCODER: [557CF402h 11D31A04h 0000739Ah 2EF31EF8h] - CLSID_TIFF_ENCODER: [557CF405h 11D31A04h 0000739Ah 2EF31EF8h] - CLSID_PNG_ENCODER: [557CF406h 11D31A04h 0000739Ah 2EF31EF8h] - RECT!: alias struct! [ left [integer!] top [integer!] @@ -94,14 +88,6 @@ OS-image: context [ return: [integer!] ] ] - "ole32.dll" stdcall [ - CreateStreamOnHGlobal: "CreateStreamOnHGlobal" [ - hMem [integer!] - fAutoDel [logic!] - ppstm [int-ptr!] - return: [integer!] - ] - ] "gdiplus.dll" stdcall [ GdipCloneImage: "GdipCloneImage" [ image [integer!] @@ -249,6 +235,19 @@ OS-image: context [ GdipGetImagePixelFormat image format ] + fixed-format?: func [ + format [integer!] + return: [logic!] + ][ + format = PixelFormat32bppARGB + ] + + fixed-format: func [ + return: [integer!] + ][ + PixelFormat32bppARGB + ] + create-bitmap-from-scan0: func [ width [integer!] height [integer!] @@ -334,16 +333,32 @@ OS-image: context [ get-data: func [ handle [integer!] + width [int-ptr!] + height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local bitmap [BitmapData!] ][ bitmap: as BitmapData! handle + width/value: bitmap/width + height/value: bitmap/height stride/value: bitmap/stride as int-ptr! bitmap/scan0 ] + get-data-pixel-format: func [ + handle [integer!] + format [int-ptr!] + return: [integer!] + /local + bitmap [BitmapData!] + ][ + bitmap: as BitmapData! handle + format/value: bitmap/pixelFormat + 0 + ] + get-pixel: func [ bitmap [node!] index [integer!] ;-- zero-based diff --git a/runtime/platform/image-quartz.reds b/runtime/platform/image-quartz.reds index 782e9d4f49..0419910c3b 100644 --- a/runtime/platform/image-quartz.reds +++ b/runtime/platform/image-quartz.reds @@ -251,13 +251,17 @@ OS-image: context [ get-data: func [ handle [integer!] + width [int-ptr!] + height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local node [img-node!] ][ node: as img-node! handle - stride/value: IMAGE_WIDTH(node/size) * 4 + width/value: IMAGE_WIDTH(node/size) + height/value: IMAGE_HEIGHT(node/size) + stride/value: width/value * 4 node/buffer ] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 85b279ba2d..6aebae3d1d 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -10,22 +10,6 @@ Red/System [ } ] - -#define PixelFormatIndexed 00010000h ;-- Indexes into a palette -#define PixelFormatGDI 00020000h ;-- Is a GDI-supported format -#define PixelFormatAlpha 00040000h ;-- Has an alpha component -#define PixelFormatPAlpha 00080000h ;-- Pre-multiplied alpha -#define PixelFormatExtended 00100000h ;-- Extended color 16 bits/channel -#define PixelFormatCanonical 00200000h - -#define PixelFormatUndefined 0 -#define PixelFormatDontCare 0 - -#define PixelFormat32bppARGB 2498570 ;-- [10 or (32 << 8) or PixelFormatAlpha or PixelFormatGDI or PixelFormatCanonical] -#define PixelFormat32bppPARGB 925707 ;-- [11 or (32 << 8) or PixelFormatAlpha or PixelFormatPAlpha or PixelFormatGDI] -#define PixelFormat32bppCMYK 8207 ;-- [15 or (32 << 8)] -#define PixelFormatMax 16 - #define WICBitmapLockRead 00000001h #define WICBitmapLockWrite 00000002h @@ -34,11 +18,18 @@ Red/System [ #define WICBitmapCacheOnLoad 2 #define WICBITMAPCREATECACHEOPTION_FORCE_DWORD 7FFFFFFFh +#define GMEM_MOVEABLE 2 + OS-image: context [ wic-factory: as this! 0 GUID_WICPixelFormat32bppBGRA: declare tagGUID GUID_WICPixelFormat32bppPBGRA: declare tagGUID + GUID_ContainerFormatBmp: declare tagGUID + GUID_ContainerFormatPng: declare tagGUID + GUID_ContainerFormatJpeg: declare tagGUID + GUID_ContainerFormatTiff: declare tagGUID + GUID_ContainerFormatGif: declare tagGUID RECT!: alias struct! [ x [integer!] @@ -47,6 +38,28 @@ OS-image: context [ h [integer!] ] + #import [ + "kernel32.dll" stdcall [ + GlobalAlloc: "GlobalAlloc" [ + flags [integer!] + size [integer!] + return: [integer!] + ] + GlobalFree: "GlobalFree" [ + hMem [integer!] + return: [integer!] + ] + GlobalLock: "GlobalLock" [ + hMem [integer!] + return: [byte-ptr!] + ] + GlobalUnlock: "GlobalUnlock" [ + hMem [integer!] + return: [integer!] + ] + ] + ] + IWICImagingFactory: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -121,7 +134,7 @@ OS-image: context [ SetPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] SetThumbnail [function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]] WritePixels [function! [this [this!] count [integer!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]] - WriteSource [function! [this [this!] piBitmapSource [int-ptr!] prc [int-ptr!] return: [integer!]]] + WriteSource [function! [this [this!] piBitmapSource [int-ptr!] prc [RECT!] return: [integer!]]] Commit [function! [this [this!] return: [integer!]]] GetMetadataQueryWriter [function! [this [this!] ppIMetaReader [ptr-ptr!] return: [integer!]]] ] @@ -137,7 +150,7 @@ OS-image: context [ SetPalette [function! [this [this!] pIPalette [int-ptr!] return: [integer!]]] SetThumbnail [function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]] SetPreview [function! [this [this!] pIPreview [int-ptr!] return: [integer!]]] - CreateNewFrame [function! [this [this!] ppIFrameEnc [ptr-ptr!] ppIEncOpts [ptr-ptr!] return: [integer!]]] + CreateNewFrame [function! [this [this!] ppIFrameEnc [interface!] ppIEncOpts [int-ptr!] return: [integer!]]] Commit [function! [this [this!] return: [integer!]]] GetMetadataQueryWriter [function! [this [this!] ppIMetaWriter [ptr-ptr!] return: [integer!]]] ] @@ -228,6 +241,12 @@ OS-image: context [ UuidFromString "EC5EC8A9-C395-4314-9C77-54D7A935FF70" :IID_IWICImagingFactory UuidFromString "6FDDC324-4E03-4BFE-B185-3D77768DC90F" GUID_WICPixelFormat32bppBGRA UuidFromString "6FDDC324-4E03-4BFE-B185-3D77768DC910" GUID_WICPixelFormat32bppPBGRA + UuidFromString "0AF1D87E-FCFE-4188-BDEB-A7906471CBE3" GUID_ContainerFormatBmp + UuidFromString "1B7CFAF4-713F-473C-BBCD-6137425FAEAF" GUID_ContainerFormatPng + UuidFromString "19E4A5AA-5662-4FC5-A0C0-1758028E1057" GUID_ContainerFormatJpeg + UuidFromString "163BCC30-E2E9-4F0B-961D-A3E9FDB788A3" GUID_ContainerFormatTiff + UuidFromString "1F8A5601-7D4D-4CBD-9C82-1BC8D4EEB9A5" GUID_ContainerFormatGif + hr: CoCreateInstance as int-ptr! CLSID_WICImagingFactory 0 CLSCTX_INPROC_SERVER as int-ptr! IID_IWICImagingFactory :II if hr = 0 [ wic-factory: as this! II/ptr @@ -238,20 +257,57 @@ OS-image: context [ image [integer!] format [int-ptr!] return: [integer!] + /local + this [this!] + IB [IWICBitmap] + guid [tagGUID value] + ret [integer!] ][ - 0 + this: as this! image + IB: as IWICBitmap this/vtbl + ret: IB/GetPixelFormat this as int-ptr! :guid + format/value: either all [ + guid/data1 = GUID_WICPixelFormat32bppBGRA/data1 + guid/data2 = GUID_WICPixelFormat32bppBGRA/data2 + guid/data3 = GUID_WICPixelFormat32bppBGRA/data3 + guid/data4 = GUID_WICPixelFormat32bppBGRA/data4 + ][1][0] + ret + ] + + fixed-format?: func [ + format [integer!] + return: [logic!] + ][ + format = 1 + ] + + fixed-format: func [ + return: [integer!] + ][ + 1 ] create-bitmap-from-scan0: func [ width [integer!] height [integer!] stride [integer!] - format [integer!] + format [integer!] ;-- only support GUID_WICPixelFormat32bppBGRA for now scan0 [byte-ptr!] bitmap [int-ptr!] return: [integer!] + /local + IFAC [IWICImagingFactory] + size [integer!] + bmp [interface! value] + ret [integer!] ][ - 0 + IFAC: as IWICImagingFactory wic-factory/vtbl + if stride = 0 [stride: width * 4] + size: stride * height + ret: IFAC/CreateBitmapFromMemory wic-factory width height as integer! GUID_WICPixelFormat32bppBGRA stride size scan0 :bmp + bitmap/value: as integer! bmp/ptr + ret ] create-bitmap-from-gdidib: func [ @@ -331,6 +387,8 @@ OS-image: context [ get-data: func [ handle [integer!] + width [int-ptr!] + height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local @@ -341,12 +399,35 @@ OS-image: context [ ][ this: as this! handle lock: as IWICBitmapLock this/vtbl - + lock/GetSize this width height + lock/GetStride this stride size: 0 data: 0 lock/GetDataPointer this :size :data as int-ptr! data ] + get-data-pixel-format: func [ + handle [integer!] + format [int-ptr!] + return: [integer!] + /local + this [this!] + lock [IWICBitmapLock] + guid [tagGUID value] + ret [integer!] + ][ + this: as this! handle + lock: as IWICBitmapLock this/vtbl + ret: lock/GetPixelFormat this as int-ptr! :guid + format/value: either all [ + guid/data1 = GUID_WICPixelFormat32bppBGRA/data1 + guid/data2 = GUID_WICPixelFormat32bppBGRA/data2 + guid/data3 = GUID_WICPixelFormat32bppBGRA/data3 + guid/data4 = GUID_WICPixelFormat32bppBGRA/data4 + ][1][0] + ret + ] + get-pixel: func [ bitmap [node!] index [integer!] ;-- zero-based @@ -444,7 +525,6 @@ OS-image: context [ ][ this: as this! img/node IB: as IWICBitmap this/vtbl - if null? wic-factory [init] IFAC: as IWICImagingFactory wic-factory/vtbl IFAC/CreateBitmapScaler wic-factory :iscale sthis: as this! iscale/ptr @@ -474,14 +554,16 @@ OS-image: context [ conv [IWICFormatConverter] bitmap [interface! value] ][ - if null? wic-factory [init] IFAC: as IWICImagingFactory wic-factory/vtbl IFAC/CreateDecoderFromFilename wic-factory file/to-OS-path src null GENERIC_READ 0 :II this: as this! II/ptr dec: as IWICBitmapDecoder this/vtbl count: 0 dec/GetFrameCount this :count - if count < 1 [return null] + if count < 1 [ + dec/Release this + return null + ] dec/GetFrame this 0 :iframe fthis: as this! iframe/ptr frame: as IWICBitmapFrameDecode fthis/vtbl @@ -524,7 +606,6 @@ OS-image: context [ g [integer!] ][ if any [zero? width zero? height][return null] - if null? wic-factory [init] IFAC: as IWICImagingFactory wic-factory/vtbl IFAC/CreateBitmap wic-factory width height as int-ptr! GUID_WICPixelFormat32bppBGRA WICBitmapCacheOnLoad :bitmap bthis: as this! bitmap/ptr @@ -567,17 +648,147 @@ OS-image: context [ ] load-binary: func [ - data [byte-ptr!] - len [integer!] - return: [node!] - ][null] + data [byte-ptr!] + len [integer!] + return: [node!] + /local + hMem [integer!] + p [byte-ptr!] + s [integer!] + IFAC [IWICImagingFactory] + idec [interface! value] + dthis [this!] + dec [IWICBitmapDecoder] + count [integer!] + iframe [interface! value] + fthis [this!] + frame [IWICBitmapFrameDecode] + iconv [interface! value] + cthis [this!] + conv [IWICFormatConverter] + bitmap [interface! value] + ][ + hMem: GlobalAlloc GMEM_MOVEABLE len + p: GlobalLock hMem + copy-memory p data len + GlobalUnlock hMem + + s: 0 + CreateStreamOnHGlobal hMem true :s + + IFAC: as IWICImagingFactory wic-factory/vtbl + IFAC/CreateDecoderFromStream wic-factory as int-ptr! s null 1 :idec + dthis: as this! idec/ptr + dec: as IWICBitmapDecoder dthis/vtbl + count: 0 + dec/GetFrameCount dthis :count + if count < 1 [ + dec/Release dthis + return null + ] + dec/GetFrame dthis 0 :iframe + fthis: as this! iframe/ptr + frame: as IWICBitmapFrameDecode fthis/vtbl + IFAC/CreateFormatConverter wic-factory :iconv + cthis: as this! iconv/ptr + conv: as IWICFormatConverter cthis/vtbl + conv/Initialize cthis as int-ptr! fthis as int-ptr! GUID_WICPixelFormat32bppBGRA 0 null 0.0 0 + IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap + + conv/Release cthis + frame/Release fthis + dec/Release dthis + as int-ptr! bitmap/ptr + ] encode: func [ - image [red-image!] - slot [red-value!] - format [integer!] - return: [red-value!] - ][null] + image [red-image!] + slot [red-value!] + format [integer!] + return: [red-value!] + /local + bin [red-binary!] + s [series!] + clsid [tagGUID] + stream [IStream] + storage [IStorage] + stat [tagSTATSTG] + IStm [interface!] + ISto [interface!] + len [integer!] + hr [integer!] + IFAC [IWICImagingFactory] + ienc [interface! value] + ethis [this!] + enc [IWICBitmapEncoder] + iframe [interface! value] + fthis [this!] + frame [IWICBitmapFrameEncode] + prop [integer!] + rect [RECT! value] + ][ + switch format [ + IMAGE_BMP [clsid: GUID_ContainerFormatBmp] + IMAGE_PNG [clsid: GUID_ContainerFormatPng] + IMAGE_GIF [clsid: GUID_ContainerFormatGif] + IMAGE_JPEG [clsid: GUID_ContainerFormatJpeg] + IMAGE_TIFF [clsid: GUID_ContainerFormatTiff] + default [probe "Cannot find image encoder" return null] + ] + + ISto: declare interface! + IStm: declare interface! + stat: declare tagSTATSTG + hr: StgCreateDocfile + null + STGM_READWRITE or STGM_CREATE or STGM_SHARE_EXCLUSIVE or STGM_DELETEONRELEASE + 0 + ISto + storage: as IStorage ISto/ptr/vtbl + hr: storage/CreateStream + ISto/ptr + #u16 "RedImageStream" + STGM_READWRITE or STGM_SHARE_EXCLUSIVE + 0 + 0 + IStm + IFAC: as IWICImagingFactory wic-factory/vtbl + hr: IFAC/CreateEncoder wic-factory as int-ptr! clsid null :ienc + ethis: as this! ienc/ptr + enc: as IWICBitmapEncoder ethis/vtbl + hr: enc/Initialize ethis as int-ptr! IStm/ptr 2 + prop: 0 + hr: enc/CreateNewFrame ethis :iframe :prop + fthis: as this! iframe/ptr + frame: as IWICBitmapFrameEncode fthis/vtbl + rect/x: 0 rect/y: 0 + rect/w: IMAGE_WIDTH(image/size) + rect/h: IMAGE_HEIGHT(image/size) + hr: frame/Initialize fthis null + hr: frame/WriteSource fthis image/node rect + hr: frame/Commit fthis + hr: enc/Commit ethis + frame/Release fthis + enc/Release ethis + stream: as IStream IStm/ptr/vtbl + stream/Stat IStm/ptr stat 1 + len: stat/cbSize_low + + bin: as red-binary! slot + bin/header: TYPE_UNSET + bin/head: 0 + bin/node: alloc-bytes len + bin/header: TYPE_BINARY + + s: GET_BUFFER(bin) + s/tail: as cell! (as byte-ptr! s/tail) + len + + stream/Seek IStm/ptr 0 0 0 0 0 + stream/Read IStm/ptr as byte-ptr! s/offset len :hr + stream/Release IStm/ptr + storage/Release ISto/ptr + as red-value! bin + ] clone: func [ src [red-image!] @@ -621,7 +832,6 @@ OS-image: context [ offset: src/head this: as this! src/node IB: as IWICBitmap this/vtbl - if null? wic-factory [init] IFAC: as IWICImagingFactory wic-factory/vtbl if all [zero? offset not part?][ IFAC/CreateBitmapFromSource wic-factory as int-ptr! this 0 :bitmap diff --git a/runtime/red.reds b/runtime/red.reds index 5b7175e89b..de9d4702bb 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -205,7 +205,12 @@ red: context [ handle/init date/init port/init - #if OS = 'Windows [image/init] ;-- temporary + #if OS = 'Windows [ ;-- temporary + #if legacy = none [ + OS-image/init + ] + image/init + ] #if OS = 'macOS [image/init] ;-- temporary actions/init From 5a87d5f1fdb201d81f5ff52c6513991274a0355d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 10 Dec 2019 16:08:02 +0100 Subject: [PATCH 0610/3432] FIX: [R/S] crashing in emitter/store-value in PIC mode on binary! arrays. --- system/targets/ARM.r | 4 ++-- system/targets/IA-32.r | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/system/targets/ARM.r b/system/targets/ARM.r index 08975ae96e..000ea440ad 100644 --- a/system/targets/ARM.r +++ b/system/targets/ARM.r @@ -1509,7 +1509,7 @@ make-profilable make target-class [ ] emit-store: func [ - name [word!] value [char! logic! integer! word! string! paren! tag! get-word! decimal! issue!] + name [word!] value [char! logic! integer! word! string! binary! paren! tag! get-word! decimal! issue!] spec [block! none!] /by-value slots [integer!] /local store-qword store-word store-byte type opcode @@ -1595,7 +1595,7 @@ make-profilable make target-class [ ] do store-word ] - string! paren! [ + string! paren! binary! [ if all [spec not PIC?][emit-load-literal-ptr spec/2] do store-word ] diff --git a/system/targets/IA-32.r b/system/targets/IA-32.r index 2a2b3fccbf..61514da4ac 100644 --- a/system/targets/IA-32.r +++ b/system/targets/IA-32.r @@ -925,7 +925,7 @@ make-profilable make target-class [ ] emit-store: func [ - name [word!] value [char! logic! integer! word! string! paren! tag! get-word! decimal! issue!] + name [word!] value [char! logic! integer! word! string! binary! paren! tag! get-word! decimal! issue!] spec [block! none!] /by-value slots [integer!] /local store-dword type offset @@ -1017,7 +1017,8 @@ make-profilable make target-class [ ] ] string! - paren! [ + paren! + binary! [ either PIC? [ emit-variable name #{A3} ;-- MOV [name], eax ; global From 0cf9a5f5fdb61dde6920c1b7ea3231b9600d788f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 10 Dec 2019 16:09:00 +0100 Subject: [PATCH 0611/3432] FIX: use strncasecmp() instead of strnicmp() on POSIX platforms. strnicmp() is deprecated in C99. --- runtime/platform/POSIX.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/platform/POSIX.reds b/runtime/platform/POSIX.reds index 496a2bf63c..e3f6dbae6f 100644 --- a/runtime/platform/POSIX.reds +++ b/runtime/platform/POSIX.reds @@ -227,7 +227,7 @@ pollfd!: alias struct! [ timeout [integer!] return: [integer!] ] - strnicmp: "strnicmp" [ + strnicmp: "strncasecmp" [ s1 [byte-ptr!] s2 [byte-ptr!] len [integer!] From 2d92c5cdfdf39bf0f742f0155f9633467c1701c6 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 11 Dec 2019 14:05:42 +0800 Subject: [PATCH 0612/3432] FIX: preserve the get-data interface not changed --- libRed/libRed.red | 5 +---- runtime/clipboard.reds | 6 ++++-- runtime/datatypes/image.reds | 27 ++++++--------------------- runtime/platform/image-gdiplus.reds | 4 ---- runtime/platform/image-quartz.reds | 4 ---- runtime/platform/image-wic.reds | 3 --- 6 files changed, 11 insertions(+), 38 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index a83d329899..cb7267139a 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -513,8 +513,6 @@ Red [ img [red-image!] rgb [byte-ptr!] sz [integer!] - w [integer!] - h [integer!] stride [integer!] bitmap [integer!] data [int-ptr!] @@ -537,10 +535,9 @@ Red [ img/node: OS-image/make-image width height rgb null null if format = RGBA_BUFFER [ - w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img yes - data: OS-image/get-data bitmap :w :h :stride + data: OS-image/get-data bitmap :stride copy-memory as byte-ptr! data src sz * 4 OS-image/unlock-bitmap img bitmap ] diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index 0f15217d0c..c7ffa21fb5 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -408,8 +408,10 @@ clipboard: context [ fmts/2: CF_DIBV5 bmdata: OS-image/lock-bitmap img no assert 0 <> bmdata - w: 0 h: 0 s: 0 - scan0: as byte-ptr! OS-image/get-data bmdata :w :h :s + w: OS-image/width? as int-ptr! bmdata + h: OS-image/height? as int-ptr! bmdata + s: 0 + scan0: as byte-ptr! OS-image/get-data bmdata :s len: w * h * 4 format: 0 OS-image/get-data-pixel-format bmdata :format diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 89895636a0..2008eca972 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -18,15 +18,12 @@ image: context [ bitmap [int-ptr!] return: [int-ptr!] /local - w [integer!] - h [integer!] stride [integer!] data [int-ptr!] ][ - w: 0 h: 0 stride: 0 bitmap/value: OS-image/lock-bitmap img yes - OS-image/get-data bitmap/value :w :h :stride + OS-image/get-data bitmap/value :stride ] release-buffer: func [ @@ -181,8 +178,6 @@ image: context [ bin [red-binary!] s [series!] p [byte-ptr!] - w [integer!] - h [integer!] stride [integer!] bitmap [integer!] i [integer!] @@ -202,10 +197,9 @@ image: context [ s/tail: as cell! (as byte-ptr! s/tail) + bytes p: as byte-ptr! s/offset - w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img no - data: OS-image/get-data bitmap :w :h :stride + data: OS-image/get-data bitmap :stride either type = EXTRACT_ARGB [ copy-memory p as byte-ptr! data bytes @@ -239,8 +233,6 @@ image: context [ sz [integer!] s [series!] p [byte-ptr!] - w [integer!] - h [integer!] stride [integer!] bitmap [integer!] pixel [integer!] @@ -256,10 +248,9 @@ image: context [ if zero? sz [return bin] offset: img/head - w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img yes - data: OS-image/get-data bitmap :w :h :stride + data: OS-image/get-data bitmap :stride end: data + sz type: TYPE_OF(bin) @@ -495,8 +486,6 @@ image: context [ count [integer!] bitmap [integer!] data [int-ptr!] - w [integer!] - h [integer!] stride [integer!] size [integer!] end [int-ptr!] @@ -523,10 +512,9 @@ image: context [ return part - 5 ] - w: 0 h: 0 stride: 0 bitmap: OS-image/lock-bitmap img no - data: OS-image/get-data bitmap :w :h :stride + data: OS-image/get-data bitmap :stride end: data + (width * height) data: data + img/head size: as-integer end - data @@ -758,8 +746,6 @@ image: context [ /local type [integer!] res [integer!] - w [integer!] - h [integer!] bmp1 [integer!] bmp2 [integer!] same? [logic!] @@ -792,13 +778,12 @@ image: context [ ][ res: 1 ][ - w: 0 h: 0 type: 0 bmp1: OS-image/lock-bitmap arg1 no bmp2: OS-image/lock-bitmap arg2 no res: compare-memory - as byte-ptr! OS-image/get-data bmp1 :w :h :type - as byte-ptr! OS-image/get-data bmp2 :w :h :type + as byte-ptr! OS-image/get-data bmp1 :type + as byte-ptr! OS-image/get-data bmp2 :type IMAGE_WIDTH(arg1/size) * IMAGE_HEIGHT(arg2/size) * 4 OS-image/unlock-bitmap arg1 bmp1 OS-image/unlock-bitmap arg2 bmp2 diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 4218146638..4593f5f67e 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -333,16 +333,12 @@ OS-image: context [ get-data: func [ handle [integer!] - width [int-ptr!] - height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local bitmap [BitmapData!] ][ bitmap: as BitmapData! handle - width/value: bitmap/width - height/value: bitmap/height stride/value: bitmap/stride as int-ptr! bitmap/scan0 ] diff --git a/runtime/platform/image-quartz.reds b/runtime/platform/image-quartz.reds index 0419910c3b..6bc0f0caf4 100644 --- a/runtime/platform/image-quartz.reds +++ b/runtime/platform/image-quartz.reds @@ -251,16 +251,12 @@ OS-image: context [ get-data: func [ handle [integer!] - width [int-ptr!] - height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local node [img-node!] ][ node: as img-node! handle - width/value: IMAGE_WIDTH(node/size) - height/value: IMAGE_HEIGHT(node/size) stride/value: width/value * 4 node/buffer ] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 6aebae3d1d..7996f26a72 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -387,8 +387,6 @@ OS-image: context [ get-data: func [ handle [integer!] - width [int-ptr!] - height [int-ptr!] stride [int-ptr!] return: [int-ptr!] /local @@ -399,7 +397,6 @@ OS-image: context [ ][ this: as this! handle lock: as IWICBitmapLock this/vtbl - lock/GetSize this width height lock/GetStride this stride size: 0 data: 0 lock/GetDataPointer this :size :data From f144290ee44d73fdb3d41d79ba93583778eaa782 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 11 Dec 2019 12:41:44 +0100 Subject: [PATCH 0613/3432] FIX: compiling error. --- modules/view/backends/windows/win32.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 702ab57a7b..a8d12a7374 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -2382,12 +2382,12 @@ XFORM!: alias struct! [ ] GdipCreateFromHWND: "GdipCreateFromHWND" [ hwnd [handle!] - graphics [GpGraphics!] + graphics [int-ptr!] return: [integer!] ] GdipCreateFromHDC: "GdipCreateFromHDC" [ hDC [handle!] - graphics [GpGraphics!] + graphics [int-ptr!] return: [integer!] ] GdipDeleteGraphics: "GdipDeleteGraphics" [ From c84300f69154f8841b70b311522a6f1d3fef9711 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 11 Dec 2019 15:28:50 +0100 Subject: [PATCH 0614/3432] FEAT: use ID2D1DeviceContext in DRAW. --- modules/view/backends/windows/draw.reds | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 932015aca0..f8a4c8d910 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -347,21 +347,21 @@ OS-draw-box: func [ lower [red-pair!] /local this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] rc [RECT32! value] ][ this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl + dc: as ID2D1DeviceContext this/vtbl rc/right: as float32! lower/x rc/bottom: as float32! lower/y rc/left: as float32! upper/x rc/top: as float32! upper/y if ctx/brush? [ - rt/FillRectangle this rc ctx/brush + dc/FillRectangle this rc ctx/brush ] if ctx/pen? [ - rt/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style + dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -405,11 +405,11 @@ OS-draw-circle: func [ radius [red-integer!] /local this [this!] - rt [ID2D1HwndRenderTarget] + dc [ID2D1DeviceContext] ellipse [D2D1_ELLIPSE] ][ this: as this! ctx/dc - rt: as ID2D1HwndRenderTarget this/vtbl + dc: as ID2D1DeviceContext this/vtbl ellipse: declare D2D1_ELLIPSE ellipse/x: as float32! center/x @@ -417,10 +417,10 @@ OS-draw-circle: func [ ellipse/radiusX: get-float32 radius ellipse/radiusY: ellipse/radiusX if ctx/brush? [ - rt/FillEllipse this ellipse ctx/brush + dc/FillEllipse this ellipse ctx/brush ] if ctx/pen? [ - rt/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style + dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style ] ] From 24a89987fa56d5f84ee930f7fcde2456bea51d53 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 11 Dec 2019 18:14:34 +0800 Subject: [PATCH 0615/3432] FIX: refactor gradient pen/fill-pen feature --- modules/view/backends/gtk3/draw.reds | 1236 ++++++++++++++++---------- runtime/definitions.reds | 40 +- 2 files changed, 797 insertions(+), 479 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 6dd05a697a..a0c5d99be3 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -14,6 +14,9 @@ Red/System [ draw-state!: alias struct! [mat [handle!]] +#define MAX_COLORS 256 ;-- max number of colors for gradient + + free-pango-cairo-font: func [ dc [draw-ctx!] ][ @@ -47,11 +50,15 @@ set-source-color: func [ cairo_set_source_rgba cr r g b a ] -;; TODO: only used for rich-text that I think need much less than that -;; certainly create -init-draw-ctx: func [ - ctx [draw-ctx!] - cr [handle!] +draw-begin: func [ + ctx [draw-ctx!] + cr [handle!] + img [red-image!] + on-graphic? [logic!] + pattern? [logic!] + return: [draw-ctx!] + /local + grad [gradient!] ][ ctx/cr: cr ctx/pen-width: 1.0 @@ -63,26 +70,27 @@ init-draw-ctx: func [ ctx/font-color: 0 ctx/pen?: yes ctx/brush?: no - ctx/grad-pen: null - ctx/grad-brush: null + + grad: ctx/grad-pen + grad/on?: off + grad/matrix-on?: off + grad/count: 0 + grad/offset-on?: off + grad/focal-on?: off + grad/pattern-on?: off + + grad: ctx/grad-brush + grad/on?: off + grad/matrix-on?: off + grad/count: 0 + grad/offset-on?: off + grad/focal-on?: off + grad/pattern-on?: off ctx/font-attrs: null ctx/font-opts: null -] - -draw-begin: func [ - ctx [draw-ctx!] - cr [handle!] - img [red-image!] - on-graphic? [logic!] - pattern? [logic!] - return: [draw-ctx!] -][ - ;; DEBUG: print ["draw-begin : " on-graphic? " " pattern? lf] - init-draw-ctx ctx cr cairo_set_line_width cr 1.0 - ;; DEBUG: print ["draw-begin: set-source-color black" lf] set-source-color cr 0 ctx ] @@ -96,6 +104,25 @@ draw-end: func [ ][ cairo_identity_matrix dc/cr free-pango-cairo-font dc + if dc/grad-pen/on? [ + free-gradient dc/grad-pen + dc/grad-pen/on?: off + ] + if dc/grad-brush/on? [ + free-gradient dc/grad-brush + dc/grad-brush/on?: off + ] +] + +free-gradient: func [ + grad [gradient!] +][ + grad/matrix-on?: off + if grad/pattern-on? [ + cairo_pattern_destroy grad/pattern + grad/pattern-on?: off + ] + free as byte-ptr! grad/colors ] do-draw-path: func [ @@ -106,10 +133,13 @@ do-draw-path: func [ cr: dc/cr if dc/brush? [ cairo_save cr - either null? dc/grad-brush [ - set-source-color cr dc/brush-color + either all [ + dc/grad-brush/on? + dc/grad-brush/pattern-on? + ][ + cairo_set_source cr dc/grad-brush/pattern ][ - cairo_set_source cr dc/grad-brush + set-source-color cr dc/brush-color ] cairo_fill_preserve cr cairo_restore cr @@ -125,8 +155,11 @@ do-draw-pen: func [ cr: dc/cr either dc/pen? [ cairo_save cr - unless null? dc/grad-pen [ - cairo_set_source cr dc/grad-pen + if all [ + dc/grad-pen/on? + dc/grad-pen/pattern-on? + ][ + cairo_set_source cr dc/grad-pen/pattern ] cairo_stroke cr cairo_restore cr @@ -135,306 +168,498 @@ do-draw-pen: func [ ] ] -copy-gradiant-props: func [ - grad [handle!] - ngrad [handle!] +line-distance: func [ + x1 [integer!] + y1 [integer!] + x2 [integer!] + y2 [integer!] + return: [float32!] + /local + x [float32!] + y [float32!] + px [float32!] + py [float32!] + delta [float32!] +][ + x: as float32! x1 + y: as float32! y1 + px: (as float32! x2) - x + py: (as float32! y2) - y + delta: (px * px) + (py * py) + sqrtf delta +] + +update-pattern: func [ + grad [gradient!] + pattern [handle!] + cx [float!] + cy [float!] /local - cnt [integer!] - index [integer!] - offset [float!] + matrix [cairo_matrix_t!] + m [cairo_matrix_t! value] + res [cairo_matrix_t! value] + color [int-ptr!] + pos [float32-ptr!] r [float!] g [float!] b [float!] a [float!] - mode [integer!] + p [float!] ][ - cnt: 0 - cairo_pattern_get_color_stop_count grad :cnt - index: 0 - loop cnt [ - offset: 0.0 r: 0.0 g: 0.0 b: 0.0 a: 0.0 - cairo_pattern_get_color_stop_rgba grad index - :offset :r :g :b :a - cairo_pattern_add_color_stop_rgba ngrad offset r g b a - index: index + 1 + cairo_matrix_init_translate m 0.0 - cx 0.0 - cy + either grad/matrix-on? [ + matrix: as cairo_matrix_t! grad/matrix + cairo_matrix_multiply res matrix m + copy-memory as byte-ptr! matrix as byte-ptr! res size? cairo_matrix_t! + cairo_pattern_set_matrix pattern matrix + ][ + cairo_pattern_set_matrix pattern m + ] + cairo_pattern_set_extend pattern + case [ + grad/spread = _pad [CAIRO_EXTEND_PAD] + grad/spread = _repeat [CAIRO_EXTEND_REPEAT] + grad/spread = _reflect [CAIRO_EXTEND_REFLECT] + true [CAIRO_EXTEND_REPEAT] ;-- default spread + ] + + color: grad/colors + pos: grad/colors-pos + unless grad/zero-base? [ + color: color + 1 + pos: pos + 1 ] - mode: cairo_pattern_get_extend grad - cairo_pattern_set_extend ngrad mode + loop grad/count [ + r: as-float color/1 and FFh + r: r / 255.0 + g: as-float color/1 >> 8 and FFh + g: g / 255.0 + b: as-float color/1 >> 16 and FFh + b: b / 255.0 + a: as-float 255 - (color/1 >>> 24) + a: a / 255.0 + p: as float! pos/1 + cairo_pattern_add_color_stop_rgba pattern p r g b a + color: color + 1 + pos: pos + 1 + ] + either grad/pattern-on? [ + cairo_pattern_destroy grad/pattern + ][ + grad/pattern-on?: on + ] + grad/pattern: pattern ] -check-grad-line: func [ - grad [handle!] - point [red-pair!] - end [red-pair!] - return: [handle!] +get-shape-center: func [ + start [red-pair!] + end [red-pair!] + cx [float32-ptr!] + cy [float32-ptr!] + d [float32-ptr!] /local - type [integer!] - ngrad [handle!] - x [float32!] - y [float32!] + point [red-pair!] + dx [float32!] + dy [float32!] + x0 [float32!] + y0 [float32!] + x1 [float32!] + y1 [float32!] + a [float32!] + r [float32!] + signedArea [float32!] + centroid-x [float32!] + centroid-y [float32!] +][ + ;-- implementation taken from http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon + signedArea: as float32! 0.0 + centroid-x: as float32! 0.0 centroid-y: as float32! 0.0 + point: start + while [point <= end][ + x0: as float32! point/x + y0: as float32! point/y + point: point + 1 + x1: as float32! point/x + y1: as float32! point/y + a: x0 * y1 - (x1 * y0) + signedArea: signedArea + a + centroid-x: centroid-x + ((x0 + x1) * a) + centroid-y: centroid-y + ((y0 + y1) * a) + ] + + signedArea: signedArea * as float32! 0.5 + centroid-x: centroid-x / (signedArea * as float32! 6.0) + centroid-y: centroid-y / (signedArea * as float32! 6.0) + + cx/value: centroid-x + cy/value: centroid-y + + if d <> null [ + ;-- take biggest distance + d/value: as float32! 0.0 + point: start + while [point <= end][ + dx: centroid-x - as float32! point/x + dy: centroid-y - as float32! point/y + r: sqrtf dx * dx + ( dy * dy ) + if r > d/value [ d/value: r ] + point: point + 1 + ] + ] +] + +check-grad-points: func [ + grad [gradient!] + upper-x [integer!] + upper-y [integer!] + lower-x [integer!] + lower-y [integer!] + /local + pattern [handle!] + t [integer!] + x1 [float!] + y1 [float!] + r1 [float!] + x2 [float!] + y2 [float!] + r2 [float!] + delta [float32!] px [float32!] py [float32!] - delta [float32!] ][ - type: cairo_pattern_get_type grad + unless grad/on? [exit] + pattern: null case [ - type = CAIRO_PATTERN_TYPE_LINEAR [ - ngrad: cairo_pattern_create_linear - as float! point/x as float! point/y - as float! end/x as float! point/y + grad/type = linear [ + either grad/offset-on? [ + x1: as float! upper-x + grad/offset/x + y1: as float! upper-y + grad/offset/y + x2: as float! upper-x + grad/offset2/x + y2: as float! upper-y + grad/offset2/y + ][ + x1: as float! upper-x y1: as float! upper-y + x2: as float! lower-x y2: as float! lower-y + ] + pattern: cairo_pattern_create_linear 0.0 0.0 x2 - x1 y2 - y1 ] - type = CAIRO_PATTERN_TYPE_RADIAL [ - x: as float32! point/x - y: as float32! point/y - px: (as float32! end/x) - x - py: (as float32! end/y) - y - delta: (px * px) + (py * py) - delta: sqrtf delta - px: (as float32! end/x) + x - py: (as float32! end/y) + y - px: px / 2.0 py: py / 2.0 - ngrad: cairo_pattern_create_radial - as float! px as float! py 0.0 - as float! px as float! py as float! delta + grad/type = radial [ + if upper-x > lower-x [ + t: lower-x + lower-x: upper-x + upper-x: t + ] + if upper-y > lower-y [ + t: lower-y + lower-y: upper-y + upper-y: t + ] + either grad/offset-on? [ + either grad/focal-on? [ + x1: as float! upper-x + grad/focal/x + y1: as float! upper-y + grad/focal/y + x2: as float! upper-x + grad/offset/x + y2: as float! upper-y + grad/offset/y + r2: as float! grad/offset2/x + delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y + r1: as float! delta + either r1 >= r2 [ + r1: 0.0 + ][ + r1: r2 - r1 + ] + ][ + x1: as float! upper-x + grad/offset/x + y1: as float! upper-y + grad/offset/y + x2: x1 + y2: y1 + r1: 0.0 + r2: as float! grad/offset2/x + ] + ][ + delta: line-distance upper-x upper-y lower-x lower-y + px: as float32! lower-x + upper-x + py: as float32! lower-y + upper-y + x1: as float! px + x1: x1 / 2.0 + y1: as float! py + y1: y1 / 2.0 + x2: x1 y2: y1 + r1: 0.0 + r2: as float! delta + ] + pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 ] - true [return null] + true [0] + ] + unless null? pattern [ + update-pattern grad pattern x1 y1 ] +] - copy-gradiant-props grad ngrad - ngrad +check-grad-line: func [ + grad [gradient!] + upper [red-pair!] + lower [red-pair!] +][ + check-grad-points grad upper/x upper/y lower/x lower/y ] -check-grad-pen-line: func [ - dc [draw-ctx!] +check-grad-brush-lines: func [ + grad [gradient!] point [red-pair!] end [red-pair!] /local - ngrad [handle!] + pattern [handle!] + next [red-pair!] + x1 [float!] + y1 [float!] + r1 [float!] + x2 [float!] + y2 [float!] + r2 [float!] + cx [float32!] + cy [float32!] + d [float32!] + x0 [float!] + y0 [float!] + delta [float32!] ][ - if all [ - dc/pen? - not null? dc/grad-pen - dc/gpen-resize? - ][ - ngrad: check-grad-line dc/grad-pen point end - unless null? ngrad [ - cairo_pattern_destroy dc/grad-pen - dc/grad-pen: ngrad - dc/gpen-resize?: false + unless grad/on? [exit] + pattern: null + case [ + grad/type = linear [ + either grad/offset-on? [ + x1: as float! point/x + grad/offset/x + y1: as float! point/y + grad/offset/y + x2: as float! point/x + grad/offset2/x + y2: as float! point/y + grad/offset2/y + ][ + x1: as float! point/x y1: as float! point/y + next: point + 1 + x2: as float! next/x y2: as float! next/y + ] + pattern: cairo_pattern_create_linear 0.0 0.0 x2 - x1 y2 - y1 ] + grad/type = radial [ + cx: as float32! 0.0 + cy: cx + d: cx + get-shape-center point end :cx :cy :d + either grad/offset-on? [ + x0: as float! cx - d + y0: as float! cy - d + either grad/focal-on? [ + x1: x0 + as float! grad/focal/x + y1: y0 + as float! grad/focal/y + x2: x0 + as float! grad/offset/x + y2: y0 + as float! grad/offset/y + r2: as float! grad/offset2/x + delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y + r1: as float! delta + either r1 >= r2 [ + r1: 0.0 + ][ + r1: r2 - r1 + ] + ][ + x1: x0 + as float! grad/offset/x + y1: y0 + as float! grad/offset/y + r1: 0.0 + x2: x1 + y2: y1 + r2: as float! grad/offset2/x + ] + ][ + x1: as float! cx + y1: as float! cy + r1: 0.0 + x2: x1 + y2: y1 + r2: as float! d + ] + pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + ] + true [0] + ] + unless null? pattern [ + update-pattern grad pattern x1 y1 ] ] -check-grad-brush-line: func [ - dc [draw-ctx!] - point [red-pair!] - end [red-pair!] +check-grad-arc-radial: func [ + grad [gradient!] + ax [float!] + ay [float!] + ar [float!] /local - ngrad [handle!] + pattern [handle!] + x0 [float!] + y0 [float!] + x1 [float!] + y1 [float!] + r1 [float!] + x2 [float!] + y2 [float!] + r2 [float!] + delta [float32!] ][ - if all [ - dc/brush? - not null? dc/grad-brush - dc/gbrush-resize? - ][ - ngrad: check-grad-line dc/grad-brush point end - unless null? ngrad [ - cairo_pattern_destroy dc/grad-brush - dc/grad-brush: ngrad - dc/gbrush-resize?: false + unless grad/on? [exit] + unless grad/type = radial [exit] + pattern: null + + x0: ax - ar + y0: ay - ar + either grad/offset-on? [ + either grad/focal-on? [ + x1: x0 + as float! grad/focal/x + y1: y0 + as float! grad/focal/y + x2: x0 + as float! grad/offset/x + y2: y0 + as float! grad/offset/y + r2: as float! grad/offset2/x + delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y + r1: as float! delta + either r1 >= r2 [ + r1: 0.0 + ][ + r1: r2 - r1 + ] + ][ + x1: x0 + as float! grad/offset/x + y1: y0 + as float! grad/offset/y + r1: 0.0 + x2: x1 + y2: y1 + r2: as float! grad/offset2/x ] + ][ + x1: ax + y1: ay + r1: 0.0 + x2: x1 + y2: y1 + r2: ar ] -] + pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 -get-shape-center: func [ - start [red-pair!] - end [red-pair!] - cx [int-ptr!] - cy [int-ptr!] - d [int-ptr!] - /local - point [red-pair!] - dx [integer!] - dy [integer!] - x0 [integer!] - y0 [integer!] - x1 [integer!] - y1 [integer!] - a [integer!] - r [integer!] - signedArea [float!] - centroid-x [float!] - centroid-y [float!] -][ - ;-- implementation taken from http://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon - x0: 0 y0: 0 x1: 0 y1: 0 - a: 0 signedArea: 0.0 - centroid-x: 0.0 centroid-y: 0.0 - point: start - while [point <= end] [ - x0: point/x - y0: point/y - point: point + 1 - x1: point/x - y1: point/y - a: x0 * y1 - (x1 * y0) - signedArea: signedArea + as-float a - centroid-x: centroid-x + as-float ((x0 + x1) * a) - centroid-y: centroid-y + as-float ((y0 + y1) * a) - ] - x0: point/x - y0: point/y - x1: start/x - y1: start/y - a: x0 * y1 - (x1 * y0) - signedArea: signedArea + as-float a - centroid-x: centroid-x + as-float ((x0 + x1) * a) - centroid-y: centroid-y + as-float ((y0 + y1) * a) - - signedArea: signedArea * 0.5 - centroid-x: centroid-x / (signedArea * 6.0) - centroid-y: centroid-y / (signedArea * 6.0) - - cx/value: as-integer centroid-x - cy/value: as-integer centroid-y - ;-- take biggest distance - d/value: 0 - point: start - while [point <= end] [ - dx: cx/value - point/x - dy: cy/value - point/y - r: as-integer sqrt as-float ( dx * dx + ( dy * dy ) ) - if r > d/value [ d/value: r ] - point: point + 1 + unless null? pattern [ + update-pattern grad pattern x1 y1 ] ] -check-grad-brush-box: func [ - dc [draw-ctx!] - point [red-pair!] - end [red-pair!] +check-grad-box-radial: func [ + grad [gradient!] + upper [red-pair!] + lower [red-pair!] /local - type [integer!] - cx [integer!] - cy [integer!] - d [integer!] - ngrad [handle!] + pattern [handle!] + x0 [float!] + y0 [float!] + x1 [float!] + y1 [float!] + r1 [float!] + x2 [float!] + y2 [float!] + r2 [float!] + delta [float32!] + w [integer!] + h [integer!] ][ - if all [ - dc/brush? - not null? dc/grad-brush - dc/gbrush-resize? - ][ - type: cairo_pattern_get_type dc/grad-brush - case [ - type = CAIRO_PATTERN_TYPE_LINEAR [ - ngrad: check-grad-line dc/grad-brush point end - ] - type = CAIRO_PATTERN_TYPE_RADIAL [ - cx: 0 cy: 0 d: 0 - get-shape-center point end :cx :cy :d - ngrad: cairo_pattern_create_radial - as float! cx as float! cy 0.0 - as float! cx as float! cy as float! d - - copy-gradiant-props dc/grad-brush ngrad + unless grad/on? [exit] + unless grad/type = radial [exit] + pattern: null + + x0: as float! either upper/x < lower/x [upper/x][lower/x] + y0: as float! either upper/y < lower/y [upper/y][lower/y] + + either grad/offset-on? [ + either grad/focal-on? [ + x1: x0 + as float! grad/focal/x + y1: y0 + as float! grad/focal/y + x2: x0 + as float! grad/offset/x + y2: y0 + as float! grad/offset/y + r2: as float! grad/offset2/x + delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y + r1: as float! delta + either r1 >= r2 [ + r1: 0.0 + ][ + r1: r2 - r1 ] - true [exit] + ][ + x1: x0 + as float! grad/offset/x + y1: y0 + as float! grad/offset/y + r1: 0.0 + x2: x1 + y2: y1 + r2: as float! grad/offset2/x ] - - unless null? ngrad [ - cairo_pattern_destroy dc/grad-brush - dc/grad-brush: ngrad - dc/gbrush-resize?: false + ][ + x1: as float! upper/x + lower/x + y1: as float! upper/y + lower/y + x1: x1 / 2.0 + y1: y1 / 2.0 + r1: 0.0 + x2: x1 + y2: y1 + w: either upper/x < lower/x [ + lower/x - upper/x + ][ + upper/x - lower/x ] + h: either upper/y < lower/y [ + lower/y - upper/y + ][ + upper/y - lower/y + ] + r2: as float! either w > h [w][h] + r2: r2 / 2.0 + ] + pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + + unless null? pattern [ + update-pattern grad pattern x1 y1 ] ] -check-grad-pen-arc: func [ - dc [draw-ctx!] - x [float!] - y [float!] - radius [float!] - /local - type [integer!] - ngrad [handle!] - ex [float!] - ey [float!] -][ - if all [ - dc/pen? - not null? dc/grad-pen - dc/gpen-resize? - ][ - type: cairo_pattern_get_type dc/grad-pen - case [ - type = CAIRO_PATTERN_TYPE_LINEAR [ - ex: x + radius - ex: ex * pi - ey: y + radius - ey: ey * pi - ngrad: cairo_pattern_create_linear - x y ex ey - copy-gradiant-props dc/grad-pen ngrad - ] - type = CAIRO_PATTERN_TYPE_RADIAL [ - ngrad: cairo_pattern_create_radial - x y 0.0 - x y radius - copy-gradiant-props dc/grad-pen ngrad - ] - true [exit] +check-grad-box: func [ + grad [gradient!] + upper [red-pair!] + lower [red-pair!] +][ + case [ + grad/type = linear [ + ;-- the windows backend use horizontal linear gradient default, + ;-- maybe should use diagonal line + check-grad-points grad upper/x upper/y lower/x upper/y ] - - unless null? ngrad [ - cairo_pattern_destroy dc/grad-pen - dc/grad-pen: ngrad - dc/gpen-resize?: false + grad/type = radial [ + check-grad-box-radial grad upper lower ] + true [0] ] ] -check-grad-brush-arc: func [ - dc [draw-ctx!] - x [float!] - y [float!] - radius [float!] +check-grad-circle: func [ + grad [gradient!] + cx [float!] + cy [float!] + rx [float!] + ry [float!] /local - type [integer!] - ngrad [handle!] - ex [float!] - ey [float!] -][ - if all [ - dc/brush? - not null? dc/grad-brush - dc/gbrush-resize? - ][ - type: cairo_pattern_get_type dc/grad-brush - case [ - type = CAIRO_PATTERN_TYPE_LINEAR [ - ex: x + radius - ex: ex * pi - ey: y + radius - ey: ey * pi - ngrad: cairo_pattern_create_linear - x y ex ey - copy-gradiant-props dc/grad-brush ngrad - ] - type = CAIRO_PATTERN_TYPE_RADIAL [ - ngrad: cairo_pattern_create_radial - x y 0.0 - x y radius - copy-gradiant-props dc/grad-brush ngrad - ] - true [exit] + r [float!] +][ + case [ + grad/type = linear [ + check-grad-points grad + as integer! cx - rx as integer! cy - ry + as integer! cx + rx as integer! cy + ry ] - - unless null? ngrad [ - cairo_pattern_destroy dc/grad-brush - dc/grad-brush: ngrad - dc/gbrush-resize?: false + grad/type = radial [ + r: rx + if rx > ry [r: ry] + check-grad-arc-radial grad cx cy r ] + true [0] ] ] @@ -461,7 +686,7 @@ OS-draw-line: func [ cairo_line_to cr as-float iter/x as-float iter/y iter: iter + 1 ] - check-grad-pen-line dc point end + check-grad-line dc/grad-pen point end do-draw-pen dc ] @@ -472,9 +697,12 @@ OS-draw-pen: func [ alpha? [logic!] ][ dc/pen?: not off? - unless null? dc/grad-pen [ - cairo_pattern_destroy dc/grad-pen - dc/grad-pen: null + if dc/grad-pen/on? [ + if dc/grad-pen/pattern-on? [ + cairo_pattern_destroy dc/grad-pen/pattern + ] + dc/grad-pen/pattern-on?: off + dc/grad-pen/on?: off ] if all [not off? dc/pen-color <> color][ dc/pen-color: color @@ -490,9 +718,12 @@ OS-draw-fill-pen: func [ alpha? [logic!] ][ dc/brush?: not off? - unless null? dc/grad-brush [ - cairo_pattern_destroy dc/grad-brush - dc/grad-brush: null + if dc/grad-brush/on? [ + if dc/grad-brush/pattern-on? [ + cairo_pattern_destroy dc/grad-brush/pattern + ] + dc/grad-brush/pattern-on?: off + dc/grad-brush/on?: off ] if dc/brush-color <> color [ dc/brush-color: color @@ -558,8 +789,8 @@ OS-draw-box: func [ ][ cairo_rectangle cr x y w h ] - check-grad-pen-line dc upper lower - check-grad-brush-box dc upper lower + check-grad-box dc/grad-pen upper lower + check-grad-box dc/grad-brush upper lower do-draw-path dc ] @@ -572,8 +803,8 @@ OS-draw-triangle: func [ start: start + 1 ] cairo_close_path dc/cr ;-- close the triangle - check-grad-pen-line dc start start + 2 - check-grad-brush-box dc start start + 2 + check-grad-line dc/grad-pen start start + 1 + check-grad-brush-lines dc/grad-brush start start + 2 do-draw-path dc ] @@ -588,8 +819,8 @@ OS-draw-polygon: func [ start > end ] cairo_close_path dc/cr - check-grad-pen-line dc start end - check-grad-brush-box dc start end + check-grad-line dc/grad-pen start start + 1 + check-grad-brush-lines dc/grad-brush start end do-draw-path dc ] @@ -690,8 +921,8 @@ OS-draw-spline: func [ end ] - check-grad-pen-line dc start end - check-grad-brush-box dc start end + check-grad-line dc/grad-pen start start + 1 + check-grad-brush-lines dc/grad-brush start end do-draw-path dc ] @@ -743,9 +974,8 @@ OS-draw-circle: func [ as-float rad-y cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi cairo_restore cr - if rad-x < rad-y [rad-x: rad-y] - check-grad-pen-arc dc as float! center/x as float! center/y as float! rad-x - check-grad-brush-arc dc as float! center/x as float! center/y as float! rad-x + check-grad-circle dc/grad-pen as float! center/x as float! center/y as float! rad-x as float! rad-y + check-grad-circle dc/grad-brush as float! center/x as float! center/y as float! rad-x as float! rad-y do-draw-path dc ] @@ -773,9 +1003,8 @@ OS-draw-ellipse: func [ as-float rad-y cairo_arc cr 0.0 0.0 1.0 0.0 2.0 * pi cairo_restore cr - if rad-x < rad-y [rad-x: rad-y] - check-grad-pen-arc dc as float! cx as float! cy as float! rad-x - check-grad-brush-arc dc as float! cx as float! cy as float! rad-x + check-grad-circle dc/grad-pen as float! cx as float! cy as float! rad-x as float! rad-y + check-grad-circle dc/grad-brush as float! cx as float! cy as float! rad-x as float! rad-y do-draw-path dc ] @@ -948,9 +1177,8 @@ OS-draw-arc: func [ if closed? [ cairo_close_path cr ] - if rad-x < rad-y [rad-x: rad-y] - check-grad-pen-arc dc cx cy rad-x - check-grad-brush-arc dc cx cy rad-x + check-grad-circle dc/grad-pen cx cy rad-x rad-y + check-grad-circle dc/grad-brush cx cy rad-x rad-y cairo_restore cr either closed? [ do-draw-path dc @@ -985,7 +1213,7 @@ OS-draw-curve: func [ as-float p2/y as-float p3/x as-float p3/y - check-grad-pen-line dc start start + 2 + check-grad-line dc/grad-pen start start + 2 do-draw-pen dc ] @@ -1154,37 +1382,73 @@ OS-draw-grad-pen-old: func [ count [integer!] ;-- number of the colors brush? [logic!] /local + w [integer!] + h [integer!] + int [red-integer!] + grad [gradient!] + nums [integer!] + pc [int-ptr!] x [float!] y [float!] - start [float!] - stop [float!] - pattern [handle!] - int [red-integer!] + n [integer!] f [red-float!] + rotate? [logic!] + scale? [logic!] head [red-value!] next [red-value!] clr [red-tuple!] - n [integer!] delta [float!] p [float!] angle [float!] - rotate? [logic!] - scale? [logic!] - matrix [cairo_matrix_t! value] + matrix [cairo_matrix_t!] + color [int-ptr!] + last-c [int-ptr!] + pos [float32-ptr!] + last-p [float32-ptr!] ][ - x: as-float offset/x - y: as-float offset/y - int: as red-integer! offset + 1 - start: as-float int/value + w: int/value int: int + 1 - stop: as-float int/value + h: int/value - pattern: either type = linear [ - cairo_pattern_create_linear x + start y x + stop y + grad: either brush? [ + dc/brush?: yes + dc/grad-brush ][ - cairo_pattern_create_radial x y start x y stop + dc/pen?: yes + dc/grad-pen ] + unless grad/on? [ + nums: 2 * MAX_COLORS + pc: as int-ptr! allocate nums * size? integer! + grad/colors: pc + grad/colors-pos: as float32-ptr! pc + MAX_COLORS + grad/on?: on + ] + grad/spread: mode + grad/type: type + grad/count: 0 + + case [ + type = linear [ + grad/offset-on?: on + grad/offset/x: offset/x + w + grad/offset/y: offset/y + w + grad/offset2/x: offset/x + h + grad/offset2/y: offset/y + h + ] + type = radial [ + grad/offset-on?: on + grad/offset/x: offset/x + grad/offset/y: offset/y + grad/offset2/x: h ;-- bigger radius + grad/offset2/y: w ;-- smaller radius + ] + true [ + grad/offset-on?: off + ] + ] + grad/focal-on?: off n: 0 rotate?: no @@ -1206,50 +1470,57 @@ OS-draw-grad-pen-old: func [ ] n: n + 1 ] - cairo_matrix_init matrix 1.0 0.0 0.0 1.0 0.0 0.0 - if rotate? [ - p: PI / 180.0 - cairo_matrix_rotate matrix p * angle - ] - if scale? [ - cairo_matrix_scale matrix x y + matrix: as cairo_matrix_t! grad/matrix + cairo_matrix_init_identity matrix + if any [rotate? scale?][ + grad/matrix-on?: on + if rotate? [ + p: PI / 180.0 + p: p * angle + cairo_matrix_rotate matrix 0.0 - p + ] + if scale? [ + x: 1.0 / x + y: 1.0 / y + cairo_matrix_scale matrix x y + ] ] - cairo_matrix_invert matrix - cairo_pattern_set_matrix pattern matrix + color: grad/colors + 1 + pos: grad/colors-pos + 1 delta: as-float count - 1 delta: 1.0 / delta p: 0.0 head: as red-value! int loop count [ clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] + color/value: clr/array1 next: head + 1 - n: clr/array1 - x: as-float n and FFh - x: x / 255.0 - y: as-float n >> 8 and FFh - y: y / 255.0 - start: as-float n >> 16 and FFh - start: start / 255.0 - stop: as-float 255 - (n >>> 24) - stop: stop / 255.0 if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] - cairo_pattern_add_color_stop_rgba pattern p x y start stop - p: p + delta + pos/value: as float32! p + if next <> head [p: p + delta] head: head + 1 + color: color + 1 + pos: pos + 1 ] - either brush? [ - dc/brush?: yes - unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] - dc/grad-brush: pattern - dc/gbrush-resize?: no - ][ - dc/pen?: yes - unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] - dc/grad-pen: pattern - dc/gpen-resize?: no + grad/zero-base?: no + last-p: pos - 1 + last-c: color - 1 + pos: pos - count + color: color - count + if pos/value > as float32! 0.0 [ ;-- first one should be always 0.0 + grad/colors-pos/value: as float32! 0.0 + grad/colors/value: color/value + count: count + 1 + grad/zero-base?: yes ] + if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 + last-c/2: last-c/value + last-p/2: as float32! 1.0 + count: count + 1 + ] + grad/count: count ] OS-draw-grad-pen: func [ @@ -1263,101 +1534,117 @@ OS-draw-grad-pen: func [ spread [integer!] brush? [logic!] /local - resize? [logic!] + grad [gradient!] + nums [integer!] + pc [int-ptr!] point [red-pair!] - x [float!] - y [float!] - pattern [handle!] - delta [float!] p [float!] + delta [float!] head [red-value!] next [red-value!] clr [red-tuple!] - n [integer!] - r [float!] - g [float!] - b [float!] - a [float!] f [red-float!] + matrix [cairo_matrix_t!] + color [int-ptr!] + last-c [int-ptr!] + pos [float32-ptr!] + last-p [float32-ptr!] ][ - resize?: false - pattern: case [ + + grad: either brush? [ + dc/brush?: yes + dc/grad-brush + ][ + dc/pen?: yes + dc/grad-pen + ] + unless grad/on? [ + nums: 2 * MAX_COLORS + pc: as int-ptr! allocate nums * size? integer! + grad/colors: pc + grad/colors-pos: as float32-ptr! pc + MAX_COLORS + grad/on?: on + ] + grad/spread: spread + grad/type: type + grad/count: 0 + + grad/focal-on?: off + case [ type = linear [ either skip-pos? [ - resize?: true - cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + grad/offset-on?: off ][ + grad/offset-on?: on point: as red-pair! positions - x: as float! point/x - y: as float! point/y + grad/offset/x: point/x + grad/offset/y: point/y point: point + 1 - cairo_pattern_create_linear x y as float! point/x as float! point/y + grad/offset2/x: point/x + grad/offset2/y: point/y ] ] - any [ type = radial type = diamond ][ + type = radial [ either skip-pos? [ - resize?: true - cairo_pattern_create_radial 0.0 0.0 0.0 0.0 0.0 1.0 + grad/offset-on?: off ][ - either type = radial [ - point: as red-pair! positions - x: as float! point/x - y: as float! point/y - p: get-float as red-integer! point + 1 - cairo_pattern_create_radial x y 0.0 x y p - ][ - resize?: true - cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + grad/offset-on?: on + point: as red-pair! positions + grad/offset/x: point/x + grad/offset/y: point/y + p: get-float as red-integer! point + 1 + grad/offset2/x: as integer! p + if focal? [ + grad/focal-on?: on + point: point + 2 + grad/focal/x: point/x + grad/focal/y: point/y ] ] ] true [ - resize?: true - cairo_pattern_create_linear 0.0 0.0 1.0 1.0 + grad/offset-on?: off ] ] + matrix: as cairo_matrix_t! grad/matrix + cairo_matrix_init_identity matrix + + color: grad/colors + 1 + pos: grad/colors-pos + 1 delta: as-float count - 1 delta: 1.0 / delta p: 0.0 - head: as red-value! stops + head: stops loop count [ clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] - n: clr/array1 - r: as-float n and FFh - r: r / 255.0 - g: as-float n >> 8 and FFh - g: g / 255.0 - b: as-float n >> 16 and FFh - b: b / 255.0 - a: as-float 255 - (n >>> 24) - a: a / 255.0 + color/value: clr/array1 next: head + 1 if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] - cairo_pattern_add_color_stop_rgba pattern p r g b a - p: p + delta + pos/value: as float32! p + if next <> head [p: p + delta] head: head + 1 + color: color + 1 + pos: pos + 1 ] - cairo_pattern_set_extend pattern - case [ - spread = _pad [CAIRO_EXTEND_PAD] - spread = _repeat [CAIRO_EXTEND_REPEAT] - spread = _reflect [CAIRO_EXTEND_REFLECT] - true [CAIRO_EXTEND_NONE] - ] - - either brush? [ - dc/brush?: yes - unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] - dc/grad-brush: pattern - dc/gbrush-resize?: resize? - ][ - dc/pen?: yes - unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] - dc/grad-pen: pattern - dc/gpen-resize?: resize? + grad/zero-base?: no + last-p: pos - 1 + last-c: color - 1 + pos: pos - count + color: color - count + if pos/value > as float32! 0.0 [ ;-- first one should be always 0.0 + grad/colors-pos/value: as float32! 0.0 + grad/colors/value: color/value + count: count + 1 + grad/zero-base?: yes + ] + if last-p/value < as float32! 1.0 [ ;-- last one should be always 1.0 + last-c/2: last-c/value + last-p/2: as float32! 1.0 + count: count + 1 ] + grad/count: count ] OS-matrix-rotate: func [ @@ -1368,8 +1655,8 @@ OS-matrix-rotate: func [ /local cr [handle!] rad [float!] - pattern [handle!] - matrix [cairo_matrix_t! value] + grad [gradient!] + matrix [cairo_matrix_t!] ][ cr: dc/cr rad: PI / 180.0 * get-float angle @@ -1384,11 +1671,11 @@ OS-matrix-rotate: func [ as float! (0 - center/y) ] ][ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix - cairo_matrix_rotate matrix rad - cairo_pattern_set_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on + cairo_matrix_rotate matrix 0.0 - rad ] ] ] @@ -1399,15 +1686,21 @@ OS-matrix-scale: func [ sx [red-integer!] sy [red-integer!] /local - pattern [handle!] - matrix [cairo_matrix_t! value] + grad [gradient!] + matrix [cairo_matrix_t!] + x [float!] + y [float!] ][ either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix - cairo_matrix_scale matrix get-float sx get-float sy - cairo_pattern_set_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on + x: get-float sx + y: get-float sy + x: 1.0 / x + y: 1.0 / y + cairo_matrix_scale matrix x y ] ][ cairo_scale dc/cr get-float sx get-float sy @@ -1420,15 +1713,15 @@ OS-matrix-translate: func [ x [integer!] y [integer!] /local - pattern [handle!] - matrix [cairo_matrix_t! value] + grad [gradient!] + matrix [cairo_matrix_t!] ][ either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix - cairo_matrix_translate matrix as-float x as-float y - cairo_pattern_set_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on + cairo_matrix_translate matrix 0.0 - as-float x 0.0 - as-float y ] ][ cairo_translate dc/cr as-float x as-float y @@ -1441,9 +1734,9 @@ OS-matrix-skew: func [ sx [red-integer!] sy [red-integer!] /local - pattern [handle!] + grad [gradient!] m [cairo_matrix_t! value] - matrix [cairo_matrix_t! value] + matrix [cairo_matrix_t!] res [cairo_matrix_t! value] ][ m/xx: 1.0 @@ -1453,11 +1746,14 @@ OS-matrix-skew: func [ m/x0: 0.0 m/y0: 0.0 either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on + m/yx: 0.0 - m/yx + m/xy: 0.0 - m/xy cairo_matrix_multiply res matrix m - cairo_pattern_set_matrix pattern res + copy-memory as byte-ptr! matrix as byte-ptr! res size? cairo_matrix_t! ] ][ cairo_transform dc/cr m @@ -1500,15 +1796,15 @@ OS-matrix-reset: func [ dc [draw-ctx!] pen-fill [integer!] /local - pattern [handle!] - matrix [cairo_matrix_t! value] + grad [gradient!] + matrix [cairo_matrix_t!] ][ either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on cairo_matrix_init_identity matrix - cairo_pattern_set_matrix pattern matrix ] ][ cairo_identity_matrix dc/cr @@ -1519,15 +1815,15 @@ OS-matrix-invert: func [ dc [draw-ctx!] pen-fill [integer!] /local - pattern [handle!] - matrix [cairo_matrix_t! value] + grad [gradient!] + matrix [cairo_matrix_t!] ][ either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on cairo_matrix_invert matrix - cairo_pattern_set_matrix pattern matrix ] ][ cairo_get_matrix dc/cr matrix @@ -1541,10 +1837,10 @@ OS-matrix-set: func [ pen-fill [integer!] blk [red-block!] /local - pattern [handle!] + grad [gradient!] m [cairo_matrix_t! value] val [red-integer!] - matrix [cairo_matrix_t! value] + matrix [cairo_matrix_t!] res [cairo_matrix_t! value] ][ m: null @@ -1556,11 +1852,13 @@ OS-matrix-set: func [ m/x0: get-float val + 4 m/y0: get-float val + 5 either pen-fill <> -1 [ - pattern: either pen-fill = pen [dc/grad-pen][dc/grad-brush] - unless null? pattern [ - cairo_pattern_get_matrix pattern matrix + grad: either pen-fill = pen [dc/grad-pen][dc/grad-brush] + if grad/on? [ + matrix: as cairo_matrix_t! grad/matrix + grad/matrix-on?: on + cairo_matrix_invert m cairo_matrix_multiply res matrix m - cairo_pattern_set_matrix pattern res + copy-memory as byte-ptr! matrix as byte-ptr! res size? cairo_matrix_t! ] ][ cairo_transform dc/cr m @@ -1971,31 +2269,19 @@ OS-draw-brush-pattern: func [ wrap = flip-xy [w: w * 2 h: h * 2] true [] ] - cairo_push_group cr - do-draw cr null block no no yes yes - if wrap = flip-x [ - cairo_scale cr -1.0 1.0 - do-draw cr null block no no yes yes - ] - if wrap = flip-y [ - cairo_matrix_init matrix 1.0 0.0 0.0 -1.0 as float! w as float! h - cairo_transform cr matrix - do-draw cr null block no no yes yes - ] - pattern: cairo_pop_group cr + ;cairo_push_group cr + ;do-draw cr null block no no yes yes + ;if wrap = flip-x [ + ; cairo_scale cr -1.0 1.0 + ; do-draw cr null block no no yes yes + ;] + ;if wrap = flip-y [ + ; cairo_matrix_init matrix 1.0 0.0 0.0 -1.0 as float! w as float! h + ; cairo_transform cr matrix + ; do-draw cr null block no no yes yes + ;] + ;pattern: cairo_pop_group cr ;pattern: cairo_pattern_create_mesh ;-- TBD: wrap mode - cairo_pattern_set_extend pattern CAIRO_EXTEND_PAD;CAIRO_EXTEND_REPEAT - - either brush? [ - dc/brush?: yes - unless null? dc/grad-brush [cairo_pattern_destroy dc/grad-brush] - dc/grad-brush: pattern - dc/gbrush-resize?: no - ][ - dc/pen?: yes - unless null? dc/grad-pen [cairo_pattern_destroy dc/grad-pen] - dc/grad-pen: pattern - dc/gpen-resize?: no - ] + ;cairo_pattern_set_extend pattern CAIRO_EXTEND_PAD;CAIRO_EXTEND_REPEAT ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 7b35268c19..8ac77ac58f 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -76,6 +76,40 @@ Red/System [ ] #if OS = 'Linux [ + + tagPOINT: alias struct! [ + x [integer!] + y [integer!] + ] + + tagMATRIX: alias struct! [ + xx [float!] + yx [float!] + xy [float!] + yy [float!] + x0 [float!] + y0 [float!] + ] + + gradient!: alias struct! [ + on? [logic!] + spread [integer!] + type [integer!] ;-- gradient on fly (just before drawing figure) + matrix-on? [logic!] + matrix [tagMATRIX value] + colors [int-ptr!] ;-- always on + colors-pos [float32-ptr!] ;-- always on + count [integer!] ;-- gradient stops count + zero-base? [logic!] + offset-on? [logic!] + offset [tagPOINT value] ;-- figure coordinates + offset2 [tagPOINT value] + focal-on? [logic!] + focal [tagPOINT value] + pattern-on? [logic!] + pattern [int-ptr!] + ] + draw-ctx!: alias struct! [ cr [handle!] pen-join [integer!] @@ -85,12 +119,10 @@ Red/System [ pen-color [integer!] ;-- 00bbggrr format brush-color [integer!] ;-- 00bbggrr format font-color [integer!] + grad-pen [gradient! value] + grad-brush [gradient! value] pen? [logic!] brush? [logic!] - grad-pen [handle!] - gpen-resize? [logic!] - grad-brush [handle!] - gbrush-resize? [logic!] on-image? [logic!] control-x [float32!] control-y [float32!] From 1ce149edd70d3b07d3b29874e031898145b3ea4c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Dec 2019 14:45:00 +0800 Subject: [PATCH 0616/3432] FIX: update grad-pen test --- tests/complexpen-test.red | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/complexpen-test.red b/tests/complexpen-test.red index f0f79d3d9e..10c31d22bf 100644 --- a/tests/complexpen-test.red +++ b/tests/complexpen-test.red @@ -113,13 +113,13 @@ drawings: [ ( as-pair start-x + width start-y + height ) text ( as-pair start-x + (1 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0" - fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 + fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height ) text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x50" - fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 + fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height ) @@ -138,13 +138,13 @@ drawings: [ ( as-pair start-x + width start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0" - fill-pen linear red green blue 0x0 50x0 + fill-pen linear red green blue 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x50" - fill-pen linear red green blue 0x0 50x50 + fill-pen linear red green blue 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) @@ -163,19 +163,19 @@ drawings: [ ( as-pair start-x + width start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; rotate 45" - fill-pen linear red green blue rotate 'fill-pen 45 + fill-pen linear red green blue repeat rotate 'fill-pen 45 box ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; translate 50x0" - fill-pen linear red green blue translate 'fill-pen 50x0 + fill-pen linear red green blue repeat translate 'fill-pen 50x0 box ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; skew 50x50" - fill-pen linear red green blue skew 'fill-pen 50 50 + fill-pen linear red green blue repeat skew 'fill-pen 50 50 box ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) From 0ca9e179cab0b9fcb12493cb049c017328eb2471 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Dec 2019 15:43:15 +0800 Subject: [PATCH 0617/3432] FIX: focal gradient's first circle rudius be fixed to 0.0 --- modules/view/backends/gtk3/draw.reds | 30 ++++++---------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index a0c5d99be3..67032362fe 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -454,13 +454,7 @@ check-grad-brush-lines: func [ x2: x0 + as float! grad/offset/x y2: y0 + as float! grad/offset/y r2: as float! grad/offset2/x - delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y - r1: as float! delta - either r1 >= r2 [ - r1: 0.0 - ][ - r1: r2 - r1 - ] + r1: 0.0 ][ x1: x0 + as float! grad/offset/x y1: y0 + as float! grad/offset/y @@ -516,13 +510,7 @@ check-grad-arc-radial: func [ x2: x0 + as float! grad/offset/x y2: y0 + as float! grad/offset/y r2: as float! grad/offset2/x - delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y - r1: as float! delta - either r1 >= r2 [ - r1: 0.0 - ][ - r1: r2 - r1 - ] + r1: 0.0 ][ x1: x0 + as float! grad/offset/x y1: y0 + as float! grad/offset/y @@ -568,8 +556,8 @@ check-grad-box-radial: func [ unless grad/type = radial [exit] pattern: null - x0: as float! either upper/x < lower/x [upper/x][lower/x] - y0: as float! either upper/y < lower/y [upper/y][lower/y] + x0: either upper/x < lower/x [as float! upper/x][as float! lower/x] + y0: either upper/y < lower/y [as float! upper/y][as float! lower/y] either grad/offset-on? [ either grad/focal-on? [ @@ -578,13 +566,7 @@ check-grad-box-radial: func [ x2: x0 + as float! grad/offset/x y2: y0 + as float! grad/offset/y r2: as float! grad/offset2/x - delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y - r1: as float! delta - either r1 >= r2 [ - r1: 0.0 - ][ - r1: r2 - r1 - ] + r1: 0.0 ][ x1: x0 + as float! grad/offset/x y1: y0 + as float! grad/offset/y @@ -611,7 +593,7 @@ check-grad-box-radial: func [ ][ upper/y - lower/y ] - r2: as float! either w > h [w][h] + r2: either w > h [as float! w][as float! h] r2: r2 / 2.0 ] pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 From 115985ce430ec47cf4a55382d6757b445e211fe1 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Dec 2019 15:55:17 +0800 Subject: [PATCH 0618/3432] FIX: update box's grad-pen tests --- tests/complexpen-test.red | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/complexpen-test.red b/tests/complexpen-test.red index 10c31d22bf..d0c33f274d 100644 --- a/tests/complexpen-test.red +++ b/tests/complexpen-test.red @@ -345,13 +345,13 @@ drawings: [ ( as-pair start-x + width start-y + height ) text ( as-pair start-x + (1 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0" - pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 + pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height ) text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x50" - pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 + pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height ) @@ -370,13 +370,13 @@ drawings: [ ( as-pair start-x + width start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0" - pen linear red green blue 0x0 50x0 + pen linear red green blue 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x50" - pen linear red green blue 0x0 50x50 + pen linear red green blue 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) @@ -395,19 +395,19 @@ drawings: [ ( as-pair start-x + width start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; rotate 45" - pen linear red green blue rotate 'pen 45 + pen linear red green blue repeat rotate 'pen 45 box ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; translate 50x0" - pen linear red green blue translate 'pen 50x0 + pen linear red green blue repeat translate 'pen 50x0 box ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; skew 50x50" - pen linear red green blue skew 'pen 50 50 + pen linear red green blue repeat skew 'pen 50 50 box ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) From d89f33b100c051edcaa94da8694f70567f83cb0e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 14 Dec 2019 10:02:13 +0800 Subject: [PATCH 0619/3432] FIX: transparent layer's boundary check issue --- modules/view/backends/gtk3/handlers.reds | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index a991184301..60705b51d2 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -280,6 +280,7 @@ base-event-after: func [ type [red-word!] color [red-tuple!] offset [red-pair!] + size [red-pair!] parent [red-object!] sym [integer!] hparent [handle!] @@ -311,6 +312,7 @@ base-event-after: func [ type: as red-word! values + FACE_OBJ_TYPE color: as red-tuple! values + FACE_OBJ_COLOR offset: as red-pair! values + FACE_OBJ_OFFSET + size: as red-pair! values + FACE_OBJ_SIZE parent: as red-object! values + FACE_OBJ_PARENT sym: symbol/resolve type/symbol @@ -334,10 +336,10 @@ base-event-after: func [ offset2: as red-pair! (object/get-values tail) + FACE_OBJ_OFFSET size2: as red-pair! (object/get-values tail) + FACE_OBJ_SIZE unless all [ - offset/x >= offset2/x - offset/x <= (offset2/x + size2/x) - offset/y >= offset2/y - offset/y <= (offset2/y + size2/y) + offset/x + size/x > offset2/x + offset2/x + size2/x > offset/x + offset/y + size/y > offset2/y + offset2/y + size2/y > offset/y ][continue] case [ etype = GDK_MOTION_NOTIFY [ From 5b88c25dd75587a15e3e0ffbd490fb14a0c891f7 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 17 Dec 2019 15:44:37 +0800 Subject: [PATCH 0620/3432] FEAT: support draw ellipse --- modules/view/backends/windows/draw.reds | 87 ++++++++++++++++++------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index f8a4c8d910..da338a8287 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -390,32 +390,33 @@ OS-draw-spline: func [ ] do-draw-ellipse: func [ - ctx [draw-ctx!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] -][ - -] - -OS-draw-circle: func [ - ctx [draw-ctx!] - center [red-pair!] - radius [red-integer!] + ctx [draw-ctx!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] /local this [this!] dc [ID2D1DeviceContext] - ellipse [D2D1_ELLIPSE] + cx [float32!] + cy [float32!] + rx [float32!] + ry [float32!] + ellipse [D2D1_ELLIPSE value] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - ellipse: declare D2D1_ELLIPSE - ellipse/x: as float32! center/x - ellipse/y: as float32! center/y - ellipse/radiusX: get-float32 radius - ellipse/radiusY: ellipse/radiusX + cx: as float32! x + cy: as float32! y + rx: as float32! width + ry: as float32! height + rx: rx / as float32! 2.0 + ry: ry / as float32! 2.0 + ellipse/x: cx + rx + ellipse/y: cy + ry + ellipse/radiusX: rx + ellipse/radiusY: ry if ctx/brush? [ dc/FillEllipse this ellipse ctx/brush ] @@ -424,12 +425,52 @@ OS-draw-circle: func [ ] ] +OS-draw-circle: func [ + ctx [draw-ctx!] + center [red-pair!] + radius [red-integer!] + /local + rad-x [integer!] + rad-y [integer!] + w [integer!] + h [integer!] + f [red-float!] +][ + either TYPE_OF(radius) = TYPE_INTEGER [ + either center + 1 = radius [ ;-- center, radius + rad-x: radius/value + rad-y: rad-x + ][ + rad-y: radius/value ;-- center, radius-x, radius-y + radius: radius - 1 + rad-x: radius/value + ] + w: rad-x * 2 + h: rad-y * 2 + ][ + f: as red-float! radius + either center + 1 = radius [ + rad-x: as-integer f/value + 0.75 + rad-y: rad-x + w: as-integer f/value * 2.0 + h: w + ][ + rad-y: as-integer f/value + 0.75 + h: as-integer f/value * 2.0 + f: f - 1 + rad-x: as-integer f/value + 0.75 + w: as-integer f/value * 2.0 + ] + ] + do-draw-ellipse ctx center/x - rad-x center/y - rad-y w h +] + OS-draw-ellipse: func [ - ctx [draw-ctx!] - upper [red-pair!] - diameter [red-pair!] + ctx [draw-ctx!] + upper [red-pair!] + diameter [red-pair!] ][ - + do-draw-ellipse ctx upper/x upper/y diameter/x diameter/y ] OS-draw-font: func [ From 2ec621f95be53512dff4678f9128706fb33ae3e7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Dec 2019 17:18:58 +0100 Subject: [PATCH 0621/3432] FEAT: moves lexer's jump table to a dynamic array. Static arrays of function pointers cannot be made easily relocatable on non-Windows platform, so they are now deprecated until such support is implemented. --- runtime/lexer.reds | 83 +++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 549c1151da..10378a337b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -340,6 +340,7 @@ lexer: context [ scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] + scanners: as int-ptr! 0 ;-- scan functions jump table (dynamically filled) stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number root-state: as state! 0 ;-- global entry point to state struct list @@ -1622,41 +1623,6 @@ lexer: context [ ] ] - scanners: [ - :scan-eof ;-- T_EOF - :scan-error ;-- T_ERROR - :scan-block-open ;-- T_BLK_OP - :scan-block-close ;-- T_BLK_CL - :scan-block-open ;-- T_PAR_OP - :scan-paren-close ;-- T_PAR_CL - :scan-string ;-- T_STRING - :scan-mstring-open ;-- T_MSTR_OP (multiline string) - :scan-mstring-close ;-- T_MSTR_CL (multiline string) - :scan-word ;-- T_WORD - :scan-file ;-- T_FILE - :scan-ref-issue ;-- T_REFINE - :scan-binary ;-- T_BINARY - :scan-char ;-- T_CHAR - :scan-map-open ;-- T_MAP_OP - :scan-construct ;-- T_CONS_MK - :scan-ref-issue ;-- T_ISSUE - :scan-percent ;-- T_PERCENT - :scan-integer ;-- T_INTEGER - :scan-float ;-- T_FLOAT - :scan-float-special ;-- T_FLOAT_SP - :scan-tuple ;-- T_TUPLE - :scan-date ;-- T_DATE - :scan-pair ;-- T_PAIR - :scan-time ;-- T_TIME - :scan-money ;-- T_MONEY - :scan-tag ;-- T_TAG - :scan-url ;-- T_URL - :scan-email ;-- T_EMAIL - :scan-path-open ;-- T_PATH - :scan-hex ;-- T_HEX - :scan-comment ;-- T_CMT - ] - scan-tokens: func [ lex [state!] one? [logic!] @@ -1762,6 +1728,18 @@ lexer: context [ if zero? depth [root-state: null] ] + set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][ + scanners: as int-ptr! allocate count * size? int-ptr! + s: scanners + until [ + s/value: list/value + list: list + 1 + count: count - 1 + s: s + 1 + zero? count + ] + ] + init: func [][ stash: as cell! allocate stash-size * size? cell! @@ -1770,6 +1748,41 @@ lexer: context [ transitions: transitions + 1 skip-table: skip-table + 1 line-table: line-table + 1 + + set-jump-table [ + :scan-eof ;-- T_EOF + :scan-error ;-- T_ERROR + :scan-block-open ;-- T_BLK_OP + :scan-block-close ;-- T_BLK_CL + :scan-block-open ;-- T_PAR_OP + :scan-paren-close ;-- T_PAR_CL + :scan-string ;-- T_STRING + :scan-mstring-open ;-- T_MSTR_OP (multiline string) + :scan-mstring-close ;-- T_MSTR_CL (multiline string) + :scan-word ;-- T_WORD + :scan-file ;-- T_FILE + :scan-ref-issue ;-- T_REFINE + :scan-binary ;-- T_BINARY + :scan-char ;-- T_CHAR + :scan-map-open ;-- T_MAP_OP + :scan-construct ;-- T_CONS_MK + :scan-ref-issue ;-- T_ISSUE + :scan-percent ;-- T_PERCENT + :scan-integer ;-- T_INTEGER + :scan-float ;-- T_FLOAT + :scan-float-special ;-- T_FLOAT_SP + :scan-tuple ;-- T_TUPLE + :scan-date ;-- T_DATE + :scan-pair ;-- T_PAIR + :scan-time ;-- T_TIME + :scan-money ;-- T_MONEY + :scan-tag ;-- T_TAG + :scan-url ;-- T_URL + :scan-email ;-- T_EMAIL + :scan-path-open ;-- T_PATH + :scan-hex ;-- T_HEX + :scan-comment ;-- T_CMT + ] ] ] \ No newline at end of file From 1dd0650eb7cdf64a2b3665f56f17c9ac7b6aaa55 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Dec 2019 19:39:15 +0100 Subject: [PATCH 0622/3432] FEAT: remembers previous lexer state before a T_ERROR, for more accurate reporting. --- runtime/lexer-transitions.reds | 7 +- runtime/lexer.reds | 18 ++- runtime/macros.reds | 4 +- utils/generate-lexer-table.red | 196 ++++++++++++++++++--------------- 4 files changed, 127 insertions(+), 98 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 27d5bd77a4..604dd7e05f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -89,7 +89,12 @@ Red/System [ T_PATH T_HEX T_CMT - ] transitions: #{ + ] + prev-table: #{ +0000070707070808080808191429000A0A00140B0C0C0C0C272F2B2B25253333 +330B2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F +} + transitions: #{ 00001313393A3B3C3E38020C2B2B2C2C2C2C212C210B38222C2C06380138291E 2828382C2C383701560101010101010101010101010101010101010101010101 0101010101010101010101013837020202020202020202023D02020202020202 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 10378a337b..8c3d49ef13 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -331,6 +331,7 @@ lexer: context [ nline [integer!] ;-- new lines count for new token type [integer!] ;-- sub-type in a typeclass entry [integer!] ;-- entry state for the FSM + prev [integer!] ;-- previous state before forced EOF transition exit [integer!] ;-- exit state for the FSM closing [integer!] ;-- any-block! expected closing delimiter type mstr-s [byte-ptr!] ;-- multiline string saved start position @@ -789,8 +790,13 @@ lexer: context [ scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][] - scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - throw-error lex s e ERR_BAD_CHAR + scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ + either lex/prev < --EXIT_STATES-- [ + index: lex/prev + 1 + throw-error lex s e as-integer prev-table/index + ][ + throw-error lex s e ERR_BAD_CHAR + ] ] scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -1627,7 +1633,7 @@ lexer: context [ lex [state!] one? [logic!] /local - cp class index state flags line mark offset [integer!] + cp class index state prev flags line mark offset [integer!] slot [red-value!] p e start [byte-ptr!] s [series!] @@ -1639,6 +1645,7 @@ lexer: context [ flags: 0 term?: no state: lex/entry + prev: state p: lex/in-pos start: p mark: line @@ -1648,16 +1655,16 @@ lexer: context [ cp: as-integer p/value flags: lex-classes/cp and FFFFFF00h or flags class: lex-classes/cp and FFh - index: state * (size? character-classes!) + class + prev: state state: as-integer transitions/index - offset: offset + as-integer skip-table/state if state > --EXIT_STATES-- [term?: yes break] line: line + as-integer line-table/class p: p + 1 ] unless term? [ + prev: state index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index ] @@ -1668,6 +1675,7 @@ lexer: context [ lex/line: line lex/nline: line - mark lex/exit: state + lex/prev: prev lex/type: -1 index: state - --EXIT_STATES-- diff --git a/runtime/macros.reds b/runtime/macros.reds index f9a5b01bd5..7ce9a7d033 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -61,7 +61,9 @@ Red/System [ TYPE_DATE ;-- 2F 47 TYPE_PORT ;-- 30 48 TYPE_IMAGE ;-- 31 49 ;-- needs to be last - TYPE_EVENT + TYPE_EVENT + + TYPE_MONEY TYPE_CLOSURE TYPE_SLICE TYPE_TOTAL_COUNT ;-- keep tabs on number of datatypes. diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 512548c973..f7d37c2f63 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -12,93 +12,94 @@ Red [ context [ states: [ - S_START ;-- 0 - S_LINE_CMT ;-- 1 - S_LINE_STR ;-- 2 - S_SKIP_STR ;-- 3 - S_M_STRING ;-- 4 - S_SKIP_MSTR ;-- 5 - S_FILE_1ST ;-- 6 - S_FILE ;-- 7 - S_FILE_HEX1 ;-- 8 - S_FILE_HEX2 ;-- 9 - S_FILE_STR ;-- 10 - S_SLASH ;-- 11 - S_SHARP ;-- 12 - S_BINARY ;-- 13 - S_LINE_CMT2 ;-- 14 - S_CHAR ;-- 15 - S_SKIP_CHAR ;-- 16 - S_CONSTRUCT ;-- 17 - S_ISSUE ;-- 18 - S_NUMBER ;-- 19 - S_DOTNUM ;-- 20 - S_DECIMAL ;-- 21 - S_DECX ;-- 22 - S_DEC_SPECIAL ;-- 23 - S_TUPLE ;-- 24 - S_DATE ;-- 25 - S_TIME_1ST ;-- 26 - S_TIME ;-- 27 - S_PAIR_1ST ;-- 28 - S_PAIR ;-- 29 - S_MONEY_1ST ;-- 30 - S_MONEY ;-- 31 - S_MONEY_DEC ;-- 32 - S_HEX ;-- 33 - S_LESSER ;-- 34 - S_TAG ;-- 35 - S_TAG_STR ;-- 36 - S_SKIP_STR2 ;-- 37 - S_TAG_STR2 ;-- 38 - S_SKIP_STR3 ;-- 39 - S_SIGN ;-- 40 - S_DOTWORD ;-- 41 - S_DOTDEC ;-- 42 - S_WORD_1ST ;-- 43 - S_WORD ;-- 44 - S_WORDSET ;-- 45 - S_URL ;-- 46 - S_EMAIL ;-- 47 - S_PATH ;-- 48 - S_PATH_NUM ;-- 49 - S_PATH_W1ST ;-- 50 - S_PATH_WORD ;-- 51 - S_PATH_SHARP ;-- 52 - S_PATH_SIGN ;-- 53 - --EXIT_STATES-- ;-- 54 - T_EOF ;-- 55 - T_ERROR ;-- 56 - T_BLK_OP ;-- 57 - T_BLK_CL ;-- 58 - T_PAR_OP ;-- 59 - T_PAR_CL ;-- 60 - T_STRING ;-- 61 - T_MSTR_OP ;-- 62 - T_MSTR_CL ;-- 63 - T_WORD ;-- 64 - T_FILE ;-- 65 - T_REFINE ;-- 66 - T_BINARY ;-- 67 - T_CHAR ;-- 68 - T_MAP_OP ;-- 69 - T_CONS_MK ;-- 70 - T_ISSUE ;-- 71 - T_PERCENT ;-- 72 - T_INTEGER ;-- 73 - T_FLOAT ;-- 74 - T_FLOAT_SP ;-- 75 - T_TUPLE ;-- 76 - T_DATE ;-- 77 - T_PAIR ;-- 78 - T_TIME ;-- 79 - T_MONEY ;-- 80 - T_TAG ;-- 81 - T_URL ;-- 82 - T_EMAIL ;-- 83 - T_PATH ;-- 84 - T_HEX ;-- 85 - T_CMT ;-- 86 + ;-- State ------------- Predicted type ---- + S_START TYPE_VALUE ;-- 0 + S_LINE_CMT TYPE_VALUE ;-- 1 + S_LINE_STR TYPE_STRING ;-- 2 + S_SKIP_STR TYPE_STRING ;-- 3 + S_M_STRING TYPE_STRING ;-- 4 + S_SKIP_MSTR TYPE_STRING ;-- 5 + S_FILE_1ST TYPE_FILE ;-- 6 + S_FILE TYPE_FILE ;-- 7 + S_FILE_HEX1 TYPE_FILE ;-- 8 + S_FILE_HEX2 TYPE_FILE ;-- 9 + S_FILE_STR TYPE_FILE ;-- 10 + S_SLASH TYPE_PATH ;-- 11 + S_SHARP TYPE_ISSUE ;-- 12 + S_BINARY TYPE_BINARY ;-- 13 + S_LINE_CMT2 TYPE_VALUE ;-- 14 + S_CHAR TYPE_CHAR ;-- 15 + S_SKIP_CHAR TYPE_CHAR ;-- 16 + S_CONSTRUCT TYPE_VALUE ;-- 17 + S_ISSUE TYPE_ISSUE ;-- 18 + S_NUMBER TYPE_INTEGER ;-- 19 + S_DOTNUM TYPE_FLOAT ;-- 20 + S_DECIMAL TYPE_FLOAT ;-- 21 + S_DECX TYPE_FLOAT ;-- 22 + S_DEC_SPECIAL TYPE_FLOAT ;-- 23 + S_TUPLE TYPE_TUPLE ;-- 24 + S_DATE TYPE_DATE ;-- 25 + S_TIME_1ST TYPE_TIME ;-- 26 + S_TIME TYPE_TIME ;-- 27 + S_PAIR_1ST TYPE_PAIR ;-- 28 + S_PAIR TYPE_PAIR ;-- 29 + S_MONEY_1ST TYPE_MONEY ;-- 30 + S_MONEY TYPE_MONEY ;-- 31 + S_MONEY_DEC TYPE_MONEY ;-- 32 + S_HEX TYPE_INTEGER ;-- 33 + S_LESSER TYPE_TAG ;-- 34 + S_TAG TYPE_TAG ;-- 35 + S_TAG_STR TYPE_TAG ;-- 36 + S_SKIP_STR2 TYPE_TAG ;-- 37 + S_TAG_STR2 TYPE_TAG ;-- 38 + S_SKIP_STR3 TYPE_TAG ;-- 39 + S_SIGN TYPE_WORD ;-- 40 + S_DOTWORD TYPE_WORD ;-- 41 + S_DOTDEC TYPE_FLOAT ;-- 42 + S_WORD_1ST TYPE_WORD ;-- 43 + S_WORD TYPE_WORD ;-- 44 + S_WORDSET TYPE_SET_WORD ;-- 45 + S_URL TYPE_URL ;-- 46 + S_EMAIL TYPE_EMAIL ;-- 47 + S_PATH TYPE_PATH ;-- 48 + S_PATH_NUM TYPE_INTEGER ;-- 49 + S_PATH_W1ST TYPE_WORD ;-- 50 + S_PATH_WORD TYPE_WORD ;-- 51 + S_PATH_SHARP TYPE_ISSUE ;-- 52 + S_PATH_SIGN TYPE_WORD ;-- 53 + --EXIT_STATES-- - ;-- 54 + T_EOF - ;-- 55 + T_ERROR - ;-- 56 + T_BLK_OP - ;-- 57 + T_BLK_CL - ;-- 58 + T_PAR_OP - ;-- 59 + T_PAR_CL - ;-- 60 + T_STRING - ;-- 61 + T_MSTR_OP - ;-- 62 + T_MSTR_CL - ;-- 63 + T_WORD - ;-- 64 + T_FILE - ;-- 65 + T_REFINE - ;-- 66 + T_BINARY - ;-- 67 + T_CHAR - ;-- 68 + T_MAP_OP - ;-- 69 + T_CONS_MK - ;-- 70 + T_ISSUE - ;-- 71 + T_PERCENT - ;-- 72 + T_INTEGER - ;-- 73 + T_FLOAT - ;-- 74 + T_FLOAT_SP - ;-- 75 + T_TUPLE - ;-- 76 + T_DATE - ;-- 77 + T_PAIR - ;-- 78 + T_TIME - ;-- 79 + T_MONEY - ;-- 80 + T_TAG - ;-- 81 + T_URL - ;-- 82 + T_EMAIL - ;-- 83 + T_PATH - ;-- 84 + T_HEX - ;-- 85 + T_CMT - ;-- 86 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -118,22 +119,35 @@ context [ foreach line next matrix [ out: make block! 50 - foreach s next line [ - either pos: find states to-word s [ - append out (index? pos) - 1 + foreach s next line [ + either pos: find/skip states to-word s 2[ + append out (index? pos) + 1 / 2 - 1 ][ do make error! form reduce ["Error: state" s "not found"] ] ] append/only table out ] + + ;-- Generate the prev-table content + prev-table: make binary! 2000 + types: load %../runtime/macros.reds + types: select types 'datatypes! + + foreach [s t] states [ + if s = '--EXIT_STATES-- [break] + append prev-table (index? find types t) - 1 + ] + template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" ] #enum lex-states! [ - (states) + (extract states 2) ] + + prev-table: (prev-table) transitions: (table) ] From 9ecb35923012218d2ef56522a694576f7c7660ad Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Dec 2019 19:40:15 +0100 Subject: [PATCH 0623/3432] TESTS: updates test #1136 for new lexer. --- tests/source/units/regression-test-red.red | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 11772510c1..87e637296f 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -1415,10 +1415,10 @@ Red [ --test-- "#1136" e1136: try [load {a: func [][set 'b: 1]}] - --assert not not all [ + --assert to logic! all [ equal? e1136/type 'syntax equal? e1136/id 'invalid - equal? e1136/arg1 lit-word! + equal? e1136/arg2 lit-word! ] comment { probe should be mocked for this test From d3d8eafd73ce468f79e4eff5ace5eade4669b8b1 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 18 Dec 2019 16:27:24 +0800 Subject: [PATCH 0624/3432] FEAT: support draw triangle --- modules/view/backends/windows/direct2d.reds | 77 ++++++++++++++++++++- modules/view/backends/windows/draw.reds | 47 ++++++++++++- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 58d90b06df..62641306b8 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -60,6 +60,35 @@ RECT32!: alias struct! [ bottom [float32!] ] +D2D1_SIZE_F: alias struct! [ + width [float32!] + height [float32!] +] + +D2D_POINT_2F: alias struct! [ + x [float32!] + y [float32!] +] + +D2D1_BEZIER_SEGMENT: alias struct! [ + point1 [D2D_POINT_2F value] + point2 [D2D_POINT_2F value] + point3 [D2D_POINT_2F value] +] + +D2D1_QUADRATIC_BEZIER_SEGMENT: alias struct! [ + point1 [D2D_POINT_2F value] + point2 [D2D_POINT_2F value] +] + +D2D1_ARC_SEGMENT: alias struct! [ + point [D2D_POINT_2F value] + size [D2D1_SIZE_F value] + angle [float32!] + direction [integer!] + arcSize [integer!] +] + D2D_MATRIX_3X2_F: alias struct! [ _11 [float32!] _12 [float32!] @@ -436,7 +465,7 @@ ID2D1Factory: alias struct! [ CreateEllipseGeometry [integer!] CreateGeometryGroup [integer!] CreateTransformedGeometry [integer!] - CreatePathGeometry [integer!] + CreatePathGeometry [function! [this [this!] pathGeometry [ptr-ptr!] return: [integer!]]] CreateStrokeStyle [integer!] CreateDrawingStateBlock [integer!] CreateWicBitmapRenderTarget [integer!] @@ -556,8 +585,8 @@ ID2D1DeviceContext: alias struct! [ FillRoundedRectangle [integer!] DrawEllipse [DrawEllipse*] FillEllipse [FillEllipse*] - DrawGeometry [integer!] - FillGeometry [integer!] + DrawGeometry [function! [this [this!] geometry [int-ptr!] brush [integer!] strokeWidth [float32!] style [integer!] return: [integer!]]] + FillGeometry [function! [this [this!] geometry [int-ptr!] brush [integer!] opacityBrush [integer!] return: [integer!]]] FillMesh [integer!] FillOpacityMask [integer!] DrawBitmap [integer!] @@ -752,6 +781,48 @@ ID2D1DCRenderTarget: alias struct! [ BindDC [function! [this [this!] hDC [handle!] rect [RECT_STRUCT] return: [integer!]]] ] +ID2D1PathGeometry: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetFactory [integer!] + GetBounds [integer!] + GetWidenedBounds [integer!] + StrokeContainsPoint [integer!] + FillContainsPoint [integer!] + CompareWithGeometry [integer!] + Simplify [integer!] + Tessellate [integer!] + CombineWithGeometry [integer!] + Outline [integer!] + ComputeArea [integer!] + ComputeLength [integer!] + ComputePointAtLength [integer!] + Widen [integer!] + Open [function! [this [this!] sink [ptr-ptr!] return: [integer!]]] + Stream [function! [this [this!] sink [ptr-ptr!] return: [integer!]]] + GetSegmentCount [function! [this [this!] count [int-ptr!] return: [integer!]]] + GetFigureCount [function! [this [this!] count [int-ptr!] return: [integer!]]] +] + +ID2D1GeometrySink: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + SetFillMode [function! [this [this!] fill_mode [integer!] return: [integer!]]] + SetSegmentFlags [function! [this [this!] vertexFlags [integer!] return: [integer!]]] + BeginFigure [function! [this [this!] startPoint [D2D_POINT_2F value] figureBegin [integer!] return: [integer!]]] + AddLines [function! [this [this!] points [D2D_POINT_2F] pointsCount [integer!] return: [integer!]]] + AddBeziers [function! [this [this!] beziers [D2D1_BEZIER_SEGMENT] beziersCount [integer!] return: [integer!]]] + EndFigure [function! [this [this!] figureEnd [integer!] return: [integer!]]] + Close [function! [this [this!] return: [integer!]]] + AddLine [function! [this [this!] point [D2D_POINT_2F value] return: [integer!]]] + AddBezier [function! [this [this!] beziers [D2D1_BEZIER_SEGMENT] return: [integer!]]] + AddQuadraticBezier [function! [this [this!] bezier [D2D1_QUADRATIC_BEZIER_SEGMENT] return: [integer!]]] + AddQuadraticBeziers [function! [this [this!] beziers [D2D1_QUADRATIC_BEZIER_SEGMENT] beziersCount [integer!] return: [integer!]]] + AddArc [function! [this [this!] arc [D2D1_ARC_SEGMENT] return: [integer!]]] +] + ;-- Direct Write DWRITE_LINE_METRICS: alias struct! [ diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index da338a8287..31ed08e0e4 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -44,6 +44,7 @@ draw-begin: func [ ][ zero-memory as byte-ptr! ctx size? draw-ctx! ctx/pen-width: as float32! 1.0 + ctx/pen-style: 0 ctx/pen?: yes ctx/hwnd: hWnd ctx/font-color: -1 @@ -366,10 +367,52 @@ OS-draw-box: func [ ] OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon - ctx [draw-ctx!] - start [red-pair!] + ctx [draw-ctx!] + start [red-pair!] + /local + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + point [D2D_POINT_2F value] + this [this!] + dc [ID2D1DeviceContext] ][ + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + + point/x: as float32! start/x + point/y: as float32! start/y + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + loop 2 [ + start: start + 1 + point/x: as float32! start/x + point/y: as float32! start/y + gsink/AddLine sthis point + ] + gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED + + hr: gsink/Close sthis + gsink/Release sthis + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis ] OS-draw-polygon: func [ From 690c632ec5f74ce2c4b4b01b124c18d95d89c7a8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 18 Dec 2019 16:38:23 +0800 Subject: [PATCH 0625/3432] FEAT: support draw polygon --- modules/view/backends/windows/draw.reds | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 31ed08e0e4..4d6c29fce4 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -369,6 +369,14 @@ OS-draw-box: func [ OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon ctx [draw-ctx!] start [red-pair!] +][ + OS-draw-polygon ctx start start + 2 +] + +OS-draw-polygon: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] /local d2d [ID2D1Factory] path [ptr-value!] @@ -393,11 +401,12 @@ OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon point/x: as float32! start/x point/y: as float32! start/y gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW - loop 2 [ - start: start + 1 + start: start + 1 + while [start <= end] [ point/x: as float32! start/x point/y: as float32! start/y gsink/AddLine sthis point + start: start + 1 ] gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED @@ -415,14 +424,6 @@ OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon gpath/Release pthis ] -OS-draw-polygon: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] -][ - -] - OS-draw-spline: func [ ctx [draw-ctx!] start [red-pair!] From cd869fb027cc6591faa52713d0b052bc772ba298 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 18 Dec 2019 16:33:38 +0100 Subject: [PATCH 0626/3432] FIX: various fixes in lexer for passing unit tests. --- runtime/lexer.reds | 16 +++++++++++----- tests/source/units/regression-test-red.red | 21 ++++++++++++--------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8c3d49ef13..5bceb287e0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -327,6 +327,7 @@ lexer: context [ input [byte-ptr!] in-end [byte-ptr!] in-pos [byte-ptr!] + in-path [byte-ptr!] ;-- records beginning of scanned path line [integer!] ;-- current line number nline [integer!] ;-- new lines count for new token type [integer!] ;-- sub-type in a typeclass @@ -612,6 +613,7 @@ lexer: context [ ][if val = 80h [return s]] s: s + 1 ] + if flip <> 0 [return s] ser/tail: as red-value! p null ] @@ -793,7 +795,9 @@ lexer: context [ scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ either lex/prev < --EXIT_STATES-- [ index: lex/prev + 1 - throw-error lex s e as-integer prev-table/index + index: as-integer prev-table/index + if zero? index [index: ERR_BAD_CHAR] ;-- fallback when no specific type detected + throw-error lex s e index ][ throw-error lex s e ERR_BAD_CHAR ] @@ -1561,6 +1565,7 @@ lexer: context [ /local type [integer!] ][ + lex/in-path: s type: switch s/1 [ #"'" [s: s + 1 flags: flags and not C_FLAG_QUOTE TYPE_LIT_PATH] #":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH] @@ -1615,16 +1620,16 @@ lexer: context [ either close? [ type: either all [e < lex/in-end e/1 = #":"][ if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence - throw-error lex s e TYPE_PATH + throw-error lex lex/in-path e TYPE_PATH ] lex/in-pos: e + 1 ;-- skip : TYPE_SET_PATH ][-1] close-block lex s e -1 type + lex/in-path: null ][ - if all [e < lex/in-end e/1 = #":"][ - throw-error lex s e TYPE_PATH ;-- set-words not allowed inside paths - ] + if e + 1 = lex/in-end [throw-error lex lex/in-path e TYPE_PATH] ;-- incomplete path error + if e/1 = #":" [throw-error lex lex/in-path e TYPE_PATH] ;-- set-words not allowed inside paths lex/in-pos: e + 1 ;-- skip / ] ] @@ -1718,6 +1723,7 @@ lexer: context [ lex/input: src lex/in-end: src + len lex/in-pos: src + lex/in-path: null lex/entry: S_START lex/type: -1 lex/mstr-nest: 0 diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index 87e637296f..dd839b6dcc 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -1619,12 +1619,12 @@ Red [ e1396: try [load {(5+2)}] --assert all [ equal? e1396/id 'invalid - equal? e1396/arg1 integer! + equal? e1396/arg2 integer! ] e1396: try [load {[5+2]}] --assert all [ equal? e1396/id 'invalid - equal? e1396/arg1 integer! + equal? e1396/arg2 integer! ] --test-- "#1416" @@ -1987,22 +1987,25 @@ Red [ --test-- "#1750" e1750: try [load "2#{FF}"] - --assert all [ + --assert to-logic all [ + error? :e1750 equal? e1750/type 'syntax equal? e1750/id 'invalid - equal? e1750/arg1 binary! + equal? e1750/arg2 binary! ] e1750: try [load "64#{AA}"] - --assert all [ + --assert to-logic all [ + error? :e1750 equal? e1750/type 'syntax equal? e1750/id 'invalid - equal? e1750/arg1 binary! + equal? e1750/arg2 binary! ] e1750: try [load "4#{0}"] - --assert all [ + --assert to-logic all [ + error? :e1750 equal? e1750/type 'syntax equal? e1750/id 'invalid - equal? e1750/arg1 integer! + equal? e1750/arg2 binary! ] not error? try [load "16#{AA}"] unset 'e1750 @@ -2717,7 +2720,7 @@ b} --test-- "#2195" e2195: try [load "system/options/"] - --assert equal? "system/options/" e2195/arg2 + --assert equal? "system/options/" e2195/arg3 unset 'e2195 --test-- "#2196" From 42a8f41e5c3706db2344a1e1dbc7afd29101901d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 18 Dec 2019 17:10:56 +0100 Subject: [PATCH 0627/3432] FIX: issue #4145 (Regression: `take` and `random` won't work in debug console) --- runtime/datatypes/block.reds | 2 -- runtime/datatypes/series.reds | 2 +- runtime/datatypes/string.reds | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 2513bc4d3d..b13404d02c 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1511,7 +1511,6 @@ block: context [ blk: as red-block! _series/take blk part-arg deep? last? s: GET_BUFFER(blk) - ownership/check as red-value! blk words/_take null blk/head 1 if deep? [ slot: s/offset until [ @@ -1535,7 +1534,6 @@ block: context [ ][ copy-cell as cell! s/offset as cell! blk ] - ownership/check as red-value! blk words/_taken null blk/head 0 as red-value! blk ] diff --git a/runtime/datatypes/series.reds b/runtime/datatypes/series.reds index cc08603e3b..ffc4c5aa57 100644 --- a/runtime/datatypes/series.reds +++ b/runtime/datatypes/series.reds @@ -157,8 +157,8 @@ _series: context [ head: head + unit size: size - 1 ] + ownership/check as red-value! ser words/_random null ser/head len ] - ownership/check as red-value! ser words/_random null ser/head len ] as red-value! ser ] diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 1051e97d92..83047e5998 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -2578,7 +2578,6 @@ string: context [ not OPTION?(part-arg) 1 = _series/get-length as red-series! str yes ][ - ownership/check as red-value! str words/_take null str/head 1 unit: GET_UNIT(s) type: TYPE_OF(str) either type = TYPE_VECTOR [ @@ -2590,7 +2589,6 @@ string: context [ char/header: type char/value: get-char as byte-ptr! s/offset unit ] - ownership/check as red-value! str words/_taken null str/head 0 ] as red-value! str ] From 652b4ba87ecd59c53d39a8017651277fc8c35272 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 18 Dec 2019 17:12:17 +0100 Subject: [PATCH 0628/3432] FEAT: asserts that lex/in-path is defined before using it. --- runtime/lexer.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5bceb287e0..2dd2dccd7a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1617,6 +1617,8 @@ lexer: context [ index: lex-classes/cp and FFh + 1 ;-- query the class of ending character as-logic path-ending/index ;-- lookup if the character class is ending path ] + assert lex/in-path <> null + either close? [ type: either all [e < lex/in-end e/1 = #":"][ if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence From 01cbaa134e24a25daf14073f638a8644f31dc20a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 18 Dec 2019 22:32:36 +0100 Subject: [PATCH 0629/3432] FIX: missing flag resetting in lexer's error handler. Was causing the GC to crash instantly. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 2dd2dccd7a..91870aa29c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -374,6 +374,7 @@ lexer: context [ lex/tail: lex/buffer ;-- clear accumulated values depth: depth - 1 + if zero? depth [root-state: null] switch type [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] From ce6372bf3f3e0b87f91e714da963c2206dd77dbb Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 19 Dec 2019 11:09:03 +0800 Subject: [PATCH 0630/3432] FEAT: support draw spline --- modules/view/backends/windows/draw.reds | 139 +++++++++++++++++++++++- 1 file changed, 133 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 4d6c29fce4..b411c4dfa7 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -400,7 +400,7 @@ OS-draw-polygon: func [ point/x: as float32! start/x point/y: as float32! start/y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW start: start + 1 while [start <= end] [ point/x: as float32! start/x @@ -408,7 +408,7 @@ OS-draw-polygon: func [ gsink/AddLine sthis point start: start + 1 ] - gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED + gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED hr: gsink/Close sthis gsink/Release sthis @@ -424,13 +424,140 @@ OS-draw-polygon: func [ gpath/Release pthis ] +spline-delta: 1.0 / 25.0 + +do-spline-step: func [ + sthis [this!] + p0 [red-pair!] + p1 [red-pair!] + p2 [red-pair!] + p3 [red-pair!] + /local + gsink [ID2D1GeometrySink] + t [float!] + t2 [float!] + t3 [float!] + x [float!] + y [float!] + point [D2D_POINT_2F value] +][ + gsink: as ID2D1GeometrySink sthis/vtbl + t: 0.0 + loop 25 [ + t: t + spline-delta + t2: t * t + t3: t2 * t + + x: + 2.0 * (as-float p1/x) + ((as-float p2/x) - (as-float p0/x) * t) + + ((2.0 * (as-float p0/x) - (5.0 * (as-float p1/x)) + (4.0 * (as-float p2/x)) - (as-float p3/x)) * t2) + + (3.0 * ((as-float p1/x) - (as-float p2/x)) + (as-float p3/x) - (as-float p0/x) * t3) * 0.5 + y: + 2.0 * (as-float p1/y) + ((as-float p2/y) - (as-float p0/y) * t) + + ((2.0 * (as-float p0/y) - (5.0 * (as-float p1/y)) + (4.0 * (as-float p2/y)) - (as-float p3/y)) * t2) + + (3.0 * ((as-float p1/y) - (as-float p2/y)) + (as-float p3/y) - (as-float p0/y) * t3) * 0.5 + point/x: as float32! x + point/y: as float32! y + gsink/AddLine sthis point + ] +] + OS-draw-spline: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - closed? [logic!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + closed? [logic!] + /local + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + point [D2D_POINT_2F value] + this [this!] + dc [ID2D1DeviceContext] + pt [red-pair!] + stop [red-pair!] ][ + if (as-integer end - start) >> 4 = 1 [ ;-- two points input + OS-draw-line ctx start end ;-- draw a line + exit + ] + + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + point/x: as float32! start/x + point/y: as float32! start/y + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + + either closed? [ + do-spline-step sthis + end + start + start + 1 + start + 2 + ][ + do-spline-step sthis + start + start + start + 1 + start + 2 + ] + + pt: start + stop: end - 3 + + while [pt <= stop] [ + do-spline-step sthis + pt + pt + 1 + pt + 2 + pt + 3 + pt: pt + 1 + ] + + either closed? [ + do-spline-step sthis + end - 2 + end - 1 + end + start + do-spline-step sthis + end - 1 + end + start + start + 1 + gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED + ][ + do-spline-step sthis + end - 2 + end - 1 + end + end + gsink/EndFigure sthis 0 ;-- D2D1_FIGURE_END_OPEN + ] + + hr: gsink/Close sthis + gsink/Release sthis + + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis ] do-draw-ellipse: func [ From 179b050c9e49cb1b7f0cace60f4c6df4e37f2b97 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 19 Dec 2019 15:25:59 +0800 Subject: [PATCH 0631/3432] FEAT: support draw arc --- modules/view/backends/windows/draw.reds | 94 +++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index b411c4dfa7..75c008d7f4 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -652,11 +652,97 @@ OS-draw-font: func [ ] OS-draw-arc: func [ - ctx [draw-ctx!] - center [red-pair!] - end [red-value!] -][ + ctx [draw-ctx!] + center [red-pair!] + end [red-value!] + /local + cx [float32!] + cy [float32!] + rad [float32!] + radius [red-pair!] + rad-x [float32!] + rad-y [float32!] + begin [red-integer!] + angle-begin [float32!] + angle [red-integer!] + sweep [integer!] + i [integer!] + angle-end [float32!] + start-x [float32!] + start-y [float32!] + end-x [float32!] + end-y [float32!] + closed? [logic!] + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + point [D2D_POINT_2F value] + this [this!] + dc [ID2D1DeviceContext] + arc [D2D1_ARC_SEGMENT value] +][ + cx: as float32! center/x + cy: as float32! center/y + rad: (as float32! PI) / as float32! 180.0 + + radius: center + 1 + rad-x: as float32! radius/x + rad-y: as float32! radius/y + begin: as red-integer! radius + 1 + angle-begin: rad * as float32! begin/value + angle: begin + 1 + sweep: angle/value + i: begin/value + sweep + angle-end: rad * as float32! i + start-x: as float32! cos as float! angle-begin + start-x: cx + (rad-x * start-x) + start-y: as float32! sin as float! angle-begin + start-y: cx + (rad-y * start-y) + end-x: as float32! cos as float! angle-end + end-x: cx + (rad-x * end-x) + end-y: as float32! sin as float! angle-end + end-y: cx + (rad-y * end-y) + + closed?: angle < end + + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + + point/x: start-x + point/y: start-y + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + arc/point/x: end-x + arc/point/y: end-y + arc/size/width: rad-x + arc/size/height: rad-y + arc/angle: as float32! 0.0 + arc/direction: 1 ;-- D2D1_SWEEP_DIRECTION_CLOCKWISE + arc/arcSize: either sweep >= 180 [1][0] + hr: gsink/AddArc sthis arc + gsink/EndFigure sthis either closed? [1][0] + hr: gsink/Close sthis + gsink/Release sthis + + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis ] OS-draw-curve: func [ From 198323eb8716f3c219a0299b4793dc3372e3fd08 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 19 Dec 2019 15:48:13 +0800 Subject: [PATCH 0632/3432] FEAT: support draw curve --- modules/view/backends/windows/draw.reds | 70 +++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 75c008d7f4..7c521c6c35 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -746,11 +746,75 @@ OS-draw-arc: func [ ] OS-draw-curve: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + /local + cp1x [float32!] + cp1y [float32!] + cp2x [float32!] + cp2y [float32!] + p2 [red-pair!] + p3 [red-pair!] + ps [D2D1_BEZIER_SEGMENT value] + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + point [D2D_POINT_2F value] + this [this!] + dc [ID2D1DeviceContext] ][ + p2: start + 1 + p3: start + 2 + + either 2 = ((as-integer end - start) >> 4) [ ;-- p0, p1, p2 --> p0, (p0 + 2p1) / 3, (2p1 + p2) / 3, p2 + cp1x: (as float32! p2/x << 1 + start/x) / as float32! 3.0 + cp1y: (as float32! p2/y << 1 + start/y) / as float32! 3.0 + cp2x: (as float32! p2/x << 1 + p3/x) / as float32! 3.0 + cp2y: (as float32! p2/y << 1 + p3/y) / as float32! 3.0 + ][ + cp1x: as float32! p2/x + cp1y: as float32! p2/y + cp2x: as float32! p3/x + cp2y: as float32! p3/y + ] + ps/point1/x: cp1x + ps/point1/y: cp1y + ps/point2/x: cp2x + ps/point2/y: cp2y + ps/point3/x: as float32! end/x + ps/point3/y: as float32! end/y + + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + + point/x: as float32! start/x + point/y: as float32! start/y + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + hr: gsink/AddBezier sthis ps + gsink/EndFigure sthis 0 + hr: gsink/Close sthis + gsink/Release sthis + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis ] OS-draw-line-join: func [ From 4b54efc89fe68844af0782c587692ec6acaddd8e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 19 Dec 2019 17:48:04 +0800 Subject: [PATCH 0633/3432] FEAT: first support pen style feature --- modules/view/backends/windows/direct2d.reds | 34 +++++++++- modules/view/backends/windows/draw.reds | 74 +++++++++++++++++++-- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 62641306b8..7450468bc6 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -113,6 +113,32 @@ D2D1_GRADIENT_STOP: alias struct! [ a [float32!] ] +#enum D2D1_CAP_STYLE [ + D2D1_CAP_STYLE_FLAT + D2D1_CAP_STYLE_SQUARE + D2D1_CAP_STYLE_ROUND + D2D1_CAP_STYLE_TRIANGLE + D2D1_CAP_STYLE_FORCE_DWORD: -1 +] + +#enum D2D1_LINE_JOIN [ + D2D1_LINE_JOIN_MITER + D2D1_LINE_JOIN_BEVEL + D2D1_LINE_JOIN_ROUND + D2D1_LINE_JOIN_MITER_OR_BEVEL + D2D1_LINE_JOIN_FORCE_DWORD: -1 +] + +D2D1_STROKE_STYLE_PROPERTIES: alias struct! [ + startCap [integer!] + endCap [integer!] + dashCap [integer!] + lineJoin [integer!] + miterLimit [float32!] + dashStyle [integer!] + dashOffset [float32!] +] + D2D1_RENDER_TARGET_PROPERTIES: alias struct! [ type [integer!] format [integer!] @@ -466,7 +492,7 @@ ID2D1Factory: alias struct! [ CreateGeometryGroup [integer!] CreateTransformedGeometry [integer!] CreatePathGeometry [function! [this [this!] pathGeometry [ptr-ptr!] return: [integer!]]] - CreateStrokeStyle [integer!] + CreateStrokeStyle [function! [this [this!] props [D2D1_STROKE_STYLE_PROPERTIES] dashes [float32-ptr!] count [integer!] style [ptr-ptr!] return: [integer!]]] CreateDrawingStateBlock [integer!] CreateWicBitmapRenderTarget [integer!] CreateHwndRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [ptr-ptr!] return: [integer!]]] @@ -823,6 +849,12 @@ ID2D1GeometrySink: alias struct! [ AddArc [function! [this [this!] arc [D2D1_ARC_SEGMENT] return: [integer!]]] ] +ID2D1StrokeStyle: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] +] + ;-- Direct Write DWRITE_LINE_METRICS: alias struct! [ diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 7c521c6c35..41be6ec9a3 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -44,10 +44,13 @@ draw-begin: func [ ][ zero-memory as byte-ptr! ctx size? draw-ctx! ctx/pen-width: as float32! 1.0 + ctx/pen-join: D2D1_LINE_JOIN_MITER + ctx/pen-cap: D2D1_CAP_STYLE_FLAT ctx/pen-style: 0 ctx/pen?: yes ctx/hwnd: hWnd ctx/font-color: -1 + update-pen-style ctx this: d2d-ctx target: get-hwnd-render-target hWnd @@ -112,6 +115,7 @@ draw-end: func [ rt [render-target!] hr [integer!] ][ + release-pen-style ctx rt: as render-target! ctx/target this: rt/dc dc: as ID2D1DeviceContext this/vtbl @@ -139,6 +143,43 @@ draw-end: func [ ] ] +release-pen-style: func [ + ctx [draw-ctx!] + /local + sthis [this!] + style [ID2D1StrokeStyle] +][ + if ctx/pen-style <> 0 [ + sthis: as this! ctx/pen-style + style: as ID2D1StrokeStyle sthis/vtbl + style/Release sthis + ctx/pen-style: 0 + ] +] + +update-pen-style: func [ + ctx [draw-ctx!] + /local + prop [D2D1_STROKE_STYLE_PROPERTIES value] + d2d [ID2D1Factory] + hr [integer!] + style [ptr-value!] +][ + release-pen-style ctx + + prop/startCap: ctx/pen-cap + prop/endCap: ctx/pen-cap + prop/dashCap: ctx/pen-cap + prop/lineJoin: ctx/pen-join + prop/miterLimit: as float32! 1.0 + prop/dashStyle: 0 + prop/dashOffset: as float32! 0.0 + + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreateStrokeStyle d2d-factory prop null 0 :style + ctx/pen-style: as integer! style/value +] + OS-draw-pen: func [ ctx [draw-ctx!] color [integer!] @@ -305,7 +346,7 @@ OS-draw-line: func [ as float32! pt1/x as float32! pt1/y ctx/pen ctx/pen-width - 0 + ctx/pen-style pt0: pt0 + 1 ] ] @@ -818,17 +859,36 @@ OS-draw-curve: func [ ] OS-draw-line-join: func [ - ctx [draw-ctx!] - style [integer!] + ctx [draw-ctx!] + style [integer!] + /local + mode [integer!] ][ - + case [ + style = miter [mode: D2D1_LINE_JOIN_MITER] + style = miter-bevel [mode: D2D1_LINE_JOIN_MITER_OR_BEVEL] + style = _round [mode: D2D1_LINE_JOIN_ROUND] + style = bevel [mode: D2D1_LINE_JOIN_BEVEL] + true [mode: D2D1_LINE_JOIN_MITER] + ] + ctx/pen-join: mode + update-pen-style ctx ] OS-draw-line-cap: func [ - ctx [draw-ctx!] - style [integer!] + ctx [draw-ctx!] + style [integer!] + /local + mode [integer!] ][ - + case [ + style = flat [mode: D2D1_CAP_STYLE_FLAT] + style = square [mode: D2D1_CAP_STYLE_SQUARE] + style = _round [mode: D2D1_CAP_STYLE_ROUND] + true [mode: D2D1_CAP_STYLE_FLAT] + ] + ctx/pen-cap: mode + update-pen-style ctx ] OS-draw-image: func [ From c646655c805fe9b6a6319371e1077c04f88cccbd Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Dec 2019 18:50:58 +0100 Subject: [PATCH 0634/3432] FEAT: lexer FSM adjustments for handling //... forms. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 22140 -> 22159 bytes runtime/lexer-transitions.reds | 6 +++--- utils/generate-lexer-table.red | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 76b191b9c3..e686958079 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -10,7 +10,7 @@ S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_E S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_WORD;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF @@ -42,7 +42,7 @@ S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_ S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR +S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 09abe3a24c9527cdbf23dab21ccc8ed376cd3827..41508a7c76908be8595d14e9328d5b17f48cdc3f 100644 GIT binary patch delta 7960 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 delta 7820 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 604dd7e05f..5d5d2c52ec 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -91,7 +91,7 @@ Red/System [ T_CMT ] prev-table: #{ -0000070707070808080808191429000A0A00140B0C0C0C0C272F2B2B25253333 +0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 330B2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F } transitions: #{ @@ -109,7 +109,7 @@ Red/System [ 0707073838383838383838383838383809090707383838383838383838383838 3838383838410A0A0A0A0A0A0A0A0A0A410A0A0A0A0A0A0A0A0A0A0A0A0A0A0A 0A0A0A0A0A0A0A0A0A0A0A383842420B0B424242424242420B0B0B0B0B0B0B0B -0B0B0B0B0B0B0B0B0B42420B0B0B0B0B0B0B384247471212113845380D380F12 +0B0B2C0B0B0B0B0B0B42420B0B0B0B0B0B0B384247471212113845380D380F12 1238121212121212121212383838123847471212121212121238470D0D0D0D38 3838383843383838380D0D0D0D0D0D0D0D3838380D38380E3838380D3838380D 38380E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E @@ -148,7 +148,7 @@ Red/System [ 402A2A40404040404040382C2D2C2C2C2A2A2C2C54402C2C2C3838402F2C382A 2A2C2C2C38404A4A2A2A4A4A4A4A4A4A4A38384A1C38382A2A38384A384A3838 4838383838382A2A383838384A38383838383838383838383838382C2C2C2C2C -2C2C2C382C2C2C383838382C382C2C382C2C383840402C2C4040404040404038 +2C2C0B382C2C2C383838382C382C2C382C2C383840402C2C4040404040404038 2C2D2C2C2C2C2C2C2C54402C2C2C3838402F2C1F2C2C2C2C2C384040402E2E40 4040404040402E2E2E2E2E2E2E2E2E2E2E40382E2E2E2E402E2E2E2E2E2E2E2E 384052522E2E525252525252522E382E2E2E2E2E2E2E2E2E5252382E2E52522E diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index f7d37c2f63..d8af5c6683 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -24,7 +24,7 @@ context [ S_FILE_HEX1 TYPE_FILE ;-- 8 S_FILE_HEX2 TYPE_FILE ;-- 9 S_FILE_STR TYPE_FILE ;-- 10 - S_SLASH TYPE_PATH ;-- 11 + S_SLASH TYPE_REFINEMENT ;-- 11 S_SHARP TYPE_ISSUE ;-- 12 S_BINARY TYPE_BINARY ;-- 13 S_LINE_CMT2 TYPE_VALUE ;-- 14 From 76233af707f39cd26b4dbd1e60f24411416f13d7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Dec 2019 18:51:51 +0100 Subject: [PATCH 0635/3432] FEAT: minor syntax error messages change. --- environment/system.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/environment/system.red b/environment/system.red index e47d1147be..0f2d7bde85 100644 --- a/environment/system.red +++ b/environment/system.red @@ -86,13 +86,13 @@ system: context [ syntax: object [ code: 200 type: "Syntax Error" - invalid: [:arg1 "invalid" :arg2 "at:" :arg3] - missing: [:arg1 "missing" :arg2 "at:" :arg3] + invalid: [:arg1 "invalid" :arg2 "at" :arg3] + missing: [:arg1 "missing" :arg2 "at" :arg3] no-header: ["script is missing a Red header:" :arg1] no-rs-header: ["script is missing a Red/System header:" :arg1] bad-header: ["script header is not valid:" :arg1] - malconstruct: [:arg1 "invalid construction spec at:" :arg2] - bad-char: [:arg1 "invalid character at:" :arg2] + malconstruct: [:arg1 "invalid construction spec at" :arg2] + bad-char: [:arg1 "invalid character at" :arg2] ] script: object [ code: 300 From bba62f8854c06f3e368eb0b041d1a97a17359fd7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Dec 2019 18:53:20 +0100 Subject: [PATCH 0636/3432] FIX: multiple fixes and improvements to string and word scanning. --- runtime/lexer.reds | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 91870aa29c..2a105b0117 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -772,7 +772,7 @@ lexer: context [ pos: c >>> 3 + 1 bit: as-byte 1 << (c and 7) either char-special/pos and bit = null-byte [ ;-- "regular" escaped char - if any [s/1 < #"^(40)" #"^(5F)" < s/1][c: as-integer s/1 - #"@"] + if all [#"^(40)" < s/1 s/1 < #"^(5F)"][c: as-integer s/1 - #"@"] ][ ;-- escaped special char c: switch s/1 [ #"/" [0Ah] @@ -998,6 +998,7 @@ lexer: context [ either zero? lex/mstr-nest [ scan-string lex lex/mstr-s e lex/mstr-flags or flags lex/mstr-s: null + lex/mstr-flags: 0 lex/entry: S_START ][ if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING] @@ -1009,6 +1010,7 @@ lexer: context [ /local cell [cell!] type [integer!] + p [byte-ptr!] ][ type: TYPE_WORD if flags and C_FLAG_COLON <> 0 [ @@ -1023,6 +1025,11 @@ lexer: context [ if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] s: s + 1 type: TYPE_LIT_WORD ] + if s/1 = #"/" [ ;-- //... + p: s + 1 + while [all [p < e p/1 = #"/"]][p: p + 1] + if p < e [throw-error lex s e TYPE_REFINEMENT] + ] cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type @@ -1144,13 +1151,22 @@ lexer: context [ /local cell [cell!] type [integer!] + p [byte-ptr!] ][ type: either s/1 = #"#" [ if s + 1 = e [throw-error lex s e TYPE_ISSUE] TYPE_ISSUE ][ assert s/1 = #"/" - either s + 1 = e [s: s - 1 TYPE_WORD][TYPE_REFINEMENT] + either s + 1 = e [s: s - 1 TYPE_WORD][ + either s/2 = #"/" [ ;-- //... + scan-word lex s e flags + exit + 0 + ][ + TYPE_REFINEMENT + ] + ] ] s: s + 1 cell: alloc-slot lex @@ -1730,6 +1746,7 @@ lexer: context [ lex/entry: S_START lex/type: -1 lex/mstr-nest: 0 + lex/mstr-flags: 0 scan-tokens lex one? From 00ed5113a50b34a43bc9a7653360b8589bac219a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Dec 2019 18:55:49 +0100 Subject: [PATCH 0637/3432] TESTS: updating some LOAD tests for new lexer. --- tests/source/units/load-test.red | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/source/units/load-test.red b/tests/source/units/load-test.red index cdeef6577f..60fc835c99 100644 --- a/tests/source/units/load-test.red +++ b/tests/source/units/load-test.red @@ -119,6 +119,7 @@ Red [ --test-- "load-word-17" --assert strict-equal? first [:a] load ":a" --test-- "load-word-18" --assert strict-equal? first ['a] load "'a" --test-- "load-word-19" --assert strict-equal? first [œ∑´®†] load "œ∑´®†" + --test-- "load-word-20" --assert word? load "//" ===end-group=== @@ -317,25 +318,25 @@ Red [ ===start-group=== "load issue #3717" --test-- "load ) 1" --assert error? res: try [load ")"] - --assert to logic! find/match form res {*** Syntax Error: missing #"(" at ")"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing ( at )^/*** Where} --test-- "load ) 2" --assert error? res: try [load "a)"] - --assert to logic! find/match form res {*** Syntax Error: missing #"(" at ")"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing ( at )^/*** Where} --test-- "load ) 3" --assert error? res: try [load "a)b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"(" at ")b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing ( at )b^/*** Where} --test-- "load ) 4" --assert error? res: try [load "())b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"(" at ")b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing ( at )b^/*** Where} --test-- "load ) 5" res: load/trap "())b" --assert [()] = res/1 --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: missing #"(" at ")b"^/*** Where} + --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing ( at )b^/*** Where} --test-- "load ) 6" s: "())b" @@ -348,25 +349,25 @@ Red [ --test-- "load ] 1" --assert error? res: try [load "]"] - --assert to logic! find/match form res {*** Syntax Error: missing #"[" at "]"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing [ at ]^/*** Where} --test-- "load ] 2" --assert error? res: try [load "a]"] - --assert to logic! find/match form res {*** Syntax Error: missing #"[" at "]"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing [ at ]^/*** Where} --test-- "load ] 3" --assert error? res: try [load "a]b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"[" at "]b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} --test-- "load ] 4" --assert error? res: try [load "[]]b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"[" at "]b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} --test-- "load ] 5" res: load/trap "[]]b" --assert [[]] = res/1 --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: missing #"[" at "]b"^/*** Where} + --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} --test-- "load ] 6" s: "[]]b" @@ -379,25 +380,25 @@ Red [ --test-- "load } 1" --assert error? res: try [load "}"] - --assert to logic! find/match form res {*** Syntax Error: missing #"{" at "}"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) invalid character at ^}^/*** Where} --test-- "load } 2" --assert error? res: try [load "a}"] - --assert to logic! find/match form res {*** Syntax Error: missing #"{" at "}"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) invalid character at ^}^/*** Where} --test-- "load } 3" --assert error? res: try [load "a}b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"{" at "}b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} --test-- "load } 4" --assert error? res: try [load "{}}b"] - --assert to logic! find/match form res {*** Syntax Error: missing #"{" at "}b"^/*** Where} + --assert to logic! find/match form res {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} --test-- "load } 5" res: load/trap "{}}b" --assert [""] = res/1 --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: missing #"{" at "}b"^/*** Where} + --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} --test-- "load } 6" s: "{}}b" From 5f8ddd61283dea300b5cc5415f866e8e2822c993 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 20 Dec 2019 10:17:34 +0800 Subject: [PATCH 0638/3432] FEAT: add anti-alias mode --- modules/view/backends/windows/direct2d.reds | 2 +- modules/view/backends/windows/draw.reds | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 7450468bc6..2b2164339c 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -621,7 +621,7 @@ ID2D1DeviceContext: alias struct! [ DrawGlyphRun [integer!] SetTransform [SetTransform*] GetTransform [integer!] - SetAntialiasMode [integer!] + SetAntialiasMode [function! [this [this!] mode [integer!]]] GetAntialiasMode [integer!] SetTextAntialiasMode [function! [this [this!] mode [integer!]]] GetTextAntialiasMode [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 41be6ec9a3..693e758d34 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -60,6 +60,7 @@ draw-begin: func [ dc: as ID2D1DeviceContext this/vtbl ;dc/SetTextAntialiasMode this 1 ;-- ClearType dc/SetTarget this target/bitmap + dc/SetAntialiasMode this 0 ;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE dc/BeginDraw this _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 @@ -319,10 +320,15 @@ OS-draw-shape-arc: func [ ] OS-draw-anti-alias: func [ - ctx [draw-ctx!] - on? [logic!] + ctx [draw-ctx!] + on? [logic!] + /local + this [this!] + dc [ID2D1DeviceContext] ][ - + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/SetAntialiasMode this either on? [0][1] ] OS-draw-line: func [ From 9f124e1b6d9b002feeb1fc2cf2a73e9e15ff5304 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 20 Dec 2019 16:31:01 +0800 Subject: [PATCH 0639/3432] FEAT: first implement matrix for direct2d --- build/includes.r | 1 + modules/view/backends/windows/direct2d.reds | 35 +++--- modules/view/backends/windows/draw.reds | 15 +-- modules/view/backends/windows/gui.reds | 1 + modules/view/backends/windows/matrix2d.reds | 125 ++++++++++++++++++++ 5 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 modules/view/backends/windows/matrix2d.reds diff --git a/build/includes.r b/build/includes.r index 9b0a2b5b91..494055dedc 100644 --- a/build/includes.r +++ b/build/includes.r @@ -190,6 +190,7 @@ write %build/bin/sources.r set-cache [ %classes.reds %comdlgs.reds %direct2d.reds + %matrix2d.reds %draw-gdi.reds %draw.reds %events.reds diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 2b2164339c..abed2e66bd 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -1168,6 +1168,22 @@ render-target!: alias struct! [ dcomp-visual [this!] ] +#import [ + "d2d1.dll" stdcall [ + D2D1CreateFactory: "D2D1CreateFactory" [ + type [integer!] + riid [int-ptr!] + options [int-ptr!] ;-- opt + factory [ptr-ptr!] + return: [integer!] + ] + D2D1InvertMatrix: "D2D1InvertMatrix" [ + matrix [D2D_MATRIX_3X2_F] + return: [logic!] + ] + ] +] + #define ConvertPointSizeToDIP(size) (as float32! 96 * size / 72) select-brush: func [ @@ -1214,13 +1230,9 @@ DX-init: func [ factory [ptr-value!] dll [handle!] options [integer!] - D2D1CreateFactory [D2D1CreateFactory!] DWriteCreateFactory [DWriteCreateFactory!] GetUserDefaultLocaleName [GetUserDefaultLocaleName!] ][ - dll: LoadLibraryA "d2d1.dll" - if null? dll [winxp?: yes exit] - D2D1CreateFactory: as D2D1CreateFactory! GetProcAddress dll "D2D1CreateFactory" dll: LoadLibraryA "DWrite.dll" if null? dll [winxp?: yes exit] DWriteCreateFactory: as DWriteCreateFactory! GetProcAddress dll "DWriteCreateFactory" @@ -1854,13 +1866,7 @@ draw-text-d2d: func [ brush [integer!] color [red-tuple!] clr [integer!] - _11 [integer!] - _12 [integer!] - _21 [integer!] - _22 [integer!] - _31 [integer!] - _32 [integer!] - m [D2D_MATRIX_3X2_F] + m [D2D_MATRIX_3X2_F value] ][ fmt: as this! create-text-format font null set-text-format fmt para @@ -1872,11 +1878,8 @@ draw-text-d2d: func [ ;rt/SetTextAntialiasMode this 1 ;-- ClearType rt/BeginDraw this - _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 - m: as D2D_MATRIX_3X2_F :_32 - m/_11: as float32! 1.0 - m/_22: as float32! 1.0 - rt/SetTransform this m ;-- set to identity matrix + matrix2d/identity m + rt/SetTransform this :m ;-- set to identity matrix clr: either TYPE_OF(font) = TYPE_OBJECT [ color: as red-tuple! (object/get-values font) + FONT_OBJ_COLOR diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 693e758d34..ca17721cc7 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -24,13 +24,7 @@ draw-begin: func [ /local this [this!] dc [ID2D1DeviceContext] - _11 [integer!] - _12 [integer!] - _21 [integer!] - _22 [integer!] - _31 [integer!] - _32 [integer!] - m [D2D_MATRIX_3X2_F] + m [D2D_MATRIX_3X2_F value] bg-clr [integer!] brush [integer!] target [render-target!] @@ -63,11 +57,8 @@ draw-begin: func [ dc/SetAntialiasMode this 0 ;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE dc/BeginDraw this - _11: 0 _12: 0 _21: 0 _22: 0 _31: 0 _32: 0 - m: as D2D_MATRIX_3X2_F :_32 - m/_11: as float32! 1.0 - m/_22: as float32! 1.0 - dc/SetTransform this m ;-- set to identity matrix + matrix2d/identity m + dc/SetTransform this :m ;-- set to identity matrix values: get-face-values hWnd clr: as red-tuple! values + FACE_OBJ_COLOR diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index f9a840f79b..960072fd52 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -34,6 +34,7 @@ Red/System [ #include %win32.reds #include %direct2d.reds +#include %matrix2d.reds #include %classes.reds #include %events.reds diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds new file mode 100644 index 0000000000..b6a9e3904a --- /dev/null +++ b/modules/view/backends/windows/matrix2d.reds @@ -0,0 +1,125 @@ +Red/System [ + Title: "matrix for direct2d" + Author: "bitbegin" + File: %matrix2d.reds + Tabs: 4 + Rights: "Copyright (C) 2016-2019 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +;-- matrix layout: +;-- _11 _12 0.0 +;-- _21 _22 0.0 +;-- _31 _32 1.0 + +matrix2d: context [ + identity: func [ + m [D2D_MATRIX_3X2_F] + ][ + m/_11: as float32! 1.0 + m/_12: as float32! 0.0 + m/_21: as float32! 0.0 + m/_22: as float32! 1.0 + m/_31: as float32! 1.0 + m/_32: as float32! 0.0 + ] + + ;-- c: l * r + mul: func [ + l [D2D_MATRIX_3X2_F] + r [D2D_MATRIX_3X2_F] + c [D2D_MATRIX_3X2_F] + ][ + c/_11: l/_11 * r/_11 + (l/_12 * r/_21) + c/_12: l/_11 * r/_12 + (l/_12 * r/_22) + c/_21: l/_21 * r/_11 + (l/_22 * r/_21) + c/_22: l/_21 * r/_12 + (l/_22 * r/_22) + c/_31: l/_31 * r/_11 + (l/_32 * r/_21) + r/_31 + c/_32: l/_31 * r/_12 + (l/_32 * r/_22) + r/_32 + ] + + translate: func [ + m [D2D_MATRIX_3X2_F] + x [float32!] + y [float32!] + r [D2D_MATRIX_3X2_F] + /local + t [D2D_MATRIX_3X2_F value] + ][ + identity t + t/_31: x + t/_32: y + mul t m r + ] + + scale: func [ + m [D2D_MATRIX_3X2_F] + x [float32!] + y [float32!] + r [D2D_MATRIX_3X2_F] + /local + t [D2D_MATRIX_3X2_F value] + ][ + identity t + t/_11: x + t/_22: y + mul t m r + ] + + rotate: func [ + m [D2D_MATRIX_3X2_F] + angle [float32!] + r [D2D_MATRIX_3X2_F] + /local + t [D2D_MATRIX_3X2_F value] + ][ + identity t + t/_11: as float32! cos as float! angle + t/_12: as float32! sin as float! angle + t/_21: (as float32! 0.0) - t/_12 + t/_22: t/_11 + mul t m r + ] + + skew: func [ + m [D2D_MATRIX_3X2_F] + x [float32!] ;-- x-axis rotate angle + y [float32!] ;-- y-axis rotate angle, but with negative direction + r [D2D_MATRIX_3X2_F] + /local + t [D2D_MATRIX_3X2_F value] + ][ + identity t + t/_12: as float32! tan as float! x + t/_21: as float32! tan as float! y + mul t m r + ] + + affine: func [ + m [D2D_MATRIX_3X2_F] + x [float32!] ;-- x-axis rotate angle + y [float32!] ;-- y-axis rotate angle, but with negative direction + r [D2D_MATRIX_3X2_F] + /local + t [D2D_MATRIX_3X2_F value] + ][ + identity t + t/_11: as float32! cos as float! x + t/_12: as float32! sin as float! x + t/_21: as float32! cos as float! y + t/_22: as float32! sin as float! y + mul t m r + ] + + invert: func [ + m [D2D_MATRIX_3X2_F] + r [D2D_MATRIX_3X2_F] + return: [logic!] + ][ + copy-memory as byte-ptr! r as byte-ptr! m size? D2D_MATRIX_3X2_F + D2D1InvertMatrix r + ] +] From afbd6bfcbd216ecad5e94d75da0867b81165a83a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 20 Dec 2019 17:38:20 +0800 Subject: [PATCH 0640/3432] FEAT: support transform on dc --- modules/view/backends/windows/direct2d.reds | 15 +- modules/view/backends/windows/draw.reds | 143 ++++++++++++++++++-- 2 files changed, 142 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index abed2e66bd..4d606fc41a 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -286,6 +286,11 @@ SetTransform*: alias function! [ transform [D2D_MATRIX_3X2_F] ] +GetTransform*: alias function! [ + this [this!] + transform [D2D_MATRIX_3X2_F] +] + Resize*: alias function! [ this [this!] pixelSize [tagSIZE] @@ -320,7 +325,7 @@ ID2D1SolidColorBrush: alias struct! [ SetOpacity [integer!] SetTransform [SetTransform*] GetOpacity [integer!] - GetTransform [integer!] + GetTransform [GetTransform*] SetColor [function! [this [this!] color [D3DCOLORVALUE]]] GetColor [integer!] ] @@ -333,7 +338,7 @@ ID2D1RadialGradientBrush: alias struct! [ SetOpacity [integer!] SetTransform [SetTransform*] GetOpacity [integer!] - GetTransform [integer!] + GetTransform [GetTransform*] SetCenter [integer!] SetGradientOriginOffset [integer!] SetRadiusX [integer!] @@ -620,7 +625,7 @@ ID2D1DeviceContext: alias struct! [ DrawTextLayout [DrawTextLayout*] DrawGlyphRun [integer!] SetTransform [SetTransform*] - GetTransform [integer!] + GetTransform [GetTransform*] SetAntialiasMode [function! [this [this!] mode [integer!]]] GetAntialiasMode [integer!] SetTextAntialiasMode [function! [this [this!] mode [integer!]]] @@ -715,7 +720,7 @@ ID2D1HwndRenderTarget: alias struct! [ DrawTextLayout [DrawTextLayout*] DrawGlyphRun [integer!] SetTransform [SetTransform*] - GetTransform [integer!] + GetTransform [GetTransform*] SetAntialiasMode [integer!] GetAntialiasMode [integer!] SetTextAntialiasMode [function! [this [this!] mode [integer!]]] @@ -778,7 +783,7 @@ ID2D1DCRenderTarget: alias struct! [ DrawTextLayout [DrawTextLayout*] DrawGlyphRun [integer!] SetTransform [SetTransform*] - GetTransform [integer!] + GetTransform [GetTransform*] SetAntialiasMode [integer!] GetAntialiasMode [integer!] SetTextAntialiasMode [function! [this [this!] mode [integer!]]] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index ca17721cc7..e1181f59f9 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -966,8 +966,30 @@ OS-matrix-rotate: func [ pen-fill [integer!] angle [red-integer!] center [red-pair!] + /local + rad [float!] + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] ][ - + rad: PI / 180.0 * get-float angle + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + either angle <> as red-integer! center [ + matrix2d/translate :m as float32! center/x as float32! center/y :t + matrix2d/rotate :t as float32! rad :m + matrix2d/translate :m as float32! 0 - center/x as float32! 0 - center/y :t + ][ + matrix2d/rotate :m as float32! rad :t + ] + dc/SetTransform this :t + ][ + ;-- TBD + exit + ] ] OS-matrix-scale: func [ @@ -975,8 +997,22 @@ OS-matrix-scale: func [ pen-fill [integer!] sx [red-integer!] sy [red-integer!] + /local + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] ][ - + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + matrix2d/scale :m get-float32 sx get-float32 sy :t + dc/SetTransform this :t + ][ + ;-- TBD + exit + ] ] OS-matrix-translate: func [ @@ -984,17 +1020,49 @@ OS-matrix-translate: func [ pen-fill [integer!] x [integer!] y [integer!] + /local + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] ][ - + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + matrix2d/translate :m as float32! x as float32! y :t + dc/SetTransform this :t + ][ + ;-- TBD + exit + ] ] OS-matrix-skew: func [ - ctx [draw-ctx!] - pen-fill [integer!] + ctx [draw-ctx!] + pen-fill [integer!] sx [red-integer!] sy [red-integer!] + /local + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] + x [float32!] + y [float32!] ][ - + x: as float32! degree-to-radians get-float sx TYPE_TANGENT + y: as float32! degree-to-radians get-float sy TYPE_TANGENT + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + matrix2d/skew :m x y :t + dc/SetTransform this :t + ][ + ;-- TBD + exit + ] ] OS-matrix-transform: func [ @@ -1003,8 +1071,16 @@ OS-matrix-transform: func [ center [red-pair!] scale [red-integer!] translate [red-pair!] + /local + rotate [red-integer!] + center? [logic!] ][ - + rotate: as red-integer! either center + 1 = scale [center][center + 1] + center?: rotate <> center + + OS-matrix-rotate ctx pen-fill rotate center + OS-matrix-scale ctx pen-fill scale scale + 1 + OS-matrix-translate ctx pen-fill translate/x translate/y ] OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!]][ @@ -1016,24 +1092,69 @@ OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][] OS-matrix-reset: func [ ctx [draw-ctx!] pen-fill [integer!] + /local + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] ][ - + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + matrix2d/identity :m + dc/SetTransform this :m + ][ + ;-- TBD + exit + ] ] OS-matrix-invert: func [ ctx [draw-ctx!] pen-fill [integer!] - + /local + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] ][ - + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/GetTransform this :m + matrix2d/invert :m :t + dc/SetTransform this :t + ][ + ;-- TBD + exit + ] ] OS-matrix-set: func [ ctx [draw-ctx!] pen-fill [integer!] blk [red-block!] + /local + val [red-integer!] + this [this!] + dc [ID2D1DeviceContext] + m [D2D_MATRIX_3X2_F value] ][ - + val: as red-integer! block/rs-head blk + m/_11: get-float32 val + m/_12: get-float32 val + 1 + m/_21: get-float32 val + 2 + m/_22: get-float32 val + 3 + m/_31: get-float32 val + 4 + m/_32: get-float32 val + 5 + either pen-fill = -1 [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/SetTransform this :m + ][ + ;-- TBD + exit + ] ] OS-set-matrix-order: func [ From 0fd75732ba1b57b9bda8d49dcadd76920943d000 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 22 Dec 2019 18:06:59 +0100 Subject: [PATCH 0641/3432] FEAT: adds /next refinement to TRANSCODE. --- environment/natives.red | 2 ++ runtime/datatypes/block.reds | 28 ++++++++++++++++++++-------- runtime/lexer.reds | 8 +++++--- runtime/natives.reds | 28 +++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index e9cce7fd45..54271f214d 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -911,12 +911,14 @@ recycle: make native! [[ transcode: make native! [[ "Translates UTF-8 binary source to values. Returns one or several values in a block" src [binary!] "UTF-8 input buffer" + /next "Translate next complete value (blocks as single value)" /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" /into "Optionally provides an output block" dst [block! none!] ;/trace ; callback [function! [...]] + return: [block!] ] #get-definition NAT_TRANSCODE ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index b13404d02c..dbf54998ca 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -369,6 +369,25 @@ block: context [ set-type as cell! blk TYPE_BLOCK blk ] + + preallocate: func [ + blk [red-block!] + size [integer!] + fixed? [logic!] ;-- alloc fixed cells instead of unset ones. + return: [red-block!] + ][ + if size < 0 [size: 1] + blk/header: TYPE_UNSET + blk/head: 0 + either fixed? [ + blk/node: alloc-fixed-series size 16 0 + ][ + blk/node: alloc-unset-cells size 16 0 + ] + blk/extra: 0 + blk/header: TYPE_BLOCK ;-- implicit reset of all header flags + blk + ] make-fixed: func [ parent [red-block!] @@ -390,14 +409,7 @@ block: context [ ] as red-block! ALLOC_TAIL(parent) ] - - if size < 0 [size: 1] - blk/header: TYPE_UNSET - blk/head: 0 - blk/node: alloc-fixed-series size 16 0 - blk/extra: 0 - blk/header: TYPE_BLOCK ;-- implicit reset of all header flags - blk + preallocate blk size yes ] make-in: func [ diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 2a105b0117..f8f1dc4e56 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1723,8 +1723,9 @@ lexer: context [ scan: func [ dst [red-value!] ;-- destination slot src [byte-ptr!] ;-- UTF-8 buffer - len [integer!] ;-- buffer size in bytes - one? [logic!] ;-- scan only one value + size [integer!] ;-- buffer size in bytes + one? [logic!] ;-- scan a single value + len [int-ptr!] ;-- return the consumed input length /local blk [red-block!] slots [integer!] @@ -1740,7 +1741,7 @@ lexer: context [ lex/tail: stash lex/slots: stash-size ;TBD: support dyn buffer case lex/input: src - lex/in-end: src + len + lex/in-end: src + size lex/in-pos: src lex/in-path: null lex/entry: S_START @@ -1757,6 +1758,7 @@ lexer: context [ ][ store-any-block dst lex/buffer slots TYPE_BLOCK ] + len/value: as-integer lex/in-pos - lex/input depth: depth - 1 if zero? depth [root-state: null] diff --git a/runtime/natives.reds b/runtime/natives.reds index 237221a80c..f5027b8b0c 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2731,24 +2731,42 @@ natives: context [ transcode*: func [ check? [logic!] + next [integer!] part [integer!] into [integer!] /local - bin [red-binary!] - slot [red-value!] - len [integer!] + bin [red-binary!] + slot [red-value!] + blk [red-block!] + s [series!] + offset [integer!] + len [integer!] + next? [logic!] ][ - #typecheck [part into] + #typecheck [next part into] + next?: next > -1 bin: as red-binary! stack/arguments slot: stack/push* + if next? [ + blk: block/preallocate as red-block! slot 2 no + s: GET_BUFFER(blk) + s/tail: s/offset + 2 + slot: s/offset + ] len: binary/rs-length? bin + offset: 0 ;if OPTION?(part) [ ; ;] - lexer/scan slot binary/rs-head bin len no + lexer/scan slot binary/rs-head bin len next? :offset + if next? [ + bin: as red-binary! copy-cell as red-value! bin s/offset + 1 + bin/head: bin/head + offset + slot: as red-value! blk + ] stack/set-last slot ] From 324eddd402ae5d3765a4f7e6179a19a965c30c79 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 23 Dec 2019 16:26:40 +0800 Subject: [PATCH 0642/3432] FEAT: first implement line shape --- modules/view/backends/windows/draw.reds | 148 ++++++++++++++++++++++-- runtime/definitions.reds | 7 ++ 2 files changed, 148 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index e1181f59f9..e278cbbbbe 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -219,30 +219,113 @@ OS-draw-text: func [ OS-draw-shape-beginpath: func [ ctx [draw-ctx!] + /local + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + vpoint [D2D_POINT_2F value] ][ + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + ctx/sub/path: as integer! pthis + ctx/sub/sink: as integer! sthis + ctx/sub/last-pt-x: as float32! 0.0 + ctx/sub/last-pt-y: as float32! 0.0 + vpoint/x: ctx/sub/last-pt-x + vpoint/y: ctx/sub/last-pt-y + gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW ] OS-draw-shape-endpath: func [ ctx [draw-ctx!] close? [logic!] return: [logic!] + /local + pthis [this!] + gpath [ID2D1PathGeometry] + sthis [this!] + gsink [ID2D1GeometrySink] + hr [integer!] + this [this!] + dc [ID2D1DeviceContext] ][ + pthis: as this! ctx/sub/path + gpath: as ID2D1PathGeometry pthis/vtbl + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + + gsink/EndFigure sthis either close? [1][0] + hr: gsink/Close sthis + gsink/Release sthis + + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis + + ctx/sub/path: 0 + ctx/sub/sink: 0 + true ] OS-draw-shape-close: func [ - ctx [draw-ctx!] + ctx [draw-ctx!] + /local + sthis [this!] + gsink [ID2D1GeometrySink] + vpoint [D2D_POINT_2F value] ][ - + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + gsink/EndFigure sthis 1 + vpoint/x: ctx/sub/last-pt-x + vpoint/y: ctx/sub/last-pt-y + gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW ] OS-draw-shape-moveto: func [ - ctx [draw-ctx!] - coord [red-pair!] - rel? [logic!] + ctx [draw-ctx!] + coord [red-pair!] + rel? [logic!] + /local + dx [float32!] + dy [float32!] + sthis [this!] + gsink [ID2D1GeometrySink] + vpoint [D2D_POINT_2F value] ][ - + dx: as float32! coord/x + dy: as float32! coord/y + either rel? [ + ctx/sub/last-pt-x: ctx/sub/last-pt-x + dx + ctx/sub/last-pt-y: ctx/sub/last-pt-y + dy + ][ + ctx/sub/last-pt-x: dx + ctx/sub/last-pt-y: dy + ] + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + gsink/EndFigure sthis 0 + vpoint/x: ctx/sub/last-pt-x + vpoint/y: ctx/sub/last-pt-y + gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW ] OS-draw-shape-line: func [ @@ -250,8 +333,39 @@ OS-draw-shape-line: func [ start [red-pair!] end [red-pair!] rel? [logic!] + /local + sthis [this!] + gsink [ID2D1GeometrySink] + vpoint [D2D_POINT_2F value] + dx [float32!] + dy [float32!] + x [float32!] + y [float32!] + pair [red-pair!] ][ + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + dx: ctx/sub/last-pt-x + dy: ctx/sub/last-pt-y + pair: start + while [pair <= end][ + x: as float32! pair/x + y: as float32! pair/y + if rel? [ + x: x + dx + y: y + dy + dx: x + dy: y + ] + vpoint/x: x + vpoint/y: y + gsink/AddLine sthis vpoint + pair: pair + 1 + ] + + ctx/sub/last-pt-x: x + ctx/sub/last-pt-y: y ] OS-draw-shape-axis: func [ @@ -259,9 +373,29 @@ OS-draw-shape-axis: func [ start [red-value!] end [red-value!] rel? [logic!] - hline [logic!] + hline? [logic!] + /local + sthis [this!] + gsink [ID2D1GeometrySink] + len [float32!] + sx [float32!] + sy [float32!] + vpoint [D2D_POINT_2F value] ][ + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + len: get-float32 as red-integer! start + sx: ctx/sub/last-pt-x + sy: ctx/sub/last-pt-y + either hline? [ + ctx/sub/last-pt-x: either rel? [sx + len][len] + ][ + ctx/sub/last-pt-y: either rel? [sy + len][len] + ] + vpoint/x: ctx/sub/last-pt-x + vpoint/y: ctx/sub/last-pt-y + gsink/AddLine sthis vpoint ] OS-draw-shape-curve: func [ diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 68fbc4e297..6e393ce536 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -256,6 +256,12 @@ Red/System [ ] #either legacy = none [ + sub-path!: alias struct! [ + path [integer!] + sink [integer!] + last-pt-x [float32!] + last-pt-y [float32!] + ] draw-ctx!: alias struct! [ dc [ptr-ptr!] target [int-ptr!] @@ -277,6 +283,7 @@ Red/System [ alpha-pen? [logic!] alpha-brush? [logic!] font-color? [logic!] + sub [sub-path! value] ] ][ draw-ctx!: alias struct! [ From 884dbceede34e74edbdd1ff700d1dc59bf77c56b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 23 Dec 2019 17:05:02 +0800 Subject: [PATCH 0643/3432] FEAT: implement shape curve --- modules/view/backends/windows/draw.reds | 97 ++++++++++++++++++++++++- runtime/definitions.reds | 3 + 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index e278cbbbbe..140e0c70b9 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -242,6 +242,7 @@ OS-draw-shape-beginpath: func [ ctx/sub/sink: as integer! sthis ctx/sub/last-pt-x: as float32! 0.0 ctx/sub/last-pt-y: as float32! 0.0 + ctx/sub/shape-curve?: no vpoint/x: ctx/sub/last-pt-x vpoint/y: ctx/sub/last-pt-y gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW @@ -326,6 +327,7 @@ OS-draw-shape-moveto: func [ vpoint/x: ctx/sub/last-pt-x vpoint/y: ctx/sub/last-pt-y gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + ctx/sub/shape-curve?: no ] OS-draw-shape-line: func [ @@ -366,6 +368,7 @@ OS-draw-shape-line: func [ ctx/sub/last-pt-x: x ctx/sub/last-pt-y: y + ctx/sub/shape-curve?: no ] OS-draw-shape-axis: func [ @@ -398,13 +401,99 @@ OS-draw-shape-axis: func [ gsink/AddLine sthis vpoint ] +draw-curve: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] + short? [logic!] + num [integer!] ;-- number of points + /local + dx [float32!] + dy [float32!] + p3y [float32!] + p3x [float32!] + p2y [float32!] + p2x [float32!] + p1y [float32!] + p1x [float32!] + pf [float32-ptr!] + pt [red-pair!] + sthis [this!] + gsink [ID2D1GeometrySink] + bezier [D2D1_BEZIER_SEGMENT value] + qbezier [D2D1_QUADRATIC_BEZIER_SEGMENT value] +][ + pt: start + 1 + p1x: as float32! start/x + p1y: as float32! start/y + p2x: as float32! pt/x + p2y: as float32! pt/y + if num = 3 [ ;-- cubic Bézier + pt: start + 2 + p3x: as float32! pt/x + p3y: as float32! pt/y + ] + + dx: ctx/sub/last-pt-x + dy: ctx/sub/last-pt-y + if rel? [ + pf: :p1x + loop num [ + pf/1: pf/1 + dx ;-- x + pf/2: pf/2 + dy ;-- y + pf: pf + 2 + ] + ] + + if short? [ + either ctx/sub/shape-curve? [ + ;-- The control point is assumed to be the reflection of the control point + ;-- on the previous command relative to the current point + p1x: dx * (as float32! 2.0) - ctx/sub/control-x + p1y: dy * (as float32! 2.0) - ctx/sub/control-y + ][ + ;-- if previous command is not curve/curv/qcurve/qcurv, use current point + p1x: dx + p1y: dy + ] + ] + + ctx/sub/shape-curve?: yes + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + either num = 3 [ ;-- cubic Bézier + bezier/point1/x: p1x + bezier/point1/y: p1y + bezier/point2/x: p2x + bezier/point2/y: p2y + bezier/point3/x: p3x + bezier/point3/y: p3y + gsink/AddBezier sthis bezier + ctx/sub/control-x: p2x + ctx/sub/control-y: p2y + ctx/sub/last-pt-x: p3x + ctx/sub/last-pt-y: p3y + ][ ;-- quadratic Bézier + qbezier/point1/x: p1x + qbezier/point1/y: p1y + qbezier/point2/x: p2x + qbezier/point2/y: p2y + gsink/AddQuadraticBezier sthis qbezier + ctx/sub/control-x: p1x + ctx/sub/control-y: p1y + ctx/sub/last-pt-x: p2x + ctx/sub/last-pt-y: p2y + ] +] + OS-draw-shape-curve: func [ ctx [draw-ctx!] start [red-pair!] end [red-pair!] rel? [logic!] ][ - + draw-curve ctx start end rel? no 3 ] OS-draw-shape-qcurve: func [ @@ -413,7 +502,7 @@ OS-draw-shape-qcurve: func [ end [red-pair!] rel? [logic!] ][ - + draw-curve ctx start end rel? no 2 ] OS-draw-shape-curv: func [ @@ -422,7 +511,7 @@ OS-draw-shape-curv: func [ end [red-pair!] rel? [logic!] ][ - + draw-curve ctx start - 1 end rel? yes 3 ] OS-draw-shape-qcurv: func [ @@ -431,7 +520,7 @@ OS-draw-shape-qcurv: func [ end [red-pair!] rel? [logic!] ][ - + draw-curve ctx start - 1 end rel? yes 2 ] OS-draw-shape-arc: func [ diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 6e393ce536..a0c3241e69 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -261,6 +261,9 @@ Red/System [ sink [integer!] last-pt-x [float32!] last-pt-y [float32!] + shape-curve? [logic!] + control-x [float32!] + control-y [float32!] ] draw-ctx!: alias struct! [ dc [ptr-ptr!] From db4e42997dba71104d464e9ad27600dba91d6b2c Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 23 Dec 2019 18:24:17 +0100 Subject: [PATCH 0644/3432] FEAT: adds some functions definition in Direct2D context. --- modules/view/backends/windows/direct2d.reds | 85 +++++++++++++++++---- modules/view/backends/windows/draw.reds | 2 +- modules/view/backends/windows/text-box.reds | 4 +- system/runtime/common.reds | 8 +- 4 files changed, 79 insertions(+), 20 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 4d606fc41a..f06f841189 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -53,13 +53,18 @@ D3DCOLORVALUE: alias struct! [ a [float32!] ] -RECT32!: alias struct! [ +RECT_F!: alias struct! [ left [float32!] top [float32!] right [float32!] bottom [float32!] ] +SIZE_U!: alias struct! [ + width [uint32!] + height [uint32!] +] + D2D1_SIZE_F: alias struct! [ width [float32!] height [float32!] @@ -246,7 +251,7 @@ DrawLine*: alias function! [ DrawRectangle*: alias function! [ this [this!] - rect [RECT32!] + rect [RECT_F!] brush [integer!] strokeWidth [float32!] strokeStyle [integer!] @@ -254,7 +259,7 @@ DrawRectangle*: alias function! [ FillRectangle*: alias function! [ this [this!] - rect [RECT32!] + rect [RECT_F!] brush [integer!] ] @@ -361,6 +366,32 @@ ID2D1GradientStopCollection: alias struct! [ GetExtendMode [integer!] ] +ID2D1Properties: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetPropertyCount [int-ptr!] + GetPropertyName [int-ptr!] + GetPropertyNameLength [int-ptr!] + GetType [int-ptr!] + GetPropertyIndex [int-ptr!] + SetValueByName [int-ptr!] + SetValue [int-ptr!] + GetValueByName [int-ptr!] + GetValue [int-ptr!] + GetValueSize [int-ptr!] + GetSubProperties [int-ptr!] +] + +ID2D1Effect: alias struct! [ + Base [ID2D1Properties value] + SetInput [function! [this [this!] idx [uint32!] input [int-ptr!] invalidate [logic!]]] + SetInputCount [function! [this [this!] count [uint32!] return: [integer!]]] + GetInput [function! [this [this!] idx [uint32!] input [ptr-ptr!]]] + GetInputCount [function! [this [this!] return: [integer!]]] + GetOutput [function! [this [this!] idx [uint!] output [ptr-ptr!]]] +] + IDXGIDevice1: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -593,6 +624,32 @@ ID3D11Device: alias struct! [ GetExceptionMode [integer!] ] +CreateBitmap*: alias function! [ + this [this!] + size [SIZE_U! value] + sourceData [int-ptr!] + pitch [uint32!] + properties [D2D1_BITMAP_PROPERTIES1] + bitmap [ptr-ptr!] + return: [integer!] +] + +CreateEffect*: alias function! [ + this [this!] + effectID [tagGUID] + effect [ptr-ptr!] + return: [integer!] +] + +DrawImage*: alias function! [ + this [this!] + image [int-ptr!] + offset [D2D_POINT_2F] + rect [RECT_F!] + interpola [integer!] + composite [integer!] +] + ID2D1DeviceContext: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -639,7 +696,7 @@ ID2D1DeviceContext: alias struct! [ Flush [integer!] SaveDrawingState [integer!] RestoreDrawingState [integer!] - PushAxisAlignedClip [function! [this [this!] rc [RECT32!] mode [integer!]]] + PushAxisAlignedClip [function! [this [this!] rc [RECT_F!] mode [integer!]]] PopAxisAlignedClip [function! [this [this!]]] Clear [function! [this [this!] color [D3DCOLORVALUE]]] BeginDraw [function! [this [this!]]] @@ -651,16 +708,16 @@ ID2D1DeviceContext: alias struct! [ GetPixelSize [integer!] GetMaximumBitmapSize [integer!] IsSupported [integer!] - CtxCreateBitmap [integer!] - CtxCreateBitmapFromWicBitmap [integer!] + CreateBitmap2 [CreateBitmap*] + CreateBitmapFromWicBitmap2 [integer!] CreateColorContext [integer!] CreateColorContextFromFilename [integer!] CreateColorContextFromWicColorContext [integer!] CreateBitmapFromDxgiSurface [function! [this [this!] surface [int-ptr!] props [D2D1_BITMAP_PROPERTIES1] bitmap [int-ptr!] return: [integer!]]] - CreateEffect [integer!] - CtxCreateGradientStopCollection [integer!] + CreateEffect [CreateEffect*] + CreateGradientStopCollection2 [integer!] CreateImageBrush [integer!] - CtxCreateBitmapBrush [integer!] + CreateBitmapBrush2 [integer!] CreateCommandList [integer!] IsDxgiFormatSupported [integer!] IsBufferPrecisionSupported [integer!] @@ -676,16 +733,16 @@ ID2D1DeviceContext: alias struct! [ GetPrimitiveBlend [integer!] SetUnitMode [integer!] GetUnitMode [integer!] - CtxDrawGlyphRun [integer!] - DrawImage [integer!] + DrawGlyphRun2 [integer!] + DrawImage [DrawImage*] DrawGdiMetafile [integer!] - CtxDrawBitmap [integer!] - CtxPushLayer [integer!] + DrawBitmap2 [integer!] + PushLayer2 [integer!] InvalidateEffectInputRectangle [integer!] GetEffectInvalidRectangleCount [integer!] GetEffectInvalidRectangles [integer!] GetEffectRequiredInputRectangles [integer!] - CtxFillOpacityMask [integer!] + FillOpacityMask2 [integer!] ] ID2D1HwndRenderTarget: alias struct! [ diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 140e0c70b9..7d4e932daf 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -610,7 +610,7 @@ OS-draw-box: func [ /local this [this!] dc [ID2D1DeviceContext] - rc [RECT32! value] + rc [RECT_F! value] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index 8bc0ef7af1..64bafd4ec5 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -389,7 +389,7 @@ txt-box-draw-background: func [ width [integer!] top [integer!] left [integer!] - rc [RECT32!] + rc [RECT_F!] ][ styles: as red-vector! target/4 if any [ @@ -412,7 +412,7 @@ txt-box-draw-background: func [ hits: as DWRITE_HIT_TEST_METRICS line-metrics left: 0 - rc: as RECT32! :left + rc: as RECT_F! :left x: as float32! pos/x y: as float32! pos/y s: GET_BUFFER(styles) diff --git a/system/runtime/common.reds b/system/runtime/common.reds index 6beb179152..49ab253720 100644 --- a/system/runtime/common.reds +++ b/system/runtime/common.reds @@ -44,9 +44,11 @@ Red/System [ ;#define int16! integer! ;#define uint16! integer! -#define uint! integer! -#define long! integer! ;-- 32bit in 32bit OS, 64bit in 64bit OS -#define ulong! integer! +#define uint! integer! +#define int32! integer! +#define uint32! integer! +#define long! integer! ;-- 32bit in 32bit OS, 64bit in 64bit OS +#define ulong! integer! ptr-ptr!: alias struct! [value [int-ptr!]] #define ptr-value! [ptr-ptr! value] From fbc16517be23a977a4188d44e89e48232be01179 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 24 Dec 2019 15:02:52 +0800 Subject: [PATCH 0645/3432] FEAT: implement shape arc --- modules/view/backends/windows/draw.reds | 78 +++++++++++++++------ modules/view/backends/windows/matrix2d.reds | 11 +++ 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 7d4e932daf..58ac9698a3 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -488,49 +488,85 @@ draw-curve: func [ ] OS-draw-shape-curve: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve ctx start end rel? no 3 ] OS-draw-shape-qcurve: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve ctx start end rel? no 2 ] OS-draw-shape-curv: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve ctx start - 1 end rel? yes 3 ] OS-draw-shape-qcurv: func [ - ctx [draw-ctx!] - start [red-pair!] - end [red-pair!] - rel? [logic!] + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + rel? [logic!] ][ draw-curve ctx start - 1 end rel? yes 2 ] OS-draw-shape-arc: func [ - ctx [draw-ctx!] - end [red-pair!] - sweep? [logic!] - large? [logic!] - rel? [logic!] + ctx [draw-ctx!] + end [red-pair!] + sweep? [logic!] + large? [logic!] + rel? [logic!] + /local + item [red-integer!] + p1-x [float32!] + p1-y [float32!] + p2-x [float32!] + p2-y [float32!] + radius-x [float32!] + radius-y [float32!] + theta [float32!] + arc [D2D1_ARC_SEGMENT value] + sthis [this!] + gsink [ID2D1GeometrySink] ][ + ;-- parse arguments + p1-x: ctx/sub/last-pt-x + p1-y: ctx/sub/last-pt-y + p2-x: either rel? [ p1-x + as float32! end/x ][ as float32! end/x ] + p2-y: either rel? [ p1-y + as float32! end/y ][ as float32! end/y ] + ctx/sub/last-pt-x: p2-x + ctx/sub/last-pt-y: p2-y + item: as red-integer! end + 1 + radius-x: get-float32 item + item: item + 1 + radius-y: get-float32 item + item: item + 1 + theta: get-float32 item + + arc/point/x: p2-x + arc/point/y: p2-y + arc/size/width: radius-x + arc/size/height: radius-y + arc/angle: theta + arc/direction: either sweep? [1][0] + arc/arcSize: either large? [1][0] + sthis: as this! ctx/sub/sink + gsink: as ID2D1GeometrySink sthis/vtbl + gsink/AddArc sthis arc ] OS-draw-anti-alias: func [ diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds index b6a9e3904a..a808f6337f 100644 --- a/modules/view/backends/windows/matrix2d.reds +++ b/modules/view/backends/windows/matrix2d.reds @@ -114,6 +114,17 @@ matrix2d: context [ mul t m r ] + transform-point: func [ + m [D2D_MATRIX_3X2_F] + x [float32!] + y [float32!] + px [float32-ptr!] + py [float32-ptr!] + ][ + px/value: (x * m/_11) + (y * m/_21) + m/_31 + py/value: (x * m/_12) + (y * m/_22) + m/_32 + ] + invert: func [ m [D2D_MATRIX_3X2_F] r [D2D_MATRIX_3X2_F] From 5d019793f0063970397365ad7883a50e1dfe9eaf Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 24 Dec 2019 17:29:38 +0800 Subject: [PATCH 0646/3432] FIX: remove no used transformation --- modules/view/backends/windows/matrix2d.reds | 31 ++++++++++----------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds index a808f6337f..ae2d0c551e 100644 --- a/modules/view/backends/windows/matrix2d.reds +++ b/modules/view/backends/windows/matrix2d.reds @@ -15,6 +15,21 @@ Red/System [ ;-- _21 _22 0.0 ;-- _31 _32 1.0 +;-- vector: +;-- i = [_11 _12 0.0]T +;-- j = [_21 _22 0.0]T +;-- j = [_31 _32 1.0]T + +;-- base fomula: +;-- p1 = p * M + +;-- compose transform +;-- 1. translate M1 +;-- 2. rotate M2 +;-- 3; translate M3 +;-- result: +;-- M = M1 * M2 * M3 + matrix2d: context [ identity: func [ m [D2D_MATRIX_3X2_F] @@ -98,22 +113,6 @@ matrix2d: context [ mul t m r ] - affine: func [ - m [D2D_MATRIX_3X2_F] - x [float32!] ;-- x-axis rotate angle - y [float32!] ;-- y-axis rotate angle, but with negative direction - r [D2D_MATRIX_3X2_F] - /local - t [D2D_MATRIX_3X2_F value] - ][ - identity t - t/_11: as float32! cos as float! x - t/_12: as float32! sin as float! x - t/_21: as float32! cos as float! y - t/_22: as float32! sin as float! y - mul t m r - ] - transform-point: func [ m [D2D_MATRIX_3X2_F] x [float32!] From ac50708a663ea8df95907d27b5e82e9357725ae1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 24 Dec 2019 18:07:48 +0100 Subject: [PATCH 0647/3432] FEAT: now LOAD/NEXT uses TRANSCODE/NEXT. --- environment/functions.red | 8 ++++++-- environment/routines.red | 21 +++++++++++++++++++++ runtime/lexer.reds | 5 +---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 4e3407d356..71c7631f24 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -424,13 +424,17 @@ load: function [ ][return none] source: source/3 ] - string! [source: to binary! source] + string! [source: to binary! src: source] ][source] result: case [ part [system/lexer/transcode/part to-string source out trap length] - next [set position system/lexer/transcode/one to-string source out trap] trap [system/lexer/transcode to-string source out trap] + next [ + out: transcode/next source + set position skip any [src source] count-chars source out/2 + return either :all [reduce [out/1]][out/1] + ] 'else [out: transcode source] ] either trap [result][ diff --git a/environment/routines.red b/environment/routines.red index 1a19a4bb7e..787f7a7b7f 100644 --- a/environment/routines.red +++ b/environment/routines.red @@ -114,6 +114,27 @@ as-ipv4: routine [ as-rgba: :as-ipv4 +count-chars: routine [ + "Count UTF-8 encoded characters between two positions in a binary series" + start [binary!] + pos [binary!] + return: [integer!] + /local + p tail [byte-ptr!] + c len [integer!] + s [series!] +][ + s: GET_BUFFER(start) + p: (as byte-ptr! s/offset) + start/head + tail: (as byte-ptr! s/offset) + pos/head + c: len: 0 + while [p < tail][ + p: lexer/decode-utf8-char p :len + c: c + 1 + ] + c +] + ;-- Temporary definition -- read-clipboard: routine [ diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f8f1dc4e56..e4d2e2ed72 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1709,10 +1709,7 @@ lexer: context [ if all [lex/entry = S_PATH state <> T_PATH][ scan-path-item lex start + offset lex/in-pos flags ;-- lex/in-pos could have changed ] - if one? [ - slot: lex/tail - 1 - if any [slot <= lex/head TYPE_OF(slot) <> TYPE_POINT][exit] - ] + if all [one? state <> T_BLK_OP state <> T_PAR_OP state <> T_MSTR_OP][exit] lex/in-pos >= lex/in-end ] From 1220f7ca5c13627643fa6b9999d2a84fcecc99e5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 24 Dec 2019 20:46:44 +0100 Subject: [PATCH 0648/3432] FEAT: split the "word" forms into two valid values. --- runtime/lexer.reds | 29 ++++++++++++++++--- .../source/compiler/regression-test-redc-5.r | 1 - 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e4d2e2ed72..e91c175863 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -31,6 +31,8 @@ lexer: context [ C_FLAG_SHARP: 00800000h C_FLAG_EOF: 00400000h C_FLAG_SIGN: 00200000h + C_FLAG_LESSER: 00100000h + C_FLAG_GREATER: 00080000h C_FLAG_ESC_HEX: 00000200h ;-- percent-escaped mode C_FLAG_NOSTORE: 00000100h ;-- do not store decoded value ] @@ -200,9 +202,9 @@ lexer: context [ C_DIGIT C_DIGIT C_DIGIT C_DIGIT ;-- 36-39 6-9 (C_COLON or C_FLAG_COLON) ;-- 3A : C_SEMICOL ;-- 3B ; - C_LESSER ;-- 3C < + (C_LESSER or C_FLAG_LESSER) ;-- 3C < C_EQUAL ;-- 3D = - C_GREATER ;-- 3E > + (C_GREATER or C_FLAG_GREATER) ;-- 3E > C_WORD ;-- 3F ? C_AT ;-- 40 @ C_ALPHAU C_ALPHAU C_ALPHAU C_ALPHAU ;-- 41-44 A-D @@ -349,6 +351,7 @@ lexer: context [ depth: 0 ;-- recursive calls depth min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer + flags-LG: C_FLAG_LESSER or C_FLAG_GREATER throw-error: func [lex [state!] s e [byte-ptr!] type [integer!] @@ -1009,9 +1012,27 @@ lexer: context [ scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] - type [integer!] - p [byte-ptr!] + cp type class index [integer!] + p pos [byte-ptr!] ][ + if flags and flags-LG = flags-LG [ ;-- handle word cases + p: s + while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < + if p + 1 < e [ + pos: p + p: p + 1 + cp: as-integer p/1 ;-- check for valid tag + class: lex-classes/cp and FFh + index: S_LESSER * (size? character-classes!) + class ;-- simulate transition from S_LESSER + if (as-integer transitions/index) = S_TAG [ ;-- check if valid tag starting is recognized + while [all [p < e p/1 <> #">"]][p: p + 1] ;-- search > + if p < e [ + e: pos ;-- cut the word before < + lex/in-pos: pos ;-- resume scanning from < + ] + ] + ] + ] type: TYPE_WORD if flags and C_FLAG_COLON <> 0 [ case [ diff --git a/tests/source/compiler/regression-test-redc-5.r b/tests/source/compiler/regression-test-redc-5.r index f01fd93308..73ca40a375 100644 --- a/tests/source/compiler/regression-test-redc-5.r +++ b/tests/source/compiler/regression-test-redc-5.r @@ -202,7 +202,6 @@ test --test-- "#3891" --compile-and-run-this-red {probe load "a<=>"} --assert not crashed? - --assert syntax-error? ===end-group=== From 3bf08791f0208761c0a93acca21b8f96c558890c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 25 Dec 2019 00:05:10 +0100 Subject: [PATCH 0649/3432] FEAT: temporarily disables /TRAP refinement for LOAD. --- environment/functions.red | 2 +- tests/source/units/load-test.red | 36 ++++++++++++++++---------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 71c7631f24..fc9e9c37b6 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -429,7 +429,7 @@ load: function [ result: case [ part [system/lexer/transcode/part to-string source out trap length] - trap [system/lexer/transcode to-string source out trap] + ;trap [system/lexer/transcode to-string source out trap] next [ out: transcode/next source set position skip any [src source] count-chars source out/2 diff --git a/tests/source/units/load-test.red b/tests/source/units/load-test.red index 60fc835c99..86f3f8d6c5 100644 --- a/tests/source/units/load-test.red +++ b/tests/source/units/load-test.red @@ -332,11 +332,11 @@ Red [ --assert error? res: try [load "())b"] --assert to logic! find/match form res {*** Syntax Error: (line 1) missing ( at )b^/*** Where} - --test-- "load ) 5" - res: load/trap "())b" - --assert [()] = res/1 - --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing ( at )b^/*** Where} + ;--test-- "load ) 5" + ; res: load/trap "())b" + ; --assert [()] = res/1 + ; --assert "b" = res/2 + ; --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing ( at )b^/*** Where} --test-- "load ) 6" s: "())b" @@ -345,7 +345,7 @@ Red [ --assert error? try [load/all/next s 's] --test-- "load ) 7" - --assert error? try [system/lexer/transcode/one ")" none false] + --assert error? try [transcode/next to-binary ")"] --test-- "load ] 1" --assert error? res: try [load "]"] @@ -363,11 +363,11 @@ Red [ --assert error? res: try [load "[]]b"] --assert to logic! find/match form res {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} - --test-- "load ] 5" - res: load/trap "[]]b" - --assert [[]] = res/1 - --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} + ;--test-- "load ] 5" + ; res: load/trap "[]]b" + ; --assert [[]] = res/1 + ; --assert "b" = res/2 + ; --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) missing [ at ]b^/*** Where} --test-- "load ] 6" s: "[]]b" @@ -376,7 +376,7 @@ Red [ --assert error? try [load/all/next s 's] --test-- "load ] 7" - --assert error? try [system/lexer/transcode/one "]" none false] + --assert error? try [transcode/next "]"] --test-- "load } 1" --assert error? res: try [load "}"] @@ -394,11 +394,11 @@ Red [ --assert error? res: try [load "{}}b"] --assert to logic! find/match form res {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} - --test-- "load } 5" - res: load/trap "{}}b" - --assert [""] = res/1 - --assert "b" = res/2 - --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} + ;--test-- "load } 5" + ; res: load/trap "{}}b" + ; --assert [""] = res/1 + ; --assert "b" = res/2 + ; --assert to logic! find/match form res/3 {*** Syntax Error: (line 1) invalid character at ^}b^/*** Where} --test-- "load } 6" s: "{}}b" @@ -407,7 +407,7 @@ Red [ --assert error? try [load/all/next s 's] --test-- "load } 7" - --assert error? try [system/lexer/transcode/one "}" none false] + --assert error? try [transcode/next "}"] ===end-group=== From b3d26e75a0053e6cfa7e68700d844c8924bbb5dd Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 25 Dec 2019 10:39:41 +0800 Subject: [PATCH 0650/3432] FIX: apply matrix to another not right --- modules/view/backends/windows/draw.reds | 10 +++++++--- modules/view/backends/windows/matrix2d.reds | 11 +++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 58ac9698a3..5c7b79f4e5 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1238,9 +1238,9 @@ OS-matrix-rotate: func [ dc: as ID2D1DeviceContext this/vtbl dc/GetTransform this :m either angle <> as red-integer! center [ - matrix2d/translate :m as float32! center/x as float32! center/y :t - matrix2d/rotate :t as float32! rad :m matrix2d/translate :m as float32! 0 - center/x as float32! 0 - center/y :t + matrix2d/rotate :t as float32! rad :m + matrix2d/translate :m as float32! center/x as float32! center/y :t ][ matrix2d/rotate :m as float32! rad :t ] @@ -1397,7 +1397,9 @@ OS-matrix-set: func [ val [red-integer!] this [this!] dc [ID2D1DeviceContext] + m0 [D2D_MATRIX_3X2_F value] m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] ][ val: as red-integer! block/rs-head blk m/_11: get-float32 val @@ -1409,7 +1411,9 @@ OS-matrix-set: func [ either pen-fill = -1 [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - dc/SetTransform this :m + dc/GetTransform this :m0 + matrix2d/mul m0 m t + dc/SetTransform this :t ][ ;-- TBD exit diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds index ae2d0c551e..d641173f81 100644 --- a/modules/view/backends/windows/matrix2d.reds +++ b/modules/view/backends/windows/matrix2d.reds @@ -26,7 +26,7 @@ Red/System [ ;-- compose transform ;-- 1. translate M1 ;-- 2. rotate M2 -;-- 3; translate M3 +;-- 3. translate M3 ;-- result: ;-- M = M1 * M2 * M3 @@ -42,7 +42,6 @@ matrix2d: context [ m/_32: as float32! 0.0 ] - ;-- c: l * r mul: func [ l [D2D_MATRIX_3X2_F] r [D2D_MATRIX_3X2_F] @@ -67,7 +66,7 @@ matrix2d: context [ identity t t/_31: x t/_32: y - mul t m r + mul m t r ] scale: func [ @@ -81,7 +80,7 @@ matrix2d: context [ identity t t/_11: x t/_22: y - mul t m r + mul m t r ] rotate: func [ @@ -96,7 +95,7 @@ matrix2d: context [ t/_12: as float32! sin as float! angle t/_21: (as float32! 0.0) - t/_12 t/_22: t/_11 - mul t m r + mul m t r ] skew: func [ @@ -110,7 +109,7 @@ matrix2d: context [ identity t t/_12: as float32! tan as float! x t/_21: as float32! tan as float! y - mul t m r + mul m t r ] transform-point: func [ From 2e772654ea765d37abbfbe72195b9ee1a0acd927 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 25 Dec 2019 17:54:33 +0800 Subject: [PATCH 0651/3432] FIX: calc arc's center-y not right --- modules/view/backends/windows/draw.reds | 6 +++--- modules/view/backends/windows/matrix2d.reds | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 5c7b79f4e5..a03d3aa936 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -999,11 +999,11 @@ OS-draw-arc: func [ start-x: as float32! cos as float! angle-begin start-x: cx + (rad-x * start-x) start-y: as float32! sin as float! angle-begin - start-y: cx + (rad-y * start-y) + start-y: cy + (rad-y * start-y) end-x: as float32! cos as float! angle-end end-x: cx + (rad-x * end-x) end-y: as float32! sin as float! angle-end - end-y: cx + (rad-y * end-y) + end-y: cy + (rad-y * end-y) closed?: angle < end @@ -1359,7 +1359,7 @@ OS-matrix-reset: func [ either pen-fill = -1 [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - dc/GetTransform this :m + ;dc/GetTransform this :m matrix2d/identity :m dc/SetTransform this :m ][ diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds index d641173f81..205eb45a59 100644 --- a/modules/view/backends/windows/matrix2d.reds +++ b/modules/view/backends/windows/matrix2d.reds @@ -38,7 +38,7 @@ matrix2d: context [ m/_12: as float32! 0.0 m/_21: as float32! 0.0 m/_22: as float32! 1.0 - m/_31: as float32! 1.0 + m/_31: as float32! 0.0 m/_32: as float32! 0.0 ] From b282f05e07b841e3f751f117b66acf2977e4d768 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 25 Dec 2019 18:05:37 +0800 Subject: [PATCH 0652/3432] TESTS: add matrix tests --- tests/matrix-test.red | 239 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 tests/matrix-test.red diff --git a/tests/matrix-test.red b/tests/matrix-test.red new file mode 100644 index 0000000000..01430917e6 --- /dev/null +++ b/tests/matrix-test.red @@ -0,0 +1,239 @@ +Red [ + Title: "Red draw matrix test" + Author: "bitbegin" + Tabs: 4 + File: %matrix-test.red + Needs: View +] + +drawings: [ + "translate" + [ + pen yellow + line-width 3 + spline 50x50 100x50 50x120 150x150 + translate 200x0 + arc 100x100 60x40 0 270 + translate 0x200 + ellipse 60x40 90x110 + translate -200x0 + curve 50x50 100x50 50x120 150x150 + ] + + "rotate arc" + [ + pen yellow + line-width 3 + arc 100x100 50x50 0 270 + + reset-matrix + rotate 45 100x100 + translate 200x0 + arc 100x100 50x50 0 270 + + reset-matrix + rotate 90 100x100 + translate 0x200 + arc 100x100 50x50 0 270 + + reset-matrix + rotate 135 100x100 + translate 200x200 + arc 100x100 50x50 0 270 + ] + + "scale circle" + [ + pen yellow + line-width 3 + circle 100x100 50 + + reset-matrix + translate -100x-100 + scale 0.5 1.5 + translate 100x100 + translate 200x0 + circle 100x100 50 + + reset-matrix + translate -100x-100 + scale 1.5 0.5 + translate 100x100 + translate 0x200 + circle 100x100 50 + + reset-matrix + translate -100x-100 + scale 1.5 1.5 + translate 100x100 + translate 200x200 + circle 100x100 50 + ] + + "skew box" + [ + pen yellow + line-width 3 + box 50x50 150x150 + + reset-matrix + translate -50x-50 + skew 20 0 + translate 50x50 + translate 200x0 + box 50x50 150x150 + + reset-matrix + translate -50x-50 + skew 0 20 + translate 50x50 + translate 0x200 + box 50x50 150x150 + + reset-matrix + translate -50x-50 + skew 20 + translate 50x50 + translate 200x200 + box 50x50 150x150 + ] + + "matrix ellipse" + [ + pen yellow + line-width 3 + ellipse 50x50 100x100 + + reset-matrix + matrix [1 0 0 1 -100 -100] + matrix [0.5 0 0 1.5 0 0] + matrix [1 0 0 1 100 100] + translate 200x0 + ellipse 50x50 100x100 + + reset-matrix + matrix [1 0 0 1 -100 -100] + matrix [1.5 0 0 0.5 0 0] + matrix [1 0 0 1 100 100] + translate 0x200 + ellipse 50x50 100x100 + + reset-matrix + matrix [1 0 0 1 -100 -100] + matrix [1.5 0 0 1.5 0 0] + matrix [1 0 0 1 100 100] + translate 200x200 + ellipse 50x50 100x100 + ] + + "invert ellipse" + [ + pen yellow + line-width 3 + ellipse 50x50 100x100 + + reset-matrix + matrix [1 0 0 1 -100 -100] + matrix [2 0 0 0.6667 0 0] + matrix [1 0 0 1 100 100] + invert-matrix + translate 200x0 + ellipse 50x50 100x100 + + reset-matrix + translate -100x-100 + matrix [0.6667 0 0 2 0 0] + translate 100x100 + invert-matrix + translate 0x200 + ellipse 50x50 100x100 + + reset-matrix + translate -100x-100 + scale 0.6667 0.6667 + translate 100x100 + invert-matrix + translate 200x200 + ellipse 50x50 100x100 + ] + + "transform graphics" + [ + line-width 3 + pen yellow + line 50x20 150x20 + pen red + polygon 150x20 120x50 60x50 60x100 150x150 + pen green + curve 50x50 100x50 50x120 150x150 + pen black + triangle 100x50 50x150 150x150 + + reset-matrix + transform 100x100 45 1 1 200x0 + pen yellow + line 50x20 150x20 + pen red + polygon 150x20 120x50 60x50 60x100 150x150 + pen green + curve 50x50 100x50 50x120 150x150 + pen black + triangle 100x50 50x150 150x150 + + reset-matrix + transform 100x100 90 1 1 0x200 + pen yellow + line 50x20 150x20 + pen red + polygon 150x20 120x50 60x50 60x100 150x150 + pen green + curve 50x50 100x50 50x120 150x150 + pen black + triangle 100x50 50x150 150x150 + + reset-matrix + transform 100x100 135 0.5 0.5 200x200 + pen yellow + line 50x20 150x20 + pen red + polygon 150x20 120x50 60x50 60x100 150x150 + pen green + curve 50x50 100x50 50x120 150x150 + pen black + triangle 100x50 50x150 150x150 + ] +] + +index: 2 +board: layout [ + below + label: text "" 200 font [size: 16] + canvas: base 400x400 + below + across + btn-prev: button "previous" [ + unless btn-next/enabled? [ btn-next/enabled?: true ] + either index > 2 [ + index: index - 2 + label/text: drawings/(index - 1) + canvas/draw: drawings/:index + show canvas + ][ btn-prev/enabled?: false ] + ] + btn-next: button "next" [ + unless btn-prev/enabled? [ btn-prev/enabled?: true ] + either index < length? drawings [ + index: index + 2 + label/text: drawings/(index - 1) + canvas/draw: drawings/:index + show canvas + ][ btn-next/enabled?: false ] + ] + do [ + label/text: drawings/(index - 1) + canvas/draw: drawings/:index + btn-prev/enabled?: false + ] +] +board/text: "draw matrix demo" +view board From fffd952992fe8a597f350047e29b350e99cb715f Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 25 Dec 2019 11:38:40 +0100 Subject: [PATCH 0653/3432] FEAT: better polyline support. --- modules/view/backends/windows/direct2d.reds | 2 +- modules/view/backends/windows/draw.reds | 115 +++++++++++--------- runtime/definitions.reds | 3 + runtime/platform/COM.reds | 2 - 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index f06f841189..883ed0977d 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -1937,7 +1937,7 @@ draw-text-d2d: func [ this: create-dc-render-target dc rc rt: as ID2D1DCRenderTarget this/vtbl - ;rt/SetTextAntialiasMode this 1 ;-- ClearType + rt/SetTextAntialiasMode this 1 ;-- ClearType rt/BeginDraw this matrix2d/identity m diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index a03d3aa936..f5d20174fc 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -52,7 +52,7 @@ draw-begin: func [ ctx/target: as int-ptr! target dc: as ID2D1DeviceContext this/vtbl - ;dc/SetTextAntialiasMode this 1 ;-- ClearType + dc/SetTextAntialiasMode this 1 ;-- ClearType dc/SetTarget this target/bitmap dc/SetAntialiasMode this 0 ;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE @@ -163,7 +163,7 @@ update-pen-style: func [ prop/endCap: ctx/pen-cap prop/dashCap: ctx/pen-cap prop/lineJoin: ctx/pen-join - prop/miterLimit: as float32! 1.0 + prop/miterLimit: as float32! 10.0 prop/dashStyle: 0 prop/dashOffset: as float32! 0.0 @@ -201,7 +201,6 @@ OS-draw-text: func [ this [this!] dc [ID2D1DeviceContext] layout [this!] - fmt [this!] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -209,8 +208,7 @@ OS-draw-text: func [ layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! OS-text-box-layout as red-object! text as render-target! ctx/target 0 yes ][ - fmt: as this! create-text-format as red-object! text null - create-text-layout text fmt 0 0 + create-text-layout text ctx/text-format 0 0 ] txt-box-draw-background ctx/target pos layout dc/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 @@ -581,6 +579,58 @@ OS-draw-anti-alias: func [ dc/SetAntialiasMode this either on? [0][1] ] +_OS-draw-polygon: func [ + ctx [draw-ctx!] + start [red-pair!] + end [red-pair!] + close? [logic!] + /local + d2d [ID2D1Factory] + path [ptr-value!] + hr [integer!] + pthis [this!] + gpath [ID2D1PathGeometry] + sink [ptr-value!] + sthis [this!] + gsink [ID2D1GeometrySink] + point [D2D_POINT_2F value] + this [this!] + dc [ID2D1DeviceContext] +][ + d2d: as ID2D1Factory d2d-factory/vtbl + hr: d2d/CreatePathGeometry d2d-factory :path + pthis: as this! path/value + gpath: as ID2D1PathGeometry pthis/vtbl + hr: gpath/Open pthis :sink + sthis: as this! sink/value + gsink: as ID2D1GeometrySink sthis/vtbl + + point/x: as float32! start/x + point/y: as float32! start/y + gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + start: start + 1 + while [start <= end] [ + point/x: as float32! start/x + point/y: as float32! start/y + gsink/AddLine sthis point + start: start + 1 + ] + gsink/EndFigure sthis as-integer close? ;-- D2D1_FIGURE_END_CLOSED + + hr: gsink/Close sthis + gsink/Release sthis + + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + if ctx/brush? [ + dc/FillGeometry this as int-ptr! pthis ctx/brush null + ] + if ctx/pen? [ + dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style + ] + gpath/Release pthis +] + OS-draw-line: func [ ctx [draw-ctx!] point [red-pair!] @@ -593,9 +643,10 @@ OS-draw-line: func [ ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - pt0: point + pt0: point + pt1: pt0 + 1 - while [pt1: pt0 + 1 pt1 <= end][ + either pt1 = end [ dc/DrawLine this as float32! pt0/x as float32! pt0/y @@ -603,7 +654,8 @@ OS-draw-line: func [ ctx/pen ctx/pen-width ctx/pen-style - pt0: pt0 + 1 + ][ + _OS-draw-polygon ctx point end no ] ] @@ -674,51 +726,8 @@ OS-draw-polygon: func [ ctx [draw-ctx!] start [red-pair!] end [red-pair!] - /local - d2d [ID2D1Factory] - path [ptr-value!] - hr [integer!] - pthis [this!] - gpath [ID2D1PathGeometry] - sink [ptr-value!] - sthis [this!] - gsink [ID2D1GeometrySink] - point [D2D_POINT_2F value] - this [this!] - dc [ID2D1DeviceContext] ][ - d2d: as ID2D1Factory d2d-factory/vtbl - hr: d2d/CreatePathGeometry d2d-factory :path - pthis: as this! path/value - gpath: as ID2D1PathGeometry pthis/vtbl - hr: gpath/Open pthis :sink - sthis: as this! sink/value - gsink: as ID2D1GeometrySink sthis/vtbl - - point/x: as float32! start/x - point/y: as float32! start/y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW - start: start + 1 - while [start <= end] [ - point/x: as float32! start/x - point/y: as float32! start/y - gsink/AddLine sthis point - start: start + 1 - ] - gsink/EndFigure sthis 1 ;-- D2D1_FIGURE_END_CLOSED - - hr: gsink/Close sthis - gsink/Release sthis - - this: as this! ctx/dc - dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ - dc/FillGeometry this as int-ptr! pthis ctx/brush null - ] - if ctx/pen? [ - dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style - ] - gpath/Release pthis + _OS-draw-polygon ctx start end yes ] spline-delta: 1.0 / 25.0 @@ -945,7 +954,7 @@ OS-draw-font: func [ ctx [draw-ctx!] font [red-object!] ][ - + ctx/text-format: as this! create-text-format font null ] OS-draw-arc: func [ diff --git a/runtime/definitions.reds b/runtime/definitions.reds index a0c3241e69..2e17a9f338 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -171,6 +171,8 @@ Red/System [ BRUSH_TYPE_TEXTURE ] + this!: alias struct! [vtbl [int-ptr!]] + tagPAINTSTRUCT: alias struct! [ hdc [handle!] fErase [integer!] @@ -286,6 +288,7 @@ Red/System [ alpha-pen? [logic!] alpha-brush? [logic!] font-color? [logic!] + text-format [this!] sub [sub-path! value] ] ][ diff --git a/runtime/platform/COM.reds b/runtime/platform/COM.reds index d0fa3501b1..1a33702fe8 100644 --- a/runtime/platform/COM.reds +++ b/runtime/platform/COM.reds @@ -101,8 +101,6 @@ tagSTATSTG: alias struct! [ reserved [integer!] ] -this!: alias struct! [vtbl [int-ptr!]] - interface!: alias struct! [ ptr [this!] ] From 4ec21cb16b7cb8311e48e7907c82590838e8c22d Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 25 Dec 2019 12:58:21 +0100 Subject: [PATCH 0654/3432] FEAT: adds FONT command. --- modules/view/backends/windows/draw.reds | 26 ++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index f5d20174fc..759b3c0f7b 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -43,7 +43,6 @@ draw-begin: func [ ctx/pen-style: 0 ctx/pen?: yes ctx/hwnd: hWnd - ctx/font-color: -1 update-pen-style ctx this: d2d-ctx @@ -183,6 +182,7 @@ OS-draw-pen: func [ if any [ctx/pen-color <> color ctx/pen? = off?][ ctx/pen?: not off? ctx/pen-color: color + unless ctx/font-color? [ctx/font-color: color] ;-- if no font, use pen color for text color if ctx/pen? [ this: as this! ctx/pen brush: as ID2D1SolidColorBrush this/vtbl @@ -201,6 +201,9 @@ OS-draw-text: func [ this [this!] dc [ID2D1DeviceContext] layout [this!] + brush [ID2D1SolidColorBrush] + color? [logic!] + pen [this!] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -208,10 +211,23 @@ OS-draw-text: func [ layout: either TYPE_OF(text) = TYPE_OBJECT [ ;-- text-box! OS-text-box-layout as red-object! text as render-target! ctx/target 0 yes ][ + if null? ctx/text-format [ + ctx/text-format: as this! create-text-format as red-object! text null + ] create-text-layout text ctx/text-format 0 0 ] + color?: no + if ctx/font-color <> ctx/pen-color [ + pen: as this! ctx/pen + brush: as ID2D1SolidColorBrush pen/vtbl + brush/SetColor pen to-dx-color ctx/font-color null + color?: yes + ] txt-box-draw-background ctx/target pos layout dc/DrawTextLayout this as float32! pos/x as float32! pos/y layout ctx/pen 0 + if color? [ + brush/SetColor pen to-dx-color ctx/pen-color null + ] true ] @@ -953,8 +969,16 @@ OS-draw-ellipse: func [ OS-draw-font: func [ ctx [draw-ctx!] font [red-object!] + /local + clr [red-tuple!] ][ ctx/text-format: as this! create-text-format font null + ;-- set font color + clr: as red-tuple! (object/get-values font) + FONT_OBJ_COLOR + if TYPE_OF(clr) = TYPE_TUPLE [ + ctx/font-color: clr/array1 + ctx/font-color?: yes + ] ] OS-draw-arc: func [ From 5d4517b65f60625490db829d9e36f1e4da8f8f7f Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 25 Dec 2019 17:27:38 +0100 Subject: [PATCH 0655/3432] FEAT: add more function definitions in Direct2D context. --- modules/view/backends/windows/direct2d.reds | 26 +++++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 883ed0977d..600d8fce5b 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -65,7 +65,7 @@ SIZE_U!: alias struct! [ height [uint32!] ] -D2D1_SIZE_F: alias struct! [ +SIZE_F!: alias struct! [ width [float32!] height [float32!] ] @@ -88,7 +88,7 @@ D2D1_QUADRATIC_BEZIER_SEGMENT: alias struct! [ D2D1_ARC_SEGMENT: alias struct! [ point [D2D_POINT_2F value] - size [D2D1_SIZE_F value] + size [SIZE_F! value] angle [float32!] direction [integer!] arcSize [integer!] @@ -624,6 +624,14 @@ ID3D11Device: alias struct! [ GetExceptionMode [integer!] ] +CreateSharedBitmap*: alias function! [ + riid [tagGUID] + data [byte-ptr!] + properties [D2D1_BITMAP_PROPERTIES1] + bitmap [ptr-ptr!] + return: [integer!] +] + CreateBitmap*: alias function! [ this [this!] size [SIZE_U! value] @@ -634,6 +642,14 @@ CreateBitmap*: alias function! [ return: [integer!] ] +CreateBitmapFromWicBitmap*: alias function! [ + this [this!] + source [int-ptr!] + properties [D2D1_BITMAP_PROPERTIES1] + bitmap [ptr-ptr!] + return: [integer!] +] + CreateEffect*: alias function! [ this [this!] effectID [tagGUID] @@ -657,13 +673,13 @@ ID2D1DeviceContext: alias struct! [ GetFactory [integer!] CreateBitmap [integer!] CreateBitmapFromWicBitmap [integer!] - CreateSharedBitmap [integer!] + CreateSharedBitmap [CreateSharedBitmap*] CreateBitmapBrush [integer!] CreateSolidColorBrush [CreateSolidColorBrush*] CreateGradientStopCollection [CreateGradientStopCollection*] CreateLinearGradientBrush [integer!] CreateRadialGradientBrush [CreateRadialGradientBrush*] - CreateCompatibleRenderTarget [integer!] + CreateCompatibleRenderTarget [function! [this [this!] size [SIZE_F! value] target [ptr-ptr!] return: [integer!]]] CreateLayer [integer!] CreateMesh [integer!] DrawLine [DrawLine*] @@ -709,7 +725,7 @@ ID2D1DeviceContext: alias struct! [ GetMaximumBitmapSize [integer!] IsSupported [integer!] CreateBitmap2 [CreateBitmap*] - CreateBitmapFromWicBitmap2 [integer!] + CreateBitmapFromWicBitmap2 [CreateBitmapFromWicBitmap*] CreateColorContext [integer!] CreateColorContextFromFilename [integer!] CreateColorContextFromWicColorContext [integer!] From b4c94680148b5ffea36f2eae886d819d6c34248d Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 11:46:05 +0800 Subject: [PATCH 0656/3432] FEAT: support draw image --- modules/view/backends/windows/direct2d.reds | 12 ++++- modules/view/backends/windows/draw.reds | 56 +++++++++++++++++++++ runtime/platform/image-wic.reds | 24 +++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 600d8fce5b..decfe357c8 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -666,6 +666,16 @@ DrawImage*: alias function! [ composite [integer!] ] +DrawBitmap*: alias function! [ + this [this!] + bmp [int-ptr!] + dst [RECT_F!] + opacity [float32!] + mode [integer!] + src [RECT_F!] + trans [int-ptr!] +] + ID2D1DeviceContext: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -752,7 +762,7 @@ ID2D1DeviceContext: alias struct! [ DrawGlyphRun2 [integer!] DrawImage [DrawImage*] DrawGdiMetafile [integer!] - DrawBitmap2 [integer!] + DrawBitmap2 [DrawBitmap*] PushLayer2 [integer!] InvalidateEffectInputRectangle [integer!] GetEffectInvalidRectangleCount [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 759b3c0f7b..e8ffb78888 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1189,8 +1189,64 @@ OS-draw-image: func [ border? [logic!] crop1 [red-pair!] pattern [red-word!] + /local + this [this!] + dc [ID2D1DeviceContext] + ithis [this!] + IB [IUnknown] + bmp [ptr-value!] + bthis [this!] + d2db [IUnknown] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + dst [RECT_F! value] + src [RECT_F! value] + crop2 [red-pair!] ][ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + ithis: OS-image/to-pbgra image + IB: as IUnknown ithis + dc/CreateBitmapFromWicBitmap2 this as int-ptr! ithis null :bmp + bthis: as this! bmp/value + d2db: as IUnknown bthis + either null? start [x: 0 y: 0][x: start/x y: start/y] + case [ + start = end [ + width: IMAGE_WIDTH(image/size) + height: IMAGE_HEIGHT(image/size) + ] + start + 1 = end [ ;-- two control points + width: end/x - x + height: end/y - y + ] + start + 2 = end [0] ;@@ TBD three control points + true [0] ;@@ TBD four control points + ] + + dst/left: as float32! x + dst/top: as float32! y + dst/right: as float32! x + width + dst/bottom: as float32! y + height + + either crop1 <> null [ + crop2: crop1 + 1 + src/left: as float32! crop1/x + src/top: as float32! crop1/y + src/right: as float32! crop1/x + crop2/x + src/bottom: as float32! crop1/y + crop2/y + ;-- D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR + dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 src null + ][ + ;-- D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR + dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 null null + ] + ;-- the bitmap can't be released here, otherwise will crash the app + ;d2db/Release bthis + ;IB/Release ithis ] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 7996f26a72..6ada82f85c 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -878,4 +878,28 @@ OS-image: context [ dst/head: 0 dst ] + + to-pbgra: func [ + image [red-image!] + return: [this!] + /local + this [this!] + IB [IWICBitmap] + IFAC [IWICImagingFactory] + iconv [interface! value] + cthis [this!] + conv [IWICFormatConverter] + bitmap [interface! value] + ][ + this: as this! image/node + IB: as IWICBitmap this/vtbl + IFAC: as IWICImagingFactory wic-factory/vtbl + IFAC/CreateFormatConverter wic-factory :iconv + cthis: as this! iconv/ptr + conv: as IWICFormatConverter cthis/vtbl + conv/Initialize cthis as int-ptr! this as int-ptr! GUID_WICPixelFormat32bppPBGRA 0 null 0.0 0 + IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap + conv/Release cthis + as this! bitmap/ptr + ] ] From efb5403e1d2bcffdc3dc210219684c8ada91097c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 15:33:13 +0800 Subject: [PATCH 0657/3432] FEAT: button image use new image! format (wic) --- modules/view/backends/windows/button.reds | 3 +- runtime/platform/image-gdiplus.reds | 17 +++++++++ runtime/platform/image-wic.reds | 44 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/button.reds b/modules/view/backends/windows/button.reds index 07d0f88c30..942221a485 100644 --- a/modules/view/backends/windows/button.reds +++ b/modules/view/backends/windows/button.reds @@ -80,8 +80,7 @@ init-button: func [ ][ img: img-1 ] - bitmap: 0 - GdipCreateHBITMAPFromBitmap as-integer img/node :bitmap 0 + bitmap: OS-image/to-HBITMAP img ImageList_Add hlist bitmap 0 DeleteObject as handle! bitmap if all [i > 0 i < num][image/delete img] diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 4593f5f67e..394802ae30 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -224,6 +224,12 @@ OS-image: context [ palette [byte-ptr!] return: [integer!] ] + GdipCreateHBITMAPFromBitmap: "GdipCreateHBITMAPFromBitmap" [ + image [integer!] + hbmp [int-ptr!] + background [integer!] + return: [integer!] + ] ] ] @@ -729,4 +735,15 @@ OS-image: context [ dst/node: as node! bmp dst ] + + to-HBITMAP: func [ + image [red-image!] + return: [integer!] + /local + bitmap [integer!] + ][ + bitmap: 0 + GdipCreateHBITMAPFromBitmap as-integer img/node :bitmap 0 + bitmap + ] ] \ No newline at end of file diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 6ada82f85c..d3d0b6040f 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -58,6 +58,16 @@ OS-image: context [ return: [integer!] ] ] + "gdi32.dll" stdcall [ + CreateBitmap: "CreateBitmap" [ + width [integer!] + height [integer!] + planes [integer!] + bitcount [integer!] + lpBits [byte-ptr!] + return: [integer!] + ] + ] ] IWICImagingFactory: alias struct! [ @@ -902,4 +912,38 @@ OS-image: context [ conv/Release cthis as this! bitmap/ptr ] + + to-HBITMAP: func [ + image [red-image!] + return: [integer!] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + rect [RECT! value] + ilock [interface! value] + lthis [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + bitmap [integer!] + ][ + this: as this! image/node + IB: as IWICBitmap this/vtbl + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + rect/x: 0 + rect/y: 0 + rect/w: w + rect/h: h + IB/Lock this rect WICBitmapLockRead :ilock + lthis: as this! ilock/ptr + lock: as IWICBitmapLock lthis/vtbl + size: 0 data: 0 + lock/GetDataPointer lthis :size :data + bitmap: CreateBitmap w h 1 32 as byte-ptr! data + lock/Release lthis + bitmap + ] ] From 0b35d5838b05b511c80dde8165de4293a1673b78 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 15:59:40 +0800 Subject: [PATCH 0658/3432] FIX: improve image! to d2d bitmap performance --- modules/view/backends/windows/direct2d.reds | 2 +- runtime/platform/image-wic.reds | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index decfe357c8..82e37e9b26 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -719,7 +719,7 @@ ID2D1DeviceContext: alias struct! [ GetTags [integer!] PushLayer [integer!] PopLayer [integer!] - Flush [integer!] + Flush [function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!]]] SaveDrawingState [integer!] RestoreDrawingState [integer!] PushAxisAlignedClip [function! [this [this!] rc [RECT_F!] mode [integer!]]] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index d3d0b6040f..4d5e40a578 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -899,7 +899,6 @@ OS-image: context [ iconv [interface! value] cthis [this!] conv [IWICFormatConverter] - bitmap [interface! value] ][ this: as this! image/node IB: as IWICBitmap this/vtbl @@ -908,9 +907,7 @@ OS-image: context [ cthis: as this! iconv/ptr conv: as IWICFormatConverter cthis/vtbl conv/Initialize cthis as int-ptr! this as int-ptr! GUID_WICPixelFormat32bppPBGRA 0 null 0.0 0 - IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap - conv/Release cthis - as this! bitmap/ptr + as this! cthis ] to-HBITMAP: func [ From 2d7f9df998e72b04f9b219f4850bb308e26c0dc2 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 16:04:01 +0800 Subject: [PATCH 0659/3432] FIX: can't release d2d bitmap --- modules/view/backends/windows/draw.reds | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index e8ffb78888..674f75adc6 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1208,10 +1208,10 @@ OS-draw-image: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl ithis: OS-image/to-pbgra image - IB: as IUnknown ithis + IB: as IUnknown ithis/vtbl dc/CreateBitmapFromWicBitmap2 this as int-ptr! ithis null :bmp bthis: as this! bmp/value - d2db: as IUnknown bthis + d2db: as IUnknown bthis/vtbl either null? start [x: 0 y: 0][x: start/x y: start/y] case [ start = end [ @@ -1244,9 +1244,8 @@ OS-draw-image: func [ dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 null null ] - ;-- the bitmap can't be released here, otherwise will crash the app - ;d2db/Release bthis - ;IB/Release ithis + d2db/Release bthis + IB/Release ithis ] From 5a6b0cd489b32387a94012d60a572ec950464b74 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 16:29:32 +0800 Subject: [PATCH 0660/3432] FEAT: base image use new image! format (wic) --- modules/view/backends/windows/base.reds | 6 ++- runtime/platform/image-gdiplus.reds | 11 +++++ runtime/platform/image-wic.reds | 60 ++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 72ff0e2219..91430fd695 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -581,9 +581,13 @@ update-base-image: func [ img [red-image!] width [integer!] height [integer!] + /local + bitmap [integer!] ][ if TYPE_OF(img) = TYPE_IMAGE [ - GdipDrawImageRectI graphic as-integer img/node 0 0 width height + bitmap: OS-image/to-gpbitmap img + GdipDrawImageRectI graphic bitmap 0 0 width height + OS-image/release-gpbitmap bitmap ] ] diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 394802ae30..beba683f6f 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -746,4 +746,15 @@ OS-image: context [ GdipCreateHBITMAPFromBitmap as-integer img/node :bitmap 0 bitmap ] + + to-gpbitmap: func [ + image [red-image!] + return: [integer!] + ][ + as integer! image/node + ] + + release-gpbitmap: func [ + bitmap [integer!] + ][] ] \ No newline at end of file diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 4d5e40a578..4c9897ec50 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -31,6 +31,8 @@ OS-image: context [ GUID_ContainerFormatTiff: declare tagGUID GUID_ContainerFormatGif: declare tagGUID + #define PixelFormat32bppARGB 2498570 + RECT!: alias struct! [ x [integer!] y [integer!] @@ -68,6 +70,21 @@ OS-image: context [ return: [integer!] ] ] + "gdiplus.dll" stdcall [ + GdipCreateBitmapFromScan0: "GdipCreateBitmapFromScan0" [ + width [integer!] + height [integer!] + stride [integer!] + format [integer!] + scan0 [byte-ptr!] + bitmap [int-ptr!] + return: [integer!] + ] + GdipDisposeImage: "GdipDisposeImage" [ + image [integer!] + return: [integer!] + ] + ] ] IWICImagingFactory: alias struct! [ @@ -910,7 +927,7 @@ OS-image: context [ as this! cthis ] - to-HBITMAP: func [ + to-HBITMAP: func [ image [red-image!] return: [integer!] /local @@ -943,4 +960,45 @@ OS-image: context [ lock/Release lthis bitmap ] + + to-gpbitmap: func [ + image [red-image!] + return: [integer!] + /local + this [this!] + IB [IWICBitmap] + w [integer!] + h [integer!] + rect [RECT! value] + ilock [interface! value] + lthis [this!] + lock [IWICBitmapLock] + size [integer!] + data [integer!] + bitmap [integer!] + ][ + this: as this! image/node + IB: as IWICBitmap this/vtbl + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + rect/x: 0 + rect/y: 0 + rect/w: w + rect/h: h + IB/Lock this rect WICBitmapLockRead :ilock + lthis: as this! ilock/ptr + lock: as IWICBitmapLock lthis/vtbl + size: 0 data: 0 + lock/GetDataPointer lthis :size :data + bitmap: 0 + GdipCreateBitmapFromScan0 w h w * 4 PixelFormat32bppARGB as byte-ptr! data :bitmap + lock/Release lthis + bitmap + ] + + release-gpbitmap: func [ + bitmap [integer!] + ][ + GdipDisposeImage bitmap + ] ] From dfdfcee43a4a1ab19611565c68838000cf42ea5b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 26 Dec 2019 16:52:22 +0800 Subject: [PATCH 0661/3432] FIX: capture the window to new image! format --- modules/view/backends/windows/gui.reds | 8 +------- runtime/platform/image-gdiplus.reds | 11 +++++++++++ runtime/platform/image-wic.reds | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 960072fd52..68f2afba28 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -2532,7 +2532,6 @@ OS-to-image: func [ width [integer!] height [integer!] bmp [handle!] - bitmap [integer!] img [red-image!] word [red-word!] size [red-pair!] @@ -2584,12 +2583,7 @@ OS-to-image: func [ ] ] - bitmap: 0 - GdipCreateBitmapFromHBITMAP bmp 0 :bitmap - - either zero? bitmap [img: as red-image! none-value][ - img: image/init-image as red-image! stack/push* as int-ptr! bitmap - ] + img: OS-image/from-HBITMAP as integer! bmp if screen? [DeleteDC mdc] ;-- we delete it in Draw when print window DeleteObject bmp diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index beba683f6f..6180e5c9cb 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -747,6 +747,17 @@ OS-image: context [ bitmap ] + from-HBITMAP: func [ + hBitmap [integer!] + return: [red-image!] + ][ + bitmap: 0 + GdipCreateBitmapFromHBITMAP hBitmap 0 :bitmap + if zero? bitmap [return as red-image! none-value] + + image/init-image as red-image! stack/push* as int-ptr! bitmap + ] + to-gpbitmap: func [ image [red-image!] return: [integer!] diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds index 4c9897ec50..6ccb284595 100644 --- a/runtime/platform/image-wic.reds +++ b/runtime/platform/image-wic.reds @@ -961,6 +961,22 @@ OS-image: context [ bitmap ] + from-HBITMAP: func [ + hBitmap [integer!] + return: [red-image!] + /local + IFAC [IWICImagingFactory] + bitmap [interface! value] + hr [integer!] + ][ + IFAC: as IWICImagingFactory wic-factory/vtbl + hr: IFAC/CreateBitmapFromHBITMAP wic-factory as int-ptr! hBitmap null 0 :bitmap + if hr < 0 [ + return as red-image! none-value + ] + image/init-image as red-image! stack/push* as int-ptr! bitmap/ptr + ] + to-gpbitmap: func [ image [red-image!] return: [integer!] From deca100d7b1e3549291023689e04ee0676855d60 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 26 Dec 2019 12:00:21 +0100 Subject: [PATCH 0662/3432] FEAT: draw on image! --- modules/view/backends/windows/direct2d.reds | 2 +- modules/view/backends/windows/draw.reds | 92 +++++++++++++-------- runtime/definitions.reds | 1 + 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 82e37e9b26..b8367cc9b9 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -644,7 +644,7 @@ CreateBitmap*: alias function! [ CreateBitmapFromWicBitmap*: alias function! [ this [this!] - source [int-ptr!] + source [this!] properties [D2D1_BITMAP_PROPERTIES1] bitmap [ptr-ptr!] return: [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 674f75adc6..e518c608b3 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -35,6 +35,9 @@ draw-begin: func [ clr [red-tuple!] text [red-string!] pos [red-pair! value] + bmp [ptr-value!] + wic-bmp [this!] + IUnk [IUnknown] ][ zero-memory as byte-ptr! ctx size? draw-ctx! ctx/pen-width: as float32! 1.0 @@ -46,11 +49,27 @@ draw-begin: func [ update-pen-style ctx this: d2d-ctx - target: get-hwnd-render-target hWnd + dc: as ID2D1DeviceContext this/vtbl + + either hWnd <> null [ + target: get-hwnd-render-target hWnd + ][ + wic-bmp: OS-image/to-pbgra img + ;-- create a bitmap target + target: as render-target! alloc0 size? render-target! + target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr! + if 0 <> dc/CreateBitmapFromWicBitmap2 this wic-bmp null bmp [ + ;TBD error!!! + probe "CreateBitmapFromWicBitmap2 failed in draw-begin" + return ctx + ] + ctx/image: img/node + target/bitmap: as this! bmp/value + COM_SAFE_RELEASE(IUnk wic-bmp) + ] ctx/dc: as ptr-ptr! this ctx/target: as int-ptr! target - dc: as ID2D1DeviceContext this/vtbl dc/SetTextAntialiasMode this 1 ;-- ClearType dc/SetTarget this target/bitmap dc/SetAntialiasMode this 0 ;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE @@ -59,13 +78,6 @@ draw-begin: func [ matrix2d/identity m dc/SetTransform this :m ;-- set to identity matrix - values: get-face-values hWnd - clr: as red-tuple! values + FACE_OBJ_COLOR - bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1] - if bg-clr <> -1 [ ;-- paint background - dc/Clear this to-dx-color bg-clr null - ] - d3d-clr: to-dx-color ctx/pen-color null brush: 0 dc/CreateSolidColorBrush this d3d-clr null :brush @@ -75,10 +87,19 @@ draw-begin: func [ dc/CreateSolidColorBrush this d3d-clr null :brush ctx/brush: brush - text: as red-string! values + FACE_OBJ_TEXT - if TYPE_OF(text) = TYPE_STRING [ - pos/x: 0 pos/y: 0 - OS-draw-text ctx pos as red-string! get-face-obj hWnd yes + if hWnd <> null [ + values: get-face-values hWnd + clr: as red-tuple! values + FACE_OBJ_COLOR + bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1] + if bg-clr <> -1 [ ;-- paint background + dc/Clear this to-dx-color bg-clr null + ] + + text: as red-string! values + FACE_OBJ_TEXT + if TYPE_OF(text) = TYPE_STRING [ + pos/x: 0 pos/y: 0 + OS-draw-text ctx pos as red-string! get-face-obj hWnd yes + ] ] ctx ] @@ -107,30 +128,35 @@ draw-end: func [ hr [integer!] ][ release-pen-style ctx - rt: as render-target! ctx/target - this: rt/dc + this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl dc/EndDraw this null null dc/SetTarget this null - this: rt/swapchain - sc: as IDXGISwapChain1 this/vtbl - hr: sc/Present this 0 0 - - switch hr [ - COM_S_OK [ValidateRect hWnd null] - DXGI_ERROR_DEVICE_REMOVED - DXGI_ERROR_DEVICE_RESET [ - release-ctx ctx - d2d-release-target rt - ctx/dc: null - SetWindowLong hWnd wc-offset - 24 0 - DX-create-dev - InvalidateRect hWnd null 0 - ] - default [ - 0 ;@@ TBD log error!!! + rt: as render-target! ctx/target + either hWnd <> null [ + this: rt/swapchain + sc: as IDXGISwapChain1 this/vtbl + hr: sc/Present this 0 0 + + switch hr [ + COM_S_OK [ValidateRect hWnd null] + DXGI_ERROR_DEVICE_REMOVED + DXGI_ERROR_DEVICE_RESET [ + release-ctx ctx + d2d-release-target rt + ctx/dc: null + SetWindowLong hWnd wc-offset - 24 0 + DX-create-dev + InvalidateRect hWnd null 0 + ] + default [ + 0 ;@@ TBD log error!!! + ] ] + ][ ;-- draw on image! + ;TBD save rt/bitmap to ctx/image + d2d-release-target rt ] ] @@ -1209,7 +1235,7 @@ OS-draw-image: func [ dc: as ID2D1DeviceContext this/vtbl ithis: OS-image/to-pbgra image IB: as IUnknown ithis/vtbl - dc/CreateBitmapFromWicBitmap2 this as int-ptr! ithis null :bmp + dc/CreateBitmapFromWicBitmap2 this ithis null :bmp bthis: as this! bmp/value d2db: as IUnknown bthis/vtbl either null? start [x: 0 y: 0][x: start/x y: start/y] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 2e17a9f338..1ccfd12545 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -281,6 +281,7 @@ Red/System [ brush-color [integer!] font-color [integer!] bitmap [int-ptr!] + image [int-ptr!] ;-- original image handle scale-ratio [float32!] pen? [logic!] brush? [logic!] From c492e317b36e82283950076f9bfbc2155490b642 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 26 Dec 2019 15:45:14 +0100 Subject: [PATCH 0663/3432] FEAT: minor code refactoring. --- modules/view/backends/macOS/draw.reds | 4 +-- modules/view/backends/test/draw.reds | 4 +-- modules/view/backends/windows/draw-gdi.reds | 4 +-- modules/view/backends/windows/draw.reds | 4 +-- modules/view/draw.red | 28 ++++++++++----------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/view/backends/macOS/draw.reds b/modules/view/backends/macOS/draw.reds index 5590ba0f0e..9e4de369dc 100644 --- a/modules/view/backends/macOS/draw.reds +++ b/modules/view/backends/macOS/draw.reds @@ -1406,7 +1406,7 @@ OS-matrix-transform: func [ OS-matrix-rotate dc pen rotate center ] -OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ +OS-draw-state-push: func [dc [draw-ctx!] state [draw-state!]][ CGContextSaveGState dc/raw state/pen-clr: dc/pen-color state/brush-clr: dc/brush-color @@ -1418,7 +1418,7 @@ OS-matrix-push: func [dc [draw-ctx!] state [draw-state!]][ state/a-brush?: dc/grad-brush? ] -OS-matrix-pop: func [dc [draw-ctx!] state [draw-state!]][ +OS-draw-state-pop: func [dc [draw-ctx!] state [draw-state!]][ CGContextRestoreGState dc/raw dc/pen-color: state/pen-clr dc/brush-color: state/brush-clr diff --git a/modules/view/backends/test/draw.reds b/modules/view/backends/test/draw.reds index a9d3dd1edc..49eda2d4c2 100644 --- a/modules/view/backends/test/draw.reds +++ b/modules/view/backends/test/draw.reds @@ -390,11 +390,11 @@ OS-matrix-transform: func [ ] -OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!]][ +OS-draw-state-push: func [ctx [draw-ctx!] state [draw-state!]][ ] -OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][] +OS-draw-state-pop: func [ctx [draw-ctx!] state [draw-state!]][] OS-matrix-reset: func [ ctx [draw-ctx!] diff --git a/modules/view/backends/windows/draw-gdi.reds b/modules/view/backends/windows/draw-gdi.reds index e351c1a6ab..e2c7447200 100644 --- a/modules/view/backends/windows/draw-gdi.reds +++ b/modules/view/backends/windows/draw-gdi.reds @@ -3432,7 +3432,7 @@ OS-matrix-transform: func [ ] ] -OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!] /local s][ +OS-draw-state-push: func [ctx [draw-ctx!] state [draw-state!] /local s][ s: 0 GdipSaveGraphics ctx/graphics :s state/gstate: s @@ -3446,7 +3446,7 @@ OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!] /local s][ state/a-brush?: ctx/alpha-brush? ] -OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][ +OS-draw-state-pop: func [ctx [draw-ctx!] state [draw-state!]][ GdipRestoreGraphics ctx/graphics state/gstate ctx/pen-join: state/pen-join ctx/pen-cap: state/pen-cap diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index e518c608b3..dd21781c57 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1456,11 +1456,11 @@ OS-matrix-transform: func [ OS-matrix-translate ctx pen-fill translate/x translate/y ] -OS-matrix-push: func [ctx [draw-ctx!] state [draw-state!]][ +OS-draw-state-push: func [ctx [draw-ctx!] state [draw-state!]][ ] -OS-matrix-pop: func [ctx [draw-ctx!] state [draw-state!]][] +OS-draw-state-pop: func [ctx [draw-ctx!] state [draw-state!]][] OS-matrix-reset: func [ ctx [draw-ctx!] diff --git a/modules/view/draw.red b/modules/view/draw.red index 1d6a2b841a..b755b230d6 100644 --- a/modules/view/draw.red +++ b/modules/view/draw.red @@ -878,10 +878,10 @@ Red/System [ ] DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-set-clip DC as red-pair! start as red-pair! value rect? clip-mode parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-set-clip DC as red-pair! start as red-pair! value rect? clip-mode ] @@ -906,10 +906,10 @@ Red/System [ DRAW_FETCH_OPT_VALUE(TYPE_PAIR) DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-matrix-rotate DC sym as red-integer! start as red-pair! cmd - 1 parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-matrix-rotate DC sym as red-integer! start as red-pair! cmd ] @@ -919,10 +919,10 @@ Red/System [ loop 2 [DRAW_FETCH_VALUE_2(TYPE_INTEGER TYPE_FLOAT)] DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-matrix-scale DC sym as red-integer! start as red-integer! cmd - 1 parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-matrix-scale DC sym as red-integer! start as red-integer! cmd ] @@ -933,10 +933,10 @@ Red/System [ point: as red-pair! start DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-matrix-translate DC sym point/x point/y parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-matrix-translate DC sym point/x point/y ] @@ -947,10 +947,10 @@ Red/System [ DRAW_FETCH_OPT_VALUE_2(TYPE_INTEGER TYPE_FLOAT) DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-matrix-skew DC sym as red-integer! start as red-integer! cmd - 1 parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-matrix-skew DC sym as red-integer! start as red-integer! cmd ] @@ -964,7 +964,7 @@ Red/System [ DRAW_FETCH_VALUE(TYPE_PAIR) DRAW_FETCH_OPT_VALUE(TYPE_BLOCK) either pos = cmd [ - OS-matrix-push DC :state + OS-draw-state-push DC :state OS-matrix-transform DC sym @@ -972,7 +972,7 @@ Red/System [ as red-integer! value as red-pair! cmd - 1 parse-draw DC as red-block! cmd catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ][ OS-matrix-transform DC @@ -984,9 +984,9 @@ Red/System [ ] sym = _push [ ;@@ push is a keyword in R/S DRAW_FETCH_VALUE(TYPE_BLOCK) - OS-matrix-push DC :state + OS-draw-state-push DC :state parse-draw DC as red-block! start catch? - OS-matrix-pop DC :state + OS-draw-state-pop DC :state ] sym = matrix [ DRAW_FETCH_OPT_TRANSFORM From 17faea6dc08c9a76fa9f48c44bf8f748408205d7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 26 Dec 2019 16:56:18 +0100 Subject: [PATCH 0664/3432] FEAT: PUSH command in DRAW. --- modules/view/backends/windows/direct2d.reds | 128 ++------------------ modules/view/backends/windows/draw.reds | 63 +++++++++- runtime/definitions.reds | 1 + 3 files changed, 70 insertions(+), 122 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index b8367cc9b9..48a55b6a7e 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -529,7 +529,7 @@ ID2D1Factory: alias struct! [ CreateTransformedGeometry [integer!] CreatePathGeometry [function! [this [this!] pathGeometry [ptr-ptr!] return: [integer!]]] CreateStrokeStyle [function! [this [this!] props [D2D1_STROKE_STYLE_PROPERTIES] dashes [float32-ptr!] count [integer!] style [ptr-ptr!] return: [integer!]]] - CreateDrawingStateBlock [integer!] + CreateDrawingStateBlock [function! [this [this!] desc [this!] param [this!] block [ptr-ptr!] return: [integer!]]] CreateWicBitmapRenderTarget [integer!] CreateHwndRenderTarget [function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [ptr-ptr!] return: [integer!]]] CreateDxgiSurfaceRenderTarget [integer!] @@ -676,7 +676,7 @@ DrawBitmap*: alias function! [ trans [int-ptr!] ] -ID2D1DeviceContext: alias struct! [ +#define ID2D1RenderTarget [ QueryInterface [QueryInterface!] AddRef [AddRef!] Release [Release!] @@ -720,8 +720,8 @@ ID2D1DeviceContext: alias struct! [ PushLayer [integer!] PopLayer [integer!] Flush [function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!]]] - SaveDrawingState [integer!] - RestoreDrawingState [integer!] + SaveDrawingState [function! [this [this!] block [this!]]] + RestoreDrawingState [function! [this [this!] block [this!]]] PushAxisAlignedClip [function! [this [this!] rc [RECT_F!] mode [integer!]]] PopAxisAlignedClip [function! [this [this!]]] Clear [function! [this [this!] color [D3DCOLORVALUE]]] @@ -734,6 +734,10 @@ ID2D1DeviceContext: alias struct! [ GetPixelSize [integer!] GetMaximumBitmapSize [integer!] IsSupported [integer!] +] + +ID2D1DeviceContext: alias struct! [ + ID2D1RenderTarget CreateBitmap2 [CreateBitmap*] CreateBitmapFromWicBitmap2 [CreateBitmapFromWicBitmap*] CreateColorContext [integer!] @@ -772,126 +776,14 @@ ID2D1DeviceContext: alias struct! [ ] ID2D1HwndRenderTarget: alias struct! [ - QueryInterface [QueryInterface!] - AddRef [AddRef!] - Release [Release!] - GetFactory [integer!] - CreateBitmap [integer!] - CreateBitmapFromWicBitmap [integer!] - CreateSharedBitmap [integer!] - CreateBitmapBrush [integer!] - CreateSolidColorBrush [CreateSolidColorBrush*] - CreateGradientStopCollection [CreateGradientStopCollection*] - CreateLinearGradientBrush [integer!] - CreateRadialGradientBrush [CreateRadialGradientBrush*] - CreateCompatibleRenderTarget [integer!] - CreateLayer [integer!] - CreateMesh [integer!] - DrawLine [DrawLine*] - DrawRectangle [DrawRectangle*] - FillRectangle [FillRectangle*] - DrawRoundedRectangle [integer!] - FillRoundedRectangle [integer!] - DrawEllipse [DrawEllipse*] - FillEllipse [FillEllipse*] - DrawGeometry [integer!] - FillGeometry [integer!] - FillMesh [integer!] - FillOpacityMask [integer!] - DrawBitmap [integer!] - DrawText [integer!] - DrawTextLayout [DrawTextLayout*] - DrawGlyphRun [integer!] - SetTransform [SetTransform*] - GetTransform [GetTransform*] - SetAntialiasMode [integer!] - GetAntialiasMode [integer!] - SetTextAntialiasMode [function! [this [this!] mode [integer!]]] - GetTextAntialiasMode [integer!] - SetTextRenderingParams [integer!] - GetTextRenderingParams [integer!] - SetTags [integer!] - GetTags [integer!] - PushLayer [integer!] - PopLayer [integer!] - Flush [integer!] - SaveDrawingState [integer!] - RestoreDrawingState [integer!] - PushAxisAlignedClip [integer!] - PopAxisAlignedClip [integer!] - Clear [function! [this [this!] color [D3DCOLORVALUE]]] - BeginDraw [function! [this [this!]]] - EndDraw [function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!] return: [integer!]]] - GetPixelFormat [integer!] - SetDpi [integer!] - GetDpi [integer!] - GetSize [integer!] - GetPixelSize [integer!] - GetMaximumBitmapSize [integer!] - IsSupported [integer!] + ID2D1RenderTarget CheckWindowState [function! [this [this!] return: [integer!]]] Resize [Resize*] GetHwnd [integer!] ] ID2D1DCRenderTarget: alias struct! [ - QueryInterface [QueryInterface!] - AddRef [AddRef!] - Release [Release!] - GetFactory [integer!] - CreateBitmap [integer!] - CreateBitmapFromWicBitmap [integer!] - CreateSharedBitmap [integer!] - CreateBitmapBrush [integer!] - CreateSolidColorBrush [CreateSolidColorBrush*] - CreateGradientStopCollection [CreateGradientStopCollection*] - CreateLinearGradientBrush [integer!] - CreateRadialGradientBrush [CreateRadialGradientBrush*] - CreateCompatibleRenderTarget [integer!] - CreateLayer [integer!] - CreateMesh [integer!] - DrawLine [DrawLine*] - DrawRectangle [integer!] - FillRectangle [FillRectangle*] - DrawRoundedRectangle [integer!] - FillRoundedRectangle [integer!] - DrawEllipse [DrawEllipse*] - FillEllipse [FillEllipse*] - DrawGeometry [integer!] - FillGeometry [integer!] - FillMesh [integer!] - FillOpacityMask [integer!] - DrawBitmap [integer!] - DrawText [integer!] - DrawTextLayout [DrawTextLayout*] - DrawGlyphRun [integer!] - SetTransform [SetTransform*] - GetTransform [GetTransform*] - SetAntialiasMode [integer!] - GetAntialiasMode [integer!] - SetTextAntialiasMode [function! [this [this!] mode [integer!]]] - GetTextAntialiasMode [integer!] - SetTextRenderingParams [integer!] - GetTextRenderingParams [integer!] - SetTags [integer!] - GetTags [integer!] - PushLayer [integer!] - PopLayer [integer!] - Flush [integer!] - SaveDrawingState [integer!] - RestoreDrawingState [integer!] - PushAxisAlignedClip [integer!] - PopAxisAlignedClip [integer!] - Clear [function! [this [this!] color [D3DCOLORVALUE]]] - BeginDraw [function! [this [this!]]] - EndDraw [function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!] return: [integer!]]] - GetPixelFormat [integer!] - SetDpi [integer!] - GetDpi [integer!] - GetSize [integer!] - GetPixelSize [integer!] - GetMaximumBitmapSize [integer!] - IsSupported [integer!] + ID2D1RenderTarget BindDC [function! [this [this!] hDC [handle!] rect [RECT_STRUCT] return: [integer!]]] ] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index dd21781c57..6260c7522e 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -12,7 +12,17 @@ Red/System [ #include %text-box.reds -draw-state!: alias struct! [unused [integer!]] +draw-state!: alias struct! [ + block [this!] + pen-clr [integer!] + brush-clr [integer!] + pen-join [integer!] + pen-cap [integer!] + pen? [logic!] + brush? [logic!] + a-pen? [logic!] + a-brush? [logic!] +] draw-begin: func [ ctx [draw-ctx!] @@ -1456,11 +1466,56 @@ OS-matrix-transform: func [ OS-matrix-translate ctx pen-fill translate/x translate/y ] -OS-draw-state-push: func [ctx [draw-ctx!] state [draw-state!]][ - +OS-draw-state-push: func [ + ctx [draw-ctx!] + state [draw-state!] + /local + factory [ID2D1Factory] + blk [ptr-value!] + this [this!] + dc [ID2D1DeviceContext] +][ + factory: as ID2D1Factory d2d-factory/vtbl + if 0 <> factory/CreateDrawingStateBlock d2d-factory null null :blk [ + ;TBD error!!! + probe "OS-draw-state-push failed" + exit + ] + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/SaveDrawingState this as this! blk/value + state/block: as this! blk/value + state/pen-clr: ctx/pen-color + state/brush-clr: ctx/brush-color + state/pen-join: ctx/pen-join + state/pen-cap: ctx/pen-cap + state/pen?: ctx/pen? + state/brush?: ctx/brush? + state/a-pen?: ctx/alpha-pen? + state/a-brush?: ctx/alpha-brush? ] -OS-draw-state-pop: func [ctx [draw-ctx!] state [draw-state!]][] +OS-draw-state-pop: func [ + ctx [draw-ctx!] + state [draw-state!] + /local + this [this!] + dc [ID2D1DeviceContext] + IUnk [IUnknown] +][ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/RestoreDrawingState this state/block + COM_SAFE_RELEASE(IUnk state/block) + ctx/pen-color: state/pen-clr + ctx/brush-color: state/brush-clr + ctx/pen-join: state/pen-join + ctx/pen-cap: state/pen-cap + ctx/pen?: state/pen? + ctx/brush?: state/brush? + ctx/alpha-pen?: state/a-pen? + ctx/alpha-brush?: state/a-brush? +] OS-matrix-reset: func [ ctx [draw-ctx!] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 1ccfd12545..6816fce75d 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -290,6 +290,7 @@ Red/System [ alpha-brush? [logic!] font-color? [logic!] text-format [this!] + state [this!] ;-- current draw state sub [sub-path! value] ] ][ From a411913c52db0e7faaeee5d4c5328087a24247a3 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 27 Dec 2019 10:33:57 +0100 Subject: [PATCH 0665/3432] FEAT: preliminary work for the bitmap pen and brush. --- modules/view/backends/windows/direct2d.reds | 32 +++++++++++++- modules/view/backends/windows/draw.reds | 47 +++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 48a55b6a7e..35467d032b 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -195,6 +195,24 @@ DXGI_SWAP_CHAIN_DESC1: alias struct! [ Flags [integer!] ] +#enum D2D1_EXTEND_MODE [ + D2D1_EXTEND_MODE_CLAMP + D2D1_EXTEND_MODE_WRAP + D2D1_EXTEND_MODE_MIRROR + D2D1_EXTEND_MODE_FORCE_DWORD: -1 +] + +D2D1_BITMAP_BRUSH_PROPERTIES1: alias struct! [ + extendModeX [D2D1_EXTEND_MODE] + extendModeY [D2D1_EXTEND_MODE] + interpolationMode [integer!] +] + +D2D1_BRUSH_PROPERTIES: alias struct! [ + opacity [float32!] + transform [D2D_MATRIX_3X2_F value] +] + D2D1_BITMAP_PROPERTIES1: alias struct! [ format [integer!] alphaMode [integer!] @@ -625,6 +643,7 @@ ID3D11Device: alias struct! [ ] CreateSharedBitmap*: alias function! [ + this [this!] riid [tagGUID] data [byte-ptr!] properties [D2D1_BITMAP_PROPERTIES1] @@ -632,6 +651,15 @@ CreateSharedBitmap*: alias function! [ return: [integer!] ] +CreateBitmapBrush*: alias function! [ + this [this!] + bitmap [this!] + properties [D2D1_BITMAP_BRUSH_PROPERTIES1] + brushProp [D2D1_BRUSH_PROPERTIES] + bitmap [ptr-ptr!] + return: [integer!] +] + CreateBitmap*: alias function! [ this [this!] size [SIZE_U! value] @@ -684,7 +712,7 @@ DrawBitmap*: alias function! [ CreateBitmap [integer!] CreateBitmapFromWicBitmap [integer!] CreateSharedBitmap [CreateSharedBitmap*] - CreateBitmapBrush [integer!] + CreateBitmapBrush [CreateBitmapBrush*] CreateSolidColorBrush [CreateSolidColorBrush*] CreateGradientStopCollection [CreateGradientStopCollection*] CreateLinearGradientBrush [integer!] @@ -747,7 +775,7 @@ ID2D1DeviceContext: alias struct! [ CreateEffect [CreateEffect*] CreateGradientStopCollection2 [integer!] CreateImageBrush [integer!] - CreateBitmapBrush2 [integer!] + CreateBitmapBrush2 [CreateBitmapBrush*] CreateCommandList [integer!] IsDxgiFormatSupported [integer!] IsBufferPrecisionSupported [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 6260c7522e..38527d1217 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1292,8 +1292,55 @@ OS-draw-brush-bitmap: func [ crop-2 [red-pair!] mode [red-word!] brush? [logic!] + /local + x [integer!] + y [integer!] + width [integer!] + height [integer!] + wrap-x [integer!] + wrap-y [integer!] + result [integer!] + props [D2D1_BITMAP_BRUSH_PROPERTIES1 value] ][ + width: OS-image/width? img/node + height: OS-image/height? img/node + either crop-1 = null [ + x: 0 + y: 0 + ][ + x: crop-1/x + y: crop-1/y + ] + either crop-2 = null [ + width: width - x + height: height - y + ][ + width: either ( x + crop-2/x ) > width [ width - x ][ crop-2/x ] + height: either ( y + crop-2/y ) > height [ height - y ][ crop-2/y ] + ] + + wrap-x: D2D1_EXTEND_MODE_WRAP + wrap-y: D2D1_EXTEND_MODE_WRAP + unless mode = null [ + wrap: symbol/resolve mode/symbol + case [ + wrap = flip-x [ wrap-x: D2D1_EXTEND_MODE_MIRROR ] + wrap = flip-y [ wrap-y: D2D1_EXTEND_MODE_MIRROR ] + wrap = flip-xy [ + wrap-x: D2D1_EXTEND_MODE_MIRROR + wrap-y: D2D1_EXTEND_MODE_MIRROR + ] + wrap = clamp [ + wrap-x: D2D1_EXTEND_MODE_CLAMP + wrap-y: D2D1_EXTEND_MODE_CLAMP + ] + true [0] + ] + ] + props/extendModeX: wrap-x + props/extendModeY: wrap-y + props/interpolationMode: 1 ;-- MODE_LINEAR ] OS-draw-brush-pattern: func [ From 51f81e71cab32f86868b837656028d497230dc83 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 27 Dec 2019 12:34:11 +0100 Subject: [PATCH 0666/3432] FEAT: adds bitmap pen and brush. --- modules/view/backends/windows/direct2d.reds | 67 +++++----- modules/view/backends/windows/draw-gdi.reds | 12 +- modules/view/backends/windows/draw.reds | 129 ++++++++++++-------- modules/view/backends/windows/text-box.reds | 6 +- runtime/definitions.reds | 11 +- 5 files changed, 127 insertions(+), 98 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 35467d032b..a4be3a8278 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -161,16 +161,6 @@ D2D1_HWND_RENDER_TARGET_PROPERTIES: alias struct! [ presentOptions [integer!] ] -D2D1_BRUSH_PROPERTIES: alias struct! [ - opacity [float32!] - transform._11 [float32!] - transform._12 [float32!] - transform._21 [float32!] - transform._22 [float32!] - transform._31 [float32!] - transform._32 [float32!] -] - D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES: alias struct! [ center.x [float32!] center.y [float32!] @@ -203,14 +193,21 @@ DXGI_SWAP_CHAIN_DESC1: alias struct! [ ] D2D1_BITMAP_BRUSH_PROPERTIES1: alias struct! [ - extendModeX [D2D1_EXTEND_MODE] - extendModeY [D2D1_EXTEND_MODE] - interpolationMode [integer!] + extendModeX [D2D1_EXTEND_MODE] + extendModeY [D2D1_EXTEND_MODE] + interpolationMode [integer!] +] + +D2D1_IMAGE_BRUSH_PROPERTIES: alias struct! [ + sourceRectangle [RECT_F! value] + extendModeX [D2D1_EXTEND_MODE] + extendModeY [D2D1_EXTEND_MODE] + interpolationMode [integer!] ] D2D1_BRUSH_PROPERTIES: alias struct! [ - opacity [float32!] - transform [D2D_MATRIX_3X2_F value] + opacity [float32!] + transform [D2D_MATRIX_3X2_F value] ] D2D1_BITMAP_PROPERTIES1: alias struct! [ @@ -233,7 +230,7 @@ CreateSolidColorBrush*: alias function! [ this [this!] color [D3DCOLORVALUE] properties [D2D1_BRUSH_PROPERTIES] - brush [int-ptr!] + brush [ptr-ptr!] return: [integer!] ] @@ -242,7 +239,7 @@ CreateRadialGradientBrush*: alias function! [ gprops [D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES] props [D2D1_BRUSH_PROPERTIES] stops [integer!] - brush [int-ptr!] + brush [ptr-ptr!] return: [integer!] ] @@ -262,7 +259,7 @@ DrawLine*: alias function! [ pt0.y [float32!] pt1.x [float32!] pt1.y [float32!] - brush [integer!] + brush [this!] width [float32!] style [integer!] ] @@ -270,7 +267,7 @@ DrawLine*: alias function! [ DrawRectangle*: alias function! [ this [this!] rect [RECT_F!] - brush [integer!] + brush [this!] strokeWidth [float32!] strokeStyle [integer!] ] @@ -278,13 +275,13 @@ DrawRectangle*: alias function! [ FillRectangle*: alias function! [ this [this!] rect [RECT_F!] - brush [integer!] + brush [this!] ] DrawEllipse*: alias function! [ this [this!] ellipse [D2D1_ELLIPSE] - brush [integer!] + brush [this!] width [float32!] style [integer!] ] @@ -292,7 +289,7 @@ DrawEllipse*: alias function! [ FillEllipse*: alias function! [ this [this!] ellipse [D2D1_ELLIPSE] - brush [integer!] + brush [this!] ] DrawTextLayout*: alias function! [ @@ -300,7 +297,7 @@ DrawTextLayout*: alias function! [ x [float32!] y [float32!] layout [this!] - brush [integer!] + brush [this!] options [integer!] ] @@ -651,12 +648,21 @@ CreateSharedBitmap*: alias function! [ return: [integer!] ] +CreateImageBrush*: alias function! [ + this [this!] + bitmap [this!] + properties [D2D1_IMAGE_BRUSH_PROPERTIES] + brushProp [D2D1_BRUSH_PROPERTIES] + brush [ptr-ptr!] + return: [integer!] +] + CreateBitmapBrush*: alias function! [ this [this!] bitmap [this!] properties [D2D1_BITMAP_BRUSH_PROPERTIES1] brushProp [D2D1_BRUSH_PROPERTIES] - bitmap [ptr-ptr!] + brush [ptr-ptr!] return: [integer!] ] @@ -727,8 +733,8 @@ DrawBitmap*: alias function! [ FillRoundedRectangle [integer!] DrawEllipse [DrawEllipse*] FillEllipse [FillEllipse*] - DrawGeometry [function! [this [this!] geometry [int-ptr!] brush [integer!] strokeWidth [float32!] style [integer!] return: [integer!]]] - FillGeometry [function! [this [this!] geometry [int-ptr!] brush [integer!] opacityBrush [integer!] return: [integer!]]] + DrawGeometry [function! [this [this!] geometry [int-ptr!] brush [this!] strokeWidth [float32!] style [integer!] return: [integer!]]] + FillGeometry [function! [this [this!] geometry [int-ptr!] brush [this!] opacityBrush [this!] return: [integer!]]] FillMesh [integer!] FillOpacityMask [integer!] DrawBitmap [integer!] @@ -774,7 +780,7 @@ ID2D1DeviceContext: alias struct! [ CreateBitmapFromDxgiSurface [function! [this [this!] surface [int-ptr!] props [D2D1_BITMAP_PROPERTIES1] bitmap [int-ptr!] return: [integer!]]] CreateEffect [CreateEffect*] CreateGradientStopCollection2 [integer!] - CreateImageBrush [integer!] + CreateImageBrush [CreateImageBrush*] CreateBitmapBrush2 [CreateBitmapBrush*] CreateCommandList [integer!] IsDxgiFormatSupported [integer!] @@ -1871,7 +1877,7 @@ draw-text-d2d: func [ obj [IUnknown] rt [ID2D1DCRenderTarget] dwrite [IDWriteFactory] - brush [integer!] + brush [ptr-value!] color [red-tuple!] clr [integer!] m [D2D_MATRIX_3X2_F value] @@ -1895,12 +1901,11 @@ draw-text-d2d: func [ ][ 0 ;-- black ] - brush: 0 rt/CreateSolidColorBrush this to-dx-color clr null null :brush - rt/DrawTextLayout this as float32! 0.0 as float32! 0.0 layout brush 0 + rt/DrawTextLayout this as float32! 0.0 as float32! 0.0 layout as this! brush/value 0 rt/EndDraw this null null - this2: as this! brush + this2: as this! brush/value COM_SAFE_RELEASE(obj this2) COM_SAFE_RELEASE(obj layout) COM_SAFE_RELEASE(obj fmt) diff --git a/modules/view/backends/windows/draw-gdi.reds b/modules/view/backends/windows/draw-gdi.reds index e2c7447200..d1bb9fa5f2 100644 --- a/modules/view/backends/windows/draw-gdi.reds +++ b/modules/view/backends/windows/draw-gdi.reds @@ -164,7 +164,7 @@ update-gdiplus-brush: func [ctx [draw-ctx!] /local handle [integer!]][ GdipDeleteBrush ctx/gp-brush ctx/gp-brush: 0 ] - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipCreateSolidFill to-gdiplus-color-fixed ctx/brush-color :handle ctx/gp-brush: handle ] @@ -1388,7 +1388,7 @@ OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon either ctx/other/GDI+? [ check-gradient-poly ctx ctx/other/edges 3 check-texture-poly ctx ctx/other/edges 3 - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipFillPolygonI ctx/graphics ctx/gp-brush @@ -1434,7 +1434,7 @@ OS-draw-polygon: func [ either ctx/other/GDI+? [ check-gradient-poly ctx ctx/other/edges nb check-texture-poly ctx ctx/other/edges nb - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipFillPolygonI ctx/graphics ctx/gp-brush @@ -1477,7 +1477,7 @@ OS-draw-spline: func [ unless ctx/other/GDI+? [update-gdiplus-modes ctx] ;-- force to use GDI+ - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipFillClosedCurveI ctx/graphics ctx/gp-brush @@ -1501,7 +1501,7 @@ do-draw-ellipse: func [ ][ either ctx/other/GDI+? [ check-gradient-ellipse ctx x y width height - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipFillEllipseI ctx/graphics ctx/gp-brush @@ -1705,7 +1705,7 @@ OS-draw-arc: func [ either ctx/other/GDI+? [ either closed? [ - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ GdipFillPieI ctx/graphics ctx/gp-brush diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 38527d1217..2f2afe54a3 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -18,10 +18,15 @@ draw-state!: alias struct! [ brush-clr [integer!] pen-join [integer!] pen-cap [integer!] - pen? [logic!] - brush? [logic!] - a-pen? [logic!] - a-brush? [logic!] + pen-type [integer!] + brush-type [integer!] +] + +#enum DRAW-BRUSH-TYPE! [ + DRAW_BRUSH_NONE + DRAW_BRUSH_COLOR + DRAW_BRUSH_IMAGE + DRAW_BRUSH_GRADIENT ] draw-begin: func [ @@ -36,7 +41,7 @@ draw-begin: func [ dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] bg-clr [integer!] - brush [integer!] + brush [ptr-value!] target [render-target!] brushes [int-ptr!] pbrush [ID2D1SolidColorBrush] @@ -54,7 +59,7 @@ draw-begin: func [ ctx/pen-join: D2D1_LINE_JOIN_MITER ctx/pen-cap: D2D1_CAP_STYLE_FLAT ctx/pen-style: 0 - ctx/pen?: yes + ctx/pen-type: DRAW_BRUSH_COLOR ctx/hwnd: hWnd update-pen-style ctx @@ -89,13 +94,11 @@ draw-begin: func [ dc/SetTransform this :m ;-- set to identity matrix d3d-clr: to-dx-color ctx/pen-color null - brush: 0 dc/CreateSolidColorBrush this d3d-clr null :brush - ctx/pen: brush + ctx/pen: as this! brush/value - brush: 0 dc/CreateSolidColorBrush this d3d-clr null :brush - ctx/brush: brush + ctx/brush: as this! brush/value if hWnd <> null [ values: get-face-values hWnd @@ -118,10 +121,9 @@ release-ctx: func [ ctx [draw-ctx!] /local IUnk [IUnknown] - this [this!] ][ - COM_SAFE_RELEASE_OBJ(IUnk ctx/pen) - COM_SAFE_RELEASE_OBJ(IUnk ctx/brush) + COM_SAFE_RELEASE(IUnk ctx/pen) + COM_SAFE_RELEASE(IUnk ctx/brush) ] draw-end: func [ @@ -215,11 +217,11 @@ OS-draw-pen: func [ this [this!] brush [ID2D1SolidColorBrush] ][ - if any [ctx/pen-color <> color ctx/pen? = off?][ - ctx/pen?: not off? - ctx/pen-color: color + if any [ctx/pen-color <> color ctx/pen-type = as-integer off?][ + ctx/pen-type: as-integer not off? unless ctx/font-color? [ctx/font-color: color] ;-- if no font, use pen color for text color - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ + ctx/pen-color: color this: as this! ctx/pen brush: as ID2D1SolidColorBrush this/vtbl brush/SetColor this to-dx-color color null @@ -323,10 +325,10 @@ OS-draw-shape-endpath: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillGeometry this as int-ptr! pthis ctx/brush null ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -674,10 +676,10 @@ _OS-draw-polygon: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillGeometry this as int-ptr! pthis ctx/brush null ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -720,10 +722,10 @@ OS-draw-fill-pen: func [ this [this!] brush [ID2D1SolidColorBrush] ][ - if any [ctx/brush-color <> color ctx/brush? = off?][ - ctx/brush?: not off? - ctx/brush-color: color - if ctx/brush? [ + if any [ctx/brush-color <> color ctx/brush-type = as-integer off?][ + ctx/brush-type: as-integer not off? + if ctx/brush-type <> DRAW_BRUSH_NONE [ + ctx/brush-color: color this: as this! ctx/brush brush: as ID2D1SolidColorBrush this/vtbl brush/SetColor this to-dx-color color null @@ -759,10 +761,10 @@ OS-draw-box: func [ rc/bottom: as float32! lower/y rc/left: as float32! upper/x rc/top: as float32! upper/y - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillRectangle this rc ctx/brush ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -909,10 +911,10 @@ OS-draw-spline: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillGeometry this as int-ptr! pthis ctx/brush null ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -946,10 +948,10 @@ do-draw-ellipse: func [ ellipse/y: cy + ry ellipse/radiusX: rx ellipse/radiusY: ry - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillEllipse this ellipse ctx/brush ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -1102,10 +1104,10 @@ OS-draw-arc: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillGeometry this as int-ptr! pthis ctx/brush null ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1174,10 +1176,10 @@ OS-draw-curve: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - if ctx/brush? [ + if ctx/brush-type <> DRAW_BRUSH_NONE [ dc/FillGeometry this as int-ptr! pthis ctx/brush null ] - if ctx/pen? [ + if ctx/pen-type <> DRAW_BRUSH_NONE [ dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1293,14 +1295,22 @@ OS-draw-brush-bitmap: func [ mode [red-word!] brush? [logic!] /local - x [integer!] - y [integer!] width [integer!] height [integer!] + x [integer!] + y [integer!] + xx [integer!] + yy [integer!] + wrap [integer!] wrap-x [integer!] wrap-y [integer!] result [integer!] - props [D2D1_BITMAP_BRUSH_PROPERTIES1 value] + props [D2D1_IMAGE_BRUSH_PROPERTIES value] + this [this!] + dc [ID2D1DeviceContext] + ithis [this!] + bmp [ptr-value!] + brush [ptr-value!] ][ width: OS-image/width? img/node height: OS-image/height? img/node @@ -1312,11 +1322,13 @@ OS-draw-brush-bitmap: func [ y: crop-1/y ] either crop-2 = null [ - width: width - x - height: height - y + xx: width + yy: height ][ - width: either ( x + crop-2/x ) > width [ width - x ][ crop-2/x ] - height: either ( y + crop-2/y ) > height [ height - y ][ crop-2/y ] + xx: crop-2/x + yy: crop-2/y + if xx > width [xx: width] + if yy > height [yy: height] ] wrap-x: D2D1_EXTEND_MODE_WRAP @@ -1338,9 +1350,26 @@ OS-draw-brush-bitmap: func [ ] ] + props/sourceRectangle/left: as float32! x + props/sourceRectangle/top: as float32! y + props/sourceRectangle/right: as float32! xx + props/sourceRectangle/bottom: as float32! yy props/extendModeX: wrap-x props/extendModeY: wrap-y props/interpolationMode: 1 ;-- MODE_LINEAR + + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + ithis: OS-image/to-pbgra img + dc/CreateBitmapFromWicBitmap2 this ithis null :bmp + dc/CreateImageBrush this as this! bmp/value :props null :brush + either brush? [ + ctx/brush: brush + ctx/brush-type: DRAW_BRUSH_IMAGE + ][ + ctx/pen: brush + ctx/pen-type: DRAW_BRUSH_IMAGE + ] ] OS-draw-brush-pattern: func [ @@ -1355,7 +1384,6 @@ OS-draw-brush-pattern: func [ ] - OS-draw-grad-pen-old: func [ ctx [draw-ctx!] type [integer!] @@ -1364,7 +1392,7 @@ OS-draw-grad-pen-old: func [ count [integer!] ;-- number of the colors brush? [logic!] ][ - + ;Deprecated ] OS-draw-grad-pen: func [ @@ -1536,10 +1564,8 @@ OS-draw-state-push: func [ state/brush-clr: ctx/brush-color state/pen-join: ctx/pen-join state/pen-cap: ctx/pen-cap - state/pen?: ctx/pen? - state/brush?: ctx/brush? - state/a-pen?: ctx/alpha-pen? - state/a-brush?: ctx/alpha-brush? + state/pen-type: ctx/pen-type + state/brush-type: ctx/brush-type ] OS-draw-state-pop: func [ @@ -1558,10 +1584,9 @@ OS-draw-state-pop: func [ ctx/brush-color: state/brush-clr ctx/pen-join: state/pen-join ctx/pen-cap: state/pen-cap - ctx/pen?: state/pen? - ctx/brush?: state/brush? - ctx/alpha-pen?: state/a-pen? - ctx/alpha-brush?: state/a-brush? + ctx/pen-type: state/pen-type + ctx/brush-type: state/brush-type + ;TBD: set pen and brush ] OS-matrix-reset: func [ diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds index 64bafd4ec5..b4c2877535 100644 --- a/modules/view/backends/windows/text-box.reds +++ b/modules/view/backends/windows/text-box.reds @@ -41,7 +41,7 @@ OS-text-box-color: func [ rt: as render-target! target this: rt/dc dc: as ID2D1DeviceContext this/vtbl - dc/CreateSolidColorBrush this to-dx-color color null null :brush + dc/CreateSolidColorBrush this to-dx-color color null null as ptr-ptr! :brush put-brush target + 1 color brush ] @@ -73,7 +73,7 @@ OS-text-box-background: func [ if zero? brush [ this: rt/dc dc: as ID2D1DeviceContext this/vtbl - dc/CreateSolidColorBrush this to-dx-color color null null :brush + dc/CreateSolidColorBrush this to-dx-color color null null as ptr-ptr! :brush put-brush target + 1 color brush ] vector/rs-append-int cache pos @@ -430,7 +430,7 @@ txt-box-draw-background: func [ rc/bottom: as float32! top + height rc/top: as float32! top rc/left: as float32! left - dc/FillRectangle this rc p/3 + dc/FillRectangle this rc as this! p/3 hit: hit + 1 ] p: p + 3 diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 6816fce75d..eb4dfdffe3 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -172,6 +172,7 @@ Red/System [ ] this!: alias struct! [vtbl [int-ptr!]] + com-ptr!: alias struct! [value [this!]] tagPAINTSTRUCT: alias struct! [ hdc [handle!] @@ -271,8 +272,8 @@ Red/System [ dc [ptr-ptr!] target [int-ptr!] hwnd [int-ptr!] ;-- Window's handle - pen [integer!] - brush [integer!] + pen [this!] + brush [this!] pen-join [integer!] pen-cap [integer!] pen-width [float32!] @@ -283,11 +284,9 @@ Red/System [ bitmap [int-ptr!] image [int-ptr!] ;-- original image handle scale-ratio [float32!] - pen? [logic!] - brush? [logic!] + pen-type [integer!] + brush-type [integer!] on-image? [logic!] ;-- drawing on image? - alpha-pen? [logic!] - alpha-brush? [logic!] font-color? [logic!] text-format [this!] state [this!] ;-- current draw state From 30a42b1e61744132a5451af0befad876202ce5de Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 27 Dec 2019 16:17:35 +0100 Subject: [PATCH 0667/3432] FIX: crashes when using bitmap brush. --- modules/view/backends/windows/direct2d.reds | 6 +++++- modules/view/backends/windows/draw.reds | 13 ++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index a4be3a8278..cc8c3aa633 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -199,7 +199,11 @@ D2D1_BITMAP_BRUSH_PROPERTIES1: alias struct! [ ] D2D1_IMAGE_BRUSH_PROPERTIES: alias struct! [ - sourceRectangle [RECT_F! value] + ;sourceRectangle [RECT_F! value] + left [float32!] + top [float32!] + right [float32!] + bottom [float32!] extendModeX [D2D1_EXTEND_MODE] extendModeY [D2D1_EXTEND_MODE] interpolationMode [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 2f2afe54a3..4757ee3db9 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1304,7 +1304,6 @@ OS-draw-brush-bitmap: func [ wrap [integer!] wrap-x [integer!] wrap-y [integer!] - result [integer!] props [D2D1_IMAGE_BRUSH_PROPERTIES value] this [this!] dc [ID2D1DeviceContext] @@ -1350,10 +1349,10 @@ OS-draw-brush-bitmap: func [ ] ] - props/sourceRectangle/left: as float32! x - props/sourceRectangle/top: as float32! y - props/sourceRectangle/right: as float32! xx - props/sourceRectangle/bottom: as float32! yy + props/left: as float32! x + props/top: as float32! y + props/right: as float32! xx + props/bottom: as float32! yy props/extendModeX: wrap-x props/extendModeY: wrap-y props/interpolationMode: 1 ;-- MODE_LINEAR @@ -1364,10 +1363,10 @@ OS-draw-brush-bitmap: func [ dc/CreateBitmapFromWicBitmap2 this ithis null :bmp dc/CreateImageBrush this as this! bmp/value :props null :brush either brush? [ - ctx/brush: brush + ctx/brush: as this! brush/value ctx/brush-type: DRAW_BRUSH_IMAGE ][ - ctx/pen: brush + ctx/pen: as this! brush/value ctx/pen-type: DRAW_BRUSH_IMAGE ] ] From 3f65df34a0797d5c30044e7697360e9bee7075a0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Dec 2019 18:13:45 +0100 Subject: [PATCH 0668/3432] FEAT: lexer can accept string! series, doing an internal UTF8 conversion. --- runtime/lexer.reds | 23 ++++++++++++++++++++++ runtime/unicode.reds | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e91c175863..ef0d3a29ba 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -344,6 +344,7 @@ lexer: context [ scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] + utf8-buffer: as byte-ptr! 0 scanners: as int-ptr! 0 ;-- scan functions jump table (dynamically filled) stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number @@ -1781,6 +1782,27 @@ lexer: context [ depth: depth - 1 if zero? depth [root-state: null] ] + + load-string: func [ + dst [red-value!] ;-- destination slot + str [red-string!] + size [integer!] + one? [logic!] + len [int-ptr!] + /local + s [series!] + unit buf-size [integer!] + ][ + s: GET_BUFFER(str) + unit: GET_UNIT(s) + buf-size: (string/rs-length? str) * unit + if buf-size > 100'000 [ + free utf8-buffer + utf8-buffer: allocate buf-size + ] + size: unicode/to-utf8-buffer str utf8-buffer size + scan dst utf8-buffer size one? len + ] set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][ scanners: as int-ptr! allocate count * size? int-ptr! @@ -1796,6 +1818,7 @@ lexer: context [ init: func [][ stash: as cell! allocate stash-size * size? cell! + utf8-buffer: allocate 100'000 ;-- switch following tables to zero-based indexing lex-classes: lex-classes + 1 diff --git a/runtime/unicode.reds b/runtime/unicode.reds index aa70cb190f..139b03446f 100644 --- a/runtime/unicode.reds +++ b/runtime/unicode.reds @@ -165,6 +165,53 @@ unicode: context [ str/cache ] + to-utf8-buffer: func [ + str [red-string!] + buf [byte-ptr!] + len [integer!] ;-- len = -1 convert all chars + return: [integer!] + /local + beg p tail [byte-ptr!] + unit cp part [integer!] + p4 [int-ptr!] + s [series!] + ][ + s: GET_BUFFER(str) + unit: GET_UNIT(s) + + part: string/rs-length? str + if all [len <> -1 len < part][part: len] + + beg: buf + p: string/rs-head str + tail: p + (part << (unit >> 1)) + + switch unit [ + Latin1 [ + while [p < tail][ + buf: buf + cp-to-utf8 as-integer p/value buf + p: p + 1 + ] + ] + UCS-2 [ + while [p < tail][ + cp: (as-integer p/2) << 8 + p/1 + buf: buf + cp-to-utf8 cp buf + p: p + 2 + ] + ] + UCS-4 [ + p4: as int-ptr! p + while [p4 < as int-ptr! tail][ + buf: buf + cp-to-utf8 p4/value buf + p4: p4 + 1 + ] + ] + ] + buf/1: null-byte + as-integer buf - beg + ] + Latin1-to-UCS2: func [ s [series!] return: [series!] From d0f189e92cb9e2333aee08ab492d48500d78ae49 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 28 Dec 2019 11:27:14 +0800 Subject: [PATCH 0669/3432] FEAT: support 4 control points for draw image --- modules/view/backends/windows/draw.reds | 146 ++++++++++++++++---- modules/view/backends/windows/matrix2d.reds | 68 +++++++++ 2 files changed, 189 insertions(+), 25 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 4757ee3db9..9b1b482a99 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1218,6 +1218,50 @@ OS-draw-line-cap: func [ update-pen-style ctx ] +create-4p-matrix: func [ + size [SIZE_F!] + ul [D2D_POINT_2F] + ur [D2D_POINT_2F] + ll [D2D_POINT_2F] + lr [D2D_POINT_2F] + m [MATRIX_4x4_F!] + /local + s [MATRIX_4x4_F! value] + a [MATRIX_4x4_F! value] + b [MATRIX_4x4_F! value] + c [MATRIX_4x4_F! value] + den [float32!] + t1 [float32!] + t2 [float32!] +][ + matrix4x4/identity s + s/_11: (as float32! 1.0) / size/width + s/_22: (as float32! 1.0) / size/height + + matrix4x4/identity a + a/_41: ul/x + a/_42: ul/y + a/_11: ur/x - ul/x + a/_12: ur/y - ul/y + a/_21: ll/x - ul/x + a/_22: ll/y - ul/y + + matrix4x4/identity b + den: a/_11 * a/_22 - (a/_12 * a/_21) + t1: a/_22 * lr/x - (a/_21 * lr/y) + (a/_21 * a/_42) - (a/_22 * a/_41) + t1: t1 / den + t2: a/_11 * lr/y - (a/_12 * lr/x) + (a/_12 * a/_41) - (a/_11 * a/_42) + t2: t2 / den + b/_11: t1 / (t1 + t2 - as float32! 1.0) + b/_22: t2 / (t1 + t2 - as float32! 1.0) + b/_14: b/_11 - as float32! 1.0 + b/_24: b/_22 - as float32! 1.0 + + matrix4x4/identity c + matrix4x4/mul s b c + matrix4x4/mul c a m +] + OS-draw-image: func [ ctx [draw-ctx!] image [red-image!] @@ -1239,8 +1283,18 @@ OS-draw-image: func [ y [integer!] width [integer!] height [integer!] - dst [RECT_F! value] - src [RECT_F! value] + pt [red-pair!] + size [SIZE_F! value] + ul [D2D_POINT_2F value] + ur [D2D_POINT_2F value] + ll [D2D_POINT_2F value] + lr [D2D_POINT_2F value] + m [MATRIX_4x4_F! value] + trans [int-ptr!] + dst* [RECT_F! value] + dst [RECT_F!] + src* [RECT_F! value] + src [RECT_F!] crop2 [red-pair!] ][ this: as this! ctx/dc @@ -1251,36 +1305,78 @@ OS-draw-image: func [ bthis: as this! bmp/value d2db: as IUnknown bthis/vtbl either null? start [x: 0 y: 0][x: start/x y: start/y] + width: IMAGE_WIDTH(image/size) + height: IMAGE_HEIGHT(image/size) + + either crop1 <> null [ + crop2: crop1 + 1 + src*/left: as float32! crop1/x + src*/top: as float32! crop1/y + src*/right: as float32! crop1/x + crop2/x + src*/bottom: as float32! crop1/y + crop2/y + src: :src* + size/width: as float32! crop2/x + size/height: as float32! crop2/y + ][ + src: null + size/width: as float32! width + size/height: as float32! height + ] + + trans: null + dst: null case [ start = end [ - width: IMAGE_WIDTH(image/size) - height: IMAGE_HEIGHT(image/size) + dst*/left: as float32! x + dst*/top: as float32! y + dst*/right: as float32! x + width + dst*/bottom: as float32! y + height + dst: :dst* ] start + 1 = end [ ;-- two control points - width: end/x - x - height: end/y - y + dst*/left: as float32! x + dst*/top: as float32! y + dst*/right: as float32! end/x + dst*/bottom: as float32! end/y + dst: :dst* + ] + start + 2 = end [ + pt: start + ul/x: as float32! pt/x + ul/y: as float32! pt/y + pt: start + 1 + ur/x: as float32! pt/x + ur/y: as float32! pt/y + pt: start + 2 + ll/x: as float32! pt/x + ll/y: as float32! pt/y + ;-- not support ll == lr + lr/x: as float32! pt/x + 1 + lr/y: as float32! pt/y + create-4p-matrix size ul ur ll lr m + trans: as int-ptr! :m ] - start + 2 = end [0] ;@@ TBD three control points - true [0] ;@@ TBD four control points + start + 3 = end [ + pt: start + ul/x: as float32! pt/x + ul/y: as float32! pt/y + pt: start + 1 + ur/x: as float32! pt/x + ur/y: as float32! pt/y + pt: start + 2 + ll/x: as float32! pt/x + ll/y: as float32! pt/y + pt: start + 3 + lr/x: as float32! pt/x + lr/y: as float32! pt/y + create-4p-matrix size ul ur ll lr m + trans: as int-ptr! :m + ] + true [0] ] - dst/left: as float32! x - dst/top: as float32! y - dst/right: as float32! x + width - dst/bottom: as float32! y + height - - either crop1 <> null [ - crop2: crop1 + 1 - src/left: as float32! crop1/x - src/top: as float32! crop1/y - src/right: as float32! crop1/x + crop2/x - src/bottom: as float32! crop1/y + crop2/y - ;-- D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR - dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 src null - ][ - ;-- D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR - dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 null null - ] + ;-- D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR + dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 src trans d2db/Release bthis IB/Release ithis diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds index 205eb45a59..5bb7b35149 100644 --- a/modules/view/backends/windows/matrix2d.reds +++ b/modules/view/backends/windows/matrix2d.reds @@ -132,3 +132,71 @@ matrix2d: context [ D2D1InvertMatrix r ] ] + +MATRIX_4x4_F!: alias struct! [ + _11 [float32!] + _12 [float32!] + _13 [float32!] + _14 [float32!] + _21 [float32!] + _22 [float32!] + _23 [float32!] + _24 [float32!] + _31 [float32!] + _32 [float32!] + _33 [float32!] + _34 [float32!] + _41 [float32!] + _42 [float32!] + _43 [float32!] + _44 [float32!] +] + +matrix4x4: context [ + identity: func [ + m [MATRIX_4x4_F!] + ][ + m/_11: as float32! 1.0 + m/_12: as float32! 0.0 + m/_13: as float32! 0.0 + m/_14: as float32! 0.0 + m/_21: as float32! 0.0 + m/_22: as float32! 1.0 + m/_23: as float32! 0.0 + m/_24: as float32! 0.0 + m/_31: as float32! 0.0 + m/_32: as float32! 0.0 + m/_33: as float32! 1.0 + m/_34: as float32! 0.0 + m/_41: as float32! 0.0 + m/_42: as float32! 0.0 + m/_43: as float32! 0.0 + m/_44: as float32! 1.0 + ] + + mul: func [ + l [MATRIX_4x4_F!] + r [MATRIX_4x4_F!] + c [MATRIX_4x4_F!] + ][ + c/_11: l/_11 * r/_11 + (l/_12 * r/_21) + (l/_13 * r/_31) + (l/_14 * r/_41) + c/_12: l/_11 * r/_12 + (l/_12 * r/_22) + (l/_13 * r/_32) + (l/_14 * r/_42) + c/_13: l/_11 * r/_13 + (l/_12 * r/_23) + (l/_13 * r/_33) + (l/_14 * r/_43) + c/_14: l/_11 * r/_14 + (l/_12 * r/_24) + (l/_13 * r/_34) + (l/_14 * r/_44) + + c/_21: l/_21 * r/_11 + (l/_22 * r/_21) + (l/_23 * r/_31) + (l/_24 * r/_41) + c/_22: l/_21 * r/_12 + (l/_22 * r/_22) + (l/_23 * r/_32) + (l/_24 * r/_42) + c/_23: l/_21 * r/_13 + (l/_22 * r/_23) + (l/_23 * r/_33) + (l/_24 * r/_43) + c/_24: l/_21 * r/_14 + (l/_22 * r/_24) + (l/_23 * r/_34) + (l/_24 * r/_44) + + c/_31: l/_31 * r/_11 + (l/_32 * r/_21) + (l/_33 * r/_31) + (l/_34 * r/_41) + c/_32: l/_31 * r/_12 + (l/_32 * r/_22) + (l/_33 * r/_32) + (l/_34 * r/_42) + c/_33: l/_31 * r/_13 + (l/_32 * r/_23) + (l/_33 * r/_33) + (l/_34 * r/_43) + c/_34: l/_31 * r/_14 + (l/_32 * r/_24) + (l/_33 * r/_34) + (l/_34 * r/_44) + + c/_41: l/_41 * r/_11 + (l/_42 * r/_21) + (l/_43 * r/_31) + (l/_44 * r/_41) + c/_42: l/_41 * r/_12 + (l/_42 * r/_22) + (l/_43 * r/_32) + (l/_44 * r/_42) + c/_43: l/_41 * r/_13 + (l/_42 * r/_23) + (l/_43 * r/_33) + (l/_44 * r/_43) + c/_44: l/_41 * r/_14 + (l/_42 * r/_24) + (l/_43 * r/_34) + (l/_44 * r/_44) + ] +] From f26cba74e5eef37371997f0fe6d987cfd37a0607 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 28 Dec 2019 11:39:14 +0800 Subject: [PATCH 0670/3432] FIX: update pen style after *pop* --- modules/view/backends/windows/draw.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 9b1b482a99..74f7f92a5a 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1681,6 +1681,7 @@ OS-draw-state-pop: func [ ctx/pen-cap: state/pen-cap ctx/pen-type: state/pen-type ctx/brush-type: state/brush-type + update-pen-style ctx ;TBD: set pen and brush ] From 019a08076023aa973fb40d428f5fb8bf5b2d25b5 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 28 Dec 2019 10:23:15 +0100 Subject: [PATCH 0671/3432] FEAT: adds support for pattern brush. --- modules/view/backends/windows/direct2d.reds | 13 ++++- modules/view/backends/windows/draw.reds | 60 ++++++++++++++++----- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index cc8c3aa633..f1c852d25b 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -411,6 +411,15 @@ ID2D1Effect: alias struct! [ GetOutput [function! [this [this!] idx [uint!] output [ptr-ptr!]]] ] +ID2D1CommandList: alias struct! [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetFactory [integer!] + Stream [int-ptr!] + Close [function! [this [this!] return: [integer!]]] +] + IDXGIDevice1: alias struct! [ QueryInterface [QueryInterface!] AddRef [AddRef!] @@ -786,7 +795,7 @@ ID2D1DeviceContext: alias struct! [ CreateGradientStopCollection2 [integer!] CreateImageBrush [CreateImageBrush*] CreateBitmapBrush2 [CreateBitmapBrush*] - CreateCommandList [integer!] + CreateCommandList [function! [this [this!] cmd [com-ptr!] return: [integer!]]] IsDxgiFormatSupported [integer!] IsBufferPrecisionSupported [integer!] GetImageLocalBounds [integer!] @@ -794,7 +803,7 @@ ID2D1DeviceContext: alias struct! [ GetGlyphRunWorldBounds [integer!] GetDevice [function! [this [this!] dev [int-ptr!]]] SetTarget [function! [this [this!] bmp [this!]]] - GetTarget [integer!] + GetTarget [function! [this [this!] bmp [com-ptr!]]] SetRenderingControls [integer!] GetRenderingControls [integer!] SetPrimitiveBlend [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 74f7f92a5a..d7289cfac6 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1382,17 +1382,16 @@ OS-draw-image: func [ IB/Release ithis ] - -OS-draw-brush-bitmap: func [ +_OS-draw-brush-bitmap: func [ ctx [draw-ctx!] - img [red-image!] + bmp [this!] + width [integer!] + height [integer!] crop-1 [red-pair!] crop-2 [red-pair!] mode [red-word!] brush? [logic!] /local - width [integer!] - height [integer!] x [integer!] y [integer!] xx [integer!] @@ -1403,12 +1402,8 @@ OS-draw-brush-bitmap: func [ props [D2D1_IMAGE_BRUSH_PROPERTIES value] this [this!] dc [ID2D1DeviceContext] - ithis [this!] - bmp [ptr-value!] brush [ptr-value!] ][ - width: OS-image/width? img/node - height: OS-image/height? img/node either crop-1 = null [ x: 0 y: 0 @@ -1455,9 +1450,7 @@ OS-draw-brush-bitmap: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - ithis: OS-image/to-pbgra img - dc/CreateBitmapFromWicBitmap2 this ithis null :bmp - dc/CreateImageBrush this as this! bmp/value :props null :brush + dc/CreateImageBrush this bmp :props null :brush either brush? [ ctx/brush: as this! brush/value ctx/brush-type: DRAW_BRUSH_IMAGE @@ -1467,6 +1460,30 @@ OS-draw-brush-bitmap: func [ ] ] +OS-draw-brush-bitmap: func [ + ctx [draw-ctx!] + img [red-image!] + crop-1 [red-pair!] + crop-2 [red-pair!] + mode [red-word!] + brush? [logic!] + /local + width [integer!] + height [integer!] + dc [ID2D1DeviceContext] + this [this!] + ithis [this!] + bmp [ptr-value!] +][ + width: OS-image/width? img/node + height: OS-image/height? img/node + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + ithis: OS-image/to-pbgra img + dc/CreateBitmapFromWicBitmap2 this ithis null :bmp + _OS-draw-brush-bitmap ctx as this! bmp/value width height crop-1 crop-2 mode brush? +] + OS-draw-brush-pattern: func [ ctx [draw-ctx!] size [red-pair!] @@ -1475,8 +1492,27 @@ OS-draw-brush-pattern: func [ mode [red-word!] block [red-block!] brush? [logic!] + /local + dc [ID2D1DeviceContext] + this [this!] + list [com-ptr! value] + cthis [this!] + cmd [ID2D1CommandList] + old-rt [com-ptr! value] ][ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + dc/CreateCommandList this :list + cthis: list/value + + dc/GetTarget this :old-rt + dc/SetTarget this cthis + parse-draw ctx block no + cmd: as ID2D1CommandList cthis/vtbl + cmd/Close cthis + dc/SetTarget this old-rt/value + _OS-draw-brush-bitmap ctx cthis size/x size/y crop-1 crop-2 mode brush? ] OS-draw-grad-pen-old: func [ From 8ff097cf5ddbdd869fa92e18a6ddf889e4f7588b Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 28 Dec 2019 13:30:37 +0100 Subject: [PATCH 0672/3432] FEAT: properly switch brushes. --- modules/view/backends/windows/draw.reds | 49 +++++++++++++++++++++++-- runtime/platform/COM.reds | 7 ++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index d7289cfac6..1779e7b17a 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -20,6 +20,8 @@ draw-state!: alias struct! [ pen-cap [integer!] pen-type [integer!] brush-type [integer!] + pen [this!] + brush [this!] ] #enum DRAW-BRUSH-TYPE! [ @@ -216,8 +218,22 @@ OS-draw-pen: func [ /local this [this!] brush [ID2D1SolidColorBrush] + unk [IUnknown] + d3d-clr [D3DCOLORVALUE] + pen [ptr-value!] + dc [ID2D1DeviceContext] ][ - if any [ctx/pen-color <> color ctx/pen-type = as-integer off?][ + if ctx/pen-type <> DRAW_BRUSH_COLOR [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + COM_SAFE_RELEASE(unk ctx/pen) + d3d-clr: to-dx-color color null + dc/CreateSolidColorBrush this d3d-clr null :pen + ctx/pen: as this! pen/value + ctx/pen-color: color + ctx/pen-type: as-integer not off? + ] + if ctx/pen-color <> color [ ctx/pen-type: as-integer not off? unless ctx/font-color? [ctx/font-color: color] ;-- if no font, use pen color for text color if ctx/pen-type <> DRAW_BRUSH_NONE [ @@ -721,12 +737,26 @@ OS-draw-fill-pen: func [ /local this [this!] brush [ID2D1SolidColorBrush] + unk [IUnknown] + d3d-clr [D3DCOLORVALUE] + pen [ptr-value!] + dc [ID2D1DeviceContext] ][ - if any [ctx/brush-color <> color ctx/brush-type = as-integer off?][ + if ctx/brush-type <> DRAW_BRUSH_COLOR [ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + COM_SAFE_RELEASE(unk ctx/brush) + d3d-clr: to-dx-color color null + dc/CreateSolidColorBrush this d3d-clr null :pen + ctx/brush: as this! pen/value + ctx/brush-color: color + ctx/brush-type: as-integer not off? + ] + if ctx/brush-color <> color [ ctx/brush-type: as-integer not off? if ctx/brush-type <> DRAW_BRUSH_NONE [ ctx/brush-color: color - this: as this! ctx/brush + this: ctx/brush brush: as ID2D1SolidColorBrush this/vtbl brush/SetColor this to-dx-color color null ] @@ -1403,6 +1433,7 @@ _OS-draw-brush-bitmap: func [ this [this!] dc [ID2D1DeviceContext] brush [ptr-value!] + unk [IUnknown] ][ either crop-1 = null [ x: 0 @@ -1452,9 +1483,11 @@ _OS-draw-brush-bitmap: func [ dc: as ID2D1DeviceContext this/vtbl dc/CreateImageBrush this bmp :props null :brush either brush? [ + COM_SAFE_RELEASE(unk ctx/brush) ctx/brush: as this! brush/value ctx/brush-type: DRAW_BRUSH_IMAGE ][ + COM_SAFE_RELEASE(unk ctx/pen) ctx/pen: as this! brush/value ctx/pen-type: DRAW_BRUSH_IMAGE ] @@ -1680,6 +1713,7 @@ OS-draw-state-push: func [ blk [ptr-value!] this [this!] dc [ID2D1DeviceContext] + unk [IUnknown] ][ factory: as ID2D1Factory d2d-factory/vtbl if 0 <> factory/CreateDrawingStateBlock d2d-factory null null :blk [ @@ -1697,6 +1731,10 @@ OS-draw-state-push: func [ state/pen-cap: ctx/pen-cap state/pen-type: ctx/pen-type state/brush-type: ctx/brush-type + state/pen: ctx/pen + state/brush: ctx/brush + COM_ADD_REF(unk state/pen) + COM_ADD_REF(unk state/brush) ] OS-draw-state-pop: func [ @@ -1717,8 +1755,11 @@ OS-draw-state-pop: func [ ctx/pen-cap: state/pen-cap ctx/pen-type: state/pen-type ctx/brush-type: state/brush-type + COM_SAFE_RELEASE(IUnk ctx/pen) + COM_SAFE_RELEASE(IUnk ctx/brush) + ctx/pen: state/pen + ctx/brush: state/brush update-pen-style ctx - ;TBD: set pen and brush ] OS-matrix-reset: func [ diff --git a/runtime/platform/COM.reds b/runtime/platform/COM.reds index 1a33702fe8..9b8944319b 100644 --- a/runtime/platform/COM.reds +++ b/runtime/platform/COM.reds @@ -27,6 +27,13 @@ Red/System [ ] ] +#define COM_ADD_REF(interface this) [ + if this <> null [ + interface: as IUnknown this/vtbl + interface/AddRef this + ] +] + #define COM_S_OK 0 #define COM_SUCCEEDED(hr) [hr >= 0] From 72c6a926829434371e0af9106e7de1f1a05ad8e5 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 28 Dec 2019 17:06:01 +0100 Subject: [PATCH 0673/3432] FIX: some fixes in D2D draw. --- modules/view/backends/windows/draw.reds | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 1779e7b17a..2d231900de 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -126,6 +126,7 @@ release-ctx: func [ ][ COM_SAFE_RELEASE(IUnk ctx/pen) COM_SAFE_RELEASE(IUnk ctx/brush) + release-pen-style ctx ] draw-end: func [ @@ -141,14 +142,15 @@ draw-end: func [ rt [render-target!] hr [integer!] ][ - release-pen-style ctx this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl dc/EndDraw this null null dc/SetTarget this null + release-ctx ctx ;@@ Possible improvement: cache resources for window target + rt: as render-target! ctx/target - either hWnd <> null [ + either hWnd <> null [ ;-- window target this: rt/swapchain sc: as IDXGISwapChain1 this/vtbl hr: sc/Present this 0 0 @@ -157,7 +159,6 @@ draw-end: func [ COM_S_OK [ValidateRect hWnd null] DXGI_ERROR_DEVICE_REMOVED DXGI_ERROR_DEVICE_RESET [ - release-ctx ctx d2d-release-target rt ctx/dc: null SetWindowLong hWnd wc-offset - 24 0 @@ -165,10 +166,10 @@ draw-end: func [ InvalidateRect hWnd null 0 ] default [ - 0 ;@@ TBD log error!!! + 0 ;@@ TBD log error!!! ] ] - ][ ;-- draw on image! + ][ ;-- image! target ;TBD save rt/bitmap to ctx/image d2d-release-target rt ] @@ -231,10 +232,9 @@ OS-draw-pen: func [ dc/CreateSolidColorBrush this d3d-clr null :pen ctx/pen: as this! pen/value ctx/pen-color: color - ctx/pen-type: as-integer not off? ] + ctx/pen-type: as-integer not off? if ctx/pen-color <> color [ - ctx/pen-type: as-integer not off? unless ctx/font-color? [ctx/font-color: color] ;-- if no font, use pen color for text color if ctx/pen-type <> DRAW_BRUSH_NONE [ ctx/pen-color: color @@ -750,10 +750,9 @@ OS-draw-fill-pen: func [ dc/CreateSolidColorBrush this d3d-clr null :pen ctx/brush: as this! pen/value ctx/brush-color: color - ctx/brush-type: as-integer not off? ] + ctx/brush-type: as-integer not off? if ctx/brush-color <> color [ - ctx/brush-type: as-integer not off? if ctx/brush-type <> DRAW_BRUSH_NONE [ ctx/brush-color: color this: ctx/brush @@ -1507,6 +1506,7 @@ OS-draw-brush-bitmap: func [ this [this!] ithis [this!] bmp [ptr-value!] + unk [IUnknown] ][ width: OS-image/width? img/node height: OS-image/height? img/node @@ -1515,6 +1515,9 @@ OS-draw-brush-bitmap: func [ ithis: OS-image/to-pbgra img dc/CreateBitmapFromWicBitmap2 this ithis null :bmp _OS-draw-brush-bitmap ctx as this! bmp/value width height crop-1 crop-2 mode brush? + COM_SAFE_RELEASE(unk ithis) + ithis: as this! bmp/value + COM_SAFE_RELEASE(unk ithis) ] OS-draw-brush-pattern: func [ @@ -1546,6 +1549,7 @@ OS-draw-brush-pattern: func [ dc/SetTarget this old-rt/value _OS-draw-brush-bitmap ctx cthis size/x size/y crop-1 crop-2 mode brush? + cmd/Release cthis ] OS-draw-grad-pen-old: func [ @@ -1556,7 +1560,7 @@ OS-draw-grad-pen-old: func [ count [integer!] ;-- number of the colors brush? [logic!] ][ - ;Deprecated + ;Deprecated, no need to implement it. ] OS-draw-grad-pen: func [ From 2ef171c0b51bb608e805a33a0b1b661253da1d27 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 29 Dec 2019 10:58:08 +0100 Subject: [PATCH 0674/3432] FEAT: remove auto-closing for SHAPE. It's problematic to auto-closing a shape. For example, how to close three separate lines? ``` shape [ move 100x100 hline 300 move 100x150 hline 250 move 100x200 hline 200 ] ``` --- modules/view/backends/windows/draw.reds | 2 +- modules/view/draw.red | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 2d231900de..43c5b7fefb 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -798,7 +798,7 @@ OS-draw-box: func [ ] ] -OS-draw-triangle: func [ ;@@ TBD merge this function with OS-draw-polygon +OS-draw-triangle: func [ ctx [draw-ctx!] start [red-pair!] ][ diff --git a/modules/view/draw.red b/modules/view/draw.red index b755b230d6..440bd3c122 100644 --- a/modules/view/draw.red +++ b/modules/view/draw.red @@ -594,13 +594,11 @@ Red/System [ sym = move [ DRAW_FETCH_VALUE(TYPE_PAIR) OS-draw-shape-moveto DC as red-pair! cmd rel? - close?: no ] sym = line [ DRAW_FETCH_VALUE(TYPE_PAIR) DRAW_FETCH_SOME_PAIR OS-draw-shape-line DC as red-pair! start as red-pair! cmd rel? - close?: yes ] any [sym = line-width sym = line-join sym = line-cap][ cmd: check-line DC cmds start tail cmd sym catch? @@ -608,7 +606,6 @@ Red/System [ any [ sym = hline sym = vline ][ DRAW_FETCH_VALUE_2(TYPE_INTEGER TYPE_FLOAT) OS-draw-shape-axis DC start cmd rel? (sym = hline) - close?: yes ] sym = _arc [ sweep?: false @@ -632,30 +629,25 @@ Red/System [ ] ] OS-draw-shape-arc DC as red-pair! start sweep? large? rel? - close?: yes ] sym = curve [ DRAW_FETCH_SOME_PAIR if (as-integer cmd - start) < 32 [throw-draw-error cmds cmd - 2 catch?] OS-draw-shape-curve DC as red-pair! start as red-pair! cmd rel? - close?: yes ] sym = curv [ DRAW_FETCH_SOME_PAIR if (as-integer cmd - start) < 16 [throw-draw-error cmds cmd - 1 catch?] OS-draw-shape-curv DC as red-pair! start as red-pair! cmd rel? - close?: yes ] sym = qcurve [ DRAW_FETCH_SOME_PAIR if (as-integer cmd - start) < 16 [throw-draw-error cmds cmd - 1 catch?] OS-draw-shape-qcurve DC as red-pair! start as red-pair! cmd rel? - close?: yes ] sym = qcurv [ DRAW_FETCH_SOME_PAIR OS-draw-shape-qcurv DC as red-pair! start as red-pair! cmd rel? - close?: yes ] sym = close-shape [OS-draw-shape-close DC] true [ throw-draw-error cmds cmd catch? ] From 0a39c0bad0a0492e5c0b38dd7e2901b16e3cbc3c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 29 Dec 2019 22:12:33 +0100 Subject: [PATCH 0675/3432] FEAT: better missing closing delimiter handling in new lexer. --- runtime/lexer.reds | 50 +++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ef0d3a29ba..57324b5e0e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -317,7 +317,8 @@ lexer: context [ ERR_BAD_CHAR: -1 ERR_MALCONSTRUCT: -2 ERR_MISSING: -3 - LEX_INT_OVERFLOW: -4 + ERR_CLOSING: -4 + LEX_INT_OVERFLOW: -5 ] state!: alias struct! [ @@ -344,6 +345,7 @@ lexer: context [ scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] + utf8-bufsize: 100'000 utf8-buffer: as byte-ptr! 0 scanners: as int-ptr! 0 ;-- scan functions jump table (dynamically filled) stash: as cell! 0 ;-- special buffer for hatching any-blocks series @@ -383,8 +385,11 @@ lexer: context [ switch type [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) line pos]] + ERR_CLOSING ERR_MISSING [ - c: either lex/in-pos < lex/in-end [lex/in-pos/1][lex/in-pos/0] + c: either type = ERR_CLOSING [#"_"][ ;-- force a closing character + either lex/in-pos < lex/in-end [lex/in-pos/1][lex/in-pos/0] ;-- guess opening/closing + ] type: switch lex/closing [ TYPE_BLOCK [as-integer either c = #"]" [#"["][#"]"]] TYPE_MAP @@ -464,8 +469,8 @@ lexer: context [ p: as red-point! alloc-slot lex set-type as cell! p TYPE_POINT ;-- use the slot for stack info p/x: len - p/y: type - p/z: hint + p/y: type << 16 or (hint and FFFFh) + p/z: as-integer lex/in-pos - lex/input ;-- opening delimiter offset saved (error handling) lex/head: lex/tail ;-- points just after p lex/entry: S_START @@ -475,7 +480,7 @@ lexer: context [ return: [integer!] /local p [red-point!] - len hint [integer!] + len hint stype [integer!] do-error [subroutine!] ][ do-error: [ @@ -483,23 +488,24 @@ lexer: context [ throw-error lex s e ERR_MISSING ] p: as red-point! lex/head - 1 + stype: p/y >> 16 unless all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][do-error] either type = -1 [ - type: either final = -1 [p/y][final] + type: either final = -1 [stype][final] ][ - if p/y <> type [do-error] + if stype <> type [do-error] ] len: (as-integer lex/tail - lex/head) >> 4 lex/tail: lex/head lex/head: as cell! p - p/x - hint: p/z - + hint: p/y and FFFFh << 16 >> 16 + store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here p: as red-point! lex/head - 1 ;-- get parent series either all [ lex/buffer <= p - not any [p/y = TYPE_BLOCK p/y = TYPE_PAREN p/y = TYPE_MAP] + not any [stype = TYPE_BLOCK stype = TYPE_PAREN stype = TYPE_MAP] ][ ;-- any-path! case lex/entry: S_PATH ][ @@ -1747,6 +1753,7 @@ lexer: context [ len [int-ptr!] ;-- return the consumed input length /local blk [red-block!] + p [red-point!] slots [integer!] s [series!] lex [state! value] @@ -1771,7 +1778,13 @@ lexer: context [ scan-tokens lex one? slots: (as-integer lex/tail - lex/buffer) >> 4 - + if slots > 0 [ + p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] + if TYPE_OF(p) = TYPE_POINT [ + lex/closing: p/y >> 16 + throw-error lex lex/input + p/z lex/in-end ERR_CLOSING + ] + ] either all [one? slots > 0][ copy-cell lex/buffer dst ;-- copy first loaded value only ][ @@ -1784,23 +1797,28 @@ lexer: context [ ] load-string: func [ - dst [red-value!] ;-- destination slot + dst [red-value!] ;-- destination slot str [red-string!] size [integer!] one? [logic!] len [int-ptr!] /local s [series!] - unit buf-size [integer!] + unit buf-size ignore [integer!] ][ + ignore: 0 s: GET_BUFFER(str) unit: GET_UNIT(s) - buf-size: (string/rs-length? str) * unit - if buf-size > 100'000 [ + + if size = -1 [size: string/rs-length? str] + buf-size: size * unit + if buf-size > utf8-bufsize [ free utf8-buffer utf8-buffer: allocate buf-size + utf8-bufsize: buf-size ] size: unicode/to-utf8-buffer str utf8-buffer size + if null? len [len: :ignore] scan dst utf8-buffer size one? len ] @@ -1818,7 +1836,7 @@ lexer: context [ init: func [][ stash: as cell! allocate stash-size * size? cell! - utf8-buffer: allocate 100'000 + utf8-buffer: allocate utf8-bufsize ;-- switch following tables to zero-based indexing lex-classes: lex-classes + 1 From 37859afafd7e497aedd7cd84080494666733a9f2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 29 Dec 2019 22:13:24 +0100 Subject: [PATCH 0676/3432] FEAT: lets DO native use the new lexer for string arguments. --- runtime/natives.reds | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 45e46d72c1..6cd0d963ef 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -532,7 +532,6 @@ natives: context [ cframe [byte-ptr!] arg [red-value!] do-arg [red-value!] - str [red-string!] slot [red-value!] blk [red-block!] job [red-value!] @@ -556,8 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - str: as red-string! arg - #call [system/lexer/transcode str none no] + lexer/load-string arg as red-string! arg -1 no null DO_EVAL_BLOCK ] TYPE_URL From 9722000a8dad3415e9c21db5a5ec2ed46da4b025 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 29 Dec 2019 22:17:14 +0100 Subject: [PATCH 0677/3432] FEAT: preliminary support for radial gradient. --- modules/view/backends/windows/direct2d.reds | 4 +- modules/view/backends/windows/draw.reds | 84 ++++++++++++++++++++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index f1c852d25b..1113cf2483 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -242,7 +242,7 @@ CreateRadialGradientBrush*: alias function! [ this [this!] gprops [D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES] props [D2D1_BRUSH_PROPERTIES] - stops [integer!] + stops [this!] brush [ptr-ptr!] return: [integer!] ] @@ -253,7 +253,7 @@ CreateGradientStopCollection*: alias function! [ stopsCount [integer!] gamma [integer!] extendMode [integer!] - stops-ptr [int-ptr!] + stops-ptr [com-ptr!] return: [integer!] ] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 43c5b7fefb..773479bd47 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -31,6 +31,8 @@ draw-state!: alias struct! [ DRAW_BRUSH_GRADIENT ] +grad-stops: as D2D1_GRADIENT_STOP allocate 256 * size? D2D1_GRADIENT_STOP + draw-begin: func [ ctx [draw-ctx!] hWnd [handle!] @@ -1565,16 +1567,94 @@ OS-draw-grad-pen-old: func [ OS-draw-grad-pen: func [ ctx [draw-ctx!] - mode [integer!] + type [integer!] stops [red-value!] count [integer!] - skip-pos [logic!] + skip-pos? [logic!] positions [red-value!] focal? [logic!] spread [integer!] brush? [logic!] + /local + dc [ID2D1DeviceContext] + this [this!] + unk [IUnknown] + gprops [D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES value] + gstops [D2D1_GRADIENT_STOP] + x [float!] + y [float!] + start [float!] + stop [float!] + brush [ptr-value!] + int [red-integer!] + f [red-float!] + head [red-value!] + next [red-value!] + clr [red-tuple!] + n [integer!] + delta [float!] + p [float!] + wrap [integer!] + sc [com-ptr! value] + pt [red-pair!] ][ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + + gstops: grad-stops + n: count - 1 + delta: as float! n + delta: 1.0 / delta + p: 0.0 + head: stops + loop count [ + clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head] + next: head + 1 + to-dx-color clr/array1 as D3DCOLORVALUE (as int-ptr! gstops) + 1 + if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value] + gstops/position: as float32! p + if next <> head [p: p + delta] + head: head + 1 + gstops: gstops + 1 + ] + + case [ + spread = _pad [wrap: 0] + spread = _repeat [wrap: 1] + spread = _reflect [wrap: 2] + true [wrap: 0] + ] + + either type = linear [ + 0 + ][ + dc/CreateGradientStopCollection this grad-stops count 0 wrap :sc + unless skip-pos? [ + pt: as red-pair! positions + gprops/center.x: as float32! pt/x + gprops/center.y: as float32! pt/y + gprops/radius.x: get-float32 as red-integer! pt + 1 + gprops/radius.y: gprops/radius.x + if focal? [ + pt: pt + 2 + gprops/offset.x: as float32! pt/x + gprops/offset.x: as float32! pt/y + ] + ] + dc/CreateRadialGradientBrush this gprops null sc/value :brush + ] + COM_SAFE_RELEASE(unk sc/value) + + either brush? [ + COM_SAFE_RELEASE(unk ctx/brush) + ctx/brush: as this! brush/value + ctx/brush-type: DRAW_BRUSH_GRADIENT + ][ + COM_SAFE_RELEASE(unk ctx/pen) + ctx/pen: as this! brush/value + ctx/pen-type: DRAW_BRUSH_GRADIENT + ] ] OS-set-clip: func [ From 613ef3b6dc6b0d53b01801b1d915aa209fa92155 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 30 Dec 2019 12:32:05 +0100 Subject: [PATCH 0678/3432] FEAT: prepare for drawing gradient on shapes. --- modules/view/backends/windows/direct2d.reds | 28 +++++++++++++--- modules/view/backends/windows/draw.reds | 36 +++++++++++++++++++-- runtime/definitions.reds | 1 + 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 1113cf2483..b21eaafc76 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -315,6 +315,26 @@ GetTransform*: alias function! [ transform [D2D_MATRIX_3X2_F] ] +SetCenter*: alias function! [ + this [this!] + center [D2D_POINT_2F value] +] + +SetGradientOriginOffset*: alias function! [ + this [this!] + Offset [D2D_POINT_2F value] +] + +SetRadiusX*: alias function! [ + this [this!] + x [float32!] +] + +SetRadiusY*: alias function! [ + this [this!] + y [float32!] +] + Resize*: alias function! [ this [this!] pixelSize [tagSIZE] @@ -363,10 +383,10 @@ ID2D1RadialGradientBrush: alias struct! [ SetTransform [SetTransform*] GetOpacity [integer!] GetTransform [GetTransform*] - SetCenter [integer!] - SetGradientOriginOffset [integer!] - SetRadiusX [integer!] - SetRadiusY [integer!] + SetCenter [SetCenter*] + SetGradientOriginOffset [SetGradientOriginOffset*] + SetRadiusX [SetRadiusX*] + SetRadiusY [SetRadiusY*] GetCenter [integer!] GetGradientOriginOffset [integer!] GetRadiusX [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 773479bd47..ae738087d8 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -29,6 +29,7 @@ draw-state!: alias struct! [ DRAW_BRUSH_COLOR DRAW_BRUSH_IMAGE DRAW_BRUSH_GRADIENT + DRAW_BRUSH_GRADIENT_SMART ] grad-stops: as D2D1_GRADIENT_STOP allocate 256 * size? D2D1_GRADIENT_STOP @@ -651,6 +652,26 @@ OS-draw-anti-alias: func [ dc/SetAntialiasMode this either on? [0][1] ] +calculate-gradient-pos: func [ + brush [this!] + path [this!] + type [integer!] + /local + radial [ID2D1RadialGradientBrush] +][ + either type = linear [ + 0 + ][ + radial: as ID2D1RadialGradientBrush brush/vtbl + ;@@ get the centroid of the shape or just use the center of the bounding box? + ;@@ check how does SVG or other graphic libraries do it. + ;radial/SetCenter brush + ;radial/SetGradientOriginOffset brush + ;radial/SetRadiusX brush + ;radial/SetRadiusY brush + ] +] + _OS-draw-polygon: func [ ctx [draw-ctx!] start [red-pair!] @@ -695,9 +716,15 @@ _OS-draw-polygon: func [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ + if ctx/brush-type = DRAW_BRUSH_GRADIENT_SMART [ + calculate-gradient-pos ctx/brush pthis ctx/grad-type + ] dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ + if ctx/pen-type = DRAW_BRUSH_GRADIENT_SMART [ + calculate-gradient-pos ctx/pen pthis ctx/grad-type + ] dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1597,6 +1624,7 @@ OS-draw-grad-pen: func [ wrap [integer!] sc [com-ptr! value] pt [red-pair!] + gtype [integer!] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -1625,11 +1653,13 @@ OS-draw-grad-pen: func [ true [wrap: 0] ] + ctx/grad-type: type either type = linear [ 0 ][ dc/CreateGradientStopCollection this grad-stops count 0 wrap :sc - unless skip-pos? [ + either skip-pos? [gtype: DRAW_BRUSH_GRADIENT_SMART][ + gtype: DRAW_BRUSH_GRADIENT pt: as red-pair! positions gprops/center.x: as float32! pt/x gprops/center.y: as float32! pt/y @@ -1649,11 +1679,11 @@ OS-draw-grad-pen: func [ either brush? [ COM_SAFE_RELEASE(unk ctx/brush) ctx/brush: as this! brush/value - ctx/brush-type: DRAW_BRUSH_GRADIENT + ctx/brush-type: gtype ][ COM_SAFE_RELEASE(unk ctx/pen) ctx/pen: as this! brush/value - ctx/pen-type: DRAW_BRUSH_GRADIENT + ctx/pen-type: gtype ] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index eb4dfdffe3..ac997e8ef7 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -286,6 +286,7 @@ Red/System [ scale-ratio [float32!] pen-type [integer!] brush-type [integer!] + grad-type [integer!] ;-- gradient type: radial, linear on-image? [logic!] ;-- drawing on image? font-color? [logic!] text-format [this!] From d7958d8a62ba6f8fdcb77d8fef3da53fad870853 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 30 Dec 2019 18:37:02 +0100 Subject: [PATCH 0679/3432] FEAT: replaces low-level calls to old lexer by new one. --- libRed/libRed.red | 2 +- runtime/datatypes/block.reds | 17 ++++++----------- runtime/datatypes/common.reds | 2 +- runtime/lexer.reds | 16 +++++++++------- runtime/natives.reds | 4 ++-- system/utils/libRedRT-exports.r | 1 + 6 files changed, 20 insertions(+), 22 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index 224541066e..3f516c1206 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -251,7 +251,7 @@ Red [ if last-error <> null [return last-error] TRAP_ERRORS(name [ - #call [system/lexer/transcode str none no] + lexer/load-string stack/arguments str -1 no no null stack/unwind-last ]) ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index dbf54998ca..6e71786d95 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -642,23 +642,18 @@ block: context [ spec [red-value!] type [integer!] return: [red-block!] - /local - str [red-string!] ][ #if debug? = yes [if verbose > 0 [print-line "block/to"]] switch TYPE_OF(spec) [ - TYPE_OBJECT [object/reflect as red-object! spec words/body] - TYPE_MAP [map/reflect as red-hash! spec words/body] - TYPE_VECTOR [vector/to-block as red-vector! spec proto] - TYPE_STRING [ - str: as red-string! spec - #call [system/lexer/transcode str none no] - ] - TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] + TYPE_OBJECT [object/reflect as red-object! spec words/body] + TYPE_MAP [map/reflect as red-hash! spec words/body] + TYPE_VECTOR [vector/to-block as red-vector! spec proto] + TYPE_STRING [lexer/load-string as red-value! proto as red-string! spec -1 no no null] + TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] TYPE_ANY_PATH TYPE_ANY_LIST [proto: clone as red-block! spec no no] - default [rs-append make-at proto 1 spec] + default [rs-append make-at proto 1 spec] ] proto/header: type proto diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 4809866278..9de07a3436 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -351,7 +351,7 @@ load-value: func [ blk [red-block!] value [red-value!] ][ - #call [system/lexer/transcode/one/only str none no] + lexer/load-string stack/arguments str -1 yes yes null blk: as red-block! stack/arguments assert TYPE_OF(blk) = TYPE_BLOCK diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 57324b5e0e..c564d1ba94 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1750,6 +1750,7 @@ lexer: context [ src [byte-ptr!] ;-- UTF-8 buffer size [integer!] ;-- buffer size in bytes one? [logic!] ;-- scan a single value + wrap? [logic!] ;-- force returned loaded value(s) in a block len [int-ptr!] ;-- return the consumed input length /local blk [red-block!] @@ -1785,7 +1786,7 @@ lexer: context [ throw-error lex lex/input + p/z lex/in-end ERR_CLOSING ] ] - either all [one? slots > 0][ + either all [one? not wrap? slots > 0][ copy-cell lex/buffer dst ;-- copy first loaded value only ][ store-any-block dst lex/buffer slots TYPE_BLOCK @@ -1797,11 +1798,12 @@ lexer: context [ ] load-string: func [ - dst [red-value!] ;-- destination slot - str [red-string!] - size [integer!] - one? [logic!] - len [int-ptr!] + dst [red-value!] ;-- destination slot + str [red-string!] + size [integer!] + one? [logic!] + wrap? [logic!] + len [int-ptr!] /local s [series!] unit buf-size ignore [integer!] @@ -1819,7 +1821,7 @@ lexer: context [ ] size: unicode/to-utf8-buffer str utf8-buffer size if null? len [len: :ignore] - scan dst utf8-buffer size one? len + scan dst utf8-buffer size one? wrap? len ] set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][ diff --git a/runtime/natives.reds b/runtime/natives.reds index 6cd0d963ef..3bca1a281d 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -555,7 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - lexer/load-string arg as red-string! arg -1 no null + lexer/load-string arg as red-string! arg -1 no no null DO_EVAL_BLOCK ] TYPE_URL @@ -2755,7 +2755,7 @@ natives: context [ ; ;] - lexer/scan slot binary/rs-head bin len next? :offset + lexer/scan slot binary/rs-head bin len next? no :offset if next? [ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index 2a0614b7c7..cb5a17df0c 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -48,6 +48,7 @@ red/interpreter/eval-path red/lexer/scan + red/lexer/load-string red/none/push-last From ca764cfb8f697067c18739ddca0dd1dcecc24fc7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 30 Dec 2019 18:52:36 +0100 Subject: [PATCH 0680/3432] FEAT: prepare for SHADOW command. --- modules/view/backends/windows/direct2d.reds | 29 +++++++++++++- modules/view/backends/windows/draw.reds | 42 +++++++++++++++++++++ modules/view/draw.red | 39 +++++++++++++++++++ runtime/definitions.reds | 13 +++++++ 4 files changed, 121 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index b21eaafc76..3cb14b92be 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -29,6 +29,7 @@ dwrite-str-cache: as node! 0 #define D2D_MAX_BRUSHES 64 +#define DXGI_FORMAT_A8_UNORM 65 #define D2DERR_RECREATE_TARGET 8899000Ch #define DXGI_ERROR_DEVICE_REMOVED 887A0005h #define DXGI_ERROR_DEVICE_RESET 887A0007h @@ -1532,8 +1533,6 @@ create-render-target: func [ this [this!] hr [integer!] buf [integer!] - props [D2D1_BITMAP_PROPERTIES1 value] - bmp [integer!] unk [IUnknown] ][ GetClientRect hWnd :rc @@ -1977,4 +1976,30 @@ render-target-lost?: func [ rt/BeginDraw target rt/Clear target to-dx-color 0 null 0 <> rt/EndDraw target null null +] + +create-bitmap: func [ + this [this!] + width [uint32!] + height [uint32!] + format [integer!] + return: [this!] + /local + dc [ID2D1DeviceContext] + props [D2D1_BITMAP_PROPERTIES1 value] + sz [SIZE_U! value] + bitmap [ptr-value!] +][ + props/format: format + props/alphaMode: 1 + props/dpiX: dpi-x + props/dpiY: dpi-y + props/options: 1 ;-- D2D1_BITMAP_OPTIONS_TARGET + props/colorContext: null + + sz/width: width + sz/height: height + dc: as ID2D1DeviceContext this/vtbl + dc/CreateBitmap2 this sz null 0 props :bitmap + as this! bitmap/value ] \ No newline at end of file diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index ae738087d8..8efdc31fad 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -1954,3 +1954,45 @@ OS-set-matrix-order: func [ ][ ] + +OS-draw-shadow: func [ + ctx [draw-ctx!] + offset [red-pair!] + blur [integer!] + spread [integer!] + color [integer!] + inset? [logic!] + /local + s [shadow!] + ss [shadow!] + chain? [logic!] +][ + chain?: ctx/shadow? + ctx/shadow?: TYPE_OF(offset) = TYPE_PAIR + either ctx/shadow? [ + either chain? [ + s: as shadow! allocate size? shadow! + ss: ctx/shadows/next + either null? ss [ctx/shadows/next: s][ + ss/next: s + ] + ][ + s: ctx/shadows + s/next: null + ] + s/offset-x: offset/x + s/offset-y: offset/y + s/blur: blur + s/spread: spread + s/color: color + s/inset?: inset? + ][ + ss: ctx/shadows/next + while [ss <> null][ + s: ss + ss: ss/next + free as byte-ptr! s + ] + ctx/shadows/next: null + ] +] \ No newline at end of file diff --git a/modules/view/draw.red b/modules/view/draw.red index 440bd3c122..df5125cafc 100644 --- a/modules/view/draw.red +++ b/modules/view/draw.red @@ -84,6 +84,8 @@ Red/System [ flip-y: symbol/make "flip-y" flip-xy: symbol/make "flip-xy" clamp: symbol/make "clamp" + _shadow: symbol/make "shadow" + _inset: symbol/make "inset" throw-draw-error: func [ cmds [red-block!] @@ -679,6 +681,7 @@ Red/System [ crop-s [red-pair!] blk [red-block!] color [red-tuple!] + int [red-integer!] sym [integer!] mode [integer!] rgb [integer!] @@ -694,6 +697,9 @@ Red/System [ state [draw-state! value] clip-mode [integer!] m-order [integer!] + blur [integer!] + spread [integer!] + inset? [logic!] ][ cmd: block/rs-head cmds tail: block/rs-tail cmds @@ -842,6 +848,39 @@ Red/System [ ] OS-draw-image DC as red-image! start point end color border? crop-s pattern ] + sym = _shadow [ + DRAW_FETCH_VALUE_2(TYPE_PAIR TYPE_WORD) + if TYPE_OF(start) = TYPE_WORD [ + word: as red-word! start + sym: symbol/resolve word/symbol + if sym <> _off [ + throw-draw-error cmds start catch? + ] + ] + inset?: no + blur: 0 + spread: 0 + rgb: 0 + DRAW_FETCH_OPT_VALUE(TYPE_INTEGER) ;-- blur radius + if pos = cmd [ + int: as red-integer! pos + blur: int/value + DRAW_FETCH_OPT_VALUE(TYPE_INTEGER) ;-- spread radius + if pos = cmd [ + int: as red-integer! pos + spread: int/value + ] + ] + DRAW_FETCH_OPT_VALUE(TYPE_TUPLE) + if pos = cmd [cmd: cmd - 1 DRAW_FETCH_TUPLE] + DRAW_FETCH_OPT_VALUE(TYPE_WORD) + if pos = cmd [ + word: as red-word! pos + sym: symbol/resolve word/symbol + either sym = _inset [inset?: yes][cmd: cmd - 1] + ] + OS-draw-shadow DC as red-pair! start blur spread rgb inset? + ] sym = clip [ rect?: false DRAW_FETCH_VALUE_2(TYPE_PAIR TYPE_BLOCK) diff --git a/runtime/definitions.reds b/runtime/definitions.reds index ac997e8ef7..227dab3b92 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -268,6 +268,17 @@ Red/System [ control-x [float32!] control-y [float32!] ] + + shadow!: alias struct! [ + offset-x [integer!] + offset-y [integer!] + blur [integer!] + spread [integer!] + color [integer!] + inset? [logic!] + next [shadow!] + ] + draw-ctx!: alias struct! [ dc [ptr-ptr!] target [int-ptr!] @@ -289,9 +300,11 @@ Red/System [ grad-type [integer!] ;-- gradient type: radial, linear on-image? [logic!] ;-- drawing on image? font-color? [logic!] + shadow? [logic!] text-format [this!] state [this!] ;-- current draw state sub [sub-path! value] + shadows [shadow! value] ] ][ draw-ctx!: alias struct! [ From e3c54092ad8fdcee4a16a6768c0579a77e2daa56 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 1 Jan 2020 16:07:54 +0800 Subject: [PATCH 0681/3432] FIX: save pen-style as this! type --- modules/view/backends/windows/direct2d.reds | 8 ++++---- modules/view/backends/windows/draw.reds | 16 ++++++---------- runtime/definitions.reds | 2 +- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 3cb14b92be..a2b4c0f772 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -266,7 +266,7 @@ DrawLine*: alias function! [ pt1.y [float32!] brush [this!] width [float32!] - style [integer!] + style [this!] ] DrawRectangle*: alias function! [ @@ -274,7 +274,7 @@ DrawRectangle*: alias function! [ rect [RECT_F!] brush [this!] strokeWidth [float32!] - strokeStyle [integer!] + strokeStyle [this!] ] FillRectangle*: alias function! [ @@ -288,7 +288,7 @@ DrawEllipse*: alias function! [ ellipse [D2D1_ELLIPSE] brush [this!] width [float32!] - style [integer!] + style [this!] ] FillEllipse*: alias function! [ @@ -767,7 +767,7 @@ DrawBitmap*: alias function! [ FillRoundedRectangle [integer!] DrawEllipse [DrawEllipse*] FillEllipse [FillEllipse*] - DrawGeometry [function! [this [this!] geometry [int-ptr!] brush [this!] strokeWidth [float32!] style [integer!] return: [integer!]]] + DrawGeometry [function! [this [this!] geometry [int-ptr!] brush [this!] strokeWidth [float32!] style [this!] return: [integer!]]] FillGeometry [function! [this [this!] geometry [int-ptr!] brush [this!] opacityBrush [this!] return: [integer!]]] FillMesh [integer!] FillOpacityMask [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 8efdc31fad..a8d924524f 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -63,7 +63,7 @@ draw-begin: func [ ctx/pen-width: as float32! 1.0 ctx/pen-join: D2D1_LINE_JOIN_MITER ctx/pen-cap: D2D1_CAP_STYLE_FLAT - ctx/pen-style: 0 + ctx/pen-style: null ctx/pen-type: DRAW_BRUSH_COLOR ctx/hwnd: hWnd update-pen-style ctx @@ -125,7 +125,7 @@ draw-begin: func [ release-ctx: func [ ctx [draw-ctx!] /local - IUnk [IUnknown] + IUnk [IUnknown] ][ COM_SAFE_RELEASE(IUnk ctx/pen) COM_SAFE_RELEASE(IUnk ctx/brush) @@ -181,14 +181,10 @@ draw-end: func [ release-pen-style: func [ ctx [draw-ctx!] /local - sthis [this!] - style [ID2D1StrokeStyle] + IUnk [IUnknown] ][ - if ctx/pen-style <> 0 [ - sthis: as this! ctx/pen-style - style: as ID2D1StrokeStyle sthis/vtbl - style/Release sthis - ctx/pen-style: 0 + unless null? ctx/pen-style [ + COM_SAFE_RELEASE(IUnk ctx/pen-style) ] ] @@ -212,7 +208,7 @@ update-pen-style: func [ d2d: as ID2D1Factory d2d-factory/vtbl hr: d2d/CreateStrokeStyle d2d-factory prop null 0 :style - ctx/pen-style: as integer! style/value + ctx/pen-style: as this! style/value ] OS-draw-pen: func [ diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 227dab3b92..ddf28318db 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -288,7 +288,7 @@ Red/System [ pen-join [integer!] pen-cap [integer!] pen-width [float32!] - pen-style [integer!] + pen-style [this!] pen-color [integer!] brush-color [integer!] font-color [integer!] From 99bae93d8fe650007e68b3199e242e21dff6971f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 2 Jan 2020 11:20:21 +0800 Subject: [PATCH 0682/3432] FEAT: support auto grad pen/fill-pen --- modules/view/backends/windows/direct2d.reds | 81 +++++-- modules/view/backends/windows/draw.reds | 233 ++++++++++++++++---- runtime/definitions.reds | 3 +- 3 files changed, 260 insertions(+), 57 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index a2b4c0f772..92c674b079 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -162,6 +162,13 @@ D2D1_HWND_RENDER_TARGET_PROPERTIES: alias struct! [ presentOptions [integer!] ] +D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES: alias struct! [ + startPoint.x [float32!] + startPoint.y [float32!] + endPoint.x [float32!] + endPoint.y [float32!] +] + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES: alias struct! [ center.x [float32!] center.y [float32!] @@ -239,12 +246,21 @@ CreateSolidColorBrush*: alias function! [ return: [integer!] ] +CreateLinearGradientBrush*: alias function! [ + this [this!] + gprops [D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES] + props [D2D1_BRUSH_PROPERTIES] + stops [this!] + brush [com-ptr!] + return: [integer!] +] + CreateRadialGradientBrush*: alias function! [ this [this!] gprops [D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES] props [D2D1_BRUSH_PROPERTIES] stops [this!] - brush [ptr-ptr!] + brush [com-ptr!] return: [integer!] ] @@ -321,21 +337,41 @@ SetCenter*: alias function! [ center [D2D_POINT_2F value] ] +GetCenter*: alias function! [ + this [this!] + return: [D2D_POINT_2F value] +] + SetGradientOriginOffset*: alias function! [ this [this!] Offset [D2D_POINT_2F value] ] +GetGradientOriginOffset*: alias function! [ + this [this!] + return: [D2D_POINT_2F value] +] + SetRadiusX*: alias function! [ this [this!] x [float32!] ] +GetRadiusX*: alias function! [ + this [this!] + return: [float32!] +] + SetRadiusY*: alias function! [ this [this!] y [float32!] ] +GetRadiusY*: alias function! [ + this [this!] + return: [float32!] +] + Resize*: alias function! [ this [this!] pixelSize [tagSIZE] @@ -362,7 +398,14 @@ CreateSwapChainForComposition*: alias function! [ return: [integer!] ] -ID2D1SolidColorBrush: alias struct! [ +#define ID2D1Resource [ + QueryInterface [QueryInterface!] + AddRef [AddRef!] + Release [Release!] + GetFactory [integer!] +] + +#define ID2D1Brush [ QueryInterface [QueryInterface!] AddRef [AddRef!] Release [Release!] @@ -371,27 +414,33 @@ ID2D1SolidColorBrush: alias struct! [ SetTransform [SetTransform*] GetOpacity [integer!] GetTransform [GetTransform*] +] + +ID2D1LinearGradientBrush: alias struct! [ + ID2D1Brush + SetStartPoint [function! [this [this!] startPoint [D2D_POINT_2F value]]] + SetEndPoint [function! [this [this!] endPoint [D2D_POINT_2F value]]] + GetStartPoint [function! [this [this!] return: [D2D_POINT_2F value]]] + GetEndPoint [function! [this [this!] return: [D2D_POINT_2F value]]] + GetGradientStopCollection [function! [this [this!] stop [ptr-ptr!]]] +] + +ID2D1SolidColorBrush: alias struct! [ + ID2D1Brush SetColor [function! [this [this!] color [D3DCOLORVALUE]]] GetColor [integer!] ] ID2D1RadialGradientBrush: alias struct! [ - QueryInterface [QueryInterface!] - AddRef [AddRef!] - Release [Release!] - GetFactory [integer!] - SetOpacity [integer!] - SetTransform [SetTransform*] - GetOpacity [integer!] - GetTransform [GetTransform*] + ID2D1Brush SetCenter [SetCenter*] SetGradientOriginOffset [SetGradientOriginOffset*] SetRadiusX [SetRadiusX*] SetRadiusY [SetRadiusY*] - GetCenter [integer!] - GetGradientOriginOffset [integer!] - GetRadiusX [integer!] - GetRadiusY [integer!] + GetCenter [GetCenter*] + GetGradientOriginOffset [GetGradientOriginOffset*] + GetRadiusX [GetRadiusX*] + GetRadiusY [GetRadiusY*] GetGradientStopCollection [integer!] ] @@ -755,7 +804,7 @@ DrawBitmap*: alias function! [ CreateBitmapBrush [CreateBitmapBrush*] CreateSolidColorBrush [CreateSolidColorBrush*] CreateGradientStopCollection [CreateGradientStopCollection*] - CreateLinearGradientBrush [integer!] + CreateLinearGradientBrush [CreateLinearGradientBrush*] CreateRadialGradientBrush [CreateRadialGradientBrush*] CreateCompatibleRenderTarget [function! [this [this!] size [SIZE_F! value] target [ptr-ptr!] return: [integer!]]] CreateLayer [integer!] @@ -860,7 +909,7 @@ ID2D1PathGeometry: alias struct! [ AddRef [AddRef!] Release [Release!] GetFactory [integer!] - GetBounds [integer!] + GetBounds [function! [this [this!] trans [D2D_MATRIX_3X2_F] bounds [RECT_F!] return: [integer!]]] GetWidenedBounds [integer!] StrokeContainsPoint [integer!] FillContainsPoint [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index a8d924524f..d9fcf03804 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -64,7 +64,6 @@ draw-begin: func [ ctx/pen-join: D2D1_LINE_JOIN_MITER ctx/pen-cap: D2D1_CAP_STYLE_FLAT ctx/pen-style: null - ctx/pen-type: DRAW_BRUSH_COLOR ctx/hwnd: hWnd update-pen-style ctx @@ -101,9 +100,11 @@ draw-begin: func [ d3d-clr: to-dx-color ctx/pen-color null dc/CreateSolidColorBrush this d3d-clr null :brush ctx/pen: as this! brush/value + ctx/pen-type: DRAW_BRUSH_COLOR dc/CreateSolidColorBrush this d3d-clr null :brush ctx/brush: as this! brush/value + ctx/brush-type: DRAW_BRUSH_NONE if hWnd <> null [ values: get-face-values hWnd @@ -284,6 +285,138 @@ OS-draw-text: func [ true ] +set-linear-points: func [ + brush [this!] + type [integer!] + upper-x [float32!] + upper-y [float32!] + lower-x [float32!] + lower-y [float32!] + /local + lin [ID2D1LinearGradientBrush] + pt [D2D_POINT_2F value] +][ + lin: as ID2D1LinearGradientBrush brush/vtbl + if type = DRAW_BRUSH_GRADIENT_SMART [ + pt/x: upper-x + pt/y: upper-y + lin/SetStartPoint brush pt + pt/x: lower-x + pt/y: lower-y + lin/SetEndPoint brush pt + exit + ] + if type = DRAW_BRUSH_GRADIENT [ + pt: lin/GetStartPoint brush + pt/x: pt/x + upper-x + pt/y: pt/y + upper-y + lin/SetStartPoint brush pt + pt: lin/GetEndPoint brush + pt/x: pt/x + upper-x + pt/y: pt/x + upper-y + lin/SetEndPoint brush pt + exit + ] +] + +set-radial-points: func [ + brush [this!] + type [integer!] + upper-x [float32!] + upper-y [float32!] + lower-x [float32!] + lower-y [float32!] + /local + rad [ID2D1RadialGradientBrush] + pt [D2D_POINT_2F value] + t1 [float32!] + t2 [float32!] +][ + rad: as ID2D1RadialGradientBrush brush/vtbl + if type = DRAW_BRUSH_GRADIENT_SMART [ + pt/x: upper-x + lower-x / as float32! 2.0 + pt/y: upper-y + lower-y / as float32! 2.0 + rad/SetCenter brush pt + pt/x: as float32! 0.0 + pt/y: as float32! 0.0 + rad/SetGradientOriginOffset brush pt + t1: lower-x - upper-x + t1: t1 / as float32! 2.0 + t2: lower-y - upper-y + t2: t2 / as float32! 2.0 + if t1 > t2 [t1: t2] + rad/SetRadiusX brush t1 + rad/SetRadiusY brush t1 + exit + ] + if type = DRAW_BRUSH_GRADIENT [ + pt: rad/GetCenter brush + pt/x: pt/x + upper-x + pt/y: pt/y + upper-y + rad/SetCenter brush pt + pt: rad/GetGradientOriginOffset brush + pt/x: pt/x + upper-x + pt/y: pt/y + upper-y + rad/SetGradientOriginOffset brush pt + exit + ] +] + +check-grad-points: func [ + brush [this!] + type [integer!] + grad-type [integer!] + upper-x [float32!] + upper-y [float32!] + lower-x [float32!] + lower-y [float32!] + /local + t [float32!] +][ + if upper-x > lower-x [ + t: upper-x + upper-x: lower-x + lower-x: t + ] + if upper-y > lower-y [ + t: upper-y + upper-y: lower-y + lower-y: t + ] + if grad-type = linear [ + set-linear-points brush type upper-x upper-y lower-x lower-y + exit + ] + if grad-type = radial [ + set-radial-points brush type upper-x upper-y lower-x lower-y + exit + ] +] + +check-grad-rect: func [ + brush [this!] + type [integer!] + grad-type [integer!] + bounds [RECT_F!] +][ + check-grad-points + brush type grad-type + bounds/left bounds/top bounds/right bounds/bottom +] + +check-grad-line: func [ + brush [this!] + type [integer!] + grad-type [integer!] + start [red-pair!] + end [red-pair!] +][ + check-grad-points + brush type grad-type + as float32! start/x as float32! start/y + as float32! end/x as float32! end/y +] + OS-draw-shape-beginpath: func [ ctx [draw-ctx!] /local @@ -325,6 +458,8 @@ OS-draw-shape-endpath: func [ sthis [this!] gsink [ID2D1GeometrySink] hr [integer!] + m [D2D_MATRIX_3X2_F value] + bounds [RECT_F! value] this [this!] dc [ID2D1DeviceContext] ][ @@ -338,12 +473,17 @@ OS-draw-shape-endpath: func [ hr: gsink/Close sthis gsink/Release sthis + matrix2d/identity m + gpath/GetBounds pthis :m :bounds + this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -648,26 +788,6 @@ OS-draw-anti-alias: func [ dc/SetAntialiasMode this either on? [0][1] ] -calculate-gradient-pos: func [ - brush [this!] - path [this!] - type [integer!] - /local - radial [ID2D1RadialGradientBrush] -][ - either type = linear [ - 0 - ][ - radial: as ID2D1RadialGradientBrush brush/vtbl - ;@@ get the centroid of the shape or just use the center of the bounding box? - ;@@ check how does SVG or other graphic libraries do it. - ;radial/SetCenter brush - ;radial/SetGradientOriginOffset brush - ;radial/SetRadiusX brush - ;radial/SetRadiusY brush - ] -] - _OS-draw-polygon: func [ ctx [draw-ctx!] start [red-pair!] @@ -683,6 +803,8 @@ _OS-draw-polygon: func [ sthis [this!] gsink [ID2D1GeometrySink] point [D2D_POINT_2F value] + m [D2D_MATRIX_3X2_F value] + bounds [RECT_F! value] this [this!] dc [ID2D1DeviceContext] ][ @@ -709,18 +831,17 @@ _OS-draw-polygon: func [ hr: gsink/Close sthis gsink/Release sthis + matrix2d/identity m + gpath/GetBounds pthis :m :bounds + this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ - if ctx/brush-type = DRAW_BRUSH_GRADIENT_SMART [ - calculate-gradient-pos ctx/brush pthis ctx/grad-type - ] + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ - if ctx/pen-type = DRAW_BRUSH_GRADIENT_SMART [ - calculate-gradient-pos ctx/pen pthis ctx/grad-type - ] + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -742,13 +863,16 @@ OS-draw-line: func [ pt1: pt0 + 1 either pt1 = end [ - dc/DrawLine - this - as float32! pt0/x as float32! pt0/y - as float32! pt1/x as float32! pt1/y - ctx/pen - ctx/pen-width - ctx/pen-style + if ctx/pen-type <> DRAW_BRUSH_NONE [ + check-grad-line ctx/pen ctx/pen-type ctx/pen-grad-type pt0 pt1 + dc/DrawLine + this + as float32! pt0/x as float32! pt0/y + as float32! pt1/x as float32! pt1/y + ctx/pen + ctx/pen-width + ctx/pen-style + ] ][ _OS-draw-polygon ctx point end no ] @@ -816,9 +940,11 @@ OS-draw-box: func [ rc/left: as float32! upper/x rc/top: as float32! upper/y if ctx/brush-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc dc/FillRectangle this rc ctx/brush ] if ctx/pen-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -891,6 +1017,8 @@ OS-draw-spline: func [ sthis [this!] gsink [ID2D1GeometrySink] point [D2D_POINT_2F value] + m [D2D_MATRIX_3X2_F value] + bounds [RECT_F! value] this [this!] dc [ID2D1DeviceContext] pt [red-pair!] @@ -963,12 +1091,17 @@ OS-draw-spline: func [ hr: gsink/Close sthis gsink/Release sthis + matrix2d/identity m + gpath/GetBounds pthis :m :bounds + this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1188,6 +1321,8 @@ OS-draw-curve: func [ sthis [this!] gsink [ID2D1GeometrySink] point [D2D_POINT_2F value] + m [D2D_MATRIX_3X2_F value] + bounds [RECT_F! value] this [this!] dc [ID2D1DeviceContext] ][ @@ -1228,12 +1363,17 @@ OS-draw-curve: func [ hr: gsink/Close sthis gsink/Release sthis + matrix2d/identity m + gpath/GetBounds pthis :m :bounds + this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1603,12 +1743,13 @@ OS-draw-grad-pen: func [ this [this!] unk [IUnknown] gprops [D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES value] + lprops [D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES value] gstops [D2D1_GRADIENT_STOP] x [float!] y [float!] start [float!] stop [float!] - brush [ptr-value!] + brush [com-ptr! value] int [red-integer!] f [red-float!] head [red-value!] @@ -1649,16 +1790,26 @@ OS-draw-grad-pen: func [ true [wrap: 0] ] - ctx/grad-type: type + dc/CreateGradientStopCollection this grad-stops count 0 wrap :sc either type = linear [ - 0 + either skip-pos? [gtype: DRAW_BRUSH_GRADIENT_SMART][ + gtype: DRAW_BRUSH_GRADIENT + pt: as red-pair! positions + lprops/startPoint.x: as float32! pt/x + lprops/startPoint.y: as float32! pt/y + pt: pt + 1 + lprops/endPoint.x: as float32! pt/x + lprops/endPoint.y: as float32! pt/y + ] + dc/CreateLinearGradientBrush this lprops null sc/value :brush ][ - dc/CreateGradientStopCollection this grad-stops count 0 wrap :sc either skip-pos? [gtype: DRAW_BRUSH_GRADIENT_SMART][ gtype: DRAW_BRUSH_GRADIENT pt: as red-pair! positions gprops/center.x: as float32! pt/x gprops/center.y: as float32! pt/y + gprops/offset.x: as float32! pt/x + gprops/offset.x: as float32! pt/y gprops/radius.x: get-float32 as red-integer! pt + 1 gprops/radius.y: gprops/radius.x if focal? [ @@ -1674,12 +1825,14 @@ OS-draw-grad-pen: func [ either brush? [ COM_SAFE_RELEASE(unk ctx/brush) - ctx/brush: as this! brush/value + ctx/brush: brush/value ctx/brush-type: gtype + ctx/brush-grad-type: type ][ COM_SAFE_RELEASE(unk ctx/pen) - ctx/pen: as this! brush/value + ctx/pen: brush/value ctx/pen-type: gtype + ctx/pen-grad-type: type ] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index ddf28318db..37837a16e7 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -297,7 +297,8 @@ Red/System [ scale-ratio [float32!] pen-type [integer!] brush-type [integer!] - grad-type [integer!] ;-- gradient type: radial, linear + pen-grad-type [integer!] ;-- gradient type: radial, linear + brush-grad-type [integer!] ;-- gradient type: radial, linear on-image? [logic!] ;-- drawing on image? font-color? [logic!] shadow? [logic!] From c80539cce37a04d46b0c90fbfa69cc11ed6f87e7 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 2 Jan 2020 15:53:01 +0800 Subject: [PATCH 0683/3432] FIX: brush api issues --- modules/view/backends/windows/direct2d.reds | 8 ++++---- modules/view/backends/windows/draw.reds | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 92c674b079..ca973ac8c6 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -339,7 +339,7 @@ SetCenter*: alias function! [ GetCenter*: alias function! [ this [this!] - return: [D2D_POINT_2F value] + center [D2D_POINT_2F] ] SetGradientOriginOffset*: alias function! [ @@ -349,7 +349,7 @@ SetGradientOriginOffset*: alias function! [ GetGradientOriginOffset*: alias function! [ this [this!] - return: [D2D_POINT_2F value] + Offset [D2D_POINT_2F] ] SetRadiusX*: alias function! [ @@ -420,8 +420,8 @@ ID2D1LinearGradientBrush: alias struct! [ ID2D1Brush SetStartPoint [function! [this [this!] startPoint [D2D_POINT_2F value]]] SetEndPoint [function! [this [this!] endPoint [D2D_POINT_2F value]]] - GetStartPoint [function! [this [this!] return: [D2D_POINT_2F value]]] - GetEndPoint [function! [this [this!] return: [D2D_POINT_2F value]]] + GetStartPoint [function! [this [this!] startPoint [D2D_POINT_2F]]] + GetEndPoint [function! [this [this!] startPoint [D2D_POINT_2F]]] GetGradientStopCollection [function! [this [this!] stop [ptr-ptr!]]] ] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index d9fcf03804..a37a34c775 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -307,11 +307,11 @@ set-linear-points: func [ exit ] if type = DRAW_BRUSH_GRADIENT [ - pt: lin/GetStartPoint brush + lin/GetStartPoint brush :pt pt/x: pt/x + upper-x pt/y: pt/y + upper-y lin/SetStartPoint brush pt - pt: lin/GetEndPoint brush + lin/GetEndPoint brush :pt pt/x: pt/x + upper-x pt/y: pt/x + upper-y lin/SetEndPoint brush pt @@ -350,11 +350,11 @@ set-radial-points: func [ exit ] if type = DRAW_BRUSH_GRADIENT [ - pt: rad/GetCenter brush + rad/GetCenter brush :pt pt/x: pt/x + upper-x pt/y: pt/y + upper-y rad/SetCenter brush pt - pt: rad/GetGradientOriginOffset brush + rad/GetGradientOriginOffset brush :pt pt/x: pt/x + upper-x pt/y: pt/y + upper-y rad/SetGradientOriginOffset brush pt From 9c05a7bbf4eebe9023ce4611c24fc883eeb0069b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 2 Jan 2020 16:32:28 +0800 Subject: [PATCH 0684/3432] FEAT: grad's offset will use world coordination --- modules/view/backends/windows/draw.reds | 85 +++++++++++-------------- 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index a37a34c775..54a1b4c969 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -296,27 +296,14 @@ set-linear-points: func [ lin [ID2D1LinearGradientBrush] pt [D2D_POINT_2F value] ][ + if type <> DRAW_BRUSH_GRADIENT_SMART [exit] lin: as ID2D1LinearGradientBrush brush/vtbl - if type = DRAW_BRUSH_GRADIENT_SMART [ - pt/x: upper-x - pt/y: upper-y - lin/SetStartPoint brush pt - pt/x: lower-x - pt/y: lower-y - lin/SetEndPoint brush pt - exit - ] - if type = DRAW_BRUSH_GRADIENT [ - lin/GetStartPoint brush :pt - pt/x: pt/x + upper-x - pt/y: pt/y + upper-y - lin/SetStartPoint brush pt - lin/GetEndPoint brush :pt - pt/x: pt/x + upper-x - pt/y: pt/x + upper-y - lin/SetEndPoint brush pt - exit - ] + pt/x: upper-x + pt/y: upper-y + lin/SetStartPoint brush pt + pt/x: lower-x + pt/y: lower-y + lin/SetEndPoint brush pt ] set-radial-points: func [ @@ -332,34 +319,21 @@ set-radial-points: func [ t1 [float32!] t2 [float32!] ][ + if type <> DRAW_BRUSH_GRADIENT_SMART [exit] rad: as ID2D1RadialGradientBrush brush/vtbl - if type = DRAW_BRUSH_GRADIENT_SMART [ - pt/x: upper-x + lower-x / as float32! 2.0 - pt/y: upper-y + lower-y / as float32! 2.0 - rad/SetCenter brush pt - pt/x: as float32! 0.0 - pt/y: as float32! 0.0 - rad/SetGradientOriginOffset brush pt - t1: lower-x - upper-x - t1: t1 / as float32! 2.0 - t2: lower-y - upper-y - t2: t2 / as float32! 2.0 - if t1 > t2 [t1: t2] - rad/SetRadiusX brush t1 - rad/SetRadiusY brush t1 - exit - ] - if type = DRAW_BRUSH_GRADIENT [ - rad/GetCenter brush :pt - pt/x: pt/x + upper-x - pt/y: pt/y + upper-y - rad/SetCenter brush pt - rad/GetGradientOriginOffset brush :pt - pt/x: pt/x + upper-x - pt/y: pt/y + upper-y - rad/SetGradientOriginOffset brush pt - exit - ] + pt/x: upper-x + lower-x / as float32! 2.0 + pt/y: upper-y + lower-y / as float32! 2.0 + rad/SetCenter brush pt + pt/x: as float32! 0.0 + pt/y: as float32! 0.0 + rad/SetGradientOriginOffset brush pt + t1: lower-x - upper-x + t1: t1 / as float32! 2.0 + t2: lower-y - upper-y + t2: t2 / as float32! 2.0 + if t1 > t2 [t1: t2] + rad/SetRadiusX brush t1 + rad/SetRadiusY brush t1 ] check-grad-points: func [ @@ -373,6 +347,7 @@ check-grad-points: func [ /local t [float32!] ][ + if type <> DRAW_BRUSH_GRADIENT_SMART [exit] if upper-x > lower-x [ t: upper-x upper-x: lower-x @@ -399,6 +374,7 @@ check-grad-rect: func [ grad-type [integer!] bounds [RECT_F!] ][ + if type <> DRAW_BRUSH_GRADIENT_SMART [exit] check-grad-points brush type grad-type bounds/left bounds/top bounds/right bounds/bottom @@ -411,6 +387,7 @@ check-grad-line: func [ start [red-pair!] end [red-pair!] ][ + if type <> DRAW_BRUSH_GRADIENT_SMART [exit] check-grad-points brush type grad-type as float32! start/x as float32! start/y @@ -940,11 +917,21 @@ OS-draw-box: func [ rc/left: as float32! upper/x rc/top: as float32! upper/y if ctx/brush-type <> DRAW_BRUSH_NONE [ - check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc + either ctx/brush-grad-type = linear [ + check-grad-points ctx/brush ctx/brush-type ctx/brush-grad-type + rc/left rc/top rc/right rc/top + ][ + check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc + ] dc/FillRectangle this rc ctx/brush ] if ctx/pen-type <> DRAW_BRUSH_NONE [ - check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc + either ctx/pen-grad-type = linear [ + check-grad-points ctx/pen ctx/pen-type ctx/pen-grad-type + rc/left rc/top rc/right rc/top + ][ + check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc + ] dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] From 748b67201183039735a4a6b469f2fa09cb7aab2b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 2 Jan 2020 17:02:51 +0800 Subject: [PATCH 0685/3432] TESTS: update linear fill-pen tests by using absolute coordination --- tests/complexpen-test.red | 77 +++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/tests/complexpen-test.red b/tests/complexpen-test.red index f0f79d3d9e..c3b3fd01be 100644 --- a/tests/complexpen-test.red +++ b/tests/complexpen-test.red @@ -13,6 +13,9 @@ height: 100 step-x: 10 step-y: 30 +box-start: 0x0 +box-stop: 0x0 + bitmap-1: make image! 30x30 draw bitmap-1 [line 0x0 30x30] bitmap-2: make image! 30x30 @@ -113,22 +116,35 @@ drawings: [ ( as-pair start-x + width start-y + height ) text ( as-pair start-x + (1 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0" - fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 - box - ( as-pair start-x + (1 * (width + step-x)) start-y ) - ( as-pair start-x + width + (1 * (width + step-x)) start-y + height ) + fill-pen linear red 0.1 green 0.8 blue 1.0 + ( + box-start: as-pair start-x + (1 * (width + step-x)) start-y + box-stop: as-pair start-x + width + (1 * (width + step-x)) start-y + height + box-start + 0x0 + ) + (box-start + 50x0) + box (box-start) (box-stop) text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x50" - fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 - box - ( as-pair start-x + (2 * (width + step-x)) start-y ) - ( as-pair start-x + width + (2 * (width + step-x)) start-y + height ) + fill-pen linear red 0.1 green 0.8 blue 1.0 + ( + box-start: as-pair start-x + (2 * (width + step-x)) start-y + box-stop: as-pair start-x + width + (2 * (width + step-x)) start-y + height + box-start + 0x0 + ) + (box-start + 50x50) + box (box-start) (box-stop) text ( as-pair start-x + (3 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0 reflect" - fill-pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 reflect - box - ( as-pair start-x + (3 * (width + step-x)) start-y ) - ( as-pair start-x + width + (3 * (width + step-x)) start-y + height ) + fill-pen linear red 0.1 green 0.8 blue 1.0 + ( + box-start: as-pair start-x + (3 * (width + step-x)) start-y + box-stop: as-pair start-x + width + (3 * (width + step-x)) start-y + height + box-start + 0x0 + ) + (box-start + 50x0) + reflect + box (box-start) (box-stop) text ( as-pair start-x start-y + (1 * (height + step-y)) - 20 ) "no stops" @@ -138,22 +154,35 @@ drawings: [ ( as-pair start-x + width start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0" - fill-pen linear red green blue 0x0 50x0 - box - ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) ) - ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) + fill-pen linear red green blue + ( + box-start: as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) + box-stop: as-pair start-x + width + (1 * (width + step-x)) start-y + height + (1 * (height + step-y)) + box-start + 0x0 + ) + (box-start + 50x0) + box (box-start) (box-stop) text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x50" - fill-pen linear red green blue 0x0 50x50 - box - ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) ) - ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) + fill-pen linear red green blue + ( + box-start: as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) + box-stop: as-pair start-x + width + (2 * (width + step-x)) start-y + height + (1 * (height + step-y)) + box-start + 0x0 + ) + (box-start + 50x50) + box (box-start) (box-stop) text ( as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0 reflect" - fill-pen linear red green blue 0x0 50x0 reflect - box - ( as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) ) - ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) + fill-pen linear red green blue + ( + box-start: as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) + box-stop: as-pair start-x + width + (3 * (width + step-x)) start-y + height + (1 * (height + step-y)) + box-start + 0x0 + ) + (box-start + 50x0) + reflect + box (box-start) (box-stop) text ( as-pair start-x start-y + (2 * (height + step-y)) - 20 ) "no stops; scale 2 1" From 5f25bed6446f28bc4e3fb4fbd97e83c94226060e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 2 Jan 2020 17:50:48 +0100 Subject: [PATCH 0686/3432] FEAT: adds some optional debugging logs to lexer. --- runtime/lexer.reds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c564d1ba94..773246dcde 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -16,6 +16,7 @@ Red/System [ ] lexer: context [ + verbose: 0 #include %lexer-transitions.reds @@ -1704,12 +1705,14 @@ lexer: context [ offset: 0 loop as-integer lex/in-end - p [ + #if debug? = yes [probe ["=== " p/1 " ==="]] cp: as-integer p/value flags: lex-classes/cp and FFFFFF00h or flags class: lex-classes/cp and FFh index: state * (size? character-classes!) + class prev: state state: as-integer transitions/index + #if debug? = yes [if verbose > 0 [?? state]] offset: offset + as-integer skip-table/state if state > --EXIT_STATES-- [term?: yes break] line: line + as-integer line-table/class @@ -1719,6 +1722,7 @@ lexer: context [ prev: state index: state * (size? character-classes!) + C_EOF state: as-integer transitions/index + #if debug? = yes [if verbose > 0 [?? state]] ] assert state <= T_CMT assert start + offset <= p From aacabb5c699748b990b1025bd3f6d98c2a70207a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 2 Jan 2020 17:52:47 +0100 Subject: [PATCH 0687/3432] FIX: regression on loading path values. Case: load "either false [prints words-of system/words][print none]" --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 773246dcde..1aca262dbc 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -504,6 +504,7 @@ lexer: context [ store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here p: as red-point! lex/head - 1 ;-- get parent series + stype: p/y >> 16 either all [ lex/buffer <= p not any [stype = TYPE_BLOCK stype = TYPE_PAREN stype = TYPE_MAP] From 6b07306f75d04edf375da6a4f822371897bf8f44 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 3 Jan 2020 10:55:35 +0800 Subject: [PATCH 0688/3432] FEAT: support brush transform --- modules/view/backends/windows/direct2d.reds | 12 +- modules/view/backends/windows/draw.reds | 226 ++++++++++++++++++-- 2 files changed, 220 insertions(+), 18 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index ca973ac8c6..5fd0873377 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -405,7 +405,7 @@ CreateSwapChainForComposition*: alias function! [ GetFactory [integer!] ] -#define ID2D1Brush [ +#define ID2D1Brush* [ QueryInterface [QueryInterface!] AddRef [AddRef!] Release [Release!] @@ -416,8 +416,12 @@ CreateSwapChainForComposition*: alias function! [ GetTransform [GetTransform*] ] +ID2D1Brush: alias struct! [ + ID2D1Brush* +] + ID2D1LinearGradientBrush: alias struct! [ - ID2D1Brush + ID2D1Brush* SetStartPoint [function! [this [this!] startPoint [D2D_POINT_2F value]]] SetEndPoint [function! [this [this!] endPoint [D2D_POINT_2F value]]] GetStartPoint [function! [this [this!] startPoint [D2D_POINT_2F]]] @@ -426,13 +430,13 @@ ID2D1LinearGradientBrush: alias struct! [ ] ID2D1SolidColorBrush: alias struct! [ - ID2D1Brush + ID2D1Brush* SetColor [function! [this [this!] color [D3DCOLORVALUE]]] GetColor [integer!] ] ID2D1RadialGradientBrush: alias struct! [ - ID2D1Brush + ID2D1Brush* SetCenter [SetCenter*] SetGradientOriginOffset [SetGradientOriginOffset*] SetRadiusX [SetRadiusX*] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 54a1b4c969..ccc3f8b61b 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -394,6 +394,69 @@ check-grad-line: func [ as float32! end/x as float32! end/y ] +set-linear-transform: func [ + brush [this!] + /local + lin [ID2D1LinearGradientBrush] + pt [D2D_POINT_2F value] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] + r [D2D_MATRIX_3X2_F value] +][ + lin: as ID2D1LinearGradientBrush brush/vtbl + lin/GetStartPoint brush :pt + matrix2d/identity :m + m/_31: pt/x + m/_32: pt/y + lin/GetTransform brush :t + matrix2d/mul :m :t :r + m/_31: (as float32! 0.0) - pt/x + m/_32: (as float32! 0.0) - pt/y + matrix2d/mul :r :m :t + lin/SetTransform brush :t +] + +set-radial-transform: func [ + brush [this!] + /local + rad [ID2D1RadialGradientBrush] + pt [D2D_POINT_2F value] + m [D2D_MATRIX_3X2_F value] + t [D2D_MATRIX_3X2_F value] + r [D2D_MATRIX_3X2_F value] +][ + rad: as ID2D1RadialGradientBrush brush/vtbl + rad/GetCenter brush :pt + matrix2d/identity :m + m/_31: pt/x + m/_32: pt/y + rad/GetTransform brush :t + matrix2d/mul :m :t :r + m/_31: (as float32! 0.0) - pt/x + m/_32: (as float32! 0.0) - pt/y + matrix2d/mul :r :m :t + rad/SetTransform brush :t +] + +transform-grad: func [ + brush [this!] + type [integer!] + grad-type [integer!] +][ + if all [ + type <> DRAW_BRUSH_GRADIENT + type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + if grad-type = linear [ + set-linear-transform brush + exit + ] + if grad-type = radial [ + set-radial-transform brush + exit + ] +] + OS-draw-shape-beginpath: func [ ctx [draw-ctx!] /local @@ -457,10 +520,12 @@ OS-draw-shape-endpath: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -815,10 +880,12 @@ _OS-draw-polygon: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -842,6 +909,7 @@ OS-draw-line: func [ either pt1 = end [ if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-line ctx/pen ctx/pen-type ctx/pen-grad-type pt0 pt1 + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawLine this as float32! pt0/x as float32! pt0/y @@ -923,6 +991,7 @@ OS-draw-box: func [ ][ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc ] + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type dc/FillRectangle this rc ctx/brush ] if ctx/pen-type <> DRAW_BRUSH_NONE [ @@ -932,6 +1001,7 @@ OS-draw-box: func [ ][ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc ] + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -1085,10 +1155,12 @@ OS-draw-spline: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1357,10 +1429,12 @@ OS-draw-curve: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1844,6 +1918,8 @@ OS-matrix-rotate: func [ dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ rad: PI / 180.0 * get-float angle either pen-fill = -1 [ @@ -1859,8 +1935,29 @@ OS-matrix-rotate: func [ ] dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m + either angle <> as red-integer! center [ + matrix2d/translate :m as float32! 0 - center/x as float32! 0 - center/y :t + matrix2d/rotate :t as float32! rad :m + matrix2d/translate :m as float32! center/x as float32! center/y :t + ][ + matrix2d/rotate :m as float32! rad :t + ] + brush/SetTransform bthis :t ] ] @@ -1874,6 +1971,8 @@ OS-matrix-scale: func [ dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -1882,8 +1981,23 @@ OS-matrix-scale: func [ matrix2d/scale :m get-float32 sx get-float32 sy :t dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m + matrix2d/scale :m get-float32 sx get-float32 sy :t + brush/SetTransform bthis :t ] ] @@ -1897,6 +2011,8 @@ OS-matrix-translate: func [ dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -1905,8 +2021,23 @@ OS-matrix-translate: func [ matrix2d/translate :m as float32! x as float32! y :t dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m + matrix2d/translate :m as float32! x as float32! y :t + brush/SetTransform bthis :t ] ] @@ -1922,6 +2053,8 @@ OS-matrix-skew: func [ t [D2D_MATRIX_3X2_F value] x [float32!] y [float32!] + bthis [this!] + brush [ID2D1Brush] ][ x: as float32! degree-to-radians get-float sx TYPE_TANGENT y: as float32! degree-to-radians get-float sy TYPE_TANGENT @@ -1932,8 +2065,23 @@ OS-matrix-skew: func [ matrix2d/skew :m x y :t dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m + matrix2d/skew :m x y :t + brush/SetTransform bthis :t ] ] @@ -2019,6 +2167,8 @@ OS-matrix-reset: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -2027,8 +2177,22 @@ OS-matrix-reset: func [ matrix2d/identity :m dc/SetTransform this :m ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + matrix2d/identity :m + brush/SetTransform bthis :m ] ] @@ -2040,6 +2204,8 @@ OS-matrix-invert: func [ dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -2048,8 +2214,23 @@ OS-matrix-invert: func [ matrix2d/invert :m :t dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m + matrix2d/invert :m :t + brush/SetTransform bthis :t ] ] @@ -2064,6 +2245,8 @@ OS-matrix-set: func [ m0 [D2D_MATRIX_3X2_F value] m [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] + bthis [this!] + brush [ID2D1Brush] ][ val: as red-integer! block/rs-head blk m/_11: get-float32 val @@ -2079,8 +2262,23 @@ OS-matrix-set: func [ matrix2d/mul m0 m t dc/SetTransform this :t ][ - ;-- TBD - exit + either pen-fill = pen [ + if all [ + ctx/pen-type <> DRAW_BRUSH_GRADIENT + ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/pen + ][ + if all [ + ctx/brush-type <> DRAW_BRUSH_GRADIENT + ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART + ][exit] + bthis: ctx/brush + ] + brush: as ID2D1Brush bthis/vtbl + brush/GetTransform bthis :m0 + matrix2d/mul m0 m t + brush/SetTransform bthis :t ] ] From 0a16930fc78b156270ae6d044fdc47a837f11895 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 3 Jan 2020 16:02:53 +0800 Subject: [PATCH 0689/3432] TESTS: update complex-pen tests --- tests/complexpen-test.red | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/complexpen-test.red b/tests/complexpen-test.red index c3b3fd01be..40464251db 100644 --- a/tests/complexpen-test.red +++ b/tests/complexpen-test.red @@ -123,6 +123,7 @@ drawings: [ box-start + 0x0 ) (box-start + 50x0) + repeat box (box-start) (box-stop) text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x50" @@ -133,6 +134,7 @@ drawings: [ box-start + 0x0 ) (box-start + 50x50) + repeat box (box-start) (box-stop) text ( as-pair start-x + (3 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0 reflect" @@ -161,6 +163,7 @@ drawings: [ box-start + 0x0 ) (box-start + 50x0) + repeat box (box-start) (box-stop) text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x50" @@ -171,6 +174,7 @@ drawings: [ box-start + 0x0 ) (box-start + 50x50) + repeat box (box-start) (box-stop) text ( as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0 reflect" @@ -192,19 +196,19 @@ drawings: [ ( as-pair start-x + width start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; rotate 45" - fill-pen linear red green blue rotate 'fill-pen 45 + fill-pen linear red green blue repeat rotate 'fill-pen 45 box ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; translate 50x0" - fill-pen linear red green blue translate 'fill-pen 50x0 + fill-pen linear red green blue repeat translate 'fill-pen 50x0 box ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; skew 50x50" - fill-pen linear red green blue skew 'fill-pen 50 50 + fill-pen linear red green blue repeat skew 'fill-pen 50 50 box ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) @@ -374,13 +378,13 @@ drawings: [ ( as-pair start-x + width start-y + height ) text ( as-pair start-x + (1 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x0" - pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 + pen linear red 0.1 green 0.8 blue 1.0 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height ) text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0; 50x50" - pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 + pen linear red 0.1 green 0.8 blue 1.0 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height ) @@ -399,13 +403,13 @@ drawings: [ ( as-pair start-x + width start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x0" - pen linear red green blue 0x0 50x0 + pen linear red green blue 0x0 50x0 repeat box ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops; 50x50" - pen linear red green blue 0x0 50x50 + pen linear red green blue 0x0 50x50 repeat box ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y)) ) @@ -424,19 +428,19 @@ drawings: [ ( as-pair start-x + width start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; rotate 45" - pen linear red green blue rotate 'pen 45 + pen linear red green blue repeat rotate 'pen 45 box ( as-pair start-x + (1 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; translate 50x0" - pen linear red green blue translate 'pen 50x0 + pen linear red green blue repeat translate 'pen 50x0 box ( as-pair start-x + (2 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) text ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) - 20 ) "no stops; skew 50x50" - pen linear red green blue skew 'pen 50 50 + pen linear red green blue repeat skew 'pen 50 50 box ( as-pair start-x + (3 * (width + step-x)) start-y + (2 * (height + step-y)) ) ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(2 * (height + step-y)) ) From a01fb41ac24efeccf804d3f9f4447463fc7c812a Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 3 Jan 2020 16:55:08 +0800 Subject: [PATCH 0690/3432] FIX: translate the brush's origin issue --- modules/view/backends/windows/draw.reds | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index ccc3f8b61b..011ffcdb8e 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -406,12 +406,12 @@ set-linear-transform: func [ lin: as ID2D1LinearGradientBrush brush/vtbl lin/GetStartPoint brush :pt matrix2d/identity :m - m/_31: pt/x - m/_32: pt/y - lin/GetTransform brush :t - matrix2d/mul :m :t :r m/_31: (as float32! 0.0) - pt/x m/_32: (as float32! 0.0) - pt/y + lin/GetTransform brush :t + matrix2d/mul :m :t :r + m/_31: pt/x + m/_32: pt/y matrix2d/mul :r :m :t lin/SetTransform brush :t ] @@ -428,12 +428,12 @@ set-radial-transform: func [ rad: as ID2D1RadialGradientBrush brush/vtbl rad/GetCenter brush :pt matrix2d/identity :m - m/_31: pt/x - m/_32: pt/y - rad/GetTransform brush :t - matrix2d/mul :m :t :r m/_31: (as float32! 0.0) - pt/x m/_32: (as float32! 0.0) - pt/y + rad/GetTransform brush :t + matrix2d/mul :m :t :r + m/_31: pt/x + m/_32: pt/y matrix2d/mul :r :m :t rad/SetTransform brush :t ] @@ -2057,7 +2057,7 @@ OS-matrix-skew: func [ brush [ID2D1Brush] ][ x: as float32! degree-to-radians get-float sx TYPE_TANGENT - y: as float32! degree-to-radians get-float sy TYPE_TANGENT + y: either sx = sy [as float32! 0.0][as float32! degree-to-radians get-float sy TYPE_TANGENT] either pen-fill = -1 [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl From 1ca14bdd0005dd736ff9c74f9767dc6d3ef901d8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 3 Jan 2020 19:14:47 +0100 Subject: [PATCH 0691/3432] FEAT: adds string! and /part support to TRANSCODE. --- environment/functions.red | 16 +++++------- environment/natives.red | 2 +- runtime/lexer.reds | 2 +- runtime/natives.reds | 54 +++++++++++++++++++++++++++++---------- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index fc9e9c37b6..772136171f 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -401,7 +401,7 @@ load: function [ ] unless out [out: make block! 10] - switch/default type?/word source [ + switch type?/word source [ file! [ suffix: suffix? source foreach [name codec] system/codecs [ @@ -424,20 +424,18 @@ load: function [ ][return none] source: source/3 ] - string! [source: to binary! src: source] - ][source] + ] - result: case [ - part [system/lexer/transcode/part to-string source out trap length] + out: case [ + part [transcode/part source length] ;trap [system/lexer/transcode to-string source out trap] next [ - out: transcode/next source - set position skip any [src source] count-chars source out/2 + set position second out: transcode/next source return either :all [reduce [out/1]][out/1] ] - 'else [out: transcode source] + 'else [transcode source] ] - either trap [result][ + either trap [out][ unless :all [if 1 = length? out [out: out/1]] out ] diff --git a/environment/natives.red b/environment/natives.red index 54271f214d..39ed7003ab 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -910,7 +910,7 @@ recycle: make native! [[ transcode: make native! [[ "Translates UTF-8 binary source to values. Returns one or several values in a block" - src [binary!] "UTF-8 input buffer" + src [binary! string!] "UTF-8 input buffer; string argument will be UTF-8 encoded" /next "Translate next complete value (blocks as single value)" /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1aca262dbc..8c9d719134 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1706,7 +1706,7 @@ lexer: context [ offset: 0 loop as-integer lex/in-end - p [ - #if debug? = yes [probe ["=== " p/1 " ==="]] + #if debug? = yes [if verbose > 0 [probe ["=== " p/1 " ==="]]] cp: as-integer p/value flags: lex-classes/cp and FFFFFF00h or flags class: lex-classes/cp and FFh diff --git a/runtime/natives.reds b/runtime/natives.reds index 3bca1a281d..8b89249747 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2730,18 +2730,18 @@ natives: context [ part [integer!] into [integer!] /local - bin [red-binary!] - slot [red-value!] - blk [red-block!] - s [series!] - offset [integer!] - len [integer!] - next? [logic!] + offset len type [integer!] + slot arg [red-value!] + bin bin2 [red-binary!] + int [red-integer!] + str [red-string!] + blk [red-block!] + s [series!] + next? [logic!] ][ #typecheck [next part into] next?: next > -1 - bin: as red-binary! stack/arguments slot: stack/push* if next? [ blk: block/preallocate as red-block! slot 2 no @@ -2749,14 +2749,40 @@ natives: context [ s/tail: s/offset + 2 slot: s/offset ] - len: binary/rs-length? bin offset: 0 - ;if OPTION?(part) [ - ; - ;] + len: -1 + bin: as red-binary! stack/arguments + type: TYPE_OF(bin) + arg: stack/arguments + part - lexer/scan slot binary/rs-head bin len next? no :offset - + if OPTION?(arg) [ + switch TYPE_OF(arg) [ + TYPE_INTEGER [ + int: as red-integer! arg + len: int/value + ] + TYPE_BINARY [ + if type <> TYPE_BINARY [fire [TO_ERROR(script not-same-type)]] + bin2: as red-binary! arg + len: bin2/head - bin/head + ] + TYPE_STRING [ + if type <> TYPE_STRING [fire [TO_ERROR(script not-same-type)]] + str: as red-string! arg + len: str/head - bin/head + ] + default [0] + ] + if len < 0 [len: 0] + ] + either type = TYPE_BINARY [ + if len < 0 [len: binary/rs-length? bin] + lexer/scan slot binary/rs-head bin len next? no :offset + ][ + str: as red-string! bin + if len < 0 [len: string/rs-length? str] + lexer/load-string slot str len next? no :offset + ] if next? [ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 bin/head: bin/head + offset From e7e106e9efa7880de8ba1678d9e9048b06e3cb84 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 3 Jan 2020 19:28:22 +0100 Subject: [PATCH 0692/3432] FEAT: removes the Parse-based runtime lexer. --- boot.red | 1 - build/includes.r | 1 - environment/functions.red | 1 + environment/lexer.red | 972 ------------------------------------ environment/system.red | 5 +- runtime/datatypes/time.reds | 7 - 6 files changed, 5 insertions(+), 982 deletions(-) delete mode 100644 environment/lexer.red diff --git a/boot.red b/boot.red index eceb214486..db79bc818c 100644 --- a/boot.red +++ b/boot.red @@ -20,7 +20,6 @@ Red [ #include %environment/colors.red #include %environment/functions.red #include %environment/system.red - #include %environment/lexer.red #include %environment/operators.red #register-intrinsics diff --git a/build/includes.r b/build/includes.r index 20d72188f7..9c4c6ca992 100644 --- a/build/includes.r +++ b/build/includes.r @@ -25,7 +25,6 @@ write %build/bin/sources.r set-cache [ ;%css-colors.red %datatypes.red %functions.red - %lexer.red %natives.red %networking.red %operators.red diff --git a/environment/functions.red b/environment/functions.red index 772136171f..0b60232482 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -425,6 +425,7 @@ load: function [ source: source/3 ] ] + if pre-load: :system/lexer/pre-load [do [pre-load source length]] out: case [ part [transcode/part source length] diff --git a/environment/lexer.red b/environment/lexer.red deleted file mode 100644 index 2ff33caebc..0000000000 --- a/environment/lexer.red +++ /dev/null @@ -1,972 +0,0 @@ -Red [ - Title: "Red runtime lexer" - Author: "Nenad Rakocevic" - File: %lexer.red - Tabs: 4 - Rights: "Copyright (C) 2014-2018 Red Foundation. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -system/lexer: context [ - - pre-load: none - - digit: charset "0123465798" - hexa-upper: charset "ABCDEF" - hexa-lower: charset "abcdef" - hexa: union digit hexa-upper - hexa-char: union hexa hexa-lower - not-word-char: charset {/\^^,[](){}"#%$@:;} - not-word-1st: union union not-word-char digit charset {'} - not-file-char: charset {[](){}"@:;} - not-str-char: #"^"" - not-mstr-char: #"}" - caret-char: charset [#"^(40)" - #"^(5F)"] - non-printable-char: charset [ - #"^(00)" - #"^(08)" ;-- (exclude TAB) - #"^(0A)" - #"^(1F)" - ] - integer-end: charset {^{"[]();:xX<} - ws-ASCII: charset " ^-^M" - ws-U+2k: charset [#"^(2000)" - #"^(200A)"] ;-- Unicode spaces in the U+2000-U+200A range - control-char: charset [ ;-- Control characters - #"^(00)" - #"^(1F)" ;-- C0 control codes - #"^(80)" - #"^(9F)" ;-- C1 control codes - ] - four: charset "01234" - half: charset "012345" - non-zero: charset "123456789" - path-end: charset {^{"[]();} - base64-char: union digit charset [ - #"A" - #"Z" #"a" - #"z" #"+" #"/" #"=" - ] - slash-end: charset {[](){}":;} - not-url-char: charset {[](){}";} - email-end: union not-file-char union ws-ASCII charset "<^/" - pair-end: charset {^{"[]();:} - file-end: charset {^{[]();:} - date-sep: charset "/-" - time-sep: charset "/T" - not-tag-1st: charset "=><[](){};^"" - - month-rule: [(m: none)] ;-- dynamically filled - mon-rule: [(m: none)] ;-- dynamically filled - - throw-error: function [spec [block!] /missing][ - type: spec/1 ;-- preserve lit-words from double reduction - spec: reduce spec - src: back tail spec - src/1: trim/tail either string? src/1 [ - form trim/with copy/part src/1 40 #"^/" - ][ - mold/flat/part src/1 40 - ] - if "^^/" = copy/part pos: skip tail src/1 -3 2 [remove/part pos 2] - spec/1: type - cause-error 'syntax any [all [missing 'missing] 'invalid] spec - ] - - make-hm: routine [h [integer!] m [integer!]][ - time/box (as-float h) * 3600.0 + ((as-float m) * 60.0) - ] - - make-msf: routine [m [integer!] s [float!]][ - time/box ((as-float m) * 60.0) + s - ] - - make-hms: routine [h [integer!] m [integer!] s [integer!]][ - time/box (as-float h) * 3600.0 + ((as-float m) * 60.0) + (as-float s) - ] - - make-hmsf: routine [h [integer!] m [integer!] s [float!]][ - time/box (as-float h) * 3600.0 + ((as-float m) * 60.0) + s - ] - - make-time: function [ - pos [string!] - hours [integer! none!] - mins [integer!] - secs [integer! float! none!] - neg? [logic!] - return: [time!] - ][ - if any [all [hours hours <> 0 mins < 0] all [secs secs < 0]][throw-error [time! pos]] - if hours [hours: absolute hours] - mins: absolute mins - - time: case [ - all [hours secs][ - either float? secs [ - make-hmsf hours mins secs - ][ - make-hms hours mins secs - ] - ] - hours [make-hm hours mins] - 'else [ - unless float? secs [] ;@@ TBD: error - make-msf mins secs - ] - ] - either neg? [negate time][time] - ] - - make-binary: routine [ - start [string!] - end [string!] - base [integer!] - /local - s [series!] - p [byte-ptr!] - len [integer!] - unit [integer!] - ret [red-binary!] - ][ - s: GET_BUFFER(start) - unit: GET_UNIT(s) - p: string/rs-head start - len: end/head - start/head - - ret: as red-binary! stack/arguments - ret/head: 0 - ret/header: TYPE_NONE - ret/node: switch base [ - 16 [binary/decode-16 p len unit] - 2 [binary/decode-2 p len unit] - 64 [binary/decode-64 p len unit] - ] - if ret/node <> null [ret/header: TYPE_BINARY] ;-- if null, return NONE! - ] - - make-tuple: routine [ - start [string!] - end [string!] - /local - s [series!] - err [integer!] - len [integer!] - unit [integer!] - p [byte-ptr!] - tp [byte-ptr!] - ret [red-value!] - ][ - s: GET_BUFFER(start) - unit: GET_UNIT(s) - p: string/rs-head start - len: end/head - start/head - ret: stack/arguments - err: 0 - - tokenizer/scan-tuple p len unit :err ret - assert err = 0 ;-- pre-checked validity - ret - ] - - make-number: routine [ - start [string!] - end [string!] - type [datatype!] - /local - s [series!] - len [integer!] - unit [integer!] - p [byte-ptr!] - err [integer!] - i [integer!] - ][ - if type/value <> TYPE_INTEGER [ - make-float start end type ;-- float! escape path - exit - ] - s: GET_BUFFER(start) - unit: GET_UNIT(s) - p: string/rs-head start - len: end/head - start/head - err: 0 - - i: tokenizer/scan-integer p len unit :err - - if err <> 0 [ - type/value: TYPE_FLOAT - make-float start end type ;-- fallback to float! loading - exit - ] - integer/box i - ] - - make-float: routine [ - start [string!] - end [string!] - type [datatype!] - /local - s [series!] - unit [integer!] - len [integer!] - p [byte-ptr!] - err [integer!] - f [float!] - ][ - s: GET_BUFFER(start) - unit: GET_UNIT(s) - p: string/rs-head start - len: end/head - start/head - err: 0 - - f: tokenizer/scan-float p len unit :err - - either type/value = TYPE_FLOAT [float/box f][percent/box f / 100.0] - ] - - make-hexa: routine [ - start [string!] - end [string!] - return: [integer!] - /local - s [series!] - unit [integer!] - p [byte-ptr!] - head [byte-ptr!] - p4 [int-ptr!] - n [integer!] - power [integer!] - cp [byte!] - ][ - s: GET_BUFFER(start) - unit: GET_UNIT(s) - - p: (string/rs-head end) - unit - head: string/rs-head start - - n: 0 - power: 0 - while [p >= head][ - cp: switch unit [ - Latin1 [p/value] - UCS-2 [as-byte ((as-integer p/2) << 8 + p/1)] - UCS-4 [p4: as int-ptr! p as-byte p4/value] - ] - if cp <> #"0" [ - case [ - all [#"0" <= cp cp <= #"9"][cp: cp - #"0"] - all [#"A" <= cp cp <= #"F"][cp: cp - #"A" + 10] - all [#"a" <= cp cp <= #"f"][cp: cp - #"a" + 10] - ] - n: n + ((as-integer cp) << power) - ] - power: power + 4 - p: p - unit - ] - n - ] - - make-char: routine [ - start [string!] - end [string!] - /local - n [integer!] - value [red-value!] - ][ - n: make-hexa start end - value: as red-value! integer/box n - set-type value TYPE_CHAR - ] - - push-path: routine [ - stack [block!] - type [datatype!] - /local - path [red-path!] - ][ - path: as red-path! block/make-at as red-block! ALLOC_TAIL(stack) 4 - path/header: switch type/value [ - TYPE_GET_WORD [TYPE_GET_PATH] - TYPE_LIT_WORD [TYPE_LIT_PATH] - default [TYPE_PATH] - ] - path/args: null - ] - - set-path: routine [ - stack [block!] - /local - path [red-path!] - ][ - path: as red-path! _series/pick as red-series! stack 1 null - path/args: null - set-type as red-value! path TYPE_SET_PATH - ] - - make-word: routine [ - src [string!] - end [string!] - type [datatype!] - ][ - set-type - as red-value! word/box (symbol/make-alt src end/head - src/head) ;-- word/box puts it in stack/arguments - type/value - ] - - to-word: func [ - stack [block!] - start [string!] - end [string!] - type [datatype!] - ][ - if (index? start) = (index? end) [throw-error [type back start]] - store stack make-word start end type - ] - - pop: function [stack [block!]][ - value: last stack - remove back tail stack - - either any [1 < length? stack head? stack/1][ - append/only last stack :value - ][ - pos: back tail stack ;-- root storage and offset-ed series (/into option) - pos/1: insert/only last stack :value - ] - ] - - store: function [stack [block!] value][ - either any [1 < length? stack head? stack/1][ - append last stack value - ][ - pos: back tail stack ;-- root storage and offset-ed series (/into option) - pos/1: insert last stack value - ] - ] - - new-line: routine [ - series [any-type!] - /local - blk [red-block!] - s [series!] - cell [red-value!] - ][ - assert any [ - TYPE_OF(series) = TYPE_BLOCK - TYPE_OF(series) = TYPE_PAREN - ] - blk: as red-block! series - s: GET_BUFFER(blk) - cell: s/offset + blk/head - - while [cell < s/tail][ - cell/header: cell/header or flag-new-line - cell: cell + 1 - ] - ] - - transcode: function [ - src [string!] - dst [block! none!] - trap [logic!] - /one - /only ;-- force returning the loaded value (with /one) - /part - length [integer! string!] - return: [block!] - /local - new s e c pos value cnt type process path - ][ - stack: clear [] - count?: yes ;-- if TRUE, lines counter is enabled - old-line: line: 1 - - append/only stack any [dst make block! 200] - - make-string: [ - new: make type len: (index? e) - index? s - parse/case/part s [ - any [ - escaped-char (append new value) - | #"^^" ;-- trash single caret chars - | set c skip (append new c) - ] - ] len - new - ] - - make-file: [ - new: make type (index? e) - index? s - buffer: copy/part s e - parse buffer [any [#"%" [2 hexa | (throw-error [type s])] | skip]] - append new dehex buffer - if type = file! [parse new [any [s: #"\" change s #"/" | skip]]] - new - ] - - byte: [ - "25" half - | "2" four digit - | "1" digit digit - | opt #"0" non-zero digit - | 0 2 #"0" digit - | 1 2 #"0" - ] - - ;-- Whitespaces list from: http://en.wikipedia.org/wiki/Whitespace_character - ws: [ - #"^/" ( - if count? [ - line: line + 1 - ;append/only lines to block! stack/tail? - ] - ) - | ws-ASCII ;-- only the common whitespaces are matched - ;| #"^(0085)" ;-- U+0085 (Newline) - | #"^(00A0)" ;-- U+00A0 (No-break space) - ;| #"^(1680)" ;-- U+1680 (Ogham space mark) - ;| #"^(180E)" ;-- U+180E (Mongolian vowel separator) - ;| ws-U+2k ;-- U+2000-U+200A range - ;| #"^(2028)" ;-- U+2028 (Line separator) - ;| #"^(2029)" ;-- U+2029 (Paragraph separator) - ;| #"^(202F)" ;-- U+202F (Narrow no-break space) - ;| #"^(205F)" ;-- U+205F (Medium mathematical space) - ;| #"^(3000)" ;-- U+3000 (Ideographic space) - ] - - newline-char: [ - #"^/" - | #"^(0085)" ;-- U+0085 (Newline) - | #"^(2028)" ;-- U+2028 (Line separator) - | #"^(2029)" ;-- U+2029 (Paragraph separator) - ] - - counted-newline: [pos: #"^/" (line: line + 1)] - - ws-no-count: [(count?: no) ws (count?: yes)] - - escaped-char: [ - "^^(" [ - [ ;-- special case first - "null" (value: #"^(00)") - | "back" (value: #"^(08)") - | "tab" (value: #"^(09)") - | "line" (value: #"^(0A)") - | "page" (value: #"^(0C)") - | "esc" (value: #"^(1B)") - | "del" (value: #"^~") - ] - | pos: [2 6 hexa-char] e: ( ;-- Unicode values allowed up to 10FFFFh - value: make-char pos e - ) - ] #")" - | #"^^" [ - [ - #"/" (value: #"^/") - | #"-" (value: #"^-") - | #"~" (value: #"^(del)") - | #"^^" (value: #"^^") ;-- caret escaping case - | #"{" (value: #"{") - | #"}" (value: #"}") - | #"^"" (value: #"^"") - ] - | pos: caret-char (value: pos/1 - 64) - ] - ] - - char-rule: [ - {#"} s: [ - escaped-char - | ahead [non-printable-char | not-str-char] - (throw-error [char! skip s -2]) - reject - | skip (value: s/1) - ][ - {"} - | (throw-error [char! skip s -2]) - ] - ] - - line-string: [ - #"^"" s: any [ - {^^"} - | ahead [#"^"" | newline-char] break - | escaped-char - | skip - ] - e: #"^"" - ] - - nested-curly-braces: [ - (cnt: 1) - any [ - counted-newline - | "^^{" - | "^^}" - | #"{" (cnt: cnt + 1) - | e: #"}" if (zero? cnt: cnt - 1) break - | escaped-char - | skip - ] - ] - - multiline-string: [ - #"{" s: nested-curly-braces ( - unless zero? cnt [throw-error [string! s]] - old-line: line - ) - ] - - string-rule: [(type: string!) line-string | multiline-string] - - tag-rule: [ - #"<" not [not-tag-1st | ws] (type: tag!) - s: some [#"^"" thru #"^"" | #"'" thru #"'" | e: #">" break | skip] - (if e/1 <> #">" [throw-error [tag! back s]]) - ] - - email-rule: [ - s: some [ahead email-end break | skip] #"@" - any [ahead email-end break | skip] e: - (type: email!) - ] - - base-2-rule: [ - "2#{" (type: binary!) [ - s: any [counted-newline | 8 [any [ws-no-count | comment-rule][#"0" | #"1" ]] | ws-no-count | comment-rule] e: #"}" - | (throw-error [binary! skip s -3]) - ] (base: 2) - ] - - base-16-rule: [ - opt "16" "#{" (type: binary!) [ - s: any [counted-newline | 2 hexa-char | ws-no-count | comment-rule] e: #"}" - | (throw-error [binary! skip s -2]) - ] (base: 16) - ] - - base-64-rule: [ - "64#{" (type: binary! cnt: 0) [ - s: any [counted-newline | base64-char | ws-no-count (cnt: cnt + 1) | comment-rule] e: #"}" - | (throw-error [binary! skip s -4]) - ]( - cnt: (offset? s e) - cnt - if all [0 < cnt cnt < 4][throw-error [binary! skip s -4]] - base: 64 - ) - ] - - binary-rule: [[base-16-rule | base-64-rule | base-2-rule] (old-line: line)] - - file-rule: [ - s: #"%" [ - #"{" (throw-error [file! s]) - | line-string (process: make-string type: file!) - | s: any [ahead [not-file-char | ws-no-count] break | skip] e: - (process: make-file type: file!) - ] - ] - - url-rule: [ - #":" not [not-url-char | ws-no-count | end] - any [#"@" | #":" | ahead [not-file-char | ws-no-count] break | skip] e: - (type: url! store stack do make-file) - ] - - symbol-rule: [ - (ot: none) some [ - ahead [not-word-char | ws-no-count | control-char] break - | #"<" ot: [ahead #"/" (ot: back ot) :ot break | none] ;-- a - | #">" if (ot) [(ot: back ot) :ot break] ;-- a - | skip - ] e: - ] - - begin-symbol-rule: [ ;-- 1st char in symbols is restricted - [not ahead [not-word-1st | ws-no-count | control-char]] - symbol-rule - ] - - path-rule: [ - ahead #"/" ( ;-- path detection barrier - push-path stack type ;-- create empty path - to-word stack s e word! ;-- push 1st path element - type: path! - ) - some [ - #"/" - s: [ - integer-number-rule (store stack make-number s e type) - | begin-symbol-rule (to-word stack s e word!) - | paren-rule - | #":" s: begin-symbol-rule (to-word stack s e get-word!) - ;@@ add more datatypes here - | (throw-error [path! path]) - reject - ] - ] - opt [#":" (type: set-path! set-path back tail stack)][ - ahead [path-end | ws-no-count | end] | (throw-error [type path]) - ] - (pop stack) - ] - - special-words: [ - #"%" [ws-no-count | ahead file-end | end] (value: "%") ;-- special case for remainder op! - | #"/" ahead [slash-end | #"/" | ws-no-count | control-char | end][ - #"/" - ahead [slash-end | ws-no-count | control-char | end] (value: "//") - | (value: "/") - ] - | "<>" (value: "<>") - ] - - word-rule: [ - (type: word!) special-words opt [#":" (type: set-word!)] - (to-word stack value tail value type) ;-- special case for / and // as words - | path: s: begin-symbol-rule (type: word!) [ - url-rule - | path-rule ;-- path matched - | opt [#":" (type: set-word!)] - (if type [to-word stack s e type]) ;-- word or set-word matched - ] - ] - - get-word-rule: [ - #":" (type: get-word!) [ - special-words (to-word stack value tail value type) - | s: begin-symbol-rule [ - path-rule (type: get-path!) - | (to-word stack s e type) ;-- get-word matched - ] - ] - ] - - lit-word-rule: [ - #"'" (type: lit-word!) [ - special-words (to-word stack value tail value type) - | [ - s: begin-symbol-rule [ - path-rule (type: lit-path!) ;-- path matched - | (to-word stack s e type) ;-- lit-word matched - ] - ] - ] - opt [#":" (throw-error [type back s])] - ] - - issue-rule: [ - #"#" (type: issue!) s: symbol-rule ( - if (index? s) = index? e [throw-error [type skip s -4]] - to-word stack s e type - ) - ] - - - refinement-rule: [ - #"/" [ - some #"/" (type: word!) e: ;-- ///... case - | ahead [not-word-char | ws-no-count | control-char] (type: word!) e: ;-- / case - | symbol-rule (type: refinement! s: next s) - ] - (to-word stack s e type) - ] - - sticky-word-rule: [ ;-- protect from sticky words typos - ahead [integer-end | ws-no-count | end | (throw-error [type s])] - ] - hexa-rule: [2 8 hexa e: #"h" ahead [integer-end | ws-no-count | end]] - - tuple-value-rule: [byte 2 11 [#"." byte] e: (type: tuple!)] - - tuple-rule: [tuple-value-rule sticky-word-rule] - - time-rule: [ - s: positive-integer-rule [ - float-number-rule (value: make-time pos none value make-number s e type neg?) ;-- mm:ss.dd - | (value2: make-number s e type) [ - #":" s: positive-integer-rule opt float-number-rule - (value: make-time pos value value2 make-number s e type neg?) ;-- hh:mm:ss[.dd] - | (value: make-time pos value value2 none neg?) ;-- hh:mm - ] - ] (type: time!) - ] - - day-year-rule: [ - s: opt #"-" 3 4 digit e: (year: make-number s e integer!) - | 1 2 digit e: ( - value: make-number s e integer! - either day [year: value + pick [2000 1900] 50 > value][day: value] - ) - ] - - date-rule: [ - ahead [opt #"-" 1 4 digit date-sep | 8 digit #"T"][ ;-- quick lookhead - s: 8 digit ee: #"T" ( ;-- yyyymmddT - year: make-number s e: skip s 4 integer! - month: make-number e e: skip e 2 integer! - day: make-number e e: skip e 2 integer! - date: make date! [day month year] - ) :ee - | day-year-rule sep: date-sep (sep: sep/1) [ - s: 1 2 digit e: (month: make-number s e integer!) - | case off month-rule (month: m) - | case off mon-rule (month: m) - ] - sep day-year-rule [if (not all [day month year]) fail | none] ( - date: make date! [day month year] - ) - | s: 4 digit #"-" ( - year: make-number s skip s 4 integer! - date: make date! [1 1 year] - )[ - "W" s: 2 digit (ee: none) opt [#"-" ee: non-zero] ( ;-- yyyy-Www - date/isoweek: make-number s skip s 2 integer! - if ee [date/weekday: to integer! ee/1 - #"0"] ;-- yyyy-Www-d - ) - | s: 3 digit (date/yearday: make-number s skip s 3 integer!) ;-- yyyy-ddd - ] (month: -1) - ]( - type: date! - if all [ - month <> -1 any [date/year <> year date/month <> month date/day <> day] - ][throw-error [type pos]] - day: month: year: none - ) opt [ - time-sep (ee: no) [ - s: 6 digit opt [#"." 1 9 digit ee:] ( ;-- Thhmmss[.sss] - hour: make-number s e: skip s 2 integer! - mn: make-number e e: skip e 2 integer! - date/time: either ee [ - sec: make-number e ee float! - make-hmsf hour mn sec - ][ - sec: make-number e e: skip e 2 integer! - make-hms hour mn sec - ] - ) - | 4 digit ( ;-- Thhmm - hour: make-number s e: skip s 2 integer! - mn: make-number e e: skip e 2 integer! - date/time: make-hms hour mn 0 - ) - | s: positive-integer-rule (value: make-number s e integer!) - #":" [(neg?: no) time-rule (date/time: value) | (throw-error [type pos])] - ] - opt [ - #"Z" | [#"-" (neg?: yes) | #"+" (neg?: no)][ - s: 4 digit ( ;-- +/-hhmm - hour: make-number s e: skip s 2 integer! - mn: make-number e e: skip e 2 integer! - ) - | 1 2 digit e: (hour: make-number s e integer! mn: none) ;-- +/-h, +/-hh - opt [#":" s: 2 digit e: (mn: make-number s e integer!)] - ] - (zone: make-hm hour any [mn 0] date/zone: either neg? [negate zone][zone]) - ] - ] sticky-word-rule (value: date) - ] - - positive-integer-rule: [digit any digit e: (type: integer!)] - - integer-number-rule: [ - opt [#"-" (neg?: yes) | #"+" (neg?: no)] digit any [digit | #"'" digit] e: - (type: integer!) - ] - - integer-rule: [ - float-special (value: make-number s e type) ;-- escape path for NaN, INFs - | (neg?: no) integer-number-rule - opt [float-number-rule | float-exp-rule e: (type: float!)] - opt [#"%" (type: percent!)] - sticky-word-rule - (value: make-number s e type) - opt [ - [#"x" | #"X"] [s: integer-number-rule | (throw-error [pair! pos])] - ahead [pair-end | ws-no-count | end | (throw-error [pair! pos])] - (value: as-pair value make-number s e type) - ] - opt [#":" [time-rule | (throw-error [type pos])]] - ] - - float-special: [ - s: opt #"-" "1.#" [ - [[#"N" | #"n"] [#"a" | #"A"] [#"N" | #"n"]] - | [[#"I" | #"i"] [#"N" | #"n"] [#"F" | #"f"]] - ] e: (type: float!) - ] - - float-exp-rule: [[#"e" | #"E"] opt [#"-" | #"+"] 1 3 digit] - - float-number-rule: [ - [#"." | #","] digit any [digit | #"'" digit] - opt float-exp-rule e: (type: float!) - ] - - float-rule: [ - opt [#"-" | #"+"] float-number-rule - opt [#"%" (type: percent!)] - sticky-word-rule - ] - - map-rule: [ - "#(" (append/only stack make block! 100) - any-value - #")" ( - value: back tail stack - value/1: make map! value/1 - pop stack - old-line: line - ) - ] - - block-rule: [ - #"[" ( - append/only stack make block! 100 - if line > old-line [old-line: line new-line back tail stack] - ) - any-value - #"]" ( - pop stack - old-line: line - ) - ] - - paren-rule: [ - #"(" ( - append/only stack make paren! 4 - if line > old-line [old-line: line new-line back tail stack] - ) - any-value - #")" ( - pop stack - old-line: line - ) - ] - - escaped-rule: [ - "#[" pos: any ws [ - "true" (value: true) - | "false" (value: false) - | [ - "none!" (value: none!) - | "logic!" (value: logic!) - | "block!" (value: block!) - | "integer!" (value: integer!) - | "word!" (value: word!) - | "set-word!" (value: set-word!) - | "get-word!" (value: get-word!) - | "lit-word!" (value: lit-word!) - | "refinement!" (value: refinement!) - ;| "binary!" (value: binary!) - | "string!" (value: string!) - | "char!" (value: char!) - | "bitset!" (value: bitset!) - | "path!" (value: path!) - | "set-path!" (value: set-path!) - | "lit-path!" (value: lit-path!) - | "get-path!" (value: get-path!) - | "native!" (value: native!) - | "action!" (value: action!) - | "op!" (value: op!) - | "issue!" (value: issue!) - | "paren!" (value: paren!) - | "function!" (value: function!) - | "routine!" (value: routine!) - ] - | "none" (value: none) - ] pos: any ws #"]" - ] - - comment-rule: [#";" [to #"^/" | to end] (old-line: line)] - - wrong-end: [( - ending: either 1 < length? stack [ - value: switch type?/word last stack [ - block! [#"]"] - paren! [#")"] - ] - quote (throw-error/missing [value pos]) - ][none] - ) - ending - ] - - literal-value: [ - pos: (e: none) s: [ - string-rule (store stack do make-string) - | block-rule - | comment-rule - | tuple-rule (store stack make-tuple s e) - | hexa-rule (store stack make-hexa s e) - | binary-rule if (value: make-binary s e base) (store stack value) - | email-rule (store stack do make-file) - | date-rule if (value) (store stack value) - | integer-rule if (value) (store stack value) - | float-rule if (value: make-float s e type) (store stack value) - | tag-rule (store stack do make-string) - | word-rule - | lit-word-rule - | get-word-rule - | refinement-rule - | file-rule (store stack value: do process) - | char-rule (if value > 10FFFFh [throw-error [char! skip pos -6]] store stack value) - | map-rule - | paren-rule - | escaped-rule (store stack value) - | issue-rule - ]( - if line > old-line [ - old-line: line - new-line back tail last stack - ] - ) - ] - - one-value: [any ws pos: literal-value pos: to end opt wrong-end] - any-value: [pos: any [some ws | literal-value e: if (not same? pos e)]] - red-rules: [any-value any ws opt wrong-end] - - if pre-load [do [pre-load src length]] - - set/any 'err try [ - unless either part [ - parse/case/part src red-rules length - ][ - parse/case src either one [one-value][red-rules] - ][ - unless tail? pos [ - if find ")]}" pos/1 [ - value: switch pos/1 [ - #")" [#"("] - #"]" [#"["] - #"}" [#"{"] - ] - pos: next pos - throw-error/missing [value back pos] - ] - throw-error ['value pos] - ] - ] - ] - either trap [ - reduce [stack/1 pos :err] - ][ - if error? :err [do :err] - either all [one not only][pos][stack/1] - ] - ] - - init: has [list p][ - list: system/locale/months - while [not tail? list][ - append month-rule list/1 - append/only month-rule p: copy quote (m: ?) - unless tail? next list [append month-rule '|] - p/2: index? list - append mon-rule copy/part list/1 3 - append/only mon-rule p - unless tail? next list [append mon-rule '|] - list: next list - ] - bind month-rule :transcode - bind mon-rule :transcode - ] - init -] diff --git a/environment/system.red b/environment/system.red index 0f2d7bde85..af7635774c 100644 --- a/environment/system.red +++ b/environment/system.red @@ -401,7 +401,10 @@ system: context [ ] ] - lexer: none + lexer: context [ + pre-load: none + ] + console: none view: none reactivity: none diff --git a/runtime/datatypes/time.reds b/runtime/datatypes/time.reds index 88596ffdda..e34e07af47 100644 --- a/runtime/datatypes/time.reds +++ b/runtime/datatypes/time.reds @@ -81,13 +81,6 @@ time: context [ t ] - box: func [ - time [float!] ;-- in nanoseconds - return: [red-time!] - ][ - make-at time stack/arguments - ] - push: func [ time [float!] ;-- in nanoseconds return: [red-time!] From a89927842b9dad790bbce3bc47e33a5cf7c3ee26 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 4 Jan 2020 10:05:08 +0800 Subject: [PATCH 0693/3432] FIX: save brush matrix to fix transform-grad issue --- modules/view/backends/windows/draw.reds | 229 +++++++++--------------- runtime/definitions.reds | 10 ++ 2 files changed, 93 insertions(+), 146 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 011ffcdb8e..dd6a4a2ed8 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -396,6 +396,7 @@ check-grad-line: func [ set-linear-transform: func [ brush [this!] + matrix [D2D_MATRIX_3X2_F] /local lin [ID2D1LinearGradientBrush] pt [D2D_POINT_2F value] @@ -408,8 +409,7 @@ set-linear-transform: func [ matrix2d/identity :m m/_31: (as float32! 0.0) - pt/x m/_32: (as float32! 0.0) - pt/y - lin/GetTransform brush :t - matrix2d/mul :m :t :r + matrix2d/mul :m matrix :r m/_31: pt/x m/_32: pt/y matrix2d/mul :r :m :t @@ -418,6 +418,7 @@ set-linear-transform: func [ set-radial-transform: func [ brush [this!] + matrix [D2D_MATRIX_3X2_F] /local rad [ID2D1RadialGradientBrush] pt [D2D_POINT_2F value] @@ -430,8 +431,7 @@ set-radial-transform: func [ matrix2d/identity :m m/_31: (as float32! 0.0) - pt/x m/_32: (as float32! 0.0) - pt/y - rad/GetTransform brush :t - matrix2d/mul :m :t :r + matrix2d/mul :m matrix :r m/_31: pt/x m/_32: pt/y matrix2d/mul :r :m :t @@ -442,17 +442,15 @@ transform-grad: func [ brush [this!] type [integer!] grad-type [integer!] + matrix [D2D_MATRIX_3X2_F] ][ - if all [ - type <> DRAW_BRUSH_GRADIENT - type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] + if type <= DRAW_BRUSH_COLOR [exit] if grad-type = linear [ - set-linear-transform brush + set-linear-transform brush matrix exit ] if grad-type = radial [ - set-radial-transform brush + set-radial-transform brush matrix exit ] ] @@ -520,12 +518,12 @@ OS-draw-shape-endpath: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds - transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -880,12 +878,12 @@ _OS-draw-polygon: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds - transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -909,7 +907,7 @@ OS-draw-line: func [ either pt1 = end [ if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-line ctx/pen ctx/pen-type ctx/pen-grad-type pt0 pt1 - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawLine this as float32! pt0/x as float32! pt0/y @@ -991,7 +989,7 @@ OS-draw-box: func [ ][ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc ] - transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix dc/FillRectangle this rc ctx/brush ] if ctx/pen-type <> DRAW_BRUSH_NONE [ @@ -1001,7 +999,7 @@ OS-draw-box: func [ ][ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc ] - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style ] ] @@ -1155,12 +1153,12 @@ OS-draw-spline: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds - transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1429,12 +1427,12 @@ OS-draw-curve: func [ dc: as ID2D1DeviceContext this/vtbl if ctx/brush-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds - transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type + transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix dc/FillGeometry this as int-ptr! pthis ctx/brush null ] if ctx/pen-type <> DRAW_BRUSH_NONE [ check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds - transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type + transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style ] gpath/Release pthis @@ -1869,8 +1867,8 @@ OS-draw-grad-pen: func [ pt: as red-pair! positions gprops/center.x: as float32! pt/x gprops/center.y: as float32! pt/y - gprops/offset.x: as float32! pt/x - gprops/offset.x: as float32! pt/y + gprops/offset.x: as float32! 0.0 + gprops/offset.x: as float32! 0.0 gprops/radius.x: get-float32 as red-integer! pt + 1 gprops/radius.y: gprops/radius.x if focal? [ @@ -1889,11 +1887,13 @@ OS-draw-grad-pen: func [ ctx/brush: brush/value ctx/brush-type: gtype ctx/brush-grad-type: type + matrix2d/identity as D2D_MATRIX_3X2_F ctx/brush-matrix ][ COM_SAFE_RELEASE(unk ctx/pen) ctx/pen: brush/value ctx/pen-type: gtype ctx/pen-grad-type: type + matrix2d/identity as D2D_MATRIX_3X2_F ctx/pen-matrix ] ] @@ -1917,9 +1917,8 @@ OS-matrix-rotate: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] t [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] ][ rad: PI / 180.0 * get-float angle either pen-fill = -1 [ @@ -1936,28 +1935,20 @@ OS-matrix-rotate: func [ dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m either angle <> as red-integer! center [ - matrix2d/translate :m as float32! 0 - center/x as float32! 0 - center/y :t - matrix2d/rotate :t as float32! rad :m - matrix2d/translate :m as float32! center/x as float32! center/y :t + matrix2d/translate m1 as float32! 0 - center/x as float32! 0 - center/y :t + matrix2d/rotate :t as float32! rad m1 + matrix2d/translate m1 as float32! center/x as float32! center/y :t ][ - matrix2d/rotate :m as float32! rad :t + matrix2d/rotate m1 as float32! rad :t ] - brush/SetTransform bthis :t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] @@ -1970,9 +1961,8 @@ OS-matrix-scale: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] t [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -1982,22 +1972,14 @@ OS-matrix-scale: func [ dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m - matrix2d/scale :m get-float32 sx get-float32 sy :t - brush/SetTransform bthis :t + matrix2d/scale m1 get-float32 sx get-float32 sy :t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] @@ -2010,9 +1992,8 @@ OS-matrix-translate: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] t [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -2022,22 +2003,14 @@ OS-matrix-translate: func [ dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m - matrix2d/translate :m as float32! x as float32! y :t - brush/SetTransform bthis :t + matrix2d/translate m1 as float32! x as float32! y :t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] @@ -2050,11 +2023,10 @@ OS-matrix-skew: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] t [D2D_MATRIX_3X2_F value] x [float32!] y [float32!] - bthis [this!] - brush [ID2D1Brush] ][ x: as float32! degree-to-radians get-float sx TYPE_TANGENT y: either sx = sy [as float32! 0.0][as float32! degree-to-radians get-float sy TYPE_TANGENT] @@ -2066,22 +2038,14 @@ OS-matrix-skew: func [ dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m - matrix2d/skew :m x y :t - brush/SetTransform bthis :t + matrix2d/skew m1 x y :t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] @@ -2167,8 +2131,7 @@ OS-matrix-reset: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] + m1 [D2D_MATRIX_3X2_F] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -2178,21 +2141,13 @@ OS-matrix-reset: func [ dc/SetTransform this :m ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - matrix2d/identity :m - brush/SetTransform bthis :m + matrix2d/identity m1 ] ] @@ -2203,9 +2158,8 @@ OS-matrix-invert: func [ this [this!] dc [ID2D1DeviceContext] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] t [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] ][ either pen-fill = -1 [ this: as this! ctx/dc @@ -2215,22 +2169,14 @@ OS-matrix-invert: func [ dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m - matrix2d/invert :m :t - brush/SetTransform bthis :t + matrix2d/invert m1 :t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] @@ -2242,43 +2188,34 @@ OS-matrix-set: func [ val [red-integer!] this [this!] dc [ID2D1DeviceContext] - m0 [D2D_MATRIX_3X2_F value] m [D2D_MATRIX_3X2_F value] + m1 [D2D_MATRIX_3X2_F] + m2 [D2D_MATRIX_3X2_F value] t [D2D_MATRIX_3X2_F value] - bthis [this!] - brush [ID2D1Brush] ][ val: as red-integer! block/rs-head blk - m/_11: get-float32 val - m/_12: get-float32 val + 1 - m/_21: get-float32 val + 2 - m/_22: get-float32 val + 3 - m/_31: get-float32 val + 4 - m/_32: get-float32 val + 5 + m2/_11: get-float32 val + m2/_12: get-float32 val + 1 + m2/_21: get-float32 val + 2 + m2/_22: get-float32 val + 3 + m2/_31: get-float32 val + 4 + m2/_32: get-float32 val + 5 either pen-fill = -1 [ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl - dc/GetTransform this :m0 - matrix2d/mul m0 m t + dc/GetTransform this :m + matrix2d/mul m2 m t dc/SetTransform this :t ][ either pen-fill = pen [ - if all [ - ctx/pen-type <> DRAW_BRUSH_GRADIENT - ctx/pen-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/pen + if ctx/pen-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/pen-matrix ][ - if all [ - ctx/brush-type <> DRAW_BRUSH_GRADIENT - ctx/brush-type <> DRAW_BRUSH_GRADIENT_SMART - ][exit] - bthis: ctx/brush + if ctx/brush-type <= DRAW_BRUSH_COLOR [exit] + m1: ctx/brush-matrix ] - brush: as ID2D1Brush bthis/vtbl - brush/GetTransform bthis :m0 - matrix2d/mul m0 m t - brush/SetTransform bthis :t + matrix2d/mul m1 m2 t + copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F ] ] diff --git a/runtime/definitions.reds b/runtime/definitions.reds index 37837a16e7..6aa26b4d90 100644 --- a/runtime/definitions.reds +++ b/runtime/definitions.reds @@ -278,6 +278,14 @@ Red/System [ inset? [logic!] next [shadow!] ] + matrix3x2!: alias struct! [ + _11 [float32!] + _12 [float32!] + _21 [float32!] + _22 [float32!] + _31 [float32!] + _32 [float32!] + ] draw-ctx!: alias struct! [ dc [ptr-ptr!] @@ -299,6 +307,8 @@ Red/System [ brush-type [integer!] pen-grad-type [integer!] ;-- gradient type: radial, linear brush-grad-type [integer!] ;-- gradient type: radial, linear + pen-matrix [matrix3x2! value] + brush-matrix [matrix3x2! value] on-image? [logic!] ;-- drawing on image? font-color? [logic!] shadow? [logic!] From 0110ce60d9ccb12e9c3fddacd6850db34e468fa0 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 4 Jan 2020 11:39:39 +0100 Subject: [PATCH 0694/3432] FIX: fill-pen does not work for SHAPE. --- modules/view/backends/windows/draw.reds | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index dd6a4a2ed8..20caff7864 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -483,7 +483,7 @@ OS-draw-shape-beginpath: func [ ctx/sub/shape-curve?: no vpoint/x: ctx/sub/last-pt-x vpoint/y: ctx/sub/last-pt-y - gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis vpoint as-integer ctx/brush-type = DRAW_BRUSH_NONE ] OS-draw-shape-endpath: func [ @@ -545,7 +545,7 @@ OS-draw-shape-close: func [ gsink/EndFigure sthis 1 vpoint/x: ctx/sub/last-pt-x vpoint/y: ctx/sub/last-pt-y - gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis vpoint as-integer ctx/brush-type = DRAW_BRUSH_NONE ] OS-draw-shape-moveto: func [ @@ -573,7 +573,7 @@ OS-draw-shape-moveto: func [ gsink/EndFigure sthis 0 vpoint/x: ctx/sub/last-pt-x vpoint/y: ctx/sub/last-pt-y - gsink/BeginFigure sthis vpoint 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis vpoint as-integer ctx/brush-type = DRAW_BRUSH_NONE ctx/sub/shape-curve?: no ] @@ -858,7 +858,7 @@ _OS-draw-polygon: func [ point/x: as float32! start/x point/y: as float32! start/y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE start: start + 1 while [start <= end] [ point/x: as float32! start/x @@ -1094,7 +1094,7 @@ OS-draw-spline: func [ point/x: as float32! start/x point/y: as float32! start/y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE either closed? [ do-spline-step sthis @@ -1332,7 +1332,7 @@ OS-draw-arc: func [ point/x: start-x point/y: start-y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE arc/point/x: end-x arc/point/y: end-y arc/size/width: rad-x @@ -1414,7 +1414,7 @@ OS-draw-curve: func [ point/x: as float32! start/x point/y: as float32! start/y - gsink/BeginFigure sthis point 1 ;-- D2D1_FIGURE_BEGIN_HOLLOW + gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE hr: gsink/AddBezier sthis ps gsink/EndFigure sthis 0 hr: gsink/Close sthis From d4175ed9e92abc7494f2e14236139e280a10f23c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 4 Jan 2020 14:41:42 +0100 Subject: [PATCH 0695/3432] FIX: improves hex literal values scanning support. --- docs/lexer/lexer-FSM.csv | 3 +- docs/lexer/lexer-FSM.xlsx | Bin 22159 -> 22385 bytes docs/lexer/lexer-states.txt | 1 + runtime/lexer-transitions.reds | 137 +++++++++++++++++---------------- runtime/lexer.reds | 14 ++-- utils/generate-lexer-table.red | 107 ++++++++++++------------- 6 files changed, 136 insertions(+), 126 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index e686958079..2d72cf48a1 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -32,7 +32,8 @@ S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_P S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;T_HEX;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 41508a7c76908be8595d14e9328d5b17f48cdc3f..f75ffbb561240562d56914485ed2562a0e223366 100644 GIT binary patch literal 22385 zcmeEuWmsI>vTft;?(WvO1P$))8r&tg6A13^?(PyixLc3_0Rq7Z?*2O2=iIaR+2_7@ z|KA56bFKAt^Q~GntHu~rJ!dP)LO@~ypaHM|0DufY7A3*w3+|509bHcQ3rb$ zGkX_9HBUz~XMJW5J6qBMNO0Ob066IV|NrNIu?Gg!M(z86s9lPG>RZ5eRz|zGpsO#-Q%>VWNzs(S!54qRGoPz8 zt}!R|&Ymh{%%ZAGQi&vke%7R2C@9&s8|>khDH)2`HfyXc9t*zc<_adqrcc#)C6m_I z&H!&>z(x|a*oUBv#sYAg}f!+MpXJ?R-~(mrz!DH3ojPM_8C^RE+6-_LXaN5d=#xsQvI7Xn!6w7N#_e)^>K@akljj> zr@1bu8?JHZp1zo9yHQR>u1Fq7KVtLt(ipIWW5YWv-JHRC>J<;ZFA_uT#g|G3jH`Za zw${z|f({ghzM1sepF73#ywW3j)6^&*B-qRJgOTV76lSll5CEmWCvkaDb(&cd9}c6KFa%p5{e#Ysy!N{B zT@Bd6Th-(0kh)gxyu-xlO#h{nk^>~6FkZQzbLm(k&c+tYH9jM@WY_oj>Z+E!R&~ZX z@A=3*4NYx(FU2x@FrIyw6tYHC$T`sO*rp|isq(JvW*$Kd?3Y@e}L{Wb}?FdQWm?Umrl(GF889Uu|d-vY2o(`eOSjL$S zT~2{NDox64Xprr5j{}VY358wRh$R`6>{*JH59{5-jt|qq54|x-NWfbf9`2F|ea%u{ zhH}ApEDR%UDRmVH)n*shV%$lWsWdu-rQ6OCCOVup@vsGN;I{E+Rjw2(eYSTxsDtp< z0o_xc#c!I}d{OkI7fked%NZF0(k=rt?I0qQ(}%tk$3;vbIC_h|ZBjmq{I1Bq|8znL zBqCD3P?KiD*@etoOSy`F9dL%@h5fwC1AQtAuQ#aiZP#&FMx4YH>$t8!0QX!lT0&SS zTEiH29cH$Vh?@ju3a8V^z1jt>x+1r!DV-ijU&f`0$IU2vMklwEag6geN=;vXu@g{< zQXRYYSz&4k-pp3ysP9`~+#8QJJiqUc@xB-zSs4*k1M#^M`T~#*pB}1q@qa2ai)`+P zJePkmcB~gR{LXO25q+R%sG3-)g9S%C*vP6oX|KgKZdzdhwF>0)rjqsYfq4;4<7i%Q z|86f^?(28N2UK;U>9#3E#hdn3}9(-g;u86c8Fqe z{w^Ch!;H_@Q{PPg`5mSfijOS&XPB!YrY<;+VKu0{ zt2#FQ>kyN}H>8}CVb>SeDZDt8Z(rA8DcuR4B~aG#>6ld77~L$<5u`8sccV|nfp-Z1 zDad8YOWr+zf?E;-0Kf;pf`Nkk4>I_3sQ;4~z(C>+lq&zbe>xK;tp|XJA5Vk3gJ!#& z5?++X_`KKdN}hktRk|NQQdd(2mBC6?;Y$mIP{}qyZs1e&hZdN!x0km zVwf5Nt)2|9wZWl0bMo~PH~WVnw8aFS2sJ57Wj{fxKCw?2v$fjv#Vw#sA`Ghu@)fh| zvQRlU(j&(D9zN7Fa7+r_yw`X={Ev~t7L1>COb!5yD}VuTK_T%EcyzWjGjnlf`F&vh zg_Bv?%kK$!6T~-$ZC^x&Zqbv!HKi4CZFiqO5=6=*TT;anve_Kf-`|P=0d)Nk?}e64 z1n8MUPhbJJ(CBcn9QoxGms zO+DR@F3;C5_P3kcxoclWdjwx@{kvX|Ue0ezSvuBUf@2+TuQs>G{a(*buC5Mt$4^$T zzl=YIu4TWbPT$6E)ZD(r#`a_j3hw_)!9dWr!=-h$e|JJ3GMKwkd4aDg?CjW$>*upek09|AhWgWyOY>e zMG}RVTlKph!zX`+WtLjMC-m3jR|UcDSC=D6o{kEf*p6uu1-+eY0t18WEI*%D{-BiB zj-DK3zgJ`b=Of!&SNFz^d&cBMoMlLmBVTS2f8O@(#-v=czu-le4N`+KP;H_H+=M}fy!l8?*JVcYs!wNz;0(uU`n*{}PXJ3Rv4 zncRfCwLU#Qr!8e*rT2M)is=v6FAqN+haYV@7AsH&M++Z<6N|bkic+HwOs7s`pUu#YK$}c2#f`U#Hy)VREx~2I)d-ixdAA5B zCbpauFUuO#3MV#UghT03);9Jjt)H1}Ty~Vw#gmS@T^9CIWr8_XX}1_xDK+l*IP-f% zwJ0WspxV|hAHk-A^r9P@r^0;Dpq7=ol0nvfTc~Ngt^c+tRfu|~{Pyfr;>1B5ib8Q? zz0kzM#f?J9(K5axgW_fBl$bdzLwbH(OkA!lB$`9i1V!gPRf#FXhcLWl1ybX?Hz2E; z?eWUh1`rQ+qIy32pMGL+T6n%tH-t06rHtG1HA>rWcb;XX=#3hWYKjSuma{W8r?{MV zL8bUq*Uu=Drk;*=`OXeyyM$0|y|u;7IU7RmZQNX15P5U@9(qP+0yd6V`4C*i71FEV zID^GpParc&KD*~ITpz#bRIw(sS%q9&$;v+I#d1OU`i>sj-Z4Uqec@Rj>Im?$P1w(ldKuv^N z3{l}CoPxYR2lkFHPY$Q(K=Qcsh#jX%dSdl-knr6)9@C_5)l&tpY8ni9`LfiS1U}bX zQ+!HvlUQhs!lt*I>q20{AD$b`f$S3_NVadeffsT~CY z!SYI&a{!o^i*Ot=El3;jPTl>cn5Xq5>Sj^@Ybd>aiH5TnnKiXCcX)_2hkStmx^?1^ca1AUY!)b(uP&C<4V#y03v%VE|07P8aJ zE6y!|P5Q(@M10$3})U2%G<vL0Bu%_y}J7d z-ojv}$V^2}(oll(t;~mv=y~VunN{&P(32l?FcDa-N)1c2bImoz``u?S)NX^JH5!5* zyCIW}E9k#_Zss?#Cs1YkeNbT5QmA<$kYLz^MJ{R6In>NyO0rmDWn>~B@zMWvfI}OL z!P_P()NNYv41V5kmDF~TK#0UXu7uv6DHy~n{biC^qh+Gyij@x6TuXdRw2NJl1;sPr zY>1zc+xQHngq!S;d0e=(oV>9)x^tpd+Q1y826a7Gc(k;wd>=0X+`}6+g`H&nE<(&Q zuODuy*j8Z-}=!HIdFF z2s6x_a2jz1EQ1fF&YB*+I2L4xt5w2_cU35i5$8mflv*ipu=Y!H`*$Qhp5*D z>n2e-XO682?PC_gU5x0*jZSncQ0jx=MDi6Oh9F&WikuwZy_ z)6ar56wMy0$1C?h{=)9^LearDA7Wi5vPt^~vxRM|G#e$mOeZ#XJ3JJGk$~5|gl=I{ z3w80-BlF;L1i*heq{BOei>)EPK3dM!)S7~wAboYDPa=h@L58%!z{@Ul`RmA{MCa$d z3f1|o<2CaFwq_pX^o+h|XC+&LvmyId+6q-0Wwp{FF;{E3KOgWlYHo~Y#~L4UDO&6< z-sk@;9E^RhprC}K@1}q2ot%DCew(BgU z3We0b>ueV&srQ7-2yj4^dpI1oFnQRpXr^hHdYWQZnj`uRB9n`Ms)$$dVrr(N*N9F^ zu%%PMtlm7cw!kJ5WWeC-+Z0t--V|ga>ehqO@G{B|pJ$++tBW@mzOuXLPdqu{`U3W; zJ>USUWM;4c;*oUfA5q;BYHUoQN|3%h@=XGptDz}AIl4+@!w%306?N;X%I4Q)uW0IU z1dxGO6KtfHQEO%(SLq=@S(%3x5H>w@e<$2Rt9HFrpn_6un4?23bG^}0Ay1#-rD5dq zv3&1ZD%kAN<{q|R<`cgRTQep_uBc6@Re+j&Z`1!J!2s+q6W~DE-YP&N^aM0ex7Q=6 zb?^rfv9NTp%w_qyyMj5$FwMIh${~>4r<_NeBKU;b`8zDf6$ucQINv_eu0~24MhhQi+=1Wqb>F^7A ze$R{LVx|xAs8(U6(z$@}@IqJ?C2(UH;-rmVj~?34vGeH0qIszoz$$ z(4Rr~Z!vMF3ArPqK5ZgaT%i;#7NN7C*!xk69&@3hg>Fn;2uu{87^*TifGobi^cn+5 z2}%_E3oi?7c|nGcTMYM&h^fJ{Tg5O7utXW1M%Ex3N@i?|Q@eMN=Kf|#kQhnC+y}D# zUF8Tg!|hnrsINttMYyv$R$C49d&cQpvQX%;$(b}Pa>9`St3VxUh;SOp>fYjNkp?8( z1*Whcc7mxP)>zWjDTdIR*vka>fXcGPz@TyN0#5X77wT!CL>D$!ky$&f*7ae5u{y0x zixJrcXO?oKbrG%3vlJp;3axJcZV+CnZ;R#S%VA9YJt7Vli)5!4c3%J0MY_>%+h2|0 zxd2}vKj{QmL6ktGF&lXW96*@I9g^HMJ~hfOcS=M=aLN%E zMP{f|h|l6v*S6cvZu=IQ$O-oE=okoQ+%gJRjIPQF49v<4#ul>5&*Wemtpxllq#z|S zSwK@NT*Dg14mN=aWCwDCurNRml<2~*RU%nPVU18uouhkwO3?)wV;WqZsC3rq@=H>P zQpQxdN==>mVjx2tyn`YG7Z3-;2SG+X&{=Cli-{c-So^=%Wy*MR5-+z1FPI{a@nag ziuxpJ2VgTLI@dQ@nJ6A|O0|ILcY!QiNIaZZYiU>j`Kc~sAvKip-F3JVgRX$3YEsqV zmU3grLXeAcvo(&`GQI}N9MW~VO4GxS3e{=!g>tNW!duw#qx*~T%k{AQsvw?dNL5}8 z-9UNpX4rXZrBGpg@N3w4ni*2z;7@uhopiC%>iq^fH1qf_e6@yG@Ip>>*z7D zY;3m!xWp&%E4@*z%BGVFMoBdLyi#c2Rl`EmO6<>U?|iWUsG`WdYZI>lK@+Ja0?@A4 z1@Hw*4h87jizxj1XA$%-119i+1i+GCLG1HsR|S3nbkMkvKk!wcRGGJacd8{3VGMfq zU$$(E^cNZ|fM$*!q=!;3JTs%12!V_s;!rU-4*X@!o>xklb9LC~DrhMilV9=!^TDwD z2OLm7t`aJZ%ZM-F0K5byP0$EB01w<8GL6-UIv^d~96F8H2s=O<+#D+HACfSWzpRW> z<~oy$RAs)RJ^>~^Os5N!T4J>?4BDvSw2PS_MfOV=K5I5uxBt2^l6Oi)2-c8p^vtG= zfgp&TuY32Yb7@5|KK;!N;DruLUkBYOfY>H+HsEP=M&<$O5awWMR7M&`jEkgG&;!eX zJfKGvH&d&yp5#QQvu>`FN>wzrijz{V&Nu|wQ5osQ*LNq=pqBkb(g#K}i!anos68k|16Br>;sPaPDOkt^v6q&;MU8kY-~1P@ty%8l%HhwY}4b zM^Fw%m)TiuiL(RZi9>b6(M0C3hy~3HP@GhCC(y))Jjl^ybhge=j1^6>>w*4-Zpb>| zD%pov%H)tt;q&&+y(h>E-haheKpL5mL;xOy`Cq3ZKpVmwB8|zYb95ElS**N9f?T{B zpTTp6xf)stW((qS2)caAPkfTjLB=d)vmbF-3_-Vzk-Xo?`vs4yMLAcZ<_%j%; z!+->*OX9S%mE6C(0n8{QFISRuiU*i6L-W@_e6T>;vK7t(F_63khr+n-allLDot2^9!Q=@+#?<|sD~$qee464EI|AZShijUbx2n*J}E z;V%#TBPc>fgSf<-E4XlXD&8vB{=WJJ>f|7FpjNCf!eHMirS{ju`srB#-}3Wf$E$s5 zOF=0z9@$Wm3gi!D{ciF^PS|3vAWH_80x1D|GCf1pM{Zjyx+))UE6A%OMC@ z1k#Hn^1K3?1g!ui(h2{L?(IKP4H>oFp4e2~eBMk!BCdkiuy+Ei5io%ctQ;^(I_`d2 znM@GoB3%a6bf?F&XMTz@MsS#%-ut)3k(UHKI}%igBu)Hdi$EV#x<8HKBZ~yxg1Hef z{(5LXJquuOZ;J{Mj|71W|Q&DM-Z7^gJJHm_wGocc+Bl)a#w29>=^Nua}Ig%W0U`y__?Vph1m7pn_}x>8#S-A=0Ve#rD7HzSUmL zmVuqh3qsiKrHdW+G-^3wVX;a-I#3EVKR|H*$|@m82y(Q+Ul%GWjTbHW;x=jgEP(<- zHLy2$sWA52iOAq;K+k&~g5G(sF910VAX9G>*cUK49H2n&m1M<1|E&QkBeB}fC*F}s3{5dhc^0WG%)m5{ZZOap_R$x;eQCzAVRC8uyz%ziP>L3`^;CMB}sV{ zX0HEB-@eoG1IKEyVgA$I%8V`=V6lO&y&NEUDEC(~1+YU-(1My>NG7Nj{~dDCSWBC! zTPF*1f}>S?CBoQ|TVI1R6s-$%9v^1>o6s89w=bnaMk|$Ox4W=Nlu2CUH~Y4C-lSK8 z&B+U*6tTLZg6d>yqrYb9{}?j=C%0|%sti5qnE13|mJ4|K{dvjbm7?#hOJm2XKac12 z#n#34kH@_w>9)vUxC*aVi8iOO1o*{k1R~;Dd%vLU{a+hCq`*TuncgV$XGRp8|1cw; zJ?wh5Y(aeHML;m0&>?|yibVd^U#Pfi z`{OL%8HrLAU0e>@d;;VD$W{qxKZQJ~krv1adRF{mh)bgZF483sW*i>ByFT(%a@M9$ zny-9!y~C9pJDwOK`MF||0ISj~%y1@^K%K6czCy!wpH>$uqMfrd2ebe1vV8w~7_0wb z(AP@b@G!}`sL8z#yo4CH{|KYDBdPyCVC~w`vDXL)JQSkSzM|y>+<;nB6pbeTFbV!@ z=AWqVEkNrmU(tMZ;eZaJUCs^YaLnrpiHJbXPU5dYw_b0>7x0g~X7-d@ttrX%dTLlS z`-wYsJ3!W`_Zv`FzT07+058^;M*8mq85a1X*RnDhB;ff4BrE;x%MXG{X*}hF>eI05i1;zLw%;*_gKnjP-hH+m+2(RE* zH33zJ6ArF*f6$3f=6X6*6I>a}qZ9fok&dnYO^aMDbm}wk%3L{n?hVDTgZr9`wR6@syF5QV8gvQ-9QF_ z%A1Z~%CYL*Mc!~|`$Hs%3Bi7f7XUOOy70*swna&g;mpYt@lB;`1j2bG=H3u>o| zYJs;!5?vMXzb#t)nh2wb!&zApS->f0;JVx=^K#J!{?$TnQDPJ$8C2Fd)(dGvfQ$*A zHoYi9`g=VAUTD7r_@&};BmZj4hkC8w;tdx8q+y{ncR?C*JY0tg@)xc1=2;BDKy?kP z_UP`ot3`4|KnAHU0`S=58RoW@fi?9FodmyF5yJaxz!$}3U-@XPzZB)><20aYNlL%H12!M|<&a~%d=$a02}O>4*r{ytijf?82C@K@%` z?x5c`g6bgBC3GOejF1hg1;m!E2;u3?eO`q@{JiyntyuxVhSYGBwSeCD9=hW#O7i6C zS&-vuhQLW&L@=xHf2q*#pvY?k!GKOrFN%HE&2qu?qs#D}Pl#-8D#GVOGlc^LpUm^#vhJKWI1`y?St>U)wU4$JHin#d9XY z=Qm4{>J>GAMff1Ir~kv=@NFsg<|lrTZ&ai1;0v&D?N0usZ7`Ooh)D$iYarT(<*-29 zk^`{+38vtIHodmOLJnX*x^j}n1F`R^1j8_kb-vEU>s~5X(kEe7MuD1Zyg`PWH1O}t zKve^$%0J|uOv6QoWREL~7k|YKO|~}2{f`JU7S+K9tolgJ=%n^`mY(CfE7UC1(yw;K zr?%sq*5RkN$F@u}hkvf7Kg??0x_PeCf>^9H8|-hDRM7cK!1)RYr}m_~7)N$}iNz{{ zY%XQJP|KzBXqQBtX$8ia{tKs`0ccd9W>tnd87PP%3)^*0E=v^+-8y`qz5JigpZl*J zIzC_jaA3NPFW$GC10={@{+-u~l?m2o^Af$gbX%Le7oIS za|N^b-2~MYo=|dMTwm`VohgJ~gg^^m{=R~+CNSlQ1+=iL3J&n!Es

*qoD|J11+R7AL^}~q(7aRsG(X0rZ`Tf1^>)u`O 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 literal 22159 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

KsTHIKTA{I|lp~eTd6b_9G&
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
A_W%F@

diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt
index 5204b6157f..65f2a244d2 100644
--- a/docs/lexer/lexer-states.txt
+++ b/docs/lexer/lexer-states.txt
@@ -36,6 +36,7 @@ S_MONEY_1ST
 S_MONEY
 S_MONEY_DEC
 S_HEX
+S_HEX_END
 S_LESSER
 S_TAG
 S_TAG_STR
diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds
index 5d5d2c52ec..b842bf191c 100644
--- a/runtime/lexer-transitions.reds
+++ b/runtime/lexer-transitions.reds
@@ -36,6 +36,7 @@ Red/System [
         S_MONEY 
         S_MONEY_DEC 
         S_HEX 
+        S_HEX_END 
         S_LESSER 
         S_TAG 
         S_TAG_STR 
@@ -92,73 +93,75 @@ Red/System [
     ] 
     prev-table: #{
 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333
-330B2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F
+330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F
 } 
     transitions: #{
-00001313393A3B3C3E38020C2B2B2C2C2C2C212C210B38222C2C06380138291E
-2828382C2C383701560101010101010101010101010101010101010101010101
-0101010101010101010101013837020202020202020202023D02020202020202
-0202020202020202020202020202020203020238380202020202020202020202
-0202020202020202020202020202020202020202020202020202383704040404
-040404043E3F0404040404040404040404040404040404040404040404040504
-0438380404040404040404040404040404040404040404040404040404040404
-04040404040404043837404007074040404040400A0707400707070707070707
-0707070707074040070707070707073840414107074141414141413807074107
-0707070707070707070707080741410707070707070738410707090938383838
-3838383838383838380909090938383838383838383838383838383838383807
-0707073838383838383838383838383809090707383838383838383838383838
-3838383838410A0A0A0A0A0A0A0A0A0A410A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
-0A0A0A0A0A0A0A0A0A0A0A383842420B0B424242424242420B0B0B0B0B0B0B0B
-0B0B2C0B0B0B0B0B0B42420B0B0B0B0B0B0B384247471212113845380D380F12
-1238121212121212121212383838123847471212121212121238470D0D0D0D38
-3838383843383838380D0D0D0D0D0D0D0D3838380D38380E3838380D3838380D
-38380E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
-0E0E0E0E0E0E0E38370F0F0F0F0F0F0F0F0F0F440F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F100F0F38440F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3838111111111146111111
-1111111111111111111111111111111111111111111111111111111138384747
-1212474747474747471212121212121212121212121212121212474712121212
-121212384749491313494949494949490C131A1C195515163821193849383848
-14492F1438381938383838494A4A15154A4A4A4A4A4A4A1715381C3838151538
-384A384A383848384A3838383838383838384A4A4A15154A4A4A4A4A4A4A3838
-4A383838151538384A384A38384838382F18381515383838384A4A4A16164A4A
-4A4A4A4A4A38384A383855152138214A384A38384838382F1838151538383838
-4A4A4A4A4B4B4B4B4B4B4B4B174B4B171717171717174B4B4B17174B4B4B4B17
-4B17174B1717384B4C4C18184C4C4C4C4C4C4C38384C383838383838384C384C
-38383838383818383838383838384C4D4D19194D4D4D4D4D4D4D191919191919
-1919191919194D19194D194D4D194D19194D3819384D38381B1B383838383838
-38383838383838383838383838383838383838383838383838383838384F4F1B
-1B4F4F4F4F4F4F4F38381B383838383838384F384F383838384F381B38383838
-3838384F38381D1D383838383838383838383838383838383838383838383838
-382F38381D1D38383838384E4E1D1D4E4E4E4E4E4E4E38384E3838381D1D3838
-4E384E383838384E2F1D383838383838384E38381F1F38383838383838383838
-3838383838383838383838383838383838383838383838383850501F1F505050
-50505050501F5038383838383838503850383838385038203838383838383837
-5050202050505050505050502050383838383838385038503838383850383838
-383838383838374040212140404040404040382C2D2C2C552C212C2154402C2C
-2C3838402F2C1F2C2C2C2C2C3840404023234040404040404023234023232323
-23232323232C2C2C232340402323232323232338402323232323232323232324
-2323262323232323232323232351232323232323232323232323383824242424
-2424242424242324242424242424242424242424242424242424242424242524
-2438382424242424242424242424242424242424242424242424242424242424
-2424242424242424383826262626262626262626262626232626262626262626
-2626262626262626262626262626263838262626262626262626262626262626
-2626262626262626262626262626262626262626262638384040131340404040
-40404038382C2C2C2C2C2C2C2C2C40382C2C382C402C292C2C2C382C2C384040
-402A2A40404040404040382C2D2C2C2C2A2A2C2C54402C2C2C3838402F2C382A
-2A2C2C2C38404A4A2A2A4A4A4A4A4A4A4A38384A1C38382A2A38384A384A3838
-4838383838382A2A383838384A38383838383838383838383838382C2C2C2C2C
-2C2C0B382C2C2C383838382C382C2C382C2C383840402C2C4040404040404038
-2C2D2C2C2C2C2C2C2C54402C2C2C3838402F2C1F2C2C2C2C2C384040402E2E40
-4040404040402E2E2E2E2E2E2E2E2E2E2E40382E2E2E2E402E2E2E2E2E2E2E2E
-384052522E2E525252525252522E382E2E2E2E2E2E2E2E2E5252382E2E52522E
-2E382E2E382E2E385253532F2F535353535353533838382F2F2F2F2F2F2F5353
-5338382F3853382F382F2F382F2F38533838313138383B3C3838023432323333
-333333333338382233333838382F333835353833333838494931314949494949
-49493813491C38381515383849384938384814492F1438383838383838493838
-3838383838383838383838383333333333333338383333333838383833383333
-3833333838404033334040404040404038334033333333333333404033333338
-38402F333833333333333840474712121138383838380F121238121212121212
-1212123838381238474712121212121212384740403131404040404040403838
-2C2C2C2C2C2C2C2C2C40382C2C382C402C2C2C2C2C382C2C3840
+000013133A3B3C3D3F39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E
+2929392D2D393801570101010101010101010101010101010101010101010101
+0101010101010101010101013938020202020202020202023E02020202020202
+0202020202020202020202020202020203020239390202020202020202020202
+0202020202020202020202020202020202020202020202020202393804040404
+040404043F400404040404040404040404040404040404040404040404040504
+0439390404040404040404040404040404040404040404040404040404040404
+04040404040404043938414107074141414141410A0707410707070707070707
+0707070707074141070707070707073941424207074242424242423907074207
+0707070707070707070707080742420707070707070739420707090939393939
+3939393939393939390909090939393939393939393939393939393939393907
+0707073939393939393939393939393909090707393939393939393939393939
+3939393939420A0A0A0A0A0A0A0A0A0A420A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
+0A0A0A0A0A0A0A0A0A0A0A393943430B0B434343434343430B0B0B0B0B0B0B0B
+0B0B2D0B0B0B0B0B0B43430B0B0B0B0B0B0B394348481212113946390D390F12
+1239121212121212121212393939123948481212121212121239480D0D0D0D39
+3939393944393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
+39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
+0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F450F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F100F0F39450F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111147111111
+1111111111111111111111111111111111111111111111111111111139394848
+1212484848484848481212121212121212121212121212121212484812121212
+12121239484A4A13134A4A4A4A4A4A4A0C131A1C19561516392119394A393949
+144A3014393919393939394A4B4B15154B4B4B4B4B4B4B1715391C3939151539
+394B394B393949394B3939393939393939394B4B4B15154B4B4B4B4B4B4B3939
+4B393939151539394B394B39394939393018391515393939394B4B4B16164B4B
+4B4B4B4B4B39394B393956152139214B394B3939493939301839151539393939
+4B4B4B4B4C4C4C4C4C4C4C4C174C4C171717171717174C4C4C17174C4C4C4C17
+4C17174C1717394C4D4D18184D4D4D4D4D4D4D39394D393939393939394D394D
+39393939393918393939393939394D4E4E19194E4E4E4E4E4E4E191919191919
+1919191919194E19194E194E4E194E19194E3919394E39391B1B393939393939
+393939393939393939393939393939393939393939393939393939393950501B
+1B5050505050505039391B393939393939395039503939393950391B39393939
+3939395039391D1D393939393939393939393939393939393939393939393939
+393039391D1D39393939394F4F1D1D4F4F4F4F4F4F4F39394F3939391D1D3939
+4F394F393939394F301D393939393939394F39391F1F39393939393939393939
+3939393939393939393939393939393939393939393939393951511F1F515151
+51515151511F5139393939393939513951393939395139203939393939393938
+5151202051515151515151512051393939393939395139513939393951393939
+393939393939384141212141414141414141392D2E2D2D222D212D2155412D2D
+2D393941302D1F2D2D2D2D2D394156562D2D56565656565656392D2E2D2D2D2D
+2D2D2D55562D2D2D393956302D1F2D2D2D2D2D39564141242441414141414141
+2424412424242424242424242D2D2D2424414124242424242424394124242424
+2424242424242524242724242424242424242424522424242424242424242424
+2439392525252525252525252524252525252525252525252525252525252525
+2525252525262525393925252525252525252525252525252525252525252525
+2525252525252525252525252525253939272727272727272727272727272427
+2727272727272727272727272727272727272727272739392727272727272727
+2727272727272727272727272727272727272727272727272727272727393941
+4113134141414141414139392D2D2D2D2D2D2D2D2D41392D2D392D412D2A2D2D
+2D392D2D394141412B2B41414141414141392D2E2D2D2D2B2B2D2D55412D2D2D
+393941302D392B2B2D2D2D39414B4B2B2B4B4B4B4B4B4B4B39394B1C39392B2B
+39394B394B39394939393939392B2B393939394B393939393939393939393939
+39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393941412D2D41
+414141414141392D2E2D2D2D2D2D2D2D55412D2D2D393941302D1F2D2D2D2D2D
+394141412F2F414141414141412F2F2F2F2F2F2F2F2F2F2F41392F2F2F2F412F
+2F2F2F2F2F2F2F394153532F2F535353535353532F392F2F2F2F2F2F2F2F2F53
+53392F2F53532F2F392F2F392F2F395354543030545454545454543939393030
+30303030305454543939303954393039303039303039543939323239393C3D39
+3902353333343434343434343939233434393939303439363639343439394A4A
+32324A4A4A4A4A4A4A39134A1C3939151539394A394A393949144A3014393939
+393939394A393939393939393939393939393934343434343434393934343439
+3939393439343439343439394141343441414141414141393441343434343434
+34414134343439394130343934343434343941484812121139393939390F1212
+3912121212121212121239393912394848121212121212123948414132324141
+414141414139392D2D2D2D2D2D2D2D2D41392D2D392D412D2D2D2D2D392D2D39
+41
 }
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 8c9d719134..622593ac73 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -108,7 +108,7 @@ lexer: context [
 	skip-table: #{
 		0100000000000000000000000000000000000000000000000000000000000000
 		0000000000000000000000000000000000000000000000000000000000000000
-		0000000000000000000000000000000000000000000000
+		000000000000000000000000000000000000000000000000
 	}
 
 	path-ending: #{
@@ -1626,13 +1626,17 @@ lexer: context [
 	
 	scan-hex: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
-			int	  [red-integer!]
-			index [integer!]
-			i	  [integer!]
-			cb	  [byte!]
+			int		[red-integer!]
+			i index [integer!]
+			cb		[byte!]
 	][
 		i: 0
 		cb: null-byte
+		if e/1 <> #"h" [e: e - 1]						;-- when coming from number states
+		assert e/1 = #"h"
+		if all [any [s/1 < #"0" s/1 > #"9"] s + 1 >= e][
+			throw-error lex s e TYPE_WORD
+		]
 		while [s < e][
 			index: 1 + as-integer s/1					;-- converts the 2 hex chars using a lookup table
 			cb: hexa-table/index						;-- decode one nibble at a time
diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red
index d8af5c6683..f6b16cc414 100644
--- a/utils/generate-lexer-table.red
+++ b/utils/generate-lexer-table.red
@@ -47,59 +47,60 @@ context [
 		S_MONEY				TYPE_MONEY			;-- 31
 		S_MONEY_DEC			TYPE_MONEY			;-- 32
 		S_HEX				TYPE_INTEGER		;-- 33
-		S_LESSER			TYPE_TAG			;-- 34
-		S_TAG				TYPE_TAG			;-- 35
-		S_TAG_STR			TYPE_TAG			;-- 36
-		S_SKIP_STR2			TYPE_TAG			;-- 37
-		S_TAG_STR2			TYPE_TAG			;-- 38
-		S_SKIP_STR3			TYPE_TAG			;-- 39
-		S_SIGN				TYPE_WORD			;-- 40
-		S_DOTWORD			TYPE_WORD			;-- 41
-		S_DOTDEC			TYPE_FLOAT			;-- 42
-		S_WORD_1ST			TYPE_WORD			;--	43
-		S_WORD				TYPE_WORD			;-- 44
-		S_WORDSET			TYPE_SET_WORD		;-- 45
-		S_URL				TYPE_URL			;-- 46
-		S_EMAIL				TYPE_EMAIL			;-- 47
-		S_PATH				TYPE_PATH			;-- 48
-		S_PATH_NUM			TYPE_INTEGER		;--	49
-		S_PATH_W1ST			TYPE_WORD			;-- 50
-		S_PATH_WORD			TYPE_WORD			;-- 51
-		S_PATH_SHARP		TYPE_ISSUE			;--	52
-		S_PATH_SIGN			TYPE_WORD			;--	53
-		--EXIT_STATES--		-					;-- 54
-		T_EOF				-					;-- 55
-		T_ERROR				-					;-- 56
-		T_BLK_OP			-					;-- 57
-		T_BLK_CL			-					;-- 58
-		T_PAR_OP			-					;-- 59
-		T_PAR_CL			-					;-- 60
-		T_STRING			-					;-- 61
-		T_MSTR_OP			-					;-- 62
-		T_MSTR_CL			-					;-- 63
-		T_WORD				-					;-- 64
-		T_FILE				-					;-- 65
-		T_REFINE			-					;-- 66
-		T_BINARY			-					;-- 67
-		T_CHAR				-					;-- 68
-		T_MAP_OP			-					;-- 69
-		T_CONS_MK			-					;-- 70
-		T_ISSUE				-					;-- 71
-		T_PERCENT			-					;-- 72
-		T_INTEGER			-					;-- 73
-		T_FLOAT				-					;-- 74
-		T_FLOAT_SP			-					;-- 75
-		T_TUPLE				-					;-- 76
-		T_DATE				-					;-- 77
-		T_PAIR				-					;-- 78
-		T_TIME				-					;-- 79
-		T_MONEY				-					;-- 80
-		T_TAG				-					;-- 81
-		T_URL				-					;-- 82
-		T_EMAIL				-					;-- 83
-		T_PATH				-					;-- 84
-		T_HEX				-					;-- 85
-		T_CMT				-					;-- 86
+		S_HEX_END			TYPE_WORD			;--	34
+		S_LESSER			TYPE_TAG			;-- 35
+		S_TAG				TYPE_TAG			;-- 36
+		S_TAG_STR			TYPE_TAG			;-- 37
+		S_SKIP_STR2			TYPE_TAG			;-- 38
+		S_TAG_STR2			TYPE_TAG			;-- 39
+		S_SKIP_STR3			TYPE_TAG			;-- 40
+		S_SIGN				TYPE_WORD			;-- 41
+		S_DOTWORD			TYPE_WORD			;-- 42
+		S_DOTDEC			TYPE_FLOAT			;-- 43
+		S_WORD_1ST			TYPE_WORD			;--	44
+		S_WORD				TYPE_WORD			;-- 45
+		S_WORDSET			TYPE_SET_WORD		;-- 46
+		S_URL				TYPE_URL			;-- 47
+		S_EMAIL				TYPE_EMAIL			;-- 48
+		S_PATH				TYPE_PATH			;-- 49
+		S_PATH_NUM			TYPE_INTEGER		;--	50
+		S_PATH_W1ST			TYPE_WORD			;-- 51
+		S_PATH_WORD			TYPE_WORD			;-- 52
+		S_PATH_SHARP		TYPE_ISSUE			;--	53
+		S_PATH_SIGN			TYPE_WORD			;--	54
+		--EXIT_STATES--		-					;-- 55
+		T_EOF				-					;-- 56
+		T_ERROR				-					;-- 57
+		T_BLK_OP			-					;-- 58
+		T_BLK_CL			-					;-- 59
+		T_PAR_OP			-					;-- 60
+		T_PAR_CL			-					;-- 61
+		T_STRING			-					;-- 62
+		T_MSTR_OP			-					;-- 63
+		T_MSTR_CL			-					;-- 64
+		T_WORD				-					;-- 65
+		T_FILE				-					;-- 66
+		T_REFINE			-					;-- 67
+		T_BINARY			-					;-- 68
+		T_CHAR				-					;-- 69
+		T_MAP_OP			-					;-- 70
+		T_CONS_MK			-					;-- 71
+		T_ISSUE				-					;-- 72
+		T_PERCENT			-					;-- 73
+		T_INTEGER			-					;-- 74
+		T_FLOAT				-					;-- 75
+		T_FLOAT_SP			-					;-- 76
+		T_TUPLE				-					;-- 77
+		T_DATE				-					;-- 78
+		T_PAIR				-					;-- 79
+		T_TIME				-					;-- 80
+		T_MONEY				-					;-- 81
+		T_TAG				-					;-- 82
+		T_URL				-					;-- 83
+		T_EMAIL				-					;-- 84
+		T_PATH				-					;-- 85
+		T_HEX				-					;-- 86
+		T_CMT				-					;-- 87
 	]
 
 	CSV-table: %../docs/lexer/lexer-FSM.csv

From 7f023f9f4bced35db1a594f3d3f3aa8325909166 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Sat, 4 Jan 2020 19:16:01 +0100
Subject: [PATCH 0696/3432] FIX: more accurate paths error reporting.

---
 runtime/lexer.reds | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 622593ac73..094f8b11a1 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -331,7 +331,6 @@ lexer: context [
 		input		[byte-ptr!]
 		in-end		[byte-ptr!]
 		in-pos		[byte-ptr!]
-		in-path		[byte-ptr!]							;-- records beginning of scanned path
 		line		[integer!]							;-- current line number
 		nline		[integer!]							;-- new lines count for new token
 		type		[integer!]							;-- sub-type in a typeclass
@@ -362,12 +361,19 @@ lexer: context [
 		/local
 			pos  [red-string!]
 			line [red-string!]
+			po	 [red-point!]
 			p	 [byte-ptr!]
 			len	 [integer!]
 			c	 [byte!]
 	][
 		e: lex/in-end
 		len: 0
+		if null? s [									;-- determine token's start
+			either lex/head = lex/buffer [s: lex/input][
+				po: as red-point! lex/head - 1			;-- take start of the parent series
+				either TYPE_OF(po) <> TYPE_POINT [s: lex/input][s: lex/input + po/z]
+			]
+		]
 		p: s
 		while [all [p < e p/1 <> #"^/" s + 30 > p]][p: decode-utf8-char p :len]
 		if p > e [p: e]
@@ -461,17 +467,18 @@ lexer: context [
 		]
 	]
 	
-	open-block: func [lex [state!] type [integer!] hint [integer!] 
+	open-block: func [lex [state!] type [integer!] hint [integer!] pos [byte-ptr!]
 		/local 
 			p	[red-point!]
 			len [integer!]
 	][
+		if null? pos [pos: lex/in-pos]
 		len: (as-integer lex/tail - lex/head) >> 4
 		p: as red-point! alloc-slot lex
 		set-type as cell! p TYPE_POINT					;-- use the slot for stack info
 		p/x: len
 		p/y: type << 16 or (hint and FFFFh)
-		p/z: as-integer lex/in-pos - lex/input			;-- opening delimiter offset saved (error handling)
+		p/z: as-integer pos - lex/input					;-- opening delimiter offset saved (error handling)
 		
 		lex/head: lex/tail								;-- points just after p
 		lex/entry: S_START
@@ -821,7 +828,7 @@ lexer: context [
 			type [integer!]
 	][
 		type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK]
-		open-block lex type -1
+		open-block lex type -1 null
 		lex/in-pos: e + 1								;-- skip delimiter
 	]
 
@@ -1145,7 +1152,7 @@ lexer: context [
 	]
 	
 	scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		open-block lex TYPE_PAREN TYPE_MAP
+		open-block lex TYPE_PAREN TYPE_MAP null
 		lex/in-pos: e + 1								;-- skip (
 	]
 	
@@ -1610,15 +1617,16 @@ lexer: context [
 	
 	scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
+			pos  [byte-ptr!]
 			type [integer!]
 	][
-		lex/in-path: s
+		pos: s
 		type: switch s/1 [
 			#"'" [s: s + 1 flags: flags and not C_FLAG_QUOTE TYPE_LIT_PATH]
 			#":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH]
 			default [TYPE_PATH]
 		]
-		open-block lex type -1							;-- open a new path series
+		open-block lex type -1 pos						;-- open a new path series
 		scan-word lex s e flags							;-- load the head word
 		lex/entry: S_PATH								;-- overwrites the S_START set by open-block
 		lex/in-pos: e + 1								;-- skip /
@@ -1668,21 +1676,19 @@ lexer: context [
 			index: lex-classes/cp and FFh + 1			;-- query the class of ending character
 			as-logic path-ending/index					;-- lookup if the character class is ending path
 		]
-		assert lex/in-path <> null
 		
 		either close? [
 			type: either all [e < lex/in-end e/1 = #":"][
 				if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence
-					throw-error lex lex/in-path e TYPE_PATH
+					throw-error lex null e TYPE_PATH
 				]
 				lex/in-pos: e + 1						;-- skip :
 				TYPE_SET_PATH
 			][-1]
 			close-block lex s e -1 type
-			lex/in-path: null
 		][
-			if e + 1 = lex/in-end [throw-error lex lex/in-path e TYPE_PATH] ;-- incomplete path error
-			if e/1 = #":" [throw-error lex lex/in-path e TYPE_PATH] ;-- set-words not allowed inside paths
+			if e + 1 = lex/in-end [throw-error lex null e TYPE_PATH] ;-- incomplete path error
+			if e/1 = #":" [throw-error lex null e TYPE_PATH] ;-- set-words not allowed inside paths
 			lex/in-pos: e + 1							;-- skip /
 		]
 	]
@@ -1779,7 +1785,6 @@ lexer: context [
 		lex/input:		src
 		lex/in-end:		src + size
 		lex/in-pos:		src
-		lex/in-path:	null
 		lex/entry:		S_START
 		lex/type:		-1
 		lex/mstr-nest:	0

From 67e0fa1c6db0369a3f50efcf238f3de862de3639 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Sat, 4 Jan 2020 19:37:09 +0100
Subject: [PATCH 0697/3432] FEAT: preliminary work on lexer's callback support.

---
 environment/natives.red | 11 +++++++++--
 runtime/lexer.reds      |  8 ++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/environment/natives.red b/environment/natives.red
index 39ed7003ab..14954a7b3b 100644
--- a/environment/natives.red
+++ b/environment/natives.red
@@ -916,8 +916,15 @@ transcode: make native! [[
 			length [integer! binary!] "Length in bytes or tail position"
 		/into			"Optionally provides an output block"
 			dst	 [block! none!]
-		;/trace
-		;	callback [function! [...]]
+		/trace
+			callback [function! [
+				event	[word!]
+				input	[binary! string!]
+				type	[datatype!]
+				range	[pair!]
+				value	[any-type!]
+				return: [logic!]
+			]]
 		return: [block!]
 	]
 	#get-definition NAT_TRANSCODE
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 094f8b11a1..3ea23e8ebd 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -322,6 +322,14 @@ lexer: context [
 		LEX_INT_OVERFLOW: -5
 	]
 	
+	#enum events! [
+		EVT_SCAN										;-- after a token has been extracted
+		EVT_LOAD										;-- after a token has been converted to a Red value
+		EVT_OPEN										;-- when a nested any-block or map is opened
+		EVT_CLOSE										;-- when a nested any-block or map is closed
+		EVT_ERROR										;-- when a scanning error occurs
+	]
+	
 	state!: alias struct! [
 		next		[state!]							;-- link to next state! structure (recursive calls)
 		buffer		[red-value!]						;-- static or dynamic stash buffer (recursive calls)

From 2d3b987b5088c9a07912e7051503815f9eddbb0f Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sat, 4 Jan 2020 23:40:49 +0100
Subject: [PATCH 0698/3432] FEAT: code refactoring.

---
 modules/view/backends/macOS/draw.reds       |   2 -
 modules/view/backends/windows/direct2d.reds |  17 +-
 modules/view/backends/windows/draw.reds     | 614 ++++++++------------
 modules/view/backends/windows/matrix2d.reds |  20 +-
 runtime/definitions.reds                    |   5 +-
 5 files changed, 274 insertions(+), 384 deletions(-)

diff --git a/modules/view/backends/macOS/draw.reds b/modules/view/backends/macOS/draw.reds
index 9e4de369dc..85d34f7784 100644
--- a/modules/view/backends/macOS/draw.reds
+++ b/modules/view/backends/macOS/draw.reds
@@ -13,8 +13,6 @@ Red/System [
 #include %text-box.reds
 
 #define DRAW_FLOAT_MAX		[as float32! 3.4e38]
-#define F32_0				[as float32! 0.0]
-#define F32_1				[as float32! 1.0]
 
 max-colors: 256												;-- max number of colors for gradient
 max-edges: 1000												;-- max number of edges for a polygon
diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 5fd0873377..5d6741a35c 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -820,8 +820,8 @@ DrawBitmap*: alias function! [
 	FillRoundedRectangle			[integer!]
 	DrawEllipse						[DrawEllipse*]
 	FillEllipse						[FillEllipse*]
-	DrawGeometry					[function! [this [this!] geometry [int-ptr!] brush [this!] strokeWidth [float32!] style [this!] return: [integer!]]]
-	FillGeometry					[function! [this [this!] geometry [int-ptr!] brush [this!] opacityBrush [this!] return: [integer!]]]
+	DrawGeometry					[function! [this [this!] geometry [this!] brush [this!] strokeWidth [float32!] style [this!] return: [integer!]]]
+	FillGeometry					[function! [this [this!] geometry [this!] brush [this!] opacityBrush [this!] return: [integer!]]]
 	FillMesh						[integer!]
 	FillOpacityMask					[integer!]
 	DrawBitmap						[integer!]
@@ -1278,6 +1278,19 @@ render-target!: alias struct! [
 			factory		[ptr-ptr!]
 			return:		[integer!]
 		]
+		D2D1MakeRotateMatrix: "D2D1MakeRotateMatrix" [
+			angle		[float32!]		;-- in degrees
+			cx			[float32!]		;-- center x
+			cy			[float32!]		;-- center y
+			matrix		[D2D_MATRIX_3X2_F]
+		]
+		D2D1MakeSkewMatrix: "D2D1MakeSkewMatrix" [
+			angleX		[float32!]		;-- in degrees
+			angleY		[float32!]		;-- in degrees
+			cx			[float32!]		;-- center x
+			cy			[float32!]		;-- center y
+			matrix		[D2D_MATRIX_3X2_F]
+		]
 		D2D1InvertMatrix: "D2D1InvertMatrix" [
 			matrix		[D2D_MATRIX_3X2_F]
 			return:		[logic!]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 20caff7864..0051090e61 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -27,13 +27,122 @@ draw-state!: alias struct! [
 #enum DRAW-BRUSH-TYPE! [
 	DRAW_BRUSH_NONE
 	DRAW_BRUSH_COLOR
-	DRAW_BRUSH_IMAGE
 	DRAW_BRUSH_GRADIENT
 	DRAW_BRUSH_GRADIENT_SMART
+	DRAW_BRUSH_IMAGE_SMART
 ]
 
 grad-stops: as D2D1_GRADIENT_STOP allocate 256 * size? D2D1_GRADIENT_STOP
 
+calc-brush-position: func [
+	brush		[this!]
+	grad-type	[integer!]
+	upper-x		[float32!]
+	upper-y		[float32!]
+	lower-x		[float32!]
+	lower-y		[float32!]
+	/local
+		t		[float32!]
+		b		[ID2D1Brush]
+		lin		[ID2D1LinearGradientBrush]
+		rad		[ID2D1RadialGradientBrush]
+		pt		[D2D_POINT_2F value]
+		t1		[float32!]
+		t2		[float32!]
+		m		[D2D_MATRIX_3X2_F value]
+		result	[D2D_MATRIX_3X2_F value]
+][
+	if upper-x > lower-x [
+		t: upper-x
+		upper-x: lower-x
+		lower-x: t
+	]
+	if upper-y > lower-y [
+		t: upper-y
+		upper-y: lower-y
+		lower-y: t
+	]
+	case [
+		grad-type = linear [
+			lin: as ID2D1LinearGradientBrush brush/vtbl
+			pt/x: upper-x
+			pt/y: upper-y
+			lin/SetStartPoint brush pt
+			pt/x: lower-x
+			pt/y: upper-y
+			lin/SetEndPoint brush pt
+		]
+		grad-type = radial [
+			rad: as ID2D1RadialGradientBrush brush/vtbl
+			pt/x: upper-x + lower-x / as float32! 2.0
+			pt/y: upper-y + lower-y / as float32! 2.0
+			rad/SetCenter brush pt
+			pt/x: as float32! 0.0
+			pt/y: as float32! 0.0
+			rad/SetGradientOriginOffset brush pt
+			t1: lower-x - upper-x
+			t1: t1 / as float32! 2.0
+			t2: lower-y - upper-y
+			t2: t2 / as float32! 2.0
+			if t1 > t2 [t1: t2]
+			rad/SetRadiusX brush t1
+			rad/SetRadiusY brush t1
+		]
+		true [	;-- bitmap brush
+			b: as ID2D1Brush brush/vtbl
+			b/GetTransform brush :m
+			matrix2d/translate :m upper-x upper-y :result
+			b/SetTransform brush :result
+		]
+	]
+]
+
+draw-geometry: func [
+	ctx			[draw-ctx!]
+	path		[this!]
+	/local
+		dc		[ID2D1DeviceContext]
+		this	[this!]
+		gpath	[ID2D1PathGeometry]
+		bounds	[RECT_F! value]
+		bounds?	[logic!]
+][
+	bounds?: no
+	this: as this! ctx/dc
+	dc: as ID2D1DeviceContext this/vtbl
+	either ctx/brush-type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
+		bounds?: yes
+		gpath: as ID2D1PathGeometry path/vtbl
+		gpath/GetBounds path null :bounds
+		calc-brush-position
+			ctx/brush
+			ctx/brush-grad-type
+			bounds/left bounds/top bounds/right bounds/bottom
+		dc/FillGeometry this path ctx/brush null
+	][
+		if ctx/brush-type <> DRAW_BRUSH_NONE [
+			dc/FillGeometry this path ctx/brush null
+		]
+	]
+	either ctx/pen-type > DRAW_BRUSH_GRADIENT [			;-- pen
+		unless bounds? [
+			bounds?: yes
+			gpath: as ID2D1PathGeometry path/vtbl
+			gpath/GetBounds path null :bounds
+		]
+		calc-brush-position
+			ctx/pen
+			ctx/pen-grad-type
+			bounds/left bounds/top bounds/right bounds/bottom
+		dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
+	][
+		if ctx/pen-type <> DRAW_BRUSH_NONE [
+			dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
+		]
+	]
+	if bounds? [gpath/Release path]
+]
+
 draw-begin: func [
 	ctx			[draw-ctx!]
 	hWnd		[handle!]
@@ -285,176 +394,6 @@ OS-draw-text: func [
 	true
 ]
 
-set-linear-points: func [
-	brush		[this!]
-	type		[integer!]
-	upper-x		[float32!]
-	upper-y		[float32!]
-	lower-x		[float32!]
-	lower-y		[float32!]
-	/local
-		lin		[ID2D1LinearGradientBrush]
-		pt		[D2D_POINT_2F value]
-][
-	if type <> DRAW_BRUSH_GRADIENT_SMART [exit]
-	lin: as ID2D1LinearGradientBrush brush/vtbl
-	pt/x: upper-x
-	pt/y: upper-y
-	lin/SetStartPoint brush pt
-	pt/x: lower-x
-	pt/y: lower-y
-	lin/SetEndPoint brush pt
-]
-
-set-radial-points: func [
-	brush		[this!]
-	type		[integer!]
-	upper-x		[float32!]
-	upper-y		[float32!]
-	lower-x		[float32!]
-	lower-y		[float32!]
-	/local
-		rad		[ID2D1RadialGradientBrush]
-		pt		[D2D_POINT_2F value]
-		t1		[float32!]
-		t2		[float32!]
-][
-	if type <> DRAW_BRUSH_GRADIENT_SMART [exit]
-	rad: as ID2D1RadialGradientBrush brush/vtbl
-	pt/x: upper-x + lower-x / as float32! 2.0
-	pt/y: upper-y + lower-y / as float32! 2.0
-	rad/SetCenter brush pt
-	pt/x: as float32! 0.0
-	pt/y: as float32! 0.0
-	rad/SetGradientOriginOffset brush pt
-	t1: lower-x - upper-x
-	t1: t1 / as float32! 2.0
-	t2: lower-y - upper-y
-	t2: t2 / as float32! 2.0
-	if t1 > t2 [t1: t2]
-	rad/SetRadiusX brush t1
-	rad/SetRadiusY brush t1
-]
-
-check-grad-points: func [
-	brush		[this!]
-	type		[integer!]
-	grad-type	[integer!]
-	upper-x		[float32!]
-	upper-y		[float32!]
-	lower-x		[float32!]
-	lower-y		[float32!]
-	/local
-		t		[float32!]
-][
-	if type <> DRAW_BRUSH_GRADIENT_SMART [exit]
-	if upper-x > lower-x [
-		t: upper-x
-		upper-x: lower-x
-		lower-x: t
-	]
-	if upper-y > lower-y [
-		t: upper-y
-		upper-y: lower-y
-		lower-y: t
-	]
-	if grad-type = linear [
-		set-linear-points brush type upper-x upper-y lower-x lower-y
-		exit
-	]
-	if grad-type = radial [
-		set-radial-points brush type upper-x upper-y lower-x lower-y
-		exit
-	]
-]
-
-check-grad-rect: func [
-	brush		[this!]
-	type		[integer!]
-	grad-type	[integer!]
-	bounds		[RECT_F!]
-][
-	if type <> DRAW_BRUSH_GRADIENT_SMART [exit]
-	check-grad-points
-		brush type grad-type
-		bounds/left bounds/top bounds/right bounds/bottom
-]
-
-check-grad-line: func [
-	brush		[this!]
-	type		[integer!]
-	grad-type	[integer!]
-	start		[red-pair!]
-	end			[red-pair!]
-][
-	if type <> DRAW_BRUSH_GRADIENT_SMART [exit]
-	check-grad-points
-		brush type grad-type
-		as float32! start/x as float32! start/y
-		as float32! end/x as float32! end/y
-]
-
-set-linear-transform: func [
-	brush		[this!]
-	matrix		[D2D_MATRIX_3X2_F]
-	/local
-		lin		[ID2D1LinearGradientBrush]
-		pt		[D2D_POINT_2F value]
-		m		[D2D_MATRIX_3X2_F value]
-		t		[D2D_MATRIX_3X2_F value]
-		r		[D2D_MATRIX_3X2_F value]
-][
-	lin: as ID2D1LinearGradientBrush brush/vtbl
-	lin/GetStartPoint brush :pt
-	matrix2d/identity :m
-	m/_31: (as float32! 0.0) - pt/x
-	m/_32: (as float32! 0.0) - pt/y
-	matrix2d/mul :m matrix :r
-	m/_31: pt/x
-	m/_32: pt/y
-	matrix2d/mul :r :m :t
-	lin/SetTransform brush :t
-]
-
-set-radial-transform: func [
-	brush		[this!]
-	matrix		[D2D_MATRIX_3X2_F]
-	/local
-		rad		[ID2D1RadialGradientBrush]
-		pt		[D2D_POINT_2F value]
-		m		[D2D_MATRIX_3X2_F value]
-		t		[D2D_MATRIX_3X2_F value]
-		r		[D2D_MATRIX_3X2_F value]
-][
-	rad: as ID2D1RadialGradientBrush brush/vtbl
-	rad/GetCenter brush :pt
-	matrix2d/identity :m
-	m/_31: (as float32! 0.0) - pt/x
-	m/_32: (as float32! 0.0) - pt/y
-	matrix2d/mul :m matrix :r
-	m/_31: pt/x
-	m/_32: pt/y
-	matrix2d/mul :r :m :t
-	rad/SetTransform brush :t
-]
-
-transform-grad: func [
-	brush		[this!]
-	type		[integer!]
-	grad-type	[integer!]
-	matrix		[D2D_MATRIX_3X2_F]
-][
-	if type <= DRAW_BRUSH_COLOR [exit]
-	if grad-type = linear [
-		set-linear-transform brush matrix
-		exit
-	]
-	if grad-type = radial [
-		set-radial-transform brush matrix
-		exit
-	]
-]
-
 OS-draw-shape-beginpath: func [
 	ctx			[draw-ctx!]
 	/local
@@ -511,22 +450,7 @@ OS-draw-shape-endpath: func [
 	hr: gsink/Close sthis
 	gsink/Release sthis
 
-	matrix2d/identity m
-	gpath/GetBounds pthis :m :bounds
-
-	this: as this! ctx/dc
-	dc: as ID2D1DeviceContext this/vtbl
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds
-		transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix
-		dc/FillGeometry this as int-ptr! pthis ctx/brush null
-	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds
-		transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
-		dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style
-	]
-	gpath/Release pthis
+	draw-geometry ctx pthis
 
 	ctx/sub/path: 0
 	ctx/sub/sink: 0
@@ -871,22 +795,7 @@ _OS-draw-polygon: func [
 	hr: gsink/Close sthis
 	gsink/Release sthis
 
-	matrix2d/identity m
-	gpath/GetBounds pthis :m :bounds
-
-	this: as this! ctx/dc
-	dc: as ID2D1DeviceContext this/vtbl
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds
-		transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix
-		dc/FillGeometry this as int-ptr! pthis ctx/brush null
-	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds
-		transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
-		dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style
-	]
-	gpath/Release pthis
+	draw-geometry ctx pthis
 ]
 
 OS-draw-line: func [
@@ -905,9 +814,13 @@ OS-draw-line: func [
 	pt1: pt0 + 1
 
 	either pt1 = end [
+		if ctx/pen-type > DRAW_BRUSH_GRADIENT [
+			calc-brush-position
+				ctx/pen
+				ctx/pen-grad-type
+				as float32! pt0/x as float32! pt0/y as float32! pt1/x as float32! pt1/y
+		]
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
-			check-grad-line ctx/pen ctx/pen-type ctx/pen-grad-type pt0 pt1
-			transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
 			dc/DrawLine
 				this
 				as float32! pt0/x as float32! pt0/y
@@ -982,25 +895,27 @@ OS-draw-box: func [
 	rc/bottom: as float32! lower/y
 	rc/left: as float32! upper/x
 	rc/top: as float32! upper/y
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		either ctx/brush-grad-type = linear [
-			check-grad-points ctx/brush ctx/brush-type ctx/brush-grad-type
-				rc/left rc/top rc/right rc/top
-		][
-			check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type rc
-		]
-		transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix
+	either ctx/brush-type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
+		calc-brush-position
+			ctx/brush
+			ctx/brush-grad-type
+			rc/left rc/top rc/right rc/bottom
 		dc/FillRectangle this rc ctx/brush 
-	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		either ctx/pen-grad-type = linear [
-			check-grad-points ctx/pen ctx/pen-type ctx/pen-grad-type
-				rc/left rc/top rc/right rc/top
-		][
-			check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type rc
+	][
+		if ctx/brush-type <> DRAW_BRUSH_NONE [
+			dc/FillRectangle this rc ctx/brush 
 		]
-		transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
+	]
+	either ctx/pen-type > DRAW_BRUSH_GRADIENT [
+		calc-brush-position
+			ctx/pen
+			ctx/pen-grad-type
+			rc/left rc/top rc/right rc/bottom
 		dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
+	][
+		if ctx/pen-type <> DRAW_BRUSH_NONE [
+			dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
+		]
 	]
 ]
 
@@ -1146,22 +1061,7 @@ OS-draw-spline: func [
 	hr: gsink/Close sthis
 	gsink/Release sthis
 
-	matrix2d/identity m
-	gpath/GetBounds pthis :m :bounds
-
-	this: as this! ctx/dc
-	dc: as ID2D1DeviceContext this/vtbl
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds
-		transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix
-		dc/FillGeometry this as int-ptr! pthis ctx/brush null
-	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds
-		transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
-		dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style
-	]
-	gpath/Release pthis
+	draw-geometry ctx pthis
 ]
 
 do-draw-ellipse: func [
@@ -1175,6 +1075,8 @@ do-draw-ellipse: func [
 		dc		[ID2D1DeviceContext]
 		cx		[float32!]
 		cy		[float32!]
+		dx		[float32!]
+		dy		[float32!]
 		rx		[float32!]
 		ry		[float32!]
 		ellipse	[D2D1_ELLIPSE value]
@@ -1184,19 +1086,35 @@ do-draw-ellipse: func [
 
 	cx: as float32! x
 	cy: as float32! y
-	rx: as float32! width
-	ry: as float32! height
-	rx: rx / as float32! 2.0
-	ry: ry / as float32! 2.0
+	dx: as float32! width
+	dy: as float32! height
+	rx: dx / as float32! 2.0
+	ry: dy / as float32! 2.0
 	ellipse/x: cx + rx
 	ellipse/y: cy + ry
 	ellipse/radiusX: rx
 	ellipse/radiusY: ry
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
+	either ctx/brush-type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
+		calc-brush-position
+			ctx/brush
+			ctx/brush-grad-type
+			cx cy cx + dx cy + dy
 		dc/FillEllipse this ellipse ctx/brush
+	][
+		if ctx/brush-type <> DRAW_BRUSH_NONE [
+			dc/FillEllipse this ellipse ctx/brush
+		]
 	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
+	either ctx/pen-type > DRAW_BRUSH_GRADIENT [
+		calc-brush-position
+			ctx/pen
+			ctx/pen-grad-type
+			cx cy cx + dx cy + dy
 		dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style
+	][
+		if ctx/pen-type <> DRAW_BRUSH_NONE [
+			dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style
+		]
 	]
 ]
 
@@ -1349,10 +1267,10 @@ OS-draw-arc: func [
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
 	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		dc/FillGeometry this as int-ptr! pthis ctx/brush null
+		dc/FillGeometry this pthis ctx/brush null
 	]
 	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style
+		dc/DrawGeometry this pthis ctx/pen ctx/pen-width ctx/pen-style
 	]
 	gpath/Release pthis
 ]
@@ -1420,22 +1338,7 @@ OS-draw-curve: func [
 	hr: gsink/Close sthis
 	gsink/Release sthis
 
-	matrix2d/identity m
-	gpath/GetBounds pthis :m :bounds
-
-	this: as this! ctx/dc
-	dc: as ID2D1DeviceContext this/vtbl
-	if ctx/brush-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/brush ctx/brush-type ctx/brush-grad-type bounds
-		transform-grad ctx/brush ctx/brush-type ctx/brush-grad-type ctx/brush-matrix
-		dc/FillGeometry this as int-ptr! pthis ctx/brush null
-	]
-	if ctx/pen-type <> DRAW_BRUSH_NONE [
-		check-grad-rect ctx/pen ctx/pen-type ctx/pen-grad-type bounds
-		transform-grad ctx/pen ctx/pen-type ctx/pen-grad-type ctx/pen-matrix
-		dc/DrawGeometry this as int-ptr! pthis ctx/pen ctx/pen-width ctx/pen-style
-	]
-	gpath/Release pthis
+	draw-geometry ctx pthis
 ]
 
 OS-draw-line-join: func [
@@ -1708,11 +1611,13 @@ _OS-draw-brush-bitmap: func [
 	either brush? [
 		COM_SAFE_RELEASE(unk ctx/brush)
 		ctx/brush: as this! brush/value
-		ctx/brush-type: DRAW_BRUSH_IMAGE
+		ctx/brush-type: DRAW_BRUSH_IMAGE_SMART
+		ctx/brush-grad-type: 0
 	][
 		COM_SAFE_RELEASE(unk ctx/pen)
 		ctx/pen: as this! brush/value
-		ctx/pen-type: DRAW_BRUSH_IMAGE
+		ctx/pen-type: DRAW_BRUSH_IMAGE_SMART
+		ctx/pen-grad-type: 0
 	]
 ]
 
@@ -1867,14 +1772,15 @@ OS-draw-grad-pen: func [
 			pt: as red-pair! positions
 			gprops/center.x: as float32! pt/x
 			gprops/center.y: as float32! pt/y
-			gprops/offset.x: as float32! 0.0
-			gprops/offset.x: as float32! 0.0
 			gprops/radius.x: get-float32 as red-integer! pt + 1
 			gprops/radius.y: gprops/radius.x
-			if focal? [
+			either focal? [
 				pt: pt + 2
 				gprops/offset.x: as float32! pt/x
 				gprops/offset.x: as float32! pt/y
+			][
+				gprops/offset.x: as float32! 0.0
+				gprops/offset.x: as float32! 0.0
 			]
 		]
 		dc/CreateRadialGradientBrush this gprops null sc/value :brush
@@ -1887,13 +1793,11 @@ OS-draw-grad-pen: func [
 		ctx/brush: brush/value
 		ctx/brush-type: gtype
 		ctx/brush-grad-type: type
-		matrix2d/identity as D2D_MATRIX_3X2_F ctx/brush-matrix
 	][
 		COM_SAFE_RELEASE(unk ctx/pen)
 		ctx/pen: brush/value
 		ctx/pen-type: gtype
 		ctx/pen-grad-type: type
-		matrix2d/identity as D2D_MATRIX_3X2_F ctx/pen-matrix
 	]
 ]
 
@@ -1907,48 +1811,51 @@ OS-set-clip: func [
 
 ]
 
+#define BEGIN_MATRIX_BRUSH [
+	either pen-fill = pen [
+		if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
+		bthis: ctx/pen
+	][
+		if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
+		bthis: ctx/brush
+	]
+	brush: as ID2D1Brush bthis/vtbl
+]
+
 OS-matrix-rotate: func [
 	ctx			[draw-ctx!]
 	pen-fill	[integer!]
 	angle		[red-integer!]
 	center		[red-pair!]
 	/local
-		rad		[float!]
+		rad		[float32!]
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
 		t		[D2D_MATRIX_3X2_F value]
+		bthis	[this!]
+		brush	[ID2D1Brush]
+		cx		[float32!]
+		cy		[float32!]
 ][
-	rad: PI / 180.0 * get-float angle
+	rad: get-float32 angle
+	either angle <> as red-integer! center [
+		cx: as float32! center/x
+		cy: as float32! center/y
+	][
+		cx: as float32! 0.0 cy: as float32! 0.0
+	]
 	either pen-fill = -1 [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		either angle <> as red-integer! center [
-			matrix2d/translate :m as float32! 0 - center/x as float32! 0 - center/y :t
-			matrix2d/rotate :t as float32! rad :m
-			matrix2d/translate :m as float32! center/x as float32! center/y :t
-		][
-			matrix2d/rotate :m as float32! rad :t
-		]
+		matrix2d/rotate :m rad cx cy :t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		either angle <> as red-integer! center [
-			matrix2d/translate m1 as float32! 0 - center/x as float32! 0 - center/y :t
-			matrix2d/rotate :t as float32! rad m1
-			matrix2d/translate m1 as float32! center/x as float32! center/y :t
-		][
-			matrix2d/rotate m1 as float32! rad :t
-		]
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m
+		matrix2d/rotate :m rad cx cy :t
+		brush/SetTransform bthis :t
 	]
 ]
 
@@ -1961,8 +1868,9 @@ OS-matrix-scale: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
 		t		[D2D_MATRIX_3X2_F value]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
 	either pen-fill = -1 [
 		this: as this! ctx/dc
@@ -1971,15 +1879,10 @@ OS-matrix-scale: func [
 		matrix2d/scale :m get-float32 sx get-float32 sy :t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/scale m1 get-float32 sx get-float32 sy :t
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m
+		matrix2d/scale :m get-float32 sx get-float32 sy :t
+		brush/SetTransform bthis :t
 	]
 ]
 
@@ -1992,8 +1895,9 @@ OS-matrix-translate: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
 		t		[D2D_MATRIX_3X2_F value]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
 	either pen-fill = -1 [
 		this: as this! ctx/dc
@@ -2002,15 +1906,10 @@ OS-matrix-translate: func [
 		matrix2d/translate :m as float32! x as float32! y :t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/translate m1 as float32! x as float32! y :t
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m
+		matrix2d/translate :m as float32! x as float32! y :t
+		brush/SetTransform bthis :t
 	]
 ]
 
@@ -2023,29 +1922,25 @@ OS-matrix-skew: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
 		t		[D2D_MATRIX_3X2_F value]
 		x		[float32!]
 		y		[float32!]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
-	x: as float32! degree-to-radians get-float sx TYPE_TANGENT
-	y: either sx = sy [as float32! 0.0][as float32! degree-to-radians get-float sy TYPE_TANGENT]
+	x: get-float32 sx
+	y: get-float32 sy
 	either pen-fill = -1 [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		matrix2d/skew :m x y :t
+		matrix2d/skew :m x y F32_0 F32_0 :t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/skew m1 x y :t
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m
+		matrix2d/skew :m x y F32_0 F32_0 :t
+		brush/SetTransform bthis :t
 	]
 ]
 
@@ -2057,11 +1952,8 @@ OS-matrix-transform: func [
 	translate	[red-pair!]
 	/local
 		rotate	[red-integer!]
-		center?	[logic!]
 ][
 	rotate: as red-integer! either center + 1 = scale [center][center + 1]
-	center?: rotate <> center
-
 	OS-matrix-rotate ctx pen-fill rotate center
 	OS-matrix-scale ctx pen-fill scale scale + 1
 	OS-matrix-translate ctx pen-fill translate/x translate/y
@@ -2131,7 +2023,8 @@ OS-matrix-reset: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
 	either pen-fill = -1 [
 		this: as this! ctx/dc
@@ -2140,14 +2033,9 @@ OS-matrix-reset: func [
 		matrix2d/identity :m
 		dc/SetTransform this :m
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/identity m1
+		BEGIN_MATRIX_BRUSH
+		matrix2d/identity :m
+		brush/SetTransform bthis :m
 	]
 ]
 
@@ -2158,8 +2046,9 @@ OS-matrix-invert: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
 		t		[D2D_MATRIX_3X2_F value]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
 	either pen-fill = -1 [
 		this: as this! ctx/dc
@@ -2168,15 +2057,10 @@ OS-matrix-invert: func [
 		matrix2d/invert :m :t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/invert m1 :t
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m
+		matrix2d/invert :m :t
+		brush/SetTransform bthis :t
 	]
 ]
 
@@ -2188,34 +2072,30 @@ OS-matrix-set: func [
 		val		[red-integer!]
 		this	[this!]
 		dc		[ID2D1DeviceContext]
+		m0		[D2D_MATRIX_3X2_F value]
 		m		[D2D_MATRIX_3X2_F value]
-		m1		[D2D_MATRIX_3X2_F]
-		m2		[D2D_MATRIX_3X2_F value]
 		t		[D2D_MATRIX_3X2_F value]
+		bthis	[this!]
+		brush	[ID2D1Brush]
 ][
 	val: as red-integer! block/rs-head blk
-	m2/_11: get-float32 val
-	m2/_12: get-float32 val + 1
-	m2/_21: get-float32 val + 2
-	m2/_22: get-float32 val + 3
-	m2/_31: get-float32 val + 4
-	m2/_32: get-float32 val + 5
+	m/_11: get-float32 val
+	m/_12: get-float32 val + 1
+	m/_21: get-float32 val + 2
+	m/_22: get-float32 val + 3
+	m/_31: get-float32 val + 4
+	m/_32: get-float32 val + 5
 	either pen-fill = -1 [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
-		dc/GetTransform this :m
-		matrix2d/mul m2 m t
+		dc/GetTransform this :m0
+		matrix2d/mul m0 m t
 		dc/SetTransform this :t
 	][
-		either pen-fill = pen [
-			if ctx/pen-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/pen-matrix
-		][
-			if ctx/brush-type <= DRAW_BRUSH_COLOR [exit]
-			m1: ctx/brush-matrix
-		]
-		matrix2d/mul m1 m2 t
-		copy-memory as byte-ptr! m1 as byte-ptr! :t size? D2D_MATRIX_3X2_F
+		BEGIN_MATRIX_BRUSH
+		brush/GetTransform bthis :m0
+		matrix2d/mul m0 m t
+		brush/SetTransform bthis :t
 	]
 ]
 
diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds
index 5bb7b35149..2aa91e52c8 100644
--- a/modules/view/backends/windows/matrix2d.reds
+++ b/modules/view/backends/windows/matrix2d.reds
@@ -85,30 +85,28 @@ matrix2d: context [
 
 	rotate: func [
 		m		[D2D_MATRIX_3X2_F]
-		angle	[float32!]
+		angle	[float32!]	;-- The clockwise rotation angle, in degrees
+		cx		[float32!]	;-- center x
+		cy		[float32!]	;-- center y
 		r		[D2D_MATRIX_3X2_F]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
-		identity t
-		t/_11: as float32! cos as float! angle
-		t/_12: as float32! sin as float! angle
-		t/_21: (as float32! 0.0) - t/_12
-		t/_22: t/_11
+		D2D1MakeRotateMatrix angle cx cy :t
 		mul m t r
 	]
 
 	skew: func [
 		m		[D2D_MATRIX_3X2_F]
-		x		[float32!]						;-- x-axis rotate angle
-		y		[float32!]						;-- y-axis rotate angle, but with negative direction
+		x		[float32!]	;-- measured in degrees counterclockwise from the y-axis.
+		y		[float32!]	;-- measured in degrees counterclockwise from the x-axis.
+		cx		[float32!]	;-- center x
+		cy		[float32!]	;-- center y
 		r		[D2D_MATRIX_3X2_F]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
-		identity t
-		t/_12: as float32! tan as float! x
-		t/_21: as float32! tan as float! y
+		D2D1MakeSkewMatrix x y cx cy :t
 		mul m t r
 	]
 
diff --git a/runtime/definitions.reds b/runtime/definitions.reds
index 6aa26b4d90..09e0582763 100644
--- a/runtime/definitions.reds
+++ b/runtime/definitions.reds
@@ -75,6 +75,9 @@ Red/System [
 	EXTRACT_ARGB
 ]
 
+#define F32_0	[as float32! 0.0]
+#define F32_1	[as float32! 1.0]
+
 #if OS = 'macOS [
 	CGAffineTransform!: alias struct! [
 		a		[float32!]
@@ -307,8 +310,6 @@ Red/System [
 			brush-type		[integer!]
 			pen-grad-type	[integer!]			;-- gradient type: radial, linear
 			brush-grad-type	[integer!]			;-- gradient type: radial, linear
-			pen-matrix		[matrix3x2! value]
-			brush-matrix	[matrix3x2! value]
 			on-image?		[logic!]			;-- drawing on image?
 			font-color?		[logic!]
 			shadow?			[logic!]

From 3b3cb3a667bf0dda02c050183b83651fb6c0a3bf Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sun, 5 Jan 2020 07:13:45 +0100
Subject: [PATCH 0699/3432] FEAT: use Prepend matrix order.

---
 modules/view/backends/windows/matrix2d.reds | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds
index 2aa91e52c8..1550da92ce 100644
--- a/modules/view/backends/windows/matrix2d.reds
+++ b/modules/view/backends/windows/matrix2d.reds
@@ -42,10 +42,10 @@ matrix2d: context [
 		m/_32: as float32! 0.0
 	]
 
-	mul: func [
-		l		[D2D_MATRIX_3X2_F]
-		r		[D2D_MATRIX_3X2_F]
-		c		[D2D_MATRIX_3X2_F]
+	mul: func [		;-- c = l * r
+		l	[D2D_MATRIX_3X2_F]	;-- left
+		r	[D2D_MATRIX_3X2_F]	;-- right
+		c	[D2D_MATRIX_3X2_F]	;-- result
 	][
 		c/_11: l/_11 * r/_11 + (l/_12 * r/_21)
 		c/_12: l/_11 * r/_12 + (l/_12 * r/_22)
@@ -66,7 +66,7 @@ matrix2d: context [
 		identity t
 		t/_31: x
 		t/_32: y
-		mul m t r
+		mul t m r
 	]
 
 	scale: func [
@@ -80,7 +80,7 @@ matrix2d: context [
 		identity t
 		t/_11: x
 		t/_22: y
-		mul m t r
+		mul t m r
 	]
 
 	rotate: func [
@@ -93,7 +93,7 @@ matrix2d: context [
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeRotateMatrix angle cx cy :t
-		mul m t r
+		mul t m r
 	]
 
 	skew: func [
@@ -107,7 +107,7 @@ matrix2d: context [
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeSkewMatrix x y cx cy :t
-		mul m t r
+		mul t m r
 	]
 
 	transform-point: func [

From d38fc698dc7af15ccdccb7c302e67decdc7a1f1c Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sun, 5 Jan 2020 07:14:14 +0100
Subject: [PATCH 0700/3432] FIX: geometry path is not released.

---
 modules/view/backends/windows/draw.reds | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 0051090e61..f47a05097c 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -108,11 +108,11 @@ draw-geometry: func [
 		bounds?	[logic!]
 ][
 	bounds?: no
+	gpath: as ID2D1PathGeometry path/vtbl
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
 	either ctx/brush-type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
 		bounds?: yes
-		gpath: as ID2D1PathGeometry path/vtbl
 		gpath/GetBounds path null :bounds
 		calc-brush-position
 			ctx/brush
@@ -127,7 +127,6 @@ draw-geometry: func [
 	either ctx/pen-type > DRAW_BRUSH_GRADIENT [			;-- pen
 		unless bounds? [
 			bounds?: yes
-			gpath: as ID2D1PathGeometry path/vtbl
 			gpath/GetBounds path null :bounds
 		]
 		calc-brush-position
@@ -140,7 +139,7 @@ draw-geometry: func [
 			dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
 		]
 	]
-	if bounds? [gpath/Release path]
+	gpath/Release path
 ]
 
 draw-begin: func [

From 4d81179b27bc2ca550ac7fe5f898b97cad315a68 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sun, 5 Jan 2020 14:39:23 +0100
Subject: [PATCH 0701/3432] FIX: properly set matrix in complex pen.

---
 modules/view/backends/windows/draw.reds | 35 ++++++++++++++-----------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index f47a05097c..6534549a76 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -50,6 +50,7 @@ calc-brush-position: func [
 		t1		[float32!]
 		t2		[float32!]
 		m		[D2D_MATRIX_3X2_F value]
+		tmp		[D2D_MATRIX_3X2_F value]
 		result	[D2D_MATRIX_3X2_F value]
 ][
 	if upper-x > lower-x [
@@ -65,18 +66,15 @@ calc-brush-position: func [
 	case [
 		grad-type = linear [
 			lin: as ID2D1LinearGradientBrush brush/vtbl
-			pt/x: upper-x
-			pt/y: upper-y
+			pt/x: F32_0
+			pt/y: F32_0
 			lin/SetStartPoint brush pt
-			pt/x: lower-x
-			pt/y: upper-y
+			pt/x: lower-x - upper-x
+			pt/y: F32_0
 			lin/SetEndPoint brush pt
 		]
 		grad-type = radial [
 			rad: as ID2D1RadialGradientBrush brush/vtbl
-			pt/x: upper-x + lower-x / as float32! 2.0
-			pt/y: upper-y + lower-y / as float32! 2.0
-			rad/SetCenter brush pt
 			pt/x: as float32! 0.0
 			pt/y: as float32! 0.0
 			rad/SetGradientOriginOffset brush pt
@@ -84,17 +82,24 @@ calc-brush-position: func [
 			t1: t1 / as float32! 2.0
 			t2: lower-y - upper-y
 			t2: t2 / as float32! 2.0
+			pt/x: t1
+			pt/y: t2
+			rad/SetCenter brush pt
 			if t1 > t2 [t1: t2]
 			rad/SetRadiusX brush t1
 			rad/SetRadiusY brush t1
 		]
-		true [	;-- bitmap brush
-			b: as ID2D1Brush brush/vtbl
-			b/GetTransform brush :m
-			matrix2d/translate :m upper-x upper-y :result
-			b/SetTransform brush :result
-		]
+		true [0]
 	]
+	;-- apply matrix transformation
+	b: as ID2D1Brush brush/vtbl
+	b/GetTransform brush :m
+	;matrix2d/post-translate :m upper-x upper-y :result
+	matrix2d/identity :tmp
+	tmp/_31: upper-x
+	tmp/_32: upper-y
+	matrix2d/mul :m :tmp :result
+	b/SetTransform brush :result
 ]
 
 draw-geometry: func [
@@ -2088,12 +2093,12 @@ OS-matrix-set: func [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m0
-		matrix2d/mul m0 m t
+		matrix2d/mul m m0 t
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m0
-		matrix2d/mul m0 m t
+		matrix2d/mul m m0 t
 		brush/SetTransform bthis :t
 	]
 ]

From 07185b9f739407cc7ffb6d93e8519eb2e9bd74d5 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Mon, 6 Jan 2020 14:16:45 +0800
Subject: [PATCH 0702/3432] Revert "FEAT: use Prepend matrix order."

This reverts commit 3b3cb3a667bf0dda02c050183b83651fb6c0a3bf.
---
 modules/view/backends/windows/matrix2d.reds | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds
index 1550da92ce..2aa91e52c8 100644
--- a/modules/view/backends/windows/matrix2d.reds
+++ b/modules/view/backends/windows/matrix2d.reds
@@ -42,10 +42,10 @@ matrix2d: context [
 		m/_32: as float32! 0.0
 	]
 
-	mul: func [		;-- c = l * r
-		l	[D2D_MATRIX_3X2_F]	;-- left
-		r	[D2D_MATRIX_3X2_F]	;-- right
-		c	[D2D_MATRIX_3X2_F]	;-- result
+	mul: func [
+		l		[D2D_MATRIX_3X2_F]
+		r		[D2D_MATRIX_3X2_F]
+		c		[D2D_MATRIX_3X2_F]
 	][
 		c/_11: l/_11 * r/_11 + (l/_12 * r/_21)
 		c/_12: l/_11 * r/_12 + (l/_12 * r/_22)
@@ -66,7 +66,7 @@ matrix2d: context [
 		identity t
 		t/_31: x
 		t/_32: y
-		mul t m r
+		mul m t r
 	]
 
 	scale: func [
@@ -80,7 +80,7 @@ matrix2d: context [
 		identity t
 		t/_11: x
 		t/_22: y
-		mul t m r
+		mul m t r
 	]
 
 	rotate: func [
@@ -93,7 +93,7 @@ matrix2d: context [
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeRotateMatrix angle cx cy :t
-		mul t m r
+		mul m t r
 	]
 
 	skew: func [
@@ -107,7 +107,7 @@ matrix2d: context [
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeSkewMatrix x y cx cy :t
-		mul t m r
+		mul m t r
 	]
 
 	transform-point: func [

From 17a9dc12f5d0cfa686debd6f9c73c587bb7e3e4a Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Mon, 6 Jan 2020 16:12:40 +0800
Subject: [PATCH 0703/3432] FEAT: support matrix order

---
 modules/view/backends/windows/draw.reds     | 33 +++++++++++++--------
 modules/view/backends/windows/matrix2d.reds | 30 +++++++++++++++----
 runtime/definitions.reds                    |  1 +
 tests/matrix-test.red                       |  9 +++++-
 4 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 6534549a76..66ad5e96f6 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -98,7 +98,8 @@ calc-brush-position: func [
 	matrix2d/identity :tmp
 	tmp/_31: upper-x
 	tmp/_32: upper-y
-	matrix2d/mul :m :tmp :result
+	;-- TBD
+	matrix2d/mul :m :tmp :result no  ;not ctx/pre-order?
 	b/SetTransform brush :result
 ]
 
@@ -219,6 +220,8 @@ draw-begin: func [
 	ctx/brush: as this! brush/value
 	ctx/brush-type:	DRAW_BRUSH_NONE
 
+	ctx/pre-order?: yes
+
 	if hWnd <> null [
 		values: get-face-values hWnd
 		clr: as red-tuple! values + FACE_OBJ_COLOR
@@ -1853,12 +1856,12 @@ OS-matrix-rotate: func [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		matrix2d/rotate :m rad cx cy :t
+		matrix2d/rotate :m rad cx cy :t ctx/pre-order?
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m
-		matrix2d/rotate :m rad cx cy :t
+		matrix2d/rotate :m rad cx cy :t ctx/pre-order?
 		brush/SetTransform bthis :t
 	]
 ]
@@ -1880,12 +1883,12 @@ OS-matrix-scale: func [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		matrix2d/scale :m get-float32 sx get-float32 sy :t
+		matrix2d/scale :m get-float32 sx get-float32 sy :t ctx/pre-order?
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m
-		matrix2d/scale :m get-float32 sx get-float32 sy :t
+		matrix2d/scale :m get-float32 sx get-float32 sy :t ctx/pre-order?
 		brush/SetTransform bthis :t
 	]
 ]
@@ -1907,12 +1910,12 @@ OS-matrix-translate: func [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		matrix2d/translate :m as float32! x as float32! y :t
+		matrix2d/translate :m as float32! x as float32! y :t ctx/pre-order?
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m
-		matrix2d/translate :m as float32! x as float32! y :t
+		matrix2d/translate :m as float32! x as float32! y :t ctx/pre-order?
 		brush/SetTransform bthis :t
 	]
 ]
@@ -1933,17 +1936,17 @@ OS-matrix-skew: func [
 		brush	[ID2D1Brush]
 ][
 	x: get-float32 sx
-	y: get-float32 sy
+	y: F32_0 - get-float32 sy
 	either pen-fill = -1 [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m
-		matrix2d/skew :m x y F32_0 F32_0 :t
+		matrix2d/skew :m x y F32_0 F32_0 :t ctx/pre-order?
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m
-		matrix2d/skew :m x y F32_0 F32_0 :t
+		matrix2d/skew :m x y F32_0 F32_0 :t ctx/pre-order?
 		brush/SetTransform bthis :t
 	]
 ]
@@ -2093,12 +2096,12 @@ OS-matrix-set: func [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl
 		dc/GetTransform this :m0
-		matrix2d/mul m m0 t
+		matrix2d/mul m0 m t ctx/pre-order?
 		dc/SetTransform this :t
 	][
 		BEGIN_MATRIX_BRUSH
 		brush/GetTransform bthis :m0
-		matrix2d/mul m m0 t
+		matrix2d/mul m0 m t ctx/pre-order?
 		brush/SetTransform bthis :t
 	]
 ]
@@ -2107,7 +2110,11 @@ OS-set-matrix-order: func [
 	ctx		[draw-ctx!]
 	order	[integer!]
 ][
-
+	case [
+		order = _append [ ctx/pre-order?: no ]
+		order = prepend [ ctx/pre-order?: yes ]
+		true [ ctx/pre-order?: yes ]
+	]
 ]
 
 OS-draw-shadow: func [
diff --git a/modules/view/backends/windows/matrix2d.reds b/modules/view/backends/windows/matrix2d.reds
index 2aa91e52c8..5b063d8478 100644
--- a/modules/view/backends/windows/matrix2d.reds
+++ b/modules/view/backends/windows/matrix2d.reds
@@ -42,11 +42,23 @@ matrix2d: context [
 		m/_32: as float32! 0.0
 	]
 
+	;-- Mc = Ml * Mr for pre? = false
+	;-- Mc = Mr * Ml for pre? = true
+	;-- this lib use row-major order, so the default flag pre? = false
 	mul: func [
-		l		[D2D_MATRIX_3X2_F]
-		r		[D2D_MATRIX_3X2_F]
+		_l		[D2D_MATRIX_3X2_F]
+		_r		[D2D_MATRIX_3X2_F]
 		c		[D2D_MATRIX_3X2_F]
+		pre?	[logic!]
+		/local
+			l	[D2D_MATRIX_3X2_F]
+			r	[D2D_MATRIX_3X2_F]
 	][
+		either pre? [
+			l: _r r: _l
+		][
+			l: _l r: _r
+		]
 		c/_11: l/_11 * r/_11 + (l/_12 * r/_21)
 		c/_12: l/_11 * r/_12 + (l/_12 * r/_22)
 		c/_21: l/_21 * r/_11 + (l/_22 * r/_21)
@@ -60,13 +72,14 @@ matrix2d: context [
 		x		[float32!]
 		y		[float32!]
 		r		[D2D_MATRIX_3X2_F]
+		pre?	[logic!]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		identity t
 		t/_31: x
 		t/_32: y
-		mul m t r
+		mul m t r pre?
 	]
 
 	scale: func [
@@ -74,13 +87,14 @@ matrix2d: context [
 		x		[float32!]
 		y		[float32!]
 		r		[D2D_MATRIX_3X2_F]
+		pre?	[logic!]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		identity t
 		t/_11: x
 		t/_22: y
-		mul m t r
+		mul m t r pre?
 	]
 
 	rotate: func [
@@ -89,11 +103,12 @@ matrix2d: context [
 		cx		[float32!]	;-- center x
 		cy		[float32!]	;-- center y
 		r		[D2D_MATRIX_3X2_F]
+		pre?	[logic!]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeRotateMatrix angle cx cy :t
-		mul m t r
+		mul m t r pre?
 	]
 
 	skew: func [
@@ -103,13 +118,16 @@ matrix2d: context [
 		cx		[float32!]	;-- center x
 		cy		[float32!]	;-- center y
 		r		[D2D_MATRIX_3X2_F]
+		pre?	[logic!]
 		/local
 			t	[D2D_MATRIX_3X2_F value]
 	][
 		D2D1MakeSkewMatrix x y cx cy :t
-		mul m t r
+		mul m t r pre?
 	]
 
+
+	;-- Assuming row vectors, this is equivalent to `p * M`
 	transform-point: func [
 		m		[D2D_MATRIX_3X2_F]
 		x		[float32!]
diff --git a/runtime/definitions.reds b/runtime/definitions.reds
index 09e0582763..8ab4a12ff0 100644
--- a/runtime/definitions.reds
+++ b/runtime/definitions.reds
@@ -310,6 +310,7 @@ Red/System [
 			brush-type		[integer!]
 			pen-grad-type	[integer!]			;-- gradient type: radial, linear
 			brush-grad-type	[integer!]			;-- gradient type: radial, linear
+			pre-order?		[logic!]			;-- matrix order, default pre-order for row-major vector
 			on-image?		[logic!]			;-- drawing on image?
 			font-color?		[logic!]
 			shadow?			[logic!]
diff --git a/tests/matrix-test.red b/tests/matrix-test.red
index 01430917e6..0a26643261 100644
--- a/tests/matrix-test.red
+++ b/tests/matrix-test.red
@@ -9,6 +9,7 @@ Red [
 drawings: [
 	"translate"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		spline 50x50 100x50 50x120 150x150
@@ -22,6 +23,7 @@ drawings: [
 
 	"rotate arc"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		arc 100x100 50x50 0 270
@@ -44,6 +46,7 @@ drawings: [
 
 	"scale circle"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		circle 100x100 50
@@ -72,6 +75,7 @@ drawings: [
 
 	"skew box"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		box 50x50 150x150
@@ -100,6 +104,7 @@ drawings: [
 
 	"matrix ellipse"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		ellipse 50x50 100x100
@@ -128,6 +133,7 @@ drawings: [
 
 	"invert ellipse"
 	[
+		matrix-order append
 		pen yellow
 		line-width 3
 		ellipse 50x50 100x100
@@ -159,6 +165,7 @@ drawings: [
 
 	"transform graphics"
 	[
+		matrix-order append
 		line-width 3
 		pen yellow
 		line 50x20 150x20
@@ -207,7 +214,7 @@ drawings: [
 index: 2
 board: layout [
 	below
-	label: text "" 200 font [size: 16]
+	label: text "" 300 font [size: 16]
 	canvas: base 400x400
 	below
 	across

From dce04790038ae54d3ccdab914f41c77c5b767c41 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 6 Jan 2020 10:09:21 +0100
Subject: [PATCH 0704/3432] FIX: better handling for complex pen
 transformation.

---
 modules/view/backends/windows/direct2d.reds | 41 +++++-----
 modules/view/backends/windows/draw.reds     | 88 ++++++++-------------
 runtime/definitions.reds                    | 34 +++++---
 3 files changed, 74 insertions(+), 89 deletions(-)

diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 5d6741a35c..7c860b7504 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -71,24 +71,19 @@ SIZE_F!: alias struct! [
 	height		[float32!]
 ]
 
-D2D_POINT_2F: alias struct! [
-	x			[float32!]
-	y			[float32!]
-]
-
 D2D1_BEZIER_SEGMENT: alias struct! [
-	point1		[D2D_POINT_2F value]
-	point2		[D2D_POINT_2F value]
-	point3		[D2D_POINT_2F value]
+	point1		[POINT_2F value]
+	point2		[POINT_2F value]
+	point3		[POINT_2F value]
 ]
 
 D2D1_QUADRATIC_BEZIER_SEGMENT: alias struct! [
-	point1		[D2D_POINT_2F value]
-	point2		[D2D_POINT_2F value]
+	point1		[POINT_2F value]
+	point2		[POINT_2F value]
 ]
 
 D2D1_ARC_SEGMENT: alias struct! [
-	point		[D2D_POINT_2F value]
+	point		[POINT_2F value]
 	size		[SIZE_F! value]
 	angle		[float32!]
 	direction	[integer!]
@@ -334,22 +329,22 @@ GetTransform*: alias function! [
 
 SetCenter*: alias function! [
 	this		[this!]
-	center		[D2D_POINT_2F value]
+	center		[POINT_2F value]
 ]
 
 GetCenter*: alias function! [
 	this		[this!]
-	center		[D2D_POINT_2F]
+	center		[POINT_2F]
 ]
 
 SetGradientOriginOffset*: alias function! [
 	this		[this!]
-	Offset		[D2D_POINT_2F value]
+	Offset		[POINT_2F value]
 ]
 
 GetGradientOriginOffset*: alias function! [
 	this		[this!]
-	Offset		[D2D_POINT_2F]
+	Offset		[POINT_2F]
 ]
 
 SetRadiusX*: alias function! [
@@ -422,10 +417,10 @@ ID2D1Brush: alias struct! [
 
 ID2D1LinearGradientBrush: alias struct! [
 	ID2D1Brush*
-	SetStartPoint		[function! [this [this!] startPoint [D2D_POINT_2F value]]]
-	SetEndPoint			[function! [this [this!] endPoint [D2D_POINT_2F value]]]
-	GetStartPoint		[function! [this [this!] startPoint [D2D_POINT_2F]]]
-	GetEndPoint			[function! [this [this!] startPoint [D2D_POINT_2F]]]
+	SetStartPoint		[function! [this [this!] startPoint [POINT_2F value]]]
+	SetEndPoint			[function! [this [this!] endPoint [POINT_2F value]]]
+	GetStartPoint		[function! [this [this!] startPoint [POINT_2F]]]
+	GetEndPoint			[function! [this [this!] startPoint [POINT_2F]]]
 	GetGradientStopCollection	[function! [this [this!] stop [ptr-ptr!]]]
 ]
 
@@ -781,7 +776,7 @@ CreateEffect*: alias function! [
 DrawImage*: alias function! [
 	this		[this!]
 	image		[int-ptr!]
-	offset		[D2D_POINT_2F]
+	offset		[POINT_2F]
 	rect		[RECT_F!]
 	interpola	[integer!]
 	composite	[integer!]
@@ -938,12 +933,12 @@ ID2D1GeometrySink: alias struct! [
 	Release							[Release!]
 	SetFillMode						[function! [this [this!] fill_mode [integer!] return: [integer!]]]
 	SetSegmentFlags					[function! [this [this!] vertexFlags [integer!] return: [integer!]]]
-	BeginFigure						[function! [this [this!] startPoint [D2D_POINT_2F value] figureBegin [integer!] return: [integer!]]]
-	AddLines						[function! [this [this!] points [D2D_POINT_2F] pointsCount [integer!] return: [integer!]]]
+	BeginFigure						[function! [this [this!] startPoint [POINT_2F value] figureBegin [integer!] return: [integer!]]]
+	AddLines						[function! [this [this!] points [POINT_2F] pointsCount [integer!] return: [integer!]]]
 	AddBeziers						[function! [this [this!] beziers [D2D1_BEZIER_SEGMENT] beziersCount [integer!] return: [integer!]]]
 	EndFigure						[function! [this [this!] figureEnd [integer!] return: [integer!]]]
 	Close							[function! [this [this!] return: [integer!]]]
-	AddLine							[function! [this [this!] point [D2D_POINT_2F value] return: [integer!]]]
+	AddLine							[function! [this [this!] point [POINT_2F value] return: [integer!]]]
 	AddBezier						[function! [this [this!] beziers [D2D1_BEZIER_SEGMENT] return: [integer!]]]
 	AddQuadraticBezier				[function! [this [this!] bezier [D2D1_QUADRATIC_BEZIER_SEGMENT] return: [integer!]]]
 	AddQuadraticBeziers				[function! [this [this!] beziers [D2D1_QUADRATIC_BEZIER_SEGMENT] beziersCount [integer!] return: [integer!]]]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 66ad5e96f6..80578336eb 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -12,18 +12,6 @@ Red/System [
 
 #include %text-box.reds
 
-draw-state!: alias struct! [
-	block		[this!]
-	pen-clr		[integer!]
-	brush-clr	[integer!]
-	pen-join	[integer!]
-	pen-cap		[integer!]
-	pen-type	[integer!]
-	brush-type	[integer!]
-	pen			[this!]
-	brush		[this!]
-]
-
 #enum DRAW-BRUSH-TYPE! [
 	DRAW_BRUSH_NONE
 	DRAW_BRUSH_COLOR
@@ -37,6 +25,7 @@ grad-stops: as D2D1_GRADIENT_STOP allocate 256 * size? D2D1_GRADIENT_STOP
 calc-brush-position: func [
 	brush		[this!]
 	grad-type	[integer!]
+	offset		[POINT_2F]
 	upper-x		[float32!]
 	upper-y		[float32!]
 	lower-x		[float32!]
@@ -46,11 +35,10 @@ calc-brush-position: func [
 		b		[ID2D1Brush]
 		lin		[ID2D1LinearGradientBrush]
 		rad		[ID2D1RadialGradientBrush]
-		pt		[D2D_POINT_2F value]
+		pt		[POINT_2F value]
 		t1		[float32!]
 		t2		[float32!]
 		m		[D2D_MATRIX_3X2_F value]
-		tmp		[D2D_MATRIX_3X2_F value]
 		result	[D2D_MATRIX_3X2_F value]
 ][
 	if upper-x > lower-x [
@@ -94,12 +82,11 @@ calc-brush-position: func [
 	;-- apply matrix transformation
 	b: as ID2D1Brush brush/vtbl
 	b/GetTransform brush :m
-	;matrix2d/post-translate :m upper-x upper-y :result
-	matrix2d/identity :tmp
-	tmp/_31: upper-x
-	tmp/_32: upper-y
-	;-- TBD
-	matrix2d/mul :m :tmp :result no  ;not ctx/pre-order?
+	t1: upper-x - offset/x
+	t2: upper-y - offset/y
+	offset/x: t1
+	offset/y: t2
+	matrix2d/translate :m t1 t2 :result no
 	b/SetTransform brush :result
 ]
 
@@ -123,6 +110,7 @@ draw-geometry: func [
 		calc-brush-position
 			ctx/brush
 			ctx/brush-grad-type
+			ctx/brush-offset
 			bounds/left bounds/top bounds/right bounds/bottom
 		dc/FillGeometry this path ctx/brush null
 	][
@@ -138,6 +126,7 @@ draw-geometry: func [
 		calc-brush-position
 			ctx/pen
 			ctx/pen-grad-type
+			ctx/pen-offset
 			bounds/left bounds/top bounds/right bounds/bottom
 		dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
 	][
@@ -412,7 +401,7 @@ OS-draw-shape-beginpath: func [
 		sink	[ptr-value!]
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		vpoint	[D2D_POINT_2F value]
+		vpoint	[POINT_2F value]
 ][
 	d2d: as ID2D1Factory d2d-factory/vtbl
 	hr: d2d/CreatePathGeometry d2d-factory :path
@@ -469,7 +458,7 @@ OS-draw-shape-close: func [
 	/local
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		vpoint	[D2D_POINT_2F value]
+		vpoint	[POINT_2F value]
 ][
 	sthis: as this! ctx/sub/sink
 	gsink: as ID2D1GeometrySink sthis/vtbl
@@ -488,7 +477,7 @@ OS-draw-shape-moveto: func [
 		dy		[float32!]
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		vpoint	[D2D_POINT_2F value]
+		vpoint	[POINT_2F value]
 ][
 	dx: as float32! coord/x
 	dy: as float32! coord/y
@@ -516,7 +505,7 @@ OS-draw-shape-line: func [
 	/local
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		vpoint	[D2D_POINT_2F value]
+		vpoint	[POINT_2F value]
 		dx		[float32!]
 		dy		[float32!]
 		x		[float32!]
@@ -561,7 +550,7 @@ OS-draw-shape-axis: func [
 		len		[float32!]
 		sx		[float32!]
 		sy		[float32!]
-		vpoint	[D2D_POINT_2F value]
+		vpoint	[POINT_2F value]
 ][
 	sthis: as this! ctx/sub/sink
 	gsink: as ID2D1GeometrySink sthis/vtbl
@@ -773,7 +762,7 @@ _OS-draw-polygon: func [
 		sink	[ptr-value!]
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		point	[D2D_POINT_2F value]
+		point	[POINT_2F value]
 		m		[D2D_MATRIX_3X2_F value]
 		bounds	[RECT_F! value]
 		this	[this!]
@@ -825,6 +814,7 @@ OS-draw-line: func [
 			calc-brush-position
 				ctx/pen
 				ctx/pen-grad-type
+				ctx/pen-offset
 				as float32! pt0/x as float32! pt0/y as float32! pt1/x as float32! pt1/y
 		]
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
@@ -906,6 +896,7 @@ OS-draw-box: func [
 		calc-brush-position
 			ctx/brush
 			ctx/brush-grad-type
+			ctx/brush-offset
 			rc/left rc/top rc/right rc/bottom
 		dc/FillRectangle this rc ctx/brush 
 	][
@@ -917,6 +908,7 @@ OS-draw-box: func [
 		calc-brush-position
 			ctx/pen
 			ctx/pen-grad-type
+			ctx/pen-offset
 			rc/left rc/top rc/right rc/bottom
 		dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
 	][
@@ -956,7 +948,7 @@ do-spline-step: func [
 		t3		[float!]
 		x		[float!]
 		y		[float!]
-		point	[D2D_POINT_2F value]
+		point	[POINT_2F value]
 ][
 		gsink: as ID2D1GeometrySink sthis/vtbl
 		t: 0.0
@@ -993,7 +985,7 @@ OS-draw-spline: func [
 		sink	[ptr-value!]
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		point	[D2D_POINT_2F value]
+		point	[POINT_2F value]
 		m		[D2D_MATRIX_3X2_F value]
 		bounds	[RECT_F! value]
 		this	[this!]
@@ -1105,6 +1097,7 @@ do-draw-ellipse: func [
 		calc-brush-position
 			ctx/brush
 			ctx/brush-grad-type
+			ctx/brush-offset
 			cx cy cx + dx cy + dy
 		dc/FillEllipse this ellipse ctx/brush
 	][
@@ -1116,6 +1109,7 @@ do-draw-ellipse: func [
 		calc-brush-position
 			ctx/pen
 			ctx/pen-grad-type
+			ctx/pen-offset
 			cx cy cx + dx cy + dy
 		dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style
 	][
@@ -1218,7 +1212,7 @@ OS-draw-arc: func [
 		sink		[ptr-value!]
 		sthis		[this!]
 		gsink		[ID2D1GeometrySink]
-		point		[D2D_POINT_2F value]
+		point		[POINT_2F value]
 		this		[this!]
 		dc			[ID2D1DeviceContext]
 		arc			[D2D1_ARC_SEGMENT value]
@@ -1302,7 +1296,7 @@ OS-draw-curve: func [
 		sink	[ptr-value!]
 		sthis	[this!]
 		gsink	[ID2D1GeometrySink]
-		point	[D2D_POINT_2F value]
+		point	[POINT_2F value]
 		m		[D2D_MATRIX_3X2_F value]
 		bounds	[RECT_F! value]
 		this	[this!]
@@ -1383,10 +1377,10 @@ OS-draw-line-cap: func [
 
 create-4p-matrix: func [
 	size		[SIZE_F!]
-	ul			[D2D_POINT_2F]
-	ur			[D2D_POINT_2F]
-	ll			[D2D_POINT_2F]
-	lr			[D2D_POINT_2F]
+	ul			[POINT_2F]
+	ur			[POINT_2F]
+	ll			[POINT_2F]
+	lr			[POINT_2F]
 	m			[MATRIX_4x4_F!]
 	/local
 		s		[MATRIX_4x4_F! value]
@@ -1448,10 +1442,10 @@ OS-draw-image: func [
 		height	[integer!]
 		pt		[red-pair!]
 		size	[SIZE_F! value]
-		ul		[D2D_POINT_2F value]
-		ur		[D2D_POINT_2F value]
-		ll		[D2D_POINT_2F value]
-		lr		[D2D_POINT_2F value]
+		ul		[POINT_2F value]
+		ur		[POINT_2F value]
+		ll		[POINT_2F value]
+		lr		[POINT_2F value]
 		m		[MATRIX_4x4_F! value]
 		trans	[int-ptr!]
 		dst*	[RECT_F! value]
@@ -1986,14 +1980,7 @@ OS-draw-state-push: func [
 	dc: as ID2D1DeviceContext this/vtbl
 	dc/SaveDrawingState this as this! blk/value
 	state/block: as this! blk/value
-	state/pen-clr: ctx/pen-color
-	state/brush-clr: ctx/brush-color
-	state/pen-join: ctx/pen-join
-	state/pen-cap: ctx/pen-cap
-	state/pen-type: ctx/pen-type
-	state/brush-type: ctx/brush-type
-	state/pen: ctx/pen
-	state/brush: ctx/brush
+	copy-memory as byte-ptr! :state/pen as byte-ptr! :ctx/pen size? draw-state!
 	COM_ADD_REF(unk state/pen)
 	COM_ADD_REF(unk state/brush)
 ]
@@ -2010,16 +1997,9 @@ OS-draw-state-pop: func [
 	dc: as ID2D1DeviceContext this/vtbl
 	dc/RestoreDrawingState this state/block
 	COM_SAFE_RELEASE(IUnk state/block)
-	ctx/pen-color: state/pen-clr
-	ctx/brush-color: state/brush-clr
-	ctx/pen-join: state/pen-join
-	ctx/pen-cap: state/pen-cap
-	ctx/pen-type: state/pen-type
-	ctx/brush-type: state/brush-type
 	COM_SAFE_RELEASE(IUnk ctx/pen)
 	COM_SAFE_RELEASE(IUnk ctx/brush)
-	ctx/pen: state/pen
-	ctx/brush: state/brush
+	copy-memory as byte-ptr! :ctx/pen as byte-ptr! :state/pen size? draw-state!
 	update-pen-style ctx
 ]
 
diff --git a/runtime/definitions.reds b/runtime/definitions.reds
index 8ab4a12ff0..3419bf0646 100644
--- a/runtime/definitions.reds
+++ b/runtime/definitions.reds
@@ -290,26 +290,36 @@ Red/System [
 			_32				[float32!]
 		]
 
-		draw-ctx!: alias struct! [
-			dc				[ptr-ptr!]
-			target			[int-ptr!]
-			hwnd			[int-ptr!]			;-- Window's handle
+		#define DRAW_STATE_DATA [
 			pen				[this!]
 			brush			[this!]
+			pen-type		[integer!]
+			brush-type		[integer!]
+			pen-color		[integer!]
+			brush-color		[integer!]
+			font-color		[integer!]
 			pen-join		[integer!]
 			pen-cap			[integer!]
+			pen-grad-type	[integer!]
+			brush-grad-type	[integer!]
+			pen-offset		[POINT_2F value]
+			brush-offset	[POINT_2F value]
+		]
+
+		draw-state!: alias struct! [
+			block			[this!]
+			DRAW_STATE_DATA
+		]
+
+		draw-ctx!: alias struct! [
+			dc				[ptr-ptr!]
+			DRAW_STATE_DATA
+			target			[int-ptr!]
+			hwnd			[int-ptr!]			;-- Window's handle
 			pen-width		[float32!]
 			pen-style		[this!]
-			pen-color		[integer!]
-			brush-color		[integer!]
-			font-color		[integer!]
 			bitmap			[int-ptr!]
 			image			[int-ptr!]			;-- original image handle
-			scale-ratio		[float32!]
-			pen-type		[integer!]
-			brush-type		[integer!]
-			pen-grad-type	[integer!]			;-- gradient type: radial, linear
-			brush-grad-type	[integer!]			;-- gradient type: radial, linear
 			pre-order?		[logic!]			;-- matrix order, default pre-order for row-major vector
 			on-image?		[logic!]			;-- drawing on image?
 			font-color?		[logic!]

From 4dd2f46069193c48a86503e63ac8e08cf6483aef Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 6 Jan 2020 16:23:55 +0100
Subject: [PATCH 0705/3432] FEAT: adds CLSID of the unpremultiply effect.

---
 modules/view/backends/windows/direct2d.reds | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 7c860b7504..4a01a63005 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -42,6 +42,7 @@ IID_ID2D1Factory1:		 [BB12D362h 4B9ADAEEh BA141DAAh 1FFA1C40h]
 IID_IDWriteFactory:		 [B859EE5Ah 4B5BD838h DC1AE8A2h 48DB937Dh]
 IID_IDXGIFactory2:		 [50C83A1Ch 4C48E072h 3036B087h D0A636FAh]
 IID_IDCompositionDevice: [C37EA93Ah 450DE7AAh 46976FB1h F30704CBh]
+CLSID_D2D1UnPremultiply: [FB9AC489h 41EDAD8Dh 63BB9999h F710D147h]
 
 D2D1_FACTORY_OPTIONS: alias struct! [
 	debugLevel	[integer!]
@@ -769,7 +770,7 @@ CreateBitmapFromWicBitmap*: alias function! [
 CreateEffect*: alias function! [
 	this		[this!]
 	effectID	[tagGUID]
-	effect		[ptr-ptr!]
+	effect		[com-ptr!]
 	return:		[integer!]
 ]
 

From c97604c6c429fda6c0dbc2dbd9e35c6b44d0b811 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 6 Jan 2020 16:36:08 +0100
Subject: [PATCH 0706/3432] FIX: sorting pointer is not correct in GC.

---
 runtime/allocator.reds | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/allocator.reds b/runtime/allocator.reds
index 138c56d917..89bf41c0f5 100644
--- a/runtime/allocator.reds
+++ b/runtime/allocator.reds
@@ -698,7 +698,7 @@ in-range?: func [
 ]
 
 compare-refs: func [[cdecl] a [int-ptr!] b [int-ptr!] return: [integer!]][
-	a/value - b/value
+	as-integer (as int-ptr! a/value) - (as int-ptr! b/value)
 ]
 
 extract-stack-refs: func [

From ad22f3b5f8deef9e9472db6aca2029c8b193653b Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Mon, 6 Jan 2020 19:04:48 +0100
Subject: [PATCH 0707/3432] FEAT: adds lexer callback evaluation support.

---
 environment/natives.red       |  2 +-
 environment/system.red        |  6 ++++
 libRed/libRed.red             |  2 +-
 runtime/datatypes/block.reds  |  2 +-
 runtime/datatypes/common.reds | 11 +++++-
 runtime/lexer.reds            | 67 ++++++++++++++++++++++++++++++++++-
 runtime/natives.reds          | 15 ++++----
 7 files changed, 94 insertions(+), 11 deletions(-)

diff --git a/environment/natives.red b/environment/natives.red
index 14954a7b3b..72781b96de 100644
--- a/environment/natives.red
+++ b/environment/natives.red
@@ -920,7 +920,7 @@ transcode: make native! [[
 			callback [function! [
 				event	[word!]
 				input	[binary! string!]
-				type	[datatype!]
+				type	[word! datatype!]
 				range	[pair!]
 				value	[any-type!]
 				return: [logic!]
diff --git a/environment/system.red b/environment/system.red
index af7635774c..b2f1078f96 100644
--- a/environment/system.red
+++ b/environment/system.red
@@ -403,6 +403,12 @@ system: context [
 	
 	lexer: context [
 		pre-load: none
+		
+		exit-states: [
+			eof error! block! block! paren! paren! string! string! string! word! file! refinement!
+			binary! char! map! any-type! issue! percent! integer! float! float! tuple! date! pair!
+			time! money! tag! url! email! path! hex comment
+		]
 	]
 	
 	console:	none
diff --git a/libRed/libRed.red b/libRed/libRed.red
index 3f516c1206..87cca7932b 100644
--- a/libRed/libRed.red
+++ b/libRed/libRed.red
@@ -251,7 +251,7 @@ Red [
 		if last-error <> null [return last-error]
 		
 		TRAP_ERRORS(name [
-			lexer/load-string stack/arguments str -1 no no null
+			lexer/load-string stack/arguments str -1 no no null null null
 			stack/unwind-last
 		])
 	]
diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds
index 6e71786d95..294ee83c46 100644
--- a/runtime/datatypes/block.reds
+++ b/runtime/datatypes/block.reds
@@ -649,7 +649,7 @@ block: context [
 			TYPE_OBJECT   [object/reflect as red-object! spec words/body]
 			TYPE_MAP	  [map/reflect as red-hash! spec words/body]
 			TYPE_VECTOR   [vector/to-block as red-vector! spec proto]
-			TYPE_STRING   [lexer/load-string as red-value! proto as red-string! spec -1 no no null]
+			TYPE_STRING   [lexer/load-string as red-value! proto as red-string! spec -1 no no null null as red-series! spec]
 			TYPE_TYPESET  [typeset/to-block as red-typeset! spec proto]
 			TYPE_ANY_PATH
 			TYPE_ANY_LIST [proto: clone as red-block! spec no no]
diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds
index 9de07a3436..14449eb867 100644
--- a/runtime/datatypes/common.reds
+++ b/runtime/datatypes/common.reds
@@ -351,7 +351,7 @@ load-value: func [
 		blk	  [red-block!]
 		value [red-value!]
 ][
-	lexer/load-string stack/arguments str -1 yes yes null
+	lexer/load-string stack/arguments str -1 yes yes null null as red-series! str
 
 	blk: as red-block! stack/arguments
 	assert TYPE_OF(blk) = TYPE_BLOCK
@@ -678,6 +678,7 @@ words: context [
 	_multiply:		as red-word! 0
 	_browse:		as red-word! 0
 	
+	;-- I/O actions
 	_open:			as red-word! 0
 	_create:		as red-word! 0
 	_close:			as red-word! 0
@@ -689,6 +690,10 @@ words: context [
 	_update:		as red-word! 0
 	_write:			as red-word! 0
 	
+	;-- lexer events
+	scan:			as red-word! 0
+	load:			as red-word! 0
+	
 	errors: context [
 		_throw:		as red-word! 0
 		note:		as red-word! 0
@@ -924,6 +929,10 @@ words: context [
 		_update:		word/load "update"
 		_write:			word/load "write"
 		
+		;-- lexer events
+		scan:			word/load "scan"
+		load:			word/load "load"
+		
 		errors/throw:	 word/load "throw"
 		errors/note:	 word/load "note"
 		errors/syntax:	 word/load "syntax"
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 3ea23e8ebd..247e8f1c5d 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -314,6 +314,18 @@ lexer: context [
 		as byte-ptr! 0									;-- never reached, just make compiler happy
 	]
 	
+	;-- Count UTF-8 encoded characters between two positions in a binary buffer
+	count-chars: func [s e [byte-ptr!] return: [integer!]
+		/local c len [integer!]
+	][
+		c: len: 0
+		while [s < e][
+			s: lexer/decode-utf8-char s :len
+			c: c + 1
+		]
+		c
+	]
+	
 	#enum errors! [
 		ERR_BAD_CHAR: 	  -1
 		ERR_MALCONSTRUCT: -2
@@ -349,6 +361,9 @@ lexer: context [
 		mstr-s		[byte-ptr!]							;-- multiline string saved start position
 		mstr-nest	[integer!]							;-- multiline string nested {} counting
 		mstr-flags	[integer!]							;-- multiline string accumulated flags
+		fun-ptr		[red-function!]						;-- callback function pointer or NULL
+		fun-locs	[integer!]							;-- number of local words in callback function
+		in-series	[red-series!]						;-- optional back reference to input series
 	]
 	
 	scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]]
@@ -417,12 +432,53 @@ lexer: context [
 		]
 	]
 	
+	fire-event: func [
+		lex		[state!]
+		event   [red-word!]
+		type	[integer!]
+		value	[red-value!]
+		s		[byte-ptr!]
+		e		[byte-ptr!]
+		return: [logic!]
+		/local
+			len x y [integer!]
+			res	  [red-value!]
+			blk	  [red-block!]
+			loop? [logic!]
+	][
+		stack/mark-func words/_body	lex/fun-ptr/ctx		;@@ find something more adequate
+		stack/push as red-value! event
+		stack/push as red-value! lex/in-series
+		blk: as red-block! #get system/lexer/exit-states
+		either TYPE_OF(blk) <> TYPE_BLOCK [none/push][
+			stack/push block/rs-abs-at blk type - 1		;-- 1-base access
+		]
+		either all [lex/in-series <> null TYPE_OF(lex/in-series) <> TYPE_BINARY][
+			x: count-chars lex/input s
+			y: x + count-chars s e
+		][
+			x: as-integer s - lex/input
+			y: as-integer e - lex/input
+		]
+		pair/push x + 1 y + 1 							;-- 1-base series positions
+		either null? value [none/push][stack/push value]
+		if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs]	;-- +1 for /local refinement
+
+		catch RED_THROWN_ERROR [_function/call lex/fun-ptr global-ctx]	;FIXME: hardcoded origin context
+		if system/thrown <> 0 [re-throw]
+
+		loop?: logic/top-true?
+		stack/unwind
+		loop?
+	]
+	
 	mark-buffers: func [/local s [state!]][
 		if root-state <> null [
 			s: root-state
 			until [
 				assert s/buffer < s/tail
 				collector/mark-values s/buffer s/tail
+				if s/in-series <> null [collector/keep s/in-series/node]
 				s: s/next
 				null? s
 			]
@@ -1754,6 +1810,7 @@ lexer: context [
 			lex/type:	-1
 			
 			index: state - --EXIT_STATES--
+			if lex/fun-ptr <> null [fire-event lex words/scan index null start + offset lex/in-pos]
 			do-scan: as scanner! scanners/index
 			do-scan lex start + offset p flags
 			
@@ -1775,6 +1832,8 @@ lexer: context [
 		one?  [logic!]									;-- scan a single value
 		wrap? [logic!]									;-- force returned loaded value(s) in a block
 		len   [int-ptr!]								;-- return the consumed input length
+		fun	  [red-function!]							;-- optional callback function
+		ser	  [red-series!]								;-- optional input series back-reference
 		/local
 			blk	  [red-block!]
 			p	  [red-point!]
@@ -1797,6 +1856,11 @@ lexer: context [
 		lex/type:		-1
 		lex/mstr-nest:	0
 		lex/mstr-flags: 0
+		lex/fun-ptr:	fun
+		lex/fun-locs:	0
+		lex/in-series:	ser
+		
+		if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no]
 		
 		scan-tokens lex one?
 
@@ -1826,6 +1890,7 @@ lexer: context [
 		one?  [logic!]
 		wrap? [logic!]
 		len	  [int-ptr!]
+		fun	  [red-function!]							;-- optional callback function
 		/local
 			s [series!]
 			unit buf-size ignore [integer!]
@@ -1843,7 +1908,7 @@ lexer: context [
 		]
 		size: unicode/to-utf8-buffer str utf8-buffer size
 		if null? len [len: :ignore]
-		scan dst utf8-buffer size one? wrap? len
+		scan dst utf8-buffer size one? wrap? len fun as red-series! str
 	]
 	
 	set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][
diff --git a/runtime/natives.reds b/runtime/natives.reds
index 8b89249747..86b9257e99 100644
--- a/runtime/natives.reds
+++ b/runtime/natives.reds
@@ -555,7 +555,7 @@ natives: context [
 					stack/set-last arg + 1
 				]
 				TYPE_STRING [
-					lexer/load-string arg as red-string! arg -1 no no null
+					lexer/load-string arg as red-string! arg -1 no no null null as red-string! arg
 					DO_EVAL_BLOCK
 				]
 				TYPE_URL 
@@ -2714,7 +2714,7 @@ natives: context [
 		on?    [integer!]
 		off?   [integer!]
 	][
-		#typecheck [on? off?]
+		#typecheck [recycle on? off?]
 
 		case [
 			on?  > -1 [collector/active?: yes]
@@ -2729,6 +2729,7 @@ natives: context [
 		next   [integer!]
 		part   [integer!]
 		into   [integer!]
+		trace  [integer!]
 		/local
 			offset len type [integer!]
 			slot arg [red-value!]
@@ -2736,11 +2737,12 @@ natives: context [
 			int	  [red-integer!]
 			str	  [red-string!]
 			blk	  [red-block!]
+			fun	  [red-function!]
 			s	  [series!]
 			next? [logic!]
 	][
-		#typecheck [next part into]
-		
+		#typecheck [transcode next part into trace]
+
 		next?: next > -1
 		slot: stack/push*
 		if next? [
@@ -2754,6 +2756,7 @@ natives: context [
 		bin: as red-binary! stack/arguments
 		type: TYPE_OF(bin)
 		arg: stack/arguments + part
+		fun: either trace < 0 [null][stack/arguments + trace]
 		
 		if OPTION?(arg) [
 			switch TYPE_OF(arg) [
@@ -2777,11 +2780,11 @@ natives: context [
 		]
 		either type = TYPE_BINARY [
 			if len < 0 [len: binary/rs-length? bin]
-			lexer/scan slot binary/rs-head bin len next? no :offset
+			lexer/scan slot binary/rs-head bin len next? no :offset fun as red-series! bin
 		][
 			str: as red-string! bin
 			if len < 0 [len: string/rs-length? str]
-			lexer/load-string slot str len next? no :offset
+			lexer/load-string slot str len next? no :offset fun as red-series! str
 		]
 		if next? [
 			bin: as red-binary! copy-cell as red-value! bin s/offset + 1

From 3ebcfdcc9c6dbce01da80e13980726f9c5ca8af6 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Tue, 7 Jan 2020 11:49:01 +0100
Subject: [PATCH 0708/3432] FIX: properly handle smart brush and skew
 transformation.

---
 modules/view/backends/windows/draw.reds | 35 +++++++++++++++++++------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 80578336eb..de02fc62c6 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -82,11 +82,23 @@ calc-brush-position: func [
 	;-- apply matrix transformation
 	b: as ID2D1Brush brush/vtbl
 	b/GetTransform brush :m
-	t1: upper-x - offset/x
-	t2: upper-y - offset/y
-	offset/x: t1
-	offset/y: t2
-	matrix2d/translate :m t1 t2 :result no
+	offset/x: upper-x
+	offset/y: upper-y
+	matrix2d/translate :m upper-x upper-y :result no
+	b/SetTransform brush :result
+]
+
+post-process-brush: func [
+	brush		[this!]
+	offset		[POINT_2F]
+	/local
+		b		[ID2D1Brush]
+		m		[D2D_MATRIX_3X2_F value]
+		result	[D2D_MATRIX_3X2_F value]
+][
+	b: as ID2D1Brush brush/vtbl
+	b/GetTransform brush :m
+	matrix2d/translate :m (F32_0) - offset/x (F32_0) - offset/y :result no
 	b/SetTransform brush :result
 ]
 
@@ -113,6 +125,7 @@ draw-geometry: func [
 			ctx/brush-offset
 			bounds/left bounds/top bounds/right bounds/bottom
 		dc/FillGeometry this path ctx/brush null
+		post-process-brush ctx/brush ctx/brush-offset
 	][
 		if ctx/brush-type <> DRAW_BRUSH_NONE [
 			dc/FillGeometry this path ctx/brush null
@@ -129,6 +142,7 @@ draw-geometry: func [
 			ctx/pen-offset
 			bounds/left bounds/top bounds/right bounds/bottom
 		dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
+		post-process-brush ctx/pen ctx/pen-offset
 	][
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
 			dc/DrawGeometry this path ctx/pen ctx/pen-width ctx/pen-style
@@ -816,9 +830,10 @@ OS-draw-line: func [
 				ctx/pen-grad-type
 				ctx/pen-offset
 				as float32! pt0/x as float32! pt0/y as float32! pt1/x as float32! pt1/y
+			post-process-brush ctx/pen ctx/pen-offset
 		]
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
-			dc/DrawLine
+			dc/DrawLine 
 				this
 				as float32! pt0/x as float32! pt0/y
 				as float32! pt1/x as float32! pt1/y
@@ -898,7 +913,8 @@ OS-draw-box: func [
 			ctx/brush-grad-type
 			ctx/brush-offset
 			rc/left rc/top rc/right rc/bottom
-		dc/FillRectangle this rc ctx/brush 
+		dc/FillRectangle this rc ctx/brush
+		post-process-brush ctx/brush ctx/brush-offset
 	][
 		if ctx/brush-type <> DRAW_BRUSH_NONE [
 			dc/FillRectangle this rc ctx/brush 
@@ -911,6 +927,7 @@ OS-draw-box: func [
 			ctx/pen-offset
 			rc/left rc/top rc/right rc/bottom
 		dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
+		post-process-brush ctx/pen ctx/pen-offset
 	][
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
 			dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
@@ -1100,6 +1117,7 @@ do-draw-ellipse: func [
 			ctx/brush-offset
 			cx cy cx + dx cy + dy
 		dc/FillEllipse this ellipse ctx/brush
+		post-process-brush ctx/brush ctx/brush-offset
 	][
 		if ctx/brush-type <> DRAW_BRUSH_NONE [
 			dc/FillEllipse this ellipse ctx/brush
@@ -1112,6 +1130,7 @@ do-draw-ellipse: func [
 			ctx/pen-offset
 			cx cy cx + dx cy + dy
 		dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style
+		post-process-brush ctx/pen ctx/pen-offset
 	][
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
 			dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style
@@ -1930,7 +1949,7 @@ OS-matrix-skew: func [
 		brush	[ID2D1Brush]
 ][
 	x: get-float32 sx
-	y: F32_0 - get-float32 sy
+	y: get-float32 sy
 	either pen-fill = -1 [
 		this: as this! ctx/dc
 		dc: as ID2D1DeviceContext this/vtbl

From 602ca0ef94466fcf2fe235f4854e3730de506571 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Tue, 7 Jan 2020 15:13:29 +0100
Subject: [PATCH 0709/3432] FEAT: change order of arguments of IMAGE command in
 DRAW.

---
 modules/view/backends/windows/draw.reds | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index de02fc62c6..2d30253ba0 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -1524,11 +1524,10 @@ OS-draw-image: func [
 			ur/x: as float32! pt/x
 			ur/y: as float32! pt/y
 			pt: start + 2
-			ll/x: as float32! pt/x
-			ll/y: as float32! pt/y
-			;-- not support ll == lr
-			lr/x: as float32! pt/x + 1
+			lr/x: as float32! pt/x
 			lr/y: as float32! pt/y
+			ll/x: ul/x
+			ll/y: lr/y
 			create-4p-matrix size ul ur ll lr m
 			trans: as int-ptr! :m
 		]
@@ -1540,11 +1539,11 @@ OS-draw-image: func [
 			ur/x: as float32! pt/x
 			ur/y: as float32! pt/y
 			pt: start + 2
-			ll/x: as float32! pt/x
-			ll/y: as float32! pt/y
-			pt: start + 3
 			lr/x: as float32! pt/x
 			lr/y: as float32! pt/y
+			pt: start + 3
+			ll/x: as float32! pt/x
+			ll/y: as float32! pt/y
 			create-4p-matrix size ul ur ll lr m
 			trans: as int-ptr! :m
 		]

From 2590ad9ec0f866fa8bd500d4ccc4bab3ffd1f120 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Tue, 7 Jan 2020 19:52:17 +0100
Subject: [PATCH 0710/3432] FEAT: wires the SCAN and most of LOAD events for
 the lexer callbacks.

---
 environment/natives.red        |   4 +-
 environment/system.red         |   6 +-
 runtime/datatypes/common.reds  |  10 ++-
 runtime/lexer-transitions.reds | 130 ++++++++++++++++-----------------
 runtime/lexer.reds             |  86 ++++++++++++++--------
 utils/generate-lexer-table.red |  52 ++++++-------
 6 files changed, 157 insertions(+), 131 deletions(-)

diff --git a/environment/natives.red b/environment/natives.red
index 72781b96de..9b56363235 100644
--- a/environment/natives.red
+++ b/environment/natives.red
@@ -921,8 +921,8 @@ transcode: make native! [[
 				event	[word!]
 				input	[binary! string!]
 				type	[word! datatype!]
-				range	[pair!]
-				value	[any-type!]
+				line	[integer!]
+				token
 				return: [logic!]
 			]]
 		return: [block!]
diff --git a/environment/system.red b/environment/system.red
index b2f1078f96..567191be4e 100644
--- a/environment/system.red
+++ b/environment/system.red
@@ -405,9 +405,9 @@ system: context [
 		pre-load: none
 		
 		exit-states: [
-			eof error! block! block! paren! paren! string! string! string! word! file! refinement!
-			binary! char! map! any-type! issue! percent! integer! float! float! tuple! date! pair!
-			time! money! tag! url! email! path! hex comment
+			eof error! block! block! paren! paren! string! string! map! path! any-type!
+			hex comment string!	word! file! refinement!	binary! char! issue! percent!
+			integer! float! float! tuple! date! pair! time! money! tag! url! email! 
 		]
 	]
 	
diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds
index 14449eb867..a1a4418bf0 100644
--- a/runtime/datatypes/common.reds
+++ b/runtime/datatypes/common.reds
@@ -691,8 +691,9 @@ words: context [
 	_write:			as red-word! 0
 	
 	;-- lexer events
-	scan:			as red-word! 0
-	load:			as red-word! 0
+	_scan:			as red-word! 0
+	_load:			as red-word! 0
+	_error:			as red-word! 0
 	
 	errors: context [
 		_throw:		as red-word! 0
@@ -930,8 +931,9 @@ words: context [
 		_write:			word/load "write"
 		
 		;-- lexer events
-		scan:			word/load "scan"
-		load:			word/load "load"
+		_scan:			word/load "scan"
+		_load:			word/load "load"
+		_error:			word/load "error"
 		
 		errors/throw:	 word/load "throw"
 		errors/note:	 word/load "note"
diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds
index b842bf191c..b39f89bd55 100644
--- a/runtime/lexer-transitions.reds
+++ b/runtime/lexer-transitions.reds
@@ -64,16 +64,19 @@ Red/System [
         T_BLK_CL 
         T_PAR_OP 
         T_PAR_CL 
-        T_STRING 
         T_MSTR_OP 
         T_MSTR_CL 
+        T_MAP_OP 
+        T_PATH 
+        T_CONS_MK 
+        T_HEX 
+        T_CMT 
+        T_STRING 
         T_WORD 
         T_FILE 
         T_REFINE 
         T_BINARY 
         T_CHAR 
-        T_MAP_OP 
-        T_CONS_MK 
         T_ISSUE 
         T_PERCENT 
         T_INTEGER 
@@ -86,82 +89,79 @@ Red/System [
         T_MONEY 
         T_TAG 
         T_URL 
-        T_EMAIL 
-        T_PATH 
-        T_HEX 
-        T_CMT
+        T_EMAIL
     ] 
     prev-table: #{
 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333
 330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F
 } 
     transitions: #{
-000013133A3B3C3D3F39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E
-2929392D2D393801570101010101010101010101010101010101010101010101
-0101010101010101010101013938020202020202020202023E02020202020202
+000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E
+2929392D2D393801440101010101010101010101010101010101010101010101
+0101010101010101010101013938020202020202020202024502020202020202
 0202020202020202020202020202020203020239390202020202020202020202
 0202020202020202020202020202020202020202020202020202393804040404
-040404043F400404040404040404040404040404040404040404040404040504
+040404043E3F0404040404040404040404040404040404040404040404040504
 0439390404040404040404040404040404040404040404040404040404040404
-04040404040404043938414107074141414141410A0707410707070707070707
-0707070707074141070707070707073941424207074242424242423907074207
-0707070707070707070707080742420707070707070739420707090939393939
+04040404040404043938464607074646464646460A0707460707070707070707
+0707070707074646070707070707073946474707074747474747473907074707
+0707070707070707070707080747470707070707070739470707090939393939
 3939393939393939390909090939393939393939393939393939393939393907
 0707073939393939393939393939393909090707393939393939393939393939
-3939393939420A0A0A0A0A0A0A0A0A0A420A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
-0A0A0A0A0A0A0A0A0A0A0A393943430B0B434343434343430B0B0B0B0B0B0B0B
-0B0B2D0B0B0B0B0B0B43430B0B0B0B0B0B0B394348481212113946390D390F12
-1239121212121212121212393939123948481212121212121239480D0D0D0D39
-3939393944393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
+3939393939470A0A0A0A0A0A0A0A0A0A470A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
+0A0A0A0A0A0A0A0A0A0A0A393948480B0B484848484848480B0B0B0B0B0B0B0B
+0B0B2D0B0B0B0B0B0B48480B0B0B0B0B0B0B39484B4B1212113940390D390F12
+123912121212121212121239393912394B4B12121212121212394B0D0D0D0D39
+3939393949393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
 39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
-0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F450F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F100F0F39450F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111147111111
-1111111111111111111111111111111111111111111111111111111139394848
-1212484848484848481212121212121212121212121212121212484812121212
-12121239484A4A13134A4A4A4A4A4A4A0C131A1C19561516392119394A393949
-144A3014393919393939394A4B4B15154B4B4B4B4B4B4B1715391C3939151539
-394B394B393949394B3939393939393939394B4B4B15154B4B4B4B4B4B4B3939
-4B393939151539394B394B39394939393018391515393939394B4B4B16164B4B
-4B4B4B4B4B39394B393956152139214B394B3939493939301839151539393939
-4B4B4B4B4C4C4C4C4C4C4C4C174C4C171717171717174C4C4C17174C4C4C4C17
-4C17174C1717394C4D4D18184D4D4D4D4D4D4D39394D393939393939394D394D
-39393939393918393939393939394D4E4E19194E4E4E4E4E4E4E191919191919
-1919191919194E19194E194E4E194E19194E3919394E39391B1B393939393939
-393939393939393939393939393939393939393939393939393939393950501B
-1B5050505050505039391B393939393939395039503939393950391B39393939
-3939395039391D1D393939393939393939393939393939393939393939393939
-393039391D1D39393939394F4F1D1D4F4F4F4F4F4F4F39394F3939391D1D3939
-4F394F393939394F301D393939393939394F39391F1F39393939393939393939
-3939393939393939393939393939393939393939393939393951511F1F515151
-51515151511F5139393939393939513951393939395139203939393939393938
-5151202051515151515151512051393939393939395139513939393951393939
-393939393939384141212141414141414141392D2E2D2D222D212D2155412D2D
-2D393941302D1F2D2D2D2D2D394156562D2D56565656565656392D2E2D2D2D2D
-2D2D2D55562D2D2D393956302D1F2D2D2D2D2D39564141242441414141414141
-2424412424242424242424242D2D2D2424414124242424242424394124242424
-2424242424242524242724242424242424242424522424242424242424242424
+0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F100F0F394A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111142111111
+1111111111111111111111111111111111111111111111111111111139394B4B
+12124B4B4B4B4B4B4B12121212121212121212121212121212124B4B12121212
+121212394B4D4D13134D4D4D4D4D4D4D0C131A1C19431516392119394D39394C
+144D3014393919393939394D4E4E15154E4E4E4E4E4E4E1715391C3939151539
+394E394E39394C394E3939393939393939394E4E4E15154E4E4E4E4E4E4E3939
+4E393939151539394E394E39394C39393018391515393939394E4E4E16164E4E
+4E4E4E4E4E39394E393943152139214E394E39394C3939301839151539393939
+4E4E4E4E4F4F4F4F4F4F4F4F174F4F171717171717174F4F4F17174F4F4F4F17
+4F17174F1717394F505018185050505050505039395039393939393939503950
+3939393939391839393939393939505151191951515151515151191919191919
+1919191919195119195119515119511919513919395139391B1B393939393939
+393939393939393939393939393939393939393939393939393939393953531B
+1B5353535353535339391B393939393939395339533939393953391B39393939
+3939395339391D1D393939393939393939393939393939393939393939393939
+393039391D1D393939393952521D1D525252525252523939523939391D1D3939
+5239523939393952301D393939393939395239391F1F39393939393939393939
+3939393939393939393939393939393939393939393939393954541F1F545454
+54545454541F5439393939393939543954393939395439203939393939393938
+5454202054545454545454542054393939393939395439543939393954393939
+393939393939384646212146464646464646392D2E2D2D222D212D2141462D2D
+2D393946302D1F2D2D2D2D2D394643432D2D43434343434343392D2E2D2D2D2D
+2D2D2D41432D2D2D393943302D1F2D2D2D2D2D39434646242446464646464646
+2424462424242424242424242D2D2D2424464624242424242424394624242424
+2424242424242524242724242424242424242424552424242424242424242424
 2439392525252525252525252524252525252525252525252525252525252525
 2525252525262525393925252525252525252525252525252525252525252525
 2525252525252525252525252525253939272727272727272727272727272427
 2727272727272727272727272727272727272727272739392727272727272727
-2727272727272727272727272727272727272727272727272727272727393941
-4113134141414141414139392D2D2D2D2D2D2D2D2D41392D2D392D412D2A2D2D
-2D392D2D394141412B2B41414141414141392D2E2D2D2D2B2B2D2D55412D2D2D
-393941302D392B2B2D2D2D39414B4B2B2B4B4B4B4B4B4B4B39394B1C39392B2B
-39394B394B39394939393939392B2B393939394B393939393939393939393939
-39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393941412D2D41
-414141414141392D2E2D2D2D2D2D2D2D55412D2D2D393941302D1F2D2D2D2D2D
-394141412F2F414141414141412F2F2F2F2F2F2F2F2F2F2F41392F2F2F2F412F
-2F2F2F2F2F2F2F394153532F2F535353535353532F392F2F2F2F2F2F2F2F2F53
-53392F2F53532F2F392F2F392F2F395354543030545454545454543939393030
-30303030305454543939303954393039303039303039543939323239393C3D39
-3902353333343434343434343939233434393939303439363639343439394A4A
-32324A4A4A4A4A4A4A39134A1C3939151539394A394A393949144A3014393939
-393939394A393939393939393939393939393934343434343434393934343439
-3939393439343439343439394141343441414141414141393441343434343434
-34414134343439394130343934343434343941484812121139393939390F1212
-3912121212121212121239393912394848121212121212123948414132324141
-414141414139392D2D2D2D2D2D2D2D2D41392D2D392D412D2D2D2D2D392D2D39
-41
+2727272727272727272727272727272727272727272727272727272727393946
+4613134646464646464639392D2D2D2D2D2D2D2D2D46392D2D392D462D2A2D2D
+2D392D2D394646462B2B46464646464646392D2E2D2D2D2B2B2D2D41462D2D2D
+393946302D392B2B2D2D2D39464E4E2B2B4E4E4E4E4E4E4E39394E1C39392B2B
+39394E394E39394C39393939392B2B393939394E393939393939393939393939
+39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393946462D2D46
+464646464646392D2E2D2D2D2D2D2D2D41462D2D2D393946302D1F2D2D2D2D2D
+394646462F2F464646464646462F2F2F2F2F2F2F2F2F2F2F46392F2F2F2F462F
+2F2F2F2F2F2F2F394656562F2F565656565656562F392F2F2F2F2F2F2F2F2F56
+56392F2F56562F2F392F2F392F2F395657573030575757575757573939393030
+30303030305757573939303957393039303039303039573939323239393C3D39
+3902353333343434343434343939233434393939303439363639343439394D4D
+32324D4D4D4D4D4D4D39134D1C3939151539394D394D39394C144D3014393939
+393939394D393939393939393939393939393934343434343434393934343439
+3939393439343439343439394646343446464646464646393446343434343434
+344646343434393946303439343434343439464B4B12121139393939390F1212
+3912121212121212121239393912394B4B12121212121212394B464632324646
+464646464639392D2D2D2D2D2D2D2D2D46392D2D392D462D2D2D2D2D392D2D39
+46
 }
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 247e8f1c5d..760c5aa47f 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -442,16 +442,22 @@ lexer: context [
 		return: [logic!]
 		/local
 			len x y [integer!]
+			ser	  [red-series!]
 			res	  [red-value!]
 			blk	  [red-block!]
-			loop? [logic!]
+			cont? [logic!]
 	][
 		stack/mark-func words/_body	lex/fun-ptr/ctx		;@@ find something more adequate
-		stack/push as red-value! event
-		stack/push as red-value! lex/in-series
-		blk: as red-block! #get system/lexer/exit-states
-		either TYPE_OF(blk) <> TYPE_BLOCK [none/push][
-			stack/push block/rs-abs-at blk type - 1		;-- 1-base access
+		stack/push as red-value! event					;-- event
+		ser: as red-series! stack/push as red-value! lex/in-series ;-- input
+		
+		either any [event = words/_scan event = words/_error][;-- type
+			blk: as red-block! #get system/lexer/exit-states
+			either TYPE_OF(blk) <> TYPE_BLOCK [none/push][
+				stack/push block/rs-abs-at blk type - 1		;-- 1-based access
+			]
+		][
+			datatype/push type
 		]
 		either all [lex/in-series <> null TYPE_OF(lex/in-series) <> TYPE_BINARY][
 			x: count-chars lex/input s
@@ -460,16 +466,17 @@ lexer: context [
 			x: as-integer s - lex/input
 			y: as-integer e - lex/input
 		]
-		pair/push x + 1 y + 1 							;-- 1-base series positions
-		either null? value [none/push][stack/push value]
-		if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs]	;-- +1 for /local refinement
+		ser/head: y										;-- 0-based offset
+		integer/push lex/line							;-- line number
+		either null? value [pair/push x + 1 y + 1][stack/push value] ;-- token
 
+		if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs]	;-- +1 for /local refinement
 		catch RED_THROWN_ERROR [_function/call lex/fun-ptr global-ctx]	;FIXME: hardcoded origin context
 		if system/thrown <> 0 [re-throw]
 
-		loop?: logic/top-true?
+		cont?: logic/top-true?
 		stack/unwind
-		loop?
+		cont?
 	]
 	
 	mark-buffers: func [/local s [state!]][
@@ -892,11 +899,13 @@ lexer: context [
 			type [integer!]
 	][
 		type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK]
+		if lex/fun-ptr <> null [fire-event lex words/_open type null s e]
 		open-block lex type -1 null
 		lex/in-pos: e + 1								;-- skip delimiter
 	]
 
 	scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		if lex/fun-ptr <> null [fire-event lex words/_close TYPE_BLOCK null s e]
 		close-block lex s e TYPE_BLOCK -1
 		lex/in-pos: e + 1								;-- skip ]
 	]
@@ -905,6 +914,7 @@ lexer: context [
 		/local
 			blk	 [red-block!]
 	][
+		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_PAREN null s e]
 		if TYPE_MAP = close-block lex s e TYPE_PAREN -1 [
 			blk: as red-block! lex/tail - 1
 			map/make-at as cell! blk blk block/rs-length? blk
@@ -1073,20 +1083,27 @@ lexer: context [
 		lex/mstr-flags: lex/mstr-flags or flags
 		lex/entry: S_M_STRING
 		lex/in-pos: e + 1								;-- skip {
+		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e]
 	]
 	
 	scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
 		lex/mstr-nest: lex/mstr-nest - 1
 
 		either zero? lex/mstr-nest [
+			if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e]
 			scan-string lex lex/mstr-s e lex/mstr-flags or flags
 			lex/mstr-s: null
 			lex/mstr-flags: 0
 			lex/entry: S_START
+			lex/in-pos: e + 1								;-- skip }
+			
+			if lex/fun-ptr <> null [
+				unless fire-event lex words/_load TYPE_STRING lex/tail - 1 s lex/in-pos [lex/tail: lex/tail - 1]
+			]
 		][
 			if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING]
+			lex/in-pos: e + 1								;-- skip }
 		]
-		lex/in-pos: e + 1								;-- skip }
 	]
 	
 	scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!]
@@ -1762,11 +1779,10 @@ lexer: context [
 		one? [logic!]
 		/local
 			cp class index state prev flags line mark offset [integer!]
-			slot	  [red-value!]
-			p e	start [byte-ptr!]
-			s		  [series!]
-			term?	  [logic!]
-			do-scan   [scanner!]
+			p e	start s [byte-ptr!]
+			slot		[cell!]
+			term? load?	[logic!]
+			do-scan		[scanner!]
 	][
 		line: 1
 		until [
@@ -1799,8 +1815,9 @@ lexer: context [
 				state: as-integer transitions/index
 				#if debug? = yes [if verbose > 0 [?? state]]
 			]
-			assert state <= T_CMT
-			assert start + offset <= p
+			s: start + offset
+			assert state <= T_EMAIL
+			assert s <= p
 			
 			lex/in-pos: p
 			lex/line:   line
@@ -1808,14 +1825,21 @@ lexer: context [
 			lex/exit:   state
 			lex/prev:	prev
 			lex/type:	-1
+			load?:		yes
 			
 			index: state - --EXIT_STATES--
-			if lex/fun-ptr <> null [fire-event lex words/scan index null start + offset lex/in-pos]
-			do-scan: as scanner! scanners/index
-			do-scan lex start + offset p flags
-			
-			if all [lex/entry = S_PATH state <> T_PATH][
-				scan-path-item lex start + offset lex/in-pos flags ;-- lex/in-pos could have changed
+			if lex/fun-ptr <> null [load?: fire-event lex words/_scan index null s lex/in-pos]
+			if load? [
+				do-scan: as scanner! scanners/index
+				do-scan lex s p flags
+
+				if all [state >= T_STRING lex/fun-ptr <> null][ ;-- for < T_STRING, events are triggered from scan-*
+					slot: lex/tail - 1
+					unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot]
+				]
+				if all [lex/entry = S_PATH state <> T_PATH][
+					scan-path-item lex s lex/in-pos flags	;-- lex/in-pos could have changed
+				]
 			]
 			if all [one? state <> T_BLK_OP state <> T_PAR_OP state <> T_MSTR_OP][exit]
 			lex/in-pos >= lex/in-end
@@ -1940,16 +1964,19 @@ lexer: context [
 			:scan-block-close							;-- T_BLK_CL
 			:scan-block-open							;-- T_PAR_OP
 			:scan-paren-close							;-- T_PAR_CL
-			:scan-string								;-- T_STRING
 			:scan-mstring-open							;-- T_MSTR_OP (multiline string)
 			:scan-mstring-close							;-- T_MSTR_CL (multiline string)
+			:scan-map-open								;-- T_MAP_OP
+			:scan-path-open								;-- T_PATH
+			:scan-construct								;-- T_CONS_MK
+			:scan-hex									;-- T_HEX
+			:scan-comment								;-- T_CMT
+			:scan-string								;-- T_STRING
 			:scan-word									;-- T_WORD
 			:scan-file									;-- T_FILE
 			:scan-ref-issue								;-- T_REFINE
 			:scan-binary								;-- T_BINARY
 			:scan-char									;-- T_CHAR
-			:scan-map-open								;-- T_MAP_OP
-			:scan-construct								;-- T_CONS_MK
 			:scan-ref-issue								;-- T_ISSUE
 			:scan-percent								;-- T_PERCENT
 			:scan-integer								;-- T_INTEGER
@@ -1963,9 +1990,6 @@ lexer: context [
 			:scan-tag									;-- T_TAG
 			:scan-url									;-- T_URL
 			:scan-email									;-- T_EMAIL
-			:scan-path-open								;-- T_PATH
-			:scan-hex									;-- T_HEX
-			:scan-comment								;-- T_CMT
 		]
 	]
 
diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red
index f6b16cc414..935f0caf5e 100644
--- a/utils/generate-lexer-table.red
+++ b/utils/generate-lexer-table.red
@@ -75,32 +75,32 @@ context [
 		T_BLK_CL			-					;-- 59
 		T_PAR_OP			-					;-- 60
 		T_PAR_CL			-					;-- 61
-		T_STRING			-					;-- 62
-		T_MSTR_OP			-					;-- 63
-		T_MSTR_CL			-					;-- 64
-		T_WORD				-					;-- 65
-		T_FILE				-					;-- 66
-		T_REFINE			-					;-- 67
-		T_BINARY			-					;-- 68
-		T_CHAR				-					;-- 69
-		T_MAP_OP			-					;-- 70
-		T_CONS_MK			-					;-- 71
-		T_ISSUE				-					;-- 72
-		T_PERCENT			-					;-- 73
-		T_INTEGER			-					;-- 74
-		T_FLOAT				-					;-- 75
-		T_FLOAT_SP			-					;-- 76
-		T_TUPLE				-					;-- 77
-		T_DATE				-					;-- 78
-		T_PAIR				-					;-- 79
-		T_TIME				-					;-- 80
-		T_MONEY				-					;-- 81
-		T_TAG				-					;-- 82
-		T_URL				-					;-- 83
-		T_EMAIL				-					;-- 84
-		T_PATH				-					;-- 85
-		T_HEX				-					;-- 86
-		T_CMT				-					;-- 87
+		T_MSTR_OP			-					;-- 62
+		T_MSTR_CL			-					;-- 63
+		T_MAP_OP			-					;-- 64
+		T_PATH				-					;-- 65
+		T_CONS_MK			-					;-- 66
+		T_HEX				-					;-- 67
+		T_CMT				-					;-- 68
+		T_STRING			-					;-- 69
+		T_WORD				-					;-- 70
+		T_FILE				-					;-- 71
+		T_REFINE			-					;-- 72
+		T_BINARY			-					;-- 73
+		T_CHAR				-					;-- 74
+		T_ISSUE				-					;-- 75
+		T_PERCENT			-					;-- 76
+		T_INTEGER			-					;-- 77
+		T_FLOAT				-					;-- 78
+		T_FLOAT_SP			-					;-- 79
+		T_TUPLE				-					;-- 80
+		T_DATE				-					;-- 81
+		T_PAIR				-					;-- 82
+		T_TIME				-					;-- 83
+		T_MONEY				-					;-- 84
+		T_TAG				-					;-- 85
+		T_URL				-					;-- 86
+		T_EMAIL				-					;-- 87
 	]
 
 	CSV-table: %../docs/lexer/lexer-FSM.csv

From 28acc8d97c69d3371c13ac609f5a59889d340066 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 8 Jan 2020 00:29:52 +0100
Subject: [PATCH 0711/3432] FEAT: better lexer event handling for hex and
 comment tokens.

---
 environment/system.red         |   4 +-
 runtime/datatypes/common.reds  |   2 +
 runtime/lexer-transitions.reds | 114 ++++++++++++++++-----------------
 runtime/lexer.reds             |   7 +-
 utils/generate-lexer-table.red |  42 ++++++------
 5 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/environment/system.red b/environment/system.red
index 567191be4e..c609236cf9 100644
--- a/environment/system.red
+++ b/environment/system.red
@@ -406,8 +406,8 @@ system: context [
 		
 		exit-states: [
 			eof error! block! block! paren! paren! string! string! map! path! any-type!
-			hex comment string!	word! file! refinement!	binary! char! issue! percent!
-			integer! float! float! tuple! date! pair! time! money! tag! url! email! 
+			comment string!	word! file! refinement!	binary! char! issue! percent!
+			integer! float! float! tuple! date! pair! time! money! tag! url! email! hex
 		]
 	]
 	
diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds
index a1a4418bf0..522cb91592 100644
--- a/runtime/datatypes/common.reds
+++ b/runtime/datatypes/common.reds
@@ -694,6 +694,7 @@ words: context [
 	_scan:			as red-word! 0
 	_load:			as red-word! 0
 	_error:			as red-word! 0
+	_comment:		as red-word! 0
 	
 	errors: context [
 		_throw:		as red-word! 0
@@ -934,6 +935,7 @@ words: context [
 		_scan:			word/load "scan"
 		_load:			word/load "load"
 		_error:			word/load "error"
+		_comment:		word/load "comment"
 		
 		errors/throw:	 word/load "throw"
 		errors/note:	 word/load "note"
diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds
index b39f89bd55..e2d9d088e7 100644
--- a/runtime/lexer-transitions.reds
+++ b/runtime/lexer-transitions.reds
@@ -69,7 +69,6 @@ Red/System [
         T_MAP_OP 
         T_PATH 
         T_CONS_MK 
-        T_HEX 
         T_CMT 
         T_STRING 
         T_WORD 
@@ -89,7 +88,8 @@ Red/System [
         T_MONEY 
         T_TAG 
         T_URL 
-        T_EMAIL
+        T_EMAIL 
+        T_HEX
     ] 
     prev-table: #{
 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333
@@ -97,71 +97,71 @@ Red/System [
 } 
     transitions: #{
 000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E
-2929392D2D393801440101010101010101010101010101010101010101010101
-0101010101010101010101013938020202020202020202024502020202020202
+2929392D2D393801430101010101010101010101010101010101010101010101
+0101010101010101010101013938020202020202020202024402020202020202
 0202020202020202020202020202020203020239390202020202020202020202
 0202020202020202020202020202020202020202020202020202393804040404
 040404043E3F0404040404040404040404040404040404040404040404040504
 0439390404040404040404040404040404040404040404040404040404040404
-04040404040404043938464607074646464646460A0707460707070707070707
-0707070707074646070707070707073946474707074747474747473907074707
-0707070707070707070707080747470707070707070739470707090939393939
+04040404040404043938454507074545454545450A0707450707070707070707
+0707070707074545070707070707073945464607074646464646463907074607
+0707070707070707070707080746460707070707070739460707090939393939
 3939393939393939390909090939393939393939393939393939393939393907
 0707073939393939393939393939393909090707393939393939393939393939
-3939393939470A0A0A0A0A0A0A0A0A0A470A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
-0A0A0A0A0A0A0A0A0A0A0A393948480B0B484848484848480B0B0B0B0B0B0B0B
-0B0B2D0B0B0B0B0B0B48480B0B0B0B0B0B0B39484B4B1212113940390D390F12
-123912121212121212121239393912394B4B12121212121212394B0D0D0D0D39
-3939393949393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
+3939393939460A0A0A0A0A0A0A0A0A0A460A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
+0A0A0A0A0A0A0A0A0A0A0A393947470B0B474747474747470B0B0B0B0B0B0B0B
+0B0B2D0B0B0B0B0B0B47470B0B0B0B0B0B0B39474A4A1212113940390D390F12
+123912121212121212121239393912394A4A12121212121212394A0D0D0D0D39
+3939393948393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
 39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
-0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F100F0F394A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
+0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F490F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F100F0F39490F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111142111111
-1111111111111111111111111111111111111111111111111111111139394B4B
-12124B4B4B4B4B4B4B12121212121212121212121212121212124B4B12121212
-121212394B4D4D13134D4D4D4D4D4D4D0C131A1C19431516392119394D39394C
-144D3014393919393939394D4E4E15154E4E4E4E4E4E4E1715391C3939151539
-394E394E39394C394E3939393939393939394E4E4E15154E4E4E4E4E4E4E3939
-4E393939151539394E394E39394C39393018391515393939394E4E4E16164E4E
-4E4E4E4E4E39394E393943152139214E394E39394C3939301839151539393939
-4E4E4E4E4F4F4F4F4F4F4F4F174F4F171717171717174F4F4F17174F4F4F4F17
-4F17174F1717394F505018185050505050505039395039393939393939503950
-3939393939391839393939393939505151191951515151515151191919191919
-1919191919195119195119515119511919513919395139391B1B393939393939
-393939393939393939393939393939393939393939393939393939393953531B
-1B5353535353535339391B393939393939395339533939393953391B39393939
-3939395339391D1D393939393939393939393939393939393939393939393939
-393039391D1D393939393952521D1D525252525252523939523939391D1D3939
-5239523939393952301D393939393939395239391F1F39393939393939393939
-3939393939393939393939393939393939393939393939393954541F1F545454
-54545454541F5439393939393939543954393939395439203939393939393938
-5454202054545454545454542054393939393939395439543939393954393939
-393939393939384646212146464646464646392D2E2D2D222D212D2141462D2D
-2D393946302D1F2D2D2D2D2D394643432D2D43434343434343392D2E2D2D2D2D
-2D2D2D41432D2D2D393943302D1F2D2D2D2D2D39434646242446464646464646
-2424462424242424242424242D2D2D2424464624242424242424394624242424
-2424242424242524242724242424242424242424552424242424242424242424
+1111111111111111111111111111111111111111111111111111111139394A4A
+12124A4A4A4A4A4A4A12121212121212121212121212121212124A4A12121212
+121212394A4C4C13134C4C4C4C4C4C4C0C131A1C19571516392119394C39394B
+144C3014393919393939394C4D4D15154D4D4D4D4D4D4D1715391C3939151539
+394D394D39394B394D3939393939393939394D4D4D15154D4D4D4D4D4D4D3939
+4D393939151539394D394D39394B39393018391515393939394D4D4D16164D4D
+4D4D4D4D4D39394D393957152139214D394D39394B3939301839151539393939
+4D4D4D4D4E4E4E4E4E4E4E4E174E4E171717171717174E4E4E17174E4E4E4E17
+4E17174E1717394E4F4F18184F4F4F4F4F4F4F39394F393939393939394F394F
+39393939393918393939393939394F5050191950505050505050191919191919
+1919191919195019195019505019501919503919395039391B1B393939393939
+393939393939393939393939393939393939393939393939393939393952521B
+1B5252525252525239391B393939393939395239523939393952391B39393939
+3939395239391D1D393939393939393939393939393939393939393939393939
+393039391D1D393939393951511D1D515151515151513939513939391D1D3939
+5139513939393951301D393939393939395139391F1F39393939393939393939
+3939393939393939393939393939393939393939393939393953531F1F535353
+53535353531F5339393939393939533953393939395339203939393939393938
+5353202053535353535353532053393939393939395339533939393953393939
+393939393939384545212145454545454545392D2E2D2D222D212D2141452D2D
+2D393945302D1F2D2D2D2D2D394557572D2D57575757575757392D2E2D2D2D2D
+2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574545242445454545454545
+2424452424242424242424242D2D2D2424454524242424242424394524242424
+2424242424242524242724242424242424242424542424242424242424242424
 2439392525252525252525252524252525252525252525252525252525252525
 2525252525262525393925252525252525252525252525252525252525252525
 2525252525252525252525252525253939272727272727272727272727272427
 2727272727272727272727272727272727272727272739392727272727272727
-2727272727272727272727272727272727272727272727272727272727393946
-4613134646464646464639392D2D2D2D2D2D2D2D2D46392D2D392D462D2A2D2D
-2D392D2D394646462B2B46464646464646392D2E2D2D2D2B2B2D2D41462D2D2D
-393946302D392B2B2D2D2D39464E4E2B2B4E4E4E4E4E4E4E39394E1C39392B2B
-39394E394E39394C39393939392B2B393939394E393939393939393939393939
-39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393946462D2D46
-464646464646392D2E2D2D2D2D2D2D2D41462D2D2D393946302D1F2D2D2D2D2D
-394646462F2F464646464646462F2F2F2F2F2F2F2F2F2F2F46392F2F2F2F462F
-2F2F2F2F2F2F2F394656562F2F565656565656562F392F2F2F2F2F2F2F2F2F56
-56392F2F56562F2F392F2F392F2F395657573030575757575757573939393030
-30303030305757573939303957393039303039303039573939323239393C3D39
-3902353333343434343434343939233434393939303439363639343439394D4D
-32324D4D4D4D4D4D4D39134D1C3939151539394D394D39394C144D3014393939
-393939394D393939393939393939393939393934343434343434393934343439
-3939393439343439343439394646343446464646464646393446343434343434
-344646343434393946303439343434343439464B4B12121139393939390F1212
-3912121212121212121239393912394B4B12121212121212394B464632324646
-464646464639392D2D2D2D2D2D2D2D2D46392D2D392D462D2D2D2D2D392D2D39
-46
+2727272727272727272727272727272727272727272727272727272727393945
+4513134545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D
+2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D
+393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B
+39394D394D39394B39393939392B2B393939394D393939393939393939393939
+39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45
+454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D1F2D2D2D2D2D
+394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F
+2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55
+55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030
+30303030305656563939303956393039303039303039563939323239393C3D39
+3902353333343434343434343939233434393939303439363639343439394C4C
+32324C4C4C4C4C4C4C39134C1C3939151539394C394C39394B144C3014393939
+393939394C393939393939393939393939393934343434343434393934343439
+3939393439343439343439394545343445454545454545393445343434343434
+344545343434393945303439343434343439454A4A12121139393939390F1212
+3912121212121212121239393912394A4A12121212121212394A454532324545
+454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39
+45
 }
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 760c5aa47f..0deb74a3ef 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -1741,9 +1741,8 @@ lexer: context [
 	]
 	
 	scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		;TBD: trigger an event
+		if lex/fun-ptr <> null [fire-event lex words/_open T_CMT - --EXIT_STATES-- null s e]
 	]
-
 	
 	scan-path-item: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
@@ -1816,7 +1815,7 @@ lexer: context [
 				#if debug? = yes [if verbose > 0 [?? state]]
 			]
 			s: start + offset
-			assert state <= T_EMAIL
+			assert state <= T_HEX
 			assert s <= p
 			
 			lex/in-pos: p
@@ -1969,7 +1968,6 @@ lexer: context [
 			:scan-map-open								;-- T_MAP_OP
 			:scan-path-open								;-- T_PATH
 			:scan-construct								;-- T_CONS_MK
-			:scan-hex									;-- T_HEX
 			:scan-comment								;-- T_CMT
 			:scan-string								;-- T_STRING
 			:scan-word									;-- T_WORD
@@ -1990,6 +1988,7 @@ lexer: context [
 			:scan-tag									;-- T_TAG
 			:scan-url									;-- T_URL
 			:scan-email									;-- T_EMAIL
+			:scan-hex									;-- T_HEX
 		]
 	]
 
diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red
index 935f0caf5e..053d366502 100644
--- a/utils/generate-lexer-table.red
+++ b/utils/generate-lexer-table.red
@@ -80,27 +80,27 @@ context [
 		T_MAP_OP			-					;-- 64
 		T_PATH				-					;-- 65
 		T_CONS_MK			-					;-- 66
-		T_HEX				-					;-- 67
-		T_CMT				-					;-- 68
-		T_STRING			-					;-- 69
-		T_WORD				-					;-- 70
-		T_FILE				-					;-- 71
-		T_REFINE			-					;-- 72
-		T_BINARY			-					;-- 73
-		T_CHAR				-					;-- 74
-		T_ISSUE				-					;-- 75
-		T_PERCENT			-					;-- 76
-		T_INTEGER			-					;-- 77
-		T_FLOAT				-					;-- 78
-		T_FLOAT_SP			-					;-- 79
-		T_TUPLE				-					;-- 80
-		T_DATE				-					;-- 81
-		T_PAIR				-					;-- 82
-		T_TIME				-					;-- 83
-		T_MONEY				-					;-- 84
-		T_TAG				-					;-- 85
-		T_URL				-					;-- 86
-		T_EMAIL				-					;-- 87
+		T_CMT				-					;-- 67
+		T_STRING			-					;-- 68
+		T_WORD				-					;-- 69
+		T_FILE				-					;-- 70
+		T_REFINE			-					;-- 71
+		T_BINARY			-					;-- 72
+		T_CHAR				-					;-- 73
+		T_ISSUE				-					;-- 74
+		T_PERCENT			-					;-- 75
+		T_INTEGER			-					;-- 76
+		T_FLOAT				-					;-- 77
+		T_FLOAT_SP			-					;-- 78
+		T_TUPLE				-					;-- 79
+		T_DATE				-					;-- 80
+		T_PAIR				-					;-- 81
+		T_TIME				-					;-- 82
+		T_MONEY				-					;-- 83
+		T_TAG				-					;-- 84
+		T_URL				-					;-- 85
+		T_EMAIL				-					;-- 86
+		T_HEX				-					;-- 87
 	]
 
 	CSV-table: %../docs/lexer/lexer-FSM.csv

From b959fc10552d5992f8c90b8eafabc76ad6029f5d Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Wed, 8 Jan 2020 10:56:58 +0100
Subject: [PATCH 0712/3432] FIX: D2D render target conflicts with caret.

---
 modules/view/backends/windows/base.reds     |  3 ++-
 modules/view/backends/windows/direct2d.reds |  5 ++---
 modules/view/backends/windows/draw.reds     |  6 ++++--
 modules/view/backends/windows/events.reds   | 10 ++++-----
 modules/view/backends/windows/gui.reds      | 23 +++++++--------------
 5 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index 91430fd695..39d98b6e07 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -36,6 +36,7 @@ init-base-face: func [
 	SetWindowLong handle wc-offset - 16 parent
 	SetWindowLong handle wc-offset - 20 0
 	SetWindowLong handle wc-offset - 24 0
+	SetWindowLong handle wc-offset - 32 0
 	pt/x: dpi-scale offset/x
 	pt/y: dpi-scale offset/y
 	either alpha? [
@@ -464,7 +465,7 @@ BaseWndProc: func [
 					update-base hWnd null null get-face-values hWnd
 				]
 			][
-				target: as render-target! GetWindowLong hWnd wc-offset - 24
+				target: as render-target! GetWindowLong hWnd wc-offset - 32
 				if target <> null [
 					DX-resize-buffer target WIN32_LOWORD(lParam) WIN32_HIWORD(lParam)
 					InvalidateRect hWnd null 1
diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 4a01a63005..dba55697b8 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -1648,7 +1648,6 @@ to-dx-color: func [
 d2d-release-target: func [
 	target	[render-target!]
 	/local
-		rt		[ID2D1HwndRenderTarget]
 		brushes [int-ptr!]
 		cnt		[integer!]
 		this	[this!]
@@ -1712,12 +1711,12 @@ get-hwnd-render-target: func [
 	/local
 		target	[render-target!]
 ][
-	target: as render-target! GetWindowLong hWnd wc-offset - 24
+	target: as render-target! GetWindowLong hWnd wc-offset - 32
 	if null? target [
 		target: as render-target! alloc0 size? render-target!
 		create-render-target hWnd target
 		target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr!
-		SetWindowLong hWnd wc-offset - 24 as-integer target
+		SetWindowLong hWnd wc-offset - 32 as-integer target
 	]
 	target
 ]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 2d30253ba0..020a58e613 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -284,7 +284,7 @@ draw-end: func [
 			DXGI_ERROR_DEVICE_RESET [
 				d2d-release-target rt
 				ctx/dc: null
-				SetWindowLong hWnd wc-offset - 24 0
+				SetWindowLong hWnd wc-offset - 32 0
 				DX-create-dev
 				InvalidateRect hWnd null 0
 			]
@@ -830,7 +830,6 @@ OS-draw-line: func [
 				ctx/pen-grad-type
 				ctx/pen-offset
 				as float32! pt0/x as float32! pt0/y as float32! pt1/x as float32! pt1/y
-			post-process-brush ctx/pen ctx/pen-offset
 		]
 		if ctx/pen-type <> DRAW_BRUSH_NONE [
 			dc/DrawLine 
@@ -841,6 +840,9 @@ OS-draw-line: func [
 				ctx/pen-width
 				ctx/pen-style
 		]
+		if ctx/pen-type > DRAW_BRUSH_GRADIENT [
+			post-process-brush ctx/pen ctx/pen-offset
+		]
 	][
 		_OS-draw-polygon ctx point end no
 	]
diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds
index 0ae3599a68..73f50fde34 100644
--- a/modules/view/backends/windows/events.reds
+++ b/modules/view/backends/windows/events.reds
@@ -978,10 +978,10 @@ update-window: func [
 					type = rich-text
 					(GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0
 				][
-					len: GetWindowLong hWnd wc-offset - 24
+					len: GetWindowLong hWnd wc-offset - 32
 					if len <> 0 [
 						d2d-release-target as render-target! len
-						SetWindowLong hWnd wc-offset - 24 0
+						SetWindowLong hWnd wc-offset - 32 0
 					]
 				]
 				type = group-box [
@@ -1089,7 +1089,7 @@ WndProc: func [
 		WM_MOVE
 		WM_SIZE [
 			if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [
-				target: as render-target! GetWindowLong hWnd wc-offset - 24
+				target: as render-target! GetWindowLong hWnd wc-offset - 32
 				if target <> null [
 					DX-resize-buffer target WIN32_LOWORD(lParam) WIN32_HIWORD(lParam)
 					InvalidateRect hWnd null 1
@@ -1412,9 +1412,9 @@ WndProc: func [
 			if hidden-hwnd <> null [
 				values: (get-face-values hidden-hwnd) + FACE_OBJ_EXT3
 				values/header: TYPE_NONE
-				target: as render-target! GetWindowLong hidden-hwnd wc-offset - 24
+				target: as render-target! GetWindowLong hidden-hwnd wc-offset - 32
 				if target <> null [d2d-release-target target]
-				SetWindowLong hidden-hwnd wc-offset - 24 0
+				SetWindowLong hidden-hwnd wc-offset - 32 0
 			]
 			RedrawWindow hWnd null null 4 or 1			;-- RDW_ERASE | RDW_INVALIDATE
 		]
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 68f2afba28..4391f881c6 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -13,9 +13,9 @@ Red/System [
 ;; ===== Extra slots usage in Window structs =====
 ;;
 ;;		-60  :							<- TOP
+;;		-32  : Direct2D render target
 ;;		-28  : Cursor handle
-;;		-24  : Direct2D target interface
-;;			   base-layered: caret's owner handle
+;;		-24  : base-layered: caret's owner handle
 ;;		-20  : evolved-base-layered: child handle, window: previous focused handle
 ;;		-16  : base-layered: owner handle, window: border width and height
 ;;		-12  : base-layered: clipped? flag, caret? flag, d2d? flag, ime? flag
@@ -626,17 +626,10 @@ free-faces: func [
 			]
 		]
 		any [sym = window sym = panel sym = base sym = rich-text][
-			if zero? (WS_EX_LAYERED and GetWindowLong handle GWL_EXSTYLE) [
-				dc: GetWindowLong handle wc-offset - 4
-				if dc <> 0 [DeleteDC as handle! dc]			;-- delete cached dc
-			]
-			dc: GetWindowLong handle wc-offset - 24
-			if dc <> 0 [
-				either (GetWindowLong handle wc-offset - 12) and BASE_FACE_IME <> 0 [
-					d2d-release-target as render-target! dc
-				][											;-- caret
-					DestroyCaret
-				]
+			dc: GetWindowLong handle wc-offset - 32
+			if dc <> 0 [d2d-release-target as render-target! dc]
+			if (GetWindowLong handle wc-offset - 12) and BASE_FACE_IME <> 0 [
+				DestroyCaret
 			]
 		]
 		true [
@@ -907,7 +900,7 @@ init-window: func [										;-- post-creation settings
 ][
 	SetWindowLong handle wc-offset - 4 0
 	SetWindowLong handle wc-offset - 16 0
-	SetWindowLong handle wc-offset - 24 0
+	SetWindowLong handle wc-offset - 32 0
 ]
 
 get-selected-handle: func [
@@ -1569,7 +1562,7 @@ OS-make-view: func [
 		]
 		panel? [
 			adjust-parent handle as handle! parent offset/x offset/y
-			SetWindowLong handle wc-offset - 24 0
+			SetWindowLong handle wc-offset - 32 0
 		]
 		sym = slider [
 			vertical?: size/y > size/x

From 9bd3424a08cf9f4b02a20a9774161acc9d3b187a Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Wed, 8 Jan 2020 20:08:34 +0800
Subject: [PATCH 0713/3432] TESTS: update radial tests

---
 tests/complexpen-test.red | 78 +++++++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 24 deletions(-)

diff --git a/tests/complexpen-test.red b/tests/complexpen-test.red
index 40464251db..778cd5403a 100644
--- a/tests/complexpen-test.red
+++ b/tests/complexpen-test.red
@@ -223,22 +223,37 @@ drawings: [
             ( as-pair start-x + width start-y + height )
 
         text ( as-pair start-x + (1 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0;c=f;r=50"
-        fill-pen radial red 0.1 green 0.8 blue 1.0  100x100 50
-        box 
-            ( as-pair start-x + (1 * (width + step-x)) start-y ) 
-            ( as-pair start-x + width + (1 * (width + step-x)) start-y + height )
+        fill-pen radial red 0.1 green 0.8 blue 1.0
+            (
+                box-start: as-pair start-x + (1 * (width + step-x)) start-y
+                box-stop: as-pair start-x + width + (1 * (width + step-x)) start-y + height
+                box-start + 100x100
+            )
+            50
+        box (box-start) (box-stop)
 
         text ( as-pair start-x + (2 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0;c<>f;r=50"
-        fill-pen radial red 0.1 green 0.8 blue 1.0 100x100 50 80x80
-        box 
-            ( as-pair start-x + (2 * (width + step-x)) start-y ) 
-            ( as-pair start-x + width + (2 * (width + step-x)) start-y + height )
+        fill-pen radial red 0.1 green 0.8 blue 1.0
+            (
+                box-start: as-pair start-x + (2 * (width + step-x)) start-y
+                box-stop: as-pair start-x + width + (2 * (width + step-x)) start-y + height
+                box-start + 100x100
+            )
+            50
+            (80x80 - 100x100)
+        box (box-start) (box-stop)
 
         text ( as-pair start-x + (3 * (width + step-x)) start-y - 20 ) "0.1, 0.8, 1.0;c=f;reflect"
-        fill-pen radial red 0.1 green 0.8 blue 1.0 70x100 50 50x80 reflect
-        box 
-            ( as-pair start-x + (3 * (width + step-x)) start-y ) 
-            ( as-pair start-x + width + (3 * (width + step-x)) start-y + height )
+        fill-pen radial red 0.1 green 0.8 blue 1.0
+            (
+                box-start: as-pair start-x + (3 * (width + step-x)) start-y
+                box-stop: as-pair start-x + width + (3 * (width + step-x)) start-y + height
+                box-start + 70x100
+            )
+            50
+            (50x80 - 70x100)
+            reflect
+        box (box-start) (box-stop)
 
 
         text ( as-pair start-x start-y + (1 * (height + step-y)) - 20 ) "no stops;c=f;r=max"
@@ -248,22 +263,37 @@ drawings: [
             ( as-pair start-x + width start-y + height +(1 * (height + step-y)) )
 
         text ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops;c=f;r=50"
-        fill-pen radial red green blue 100x100 50 
-        box 
-            ( as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y)) ) 
-            ( as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y)) )
+        fill-pen radial red green blue
+            (
+                box-start: as-pair start-x + (1 * (width + step-x)) start-y + (1 * (height + step-y))
+                box-stop: as-pair start-x + width + (1 * (width + step-x)) start-y + height +(1 * (height + step-y))
+                box-start + 100x100
+            )
+            50
+        box (box-start) (box-stop)
 
         text ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops;c<>f;r=50"
-        fill-pen radial red green blue 100x100 50 80x80
-        box 
-            ( as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y)) ) 
-            ( as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y)) )
+        fill-pen radial red green blue
+            (
+                box-start: as-pair start-x + (2 * (width + step-x)) start-y + (1 * (height + step-y))
+                box-stop: as-pair start-x + width + (2 * (width + step-x)) start-y + height +(1 * (height + step-y))
+                box-start + 100x100
+            )
+            50
+            (80x80 - 100x100)
+        box (box-start) (box-stop)
 
         text ( as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) - 20 ) "no stops;c=f;reflect"
-        fill-pen radial red green blue  70x100 50 50x80 reflect
-        box 
-            ( as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y)) ) 
-            ( as-pair start-x + width + (3 * (width + step-x)) start-y + height +(1 * (height + step-y)) )
+        fill-pen radial red green blue
+            (
+                box-start: as-pair start-x + (3 * (width + step-x)) start-y + (1 * (height + step-y))
+                box-stop: as-pair start-x + width + (3 * (width + step-x)) start-y + height +(1 * (height + step-y))
+                box-start + 70x100
+            )
+            50
+            (50x80 - 70x100)
+            reflect
+        box (box-start) (box-stop)
 
         
         text ( as-pair start-x start-y + (2 * (height + step-y)) - 20 ) "no stops; scale 2 1"

From 00aee09bf151ab535487f0f29baaae0e4759da4a Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Wed, 8 Jan 2020 15:46:35 +0100
Subject: [PATCH 0714/3432] FEAT: draw on layered window with Direct2D.

---
 modules/view/backends/windows/base.reds     | 57 ++++++++++-----------
 modules/view/backends/windows/direct2d.reds | 46 ++++++++++++++---
 modules/view/backends/windows/draw.reds     | 15 +++++-
 modules/view/backends/windows/text-box.reds |  2 +-
 4 files changed, 78 insertions(+), 42 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index 39d98b6e07..cf0f1b1e58 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -741,6 +741,11 @@ update-base: func [
 		bf		[tagBLENDFUNCTION value]
 		graphic [integer!]
 		flags	[integer!]
+		ctx		[draw-ctx! value]
+		pdc		[com-ptr! value]
+		this	[this!]
+		rt-dc	[ID2D1GdiInteropRenderTarget]
+		hdc		[ptr-value!]
 ][
 	if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [
 		InvalidateRect hWnd null 0
@@ -756,43 +761,33 @@ update-base: func [
 		exit
 	]
 
-	img:	as red-image!  values + FACE_OBJ_IMAGE
-	color:	as red-tuple!  values + FACE_OBJ_COLOR
 	cmds:	as red-block!  values + FACE_OBJ_DRAW
-	text:	as red-string! values + FACE_OBJ_TEXT
-	font:	as red-object! values + FACE_OBJ_FONT
-	para:	as red-object! values + FACE_OBJ_PARA
 	sz:		as red-pair!   values + FACE_OBJ_SIZE
-	graphic: 0
-
 	width: dpi-scale sz/x
 	height: dpi-scale sz/y
-	hBackDC: CreateCompatibleDC hScreen
-	hBitmap: CreateCompatibleBitmap hScreen width height
-	SelectObject hBackDC hBitmap
-	GdipCreateFromHDC hBackDC :graphic
 
-	if TYPE_OF(color) = TYPE_TUPLE [				;-- update background
-		update-base-background graphic color width height
+	system/thrown: 0
+	catch RED_THROWN_ERROR [
+		draw-begin ctx hWnd as red-image! :pdc yes yes
+		if TYPE_OF(cmds) = TYPE_BLOCK [parse-draw ctx cmds yes]
+
+		this: pdc/value
+		rt-dc: as ID2D1GdiInteropRenderTarget this/vtbl
+		rt-dc/GetDC this 0 :hdc
+		ptSrc/x: 0
+		ptSrc/y: 0
+		size: as tagSIZE :width
+		bf/BlendOp: as-byte 0
+		bf/BlendFlags: as-byte 0
+		bf/SourceConstantAlpha: as-byte 255
+		bf/AlphaFormat: as-byte 1
+		flags: 2
+		UpdateLayeredWindow hWnd null ptDst size hdc/value :ptSrc 0 :bf flags
+		rt-dc/ReleaseDC this null
+
+		draw-end ctx hWnd yes no yes
 	]
-	GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS
-	update-base-image graphic img width height
-	update-base-text hWnd graphic hBackDC text font para width height null
-	do-draw null as red-image! graphic cmds yes no no yes
-
-	ptSrc/x: 0
-	ptSrc/y: 0
-	size: as tagSIZE :width
-	bf/BlendOp: as-byte 0
-	bf/BlendFlags: as-byte 0
-	bf/SourceConstantAlpha: as-byte 255
-	bf/AlphaFormat: as-byte 1
-	flags: 2
-	UpdateLayeredWindow hWnd null ptDst size hBackDC :ptSrc 0 :bf flags
-
-	GdipDeleteGraphics graphic
-	DeleteObject hBitmap
-	DeleteDC hBackDC
+	system/thrown: 0
 ]
 
 
diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index dba55697b8..c011cbb711 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -42,6 +42,7 @@ IID_ID2D1Factory1:		 [BB12D362h 4B9ADAEEh BA141DAAh 1FFA1C40h]
 IID_IDWriteFactory:		 [B859EE5Ah 4B5BD838h DC1AE8A2h 48DB937Dh]
 IID_IDXGIFactory2:		 [50C83A1Ch 4C48E072h 3036B087h D0A636FAh]
 IID_IDCompositionDevice: [C37EA93Ah 450DE7AAh 46976FB1h F30704CBh]
+IID_IDGdiInterop: 		 [E0DB51C3h 4BAE6F77h 75E4D5B3h 3858B309h]
 CLSID_D2D1UnPremultiply: [FB9AC489h 41EDAD8Dh 63BB9999h F710D147h]
 
 D2D1_FACTORY_OPTIONS: alias struct! [
@@ -794,7 +795,7 @@ DrawBitmap*: alias function! [
 ]
 
 #define ID2D1RenderTarget [
-	QueryInterface					[QueryInterface!]
+	QueryInterface					[function! [this [this!] riid [int-ptr!] ppvObject [com-ptr!] return: [integer!]]]
 	AddRef							[AddRef!]
 	Release							[Release!]
 	GetFactory						[integer!]
@@ -892,6 +893,14 @@ ID2D1DeviceContext: alias struct! [
     FillOpacityMask2				[integer!]
 ]
 
+ID2D1GdiInteropRenderTarget: alias struct! [
+	QueryInterface					[QueryInterface!]
+	AddRef							[AddRef!]
+	Release							[Release!]
+	GetDC							[function! [this [this!] mode [integer!] hDC [ptr-ptr!] return: [integer!]]]
+	ReleaseDC						[function! [this [this!] update [RECT_STRUCT] return: [integer!]]]
+]
+
 ID2D1HwndRenderTarget: alias struct! [
 	ID2D1RenderTarget
 	CheckWindowState				[function! [this [this!] return: [integer!]]]
@@ -1626,6 +1635,22 @@ create-render-target: func [
 	rt
 ]
 
+create-bitmap-target: func [
+	hWnd		[handle!]
+	rt			[render-target!]
+	/local
+		rc		[RECT_STRUCT value]
+		this	[this!]
+		unk		[IUnknown]
+		d2d		[ID2D1DeviceContext]
+][
+	GetClientRect hWnd :rc
+
+	d2d: as ID2D1DeviceContext d2d-ctx/vtbl	
+	rt/dc: d2d-ctx
+	rt/bitmap: create-d2d-bitmap d2d-ctx rc/right - rc/left rc/bottom - rc/top 9
+]
+
 to-dx-color: func [
 	color	[integer!]
 	clr-ptr [D3DCOLORVALUE]
@@ -1706,15 +1731,20 @@ create-hwnd-render-target: func [
 ]
 
 get-hwnd-render-target: func [
-	hWnd	[handle!]
-	return:	[render-target!]
+	hWnd		[handle!]
+	layered?	[logic!]
+	return:		[render-target!]
 	/local
 		target	[render-target!]
 ][
 	target: as render-target! GetWindowLong hWnd wc-offset - 32
 	if null? target [
 		target: as render-target! alloc0 size? render-target!
-		create-render-target hWnd target
+		either layered? [
+			create-bitmap-target hwnd target
+		][
+			create-render-target hWnd target
+		]
 		target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr!
 		SetWindowLong hWnd wc-offset - 32 as-integer target
 	]
@@ -2039,11 +2069,11 @@ render-target-lost?: func [
 	0 <> rt/EndDraw target null null
 ]
 
-create-bitmap: func [
+create-d2d-bitmap: func [
 	this	[this!]
 	width	[uint32!]
 	height	[uint32!]
-	format	[integer!]
+	options	[integer!]
 	return: [this!]
 	/local
 		dc		[ID2D1DeviceContext]
@@ -2051,11 +2081,11 @@ create-bitmap: func [
 		sz		[SIZE_U! value]
 		bitmap	[ptr-value!]
 ][
-	props/format: format
+	props/format: 87
 	props/alphaMode: 1
 	props/dpiX: dpi-x
 	props/dpiY: dpi-y
-	props/options: 1		;-- D2D1_BITMAP_OPTIONS_TARGET
+	props/options: options
 	props/colorContext: null
 
 	sz/width: width
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 020a58e613..7b99b66347 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -175,6 +175,9 @@ draw-begin: func [
 		bmp		[ptr-value!]
 		wic-bmp	[this!]
 		IUnk	[IUnknown]
+		gdi		[com-ptr! value]
+		pp		[com-ptr!]
+		pdc		[this!]
 ][
 	zero-memory as byte-ptr! ctx size? draw-ctx!
 	ctx/pen-width:	as float32! 1.0
@@ -188,7 +191,7 @@ draw-begin: func [
 	dc: as ID2D1DeviceContext this/vtbl
 
 	either hWnd <> null [
-		target: get-hwnd-render-target hWnd
+		target: get-hwnd-render-target hWnd on-graphic?
 	][
 		wic-bmp: OS-image/to-pbgra img
 		;-- create a bitmap target
@@ -206,11 +209,17 @@ draw-begin: func [
 	ctx/dc: as ptr-ptr! this
 	ctx/target: as int-ptr! target
 
+	dc/BeginDraw this
+	if on-graphic? [
+		dc/QueryInterface this IID_IDGdiInterop :gdi
+		pp: as com-ptr! img
+		pp/value: gdi/value
+	]
+
 	dc/SetTextAntialiasMode this 1				;-- ClearType
 	dc/SetTarget this target/bitmap
 	dc/SetAntialiasMode this 0					;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
 
-	dc/BeginDraw this
 	matrix2d/identity m
 	dc/SetTransform this :m						;-- set to identity matrix
 
@@ -272,6 +281,8 @@ draw-end: func [
 
 	release-ctx ctx		;@@ Possible improvement: cache resources for window target
 
+	if on-graphic? [exit]
+
 	rt: as render-target! ctx/target
 	either hWnd <> null [	;-- window target
 		this: rt/swapchain
diff --git a/modules/view/backends/windows/text-box.reds b/modules/view/backends/windows/text-box.reds
index b4c2877535..b84237964a 100644
--- a/modules/view/backends/windows/text-box.reds
+++ b/modules/view/backends/windows/text-box.reds
@@ -319,7 +319,7 @@ OS-text-box-layout: func [
 			]
 			hWnd: hidden-hwnd
 		]
-		target: get-hwnd-render-target hWnd
+		target: get-hwnd-render-target hWnd no
 	]
 
 	either TYPE_OF(state) = TYPE_BLOCK [

From a3c0c03ef3b0965aff1f88d725de5d6147039e6d Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 8 Jan 2020 17:03:04 +0100
Subject: [PATCH 0715/3432] FEAT: minor lexer code layout refactoring.

---
 environment/routines.red |   2 +-
 runtime/lexer.reds       | 303 ++++++++++++++++-----------------------
 runtime/unicode.reds     |  62 ++++++++
 3 files changed, 183 insertions(+), 184 deletions(-)

diff --git a/environment/routines.red b/environment/routines.red
index 787f7a7b7f..799cb97ee8 100644
--- a/environment/routines.red
+++ b/environment/routines.red
@@ -129,7 +129,7 @@ count-chars: routine [
 	tail: (as byte-ptr! s/offset) + pos/head
 	c: len: 0
 	while [p < tail][
-		p: lexer/decode-utf8-char p :len
+		p: unicode/fast-decode-utf8-char p :len
 		c: c + 1
 	]
 	c
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 0deb74a3ef..7d55d3cf96 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -262,69 +262,6 @@ lexer: context [
 		C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL 		;-- F9-FC
 		C_ILLEGAL C_ILLEGAL C_ILLEGAL			 		;-- FD-FF
 	]
-
-	;; For UTF-8 decoding, uses DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations
-	
-	utf8d: #{
-		0000000000000000000000000000000000000000000000000000000000000000
-		0000000000000000000000000000000000000000000000000000000000000000
-		0000000000000000000000000000000000000000000000000000000000000000
-		0000000000000000000000000000000000000000000000000000000000000000
-		0101010101010101010101010101010109090909090909090909090909090909
-		0707070707070707070707070707070707070707070707070707070707070707
-		0808020202020202020202020202020202020202020202020202020202020202
-		0A0303030303030303030303030403030B060606050808080808080808080808
-		000C18243C60540C0C0C30480C0C0C0C0C0C0C0C0C0C0C0C0C000C0C0C0C0C00
-		0C000C0C0C180C0C0C0C0C180C180C0C0C0C0C0C0C0C0C180C0C0C0C0C180C0C
-		0C0C0C0C0C180C0C0C0C0C0C0C0C0C240C240C0C0C240C0C0C0C0C240C240C0C
-		0C240C0C0C0C0C0C0C0C0C0C 
-	}
-	
-	decode-utf8-char: func [
-		p		[byte-ptr!]
-		cp		[int-ptr!]
-		return: [byte-ptr!]
-		/local
-			state byte idx type [integer!]
-	][
-		state: 0
-		forever [
-			byte: as-integer p/value
-			idx: byte + 1
-			type: as-integer utf8d/idx
-			
-			idx: 256 + state + type + 1
-			state: as-integer utf8d/idx
-			
-			switch state [
-				0 [										;-- ACCEPT
-					cp/value: FFh >> type and byte
-					return p + 1
-				]
-				12 [									;-- REJECT
-					cp/value: -1
-					return p
-				]
-				default [
-					cp/value: byte and 3Fh or (cp/value << 6)
-					p: p + 1
-				]
-			]
-		]
-		as byte-ptr! 0									;-- never reached, just make compiler happy
-	]
-	
-	;-- Count UTF-8 encoded characters between two positions in a binary buffer
-	count-chars: func [s e [byte-ptr!] return: [integer!]
-		/local c len [integer!]
-	][
-		c: len: 0
-		while [s < e][
-			s: lexer/decode-utf8-char s :len
-			c: c + 1
-		]
-		c
-	]
 	
 	#enum errors! [
 		ERR_BAD_CHAR: 	  -1
@@ -398,7 +335,7 @@ lexer: context [
 			]
 		]
 		p: s
-		while [all [p < e p/1 <> #"^/" s + 30 > p]][p: decode-utf8-char p :len]
+		while [all [p < e p/1 <> #"^/" s + 30 > p]][p: unicode/fast-decode-utf8-char p :len]
 		if p > e [p: e]
 		len: as-integer p - s
 		pos: string/load as-c-string s len UTF-8
@@ -460,8 +397,8 @@ lexer: context [
 			datatype/push type
 		]
 		either all [lex/in-series <> null TYPE_OF(lex/in-series) <> TYPE_BINARY][
-			x: count-chars lex/input s
-			y: x + count-chars s e
+			x: unicode/count-chars lex/input s
+			y: x + unicode/count-chars s e
 		][
 			x: as-integer s - lex/input
 			y: as-integer e - lex/input
@@ -922,6 +859,118 @@ lexer: context [
 		lex/in-pos: e + 1								;-- skip )
 	]
 
+	scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		if zero? lex/mstr-nest [lex/mstr-s: s]
+		lex/mstr-nest: lex/mstr-nest + 1
+		lex/mstr-flags: lex/mstr-flags or flags
+		lex/entry: S_M_STRING
+		lex/in-pos: e + 1								;-- skip {
+		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e]
+	]
+	
+	scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		lex/mstr-nest: lex/mstr-nest - 1
+
+		either zero? lex/mstr-nest [
+			if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e]
+			scan-string lex lex/mstr-s e lex/mstr-flags or flags
+			lex/mstr-s: null
+			lex/mstr-flags: 0
+			lex/entry: S_START
+			lex/in-pos: e + 1								;-- skip }
+			
+			if lex/fun-ptr <> null [
+				unless fire-event lex words/_load TYPE_STRING lex/tail - 1 s lex/in-pos [lex/tail: lex/tail - 1]
+			]
+		][
+			if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING]
+			lex/in-pos: e + 1								;-- skip }
+		]
+	]
+	
+	scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		open-block lex TYPE_PAREN TYPE_MAP null
+		lex/in-pos: e + 1								;-- skip (
+	]
+	
+	scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!]
+		/local
+			pos  [byte-ptr!]
+			type [integer!]
+	][
+		pos: s
+		type: switch s/1 [
+			#"'" [s: s + 1 flags: flags and not C_FLAG_QUOTE TYPE_LIT_PATH]
+			#":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH]
+			default [TYPE_PATH]
+		]
+		open-block lex type -1 pos						;-- open a new path series
+		scan-word lex s e flags							;-- load the head word
+		lex/entry: S_PATH								;-- overwrites the S_START set by open-block
+		lex/in-pos: e + 1								;-- skip /
+	]
+
+	scan-path-item: func [lex [state!] s e [byte-ptr!] flags [integer!]
+		/local
+			type	[integer!]
+			cp		[integer!]
+			index	[integer!]
+			close?	[logic!]
+	][
+		close?: either e >= lex/in-end [yes][			;-- EOF reached
+			cp: as-integer e/1
+			index: lex-classes/cp and FFh + 1			;-- query the class of ending character
+			as-logic path-ending/index					;-- lookup if the character class is ending path
+		]
+
+		either close? [
+			type: either all [e < lex/in-end e/1 = #":"][
+				if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence
+					throw-error lex null e TYPE_PATH
+				]
+				lex/in-pos: e + 1						;-- skip :
+				TYPE_SET_PATH
+			][-1]
+			close-block lex s e -1 type
+		][
+			if e + 1 = lex/in-end [throw-error lex null e TYPE_PATH] ;-- incomplete path error
+			if e/1 = #":" [throw-error lex null e TYPE_PATH] ;-- set-words not allowed inside paths
+			lex/in-pos: e + 1							;-- skip /
+		]
+	]
+			
+	scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		if lex/fun-ptr <> null [fire-event lex words/_open T_CMT - --EXIT_STATES-- null s e]
+	]
+
+	scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!]
+		/local
+			dt		[red-datatype!]
+			len		[integer!]
+			p dtypes end [int-ptr!]
+	][
+		s: s + 2										;-- skip #[
+		p: cons-syntax
+		dtypes: p + (3 * 2)
+		end: p + size? cons-syntax						;-- point to end of array
+		loop 4 [
+			if zero? platform/strnicmp s as byte-ptr! p/1 p/2 [break]
+			p: p + 3
+		]
+		if p = end [throw-error lex s e ERR_MALCONSTRUCT] ;-- no match, error case
+		len: p/2 + 1
+		if s/len <> #"]" [throw-error lex s e ERR_MALCONSTRUCT]
+
+		dt: as red-datatype! alloc-slot lex
+		either p < dtypes [
+			set-type as cell! dt TYPE_LOGIC
+			dt/value: p/3
+		][
+			set-type as cell! dt p/3
+		]
+		lex/in-pos: e + 1								;-- skip ]
+	]
+	
 	scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
 			len unit index class digits extra cp type [integer!]
@@ -947,7 +996,7 @@ lexer: context [
 					cp: -1
 					p: as byte-ptr! ser/offset
 					while [s < e][
-						s: decode-utf8-char s :cp
+						s: unicode/fast-decode-utf8-char s :cp
 						if cp = -1 [throw-error lex s e type]
 						p/1: as-byte cp and FFh
 						p/2: as-byte cp >> 8
@@ -958,7 +1007,7 @@ lexer: context [
 					cp: -1
 					p4: as int-ptr! ser/offset
 					while [s < e][
-						s: decode-utf8-char s :cp
+						s: unicode/fast-decode-utf8-char s :cp
 						if cp = -1 [throw-error lex s e type]
 						p4/value: cp
 						p4: p4 + 1
@@ -1008,7 +1057,7 @@ lexer: context [
 				]
 			]
 			esc: either flags and C_FLAG_ESC_HEX = 0 [#"^^"][#"%"]
-			
+
 			str: string/make-at alloc-slot lex len - extra unit
 			ser: GET_BUFFER(str)
 			switch unit [
@@ -1042,7 +1091,7 @@ lexer: context [
 								scan-percent-char s + 1 e :cp
 							]
 						][
-							decode-utf8-char s :cp
+							unicode/fast-decode-utf8-char s :cp
 						]
 						if cp = -1 [throw-error lex s e type]
 						p/1: as-byte cp and FFh
@@ -1062,7 +1111,7 @@ lexer: context [
 								scan-percent-char s + 1 e :cp
 							]
 						][
-							decode-utf8-char s :cp
+							unicode/fast-decode-utf8-char s :cp
 						]
 						if cp = -1 [throw-error lex s e type]
 						p4/value: cp
@@ -1076,35 +1125,6 @@ lexer: context [
 		if type <> TYPE_STRING [set-type as cell! str type]
 		lex/in-pos: e + 1								;-- skip ending delimiter
 	]
-
-	scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		if zero? lex/mstr-nest [lex/mstr-s: s]
-		lex/mstr-nest: lex/mstr-nest + 1
-		lex/mstr-flags: lex/mstr-flags or flags
-		lex/entry: S_M_STRING
-		lex/in-pos: e + 1								;-- skip {
-		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e]
-	]
-	
-	scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		lex/mstr-nest: lex/mstr-nest - 1
-
-		either zero? lex/mstr-nest [
-			if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e]
-			scan-string lex lex/mstr-s e lex/mstr-flags or flags
-			lex/mstr-s: null
-			lex/mstr-flags: 0
-			lex/entry: S_START
-			lex/in-pos: e + 1								;-- skip }
-			
-			if lex/fun-ptr <> null [
-				unless fire-event lex words/_load TYPE_STRING lex/tail - 1 s lex/in-pos [lex/tail: lex/tail - 1]
-			]
-		][
-			if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING]
-			lex/in-pos: e + 1								;-- skip }
-		]
-	]
 	
 	scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
@@ -1232,39 +1252,6 @@ lexer: context [
 		lex/in-pos: e + 1								;-- skip "
 	]
 	
-	scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		open-block lex TYPE_PAREN TYPE_MAP null
-		lex/in-pos: e + 1								;-- skip (
-	]
-	
-	scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!]
-		/local
-			dt		[red-datatype!]
-			len		[integer!]
-			p dtypes end [int-ptr!]
-	][
-		s: s + 2										;-- skip #[
-		p: cons-syntax
-		dtypes: p + (3 * 2)
-		end: p + size? cons-syntax						;-- point to end of array
-		loop 4 [
-			if zero? platform/strnicmp s as byte-ptr! p/1 p/2 [break]
-			p: p + 3
-		]
-		if p = end [throw-error lex s e ERR_MALCONSTRUCT] ;-- no match, error case
-		len: p/2 + 1
-		if s/len <> #"]" [throw-error lex s e ERR_MALCONSTRUCT]
-		
-		dt: as red-datatype! alloc-slot lex
-		either p < dtypes [
-			set-type as cell! dt TYPE_LOGIC
-			dt/value: p/3
-		][
-			set-type as cell! dt p/3
-		]
-		lex/in-pos: e + 1								;-- skip ]
-	]
-	
 	scan-ref-issue: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
 			cell [cell!]
@@ -1696,23 +1683,6 @@ lexer: context [
 		lex/in-pos: e 									;-- reset the input position to delimiter byte
 	]
 	
-	scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!]
-		/local
-			pos  [byte-ptr!]
-			type [integer!]
-	][
-		pos: s
-		type: switch s/1 [
-			#"'" [s: s + 1 flags: flags and not C_FLAG_QUOTE TYPE_LIT_PATH]
-			#":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH]
-			default [TYPE_PATH]
-		]
-		open-block lex type -1 pos						;-- open a new path series
-		scan-word lex s e flags							;-- load the head word
-		lex/entry: S_PATH								;-- overwrites the S_START set by open-block
-		lex/in-pos: e + 1								;-- skip /
-	]
-	
 	scan-hex: func [lex [state!] s e [byte-ptr!] flags [integer!]
 		/local
 			int		[red-integer!]
@@ -1739,39 +1709,6 @@ lexer: context [
 		int/value: i
 		lex/in-pos: e + 1								;-- skip h
 	]
-	
-	scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		if lex/fun-ptr <> null [fire-event lex words/_open T_CMT - --EXIT_STATES-- null s e]
-	]
-	
-	scan-path-item: func [lex [state!] s e [byte-ptr!] flags [integer!]
-		/local
-			type	[integer!]
-			cp		[integer!]
-			index	[integer!]
-			close?	[logic!]
-	][
-		close?: either e >= lex/in-end [yes][			;-- EOF reached
-			cp: as-integer e/1
-			index: lex-classes/cp and FFh + 1			;-- query the class of ending character
-			as-logic path-ending/index					;-- lookup if the character class is ending path
-		]
-		
-		either close? [
-			type: either all [e < lex/in-end e/1 = #":"][
-				if all [e + 1 < lex/in-end e/2 = #"/"][ ;-- detect :/ illegal sequence
-					throw-error lex null e TYPE_PATH
-				]
-				lex/in-pos: e + 1						;-- skip :
-				TYPE_SET_PATH
-			][-1]
-			close-block lex s e -1 type
-		][
-			if e + 1 = lex/in-end [throw-error lex null e TYPE_PATH] ;-- incomplete path error
-			if e/1 = #":" [throw-error lex null e TYPE_PATH] ;-- set-words not allowed inside paths
-			lex/in-pos: e + 1							;-- skip /
-		]
-	]
 
 	scan-tokens: func [
 		lex  [state!]
diff --git a/runtime/unicode.reds b/runtime/unicode.reds
index 139b03446f..115fa397c3 100644
--- a/runtime/unicode.reds
+++ b/runtime/unicode.reds
@@ -23,6 +23,68 @@ unicode: context [
 	;	3Fh				; U+003F = question mark
 	;	BFh				; U+00BF = inverted question mark
 	;	DC00h + b1		; U+DCxx where xx = b1 (never a Unicode codepoint)
+	
+	;; DFA algorithm: http://bjoern.hoehrmann.de/utf-8/decoder/dfa/#variations
+	utf8d: #{
+		0000000000000000000000000000000000000000000000000000000000000000
+		0000000000000000000000000000000000000000000000000000000000000000
+		0000000000000000000000000000000000000000000000000000000000000000
+		0000000000000000000000000000000000000000000000000000000000000000
+		0101010101010101010101010101010109090909090909090909090909090909
+		0707070707070707070707070707070707070707070707070707070707070707
+		0808020202020202020202020202020202020202020202020202020202020202
+		0A0303030303030303030303030403030B060606050808080808080808080808
+		000C18243C60540C0C0C30480C0C0C0C0C0C0C0C0C0C0C0C0C000C0C0C0C0C00
+		0C000C0C0C180C0C0C0C0C180C180C0C0C0C0C0C0C0C0C180C0C0C0C0C180C0C
+		0C0C0C0C0C180C0C0C0C0C0C0C0C0C240C240C0C0C240C0C0C0C0C240C240C0C
+		0C240C0C0C0C0C0C0C0C0C0C 
+	}
+
+	fast-decode-utf8-char: func [
+		p		[byte-ptr!]
+		cp		[int-ptr!]
+		return: [byte-ptr!]
+		/local
+			state byte idx type [integer!]
+	][
+		state: 0
+		forever [
+			byte: as-integer p/value
+			idx: byte + 1
+			type: as-integer utf8d/idx
+
+			idx: 256 + state + type + 1
+			state: as-integer utf8d/idx
+
+			switch state [
+				0 [										;-- ACCEPT
+					cp/value: FFh >> type and byte
+					return p + 1
+				]
+				12 [									;-- REJECT
+					cp/value: -1
+					return p
+				]
+				default [
+					cp/value: byte and 3Fh or (cp/value << 6)
+					p: p + 1
+				]
+			]
+		]
+		as byte-ptr! 0									;-- never reached, just make compiler happy
+	]
+
+	;-- Count UTF-8 encoded characters between two positions in a binary buffer
+	count-chars: func [s e [byte-ptr!] return: [integer!]
+		/local c len [integer!]
+	][
+		c: len: 0
+		while [s < e][
+			s: fast-decode-utf8-char s :len
+			c: c + 1
+		]
+		c
+	]
 
 	latin1-idx: [
 		0402h 0403h 201Ah 0453h 201Eh 2026h 2020h 2021h

From b6a2fb0455e9f56bcdfce9d0dac6f8bedd4eb91e Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Wed, 8 Jan 2020 17:12:20 +0100
Subject: [PATCH 0716/3432] FEAT: draw image facets in base face.

---
 modules/view/backends/windows/base.reds | 66 +++++++++++++++++--------
 modules/view/backends/windows/draw.reds | 15 +++++-
 2 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index cf0f1b1e58..00ae5187cd 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -765,29 +765,53 @@ update-base: func [
 	sz:		as red-pair!   values + FACE_OBJ_SIZE
 	width: dpi-scale sz/x
 	height: dpi-scale sz/y
+	ptSrc/x: 0
+	ptSrc/y: 0
+	size: as tagSIZE :width
+	bf/BlendOp: as-byte 0
+	bf/BlendFlags: as-byte 0
+	bf/SourceConstantAlpha: as-byte 255
+	bf/AlphaFormat: as-byte 1
+	flags: 2
+
+	either TYPE_OF(cmds) = TYPE_BLOCK [
+		system/thrown: 0
+		catch RED_THROWN_ERROR [
+			draw-begin ctx hWnd as red-image! :pdc yes yes
+			parse-draw ctx cmds yes
+
+			this: pdc/value
+			rt-dc: as ID2D1GdiInteropRenderTarget this/vtbl
+			rt-dc/GetDC this 0 :hdc
+			UpdateLayeredWindow hWnd null ptDst size hdc/value :ptSrc 0 :bf flags
+			rt-dc/ReleaseDC this null
+
+			draw-end ctx hWnd yes no yes
+		]
+		system/thrown: 0
+	][
+		img:	as red-image!  values + FACE_OBJ_IMAGE
+		color:	as red-tuple!  values + FACE_OBJ_COLOR
+		text:	as red-string! values + FACE_OBJ_TEXT
+		font:	as red-object! values + FACE_OBJ_FONT
+		para:	as red-object! values + FACE_OBJ_PARA
+		graphic: 0
+		hBackDC: CreateCompatibleDC hScreen
+		hBitmap: CreateCompatibleBitmap hScreen width height
+		SelectObject hBackDC hBitmap
+		GdipCreateFromHDC hBackDC :graphic
 
-	system/thrown: 0
-	catch RED_THROWN_ERROR [
-		draw-begin ctx hWnd as red-image! :pdc yes yes
-		if TYPE_OF(cmds) = TYPE_BLOCK [parse-draw ctx cmds yes]
-
-		this: pdc/value
-		rt-dc: as ID2D1GdiInteropRenderTarget this/vtbl
-		rt-dc/GetDC this 0 :hdc
-		ptSrc/x: 0
-		ptSrc/y: 0
-		size: as tagSIZE :width
-		bf/BlendOp: as-byte 0
-		bf/BlendFlags: as-byte 0
-		bf/SourceConstantAlpha: as-byte 255
-		bf/AlphaFormat: as-byte 1
-		flags: 2
-		UpdateLayeredWindow hWnd null ptDst size hdc/value :ptSrc 0 :bf flags
-		rt-dc/ReleaseDC this null
-
-		draw-end ctx hWnd yes no yes
+		if TYPE_OF(color) = TYPE_TUPLE [		;-- update background
+			update-base-background graphic color width height
+		]
+		GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS
+		update-base-image graphic img width height
+		update-base-text hWnd graphic hBackDC text font para width height null
+		UpdateLayeredWindow hWnd null ptDst size hBackDC :ptSrc 0 :bf flags
+		GdipDeleteGraphics graphic
+		DeleteObject hBitmap
+		DeleteDC hBackDC
 	]
-	system/thrown: 0
 ]
 
 
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 7b99b66347..271bb3bf94 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -171,7 +171,9 @@ draw-begin: func [
 		values	[red-value!]
 		clr		[red-tuple!]
 		text	[red-string!]
+		red-img [red-image!]
 		pos		[red-pair! value]
+		pos2	[red-pair!]
 		bmp		[ptr-value!]
 		wic-bmp	[this!]
 		IUnk	[IUnknown]
@@ -242,10 +244,16 @@ draw-begin: func [
 			dc/Clear this to-dx-color bg-clr null
 		]
 
+		red-img: as red-image! values + FACE_OBJ_IMAGE
+		if TYPE_OF(red-img) = TYPE_IMAGE [
+			pos2: as red-pair! values + FACE_OBJ_SIZE
+			OS-draw-image ctx red-img null pos2 null no null null
+		]
+
 		text: as red-string! values + FACE_OBJ_TEXT
 		if TYPE_OF(text) = TYPE_STRING [
 			pos/x: 0 pos/y: 0
-			OS-draw-text ctx pos as red-string! get-face-obj hWnd yes
+			OS-draw-text ctx :pos as red-string! get-face-obj hWnd yes
 		]
 	]
 	ctx
@@ -1522,7 +1530,10 @@ OS-draw-image: func [
 			dst*/bottom: as float32! y + height
 			dst: :dst*
 		]
-		start + 1 = end [					;-- two control points
+		any [					;-- two control points
+			start + 1 = end
+			all [null? start end <> null]
+		][
 			dst*/left: as float32! x
 			dst*/top: as float32! y
 			dst*/right: as float32! end/x

From a0566d25dcf11492971f325b36a4167bd981fd30 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 12 Dec 2019 17:26:32 +0100
Subject: [PATCH 0717/3432] FEAT: preliminary support for calendar widget

---
 modules/view/backends/platform.red         | 1 +
 modules/view/backends/windows/classes.reds | 2 ++
 modules/view/backends/windows/gui.reds     | 3 +++
 modules/view/backends/windows/win32.reds   | 4 ++++
 modules/view/styles.red                    | 5 ++++-
 5 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red
index d25e2bd806..9bd18cae5c 100644
--- a/modules/view/backends/platform.red
+++ b/modules/view/backends/platform.red
@@ -246,6 +246,7 @@ system/view/platform: context [
 			caret:			symbol/make "caret"
 			scroller:		symbol/make "scroller"
 			rich-text:		symbol/make "rich-text"
+			calendar:		symbol/make "calendar"
 
 			---:			symbol/make "---"
 			done:			symbol/make "done"
diff --git a/modules/view/backends/windows/classes.reds b/modules/view/backends/windows/classes.reds
index 4f3414cee0..9e46ad6921 100644
--- a/modules/view/backends/windows/classes.reds
+++ b/modules/view/backends/windows/classes.reds
@@ -234,6 +234,7 @@ register-classes: func [
 	make-super-class #u16 "RedSlider"	#u16 "msctls_trackbar32" 0 yes
 	make-super-class #u16 "RedScroller"	#u16 "SCROLLBAR"		 0 yes
 	make-super-class #u16 "RedTabpanel"	#u16 "SysTabControl32"	 0 yes
+	make-super-class #u16 "RedCalendar" #u16 "SysMonthCal32"     0 yes
 
 	OldFaceWndProc: make-super-class
 		#u16 "RedFace"
@@ -266,5 +267,6 @@ unregister-classes: func [
 	UnregisterClass #u16 "RedPanel"			hInstance
 	UnregisterClass #u16 "RedFace"			hInstance
 	UnregisterClass #u16 "RedArea"			hInstance
+	UnregisterClass #u16 "RedCalendar"      hInstance
 	;@@ unregister custom classes too!
 ]
\ No newline at end of file
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 0c16a7362d..d2a045f76a 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1444,6 +1444,9 @@ OS-make-view: func [
 		sym = camera [
 			class: #u16 "RedCamera"
 		]
+		sym = calendar [
+			class: #u16 "RedCalendar"
+		]
 		sym = window [
 			class: #u16 "RedWindow"
 			flags: WS_CAPTION or WS_CLIPCHILDREN
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index a413dabc22..7628e4c666 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,6 +142,10 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
+#define MCN_SELECT			1000h
+#define MCM_GETCURSEL       1001h
+#define MCM_SETCURSEL		1002h
+
 #define TCIF_TEXT			0001h
 
 #define MIIM_STATE			0001h
diff --git a/modules/view/styles.red b/modules/view/styles.red
index 67677a5c99..3b89fc38c3 100644
--- a/modules/view/styles.red
+++ b/modules/view/styles.red
@@ -119,5 +119,8 @@ Red [
 		template: [type: 'base size: 100x100]
 		init: [unless face/image [face/image: make image! face/size]]
 	]
-
+	calendar: [
+		default-actor: on-select
+		template: [type: 'calendar size: 206x167]
+	]
 )
\ No newline at end of file

From 1a5759e501f7dcf5621d54699adaaee3502e0383 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 12 Dec 2019 17:55:48 +0100
Subject: [PATCH 0718/3432] FIX: incorrect commctrl macro definitions

---
 modules/view/backends/windows/win32.reds | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 7628e4c666..43ac3985aa 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,7 +142,8 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
-#define MCN_SELECT			1000h
+#define MCN_SELECT			FFFFFD16h
+
 #define MCM_GETCURSEL       1001h
 #define MCM_SETCURSEL		1002h
 

From acae798071c0d97583230fdd12990409f804264d Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 13 Dec 2019 18:13:57 +0100
Subject: [PATCH 0719/3432] FEAT: MAKE-AT constructor for DATE! value

---
 runtime/datatypes/date.reds | 40 +++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds
index 803e6bbf73..cb447ddb79 100644
--- a/runtime/datatypes/date.reds
+++ b/runtime/datatypes/date.reds
@@ -481,6 +481,46 @@ date: context [
 		]
 	]
 
+	make-at: func [
+		slot	[red-value!]
+		year	[integer!]
+		month	[integer!]
+		day		[integer!]
+		tm		[float!]
+		TZ-h	[integer!]
+		TZ-m	[integer!]
+		time?	[logic!]
+		TZ? 	[logic!]
+		return: [red-date!]
+		/local
+			dt	 [red-date!]
+			d	 [integer!]
+			z	 [integer!]
+			-TZ? [logic!]
+	][
+		dt: as red-date! slot
+		d: 0
+		d: DATE_SET_YEAR(d year)
+		d: DATE_SET_MONTH(d month)
+		d: DATE_SET_DAY(d day)
+		d: DATE_SET_TIME_FLAG(d)
+		set-type as red-value! dt TYPE_DATE				;-- preserve eventual flags in the header
+		dt/date: d
+		
+		-TZ?: no
+		if tz-h < 0 [-TZ?: yes tz-h: 0 - tz-h]
+		z: tz-h << 2 and 7Fh or (tz-m / 15)
+		if -TZ? [z: DATE_SET_ZONE_NEG(z)]
+		dt/date: DATE_SET_ZONE(dt/date z)
+		either time? [
+			dt/time: to-utc-time tm DATE_GET_ZONE(dt/date)
+		][
+			dt/date: DATE_CLEAR_TIME_FLAG(dt/date)
+			dt/time: 0.0
+		]
+		dt
+	]
+
 	set-all: func[
 		dt     [red-date!]
 		year   [integer!]

From 2997a26c0ae665f92f9b4b44409dc858dd951f8a Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 13 Dec 2019 18:15:39 +0100
Subject: [PATCH 0720/3432] FEAT: extra styles for calendar widget

---
 modules/view/backends/windows/gui.reds   | 1 +
 modules/view/backends/windows/win32.reds | 3 +++
 modules/view/styles.red                  | 4 ++--
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index d2a045f76a..7ff3783272 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1446,6 +1446,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
+			flags: flags or MCS_NOTODAY or MCS_NOTODAYCIRCLE
 		]
 		sym = window [
 			class: #u16 "RedWindow"
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 43ac3985aa..f6f5a50a3d 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,6 +142,9 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
+#define MCS_NOTODAYCIRCLE	08h
+#define MCS_NOTODAY			10h
+
 #define MCN_SELECT			FFFFFD16h
 
 #define MCM_GETCURSEL       1001h
diff --git a/modules/view/styles.red b/modules/view/styles.red
index 3b89fc38c3..f94945ba6a 100644
--- a/modules/view/styles.red
+++ b/modules/view/styles.red
@@ -120,7 +120,7 @@ Red [
 		init: [unless face/image [face/image: make image! face/size]]
 	]
 	calendar: [
-		default-actor: on-select
-		template: [type: 'calendar size: 206x167]
+		default-actor: on-change
+		template: [type: 'calendar size: 206x149]
 	]
 )
\ No newline at end of file

From 14bcc8241c698f846ff87a9d7416d44fcee786a1 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 13 Dec 2019 18:16:31 +0100
Subject: [PATCH 0721/3432] FEAT: minimal two-way binding for calendar widget

---
 modules/view/backends/windows/calendar.reds | 64 +++++++++++++++++++++
 modules/view/backends/windows/events.reds   |  1 +
 modules/view/backends/windows/gui.reds      |  4 ++
 3 files changed, 69 insertions(+)
 create mode 100644 modules/view/backends/windows/calendar.reds

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
new file mode 100644
index 0000000000..51da08e243
--- /dev/null
+++ b/modules/view/backends/windows/calendar.reds
@@ -0,0 +1,64 @@
+Red/System [
+	Title:	"Windows calendar widget"
+	Author: "Vladimir Vasilyev"
+	File: 	%calendar.reds
+	Tabs: 	4
+	Rights: "Copyright (C) 2019 Red Foundation. All rights reserved."
+	License: {
+		Distributed under the Boost Software License, Version 1.0.
+		See https://github.com/red/red/blob/master/BSL-License.txt
+	}
+]
+
+with [platform][
+	calendar-change: func [
+		hWnd [handle!]
+		date [red-date!]
+		/local
+			st [tagSYSTEMTIME]
+	][
+		st: declare tagSYSTEMTIME		
+		st/year-month: get-year-month date/date
+		st/week-day: get-day date/date
+
+		SendMessage hWnd MCM_SETCURSEL 0 as integer! st
+	]
+
+	process-calendar-change: func [
+		hWnd [handle!]
+		/local
+			slot  [red-value!]
+			st    [tagSYSTEMTIME]
+			year  [integer!]
+			month [integer!]
+			day   [integer!]
+	][
+		st: declare tagSYSTEMTIME
+		SendMessage hWnd MCM_GETCURSEL 0 as integer! st
+		
+		year:  cap WIN32_LOWORD(st/year-month) 			;-- possible overflow: Win32 1601:30827, Red -16384:16383
+		month: WIN32_HIWORD(st/year-month)
+		day:   WIN32_HIWORD(st/week-day)
+		
+		current-msg/hWnd: hWnd
+		
+		slot: get-facet current-msg FACE_OBJ_DATA
+		date/make-at slot year month day 0.0 0 0 no no
+		
+		make-event current-msg 0 EVT_CHANGE
+	]
+	
+	get-year-month: func [date [integer!] return: [integer!]][
+		return DATE_GET_MONTH(date) << 16 or cap DATE_GET_YEAR(date)
+	]
+	
+	get-day: func [date [integer!] return: [integer!]][
+		return DATE_GET_DAY(date) << 16 and FFFF0000h
+	]
+	
+	cap: func [year [integer!] return: [integer!]][
+		if year < 1601  [year: 1601]
+		if year > 16383 [year: 16383]
+		return year
+	]
+]
\ No newline at end of file
diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds
index ebbf78bf1e..1692c7a531 100644
--- a/modules/view/backends/windows/events.reds
+++ b/modules/view/backends/windows/events.reds
@@ -1225,6 +1225,7 @@ WndProc: func [
 			switch nmhdr/code [
 				TCN_SELCHANGING [return process-tab-select nmhdr/hWndFrom]
 				TCN_SELCHANGE	[process-tab-change nmhdr/hWndFrom]
+				MCN_SELECT      [process-calendar-change nmhdr/hWndFrom]
 				NM_CUSTOMDRAW	[
 					res: process-custom-draw wParam lParam
 					if res <> 0 [return res]
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 7ff3783272..36b07c451a 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -46,6 +46,7 @@ Red/System [
 #include %tab-panel.reds
 #include %text-list.reds
 #include %button.reds
+#include %calendar.reds
 #include %draw-d2d.reds
 #include %draw.reds
 #include %comdlgs.reds
@@ -2119,6 +2120,9 @@ change-data: func [
 		type = tab-panel [
 			set-tabs hWnd get-face-values hWnd
 		]
+		all [type = calendar TYPE_OF(data) = TYPE_DATE][
+			calendar-change hWnd as red-date! data
+		]
 		type = text-list [
 			if TYPE_OF(data) = TYPE_BLOCK [
 				init-text-list 

From 70673d1e19e030953f006e1e4e0cad19b32a82cb Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 13 Dec 2019 19:42:40 +0100
Subject: [PATCH 0722/3432] FIX: better naming

---
 modules/view/backends/windows/calendar.reds | 2 +-
 modules/view/backends/windows/gui.reds      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 51da08e243..ab35b8b4c4 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -11,7 +11,7 @@ Red/System [
 ]
 
 with [platform][
-	calendar-change: func [
+	change-calendar: func [
 		hWnd [handle!]
 		date [red-date!]
 		/local
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 36b07c451a..93c425da24 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -2121,7 +2121,7 @@ change-data: func [
 			set-tabs hWnd get-face-values hWnd
 		]
 		all [type = calendar TYPE_OF(data) = TYPE_DATE][
-			calendar-change hWnd as red-date! data
+			change-calendar hWnd as red-date! data
 		]
 		type = text-list [
 			if TYPE_OF(data) = TYPE_BLOCK [

From 96ff94d750d882df5cbed3afb4f23508bdac73e8 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 13 Dec 2019 20:05:55 +0100
Subject: [PATCH 0723/3432] FIX: add face post-processing

---
 modules/view/backends/windows/gui.reds | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 93c425da24..7f86e50f63 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1625,6 +1625,11 @@ OS-make-view: func [
 			init-base-face handle parent values alpha?
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
+		sym = calendar [
+			if TYPE_OF(data) = TYPE_DATE [
+				change-calendar handle as red-date! data
+			]
+		]
 		sym = window [
 			init-window handle
 			SetWindowLong handle wc-offset - 20 as-integer focused

From cb754db0da0d0001c749c69ae92ff6c4e422fad8 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sat, 14 Dec 2019 11:41:59 +0100
Subject: [PATCH 0724/3432] FIX: better naming

---
 modules/view/backends/windows/calendar.reds | 30 ++++++++++-----------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index ab35b8b4c4..26b264b982 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -12,35 +12,35 @@ Red/System [
 
 with [platform][
 	change-calendar: func [
-		hWnd [handle!]
-		date [red-date!]
+		handle [handle!]
+		date   [red-date!]
 		/local
-			st [tagSYSTEMTIME]
+			time [tagSYSTEMTIME]
 	][
-		st: declare tagSYSTEMTIME		
-		st/year-month: get-year-month date/date
-		st/week-day: get-day date/date
+		time: declare tagSYSTEMTIME		
+		time/year-month: get-year-month date/date
+		time/week-day: get-day date/date
 
-		SendMessage hWnd MCM_SETCURSEL 0 as integer! st
+		SendMessage handle MCM_SETCURSEL 0 as integer! time
 	]
 
 	process-calendar-change: func [
-		hWnd [handle!]
+		handle [handle!]
 		/local
 			slot  [red-value!]
-			st    [tagSYSTEMTIME]
+			time  [tagSYSTEMTIME]
 			year  [integer!]
 			month [integer!]
 			day   [integer!]
 	][
-		st: declare tagSYSTEMTIME
-		SendMessage hWnd MCM_GETCURSEL 0 as integer! st
+		time: declare tagSYSTEMTIME
+		SendMessage handle MCM_GETCURSEL 0 as integer! time
 		
-		year:  cap WIN32_LOWORD(st/year-month) 			;-- possible overflow: Win32 1601:30827, Red -16384:16383
-		month: WIN32_HIWORD(st/year-month)
-		day:   WIN32_HIWORD(st/week-day)
+		year:  cap WIN32_LOWORD(time/year-month) 			;-- possible overflow: Win32 1601:30827, Red -16384:16383
+		month: WIN32_HIWORD(time/year-month)
+		day:   WIN32_HIWORD(time/week-day)
 		
-		current-msg/hWnd: hWnd
+		current-msg/hWnd: handle
 		
 		slot: get-facet current-msg FACE_OBJ_DATA
 		date/make-at slot year month day 0.0 0 0 no no

From da56335b39aa9ad817906df590581c09d7eb4e46 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sat, 14 Dec 2019 11:42:59 +0100
Subject: [PATCH 0725/3432] FEAT: define some calendar-related imports

---
 modules/view/backends/windows/win32.reds | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index f6f5a50a3d..1c8774c05d 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,9 +142,12 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
+
 #define MCS_NOTODAYCIRCLE	08h
 #define MCS_NOTODAY			10h
+#define MCS_NOSELCHANGEONNAV 0100h
 
+#define MCN_SELCHANGE		FFFFFD13h
 #define MCN_SELECT			FFFFFD16h
 
 #define MCM_GETCURSEL       1001h

From 744bb70650211d322fa9dd502c418b38e71a81f8 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sat, 14 Dec 2019 11:44:10 +0100
Subject: [PATCH 0726/3432] FIX: don't change selection in month navigation

---
 modules/view/backends/windows/gui.reds | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 7f86e50f63..012c1750a4 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1447,7 +1447,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
-			flags: flags or MCS_NOTODAY or MCS_NOTODAYCIRCLE
+			flags: flags or MCS_NOTODAY or MCS_NOTODAYCIRCLE or MCS_NOSELCHANGEONNAV
 		]
 		sym = window [
 			class: #u16 "RedWindow"

From b7eea16635c9e12c8ca6f97938bab4c0731d3cb6 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sat, 14 Dec 2019 11:45:03 +0100
Subject: [PATCH 0727/3432] FIX: use MCN_SELCHANGE notification instead

---
 modules/view/backends/windows/events.reds | 2 +-
 modules/view/backends/windows/win32.reds  | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds
index 1692c7a531..08bcd7bb54 100644
--- a/modules/view/backends/windows/events.reds
+++ b/modules/view/backends/windows/events.reds
@@ -1225,7 +1225,7 @@ WndProc: func [
 			switch nmhdr/code [
 				TCN_SELCHANGING [return process-tab-select nmhdr/hWndFrom]
 				TCN_SELCHANGE	[process-tab-change nmhdr/hWndFrom]
-				MCN_SELECT      [process-calendar-change nmhdr/hWndFrom]
+				MCN_SELCHANGE	[process-calendar-change nmhdr/hWndFrom]
 				NM_CUSTOMDRAW	[
 					res: process-custom-draw wParam lParam
 					if res <> 0 [return res]
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 1c8774c05d..fd2e0c75cb 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -148,7 +148,6 @@ Red/System [
 #define MCS_NOSELCHANGEONNAV 0100h
 
 #define MCN_SELCHANGE		FFFFFD13h
-#define MCN_SELECT			FFFFFD16h
 
 #define MCM_GETCURSEL       1001h
 #define MCM_SETCURSEL		1002h

From cd872957ccf7eb2f1a5eb212567604c8bfcbb4bd Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sat, 14 Dec 2019 15:59:00 +0100
Subject: [PATCH 0728/3432] FIX: minor typo in macro name

---
 environment/console/GUI/old/windows.reds  | 2 +-
 modules/view/backends/windows/events.reds | 2 +-
 modules/view/backends/windows/win32.reds  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/environment/console/GUI/old/windows.reds b/environment/console/GUI/old/windows.reds
index 9848b5f5ec..b517e1fafd 100644
--- a/environment/console/GUI/old/windows.reds
+++ b/environment/console/GUI/old/windows.reds
@@ -471,7 +471,7 @@ ConsoleWndProc: func [
 			unless zero? delta [scroll vt delta]
 			return 0
 		]
-		WM_MOUSEWHELL [
+		WM_MOUSEWHEEL [
 			delta: either WIN32_HIWORD(wParam) > 0 [-3][3]
 			scroll vt delta
 			return 0
diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds
index 08bcd7bb54..855815c419 100644
--- a/modules/view/backends/windows/events.reds
+++ b/modules/view/backends/windows/events.reds
@@ -1488,7 +1488,7 @@ process: func [
 			if msg/hWnd = hover-saved [hover-saved: null]
 			EVT_DISPATCH
 		]
-		WM_MOUSEWHELL [
+		WM_MOUSEWHEEL [
 			flags: 0
 			if msg/wParam and 08h <> 0 [flags: flags or EVT_FLAG_CTRL_DOWN]		;-- MK_CONTROL
 			if msg/wParam and 04h <> 0 [flags: flags or EVT_FLAG_SHIFT_DOWN]	;-- MK_SHIFT
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index fd2e0c75cb..22993fc2c7 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -315,7 +315,7 @@ Red/System [
 #define WM_RBUTTONUP		0205h
 #define WM_MBUTTONDOWN		0207h
 #define WM_MBUTTONUP		0208h
-#define	WM_MOUSEWHELL		020Ah
+#define	WM_MOUSEWHEEL		020Ah
 #define WM_ENTERMENULOOP	0211h
 #define WM_SIZING			0214h
 #define WM_MOVING			0216h

From 2542474bc59c865565797aa95660aa188760308d Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Mon, 23 Dec 2019 17:19:28 +0100
Subject: [PATCH 0729/3432] FEAT: VID support for DATE! option

---
 modules/view/VID.red | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/view/VID.red b/modules/view/VID.red
index 06af73b12a..9b6e1a0aaf 100644
--- a/modules/view/VID.red
+++ b/modules/view/VID.red
@@ -344,6 +344,7 @@ system/view/VID: context [
 							pair!	 [unless opts/size  [opts/size:  value]]
 							string!	 [unless opts/text  [opts/text:  value]]
 							logic!
+							date!
 							percent! [unless opts/data  [opts/data:  value] yes]
 							image!	 [unless opts/image [opts/image: value]]
 							tuple!	 [

From defa569f125c52bf4fb5f0ab6b5d42f09e3559e3 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 24 Dec 2019 16:52:08 +0100
Subject: [PATCH 0730/3432] FIX: minor code cleanup

---
 modules/view/backends/windows/calendar.reds | 5 +++--
 modules/view/backends/windows/gui.reds      | 6 ++----
 modules/view/backends/windows/win32.reds    | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 26b264b982..0c42da85ae 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -36,7 +36,7 @@ with [platform][
 		time: declare tagSYSTEMTIME
 		SendMessage handle MCM_GETCURSEL 0 as integer! time
 		
-		year:  cap WIN32_LOWORD(time/year-month) 			;-- possible overflow: Win32 1601:30827, Red -16384:16383
+		year:  cap WIN32_LOWORD(time/year-month)
 		month: WIN32_HIWORD(time/year-month)
 		day:   WIN32_HIWORD(time/week-day)
 		
@@ -56,9 +56,10 @@ with [platform][
 		return DATE_GET_DAY(date) << 16 and FFFF0000h
 	]
 	
+	;-- possible overflow: Win32 1601:30827, Red -16384:16383
 	cap: func [year [integer!] return: [integer!]][
 		if year < 1601  [year: 1601]
 		if year > 16383 [year: 16383]
 		return year
 	]
-]
\ No newline at end of file
+]
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 012c1750a4..59b76aeabd 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1616,7 +1616,7 @@ OS-make-view: func [
 			set-hint-text handle options
 			if TYPE_OF(selected) <> TYPE_NONE [change-selection handle selected values]
 		]
-		sym = area	 [
+		sym = area [
 			set-area-options handle options
 			change-text handle values sym
 			if TYPE_OF(selected) <> TYPE_NONE [change-selection handle selected values]
@@ -1626,9 +1626,7 @@ OS-make-view: func [
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
 		sym = calendar [
-			if TYPE_OF(data) = TYPE_DATE [
-				change-calendar handle as red-date! data
-			]
+			if TYPE_OF(data) = TYPE_DATE [change-calendar handle as red-date! data]
 		]
 		sym = window [
 			init-window handle
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 22993fc2c7..242cccfab3 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,7 +142,6 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
-
 #define MCS_NOTODAYCIRCLE	08h
 #define MCS_NOTODAY			10h
 #define MCS_NOSELCHANGEONNAV 0100h
@@ -151,6 +150,7 @@ Red/System [
 
 #define MCM_GETCURSEL       1001h
 #define MCM_SETCURSEL		1002h
+#define MCM_SETCOLOR		100Ah
 
 #define TCIF_TEXT			0001h
 

From 97e838bfd2e588868daccfccafd5a2f08e0c9944 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 27 Dec 2019 18:12:05 +0100
Subject: [PATCH 0731/3432] FEAT: preliminary calendar widget support on macOS

---
 modules/view/backends/macOS/classes.reds | 3 +++
 modules/view/backends/macOS/cocoa.reds   | 4 ++++
 modules/view/backends/macOS/gui.reds     | 6 ++++++
 3 files changed, 13 insertions(+)

diff --git a/modules/view/backends/macOS/classes.reds b/modules/view/backends/macOS/classes.reds
index 77837c6db2..73f9d16b25 100644
--- a/modules/view/backends/macOS/classes.reds
+++ b/modules/view/backends/macOS/classes.reds
@@ -145,6 +145,8 @@ add-camera-handler: func [class [integer!]][
 	0
 ]
 
+add-calendar-handler: func [class [integer!]][0]
+
 add-tabview-handler: func [class [integer!]][
 	class_addMethod class sel_getUid "tabView:shouldSelectTabViewItem:" as-integer :tabview-should-select "B@:@@"
 ]
@@ -326,6 +328,7 @@ register-classes: does [
 	make-super-class "RedPopUpButton"	"NSPopUpButton"			as-integer :add-droplist-handler STORE_FACE_FLAG
 	make-super-class "RedTableView"		"NSTableView"			as-integer :add-table-view-handler STORE_FACE_FLAG
 	make-super-class "RedCamera"		"NSView"				as-integer :add-camera-handler STORE_FACE_FLAG
+	make-super-class "RedCalendar"		"NSDatePicker"			as-integer :add-calendar-handler STORE_FACE_FLAG
 	make-super-class "RedTabView"		"NSTabView"				as-integer :add-tabview-handler STORE_FACE_FLAG
 	make-super-class "RedOpenPanel"		"NSOpenPanel"			as-integer :add-filedialog-handler EXTRA_DATA_FLAG
 	make-super-class "RedSavePanel"		"NSSavePanel"			as-integer :add-filedialog-handler EXTRA_DATA_FLAG
diff --git a/modules/view/backends/macOS/cocoa.reds b/modules/view/backends/macOS/cocoa.reds
index 6b435adb43..62a7021be5 100644
--- a/modules/view/backends/macOS/cocoa.reds
+++ b/modules/view/backends/macOS/cocoa.reds
@@ -122,6 +122,10 @@ Red/System [
 #define NSTrackingInVisibleRect				512
 #define NSTrackingEnabledDuringMouseDrag	1024
 
+#define NSDatePickerModeSingle				0
+#define NSDatePickerStyleClockAndCalendar 	1
+#define NSDatePickerElementFlagYearMonthDay 00E0h
+
 #define kCGLineJoinMiter			0
 #define kCGLineJoinRound			1
 #define kCGLineJoinBevel			2
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index 7f2537ddfe..d8fd4a1562 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -1798,6 +1798,7 @@ OS-make-view: func [
 			class: "RedBox"
 		]
 		sym = camera [class: "RedCamera"]
+		sym = calendar [class: "RedCalendar"]
 		true [											;-- search in user-defined classes
 			p: find-class type
 			either null? p [
@@ -1945,6 +1946,11 @@ OS-make-view: func [
 		sym = camera [
 			init-camera obj rc data
 		]
+		sym = calendar [
+			objc_msgSend [obj sel_getUid "setDatePickerMode:" NSDatePickerModeSingle]
+			objc_msgSend [obj sel_getUid "setDatePickerStyle:" NSDatePickerStyleClockAndCalendar]
+			objc_msgSend [obj sel_getUid "setDatePickerElements:" NSDatePickerElementFlagYearMonthDay]
+		]
 		true [											;-- search in user-defined classes
 			if p <> null [
 				p/init-proc as int-ptr! obj values

From 5e20c102f6669ac89c67b425e105f082d96af3ee Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sun, 29 Dec 2019 15:29:50 +0100
Subject: [PATCH 0732/3432] FEAT: target-action skeleton

---
 modules/view/backends/macOS/classes.reds   |  4 +++-
 modules/view/backends/macOS/delegates.reds |  9 +++++++++
 modules/view/backends/macOS/gui.reds       | 21 ++++++++++++++++++---
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/modules/view/backends/macOS/classes.reds b/modules/view/backends/macOS/classes.reds
index 73f9d16b25..637696e2bf 100644
--- a/modules/view/backends/macOS/classes.reds
+++ b/modules/view/backends/macOS/classes.reds
@@ -145,7 +145,9 @@ add-camera-handler: func [class [integer!]][
 	0
 ]
 
-add-calendar-handler: func [class [integer!]][0]
+add-calendar-handler: func [class [integer!]][
+	class_addMethod class sel_getUid "calendar-change:" as-integer :calendar-change "v@:@"
+]
 
 add-tabview-handler: func [class [integer!]][
 	class_addMethod class sel_getUid "tabView:shouldSelectTabViewItem:" as-integer :tabview-should-select "B@:@@"
diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds
index 4724caa181..5275ad18b5 100644
--- a/modules/view/backends/macOS/delegates.reds
+++ b/modules/view/backends/macOS/delegates.reds
@@ -543,6 +543,15 @@ slider-change: func [
 	make-event self 0 EVT_CHANGE
 ]
 
+calendar-change: func [
+	[cdecl]
+	self	[integer!]
+	cmd		[integer!]
+	sender	[integer!]
+][
+	make-event self 0 EVT_CHANGE
+]
+
 set-selected: func [
 	obj [integer!]
 	idx [integer!]
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index d8fd4a1562..7fe0b8162d 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -1174,6 +1174,23 @@ init-combo-box: func [
 	]
 ]
 
+init-calendar: func [
+	calendar [integer!]
+	/local
+		today [integer!]
+][
+	objc_msgSend [calendar sel_getUid "setDatePickerMode:" NSDatePickerModeSingle]
+	objc_msgSend [calendar sel_getUid "setDatePickerStyle:" NSDatePickerStyleClockAndCalendar]
+	objc_msgSend [calendar sel_getUid "setDatePickerElements:" NSDatePickerElementFlagYearMonthDay]
+	
+	today: objc_msgSend [objc_getClass "NSDate" sel_getUid "date"]
+	objc_msgSend [calendar sel_getUid "setDateValue:" today]
+	
+	objc_msgSend [calendar sel_getUid "setTarget:" calendar]
+	objc_msgSend [calendar sel_getUid "setAction:" sel_getUid "calendar-change:"]
+	objc_msgSend [calendar sel_getUid "sendActionOn:" NSLeftMouseDown]
+]
+
 init-window: func [
 	face	[red-object!]
 	window	[integer!]
@@ -1947,9 +1964,7 @@ OS-make-view: func [
 			init-camera obj rc data
 		]
 		sym = calendar [
-			objc_msgSend [obj sel_getUid "setDatePickerMode:" NSDatePickerModeSingle]
-			objc_msgSend [obj sel_getUid "setDatePickerStyle:" NSDatePickerStyleClockAndCalendar]
-			objc_msgSend [obj sel_getUid "setDatePickerElements:" NSDatePickerElementFlagYearMonthDay]
+			init-calendar obj
 		]
 		true [											;-- search in user-defined classes
 			if p <> null [

From ff976f78a06380cbb757cc46f10cce9852a2f0bd Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Sun, 29 Dec 2019 20:34:00 +0100
Subject: [PATCH 0733/3432] FEAT: two-way binding for calendar widget

---
 modules/view/backends/macOS/cocoa.reds     |  4 ++
 modules/view/backends/macOS/delegates.reds | 35 +++++++++++++--
 modules/view/backends/macOS/gui.reds       | 50 +++++++++++++++++++---
 3 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/modules/view/backends/macOS/cocoa.reds b/modules/view/backends/macOS/cocoa.reds
index 62a7021be5..3ca82f4094 100644
--- a/modules/view/backends/macOS/cocoa.reds
+++ b/modules/view/backends/macOS/cocoa.reds
@@ -126,6 +126,10 @@ Red/System [
 #define NSDatePickerStyleClockAndCalendar 	1
 #define NSDatePickerElementFlagYearMonthDay 00E0h
 
+#define NSCalendarUnitYear 			4
+#define NSCalendarUnitMonth 		8
+#define NSCalendarUnitDay 			16
+
 #define kCGLineJoinMiter			0
 #define kCGLineJoinRound			1
 #define kCGLineJoinBevel			2
diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds
index 5275ad18b5..e5e636fccc 100644
--- a/modules/view/backends/macOS/delegates.reds
+++ b/modules/view/backends/macOS/delegates.reds
@@ -545,10 +545,37 @@ slider-change: func [
 
 calendar-change: func [
 	[cdecl]
-	self	[integer!]
-	cmd		[integer!]
-	sender	[integer!]
-][
+	self   [integer!]
+	cmd	   [integer!]
+	sender [integer!]
+	/local
+		slot 	   [red-value!]
+		calendar   [integer!]
+		components [integer!]
+		day 	   [integer!]
+		month 	   [integer!]
+		year	   [integer!]
+][	
+	calendar: objc_msgSend [
+		objc_msgSend [objc_getClass "NSCalendar" sel_getUid "alloc"]
+		sel_getUid "initWithCalendarIdentifier:"
+		NSString("gregorian")
+	]
+	
+	components: objc_msgSend [
+		calendar sel_getUid "components:fromDate:"
+		NSCalendarUnitDay or NSCalendarUnitMonth or NSCalendarUnitYear
+		objc_msgSend [self sel_getUid "dateValue"]
+	]
+	
+	day:   objc_msgSend [components sel_getUid "day"]
+	month: objc_msgSend [components sel_getUid "month"]
+	year:  objc_msgSend [components sel_getUid "year"]
+	
+	slot: (get-face-values self) + FACE_OBJ_DATA
+	date/make-at slot year month day 0.0 0 0 no no
+	
+	objc_msgSend [calendar sel_getUid "release"]
 	make-event self 0 EVT_CHANGE
 ]
 
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index 7fe0b8162d..5a0622e6a1 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -984,6 +984,9 @@ change-data: func [
 		type = rich-text [
 			objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes]
 		]
+		all [type = calendar TYPE_OF(data) = TYPE_DATE][
+			objc_msgSend [hWnd sel_getUid "setDateValue:" to-NSDate as red-date! data]
+		]
 		true [0]										;-- default, do nothing
 	]
 ]
@@ -1174,21 +1177,56 @@ init-combo-box: func [
 	]
 ]
 
+to-NSDate: func [
+	date 	[red-date!]
+	return: [integer!]
+	/local
+		components [integer!]
+		calendar   [integer!]
+		NSDate 	   [integer!]
+][	
+	components: objc_msgSend [
+		objc_msgSend [objc_getClass "NSDateComponents" sel_getUid "alloc"]
+		sel_getUid "init"
+	]
+	
+	objc_msgSend [components sel_getUid "setDay:" DATE_GET_DAY(date/date)]
+	objc_msgSend [components sel_getUid "setMonth:" DATE_GET_MONTH(date/date)]
+	objc_msgSend [components sel_getUid "setYear:" DATE_GET_YEAR(date/date)]
+	
+	calendar: objc_msgSend [
+		objc_msgSend [objc_getClass "NSCalendar" sel_getUid "alloc"]
+		sel_getUid "initWithCalendarIdentifier:"
+		NSString("gregorian")
+	]
+	
+	NSDate: objc_msgSend [calendar sel_getUid "dateFromComponents:" components]
+	objc_msgSend [components sel_getUid "release"]
+	objc_msgSend [calendar sel_getUid "release"]
+	
+	return NSDate
+]
+
 init-calendar: func [
 	calendar [integer!]
-	/local
-		today [integer!]
+	data	 [red-value!]
 ][
 	objc_msgSend [calendar sel_getUid "setDatePickerMode:" NSDatePickerModeSingle]
 	objc_msgSend [calendar sel_getUid "setDatePickerStyle:" NSDatePickerStyleClockAndCalendar]
 	objc_msgSend [calendar sel_getUid "setDatePickerElements:" NSDatePickerElementFlagYearMonthDay]
 	
-	today: objc_msgSend [objc_getClass "NSDate" sel_getUid "date"]
-	objc_msgSend [calendar sel_getUid "setDateValue:" today]
-	
 	objc_msgSend [calendar sel_getUid "setTarget:" calendar]
 	objc_msgSend [calendar sel_getUid "setAction:" sel_getUid "calendar-change:"]
 	objc_msgSend [calendar sel_getUid "sendActionOn:" NSLeftMouseDown]
+	
+	objc_msgSend [
+		calendar
+		sel_getUid "setDateValue:" either TYPE_OF(data) = TYPE_DATE [
+			to-NSDate as red-date! data
+		][
+			objc_msgSend [objc_getClass "NSDate" sel_getUid "date"]
+		]
+	]
 ]
 
 init-window: func [
@@ -1964,7 +2002,7 @@ OS-make-view: func [
 			init-camera obj rc data
 		]
 		sym = calendar [
-			init-calendar obj
+			init-calendar obj as red-value! data
 		]
 		true [											;-- search in user-defined classes
 			if p <> null [

From c3f7416e5362be90b067877b5ffac8ae6ba05d17 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Mon, 30 Dec 2019 13:15:53 +0100
Subject: [PATCH 0734/3432] FIX: highlight "today" day on Windows

---
 modules/view/backends/windows/gui.reds   | 6 +++---
 modules/view/backends/windows/win32.reds | 1 -
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 59b76aeabd..fd797a559d 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -313,8 +313,8 @@ get-text-size: func [
 	size/height: as integer! ceil as float! bbox/height
 
 	if pair <> null [
-		pair/x: as integer! ceil as float! bbox/width
-		pair/y: as integer! ceil as float! bbox/height
+		pair/x: as integer! ceil as float! bbox/width  * 100 / dpi-factor
+		pair/y: as integer! ceil as float! bbox/height * 100 / dpi-factor
 	]
 
 	size
@@ -1447,7 +1447,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
-			flags: flags or MCS_NOTODAY or MCS_NOTODAYCIRCLE or MCS_NOSELCHANGEONNAV
+			flags: flags or MCS_NOTODAY or MCS_NOSELCHANGEONNAV
 		]
 		sym = window [
 			class: #u16 "RedWindow"
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 242cccfab3..12fb1de2e6 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,7 +142,6 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
-#define MCS_NOTODAYCIRCLE	08h
 #define MCS_NOTODAY			10h
 #define MCS_NOSELCHANGEONNAV 0100h
 

From ce874f4ab61496a230fe82db6418ce55a38809ad Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Mon, 30 Dec 2019 14:58:19 +0100
Subject: [PATCH 0735/3432] FEAT: pre-select "today" day if DATA facet is NONE

---
 modules/view/backends/macOS/delegates.reds  | 28 +---------------
 modules/view/backends/macOS/gui.reds        | 37 ++++++++++++++++++++-
 modules/view/backends/windows/calendar.reds | 20 +++++++++--
 modules/view/backends/windows/gui.reds      |  2 +-
 4 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds
index e5e636fccc..0aa7d7407c 100644
--- a/modules/view/backends/macOS/delegates.reds
+++ b/modules/view/backends/macOS/delegates.reds
@@ -548,34 +548,8 @@ calendar-change: func [
 	self   [integer!]
 	cmd	   [integer!]
 	sender [integer!]
-	/local
-		slot 	   [red-value!]
-		calendar   [integer!]
-		components [integer!]
-		day 	   [integer!]
-		month 	   [integer!]
-		year	   [integer!]
 ][	
-	calendar: objc_msgSend [
-		objc_msgSend [objc_getClass "NSCalendar" sel_getUid "alloc"]
-		sel_getUid "initWithCalendarIdentifier:"
-		NSString("gregorian")
-	]
-	
-	components: objc_msgSend [
-		calendar sel_getUid "components:fromDate:"
-		NSCalendarUnitDay or NSCalendarUnitMonth or NSCalendarUnitYear
-		objc_msgSend [self sel_getUid "dateValue"]
-	]
-	
-	day:   objc_msgSend [components sel_getUid "day"]
-	month: objc_msgSend [components sel_getUid "month"]
-	year:  objc_msgSend [components sel_getUid "year"]
-	
-	slot: (get-face-values self) + FACE_OBJ_DATA
-	date/make-at slot year month day 0.0 0 0 no no
-	
-	objc_msgSend [calendar sel_getUid "release"]
+	sync-calendar self
 	make-event self 0 EVT_CHANGE
 ]
 
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index 5a0622e6a1..8288b567b5 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -1207,6 +1207,38 @@ to-NSDate: func [
 	return NSDate
 ]
 
+sync-calendar: func [
+	handle [integer!]
+	/local
+		slot 	   [red-value!]
+		calendar   [integer!]
+		components [integer!]
+		day 	   [integer!]
+		month 	   [integer!]
+		year	   [integer!]
+][
+	calendar: objc_msgSend [
+		objc_msgSend [objc_getClass "NSCalendar" sel_getUid "alloc"]
+		sel_getUid "initWithCalendarIdentifier:"
+		NSString("gregorian")
+	]
+	
+	components: objc_msgSend [
+		calendar sel_getUid "components:fromDate:"
+		NSCalendarUnitDay or NSCalendarUnitMonth or NSCalendarUnitYear
+		objc_msgSend [handle sel_getUid "dateValue"]
+	]
+	
+	day:   objc_msgSend [components sel_getUid "day"]
+	month: objc_msgSend [components sel_getUid "month"]
+	year:  objc_msgSend [components sel_getUid "year"]
+	
+	slot: (get-face-values handle) + FACE_OBJ_DATA
+	date/make-at slot year month day 0.0 0 0 no no
+	
+	objc_msgSend [calendar sel_getUid "release"]
+]
+
 init-calendar: func [
 	calendar [integer!]
 	data	 [red-value!]
@@ -1221,12 +1253,15 @@ init-calendar: func [
 	
 	objc_msgSend [
 		calendar
-		sel_getUid "setDateValue:" either TYPE_OF(data) = TYPE_DATE [
+		sel_getUid "setDateValue:"
+		either TYPE_OF(data) = TYPE_DATE [
 			to-NSDate as red-date! data
 		][
 			objc_msgSend [objc_getClass "NSDate" sel_getUid "date"]
 		]
 	]
+	
+	unless TYPE_OF(data) = TYPE_DATE [sync-calendar calendar]
 ]
 
 init-window: func [
diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 0c42da85ae..45b4efca4a 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -23,8 +23,8 @@ with [platform][
 
 		SendMessage handle MCM_SETCURSEL 0 as integer! time
 	]
-
-	process-calendar-change: func [
+	
+	sync-calendar: func [
 		handle [handle!]
 		/local
 			slot  [red-value!]
@@ -44,7 +44,21 @@ with [platform][
 		
 		slot: get-facet current-msg FACE_OBJ_DATA
 		date/make-at slot year month day 0.0 0 0 no no
-		
+	]
+	
+	init-calendar: func [
+		handle [handle!]
+		data   [red-value!]
+	][
+		either TYPE_OF(data) = TYPE_DATE [
+			change-calendar handle as red-date! data
+		][
+			sync-calendar handle
+		]
+	]
+	
+	process-calendar-change: func [handle [handle!]][
+		sync-calendar handle
 		make-event current-msg 0 EVT_CHANGE
 	]
 	
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index fd797a559d..5d08618b3f 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1626,7 +1626,7 @@ OS-make-view: func [
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
 		sym = calendar [
-			if TYPE_OF(data) = TYPE_DATE [change-calendar handle as red-date! data]
+			init-calendar handle data
 		]
 		sym = window [
 			init-window handle

From 4740976f196e3289c4f3b65fc339baba3348bfe7 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 2 Jan 2020 18:20:45 +0100
Subject: [PATCH 0736/3432] FEAT: change interface of calendar selectors

---
 modules/view/backends/windows/calendar.reds | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 45b4efca4a..d75f5df34f 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -18,8 +18,8 @@ with [platform][
 			time [tagSYSTEMTIME]
 	][
 		time: declare tagSYSTEMTIME		
-		time/year-month: get-year-month date/date
-		time/week-day: get-day date/date
+		time/year-month: get-year-month date
+		time/week-day: get-day date
 
 		SendMessage handle MCM_SETCURSEL 0 as integer! time
 	]
@@ -62,12 +62,12 @@ with [platform][
 		make-event current-msg 0 EVT_CHANGE
 	]
 	
-	get-year-month: func [date [integer!] return: [integer!]][
-		return DATE_GET_MONTH(date) << 16 or cap DATE_GET_YEAR(date)
+	get-year-month: func [date [red-date!] return: [integer!]][
+		return DATE_GET_MONTH(date/date) << 16 or cap DATE_GET_YEAR(date/date)
 	]
 	
-	get-day: func [date [integer!] return: [integer!]][
-		return DATE_GET_DAY(date) << 16 and FFFF0000h
+	get-day: func [date [red-date!] return: [integer!]][
+		return DATE_GET_DAY(date/date) << 16 and FFFF0000h
 	]
 	
 	;-- possible overflow: Win32 1601:30827, Red -16384:16383

From dde8a8c162d59c80eef9bc9795b4b9ac321a0675 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 2 Jan 2020 19:07:16 +0100
Subject: [PATCH 0737/3432] FEAT: support for calendar coloring

---
 modules/view/backends/windows/calendar.reds | 11 +++++++++++
 modules/view/backends/windows/gui.reds      | 18 ++++++++++++------
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index d75f5df34f..8c6052e12a 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -57,6 +57,17 @@ with [platform][
 		]
 	]
 	
+	update-calendar-color: func [
+		handle [handle!]
+		color  [red-value!]
+	][
+		switch TYPE_OF(color) [
+			TYPE_TUPLE [SendMessage handle MCM_SETCOLOR 0 color/data1]
+			TYPE_NONE  [SendMessage handle MCM_SETCOLOR 0 00FFFFFFh]
+			default    [0]
+		]
+	]
+	
 	process-calendar-change: func [handle [handle!]][
 		sync-calendar handle
 		make-event current-msg 0 EVT_CHANGE
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 5d08618b3f..3c66d4f0cc 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1336,7 +1336,7 @@ OS-make-view: func [
 	selected: as red-integer!	values + FACE_OBJ_SELECTED
 	para:	  as red-object!	values + FACE_OBJ_PARA
 	rate:	  					values + FACE_OBJ_RATE
-	options:   as red-block!	values + FACE_OBJ_OPTIONS
+	options:  as red-block!		values + FACE_OBJ_OPTIONS
 	
 	bits: 	  get-flags as red-block! values + FACE_OBJ_FLAGS
 
@@ -1626,7 +1626,8 @@ OS-make-view: func [
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
 		sym = calendar [
-			init-calendar handle data
+			init-calendar handle as red-value! data
+			update-calendar-color handle as red-value! values + FACE_OBJ_COLOR
 		]
 		sym = window [
 			init-window handle
@@ -2348,6 +2349,7 @@ OS-update-view: func [
 		int		[red-integer!]
 		int2	[red-integer!]
 		bool	[red-logic!]
+		color	[red-tuple!]
 		s		[series!]
 		hWnd	[handle!]
 		flags	[integer!]
@@ -2413,10 +2415,14 @@ OS-update-view: func [
 		]
 	]
 	if flags and FACET_FLAG_COLOR <> 0 [
-		either type = base [
-			update-base hWnd GetParent hWnd null values
-		][
-			InvalidateRect hWnd null 1
+		case [
+			type = base [
+				update-base hWnd GetParent hWnd null values
+			]
+			type = calendar [
+				update-calendar-color hWnd as red-value! values + FACE_OBJ_COLOR
+			]
+			true [InvalidateRect hWnd null 1]
 		]
 	]
 	if flags and FACET_FLAG_PANE <> 0 [

From 0674d5206c0eda6af92f15954daa1cd6d4b2c47e Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 3 Jan 2020 14:09:40 +0100
Subject: [PATCH 0738/3432] FIX: allow quick "today" selection on Win32

---
 modules/view/backends/windows/gui.reds   | 2 +-
 modules/view/backends/windows/win32.reds | 1 -
 modules/view/styles.red                  | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 3c66d4f0cc..953e159a4c 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1447,7 +1447,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
-			flags: flags or MCS_NOTODAY or MCS_NOSELCHANGEONNAV
+			flags: flags or MCS_NOSELCHANGEONNAV
 		]
 		sym = window [
 			class: #u16 "RedWindow"
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 12fb1de2e6..025e2e88f4 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,7 +142,6 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
-#define MCS_NOTODAY			10h
 #define MCS_NOSELCHANGEONNAV 0100h
 
 #define MCN_SELCHANGE		FFFFFD13h
diff --git a/modules/view/styles.red b/modules/view/styles.red
index f94945ba6a..7452752a07 100644
--- a/modules/view/styles.red
+++ b/modules/view/styles.red
@@ -121,6 +121,6 @@ Red [
 	]
 	calendar: [
 		default-actor: on-change
-		template: [type: 'calendar size: 206x149]
+		template: [type: 'calendar size: 206x167]
 	]
 )
\ No newline at end of file

From 8dabc72ea265e065ed59e528853c70bcfad13fda Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 3 Jan 2020 14:09:59 +0100
Subject: [PATCH 0739/3432] FIX: minor code refactoring

---
 modules/view/view.red | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/view/view.red b/modules/view/view.red
index c525d09574..542a7a7803 100644
--- a/modules/view/view.red
+++ b/modules/view/view.red
@@ -439,7 +439,7 @@ face!: object [				;-- keep in sync with facet! enum
 						all [options options/default]
 					]
 				]
-				if 'data = word [
+				if word = 'data [
 					either data [
 						if string? text [modify text 'owned none]
 						set-quiet 'text form data		;@@ use form/into (avoids rebinding)

From c6208fb88a060f3f0a7fbb65f9414dc86c5a3d48 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 3 Jan 2020 16:33:36 +0100
Subject: [PATCH 0740/3432] FIX: proper cross-platform calendar widget sizing

---
 modules/view/backends/platform.red | 1 +
 modules/view/styles.red            | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red
index 9bd18cae5c..3287ec993c 100644
--- a/modules/view/backends/platform.red
+++ b/modules/view/backends/platform.red
@@ -738,6 +738,7 @@ system/view/platform: context [
 				button:			[8x8   0x0]
 				drop-down:		[0x7   0x0]
 				drop-list:		[0x7   0x0]
+				calendar:		[67x0 19x0]
 			]
 			macOS [
 				button:			[11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0]
diff --git a/modules/view/styles.red b/modules/view/styles.red
index 7452752a07..b84e4497f8 100644
--- a/modules/view/styles.red
+++ b/modules/view/styles.red
@@ -121,6 +121,6 @@ Red [
 	]
 	calendar: [
 		default-actor: on-change
-		template: [type: 'calendar size: 206x167]
+		template: [type: 'calendar size: 139x148]
 	]
 )
\ No newline at end of file

From f5fd6ab96721e7c8bf65e3b83d16eadc3903315f Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 3 Jan 2020 17:06:54 +0100
Subject: [PATCH 0741/3432] FEAT: minor refactoring

---
 modules/view/backends/windows/calendar.reds | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 8c6052e12a..0efcf9fe49 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -60,12 +60,16 @@ with [platform][
 	update-calendar-color: func [
 		handle [handle!]
 		color  [red-value!]
+		/local
+			colorref [integer!]
 	][
 		switch TYPE_OF(color) [
-			TYPE_TUPLE [SendMessage handle MCM_SETCOLOR 0 color/data1]
-			TYPE_NONE  [SendMessage handle MCM_SETCOLOR 0 00FFFFFFh]
+			TYPE_TUPLE [colorref: color/data1]
+			TYPE_NONE  [colorref: 00FFFFFFh]
 			default    [0]
 		]
+		
+		SendMessage handle MCM_SETCOLOR 0 colorref 			;-- MCSC_BACKGROUND
 	]
 	
 	process-calendar-change: func [handle [handle!]][

From 0d9450688c1107406825281185a9fede958b1b50 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Fri, 3 Jan 2020 17:40:24 +0100
Subject: [PATCH 0742/3432] FIX: set hard limits on supported date ranges

---
 modules/view/backends/macOS/gui.reds        | 16 +++++++++++++++-
 modules/view/backends/windows/calendar.reds |  6 +++---
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index 8288b567b5..ee94c4c897 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -1177,6 +1177,12 @@ init-combo-box: func [
 	]
 ]
 
+cap-year: func [year [integer!] return: [integer!]][
+	if year < 1601 [year: 1601]
+	if year > 9999 [year: 9999]
+	return year
+]
+
 to-NSDate: func [
 	date 	[red-date!]
 	return: [integer!]
@@ -1192,7 +1198,7 @@ to-NSDate: func [
 	
 	objc_msgSend [components sel_getUid "setDay:" DATE_GET_DAY(date/date)]
 	objc_msgSend [components sel_getUid "setMonth:" DATE_GET_MONTH(date/date)]
-	objc_msgSend [components sel_getUid "setYear:" DATE_GET_YEAR(date/date)]
+	objc_msgSend [components sel_getUid "setYear:" cap-year DATE_GET_YEAR(date/date)]
 	
 	calendar: objc_msgSend [
 		objc_msgSend [objc_getClass "NSCalendar" sel_getUid "alloc"]
@@ -1242,6 +1248,8 @@ sync-calendar: func [
 init-calendar: func [
 	calendar [integer!]
 	data	 [red-value!]
+	/local
+		slot [red-value!]
 ][
 	objc_msgSend [calendar sel_getUid "setDatePickerMode:" NSDatePickerModeSingle]
 	objc_msgSend [calendar sel_getUid "setDatePickerStyle:" NSDatePickerStyleClockAndCalendar]
@@ -1251,6 +1259,12 @@ init-calendar: func [
 	objc_msgSend [calendar sel_getUid "setAction:" sel_getUid "calendar-change:"]
 	objc_msgSend [calendar sel_getUid "sendActionOn:" NSLeftMouseDown]
 	
+	slot: declare red-value!
+	date/make-at slot 1601 01 01 0.0 0 0 no no
+	objc_msgSend [calendar sel_getUid "setMinDate:" to-NSDate as red-date! slot]
+	date/make-at slot 9999 12 31 0.0 0 0 no no
+	objc_msgSend [calendar sel_getUid "setMaxDate:" to-NSDate as red-date! slot]
+	
 	objc_msgSend [
 		calendar
 		sel_getUid "setDateValue:"
diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 0efcf9fe49..876baa1bc7 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -85,10 +85,10 @@ with [platform][
 		return DATE_GET_DAY(date/date) << 16 and FFFF0000h
 	]
 	
-	;-- possible overflow: Win32 1601:30827, Red -16384:16383
+	;-- possible overflow: Win32 1601:30827, Red -9999:9999
 	cap: func [year [integer!] return: [integer!]][
-		if year < 1601  [year: 1601]
-		if year > 16383 [year: 16383]
+		if year < 1601 [year: 1601]
+		if year > 9999 [year: 9999]
 		return year
 	]
 ]

From 2e355a844f178d5dae1ce816873ecea53224adb3 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Mon, 6 Jan 2020 14:31:32 +0100
Subject: [PATCH 0743/3432] FEAT: emit SELECT event prior to selection

---
 modules/view/backends/macOS/delegates.reds  | 1 +
 modules/view/backends/windows/calendar.reds | 1 +
 2 files changed, 2 insertions(+)

diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds
index 0aa7d7407c..0e9ede48fb 100644
--- a/modules/view/backends/macOS/delegates.reds
+++ b/modules/view/backends/macOS/delegates.reds
@@ -549,6 +549,7 @@ calendar-change: func [
 	cmd	   [integer!]
 	sender [integer!]
 ][	
+	make-event self 0 EVT_SELECT
 	sync-calendar self
 	make-event self 0 EVT_CHANGE
 ]
diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 876baa1bc7..d138c8b60d 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -73,6 +73,7 @@ with [platform][
 	]
 	
 	process-calendar-change: func [handle [handle!]][
+		make-event current-msg 0 EVT_SELECT
 		sync-calendar handle
 		make-event current-msg 0 EVT_CHANGE
 	]

From 39006627f0be81ee96f4a84e0ccb4ae2d72e48f3 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Mon, 6 Jan 2020 14:32:07 +0100
Subject: [PATCH 0744/3432] FEAT: use SELECTED facet instead of DATA

---
 modules/view/backends/macOS/gui.reds        | 2 +-
 modules/view/backends/windows/calendar.reds | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index ee94c4c897..69ebb1013f 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -1239,7 +1239,7 @@ sync-calendar: func [
 	month: objc_msgSend [components sel_getUid "month"]
 	year:  objc_msgSend [components sel_getUid "year"]
 	
-	slot: (get-face-values handle) + FACE_OBJ_DATA
+	slot: (get-face-values handle) + FACE_OBJ_SELECTED
 	date/make-at slot year month day 0.0 0 0 no no
 	
 	objc_msgSend [calendar sel_getUid "release"]
diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index d138c8b60d..5a1f49d8bb 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -42,7 +42,7 @@ with [platform][
 		
 		current-msg/hWnd: handle
 		
-		slot: get-facet current-msg FACE_OBJ_DATA
+		slot: get-facet current-msg FACE_OBJ_SELECTED
 		date/make-at slot year month day 0.0 0 0 no no
 	]
 	

From 097c1443272fabb03229836d987a0abb96a43a88 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 13:21:40 +0100
Subject: [PATCH 0745/3432] FIX: full support of new calendar API

---
 modules/view/VID.red                   |  6 +++++-
 modules/view/backends/macOS/gui.reds   | 10 +++++-----
 modules/view/backends/windows/gui.reds | 10 +++++-----
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/modules/view/VID.red b/modules/view/VID.red
index 9b6e1a0aaf..a16d6a083d 100644
--- a/modules/view/VID.red
+++ b/modules/view/VID.red
@@ -344,7 +344,6 @@ system/view/VID: context [
 							pair!	 [unless opts/size  [opts/size:  value]]
 							string!	 [unless opts/text  [opts/text:  value]]
 							logic!
-							date!
 							percent! [unless opts/data  [opts/data:  value] yes]
 							image!	 [unless opts/image [opts/image: value]]
 							tuple!	 [
@@ -354,6 +353,11 @@ system/view/VID: context [
 									opts/color: value
 								]
 							]
+							date! [
+								if all ['calendar = face/type not opts/selected][
+									opts/selected: value
+								]
+							]
 							integer! [
 								unless opts/size [
 									either find [panel group-box] face/type [
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index 69ebb1013f..cbb18e689e 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -984,16 +984,13 @@ change-data: func [
 		type = rich-text [
 			objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes]
 		]
-		all [type = calendar TYPE_OF(data) = TYPE_DATE][
-			objc_msgSend [hWnd sel_getUid "setDateValue:" to-NSDate as red-date! data]
-		]
 		true [0]										;-- default, do nothing
 	]
 ]
 
 change-selection: func [
 	hWnd   [integer!]
-	int	   [red-integer!]								;-- can be also none! | object!
+	int	   [red-integer!]								;-- can be also none! | object! | percent! | date!
 	type   [integer!]
 	/local
 		idx [integer!]
@@ -1032,6 +1029,9 @@ change-selection: func [
 				toggle-preview hWnd true
 			]
 		]
+		all [type = calendar TYPE_OF(int) = TYPE_DATE][
+			objc_msgSend [hWnd sel_getUid "setDateValue:" to-NSDate as red-date! int]
+		]
 		type = text-list [
 			hWnd: objc_msgSend [hWnd sel_getUid "documentView"]
 			if idx = -1 [
@@ -2051,7 +2051,7 @@ OS-make-view: func [
 			init-camera obj rc data
 		]
 		sym = calendar [
-			init-calendar obj as red-value! data
+			init-calendar obj as red-value! values + FACE_OBJ_SELECTED
 		]
 		true [											;-- search in user-defined classes
 			if p <> null [
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index 953e159a4c..b39232b72f 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1626,7 +1626,7 @@ OS-make-view: func [
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
 		sym = calendar [
-			init-calendar handle as red-value! data
+			init-calendar handle as red-value! selected
 			update-calendar-color handle as red-value! values + FACE_OBJ_COLOR
 		]
 		sym = window [
@@ -2005,7 +2005,7 @@ change-image: func [
 
 change-selection: func [
 	hWnd   [handle!]
-	int	   [red-integer!]								;-- can be also none! | object! | percent!
+	int	   [red-integer!]								;-- can be also none! | object! | percent! | date!
 	values [red-value!]
 	/local
 		type [red-word!]
@@ -2037,6 +2037,9 @@ change-selection: func [
 				]
 			]
 		]
+		all [sym = calendar TYPE_OF(int) = TYPE_DATE][
+			change-calendar hWnd as red-date! int
+		]
 		sym = text-list [
 			SendMessage hWnd LB_SETCURSEL int/value - 1 0
 		]
@@ -2124,9 +2127,6 @@ change-data: func [
 		type = tab-panel [
 			set-tabs hWnd get-face-values hWnd
 		]
-		all [type = calendar TYPE_OF(data) = TYPE_DATE][
-			change-calendar hWnd as red-date! data
-		]
 		type = text-list [
 			if TYPE_OF(data) = TYPE_BLOCK [
 				init-text-list 

From 01ce2f6835088f6baddc42e2bf74ae1e8feee229 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 13:32:57 +0100
Subject: [PATCH 0746/3432] TESTS: add calendar to GUI testing script

---
 tests/view-test.red | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tests/view-test.red b/tests/view-test.red
index 6b2d1580c2..0588669196 100644
--- a/tests/view-test.red
+++ b/tests/view-test.red
@@ -869,6 +869,39 @@ win/pane: reduce [
 			]
 		]
 	]
+	calendar: make face! [
+		type: 'calendar offset: 750x450 size: 300x300 color: rebolor
+		actors: object [
+			on-select: func [face [object!] event [event!]][
+				print ["Previous date:" face/selected]
+			]
+			on-change: func [face [object!] event [event!]][
+				print ["New date:" face/selected]
+			]
+		]
+	]
+	make face! [
+		type: 'button offset: 750x750 size: 90x30 text: "Previous month"
+		actors: object [
+			on-click: func [face [object!] event [event!]][
+				if date? calendar/selected [
+					calendar/selected/month: calendar/selected/month - 1
+					show calendar
+				]
+			]
+		]
+	]
+	make face! [
+		type: 'button offset: 960x750 size: 90x30 text: "Next week"
+		actors: object [
+			on-click: func [face [object!] event [event!]][
+				if date? calendar/selected [
+					calendar/selected: calendar/selected + 7
+					show calendar
+				]
+			]
+		]
+	]
 ]
 
 append win/pane panel: make face! [

From c2dba21404d0948acb1981b715faac38c2af9202 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 16:08:05 +0100
Subject: [PATCH 0747/3432] FIX: proper styling on Windows

---
 modules/view/backends/platform.red       | 2 +-
 modules/view/backends/windows/gui.reds   | 2 +-
 modules/view/backends/windows/win32.reds | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red
index 3287ec993c..f665daf44f 100644
--- a/modules/view/backends/platform.red
+++ b/modules/view/backends/platform.red
@@ -738,7 +738,7 @@ system/view/platform: context [
 				button:			[8x8   0x0]
 				drop-down:		[0x7   0x0]
 				drop-list:		[0x7   0x0]
-				calendar:		[67x0 19x0]
+				calendar:		[21x0 1x0]
 			]
 			macOS [
 				button:			[11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0]
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index b39232b72f..b496bc63af 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1447,7 +1447,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
-			flags: flags or MCS_NOSELCHANGEONNAV
+			flags: flags or MCS_NOSELCHANGEONNAV or MCS_NOTODAY or 0080h			;-- undocumented flag for compacting calendar cell's padding
 		]
 		sym = window [
 			class: #u16 "RedWindow"
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 025e2e88f4..12fb1de2e6 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -142,6 +142,7 @@ Red/System [
 #define TCM_SETCURFOCUS		1330h
 #define TCM_INSERTITEMW		133Eh
 
+#define MCS_NOTODAY			10h
 #define MCS_NOSELCHANGEONNAV 0100h
 
 #define MCN_SELCHANGE		FFFFFD13h

From 1c7c9c47531a7e318e4a7a52823789d471723d9b Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 16:09:00 +0100
Subject: [PATCH 0748/3432] FIX: revert back to support of DATA facet

---
 modules/view/VID.red                        |  6 +-----
 modules/view/backends/macOS/delegates.reds  |  1 -
 modules/view/backends/macOS/gui.reds        | 12 ++++++------
 modules/view/backends/windows/calendar.reds |  3 +--
 modules/view/backends/windows/gui.reds      | 10 +++++-----
 tests/view-test.red                         | 13 +++++--------
 6 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/modules/view/VID.red b/modules/view/VID.red
index a16d6a083d..9b6e1a0aaf 100644
--- a/modules/view/VID.red
+++ b/modules/view/VID.red
@@ -344,6 +344,7 @@ system/view/VID: context [
 							pair!	 [unless opts/size  [opts/size:  value]]
 							string!	 [unless opts/text  [opts/text:  value]]
 							logic!
+							date!
 							percent! [unless opts/data  [opts/data:  value] yes]
 							image!	 [unless opts/image [opts/image: value]]
 							tuple!	 [
@@ -353,11 +354,6 @@ system/view/VID: context [
 									opts/color: value
 								]
 							]
-							date! [
-								if all ['calendar = face/type not opts/selected][
-									opts/selected: value
-								]
-							]
 							integer! [
 								unless opts/size [
 									either find [panel group-box] face/type [
diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds
index 0e9ede48fb..0aa7d7407c 100644
--- a/modules/view/backends/macOS/delegates.reds
+++ b/modules/view/backends/macOS/delegates.reds
@@ -549,7 +549,6 @@ calendar-change: func [
 	cmd	   [integer!]
 	sender [integer!]
 ][	
-	make-event self 0 EVT_SELECT
 	sync-calendar self
 	make-event self 0 EVT_CHANGE
 ]
diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds
index cbb18e689e..ee94c4c897 100644
--- a/modules/view/backends/macOS/gui.reds
+++ b/modules/view/backends/macOS/gui.reds
@@ -984,13 +984,16 @@ change-data: func [
 		type = rich-text [
 			objc_msgSend [hWnd sel_getUid "setNeedsDisplay:" yes]
 		]
+		all [type = calendar TYPE_OF(data) = TYPE_DATE][
+			objc_msgSend [hWnd sel_getUid "setDateValue:" to-NSDate as red-date! data]
+		]
 		true [0]										;-- default, do nothing
 	]
 ]
 
 change-selection: func [
 	hWnd   [integer!]
-	int	   [red-integer!]								;-- can be also none! | object! | percent! | date!
+	int	   [red-integer!]								;-- can be also none! | object!
 	type   [integer!]
 	/local
 		idx [integer!]
@@ -1029,9 +1032,6 @@ change-selection: func [
 				toggle-preview hWnd true
 			]
 		]
-		all [type = calendar TYPE_OF(int) = TYPE_DATE][
-			objc_msgSend [hWnd sel_getUid "setDateValue:" to-NSDate as red-date! int]
-		]
 		type = text-list [
 			hWnd: objc_msgSend [hWnd sel_getUid "documentView"]
 			if idx = -1 [
@@ -1239,7 +1239,7 @@ sync-calendar: func [
 	month: objc_msgSend [components sel_getUid "month"]
 	year:  objc_msgSend [components sel_getUid "year"]
 	
-	slot: (get-face-values handle) + FACE_OBJ_SELECTED
+	slot: (get-face-values handle) + FACE_OBJ_DATA
 	date/make-at slot year month day 0.0 0 0 no no
 	
 	objc_msgSend [calendar sel_getUid "release"]
@@ -2051,7 +2051,7 @@ OS-make-view: func [
 			init-camera obj rc data
 		]
 		sym = calendar [
-			init-calendar obj as red-value! values + FACE_OBJ_SELECTED
+			init-calendar obj as red-value! data
 		]
 		true [											;-- search in user-defined classes
 			if p <> null [
diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 5a1f49d8bb..876baa1bc7 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -42,7 +42,7 @@ with [platform][
 		
 		current-msg/hWnd: handle
 		
-		slot: get-facet current-msg FACE_OBJ_SELECTED
+		slot: get-facet current-msg FACE_OBJ_DATA
 		date/make-at slot year month day 0.0 0 0 no no
 	]
 	
@@ -73,7 +73,6 @@ with [platform][
 	]
 	
 	process-calendar-change: func [handle [handle!]][
-		make-event current-msg 0 EVT_SELECT
 		sync-calendar handle
 		make-event current-msg 0 EVT_CHANGE
 	]
diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index b496bc63af..c1235c5ff6 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1626,7 +1626,7 @@ OS-make-view: func [
 			SetWindowLong handle wc-offset - 12 BASE_FACE_D2D or BASE_FACE_IME
 		]
 		sym = calendar [
-			init-calendar handle as red-value! selected
+			init-calendar handle as red-value! data
 			update-calendar-color handle as red-value! values + FACE_OBJ_COLOR
 		]
 		sym = window [
@@ -2005,7 +2005,7 @@ change-image: func [
 
 change-selection: func [
 	hWnd   [handle!]
-	int	   [red-integer!]								;-- can be also none! | object! | percent! | date!
+	int	   [red-integer!]								;-- can be also none! | object! | percent!
 	values [red-value!]
 	/local
 		type [red-word!]
@@ -2037,9 +2037,6 @@ change-selection: func [
 				]
 			]
 		]
-		all [sym = calendar TYPE_OF(int) = TYPE_DATE][
-			change-calendar hWnd as red-date! int
-		]
 		sym = text-list [
 			SendMessage hWnd LB_SETCURSEL int/value - 1 0
 		]
@@ -2127,6 +2124,9 @@ change-data: func [
 		type = tab-panel [
 			set-tabs hWnd get-face-values hWnd
 		]
+		all [type = calendar TYPE_OF(data) = TYPE_DATE][
+			change-calendar hWnd as red-date! data
+		]
 		type = text-list [
 			if TYPE_OF(data) = TYPE_BLOCK [
 				init-text-list 
diff --git a/tests/view-test.red b/tests/view-test.red
index 0588669196..3c33a4818a 100644
--- a/tests/view-test.red
+++ b/tests/view-test.red
@@ -872,11 +872,8 @@ win/pane: reduce [
 	calendar: make face! [
 		type: 'calendar offset: 750x450 size: 300x300 color: rebolor
 		actors: object [
-			on-select: func [face [object!] event [event!]][
-				print ["Previous date:" face/selected]
-			]
 			on-change: func [face [object!] event [event!]][
-				print ["New date:" face/selected]
+				print ["Selected date:" face/data]
 			]
 		]
 	]
@@ -884,8 +881,8 @@ win/pane: reduce [
 		type: 'button offset: 750x750 size: 90x30 text: "Previous month"
 		actors: object [
 			on-click: func [face [object!] event [event!]][
-				if date? calendar/selected [
-					calendar/selected/month: calendar/selected/month - 1
+				if date? calendar/data [
+					calendar/data/month: calendar/data/month - 1
 					show calendar
 				]
 			]
@@ -895,8 +892,8 @@ win/pane: reduce [
 		type: 'button offset: 960x750 size: 90x30 text: "Next week"
 		actors: object [
 			on-click: func [face [object!] event [event!]][
-				if date? calendar/selected [
-					calendar/selected: calendar/selected + 7
+				if date? calendar/data [
+					calendar/data: calendar/data + 7
 					show calendar
 				]
 			]

From 5cbdac43a854f4b6258417adf07fda2d1b92fcbc Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 18:02:36 +0100
Subject: [PATCH 0749/3432] FIX: define macro for styling flag

---
 modules/view/backends/windows/gui.reds   | 2 +-
 modules/view/backends/windows/win32.reds | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds
index c1235c5ff6..b151af17aa 100644
--- a/modules/view/backends/windows/gui.reds
+++ b/modules/view/backends/windows/gui.reds
@@ -1447,7 +1447,7 @@ OS-make-view: func [
 		]
 		sym = calendar [
 			class: #u16 "RedCalendar"
-			flags: flags or MCS_NOSELCHANGEONNAV or MCS_NOTODAY or 0080h			;-- undocumented flag for compacting calendar cell's padding
+			flags: flags or MCS_NOSELCHANGEONNAV or MCS_NOTODAY or MCS_SHORTDAYSOFWEEK
 		]
 		sym = window [
 			class: #u16 "RedWindow"
diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 12fb1de2e6..76557e1a9b 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -143,6 +143,7 @@ Red/System [
 #define TCM_INSERTITEMW		133Eh
 
 #define MCS_NOTODAY			10h
+#define MCS_SHORTDAYSOFWEEK 80h
 #define MCS_NOSELCHANGEONNAV 0100h
 
 #define MCN_SELCHANGE		FFFFFD13h

From 7988efa6e3efcca8db8d5923636ce4414788fd40 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 18:54:00 +0100
Subject: [PATCH 0750/3432] FIX: properly handle default background color

---
 modules/view/backends/windows/calendar.reds | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 876baa1bc7..40ac140c90 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -62,14 +62,16 @@ with [platform][
 		color  [red-value!]
 		/local
 			colorref [integer!]
-	][
+			painted? [logic!]
+	][	
+		painted?: yes
 		switch TYPE_OF(color) [
 			TYPE_TUPLE [colorref: color/data1]
-			TYPE_NONE  [colorref: 00FFFFFFh]
-			default    [0]
+			TYPE_NONE  [colorref: GetSysColor COLOR_3DFACE]				;-- same as panel
+			default    [painted?: no]
 		]
 		
-		SendMessage handle MCM_SETCOLOR 0 colorref 			;-- MCSC_BACKGROUND
+		if painted? [SendMessage handle MCM_SETCOLOR 0 colorref] 		;-- MCSC_BACKGROUND
 	]
 	
 	process-calendar-change: func [handle [handle!]][
@@ -85,7 +87,6 @@ with [platform][
 		return DATE_GET_DAY(date/date) << 16 and FFFF0000h
 	]
 	
-	;-- possible overflow: Win32 1601:30827, Red -9999:9999
 	cap: func [year [integer!] return: [integer!]][
 		if year < 1601 [year: 1601]
 		if year > 9999 [year: 9999]

From 4acc503efabe08006abde3d5c138d9a06e104e07 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Tue, 7 Jan 2020 19:22:22 +0100
Subject: [PATCH 0751/3432] FIX: add small left margin

---
 modules/view/backends/platform.red | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red
index f665daf44f..e4ca458b76 100644
--- a/modules/view/backends/platform.red
+++ b/modules/view/backends/platform.red
@@ -717,6 +717,7 @@ system/view/platform: context [
 				button:			[1x1   1x1]				;-- LeftxRight TopxBottom
 				tab-panel:		[0x2   0x1]
 				group-box:		[0x0   0x1]
+				calendar:		[1x0   0x0]
 			]
 			macOS [
 				button:			[2x2   2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1]

From ecb269539120d89c482c9c12c714786347eb8762 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 8 Jan 2020 21:27:20 +0100
Subject: [PATCH 0752/3432] FEAT: more complete lexer events triggering.

---
 runtime/lexer.reds | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 7d55d3cf96..8e213b26ab 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -394,7 +394,7 @@ lexer: context [
 				stack/push block/rs-abs-at blk type - 1		;-- 1-based access
 			]
 		][
-			datatype/push type
+			either zero? type [none/push][datatype/push type]
 		]
 		either all [lex/in-series <> null TYPE_OF(lex/in-series) <> TYPE_BINARY][
 			x: unicode/count-chars lex/input s
@@ -481,6 +481,7 @@ lexer: context [
 			len [integer!]
 	][
 		if null? pos [pos: lex/in-pos]
+		if lex/fun-ptr <> null [unless fire-event lex words/_open type null pos pos [exit]]
 		len: (as-integer lex/tail - lex/head) >> 4
 		p: as red-point! alloc-slot lex
 		set-type as cell! p TYPE_POINT					;-- use the slot for stack info
@@ -504,13 +505,14 @@ lexer: context [
 			throw-error lex s e ERR_MISSING
 		]
 		p: as red-point! lex/head - 1
+		if lex/fun-ptr <> null [
+			type: either all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][p/y >> 16][0]
+			unless fire-event lex words/_close type null s e [return 0]
+		]
 		stype: p/y >> 16
 		unless all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][do-error]
-		either type = -1 [
-			type: either final = -1 [stype][final]
-		][
-			if stype <> type [do-error]
-		]
+		either type = -1 [type: either final = -1 [stype][final]][if stype <> type [do-error]]
+		
 		len: (as-integer lex/tail - lex/head) >> 4
 		lex/tail: lex/head
 		lex/head: as cell! p - p/x
@@ -821,6 +823,8 @@ lexer: context [
 	scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][]
 	
 	scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][
+		if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [exit]]
+		
 		either lex/prev < --EXIT_STATES-- [
 			index: lex/prev + 1
 			index: as-integer prev-table/index
@@ -831,18 +835,13 @@ lexer: context [
 		]
 	]
 	
-	scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!]
-		/local
-			type [integer!]
-	][
+	scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local	type [integer!]][
 		type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK]
-		if lex/fun-ptr <> null [fire-event lex words/_open type null s e]
 		open-block lex type -1 null
 		lex/in-pos: e + 1								;-- skip delimiter
 	]
 
 	scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
-		if lex/fun-ptr <> null [fire-event lex words/_close TYPE_BLOCK null s e]
 		close-block lex s e TYPE_BLOCK -1
 		lex/in-pos: e + 1								;-- skip ]
 	]
@@ -851,7 +850,6 @@ lexer: context [
 		/local
 			blk	 [red-block!]
 	][
-		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_PAREN null s e]
 		if TYPE_MAP = close-block lex s e TYPE_PAREN -1 [
 			blk: as red-block! lex/tail - 1
 			map/make-at as cell! blk blk block/rs-length? blk
@@ -860,32 +858,27 @@ lexer: context [
 	]
 
 	scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e]
 		if zero? lex/mstr-nest [lex/mstr-s: s]
 		lex/mstr-nest: lex/mstr-nest + 1
 		lex/mstr-flags: lex/mstr-flags or flags
 		lex/entry: S_M_STRING
 		lex/in-pos: e + 1								;-- skip {
-		if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e]
 	]
 	
 	scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][
+		if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e]
 		lex/mstr-nest: lex/mstr-nest - 1
 
 		either zero? lex/mstr-nest [
-			if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e]
 			scan-string lex lex/mstr-s e lex/mstr-flags or flags
 			lex/mstr-s: null
 			lex/mstr-flags: 0
 			lex/entry: S_START
-			lex/in-pos: e + 1								;-- skip }
-			
-			if lex/fun-ptr <> null [
-				unless fire-event lex words/_load TYPE_STRING lex/tail - 1 s lex/in-pos [lex/tail: lex/tail - 1]
-			]
 		][
 			if e + 1 = lex/in-end [throw-error lex s e TYPE_STRING]
-			lex/in-pos: e + 1								;-- skip }
 		]
+		lex/in-pos: e + 1								;-- skip }
 	]
 	
 	scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][

From cc0669e5dd1f7abc6c746ec10724c2593900bf24 Mon Sep 17 00:00:00 2001
From: hiiamboris 
Date: Wed, 8 Jan 2020 23:32:16 +0300
Subject: [PATCH 0753/3432] FIX: missing calendar.reds in PR #4225

---
 build/includes.r | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build/includes.r b/build/includes.r
index 20d72188f7..17433017b2 100644
--- a/build/includes.r
+++ b/build/includes.r
@@ -186,6 +186,7 @@ write %build/bin/sources.r set-cache [
 					%base.reds
 					%button.reds
 					%camera.reds
+					%calendar.reds
 					%classes.reds
 					%comdlgs.reds
 					%direct2d.reds

From da3ef9a32761984de7de62ea66c704cd79eb4882 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 8 Jan 2020 23:18:38 +0100
Subject: [PATCH 0754/3432] FIX: minor code cleaning.

---
 runtime/lexer.reds | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 8e213b26ab..ea1fe00cfc 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -271,14 +271,6 @@ lexer: context [
 		LEX_INT_OVERFLOW: -5
 	]
 	
-	#enum events! [
-		EVT_SCAN										;-- after a token has been extracted
-		EVT_LOAD										;-- after a token has been converted to a Red value
-		EVT_OPEN										;-- when a nested any-block or map is opened
-		EVT_CLOSE										;-- when a nested any-block or map is closed
-		EVT_ERROR										;-- when a scanning error occurs
-	]
-	
 	state!: alias struct! [
 		next		[state!]							;-- link to next state! structure (recursive calls)
 		buffer		[red-value!]						;-- static or dynamic stash buffer (recursive calls)
@@ -305,17 +297,16 @@ lexer: context [
 	
 	scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]]
 
-	utf8-bufsize: 100'000
-	utf8-buffer: as byte-ptr! 0
-	scanners: as int-ptr! 0								;-- scan functions jump table (dynamically filled)
-	stash: as cell! 0									;-- special buffer for hatching any-blocks series
-	stash-size: 1000									;-- pre-allocated cells	number
-	root-state: as state! 0								;-- global entry point to state struct list
-	depth: 0											;-- recursive calls depth
+	utf8-bufsize:	100'000
+	utf8-buffer:	as byte-ptr! 0
+	scanners:		as int-ptr! 0						;-- scan functions jump table (dynamically filled)
+	stash:			as cell! 0							;-- special buffer for hatching any-blocks series
+	stash-size:		1000								;-- pre-allocated cells	number
+	root-state:		as state! 0							;-- global entry point to state struct list
+	depth:			0									;-- recursive calls depth
 	
 	min-integer: as byte-ptr! "-2147483648"				;-- used in scan-integer
 	flags-LG: C_FLAG_LESSER or C_FLAG_GREATER
-	
 
 	throw-error: func [lex [state!] s e [byte-ptr!] type [integer!]
 		/local

From 8968b651dc38a5d21f6db7470ac2600ec11af609 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Thu, 9 Jan 2020 12:09:34 +0800
Subject: [PATCH 0755/3432] FEAT: support old gradient pen/fill-pen

---
 modules/view/backends/windows/draw.reds | 133 +++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 2 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 271bb3bf94..844f16f0c3 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -1727,12 +1727,141 @@ OS-draw-brush-pattern: func [
 OS-draw-grad-pen-old: func [
 	ctx			[draw-ctx!]
 	type		[integer!]
-	mode		[integer!]
+	spread		[integer!]
 	offset		[red-pair!]
 	count		[integer!]					;-- number of the colors
 	brush?		[logic!]
+	/local
+		x		[integer!]
+		y		[integer!]
+		int		[red-integer!]
+		start	[integer!]
+		stop	[integer!]
+		n		[integer!]
+		rotate? [logic!]
+		scale?	[logic!]
+		sx		[float32!]
+		sy		[float32!]
+		p		[float!]
+		f		[red-float!]
+		angle	[float32!]
+		delta	[float!]
+		gstops	[D2D1_GRADIENT_STOP]
+		head	[red-value!]
+		next	[red-value!]
+		clr		[red-tuple!]
+		wrap	[integer!]
+		dc		[ID2D1DeviceContext]
+		this	[this!]
+		sc		[com-ptr! value]
+		brush	[com-ptr! value]
+		bthis	[this!]
+		ibrush	[ID2D1Brush]
+		gprops	[D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES value]
+		lprops	[D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES value]
+		unk		[IUnknown]
+		m		[D2D_MATRIX_3X2_F value]
+		t		[D2D_MATRIX_3X2_F value]
 ][
-	;Deprecated, no need to implement it.
+	x: offset/x
+	y: offset/y
+
+	int: as red-integer! offset + 1
+	start: int/value
+	int: int + 1
+	stop: int/value
+
+	n: 0
+	rotate?: no
+	scale?: no
+	sy: as float32! 1.0
+	while [
+		int: int + 1
+		n < 3
+	][								;-- fetch angle, scale-x and scale-y (optional)
+		switch TYPE_OF(int) [
+			TYPE_INTEGER	[p: as-float int/value]
+			TYPE_FLOAT		[f: as red-float! int p: f/value]
+			default			[break]
+		]
+		switch n [
+			0	[if p <> 0.0 [angle: as float32! p rotate?: yes]]
+			1	[if p <> 1.0 [sx: as float32! p scale?: yes]]
+			2	[if p <> 1.0 [sy: as float32! p scale?: yes]]
+		]
+		n: n + 1
+	]
+
+	gstops: grad-stops
+	n: count - 1
+	delta: as float! n
+	delta: 1.0 / delta
+	p: 0.0
+	head: as red-value! int
+	loop count [
+		clr: as red-tuple! either TYPE_OF(head) = TYPE_WORD [_context/get as red-word! head][head]
+		next: head + 1
+		to-dx-color clr/array1 as D3DCOLORVALUE (as int-ptr! gstops) + 1
+		if TYPE_OF(next) = TYPE_FLOAT [head: next f: as red-float! head p: f/value]
+		gstops/position: as float32! p
+		if next <> head [p: p + delta]
+		head: head + 1
+		gstops: gstops + 1
+	]
+
+	case [
+		spread = _pad		[wrap: 0]
+		spread = _repeat	[wrap: 1]
+		spread = _reflect	[wrap: 2]
+		true [wrap: 0]
+	]
+
+	this: as this! ctx/dc
+	dc: as ID2D1DeviceContext this/vtbl
+	dc/CreateGradientStopCollection this grad-stops count 0 wrap :sc
+	either type = linear [
+		lprops/startPoint.x: as float32! x + start
+		lprops/startPoint.y: as float32! y
+		lprops/endPoint.x: as float32! x + stop
+		lprops/endPoint.y: as float32! y
+		dc/CreateLinearGradientBrush this lprops null sc/value :brush
+	][
+		gprops/center.x: as float32! x
+		gprops/center.y: as float32! y
+		gprops/radius.x: as float32! stop - start
+		gprops/radius.y: gprops/radius.x
+		gprops/offset.x: as float32! 0.0
+		gprops/offset.x: as float32! 0.0
+		dc/CreateRadialGradientBrush this gprops null sc/value :brush
+	]
+
+	bthis: brush/value
+	ibrush: as ID2D1Brush bthis/vtbl
+	ibrush/GetTransform bthis :m
+	matrix2d/identity :m
+	if rotate? [
+		matrix2d/rotate :m angle F32_0 F32_0 :t ctx/pre-order?
+		copy-memory as byte-ptr! :m as byte-ptr! :t size? D2D_MATRIX_3X2_F
+	]
+	if scale? [
+		matrix2d/scale :m sx sy :t ctx/pre-order?
+		copy-memory as byte-ptr! :m as byte-ptr! :t size? D2D_MATRIX_3X2_F
+	]
+	ibrush/SetTransform bthis :m
+
+	COM_SAFE_RELEASE(unk sc/value)
+
+	either brush? [
+		COM_SAFE_RELEASE(unk ctx/brush)
+		ctx/brush: bthis
+		ctx/brush-type: DRAW_BRUSH_GRADIENT
+		ctx/brush-grad-type: type
+	][
+		COM_SAFE_RELEASE(unk ctx/pen)
+		ctx/pen: bthis
+		ctx/pen-type: DRAW_BRUSH_GRADIENT
+		ctx/pen-grad-type: type
+	]
 ]
 
 OS-draw-grad-pen: func [

From 34da8ed88ea09a5f9850d4b545f152fabb0e37a7 Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 9 Jan 2020 23:07:11 +0100
Subject: [PATCH 0756/3432] FIX: crash on calendar usage

---
 modules/view/backends/windows/calendar.reds | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index 40ac140c90..f1747af43a 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -40,10 +40,11 @@ with [platform][
 		month: WIN32_HIWORD(time/year-month)
 		day:   WIN32_HIWORD(time/week-day)
 		
-		current-msg/hWnd: handle
-		
-		slot: get-facet current-msg FACE_OBJ_DATA
-		date/make-at slot year month day 0.0 0 0 no no
+		unless null? current-msg [
+            current-msg/hWnd: handle
+            slot: get-facet current-msg FACE_OBJ_DATA
+            date/make-at slot year month day 0.0 0 0 no no
+        ]
 	]
 	
 	init-calendar: func [

From aae7d5358f4bdef2a70d91803079bdc8869067dd Mon Sep 17 00:00:00 2001
From: 9214 <9214@protonmail.com>
Date: Thu, 9 Jan 2020 23:07:58 +0100
Subject: [PATCH 0757/3432] FEAT: update copyright info

---
 modules/view/backends/windows/calendar.reds | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/calendar.reds b/modules/view/backends/windows/calendar.reds
index f1747af43a..2f78eef711 100644
--- a/modules/view/backends/windows/calendar.reds
+++ b/modules/view/backends/windows/calendar.reds
@@ -3,7 +3,7 @@ Red/System [
 	Author: "Vladimir Vasilyev"
 	File: 	%calendar.reds
 	Tabs: 	4
-	Rights: "Copyright (C) 2019 Red Foundation. All rights reserved."
+	Rights: "Copyright (C) 2019-2020 Red Foundation. All rights reserved."
 	License: {
 		Distributed under the Boost Software License, Version 1.0.
 		See https://github.com/red/red/blob/master/BSL-License.txt

From 49d93e3dd6e559867570149009d644a67001936f Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Fri, 10 Jan 2020 15:24:54 +0800
Subject: [PATCH 0758/3432] FIX: issue #4212 (text face not rendering properly)

---
 modules/view/backends/gtk3/font.reds | 53 ++++++++++++++++++++++++----
 modules/view/backends/gtk3/gtk.reds  |  8 +++++
 modules/view/backends/gtk3/gui.reds  |  7 +++-
 3 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds
index 61186f14a2..fd532a5129 100644
--- a/modules/view/backends/gtk3/font.reds
+++ b/modules/view/backends/gtk3/font.reds
@@ -125,6 +125,34 @@ create-trans-css: func [
 	css
 ]
 
+create-background-css: func [
+	color		[red-tuple!]
+	return:		[GString!]
+	/local
+		css		[GString!]
+		rgb		[integer!]
+		alpha?	[integer!]
+		r		[integer!]
+		g		[integer!]
+		b		[integer!]
+		a		[float!]
+][
+	css: g_string_sized_new 64
+	g_string_append css "* {"
+	alpha?: 0
+	rgb: get-color-int color :alpha?
+	b: rgb >> 16 and FFh
+	g: rgb >> 8 and FFh
+	r: rgb and FFh
+	a: 1.0
+	if alpha? = 1 [
+		a: (as float! 255 - (rgb >>> 24)) / 255.0
+	]
+	g_string_append_printf [css { background-color: rgba(%d, %d, %d, %.3f);} r g b a]
+	g_string_append css "}"
+	css
+]
+
 set-label-attrs: func [
 	label		[handle!]
 	font		[red-object!]
@@ -154,29 +182,33 @@ set-label-para: func [
 	hsym		[integer!]
 	vsym		[integer!]
 	wrap?		[logic!]
+	/local
+		f		[float32!]
 ][
 	case [
 		hsym = _para/left [
-			gtk_label_set_justify label GTK_JUSTIFY_LEFT
+			f: as float32! 0.0
 		]
 		hsym = _para/right [
-			gtk_label_set_justify label GTK_JUSTIFY_RIGHT
+			f: as float32! 1.0
 		]
 		true [
-			gtk_label_set_justify label GTK_JUSTIFY_CENTER
+			f: as float32! 0.5
 		]
 	]
+	gtk_label_set_xalign label f
 	case [
 		vsym = _para/top [
-			gtk_widget_set_halign label GTK_ALIGN_START
+			f: as float32! 0.0
 		]
 		vsym = _para/bottom [
-			gtk_widget_set_halign label GTK_ALIGN_END
+			f: as float32! 1.0
 		]
 		true [
-			gtk_widget_set_halign label GTK_ALIGN_CENTER
+			f: as float32! 0.5
 		]
 	]
+	gtk_label_set_yalign label f
 	gtk_label_set_line_wrap label wrap?
 ]
 
@@ -734,6 +766,7 @@ set-font: func [
 		newC?	[logic!]
 		type	[red-word!]
 		sym		[integer!]
+		layout	[handle!]
 		pvalues	[red-value!]
 		wrap?	[logic!]
 		hsym	[integer!]
@@ -759,6 +792,14 @@ set-font: func [
 	]
 	type: as red-word! values + FACE_OBJ_TYPE
 	sym: symbol/resolve type/symbol
+	layout: get-face-layout widget values sym
+	if all [
+		sym = text
+		layout <> widget
+		TYPE_OF(color) = TYPE_TUPLE
+	][
+		apply-css-styles layout create-background-css color
+	]
 	either TYPE_OF(para) = TYPE_OBJECT [
 		pvalues: object/get-values para
 		wrap?: get-para-wrap pvalues
diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds
index 89d232ea0f..43b860e7b5 100644
--- a/modules/view/backends/gtk3/gtk.reds
+++ b/modules/view/backends/gtk3/gtk.reds
@@ -1805,6 +1805,14 @@ GPtrArray!: alias struct! [
 			widget		[handle!]
 			label		[c-string!]
 		]
+		gtk_label_set_xalign: "gtk_label_set_xalign" [
+			widget		[handle!]
+			xalign		[float32!]
+		]
+		gtk_label_set_yalign: "gtk_label_set_yalign" [
+			widget		[handle!]
+			yalign		[float32!]
+		]
 		gtk_label_set_justify: "gtk_label_set_justify" [
 			widget		[handle!]
 			justify		[integer!]
diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds
index 058dd5ba59..7420341794 100644
--- a/modules/view/backends/gtk3/gui.reds
+++ b/modules/view/backends/gtk3/gui.reds
@@ -1744,7 +1744,12 @@ OS-make-view: func [
 		]
 	]
 
-	unless null? container [SET-CONTAINER(widget container)]
+	unless null? container [
+		SET-CONTAINER(widget container)
+		if sym = text [
+			make-styles-provider container
+		]
+	]
 	;-- store the face value in the extra space of the window struct
 	assert TYPE_OF(face) = TYPE_OBJECT
 	store-face-to-obj widget face

From 4e54f66b4b617a26c96b55c0103f54ded4a70639 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Fri, 10 Jan 2020 17:38:20 +0800
Subject: [PATCH 0759/3432] FEAT: first support calendar for gtk3

---
 modules/view/backends/gtk3/events.reds   |  3 ++
 modules/view/backends/gtk3/gtk.reds      | 44 +++++++++++++++++++++++-
 modules/view/backends/gtk3/gui.reds      |  3 ++
 modules/view/backends/gtk3/handlers.reds | 21 +++++++++++
 4 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds
index 0e2753a74f..60ae4abaf4 100644
--- a/modules/view/backends/gtk3/events.reds
+++ b/modules/view/backends/gtk3/events.reds
@@ -1035,6 +1035,9 @@ connect-widget-events: func [
 		sym = progress [
 			0
 		]
+		sym = calendar [
+			gobj_signal_connect(widget "day-selected" :calendar-changed widget)
+		]
 		sym = area [
 			buffer: gtk_text_view_get_buffer widget
 			gobj_signal_connect(buffer "changed" :area-changed widget)
diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds
index 43b860e7b5..a5eb11ff57 100644
--- a/modules/view/backends/gtk3/gtk.reds
+++ b/modules/view/backends/gtk3/gtk.reds
@@ -1600,9 +1600,51 @@ GPtrArray!: alias struct! [
 			prop		[c-string!]
 			value		[int-ptr!]
 		]
+		gtk_calendar_new: "gtk_calendar_new" [
+			return:		[handle!]
+		]
+		gtk_calendar_select_month: "gtk_calendar_select_month" [
+			calendar	[handle!]
+			month		[integer!]
+			year		[integer!]
+		]
+		gtk_calendar_select_day: "gtk_calendar_select_day" [
+			calendar	[handle!]
+			day			[integer!]
+		]
+		gtk_calendar_mark_day: "gtk_calendar_mark_day" [
+			calendar	[handle!]
+			day			[integer!]
+		]
+		gtk_calendar_unmark_day: "gtk_calendar_unmark_day" [
+			calendar	[handle!]
+			day			[integer!]
+		]
+		gtk_calendar_get_day_is_marked: "gtk_calendar_get_day_is_marked" [
+			calendar	[handle!]
+			day			[integer!]
+			return:		[logic!]
+		]
+		gtk_calendar_clear_marks: "gtk_calendar_clear_marks" [
+			calendar	[handle!]
+		]
+		gtk_calendar_get_display_options: "gtk_calendar_get_display_options" [
+			calendar	[handle!]
+			return:		[integer!]
+		]
+		gtk_calendar_set_display_options: "gtk_calendar_set_display_options" [
+			calendar	[handle!]
+			flags		[integer!]
+		]
+		gtk_calendar_get_date: "gtk_calendar_get_date" [
+			calendar	[handle!]
+			year		[int-ptr!]
+			month		[int-ptr!]
+			day			[int-ptr!]
+		]
 		gtk_frame_new: "gtk_frame_new" [
 			label		[c-string!]
-			return: 	[handle!]
+			return:		[handle!]
 		]
 		gtk_frame_set_label: "gtk_frame_set_label" [
 			frame		[handle!]
diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds
index 7420341794..7b8b0773c5 100644
--- a/modules/view/backends/gtk3/gui.reds
+++ b/modules/view/backends/gtk3/gui.reds
@@ -1654,6 +1654,9 @@ OS-make-view: func [
 			widget: gtk_layout_new null null
 			gtk_layout_set_size widget size/x size/y
 		]
+		sym = calendar [
+			widget: gtk_calendar_new
+		]
 		sym = slider [
 			vertical?: size/y > size/x
 			widget: gtk_scale_new_with_range vertical? 0.0 100.0 1.0
diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds
index 60705b51d2..26a35d054d 100644
--- a/modules/view/backends/gtk3/handlers.reds
+++ b/modules/view/backends/gtk3/handlers.reds
@@ -955,3 +955,24 @@ menu-item-activate: func [
 		make-event widget key EVT_MENU
 	]
 ]
+
+calendar-changed: func [
+	[cdecl]
+	evbox		[handle!]
+	widget		[handle!]
+	/local
+		face	[red-object!]
+		values	[red-value!]
+		data	[red-value!]
+		year	[integer!]
+		month	[integer!]
+		day		[integer!]
+][
+	face: get-face-obj widget
+	values: object/get-values face
+	data: as red-value! values + FACE_OBJ_DATA
+	year: 0 month: 0 day: 0
+	gtk_calendar_get_date widget :year :month :day
+	date/make-at data year month + 1 day 0.0 0 0 no no
+	make-event widget 0 EVT_CHANGE
+]

From 1594865b662bacb4e3af17ef518edfabe1567e0d Mon Sep 17 00:00:00 2001
From: loziniak 
Date: Fri, 3 Jan 2020 12:25:23 +0100
Subject: [PATCH 0760/3432] FIX: organize libRedRT exports for GTK branch

---
 system/utils/libRedRT-exports.r | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r
index e1d64402d9..5b65e75294 100644
--- a/system/utils/libRedRT-exports.r
+++ b/system/utils/libRedRT-exports.r
@@ -391,7 +391,6 @@
 	red/string/to-hex
 	red/integer/make-in
 	red/logic/make-in
-	red/OS-image/to-pixbuf
 	red/string/make-at
 	red/unicode/load-utf8-buffer
 	red/unicode/utf8-next-char
@@ -405,12 +404,10 @@
 	red/block/select-word
 	red/block/find
 	red/_series/remove
-	red/OS-image/load-pixbuf
 	red/image/init-image
 	red/OS-image/lock-bitmap
 	red/OS-image/get-data
 	red/OS-image/unlock-bitmap
-	red/OS-image/buffer-argb-to-abgr
 	red/ownership/check
 	red/report
 	red/_context/set

From 0956cb20a12b4723068dfcf1ec6b01d06ce0bca0 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Fri, 10 Jan 2020 16:10:48 +0100
Subject: [PATCH 0761/3432] FEAT: properly support draw on image! in D2D.

---
 modules/view/backends/windows/direct2d.reds |   3 +-
 modules/view/backends/windows/draw.reds     |  31 +-
 runtime/platform/image-wic.reds             | 458 ++++++++++++--------
 3 files changed, 291 insertions(+), 201 deletions(-)

diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index c011cbb711..a499ace375 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -43,6 +43,7 @@ IID_IDWriteFactory:		 [B859EE5Ah 4B5BD838h DC1AE8A2h 48DB937Dh]
 IID_IDXGIFactory2:		 [50C83A1Ch 4C48E072h 3036B087h D0A636FAh]
 IID_IDCompositionDevice: [C37EA93Ah 450DE7AAh 46976FB1h F30704CBh]
 IID_IDGdiInterop: 		 [E0DB51C3h 4BAE6F77h 75E4D5B3h 3858B309h]
+IID_ID2D1DeviceContext:	 [E8F7FE7Ah 466D191Ch 569795ADh 98A9BD78h]
 CLSID_D2D1UnPremultiply: [FB9AC489h 41EDAD8Dh 63BB9999h F710D147h]
 
 D2D1_FACTORY_OPTIONS: alias struct! [
@@ -629,7 +630,7 @@ ID2D1Factory: alias struct! [
 	CreatePathGeometry				[function! [this [this!] pathGeometry [ptr-ptr!] return: [integer!]]]
 	CreateStrokeStyle				[function! [this [this!] props [D2D1_STROKE_STYLE_PROPERTIES] dashes [float32-ptr!] count [integer!] style [ptr-ptr!] return: [integer!]]]
 	CreateDrawingStateBlock			[function! [this [this!] desc [this!] param [this!] block [ptr-ptr!] return: [integer!]]]
-	CreateWicBitmapRenderTarget		[integer!]
+	CreateWicBitmapRenderTarget		[function! [this [this!] target [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] bmp [com-ptr!] return: [integer!]]]
 	CreateHwndRenderTarget			[function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] hwndProperties [D2D1_HWND_RENDER_TARGET_PROPERTIES] target [ptr-ptr!] return: [integer!]]]
 	CreateDxgiSurfaceRenderTarget	[integer!]
 	CreateDCRenderTarget			[function! [this [this!] properties [D2D1_RENDER_TARGET_PROPERTIES] target [int-ptr!] return: [integer!]]]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 844f16f0c3..c660158dcf 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -174,12 +174,14 @@ draw-begin: func [
 		red-img [red-image!]
 		pos		[red-pair! value]
 		pos2	[red-pair!]
-		bmp		[ptr-value!]
+		rt		[com-ptr! value]
 		wic-bmp	[this!]
 		IUnk	[IUnknown]
 		gdi		[com-ptr! value]
 		pp		[com-ptr!]
 		pdc		[this!]
+		props	[D2D1_RENDER_TARGET_PROPERTIES value]
+		factory [ID2D1Factory]
 ][
 	zero-memory as byte-ptr! ctx size? draw-ctx!
 	ctx/pen-width:	as float32! 1.0
@@ -194,19 +196,27 @@ draw-begin: func [
 
 	either hWnd <> null [
 		target: get-hwnd-render-target hWnd on-graphic?
+		dc/SetTarget this target/bitmap
+		dc/setDpi this dpi-x dpi-y
 	][
-		wic-bmp: OS-image/to-pbgra img
+		wic-bmp: OS-image/get-wicbitmap img
 		;-- create a bitmap target
 		target: as render-target! alloc0 size? render-target!
 		target/brushes: as int-ptr! allocate D2D_MAX_BRUSHES * 2 * size? int-ptr!
-		if 0 <> dc/CreateBitmapFromWicBitmap2 this wic-bmp null bmp [
+
+		zero-memory as byte-ptr! :props size? D2D1_RENDER_TARGET_PROPERTIES
+		factory: as ID2D1Factory d2d-factory/vtbl
+		if 0 <> factory/CreateWicBitmapRenderTarget d2d-factory wic-bmp :props :rt [
 			;TBD error!!!
-			probe "CreateBitmapFromWicBitmap2 failed in draw-begin"
+			probe "CreateWicBitmapRenderTarget failed in draw-begin"
 			return ctx
 		]
 		ctx/image: img/node
-		target/bitmap: as this! bmp/value
-		COM_SAFE_RELEASE(IUnk wic-bmp)
+		this: rt/value
+		dc: as ID2D1DeviceContext this/vtbl
+		dc/QueryInterface this IID_ID2D1DeviceContext :rt	;-- Query ID2D1DeviceContext interface
+		this: rt/value
+		dc: as ID2D1DeviceContext this/vtbl
 	]
 	ctx/dc: as ptr-ptr! this
 	ctx/target: as int-ptr! target
@@ -219,7 +229,6 @@ draw-begin: func [
 	]
 
 	dc/SetTextAntialiasMode this 1				;-- ClearType
-	dc/SetTarget this target/bitmap
 	dc/SetAntialiasMode this 0					;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
 
 	matrix2d/identity m
@@ -285,7 +294,7 @@ draw-end: func [
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
 	dc/EndDraw this null null
-	dc/SetTarget this null
+	if hWnd <> null [dc/SetTarget this null]
 
 	release-ctx ctx		;@@ Possible improvement: cache resources for window target
 
@@ -312,8 +321,8 @@ draw-end: func [
 			]
 		]
 	][						;-- image! target
-		;TBD save rt/bitmap to ctx/image
 		d2d-release-target rt
+		dc/Release this
 	]
 ]
 
@@ -1496,7 +1505,7 @@ OS-draw-image: func [
 ][
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
-	ithis: OS-image/to-pbgra image
+	ithis: OS-image/get-handle image
 	IB: as IUnknown ithis/vtbl
 	dc/CreateBitmapFromWicBitmap2 this ithis null :bmp
 	bthis: as this! bmp/value
@@ -1684,7 +1693,7 @@ OS-draw-brush-bitmap: func [
 	height: OS-image/height? img/node
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
-	ithis: OS-image/to-pbgra img
+	ithis: OS-image/get-handle img
 	dc/CreateBitmapFromWicBitmap2 this ithis null :bmp
 	_OS-draw-brush-bitmap ctx as this! bmp/value width height crop-1 crop-2 mode brush?
 	COM_SAFE_RELEASE(unk ithis)
diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds
index 6ccb284595..69bf3fbb8c 100644
--- a/runtime/platform/image-wic.reds
+++ b/runtime/platform/image-wic.reds
@@ -20,6 +20,11 @@ Red/System [
 
 #define GMEM_MOVEABLE	2
 
+#define IMG_NODE_HAS_BUFFER		1
+#define IMG_NODE_MODIFIED		2
+#define IMG_NODE_GC_MARKED		4
+#define IMG_NODE_WICBITMAP		8
+
 OS-image: context [
 
 	wic-factory: as this! 0
@@ -40,6 +45,17 @@ OS-image: context [
 		h	[integer!]
 	]
 
+	;-- flags bits layout
+	;	0: if set, has an editable buffer with unpremultiply data
+	;	1: if set, the editable buffer has been modified
+	;	2: if set, the image has been marked by the GC
+	img-node!: alias struct! [
+		flags	[integer!]
+		handle	[this!]
+		buffer	[this!]
+		size	[integer!]
+	]
+
 	#import [
 		"kernel32.dll" stdcall [
 			GlobalAlloc: "GlobalAlloc" [
@@ -91,31 +107,31 @@ OS-image: context [
 		QueryInterface				[QueryInterface!]
 		AddRef						[AddRef!]
 		Release						[Release!]
-		CreateDecoderFromFilename	[function! [this [this!] file [c-string!] vendor [int-ptr!] access [integer!] opts [integer!] dec [interface!] return: [integer!]]]
-		CreateDecoderFromStream		[function! [this [this!] pIStread [int-ptr!] vendor [int-ptr!] opts [integer!] dec [interface!] return: [integer!]]]
-		CreateDecoderFromFileHandle	[function! [this [this!] hFile [int-ptr!] vendor [int-ptr!] opts [integer!] dec [interface!] return: [integer!]]]
-		CreateComponentInfo			[function! [this [this!] clsid [int-ptr!] ppIInfo [interface!] return: [integer!]]]
-		CreateDecoder				[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [interface!] return: [integer!]]]
-		CreateEncoder				[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [interface!] return: [integer!]]]
-		CreatePalette				[function! [this [this!] ppIPal [interface!] return: [integer!]]]
-		CreateFormatConverter		[function! [this [this!] ppIFormat [interface!] return: [integer!]]]
-		CreateBitmapScaler			[function! [this [this!] ppIScaler [interface!] return: [integer!]]]
-		CreateBitmapClipper			[function! [this [this!] ppIClipper [interface!] return: [integer!]]]
-		CreateBitmapFlipRotator		[function! [this [this!] ppIFlip [interface!] return: [integer!]]]
-		CreateStream				[function! [this [this!] ppIStream [interface!] return: [integer!]]]
-		CreateColorContext			[function! [this [this!] ppIColorCtx [interface!] return: [integer!]]]
-		CreateColorTransformer		[function! [this [this!] ppIColorTrans [interface!] return: [integer!]]]
-		CreateBitmap				[function! [this [this!] width [integer!] height [integer!] format [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]]
-		CreateBitmapFromSource		[function! [this [this!] piBitmapSource [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]]
-		CreateBitmapFromSourceRect	[function! [this [this!] piBitmapSource [int-ptr!] x [integer!] y [integer!] w [integer!] h [integer!] ppIBitmap [interface!] return: [integer!]]]
-		CreateBitmapFromMemory		[function! [this [this!] w [integer!] h [integer!] format [integer!] stride [integer!] buffer-size [integer!] buffer [byte-ptr!] ppIBitmap [interface!] return: [integer!]]]
-		CreateBitmapFromHBITMAP		[function! [this [this!] hBitmap [int-ptr!] hPalette [int-ptr!] opts [integer!] ppIBitmap [interface!] return: [integer!]]]
-		CreateBitmapFromHICON		[function! [this [this!] hIcon [int-ptr!] ppIBitmap [interface!] return: [integer!]]]
-		CreateComponentEnumerator	[function! [this [this!] types [integer!] opts [integer!] ppIEnum [interface!] return: [integer!]]]
+		CreateDecoderFromFilename	[function! [this [this!] file [c-string!] vendor [int-ptr!] access [integer!] opts [integer!] dec [com-ptr!] return: [integer!]]]
+		CreateDecoderFromStream		[function! [this [this!] pIStread [int-ptr!] vendor [int-ptr!] opts [integer!] dec [com-ptr!] return: [integer!]]]
+		CreateDecoderFromFileHandle	[function! [this [this!] hFile [int-ptr!] vendor [int-ptr!] opts [integer!] dec [com-ptr!] return: [integer!]]]
+		CreateComponentInfo			[function! [this [this!] clsid [int-ptr!] ppIInfo [com-ptr!] return: [integer!]]]
+		CreateDecoder				[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [com-ptr!] return: [integer!]]]
+		CreateEncoder				[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIDec [com-ptr!] return: [integer!]]]
+		CreatePalette				[function! [this [this!] ppIPal [com-ptr!] return: [integer!]]]
+		CreateFormatConverter		[function! [this [this!] ppIFormat [com-ptr!] return: [integer!]]]
+		CreateBitmapScaler			[function! [this [this!] ppIScaler [com-ptr!] return: [integer!]]]
+		CreateBitmapClipper			[function! [this [this!] ppIClipper [com-ptr!] return: [integer!]]]
+		CreateBitmapFlipRotator		[function! [this [this!] ppIFlip [com-ptr!] return: [integer!]]]
+		CreateStream				[function! [this [this!] ppIStream [com-ptr!] return: [integer!]]]
+		CreateColorContext			[function! [this [this!] ppIColorCtx [com-ptr!] return: [integer!]]]
+		CreateColorTransformer		[function! [this [this!] ppIColorTrans [com-ptr!] return: [integer!]]]
+		CreateBitmap				[function! [this [this!] width [integer!] height [integer!] format [int-ptr!] opts [integer!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateBitmapFromSource		[function! [this [this!] piBitmapSource [this!] opts [integer!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateBitmapFromSourceRect	[function! [this [this!] piBitmapSource [this!] x [integer!] y [integer!] w [integer!] h [integer!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateBitmapFromMemory		[function! [this [this!] w [integer!] h [integer!] format [integer!] stride [integer!] buffer-size [integer!] buffer [byte-ptr!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateBitmapFromHBITMAP		[function! [this [this!] hBitmap [int-ptr!] hPalette [int-ptr!] opts [integer!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateBitmapFromHICON		[function! [this [this!] hIcon [int-ptr!] ppIBitmap [com-ptr!] return: [integer!]]]
+		CreateComponentEnumerator	[function! [this [this!] types [integer!] opts [integer!] ppIEnum [com-ptr!] return: [integer!]]]
 		CreateFastMetadataEncoderFromDecoder		[integer!]
 		CreateFastMetadataEncoderFromFrameDecode	[integer!]
-		CreateQueryWriter			[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIQueryWriter [interface!] return: [integer!]]]
-		CreateQueryWriterFromReader	[function! [this [this!] pIQueryReader [int-ptr!] vendor [int-ptr!] ppIQueryWriter [interface!] return: [integer!]]]
+		CreateQueryWriter			[function! [this [this!] format [int-ptr!] vendor [int-ptr!] ppIQueryWriter [com-ptr!] return: [integer!]]]
+		CreateQueryWriterFromReader	[function! [this [this!] pIQueryReader [int-ptr!] vendor [int-ptr!] ppIQueryWriter [com-ptr!] return: [integer!]]]
 	]
 
 	IWICBitmapDecoder: alias struct! [
@@ -132,7 +148,7 @@ OS-image: context [
 		GetColorContexts			[function! [this [this!] count [integer!] ppIColorCtx [ptr-ptr!] pCount [int-ptr!] return: [integer!]]]
 		GetThumbnail				[function! [this [this!] ppIThumbnail [ptr-ptr!] return: [integer!]]]
 		GetFrameCount				[function! [this [this!] pCount [int-ptr!] return: [integer!]]]
-		GetFrame					[function! [this [this!] index [integer!] ppIBitmapFrame [interface!] return: [integer!]]]
+		GetFrame					[function! [this [this!] index [integer!] ppIBitmapFrame [com-ptr!] return: [integer!]]]
 	]
 
 	IWICBitmapFrameDecode: alias struct! [
@@ -144,9 +160,9 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		GetMetadataQueryReader		[function! [this [this!] ppIMetaReader [interface!] return: [integer!]]]
-		GetColorContexts			[function! [this [this!] count [integer!] ppIColorCtx [interface!] pCount [int-ptr!] return: [integer!]]]
-		GetThumbnail				[function! [this [this!] ppIThumbnail [interface!] return: [integer!]]]
+		GetMetadataQueryReader		[function! [this [this!] ppIMetaReader [com-ptr!] return: [integer!]]]
+		GetColorContexts			[function! [this [this!] count [integer!] ppIColorCtx [com-ptr!] pCount [int-ptr!] return: [integer!]]]
+		GetThumbnail				[function! [this [this!] ppIThumbnail [com-ptr!] return: [integer!]]]
 	]
 
 	IWICBitmapFrameEncode: alias struct! [
@@ -161,7 +177,7 @@ OS-image: context [
 		SetPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		SetThumbnail				[function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]]
 		WritePixels					[function! [this [this!] count [integer!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		WriteSource					[function! [this [this!] piBitmapSource [int-ptr!] prc [RECT!] return: [integer!]]]
+		WriteSource					[function! [this [this!] piBitmapSource [this!] prc [RECT!] return: [integer!]]]
 		Commit						[function! [this [this!] return: [integer!]]]
 		GetMetadataQueryWriter		[function! [this [this!] ppIMetaReader [ptr-ptr!] return: [integer!]]]
 	]
@@ -170,14 +186,14 @@ OS-image: context [
 		QueryInterface				[QueryInterface!]
 		AddRef						[AddRef!]
 		Release						[Release!]
-		Initialize					[function! [this [this!] pIStream [int-ptr!] opts [integer!] return: [integer!]]]
+		Initialize					[function! [this [this!] pIStream [this!] opts [integer!] return: [integer!]]]
 		GetContainerFormat			[function! [this [this!] format [int-ptr!] return: [integer!]]]
 		GetEncoderInfo				[function! [this [this!] ppIEncInfo [ptr-ptr!] return: [integer!]]]
 		SetColorContexts			[function! [this [this!] count [integer!] ppIColorCtx [ptr-ptr!] return: [integer!]]]
 		SetPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		SetThumbnail				[function! [this [this!] pIThumbnail [int-ptr!] return: [integer!]]]
 		SetPreview					[function! [this [this!] pIPreview [int-ptr!] return: [integer!]]]
-		CreateNewFrame				[function! [this [this!] ppIFrameEnc [interface!] ppIEncOpts [int-ptr!] return: [integer!]]]
+		CreateNewFrame				[function! [this [this!] ppIFrameEnc [com-ptr!] ppIEncOpts [int-ptr!] return: [integer!]]]
 		Commit						[function! [this [this!] return: [integer!]]]
 		GetMetadataQueryWriter		[function! [this [this!] ppIMetaWriter [ptr-ptr!] return: [integer!]]]
 	]
@@ -191,7 +207,7 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		Initialize					[function! [this [this!] pISource [int-ptr!] format [int-ptr!] dither [integer!] pIPalette [int-ptr!] percent [float!] trans [integer!] return: [integer!]]]
+		Initialize					[function! [this [this!] pISource [this!] format [int-ptr!] dither [integer!] pIPalette [int-ptr!] percent [float!] trans [integer!] return: [integer!]]]
 		CanConvert					[function! [this [this!] srcFormat [int-ptr!] dstFormat [int-ptr!] return: [integer!]]]
 	]
 
@@ -204,7 +220,7 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		Initialize					[function! [this [this!] pISource [int-ptr!] w [integer!] h [integer!] mode [integer!] return: [integer!]]]
+		Initialize					[function! [this [this!] pISource [this!] w [integer!] h [integer!] mode [integer!] return: [integer!]]]
 	]
 
 	IWICBitmap: alias struct! [
@@ -216,7 +232,7 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		Lock						[function! [this [this!] prcLock [RECT!] flags [integer!] ppILock [interface!] return: [integer!]]]
+		Lock						[function! [this [this!] prcLock [RECT!] flags [integer!] ppILock [com-ptr!] return: [integer!]]]
 		SetPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		SetResolution				[function! [this [this!] x [float!] y [float!] return: [integer!]]]
 	]
@@ -240,7 +256,7 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		Initialize					[function! [this [this!] pISource [int-ptr!] w [integer!] h [integer!] mode [integer!] return: [integer!]]]
+		Initialize					[function! [this [this!] pISource [this!] w [integer!] h [integer!] mode [integer!] return: [integer!]]]
 	]
 
 	IWICBitmapClipper: alias struct! [
@@ -252,7 +268,116 @@ OS-image: context [
 		GetResolution				[function! [this [this!] pX [float-ptr!] pY [float-ptr!] return: [integer!]]]
 		CopyPalette					[function! [this [this!] pIPalette [int-ptr!] return: [integer!]]]
 		CopyPixels					[function! [this [this!] prc [int-ptr!] stride [integer!] size [integer!] buffer [byte-ptr!] return: [integer!]]]
-		Initialize					[function! [this [this!] pISource [int-ptr!] rec [RECT!] return: [integer!]]]
+		Initialize					[function! [this [this!] pISource [this!] rec [RECT!] return: [integer!]]]
+	]
+
+	make-node: func [
+		handle	[this!]
+		buffer	[this!]
+		flags	[integer!]
+		width	[integer!]
+		height	[integer!]
+		return: [node!]
+		/local
+			inode	[img-node!]
+	][
+		inode: as img-node! allocate size? img-node!
+		inode/flags: flags
+		inode/handle: handle
+		inode/buffer: buffer
+		inode/size: height << 16 or width
+		as node! inode
+	]
+
+	to-bgra: func [
+		image		[this!]
+		premul?		[logic!]
+		return:		[this!]
+		/local
+			IFAC	[IWICImagingFactory]
+			iconv	[com-ptr! value]
+			cthis	[this!]
+			conv	[IWICFormatConverter]
+			fmt		[int-ptr!]
+	][
+		fmt: as int-ptr! either premul? [
+			GUID_WICPixelFormat32bppPBGRA
+		][
+			GUID_WICPixelFormat32bppBGRA
+		]
+		IFAC: as IWICImagingFactory wic-factory/vtbl
+		IFAC/CreateFormatConverter wic-factory :iconv
+		cthis: iconv/value
+		conv: as IWICFormatConverter cthis/vtbl
+		conv/Initialize cthis image fmt 0 null 0.0 0
+		cthis
+	]
+
+	get-handle: func [
+		img			[red-image!]
+		return:		[this!]
+		/local
+			inode	[img-node!]
+			unk		[IUnknown]
+			h		[this!]
+	][
+		inode: as img-node! img/node
+		h: inode/handle
+		if any [null? h inode/flags and IMG_NODE_MODIFIED <> 0][
+			if h <> null [COM_SAFE_RELEASE(unk h)]
+			h: to-bgra inode/buffer yes
+			inode/handle: h
+			inode/flags: IMG_NODE_HAS_BUFFER
+		]
+		h
+	]
+
+	get-wicbitmap: func [
+		img			[red-image!]
+		return:		[this!]
+		/local
+			inode	[img-node!]
+			unk		[IUnknown]
+			h		[this!]
+			IFAC	[IWICImagingFactory]
+			bitmap	[com-ptr! value]
+	][
+		inode: as img-node! img/node
+		h: get-handle img
+		either inode/flags and IMG_NODE_WICBITMAP <> 0 [h][
+			IFAC: as IWICImagingFactory wic-factory/vtbl
+			IFAC/CreateBitmapFromSource wic-factory h WICBitmapCacheOnLoad :bitmap
+			inode/handle: bitmap/value
+			if inode/buffer <> null [
+				COM_SAFE_RELEASE(unk inode/buffer)
+				inode/flags: IMG_NODE_WICBITMAP
+			]
+			bitmap/value
+		]
+	]
+
+	get-buffer: func [
+		img			[node!]
+		return:		[this!]
+		/local
+			inode	[img-node!]
+			unk		[IUnknown]
+			IFAC	[IWICImagingFactory]
+			h		[this!]
+			bitmap	[com-ptr! value]
+	][
+		inode: as img-node! img
+		h: inode/buffer
+		if inode/flags and IMG_NODE_HAS_BUFFER = 0 [
+			h: to-bgra inode/handle no
+			IFAC: as IWICImagingFactory wic-factory/vtbl
+			IFAC/CreateBitmapFromSource wic-factory h 0 :bitmap
+			COM_SAFE_RELEASE(unk h)
+			h: bitmap/value
+			inode/buffer: h
+			inode/flags: IMG_NODE_HAS_BUFFER
+		]
+		h
 	]
 
 	init: func [
@@ -276,7 +401,7 @@ OS-image: context [
 
 		hr: CoCreateInstance as int-ptr! CLSID_WICImagingFactory 0 CLSCTX_INPROC_SERVER as int-ptr! IID_IWICImagingFactory :II
 		if hr = 0 [
-			wic-factory: as this! II/ptr
+			wic-factory: II/ptr
 		]
 	]
 
@@ -326,14 +451,14 @@ OS-image: context [
 		/local
 			IFAC	[IWICImagingFactory]
 			size	[integer!]
-			bmp		[interface! value]
+			bmp		[com-ptr! value]
 			ret		[integer!]
 	][
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		if stride = 0 [stride: width * 4]
 		size: stride * height
 		ret: IFAC/CreateBitmapFromMemory wic-factory width height as integer! GUID_WICPixelFormat32bppBGRA stride size scan0 :bmp
-		bitmap/value: as integer! bmp/ptr
+		bitmap/value: as integer! make-node null bmp/value 3 width height
 		ret
 	]
 
@@ -350,32 +475,20 @@ OS-image: context [
 		handle		[int-ptr!]
 		return:		[integer!]
 		/local
-			this	[this!]
-			IB		[IWICBitmap]
-			w		[integer!]
-			h		[integer!]
+			inode	[img-node!]
 	][
-		this: as this! handle
-		IB: as IWICBitmap this/vtbl
-		w: 0 h: 0
-		IB/GetSize this :w :h
-		w
+		inode: as img-node! handle
+		IMAGE_WIDTH(inode/size)
 	]
 
 	height?: func [
 		handle		[int-ptr!]
 		return:		[integer!]
 		/local
-			this	[this!]
-			IB		[IWICBitmap]
-			w		[integer!]
-			h		[integer!]
+			inode	[img-node!]
 	][
-		this: as this! handle
-		IB: as IWICBitmap this/vtbl
-		w: 0 h: 0
-		IB/GetSize this :w :h
-		h
+		inode: as img-node! handle
+		IMAGE_HEIGHT(inode/size)
 	]
 
 	lock-bitmap: func [
@@ -387,17 +500,22 @@ OS-image: context [
 			IB		[IWICBitmap]
 			flag	[integer!]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
+			inode	[img-node!]
 	][
-		this: as this! img/node
+		this: get-buffer img/node
 		IB: as IWICBitmap this/vtbl
-		flag: either write? [WICBitmapLockWrite][WICBitmapLockRead]
+		flag: either write? [
+			inode: as img-node! img/node
+			inode/flags: inode/flags or IMG_NODE_MODIFIED
+			WICBitmapLockWrite
+		][WICBitmapLockRead]
 		rect/x: 0
 		rect/y: 0
 		rect/w: IMAGE_WIDTH(img/size)
 		rect/h: IMAGE_HEIGHT(img/size)
 		IB/Lock this rect flag :ilock
-		as integer! ilock/ptr
+		as integer! ilock/value
 	]
 
 	unlock-bitmap: func [
@@ -462,7 +580,7 @@ OS-image: context [
 			w		[integer!]
 			h		[integer!]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
@@ -470,13 +588,13 @@ OS-image: context [
 			scan0	[int-ptr!]
 			ret		[integer!]
 	][
-		this: as this! bitmap
+		this: get-buffer bitmap
 		IB: as IWICBitmap this/vtbl
 		w: 0 h: 0
 		IB/GetSize this :w :h
 		rect/x: 0 rect/y: 0 rect/w: w rect/h: h
 		IB/Lock this rect WICBitmapLockRead :ilock
-		lthis: as this! ilock/ptr
+		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 		size: 0 data: 0
 		lock/GetDataPointer lthis :size :data
@@ -498,20 +616,21 @@ OS-image: context [
 			w		[integer!]
 			h		[integer!]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
 			data	[integer!]
 			scan0	[int-ptr!]
+			inode	[img-node!]
 	][
-		this: as this! bitmap
+		this: get-buffer bitmap
 		IB: as IWICBitmap this/vtbl
 		w: 0 h: 0
 		IB/GetSize this :w :h
 		rect/x: 0 rect/y: 0 rect/w: w rect/h: h
 		IB/Lock this rect WICBitmapLockRead :ilock
-		lthis: as this! ilock/ptr
+		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 		size: 0 data: 0
 		lock/GetDataPointer lthis :size :data
@@ -519,18 +638,21 @@ OS-image: context [
 		scan0: scan0 + index
 		scan0/1: color
 		lock/Release lthis
+		inode: as img-node! bitmap
+		inode/flags: inode/flags or IMG_NODE_MODIFIED
 		0
 	]
 
 	delete: func [
 		img			[red-image!]
 		/local
-			this	[this!]
-			IB		[IWICBitmap]
+			unk		[IUnknown]
+			inode	[img-node!]
 	][
-		this: as this! img/node
-		IB: as IWICBitmap this/vtbl
-		IB/Release this
+		inode: as img-node! img/node
+		COM_SAFE_RELEASE(unk inode/handle)
+		COM_SAFE_RELEASE(unk inode/buffer)
+		free as byte-ptr! inode
 	]
 
 	resize: func [
@@ -540,47 +662,40 @@ OS-image: context [
 		return:		[integer!]
 		/local
 			this	[this!]
-			IB		[IWICBitmap]
 			IFAC	[IWICImagingFactory]
-			iscale	[interface! value]
+			iscale	[com-ptr! value]
 			sthis	[this!]
 			scale	[IWICBitmapScaler]
-			bitmap	[interface! value]
+			bitmap	[com-ptr! value]
 	][
-		this: as this! img/node
-		IB: as IWICBitmap this/vtbl
+		this: get-handle img
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		IFAC/CreateBitmapScaler wic-factory :iscale
-		sthis: as this! iscale/ptr
+		sthis: iscale/value
 		scale: as IWICBitmapScaler sthis/vtbl
-		scale/Initialize sthis as int-ptr! this width height 0		;-- NearestNeighbor
-		IFAC/CreateBitmapFromSource wic-factory as int-ptr! sthis 0 :bitmap
-		scale/Release sthis
-		as integer! bitmap/ptr
+		scale/Initialize sthis this width height 0		;-- NearestNeighbor
+		as-integer make-node sthis null 0 width height
 	]
 
-	load-image: func [
-		src			[red-string!]
-		return:		[int-ptr!]
+	get-frame: func [
+		IFAC		[IWICImagingFactory]
+		idec		[com-ptr!]
+		idx			[integer!]
+		return:		[node!]
 		/local
-			IFAC	[IWICImagingFactory]
-			II		[interface! value]
 			this	[this!]
 			dec		[IWICBitmapDecoder]
 			count	[integer!]
-			iframe	[interface! value]
+			iframe	[com-ptr! value]
 			fthis	[this!]
 			frame	[IWICBitmapFrameDecode]
 			w		[integer!]
 			h		[integer!]
-			iconv	[interface! value]
+			iconv	[com-ptr! value]
 			cthis	[this!]
 			conv	[IWICFormatConverter]
-			bitmap	[interface! value]
 	][
-		IFAC: as IWICImagingFactory wic-factory/vtbl
-		IFAC/CreateDecoderFromFilename wic-factory file/to-OS-path src null GENERIC_READ 0 :II
-		this: as this! II/ptr
+		this: idec/value
 		dec: as IWICBitmapDecoder this/vtbl
 		count: 0
 		dec/GetFrameCount this :count
@@ -588,20 +703,30 @@ OS-image: context [
 			dec/Release this
 			return null
 		]
-		dec/GetFrame this 0 :iframe
-		fthis: as this! iframe/ptr
+		dec/GetFrame this idx :iframe
+		fthis: iframe/value
 		frame: as IWICBitmapFrameDecode fthis/vtbl
 		w: 0 h: 0
 		frame/GetSize fthis :w :h
 		IFAC/CreateFormatConverter wic-factory :iconv
-		cthis: as this! iconv/ptr
+		cthis: iconv/value
 		conv: as IWICFormatConverter cthis/vtbl
-		conv/Initialize cthis as int-ptr! fthis as int-ptr! GUID_WICPixelFormat32bppBGRA 0 null 0.0 0
-		IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap
-		conv/Release cthis
+		conv/Initialize cthis fthis as int-ptr! GUID_WICPixelFormat32bppPBGRA 0 null 0.0 0
 		frame/Release fthis
 		dec/Release this
-		as int-ptr! bitmap/ptr
+		make-node cthis null 0 w h 
+	]
+
+	load-image: func [
+		src			[red-string!]
+		return:		[int-ptr!]
+		/local
+			IFAC	[IWICImagingFactory]
+			II		[com-ptr! value]
+	][
+		IFAC: as IWICImagingFactory wic-factory/vtbl
+		IFAC/CreateDecoderFromFilename wic-factory file/to-OS-path src null GENERIC_READ 0 :II
+		get-frame IFAC as com-ptr! :II 0
 	]
 
 	make-image: func [
@@ -613,11 +738,11 @@ OS-image: context [
 		return:		[int-ptr!]
 		/local
 			IFAC	[IWICImagingFactory]
-			bitmap	[interface! value]
+			bitmap	[com-ptr! value]
 			bthis	[this!]
 			bmp		[IWICBitmap]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
@@ -632,11 +757,11 @@ OS-image: context [
 		if any [zero? width zero? height][return null]
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		IFAC/CreateBitmap wic-factory width height as int-ptr! GUID_WICPixelFormat32bppBGRA WICBitmapCacheOnLoad :bitmap
-		bthis: as this! bitmap/ptr
+		bthis: bitmap/value
 		bmp: as IWICBitmap bthis/vtbl
 		rect/x: 0 rect/y: 0 rect/w: width rect/h: height
 		bmp/Lock bthis rect WICBitmapLockWrite :ilock
-		lthis: as this! ilock/ptr
+		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 
 		size: 0 data: 0
@@ -668,7 +793,7 @@ OS-image: context [
 		]
 
 		lock/Release lthis
-		as int-ptr! bthis
+		make-node null bthis IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height
 	]
 
 	load-binary: func [
@@ -679,18 +804,8 @@ OS-image: context [
 			hMem	[integer!]
 			p		[byte-ptr!]
 			s		[integer!]
+			idec	[com-ptr! value]
 			IFAC	[IWICImagingFactory]
-			idec	[interface! value]
-			dthis	[this!]
-			dec		[IWICBitmapDecoder]
-			count	[integer!]
-			iframe	[interface! value]
-			fthis	[this!]
-			frame	[IWICBitmapFrameDecode]
-			iconv	[interface! value]
-			cthis	[this!]
-			conv	[IWICFormatConverter]
-			bitmap	[interface! value]
 	][
 		hMem: GlobalAlloc GMEM_MOVEABLE len
 		p: GlobalLock hMem
@@ -702,27 +817,7 @@ OS-image: context [
 
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		IFAC/CreateDecoderFromStream wic-factory as int-ptr! s null 1 :idec
-		dthis: as this! idec/ptr
-		dec: as IWICBitmapDecoder dthis/vtbl
-		count: 0
-		dec/GetFrameCount dthis :count
-		if count < 1 [
-			dec/Release dthis
-			return null
-		]
-		dec/GetFrame dthis 0 :iframe
-		fthis: as this! iframe/ptr
-		frame: as IWICBitmapFrameDecode fthis/vtbl
-		IFAC/CreateFormatConverter wic-factory :iconv
-		cthis: as this! iconv/ptr
-		conv: as IWICFormatConverter cthis/vtbl
-		conv/Initialize cthis as int-ptr! fthis as int-ptr! GUID_WICPixelFormat32bppBGRA 0 null 0.0 0
-		IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap
-
-		conv/Release cthis
-		frame/Release fthis
-		dec/Release dthis
-		as int-ptr! bitmap/ptr
+		get-frame IFAC as com-ptr! :idec 0
 	]
 
 	encode: func [
@@ -736,16 +831,16 @@ OS-image: context [
 			clsid	[tagGUID]
 			stream	[IStream]
 			storage [IStorage]
-			stat	[tagSTATSTG]
-			IStm	[interface!]
-			ISto	[interface!]
+			stat	[tagSTATSTG value]
+			IStm	[interface! value]
+			ISto	[interface! value]
 			len		[integer!]
 			hr		[integer!]
 			IFAC	[IWICImagingFactory]
-			ienc	[interface! value]
+			ienc	[com-ptr! value]
 			ethis	[this!]
 			enc		[IWICBitmapEncoder]
-			iframe	[interface! value]
+			iframe	[com-ptr! value]
 			fthis	[this!]
 			frame	[IWICBitmapFrameEncode]
 			prop	[integer!]
@@ -760,14 +855,11 @@ OS-image: context [
 			default    [probe "Cannot find image encoder" return null]
 		]
 
-		ISto: declare interface!
-		IStm: declare interface!
-		stat: declare tagSTATSTG
 		hr: StgCreateDocfile
 			null
 			STGM_READWRITE or STGM_CREATE or STGM_SHARE_EXCLUSIVE or STGM_DELETEONRELEASE 
 			0
-			ISto
+			:ISto
 		storage: as IStorage ISto/ptr/vtbl
 		hr: storage/CreateStream
 			ISto/ptr
@@ -778,18 +870,18 @@ OS-image: context [
 			IStm
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		hr: IFAC/CreateEncoder wic-factory as int-ptr! clsid null :ienc
-		ethis: as this! ienc/ptr
+		ethis: ienc/value
 		enc: as IWICBitmapEncoder ethis/vtbl
-		hr: enc/Initialize ethis as int-ptr! IStm/ptr 2
+		hr: enc/Initialize ethis IStm/ptr 2
 		prop: 0
 		hr: enc/CreateNewFrame ethis :iframe :prop
-		fthis: as this! iframe/ptr
+		fthis: iframe/value
 		frame: as IWICBitmapFrameEncode fthis/vtbl
 		rect/x: 0 rect/y: 0
 		rect/w: IMAGE_WIDTH(image/size)
 		rect/h: IMAGE_HEIGHT(image/size)
 		hr: frame/Initialize fthis null
-		hr: frame/WriteSource fthis image/node rect
+		hr: frame/WriteSource fthis get-handle image rect
 		hr: frame/Commit fthis
 		hr: enc/Commit ethis
 		frame/Release fthis
@@ -826,15 +918,14 @@ OS-image: context [
 			height	[integer!]
 			offset	[integer!]
 			this	[this!]
-			IB		[IWICBitmap]
 			IFAC	[IWICImagingFactory]
-			bitmap	[interface! value]
+			bitmap	[com-ptr! value]
 			x		[integer!]
 			y		[integer!]
 			w		[integer!]
 			h		[integer!]
 			handle	[node!]
-			iclip	[interface! value]
+			iclip	[com-ptr! value]
 			cthis	[this!]
 			clip	[IWICBitmapClipper]
 			rect	[RECT! value]
@@ -854,15 +945,14 @@ OS-image: context [
 		]
 
 		offset: src/head
-		this: as this! src/node
-		IB: as IWICBitmap this/vtbl
+		this: get-handle src
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		if all [zero? offset not part?][
-			IFAC/CreateBitmapFromSource wic-factory as int-ptr! this 0 :bitmap
+			IFAC/CreateBitmapFromSource wic-factory this WICBitmapCacheOnDemand :bitmap
 			dst/size: src/size
 			dst/header: TYPE_IMAGE
 			dst/head: 0
-			dst/node: as node! bitmap/ptr
+			dst/node: make-node bitmap/value null 0 width height
 			return dst
 		]
 
@@ -891,14 +981,14 @@ OS-image: context [
 			dst/node: null
 		][
 			IFAC/CreateBitmapClipper wic-factory :iclip
-			cthis: as this! iclip/ptr
+			cthis: iclip/value
 			clip: as IWICBitmapClipper cthis/vtbl
 			rect/x: x rect/y: y
 			rect/w: w rect/h: h
-			clip/Initialize cthis as int-ptr! this rect
-			IFAC/CreateBitmapFromSource wic-factory as int-ptr! cthis 0 :bitmap
+			clip/Initialize cthis this rect
+			IFAC/CreateBitmapFromSource wic-factory cthis 0 :bitmap
 			clip/Release cthis
-			dst/node: as node! bitmap/ptr
+			dst/node: make-node bitmap/value null 0 w h
 			dst/size: h << 16 or w
 		]
 		dst/header: TYPE_IMAGE
@@ -906,27 +996,6 @@ OS-image: context [
 		dst
 	]
 
-	to-pbgra: func [
-		image		[red-image!]
-		return:		[this!]
-		/local
-			this	[this!]
-			IB		[IWICBitmap]
-			IFAC	[IWICImagingFactory]
-			iconv	[interface! value]
-			cthis	[this!]
-			conv	[IWICFormatConverter]
-	][
-		this: as this! image/node
-		IB: as IWICBitmap this/vtbl
-		IFAC: as IWICImagingFactory wic-factory/vtbl
-		IFAC/CreateFormatConverter wic-factory :iconv
-		cthis: as this! iconv/ptr
-		conv: as IWICFormatConverter cthis/vtbl
-		conv/Initialize cthis as int-ptr! this as int-ptr! GUID_WICPixelFormat32bppPBGRA 0 null 0.0 0
-		as this! cthis
-	]
-
 	to-HBITMAP: func [
 		image		[red-image!]
 		return:		[integer!]
@@ -936,14 +1005,14 @@ OS-image: context [
 			w		[integer!]
 			h		[integer!]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
 			data	[integer!]
 			bitmap	[integer!]
 	][
-		this: as this! image/node
+		this: get-buffer image/node
 		IB: as IWICBitmap this/vtbl
 		w: IMAGE_WIDTH(image/size)
 		h: IMAGE_HEIGHT(image/size)
@@ -952,7 +1021,7 @@ OS-image: context [
 		rect/w: w
 		rect/h: h
 		IB/Lock this rect WICBitmapLockRead :ilock
-		lthis: as this! ilock/ptr
+		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 		size: 0 data: 0
 		lock/GetDataPointer lthis :size :data
@@ -966,15 +1035,26 @@ OS-image: context [
 		return:		[red-image!]
 		/local
 			IFAC	[IWICImagingFactory]
-			bitmap	[interface! value]
+			bitmap	[com-ptr! value]
 			hr		[integer!]
+			this	[this!]
+			IB		[IWICBitmap]
+			w		[integer!]
+			h		[integer!]
 	][
 		IFAC: as IWICImagingFactory wic-factory/vtbl
 		hr: IFAC/CreateBitmapFromHBITMAP wic-factory as int-ptr! hBitmap null 0 :bitmap
 		if hr < 0 [
 			return as red-image! none-value
 		]
-		image/init-image as red-image! stack/push* as int-ptr! bitmap/ptr
+		
+		this: bitmap/value
+		IB: as IWICBitmap this/vtbl
+		w: 0 h: 0
+		IB/GetSize this :w :h
+		image/init-image
+			as red-image! stack/push*
+			make-node null this 3 w h
 	]
 
 	to-gpbitmap: func [
@@ -986,14 +1066,14 @@ OS-image: context [
 			w		[integer!]
 			h		[integer!]
 			rect	[RECT! value]
-			ilock	[interface! value]
+			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
 			data	[integer!]
 			bitmap	[integer!]
 	][
-		this: as this! image/node
+		this: get-buffer image/node
 		IB: as IWICBitmap this/vtbl
 		w: IMAGE_WIDTH(image/size)
 		h: IMAGE_HEIGHT(image/size)
@@ -1002,7 +1082,7 @@ OS-image: context [
 		rect/w: w
 		rect/h: h
 		IB/Lock this rect WICBitmapLockRead :ilock
-		lthis: as this! ilock/ptr
+		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 		size: 0 data: 0
 		lock/GetDataPointer lthis :size :data

From 3ed2eae773f2fb5cf021285ce419d1bfed44006b Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Fri, 10 Jan 2020 18:28:35 +0100
Subject: [PATCH 0762/3432] FEAT: improves accuracy of SCAN and ERROR lexer
 events.

---
 environment/system.red         |  2 +-
 runtime/lexer-transitions.reds | 68 +++++++++++++++++-----------------
 runtime/lexer.reds             | 26 ++++++++-----
 utils/generate-lexer-table.red | 14 +++----
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/environment/system.red b/environment/system.red
index c609236cf9..64199d3b81 100644
--- a/environment/system.red
+++ b/environment/system.red
@@ -406,7 +406,7 @@ system: context [
 		
 		exit-states: [
 			eof error! block! block! paren! paren! string! string! map! path! any-type!
-			comment string!	word! file! refinement!	binary! char! issue! percent!
+			comment word! refinement! issue! string! file! binary! char! percent!
 			integer! float! float! tuple! date! pair! time! money! tag! url! email! hex
 		]
 	]
diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds
index e2d9d088e7..4cb76506ed 100644
--- a/runtime/lexer-transitions.reds
+++ b/runtime/lexer-transitions.reds
@@ -70,13 +70,13 @@ Red/System [
         T_PATH 
         T_CONS_MK 
         T_CMT 
-        T_STRING 
         T_WORD 
-        T_FILE 
         T_REFINE 
+        T_ISSUE 
+        T_STRING 
+        T_FILE 
         T_BINARY 
         T_CHAR 
-        T_ISSUE 
         T_PERCENT 
         T_INTEGER 
         T_FLOAT 
@@ -98,28 +98,28 @@ Red/System [
     transitions: #{
 000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E
 2929392D2D393801430101010101010101010101010101010101010101010101
-0101010101010101010101013938020202020202020202024402020202020202
+0101010101010101010101013938020202020202020202024702020202020202
 0202020202020202020202020202020203020239390202020202020202020202
 0202020202020202020202020202020202020202020202020202393804040404
 040404043E3F0404040404040404040404040404040404040404040404040504
 0439390404040404040404040404040404040404040404040404040404040404
-04040404040404043938454507074545454545450A0707450707070707070707
-0707070707074545070707070707073945464607074646464646463907074607
-0707070707070707070707080746460707070707070739460707090939393939
+04040404040404043938444407074444444444440A0707440707070707070707
+0707070707074444070707070707073944484807074848484848483907074807
+0707070707070707070707080748480707070707070739480707090939393939
 3939393939393939390909090939393939393939393939393939393939393907
 0707073939393939393939393939393909090707393939393939393939393939
-3939393939460A0A0A0A0A0A0A0A0A0A460A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
-0A0A0A0A0A0A0A0A0A0A0A393947470B0B474747474747470B0B0B0B0B0B0B0B
-0B0B2D0B0B0B0B0B0B47470B0B0B0B0B0B0B39474A4A1212113940390D390F12
-123912121212121212121239393912394A4A12121212121212394A0D0D0D0D39
-3939393948393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
+3939393939480A0A0A0A0A0A0A0A0A0A480A0A0A0A0A0A0A0A0A0A0A0A0A0A0A
+0A0A0A0A0A0A0A0A0A0A0A393945450B0B454545454545450B0B0B0B0B0B0B0B
+0B0B2D0B0B0B0B0B0B45450B0B0B0B0B0B0B394546461212113940390D390F12
+1239121212121212121212393939123946461212121212121239460D0D0D0D39
+3939393949393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D
 39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E
-0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F490F0F0F0F0F0F0F0F0F0F0F0F
-0F0F0F0F0F0F0F0F0F0F0F100F0F39490F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
+0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F
+0F0F0F0F0F0F0F0F0F0F0F100F0F394A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111142111111
-1111111111111111111111111111111111111111111111111111111139394A4A
-12124A4A4A4A4A4A4A12121212121212121212121212121212124A4A12121212
-121212394A4C4C13134C4C4C4C4C4C4C0C131A1C19571516392119394C39394B
+1111111111111111111111111111111111111111111111111111111139394646
+1212464646464646461212121212121212121212121212121212464612121212
+12121239464C4C13134C4C4C4C4C4C4C0C131A1C19571516392119394C39394B
 144C3014393919393939394C4D4D15154D4D4D4D4D4D4D1715391C3939151539
 394D394D39394B394D3939393939393939394D4D4D15154D4D4D4D4D4D4D3939
 4D393939151539394D394D39394B39393018391515393939394D4D4D16164D4D
@@ -136,32 +136,32 @@ Red/System [
 3939393939393939393939393939393939393939393939393953531F1F535353
 53535353531F5339393939393939533953393939395339203939393939393938
 5353202053535353535353532053393939393939395339533939393953393939
-393939393939384545212145454545454545392D2E2D2D222D212D2141452D2D
-2D393945302D1F2D2D2D2D2D394557572D2D57575757575757392D2E2D2D2D2D
-2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574545242445454545454545
-2424452424242424242424242D2D2D2424454524242424242424394524242424
+393939393939384444212144444444444444392D2E2D2D222D212D2141442D2D
+2D393944302D1F2D2D2D2D2D394457572D2D57575757575757392D2E2D2D2D2D
+2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574444242444444444444444
+2424442424242424242424242D2D2D2424444424242424242424394424242424
 2424242424242524242724242424242424242424542424242424242424242424
 2439392525252525252525252524252525252525252525252525252525252525
 2525252525262525393925252525252525252525252525252525252525252525
 2525252525252525252525252525253939272727272727272727272727272427
 2727272727272727272727272727272727272727272739392727272727272727
-2727272727272727272727272727272727272727272727272727272727393945
-4513134545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D
-2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D
-393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B
+2727272727272727272727272727272727272727272727272727272727393944
+4413134444444444444439392D2D2D2D2D2D2D2D2D44392D2D392D442D2A2D2D
+2D392D2D394444442B2B44444444444444392D2E2D2D2D2B2B2D2D41442D2D2D
+393944302D392B2B2D2D2D39444D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B
 39394D394D39394B39393939392B2B393939394D393939393939393939393939
-39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45
-454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D1F2D2D2D2D2D
-394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F
-2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55
+39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393944442D2D44
+444444444444392D2E2D2D2D2D2D2D2D41442D2D2D393944302D1F2D2D2D2D2D
+394444442F2F444444444444442F2F2F2F2F2F2F2F2F2F2F44392F2F2F2F442F
+2F2F2F2F2F2F2F394455552F2F555555555555552F392F2F2F2F2F2F2F2F2F55
 55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030
 30303030305656563939303956393039303039303039563939323239393C3D39
 3902353333343434343434343939233434393939303439363639343439394C4C
 32324C4C4C4C4C4C4C39134C1C3939151539394C394C39394B144C3014393939
 393939394C393939393939393939393939393934343434343434393934343439
-3939393439343439343439394545343445454545454545393445343434343434
-344545343434393945303439343434343439454A4A12121139393939390F1212
-3912121212121212121239393912394A4A12121212121212394A454532324545
-454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39
-45
+3939393439343439343439394444343444444444444444393444343434343434
+34444434343439394430343934343434343944464612121139393939390F1212
+3912121212121212121239393912394646121212121212123946444432324444
+444444444439392D2D2D2D2D2D2D2D2D44392D2D392D442D2D2D2D2D392D2D39
+44
 }
diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index ea1fe00cfc..4620f29345 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -317,6 +317,7 @@ lexer: context [
 			len	 [integer!]
 			c	 [byte!]
 	][
+		if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [exit]]
 		e: lex/in-end
 		len: 0
 		if null? s [									;-- determine token's start
@@ -375,14 +376,16 @@ lexer: context [
 			blk	  [red-block!]
 			cont? [logic!]
 	][
+		if all [event = words/_scan type = -2][event: words/_error type: TYPE_ERROR]
+		
 		stack/mark-func words/_body	lex/fun-ptr/ctx		;@@ find something more adequate
 		stack/push as red-value! event					;-- event
 		ser: as red-series! stack/push as red-value! lex/in-series ;-- input
 		
-		either any [event = words/_scan event = words/_error][;-- type
+		either type < 0 [								;-- type
 			blk: as red-block! #get system/lexer/exit-states
 			either TYPE_OF(blk) <> TYPE_BLOCK [none/push][
-				stack/push block/rs-abs-at blk type - 1		;-- 1-based access
+				stack/push block/rs-abs-at blk (0 - type) - 1	;-- 1-based access
 			]
 		][
 			either zero? type [none/push][datatype/push type]
@@ -497,7 +500,7 @@ lexer: context [
 		]
 		p: as red-point! lex/head - 1
 		if lex/fun-ptr <> null [
-			type: either all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][p/y >> 16][0]
+			if all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][type: p/y >> 16]
 			unless fire-event lex words/_close type null s e [return 0]
 		]
 		stype: p/y >> 16
@@ -814,8 +817,6 @@ lexer: context [
 	scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][]
 	
 	scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][
-		if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [exit]]
-		
 		either lex/prev < --EXIT_STATES-- [
 			index: lex/prev + 1
 			index: as-integer prev-table/index
@@ -1114,8 +1115,9 @@ lexer: context [
 		/local
 			cell [cell!]
 			cp type class index [integer!]
-			p pos [byte-ptr!]
+			p pos s-pos e-pos [byte-ptr!]
 	][
+		s-pos: s e-pos: e
 		if flags and flags-LG = flags-LG [				;-- handle word cases
 			p: s
 			while [all [p < e p/1 <> #"<"]][p: p + 1]	;-- search <
@@ -1152,6 +1154,7 @@ lexer: context [
 			while [all [p < e p/1 = #"/"]][p: p + 1]
 			if p < e [throw-error lex s e TYPE_REFINEMENT]
 		]
+		if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s-pos e-pos [exit]]
 		cell: alloc-slot lex
 		word/make-at symbol/make-alt-utf8 s as-integer e - s cell
 		set-type cell type
@@ -1257,6 +1260,7 @@ lexer: context [
 				]
 			]
 		]
+		if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s e [exit]]
 		s: s + 1
 		cell: alloc-slot lex
 		word/make-at symbol/make-alt-utf8 s as-integer e - s cell
@@ -1748,7 +1752,9 @@ lexer: context [
 			load?:		yes
 			
 			index: state - --EXIT_STATES--
-			if lex/fun-ptr <> null [load?: fire-event lex words/_scan index null s lex/in-pos]
+			if lex/fun-ptr <> null [
+				if state >= T_STRING [load?: fire-event lex words/_scan 0 - index null s lex/in-pos]
+			]
 			if load? [
 				do-scan: as scanner! scanners/index
 				do-scan lex s p flags
@@ -1890,13 +1896,13 @@ lexer: context [
 			:scan-path-open								;-- T_PATH
 			:scan-construct								;-- T_CONS_MK
 			:scan-comment								;-- T_CMT
-			:scan-string								;-- T_STRING
 			:scan-word									;-- T_WORD
-			:scan-file									;-- T_FILE
 			:scan-ref-issue								;-- T_REFINE
+			:scan-ref-issue								;-- T_ISSUE
+			:scan-string								;-- T_STRING
+			:scan-file									;-- T_FILE
 			:scan-binary								;-- T_BINARY
 			:scan-char									;-- T_CHAR
-			:scan-ref-issue								;-- T_ISSUE
 			:scan-percent								;-- T_PERCENT
 			:scan-integer								;-- T_INTEGER
 			:scan-float									;-- T_FLOAT
diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red
index 053d366502..eb1d58eb16 100644
--- a/utils/generate-lexer-table.red
+++ b/utils/generate-lexer-table.red
@@ -81,13 +81,13 @@ context [
 		T_PATH				-					;-- 65
 		T_CONS_MK			-					;-- 66
 		T_CMT				-					;-- 67
-		T_STRING			-					;-- 68
-		T_WORD				-					;-- 69
-		T_FILE				-					;-- 70
-		T_REFINE			-					;-- 71
-		T_BINARY			-					;-- 72
-		T_CHAR				-					;-- 73
-		T_ISSUE				-					;-- 74
+		T_WORD				-					;-- 68
+		T_REFINE			-					;-- 69
+		T_ISSUE				-					;-- 70
+		T_STRING			-					;-- 71
+		T_FILE				-					;-- 72
+		T_BINARY			-					;-- 73
+		T_CHAR				-					;-- 74
 		T_PERCENT			-					;-- 75
 		T_INTEGER			-					;-- 76
 		T_FLOAT				-					;-- 77

From 1020bedc8fea8f542c3c0822276a9a71a96e9e78 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sat, 11 Jan 2020 11:27:15 +0100
Subject: [PATCH 0763/3432] FIX: avoid releasing bitmap.

---
 modules/view/backends/windows/base.reds |  6 +++++-
 modules/view/backends/windows/draw.reds | 11 +----------
 2 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index 00ae5187cd..2f4c76e1b8 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -744,6 +744,7 @@ update-base: func [
 		ctx		[draw-ctx! value]
 		pdc		[com-ptr! value]
 		this	[this!]
+		dc		[ID2D1DeviceContext]
 		rt-dc	[ID2D1GdiInteropRenderTarget]
 		hdc		[ptr-value!]
 ][
@@ -777,9 +778,12 @@ update-base: func [
 	either TYPE_OF(cmds) = TYPE_BLOCK [
 		system/thrown: 0
 		catch RED_THROWN_ERROR [
-			draw-begin ctx hWnd as red-image! :pdc yes yes
+			draw-begin ctx hWnd null yes yes
 			parse-draw ctx cmds yes
 
+			this: as this! ctx/dc
+			dc: as ID2D1DeviceContext this/vtbl
+			dc/QueryInterface this IID_IDGdiInterop :pdc
 			this: pdc/value
 			rt-dc: as ID2D1GdiInteropRenderTarget this/vtbl
 			rt-dc/GetDC this 0 :hdc
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index c660158dcf..b658aa65f0 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -222,12 +222,6 @@ draw-begin: func [
 	ctx/target: as int-ptr! target
 
 	dc/BeginDraw this
-	if on-graphic? [
-		dc/QueryInterface this IID_IDGdiInterop :gdi
-		pp: as com-ptr! img
-		pp/value: gdi/value
-	]
-
 	dc/SetTextAntialiasMode this 1				;-- ClearType
 	dc/SetAntialiasMode this 0					;-- D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
 
@@ -249,7 +243,7 @@ draw-begin: func [
 		values: get-face-values hWnd
 		clr: as red-tuple! values + FACE_OBJ_COLOR
 		bg-clr: either TYPE_OF(clr) = TYPE_TUPLE [clr/array1][-1]
-		if bg-clr <> -1 [							;-- paint background
+		if any [on-graphic? bg-clr <> -1][		;-- paint background
 			dc/Clear this to-dx-color bg-clr null
 		]
 
@@ -1481,7 +1475,6 @@ OS-draw-image: func [
 		this	[this!]
 		dc		[ID2D1DeviceContext]
 		ithis	[this!]
-		IB		[IUnknown]
 		bmp		[ptr-value!]
 		bthis	[this!]
 		d2db	[IUnknown]
@@ -1506,7 +1499,6 @@ OS-draw-image: func [
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
 	ithis: OS-image/get-handle image
-	IB: as IUnknown ithis/vtbl
 	dc/CreateBitmapFromWicBitmap2 this ithis null :bmp
 	bthis: as this! bmp/value
 	d2db: as IUnknown bthis/vtbl
@@ -1587,7 +1579,6 @@ OS-draw-image: func [
 	dc/DrawBitmap2 this as int-ptr! bthis dst as float32! 1.0 1 src trans
 
 	d2db/Release bthis
-	IB/Release ithis
 ]
 
 _OS-draw-brush-bitmap: func [

From 2de3f40307e6eb49b963920b6bb859da88f96061 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Sun, 12 Jan 2020 15:45:52 +0100
Subject: [PATCH 0764/3432] FIX: make image node GC compatible.

---
 runtime/collector.reds          |  2 +-
 runtime/platform/image-wic.reds | 23 ++++++++++++-----------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/runtime/collector.reds b/runtime/collector.reds
index fb6dc143de..ccc22b4640 100644
--- a/runtime/collector.reds
+++ b/runtime/collector.reds
@@ -244,7 +244,7 @@ collector: context [
 						mark-block-node as node! native/code
 					]
 				]
-				#if OS = 'macOS [
+				#if any [OS = 'macOS OS = 'Windows][
 				TYPE_IMAGE [
 					image: as red-image! value
 					keep image/node
diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds
index 69bf3fbb8c..69db9746a0 100644
--- a/runtime/platform/image-wic.reds
+++ b/runtime/platform/image-wic.reds
@@ -279,14 +279,16 @@ OS-image: context [
 		height	[integer!]
 		return: [node!]
 		/local
+			node	[node!]
 			inode	[img-node!]
 	][
-		inode: as img-node! allocate size? img-node!
+		node: alloc-cells 1			;-- 16 bytes
+		inode: as img-node! (as series! node/value) + 1
 		inode/flags: flags
 		inode/handle: handle
 		inode/buffer: buffer
 		inode/size: height << 16 or width
-		as node! inode
+		node
 	]
 
 	to-bgra: func [
@@ -321,7 +323,7 @@ OS-image: context [
 			unk		[IUnknown]
 			h		[this!]
 	][
-		inode: as img-node! img/node
+		inode: as img-node! (as series! img/node/value) + 1
 		h: inode/handle
 		if any [null? h inode/flags and IMG_NODE_MODIFIED <> 0][
 			if h <> null [COM_SAFE_RELEASE(unk h)]
@@ -342,7 +344,7 @@ OS-image: context [
 			IFAC	[IWICImagingFactory]
 			bitmap	[com-ptr! value]
 	][
-		inode: as img-node! img/node
+		inode: as img-node! (as series! img/node/value) + 1
 		h: get-handle img
 		either inode/flags and IMG_NODE_WICBITMAP <> 0 [h][
 			IFAC: as IWICImagingFactory wic-factory/vtbl
@@ -366,7 +368,7 @@ OS-image: context [
 			h		[this!]
 			bitmap	[com-ptr! value]
 	][
-		inode: as img-node! img
+		inode: as img-node! (as series! img/value) + 1
 		h: inode/buffer
 		if inode/flags and IMG_NODE_HAS_BUFFER = 0 [
 			h: to-bgra inode/handle no
@@ -477,7 +479,7 @@ OS-image: context [
 		/local
 			inode	[img-node!]
 	][
-		inode: as img-node! handle
+		inode: as img-node! (as series! handle/value) + 1
 		IMAGE_WIDTH(inode/size)
 	]
 
@@ -487,7 +489,7 @@ OS-image: context [
 		/local
 			inode	[img-node!]
 	][
-		inode: as img-node! handle
+		inode: as img-node! (as series! handle/value) + 1
 		IMAGE_HEIGHT(inode/size)
 	]
 
@@ -506,7 +508,7 @@ OS-image: context [
 		this: get-buffer img/node
 		IB: as IWICBitmap this/vtbl
 		flag: either write? [
-			inode: as img-node! img/node
+			inode: as img-node! (as series! img/node/value) + 1
 			inode/flags: inode/flags or IMG_NODE_MODIFIED
 			WICBitmapLockWrite
 		][WICBitmapLockRead]
@@ -638,7 +640,7 @@ OS-image: context [
 		scan0: scan0 + index
 		scan0/1: color
 		lock/Release lthis
-		inode: as img-node! bitmap
+		inode: as img-node! (as series! bitmap/value) + 1
 		inode/flags: inode/flags or IMG_NODE_MODIFIED
 		0
 	]
@@ -649,10 +651,9 @@ OS-image: context [
 			unk		[IUnknown]
 			inode	[img-node!]
 	][
-		inode: as img-node! img/node
+		inode: as img-node! (as series! img/node/value) + 1
 		COM_SAFE_RELEASE(unk inode/handle)
 		COM_SAFE_RELEASE(unk inode/buffer)
-		free as byte-ptr! inode
 	]
 
 	resize: func [

From e7f9f824369f6523dd1ac11c9e70e71220755006 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Mon, 13 Jan 2020 17:47:48 +0800
Subject: [PATCH 0765/3432] FEAT: first support clip

---
 modules/view/backends/macOS/draw.reds       |  4 ++
 modules/view/backends/test/draw.reds        |  4 ++
 modules/view/backends/windows/direct2d.reds | 34 ++++++++--
 modules/view/backends/windows/draw-gdi.reds |  4 ++
 modules/view/backends/windows/draw.reds     | 70 +++++++++++++++++++++
 modules/view/draw.red                       |  2 +
 runtime/definitions.reds                    |  1 +
 7 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/modules/view/backends/macOS/draw.reds b/modules/view/backends/macOS/draw.reds
index 85d34f7784..3a9dbd018f 100644
--- a/modules/view/backends/macOS/draw.reds
+++ b/modules/view/backends/macOS/draw.reds
@@ -1525,6 +1525,10 @@ OS-set-clip: func [
 	CGContextClip ctx
 ]
 
+OS-clip-end: func [
+	ctx		[draw-ctx!]
+][]
+
 ;-- shape sub command --
 
 OS-draw-shape-beginpath: func [
diff --git a/modules/view/backends/test/draw.reds b/modules/view/backends/test/draw.reds
index 49eda2d4c2..92ff8f24bd 100644
--- a/modules/view/backends/test/draw.reds
+++ b/modules/view/backends/test/draw.reds
@@ -344,6 +344,10 @@ OS-set-clip: func [
 
 ]
 
+OS-clip-end: func [
+	ctx		[draw-ctx!]
+][]
+
 OS-matrix-rotate: func [
 	ctx			[draw-ctx!]
 	pen-fill	[integer!]
diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 7729b4fab7..ecb88e0d2f 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -795,6 +795,32 @@ DrawBitmap*: alias function! [
 	trans		[int-ptr!]
 ]
 
+D2D1_LAYER_PARAMETERS1: alias struct! [
+	bounds		[RECT_F! value]
+	mask		[int-ptr!]
+	mode		[integer!]
+	trans		[D2D_MATRIX_3X2_F value]
+	opacity		[float32!]
+	brush		[int-ptr!]
+	opts		[integer!]
+]
+
+PushLayer*: alias function! [
+	this		[this!]
+	param		[D2D1_LAYER_PARAMETERS1]
+	layer		[int-ptr!]
+]
+
+CombineWithGeometry*: alias function! [
+	this		[this!]
+	input		[int-ptr!]
+	mode		[integer!]
+	trans		[D2D_MATRIX_3X2_F]
+	flat		[float32!]
+	sink		[int-ptr!]
+	return:		[integer!]
+]
+
 #define ID2D1RenderTarget [
 	QueryInterface					[function! [this [this!] riid [int-ptr!] ppvObject [com-ptr!] return: [integer!]]]
 	AddRef							[AddRef!]
@@ -809,7 +835,7 @@ DrawBitmap*: alias function! [
 	CreateLinearGradientBrush		[CreateLinearGradientBrush*]
 	CreateRadialGradientBrush		[CreateRadialGradientBrush*]
 	CreateCompatibleRenderTarget	[function! [this [this!] size [SIZE_F! value] target [ptr-ptr!] return: [integer!]]]
-	CreateLayer						[integer!]
+	CreateLayer						[function! [this [this!] size [SIZE_F!] layer [ptr-ptr!] return: [integer!]]]
 	CreateMesh						[integer!]
 	DrawLine						[DrawLine*]
 	DrawRectangle					[DrawRectangle*]
@@ -837,7 +863,7 @@ DrawBitmap*: alias function! [
 	SetTags							[integer!]
 	GetTags							[integer!]
 	PushLayer						[integer!]
-	PopLayer						[integer!]
+	PopLayer						[function! [this [this!]]]
 	Flush							[function! [this [this!] tag1 [int-ptr!] tag2 [int-ptr!]]]
 	SaveDrawingState				[function! [this [this!] block [this!]]]
 	RestoreDrawingState				[function! [this [this!] block [this!]]]
@@ -886,7 +912,7 @@ ID2D1DeviceContext: alias struct! [
     DrawImage						[DrawImage*]
     DrawGdiMetafile					[integer!]
     DrawBitmap2						[DrawBitmap*]
-    PushLayer2						[integer!]
+    PushLayer2						[PushLayer*]
     InvalidateEffectInputRectangle	[integer!]
     GetEffectInvalidRectangleCount	[integer!]
     GetEffectInvalidRectangles		[integer!]
@@ -926,7 +952,7 @@ ID2D1PathGeometry: alias struct! [
 	CompareWithGeometry				[integer!]
 	Simplify						[integer!]
 	Tessellate						[integer!]
-	CombineWithGeometry				[integer!]
+	CombineWithGeometry				[CombineWithGeometry*]
 	Outline							[integer!]
 	ComputeArea						[integer!]
 	ComputeLength					[integer!]
diff --git a/modules/view/backends/windows/draw-gdi.reds b/modules/view/backends/windows/draw-gdi.reds
index d1bb9fa5f2..e0bb10df3d 100644
--- a/modules/view/backends/windows/draw-gdi.reds
+++ b/modules/view/backends/windows/draw-gdi.reds
@@ -3266,6 +3266,10 @@ OS-set-clip: func [
 	]
 ]
 
+OS-clip-end: func [
+	ctx		[draw-ctx!]
+][]
+
 OS-matrix-rotate: func [
 	ctx			[draw-ctx!]
 	pen-fill	[integer!]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index b658aa65f0..34f8426562 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -238,6 +238,7 @@ draw-begin: func [
 	ctx/brush-type:	DRAW_BRUSH_NONE
 
 	ctx/pre-order?: yes
+	ctx/clip-layer: null
 
 	if hWnd <> null [
 		values: get-face-values hWnd
@@ -267,6 +268,9 @@ release-ctx: func [
 	/local
 		IUnk	[IUnknown]
 ][
+	unless null? ctx/clip-layer [
+		COM_SAFE_RELEASE(IUnk ctx/clip-layer)
+	]
 	COM_SAFE_RELEASE(IUnk ctx/pen)
 	COM_SAFE_RELEASE(IUnk ctx/brush)
 	release-pen-style ctx
@@ -1979,8 +1983,74 @@ OS-set-clip: func [
 	l		[red-pair!]
 	rect?	[logic!]
 	mode	[integer!]
+	/local
+		dc		[ID2D1DeviceContext]
+		this	[this!]
+		layer	[ptr-value!]
+		lthis	[this!]
+		hr		[integer!]
+		pthis	[this!]
+		gpath	[ID2D1PathGeometry]
+		sthis	[this!]
+		gsink	[ID2D1GeometrySink]
+		para	[D2D1_LAYER_PARAMETERS1 value]
+		inf4	[integer!]
+		inf3	[integer!]
+		inf2	[integer!]
+		inf1	[integer!]
 ][
+	this: as this! ctx/dc
+	dc: as ID2D1DeviceContext this/vtbl
+	if null? ctx/clip-layer [
+		hr: dc/CreateLayer this null :layer
+		ctx/clip-layer: as this! layer/value
+	]
+	lthis: ctx/clip-layer
+
+	para/mode: 0
+	matrix2d/identity para/trans
+	para/opacity: as float32! 1.0
+	para/brush: null
+	para/opts: 0
+	para/mask: null
+	either rect? [
+		para/bounds/left: as float32! u/x
+		para/bounds/top: as float32! u/y
+		para/bounds/right: as float32! l/x
+		para/bounds/bottom: as float32! l/y
+	][
+		inf1: FF800000h
+		inf2: FF800000h
+		inf3: 7F800000h
+		inf4: 7F800000h
+		copy-memory as byte-ptr! para/bounds as byte-ptr! :inf1 16
+
+		;-- TDB: as the shape path are auto closed, so need a way to reserve path
+		if ctx/sub/path <> 0 [
+			pthis: as this! ctx/sub/path
+			gpath: as ID2D1PathGeometry pthis/vtbl
+			sthis: as this! ctx/sub/sink
+			gsink: as ID2D1GeometrySink sthis/vtbl
+			gsink/EndFigure sthis 1
+			hr: gsink/Close sthis
+			gsink/Release sthis
+
+			para/mask: as int-ptr! pthis
+		]
+	]
+
+	dc/PushLayer2 this :para as int-ptr! lthis
+]
 
+OS-clip-end: func [
+	ctx			[draw-ctx!]
+	/local
+		dc		[ID2D1DeviceContext]
+		this	[this!]
+][
+	this: as this! ctx/dc
+	dc: as ID2D1DeviceContext this/vtbl
+	dc/PopLayer this
 ]
 
 #define BEGIN_MATRIX_BRUSH [
diff --git a/modules/view/draw.red b/modules/view/draw.red
index df5125cafc..c97124e3cb 100644
--- a/modules/view/draw.red
+++ b/modules/view/draw.red
@@ -912,9 +912,11 @@ Red/System [
 									OS-draw-state-push DC :state
 									OS-set-clip DC as red-pair! start as red-pair! value rect? clip-mode
 									parse-draw DC as red-block! cmd catch?
+									OS-clip-end DC
 									OS-draw-state-pop DC :state
 								][
 									OS-set-clip DC as red-pair! start as red-pair! value rect? clip-mode
+									OS-clip-end DC
 								]
 							]
 							sym = shape [
diff --git a/runtime/definitions.reds b/runtime/definitions.reds
index 3419bf0646..5f220b1d77 100644
--- a/runtime/definitions.reds
+++ b/runtime/definitions.reds
@@ -328,6 +328,7 @@ Red/System [
 			state			[this!]				;-- current draw state
 			sub				[sub-path! value]
 			shadows			[shadow! value]
+			clip-layer		[this!]
 		]
 	][
 		draw-ctx!: alias struct! [

From f0ec9ccc30e9397161fe359addd3fddce0975c9a Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 11:18:00 +0100
Subject: [PATCH 0766/3432] FIX: compiling error in dev mode.

---
 modules/view/backends/windows/win32.reds | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds
index 8f83d4c1e3..71ae865093 100644
--- a/modules/view/backends/windows/win32.reds
+++ b/modules/view/backends/windows/win32.reds
@@ -12,7 +12,7 @@ Red/System [
 
 #if dev-mode? = yes [
 	#include %../../../../runtime/platform/COM.reds
-	#ether legacy = none [
+	#either legacy = none [
 		#include %../../../../runtime/platform/image-wic.reds
 	][
 		#include %../../../../runtime/platform/image-gdiplus.reds

From af23a980ec2be15fcda5531f92b14a1b0ce12fc0 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 11:25:06 +0100
Subject: [PATCH 0767/3432] FIX: convert wicbitmap to gdiplus bitmap properly.

---
 modules/view/backends/windows/base.reds |  5 +++--
 runtime/platform/image-wic.reds         | 13 ++++++++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index 828704ce3c..dc5c012579 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -582,11 +582,12 @@ update-base-image: func [
 	height		[integer!]
 	/local
 		bitmap	[integer!]
+		lock	[com-ptr! value]
 ][
 	if TYPE_OF(img) = TYPE_IMAGE [
-		bitmap: OS-image/to-gpbitmap img
+		bitmap: OS-image/to-gpbitmap img :lock
 		GdipDrawImageRectI graphic bitmap 0 0 width height
-		OS-image/release-gpbitmap bitmap
+		OS-image/release-gpbitmap bitmap :lock
 	]
 ]
 
diff --git a/runtime/platform/image-wic.reds b/runtime/platform/image-wic.reds
index 69db9746a0..359d30587a 100644
--- a/runtime/platform/image-wic.reds
+++ b/runtime/platform/image-wic.reds
@@ -1060,6 +1060,7 @@ OS-image: context [
 
 	to-gpbitmap: func [
 		image		[red-image!]
+		ilock		[com-ptr!]
 		return:		[integer!]
 		/local
 			this	[this!]
@@ -1067,7 +1068,6 @@ OS-image: context [
 			w		[integer!]
 			h		[integer!]
 			rect	[RECT! value]
-			ilock	[com-ptr! value]
 			lthis	[this!]
 			lock	[IWICBitmapLock]
 			size	[integer!]
@@ -1082,20 +1082,27 @@ OS-image: context [
 		rect/y: 0
 		rect/w: w
 		rect/h: h
-		IB/Lock this rect WICBitmapLockRead :ilock
+		IB/Lock this rect WICBitmapLockRead ilock
 		lthis: ilock/value
 		lock: as IWICBitmapLock lthis/vtbl
 		size: 0 data: 0
 		lock/GetDataPointer lthis :size :data
 		bitmap: 0
+		;-- GdipCreateBitmapFromScan0 uses data without copying it
 		GdipCreateBitmapFromScan0 w h w * 4 PixelFormat32bppARGB as byte-ptr! data :bitmap
-		lock/Release lthis
 		bitmap
 	]
 
 	release-gpbitmap: func [
 		bitmap		[integer!]
+		ilock		[com-ptr!]
+		/local
+			lthis	[this!]
+			lock	[IWICBitmapLock]
 	][
 		GdipDisposeImage bitmap
+		lthis: ilock/value
+		lock: as IWICBitmapLock lthis/vtbl
+		lock/Release lthis
 	]
 ]

From 7912cda46ee90da7a9a98b419b10809c8d066f7b Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 11:54:54 +0100
Subject: [PATCH 0768/3432] FIX: ballots demo doesn't work properly on Win10.

---
 modules/view/backends/windows/base.reds     |  4 ++--
 modules/view/backends/windows/direct2d.reds | 11 ++---------
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds
index dc5c012579..a3fb81e165 100644
--- a/modules/view/backends/windows/base.reds
+++ b/modules/view/backends/windows/base.reds
@@ -686,8 +686,8 @@ update-base-text: func [
 
 	rect/x: as float32! 0.0
 	rect/y: as float32! 0.0
-	rect/width: as float32! dpi-unscale width
-	rect/height: as float32! dpi-unscale height
+	rect/width: as float32! width
+	rect/height: as float32! height
 
 	either bbox = null [
 		if default-color [clr: GetSysColor COLOR_WINDOWTEXT]
diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index ecb88e0d2f..3c9b68e532 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -1642,23 +1642,16 @@ create-render-target: func [
 	desc/SampleCount: 1
 	desc/BufferUsage: 20h	;-- DXGI_USAGE_RENDER_TARGET_OUTPUT
 	desc/BufferCount: 2
-	desc/AlphaMode: 1		;-- DXGI_ALPHA_MODE_PREMULTIPLIED
+	desc/AlphaMode: 0
 	desc/SwapEffect: 3		;-- DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
 
 	int: 0
 	buf: 0
 	dxgi: as IDXGIFactory2 dxgi-factory/vtbl
-	either win8+? [			;-- use direct composition
-		hr: dxgi/CreateSwapChainForComposition dxgi-factory d3d-device desc null :int
-	][
-		desc/AlphaMode: 0
-		hr: dxgi/CreateSwapChainForHwnd dxgi-factory d3d-device hWnd desc null null :int
-	]
+	hr: dxgi/CreateSwapChainForHwnd dxgi-factory d3d-device hWnd desc null null :int
 	assert zero? hr
 
 	DX-create-buffer rt as this! int
-
-	if win8+? [create-dcomp rt hWnd]
 	rt
 ]
 

From 938744fc0d5ae1ae48ca65c42c09356bb4884a83 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 15:41:02 +0100
Subject: [PATCH 0769/3432] FEAT: View: improve memory usage when changing DRAW
 facet.

---
 modules/view/view.red | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/modules/view/view.red b/modules/view/view.red
index 542a7a7803..f0e3a015f0 100644
--- a/modules/view/view.red
+++ b/modules/view/view.red
@@ -299,7 +299,10 @@ on-face-deep-change*: function ["Internal use only" owner word target action new
 				not find/skip next state/3 word 8
 			][
 				unless find [cleared removed taken] action [
-					if find [clear remove take] action [
+					if all [
+						find [clear remove take] action
+						word <> 'draw
+					][
 						index: 0
 						target: copy/part target part
 					]

From ac3f941fec8a715ae0bc57b4861209a2167d0cae Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 16:27:09 +0100
Subject: [PATCH 0770/3432] FEAT: adds round box in DRAW.

---
 modules/view/backends/windows/direct2d.reds | 27 +++++++++++-
 modules/view/backends/windows/draw.reds     | 47 +++++++++++++++------
 2 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds
index 3c9b68e532..40b8bf6c2e 100644
--- a/modules/view/backends/windows/direct2d.reds
+++ b/modules/view/backends/windows/direct2d.reds
@@ -64,6 +64,15 @@ RECT_F!: alias struct! [
 	bottom		[float32!]
 ]
 
+ROUNDED_RECT_F!: alias struct! [
+	left		[float32!]
+	top			[float32!]
+	right		[float32!]
+	bottom		[float32!]
+	radiusX		[float32!]
+	radiusY		[float32!]
+]
+
 SIZE_U!: alias struct! [
 	width		[uint32!]
 	height		[uint32!]
@@ -297,6 +306,20 @@ FillRectangle*: alias function! [
 	brush		[this!]
 ]
 
+DrawRoundedRectangle*: alias function! [
+	this		[this!]
+	rect		[ROUNDED_RECT_F!]
+	brush		[this!]
+	strokeWidth [float32!]
+	strokeStyle [this!]
+]
+
+FillRoundedRectangle*: alias function! [
+	this		[this!]
+	rect		[ROUNDED_RECT_F!]
+	brush		[this!]
+]
+
 DrawEllipse*: alias function! [
 	this		[this!]
 	ellipse		[D2D1_ELLIPSE]
@@ -840,8 +863,8 @@ CombineWithGeometry*: alias function! [
 	DrawLine						[DrawLine*]
 	DrawRectangle					[DrawRectangle*]
 	FillRectangle					[FillRectangle*]
-	DrawRoundedRectangle			[integer!]
-	FillRoundedRectangle			[integer!]
+	DrawRoundedRectangle			[DrawRoundedRectangle*]
+	FillRoundedRectangle			[FillRoundedRectangle*]
 	DrawEllipse						[DrawEllipse*]
 	FillEllipse						[FillEllipse*]
 	DrawGeometry					[function! [this [this!] geometry [this!] brush [this!] strokeWidth [float32!] style [this!] return: [integer!]]]
diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 34f8426562..45b3072858 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -926,41 +926,62 @@ OS-draw-box: func [
 	/local
 		this	[this!]
 		dc		[ID2D1DeviceContext]
-		rc		[RECT_F! value]
+		t		[integer!]
+		rc		[ROUNDED_RECT_F! value]
+		radius	[red-integer!]
+		type	[integer!]
 ][
 	this: as this! ctx/dc
 	dc: as ID2D1DeviceContext this/vtbl
 
+	radius: null
+	if TYPE_OF(lower) = TYPE_INTEGER [
+		radius: as red-integer! lower
+		rc/radiusX: as float32! radius/value
+		rc/radiusY: rc/radiusX
+		lower:  lower - 1
+	]
+	if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t]
+	if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t]
+
 	rc/right: as float32! lower/x
 	rc/bottom: as float32! lower/y
 	rc/left: as float32! upper/x
 	rc/top: as float32! upper/y
-	either ctx/brush-type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
+
+	type: ctx/brush-type
+	if type > DRAW_BRUSH_GRADIENT [		;-- fill-pen
 		calc-brush-position
 			ctx/brush
 			ctx/brush-grad-type
 			ctx/brush-offset
 			rc/left rc/top rc/right rc/bottom
-		dc/FillRectangle this rc ctx/brush
-		post-process-brush ctx/brush ctx/brush-offset
-	][
-		if ctx/brush-type <> DRAW_BRUSH_NONE [
-			dc/FillRectangle this rc ctx/brush 
+	]
+	if type <> DRAW_BRUSH_NONE [
+		either null? radius [
+			dc/FillRectangle this as RECT_F! :rc ctx/brush
+		][
+			dc/FillRoundedRectangle this :rc ctx/brush
 		]
 	]
-	either ctx/pen-type > DRAW_BRUSH_GRADIENT [
+	if type > DRAW_BRUSH_GRADIENT [post-process-brush ctx/brush ctx/brush-offset]
+
+	type: ctx/pen-type
+	if type > DRAW_BRUSH_GRADIENT [
 		calc-brush-position
 			ctx/pen
 			ctx/pen-grad-type
 			ctx/pen-offset
 			rc/left rc/top rc/right rc/bottom
-		dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
-		post-process-brush ctx/pen ctx/pen-offset
-	][
-		if ctx/pen-type <> DRAW_BRUSH_NONE [
-			dc/DrawRectangle this rc ctx/pen ctx/pen-width ctx/pen-style
+	]
+	if type <> DRAW_BRUSH_NONE [
+		either null? radius [
+			dc/DrawRectangle this as RECT_F! :rc ctx/pen ctx/pen-width ctx/pen-style
+		][
+			dc/DrawRoundedRectangle this :rc ctx/pen ctx/pen-width ctx/pen-style
 		]
 	]
+	if type > DRAW_BRUSH_GRADIENT [post-process-brush ctx/pen ctx/pen-offset]
 ]
 
 OS-draw-triangle: func [

From e3227ecefdb9d130d95f7ecb28eb83d17c891b03 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 16:27:42 +0100
Subject: [PATCH 0771/3432] FIX: error in view-test.red due to datatype changes
 in on-wheel event.

---
 tests/view-test.red | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/view-test.red b/tests/view-test.red
index 3c33a4818a..a11fbbf875 100644
--- a/tests/view-test.red
+++ b/tests/view-test.red
@@ -765,7 +765,7 @@ win/pane: reduce [
 		actors: object [
 			on-wheel: func [face [object!] event [event!]][
 				print [face/type event/picked]
-				canvas/offset/y: canvas/offset/y + event/picked
+				canvas/offset/y: canvas/offset/y + to-integer event/picked
 				unless live? [show canvas]
 			]
 		]

From 374eb6beeab78c179b26b621450c3ea0af8aa289 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 16:54:43 +0100
Subject: [PATCH 0772/3432] FIX: curve is auto-closed in DRAW.

---
 modules/view/backends/windows/draw.reds | 26 ++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 45b3072858..4276d97a66 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -481,7 +481,7 @@ OS-draw-shape-endpath: func [
 	sthis: as this! ctx/sub/sink
 	gsink: as ID2D1GeometrySink sthis/vtbl
 
-	gsink/EndFigure sthis either close? [1][0]
+	gsink/EndFigure sthis as-integer close?
 
 	hr: gsink/Close sthis
 	gsink/Release sthis
@@ -1267,8 +1267,7 @@ OS-draw-arc: func [
 		sweep		[integer!]
 		i			[integer!]
 		angle-end	[float32!]
-		start-x		[float32!]
-		start-y		[float32!]
+		pt-start	[POINT_2F value]
 		end-x		[float32!]
 		end-y		[float32!]
 		closed?		[logic!]
@@ -1298,10 +1297,10 @@ OS-draw-arc: func [
 	sweep: angle/value
 	i: begin/value + sweep
 	angle-end: rad * as float32! i
-	start-x: as float32! cos as float! angle-begin
-	start-x: cx + (rad-x * start-x)
-	start-y: as float32! sin as float! angle-begin
-	start-y: cy + (rad-y * start-y)
+	pt-start/x: as float32! cos as float! angle-begin
+	pt-start/x: cx + (rad-x * pt-start/x)
+	pt-start/y: as float32! sin as float! angle-begin
+	pt-start/y: cy + (rad-y * pt-start/y)
 	end-x: as float32! cos as float! angle-end
 	end-x: cx + (rad-x * end-x)
 	end-y: as float32! sin as float! angle-end
@@ -1317,9 +1316,14 @@ OS-draw-arc: func [
 	sthis: as this! sink/value
 	gsink: as ID2D1GeometrySink sthis/vtbl
 
-	point/x: start-x
-	point/y: start-y
-	gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE
+	either closed? [
+		point/x: cx point/y: cy
+	][
+		point/x: pt-start/x point/y: pt-start/y
+	]
+	gsink/BeginFigure sthis :point as-integer not closed?
+	if closed? [gsink/AddLine sthis :pt-start]
+
 	arc/point/x: end-x
 	arc/point/y: end-y
 	arc/size/width: rad-x
@@ -1401,7 +1405,7 @@ OS-draw-curve: func [
 
 	point/x: as float32! start/x
 	point/y: as float32! start/y
-	gsink/BeginFigure sthis point as-integer ctx/brush-type = DRAW_BRUSH_NONE
+	gsink/BeginFigure sthis point 1
 	hr: gsink/AddBezier sthis ps
 	gsink/EndFigure sthis 0
 	hr: gsink/Close sthis

From 73b28a257df89db1cc171bd4310b96200fc9a3e1 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Mon, 13 Jan 2020 18:30:01 +0100
Subject: [PATCH 0773/3432] FEAT: allows changing the current input position
 from a lexer callback.

---
 runtime/lexer.reds   |  8 ++++++++
 runtime/unicode.reds | 12 ++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 4620f29345..04897623cc 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -405,6 +405,14 @@ lexer: context [
 		catch RED_THROWN_ERROR [_function/call lex/fun-ptr global-ctx]	;FIXME: hardcoded origin context
 		if system/thrown <> 0 [re-throw]
 
+		if ser/head <> y [
+			lex/in-series/head: ser/head
+			either TYPE_OF(ser) = TYPE_BINARY [
+				lex/in-pos: lex/input + ser/head
+			][
+				lex/in-pos: unicode/skip-chars lex/input lex/in-end ser/head
+			]
+		]
 		cont?: logic/top-true?
 		stack/unwind
 		cont?
diff --git a/runtime/unicode.reds b/runtime/unicode.reds
index 115fa397c3..a0467e36ff 100644
--- a/runtime/unicode.reds
+++ b/runtime/unicode.reds
@@ -85,6 +85,18 @@ unicode: context [
 		]
 		c
 	]
+	
+	;-- Skips a given amount of UTF-8 encoded characters in a binary buffer
+	skip-chars: func [s e [byte-ptr!] c [integer!] return: [byte-ptr!]
+		/local len [integer!] p [byte-ptr!]
+	][
+		len: 0
+		while [all [c > 0 s < e]][
+			s: fast-decode-utf8-char s :len
+			c: c - 1
+		]
+		s
+	]
 
 	latin1-idx: [
 		0402h 0403h 201Ah 0453h 201Eh 2026h 2020h 2021h

From 8b2f23a050629bf9c48627550184d9c100b961e2 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Mon, 13 Jan 2020 18:48:09 +0100
Subject: [PATCH 0774/3432] FIX: draw elliptical arc properly.

---
 modules/view/backends/windows/draw.reds | 25 +++++++++++++++++++++++++
 system/runtime/libc.reds                |  4 ++++
 2 files changed, 29 insertions(+)

diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds
index 4276d97a66..14672f0639 100644
--- a/modules/view/backends/windows/draw.reds
+++ b/modules/view/backends/windows/draw.reds
@@ -1283,6 +1283,10 @@ OS-draw-arc: func [
 		this		[this!]
 		dc			[ID2D1DeviceContext]
 		arc			[D2D1_ARC_SEGMENT value]
+		alpha		[float!]
+		beta		[float!]
+		rx			[float!]
+		ry			[float!]
 ][
 	cx: as float32! center/x
 	cy: as float32! center/y
@@ -1297,6 +1301,27 @@ OS-draw-arc: func [
 	sweep: angle/value
 	i: begin/value + sweep
 	angle-end: rad * as float32! i
+
+	;-- adjust angles for ellipses
+	if rad-x <> rad-y [
+		alpha: as float! angle-begin
+		beta: as float! angle-end
+		rx: as float! rad-x
+		ry: as float! rad-y
+		alpha: atan2 (sin alpha) * rx (cos alpha) * ry
+		beta:  atan2 (sin beta)  * rx (cos beta) * ry
+
+		if PI < fabs beta - alpha [
+			either beta > alpha [
+				beta: beta - (PI * 2.0)
+			][
+				alpha: alpha - (PI * 2.0)
+			]
+		]
+		angle-begin: as float32! alpha
+		angle-end: as float32! beta
+	]
+
 	pt-start/x: as float32! cos as float! angle-begin
 	pt-start/x: cx + (rad-x * pt-start/x)
 	pt-start/y: as float32! sin as float! angle-begin
diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds
index 12403de942..d17e736a4a 100644
--- a/system/runtime/libc.reds
+++ b/system/runtime/libc.reds
@@ -143,6 +143,10 @@ Red/System [
 			value		[float!]
 			return:		[float!]
 		]
+		fabs:		"fabs" [
+			value		[float!]
+			return:		[float!]
+		]
 		fmod:		"fmod" [
 			x           [float!]
 			y           [float!]

From 0dc76ab27a135b5e6fb1f4d749776d57085e9bf9 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Tue, 14 Jan 2020 16:07:01 +0800
Subject: [PATCH 0775/3432] FIX: draw elliptical arc properly for gtk3

---
 modules/view/backends/gtk3/draw.reds | 24 ++++++++++++++++++++++++
 system/runtime/libc.reds             |  4 ++++
 2 files changed, 28 insertions(+)

diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds
index 67032362fe..7e0cc66036 100644
--- a/modules/view/backends/gtk3/draw.reds
+++ b/modules/view/backends/gtk3/draw.reds
@@ -1125,6 +1125,10 @@ OS-draw-arc: func [
 		sweep		[integer!]
 		i			[integer!]
 		closed?		[logic!]
+		alpha		[float!]
+		beta		[float!]
+		rx			[float!]
+		ry			[float!]
 ][
 	cr: dc/cr
 	cx: as float! center/x
@@ -1141,6 +1145,26 @@ OS-draw-arc: func [
 	i: begin/value + sweep
 	angle-end: rad * as float! i
 
+	;-- adjust angles for ellipses
+	if rad-x <> rad-y [
+		alpha: angle-begin
+		beta: angle-end
+		rx: rad-x
+		ry: rad-y
+		alpha: atan2 (sin alpha) * rx (cos alpha) * ry
+		beta:  atan2 (sin beta)  * rx (cos beta) * ry
+
+		if PI < fabs beta - alpha [
+			either beta > alpha [
+				beta: beta - (PI * 2.0)
+			][
+				alpha: alpha - (PI * 2.0)
+			]
+		]
+		angle-begin: alpha
+		angle-end: beta
+	]
+
 	closed?: angle < end
 
 	cairo_save cr
diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds
index bd33977270..5e772aaf4f 100644
--- a/system/runtime/libc.reds
+++ b/system/runtime/libc.reds
@@ -143,6 +143,10 @@ Red/System [
 			value		[float!]
 			return:		[float!]
 		]
+		fabs:		"fabs" [
+			value		[float!]
+			return:		[float!]
+		]
 		fmod:		"fmod" [
 			x           [float!]
 			y           [float!]

From 62d0d075fbe3241e87311674d1a12221ea2de7b0 Mon Sep 17 00:00:00 2001
From: bitbegin 
Date: Tue, 14 Jan 2020 16:19:21 +0800
Subject: [PATCH 0776/3432] FIX: small code improve

---
 modules/view/backends/gtk3/draw.reds | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds
index 7e0cc66036..76c3349372 100644
--- a/modules/view/backends/gtk3/draw.reds
+++ b/modules/view/backends/gtk3/draw.reds
@@ -1125,10 +1125,6 @@ OS-draw-arc: func [
 		sweep		[integer!]
 		i			[integer!]
 		closed?		[logic!]
-		alpha		[float!]
-		beta		[float!]
-		rx			[float!]
-		ry			[float!]
 ][
 	cr: dc/cr
 	cx: as float! center/x
@@ -1147,22 +1143,16 @@ OS-draw-arc: func [
 
 	;-- adjust angles for ellipses
 	if rad-x <> rad-y [
-		alpha: angle-begin
-		beta: angle-end
-		rx: rad-x
-		ry: rad-y
-		alpha: atan2 (sin alpha) * rx (cos alpha) * ry
-		beta:  atan2 (sin beta)  * rx (cos beta) * ry
-
-		if PI < fabs beta - alpha [
-			either beta > alpha [
-				beta: beta - (PI * 2.0)
+		angle-begin: atan2 (sin angle-begin) * rad-x (cos angle-begin) * rad-y
+		angle-end:   atan2 (sin angle-end)  * rad-x (cos angle-end) * rad-y
+
+		if PI < fabs angle-end - angle-begin [
+			either angle-end > angle-begin [
+				angle-end: angle-end - (PI * 2.0)
 			][
-				alpha: alpha - (PI * 2.0)
+				angle-begin: angle-begin - (PI * 2.0)
 			]
 		]
-		angle-begin: alpha
-		angle-end: beta
 	]
 
 	closed?: angle < end

From 1fc38902ff3753808049fea031ce96c052a4565e Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Tue, 14 Jan 2020 18:48:22 +0100
Subject: [PATCH 0777/3432] FEAT: improves lexer errors canceling from within
 the callback function.

---
 runtime/lexer.reds | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 04897623cc..0220296e4f 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -269,6 +269,7 @@ lexer: context [
 		ERR_MISSING: 	  -3
 		ERR_CLOSING: 	  -4
 		LEX_INT_OVERFLOW: -5
+		LEX_ERR:		  10
 	]
 	
 	state!: alias struct! [
@@ -317,7 +318,7 @@ lexer: context [
 			len	 [integer!]
 			c	 [byte!]
 	][
-		if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [exit]]
+		if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [throw LEX_ERR]]
 		e: lex/in-end
 		len: 0
 		if null? s [									;-- determine token's start
@@ -1765,7 +1766,7 @@ lexer: context [
 			]
 			if load? [
 				do-scan: as scanner! scanners/index
-				do-scan lex s p flags
+				catch LEX_ERR [do-scan lex s p flags]
 
 				if all [state >= T_STRING lex/fun-ptr <> null][ ;-- for < T_STRING, events are triggered from scan-*
 					slot: lex/tail - 1
@@ -1779,7 +1780,7 @@ lexer: context [
 			lex/in-pos >= lex/in-end
 		]
 		
-		if lex/entry = S_M_STRING [throw-error lex start lex/in-end TYPE_STRING]
+		if lex/entry = S_M_STRING [catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING]]
 		assert lex/in-pos = lex/in-end
 	]
 
@@ -1793,14 +1794,19 @@ lexer: context [
 		fun	  [red-function!]							;-- optional callback function
 		ser	  [red-series!]								;-- optional input series back-reference
 		/local
-			blk	  [red-block!]
-			p	  [red-point!]
-			slots [integer!]
-			s	  [series!]
-			lex	  [state! value]
+			blk	  	 [red-block!]
+			p	  	 [red-point!]
+			slots 	 [integer!]
+			s	  	 [series!]
+			lex	  	 [state! value]
+			clean-up [subroutine!]
 	][
 		if zero? depth [root-state: lex]
 		depth: depth + 1
+		clean-up: [
+			depth: depth - 1
+			if zero? depth [root-state: null]
+		]
 		
 		lex/next:		null							;-- last element of the states linked list
 		lex/buffer:		stash							;TBD: support dyn buffer case
@@ -1827,7 +1833,8 @@ lexer: context [
 			p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer]
 			if TYPE_OF(p) = TYPE_POINT [
 				lex/closing: p/y >> 16
-				throw-error lex lex/input + p/z lex/in-end ERR_CLOSING
+				catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING]
+				if system/thrown <> 0 [dst/header: TYPE_NONE clean-up exit]
 			]
 		]
 		either all [one? not wrap? slots > 0][
@@ -1836,9 +1843,7 @@ lexer: context [
 			store-any-block dst lex/buffer slots TYPE_BLOCK
 		]
 		len/value: as-integer lex/in-pos - lex/input
-		
-		depth: depth - 1
-		if zero? depth [root-state: null]
+		clean-up
 	]
 
 	load-string: func [

From 74ecdd4c618daedf047745278f7039b57644c009 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Tue, 14 Jan 2020 19:04:10 +0100
Subject: [PATCH 0778/3432] FEAT: supports lexer callbacks defined in objects.

---
 runtime/lexer.reds | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 0220296e4f..541aa696b3 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -375,11 +375,18 @@ lexer: context [
 			ser	  [red-series!]
 			res	  [red-value!]
 			blk	  [red-block!]
+			int	  [red-integer!]
+			more  [series!]
+			ctx	  [node!]
 			cont? [logic!]
 	][
 		if all [event = words/_scan type = -2][event: words/_error type: TYPE_ERROR]
+
+		more: as series! lex/fun-ptr/more/value
+		int: as red-integer! more/offset + 4
+		ctx: either TYPE_OF(int) = TYPE_INTEGER [as node! int/value][lex/fun-ptr/ctx]
 		
-		stack/mark-func words/_body	lex/fun-ptr/ctx		;@@ find something more adequate
+		stack/mark-func words/_body	ctx
 		stack/push as red-value! event					;-- event
 		ser: as red-series! stack/push as red-value! lex/in-series ;-- input
 		

From 7498fef5160c54565551d81a034ad67b80167b39 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Tue, 14 Jan 2020 19:04:10 +0100
Subject: [PATCH 0779/3432] FEAT: supports lexer callbacks defined in objects.

---
 runtime/lexer.reds | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index 0220296e4f..bb024dfab8 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -375,9 +375,16 @@ lexer: context [
 			ser	  [red-series!]
 			res	  [red-value!]
 			blk	  [red-block!]
+			int	  [red-integer!]
+			more  [series!]
+			ctx	  [node!]
 			cont? [logic!]
 	][
 		if all [event = words/_scan type = -2][event: words/_error type: TYPE_ERROR]
+
+		more: as series! lex/fun-ptr/more/value
+		int: as red-integer! more/offset + 4
+		ctx: either TYPE_OF(int) = TYPE_INTEGER [as node! int/value][global-ctx]
 		
 		stack/mark-func words/_body	lex/fun-ptr/ctx		;@@ find something more adequate
 		stack/push as red-value! event					;-- event
@@ -403,7 +410,7 @@ lexer: context [
 		either null? value [pair/push x + 1 y + 1][stack/push value] ;-- token
 
 		if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs]	;-- +1 for /local refinement
-		catch RED_THROWN_ERROR [_function/call lex/fun-ptr global-ctx]	;FIXME: hardcoded origin context
+		catch RED_THROWN_ERROR [_function/call lex/fun-ptr ctx]
 		if system/thrown <> 0 [re-throw]
 
 		if ser/head <> y [

From 8f3b2832b52eaeb2442d60a0854153daf88ff134 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 15 Jan 2020 00:03:15 +0100
Subject: [PATCH 0780/3432] FIX: sets properly the lexer callback context on
 the call stack.

---
 runtime/lexer.reds | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/lexer.reds b/runtime/lexer.reds
index acae7b937c..a99b83927a 100644
--- a/runtime/lexer.reds
+++ b/runtime/lexer.reds
@@ -386,7 +386,7 @@ lexer: context [
 		int: as red-integer! more/offset + 4
 		ctx: either TYPE_OF(int) = TYPE_INTEGER [as node! int/value][global-ctx]
 		
-		stack/mark-func words/_body	ctx
+		stack/mark-func words/_body	lex/fun-ptr/ctx
 		stack/push as red-value! event					;-- event
 		ser: as red-series! stack/push as red-value! lex/in-series ;-- input
 		

From e4d17f83f8772c576f425b3c4826a5e5b80e8b2d Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 15 Jan 2020 00:41:43 +0100
Subject: [PATCH 0781/3432] FEAT: allows Parse callbacks to be defined in
 objects.

---
 runtime/parse.reds | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/runtime/parse.reds b/runtime/parse.reds
index b3b987ae02..9cbce24b6d 100644
--- a/runtime/parse.reds
+++ b/runtime/parse.reds
@@ -674,11 +674,18 @@ parser: context [
 			len	  [integer!]
 			saved [red-value!]
 			res	  [red-value!]
+			int	  [red-integer!]
+			more  [series!]
+			ctx	  [node!]
 	][
 		PARSE_SAVE_SERIES
 		saved: stack/top
 		stack/top: stack/top + 1						;-- keep last value from paren expression
 
+		more: as series! fun/more/value
+		int: as red-integer! more/offset + 4
+		ctx: either TYPE_OF(int) = TYPE_INTEGER [as node! int/value][global-ctx]
+
 		stack/mark-func words/_body	fun/ctx				;@@ find something more adequate
 		stack/push as red-value! event
 		logic/push match?
@@ -687,7 +694,7 @@ parser: context [
 		stack/push as red-value! rules
 		if positive? locals [_function/init-locals 1 + locals]	;-- +1 for /local refinement
 		
-		catch RED_THROWN_ERROR [_function/call fun global-ctx]	;FIXME: hardcoded origin context
+		catch RED_THROWN_ERROR [_function/call fun ctx]
 
 		PARSE_RESTORE_SERIES							;-- restore localy saved series/head first
 		if system/thrown <> 0 [reset saved? re-throw]

From 3f5a7fa3f8b07bcb6efb59c2278c402b5e521d38 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 15 Jan 2020 00:42:32 +0100
Subject: [PATCH 0782/3432] FEAT: hides parse-trace dependencies in a local
 context.

---
 boot.red                  |  4 +-
 environment/functions.red | 88 ++++++++++++++++++++-------------------
 2 files changed, 47 insertions(+), 45 deletions(-)

diff --git a/boot.red b/boot.red
index db79bc818c..68b9227017 100644
--- a/boot.red
+++ b/boot.red
@@ -18,12 +18,12 @@ Red [
 	#include %environment/routines.red
 	#include %environment/scalars.red
 	#include %environment/colors.red
+	
+	#register-intrinsics
 	#include %environment/functions.red
 	#include %environment/system.red
 	#include %environment/operators.red
 
-	#register-intrinsics
-
 	#include %environment/codecs/png.red
 	#include %environment/codecs/jpeg.red
 	#include %environment/codecs/bmp.red
diff --git a/environment/functions.red b/environment/functions.red
index 0b60232482..4f69286bae 100644
--- a/environment/functions.red
+++ b/environment/functions.red
@@ -300,55 +300,57 @@ charset: func [
 	make bitset! spec
 ]
 
-p-indent: make string! 30								;@@ to be put in a local context
-
-on-parse-event: func [
-	"Standard parse/trace callback used by PARSE-TRACE"
-	event	[word!]   "Trace events: push, pop, fetch, match, iterate, paren, end"
-	match?	[logic!]  "Result of last matching operation"
-	rule	[block!]  "Current rule at current position"
-	input	[series!] "Input series at next position to match"
-	stack	[block!]  "Internal parse rules stack"
-	return: [logic!]  "TRUE: continue parsing, FALSE: stop and exit parsing"
-][
-	switch event [
-		push  [
-			print [p-indent "-->"]
-			append p-indent "  "
-		]
-		pop	  [
-			clear back back tail p-indent
-			print [p-indent "<--"]
-		]
-		fetch [
-			print [
-				p-indent "match:" mold/flat/part rule 50 newline
-				p-indent "input:" mold/flat/part input 50 p-indent
+context [
+	p-indent: make string! 30
+	
+	on-parse-event: func [
+		"Standard parse/trace callback used by PARSE-TRACE"
+		event	[word!]   "Trace events: push, pop, fetch, match, iterate, paren, end"
+		match?	[logic!]  "Result of last matching operation"
+		rule	[block!]  "Current rule at current position"
+		input	[series!] "Input series at next position to match"
+		stack	[block!]  "Internal parse rules stack"
+		return: [logic!]  "TRUE: continue parsing, FALSE: stop and exit parsing"
+	][
+		switch event [
+			push  [
+				print [p-indent "-->"]
+				append p-indent "  "
+			]
+			pop	  [
+				clear back back tail p-indent
+				print [p-indent "<--"]
 			]
+			fetch [
+				print [
+					p-indent "match:" mold/flat/part rule 50 newline
+					p-indent "input:" mold/flat/part input 50 p-indent
+				]
+			]
+			match [print [p-indent "==>" pick ["matched" "not matched"]  match?]]
+			end   [print ["return:" match?]]
 		]
-		match [print [p-indent "==>" pick ["matched" "not matched"]  match?]]
-		end   [print ["return:" match?]]
+		true
 	]
-	true
-]
 
-parse-trace: func [
-	"Wrapper for parse/trace using the default event processor"
-	input [series!]
-	rules [block!]
-	/case "Uses case-sensitive comparison"
-	/part "Limit to a length or position"
-		limit [integer!]
-	return: [logic! block!]
-][
-	clear p-indent
-	either case [
-		parse/case/trace input rules :on-parse-event
+	set 'parse-trace func [
+		"Wrapper for parse/trace using the default event processor"
+		input [series!]
+		rules [block!]
+		/case "Uses case-sensitive comparison"
+		/part "Limit to a length or position"
+			limit [integer!]
+		return: [logic! block!]
 	][
-		either part [
-			parse/part/trace input rules limit :on-parse-event
+		clear p-indent
+		either case [
+			parse/case/trace input rules :on-parse-event
 		][
-			parse/trace input rules :on-parse-event
+			either part [
+				parse/part/trace input rules limit :on-parse-event
+			][
+				parse/trace input rules :on-parse-event
+			]
 		]
 	]
 ]

From 1ec2aae09f911f5210c4587749b0f891c4249865 Mon Sep 17 00:00:00 2001
From: Xie Qingtian 
Date: Wed, 15 Jan 2020 13:20:17 +0100
Subject: [PATCH 0783/3432] FEAT: remove the old code highlighter in the
 gui-console.

---
 environment/console/GUI/highlight.red | 511 ++------------------------
 1 file changed, 28 insertions(+), 483 deletions(-)

diff --git a/environment/console/GUI/highlight.red b/environment/console/GUI/highlight.red
index 08878ddb0f..ae4e385794 100644
--- a/environment/console/GUI/highlight.red
+++ b/environment/console/GUI/highlight.red
@@ -11,494 +11,39 @@ Red [
 ]
 
 highlight: context [
-	throw-error: function [spec [block!] /missing][
-		type: spec/1									;-- preserve lit-words from double reduction
+	_dst:   none
+	_theme: none
+
+	lex: func [
+		event	[word!]
+		input	[string! binary!]
+		type	[datatype! word! none!]
+		line	[integer!]
+		token
+		return:	[logic!]
+		/local style
+	][
+		switch event [
+			scan [
+				if all [type style: select _theme type][
+					append _dst as-pair token/x token/y - token/x
+					append _dst style
+				]
+			]
+			error [input: next input]
+		]
+		false
 	]
-	
-	add-styles: function [
+
+	add-styles: func [
 		src		[string!]
 		dst		[block! none!]
 		theme	[map!]
-		/part	
-			length [integer! string!]
 		return: [block!]
-		/local
-			new s e len style c pos value cnt type process path
-			digit hexa-upper hexa-lower hexa hexa-char not-word-char not-word-1st
-			not-file-char not-str-char not-mstr-char caret-char
-			non-printable-char integer-end ws-ASCII ws-U+2k control-char
-			four half non-zero path-end base base64-char slash-end not-url-char
-			email-end
 	][
-		cs:		[- - - - - - - - - - - - - - - - - - - - - - - -]	;-- memoized bitsets
-		count?:	yes										;-- if TRUE, lines counter is enabled
-
-		stack: 0
-		line: 1
-		dst: any [dst make block! 200]
-
-		if cs/1 = '- [
-			cs/1:  charset "0123465798"					;-- digit
-			cs/2:  charset "ABCDEF"						;-- hexa-upper
-			cs/3:  charset "abcdef"						;-- hexa-lower
-			cs/4:  union cs/1 cs/2						;-- hexa
-			cs/5:  union cs/4 cs/3						;-- hexa-char	
-			cs/6:  charset {/\^^,[](){}"#%$@:;}			;-- not-word-char
-			cs/7:  union union cs/6 cs/1 charset {'}	;-- not-word-1st
-			cs/8:  charset {[](){}"@:;}					;-- not-file-char
-			cs/9:  #"^""								;-- not-str-char
-			cs/10: #"}"									;-- not-mstr-char
-			cs/11: charset [#"^(40)" - #"^(5F)"]		;-- caret-char
-			cs/12: charset [							;-- non-printable-char
-				#"^(00)" - #"^(08)"						;-- (exclude TAB)
-				#"^(0A)" - #"^(1F)"
-			]
-			cs/13: charset {^{"[]();:xX}				;-- integer-end
-			cs/14: charset " ^-^M"						;-- ws-ASCII, ASCII common whitespaces
-			cs/15: charset [#"^(2000)" - #"^(200A)"]	;-- ws-U+2k, Unicode spaces in the U+2000-U+200A range
-			cs/16: charset [ 							;-- Control characters
-				#"^(00)" - #"^(1F)"						;-- C0 control codes
-				#"^(80)" - #"^(9F)"						;-- C1 control codes
-			]
-			cs/17: charset "01234"						;-- four
-			cs/18: charset "012345"						;-- half
-			cs/19: charset "123456789"					;-- non-zero
-			cs/20: charset {^{"[]();}					;-- path-end
-			cs/21: union cs/1 charset [					;-- base64-char
-				#"A" - #"Z" #"a" - #"z" #"+" #"/" #"="
-			]
-			cs/22: charset {[](){}":;}					;-- slash-end
-			cs/23: charset {[](){}";}					;-- not-url-char
-			cs/24: union cs/8 union cs/14 charset "<^/" ;-- email-end
-		]
-		set [
-			digit hexa-upper hexa-lower hexa hexa-char not-word-char not-word-1st
-			not-file-char not-str-char not-mstr-char caret-char
-			non-printable-char integer-end ws-ASCII ws-U+2k control-char
-			four half non-zero path-end base64-char slash-end not-url-char email-end
-		] cs
-
-		byte: [
-			"25" half
-			| "2" four digit
-			| "1" digit digit
-			| non-zero digit
-			| digit
-		]
-
-		;-- Whitespaces list from: http://en.wikipedia.org/wiki/Whitespace_character
-		ws: [
-			pos: #"^/" (
-				if count? [
-					line: line + 1 
-				]
-			)
-			| ws-ASCII									;-- only the common whitespaces are matched
-			;| #"^(0085)"								;-- U+0085 (Newline)
-			| #"^(00A0)"								;-- U+00A0 (No-break space)
-			;| #"^(1680)"								;-- U+1680 (Ogham space mark)
-			;| #"^(180E)"								;-- U+180E (Mongolian vowel separator)
-			;| ws-U+2k									;-- U+2000-U+200A range
-			;| #"^(2028)"								;-- U+2028 (Line separator)
-			;| #"^(2029)"								;-- U+2029 (Paragraph separator)
-			;| #"^(202F)"								;-- U+202F (Narrow no-break space)
-			;| #"^(205F)"								;-- U+205F (Medium mathematical space)
-			;| #"^(3000)"								;-- U+3000 (Ideographic space)
-		]
-
-		newline-char: [
-			#"^/"
-			| #"^(0085)"								;-- U+0085 (Newline)
-			| #"^(2028)"								;-- U+2028 (Line separator)
-			| #"^(2029)"								;-- U+2029 (Paragraph separator)
-		]
-
-		counted-newline: [pos: #"^/" (line: line + 1)]
-
-		ws-no-count: [(count?: no) ws (count?: yes)]
-
-		escaped-char: [
-			"^^(" [
-				[										;-- special case first
-					"null" 	 (value: #"^(00)")
-					| "back" (value: #"^(08)")
-					| "tab"  (value: #"^(09)")
-					| "line" (value: #"^(0A)")
-					| "page" (value: #"^(0C)")
-					| "esc"  (value: #"^(1B)")
-					| "del"	 (value: #"^(7F)")
-				]
-				| pos: [2 6 hexa-char] (				;-- Unicode values allowed up to 10FFFFh
-					type: 'char!
-				)
-			] #")"
-			| #"^^" [
-				[
-					#"/" 	(value: #"^/")
-					| #"-"	(value: #"^-")
-					| #"?" 	(value: #"^(del)")			;@@FIXME
-					| #"^^" (value: #"^^")				;-- caret escaping case
-					| #"{"	(value: #"{")
-					| #"}"	(value: #"}")
-					| #"^""	(value: #"^"")
-				]
-				| pos: caret-char (value: pos/1 - 64)
-			]
-		]
-
-		char-rule: [
-			{#"} [
-				 escaped-char
-				| ahead [non-printable-char | not-str-char]
-				  (throw-error [char! skip s -2])
-				  reject
-				| skip (value: s/1)
-			][
-				{"} (type: 'char!)
-				| (throw-error [char! skip s -2])
-			]
-		]
-
-		line-string: [
-			#"^"" any [
-				{^^"}
-				| ahead [#"^"" | newline-char] break
-				| escaped-char
-				| skip
-			]
-			#"^""
-		]
-
-		nested-curly-braces: [
-			(cnt: 1)
-			any [
-				counted-newline 
-				| "^^{"
-				| "^^}"
-				| #"{" (cnt: cnt + 1)
-				| #"}" if (zero? cnt: cnt - 1) break
-				| escaped-char
-				| skip
-			]
-		]
-
-		multiline-string: [
-			#"{" nested-curly-braces (unless zero? cnt [throw-error [string! s]])
-		]
-
-		string-rule: [(type: 'string!) line-string | multiline-string]
-		
-		tag-rule: [
-			#"<" not [#"=" | #">" | #"<" | ws] (type: 'tag!)
-			 some [#"^"" thru #"^"" | #"'" thru #"'" | e: #">" break | skip]
-			(if e/1 <> #">" [throw-error [tag! back s]])
-		]
-		
-		email-rule: [
-			some [ahead email-end break | skip] #"@"
-			any [ahead email-end break | skip]
-			(type: 'email!)
-		]
-
-		base-2-rule: [
-			"2#{" [
-				any [counted-newline | 8 [#"0" | #"1" ] | ws-no-count | comment-rule] #"}"
-				| break
-			] (base: 2)
-		]
-
-		base-16-rule: [
-			opt "16" "#{" [
-				any [counted-newline | 2 hexa-char | ws-no-count | comment-rule] #"}"
-				| break
-			] (base: 16)
-		]
-
-		base-64-rule: [
-			"64#{" (cnt: 0) [
-				any [counted-newline | base64-char | ws-no-count (cnt: cnt + 1) | comment-rule] #"}"
-				| break
-			] (base: 64)
-		]
-
-		binary-rule: [base-16-rule | base-64-rule | base-2-rule]
-
-		file-rule: [
-			#"%" [
-				#"{" (throw-error [file! s])
-				| line-string (type: 'file!)
-				| any [ahead [not-file-char | ws-no-count] break | skip]
-				  (type: 'file!)
-			]
-		]
-
-		url-rule: [
-			#":" not [not-url-char | ws-no-count | end]
-			any [#"@" | #":" | ahead [not-file-char | ws-no-count] break | skip]
-			(type: 'url!)
-		]
-
-		symbol-rule: [
-			(ot: none) some [
-				ahead [not-word-char | ws-no-count | control-char] break
-				| #"<" ot: [ahead #"/" (ot: back ot) :ot break | none]	;-- a
-				| #">" if (ot) [(ot: back ot) :ot break]				;-- a
-				| skip
-			] e:
-		]
-
-		begin-symbol-rule: [							;-- 1st char in symbols is restricted
-			[not ahead [not-word-1st | ws-no-count | control-char]]
-			symbol-rule
-		]
-
-		path-rule: [
-			ahead slash (								;-- path detection barrier
-				stack: stack + 1
-				type: 'path!
-			)
-			some [
-				slash
-				[
-					integer-number-rule
-					| begin-symbol-rule			(type: 'word!)
-					| paren-rule
-					| #":" begin-symbol-rule	(type: 'get-word!)
-					;@@ add more datatypes here
-					| (throw-error [path! path])
-					  reject
-				]
-			]
-			opt [#":" (type: 'set-path!)][
-				ahead [path-end | ws | end] | (throw-error [type path])
-			]
-			(stack: stack + 1)
-		]
-		
-		special-words: [
-			#"%" [ws-no-count | end] (value: "%")	;-- special case for remainder op!
-			| #"/" ahead [slash-end | slash | ws-no-count | control-char | end][
-				#"/" 
-				ahead [slash-end | ws-no-count | control-char | end] (value: "//")
-				| (value: "/")
-			]
-			| "<>" (value: "<>")
-		]
-
-		word-rule: 	[
-			(type: 'word!) special-words	opt [#":" (type: 'set-word!)]
-			| path: begin-symbol-rule (type: 'word!) [
-				url-rule
-				| path-rule							;-- path matched
-				| opt [#":" (type: 'set-word!)]
-			]
-		]
-
-		get-word-rule: [
-			#":" (type: 'get-word!) [
-				special-words
-				| begin-symbol-rule [
-					path-rule (type: 'get-path!)
-					| (type: 'get-word!)	;-- get-word matched
-				]
-			]
-		]
-
-		lit-word-rule: [
-			#"'" (type: 'lit-word!) [
-				special-words
-				| [
-					begin-symbol-rule [
-						path-rule (type: 'lit-path!)			 ;-- path matched
-						| (type: 'lit-word!) ;-- lit-word matched
-					]
-				]
-			]
-			opt [#":" (throw-error [type back s])]
-		]
-
-		issue-rule: [
-			#"#" (type: 'issue!) symbol-rule (
-				if (index? s) = index? e [throw-error [type skip s -4]]
-			)
-		]
-		
-
-		refinement-rule: [
-			slash [
-				some slash (type: 'word!)				;--  ///... case
-				| ahead [not-word-char | ws-no-count | control-char] (type: 'word!) ;-- / case
-				| symbol-rule (type: 'refinement! next s)
-			]
-		]
-		
-		sticky-word-rule: [								;-- protect from sticky words typos
-			ahead [integer-end | ws-no-count | end | (throw-error [type s])]
-		]
-		hexa-rule: [2 8 hexa #"h"]
-
-		tuple-value-rule: [byte 2 11 [dot byte] (type: 'tuple!)]
-
-		tuple-rule: [tuple-value-rule sticky-word-rule]
-		
-		time-rule: [
-			positive-integer-rule [
-				float-number-rule ;-- mm:ss.dd
-				| [
-					#":" positive-integer-rule opt float-number-rule	;-- hh:mm:ss[.dd]
-					| (type: 'time!)						;-- hh:mm
-				]
-			] (type: 'time!)
-		]
-		
-		positive-integer-rule: [(type: 'integer!) digit any digit]
-
-		integer-number-rule: [
-			opt [#"-" (neg?: yes) | #"+" (neg?: no)] digit any [digit | #"'" digit] (type: 'integer!)
-		]
-
-		integer-rule: [
-			float-special	;-- escape path for NaN, INFs
-			| (neg?: no) integer-number-rule
-			  opt [float-number-rule | float-exp-rule (type: 'float!)]
-			  opt [#"%" (type: 'percent!)]
-			  sticky-word-rule
-			  opt [
-				[#"x" | #"X"] integer-number-rule
-				(type: 'pair!)
-			  ]
-			  opt [#":" [time-rule | (throw-error [type pos])]]
-		]
-
-		float-special: [
-			opt #"-" "1.#" [
-				[[#"N" | #"n"] [#"a" | #"A"] [#"N" | #"n"]]
-				| [[#"I" | #"i"] [#"N" | #"n"] [#"F" | #"f"]]
-			] (type: 'float!)
-		]
-
-		float-exp-rule: [[#"e" | #"E"] opt [#"-" | #"+"] 1 3 digit]
-
-		float-number-rule: [
-			[dot | comma] digit any [digit | #"'" digit]
-			opt float-exp-rule (type: 'float!)
-		]
-
-		float-rule: [
-			opt [#"-" | #"+"] float-number-rule
-			opt [#"%" (type: 'percent!)]
-			sticky-word-rule
-		]
-		
-		map-rule: [
-			"#(" (stack: stack + 1)
-			any-value (type: none)
-			#")" (stack: stack - 1)
-		]
-
-		block-rule: [
-			#"[" (stack: stack + 1)
-			any-value (type: none)
-			#"]" (stack: stack - 1)
-		]
-
-		paren-rule: [
-			#"(" (stack: stack + 1)
-			any-value (type: none)
-			#")" (stack: stack - 1)
-		]
-
-		escaped-rule: [
-			"#[" pos: any ws [
-				  "true"  			(value: true)
-				| "false" 			(value: false)
-				| [
-					"none!"			
-					| "logic!"
-					| "block!"
-					| "integer!"
-					| "word!"
-					| "set-word!"
-					| "get-word!"
-					| "lit-word!"
-					| "refinement!"
-					| "binary!"
-					| "string!"
-					| "char!"
-					| "bitset!"
-					| "path!"
-					| "set-path!"
-					| "lit-path!"
-					| "get-path!"
-					| "native!"
-					| "action!"
-					| "op!"
-					| "issue!"
-					| "paren!"
-					| "function!"
-					| "routine!"
-				]
-				| "none" 			(value: none)
-			] pos: any ws #"]"
-		]
-
-		comment-rule: [(type: 'comment!) #";" [to lf | to end]]
-
-		wrong-delimiters: [
-			pos: [
-				  #"]" (value: #"[") | #")" (value: #"(")
-				| #"[" (value: #"]") | #"(" (value: #")")
-			] :pos
-		]
-
-		literal-value: [
-			pos: (type: none) s: [
-				 string-rule
-				| block-rule
-				| comment-rule
-				| tuple-rule
-				| hexa-rule
-				| binary-rule (type: 'binary!)
-				| email-rule
-				| integer-rule
-				| float-rule
-				| tag-rule
-				| word-rule
-				| lit-word-rule
-				| get-word-rule
-				| refinement-rule
-				| file-rule
-				| char-rule
-				| map-rule
-				| paren-rule
-				| escaped-rule
-				| issue-rule
-			] e:
-		]
-
-		any-value: [
-			pos: any [some ws | literal-value (
-				if all [type style: select theme type][
-					len: offset? s e
-					append dst as-pair (index? s) len
-					append dst style
-				]
-			)]
-		]
-		red-rules: [any-value opt wrong-delimiters]
-
-		unless either part [
-			parse/case/part src red-rules length
-		][
-			parse/case src red-rules
-		][
-			throw-error ['value pos]
-		]
+		_dst: dst
+		_theme: theme
+		transcode/trace src :lex
 		dst
 	]
-]
-
-;styles: make block! 100
-;highlight/add-styles {--== Red 0.6.1 ==-- ^/} styles
-
-;?? styles
\ No newline at end of file
+]
\ No newline at end of file

From f51d8d7e2e222ef640e4a4d5a99f0c6b359b4d12 Mon Sep 17 00:00:00 2001
From: Nenad Rakocevic 
Date: Wed, 15 Jan 2020 18:36:30 +0100
Subject: [PATCH 0784/3432] FIX: incomplete error management for base-16
 binaries loading.

---
 docs/lexer/lexer-FSM.xlsx      | Bin 22385 -> 22306 bytes
 runtime/lexer.reds             |   6 +++---
 utils/generate-misc-tables.red |   2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx
index f75ffbb561240562d56914485ed2562a0e223366..f020636fefaf9569adf27ddb6fd2f08b34c47802 100644
GIT binary patch
literal 22306
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

literal 22385
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

*qoD|J11+R7AL^}~q(7aRsG(X0rZ`Tf1^>)u`O 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 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a99b83927a..692c8fb999 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -84,7 +84,7 @@ lexer: context [ ] #enum bin16-char-classes! [ - C_BIN_SKIP ;-- 0 + C_BIN_ILLEGAL ;-- 0 C_BIN_BLANK ;-- 1 C_BIN_LINE ;-- 2 C_BIN_HEXA ;-- 3 @@ -128,7 +128,7 @@ lexer: context [ } bin16-FSM: #{ - 0000000102 + 0500000102 0505050405 0202000202 } @@ -595,7 +595,7 @@ lexer: context [ fstate: as-integer bin16-FSM/index any [fstate - S_BIN_FINAL_STATES > 0 s >= e] ] - if fstate = T_BIN_ERROR [return s] + if fstate = T_BIN_ERROR [return s - 1] index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables c: as-integer hexa-table/index index: 1 + as-integer pos/2 diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index 0c8f1d075d..cb4fdbd4c2 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -23,7 +23,7 @@ gen-bitarray: function [list][ ] bin-classes: [ - C_BIN_SKIP ;-- 0 + C_BIN_ILLEGAL ;-- 0 C_BIN_BLANK ;-- 1 C_BIN_LINE ;-- 2 C_BIN_HEXA ;-- 3 From 96ccacfc3eb931c6d0c5b7450c7e917e1e4f4e6d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 15 Jan 2020 19:08:07 +0100 Subject: [PATCH 0785/3432] FEAT: ensures that `type` argument in lexer events is of type word! for `scan` events. --- runtime/lexer.reds | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 692c8fb999..fe96c89b65 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -376,6 +376,7 @@ lexer: context [ res [red-value!] blk [red-block!] int [red-integer!] + name [names!] more [series!] ctx [node!] cont? [logic!] @@ -393,10 +394,15 @@ lexer: context [ either type < 0 [ ;-- type blk: as red-block! #get system/lexer/exit-states either TYPE_OF(blk) <> TYPE_BLOCK [none/push][ - stack/push block/rs-abs-at blk (0 - type) - 1 ;-- 1-based access + stack/push block/rs-abs-at blk (0 - type) - 1 ;-- 1-based access ] ][ - either zero? type [none/push][datatype/push type] + either event = words/_scan [ + name: name-table + type + stack/push as red-value! name/word + ][ + either zero? type [none/push][datatype/push type] + ] ] either all [lex/in-series <> null TYPE_OF(lex/in-series) <> TYPE_BINARY][ x: unicode/count-chars lex/input s @@ -409,7 +415,7 @@ lexer: context [ integer/push lex/line ;-- line number either null? value [pair/push x + 1 y + 1][stack/push value] ;-- token - if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs] ;-- +1 for /local refinement + if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs] ;-- +1 for /local refinement catch RED_THROWN_ERROR [_function/call lex/fun-ptr ctx] if system/thrown <> 0 [re-throw] From 34fd3c0622f08afcca69db6b56e07e7fb85dadcf Mon Sep 17 00:00:00 2001 From: Gregg Irwin Date: Wed, 15 Jan 2020 19:07:07 -0700 Subject: [PATCH 0786/3432] FIX: #4242 --- environment/networking.red | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/environment/networking.red b/environment/networking.red index c83bcb3793..044d08f1fb 100644 --- a/environment/networking.red +++ b/environment/networking.red @@ -59,7 +59,7 @@ url-parser: object [ ;-- URL Grammar url-rules: [scheme-part hier-part opt query opt fragment] ; mark: (print mark) - scheme-part: [copy =scheme [alpha some scheme-char] #":"] + scheme-part: [copy =scheme [alpha any scheme-char] #":"] hier-part: ["//" authority path-abempty | path-absolute | path-rootless | path-empty] ; The authority component is preceded by a double slash ("//") and is @@ -71,7 +71,7 @@ url-parser: object [ user-info: [ ;mark: (print mold mark) copy =user-info [any [unreserved | pct-encoded | sub-delims | #":"] #"@"] - ;(print mold =user-info) + ;(print ["user-info:" mold =user-info]) (take/last =user-info) ] @@ -98,6 +98,7 @@ url-parser: object [ ;!! path-noscheme is only used in relative URIs, which aren't supported here yet. ;path-noscheme: [copy =path [segment-nz-nc any-segments]] ; (print ["path-no-scheme:" mold =path]) path-rootless: [copy =path [segment-nz any-segments]] ; (print ["path-rootless:" mold =path]) + path-empty: [none] any-segments: [any [#"/" segment]] From df9f2780b4e4244b4923d097d088be13528a6e18 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 16 Jan 2020 17:18:29 +0100 Subject: [PATCH 0787/3432] FIX: uncaught lexer exception. --- runtime/lexer.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fe96c89b65..9122e32240 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1817,8 +1817,10 @@ lexer: context [ if zero? depth [root-state: lex] depth: depth + 1 clean-up: [ + system/thrown: 0 depth: depth - 1 if zero? depth [root-state: null] + len/value: as-integer lex/in-pos - lex/input ] lex/next: null ;-- last element of the states linked list @@ -1855,7 +1857,6 @@ lexer: context [ ][ store-any-block dst lex/buffer slots TYPE_BLOCK ] - len/value: as-integer lex/in-pos - lex/input clean-up ] From b426f7b31c0f5d083352e8dfcaf9adc3d65c771e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 17 Jan 2020 20:55:04 +0100 Subject: [PATCH 0788/3432] FEAT: simplifies lexer's open-block/close-block API. --- runtime/lexer.reds | 47 +++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9122e32240..6771ff582d 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -491,7 +491,7 @@ lexer: context [ ] ] - open-block: func [lex [state!] type [integer!] hint [integer!] pos [byte-ptr!] + open-block: func [lex [state!] type [integer!] pos [byte-ptr!] /local p [red-point!] len [integer!] @@ -502,51 +502,56 @@ lexer: context [ p: as red-point! alloc-slot lex set-type as cell! p TYPE_POINT ;-- use the slot for stack info p/x: len - p/y: type << 16 or (hint and FFFFh) + p/y: type p/z: as-integer pos - lex/input ;-- opening delimiter offset saved (error handling) - lex/head: lex/tail ;-- points just after p lex/entry: S_START ] - close-block: func [lex [state!] s e [byte-ptr!] type [integer!] final [integer!] + close-block: func [lex [state!] s e [byte-ptr!] type [integer!] return: [integer!] /local p [red-point!] - len hint stype [integer!] + len stype t [integer!] do-error [subroutine!] + point? [logic!] ][ do-error: [ lex/closing: type throw-error lex s e ERR_MISSING ] p: as red-point! lex/head - 1 + point?: all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] if lex/fun-ptr <> null [ - if all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][type: p/y >> 16] - unless fire-event lex words/_close type null s e [return 0] + t: either point? [p/y][type] + unless fire-event lex words/_close t null s e [return 0] + ] + unless point? [do-error] ;-- postpone error checking after callback call + stype: p/y + either type = -1 [type: stype][ ;-- no closing type provided, use saved one + if all [ + type <> TYPE_SET_PATH ;-- let set-path override saved type + not all [stype = TYPE_MAP type = TYPE_PAREN];-- paren can close a map + stype <> type ;-- saved type <> closing type => error + ][do-error] ] - stype: p/y >> 16 - unless all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT][do-error] - either type = -1 [type: either final = -1 [stype][final]][if stype <> type [do-error]] len: (as-integer lex/tail - lex/head) >> 4 lex/tail: lex/head lex/head: as cell! p - p/x - hint: p/y and FFFFh << 16 >> 16 - store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here p: as red-point! lex/head - 1 ;-- get parent series - stype: p/y >> 16 + type: p/y either all [ lex/buffer <= p - not any [stype = TYPE_BLOCK stype = TYPE_PAREN stype = TYPE_MAP] + not any [type = TYPE_BLOCK type = TYPE_PAREN type = TYPE_MAP] ][ ;-- any-path! case lex/entry: S_PATH ][ lex/entry: S_START ] - hint + stype ] decode-2: func [s e [byte-ptr!] ser [series!] @@ -851,12 +856,12 @@ lexer: context [ scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!]][ type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] - open-block lex type -1 null + open-block lex type null lex/in-pos: e + 1 ;-- skip delimiter ] scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - close-block lex s e TYPE_BLOCK -1 + close-block lex s e TYPE_BLOCK lex/in-pos: e + 1 ;-- skip ] ] @@ -864,7 +869,7 @@ lexer: context [ /local blk [red-block!] ][ - if TYPE_MAP = close-block lex s e TYPE_PAREN -1 [ + if TYPE_MAP = close-block lex s e TYPE_PAREN [ blk: as red-block! lex/tail - 1 map/make-at as cell! blk blk block/rs-length? blk ] @@ -896,7 +901,7 @@ lexer: context [ ] scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - open-block lex TYPE_PAREN TYPE_MAP null + open-block lex TYPE_MAP null lex/in-pos: e + 1 ;-- skip ( ] @@ -911,7 +916,7 @@ lexer: context [ #":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH] default [TYPE_PATH] ] - open-block lex type -1 pos ;-- open a new path series + open-block lex type pos ;-- open a new path series scan-word lex s e flags ;-- load the head word lex/entry: S_PATH ;-- overwrites the S_START set by open-block lex/in-pos: e + 1 ;-- skip / @@ -938,7 +943,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip : TYPE_SET_PATH ][-1] - close-block lex s e -1 type + close-block lex s e type ][ if e + 1 = lex/in-end [throw-error lex null e TYPE_PATH] ;-- incomplete path error if e/1 = #":" [throw-error lex null e TYPE_PATH] ;-- set-words not allowed inside paths From 9a2e0b607ea205da8217b2dde399f89903a2d1f4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 18 Jan 2020 01:00:06 +0100 Subject: [PATCH 0789/3432] FIX: missing change from open/close refactoring in previous commit. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 6771ff582d..536c73d0a9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1852,7 +1852,7 @@ lexer: context [ if slots > 0 [ p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] if TYPE_OF(p) = TYPE_POINT [ - lex/closing: p/y >> 16 + lex/closing: p/y catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] if system/thrown <> 0 [dst/header: TYPE_NONE clean-up exit] ] From e763f5a901f20e5c96770aa3235d935d91db33f8 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 18 Jan 2020 12:35:45 +0100 Subject: [PATCH 0790/3432] FEAT: preliminary cross-platform support for tri-state checkboxes --- modules/view/VID.red | 1 + modules/view/backends/platform.red | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index 9b6e1a0aaf..564992d9f1 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -306,6 +306,7 @@ system/view/VID: context [ | 'loose (add-option opts [drag-on: 'down]) | 'all-over (set-flag opts 'flags 'all-over) | 'password (set-flag opts 'flags 'password) + | 'tri-state (set-flag opts 'flags 'tri-state) | 'hidden (opts/visible?: no) | 'disabled (opts/enabled?: no) | 'select (opts/selected: fetch-argument integer! spec) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index e4ca458b76..10896c5da2 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -75,7 +75,8 @@ system/view/platform: context [ #enum flags-flag! [ FACET_FLAGS_ALL_OVER: 00000001h - + + FACET_FLAGS_TRISTATE: 00020000h FACET_FLAGS_SCROLLABLE: 00040000h FACET_FLAGS_PASSWORD: 00080000h @@ -278,6 +279,7 @@ system/view/platform: context [ no-buttons: symbol/make "no-buttons" modal: symbol/make "modal" popup: symbol/make "popup" + tri-state: symbol/make "tri-state" scrollable: symbol/make "scrollable" password: symbol/make "password" From a7bb0f94187e815129992494268f6fd21f9b4dd7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 18 Jan 2020 19:42:54 +0100 Subject: [PATCH 0791/3432] FIX: transcode/next was failing to load any-block! values. Example: transcode/next "[a] 123" --- runtime/lexer-transitions.reds | 5 ++-- runtime/lexer.reds | 36 ++++++++++++++++---------- utils/generate-lexer-table.red | 47 ++++++++++++++++------------------ 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 4cb76506ed..c6b614a7cd 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -91,9 +91,10 @@ Red/System [ T_EMAIL T_HEX ] - prev-table: #{ + type-table: #{ 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 -330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F +330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 +000000000000140708290A26000C0C272F252B332C092D0B } transitions: #{ 000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 536c73d0a9..45979bf11a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -284,6 +284,7 @@ lexer: context [ line [integer!] ;-- current line number nline [integer!] ;-- new lines count for new token type [integer!] ;-- sub-type in a typeclass + scanned [integer!] ;-- type of first scanned value entry [integer!] ;-- entry state for the FSM prev [integer!] ;-- previous state before forced EOF transition exit [integer!] ;-- exit state for the FSM @@ -540,6 +541,7 @@ lexer: context [ lex/tail: lex/head lex/head: as cell! p - p/x store-any-block as cell! p lex/tail len type ;-- p slot gets overwritten here + lex/scanned: type p: as red-point! lex/head - 1 ;-- get parent series type: p/y @@ -845,8 +847,8 @@ lexer: context [ scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ either lex/prev < --EXIT_STATES-- [ - index: lex/prev + 1 - index: as-integer prev-table/index + index: lex/prev + index: as-integer type-table/index if zero? index [index: ERR_BAD_CHAR] ;-- fallback when no specific type detected throw-error lex s e index ][ @@ -1181,6 +1183,7 @@ lexer: context [ while [all [p < e p/1 = #"/"]][p: p + 1] if p < e [throw-error lex s e TYPE_REFINEMENT] ] + lex/scanned: type if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s-pos e-pos [exit]] cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell @@ -1287,6 +1290,7 @@ lexer: context [ ] ] ] + lex/scanned: type if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s e [exit]] s: s + 1 cell: alloc-slot lex @@ -1359,6 +1363,7 @@ lexer: context [ if flags and C_FLAG_NOSTORE = 0 [ integer/make-at alloc-slot lex i ] + lex/scanned: TYPE_INTEGER lex/in-pos: e ;-- reset the input position to delimiter byte i ] @@ -1373,6 +1378,7 @@ lexer: context [ set-type as cell! fl TYPE_FLOAT fl/value: dtoa/to-float s e :err if err <> 0 [throw-error lex s e TYPE_FLOAT] + lex/scanned: TYPE_FLOAT lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1776,6 +1782,7 @@ lexer: context [ lex/exit: state lex/prev: prev lex/type: -1 + lex/scanned: as-integer type-table/state load?: yes index: state - --EXIT_STATES-- @@ -1794,23 +1801,23 @@ lexer: context [ scan-path-item lex s lex/in-pos flags ;-- lex/in-pos could have changed ] ] - if all [one? state <> T_BLK_OP state <> T_PAR_OP state <> T_MSTR_OP][exit] + if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH lex/tail - 1 = lex/buffer][exit] lex/in-pos >= lex/in-end ] - if lex/entry = S_M_STRING [catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING]] assert lex/in-pos = lex/in-end ] scan: func [ - dst [red-value!] ;-- destination slot - src [byte-ptr!] ;-- UTF-8 buffer - size [integer!] ;-- buffer size in bytes - one? [logic!] ;-- scan a single value - wrap? [logic!] ;-- force returned loaded value(s) in a block - len [int-ptr!] ;-- return the consumed input length - fun [red-function!] ;-- optional callback function - ser [red-series!] ;-- optional input series back-reference + dst [red-value!] ;-- destination slot + src [byte-ptr!] ;-- UTF-8 buffer + size [integer!] ;-- buffer size in bytes + one? [logic!] ;-- scan a single value + wrap? [logic!] ;-- force returned loaded value(s) in a block + len [int-ptr!] ;-- return the consumed input length + fun [red-function!] ;-- optional callback function + ser [red-series!] ;-- optional input series back-reference + return: [integer!] ;-- scanned type when one? is set, else zero /local blk [red-block!] p [red-point!] @@ -1838,6 +1845,7 @@ lexer: context [ lex/in-pos: src lex/entry: S_START lex/type: -1 + lex/scanned: 0 lex/mstr-nest: 0 lex/mstr-flags: 0 lex/fun-ptr: fun @@ -1854,7 +1862,7 @@ lexer: context [ if TYPE_OF(p) = TYPE_POINT [ lex/closing: p/y catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] - if system/thrown <> 0 [dst/header: TYPE_NONE clean-up exit] + if system/thrown <> 0 [dst/header: TYPE_NONE clean-up return lex/scanned] ] ] either all [one? not wrap? slots > 0][ @@ -1863,6 +1871,7 @@ lexer: context [ store-any-block dst lex/buffer slots TYPE_BLOCK ] clean-up + lex/scanned ] load-string: func [ @@ -1914,6 +1923,7 @@ lexer: context [ transitions: transitions + 1 skip-table: skip-table + 1 line-table: line-table + 1 + type-table: type-table + 1 set-jump-table [ :scan-eof ;-- T_EOF diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index eb1d58eb16..570bf1007f 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -76,31 +76,31 @@ context [ T_PAR_OP - ;-- 60 T_PAR_CL - ;-- 61 T_MSTR_OP - ;-- 62 - T_MSTR_CL - ;-- 63 + T_MSTR_CL TYPE_STRING ;-- 63 T_MAP_OP - ;-- 64 T_PATH - ;-- 65 T_CONS_MK - ;-- 66 T_CMT - ;-- 67 T_WORD - ;-- 68 T_REFINE - ;-- 69 - T_ISSUE - ;-- 70 - T_STRING - ;-- 71 - T_FILE - ;-- 72 - T_BINARY - ;-- 73 - T_CHAR - ;-- 74 - T_PERCENT - ;-- 75 + T_ISSUE TYPE_ISSUE ;-- 70 + T_STRING TYPE_STRING ;-- 71 + T_FILE TYPE_FILE ;-- 72 + T_BINARY TYPE_BINARY ;-- 73 + T_CHAR TYPE_CHAR ;-- 74 + T_PERCENT TYPE_PERCENT ;-- 75 T_INTEGER - ;-- 76 - T_FLOAT - ;-- 77 - T_FLOAT_SP - ;-- 78 - T_TUPLE - ;-- 79 - T_DATE - ;-- 80 - T_PAIR - ;-- 81 - T_TIME - ;-- 82 - T_MONEY - ;-- 83 - T_TAG - ;-- 84 - T_URL - ;-- 85 - T_EMAIL - ;-- 86 - T_HEX - ;-- 87 + T_FLOAT TYPE_FLOAT ;-- 77 + T_FLOAT_SP TYPE_FLOAT ;-- 78 + T_TUPLE TYPE_TUPLE ;-- 79 + T_DATE TYPE_DATE ;-- 80 + T_PAIR TYPE_PAIR ;-- 81 + T_TIME TYPE_TIME ;-- 82 + T_MONEY TYPE_MONEY ;-- 83 + T_TAG TYPE_TAG ;-- 84 + T_URL TYPE_URL ;-- 85 + T_EMAIL TYPE_EMAIL ;-- 86 + T_HEX TYPE_INTEGER ;-- 87 ] CSV-table: %../docs/lexer/lexer-FSM.csv @@ -130,15 +130,12 @@ context [ append/only table out ] - ;-- Generate the prev-table content - prev-table: make binary! 2000 + ;-- Generate the type-table content + type-table: make binary! 2000 types: load %../runtime/macros.reds types: select types 'datatypes! - foreach [s t] states [ - if s = '--EXIT_STATES-- [break] - append prev-table (index? find types t) - 1 - ] + foreach [s t] states [append type-table either t = '- [0][(index? find types t) - 1]] template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" @@ -148,7 +145,7 @@ context [ (extract states 2) ] - prev-table: (prev-table) + type-table: (type-table) transitions: (table) ] From 5e31cee5ed96adeb530f616e1bf2a01f897a5b9b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 18 Jan 2020 20:07:38 +0100 Subject: [PATCH 0792/3432] FEAT: [Windows] support tri-state CHECK face --- modules/view/backends/windows/gui.reds | 5 ++++- modules/view/backends/windows/win32.reds | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index b151af17aa..6304705ddf 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -984,6 +984,7 @@ get-flags: func [ sym = no-buttons [flags: flags or FACET_FLAGS_NO_BTNS] sym = modal [flags: flags or FACET_FLAGS_MODAL] sym = popup [flags: flags or FACET_FLAGS_POPUP] + sym = tri-state [flags: flags or FACET_FLAGS_TRISTATE] sym = scrollable [flags: flags or FACET_FLAGS_SCROLLABLE] sym = password [flags: flags or FACET_FLAGS_PASSWORD] true [fire [TO_ERROR(script invalid-arg) word]] @@ -1304,6 +1305,7 @@ OS-make-view: func [ ws-flags [integer!] bits [integer!] sym [integer!] + state [integer!] class [c-string!] caption [c-string!] value [integer!] @@ -1366,7 +1368,8 @@ OS-make-view: func [ ] sym = check [ class: #u16 "RedButton" - flags: flags or WS_TABSTOP or BS_AUTOCHECKBOX + state: either bits and FACET_FLAGS_TRISTATE <> 0 [BS_AUTO3STATE][BS_AUTOCHECKBOX] + flags: flags or WS_TABSTOP or state ] sym = radio [ class: #u16 "RedButton" diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 76557e1a9b..3e82c4c2b9 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -236,6 +236,7 @@ Red/System [ #define BS_CHECKBOX 00000002h #define BS_AUTOCHECKBOX 00000003h #define BS_RADIOBUTTON 00000004h +#define BS_AUTO3STATE 00000006h #define BS_GROUPBOX 00000007h #define BS_AUTORADIOBUTTON 00000009h From 5e4479ea81027480b88e6355c0a90f2c2a9c297b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 18 Jan 2020 20:17:47 +0100 Subject: [PATCH 0793/3432] FEAT: [macOS] support tri-state CHECK face --- modules/view/backends/macOS/cocoa.reds | 4 ++++ modules/view/backends/macOS/gui.reds | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/modules/view/backends/macOS/cocoa.reds b/modules/view/backends/macOS/cocoa.reds index 3ca82f4094..7f272c39ed 100644 --- a/modules/view/backends/macOS/cocoa.reds +++ b/modules/view/backends/macOS/cocoa.reds @@ -67,6 +67,10 @@ Red/System [ #define NSAtBottom 5 #define NSBelowBottom 6 +#define NSMixedState -1 +#define NSOffState 0 +#define NSOnState 1 + #define NSLeftMouseDown 1 #define NSLeftMouseUp 2 #define NSRightMouseDown 3 diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index ee94c4c897..0d646bddb5 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -420,6 +420,7 @@ get-flags: func [ sym = no-buttons [flags: flags or FACET_FLAGS_NO_BTNS] sym = modal [flags: flags or FACET_FLAGS_MODAL] sym = popup [flags: flags or FACET_FLAGS_POPUP] + sym = tri-state [flags: flags or FACET_FLAGS_TRISTATE] sym = scrollable [flags: flags or FACET_FLAGS_SCROLLABLE] sym = password [flags: flags or FACET_FLAGS_PASSWORD] true [fire [TO_ERROR(script invalid-arg) word]] @@ -1977,6 +1978,9 @@ OS-make-view: func [ ] any [sym = button sym = check sym = radio][ if sym <> button [ + if all [sym = check bits and FACET_FLAGS_TRISTATE <> 0][ + objc_msgSend [obj sel_getUid "setAllowsMixedState:" yes] + ] objc_msgSend [obj sel_getUid "setButtonType:" flags] set-logic-state obj as red-logic! data no ] From 76cd5e395de818a0d08ce5ba30349720fb8405df Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 18 Jan 2020 20:44:18 +0100 Subject: [PATCH 0794/3432] FIX: missing LOAD lexer events for some types. --- libRed/libRed.red | 2 +- runtime/datatypes/block.reds | 2 +- runtime/datatypes/common.reds | 2 +- runtime/lexer.reds | 24 ++++++++++++++---------- runtime/natives.reds | 6 +++--- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index 87cca7932b..1881715da7 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -251,7 +251,7 @@ Red [ if last-error <> null [return last-error] TRAP_ERRORS(name [ - lexer/load-string stack/arguments str -1 no no null null null + lexer/load-string stack/arguments str -1 no yes no null null null stack/unwind-last ]) ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 294ee83c46..71f3940875 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -649,7 +649,7 @@ block: context [ TYPE_OBJECT [object/reflect as red-object! spec words/body] TYPE_MAP [map/reflect as red-hash! spec words/body] TYPE_VECTOR [vector/to-block as red-vector! spec proto] - TYPE_STRING [lexer/load-string as red-value! proto as red-string! spec -1 no no null null as red-series! spec] + TYPE_STRING [lexer/load-string as red-value! proto as red-string! spec -1 no yes no null null as red-series! spec] TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] TYPE_ANY_PATH TYPE_ANY_LIST [proto: clone as red-block! spec no no] diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 522cb91592..38278b4b81 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -351,7 +351,7 @@ load-value: func [ blk [red-block!] value [red-value!] ][ - lexer/load-string stack/arguments str -1 yes yes null null as red-series! str + lexer/load-string stack/arguments str -1 yes yes yes null null as red-series! str blk: as red-block! stack/arguments assert TYPE_OF(blk) = TYPE_BLOCK diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 45979bf11a..c85d2e7a1f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1184,12 +1184,13 @@ lexer: context [ if p < e [throw-error lex s e TYPE_REFINEMENT] ] lex/scanned: type - if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s-pos e-pos [exit]] + if all [lex/fun-ptr <> null not fire-event lex words/_scan type null s-pos e-pos][exit] cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter + if all [lex/fun-ptr <> null not fire-event lex words/_load type cell s-pos e-pos][lex/tail: cell] ] scan-file: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -1291,12 +1292,13 @@ lexer: context [ ] ] lex/scanned: type - if lex/fun-ptr <> null [unless fire-event lex words/_scan type null s e [exit]] + if all [lex/fun-ptr <> null not fire-event lex words/_scan type null s e][exit] s: s + 1 cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type lex/in-pos: e ;-- reset the input position to delimiter byte + if all [lex/fun-ptr <> null not fire-event lex words/_load type cell s - 1 e][lex/tail: cell] ] scan-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -1732,8 +1734,9 @@ lexer: context [ ] scan-tokens: func [ - lex [state!] - one? [logic!] + lex [state!] + one? [logic!] + ld? [logic!] /local cp class index state prev flags line mark offset [integer!] p e start s [byte-ptr!] @@ -1783,11 +1786,10 @@ lexer: context [ lex/prev: prev lex/type: -1 lex/scanned: as-integer type-table/state - load?: yes - + index: state - --EXIT_STATES-- - if lex/fun-ptr <> null [ - if state >= T_STRING [load?: fire-event lex words/_scan 0 - index null s lex/in-pos] + load?: either lex/fun-ptr = null [any [not one? ld?]][ + either state >= T_STRING [fire-event lex words/_scan 0 - index null s lex/in-pos][yes] ] if load? [ do-scan: as scanner! scanners/index @@ -1813,6 +1815,7 @@ lexer: context [ src [byte-ptr!] ;-- UTF-8 buffer size [integer!] ;-- buffer size in bytes one? [logic!] ;-- scan a single value + load? [logic!] ;-- disable value loading, only scanning (one? implied) wrap? [logic!] ;-- force returned loaded value(s) in a block len [int-ptr!] ;-- return the consumed input length fun [red-function!] ;-- optional callback function @@ -1854,7 +1857,7 @@ lexer: context [ if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no] - scan-tokens lex one? + scan-tokens lex one? load? slots: (as-integer lex/tail - lex/buffer) >> 4 if slots > 0 [ @@ -1879,6 +1882,7 @@ lexer: context [ str [red-string!] size [integer!] one? [logic!] + load? [logic!] wrap? [logic!] len [int-ptr!] fun [red-function!] ;-- optional callback function @@ -1899,7 +1903,7 @@ lexer: context [ ] size: unicode/to-utf8-buffer str utf8-buffer size if null? len [len: :ignore] - scan dst utf8-buffer size one? wrap? len fun as red-series! str + scan dst utf8-buffer size one? load? wrap? len fun as red-series! str ] set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][ diff --git a/runtime/natives.reds b/runtime/natives.reds index 86b9257e99..395f2d9558 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -555,7 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - lexer/load-string arg as red-string! arg -1 no no null null as red-string! arg + lexer/load-string arg as red-string! arg -1 no yes no null null as red-string! arg DO_EVAL_BLOCK ] TYPE_URL @@ -2780,11 +2780,11 @@ natives: context [ ] either type = TYPE_BINARY [ if len < 0 [len: binary/rs-length? bin] - lexer/scan slot binary/rs-head bin len next? no :offset fun as red-series! bin + lexer/scan slot binary/rs-head bin len next? yes no :offset fun as red-series! bin ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - lexer/load-string slot str len next? no :offset fun as red-series! str + lexer/load-string slot str len next? yes no :offset fun as red-series! str ] if next? [ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 From 3fbbbf8368a5c6c2b2418fe479c2bb9ac0b8f063 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 18 Jan 2020 21:22:27 +0100 Subject: [PATCH 0795/3432] FIX: accounts for float promotion in scan-integer for more accurate lexer event info. --- runtime/lexer-transitions.reds | 82 +++++++++++++++++----------------- runtime/lexer.reds | 32 +++++++------ utils/generate-lexer-table.red | 18 ++++---- 3 files changed, 68 insertions(+), 64 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index c6b614a7cd..de9d45ef54 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -70,6 +70,7 @@ Red/System [ T_PATH T_CONS_MK T_CMT + T_INTEGER T_WORD T_REFINE T_ISSUE @@ -78,7 +79,6 @@ Red/System [ T_BINARY T_CHAR T_PERCENT - T_INTEGER T_FLOAT T_FLOAT_SP T_TUPLE @@ -94,37 +94,37 @@ Red/System [ type-table: #{ 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 -000000000000140708290A26000C0C272F252B332C092D0B +00000000000000140708290A260C0C272F252B332C092D0B } transitions: #{ 000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E 2929392D2D393801430101010101010101010101010101010101010101010101 -0101010101010101010101013938020202020202020202024702020202020202 +0101010101010101010101013938020202020202020202024802020202020202 0202020202020202020202020202020203020239390202020202020202020202 0202020202020202020202020202020202020202020202020202393804040404 040404043E3F0404040404040404040404040404040404040404040404040504 0439390404040404040404040404040404040404040404040404040404040404 -04040404040404043938444407074444444444440A0707440707070707070707 -0707070707074444070707070707073944484807074848484848483907074807 -0707070707070707070707080748480707070707070739480707090939393939 +04040404040404043938454507074545454545450A0707450707070707070707 +0707070707074545070707070707073945494907074949494949493907074907 +0707070707070707070707080749490707070707070739490707090939393939 3939393939393939390909090939393939393939393939393939393939393907 0707073939393939393939393939393909090707393939393939393939393939 -3939393939480A0A0A0A0A0A0A0A0A0A480A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A393945450B0B454545454545450B0B0B0B0B0B0B0B -0B0B2D0B0B0B0B0B0B45450B0B0B0B0B0B0B394546461212113940390D390F12 -1239121212121212121212393939123946461212121212121239460D0D0D0D39 -3939393949393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D +3939393939490A0A0A0A0A0A0A0A0A0A490A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A393946460B0B464646464646460B0B0B0B0B0B0B0B +0B0B2D0B0B0B0B0B0B46460B0B0B0B0B0B0B394647471212113940390D390F12 +1239121212121212121212393939123947471212121212121239470D0D0D0D39 +393939394A393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D 39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F394A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4B0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F394B0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F 0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111142111111 -1111111111111111111111111111111111111111111111111111111139394646 -1212464646464646461212121212121212121212121212121212464612121212 -12121239464C4C13134C4C4C4C4C4C4C0C131A1C19571516392119394C39394B -144C3014393919393939394C4D4D15154D4D4D4D4D4D4D1715391C3939151539 -394D394D39394B394D3939393939393939394D4D4D15154D4D4D4D4D4D4D3939 -4D393939151539394D394D39394B39393018391515393939394D4D4D16164D4D -4D4D4D4D4D39394D393957152139214D394D39394B3939301839151539393939 +1111111111111111111111111111111111111111111111111111111139394747 +1212474747474747471212121212121212121212121212121212474712121212 +121212394744441313444444444444440C131A1C19571516392119394439394C +1444301439391939393939444D4D15154D4D4D4D4D4D4D1715391C3939151539 +394D394D39394C394D3939393939393939394D4D4D15154D4D4D4D4D4D4D3939 +4D393939151539394D394D39394C39393018391515393939394D4D4D16164D4D +4D4D4D4D4D39394D393957152139214D394D39394C3939301839151539393939 4D4D4D4D4E4E4E4E4E4E4E4E174E4E171717171717174E4E4E17174E4E4E4E17 4E17174E1717394E4F4F18184F4F4F4F4F4F4F39394F393939393939394F394F 39393939393918393939393939394F5050191950505050505050191919191919 @@ -137,32 +137,32 @@ Red/System [ 3939393939393939393939393939393939393939393939393953531F1F535353 53535353531F5339393939393939533953393939395339203939393939393938 5353202053535353535353532053393939393939395339533939393953393939 -393939393939384444212144444444444444392D2E2D2D222D212D2141442D2D -2D393944302D1F2D2D2D2D2D394457572D2D57575757575757392D2E2D2D2D2D -2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574444242444444444444444 -2424442424242424242424242D2D2D2424444424242424242424394424242424 +393939393939384545212145454545454545392D2E2D2D222D212D2141452D2D +2D393945302D1F2D2D2D2D2D394557572D2D57575757575757392D2E2D2D2D2D +2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574545242445454545454545 +2424452424242424242424242D2D2D2424454524242424242424394524242424 2424242424242524242724242424242424242424542424242424242424242424 2439392525252525252525252524252525252525252525252525252525252525 2525252525262525393925252525252525252525252525252525252525252525 2525252525252525252525252525253939272727272727272727272727272427 2727272727272727272727272727272727272727272739392727272727272727 -2727272727272727272727272727272727272727272727272727272727393944 -4413134444444444444439392D2D2D2D2D2D2D2D2D44392D2D392D442D2A2D2D -2D392D2D394444442B2B44444444444444392D2E2D2D2D2B2B2D2D41442D2D2D -393944302D392B2B2D2D2D39444D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B -39394D394D39394B39393939392B2B393939394D393939393939393939393939 -39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393944442D2D44 -444444444444392D2E2D2D2D2D2D2D2D41442D2D2D393944302D1F2D2D2D2D2D -394444442F2F444444444444442F2F2F2F2F2F2F2F2F2F2F44392F2F2F2F442F -2F2F2F2F2F2F2F394455552F2F555555555555552F392F2F2F2F2F2F2F2F2F55 +2727272727272727272727272727272727272727272727272727272727393945 +4513134545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D +2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D +393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B +39394D394D39394C39393939392B2B393939394D393939393939393939393939 +39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45 +454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D1F2D2D2D2D2D +394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F +2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55 55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030 30303030305656563939303956393039303039303039563939323239393C3D39 -3902353333343434343434343939233434393939303439363639343439394C4C -32324C4C4C4C4C4C4C39134C1C3939151539394C394C39394B144C3014393939 -393939394C393939393939393939393939393934343434343434393934343439 -3939393439343439343439394444343444444444444444393444343434343434 -34444434343439394430343934343434343944464612121139393939390F1212 -3912121212121212121239393912394646121212121212123946444432324444 -444444444439392D2D2D2D2D2D2D2D2D44392D2D392D442D2D2D2D2D392D2D39 -44 +3902353333343434343434343939233434393939303439363639343439394444 +3232444444444444443913441C39391515393944394439394C14443014393939 +3939393944393939393939393939393939393934343434343434393934343439 +3939393439343439343439394545343445454545454545393445343434343434 +34454534343439394530343934343434343945474712121139393939390F1212 +3912121212121212121239393912394747121212121212123947454532324545 +454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39 +45 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c85d2e7a1f..3f57545821 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1310,17 +1310,25 @@ lexer: context [ fl: as red-float! lex/tail - 1 set-type as cell! fl TYPE_PERCENT fl/value: fl/value / 100.0 - lex/in-pos: e + 1 ;-- skip ending delimiter ] scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] return: [integer!] /local - p [byte-ptr!] - len i [integer!] - o? [logic!] + o? root? evt? [logic!] + p [byte-ptr!] + len i [integer!] + promote [subroutine!] ][ + root?: flags and C_FLAG_NOSTORE = 0 ;-- scan-integer is not called by another scanner function + evt?: all [root? lex/fun-ptr <> null] + promote: [ + if all [evt? not fire-event lex words/_scan TYPE_FLOAT null s e][return 0] + scan-float lex s e flags ;-- overflow, fall back on float + if all [evt? not fire-event lex words/_load TYPE_FLOAT lex/tail - 1 s e][lex/tail: lex/tail - 1] + return 0 + ] p: s if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present @@ -1328,10 +1336,7 @@ lexer: context [ i: as-integer (p/1 - #"0") ][ len: as-integer e - p - if len > 10 [ - scan-float lex s e flags ;-- overflow, fall back on float - return 0 - ] + if len > 10 [promote] i: 0 o?: no either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path @@ -1356,17 +1361,16 @@ lexer: context [ i: 80000000h s: s + 1 ;-- ensure that the 0 subtraction does not occur ][ - scan-float lex s e flags ;-- overflow, fall back on float - return 0 + promote ] ] ] + if all [evt? not fire-event lex words/_scan TYPE_INTEGER null s e][return 0] if s/value = #"-" [i: 0 - i] - if flags and C_FLAG_NOSTORE = 0 [ - integer/make-at alloc-slot lex i - ] + if root? [integer/make-at alloc-slot lex i] lex/scanned: TYPE_INTEGER lex/in-pos: e ;-- reset the input position to delimiter byte + if all [evt? not fire-event lex words/_load TYPE_INTEGER lex/tail - 1 s e][lex/tail: lex/tail - 1] i ] @@ -1942,6 +1946,7 @@ lexer: context [ :scan-path-open ;-- T_PATH :scan-construct ;-- T_CONS_MK :scan-comment ;-- T_CMT + :scan-integer ;-- T_INTEGER :scan-word ;-- T_WORD :scan-ref-issue ;-- T_REFINE :scan-ref-issue ;-- T_ISSUE @@ -1950,7 +1955,6 @@ lexer: context [ :scan-binary ;-- T_BINARY :scan-char ;-- T_CHAR :scan-percent ;-- T_PERCENT - :scan-integer ;-- T_INTEGER :scan-float ;-- T_FLOAT :scan-float-special ;-- T_FLOAT_SP :scan-tuple ;-- T_TUPLE diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 570bf1007f..7d113c08d0 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -81,15 +81,15 @@ context [ T_PATH - ;-- 65 T_CONS_MK - ;-- 66 T_CMT - ;-- 67 - T_WORD - ;-- 68 - T_REFINE - ;-- 69 - T_ISSUE TYPE_ISSUE ;-- 70 - T_STRING TYPE_STRING ;-- 71 - T_FILE TYPE_FILE ;-- 72 - T_BINARY TYPE_BINARY ;-- 73 - T_CHAR TYPE_CHAR ;-- 74 - T_PERCENT TYPE_PERCENT ;-- 75 - T_INTEGER - ;-- 76 + T_INTEGER - ;-- 68 + T_WORD - ;-- 69 + T_REFINE - ;-- 70 + T_ISSUE TYPE_ISSUE ;-- 71 + T_STRING TYPE_STRING ;-- 72 + T_FILE TYPE_FILE ;-- 73 + T_BINARY TYPE_BINARY ;-- 74 + T_CHAR TYPE_CHAR ;-- 75 + T_PERCENT TYPE_PERCENT ;-- 76 T_FLOAT TYPE_FLOAT ;-- 77 T_FLOAT_SP TYPE_FLOAT ;-- 78 T_TUPLE TYPE_TUPLE ;-- 79 From e1336ff9b404c490486f2b0c32f5c9afb01a1fb6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 19 Jan 2020 11:47:04 +0100 Subject: [PATCH 0796/3432] FIX: [Windows] fix for #4246 --- modules/view/backends/windows/events.reds | 36 ++++++++++++++++++----- modules/view/backends/windows/win32.reds | 4 +++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 855815c419..f2d1ed8ae0 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -621,6 +621,7 @@ process-command-event: func [ int [red-integer!] idx [integer!] res [integer!] + sym [integer!] saved [handle!] child [handle!] evt [integer!] @@ -638,18 +639,36 @@ process-command-event: func [ switch WIN32_HIWORD(wParam) [ BN_CLICKED [ type: as red-word! get-facet current-msg FACE_OBJ_TYPE - current-msg/hWnd: child ;-- force child handle - evt: either type/symbol <> check [EVT_CLICK][ - get-logic-state current-msg - EVT_CHANGE + sym: symbol/resolve type/symbol + current-msg/hWnd: child ;-- force child handle + + evt: case [ + sym = button [EVT_CLICK] + sym = check [ + get-logic-state current-msg + EVT_CHANGE + ] + all [ + sym = radio ;-- ignore double-click (fixes #4246) + BST_CHECKED <> (BST_CHECKED and as integer! SendMessage child BM_GETSTATE 0 0) + ][ + get-logic-state current-msg + EVT_CLICK ;-- gets converted to CHANGE by high-level event handler + ] + true [0] ] - make-event current-msg 0 evt ;-- should be *after* get-facet call (Windows closing on click case) + + unless zero? evt [make-event current-msg 0 evt] ;-- should be *after* get-facet call (Windows closing on click case) ] BN_UNPUSHED [ type: as red-word! get-facet current-msg FACE_OBJ_TYPE if type/symbol = radio [ current-msg/hWnd: child ;-- force child handle - make-event current-msg 0 EVT_CHANGE + + ;-- ignore double-click (fixes #4246) + unless BST_UNCHECKED <> as integer! SendMessage child BM_GETSTATE 0 0 [ + make-event current-msg 0 EVT_CHANGE + ] ] ] EN_CHANGE [ ;-- sent also by CreateWindow @@ -719,7 +738,10 @@ process-command-event: func [ CBN_EDITCHANGE [ current-msg/hWnd: child ;-- force Combobox handle type: as red-word! get-facet current-msg FACE_OBJ_TYPE - unless type/symbol = text-list [ + unless any[ + type/symbol = text-list + type/symbol = radio ;-- ignore radio button (fixes #4246) + ][ make-event current-msg -1 EVT_CHANGE ] ] diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 76557e1a9b..5a10c52a8b 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -342,6 +342,8 @@ Red/System [ #define BM_GETCHECK F0h #define BM_SETCHECK F1h +#define BM_GETSTATE F2h +#define BM_SETSTATE F3h #define BM_SETSTYLE F4h #define BM_SETIMAGE F7h @@ -351,6 +353,8 @@ Red/System [ #define BST_UNCHECKED 0 #define BST_CHECKED 1 #define BST_INDETERMINATE 2 +#define BST_PUSHED 4 +#define BST_FOCUS 8 #define VK_SHIFT 10h #define VK_CONTROL 11h From 66778d7daad6b2874f9f3bad64471be1a0acc61e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 19 Jan 2020 11:59:47 +0100 Subject: [PATCH 0797/3432] FIX: [Windows] issue #4244 --- modules/view/backends/windows/gui.reds | 50 ++++++++++++++++---------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 6304705ddf..6744389a47 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -937,15 +937,27 @@ set-logic-state: func [ state [red-logic!] check? [logic!] /local - value [integer!] -][ - value: either TYPE_OF(state) <> TYPE_LOGIC [ - state/header: TYPE_LOGIC - state/value: check? - either check? [BST_INDETERMINATE][false] - ][ - as-integer state/value ;-- returns 0/1, matches the messages + values [red-block!] + flags [integer!] + type [integer!] + value [integer!] + tri? [logic!] +][ + if check? [ + values: as red-block! object/get-values get-face-obj hWnd + flags: get-flags as red-block! values + FACE_OBJ_FLAGS + tri?: flags and FACET_FLAGS_TRISTATE <> 0 ] + + type: TYPE_OF(state) + value: either all [check? tri? type = TYPE_NONE][BST_INDETERMINATE][ + as integer! switch type [ + TYPE_NONE [false] + TYPE_LOGIC [state/value] ;-- returns 0/1, matches the state flag + default [true] + ] + ] + SendMessage hWnd BM_SETCHECK value 0 ] @@ -995,26 +1007,28 @@ get-flags: func [ ] get-logic-state: func [ - msg [tagMSG] - return: [logic!] ;-- TRUE if state has changed + msg [tagMSG] + return: [logic!] ;-- TRUE if state has changed /local bool [red-logic!] state [integer!] - otype [integer!] - obool [logic!] + type [integer!] + value [logic!] ][ bool: as red-logic! get-facet msg FACE_OBJ_DATA state: as-integer SendMessage msg/hWnd BM_GETCHECK 0 0 + + type: TYPE_OF(bool) + value: bool/value either state = BST_INDETERMINATE [ - otype: TYPE_OF(bool) - bool/header: TYPE_NONE ;-- NONE indicates undeterminate - bool/header <> otype + bool/header: TYPE_NONE ][ - obool: bool/value + bool/header: TYPE_LOGIC bool/value: state = BST_CHECKED - bool/value <> obool ] + + any [type <> TYPE_OF(bool) value <> bool/value] ] get-selected: func [ @@ -1607,7 +1621,7 @@ OS-make-view: func [ value: get-position-value as red-float! data 100 SendMessage handle PBM_SETPOS value 0 ] - sym = check [set-logic-state handle as red-logic! data no] + sym = check [set-logic-state handle as red-logic! data yes] sym = radio [set-logic-state handle as red-logic! data no] any [ sym = drop-down From 153a575da1987fedf13e999e6abbad02d01a522a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 19 Jan 2020 14:37:26 +0100 Subject: [PATCH 0798/3432] FIX: [macOS] issue #4244 --- modules/view/backends/macOS/delegates.reds | 34 +++++-------- modules/view/backends/macOS/gui.reds | 59 +++++++++++++++++----- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds index 0aa7d7407c..3a94d698e5 100644 --- a/modules/view/backends/macOS/delegates.reds +++ b/modules/view/backends/macOS/delegates.reds @@ -401,36 +401,26 @@ on-flags-changed: func [ ] button-click: func [ - self [integer!] + [cdecl] + self [integer!] /local w [red-word!] values [red-value!] - bool [red-logic!] type [integer!] - state [integer!] - change? [logic!] -][ - make-event self 0 EVT_CLICK + event [integer!] +][ values: get-face-values self w: as red-word! values + FACE_OBJ_TYPE type: symbol/resolve w/symbol - if any [ - type = check - type = radio - ][ - bool: as red-logic! values + FACE_OBJ_DATA - state: objc_msgSend [self sel_getUid "state"] - change?: either state = -1 [ - type: TYPE_OF(bool) - bool/header: TYPE_NONE ;-- NONE indicates undeterminate - bool/header <> type - ][ - change?: bool/value ;-- save the old value - bool/value: as logic! state - bool/value <> change? - ] - if change? [make-event self 0 EVT_CHANGE] + + event: case [ + type = button [EVT_CLICK] + type = radio [get-logic-state self EVT_CLICK] ;-- gets converted to CHANGE by high-level event handler + type = check [get-logic-state self EVT_CHANGE] + true [0] ] + + unless zero? event [make-event self 0 event] ] empty-func: func [ diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index 0d646bddb5..cee494c83d 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -369,20 +369,57 @@ init: func [ ] set-logic-state: func [ - hWnd [integer!] + handle [integer!] state [red-logic!] check? [logic!] /local - value [integer!] + values [red-block!] + flags [integer!] + type [integer!] + value [integer!] + tri? [logic!] +][ + if check? [ + values: as red-block! get-face-values handle + flags: get-flags as red-block! values + FACE_OBJ_FLAGS + tri?: flags and FACET_FLAGS_TRISTATE <> 0 + ] + + type: TYPE_OF(state) + value: either all [check? tri? type = TYPE_NONE][NSMixedState][ + as integer! switch type [ + TYPE_NONE [false] + TYPE_LOGIC [state/value] ;-- returns 0/1, matches the state flag + default [true] + ] + ] + + objc_msgSend [handle sel_getUid "setState:" value] +] + +get-logic-state: func [ + handle [integer!] + return: [logic!] ;-- TRUE: change in state + /local + bool [red-logic!] + state [integer!] + type [integer!] + value [logic!] ][ - value: either TYPE_OF(state) <> TYPE_LOGIC [ - state/header: TYPE_LOGIC - state/value: check? - either check? [-1][0] + bool: as red-logic! (get-face-values handle) + FACE_OBJ_DATA + state: objc_msgSend [handle sel_getUid "state"] + + type: TYPE_OF(bool) + value: bool/value + + either state = NSMixedState [ + bool/header: TYPE_NONE ][ - as-integer state/value ;-- returns 0/1, matches the messages + bool/header: TYPE_LOGIC + bool/value: state = NSOnState ] - objc_msgSend [hWnd sel_getUid "setState:" value] + + any [type <> TYPE_OF(bool) value <> bool/value] ] get-flags: func [ @@ -1982,11 +2019,9 @@ OS-make-view: func [ objc_msgSend [obj sel_getUid "setAllowsMixedState:" yes] ] objc_msgSend [obj sel_getUid "setButtonType:" flags] - set-logic-state obj as red-logic! data no - ] - if TYPE_OF(img) = TYPE_IMAGE [ - change-image obj img sym + set-logic-state obj as red-logic! data sym = check ] + if TYPE_OF(img) = TYPE_IMAGE [change-image obj img sym] if caption <> 0 [objc_msgSend [obj sel_getUid "setTitle:" caption]] ;objc_msgSend [obj sel_getUid "setTarget:" obj] ;objc_msgSend [obj sel_getUid "setAction:" sel_getUid "button-click:"] From 1a3076ff0438d3291b92f0a1538cd46eb1996d85 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 19 Jan 2020 14:41:15 +0100 Subject: [PATCH 0799/3432] FEAT: remove redundant code --- modules/view/backends/macOS/gui.reds | 10 +--------- modules/view/backends/windows/gui.reds | 10 +--------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index cee494c83d..736e81f950 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -398,28 +398,20 @@ set-logic-state: func [ ] get-logic-state: func [ - handle [integer!] - return: [logic!] ;-- TRUE: change in state + handle [integer!] /local bool [red-logic!] state [integer!] - type [integer!] - value [logic!] ][ bool: as red-logic! (get-face-values handle) + FACE_OBJ_DATA state: objc_msgSend [handle sel_getUid "state"] - type: TYPE_OF(bool) - value: bool/value - either state = NSMixedState [ bool/header: TYPE_NONE ][ bool/header: TYPE_LOGIC bool/value: state = NSOnState ] - - any [type <> TYPE_OF(bool) value <> bool/value] ] get-flags: func [ diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 6744389a47..d9591bb30a 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1007,19 +1007,13 @@ get-flags: func [ ] get-logic-state: func [ - msg [tagMSG] - return: [logic!] ;-- TRUE if state has changed + msg [tagMSG] /local bool [red-logic!] state [integer!] - type [integer!] - value [logic!] ][ bool: as red-logic! get-facet msg FACE_OBJ_DATA state: as-integer SendMessage msg/hWnd BM_GETCHECK 0 0 - - type: TYPE_OF(bool) - value: bool/value either state = BST_INDETERMINATE [ bool/header: TYPE_NONE @@ -1027,8 +1021,6 @@ get-logic-state: func [ bool/header: TYPE_LOGIC bool/value: state = BST_CHECKED ] - - any [type <> TYPE_OF(bool) value <> bool/value] ] get-selected: func [ From 63263f5d435d95e39855b0850d5ca35bbdebec32 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 19 Jan 2020 18:13:41 +0100 Subject: [PATCH 0800/3432] FEAT: better support for scanning-only processing in lexer. --- runtime/lexer.reds | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3f57545821..56813869d8 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1792,9 +1792,11 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - load?: either lex/fun-ptr = null [any [not one? ld?]][ - either state >= T_STRING [fire-event lex words/_scan 0 - index null s lex/in-pos][yes] - ] + load?: either state >= T_STRING [ + either lex/fun-ptr = null [any [not one? ld?]][ + fire-event lex words/_scan 0 - index null s lex/in-pos + ] + ][yes] if load? [ do-scan: as scanner! scanners/index catch LEX_ERR [do-scan lex s p flags] @@ -1863,19 +1865,21 @@ lexer: context [ scan-tokens lex one? load? - slots: (as-integer lex/tail - lex/buffer) >> 4 - if slots > 0 [ - p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] - if TYPE_OF(p) = TYPE_POINT [ - lex/closing: p/y - catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] - if system/thrown <> 0 [dst/header: TYPE_NONE clean-up return lex/scanned] + if load? [ + slots: (as-integer lex/tail - lex/buffer) >> 4 + if slots > 0 [ + p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] + if TYPE_OF(p) = TYPE_POINT [ + lex/closing: p/y + catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] + if system/thrown <> 0 [dst/header: TYPE_NONE clean-up return lex/scanned] + ] + ] + either all [one? not wrap? slots > 0][ + copy-cell lex/buffer dst ;-- copy first loaded value only + ][ + store-any-block dst lex/buffer slots TYPE_BLOCK ] - ] - either all [one? not wrap? slots > 0][ - copy-cell lex/buffer dst ;-- copy first loaded value only - ][ - store-any-block dst lex/buffer slots TYPE_BLOCK ] clean-up lex/scanned From 5b794ceebec4f6a16e1f130906653831e922c9b1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 19 Jan 2020 18:14:31 +0100 Subject: [PATCH 0801/3432] FEAT: preliminary support for matching datatypes in Parse on binary inputs. --- runtime/parse.reds | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index 9cbce24b6d..ae84cc5c9e 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -196,6 +196,28 @@ parser: context [ actions/compare value2 value comp-op ] + match-datatype?: func [ + input [red-binary!] + dt [red-datatype!] + dt-type [integer!] + return: [logic!] + /local + len type size [integer!] + s [series!] + buf pos [byte-ptr!] + match? [logic!] + ][ + len: 0 + s: GET_BUFFER(input) + buf: (as byte-ptr! s/offset) + input/head + size: as-integer (as byte-ptr! s/tail) - buf + type: lexer/scan null buf size yes no no :len null null + + match?: either dt-type = TYPE_TYPESET [BS_TEST_BIT_ALT(dt type)][type = dt/value] + if match? [_series/rs-skip as red-series! input len - 1] ;-- -1 to account for later rs-skip + match? + ] + advance: func [ str [red-string!] value [red-value!] ;-- char! or string! value @@ -1251,19 +1273,22 @@ parser: context [ type = TYPE_URL type = TYPE_TAG type = TYPE_EMAIL - type = TYPE_BINARY ][ PARSE_ERROR [TO_ERROR(script parse-unsupported)] ] PARSE_CHECK_INPUT_EMPTY? either end? [match?: false][ dt: as red-datatype! value - value: block/rs-head input - match?: either dt-type = TYPE_TYPESET [ - type: TYPE_OF(value) - BS_TEST_BIT_ALT(dt type) + match?: either type = TYPE_BINARY [ + match-datatype? as red-binary! input dt dt-type ][ - TYPE_OF(value) = dt/value + value: block/rs-head input + type: TYPE_OF(value) + either dt-type = TYPE_TYPESET [ + BS_TEST_BIT_ALT(dt type) + ][ + type = dt/value + ] ] PARSE_TRACE(_match) ] From 9ec8f1795672f941924bd5ec2b6e71778a86c3b6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 18 Jan 2020 12:35:45 +0100 Subject: [PATCH 0802/3432] FEAT: preliminary cross-platform support for tri-state checkboxes --- modules/view/VID.red | 1 + modules/view/backends/platform.red | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index 32a08befa8..d7abb3418b 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -309,6 +309,7 @@ system/view/VID: context [ | 'loose (add-option opts [drag-on: 'down]) | 'all-over (set-flag opts 'flags 'all-over) | 'password (set-flag opts 'flags 'password) + | 'tri-state (set-flag opts 'flags 'tri-state) | 'hidden (opts/visible?: no) | 'disabled (opts/enabled?: no) | 'select (opts/selected: fetch-argument integer! spec) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 676a863baf..8d02159184 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -75,7 +75,8 @@ system/view/platform: context [ #enum flags-flag! [ FACET_FLAGS_ALL_OVER: 00000001h - + + FACET_FLAGS_TRISTATE: 00020000h FACET_FLAGS_SCROLLABLE: 00040000h FACET_FLAGS_PASSWORD: 00080000h @@ -278,6 +279,7 @@ system/view/platform: context [ no-buttons: symbol/make "no-buttons" modal: symbol/make "modal" popup: symbol/make "popup" + tri-state: symbol/make "tri-state" scrollable: symbol/make "scrollable" password: symbol/make "password" From 1c70e665e9df9cb885aed77cb5d1f59ee1988bf2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 20 Jan 2020 19:16:23 +0100 Subject: [PATCH 0803/3432] FIX: avoids lexer crashing after skipping an invalid path error. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 56813869d8..e7e8a451d0 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1805,7 +1805,7 @@ lexer: context [ slot: lex/tail - 1 unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] - if all [lex/entry = S_PATH state <> T_PATH][ + if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ scan-path-item lex s lex/in-pos flags ;-- lex/in-pos could have changed ] ] From 5b1faac0500153f38b754f5038083ece34308fed Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 20 Jan 2020 19:16:59 +0100 Subject: [PATCH 0804/3432] FIX: wrong lex/scanned value on pair! values. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index e7e8a451d0..edb3769701 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1636,6 +1636,7 @@ lexer: context [ scan-integer lex s p flags or C_FLAG_NOSTORE scan-integer lex p + 1 e flags or C_FLAG_NOSTORE + lex/scanned: TYPE_PAIR ;-- overwrite value set by scan-integer lex/in-pos: e ;-- reset the input position to delimiter byte ] From aab4d6c02f2f1d8963bfd86894e773882693db49 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 20 Jan 2020 20:03:05 +0100 Subject: [PATCH 0805/3432] FEAT: splits issue! and refinement! scanning code. Issue! fits the "regular" lexer processing model, so its handler should be standalone. --- runtime/lexer.reds | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index edb3769701..d0e058a9cb 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1270,25 +1270,20 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip " ] - scan-ref-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] + scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] type [integer!] p [byte-ptr!] ][ - type: either s/1 = #"#" [ - if s + 1 = e [throw-error lex s e TYPE_ISSUE] - TYPE_ISSUE - ][ - assert s/1 = #"/" - either s + 1 = e [s: s - 1 TYPE_WORD][ - either s/2 = #"/" [ ;-- //... - scan-word lex s e flags - exit - 0 - ][ - TYPE_REFINEMENT - ] + assert s/1 = #"/" + type: either s + 1 = e [s: s - 1 TYPE_WORD][ + either s/2 = #"/" [ ;-- //... + scan-word lex s e flags + exit + 0 + ][ + TYPE_REFINEMENT ] ] lex/scanned: type @@ -1301,6 +1296,19 @@ lexer: context [ if all [lex/fun-ptr <> null not fire-event lex words/_load type cell s - 1 e][lex/tail: cell] ] + scan-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] + /local + cell [cell!] + ][ + assert s/1 = #"#" + s: s + 1 + if s = e [throw-error lex s - 1 e TYPE_ISSUE] + cell: alloc-slot lex + word/make-at symbol/make-alt-utf8 s as-integer e - s cell + set-type cell TYPE_ISSUE + lex/in-pos: e ;-- reset the input position to delimiter byte + ] + scan-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] @@ -1793,7 +1801,7 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - load?: either state >= T_STRING [ + load?: either state >= T_ISSUE [ either lex/fun-ptr = null [any [not one? ld?]][ fire-event lex words/_scan 0 - index null s lex/in-pos ] @@ -1802,7 +1810,7 @@ lexer: context [ do-scan: as scanner! scanners/index catch LEX_ERR [do-scan lex s p flags] - if all [state >= T_STRING lex/fun-ptr <> null][ ;-- for < T_STRING, events are triggered from scan-* + if all [state >= T_ISSUE lex/fun-ptr <> null][ ;-- for < T_ISSUE, events are triggered from scan-* slot: lex/tail - 1 unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] @@ -1953,8 +1961,8 @@ lexer: context [ :scan-comment ;-- T_CMT :scan-integer ;-- T_INTEGER :scan-word ;-- T_WORD - :scan-ref-issue ;-- T_REFINE - :scan-ref-issue ;-- T_ISSUE + :scan-refinement ;-- T_REFINE + :scan-issue ;-- T_ISSUE :scan-string ;-- T_STRING :scan-file ;-- T_FILE :scan-binary ;-- T_BINARY From a531da296fe1d43e10ad9cbb911b78dad4580ec6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 20 Jan 2020 17:33:45 +0100 Subject: [PATCH 0806/3432] FIX: incorrect library import --- modules/view/backends/gtk3/gtk.reds | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a5eb11ff57..e18dce853e 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1791,17 +1791,17 @@ GPtrArray!: alias struct! [ button [handle!] return: [logic!] ] - gtk_toggle_button_get_inconsistent: "gtk_toggle_button_get_inconsistent" [ + gtk_toggle_button_set_active: "gtk_toggle_button_set_active" [ button [handle!] - return: [logic!] + active? [logic!] ] - gtk_toggle_button_set_inconsistent: "gtk_toggle_button_get_inconsistent" [ + gtk_toggle_button_get_inconsistent: "gtk_toggle_button_get_inconsistent" [ button [handle!] - inconsist? [logic!] + return: [logic!] ] - gtk_toggle_button_set_active: "gtk_toggle_button_set_active" [ + gtk_toggle_button_set_inconsistent: "gtk_toggle_button_set_inconsistent" [ button [handle!] - active? [logic!] + setting [logic!] ] gtk_toggle_button_toggled: "gtk_toggle_button_toggled" [ button [handle!] From d523f1c66746cd9d2a3694e654685bf9fe74c2e6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 22 Jan 2020 13:27:38 +0100 Subject: [PATCH 0807/3432] FIX: issue #4084 (`parse/trace` fails on 2 integer! rule) --- runtime/parse.reds | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index ae84cc5c9e..0a0b16fa81 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -86,9 +86,9 @@ parser: context [ #define PARSE_TRACE(event) [ #if red-tracing? = yes [ if OPTION?(fun) [ - rule/head: (as-integer cmd - block/rs-head rule) >> 4 - if negative? rule/head [rule/head: 0] - unless fire-event fun words/event match? rule input fun-locs saved? [ + head: (as-integer cmd - block/rs-head rule) >> 4 + if negative? head [head: 0] + unless fire-event fun words/event match? rule input fun-locs head saved? [ return as red-value! logic/push match? ] ] @@ -689,6 +689,7 @@ parser: context [ rule [red-block!] input [red-series!] locals [integer!] + offset [integer!] saved? [logic!] return: [logic!] /local @@ -711,10 +712,11 @@ parser: context [ stack/mark-func words/_body fun/ctx ;@@ find something more adequate stack/push as red-value! event logic/push match? - stack/push as red-value! rule + rule: as red-block! stack/push as red-value! rule stack/push as red-value! input stack/push as red-value! rules if positive? locals [_function/init-locals 1 + locals] ;-- +1 for /local refinement + rule/head: offset catch RED_THROWN_ERROR [_function/call fun ctx] @@ -827,6 +829,7 @@ parser: context [ cnt [integer!] len [integer!] offset [integer!] + head [integer!] cnt-col [integer!] saved [integer!] before [integer!] From db35bd7dad5dc75d32064048dbc031c658233749 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 22 Jan 2020 13:27:38 +0100 Subject: [PATCH 0808/3432] FIX: issue #4084 (`parse/trace` fails on 2 integer! rule) --- runtime/parse.reds | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index b3b987ae02..0239bad18d 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -86,9 +86,9 @@ parser: context [ #define PARSE_TRACE(event) [ #if red-tracing? = yes [ if OPTION?(fun) [ - rule/head: (as-integer cmd - block/rs-head rule) >> 4 - if negative? rule/head [rule/head: 0] - unless fire-event fun words/event match? rule input fun-locs saved? [ + head: (as-integer cmd - block/rs-head rule) >> 4 + if negative? head [head: 0] + unless fire-event fun words/event match? rule input fun-locs head saved? [ return as red-value! logic/push match? ] ] @@ -667,6 +667,7 @@ parser: context [ rule [red-block!] input [red-series!] locals [integer!] + offset [integer!] saved? [logic!] return: [logic!] /local @@ -682,10 +683,11 @@ parser: context [ stack/mark-func words/_body fun/ctx ;@@ find something more adequate stack/push as red-value! event logic/push match? - stack/push as red-value! rule + rule: as red-block! stack/push as red-value! rule stack/push as red-value! input stack/push as red-value! rules if positive? locals [_function/init-locals 1 + locals] ;-- +1 for /local refinement + rule/head: offset catch RED_THROWN_ERROR [_function/call fun global-ctx] ;FIXME: hardcoded origin context @@ -798,6 +800,7 @@ parser: context [ cnt [integer!] len [integer!] offset [integer!] + head [integer!] cnt-col [integer!] saved [integer!] before [integer!] From 6d787d95112c76c5934615351a779ee0e0f33de0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 22 Jan 2020 13:37:16 +0100 Subject: [PATCH 0809/3432] TESTS: regression test for #4084. --- tests/source/environment/functions-test.red | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/source/environment/functions-test.red b/tests/source/environment/functions-test.red index 10c023c26a..fbae142d70 100644 --- a/tests/source/environment/functions-test.red +++ b/tests/source/environment/functions-test.red @@ -234,12 +234,11 @@ Red [ --assert (make bitset! #{00000000000000000000000020}) = charset "b" ===end-group=== -===start-group=== "on-parse-event tests" - ;TODO -===end-group=== - ===start-group=== "parse-trace tests" - ;TODO + --test-- "#4084" + --assert parse/trace "aaa" [1 3 skip] func [e m r i s][true] + --assert parse/trace [a a a][0 3 word!] func [e m r i s][true] + ===end-group=== ===start-group=== "suffix? tests" From 28a3fe96f0822c4dc14a960dd0c8c16887e105d4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 22 Jan 2020 14:08:22 +0100 Subject: [PATCH 0810/3432] FEAT: import signal blocking/unblocking functions --- modules/view/backends/gtk3/gtk.reds | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index e18dce853e..8c35f2c043 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -609,6 +609,14 @@ GPtrArray!: alias struct! [ g_signal_emit_by_name: "g_signal_emit_by_name" [ [variadic] ] + g_signal_handler_block: "g_signal_handler_block" [ + object [handle!] + handler [integer!] + ] + g_signal_handler_unblock: "g_signal_handler_unblock" [ + object [handle!] + handler [integer!] + ] g_object_ref: "g_object_ref" [ object [int-ptr!] return: [int-ptr!] From daaf49cf24280659f668f2f632b989c818773cd9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 22 Jan 2020 14:13:42 +0100 Subject: [PATCH 0811/3432] FIX: [GTK] issues #4244, #4245 --- modules/view/backends/gtk3/gui.reds | 51 +++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7b8b0773c5..dafdcc07e9 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1191,21 +1191,39 @@ set-selected-focus: func [ ] set-logic-state: func [ - widget [handle!] - state [red-logic!] - check? [logic!] + widget [handle!] + state [red-logic!] + check? [logic!] /local - value [integer!] -][ - value: either TYPE_OF(state) <> TYPE_LOGIC [ - state/header: TYPE_LOGIC - state/value: check? - either check? [-1][0] + flags [integer!] + type [integer!] + tri? [logic!] + value [logic!] +][ + if check? [ + flags: get-flags as red-block! (get-face-values widget) + FACE_OBJ_FLAGS + tri?: flags and FACET_FLAGS_TRISTATE <> 0 + g_signal_handler_block widget check-handler ;-- suppress signal handler + ] + + type: TYPE_OF(state) + either all [check? tri? type = TYPE_NONE][ + gtk_toggle_button_set_inconsistent widget yes + gtk_toggle_button_set_active widget no ][ - as-integer state/value ;-- returns 0/1, matches the messages + value: switch type [ + TYPE_NONE [false] + TYPE_LOGIC [state/value] ;-- returns 0/1, matches the messages + default [true] + ] + + gtk_toggle_button_set_inconsistent widget no + gtk_toggle_button_set_active widget value + ] + + if check? [ + g_signal_handler_unblock widget check-handler ;-- resume signal handling ] - gtk_toggle_button_set_active widget as logic! value - if value = -1 [gtk_toggle_button_set_inconsistent widget true] ] get-flags: func [ @@ -1243,6 +1261,7 @@ get-flags: func [ sym = no-buttons [flags: flags or FACET_FLAGS_NO_BTNS] sym = modal [flags: flags or FACET_FLAGS_MODAL] sym = popup [flags: flags or FACET_FLAGS_POPUP] + sym = tri-state [flags: flags or FACET_FLAGS_TRISTATE] sym = scrollable [flags: flags or FACET_FLAGS_SCROLLABLE] sym = password [flags: flags or FACET_FLAGS_PASSWORD] true [fire [TO_ERROR(script invalid-arg) word]] @@ -1586,7 +1605,6 @@ OS-make-view: func [ case [ sym = check [ widget: gtk_check_button_new_with_label caption - set-logic-state widget as red-logic! data no ] sym = radio [ handle: as handle! parent @@ -1795,14 +1813,19 @@ OS-make-view: func [ ] unless any [sym = window sym = area][build-context-menu widget menu] - + ; Deal with actors connect-widget-events widget values sym + if sym = radio [ if last-face-type? face as handle! parent sym [ connect-radio-toggled-events face widget as handle! parent ] ] + + if sym = check [ + set-logic-state widget as red-logic! data yes + ] change-selection widget selected sym if sym <> base [change-font widget face values] From 3dd6e4c4e602b170c18bbc231ad476e4ca63212e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 22 Jan 2020 14:14:16 +0100 Subject: [PATCH 0812/3432] FEAT: [GTK] support tri-state CHECK face --- modules/view/backends/gtk3/events.reds | 8 ++-- modules/view/backends/gtk3/handlers.reds | 47 +++++++++++++++++------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 60ae4abaf4..e98eb3b3d2 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -23,9 +23,11 @@ Red/System [ gui-evt: declare red-event! ;-- low-level event value slot gui-evt/header: TYPE_EVENT -modal-loop-type: 0 ;-- remanence of last EVT_MOVE or EVT_SIZE +check-handler: 0 ;-- for blocking signal propagation during check's state update + +modal-loop-type: 0 ;-- remanence of last EVT_MOVE or EVT_SIZE zoom-distance: 0 -special-key: -1 ;-- <> -1 if a non-displayable key is pressed +special-key: -1 ;-- <> -1 if a non-displayable key is pressed flags-blk: declare red-block! ;-- static block value for event/flags flags-blk/header: TYPE_BLOCK @@ -1001,7 +1003,7 @@ connect-widget-events: func [ case [ sym = check [ - gobj_signal_connect(widget "toggled" :button-toggled widget) + check-handler: gobj_signal_connect(widget "toggled" :button-toggled widget) ;-- used to block signal ] sym = radio [ 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 26a35d054d..ef3930155d 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -64,22 +64,43 @@ button-clicked: func [ button-toggled: func [ [cdecl] - evbox [handle!] - button [handle!] + evbox [handle!] + button [handle!] /local - bool [red-logic!] - type [integer!] - undetermined? [logic!] -][ - bool: (as red-logic! get-face-values button) + FACE_OBJ_DATA - undetermined?: gtk_toggle_button_get_inconsistent button - - either undetermined? [ - type: TYPE_OF(bool) - bool/header: TYPE_NONE ;-- NONE indicates undeterminate + values [red-value!] + bool [red-logic!] + type [red-word!] + flags [integer!] + sym [integer!] + tri? [logic!] + toggled? [logic!] + mixed? [logic!] +][ + values: get-face-values button + bool: as red-logic! values + FACE_OBJ_DATA + type: as red-word! values + FACE_OBJ_TYPE + flags: get-flags as red-block! values + FACE_OBJ_FLAGS + + sym: symbol/resolve type/symbol + tri?: flags and FACET_FLAGS_TRISTATE <> 0 + toggled?: gtk_toggle_button_get_active button + + either all [sym = check tri?][ + mixed?: gtk_toggle_button_get_inconsistent button + if toggled? [ + gtk_toggle_button_set_inconsistent button not mixed? ;-- flip on each toggle + unless mixed? [ ;-- N Y + g_signal_handler_block button check-handler ;-- [ ] <-> [v] <-> [-] + gtk_toggle_button_set_active button no ;-- |--- emulate ---^ + g_signal_handler_unblock button check-handler + bool/header: TYPE_NONE + ] + ] ][ - bool/value: gtk_toggle_button_get_active button + bool/header: TYPE_LOGIC + bool/value: toggled? ] + make-event button 0 EVT_CHANGE ] From 9c4048468e58b8c5cfc590b086ed17112f5c7fd9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 19 Jan 2020 20:22:51 +0100 Subject: [PATCH 0813/3432] FIX: [macOS] issue #4246 --- modules/view/backends/macOS/delegates.reds | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds index 3a94d698e5..3cf56afc84 100644 --- a/modules/view/backends/macOS/delegates.reds +++ b/modules/view/backends/macOS/delegates.reds @@ -155,7 +155,6 @@ button-mouse-down: func [ make-event self 0 EVT_LEFT_UP if inside? [ inside?: false - objc_msgSend [self sel_getUid "setNextState"] button-click self ] ] @@ -413,10 +412,19 @@ button-click: func [ w: as red-word! values + FACE_OBJ_TYPE type: symbol/resolve w/symbol + if type <> radio [objc_msgSend [self sel_getUid "setNextState"]] + event: case [ type = button [EVT_CLICK] - type = radio [get-logic-state self EVT_CLICK] ;-- gets converted to CHANGE by high-level event handler type = check [get-logic-state self EVT_CHANGE] + all [ + type = radio + NSOffState = objc_msgSend [self sel_getUid "state"] ;-- ignore double-click (fixes #4246) + ][ + objc_msgSend [self sel_getUid "setNextState"] ;-- gets converted to CHANGE by high-level event handler + get-logic-state self + EVT_CLICK + ] true [0] ] From 84e5db8c3b5c0321963380d6454ba87c5cc31083 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 22 Jan 2020 18:01:54 +0100 Subject: [PATCH 0814/3432] FEAT: closes malformed path before triggering an error event. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d0e058a9cb..cb8de3ab39 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -846,6 +846,7 @@ lexer: context [ scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][] scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ + if all [lex/fun-ptr <> null lex/entry = S_PATH][close-block lex s e -1] either lex/prev < --EXIT_STATES-- [ index: lex/prev index: as-integer type-table/index From 8cb7189ecd78615a000308172c610f627fdec258 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 22 Jan 2020 18:15:47 +0100 Subject: [PATCH 0815/3432] TESTS: add tri-state check box to manual View test --- tests/view-test.red | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/view-test.red b/tests/view-test.red index 3c33a4818a..a9301d9c7d 100644 --- a/tests/view-test.red +++ b/tests/view-test.red @@ -585,11 +585,21 @@ win/pane: reduce [ ] check-face: make face! [ - type: 'check text: "check box" offset: 300x170 size: 90x24 + type: 'check text: "2 states" offset: 300x150 size: 80x24 data: on actors: object [ on-change: func [face [object!] event [event!]][ - probe face/data + print ["2-state checkbox:" face/data] + ] + ] + ] + make face! [ + type: 'check text: "3 states" offset: 300x170 size: 80x24 + data: none + flags: 'tri-state + actors: object [ + on-change: function [face [object!] event [event!]][ + print ["3-state checkbox:" face/data] ] ] ] From fe4f3f4494967f3631c9e662ebefa7f50d082b91 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 22 Jan 2020 19:12:52 +0100 Subject: [PATCH 0816/3432] FIX: force consistent state transition --- modules/view/backends/windows/events.reds | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index f2d1ed8ae0..466e821134 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -622,6 +622,7 @@ process-command-event: func [ idx [integer!] res [integer!] sym [integer!] + state [integer!] saved [handle!] child [handle!] evt [integer!] @@ -645,6 +646,16 @@ process-command-event: func [ evt: case [ sym = button [EVT_CLICK] sym = check [ + if 0 <> (FACET_FLAGS_TRISTATE and get-flags as red-block! get-facet current-msg FACE_OBJ_FLAGS)[ + state: as integer! SendMessage child BM_GETCHECK 0 0 + state: switch state [ ;-- force [ ] -> [-] -> [v] transition + BST_UNCHECKED [BST_CHECKED] + BST_INDETERMINATE [BST_UNCHECKED] + BST_CHECKED [BST_INDETERMINATE] + default [0] + ] + SendMessage child BM_SETCHECK state 0 + ] get-logic-state current-msg EVT_CHANGE ] From b4e2d9a842e1d274b94b1fa7e1fd11eda0c06de7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 22 Jan 2020 20:16:27 +0100 Subject: [PATCH 0817/3432] FEAT: preliminary work on stricter separation between scanning and loading stages. --- runtime/lexer.reds | 104 ++++++++++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index cb8de3ab39..eae8c3a401 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -302,6 +302,7 @@ lexer: context [ utf8-bufsize: 100'000 utf8-buffer: as byte-ptr! 0 scanners: as int-ptr! 0 ;-- scan functions jump table (dynamically filled) + loaders: as int-ptr! 0 ;-- load functions jump table (dynamically filled) stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number root-state: as state! 0 ;-- global entry point to state struct list @@ -925,7 +926,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip / ] - scan-path-item: func [lex [state!] s e [byte-ptr!] flags [integer!] + check-path-end: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!] cp [integer!] @@ -1802,21 +1803,21 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - load?: either state >= T_ISSUE [ - either lex/fun-ptr = null [any [not one? ld?]][ - fire-event lex words/_scan 0 - index null s lex/in-pos - ] - ][yes] + do-scan: as scanner! scanners/index + if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] + load?: either lex/fun-ptr = null [any [not one? ld?]][ + fire-event lex words/_scan 0 - index null s lex/in-pos + ] if load? [ - do-scan: as scanner! scanners/index - catch LEX_ERR [do-scan lex s p flags] - - if all [state >= T_ISSUE lex/fun-ptr <> null][ ;-- for < T_ISSUE, events are triggered from scan-* + do-load: as loader! loaders/index + if :do-load <> null [catch LEX_ERR [do-load lex s p flags]] + + if lex/fun-ptr <> null [ slot: lex/tail - 1 unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ - scan-path-item lex s lex/in-pos flags ;-- lex/in-pos could have changed + check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] ] if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH lex/tail - 1 = lex/buffer][exit] @@ -1924,14 +1925,19 @@ lexer: context [ scan dst utf8-buffer size one? load? wrap? len fun as red-series! str ] - set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s [int-ptr!]][ + set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s l [int-ptr!]][ + count: count / 2 scanners: as int-ptr! allocate count * size? int-ptr! + loaders: as int-ptr! allocate count * size? int-ptr! s: scanners + l: loaders until [ - s/value: list/value - list: list + 1 + s/value: list/1 + l/value: list/2 + list: list + 2 count: count - 1 s: s + 1 + l: l + 1 zero? count ] ] @@ -1943,43 +1949,43 @@ lexer: context [ ;-- switch following tables to zero-based indexing lex-classes: lex-classes + 1 transitions: transitions + 1 - skip-table: skip-table + 1 - line-table: line-table + 1 - type-table: type-table + 1 + skip-table: skip-table + 1 + line-table: line-table + 1 + type-table: type-table + 1 set-jump-table [ - :scan-eof ;-- T_EOF - :scan-error ;-- T_ERROR - :scan-block-open ;-- T_BLK_OP - :scan-block-close ;-- T_BLK_CL - :scan-block-open ;-- T_PAR_OP - :scan-paren-close ;-- T_PAR_CL - :scan-mstring-open ;-- T_MSTR_OP (multiline string) - :scan-mstring-close ;-- T_MSTR_CL (multiline string) - :scan-map-open ;-- T_MAP_OP - :scan-path-open ;-- T_PATH - :scan-construct ;-- T_CONS_MK - :scan-comment ;-- T_CMT - :scan-integer ;-- T_INTEGER - :scan-word ;-- T_WORD - :scan-refinement ;-- T_REFINE - :scan-issue ;-- T_ISSUE - :scan-string ;-- T_STRING - :scan-file ;-- T_FILE - :scan-binary ;-- T_BINARY - :scan-char ;-- T_CHAR - :scan-percent ;-- T_PERCENT - :scan-float ;-- T_FLOAT - :scan-float-special ;-- T_FLOAT_SP - :scan-tuple ;-- T_TUPLE - :scan-date ;-- T_DATE - :scan-pair ;-- T_PAIR - :scan-time ;-- T_TIME - :scan-money ;-- T_MONEY - :scan-tag ;-- T_TAG - :scan-url ;-- T_URL - :scan-email ;-- T_EMAIL - :scan-hex ;-- T_HEX + :scan-eof null ;-- T_EOF + :scan-error null ;-- T_ERROR + :scan-block-open null ;-- T_BLK_OP + :scan-block-close null ;-- T_BLK_CL + :scan-block-open null ;-- T_PAR_OP + :scan-paren-close null ;-- T_PAR_CL + :scan-mstring-open null ;-- T_MSTR_OP (multiline string) + :scan-mstring-close null ;-- T_MSTR_CL (multiline string) + :scan-map-open null ;-- T_MAP_OP + :scan-path-open null ;-- T_PATH + :scan-construct null ;-- T_CONS_MK + :scan-comment null ;-- T_CMT + :scan-integer :load-integer ;-- T_INTEGER + :scan-word :load-word ;-- T_WORD + :scan-refinement :load-word ;-- T_REFINE + null :load-word ;-- T_ISSUE + null :load-string ;-- T_STRING + null :load-file ;-- T_FILE + null :load-binary ;-- T_BINARY + null :load-char ;-- T_CHAR + null :load-percent ;-- T_PERCENT + null :load-float ;-- T_FLOAT + null :load-float-special ;-- T_FLOAT_SP + null :load-tuple ;-- T_TUPLE + null :load-date ;-- T_DATE + null :load-pair ;-- T_PAIR + null :load-time ;-- T_TIME + null :load-money ;-- T_MONEY + null :load-tag ;-- T_TAG + null :load-url ;-- T_URL + null :load-email ;-- T_EMAIL + null :load-hex ;-- T_HEX ] ] From 5800d86dc850ff09c92b63371bfd9d3499d4df60 Mon Sep 17 00:00:00 2001 From: x8x Date: Mon, 13 Jan 2020 02:31:19 +0700 Subject: [PATCH 0818/3432] FIX: wrong binaries download URL --- environment/console/help.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/console/help.red b/environment/console/help.red index 25b810df1a..ce02b68bc8 100644 --- a/environment/console/help.red +++ b/environment/console/help.red @@ -618,7 +618,7 @@ help-ctx: context [ "--------------------------------------------" ] ][ - "Looks like this Red binary has been built from source.^/Please download latest build from our website:^/https://www.red-lang.org/download.html^/and try your code on it before submitting an issue." + "Looks like this Red binary has been built from source.^/Please download latest build from our website:^/https://www.red-lang.org/p/download.html^/and try your code on it before submitting an issue." ] ][ prin [ From 5c8050fc6bc62df62113cbdbe37e90750af93de4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 23 Jan 2020 13:14:15 +0100 Subject: [PATCH 0819/3432] FEAT: minor refactoring --- modules/view/backends/windows/events.reds | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 466e821134..d64ba407f3 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -674,11 +674,9 @@ process-command-event: func [ BN_UNPUSHED [ type: as red-word! get-facet current-msg FACE_OBJ_TYPE if type/symbol = radio [ - current-msg/hWnd: child ;-- force child handle - - ;-- ignore double-click (fixes #4246) - unless BST_UNCHECKED <> as integer! SendMessage child BM_GETSTATE 0 0 [ - make-event current-msg 0 EVT_CHANGE + current-msg/hWnd: child ;-- force child handle + unless as logic! SendMessage child BM_GETSTATE 0 0 [ + make-event current-msg 0 EVT_CHANGE ;-- ignore double-click (fixes #4246) ] ] ] From a60a4e3defa9e8045ab2ee736834f1da1a0d0f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boleslav=20B=C5=99ezovsk=C3=BD?= Date: Thu, 23 Jan 2020 15:06:26 +0100 Subject: [PATCH 0820/3432] FIX: Fixes #4258 --- environment/functions.red | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/environment/functions.red b/environment/functions.red index ff457720b5..e89a76d387 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -820,7 +820,8 @@ clean-path: func [ 'else [append what-dir file] ] if all [dir not dir? file][append file #"/"] - + if only [return file] + out: make file! length? file cnt: 0 From f0ab3fa05be0df044f7c7af3f6358abe912f3633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boleslav=20B=C5=99ezovsk=C3=BD?= Date: Thu, 23 Jan 2020 18:27:48 +0100 Subject: [PATCH 0821/3432] FIX: Updated CLEAN-PATH/ONLY tests --- tests/source/environment/functions-test.red | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/source/environment/functions-test.red b/tests/source/environment/functions-test.red index 10c023c26a..e388f3f6a9 100644 --- a/tests/source/environment/functions-test.red +++ b/tests/source/environment/functions-test.red @@ -404,8 +404,8 @@ Red [ --test-- "clean-path test" --assert %/red-lang.com = clean-path http://red-lang.com --assert (rejoin [what-dir %a]) = clean-path %a - --assert %"" = clean-path/only %a - --assert %/red-lang.com/ = clean-path/only/dir http://red-lang.com + --assert %a = clean-path/only %a + --assert http://red-lang.com/ = clean-path/only/dir http://red-lang.com ===end-group=== ===start-group=== "split-path tests" From e82a099606f2e9c7d330198820cb9520ebb8d681 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 24 Jan 2020 20:14:56 +0100 Subject: [PATCH 0822/3432] FEAT: completes lexer refactoring. --- libRed/libRed.red | 2 +- runtime/datatypes/block.reds | 2 +- runtime/datatypes/common.reds | 2 +- runtime/lexer.reds | 338 ++++++++++++++++---------------- runtime/natives.reds | 4 +- system/utils/libRedRT-exports.r | 2 +- utils/generate-lexer-table.red | 2 +- 7 files changed, 173 insertions(+), 179 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index 1881715da7..daf61a1797 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -251,7 +251,7 @@ Red [ if last-error <> null [return last-error] TRAP_ERRORS(name [ - lexer/load-string stack/arguments str -1 no yes no null null null + lexer/scan-string stack/arguments str -1 no yes no null null null stack/unwind-last ]) ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 71f3940875..7cd27a98b2 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -649,7 +649,7 @@ block: context [ TYPE_OBJECT [object/reflect as red-object! spec words/body] TYPE_MAP [map/reflect as red-hash! spec words/body] TYPE_VECTOR [vector/to-block as red-vector! spec proto] - TYPE_STRING [lexer/load-string as red-value! proto as red-string! spec -1 no yes no null null as red-series! spec] + TYPE_STRING [lexer/scan-string as red-value! proto as red-string! spec -1 no yes no null null as red-series! spec] TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] TYPE_ANY_PATH TYPE_ANY_LIST [proto: clone as red-block! spec no no] diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 38278b4b81..a4a7c73411 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -351,7 +351,7 @@ load-value: func [ blk [red-block!] value [red-value!] ][ - lexer/load-string stack/arguments str -1 yes yes yes null null as red-series! str + lexer/scan-string stack/arguments str -1 yes yes yes null null as red-series! str blk: as red-block! stack/arguments assert TYPE_OF(blk) = TYPE_BLOCK diff --git a/runtime/lexer.reds b/runtime/lexer.reds index eae8c3a401..7d5b3cbbe4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -34,8 +34,7 @@ lexer: context [ C_FLAG_SIGN: 00200000h C_FLAG_LESSER: 00100000h C_FLAG_GREATER: 00080000h - C_FLAG_ESC_HEX: 00000200h ;-- percent-escaped mode - C_FLAG_NOSTORE: 00000100h ;-- do not store decoded value + C_FLAG_ESC_HEX: 00000100h ;-- percent-escaped mode ] #define FL_UCS4 [(C_WORD or C_FLAG_UCS4)] @@ -295,9 +294,11 @@ lexer: context [ fun-ptr [red-function!] ;-- callback function pointer or NULL fun-locs [integer!] ;-- number of local words in callback function in-series [red-series!] ;-- optional back reference to input series + int-value [integer!] ;-- decoded integer! value (from scanner to loader) ] scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] + loader!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] utf8-bufsize: 100'000 utf8-buffer: as byte-ptr! 0 @@ -894,7 +895,7 @@ lexer: context [ lex/mstr-nest: lex/mstr-nest - 1 either zero? lex/mstr-nest [ - scan-string lex lex/mstr-s e lex/mstr-flags or flags + load-string lex lex/mstr-s e lex/mstr-flags or flags lex/mstr-s: null lex/mstr-flags: 0 lex/entry: S_START @@ -911,19 +912,18 @@ lexer: context [ scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - pos [byte-ptr!] type [integer!] ][ - pos: s type: switch s/1 [ - #"'" [s: s + 1 flags: flags and not C_FLAG_QUOTE TYPE_LIT_PATH] - #":" [s: s + 1 flags: flags and not C_FLAG_COLON TYPE_GET_PATH] + #"'" [TYPE_LIT_PATH] + #":" [TYPE_GET_PATH] default [TYPE_PATH] ] - open-block lex type pos ;-- open a new path series - scan-word lex s e flags ;-- load the head word + open-block lex type s ;-- open a new path series lex/entry: S_PATH ;-- overwrites the S_START set by open-block lex/in-pos: e + 1 ;-- skip / + lex/exit: T_WORD ;-- load the head word + lex/scanned: TYPE_WORD ] check-path-end: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -954,9 +954,9 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip / ] ] - + scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - if lex/fun-ptr <> null [fire-event lex words/_open T_CMT - --EXIT_STATES-- null s e] + if lex/fun-ptr <> null [fire-event lex words/_scan T_CMT - --EXIT_STATES-- null s e] ] scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -987,7 +987,103 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ] ] - scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] + scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] + /local + type [integer!] + p [byte-ptr!] + ][ + type: TYPE_WORD + if flags and C_FLAG_COLON <> 0 [ + case [ + s/1 = #":" [type: TYPE_GET_WORD] + e/0 = #":" [type: TYPE_SET_WORD] + all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path + true [throw-error lex s e type] + ] + ] + if s/1 = #"'" [ + if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] + type: TYPE_LIT_WORD + ] + if all [s/1 = #"/" type = TYPE_WORD][ ;-- //... + p: s + 1 + while [all [p < e p/1 = #"/"]][p: p + 1] + if p < e [throw-error lex s e TYPE_REFINEMENT] + ] + lex/scanned: type + ] + + scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] + /local + type [integer!] + ][ + assert s/1 = #"/" + type: either s + 1 = e [TYPE_WORD][ + either s/2 = #"/" [TYPE_WORD][TYPE_REFINEMENT] ;-- //... + ] + lex/scanned: type + lex/exit: T_WORD ;-- route to load-word + ] + + scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] + return: [integer!] + /local + o? [logic!] + p [byte-ptr!] + len i [integer!] + promote [subroutine!] + ][ + promote: [ + lex/scanned: TYPE_FLOAT + lex/exit: T_FLOAT ;-- fallback on load-float + return 0 + ] + p: s + if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present + + either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers + i: as-integer (p/1 - #"0") + ][ + len: as-integer e - p + if len > 10 [promote] + i: 0 + o?: no + either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path + loop len [ + i: 10 * i + as-integer (p/1 - #"0") + o?: o? or system/cpu/overflow? + p: p + 1 + ] + ][ ;-- process with quote(s) + loop len [ + if p/1 <> #"'" [ + i: 10 * i + as-integer (p/1 - #"0") + o?: o? or system/cpu/overflow? + ] + p: p + 1 + ] + ] + assert p = e + if o? [ + len: as-integer e - s ;-- account for sign in len now + either all [len = 11 zero? compare-memory s min-integer len][ + i: 80000000h + s: s + 1 ;-- ensure that the 0 subtraction does not occur + ][promote] + ] + ] + if s/value = #"-" [i: 0 - i] + lex/scanned: TYPE_INTEGER + lex/int-value: i + i + ] + + load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + integer/make-at alloc-slot lex lex/int-value + lex/in-pos: e ;-- reset the input position to delimiter byte + ] + + load-string: func [lex [state!] s e [byte-ptr!] flags [integer!] /local len unit index class digits extra cp type [integer!] str [red-string!] @@ -1142,13 +1238,15 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-word: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - cell [cell!] cp type class index [integer!] - p pos s-pos e-pos [byte-ptr!] + p pos [byte-ptr!] + cell [cell!] ][ - s-pos: s e-pos: e + type: lex/scanned + assert type > 0 + if flags and flags-LG = flags-LG [ ;-- handle word cases p: s while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < @@ -1167,35 +1265,28 @@ lexer: context [ ] ] ] - type: TYPE_WORD - if flags and C_FLAG_COLON <> 0 [ - case [ - s/1 = #":" [s: s + 1 type: TYPE_GET_WORD] - e/0 = #":" [e: e - 1 type: TYPE_SET_WORD] - all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path - true [throw-error lex s e type] + if type <> TYPE_WORD [ + switch type [ + TYPE_ISSUE + TYPE_REFINEMENT [ + s: s + 1 + if s = e [throw-error lex s - 1 e type] + ] + TYPE_LIT_WORD + TYPE_GET_WORD [s: s + 1] + TYPE_SET_WORD [e: e - 1] + default [0] ] ] - if s/1 = #"'" [ - if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] - s: s + 1 type: TYPE_LIT_WORD - ] - if s/1 = #"/" [ ;-- //... - p: s + 1 - while [all [p < e p/1 = #"/"]][p: p + 1] - if p < e [throw-error lex s e TYPE_REFINEMENT] - ] - lex/scanned: type - if all [lex/fun-ptr <> null not fire-event lex words/_scan type null s-pos e-pos][exit] + if lex/entry = S_PATH [if any [s/1 = #"'" s/1 = #":"][s: s + 1]] + cell: alloc-slot lex word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type - - if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter - if all [lex/fun-ptr <> null not fire-event lex words/_load type cell s-pos e-pos][lex/tail: cell] + if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] - scan-file: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ @@ -1205,12 +1296,12 @@ lexer: context [ if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] lex/type: TYPE_FILE - scan-string lex s e flags + load-string lex s e flags if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] /local bin [red-binary!] err [byte-ptr!] @@ -1247,7 +1338,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip } ] - scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-char: func [lex [state!] s e [byte-ptr!] flags [integer!] /local char [red-char!] len c [integer!] @@ -1272,119 +1363,19 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip " ] - scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - cell [cell!] - type [integer!] - p [byte-ptr!] - ][ - assert s/1 = #"/" - type: either s + 1 = e [s: s - 1 TYPE_WORD][ - either s/2 = #"/" [ ;-- //... - scan-word lex s e flags - exit - 0 - ][ - TYPE_REFINEMENT - ] - ] - lex/scanned: type - if all [lex/fun-ptr <> null not fire-event lex words/_scan type null s e][exit] - s: s + 1 - cell: alloc-slot lex - word/make-at symbol/make-alt-utf8 s as-integer e - s cell - set-type cell type - lex/in-pos: e ;-- reset the input position to delimiter byte - if all [lex/fun-ptr <> null not fire-event lex words/_load type cell s - 1 e][lex/tail: cell] - ] - - scan-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - cell [cell!] - ][ - assert s/1 = #"#" - s: s + 1 - if s = e [throw-error lex s - 1 e TYPE_ISSUE] - cell: alloc-slot lex - word/make-at symbol/make-alt-utf8 s as-integer e - s cell - set-type cell TYPE_ISSUE - lex/in-pos: e ;-- reset the input position to delimiter byte - ] - - scan-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] ][ assert e/1 = #"%" - scan-float lex s e flags + load-float lex s e flags fl: as red-float! lex/tail - 1 set-type as cell! fl TYPE_PERCENT fl/value: fl/value / 100.0 lex/in-pos: e + 1 ;-- skip ending delimiter ] - - scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] - return: [integer!] - /local - o? root? evt? [logic!] - p [byte-ptr!] - len i [integer!] - promote [subroutine!] - ][ - root?: flags and C_FLAG_NOSTORE = 0 ;-- scan-integer is not called by another scanner function - evt?: all [root? lex/fun-ptr <> null] - promote: [ - if all [evt? not fire-event lex words/_scan TYPE_FLOAT null s e][return 0] - scan-float lex s e flags ;-- overflow, fall back on float - if all [evt? not fire-event lex words/_load TYPE_FLOAT lex/tail - 1 s e][lex/tail: lex/tail - 1] - return 0 - ] - p: s - if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present - - either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers - i: as-integer (p/1 - #"0") - ][ - len: as-integer e - p - if len > 10 [promote] - i: 0 - o?: no - either flags and C_FLAG_QUOTE = 0 [ ;-- no quote, faster path - loop len [ - i: 10 * i + as-integer (p/1 - #"0") - o?: o? or system/cpu/overflow? - p: p + 1 - ] - ][ ;-- process with quote(s) - loop len [ - if p/1 <> #"'" [ - i: 10 * i + as-integer (p/1 - #"0") - o?: o? or system/cpu/overflow? - ] - p: p + 1 - ] - ] - assert p = e - if o? [ - len: as-integer e - s ;-- account for sign in len now - either all [len = 11 zero? compare-memory s min-integer len][ - i: 80000000h - s: s + 1 ;-- ensure that the 0 subtraction does not occur - ][ - promote - ] - ] - ] - if all [evt? not fire-event lex words/_scan TYPE_INTEGER null s e][return 0] - if s/value = #"-" [i: 0 - i] - if root? [integer/make-at alloc-slot lex i] - lex/scanned: TYPE_INTEGER - lex/in-pos: e ;-- reset the input position to delimiter byte - if all [evt? not fire-event lex words/_load TYPE_INTEGER lex/tail - 1 s e][lex/tail: lex/tail - 1] - i - ] - - scan-float: func [lex [state!] s e [byte-ptr!] flags [integer!] + + load-float: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] err [integer!] @@ -1398,7 +1389,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-float-special: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-float-special: func [lex [state!] s e [byte-ptr!] flags [integer!] /local fl [red-float!] p [byte-ptr!] @@ -1422,7 +1413,7 @@ lexer: context [ lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] /local cell [cell!] i pos [integer!] @@ -1452,7 +1443,7 @@ lexer: context [ ] - scan-date: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-date: func [lex [state!] s e [byte-ptr!] flags [integer!] /local err year month day hour min tz-h tz-m len ylen dlen value week wday yday [integer!] @@ -1628,7 +1619,7 @@ lexer: context [ store-date ] - scan-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] /local index [integer!] class [integer!] @@ -1643,14 +1634,14 @@ lexer: context [ ] pair/make-at alloc-slot lex - scan-integer lex s p flags or C_FLAG_NOSTORE - scan-integer lex p + 1 e flags or C_FLAG_NOSTORE + scan-integer lex s p flags + scan-integer lex p + 1 e flags lex/scanned: TYPE_PAIR ;-- overwrite value set by scan-integer lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-time: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-time: func [lex [state!] s e [byte-ptr!] flags [integer!] /local err hour min len [integer!] p mark [byte-ptr!] @@ -1687,19 +1678,19 @@ lexer: context [ time/make-at tm alloc-slot lex ] - scan-money: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + load-money: func [lex [state!] s e [byte-ptr!] flags [integer!]][ ;;TBD: implement this function once money! type is done throw-error lex s e ERR_BAD_CHAR ] - scan-tag: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!]][ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_TAG - scan-string lex s e flags + load-string lex s e flags lex/in-pos: e + 1 ;-- skip ending delimiter ] - scan-url: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-url: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ @@ -1707,21 +1698,21 @@ lexer: context [ p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] lex/type: TYPE_URL - scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + load-string lex s - 1 e flags ;-- compensate for lack of starting delimiter lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-email: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-email: func [lex [state!] s e [byte-ptr!] flags [integer!] /local p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_EMAIL - scan-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + load-string lex s - 1 e flags ;-- compensate for lack of starting delimiter lex/in-pos: e ;-- reset the input position to delimiter byte ] - scan-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] /local int [red-integer!] i index [integer!] @@ -1758,10 +1749,11 @@ lexer: context [ slot [cell!] term? load? [logic!] do-scan [scanner!] + do-load [loader!] ][ line: 1 until [ - flags: 0 + flags: 0 ;-- Scanning stage -- term?: no state: lex/entry prev: state @@ -1806,15 +1798,17 @@ lexer: context [ do-scan: as scanner! scanners/index if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] load?: either lex/fun-ptr = null [any [not one? ld?]][ - fire-event lex words/_scan 0 - index null s lex/in-pos + either state >= T_INTEGER [fire-event lex words/_scan 0 - index null s lex/in-pos][yes] ] - if load? [ + if load? [ ;-- Loading stage -- + index: lex/exit - --EXIT_STATES-- do-load: as loader! loaders/index - if :do-load <> null [catch LEX_ERR [do-load lex s p flags]] - - if lex/fun-ptr <> null [ - slot: lex/tail - 1 - unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] + if :do-load <> null [ + catch LEX_ERR [do-load lex s p flags] + if lex/fun-ptr <> null [ + slot: lex/tail - 1 + unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] + ] ] if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed @@ -1896,7 +1890,7 @@ lexer: context [ lex/scanned ] - load-string: func [ + scan-string: func [ dst [red-value!] ;-- destination slot str [red-string!] size [integer!] @@ -1925,7 +1919,7 @@ lexer: context [ scan dst utf8-buffer size one? load? wrap? len fun as red-series! str ] - set-jump-table: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s l [int-ptr!]][ + set-jump-tables: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s l [int-ptr!]][ count: count / 2 scanners: as int-ptr! allocate count * size? int-ptr! loaders: as int-ptr! allocate count * size? int-ptr! @@ -1953,7 +1947,7 @@ lexer: context [ line-table: line-table + 1 type-table: type-table + 1 - set-jump-table [ + set-jump-tables [ :scan-eof null ;-- T_EOF :scan-error null ;-- T_ERROR :scan-block-open null ;-- T_BLK_OP @@ -1963,7 +1957,7 @@ lexer: context [ :scan-mstring-open null ;-- T_MSTR_OP (multiline string) :scan-mstring-close null ;-- T_MSTR_CL (multiline string) :scan-map-open null ;-- T_MAP_OP - :scan-path-open null ;-- T_PATH + :scan-path-open :load-word ;-- T_PATH :scan-construct null ;-- T_CONS_MK :scan-comment null ;-- T_CMT :scan-integer :load-integer ;-- T_INTEGER diff --git a/runtime/natives.reds b/runtime/natives.reds index 395f2d9558..2b05ea8b20 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -555,7 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - lexer/load-string arg as red-string! arg -1 no yes no null null as red-string! arg + lexer/scan-string arg as red-string! arg -1 no yes no null null as red-string! arg DO_EVAL_BLOCK ] TYPE_URL @@ -2784,7 +2784,7 @@ natives: context [ ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - lexer/load-string slot str len next? yes no :offset fun as red-series! str + lexer/scan-string slot str len next? yes no :offset fun as red-series! str ] if next? [ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index cb5a17df0c..b3ac6c48ca 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -48,7 +48,7 @@ red/interpreter/eval-path red/lexer/scan - red/lexer/load-string + red/lexer/scan-string red/none/push-last diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 7d113c08d0..13801cb2df 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -81,7 +81,7 @@ context [ T_PATH - ;-- 65 T_CONS_MK - ;-- 66 T_CMT - ;-- 67 - T_INTEGER - ;-- 68 + T_INTEGER TYPE_INTEGER ;-- 68 T_WORD - ;-- 69 T_REFINE - ;-- 70 T_ISSUE TYPE_ISSUE ;-- 71 From d5a1813372bfc735cc9319123111bc142674954c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 24 Jan 2020 20:20:11 +0100 Subject: [PATCH 0823/3432] FIX: lexer-transitions.reds file was not refreshed in previous commit. --- runtime/lexer-transitions.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index de9d45ef54..957740688f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -94,7 +94,7 @@ Red/System [ type-table: #{ 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 -00000000000000140708290A260C0C272F252B332C092D0B +000000000B0000140708290A260C0C272F252B332C092D0B } transitions: #{ 000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E From 72ad41309bf7fe75a83b6264d878d48009e42b0f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 24 Jan 2020 23:00:44 +0100 Subject: [PATCH 0824/3432] TESTS: adds a new test file for `transcode` and new lexer's features. --- tests/source/units/all-tests.txt | 1 + tests/source/units/lexer-tests.red | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/source/units/lexer-tests.red diff --git a/tests/source/units/all-tests.txt b/tests/source/units/all-tests.txt index c281864797..75c68c9ccb 100644 --- a/tests/source/units/all-tests.txt +++ b/tests/source/units/all-tests.txt @@ -12,6 +12,7 @@ select-test.red binding-test.red evaluation-test.red load-test.red +lexer-test.red switch-test.red case-test.red char-test.red diff --git a/tests/source/units/lexer-tests.red b/tests/source/units/lexer-tests.red new file mode 100644 index 0000000000..799352e712 --- /dev/null +++ b/tests/source/units/lexer-tests.red @@ -0,0 +1,21 @@ +Red [ + Title: "Red lexer test script" + Author: "Nenad Rakocevic" + File: %lexer-test.reds + Tabs: 4 + Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../quick-test/quick-test.red + +~~~start-file~~~ "lexer" + +===start-group=== "transcode/next" + +===end-group=== + + +===start-group=== "transcode/trace" + +===end-group=== \ No newline at end of file From def789a1caf43b3e2257d4a177d6f5c42f1b440d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 24 Jan 2020 23:28:29 +0100 Subject: [PATCH 0825/3432] FIX: matching values in Parse on binary input not always working properly. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7d5b3cbbe4..59d1051e25 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1814,7 +1814,10 @@ lexer: context [ check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] ] - if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH lex/tail - 1 = lex/buffer][exit] + if all [ + one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH + any [not ld? lex/tail - 1 = lex/buffer] + ][exit] ;-- early exit for single value request lex/in-pos >= lex/in-end ] if lex/entry = S_M_STRING [catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING]] From 65e60cd91b317d87537c70de463a9eafca3594ec Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 24 Jan 2020 23:34:21 +0100 Subject: [PATCH 0826/3432] TESTS: wrong test file name. --- tests/source/units/{lexer-tests.red => lexer-test.red} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/source/units/{lexer-tests.red => lexer-test.red} (100%) diff --git a/tests/source/units/lexer-tests.red b/tests/source/units/lexer-test.red similarity index 100% rename from tests/source/units/lexer-tests.red rename to tests/source/units/lexer-test.red From 706dada470d9c536f665b2a2e48e0b493b6999ac Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 25 Jan 2020 20:36:14 +0100 Subject: [PATCH 0827/3432] FIX: type reported in lexer's scan event not always correct. --- environment/system.red | 4 ++-- runtime/lexer.reds | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/environment/system.red b/environment/system.red index 64199d3b81..78edf55de3 100644 --- a/environment/system.red +++ b/environment/system.red @@ -406,8 +406,8 @@ system: context [ exit-states: [ eof error! block! block! paren! paren! string! string! map! path! any-type! - comment word! refinement! issue! string! file! binary! char! percent! - integer! float! float! tuple! date! pair! time! money! tag! url! email! hex + comment integer! word! refinement! issue! string! file! binary! char! percent! + float! float! tuple! date! pair! time! money! tag! url! email! hex ] ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 59d1051e25..5b9670ef88 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1798,7 +1798,8 @@ lexer: context [ do-scan: as scanner! scanners/index if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] load?: either lex/fun-ptr = null [any [not one? ld?]][ - either state >= T_INTEGER [fire-event lex words/_scan 0 - index null s lex/in-pos][yes] + index: either zero? lex/scanned [0 - index][lex/scanned] + either state >= T_INTEGER [fire-event lex words/_scan index null s lex/in-pos][yes] ] if load? [ ;-- Loading stage -- index: lex/exit - --EXIT_STATES-- From 86e57b92df4fa163b86c32d8e5b92cba5e8a0722 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 25 Jan 2020 20:42:38 +0100 Subject: [PATCH 0828/3432] TESTS: adds tests for transcode/trace. --- tests/source/units/lexer-test.red | 178 +++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 1 deletion(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 799352e712..871322651c 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -13,9 +13,185 @@ Red [ ===start-group=== "transcode/next" + --test-- "tn-1" + --assert [123 " []hello"] == transcode/next "123 []hello" + --assert [[] "hello"] == transcode/next " []hello" + --assert [hello ""] == transcode/next "hello" + + --test-- "tn-2" + --assert [[a] " 123"] == transcode/next "[a] 123" + + ===end-group=== ===start-group=== "transcode/trace" -===end-group=== \ No newline at end of file + logs: make block! 100 + + lex-logger: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + any [event <> 'error all [input: next input false]] + ] + + --test-- "tt-1" + clear logs + --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger + --assert logs = [ + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + open path! datatype! 1 6x6 + load word! datatype! 1 b + close path! datatype! 1 8x8 + error error! datatype! 1 8x8 + open block! datatype! 1 9x9 + close block! datatype! 1 10x10 + ] + + --test-- "tt-2" + clear logs + --assert (compose [a: 1 (to-path 'b) x]) == transcode/trace "a: 1 b/ x" :lex-logger + --assert logs = [ + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + open path! datatype! 1 6x6 + load word! datatype! 1 b + close path! datatype! 1 8x8 + error error! datatype! 1 8x8 + scan word! word! 1 9x10 + load word! datatype! 1 x + ] + + --test-- "tt-3" + clear logs + --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-logger + --assert logs = [ + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + open map! datatype! 1 7x7 + scan set-word! word! 1 8x10 + load set-word! datatype! 1 r: + scan integer! word! 1 11x12 + load integer! datatype! 1 2 + close map! datatype! 1 12x12 + open block! datatype! 1 14x14 + scan word! word! 1 16x17 + load word! datatype! 1 x + error error! datatype! 1 14x17 + ] + + --test-- "tt-4" + clear logs + --assert [a: 1 x] == transcode/trace "a: 1 ) x" :lex-logger + --assert logs = [ + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + close paren! datatype! 1 6x6 + error error! datatype! 1 6x6 + scan word! word! 1 8x9 + load word! datatype! 1 x + ] + + --test-- "tt-5" + clear logs + --assert [hello 3.14 pi world] == transcode/trace "hello ^/\ 3.14 pi world" :lex-logger + --assert logs = [ + scan word! word! 1 1x6 + load word! datatype! 1 hello + error error! datatype! 2 8x8 + scan float! word! 2 10x14 + load float! datatype! 2 3.14 + scan word! word! 2 15x17 + load word! datatype! 2 pi + scan word! word! 2 18x23 + load word! datatype! 2 world + ] + + --test-- "tt-6" + clear logs + --assert [123 "abc" 123456789123.0 test] == transcode/trace "123 {abc} 123456789123 test" :lex-logger + --assert logs = [ + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + open string! datatype! 1 5x5 + close string! datatype! 1 6x9 + scan float! word! 1 11x23 + load float! datatype! 1 123456789123.0 + scan word! word! 1 24x28 + load word! datatype! 1 test + ] + + --test-- "tt-7" + clear logs + --assert [a: 1] == transcode/trace "a: 1 ]" :lex-logger + --assert logs = [ + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + close block! datatype! 1 6x6 + error error! datatype! 1 6x6 + ] + + --test-- "tt-8" + lex-filter: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + switch event [ + scan [yes] + load [to-logic find [integer! float! pair!] type] + open [no] + close [no] + ] + ] + + clear logs + --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter + --assert logs = [ + scan word! word! 1 1x6 + load word! datatype! 1 hello + scan integer! word! 2 8x11 + load integer! datatype! 2 123 + open block! datatype! 3 13x13 + scan pair! word! 4 15x18 + load pair! datatype! 4 3x4 + open string! datatype! 4 19x19 + close string! datatype! 4 20x24 + scan float! word! 4 26x30 + load float! datatype! 4 3.14 + scan word! word! 4 31x33 + load word! datatype! 4 pi + close block! datatype! 4 33x33 + scan word! word! 5 36x41 + load word! datatype! 5 world + ] + + +===end-group=== + +~~~end-file~~~ \ No newline at end of file From aff6eedcbf3baac71b4adb756c11c23820003a3b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 27 Jan 2020 16:54:04 +0100 Subject: [PATCH 0829/3432] FEAT: adds /one refinement to TRANSCODE. Purpose: avoids allocating any extra wrapper block, just loads and returns a single value. --- environment/natives.red | 1 + runtime/lexer.reds | 2 +- runtime/natives.reds | 15 +++++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index 9b56363235..68d5ba0fd5 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -912,6 +912,7 @@ transcode: make native! [[ "Translates UTF-8 binary source to values. Returns one or several values in a block" src [binary! string!] "UTF-8 input buffer; string argument will be UTF-8 encoded" /next "Translate next complete value (blocks as single value)" + /one "Translate next complete value, returns the value only" /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" /into "Optionally provides an output block" diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5b9670ef88..0bde8840e1 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1830,7 +1830,7 @@ lexer: context [ src [byte-ptr!] ;-- UTF-8 buffer size [integer!] ;-- buffer size in bytes one? [logic!] ;-- scan a single value - load? [logic!] ;-- disable value loading, only scanning (one? implied) + load? [logic!] ;-- disable value loading, only scanning wrap? [logic!] ;-- force returned loaded value(s) in a block len [int-ptr!] ;-- return the consumed input length fun [red-function!] ;-- optional callback function diff --git a/runtime/natives.reds b/runtime/natives.reds index 2b05ea8b20..beca3bf15a 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2727,11 +2727,13 @@ natives: context [ transcode*: func [ check? [logic!] next [integer!] + one [integer!] part [integer!] into [integer!] trace [integer!] /local offset len type [integer!] + next? one? all? [logic!] slot arg [red-value!] bin bin2 [red-binary!] int [red-integer!] @@ -2739,13 +2741,13 @@ natives: context [ blk [red-block!] fun [red-function!] s [series!] - next? [logic!] ][ - #typecheck [transcode next part into trace] + #typecheck [transcode next one part into trace] + all?: one = -1 next?: next > -1 slot: stack/push* - if next? [ + if all [next? all?][ blk: block/preallocate as red-block! slot 2 no s: GET_BUFFER(blk) s/tail: s/offset + 2 @@ -2778,15 +2780,16 @@ natives: context [ ] if len < 0 [len: 0] ] + one?: any [next? not all?] either type = TYPE_BINARY [ if len < 0 [len: binary/rs-length? bin] - lexer/scan slot binary/rs-head bin len next? yes no :offset fun as red-series! bin + lexer/scan slot binary/rs-head bin len one? yes no :offset fun as red-series! bin ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - lexer/scan-string slot str len next? yes no :offset fun as red-series! str + lexer/scan-string slot str len one? yes no :offset fun as red-series! str ] - if next? [ + if all [next? all?][ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 bin/head: bin/head + offset slot: as red-value! blk From 02bd16211f7c5a3074b408be6afbbd084607c9a1 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 27 Jan 2020 19:25:21 +0100 Subject: [PATCH 0830/3432] TESTS: preliminary basic tests for TRANSCODE. --- tests/source/units/lexer-test.red | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 871322651c..4d8da0a138 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -11,6 +11,37 @@ Red [ ~~~start-file~~~ "lexer" +===start-group=== "transcode" + + --test-- "tr-1" --assert [123 456 789] == transcode "123 456 789" + --test-- "tr-2" --assert ["world" 111] == transcode {"world" 111} + --test-- "tr-3" --assert [132 [111] ["world" [456 ["hi"]]] 222] == transcode { 132 [111] ["world" [456 ["hi"]]] 222} + --test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} + --test-- "tr-5" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode #{2322722220232261222023225E2F222023225E286C696E6529222023225E2836362922} + --test-- "tr-6" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode {#"r" #"a" #"^^/" #"^^(line)" #"^^(66)"} + --test-- "tr-7" --assert [#r #abcdc /z /abcdef] == transcode {#r #abcdc /z /abcdef} + --test-- "tr-8" --assert [[/a] [#a]] == transcode "[/a] [#a]" + +===end-group=== +===start-group=== "transcode/one" + --test-- "tro-1" --assert 8 == transcode/one "8" + --test-- "tro-2" --assert 123 == transcode/one "123" + --test-- "tro-3" --assert 123 == transcode/one " 123 " + --test-- "tro-4" --assert 8 == transcode/one " ;hello^/ 8" + --test-- "tro-5" --assert 'Hello == transcode/one "Hello" + --test-- "tro-6" --assert 'Hel我lo == transcode/one "Hel我lo" + --test-- "tro-7" --assert "world" == transcode/one {"world"} + --test-- "tro-8" --assert 1.2.3 == transcode/one "1.2.3" + --test-- "tro-10" --assert [1.2.3] == transcode/one " [1.2.3]" + --test-- "tro-11" --assert #"z" == transcode/one {#"z"} + --test-- "tro-12" --assert #"r" == transcode/one {#"r"} + --test-- "tro-13" --assert [#abcde] == transcode/one "[#abcde]" + --test-- "tro-14" --assert "ra^/^(line)^(66)^(10123)" == transcode/one #{2272615E2F5E286C696E65295E283636295E2831303132332922} + --test-- "tro-15" --assert "ra^/^(line)^(66)^(10123)" == transcode/one {"ra^^/^^(line)^^(66)^^(10123)"} + --test-- "tro-16" --assert "ra^/^(line)^(66)^(12)" == transcode/one {"ra^^/^^(line)^^(66)^^(12)"} + --test-- "tro-17" --assert "ra^/^(line)^(66)^(1A3)" == transcode/one {"ra^^/^^(line)^^(66)^^(1A3)"} + +===end-group=== ===start-group=== "transcode/next" --test-- "tn-1" @@ -23,8 +54,6 @@ Red [ ===end-group=== - - ===start-group=== "transcode/trace" logs: make block! 100 From a626027ddeb8fab2d96c81d5af83af48e69170dc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 28 Jan 2020 00:36:19 +0100 Subject: [PATCH 0831/3432] TESTS: additional lexer tests. --- tests/source/units/lexer-test.red | 113 +++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 8 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 4d8da0a138..2b1d21faaf 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -13,18 +13,104 @@ Red [ ===start-group=== "transcode" - --test-- "tr-1" --assert [123 456 789] == transcode "123 456 789" - --test-- "tr-2" --assert ["world" 111] == transcode {"world" 111} - --test-- "tr-3" --assert [132 [111] ["world" [456 ["hi"]]] 222] == transcode { 132 [111] ["world" [456 ["hi"]]] 222} - --test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} - --test-- "tr-5" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode #{2322722220232261222023225E2F222023225E286C696E6529222023225E2836362922} - --test-- "tr-6" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode {#"r" #"a" #"^^/" #"^^(line)" #"^^(66)"} - --test-- "tr-7" --assert [#r #abcdc /z /abcdef] == transcode {#r #abcdc /z /abcdef} - --test-- "tr-8" --assert [[/a] [#a]] == transcode "[/a] [#a]" + --test-- "tr-1" --assert [123 456 789] == transcode "123 456 789" + --test-- "tr-2" --assert ["world" 111] == transcode {"world" 111} + --test-- "tr-3" --assert [132 [111] ["world" [456 ["hi"]]] 222] == transcode { 132 [111] ["world" [456 ["hi"]]] 222} + --test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} + --test-- "tr-5" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode #{2322722220232261222023225E2F222023225E286C696E6529222023225E2836362922} + --test-- "tr-6" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode {#"r" #"a" #"^^/" #"^^(line)" #"^^(66)"} + --test-- "tr-7" --assert [#r #abcdc /z /abcdef] == transcode {#r #abcdc /z /abcdef} + --test-- "tr-8" --assert [[/a] [#a]] == transcode "[/a] [#a]" + --test-- "tr-9" --assert [123 456 789 82] == transcode "123 456 789 ;hello^/ 82" + --test-- "tr-10" --assert [8x5 10x234] == transcode "8x5 10x234 " + --test-- "tr-11" --assert [123 2% 34% 98.765% [456] [789 [8]] 34] == transcode "123 2% 34% 98.765% [456] [789 [;hello^/ 8]] 34" + --test-- "tr-12" --assert [123 (456) (789 (8)) 34] == transcode "123 (456) (789 (;hello^/ 8)) 34" + --test-- "tr-13" --assert [#"q" #"A"] == transcode { #"q" #"A" } + --test-- "tr-14" + out: transcode {a: abc: :a :abc 'a 'abc + #hello + #1abc + [#define] + } + --assert out = [a: abc: :a :abc 'a 'abc + #hello + #1abc + [#define] + ] + nl: reduce [no no no no no no yes yes yes] + forall out [--assert nl/1 = new-line? out nl: next nl] + + --test-- "tr-15" --assert [#"@" #" " #"^/"] == transcode {#"^^@" #"^^(20)" #"^^(line)" } + --test-- "tr-16" + out: transcode { + #{33AA} + #{eaFF} + 2#{01100101} + 2#{0110010100001111} + 2#{ + 01100101 + 00001110 + } + 2#{ ;comment + 01100101 ;ok + 00001111 ;another + } + } + --assert out = [#{33AA} #{EAFF} #{65} #{650F} #{650E} #{650F}] + forall out [--assert new-line? out --assert binary? out/1] + + --test-- "tr-17" + out: transcode { + + + + + <a href="http://www.rebol.com/"> + ;<img src='mypi>c.jpg'> + } + --assert out = [ + <img src="my>pic.jpg"> + <a href="index.html"> + <img src="mypic.jpg" width="150" height="200"> + <title> + <a href="http://www.rebol.com/"> + ;<img src='mypi> c.jpg'> + ] + forall out [--assert tag? out/1] + + --test-- "tr-18" + out: transcode { + http://host.dom/path/file + ftp://host.dom/path/file + nntp://news.some-isp.net/some.news.group + mailto:name@domain + file://host/path/file + finger://user@host.dom + whois://rebol@rs.internic.net + daytime://everest.cclabs.missouri.edu + pop://user:passwd@host.dom/ + tcp://host.dom:21 + dns://host.dom + } + --assert out = [ + http://host.dom/path/file + ftp://host.dom/path/file + nntp://news.some-isp.net/some.news.group + mailto:name@domain + file://host/path/file + finger://user@host.dom + whois://rebol@rs.internic.net + daytime://everest.cclabs.missouri.edu + pop://user:passwd@host.dom/ + tcp://host.dom:21 + dns://host.dom + ] + forall out [--assert url? out/1] ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" + --test-- "tro-1.1" --assert 8 == transcode/one "8 " --test-- "tro-2" --assert 123 == transcode/one "123" --test-- "tro-3" --assert 123 == transcode/one " 123 " --test-- "tro-4" --assert 8 == transcode/one " ;hello^/ 8" @@ -40,6 +126,17 @@ Red [ --test-- "tro-15" --assert "ra^/^(line)^(66)^(10123)" == transcode/one {"ra^^/^^(line)^^(66)^^(10123)"} --test-- "tro-16" --assert "ra^/^(line)^(66)^(12)" == transcode/one {"ra^^/^^(line)^^(66)^^(12)"} --test-- "tro-17" --assert "ra^/^(line)^(66)^(1A3)" == transcode/one {"ra^^/^^(line)^^(66)^^(1A3)"} + --test-- "tro-18" --assert "q^-" == transcode/one {"q^(tab)" } + --test-- "tro-19" --assert "abc {hfdjhjdh" == transcode/one "{abc ^^{hfdjhjdh}" + --test-- "tro-20" --assert #"q" == transcode/one {#"q" } + --test-- "tro-21" --assert 10x234 == transcode/one "10x234" + --test-- "tro-22" --assert (quote a:) == transcode/one {a: } + --test-- "tro-23" --assert #{000041} == transcode/one {64#{AABB}} + --test-- "tro-24" --assert "Hello World!" == to-string transcode/one {64#{SGVsbG8gV29ybGQh}} + --test-- "tro-25" --assert %hello.red == transcode/one {%hello.red} + --test-- "tro-26" --assert %hello%20world.red == transcode/one {%"hello world.red"} + --test-- "tro-27" --assert %hello%20world.red == transcode/one {%hello%20world.red} + --test-- "tro-28" --assert <img src="mypic.jpg"> == transcode/one {<img src="mypic.jpg">} ===end-group=== ===start-group=== "transcode/next" From d98270f638da6e5ad25beb3f3ef4ad9f137dd452 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 28 Jan 2020 17:53:13 +0100 Subject: [PATCH 0832/3432] FEAT: extends path syntax in compiler's lexer to match the runtime lexer. --- lexer.r | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lexer.r b/lexer.r index 393df559ce..02788872b0 100644 --- a/lexer.r +++ b/lexer.r @@ -22,6 +22,7 @@ lexer: context [ pos: none ;-- source input position (error reporting) mark: none ;-- use for keeping input cursor at same position path: none ;-- path input position (error reporting) + in-path?: no ;-- flag for path items s: none ;-- mark start position of new value e: none ;-- mark end position of new value series: none ;-- temporary hold last stack series @@ -107,8 +108,8 @@ lexer: context [ tag-char: charset "<>" caret-char: charset [#"^(40)" - #"^(5F)"] non-printable-char: charset [#"^(00)" - #"^(1F)"] - pair-end: charset {^{"[]();:} - integer-end: charset {^{"[]();:xX<} + pair-end: charset {^{"[]();:/} + integer-end: charset {^{"[]();:xX</} path-end: charset {^{"[]();} file-end: charset {^{[]();} date-sep: charset "/-" @@ -189,6 +190,8 @@ lexer: context [ opt symbol-rule ] + by-value: [paren! string! integer! pair! char! decimal! issue!] + path-rule: [ pos: slash :pos ( ;-- path detection barrier stack/allocate block! 4 @@ -196,19 +199,21 @@ lexer: context [ ) some [ slash - s: [ - integer-number-rule + s: [(in-path?: yes) + integer-rule | begin-symbol-rule (type: word!) | paren-rule (type: paren!) | #":" s: begin-symbol-rule (type: get-word!) - ;@@ add more datatypes here + | line-string (value: load-string s e) + | char-rule (value: decode-UTF8-char value) ] ( - stack/push either type = paren! [ ;-- append path element + stack/push either find by-value to word! type [ ;-- append path element value ][ to type copy/part s e ] type: path! + in-path?: no ) ] opt [#":" (type: set-path!)] @@ -422,7 +427,7 @@ lexer: context [ mark: [pair-end | ws-no-count | end | (type: pair! throw-error)] :mark (value2/2: load-number copy/part s e value: value2) ] - opt [#":" [time-rule | (throw-error)]] + e: opt [#":" [time-rule | (unless in-path? [throw-error]) :e]] ] decimal-special: [ From 17d085fe97e57713d310246ba114e1a48764ce05 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 28 Jan 2020 19:12:43 +0100 Subject: [PATCH 0833/3432] TESTS: additional lexer tests. --- tests/source/units/lexer-test.red | 252 +++++++++++++++++++++++++++++- 1 file changed, 249 insertions(+), 3 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 2b1d21faaf..57e146423d 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -56,7 +56,7 @@ Red [ 00001111 ;another } } - --assert out = [#{33AA} #{EAFF} #{65} #{650F} #{650E} #{650F}] + --assert out == [#{33AA} #{EAFF} #{65} #{650F} #{650E} #{650F}] forall out [--assert new-line? out --assert binary? out/1] --test-- "tr-17" @@ -68,7 +68,7 @@ Red [ <a href="http://www.rebol.com/"> ;<img src='mypi>c.jpg'> } - --assert out = [ + --assert out == [ <img src="my>pic.jpg"> <a href="index.html"> <img src="mypic.jpg" width="150" height="200"> @@ -92,7 +92,7 @@ Red [ tcp://host.dom:21 dns://host.dom } - --assert out = [ + --assert out == [ http://host.dom/path/file ftp://host.dom/path/file nntp://news.some-isp.net/some.news.group @@ -107,6 +107,205 @@ Red [ ] forall out [--assert url? out/1] + --test-- "tr-19" + out: transcode { + %examples.r + %big-image.jpg + %graphics/amiga.jpg + %/c/plug-in/video.r + %//sound/goldfinger.mp3 + %"this file.txt" + %"cool movie clip.mpg" + %this%20file.txt + %cool%20movie%20clip.mpg + %dir/file.txt + %docs/intro.txt + %docs/new/notes.txt + %"new mail/inbox.mbx" + %. + %./ + %./file.txt + %.. + %../ + %../script.r + %../../plans/schedule.r + %/C/docs/file.txt + %"/c/program files/qualcomm/eudora mail/out.mbx" + %//docs/notes + } + --assert out == [ + %examples.r + %big-image.jpg + %graphics/amiga.jpg + %/c/plug-in/video.r + %//sound/goldfinger.mp3 + %this%20file.txt + %cool%20movie%20clip.mpg + %this%20file.txt + %cool%20movie%20clip.mpg + %dir/file.txt + %docs/intro.txt + %docs/new/notes.txt + %new%20mail/inbox.mbx + %. + %./ + %./file.txt + %.. + %../ + %../script.r + %../../plans/schedule.r + %/C/docs/file.txt + %/c/program%20files/qualcomm/eudora%20mail/out.mbx + %//docs/notes + ] + forall out [--assert file? out/1] + + --test-- "tr-20" + --assert (reduce [true false none none]) == transcode {#[true] #[false] #[none] #[none!]} + + --test-- "tr-21" + out: transcode { + 26-jan-2019 + 26-feb-2019 + 26-mar-2019 + 26-apr-2019 + 26-may-2019 + 26-jun-2019 + 26-jul-2019 + 26-aug-2019 + 26-sep-2019 + 26-oct-2019 + 26-nov-2019 + 26-dec-2019 + 26-january-2019 + 26-february-2019 + 26-march-2019 + 26-april-2019 + 26-may-2019 + 26-june-2019 + 26-july-2019 + 26-august-2019 + 26-september-2019 + 26-october-2019 + 26-november-2019 + 26-december-2019 + } + --assert out == [ + 26-Jan-2019 + 26-Feb-2019 + 26-Mar-2019 + 26-Apr-2019 + 26-May-2019 + 26-Jun-2019 + 26-Jul-2019 + 26-Aug-2019 + 26-Sep-2019 + 26-Oct-2019 + 26-Nov-2019 + 26-Dec-2019 + 26-Jan-2019 + 26-Feb-2019 + 26-Mar-2019 + 26-Apr-2019 + 26-May-2019 + 26-Jun-2019 + 26-Jul-2019 + 26-Aug-2019 + 26-Sep-2019 + 26-Oct-2019 + 26-Nov-2019 + 26-Dec-2019 + ] + forall out [--assert date? out/1] + + --test-- "tr-22" + out: transcode { + 1999-10-5 + 1999/10/5 + 5-10-1999 + 5/10/1999 + 5-October-1999 + 1999-9-11 + 11-9-1999 + 5/sep/2012 + 5-SEPTEMBER-2012 + + 02/03/04 + 02/03/71 + + 5/9/2012/6:0 + 5/9/2012/6:00 + 5/9/2012/6:00+8 + 5/9/2012/6:0+0430 + 4/Apr/2000/6:00+8:00 + 1999-10-2/2:00-4:30 + 1/1/1990/12:20:25-6 + + 2017-07-07T08:22:23+00:00 + 2017-07-07T08:22:23Z + 20170707T082223Z + 20170707T0822Z + 20170707T082223+0530 + + 2017-W01 + 2017-W23-5 + 2017-W23-5T10:50Z + 2017-001 + 2017-153T10:50:00-4:00 + } + --assert out == [ + 5-Oct-1999 + 5-Oct-1999 + 5-Oct-1999 + 5-Oct-1999 + 5-Oct-1999 + 11-Sep-1999 + 11-Sep-1999 + 5-Sep-2012 + 5-Sep-2012 + 2-Mar-2004 + 2-Mar-1971 + 5-Sep-2012/6:00:00 + 5-Sep-2012/6:00:00 + 5-Sep-2012/6:00:00+08:00 + 5-Sep-2012/6:00:00+04:30 + 4-Apr-2000/6:00:00+08:00 + 2-Oct-1999/2:00:00-04:30 + 1-Jan-1990/12:20:25-06:00 + 7-Jul-2017/8:22:23 + 7-Jul-2017/8:22:23 + 7-Jul-2017/8:22:23 + 7-Jul-2017/8:22:00 + 7-Jul-2017/8:22:23+05:30 + 2-Jan-2017 + 9-Jun-2017 + 9-Jun-2017/10:50:00 + 1-Jan-2017 + 2-Jun-2017/10:50:00-04:00 + ] + forall out [--assert date? out/1] + + --test-- "tr-23" + out: transcode { + 0:0:3 + 0:0:3.12346 + insert + } + --assert out = [ + 0:00:03 + 0:00:03.12346 + insert + ] + --assert time? out/1 + --assert time? out/2 + --assert word? out/3 + forall out [--assert new-line? out] + + --test-- "tr-24" --assert error? try [transcode "#"] + --test-- "tr-25" --assert error? try [transcode {a: func [][set 'b: 1]}] + --test-- "tr-26" --assert error? try [transcode "1.2..4"] + + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" @@ -138,6 +337,53 @@ Red [ --test-- "tro-27" --assert %hello%20world.red == transcode/one {%hello%20world.red} --test-- "tro-28" --assert <img src="mypic.jpg"> == transcode/one {<img src="mypic.jpg">} + --test-- "tro-29" --assert #{00} == transcode/one "#{00} " + --test-- "tro-30" --assert #{1234} == transcode/one "#{1234} " + --test-- "tro-31" --assert #{FFABCD}== transcode/one "#{FFABCD}" + --test-- "tro-32" --assert #{00112233445566778899AABBCCDDEEFFF01A} == transcode/one "#{00112233445566778899AABBCCDDEEFFF01A}" + --test-- "tro-33" --assert #{CD} == transcode/one "2#{11001101}" + --test-- "tro-34" --assert #{CAFEBABE} == transcode/one "16#{CAFEBABE}" + --test-- "tro-35" --assert #{00004108} == transcode/one "64#{AAB ^/^-^-BCC==}" + --test-- "tro-36" --assert "Hello Nice World!" == to-string transcode/one "64#{SGVsbG8gTmljZSBXb3JsZCE=}" + + --test-- "tro-37" + p: [ + a/b aa/b a/1 a/123 a/123/b a/b/1/d/3 a/(b + 2) a/(b + 2)/c a/(b + 2)/456 + a/"hi" a/"hi"/456 a/2x3 a/2x3/456 a/2x3/c a/1.234 a/1.234/c + a/#"b" a/#"b"/c + ] + forall p [ + --assert p/1 == transcode/one mold p/1 + --assert (to set-path! p/1) == transcode/one mold to set-path! p/1 + --assert (to get-path! p/1) == transcode/one mold to get-path! p/1 + --assert (to lit-path! p/1) == transcode/one mold to lit-path! p/1 + ] + + --test-- "tro-38" --assert 'a/:b/c == transcode/one {a/:b/c} + --test-- "tro-39" --assert 26-Oct-2019 == transcode/one "26/10/2019" + --test-- "tro-40" --assert 26-Oct-2019 == transcode/one "26-10-2019" + --test-- "tro-41" --assert 26-Oct-2019 == transcode/one "2019/10/26" + --test-- "tro-42" --assert 26-Oct-2019 == transcode/one "2019-10-26" + --test-- "tro-43" --assert error? try [transcode/one "2019-10/26"] + --test-- "tro-44" --assert error? try [transcode/one "2019/10-26"] + --test-- "tro-45" --assert error? try [transcode/one "26/10-2019"] + --test-- "tro-46" --assert error? try [transcode/one "26-10/2019"] + + --test-- "tro-47" --assert 26-Oct-2019/13:28:15 == transcode/one "26-October-2019/13:28:15" + --test-- "tro-48" --assert 26-Oct-2019/13:28:15 == transcode/one "2019/10/26/13:28:15" + --test-- "tro-49" --assert 13:28 == transcode/one "13:28" + --test-- "tro-50" --assert 13:28:15 == transcode/one "13:28:15" + --test-- "tro-51" --assert 26-Jan-2019 == transcode/one "26-jan-2019" + --test-- "tro-52" --assert 26-Feb-2019 == transcode/one "26-FEB-2019" + --test-- "tro-53" --assert 26-Dec-2019 == transcode/one "26/December/2019" + --test-- "tro-54" --assert 26-Sep-2019 == transcode/one "2019/Sep/26" + --test-- "tro-55" --assert 2-Oct-1999/2:00:00-04:30 == transcode/one "1999-10-2/2:00-4:30" + + --test-- "tro-56" --assert error? try [transcode/one "#"] + --test-- "tro-57" --assert error? try [transcode/one "1.2..4"] + + ;--test-- "tro-58" --assert {/\^^,[](){}"#%$@:;^/^(70) ^-^M<>} == transcode {{/\^^^^,[](){}"#%$@:;^^/^^(0065)  ^^-^^M<>}} + ===end-group=== ===start-group=== "transcode/next" From b9b5cd0d6ec1f6d11b11f635a51327bfdd9d68a7 Mon Sep 17 00:00:00 2001 From: hiiamboris <hiiamboris@gmail.com> Date: Wed, 29 Jan 2020 00:44:13 +0300 Subject: [PATCH 0834/3432] FEAT: scale hex-to-rgb to full intensity range --- modules/view/utils.red | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/view/utils.red b/modules/view/utils.red index 18662c1919..7b2be337a2 100644 --- a/modules/view/utils.red +++ b/modules/view/utils.red @@ -19,11 +19,7 @@ hex-to-rgb: function [ 3 [ uppercase str forall str [str/1: str/1 - pick "70" str/1 >= #"A"] - - as-color - shift/left to integer! str/1 4 - shift/left to integer! str/2 4 - shift/left to integer! str/3 4 + as-color 11h * str/1 11h * str/2 11h * str/3 ] 6 [if bin: to binary! hex [as-color bin/1 bin/2 bin/3]] 8 [if bin: to binary! hex [as-rgba bin/1 bin/2 bin/3 bin/4]] From ee6051c57d8afe311915d169f7146d2f9f5828f3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 28 Jan 2020 23:31:21 +0100 Subject: [PATCH 0835/3432] TESTS: additional lexer tests. --- tests/source/units/lexer-test.red | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 57e146423d..46747077fd 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -107,6 +107,27 @@ Red [ ] forall out [--assert url? out/1] + --test-- "tr-18.1" + out: transcode { + john@keats.dom + lord@byron.dom + edger@guest.dom + alfred@tennyson.dom + info@rebol.com + 123@number-mail.org + my-name.here@an.example-domain.com + } + --assert out == [ + john@keats.dom + lord@byron.dom + edger@guest.dom + alfred@tennyson.dom + info@rebol.com + 123@number-mail.org + my-name.here@an.example-domain.com + ] + forall out [--assert email? out/1] + --test-- "tr-19" out: transcode { %examples.r @@ -373,6 +394,12 @@ Red [ --test-- "tro-48" --assert 26-Oct-2019/13:28:15 == transcode/one "2019/10/26/13:28:15" --test-- "tro-49" --assert 13:28 == transcode/one "13:28" --test-- "tro-50" --assert 13:28:15 == transcode/one "13:28:15" + --test-- "tro-5A" + out: transcode/one "10:3:01.456" + --assert out/hour = 10 + --assert out/minute = 3 + --assertf~= out/second 1.456 1E-3 + --test-- "tro-51" --assert 26-Jan-2019 == transcode/one "26-jan-2019" --test-- "tro-52" --assert 26-Feb-2019 == transcode/one "26-FEB-2019" --test-- "tro-53" --assert 26-Dec-2019 == transcode/one "26/December/2019" @@ -382,6 +409,17 @@ Red [ --test-- "tro-56" --assert error? try [transcode/one "#"] --test-- "tro-57" --assert error? try [transcode/one "1.2..4"] + --test-- "tro-58" --assert (quote (b + 2)) == transcode/one"(b + 2)" + --test-- "tro-59" --assert #() == transcode/one {#()} + --test-- "tro-60" --assert #(a: 2) == transcode/one {#(a: 2)} + --test-- "tro-61" --assert #("b" 2.345) == transcode/one {#("b" 2.345)} + --test-- "tro-62" --assert "hel^/lo" == transcode/one {"hel^^/lo"} + --test-- "tro-63" --assert "{^/}" == transcode/one {{{^/}}} + --test-- "tro-64" --assert 1 == transcode/one "01h" + --test-- "tro-65" --assert 2147483647 == transcode/one "7FFFFFFFh" + --test-- "tro-66" --assert -1 == transcode/one "FFFFFFFFh" + + ;--test-- "tro-58" --assert {/\^^,[](){}"#%$@:;^/^(70) ^-^M<>} == transcode {{/\^^^^,[](){}"#%$@:;^^/^^(0065)  ^^-^^M<>}} ===end-group=== From 229dc498b9ade73ee7392e7d0393498fded2eee2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 29 Jan 2020 17:29:38 +0100 Subject: [PATCH 0836/3432] TESTS: adds one extra lexer test. --- tests/source/units/lexer-test.red | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 46747077fd..b7c5f1fe0d 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -326,6 +326,11 @@ Red [ --test-- "tr-25" --assert error? try [transcode {a: func [][set 'b: 1]}] --test-- "tr-26" --assert error? try [transcode "1.2..4"] + --test-- "tr-27" + out: transcode { + --assert 0:00:15.0 == (10:00.0 % 0:45.0) + } + --assert out == [--assert 0:00:15.0 == (10:00.0 % 0:45.0)] ===end-group=== ===start-group=== "transcode/one" @@ -420,7 +425,6 @@ Red [ --test-- "tro-66" --assert -1 == transcode/one "FFFFFFFFh" - ;--test-- "tro-58" --assert {/\^^,[](){}"#%$@:;^/^(70) ^-^M<>} == transcode {{/\^^^^,[](){}"#%$@:;^^/^^(0065)  ^^-^^M<>}} ===end-group=== ===start-group=== "transcode/next" From d24b3beb6935bdc19909d6ddf210f46f95c0cac6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 29 Jan 2020 17:40:19 +0100 Subject: [PATCH 0837/3432] FIX: tag! scanning not accurate. Removes Red-style quote and double-quote escaping. Fixes a scanning issue with single quoted attribute values. --- docs/lexer/lexer-FSM.csv | 8 +- docs/lexer/lexer-FSM.xlsx | Bin 22306 -> 22094 bytes docs/lexer/lexer-states.txt | 18 ++--- runtime/lexer-transitions.reds | 139 ++++++++++++++++----------------- runtime/lexer.reds | 2 +- utils/generate-lexer-table.red | 98 ++++++++++++----------- 6 files changed, 126 insertions(+), 139 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 2d72cf48a1..df2135d945 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -35,11 +35,9 @@ S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MO S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD -S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR -S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_SKIP_STR2;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_SKIP_STR2;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR -S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SKIP_STR3;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR +S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR +S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR +S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index f020636fefaf9569adf27ddb6fd2f08b34c47802..796db7bbe623939cae1c1333227c25afcfc1f03d 100644 GIT binary patch delta 11326 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 QqdNRpkL3!R*5&R04@ykhp#T5? delta 11569 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 65f2a244d2..968f17a6a5 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -40,9 +40,7 @@ S_HEX_END S_LESSER S_TAG S_TAG_STR -S_SKIP_STR2 S_TAG_STR2 -S_SKIP_STR3 S_SIGN S_DOTWORD S_DOTDEC @@ -273,15 +271,13 @@ S_START->"<"->S_LESSER \->">"|"<"|"="->S_WORD \->else->S_TAG \->dbl-quote->S_TAG_STR->not("^"|dbl-quote)->S_TAG_STR - \ \->"^"->S_SKIP_STR2->*->S_TAG_STR - \ \->dbl-quote->S_TAG - \ - \->"'"->S_TAG_STR2->not("^"|"'")->S_TAG_STR2 - \ \->"^"->S_SKIP_STR3->*->S_TAG_STR2 - \ \->"'"->S_TAG - \ - \->">"->T_TAG - \->else->S_TAG + \ \->dbl-quote->S_TAG + \ + \->"'"->S_TAG_STR2->not("^"|"'")->S_TAG_STR2 + \ \->"'"->S_TAG + \ + \->">"->T_TAG + \->else->S_TAG S_START->"+"|"-"->S_SIGN->digit->S_NUMBER diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 957740688f..adb3804e74 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -40,9 +40,7 @@ Red/System [ S_LESSER S_TAG S_TAG_STR - S_SKIP_STR2 S_TAG_STR2 - S_SKIP_STR3 S_SIGN S_DOTWORD S_DOTDEC @@ -93,76 +91,73 @@ Red/System [ ] type-table: #{ 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 -330B0F2C2C2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 -000000000B0000140708290A260C0C272F252B332C092D0B +330B0F2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000000000000000070000 +00000B0000140708290A260C0C272F252B332C092D0B } transitions: #{ -000013133A3B3C3D3E39020C2C2C2D2D2D2D212D210B39232D2D063901392A1E -2929392D2D393801430101010101010101010101010101010101010101010101 -0101010101010101010101013938020202020202020202024802020202020202 -0202020202020202020202020202020203020239390202020202020202020202 -0202020202020202020202020202020202020202020202020202393804040404 -040404043E3F0404040404040404040404040404040404040404040404040504 -0439390404040404040404040404040404040404040404040404040404040404 -04040404040404043938454507074545454545450A0707450707070707070707 -0707070707074545070707070707073945494907074949494949493907074907 -0707070707070707070707080749490707070707070739490707090939393939 -3939393939393939390909090939393939393939393939393939393939393907 -0707073939393939393939393939393909090707393939393939393939393939 -3939393939490A0A0A0A0A0A0A0A0A0A490A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A393946460B0B464646464646460B0B0B0B0B0B0B0B -0B0B2D0B0B0B0B0B0B46460B0B0B0B0B0B0B394647471212113940390D390F12 -1239121212121212121212393939123947471212121212121239470D0D0D0D39 -393939394A393939390D0D0D0D0D0D0D0D3939390D39390E3939390D3939390D -39390E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E39380F0F0F0F0F0F0F0F0F0F4B0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F394B0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3939111111111142111111 -1111111111111111111111111111111111111111111111111111111139394747 -1212474747474747471212121212121212121212121212121212474712121212 -121212394744441313444444444444440C131A1C19571516392119394439394C -1444301439391939393939444D4D15154D4D4D4D4D4D4D1715391C3939151539 -394D394D39394C394D3939393939393939394D4D4D15154D4D4D4D4D4D4D3939 -4D393939151539394D394D39394C39393018391515393939394D4D4D16164D4D -4D4D4D4D4D39394D393957152139214D394D39394C3939301839151539393939 -4D4D4D4D4E4E4E4E4E4E4E4E174E4E171717171717174E4E4E17174E4E4E4E17 -4E17174E1717394E4F4F18184F4F4F4F4F4F4F39394F393939393939394F394F -39393939393918393939393939394F5050191950505050505050191919191919 -1919191919195019195019505019501919503919395039391B1B393939393939 -393939393939393939393939393939393939393939393939393939393952521B -1B5252525252525239391B393939393939395239523939393952391B39393939 -3939395239391D1D393939393939393939393939393939393939393939393939 -393039391D1D393939393951511D1D515151515151513939513939391D1D3939 -5139513939393951301D393939393939395139391F1F39393939393939393939 -3939393939393939393939393939393939393939393939393953531F1F535353 -53535353531F5339393939393939533953393939395339203939393939393938 -5353202053535353535353532053393939393939395339533939393953393939 -393939393939384545212145454545454545392D2E2D2D222D212D2141452D2D -2D393945302D1F2D2D2D2D2D394557572D2D57575757575757392D2E2D2D2D2D -2D2D2D41572D2D2D393957302D1F2D2D2D2D2D39574545242445454545454545 -2424452424242424242424242D2D2D2424454524242424242424394524242424 -2424242424242524242724242424242424242424542424242424242424242424 -2439392525252525252525252524252525252525252525252525252525252525 -2525252525262525393925252525252525252525252525252525252525252525 -2525252525252525252525252525253939272727272727272727272727272427 -2727272727272727272727272727272727272727272739392727272727272727 -2727272727272727272727272727272727272727272727272727272727393945 -4513134545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D -2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D -393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1C39392B2B -39394D394D39394C39393939392B2B393939394D393939393939393939393939 -39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45 -454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D1F2D2D2D2D2D -394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F -2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55 -55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030 -30303030305656563939303956393039303039303039563939323239393C3D39 -3902353333343434343434343939233434393939303439363639343439394444 -3232444444444444443913441C39391515393944394439394C14443014393939 -3939393944393939393939393939393939393934343434343434393934343439 -3939393439343439343439394545343445454545454545393445343434343434 -34454534343439394530343934343434343945474712121139393939390F1212 -3912121212121212121239393912394747121212121212123947454532324545 -454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39 -45 +0000131338393A3B3C37020C2A2A2B2B2B2B212B210B37232B2B06370137281E +2727372B2B373601410101010101010101010101010101010101010101010101 +0101010101010101010101013736020202020202020202024602020202020202 +0202020202020202020202020202020203020237370202020202020202020202 +0202020202020202020202020202020202020202020202020202373604040404 +040404043C3D0404040404040404040404040404040404040404040404040504 +0437370404040404040404040404040404040404040404040404040404040404 +04040404040404043736434307074343434343430A0707430707070707070707 +0707070707074343070707070707073743474707074747474747473707074707 +0707070707070707070707080747470707070707070737470707090937373737 +3737373737373737370909090937373737373737373737373737373737373707 +0707073737373737373737373737373709090707373737373737373737373737 +3737373737470A0A0A0A0A0A0A0A0A0A470A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A373744440B0B444444444444440B0B0B0B0B0B0B0B +0B0B2B0B0B0B0B0B0B44440B0B0B0B0B0B0B37444545121211373E370D370F12 +1237121212121212121212373737123745451212121212121237450D0D0D0D37 +3737373748373737370D0D0D0D0D0D0D0D3737370D37370E3737370D3737370D +37370E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E37360F0F0F0F0F0F0F0F0F0F490F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F37490F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3737111111111140111111 +1111111111111111111111111111111111111111111111111111111137374545 +1212454545454545451212121212121212121212121212121212454512121212 +121212374542421313424242424242420C131A1C19551516372119374237374A +14422E1437371937373737424B4B15154B4B4B4B4B4B4B1715371C3737151537 +374B374B37374A374B3737373737373737374B4B4B15154B4B4B4B4B4B4B3737 +4B373737151537374B374B37374A37372E18371515373737374B4B4B16164B4B +4B4B4B4B4B37374B373755152137214B374B37374A37372E1837151537373737 +4B4B4B4B4C4C4C4C4C4C4C4C174C4C171717171717174C4C4C17174C4C4C4C17 +4C17174C1717374C4D4D18184D4D4D4D4D4D4D37374D373737373737374D374D +37373737373718373737373737374D4E4E19194E4E4E4E4E4E4E191919191919 +1919191919194E19194E194E4E194E19194E3719374E37371B1B373737373737 +373737373737373737373737373737373737373737373737373737373750501B +1B5050505050505037371B373737373737375037503737373750371B37373737 +3737375037371D1D373737373737373737373737373737373737373737373737 +372E37371D1D37373737374F4F1D1D4F4F4F4F4F4F4F37374F3737371D1D3737 +4F374F373737374F2E1D373737373737374F37371F1F37373737373737373737 +3737373737373737373737373737373737373737373737373751511F1F515151 +51515151511F5137373737373737513751373737375137203737373737373736 +5151202051515151515151512051373737373737375137513737373751373737 +373737373737364343212143434343434343372B2C2B2B222B212B213F432B2B +2B3737432E2B1F2B2B2B2B2B374355552B2B55555555555555372B2C2B2B2B2B +2B2B2B3F552B2B2B3737552E2B1F2B2B2B2B2B37554343242443434343434343 +2424432424242424242424242B2B2B2424434324242424242424374324242424 +2424242424242524262424242424242424242424522424242424242424242424 +2437372525252525252525252524252525252525252525252525252525252525 +2525252525252525373726262626262626262626262624262626262626262626 +2626262626262626262626262626263737434313134343434343434337372B2B +2B2B2B2B2B2B2B43372B2B372B432B282B2B2B372B2B37434343292943434343 +434343372B2C2B2B2B29292B2B3F432B2B2B3737432E2B3729292B2B2B37434B +4B29294B4B4B4B4B4B4B37374B1C3737292937374B374B37374A373737373729 +29373737374B37373737373737373737373737372B2B2B2B2B2B2B0B372B2B2B +373737372B372B2B372B2B373743432B2B43434343434343372B2C2B2B2B2B2B +2B2B3F432B2B2B3737432E2B1F2B2B2B2B2B374343432D2D434343434343432D +2D2D2D2D2D2D2D2D2D2D43372D2D2D2D432D2D2D2D2D2D2D2D374353532D2D53 +5353535353532D372D2D2D2D2D2D2D2D2D5353372D2D53532D2D372D2D372D2D +375354542E2E545454545454543737372E2E2E2E2E2E2E54545437372E375437 +2E372E2E372E2E37543737303037373A3B373702333131323232323232323737 +2332323737372E32373434373232373742423030424242424242423713421C37 +371515373742374237374A14422E143737373737373742373737373737373737 +3737373737323232323232323737323232373737373237323237323237374343 +3232434343434343433732433232323232323243433232323737432E32373232 +3232323743454512121137373737370F12123712121212121212121237373712 +374545121212121212123745434330304343434343434337372B2B2B2B2B2B2B +2B2B43372B2B372B432B2B2B2B2B372B2B3743 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 0bde8840e1..d6fd1e8413 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -107,7 +107,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000 } path-ending: #{ diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 13801cb2df..1aff5087e2 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -51,56 +51,54 @@ context [ S_LESSER TYPE_TAG ;-- 35 S_TAG TYPE_TAG ;-- 36 S_TAG_STR TYPE_TAG ;-- 37 - S_SKIP_STR2 TYPE_TAG ;-- 38 - S_TAG_STR2 TYPE_TAG ;-- 39 - S_SKIP_STR3 TYPE_TAG ;-- 40 - S_SIGN TYPE_WORD ;-- 41 - S_DOTWORD TYPE_WORD ;-- 42 - S_DOTDEC TYPE_FLOAT ;-- 43 - S_WORD_1ST TYPE_WORD ;-- 44 - S_WORD TYPE_WORD ;-- 45 - S_WORDSET TYPE_SET_WORD ;-- 46 - S_URL TYPE_URL ;-- 47 - S_EMAIL TYPE_EMAIL ;-- 48 - S_PATH TYPE_PATH ;-- 49 - S_PATH_NUM TYPE_INTEGER ;-- 50 - S_PATH_W1ST TYPE_WORD ;-- 51 - S_PATH_WORD TYPE_WORD ;-- 52 - S_PATH_SHARP TYPE_ISSUE ;-- 53 - S_PATH_SIGN TYPE_WORD ;-- 54 - --EXIT_STATES-- - ;-- 55 - T_EOF - ;-- 56 - T_ERROR - ;-- 57 - T_BLK_OP - ;-- 58 - T_BLK_CL - ;-- 59 - T_PAR_OP - ;-- 60 - T_PAR_CL - ;-- 61 - T_MSTR_OP - ;-- 62 - T_MSTR_CL TYPE_STRING ;-- 63 - T_MAP_OP - ;-- 64 - T_PATH - ;-- 65 - T_CONS_MK - ;-- 66 - T_CMT - ;-- 67 - T_INTEGER TYPE_INTEGER ;-- 68 - T_WORD - ;-- 69 - T_REFINE - ;-- 70 - T_ISSUE TYPE_ISSUE ;-- 71 - T_STRING TYPE_STRING ;-- 72 - T_FILE TYPE_FILE ;-- 73 - T_BINARY TYPE_BINARY ;-- 74 - T_CHAR TYPE_CHAR ;-- 75 - T_PERCENT TYPE_PERCENT ;-- 76 - T_FLOAT TYPE_FLOAT ;-- 77 - T_FLOAT_SP TYPE_FLOAT ;-- 78 - T_TUPLE TYPE_TUPLE ;-- 79 - T_DATE TYPE_DATE ;-- 80 - T_PAIR TYPE_PAIR ;-- 81 - T_TIME TYPE_TIME ;-- 82 - T_MONEY TYPE_MONEY ;-- 83 - T_TAG TYPE_TAG ;-- 84 - T_URL TYPE_URL ;-- 85 - T_EMAIL TYPE_EMAIL ;-- 86 - T_HEX TYPE_INTEGER ;-- 87 + S_TAG_STR2 TYPE_TAG ;-- 38 + S_SIGN TYPE_WORD ;-- 39 + S_DOTWORD TYPE_WORD ;-- 40 + S_DOTDEC TYPE_FLOAT ;-- 41 + S_WORD_1ST TYPE_WORD ;-- 42 + S_WORD TYPE_WORD ;-- 43 + S_WORDSET TYPE_SET_WORD ;-- 44 + S_URL TYPE_URL ;-- 45 + S_EMAIL TYPE_EMAIL ;-- 46 + S_PATH TYPE_PATH ;-- 47 + S_PATH_NUM TYPE_INTEGER ;-- 48 + S_PATH_W1ST TYPE_WORD ;-- 49 + S_PATH_WORD TYPE_WORD ;-- 50 + S_PATH_SHARP TYPE_ISSUE ;-- 51 + S_PATH_SIGN TYPE_WORD ;-- 52 + --EXIT_STATES-- - ;-- 53 + T_EOF - ;-- 54 + T_ERROR - ;-- 55 + T_BLK_OP - ;-- 56 + T_BLK_CL - ;-- 57 + T_PAR_OP - ;-- 58 + T_PAR_CL - ;-- 59 + T_MSTR_OP - ;-- 60 + T_MSTR_CL TYPE_STRING ;-- 61 + T_MAP_OP - ;-- 62 + T_PATH - ;-- 63 + T_CONS_MK - ;-- 64 + T_CMT - ;-- 65 + T_INTEGER TYPE_INTEGER ;-- 66 + T_WORD - ;-- 67 + T_REFINE - ;-- 68 + T_ISSUE TYPE_ISSUE ;-- 69 + T_STRING TYPE_STRING ;-- 70 + T_FILE TYPE_FILE ;-- 71 + T_BINARY TYPE_BINARY ;-- 72 + T_CHAR TYPE_CHAR ;-- 73 + T_PERCENT TYPE_PERCENT ;-- 74 + T_FLOAT TYPE_FLOAT ;-- 75 + T_FLOAT_SP TYPE_FLOAT ;-- 76 + T_TUPLE TYPE_TUPLE ;-- 77 + T_DATE TYPE_DATE ;-- 78 + T_PAIR TYPE_PAIR ;-- 79 + T_TIME TYPE_TIME ;-- 80 + T_MONEY TYPE_MONEY ;-- 81 + T_TAG TYPE_TAG ;-- 82 + T_URL TYPE_URL ;-- 83 + T_EMAIL TYPE_EMAIL ;-- 84 + T_HEX TYPE_INTEGER ;-- 85 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 3034f1dc46ec074e81492e3323e768d586d8be85 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 29 Jan 2020 19:11:53 +0100 Subject: [PATCH 0838/3432] FEAT: simplifies and optimizes base-16 binary decoding. --- docs/lexer/lexer-states.txt | 32 +++-------------- runtime/lexer.reds | 65 +++++++++++++--------------------- utils/generate-misc-tables.red | 12 +++---- 3 files changed, 35 insertions(+), 74 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 968f17a6a5..619745ca4b 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -369,33 +369,11 @@ S_PATH->not(delimit6)->S_PATH_WORD->not(delimit5)->S_PATH_WORD \->","|"#"|"%"->T_ERROR -=== Binary16 FSM === +=== Binary16 classes === +C_BIN_ILLEGAL : all the rest ;-- 0 +C_BIN_BLANK : space, tab, cr, lf ;-- 1 +C_BIN_HEXA : 0-9, a-f, A-F ;-- 2 +C_BIN_CMT : ; ;-- 3 -S_BIN_START ;-- 0 -S_BIN_1ST ;-- 1 -S_BIN_CMT ;-- 2 -S_BIN_FINAL_STATES ;-- 3 -T_BIN_BYTE ;-- 4 -T_BIN_ERROR ;-- 5 - - -C_BIN_SKIP : all the rest ;-- 0 -C_BIN_BLANK : space, tab, cr ;-- 1 -C_BIN_LINE : lf ;-- 2 -C_BIN_HEXA : 0-9, a-f, A-F ;-- 3 -C_BIN_CMT : ; ;-- 4 - - -hexa: 0-9, a-f, A-F -blank: space, tab, cr - - -S_BIN_START->hexa->S_BIN_1ST->hexa->T_BIN_BYTE - \ \->not(hexa)->T_BIN_ERROR - \ - \->blank->S_BIN_START - \ - \->;->S_BIN_CMT->lf->S_BIN_START - \->not(lf)->S_BIN_CMT \ No newline at end of file diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d6fd1e8413..a0fc03aa53 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -85,20 +85,10 @@ lexer: context [ #enum bin16-char-classes! [ C_BIN_ILLEGAL ;-- 0 C_BIN_BLANK ;-- 1 - C_BIN_LINE ;-- 2 - C_BIN_HEXA ;-- 3 - C_BIN_CMT ;-- 4 + C_BIN_HEXA ;-- 2 + C_BIN_CMT ;-- 3 ] - - #enum bin16-states! [ - S_BIN_START ;-- 0 - S_BIN_1ST ;-- 1 - S_BIN_CMT ;-- 2 - S_BIN_FINAL_STATES ;-- 3 - T_BIN_BYTE ;-- 4 - T_BIN_ERROR ;-- 5 - ] - + line-table: #{ 0001000000000000000000000000000000000000000000000000000000000000 0000000000000000 @@ -116,22 +106,16 @@ lexer: context [ } bin16-classes: #{ - 0000000000000000000102000001000000000000000000000000000000000000 - 0100000000000000000000000000000003030303030303030303000400000000 - 0003030303030300000000000000000000000000000000000000000000000000 - 0003030303030300000000000000000000000000000000000000000000000000 + 0000000000000000000101000001000000000000000000000000000000000000 + 0100000000000000000000000000000002020202020202020202000300000000 + 0002020202020200000000000000000000000000000000000000000000000000 + 0002020202020200000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 } - bin16-FSM: #{ - 0500000102 - 0505050405 - 0202000202 - } - hexa-table: #{ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00010203040506070809FFFFFFFFFFFF @@ -595,27 +579,28 @@ lexer: context [ decode-16: func [s e [byte-ptr!] ser [series!] return: [byte-ptr!] ;-- null: ok, not null: error position /local - p pos [byte-ptr!] - c index class fstate [integer!] + p [byte-ptr!] + c index class b1 [integer!] ][ p: as byte-ptr! ser/offset + b1: -1 while [s < e][ - fstate: S_BIN_START - pos: s - until [ ;-- scans 2 hex characters, skip the rest - index: 1 + as-integer s/1 - class: as-integer bin16-classes/index - s: s + 1 - index: fstate * 5 + class + 1 - fstate: as-integer bin16-FSM/index - any [fstate - S_BIN_FINAL_STATES > 0 s >= e] + index: 1 + as-integer s/1 + class: as-integer bin16-classes/index + switch class [ + C_BIN_HEXA [ + either b1 < 0 [b1: index][ + c: as-integer hexa-table/b1 + p/value: as byte! c << 4 or as-integer hexa-table/index + p: p + 1 + b1: -1 + ] + ] + C_BIN_CMT [until [s: s + 1 any [s/1 = lf s = e]]] + C_BIN_ILLEGAL [return s] + default [0] ] - if fstate = T_BIN_ERROR [return s - 1] - index: 1 + as-integer pos/1 ;-- converts the 2 hex chars using tables - c: as-integer hexa-table/index - index: 1 + as-integer pos/2 - p/value: as byte! c << 4 or as-integer hexa-table/index - p: p + 1 + s: s + 1 ] ser/tail: as cell! p null diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index cb4fdbd4c2..aef141b22d 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -25,23 +25,21 @@ gen-bitarray: function [list][ bin-classes: [ C_BIN_ILLEGAL ;-- 0 C_BIN_BLANK ;-- 1 - C_BIN_LINE ;-- 2 - C_BIN_HEXA ;-- 3 - C_BIN_COMMENT ;-- 4 + C_BIN_HEXA ;-- 2 + C_BIN_COMMENT ;-- 3 ] gen-bin16-table: function [][ out: make binary! 256 - blank: charset "^-^M " + blank: charset "^-^/^M " hexa: charset [#"A" - #"F" #"a" - #"f" #"0" - #"9"] repeat i 256 [ c: to-char i - 1 append out to-char case [ find blank c [1] - c = #"^/" [2] - find hexa c [3] - c = #";" [4] + find hexa c [2] + c = #";" [3] 'else [0] ] ] From 6f5f6b4550630d53fe33bb978b364f21924f11b3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 29 Jan 2020 19:13:46 +0100 Subject: [PATCH 0839/3432] FEAT: removes the bin16 FSM table. Missing change from last commit. --- docs/lexer/lexer-FSM.xlsx | Bin 22094 -> 19893 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 796db7bbe623939cae1c1333227c25afcfc1f03d..e1d1b6bf4622e85bef66ee4ccd9559e6acedeb08 100644 GIT binary patch delta 13225 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 A-v9sr delta 15249 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 b?Qb7D6;QO&eS8AMs3I{M5)za8?Qj1FNU_rC From d66fc1a4eb6b28e2d160ae1e94c7df623caa5a4b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 00:43:30 +0100 Subject: [PATCH 0840/3432] FEAT: adds /scan refinement to TRANSCODE. Switches the lexer to scan-mode only, no value loading occurs. Returns the type of the first scanned value, and stops there. --- environment/natives.red | 1 + runtime/lexer.reds | 17 +++++++++-------- runtime/natives.reds | 26 +++++++++++++++++--------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index 68d5ba0fd5..2089faa594 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -913,6 +913,7 @@ transcode: make native! [[ src [binary! string!] "UTF-8 input buffer; string argument will be UTF-8 encoded" /next "Translate next complete value (blocks as single value)" /one "Translate next complete value, returns the value only" + /scan "Scans only, do not load values. Returns recognized type." /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" /into "Optionally provides an output block" diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a0fc03aa53..76ccb400b3 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1880,14 +1880,15 @@ lexer: context [ ] scan-string: func [ - dst [red-value!] ;-- destination slot - str [red-string!] - size [integer!] - one? [logic!] - load? [logic!] - wrap? [logic!] - len [int-ptr!] - fun [red-function!] ;-- optional callback function + dst [red-value!] ;-- destination slot + str [red-string!] + size [integer!] + one? [logic!] + load? [logic!] + wrap? [logic!] + len [int-ptr!] + fun [red-function!] ;-- optional callback function + return: [integer!] ;-- scanned type when one? is set, else zero /local s [series!] unit buf-size ignore [integer!] diff --git a/runtime/natives.reds b/runtime/natives.reds index beca3bf15a..0fcdf48632 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2728,26 +2728,29 @@ natives: context [ check? [logic!] next [integer!] one [integer!] + scan [integer!] part [integer!] into [integer!] trace [integer!] /local offset len type [integer!] - next? one? all? [logic!] + next? one? all? load? [logic!] slot arg [red-value!] bin bin2 [red-binary!] int [red-integer!] str [red-string!] blk [red-block!] + dt [red-datatype!] fun [red-function!] s [series!] ][ - #typecheck [transcode next one part into trace] + #typecheck [transcode next one scan part into trace] - all?: one = -1 - next?: next > -1 + load?: scan < 0 + all?: all [one < 0 load?] + next?: next >= 0 slot: stack/push* - if all [next? all?][ + if all [next? any [one < 0 not load?]][ blk: block/preallocate as red-block! slot 2 no s: GET_BUFFER(blk) s/tail: s/offset + 2 @@ -2780,16 +2783,21 @@ natives: context [ ] if len < 0 [len: 0] ] - one?: any [next? not all?] + one?: any [next? not all? not load?] either type = TYPE_BINARY [ if len < 0 [len: binary/rs-length? bin] - lexer/scan slot binary/rs-head bin len one? yes no :offset fun as red-series! bin + type: lexer/scan slot binary/rs-head bin len one? load? no :offset fun as red-series! bin ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - lexer/scan-string slot str len one? yes no :offset fun as red-series! str + type: lexer/scan-string slot str len one? load? no :offset fun as red-series! str + ] + unless load? [ + dt: as red-datatype! slot + dt/header: TYPE_DATATYPE + dt/value: type ] - if all [next? all?][ + if all [next? any [one < 0 not load?]][ bin: as red-binary! copy-cell as red-value! bin s/offset + 1 bin/head: bin/head + offset slot: as red-value! blk From 3e7d268ed782b37097cb363c88ebca14c565c90d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 00:51:04 +0100 Subject: [PATCH 0841/3432] FEAT: adds SCAN function, for scanning serialized values without loading. Returns the guessed type of the first value in the input buffer. --- environment/functions.red | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/environment/functions.red b/environment/functions.red index 4f69286bae..84949764bb 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -365,6 +365,15 @@ suffix?: function [ ][to file! path] ] +scan: func [ + "Returns the guessed type of the first serialized value from the input" + buffer [binary! string!] "Input UTF-8 buffer or string" + /next "Returns both the type and the input after the value" + return: [datatype!] "Guessed type" +][ + either next [transcode/next/scan buffer][transcode/scan buffer] +] + load: function [ "Returns a value or block of values by reading and evaluating a source" source [file! url! string! binary!] From 6991283d4d90ff7a119873748cb490dad150691a Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 30 Jan 2020 17:18:28 +0800 Subject: [PATCH 0842/3432] FIX: issue #4253 ([View] Base started feeding on text) --- modules/view/backends/windows/base.reds | 1731 +++++++++++------------ 1 file changed, 865 insertions(+), 866 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 2676b05a28..1419047060 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -1,866 +1,865 @@ -Red/System [ - Title: "Windows layered window widget" - Author: "Xie Qingtian" - File: %base.reds - Tabs: 4 - Rights: "Copyright (C) 2015 Xie Qingtian. All rights reserved." - License: { - Distributed under the Boost Software License, Version 1.0. - See https://github.com/red/red/blob/master/BSL-License.txt - } -] - -init-base-face: func [ - handle [handle!] - parent [integer!] - values [red-value!] - alpha? [logic!] - /local - pt [tagPOINT value] - offset [red-pair!] - size [red-pair!] - show? [red-logic!] - opts [red-block!] - word [red-word!] - len [integer!] - sym [integer!] - flags [integer!] -][ - offset: as red-pair! values + FACE_OBJ_OFFSET - size: as red-pair! values + FACE_OBJ_SIZE - show?: as red-logic! values + FACE_OBJ_VISIBLE? - opts: as red-block! values + FACE_OBJ_OPTIONS - - SetWindowLong handle wc-offset - 4 0 - SetWindowLong handle wc-offset - 12 0 - SetWindowLong handle wc-offset - 16 parent - SetWindowLong handle wc-offset - 20 0 - SetWindowLong handle wc-offset - 24 0 - pt/x: dpi-scale offset/x - pt/y: dpi-scale offset/y - either alpha? [ - unless win8+? [ - position-base handle as handle! parent :pt - ] - update-base handle as handle! parent :pt values - if all [show?/value IsWindowVisible as handle! parent][ - ShowWindow handle SW_SHOWNA - ] - unless win8+? [ - process-layered-region handle size offset null offset null yes - ] - ][ - SetWindowLong handle wc-offset - 8 WIN32_MAKE_LPARAM(pt/x pt/y) - ] - - if TYPE_OF(opts) = TYPE_BLOCK [ - word: as red-word! block/rs-head opts - len: block/rs-length? opts - if len % 2 <> 0 [exit] - flags: GetWindowLong handle wc-offset - 12 - while [len > 0][ - sym: symbol/resolve word/symbol - case [ - sym = caret [ - SetWindowLong handle wc-offset - 12 flags or BASE_FACE_CARET - SetWindowLong handle wc-offset - 24 as-integer get-face-handle as red-object! word + 1 - update-caret handle values - ] - true [0] - ] - word: word + 2 - len: len - 2 - ] - ] -] - -position-base: func [ - base [handle!] - parent [handle!] - pt [tagPOINT] -][ - ClientToScreen parent pt ;-- convert client offset to screen offset - SetWindowLong base wc-offset - 8 WIN32_MAKE_LPARAM(pt/x pt/y) -] - -layered-win?: func [ - hWnd [handle!] - return: [logic!] -][ - (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) <> 0 -] - -detached?: func [ - hWnd [handle!] - return: [logic!] -][ - (GetWindowLong hWnd GWL_STYLE) and WS_CHILD = 0 -] - -render-base: func [ - hWnd [handle!] - hDC [handle!] - return: [logic!] - /local - values [red-value!] - img [red-image!] - w [red-word!] - rc [RECT_STRUCT value] - graphic [integer!] - type [integer!] - res [logic!] -][ - graphic: 0 - res: paint-background hWnd hDC - - values: get-face-values hWnd - w: as red-word! values + FACE_OBJ_TYPE - img: as red-image! values + FACE_OBJ_IMAGE - - GetClientRect hWnd :rc - if TYPE_OF(img) = TYPE_IMAGE [ - GdipCreateFromHDC hDC :graphic - if zero? GdipDrawImageRectI - graphic - as-integer img/node - 0 0 - rc/right - rc/left rc/bottom - rc/top [res: true] - GdipDeleteGraphics graphic - ] - - type: symbol/resolve w/symbol - if all [ - type = base - render-text values hWnd hDC :rc null null - ][ - res: true - ] - res -] - -render-text: func [ - values [red-value!] - hWnd [handle!] - hDC [handle!] - rc [RECT_STRUCT] - text [red-string!] - bbox [RECT_STRUCT_FLOAT32] ; renders if = null, measures otherwise - return: [logic!] - /local - font [red-object!] - para [red-object!] - res [logic!] - graphic [integer!] -][ - ;unless winxp? [return render-text-d2d values hDC rc] - res: false - if text = null [text: as red-string! values + FACE_OBJ_TEXT] - para: as red-object! values + FACE_OBJ_PARA - if TYPE_OF(text) = TYPE_STRING [ - font: as red-object! values + FACE_OBJ_FONT - graphic: 0 - GdipCreateFromHDC hDC :graphic - ; GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS - ; using GDI+ text rendering instead of GDI, see #2503 and #3465 - update-base-text hWnd graphic hDC text font para rc/right - rc/left rc/bottom - rc/top bbox - GdipDeleteGraphics graphic - res: true - ] - res -] - -clip-layered-window: func [ - hWnd [handle!] - size [tagSIZE] - x [integer!] - y [integer!] - new-width [integer!] - new-height [integer!] - /local - rgn [handle!] - child [handle!] - flags [integer!] -][ - flags: GetWindowLong hWnd wc-offset - 12 - if any [ - not zero? x - not zero? y - size/width <> new-width - size/height <> new-height - BASE_FACE_CLIPPED and flags <> 0 - ][ - SetWindowLong hWnd wc-offset - 12 flags or BASE_FACE_CLIPPED - rgn: CreateRectRgn x y new-width new-height - SetWindowRgn hWnd rgn false - child: as handle! GetWindowLong hWnd wc-offset - 20 - if child <> null [ - rgn: CreateRectRgn x y new-width new-height - SetWindowRgn child rgn false - ] - ] - if all [ - BASE_FACE_CLIPPED and flags <> 0 - zero? x - zero? y - size/width = new-width - size/height = new-height - ][SetWindowLong hWnd wc-offset - 12 flags and FFFFFFFEh] -] - -process-layered-region: func [ - hWnd [handle!] - size [red-pair!] - pos [red-pair!] - pane [red-block!] - origin [red-pair!] - rect [RECT_STRUCT] - layer? [logic!] - /local - x [integer!] - y [integer!] - w [integer!] - h [integer!] - rc [RECT_STRUCT value] - sz [tagSIZE] - owner [handle!] - type [red-word!] - value [red-value!] - face [red-object!] - tail [red-object!] -][ - x: dpi-scale origin/x - y: dpi-scale origin/y - either null? rect [ - rect: :rc - owner: as handle! GetWindowLong hWnd wc-offset - 16 - assert owner <> null - GetClientRect owner rect - ][ - x: x + dpi-scale pos/x - y: y + dpi-scale pos/y - ] - - sz: as tagSIZE :rc - sz/width: dpi-scale size/x - sz/height: dpi-scale size/y - if layer? [ - w: x + sz/width - rect/right - w: either positive? w [sz/width - w][sz/width] - either negative? x [ - x: either x + sz/width < 0 [sz/width][0 - x] - ][ - x: 0 - ] - h: y + sz/height - rect/bottom - h: either positive? h [sz/height - h][sz/height] - either negative? y [ - y: either y + sz/height < 0 [sz/height][0 - y] - ][ - y: 0 - ] - clip-layered-window hWnd sz x y w h - ] - - if all [ - pane <> null - TYPE_OF(pane) = TYPE_BLOCK - ][ - face: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - while [face < tail][ - hWnd: get-face-handle face - value: get-face-values hWnd - size: as red-pair! value + FACE_OBJ_SIZE - pos: as red-pair! value + FACE_OBJ_OFFSET - pane: as red-block! value + FACE_OBJ_PANE - type: as red-word! value + FACE_OBJ_TYPE - layer?: all [ - base = symbol/resolve type/symbol - (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) > 0 - ] - process-layered-region hWnd size pos pane origin rect layer? - face: face + 1 - ] - ] -] - -update-layered-window: func [ - hWnd [handle!] - hdwp [handle!] - offset [tagPOINT] - winpos [tagWINDOWPOS] - showflag [integer!] - /local - values [red-value!] - pane [red-block!] - state [red-block!] - type [red-word!] - bool [red-logic!] - face [red-object!] - tail [red-object!] - size [red-pair!] - x [integer!] - y [integer!] - rect [RECT_STRUCT value] - sz [tagSIZE] - border [integer!] - width [integer!] - height [integer!] - sub? [logic!] -][ - values: get-face-values hWnd - type: as red-word! values + FACE_OBJ_TYPE - - sub?: either all [null? hdwp offset <> null] [ - hdwp: BeginDeferWindowPos 1 - no - ][ - yes - ] - - pane: as red-block! values + FACE_OBJ_PANE - if TYPE_OF(pane) = TYPE_BLOCK [ - bool: as red-logic! values + FACE_OBJ_VISIBLE? - unless bool/value [showflag: -2] - face: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - while [face < tail][ - state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE - if TYPE_OF(state) = TYPE_BLOCK [ - update-layered-window get-face-handle face hdwp offset winpos showflag - ] - face: face + 1 - ] - ] - if all [ - sub? - base = symbol/resolve type/symbol - (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) > 0 - ][ - either offset <> null [ - border: GetWindowLong hWnd wc-offset - 8 - x: offset/x + WIN32_LOWORD(border) - y: offset/y + WIN32_HIWORD(border) - unless all [zero? offset/x zero? offset/y][ - hdwp: DeferWindowPos - hdwp - hWnd - null - x y - 0 0 - SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE - SetWindowLong hWnd wc-offset - 8 WIN32_MAKE_LPARAM(x y) - hWnd: as handle! GetWindowLong hWnd wc-offset - 20 - if hWnd <> null [ - hdwp: DeferWindowPos - hdwp - hWnd - null - x y - 0 0 - SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE - ] - ] - if all [ ;-- clip window - winpos <> null - winpos/flags and SWP_NOSIZE = 0 ;-- sized - winpos/flags and 8000h = 0 ;-- not maximize and minimize - ][ - GetClientRect winpos/hWnd rect - border: winpos/cx - rect/right >> 1 - size: as red-pair! values + FACE_OBJ_SIZE - sz: as tagSIZE :rect - sz/width: dpi-scale size/x - sz/height: dpi-scale size/y - width: sz/width - height: sz/height - if x + sz/width + border > (winpos/x + winpos/cx) [ - width: sz/width - (x + sz/width - (winpos/x + winpos/cx)) - border - ] - if y + sz/height + border > (winpos/y + winpos/cy) [ - height: sz/height - (y + sz/height - (winpos/y + winpos/cy)) - border - ] - - clip-layered-window hWnd sz 0 0 width height - ] - ][ - bool: as red-logic! values + FACE_OBJ_VISIBLE? - either bool/value [ - case [ - showflag = -1 [showflag: SW_SHOWNA] - showflag = -2 [showflag: SW_HIDE] ;-- parent is invisible - true [0] - ] - ][showflag: SW_HIDE] - ShowWindow hWnd showflag - hWnd: as handle! GetWindowLong hWnd wc-offset - 20 - if hWnd <> null [ShowWindow hWnd showflag] - ] - ] - unless sub? [EndDeferWindowPos hdwp] -] - -BaseInternalWndProc: func [ - [stdcall] - hWnd [handle!] - msg [integer!] - wParam [integer!] - lParam [integer!] - return: [integer!] - /local - rect [RECT_STRUCT] - hBrush [handle!] -][ - switch msg [ - WM_MOUSEACTIVATE [return 3] ;-- do not make it activated when click it - WM_NCHITTEST [return -1] - WM_ERASEBKGND [ - hBrush: GetSysColorBrush COLOR_3DFACE - rect: declare RECT_STRUCT - GetClientRect hWnd rect - FillRect as handle! wParam rect hBrush - return 1 - ] - default [0] - ] - DefWindowProc hWnd msg wParam lParam -] - -BaseWndProc: func [ - [stdcall] - hWnd [handle!] - msg [integer!] - wParam [integer!] - lParam [integer!] - return: [integer!] - /local - target [int-ptr!] - this [this!] - rt [ID2D1HwndRenderTarget] - flags [integer!] - w [integer!] - len [integer!] - hfont [handle!] - draw [red-block!] - DC [draw-ctx!] - font [red-object!] -][ - switch msg [ - WM_MOUSEACTIVATE [ - flags: GetWindowLong hWnd GWL_EXSTYLE - if flags and WS_EX_LAYERED > 0 [ - SetForegroundWindow GetParent hWnd - return 3 ;-- do not make it activated when click it - ] - ] - WM_LBUTTONDOWN [SetCapture hWnd return 0] - WM_LBUTTONUP [ReleaseCapture return 0] - WM_ERASEBKGND [return 1] ;-- drawing in WM_PAINT to avoid flicker - WM_SIZE [ - either (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D = 0 [ - unless zero? GetWindowLong hWnd wc-offset + 4 [ - update-base hWnd null null get-face-values hWnd - ] - ][ - target: as int-ptr! GetWindowLong hWnd wc-offset - 24 - if target <> null [ - this: as this! target/value - rt: as ID2D1HwndRenderTarget this/vtbl - w: WIN32_LOWORD(lParam) - flags: WIN32_HIWORD(lParam) - rt/Resize this as tagSIZE :w - InvalidateRect hWnd null 1 - ] - ] - return 0 - ] - 0317h ;-- WM_PRINT ;-- these messages are not actually being used - 0318h ;-- WM_PRINTCLIENT ; see https://stackoverflow.com/a/44062144 - WM_PAINT - WM_DISPLAYCHANGE [ - if (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) = 0 [ - draw: (as red-block! get-face-values hWnd) + FACE_OBJ_DRAW - either TYPE_OF(draw) = TYPE_BLOCK [ - either zero? GetWindowLong hWnd wc-offset - 4 [ - do-draw hWnd null draw no yes yes yes - ][ - bitblt-memory-dc hWnd no null 0 0 - ] - ][ - if null? current-msg [return -1] - system/thrown: 0 - DC: declare draw-ctx! ;@@ should declare it on stack - catch RED_THROWN_ERROR [ - draw-begin DC hWnd null no yes - integer/make-at as red-value! draw as-integer DC - current-msg/hWnd: hWnd - make-event current-msg 0 EVT_DRAWING - draw/header: TYPE_NONE - draw-end DC hWnd no no yes - ] - system/thrown: 0 - ] - return 0 - ] - ] - WM_VSCROLL - WM_HSCROLL [ - if zero? lParam [ ;-- message from standard scroll bar - current-msg/hWnd: hWnd - current-msg/msg: msg - current-msg/wParam: wParam - make-event current-msg 0 EVT_SCROLL - return 0 - ] - ] - WM_NCHITTEST [ - w: DefWindowProc hWnd msg wParam lParam - flags: GetWindowLong hWnd wc-offset - 28 - if flags <> 0 [ ;-- has custom cursor - either w = 1 [ ;-- client area - flags: flags or 80000000h - ][ - flags: flags and 7FFFFFFFh - ] - SetWindowLong hWnd wc-offset - 28 flags - ] - return w - ] - WM_SETCURSOR [ - w: GetWindowLong as handle! wParam wc-offset - 28 - if all [ - w <> 0 - w and 80000000h <> 0 ;-- inside client area - ][ - SetCursor as handle! (w and 7FFFFFFFh) - return 1 - ] - ] - WM_MENUSELECT [ - if wParam <> FFFF0000h [ - menu-selected: WIN32_LOWORD(wParam) - menu-handle: as handle! lParam - ] - return 0 - ] - WM_COMMAND [ - process-command-event hWnd msg wParam lParam - return 0 - ] - default [0] - ] - if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_IME <> 0 [ - switch msg [ - WM_IME_SETCONTEXT [ - either zero? wParam [ - ImmReleaseContext hWnd hIMCtx - ][ - hIMCtx: ImmGetContext hWnd - ] - ] - 010Dh [ ;-- WM_IME_STARTCOMPOSITION - ime-open?: yes - font: as red-object! (get-face-values hWnd) + FACE_OBJ_FONT - if TYPE_OF(font) = TYPE_OBJECT [ - hfont: get-font-handle font 0 - if hfont <> null [ - GetObject hFont 92 as byte-ptr! ime-font - ImmSetCompositionFontW hIMCtx ime-font - ] - ] - ] - 010Eh [ ;-- WM_IME_ENDCOMPOSITION - ime-open?: no - ] - default [0] - ] - ] - DefWindowProc hWnd msg wParam lParam -] - -update-base-image: func [ - graphic [integer!] - img [red-image!] - width [integer!] - height [integer!] -][ - if TYPE_OF(img) = TYPE_IMAGE [ - GdipDrawImageRectI graphic as-integer img/node 0 0 width height - ] -] - -update-base-background: func [ - graphic [integer!] - color [red-tuple!] - width [integer!] - height [integer!] - /local - clr [integer!] - brush [integer!] -][ - clr: to-gdiplus-color-fixed color/array1 - brush: 0 - GdipCreateSolidFill clr :brush - GdipFillRectangleI graphic brush 0 0 width height - GdipDeleteBrush brush -] - -update-base-text: func [ - hWnd [handle!] - graphic [integer!] - dc [handle!] - text [red-string!] - font [red-object!] - para [red-object!] - width [integer!] - height [integer!] - bbox [RECT_STRUCT_FLOAT32] ;-- renders if = null, measures otherwise - /local - format [integer!] - fflags [integer!] - hFont [integer!] - hBrush [integer!] - flags [integer!] - v-align [integer!] - h-align [integer!] - clr [integer!] - handle [red-handle!] - values [red-value!] - color [red-tuple!] - state [red-block!] - rect [RECT_STRUCT_FLOAT32 value] - gdiclr [integer!] - default-color [logic!] -][ - if TYPE_OF(text) <> TYPE_STRING [exit] - - ;GdipSetCompositingMode graphic 0 ;-- over mode - ;GdipSetCompositingQuality graphic 2 ;-- high quality - ;GdipSetPixelOffsetMode graphic 2 ;-- high quality - ;-- ClearType looks BAD on alpha-enabled background - ; GdipSetTextRenderingHint graphic TextRenderingHintClearTypeGridFit - GdipSetTextRenderingHint graphic TextRenderingHintAntiAliasGridFit - - format: 0 - hBrush: 0 - clr: 0 - default-color: yes - hFont: as-integer default-font - - if TYPE_OF(font) = TYPE_OBJECT [ - values: object/get-values font - color: as red-tuple! values + FONT_OBJ_COLOR - - state: as red-block! values + FONT_OBJ_STATE - either TYPE_OF(state) = TYPE_BLOCK [ - handle: as red-handle! block/rs-head state - if TYPE_OF(handle) = TYPE_HANDLE [ - hFont: handle/value - ] - ][ - hFont: as-integer make-font get-face-obj hWnd font - ] - if TYPE_OF(color) = TYPE_TUPLE [ - clr: color/array1 - default-color: no - ] - ] - SelectObject dc as handle! hFont - - flags: either TYPE_OF(para) = TYPE_OBJECT [ - get-para-flags base para - ][ - 5 ;-- 1 = center + 4 = middle - ] - h-align: flags and 3 ;-- 0,1,2 = left,center,right - v-align: flags >>> 2 and 3 ;-- 0,4,8 = top,middle,bottom - - GdipCreateFontFromDC as-integer dc :hFont - - fflags: either flags and DT_WORDBREAK = 0 [1000h][0] ;-- 1000h = nowrap - GdipCreateStringFormat fflags or 80000000h 0 :format ;-- 1 << 31 = GDI passthrough - GdipSetStringFormatAlign format h-align - GdipSetStringFormatLineAlign format v-align - - rect/x: as float32! 0.0 - rect/y: as float32! 0.0 - rect/width: as float32! dpi-unscale width - rect/height: as float32! dpi-unscale height - - either bbox = null [ - if default-color [clr: GetSysColor COLOR_WINDOWTEXT] - gdiclr: to-gdiplus-color-fixed clr - GdipCreateSolidFill gdiclr :hBrush - GdipDrawString graphic unicode/to-utf16 text -1 hFont :rect format hBrush - GdipDeleteBrush hBrush - ][ - rect/height: as float32! 1e6 ;-- allow some room for rendering, otherwise stops at height - GdipMeasureString graphic unicode/to-utf16 text -1 hFont :rect format bbox null null - ] - - GdipDeleteStringFormat format - GdipDeleteFont hFont -] - -transparent-base?: func [ - color [red-tuple!] - img [red-image!] - return: [logic!] -][ - either all [ - TYPE_OF(color) = TYPE_TUPLE - any [ - TUPLE_SIZE?(color) = 3 - color/array1 and FF000000h = 0 - ] - ][false][true] -] - -scale-graphic: func [ - graphic [integer!] - /local - ratio [float32!] -][ - if dpi-factor <> 100 [ - ratio: (as float32! dpi-factor) / (as float32! 100.0) - GdipScaleWorldTransform graphic ratio ratio GDIPLUS_MATRIX_PREPEND - ] -] - -update-base: func [ - hWnd [handle!] - parent [handle!] - ptDst [tagPOINT] - values [red-value!] - /local - img [red-image!] - color [red-tuple!] - cmds [red-block!] - text [red-string!] - font [red-object!] - para [red-object!] - sz [red-pair!] - height [integer!] - width [integer!] - size [tagSIZE] - hBitmap [handle!] - hBackDC [handle!] - ptSrc [tagPOINT value] - bf [tagBLENDFUNCTION value] - graphic [integer!] - flags [integer!] -][ - if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [ - InvalidateRect hWnd null 0 - exit - ] - - flags: GetWindowLong hWnd GWL_EXSTYLE - if zero? (flags and WS_EX_LAYERED) [ - graphic: GetWindowLong hWnd wc-offset - 4 - DeleteDC as handle! graphic - SetWindowLong hWnd wc-offset - 4 0 - InvalidateRect hWnd null 0 - exit - ] - - img: as red-image! values + FACE_OBJ_IMAGE - color: as red-tuple! values + FACE_OBJ_COLOR - cmds: as red-block! values + FACE_OBJ_DRAW - text: as red-string! values + FACE_OBJ_TEXT - font: as red-object! values + FACE_OBJ_FONT - para: as red-object! values + FACE_OBJ_PARA - sz: as red-pair! values + FACE_OBJ_SIZE - graphic: 0 - - width: dpi-scale sz/x - height: dpi-scale sz/y - hBackDC: CreateCompatibleDC hScreen - hBitmap: CreateCompatibleBitmap hScreen width height - SelectObject hBackDC hBitmap - GdipCreateFromHDC hBackDC :graphic - if TYPE_OF(color) = TYPE_TUPLE [ ;-- update background - update-base-background graphic color width height - ] - GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS - update-base-image graphic img width height - update-base-text hWnd graphic hBackDC text font para width height null - do-draw null as red-image! graphic cmds yes no no yes - - ptSrc/x: 0 - ptSrc/y: 0 - size: as tagSIZE :width - bf/BlendOp: as-byte 0 - bf/BlendFlags: as-byte 0 - bf/SourceConstantAlpha: as-byte 255 - bf/AlphaFormat: as-byte 1 - flags: 2 - UpdateLayeredWindow hWnd null ptDst size hBackDC :ptSrc 0 :bf flags - - GdipDeleteGraphics graphic - DeleteObject hBitmap - DeleteDC hBackDC -] - - -;-- blends the image of every encountered visible layered window into the DC -imprint-layers-deep: func [ - dc [handle!] - hwnd [handle!] - bx [integer!] ;-- "base" offset: where on the DC this window will appear - by [integer!] - values [red-value!] - /local - type [red-word!] - sym [integer!] - draw [red-block!] - pane [red-block!] - visible? [red-logic!] - child [red-object!] - tail [red-object!] - state [red-block!] - cofs [red-pair!] ;-- "child" offset - it's position inside the parent - chwnd [handle!] - cvalues [red-value!] -][ - if null = values [values: get-face-values hwnd] - - ;-- imprint hwnd - type: as red-word! values + FACE_OBJ_TYPE - sym: symbol/resolve type/symbol - if all [sym = base layered-win? hwnd][ - draw: as red-block! values + FACE_OBJ_DRAW - either all [bx = 0 by = 0] [ - ;-- paint directly to DC - do-draw hwnd as red-image! dc draw no no no yes - ][ - do-draw hwnd null draw no yes no yes ;-- paint into RAM - bitblt-memory-dc hwnd yes dc bx by ;-- blend back - ] - ] - - ;-- imprint hwnd's children if any - pane: as red-block! values + FACE_OBJ_PANE - if TYPE_OF(pane) = TYPE_BLOCK [ - visible?: as red-logic! values + FACE_OBJ_VISIBLE? - if visible?/value [ - child: as red-object! block/rs-head pane - tail: as red-object! block/rs-tail pane - while [child < tail][ - state: as red-block! get-node-facet child/ctx FACE_OBJ_STATE - if TYPE_OF(state) = TYPE_BLOCK [ - chwnd: get-face-handle child - cvalues: get-face-values chwnd - cofs: as red-pair! cvalues + FACE_OBJ_OFFSET - imprint-layers-deep - dc chwnd - bx + dpi-scale cofs/x - by + dpi-scale cofs/y - cvalues - ] - child: child + 1 - ] - ] - ] -] - +Red/System [ + Title: "Windows layered window widget" + Author: "Xie Qingtian" + File: %base.reds + Tabs: 4 + Rights: "Copyright (C) 2015 Xie Qingtian. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +init-base-face: func [ + handle [handle!] + parent [integer!] + values [red-value!] + alpha? [logic!] + /local + pt [tagPOINT value] + offset [red-pair!] + size [red-pair!] + show? [red-logic!] + opts [red-block!] + word [red-word!] + len [integer!] + sym [integer!] + flags [integer!] +][ + offset: as red-pair! values + FACE_OBJ_OFFSET + size: as red-pair! values + FACE_OBJ_SIZE + show?: as red-logic! values + FACE_OBJ_VISIBLE? + opts: as red-block! values + FACE_OBJ_OPTIONS + + SetWindowLong handle wc-offset - 4 0 + SetWindowLong handle wc-offset - 12 0 + SetWindowLong handle wc-offset - 16 parent + SetWindowLong handle wc-offset - 20 0 + SetWindowLong handle wc-offset - 24 0 + pt/x: dpi-scale offset/x + pt/y: dpi-scale offset/y + either alpha? [ + unless win8+? [ + position-base handle as handle! parent :pt + ] + update-base handle as handle! parent :pt values + if all [show?/value IsWindowVisible as handle! parent][ + ShowWindow handle SW_SHOWNA + ] + unless win8+? [ + process-layered-region handle size offset null offset null yes + ] + ][ + SetWindowLong handle wc-offset - 8 WIN32_MAKE_LPARAM(pt/x pt/y) + ] + + if TYPE_OF(opts) = TYPE_BLOCK [ + word: as red-word! block/rs-head opts + len: block/rs-length? opts + if len % 2 <> 0 [exit] + flags: GetWindowLong handle wc-offset - 12 + while [len > 0][ + sym: symbol/resolve word/symbol + case [ + sym = caret [ + SetWindowLong handle wc-offset - 12 flags or BASE_FACE_CARET + SetWindowLong handle wc-offset - 24 as-integer get-face-handle as red-object! word + 1 + update-caret handle values + ] + true [0] + ] + word: word + 2 + len: len - 2 + ] + ] +] + +position-base: func [ + base [handle!] + parent [handle!] + pt [tagPOINT] +][ + ClientToScreen parent pt ;-- convert client offset to screen offset + SetWindowLong base wc-offset - 8 WIN32_MAKE_LPARAM(pt/x pt/y) +] + +layered-win?: func [ + hWnd [handle!] + return: [logic!] +][ + (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) <> 0 +] + +detached?: func [ + hWnd [handle!] + return: [logic!] +][ + (GetWindowLong hWnd GWL_STYLE) and WS_CHILD = 0 +] + +render-base: func [ + hWnd [handle!] + hDC [handle!] + return: [logic!] + /local + values [red-value!] + img [red-image!] + w [red-word!] + rc [RECT_STRUCT value] + graphic [integer!] + type [integer!] + res [logic!] +][ + graphic: 0 + res: paint-background hWnd hDC + + values: get-face-values hWnd + w: as red-word! values + FACE_OBJ_TYPE + img: as red-image! values + FACE_OBJ_IMAGE + + GetClientRect hWnd :rc + if TYPE_OF(img) = TYPE_IMAGE [ + GdipCreateFromHDC hDC :graphic + if zero? GdipDrawImageRectI + graphic + as-integer img/node + 0 0 + rc/right - rc/left rc/bottom - rc/top [res: true] + GdipDeleteGraphics graphic + ] + + type: symbol/resolve w/symbol + if all [ + type = base + render-text values hWnd hDC :rc null null + ][ + res: true + ] + res +] + +render-text: func [ + values [red-value!] + hWnd [handle!] + hDC [handle!] + rc [RECT_STRUCT] + text [red-string!] + bbox [RECT_STRUCT_FLOAT32] ; renders if = null, measures otherwise + return: [logic!] + /local + font [red-object!] + para [red-object!] + res [logic!] + graphic [integer!] +][ + ;unless winxp? [return render-text-d2d values hDC rc] + res: false + if text = null [text: as red-string! values + FACE_OBJ_TEXT] + para: as red-object! values + FACE_OBJ_PARA + if TYPE_OF(text) = TYPE_STRING [ + font: as red-object! values + FACE_OBJ_FONT + graphic: 0 + GdipCreateFromHDC hDC :graphic + ; GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS + ; using GDI+ text rendering instead of GDI, see #2503 and #3465 + update-base-text hWnd graphic hDC text font para rc/right - rc/left rc/bottom - rc/top bbox + GdipDeleteGraphics graphic + res: true + ] + res +] + +clip-layered-window: func [ + hWnd [handle!] + size [tagSIZE] + x [integer!] + y [integer!] + new-width [integer!] + new-height [integer!] + /local + rgn [handle!] + child [handle!] + flags [integer!] +][ + flags: GetWindowLong hWnd wc-offset - 12 + if any [ + not zero? x + not zero? y + size/width <> new-width + size/height <> new-height + BASE_FACE_CLIPPED and flags <> 0 + ][ + SetWindowLong hWnd wc-offset - 12 flags or BASE_FACE_CLIPPED + rgn: CreateRectRgn x y new-width new-height + SetWindowRgn hWnd rgn false + child: as handle! GetWindowLong hWnd wc-offset - 20 + if child <> null [ + rgn: CreateRectRgn x y new-width new-height + SetWindowRgn child rgn false + ] + ] + if all [ + BASE_FACE_CLIPPED and flags <> 0 + zero? x + zero? y + size/width = new-width + size/height = new-height + ][SetWindowLong hWnd wc-offset - 12 flags and FFFFFFFEh] +] + +process-layered-region: func [ + hWnd [handle!] + size [red-pair!] + pos [red-pair!] + pane [red-block!] + origin [red-pair!] + rect [RECT_STRUCT] + layer? [logic!] + /local + x [integer!] + y [integer!] + w [integer!] + h [integer!] + rc [RECT_STRUCT value] + sz [tagSIZE] + owner [handle!] + type [red-word!] + value [red-value!] + face [red-object!] + tail [red-object!] +][ + x: dpi-scale origin/x + y: dpi-scale origin/y + either null? rect [ + rect: :rc + owner: as handle! GetWindowLong hWnd wc-offset - 16 + assert owner <> null + GetClientRect owner rect + ][ + x: x + dpi-scale pos/x + y: y + dpi-scale pos/y + ] + + sz: as tagSIZE :rc + sz/width: dpi-scale size/x + sz/height: dpi-scale size/y + if layer? [ + w: x + sz/width - rect/right + w: either positive? w [sz/width - w][sz/width] + either negative? x [ + x: either x + sz/width < 0 [sz/width][0 - x] + ][ + x: 0 + ] + h: y + sz/height - rect/bottom + h: either positive? h [sz/height - h][sz/height] + either negative? y [ + y: either y + sz/height < 0 [sz/height][0 - y] + ][ + y: 0 + ] + clip-layered-window hWnd sz x y w h + ] + + if all [ + pane <> null + TYPE_OF(pane) = TYPE_BLOCK + ][ + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [face < tail][ + hWnd: get-face-handle face + value: get-face-values hWnd + size: as red-pair! value + FACE_OBJ_SIZE + pos: as red-pair! value + FACE_OBJ_OFFSET + pane: as red-block! value + FACE_OBJ_PANE + type: as red-word! value + FACE_OBJ_TYPE + layer?: all [ + base = symbol/resolve type/symbol + (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) > 0 + ] + process-layered-region hWnd size pos pane origin rect layer? + face: face + 1 + ] + ] +] + +update-layered-window: func [ + hWnd [handle!] + hdwp [handle!] + offset [tagPOINT] + winpos [tagWINDOWPOS] + showflag [integer!] + /local + values [red-value!] + pane [red-block!] + state [red-block!] + type [red-word!] + bool [red-logic!] + face [red-object!] + tail [red-object!] + size [red-pair!] + x [integer!] + y [integer!] + rect [RECT_STRUCT value] + sz [tagSIZE] + border [integer!] + width [integer!] + height [integer!] + sub? [logic!] +][ + values: get-face-values hWnd + type: as red-word! values + FACE_OBJ_TYPE + + sub?: either all [null? hdwp offset <> null] [ + hdwp: BeginDeferWindowPos 1 + no + ][ + yes + ] + + pane: as red-block! values + FACE_OBJ_PANE + if TYPE_OF(pane) = TYPE_BLOCK [ + bool: as red-logic! values + FACE_OBJ_VISIBLE? + unless bool/value [showflag: -2] + face: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [face < tail][ + state: as red-block! get-node-facet face/ctx FACE_OBJ_STATE + if TYPE_OF(state) = TYPE_BLOCK [ + update-layered-window get-face-handle face hdwp offset winpos showflag + ] + face: face + 1 + ] + ] + if all [ + sub? + base = symbol/resolve type/symbol + (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) > 0 + ][ + either offset <> null [ + border: GetWindowLong hWnd wc-offset - 8 + x: offset/x + WIN32_LOWORD(border) + y: offset/y + WIN32_HIWORD(border) + unless all [zero? offset/x zero? offset/y][ + hdwp: DeferWindowPos + hdwp + hWnd + null + x y + 0 0 + SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE + SetWindowLong hWnd wc-offset - 8 WIN32_MAKE_LPARAM(x y) + hWnd: as handle! GetWindowLong hWnd wc-offset - 20 + if hWnd <> null [ + hdwp: DeferWindowPos + hdwp + hWnd + null + x y + 0 0 + SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE + ] + ] + if all [ ;-- clip window + winpos <> null + winpos/flags and SWP_NOSIZE = 0 ;-- sized + winpos/flags and 8000h = 0 ;-- not maximize and minimize + ][ + GetClientRect winpos/hWnd rect + border: winpos/cx - rect/right >> 1 + size: as red-pair! values + FACE_OBJ_SIZE + sz: as tagSIZE :rect + sz/width: dpi-scale size/x + sz/height: dpi-scale size/y + width: sz/width + height: sz/height + if x + sz/width + border > (winpos/x + winpos/cx) [ + width: sz/width - (x + sz/width - (winpos/x + winpos/cx)) - border + ] + if y + sz/height + border > (winpos/y + winpos/cy) [ + height: sz/height - (y + sz/height - (winpos/y + winpos/cy)) - border + ] + + clip-layered-window hWnd sz 0 0 width height + ] + ][ + bool: as red-logic! values + FACE_OBJ_VISIBLE? + either bool/value [ + case [ + showflag = -1 [showflag: SW_SHOWNA] + showflag = -2 [showflag: SW_HIDE] ;-- parent is invisible + true [0] + ] + ][showflag: SW_HIDE] + ShowWindow hWnd showflag + hWnd: as handle! GetWindowLong hWnd wc-offset - 20 + if hWnd <> null [ShowWindow hWnd showflag] + ] + ] + unless sub? [EndDeferWindowPos hdwp] +] + +BaseInternalWndProc: func [ + [stdcall] + hWnd [handle!] + msg [integer!] + wParam [integer!] + lParam [integer!] + return: [integer!] + /local + rect [RECT_STRUCT] + hBrush [handle!] +][ + switch msg [ + WM_MOUSEACTIVATE [return 3] ;-- do not make it activated when click it + WM_NCHITTEST [return -1] + WM_ERASEBKGND [ + hBrush: GetSysColorBrush COLOR_3DFACE + rect: declare RECT_STRUCT + GetClientRect hWnd rect + FillRect as handle! wParam rect hBrush + return 1 + ] + default [0] + ] + DefWindowProc hWnd msg wParam lParam +] + +BaseWndProc: func [ + [stdcall] + hWnd [handle!] + msg [integer!] + wParam [integer!] + lParam [integer!] + return: [integer!] + /local + target [int-ptr!] + this [this!] + rt [ID2D1HwndRenderTarget] + flags [integer!] + w [integer!] + len [integer!] + hfont [handle!] + draw [red-block!] + DC [draw-ctx!] + font [red-object!] +][ + switch msg [ + WM_MOUSEACTIVATE [ + flags: GetWindowLong hWnd GWL_EXSTYLE + if flags and WS_EX_LAYERED > 0 [ + SetForegroundWindow GetParent hWnd + return 3 ;-- do not make it activated when click it + ] + ] + WM_LBUTTONDOWN [SetCapture hWnd return 0] + WM_LBUTTONUP [ReleaseCapture return 0] + WM_ERASEBKGND [return 1] ;-- drawing in WM_PAINT to avoid flicker + WM_SIZE [ + either (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D = 0 [ + unless zero? GetWindowLong hWnd wc-offset + 4 [ + update-base hWnd null null get-face-values hWnd + ] + ][ + target: as int-ptr! GetWindowLong hWnd wc-offset - 24 + if target <> null [ + this: as this! target/value + rt: as ID2D1HwndRenderTarget this/vtbl + w: WIN32_LOWORD(lParam) + flags: WIN32_HIWORD(lParam) + rt/Resize this as tagSIZE :w + InvalidateRect hWnd null 1 + ] + ] + return 0 + ] + 0317h ;-- WM_PRINT ;-- these messages are not actually being used + 0318h ;-- WM_PRINTCLIENT ; see https://stackoverflow.com/a/44062144 + WM_PAINT + WM_DISPLAYCHANGE [ + if (WS_EX_LAYERED and GetWindowLong hWnd GWL_EXSTYLE) = 0 [ + draw: (as red-block! get-face-values hWnd) + FACE_OBJ_DRAW + either TYPE_OF(draw) = TYPE_BLOCK [ + either zero? GetWindowLong hWnd wc-offset - 4 [ + do-draw hWnd null draw no yes yes yes + ][ + bitblt-memory-dc hWnd no null 0 0 + ] + ][ + if null? current-msg [return -1] + system/thrown: 0 + DC: declare draw-ctx! ;@@ should declare it on stack + catch RED_THROWN_ERROR [ + draw-begin DC hWnd null no yes + integer/make-at as red-value! draw as-integer DC + current-msg/hWnd: hWnd + make-event current-msg 0 EVT_DRAWING + draw/header: TYPE_NONE + draw-end DC hWnd no no yes + ] + system/thrown: 0 + ] + return 0 + ] + ] + WM_VSCROLL + WM_HSCROLL [ + if zero? lParam [ ;-- message from standard scroll bar + current-msg/hWnd: hWnd + current-msg/msg: msg + current-msg/wParam: wParam + make-event current-msg 0 EVT_SCROLL + return 0 + ] + ] + WM_NCHITTEST [ + w: DefWindowProc hWnd msg wParam lParam + flags: GetWindowLong hWnd wc-offset - 28 + if flags <> 0 [ ;-- has custom cursor + either w = 1 [ ;-- client area + flags: flags or 80000000h + ][ + flags: flags and 7FFFFFFFh + ] + SetWindowLong hWnd wc-offset - 28 flags + ] + return w + ] + WM_SETCURSOR [ + w: GetWindowLong as handle! wParam wc-offset - 28 + if all [ + w <> 0 + w and 80000000h <> 0 ;-- inside client area + ][ + SetCursor as handle! (w and 7FFFFFFFh) + return 1 + ] + ] + WM_MENUSELECT [ + if wParam <> FFFF0000h [ + menu-selected: WIN32_LOWORD(wParam) + menu-handle: as handle! lParam + ] + return 0 + ] + WM_COMMAND [ + process-command-event hWnd msg wParam lParam + return 0 + ] + default [0] + ] + if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_IME <> 0 [ + switch msg [ + WM_IME_SETCONTEXT [ + either zero? wParam [ + ImmReleaseContext hWnd hIMCtx + ][ + hIMCtx: ImmGetContext hWnd + ] + ] + 010Dh [ ;-- WM_IME_STARTCOMPOSITION + ime-open?: yes + font: as red-object! (get-face-values hWnd) + FACE_OBJ_FONT + if TYPE_OF(font) = TYPE_OBJECT [ + hfont: get-font-handle font 0 + if hfont <> null [ + GetObject hFont 92 as byte-ptr! ime-font + ImmSetCompositionFontW hIMCtx ime-font + ] + ] + ] + 010Eh [ ;-- WM_IME_ENDCOMPOSITION + ime-open?: no + ] + default [0] + ] + ] + DefWindowProc hWnd msg wParam lParam +] + +update-base-image: func [ + graphic [integer!] + img [red-image!] + width [integer!] + height [integer!] +][ + if TYPE_OF(img) = TYPE_IMAGE [ + GdipDrawImageRectI graphic as-integer img/node 0 0 width height + ] +] + +update-base-background: func [ + graphic [integer!] + color [red-tuple!] + width [integer!] + height [integer!] + /local + clr [integer!] + brush [integer!] +][ + clr: to-gdiplus-color-fixed color/array1 + brush: 0 + GdipCreateSolidFill clr :brush + GdipFillRectangleI graphic brush 0 0 width height + GdipDeleteBrush brush +] + +update-base-text: func [ + hWnd [handle!] + graphic [integer!] + dc [handle!] + text [red-string!] + font [red-object!] + para [red-object!] + width [integer!] + height [integer!] + bbox [RECT_STRUCT_FLOAT32] ;-- renders if = null, measures otherwise + /local + format [integer!] + fflags [integer!] + hFont [integer!] + hBrush [integer!] + flags [integer!] + v-align [integer!] + h-align [integer!] + clr [integer!] + handle [red-handle!] + values [red-value!] + color [red-tuple!] + state [red-block!] + rect [RECT_STRUCT_FLOAT32 value] + gdiclr [integer!] + default-color [logic!] +][ + if TYPE_OF(text) <> TYPE_STRING [exit] + + ;GdipSetCompositingMode graphic 0 ;-- over mode + ;GdipSetCompositingQuality graphic 2 ;-- high quality + ;GdipSetPixelOffsetMode graphic 2 ;-- high quality + ;-- ClearType looks BAD on alpha-enabled background + ; GdipSetTextRenderingHint graphic TextRenderingHintClearTypeGridFit + GdipSetTextRenderingHint graphic TextRenderingHintAntiAliasGridFit + + format: 0 + hBrush: 0 + clr: 0 + default-color: yes + hFont: as-integer default-font + + if TYPE_OF(font) = TYPE_OBJECT [ + values: object/get-values font + color: as red-tuple! values + FONT_OBJ_COLOR + + state: as red-block! values + FONT_OBJ_STATE + either TYPE_OF(state) = TYPE_BLOCK [ + handle: as red-handle! block/rs-head state + if TYPE_OF(handle) = TYPE_HANDLE [ + hFont: handle/value + ] + ][ + hFont: as-integer make-font get-face-obj hWnd font + ] + if TYPE_OF(color) = TYPE_TUPLE [ + clr: color/array1 + default-color: no + ] + ] + SelectObject dc as handle! hFont + + flags: either TYPE_OF(para) = TYPE_OBJECT [ + get-para-flags base para + ][ + 5 ;-- 1 = center + 4 = middle + ] + h-align: flags and 3 ;-- 0,1,2 = left,center,right + v-align: flags >>> 2 and 3 ;-- 0,4,8 = top,middle,bottom + + GdipCreateFontFromDC as-integer dc :hFont + + fflags: either flags and DT_WORDBREAK = 0 [1000h][0] ;-- 1000h = nowrap + GdipCreateStringFormat fflags or 80000000h 0 :format ;-- 1 << 31 = GDI passthrough + GdipSetStringFormatAlign format h-align + GdipSetStringFormatLineAlign format v-align + + rect/x: as float32! 0.0 + rect/y: as float32! 0.0 + rect/width: as float32! width + rect/height: as float32! height + either bbox = null [ + if default-color [clr: GetSysColor COLOR_WINDOWTEXT] + gdiclr: to-gdiplus-color-fixed clr + GdipCreateSolidFill gdiclr :hBrush + GdipDrawString graphic unicode/to-utf16 text -1 hFont :rect format hBrush + GdipDeleteBrush hBrush + ][ + rect/height: as float32! 1e6 ;-- allow some room for rendering, otherwise stops at height + GdipMeasureString graphic unicode/to-utf16 text -1 hFont :rect format bbox null null + ] + + GdipDeleteStringFormat format + GdipDeleteFont hFont +] + +transparent-base?: func [ + color [red-tuple!] + img [red-image!] + return: [logic!] +][ + either all [ + TYPE_OF(color) = TYPE_TUPLE + any [ + TUPLE_SIZE?(color) = 3 + color/array1 and FF000000h = 0 + ] + ][false][true] +] + +scale-graphic: func [ + graphic [integer!] + /local + ratio [float32!] +][ + if dpi-factor <> 100 [ + ratio: (as float32! dpi-factor) / (as float32! 100.0) + GdipScaleWorldTransform graphic ratio ratio GDIPLUS_MATRIX_PREPEND + ] +] + +update-base: func [ + hWnd [handle!] + parent [handle!] + ptDst [tagPOINT] + values [red-value!] + /local + img [red-image!] + color [red-tuple!] + cmds [red-block!] + text [red-string!] + font [red-object!] + para [red-object!] + sz [red-pair!] + height [integer!] + width [integer!] + size [tagSIZE] + hBitmap [handle!] + hBackDC [handle!] + ptSrc [tagPOINT value] + bf [tagBLENDFUNCTION value] + graphic [integer!] + flags [integer!] +][ + if (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D <> 0 [ + InvalidateRect hWnd null 0 + exit + ] + + flags: GetWindowLong hWnd GWL_EXSTYLE + if zero? (flags and WS_EX_LAYERED) [ + graphic: GetWindowLong hWnd wc-offset - 4 + DeleteDC as handle! graphic + SetWindowLong hWnd wc-offset - 4 0 + InvalidateRect hWnd null 0 + exit + ] + + img: as red-image! values + FACE_OBJ_IMAGE + color: as red-tuple! values + FACE_OBJ_COLOR + cmds: as red-block! values + FACE_OBJ_DRAW + text: as red-string! values + FACE_OBJ_TEXT + font: as red-object! values + FACE_OBJ_FONT + para: as red-object! values + FACE_OBJ_PARA + sz: as red-pair! values + FACE_OBJ_SIZE + graphic: 0 + + width: dpi-scale sz/x + height: dpi-scale sz/y + hBackDC: CreateCompatibleDC hScreen + hBitmap: CreateCompatibleBitmap hScreen width height + SelectObject hBackDC hBitmap + GdipCreateFromHDC hBackDC :graphic + if TYPE_OF(color) = TYPE_TUPLE [ ;-- update background + update-base-background graphic color width height + ] + GdipSetSmoothingMode graphic GDIPLUS_ANTIALIAS + update-base-image graphic img width height + update-base-text hWnd graphic hBackDC text font para width height null + do-draw null as red-image! graphic cmds yes no no yes + + ptSrc/x: 0 + ptSrc/y: 0 + size: as tagSIZE :width + bf/BlendOp: as-byte 0 + bf/BlendFlags: as-byte 0 + bf/SourceConstantAlpha: as-byte 255 + bf/AlphaFormat: as-byte 1 + flags: 2 + UpdateLayeredWindow hWnd null ptDst size hBackDC :ptSrc 0 :bf flags + + GdipDeleteGraphics graphic + DeleteObject hBitmap + DeleteDC hBackDC +] + + +;-- blends the image of every encountered visible layered window into the DC +imprint-layers-deep: func [ + dc [handle!] + hwnd [handle!] + bx [integer!] ;-- "base" offset: where on the DC this window will appear + by [integer!] + values [red-value!] + /local + type [red-word!] + sym [integer!] + draw [red-block!] + pane [red-block!] + visible? [red-logic!] + child [red-object!] + tail [red-object!] + state [red-block!] + cofs [red-pair!] ;-- "child" offset - it's position inside the parent + chwnd [handle!] + cvalues [red-value!] +][ + if null = values [values: get-face-values hwnd] + + ;-- imprint hwnd + type: as red-word! values + FACE_OBJ_TYPE + sym: symbol/resolve type/symbol + if all [sym = base layered-win? hwnd][ + draw: as red-block! values + FACE_OBJ_DRAW + either all [bx = 0 by = 0] [ + ;-- paint directly to DC + do-draw hwnd as red-image! dc draw no no no yes + ][ + do-draw hwnd null draw no yes no yes ;-- paint into RAM + bitblt-memory-dc hwnd yes dc bx by ;-- blend back + ] + ] + + ;-- imprint hwnd's children if any + pane: as red-block! values + FACE_OBJ_PANE + if TYPE_OF(pane) = TYPE_BLOCK [ + visible?: as red-logic! values + FACE_OBJ_VISIBLE? + if visible?/value [ + child: as red-object! block/rs-head pane + tail: as red-object! block/rs-tail pane + while [child < tail][ + state: as red-block! get-node-facet child/ctx FACE_OBJ_STATE + if TYPE_OF(state) = TYPE_BLOCK [ + chwnd: get-face-handle child + cvalues: get-face-values chwnd + cofs: as red-pair! cvalues + FACE_OBJ_OFFSET + imprint-layers-deep + dc chwnd + bx + dpi-scale cofs/x + by + dpi-scale cofs/y + cvalues + ] + child: child + 1 + ] + ] + ] +] + From 35a023f609484bc309c66950efb6b96ce228b4da Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 17:22:45 +0100 Subject: [PATCH 0843/3432] FIX: hex literals ending not always checked for illegal characters. --- docs/lexer/lexer-FSM.csv | 5 +- docs/lexer/lexer-FSM.xlsx | Bin 19893 -> 18812 bytes docs/lexer/lexer-states.txt | 1 + runtime/lexer-transitions.reds | 136 +++++++++++++++--------------- runtime/lexer.reds | 2 +- tests/source/units/lexer-test.red | 2 + utils/generate-lexer-table.red | 103 +++++++++++----------- 7 files changed, 128 insertions(+), 121 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index df2135d945..e01924a524 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -18,10 +18,10 @@ S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_C S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;T_HEX;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_HEX_END2;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_HEX;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE @@ -34,6 +34,7 @@ S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY; S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX +S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index e1d1b6bf4622e85bef66ee4ccd9559e6acedeb08..9a0042a2dd68aae0f60f2dd0ab9d7e22cc98b96d 100644 GIT binary patch delta 10978 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 RvBDLRQCe(x^2!%)_&+$xynz4! delta 12155 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 GkNzL3?(?hw diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 619745ca4b..df5d29548b 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -37,6 +37,7 @@ S_MONEY S_MONEY_DEC S_HEX S_HEX_END +S_HEX_END2 S_LESSER S_TAG S_TAG_STR diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index adb3804e74..3a04d91bac 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -37,6 +37,7 @@ Red/System [ S_MONEY_DEC S_HEX S_HEX_END + S_HEX_END2 S_LESSER S_TAG S_TAG_STR @@ -91,73 +92,74 @@ Red/System [ ] type-table: #{ 0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 -330B0F2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000000000000000070000 -00000B0000140708290A260C0C272F252B332C092D0B +330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00000000000000000700 +0000000B0000140708290A260C0C272F252B332C092D0B } transitions: #{ -0000131338393A3B3C37020C2A2A2B2B2B2B212B210B37232B2B06370137281E -2727372B2B373601410101010101010101010101010101010101010101010101 -0101010101010101010101013736020202020202020202024602020202020202 -0202020202020202020202020202020203020237370202020202020202020202 -0202020202020202020202020202020202020202020202020202373604040404 -040404043C3D0404040404040404040404040404040404040404040404040504 -0437370404040404040404040404040404040404040404040404040404040404 -04040404040404043736434307074343434343430A0707430707070707070707 -0707070707074343070707070707073743474707074747474747473707074707 -0707070707070707070707080747470707070707070737470707090937373737 -3737373737373737370909090937373737373737373737373737373737373707 -0707073737373737373737373737373709090707373737373737373737373737 -3737373737470A0A0A0A0A0A0A0A0A0A470A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A373744440B0B444444444444440B0B0B0B0B0B0B0B -0B0B2B0B0B0B0B0B0B44440B0B0B0B0B0B0B37444545121211373E370D370F12 -1237121212121212121212373737123745451212121212121237450D0D0D0D37 -3737373748373737370D0D0D0D0D0D0D0D3737370D37370E3737370D3737370D -37370E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E37360F0F0F0F0F0F0F0F0F0F490F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F37490F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3737111111111140111111 -1111111111111111111111111111111111111111111111111111111137374545 -1212454545454545451212121212121212121212121212121212454512121212 -121212374542421313424242424242420C131A1C19551516372119374237374A -14422E1437371937373737424B4B15154B4B4B4B4B4B4B1715371C3737151537 -374B374B37374A374B3737373737373737374B4B4B15154B4B4B4B4B4B4B3737 -4B373737151537374B374B37374A37372E18371515373737374B4B4B16164B4B -4B4B4B4B4B37374B373755152137214B374B37374A37372E1837151537373737 -4B4B4B4B4C4C4C4C4C4C4C4C174C4C171717171717174C4C4C17174C4C4C4C17 -4C17174C1717374C4D4D18184D4D4D4D4D4D4D37374D373737373737374D374D -37373737373718373737373737374D4E4E19194E4E4E4E4E4E4E191919191919 -1919191919194E19194E194E4E194E19194E3719374E37371B1B373737373737 -373737373737373737373737373737373737373737373737373737373750501B -1B5050505050505037371B373737373737375037503737373750371B37373737 -3737375037371D1D373737373737373737373737373737373737373737373737 -372E37371D1D37373737374F4F1D1D4F4F4F4F4F4F4F37374F3737371D1D3737 -4F374F373737374F2E1D373737373737374F37371F1F37373737373737373737 -3737373737373737373737373737373737373737373737373751511F1F515151 -51515151511F5137373737373737513751373737375137203737373737373736 -5151202051515151515151512051373737373737375137513737373751373737 -373737373737364343212143434343434343372B2C2B2B222B212B213F432B2B -2B3737432E2B1F2B2B2B2B2B374355552B2B55555555555555372B2C2B2B2B2B -2B2B2B3F552B2B2B3737552E2B1F2B2B2B2B2B37554343242443434343434343 -2424432424242424242424242B2B2B2424434324242424242424374324242424 -2424242424242524262424242424242424242424522424242424242424242424 -2437372525252525252525252524252525252525252525252525252525252525 -2525252525252525373726262626262626262626262624262626262626262626 -2626262626262626262626262626263737434313134343434343434337372B2B -2B2B2B2B2B2B2B43372B2B372B432B282B2B2B372B2B37434343292943434343 -434343372B2C2B2B2B29292B2B3F432B2B2B3737432E2B3729292B2B2B37434B -4B29294B4B4B4B4B4B4B37374B1C3737292937374B374B37374A373737373729 -29373737374B37373737373737373737373737372B2B2B2B2B2B2B0B372B2B2B -373737372B372B2B372B2B373743432B2B43434343434343372B2C2B2B2B2B2B -2B2B3F432B2B2B3737432E2B1F2B2B2B2B2B374343432D2D434343434343432D -2D2D2D2D2D2D2D2D2D2D43372D2D2D2D432D2D2D2D2D2D2D2D374353532D2D53 -5353535353532D372D2D2D2D2D2D2D2D2D5353372D2D53532D2D372D2D372D2D -375354542E2E545454545454543737372E2E2E2E2E2E2E54545437372E375437 -2E372E2E372E2E37543737303037373A3B373702333131323232323232323737 -2332323737372E32373434373232373742423030424242424242423713421C37 -371515373742374237374A14422E143737373737373742373737373737373737 -3737373737323232323232323737323232373737373237323237323237374343 -3232434343434343433732433232323232323243433232323737432E32373232 -3232323743454512121137373737370F12123712121212121212121237373712 -374545121212121212123745434330304343434343434337372B2B2B2B2B2B2B -2B2B43372B2B372B432B2B2B2B2B372B2B3743 +00001313393A3B3C3D38020C2B2B2C2C2C2C212C210B38242C2C06380138291E +2828382C2C383701420101010101010101010101010101010101010101010101 +0101010101010101010101013837020202020202020202024702020202020202 +0202020202020202020202020202020203020238380202020202020202020202 +0202020202020202020202020202020202020202020202020202383704040404 +040404043D3E0404040404040404040404040404040404040404040404040504 +0438380404040404040404040404040404040404040404040404040404040404 +04040404040404043837444407074444444444440A0707440707070707070707 +0707070707074444070707070707073844484807074848484848483807074807 +0707070707070707070707080748480707070707070738480707090938383838 +3838383838383838380909090938383838383838383838383838383838383807 +0707073838383838383838383838383809090707383838383838383838383838 +3838383838480A0A0A0A0A0A0A0A0A0A480A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A383845450B0B454545454545450B0B0B0B0B0B0B0B +0B0B2C0B0B0B0B0B0B45450B0B0B0B0B0B0B38454646121211383F380D380F12 +1238121212121212121212383838123846461212121212121238460D0D0D0D38 +3838383849383838380D0D0D0D0D0D0D0D3838380D38380E3838380D3838380D +38380E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E38370F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F384A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3838111111111141111111 +1111111111111111111111111111111111111111111111111111111138384646 +1212464646464646461212121212121212121212121212121212464612121212 +121212384643431313434343434343430C131A1C19231516382119384338384B +14432F1438381938383838434C4C15154C4C4C4C4C4C4C1715381C3838151538 +384C384C38384B384C3838383838383838384C4C4C15154C4C4C4C4C4C4C3838 +4C383838151538384C384C38384B38382F18381515383838384C4C4C16164C4C +4C4C4C4C4C38384C383823152138214C384C38384B38382F1838151538383838 +4C4C4C4C4D4D4D4D4D4D4D4D174D4D171717171717174D4D4D17174D4D4D4D17 +4D17174D1717384D4E4E18184E4E4E4E4E4E4E38384E383838383838384E384E +38383838383818383838383838384E4F4F19194F4F4F4F4F4F4F191919191919 +1919191919194F19194F194F4F194F19194F3819384F38381B1B383838383838 +383838383838383838383838383838383838383838383838383838383851511B +1B5151515151515138381B383838383838385138513838383851381B38383838 +3838385138381D1D383838383838383838383838383838383838383838383838 +382F38381D1D383838383850501D1D505050505050503838503838381D1D3838 +50385038383838502F1D383838383838385038381F1F38383838383838383838 +3838383838383838383838383838383838383838383838383852521F1F525252 +52525252521F5238383838383838523852383838385238203838383838383837 +5252202052525252525252522052383838383838385238523838383852383838 +383838383838374444212144444444444444382C2D2C2C222C212C2140442C2C +2C3838442F2C1F2C2C2C2C2C384456562C2C56565656565656382C2D2C2C2C2C +2C2C2C40562C2C2C3838562F2C1F2C2C2C2C2C38565656383856565656565656 +3838383838383838383840565638383838562F381F3838383838385644442525 +444444444444442525442525252525252525252C2C2C25254444252525252525 +2538442525252525252525252526252725252525252525252525255325252525 +2525252525252525383826262626262626262626252626262626262626262626 +2626262626262626262626262626263838272727272727272727272727252727 +2727272727272727272727272727272727272727272738384444131344444444 +44444438382C2C2C2C2C2C2C2C2C44382C2C382C442C292C2C2C382C2C384444 +442A2A44444444444444382C2D2C2C2C2A2A2C2C40442C2C2C3838442F2C382A +2A2C2C2C38444C4C2A2A4C4C4C4C4C4C4C38384C1C38382A2A38384C384C3838 +4B38383838382A2A383838384C38383838383838383838383838382C2C2C2C2C +2C2C0B382C2C2C383838382C382C2C382C2C383844442C2C4444444444444438 +2C2D2C2C2C2C2C2C2C40442C2C2C3838442F2C1F2C2C2C2C2C384444442E2E44 +4444444444442E2E2E2E2E2E2E2E2E2E2E44382E2E2E2E442E2E2E2E2E2E2E2E +384454542E2E545454545454542E382E2E2E2E2E2E2E2E2E5454382E2E54542E +2E382E2E382E2E385455552F2F555555555555553838382F2F2F2F2F2F2F5555 +5538382F3855382F382F2F382F2F38553838313138383B3C3838023432323333 +333333333338382433333838382F333835353833333838434331314343434343 +43433813431C38381515383843384338384B14432F1438383838383838433838 +3838383838383838383838383333333333333338383333333838383833383333 +3833333838444433334444444444444438334433333333333333444433333338 +38442F333833333333333844464612121138383838380F121238121212121212 +1212123838381238464612121212121212384644443131444444444444443838 +2C2C2C2C2C2C2C2C2C44382C2C382C442C2C2C2C2C382C2C3844 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 76ccb400b3..f0647bea97 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -97,7 +97,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000 } path-ending: #{ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index b7c5f1fe0d..5cb11d19db 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -332,6 +332,8 @@ Red [ } --assert out == [--assert 0:00:15.0 == (10:00.0 % 0:45.0)] + --test-- "tr-28" --assert error? try [transcode "2hello"] + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 1aff5087e2..076f54f2cc 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -48,57 +48,58 @@ context [ S_MONEY_DEC TYPE_MONEY ;-- 32 S_HEX TYPE_INTEGER ;-- 33 S_HEX_END TYPE_WORD ;-- 34 - S_LESSER TYPE_TAG ;-- 35 - S_TAG TYPE_TAG ;-- 36 - S_TAG_STR TYPE_TAG ;-- 37 - S_TAG_STR2 TYPE_TAG ;-- 38 - S_SIGN TYPE_WORD ;-- 39 - S_DOTWORD TYPE_WORD ;-- 40 - S_DOTDEC TYPE_FLOAT ;-- 41 - S_WORD_1ST TYPE_WORD ;-- 42 - S_WORD TYPE_WORD ;-- 43 - S_WORDSET TYPE_SET_WORD ;-- 44 - S_URL TYPE_URL ;-- 45 - S_EMAIL TYPE_EMAIL ;-- 46 - S_PATH TYPE_PATH ;-- 47 - S_PATH_NUM TYPE_INTEGER ;-- 48 - S_PATH_W1ST TYPE_WORD ;-- 49 - S_PATH_WORD TYPE_WORD ;-- 50 - S_PATH_SHARP TYPE_ISSUE ;-- 51 - S_PATH_SIGN TYPE_WORD ;-- 52 - --EXIT_STATES-- - ;-- 53 - T_EOF - ;-- 54 - T_ERROR - ;-- 55 - T_BLK_OP - ;-- 56 - T_BLK_CL - ;-- 57 - T_PAR_OP - ;-- 58 - T_PAR_CL - ;-- 59 - T_MSTR_OP - ;-- 60 - T_MSTR_CL TYPE_STRING ;-- 61 - T_MAP_OP - ;-- 62 - T_PATH - ;-- 63 - T_CONS_MK - ;-- 64 - T_CMT - ;-- 65 - T_INTEGER TYPE_INTEGER ;-- 66 - T_WORD - ;-- 67 - T_REFINE - ;-- 68 - T_ISSUE TYPE_ISSUE ;-- 69 - T_STRING TYPE_STRING ;-- 70 - T_FILE TYPE_FILE ;-- 71 - T_BINARY TYPE_BINARY ;-- 72 - T_CHAR TYPE_CHAR ;-- 73 - T_PERCENT TYPE_PERCENT ;-- 74 - T_FLOAT TYPE_FLOAT ;-- 75 - T_FLOAT_SP TYPE_FLOAT ;-- 76 - T_TUPLE TYPE_TUPLE ;-- 77 - T_DATE TYPE_DATE ;-- 78 - T_PAIR TYPE_PAIR ;-- 79 - T_TIME TYPE_TIME ;-- 80 - T_MONEY TYPE_MONEY ;-- 81 - T_TAG TYPE_TAG ;-- 82 - T_URL TYPE_URL ;-- 83 - T_EMAIL TYPE_EMAIL ;-- 84 - T_HEX TYPE_INTEGER ;-- 85 + S_HEX_END2 TYPE_INTEGER ;-- 35 + S_LESSER TYPE_TAG ;-- 36 + S_TAG TYPE_TAG ;-- 37 + S_TAG_STR TYPE_TAG ;-- 38 + S_TAG_STR2 TYPE_TAG ;-- 39 + S_SIGN TYPE_WORD ;-- 40 + S_DOTWORD TYPE_WORD ;-- 41 + S_DOTDEC TYPE_FLOAT ;-- 42 + S_WORD_1ST TYPE_WORD ;-- 43 + S_WORD TYPE_WORD ;-- 44 + S_WORDSET TYPE_SET_WORD ;-- 45 + S_URL TYPE_URL ;-- 46 + S_EMAIL TYPE_EMAIL ;-- 47 + S_PATH TYPE_PATH ;-- 48 + S_PATH_NUM TYPE_INTEGER ;-- 49 + S_PATH_W1ST TYPE_WORD ;-- 50 + S_PATH_WORD TYPE_WORD ;-- 51 + S_PATH_SHARP TYPE_ISSUE ;-- 52 + S_PATH_SIGN TYPE_WORD ;-- 53 + --EXIT_STATES-- - ;-- 54 + T_EOF - ;-- 55 + T_ERROR - ;-- 56 + T_BLK_OP - ;-- 57 + T_BLK_CL - ;-- 58 + T_PAR_OP - ;-- 59 + T_PAR_CL - ;-- 60 + T_MSTR_OP - ;-- 61 + T_MSTR_CL TYPE_STRING ;-- 62 + T_MAP_OP - ;-- 63 + T_PATH - ;-- 64 + T_CONS_MK - ;-- 65 + T_CMT - ;-- 66 + T_INTEGER TYPE_INTEGER ;-- 67 + T_WORD - ;-- 68 + T_REFINE - ;-- 69 + T_ISSUE TYPE_ISSUE ;-- 70 + T_STRING TYPE_STRING ;-- 71 + T_FILE TYPE_FILE ;-- 72 + T_BINARY TYPE_BINARY ;-- 73 + T_CHAR TYPE_CHAR ;-- 74 + T_PERCENT TYPE_PERCENT ;-- 75 + T_FLOAT TYPE_FLOAT ;-- 76 + T_FLOAT_SP TYPE_FLOAT ;-- 77 + T_TUPLE TYPE_TUPLE ;-- 78 + T_DATE TYPE_DATE ;-- 79 + T_PAIR TYPE_PAIR ;-- 80 + T_TIME TYPE_TIME ;-- 81 + T_MONEY TYPE_MONEY ;-- 82 + T_TAG TYPE_TAG ;-- 83 + T_URL TYPE_URL ;-- 84 + T_EMAIL TYPE_EMAIL ;-- 85 + T_HEX TYPE_INTEGER ;-- 86 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 73ee7a45d45b897680fbbfefe85524f79baa048a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 17:33:49 +0100 Subject: [PATCH 0844/3432] FEAT: bypass error throwing when lexer in scanning mode. SCAN will return `error!` now on lexical errors. --- runtime/lexer.reds | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f0647bea97..b948b4de1f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -279,6 +279,7 @@ lexer: context [ fun-locs [integer!] ;-- number of local words in callback function in-series [red-series!] ;-- optional back reference to input series int-value [integer!] ;-- decoded integer! value (from scanner to loader) + load? [logic!] ;-- TRUE: load values, else scan only ] scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] @@ -305,6 +306,10 @@ lexer: context [ len [integer!] c [byte!] ][ + unless lex/load? [ + lex/scanned: TYPE_ERROR + throw LEX_ERR ;-- bypass errors when scanning only + ] if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [throw LEX_ERR]] e: lex/in-end len: 0 @@ -1727,16 +1732,16 @@ lexer: context [ scan-tokens: func [ lex [state!] one? [logic!] - ld? [logic!] /local cp class index state prev flags line mark offset [integer!] + term? load? ld? [logic!] p e start s [byte-ptr!] slot [cell!] - term? load? [logic!] do-scan [scanner!] do-load [loader!] ][ line: 1 + ld?: lex/load? until [ flags: 0 ;-- Scanning stage -- term?: no @@ -1854,6 +1859,7 @@ lexer: context [ lex/fun-ptr: fun lex/fun-locs: 0 lex/in-series: ser + lex/load?: load? if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no] From 34bf6019f1a4beec2dcff4f47d35e0577d68c163 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 17:58:23 +0100 Subject: [PATCH 0845/3432] FIX: issue #3606 (Strings converted to words in VID styles) --- modules/view/view.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/view.red b/modules/view/view.red index c525d09574..cf8d48377f 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -435,7 +435,7 @@ face!: object [ ;-- keep in sync with facet! enum if find [field text] type [ if word = 'text [ set-quiet 'data any [ - all [not empty? new attempt/safer [load new]] + all [not empty? new find scalar! scan new attempt/safer [load new]] all [options options/default] ] ] From 5e5032b71baa17cac72be6b4324f6175aae70cd3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 21:02:30 +0100 Subject: [PATCH 0846/3432] FIX: SCAN/NEXT sometimes stopping after a partial value. Example: scan/next "[test] hello" --- runtime/lexer.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b948b4de1f..3148e8fdb4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1805,10 +1805,10 @@ lexer: context [ check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] ] - if all [ - one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH - any [not ld? lex/tail - 1 = lex/buffer] - ][exit] ;-- early exit for single value request + if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH][ + slot: lex/tail - 1 + if all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT][exit] ;-- early exit for single value request + ] lex/in-pos >= lex/in-end ] if lex/entry = S_M_STRING [catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING]] From 05e52933464f6cdd53917b6cf2bf045aaf556a62 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 23:33:03 +0100 Subject: [PATCH 0847/3432] FIX: SCAN on path! literals can lead to infinite loops. --- runtime/lexer.reds | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3148e8fdb4..14d6b54fc4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1801,9 +1801,9 @@ lexer: context [ unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] ] - if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ - check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed - ] + ] + if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ + check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH][ slot: lex/tail - 1 From 828dd6898a231522fc7dd17d7e58a21905e66b07 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 30 Jan 2020 23:51:37 +0100 Subject: [PATCH 0848/3432] FIX: more accurate SCAN/NEXT first expression detection. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 14d6b54fc4..b12f26b609 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1807,7 +1807,10 @@ lexer: context [ ] if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH][ slot: lex/tail - 1 - if all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT][exit] ;-- early exit for single value request + if any [ + lex/tail = lex/buffer + all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT] + ][exit] ;-- early exit for single value request ] lex/in-pos >= lex/in-end ] From 0e92743bff7c5c9eac0c0830fbb8df38c28cb8b4 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 01:15:19 +0100 Subject: [PATCH 0849/3432] FIX: regression on test "tro-63". --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b12f26b609..ceb4050db9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1805,7 +1805,7 @@ lexer: context [ if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] - if all [one? lex/scanned > 0 lex/entry <> S_PATH state <> T_PATH][ + if all [one? lex/scanned > 0 lex/entry <> S_PATH lex/entry <> S_M_STRING state <> T_PATH][ slot: lex/tail - 1 if any [ lex/tail = lex/buffer From 51df254cb42582937e04dc0e3314570f5d7ee405 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 01:45:28 +0100 Subject: [PATCH 0850/3432] FIX: SCAN returns paren! instead of map! type. --- runtime/lexer.reds | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ceb4050db9..b910b62fbb 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -865,8 +865,11 @@ lexer: context [ blk [red-block!] ][ if TYPE_MAP = close-block lex s e TYPE_PAREN [ - blk: as red-block! lex/tail - 1 - map/make-at as cell! blk blk block/rs-length? blk + lex/scanned: TYPE_MAP + if lex/load? [ + blk: as red-block! lex/tail - 1 + map/make-at as cell! blk blk block/rs-length? blk + ] ] lex/in-pos: e + 1 ;-- skip ) ] From b3caf44ed08aa36ce22df8124dd00aed9622f7a7 Mon Sep 17 00:00:00 2001 From: bitbegin <bitbegin@gmail.com> Date: Fri, 31 Jan 2020 10:09:17 +0800 Subject: [PATCH 0851/3432] FIX: issue #4265 ([GTK] on-focus does not work on field) --- modules/view/backends/gtk3/handlers.reds | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 26a35d054d..37cd3cbc51 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -662,13 +662,13 @@ focus-in-event: func [ int [red-integer!] sym [integer!] ][ - if evbox <> gtk_get_event_widget event [return EVT_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE int: as red-integer! values + FACE_OBJ_SELECTED sym: symbol/resolve type/symbol if sym = window [ + if evbox <> gtk_get_event_widget event [return EVT_DISPATCH] unless null? GET-RESIZING(widget) [ make-event widget 0 EVT_SIZING make-event widget 0 EVT_SIZE @@ -694,7 +694,6 @@ focus-out-event: func [ type [red-word!] sym [integer!] ][ - if evbox <> gtk_get_event_widget event [return EVT_DISPATCH] face: get-face-obj widget values: object/get-values face type: as red-word! values + FACE_OBJ_TYPE From caf68d797ddaf23c579607f6dd61d6a4b38d7a77 Mon Sep 17 00:00:00 2001 From: bitbegin <bitbegin@gmail.com> Date: Fri, 31 Jan 2020 10:34:25 +0800 Subject: [PATCH 0852/3432] FIX: issue #4266 ([GTK] crash on creating FIELD with font of zero size) --- modules/view/backends/gtk3/font.reds | 7 ++++++- modules/view/backends/gtk3/gui.reds | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index fd532a5129..73bb7b0189 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -629,7 +629,12 @@ create-pango-font: func [ pango_font_description_set_family hFont name int: as red-integer! values + FONT_OBJ_SIZE - size: either TYPE_OF(int) <> TYPE_INTEGER [default-font-size][ + size: either any [ + TYPE_OF(int) <> TYPE_INTEGER + int/value <= 0 + ][ + default-font-size + ][ int/value ] pango_font_description_set_size hFont PANGO_SCALE * size diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 7b8b0773c5..011130d255 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1359,7 +1359,10 @@ font-size?: func [ if TYPE_OF(font) <> TYPE_OBJECT [return default-font-size] values: object/get-values font size: as red-integer! values + FONT_OBJ_SIZE - if TYPE_OF(size) <> TYPE_INTEGER [return default-font-size] + if any [ + TYPE_OF(size) <> TYPE_INTEGER + size/value <= 0 + ][print default-font-size return default-font-size] size/value ] From b185e107e83e0517a2f6c925c72862160280f7c9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 12:55:03 +0100 Subject: [PATCH 0853/3432] FIX: adjusts input position ending on SCAN/NEXT exit. --- runtime/lexer.reds | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b910b62fbb..f27e841fce 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -105,6 +105,10 @@ lexer: context [ 00000000000101 } + ending-skip: #{ + 0000000000000000000000000000000001000101010000000000000001000000 + } + bin16-classes: #{ 0000000000000000000101000001000000000000000000000000000000000000 0100000000000000000000000000000002020202020202020202000300000000 @@ -1813,7 +1817,10 @@ lexer: context [ if any [ lex/tail = lex/buffer all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT] - ][exit] ;-- early exit for single value request + ][ + lex/in-pos: lex/in-pos + as-integer ending-skip/index + exit ;-- early exit for single value request + ] ] lex/in-pos >= lex/in-end ] From bf2bec9d7330b79e674fb5dc4f09d5f2f7551c4c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 14:09:28 +0100 Subject: [PATCH 0854/3432] TESTS: adds SCAN tests. --- tests/source/units/lexer-test.red | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 5cb11d19db..c3abbc6b8a 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -439,6 +439,33 @@ Red [ --test-- "tn-2" --assert [[a] " 123"] == transcode/next "[a] 123" + --test-- "tn-3" + --assert [#(a: 4) " hello"] == out: transcode/next "#(a: 4) hello" + --assert map? out/1 + +===end-group=== +===start-group=== "scan" + + --test-- "scan-1" --assert (reduce [integer! " hello"]) == scan/next "123 hello" + --test-- "scan-2" --assert (reduce [block! " hello"]) == scan/next "[test] hello" + + --test-- "scan-3" --assert (reduce [percent! " hello"]) == scan/next "123% hello" + --test-- "scan-4" --assert (reduce [integer! " hello"]) == scan/next "123h hello" + --test-- "scan-5" --assert (reduce [tag! " hello"]) == scan/next "<p> hello" + --test-- "scan-6" --assert (reduce [char! " hello"]) == scan/next {#"p" hello} + --test-- "scan-7" --assert (reduce [binary! " hello"]) == scan/next {#{23} hello} + --test-- "scan-8" --assert (reduce [string! " hello"]) == scan/next {"world" hello} + + --test-- "scan-9" --assert (reduce [set-word! " hello"]) == scan/next "a: hello" + --test-- "scan-10" --assert (reduce [word! " hello"]) == scan/next "a hello" + --test-- "scan-11" --assert (reduce [lit-word! " hello"]) == scan/next "'a hello" + --test-- "scan-12" --assert (reduce [get-word! " hello"]) == scan/next ":a hello" + + --test-- "scan-13" --assert (reduce [map! " hello"]) == scan/next "#(a: 4) hello" + --test-- "scan-14" --assert (reduce [set-path! " hello"]) == scan/next "a/b: hello" + --test-- "scan-15" --assert (reduce [path! " hello"]) == scan/next "a/b hello" + --test-- "scan-16" --assert (reduce [lit-path! " hello"]) == scan/next "'a/b hello" + --test-- "scan-17" --assert (reduce [get-path! " hello"]) == scan/next ":a/b hello" ===end-group=== ===start-group=== "transcode/trace" From 414cdb325f90b3a8eec3731549f3aa05dfee2d72 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Fri, 31 Jan 2020 22:12:41 +0800 Subject: [PATCH 0855/3432] FIX: one of the issues in issue #4241 --- runtime/call.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/call.reds b/runtime/call.reds index 32e5109332..9ce170a070 100644 --- a/runtime/call.reds +++ b/runtime/call.reds @@ -317,7 +317,6 @@ ext-process: context [ s-inf/dwFlags: STARTF_USESTDHANDLES ] unless console? [ - if in-buf = null [ s-inf/hStdInput: 0 ] inherit: true s-inf/dwFlags: STARTF_USESTDHANDLES ] From 6b57c1edcd7ce57a3fbe386089d99d2ce3e10646 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 19:05:05 +0100 Subject: [PATCH 0856/3432] FEAT: better handling of ///... tokens. --- docs/lexer/lexer-FSM.csv | 3 +- docs/lexer/lexer-FSM.xlsx | Bin 18812 -> 18992 bytes runtime/lexer-transitions.reds | 141 +++++++++++++++--------------- runtime/lexer.reds | 21 +---- utils/generate-lexer-table.red | 151 +++++++++++++++++---------------- 5 files changed, 152 insertions(+), 164 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index e01924a524..aadd8c368a 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -10,7 +10,8 @@ S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_E S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_WORD;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH_N;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE +S_SLASH_N;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH_N;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;T_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 9a0042a2dd68aae0f60f2dd0ab9d7e22cc98b96d..6b8ee1a1959d4fe4a9778c2136fcff48d211d548 100644 GIT binary patch delta 10808 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 delta 10634 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 3a04d91bac..e802e58443 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -14,6 +14,7 @@ Red/System [ S_FILE_HEX2 S_FILE_STR S_SLASH + S_SLASH_N S_SHARP S_BINARY S_LINE_CMT2 @@ -91,75 +92,77 @@ Red/System [ T_HEX ] type-table: #{ -0000070707070808080808131429000A0A00140B0C0C0C0C272F2B2B25253333 -330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00000000000000000700 -0000000B0000140708290A260C0C272F252B332C092D0B +0000070707070808080808130F1429000A0A00140B0C0C0C0C272F2B2B252533 +33330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 +000000000B0013140708290A260C0C272F252B332C092D0B } transitions: #{ -00001313393A3B3C3D38020C2B2B2C2C2C2C212C210B38242C2C06380138291E -2828382C2C383701420101010101010101010101010101010101010101010101 -0101010101010101010101013837020202020202020202024702020202020202 -0202020202020202020202020202020203020238380202020202020202020202 -0202020202020202020202020202020202020202020202020202383704040404 -040404043D3E0404040404040404040404040404040404040404040404040504 -0438380404040404040404040404040404040404040404040404040404040404 -04040404040404043837444407074444444444440A0707440707070707070707 -0707070707074444070707070707073844484807074848484848483807074807 -0707070707070707070707080748480707070707070738480707090938383838 -3838383838383838380909090938383838383838383838383838383838383807 -0707073838383838383838383838383809090707383838383838383838383838 -3838383838480A0A0A0A0A0A0A0A0A0A480A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A383845450B0B454545454545450B0B0B0B0B0B0B0B -0B0B2C0B0B0B0B0B0B45450B0B0B0B0B0B0B38454646121211383F380D380F12 -1238121212121212121212383838123846461212121212121238460D0D0D0D38 -3838383849383838380D0D0D0D0D0D0D0D3838380D38380E3838380D3838380D -38380E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E38370F0F0F0F0F0F0F0F0F0F4A0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F100F0F384A0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3838111111111141111111 -1111111111111111111111111111111111111111111111111111111138384646 -1212464646464646461212121212121212121212121212121212464612121212 -121212384643431313434343434343430C131A1C19231516382119384338384B -14432F1438381938383838434C4C15154C4C4C4C4C4C4C1715381C3838151538 -384C384C38384B384C3838383838383838384C4C4C15154C4C4C4C4C4C4C3838 -4C383838151538384C384C38384B38382F18381515383838384C4C4C16164C4C -4C4C4C4C4C38384C383823152138214C384C38384B38382F1838151538383838 -4C4C4C4C4D4D4D4D4D4D4D4D174D4D171717171717174D4D4D17174D4D4D4D17 -4D17174D1717384D4E4E18184E4E4E4E4E4E4E38384E383838383838384E384E -38383838383818383838383838384E4F4F19194F4F4F4F4F4F4F191919191919 -1919191919194F19194F194F4F194F19194F3819384F38381B1B383838383838 -383838383838383838383838383838383838383838383838383838383851511B -1B5151515151515138381B383838383838385138513838383851381B38383838 -3838385138381D1D383838383838383838383838383838383838383838383838 -382F38381D1D383838383850501D1D505050505050503838503838381D1D3838 -50385038383838502F1D383838383838385038381F1F38383838383838383838 -3838383838383838383838383838383838383838383838383852521F1F525252 -52525252521F5238383838383838523852383838385238203838383838383837 -5252202052525252525252522052383838383838385238523838383852383838 -383838383838374444212144444444444444382C2D2C2C222C212C2140442C2C -2C3838442F2C1F2C2C2C2C2C384456562C2C56565656565656382C2D2C2C2C2C -2C2C2C40562C2C2C3838562F2C1F2C2C2C2C2C38565656383856565656565656 -3838383838383838383840565638383838562F381F3838383838385644442525 -444444444444442525442525252525252525252C2C2C25254444252525252525 -2538442525252525252525252526252725252525252525252525255325252525 -2525252525252525383826262626262626262626252626262626262626262626 -2626262626262626262626262626263838272727272727272727272727252727 -2727272727272727272727272727272727272727272738384444131344444444 -44444438382C2C2C2C2C2C2C2C2C44382C2C382C442C292C2C2C382C2C384444 -442A2A44444444444444382C2D2C2C2C2A2A2C2C40442C2C2C3838442F2C382A -2A2C2C2C38444C4C2A2A4C4C4C4C4C4C4C38384C1C38382A2A38384C384C3838 -4B38383838382A2A383838384C38383838383838383838383838382C2C2C2C2C -2C2C0B382C2C2C383838382C382C2C382C2C383844442C2C4444444444444438 -2C2D2C2C2C2C2C2C2C40442C2C2C3838442F2C1F2C2C2C2C2C384444442E2E44 -4444444444442E2E2E2E2E2E2E2E2E2E2E44382E2E2E2E442E2E2E2E2E2E2E2E -384454542E2E545454545454542E382E2E2E2E2E2E2E2E2E5454382E2E54542E -2E382E2E382E2E385455552F2F555555555555553838382F2F2F2F2F2F2F5555 -5538382F3855382F382F2F382F2F38553838313138383B3C3838023432323333 -333333333338382433333838382F333835353833333838434331314343434343 -43433813431C38381515383843384338384B14432F1438383838383838433838 -3838383838383838383838383333333333333338383333333838383833383333 -3833333838444433334444444444444438334433333333333333444433333338 -38442F333833333333333844464612121138383838380F121238121212121212 -1212123838381238464612121212121212384644443131444444444444443838 -2C2C2C2C2C2C2C2C2C44382C2C382C442C2C2C2C2C382C2C3844 +000014143A3B3C3D3E39020D2C2C2D2D2D2D222D220B39252D2D063901392A1F +2929392D2D393801430101010101010101010101010101010101010101010101 +0101010101010101010101013938020202020202020202024802020202020202 +0202020202020202020202020202020203020239390202020202020202020202 +0202020202020202020202020202020202020202020202020202393804040404 +040404043E3F0404040404040404040404040404040404040404040404040504 +0439390404040404040404040404040404040404040404040404040404040404 +04040404040404043938454507074545454545450A0707450707070707070707 +0707070707074545070707070707073945494907074949494949493907074907 +0707070707070707070707080749490707070707070739490707090939393939 +3939393939393939390909090939393939393939393939393939393939393907 +0707073939393939393939393939393909090707393939393939393939393939 +3939393939490A0A0A0A0A0A0A0A0A0A490A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A393946460B0B464646464646460B0B0B0B0B0B0B0B +0B0B0C0B0B0B0B0B0B46460B0B0B0B0B0B0B394645452D2D4545454545454539 +2D2D2D2D2D2D2D2D2D0C2D2D2D2D392D45452D392D2D2D2D2D39454747131312 +3940390E39101313391313131313131313133939391339474713131313131313 +39470E0E0E0E39393939394A393939390E0E0E0E0E0E0E0E3939390E39390F39 +39390E3939390E39390F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F3938101010101010101010104B1010101010 +101010101010101010101010101010101010111010394B101010101010101010 +1010101010101010101010101010101010101010101010101010101039391212 +1212124212121212121212121212121212121212121212121212121212121212 +1212123939474713134747474747474713131313131313131313131313131313 +13474713131313131313394744441414444444444444440D141B1D1A24161739 +221A394439394C1544301539391A39393939444D4D16164D4D4D4D4D4D4D1816 +391D3939161639394D394D39394C394D3939393939393939394D4D4D16164D4D +4D4D4D4D4D39394D393939161639394D394D39394C3939301939161639393939 +4D4D4D17174D4D4D4D4D4D4D39394D393924162239224D394D39394C39393019 +391616393939394D4D4D4D4E4E4E4E4E4E4E4E184E4E181818181818184E4E4E +18184E4E4E4E184E18184E1818394E4F4F19194F4F4F4F4F4F4F39394F393939 +393939394F394F39393939393919393939393939394F50501A1A505050505050 +501A1A1A1A1A1A1A1A1A1A1A1A501A1A501A50501A501A1A50391A395039391C +1C39393939393939393939393939393939393939393939393939393939393939 +3939393952521C1C5252525252525239391C3939393939393952395239393939 +52391C393939393939395239391E1E3939393939393939393939393939393939 +39393939393939393039391E1E393939393951511E1E51515151515151393951 +3939391E1E39395139513939393951301E393939393939395139392020393939 +3939393939393939393939393939393939393939393939393939393939393939 +5353202053535353535353532053393939393939395339533939393953392139 +3939393939393853532121535353535353535321533939393939393953395339 +39393953393939393939393939384545222245454545454545392D2E2D2D232D +222D2241452D2D2D393945302D202D2D2D2D2D394557572D2D57575757575757 +392D2E2D2D2D2D2D2D2D41572D2D2D393957302D202D2D2D2D2D395757573939 +5757575757575739393939393939393939415757393939395730392039393939 +39395745452626454545454545452626452626262626262626262D2D2D262645 +4526262626262626394526262626262626262626272628262626262626262626 +2626542626262626262626262626263939272727272727272727272627272727 +2727272727272727272727272727272727272727272739392828282828282828 +2828282826282828282828282828282828282828282828282828282828393945 +4514144545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D +2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D +393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1D39392B2B +39394D394D39394C39393939392B2B393939394D393939393939393939393939 +39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45 +454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D202D2D2D2D2D +394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F +2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55 +55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030 +30303030305656563939303956393039303039303039563939323239393C3D39 +3902353333343434343434343939253434393939303439363639343439394444 +3232444444444444443914441D39391616393944394439394C15443015393939 +3939393944393939393939393939393939393934343434343434393934343439 +3939393439343439343439394545343445454545454545393445343434343434 +3445453434343939453034393434343434394547471313123939393939101313 +3913131313131313131339393913394747131313131313133947454532324545 +454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39 +45 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index f27e841fce..4905caf631 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -97,7 +97,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000 } path-ending: #{ @@ -1002,24 +1002,7 @@ lexer: context [ if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] type: TYPE_LIT_WORD ] - if all [s/1 = #"/" type = TYPE_WORD][ ;-- //... - p: s + 1 - while [all [p < e p/1 = #"/"]][p: p + 1] - if p < e [throw-error lex s e TYPE_REFINEMENT] - ] - lex/scanned: type - ] - - scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - type [integer!] - ][ - assert s/1 = #"/" - type: either s + 1 = e [TYPE_WORD][ - either s/2 = #"/" [TYPE_WORD][TYPE_REFINEMENT] ;-- //... - ] lex/scanned: type - lex/exit: T_WORD ;-- route to load-word ] scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -1971,7 +1954,7 @@ lexer: context [ :scan-comment null ;-- T_CMT :scan-integer :load-integer ;-- T_INTEGER :scan-word :load-word ;-- T_WORD - :scan-refinement :load-word ;-- T_REFINE + null :load-word ;-- T_REFINE null :load-word ;-- T_ISSUE null :load-string ;-- T_STRING null :load-file ;-- T_FILE diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 076f54f2cc..134636df20 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -25,81 +25,82 @@ context [ S_FILE_HEX2 TYPE_FILE ;-- 9 S_FILE_STR TYPE_FILE ;-- 10 S_SLASH TYPE_REFINEMENT ;-- 11 - S_SHARP TYPE_ISSUE ;-- 12 - S_BINARY TYPE_BINARY ;-- 13 - S_LINE_CMT2 TYPE_VALUE ;-- 14 - S_CHAR TYPE_CHAR ;-- 15 - S_SKIP_CHAR TYPE_CHAR ;-- 16 - S_CONSTRUCT TYPE_VALUE ;-- 17 - S_ISSUE TYPE_ISSUE ;-- 18 - S_NUMBER TYPE_INTEGER ;-- 19 - S_DOTNUM TYPE_FLOAT ;-- 20 - S_DECIMAL TYPE_FLOAT ;-- 21 - S_DECX TYPE_FLOAT ;-- 22 - S_DEC_SPECIAL TYPE_FLOAT ;-- 23 - S_TUPLE TYPE_TUPLE ;-- 24 - S_DATE TYPE_DATE ;-- 25 - S_TIME_1ST TYPE_TIME ;-- 26 - S_TIME TYPE_TIME ;-- 27 - S_PAIR_1ST TYPE_PAIR ;-- 28 - S_PAIR TYPE_PAIR ;-- 29 - S_MONEY_1ST TYPE_MONEY ;-- 30 - S_MONEY TYPE_MONEY ;-- 31 - S_MONEY_DEC TYPE_MONEY ;-- 32 - S_HEX TYPE_INTEGER ;-- 33 - S_HEX_END TYPE_WORD ;-- 34 - S_HEX_END2 TYPE_INTEGER ;-- 35 - S_LESSER TYPE_TAG ;-- 36 - S_TAG TYPE_TAG ;-- 37 - S_TAG_STR TYPE_TAG ;-- 38 - S_TAG_STR2 TYPE_TAG ;-- 39 - S_SIGN TYPE_WORD ;-- 40 - S_DOTWORD TYPE_WORD ;-- 41 - S_DOTDEC TYPE_FLOAT ;-- 42 - S_WORD_1ST TYPE_WORD ;-- 43 - S_WORD TYPE_WORD ;-- 44 - S_WORDSET TYPE_SET_WORD ;-- 45 - S_URL TYPE_URL ;-- 46 - S_EMAIL TYPE_EMAIL ;-- 47 - S_PATH TYPE_PATH ;-- 48 - S_PATH_NUM TYPE_INTEGER ;-- 49 - S_PATH_W1ST TYPE_WORD ;-- 50 - S_PATH_WORD TYPE_WORD ;-- 51 - S_PATH_SHARP TYPE_ISSUE ;-- 52 - S_PATH_SIGN TYPE_WORD ;-- 53 - --EXIT_STATES-- - ;-- 54 - T_EOF - ;-- 55 - T_ERROR - ;-- 56 - T_BLK_OP - ;-- 57 - T_BLK_CL - ;-- 58 - T_PAR_OP - ;-- 59 - T_PAR_CL - ;-- 60 - T_MSTR_OP - ;-- 61 - T_MSTR_CL TYPE_STRING ;-- 62 - T_MAP_OP - ;-- 63 - T_PATH - ;-- 64 - T_CONS_MK - ;-- 65 - T_CMT - ;-- 66 - T_INTEGER TYPE_INTEGER ;-- 67 - T_WORD - ;-- 68 - T_REFINE - ;-- 69 - T_ISSUE TYPE_ISSUE ;-- 70 - T_STRING TYPE_STRING ;-- 71 - T_FILE TYPE_FILE ;-- 72 - T_BINARY TYPE_BINARY ;-- 73 - T_CHAR TYPE_CHAR ;-- 74 - T_PERCENT TYPE_PERCENT ;-- 75 - T_FLOAT TYPE_FLOAT ;-- 76 - T_FLOAT_SP TYPE_FLOAT ;-- 77 - T_TUPLE TYPE_TUPLE ;-- 78 - T_DATE TYPE_DATE ;-- 79 - T_PAIR TYPE_PAIR ;-- 80 - T_TIME TYPE_TIME ;-- 81 - T_MONEY TYPE_MONEY ;-- 82 - T_TAG TYPE_TAG ;-- 83 - T_URL TYPE_URL ;-- 84 - T_EMAIL TYPE_EMAIL ;-- 85 - T_HEX TYPE_INTEGER ;-- 86 + S_SLASH_N TYPE_WORD ;-- 12 + S_SHARP TYPE_ISSUE ;-- 13 + S_BINARY TYPE_BINARY ;-- 14 + S_LINE_CMT2 TYPE_VALUE ;-- 15 + S_CHAR TYPE_CHAR ;-- 16 + S_SKIP_CHAR TYPE_CHAR ;-- 17 + S_CONSTRUCT TYPE_VALUE ;-- 18 + S_ISSUE TYPE_ISSUE ;-- 19 + S_NUMBER TYPE_INTEGER ;-- 20 + S_DOTNUM TYPE_FLOAT ;-- 21 + S_DECIMAL TYPE_FLOAT ;-- 22 + S_DECX TYPE_FLOAT ;-- 23 + S_DEC_SPECIAL TYPE_FLOAT ;-- 24 + S_TUPLE TYPE_TUPLE ;-- 25 + S_DATE TYPE_DATE ;-- 26 + S_TIME_1ST TYPE_TIME ;-- 27 + S_TIME TYPE_TIME ;-- 28 + S_PAIR_1ST TYPE_PAIR ;-- 29 + S_PAIR TYPE_PAIR ;-- 30 + S_MONEY_1ST TYPE_MONEY ;-- 31 + S_MONEY TYPE_MONEY ;-- 32 + S_MONEY_DEC TYPE_MONEY ;-- 33 + S_HEX TYPE_INTEGER ;-- 34 + S_HEX_END TYPE_WORD ;-- 35 + S_HEX_END2 TYPE_INTEGER ;-- 36 + S_LESSER TYPE_TAG ;-- 37 + S_TAG TYPE_TAG ;-- 38 + S_TAG_STR TYPE_TAG ;-- 39 + S_TAG_STR2 TYPE_TAG ;-- 40 + S_SIGN TYPE_WORD ;-- 41 + S_DOTWORD TYPE_WORD ;-- 42 + S_DOTDEC TYPE_FLOAT ;-- 43 + S_WORD_1ST TYPE_WORD ;-- 44 + S_WORD TYPE_WORD ;-- 45 + S_WORDSET TYPE_SET_WORD ;-- 46 + S_URL TYPE_URL ;-- 47 + S_EMAIL TYPE_EMAIL ;-- 48 + S_PATH TYPE_PATH ;-- 49 + S_PATH_NUM TYPE_INTEGER ;-- 50 + S_PATH_W1ST TYPE_WORD ;-- 51 + S_PATH_WORD TYPE_WORD ;-- 52 + S_PATH_SHARP TYPE_ISSUE ;-- 53 + S_PATH_SIGN TYPE_WORD ;-- 54 + --EXIT_STATES-- - ;-- 55 + T_EOF - ;-- 56 + T_ERROR - ;-- 57 + T_BLK_OP - ;-- 58 + T_BLK_CL - ;-- 59 + T_PAR_OP - ;-- 60 + T_PAR_CL - ;-- 61 + T_MSTR_OP - ;-- 62 + T_MSTR_CL TYPE_STRING ;-- 63 + T_MAP_OP - ;-- 64 + T_PATH - ;-- 65 + T_CONS_MK - ;-- 66 + T_CMT - ;-- 67 + T_INTEGER TYPE_INTEGER ;-- 68 + T_WORD - ;-- 69 + T_REFINE TYPE_REFINEMENT ;-- 70 + T_ISSUE TYPE_ISSUE ;-- 71 + T_STRING TYPE_STRING ;-- 72 + T_FILE TYPE_FILE ;-- 73 + T_BINARY TYPE_BINARY ;-- 74 + T_CHAR TYPE_CHAR ;-- 75 + T_PERCENT TYPE_PERCENT ;-- 76 + T_FLOAT TYPE_FLOAT ;-- 77 + T_FLOAT_SP TYPE_FLOAT ;-- 78 + T_TUPLE TYPE_TUPLE ;-- 79 + T_DATE TYPE_DATE ;-- 80 + T_PAIR TYPE_PAIR ;-- 81 + T_TIME TYPE_TIME ;-- 82 + T_MONEY TYPE_MONEY ;-- 83 + T_TAG TYPE_TAG ;-- 84 + T_URL TYPE_URL ;-- 85 + T_EMAIL TYPE_EMAIL ;-- 86 + T_HEX TYPE_INTEGER ;-- 87 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 933715baacd2e86389a40693d0f62f040a81f4ef Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 19:39:49 +0100 Subject: [PATCH 0857/3432] TESTS: adds tests for lexing ///... patterns. --- tests/source/units/lexer-test.red | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index c3abbc6b8a..f4996d7ff3 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -425,8 +425,17 @@ Red [ --test-- "tro-64" --assert 1 == transcode/one "01h" --test-- "tro-65" --assert 2147483647 == transcode/one "7FFFFFFFh" --test-- "tro-66" --assert -1 == transcode/one "FFFFFFFFh" - + --test-- "tro-67" --assert word? out: transcode/one "///" --assert "///" = mold out + --test-- "tro-68" --assert word? out: transcode/one "////" --assert "////" = mold out + --test-- "tro-69" --assert set-word? out: transcode/one "//////////:" --assert "//////////:" = mold out + --test-- "tro-70" --assert lit-word? out: transcode/one "'//////////" --assert "'//////////" = mold out + --test-- "tro-71" --assert get-word? out: transcode/one "://////////" --assert "://////////" = mold out + + --test-- "tro-72" --assert lit-word? out: transcode/one "'//" --assert "'//" = mold out + --test-- "tro-73" --assert get-word? out: transcode/one "://" --assert "://" = mold out + --test-- "tro-74" --assert set-word? out: transcode/one "//:" --assert "//:" = mold out + --test-- "tro-75" --assert word? out: transcode/one "//" --assert "//" = mold out ===end-group=== ===start-group=== "transcode/next" @@ -467,6 +476,12 @@ Red [ --test-- "scan-16" --assert (reduce [lit-path! " hello"]) == scan/next "'a/b hello" --test-- "scan-17" --assert (reduce [get-path! " hello"]) == scan/next ":a/b hello" + --test-- "scan-18" --assert word! = scan "///" + --test-- "scan-19" --assert word! = scan "////" + --test-- "scan-20" --assert set-word! = scan "//////////:" + --test-- "scan-21" --assert lit-word! = scan "'//////////" + --test-- "scan-22" --assert get-word! = scan "://////////" + ===end-group=== ===start-group=== "transcode/trace" From 4e745075c503f25098992c17aebd780bbd7b31a7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 31 Jan 2020 22:48:31 +0100 Subject: [PATCH 0858/3432] FEAT: better handling of word</tag> pattern. --- runtime/lexer.reds | 12 +++++++++++- tests/source/units/lexer-test.red | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 4905caf631..3caf89802b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1227,7 +1227,7 @@ lexer: context [ type: lex/scanned assert type > 0 - if flags and flags-LG = flags-LG [ ;-- handle word<tag> cases + either flags and flags-LG = flags-LG [ ;-- handle word<tag> cases p: s while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < if p + 1 < e [ @@ -1244,6 +1244,16 @@ lexer: context [ ] ] ] + ][ + if all [flags and C_FLAG_LESSER <> 0 lex/entry = S_PATH e/0 = #"<"][ + cell: lex/tail - 1 + if TYPE_OF(cell) = TYPE_POINT [ + e: e - 1 ;-- handle word</tag> cases + lex/in-pos: e ;-- resume scanning from < + lex/entry: S_START ;-- cancel the newly opened path + lex/tail: cell + ] + ] ] if type <> TYPE_WORD [ switch type [ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index f4996d7ff3..f007669926 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -334,6 +334,16 @@ Red [ --test-- "tr-28" --assert error? try [transcode "2hello"] + --test-- "tr-29" + out: transcode "word<tag>" + --assert word? out/1 + --assert tag? out/2 + + --test-- "tr-30" + out: transcode "word</tag>" + --assert word? out/1 + --assert tag? out/2 + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" From 06170e897a1f8153f0c4f5f76cc4c66f5c9600f6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sat, 1 Feb 2020 20:52:48 +0100 Subject: [PATCH 0859/3432] FEAT: preliminary support for recursive lexer calls. Recursion happens when the lexer is invoked (`load`, `scan`, `transcode`) from a lexer event handler function. --- runtime/lexer.reds | 59 ++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3caf89802b..567e8d7a29 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -261,10 +261,10 @@ lexer: context [ state!: alias struct! [ next [state!] ;-- link to next state! structure (recursive calls) + back [state!] ;-- link to previous state! structure (recursive calls) buffer [red-value!] ;-- static or dynamic stash buffer (recursive calls) head [red-value!] tail [red-value!] - slots [integer!] input [byte-ptr!] in-end [byte-ptr!] in-pos [byte-ptr!] @@ -296,7 +296,6 @@ lexer: context [ stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number root-state: as state! 0 ;-- global entry point to state struct list - depth: 0 ;-- recursive calls depth min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer flags-LG: C_FLAG_LESSER or C_FLAG_GREATER @@ -335,8 +334,7 @@ lexer: context [ string/append-char GET_BUFFER(line) as-integer #")" lex/tail: lex/buffer ;-- clear accumulated values - depth: depth - 1 - if zero? depth [root-state: null] + if null? root-state/next [root-state: null] ;@@ do a proper clean-up before throwing switch type [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] @@ -443,22 +441,22 @@ lexer: context [ alloc-slot: func [lex [state!] return: [red-value!] /local - slot [red-value!] - size deltaH deltaT [integer!] + slot new [red-value!] + s [state!] ][ - size: lex/slots - if lex/buffer + size <= lex/tail [ - deltaH: (as-integer lex/head - lex/buffer) >> 4 - deltaT: (as-integer lex/tail - lex/buffer) >> 4 - lex/slots: size * 2 - lex/buffer: as cell! realloc as byte-ptr! lex/buffer lex/slots << 4 - if null? lex/buffer [fire [TO_ERROR(internal no-memory)]] - lex/head: lex/buffer + deltaH - lex/tail: lex/buffer + deltaT - if depth = 1 [ - stash: lex/buffer - stash-size: lex/slots + if stash + stash-size <= lex/tail [ + stash-size: stash-size * 2 + new: as cell! realloc as byte-ptr! stash stash-size << 4 + if null? new [fire [TO_ERROR(internal no-memory)]] + s: root-state + until [ + s/buffer: new + ((as-integer s/buffer - stash) >> 4) + s/head: new + ((as-integer s/head - stash) >> 4) + s/tail: new + ((as-integer s/tail - stash) >> 4) + s: s/next + null? s ] + stash: new ] slot: lex/tail slot/header: TYPE_UNSET @@ -1835,25 +1833,34 @@ lexer: context [ /local blk [red-block!] p [red-point!] + base [red-value!] slots [integer!] s [series!] + prev [state!] lex [state! value] clean-up [subroutine!] ][ - if zero? depth [root-state: lex] - depth: depth + 1 + either null? root-state [ + root-state: lex + lex/back: null + base: stash + ][ + prev: root-state + while [prev/next <> null][prev: prev/next] + prev/next: lex + lex/back: prev + base: prev/tail + ] clean-up: [ system/thrown: 0 - depth: depth - 1 - if zero? depth [root-state: null] + either null? root-state/next [root-state: null][lex/back/next: null] len/value: as-integer lex/in-pos - lex/input ] lex/next: null ;-- last element of the states linked list - lex/buffer: stash ;TBD: support dyn buffer case - lex/head: stash - lex/tail: stash - lex/slots: stash-size ;TBD: support dyn buffer case + lex/buffer: base + lex/head: base + lex/tail: base lex/input: src lex/in-end: src + size lex/in-pos: src From c9417867619ee767e2e225e674caec21882431f7 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 30 Jan 2020 16:10:12 +0100 Subject: [PATCH 0860/3432] FEAT: preliminary support for toggle widget --- modules/view/backends/platform.red | 1 + modules/view/backends/windows/gui.reds | 13 +++++++++++-- modules/view/backends/windows/win32.reds | 1 + modules/view/styles.red | 4 ++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 10896c5da2..a6d278c195 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -228,6 +228,7 @@ system/view/platform: context [ screen: symbol/make "screen" window: symbol/make "window" button: symbol/make "button" + toggle: symbol/make "toggle" check: symbol/make "check" radio: symbol/make "radio" field: symbol/make "field" diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index d9591bb30a..0bda20b9b9 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1372,6 +1372,10 @@ OS-make-view: func [ class: #u16 "RedButton" ;flags: flags or BS_PUSHBUTTON ] + sym = toggle [ + class: #u16 "RedButton" + flags: flags or BS_AUTOCHECKBOX or BS_PUSHLIKE + ] sym = check [ class: #u16 "RedButton" state: either bits and FACET_FLAGS_TRISTATE <> 0 [BS_AUTO3STATE][BS_AUTOCHECKBOX] @@ -1613,8 +1617,13 @@ OS-make-view: func [ value: get-position-value as red-float! data 100 SendMessage handle PBM_SETPOS value 0 ] - sym = check [set-logic-state handle as red-logic! data yes] - sym = radio [set-logic-state handle as red-logic! data no] + any [ + sym = toggle + sym = check + sym = radio + ][ + set-logic-state handle as red-logic! data sym = check + ] any [ sym = drop-down sym = drop-list diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index d7b559c6d2..d01ee57f28 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -239,6 +239,7 @@ Red/System [ #define BS_AUTO3STATE 00000006h #define BS_GROUPBOX 00000007h #define BS_AUTORADIOBUTTON 00000009h +#define BS_PUSHLIKE 00001000h #define EM_GETSEL 000000B0h #define EM_SETSEL 000000B1h diff --git a/modules/view/styles.red b/modules/view/styles.red index b84e4497f8..6571a09d4f 100644 --- a/modules/view/styles.red +++ b/modules/view/styles.red @@ -42,6 +42,10 @@ Red [ tabs: none line-spacing: 'default handles: none ] ] + toggle: [ + default-actor: on-change + template: [type: 'toggle size: 60x25] + ] check: [ default-actor: on-change template: [type: 'check size: 80x25] From 8283b296e6cb90a01e73fca2615f6f1dd3da45ea Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 30 Jan 2020 16:25:01 +0100 Subject: [PATCH 0861/3432] FEAT: [Windows] implement two-way binding --- modules/view/backends/windows/events.reds | 4 ++++ modules/view/backends/windows/gui.reds | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index d64ba407f3..0e65f1d499 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -645,6 +645,10 @@ process-command-event: func [ evt: case [ sym = button [EVT_CLICK] + sym = toggle [ + get-logic-state current-msg + EVT_CHANGE + ] sym = check [ if 0 <> (FACET_FLAGS_TRISTATE and get-flags as red-block! get-facet current-msg FACE_OBJ_FLAGS)[ state: as integer! SendMessage child BM_GETCHECK 0 0 diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 0bda20b9b9..31b2b468f0 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -2129,8 +2129,11 @@ change-data: func [ f: as red-float! data SendMessage hWnd PBM_SETPOS as-integer f/value * 100.0 0 ] - type = check [ - set-logic-state hWnd as red-logic! data yes + any [ + type = check + type = toggle + ][ + set-logic-state hWnd as red-logic! data type = check ] type = radio [ set-logic-state hWnd as red-logic! data no From faa45a4653be91fae9d666712b634bd2f3eb313d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 30 Jan 2020 20:01:29 +0100 Subject: [PATCH 0862/3432] FEAT: [macOS] implement two-way binding --- modules/view/backends/macOS/cocoa.reds | 3 +-- modules/view/backends/macOS/delegates.reds | 7 ++++- modules/view/backends/macOS/gui.reds | 30 +++++++++++++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/macOS/cocoa.reds b/modules/view/backends/macOS/cocoa.reds index 7f272c39ed..69b1745f1f 100644 --- a/modules/view/backends/macOS/cocoa.reds +++ b/modules/view/backends/macOS/cocoa.reds @@ -49,10 +49,9 @@ Red/System [ #define NSRoundedBezelStyle 1 #define NSRegularSquareBezelStyle 2 -#define NSToggleButton 2 +#define NSPushOnPushOffButton 1 #define NSSwitchButton 3 #define NSRadioButton 4 -#define NSMomentaryPushInButton 7 #define NSNoBorder 0 #define NSLineBorder 1 diff --git a/modules/view/backends/macOS/delegates.reds b/modules/view/backends/macOS/delegates.reds index 3cf56afc84..1539254fa6 100644 --- a/modules/view/backends/macOS/delegates.reds +++ b/modules/view/backends/macOS/delegates.reds @@ -416,7 +416,12 @@ button-click: func [ event: case [ type = button [EVT_CLICK] - type = check [get-logic-state self EVT_CHANGE] + any [ + type = toggle + type = check + ][ + get-logic-state self EVT_CHANGE + ] all [ type = radio NSOffState = objc_msgSend [self sel_getUid "state"] ;-- ignore double-click (fixes #4246) diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index 736e81f950..6ab2cdf964 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -955,11 +955,12 @@ change-data: func [ len: either size/x > size/y [size/x][size/y] objc_msgSend [hWnd sel_getUid "setDoubleValue:" f/value * (as-float len)] ] - type = check [ - set-logic-state hWnd as red-logic! data yes - ] - type = radio [ - set-logic-state hWnd as red-logic! data no + any [ + type = check + type = toggle + type = radio + ][ + set-logic-state hWnd as red-logic! data type = check ] type = tab-panel [ set-tabs hWnd values @@ -1817,8 +1818,8 @@ parse-common-opts: func [ ] ] - if type = button [ - len: either btn? [NSRegularSquareBezelStyle][NSRoundedBezelStyle] + if any [type = button type = toggle][ + len: either all [btn? type = button][NSRegularSquareBezelStyle][NSRoundedBezelStyle] objc_msgSend [hWnd sel_getUid "setBezelStyle:" len] ] ] @@ -1891,7 +1892,9 @@ OS-make-view: func [ any [ sym = text-list sym = area - ][class: "RedScrollView"] + ][ + class: "RedScrollView" + ] sym = text [class: "RedTextField"] sym = field [ class: either bits and FACET_FLAGS_PASSWORD = 0 ["RedTextField"][ @@ -1901,6 +1904,10 @@ OS-make-view: func [ sym = button [ class: "RedButton" ] + sym = toggle [ + class: "RedButton" + flags: NSPushOnPushOffButton + ] sym = check [ class: "RedButton" flags: NSSwitchButton @@ -2005,7 +2012,12 @@ OS-make-view: func [ make-text-list face obj rc menu bits and FACET_FLAGS_NO_BORDER = 0 integer/make-at values + FACE_OBJ_SELECTED 0 ] - any [sym = button sym = check sym = radio][ + any [ + sym = button + sym = toggle + sym = check + sym = radio + ][ if sym <> button [ if all [sym = check bits and FACET_FLAGS_TRISTATE <> 0][ objc_msgSend [obj sel_getUid "setAllowsMixedState:" yes] From 9764cb6dfe9cf8fb7654c55bc424851fba433653 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 15:09:26 +0100 Subject: [PATCH 0863/3432] FEAT: preliminary support for toggle widget --- modules/view/backends/gtk3/gtk.reds | 4 ++++ modules/view/backends/gtk3/gui.reds | 11 ++++++++++- modules/view/backends/platform.red | 1 + modules/view/styles.red | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index 8c35f2c043..a945369241 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1795,6 +1795,10 @@ GPtrArray!: alias struct! [ label [c-string!] return: [handle!] ] + gtk_toggle_button_new_with_label: "gtk_toggle_button_new_with_label" [ + label [c-string!] + return: [handle!] + ] gtk_toggle_button_get_active: "gtk_toggle_button_get_active" [ button [handle!] return: [logic!] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index dafdcc07e9..35cfbdd160 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1063,7 +1063,10 @@ change-data: func [ type = check [ set-logic-state widget as red-logic! data yes ] - type = radio [ + any [ + type = radio + type = toggle + ][ set-logic-state widget as red-logic! data no ] ; type = tab-panel [ @@ -1617,6 +1620,12 @@ OS-make-view: func [ ] set-logic-state widget as red-logic! data no ] + sym = toggle [ + widget: gtk_toggle_button_new_with_label caption + if TYPE_OF(img) = TYPE_IMAGE [ + change-image widget img sym + ] + ] sym = button [ widget: gtk_button_new_with_label caption if TYPE_OF(img) = TYPE_IMAGE [ diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 8d02159184..cc5baeaf9d 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -228,6 +228,7 @@ system/view/platform: context [ screen: symbol/make "screen" window: symbol/make "window" button: symbol/make "button" + toggle: symbol/make "toggle" check: symbol/make "check" radio: symbol/make "radio" field: symbol/make "field" diff --git a/modules/view/styles.red b/modules/view/styles.red index b84e4497f8..6571a09d4f 100644 --- a/modules/view/styles.red +++ b/modules/view/styles.red @@ -42,6 +42,10 @@ Red [ tabs: none line-spacing: 'default handles: none ] ] + toggle: [ + default-actor: on-change + template: [type: 'toggle size: 60x25] + ] check: [ default-actor: on-change template: [type: 'check size: 80x25] From 5db1c6353d704405b96a760fc63ff75980e8a759 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 15:09:45 +0100 Subject: [PATCH 0864/3432] FIX: remove debugging leftovers --- modules/view/backends/gtk3/gui.reds | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 35cfbdd160..9d8f7adf92 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1043,8 +1043,6 @@ change-data: func [ selected: as red-integer! values + FACE_OBJ_SELECTED type: word/symbol - ;;DEBUG: print ["change-data: " get-symbol-name type lf] - case [ all [ type = progress @@ -1103,8 +1101,6 @@ change-selection: func [ bound [GtkTextIter! value] buffer [handle!] ][ - ;; DEBUG: print ["change-selection: " widget " (" get-symbol-name type ")" lf] - if type <> window [ idx: either TYPE_OF(int) = TYPE_INTEGER [int/value - 1][-1] ] @@ -1866,7 +1862,6 @@ OS-update-view: func [ flags-flags [integer!] type [integer!] ][ - ;; DEBUG: print ["OS-update-view" lf] ctx: GET_CTX(face) s: as series! ctx/values/value values: s/offset @@ -1879,7 +1874,6 @@ OS-update-view: func [ type = rich-text update-rich-text state as red-block! values + FACE_OBJ_EXT3 ][ - ;; DEBUG: print ["update-view rich-text" lf] exit ] @@ -1920,7 +1914,6 @@ OS-update-view: func [ flags-flags: get-flags as red-block! values + FACE_OBJ_FLAGS if type = field [ if flags-flags and FACET_FLAGS_PASSWORD <> 0 [ - ;; DEBUG: print ["password flag activated for field" lf] gtk_entry_set_visibility widget no ] gtk_entry_set_has_frame widget (flags-flags and FACET_FLAGS_NO_BORDER = 0) @@ -1928,7 +1921,6 @@ OS-update-view: func [ ] if flags and FACET_FLAG_DRAW <> 0 [ gtk_widget_queue_draw widget - ; 0 ] if flags and FACET_FLAG_COLOR <> 0 [ if type <> base [ From 474f4061f797ebed255d56cc0c1d6d8f809fc860 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 15:38:46 +0100 Subject: [PATCH 0865/3432] FEAT: implement two-way binding --- modules/view/backends/gtk3/events.reds | 5 ++++- modules/view/backends/gtk3/gui.reds | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index e98eb3b3d2..e1e042816c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1002,7 +1002,10 @@ connect-widget-events: func [ gobj_signal_connect(evbox "realize" :widget-realize widget) case [ - sym = check [ + any [ + sym = check + sym = toggle + ][ check-handler: gobj_signal_connect(widget "toggled" :button-toggled widget) ;-- used to block signal ] sym = radio [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 9d8f7adf92..052adfde43 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1058,13 +1058,13 @@ change-data: func [ f: as red-float! data gtk_range_set_value widget f/value * 100.0 ] - type = check [ - set-logic-state widget as red-logic! data yes - ] any [ - type = radio + type = check type = toggle ][ + set-logic-state widget as red-logic! data yes + ] + type = radio [ set-logic-state widget as red-logic! data no ] ; type = tab-panel [ @@ -1828,7 +1828,7 @@ OS-make-view: func [ ] ] - if sym = check [ + if any [sym = check sym = toggle][ set-logic-state widget as red-logic! data yes ] From 36da717aaf6ec62ed62805d00399bb8e36e881a5 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:17:15 +0100 Subject: [PATCH 0866/3432] FEAT: [Windows] extend platform metrics --- modules/view/backends/platform.red | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index a6d278c195..f404d1f695 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -718,6 +718,7 @@ system/view/platform: context [ extend system/view/metrics/margins [#switch config/OS [ Windows [ button: [1x1 1x1] ;-- LeftxRight TopxBottom + toggle: [1x1 1x1] tab-panel: [0x2 0x1] group-box: [0x0 0x1] calendar: [1x0 0x0] @@ -740,6 +741,7 @@ system/view/platform: context [ group-box: [3x3 10x3] tab-panel: [1x3 25x0] button: [8x8 0x0] + toggle: [8x8 0x0] drop-down: [0x7 0x0] drop-list: [0x7 0x0] calendar: [21x0 1x0] @@ -759,6 +761,7 @@ system/view/platform: context [ if version/1 <= 6 [ ;-- for Win7 & XP extend system/view/metrics/def-heights [ button: 23 + toggle: 23 text: 24 field: 24 check: 24 From 601181a7f7d952efb57c7669151809c0a913b1a1 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:17:39 +0100 Subject: [PATCH 0867/3432] FEAT: [macOS] extend platform metrics --- modules/view/backends/platform.red | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index f404d1f695..13cd0fae25 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -725,6 +725,7 @@ system/view/platform: context [ ] macOS [ button: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] + toggle: [2x2 2x3 regular 6x6 4x7 small 5x5 4x6 mini 1x1 0x1] regular: [6x6 4x7] small: [5x5 4x6] mini: [1x1 0x1] @@ -748,6 +749,7 @@ system/view/platform: context [ ] macOS [ button: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] + toggle: [11x11 0x0 regular 14x14 0x0 small 11x11 0x0 mini 11x11 0x0] check: [20x0 3x1] radio: [20x0 1x1] text: [3x3 0x0] From 298b7d21947b39adc9b3ead5772373e1482b7536 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:18:47 +0100 Subject: [PATCH 0868/3432] FEAT: [macOS] extend post-processing rules --- modules/view/backends/macOS/rules.red | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/rules.red b/modules/view/backends/macOS/rules.red index 6ec3e24330..07894498c7 100644 --- a/modules/view/backends/macOS/rules.red +++ b/modules/view/backends/macOS/rules.red @@ -52,7 +52,7 @@ capitalize: function [ ] ][ all [ - face/type = 'button + find [button toggle radio check] face/type face/text not empty? face/text ] @@ -94,7 +94,7 @@ adjust-buttons: function [ ] ][ all [ - face/type = 'button + find [button toggle] face/type face/size face/size/y <= 42 ;-- 37 + 5 not empty? face/text From 0a13be749751eba0620725fd73fe6c7339989978 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:56:48 +0100 Subject: [PATCH 0869/3432] FEAT: [Windows] add support for text alignment --- modules/view/backends/windows/para.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/para.reds b/modules/view/backends/windows/para.reds index 52312ffbed..89e640dcfc 100644 --- a/modules/view/backends/windows/para.reds +++ b/modules/view/backends/windows/para.reds @@ -51,6 +51,7 @@ update-para: func [ sym = base [mask: not 002Fh] any [ sym = button + sym = toggle sym = check sym = radio ][ @@ -144,6 +145,7 @@ get-para-flags: func [ ] any [ type = button + type = toggle type = check type = radio ][ @@ -155,7 +157,7 @@ get-para-flags: func [ bottom: 00000800h ;-- BS_BOTTOM vdefault: middle - default: either type = button [center][left] + default: either any [type = button type = toggle][center][left] ] any [ type = field From c74d561312b3cc71f082f598fbad6b86f704feda Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:57:32 +0100 Subject: [PATCH 0870/3432] FIX: [Windows] proper toggle button initialization --- modules/view/backends/windows/gui.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index 31b2b468f0..89b6f10fb6 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1561,11 +1561,16 @@ OS-make-view: func [ ;-- extra initialization case [ - sym = button [init-button handle values] sym = camera [init-camera handle data selected false] sym = text-list [init-text-list handle data selected] sym = base [init-base-face handle parent values alpha?] sym = tab-panel [set-tabs handle values] + any [ + sym = button + sym = toggle + ][ + init-button handle values + ] sym = group-box [ flags: flags or WS_GROUP or BS_GROUPBOX hWnd: CreateWindowEx @@ -2018,7 +2023,7 @@ change-image: func [ type [integer!] ][ if type = base [update-base hWnd null null values] - if type = button [init-button hWnd values] + if any [type = button type = toggle][init-button hWnd values] ] change-selection: func [ From 03e9804b6c65c7c7e67b241f756506d02d83b7d5 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:58:22 +0100 Subject: [PATCH 0871/3432] FEAT: [macOS] add support for text alignment --- modules/view/backends/macOS/font.reds | 2 +- modules/view/backends/macOS/para.reds | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/font.reds b/modules/view/backends/macOS/font.reds index b2033850b0..cc15903fcc 100644 --- a/modules/view/backends/macOS/font.reds +++ b/modules/view/backends/macOS/font.reds @@ -240,7 +240,7 @@ make-font-attrs: func [ o-para: as red-object! (object/get-values face) + FACE_OBJ_PARA if TYPE_OF(o-para) = TYPE_OBJECT [len: 3 and get-para-flags type o-para] ] - if all [type = button len = -1][len: NSTextAlignmentCenter] + if all [any [type = button type = toggle] len = -1][len: NSTextAlignmentCenter] para: 0 if len <> -1 [ diff --git a/modules/view/backends/macOS/para.reds b/modules/view/backends/macOS/para.reds index da4fcbb0e1..ae3d4f5b0c 100644 --- a/modules/view/backends/macOS/para.reds +++ b/modules/view/backends/macOS/para.reds @@ -29,6 +29,7 @@ change-para: func [ ] any [ type = button + type = toggle type = check type = radio type = field @@ -113,7 +114,7 @@ get-para-flags: func [ bottom: 0008h ;-- DT_BOTTOM unless wrap? [flags: 20h] ;-- DT_SINGLELINE - either any [type = base type = button][ + either any [type = base type = toggle type = button][ default: center ][ default: left From 3ef45747c82ee2b694becc3b96d6372196952d87 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 17:59:08 +0100 Subject: [PATCH 0872/3432] FIX: [macOS] proper toggle button initialization --- modules/view/backends/macOS/gui.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index 6ab2cdf964..6ee226c59a 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -593,7 +593,7 @@ change-image: func [ id [integer!] ][ case [ - any [type = button type = check type = radio][ + any [type = button type = toggle type = check type = radio][ if TYPE_OF(image) <> TYPE_IMAGE [ objc_msgSend [hWnd sel_getUid "setImage:" 0] exit @@ -776,7 +776,7 @@ change-font: func [ sel_getUid "initWithString:attributes:" title attrs ] case [ - any [type = button type = check type = radio][ + any [type = button type = toggle type = check type = radio][ objc_msgSend [hWnd sel_getUid "setAttributedTitle:" str] ] any [type = field type = text][ @@ -817,7 +817,7 @@ change-visible: func [ type [integer!] ][ case [ - any [type = button type = check type = radio][ + any [type = button type = toggle type = check type = radio][ objc_msgSend [hWnd sel_getUid "setEnabled:" show?] objc_msgSend [hWnd sel_getUid "setTransparent:" not show?] ] @@ -902,7 +902,7 @@ change-text: func [ any [type = field type = text][ objc_msgSend [hWnd sel_getUid "setStringValue:" txt] ] - any [type = button type = radio type = check type = window type = group-box][ + any [type = button type = toggle type = radio type = check type = window type = group-box][ objc_msgSend [hWnd sel_getUid "setTitle:" txt] ] true [0] From 604fd538d842b3a6d7a084b188953eb552ded510 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 18:35:58 +0100 Subject: [PATCH 0873/3432] FEAT: extend platform metrics --- modules/view/backends/platform.red | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index cc5baeaf9d..eb1ce62057 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -736,6 +736,7 @@ system/view/platform: context [ ] Linux [ button: [1x1 1x1] + toggle: [1x1 1x1] tab-panel: [0x2 0x1] group-box: [0x0 0x1] ] @@ -762,6 +763,7 @@ system/view/platform: context [ ] Linux [ button: [11x11 0x0] + toggle: [11x11 0x0] check: [20x0 3x1] radio: [20x0 1x1] text: [3x3 0x0] @@ -799,6 +801,7 @@ system/view/platform: context [ Linux [ extend system/view/metrics/def-heights [ button: 29 + toggle: 29 check: 20 radio: 19 text: 17 From b9b49ec085881779e5d3941fc635a716499ae534 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 18:36:41 +0100 Subject: [PATCH 0874/3432] FIX: proper toggle button initialization --- modules/view/backends/gtk3/gui.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 052adfde43..787fb7915a 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -763,7 +763,7 @@ change-image: func [ ; snap-camera widget ; until [TYPE_OF(image) = TYPE_IMAGE] ;-- wait ; ] - any [type = button type = check type = radio][ + any [type = button type = toggle type = check type = radio][ if TYPE_OF(image) = TYPE_IMAGE [ img: gtk_image_new_from_pixbuf OS-image/to-pixbuf image gtk_button_set_image widget img @@ -1009,7 +1009,7 @@ change-text: func [ buffer: gtk_entry_get_buffer widget gtk_entry_buffer_set_text buffer cstr -1 ] - any [type = button type = radio type = check] [ + any [type = button type = toggle type = radio type = check][ gtk_button_set_label widget cstr ] type = window [ From 0cd12b75e1cecc684ef5d8ebd8cc628960b42818 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 3 Feb 2020 18:37:06 +0100 Subject: [PATCH 0875/3432] FEAT: add font support --- modules/view/backends/gtk3/font.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/gtk3/font.reds b/modules/view/backends/gtk3/font.reds index fd532a5129..7c53b9dd58 100644 --- a/modules/view/backends/gtk3/font.reds +++ b/modules/view/backends/gtk3/font.reds @@ -817,6 +817,7 @@ set-font: func [ ] any [ sym = button + sym = toggle sym = check sym = radio ][ From ef1e8601ff397aefe10ae3b1bff34a120c87c4fe Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Mon, 3 Feb 2020 19:43:55 +0100 Subject: [PATCH 0876/3432] FEAT: handle properly recursive lexer/scan-string calls. Accumulates conversion buffers from the main one. If required size is too big, allocates a temporary one freed on function's exit. --- runtime/lexer.reds | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 567e8d7a29..6963544d9b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -289,8 +289,9 @@ lexer: context [ scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] loader!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] - utf8-bufsize: 100'000 + utf8-buf-size: 100'000 utf8-buffer: as byte-ptr! 0 + utf8-buf-tail: as byte-ptr! 0 scanners: as int-ptr! 0 ;-- scan functions jump table (dynamically filled) loaders: as int-ptr! 0 ;-- load functions jump table (dynamically filled) stash: as cell! 0 ;-- special buffer for hatching any-blocks series @@ -1909,23 +1910,32 @@ lexer: context [ fun [red-function!] ;-- optional callback function return: [integer!] ;-- scanned type when one? is set, else zero /local + unit buf-size ignore type used [integer!] + base extra [byte-ptr!] s [series!] - unit buf-size ignore [integer!] ][ ignore: 0 + extra: null s: GET_BUFFER(str) unit: GET_UNIT(s) if size = -1 [size: string/rs-length? str] - buf-size: size * unit - if buf-size > utf8-bufsize [ - free utf8-buffer - utf8-buffer: allocate buf-size - utf8-bufsize: buf-size + buf-size: size * unit ;-- required (upper estimate) + used: as-integer utf8-buf-tail - utf8-buffer + if buf-size > (utf8-buf-size - used) [ + extra: allocate buf-size + 1 ;-- fallback to a temporary buffer + utf8-buf-tail: extra ] - size: unicode/to-utf8-buffer str utf8-buffer size + size: unicode/to-utf8-buffer str utf8-buf-tail size + base: utf8-buf-tail + utf8-buf-tail: utf8-buf-tail + size + 1 ;-- move at tail for new buffer; +1 for terminal NUL + if null? len [len: :ignore] - scan dst utf8-buffer size one? load? wrap? len fun as red-series! str + catch RED_THROWN_ERROR [type: scan dst base size one? load? wrap? len fun as red-series! str] + utf8-buf-tail: base + if extra <> null [free extra] + if system/thrown <> 0 [re-throw] ;-- clean place to rethrow errors + type ] set-jump-tables: func [[variadic] count [integer!] list [int-ptr!] /local i [integer!] s l [int-ptr!]][ @@ -1947,7 +1957,8 @@ lexer: context [ init: func [][ stash: as cell! allocate stash-size * size? cell! - utf8-buffer: allocate utf8-bufsize + utf8-buffer: allocate utf8-buf-size + utf8-buf-tail: utf8-buffer ;-- switch following tables to zero-based indexing lex-classes: lex-classes + 1 From 2768838dfc6a5c3c4f8df4c9eaa242a1842362a0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 00:59:59 +0100 Subject: [PATCH 0877/3432] FIX: regression in lexer on handling single slash as any-word!. --- runtime/lexer.reds | 17 ++++++++++++++++- tests/source/units/lexer-test.red | 17 +++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 6963544d9b..03f4fedc74 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1004,6 +1004,21 @@ lexer: context [ lex/scanned: type ] + scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + case [ + s + 1 = e [lex/scanned: TYPE_WORD] + s + 2 = e [ + case [ + s/1 = #"'" [lex/scanned: TYPE_LIT_WORD] + s/1 = #":" [lex/scanned: TYPE_GET_WORD] + e/0 = #":" [lex/scanned: TYPE_SET_WORD] + true [0] + ] + ] + true [0] + ] + ] + scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] return: [integer!] /local @@ -1982,7 +1997,7 @@ lexer: context [ :scan-comment null ;-- T_CMT :scan-integer :load-integer ;-- T_INTEGER :scan-word :load-word ;-- T_WORD - null :load-word ;-- T_REFINE + :scan-refinement :load-word ;-- T_REFINE null :load-word ;-- T_ISSUE null :load-string ;-- T_STRING null :load-file ;-- T_FILE diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index f007669926..ba958a3a4b 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -344,6 +344,11 @@ Red [ --assert word? out/1 --assert tag? out/2 + --test-- "tr-31" + out: transcode "1 / 3" + --assert out == [1 / 3] + --assert word? out/2 + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" @@ -442,10 +447,14 @@ Red [ --test-- "tro-70" --assert lit-word? out: transcode/one "'//////////" --assert "'//////////" = mold out --test-- "tro-71" --assert get-word? out: transcode/one "://////////" --assert "://////////" = mold out - --test-- "tro-72" --assert lit-word? out: transcode/one "'//" --assert "'//" = mold out - --test-- "tro-73" --assert get-word? out: transcode/one "://" --assert "://" = mold out - --test-- "tro-74" --assert set-word? out: transcode/one "//:" --assert "//:" = mold out - --test-- "tro-75" --assert word? out: transcode/one "//" --assert "//" = mold out + --test-- "tro-72" --assert lit-word? out: transcode/one "'//" --assert "'//" = mold out + --test-- "tro-73" --assert get-word? out: transcode/one "://" --assert "://" = mold out + --test-- "tro-74" --assert set-word? out: transcode/one "//:" --assert "//:" = mold out + --test-- "tro-75" --assert word? out: transcode/one "//" --assert "//" = mold out + --test-- "tro-76" --assert word? out: transcode/one "/" --assert "/" = mold out + --test-- "tro-77" --assert lit-word? out: transcode/one "'/" --assert "'/" = mold out + --test-- "tro-78" --assert get-word? out: transcode/one ":/" --assert ":/" = mold out + --test-- "tro-79" --assert set-word? out: transcode/one "/:" --assert "/:" = mold out ===end-group=== ===start-group=== "transcode/next" From 6c54b90ac752538ecb9c93a3c219bf8492904ead Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 01:40:24 +0100 Subject: [PATCH 0878/3432] FIX: crash on loading an incomplete path. --- runtime/lexer.reds | 3 ++- tests/source/units/lexer-test.red | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 03f4fedc74..674275e36b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -336,7 +336,8 @@ lexer: context [ lex/tail: lex/buffer ;-- clear accumulated values if null? root-state/next [root-state: null] ;@@ do a proper clean-up before throwing - + if lex/closing = TYPE_PATH [type: ERR_BAD_CHAR] ;-- forces a better error report + switch type [ ERR_BAD_CHAR [fire [TO_ERROR(syntax bad-char) line pos]] ERR_MALCONSTRUCT [fire [TO_ERROR(syntax malconstruct) line pos]] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index ba958a3a4b..5824ef421b 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -668,6 +668,8 @@ Red [ load word! datatype! 5 world ] + --test-- "tt-8" + --assert error? try [transcode/trace "a: 3 t/" func [e i t l o][true]] ===end-group=== From 50dfabaa985894abc6b6fa5027d7be524b50cadb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 4 Feb 2020 12:19:57 +0100 Subject: [PATCH 0879/3432] FIX: [macOS] toggle has improper vertical sizing --- modules/view/backends/macOS/gui.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/macOS/gui.reds b/modules/view/backends/macOS/gui.reds index 6ee226c59a..32463abd35 100644 --- a/modules/view/backends/macOS/gui.reds +++ b/modules/view/backends/macOS/gui.reds @@ -563,7 +563,7 @@ change-size: func [ h [float32!] ][ rc: make-rect size/x size/y 0 0 - if all [type = button size/y > 32][ + if all [any [type = button type = toggle] size/y > 32][ objc_msgSend [hWnd sel_getUid "setBezelStyle:" NSRegularSquareBezelStyle] ] either type = window [ @@ -1819,7 +1819,7 @@ parse-common-opts: func [ ] if any [type = button type = toggle][ - len: either all [btn? type = button][NSRegularSquareBezelStyle][NSRoundedBezelStyle] + len: either btn? [NSRegularSquareBezelStyle][NSRoundedBezelStyle] objc_msgSend [hWnd sel_getUid "setBezelStyle:" len] ] ] From 25e036d95d308bde0e3fc6b937f85575507c7834 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 4 Feb 2020 15:47:51 +0100 Subject: [PATCH 0880/3432] FIX: [Windows] font color is ignored --- modules/view/backends/windows/events.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 0e65f1d499..f9ac2bb88a 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -841,6 +841,7 @@ process-custom-draw: func [ sym = check sym = radio sym = button + sym = toggle ][ if all [ item/dwDrawStage = CDDS_PREPAINT @@ -1350,7 +1351,7 @@ WndProc: func [ ] ] WM_CTLCOLOREDIT - WM_CTLCOLORSTATIC + WM_CTLCOLORSTATIC WM_CTLCOLORLISTBOX [ if null? current-msg [init-current-msg] current-msg/hWnd: as handle! lParam ;-- force child handle From 811db9958897503372f975b87cc8928c06f35467 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Tue, 4 Feb 2020 23:11:59 +0800 Subject: [PATCH 0881/3432] FIX: issue #4270 ([View] Window offset reports inconsistent values) --- modules/view/backends/windows/gui.reds | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index b151af17aa..da69361975 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1637,8 +1637,6 @@ OS-make-view: func [ if null? main-hWnd [main-hWnd: handle] ] ] - offset/x: off-x - rc/left * 100 / dpi-factor - offset/y: off-y - rc/top * 100 / dpi-factor SetWindowLong handle wc-offset - 8 From ce28306ae2287155fa4341d8c2cbfbe474626e29 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 17:34:23 +0100 Subject: [PATCH 0882/3432] FIX: compiled `system/words/*` paths not binding to global context properly. --- compiler.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler.r b/compiler.r index 3d4331bf69..a9654f279e 100644 --- a/compiler.r +++ b/compiler.r @@ -1056,7 +1056,7 @@ red: context [ ] path: none ][ - bind path/1 'rebol ;-- force binding to global context + path/1: bind path/1 'rebol ;-- force binding to global context ] ] path From 4b511b6a197a6889f03ea5aeb4a3d39cc28463a2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 17:36:27 +0100 Subject: [PATCH 0883/3432] FIX: properly clean up lexer internal state on exceptions. --- runtime/lexer.reds | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 674275e36b..1382b7342e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -335,7 +335,6 @@ lexer: context [ string/append-char GET_BUFFER(line) as-integer #")" lex/tail: lex/buffer ;-- clear accumulated values - if null? root-state/next [root-state: null] ;@@ do a proper clean-up before throwing if lex/closing = TYPE_PATH [type: ERR_BAD_CHAR] ;-- forces a better error report switch type [ @@ -412,8 +411,7 @@ lexer: context [ either null? value [pair/push x + 1 y + 1][stack/push value] ;-- token if lex/fun-locs > 0 [_function/init-locals 1 + lex/fun-locs] ;-- +1 for /local refinement - catch RED_THROWN_ERROR [_function/call lex/fun-ptr ctx] - if system/thrown <> 0 [re-throw] + _function/call lex/fun-ptr ctx if ser/head <> y [ lex/in-series/head: ser/head @@ -1817,6 +1815,8 @@ lexer: context [ ] ] ] + system/thrown: 0 + if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed ] @@ -1869,7 +1869,6 @@ lexer: context [ base: prev/tail ] clean-up: [ - system/thrown: 0 either null? root-state/next [root-state: null][lex/back/next: null] len/value: as-integer lex/in-pos - lex/input ] @@ -1893,16 +1892,25 @@ lexer: context [ if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no] - scan-tokens lex one? load? - + catch RED_THROWN_ERROR [scan-tokens lex one? load?] + if system/thrown <> 0 [clean-up re-throw] + if load? [ slots: (as-integer lex/tail - lex/buffer) >> 4 if slots > 0 [ p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] if TYPE_OF(p) = TYPE_POINT [ lex/closing: p/y - catch LEX_ERR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] - if system/thrown <> 0 [dst/header: TYPE_NONE clean-up return lex/scanned] + catch RED_THROWN_ERROR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] + either system/thrown <= LEX_ERR [ + dst/header: TYPE_NONE + system/thrown: 0 + clean-up + return lex/scanned + ][ + clean-up + re-throw + ] ] ] either all [one? not wrap? slots > 0][ From cf41fc0da9de690ef55ba9eb7fece4232fc9349a Mon Sep 17 00:00:00 2001 From: hiiamboris <hiiamboris@gmail.com> Date: Tue, 4 Feb 2020 21:02:52 +0300 Subject: [PATCH 0884/3432] FEAT: fetch-next supports set-words/paths, get/lit-args, object/series paths --- utils/preprocessor.r | 109 +++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 30 deletions(-) diff --git a/utils/preprocessor.r b/utils/preprocessor.r index 731c7d8683..4755834329 100644 --- a/utils/preprocessor.r +++ b/utils/preprocessor.r @@ -99,11 +99,13 @@ preprocessor: context [ do-safe/with bind to block! code exec cmd ] - count-args: func [spec [block!] /local total][ - total: 0 + count-args: func [spec [block!] /block /local total pos][ + total: either block [copy []][0] parse spec [ any [ - [word! | lit-word! | get-word!] (total: total + 1) + pos: [word! | lit-word! | get-word!] ( + either block [append total type? pos/1] [total: total + 1] + ) | refinement! (return total) | skip ] @@ -111,8 +113,12 @@ preprocessor: context [ total ] - func-arity?: func [spec [block!] /with path [path!] /local arity pos][ - arity: count-args spec + arg-mode?: func [spec [block!] idx [integer!]][ + pick count-args/block spec idx + ] + + func-arity?: func [spec [block!] /with path [path!] /block /local arity pos][ + arity: either block [count-args/block spec] [count-args spec] if path [ foreach word next path [ unless pos: find/tail spec to refinement! word [ @@ -122,39 +128,82 @@ preprocessor: context [ ] do-quit ] - arity: arity + count-args pos + either block + [append arity count-args/block pos] + [arity: arity + count-args pos] ] ] arity ] - - fetch-next: func [code [block! paren!] /local base arity value path][ - base: code - arity: 1 - - while [arity > 0][ - arity: arity + either all [ - not tail? next code - word? value: code/2 - op? get/any value + + value-path?: func [path [path!] /local value i] [ + repeat i length? path [ + set/any 'value either i = 1 [get/any first path][select value pick path i] + unless any [ ;-- select-able types + series? get/any 'value + any-object? get/any 'value + map? get/any 'value ][ - code: next code - 1 + path: copy/part path i + break + ] + ] + reduce [path get/any 'value] + ] + + fetch-next: func [code [block! paren!] /local i left item item2 value fn-spec path f-arity at-op? op-mode][ + left: reduce [yes] + + while [all [not tail? left not tail? code]] [ + either not left/1 [ ;-- skip quoted argument + remove left ][ - either all [ - find [word! path!] type?/word value: code/1 - value: either word? value [value][first path: value] - any-function? get/any value - ][ - either path [ - func-arity?/with spec-of get value path - ][ - func-arity? spec-of get value + item: first code + f-arity: any [ + all [ ;-- a ... + word? :item + any-function? set/any 'value get/any :item + func-arity?/block fn-spec: spec-of get/any :item ] - ][0] - ] + all [ ;-- a/b ... + path? :item + set/any [path value] value-path? :item + any-function? get/any 'value + func-arity?/block/with + fn-spec: spec-of :value + at :item length? :path + ] + ] + + if at-op?: all [ ;-- a * b + 1 < length? code + word? item2: second code + op? get/any :item2 + ] [ + op-mode: arg-mode? spec-of get/any :item2 1 + if all [f-arity op-mode = word!] [ ;-- check if function's lit/get-arg takes priority + at-op?: word! = arg-mode? fn-spec 1 + ] + ] + + case [ + at-op? [ ;-- a * b + code: next code ;-- skip `a *` part + left/1: word! = arg-mode? spec-of get/any :item2 2 + ] + + f-arity [ ;-- a ... / a/b ... + if op? get/any 'value [return skip code 2] ;-- starting with op is an error + remove left + repeat i length? f-arity [insert at left i word! = f-arity/:i] + ] + + not find [set-word! set-path!] type?/word item [ ;-- not a: or a/b: + remove left + ] + ] + ];;either not left/1 [][ code: next code - arity: arity - 1 ] code ] From b0b5ad41f29bd176bb6e8668f5f185da86455190 Mon Sep 17 00:00:00 2001 From: hiiamboris <hiiamboris@gmail.com> Date: Tue, 4 Feb 2020 21:03:26 +0300 Subject: [PATCH 0885/3432] TESTS: more tests for fetch-next --- tests/source/compiler/preprocessor-test.r | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/source/compiler/preprocessor-test.r b/tests/source/compiler/preprocessor-test.r index 6966b1d881..5c7b35a409 100644 --- a/tests/source/compiler/preprocessor-test.r +++ b/tests/source/compiler/preprocessor-test.r @@ -96,4 +96,40 @@ REBOL [ --assert-printed? "*test9*" --assert-printed? "*test10* foo 5 9" + --test-- "fetch-next" + --compile-and-run-this { + Red [] + prin "*test1* " probe preprocessor/fetch-next [] + prin "*test2* " probe preprocessor/fetch-next [1 2] + prin "*test3* " probe preprocessor/fetch-next [1 + 2 3] + prin "*test4* " probe preprocessor/fetch-next [a: 1 + b: 2 3] + prin "*test5* " probe preprocessor/fetch-next [+ 1 2 3] + b: reduce ['o make object! [f: func [/x y z][]]] + prin "*test6* " probe preprocessor/fetch-next [a: 1 + b/o/f 2 3 4] + prin "*test7* " probe preprocessor/fetch-next [a: 1 + b/o/f/x 2 3 4] + prin "*test8* " probe preprocessor/fetch-next [a: 1 + b/o/f/x 2 3 * 4 * 5 6] + b: reduce ['o make object! [f: func [/x 'y :z][]]] + f: func [x][] + prin "*test9* " probe preprocessor/fetch-next [a: 1 + b/o/f/x f f 4 5 6] + prin "*test10* " probe preprocessor/fetch-next [a: 1 + b/o/f/x + * 4 5 6] + o: make op! func ['x 'y][] + prin "*test11* " probe preprocessor/fetch-next [a: o b: 1] + prin "*test12* " probe preprocessor/fetch-next [f o f 1] + prin "*test13* " probe preprocessor/fetch-next [b/o/f o b/o/f/x 1 2 3] + } + + --assert-printed? "*test1* []" + --assert-printed? "*test2* [2]" + --assert-printed? "*test3* [3]" + --assert-printed? "*test4* [3]" + --assert-printed? "*test5* [2 3]" + --assert-printed? "*test6* [2 3 4]" + --assert-printed? "*test7* [4]" + --assert-printed? "*test8* [6]" + --assert-printed? "*test9* [4 5 6]" + --assert-printed? "*test10* [4 5 6]" + --assert-printed? "*test11* [1]" + --assert-printed? "*test12* [1]" + --assert-printed? "*test13* [1 2 3]" + ~~~end-file~~~ From 02076e0c0729e0d9a76487ef9dab77c77724740a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 19:43:53 +0100 Subject: [PATCH 0886/3432] TESTS: adds tests for recursive lexer calls. --- tests/source/units/lexer-test.red | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 5824ef421b..5a7121cf10 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -634,7 +634,7 @@ Red [ type [datatype! word! none!] line [integer!] token - return: [logic!] + return: [logic!] ][ t: tail logs reduce/into [event to-word type to-word type? type line token] tail logs @@ -668,9 +668,34 @@ Red [ load word! datatype! 5 world ] - --test-- "tt-8" + --test-- "tt-9" --assert error? try [transcode/trace "a: 3 t/" func [e i t l o][true]] + --test-- "tt-10" + lex-filter10: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + --assert 456 == load "456" + --assert [[456] world] == load "[456] world" + yes + ] + clear logs + --assert [123 abc] == transcode/trace "123 abc" :lex-filter10 + --assert logs = [ + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + scan word! word! 1 5x8 + load word! datatype! 1 abc + ] + ===end-group=== ~~~end-file~~~ \ No newline at end of file From d9179ad8d3c0565b68381182cc00b0efd724c9f8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 4 Feb 2020 22:16:44 +0100 Subject: [PATCH 0887/3432] TESTS: additional lexer recursive test. --- tests/source/units/lexer-test.red | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 5a7121cf10..2402cf7c3f 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -696,6 +696,44 @@ Red [ load word! datatype! 1 abc ] + --test-- "tt-11" + lex-filter11B: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + --assert 456 == load "456" + --assert [[456] world] == load "[456] world" + yes + ] + lex-filter11A: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + --assert 789 == load "789" + --assert [[789] world] == load "[789] world" + --assert [123 abc] == transcode/trace "123 abc" :lex-filter11B + yes + ] + clear logs + --assert [123 abc] == transcode/trace "123 abc" :lex-filter11A + --assert logs = [ + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + scan word! word! 1 5x8 + load word! datatype! 1 abc + ] + ===end-group=== ~~~end-file~~~ \ No newline at end of file From a75ce81ca2b8b199099215cb919ceb7bb4c6647f Mon Sep 17 00:00:00 2001 From: hiiamboris <hiiamboris@gmail.com> Date: Wed, 5 Feb 2020 16:29:16 +0300 Subject: [PATCH 0888/3432] FIX: PR #4283 compatibility with the antediluvian Rebol --- utils/preprocessor.r | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/utils/preprocessor.r b/utils/preprocessor.r index 4755834329..191e339e72 100644 --- a/utils/preprocessor.r +++ b/utils/preprocessor.r @@ -141,8 +141,7 @@ preprocessor: context [ set/any 'value either i = 1 [get/any first path][select value pick path i] unless any [ ;-- select-able types series? get/any 'value - any-object? get/any 'value - map? get/any 'value + find [object! port! error! map!] type?/word get/any 'value ][ path: copy/part path i break From a934616089898670d7c9fbd7b35a480cf76d4bde Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 5 Feb 2020 15:08:58 +0100 Subject: [PATCH 0889/3432] FIX: [Windows] alignment is not honored with custom font --- modules/view/backends/windows/events.reds | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index f9ac2bb88a..9f7366a021 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -825,10 +825,11 @@ process-custom-draw: func [ type [red-word!] txt [red-string!] font [red-object!] + para [red-object!] color [red-tuple!] + flags [integer!] sym [integer!] old [integer!] - flags [integer!] DC [handle!] rc [RECT_STRUCT] ][ @@ -836,7 +837,8 @@ process-custom-draw: func [ values: get-face-values item/hWndFrom type: as red-word! values + FACE_OBJ_TYPE DC: item/hdc - sym: symbol/resolve type/symbol + sym: symbol/resolve type/symbol + if any [ sym = check sym = radio @@ -849,6 +851,7 @@ process-custom-draw: func [ ][ ;@@ TBD draw image font: as red-object! values + FACE_OBJ_FONT + para: as red-object! values + FACE_OBJ_PARA if TYPE_OF(font) = TYPE_OBJECT [ txt: as red-string! values + FACE_OBJ_TEXT values: object/get-values font @@ -861,14 +864,12 @@ process-custom-draw: func [ SetTextColor DC color/array1 and 00FFFFFFh ] rc: as RECT_STRUCT (as int-ptr! item) + 5 - flags: DT_VCENTER or DT_SINGLELINE - either sym = button [ - flags: flags or DT_CENTER - ][ - rc/left: rc/left + dpi-scale 16 + unless any [sym = button sym = toggle][ + rc/left: rc/left + dpi-scale 16 ;-- compensate for invisible check box ] if TYPE_OF(txt) = TYPE_STRING [ - DrawText DC unicode/to-utf16 txt -1 rc flags + flags: get-para-flags base para + DrawText DC unicode/to-utf16 txt -1 rc flags or DT_SINGLELINE ] SetBkMode DC old return CDRF_SKIPDEFAULT From 56b6c889768385ea6fa7ee4f171bd8402861ae7f Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 5 Feb 2020 16:07:35 +0100 Subject: [PATCH 0890/3432] TESTS: update manual View test --- tests/view-test.red | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/view-test.red b/tests/view-test.red index a9301d9c7d..74dd25ac24 100644 --- a/tests/view-test.red +++ b/tests/view-test.red @@ -766,8 +766,13 @@ win/pane: reduce [ ] ] make face! [ - type: 'button offset: 570x440 size: 38x38 + type: 'toggle offset: 570x440 size: 38x38 image: smiley + actors: object [ + on-change: func [face [object!] event [event!]][ + print [face/type pick "☻☺" face/data] + ] + ] ] make face! [ ;-- clip view for canvas type: 'panel offset: 10x460 size: 300x200 From 919d0782fc668a242166e46230daa8ae5ad1576f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 5 Feb 2020 22:40:42 +0100 Subject: [PATCH 0891/3432] FIX: lexer was not reporting an error on overlong char! literals. E.g. #"ab" --- environment/system.red | 2 +- runtime/lexer-transitions.reds | 33 ++++++++++--------- runtime/lexer.reds | 53 ++++++++++++++++--------------- tests/source/units/lexer-test.red | 2 ++ utils/generate-lexer-table.red | 22 ++++++++++--- 5 files changed, 65 insertions(+), 47 deletions(-) diff --git a/environment/system.red b/environment/system.red index 78edf55de3..22e902b55d 100644 --- a/environment/system.red +++ b/environment/system.red @@ -406,7 +406,7 @@ system: context [ exit-states: [ eof error! block! block! paren! paren! string! string! map! path! any-type! - comment integer! word! refinement! issue! string! file! binary! char! percent! + comment integer! word! refinement! char! issue! string! file! binary! percent! float! float! tuple! date! pair! time! money! tag! url! email! hex ] ] diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index e802e58443..6503856a5c 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -73,11 +73,11 @@ Red/System [ T_INTEGER T_WORD T_REFINE + T_CHAR T_ISSUE T_STRING T_FILE T_BINARY - T_CHAR T_PERCENT T_FLOAT T_FLOAT_SP @@ -91,37 +91,40 @@ Red/System [ T_EMAIL T_HEX ] + ending-skip: #{ +0000000000000000000000000000000000010001010000000000000001000000 +} type-table: #{ 0000070707070808080808130F1429000A0A00140B0C0C0C0C272F2B2B252533 33330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 -000000000B0013140708290A260C0C272F252B332C092D0B +000000000B00130A14070829260C0C272F252B332C092D0B } transitions: #{ 000014143A3B3C3D3E39020D2C2C2D2D2D2D222D220B39252D2D063901392A1F 2929392D2D393801430101010101010101010101010101010101010101010101 -0101010101010101010101013938020202020202020202024802020202020202 +0101010101010101010101013938020202020202020202024902020202020202 0202020202020202020202020202020203020239390202020202020202020202 0202020202020202020202020202020202020202020202020202393804040404 040404043E3F0404040404040404040404040404040404040404040404040504 0439390404040404040404040404040404040404040404040404040404040404 04040404040404043938454507074545454545450A0707450707070707070707 -0707070707074545070707070707073945494907074949494949493907074907 -0707070707070707070707080749490707070707070739490707090939393939 +07070707070745450707070707070739454A4A07074A4A4A4A4A4A3907074A07 +070707070707070707070708074A4A07070707070707394A0707090939393939 3939393939393939390909090939393939393939393939393939393939393907 0707073939393939393939393939393909090707393939393939393939393939 -3939393939490A0A0A0A0A0A0A0A0A0A490A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +39393939394A0A0A0A0A0A0A0A0A0A0A4A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A 0A0A0A0A0A0A0A0A0A0A0A393946460B0B464646464646460B0B0B0B0B0B0B0B 0B0B0C0B0B0B0B0B0B46460B0B0B0B0B0B0B394645452D2D4545454545454539 -2D2D2D2D2D2D2D2D2D0C2D2D2D2D392D45452D392D2D2D2D2D39454747131312 -3940390E39101313391313131313131313133939391339474713131313131313 -39470E0E0E0E39393939394A393939390E0E0E0E0E0E0E0E3939390E39390F39 +2D2D2D2D2D2D2D2D2D0C2D2D2D2D392D45452D392D2D2D2D2D39454848131312 +3940390E39101313391313131313131313133939391339484813131313131313 +39480E0E0E0E39393939394B393939390E0E0E0E0E0E0E0E3939390E39390F39 39390E3939390E39390F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F3938101010101010101010104B1010101010 -101010101010101010101010101010101010111010394B101010101010101010 +0F0F0F0F0F0F0F0F0F0F0F0F0F0F393810101010101010101010471010101010 +1010101010101010101010101010101010101110103947101010101010101010 1010101010101010101010101010101010101010101010101010101039391212 1212124212121212121212121212121212121212121212121212121212121212 -1212123939474713134747474747474713131313131313131313131313131313 -13474713131313131313394744441414444444444444440D141B1D1A24161739 +1212123939484813134848484848484813131313131313131313131313131313 +13484813131313131313394844441414444444444444440D141B1D1A24161739 221A394439394C1544301539391A39393939444D4D16164D4D4D4D4D4D4D1816 391D3939161639394D394D39394C394D3939393939393939394D4D4D16164D4D 4D4D4D4D4D39394D393939161639394D394D39394C3939301939161639393939 @@ -161,8 +164,8 @@ Red/System [ 3232444444444444443914441D39391616393944394439394C15443015393939 3939393944393939393939393939393939393934343434343434393934343439 3939393439343439343439394545343445454545454545393445343434343434 -3445453434343939453034393434343434394547471313123939393939101313 -3913131313131313131339393913394747131313131313133947454532324545 +3445453434343939453034393434343434394548481313123939393939101313 +3913131313131313131339393913394848131313131313133948454532324545 454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39 45 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1382b7342e..fae0ee14d9 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -105,10 +105,6 @@ lexer: context [ 00000000000101 } - ending-skip: #{ - 0000000000000000000000000000000001000101010000000000000001000000 - } - bin16-classes: #{ 0000000000000000000101000001000000000000000000000000000000000000 0100000000000000000000000000000002020202020202020202000300000000 @@ -282,7 +278,7 @@ lexer: context [ fun-ptr [red-function!] ;-- callback function pointer or NULL fun-locs [integer!] ;-- number of local words in callback function in-series [red-series!] ;-- optional back reference to input series - int-value [integer!] ;-- decoded integer! value (from scanner to loader) + value [integer!] ;-- decoded integer! or char! value (from scanner to loader) load? [logic!] ;-- TRUE: load values, else scan only ] @@ -1067,12 +1063,33 @@ lexer: context [ ] if s/value = #"-" [i: 0 - i] lex/scanned: TYPE_INTEGER - lex/int-value: i + lex/value: i i ] + scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] + /local + len c [integer!] + ][ + assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] + len: as-integer e - s + if len = 2 [throw-error lex s e TYPE_CHAR] ;-- #"" + + either s/3 = #"^^" [ + if len = 3 [throw-error lex s e TYPE_CHAR] ;-- #"^" + c: -1 + scan-escaped-char s + 3 e :c + ][ ;-- simple char + if len > 3 [throw-error lex s e TYPE_CHAR] + c: as-integer s/3 + ] + if any [c > 0010FFFFh c = -1][throw-error lex s e TYPE_CHAR] + lex/value: c + lex/in-pos: e + 1 ;-- skip " + ] + load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - integer/make-at alloc-slot lex lex/int-value + integer/make-at alloc-slot lex lex/value lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1343,27 +1360,11 @@ lexer: context [ load-char: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - char [red-char!] - len c [integer!] + char [red-char!] ][ - assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] - len: as-integer e - s - if len = 2 [throw-error lex s e TYPE_CHAR] ;-- #"" - - either s/3 = #"^^" [ - if len = 3 [throw-error lex s e TYPE_CHAR] ;-- #"^" - c: -1 - scan-escaped-char s + 3 e :c - ][ ;-- simple char - c: as-integer s/3 - ] - if any [c > 0010FFFFh c = -1][throw-error lex s e TYPE_CHAR] - char: as red-char! alloc-slot lex set-type as cell! char TYPE_CHAR - char/value: c - - lex/in-pos: e + 1 ;-- skip " + char/value: lex/value ] load-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -2007,11 +2008,11 @@ lexer: context [ :scan-integer :load-integer ;-- T_INTEGER :scan-word :load-word ;-- T_WORD :scan-refinement :load-word ;-- T_REFINE + :scan-char :load-char ;-- T_CHAR null :load-word ;-- T_ISSUE null :load-string ;-- T_STRING null :load-file ;-- T_FILE null :load-binary ;-- T_BINARY - null :load-char ;-- T_CHAR null :load-percent ;-- T_PERCENT null :load-float ;-- T_FLOAT null :load-float-special ;-- T_FLOAT_SP diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 2402cf7c3f..5a5028063f 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -456,6 +456,8 @@ Red [ --test-- "tro-78" --assert get-word? out: transcode/one ":/" --assert ":/" = mold out --test-- "tro-79" --assert set-word? out: transcode/one "/:" --assert "/:" = mold out + --test-- "tro-80" --assert error? try [transcode/one {#"ab"}] + ===end-group=== ===start-group=== "transcode/next" diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 134636df20..ab7ffa52f4 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -84,11 +84,11 @@ context [ T_INTEGER TYPE_INTEGER ;-- 68 T_WORD - ;-- 69 T_REFINE TYPE_REFINEMENT ;-- 70 - T_ISSUE TYPE_ISSUE ;-- 71 - T_STRING TYPE_STRING ;-- 72 - T_FILE TYPE_FILE ;-- 73 - T_BINARY TYPE_BINARY ;-- 74 - T_CHAR TYPE_CHAR ;-- 75 + T_CHAR TYPE_CHAR ;-- 71 + T_ISSUE TYPE_ISSUE ;-- 72 + T_STRING TYPE_STRING ;-- 73 + T_FILE TYPE_FILE ;-- 74 + T_BINARY TYPE_BINARY ;-- 75 T_PERCENT TYPE_PERCENT ;-- 76 T_FLOAT TYPE_FLOAT ;-- 77 T_FLOAT_SP TYPE_FLOAT ;-- 78 @@ -136,6 +136,16 @@ context [ types: select types 'datatypes! foreach [s t] states [append type-table either t = '- [0][(index? find types t) - 1]] + + ;-- Generate the ending-skip table content + ending-table: make binary! 2000 + list: skip find states '--EXIT_STATES-- 2 + + foreach [s t] list [ + append ending-table pick 1x0 to-logic find [ + T_STRING T_BINARY T_PERCENT T_TAG + ] s + ] template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" @@ -145,6 +155,8 @@ context [ (extract states 2) ] + ending-skip: (ending-table) + type-table: (type-table) transitions: (table) From 61ff44b217d4e6c3bc54d1c10dda8474a1c95f38 Mon Sep 17 00:00:00 2001 From: hiiamboris <hiiamboris@gmail.com> Date: Wed, 5 Feb 2020 16:11:01 +0300 Subject: [PATCH 0892/3432] FIX: issue #4284 magic fix (Windows clipboard failure when accessed by other programs) --- runtime/clipboard.reds | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/runtime/clipboard.reds b/runtime/clipboard.reds index 3b65140839..7f86592ea4 100644 --- a/runtime/clipboard.reds +++ b/runtime/clipboard.reds @@ -14,6 +14,16 @@ clipboard: context [ #switch OS [ Windows [ + tagMSG: alias struct! [ ;-- used to work around #4284 + hWnd [handle!] + msg [integer!] + wParam [integer!] + lParam [integer!] + time [integer!] + x [integer!] ;@@ POINT struct + y [integer!] + ] + #import [ "User32.dll" stdcall [ OpenClipboard: "OpenClipboard" [ @@ -46,6 +56,14 @@ clipboard: context [ lpszFormat [c-string!] return: [integer!] ] + PeekMessage: "PeekMessageW" [ ;-- used to work around #4284 + msg [tagMSG] + hWnd [handle!] + msgMin [integer!] + msgMax [integer!] + removeMsg [integer!] + return: [integer!] + ] ] "kernel32.dll" stdcall [ GlobalAlloc: "GlobalAlloc" [ @@ -169,6 +187,7 @@ clipboard: context [ i [integer!] len [integer!] hdr [BITMAPV5HEADER!] + msg [tagMSG value] ][ val: none-value p: null @@ -180,6 +199,7 @@ clipboard: context [ unless ok [Sleep 1] ok: OpenClipboard main-hWnd if ok [break] + PeekMessage :msg null 0 0 0 ;-- magic workaround for #4284 ] unless ok [return as red-value! false-value] @@ -321,6 +341,7 @@ clipboard: context [ df [DROPFILES!] bmdata [BitmapData!] hdr [BITMAPV5HEADER!] + msg [tagMSG value] ][ hMem: [0 0] hMem/1: 0 hMem/2: 0 fmts: [0 0] fmts/1: 0 fmts/2: 0 @@ -449,6 +470,7 @@ clipboard: context [ unless ok [Sleep 1] ok: OpenClipboard main-hWnd if ok [break] + PeekMessage :msg null 0 0 0 ;-- magic workaround for #4284 ] unless ok [ ;-- clean up after a (rare) failure unless hMem/1 = 0 [ From 049f215038050e39132e3aecf822e8b106abd531 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 1 Feb 2020 11:21:37 +0100 Subject: [PATCH 0893/3432] FEAT: import decoration-related functions --- modules/view/backends/gtk3/gtk.reds | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a5eb11ff57..e4b13b1b3c 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -1278,6 +1278,10 @@ GPtrArray!: alias struct! [ window [handle!] mode [logic!] ] + gtk_window_set_type_hint: "gtk_window_set_type_hint" [ + window [handle!] + mode [integer!] + ] gtk_window_move: "gtk_window_move" [ window [handle!] x [integer!] @@ -2930,7 +2934,10 @@ GPtrArray!: alias struct! [ win [handle!] cursor [handle!] ] - + gdk_window_set_decorations: "gdk_window_set_decorations" [ + window [handle!] + flags [integer!] + ] ;; Useless since already called inside pango_cairo_create_context ; pango_cairo_font_map_get_default: "pango_cairo_font_map_get_default" [ ; return: [handle!] From 572db9fb139158321ebfbada60b9f579edf5cc5c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 1 Feb 2020 11:22:47 +0100 Subject: [PATCH 0894/3432] FIX: issue #4271 --- modules/view/backends/gtk3/gui.reds | 32 ++++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 011130d255..3cebfad5f4 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1620,13 +1620,30 @@ OS-make-view: func [ ] sym = window [ widget: gtk_window_new 0 - + if bits and FACET_FLAGS_MODAL <> 0 [ gtk_window_set_modal widget yes ] + if any [ + bits and FACET_FLAGS_NO_TITLE <> 0 + bits and FACET_FLAGS_NO_BORDER <> 0 + ][ + gtk_window_set_decorated widget no + ] + if any [ + bits and FACET_FLAGS_NO_MIN <> 0 + bits and FACET_FLAGS_NO_MAX <> 0 + bits and FACET_FLAGS_NO_BTNS <> 0 + ][ + gtk_window_set_type_hint widget 5 ;-- WINDOW_TYPE_HINT_UTILITY + ] + if bits and FACET_FLAGS_NO_BTNS <> 0 [ + gtk_window_set_deletable widget no ;-- hide Close button + ] + unless null? caption [gtk_window_set_title widget caption] - winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 + winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox if menu-bar? menu window [ hMenu: gtk_menu_bar_new @@ -1641,17 +1658,8 @@ OS-make-view: func [ gtk_box_pack_start winbox container yes yes 0 gtk_window_move widget offset/x offset/y - ;; The following line really matters to fix the initial size of the window - gtk_widget_set_size_request widget size/x size/y + gtk_widget_set_size_request widget size/x size/y ;-- fix the initial size of the window gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) - either any [ - bits and FACET_FLAGS_NO_TITLE <> 0 - bits and FACET_FLAGS_NO_BORDER <> 0 - ][ - gtk_window_set_decorated widget no - ][ - gtk_window_set_decorated widget yes - ] ] sym = camera [ widget: gtk_layout_new null null From 2445b916415a47e2a03e379c0435ca7de7fa3392 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 1 Feb 2020 11:23:18 +0100 Subject: [PATCH 0895/3432] FIX: extra fix for #4271 --- modules/view/backends/gtk3/events.reds | 1 + modules/view/backends/gtk3/handlers.reds | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 60ae4abaf4..044de16675 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1024,6 +1024,7 @@ connect-widget-events: func [ gobj_signal_connect(widget "focus-in-event" :focus-in-event widget) gobj_signal_connect(widget "focus-out-event" :focus-out-event widget) gobj_signal_connect(widget "configure-event" :window-configure-event widget) + gobj_signal_connect(widget "realize" :window-realize widget) ] sym = slider [ gobj_signal_connect(widget "value-changed" :range-value-changed widget) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 37cd3cbc51..4e0aaa53d8 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -440,6 +440,25 @@ window-size-allocate: func [ ] ] +window-realize: func [ + [cdecl] + widget [handle!] + /local + values [red-value!] + flags [integer!] + bits [integer!] +][ + values: get-face-values widget + flags: get-flags as red-block! values + FACE_OBJ_FLAGS + bits: 1 ;-- GDK_DECOR_ALL + + if flags and FACET_FLAGS_NO_BTNS <> 0 [bits: bits or 16 or 32 or 64] ;-- hide Menu, Min and Max buttons + if flags and FACET_FLAGS_NO_MIN <> 0 [bits: bits or 32] ;-- hide Min button + if flags and FACET_FLAGS_NO_MAX <> 0 [bits: bits or 64] ;-- hide Max button + + gdk_window_set_decorations gtk_widget_get_window widget bits +] + widget-realize: func [ [cdecl] evbox [handle!] From ba4627659d7d27d37b1bff824f69e4eaaf2eb4ed Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 1 Feb 2020 12:09:17 +0100 Subject: [PATCH 0896/3432] FIX: ignore NO-MAX flag --- modules/view/backends/gtk3/gui.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 3cebfad5f4..a5b6eba706 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1632,7 +1632,6 @@ OS-make-view: func [ ] if any [ bits and FACET_FLAGS_NO_MIN <> 0 - bits and FACET_FLAGS_NO_MAX <> 0 bits and FACET_FLAGS_NO_BTNS <> 0 ][ gtk_window_set_type_hint widget 5 ;-- WINDOW_TYPE_HINT_UTILITY From ebad56ada19d5eecdcfa06f86c7fb1ddc5fad7c0 Mon Sep 17 00:00:00 2001 From: bitbegin <bitbegin@gmail.com> Date: Sat, 1 Feb 2020 14:11:49 +0800 Subject: [PATCH 0897/3432] FIX: remove debug print --- modules/view/backends/gtk3/gui.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a5b6eba706..97a8c138d8 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1362,7 +1362,7 @@ font-size?: func [ if any [ TYPE_OF(size) <> TYPE_INTEGER size/value <= 0 - ][print default-font-size return default-font-size] + ][return default-font-size] size/value ] From 5e1be280ccdde25ece875abe7f837ae657043d55 Mon Sep 17 00:00:00 2001 From: bitbegin <bitbegin@gmail.com> Date: Mon, 3 Feb 2020 16:35:59 +0800 Subject: [PATCH 0898/3432] FIX: issue #4267 ([GTK] shift + tab not handled properly) --- modules/view/backends/gtk3/events.reds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 044de16675..a91eaa8e76 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -892,6 +892,10 @@ translate-key: func [ pos: keycode - FF00h + 1 return keycode-special/pos ] + ;-- simple fix #4267 + if keycode = FE20h [ + return RED_VK_TAB + ] RED_VK_UNKNOWN ] From 7d01c85e84c208e6b64544bde295e90733eb21c0 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 4 Feb 2020 19:00:23 +0100 Subject: [PATCH 0899/3432] FIX: issue #4280 --- modules/view/backends/windows/events.reds | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 855815c419..d567fd6d97 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -790,10 +790,11 @@ process-custom-draw: func [ type [red-word!] txt [red-string!] font [red-object!] + para [red-object!] color [red-tuple!] + flags [integer!] sym [integer!] old [integer!] - flags [integer!] DC [handle!] rc [RECT_STRUCT] ][ @@ -813,6 +814,7 @@ process-custom-draw: func [ ][ ;@@ TBD draw image font: as red-object! values + FACE_OBJ_FONT + para: as red-object! values + FACE_OBJ_PARA if TYPE_OF(font) = TYPE_OBJECT [ txt: as red-string! values + FACE_OBJ_TEXT values: object/get-values font @@ -825,14 +827,12 @@ process-custom-draw: func [ SetTextColor DC color/array1 and 00FFFFFFh ] rc: as RECT_STRUCT (as int-ptr! item) + 5 - flags: DT_VCENTER or DT_SINGLELINE - either sym = button [ - flags: flags or DT_CENTER - ][ + unless sym = button [ rc/left: rc/left + dpi-scale 16 ] if TYPE_OF(txt) = TYPE_STRING [ - DrawText DC unicode/to-utf16 txt -1 rc flags + flags: get-para-flags base para + DrawText DC unicode/to-utf16 txt -1 rc flags or DT_SINGLELINE ] SetBkMode DC old return CDRF_SKIPDEFAULT @@ -1586,4 +1586,4 @@ do-events: func [ if exit-loop > 0 [PostQuitMessage 0] ] msg? -] \ No newline at end of file +] From 155d434d033a7198ef2a3fa6157a9635ff3f1151 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 6 Feb 2020 20:07:42 +0100 Subject: [PATCH 0900/3432] FIX: fixed and improved fast UTF-8 decoding routine. --- runtime/unicode.reds | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/runtime/unicode.reds b/runtime/unicode.reds index a0467e36ff..6cb6c5f8f8 100644 --- a/runtime/unicode.reds +++ b/runtime/unicode.reds @@ -39,6 +39,7 @@ unicode: context [ 0C0C0C0C0C180C0C0C0C0C0C0C0C0C240C240C0C0C240C0C0C0C0C240C240C0C 0C240C0C0C0C0C0C0C0C0C0C } + utf8d: utf8d + 1 ;-- switch it to 0-base indexing fast-decode-utf8-char: func [ p [byte-ptr!] @@ -48,28 +49,27 @@ unicode: context [ state byte idx type [integer!] ][ state: 0 + byte: as-integer p/value + type: as-integer utf8d/byte + cp/value: FFh >> type and byte + idx: 256 + state + type + state: as-integer utf8d/idx + p: p + 1 + if zero? state [return p] ;-- fast-path for mono-byte codepoint + forever [ byte: as-integer p/value - idx: byte + 1 - type: as-integer utf8d/idx - - idx: 256 + state + type + 1 - state: as-integer utf8d/idx - + type: as-integer utf8d/byte switch state [ - 0 [ ;-- ACCEPT - cp/value: FFh >> type and byte - return p + 1 - ] - 12 [ ;-- REJECT - cp/value: -1 - return p - ] + 0 [return p] ;-- ACCEPT + 12 [cp/value: -1 return p] ;-- REJECT default [ cp/value: byte and 3Fh or (cp/value << 6) p: p + 1 ] ] + idx: 256 + state + type + state: as-integer utf8d/idx ] as byte-ptr! 0 ;-- never reached, just make compiler happy ] From 3117e893a390bb6808b911111d5de39a279249fd Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 6 Feb 2020 20:12:58 +0100 Subject: [PATCH 0901/3432] FIX: more accurate high codepoint char! values loading. --- runtime/lexer.reds | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fae0ee14d9..c40a42787b 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1069,21 +1069,23 @@ lexer: context [ scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] /local - len c [integer!] + len c [integer!] + do-error [subroutine!] ][ assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] + do-error: [throw-error lex s e TYPE_CHAR] len: as-integer e - s - if len = 2 [throw-error lex s e TYPE_CHAR] ;-- #"" - + if len = 2 [do-error] ;-- #"" + c: -1 + either s/3 = #"^^" [ - if len = 3 [throw-error lex s e TYPE_CHAR] ;-- #"^" - c: -1 + if len = 3 [do-error] ;-- #"^" scan-escaped-char s + 3 e :c ][ ;-- simple char - if len > 3 [throw-error lex s e TYPE_CHAR] - c: as-integer s/3 + s: unicode/fast-decode-utf8-char s + 2 :c + if s < e [do-error] ] - if any [c > 0010FFFFh c = -1][throw-error lex s e TYPE_CHAR] + if any [c > 0010FFFFh c = -1][do-error] lex/value: c lex/in-pos: e + 1 ;-- skip " ] From e832c3dddcac69d8ac6a2da6e50a3497889804e7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Fri, 7 Feb 2020 17:31:21 +0800 Subject: [PATCH 0902/3432] FIX: crashes in dtoa when loading invalid float string. --- runtime/dtoa.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 25c1ba28ce..bdfb36aa3b 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1446,7 +1446,10 @@ dtoa: context [ nd0: ndigits - fraclen e: 0 - if any [c = #"e" c = #"E"][ + if all [ + any [c = #"e" c = #"E"] + s + 1 < end + ][ s: s + 1 e-neg?: no From b08022dcd71710eee9030c11da4b840bcbac3e85 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 7 Feb 2020 15:50:57 +0100 Subject: [PATCH 0903/3432] FIX: invalid loaded string tail for UCS2/4. --- runtime/lexer.reds | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c40a42787b..c5b5a18f64 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1115,7 +1115,10 @@ lexer: context [ str: string/make-at alloc-slot lex len unit ser: GET_BUFFER(str) switch unit [ - UCS-1 [copy-memory as byte-ptr! ser/offset s len] + UCS-1 [ + copy-memory as byte-ptr! ser/offset s len + ser/tail: as cell! (as byte-ptr! ser/offset) + len + ] UCS-2 [ cp: -1 p: as byte-ptr! ser/offset @@ -1126,6 +1129,7 @@ lexer: context [ p/2: as-byte cp >> 8 p: p + 2 ] + ser/tail: as cell! p ] UCS-4 [ cp: -1 @@ -1136,9 +1140,9 @@ lexer: context [ p4/value: cp p4: p4 + 1 ] + ser/tail: as cell! p4 ] ] - ser/tail: as cell! (as byte-ptr! ser/offset) + (len << (unit >> 1)) ][ ;-- prescan the string for determining unit and accurate final codepoints count extra: 0 ;-- count extra bytes used by escape sequences From 90ef11131136af1ef076755b455f6d79660eea3d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 7 Feb 2020 21:29:09 +0100 Subject: [PATCH 0904/3432] FEAT: strict format validation on scanning float values. --- docs/lexer/lexer-FSM.xlsx | Bin 18992 -> 21210 bytes docs/lexer/lexer-states.txt | 33 +++++++++++++++++++- runtime/lexer.reds | 53 +++++++++++++++++++++++++++++---- utils/generate-misc-tables.red | 28 +++++++++++++++++ 4 files changed, 107 insertions(+), 7 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 6b8ee1a1959d4fe4a9778c2136fcff48d211d548..824b07715957ae5f9d1112ad5bdd7b8fad7ce116 100644 GIT binary patch delta 14194 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 DyTr!s delta 12958 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index df5d29548b..c6a62145d4 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -377,4 +377,35 @@ C_BIN_BLANK : space, tab, cr, lf ;-- 1 C_BIN_HEXA : 0-9, a-f, A-F ;-- 2 C_BIN_CMT : ; ;-- 3 - \ No newline at end of file +=== Float FSM === + +C_FL_ILLEGAL : all the rest ;-- 0 +C_FL_SIGN : +, - ;-- 1 +C_FL_DIGIT : 0-9 ;-- 2 +C_FL_EXP : e, E ;-- 3 +C_FL_DOT : . ;-- 4 + +S_FL_START ;-- 0 +S_FL_NUM ;-- 1 +S_FL_DEC ;-- 2 +S_FL_EXP ;-- 3 +S_FL_EXPS ;-- 4 +S_FL_EXPD ;-- 5 +T_FL_FLOAT ;-- 6 +T_FL_ERROR ;-- 7 + + +S_FL_START->"+"|"-"->S_FL_START + +S_FL_START->"."->S_FL_DEC + \->digit->S_FL_NUM->digit->S_FL_NUM + \->"."->S_FL_DEC + \->"e"|"E"->S_FL_EXP + +S_FL_DEC->digit->S_FL_DEC + \->"e"|"E"->S_FL_EXP + +S_FL_EXP->"+"|"-"->S_FL_EXPS->digit->S_FL_EXPD + \->digit->S_FL_EXPD + +S_FL_EXPD->digit->S_FL_EXPD \ No newline at end of file diff --git a/runtime/lexer.reds b/runtime/lexer.reds index c5b5a18f64..897bdf8235 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -88,6 +88,15 @@ lexer: context [ C_BIN_HEXA ;-- 2 C_BIN_CMT ;-- 3 ] + + #enum float-char-classes! [ + C_FL_ILLEGAL ;-- 0 + C_FL_SIGN ;-- 1 + C_FL_DIGIT ;-- 2 + C_FL_EXP ;-- 3 + C_FL_DOT ;-- 4 + C_FL_EOF ;-- 5 + ] line-table: #{ 0001000000000000000000000000000000000000000000000000000000000000 @@ -105,6 +114,13 @@ lexer: context [ 00000000000101 } + float-classes: #{ + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000010001040002020202020202020202000000000000 + 0000000000030000000000000000000000000000000000000000000000000000 + 00000000000300 + } + bin16-classes: #{ 0000000000000000000101000001000000000000000000000000000000000000 0100000000000000000000000000000002020202020202020202000300000000 @@ -127,6 +143,10 @@ lexer: context [ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF } + float-transitions: #{ + 070001070207070701030206070702030706070405070707070705070707070705070706070707070707 + } + ;-- Bit-array for /-~^{}" char-special: #{0000000004A00000000000400000006800000000000000000000000000000000} @@ -1090,6 +1110,24 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip " ] + scan-float: func [lex [state!] s e [byte-ptr!] flags [integer!] + /local + state index class [integer!] + ][ + state: 0 ;-- S_FL_START + until [ + index: as-integer s/1 + class: as-integer float-classes/index + index: state * (size? float-char-classes!) + class + state: as-integer float-transitions/index + s: s + 1 + s = e + ] + index: state * (size? float-char-classes!) + C_FL_EOF + state: as-integer float-transitions/index + if state = 7 [throw-error lex s e TYPE_FLOAT] ;-- T_FL_ERROR + ] + load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!]][ integer/make-at alloc-slot lex lex/value lex/in-pos: e ;-- reset the input position to delimiter byte @@ -1992,11 +2030,14 @@ lexer: context [ utf8-buf-tail: utf8-buffer ;-- switch following tables to zero-based indexing - lex-classes: lex-classes + 1 - transitions: transitions + 1 - skip-table: skip-table + 1 - line-table: line-table + 1 - type-table: type-table + 1 + lex-classes: lex-classes + 1 + transitions: transitions + 1 + skip-table: skip-table + 1 + line-table: line-table + 1 + type-table: type-table + 1 + + float-classes: float-classes + 1 + float-transitions: float-transitions + 1 set-jump-tables [ :scan-eof null ;-- T_EOF @@ -2020,7 +2061,7 @@ lexer: context [ null :load-file ;-- T_FILE null :load-binary ;-- T_BINARY null :load-percent ;-- T_PERCENT - null :load-float ;-- T_FLOAT + :scan-float :load-float ;-- T_FLOAT null :load-float-special ;-- T_FLOAT_SP null :load-tuple ;-- T_TUPLE null :load-date ;-- T_DATE diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index aef141b22d..5e39358749 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -66,6 +66,34 @@ gen-hexa-table: function [][ probe out ] +float-classes: [ + C_FL_ILLEGAL ;-- 0 + C_FL_SIGN ;-- 1 + C_FL_DIGIT ;-- 2 + C_FL_EXP ;-- 3 + C_FL_DOT ;-- 4 + C_FL_EOF ;-- 5 +] + +gen-float-classes-table: function [][ + out: make binary! 256 + digit: charset [#"0" - #"9"] + + repeat i 256 [ + c: to-char i - 1 + append out case [ + find digit c [2] + c = #"." [4] + find "+-" c [1] + find "eE" c [3] + 'else [0] + ] + ] + print "--gen-fl-classes-- (lexer/fl-classes)" + probe out +] + gen-bitarray {/-~^^{}"} gen-bin16-table gen-hexa-table +gen-float-classes-table From 157c351b1a5c0a64d082d087ac555c1c5e4c9165 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sat, 8 Feb 2020 01:17:31 +0100 Subject: [PATCH 0905/3432] FIX: minor fix for the type of Redbin string conversion buffer. --- utils/redbin.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/redbin.r b/utils/redbin.r index e24a75e8f7..6b26de665a 100644 --- a/utils/redbin.r +++ b/utils/redbin.r @@ -22,7 +22,7 @@ context [ UTF8-char: lexer/UTF8-char chars: make block! 10'000 - decoded: make string! 10'000 + decoded: make binary! 10'000 nl-flag: to-integer #{80000000} ;-- header's new-line flag nl?: no From 3693a10c145b97d3631a86c07129ba604bd44929 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sat, 8 Feb 2020 20:21:47 +0100 Subject: [PATCH 0906/3432] FIX: fixes some float! value loading edge cases. --- docs/lexer/lexer-FSM.csv | 11 +-- docs/lexer/lexer-FSM.xlsx | Bin 21210 -> 21370 bytes docs/lexer/lexer-states.txt | 87 +++++++++++--------- runtime/lexer-transitions.reds | 144 +++++++++++++++++---------------- runtime/lexer.reds | 2 +- utils/generate-lexer-table.red | 131 +++++++++++++++--------------- 6 files changed, 193 insertions(+), 182 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index aadd8c368a..2892ae9ce0 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -19,10 +19,11 @@ S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_C S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_CONS_MK;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;S_CONSTRUCT;T_ERROR;T_ERROR S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_HEX_END2;S_DECIMAL;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER -S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;S_DECIMAL;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_HEX_END2;S_DECEXP;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;T_ERROR;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE @@ -49,7 +50,7 @@ S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_W1ST;S_PATH_W1ST;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR -S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECIMAL;S_DECIMAL;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER +S_PATH_NUM;T_INTEGER;T_INTEGER;S_PATH_NUM;S_PATH_NUM;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_ERROR;S_NUMBER;T_INTEGER;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_INTEGER;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_PATH_W1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_PATH_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_WORD;T_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_WORD S_PATH_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 824b07715957ae5f9d1112ad5bdd7b8fad7ce116..02271afe925f187957b1008aa70d16a22e284b40 100644 GIT binary patch delta 9868 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 L(n1Z6e*6CbKh;as delta 9716 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 a>Oe?P9jbws`cz~M6hfbmrbzqf)Bgu-fB}gB diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index c6a62145d4..a92065c8a7 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -24,6 +24,7 @@ S_ISSUE S_NUMBER S_DOTNUM S_DECIMAL +S_DECEXP S_DECX S_DEC_SPECIAL S_TUPLE @@ -211,47 +212,53 @@ S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY S_START->digit->S_NUMBER->digit|"'"->S_NUMBER \->delimit10->T_INTEGER - \->"%"->T_PERCENT - \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"e"|"E"|"+"|"-"|"'"->S_DECIMAL - \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE - \ \ \ \->delimit11->T_TUPLE - \ \ \ \->else->T_ERROR - \ \ \ - \ \ \->"%"->T_PERCENT - \ \ \->"x"|"X"->S_PAIR_1ST - \ \ \->delimit11->T_FLOAT - \ \ \->else->T_ERROR - \ \ - \ \->"#"->S_DEC_SPECIAL->not(delimit12)->S_DEC_SPECIAL - \ \ \->delimit12->T_FLOAT_SP + \->"."->S_DOTNUM->digit->S_DECIMAL->digit|"'"->S_DECIMAL + \ \ \->"e"|"E"->S_DECEXP->digit|"+"|"-"|"'"->S_DECEXP + \ \ \ \->delimit11->T_FLOAT + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"."->S_TUPLE->digit|"."->S_TUPLE + \ \ \ \->delimit11->T_TUPLE + \ \ \ \->else->T_ERROR + \ \ \ + \ \ \->"%"->T_PERCENT + \ \ \->"x"|"X"->S_PAIR_1ST + \ \ \->delimit11->T_FLOAT + \ \ \->else->T_ERROR \ \ - \ \->"%"->T_PERCENT - \ \->"x"|"X"->S_PAIR_1ST - \ \->"e"|"E"|"'"->S_DECIMAL - \ \->delimit11->T_FLOAT - \ \->else->T_ERROR - \ - \->"/"|"T"->S_DATE->not(delimit13)->S_DATE - \ \->delimit13->T_DATE + \ \->"#"->S_DEC_SPECIAL->not(delimit12)->S_DEC_SPECIAL + \ \ \->delimit12->T_FLOAT_SP + \ \ + \ \->"%"->T_PERCENT + \ \->"x"|"X"->S_PAIR_1ST + \ \->"e"|"E"|"'"->S_DECEXP + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR \ - \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME - \ \->else->T_ERROR \->delimit11->T_TIME - \ \->else->T_ERROR - \ - \->"x"|"X"->S_PAIR_1ST->digit|sign->S_PAIR->digit|"."|"e"|"E"->S_PAIR - \ \->else->T_ERROR \->delimit10->T_PAIR - \ \->else->T_ERROR - \ - \->"#"->S_SHARP - \->"@"->S_EMAIL - \->"e"->S_DECIMAL - \->"E"->S_DECX->digit->S_DECX - \ \->alphaU|"E"->S_HEX - \ \->"h"->T_HEX - \ \->delimit11->T_FLOAT - \->alphaU->S_HEX - \->"h"->T_HEX - \->else->T_ERROR + \->"/"|"T"->S_DATE->not(delimit13)->S_DATE + \ \->delimit13->T_DATE + \ + \->":"->S_TIME_1ST->digit->S_TIME->digit|":"|"."->S_TIME + \ \->else->T_ERROR \->delimit11->T_TIME + \ \->else->T_ERROR + \ + \->"x"|"X"->S_PAIR_1ST->digit|sign->S_PAIR->digit|"."|"e"|"E"->S_PAIR + \ \->else->T_ERROR \->delimit10->T_PAIR + \ \->else->T_ERROR + \ + \->"%"->T_PERCENT + \->"#"->S_SHARP + \->"@"->S_EMAIL + \->"e"->S_DECEXP + \->"E"->S_DECX->digit->S_DECX + \ \->"+"|"-"->S_DECEXP + \ \->alphaU|"E"->S_HEX + \ \->"h"->T_HEX + \ \->delimit11->T_FLOAT + \ \->else->T_ERROR + \->alphaU->S_HEX + \->"h"->T_HEX + \->else->T_ERROR S_START->"."->S_DOTWORD->digit->S_DOTDEC->digit|"e"|"E"|"+"|"-"|"'"->S_DOTDEC @@ -342,7 +349,7 @@ S_PATH->digit->S_PATH_NUM->digit|"'"->S_PATH_NUM \ \->else->T_ERROR \->delimit10->T_PAIR \ \->else->T_ERROR \ - \->"e"|"E"->S_DECIMAL + \->"e"|"E"->S_DECEXP \->else->T_ERROR S_PATH->"<"->S_LESSER diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 6503856a5c..a9d2cc225f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -25,6 +25,7 @@ Red/System [ S_NUMBER S_DOTNUM S_DECIMAL + S_DECEXP S_DECX S_DEC_SPECIAL S_TUPLE @@ -95,77 +96,78 @@ Red/System [ 0000000000000000000000000000000000010001010000000000000001000000 } type-table: #{ -0000070707070808080808130F1429000A0A00140B0C0C0C0C272F2B2B252533 -33330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F000000000000000007 -000000000B00130A14070829260C0C272F252B332C092D0B +0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 +3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000000000000000 +07000000000B00130A14070829260C0C272F252B332C092D0B } transitions: #{ -000014143A3B3C3D3E39020D2C2C2D2D2D2D222D220B39252D2D063901392A1F -2929392D2D393801430101010101010101010101010101010101010101010101 -0101010101010101010101013938020202020202020202024902020202020202 -0202020202020202020202020202020203020239390202020202020202020202 -0202020202020202020202020202020202020202020202020202393804040404 -040404043E3F0404040404040404040404040404040404040404040404040504 -0439390404040404040404040404040404040404040404040404040404040404 -04040404040404043938454507074545454545450A0707450707070707070707 -07070707070745450707070707070739454A4A07074A4A4A4A4A4A3907074A07 -070707070707070707070708074A4A07070707070707394A0707090939393939 -3939393939393939390909090939393939393939393939393939393939393907 -0707073939393939393939393939393909090707393939393939393939393939 -39393939394A0A0A0A0A0A0A0A0A0A0A4A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A393946460B0B464646464646460B0B0B0B0B0B0B0B -0B0B0C0B0B0B0B0B0B46460B0B0B0B0B0B0B394645452D2D4545454545454539 -2D2D2D2D2D2D2D2D2D0C2D2D2D2D392D45452D392D2D2D2D2D39454848131312 -3940390E39101313391313131313131313133939391339484813131313131313 -39480E0E0E0E39393939394B393939390E0E0E0E0E0E0E0E3939390E39390F39 -39390E3939390E39390F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F393810101010101010101010471010101010 -1010101010101010101010101010101010101110103947101010101010101010 -1010101010101010101010101010101010101010101010101010101039391212 -1212124212121212121212121212121212121212121212121212121212121212 -1212123939484813134848484848484813131313131313131313131313131313 -13484813131313131313394844441414444444444444440D141B1D1A24161739 -221A394439394C1544301539391A39393939444D4D16164D4D4D4D4D4D4D1816 -391D3939161639394D394D39394C394D3939393939393939394D4D4D16164D4D -4D4D4D4D4D39394D393939161639394D394D39394C3939301939161639393939 -4D4D4D17174D4D4D4D4D4D4D39394D393924162239224D394D39394C39393019 -391616393939394D4D4D4D4E4E4E4E4E4E4E4E184E4E181818181818184E4E4E -18184E4E4E4E184E18184E1818394E4F4F19194F4F4F4F4F4F4F39394F393939 -393939394F394F39393939393919393939393939394F50501A1A505050505050 -501A1A1A1A1A1A1A1A1A1A1A1A501A1A501A50501A501A1A50391A395039391C -1C39393939393939393939393939393939393939393939393939393939393939 -3939393952521C1C5252525252525239391C3939393939393952395239393939 -52391C393939393939395239391E1E3939393939393939393939393939393939 -39393939393939393039391E1E393939393951511E1E51515151515151393951 -3939391E1E39395139513939393951301E393939393939395139392020393939 -3939393939393939393939393939393939393939393939393939393939393939 -5353202053535353535353532053393939393939395339533939393953392139 -3939393939393853532121535353535353535321533939393939393953395339 -39393953393939393939393939384545222245454545454545392D2E2D2D232D -222D2241452D2D2D393945302D202D2D2D2D2D394557572D2D57575757575757 -392D2E2D2D2D2D2D2D2D41572D2D2D393957302D202D2D2D2D2D395757573939 -5757575757575739393939393939393939415757393939395730392039393939 -39395745452626454545454545452626452626262626262626262D2D2D262645 -4526262626262626394526262626262626262626272628262626262626262626 -2626542626262626262626262626263939272727272727272727272627272727 -2727272727272727272727272727272727272727272739392828282828282828 -2828282826282828282828282828282828282828282828282828282828393945 -4514144545454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2A2D2D -2D392D2D394545452B2B45454545454545392D2E2D2D2D2B2B2D2D41452D2D2D -393945302D392B2B2D2D2D39454D4D2B2B4D4D4D4D4D4D4D39394D1D39392B2B -39394D394D39394C39393939392B2B393939394D393939393939393939393939 -39392D2D2D2D2D2D2D0B392D2D2D393939392D392D2D392D2D393945452D2D45 -454545454545392D2E2D2D2D2D2D2D2D41452D2D2D393945302D202D2D2D2D2D -394545452F2F454545454545452F2F2F2F2F2F2F2F2F2F2F45392F2F2F2F452F -2F2F2F2F2F2F2F394555552F2F555555555555552F392F2F2F2F2F2F2F2F2F55 -55392F2F55552F2F392F2F392F2F395556563030565656565656563939393030 -30303030305656563939303956393039303039303039563939323239393C3D39 -3902353333343434343434343939253434393939303439363639343439394444 -3232444444444444443914441D39391616393944394439394C15443015393939 -3939393944393939393939393939393939393934343434343434393934343439 -3939393439343439343439394545343445454545454545393445343434343434 -3445453434343939453034393434343434394548481313123939393939101313 -3913131313131313131339393913394848131313131313133948454532324545 -454545454539392D2D2D2D2D2D2D2D2D45392D2D392D452D2D2D2D2D392D2D39 -45 +000014143B3C3D3E3F3A020D2D2D2E2E2E2E232E230B3A262E2E063A013A2B20 +2A2A3A2E2E3A3901440101010101010101010101010101010101010101010101 +0101010101010101010101013A39020202020202020202024A02020202020202 +020202020202020202020202020202020302023A3A0202020202020202020202 +02020202020202020202020202020202020202020202020202023A3904040404 +040404043F400404040404040404040404040404040404040404040404040504 +043A3A0404040404040404040404040404040404040404040404040404040404 +04040404040404043A39464607074646464646460A0707460707070707070707 +0707070707074646070707070707073A464B4B07074B4B4B4B4B4B3A07074B07 +070707070707070707070708074B4B070707070707073A4B070709093A3A3A3A +3A3A3A3A3A3A3A3A3A090909093A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A07 +0707073A3A3A3A3A3A3A3A3A3A3A3A3A090907073A3A3A3A3A3A3A3A3A3A3A3A +3A3A3A3A3A4B0A0A0A0A0A0A0A0A0A0A4B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A3A3A47470B0B474747474747470B0B0B0B0B0B0B0B +0B0B0C0B0B0B0B0B0B47470B0B0B0B0B0B0B3A4746462E2E464646464646463A +2E2E2E2E2E2E2E2E2E0C2E2E2E2E3A2E46462E3A2E2E2E2E2E3A464949131312 +3A413A0E3A1013133A1313131313131313133A3A3A133A494913131313131313 +3A490E0E0E0E3A3A3A3A3A4C3A3A3A3A0E0E0E0E0E0E0E0E3A3A3A0E3A3A0F3A +3A3A0E3A3A3A0E3A3A0F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F3A3910101010101010101010481010101010 +1010101010101010101010101010101010101110103A48101010101010101010 +101010101010101010101010101010101010101010101010101010103A3A1212 +1212124312121212121212121212121212121212121212121212121212121212 +1212123A3A494913134949494949494913131313131313131313131313131313 +134949131313131313133A4945451414454545454545450D141C1E1B2517183A +231B3A453A3A4D154531153A3A1B3A3A3A3A454E4E16164E4E4E4E4E4E4E1916 +3A1E3A3A17173A3A4E3A4E3A3A4D3A4E3A3A3A3A3A3A3A3A3A4E4E4E16164E4E +4E4E4E4E4E3A3A4E1E3A3A17173A3A4E3A4E3A3A4D3A3A311A3A3A3A3A3A3A3A +4E4E4E17174E4E4E4E4E4E4E3A3A4E3A3A3A3A3A3A3A4E3A4E3A3A3A3A3A313A +3A3A3A3A3A3A3A4E4E4E18184E4E4E4E4E4E4E3A3A4E3A3A253A233A234E3A4E +3A3A4D3A3A311A3A17173A3A3A3A4E4E4E4E4F4F4F4F4F4F4F4F194F4F191919 +191919194F4F4F19194F4F4F4F194F19194F19193A4F50501A1A505050505050 +503A3A503A3A3A3A3A3A3A503A503A3A3A3A3A3A1A3A3A3A3A3A3A3A5051511B +1B515151515151511B1B1B1B1B1B1B1B1B1B1B1B511B1B511B51511B511B1B51 +3A1B3A513A3A1D1D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A +3A3A3A3A3A3A3A3A3A3A3A53531D1D535353535353533A3A1D3A3A3A3A3A3A3A +533A533A3A3A3A533A1D3A3A3A3A3A3A3A533A3A1F1F3A3A3A3A3A3A3A3A3A3A +3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A313A3A1F1F3A3A3A3A3A52521F1F525252 +525252523A3A523A3A3A1F1F3A3A523A523A3A3A3A52311F3A3A3A3A3A3A3A52 +3A3A21213A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A +3A3A3A3A3A3A3A54542121545454545454545421543A3A3A3A3A3A3A543A543A +3A3A3A543A223A3A3A3A3A3A3A3954542222545454545454545422543A3A3A3A +3A3A3A543A543A3A3A3A543A3A3A3A3A3A3A3A3A394646232346464646464646 +3A2E2F2E2E242E232E2342462E2E2E3A3A46312E212E2E2E2E2E3A4658582E2E +585858585858583A2E2F2E2E2E2E2E2E2E42582E2E2E3A3A58312E212E2E2E2E +2E3A5858583A3A585858585858583A3A3A3A3A3A3A3A3A3A4258583A3A3A3A58 +313A213A3A3A3A3A3A5846462727464646464646462727462727272727272727 +272E2E2E27274646272727272727273A46272727272727272727272827292727 +272727272727272727552727272727272727272727273A3A2828282828282828 +28282728282828282828282828282828282828282828282828282828283A3A29 +2929292929292929292929272929292929292929292929292929292929292929 +292929293A3A46461414464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E +3A2E462E2B2E2E2E3A2E2E3A4646462C2C464646464646463A2E2F2E2E2E2C2C +2E2E42462E2E2E3A3A46312E3A2C2C2E2E2E3A464E4E2C2C4E4E4E4E4E4E4E3A +3A4E1E3A3A2C2C3A3A4E3A4E3A3A4D3A3A3A3A3A2C2C3A3A3A3A4E3A3A3A3A3A +3A3A3A3A3A3A3A3A3A2E2E2E2E2E2E2E0B3A2E2E2E3A3A3A3A2E3A2E2E3A2E2E +3A3A46462E2E464646464646463A2E2F2E2E2E2E2E2E2E42462E2E2E3A3A4631 +2E212E2E2E2E2E3A464646303046464646464646303030303030303030303046 +3A303030304630303030303030303A465656303056565656565656303A303030 +30303030303056563A3030565630303A30303A30303A56575731315757575757 +57573A3A3A313131313131315757573A3A313A573A313A31313A31313A573A3A +33333A3A3D3E3A3A02363434353535353535353A3A2635353A3A3A31353A3737 +3A35353A3A45453333454545454545453A14451E3A3A17173A3A453A453A3A4D +154531153A3A3A3A3A3A3A453A3A3A3A3A3A3A3A3A3A3A3A3A3A353535353535 +353A3A3535353A3A3A3A353A35353A35353A3A46463535464646464646463A35 +463535353535353546463535353A3A4631353A35353535353A4649491313123A +3A3A3A3A1013133A1313131313131313133A3A3A133A4949131313131313133A +4946463333464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E3A2E462E2E +2E2E2E3A2E2E3A46 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 897bdf8235..02c83b4582 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -106,7 +106,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000 } path-ending: #{ diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index ab7ffa52f4..a5c245aa6b 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -36,71 +36,72 @@ context [ S_NUMBER TYPE_INTEGER ;-- 20 S_DOTNUM TYPE_FLOAT ;-- 21 S_DECIMAL TYPE_FLOAT ;-- 22 - S_DECX TYPE_FLOAT ;-- 23 - S_DEC_SPECIAL TYPE_FLOAT ;-- 24 - S_TUPLE TYPE_TUPLE ;-- 25 - S_DATE TYPE_DATE ;-- 26 - S_TIME_1ST TYPE_TIME ;-- 27 - S_TIME TYPE_TIME ;-- 28 - S_PAIR_1ST TYPE_PAIR ;-- 29 - S_PAIR TYPE_PAIR ;-- 30 - S_MONEY_1ST TYPE_MONEY ;-- 31 - S_MONEY TYPE_MONEY ;-- 32 - S_MONEY_DEC TYPE_MONEY ;-- 33 - S_HEX TYPE_INTEGER ;-- 34 - S_HEX_END TYPE_WORD ;-- 35 - S_HEX_END2 TYPE_INTEGER ;-- 36 - S_LESSER TYPE_TAG ;-- 37 - S_TAG TYPE_TAG ;-- 38 - S_TAG_STR TYPE_TAG ;-- 39 - S_TAG_STR2 TYPE_TAG ;-- 40 - S_SIGN TYPE_WORD ;-- 41 - S_DOTWORD TYPE_WORD ;-- 42 - S_DOTDEC TYPE_FLOAT ;-- 43 - S_WORD_1ST TYPE_WORD ;-- 44 - S_WORD TYPE_WORD ;-- 45 - S_WORDSET TYPE_SET_WORD ;-- 46 - S_URL TYPE_URL ;-- 47 - S_EMAIL TYPE_EMAIL ;-- 48 - S_PATH TYPE_PATH ;-- 49 - S_PATH_NUM TYPE_INTEGER ;-- 50 - S_PATH_W1ST TYPE_WORD ;-- 51 - S_PATH_WORD TYPE_WORD ;-- 52 - S_PATH_SHARP TYPE_ISSUE ;-- 53 - S_PATH_SIGN TYPE_WORD ;-- 54 - --EXIT_STATES-- - ;-- 55 - T_EOF - ;-- 56 - T_ERROR - ;-- 57 - T_BLK_OP - ;-- 58 - T_BLK_CL - ;-- 59 - T_PAR_OP - ;-- 60 - T_PAR_CL - ;-- 61 - T_MSTR_OP - ;-- 62 - T_MSTR_CL TYPE_STRING ;-- 63 - T_MAP_OP - ;-- 64 - T_PATH - ;-- 65 - T_CONS_MK - ;-- 66 - T_CMT - ;-- 67 - T_INTEGER TYPE_INTEGER ;-- 68 - T_WORD - ;-- 69 - T_REFINE TYPE_REFINEMENT ;-- 70 - T_CHAR TYPE_CHAR ;-- 71 - T_ISSUE TYPE_ISSUE ;-- 72 - T_STRING TYPE_STRING ;-- 73 - T_FILE TYPE_FILE ;-- 74 - T_BINARY TYPE_BINARY ;-- 75 - T_PERCENT TYPE_PERCENT ;-- 76 - T_FLOAT TYPE_FLOAT ;-- 77 - T_FLOAT_SP TYPE_FLOAT ;-- 78 - T_TUPLE TYPE_TUPLE ;-- 79 - T_DATE TYPE_DATE ;-- 80 - T_PAIR TYPE_PAIR ;-- 81 - T_TIME TYPE_TIME ;-- 82 - T_MONEY TYPE_MONEY ;-- 83 - T_TAG TYPE_TAG ;-- 84 - T_URL TYPE_URL ;-- 85 - T_EMAIL TYPE_EMAIL ;-- 86 - T_HEX TYPE_INTEGER ;-- 87 + S_DECEXP TYPE_FLOAT ;-- 23 + S_DECX TYPE_FLOAT ;-- 24 + S_DEC_SPECIAL TYPE_FLOAT ;-- 25 + S_TUPLE TYPE_TUPLE ;-- 26 + S_DATE TYPE_DATE ;-- 27 + S_TIME_1ST TYPE_TIME ;-- 28 + S_TIME TYPE_TIME ;-- 29 + S_PAIR_1ST TYPE_PAIR ;-- 30 + S_PAIR TYPE_PAIR ;-- 31 + S_MONEY_1ST TYPE_MONEY ;-- 32 + S_MONEY TYPE_MONEY ;-- 33 + S_MONEY_DEC TYPE_MONEY ;-- 34 + S_HEX TYPE_INTEGER ;-- 35 + S_HEX_END TYPE_WORD ;-- 36 + S_HEX_END2 TYPE_INTEGER ;-- 37 + S_LESSER TYPE_TAG ;-- 38 + S_TAG TYPE_TAG ;-- 39 + S_TAG_STR TYPE_TAG ;-- 40 + S_TAG_STR2 TYPE_TAG ;-- 41 + S_SIGN TYPE_WORD ;-- 42 + S_DOTWORD TYPE_WORD ;-- 43 + S_DOTDEC TYPE_FLOAT ;-- 44 + S_WORD_1ST TYPE_WORD ;-- 45 + S_WORD TYPE_WORD ;-- 46 + S_WORDSET TYPE_SET_WORD ;-- 47 + S_URL TYPE_URL ;-- 48 + S_EMAIL TYPE_EMAIL ;-- 49 + S_PATH TYPE_PATH ;-- 50 + S_PATH_NUM TYPE_INTEGER ;-- 51 + S_PATH_W1ST TYPE_WORD ;-- 52 + S_PATH_WORD TYPE_WORD ;-- 53 + S_PATH_SHARP TYPE_ISSUE ;-- 54 + S_PATH_SIGN TYPE_WORD ;-- 55 + --EXIT_STATES-- - ;-- 56 + T_EOF - ;-- 57 + T_ERROR - ;-- 58 + T_BLK_OP - ;-- 59 + T_BLK_CL - ;-- 60 + T_PAR_OP - ;-- 61 + T_PAR_CL - ;-- 62 + T_MSTR_OP - ;-- 63 + T_MSTR_CL TYPE_STRING ;-- 64 + T_MAP_OP - ;-- 65 + T_PATH - ;-- 66 + T_CONS_MK - ;-- 67 + T_CMT - ;-- 68 + T_INTEGER TYPE_INTEGER ;-- 69 + T_WORD - ;-- 70 + T_REFINE TYPE_REFINEMENT ;-- 71 + T_CHAR TYPE_CHAR ;-- 72 + T_ISSUE TYPE_ISSUE ;-- 73 + T_STRING TYPE_STRING ;-- 74 + T_FILE TYPE_FILE ;-- 75 + T_BINARY TYPE_BINARY ;-- 76 + T_PERCENT TYPE_PERCENT ;-- 77 + T_FLOAT TYPE_FLOAT ;-- 78 + T_FLOAT_SP TYPE_FLOAT ;-- 79 + T_TUPLE TYPE_TUPLE ;-- 80 + T_DATE TYPE_DATE ;-- 81 + T_PAIR TYPE_PAIR ;-- 82 + T_TIME TYPE_TIME ;-- 83 + T_MONEY TYPE_MONEY ;-- 84 + T_TAG TYPE_TAG ;-- 85 + T_URL TYPE_URL ;-- 86 + T_EMAIL TYPE_EMAIL ;-- 87 + T_HEX TYPE_INTEGER ;-- 88 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 40900309d46d3e9589b032c57a77a82838306a8a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sat, 8 Feb 2020 20:29:50 +0100 Subject: [PATCH 0907/3432] TESTS: adds passing/non-passing tests for float literal formats. --- tests/source/units/lexer-test.red | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 5a5028063f..c0a5f6a5cf 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -503,6 +503,12 @@ Red [ --test-- "scan-21" --assert lit-word! = scan "'//////////" --test-- "scan-22" --assert get-word! = scan "://////////" + --test-- "scan-23" + allow: ["1.2" "123.456789" "123." "123." ".1" "1e2" "+1.0" "-1.0" "+1e2" "-1.0e2" "123.e1"] + deny: ["123.." "123.e" "123e" "123E" "1e" "1E" "1e." "-1e" "-1e."] + foreach s allow [--test-- s --assert float! = scan s] + foreach s deny [--test-- s --assert error! = scan s] + ===end-group=== ===start-group=== "transcode/trace" From 002ef99b58198ded149fced23be9ebe3be3157ed Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 11 Feb 2020 00:36:01 +0100 Subject: [PATCH 0908/3432] FIX: avoids generating a `close path!` lexer event on invalid paths. --- runtime/lexer.reds | 12 ++++++------ tests/source/units/lexer-test.red | 2 -- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 02c83b4582..04173a98bc 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -518,7 +518,7 @@ lexer: context [ lex/entry: S_START ] - close-block: func [lex [state!] s e [byte-ptr!] type [integer!] + close-block: func [lex [state!] s e [byte-ptr!] type [integer!] quiet? [logic!] return: [integer!] /local p [red-point!] @@ -532,7 +532,7 @@ lexer: context [ ] p: as red-point! lex/head - 1 point?: all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] - if lex/fun-ptr <> null [ + if all [not quiet? lex/fun-ptr <> null][ t: either point? [p/y][type] unless fire-event lex words/_close t null s e [return 0] ] @@ -856,7 +856,7 @@ lexer: context [ scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][] scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ - if all [lex/fun-ptr <> null lex/entry = S_PATH][close-block lex s e -1] + if all [lex/fun-ptr <> null lex/entry = S_PATH][close-block lex s e -1 yes] either lex/prev < --EXIT_STATES-- [ index: lex/prev index: as-integer type-table/index @@ -874,7 +874,7 @@ lexer: context [ ] scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - close-block lex s e TYPE_BLOCK + close-block lex s e TYPE_BLOCK no lex/in-pos: e + 1 ;-- skip ] ] @@ -882,7 +882,7 @@ lexer: context [ /local blk [red-block!] ][ - if TYPE_MAP = close-block lex s e TYPE_PAREN [ + if TYPE_MAP = close-block lex s e TYPE_PAREN no [ lex/scanned: TYPE_MAP if lex/load? [ blk: as red-block! lex/tail - 1 @@ -958,7 +958,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip : TYPE_SET_PATH ][-1] - close-block lex s e type + close-block lex s e type no ][ if e + 1 = lex/in-end [throw-error lex null e TYPE_PATH] ;-- incomplete path error if e/1 = #":" [throw-error lex null e TYPE_PATH] ;-- set-words not allowed inside paths diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index c0a5f6a5cf..e3b9a46380 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -538,7 +538,6 @@ Red [ load integer! datatype! 1 1 open path! datatype! 1 6x6 load word! datatype! 1 b - close path! datatype! 1 8x8 error error! datatype! 1 8x8 open block! datatype! 1 9x9 close block! datatype! 1 10x10 @@ -554,7 +553,6 @@ Red [ load integer! datatype! 1 1 open path! datatype! 1 6x6 load word! datatype! 1 b - close path! datatype! 1 8x8 error error! datatype! 1 8x8 scan word! word! 1 9x10 load word! datatype! 1 x From 593eab274d4014c326ed296b4782d532b19067f7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 11 Feb 2020 18:10:29 +0100 Subject: [PATCH 0909/3432] FEAT: more aggressive object path words rebinding to parent context. This fixes the missing calls issue in stack traces. A notable side-effect of this change is a faster compiled paths evaluation on second use, as all the nested words will be properly bound already. --- compiler.r | 14 ++++++++++++-- runtime/datatypes/context.reds | 19 +++++++++++++++++++ runtime/datatypes/object.reds | 9 +-------- runtime/datatypes/word.reds | 5 +++++ runtime/interpreter.reds | 3 +++ runtime/stack.reds | 4 ++-- system/utils/libRedRT-exports.r | 1 + tests/source/units/recycle-test.red | 10 +++++----- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/compiler.r b/compiler.r index a9654f279e..0a8ef71d91 100644 --- a/compiler.r +++ b/compiler.r @@ -447,7 +447,7 @@ red: context [ append blk decorate-symbol/no-alias name ;-- local word, point to value slot ][ append blk [as cell!] - append/only blk prefix-exec name ;-- force global word + append/only blk duplicate-symbol name ] ][ if new: select-ssa name [name: new] ;@@ add a check for function! type @@ -468,7 +468,7 @@ red: context [ ] ][ append blk [as cell!] - append/only blk prefix-exec name + append/only blk duplicate-symbol name ] ] @@ -837,6 +837,16 @@ red: context [ ] ] + duplicate-symbol: func [name [word!] /local new][ + new: decorate-symbol to word! append append mold/flat name #"|" get-counter + repend symbols [name select symbols name] + repend sym-table [ + to set-word! new 'word/duplicate decorate-symbol name + ] + new-line skip tail sym-table -3 on + new + ] + get-symbol-id: func [name [word!]][ second select symbols name ] diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index 2a54dc5ab3..c9f0dcf73d 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -33,6 +33,25 @@ _context: context [ _hashtable/get-ctx-symbol ctx/symbols sym case? w-ctx new-id ] + get-any: func [ + symbol [integer!] + node [node!] + return: [red-value!] + /local + ctx [red-context!] + values [series!] + index [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "_context/get-any"]] + + ctx: TO_CTX(node) + if ON_STACK?(ctx) [ctx: TO_CTX(global-ctx)] + values: as series! ctx/values/value + index: find-word ctx symbol yes + assert index <> -1 + values/offset + index + ] + set-global: func [ symbol [integer!] value [red-value!] diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index 081d92f3b6..ecf3cb374f 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -1128,7 +1128,6 @@ object: context [ save-ctx [node!] save-idx [integer!] on-set? [logic!] - rebind? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "object/eval-path"]] @@ -1136,9 +1135,7 @@ object: context [ if TYPE_OF(word) <> TYPE_WORD [fire [TO_ERROR(script invalid-path) path element]] ctx: GET_CTX(parent) - - rebind?: word/ctx <> parent/ctx - if rebind? [ ;-- bind the word to object's context + if word/ctx <> parent/ctx [ ;-- bind the word to object's context save-idx: word/index save-ctx: word/ctx word/index: _context/find-word ctx word/symbol yes @@ -1167,10 +1164,6 @@ object: context [ ] ] ] - if rebind? [ - word/index: save-idx - word/ctx: save-ctx - ] res ] diff --git a/runtime/datatypes/word.reds b/runtime/datatypes/word.reds index 4e136ce1df..44cbd09305 100644 --- a/runtime/datatypes/word.reds +++ b/runtime/datatypes/word.reds @@ -19,6 +19,11 @@ Red/System [ word: context [ verbose: 0 + duplicate: func [w [red-word!] return: [red-word!]][ + assert red/boot? + as red-word! copy-cell as red-value! w ALLOC_TAIL(root) + ] + load-in: func [ str [c-string!] blk [red-block!] diff --git a/runtime/interpreter.reds b/runtime/interpreter.reds index 07ef25b227..fdc9e810fb 100644 --- a/runtime/interpreter.reds +++ b/runtime/interpreter.reds @@ -749,6 +749,9 @@ interpreter: context [ ctx [node!] ][ name: as red-word! either null? slot [pc - 1][slot] +;if path <> null [ +; name: as red-word! (block/rs-tail as red-block! path) - 1 +;] if TYPE_OF(name) <> TYPE_WORD [name: words/_anon] saved: stack/push value ;-- prevent word's value slot to be corrupted #2199 diff --git a/runtime/stack.reds b/runtime/stack.reds index 98ff84999e..bd60686b93 100644 --- a/runtime/stack.reds +++ b/runtime/stack.reds @@ -355,7 +355,7 @@ stack: context [ ;-- call stack sym: base/header >> 8 and FFFFh if all [sym <> body-symbol sym <> anon-symbol][ - fun: _context/get-global sym + fun: _context/get-any sym base/ctx if any [level > 1 TYPE_OF(fun) = TYPE_FUNCTION][ part: word/form word/make-at sym value @@ -370,7 +370,7 @@ stack: context [ ;-- call stack ] ] base: base + 1 - base >= top ;-- defensive test + base >= top ;-- defensive exit condition ] part ] diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index b3ac6c48ca..7af2f73621 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -116,6 +116,7 @@ red/word/from red/word/load red/word/push-local + red/word/duplicate red/get-word/get red/set-word/push-local diff --git a/tests/source/units/recycle-test.red b/tests/source/units/recycle-test.red index 1e010ccc0f..9340e619ac 100644 --- a/tests/source/units/recycle-test.red +++ b/tests/source/units/recycle-test.red @@ -644,11 +644,11 @@ Red [ d: [ "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20" ] e: [ "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20" ] ] - clear ro2-o/a - clear ro2-o/b - clear ro2-o/c - clear ro2-o/d - clear ro2-o/e + clear select ro2-o 'a + clear select ro2-o 'b + clear select ro2-o 'c + clear select ro2-o 'd + clear select ro2-o 'e ro2-o: none recycle From 47b48a5ef4ad5a47d72fb20eb680be48d1d8403d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 11 Feb 2020 18:16:29 +0100 Subject: [PATCH 0910/3432] FIX: missing commented code clean-up in previous commit. --- runtime/interpreter.reds | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime/interpreter.reds b/runtime/interpreter.reds index fdc9e810fb..c2be4122c7 100644 --- a/runtime/interpreter.reds +++ b/runtime/interpreter.reds @@ -749,9 +749,7 @@ interpreter: context [ ctx [node!] ][ name: as red-word! either null? slot [pc - 1][slot] -;if path <> null [ -; name: as red-word! (block/rs-tail as red-block! path) - 1 -;] + if TYPE_OF(name) <> TYPE_WORD [name: words/_anon] saved: stack/push value ;-- prevent word's value slot to be corrupted #2199 From 3178f42b714653c4f478a05f37f7f7f60c6b0279 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 11 Feb 2020 18:10:29 +0100 Subject: [PATCH 0911/3432] FEAT: more aggressive object path words rebinding to parent context. This fixes the missing calls issue in stack traces. A notable side-effect of this change is a faster compiled paths evaluation on second use, as all the nested words will be properly bound already. # Conflicts: # tests/source/units/recycle-test.red --- compiler.r | 14 ++++++++++++-- runtime/datatypes/context.reds | 19 +++++++++++++++++++ runtime/datatypes/object.reds | 9 +-------- runtime/datatypes/word.reds | 5 +++++ runtime/interpreter.reds | 3 +++ runtime/stack.reds | 4 ++-- system/utils/libRedRT-exports.r | 1 + tests/source/units/recycle-test.red | 11 ++++++----- 8 files changed, 49 insertions(+), 17 deletions(-) diff --git a/compiler.r b/compiler.r index bac332791b..b0c336f62a 100644 --- a/compiler.r +++ b/compiler.r @@ -447,7 +447,7 @@ red: context [ append blk decorate-symbol/no-alias name ;-- local word, point to value slot ][ append blk [as cell!] - append/only blk prefix-exec name ;-- force global word + append/only blk duplicate-symbol name ] ][ if new: select-ssa name [name: new] ;@@ add a check for function! type @@ -468,7 +468,7 @@ red: context [ ] ][ append blk [as cell!] - append/only blk prefix-exec name + append/only blk duplicate-symbol name ] ] @@ -837,6 +837,16 @@ red: context [ ] ] + duplicate-symbol: func [name [word!] /local new][ + new: decorate-symbol to word! append append mold/flat name #"|" get-counter + repend symbols [name select symbols name] + repend sym-table [ + to set-word! new 'word/duplicate decorate-symbol name + ] + new-line skip tail sym-table -3 on + new + ] + get-symbol-id: func [name [word!]][ second select symbols name ] diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index bf160242b8..c836e539ae 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -46,6 +46,25 @@ _context: context [ -1 ;-- search failed ] + get-any: func [ + symbol [integer!] + node [node!] + return: [red-value!] + /local + ctx [red-context!] + values [series!] + index [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "_context/get-any"]] + + ctx: TO_CTX(node) + if ON_STACK?(ctx) [ctx: TO_CTX(global-ctx)] + values: as series! ctx/values/value + index: find-word ctx symbol yes + assert index <> -1 + values/offset + index + ] + set-global: func [ symbol [integer!] value [red-value!] diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index 889d294c39..1a6af90236 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -1135,7 +1135,6 @@ object: context [ save-ctx [node!] save-idx [integer!] on-set? [logic!] - rebind? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "object/eval-path"]] @@ -1143,9 +1142,7 @@ object: context [ if TYPE_OF(word) <> TYPE_WORD [fire [TO_ERROR(script invalid-path) path element]] ctx: GET_CTX(parent) - - rebind?: word/ctx <> parent/ctx - if rebind? [ ;-- bind the word to object's context + if word/ctx <> parent/ctx [ ;-- bind the word to object's context save-idx: word/index save-ctx: word/ctx word/index: _context/find-word ctx word/symbol yes @@ -1174,10 +1171,6 @@ object: context [ ] ] ] - if rebind? [ - word/index: save-idx - word/ctx: save-ctx - ] res ] diff --git a/runtime/datatypes/word.reds b/runtime/datatypes/word.reds index 860986c170..982c796a3e 100644 --- a/runtime/datatypes/word.reds +++ b/runtime/datatypes/word.reds @@ -19,6 +19,11 @@ Red/System [ word: context [ verbose: 0 + duplicate: func [w [red-word!] return: [red-word!]][ + assert red/boot? + as red-word! copy-cell as red-value! w ALLOC_TAIL(root) + ] + load-in: func [ str [c-string!] blk [red-block!] diff --git a/runtime/interpreter.reds b/runtime/interpreter.reds index 07ef25b227..fdc9e810fb 100644 --- a/runtime/interpreter.reds +++ b/runtime/interpreter.reds @@ -749,6 +749,9 @@ interpreter: context [ ctx [node!] ][ name: as red-word! either null? slot [pc - 1][slot] +;if path <> null [ +; name: as red-word! (block/rs-tail as red-block! path) - 1 +;] if TYPE_OF(name) <> TYPE_WORD [name: words/_anon] saved: stack/push value ;-- prevent word's value slot to be corrupted #2199 diff --git a/runtime/stack.reds b/runtime/stack.reds index 98ff84999e..bd60686b93 100644 --- a/runtime/stack.reds +++ b/runtime/stack.reds @@ -355,7 +355,7 @@ stack: context [ ;-- call stack sym: base/header >> 8 and FFFFh if all [sym <> body-symbol sym <> anon-symbol][ - fun: _context/get-global sym + fun: _context/get-any sym base/ctx if any [level > 1 TYPE_OF(fun) = TYPE_FUNCTION][ part: word/form word/make-at sym value @@ -370,7 +370,7 @@ stack: context [ ;-- call stack ] ] base: base + 1 - base >= top ;-- defensive test + base >= top ;-- defensive exit condition ] part ] diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index f3f0e77986..49b5d82ba0 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -114,6 +114,7 @@ red/word/from red/word/load red/word/push-local + red/word/duplicate red/get-word/get red/set-word/push-local diff --git a/tests/source/units/recycle-test.red b/tests/source/units/recycle-test.red index 590d5f0353..9340e619ac 100644 --- a/tests/source/units/recycle-test.red +++ b/tests/source/units/recycle-test.red @@ -644,11 +644,12 @@ Red [ d: [ "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20" ] e: [ "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20" ] ] - clear ro2-o/a - clear ro2-o/b - clear ro2-o/c - clear ro2-o/d - clear ro2-o/e + clear select ro2-o 'a + clear select ro2-o 'b + clear select ro2-o 'c + clear select ro2-o 'd + clear select ro2-o 'e + ro2-o: none recycle ro2-mem2: stats From 687e2533c8255e15a73059e2c7460ae12a641758 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 6 Feb 2020 13:39:12 +0100 Subject: [PATCH 0912/3432] FEAT: grant wish red/REP#51 (BODY-OF on ACTION! and NATIVE! values) --- runtime/datatypes/native.reds | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/native.reds b/runtime/datatypes/native.reds index 2e0fc52702..c05124c708 100644 --- a/runtime/datatypes/native.reds +++ b/runtime/datatypes/native.reds @@ -186,7 +186,9 @@ native: context [ field [integer!] return: [red-block!] /local - blk [red-block!] + blk [red-block!] + table [int-ptr!] + index [integer!] ][ case [ field = words/spec [ @@ -195,6 +197,14 @@ native: context [ blk/node: native/spec blk/head: 0 ] + field = words/body [ + table: either TYPE_OF(native) = TYPE_NATIVE [natives/table][actions/table] + index: 0 + + until [index: index + 1 native/code = table/index] + + return as red-block! integer/box index + ] field = words/words [ --NOT_IMPLEMENTED-- ;@@ build the words block from spec ] From 2de82c81d38ffb9a6644f2bc24718e6c5de2513a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 6 Feb 2020 10:57:25 +0100 Subject: [PATCH 0913/3432] FIX: remove redundant signal handler --- modules/view/backends/gtk3/events.reds | 1 - modules/view/backends/gtk3/handlers.reds | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index a91eaa8e76..60b6e0d3f4 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -1028,7 +1028,6 @@ connect-widget-events: func [ gobj_signal_connect(widget "focus-in-event" :focus-in-event widget) gobj_signal_connect(widget "focus-out-event" :focus-out-event widget) gobj_signal_connect(widget "configure-event" :window-configure-event widget) - gobj_signal_connect(widget "realize" :window-realize widget) ] sym = slider [ gobj_signal_connect(widget "value-changed" :range-value-changed widget) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 4e0aaa53d8..37cd3cbc51 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -440,25 +440,6 @@ window-size-allocate: func [ ] ] -window-realize: func [ - [cdecl] - widget [handle!] - /local - values [red-value!] - flags [integer!] - bits [integer!] -][ - values: get-face-values widget - flags: get-flags as red-block! values + FACE_OBJ_FLAGS - bits: 1 ;-- GDK_DECOR_ALL - - if flags and FACET_FLAGS_NO_BTNS <> 0 [bits: bits or 16 or 32 or 64] ;-- hide Menu, Min and Max buttons - if flags and FACET_FLAGS_NO_MIN <> 0 [bits: bits or 32] ;-- hide Min button - if flags and FACET_FLAGS_NO_MAX <> 0 [bits: bits or 64] ;-- hide Max button - - gdk_window_set_decorations gtk_widget_get_window widget bits -] - widget-realize: func [ [cdecl] evbox [handle!] From 432de14c6c5dbcec9bf6201a6638a78c05228136 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 16:46:53 +0100 Subject: [PATCH 0914/3432] FIX: UTF8 encodings starting with F4h-F7h are now accepted. --- runtime/lexer.reds | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 04173a98bc..b7897c1480 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -260,10 +260,9 @@ lexer: context [ FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- E6-EB FL_UCS2 FL_UCS2 FL_UCS2 FL_UCS2 ;-- EC-EF C_WORD C_WORD C_WORD ;-- F0-F2 - FL_UCS4 FL_UCS4 ;-- F3-F4 - C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F5-F8 - C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F9-FC - C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- FD-FF + FL_UCS4 FL_UCS4 FL_UCS4 FL_UCS4 FL_UCS4 ;-- F3-F7 + C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- F8-FB + C_ILLEGAL C_ILLEGAL C_ILLEGAL C_ILLEGAL ;-- FC-FF ] #enum errors! [ @@ -2030,11 +2029,11 @@ lexer: context [ utf8-buf-tail: utf8-buffer ;-- switch following tables to zero-based indexing - lex-classes: lex-classes + 1 - transitions: transitions + 1 - skip-table: skip-table + 1 - line-table: line-table + 1 - type-table: type-table + 1 + lex-classes: lex-classes + 1 + transitions: transitions + 1 + skip-table: skip-table + 1 + line-table: line-table + 1 + type-table: type-table + 1 float-classes: float-classes + 1 float-transitions: float-transitions + 1 From 8fdc8295168b228971e9c89e70f4a9b642474a85 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 17:15:24 +0100 Subject: [PATCH 0915/3432] FIX: removes duplicated code created by "git squash" merge... --- runtime/datatypes/context.reds | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index a7a257dfd4..3435404230 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -51,26 +51,7 @@ _context: context [ assert index <> -1 values/offset + index ] - - get-any: func [ - symbol [integer!] - node [node!] - return: [red-value!] - /local - ctx [red-context!] - values [series!] - index [integer!] - ][ - #if debug? = yes [if verbose > 0 [print-line "_context/get-any"]] - ctx: TO_CTX(node) - if ON_STACK?(ctx) [ctx: TO_CTX(global-ctx)] - values: as series! ctx/values/value - index: find-word ctx symbol yes - assert index <> -1 - values/offset + index - ] - set-global: func [ symbol [integer!] value [red-value!] From 01904c2e40c8511fb4960ec497ace1a9a90fa9de Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 17:43:48 +0100 Subject: [PATCH 0916/3432] FIX: regression on tests "load-41" and "load-43". --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21370 -> 21372 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 2892ae9ce0..62d8039356 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -22,7 +22,7 @@ S_ISSUE;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE;T_ISSUE; S_NUMBER;T_INTEGER;T_INTEGER;S_NUMBER;S_NUMBER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;T_INTEGER;S_SHARP;S_NUMBER;S_TIME_1ST;S_PAIR_1ST;S_DATE;S_HEX_END2;S_DECEXP;S_DECX;T_ERROR;S_HEX;S_DATE;T_ERROR;T_INTEGER;T_ERROR;T_ERROR;T_PERCENT;S_DOTNUM;T_INTEGER;S_EMAIL;S_DOTNUM;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_INTEGER S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;S_DEC_SPECIAL;S_DECIMAL;T_ERROR;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT +S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;T_ERROR;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 02271afe925f187957b1008aa70d16a22e284b40..cb84ffcd9f608df5247a0628263f69be7b824d7c 100644 GIT binary patch delta 5353 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 delta 5480 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 AtN;K2 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a9d2cc225f..88cc45c89a 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -130,7 +130,7 @@ Red/System [ 3A1E3A3A17173A3A4E3A4E3A3A4D3A4E3A3A3A3A3A3A3A3A3A4E4E4E16164E4E 4E4E4E4E4E3A3A4E1E3A3A17173A3A4E3A4E3A3A4D3A3A311A3A3A3A3A3A3A3A 4E4E4E17174E4E4E4E4E4E4E3A3A4E3A3A3A3A3A3A3A4E3A4E3A3A3A3A3A313A -3A3A3A3A3A3A3A4E4E4E18184E4E4E4E4E4E4E3A3A4E3A3A253A233A234E3A4E +3A17173A3A3A3A4E4E4E18184E4E4E4E4E4E4E3A3A4E3A3A253A233A234E3A4E 3A3A4D3A3A311A3A17173A3A3A3A4E4E4E4E4F4F4F4F4F4F4F4F194F4F191919 191919194F4F4F19194F4F4F4F194F19194F19193A4F50501A1A505050505050 503A3A503A3A3A3A3A3A3A503A503A3A3A3A3A3A1A3A3A3A3A3A3A3A5051511B From 9fc10591bede3c69cac2de83ae7f4faffeb7a103 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 17:46:38 +0100 Subject: [PATCH 0917/3432] TESTS: adds a regression test for improved stack trace for locally bound function names. --- tests/source/compiler/run-time-error-test.r | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/source/compiler/run-time-error-test.r b/tests/source/compiler/run-time-error-test.r index 7aa34d5ce8..4869321ea2 100644 --- a/tests/source/compiler/run-time-error-test.r +++ b/tests/source/compiler/run-time-error-test.r @@ -40,4 +40,22 @@ REBOL [ --compile-and-run-this/error {Red[] do [#"^^(010FFF)" * #"^^(11)" ]} --assert-red-printed? "*** Math Error: math or number overflow" + --test-- "stack-trace-1" + --compile-and-run-this/error {Red[] + do { + system/state/trace: 1 + a: object [af: does [b/bf]] + b: object [bf: does [cf]] + c: object [set 'system/words/cf does [df] cf: none] + d: object [set 'df does [ff]] + ff: does [ + gf: does [do make error! "error"] + gf + ] + a/af + } + } + --assert-red-printed? "*** Stack: af bf cf df ff gf" + + ~~~end-file~~~ From 733be5114ba00e2af0407fa98b263a9a7b94549e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 18:01:35 +0100 Subject: [PATCH 0918/3432] FIX: load-float was missing an error checking on finishing. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b7897c1480..3f30a60e44 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1485,6 +1485,7 @@ lexer: context [ ] pos: pos + 1 ;-- last number tp/pos: as byte! i + if any [i < 0 i > 255 pos > 12][throw-error lex s e TYPE_TUPLE] cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) lex/in-pos: e ;-- reset the input position to delimiter byte ] From 31742c38b7ba3cf73409713714471331f6ebf122 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 12 Feb 2020 18:07:16 +0100 Subject: [PATCH 0919/3432] TESTS: adds more tuple! loading tests. --- tests/source/units/lexer-test.red | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index e3b9a46380..f0ffe83d9c 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -458,6 +458,16 @@ Red [ --test-- "tro-80" --assert error? try [transcode/one {#"ab"}] + --test-- "tro-81" --assert 1.2.3 == transcode/one "1.2.3" + --test-- "tro-82" --assert 11.22.33 == transcode/one "11.22.33" + --test-- "tro-83" --assert 255.255.255 == transcode/one "255.255.255" + --test-- "tro-84" --assert error? try [transcode/one "256.255.255"] + --test-- "tro-85" --assert error? try [transcode/one "255.255.256"] + --test-- "tro-86" --assert error? try [transcode/one "255.255.256.0"] + --test-- "tro-87" --assert error? try [transcode/one "1234.0.0"] + --test-- "tro-88" --assert 1.2.3.4.5.6.7.8.9.10.11.12 == transcode/one "1.2.3.4.5.6.7.8.9.10.11.12" + --test-- "tro-89" --assert error? try [transcode/one "1.2.3.4.5.6.7.8.9.10.11.12.13"] + ===end-group=== ===start-group=== "transcode/next" From 7c5acb6b9a34524071a44ebce03f08e85e2def3b Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 13 Feb 2020 16:55:39 +0800 Subject: [PATCH 0920/3432] FIX: issue #4294 (CRASH in OS-image/get-data) --- runtime/datatypes/image.reds | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 2008eca972..341d176f2d 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -778,15 +778,17 @@ image: context [ ][ res: 1 ][ - type: 0 - bmp1: OS-image/lock-bitmap arg1 no - bmp2: OS-image/lock-bitmap arg2 no - res: compare-memory - as byte-ptr! OS-image/get-data bmp1 :type - as byte-ptr! OS-image/get-data bmp2 :type - IMAGE_WIDTH(arg1/size) * IMAGE_HEIGHT(arg2/size) * 4 - OS-image/unlock-bitmap arg1 bmp1 - OS-image/unlock-bitmap arg2 bmp2 + either zero? arg1/size [res: 0][ + type: 0 + bmp1: OS-image/lock-bitmap arg1 no + bmp2: OS-image/lock-bitmap arg2 no + res: compare-memory + as byte-ptr! OS-image/get-data bmp1 :type + as byte-ptr! OS-image/get-data bmp2 :type + IMAGE_WIDTH(arg1/size) * IMAGE_HEIGHT(arg2/size) * 4 + OS-image/unlock-bitmap arg1 bmp1 + OS-image/unlock-bitmap arg2 bmp2 + ] ] ] default [ From d513c8f9b0882e541ec3068d0691ae6376302793 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 13 Feb 2020 17:18:35 +0800 Subject: [PATCH 0921/3432] FIX: issue #4293 (SAVE doesn't save an empty image) --- environment/system.red | 2 +- runtime/datatypes/image.reds | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/environment/system.red b/environment/system.red index d187b5f8ff..9c85273b0f 100644 --- a/environment/system.red +++ b/environment/system.red @@ -234,7 +234,7 @@ system: context [ ;security-level: ["attempt to lower security to" :arg1] ;security-error: ["invalid" :arg1 "security policy:" :arg2] ;no-codec: ["cannot decode or encode (no codec):" :arg1] - ;bad-media: ["bad media data (corrupt image, sound, video)"] + bad-media: ["bad media data (corrupt image, sound, video)"] ;no-extension: ["cannot open extension:" :arg1] ;bad-extension: ["invalid extension format:" :arg1] ;extension-init: ["extension cannot be initialized (check version):" :arg1] diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 341d176f2d..156bc18415 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -153,6 +153,7 @@ image: context [ format [integer!] return: [red-value!] ][ + if zero? image/size [fire [TO_ERROR(access bad-media)]] if TYPE_OF(dst) = TYPE_NONE [dst: stack/push*] OS-image/encode image dst format ] From 021e34dc15d984e00fb838ced4714e94a8f5af03 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 13 Feb 2020 17:28:29 +0100 Subject: [PATCH 0922/3432] FEAT: exposes prescanning stage to user-level, allows fast token guessing. SCAN gets /FAST refinement. TRANSCODE gets /PRESCAN refinement. Lexer callback gets the 'prescan event (needs to return TRUE to get 'scan event). Prescanning mode will only use the FSM to parse tokens and guess their type (not always accurate, but close enough). --- environment/functions.red | 9 +- environment/natives.red | 3 +- libRed/libRed.red | 2 +- runtime/datatypes/block.reds | 2 +- runtime/datatypes/common.reds | 4 +- runtime/lexer.reds | 59 ++++---- runtime/natives.reds | 14 +- runtime/parse.reds | 2 +- tests/source/units/lexer-test.red | 237 ++++++++++++++++++------------ 9 files changed, 201 insertions(+), 131 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 26c88e2437..3b3f5061e8 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -369,9 +369,14 @@ scan: func [ "Returns the guessed type of the first serialized value from the input" buffer [binary! string!] "Input UTF-8 buffer or string" /next "Returns both the type and the input after the value" - return: [datatype!] "Guessed type" + /fast "Fast scanning, returns best guessed type" + return: [datatype!] "Recognized or guessed type" ][ - either next [transcode/next/scan buffer][transcode/scan buffer] + either fast [ + either next [transcode/next/prescan buffer][transcode/prescan buffer] + ][ + either next [transcode/next/scan buffer][transcode/scan buffer] + ] ] load: function [ diff --git a/environment/natives.red b/environment/natives.red index 2089faa594..99031c67d1 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -913,11 +913,12 @@ transcode: make native! [[ src [binary! string!] "UTF-8 input buffer; string argument will be UTF-8 encoded" /next "Translate next complete value (blocks as single value)" /one "Translate next complete value, returns the value only" + /prescan "Prescans only, do not load values. Returns guessed type." /scan "Scans only, do not load values. Returns recognized type." /part "Translates only part of the input buffer" length [integer! binary!] "Length in bytes or tail position" /into "Optionally provides an output block" - dst [block! none!] + dst [block! none!] /trace callback [function! [ event [word!] diff --git a/libRed/libRed.red b/libRed/libRed.red index daf61a1797..ce215408a8 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -251,7 +251,7 @@ Red [ if last-error <> null [return last-error] TRAP_ERRORS(name [ - lexer/scan-string stack/arguments str -1 no yes no null null null + lexer/scan-string stack/arguments str -1 no yes yes no null null null stack/unwind-last ]) ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 7cd27a98b2..ddd4ec8309 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -649,7 +649,7 @@ block: context [ TYPE_OBJECT [object/reflect as red-object! spec words/body] TYPE_MAP [map/reflect as red-hash! spec words/body] TYPE_VECTOR [vector/to-block as red-vector! spec proto] - TYPE_STRING [lexer/scan-string as red-value! proto as red-string! spec -1 no yes no null null as red-series! spec] + TYPE_STRING [lexer/scan-string as red-value! proto as red-string! spec -1 no yes yes no null null as red-series! spec] TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] TYPE_ANY_PATH TYPE_ANY_LIST [proto: clone as red-block! spec no no] diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index a4a7c73411..7468caf4a5 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -351,7 +351,7 @@ load-value: func [ blk [red-block!] value [red-value!] ][ - lexer/scan-string stack/arguments str -1 yes yes yes null null as red-series! str + lexer/scan-string stack/arguments str -1 yes yes yes yes null null as red-series! str blk: as red-block! stack/arguments assert TYPE_OF(blk) = TYPE_BLOCK @@ -691,6 +691,7 @@ words: context [ _write: as red-word! 0 ;-- lexer events + _prescan: as red-word! 0 _scan: as red-word! 0 _load: as red-word! 0 _error: as red-word! 0 @@ -932,6 +933,7 @@ words: context [ _write: word/load "write" ;-- lexer events + _prescan: word/load "prescan" _scan: word/load "scan" _load: word/load "load" _error: word/load "error" diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3f30a60e44..90b28037cb 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1790,9 +1790,10 @@ lexer: context [ scan-tokens: func [ lex [state!] one? [logic!] + only? [logic!] ;-- prescan only /local - cp class index state prev flags line mark offset [integer!] - term? load? ld? [logic!] + cp class index state prev flags line mark offset idx [integer!] + term? load? ld? scan? [logic!] p e start s [byte-ptr!] slot [cell!] do-scan [scanner!] @@ -1801,7 +1802,7 @@ lexer: context [ line: 1 ld?: lex/load? until [ - flags: 0 ;-- Scanning stage -- + flags: 0 ;-- Pre-scanning stage -- term?: no state: lex/entry prev: state @@ -1843,27 +1844,33 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - do-scan: as scanner! scanners/index - if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] - load?: either lex/fun-ptr = null [any [not one? ld?]][ - index: either zero? lex/scanned [0 - index][lex/scanned] - either state >= T_INTEGER [fire-event lex words/_scan index null s lex/in-pos][yes] + scan?: either lex/fun-ptr = null [not only?][ + idx: either zero? lex/scanned [0 - index][lex/scanned] + fire-event lex words/_prescan idx null s lex/in-pos ] - if load? [ ;-- Loading stage -- - index: lex/exit - --EXIT_STATES-- - do-load: as loader! loaders/index - if :do-load <> null [ - catch LEX_ERR [do-load lex s p flags] - if lex/fun-ptr <> null [ - slot: lex/tail - 1 - unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] + if scan? [ + do-scan: as scanner! scanners/index ;-- Scanning stage -- + if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] + load?: either lex/fun-ptr = null [any [not one? ld?]][ + index: either zero? lex/scanned [0 - index][lex/scanned] + either state >= T_INTEGER [fire-event lex words/_scan index null s lex/in-pos][yes] + ] + if load? [ ;-- Loading stage -- + index: lex/exit - --EXIT_STATES-- + do-load: as loader! loaders/index + if :do-load <> null [ + catch LEX_ERR [do-load lex s p flags] + if lex/fun-ptr <> null [ + slot: lex/tail - 1 + unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] + ] ] ] - ] - system/thrown: 0 - - if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ - check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed + system/thrown: 0 + + if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ + check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed + ] ] if all [one? lex/scanned > 0 lex/entry <> S_PATH lex/entry <> S_M_STRING state <> T_PATH][ slot: lex/tail - 1 @@ -1886,7 +1893,8 @@ lexer: context [ src [byte-ptr!] ;-- UTF-8 buffer size [integer!] ;-- buffer size in bytes one? [logic!] ;-- scan a single value - load? [logic!] ;-- disable value loading, only scanning + scan? [logic!] ;-- NO: disable value scanning, only prescanning + load? [logic!] ;-- NO: disable value loading, only scanning wrap? [logic!] ;-- force returned loaded value(s) in a block len [int-ptr!] ;-- return the consumed input length fun [red-function!] ;-- optional callback function @@ -1933,11 +1941,11 @@ lexer: context [ lex/fun-ptr: fun lex/fun-locs: 0 lex/in-series: ser - lex/load?: load? + lex/load?: all [scan? load?] if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no] - catch RED_THROWN_ERROR [scan-tokens lex one? load?] + catch RED_THROWN_ERROR [scan-tokens lex one? not scan?] if system/thrown <> 0 [clean-up re-throw] if load? [ @@ -1973,6 +1981,7 @@ lexer: context [ str [red-string!] size [integer!] one? [logic!] + scan? [logic!] load? [logic!] wrap? [logic!] len [int-ptr!] @@ -2000,7 +2009,7 @@ lexer: context [ utf8-buf-tail: utf8-buf-tail + size + 1 ;-- move at tail for new buffer; +1 for terminal NUL if null? len [len: :ignore] - catch RED_THROWN_ERROR [type: scan dst base size one? load? wrap? len fun as red-series! str] + catch RED_THROWN_ERROR [type: scan dst base size one? scan? load? wrap? len fun as red-series! str] utf8-buf-tail: base if extra <> null [free extra] if system/thrown <> 0 [re-throw] ;-- clean place to rethrow errors diff --git a/runtime/natives.reds b/runtime/natives.reds index 0fcdf48632..f025e5ca16 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -555,7 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - lexer/scan-string arg as red-string! arg -1 no yes no null null as red-string! arg + lexer/scan-string arg as red-string! arg -1 no yes yes no null null as red-string! arg DO_EVAL_BLOCK ] TYPE_URL @@ -2728,13 +2728,14 @@ natives: context [ check? [logic!] next [integer!] one [integer!] + prescan[integer!] scan [integer!] part [integer!] into [integer!] trace [integer!] /local offset len type [integer!] - next? one? all? load? [logic!] + next? one? all? scan? load? [logic!] slot arg [red-value!] bin bin2 [red-binary!] int [red-integer!] @@ -2744,8 +2745,9 @@ natives: context [ fun [red-function!] s [series!] ][ - #typecheck [transcode next one scan part into trace] + #typecheck [transcode next one prescan scan part into trace] + scan?: prescan < 0 load?: scan < 0 all?: all [one < 0 load?] next?: next >= 0 @@ -2786,13 +2788,13 @@ natives: context [ one?: any [next? not all? not load?] either type = TYPE_BINARY [ if len < 0 [len: binary/rs-length? bin] - type: lexer/scan slot binary/rs-head bin len one? load? no :offset fun as red-series! bin + type: lexer/scan slot binary/rs-head bin len one? scan? load? no :offset fun as red-series! bin ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - type: lexer/scan-string slot str len one? load? no :offset fun as red-series! str + type: lexer/scan-string slot str len one? scan? load? no :offset fun as red-series! str ] - unless load? [ + if any [not scan? not load?][ dt: as red-datatype! slot dt/header: TYPE_DATATYPE dt/value: type diff --git a/runtime/parse.reds b/runtime/parse.reds index 0a0b16fa81..d7821d98aa 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -211,7 +211,7 @@ parser: context [ s: GET_BUFFER(input) buf: (as byte-ptr! s/offset) + input/head size: as-integer (as byte-ptr! s/tail) - buf - type: lexer/scan null buf size yes no no :len null null + type: lexer/scan null buf size yes yes no no :len null null match?: either dt-type = TYPE_TYPESET [BS_TEST_BIT_ALT(dt type)][type = dt/value] if match? [_series/rs-skip as red-series! input len - 1] ;-- -1 to account for later rs-skip diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index f0ffe83d9c..17c0d1d6a4 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -540,107 +540,143 @@ Red [ --test-- "tt-1" clear logs - --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger + --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger --assert logs = [ - scan set-word! word! 1 1x3 - load set-word! datatype! 1 a: - scan integer! word! 1 4x5 - load integer! datatype! 1 1 - open path! datatype! 1 6x6 - load word! datatype! 1 b - error error! datatype! 1 8x8 - open block! datatype! 1 9x9 - close block! datatype! 1 10x10 + prescan word! word! 1 1x3 + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + prescan integer! datatype! 1 4x5 + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + prescan path! word! 1 6x7 + open path! datatype! 1 6x6 + load word! datatype! 1 b + prescan error! word! 1 8x8 + error error! datatype! 1 8x8 + prescan block! word! 1 9x9 + open block! datatype! 1 9x9 + prescan block! word! 1 10x10 + close block! datatype! 1 10x10 ] --test-- "tt-2" clear logs - --assert (compose [a: 1 (to-path 'b) x]) == transcode/trace "a: 1 b/ x" :lex-logger + --assert (compose [a: 1 (to-path 'b) x]) == transcode/trace "a: 1 b/ x" :lex-logger --assert logs = [ - scan set-word! word! 1 1x3 - load set-word! datatype! 1 a: - scan integer! word! 1 4x5 - load integer! datatype! 1 1 - open path! datatype! 1 6x6 - load word! datatype! 1 b - error error! datatype! 1 8x8 - scan word! word! 1 9x10 - load word! datatype! 1 x + prescan word! word! 1 1x3 + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + prescan integer! datatype! 1 4x5 + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + prescan path! word! 1 6x7 + open path! datatype! 1 6x6 + load word! datatype! 1 b + prescan error! word! 1 8x8 + error error! datatype! 1 8x8 + prescan word! word! 1 9x10 + scan word! word! 1 9x10 + load word! datatype! 1 x ] --test-- "tt-3" clear logs - --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-logger + --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-logger --assert logs = [ - scan set-word! word! 1 1x3 - load set-word! datatype! 1 a: - scan integer! word! 1 4x5 - load integer! datatype! 1 1 - open map! datatype! 1 7x7 - scan set-word! word! 1 8x10 - load set-word! datatype! 1 r: - scan integer! word! 1 11x12 - load integer! datatype! 1 2 - close map! datatype! 1 12x12 - open block! datatype! 1 14x14 - scan word! word! 1 16x17 - load word! datatype! 1 x - error error! datatype! 1 14x17 + prescan word! word! 1 1x3 + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + prescan integer! datatype! 1 4x5 + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + prescan map! word! 1 6x7 + open map! datatype! 1 7x7 + prescan word! word! 1 8x10 + scan set-word! word! 1 8x10 + load set-word! datatype! 1 r: + prescan integer! datatype! 1 11x12 + scan integer! word! 1 11x12 + load integer! datatype! 1 2 + prescan paren! word! 1 12x12 + close map! datatype! 1 12x12 + prescan block! word! 1 14x14 + open block! datatype! 1 14x14 + prescan word! word! 1 16x17 + scan word! word! 1 16x17 + load word! datatype! 1 x + error error! datatype! 1 14x17 ] --test-- "tt-4" clear logs - --assert [a: 1 x] == transcode/trace "a: 1 ) x" :lex-logger + --assert [a: 1 x] == transcode/trace "a: 1 ) x" :lex-logger --assert logs = [ - scan set-word! word! 1 1x3 - load set-word! datatype! 1 a: - scan integer! word! 1 4x5 - load integer! datatype! 1 1 - close paren! datatype! 1 6x6 - error error! datatype! 1 6x6 - scan word! word! 1 8x9 - load word! datatype! 1 x + prescan word! word! 1 1x3 + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + prescan integer! datatype! 1 4x5 + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + prescan paren! word! 1 6x6 + close paren! datatype! 1 6x6 + error error! datatype! 1 6x6 + prescan word! word! 1 8x9 + scan word! word! 1 8x9 + load word! datatype! 1 x ] --test-- "tt-5" clear logs --assert [hello 3.14 pi world] == transcode/trace "hello ^/\ 3.14 pi world" :lex-logger --assert logs = [ - scan word! word! 1 1x6 - load word! datatype! 1 hello - error error! datatype! 2 8x8 - scan float! word! 2 10x14 - load float! datatype! 2 3.14 - scan word! word! 2 15x17 - load word! datatype! 2 pi - scan word! word! 2 18x23 - load word! datatype! 2 world + prescan word! word! 1 1x6 + scan word! word! 1 1x6 + load word! datatype! 1 hello + prescan error! word! 2 8x8 + error error! datatype! 2 8x8 + prescan float! datatype! 2 10x14 + scan float! word! 2 10x14 + load float! datatype! 2 3.14 + prescan word! word! 2 15x17 + scan word! word! 2 15x17 + load word! datatype! 2 pi + prescan word! word! 2 18x23 + scan word! word! 2 18x23 + load word! datatype! 2 world ] --test-- "tt-6" clear logs - --assert [123 "abc" 123456789123.0 test] == transcode/trace "123 {abc} 123456789123 test" :lex-logger + --assert [123 "abc" 123456789123.0 test] == transcode/trace "123 {abc} 123456789123 test" :lex-logger --assert logs = [ - scan integer! word! 1 1x4 - load integer! datatype! 1 123 - open string! datatype! 1 5x5 - close string! datatype! 1 6x9 - scan float! word! 1 11x23 - load float! datatype! 1 123456789123.0 - scan word! word! 1 24x28 - load word! datatype! 1 test + prescan integer! datatype! 1 1x4 + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + prescan string! word! 1 5x5 + open string! datatype! 1 5x5 + prescan string! datatype! 1 6x9 + close string! datatype! 1 6x9 + prescan integer! datatype! 1 11x23 + scan float! word! 1 11x23 + load float! datatype! 1 123456789123.0 + prescan word! word! 1 24x28 + scan word! word! 1 24x28 + load word! datatype! 1 test ] --test-- "tt-7" clear logs - --assert [a: 1] == transcode/trace "a: 1 ]" :lex-logger + --assert [a: 1] == transcode/trace "a: 1 ]" :lex-logger --assert logs = [ + prescan word! word! 1 1x3 scan set-word! word! 1 1x3 - load set-word! datatype! 1 a: - scan integer! word! 1 4x5 - load integer! datatype! 1 1 - close block! datatype! 1 6x6 - error error! datatype! 1 6x6 + load set-word! datatype! 1 a: + prescan integer! datatype! 1 4x5 + scan integer! word! 1 4x5 + load integer! datatype! 1 1 + prescan block! word! 1 6x6 + close block! datatype! 1 6x6 + error error! datatype! 1 6x6 ] --test-- "tt-8" @@ -656,32 +692,43 @@ Red [ reduce/into [event to-word type to-word type? type line token] tail logs new-line t yes switch event [ + prescan scan [yes] load [to-logic find [integer! float! pair!] type] - open [no] + open close [no] ] ] clear logs - --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter + --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter --assert logs = [ - scan word! word! 1 1x6 - load word! datatype! 1 hello - scan integer! word! 2 8x11 - load integer! datatype! 2 123 - open block! datatype! 3 13x13 - scan pair! word! 4 15x18 - load pair! datatype! 4 3x4 - open string! datatype! 4 19x19 - close string! datatype! 4 20x24 - scan float! word! 4 26x30 - load float! datatype! 4 3.14 - scan word! word! 4 31x33 - load word! datatype! 4 pi - close block! datatype! 4 33x33 - scan word! word! 5 36x41 - load word! datatype! 5 world + prescan word! word! 1 1x6 + scan word! word! 1 1x6 + load word! datatype! 1 hello + prescan integer! datatype! 2 8x11 + scan integer! word! 2 8x11 + load integer! datatype! 2 123 + prescan block! word! 3 13x13 + open block! datatype! 3 13x13 + prescan pair! datatype! 4 15x18 + scan pair! word! 4 15x18 + load pair! datatype! 4 3x4 + prescan string! word! 4 19x19 + open string! datatype! 4 19x19 + prescan string! datatype! 4 20x24 + close string! datatype! 4 20x24 + prescan float! datatype! 4 26x30 + scan float! word! 4 26x30 + load float! datatype! 4 3.14 + prescan word! word! 4 31x33 + scan word! word! 4 31x33 + load word! datatype! 4 pi + prescan block! word! 4 33x33 + close block! datatype! 4 33x33 + prescan word! word! 5 36x41 + scan word! word! 5 36x41 + load word! datatype! 5 world ] --test-- "tt-9" @@ -704,11 +751,13 @@ Red [ yes ] clear logs - --assert [123 abc] == transcode/trace "123 abc" :lex-filter10 + --assert [123 abc] == transcode/trace "123 abc" :lex-filter10 --assert logs = [ - scan integer! word! 1 1x4 - load integer! datatype! 1 123 - scan word! word! 1 5x8 + prescan integer! datatype! 1 1x4 + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + prescan word! word! 1 5x8 + scan word! word! 1 5x8 load word! datatype! 1 abc ] @@ -744,9 +793,11 @@ Red [ clear logs --assert [123 abc] == transcode/trace "123 abc" :lex-filter11A --assert logs = [ - scan integer! word! 1 1x4 - load integer! datatype! 1 123 - scan word! word! 1 5x8 + prescan integer! datatype! 1 1x4 + scan integer! word! 1 1x4 + load integer! datatype! 1 123 + prescan word! word! 1 5x8 + scan word! word! 1 5x8 load word! datatype! 1 abc ] From 82497aa8aaa1e66bae5c7b965b27cb099b192f52 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 13 Feb 2020 19:23:04 +0100 Subject: [PATCH 0923/3432] FEAT: adds event filtering support to lexer callbacks. An optional block of event names is now checked from inside the callback body. If found as first value, it will be processed and only events mentioned in that block will be triggered. Usage: transcode/trace <input> func [...][ [<allowed>] ... ] --- environment/console/GUI/highlight.red | 1 + runtime/lexer.reds | 96 +++++++++++++++++++++------ 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/environment/console/GUI/highlight.red b/environment/console/GUI/highlight.red index ae4e385794..ffa8902e2b 100644 --- a/environment/console/GUI/highlight.red +++ b/environment/console/GUI/highlight.red @@ -23,6 +23,7 @@ highlight: context [ return: [logic!] /local style ][ + [scan error] switch event [ scan [ if all [type style: select _theme type][ diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 90b28037cb..24d5a3e000 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -274,6 +274,15 @@ lexer: context [ LEX_ERR: 10 ] + #enum events! [ + EVT_PRESCAN: 1 + EVT_SCAN: 2 + EVT_LOAD: 4 + EVT_OPEN: 8 + EVT_CLOSE: 16 + EVT_ERROR: 32 + ] + state!: alias struct! [ next [state!] ;-- link to next state! structure (recursive calls) back [state!] ;-- link to previous state! structure (recursive calls) @@ -296,6 +305,7 @@ lexer: context [ mstr-flags [integer!] ;-- multiline string accumulated flags fun-ptr [red-function!] ;-- callback function pointer or NULL fun-locs [integer!] ;-- number of local words in callback function + fun-evts [integer!] ;-- bitmap of allowed events in-series [red-series!] ;-- optional back reference to input series value [integer!] ;-- decoded integer! or char! value (from scanner to loader) load? [logic!] ;-- TRUE: load values, else scan only @@ -312,9 +322,46 @@ lexer: context [ stash: as cell! 0 ;-- special buffer for hatching any-blocks series stash-size: 1000 ;-- pre-allocated cells number root-state: as state! 0 ;-- global entry point to state struct list + all-events: 3Fh ;-- bit-mask of all events min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer flags-LG: C_FLAG_LESSER or C_FLAG_GREATER + + decode-filter: func [fun [red-function!] return: [integer!] + /local + evts flag sym [integer!] + value tail [red-word!] + blk [red-block!] + s [series!] + ][ + s: as series! fun/more/value + blk: as red-block! s/offset + if any [TYPE_OF(blk) <> TYPE_BLOCK block/rs-tail? blk][return all-events] + blk: as red-block! block/rs-head blk + if TYPE_OF(blk) <> TYPE_BLOCK [return all-events] + + s: GET_BUFFER(blk) + value: as red-word! s/offset + blk/head + tail: as red-word! s/tail + evts: 0 + while [value < tail][ + if TYPE_OF(value) = TYPE_WORD [ + sym: symbol/resolve value/symbol + flag: case [ + sym = words/_prescan/symbol [EVT_PRESCAN] + sym = words/_scan/symbol [EVT_SCAN] + sym = words/_load/symbol [EVT_LOAD] + sym = words/_open/symbol [EVT_OPEN] + sym = words/_close/symbol [EVT_CLOSE] + sym = words/_error/symbol [EVT_ERROR] + true [0] + ] + evts: evts or flag + ] + value: value + 1 + ] + evts + ] throw-error: func [lex [state!] s e [byte-ptr!] type [integer!] /local @@ -329,7 +376,7 @@ lexer: context [ lex/scanned: TYPE_ERROR throw LEX_ERR ;-- bypass errors when scanning only ] - if lex/fun-ptr <> null [unless fire-event lex words/_error TYPE_ERROR null s e [throw LEX_ERR]] + if lex/fun-ptr <> null [unless fire-event lex EVT_ERROR TYPE_ERROR null s e [throw LEX_ERR]] e: lex/in-end len: 0 if null? s [ ;-- determine token's start @@ -372,33 +419,37 @@ lexer: context [ ] ] - fire-event: func [ - lex [state!] - event [red-word!] - type [integer!] - value [red-value!] - s [byte-ptr!] - e [byte-ptr!] - return: [logic!] + fire-event: func [lex [state!] event [events!] type [integer!] value [red-value!] s e [byte-ptr!] return: [logic!] /local len x y [integer!] ser [red-series!] res [red-value!] blk [red-block!] + evt [red-word!] int [red-integer!] name [names!] more [series!] ctx [node!] cont? [logic!] ][ - if all [event = words/_scan type = -2][event: words/_error type: TYPE_ERROR] + if lex/fun-evts and event = 0 [return true] + if all [event = EVT_SCAN type = -2][event: EVT_ERROR type: TYPE_ERROR] more: as series! lex/fun-ptr/more/value int: as red-integer! more/offset + 4 ctx: either TYPE_OF(int) = TYPE_INTEGER [as node! int/value][global-ctx] stack/mark-func words/_body lex/fun-ptr/ctx - stack/push as red-value! event ;-- event + evt: switch event [ + EVT_PRESCAN [words/_prescan] + EVT_SCAN [words/_scan] + EVT_LOAD [words/_load] + EVT_OPEN [words/_open] + EVT_CLOSE [words/_close] + EVT_ERROR [words/_error] + default [assert false null] + ] + stack/push as red-value! evt ;-- event name ser: as red-series! stack/push as red-value! lex/in-series ;-- input either type < 0 [ ;-- type @@ -407,7 +458,7 @@ lexer: context [ stack/push block/rs-abs-at blk (0 - type) - 1 ;-- 1-based access ] ][ - either event = words/_scan [ + either event = EVT_SCAN [ name: name-table + type stack/push as red-value! name/word ][ @@ -506,7 +557,7 @@ lexer: context [ len [integer!] ][ if null? pos [pos: lex/in-pos] - if lex/fun-ptr <> null [unless fire-event lex words/_open type null pos pos [exit]] + if lex/fun-ptr <> null [unless fire-event lex EVT_OPEN type null pos pos [exit]] len: (as-integer lex/tail - lex/head) >> 4 p: as red-point! alloc-slot lex set-type as cell! p TYPE_POINT ;-- use the slot for stack info @@ -533,7 +584,7 @@ lexer: context [ point?: all [lex/buffer <= p TYPE_OF(p) = TYPE_POINT] if all [not quiet? lex/fun-ptr <> null][ t: either point? [p/y][type] - unless fire-event lex words/_close t null s e [return 0] + unless fire-event lex EVT_CLOSE t null s e [return 0] ] unless point? [do-error] ;-- postpone error checking after callback call stype: p/y @@ -892,7 +943,7 @@ lexer: context [ ] scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - if lex/fun-ptr <> null [fire-event lex words/_open TYPE_STRING null s e] + if lex/fun-ptr <> null [fire-event lex EVT_OPEN TYPE_STRING null s e] if zero? lex/mstr-nest [lex/mstr-s: s] lex/mstr-nest: lex/mstr-nest + 1 lex/mstr-flags: lex/mstr-flags or flags @@ -901,7 +952,7 @@ lexer: context [ ] scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - if lex/fun-ptr <> null [fire-event lex words/_close TYPE_STRING null s e] + if lex/fun-ptr <> null [fire-event lex EVT_CLOSE TYPE_STRING null s e] lex/mstr-nest: lex/mstr-nest - 1 either zero? lex/mstr-nest [ @@ -966,7 +1017,7 @@ lexer: context [ ] scan-comment: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - if lex/fun-ptr <> null [fire-event lex words/_scan T_CMT - --EXIT_STATES-- null s e] + if lex/fun-ptr <> null [fire-event lex EVT_SCAN T_CMT - --EXIT_STATES-- null s e] ] scan-construct: func [lex [state!] s e [byte-ptr!] flags [integer!] @@ -1846,14 +1897,14 @@ lexer: context [ index: state - --EXIT_STATES-- scan?: either lex/fun-ptr = null [not only?][ idx: either zero? lex/scanned [0 - index][lex/scanned] - fire-event lex words/_prescan idx null s lex/in-pos + fire-event lex EVT_PRESCAN idx null s lex/in-pos ] if scan? [ do-scan: as scanner! scanners/index ;-- Scanning stage -- if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] load?: either lex/fun-ptr = null [any [not one? ld?]][ index: either zero? lex/scanned [0 - index][lex/scanned] - either state >= T_INTEGER [fire-event lex words/_scan index null s lex/in-pos][yes] + either state >= T_INTEGER [fire-event lex EVT_SCAN index null s lex/in-pos][yes] ] if load? [ ;-- Loading stage -- index: lex/exit - --EXIT_STATES-- @@ -1862,7 +1913,7 @@ lexer: context [ catch LEX_ERR [do-load lex s p flags] if lex/fun-ptr <> null [ slot: lex/tail - 1 - unless fire-event lex words/_load TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] + unless fire-event lex EVT_LOAD TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] ] ] @@ -1943,7 +1994,10 @@ lexer: context [ lex/in-series: ser lex/load?: all [scan? load?] - if fun <> null [lex/fun-locs: _function/count-locals fun/spec 0 no] + if fun <> null [ + lex/fun-locs: _function/count-locals fun/spec 0 no + lex/fun-evts: decode-filter fun + ] catch RED_THROWN_ERROR [scan-tokens lex one? not scan?] if system/thrown <> 0 [clean-up re-throw] From 10361ebde70c1a94c47646230837d24182fe7ffc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 13 Feb 2020 21:02:40 +0100 Subject: [PATCH 0924/3432] TESTS: adds some tests for filtered lexer events. --- tests/source/units/lexer-test.red | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 17c0d1d6a4..7d9b4e3526 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -538,6 +538,21 @@ Red [ any [event <> 'error all [input: next input false]] ] + lex-filtered-logger: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + [load error] + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + any [event <> 'error all [input: next input false]] + ] + --test-- "tt-1" clear logs --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger @@ -801,6 +816,54 @@ Red [ load word! datatype! 1 abc ] + --test-- "tt-12" + clear logs + --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-filtered-logger + --assert logs = [ + load set-word! datatype! 1 a: + load integer! datatype! 1 1 + load set-word! datatype! 1 r: + load integer! datatype! 1 2 + load word! datatype! 1 x + error error! datatype! 1 14x17 + ] + + --test-- "tt-13" + lex-filter13: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + [load open close] + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + switch event [ + load [to-logic find [integer! float! pair!] type] + open + close [no] + ] + ] + + clear logs + --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter13 + --assert logs = [ + load word! datatype! 1 hello + load integer! datatype! 2 123 + open block! datatype! 3 13x13 + load pair! datatype! 4 3x4 + open string! datatype! 4 19x19 + close string! datatype! 4 20x24 + load float! datatype! 4 3.14 + load word! datatype! 4 pi + close block! datatype! 4 33x33 + load word! datatype! 5 world + ] + + ===end-group=== ~~~end-file~~~ \ No newline at end of file From ab700aa6237714d59d3e9adaf9e64e6070068d71 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 14 Feb 2020 00:10:42 +0100 Subject: [PATCH 0925/3432] FIX: C1 Unicode codepoints were molded as #"" char!. Now they are molded using a hex escaping form. Example: >> #"^(80)" == #"^(80)" --- runtime/datatypes/string.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 83047e5998..ab205ac1e1 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -466,7 +466,7 @@ string: context [ switch GET_UNIT(s) [ Latin1 [ case [ - cp <= FFh [ + cp <= 7Fh [ node: s/node p: alloc-tail-unit s 1 p/1: as-byte cp @@ -1393,7 +1393,7 @@ string: context [ ][ idx: cp + 1 case [ - any [cp = 1Eh all [all? cp > 7Fh]][ + any [cp = 1Eh all [80h <= cp cp <= 9Fh] all [all? cp > 7Fh]][ append-char GET_BUFFER(buffer) as-integer #"^^" append-char GET_BUFFER(buffer) as-integer #"(" concatenate-literal buffer to-hex cp yes From eb8e5f47e99cf21399b7663facbfd70c210f405c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 14 Feb 2020 13:44:36 +0100 Subject: [PATCH 0926/3432] FIX: better detect extra invalid characters in char! literals. --- runtime/lexer.reds | 7 +++---- tests/source/units/lexer-test.red | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 24d5a3e000..5b8f704dcf 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1148,14 +1148,13 @@ lexer: context [ if len = 2 [do-error] ;-- #"" c: -1 - either s/3 = #"^^" [ + s: either s/3 = #"^^" [ if len = 3 [do-error] ;-- #"^" scan-escaped-char s + 3 e :c ][ ;-- simple char - s: unicode/fast-decode-utf8-char s + 2 :c - if s < e [do-error] + unicode/fast-decode-utf8-char s + 2 :c ] - if any [c > 0010FFFFh c = -1][do-error] + if any [c > 0010FFFFh c = -1 s < e][do-error] lex/value: c lex/in-pos: e + 1 ;-- skip " ] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 7d9b4e3526..e6822543c2 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -468,6 +468,8 @@ Red [ --test-- "tro-88" --assert 1.2.3.4.5.6.7.8.9.10.11.12 == transcode/one "1.2.3.4.5.6.7.8.9.10.11.12" --test-- "tro-89" --assert error? try [transcode/one "1.2.3.4.5.6.7.8.9.10.11.12.13"] + --test-- "tro-90" --assert error? try [transcode/one {#"^(80)abc"}] + ===end-group=== ===start-group=== "transcode/next" From 367b2f583d6646dd5c0d828295969e04e133abbf Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 14 Feb 2020 17:04:16 +0100 Subject: [PATCH 0927/3432] FIX: missing ending quote in char! literals could crash the lexer. --- runtime/lexer.reds | 4 ++-- tests/source/units/lexer-test.red | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5b8f704dcf..08834976da 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1142,10 +1142,10 @@ lexer: context [ len c [integer!] do-error [subroutine!] ][ - assert all [s/1 = #"#" s/2 = #"^"" e/1 = #"^""] + assert all [s/1 = #"#" s/2 = #"^""] do-error: [throw-error lex s e TYPE_CHAR] len: as-integer e - s - if len = 2 [do-error] ;-- #"" + if any [len = 2 e/1 <> #"^""][do-error] ;-- #"" c: -1 s: either s/3 = #"^^" [ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index e6822543c2..72bf9683f4 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -469,6 +469,8 @@ Red [ --test-- "tro-89" --assert error? try [transcode/one "1.2.3.4.5.6.7.8.9.10.11.12.13"] --test-- "tro-90" --assert error? try [transcode/one {#"^(80)abc"}] + --test-- "tro-91" --assert error? try [transcode/one {#"^^(80)}] + --test-- "tro-92" --assert error? try [transcode/one {#"^(80)}] ===end-group=== ===start-group=== "transcode/next" From d706c2051064179066b8dac3510e7f194fcf4de5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 14 Feb 2020 19:16:23 +0100 Subject: [PATCH 0928/3432] FEAT: handles NUL character in-between tokens as input termination. --- runtime/lexer.reds | 2 +- tests/source/units/lexer-test.red | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 08834976da..3aaab2a02d 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -903,7 +903,7 @@ lexer: context [ p ] - scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][] + scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][lex/in-pos: lex/in-end] scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ if all [lex/fun-ptr <> null lex/entry = S_PATH][close-block lex s e -1 yes] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 72bf9683f4..c5d6c08bac 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -349,6 +349,9 @@ Red [ --assert out == [1 / 3] --assert word? out/2 + --test-- "tr-32" + --assert [a] == transcode #{610062} ; a^(NUL)b + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" @@ -472,6 +475,9 @@ Red [ --test-- "tro-91" --assert error? try [transcode/one {#"^^(80)}] --test-- "tro-92" --assert error? try [transcode/one {#"^(80)}] + --test-- "tro-93" --assert error? try [transcode/one #{3C6100623E}] ; <a^(NUL)b> + --test-- "tro-94" --assert 'a == transcode/one #{610062} ; a^(NUL)b + ===end-group=== ===start-group=== "transcode/next" From d2230781a9bc58752d63474b13d9480d62d584e8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Fri, 14 Feb 2020 19:51:35 +0100 Subject: [PATCH 0929/3432] FEAT: scan "<-" as word! instead of tag!. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21372 -> 21400 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 62d8039356..2990150714 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -37,7 +37,7 @@ S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MO S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index cb84ffcd9f608df5247a0628263f69be7b824d7c..bc50ef2fce185806f476c52cd4a82aa94932fd85 100644 GIT binary patch delta 9668 zcmZ`<c|4Ts`?f_3O<AL&WC>xiq=k``We~<Pmdwl%V=I*{`<oOINn;s=#MlOteIGia zXpmtjSt3gaS;ts^FK7AIIp^n($2>mohx@so>%Q*my1na}%=j$kSA#-(BsOuHuf&;{ zsJL%J62S7@S{Q!z#g`2W=kTuKSE@k+^nki_@m}l^-7Y=q+qVl7gKWfb7VdA9I`6Mb zJ(dqIseL+DrLi$zx5b!eG}e)3XKuOH1)g<TU!45jxYQF>p6W{8oEy4PJhRzeT`WL{ zAkpeJ0ptzejiK+UQ)|Ur8%uRtQ}K1TW;Z>z#(|}!hJ86dmNpwcr9vQsfq{(q&9A9F z=z<xbYQt;8Y_ol~{4TmccmzGW>Fu*MJ+nI5`Smf`KhS4$l9m*YE^sBMJlv~37%fy@ zw-vZBR~4`}N0RSBi(HDXo@z%z6t>pXZ;|`6oYAmnZs2d-T<R&`VtB8OCdI5wk1ezU z4eC)>+EM<Dm4z=+r1HDSx`4Q^n}%P9C$HyjtjNdCqg`PG{R4xWn?G<deu5HKYGZWy z!MYfD-RAs+){|rCWr4drb->y8Lh25k@5>$JfsN5S56e_~fI)#xMq>l*7ICV*M?|DR zy*cc>-`wrBoBkVXnp3L_;}8dT2800!GNzZ8(F_?5TU7J0!2&X>ZpC5A;0bZ{<@fdP zjkLF+NdUV2VZhn7>E)rJWj)m5+;jDJ!0N`#@>W3|?CRv5@BURjtqS|E{H|a0`r-Gq zwJm}D(pv)OUd9`Sny!y~c=x|mQ>gQsn^>h2>tO1qZf(t=2iNBuV55&y<?Ly|LgN;r zQ+;}BEy}HX^h2O;Ktj)k_nKw+J2cwAvbmh}yp*`5y16l%WC#IT)WiH2R@ZI5UTf)7 zU&p1kfaeXYCIjD^#2G6+wMUlZRxOmfa7#XUbSr+9^)32Cw^#43oDv11t_*A}F0Z$a zCi%mgzRUw69PxGPT$_vM&jQOyCCA*vXrfJDxXz8difOzKY)#&w-u}_l8T~%wSb802 z*1{c92}!shaAS04c~*eRKT<RBz5plDxpHpM=8i*6G{I+OVeD&NV)<`(d%olJ_Pl;u zqZKE>xV=0!$2Pu|Cb+4I`r7cR_7$+Tx;h^pzZG|M^)xxtOmiScw>kt~Ba6Gr<%5*y z7n&#Q`<l7U<?630XBbNaOZ&JROEgIP1fV3+h32dDo0KneDdjxdr~IKLBs&NT?qXE5 z&n-172BftuzJv>raGJvMz?`a58%?;)+14k=z(7u(rq%9z-zUclX^x}ld0r|`bVTLy zB+~2_5Xm3%B%VhitBed(50e%noLPKx+MLXBALzcX5+9)^P0Vo}dY)s&iBD01gBRrq zq3X(RK8JH%Mi>`<Gngf>4Ad+L1fIpYbY!9OmoF>sW=u(SxLv6Rq=lT{d-zkiF3<l^ z!l^jBFFQXH%0_E;X&vf1P&yT2M)f8vx12oWlez^%msWheI6@k1rYo+mET7LgK6>|o zlNlKP@05E9$W|BS!H0%%FiVD=jW}1W{TZ|L@#_3%@B|xLHm(-(`}ycl=V*7cQ44Y3 zD$C8_;5Wvbt0f|Ubf&~p=Pm5%=<Wx_iTY&Y!)G6-DNVgG<<IK#CS0(j*dI(LUc;Wo zi>Fs(^)sDpm0ES*I`U7Mc2`Oy@$ob`J>mOm>1;h1MeJ%Mv@KM5Z~hK(nBDhTEA>70 zSmTNA3_hJZFC&}i2{5npGIZuwT!Eo4Y+}vs3ogx23nsV**bU=y46(3;HM=1k!O$FL zxn}njmv86=`?NOl1($AE#ChnzyHgU>y*Jsp6M}TG$8dtX?b#6tK^E9!@q)Xt?9UP! z9a}8@d_M=I7x)+9TW#<9FVvok>#gWZ@j)GKM`!m|R0-W+NAw;HFY%`?>%Nt=NnP}( z(wplgHB%!v{T23Sct07;4S>!Oar4I%0D`~p+{c1ER19qdv0;}Ow0-z7qtgjqJP;Gu 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�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 I;r65d2aOWfzyJUM delta 9786 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 88cc45c89a..64affe7a61 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -148,7 +148,7 @@ Red/System [ 585858585858583A2E2F2E2E2E2E2E2E2E42582E2E2E3A3A58312E212E2E2E2E 2E3A5858583A3A585858585858583A3A3A3A3A3A3A3A3A3A4258583A3A3A3A58 313A213A3A3A3A3A3A5846462727464646464646462727462727272727272727 -272E2E2E27274646272727272727273A46272727272727272727272827292727 +272E2E2E272746462727272E2727273A46272727272727272727272827292727 272727272727272727552727272727272727272727273A3A2828282828282828 28282728282828282828282828282828282828282828282828282828283A3A29 2929292929292929292929272929292929292929292929292929292929292929 From 7c9161668bfe521faf6fb1d36f0dc2d3650df2a9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sat, 15 Feb 2020 17:14:27 +0100 Subject: [PATCH 0930/3432] FIX: report an error on quoted refinement! values. Before this fix, '/a or '/\ was accepted as refinement. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3aaab2a02d..fc72d4111c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1080,6 +1080,7 @@ lexer: context [ true [0] ] ] + s/1 <> #"/" [throw-error lex s e TYPE_REFINEMENT] true [0] ] ] From b7c63740f4b4ca600e3607d955b333a1c153ff0b Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Tue, 18 Feb 2020 22:08:58 +0800 Subject: [PATCH 0931/3432] FIX: size-text returns wrong value in some cases. --- modules/view/backends/platform.red | 9 +++++---- modules/view/backends/windows/font.reds | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index e4ca458b76..952442c6dc 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -566,12 +566,13 @@ system/view/platform: context [ ] font: as red-object! values + gui/FACE_OBJ_FONT - hFont: either TYPE_OF(font) = TYPE_OBJECT [ + hFont: null + if TYPE_OF(font) = TYPE_OBJECT [ state: as red-block! (object/get-values font) + gui/FONT_OBJ_STATE - either TYPE_OF(state) <> TYPE_BLOCK [gui/make-font face font][gui/get-font-handle font 0] - ][ - null + if TYPE_OF(state) <> TYPE_BLOCK [hFont: gui/get-font-handle font 0] + if null? hFont [hFont: gui/make-font face font] ] + pair: as red-pair! stack/arguments pair/header: TYPE_PAIR diff --git a/modules/view/backends/windows/font.reds b/modules/view/backends/windows/font.reds index a1b575861e..2426d7845a 100644 --- a/modules/view/backends/windows/font.reds +++ b/modules/view/backends/windows/font.reds @@ -128,7 +128,7 @@ OS-make-font: func [ blk: as red-block! values + FONT_OBJ_STATE either TYPE_OF(blk) <> TYPE_BLOCK [ block/make-at blk 3 - handle/make-in blk as-integer hFont + either scaling? [handle/make-in blk as-integer hFont][none/make-in blk] none/make-in blk ;-- DWrite font either scaling? [ none/make-in blk From b0b4d7238722d6c5e16952eed4cb529ca77b3dd3 Mon Sep 17 00:00:00 2001 From: loziniak <maciej@robotix-lozinski.pl> Date: Thu, 20 Feb 2020 18:33:04 +0100 Subject: [PATCH 0932/3432] FIX: seeding random with time! and float! issue #4205 --- runtime/datatypes/float.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index e243040084..3f9c462227 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -499,12 +499,14 @@ float: context [ return: [red-float!] /local s [float!] + sp [int-ptr!] ][ #if debug? = yes [if verbose > 0 [print-line "float/random"]] either seed? [ s: f/value - _random/srand as-integer s + sp: as int-ptr! :s + _random/srand sp/value f/header: TYPE_UNSET ][ s: (as-float _random/rand) / 2147483647.0 From 3c68ef12a5ff0a09624359543c78e3ac25c23b53 Mon Sep 17 00:00:00 2001 From: loziniak <maciej@robotix-lozinski.pl> Date: Fri, 21 Feb 2020 00:22:06 +0100 Subject: [PATCH 0933/3432] FEAT: xor float's bytes in random seed --- runtime/datatypes/float.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 3f9c462227..972f0549ce 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -506,7 +506,7 @@ float: context [ either seed? [ s: f/value sp: as int-ptr! :s - _random/srand sp/value + _random/srand sp/1 xor sp/2 f/header: TYPE_UNSET ][ s: (as-float _random/rand) / 2147483647.0 From a44ab7c5ef22862cd649a9f716f4fe3fa3107367 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 22 Feb 2020 19:33:16 +0100 Subject: [PATCH 0934/3432] FEAT: add skeleton of MONEY! definitions --- runtime/datatypes/money.reds | 127 +++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 runtime/datatypes/money.reds diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds new file mode 100644 index 0000000000..214f9f38bf --- /dev/null +++ b/runtime/datatypes/money.reds @@ -0,0 +1,127 @@ +Red/System [ + Title: "Money! datatype runtime functions" + Author: "Vladimir Vasilyev" + File: %money.reds + Tabs: 4 + Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +#define STUB [func [][--NOT_IMPLEMENTED--]] + +money: context [ + verbose: 0 + + ;-- Support -- + + ;-- Natives -- + + negative?: STUB + zero?: STUB + positive?: STUB + sign?: STUB + + ;-- Actions -- + + make: STUB + to: STUB + + form: STUB + mold: STUB + + random: STUB + + compare: STUB + + absolute: STUB + negate: STUB + + add: STUB + subtract: STUB + multiply: STUB + divide: STUB + remainder: STUB + + round: STUB + + even?: STUB + odd?: STUB + + init: does [ + datatype/register [ + TYPE_MONEY + TYPE_VALUE + "money!" + ;-- General actions -- + null;:make + null;:random + null ;reflect + null;:to + null;:form + null;:mold + null ;eval-path + null ;set-path + null;:compare + ;-- Scalar actions -- + null;:absolute + null;:add + null;:divide + null;:multiply + null;:negate + null ;power + null;:remainder + null;:round + null;:subtract + null;:even? + null;:odd? + ;-- Bitwise actions -- + null ;and~ + null ;complement + null ;or~ + null ;xor~ + ;-- Series actions -- + null ;append + null ;at + null ;back + null ;change + null ;clear + null ;copy + null ;find + null ;head + null ;head? + null ;index? + null ;insert + null ;length? + null ;move + null ;next + null ;pick + null ;poke + null ;put + null ;remove + null ;reverse + null ;select + null ;sort + null ;skip + null ;swap + null ;tail + null ;tail? + null ;take + null ;trim + ;-- I/O actions -- + null ;create + null ;close + null ;delete + null ;modify + null ;open + null ;open? + null ;query + null ;read + null ;rename + null ;update + null ;write + ] + ] +] From 354c401b5ab5541e22a09d8480436c3f9dc12aab Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 22 Feb 2020 19:34:04 +0100 Subject: [PATCH 0935/3432] FEAT: plug MONEY! into runtime --- runtime/allocator.reds | 3 ++- runtime/datatypes/structures.reds | 7 +++++++ runtime/macros.reds | 7 +++---- runtime/red.reds | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index add271300f..68dce1110c 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -30,7 +30,8 @@ int-array!: alias struct! [ptr [int-ptr!]] ; 17: owner ;-- indicate that an object is an owner ; 16: native! op ;-- operator is made from a native! function ; 15: extern flag ;-- routine code is external to Red (from FFI) -; 14-8: <reserved> +; 14: sign bit ;-- sign of money +; 13-8: <reserved> ; 7-0: datatype ID ;-- datatype number cell!: alias struct! [ diff --git a/runtime/datatypes/structures.reds b/runtime/datatypes/structures.reds index 5c589f4e39..dd072d31dd 100644 --- a/runtime/datatypes/structures.reds +++ b/runtime/datatypes/structures.reds @@ -331,6 +331,13 @@ red-handle!: alias struct! [ _pad [integer!] ] +red-money!: alias struct! [ + header [integer!] + amount1 [integer!] + amount2 [integer!] + amount3 [integer!] +] + red-slice!: alias struct! [ ;@@ internal use only !!! header [integer!] ;-- cell header head [integer!] ;-- head index (zero-based) diff --git a/runtime/macros.reds b/runtime/macros.reds index 7ce9a7d033..d67d104b34 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -60,10 +60,9 @@ Red/System [ TYPE_HANDLE ;-- 2E 46 TYPE_DATE ;-- 2F 47 TYPE_PORT ;-- 30 48 - TYPE_IMAGE ;-- 31 49 ;-- needs to be last - TYPE_EVENT - - TYPE_MONEY + TYPE_MONEY ;-- 31 49 + TYPE_IMAGE ;-- 32 50 ;-- needs to be last + TYPE_EVENT TYPE_CLOSURE TYPE_SLICE TYPE_TOTAL_COUNT ;-- keep tabs on number of datatypes. diff --git a/runtime/red.reds b/runtime/red.reds index 133d2154f6..29c1311935 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -104,6 +104,7 @@ red: context [ #include %datatypes/handle.reds #include %datatypes/date.reds #include %datatypes/port.reds + #include %datatypes/money.reds #if OS = 'Windows [#include %datatypes/image.reds] ;-- temporary #if OS = 'macOS [#include %datatypes/image.reds] ;-- temporary @@ -200,6 +201,7 @@ red: context [ handle/init date/init port/init + money/init #if OS = 'Windows [image/init] ;-- temporary #if OS = 'macOS [image/init] ;-- temporary @@ -276,6 +278,7 @@ red: context [ handle/verbose: verbosity date/verbose: verbosity port/verbose: verbosity + money/verbose: verbosity #if OS = 'Windows [image/verbose: verbosity] #if OS = 'macOS [image/verbose: verbosity] From 83d2ccdd27d455df3a9e87a6a0b0e0a662f56a84 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 22 Feb 2020 19:34:36 +0100 Subject: [PATCH 0936/3432] FEAT: make environment MONEY!-aware --- environment/datatypes.red | 1 + environment/functions.red | 2 +- environment/scalars.red | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/environment/datatypes.red b/environment/datatypes.red index e7d0bce3e5..e76923ab1e 100644 --- a/environment/datatypes.red +++ b/environment/datatypes.red @@ -60,6 +60,7 @@ email!: make datatype! #get-definition TYPE_EMAIL handle!: make datatype! #get-definition TYPE_HANDLE date!: make datatype! #get-definition TYPE_DATE port!: make datatype! #get-definition TYPE_PORT +money!: make datatype! #get-definition TYPE_MONEY #if find config/modules 'view [ event!: make datatype! #get-definition TYPE_EVENT diff --git a/environment/functions.red b/environment/functions.red index 26c88e2437..0cddc0f3ad 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -113,7 +113,7 @@ last: func ["Returns the last value in a series" s [series! tuple!]] [pick s len bitset! binary! block! char! email! file! float! get-path! get-word! hash! integer! issue! lit-path! lit-word! logic! map! none! pair! paren! path! percent! refinement! set-path! set-word! string! tag! time! typeset! tuple! - unset! url! word! image! date! + unset! url! word! image! date! money! ] test-list: union to-list [ handle! error! action! native! datatype! function! image! object! op! routine! vector! diff --git a/environment/scalars.red b/environment/scalars.red index 26c89656da..73c96c292f 100644 --- a/environment/scalars.red +++ b/environment/scalars.red @@ -35,7 +35,7 @@ Rebol: false ;-- makes loading Rebol scripts easier internal!: make typeset! [unset!] external!: make typeset! [#if find config/modules 'view [event!]] number!: make typeset! [integer! float! percent!] -scalar!: union number! make typeset! [char! pair! tuple! time! date!] +scalar!: union number! make typeset! [money! char! pair! tuple! time! date!] any-word!: make typeset! [word! set-word! get-word! lit-word!] ;-- any bindable word all-word!: union any-word! make typeset! [refinement! issue!] ;-- all types of word nature any-list!: make typeset! [block! paren! hash!] From ca752b38b471f3483bd344d4c4612b084935a307 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 22 Feb 2020 19:36:27 +0100 Subject: [PATCH 0937/3432] FEAT: add MONEY! to the build --- build/includes.r | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/includes.r b/build/includes.r index bccd02c4cb..b065707521 100644 --- a/build/includes.r +++ b/build/includes.r @@ -109,6 +109,7 @@ write %build/bin/sources.r set-cache [ %common.reds %context.reds %datatype.reds + %date.reds %email.reds %error.reds %event.reds @@ -117,6 +118,7 @@ write %build/bin/sources.r set-cache [ %function.reds %get-path.reds %get-word.reds + %handle.reds %hash.reds %image.reds %integer.reds @@ -125,6 +127,7 @@ write %build/bin/sources.r set-cache [ %lit-word.reds %logic.reds %map.reds + %money.reds %native.reds %none.reds %op.reds @@ -151,8 +154,6 @@ write %build/bin/sources.r set-cache [ %url.reds %vector.reds %word.reds - %handle.reds - %date.reds ] %platform/ [ %android.reds From c8c3e9c00b17ea6cb9a8265f6f39dfb62d7d5c23 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Sun, 23 Feb 2020 20:50:38 +0100 Subject: [PATCH 0938/3432] FEAT: preliminary lexer refactoring to improve SCAN event accuracy. --- runtime/lexer.reds | 414 +++++++++++++++++++++++++-------------------- 1 file changed, 228 insertions(+), 186 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index fc72d4111c..d001ac6080 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -311,8 +311,8 @@ lexer: context [ load? [logic!] ;-- TRUE: load values, else scan only ] - scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] - loader!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!]] + scanner!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]] + loader!: alias function! [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]] utf8-buf-size: 100'000 utf8-buffer: as byte-ptr! 0 @@ -324,7 +324,7 @@ lexer: context [ root-state: as state! 0 ;-- global entry point to state struct list all-events: 3Fh ;-- bit-mask of all events - min-integer: as byte-ptr! "-2147483648" ;-- used in scan-integer + min-integer: as byte-ptr! "-2147483648" ;-- used in load-integer flags-LG: C_FLAG_LESSER or C_FLAG_GREATER decode-filter: func [fun [red-function!] return: [integer!] @@ -615,14 +615,14 @@ lexer: context [ stype ] - decode-2: func [s e [byte-ptr!] ser [series!] + decode-2: func [s e [byte-ptr!] ser [series!] load? [logic!] return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] c [integer!] cnt [integer!] ][ - p: as byte-ptr! ser/offset + p: either load? [as byte-ptr! ser/offset][null] while [s < e][ c: 0 cnt: 8 @@ -639,23 +639,25 @@ lexer: context [ ] ] either zero? cnt [ - p/value: as byte! c - p: p + 1 + if load? [ + p/value: as byte! c + p: p + 1 + ] ][ if cnt <> 8 [return s] ] ] - ser/tail: as cell! p + if load? [ser/tail: as cell! p] null ] - decode-16: func [s e [byte-ptr!] ser [series!] + decode-16: func [s e [byte-ptr!] ser [series!] load? [logic!] return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] c index class b1 [integer!] ][ - p: as byte-ptr! ser/offset + p: either load? [as byte-ptr! ser/offset][null] b1: -1 while [s < e][ index: 1 + as-integer s/1 @@ -663,9 +665,11 @@ lexer: context [ switch class [ C_BIN_HEXA [ either b1 < 0 [b1: index][ - c: as-integer hexa-table/b1 - p/value: as byte! c << 4 or as-integer hexa-table/index - p: p + 1 + if load? [ + c: as-integer hexa-table/b1 + p/value: as byte! c << 4 or as-integer hexa-table/index + p: p + 1 + ] b1: -1 ] ] @@ -675,17 +679,17 @@ lexer: context [ ] s: s + 1 ] - ser/tail: as cell! p + if load? [ser/tail: as cell! p] null ] - decode-64: func [s e [byte-ptr!] ser [series!] + decode-64: func [s e [byte-ptr!] ser [series!] load? [logic!] return: [byte-ptr!] ;-- null: ok, not null: error position /local p [byte-ptr!] val accum flip index [integer!] ][ - p: as byte-ptr! ser/offset + p: either load? [as byte-ptr! ser/offset][null] accum: 0 flip: 0 while [s < e][ @@ -697,10 +701,12 @@ lexer: context [ accum: accum << 6 + val flip: flip + 1 if flip = 4 [ - p/1: as-byte accum >> 16 - p/2: as-byte accum >> 8 - p/3: as-byte accum - p: p + 3 + if load? [ + p/1: as-byte accum >> 16 + p/2: as-byte accum >> 8 + p/3: as-byte accum + p: p + 3 + ] accum: 0 flip: 0 ] @@ -708,15 +714,19 @@ lexer: context [ s: s + 1 case [ flip = 3 [ - p/1: as-byte accum >> 10 - p/2: as-byte accum >> 2 - p: p + 2 + if load? [ + p/1: as-byte accum >> 10 + p/2: as-byte accum >> 2 + p: p + 2 + ] flip: 0 ] flip = 2 [ s: s + 1 - p/1: as-byte accum >> 4 - p: p + 1 + if load? [ + p/1: as-byte accum >> 4 + p: p + 1 + ] flip: 0 ] true [return s] @@ -727,7 +737,7 @@ lexer: context [ s: s + 1 ] if flip <> 0 [return s] - ser/tail: as red-value! p + if load? [ser/tail: as red-value! p] null ] @@ -903,9 +913,11 @@ lexer: context [ p ] - scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!]][lex/in-pos: lex/in-end] + scan-eof: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][lex/in-pos: lex/in-end] - scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type index [integer!]][ + scan-error: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + /local type index [integer!] + ][ if all [lex/fun-ptr <> null lex/entry = S_PATH][close-block lex s e -1 yes] either lex/prev < --EXIT_STATES-- [ index: lex/prev @@ -917,18 +929,20 @@ lexer: context [ ] ] - scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] /local type [integer!]][ + scan-block-open: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + /local type [integer!] + ][ type: either s/1 = #"(" [TYPE_PAREN][TYPE_BLOCK] open-block lex type null lex/in-pos: e + 1 ;-- skip delimiter ] - scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ close-block lex s e TYPE_BLOCK no lex/in-pos: e + 1 ;-- skip ] ] - scan-paren-close: func [lex [state!] s e [byte-ptr!] flags [integer!] + scan-paren-close: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local blk [red-block!] ][ @@ -942,7 +956,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ) ] - scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + scan-mstring-open: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ if lex/fun-ptr <> null [fire-event lex EVT_OPEN TYPE_STRING null s e] if zero? lex/mstr-nest [lex/mstr-s: s] lex/mstr-nest: lex/mstr-nest + 1 @@ -951,12 +965,17 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip { ] - scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + scan-mstring-close: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ if lex/fun-ptr <> null [fire-event lex EVT_CLOSE TYPE_STRING null s e] lex/mstr-nest: lex/mstr-nest - 1 either zero? lex/mstr-nest [ - load-string lex lex/mstr-s e lex/mstr-flags or flags + either load? [ + load-string lex lex/mstr-s e lex/mstr-flags or flags yes + ][ + ;scan-string lex lex/mstr-s e lex/mstr-flags or flags no + 0 + ] lex/mstr-s: null lex/mstr-flags: 0 lex/entry: S_START @@ -966,12 +985,12 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip } ] - scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + scan-map-open: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ open-block lex TYPE_MAP null lex/in-pos: e + 1 ;-- skip ( ] - scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!] + scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local type [integer!] ][ @@ -981,13 +1000,15 @@ lexer: context [ default [TYPE_PATH] ] open-block lex type s ;-- open a new path series - lex/entry: S_PATH ;-- overwrites the S_START set by open-block - lex/in-pos: e + 1 ;-- skip / + if type <> TYPE_PATH [s: s + 1] lex/exit: T_WORD ;-- load the head word lex/scanned: TYPE_WORD + load-word lex s e flags load? + lex/entry: S_PATH ;-- overwrites the S_START set by open-block + lex/in-pos: e + 1 ;-- skip / ] - check-path-end: func [lex [state!] s e [byte-ptr!] flags [integer!] + check-path-end: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local type [integer!] cp [integer!] @@ -1048,10 +1069,11 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ] ] - scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] + scan-word: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local - type [integer!] - p [byte-ptr!] + cp type class index [integer!] + p pos [byte-ptr!] + cell [cell!] ][ type: TYPE_WORD if flags and C_FLAG_COLON <> 0 [ @@ -1067,9 +1089,43 @@ lexer: context [ type: TYPE_LIT_WORD ] lex/scanned: type + + either flags and flags-LG = flags-LG [ ;-- handle word<tag> cases + p: s + while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < + if p + 1 < e [ + pos: p + p: p + 1 + cp: as-integer p/1 ;-- check for valid tag + class: lex-classes/cp and FFh + index: S_LESSER * (size? character-classes!) + class ;-- simulate transition from S_LESSER + if (as-integer transitions/index) = S_TAG [ ;-- check if valid tag starting is recognized + while [all [p < e p/1 <> #">"]][p: p + 1] ;-- search > + if p < e [ + e: pos ;-- cut the word before < + lex/in-pos: pos ;-- resume scanning from < + ] + ] + ] + ][ + if all [flags and C_FLAG_LESSER <> 0 lex/entry = S_PATH e/0 = #"<"][ + cell: lex/tail - 1 + if TYPE_OF(cell) = TYPE_POINT [ + e: e - 1 ;-- handle word</tag> cases + lex/in-pos: e ;-- resume scanning from < + lex/entry: S_START ;-- cancel the newly opened path + lex/tail: cell + ] + ] + ] ] - scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + scan-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ + s: s + 1 + if s = e [throw-error lex s - 1 e TYPE_ISSUE] + ] + + scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ case [ s + 1 = e [lex/scanned: TYPE_WORD] s + 2 = e [ @@ -1085,17 +1141,18 @@ lexer: context [ ] ] - scan-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] return: [integer!] /local o? [logic!] p [byte-ptr!] len i [integer!] + cell [cell!] promote [subroutine!] ][ promote: [ lex/scanned: TYPE_FLOAT - lex/exit: T_FLOAT ;-- fallback on load-float + load-float lex s e flags load? return 0 ] p: s @@ -1134,12 +1191,17 @@ lexer: context [ ] if s/value = #"-" [i: 0 - i] lex/scanned: TYPE_INTEGER - lex/value: i + if load? [ + cell: alloc-slot lex + integer/make-at cell i + ] + lex/in-pos: e ;-- reset the input position to delimiter byte i ] - scan-char: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-char: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local + char [red-char!] len c [integer!] do-error [subroutine!] ][ @@ -1156,34 +1218,15 @@ lexer: context [ unicode/fast-decode-utf8-char s + 2 :c ] if any [c > 0010FFFFh c = -1 s < e][do-error] - lex/value: c - lex/in-pos: e + 1 ;-- skip " - ] - - scan-float: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - state index class [integer!] - ][ - state: 0 ;-- S_FL_START - until [ - index: as-integer s/1 - class: as-integer float-classes/index - index: state * (size? float-char-classes!) + class - state: as-integer float-transitions/index - s: s + 1 - s = e + if load? [ + char: as red-char! alloc-slot lex + set-type as cell! char TYPE_CHAR + char/value: c ] - index: state * (size? float-char-classes!) + C_FL_EOF - state: as-integer float-transitions/index - if state = 7 [throw-error lex s e TYPE_FLOAT] ;-- T_FL_ERROR - ] - - load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!]][ - integer/make-at alloc-slot lex lex/value - lex/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: e + 1 ;-- skip " ] - load-string: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-string: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local len unit index class digits extra cp type [integer!] str [red-string!] @@ -1342,7 +1385,7 @@ lexer: context [ lex/in-pos: e + 1 ;-- skip ending delimiter ] - load-word: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-word: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local cp type class index [integer!] p pos [byte-ptr!] @@ -1351,34 +1394,6 @@ lexer: context [ type: lex/scanned assert type > 0 - either flags and flags-LG = flags-LG [ ;-- handle word<tag> cases - p: s - while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < - if p + 1 < e [ - pos: p - p: p + 1 - cp: as-integer p/1 ;-- check for valid tag - class: lex-classes/cp and FFh - index: S_LESSER * (size? character-classes!) + class ;-- simulate transition from S_LESSER - if (as-integer transitions/index) = S_TAG [ ;-- check if valid tag starting is recognized - while [all [p < e p/1 <> #">"]][p: p + 1] ;-- search > - if p < e [ - e: pos ;-- cut the word before < - lex/in-pos: pos ;-- resume scanning from < - ] - ] - ] - ][ - if all [flags and C_FLAG_LESSER <> 0 lex/entry = S_PATH e/0 = #"<"][ - cell: lex/tail - 1 - if TYPE_OF(cell) = TYPE_POINT [ - e: e - 1 ;-- handle word</tag> cases - lex/in-pos: e ;-- resume scanning from < - lex/entry: S_START ;-- cancel the newly opened path - lex/tail: cell - ] - ] - ] if type <> TYPE_WORD [ switch type [ TYPE_ISSUE @@ -1392,15 +1407,15 @@ lexer: context [ default [0] ] ] - if lex/entry = S_PATH [if any [s/1 = #"'" s/1 = #":"][s: s + 1]] - - cell: alloc-slot lex - word/make-at symbol/make-alt-utf8 s as-integer e - s cell - set-type cell type + if load? [ + cell: alloc-slot lex + word/make-at symbol/make-alt-utf8 s as-integer e - s cell + set-type cell type + ] if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] - load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local p [byte-ptr!] ][ @@ -1410,12 +1425,12 @@ lexer: context [ if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] lex/type: TYPE_FILE - load-string lex s e flags + load-string lex s e flags load? if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local bin [red-binary!] err [byte-ptr!] @@ -1439,55 +1454,65 @@ lexer: context [ 2 [len / 8] default [throw-error lex s e TYPE_BINARY 0] ] - bin: binary/make-at alloc-slot lex size - ser: GET_BUFFER(bin) + ser: either load? [ + bin: binary/make-at alloc-slot lex size + GET_BUFFER(bin) + ][null] err: switch base [ - 16 [decode-16 s e ser] - 64 [decode-64 s e ser] - 2 [decode-2 s e ser] + 16 [decode-16 s e ser load?] + 64 [decode-64 s e ser load?] + 2 [decode-2 s e ser load?] default [assert false null] ] if err <> null [throw-error lex err e TYPE_BINARY] - assert (as byte-ptr! ser/offset) + ser/size >= as byte-ptr! ser/tail + assert any [not load? (as byte-ptr! ser/offset) + ser/size >= as byte-ptr! ser/tail] lex/in-pos: e + 1 ;-- skip } ] - load-char: func [lex [state!] s e [byte-ptr!] flags [integer!] - /local - char [red-char!] - ][ - char: as red-char! alloc-slot lex - set-type as cell! char TYPE_CHAR - char/value: lex/value - ] - - load-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-percent: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local fl [red-float!] ][ assert e/1 = #"%" - load-float lex s e flags + load-float lex s e flags load? fl: as red-float! lex/tail - 1 set-type as cell! fl TYPE_PERCENT fl/value: fl/value / 100.0 lex/in-pos: e + 1 ;-- skip ending delimiter ] - load-float: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-float: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local + state index class err [integer!] fl [red-float!] - err [integer!] + f [float!] ][ - err: 0 - fl: as red-float! alloc-slot lex - set-type as cell! fl TYPE_FLOAT - fl/value: dtoa/to-float s e :err - if err <> 0 [throw-error lex s e TYPE_FLOAT] - lex/scanned: TYPE_FLOAT + state: 0 ;-- S_FL_START + until [ + index: as-integer s/1 + class: as-integer float-classes/index + index: state * (size? float-char-classes!) + class + state: as-integer float-transitions/index + s: s + 1 + s = e + ] + index: state * (size? float-char-classes!) + C_FL_EOF + state: as-integer float-transitions/index + if state = 7 [throw-error lex s e TYPE_FLOAT] ;-- T_FL_ERROR + + if load? [ + err: 0 + f: dtoa/to-float s e :err + if err <> 0 [throw-error lex s e TYPE_FLOAT] + fl: as red-float! alloc-slot lex + set-type as cell! fl TYPE_FLOAT + fl/value: f + ] + ;lex/scanned: TYPE_FLOAT lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-float-special: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-float-special: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local fl [red-float!] p [byte-ptr!] @@ -1505,20 +1530,24 @@ lexer: context [ throw-error lex s e TYPE_FLOAT ] ] - fl: as red-float! alloc-slot lex - set-type as cell! fl TYPE_FLOAT - fl/value: f + if load? [ + fl: as red-float! alloc-slot lex + set-type as cell! fl TYPE_FLOAT + fl/value: f + ] lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-tuple: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local cell [cell!] i pos [integer!] tp p [byte-ptr!] ][ - cell: alloc-slot lex - tp: (as byte-ptr! cell) + 4 + if load? [ + cell: alloc-slot lex + tp: (as byte-ptr! cell) + 4 + ] pos: 0 i: 0 p: s @@ -1527,7 +1556,7 @@ lexer: context [ either p/1 = #"." [ pos: pos + 1 if any [i < 0 i > 255 pos > 12 p/2 = #"."][throw-error lex s e TYPE_TUPLE] - tp/pos: as byte! i + if load? [tp/pos: as byte! i] i: 0 ][ i: i * 10 + as-integer (p/1 - #"0") @@ -1535,14 +1564,16 @@ lexer: context [ p: p + 1 ] pos: pos + 1 ;-- last number - tp/pos: as byte! i if any [i < 0 i > 255 pos > 12][throw-error lex s e TYPE_TUPLE] - cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) + if load? [ + tp/pos: as byte! i + cell/header: cell/header and type-mask or TYPE_TUPLE or (pos << 19) + ] lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-date: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-date: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local err year month day hour min tz-h tz-m len ylen dlen value week wday yday [integer!] @@ -1613,7 +1644,7 @@ lexer: context [ calc-time ] store-date: [ - dt: date/make-at alloc-slot lex year month day tm tz-h tz-m time? TZ? + if load? [dt: date/make-at alloc-slot lex year month day tm tz-h tz-m time? TZ?] lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1718,11 +1749,10 @@ lexer: context [ store-date ] - load-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-pair: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local - index [integer!] - class [integer!] - p [byte-ptr!] + index class x y [integer!] + p [byte-ptr!] ][ p: s until [ @@ -1731,16 +1761,14 @@ lexer: context [ class: lex-classes/index class = C_X ] - pair/make-at - alloc-slot lex - scan-integer lex s p flags - scan-integer lex p + 1 e flags - - lex/scanned: TYPE_PAIR ;-- overwrite value set by scan-integer + x: load-integer lex s p flags no + y: load-integer lex p + 1 e flags no + if load? [pair/make-at alloc-slot lex x y] + lex/scanned: TYPE_PAIR ;-- overwrite value set by load-integer lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-time: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-time: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local err hour min len [integer!] p mark [byte-ptr!] @@ -1774,22 +1802,22 @@ lexer: context [ tm: (3600.0 * as-float hour) + (60.0 * as-float min) + tm if hour < 0 [tm: 0.0 - tm] - time/make-at tm alloc-slot lex + if load? [time/make-at tm alloc-slot lex] ] - load-money: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + load-money: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ ;;TBD: implement this function once money! type is done throw-error lex s e ERR_BAD_CHAR ] - load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!]][ + load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_TAG - load-string lex s e flags + load-string lex s e flags load? lex/in-pos: e + 1 ;-- skip ending delimiter ] - load-url: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-url: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local p [byte-ptr!] ][ @@ -1797,21 +1825,21 @@ lexer: context [ p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] lex/type: TYPE_URL - load-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + load-string lex s - 1 e flags load? ;-- compensate for lack of starting delimiter lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-email: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-email: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local p [byte-ptr!] ][ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_EMAIL - load-string lex s - 1 e flags ;-- compensate for lack of starting delimiter + load-string lex s - 1 e flags load? ;-- compensate for lack of starting delimiter lex/in-pos: e ;-- reset the input position to delimiter byte ] - load-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] + load-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local int [red-integer!] i index [integer!] @@ -1832,16 +1860,18 @@ lexer: context [ s: s + 1 ] assert all [s = e s/1 = #"h"] - int: as red-integer! alloc-slot lex - set-type as cell! int TYPE_INTEGER - int/value: i + if load? [ + int: as red-integer! alloc-slot lex + set-type as cell! int TYPE_INTEGER + int/value: i + ] lex/in-pos: e + 1 ;-- skip h ] scan-tokens: func [ - lex [state!] - one? [logic!] - only? [logic!] ;-- prescan only + lex [state!] + one? [logic!] + pscan? [logic!] ;-- prescan only /local cp class index state prev flags line mark offset idx [integer!] term? load? ld? scan? [logic!] @@ -1895,22 +1925,34 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - scan?: either lex/fun-ptr = null [not only?][ + scan?: either lex/fun-ptr = null [not pscan?][ idx: either zero? lex/scanned [0 - index][lex/scanned] fire-event lex EVT_PRESCAN idx null s lex/in-pos ] - if scan? [ - do-scan: as scanner! scanners/index ;-- Scanning stage -- - if :do-scan <> null [catch LEX_ERR [do-scan lex s p flags]] - load?: either lex/fun-ptr = null [any [not one? ld?]][ - index: either zero? lex/scanned [0 - index][lex/scanned] - either state >= T_INTEGER [fire-event lex EVT_SCAN index null s lex/in-pos][yes] + if scan? [ ;-- Scanning stage -- + load?: any [not one? ld?] + do-scan: as scanner! scanners/index + either state < T_INTEGER [ + catch LEX_ERR [do-scan lex s p flags no] + ][ + if any [not lex/load? lex/fun-ptr = null][ + if :do-scan = null [do-scan: as scanner! loaders/index] + catch LEX_ERR [do-scan lex s p flags lex/load?] + if lex/fun-ptr <> null [ + index: either zero? lex/scanned [0 - index][lex/scanned] + load?: fire-event lex EVT_SCAN index null s lex/in-pos + ] + ] ] + ;load?: either lex/fun-ptr = null [any [not one? ld?]][ + ; index: either zero? lex/scanned [0 - index][lex/scanned] + ; either state >= T_INTEGER [fire-event lex EVT_SCAN index null s lex/in-pos][yes] + ;] if load? [ ;-- Loading stage -- index: lex/exit - --EXIT_STATES-- do-load: as loader! loaders/index if :do-load <> null [ - catch LEX_ERR [do-load lex s p flags] + catch LEX_ERR [do-load lex s p flags yes] if lex/fun-ptr <> null [ slot: lex/tail - 1 unless fire-event lex EVT_LOAD TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] @@ -1920,7 +1962,7 @@ lexer: context [ system/thrown: 0 if all [lex/entry = S_PATH state <> T_PATH state <> T_ERROR][ - check-path-end lex s lex/in-pos flags ;-- lex/in-pos could have changed + check-path-end lex s lex/in-pos flags load? ;-- lex/in-pos could have changed ] ] if all [one? lex/scanned > 0 lex/entry <> S_PATH lex/entry <> S_M_STRING state <> T_PATH][ @@ -2112,19 +2154,19 @@ lexer: context [ :scan-mstring-open null ;-- T_MSTR_OP (multiline string) :scan-mstring-close null ;-- T_MSTR_CL (multiline string) :scan-map-open null ;-- T_MAP_OP - :scan-path-open :load-word ;-- T_PATH + :scan-path-open null ;-- T_PATH :scan-construct null ;-- T_CONS_MK :scan-comment null ;-- T_CMT - :scan-integer :load-integer ;-- T_INTEGER + null :load-integer ;-- T_INTEGER :scan-word :load-word ;-- T_WORD :scan-refinement :load-word ;-- T_REFINE - :scan-char :load-char ;-- T_CHAR - null :load-word ;-- T_ISSUE + null :load-char ;-- T_CHAR + :scan-issue :load-word ;-- T_ISSUE null :load-string ;-- T_STRING null :load-file ;-- T_FILE null :load-binary ;-- T_BINARY null :load-percent ;-- T_PERCENT - :scan-float :load-float ;-- T_FLOAT + null :load-float ;-- T_FLOAT null :load-float-special ;-- T_FLOAT_SP null :load-tuple ;-- T_TUPLE null :load-date ;-- T_DATE From b66b90b3bfe9cb717433bc8f156d8602633648f1 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Mon, 24 Feb 2020 14:17:00 +0800 Subject: [PATCH 0939/3432] FEAT: preliminary support for box-shadow effect in DRAW. ``` view [base 200x200 white draw [ fill-pen white shadow 10x10 10 255.0.0 box 30x30 130x130 20 ]] view [base 200x200 white draw [fill-pen white shadow 5x10 18 255.0.0 shadow -5x-10 18 0.0.255 box 30x30 130x130 line 30x180 130x180]] ``` --- modules/view/backends/windows/direct2d.reds | 14 +-- modules/view/backends/windows/draw.reds | 94 ++++++++++++++++++++- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/modules/view/backends/windows/direct2d.reds b/modules/view/backends/windows/direct2d.reds index 40b8bf6c2e..95a9058fe1 100644 --- a/modules/view/backends/windows/direct2d.reds +++ b/modules/view/backends/windows/direct2d.reds @@ -45,6 +45,8 @@ IID_IDCompositionDevice: [C37EA93Ah 450DE7AAh 46976FB1h F30704CBh] IID_IDGdiInterop: [E0DB51C3h 4BAE6F77h 75E4D5B3h 3858B309h] IID_ID2D1DeviceContext: [E8F7FE7Ah 466D191Ch 569795ADh 98A9BD78h] CLSID_D2D1UnPremultiply: [FB9AC489h 41EDAD8Dh 63BB9999h F710D147h] +CLSID_D2D1Scale: [9DAF9369h 4D0E3846h 600C4EA4h D7A53479h] +CLSID_D2D1Shadow: [C67EA361h 4E691863h 5D69DB89h 6B5B9A3Eh] D2D1_FACTORY_OPTIONS: alias struct! [ debugLevel [integer!] @@ -490,7 +492,7 @@ ID2D1Properties: alias struct! [ GetType [int-ptr!] GetPropertyIndex [int-ptr!] SetValueByName [int-ptr!] - SetValue [int-ptr!] + SetValue [function! [this [this!] idx [uint32!] type [integer!] data [byte-ptr!] datasize [uint32!] return: [integer!]]] GetValueByName [int-ptr!] GetValue [int-ptr!] GetValueSize [int-ptr!] @@ -499,11 +501,11 @@ ID2D1Properties: alias struct! [ ID2D1Effect: alias struct! [ Base [ID2D1Properties value] - SetInput [function! [this [this!] idx [uint32!] input [int-ptr!] invalidate [logic!]]] + SetInput [function! [this [this!] idx [uint32!] input [this!] invalidate [logic!]]] SetInputCount [function! [this [this!] count [uint32!] return: [integer!]]] - GetInput [function! [this [this!] idx [uint32!] input [ptr-ptr!]]] + GetInput [function! [this [this!] idx [uint32!] input [com-ptr!]]] GetInputCount [function! [this [this!] return: [integer!]]] - GetOutput [function! [this [this!] idx [uint!] output [ptr-ptr!]]] + GetOutput [function! [this [this!] output [com-ptr!]]] ] ID2D1CommandList: alias struct! [ @@ -794,14 +796,14 @@ CreateBitmapFromWicBitmap*: alias function! [ CreateEffect*: alias function! [ this [this!] - effectID [tagGUID] + effectID [int-ptr!] effect [com-ptr!] return: [integer!] ] DrawImage*: alias function! [ this [this!] - image [int-ptr!] + image [this!] offset [POINT_2F] rect [RECT_F!] interpola [integer!] diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 14672f0639..270be76ece 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -10,6 +10,8 @@ Red/System [ } ] +#define GAUSSIAN_SCALE_FACTOR 1.87997120597325 + #include %text-box.reds #enum DRAW-BRUSH-TYPE! [ @@ -930,6 +932,23 @@ OS-draw-box: func [ rc [ROUNDED_RECT_F! value] radius [red-integer!] type [integer!] + bmp [this!] + sbmp [this!] + eff-v [com-ptr! value] + eff-s [com-ptr! value] + eff [this!] + eff2 [this!] + effect [ID2D1Effect] + pt [POINT_2F value] + target [render-target!] + output [com-ptr! value] + sigma [float32!] + s [shadow!] + w [integer!] + h [integer!] + spread [integer!] + scale [float32!] + unk [IUnknown] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -944,10 +963,27 @@ OS-draw-box: func [ if upper/x > lower/x [t: upper/x upper/x: lower/x lower/x: t] if upper/y > lower/y [t: upper/y upper/y: lower/y lower/y: t] - rc/right: as float32! lower/x - rc/bottom: as float32! lower/y - rc/left: as float32! upper/x - rc/top: as float32! upper/y + w: lower/x - upper/x + h: lower/y - upper/y + either ctx/shadow? [ + scale: dpi-value / as float32! 96.0 + rc/left: as float32! 0.5 + rc/top: as float32! 0.5 + rc/right: (as float32! w) + (as float32! 0.5) + rc/bottom: (as float32! h) + (as float32! 0.5) + + bmp: create-d2d-bitmap ;-- create an intermediate bitmap + this + as-integer ceil (as-float w + 1) * scale + as-integer ceil (as-float h + 1) * scale + 1 + dc/SetTarget this bmp + ][ + rc/left: as float32! upper/x + rc/top: as float32! upper/y + rc/right: as float32! lower/x + rc/bottom: as float32! lower/y + ] type: ctx/brush-type if type > DRAW_BRUSH_GRADIENT [ ;-- fill-pen @@ -982,6 +1018,56 @@ OS-draw-box: func [ ] ] if type > DRAW_BRUSH_GRADIENT [post-process-brush ctx/pen ctx/pen-offset] + + if ctx/shadow? [ + target: as render-target! ctx/target + dc/SetTarget this target/bitmap + + s: ctx/shadows + until [ + sbmp: bmp + spread: s/spread + if spread <> 0 [ ;-- scale intput bitmap + dc/CreateEffect this CLSID_D2D1Scale :eff-s + eff2: eff-s/value + effect: as ID2D1Effect eff2/vtbl + effect/SetInput eff2 0 bmp true + pt/x: (as float32! spread * 2 + w) / (as float32! w) + pt/y: (as float32! spread * 2 + h) / (as float32! h) + effect/base/setValue eff2 0 0 as byte-ptr! :pt size? POINT_2F + effect/GetOutput eff2 :output + sbmp: output/value + ] + + dc/CreateEffect this CLSID_D2D1Shadow :eff-v + eff: eff-v/value + effect: as ID2D1Effect eff/vtbl + effect/SetInput eff 0 sbmp true + if spread <> 0 [ + COM_SAFE_RELEASE(unk sbmp) + COM_SAFE_RELEASE(unk eff2) + ] + + sigma: as float32! (as float! s/blur) / GAUSSIAN_SCALE_FACTOR + effect/base/setValue eff 0 0 as byte-ptr! :sigma size? float32! + effect/base/setValue eff 1 0 as byte-ptr! to-dx-color s/color null size? D3DCOLORVALUE + + effect/GetOutput eff :output + sbmp: output/value + + pt/x: as float32! upper/x + s/offset-x - spread + pt/y: as float32! upper/y + s/offset-y - spread + dc/DrawImage this sbmp pt null 1 0 + COM_SAFE_RELEASE(unk sbmp) + COM_SAFE_RELEASE(unk eff) + s: s/next + null? s + ] + pt/x: as float32! upper/x + pt/y: as float32! upper/y + dc/DrawImage this bmp pt null 1 0 + COM_SAFE_RELEASE(unk bmp) + ] ] OS-draw-triangle: func [ From c299227047d0fe0a952f3ed0370bdb56cb2e9d45 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Mon, 24 Feb 2020 18:20:04 +0800 Subject: [PATCH 0940/3432] FEAT: adds shadow effect for ellipse in DRAW. --- modules/view/backends/windows/draw.reds | 162 ++++++++++++++---------- 1 file changed, 98 insertions(+), 64 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 270be76ece..f2a1781269 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -921,18 +921,16 @@ OS-draw-line-width: func [ ] ] -OS-draw-box: func [ +draw-shadow: func [ ctx [draw-ctx!] - upper [red-pair!] - lower [red-pair!] + bmp [this!] ;-- input bitmap + x [integer!] + y [integer!] + w [integer!] + h [integer!] /local this [this!] dc [ID2D1DeviceContext] - t [integer!] - rc [ROUNDED_RECT_F! value] - radius [red-integer!] - type [integer!] - bmp [this!] sbmp [this!] eff-v [com-ptr! value] eff-s [com-ptr! value] @@ -944,11 +942,80 @@ OS-draw-box: func [ output [com-ptr! value] sigma [float32!] s [shadow!] + spread [integer!] + unk [IUnknown] + err1 [integer!] + err2 [integer!] +][ + this: as this! ctx/dc + dc: as ID2D1DeviceContext this/vtbl + err1: 0 err2: 0 + dc/Flush this :err1 :err2 + + target: as render-target! ctx/target + dc/SetTarget this target/bitmap + + s: ctx/shadows + until [ + sbmp: bmp + spread: s/spread + if spread <> 0 [ ;-- scale intput bitmap + dc/CreateEffect this CLSID_D2D1Scale :eff-s + eff2: eff-s/value + effect: as ID2D1Effect eff2/vtbl + effect/SetInput eff2 0 bmp true + pt/x: (as float32! spread * 2 + w) / (as float32! w) + pt/y: (as float32! spread * 2 + h) / (as float32! h) + effect/base/setValue eff2 0 0 as byte-ptr! :pt size? POINT_2F + effect/GetOutput eff2 :output + sbmp: output/value + ] + + dc/CreateEffect this CLSID_D2D1Shadow :eff-v + eff: eff-v/value + effect: as ID2D1Effect eff/vtbl + effect/SetInput eff 0 sbmp true + if spread <> 0 [ + COM_SAFE_RELEASE(unk sbmp) + COM_SAFE_RELEASE(unk eff2) + ] + + sigma: as float32! (as float! s/blur) / GAUSSIAN_SCALE_FACTOR + effect/base/setValue eff 0 0 as byte-ptr! :sigma size? float32! + effect/base/setValue eff 1 0 as byte-ptr! to-dx-color s/color null size? D3DCOLORVALUE + + effect/GetOutput eff :output + sbmp: output/value + + pt/x: as float32! x + s/offset-x - spread + pt/y: as float32! y + s/offset-y - spread + dc/DrawImage this sbmp pt null 1 0 + COM_SAFE_RELEASE(unk sbmp) + COM_SAFE_RELEASE(unk eff) + s: s/next + null? s + ] + pt/x: as float32! x + pt/y: as float32! y + dc/DrawImage this bmp pt null 1 0 + COM_SAFE_RELEASE(unk bmp) +] + +OS-draw-box: func [ + ctx [draw-ctx!] + upper [red-pair!] + lower [red-pair!] + /local + this [this!] + dc [ID2D1DeviceContext] + t [integer!] + rc [ROUNDED_RECT_F! value] + radius [red-integer!] + type [integer!] + bmp [this!] w [integer!] h [integer!] - spread [integer!] scale [float32!] - unk [IUnknown] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -974,8 +1041,8 @@ OS-draw-box: func [ bmp: create-d2d-bitmap ;-- create an intermediate bitmap this - as-integer ceil (as-float w + 1) * scale - as-integer ceil (as-float h + 1) * scale + as-integer (as float32! w + 1) * scale + as-integer (as float32! h + 1) * scale 1 dc/SetTarget this bmp ][ @@ -1019,55 +1086,7 @@ OS-draw-box: func [ ] if type > DRAW_BRUSH_GRADIENT [post-process-brush ctx/pen ctx/pen-offset] - if ctx/shadow? [ - target: as render-target! ctx/target - dc/SetTarget this target/bitmap - - s: ctx/shadows - until [ - sbmp: bmp - spread: s/spread - if spread <> 0 [ ;-- scale intput bitmap - dc/CreateEffect this CLSID_D2D1Scale :eff-s - eff2: eff-s/value - effect: as ID2D1Effect eff2/vtbl - effect/SetInput eff2 0 bmp true - pt/x: (as float32! spread * 2 + w) / (as float32! w) - pt/y: (as float32! spread * 2 + h) / (as float32! h) - effect/base/setValue eff2 0 0 as byte-ptr! :pt size? POINT_2F - effect/GetOutput eff2 :output - sbmp: output/value - ] - - dc/CreateEffect this CLSID_D2D1Shadow :eff-v - eff: eff-v/value - effect: as ID2D1Effect eff/vtbl - effect/SetInput eff 0 sbmp true - if spread <> 0 [ - COM_SAFE_RELEASE(unk sbmp) - COM_SAFE_RELEASE(unk eff2) - ] - - sigma: as float32! (as float! s/blur) / GAUSSIAN_SCALE_FACTOR - effect/base/setValue eff 0 0 as byte-ptr! :sigma size? float32! - effect/base/setValue eff 1 0 as byte-ptr! to-dx-color s/color null size? D3DCOLORVALUE - - effect/GetOutput eff :output - sbmp: output/value - - pt/x: as float32! upper/x + s/offset-x - spread - pt/y: as float32! upper/y + s/offset-y - spread - dc/DrawImage this sbmp pt null 1 0 - COM_SAFE_RELEASE(unk sbmp) - COM_SAFE_RELEASE(unk eff) - s: s/next - null? s - ] - pt/x: as float32! upper/x - pt/y: as float32! upper/y - dc/DrawImage this bmp pt null 1 0 - COM_SAFE_RELEASE(unk bmp) - ] + if ctx/shadow? [draw-shadow ctx bmp upper/x upper/y w h] ] OS-draw-triangle: func [ @@ -1231,6 +1250,8 @@ do-draw-ellipse: func [ rx [float32!] ry [float32!] ellipse [D2D1_ELLIPSE value] + scale [float32!] + bmp [this!] ][ this: as this! ctx/dc dc: as ID2D1DeviceContext this/vtbl @@ -1241,10 +1262,22 @@ do-draw-ellipse: func [ dy: as float32! height rx: dx / as float32! 2.0 ry: dy / as float32! 2.0 - ellipse/x: cx + rx - ellipse/y: cy + ry + either ctx/shadow? [ + scale: dpi-value / as float32! 96.0 + ellipse/x: rx + as float32! 0.5 + ellipse/y: ry + as float32! 0.5 + bmp: create-d2d-bitmap ;-- create an intermediate bitmap + this + as-integer (as float32! width + 1) * scale + as-integer (as float32! height + 1) * scale + 1 + dc/SetTarget this bmp + ][ + ellipse/x: cx + rx + ellipse/y: cy + ry + ] ellipse/radiusX: rx - ellipse/radiusY: ry + ellipse/radiusy: ry either ctx/brush-type > DRAW_BRUSH_GRADIENT [ ;-- fill-pen calc-brush-position ctx/brush @@ -1271,6 +1304,7 @@ do-draw-ellipse: func [ dc/DrawEllipse this ellipse ctx/pen ctx/pen-width ctx/pen-style ] ] + if ctx/shadow? [draw-shadow ctx bmp x y width height] ] OS-draw-circle: func [ From a815d530244f8c41cde004a85a63e375682d0932 Mon Sep 17 00:00:00 2001 From: bitbegin <bitbegin@gmail.com> Date: Sun, 23 Feb 2020 17:37:18 +0800 Subject: [PATCH 0941/3432] FIX: radial gradient issues like code/Scripts/bubbles.red --- modules/view/backends/gtk3/draw.reds | 171 ++++++++++++--------------- 1 file changed, 76 insertions(+), 95 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 76c3349372..a7102b9b80 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -206,7 +206,7 @@ update-pattern: func [ a [float!] p [float!] ][ - cairo_matrix_init_translate m 0.0 - cx 0.0 - cy + cairo_matrix_init_identity m either grad/matrix-on? [ matrix: as cairo_matrix_t! grad/matrix cairo_matrix_multiply res matrix m @@ -332,50 +332,44 @@ check-grad-points: func [ case [ grad/type = linear [ either grad/offset-on? [ - x1: as float! upper-x + grad/offset/x - y1: as float! upper-y + grad/offset/y - x2: as float! upper-x + grad/offset2/x - y2: as float! upper-y + grad/offset2/y + x1: as float! grad/offset/x + y1: as float! grad/offset/y + x2: as float! grad/offset2/x + y2: as float! grad/offset2/y ][ x1: as float! upper-x y1: as float! upper-y x2: as float! lower-x y2: as float! lower-y ] - pattern: cairo_pattern_create_linear 0.0 0.0 x2 - x1 y2 - y1 + pattern: cairo_pattern_create_linear x1 y1 x2 y2 ] grad/type = radial [ - if upper-x > lower-x [ - t: lower-x - lower-x: upper-x - upper-x: t - ] - if upper-y > lower-y [ - t: lower-y - lower-y: upper-y - upper-y: t - ] either grad/offset-on? [ either grad/focal-on? [ - x1: as float! upper-x + grad/focal/x - y1: as float! upper-y + grad/focal/y - x2: as float! upper-x + grad/offset/x - y2: as float! upper-y + grad/offset/y - r2: as float! grad/offset2/x - delta: line-distance grad/offset/x grad/offset/y grad/focal/x grad/focal/y - r1: as float! delta - either r1 >= r2 [ - r1: 0.0 - ][ - r1: r2 - r1 - ] + x1: as float! grad/focal/x + y1: as float! grad/focal/y + x2: as float! grad/offset/x + y2: as float! grad/offset/y + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ][ - x1: as float! upper-x + grad/offset/x - y1: as float! upper-y + grad/offset/y + x1: as float! grad/offset/x + y1: as float! grad/offset/y x2: x1 y2: y1 - r1: 0.0 - r2: as float! grad/offset2/x + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ] ][ + if upper-x > lower-x [ + t: lower-x + lower-x: upper-x + upper-x: t + ] + if upper-y > lower-y [ + t: lower-y + lower-y: upper-y + upper-y: t + ] delta: line-distance upper-x upper-y lower-x lower-y px: as float32! lower-x + upper-x py: as float32! lower-y + upper-y @@ -387,7 +381,7 @@ check-grad-points: func [ r1: 0.0 r2: as float! delta ] - pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + pattern: cairo_pattern_create_radial x1 y1 r1 x2 y2 r2 ] true [0] ] @@ -420,50 +414,45 @@ check-grad-brush-lines: func [ cx [float32!] cy [float32!] d [float32!] - x0 [float!] - y0 [float!] - delta [float32!] ][ unless grad/on? [exit] pattern: null case [ grad/type = linear [ either grad/offset-on? [ - x1: as float! point/x + grad/offset/x - y1: as float! point/y + grad/offset/y - x2: as float! point/x + grad/offset2/x - y2: as float! point/y + grad/offset2/y + x1: as float! grad/offset/x + y1: as float! grad/offset/y + x2: as float! grad/offset2/x + y2: as float! grad/offset2/y ][ x1: as float! point/x y1: as float! point/y next: point + 1 x2: as float! next/x y2: as float! next/y ] - pattern: cairo_pattern_create_linear 0.0 0.0 x2 - x1 y2 - y1 + pattern: cairo_pattern_create_linear x1 y1 x2 y2 ] grad/type = radial [ - cx: as float32! 0.0 - cy: cx - d: cx - get-shape-center point end :cx :cy :d either grad/offset-on? [ - x0: as float! cx - d - y0: as float! cy - d either grad/focal-on? [ - x1: x0 + as float! grad/focal/x - y1: y0 + as float! grad/focal/y - x2: x0 + as float! grad/offset/x - y2: y0 + as float! grad/offset/y - r2: as float! grad/offset2/x - r1: 0.0 + x1: as float! grad/focal/x + y1: as float! grad/focal/y + x2: as float! grad/offset/x + y2: as float! grad/offset/y + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ][ - x1: x0 + as float! grad/offset/x - y1: y0 + as float! grad/offset/y - r1: 0.0 + x1: as float! grad/offset/x + y1: as float! grad/offset/y x2: x1 y2: y1 - r2: as float! grad/offset2/x + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ] ][ + cx: as float32! 0.0 + cy: cx + d: cx + get-shape-center point end :cx :cy :d x1: as float! cx y1: as float! cy r1: 0.0 @@ -471,7 +460,7 @@ check-grad-brush-lines: func [ y2: y1 r2: as float! d ] - pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + pattern: cairo_pattern_create_radial x1 y1 r1 x2 y2 r2 ] true [0] ] @@ -487,8 +476,6 @@ check-grad-arc-radial: func [ ar [float!] /local pattern [handle!] - x0 [float!] - y0 [float!] x1 [float!] y1 [float!] r1 [float!] @@ -501,33 +488,31 @@ check-grad-arc-radial: func [ unless grad/type = radial [exit] pattern: null - x0: ax - ar - y0: ay - ar either grad/offset-on? [ either grad/focal-on? [ - x1: x0 + as float! grad/focal/x - y1: y0 + as float! grad/focal/y - x2: x0 + as float! grad/offset/x - y2: y0 + as float! grad/offset/y - r2: as float! grad/offset2/x - r1: 0.0 + x1: as float! grad/focal/x + y1: as float! grad/focal/y + x2: as float! grad/offset/x + y2: as float! grad/offset/y + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ][ - x1: x0 + as float! grad/offset/x - y1: y0 + as float! grad/offset/y - r1: 0.0 + x1: as float! grad/offset/x + y1: as float! grad/offset/y x2: x1 y2: y1 - r2: as float! grad/offset2/x + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ] ][ - x1: ax - y1: ay + x1: ax - ar + y1: ay - ar r1: 0.0 x2: x1 y2: y1 r2: ar ] - pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + pattern: cairo_pattern_create_radial x1 y1 r1 x2 y2 r2 unless null? pattern [ update-pattern grad pattern x1 y1 @@ -540,8 +525,6 @@ check-grad-box-radial: func [ lower [red-pair!] /local pattern [handle!] - x0 [float!] - y0 [float!] x1 [float!] y1 [float!] r1 [float!] @@ -556,24 +539,21 @@ check-grad-box-radial: func [ unless grad/type = radial [exit] pattern: null - x0: either upper/x < lower/x [as float! upper/x][as float! lower/x] - y0: either upper/y < lower/y [as float! upper/y][as float! lower/y] - either grad/offset-on? [ either grad/focal-on? [ - x1: x0 + as float! grad/focal/x - y1: y0 + as float! grad/focal/y - x2: x0 + as float! grad/offset/x - y2: y0 + as float! grad/offset/y - r2: as float! grad/offset2/x - r1: 0.0 + x1: as float! grad/focal/x + y1: as float! grad/focal/y + x2: as float! grad/offset/x + y2: as float! grad/offset/y + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ][ - x1: x0 + as float! grad/offset/x - y1: y0 + as float! grad/offset/y - r1: 0.0 + x1: as float! grad/offset/x + y1: as float! grad/offset/y x2: x1 y2: y1 - r2: as float! grad/offset2/x + r1: 0.0 ;as float! grad/offset2/x + r2: as float! grad/offset2/y ] ][ x1: as float! upper/x + lower/x @@ -596,7 +576,7 @@ check-grad-box-radial: func [ r2: either w > h [as float! w][as float! h] r2: r2 / 2.0 ] - pattern: cairo_pattern_create_radial 0.0 0.0 r1 x2 - x1 y2 - y1 r2 + pattern: cairo_pattern_create_radial x1 y1 r1 x2 y2 r2 unless null? pattern [ update-pattern grad pattern x1 y1 @@ -1431,14 +1411,14 @@ OS-draw-grad-pen-old: func [ grad/offset/x: offset/x + w grad/offset/y: offset/y + w grad/offset2/x: offset/x + h - grad/offset2/y: offset/y + h + grad/offset2/y: offset/y + w ] type = radial [ grad/offset-on?: on grad/offset/x: offset/x grad/offset/y: offset/y - grad/offset2/x: h ;-- bigger radius - grad/offset2/y: w ;-- smaller radius + grad/offset2/x: w ;-- smaller radius + grad/offset2/y: h ;-- bigger radius ] true [ grad/offset-on?: off @@ -1589,7 +1569,8 @@ OS-draw-grad-pen: func [ grad/offset/x: point/x grad/offset/y: point/y p: get-float as red-integer! point + 1 - grad/offset2/x: as integer! p + grad/offset2/x: 0 + grad/offset2/y: as integer! p if focal? [ grad/focal-on?: on point: point + 2 From 5813ecda4f19c9af61c514a34cf107c7e8a6c99d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Mon, 24 Feb 2020 11:54:08 +0100 Subject: [PATCH 0942/3432] FEAT: more changes for the refactoring. --- libRed/libRed.red | 2 +- runtime/datatypes/block.reds | 2 +- runtime/datatypes/common.reds | 2 +- runtime/lexer.reds | 105 +++++++++++++++++++++++------- runtime/natives.reds | 4 +- system/utils/libRedRT-exports.r | 2 +- tests/source/units/lexer-test.red | 2 +- 7 files changed, 87 insertions(+), 32 deletions(-) diff --git a/libRed/libRed.red b/libRed/libRed.red index ce215408a8..29f71909e7 100644 --- a/libRed/libRed.red +++ b/libRed/libRed.red @@ -251,7 +251,7 @@ Red [ if last-error <> null [return last-error] TRAP_ERRORS(name [ - lexer/scan-string stack/arguments str -1 no yes yes no null null null + lexer/scan-alt stack/arguments str -1 no yes yes no null null null stack/unwind-last ]) ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index ddd4ec8309..8e196fbd0b 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -649,7 +649,7 @@ block: context [ TYPE_OBJECT [object/reflect as red-object! spec words/body] TYPE_MAP [map/reflect as red-hash! spec words/body] TYPE_VECTOR [vector/to-block as red-vector! spec proto] - TYPE_STRING [lexer/scan-string as red-value! proto as red-string! spec -1 no yes yes no null null as red-series! spec] + TYPE_STRING [lexer/scan-alt as red-value! proto as red-string! spec -1 no yes yes no null null as red-series! spec] TYPE_TYPESET [typeset/to-block as red-typeset! spec proto] TYPE_ANY_PATH TYPE_ANY_LIST [proto: clone as red-block! spec no no] diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 7468caf4a5..8611bd7d28 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -351,7 +351,7 @@ load-value: func [ blk [red-block!] value [red-value!] ][ - lexer/scan-string stack/arguments str -1 yes yes yes yes null null as red-series! str + lexer/scan-alt stack/arguments str -1 yes yes yes yes null null as red-series! str blk: as red-block! stack/arguments assert TYPE_OF(blk) = TYPE_BLOCK diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d001ac6080..3bea4c1631 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1141,6 +1141,42 @@ lexer: context [ ] ] + scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + /local + len unit cp type [integer!] + esc [byte!] + ][ + s: s + 1 ;-- skip start delimiter + unit: 1 << (flags >>> 30) + if unit > 4 [unit: 4] + type: either lex/type = -1 [TYPE_STRING][lex/type] + + either flags and C_FLAG_CARET = 0 [ ;-- fast path when no escape sequence + if unit > UCS-1 [ + cp: -1 + while [s < e][ + s: unicode/fast-decode-utf8-char s :cp + if cp = -1 [throw-error lex s e type] + ] + ] + ][ + cp: -1 + esc: either flags and C_FLAG_ESC_HEX = 0 [#"^^"][#"%"] + while [s < e][ + s: either s/1 = esc [ + either esc = #"^^" [ + scan-escaped-char s + 1 e :cp + ][ + scan-percent-char s + 1 e :cp + ] + ][ + unicode/fast-decode-utf8-char s :cp + ] + if cp = -1 [throw-error lex s e type] + ] + ] + ] + load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] return: [integer!] /local @@ -1425,9 +1461,16 @@ lexer: context [ if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] ] lex/type: TYPE_FILE - load-string lex s e flags load? - if s/1 = #"^"" [assert e/1 = #"^"" e: e + 1] - lex/in-pos: e ;-- reset the input position to delimiter byte + either load? [ + scan-string lex s e flags no + ][ + load-string lex s e flags yes + if s/1 = #"^"" [ + if e/1 <> #"^"" [throw-error lex s e TYPE_FILE] + e: e + 1 + ] + lex/in-pos: e ;-- reset the input position to delimiter byte + ] ] load-binary: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1475,26 +1518,30 @@ lexer: context [ ][ assert e/1 = #"%" load-float lex s e flags load? - fl: as red-float! lex/tail - 1 - set-type as cell! fl TYPE_PERCENT - fl/value: fl/value / 100.0 + if load? [ + fl: as red-float! lex/tail - 1 + set-type as cell! fl TYPE_PERCENT + fl/value: fl/value / 100.0 + ] lex/in-pos: e + 1 ;-- skip ending delimiter ] load-float: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local state index class err [integer!] + p [byte-ptr!] fl [red-float!] f [float!] ][ + p: s state: 0 ;-- S_FL_START until [ - index: as-integer s/1 + index: as-integer p/1 class: as-integer float-classes/index index: state * (size? float-char-classes!) + class state: as-integer float-transitions/index - s: s + 1 - s = e + p: p + 1 + p = e ] index: state * (size? float-char-classes!) + C_FL_EOF state: as-integer float-transitions/index @@ -1687,10 +1734,10 @@ lexer: context [ ] if all [p < e p/1 = #"T"][grab-time-TZ] store-date - if week or wday <> 0 [date/set-isoweek dt week] + if all [week or wday <> 0 load?][date/set-isoweek dt week] if wday <> 0 [ if any [wday < 1 wday > 7][do-error] - date/set-weekday dt wday + if load? [date/set-weekday dt wday] ] exit ] @@ -1702,7 +1749,7 @@ lexer: context [ day: month: 1 if all [p < e p/1 = #"T"][grab-time-TZ] store-date - date/set-yearday dt yday ;-- yyyy-ddd + if load? [date/set-yearday dt yday] ;-- yyyy-ddd exit ] ][ @@ -1811,10 +1858,12 @@ lexer: context [ ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ - flags: flags and not C_FLAG_CARET ;-- clears caret flag - lex/type: TYPE_TAG - load-string lex s e flags load? - lex/in-pos: e + 1 ;-- skip ending delimiter + if load? [ + flags: flags and not C_FLAG_CARET ;-- clears caret flag + lex/type: TYPE_TAG + load-string lex s e flags yes + lex/in-pos: e + 1 ;-- skip ending delimiter + ] ] load-url: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1825,18 +1874,24 @@ lexer: context [ p: s while [all [p/1 <> #"%" p < e]][p: p + 1] ;-- check if any %xx if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] lex/type: TYPE_URL - load-string lex s - 1 e flags load? ;-- compensate for lack of starting delimiter - lex/in-pos: e ;-- reset the input position to delimiter byte + either load? [ + scan-string lex s - 1 e flags no + ][ + load-string lex s - 1 e flags yes ;-- compensate for lack of starting delimiter + lex/in-pos: e ;-- reset the input position to delimiter byte + ] ] load-email: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local p [byte-ptr!] ][ - flags: flags and not C_FLAG_CARET ;-- clears caret flag - lex/type: TYPE_EMAIL - load-string lex s - 1 e flags load? ;-- compensate for lack of starting delimiter - lex/in-pos: e ;-- reset the input position to delimiter byte + if load? [ + flags: flags and not C_FLAG_CARET ;-- clears caret flag + lex/type: TYPE_EMAIL + load-string lex s - 1 e flags load? ;-- compensate for lack of starting delimiter + lex/in-pos: e ;-- reset the input position to delimiter byte + ] ] load-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1937,7 +1992,7 @@ lexer: context [ ][ if any [not lex/load? lex/fun-ptr = null][ if :do-scan = null [do-scan: as scanner! loaders/index] - catch LEX_ERR [do-scan lex s p flags lex/load?] + catch LEX_ERR [do-scan lex s p flags no] if lex/fun-ptr <> null [ index: either zero? lex/scanned [0 - index][lex/scanned] load?: fire-event lex EVT_SCAN index null s lex/in-pos @@ -2072,7 +2127,7 @@ lexer: context [ lex/scanned ] - scan-string: func [ + scan-alt: func [ dst [red-value!] ;-- destination slot str [red-string!] size [integer!] @@ -2162,7 +2217,7 @@ lexer: context [ :scan-refinement :load-word ;-- T_REFINE null :load-char ;-- T_CHAR :scan-issue :load-word ;-- T_ISSUE - null :load-string ;-- T_STRING + :scan-string :load-string ;-- T_STRING null :load-file ;-- T_FILE null :load-binary ;-- T_BINARY null :load-percent ;-- T_PERCENT diff --git a/runtime/natives.reds b/runtime/natives.reds index f025e5ca16..dc9f125ec8 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -555,7 +555,7 @@ natives: context [ stack/set-last arg + 1 ] TYPE_STRING [ - lexer/scan-string arg as red-string! arg -1 no yes yes no null null as red-string! arg + lexer/scan-alt arg as red-string! arg -1 no yes yes no null null as red-string! arg DO_EVAL_BLOCK ] TYPE_URL @@ -2792,7 +2792,7 @@ natives: context [ ][ str: as red-string! bin if len < 0 [len: string/rs-length? str] - type: lexer/scan-string slot str len one? scan? load? no :offset fun as red-series! str + type: lexer/scan-alt slot str len one? scan? load? no :offset fun as red-series! str ] if any [not scan? not load?][ dt: as red-datatype! slot diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index 7af2f73621..34a4ffc303 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -48,7 +48,7 @@ red/interpreter/eval-path red/lexer/scan - red/lexer/scan-string + red/lexer/scan-alt red/none/push-last diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index c5d6c08bac..29db931f29 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -16,7 +16,7 @@ Red [ --test-- "tr-1" --assert [123 456 789] == transcode "123 456 789" --test-- "tr-2" --assert ["world" 111] == transcode {"world" 111} --test-- "tr-3" --assert [132 [111] ["world" [456 ["hi"]]] 222] == transcode { 132 [111] ["world" [456 ["hi"]]] 222} - --test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} + ;--test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} --test-- "tr-5" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode #{2322722220232261222023225E2F222023225E286C696E6529222023225E2836362922} --test-- "tr-6" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode {#"r" #"a" #"^^/" #"^^(line)" #"^^(66)"} --test-- "tr-7" --assert [#r #abcdc /z /abcdef] == transcode {#r #abcdc /z /abcdef} From 44f2e9550788a8651d1433c1120d45803de51abf Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 13:02:59 +0100 Subject: [PATCH 0943/3432] FIX: amend description of R/S debugging functions --- system/runtime/debug.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/runtime/debug.reds b/system/runtime/debug.reds index a6c6edee1d..e260a0c7ef 100644 --- a/system/runtime/debug.reds +++ b/system/runtime/debug.reds @@ -241,7 +241,7 @@ dump-memory: func [ ] ;------------------------------------------- -;-- Dump memory on screen in hex format as array of bytes (handy wrapper on dump-hex) +;-- Dump memory on screen in hex format as array of bytes (handy wrapper on dump-memory) ;------------------------------------------- dump-hex: func [ address [byte-ptr!] ;-- memory address where the dump starts @@ -251,7 +251,7 @@ dump-hex: func [ ] ;------------------------------------------- -;-- Dump memory on screen in hex format as array of 32-bit integers (handy wrapper on dump-hex) +;-- Dump memory on screen in hex format as array of 32-bit integers (handy wrapper on dump-memory) ;------------------------------------------- dump-hex4: func [ address [int-ptr!] ;-- memory address where the dump starts From c917184c0f9ec2aaa7316693a33851c70f683396 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 13:05:34 +0100 Subject: [PATCH 0944/3432] FEAT: implement custom datatype constructors --- runtime/datatypes/money.reds | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 214f9f38bf..3e3ca79117 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -17,6 +17,45 @@ money: context [ ;-- Support -- + make-at: func [ + slot [red-value!] + sign [integer!] + amount1 [integer!] + amount2 [integer!] + amount3 [integer!] + return: [red-money!] + /local + money [red-money!] + ][ + money: as red-money! slot + money/header: TYPE_MONEY or (sign << 14) + money/amount1: amount1 + money/amount2: amount2 + money/amount3: amount3 + money + ] + + make-in: func [ + parent [red-block!] + sign [integer!] + amount1 [integer!] + amount2 [integer!] + amount3 [integer!] + return: [red-money!] + ][ + make-at ALLOC_TAIL(parent) sign amount1 amount2 amount3 + ] + + push: func [ + sign [integer!] + amount1 [integer!] + amount2 [integer!] + amount3 [integer!] + return: [red-money!] + ][ + make-at stack/push* sign amount1 amount2 amount3 + ] + ;-- Natives -- negative?: STUB From ec19a428d2bda736b9f47265269647af50b5c972 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 13:07:16 +0100 Subject: [PATCH 0945/3432] FEAT: plug temporary high-level MONEY! loader --- boot.red | 2 ++ environment/kludge.red | 44 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 environment/kludge.red diff --git a/boot.red b/boot.red index 68b9227017..dc24cb82a3 100644 --- a/boot.red +++ b/boot.red @@ -24,6 +24,8 @@ Red [ #include %environment/system.red #include %environment/operators.red + #include %environment/kludge.red + #include %environment/codecs/png.red #include %environment/codecs/jpeg.red #include %environment/codecs/bmp.red diff --git a/environment/kludge.red b/environment/kludge.red new file mode 100644 index 0000000000..feff0ecc6a --- /dev/null +++ b/environment/kludge.red @@ -0,0 +1,44 @@ +Red [Note: "Ad-hoc loader for money! datatype."] + +forge: routine [ + sign [integer!] + amount1 [integer!] + amount2 [integer!] + amount3 [integer!] +][ + stack/set-last as red-value! money/push sign amount1 amount2 amount3 +] + +coin: function [ + string [string!] + /local + sign integral fractional +][ + digit: charset [#"0" - #"9"] + precision: 22 + scale: 05 + digits: precision - scale + + either parse string [ + set sign opt [#"-" | #"+"] + #"$" + copy integral [1 digits digit] + opt [[dot | comma] copy fractional [1 scale digit]] + end + ][ + string: rejoin [ + pad/left/with integral digits #"0" + pad/with any [fractional copy ""] scale #"0" + ] + + sign: select [#"-" 1 #"+" 0 #[none] 0] sign + binary: debase/base string 16 + + insert binary 0 ; placeholder for currency index + slice'n'dice: [loop 3 [keep to integer! reverse take/part binary 4]] ; little-endian order + + do compose [forge sign (collect slice'n'dice)] + ][ + make error! "Cannot load this." + ] +] From 8fdd28fb206d3349a199f5da03a9c7662d916497 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 13:09:30 +0100 Subject: [PATCH 0946/3432] FEAT: preliminary work on MOLD action --- runtime/datatypes/money.reds | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3e3ca79117..b469c9278a 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -14,9 +14,29 @@ Red/System [ money: context [ verbose: 0 - + + #enum sizes! [ + SIZE_BYTES: 11 + SIZE_SCALE: 05 + ] + ;-- Support -- + see: func [ + money [red-money!] + return: [red-money!] + ][ + dump-memory get-amount money 1 1 + money + ] + + get-amount: func [ + money [red-money!] + return: [byte-ptr!] + ][ + (as byte-ptr! money) + (size? money) - SIZE_BYTES + ] + make-at: func [ slot [red-value!] sign [integer!] @@ -68,8 +88,30 @@ money: context [ make: STUB to: STUB - form: STUB - mold: STUB + form: func [ + money [red-money!] + buffer [red-string!] + arg [red-value!] + part [integer!] + return: [integer!] + ][ + see money + part + ] + + mold: func [ + money [red-money!] + buffer [red-string!] + only? [logic!] + all? [logic!] + flat? [logic!] + arg [red-value!] + part [integer!] + indent [integer!] + return: [integer!] + ][ + form money buffer arg part + ] random: STUB @@ -100,7 +142,7 @@ money: context [ null ;reflect null;:to null;:form - null;:mold + :mold null ;eval-path null ;set-path null;:compare From 7e24419adb41a8ad0b0cb9fd16945990a5a3ff24 Mon Sep 17 00:00:00 2001 From: loziniak <maciej@robotix-lozinski.pl> Date: Mon, 24 Feb 2020 14:29:41 +0100 Subject: [PATCH 0947/3432] TESTS: regression test for #4205 - seed random with precise time! --- tests/source/units/regression-test-red.red | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..5c38970a9d 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2841,6 +2841,17 @@ comment { ] } + --test-- "#4205 - seed random with precise time!" + anded4205: to integer! #{FFFFFFFF} + loop 10 [ + random/seed now/time/precise + anded4205: anded4205 and last-random4205: random 10000 + wait 0.001 + ] + all-equal?4205: anded4205 = last-random4205 + --assert not all-equal?4205 + unset [anded4205 last-random4205 all-equal?4205] + ===end-group=== ~~~end-file~~~ From 907a42f0eb83d00ed7f7686fd0606ed6bab5e8b6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 15:09:54 +0100 Subject: [PATCH 0948/3432] FEAT: simple version of FORM and MOLD --- runtime/datatypes/money.reds | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b469c9278a..a3092a6411 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -20,6 +20,8 @@ money: context [ SIZE_SCALE: 05 ] + SIZE_DIGITS: SIZE_BYTES * 2 + ;-- Support -- see: func [ @@ -30,13 +32,32 @@ money: context [ money ] + get-sign: func [ + money [red-money!] + return: [integer!] + ][ + money/header and 4000h >> 14 + ] + get-amount: func [ money [red-money!] return: [byte-ptr!] ][ (as byte-ptr! money) + (size? money) - SIZE_BYTES ] - + + zero-amount?: func [ + amount [byte-ptr!] + return: [logic!] + ][ + loop SIZE_BYTES [ + unless null-byte = amount/value [return no] + amount: amount + 1 + ] + + yes + ] + make-at: func [ slot [red-value!] sign [integer!] @@ -81,7 +102,15 @@ money: context [ negative?: STUB zero?: STUB positive?: STUB - sign?: STUB + + sign?: func [ + money [red-money!] + return: [integer!] + ][ + either zero-amount? get-amount money [0][ + either as logic! get-sign money [-1][+1] + ] + ] ;-- Actions -- @@ -94,9 +123,29 @@ money: context [ arg [red-value!] part [integer!] return: [integer!] + /local + amount [byte-ptr!] + sign [integer!] ][ - see money - part + amount: get-amount money + sign: sign? money + + if sign < 0 [ + string/concatenate-literal buffer "-" + part: part - 1 + ] + + string/concatenate-literal buffer "$" + + loop SIZE_BYTES [ + string/concatenate-literal + buffer + string/byte-to-hex as integer! amount/value + + amount: amount + 1 + ] + + part - SIZE_DIGITS - 1 ] mold: func [ @@ -141,7 +190,7 @@ money: context [ null;:random null ;reflect null;:to - null;:form + :form :mold null ;eval-path null ;set-path From 219455abb3b53e00410e64f62187846f03478086 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 15:38:33 +0100 Subject: [PATCH 0949/3432] FEAT: implement sign-related predicates --- runtime/datatypes/money.reds | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a3092a6411..07a9b32699 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -99,9 +99,26 @@ money: context [ ;-- Natives -- - negative?: STUB - zero?: STUB - positive?: STUB + negative-money?: func [ + money [red-money!] + return: [logic!] + ][ + -1 = sign? money + ] + + zero-money?: func [ + money [red-money!] + return: [logic!] + ][ + 0 = sign? money + ] + + positive-money?: func [ + money [red-money!] + return: [logic!] + ][ + 1 = sign? money + ] sign?: func [ money [red-money!] From 9a3bca3fed90ea93ad5d78fbce1fb80c4cea09dc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 15:39:19 +0100 Subject: [PATCH 0950/3432] FEAT: add support for sign-related natives --- environment/natives.red | 8 ++++---- runtime/natives.reds | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index 2089faa594..313c9a366c 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -437,14 +437,14 @@ dehex: make native! [[ negative?: make native! [[ "Returns TRUE if the number is negative" - number [number! time!] + number [number! money! time!] ] #get-definition NAT_NEGATIVE? ] positive?: make native! [[ "Returns TRUE if the number is positive" - number [number! time!] + number [number! money! time!] ] #get-definition NAT_POSITIVE? ] @@ -559,7 +559,7 @@ NaN?: make native! [[ zero?: make native! [[ "Returns TRUE if the value is zero" - value [number! pair! time! char! tuple!] + value [number! money! pair! time! char! tuple!] return: [logic!] ] #get-definition NAT_ZERO? @@ -837,7 +837,7 @@ now: make native! [[ sign?: make native! [[ "Returns sign of N as 1, 0, or -1 (to use as a multiplier)" - number [number! time!] + number [number! money! time!] ] #get-definition NAT_SIGN? ] diff --git a/runtime/natives.reds b/runtime/natives.reds index 0fcdf48632..c952ebd81e 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1488,7 +1488,10 @@ natives: context [ ][ #typecheck -negative?- ;-- `negative?` would be replaced by lexer res: as red-logic! stack/arguments - switch TYPE_OF(res) [ ;@@ Add money! pair! + switch TYPE_OF(res) [ ;@@ Add pair! + TYPE_MONEY [ + res/value: money/negative-money? as red-money! res + ] TYPE_INTEGER [ num: as red-integer! res res/value: negative? num/value @@ -1513,7 +1516,10 @@ natives: context [ ][ #typecheck -positive?- ;-- `positive?` would be replaced by lexer res: as red-logic! stack/arguments - switch TYPE_OF(res) [ ;@@ Add money! pair! + switch TYPE_OF(res) [ ;@@ Add pair! + TYPE_MONEY [ + res/value: money/positive-money? as red-money! res + ] TYPE_INTEGER [ num: as red-integer! res res/value: positive? num/value @@ -1540,7 +1546,10 @@ natives: context [ #typecheck sign? res: stack/arguments ret: 0 - switch TYPE_OF(res) [ ;@@ Add money! pair! + switch TYPE_OF(res) [ ;@@ Add pair! + TYPE_MONEY [ + ret: money/sign? as red-money! stack/arguments + ] TYPE_INTEGER [ i: as red-integer! stack/arguments ret: case [ @@ -1750,6 +1759,9 @@ natives: context [ i: as red-integer! stack/arguments ret: as red-logic! i ret/value: switch TYPE_OF(i) [ + TYPE_MONEY [ + money/zero-money? as red-money! i + ] TYPE_INTEGER TYPE_CHAR [ i/value = 0 From 810db3a3fef30604976ea717512eca5779012dcf Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 15:59:17 +0100 Subject: [PATCH 0951/3432] FEAT: implement parity checking --- runtime/datatypes/money.reds | 42 ++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 07a9b32699..fef30798bc 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -22,6 +22,9 @@ money: context [ SIZE_DIGITS: SIZE_BYTES * 2 + #define HIGH_NIBBLE #"^(0F)" + #define LOW_NIBBLE #"^(F0)" + ;-- Support -- see: func [ @@ -58,6 +61,23 @@ money: context [ yes ] + get-digit: func [ + amount [byte-ptr!] + index [integer!] + return: [integer!] + /local + bit byte offset + [integer!] + ][ + bit: index and 1 + byte: index >>> 1 + bit + offset: either as logic! bit [4][0] + + as integer! amount/byte + and (HIGH_NIBBLE << offset) + >>> offset + ] + make-at: func [ slot [red-value!] sign [integer!] @@ -194,8 +214,22 @@ money: context [ round: STUB - even?: STUB - odd?: STUB + even?: func [ + money [red-money!] + return: [logic!] + ][ + not odd? money + ] + + odd?: func [ + money [red-money!] + return: [logic!] + /local + digit [integer!] + ][ + digit: get-digit get-amount money SIZE_DIGITS - SIZE_SCALE + as logic! digit and 1 + ] init: does [ datatype/register [ @@ -222,8 +256,8 @@ money: context [ null;:remainder null;:round null;:subtract - null;:even? - null;:odd? + :even? + :odd? ;-- Bitwise actions -- null ;and~ null ;complement From 325de8155215ba17e36f43645f0f7dbc0563061e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 15:59:56 +0100 Subject: [PATCH 0952/3432] FEAT: add support for parity-related actions --- environment/actions.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index 8694f4f741..fd7372ac9d 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -170,16 +170,16 @@ subtract: make action! [[ even?: make action! [[ "Returns true if the number is evenly divisible by 2" - number [number! char! time!] - return: [number! char! time!] + number [number! money! char! time!] + return: [logic!] ] #get-definition ACT_EVEN? ] odd?: make action! [[ "Returns true if the number has a remainder of 1 when divided by 2" - number [number! char! time!] - return: [number! char! time!] + number [number! money! char! time!] + return: [logic!] ] #get-definition ACT_ODD? ] From 1d288ec2c80f2701973cc4247abb50fe877b87f8 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 16:00:59 +0100 Subject: [PATCH 0953/3432] FIX: amend the specs of sign-related natives --- environment/natives.red | 3 +++ 1 file changed, 3 insertions(+) diff --git a/environment/natives.red b/environment/natives.red index 313c9a366c..acd3038cee 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -438,6 +438,7 @@ dehex: make native! [[ negative?: make native! [[ "Returns TRUE if the number is negative" number [number! money! time!] + return: [logic!] ] #get-definition NAT_NEGATIVE? ] @@ -445,6 +446,7 @@ negative?: make native! [[ positive?: make native! [[ "Returns TRUE if the number is positive" number [number! money! time!] + return: [logic!] ] #get-definition NAT_POSITIVE? ] @@ -838,6 +840,7 @@ now: make native! [[ sign?: make native! [[ "Returns sign of N as 1, 0, or -1 (to use as a multiplier)" number [number! money! time!] + return: [integer!] ] #get-definition NAT_SIGN? ] From 3515cecfa1e456bbfb5cb82b7c9c81836d4650c2 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 17:40:27 +0100 Subject: [PATCH 0954/3432] FEAT: implement ABSOLUTE and NEGATE actions --- environment/actions.red | 8 +++---- runtime/datatypes/money.reds | 44 +++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index fd7372ac9d..60d801a3c1 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -85,8 +85,8 @@ modify: make action! [[ absolute: make action! [[ "Returns the non-negative value" - value [number! char! pair! time!] - return: [number! char! pair! time!] + value [number! money! char! pair! time!] + return: [number! money! char! pair! time!] ] #get-definition ACT_ABSOLUTE ] @@ -120,8 +120,8 @@ multiply: make action! [[ negate: make action! [[ "Returns the opposite (additive inverse) value" - number [number! bitset! pair! time!] - return: [number! bitset! pair! time!] + number [number! money! bitset! pair! time!] + return: [number! money! bitset! pair! time!] ] #get-definition ACT_NEGATE ] diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index fef30798bc..570f035543 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -25,23 +25,40 @@ money: context [ #define HIGH_NIBBLE #"^(0F)" #define LOW_NIBBLE #"^(F0)" + #define SIGN_MASK 4000h + #define SIGN_OFFSET 14 + ;-- Support -- - see: func [ + get-sign: func [ money [red-money!] + return: [integer!] + ][ + money/header and SIGN_MASK >> SIGN_OFFSET + ] + + set-sign: func [ + money [red-money!] + sign [integer!] return: [red-money!] ][ - dump-memory get-amount money 1 1 + money/header: money/header + and (FFFFFFFFh - SIGN_MASK) + or (sign << SIGN_OFFSET) money ] - get-sign: func [ + flip-sign: func [ money [red-money!] - return: [integer!] + return: [red-money!] + /local + sign [integer!] ][ - money/header and 4000h >> 14 - ] + sign: as integer! not as logic! get-sign money + set-sign money sign + ] + get-amount: func [ money [red-money!] return: [byte-ptr!] @@ -89,7 +106,7 @@ money: context [ money [red-money!] ][ money: as red-money! slot - money/header: TYPE_MONEY or (sign << 14) + money/header: TYPE_MONEY or (sign << SIGN_OFFSET) money/amount1: amount1 money/amount2: amount2 money/amount3: amount3 @@ -203,8 +220,13 @@ money: context [ compare: STUB - absolute: STUB - negate: STUB + absolute: func [return: [red-money!]][ + set-sign as red-money! stack/arguments 0 + ] + + negate: func [return: [red-money!]][ + flip-sign as red-money! stack/arguments + ] add: STUB subtract: STUB @@ -247,11 +269,11 @@ money: context [ null ;set-path null;:compare ;-- Scalar actions -- - null;:absolute + :absolute null;:add null;:divide null;:multiply - null;:negate + :negate null ;power null;:remainder null;:round From e7748eb00f38d661ae9bcf5a32be760a6aff9267 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 17:53:01 +0100 Subject: [PATCH 0955/3432] FIX: minor formatting corrections --- runtime/datatypes/money.reds | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 570f035543..4dabadce66 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -45,18 +45,15 @@ money: context [ money/header: money/header and (FFFFFFFFh - SIGN_MASK) or (sign << SIGN_OFFSET) + money ] flip-sign: func [ money [red-money!] return: [red-money!] - /local - sign [integer!] ][ - sign: as integer! not as logic! get-sign money - set-sign money sign - + set-sign money as integer! not as logic! get-sign money ] get-amount: func [ From fc6d3486dddbd00045f543d52794d11fe2f00869 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 24 Feb 2020 21:01:43 +0100 Subject: [PATCH 0956/3432] FEAT: implement MAKE for integer case --- runtime/datatypes/money.reds | 93 +++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4dabadce66..f534fda48e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -74,7 +74,14 @@ money: context [ yes ] - + + zero-out: func [amount [byte-ptr!]][ + loop SIZE_BYTES [ + amount/value: null-byte + amount: amount + 1 + ] + ] + get-digit: func [ amount [byte-ptr!] index [integer!] @@ -91,6 +98,24 @@ money: context [ and (HIGH_NIBBLE << offset) >>> offset ] + + set-digit: func [ + amount [byte-ptr!] + index [integer!] + value [integer!] + /local + bit byte offset reverse + [integer!] + ][ + bit: index and 1 + byte: index >>> 1 + bit + offset: either as logic! bit [4][0] + reverse: either offset = 0 [4][0] + + amount/byte: amount/byte + and (HIGH_NIBBLE << reverse) + or as byte! (value << offset) + ] make-at: func [ slot [red-value!] @@ -130,6 +155,34 @@ money: context [ ][ make-at stack/push* sign amount1 amount2 amount3 ] + + from-integer: func [ + money [red-money!] + integer [integer!] + /local + amount + [byte-ptr!] + start index power digit + [integer!] + ][ + if integer = 0 [exit] + + set-sign money as integer! integer < 0 + + amount: get-amount money + start: SIZE_DIGITS - SIZE_SCALE + index: start + power: 0 + + loop 10 [ + power: as integer! pow 10.0 as float! start - index + digit: integer / power // 10 + + unless digit = 0 [set-digit amount index digit] + + index: index - 1 + ] + ] ;-- Natives -- @@ -162,11 +215,39 @@ money: context [ either as logic! get-sign money [-1][+1] ] ] - + ;-- Actions -- - make: STUB - to: STUB + make: func [ + proto [red-value!] + spec [red-value!] + type [integer!] + return: [red-money!] + /local + money [red-money!] + integer [red-integer!] + ][ + if TYPE_OF(spec) = TYPE_MONEY [return as red-money! spec] + + money: as red-money! proto + money/header: TYPE_MONEY + zero-out get-amount money + + switch TYPE_OF(spec) [ + TYPE_INTEGER [ + integer: as red-integer! spec + from-integer money integer/value + ] + TYPE_FLOAT [--NOT_IMPLEMENTED--] + default [ + fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] + ] + ] + + money + ] + + ;-- to: :make form: func [ money [red-money!] @@ -256,10 +337,10 @@ money: context [ TYPE_VALUE "money!" ;-- General actions -- - null;:make + :make null;:random null ;reflect - null;:to + :make :form :mold null ;eval-path From a0389193fe5fd070a92fcb7b0b1ca9740c661194 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Mon, 24 Feb 2020 21:06:45 +0100 Subject: [PATCH 0957/3432] FEAT: more changes to pass most of unit tests. --- quick-test/quick-test.red | 4 ++-- runtime/lexer.reds | 25 +++++++++++++++---------- tests/source/units/lexer-test.red | 3 ++- utils/generate-lexer-table.red | 4 +--- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/quick-test/quick-test.red b/quick-test/quick-test.red index 935b192d52..9ef6dd1811 100644 --- a/quick-test/quick-test.red +++ b/quick-test/quick-test.red @@ -94,10 +94,10 @@ qt-init-file: func [] [ --test--: func [ title [string!] ][ - if qt-verbose [ + ;if qt-verbose [ prin "--test-- " print title - ] + ;] qt-test-name: title qt-file-tests: qt-file-tests + 1 ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3bea4c1631..ac397ebad7 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -298,7 +298,6 @@ lexer: context [ scanned [integer!] ;-- type of first scanned value entry [integer!] ;-- entry state for the FSM prev [integer!] ;-- previous state before forced EOF transition - exit [integer!] ;-- exit state for the FSM closing [integer!] ;-- any-block! expected closing delimiter type mstr-s [byte-ptr!] ;-- multiline string saved start position mstr-nest [integer!] ;-- multiline string nested {} counting @@ -973,8 +972,7 @@ lexer: context [ either load? [ load-string lex lex/mstr-s e lex/mstr-flags or flags yes ][ - ;scan-string lex lex/mstr-s e lex/mstr-flags or flags no - 0 + scan-string lex lex/mstr-s e lex/mstr-flags or flags no ] lex/mstr-s: null lex/mstr-flags: 0 @@ -992,6 +990,7 @@ lexer: context [ scan-path-open: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local + slot [red-value!] type [integer!] ][ type: switch s/1 [ @@ -1001,9 +1000,14 @@ lexer: context [ ] open-block lex type s ;-- open a new path series if type <> TYPE_PATH [s: s + 1] - lex/exit: T_WORD ;-- load the head word lex/scanned: TYPE_WORD - load-word lex s e flags load? + if load? [ + load-word lex s e flags yes + if lex/fun-ptr <> null [ + slot: lex/tail - 1 + unless fire-event lex EVT_LOAD TYPE_OF(slot) slot s e [lex/tail: slot] + ] + ] lex/entry: S_PATH ;-- overwrites the S_START set by open-block lex/in-pos: e + 1 ;-- skip / ] @@ -1175,6 +1179,7 @@ lexer: context [ if cp = -1 [throw-error lex s e type] ] ] + lex/in-pos: e + 1 ;-- skip ending delimiter ] load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1824,6 +1829,7 @@ lexer: context [ ][ p: s err: hour: 0 + tm: 0.0 do-error: [throw-error lex s e TYPE_TIME] p: grab-integer p e flags :hour :err @@ -1846,7 +1852,6 @@ lexer: context [ tm: dtoa/to-float p e :err if any [err <> 0 tm < 0.0][do-error] ] - tm: (3600.0 * as-float hour) + (60.0 * as-float min) + tm if hour < 0 [tm: 0.0 - tm] if load? [time/make-at tm alloc-slot lex] @@ -1862,8 +1867,8 @@ lexer: context [ flags: flags and not C_FLAG_CARET ;-- clears caret flag lex/type: TYPE_TAG load-string lex s e flags yes - lex/in-pos: e + 1 ;-- skip ending delimiter ] + lex/in-pos: e + 1 ;-- skip ending delimiter ] load-url: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1974,7 +1979,6 @@ lexer: context [ lex/in-pos: p lex/line: line lex/nline: line - mark - lex/exit: state lex/prev: prev lex/type: -1 lex/scanned: as-integer type-table/state @@ -1988,9 +1992,10 @@ lexer: context [ load?: any [not one? ld?] do-scan: as scanner! scanners/index either state < T_INTEGER [ - catch LEX_ERR [do-scan lex s p flags no] + catch LEX_ERR [do-scan lex s p flags ld?] ][ if any [not lex/load? lex/fun-ptr = null][ + if any [not ld? lex/fun-ptr = null][ if :do-scan = null [do-scan: as scanner! loaders/index] catch LEX_ERR [do-scan lex s p flags no] if lex/fun-ptr <> null [ @@ -2026,7 +2031,7 @@ lexer: context [ lex/tail = lex/buffer all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT] ][ - lex/in-pos: lex/in-pos + as-integer ending-skip/index + ;lex/in-pos: lex/in-pos + as-integer ending-skip/index exit ;-- early exit for single value request ] ] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 29db931f29..f351651ea3 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -398,7 +398,7 @@ Red [ a/"hi" a/"hi"/456 a/2x3 a/2x3/456 a/2x3/c a/1.234 a/1.234/c a/#"b" a/#"b"/c ] - forall p [ + forall p [ --assert p/1 == transcode/one mold p/1 --assert (to set-path! p/1) == transcode/one mold to set-path! p/1 --assert (to get-path! p/1) == transcode/one mold to get-path! p/1 @@ -559,6 +559,7 @@ Red [ [load error] t: tail logs reduce/into [event to-word type to-word type? type line token] tail logs + print t new-line t yes any [event <> 'error all [input: next input false]] ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index a5c245aa6b..ed345d7d66 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -143,9 +143,7 @@ context [ list: skip find states '--EXIT_STATES-- 2 foreach [s t] list [ - append ending-table pick 1x0 to-logic find [ - T_STRING T_BINARY T_PERCENT T_TAG - ] s + append ending-table pick 1x0 to-logic find [T_STRING T_TAG] s ] template: compose/deep [Red/System [ From 6a7e77d773c2b0ac71c076c7fb1ce5b439bdf01a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 11:55:29 +0100 Subject: [PATCH 0958/3432] FIX: fixes almost all remaining non-passing tests. --- quick-test/quick-test.red | 4 ++-- runtime/lexer.reds | 33 +++++++++++++++++++------------ tests/source/units/lexer-test.red | 1 - 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/quick-test/quick-test.red b/quick-test/quick-test.red index 9ef6dd1811..935b192d52 100644 --- a/quick-test/quick-test.red +++ b/quick-test/quick-test.red @@ -94,10 +94,10 @@ qt-init-file: func [] [ --test--: func [ title [string!] ][ - ;if qt-verbose [ + if qt-verbose [ prin "--test-- " print title - ;] + ] qt-test-name: title qt-file-tests: qt-file-tests + 1 ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ac397ebad7..80b36265fa 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1002,6 +1002,7 @@ lexer: context [ if type <> TYPE_PATH [s: s + 1] lex/scanned: TYPE_WORD if load? [ + flags: flags and not C_FLAG_COLON load-word lex s e flags yes if lex/fun-ptr <> null [ slot: lex/tail - 1 @@ -1432,9 +1433,21 @@ lexer: context [ p pos [byte-ptr!] cell [cell!] ][ - type: lex/scanned - assert type > 0 - + either lex/scanned > 0 [type: lex/scanned][ + type: TYPE_WORD + if flags and C_FLAG_COLON <> 0 [ + case [ + s/1 = #":" [type: TYPE_GET_WORD] + e/0 = #":" [type: TYPE_SET_WORD] + all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path + true [throw-error lex s e type] + ] + ] + if s/1 = #"'" [ + if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] + type: TYPE_LIT_WORD + ] + ] if type <> TYPE_WORD [ switch type [ TYPE_ISSUE @@ -1453,7 +1466,7 @@ lexer: context [ word/make-at symbol/make-alt-utf8 s as-integer e - s cell set-type cell type ] - if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter + if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1994,22 +2007,16 @@ lexer: context [ either state < T_INTEGER [ catch LEX_ERR [do-scan lex s p flags ld?] ][ - if any [not lex/load? lex/fun-ptr = null][ - if any [not ld? lex/fun-ptr = null][ + if any [not ld? lex/fun-ptr = null lex/fun-evts and EVT_SCAN <> 0][ if :do-scan = null [do-scan: as scanner! loaders/index] catch LEX_ERR [do-scan lex s p flags no] if lex/fun-ptr <> null [ - index: either zero? lex/scanned [0 - index][lex/scanned] - load?: fire-event lex EVT_SCAN index null s lex/in-pos + idx: either zero? lex/scanned [0 - index][lex/scanned] + load?: fire-event lex EVT_SCAN idx null s lex/in-pos ] ] ] - ;load?: either lex/fun-ptr = null [any [not one? ld?]][ - ; index: either zero? lex/scanned [0 - index][lex/scanned] - ; either state >= T_INTEGER [fire-event lex EVT_SCAN index null s lex/in-pos][yes] - ;] if load? [ ;-- Loading stage -- - index: lex/exit - --EXIT_STATES-- do-load: as loader! loaders/index if :do-load <> null [ catch LEX_ERR [do-load lex s p flags yes] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index f351651ea3..7c33bc4036 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -559,7 +559,6 @@ Red [ [load error] t: tail logs reduce/into [event to-word type to-word type? type line token] tail logs - print t new-line t yes any [event <> 'error all [input: next input false]] ] From d748bd11a33b152eef659be5d3cb70b459504f66 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 12:32:30 +0100 Subject: [PATCH 0959/3432] FIX: set callback event bitmap to zero when not used. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 80b36265fa..81bc14cf85 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -2100,6 +2100,7 @@ lexer: context [ lex/mstr-flags: 0 lex/fun-ptr: fun lex/fun-locs: 0 + lex/fun-evts: 0 lex/in-series: ser lex/load?: all [scan? load?] From 4d14076c8477c9f4d1845ae1089178fd0e6268dd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 12:44:54 +0100 Subject: [PATCH 0960/3432] FIX: take sign into account during conversion --- runtime/datatypes/money.reds | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index f534fda48e..16fd366117 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -28,6 +28,8 @@ money: context [ #define SIGN_MASK 4000h #define SIGN_OFFSET 14 + #define MAX_INT_DIGITS 10 + ;-- Support -- get-sign: func [ @@ -158,30 +160,33 @@ money: context [ from-integer: func [ money [red-money!] - integer [integer!] + int [integer!] + return: [red-money!] /local amount [byte-ptr!] start index power digit [integer!] ][ - if integer = 0 [exit] + if int = 0 [return money] + + set-sign money as integer! int < 0 + int: integer/abs int - set-sign money as integer! integer < 0 - amount: get-amount money start: SIZE_DIGITS - SIZE_SCALE index: start - power: 0 - loop 10 [ + loop MAX_INT_DIGITS [ power: as integer! pow 10.0 as float! start - index - digit: integer / power // 10 + digit: int / power // 10 unless digit = 0 [set-digit amount index digit] index: index - 1 ] + + money ] ;-- Natives -- From 5860d83033ae3f4be605d7ae6a4cc24e662532f4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 13:32:30 +0100 Subject: [PATCH 0961/3432] FIX: more robust integer conversion --- runtime/datatypes/money.reds | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 16fd366117..6482e3b387 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -165,27 +165,35 @@ money: context [ /local amount [byte-ptr!] - start index power digit + extra start index power digit [integer!] - ][ + ][ + amount: get-amount money + + zero-out amount if int = 0 [return money] set-sign money as integer! int < 0 - int: integer/abs int - amount: get-amount money - start: SIZE_DIGITS - SIZE_SCALE - index: start + extra: as integer! int = (1 << 31) + int: integer/abs int + extra + + start: SIZE_DIGITS - SIZE_SCALE + index: start loop MAX_INT_DIGITS [ power: as integer! pow 10.0 as float! start - index digit: int / power // 10 - unless digit = 0 [set-digit amount index digit] + unless zero? digit [set-digit amount index digit] index: index - 1 ] + unless zero? extra [ + set-digit amount start extra + get-digit amount start + ] + money ] @@ -236,7 +244,6 @@ money: context [ money: as red-money! proto money/header: TYPE_MONEY - zero-out get-amount money switch TYPE_OF(spec) [ TYPE_INTEGER [ From d92f96d9314fb74a7707dd3a95aaa4af7311ef74 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 13:48:34 +0100 Subject: [PATCH 0962/3432] FEAT: minor refactoring --- runtime/datatypes/money.reds | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 6482e3b387..65c24c5acb 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -77,11 +77,13 @@ money: context [ yes ] - zero-out: func [amount [byte-ptr!]][ - loop SIZE_BYTES [ - amount/value: null-byte - amount: amount + 1 - ] + zero-out: func [ + money [red-money!] + all? [logic!] + ][ + money/amount1: either all? [0][money/amount1 and FF000000h] + money/amount2: 0 + money/amount3: 0 ] get-digit: func [ @@ -168,9 +170,7 @@ money: context [ extra start index power digit [integer!] ][ - amount: get-amount money - - zero-out amount + zero-out money yes if int = 0 [return money] set-sign money as integer! int < 0 @@ -178,8 +178,9 @@ money: context [ extra: as integer! int = (1 << 31) int: integer/abs int + extra - start: SIZE_DIGITS - SIZE_SCALE - index: start + amount: get-amount money + start: SIZE_DIGITS - SIZE_SCALE + index: start loop MAX_INT_DIGITS [ power: as integer! pow 10.0 as float! start - index From a47e00646a50eec5854ca1689797cc7c13ca3d40 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 14:05:38 +0100 Subject: [PATCH 0963/3432] FEAT: some extra refactoring --- runtime/datatypes/money.reds | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 65c24c5acb..f73349889d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -20,7 +20,8 @@ money: context [ SIZE_SCALE: 05 ] - SIZE_DIGITS: SIZE_BYTES * 2 + SIZE_DIGITS: SIZE_BYTES * 2 + SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE #define HIGH_NIBBLE #"^(0F)" #define LOW_NIBBLE #"^(F0)" @@ -45,7 +46,7 @@ money: context [ return: [red-money!] ][ money/header: money/header - and (FFFFFFFFh - SIGN_MASK) + and (not SIGN_MASK) or (sign << SIGN_OFFSET) money @@ -249,7 +250,7 @@ money: context [ switch TYPE_OF(spec) [ TYPE_INTEGER [ integer: as red-integer! spec - from-integer money integer/value + money: from-integer money integer/value ] TYPE_FLOAT [--NOT_IMPLEMENTED--] default [ @@ -340,7 +341,7 @@ money: context [ /local digit [integer!] ][ - digit: get-digit get-amount money SIZE_DIGITS - SIZE_SCALE + digit: get-digit get-amount money SIZE_INTEGRAL as logic! digit and 1 ] From d8ad554549f3928bb9d81803659f15bd52474349 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 15:32:39 +0100 Subject: [PATCH 0964/3432] FIX: more post-refactoring fixes and improvements. --- runtime/lexer.reds | 54 ++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 81bc14cf85..60fbbd9101 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1130,22 +1130,6 @@ lexer: context [ if s = e [throw-error lex s - 1 e TYPE_ISSUE] ] - scan-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ - case [ - s + 1 = e [lex/scanned: TYPE_WORD] - s + 2 = e [ - case [ - s/1 = #"'" [lex/scanned: TYPE_LIT_WORD] - s/1 = #":" [lex/scanned: TYPE_GET_WORD] - e/0 = #":" [lex/scanned: TYPE_SET_WORD] - true [0] - ] - ] - s/1 <> #"/" [throw-error lex s e TYPE_REFINEMENT] - true [0] - ] - ] - scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local len unit cp type [integer!] @@ -1468,6 +1452,23 @@ lexer: context [ ] if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] + + load-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ + case [ + s + 1 = e [lex/scanned: TYPE_WORD] + s + 2 = e [ + case [ + s/1 = #"'" [lex/scanned: TYPE_LIT_WORD] + s/1 = #":" [lex/scanned: TYPE_GET_WORD] + e/0 = #":" [lex/scanned: TYPE_SET_WORD] + true [0] + ] + ] + s/1 <> #"/" [throw-error lex s e TYPE_REFINEMENT] + true [0] + ] + if load? [load-word lex s e flags yes] + ] load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local @@ -1480,14 +1481,14 @@ lexer: context [ ] lex/type: TYPE_FILE either load? [ - scan-string lex s e flags no - ][ load-string lex s e flags yes if s/1 = #"^"" [ if e/1 <> #"^"" [throw-error lex s e TYPE_FILE] e: e + 1 ] lex/in-pos: e ;-- reset the input position to delimiter byte + ][ + scan-string lex s e flags no ] ] @@ -1893,10 +1894,10 @@ lexer: context [ if p < e [flags: flags or C_FLAG_ESC_HEX or C_FLAG_CARET] lex/type: TYPE_URL either load? [ - scan-string lex s - 1 e flags no - ][ load-string lex s - 1 e flags yes ;-- compensate for lack of starting delimiter lex/in-pos: e ;-- reset the input position to delimiter byte + ][ + scan-string lex s - 1 e flags no ] ] @@ -1947,7 +1948,7 @@ lexer: context [ pscan? [logic!] ;-- prescan only /local cp class index state prev flags line mark offset idx [integer!] - term? load? ld? scan? [logic!] + term? load? ld? scan? events? [logic!] p e start s [byte-ptr!] slot [cell!] do-scan [scanner!] @@ -1955,6 +1956,7 @@ lexer: context [ ][ line: 1 ld?: lex/load? + events?: lex/fun-ptr <> null until [ flags: 0 ;-- Pre-scanning stage -- term?: no @@ -1997,7 +1999,7 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- - scan?: either lex/fun-ptr = null [not pscan?][ + scan?: either not events? [not pscan?][ idx: either zero? lex/scanned [0 - index][lex/scanned] fire-event lex EVT_PRESCAN idx null s lex/in-pos ] @@ -2007,10 +2009,10 @@ lexer: context [ either state < T_INTEGER [ catch LEX_ERR [do-scan lex s p flags ld?] ][ - if any [not ld? lex/fun-ptr = null lex/fun-evts and EVT_SCAN <> 0][ + if any [not ld? all [events? lex/fun-evts and EVT_SCAN <> 0]][ if :do-scan = null [do-scan: as scanner! loaders/index] catch LEX_ERR [do-scan lex s p flags no] - if lex/fun-ptr <> null [ + if events? [ idx: either zero? lex/scanned [0 - index][lex/scanned] load?: fire-event lex EVT_SCAN idx null s lex/in-pos ] @@ -2020,7 +2022,7 @@ lexer: context [ do-load: as loader! loaders/index if :do-load <> null [ catch LEX_ERR [do-load lex s p flags yes] - if lex/fun-ptr <> null [ + if events? [ slot: lex/tail - 1 unless fire-event lex EVT_LOAD TYPE_OF(slot) slot s lex/in-pos [lex/tail: slot] ] @@ -2227,7 +2229,7 @@ lexer: context [ :scan-comment null ;-- T_CMT null :load-integer ;-- T_INTEGER :scan-word :load-word ;-- T_WORD - :scan-refinement :load-word ;-- T_REFINE + null :load-refinement ;-- T_REFINE null :load-char ;-- T_CHAR :scan-issue :load-word ;-- T_ISSUE :scan-string :load-string ;-- T_STRING From 2f1f5a13c3c4cf6137d565ef7a57bec945a4e9e1 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 15:37:57 +0100 Subject: [PATCH 0965/3432] FIX: correct typos --- runtime/stack.reds | 6 +++--- system/runtime/common.reds | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/stack.reds b/runtime/stack.reds index 98ff84999e..6baf001168 100644 --- a/runtime/stack.reds +++ b/runtime/stack.reds @@ -65,9 +65,9 @@ stack: context [ ;-- call stack ;-- header flags #enum flags! [ FLAG_INTERPRET: 80000000h ;-- Called from interpreter - FLAG_THROW_ATR: 40000000h ;-- Throw function attribut - FLAG_CATCH_ATR: 20000000h ;-- Catch function attribut - FLAG_IN_FUNC: 10000000h ;-- Inside of a function body (volative flag) + FLAG_THROW_ATR: 40000000h ;-- Throw function attribute + FLAG_CATCH_ATR: 20000000h ;-- Catch function attribute + FLAG_IN_FUNC: 10000000h ;-- Inside of a function body (volatile flag) FRAME_FUNCTION: 01000000h ;-- function! call FRAME_NATIVE: 02000000h ;-- native! or action! call diff --git a/system/runtime/common.reds b/system/runtime/common.reds index 7ebcd96eb1..4014b8f718 100644 --- a/system/runtime/common.reds +++ b/system/runtime/common.reds @@ -53,7 +53,7 @@ Red/System [ #define write-io32 [system/io/write as int-ptr!] -#define type-logic! 1 ;-- type ID list for 'typeinfo attribut +#define type-logic! 1 ;-- type ID list for 'typed' attribute #define type-integer! 2 #define type-byte! 3 #define type-float32! 4 From 52ebe4a9b94427c49e195cd3edcfc11885de58d0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 17:06:02 +0100 Subject: [PATCH 0966/3432] FEAT: make opening angle bracket a stricter delimiter. Solves the "<a > 3" ambiguous patterns. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 21400 -> 21387 bytes runtime/lexer-transitions.reds | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 2990150714..b3dd17ea17 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -37,7 +37,7 @@ S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MO S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_WORD;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_LESSER;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR @@ -45,7 +45,7 @@ S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index bc50ef2fce185806f476c52cd4a82aa94932fd85..5c1733092349ce45c0304b3f5e6f2333602fe16a 100644 GIT binary patch delta 8890 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%0DGv24|tV` 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 Pux^GTEVlY|;Me~F>ZS`U delta 8881 zcmZ`<c|4SR`?i%9Oj)BMOB{r;C1ND9jD0L)36mHxamp6LLyCx`u?(^s+YFOESvy71 zAj?qJ$Pz-<L6+Y$&U-qi_dUP)<7*xtpU>RS{ap8TU)N<G<<sNx>7S4C9TwfiYCb<p zN7r5cl`oDSSi1GYJ#goT=G@lGG{nVg6SB#>IlsQ{uqnyxXy1Bfw4}klal>WJ@G)U4 z``h-nX3E=$RKTJ0LC}RC^Xp?{>-zSqOV8Bb0b4r@>w6`QFr(Sq-vVFyx683z`NN>> z)q`(YKlXUoB=&fevy+S?%(th#{f6JF$u-_xn%SZf8UdL4x!?B|97ea7Tws%rGNhd; zE6sbGJ?iswKVm)mCO-rR1SR+H`2DbsdgtH}SkqcfdR9r;Q{CNJOf`l8ZR(MMD_h%k zU#_+dsc&O5+Nxb-f@>RquPtXcH~Q;Otx0cLDfVL5{E1W>Zl&!#>I2W`@2;E^0%EU> z?5wVDw*!-@f$)~k%YXoLQlmQS?yAa#_0)<po+1>Xmd~up6VKzDuLFCtx4UnBZ|RA9 zAATmMktKiSHmQQdUlP1Cxv;*-)6G3mH}bv&E84T6JZg8_r7jNdzp*m)r7@-Y+MWJy zSpCDV-qvX+@@(E(pITy?-pk_M)wKWe`cwULU~dc9T24yZOFX?L+mL6WITEi|8(t@c zHDdKgiVpKFHy8w1crFzgY$@iNiiSz}dzp&9mhca<7tP^YereF6sKu&K`1Gjahl=om zP&9ZIucV{A)+`^C)v=ll=Oe{i_u;}*+KW00W{7jqd>AvA-oC*;-b$*kg;!SFH_XE# zPe_5F8?ylB;lL~FXw;Ib0`?C7O$JOCc9Q=AeONh0K$9N82l6j{EFs#*Qzj5QPAQ>R z(XzNH6WL^64u~1-8r<;e!ZTG;<h0B=rQ1Gl+RqTfTsL#)v5$>k!e%ye7qOwn;V|A! zr*GIu<2+dMrqcrUfpH?tdednh8)IAr`?Tq_hz&D-3~QA`UE-HN_KrnFjxmmWNmTw= z8%wSnW2rIulC=CWGK+}(qb}91%-7Q~vZ>943Nz&Rvh4gyir?-Z+nNi17&FZVTgX3g z<UwXnMpa3wlze@eJss5`d9dWfK~q&p%EfUX?VSxdU!4@}nxHUHM~=0ha*<hiowPag zetW|?cvnt6#M%H=DqL@ol>X_RgFWpsa~S_xSIl4rVcVdzS|^>>_&l(%81jNw_qL&T zlJAv4uG2_wyDqOQqg;$g7CTwb=8s$)NCP`rujV1HqsVi1rJl_LTqlt??Ml6xN4S`g zr|jaKVM}I7mB6+{@PeGWUvkF(7E*SiiKAV~UOPhGqz-k_hc^wdsF}jt+pX4L=1DwR zu~qPrSL-(W?>=GcdKaHKCLu>#XI^B_L3&p7M#UI2Sc2r1TQ58rFRDZG3}Pirk1F{z zlQUX}q{?nJcXLT1iFT#8oBIH+i^y+ww{JCfaam7cagF2rrYFx}HZ2@?iJUI7p?Q(K z6=)9m8*w;|M{ihcM9?3EWW%@%TQluPaT>MA2(Md?OK_f^<+D$w*JigLOxhQt2UxNd z4pTa8VXn-M=WO0`*#Wq8<1HBPhSOJUoN-I2RVs@8Vd*V1BzZfTJPZi^zwL?Kl=KLp z&Rz_+W<hlofYpRpMwg$^=y`L@Mzi^tjYv3H%YE)h!3tfLtSgR(q}VlYOe#E*RW0?y zqtixF!S>a`fzCB{bL}6ZTP~z08V@K=)Nf_qV8(eU^mVU=%rMH+p$}mNM7RL9p1aps z$p>*#(ApbBwJPQ*I`Z)o{!lT<Mua@(@-m9;l6WB+A8)~df1dI%*CM@xo<q#PT^A+) z)XE>mOpbIqFPxR2<4qoGYquXcp8o0E3bF`Ivbj}$+(0&JHmz|ITV<>Qo6&Zhf6fmL zLLF>k3FW1iKZs@^bK-cRUI2=_>0GGw6|*4+ilxJF*uYJ<*@B>#YprZ#KM0u~Ck*ZW z`Z~+j)}Bx8k~khL#Eb)<oAS`ff=>;1L64viU=le2zAw;XmyF>zhbMDwt)5=09$gHM zKUsf&A~^;I;N4bd6Wzgb#2>a*gt#*H(B~aBfZ$+IMpSrHG!Vk8<28Oi!bM&qO<Z znrb>1V$D#_fc~>57g6g?r$Uq&gy%;fSrvCfbj>H@?wUm2x8Q%toS=JkvJ|{vvMia? zILrR&oU`SunxgAYTvEjk=(Ei#9O5oR!eD(SqL$=8ZXZnO=ppI1`q#WA)cUn=C%ri& zUdith2lO)Joi@C!+-q_=!~2!48fvSFC4`qjo&n857U8>oAphUUf^uv#2r)V8@tmX) zbt=$vHBw>i*u^hS`o>hls5}d?D?L#!wz;_)A-XzLm-unl_TQR&<iyhx^_D6OqVk;) zs#4f-amnw!iv)-VFhH>KnA}{^X#V}>g<@4zBN2gNRaS>jjqTgjJ~QZ&#&HINiz(v) zUq^L5fQ@UJrSD-z(~*zijzh1bM7ykhIP=9+cKlD@YWd6#w=^7_VGW|2IuyOS{^ar; z5$*+fH^6WG$Q*u6s`3t3fa_wg%M)OoO*DPk%}Dh?-_?8ZRvh?uDZe@QX^B^e3Kb@t zT$*xBtPR{X`3Uje{LW%s`X1@gz>H8C9tD(}zSQ5de62KpBkFyZiNn|;T~D$6tj4;% zLSOofj+u(I56P8omIX7F(-wUx`L-eNT57ncq88~hh&o)ysa|WkawhZvG9Q3rh1#Ng zo4$oAYh9oJ1BBaW%{t=c?$3;6%V$|ZMCnPL)jVs@S0~`_`W<B?PMmsUW@8vX?w0+s zZkDr^)epM#@|~pw{zJ;NG=BX}RMN@7-EXF)uilPg=74MU$J1>j)&nR7DRG=UCUM{# z!e%ydPexYW`s+ah@=<x-{1nLQbrY9AM`Gnhv{%FT)^0J$3}R5(Qfr^s#f)#lrR$^n z!!SnZlrH+L7p9b<!UAc?^|L8Yv|XTdjTAg$1?#)Oj@Z1<We%5BtjY>(I&viL8603v zKp=|6<8s^9YL#tj>ZgsR)kyUbF6mM8b{V~BAZN=d<$N(;PL*SA_*c2psFzKv|Dgx+ zA)G9f1C`fA4oPM#r$ZkmAHgX?Pok=tzJ+{Z^rAi3iU9Sn?m7A*{i4TNtKcZ!w~(F! zM*+F%$7L=Qnh=WwFRW=7@GQkqJ2SUOJfZpgF!za0m>Ov?B0n!`7_hGoQxbTT1dNpl zNo7<7bua1li>YO-2FZPI{U9cs5iKm9K3P56_vwv{{8}qn%q!zuVA*PGn;0hJW?<P` zYlqm~jQtVtUYo_{O5E)34Ps;$ml`H9%89drCqjIFh{WhA-d<;;GwRFG8gFS|oYQ$F zDzB$iGmC>)=9ELVzF06?tkc1Iw<B6*7A^c_93nIuVgqyik&FE-AZwi)S8I*cUO0J7 z*L5QJ^fA5t6TW}y@1F+XnZ{|D9~W_1%%m_bV;Z8SHurRUDPdB3#6-a0e2%!Ur@Kv4 zMd%D&&w)H1!x=l1`khscH0*5|QD6chbfi<!Mv$zFnCui{NYJ&MG!_Pb*pzc3SH9}n z%d>xs7CA2**RG2$=N#ZjQ{7!By}*f?)C}v}-bL4TIus7nZ^86eRB?zoa~`S`YM?8= zqmYllXuuOqVa$V&>2QKjVN^?#L3U~1ts`U>oHFz%DzS+eV$E1ik47IQv*FaB%&5mr zy0s9&3ZpuZ<PhfVaB+g=6n;2j%pktojV%d;dpwc@-<0y(S#UPXMB&Mbrbp%@jnW6| zYjBgkGOrT`>UYj=tUM#|lNx3RqVxPDMhoBXazp2Dz~{1BX0d{j96%JNV4>9*^KkdI zl8cXa&_NhUezrKs)TK8t(P!$a+Og^)%`M2XeZSyNP=%qEWoA|7gI>!ailEQUyU>q< ze3CF76P<y;cSSx<-BXMbF?rIt6GgDhap{13HizAZT`6#h_3kM`!fJ+nDp=`j{F@Y= zBq2<8{HO6-tUlutKoQJfh!~H+WOLeb;D^9lsrFuIAo<m_>*EorZylbhf*4rX*cwvG z5jULpLDD}o`j8pq<{5(m6>uz2#9!7IyP+$q1@##yBRk4(5Kmtq5zJgSukBg+B%+8G z!&a2X0tY1pwyC<R3vXCYxF01;^8uLtMU6DZ0xu??+_4|}QmpEk-9!SbfH~Y%$^ucV z%LglnUzS*%>1u1krining-0ryMiC<sXv6r+;9b~o;6JAPHn~qR!Mpd(mrClr>;(7= zo*ExW@3^Fy_I}ELEsJo6w&HZmjuaNr*4!^_4bbR%&>4h4v|?<YcY}l->>DcvrVq`a z)hi9wYp9#^XRRq5$#(;FK82|;n@k^?)lH%%*}M!iv?SPpeCS%)LG<37<t?lslCr}C zxV1d`!j!>Yd%@!rP20eFZy16-7GfVf2iE#n^3LXVAyMG#@|d7h2_mWgmFrZeVe5gt z$gwZYb-xdkK2Gjt)3Af){My@?%3|y_X>Q>9{FYjQ7oE@J%*Pd*$7JW;=%+FlTrq(Y zl&{*^U<OoiW>MhVHo_;33C&N?^kM|Mo!;y}pKt5BdTmN<{c26uG{j)%QVygOnZQ@y zu<}V2^7YO4(ykwQr|060LimZACOqT<W&;5nJya8=-4q>~taaU;0BQj!(6_%QqVv3` z2-UN%xy#sY+97p;L#6cc15Yp4J|xC8GKZbMlqOstTtDI<G_$5?O0@3|gNr}!<Bikb zGAZ=)zyt(wQLc7_9eT$df%&R$2L90(3-hRA|3L9-QTQvx<9a2lThJAbyCp+&E6k** z`t(r(B=%;)K*LKaFsKTddZXpoPc=N*JJX8`-}QA#%H-Dwx_6L?^)TOY1<@Pqrv58Q zfc$toXUcH}<{YViYM0s@QMHX_!c?Zyhg9x~>ro-D<sA*)du}3<97zzj$f8FcmE1>2 zftE)_W4lxF8!2;7#xX*i4x4PExPUg2vV9vs+B`pY0F)9>)Lqu<szbitx15o>H0*>) zM`nx%<d2Agq?RLI9P{sNQ`G^k+7lSI*<S<|SX7L|;^tqE)qCgIW$>}~GyislLX0nS z%jUG?z*pE5CJk<&##O{gQ@4JZ1g*=G$Zd3zRP|lg{?41!P09D89bKb#Zt2Ws16xIg z)ims@EY03UU|Ync0j=xKH2D6-YwCrbF%Stn(PkylRu%Ok-qLGaq{K4_BAU*CVbfuk zOrl=9P>#(fgVgaMB>~}PO!O-pZVX=MsEj3<&)Ww<YI$Q62lqKmKPTOD9%S?De@W?o z+m*nt%hDk6xYpB@xB@hdTFb%vjH^J4l<>A<v>8(4-k?Rwcw293Urtpn1n<t@*l&cg zGq;^kG)&+giq2bY$SG;F1-o537=(*;{vR@mNq8;}1$oFPJxt{%y94wfyG!$7I)Bp6 za0JRq45qIK5=&7e!m{{Fk}qTmB=~s+S867rji9{52`aERDZgC-S-xCUC@aBNAn`LO zY6k1iP00@i?ZPPw6rSQ#QdlWl;Q^X1j8sQL+Pp(%?v(~Kt%mZ_$upsu$R}`zp=KyF zc2t}Xs28~GN~Mb{XrrhVn4h%VSv&L8(v=E!ADLwgVVT(#L{hV!M(R3F&hmp^!m?yR z<E&UExKWBXlILN7bItJF*_#b)v<7%=(5UTtS|l6P4r=*Rz=!ZM%15>Y%%w5NGhT1k zNIL-4M_G1R?VFnDO5gyRC#G_mn%P0$t9(zTdqMM1F^9}Ne<r6zIijt|XWP?9AY3x7 z!mXC1F)L&|poa7Nw>A*&77C_q&>9i68#qwjki4Rz`bjhc9tgZOZ`8`+jq%al-@LvN z!Ed;6(kBRi@d*|u%#MwaIR@kohv}H;Atp!E3P6}U+Yf-2rCVa2-(1K)fdHBak^NhL zYFz{Rif6rv;O9K-TNw!QdqL=3usG_`P~uN#F#O$>zUOg^2ld*y_uj9p{*sXUUV#bc zs?f*RaVgDT!E%C!W~u1Q526{#+&DW0JVxrqFFk+~v0&fn@C6{u|3pE!zN^%{_L`!{ zzXAbNZ>Dhf+s(#1OJ<~%{EGDch1V-~cwdr{_Dbo?Em=+X9okqBIY#NR$K<#H|AVvS zoKoKz2HaVwB&x6JX2>Uo@<(|m8t%CL6O5TQVwwY>tt+DW%ef8waM&2arhN=?)i8b; zWP*P}@n;29Kei7)pRWAz{hL+ku+l2yTzfw~m&>x{@Di;zc^@Mr!hC>3v-i4w!K0o+ z-&C@;+0~i;+3*=+OC8e1$NsuEh?VzzJr|JbS4!NT@ZYq%E@6AaEX+I0J*JRz;EMUs z#v-MCCMc$B>_RU~o|re2c1rM?sj;1IO7Nw=gK@ShboeIjSO<Yrg`L@FMUAMegBGIc z?6yOdKmhh#zbxUkg#@0=EootLq&O1cW*F~?5qfG{6DII@0R+<TGZUT8T&WE^sj?0c zZ(qRE>`5N-+2h}1!ng9!k1~C=`ksPg_4HK$)7oLaV+tZSv_9Z6^|UP0^Si9xs}W== z;R3#q7A~e{IuV$E2=i=lk6kyQngnC9KKzcJ#g|EYpdL7%JIw6l4gu#7tcNGl^H%pF z0b4XfwaBGD9O@|)8ji~yMVjIfQN@++lXD;wL={_$H}`3YRCO=Der6=)Uo)n^xEmLq zv9jFn$+wkcqv*iw?Y8|L<9*0Y$I1OQIFNEyv6(Op#(UvRF^Bj74u!~fHf{f6r$P2l zZ5;Tnafwawfke#8A+*S8brzSjfSC=t%0uuhsgg_1<K0WI{hED|Jxi~05gz&py|JO) zOB(oiTdypHhhe-YD1~e};)dXFAv$;5TJ=xwT~<e79LCj`J>RM$8_#6%8s28}+Yz=q zit|;#%NO$Z?~70DqVz%FCp|O~LqE}#A3!sc`Ei;tT}jzGsIutHcyr7hC-EXtxOJsm z2AFpIhNqm8Zl-97lSJX6QbP5gt>HJ1rxA?ee|prZiyH9x$mVlYKMnO;7C@XA<qM_j zd`{`(oC5|YabR0e|3KjjprasyPt->{jpUkUsx*xD(Wd;nuR38UJG|Jt`IKMap4$Vc zuwDW`L?Vs|j|CG48+rEr=m|yPQ1Ex6Mnb6+wB_V)`dK~!fw-Q-<_k+@M}u?UPG4Q~ zqaagwUd2}>$$`Ao1R{x{hY|SO4ftr!C+Ve`PCNdOA^3+Mh^1=&rpAAUof7S25ukeF zaV~fkXe~>qfut3gFz07dc)naBw)=}Fo@4&UQp=r0THbNDE>mD;Ng1hTZ>Omsb1yD3 z80dy4b3@%xDnOHW=*%ziL6gB;bN~rQ;q@_^{(o{8H86Ks^#gMk{M#_N2$5Hhu<8dr z)e4?8&ZHG2C#eQAf7%FB{Lq&1Hg&&-z+H3hy|(r%eh>9MHq=>xk_P#qXl)=k(NB)@ zV=3#g^FXQ5QvGEhwj8uc<ov(L`cLua<tV0V&u$Q!e8o(aXRB)R6mEZ|{EZnHxKahO zOFR0HN1s)LF_BfSb$?+j)5hLa1b1kW&rQ$MpvtJ=78~)yON-^Uh9ShCHzNXi-~bl1 z;!f=kK=Tx#p9Lzv;;Zi>A~UR(J+Yk`3X<pjx8GXY-FNAY+G+4SpK?46r?>G3D@dzR zm>xg;h@A?P&#N21aJ~p1hGdi@UQ%JyLToW_u(jT&G;sYX=9OLSV{&(UlD<ac|K=cv z%`(Fnpo>S78QORJgzJ`Iai42K9)$m*`|<c?8`a>To87AfucF|dyn{3HLTUmAs%NWS zFeTUt88)gE7QqXp`ijUBAR~a9Rp?bhi2yp-vHiWBI^aF;Z>O%hYPqmgbX-Y>L84<K zZEM_&HhRsKh0h+*q`l40O$|nEv{k*ZwObx75A9P;>E<=7y-q&`1~C>&i4CGw92N9A z?xCNqT%Z5(Qy&KHRlxg6dW3)led#rj29TJ1y?(Hd_Mk<jc_gWM-Fp4pxd^>a68OGT z(7$VR@LF%64tVx=3RDN!_d_6V2}fQw1QR^$nVe3WVO!Mr0rKMpZkzwaK!2t{irPWU z{sNI)k2DQ=>+kEJa>pWAY^E>sH3*oyZh#^N{u=ybtM*82MH}^26MJr5%ImnMww=4s zt5HPdQ?0~`yI!*ILD@1e>pu@u&9}Ho4Y+t-rl`|%CgVFzE0-qb{q4(vzm2&KS%D9e z=AxJv;2`$w4xuAE@9~H__#FSj9FO7BRzm>tZD%umw9h`J%h4!(o{dK7L~sYW*bfBx z7;Pa;VI{>v^_mkUMqCydxMGb2nit7SAlX?)5X?b?CW$AfJiKo?5QOWA1h`~=k<q2U z+cSAN3N2|jfWFMg)wLIrO0&JN|AO4+lj#|=)qXeD{C~}bbgoa1AB&-c#G=l*QUy_c zk)Xshd6Wt6_m7|iqV4y{{1>2)rDy@aD0|T3x-+;^(achnKlFDh&h36)2Llve(x8rf z%6K6_3dUQ~V1=$_{x4fgbG4WYF)agj@+K~9<X<EQBU&IP;SnSB?G55ef-~x}HN2?u zq8vNroHIqG3Lt9Iv~P!aGX+c@k>!XZpm}u!<%bgpt#VONaYX1Bs+Ep|V)Uy&l9~jX zjd}Y$)xPLFg}6llq5FipVAjH!q#aB7Z>LQw>7ombTKyIJHh+Z}s7!-tx%PDhpidc; z*Z06=#e6PWuNFkspHd9u4$w^BR*aRN1T7H*xbLjIUT|82a+MgVd!sylfJ4&WgDQ8m zaCors=(ODQ^2OOnmwWlP42u+{>#4`B^}F{IWsMQSqTgT2JV#u5?&R8(VuAc@*h|3^ z7$)+C6kvR-&J;3X=w|RGp&`O7qJttMm3~}-q)F=S^g4Pkk*WBQ4M&CG4gC+&LKx~| zs4^&mfcf6i7KK$${YFTZ)B?5$%xJ>};MUAy{Zu;20i?q#XYrbKvYu}_=ZL3x<=b*j z2irJ07x7n<2#F)scHx9+QT)fN>xK2-CQD?1gy7t{>AFB?(#hK^ayUn?!2HKm`=+97 zrc|ZrzXdKxcC`i|*_8*ExgTsv>8F_f-hC9BaTZE=St{KtYWp{N{LBniw~lGf^}a8D zmO?DTFu1PKb1A*MI4omk0~#O955NtdV(D-tVGMzK0J96SOjkAh@5CkUV_Ri??>kb{ zQGJuI<&)Af0-W2rNuB;R@0C_9P%Cn0<}Urr^?q3*bn*w#2g#}_j!Fer^Uoc!VXqLn zVfZ0DQ%VC&4T>9?r!F15=)f*A49o3OmF!;FA;W8#ALd$urT`Q;ozFy&CEr?wa=#BS zKHX?bP~(N3{mB2s$ts|sCVMhHLp{}ETRP86T}-v@Y{o(L`YcPw;W~v3YLwD^P|sr@ zGS|$p-UITpSUZ?FIO8u??;NK#oqC7TxtBX1@jN*nIS_2pryW-XF*#CF$<)0LO2L{o zQZ~G?72(~Uod0d$(UWcrA>P3j&on6E{LxaRxtsdhEzOGRIog@gu@%}Nz&|BH4O$aM zt(0xO>9<|W3EJ0MT&CB3LT37S*LnaMKFr*{8|0?h!3!zlTLrP^qKdg$iL?aLzy*6v zkrT)+tr`P&(VAeGrQpme_-vkxobH~{z;jX%Z%yNpj25W}YJB$XsgdemDh#wC#K>78 zTk9oGo0TDaZ@SfzXKbfH>sBbgK>BA1s-F)t$)DH6)z5i9nkcbZs|q^tUhaSW;(!bQ zI@B)Cert6HIc79HnH|Rk#h}hN-3<LiUmn}i)-1?37kK)WRrdtp)dw+yl)y`UH@YXl z1w<pVRxsl!?lZy?{7uCF9@4b`Fb8Oxk8VC^60=lQ*i51V_73X*`8W9>MW7!`s8#o9 z7-`%90(WYMQvKJk@h@sOh4+?szNo7Y1>fBk+dMv2Js1%&C^Iv<Ti3AV9h9_}dhXR? zbv0zh!9M&YVJ@Pvp?<@6ZGOwcX9ehwRoec2(F6R-!Bw@Pq2Qfc>+|aiV+*rW8ZAFI zr+OmFYhUHJB-d?Bj#l5<3wSm`+H;@-UweDlJcDE9wU^=;4-8%E{HR@SswGbk<PJI= zb!V2i>v`saY2eY;VavW;!ARd9)Vz61Ne+QUHL+1O>eHM4<`%05`VuNTjvF3|y7b5< zF(4_Yzg;3d=beAaS&|#8vP!7t`|)*Aj_}BVKgx?)tsL$>V$i!NYVde{<Yag$$6b@5 zv#+wkUKAIP!{U7-Sb3Nm7@x6wMsNXs(lygB4z!@pWXmI>=v`s%6#CpIlTe2F(|L!R z)$JjcHR=N1ZSM-<fZVlwuOV66DEm`GI!LybJlCh_?&d?A;=vB;_1=UQyvOfn>9~?P z4Xi#lR6S62@-wf>C%jmhyEW;4czL&1xuiC<>&k-0nVe(y*5YK^1}DaDmtVdj2mdN0 z`pEC{dG9v#{dR7F`40|@gC;?mX*zrQ26_hFI3p$Rjyx}IwD9-=6Q_+?Va`!(mH`*G zK~JuHLwn@N-`^_1j+!FrtFcN5v6K7lrKh8_V4$NrPV4>8moC;H0b^*^#<H1-V22Sh W^z~R)GjsY%tfQIm!CS_(zxzMKSo%u< diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 64affe7a61..06135acf42 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -93,7 +93,7 @@ Red/System [ T_HEX ] ending-skip: #{ -0000000000000000000000000000000000010001010000000000000001000000 +0000000000000000000000000000000000010000000000000000000001000000 } type-table: #{ 0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 @@ -148,7 +148,7 @@ Red/System [ 585858585858583A2E2F2E2E2E2E2E2E2E42582E2E2E3A3A58312E212E2E2E2E 2E3A5858583A3A585858585858583A3A3A3A3A3A3A3A3A3A4258583A3A3A3A58 313A213A3A3A3A3A3A5846462727464646464646462727462727272727272727 -272E2E2E272746462727272E2727273A46272727272727272727272827292727 +27262E2E272746462727272E2727273A46272727272727272727272827292727 272727272727272727552727272727272727272727273A3A2828282828282828 28282728282828282828282828282828282828282828282828282828283A3A29 2929292929292929292929272929292929292929292929292929292929292929 @@ -157,7 +157,7 @@ Red/System [ 2E2E42462E2E2E3A3A46312E3A2C2C2E2E2E3A464E4E2C2C4E4E4E4E4E4E4E3A 3A4E1E3A3A2C2C3A3A4E3A4E3A3A4D3A3A3A3A3A2C2C3A3A3A3A4E3A3A3A3A3A 3A3A3A3A3A3A3A3A3A2E2E2E2E2E2E2E0B3A2E2E2E3A3A3A3A2E3A2E2E3A2E2E -3A3A46462E2E464646464646463A2E2F2E2E2E2E2E2E2E42462E2E2E3A3A4631 +3A3A46462E2E464646464646463A2E2F2E2E2E2E2E2E2E4246462E2E3A3A4631 2E212E2E2E2E2E3A464646303046464646464646303030303030303030303046 3A303030304630303030303030303A465656303056565656565656303A303030 30303030303056563A3030565630303A30303A30303A56575731315757575757 From ecd0e519b9a3ad31727e29a4c247d0ca50c12653 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 17:23:24 +0100 Subject: [PATCH 0967/3432] FEAT: improves date! values ending validity checking. --- docs/lexer/lexer-FSM.xlsx | Bin 21387 -> 21398 bytes runtime/lexer.reds | 47 +++++++++++++++++------------- tests/source/units/lexer-test.red | 3 ++ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 5c1733092349ce45c0304b3f5e6f2333602fe16a..88927fcb2ffe2fbe21be6aff14e18469b61d5af5 100644 GIT binary patch delta 9467 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 F{6A89Do+3a delta 9260 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 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 60fbbd9101..546a546280 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1693,23 +1693,26 @@ lexer: context [ min: grab2-max if p < e [ if p/1 = #":" [p: grab-float p + 1 e :sec :err check-err] - if all [p < e p/1 <> #"Z"][ - neg?: p/1 = #"-" - either any [p/1 = #"+" neg?][ - TZ-h: grab2-max - if neg? [TZ-h: 0 - TZ-h] - if p < e [ - if p/1 = #":" [p: p + 1] - p: grab-digits p e 0 2 :TZ-m :err + if p < e [ + either p/1 = #"Z" [p: p + 1][ + neg?: p/1 = #"-" + either any [p/1 = #"+" neg?][ + TZ-h: grab2-max + if neg? [TZ-h: 0 - TZ-h] + if p < e [ + if p/1 = #":" [p: p + 1] + p: grab-digits p e 0 2 :TZ-m :err + ] + ][ + do-error ] - ][ - do-error ] ] ] calc-time ] store-date: [ + if p < e [do-error] if load? [dt: date/make-at alloc-slot lex year month day tm tz-h tz-m time? TZ?] lex/in-pos: e ;-- reset the input position to delimiter byte ] @@ -1725,19 +1728,21 @@ lexer: context [ p: p + 1 hour: grab2 min: grab2 - if p/1 <> #"Z" [ ;-- yyymmddThhmmZ + either p/1 = #"Z" [p: p + 1][ ;-- yyymmddThhmmZ p: grab-float p e :sec :err check-err - if all [p < e p/1 <> #"Z"][ - TZ?: yes - neg?: p/1 = #"-" - either any [p/1 = #"+" neg?][ ;-- yyymmddThhmm+-hhmm - p: p + 1 - TZ-h: grab2r - if neg? [TZ-h: 0 - TZ-h] - TZ-m: grab2r - ][ - do-error + if p < e [ + either p/1 = #"Z" [p: p + 1][ + TZ?: yes + neg?: p/1 = #"-" + either any [p/1 = #"+" neg?][ ;-- yyymmddThhmm+-hhmm + p: p + 1 + TZ-h: grab2r + if neg? [TZ-h: 0 - TZ-h] + TZ-m: grab2r + ][ + do-error + ] ] ] ] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 7c33bc4036..31abe39019 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -529,6 +529,9 @@ Red [ foreach s allow [--test-- s --assert float! = scan s] foreach s deny [--test-- s --assert error! = scan s] + --test-- "scan-24" + --assert error! = scan "1/2/12io23" + ===end-group=== ===start-group=== "transcode/trace" From 4d6a61e921d0c07c1164a4ab60557abfa21b86f3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 17:28:00 +0100 Subject: [PATCH 0968/3432] FEAT: removes deprecated `ending-skip` table. --- runtime/lexer.reds | 1 - utils/generate-lexer-table.red | 10 +--------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 546a546280..b6dbfc6b6e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -2045,7 +2045,6 @@ lexer: context [ lex/tail = lex/buffer all [slot = lex/buffer TYPE_OF(slot) <> TYPE_POINT] ][ - ;lex/in-pos: lex/in-pos + as-integer ending-skip/index exit ;-- early exit for single value request ] ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index ed345d7d66..b172590a9b 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -138,13 +138,7 @@ context [ foreach [s t] states [append type-table either t = '- [0][(index? find types t) - 1]] - ;-- Generate the ending-skip table content - ending-table: make binary! 2000 - list: skip find states '--EXIT_STATES-- 2 - - foreach [s t] list [ - append ending-table pick 1x0 to-logic find [T_STRING T_TAG] s - ] + ;-- Template -- template: compose/deep [Red/System [ Note: "Auto-generated lexical scanner transitions table" @@ -154,8 +148,6 @@ context [ (extract states 2) ] - ending-skip: (ending-table) - type-table: (type-table) transitions: (table) From 988af79da6ebaf7d791ef3762ad487cdf3cd491f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 17:52:47 +0100 Subject: [PATCH 0969/3432] FEAT: more accurate overflow detection on integer! values loading. --- runtime/lexer.reds | 13 ++++++++----- tests/source/units/lexer-test.red | 6 ++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index b6dbfc6b6e..5e0d567b11 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1170,7 +1170,7 @@ lexer: context [ load-integer: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] return: [integer!] /local - o? [logic!] + o? neg? [logic!] p [byte-ptr!] len i [integer!] cell [cell!] @@ -1182,8 +1182,11 @@ lexer: context [ return 0 ] p: s - if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign if present - + neg?: no + if flags and C_FLAG_SIGN <> 0 [ + neg?: s/1 = #"-" + p: p + 1 ;-- skip sign when present + ] either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers i: as-integer (p/1 - #"0") ][ @@ -1207,7 +1210,7 @@ lexer: context [ ] ] assert p = e - if o? [ + if any [o? neg? <> (as-logic i and 80000000h)][ len: as-integer e - s ;-- account for sign in len now either all [len = 11 zero? compare-memory s min-integer len][ i: 80000000h @@ -1215,7 +1218,7 @@ lexer: context [ ][promote] ] ] - if s/value = #"-" [i: 0 - i] + if neg? [i: 0 - i] lex/scanned: TYPE_INTEGER if load? [ cell: alloc-slot lex diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 31abe39019..b010db0117 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -478,6 +478,8 @@ Red [ --test-- "tro-93" --assert error? try [transcode/one #{3C6100623E}] ; <a^(NUL)b> --test-- "tro-94" --assert 'a == transcode/one #{610062} ; a^(NUL)b + --test-- "tro-95" --assert 2999999999.0 == transcode/one "2999999999" + ===end-group=== ===start-group=== "transcode/next" @@ -529,8 +531,8 @@ Red [ foreach s allow [--test-- s --assert float! = scan s] foreach s deny [--test-- s --assert error! = scan s] - --test-- "scan-24" - --assert error! = scan "1/2/12io23" + --test-- "scan-24" --assert error! = scan "1/2/12io23" + --test-- "scan-25" --assert float! = scan "2999999999" ===end-group=== ===start-group=== "transcode/trace" From f3fed641147bc26578456013afd8cf31f2ef15bf Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 18:15:23 +0100 Subject: [PATCH 0970/3432] FEAT: removes deprecated code for handling word<tag> cases. --- runtime/lexer.reds | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 5e0d567b11..1cfeb0be43 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -324,7 +324,6 @@ lexer: context [ all-events: 3Fh ;-- bit-mask of all events min-integer: as byte-ptr! "-2147483648" ;-- used in load-integer - flags-LG: C_FLAG_LESSER or C_FLAG_GREATER decode-filter: func [fun [red-function!] return: [integer!] /local @@ -1094,35 +1093,6 @@ lexer: context [ type: TYPE_LIT_WORD ] lex/scanned: type - - either flags and flags-LG = flags-LG [ ;-- handle word<tag> cases - p: s - while [all [p < e p/1 <> #"<"]][p: p + 1] ;-- search < - if p + 1 < e [ - pos: p - p: p + 1 - cp: as-integer p/1 ;-- check for valid tag - class: lex-classes/cp and FFh - index: S_LESSER * (size? character-classes!) + class ;-- simulate transition from S_LESSER - if (as-integer transitions/index) = S_TAG [ ;-- check if valid tag starting is recognized - while [all [p < e p/1 <> #">"]][p: p + 1] ;-- search > - if p < e [ - e: pos ;-- cut the word before < - lex/in-pos: pos ;-- resume scanning from < - ] - ] - ] - ][ - if all [flags and C_FLAG_LESSER <> 0 lex/entry = S_PATH e/0 = #"<"][ - cell: lex/tail - 1 - if TYPE_OF(cell) = TYPE_POINT [ - e: e - 1 ;-- handle word</tag> cases - lex/in-pos: e ;-- resume scanning from < - lex/entry: S_START ;-- cancel the newly opened path - lex/tail: cell - ] - ] - ] ] scan-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ @@ -1577,7 +1547,6 @@ lexer: context [ set-type as cell! fl TYPE_FLOAT fl/value: f ] - ;lex/scanned: TYPE_FLOAT lex/in-pos: e ;-- reset the input position to delimiter byte ] From 123efb211b337fa90eea65e2a50b3821dc64e654 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 25 Feb 2020 18:30:15 +0100 Subject: [PATCH 0971/3432] FEAT: implement money to integer conversion --- runtime/datatypes/integer.reds | 13 +++++ runtime/datatypes/money.reds | 94 ++++++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index b9d91fbcd7..e82e393e1a 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -73,6 +73,13 @@ integer: context [ int ] + from-money: func [ + mn [red-money!] + return: [integer!] + ][ + money/to-integer mn + ] + from-binary: func [ bin [red-binary!] return: [integer!] @@ -374,6 +381,7 @@ integer: context [ /local int [red-integer!] fl [red-float!] + mn [red-money!] str [red-string!] t [red-time!] p [byte-ptr!] @@ -400,6 +408,11 @@ integer: context [ if overflow? fl [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] int/value: as-integer fl/value ] + TYPE_MONEY [ + mn: as red-money! spec + if money/overflow? mn [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] + int/value: from-money mn + ] TYPE_BINARY [ int/value: from-binary as red-binary! spec ] diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index f73349889d..69c3bd3165 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -78,6 +78,14 @@ money: context [ yes ] + compare-amounts: func [ + this [byte-ptr!] + that [byte-ptr!] + return: [integer!] + ][ + compare-memory this that SIZE_BYTES + ] + zero-out: func [ money [red-money!] all? [logic!] @@ -96,7 +104,7 @@ money: context [ [integer!] ][ bit: index and 1 - byte: index >>> 1 + bit + byte: index >> 1 + bit offset: either as logic! bit [4][0] as integer! amount/byte @@ -113,7 +121,7 @@ money: context [ [integer!] ][ bit: index and 1 - byte: index >>> 1 + bit + byte: index >> 1 + bit offset: either as logic! bit [4][0] reverse: either offset = 0 [4][0] @@ -121,7 +129,25 @@ money: context [ and (HIGH_NIBBLE << reverse) or as byte! (value << offset) ] - + + count-digits: func [ + amount [byte-ptr!] + return: [integer!] + /local + count [integer!] + ][ + count: SIZE_DIGITS + loop SIZE_BYTES [ + either null-byte = amount/value [count: count - 2][ + count: count - as integer! null-byte = (amount/value and LOW_NIBBLE) + break + ] + amount: amount + 1 + ] + + either zero? count [1][count] + ] + make-at: func [ slot [red-value!] sign [integer!] @@ -160,6 +186,66 @@ money: context [ ][ make-at stack/push* sign amount1 amount2 amount3 ] + + overflow?: func [ + money [red-money!] + return: [logic!] + /local + other + [red-money!] + amount limit + [byte-ptr!] + sign count lower bytes + [integer!] + flag + [logic!] + ][ + sign: sign? money + if zero? sign [return no] + + amount: get-amount money + count: (count-digits amount) - SIZE_SCALE + if count <> MAX_INT_DIGITS [return count > MAX_INT_DIGITS] + + lower: 1 << 31 + other: as red-money! stack/push* + limit: get-amount other + from-integer other either negative? sign [lower][not lower] + + flag: positive? compare-amounts amount limit + stack/pop 1 + flag + ] + + to-integer: func [ + money [red-money!] + return: [integer!] + /local + amount + [byte-ptr!] + sign integer index + start power digit + [integer!] + ][ + sign: sign? money + + if zero? sign [return sign] + + amount: get-amount money + integer: 0 + index: SIZE_INTEGRAL + start: index + + loop MAX_INT_DIGITS [ + digit: get-digit amount index + power: as integer! pow 10.0 as float! start - index + integer: integer + (digit * power) + + index: index - 1 + ] + + sign * integer + ] from-integer: func [ money [red-money!] @@ -180,7 +266,7 @@ money: context [ int: integer/abs int + extra amount: get-amount money - start: SIZE_DIGITS - SIZE_SCALE + start: SIZE_INTEGRAL index: start loop MAX_INT_DIGITS [ From f6050043b127437b979ec9403cc308ff864be9b3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Tue, 25 Feb 2020 23:26:56 +0100 Subject: [PATCH 0972/3432] FIX: SCAN crashing on unmatched open bracket/paren. --- runtime/lexer.reds | 37 +++++++++++++++++-------------- runtime/natives.reds | 1 + tests/source/units/lexer-test.red | 12 ++++++++++ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1cfeb0be43..00f2429ec4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -2022,7 +2022,10 @@ lexer: context [ ] lex/in-pos >= lex/in-end ] - if lex/entry = S_M_STRING [catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING]] + if lex/entry = S_M_STRING [ + catch LEX_ERR [throw-error lex start lex/in-end TYPE_STRING] + system/thrown: 0 + ] assert lex/in-pos = lex/in-end ] @@ -2090,24 +2093,24 @@ lexer: context [ catch RED_THROWN_ERROR [scan-tokens lex one? not scan?] if system/thrown <> 0 [clean-up re-throw] - if load? [ - slots: (as-integer lex/tail - lex/buffer) >> 4 - if slots > 0 [ - p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] - if TYPE_OF(p) = TYPE_POINT [ - lex/closing: p/y - catch RED_THROWN_ERROR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] - either system/thrown <= LEX_ERR [ - dst/header: TYPE_NONE - system/thrown: 0 - clean-up - return lex/scanned - ][ - clean-up - re-throw - ] + slots: (as-integer lex/tail - lex/buffer) >> 4 + if slots > 0 [ + p: as red-point! either lex/buffer < lex/head [lex/head - 1][lex/buffer] + if TYPE_OF(p) = TYPE_POINT [ + lex/closing: p/y + catch RED_THROWN_ERROR [throw-error lex lex/input + p/z lex/in-end ERR_CLOSING] + either system/thrown <= LEX_ERR [ + dst/header: TYPE_NONE + system/thrown: 0 + clean-up + return lex/scanned + ][ + clean-up + re-throw ] ] + ] + if load? [ either all [one? not wrap? slots > 0][ copy-cell lex/buffer dst ;-- copy first loaded value only ][ diff --git a/runtime/natives.reds b/runtime/natives.reds index dc9f125ec8..5ab49a2f65 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2795,6 +2795,7 @@ natives: context [ type: lexer/scan-alt slot str len one? scan? load? no :offset fun as red-series! str ] if any [not scan? not load?][ + assert type > 0 dt: as red-datatype! slot dt/header: TYPE_DATATYPE dt/value: type diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index b010db0117..b025a62769 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -534,6 +534,18 @@ Red [ --test-- "scan-24" --assert error! = scan "1/2/12io23" --test-- "scan-25" --assert float! = scan "2999999999" + --test-- "scan-26" --assert error! = scan "[" + --test-- "scan-27" --assert error! = scan "]" + --test-- "scan-28" --assert error! = scan "(" + --test-- "scan-29" --assert error! = scan ")" + --test-- "scan-30" --assert error! = scan "#(" + --test-- "scan-31" --assert error! = scan "{" + --test-- "scan-32" --assert block! = scan "[]" + --test-- "scan-33" --assert paren! = scan "()" + --test-- "scan-34" --assert map! = scan "#()" + --test-- "scan-35" --assert string! = scan "{}" + --test-- "scan-36" --assert string! = scan {""} + ===end-group=== ===start-group=== "transcode/trace" From 5362274bf364255081883f564e1e0dfe070c0941 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Wed, 26 Feb 2020 11:44:39 +0800 Subject: [PATCH 0973/3432] FEAT: allow ' separator in dtoa. --- runtime/dtoa.reds | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index bdfb36aa3b..78e93d7dbc 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1408,10 +1408,18 @@ dtoa: context [ s0: s s1: s - while [ + c: s/1 + while [true][ + case [ + all [c >= #"0" c <= #"9"][s: s + 1] + c = #"'" [ + move-memory s s + 1 as-integer end - s + end: end - 1 + ] + true [break] + ] c: s/1 - all [c >= #"0" c <= #"9"] - ][s: s + 1] + ] ndigits: as-integer s - s1 fraclen: 0 From 945a6d618b8b28841188e3aa72a6ce83e453f2e4 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Wed, 26 Feb 2020 11:45:06 +0800 Subject: [PATCH 0974/3432] FIX: adds missing files in includes.r --- build/includes.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/includes.r b/build/includes.r index bccd02c4cb..f1f7548320 100644 --- a/build/includes.r +++ b/build/includes.r @@ -84,6 +84,8 @@ write %build/bin/sources.r set-cache [ %dtoa.reds %hashtable.reds %interpreter.reds + %lexer.reds + %lexer-transitions.reds %macros.reds %natives.reds %ownership.reds From f71e6fe3f5d61d5ced1fb598ca713ea40d027a10 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Wed, 26 Feb 2020 14:20:40 +0800 Subject: [PATCH 0975/3432] FIX: GC crashes when creating object! --- runtime/datatypes/context.reds | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/context.reds b/runtime/datatypes/context.reds index 3435404230..6431f2e05f 100644 --- a/runtime/datatypes/context.reds +++ b/runtime/datatypes/context.reds @@ -364,7 +364,7 @@ _context: context [ cell [red-context!] slot [red-value!] node [node!] - symbols [node!] + vals [node!] ][ #if debug? = yes [if verbose > 0 [print-line "_context/create"]] @@ -374,17 +374,18 @@ _context: context [ slot: alloc-tail as series! node/value ;-- allocate a slot for obj/func back-reference slot/header: TYPE_UNSET cell/header: TYPE_UNSET ;-- implicit reset of all header flags - symbols: _hashtable/init slots as red-block! proto HASH_TABLE_SYMBOL HASH_SYMBOL_CONTEXT ;@@ create the node! on native stack, so it can be marked by GC cell/self: node either stack? [ cell/values: null ;-- will be set to stack frame dynamically + cell/symbols: _hashtable/init slots as red-block! proto HASH_TABLE_SYMBOL HASH_SYMBOL_CONTEXT cell/header: TYPE_CONTEXT or flag-series-stk ][ - cell/values: alloc-unset-cells slots + vals: alloc-unset-cells slots ;@@ keep it on native stack, so it can be marked by the GC + cell/symbols: _hashtable/init slots as red-block! proto HASH_TABLE_SYMBOL HASH_SYMBOL_CONTEXT + cell/values: vals cell/header: TYPE_CONTEXT ] - cell/symbols: symbols if self? [cell/header: cell/header or flag-self-mask] node From ef6d62db1615de9b3902041b1b3d7f048034acd7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Wed, 26 Feb 2020 15:13:55 +0800 Subject: [PATCH 0976/3432] FEAT: reduce memory usage in object! --- runtime/hashtable.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 9b80bba81c..70b351a98b 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -430,7 +430,7 @@ _hashtable: context [ if all [vsize = HASH_SYMBOL_CONTEXT blk <> null][ return copy-context as red-context! blk node ] - size: size << 4 + if size >= 4000 [size: size << 4] ;-- global context ] s: as series! node/value @@ -438,7 +438,7 @@ _hashtable: context [ h/type: type if type = HASH_TABLE_INTEGER [h/indexes: as node! vsize + 1 << 4] - if size < 32 [size: 32] + if size < 4 [size: 4] fsize: as-float size f-buckets: fsize / _HT_HASH_UPPER skip: either type = HASH_TABLE_MAP [2][1] From 3b313400c266a4511c4e6e2c95a40e97208d9a60 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 26 Feb 2020 11:24:10 +0100 Subject: [PATCH 0977/3432] FEAT: improve custom loader --- environment/kludge.red | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/environment/kludge.red b/environment/kludge.red index feff0ecc6a..008a0cf62f 100644 --- a/environment/kludge.red +++ b/environment/kludge.red @@ -21,10 +21,12 @@ coin: function [ either parse string [ set sign opt [#"-" | #"+"] - #"$" - copy integral [1 digits digit] - opt [[dot | comma] copy fractional [1 scale digit]] - end + #"$" [ + some #"0" end (integral: #"0") + | any #"0" copy integral [1 digits digit] + opt [[dot | comma] copy fractional [1 scale digit]] + end + ] ][ string: rejoin [ pad/left/with integral digits #"0" From 732e8f8121ed1eb8d8537baabdee43a521456d9c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 26 Feb 2020 11:24:34 +0100 Subject: [PATCH 0978/3432] FEAT: slight refactoring --- runtime/datatypes/money.reds | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 69c3bd3165..43c9b85841 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -23,13 +23,15 @@ money: context [ SIZE_DIGITS: SIZE_BYTES * 2 SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE - #define HIGH_NIBBLE #"^(0F)" - #define LOW_NIBBLE #"^(F0)" + HIGH_NIBBLE: #"^(0F)" + LOW_NIBBLE: #"^(F0)" - #define SIGN_MASK 4000h - #define SIGN_OFFSET 14 + SIGN_MASK: 4000h + SIGN_OFFSET: 14 - #define MAX_INT_DIGITS 10 + MAX_INT_DIGITS: 10 + INT32_MIN: 1 << 31 + INT32_MAX: not INT32_MIN ;-- Support -- @@ -163,6 +165,7 @@ money: context [ money/amount1: amount1 money/amount2: amount2 money/amount3: amount3 + money ] @@ -195,7 +198,7 @@ money: context [ [red-money!] amount limit [byte-ptr!] - sign count lower bytes + sign count bytes [integer!] flag [logic!] @@ -207,10 +210,9 @@ money: context [ count: (count-digits amount) - SIZE_SCALE if count <> MAX_INT_DIGITS [return count > MAX_INT_DIGITS] - lower: 1 << 31 other: as red-money! stack/push* limit: get-amount other - from-integer other either negative? sign [lower][not lower] + from-integer other either negative? sign [INT32_MIN][INT32_MAX] flag: positive? compare-amounts amount limit stack/pop 1 @@ -258,11 +260,11 @@ money: context [ [integer!] ][ zero-out money yes - if int = 0 [return money] + if zero? int [return money] set-sign money as integer! int < 0 - extra: as integer! int = (1 << 31) + extra: as integer! int = INT32_MIN int: integer/abs int + extra amount: get-amount money From 2872eeac1fb287d5040112d142cbc7f12a3fcee0 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 26 Feb 2020 14:49:04 +0100 Subject: [PATCH 0979/3432] FEAT: document MONEY! slot layout --- runtime/datatypes/structures.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/structures.reds b/runtime/datatypes/structures.reds index dd072d31dd..e3a13cffe2 100644 --- a/runtime/datatypes/structures.reds +++ b/runtime/datatypes/structures.reds @@ -332,10 +332,10 @@ red-handle!: alias struct! [ ] red-money!: alias struct! [ - header [integer!] - amount1 [integer!] - amount2 [integer!] - amount3 [integer!] + header [integer!] ;-- cell header + amount1 [integer!] ;-- 1 bytes for currency index + amount2 [integer!] ;-- 11 bytes for BCD encoded amount + amount3 [integer!] ;-- (unsigned, packed) ] red-slice!: alias struct! [ ;@@ internal use only !!! From ab509d0c41ad7ac16e662dc4c073c50b71915c7d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 26 Feb 2020 17:20:22 +0100 Subject: [PATCH 0980/3432] FEAT: fix formatting --- environment/kludge.red | 4 ++-- runtime/datatypes/money.reds | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/environment/kludge.red b/environment/kludge.red index 008a0cf62f..b741d17dfc 100644 --- a/environment/kludge.red +++ b/environment/kludge.red @@ -24,8 +24,8 @@ coin: function [ #"$" [ some #"0" end (integral: #"0") | any #"0" copy integral [1 digits digit] - opt [[dot | comma] copy fractional [1 scale digit]] - end + opt [[dot | comma] copy fractional [1 scale digit]] + end ] ][ string: rejoin [ diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 43c9b85841..5d1c370299 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -115,9 +115,9 @@ money: context [ ] set-digit: func [ - amount [byte-ptr!] - index [integer!] - value [integer!] + amount [byte-ptr!] + index [integer!] + value [integer!] /local bit byte offset reverse [integer!] @@ -256,7 +256,7 @@ money: context [ /local amount [byte-ptr!] - extra start index power digit + extra index start power digit [integer!] ][ zero-out money yes @@ -268,8 +268,8 @@ money: context [ int: integer/abs int + extra amount: get-amount money - start: SIZE_INTEGRAL - index: start + index: SIZE_INTEGRAL + start: index loop MAX_INT_DIGITS [ power: as integer! pow 10.0 as float! start - index From 32e8e26f1800cd292a7eecf87ef4777f31afc17b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 26 Feb 2020 18:08:00 +0100 Subject: [PATCH 0981/3432] TESTS: uncomments lexer test tr-4. --- tests/source/units/lexer-test.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index b025a62769..930e4543b3 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -16,7 +16,7 @@ Red [ --test-- "tr-1" --assert [123 456 789] == transcode "123 456 789" --test-- "tr-2" --assert ["world" 111] == transcode {"world" 111} --test-- "tr-3" --assert [132 [111] ["world" [456 ["hi"]]] 222] == transcode { 132 [111] ["world" [456 ["hi"]]] 222} - ;--test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} + --test-- "tr-4" --assert do {[12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]] == transcode "12.34.210.5.66.88 192.168.0.1 [1.0.0 0.0.255]"} --test-- "tr-5" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode #{2322722220232261222023225E2F222023225E286C696E6529222023225E2836362922} --test-- "tr-6" --assert [#"r" #"a" #"^/" #"^/" #"f"] == transcode {#"r" #"a" #"^^/" #"^^(line)" #"^^(66)"} --test-- "tr-7" --assert [#r #abcdc /z /abcdef] == transcode {#r #abcdc /z /abcdef} From d58cc42917a1308932dc1c2d10c4293dcabfba5a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 26 Feb 2020 19:07:00 +0100 Subject: [PATCH 0982/3432] FIX: scanning words could lead to crashes. Ex: scan/fast "a" --- runtime/lexer-transitions.reds | 5 +-- runtime/lexer.reds | 50 ++++++++++++++++------------- tests/source/units/lexer-test.red | 53 ++++++++++++++++--------------- utils/generate-lexer-table.red | 2 +- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 06135acf42..a54f4eeb49 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -92,13 +92,10 @@ Red/System [ T_EMAIL T_HEX ] - ending-skip: #{ -0000000000000000000000000000000000010000000000000000000001000000 -} type-table: #{ 0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000000000000000 -07000000000B00130A14070829260C0C272F252B332C092D0B +07000000000B0F130A14070829260C0C272F252B332C092D0B } transitions: #{ 000014143B3C3D3E3F3A020D2D2D2E2E2E2E232E230B3A262E2E063A013A2B20 diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 00f2429ec4..d3e8b50619 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -999,7 +999,7 @@ lexer: context [ ] open-block lex type s ;-- open a new path series if type <> TYPE_PATH [s: s + 1] - lex/scanned: TYPE_WORD + lex/type: TYPE_WORD if load? [ flags: flags and not C_FLAG_COLON load-word lex s e flags yes @@ -1096,8 +1096,7 @@ lexer: context [ ] scan-issue: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ - s: s + 1 - if s = e [throw-error lex s - 1 e TYPE_ISSUE] + if s + 1 = e [throw-error lex s e TYPE_ISSUE] ] scan-string: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] @@ -1390,21 +1389,20 @@ lexer: context [ p pos [byte-ptr!] cell [cell!] ][ - either lex/scanned > 0 [type: lex/scanned][ - type: TYPE_WORD - if flags and C_FLAG_COLON <> 0 [ - case [ - s/1 = #":" [type: TYPE_GET_WORD] - e/0 = #":" [type: TYPE_SET_WORD] - all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path - true [throw-error lex s e type] - ] - ] - if s/1 = #"'" [ - if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] - type: TYPE_LIT_WORD + type: either lex/type > 0 [lex/type][lex/scanned] + + if flags and C_FLAG_COLON <> 0 [ + case [ + s/1 = #":" [type: TYPE_GET_WORD] + e/0 = #":" [type: TYPE_SET_WORD] + all [e/1 = #":" lex/entry = S_PATH][0] ;-- do nothing if in a path + true [throw-error lex s e type] ] ] + if s/1 = #"'" [ + if type = TYPE_SET_WORD [throw-error lex s e TYPE_LIT_WORD] + type: TYPE_LIT_WORD + ] if type <> TYPE_WORD [ switch type [ TYPE_ISSUE @@ -1426,21 +1424,29 @@ lexer: context [ if type = TYPE_SET_WORD [lex/in-pos: e + 1] ;-- skip ending delimiter ] - load-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ + load-refinement: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + /local type [integer!] + ][ + type: TYPE_REFINEMENT case [ - s + 1 = e [lex/scanned: TYPE_WORD] + s + 1 = e [type: TYPE_WORD] s + 2 = e [ case [ - s/1 = #"'" [lex/scanned: TYPE_LIT_WORD] - s/1 = #":" [lex/scanned: TYPE_GET_WORD] - e/0 = #":" [lex/scanned: TYPE_SET_WORD] + s/1 = #"'" [type: TYPE_LIT_WORD] + s/1 = #":" [type: TYPE_GET_WORD] + e/0 = #":" [type: TYPE_SET_WORD] true [0] ] ] s/1 <> #"/" [throw-error lex s e TYPE_REFINEMENT] true [0] ] - if load? [load-word lex s e flags yes] + either load? [ + lex/type: type + load-word lex s e flags yes + ][ + lex/scanned: type + ] ] load-file: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 930e4543b3..566406346f 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -545,6 +545,7 @@ Red [ --test-- "scan-34" --assert map! = scan "#()" --test-- "scan-35" --assert string! = scan "{}" --test-- "scan-36" --assert string! = scan {""} + --test-- "scan-37" --assert word! = scan/fast "a" ===end-group=== ===start-group=== "transcode/trace" @@ -582,9 +583,9 @@ Red [ --test-- "tt-1" clear logs - --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger + --assert (compose [a: 1 (to-path 'b) []]) == transcode/trace "a: 1 b/ []" :lex-logger --assert logs = [ - prescan word! word! 1 1x3 + prescan word! datatype! 1 1x3 scan set-word! word! 1 1x3 load set-word! datatype! 1 a: prescan integer! datatype! 1 4x5 @@ -603,9 +604,9 @@ Red [ --test-- "tt-2" clear logs - --assert (compose [a: 1 (to-path 'b) x]) == transcode/trace "a: 1 b/ x" :lex-logger + --assert (compose [a: 1 (to-path 'b) x]) == transcode/trace "a: 1 b/ x" :lex-logger --assert logs = [ - prescan word! word! 1 1x3 + prescan word! datatype! 1 1x3 scan set-word! word! 1 1x3 load set-word! datatype! 1 a: prescan integer! datatype! 1 4x5 @@ -616,16 +617,16 @@ Red [ load word! datatype! 1 b prescan error! word! 1 8x8 error error! datatype! 1 8x8 - prescan word! word! 1 9x10 + prescan word! datatype! 1 9x10 scan word! word! 1 9x10 load word! datatype! 1 x ] --test-- "tt-3" clear logs - --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-logger + --assert none == transcode/trace "a: 1 #(r: 2) [ x" :lex-logger --assert logs = [ - prescan word! word! 1 1x3 + prescan word! datatype! 1 1x3 scan set-word! word! 1 1x3 load set-word! datatype! 1 a: prescan integer! datatype! 1 4x5 @@ -633,7 +634,7 @@ Red [ load integer! datatype! 1 1 prescan map! word! 1 6x7 open map! datatype! 1 7x7 - prescan word! word! 1 8x10 + prescan word! datatype! 1 8x10 scan set-word! word! 1 8x10 load set-word! datatype! 1 r: prescan integer! datatype! 1 11x12 @@ -643,7 +644,7 @@ Red [ close map! datatype! 1 12x12 prescan block! word! 1 14x14 open block! datatype! 1 14x14 - prescan word! word! 1 16x17 + prescan word! datatype! 1 16x17 scan word! word! 1 16x17 load word! datatype! 1 x error error! datatype! 1 14x17 @@ -651,9 +652,9 @@ Red [ --test-- "tt-4" clear logs - --assert [a: 1 x] == transcode/trace "a: 1 ) x" :lex-logger + --assert [a: 1 x] == transcode/trace "a: 1 ) x" :lex-logger --assert logs = [ - prescan word! word! 1 1x3 + prescan word! datatype! 1 1x3 scan set-word! word! 1 1x3 load set-word! datatype! 1 a: prescan integer! datatype! 1 4x5 @@ -662,7 +663,7 @@ Red [ prescan paren! word! 1 6x6 close paren! datatype! 1 6x6 error error! datatype! 1 6x6 - prescan word! word! 1 8x9 + prescan word! datatype! 1 8x9 scan word! word! 1 8x9 load word! datatype! 1 x ] @@ -671,7 +672,7 @@ Red [ clear logs --assert [hello 3.14 pi world] == transcode/trace "hello ^/\ 3.14 pi world" :lex-logger --assert logs = [ - prescan word! word! 1 1x6 + prescan word! datatype! 1 1x6 scan word! word! 1 1x6 load word! datatype! 1 hello prescan error! word! 2 8x8 @@ -679,17 +680,17 @@ Red [ prescan float! datatype! 2 10x14 scan float! word! 2 10x14 load float! datatype! 2 3.14 - prescan word! word! 2 15x17 + prescan word! datatype! 2 15x17 scan word! word! 2 15x17 load word! datatype! 2 pi - prescan word! word! 2 18x23 + prescan word! datatype! 2 18x23 scan word! word! 2 18x23 load word! datatype! 2 world ] --test-- "tt-6" clear logs - --assert [123 "abc" 123456789123.0 test] == transcode/trace "123 {abc} 123456789123 test" :lex-logger + --assert [123 "abc" 123456789123.0 test] == transcode/trace "123 {abc} 123456789123 test" :lex-logger --assert logs = [ prescan integer! datatype! 1 1x4 scan integer! word! 1 1x4 @@ -701,16 +702,16 @@ Red [ prescan integer! datatype! 1 11x23 scan float! word! 1 11x23 load float! datatype! 1 123456789123.0 - prescan word! word! 1 24x28 + prescan word! datatype! 1 24x28 scan word! word! 1 24x28 load word! datatype! 1 test ] --test-- "tt-7" clear logs - --assert [a: 1] == transcode/trace "a: 1 ]" :lex-logger + --assert [a: 1] == transcode/trace "a: 1 ]" :lex-logger --assert logs = [ - prescan word! word! 1 1x3 + prescan word! datatype! 1 1x3 scan set-word! word! 1 1x3 load set-word! datatype! 1 a: prescan integer! datatype! 1 4x5 @@ -743,9 +744,9 @@ Red [ ] clear logs - --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter + --assert [hello "test" pi world] = transcode/trace "hello ^/123 ^/[^/3x4 {test} 3.14 pi]^/ world" :lex-filter --assert logs = [ - prescan word! word! 1 1x6 + prescan word! datatype! 1 1x6 scan word! word! 1 1x6 load word! datatype! 1 hello prescan integer! datatype! 2 8x11 @@ -763,12 +764,12 @@ Red [ prescan float! datatype! 4 26x30 scan float! word! 4 26x30 load float! datatype! 4 3.14 - prescan word! word! 4 31x33 + prescan word! datatype! 4 31x33 scan word! word! 4 31x33 load word! datatype! 4 pi prescan block! word! 4 33x33 close block! datatype! 4 33x33 - prescan word! word! 5 36x41 + prescan word! datatype! 5 36x41 scan word! word! 5 36x41 load word! datatype! 5 world ] @@ -793,12 +794,12 @@ Red [ yes ] clear logs - --assert [123 abc] == transcode/trace "123 abc" :lex-filter10 + --assert [123 abc] == transcode/trace "123 abc" :lex-filter10 --assert logs = [ prescan integer! datatype! 1 1x4 scan integer! word! 1 1x4 load integer! datatype! 1 123 - prescan word! word! 1 5x8 + prescan word! datatype! 1 5x8 scan word! word! 1 5x8 load word! datatype! 1 abc ] @@ -838,7 +839,7 @@ Red [ prescan integer! datatype! 1 1x4 scan integer! word! 1 1x4 load integer! datatype! 1 123 - prescan word! word! 1 5x8 + prescan word! datatype! 1 5x8 scan word! word! 1 5x8 load word! datatype! 1 abc ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index b172590a9b..a15ad2406c 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -83,7 +83,7 @@ context [ T_CONS_MK - ;-- 67 T_CMT - ;-- 68 T_INTEGER TYPE_INTEGER ;-- 69 - T_WORD - ;-- 70 + T_WORD TYPE_WORD ;-- 70 T_REFINE TYPE_REFINEMENT ;-- 71 T_CHAR TYPE_CHAR ;-- 72 T_ISSUE TYPE_ISSUE ;-- 73 From a09b90de9f8c4897146ea52557c53c9a0f8d4fbe Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 26 Feb 2020 19:41:33 +0100 Subject: [PATCH 0983/3432] TESTS: adding commented non-passing scan/fast tests. --- tests/source/units/lexer-test.red | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 566406346f..aca8e09db6 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -545,8 +545,24 @@ Red [ --test-- "scan-34" --assert map! = scan "#()" --test-- "scan-35" --assert string! = scan "{}" --test-- "scan-36" --assert string! = scan {""} - --test-- "scan-37" --assert word! = scan/fast "a" +===end-group=== +===start-group=== "scan/fast" + + --test-- "scan-1" --assert word! = scan/fast "a" + --test-- "scan-2" --assert error! = scan/fast "[" +comment { + --test-- "scan-3" --assert error! = scan/fast "]" + --test-- "scan-4" --assert error! = scan/fast "(" + --test-- "scan-5" --assert error! = scan/fast ")" + --test-- "scan-6" --assert error! = scan/fast "#(" + --test-- "scan-7" --assert error! = scan/fast "^{" + --test-- "scan-8" --assert block! = scan/fast "[]" + --test-- "scan-9" --assert paren! = scan/fast "()" + --test-- "scan-10" --assert map! = scan/fast "#()" + --test-- "scan-11" --assert string! = scan/fast "{}" + --test-- "scan-12" --assert string! = scan/fast ^{""^} +} ===end-group=== ===start-group=== "transcode/trace" From 6a7d963a8d0116f44de3e8fc9549cec496aae55e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Wed, 26 Feb 2020 14:04:06 +0100 Subject: [PATCH 0984/3432] FIX: avoids some crashes on lexer errors. --- runtime/lexer.reds | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index d3e8b50619..9527d98f86 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -374,15 +374,15 @@ lexer: context [ lex/scanned: TYPE_ERROR throw LEX_ERR ;-- bypass errors when scanning only ] - if lex/fun-ptr <> null [unless fire-event lex EVT_ERROR TYPE_ERROR null s e [throw LEX_ERR]] - e: lex/in-end - len: 0 if null? s [ ;-- determine token's start either lex/head = lex/buffer [s: lex/input][ po: as red-point! lex/head - 1 ;-- take start of the parent series either TYPE_OF(po) <> TYPE_POINT [s: lex/input][s: lex/input + po/z] ] ] + if lex/fun-ptr <> null [unless fire-event lex EVT_ERROR TYPE_ERROR null s e [throw LEX_ERR]] + e: lex/in-end + len: 0 p: s while [all [p < e p/1 <> #"^/" s + 30 > p]][p: unicode/fast-decode-utf8-char p :len] if p > e [p: e] @@ -2001,6 +2001,8 @@ lexer: context [ ] ] ] + system/thrown: 0 + if load? [ ;-- Loading stage -- do-load: as loader! loaders/index if :do-load <> null [ @@ -2097,7 +2099,7 @@ lexer: context [ ] catch RED_THROWN_ERROR [scan-tokens lex one? not scan?] - if system/thrown <> 0 [clean-up re-throw] + if system/thrown > LEX_ERR [clean-up re-throw] slots: (as-integer lex/tail - lex/buffer) >> 4 if slots > 0 [ From ac8e81c285bfcdda731aeac7ed841312849f05bc Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 27 Feb 2020 10:06:46 +0800 Subject: [PATCH 0985/3432] FIX: reduce runtime initial memory usage. --- runtime/hashtable.reds | 2 +- tests/source/units/lexer-test.red | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 70b351a98b..0fd5ccf9b5 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -430,7 +430,7 @@ _hashtable: context [ if all [vsize = HASH_SYMBOL_CONTEXT blk <> null][ return copy-context as red-context! blk node ] - if size >= 4000 [size: size << 4] ;-- global context + if size >= 4000 [size: size << 1] ;-- global context ] s: as series! node/value diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index aca8e09db6..ecf657055d 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -549,19 +549,19 @@ Red [ ===end-group=== ===start-group=== "scan/fast" - --test-- "scan-1" --assert word! = scan/fast "a" - --test-- "scan-2" --assert error! = scan/fast "[" + --test-- "scan/fast-1" --assert word! = scan/fast "a" comment { - --test-- "scan-3" --assert error! = scan/fast "]" - --test-- "scan-4" --assert error! = scan/fast "(" - --test-- "scan-5" --assert error! = scan/fast ")" - --test-- "scan-6" --assert error! = scan/fast "#(" - --test-- "scan-7" --assert error! = scan/fast "^{" - --test-- "scan-8" --assert block! = scan/fast "[]" - --test-- "scan-9" --assert paren! = scan/fast "()" - --test-- "scan-10" --assert map! = scan/fast "#()" - --test-- "scan-11" --assert string! = scan/fast "{}" - --test-- "scan-12" --assert string! = scan/fast ^{""^} + --test-- "scan/fast-2" --assert error! = scan/fast "[" + --test-- "scan/fast-3" --assert error! = scan/fast "]" + --test-- "scan/fast-4" --assert error! = scan/fast "(" + --test-- "scan/fast-5" --assert error! = scan/fast ")" + --test-- "scan/fast-6" --assert error! = scan/fast "#(" + --test-- "scan/fast-7" --assert error! = scan/fast "^{" + --test-- "scan/fast-8" --assert block! = scan/fast "[]" + --test-- "scan/fast-9" --assert paren! = scan/fast "()" + --test-- "scan/fast-10" --assert map! = scan/fast "#()" + --test-- "scan/fast-11" --assert string! = scan/fast "{}" + --test-- "scan/fast-12" --assert string! = scan/fast ^{""^} } ===end-group=== ===start-group=== "transcode/trace" From ec87ed196a4c5bd9b01d5b7f05f877f7ff65a250 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 27 Feb 2020 11:03:01 +0800 Subject: [PATCH 0986/3432] FIX: wrongly convert 12345678901234567.0 in dtoa lib. --- runtime/dtoa.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 78e93d7dbc..30a2840bd2 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1770,7 +1770,7 @@ dtoa: context [ STRTOD_BREAK ] ] - not all [zero? (w0 and BNDRY_MASK) zero? w1][ + all [zero? (w0 and BNDRY_MASK) zero? w1][ STRTOD_DROP_DOWN ] true [] From bf15211a20a482bbd7ab56cba5b26a394f896581 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 27 Feb 2020 11:03:01 +0800 Subject: [PATCH 0987/3432] FIX: wrongly convert 12345678901234567.0 in dtoa lib. --- runtime/dtoa.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 999a039c53..50d99a72e1 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1774,7 +1774,7 @@ dtoa: context [ STRTOD_BREAK ] ] - not all [zero? (w0 and BNDRY_MASK) zero? w1][ + all [zero? (w0 and BNDRY_MASK) zero? w1][ STRTOD_DROP_DOWN ] true [] From c03605b4a13b8d8eb0ea4d7a3fde528e47e4b5cc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 11:31:25 +0100 Subject: [PATCH 0988/3432] FEAT: more robust overflow detection --- runtime/datatypes/money.reds | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 5d1c370299..0ad61e596d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -29,9 +29,9 @@ money: context [ SIGN_MASK: 4000h SIGN_OFFSET: 14 - MAX_INT_DIGITS: 10 - INT32_MIN: 1 << 31 - INT32_MAX: not INT32_MIN + INT32_MAX_DIGITS: 10 + INT32_MIN_AMOUNT: #{00000002147483648FFFFF} + INT32_MAX_AMOUNT: #{00000002147483647FFFFF} ;-- Support -- @@ -194,29 +194,20 @@ money: context [ money [red-money!] return: [logic!] /local - other - [red-money!] amount limit [byte-ptr!] - sign count bytes + sign count [integer!] - flag - [logic!] ][ sign: sign? money if zero? sign [return no] amount: get-amount money count: (count-digits amount) - SIZE_SCALE - if count <> MAX_INT_DIGITS [return count > MAX_INT_DIGITS] + if count <> INT32_MAX_DIGITS [return count > INT32_MAX_DIGITS] - other: as red-money! stack/push* - limit: get-amount other - from-integer other either negative? sign [INT32_MIN][INT32_MAX] - - flag: positive? compare-amounts amount limit - stack/pop 1 - flag + limit: either negative? sign [INT32_MIN_AMOUNT][INT32_MAX_AMOUNT] + positive? compare-amounts amount limit ] to-integer: func [ @@ -238,7 +229,7 @@ money: context [ index: SIZE_INTEGRAL start: index - loop MAX_INT_DIGITS [ + loop INT32_MAX_DIGITS [ digit: get-digit amount index power: as integer! pow 10.0 as float! start - index integer: integer + (digit * power) @@ -262,16 +253,16 @@ money: context [ zero-out money yes if zero? int [return money] - set-sign money as integer! int < 0 + set-sign money as integer! negative? int - extra: as integer! int = INT32_MIN + extra: as integer! int = (1 << 31) int: integer/abs int + extra amount: get-amount money index: SIZE_INTEGRAL start: index - loop MAX_INT_DIGITS [ + loop INT32_MAX_DIGITS [ power: as integer! pow 10.0 as float! start - index digit: int / power // 10 From eb5c4b102e82131f5781d9d23cd333be31f36f7b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 11:32:08 +0100 Subject: [PATCH 0989/3432] FEAT: use predicates instead of comparison --- runtime/datatypes/money.reds | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 0ad61e596d..a42c504c7e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -125,7 +125,7 @@ money: context [ bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] - reverse: either offset = 0 [4][0] + reverse: either zero? offset [4][0] amount/byte: amount/byte and (HIGH_NIBBLE << reverse) @@ -216,8 +216,7 @@ money: context [ /local amount [byte-ptr!] - sign integer index - start power digit + sign integer index start power digit [integer!] ][ sign: sign? money @@ -284,21 +283,21 @@ money: context [ money [red-money!] return: [logic!] ][ - -1 = sign? money + negative? sign? money ] zero-money?: func [ money [red-money!] return: [logic!] ][ - 0 = sign? money + zero? sign? money ] positive-money?: func [ money [red-money!] return: [logic!] ][ - 1 = sign? money + positive? sign? money ] sign?: func [ @@ -355,7 +354,7 @@ money: context [ amount: get-amount money sign: sign? money - if sign < 0 [ + if negative? sign [ string/concatenate-literal buffer "-" part: part - 1 ] From 3e93bec9a581f26ebdf3caaf35635f5cf0d0f1c3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 14:11:57 +0100 Subject: [PATCH 0990/3432] FEAT: small sign-checking helper for integers --- runtime/datatypes/integer.reds | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index e82e393e1a..5c76d5291d 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -19,6 +19,13 @@ integer: context [ ][ any [fl/value > 2147483647.0 fl/value < -2147483648.0] ] + + sign?: func [ + integer [integer!] + return: [integer!] + ][ + SIGN_COMPARE_RESULT(integer 0) + ] abs: func [ value [integer!] From 80ea6c77d95ce530874b88f85c6e45ba9de66b37 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 14:13:10 +0100 Subject: [PATCH 0991/3432] FIX: don't overwrite value slot during conversion --- runtime/datatypes/money.reds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a42c504c7e..32bb619259 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -89,12 +89,15 @@ money: context [ ] zero-out: func [ - money [red-money!] - all? [logic!] + money [red-money!] + all? [logic!] + return: [red-money!] ][ money/amount1: either all? [0][money/amount1 and FF000000h] money/amount2: 0 money/amount3: 0 + + money ] get-digit: func [ @@ -240,16 +243,17 @@ money: context [ ] from-integer: func [ - money [red-money!] int [integer!] return: [red-money!] /local + money + [red-money!] amount [byte-ptr!] extra index start power digit [integer!] ][ - zero-out money yes + money: zero-out as red-money! stack/push* yes if zero? int [return money] set-sign money as integer! negative? int @@ -328,7 +332,7 @@ money: context [ switch TYPE_OF(spec) [ TYPE_INTEGER [ integer: as red-integer! spec - money: from-integer money integer/value + money: from-integer integer/value ] TYPE_FLOAT [--NOT_IMPLEMENTED--] default [ From 0c58ede000e482a9376e61c5f2b30bf50532de24 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 14:13:48 +0100 Subject: [PATCH 0992/3432] FEAT: implement COMPARE action --- runtime/datatypes/money.reds | 87 ++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 32bb619259..1c740a0c77 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -20,6 +20,27 @@ money: context [ SIZE_SCALE: 05 ] + #enum signs! [ + ;-- -0+ + ;-- -101 + ;-- +1 012 + + SIGN_--: 00h + SIGN_-0: 01h + SIGN_-+: 02h + + SIGN_0-: 10h + SIGN_00: 11h + SIGN_0+: 12h + + SIGN_+-: 20h + SIGN_+0: 21h + SIGN_++: 22h + ] + + #define DISPATCH_SIGNS(this that) [switch collate-signs this that] + #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] + SIZE_DIGITS: SIZE_BYTES * 2 SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE @@ -61,6 +82,14 @@ money: context [ set-sign money as integer! not as logic! get-sign money ] + collate-signs: func [ + this [integer!] + that [integer!] + return: [integer!] + ][ + this + 1 << 4 or (that + 1) + ] + get-amount: func [ money [red-money!] return: [byte-ptr!] @@ -280,8 +309,26 @@ money: context [ money ] - - ;-- Natives -- + + compare-money: func [ + this [red-money!] + that [red-money!] + return: [integer!] + /local + this-sign that-sign + [integer!] + ][ + this-sign: sign? this + that-sign: sign? that + + DISPATCH_SIGNS(this-sign that-sign)[ + SIGN_-- [SWAP_ARGUMENTS(this that) 0] + SIGN_++ [0] + default [return integer/sign? this-sign - that-sign] + ] + + integer/sign? compare-amounts get-amount this get-amount that + ] negative-money?: func [ money [red-money!] @@ -392,7 +439,39 @@ money: context [ random: STUB - compare: STUB + compare: func [ + money [red-money!] + value [red-money!] + op [integer!] + return: [integer!] + /local + int [red-integer!] + ][ + if all [ + TYPE_OF(money) <> TYPE_OF(value) + any [ + op = COMP_SORT + op = COMP_CASE_SORT + op = COMP_FIND + op = COMP_SAME + op = COMP_STRICT_EQUAL + ] + ][ + return 1 + ] + + switch TYPE_OF(value) [ + TYPE_MONEY [0] + TYPE_INTEGER [ + int: as red-integer! value + value: from-integer int/value + ] + TYPE_FLOAT [--NOT_IMPLEMENTED--] + default [RETURN_COMPARE_OTHER] + ] + + compare-money money value + ] absolute: func [return: [red-money!]][ set-sign as red-money! stack/arguments 0 @@ -441,7 +520,7 @@ money: context [ :mold null ;eval-path null ;set-path - null;:compare + :compare ;-- Scalar actions -- :absolute null;:add From 2ab40d3a71e095439175e5f20112d198b3deec88 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 14:14:40 +0100 Subject: [PATCH 0993/3432] FEAT: implement integer/money comparison --- runtime/datatypes/integer.reds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index 5c76d5291d..2a709ccb08 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -512,6 +512,12 @@ integer: context [ char: as red-char! value2 ;@@ could be optimized as integer! and char! right: char/value ;@@ structures are overlapping exactly ] + TYPE_MONEY [ + return money/compare + money/from-integer left + as red-money! value2 + op + ] TYPE_FLOAT TYPE_TIME TYPE_PERCENT [ From 064908ca5b77b17dda3228cf77b01979b2ead403 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 14:22:46 +0100 Subject: [PATCH 0994/3432] FEAT: leave a TBD note for the future --- runtime/datatypes/money.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1c740a0c77..3477be5cf0 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -318,6 +318,8 @@ money: context [ this-sign that-sign [integer!] ][ + ;@@ TBD: take currencies into account + this-sign: sign? this that-sign: sign? that From 7f02f25b7c020f4919df67417475c9696bcaf28a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 27 Feb 2020 14:56:53 +0100 Subject: [PATCH 0995/3432] FIX: fixes some infinite loops in lexer's Prescan mode. --- runtime/lexer.reds | 20 +++++++++++++------- tests/source/units/lexer-test.red | 28 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9527d98f86..7c7026a620 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -936,7 +936,7 @@ lexer: context [ ] scan-block-close: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ - close-block lex s e TYPE_BLOCK no + catch LEX_ERR [close-block lex s e TYPE_BLOCK no] lex/in-pos: e + 1 ;-- skip ] ] @@ -944,11 +944,13 @@ lexer: context [ /local blk [red-block!] ][ - if TYPE_MAP = close-block lex s e TYPE_PAREN no [ - lex/scanned: TYPE_MAP - if lex/load? [ - blk: as red-block! lex/tail - 1 - map/make-at as cell! blk blk block/rs-length? blk + catch LEX_ERR [ + if TYPE_MAP = close-block lex s e TYPE_PAREN no [ + lex/scanned: TYPE_MAP + if lex/load? [ + blk: as red-block! lex/tail - 1 + map/make-at as cell! blk blk block/rs-length? blk + ] ] ] lex/in-pos: e + 1 ;-- skip ) @@ -1982,13 +1984,17 @@ lexer: context [ lex/scanned: as-integer type-table/state index: state - --EXIT_STATES-- + do-scan: as scanner! scanners/index + if all [pscan? state < T_INTEGER][ + catch LEX_ERR [do-scan lex s p flags no] + system/thrown: 0 + ] scan?: either not events? [not pscan?][ idx: either zero? lex/scanned [0 - index][lex/scanned] fire-event lex EVT_PRESCAN idx null s lex/in-pos ] if scan? [ ;-- Scanning stage -- load?: any [not one? ld?] - do-scan: as scanner! scanners/index either state < T_INTEGER [ catch LEX_ERR [do-scan lex s p flags ld?] ][ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index ecf657055d..08e2b27bbc 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -549,20 +549,20 @@ Red [ ===end-group=== ===start-group=== "scan/fast" - --test-- "scan/fast-1" --assert word! = scan/fast "a" -comment { - --test-- "scan/fast-2" --assert error! = scan/fast "[" - --test-- "scan/fast-3" --assert error! = scan/fast "]" - --test-- "scan/fast-4" --assert error! = scan/fast "(" - --test-- "scan/fast-5" --assert error! = scan/fast ")" - --test-- "scan/fast-6" --assert error! = scan/fast "#(" - --test-- "scan/fast-7" --assert error! = scan/fast "^{" - --test-- "scan/fast-8" --assert block! = scan/fast "[]" - --test-- "scan/fast-9" --assert paren! = scan/fast "()" - --test-- "scan/fast-10" --assert map! = scan/fast "#()" - --test-- "scan/fast-11" --assert string! = scan/fast "{}" - --test-- "scan/fast-12" --assert string! = scan/fast ^{""^} -} + --test-- "scan-f1" --assert word! = scan/fast "a" + --test-- "scan-f2" --assert error! = scan/fast "[" + --test-- "scan-f3" --assert error! = scan/fast "]" + --test-- "scan-f4" --assert error! = scan/fast "(" + --test-- "scan-f5" --assert error! = scan/fast ")" + --test-- "scan-f6" --assert error! = scan/fast "#(" + --test-- "scan-f7" --assert error! = scan/fast "{" + ;--test-- "scan-f8" --assert error! = scan/fast "}" + --test-- "scan-f9" --assert block! = scan/fast "[]" + --test-- "scan-f10" --assert paren! = scan/fast "()" + --test-- "scan-f11" --assert map! = scan/fast "#()" + --test-- "scan-f12" --assert string! = scan/fast "{}" + --test-- "scan-f13" --assert string! = scan/fast {""} + ===end-group=== ===start-group=== "transcode/trace" From 98a9874c2678ebb34213c1819523ae97bad19db3 Mon Sep 17 00:00:00 2001 From: Xie Qingtian <xqtxyz@gmail.com> Date: Thu, 27 Feb 2020 22:27:22 +0800 Subject: [PATCH 0996/3432] FEAT: try to avoid frame edge effect on GC triggering. --- runtime/allocator.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/allocator.reds b/runtime/allocator.reds index add271300f..a92b302cf8 100644 --- a/runtime/allocator.reds +++ b/runtime/allocator.reds @@ -916,7 +916,10 @@ alloc-series-buffer: func [ if null? frame [ collector/do-cycle ;-- launch a GC pass frame: find-space sz - if null? frame [ + if any [ + null? frame + (as-integer frame/tail - frame/heap) < 52428 ;- 1MB * 5% + ][ if sz >= memory/s-size [ ;@@ temporary checks memory/s-size: memory/s-max ] From 8f117e4955969725d4717cf481715635ac7afc98 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 17:52:55 +0100 Subject: [PATCH 0997/3432] FEAT: amend the specs of ADD/SUBTRACT actions --- environment/actions.red | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index 60d801a3c1..8c83c7d099 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -93,9 +93,9 @@ absolute: make action! [[ add: make action! [[ "Returns the sum of the two values" - value1 [number! char! pair! tuple! vector! time! date!] - value2 [number! char! pair! tuple! vector! time! date!] - return: [number! char! pair! tuple! vector! time! date!] + value1 [scalar! vector!] "The augend" + value2 [scalar! vector!] "The addend" + return: [scalar! vector!] "The sum" ] #get-definition ACT_ADD ] @@ -161,9 +161,9 @@ round: make action! [[ subtract: make action! [[ "Returns the difference between two values" - value1 [number! char! pair! tuple! vector! time! date!] - value2 [number! char! pair! tuple! vector! time! date!] - return: [number! char! pair! tuple! vector! time! date!] + value1 [scalar! vector!] "The minuend" + value2 [scalar! vector!] "The subtrahend" + return: [scalar! vector!] "The difference" ] #get-definition ACT_SUBTRACT ] From 9fa962ce97e42b3691b646b5719e574ba9b00d0c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 17:53:48 +0100 Subject: [PATCH 0998/3432] FIX: set MONEY! type ID during conversion --- runtime/datatypes/money.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3477be5cf0..8821fc8072 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -283,6 +283,8 @@ money: context [ [integer!] ][ money: zero-out as red-money! stack/push* yes + money/header: TYPE_MONEY + if zero? int [return money] set-sign money as integer! negative? int From eb1e4c8315c0d2cc69e377a8f8b3e0fad1e1a1ae Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 17:55:03 +0100 Subject: [PATCH 0999/3432] FEAT: preliminary work on ADD/SUBTRACT actions --- runtime/datatypes/money.reds | 207 ++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 8821fc8072..6827a9b1fc 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -41,6 +41,8 @@ money: context [ #define DISPATCH_SIGNS(this that) [switch collate-signs this that] #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] + #define MONEY_OVERFLOW [fire [TO_ERROR(math overflow)]] + SIZE_DIGITS: SIZE_BYTES * 2 SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE @@ -363,7 +365,174 @@ money: context [ either as logic! get-sign money [-1][+1] ] ] + + absolute-money: func [ + money [red-money!] + return: [red-money!] + ][ + set-sign money 0 + ] + + negate-money: func [ + money [red-money!] + return: [red-money!] + ][ + flip-sign money + ] + + add-money: func [ + augend [red-money!] + addend [red-money!] + return: [red-money!] + /local + left-amount right-amount + [byte-ptr!] + augend-sign addend-sign + index carry left right sum + [integer!] + ][ + ;@@ TBD: take currencies into account + + augend-sign: sign? augend + addend-sign: sign? addend + + DISPATCH_SIGNS(augend-sign addend-sign)[ + SIGN_00 + SIGN_-0 + SIGN_+0 [return augend] + SIGN_0- + SIGN_0+ [return addend] + SIGN_+- [return subtract-money augend absolute-money addend] + SIGN_-+ [return subtract-money addend absolute-money augend] + default [0] + ] + + left-amount: get-amount augend + right-amount: get-amount addend + + if (get-digit left-amount 1) + (get-digit right-amount 1) > 9 [MONEY_OVERFLOW] + + index: SIZE_DIGITS + carry: 0 + + loop index [ + left: get-digit left-amount index + right: get-digit right-amount index + + sum: left + right + carry + carry: sum / 10 + unless zero? carry [sum: sum + 6 and 0Fh] + + set-digit left-amount index sum + + index: index - 1 + ] + + if as logic! carry [MONEY_OVERFLOW] + augend + ] + + subtract-money: func [ + minuend [red-money!] + subtrahend [red-money!] + return: [red-money!] + /local + left-amount right-amount + [byte-ptr!] + minuend-sign subtrahend-sign sign + index borrow left right difference + [integer!] + lesser? + [logic!] + ][ + ;@@ TBD: take currencies into account + + minuend-sign: sign? minuend + subtrahend-sign: sign? subtrahend + + DISPATCH_SIGNS(minuend-sign subtrahend-sign)[ + SIGN_00 + SIGN_0- + SIGN_0+ [return negate-money subtrahend] + SIGN_-0 + SIGN_+0 [return minuend] + SIGN_-+ [return negate-money add-money absolute-money minuend absolute-money subtrahend] + SIGN_+- [return add-money minuend absolute-money subtrahend] + + SIGN_-- [ + lesser?: negative? compare-money minuend subtrahend + sign: as integer! lesser? + + minuend: absolute-money minuend + subtrahend: absolute-money subtrahend + + unless lesser? [SWAP_ARGUMENTS(minuend subtrahend)] + ] + + SIGN_++ [ + lesser?: negative? compare-money minuend subtrahend + sign: as integer! lesser? + + if lesser? [SWAP_ARGUMENTS(minuend subtrahend)] + ] + ] + + left-amount: get-amount minuend + right-amount: get-amount subtrahend + + index: SIZE_DIGITS + borrow: 0 + + loop index [ + left: get-digit left-amount index + right: get-digit right-amount index + + difference: left - right - borrow + borrow: as integer! negative? difference + if as logic! borrow [difference: difference + 10] + + set-digit left-amount index difference + + index: index - 1 + ] + + set-sign minuend sign + ] + + do-math: func [ + left [red-money!] + right [red-money!] + op [integer!] + return: [red-money!] + /local + int [red-integer!] + ][ + switch TYPE_OF(right) [ + TYPE_MONEY [0] + TYPE_INTEGER [ + int: as red-integer! right + right: from-integer int/value + ] + TYPE_FLOAT [--NOT_IMPLEMENTED--] + default [ + fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] + ] + ] + switch op [ + OP_ADD [return add-money left right] + OP_SUB [return subtract-money left right] + OP_MUL + OP_DIV + OP_REM [--NOT_IMPLEMENTED--] + default [ + fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] + ] + ] + + left + ] + ;-- Actions -- make: func [ @@ -478,15 +647,41 @@ money: context [ ] absolute: func [return: [red-money!]][ - set-sign as red-money! stack/arguments 0 + absolute-money as red-money! stack/arguments ] negate: func [return: [red-money!]][ - flip-sign as red-money! stack/arguments + negate-money as red-money! stack/arguments + ] + + add: func [ + return: [red-value!] + /local + left [red-money!] + right [red-money!] + result [red-money!] + ][ + left: as red-money! stack/arguments + right: left + 1 + + result: do-math left right OP_ADD + SET_RETURN(result) + ] + + subtract: func [ + return: [red-value!] + /local + left [red-money!] + right [red-money!] + result [red-money!] + ][ + left: as red-money! stack/arguments + right: left + 1 + + result: do-math left right OP_SUB + SET_RETURN(result) ] - add: STUB - subtract: STUB multiply: STUB divide: STUB remainder: STUB @@ -527,14 +722,14 @@ money: context [ :compare ;-- Scalar actions -- :absolute - null;:add + :add null;:divide null;:multiply :negate null ;power null;:remainder null;:round - null;:subtract + :subtract :even? :odd? ;-- Bitwise actions -- From a3665161582308c2b1301ad30740ccabfa5ef047 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 17:55:42 +0100 Subject: [PATCH 1000/3432] FEAT: support integer/money math operations --- runtime/datatypes/integer.reds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index 2a709ccb08..63e132127a 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -245,6 +245,12 @@ integer: context [ TYPE_INTEGER TYPE_CHAR [ left/value: do-math-op left/value right/value op ] + TYPE_MONEY [ + left: as red-integer! money/do-math + money/from-integer left/value + as red-money! right + op + ] TYPE_FLOAT TYPE_PERCENT TYPE_TIME [float/do-math op] TYPE_PAIR TYPE_TUPLE [ From 278130ad4c0a1fb9d9fb3f530c0130350b40a691 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 27 Feb 2020 18:07:13 +0100 Subject: [PATCH 1001/3432] FIX: non-passing lexer test "scan-f8". --- runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 4 +++- tests/source/units/lexer-test.red | 10 +++++----- utils/generate-lexer-table.red | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a54f4eeb49..a9b2cd597f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -94,7 +94,7 @@ Red/System [ ] type-table: #{ 0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 -3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000000000000000 +3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000220000000000 07000000000B0F130A14070829260C0C272F252B332C092D0B } transitions: #{ diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7c7026a620..41891f8467 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1933,7 +1933,7 @@ lexer: context [ pscan? [logic!] ;-- prescan only /local cp class index state prev flags line mark offset idx [integer!] - term? load? ld? scan? events? [logic!] + term? load? ld? scan? events? err? [logic!] p e start s [byte-ptr!] slot [cell!] do-scan [scanner!] @@ -1987,7 +1987,9 @@ lexer: context [ do-scan: as scanner! scanners/index if all [pscan? state < T_INTEGER][ catch LEX_ERR [do-scan lex s p flags no] + err?: system/thrown = LEX_ERR system/thrown: 0 + if err? [exit] ] scan?: either not events? [not pscan?][ idx: either zero? lex/scanned [0 - index][lex/scanned] diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 08e2b27bbc..85f19c89fb 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -556,7 +556,7 @@ Red [ --test-- "scan-f5" --assert error! = scan/fast ")" --test-- "scan-f6" --assert error! = scan/fast "#(" --test-- "scan-f7" --assert error! = scan/fast "{" - ;--test-- "scan-f8" --assert error! = scan/fast "}" + --test-- "scan-f8" --assert error! = scan/fast "}" --test-- "scan-f9" --assert block! = scan/fast "[]" --test-- "scan-f10" --assert paren! = scan/fast "()" --test-- "scan-f11" --assert map! = scan/fast "#()" @@ -610,7 +610,7 @@ Red [ prescan path! word! 1 6x7 open path! datatype! 1 6x6 load word! datatype! 1 b - prescan error! word! 1 8x8 + prescan error! datatype! 1 8x8 error error! datatype! 1 8x8 prescan block! word! 1 9x9 open block! datatype! 1 9x9 @@ -631,7 +631,7 @@ Red [ prescan path! word! 1 6x7 open path! datatype! 1 6x6 load word! datatype! 1 b - prescan error! word! 1 8x8 + prescan error! datatype! 1 8x8 error error! datatype! 1 8x8 prescan word! datatype! 1 9x10 scan word! word! 1 9x10 @@ -686,12 +686,12 @@ Red [ --test-- "tt-5" clear logs - --assert [hello 3.14 pi world] == transcode/trace "hello ^/\ 3.14 pi world" :lex-logger + --assert [hello 3.14 pi world] == transcode/trace "hello ^/\ 3.14 pi world" :lex-logger --assert logs = [ prescan word! datatype! 1 1x6 scan word! word! 1 1x6 load word! datatype! 1 hello - prescan error! word! 2 8x8 + prescan error! datatype! 2 8x8 error error! datatype! 2 8x8 prescan float! datatype! 2 10x14 scan float! word! 2 10x14 diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index a15ad2406c..daa9b6ffda 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -71,7 +71,7 @@ context [ S_PATH_SIGN TYPE_WORD ;-- 55 --EXIT_STATES-- - ;-- 56 T_EOF - ;-- 57 - T_ERROR - ;-- 58 + T_ERROR TYPE_ERROR ;-- 58 T_BLK_OP - ;-- 59 T_BLK_CL - ;-- 60 T_PAR_OP - ;-- 61 From feb712c32e809cfcf7212a0d5048f0c1bbfa88fd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 18:16:46 +0100 Subject: [PATCH 1002/3432] FEAT: refactor subtraction --- runtime/datatypes/money.reds | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 6827a9b1fc..c32a369415 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -442,7 +442,7 @@ money: context [ minuend-sign subtrahend-sign sign index borrow left right difference [integer!] - lesser? + lesser? flag [logic!] ][ ;@@ TBD: take currencies into account @@ -458,22 +458,20 @@ money: context [ SIGN_+0 [return minuend] SIGN_-+ [return negate-money add-money absolute-money minuend absolute-money subtrahend] SIGN_+- [return add-money minuend absolute-money subtrahend] - - SIGN_-- [ + default [ lesser?: negative? compare-money minuend subtrahend sign: as integer! lesser? - minuend: absolute-money minuend - subtrahend: absolute-money subtrahend - - unless lesser? [SWAP_ARGUMENTS(minuend subtrahend)] - ] - - SIGN_++ [ - lesser?: negative? compare-money minuend subtrahend - sign: as integer! lesser? + DISPATCH_SIGNS(minuend-sign subtrahend-sign)[ + SIGN_++ [flag: lesser?] + SIGN_-- [ + minuend: absolute-money minuend + subtrahend: absolute-money subtrahend + flag: not lesser? + ] + ] - if lesser? [SWAP_ARGUMENTS(minuend subtrahend)] + if flag [SWAP_ARGUMENTS(minuend subtrahend)] ] ] From b464878c9646dcc8716b0eef4bf96f29f7e8a2e1 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 18:22:38 +0100 Subject: [PATCH 1003/3432] FIX: properly return math result on the stack Since some of the math operators swap the arguments, we cannot know which of the two value slots serves as an 'accumulator' for the result. A workaround for that is to copy value returned from math-related function into the bottommost stack slot via STACK/SET-LAST. --- runtime/datatypes/money.reds | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index c32a369415..14ecf421e9 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -391,8 +391,6 @@ money: context [ index carry left right sum [integer!] ][ - ;@@ TBD: take currencies into account - augend-sign: sign? augend addend-sign: sign? addend @@ -445,8 +443,6 @@ money: context [ lesser? flag [logic!] ][ - ;@@ TBD: take currencies into account - minuend-sign: sign? minuend subtrahend-sign: sign? subtrahend @@ -501,10 +497,13 @@ money: context [ left [red-money!] right [red-money!] op [integer!] - return: [red-money!] + return: [red-value!] /local - int [red-integer!] + int [red-integer!] + result [red-money!] ][ + ;@@ TBD: take currencies into account + switch TYPE_OF(right) [ TYPE_MONEY [0] TYPE_INTEGER [ @@ -517,18 +516,19 @@ money: context [ ] ] - switch op [ - OP_ADD [return add-money left right] - OP_SUB [return subtract-money left right] + result: switch op [ + OP_ADD [add-money left right] + OP_SUB [subtract-money left right] OP_MUL OP_DIV - OP_REM [--NOT_IMPLEMENTED--] + OP_REM [--NOT_IMPLEMENTED-- left] default [ fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] + left ] ] - left + SET_RETURN(result) ] ;-- Actions -- @@ -657,13 +657,11 @@ money: context [ /local left [red-money!] right [red-money!] - result [red-money!] ][ left: as red-money! stack/arguments right: left + 1 - result: do-math left right OP_ADD - SET_RETURN(result) + do-math left right OP_ADD ] subtract: func [ @@ -671,13 +669,11 @@ money: context [ /local left [red-money!] right [red-money!] - result [red-money!] ][ left: as red-money! stack/arguments right: left + 1 - result: do-math left right OP_SUB - SET_RETURN(result) + do-math left right OP_SUB ] multiply: STUB From 00506ffb7e17986df28049ad011f1b358e5cacbf Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 27 Feb 2020 18:38:05 +0100 Subject: [PATCH 1004/3432] FIX: non-passing lexer test "scan-f13". --- environment/system.red | 2 +- runtime/lexer-transitions.reds | 40 +++++++++++++++---------------- runtime/lexer.reds | 10 ++++---- tests/source/units/lexer-test.red | 12 ++++++---- utils/generate-lexer-table.red | 10 ++++---- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/environment/system.red b/environment/system.red index c6d6231c78..87da2b76a4 100644 --- a/environment/system.red +++ b/environment/system.red @@ -406,7 +406,7 @@ system: context [ exit-states: [ eof error! block! block! paren! paren! string! string! map! path! any-type! - comment integer! word! refinement! char! issue! string! file! binary! percent! + comment string! word! issue! integer! refinement! char! file! binary! percent! float! float! tuple! date! pair! time! money! tag! url! email! hex ] ] diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a9b2cd597f..88ed3877a1 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -71,12 +71,12 @@ Red/System [ T_PATH T_CONS_MK T_CMT - T_INTEGER + T_STRING T_WORD + T_ISSUE + T_INTEGER T_REFINE T_CHAR - T_ISSUE - T_STRING T_FILE T_BINARY T_PERCENT @@ -95,12 +95,12 @@ Red/System [ type-table: #{ 0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000220000000000 -07000000000B0F130A14070829260C0C272F252B332C092D0B +0700000000070F140B130A0829260C0C272F252B332C092D0B } transitions: #{ 000014143B3C3D3E3F3A020D2D2D2E2E2E2E232E230B3A262E2E063A013A2B20 2A2A3A2E2E3A3901440101010101010101010101010101010101010101010101 -0101010101010101010101013A39020202020202020202024A02020202020202 +0101010101010101010101013A39020202020202020202024502020202020202 020202020202020202020202020202020302023A3A0202020202020202020202 02020202020202020202020202020202020202020202020202023A3904040404 040404043F400404040404040404040404040404040404040404040404040504 @@ -111,19 +111,19 @@ Red/System [ 3A3A3A3A3A3A3A3A3A090909093A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A07 0707073A3A3A3A3A3A3A3A3A3A3A3A3A090907073A3A3A3A3A3A3A3A3A3A3A3A 3A3A3A3A3A4B0A0A0A0A0A0A0A0A0A0A4B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A3A3A47470B0B474747474747470B0B0B0B0B0B0B0B -0B0B0C0B0B0B0B0B0B47470B0B0B0B0B0B0B3A4746462E2E464646464646463A -2E2E2E2E2E2E2E2E2E0C2E2E2E2E3A2E46462E3A2E2E2E2E2E3A464949131312 -3A413A0E3A1013133A1313131313131313133A3A3A133A494913131313131313 -3A490E0E0E0E3A3A3A3A3A4C3A3A3A3A0E0E0E0E0E0E0E0E3A3A3A0E3A3A0F3A +0A0A0A0A0A0A0A0A0A0A0A3A3A49490B0B494949494949490B0B0B0B0B0B0B0B +0B0B0C0B0B0B0B0B0B49490B0B0B0B0B0B0B3A4946462E2E464646464646463A +2E2E2E2E2E2E2E2E2E0C2E2E2E2E3A2E46462E3A2E2E2E2E2E3A464747131312 +3A413A0E3A1013133A1313131313131313133A3A3A133A474713131313131313 +3A470E0E0E0E3A3A3A3A3A4C3A3A3A3A0E0E0E0E0E0E0E0E3A3A3A0E3A3A0F3A 3A3A0E3A3A3A0E3A3A0F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F3A3910101010101010101010481010101010 -1010101010101010101010101010101010101110103A48101010101010101010 +0F0F0F0F0F0F0F0F0F0F0F0F0F0F3A39101010101010101010104A1010101010 +1010101010101010101010101010101010101110103A4A101010101010101010 101010101010101010101010101010101010101010101010101010103A3A1212 1212124312121212121212121212121212121212121212121212121212121212 -1212123A3A494913134949494949494913131313131313131313131313131313 -134949131313131313133A4945451414454545454545450D141C1E1B2517183A -231B3A453A3A4D154531153A3A1B3A3A3A3A454E4E16164E4E4E4E4E4E4E1916 +1212123A3A474713134747474747474713131313131313131313131313131313 +134747131313131313133A4748481414484848484848480D141C1E1B2517183A +231B3A483A3A4D154831153A3A1B3A3A3A3A484E4E16164E4E4E4E4E4E4E1916 3A1E3A3A17173A3A4E3A4E3A3A4D3A4E3A3A3A3A3A3A3A3A3A4E4E4E16164E4E 4E4E4E4E4E3A3A4E1E3A3A17173A3A4E3A4E3A3A4D3A3A311A3A3A3A3A3A3A3A 4E4E4E17174E4E4E4E4E4E4E3A3A4E3A3A3A3A3A3A3A4E3A4E3A3A3A3A3A313A @@ -160,11 +160,11 @@ Red/System [ 30303030303056563A3030565630303A30303A30303A56575731315757575757 57573A3A3A313131313131315757573A3A313A573A313A31313A31313A573A3A 33333A3A3D3E3A3A02363434353535353535353A3A2635353A3A3A31353A3737 -3A35353A3A45453333454545454545453A14451E3A3A17173A3A453A453A3A4D -154531153A3A3A3A3A3A3A453A3A3A3A3A3A3A3A3A3A3A3A3A3A353535353535 +3A35353A3A48483333484848484848483A14481E3A3A17173A3A483A483A3A4D +154831153A3A3A3A3A3A3A483A3A3A3A3A3A3A3A3A3A3A3A3A3A353535353535 353A3A3535353A3A3A3A353A35353A35353A3A46463535464646464646463A35 -463535353535353546463535353A3A4631353A35353535353A4649491313123A -3A3A3A3A1013133A1313131313131313133A3A3A133A4949131313131313133A -4946463333464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E3A2E462E2E +463535353535353546463535353A3A4631353A35353535353A4647471313123A +3A3A3A3A1013133A1313131313131313133A3A3A133A4747131313131313133A +4746463333464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E3A2E462E2E 2E2E2E3A2E2E3A46 } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 41891f8467..a1134ffc13 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1985,7 +1985,7 @@ lexer: context [ index: state - --EXIT_STATES-- do-scan: as scanner! scanners/index - if all [pscan? state < T_INTEGER][ + if all [pscan? state <= T_STRING][ catch LEX_ERR [do-scan lex s p flags no] err?: system/thrown = LEX_ERR system/thrown: 0 @@ -1997,7 +1997,7 @@ lexer: context [ ] if scan? [ ;-- Scanning stage -- load?: any [not one? ld?] - either state < T_INTEGER [ + either state < T_STRING [ catch LEX_ERR [do-scan lex s p flags ld?] ][ if any [not ld? all [events? lex/fun-evts and EVT_SCAN <> 0]][ @@ -2222,12 +2222,12 @@ lexer: context [ :scan-path-open null ;-- T_PATH :scan-construct null ;-- T_CONS_MK :scan-comment null ;-- T_CMT - null :load-integer ;-- T_INTEGER + :scan-string :load-string ;-- T_STRING :scan-word :load-word ;-- T_WORD + :scan-issue :load-word ;-- T_ISSUE + null :load-integer ;-- T_INTEGER null :load-refinement ;-- T_REFINE null :load-char ;-- T_CHAR - :scan-issue :load-word ;-- T_ISSUE - :scan-string :load-string ;-- T_STRING null :load-file ;-- T_FILE null :load-binary ;-- T_BINARY null :load-percent ;-- T_PERCENT diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 85f19c89fb..85913c79c9 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -540,11 +540,13 @@ Red [ --test-- "scan-29" --assert error! = scan ")" --test-- "scan-30" --assert error! = scan "#(" --test-- "scan-31" --assert error! = scan "{" - --test-- "scan-32" --assert block! = scan "[]" - --test-- "scan-33" --assert paren! = scan "()" - --test-- "scan-34" --assert map! = scan "#()" - --test-- "scan-35" --assert string! = scan "{}" - --test-- "scan-36" --assert string! = scan {""} + --test-- "scan-32" --assert error! = scan "}" + --test-- "scan-33" --assert block! = scan "[]" + --test-- "scan-34" --assert paren! = scan "()" + --test-- "scan-35" --assert map! = scan "#()" + --test-- "scan-36" --assert string! = scan "{}" + --test-- "scan-37" --assert string! = scan {""} + --test-- "scan-38" --assert word! = scan "a" ===end-group=== ===start-group=== "scan/fast" diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index daa9b6ffda..2f08da73bc 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -82,12 +82,12 @@ context [ T_PATH - ;-- 66 T_CONS_MK - ;-- 67 T_CMT - ;-- 68 - T_INTEGER TYPE_INTEGER ;-- 69 + T_STRING TYPE_STRING ;-- 69 T_WORD TYPE_WORD ;-- 70 - T_REFINE TYPE_REFINEMENT ;-- 71 - T_CHAR TYPE_CHAR ;-- 72 - T_ISSUE TYPE_ISSUE ;-- 73 - T_STRING TYPE_STRING ;-- 74 + T_ISSUE TYPE_ISSUE ;-- 71 + T_INTEGER TYPE_INTEGER ;-- 72 + T_REFINE TYPE_REFINEMENT ;-- 73 + T_CHAR TYPE_CHAR ;-- 74 T_FILE TYPE_FILE ;-- 75 T_BINARY TYPE_BINARY ;-- 76 T_PERCENT TYPE_PERCENT ;-- 77 From fe7823977e5e6a4b9fa10fdec2d1c8fc10454902 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic <nr@red-lang.org> Date: Thu, 27 Feb 2020 19:20:34 +0100 Subject: [PATCH 1005/3432] TESTS: more lexer tests for words and tags. --- tests/source/units/lexer-test.red | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 85913c79c9..81d888cdf8 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -352,6 +352,28 @@ Red [ --test-- "tr-32" --assert [a] == transcode #{610062} ; a^(NUL)b + --test-- "tr-33" + --assert [aa <title> ] == out: transcode "aa" + --assert word? out/1 + --assert tag? out/2 + --assert tag? out/3 + + --test-- "tr-34" + --assert [ 3] == out: transcode " 3" + --assert tag? out/1 + --assert integer? out/2 + + --test-- "tr-35" + --assert [ 3] == out: transcode " 3" + --assert tag? out/1 + --assert integer? out/2 + + --test-- "tr-36" + --assert (compose [3 < (to-word "a>")]) == out: transcode "3 < a>" + --assert integer? out/1 + --assert word? out/2 + --assert word? out/3 + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" @@ -480,6 +502,38 @@ Red [ --test-- "tro-95" --assert 2999999999.0 == transcode/one "2999999999" + --test-- "tro-96" + --assert (to-word "<<") == out: transcode/one "<<" + --assert word? :out + + --test-- "tro-97" + --assert (to-word "<<<") == out: transcode/one "<<<" + --assert word? :out + + --test-- "tro-98" + --assert (to-word ">>") == out: transcode/one ">>" + --assert word? :out + + --test-- "tro-99" + --assert (to-word ">>>") == out: transcode/one ">>>" + --assert word? :out + + --test-- "tro-100" + --assert (to-word "<<<<") == out: transcode/one "<<<<" + --assert word? :out + + --test-- "tro-101" + --assert (to-word "<=") == out: transcode/one "<=" + --assert word? :out + + --test-- "tro-102" + --assert (to-word ">=") == out: transcode/one ">=" + --assert word? :out + + --test-- "tro-103" + --assert (to-word "<>") == out: transcode/one "<>" + --assert word? :out + ===end-group=== ===start-group=== "transcode/next" From 85fe7f189795556cb434b28be17551448ba68616 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 27 Feb 2020 21:13:10 +0100 Subject: [PATCH 1006/3432] FEAT: organize definitions into sections --- runtime/datatypes/money.reds | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 14ecf421e9..b8efa17d22 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -15,6 +15,8 @@ Red/System [ money: context [ verbose: 0 + ;-- Base -- + #enum sizes! [ SIZE_BYTES: 11 SIZE_SCALE: 05 @@ -56,7 +58,7 @@ money: context [ INT32_MIN_AMOUNT: #{00000002147483648FFFFF} INT32_MAX_AMOUNT: #{00000002147483647FFFFF} - ;-- Support -- + ;-- Sign -- get-sign: func [ money [red-money!] @@ -92,6 +94,8 @@ money: context [ this + 1 << 4 or (that + 1) ] + ;-- Amount -- + get-amount: func [ money [red-money!] return: [byte-ptr!] @@ -131,6 +135,8 @@ money: context [ money ] + ;-- Digits -- + get-digit: func [ amount [byte-ptr!] index [integer!] @@ -184,6 +190,8 @@ money: context [ either zero? count [1][count] ] + ;-- Construction -- + make-at: func [ slot [red-value!] sign [integer!] @@ -224,6 +232,8 @@ money: context [ make-at stack/push* sign amount1 amount2 amount3 ] + ;-- Conversion -- + overflow?: func [ money [red-money!] return: [logic!] @@ -313,6 +323,8 @@ money: context [ money ] + + ;-- Comparison -- compare-money: func [ this [red-money!] @@ -365,6 +377,8 @@ money: context [ either as logic! get-sign money [-1][+1] ] ] + + ;-- Math -- absolute-money: func [ money [red-money!] @@ -427,6 +441,7 @@ money: context [ ] if as logic! carry [MONEY_OVERFLOW] + augend ] From 6e51bc1296a657bef167bd5f4951046175fa7f04 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 27 Feb 2020 22:14:00 +0100 Subject: [PATCH 1007/3432] FIX: prescanning was returning last value type from input instead of first one. --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a1134ffc13..60381f30f6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -2027,7 +2027,7 @@ lexer: context [ check-path-end lex s lex/in-pos flags load? ;-- lex/in-pos could have changed ] ] - if all [one? lex/scanned > 0 lex/entry <> S_PATH lex/entry <> S_M_STRING state <> T_PATH][ + if all [any [one? pscan?] lex/scanned > 0 lex/entry <> S_PATH lex/entry <> S_M_STRING state <> T_PATH][ slot: lex/tail - 1 if any [ lex/tail = lex/buffer From 25ec40e34fb64205445eae9e57192a0fe337bb47 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 00:24:39 +0100 Subject: [PATCH 1008/3432] FIX: regression on loading negative integers. --- runtime/lexer.reds | 12 +++++------- tests/source/units/lexer-test.red | 5 +++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 60381f30f6..988f93ce69 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1153,11 +1153,9 @@ lexer: context [ return 0 ] p: s - neg?: no - if flags and C_FLAG_SIGN <> 0 [ - neg?: s/1 = #"-" - p: p + 1 ;-- skip sign when present - ] + neg?: s/1 = #"-" + if neg? [p: p + 1] ;-- skip sign when present + either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers i: as-integer (p/1 - #"0") ][ @@ -1181,7 +1179,7 @@ lexer: context [ ] ] assert p = e - if any [o? neg? <> (as-logic i and 80000000h)][ + if any [o? i < 0][ len: as-integer e - s ;-- account for sign in len now either all [len = 11 zero? compare-memory s min-integer len][ i: 80000000h @@ -1190,7 +1188,7 @@ lexer: context [ ] ] if neg? [i: 0 - i] - lex/scanned: TYPE_INTEGER + ;lex/scanned: TYPE_INTEGER if load? [ cell: alloc-slot lex integer/make-at cell i diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 81d888cdf8..c3473a5ad1 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -534,6 +534,9 @@ Red [ --assert (to-word "<>") == out: transcode/one "<>" --assert word? :out + --test-- "tro-104" --assert 123 == transcode/one "123" + --test-- "tro-105" --assert -123 == transcode/one "-123" + ===end-group=== ===start-group=== "transcode/next" @@ -601,6 +604,8 @@ Red [ --test-- "scan-36" --assert string! = scan "{}" --test-- "scan-37" --assert string! = scan {""} --test-- "scan-38" --assert word! = scan "a" + --test-- "scan-39" --assert integer! = scan "123" + --test-- "scan-40" --assert integer! = scan "-123" ===end-group=== ===start-group=== "scan/fast" From f8a76817c87ab28cb6bde6f545bcb88d6dfbb194 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 00:38:50 +0100 Subject: [PATCH 1009/3432] TESTS: removes duplicated test. --- tests/source/units/lexer-test.red | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index c3473a5ad1..997da510d3 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -379,6 +379,7 @@ Red [ --test-- "tro-1" --assert 8 == transcode/one "8" --test-- "tro-1.1" --assert 8 == transcode/one "8 " --test-- "tro-2" --assert 123 == transcode/one "123" + --test-- "tro-2.1" --assert -123 == transcode/one "-123" --test-- "tro-3" --assert 123 == transcode/one " 123 " --test-- "tro-4" --assert 8 == transcode/one " ;hello^/ 8" --test-- "tro-5" --assert 'Hello == transcode/one "Hello" @@ -534,9 +535,6 @@ Red [ --assert (to-word "<>") == out: transcode/one "<>" --assert word? :out - --test-- "tro-104" --assert 123 == transcode/one "123" - --test-- "tro-105" --assert -123 == transcode/one "-123" - ===end-group=== ===start-group=== "transcode/next" From bd53186b361992bc185dca7d2274efb0daa8a8a1 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 28 Feb 2020 10:19:31 +0800 Subject: [PATCH 1010/3432] FIX: crashes in move-test. --- runtime/hashtable.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index 0fd5ccf9b5..fc323bac59 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1198,7 +1198,7 @@ _hashtable: context [ part: part + 1 ] ][ ;-- may need to expand indexes - if size + head << 2 > s/size [ + if size + head + offset << 2 > s/size [ s: expand-series-filled s s/size << 1 #"^(FF)" indexes: as int-ptr! s/offset s/tail: as cell! (as byte-ptr! s/offset) + s/size From 2be99806f6c3e38bbe00a2f7942612ba2068e657 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 28 Feb 2020 11:05:01 +0800 Subject: [PATCH 1011/3432] FIX: git action doesn't report error properly. --- .github/workflows/main.yml | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e0f1c770d0..a4045836bb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,9 +15,7 @@ jobs: $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - name: run view test - run: | - rebview.exe -qws tests\run-core-tests.r --batch - rebview.exe -qws system\tests\run-all.r --batch + run: rebview.exe -qws tests\run-core-tests.r --batch shell: cmd - uses: actions/upload-artifact@v1 @@ -80,9 +78,7 @@ jobs: $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - name: run view test - run: | - rebview.exe -qws tests\run-all.r --each - rebview.exe -qws system\tests\run-all.r --each + run: rebview.exe -qws tests\run-all.r --each shell: cmd - uses: actions/upload-artifact@v1 @@ -90,3 +86,24 @@ jobs: with: name: each-test-log path: quick-test/quick-test.log + + Red-System-Test: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run view test + run: rebview.exe -qws system\tests\run-all.r --each + shell: cmd + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: rs-test-log + path: quick-test/quick-test.log \ No newline at end of file From 4ca83eca266b07aa8c8d1a5f4863f5e4eecbf16a Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 28 Feb 2020 12:54:50 +0800 Subject: [PATCH 1012/3432] TESTS: add debug mode tests in github action. --- .github/workflows/main.yml | 52 ++++++++++++++++++++++++++++++++++---- quick-test/quick-test.r | 11 ++++---- tests/run-all.r | 10 +++++--- tests/run-core-tests.r | 10 +++++--- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a4045836bb..32a3204d01 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: $url = "http://static.red-lang.org/build/rebview.exe" $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - - name: run view test + - name: run core test run: rebview.exe -qws tests\run-core-tests.r --batch shell: cmd @@ -24,6 +24,27 @@ jobs: name: core-test-log path: quick-test/quick-test.log + Core-Debug: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run core test + run: rebview.exe -qws tests\run-core-tests.r --batch --debug + shell: cmd + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: core-test-log + path: quick-test/quick-test.log + View: runs-on: windows-latest @@ -77,8 +98,29 @@ jobs: $url = "http://static.red-lang.org/build/rebview.exe" $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - - name: run view test - run: rebview.exe -qws tests\run-all.r --each + - name: run each test + run: rebview.exe -qws tests\run-core-tests.r --ci-each + shell: cmd + + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: each-test-log + path: quick-test/quick-test.log + + Each-Mode-Debug: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: setup red repo + run: | + $url = "http://static.red-lang.org/build/rebview.exe" + $output = "$Env:GITHUB_WORKSPACE\rebview.exe" + (New-Object System.Net.WebClient).DownloadFile($url, $output) + - name: run each test + run: rebview.exe -qws tests\run-core-tests.r --ci-each --debug shell: cmd - uses: actions/upload-artifact@v1 @@ -98,8 +140,8 @@ jobs: $url = "http://static.red-lang.org/build/rebview.exe" $output = "$Env:GITHUB_WORKSPACE\rebview.exe" (New-Object System.Net.WebClient).DownloadFile($url, $output) - - name: run view test - run: rebview.exe -qws system\tests\run-all.r --each + - name: run Red/System test + run: rebview.exe -qws system\tests\run-all.r --batch shell: cmd - uses: actions/upload-artifact@v1 diff --git a/quick-test/quick-test.r b/quick-test/quick-test.r index 173e81843c..fcf2e1c509 100644 --- a/quick-test/quick-test.r +++ b/quick-test/quick-test.r @@ -102,7 +102,8 @@ qt: make object! [ exe: none ;; filepath to executable source-file?: true ;; true = running test file ;; false = runnning test script - + compile-flag: copy " " + summary-template: ".. - .................................................. / " @@ -201,18 +202,18 @@ qt: make object! [ ;; red/system or red red?: false parse read src red?-rule - + ;; compose and write compilation script either binary-compiler? [ if #"/" <> first src [src: tests-dir/:src] ;; relative path supplied either lib [ - cmd: join "" [to-local-file bin-compiler " -o " + cmd: join "" [to-local-file bin-compiler compile-flag " -o " to-local-file runnable-dir/:exe " -dlib -t " target " " to-local-file src ] ][ - cmd: join "" [to-local-file bin-compiler " -o " + cmd: join "" [to-local-file bin-compiler compile-flag " -o " to-local-file runnable-dir/:exe " " to-local-file src ] @@ -224,7 +225,7 @@ qt: make object! [ REBOL [] halt: :quit echo (comp-echo) - do/args (reduce base-dir/red.r) (join " -o " [ + do/args (reduce base-dir/red.r) (join "" [compile-flag " -o " reduce runnable-dir/:exe " ###lib###***src***" ]) echo none diff --git a/tests/run-all.r b/tests/run-all.r index 2dda9b0671..73a31388e9 100644 --- a/tests/run-all.r +++ b/tests/run-all.r @@ -7,11 +7,13 @@ REBOL [ ] ;; should we run non-interactively? -each-mode: batch-mode: no +each-mode: batch-mode: ci-each: debug-mode: no if args: any [system/script/args system/options/args][ batch-mode: find args "--batch" each-mode: find args "--each" + ci-each: find args "--ci-each" + debug-mode: find args "--debug" ] ;; supress script messages @@ -29,6 +31,8 @@ print ["REBOL " system/version] start-time: now/precise print ["This test started at" start-time] +if debug-mode [qt/compile-flag: " -d "] + qt/script-header: "Red []" --setup-temp-files @@ -38,7 +42,7 @@ qt/script-header: "Red []" do %source/units/run-pre-extra-tests.r ===start-group=== "Main Red Tests" - either each-mode [ + either any [each-mode ci-each][ do %source/units/auto-tests/run-each-comp.r do %source/units/auto-tests/run-each-interp.r ][ @@ -69,7 +73,7 @@ end-time: now/precise print [" in" difference end-time start-time newline] print ["The test finished at" end-time] system/options/quiet: store-quiet-mode -either batch-mode [ +either any [batch-mode ci-each][ quit/return either qt/test-run/failures > 0 [1] [0] ][ print ["The test output was logged to" qt/log-file] diff --git a/tests/run-core-tests.r b/tests/run-core-tests.r index 59f9c21ae1..f5d0155af8 100644 --- a/tests/run-core-tests.r +++ b/tests/run-core-tests.r @@ -7,11 +7,13 @@ REBOL [ ] ;; should we run non-interactively? -each-mode: batch-mode: no +each-mode: batch-mode: ci-each: debug-mode: no if args: any [system/script/args system/options/args][ batch-mode: find args "--batch" each-mode: find args "--each" + ci-each: find args "--ci-each" + debug-mode: find args "--debug" ] ;; supress script messages @@ -29,6 +31,8 @@ print ["REBOL " system/version] start-time: now/precise print ["This test started at" start-time] +if debug-mode [qt/compile-flag: " -d "] + qt/script-header: "Red []" --setup-temp-files @@ -38,7 +42,7 @@ qt/script-header: "Red []" do %source/units/run-pre-extra-tests.r ===start-group=== "Main Red Tests" - either each-mode [ + either any [each-mode ci-each][ do %source/units/auto-tests/run-each-comp.r do %source/units/auto-tests/run-each-interp.r ][ @@ -57,7 +61,7 @@ end-time: now/precise print [" in" difference end-time start-time newline] print ["The test finished at" end-time] system/options/quiet: store-quiet-mode -either batch-mode [ +either any [batch-mode ci-each][ quit/return either qt/test-run/failures > 0 [1] [0] ][ print ["The test output was logged to" qt/log-file] From 2b42ea4e6db17b99d92330a4f6290f496431cf1d Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 28 Feb 2020 15:03:00 +0800 Subject: [PATCH 1013/3432] FIX: regression on loading +1 --- runtime/lexer.reds | 2 +- tests/run-core-tests.r | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 988f93ce69..0b58873c5c 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1154,7 +1154,7 @@ lexer: context [ ] p: s neg?: s/1 = #"-" - if neg? [p: p + 1] ;-- skip sign when present + if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign when present either (as-integer e - p) = 1 [ ;-- fast path for 1-digit integers i: as-integer (p/1 - #"0") diff --git a/tests/run-core-tests.r b/tests/run-core-tests.r index f5d0155af8..443be24d2b 100644 --- a/tests/run-core-tests.r +++ b/tests/run-core-tests.r @@ -31,13 +31,17 @@ print ["REBOL " system/version] start-time: now/precise print ["This test started at" start-time] -if debug-mode [qt/compile-flag: " -d "] +info: "" +if debug-mode [ + qt/compile-flag: " -d " + info: " (Debug Mode)" +] qt/script-header: "Red []" --setup-temp-files -***start-run-quiet*** "Red Test Suite" +***start-run-quiet*** join "Red Test Suite" info do %source/units/run-pre-extra-tests.r From bc001faaa08441ba81a6b73dd9cb5df2c435e08f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 12:19:49 +0100 Subject: [PATCH 1014/3432] TESTS: adds more passing float loading tests. --- tests/source/units/lexer-test.red | 49 +++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 997da510d3..80e7f7e6bd 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -380,6 +380,7 @@ Red [ --test-- "tro-1.1" --assert 8 == transcode/one "8 " --test-- "tro-2" --assert 123 == transcode/one "123" --test-- "tro-2.1" --assert -123 == transcode/one "-123" + --test-- "tro-2.2" --assert 123 == transcode/one "+123" --test-- "tro-3" --assert 123 == transcode/one " 123 " --test-- "tro-4" --assert 8 == transcode/one " ;hello^/ 8" --test-- "tro-5" --assert 'Hello == transcode/one "Hello" @@ -484,7 +485,6 @@ Red [ --test-- "tro-80" --assert error? try [transcode/one {#"ab"}] - --test-- "tro-81" --assert 1.2.3 == transcode/one "1.2.3" --test-- "tro-82" --assert 11.22.33 == transcode/one "11.22.33" --test-- "tro-83" --assert 255.255.255 == transcode/one "255.255.255" --test-- "tro-84" --assert error? try [transcode/one "256.255.255"] @@ -535,6 +535,16 @@ Red [ --assert (to-word "<>") == out: transcode/one "<>" --assert word? :out + --test-- "tro-104" --assert 1.0 == transcode/one "1.0" + --test-- "tro-105" --assert 123.0 == transcode/one "123.0" + --test-- "tro-106" --assert 1.0 == transcode/one "+1.0" + --test-- "tro-107" --assert -1.0 == transcode/one "-1.0" + --test-- "tro-108" --assert -123.0 == transcode/one "-123.0" + --test-- "tro-109" --assert 123.0 == transcode/one "+123.0" + --test-- "tro-110" --assert -123.0 == transcode/one "-123." + --test-- "tro-111" --assert 123.0 == transcode/one "123." + --test-- "tro-112" --assert 0.5 == transcode/one ".5" + ===end-group=== ===start-group=== "transcode/next" @@ -602,8 +612,23 @@ Red [ --test-- "scan-36" --assert string! = scan "{}" --test-- "scan-37" --assert string! = scan {""} --test-- "scan-38" --assert word! = scan "a" - --test-- "scan-39" --assert integer! = scan "123" - --test-- "scan-40" --assert integer! = scan "-123" + --test-- "scan-39" --assert error! = scan "[a" + --test-- "scan-40" --assert error! = scan "(a" + --test-- "scan-41" --assert block! = scan "[a]" + --test-- "scan-42" --assert paren! = scan "(a)" + --test-- "scan-43" --assert block! = scan "[a 123]" + --test-- "scan-44" --assert paren! = scan "(a 123)" + --test-- "scan-45" --assert integer! = scan "123" + --test-- "scan-46" --assert integer! = scan "-123" + --test-- "scan-47" --assert float! == scan "1.0" + --test-- "scan-48" --assert float! == scan "123.0" + --test-- "scan-49" --assert float! == scan "+1.0" + --test-- "scan-50" --assert float! == scan "-1.0" + --test-- "scan-51" --assert float! == scan "-123.0" + --test-- "scan-52" --assert float! == scan "+123.0" + --test-- "scan-53" --assert float! == scan "-123." + --test-- "scan-54" --assert float! == scan "123." + --test-- "scan-55" --assert float! == scan ".5" ===end-group=== ===start-group=== "scan/fast" @@ -622,6 +647,24 @@ Red [ --test-- "scan-f12" --assert string! = scan/fast "{}" --test-- "scan-f13" --assert string! = scan/fast {""} + --test-- "scan-39" --assert error! = scan/fast "[a" + --test-- "scan-40" --assert error! = scan/fast "(a" + --test-- "scan-41" --assert block! = scan/fast "[a]" + --test-- "scan-42" --assert paren! = scan/fast "(a)" + --test-- "scan-43" --assert block! = scan/fast "[a 123]" + --test-- "scan-44" --assert paren! = scan/fast "(a 123)" + --test-- "scan-45" --assert integer! = scan/fast "123" + --test-- "scan-46" --assert integer! = scan/fast "-123" + --test-- "scan-47" --assert float! == scan/fast "1.0" + --test-- "scan-48" --assert float! == scan/fast "123.0" + --test-- "scan-49" --assert float! == scan/fast "+1.0" + --test-- "scan-50" --assert float! == scan/fast "-1.0" + --test-- "scan-51" --assert float! == scan/fast "-123.0" + --test-- "scan-52" --assert float! == scan/fast "+123.0" + --test-- "scan-53" --assert float! == scan/fast "-123." + --test-- "scan-54" --assert float! == scan/fast "123." + --test-- "scan-55" --assert float! == scan/fast ".5" + ===end-group=== ===start-group=== "transcode/trace" From fb0cc831ea159865170d26363d0ab8ed8295cea1 Mon Sep 17 00:00:00 2001 From: loziniak Date: Fri, 28 Feb 2020 14:36:08 +0100 Subject: [PATCH 1015/3432] FEAT: random/secure --- environment/actions.red | 2 +- runtime/datatypes/date.reds | 16 +++++++++++++--- runtime/datatypes/float.reds | 9 +++++++-- runtime/datatypes/integer.reds | 2 +- runtime/datatypes/logic.reds | 2 +- runtime/datatypes/pair.reds | 4 ++-- runtime/datatypes/series.reds | 4 ++-- runtime/datatypes/tuple.reds | 4 +++- runtime/random.reds | 10 ++++++++++ runtime/red.reds | 2 +- 10 files changed, 41 insertions(+), 14 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index 8694f4f741..f59b974b02 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -25,7 +25,7 @@ random: make action! [[ "Returns a random value of the same datatype; or shuffles series" value "Maximum value of result (modified when series)" /seed "Restart or randomize" - /secure "TBD: Returns a cryptographically secure random number" + /secure "Returns a cryptographically secure random number" /only "Pick a random value from a series" return: [any-type!] ] diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index cb447ddb79..50e9f673ae 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -735,10 +735,20 @@ date: context [ dt/header: TYPE_UNSET ][ time?: DATE_GET_TIME_FLAG(d) - dt/date: days-to-date _random/rand % date-to-days d DATE_GET_ZONE(d) time? + dt/date: days-to-date (either secure? [_random/rand-secure] [_random/rand]) + % date-to-days d DATE_GET_ZONE(d) time? if time? [ - dt/date: DATE_SET_ZONE(dt/date _random/rand) - s: (as-float _random/rand) / 2147483647.0 * 3600.0 + dt/date: either secure? [ + DATE_SET_ZONE(dt/date _random/rand-secure) + ] [ + DATE_SET_ZONE(dt/date _random/rand) + ] + s: either secure? [ + ((as-float _random/rand-secure) / 2147483647.0 + (as-float _random/rand-secure)) + / (2147483648.0 / 3600.0) + ] [ + (as-float _random/rand) / 2147483647.0 * 3600.0 + ] s: (floor s) / 3600.0 dt/time: s * 24.0 * time/h-factor set-time dt dt/time yes diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 972f0549ce..8346e2a223 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -509,8 +509,13 @@ float: context [ _random/srand sp/1 xor sp/2 f/header: TYPE_UNSET ][ - s: (as-float _random/rand) / 2147483647.0 - f/value: s * f/value + either secure? [ + f/value: ((as-float _random/rand-secure) / 2147483647.0 + (as-float _random/rand-secure)) + / (2147483648.0 / f/value) + ] [ + s: (as-float _random/rand) / 2147483647.0 + f/value: s * f/value + ] ] f ] diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index ca1984af56..e8646f59d4 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -359,7 +359,7 @@ integer: context [ int/header: TYPE_UNSET ][ unless zero? int/value [ - n: _random/rand % int/value + 1 + n: (either secure? [_random/rand-secure] [_random/rand]) % int/value + 1 int/value: either negative? int/value [0 - n][n] ] ] diff --git a/runtime/datatypes/logic.reds b/runtime/datatypes/logic.reds index 1bc77c2f17..9fed94e463 100644 --- a/runtime/datatypes/logic.reds +++ b/runtime/datatypes/logic.reds @@ -171,7 +171,7 @@ logic: context [ _random/srand as-integer logic/value logic/header: TYPE_UNSET ][ - logic/value: _random/rand % 2 <> 0 + logic/value: (either secure? [_random/rand-secure] [_random/rand]) > 3FFFFFFFh ] logic ] diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index a8dd704293..7a127bf389 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -195,11 +195,11 @@ pair: context [ pair/header: TYPE_UNSET ][ unless zero? pair/x [ - n: _random/rand % pair/x + 1 + n: (either secure? [_random/rand-secure] [_random/rand]) % pair/x + 1 pair/x: either negative? pair/x [0 - n][n] ] unless zero? pair/y [ - n: _random/rand % pair/y + 1 + n: (either secure? [_random/rand-secure] [_random/rand]) % pair/y + 1 pair/y: either negative? pair/y [0 - n][n] ] ] diff --git a/runtime/datatypes/series.reds b/runtime/datatypes/series.reds index ffc4c5aa57..4d2debc12d 100644 --- a/runtime/datatypes/series.reds +++ b/runtime/datatypes/series.reds @@ -119,7 +119,7 @@ _series: context [ either only? [ either positive? size [ - idx: head + (_random/rand % size << (log-b unit)) + idx: head + ((either secure? [_random/rand-secure] [_random/rand]) % size << (log-b unit)) switch TYPE_OF(ser) [ TYPE_BLOCK TYPE_HASH @@ -148,7 +148,7 @@ _series: context [ len: size temp: as byte-ptr! :val while [size > 0][ - idx: head + (_random/rand % size << (log-b unit)) + idx: head + ((either secure? [_random/rand-secure] [_random/rand]) % size << (log-b unit)) if idx <> head [ copy-memory temp head unit copy-memory head idx unit diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index d9419c0632..36c60d6934 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -264,7 +264,9 @@ tuple: context [ n: 0 until [ n: n + 1 - array/n: as-byte _random/rand % ((as-integer array/n) + 1) + array/n: as-byte + (either secure? [_random/rand-secure] [_random/rand]) + % ((as-integer array/n) + 1) n = size ] ] diff --git a/runtime/random.reds b/runtime/random.reds index 1a150f0278..9f14bc30a6 100644 --- a/runtime/random.reds +++ b/runtime/random.reds @@ -88,6 +88,16 @@ _random: context [ state: state >> 18 xor state state ] + + rand-secure: func [ + return: [integer!] + /local + i [integer!] + ] [ + i: 0 + crypto/urandom (as byte-ptr! :i) 4 + i and 7FFFFFFFh ;-- range 0-2147483647 inclusive + ] init: does [ table: as int-ptr! allocate MT_RANDOM_STATE_SIZE * size? integer! diff --git a/runtime/red.reds b/runtime/red.reds index bde151a79e..99442117ae 100644 --- a/runtime/red.reds +++ b/runtime/red.reds @@ -115,8 +115,8 @@ red: context [ #include %actions.reds #include %natives.reds #include %parse.reds - #include %random.reds #include %crypto.reds + #include %random.reds #include %stack.reds #include %interpreter.reds #include %tokenizer.reds From a4eecca5961bbdb7edde5cdefa45a39c2ed9655d Mon Sep 17 00:00:00 2001 From: loziniak Date: Fri, 28 Feb 2020 15:23:41 +0100 Subject: [PATCH 1016/3432] FIX: a workaround for r/s 'either issue #3620 --- docs/red-system-specs.txt | 9 ++++++++- runtime/datatypes/date.reds | 9 ++++----- runtime/datatypes/tuple.reds | 6 +++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/red-system-specs.txt b/docs/red-system-specs.txt index 4faf4f21ac..4d088ea2e6 100644 --- a/docs/red-system-specs.txt +++ b/docs/red-system-specs.txt @@ -2147,7 +2147,14 @@ An alternative way to write it (allowed because all code paths return a value of ] prin ["a is " msg lf] - + +\note Known problems +EITHER should not be used as a part of expression, for example this gives incorrect result: + +print 1 * 1 + either 0 <> 0 [1][0] + +/note + ---loop Loop over a block of code, decrementing a counter down to zero. LOOP does not return any value, so it cannot be used in an expression. diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 50e9f673ae..8c8b232830 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -719,12 +719,10 @@ date: context [ return: [red-value!] /local d [integer!] - n [integer!] - dd [integer!] - tz [integer!] s [float!] d1 [integer!] time? [logic!] + rnd [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "date/random"]] @@ -735,8 +733,9 @@ date: context [ dt/header: TYPE_UNSET ][ time?: DATE_GET_TIME_FLAG(d) - dt/date: days-to-date (either secure? [_random/rand-secure] [_random/rand]) - % date-to-days d DATE_GET_ZONE(d) time? + + rnd: either secure? [_random/rand-secure] [_random/rand] ;-- a workaround for issue #3620 + dt/date: days-to-date rnd % (date-to-days d) DATE_GET_ZONE(d) time? if time? [ dt/date: either secure? [ DATE_SET_ZONE(dt/date _random/rand-secure) diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index 36c60d6934..af117875c5 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -251,6 +251,7 @@ tuple: context [ array [byte-ptr!] n [integer!] size [integer!] + rnd [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "tuple/random"]] @@ -263,10 +264,9 @@ tuple: context [ size: TUPLE_SIZE?(tp) n: 0 until [ + rnd: either secure? [_random/rand-secure] [_random/rand] n: n + 1 - array/n: as-byte - (either secure? [_random/rand-secure] [_random/rand]) - % ((as-integer array/n) + 1) + array/n: as-byte rnd % ((as-integer array/n) + 1) n = size ] ] From b180a31334e8dfda2191e7279c7ced431a8fd109 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 15:54:13 +0100 Subject: [PATCH 1017/3432] FEAT: adds money! scanning and value making call in lexer. --- runtime/lexer.reds | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 0b58873c5c..db64825f7a 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1854,9 +1854,31 @@ lexer: context [ if load? [time/make-at tm alloc-slot lex] ] - load-money: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ - ;;TBD: implement this function once money! type is done - throw-error lex s e ERR_BAD_CHAR + load-money: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + /local + do-error [subroutine!] + cur p [byte-ptr!] + neg? dec? [logic!] + ][ + do-error: [throw-error lex s e TYPE_MONEY] + p: s + neg?: p/1 = #"-" + if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign when present + cur: p + while [cur/1 <> #"$"][cur: cur + 1] ;-- cur is always < e + either p = cur [cur: null][ + if p + 3 <> cur [do-error] + p: cur + ] + assert p/1 = #"$" + p: p + 1 + dec?: no + while [p < e][ + if p/1 = #"." [if dec? [do-error] dec?: yes] + p: p + 1 + ] + lex/in-pos: e + 1 ;-- skip ending delimiter + ;if load? [money/make-at alloc-slot lex cur s e neg?] ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ From 0880e68700097d3e70239833c35a87ce6f7f0302 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 28 Feb 2020 17:14:08 +0100 Subject: [PATCH 1018/3432] FEAT: amend specs of math-related actions --- environment/actions.red | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index 8c83c7d099..8724cfbbbb 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -102,18 +102,18 @@ add: make action! [[ divide: make action! [[ "Returns the quotient of two values" - value1 [number! char! pair! tuple! vector! time!] "The dividend (numerator)" - value2 [number! char! pair! tuple! vector! time!] "The divisor (denominator)" - return: [number! char! pair! tuple! vector! time!] + value1 [number! money! char! pair! tuple! vector! time!] "The dividend (numerator)" + value2 [number! money! char! pair! tuple! vector! time!] "The divisor (denominator)" + return: [number! money! char! pair! tuple! vector! time!] "The quotient" ] #get-definition ACT_DIVIDE ] multiply: make action! [[ "Returns the product of two values" - value1 [number! char! pair! tuple! vector! time!] - value2 [number! char! pair! tuple! vector! time!] - return: [number! char! pair! tuple! vector! time!] + value1 [number! money! char! pair! tuple! vector! time!] "The multiplicand" + value2 [number! money! char! pair! tuple! vector! time!] "the multiplier" + return: [number! money! char! pair! tuple! vector! time!] "The product" ] #get-definition ACT_MULTIPLY ] @@ -137,9 +137,9 @@ power: make action! [[ remainder: make action! [[ "Returns what is left over when one value is divided by another" - value1 [number! char! pair! tuple! vector! time!] - value2 [number! char! pair! tuple! vector! time!] - return: [number! char! pair! tuple! vector! time!] + value1 [number! money! char! pair! tuple! vector! time!] "The dividend (numerator)" + value2 [number! money! char! pair! tuple! vector! time!] "The divisor (denominator)" + return: [number! money! char! pair! tuple! vector! time!] "The remainder" ] #get-definition ACT_REMAINDER ] From 6623601d8cf53751cace17b19714abdba610d666 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 28 Feb 2020 17:24:46 +0100 Subject: [PATCH 1019/3432] FEAT: pre-define remaining math-related actions --- runtime/datatypes/money.reds | 38 +++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b8efa17d22..a7a45d8140 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -691,9 +691,41 @@ money: context [ do-math left right OP_SUB ] - multiply: STUB - divide: STUB - remainder: STUB + multiply: func [ + return: [red-value!] + /local + left [red-money!] + right [red-money!] + ][ + left: as red-money! stack/arguments + right: left + 1 + + do-math left right OP_MUL + ] + + divide: func [ + return: [red-value!] + /local + left [red-money!] + right [red-money!] + ][ + left: as red-money! stack/arguments + right: left + 1 + + do-math left right OP_DIV + ] + + remainder: func [ + return: [red-value!] + /local + left [red-money!] + right [red-money!] + ][ + left: as red-money! stack/arguments + right: left + 1 + + do-math left right OP_REM + ] round: STUB From 49f1480274c68068561526804ec8cb0cd3e5f102 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 28 Feb 2020 17:30:33 +0100 Subject: [PATCH 1020/3432] FEAT: refactor 'same signs' case in subtraction --- runtime/datatypes/money.reds | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a7a45d8140..1f34096a90 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -473,13 +473,10 @@ money: context [ lesser?: negative? compare-money minuend subtrahend sign: as integer! lesser? - DISPATCH_SIGNS(minuend-sign subtrahend-sign)[ - SIGN_++ [flag: lesser?] - SIGN_-- [ - minuend: absolute-money minuend - subtrahend: absolute-money subtrahend - flag: not lesser? - ] + either positive? minuend-sign [flag: lesser?][ + minuend: absolute-money minuend + subtrahend: absolute-money subtrahend + flag: not lesser? ] if flag [SWAP_ARGUMENTS(minuend subtrahend)] From 8d8a1b599d90b1a626327a7318361f81a32417af Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 28 Feb 2020 17:31:32 +0100 Subject: [PATCH 1021/3432] FEAT: preliminary work on MULTIPLY action --- runtime/datatypes/money.reds | 114 ++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1f34096a90..57ec22cec9 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -48,6 +48,12 @@ money: context [ SIZE_DIGITS: SIZE_BYTES * 2 SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE + SIZE_UNNORM: SIZE_DIGITS + SIZE_SCALE + SIZE_BUFFER: (SIZE_UNNORM + (SIZE_UNNORM and 1)) >> 1 + + SIZE_SBYTES: (SIZE_BUFFER + size? integer!) - (SIZE_BUFFER // size? integer!) + SIZE_SSLOTS: SIZE_SBYTES >> 2 + HIGH_NIBBLE: #"^(0F)" LOW_NIBBLE: #"^(F0)" @@ -135,6 +141,32 @@ money: context [ money ] + shift-right: func [ + amount [byte-ptr!] + size [integer!] + offset [integer!] + return: [byte-ptr!] + /local + this that + [integer!] + half + [byte!] + ][ + loop offset [ + this: size + that: this - 1 + loop size [ + half: either that <= 0 [null-byte][amount/that << 4] + amount/this: amount/this >>> 4 or half + + this: this - 1 + that: that - 1 + ] + ] + + amount + ] + ;-- Digits -- get-digit: func [ @@ -505,6 +537,84 @@ money: context [ set-sign minuend sign ] + multiply-money: func [ + multiplicand [red-money!] + multiplier [red-money!] + return: [red-money!] + /local + left-amount right-amount product + [byte-ptr!] + multiplicand-sign multiplier-sign sign + left-count right-count + delta index1 index2 index3 + carry left right other prod + [integer!] + ][ + multiplicand-sign: sign? multiplicand + multiplier-sign: sign? multiplier + + DISPATCH_SIGNS(multiplicand-sign multiplier-sign)[ + SIGN_00 + SIGN_0- + SIGN_0+ [return multiplicand] + SIGN_+0 + SIGN_-0 [return multiplier] + default [sign: as integer! multiplicand-sign <> multiplier-sign] + ] + + left-amount: get-amount multiplicand + right-amount: get-amount multiplier + + left-count: count-digits left-amount + right-count: count-digits right-amount + + if (left-count + right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + + product: set-memory + as byte-ptr! system/stack/allocate SIZE_SSLOTS + null-byte + SIZE_SBYTES + + delta: SIZE_DIGITS - SIZE_BUFFER << 1 + index1: SIZE_DIGITS + + loop right-count [ + carry: 0 + index2: SIZE_DIGITS + + loop left-count [ + index3: index1 + index2 - delta + + left: get-digit left-amount index2 + right: get-digit right-amount index1 + other: get-digit product index3 + + prod: left * right + other + carry + carry: prod / 10 + prod: prod // 10 + + set-digit product index3 prod + + index2: index2 - 1 + ] + + set-digit product index3 - 1 carry + + index1: index1 - 1 + ] + + unless zero? get-digit product 1 [MONEY_OVERFLOW] + + ;@@ TBD: round to nearest, check underflow + shift-right product SIZE_SBYTES SIZE_SCALE + copy-memory + left-amount + product + SIZE_BUFFER - SIZE_BYTES + SIZE_BYTES + + set-sign multiplicand sign + ] + do-math: func [ left [red-money!] right [red-money!] @@ -531,7 +641,7 @@ money: context [ result: switch op [ OP_ADD [add-money left right] OP_SUB [subtract-money left right] - OP_MUL + OP_MUL [multiply-money left right] OP_DIV OP_REM [--NOT_IMPLEMENTED-- left] default [ @@ -762,7 +872,7 @@ money: context [ :absolute :add null;:divide - null;:multiply + :multiply :negate null ;power null;:remainder From 7a4ac7eec7129d856d96b940a1ed6da89d85ee1b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 28 Feb 2020 17:32:31 +0100 Subject: [PATCH 1022/3432] FEAT: preliminary support for literal MONEY! --- runtime/datatypes/money.reds | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 57ec22cec9..672e3903e4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -225,6 +225,17 @@ money: context [ ;-- Construction -- make-at: func [ + slot [red-value!] + currency [byte-ptr!] ; can be null + start [byte-ptr!] + end [byte-ptr!] + sign [logic!] ; true: negative + ; return: [red-money!] + ][ + 0 + ] + + make~at: func [ slot [red-value!] sign [integer!] amount1 [integer!] @@ -251,7 +262,7 @@ money: context [ amount3 [integer!] return: [red-money!] ][ - make-at ALLOC_TAIL(parent) sign amount1 amount2 amount3 + make~at ALLOC_TAIL(parent) sign amount1 amount2 amount3 ] push: func [ @@ -261,7 +272,7 @@ money: context [ amount3 [integer!] return: [red-money!] ][ - make-at stack/push* sign amount1 amount2 amount3 + make~at stack/push* sign amount1 amount2 amount3 ] ;-- Conversion -- From 53840d86d212a4af4baccc1e650bc05d69584b4e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 20:24:13 +0100 Subject: [PATCH 1023/3432] FEAT: preliminary support for loading raw strings. --- docs/lexer/lexer-FSM.csv | 14 ++- docs/lexer/lexer-FSM.xlsx | Bin 21398 -> 21951 bytes docs/lexer/lexer-states.txt | 21 ++++- environment/system.red | 2 +- runtime/lexer-transitions.reds | 156 +++++++++++++++++--------------- runtime/lexer.reds | 13 ++- utils/generate-lexer-table.red | 161 +++++++++++++++++---------------- 7 files changed, 204 insertions(+), 163 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index b3dd17ea17..94301d66f0 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -5,11 +5,15 @@ S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_L S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_HDPER_ST;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE -S_FILE_HEX1;S_FILE;S_FILE;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FILE +S_FILE_HEX1;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_FILE_HEX2;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR +S_HDPER_ST;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HERDOC_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR +S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR +S_HDPER_CL;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_ERROR;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;S_HDPER_CL;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH_N;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SLASH_N;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH_N;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;T_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE @@ -26,7 +30,7 @@ S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLO S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;T_ERROR;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE -S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_ERROR;S_DATE;T_ERROR;T_DATE +S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_ERROR;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;T_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME;T_ERROR;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TIME S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR @@ -41,7 +45,7 @@ S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_W S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR -S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD +S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_MONEY;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 88927fcb2ffe2fbe21be6aff14e18469b61d5af5..82336dc161fc7478d8a4d72a4198472d78bc5f28 100644 GIT binary patch delta 10512 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 G$^QfLP-egY delta 10224 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index a92065c8a7..0f453209a2 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -12,7 +12,10 @@ S_FILE S_FILE_HEX1 S_FILE_HEX2 S_FILE_STR -S_SKIP_FILE +S_HDPER_ST +S_HERDOC_ST +S_HDPER_C0 +S_HDPER_CL S_SLASH S_SHARP S_BINARY @@ -90,6 +93,7 @@ T_EMAIL T_PATH T_HEX T_CMT +T_RAWSTRING C_BLANK : space, tab, cr @@ -187,9 +191,18 @@ S_START->"%"->S_FILE_1ST->not(delimit8)->S_FILE->not(delimit1)->S_FILE \->dbl-quote->S_FILE_STR->not(dbl-quote)->S_FILE_STR \ \->dbl-quote->T_FILE \ - \->delimit8->T_WORD - - + \->"%"->S_HDPER_ST->"%"->S_HDPER_ST + \ \->"{"->S_HERDOC_ST + \ \->hexa->S_FILE_HEX2 + \ \->else->T_ERROR + \ + \->"{"->S_HERDOC_ST->"}"->S_HDPER_C0->"%"->S_HDPER_CL->"%"->S_HDPER_CL + \ \ \ \->else->T_RAWSTRING + \ \ \->else->S_HERDOC_ST + \ \->else->S_HERDOC_ST + \->delimit8->T_WORD + + S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY \ \->";"->S_LINE_CMT2->not(lf)->S_LINE_CMT2 \ \ \->lf->S_BINARY diff --git a/environment/system.red b/environment/system.red index 87da2b76a4..dbbb5bed44 100644 --- a/environment/system.red +++ b/environment/system.red @@ -407,7 +407,7 @@ system: context [ exit-states: [ eof error! block! block! paren! paren! string! string! map! path! any-type! comment string! word! issue! integer! refinement! char! file! binary! percent! - float! float! tuple! date! pair! time! money! tag! url! email! hex + float! float! tuple! date! pair! time! money! tag! url! email! hex rawstring ] ] diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 88ed3877a1..15bf397d2e 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -13,6 +13,10 @@ Red/System [ S_FILE_HEX1 S_FILE_HEX2 S_FILE_STR + S_HDPER_ST + S_HERDOC_ST + S_HDPER_C0 + S_HDPER_CL S_SLASH S_SLASH_N S_SHARP @@ -90,81 +94,87 @@ Red/System [ T_TAG T_URL T_EMAIL - T_HEX + T_HEX + T_RAWSTRING ] type-table: #{ -0000070707070808080808130F1429000A0A00140B0C0C0C0C0C272F2B2B2525 -3333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F0000220000000000 -0700000000070F140B130A0829260C0C272F252B332C092D0B +000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F +2B2B25253333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00002200 +000000000700000000070F140B130A0829260C0C272F252B332C092D0B07 } transitions: #{ -000014143B3C3D3E3F3A020D2D2D2E2E2E2E232E230B3A262E2E063A013A2B20 -2A2A3A2E2E3A3901440101010101010101010101010101010101010101010101 -0101010101010101010101013A39020202020202020202024502020202020202 -020202020202020202020202020202020302023A3A0202020202020202020202 -02020202020202020202020202020202020202020202020202023A3904040404 -040404043F400404040404040404040404040404040404040404040404040504 -043A3A0404040404040404040404040404040404040404040404040404040404 -04040404040404043A39464607074646464646460A0707460707070707070707 -0707070707074646070707070707073A464B4B07074B4B4B4B4B4B3A07074B07 -070707070707070707070708074B4B070707070707073A4B070709093A3A3A3A -3A3A3A3A3A3A3A3A3A090909093A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A07 -0707073A3A3A3A3A3A3A3A3A3A3A3A3A090907073A3A3A3A3A3A3A3A3A3A3A3A -3A3A3A3A3A4B0A0A0A0A0A0A0A0A0A0A4B0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A3A3A49490B0B494949494949490B0B0B0B0B0B0B0B -0B0B0C0B0B0B0B0B0B49490B0B0B0B0B0B0B3A4946462E2E464646464646463A -2E2E2E2E2E2E2E2E2E0C2E2E2E2E3A2E46462E3A2E2E2E2E2E3A464747131312 -3A413A0E3A1013133A1313131313131313133A3A3A133A474713131313131313 -3A470E0E0E0E3A3A3A3A3A4C3A3A3A3A0E0E0E0E0E0E0E0E3A3A3A0E3A3A0F3A -3A3A0E3A3A3A0E3A3A0F0E0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F0F0F0F0F0F0F0F0F0F0F3A39101010101010101010104A1010101010 -1010101010101010101010101010101010101110103A4A101010101010101010 -101010101010101010101010101010101010101010101010101010103A3A1212 -1212124312121212121212121212121212121212121212121212121212121212 -1212123A3A474713134747474747474713131313131313131313131313131313 -134747131313131313133A4748481414484848484848480D141C1E1B2517183A -231B3A483A3A4D154831153A3A1B3A3A3A3A484E4E16164E4E4E4E4E4E4E1916 -3A1E3A3A17173A3A4E3A4E3A3A4D3A4E3A3A3A3A3A3A3A3A3A4E4E4E16164E4E -4E4E4E4E4E3A3A4E1E3A3A17173A3A4E3A4E3A3A4D3A3A311A3A3A3A3A3A3A3A -4E4E4E17174E4E4E4E4E4E4E3A3A4E3A3A3A3A3A3A3A4E3A4E3A3A3A3A3A313A -3A17173A3A3A3A4E4E4E18184E4E4E4E4E4E4E3A3A4E3A3A253A233A234E3A4E -3A3A4D3A3A311A3A17173A3A3A3A4E4E4E4E4F4F4F4F4F4F4F4F194F4F191919 -191919194F4F4F19194F4F4F4F194F19194F19193A4F50501A1A505050505050 -503A3A503A3A3A3A3A3A3A503A503A3A3A3A3A3A1A3A3A3A3A3A3A3A5051511B -1B515151515151511B1B1B1B1B1B1B1B1B1B1B1B511B1B511B51511B511B1B51 -3A1B3A513A3A1D1D3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A -3A3A3A3A3A3A3A3A3A3A3A53531D1D535353535353533A3A1D3A3A3A3A3A3A3A -533A533A3A3A3A533A1D3A3A3A3A3A3A3A533A3A1F1F3A3A3A3A3A3A3A3A3A3A -3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A313A3A1F1F3A3A3A3A3A52521F1F525252 -525252523A3A523A3A3A1F1F3A3A523A523A3A3A3A52311F3A3A3A3A3A3A3A52 -3A3A21213A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A -3A3A3A3A3A3A3A54542121545454545454545421543A3A3A3A3A3A3A543A543A -3A3A3A543A223A3A3A3A3A3A3A3954542222545454545454545422543A3A3A3A -3A3A3A543A543A3A3A3A543A3A3A3A3A3A3A3A3A394646232346464646464646 -3A2E2F2E2E242E232E2342462E2E2E3A3A46312E212E2E2E2E2E3A4658582E2E -585858585858583A2E2F2E2E2E2E2E2E2E42582E2E2E3A3A58312E212E2E2E2E -2E3A5858583A3A585858585858583A3A3A3A3A3A3A3A3A3A4258583A3A3A3A58 -313A213A3A3A3A3A3A5846462727464646464646462727462727272727272727 -27262E2E272746462727272E2727273A46272727272727272727272827292727 -272727272727272727552727272727272727272727273A3A2828282828282828 -28282728282828282828282828282828282828282828282828282828283A3A29 -2929292929292929292929272929292929292929292929292929292929292929 -292929293A3A46461414464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E -3A2E462E2B2E2E2E3A2E2E3A4646462C2C464646464646463A2E2F2E2E2E2C2C -2E2E42462E2E2E3A3A46312E3A2C2C2E2E2E3A464E4E2C2C4E4E4E4E4E4E4E3A -3A4E1E3A3A2C2C3A3A4E3A4E3A3A4D3A3A3A3A3A2C2C3A3A3A3A4E3A3A3A3A3A -3A3A3A3A3A3A3A3A3A2E2E2E2E2E2E2E0B3A2E2E2E3A3A3A3A2E3A2E2E3A2E2E -3A3A46462E2E464646464646463A2E2F2E2E2E2E2E2E2E4246462E2E3A3A4631 -2E212E2E2E2E2E3A464646303046464646464646303030303030303030303046 -3A303030304630303030303030303A465656303056565656565656303A303030 -30303030303056563A3030565630303A30303A30303A56575731315757575757 -57573A3A3A313131313131315757573A3A313A573A313A31313A31313A573A3A -33333A3A3D3E3A3A02363434353535353535353A3A2635353A3A3A31353A3737 -3A35353A3A48483333484848484848483A14481E3A3A17173A3A483A483A3A4D -154831153A3A3A3A3A3A3A483A3A3A3A3A3A3A3A3A3A3A3A3A3A353535353535 -353A3A3535353A3A3A3A353A35353A35353A3A46463535464646464646463A35 -463535353535353546463535353A3A4631353A35353535353A4647471313123A -3A3A3A3A1013133A1313131313131313133A3A3A133A4747131313131313133A -4746463333464646464646463A3A2E2E2E2E2E2E2E2E2E463A2E2E3A2E462E2E -2E2E2E3A2E2E3A46 +000018183F404142433E02113131323232322732270F3E2A3232063E013E2F24 +2E2E3E32323E3D01480101010101010101010101010101010101010101010101 +0101010101010101010101013E3D020202020202020202024902020202020202 +020202020202020202020202020202020302023E3E0202020202020202020202 +02020202020202020202020202020202020202020202020202023E3D04040404 +0404040443440404040404040404040404040404040404040404040404040504 +043E3E0404040404040404040404040404040404040404040404040404040404 +04040404040404043E3D4A4A07074A4A4A4A0C4A0A07074A0707070707070707 +070707070B074A4A070707070707073E4A4F4F07074F4F4F4F4F4F3E07074F07 +070707070707070707070708074F4F070707070707073E4F3E3E09093E3E3E3E +3E3E3E3E3E3E3E3E3E090909093E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E +3E07073E3E3E3E3E3E3E3E3E3E3E3E3E090907073E3E3E3E3E3E3E3E3E3E3E3E +3E3E3E3E3E3E0A0A0A0A0A0A0A0A0A0A4F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A3E3E3E3E09093E3E3E3E3E0C3E3E3E3E3E3E3E0909 +09093E3E3E3E3E0B3E3E3E3E3E3E3E3E3E3E3E3E0C0C0C0C0C0C0C0C0C0D0C0C +0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C3E3E0C0C0C0C0C +0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0E0C0C0C0C0C0C0C0C0C0C +3E3E5D5D3E3E5D5D5D5D5D3E5D3E3E3E3E3E3E3E3E3E3E3E3E5D3E3E0E3E5D3E +3E3E3E3E3E3E3E3E5D4D4D0F0F4D4D4D4D4D4D4D0F0F0F0F0F0F0F0F0F0F100F +0F0F0F0F0F4D4D0F0F0F0F0F0F0F3E4D4A4A32324A4A4A4A4A4A4A3E32323232 +323232323210323232323E324A4A323E32323232323E4A4B4B1717163E453E12 +3E1417173E1717171717171717173E3E3E173E4B4B171717171717173E4B1212 +12123E3E3E3E3E503E3E3E3E12121212121212123E3E3E123E3E133E3E3E123E +3E3E123E3E131213131313131313131313131313131313131313131313131313 +131313131313131313133E3D141414141414141414144E141414141414141414 +14141414141414141414141414141514143E4E14141414141414141414141414 +1414141414141414141414141414141414141414141414143E3E161616161647 +161616161616161616161616161616161616161616161616161616161616163E +3E4B4B17174B4B4B4B4B4B4B17171717171717171717171717171717174B4B17 +1717171717173E4B4C4C18184C4C4C4C4C4C4C111820221F291B1C3E271F3E4C +3E3E51194C35193E3E1F3E3E3E3E4C52521A1A525252525252521D1A3E223E3E +1B1B3E3E523E523E3E513E523E3E3E3E3E3E3E3E3E5252521A1A525252525252 +523E3E52223E3E1B1B3E3E523E523E3E513E3E351E3E3E3E3E3E3E3E5252521B +1B525252525252523E3E523E3E3E3E3E3E3E523E523E3E3E3E3E353E3E1B1B3E +3E3E3E5252521C1C525252525252523E3E523E3E293E273E27523E523E3E513E +3E351E3E1B1B3E3E3E3E5252525253535353535353531D53531D1D1D1D1D1D1D +5353531D1D535353531D531D1D531D1D3E5354541E1E545454545454543E3E54 +3E3E3E3E3E3E3E543E543E3E3E3E3E3E1E3E3E3E3E3E3E3E5455551F1F555555 +555555551F1F1F1F1F1F1F1F1F1F1F1F551F1F3E1F55551F551F1F3E3E1F3E55 +3E3E21213E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E +3E3E3E3E3E3E3E57572121575757575757573E3E213E3E3E3E3E3E3E573E573E +3E3E3E573E213E3E3E3E3E3E3E573E3E23233E3E3E3E3E3E3E3E3E3E3E3E3E3E +3E3E3E3E3E3E3E3E3E3E3E353E3E23233E3E3E3E3E5656232356565656565656 +3E3E563E3E3E23233E3E563E563E3E3E3E5635233E3E3E3E3E3E3E563E3E2525 +3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E +3E3E3E58582525585858585858585825583E3E3E3E3E3E3E583E583E3E3E3E58 +3E263E3E3E3E3E3E3E3D58582626585858585858585826583E3E3E3E3E3E3E58 +3E583E3E3E3E583E3E3E3E3E3E3E3E3E3D4A4A27274A4A4A4A4A4A4A3E323332 +322832273227464A3232323E3E4A35322532323232323E4A5C5C32325C5C5C5C +5C5C5C3E323332323232323232465C3232323E3E5C35322532323232323E5C5C +5C3E3E5C5C5C5C5C5C5C3E3E3E3E3E3E3E3E3E3E465C5C3E3E3E3E5C353E253E +3E3E3E3E3E5C4A4A2B2B4A4A4A4A4A4A4A2B2B4A2B2B2B2B2B2B2B2B2B2A3232 +2B2B4A4A2B2B2B322B2B2B3E4A2B2B2B2B2B2B2B2B2B2B2C2B2D2B2B2B2B2B2B +2B2B2B2B2B592B2B2B2B2B2B2B2B2B2B2B2B3E3E2C2C2C2C2C2C2C2C2C2C2B2C +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C3E3E2D2D2D2D2D +2D2D2D2D2D2D2D2B2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D +3E3E4A4A18184A4A4A4A4A4A4A3E3E3232323232323232324A3E32323E324A32 +2F2532323E32323E4A4A4A30304A4A4A4A4A4A4A3E323332323230303232464A +3232323E3E4A35323E30303232323E4A52523030525252525252523E3E52223E +3E30303E3E523E523E3E513E3E3E3E3E30303E3E3E3E523E3E3E3E3E3E3E3E3E +3E3E3E3E3E323232323232320F3E3232323E3E3E3E323E32323E32323E3E4A4A +32324A4A4A4A4A4A4A3E323332323232323232464A4A32323E3E4A3532253232 +3232323E4A4A4A34344A4A4A4A4A4A4A34343434343434343434344A3E343434 +344A34343434343434343E4A5A5A34345A5A5A5A5A5A5A343E34343434343434 +34345A5A3E34345A5A34343E34343E34343E5A5B5B35355B5B5B5B5B5B5B3E3E +3E353535353535355B5B5B3E3E353E5B3E353E35353E35353E5B3E3E37373E3E +41423E3E023A3838393939393939393E3E2A39393E3E3E35393E3B3B3E39393E +3E4C4C37374C4C4C4C4C4C4C3E184C223E3E1B1B3E3E4C3E4C3E3E51194C3519 +3E3E3E3E3E3E3E4C3E3E3E3E3E3E3E3E3E3E3E3E3E3E393939393939393E3E39 +39393E3E3E3E393E39393E39393E3E4A4A39394A4A4A4A4A4A4A3E394A393939 +393939394A4A3939393E3E4A35393E39393939393E4A4B4B1717163E3E3E3E3E +1417173E1717171717171717173E3E3E173E4B4B171717171717173E4B4A4A37 +374A4A4A4A4A4A4A3E3E3232323232323232324A3E32323E324A32323232323E +32323E4A } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index db64825f7a..bc98b49409 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -106,7 +106,7 @@ lexer: context [ skip-table: #{ 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000 } path-ending: #{ @@ -1946,6 +1946,14 @@ lexer: context [ ] lex/in-pos: e + 1 ;-- skip h ] + + load-rawstring: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] + ;/local + + ][ + + lex/in-pos: e ;-- reset the input position to delimiter byte + ] scan-tokens: func [ lex [state!] @@ -1993,7 +2001,7 @@ lexer: context [ #if debug? = yes [if verbose > 0 [?? state]] ] s: start + offset - assert state <= T_HEX + assert state <= T_RAWSTRING assert s <= p lex/in-pos: p @@ -2262,6 +2270,7 @@ lexer: context [ null :load-url ;-- T_URL null :load-email ;-- T_EMAIL null :load-hex ;-- T_HEX + null :load-rawstring ;-- T_RAWSTRING ] ] diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 2f08da73bc..96f8034da0 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -24,84 +24,89 @@ context [ S_FILE_HEX1 TYPE_FILE ;-- 8 S_FILE_HEX2 TYPE_FILE ;-- 9 S_FILE_STR TYPE_FILE ;-- 10 - S_SLASH TYPE_REFINEMENT ;-- 11 - S_SLASH_N TYPE_WORD ;-- 12 - S_SHARP TYPE_ISSUE ;-- 13 - S_BINARY TYPE_BINARY ;-- 14 - S_LINE_CMT2 TYPE_VALUE ;-- 15 - S_CHAR TYPE_CHAR ;-- 16 - S_SKIP_CHAR TYPE_CHAR ;-- 17 - S_CONSTRUCT TYPE_VALUE ;-- 18 - S_ISSUE TYPE_ISSUE ;-- 19 - S_NUMBER TYPE_INTEGER ;-- 20 - S_DOTNUM TYPE_FLOAT ;-- 21 - S_DECIMAL TYPE_FLOAT ;-- 22 - S_DECEXP TYPE_FLOAT ;-- 23 - S_DECX TYPE_FLOAT ;-- 24 - S_DEC_SPECIAL TYPE_FLOAT ;-- 25 - S_TUPLE TYPE_TUPLE ;-- 26 - S_DATE TYPE_DATE ;-- 27 - S_TIME_1ST TYPE_TIME ;-- 28 - S_TIME TYPE_TIME ;-- 29 - S_PAIR_1ST TYPE_PAIR ;-- 30 - S_PAIR TYPE_PAIR ;-- 31 - S_MONEY_1ST TYPE_MONEY ;-- 32 - S_MONEY TYPE_MONEY ;-- 33 - S_MONEY_DEC TYPE_MONEY ;-- 34 - S_HEX TYPE_INTEGER ;-- 35 - S_HEX_END TYPE_WORD ;-- 36 - S_HEX_END2 TYPE_INTEGER ;-- 37 - S_LESSER TYPE_TAG ;-- 38 - S_TAG TYPE_TAG ;-- 39 - S_TAG_STR TYPE_TAG ;-- 40 - S_TAG_STR2 TYPE_TAG ;-- 41 - S_SIGN TYPE_WORD ;-- 42 - S_DOTWORD TYPE_WORD ;-- 43 - S_DOTDEC TYPE_FLOAT ;-- 44 - S_WORD_1ST TYPE_WORD ;-- 45 - S_WORD TYPE_WORD ;-- 46 - S_WORDSET TYPE_SET_WORD ;-- 47 - S_URL TYPE_URL ;-- 48 - S_EMAIL TYPE_EMAIL ;-- 49 - S_PATH TYPE_PATH ;-- 50 - S_PATH_NUM TYPE_INTEGER ;-- 51 - S_PATH_W1ST TYPE_WORD ;-- 52 - S_PATH_WORD TYPE_WORD ;-- 53 - S_PATH_SHARP TYPE_ISSUE ;-- 54 - S_PATH_SIGN TYPE_WORD ;-- 55 - --EXIT_STATES-- - ;-- 56 - T_EOF - ;-- 57 - T_ERROR TYPE_ERROR ;-- 58 - T_BLK_OP - ;-- 59 - T_BLK_CL - ;-- 60 - T_PAR_OP - ;-- 61 - T_PAR_CL - ;-- 62 - T_MSTR_OP - ;-- 63 - T_MSTR_CL TYPE_STRING ;-- 64 - T_MAP_OP - ;-- 65 - T_PATH - ;-- 66 - T_CONS_MK - ;-- 67 - T_CMT - ;-- 68 - T_STRING TYPE_STRING ;-- 69 - T_WORD TYPE_WORD ;-- 70 - T_ISSUE TYPE_ISSUE ;-- 71 - T_INTEGER TYPE_INTEGER ;-- 72 - T_REFINE TYPE_REFINEMENT ;-- 73 - T_CHAR TYPE_CHAR ;-- 74 - T_FILE TYPE_FILE ;-- 75 - T_BINARY TYPE_BINARY ;-- 76 - T_PERCENT TYPE_PERCENT ;-- 77 - T_FLOAT TYPE_FLOAT ;-- 78 - T_FLOAT_SP TYPE_FLOAT ;-- 79 - T_TUPLE TYPE_TUPLE ;-- 80 - T_DATE TYPE_DATE ;-- 81 - T_PAIR TYPE_PAIR ;-- 82 - T_TIME TYPE_TIME ;-- 83 - T_MONEY TYPE_MONEY ;-- 84 - T_TAG TYPE_TAG ;-- 85 - T_URL TYPE_URL ;-- 86 - T_EMAIL TYPE_EMAIL ;-- 87 - T_HEX TYPE_INTEGER ;-- 88 + S_HDPER_ST TYPE_STRING ;-- 11 + S_HERDOC_ST TYPE_STRING ;-- 12 + S_HDPER_C0 TYPE_STRING ;-- 13 + S_HDPER_CL TYPE_STRING ;-- 14 + S_SLASH TYPE_REFINEMENT ;-- 15 + S_SLASH_N TYPE_WORD ;-- 16 + S_SHARP TYPE_ISSUE ;-- 17 + S_BINARY TYPE_BINARY ;-- 18 + S_LINE_CMT2 TYPE_VALUE ;-- 19 + S_CHAR TYPE_CHAR ;-- 20 + S_SKIP_CHAR TYPE_CHAR ;-- 21 + S_CONSTRUCT TYPE_VALUE ;-- 22 + S_ISSUE TYPE_ISSUE ;-- 23 + S_NUMBER TYPE_INTEGER ;-- 24 + S_DOTNUM TYPE_FLOAT ;-- 25 + S_DECIMAL TYPE_FLOAT ;-- 26 + S_DECEXP TYPE_FLOAT ;-- 27 + S_DECX TYPE_FLOAT ;-- 28 + S_DEC_SPECIAL TYPE_FLOAT ;-- 29 + S_TUPLE TYPE_TUPLE ;-- 30 + S_DATE TYPE_DATE ;-- 31 + S_TIME_1ST TYPE_TIME ;-- 32 + S_TIME TYPE_TIME ;-- 33 + S_PAIR_1ST TYPE_PAIR ;-- 34 + S_PAIR TYPE_PAIR ;-- 35 + S_MONEY_1ST TYPE_MONEY ;-- 36 + S_MONEY TYPE_MONEY ;-- 37 + S_MONEY_DEC TYPE_MONEY ;-- 38 + S_HEX TYPE_INTEGER ;-- 39 + S_HEX_END TYPE_WORD ;-- 40 + S_HEX_END2 TYPE_INTEGER ;-- 41 + S_LESSER TYPE_TAG ;-- 42 + S_TAG TYPE_TAG ;-- 43 + S_TAG_STR TYPE_TAG ;-- 44 + S_TAG_STR2 TYPE_TAG ;-- 45 + S_SIGN TYPE_WORD ;-- 46 + S_DOTWORD TYPE_WORD ;-- 47 + S_DOTDEC TYPE_FLOAT ;-- 48 + S_WORD_1ST TYPE_WORD ;-- 49 + S_WORD TYPE_WORD ;-- 50 + S_WORDSET TYPE_SET_WORD ;-- 51 + S_URL TYPE_URL ;-- 52 + S_EMAIL TYPE_EMAIL ;-- 53 + S_PATH TYPE_PATH ;-- 54 + S_PATH_NUM TYPE_INTEGER ;-- 55 + S_PATH_W1ST TYPE_WORD ;-- 56 + S_PATH_WORD TYPE_WORD ;-- 57 + S_PATH_SHARP TYPE_ISSUE ;-- 58 + S_PATH_SIGN TYPE_WORD ;-- 59 + --EXIT_STATES-- - ;-- 60 + T_EOF - ;-- 61 + T_ERROR TYPE_ERROR ;-- 62 + T_BLK_OP - ;-- 63 + T_BLK_CL - ;-- 64 + T_PAR_OP - ;-- 65 + T_PAR_CL - ;-- 66 + T_MSTR_OP - ;-- 67 + T_MSTR_CL TYPE_STRING ;-- 68 + T_MAP_OP - ;-- 69 + T_PATH - ;-- 70 + T_CONS_MK - ;-- 71 + T_CMT - ;-- 72 + T_STRING TYPE_STRING ;-- 73 + T_WORD TYPE_WORD ;-- 74 + T_ISSUE TYPE_ISSUE ;-- 75 + T_INTEGER TYPE_INTEGER ;-- 76 + T_REFINE TYPE_REFINEMENT ;-- 77 + T_CHAR TYPE_CHAR ;-- 78 + T_FILE TYPE_FILE ;-- 79 + T_BINARY TYPE_BINARY ;-- 80 + T_PERCENT TYPE_PERCENT ;-- 81 + T_FLOAT TYPE_FLOAT ;-- 82 + T_FLOAT_SP TYPE_FLOAT ;-- 83 + T_TUPLE TYPE_TUPLE ;-- 84 + T_DATE TYPE_DATE ;-- 85 + T_PAIR TYPE_PAIR ;-- 86 + T_TIME TYPE_TIME ;-- 87 + T_MONEY TYPE_MONEY ;-- 88 + T_TAG TYPE_TAG ;-- 89 + T_URL TYPE_URL ;-- 90 + T_EMAIL TYPE_EMAIL ;-- 91 + T_HEX TYPE_INTEGER ;-- 92 + T_RAWSTRING TYPE_STRING ;-- 93 ] CSV-table: %../docs/lexer/lexer-FSM.csv From b6e9c4f6feeff50f69fbb667f37cef92c142a95a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 28 Feb 2020 23:57:51 +0100 Subject: [PATCH 1024/3432] TESTS: deprecates regression test #1768. --- tests/source/units/regression-test-red.red | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index dd839b6dcc..a317f50c21 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2028,9 +2028,10 @@ Red [ ; --test-- "#1764" ; console behaviour (nonGUI) - --test-- "#1768" - --assert not error? try [load {a: %{test ing.txt}}] - --assert equal? [a: % "test ing.txt"] load {a: %{test ing.txt}} + ;; DEPRECATED: raw string syntax deprecates this test and issue. + ;--test-- "#1768" + ; --assert not error? try [load {a: %{test ing.txt}}] + ; --assert equal? [a: % "test ing.txt"] load {a: %{test ing.txt}} ; --test-- "#1769" ; console behaviour From 359fd4c2a13102a0b7f5d5cba94a6641aaaeae62 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 12:25:00 +0100 Subject: [PATCH 1025/3432] FEAT: extend lexer with literal MONEY! support --- runtime/lexer.reds | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index bc98b49409..bebfc1de34 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1856,9 +1856,9 @@ lexer: context [ load-money: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local - do-error [subroutine!] - cur p [byte-ptr!] - neg? dec? [logic!] + do-error [subroutine!] + cur p st pt [byte-ptr!] + neg? dec? [logic!] ][ do-error: [throw-error lex s e TYPE_MONEY] p: s @@ -1871,14 +1871,16 @@ lexer: context [ p: cur ] assert p/1 = #"$" + st: p p: p + 1 dec?: no + pt: null while [p < e][ - if p/1 = #"." [if dec? [do-error] dec?: yes] + if any [p/1 = #"." p/1 = #","][if dec? [do-error] pt: p dec?: yes] p: p + 1 ] lex/in-pos: e + 1 ;-- skip ending delimiter - ;if load? [money/make-at alloc-slot lex cur s e neg?] + if load? [money/make-at alloc-slot lex neg? cur st pt e] ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ From e34bbcd5b8ff6fd22b61adfe8f171a9292f60b8d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 12:25:16 +0100 Subject: [PATCH 1026/3432] FEAT: regenerate lexer tables --- runtime/lexer-transitions.reds | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 15bf397d2e..c66d7716cf 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -99,10 +99,9 @@ Red/System [ ] type-table: #{ 000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F -2B2B25253333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00002200 -000000000700000000070F140B130A0829260C0C272F252B332C092D0B07 -} - transitions: #{ +2B2B25253131310B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00002200 +000000000700000000070F140B130A0829260C0C272F252B312C092D0B07 +} transitions: #{ 000018183F404142433E02113131323232322732270F3E2A3232063E013E2F24 2E2E3E32323E3D01480101010101010101010101010101010101010101010101 0101010101010101010101013E3D020202020202020202024902020202020202 From a477d755ea8e869c17f2c2380ab689aebe272c5d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 12:27:05 +0100 Subject: [PATCH 1027/3432] FEAT: full support for literal MONEY! loading --- runtime/datatypes/money.reds | 51 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 672e3903e4..511b130fee 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -226,13 +226,56 @@ money: context [ make-at: func [ slot [red-value!] - currency [byte-ptr!] ; can be null + sign [logic!] + currency [byte-ptr!] start [byte-ptr!] + point [byte-ptr!] end [byte-ptr!] - sign [logic!] ; true: negative - ; return: [red-money!] + return: [red-money!] + /local + convert [subroutine!] + money [red-money!] + here amount limit [byte-ptr!] + index stop step [integer!] ][ - 0 + money: as red-money! slot + money/header: TYPE_MONEY + + zero-out money yes + set-sign money as integer! sign + ;@@ TBD: store currency index + amount: get-amount money + + convert: [ + here: here + step + until [ + set-digit amount index as integer! here/value - #"0" + + here: here + step + index: index + step + any [index = stop here = limit] + ] + ] + + here: either null? point [end][point] + limit: start + index: SIZE_INTEGRAL + stop: 0 + + step: -1 + convert + + if null? point [return money] + + here: point + limit: end + index: SIZE_INTEGRAL + 1 + stop: SIZE_DIGITS + 1 + + step: +1 + convert + + money ] make~at: func [ From dc53c12e994e1fccbc8e7ecb2c95306dcbae49c9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 12:29:04 +0100 Subject: [PATCH 1028/3432] FEAT: remove temporary custom loader --- boot.red | 2 -- environment/kludge.red | 46 ------------------------------------ runtime/datatypes/money.reds | 40 ------------------------------- 3 files changed, 88 deletions(-) delete mode 100644 environment/kludge.red diff --git a/boot.red b/boot.red index dc24cb82a3..68b9227017 100644 --- a/boot.red +++ b/boot.red @@ -24,8 +24,6 @@ Red [ #include %environment/system.red #include %environment/operators.red - #include %environment/kludge.red - #include %environment/codecs/png.red #include %environment/codecs/jpeg.red #include %environment/codecs/bmp.red diff --git a/environment/kludge.red b/environment/kludge.red deleted file mode 100644 index b741d17dfc..0000000000 --- a/environment/kludge.red +++ /dev/null @@ -1,46 +0,0 @@ -Red [Note: "Ad-hoc loader for money! datatype."] - -forge: routine [ - sign [integer!] - amount1 [integer!] - amount2 [integer!] - amount3 [integer!] -][ - stack/set-last as red-value! money/push sign amount1 amount2 amount3 -] - -coin: function [ - string [string!] - /local - sign integral fractional -][ - digit: charset [#"0" - #"9"] - precision: 22 - scale: 05 - digits: precision - scale - - either parse string [ - set sign opt [#"-" | #"+"] - #"$" [ - some #"0" end (integral: #"0") - | any #"0" copy integral [1 digits digit] - opt [[dot | comma] copy fractional [1 scale digit]] - end - ] - ][ - string: rejoin [ - pad/left/with integral digits #"0" - pad/with any [fractional copy ""] scale #"0" - ] - - sign: select [#"-" 1 #"+" 0 #[none] 0] sign - binary: debase/base string 16 - - insert binary 0 ; placeholder for currency index - slice'n'dice: [loop 3 [keep to integer! reverse take/part binary 4]] ; little-endian order - - do compose [forge sign (collect slice'n'dice)] - ][ - make error! "Cannot load this." - ] -] diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 511b130fee..4be9b08436 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -278,46 +278,6 @@ money: context [ money ] - make~at: func [ - slot [red-value!] - sign [integer!] - amount1 [integer!] - amount2 [integer!] - amount3 [integer!] - return: [red-money!] - /local - money [red-money!] - ][ - money: as red-money! slot - money/header: TYPE_MONEY or (sign << SIGN_OFFSET) - money/amount1: amount1 - money/amount2: amount2 - money/amount3: amount3 - - money - ] - - make-in: func [ - parent [red-block!] - sign [integer!] - amount1 [integer!] - amount2 [integer!] - amount3 [integer!] - return: [red-money!] - ][ - make~at ALLOC_TAIL(parent) sign amount1 amount2 amount3 - ] - - push: func [ - sign [integer!] - amount1 [integer!] - amount2 [integer!] - amount3 [integer!] - return: [red-money!] - ][ - make~at stack/push* sign amount1 amount2 amount3 - ] - ;-- Conversion -- overflow?: func [ From b6ccd8bc3b78653b58d79ca910b0f1a4a30d0523 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 12:30:22 +0100 Subject: [PATCH 1029/3432] FEAT: improve code formatting --- runtime/datatypes/money.reds | 79 ++++++++++++++---------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4be9b08436..88a9ac1442 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -147,10 +147,8 @@ money: context [ offset [integer!] return: [byte-ptr!] /local - this that - [integer!] - half - [byte!] + this that [integer!] + half [byte!] ][ loop offset [ this: size @@ -174,8 +172,7 @@ money: context [ index [integer!] return: [integer!] /local - bit byte offset - [integer!] + bit byte offset [integer!] ][ bit: index and 1 byte: index >> 1 + bit @@ -191,8 +188,7 @@ money: context [ index [integer!] value [integer!] /local - bit byte offset reverse - [integer!] + bit byte offset reverse [integer!] ][ bit: index and 1 byte: index >> 1 + bit @@ -284,10 +280,8 @@ money: context [ money [red-money!] return: [logic!] /local - amount limit - [byte-ptr!] - sign count - [integer!] + amount limit [byte-ptr!] + sign count [integer!] ][ sign: sign? money if zero? sign [return no] @@ -304,10 +298,9 @@ money: context [ money [red-money!] return: [integer!] /local - amount - [byte-ptr!] - sign integer index start power digit - [integer!] + amount [byte-ptr!] + sign integer index + start power digit [integer!] ][ sign: sign? money @@ -333,12 +326,10 @@ money: context [ int [integer!] return: [red-money!] /local - money - [red-money!] - amount - [byte-ptr!] - extra index start power digit - [integer!] + money [red-money!] + amount [byte-ptr!] + extra index start + power digit [integer!] ][ money: zero-out as red-money! stack/push* yes money/header: TYPE_MONEY @@ -377,8 +368,7 @@ money: context [ that [red-money!] return: [integer!] /local - this-sign that-sign - [integer!] + this-sign that-sign [integer!] ][ ;@@ TBD: take currencies into account @@ -445,11 +435,9 @@ money: context [ addend [red-money!] return: [red-money!] /local - left-amount right-amount - [byte-ptr!] + left-amount right-amount [byte-ptr!] augend-sign addend-sign - index carry left right sum - [integer!] + index carry left right sum [integer!] ][ augend-sign: sign? augend addend-sign: sign? addend @@ -496,13 +484,10 @@ money: context [ subtrahend [red-money!] return: [red-money!] /local - left-amount right-amount - [byte-ptr!] + left-amount right-amount [byte-ptr!] minuend-sign subtrahend-sign sign - index borrow left right difference - [integer!] - lesser? flag - [logic!] + index borrow left right difference [integer!] + lesser? flag [logic!] ][ minuend-sign: sign? minuend subtrahend-sign: sign? subtrahend @@ -556,13 +541,11 @@ money: context [ multiplier [red-money!] return: [red-money!] /local - left-amount right-amount product - [byte-ptr!] + left-amount right-amount product [byte-ptr!] multiplicand-sign multiplier-sign sign left-count right-count delta index1 index2 index3 - carry left right other prod - [integer!] + carry left right other prod [integer!] ][ multiplicand-sign: sign? multiplicand multiplier-sign: sign? multiplier @@ -791,8 +774,8 @@ money: context [ add: func [ return: [red-value!] /local - left [red-money!] - right [red-money!] + left [red-money!] + right [red-money!] ][ left: as red-money! stack/arguments right: left + 1 @@ -803,8 +786,8 @@ money: context [ subtract: func [ return: [red-value!] /local - left [red-money!] - right [red-money!] + left [red-money!] + right [red-money!] ][ left: as red-money! stack/arguments right: left + 1 @@ -815,8 +798,8 @@ money: context [ multiply: func [ return: [red-value!] /local - left [red-money!] - right [red-money!] + left [red-money!] + right [red-money!] ][ left: as red-money! stack/arguments right: left + 1 @@ -827,8 +810,8 @@ money: context [ divide: func [ return: [red-value!] /local - left [red-money!] - right [red-money!] + left [red-money!] + right [red-money!] ][ left: as red-money! stack/arguments right: left + 1 @@ -839,8 +822,8 @@ money: context [ remainder: func [ return: [red-value!] /local - left [red-money!] - right [red-money!] + left [red-money!] + right [red-money!] ][ left: as red-money! stack/arguments right: left + 1 From 5885c680f4f9755cd16d562679e2f931d850c8a6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 29 Feb 2020 12:58:07 +0100 Subject: [PATCH 1030/3432] FEAT: partial support for loading raw strings. Syntax: %{...}%, with multiple matching leading/trailing % allowed. --- runtime/lexer.reds | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index bc98b49409..febdaa1bb3 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1948,10 +1948,35 @@ lexer: context [ ] load-rawstring: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] - ;/local - + /local + do-error [subroutine!] + cnt cnt2 [integer!] + p q [byte-ptr!] ][ - + do-error: [throw-error lex s e TYPE_STRING] + p: s + while [s/1 = #"%"][s: s + 1] + cnt: as-integer s - p + q: e + until [q: q - 1 q/1 <> #"%"] + cnt2: as-integer e - q - 1 + if cnt < cnt2 [do-error] + ;if cnt > cnt2 [ + ;until [ + ; if e + 1 >= lex/in-end [do-error] + ; + ;] + ;while [e/1 <> #"}"][ + ; e: e + 2 + ; if e >= lex/in-end [do-error] + ;] + ;p: e + ;while [e/1 = #"%"][s: s + 1] + ;] + if load? [ + flags: flags and not C_FLAG_CARET ;-- clears caret flag + load-string lex s + cnt - 1 e - cnt2 - 1 flags load? + ] lex/in-pos: e ;-- reset the input position to delimiter byte ] From 43a0b3706b8433a3f816c9438eb85b2e5ce67906 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 14:37:38 +0100 Subject: [PATCH 1031/3432] FIX: handle literal forms with trailing delimiter --- runtime/datatypes/money.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 88a9ac1442..d135de5f18 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -245,6 +245,7 @@ money: context [ convert: [ here: here + step until [ + if here = limit [break] set-digit amount index as integer! here/value - #"0" here: here + step From c110869e1e1a4a0e636b070c6181184ae31fc509 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 29 Feb 2020 15:47:45 +0100 Subject: [PATCH 1032/3432] FEAT: support comma as decimal separator in money! values. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21951 -> 21953 bytes docs/lexer/lexer-states.txt | 2 +- runtime/lexer-transitions.reds | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 94301d66f0..2e76bce21d 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -36,7 +36,7 @@ S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_T S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;S_EMAIL;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 82336dc161fc7478d8a4d72a4198472d78bc5f28..ebc07988f73486c3daf3ad84e65b9acfb425ae38 100644 GIT binary patch delta 9841 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 delta 9887 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"+"|"-"->S_SIGN->digit->S_NUMBER S_START->"$"->S_MONEY_1ST->digit->S_MONEY->digit|"'"->S_MONEY - \->else->T_ERROR \->"."->S_MONEY_DEC->digit|"'"->S_MONEY_DEC + \->else->T_ERROR \->"."|","->S_MONEY_DEC->digit|"'"->S_MONEY_DEC \ \->delimit3->T_MONEY \ \->else->T_ERROR \ diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 15bf397d2e..74fab3203a 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -148,7 +148,7 @@ Red/System [ 3E3E3E3E3E3E3E3E3E3E3E353E3E23233E3E3E3E3E5656232356565656565656 3E3E563E3E3E23233E3E563E563E3E3E3E5635233E3E3E3E3E3E3E563E3E2525 3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E -3E3E3E58582525585858585858585825583E3E3E3E3E3E3E583E583E3E3E3E58 +3E3E3E58582525585858585858585825583E3E3E3E3E3E3E583E583E3E3E2658 3E263E3E3E3E3E3E3E3D58582626585858585858585826583E3E3E3E3E3E3E58 3E583E3E3E3E583E3E3E3E3E3E3E3E3E3D4A4A27274A4A4A4A4A4A4A3E323332 322832273227464A3232323E3E4A35322532323232323E4A5C5C32325C5C5C5C From 40a647661aef07990ccb68f622d4be2528f57cfb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 29 Feb 2020 16:00:42 +0100 Subject: [PATCH 1033/3432] FEAT: forbid literal forms with trailing delimiter --- runtime/datatypes/money.reds | 1 - runtime/lexer.reds | 15 +++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d135de5f18..88a9ac1442 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -245,7 +245,6 @@ money: context [ convert: [ here: here + step until [ - if here = limit [break] set-digit amount index as integer! here/value - #"0" here: here + step diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 0efc081886..e1c394ee41 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1857,8 +1857,8 @@ lexer: context [ load-money: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local do-error [subroutine!] - cur p st pt [byte-ptr!] - neg? dec? [logic!] + cur p st ds [byte-ptr!] + neg? [logic!] ][ do-error: [throw-error lex s e TYPE_MONEY] p: s @@ -1873,14 +1873,17 @@ lexer: context [ assert p/1 = #"$" st: p p: p + 1 - dec?: no - pt: null + ds: null while [p < e][ - if any [p/1 = #"." p/1 = #","][if dec? [do-error] pt: p dec?: yes] + if any [p/1 = #"." p/1 = #","][ + ds: p + if ds + 1 = e [do-error] + break + ] p: p + 1 ] lex/in-pos: e + 1 ;-- skip ending delimiter - if load? [money/make-at alloc-slot lex neg? cur st pt e] + if load? [money/make-at alloc-slot lex neg? cur st ds e] ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ From 3d104a5aeb329f0c31fd4a3c5e3665629a7ccc42 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 29 Feb 2020 18:33:32 +0300 Subject: [PATCH 1034/3432] FEAT: preprocessor support of integer, get-word, paren in paths --- utils/preprocessor.r | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/utils/preprocessor.r b/utils/preprocessor.r index 191e339e72..e1cf8340aa 100644 --- a/utils/preprocessor.r +++ b/utils/preprocessor.r @@ -136,13 +136,20 @@ preprocessor: context [ arity ] - value-path?: func [path [path!] /local value i] [ + value-path?: func [path [path!] /local value i item] [ repeat i length? path [ - set/any 'value either i = 1 [get/any first path][select value pick path i] - unless any [ ;-- select-able types - series? get/any 'value - find [object! port! error! map!] type?/word get/any 'value - ][ + set/any 'value either i = 1 [get/any first path][ + set/any 'item pick path i + case [ + get-word? :item [set/any 'item get/any to word! item] + paren? :item [set/any 'item do item] + ] + either integer? :item [pick value item][select value :item] + ] + unless find [ ;-- select-able types + block! paren! path! lit-path! set-path! get-path! + object! port! error! map! + ] type?/word get/any 'value [ path: copy/part path i break ] From 5ca7fa3800775cf45eec765418cfd5a2e11f3cee Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 29 Feb 2020 18:54:07 +0300 Subject: [PATCH 1035/3432] TESTS: extended path syntax tests for fetch-next --- tests/source/compiler/preprocessor-test.r | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/source/compiler/preprocessor-test.r b/tests/source/compiler/preprocessor-test.r index 5c7b35a409..102cb9e4ba 100644 --- a/tests/source/compiler/preprocessor-test.r +++ b/tests/source/compiler/preprocessor-test.r @@ -116,6 +116,13 @@ REBOL [ prin "*test11* " probe preprocessor/fetch-next [a: o b: 1] prin "*test12* " probe preprocessor/fetch-next [f o f 1] prin "*test13* " probe preprocessor/fetch-next [b/o/f o b/o/f/x 1 2 3] + i: make image! 10x10 s: "abcd" + b: reduce [i s] + w1: 'i w2: 's w3: 3 + prin "*test14* " probe preprocessor/fetch-next [i/size s/3] + prin "*test15* " probe preprocessor/fetch-next [s/3] + prin "*test16* " probe preprocessor/fetch-next [b/:w1/size b/(w2)/:w3] + prin "*test17* " probe preprocessor/fetch-next [b/(w2)/:w3] } --assert-printed? "*test1* []" @@ -131,5 +138,9 @@ REBOL [ --assert-printed? "*test11* [1]" --assert-printed? "*test12* [1]" --assert-printed? "*test13* [1 2 3]" + --assert-printed? "*test14* [s/3]" + --assert-printed? "*test15* []" + --assert-printed? "*test16* [b/(w2)/:w3]" + --assert-printed? "*test17* []" ~~~end-file~~~ From 78a68e01886258e9ddac99f976be98c8f302a80a Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 29 Feb 2020 19:32:34 +0300 Subject: [PATCH 1036/3432] FIX: using typeset for preprocessor/fetch-next --- utils/preprocessor.r | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/utils/preprocessor.r b/utils/preprocessor.r index e1cf8340aa..88e36d9adc 100644 --- a/utils/preprocessor.r +++ b/utils/preprocessor.r @@ -136,7 +136,11 @@ preprocessor: context [ arity ] - value-path?: func [path [path!] /local value i item] [ + value-path?: func [path [path!] /local value i item selectable] [ + selectable: make typeset! [ + block! paren! path! lit-path! set-path! get-path! + object! port! error! map! + ] repeat i length? path [ set/any 'value either i = 1 [get/any first path][ set/any 'item pick path i @@ -146,10 +150,7 @@ preprocessor: context [ ] either integer? :item [pick value item][select value :item] ] - unless find [ ;-- select-able types - block! paren! path! lit-path! set-path! get-path! - object! port! error! map! - ] type?/word get/any 'value [ + unless find selectable type? get/any 'value [ path: copy/part path i break ] From 7b93056aa8d3daa7d4797ab0dc38b3e536225a99 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 29 Feb 2020 19:44:38 +0300 Subject: [PATCH 1037/3432] FIX: no images for linux users! --- tests/source/compiler/preprocessor-test.r | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/source/compiler/preprocessor-test.r b/tests/source/compiler/preprocessor-test.r index 102cb9e4ba..1b51697edb 100644 --- a/tests/source/compiler/preprocessor-test.r +++ b/tests/source/compiler/preprocessor-test.r @@ -116,12 +116,12 @@ REBOL [ prin "*test11* " probe preprocessor/fetch-next [a: o b: 1] prin "*test12* " probe preprocessor/fetch-next [f o f 1] prin "*test13* " probe preprocessor/fetch-next [b/o/f o b/o/f/x 1 2 3] - i: make image! 10x10 s: "abcd" - b: reduce [i s] - w1: 'i w2: 's w3: 3 - prin "*test14* " probe preprocessor/fetch-next [i/size s/3] + p: 10x20 s: "abcd" + b: reduce [p s] + w1: 'p w2: 's w3: 3 + prin "*test14* " probe preprocessor/fetch-next [p/y s/3] prin "*test15* " probe preprocessor/fetch-next [s/3] - prin "*test16* " probe preprocessor/fetch-next [b/:w1/size b/(w2)/:w3] + prin "*test16* " probe preprocessor/fetch-next [b/:w1/y b/(w2)/:w3] prin "*test17* " probe preprocessor/fetch-next [b/(w2)/:w3] } From 9fff7f6d5dc25118c8a1e211f6e69f41b7549f2e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 29 Feb 2020 18:50:01 +0100 Subject: [PATCH 1038/3432] FEAT: completes raw strings support. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21953 -> 21951 bytes runtime/lexer-transitions.reds | 2 +- runtime/lexer.reds | 36 +++++++++++++++++------------- tests/source/units/lexer-test.red | 6 +++++ 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 2e76bce21d..9adafa7abd 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -10,7 +10,7 @@ S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_E S_FILE_HEX1;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_HEX2;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_HDPER_ST;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HERDOC_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_HDPER_ST;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HERDOC_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR S_HDPER_CL;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_ERROR;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;S_HDPER_CL;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index ebc07988f73486c3daf3ad84e65b9acfb425ae38..688d37844f051c25af1ab71da9591c3989b38afd 100644 GIT binary patch delta 10236 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 #"%"] cnt2: as-integer e - q - 1 if cnt < cnt2 [do-error] - ;if cnt > cnt2 [ - ;until [ - ; if e + 1 >= lex/in-end [do-error] - ; - ;] - ;while [e/1 <> #"}"][ - ; e: e + 2 - ; if e >= lex/in-end [do-error] - ;] - ;p: e - ;while [e/1 = #"%"][s: s + 1] - ;] + if cnt > cnt2 [ ;-- trailing % count too low + q: e + until [ ;-- searching for the right ending sequence + if q >= lex/in-end [do-error] + while [q/1 <> #"}"][ + q: q + 1 + if q + cnt >= lex/in-end [do-error] + ] + q: q + 1 + match?: yes + loop cnt [if q/1 <> #"%" [match?: no break] q: q + 1] + match? + ] + q: q - cnt - 1 + ] if load? [ flags: flags and not C_FLAG_CARET ;-- clears caret flag - load-string lex s + cnt - 1 e - cnt2 - 1 flags load? + load-string lex p q flags load? ] - lex/in-pos: e ;-- reset the input position to delimiter byte + lex/in-pos: q + cnt + 1 ;-- reset the input position to delimiter byte ] scan-tokens: func [ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 80e7f7e6bd..17732d409e 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -374,6 +374,12 @@ Red [ --assert word? out/2 --assert word? out/3 + --test-- "tr-37" --assert [""] == transcode "%{}%" + --test-- "tr-38" --assert [""] == transcode "%%{}%%" + --test-- "tr-39" --assert ["a^^b"] == transcode "%{a^^b}%" + --test-- "tr-40" --assert ["}"] == transcode "%{^}}%" + --test-- "tr-41" --assert ["Nice^^World}% rawstring! "] == transcode "%%{Nice^^World}% rawstring! }%%" + ===end-group=== ===start-group=== "transcode/one" --test-- "tro-1" --assert 8 == transcode/one "8" From 43964b6816b706a210a52c6b0e6208691b945bde Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 29 Feb 2020 21:00:26 +0100 Subject: [PATCH 1039/3432] FIX: fixes non-passing test "tr-40". --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21951 -> 21933 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 9adafa7abd..cc4156e20c 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -12,7 +12,7 @@ S_FILE_HEX2;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERRO S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR S_HDPER_ST;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HERDOC_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR -S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR +S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR S_HDPER_CL;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_ERROR;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;S_HDPER_CL;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH_N;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SLASH_N;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH_N;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;T_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 688d37844f051c25af1ab71da9591c3989b38afd..78ad179868f8a62ccf69b28f3a7324c0e86d34b8 100644 GIT binary patch literal 21933 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 literal 21951 zcmeIaWmH^S(>01qLU0I9f(CEgU4pv@cXxMpcZU$%J-7r5F2RB(XmEGCo1F6;$vMwA z-f_qMbI14gj}1-tE~;x+)tohVuO%x1355;@0|o~M2KE~4b%Y3q6F3-H1T+{J8WQN26 zPe3IPrtN2mIfFzuw+Nq$8<(71Kjd`66#wjJn)4D@BJE=Yvo)L6tWuqyPv2L?v-qr# zP9tgDcX_Mk7X-YaaAIoZl*X?yaQWy7mR4RE<04_%*7qtV2tBBY4~rLJkd69pWG)7( zqj(1ixFymkg4>Pnat{uxK}gUuW9cz@1ZvPwg)Pstwkk2ODhtsq*uPMsOt?%OK(Cf< zs<{avadNd{7^i(VgOHhnl*5z+rl=B%6olQ49x{jZ%r%aYFK|iJxdOGqB2d?qi>Ky^M?aqp- z=vpQ8L6QEE3`fWz$LEXdOXWI{N(8YbWhZXSlAo47tr8eFX;$v)CWM#1_GH%wZun8+ z!nZyLnsd=+3i$3Yeta;9-EKRRgjnou&1eMBs7zlA__MzyStdn!0h#vr2niudMF6CqxcA*{Wwv0x++V{7TPX(3F&&Xw?#GK;W*6+cf@*3_%i6vkN52IV?lC*x+W9x z*hPkm2^-u&9R#v8T+>}$ZT2h}{EK3e}w>rzJL@>NJZWAh~>&%D_=A1OsuuM5*=S`d*FNA?> zYs(cT&B*9>FWm8C?B@fa&*O8VXlndS@3b)0AfR2d-fP5v@9u|G6XLPOQz0poXo6C> zV;t6F_-OtqW*TMWdA}kLM?T{_I#T;uN`z?7ottVZrV-u?JLSin=l|AUZ5cI{?SX7? z0{SZwkP<-V{55AHEbYT5GP+tK^<>GktdYDsdgn;l3(ST^`rXmI^WpFAyHGC z=AC}DyM7cDe4T{pwr5)iQF5}ZEh`JN$sT&2@*;6v@aJjFMjKL}O2wX47Xl>>vw249 zJ#RKixzBh6Qp<`to-%s;w$Ue=6y|Sh4PRqexW5gUJ*TRay%dwnZ9J6`a6_iZe9c62 zM>$u}Zk_k(V2R0yX|P?YU5zN`TjU9D9cz`o7PYPgfmP6(22}M+M)X(g`+1lJQrjk| z`VCv)3{aM{^J3qJ5*VD&XwT|j#sp6id&e#6O`P7lSB2DUiOpeZmhD3H)-Q=UY|Xr@ z$lMd?+Ik*ZIWe7p+7ff6JFACkLi_faVI#RW64^_CP1=bnrY*{Tn@=b#Im_7HCiWjr z`_w&hVfXTw4up_8BrgC$`cM2@P^Pu)2C6z7xHvC&&PZiyxvS78qhU}@W z^T_|LB{!V3(n6Hdj1%ISLpXFC^o_Vgf>gpw!CZxw-Us*KDQ3$I7hK{Cf3c{b?(S4Z zJO(f4Z^Le{l%(=SW1QEB!b3DL6)jND4n2+DelEelgf^0ofx;JyT+a7?K$+e7{COz} z+0YkWj@+bl%Ibj4v7HoemeuYplm~@jZ?&Ipz3q;su#McVSO$Cht~7pBF<)dL``8%$ zC);zwj#~QxXVnR2Lq+^Z8iQkx2VG)=z*&SGf>yAtOiRYAUamq{QggKuT+r6%nmqPv zjE&(`b{&dH2?|Ba4LdqTzXBcgO3)+Gx=QS}%(qTus>ogI8Azj7$1(AJO$IeJ=q@lm z*rA;nOgIw5KbmvZ%X>0v^ocL(JK1Wd*U%dZ0;BpSa>Ul^XWTy2H#-tVu39!YWagKQ zaPX@&IGoE^U&v3mt#{4hGD{ZuK1-<1NVxjZr2zR?d>Q#M ze=Ny%|1C!%X8sfZboGOAfKg<>gu^Kt#gDA)jIZCWA8oWioM0Siur6B|qwKgN5-28u z;Jzd9`p)y`*+V?dHxAqhNpq(WrAU0pMannSd(E8@4GTgw*gxQ+%b6ScjqX=!%<%`k zd=-kwz>Z86?=7AmI_(wh23H`A{NVn8+a*RUuKxykWPE-w%nMRUQ;kVN$_sDsi`8-E zi&u>-K1cIl(zalJOY}b|5UGa;W|lFfkDps`4OG@zYNuIq5RVbvZM@+*p{w%z?19C# zwSu67h|TJ9J4t}u1-XTA#P@*L$_jq=S(^^5xuK)eb?ka~@iXqGj@ zMdl-uVDZ$#7lsEYTvq-#g9U2&pVf}mLyh(cctrr{$i#nkV|x=rLkIicA^qnQhCcv3 zAiC>mND(>=yz`%PC*cg14I|YSe?3cf4<@X&kb5C+@{#oV_Qza+KvcK>GDy=~?d5rR zpgz&_ax1>qflNYa)E=2U4V5{nTra%D0x&B+kGG6ST!w}xtFN*fDNhSn=wc37_t~V_ zo|h?zlo&`Fp3Cc}N?v?lkTG$Rs%71%gj~#2z=wIh0jkT9p4CXsZu!F2=W|GLS0;Kg z7BD~>r^B8r%Kcese<(nYfA{T0it`N~e8leXlD#v~*8Uj+PD=)fuK!60=>HmmuumX# z;Y-K|K^OPZxXk zz;*qXCRIo7^E4g&)oeS9=IxdT4#yoYD>1V?(T1&~ldeCcUiVb-=iruCd)SNeB;>OC&@uWH0WtO%9iCiK z_RqrmCq6&~oG-G>JrSV_EQg0qFW~O$*e_sBCWI6j>5OV*D z^=3O{{AE~C{WJ<^e#mTadQ;Q#l6yc7wy%xY)CG?x>wp+(zT{0Vl=mI$?F#fv?~=Wm z%iB-ThDsrRUC6F^;%XwLmLXn`;uTi0ltj=nrbF2(-ki=-_kQhEs_ z(&9Xn?|Gf57j#Z_n8x)CjKdZ*Q zdrs^AC?(JY?wKDtiBhOLR(sUCFS>BZsty$CZK?1yz35Hk=Ekua?*!>hS6jsTmF(y2 zy|c*ieQ5z+NtoG~x|Lx&b$rQajz!pNhM-X23@TgLsbznLh_V=KtrbyrFC2ue&9G*R_RjrA2kYui zmHa@jj7tTvI*t~<)N9u(Gf6uprA7N0;zU_uVWOZxidP3-${Z+WAh1xmOzGw6%*$pL zv6uR{hACk4do*({Q|L{GbL)&j6mu-Y&j_$#8f;J&tU$12ERqW#s+p4T>KFDQ^(+zT zx<^H}hal*MAT`_wgfG@9y6Q#|!BYH=#yy&n<3`Ge)u^yWOJj977B|=(=oZ(8TiDnI zD|A2YC@j#yX7>21T{6;ie5?Plto^LvzQ!&D;mct%BpUA1yPjUf?b{DhL@PR_lJ9EJ zo%uq+AladdD7n{JhL_Ug>pLO4aXyhH<)2DFHmuLQ9Cw&vZA#kew|-PcfY|9^waMX0 ztyVtvsjXdCzUHKLzAHgm2g{!x$(3FIq}AuW;f@&P1#UY#QU2r+%4aSA2cn#KT&v%yh62k+;X=${Mlb`MiI~dqEfz!DM?WHt9X*q8}|dnNz)U< z&UCSchPYnS4@)(MRQai(DE2`Rf-i+A&6G?Vk$z&jkc}XI?mD{HXJmovtiVc@Qwyh^KZuma zPf+{ptugFd)ytK)TtVEQlcv7QlrEeQH>?(V@tJ2P`3QH~$kTnK3pb{hHRhdCmQq}}1$D)sJa?q%767!@`~5R)-2%%-Yl=vljD~gE^0lG zH{IkNcXzJr$P6a0C&KBn?=JQR!Yg_1?_2swk1T!P3SY&D2<5(8hr>UDb6^azB_$`e zZO7s$fzLs$P{`xjG2qnhn;{6v(F>HDVjCfRdF)45IwyqLl zQ1=hycIF(TZ~P>9G`CT}BDI9b#>zjS1y`r;Oh*DNXu zH!L1Nh`O0_%#lTbml%t;8iMh{3$3(D@^hEQm9T~k<&gs)*4sAv*cyuwOYj@a3@=E* zHcH1^g7mkv@^3h3KDeUUYY813nX>lC$p_(&vr+5u#wftaMO-vd`XAb|3Z8LZf%j7_ zc_yRwFBQJ@<7BcCQilr3N)1KT)*@dFUFph@0?{kMh&L+~6XQH;elg0s-6N|u!S{QO;EZyn z#8x-7oXc%ut_6lW#3CH0!?x;+{r;xf(&i7G`IFS@x0RoGflonK?qjB8Zna|qpeTZJ%=KHHhrSanl7cE zm+vmSr6uDA<`&a-Sh60BaX-C;Kt|HL%v?3Hca0RHO$eLiuLyo9Q?|$*+?Avxbi7gu z)4k(W5I!Wgfv)D6AvpT(q^gt0n7?oPUI0<)4Sey+%W<}pdGHAcl~<erV^Z&5l>W zHytDF65V;s86?x-FJf}42#aNrYmf{FgjOhe%(j;e#cC2_LW}$w8LIW7Kfl%$)PziT zv%Zvtdv8@DrVfK}U~t!TXbKYvv9ykUI#O(Ky=-p(E&IU3g27+j3ZLbLl+mL`Pb;_T zUWrqiTGoD>u<%(=?nsHT8u;+Dcl=aRx3lQqGv1Y#t4iQhGBbSd3?IVj)>%d-wTTTl zBb<9II!e9&_MUa>HLuTn*tgq2G8kP*InMzW0@0VEoNRu51BmlFlX+#PUuMMK(JYkF zHGUbn&H^rA9b2dy)eft_u@k}s&@0C8DetQB2uhH>@ zr_C9n2TKY)sT8QIkka>kFhL5J&-zEak;(E70HXd0Vr=f#na$*2V1^dp|BWvGM6!&f zuXam)aSh*3qkg!{9<|cYAmZR9aaL`*W{sJI)?mLwJ&!-TaMHfd)=`?^gP=N1l;+|Y zrbOQvg7yPDA9{S)8rpjK*xuyb*misKP;28`ZS6?&EwA;M78jS6 z_r1&g^}+7QZEc4&!RW)~?BheF_Cs^a<7_t}D{C}e-ly5%OJi>?9e4h`PHj^)RPlkW@nBj^2vbT=p08`q^OmD*lS?e}h&ly@F7W{aLT z4!7S6JTJeG(Xnb13dY{1kIhCiJO=Yxb#UjIY4gO`X;&ORo^O48ytcXANKd%hzc}4r zTaghS)AG1JI{kK8>3lic;hD7dAhULIBUo~OMwfV^ZN3rkBKc5E?^XX0jFEe~#|tB2F9>=ERrE|-=br`y%QyK5tCye?L6y4UtQ ztT#U`XWu(rUb$S7K0eA6UdcUtDZFiYY`MN+3NCzq@^yoGhz%WH_-*9#>z&6-2e@nA zp)+lsv5u>;ZPjKOTs^PH)wPkrU0z;Z+QWyPmBojLw>;m6vMUTiPZJ-m*H-q^gOTjQ zHafkU8wYp28gHqE*DLAT7dPFNq$ke3Kgln8dE5y;h^_C2pMH$Ar#L;ja`swY&S<;Z z-~3*U`*OWI8_90C<%j;Xtc>zjaTeZ~_V>pQssw*wT78sjcj}XiLe{OyO06vg2AJf> zTc*ald)K3_N`L(h>E}dmYf;X01#G2?XH@j+)l`{ny<> zw2a4KqbnrW$V+3SPY?IIz0-7bk2IWTf_G`kFI+Xr_Hj-MBsrMZEmIxLKesS!D-CRv zGHlPrh@>Kvte+dEB9yMLwn~aHujfkkF$=w5Dvpz29bGXb~rF&H-r?z^Vgp?+CS;xS%$bGOS4-Vx5nPnX7a z->(--r?X68UVC$ss#ln(2n$-KM#(h$iV|cQpQu}oYQ2zyJU0)Shw}%VT&fbsshrZn zh9=HFeH>PyIbcJ+-sN4-X1qH)<|ux>AroM##56knY1k)KWh5}|@DsU2c9};_MO@G_ zLwd=?>5{To{&0oa)W9;VZsupf`p-=zc4esCOVp1I{Ht%gJ(rO%6wpNLy=zlM%|EG0 zk!hE{$mo?#bJU{@SFmcG%%t9|2^m$Qt;HISo6uw=`@%$@wwb5T6z)j5s}VmE7W$p3 zKkS&gzT7*ibgDOhG}`g_?)ge~8rIBZu}= z3C-88UzV^`RKTSBCO8EU(PY)QCn7*h zHt?BTKU>m+;e242+&-JyqvmX2klZ}m!lUMVV3gcF8_&b;Oe_f;@+8HV&*)Vwc8CEC zL#nT=(W^x45JMQdR9_vVSE*_do1rlHUdvduYOUg&j-<4_1@}My?}OmMCugV~FD1qp zy_YJv8(|Gp92J1#x)s(=1yg|qBgaKG&AI9*;(5#9^fs+gZzn93YO_MMQExjek!q%5 zu2F9{ER*V@f~|4&M;P^KXm;yxwAQ9E-D!97_4d%+m7&)I1Fw&oq)s()n_P0%*U#Eo zPfv4}^1DUJCAa0@W#Qgb(`I_>Udz8Dv|)@{P5VK+|BDmNdh21;RAdz?&3c<*O;nf_ zs?B;EVf9oj6?4scTVZWfh!t$jL_;2{g|z0^N_UHfUPlbPuBn7=!(&>T!E~ozlCO`4 z?(PifeaO?STO$ySb6mQdb{IIkX`8N6bVi6tPv%VA2tczN6=hyLO9;7aC%8+Ao|A}q zbMw>wZ1^e;_quL8+qVYa;&os3u9^PmzYy_CwXGlKbPVM#MyizF6Tiw!*W71zYj$GB7;YHwNqRwy$Q$QlRvx7pE{7y~*r9e*T0Zp;D$%?bO?c z@lIt=quRN*3*)VdL8^@2Lm2M2Ot%J5I5;&<;wm-Fc$h6Fu}K=1fO!#?KzI+bI!Vwt z5q$t==<7OB1i(?a@(d&TAacygsj^etp?oV#Z8_d!yXYCt9PCKuZcNa=Nm%%?H22GS z@Pg-kJK$enjlhPHQ&2$qI%J)azNz4hutwm+s3}TJGs~)wwctk2hiP%l#}0kj!R(<# zmb(Y+?;nQKVp@YCkwZ&bLm?^itJ3U=OcRrBJ8eiRvEeO5P^l`{eAr`$jY#TFM55R= zn)-)eyDrbJGD-<5Z>(xjA{;5-b=G~L*i_Y|0cr@E_}ph3k`c@ZZWu0w9)zY-&av7&s)mu-bVek}U(B#TJn7B7=NRQ$TXHi0&8BJWP zIXq=-)!;%>4r*xWnX_yt6bo@^;saukJ;S?$L)5s#?L&5zd(EX}OBO$he3?{Ckfjbs zr-SeIpD|c7F%ab9J$w{dnn?5EP|z{z9QIWMtA#Rx9>z&|0eYw7)VcRtAlzCB1-6gD zVvEG1VG~7F^ZWh9Nh&7S_(@S!w~qk_%FbM5DFSEis3nWJeFwR<#-9R^?C!B9f3K0B z`Ur!y<=*pjEezDM(o@;E1HEUDwh5?)y7z`jmNpHv7&NF&5yh!j##DRAM6 zSo?o>WFq79;ulDGcOAq|Jl|N_!$R3+558WdvUPT1-9#3oJ_*};WwCj#A|VJWO9Dlr zSm1Azfh$^@i+IHE6D3?h8E6Z3>0{c@SCJamJG@ILH>V+~M?wbO-@eD>xAfzHa)jSO znIbpg8;{A6qmftHTT{HsAd|CU$6j_#vtH^K zqZQqW#dOeJ;Aca9KWDhcemFgfl$cIVi`?NfNo<=TDw2{7&Y|V!_Pc?40f&RiL}Vg4 z9*{%9&*--aMFXdfT1R9eH6D~h!_Vn=0fi68fl87M^(ym3Otx@JhH0JCmm{AOSG@WT zMp*v&hN_p1gxPzNp=c{Hngqk^?=;1Mlhi9{0qW#w9vL^M42_gT{&%K$A6jHjI$M4tlPW z)LG`E_FLs3rf`FTO@5MSrs*fOY8P5r8~(U^)?evB4Q(j8G%1{r(jN%|h;~kvFvETPyj)o=_?D>>QbM z&0y%f)momZoP#2*7v=*oEzQy)q@7HEwp>^t^9OX9p*$CLvfeKY6j@1P$90lnh1V0Y z5N>+KL*-oFmOGs4t}a6*bAwd3AHRaMd)=DVO~AiI6*Lmu%szAW+4ie;>pb(t24jRW zf*Qt35o4P1N)^#BKmA9zD*6=tsw?^31POiEA&A?!^Ts(!Cl?`W8iF-y{KYBC^0Pi1 zZspabz3H9Ka2YIRKSo!rl@~7yl{b(|U@*@`S4WGT8pLS%YBZ#&g>!M~aGjA%I9kl5 zO(?o8`EbhVr5}AM)q)~v%Z{@{pMwZm;`rc2Xh{cjx3dov_{nY+4q!V7=9?b|BluEn zrLfOoVI<8$w7MujjG#>RqMr@vSqd`OtvI7QuNlSDCh zbxJ;rcUFgmQfowi$Cq#0R6}iA%q2!7y-Lb?8}SV?96Z}1dNdkHDLf!ZouJN$T#C%M z=P&NDrc%Kep^adMxp3Ap=zifFx1weD&S0Bx5qBtWzhj86kr+^9%ml0>u`{gnB3vHs zLfoipT6`w7hoX#)F(S!7fyKY3;?qlu%`l=U+Eg#dQzs83VYbgzw>q5U^r~vx(pIxN zyvbu3^QRz)Whuw`zymqYER?(rG_3+yNx~Fxkf4r8XN2$X9^s`xgCum6JIj2(g4IGB z!44CoK!SikP2XZCXd%gJ$~z)#$kagsZIdxhdHY<4Ep9dfN;!=iD@urkICVtcWF$H= zK|S^B>1lMKSMYk1!z$t4#kEROOWO^UH4g^eV^e5YoyX*bSU@v@qnx#re28tKJQJy0CzzaV{!gO<*foVC`G051jT;91wkY?9;`|&^x@@!w{9mf001o2>B8|=l0$`tUVUKfl^=WS$Vc+?_~z%4`sWe!bd+Zj=DFAvcgYeHyw|C5)jEYpW}wlT?{x6lhWHX*a7IzY<8_lW z3YPL3M6B}*j8N&!bXxd)g{Xxz`W;DE?~wr%3lUOk2H@for6+-+xGjwq^$rV3CV(8i ziCRdMv7g01!Y0a_$T*xFokk|iqZKV4oU-P5l`RE3mx}Le-CMMzKIXbMHPF>dJKC;5 z6yQs3XOvU}@YLLoQC?qDV+VC7>)*R ztUcsNjBMf}VoM%_VGah3i^2S2*9`%z=1hmjIc(kN5 zT+QfeX!*mK!RAG1S+0MX>T@w57b2NB;GW#br^}Uz~wE<&}yr^cXhMK zI#ya)(Wca~QUEQ-aCRO`F6iIbbhmG|M!eQ027IQYoA~>0Ykdq3%*GZLTiC z=S5KFahVQa(W#>WwU~$>E0i|EIwIzbqD;jG9n#e^-KCZ7AZC0r%VaXWVosbomgt7H z7k6b2mhfek`&*mMp8|R?;Oj?nCk+6btVID-vezWkDx!3{4&q22Io**^nWjB_3i-2Q zoKi^1m&1jBYZOBImdQ_jb%rZ#^18&~+Ge@@n!3wF*->Aq#RIF1>2>7qPD&dbY~vnq z7ukb3M&(2~xOx}o56!Mu&2RAMCn)a@izioR#ikA2P?{Av^RL^AfeI5;?WHMd$i!2b z<(`#?%9}|E=}{r|2a~c@uMPfz3fX0*KfW=IL2}UFeF?G#u&Phe6kr%w<-a;v`qN3g zslSuJ3Dp)aq#ZoI%%9i2XPo1BauZx!mzgTRF0F{RoY|6Kn4)(Yk9K2v@70N_2iBM} zMeU{!MID)VF*8bNInxd36wSS2>IdCPa@Wv)|C7 zE1KFpZo3J;qf%N>x%5h($Vd_0yLlgFIG-b3*vEACK}FNg4eA^o2bqb)L})xEM@(qL zQuARXL_yv}WE?M|;fcKeQQNr`2YZ82i)aq7e!vxwEb-=zaNMeCT2P^lsT;_vX*!hF z%evGiXxX29_XO=$T2T5U4L?IQS)}rg^B-*)Dg{V%oy|^aA2oc4FYpF>xE+$m`V9KdN=3a+O9bJ+Q9=!-Wg3y|_n6$VJ*KWZ(ZqJAoC#h(LK z_9;XyNL^LZt$;J~iX-9_r8CDv)7)6J`P1{JcCfIDK(ivx`Wrrw)J-0Aqh_cc+qH~o zBi&Xz5o%FW)w`cNIG%p;zAk$T$!aLCigiB#oxku@c+h{lTu+nmd>f&F=_N1#4o-6y zDdH;MOCpPv*13Z;21}=T*ReBY2ZTtf?HrLdg&3$*E_34I=K&8^%$_`04yI~wU-CjLQQ6_k^l(F3=<+rXdTEhW|kA-0BK4U>NRHwU;&i>qxF|>HAe!p?OB${f{oR zPte+!7H77P==uhTf?9o)cEy2U{-juG!!1r8?MdE}KYM;_+S}w`Vq@n>nDnhDEE&K~ zk(ucF+ap?);-%7+jEUAGZCCTBT(09hbFcq@kuDlbkV3hXzz3HPeif$-z&Bf*N>ekC zE_xd~0I5h#EOnP15VLGrl4zl=ci*zj0H}IDyNc&WR}{(ZZjq%8)2FU{aI8x`^ecsc zN-<@c!5QVtbY+^^82s;*ef%10W*~+DsBAM+_agG5{Qle2WC=HrhIlEvMp&t<14Sj7 z_&<>i(|NI&*JMY&LpGeS-}Od(`e3@rT0|k^^Sh-3pgHSjULk@sLCSw?&EQ5jk@cgD zvc?3F^%5^TseRSJYhjEahcQz$nP&b-UIT1?isBjUA@w}@!4k(iwP%1I;-#VT8d3=- zX1VA9r|C(1BMiW5Et&Xx0C6pCdu1Bj`ST^*mJd!VsXyKZc`>)SV$0f+Sx;GJ{Zw*1 zix^b@6}YlYnR*l3Wu3*0nKv^zN>6b<>;kntlM?hmYp3LYrn8Hq@KqokC-1qXxn%x0 zZSHEHcj1BPp?L&i|9c}4_j^EKITJ)JKTXSTRL2!c^C~jPMW0(e-qnvU(9TpiSD~1C z)dry^ZgKqMjBG&OAiPMP;wKw>g1Da(tW_=gA{v!ebF@80cVb$*C*f9TsdS~vM{GIU zD-l8Ntgl2x__6gQK%X?IBH;J*gMoShkAuQQW`Y`vF%4W`yD>A#`tMumC3nGayACvF zJ0^dXVJ6U7z3Uf(&neQx`4Dxg0B;ZOYhUm4yfSwe1-PT(3>Vw><+RxJ*)8RyyU>j% z#ReR~*XqP#^QPlu2qKScxCAG3D;io}b7g9l|qv{ zs8`T~InlHuq!tDY-9}Og0_I+*c~e=c$0tgj4>&W>+m8WF2lv)J|8WR4=4;r}P>;|8$r%mu){pAui0 z9X>D&H4cv80P>=;8!#^sQE>zF(tGZS_G~MUp^-G%Z79mitGmF`!ym`r@5|()Rc4V# zhIGWawf;?T{3*KbM%2rG7_43RHq35PA)~( zbI%34-&DsxSQDfXVPs;sAk)k>hhKGGf3S}lxuly1-;9YJFAx9#a-kLd)u8vQk1Si&rw+ zJKt?pBs+4`kdNF5m9X(xigSjdLTWAX#$g+I3YzinO7(=QyCaU2ZT`7(=5)$VZQ}Pb zbw^BQ$1_zxcVI54;hcf8G>gfacCwm;%C>dfvQk$b=Jh zE-%mb21T_LX$En0CXgZv5VZg)z5Jb&W>OOuv6Sz$RZ{m(&kLyy0uTX=z5juTB&WP( zQnkUda(S~6a0Lsg1Uqvg)J1C2%bqMMXHR}!r*iK^@BE#cn-9&{v5t~|$O3<(7QgAr z1XA>zH-J_L$o+p*-!#^F#5xZu6=rZ6gByHwr)W1oN=Jo7{3u`WD%KRxydZoPH%%Ql zoxvt%p0sMF3{Wl*4d3 zf_u5DS2vvKy6<&bo&u$%lvOy zCak}I%?*Opi2`0xocDxF36+;GXCz~_=gUt}+P%tO0_5IuK~Mbsp>jN^ z#k#tw1nS+qQpUG@p5nyRtCiQk^Ou`L|CyJh_X3X6l$d%QXDVw)fVR@iu_NdPz6o$7 zCDxhzc>{C5-vyL1&5r+QJX+T6=GP880JV`)o@Vx~yYUIbT`xaKrYHx-sCv(Od8yLM zT%bQ!&GaQn6H=!Bm5V;zlgJ+m{=f<3CvA2|+&R7`PivRb-brF<=cW?hjPJhzEF>ei z(GxpzW$Lw(ZIV_)t|KuK9#6}8!T-+B2}SLlH`1^#f)j~ov#00>SLM8=+tfrSBxJGj zI(J!$jhQTVv5GVI8aRs93m=kpJ3|>5N%#g>66~Zb>k5;mtt~nO&$nY^uGeqt5>;6% zAt=4p(X(EJUD|s9AUBNhub^RRf)m*^$q1UuKv)08nU?=JGw%hL?&_Am4{K`cc>%X`Tgw8 zzWOcC1KKPAJkRGMikMn&W`1ibVLxRG0PYVuUPjh$-~LAy#gnr2oQhT?W6pb@^hDJp zjS+YL*8YA@;B$xMx*4|^;eI7Sk{Vmoqk0jAIcfWmG>wbZdb(YZj;M6;w^vc2c zGUZ{zu&AZk_3m^b+Oke=qx0z*xUI9d`|0`d&GE&-?rp8L^JVnq?8j(^<*|>1 zE7?m(JS?N@;o1+5&X1LaVh=Zuz=FVk`Mw`X?~tJfuslQ)5ey9dw=b>Ro9NmZ8Yno} znOYhDTo~v8EDZd@hwS-wm5``IaI!?eC+?MTo0zhu_Ks$0V6xm44o2p9+&hu^-Bd!3tW5Y zZkYGQ3qOYL_R~!loQRhf>S}+q?-KAv_wVm}wk^~hUPe21f4;o`V)f;C>r1rl?UkbS z!TfFWffLf&>A-ro%g3)Q6F;0D7aeMU+^v2QW^%J?;LSF71Z8S^glv9s;>>oke>>Wr zpB>e5?SLm)xhbIlQWht9VH96ZQp2SDB^9y|TByRA#mQVptKabT$n*H#4HZ+BRt&7>$v~K767^K3h7%{4&lnLz<0{aDBB<^*^{m@`(vU>fw0a7w zI8Z_rv!)h&V5V8yl~)-Aaj^JKHs4Td=GhZ?2q96cQBDuwGKNkw)eI-yGLu8=l=DN9 zB&N~Q?7Es&M13^}K20hm4wX=-&#|>|wQ0mMr@l$e?J0}+mYZwcJiLMOJiS!n$2K^B z6sB!4V`Kk&Wd%XG;>As(i7>0YYB8b~KeWZ_bIdj+@|N=k=f2bj2m6Q)RCUJmBH zHYhzCkvK?VgEpexV(3!G_5^2a^K)@TDB+OeEC;nsB8Ralfeqd{!((pSW8H0}JgoWG z`xVA?#fky$LOH5XeZkzh=IlJF#Jq24?%8CzFuY#5i`sG}y1}c*#KYG23W6Ue^g)YK zR2u2NS3GMYe?w(4+NveyW4Cf3zsh5Fg3LwFp!Zo<$9g}y_Zi0!ZXk8NS(cj zora$=&st|SNS|BwVH{5S0?i(}7<~+lxG(m@14hjZt8rn)oj(+AH1fA(TpMO6z8uWp z^O%IUaHESa5r7Cy86ipc54D%Fv{3|jLG*ax558D?ZkaD#vdR zU5X%iCTZcp89O}KD`UF!fJQ4w_0E*A~~PN*`7JS zl2gz{a_c$o>^z0z^qBL7%9urZX2T{?A~&X)lHm9WEsZhSOqI;lg&Cq~C6CNM#3idr zt9N#>1wX?Rdr_;B#GkjXX2JB+- zzYFq#Hs%p0C*u!74_uMDL&`fGhsd1-lbG5QLqjuWYG>YG5)qO3qWtxt4VtBA_{!yw z{r;edl?K!OE0ng5#Zn1sFA6{So8>TdOYyU2^`MV$s-h^m(v%4H9t!L2`);$)l7Jpp(Gw79=~b9ffYJ3^-m}?To~gN*{)tCaG}Jf}$rGiF ziL)TGuMsW~iqJf_aMP^+3KjIrKTK+Y#DfD?n*!eue_Gsc17L)Mp`C)EgToV8{Q8`M zR?pOGPjTc4Jsu|co(sScycfV@0~1f9Ovp-`lTIJ>j>NCe$R%ASDV=YbaMQ#g2t-q{ z+UOZNf@_705QH#w1Ba)Dd)tyq=x)?*Z9MZfgm&I!(rkRJk0t9{NZEo-SB$^lT8fh( zCQ@coe>dWVEKlOQxx0wM^qImz5oqV*gXM!vC=9Mn>}`zs(z=gToZh!%7Ky?sC*J-u znDE-$YSC8C_YcGxN*#+lo&B5lNV^Y8_w*D)jind6Co_)c9Tzh6Rc;R|O0P~<*HFI+ zwpKpO3vqpbH_eH%OhXOdBo`D~ao(r{S-zI@4$VUQS`prkp0<^5aQd8noi={WFOpqg zXoSdx@_X?ZL)2$b=Gq$zD#t84dsVD%=8LpQGHlKa@?(oZu{v>Vf_P|&eZ91kp+E@E zx^dfg)o51-R2dFcD*pNM`9madBE)A`(6j7F4xb#00+|G&CMLwwRO`PU;k{PEL=Te9 zkaf{DI!YW>efI7}c!b2-Wnq9@G0IdP!gne$A2{;1t_aylvhi+tKA8yeg7OGCY|M=t z-@_c5J{Cp<@FfY0K}V8hyGCg|PHrf5YRK0JZnl-vk;NAp`Mq35waP7d(9z_6Bc|K8 zaz9j;q-U#j%`Xbd#Y3*~&g9sFaYRe>P(uT@Rt6-D;W!+IXk0?b#M5fK2E4~c-Z=e zk?q83hvA#h7&pr-eyE7ERoW4W}})Yq=IzNXT%7wM`kDY2)-DHx|jc^uyp53S-AeECZ81>3RLfCD$YhkZY}f2Vr;bcp&M zH@OcS`kd(2!ZFC3eC+?Lyr=))y#L?4|Nnj7m(8h81p;J)0vHdF|4KG=ZEXIRYXAWF z`y(Tc-+T>(9C#Rbk0f#_V%0!R`uQ2@QhqSa3lhsQ1y{Uq%D4$hshW;3+)CLHD!OU)TQ5?qhhv}8@6$J1riJ1Ba(Z^o_@KZkTBfAi}X*o*Dacw|!;!orEL zh^;~YUX09a&ln#k8Tl?pEY4HD1o>lUaU?Ew$skTE{H9}g)&|p2+_$zQlGs~Bn(xXG-(ysI&wTdE9$ zM=M`d(TPIoic|D1z{*sjDz?tdbtd;aGGoo-=41NR$+x@_wxsaDZ3Q~-S)Z{~o3!q<}uMupnOhUe}&>7>~dnVbBrri^cufuWfV1_0{J-y|^{bs<_fq=P5)!b{!!J84{d)4R8~yxw za^W;H{T-fUC7^+Nd)kK#2@Dkq3@lmh>Dm7Smgm~O diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 2bef45cc6b..a52faee482 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -119,7 +119,7 @@ Red/System [ 0A0A0A0A0A0A0A0A0A0A0A3E3E3E3E09093E3E3E3E0C3E3E3E3E3E3E3E3E0909 09093E3E3E3E3E0B3E3E3E3E3E3E3E3E3E3E3E3E0C0C0C0C0C0C0C0C0C0D0C0C 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C3E3E0C0C0C0C0C -0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0E0C0C0C0C0C0C0C0C0C0C +0C0C0C0C0D0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0E0C0C0C0C0C0C0C0C0C0C 3E3E5D5D3E3E5D5D5D5D5D3E5D3E3E3E3E3E3E3E3E3E3E3E3E5D3E3E0E3E5D3E 3E3E3E3E3E3E3E3E5D4D4D0F0F4D4D4D4D4D4D4D0F0F0F0F0F0F0F0F0F0F100F 0F0F0F0F0F4D4D0F0F0F0F0F0F0F3E4D4A4A32324A4A4A4A4A4A4A3E32323232 From 0052fccd704c6839b28f48716f32454b9b6678d3 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 1 Mar 2020 12:31:07 +0100 Subject: [PATCH 1040/3432] FEAT: reports an error on integer literals using sequence of quotes. --- runtime/lexer.reds | 5 +++-- tests/source/units/lexer-test.red | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 53557ecdbe..3374921aff 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1171,9 +1171,11 @@ lexer: context [ ] ][ ;-- process with quote(s) loop len [ - if p/1 <> #"'" [ + either p/1 <> #"'" [ i: 10 * i + as-integer (p/1 - #"0") o?: o? or system/cpu/overflow? + ][ + if any [p + 1 = e p/2 = #"'"][throw-error lex s e TYPE_INTEGER] ] p: p + 1 ] @@ -1188,7 +1190,6 @@ lexer: context [ ] ] if neg? [i: 0 - i] - ;lex/scanned: TYPE_INTEGER if load? [ cell: alloc-slot lex integer/make-at cell i diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 17732d409e..841420c36a 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -551,6 +551,12 @@ Red [ --test-- "tro-111" --assert 123.0 == transcode/one "123." --test-- "tro-112" --assert 0.5 == transcode/one ".5" + --test-- "tro-113" --assert error? try [transcode/one "1'''''''''"] + --test-- "tro-114" --assert error? try [transcode "1''''''''''"] + --test-- "tro-115" --assert error? try [transcode "1'''''''''''"] + --test-- "tro-116" --assert error? try [transcode "1'"] + --test-- "tro-117" --assert error? try [transcode "1''2"] + ===end-group=== ===start-group=== "transcode/next" From f1d20cde0ee9912427c9c247dfd2623af2154229 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 1 Mar 2020 12:32:20 +0100 Subject: [PATCH 1041/3432] TESTS: missing /one refinement in added tests in previous commit. --- tests/source/units/lexer-test.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 841420c36a..7d27fbdff8 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -552,10 +552,10 @@ Red [ --test-- "tro-112" --assert 0.5 == transcode/one ".5" --test-- "tro-113" --assert error? try [transcode/one "1'''''''''"] - --test-- "tro-114" --assert error? try [transcode "1''''''''''"] - --test-- "tro-115" --assert error? try [transcode "1'''''''''''"] - --test-- "tro-116" --assert error? try [transcode "1'"] - --test-- "tro-117" --assert error? try [transcode "1''2"] + --test-- "tro-114" --assert error? try [transcode/one "1''''''''''"] + --test-- "tro-115" --assert error? try [transcode/one "1'''''''''''"] + --test-- "tro-116" --assert error? try [transcode/one "1'"] + --test-- "tro-117" --assert error? try [transcode/one "1''2"] ===end-group=== ===start-group=== "transcode/next" From c5f1a59aaeaf7d1e8464b9ef8c42bac9216f1ae7 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 1 Mar 2020 21:59:15 +0800 Subject: [PATCH 1042/3432] TESTS: avoid overwriting test log on Github Action. --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 32a3204d01..1bbb62cde9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,7 +42,7 @@ jobs: - uses: actions/upload-artifact@v1 if: failure() with: - name: core-test-log + name: core-debug-test-log path: quick-test/quick-test.log View: @@ -126,7 +126,7 @@ jobs: - uses: actions/upload-artifact@v1 if: failure() with: - name: each-test-log + name: each-debug-test-log path: quick-test/quick-test.log Red-System-Test: From 2e9fd94d0868e0be1407a76f46e09dcaf05e9215 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 1 Mar 2020 22:00:17 +0800 Subject: [PATCH 1043/3432] FEAT: reports an error on float literals using sequence of quotes. --- runtime/dtoa.reds | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/dtoa.reds b/runtime/dtoa.reds index 30a2840bd2..6f6294ccd9 100644 --- a/runtime/dtoa.reds +++ b/runtime/dtoa.reds @@ -1316,7 +1316,7 @@ dtoa: context [ to-float: func [ start [byte-ptr!] end [byte-ptr!] - ret [int-ptr!] + ret [int-ptr!] ;-- mandatory return: [float!] /local STRTOD_RETURN STRTOD_OVERFLOW STRTOD_BREAK STRTOD_DROP_DOWN [subroutine!] @@ -1413,6 +1413,7 @@ dtoa: context [ case [ all [c >= #"0" c <= #"9"][s: s + 1] c = #"'" [ + if s/2 = #"'" [ret/value: 1 return rv] move-memory s s + 1 as-integer end - s end: end - 1 ] @@ -1485,7 +1486,7 @@ dtoa: context [ if nd0 <= 0 [nd0: nd] ;-- finish parsing - if ret <> null [ret/value: as-integer s <> end] + ret/value: as-integer s <> end if zero? nd [return either neg? [d/int2: 80000000h rv][0.0]] From fe48c74a4d49555c9e807369b501f76a77d346f7 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 1 Mar 2020 15:49:56 +0100 Subject: [PATCH 1044/3432] FEAT: adds compiler's lexer support for rawstrings syntax. --- lexer.r | 7 +++++++ tests/source/compiler/lexer-test.r | 17 +++++++++++++++++ tests/source/units/lexer-test.red | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index 02788872b0..fb425e9a69 100644 --- a/lexer.r +++ b/lexer.r @@ -568,6 +568,12 @@ lexer: context [ | s: any UTF8-filtered-char e: (value: copy/part s e) ] ] + + rawstr-rule: [ + pos: (type: string! cnt: 0 value: none) some [#"%" (cnt: cnt + 1)] #"{" s: + some [e: #"}" cnt #"%" (value: copy/part s e) break | skip] + (unless value [throw-error]) + ] url-rule: [ #":" (type: url! stop: [not-url-char | ws-no-count]) @@ -615,6 +621,7 @@ lexer: context [ | integer-rule (stack/push value) | decimal-rule (stack/push load-decimal copy/part s e) | tag-rule (stack/push to tag! copy/part s e) + | rawstr-rule (stack/push value) | word-rule (stack/push to type value) | lit-word-rule (stack/push to type value) | get-word-rule (stack/push to type value) diff --git a/tests/source/compiler/lexer-test.r b/tests/source/compiler/lexer-test.r index 5789f32bd7..6d7b1825fe 100644 --- a/tests/source/compiler/lexer-test.r +++ b/tests/source/compiler/lexer-test.r @@ -247,6 +247,23 @@ do %../../../lexer.r }} --assert "#{3D}" = mold second lexer/process src + --test-- "lexer-41" + src: {Red [] + %{abc}% + %{}% + %%{}%% + %{a^^b}% + %{^}}% + %%{Nice^^World^}% rawstring! }%% + } + --assert [ + "abc" + "" + "" + "a^^b" + "}" + "Nice^^World}% rawstring! " + ] = next lexer/process src ===end-group=== diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 7d27fbdff8..7265bbc118 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -377,7 +377,7 @@ Red [ --test-- "tr-37" --assert [""] == transcode "%{}%" --test-- "tr-38" --assert [""] == transcode "%%{}%%" --test-- "tr-39" --assert ["a^^b"] == transcode "%{a^^b}%" - --test-- "tr-40" --assert ["}"] == transcode "%{^}}%" + --test-- "tr-40" --assert ["}"] == transcode "%{}}%" --test-- "tr-41" --assert ["Nice^^World}% rawstring! "] == transcode "%%{Nice^^World}% rawstring! }%%" ===end-group=== From 1a1e6bcad2d34466fc86c729bc8029d84336ad4f Mon Sep 17 00:00:00 2001 From: loziniak Date: Mon, 2 Mar 2020 12:57:23 +0100 Subject: [PATCH 1045/3432] DOCS: move 'either quirks info to wiki --- docs/red-system-specs.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/red-system-specs.txt b/docs/red-system-specs.txt index 4d088ea2e6..f4cec5764f 100644 --- a/docs/red-system-specs.txt +++ b/docs/red-system-specs.txt @@ -2148,13 +2148,6 @@ An alternative way to write it (allowed because all code paths return a value of prin ["a is " msg lf] -\note Known problems -EITHER should not be used as a part of expression, for example this gives incorrect result: - -print 1 * 1 + either 0 <> 0 [1][0] - -/note - ---loop Loop over a block of code, decrementing a counter down to zero. LOOP does not return any value, so it cannot be used in an expression. From a43cdf2d6e6f89ddf9791b987d4338d223461e32 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 2 Mar 2020 15:58:41 +0100 Subject: [PATCH 1046/3432] FEAT: preliminary work on DIVIDE/REMAINDER --- runtime/datatypes/money.reds | 177 ++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 88a9ac1442..3ae1e45bb4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -141,6 +141,30 @@ money: context [ money ] + shift-left: func [ + amount [byte-ptr!] + size [integer!] + offset [integer!] + return: [byte-ptr!] + /local + this that [integer!] + half [byte!] + ][ + loop offset [ + this: 1 + that: this + 1 + loop size [ + half: either that > size [null-byte][amount/that >>> 4] + amount/this: amount/this << 4 or half + + this: this + 1 + that: that + 1 + ] + ] + + amount + ] + shift-right: func [ amount [byte-ptr!] size [integer!] @@ -218,6 +242,66 @@ money: context [ either zero? count [1][count] ] + ;-- Slices -- + + compare-slices: func [ + this-buffer [byte-ptr!] this-high? [logic!] this-count [integer!] + that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] + return: [integer!] + /local + delta index1 index2 end this that [integer!] + ][ + delta: integer/abs this-count - that-count + switch integer/sign? this-count - that-count [ + -1 [index1: 1 - delta index2: 1 end: that-count] + 00 [index1: 1 index2: 1 end: this-count] + +1 [index2: 1 - delta index1: 1 end: this-count] + default [0] + ] + + index1: index1 + as integer! this-high? + index2: index2 + as integer! that-high? + + until [ + this: either index1 < 1 [0][get-digit this-buffer index1] + that: either index2 < 1 [0][get-digit that-buffer index2] + + index1: index1 + 1 + index2: index2 + 1 + end: end - 1 + + any [this <> that zero? end] + ] + + this - that + ] + + subtract-slice: func [ + this-buffer [byte-ptr!] this-high? [logic!] this-count [integer!] + that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] + /local + this that borrow difference [integer!] + ][ + this-count: this-count + as integer! this-high? + that-count: that-count + as integer! that-high? + borrow: 0 + until [ + this: get-digit this-buffer this-count + that: either that-count < 1 [0][get-digit that-buffer that-count] + + difference: this - that - borrow + borrow: as integer! difference < 0 + if as logic! borrow [difference: difference + 10] + + set-digit this-buffer this-count difference + + this-count: this-count - 1 + that-count: that-count - 1 + + zero? this-count + ] + ] + ;-- Construction -- make-at: func [ @@ -612,6 +696,95 @@ money: context [ set-sign multiplicand sign ] + divide-money: func [ + dividend [red-money!] + divisor [red-money!] + remainder? [logic!] + only? [logic!] + return: [red-money!] + /local + shift increment subtract [subroutine!] + greater? greatest? [subroutine!] + left-amount right-amount [byte-ptr!] + left-start right-start [byte-ptr!] + quotient old [byte-ptr!] + dividend-sign divisor-sign sign [integer!] + left-count right-count [integer!] + digits index [integer!] + left-high? right-high? [logic!] + ][ + dividend-sign: sign? dividend + divisor-sign: sign? divisor + + DISPATCH_SIGNS(dividend-sign divisor-sign)[ + SIGN_00 + SIGN_+0 + SIGN_-0 [fire [TO_ERROR(math zero-divide)]] + SIGN_0- + SIGN_0+ [return dividend] + default [sign: as integer! dividend-sign <> divisor-sign] + ] + + left-amount: get-amount dividend + right-amount: get-amount divisor + + unless only? [shift-left left-amount SIZE_BYTES SIZE_SCALE] + + left-count: count-digits left-amount + right-count: count-digits right-amount + + ;@@ TBD: overflow heuristics + + left-high?: as logic! left-count and 1 + right-high?: as logic! right-count and 1 + + left-start: left-amount + (SIZE_DIGITS - left-count >> 1) + right-start: right-amount + (SIZE_DIGITS - right-count >> 1) + + digits: either left-count < right-count [left-count][right-count] + + index: SIZE_DIGITS - (integer/abs left-count - right-count) - SIZE_SCALE + quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + + shift: [ + digits: digits + 1 + index: index + 1 + ] + subtract: [ + subtract-slice + left-start left-high? digits + right-start right-high? right-count + ] + increment: [ + set-digit quotient index (get-digit quotient index) + 1 + ] + greater?: [ + compare-slices + right-start right-high? right-count + left-start left-high? digits + ] + greatest?: [ + compare-slices + right-start right-high? right-count + left-start left-high? left-count + ] + + until [ + either greater? > 0 [either greatest? > 0 [yes][shift no]][ + subtract increment no + ] + ] + + unless remainder? [ + unless only? [shift-right quotient SIZE_BYTES SIZE_SCALE] + copy-memory left-amount quotient SIZE_BYTES + ] + + ;@@ TBD: check overflow / underflow + + set-sign dividend sign + ] + do-math: func [ left [red-money!] right [red-money!] @@ -868,11 +1041,11 @@ money: context [ ;-- Scalar actions -- :absolute :add - null;:divide + :divide :multiply :negate null ;power - null;:remainder + :remainder null;:round :subtract :even? From c7f0fead28deb3de565e04c996b0506eb8e5ef28 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 2 Mar 2020 15:58:57 +0100 Subject: [PATCH 1047/3432] FIX: typo in struct layout description --- runtime/datatypes/structures.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/structures.reds b/runtime/datatypes/structures.reds index e3a13cffe2..1b4c071c85 100644 --- a/runtime/datatypes/structures.reds +++ b/runtime/datatypes/structures.reds @@ -333,8 +333,8 @@ red-handle!: alias struct! [ red-money!: alias struct! [ header [integer!] ;-- cell header - amount1 [integer!] ;-- 1 bytes for currency index - amount2 [integer!] ;-- 11 bytes for BCD encoded amount + amount1 [integer!] ;-- 1 byte for currency index + amount2 [integer!] ;-- 11 bytes for BCD-encoded amount amount3 [integer!] ;-- (unsigned, packed) ] From 01aee5bf60b169722ef1c888e84a29dac72d07bd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 2 Mar 2020 16:00:19 +0100 Subject: [PATCH 1048/3432] FEAT: refactor DO-MATH and math-related actions --- runtime/datatypes/integer.reds | 5 +- runtime/datatypes/money.reds | 101 ++++++++++----------------------- 2 files changed, 30 insertions(+), 76 deletions(-) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index 63e132127a..8678474fcc 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -246,10 +246,7 @@ integer: context [ left/value: do-math-op left/value right/value op ] TYPE_MONEY [ - left: as red-integer! money/do-math - money/from-integer left/value - as red-money! right - op + left: as red-integer! money/do-math op ] TYPE_FLOAT TYPE_PERCENT TYPE_TIME [float/do-math op] TYPE_PAIR diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3ae1e45bb4..fb346bd4ac 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -791,16 +791,32 @@ money: context [ op [integer!] return: [red-value!] /local - int [red-integer!] - result [red-money!] + left right [red-money!] + integer [red-integer!] + result [red-money!] ][ + left: as red-money! stack/arguments + right: left + 1 + ;@@ TBD: take currencies into account + switch TYPE_OF(left) [ + TYPE_MONEY [0] + TYPE_INTEGER [ + integer: as red-integer! left + left: from-integer integer/value + ] + TYPE_FLOAT [--NOT_IMPLEMENTED--] + default [ + fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(left)] + ] + ] + switch TYPE_OF(right) [ TYPE_MONEY [0] TYPE_INTEGER [ - int: as red-integer! right - right: from-integer int/value + integer: as red-integer! right + right: from-integer integer/value ] TYPE_FLOAT [--NOT_IMPLEMENTED--] default [ @@ -812,8 +828,8 @@ money: context [ OP_ADD [add-money left right] OP_SUB [subtract-money left right] OP_MUL [multiply-money left right] - OP_DIV - OP_REM [--NOT_IMPLEMENTED-- left] + OP_DIV [divide-money left right no no] + OP_REM [divide-money left right yes no] default [ fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] left @@ -936,73 +952,14 @@ money: context [ compare-money money value ] - absolute: func [return: [red-money!]][ - absolute-money as red-money! stack/arguments - ] - - negate: func [return: [red-money!]][ - negate-money as red-money! stack/arguments - ] + absolute: func [return: [red-money!]][absolute-money as red-money! stack/arguments] + negate: func [return: [red-money!]][negate-money as red-money! stack/arguments] - add: func [ - return: [red-value!] - /local - left [red-money!] - right [red-money!] - ][ - left: as red-money! stack/arguments - right: left + 1 - - do-math left right OP_ADD - ] - - subtract: func [ - return: [red-value!] - /local - left [red-money!] - right [red-money!] - ][ - left: as red-money! stack/arguments - right: left + 1 - - do-math left right OP_SUB - ] - - multiply: func [ - return: [red-value!] - /local - left [red-money!] - right [red-money!] - ][ - left: as red-money! stack/arguments - right: left + 1 - - do-math left right OP_MUL - ] - - divide: func [ - return: [red-value!] - /local - left [red-money!] - right [red-money!] - ][ - left: as red-money! stack/arguments - right: left + 1 - - do-math left right OP_DIV - ] - - remainder: func [ - return: [red-value!] - /local - left [red-money!] - right [red-money!] - ][ - left: as red-money! stack/arguments - right: left + 1 - - do-math left right OP_REM - ] + add: func [return: [red-value!]][do-math OP_ADD] + subtract: func [return: [red-value!]][do-math OP_SUB] + multiply: func [return: [red-value!]][do-math OP_MUL] + divide: func [return: [red-value!]][do-math OP_DIV] + remainder: func [return: [red-value!]][do-math OP_REM] round: STUB From a4c613137a69831d17e2cbab1f7cc4bd4b850cfb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 2 Mar 2020 16:00:41 +0100 Subject: [PATCH 1049/3432] FEAT: improve formatting and coding style --- runtime/datatypes/money.reds | 52 ++++++++++++++---------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index fb346bd4ac..879a648dba 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -78,10 +78,7 @@ money: context [ sign [integer!] return: [red-money!] ][ - money/header: money/header - and (not SIGN_MASK) - or (sign << SIGN_OFFSET) - + money/header: money/header and (not SIGN_MASK) or (sign << SIGN_OFFSET) money ] @@ -178,7 +175,7 @@ money: context [ this: size that: this - 1 loop size [ - half: either that <= 0 [null-byte][amount/that << 4] + half: either that < 1 [null-byte][amount/that << 4] amount/this: amount/this >>> 4 or half this: this - 1 @@ -202,9 +199,7 @@ money: context [ byte: index >> 1 + bit offset: either as logic! bit [4][0] - as integer! amount/byte - and (HIGH_NIBBLE << offset) - >>> offset + as integer! amount/byte and (HIGH_NIBBLE << offset) >>> offset ] set-digit: func [ @@ -219,9 +214,7 @@ money: context [ offset: either as logic! bit [4][0] reverse: either zero? offset [4][0] - amount/byte: amount/byte - and (HIGH_NIBBLE << reverse) - or as byte! (value << offset) + amount/byte: amount/byte and (HIGH_NIBBLE << reverse) or as byte! (value << offset) ] count-digits: func [ @@ -341,8 +334,8 @@ money: context [ limit: start index: SIZE_INTEGRAL stop: 0 + step: -1 - step: -1 convert if null? point [return money] @@ -351,8 +344,8 @@ money: context [ limit: end index: SIZE_INTEGRAL + 1 stop: SIZE_DIGITS + 1 + step: +1 - step: +1 convert money @@ -383,7 +376,7 @@ money: context [ return: [integer!] /local amount [byte-ptr!] - sign integer index + sign integer index [integer!] start power digit [integer!] ][ sign: sign? money @@ -412,7 +405,7 @@ money: context [ /local money [red-money!] amount [byte-ptr!] - extra index start + extra index start [integer!] power digit [integer!] ][ money: zero-out as red-money! stack/push* yes @@ -520,7 +513,7 @@ money: context [ return: [red-money!] /local left-amount right-amount [byte-ptr!] - augend-sign addend-sign + augend-sign addend-sign [integer!] index carry left right sum [integer!] ][ augend-sign: sign? augend @@ -569,7 +562,7 @@ money: context [ return: [red-money!] /local left-amount right-amount [byte-ptr!] - minuend-sign subtrahend-sign sign + minuend-sign subtrahend-sign sign [integer!] index borrow left right difference [integer!] lesser? flag [logic!] ][ @@ -626,10 +619,10 @@ money: context [ return: [red-money!] /local left-amount right-amount product [byte-ptr!] - multiplicand-sign multiplier-sign sign - left-count right-count - delta index1 index2 index3 - carry left right other prod [integer!] + multiplicand-sign multiplier-sign sign [integer!] + left-count right-count [integer!] + delta index1 index2 index3 [integer!] + carry left right other result [integer!] ][ multiplicand-sign: sign? multiplicand multiplier-sign: sign? multiplier @@ -670,11 +663,11 @@ money: context [ right: get-digit right-amount index1 other: get-digit product index3 - prod: left * right + other + carry - carry: prod / 10 - prod: prod // 10 + result: left * right + other + carry + carry: result / 10 + result: result // 10 - set-digit product index3 prod + set-digit product index3 result index2: index2 - 1 ] @@ -688,10 +681,7 @@ money: context [ ;@@ TBD: round to nearest, check underflow shift-right product SIZE_SBYTES SIZE_SCALE - copy-memory - left-amount - product + SIZE_BUFFER - SIZE_BYTES - SIZE_BYTES + copy-memory left-amount product + SIZE_BUFFER - SIZE_BYTES SIZE_BYTES set-sign multiplicand sign ] @@ -786,8 +776,6 @@ money: context [ ] do-math: func [ - left [red-money!] - right [red-money!] op [integer!] return: [red-value!] /local @@ -989,7 +977,7 @@ money: context [ :make null;:random null ;reflect - :make + :make ;-- to :form :mold null ;eval-path From f04a29e8cfb1d63c7007722ad44280aaa214fa77 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 2 Mar 2020 21:11:44 +0100 Subject: [PATCH 1050/3432] FEAT: preliminary work on precise division --- runtime/datatypes/money.reds | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 879a648dba..c3db1f75db 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -697,7 +697,7 @@ money: context [ greater? greatest? [subroutine!] left-amount right-amount [byte-ptr!] left-start right-start [byte-ptr!] - quotient old [byte-ptr!] + quotient hold [byte-ptr!] dividend-sign divisor-sign sign [integer!] left-count right-count [integer!] digits index [integer!] @@ -717,13 +717,19 @@ money: context [ left-amount: get-amount dividend right-amount: get-amount divisor - - unless only? [shift-left left-amount SIZE_BYTES SIZE_SCALE] - + left-count: count-digits left-amount right-count: count-digits right-amount - ;@@ TBD: overflow heuristics + if left-count + (SIZE_SCALE + 1 - right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + + unless any [remainder? only?][ + hold: left-amount + left-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + copy-memory left-amount hold SIZE_BYTES + shift-left left-amount SIZE_SBYTES SIZE_SCALE + left-count: left-count + SIZE_SCALE + ] left-high?: as logic! left-count and 1 right-high?: as logic! right-count and 1 @@ -766,7 +772,10 @@ money: context [ ] unless remainder? [ - unless only? [shift-right quotient SIZE_BYTES SIZE_SCALE] + unless only? [ + left-amount: hold + shift-right quotient SIZE_BYTES SIZE_SCALE + ] copy-memory left-amount quotient SIZE_BYTES ] From e7bc377c9eefd788878eb3b3864e707089b3d03a Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 3 Mar 2020 16:34:27 +0800 Subject: [PATCH 1051/3432] FIX: issue #4313 (GUI console prints NL at head when one is at tail). --- environment/console/GUI/core.red | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index 84b159e9f2..186e032c35 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -122,10 +122,10 @@ object [ calc-top ] - vprint: func [str [string!] lf? [logic!] /local s cnt][ + vprint: func [str [string!] lf? [logic!] /local s cnt first-prin?][ unless console/state [exit] - if all [not lf? newline?][newline?: no add-line make string! 8] + if all [not lf? newline?][newline?: no first-prin?: yes] if lf? [newline?: yes] s: find str lf either s [ @@ -140,13 +140,14 @@ object [ ] not s: find str lf ] - either str/1 = lf [ - add-line "" - ][ + either all [empty? str lf = first back str][add-line copy ""][ either all [lf? not prin?][add-line copy str][vprin str] ] ][ - either all [lf? not prin?][add-line copy str][vprin str] + either all [lf? not prin?][add-line copy str][ + if first-prin? [add-line make string! 8] + vprin str + ] ] prin?: not lf? if system/console/running? [ From b01435851863599be61646821834a9dd39e68099 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 11:56:25 +0100 Subject: [PATCH 1052/3432] FEAT: implement precise division ONLY? mode is reserved for cases where only integral part is needed. --- runtime/datatypes/money.reds | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index c3db1f75db..318bf59f39 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -700,7 +700,7 @@ money: context [ quotient hold [byte-ptr!] dividend-sign divisor-sign sign [integer!] left-count right-count [integer!] - digits index [integer!] + size digits index [integer!] left-high? right-high? [logic!] ][ dividend-sign: sign? dividend @@ -717,31 +717,36 @@ money: context [ left-amount: get-amount dividend right-amount: get-amount divisor - + left-count: count-digits left-amount right-count: count-digits right-amount + ;@@ TBD: overflow heuristics if left-count + (SIZE_SCALE + 1 - right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + size: SIZE_DIGITS unless any [remainder? only?][ + size: SIZE_SBYTES << 1 hold: left-amount + + left-count: left-count + SIZE_SCALE left-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES - copy-memory left-amount hold SIZE_BYTES + + copy-memory left-amount + (SIZE_SBYTES - SIZE_BYTES) hold SIZE_BYTES shift-left left-amount SIZE_SBYTES SIZE_SCALE - left-count: left-count + SIZE_SCALE ] left-high?: as logic! left-count and 1 right-high?: as logic! right-count and 1 - left-start: left-amount + (SIZE_DIGITS - left-count >> 1) + left-start: left-amount + (size - left-count >> 1) right-start: right-amount + (SIZE_DIGITS - right-count >> 1) digits: either left-count < right-count [left-count][right-count] - index: SIZE_DIGITS - (integer/abs left-count - right-count) - SIZE_SCALE + index: size - (integer/abs left-count - right-count) - SIZE_SCALE quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES - + shift: [ digits: digits + 1 index: index + 1 @@ -773,8 +778,9 @@ money: context [ unless remainder? [ unless only? [ + shift-right quotient SIZE_SBYTES SIZE_SCALE + quotient: quotient + (SIZE_SBYTES - SIZE_BYTES) left-amount: hold - shift-right quotient SIZE_BYTES SIZE_SCALE ] copy-memory left-amount quotient SIZE_BYTES ] From 240ede07972822cc6b0ef0c515bd342873ed5980 Mon Sep 17 00:00:00 2001 From: loziniak Date: Tue, 3 Mar 2020 13:43:45 +0100 Subject: [PATCH 1053/3432] FEAT: log-2 in Red/System --- runtime/natives.reds | 4 ++-- system/runtime/libc.reds | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index c67fc407c5..f8e30d9eef 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1798,7 +1798,7 @@ natives: context [ ][ #typecheck log-2 f: argument-as-float - f/value: (log-2 f/value) / 0.6931471805599453 + f/value: log-2 f/value ] log-10*: func [ @@ -1818,7 +1818,7 @@ natives: context [ ][ #typecheck log-e f: argument-as-float - f/value: log-2 f/value + f/value: log-e f/value ] exp*: func [ diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds index bd33977270..5b86d2ec23 100644 --- a/system/runtime/libc.reds +++ b/system/runtime/libc.reds @@ -135,7 +135,11 @@ Red/System [ value [float!] return: [float!] ] - log-2: "log" [ + log-e: "log" [ + value [float!] + return: [float!] + ] + log-2: "log2" [ value [float!] return: [float!] ] From a33b16fdfc3b4626f78171c8dd529404efcada87 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 15:56:54 +0100 Subject: [PATCH 1054/3432] FEAT: add support for MONEY! in MOD and MODULO --- environment/functions.red | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 876f12a651..db0af83f21 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -559,9 +559,9 @@ pad: func [ mod: func [ "Compute a nonnegative remainder of A divided by B" - a [number! char! pair! tuple! vector! time!] - b [number! char! pair! tuple! vector! time!] "Must be nonzero" - return: [number! char! pair! tuple! vector! time!] + a [number! money! char! pair! tuple! vector! time!] + b [number! money! char! pair! tuple! vector! time!] "Must be nonzero" + return: [number! money! char! pair! tuple! vector! time!] /local r ][ if (r: a % b) < 0 [r: r + b] @@ -571,9 +571,9 @@ mod: func [ modulo: func [ "Wrapper for MOD that handles errors like REMAINDER. Negligible values (compared to A and B) are rounded to zero" - a [number! char! pair! tuple! vector! time!] - b [number! char! pair! tuple! vector! time!] - return: [number! char! pair! tuple! vector! time!] + a [number! money! char! pair! tuple! vector! time!] + b [number! money! char! pair! tuple! vector! time!] + return: [number! money! char! pair! tuple! vector! time!] /local r ][ r: mod a absolute b From ecdb002bcf39e87a31e38567b9041ae2da7b3a17 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 15:59:17 +0100 Subject: [PATCH 1055/3432] FEAT: minor corrections --- runtime/datatypes/money.reds | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 318bf59f39..10a7f3008e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -794,9 +794,8 @@ money: context [ op [integer!] return: [red-value!] /local - left right [red-money!] - integer [red-integer!] - result [red-money!] + left right result [red-money!] + integer [red-integer!] ][ left: as red-money! stack/arguments right: left + 1 @@ -865,7 +864,7 @@ money: context [ ] TYPE_FLOAT [--NOT_IMPLEMENTED--] default [ - fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] + fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY spec] ] ] From fecf4ea01664984090a452f9c10a6d05f945bb38 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 16:00:20 +0100 Subject: [PATCH 1056/3432] FEAT: implement overflow detection in division --- runtime/datatypes/money.reds | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 10a7f3008e..8a151096e4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -697,10 +697,10 @@ money: context [ greater? greatest? [subroutine!] left-amount right-amount [byte-ptr!] left-start right-start [byte-ptr!] - quotient hold [byte-ptr!] + quotient buffer hold [byte-ptr!] dividend-sign divisor-sign sign [integer!] left-count right-count [integer!] - size digits index [integer!] + size overflow digits index [integer!] left-high? right-high? [logic!] ][ dividend-sign: sign? dividend @@ -721,16 +721,17 @@ money: context [ left-count: count-digits left-amount right-count: count-digits right-amount - ;@@ TBD: overflow heuristics - if left-count + (SIZE_SCALE + 1 - right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + if left-count + (SIZE_SCALE + 1 - right-count) > SIZE_DIGITS [MONEY_OVERFLOW] size: SIZE_DIGITS + overflow: SIZE_SBYTES << 1 - SIZE_DIGITS + unless any [remainder? only?][ size: SIZE_SBYTES << 1 hold: left-amount - left-count: left-count + SIZE_SCALE left-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + left-count: left-count + SIZE_SCALE copy-memory left-amount + (SIZE_SBYTES - SIZE_BYTES) hold SIZE_BYTES shift-left left-amount SIZE_SBYTES SIZE_SCALE @@ -746,6 +747,9 @@ money: context [ index: size - (integer/abs left-count - right-count) - SIZE_SCALE quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + buffer: quotient + + if any [remainder? only?][quotient: quotient + SIZE_SBYTES - SIZE_BYTES - 1] shift: [ digits: digits + 1 @@ -769,12 +773,8 @@ money: context [ right-start right-high? right-count left-start left-high? left-count ] - - until [ - either greater? > 0 [either greatest? > 0 [yes][shift no]][ - subtract increment no - ] - ] + ;@@ TBD: bug with subroutines + until [either greater? > 0 [either greatest? > 0 [yes][shift no]][subtract increment no]] unless remainder? [ unless only? [ @@ -782,10 +782,11 @@ money: context [ quotient: quotient + (SIZE_SBYTES - SIZE_BYTES) left-amount: hold ] + unless zero? get-digit buffer overflow [MONEY_OVERFLOW] copy-memory left-amount quotient SIZE_BYTES ] - ;@@ TBD: check overflow / underflow + ;@@ TBD: check underflow set-sign dividend sign ] From 34017cec9b9dd2851b03f911a83571b271aa0ebc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 17:03:54 +0100 Subject: [PATCH 1057/3432] FEAT: minor refactoring --- runtime/datatypes/money.reds | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 8a151096e4..69ea678c66 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -679,9 +679,10 @@ money: context [ unless zero? get-digit product 1 [MONEY_OVERFLOW] - ;@@ TBD: round to nearest, check underflow - shift-right product SIZE_SBYTES SIZE_SCALE - copy-memory left-amount product + SIZE_BUFFER - SIZE_BYTES SIZE_BYTES + ;@@ TBD: check underflow + product: product + SIZE_BUFFER - SIZE_BYTES + shift-right product SIZE_BYTES SIZE_SCALE + copy-memory left-amount product SIZE_BYTES set-sign multiplicand sign ] From 50e90ab28336f7e50462472a4ce4a70f3f452694 Mon Sep 17 00:00:00 2001 From: loziniak Date: Tue, 3 Mar 2020 17:14:01 +0100 Subject: [PATCH 1058/3432] FIX: random integer uniform distribution (rejection sampling) --- runtime/datatypes/date.reds | 4 ++-- runtime/datatypes/integer.reds | 5 +---- runtime/datatypes/pair.reds | 6 ++---- runtime/datatypes/series.reds | 4 ++-- runtime/datatypes/tuple.reds | 4 +--- runtime/random.reds | 32 +++++++++++++++++++++++++++++++- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/runtime/datatypes/date.reds b/runtime/datatypes/date.reds index 8c8b232830..07064bbd9b 100644 --- a/runtime/datatypes/date.reds +++ b/runtime/datatypes/date.reds @@ -734,8 +734,8 @@ date: context [ ][ time?: DATE_GET_TIME_FLAG(d) - rnd: either secure? [_random/rand-secure] [_random/rand] ;-- a workaround for issue #3620 - dt/date: days-to-date rnd % (date-to-days d) DATE_GET_ZONE(d) time? + rnd: _random/int-uniform-distr secure? date-to-days d + dt/date: days-to-date rnd - 1 DATE_GET_ZONE(d) time? if time? [ dt/date: either secure? [ DATE_SET_ZONE(dt/date _random/rand-secure) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index e8646f59d4..b90ccc4c01 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -349,8 +349,6 @@ integer: context [ secure? [logic!] only? [logic!] return: [red-value!] - /local - n [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "integer/random"]] @@ -359,8 +357,7 @@ integer: context [ int/header: TYPE_UNSET ][ unless zero? int/value [ - n: (either secure? [_random/rand-secure] [_random/rand]) % int/value + 1 - int/value: either negative? int/value [0 - n][n] + int/value: _random/int-uniform-distr secure? int/value ] ] as red-value! int diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index 7a127bf389..cbdb2afcd4 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -195,12 +195,10 @@ pair: context [ pair/header: TYPE_UNSET ][ unless zero? pair/x [ - n: (either secure? [_random/rand-secure] [_random/rand]) % pair/x + 1 - pair/x: either negative? pair/x [0 - n][n] + pair/x: _random/int-uniform-distr secure? pair/x ] unless zero? pair/y [ - n: (either secure? [_random/rand-secure] [_random/rand]) % pair/y + 1 - pair/y: either negative? pair/y [0 - n][n] + pair/y: _random/int-uniform-distr secure? pair/y ] ] as red-value! pair diff --git a/runtime/datatypes/series.reds b/runtime/datatypes/series.reds index 4d2debc12d..3b24ca49f6 100644 --- a/runtime/datatypes/series.reds +++ b/runtime/datatypes/series.reds @@ -119,7 +119,7 @@ _series: context [ either only? [ either positive? size [ - idx: head + ((either secure? [_random/rand-secure] [_random/rand]) % size << (log-b unit)) + idx: head + ((-1 + _random/int-uniform-distr secure? size) << (log-b unit)) switch TYPE_OF(ser) [ TYPE_BLOCK TYPE_HASH @@ -148,7 +148,7 @@ _series: context [ len: size temp: as byte-ptr! :val while [size > 0][ - idx: head + ((either secure? [_random/rand-secure] [_random/rand]) % size << (log-b unit)) + idx: head + ((-1 + _random/int-uniform-distr secure? size) << (log-b unit)) if idx <> head [ copy-memory temp head unit copy-memory head idx unit diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index af117875c5..bfa2b0c427 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -251,7 +251,6 @@ tuple: context [ array [byte-ptr!] n [integer!] size [integer!] - rnd [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "tuple/random"]] @@ -264,9 +263,8 @@ tuple: context [ size: TUPLE_SIZE?(tp) n: 0 until [ - rnd: either secure? [_random/rand-secure] [_random/rand] n: n + 1 - array/n: as-byte rnd % ((as-integer array/n) + 1) + array/n: as-byte (-1 + _random/int-uniform-distr secure? as-integer (array/n + 1)) n = size ] ] diff --git a/runtime/random.reds b/runtime/random.reds index 9f14bc30a6..3044e77a24 100644 --- a/runtime/random.reds +++ b/runtime/random.reds @@ -98,7 +98,37 @@ _random: context [ crypto/urandom (as byte-ptr! :i) 4 i and 7FFFFFFFh ;-- range 0-2147483647 inclusive ] - + + int-uniform-distr: func [ + secure? [logic!] + max [integer!] + return: [integer!] + /local + mask [integer!] + rnd [integer!] + neg? [logic!] + ] [ + if max = 0 [return 0] + either max < 0 [ + max: 0 - max + neg?: true + ] [ + neg?: false + ] + mask: 7FFFFFFFh >> (30 - (as-integer floor log-2 as-float (max - 1))) + until [ + rnd: either secure? [rand-secure] [rand] + rnd: rnd and mask + max > rnd + ] + rnd: rnd + 1 + either neg? [ + 0 - rnd + ] [ + rnd + ] + ] + init: does [ table: as int-ptr! allocate MT_RANDOM_STATE_SIZE * size? integer! srand 19650218 From 95868f9b3acd42b8ecf7a0bd4edf83b7da9e72ac Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 17:33:58 +0100 Subject: [PATCH 1059/3432] FEAT: underflow detections --- runtime/datatypes/money.reds | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 69ea678c66..b7d8c01997 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -43,7 +43,7 @@ money: context [ #define DISPATCH_SIGNS(this that) [switch collate-signs this that] #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] - #define MONEY_OVERFLOW [fire [TO_ERROR(math overflow)]] + #define MONEY_OVERFLOW [fire [TO_ERROR(script type-limit) datatype/push TYPE_MONEY]] SIZE_DIGITS: SIZE_BYTES * 2 SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE @@ -679,11 +679,12 @@ money: context [ unless zero? get-digit product 1 [MONEY_OVERFLOW] - ;@@ TBD: check underflow product: product + SIZE_BUFFER - SIZE_BYTES + shift-right product SIZE_BYTES SIZE_SCALE - copy-memory left-amount product SIZE_BYTES + if zero-amount? product [MONEY_OVERFLOW] + copy-memory left-amount product SIZE_BYTES set-sign multiplicand sign ] @@ -783,12 +784,11 @@ money: context [ quotient: quotient + (SIZE_SBYTES - SIZE_BYTES) left-amount: hold ] + if zero-amount? quotient [MONEY_OVERFLOW] unless zero? get-digit buffer overflow [MONEY_OVERFLOW] copy-memory left-amount quotient SIZE_BYTES ] - ;@@ TBD: check underflow - set-sign dividend sign ] From 797af441ef5607b74aeb864aa23f3dafe3165680 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 3 Mar 2020 18:21:51 +0100 Subject: [PATCH 1060/3432] FIX: checking logic value on top of stack not always correct. When a `return` is used in Red code, the resulting stack on function's exit has stack/top = stack/arguments, while logic/top-false? expects stack/top = stack/arguments + 1. --- runtime/datatypes/logic.reds | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/datatypes/logic.reds b/runtime/datatypes/logic.reds index 1bc77c2f17..705a133e1e 100644 --- a/runtime/datatypes/logic.reds +++ b/runtime/datatypes/logic.reds @@ -51,9 +51,8 @@ logic: context [ arg [red-logic!] type [integer!] ][ - arg: as red-logic! stack/get-top + arg: as red-logic! either stack/top = stack/arguments [stack/top][stack/get-top] type: TYPE_OF(arg) - any [ type = TYPE_NONE all [type = TYPE_LOGIC not arg/value] From 500db45f5252edd936c5892ce5b4891419951b8c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 3 Mar 2020 18:23:05 +0100 Subject: [PATCH 1061/3432] FIX: avoids returned values from lexer callback accumulating on the stack. Should eventually apply this to Parse's callback too. --- runtime/lexer.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 3374921aff..efcc516483 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -487,6 +487,7 @@ lexer: context [ ] cont?: logic/top-true? stack/unwind + stack/pop 1 cont? ] From 725e9a446cf18d62675821ba2eb098a741bd1ebd Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 3 Mar 2020 18:42:13 +0100 Subject: [PATCH 1062/3432] TESTS: adds a new lexer callback test on wrongly formed paths and blocks. --- tests/source/units/lexer-test.red | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 7265bbc118..5aa9b7d19c 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -1021,6 +1021,48 @@ Red [ load word! datatype! 5 world ] + --test-- "tt-14" + lex-filter14: function [ + event [word!] + input [string! binary!] + type [datatype! word! none!] + line [integer!] + token + return: [logic!] + ][ + t: tail logs + reduce/into [event to-word type to-word type? type line token] tail logs + new-line t yes + if event = 'error [input: next input return false] + true + ] + + clear logs + --assert none? transcode/trace "a: [b/c/ d/e" :lex-filter14 + --assert logs = [ + prescan word! datatype! 1 1x3 + scan set-word! word! 1 1x3 + load set-word! datatype! 1 a: + prescan block! word! 1 4x4 + open block! datatype! 1 4x4 + prescan path! word! 1 5x6 + open path! datatype! 1 5x5 + load word! datatype! 1 b + prescan word! datatype! 1 7x8 + scan word! word! 1 7x8 + load word! datatype! 1 c + prescan error! datatype! 1 9x9 + error error! datatype! 1 9x9 + prescan path! word! 1 10x11 + open path! datatype! 1 10x10 + load word! datatype! 1 d + prescan word! datatype! 1 12x13 + scan word! word! 1 12x13 + load word! datatype! 1 e + close path! datatype! 1 12x13 + error error! datatype! 1 4x13 + ] + ===end-group=== From 7cc70602fadd6ff4ffa8f9ed582d88b1fcfa1513 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 3 Mar 2020 19:40:22 +0100 Subject: [PATCH 1063/3432] FIX: [R/S] subroutines not always returning correct logic! value. --- system/compiler.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/compiler.r b/system/compiler.r index 2b5e5084f8..90e5ea35bb 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -2003,7 +2003,7 @@ system-dialect: make-profilable context [ in-subroutine?: name fetch-into reduce [code][ chunk: comp-chunked [emitter/target/emit-init-sub] - set [expr body] comp-block-chunked ;-- compiles subroutine's body + set [expr body] comp-block-chunked/bool ;-- compiles subroutine's body subs/2: reduce [base + length? chunks/1 get-type expr make block! 4] ;-- [start-ptr type [call-sites]] emitter/chunks/join chunk body ret: comp-chunked [emitter/target/emit-return-sub] From c8055a1c45589478db266c77a3c9e1a960597983 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 3 Mar 2020 20:04:03 +0100 Subject: [PATCH 1064/3432] FEAT: improve code formatting --- runtime/datatypes/money.reds | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b7d8c01997..6fc633bacd 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -644,10 +644,7 @@ money: context [ if (left-count + right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] - product: set-memory - as byte-ptr! system/stack/allocate SIZE_SSLOTS - null-byte - SIZE_SBYTES + product: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES delta: SIZE_DIGITS - SIZE_BUFFER << 1 index1: SIZE_DIGITS @@ -735,7 +732,7 @@ money: context [ left-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES left-count: left-count + SIZE_SCALE - copy-memory left-amount + (SIZE_SBYTES - SIZE_BYTES) hold SIZE_BYTES + copy-memory left-amount + SIZE_SBYTES - SIZE_BYTES hold SIZE_BYTES shift-left left-amount SIZE_SBYTES SIZE_SCALE ] @@ -749,9 +746,9 @@ money: context [ index: size - (integer/abs left-count - right-count) - SIZE_SCALE quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES - buffer: quotient + buffer: quotient - if any [remainder? only?][quotient: quotient + SIZE_SBYTES - SIZE_BYTES - 1] + if any [remainder? only?][quotient: quotient + SIZE_SBYTES - SIZE_BYTES] shift: [ digits: digits + 1 @@ -781,7 +778,7 @@ money: context [ unless remainder? [ unless only? [ shift-right quotient SIZE_SBYTES SIZE_SCALE - quotient: quotient + (SIZE_SBYTES - SIZE_BYTES) + quotient: quotient + SIZE_SBYTES - SIZE_BYTES left-amount: hold ] if zero-amount? quotient [MONEY_OVERFLOW] @@ -791,7 +788,7 @@ money: context [ set-sign dividend sign ] - + do-math: func [ op [integer!] return: [red-value!] From a83dbdf8e0aa4d8e80a2ce256250788e2a84e052 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 3 Mar 2020 17:31:28 +0800 Subject: [PATCH 1065/3432] FIX: Global memory not be freed --- runtime/platform/image-gdiplus.reds | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/runtime/platform/image-gdiplus.reds b/runtime/platform/image-gdiplus.reds index 9b6448edee..d5ffcf6dad 100644 --- a/runtime/platform/image-gdiplus.reds +++ b/runtime/platform/image-gdiplus.reds @@ -528,10 +528,12 @@ OS-image: context [ len [integer!] return: [node!] /local - hMem [integer!] - p [byte-ptr!] - s [integer!] - bmp [integer!] + hMem [integer!] + p [byte-ptr!] + s [integer!] + bmp [integer!] + sthis [this!] + stream [IStream] ][ hMem: GlobalAlloc GMEM_MOVEABLE len p: GlobalLock hMem @@ -542,6 +544,9 @@ OS-image: context [ bmp: 0 CreateStreamOnHGlobal hMem true :s GdipCreateBitmapFromStream s :bmp + sthis: as this! s + stream: as IStream sthis/vtbl + stream/Release sthis ;-- the hMem will also be released as node! bmp ] From 99da4f4ca57fa5b23fa83b56d518295f6b79d531 Mon Sep 17 00:00:00 2001 From: loziniak Date: Wed, 4 Mar 2020 08:40:07 +0100 Subject: [PATCH 1066/3432] FIX: byte overflow --- runtime/datatypes/tuple.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index bfa2b0c427..8361c4b5a3 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -264,7 +264,7 @@ tuple: context [ n: 0 until [ n: n + 1 - array/n: as-byte (-1 + _random/int-uniform-distr secure? as-integer (array/n + 1)) + array/n: as-byte (-1 + _random/int-uniform-distr secure? (1 + as-integer array/n)) n = size ] ] From 99fe03b50724255b9a153ab1129f8ea8fd65851b Mon Sep 17 00:00:00 2001 From: loziniak Date: Wed, 4 Mar 2020 10:23:02 +0100 Subject: [PATCH 1067/3432] FIX: faster random integer algorithm by @hiiamboris --- runtime/random.reds | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/random.reds b/runtime/random.reds index 3044e77a24..b0f76826a8 100644 --- a/runtime/random.reds +++ b/runtime/random.reds @@ -104,7 +104,7 @@ _random: context [ max [integer!] return: [integer!] /local - mask [integer!] + limit [integer!] rnd [integer!] neg? [logic!] ] [ @@ -115,13 +115,12 @@ _random: context [ ] [ neg?: false ] - mask: 7FFFFFFFh >> (30 - (as-integer floor log-2 as-float (max - 1))) + limit: 2147483647 / max * max until [ rnd: either secure? [rand-secure] [rand] - rnd: rnd and mask - max > rnd + limit > rnd ] - rnd: rnd + 1 + rnd: rnd % max + 1 either neg? [ 0 - rnd ] [ From 86683bd37eaa2e7e1bbfea62087624d169ad32f6 Mon Sep 17 00:00:00 2001 From: loziniak Date: Wed, 4 Mar 2020 10:30:18 +0100 Subject: [PATCH 1068/3432] FIX: log2 is not available in Windows --- runtime/natives.reds | 2 +- system/runtime/libc.reds | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index f8e30d9eef..8c76a7e410 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1798,7 +1798,7 @@ natives: context [ ][ #typecheck log-2 f: argument-as-float - f/value: log-2 f/value + f/value: (log-e f/value) / 0.6931471805599453 ] log-10*: func [ diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds index 5b86d2ec23..ee74260765 100644 --- a/system/runtime/libc.reds +++ b/system/runtime/libc.reds @@ -139,10 +139,6 @@ Red/System [ value [float!] return: [float!] ] - log-2: "log2" [ - value [float!] - return: [float!] - ] sqrt: "sqrt" [ value [float!] return: [float!] From f68203e9ab1665b8ae5ec122997322f419f855ab Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 12:50:41 +0100 Subject: [PATCH 1069/3432] FIX: ignore thousands separators during loading --- runtime/datatypes/money.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 6fc633bacd..938d40c191 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -322,6 +322,7 @@ money: context [ convert: [ here: here + step until [ + if here/value = #"'" [here: here + step continue] set-digit amount index as integer! here/value - #"0" here: here + step From c2803336f85d437973f20c7e10c32c9082f24ea6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 12:51:01 +0100 Subject: [PATCH 1070/3432] FEAT: add runtime constructors --- runtime/datatypes/money.reds | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 938d40c191..ac076e31df 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -352,6 +352,29 @@ money: context [ money ] + make-in: func [ + parent [red-block!] + sign [logic!] + currency [byte-ptr!] + start [byte-ptr!] + point [byte-ptr!] + end [byte-ptr!] + return: [red-money!] + ][ + make-at ALLOC_TAIL(parent) sign currency start point end + ] + + push: func [ + sign [logic!] + currency [byte-ptr!] + start [byte-ptr!] + point [byte-ptr!] + end [byte-ptr!] + return: [red-money!] + ][ + make-at stack/push* sign currency start point end + ] + ;-- Conversion -- overflow?: func [ From 2e0343714f567a1c106faee7f1694f00b86cafae Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 13:08:42 +0100 Subject: [PATCH 1071/3432] FEAT: improve formatting and coding style --- runtime/datatypes/money.reds | 176 ++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 87 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index ac076e31df..79da4d559b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -105,7 +105,7 @@ money: context [ ][ (as byte-ptr! money) + (size? money) - SIZE_BYTES ] - + zero-amount?: func [ amount [byte-ptr!] return: [logic!] @@ -422,7 +422,7 @@ money: context [ sign * integer ] - + from-integer: func [ int [integer!] return: [red-money!] @@ -463,7 +463,7 @@ money: context [ ] ;-- Comparison -- - + compare-money: func [ this [red-money!] that [red-money!] @@ -514,7 +514,7 @@ money: context [ either as logic! get-sign money [-1][+1] ] ] - + ;-- Math -- absolute-money: func [ @@ -536,14 +536,14 @@ money: context [ addend [red-money!] return: [red-money!] /local - left-amount right-amount [byte-ptr!] - augend-sign addend-sign [integer!] + this-amount that-amount [byte-ptr!] + this-sign that-sign [integer!] index carry left right sum [integer!] ][ - augend-sign: sign? augend - addend-sign: sign? addend + this-sign: sign? augend + that-sign: sign? addend - DISPATCH_SIGNS(augend-sign addend-sign)[ + DISPATCH_SIGNS(this-sign that-sign)[ SIGN_00 SIGN_-0 SIGN_+0 [return augend] @@ -554,23 +554,23 @@ money: context [ default [0] ] - left-amount: get-amount augend - right-amount: get-amount addend + this-amount: get-amount augend + that-amount: get-amount addend - if (get-digit left-amount 1) + (get-digit right-amount 1) > 9 [MONEY_OVERFLOW] + if (get-digit this-amount 1) + (get-digit that-amount 1) > 9 [MONEY_OVERFLOW] index: SIZE_DIGITS carry: 0 loop index [ - left: get-digit left-amount index - right: get-digit right-amount index + left: get-digit this-amount index + right: get-digit that-amount index - sum: left + right + carry + sum: left + right + carry carry: sum / 10 unless zero? carry [sum: sum + 6 and 0Fh] - set-digit left-amount index sum + set-digit this-amount index sum index: index - 1 ] @@ -585,15 +585,15 @@ money: context [ subtrahend [red-money!] return: [red-money!] /local - left-amount right-amount [byte-ptr!] - minuend-sign subtrahend-sign sign [integer!] + this-amount that-amount [byte-ptr!] + this-sign that-sign sign [integer!] index borrow left right difference [integer!] lesser? flag [logic!] ][ - minuend-sign: sign? minuend - subtrahend-sign: sign? subtrahend + this-sign: sign? minuend + that-sign: sign? subtrahend - DISPATCH_SIGNS(minuend-sign subtrahend-sign)[ + DISPATCH_SIGNS(this-sign that-sign)[ SIGN_00 SIGN_0- SIGN_0+ [return negate-money subtrahend] @@ -605,7 +605,7 @@ money: context [ lesser?: negative? compare-money minuend subtrahend sign: as integer! lesser? - either positive? minuend-sign [flag: lesser?][ + either positive? this-sign [flag: lesser?][ minuend: absolute-money minuend subtrahend: absolute-money subtrahend flag: not lesser? @@ -615,21 +615,21 @@ money: context [ ] ] - left-amount: get-amount minuend - right-amount: get-amount subtrahend + this-amount: get-amount minuend + that-amount: get-amount subtrahend index: SIZE_DIGITS borrow: 0 loop index [ - left: get-digit left-amount index - right: get-digit right-amount index + left: get-digit this-amount index + right: get-digit that-amount index difference: left - right - borrow borrow: as integer! negative? difference if as logic! borrow [difference: difference + 10] - set-digit left-amount index difference + set-digit this-amount index difference index: index - 1 ] @@ -642,47 +642,47 @@ money: context [ multiplier [red-money!] return: [red-money!] /local - left-amount right-amount product [byte-ptr!] - multiplicand-sign multiplier-sign sign [integer!] - left-count right-count [integer!] - delta index1 index2 index3 [integer!] - carry left right other result [integer!] + this-amount that-amount product [byte-ptr!] + this-sign that-sign sign [integer!] + this-count that-count [integer!] + delta index1 index2 index3 [integer!] + carry left right other result [integer!] ][ - multiplicand-sign: sign? multiplicand - multiplier-sign: sign? multiplier + this-sign: sign? multiplicand + that-sign: sign? multiplier - DISPATCH_SIGNS(multiplicand-sign multiplier-sign)[ + DISPATCH_SIGNS(this-sign that-sign)[ SIGN_00 SIGN_0- SIGN_0+ [return multiplicand] SIGN_+0 SIGN_-0 [return multiplier] - default [sign: as integer! multiplicand-sign <> multiplier-sign] + default [sign: as integer! this-sign <> that-sign] ] - left-amount: get-amount multiplicand - right-amount: get-amount multiplier + this-amount: get-amount multiplicand + that-amount: get-amount multiplier - left-count: count-digits left-amount - right-count: count-digits right-amount + this-count: count-digits this-amount + that-count: count-digits that-amount - if (left-count + right-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + if (this-count + that-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] product: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES delta: SIZE_DIGITS - SIZE_BUFFER << 1 index1: SIZE_DIGITS - loop right-count [ + loop that-count [ carry: 0 index2: SIZE_DIGITS - loop left-count [ + loop this-count [ index3: index1 + index2 - delta - left: get-digit left-amount index2 - right: get-digit right-amount index1 - other: get-digit product index3 + left: get-digit this-amount index2 + right: get-digit that-amount index1 + other: get-digit product index3 result: left * right + other + carry carry: result / 10 @@ -705,7 +705,7 @@ money: context [ shift-right product SIZE_BYTES SIZE_SCALE if zero-amount? product [MONEY_OVERFLOW] - copy-memory left-amount product SIZE_BYTES + copy-memory this-amount product SIZE_BYTES set-sign multiplicand sign ] @@ -716,59 +716,59 @@ money: context [ only? [logic!] return: [red-money!] /local - shift increment subtract [subroutine!] - greater? greatest? [subroutine!] - left-amount right-amount [byte-ptr!] - left-start right-start [byte-ptr!] - quotient buffer hold [byte-ptr!] - dividend-sign divisor-sign sign [integer!] - left-count right-count [integer!] - size overflow digits index [integer!] - left-high? right-high? [logic!] + shift increment subtract [subroutine!] + greater? greatest? [subroutine!] + this-amount that-amount [byte-ptr!] + this-start that-start [byte-ptr!] + quotient buffer hold [byte-ptr!] + this-sign that-sign sign [integer!] + this-count that-count [integer!] + size overflow digits index [integer!] + this-high? that-high? [logic!] ][ - dividend-sign: sign? dividend - divisor-sign: sign? divisor + this-sign: sign? dividend + that-sign: sign? divisor - DISPATCH_SIGNS(dividend-sign divisor-sign)[ + DISPATCH_SIGNS(this-sign that-sign)[ SIGN_00 SIGN_+0 SIGN_-0 [fire [TO_ERROR(math zero-divide)]] SIGN_0- SIGN_0+ [return dividend] - default [sign: as integer! dividend-sign <> divisor-sign] + default [sign: as integer! this-sign <> that-sign] ] - left-amount: get-amount dividend - right-amount: get-amount divisor + this-amount: get-amount dividend + that-amount: get-amount divisor - left-count: count-digits left-amount - right-count: count-digits right-amount + this-count: count-digits this-amount + that-count: count-digits that-amount - if left-count + (SIZE_SCALE + 1 - right-count) > SIZE_DIGITS [MONEY_OVERFLOW] + if this-count + (SIZE_SCALE + 1 - that-count) > SIZE_DIGITS [MONEY_OVERFLOW] size: SIZE_DIGITS overflow: SIZE_SBYTES << 1 - SIZE_DIGITS unless any [remainder? only?][ size: SIZE_SBYTES << 1 - hold: left-amount + hold: this-amount - left-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES - left-count: left-count + SIZE_SCALE + this-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + this-count: this-count + SIZE_SCALE - copy-memory left-amount + SIZE_SBYTES - SIZE_BYTES hold SIZE_BYTES - shift-left left-amount SIZE_SBYTES SIZE_SCALE + copy-memory this-amount + SIZE_SBYTES - SIZE_BYTES hold SIZE_BYTES + shift-left this-amount SIZE_SBYTES SIZE_SCALE ] - left-high?: as logic! left-count and 1 - right-high?: as logic! right-count and 1 + this-high?: as logic! this-count and 1 + that-high?: as logic! that-count and 1 - left-start: left-amount + (size - left-count >> 1) - right-start: right-amount + (SIZE_DIGITS - right-count >> 1) + this-start: this-amount + (size - this-count >> 1) + that-start: that-amount + (SIZE_DIGITS - that-count >> 1) - digits: either left-count < right-count [left-count][right-count] + digits: either this-count < that-count [this-count][that-count] - index: size - (integer/abs left-count - right-count) - SIZE_SCALE + index: size - (integer/abs this-count - that-count) - SIZE_SCALE quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES buffer: quotient @@ -780,21 +780,21 @@ money: context [ ] subtract: [ subtract-slice - left-start left-high? digits - right-start right-high? right-count + this-start this-high? digits + that-start that-high? that-count ] increment: [ set-digit quotient index (get-digit quotient index) + 1 ] greater?: [ compare-slices - right-start right-high? right-count - left-start left-high? digits + that-start that-high? that-count + this-start this-high? digits ] greatest?: [ compare-slices - right-start right-high? right-count - left-start left-high? left-count + that-start that-high? that-count + this-start this-high? this-count ] ;@@ TBD: bug with subroutines until [either greater? > 0 [either greatest? > 0 [yes][shift no]][subtract increment no]] @@ -803,11 +803,11 @@ money: context [ unless only? [ shift-right quotient SIZE_SBYTES SIZE_SCALE quotient: quotient + SIZE_SBYTES - SIZE_BYTES - left-amount: hold + this-amount: hold ] if zero-amount? quotient [MONEY_OVERFLOW] unless zero? get-digit buffer overflow [MONEY_OVERFLOW] - copy-memory left-amount quotient SIZE_BYTES + copy-memory this-amount quotient SIZE_BYTES ] set-sign dividend sign @@ -895,7 +895,7 @@ money: context [ ] ;-- to: :make - + form: func [ money [red-money!] buffer [red-string!] @@ -914,6 +914,8 @@ money: context [ part: part - 1 ] + ;@@ TBD: take currency into account + string/concatenate-literal buffer "$" loop SIZE_BYTES [ @@ -935,7 +937,7 @@ money: context [ flat? [logic!] arg [red-value!] part [integer!] - indent [integer!] + indent [integer!] return: [integer!] ][ form money buffer arg part @@ -1004,7 +1006,7 @@ money: context [ digit: get-digit get-amount money SIZE_INTEGRAL as logic! digit and 1 ] - + init: does [ datatype/register [ TYPE_MONEY From eff49c5f59d34f550fb0577bef1f808ebc4351ee Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 13:23:26 +0100 Subject: [PATCH 1072/3432] FEAT: amend spec of ROUND action --- environment/actions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index 8724cfbbbb..370ae44df1 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -146,7 +146,7 @@ remainder: make action! [[ round: make action! [[ "Returns the nearest integer. Halves round up (away from zero) by default" - n [number! time! pair!] + n [number! money! time! pair!] /to "Return the nearest multiple of the scale parameter" scale [number! time!] "Must be a non-zero value" /even "Halves round toward even results" From a7a67855003e09fd7a6041eaaafed5080602e91d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 13:23:55 +0100 Subject: [PATCH 1073/3432] FEAT: expose unfinished actions --- runtime/datatypes/money.reds | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 79da4d559b..73f4ec0758 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -10,8 +10,6 @@ Red/System [ } ] -#define STUB [func [][--NOT_IMPLEMENTED--]] - money: context [ verbose: 0 @@ -943,7 +941,16 @@ money: context [ form money buffer arg part ] - random: STUB + random: func [ + money [red-money!] + seed? [logic!] + secure? [logic!] + only? [logic!] + return: [red-money!] + ][ + --NOT_IMPLEMENTED-- + money + ] compare: func [ money [red-money!] @@ -988,7 +995,20 @@ money: context [ divide: func [return: [red-value!]][do-math OP_DIV] remainder: func [return: [red-value!]][do-math OP_REM] - round: STUB + round: func [ + value [red-money!] + scale [red-float!] + _even? [logic!] + down? [logic!] + half-down? [logic!] + floor? [logic!] + ceil? [logic!] + half-ceil? [logic!] + return: [red-money!] + ][ + --NOT_IMPLEMENTED-- + value + ] even?: func [ money [red-money!] @@ -1014,7 +1034,7 @@ money: context [ "money!" ;-- General actions -- :make - null;:random + :random null ;reflect :make ;-- to :form @@ -1030,7 +1050,7 @@ money: context [ :negate null ;power :remainder - null;:round + :round :subtract :even? :odd? From 1c2537b2bfe1c129293c9327baa6eaf5c6a1e3dc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 14:42:19 +0100 Subject: [PATCH 1074/3432] FEAT: finish up FORM and MOLD actions FORM groups digits by adding thousands separators. Number of fractional digits is controlled by a dedicated constant. --- runtime/datatypes/money.reds | 102 ++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 36 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 73f4ec0758..653324b114 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -18,6 +18,7 @@ money: context [ #enum sizes! [ SIZE_BYTES: 11 SIZE_SCALE: 05 + SIZE_AFTER: 05 ] #enum signs! [ @@ -373,6 +374,65 @@ money: context [ make-at stack/push* sign currency start point end ] + form-money: func [ + money [red-money!] + buffer [red-string!] + part [integer!] + group? [logic!] + return: [integer!] + /local + fill [subroutine!] + amount [byte-ptr!] + sign count [integer!] + index times [integer!] + ][ + amount: get-amount money + sign: sign? money + + if negative? sign [ + string/concatenate-literal buffer "-" + part: part - 1 + ] + + ;@@ TBD: take currency into account + + string/concatenate-literal buffer "$" + + count: count-digits amount + index: SIZE_DIGITS - count + 1 + + fill: [ + loop times [ + string/concatenate-literal + buffer + integer/form-signed get-digit amount index + + if all [group? zero? (index + 1 // 3) index <> SIZE_INTEGRAL][ + string/concatenate-literal buffer "'" + part: part - 1 + ] + + index: index + 1 + part: part - 1 + ] + ] + + times: count - SIZE_SCALE + either positive? times [fill][ + string/concatenate-literal buffer "0" + index: SIZE_INTEGRAL + 1 + part: part - 1 + ] + + string/concatenate-literal buffer "." + + group?: no + times: SIZE_AFTER + fill + + part - 2 + ] + ;-- Conversion -- overflow?: func [ @@ -901,30 +961,11 @@ money: context [ part [integer!] return: [integer!] /local - amount [byte-ptr!] - sign [integer!] + form-integral [subroutine!] + amount end [byte-ptr!] + sign count index size-integral [integer!] ][ - amount: get-amount money - sign: sign? money - - if negative? sign [ - string/concatenate-literal buffer "-" - part: part - 1 - ] - - ;@@ TBD: take currency into account - - string/concatenate-literal buffer "$" - - loop SIZE_BYTES [ - string/concatenate-literal - buffer - string/byte-to-hex as integer! amount/value - - amount: amount + 1 - ] - - part - SIZE_DIGITS - 1 + form-money money buffer part yes ] mold: func [ @@ -938,20 +979,9 @@ money: context [ indent [integer!] return: [integer!] ][ - form money buffer arg part - ] - - random: func [ - money [red-money!] - seed? [logic!] - secure? [logic!] - only? [logic!] - return: [red-money!] - ][ - --NOT_IMPLEMENTED-- - money + form-money money buffer part no ] - + compare: func [ money [red-money!] value [red-money!] From 1fbde400c5a5fd54749b4d55a8f96c819e6f2a1a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 18:50:29 +0100 Subject: [PATCH 1075/3432] FEAT: change code layout a bit --- runtime/datatypes/money.reds | 38 +++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 653324b114..d422aed728 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -923,12 +923,28 @@ money: context [ ] ;-- Actions -- - + make: func [ proto [red-value!] spec [red-value!] type [integer!] return: [red-money!] + ][ + switch TYPE_OF(spec) [ + TYPE_MONEY [return as red-money! spec] + TYPE_BLOCK [--NOT_IMPLEMENTED--] + TYPE_BINARY [--NOT_IMPLEMENTED--] + default [to proto spec type] + ] + + as red-money! spec + ] + + to: func [ + proto [red-value!] + spec [red-value!] + type [integer!] + return: [red-money!] /local money [red-money!] integer [red-integer!] @@ -944,6 +960,7 @@ money: context [ money: from-integer integer/value ] TYPE_FLOAT [--NOT_IMPLEMENTED--] + TYPE_STRING [--NOT_IMPLEMENTED--] default [ fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY spec] ] @@ -952,7 +969,16 @@ money: context [ money ] - ;-- to: :make + random: func [ + money [red-money!] + seed? [logic!] + secure? [logic!] + only? [logic!] + return: [red-money!] + ][ + --NOT_IMPLEMENTED-- + money + ] form: func [ money [red-money!] @@ -960,10 +986,6 @@ money: context [ arg [red-value!] part [integer!] return: [integer!] - /local - form-integral [subroutine!] - amount end [byte-ptr!] - sign count index size-integral [integer!] ][ form-money money buffer part yes ] @@ -1003,6 +1025,8 @@ money: context [ return 1 ] + ;@@ TBD: take currencies into account (strict comparison) + switch TYPE_OF(value) [ TYPE_MONEY [0] TYPE_INTEGER [ @@ -1066,7 +1090,7 @@ money: context [ :make :random null ;reflect - :make ;-- to + :to :form :mold null ;eval-path From 7a4d0941d64399a929d30de9a949ae63b134dee0 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 21:21:21 +0100 Subject: [PATCH 1076/3432] FEAT: move overflow checking in integer conversion --- runtime/datatypes/integer.reds | 4 +--- runtime/datatypes/money.reds | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index 8678474fcc..a43a6081b0 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -419,9 +419,7 @@ integer: context [ int/value: as-integer fl/value ] TYPE_MONEY [ - mn: as red-money! spec - if money/overflow? mn [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] - int/value: from-money mn + int/value: from-money as red-money! spec ] TYPE_BINARY [ int/value: from-binary as red-binary! spec diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d422aed728..f1f625c451 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -461,9 +461,11 @@ money: context [ sign integer index [integer!] start power digit [integer!] ][ + if overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] + sign: sign? money - if zero? sign [return sign] + if zero? sign [return 0] amount: get-amount money integer: 0 From 186055d87a404de2cceced00c51b0f51f2cb1b0a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 5 Mar 2020 21:21:43 +0100 Subject: [PATCH 1077/3432] FEAT: implement MAKE for BINARY! case --- runtime/datatypes/money.reds | 37 +++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index f1f625c451..d219d39c5e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -522,6 +522,35 @@ money: context [ money ] + from-binary: func [ + bin [red-binary!] + return: [red-money!] + /local + bad [subroutine!] + money [red-money!] + head [byte-ptr!] + length [integer!] + index [integer!] + ][ + bad: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY bin]] + + length: binary/rs-length? bin + if length > SIZE_BYTES [bad] + + head: binary/rs-head bin + index: 1 + loop length << 1 [ + if 9 < get-digit head index [bad] + index: index + 1 + ] + + money: zero-out as red-money! stack/push* yes + money/header: TYPE_MONEY + + copy-memory (get-amount money) + SIZE_BYTES - length head length + money + ] + ;-- Comparison -- compare-money: func [ @@ -931,15 +960,17 @@ money: context [ spec [red-value!] type [integer!] return: [red-money!] + /local + money [red-money!] ][ switch TYPE_OF(spec) [ TYPE_MONEY [return as red-money! spec] TYPE_BLOCK [--NOT_IMPLEMENTED--] - TYPE_BINARY [--NOT_IMPLEMENTED--] + TYPE_BINARY [money: from-binary as red-binary! spec] default [to proto spec type] ] - as red-money! spec + money ] to: func [ @@ -964,7 +995,7 @@ money: context [ TYPE_FLOAT [--NOT_IMPLEMENTED--] TYPE_STRING [--NOT_IMPLEMENTED--] default [ - fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY spec] + fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] ] ] From 2b57f50b9ebef1c1acf90c80eeb026a9060e9a5d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 13:12:08 +0100 Subject: [PATCH 1078/3432] FEAT: implement float to money conversion --- runtime/datatypes/money.reds | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d219d39c5e..e5fb175829 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -522,6 +522,27 @@ money: context [ money ] + from-float: func [ + flt [float!] + return: [red-money!] + /local + formed [c-string!] + start end [byte-ptr!] + point [byte-ptr!] + sign [logic!] + ][ + formed: dtoa/form-float flt SIZE_DIGITS yes + + point: as byte-ptr! formed + until [point: point + 1 point/value = #"."] + + sign: formed/1 = #"-" + start: as byte-ptr! either sign [formed][formed - 1] + end: as byte-ptr! formed + length? formed + + push sign null start point end + ] + from-binary: func [ bin [red-binary!] return: [red-money!] @@ -967,7 +988,7 @@ money: context [ TYPE_MONEY [return as red-money! spec] TYPE_BLOCK [--NOT_IMPLEMENTED--] TYPE_BINARY [money: from-binary as red-binary! spec] - default [to proto spec type] + default [money: to proto spec type] ] money @@ -981,6 +1002,7 @@ money: context [ /local money [red-money!] integer [red-integer!] + float [red-float!] ][ if TYPE_OF(spec) = TYPE_MONEY [return as red-money! spec] @@ -992,7 +1014,10 @@ money: context [ integer: as red-integer! spec money: from-integer integer/value ] - TYPE_FLOAT [--NOT_IMPLEMENTED--] + TYPE_FLOAT [ + float: as red-float! spec + money: from-float float/value + ] TYPE_STRING [--NOT_IMPLEMENTED--] default [ fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] From 9a3e669e6e41b615252a92ab19954c9b1eaae761 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 13:12:58 +0100 Subject: [PATCH 1079/3432] FEAT: more permissive binary conversion Only first N relevant bytes are taken into account. --- runtime/datatypes/money.reds | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index e5fb175829..cb0479afbc 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -547,21 +547,20 @@ money: context [ bin [red-binary!] return: [red-money!] /local - bad [subroutine!] money [red-money!] head [byte-ptr!] length [integer!] index [integer!] ][ - bad: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY bin]] - length: binary/rs-length? bin - if length > SIZE_BYTES [bad] + if length > SIZE_BYTES [length: SIZE_BYTES] head: binary/rs-head bin index: 1 loop length << 1 [ - if 9 < get-digit head index [bad] + if 9 < get-digit head index [ + fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY bin] + ] index: index + 1 ] From aad9f42c51584fa9475111220546bf2b7a97d9ed Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 13:13:22 +0100 Subject: [PATCH 1080/3432] FEAT: simplify macro call --- runtime/datatypes/money.reds | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index cb0479afbc..fe882f2a98 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -39,7 +39,7 @@ money: context [ SIGN_++: 22h ] - #define DISPATCH_SIGNS(this that) [switch collate-signs this that] + #define DISPATCH_SIGNS [switch collate-signs this-sign that-sign] #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] #define MONEY_OVERFLOW [fire [TO_ERROR(script type-limit) datatype/push TYPE_MONEY]] @@ -585,7 +585,7 @@ money: context [ this-sign: sign? this that-sign: sign? that - DISPATCH_SIGNS(this-sign that-sign)[ + DISPATCH_SIGNS [ SIGN_-- [SWAP_ARGUMENTS(this that) 0] SIGN_++ [0] default [return integer/sign? this-sign - that-sign] @@ -652,7 +652,7 @@ money: context [ this-sign: sign? augend that-sign: sign? addend - DISPATCH_SIGNS(this-sign that-sign)[ + DISPATCH_SIGNS [ SIGN_00 SIGN_-0 SIGN_+0 [return augend] @@ -702,7 +702,7 @@ money: context [ this-sign: sign? minuend that-sign: sign? subtrahend - DISPATCH_SIGNS(this-sign that-sign)[ + DISPATCH_SIGNS [ SIGN_00 SIGN_0- SIGN_0+ [return negate-money subtrahend] @@ -760,7 +760,7 @@ money: context [ this-sign: sign? multiplicand that-sign: sign? multiplier - DISPATCH_SIGNS(this-sign that-sign)[ + DISPATCH_SIGNS [ SIGN_00 SIGN_0- SIGN_0+ [return multiplicand] @@ -838,7 +838,7 @@ money: context [ this-sign: sign? dividend that-sign: sign? divisor - DISPATCH_SIGNS(this-sign that-sign)[ + DISPATCH_SIGNS [ SIGN_00 SIGN_+0 SIGN_-0 [fire [TO_ERROR(math zero-divide)]] From b4803d750a6906f36b70a2fc50bc1212641191f5 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 14:01:40 +0100 Subject: [PATCH 1081/3432] FEAT: comparison between FLOAT! and MONEY! --- runtime/datatypes/float.reds | 1 + runtime/datatypes/money.reds | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 972f0549ce..623a9928ac 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -719,6 +719,7 @@ float: context [ left: value1/value switch TYPE_OF(value2) [ + TYPE_MONEY [return money/compare money/from-float left as red-money! value2 op] TYPE_CHAR TYPE_INTEGER [ int: as red-integer! value2 diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index fe882f2a98..3e4446244d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1067,7 +1067,8 @@ money: context [ op [integer!] return: [integer!] /local - int [red-integer!] + integer [red-integer!] + float [red-float!] ][ if all [ TYPE_OF(money) <> TYPE_OF(value) @@ -1087,10 +1088,13 @@ money: context [ switch TYPE_OF(value) [ TYPE_MONEY [0] TYPE_INTEGER [ - int: as red-integer! value - value: from-integer int/value + integer: as red-integer! value + value: from-integer integer/value + ] + TYPE_FLOAT [ + float: as red-float! value + value: from-float float/value ] - TYPE_FLOAT [--NOT_IMPLEMENTED--] default [RETURN_COMPARE_OTHER] ] From 333fe070a625b0c7a50befc91bd2e110eb33be61 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 14:02:22 +0100 Subject: [PATCH 1082/3432] FEAT: math operations between FLOAT! and MONEY! --- runtime/datatypes/float.reds | 1 + runtime/datatypes/money.reds | 47 ++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 623a9928ac..fec3796a16 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -288,6 +288,7 @@ float: context [ switch type2 [ TYPE_TUPLE [return as red-float! tuple/do-math type] + TYPE_MONEY [return as red-float! money/do-math type] TYPE_PAIR [ if type1 <> TYPE_TIME [ if any [type = OP_SUB type = OP_DIV][ diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3e4446244d..5b597401af 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -921,13 +921,33 @@ money: context [ set-sign dividend sign ] - + + do-math-op: func [ + left [red-money!] + right [red-money!] + op [integer!] + return: [red-money!] + ][ + switch op [ + OP_ADD [add-money left right] + OP_SUB [subtract-money left right] + OP_MUL [multiply-money left right] + OP_DIV [divide-money left right no no] + OP_REM [divide-money left right yes no] + default [ + fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] + left + ] + ] + ] + do-math: func [ op [integer!] return: [red-value!] /local left right result [red-money!] integer [red-integer!] + float [red-float!] ][ left: as red-money! stack/arguments right: left + 1 @@ -940,7 +960,10 @@ money: context [ integer: as red-integer! left left: from-integer integer/value ] - TYPE_FLOAT [--NOT_IMPLEMENTED--] + TYPE_FLOAT [ + float: as red-float! left + left: from-float float/value + ] default [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(left)] ] @@ -952,27 +975,19 @@ money: context [ integer: as red-integer! right right: from-integer integer/value ] - TYPE_FLOAT [--NOT_IMPLEMENTED--] - default [ - fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] + TYPE_FLOAT [ + float: as red-float! right + right: from-float float/value ] - ] - - result: switch op [ - OP_ADD [add-money left right] - OP_SUB [subtract-money left right] - OP_MUL [multiply-money left right] - OP_DIV [divide-money left right no no] - OP_REM [divide-money left right yes no] default [ - fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] - left + fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] ] ] + result: do-math-op left right op SET_RETURN(result) ] - + ;-- Actions -- make: func [ From d939f8a7080a2ef7b61d07daafb6e8ebb2e8c88e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 16:19:00 +0100 Subject: [PATCH 1083/3432] FEAT: implement money to float conversion --- runtime/datatypes/float.reds | 12 +++++++++++- runtime/datatypes/money.reds | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index fec3796a16..2a01a4ddce 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -412,7 +412,14 @@ float: context [ fl/value: value fl ] - + + from-money: func [ + mn [red-money!] + return: [float!] + ][ + money/to-float mn + ] + from-binary: func [ bin [red-binary!] return: [float!] @@ -540,6 +547,9 @@ float: context [ int: as red-integer! spec proto/value: as-float int/value ] + TYPE_MONEY [ + proto/value: from-money as red-money! spec + ] TYPE_TIME [ tm: as red-time! spec proto/value: tm/time diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 5b597401af..a2bddb40d7 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -522,8 +522,36 @@ money: context [ money ] + to-float: func [ + money [red-money!] + return: [float!] + /local + buffer [red-string!] + head [byte-ptr!] + float [float!] + sign delta [integer!] + length error [integer!] + ][ + sign: sign? money + + if zero? sign [return 0.0] + + buffer: string/make-at stack/push* SIZE_DIGITS + 6 Latin1 + form-money money buffer 0 no + + delta: (string/rs-find buffer as integer! #"$") + 1 + head: (string/rs-head buffer) + delta + length: (string/rs-length? buffer) - delta + + error: 0 + float: string/to-float head length :error + stack/pop 1 + + float * as float! sign + ] + from-float: func [ - flt [float!] + float [float!] return: [red-money!] /local formed [c-string!] @@ -531,7 +559,7 @@ money: context [ point [byte-ptr!] sign [logic!] ][ - formed: dtoa/form-float flt SIZE_DIGITS yes + formed: dtoa/form-float float SIZE_DIGITS yes point: as byte-ptr! formed until [point: point + 1 point/value = #"."] @@ -1117,7 +1145,7 @@ money: context [ ] absolute: func [return: [red-money!]][absolute-money as red-money! stack/arguments] - negate: func [return: [red-money!]][negate-money as red-money! stack/arguments] + negate: func [return: [red-money!]][negate-money as red-money! stack/arguments] add: func [return: [red-value!]][do-math OP_ADD] subtract: func [return: [red-value!]][do-math OP_SUB] From 41ae4e12adea3b3c0de3a97423bc46dcb543b119 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 16:54:41 +0100 Subject: [PATCH 1084/3432] FEAT: implement money to binary conversion --- runtime/datatypes/binary.reds | 10 ++++++++++ runtime/datatypes/money.reds | 7 +++++++ runtime/datatypes/string.reds | 3 +++ 3 files changed, 20 insertions(+) diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index 262b35617c..f6f6261487 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -226,6 +226,13 @@ binary: context [ int: int >> 8 ] ] + + from-money: func [ + mn [red-money!] + return: [red-binary!] + ][ + money/to-binary mn + ] from-issue: func [ issue [red-word!] @@ -1003,6 +1010,9 @@ binary: context [ p: as byte-ptr! unicode/to-utf8 as red-string! spec :len proto: load p len ] + TYPE_MONEY [ + proto: from-money as red-money! spec + ] TYPE_INTEGER [ int: as red-integer! spec make-at as red-value! proto 4 diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a2bddb40d7..b91d85552e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -571,6 +571,13 @@ money: context [ push sign null start point end ] + to-binary: func [ + money [red-money!] + return: [red-binary!] + ][ + binary/load-in get-amount money SIZE_BYTES null + ] + from-binary: func [ bin [red-binary!] return: [red-money!] diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index ab205ac1e1..92bdcbdaa4 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -1256,6 +1256,9 @@ string: context [ proto ][ either type = TYPE_BINARY [ + if TYPE_OF(spec) = TYPE_MONEY [ + fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_BINARY spec] + ] as red-string! binary/to as red-binary! proto spec type ][ to as red-value! proto spec type From f462d182e146e2b48607cb5b8918a4a2c6103ffb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 19:56:30 +0100 Subject: [PATCH 1085/3432] FIX: passing incorrect pointer to currency code --- runtime/lexer.reds | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 1e555e5b2e..e723ef8765 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1867,10 +1867,9 @@ lexer: context [ neg?: p/1 = #"-" if flags and C_FLAG_SIGN <> 0 [p: p + 1] ;-- skip sign when present cur: p - while [cur/1 <> #"$"][cur: cur + 1] ;-- cur is always < e + while [p/1 <> #"$"][p: p + 1] ;-- cur is always < e either p = cur [cur: null][ - if p + 3 <> cur [do-error] - p: cur + if cur + 3 <> p [do-error] ] assert p/1 = #"$" st: p From 9904009aeee6581e13ce127bcb20d3e4446cf148 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 6 Mar 2020 20:11:33 +0100 Subject: [PATCH 1086/3432] FEAT: implement string to money conversion --- runtime/datatypes/money.reds | 94 +++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 11 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b91d85552e..4372c50ee3 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -606,6 +606,80 @@ money: context [ money ] + from-string: func [ + str [red-string!] + return: [red-money!] + /local + bail make [subroutine!] + end? dot? [subroutine!] + digit? letter? [subroutine!] + tail head here [byte-ptr!] + currency digits [byte-ptr!] + start point [byte-ptr!] + char [byte!] + sign [logic!] + ][ + bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] + make: [return push sign currency start point tail] + + end?: [here >= tail] + dot?: [any [here/value = #"." here/value = #","]] + digit?: [all [here/value >= #"0" here/value <= #"9"]] + letter?: [ + any [ + all [here/value >= #"a" here/value <= #"z"] + all [here/value >= #"A" here/value <= #"Z"] + ] + ] + + tail: string/rs-tail str + head: string/rs-head str + here: head + + sign: no + switch here/value [ + #"-" [here: here + 1 sign: yes] + #"+" [here: here + 1] + default [0] + ] + + currency: here + while [not any [end? here/value = #"$"]][here: here + 1] + + if end? [here: currency] + either here = currency [currency: null][ + if currency + 3 <> here [bail] + loop 3 [here: here - 1 unless letter? [bail]] + here: here + 3 + ] + + start: here - as integer! here/value <> #"$" + here: start + 1 + + until [here: here + 1 any [here = tail here/value <> #"0"]] + if any [here = tail dot?][here: here - 1] + digits: here + + until [ + if here/value = #"'" [here: here + 1 continue] + unless digit? [bail] + here: here + 1 + any [end? dot?] + ] + + if any [here > tail all [dot? here + 1 = tail]][bail] + + point: here + if SIZE_INTEGRAL < as integer! point - digits [bail] + if here = tail [point: null make] + here: here + 1 + + until [unless digit? [bail] here: here + 1 end?] + if here <> tail [bail] + + make + ] + ;-- Comparison -- compare-money: func [ @@ -1049,31 +1123,29 @@ money: context [ type [integer!] return: [red-money!] /local - money [red-money!] integer [red-integer!] float [red-float!] ][ - if TYPE_OF(spec) = TYPE_MONEY [return as red-money! spec] - - money: as red-money! proto - money/header: TYPE_MONEY - switch TYPE_OF(spec) [ + TYPE_MONEY [ + return as red-money! spec + ] TYPE_INTEGER [ integer: as red-integer! spec - money: from-integer integer/value + from-integer integer/value ] TYPE_FLOAT [ float: as red-float! spec - money: from-float float/value + from-float float/value + ] + TYPE_STRING [ + from-string as red-string! spec ] - TYPE_STRING [--NOT_IMPLEMENTED--] default [ fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] + as red-money! proto ] ] - - money ] random: func [ From 87d8f523b212cb059114c12d8ab9a49884a671a0 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 7 Mar 2020 12:07:29 +0800 Subject: [PATCH 1087/3432] FIX: #4291 (Heisenbug with zero bytes in `mold` output). --- runtime/datatypes/object.reds | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index 1a6af90236..af85d72d35 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -524,7 +524,7 @@ object: context [ evt1 [integer!] evt2 [integer!] id [integer!] - blank [byte!] + blank [integer!] ][ ctx: GET_CTX(obj) syms: as series! ctx/symbols/value @@ -540,13 +540,13 @@ object: context [ either flat? [ indent?: no - blank: space + blank: as-integer space ][ if mold? [ string/append-char GET_BUFFER(buffer) as-integer lf part: part - 1 ] - blank: lf + blank: as-integer lf ] cycles/push obj/ctx @@ -569,7 +569,7 @@ object: context [ part: actions/mold value buffer only? all? flat? arg part tabs if any [indent? sym + 1 < s-tail][ ;-- no final LF when FORMed - string/append-char GET_BUFFER(buffer) as-integer blank + string/append-char GET_BUFFER(buffer) blank part: part - 1 ] ] From 383d4ab1ec20c55e346a1c3146f1e5154eac939b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 7 Mar 2020 19:44:32 +0100 Subject: [PATCH 1088/3432] FIX: issue #4318 ([Parse] SET and COPY work even without a sub-rule) --- runtime/parse.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index 0239bad18d..c64b2743f2 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -1514,7 +1514,7 @@ parser: context [ ] sym = words/copy [ ;-- COPY cmd: cmd + 1 - if any [cmd = tail TYPE_OF(cmd) <> TYPE_WORD][ + if any [cmd + 1 >= tail TYPE_OF(cmd) <> TYPE_WORD][ PARSE_ERROR [TO_ERROR(script parse-end) words/_copy] ] min: R_NONE @@ -1827,7 +1827,7 @@ parser: context [ ] sym = words/set [ ;-- SET cmd: cmd + 1 - if any [cmd = tail TYPE_OF(cmd) <> TYPE_WORD][ + if any [cmd + 1 >= tail TYPE_OF(cmd) <> TYPE_WORD][ PARSE_ERROR [TO_ERROR(script parse-end) words/_set] ] min: R_NONE From 9bc93fb9a851ace0beebdd75330e63b754d56f60 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 7 Mar 2020 19:45:03 +0100 Subject: [PATCH 1089/3432] TESTS: tests for issue #4318 --- tests/source/units/parse-test.red | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 0b49fcd581..2f9cece256 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2734,6 +2734,11 @@ Red [ --assert parse [a/b] ['a/b] --assert error? try [parse [a/b] [a/b]] + --test-- "#4318" + --assert error? try [parse [][copy x4318]] + --assert error? try [parse [][set x4318]] + --assert unset? :x4318 + ===end-group=== ~~~end-file~~~ From 7bee067f089c4767bbc3d9a977eaeeb3705cd2fd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 7 Mar 2020 20:31:15 +0100 Subject: [PATCH 1090/3432] FIX: fix non-passing test --- tests/source/units/parse-test.red | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 2f9cece256..62ec167d78 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2735,9 +2735,10 @@ Red [ --assert error? try [parse [a/b] [a/b]] --test-- "#4318" + x4318: 0 --assert error? try [parse [][copy x4318]] --assert error? try [parse [][set x4318]] - --assert unset? :x4318 + --assert zero? x4318 ===end-group=== From d2f50a46d28180d7e550a19bbadc253fe6857fb7 Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Mon, 9 Mar 2020 00:49:55 +0300 Subject: [PATCH 1091/3432] FIX: #4321 (Shared state in LAYOUT causes stack overflows) --- modules/view/VID.red | 16 ++++++---------- modules/view/view.red | 5 +++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/modules/view/VID.red b/modules/view/VID.red index 9b6e1a0aaf..e3d67346aa 100644 --- a/modules/view/VID.red +++ b/modules/view/VID.red @@ -53,8 +53,6 @@ system/view/VID: context [ ] ] - focal-face: none - reactors: make block! 20 debug?: no containers: [panel tab-panel group-box] @@ -77,7 +75,7 @@ system/view/VID: context [ ] ] - process-reactors: function [/local res][ + process-reactors: function [reactors [block!] /local res][ set 'res try/all [ foreach [f blk later?] reactors [ blk: copy/deep blk @@ -89,7 +87,6 @@ system/view/VID: context [ ] ] ] - clear reactors ;-- ensures clearing even if reaction fails if error? :res [do res] ] @@ -265,9 +262,8 @@ system/view/VID: context [ fetch-expr: func [code [word!]][do/next next get code code] fetch-options: function [ - face [object!] opts [object!] style [block!] spec [block!] css [block!] styling? [logic!] + face [object!] opts [object!] style [block!] spec [block!] css [block!] reactors [block!] styling? [logic!] /no-skip - /extern focal-face return: [block!] ][ opt?: yes @@ -298,7 +294,7 @@ system/view/VID: context [ | 'para (opts/para: make any [opts/para para!] fetch-argument obj-spec! spec) | 'wrap (opt?: add-flag opts 'para 'wrap? yes) | 'no-wrap (add-flag opts 'para 'wrap? no opt?: yes) - | 'focus (focal-face: face) + | 'focus (set bind 'focal-face :layout face) | 'font-name (add-flag opts 'font 'name fetch-argument string! spec) | 'font-size (add-flag opts 'font 'size fetch-argument integer! spec) | 'font-color (add-flag opts 'font 'color pre-load fetch-argument color! spec) @@ -516,10 +512,10 @@ system/view/VID: context [ /styles "Use an existing styles list" css [block!] "Styles list" /local axis anti ;-- defined in a SET block - /extern focal-face ][ background!: make typeset! [image! file! url! tuple! word! issue!] list: make block! 4 ;-- panel's pane block + reactors: make block! 10 ;-- reactors of this particular layout local-styles: any [css make block! 2] ;-- panel-local styles definitions pane-size: 0x0 ;-- panel's content dynamic size direction: 'across @@ -664,7 +660,7 @@ system/view/VID: context [ if h: select system/view/metrics/def-heights face/type [face/size/y: h] unless styling? [face/parent: panel] - spec: fetch-options face opts style spec local-styles to-logic styling? + spec: fetch-options face opts style spec local-styles reactors to-logic styling? if all [style/init not styling?][do bind style/init 'face] either styling? [ @@ -732,7 +728,7 @@ system/view/VID: context [ spec: next spec ] do re-align - process-reactors ;-- Needs to be after [set name face] + process-reactors reactors ;-- Needs to be after [set name face] either size [panel/size: size][ if pane-size <> 0x0 [ diff --git a/modules/view/view.red b/modules/view/view.red index f0e3a015f0..8add3f59cb 100644 --- a/modules/view/view.red +++ b/modules/view/view.red @@ -913,9 +913,10 @@ make-face: func [ unless spec [blk: []] opts: svv/opts-proto css: make block! 2 - spec: svv/fetch-options/no-skip face opts model blk css no + reactors: make block! 4 + spec: svv/fetch-options/no-skip face opts model blk css reactors no if model/init [do bind model/init 'face] - svv/process-reactors + svv/process-reactors reactors if offset [face/offset: xy] if size [face/size: wh] From e578ea35e33f0218614e2b30c5305cf1c8a2b4b9 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 10 Mar 2020 15:51:33 +0800 Subject: [PATCH 1092/3432] FIX: issue #3486 (Smooth cubic bezier `curv` after another `curv` not smooth) --- modules/view/backends/windows/draw.reds | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/draw.reds b/modules/view/backends/windows/draw.reds index 3f71f90493..15ecaa8acb 100644 --- a/modules/view/backends/windows/draw.reds +++ b/modules/view/backends/windows/draw.reds @@ -682,11 +682,17 @@ draw-short-curves: func [ pt: pt + 1 pt/x: ( 2 * ctx/other/path-last-point/x ) - control/x pt/y: ( 2 * ctx/other/path-last-point/y ) - control/y - control/x: pt/x - control/y: pt/y + if nr-points = 1 [ + control/x: pt/x + control/y: pt/y + ] pt: pt + 1 pt/x: either rel? [ ctx/other/path-last-point/x + pair/x ][ pair/x ] pt/y: either rel? [ ctx/other/path-last-point/y + pair/y ][ pair/y ] + if nr-points = 2 [ + control/x: pt/x + control/y: pt/y + ] pt: pt + 1 loop nr-points - 1 [ pair: pair + 1 ] if pair <= end [ From f2e48342fd9987ec28f5baf15853250209d608cf Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 18:29:38 +0100 Subject: [PATCH 1093/3432] FIX: counter NaN and INF in float conversion --- runtime/datatypes/money.reds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4372c50ee3..d79ea2d1c7 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -564,6 +564,8 @@ money: context [ point: as byte-ptr! formed until [point: point + 1 point/value = #"."] + if point/2 = #"#" [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float]] + sign: formed/1 = #"-" start: as byte-ptr! either sign [formed][formed - 1] end: as byte-ptr! formed + length? formed From 30505676c408efc42fc039163a94e36cd0e28d72 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 21:44:45 +0100 Subject: [PATCH 1094/3432] FIX: incorrect product normalization --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d79ea2d1c7..8d77b3bd16 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -920,9 +920,9 @@ money: context [ unless zero? get-digit product 1 [MONEY_OVERFLOW] + shift-right product SIZE_SBYTES SIZE_SCALE product: product + SIZE_BUFFER - SIZE_BYTES - shift-right product SIZE_BYTES SIZE_SCALE if zero-amount? product [MONEY_OVERFLOW] copy-memory this-amount product SIZE_BYTES From 00ee34e39a6f2342ac94490b7e6359a952463826 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 21:45:01 +0100 Subject: [PATCH 1095/3432] FEAT: minor code layout improvement --- runtime/datatypes/money.reds | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 8d77b3bd16..d367b94fa6 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -805,10 +805,11 @@ money: context [ subtrahend [red-money!] return: [red-money!] /local - this-amount that-amount [byte-ptr!] - this-sign that-sign sign [integer!] - index borrow left right difference [integer!] - lesser? flag [logic!] + this-amount that-amount [byte-ptr!] + this-sign that-sign sign [integer!] + index borrow left right [integer!] + difference [integer!] + lesser? flag [logic!] ][ this-sign: sign? minuend that-sign: sign? subtrahend From 65b883daebe7256b2d598a8f89498b497b0cf8da Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 22:04:26 +0100 Subject: [PATCH 1096/3432] FEAT: support conversion from ANY-STRING! values --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d367b94fa6..7cce3f6879 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1141,7 +1141,7 @@ money: context [ float: as red-float! spec from-float float/value ] - TYPE_STRING [ + TYPE_ANY_STRING [ from-string as red-string! spec ] default [ From 15d531237b523934f0f0a3105de0fbd650a75237 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 22:11:26 +0100 Subject: [PATCH 1097/3432] FIX: boxing NaN/INF prior to firing an error --- runtime/datatypes/money.reds | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 7cce3f6879..491f5c1f5c 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -551,7 +551,7 @@ money: context [ ] from-float: func [ - float [float!] + flt [float!] return: [red-money!] /local formed [c-string!] @@ -559,12 +559,14 @@ money: context [ point [byte-ptr!] sign [logic!] ][ - formed: dtoa/form-float float SIZE_DIGITS yes + formed: dtoa/form-float flt SIZE_DIGITS yes point: as byte-ptr! formed until [point: point + 1 point/value = #"."] - if point/2 = #"#" [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float]] + if point/2 = #"#" [ + fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float/box flt] + ] sign: formed/1 = #"-" start: as byte-ptr! either sign [formed][formed - 1] From 819d1d822f0c09165ef0964dc289d5f8a83b1d30 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 22:13:01 +0100 Subject: [PATCH 1098/3432] FIX: more robust money to float conversion --- runtime/datatypes/money.reds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 491f5c1f5c..62a7d06faa 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -547,6 +547,10 @@ money: context [ float: string/to-float head length :error stack/pop 1 + unless zero? error [ + fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_FLOAT money] + ] + float * as float! sign ] From 88a08450d620bc24c908aa6bddefa2e50ac5fde7 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 10 Mar 2020 23:58:27 +0100 Subject: [PATCH 1099/3432] FIX: incorrect sign in remainder result --- runtime/datatypes/money.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 62a7d06faa..a1329b13f6 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -962,7 +962,9 @@ money: context [ SIGN_-0 [fire [TO_ERROR(math zero-divide)]] SIGN_0- SIGN_0+ [return dividend] - default [sign: as integer! this-sign <> that-sign] + default [ + sign: as integer! either remainder? [negative? this-sign][this-sign <> that-sign] + ] ] this-amount: get-amount dividend From 9a3180b111682c543ba88549bc7b03c1c378ddbf Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 11 Mar 2020 15:40:21 +0100 Subject: [PATCH 1100/3432] FEAT: signal underflow in float conversion --- runtime/datatypes/money.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a1329b13f6..d15755294a 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -558,6 +558,7 @@ money: context [ flt [float!] return: [red-money!] /local + money [red-money!] formed [c-string!] start end [byte-ptr!] point [byte-ptr!] @@ -576,7 +577,9 @@ money: context [ start: as byte-ptr! either sign [formed][formed - 1] end: as byte-ptr! formed + length? formed - push sign null start point end + money: push sign null start point end + if all [0.0 <> flt zero? sign? money][MONEY_OVERFLOW] + money ] to-binary: func [ From 56f4e6b297595ab11c3a849fd82d3644dcda23f3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 11 Mar 2020 17:06:30 +0100 Subject: [PATCH 1101/3432] FEAT: Rebol2 semantics for *, / and % --- runtime/datatypes/money.reds | 44 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d15755294a..b3e462b3bd 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1068,46 +1068,62 @@ money: context [ op [integer!] return: [red-value!] /local - left right result [red-money!] - integer [red-integer!] - float [red-float!] + left right [red-money!] + result [red-value!] + int [red-integer!] + flt [red-float!] + left-type [integer!] + right-type [integer!] ][ left: as red-money! stack/arguments right: left + 1 + + left-type: TYPE_OF(left) + right-type: TYPE_OF(right) + if any [ + all [op = OP_MUL left-type = TYPE_MONEY right-type = TYPE_MONEY] + all [any [op = OP_DIV op = OP_REM] left-type <> TYPE_MONEY right-type = TYPE_MONEY] + ][ + fire [TO_ERROR(script invalid-type) datatype/push left-type] + ] + ;@@ TBD: take currencies into account - switch TYPE_OF(left) [ + switch left-type [ TYPE_MONEY [0] TYPE_INTEGER [ - integer: as red-integer! left - left: from-integer integer/value + int: as red-integer! left + left: from-integer int/value ] TYPE_FLOAT [ - float: as red-float! left - left: from-float float/value + flt: as red-float! left + left: from-float flt/value ] default [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(left)] ] ] - switch TYPE_OF(right) [ + switch right-type [ TYPE_MONEY [0] TYPE_INTEGER [ - integer: as red-integer! right - right: from-integer integer/value + int: as red-integer! right + right: from-integer int/value ] TYPE_FLOAT [ - float: as red-float! right - right: from-float float/value + flt: as red-float! right + right: from-float flt/value ] default [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] ] ] - result: do-math-op left right op + result: as red-value! do-math-op left right op + if all [op = OP_DIV left-type = TYPE_MONEY right-type = TYPE_MONEY][ + result: as red-value! float/box to-float as red-money! result + ] SET_RETURN(result) ] From 12cedcc12d5d97f032ee59457ff7f2177ac5a872 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Thu, 12 Mar 2020 13:54:52 +0800 Subject: [PATCH 1102/3432] FIX: issue #4329 (Downloading >520kB file gets mangled with GC on) --- runtime/simple-io.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/simple-io.reds b/runtime/simple-io.reds index 8b05a73c47..8b286b099f 100644 --- a/runtime/simple-io.reds +++ b/runtime/simple-io.reds @@ -1945,8 +1945,8 @@ simple-io: context [ either lines? [ bin: as red-binary! lines-to-block buf len ][ - bin/header: TYPE_UNSET bin/node: unicode/load-utf8 as c-string! buf len + bin/head: 0 bin/_pad: 0 bin/header: TYPE_STRING ] From f5e2c404a16f525d996da1fec2f398304a7ad60a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 11:44:22 +0100 Subject: [PATCH 1103/3432] FIX: issue #2532 (Math doesn't follow the arithmetic precedence for %, **) --- environment/functions.red | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index e89a76d387..d88e663217 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -275,22 +275,21 @@ replace: function [ ] math: function [ - "Evaluates a block using math precedence rules, returning the last result" - body [block!] "Block to evaluate" - /safe "Returns NONE on error" + "Evaluates expression using math precedence rules" + datum [block! paren!] "Expression to evaluate" + /local match ][ - parse body: copy/deep body rule: [ - any [ - pos: ['* (op: 'multiply) | quote / (op: 'divide)] - [ahead sub: paren! (sub/1: math as block! sub/1) | skip] ( - end: skip pos: back pos 3 - pos: change/only/part pos as paren! copy/part pos end end - ) :pos - | into rule - | skip - ] + order: ['** ['* | '/ | '% | '//]] + infix: [skip operator [enter | skip]] + + tally: [any [enter [fail] | recur [fail] | count [fail] | skip]] + enter: [ahead paren! into tally] + recur: [if (operator = '**) skip operator tally] + count: [while ahead change only copy match infix (do match)] + + do also datum: copy/deep datum foreach operator order [ + parse datum tally ] - either safe [attempt body][do body] ] charset: func [ From eb99963cbb3b047aa5a633854c3bfc85a4a1c5cb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 13:02:40 +0100 Subject: [PATCH 1104/3432] FIX: workaround for Rebol2 lexer limitations --- environment/functions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/functions.red b/environment/functions.red index d88e663217..b90e388fdd 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -279,7 +279,7 @@ math: function [ datum [block! paren!] "Expression to evaluate" /local match ][ - order: ['** ['* | '/ | '% | '//]] + order: ['** ['* | quote / | quote % | quote //]] ;@@ compiler's lexer chokes on '/, '% and '// infix: [skip operator [enter | skip]] tally: [any [enter [fail] | recur [fail] | count [fail] | skip]] From 7588e7c51b9fa683533c2d91986fc53bf0efe414 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 13:03:16 +0100 Subject: [PATCH 1105/3432] TESTS: a batch of MATH tests --- tests/source/environment/functions-test.red | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/source/environment/functions-test.red b/tests/source/environment/functions-test.red index b43e5d3db3..3929887897 100644 --- a/tests/source/environment/functions-test.red +++ b/tests/source/environment/functions-test.red @@ -226,7 +226,12 @@ Red [ --assert 0.5 = math [1 / 2.0] --assert 2 = math [(1 / 2.0) (2 * 1)] --assert 8 = math [(1 / 2) (power 2 3)] - --assert none = math/safe [(1 / 0) (power 2 3)] + --assert none = attempt [math [(1 / 0) (power 2 3)]] + --assert 7 = math [1 + 2 * 3] + --assert 9 = math [(1 + 2) * 3] + --assert 100000010 = math [10 + 10 ** 2 ** 3] + --assert 10 = math [10 + 10 % 2] + --assert 1 = math [8 / 5 % 2] ===end-group=== ===start-group=== "charset tests" From b5e565f4f527511d1c4ae0c573bdf2ea3eeb97cf Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 18:07:35 +0100 Subject: [PATCH 1106/3432] FIX: proper sorting of series with MONEY! values --- runtime/datatypes/money.reds | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b3e462b3bd..32f933881e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1224,13 +1224,7 @@ money: context [ ][ if all [ TYPE_OF(money) <> TYPE_OF(value) - any [ - op = COMP_SORT - op = COMP_CASE_SORT - op = COMP_FIND - op = COMP_SAME - op = COMP_STRICT_EQUAL - ] + any [op = COMP_FIND op = COMP_SAME op = COMP_STRICT_EQUAL] ][ return 1 ] From 7efae64485b209da9e852e8d45adf52683826c43 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 12 Mar 2020 18:39:24 +0100 Subject: [PATCH 1107/3432] FIX: unbalanced single quotes in tags passing silently in some cases. Fixes those cases: >> <'> == <'> >> <''> *** Syntax Error: (line 2) invalid tag at <''> Now: >> <'> *** Syntax Error: (line 2) invalid tag at <'> *** Where: transcode *** Stack: load >> <''> == <''> --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 21933 -> 21923 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index cc4156e20c..9b8b86437b 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -41,7 +41,7 @@ S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MO S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX -S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_LESSER;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD +S_LESSER;T_WORD;T_WORD;S_TAG;S_TAG;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_TAG;S_TAG_STR2;T_WORD;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_LESSER;S_WORD;S_WORD;S_TAG;S_TAG;T_WORD;T_WORD;S_TAG;S_TAG;S_TAG;S_WORD;S_TAG;S_TAG;S_TAG;T_ERROR;T_WORD S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG_STR;S_TAG;S_TAG_STR2;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;S_TAG;T_ERROR;T_ERROR S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;S_TAG_STR;T_ERROR;T_ERROR S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 78ad179868f8a62ccf69b28f3a7324c0e86d34b8..7714b72158a885ed906e8c035d841495b4e693c2 100644 GIT binary patch literal 21923 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 diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index a52faee482..8a71a74254 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -154,7 +154,7 @@ Red/System [ 322832273227464A3232323E3E4A35322532323232323E4A5C5C32325C5C5C5C 5C5C5C3E323332323232323232465C3232323E3E5C35322532323232323E5C5C 5C3E3E5C5C5C5C5C5C5C3E3E3E3E3E3E3E3E3E3E465C5C3E3E3E3E5C353E253E -3E3E3E3E3E5C4A4A2B2B4A4A4A4A4A4A4A2B2B4A2B2B2B2B2B2B2B2B2B2A3232 +3E3E3E3E3E5C4A4A2B2B4A4A4A4A4A4A4A2B2D4A2B2B2B2B2B2B2B2B2B2A3232 2B2B4A4A2B2B2B322B2B2B3E4A2B2B2B2B2B2B2B2B2B2B2C2B2D2B2B2B2B2B2B 2B2B2B2B2B592B2B2B2B2B2B2B2B2B2B2B2B3E3E2C2C2C2C2C2C2C2C2C2C2B2C 2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C3E3E2D2D2D2D2D From 0381c66c700de6607f47fe156ff3248737685f84 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 18:41:00 +0100 Subject: [PATCH 1108/3432] TESTS: test suite for MONEY! datatype --- tests/source/units/money-test.red | 368 ++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 tests/source/units/money-test.red diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red new file mode 100644 index 0000000000..31168c7bc0 --- /dev/null +++ b/tests/source/units/money-test.red @@ -0,0 +1,368 @@ +Red [ + Title: "Red money! datatype test script" + Author: "Vladimir Vasilyev" + File: %money-test.reds + Tabs: 4 + Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." + License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" +] + +#include %../../../quick-test/quick-test.red + +~~~start-file~~~ "money" + +===start-group=== "zero?" + --test-- "zero-1" --assert zero? -$0 + --test-- "zero-2" --assert zero? +$0 + --test-- "zero-3" --assert not zero? $0.1 + --test-- "zero-4" --assert not zero? -$2 +===end-group=== + +===start-group=== "negative?" + --test-- "negative-1" --assert negative? -$1 + --test-- "negative-2" --assert not negative? +$0 + --test-- "negative-3" --assert not negative? -$0 + --test-- "negative-4" --assert not negative? +$1 +===end-group=== + +===start-group=== "positive?" + --test-- "positive-1" --assert positive? +$1 + --test-- "positive-2" --assert not positive? +$0 + --test-- "positive-3" --assert not positive? -$0 + --test-- "positive-4" --assert not positive? -$1 +===end-group=== + +===start-group=== "even?" + --test-- "even-1" --assert even? $0 + --test-- "even-2" --assert even? $2.345 + --test-- "even-3" --assert even? -$4.678 + --test-- "even-4" --assert not even? $5 +===end-group=== + +===start-group=== "odd?" + --test-- "odd-1" --assert odd? $1.234 + --test-- "odd-2" --assert odd? -$3.456 + --test-- "odd-3" --assert odd? $12345678901234567.12345 + --test-- "odd-4" --assert not odd? $0.12345 +===end-group=== + +===start-group=== "equal?" + --test-- "equal-1" --assert equal? $0 $0 + --test-- "equal-2" --assert equal? $0.12345 $0.12345 + --test-- "equal-3" --assert equal? +$0 -$0 + --test-- "equal-4" --assert equal? -$000123.45 -$123.45000 + --test-- "equal-5" --assert equal? $123.456 123.456 + --test-- "equal-6" --assert equal? -$2147483648 -2147483648 +===end-group=== + +===start-group=== "not-equal?" + --test-- "not-equal-1" --assert not-equal? +$1 -$1 + --test-- "not-equal-2" --assert not-equal? $0.00001 $0.0001 + --test-- "not-equal-3" --assert not-equal? $123.456 $12.3456 + --test-- "not-equal-4" --assert not-equal? -$1 -$2 + --test-- "not-equal-5" --assert not-equal? $123.45 123 + --test-- "not-equal-6" --assert not-equal? $123.45 123.456 +===end-group=== + +===start-group=== "strict-equal?" + --test-- "strict-equal-1" --assert strict-equal? $12345678901234567.12345 $12345678901234567.12345 + --test-- "strict-equal-2" --assert not strict-equal? $123.456 123.456 + --test-- "strict-equal-3" --assert not strict-equal? $123 123 + --test-- "strict-equal-4" --assert strict-equal? -$0 +$0 + --test-- "strict-equal-5" --assert strict-equal? -$1 -$1 + --test-- "strict-equal-6" --assert strict-equal? +$1 +$1 +===end-group=== + +===start-group=== "same?" + --test-- "same-1" --assert same? $12345678901234567.12345 $12345678901234567.12345 + --test-- "same-2" --assert not same? $123.456 123.456 + --test-- "same-3" --assert not same? $123 123 + --test-- "same-4" --assert same? -$0 +$0 + --test-- "same-5" --assert same? -$1 -$1 + --test-- "same-6" --assert same? +$1 +$1 +===end-group=== + +===start-group=== "lesser?" + --test-- "lesser-1" --assert lesser? $0 1 + --test-- "lesser-2" --assert lesser? 1 $2 + --test-- "lesser-3" --assert lesser? -$1 $2 + --test-- "lesser-4" --assert lesser? -$1 $0 + --test-- "lesser-5" --assert lesser? $1 1.00001 + --test-- "lesser-6" --assert lesser? -1.00001 -$1 + --test-- "lesser-7" --assert not lesser? -$0 +$0 +===end-group=== + +===start-group=== "greater?" + --test-- "greater-1" --assert greater? $1 0 + --test-- "greater-2" --assert greater? 2 $1 + --test-- "greater-3" --assert greater? $2 -1 + --test-- "greater-4" --assert greater? $0 -$1 + --test-- "greater-5" --assert greater? -$1 -1.00001 + --test-- "greater-6" --assert greater? 1.00001 $1 + --test-- "greater-7" --assert not greater? +$0 -$0 +===end-group=== + +===start-group=== "lesser-or-equal?" + --test-- "lesser-or-equal-1" --assert lesser-or-equal? $0 0 + --test-- "lesser-or-equal-2" --assert lesser-or-equal? 0 $1 + --test-- "lesser-or-equal-3" --assert lesser-or-equal? $1 $1 + --test-- "lesser-or-equal-4" --assert lesser-or-equal? $1 2.0 + --test-- "lesser-or-equal-5" --assert lesser-or-equal? -1.0 $1 + --test-- "lesser-or-equal-6" --assert lesser-or-equal? -$2 -1 + --test-- "lesser-or-equal-7" --assert lesser-or-equal? -$2 -$2 +===end-group=== + +===start-group=== "greater-or-equal?" + --test-- "greater-or-equal-1" --assert greater-or-equal? $0 0 + --test-- "greater-or-equal-2" --assert greater-or-equal? 1 $0 + --test-- "greater-or-equal-3" --assert greater-or-equal? $1 1.0 + --test-- "greater-or-equal-4" --assert greater-or-equal? 2.0 $1 + --test-- "greater-or-equal-5" --assert greater-or-equal? $1 -1 + --test-- "greater-or-equal-6" --assert greater-or-equal? -$1 -2.0 + --test-- "greater-or-equal-7" --assert greater-or-equal? -$2 -$2 +===end-group=== + +===start-group=== "min" + --test-- "min-1" --assert $0 == min $0 $0 + --test-- "min-2" --assert $1 == min 2 $1 + --test-- "min-3" --assert -$1 == min -$1 0 + --test-- "min-4" --assert -$2 == min -$1 -$2 + --test-- "min-5" --assert $1.99999 == min $1.99999 $2 +===end-group=== + +===start-group=== "max" + --test-- "max-1" --assert $0 == max $0 $0 + --test-- "max-2" --assert $2 == max $2 1 + --test-- "max-3" --assert -$1 == max -2 -$1 + --test-- "max-4" --assert $2 == max $2 -$1 + --test-- "max-5" --assert -$1 == max -$1.99999 -$1 +===end-group=== + +===start-group=== "negate" + --test-- "negate-1" --assert $0 == negate $0 + --test-- "negate-2" --assert -$1 == negate $1 + --test-- "negate-3" --assert $1 == negate -$1 +===end-group=== + +===start-group=== "absolute" + --test-- "absolute-1" --assert $0 == absolute $0 + --test-- "absolute-2" --assert $1 == absolute $1 + --test-- "absolute-3" --assert $1 == absolute -$1 +===end-group=== + +===start-group=== "to" + --test-- "to-1" --assert $123.456 == to money! $123.456 + --test-- "to-2" --assert $123.456 == to money! 123.456 + --test-- "to-3" --assert $123 == to money! 123 + --test-- "to-4" --assert 123 == to integer! to money! 123 + --test-- "to-5" --assert 123.456 == to float! to money! 123.456 + --test-- "to-6" --assert 2147483647 == to integer! $2147483647 + --test-- "to-7" --assert -2147483648 == to integer! -$2147483648 + --test-- "to-8" --assert error? try [to integer! $9999999999 ] + --test-- "to-9" --assert 0.00001 == to float! to money! 0.00001 + --test-- "to-10" --assert error? try [to float! to money! 0.000001] + --test-- "to-11" --assert error? try [to money! 0 / 0.0] ;-- 1.#NaN + --test-- "to-12" --assert error? try [to money! 1 / 0.0] ;-- 1.#INF + --test-- "to-13" --assert error? try [to money! -1 / 0.0] ;-- -1.#INF + --test-- "to-14" --assert "$123.00000" == to string! $123 + --test-- "to-15" --assert "-$12'345'678'901'234'567.12345" == to string! -$12345678901234567.12345 + --test-- "to-16" --assert $12'345'678'901'234'567.12345 == to money! <12345678901234567.12345> + --test-- "to-17" --assert error? try [to money! "12345679O1234567.12345"] + --test-- "to-18" --assert -$1 == to money! "-0000000000000000000000000000000001.000000000000000000" +===end-group=== + +===start-group=== "make" + --test-- "make-1" --assert $12345678901234567.12345 == make money! #{1234567890123456712345 DEADBEEF} + --test-- "make-2" --assert $0 == make money! #{} + --test-- "make-3" --assert error? try [make money! #{DEADBEEF}] + ;@@ make money! +===end-group=== + +===start-group=== "add" + max-money: $99999999999999999.99999 + min-money: negate max-money + --test-- "add-1" --assert $0 == add $0 $0 + --test-- "add-2" --assert $0 == add $1 -$1 + --test-- "add-3" --assert $0 == add -$1 $1 + --test-- "add-4" --assert -$2 == add -$1 -$1 + --test-- "add-5" --assert error? try [add max-money 1] + --test-- "add-6" --assert error? try [add min-money -1] + --test-- "add-7" --assert max-money == add max-money 0 + --test-- "add-8" --assert min-money == add min-money 0 + --test-- "add-9" --assert $2 == add $1 $1 + --test-- "add-10" --assert $444.444 == add $123.321 $321.123 + --test-- "add-11" --assert $1000.01998 == add $1000.00999 $0.00999 + --test-- "add-12" --assert $1111.11111 == add $1010.10101 $0101.01010 + --test-- "add-13" --assert $0 == add min-money max-money + --test-- "add-14" --assert $1000.00999 == add $999.99999 $0.01 + --test-- "add-15" --assert $198 == add $321 -$123 +===end-group=== + +===start-group=== "subtract" + max-money: $99999999999999999.99999 + min-money: negate max-money + --test-- "subtract-1" --assert $0 == subtract $0 $0 + --test-- "subtract-2" --assert $0 == subtract $1 $1 + --test-- "subtract-3" --assert $0 == subtract -$1 -$1 + --test-- "subtract-4" --assert $1 == subtract $4 $3 + --test-- "subtract-5" --assert -$1 == subtract $3 $4 + --test-- "subtract-6" --assert -$7 == subtract -$4 $3 + --test-- "subtract-7" --assert $1 == subtract -$3 -$4 + --test-- "subtract-8" --assert -$1 == subtract -$4 -$3 + --test-- "subtract-9" --assert $0 == subtract max-money max-money + --test-- "subtract-10" --assert $0 == subtract min-money min-money + --test-- "subtract-11" --assert error? try [subtract max-money min-money] + --test-- "subtract-12" --assert error? try [subtract min-money max-money] + --test-- "subtract-13" --assert $090.909 == subtract $989.898 $898.989 + --test-- "subtract-14" --assert $998001 == subtract $999000 $000999 + --test-- "subtract-15" --assert $1985654.32092 == subtract $997999.99992 -$987654.3210 +===end-group=== + +===start-group=== "multiply" + max-money: $99999999999999999.99999 + min-money: negate max-money + --test-- "multiply-1" --assert $0 == multiply $0 0 + --test-- "multiply-2" --assert $0 == multiply $0 1 + --test-- "multiply-3" --assert $2 == multiply $2 1 + --test-- "multiply-4" --assert $1 == multiply $0.001 1000 + --test-- "multiply-5" --assert -$8 == multiply -$4 2 + --test-- "multiply-6" --assert -$4 == multiply $8 -0.5 + --test-- "multiply-7" --assert -$4 == multiply -$0.00025 16000 + --test-- "multiply-8" --assert $2.02016 == multiply $8 0.25252 + --test-- "multiply-9" --assert $72.05088 == multiply $9.00123 8.00456 + --test-- "multiply-10" --assert $1303030.30302 == multiply $434343.43434 3 + --test-- "multiply-11" --assert error? try [multiply $0.12345 0.00001 ] + --test-- "multiply-12" --assert error? try [multiply max-money 1.1 ] + --test-- "multiply-13" --assert $999999999999.99999 == multiply -$33333333333333333.33333 -0.00003 + --test-- "multiply-14" --assert min-money == multiply $33333333333333333.33333 -3 + --test-- "multiply-15" --assert error? try [multiply $1 $1 ] +===end-group=== + +===start-group=== "divide" + max-money: $99999999999999999.99999 + min-money: negate max-money + --test-- "divide-1" --assert 0.0 == divide $0 $1 + --test-- "divide-2" --assert $0 == divide $0 1 + --test-- "divide-3" --assert error? try [divide $0 0 ] + --test-- "divide-4" --assert error? try [divide 0 $1 ] + --test-- "divide-5" --assert 1.0 == divide -$12345 -$12345 + --test-- "divide-6" --assert $2407581171 == divide $4815162342 2 + --test-- "divide-7" --assert -$4815162342 == divide $2407581171 -0.5 + --test-- "divide-8" --assert -0.25 == divide -$1 $4 + --test-- "divide-9" --assert error? try [divide $1234567890123.45678 0.00001 ] + --test-- "divide-10" --assert $123.45678 == divide $123.45678 1 + --test-- "divide-11" --assert 123.0 == divide $0.00123 $0.00001 + --test-- "divide-12" --assert error? try [divide $123 100000000] + --test-- "divide-13" --assert $33333333333333333.33333 == divide max-money 3 + --test-- "divide-14" --assert -1.0 == divide max-money min-money + --test-- "divide-15" --assert $00000000000000009.99999 == divide max-money 1e16 +===end-group=== + +===start-group=== "remainder" + max-money: $99999999999999999.99999 + min-money: negate max-money + --test-- "remainder-1" --assert error? try [remainder $0 0 ] + --test-- "remainder-2" --assert $0 == remainder $0 1 + --test-- "remainder-3" --assert $0.456 == remainder $123.456 1 + --test-- "remainder-4" --assert error? try [remainder 123.456 $1 ] + --test-- "remainder-5" --assert $5.856 == remainder $321.456 $7.89 + --test-- "remainder-6" --assert $2 == remainder $8 3 + --test-- "remainder-7" --assert $2 == remainder $8 -3 + --test-- "remainder-8" --assert -$2 == remainder -$8 3 + --test-- "remainder-9" --assert -$2 == remainder -$8 -3 + --test-- "remainder-10" --assert $000000000999999.99999 == remainder max-money 1e6 + --test-- "remainder-11" --assert $0 == remainder max-money min-money + --test-- "remainder-12" --assert $0.006 == remainder $123.456 0.01 + --test-- "remainder-13" --assert $0.00001 == remainder $0.00009 0.00004 + --test-- "remainder-14" --assert $0.2 == remainder $9 0.4 + --test-- "remainder-15" --assert $0.56789 == remainder $0.56789 123.456 +===end-group=== + +===start-group=== "sort" + --test-- "sort-1" + block: [9 2.0 $4 5.0 $8 7 $3 6.0 2.0 $1 5] + result: [$1 2.0 2.0 $3 $4 5 5.0 6.0 7 $8 9] + --assert result = sort block + --test-- "sort-2" + block: [-1 -$8 2 3 -4.0 $7 2 $5 -$6 9] + result: [-$8 -$6 -4.0 -1 2 2 3.0 $5 $7 9] + --assert result = sort block +===end-group=== + +===start-group=== "find" + --test-- "find-1" --assert none == find [] $123 + --test-- "find-2" --assert none == find [123 123.0 12300%] $123 + --test-- "find-3" --assert none == find [$0.00001 ] 0.00001 + --test-- "find-4" --assert none == find [$1 ] 1 + --test-- "find-5" --assert 3 = index? find [a b $1 c d] $1 + --test-- "find-6" --assert last? find [a b c d $0.00001 ] $0.00001 +===end-group=== + +===start-group=== "generated" + --test-- "generated-1-+" --assert -$46256738.73641 + -$382909867.62517 == -$429166606.36158 + --test-- "generated-2-+" --assert -$861608569.91149 + -$385303837.42661 == -$1246912407.33810 + --test-- "generated-3-+" --assert $406101726.18464 + $451878314.11690 == $857980040.30154 + --test-- "generated-4-+" --assert -$924194595.27552 + 818047457.75555 == -$106147137.51997 + --test-- "generated-5-+" --assert $343313757.49004 + -500051462.32435 == -$156737704.83431 + + --test-- "generated-1--" --assert $697707660.35546 - -$784908132.06177 == $1482615792.41723 + --test-- "generated-2--" --assert $0.00000 - $478883852.93952 == -$478883852.93952 + --test-- "generated-3--" --assert -$906981959.43001 - $707098374.93816 == -$1614080334.36817 + --test-- "generated-4--" --assert $578714290.90327 - $357084565.49657 == $221629725.40670 + --test-- "generated-5--" --assert -$681046219.85975 - $912477347.02772 == -$1593523566.88747 + + --test-- "generated-1-*" --assert $362973781.93725 * 47800116.26323 == $17350188977104843.34034 + --test-- "generated-2-*" --assert $156244716.21412 * -55410156.51794 == -$8657544180525506.91866 + --test-- "generated-3-*" --assert $14354088.35036 * 520106887.22138 == $7465660210806413.00832 + --test-- "generated-4-*" --assert $198848883.24832 * -168188266.06878 == -$33444048883248214.40293 + --test-- "generated-5-*" --assert -$77543792.35093 * -259182608.34141 == $20098002362198714.77197 + + --test-- "generated-1-/" --assert $230432974.28192 / -$789641370.898869 == -0.29181 + --test-- "generated-2-/" --assert -$63871490.79883 / -$527109821.57248 == 0.12117 + --test-- "generated-3-/" --assert $759773312.95598 / $133309383.93869 == 5.69932 + --test-- "generated-4-/" --assert -$854685410.78952 / $195492505.65259 == -4.37195 + --test-- "generated-5-/" --assert -$751138200.40185 / -$112696153.62989 == 6.66516 + + --test-- "generated-1-%" --assert -$957563788.14463 % $779532506.49362 == -$178031281.65101 + --test-- "generated-2-%" --assert $132314569.37841 % $76536801.67930 == $55777767.69911 + --test-- "generated-3-%" --assert $963775501.56961 % -$282119043.76843 == $117418370.26432 + --test-- "generated-4-%" --assert -$178534509.23158 % $717081736.64150 == -$178534509.23158 + --test-- "generated-5-%" --assert -$208895940.89653 % -$659465734.68830 == -$208895940.89653 + + --test-- "generated-1-//" --assert $565109371.00513 // -$402218239.56920 == $162891131.43593 + --test-- "generated-2-//" --assert $199006393.17883 // -$54347604.07281 == $35963580.96040 + --test-- "generated-3-//" --assert -$214794486.39545 // -$706261607.68151 == $491467121.28606 + --test-- "generated-4-//" --assert -$462802999.86842 // -$786203480.22607 == $323400480.35765 + --test-- "generated-5-//" --assert -$720945595.63367 // $994421652.98126 == $273476057.34759 + + --test-- "generated-1-=" --assert -$638863945.67734 = $99554975.09779 == false + --test-- "generated-2-=" --assert $394800340.47495 = $386906189.09285 == false + --test-- "generated-3-=" --assert $27392364.58548 = -$817914108.19529 == false + --test-- "generated-4-=" --assert $857418370.83240 = $849162471.41042 == false + --test-- "generated-5-=" --assert -$123616631.20035 = -$825913311.36687 == false + + --test-- "generated-1->" --assert $782775981.25057 > -$439229823.38779 == true + --test-- "generated-2->" --assert -$771057614.48435 > $365815091.11719 == false + --test-- "generated-3->" --assert -$147504274.80205 > -$878620700.38849 == true + --test-- "generated-4->" --assert -$813063470.09402 > $920014728.28909 == false + --test-- "generated-5->" --assert -$876986659.07465 > -134834604.40059736 == false + + --test-- "generated-1-<" --assert -$544867101.84479 < -$46940005.40624 == true + --test-- "generated-2-<" --assert $479498603.13883 < $562156187.63218 == true + --test-- "generated-3-<" --assert $411283579.38084 < $365425110.49910 == false + --test-- "generated-4-<" --assert -$756771806.51424 < -$554513646.08225 == true + --test-- "generated-5-<" --assert $0.00000 < 222266816.63760078 == true + + --test-- "generated-1->=" --assert -$880521171.67064 >= -$964203733.93417 == true + --test-- "generated-2->=" --assert $645425207.28214 >= -$474653873.81363 == true + --test-- "generated-3->=" --assert $205025497.91942 >= $724002546.0366099 == false + --test-- "generated-4->=" --assert $582886748.75296 >= 920936930.4221668 == false + --test-- "generated-5->=" --assert -$885142156.80077 >= 828554261.8616188 == false + + --test-- "generated-1-<=" --assert $116818469.07214 <= -$928374897.65526 == false + --test-- "generated-2-<=" --assert $431016918.93814 <= $581463247.34271 == true + --test-- "generated-3-<=" --assert $220037805.01896 <= -$686523818.26495 == false + --test-- "generated-4-<=" --assert $35305992.25093 <= -$609764191.14030 == false + --test-- "generated-5-<=" --assert $761650628.29928 <= -$188013192.81943 == false +===end-group=== +~~~end-file~~~ From 50e0efc4b4eedb153663e3300c35a777121d5a78 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 12 Mar 2020 18:50:45 +0100 Subject: [PATCH 1109/3432] FIX: sticky delimiter on money! value ending was skipped. Example: >> [$1] *** Syntax Error: (line 2) missing ] at [$1] --- runtime/lexer.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index efcc516483..e1d3c4eed4 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1879,7 +1879,7 @@ lexer: context [ if p/1 = #"." [if dec? [do-error] dec?: yes] p: p + 1 ] - lex/in-pos: e + 1 ;-- skip ending delimiter + lex/in-pos: e ;-- reset the input position to delimiter byte ;if load? [money/make-at alloc-slot lex cur s e neg?] ] From 470abfa1fa102b1efac9a6d35222f2eb733191f4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 20:26:33 +0100 Subject: [PATCH 1110/3432] FEAT: remove workarounds for lexer bug --- tests/source/units/money-test.red | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 31168c7bc0..fadb1fc3f1 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -158,7 +158,7 @@ Red [ --test-- "to-5" --assert 123.456 == to float! to money! 123.456 --test-- "to-6" --assert 2147483647 == to integer! $2147483647 --test-- "to-7" --assert -2147483648 == to integer! -$2147483648 - --test-- "to-8" --assert error? try [to integer! $9999999999 ] + --test-- "to-8" --assert error? try [to integer! $9999999999] --test-- "to-9" --assert 0.00001 == to float! to money! 0.00001 --test-- "to-10" --assert error? try [to float! to money! 0.000001] --test-- "to-11" --assert error? try [to money! 0 / 0.0] ;-- 1.#NaN @@ -231,8 +231,8 @@ Red [ --test-- "multiply-8" --assert $2.02016 == multiply $8 0.25252 --test-- "multiply-9" --assert $72.05088 == multiply $9.00123 8.00456 --test-- "multiply-10" --assert $1303030.30302 == multiply $434343.43434 3 - --test-- "multiply-11" --assert error? try [multiply $0.12345 0.00001 ] - --test-- "multiply-12" --assert error? try [multiply max-money 1.1 ] + --test-- "multiply-11" --assert error? try [multiply $0.12345 0.00001] + --test-- "multiply-12" --assert error? try [multiply max-money 1.1] --test-- "multiply-13" --assert $999999999999.99999 == multiply -$33333333333333333.33333 -0.00003 --test-- "multiply-14" --assert min-money == multiply $33333333333333333.33333 -3 --test-- "multiply-15" --assert error? try [multiply $1 $1 ] @@ -243,13 +243,13 @@ Red [ min-money: negate max-money --test-- "divide-1" --assert 0.0 == divide $0 $1 --test-- "divide-2" --assert $0 == divide $0 1 - --test-- "divide-3" --assert error? try [divide $0 0 ] - --test-- "divide-4" --assert error? try [divide 0 $1 ] + --test-- "divide-3" --assert error? try [divide $0 0] + --test-- "divide-4" --assert error? try [divide 0 $1] --test-- "divide-5" --assert 1.0 == divide -$12345 -$12345 --test-- "divide-6" --assert $2407581171 == divide $4815162342 2 --test-- "divide-7" --assert -$4815162342 == divide $2407581171 -0.5 --test-- "divide-8" --assert -0.25 == divide -$1 $4 - --test-- "divide-9" --assert error? try [divide $1234567890123.45678 0.00001 ] + --test-- "divide-9" --assert error? try [divide $1234567890123.45678 0.00001] --test-- "divide-10" --assert $123.45678 == divide $123.45678 1 --test-- "divide-11" --assert 123.0 == divide $0.00123 $0.00001 --test-- "divide-12" --assert error? try [divide $123 100000000] @@ -261,10 +261,10 @@ Red [ ===start-group=== "remainder" max-money: $99999999999999999.99999 min-money: negate max-money - --test-- "remainder-1" --assert error? try [remainder $0 0 ] + --test-- "remainder-1" --assert error? try [remainder $0 0] --test-- "remainder-2" --assert $0 == remainder $0 1 --test-- "remainder-3" --assert $0.456 == remainder $123.456 1 - --test-- "remainder-4" --assert error? try [remainder 123.456 $1 ] + --test-- "remainder-4" --assert error? try [remainder 123.456 $1] --test-- "remainder-5" --assert $5.856 == remainder $321.456 $7.89 --test-- "remainder-6" --assert $2 == remainder $8 3 --test-- "remainder-7" --assert $2 == remainder $8 -3 @@ -292,10 +292,10 @@ Red [ ===start-group=== "find" --test-- "find-1" --assert none == find [] $123 --test-- "find-2" --assert none == find [123 123.0 12300%] $123 - --test-- "find-3" --assert none == find [$0.00001 ] 0.00001 - --test-- "find-4" --assert none == find [$1 ] 1 + --test-- "find-3" --assert none == find [$0.00001] 0.00001 + --test-- "find-4" --assert none == find [$1] 1 --test-- "find-5" --assert 3 = index? find [a b $1 c d] $1 - --test-- "find-6" --assert last? find [a b c d $0.00001 ] $0.00001 + --test-- "find-6" --assert last? find [a b c d $0.00001] $0.00001 ===end-group=== ===start-group=== "generated" From 1c01b10a02e09f91093e6bdcca1ccbd6f7e7f479 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 12 Mar 2020 20:34:47 +0100 Subject: [PATCH 1111/3432] FIX: more robust sorting test --- tests/source/units/money-test.red | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index fadb1fc3f1..28ba0af7de 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -282,11 +282,11 @@ Red [ --test-- "sort-1" block: [9 2.0 $4 5.0 $8 7 $3 6.0 2.0 $1 5] result: [$1 2.0 2.0 $3 $4 5 5.0 6.0 7 $8 9] - --assert result = sort block + --assert result == sort block --test-- "sort-2" - block: [-1 -$8 2 3 -4.0 $7 2 $5 -$6 9] + block: [-1 -$8 2 3.0 -4.0 $7 2 $5 -$6 9] result: [-$8 -$6 -4.0 -1 2 2 3.0 $5 $7 9] - --assert result = sort block + --assert result == sort block ===end-group=== ===start-group=== "find" From 6e23c39e88c0f09e12b998bb8642a60ea89ad17f Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 7 Mar 2020 17:46:32 +0800 Subject: [PATCH 1112/3432] FIX: improve gdk image! --- modules/view/backends/gtk3/gui.reds | 30 -- runtime/platform/image-gdk.reds | 699 ++++++++-------------------- 2 files changed, 183 insertions(+), 546 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 97a8c138d8..e9d5958bc4 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -2128,36 +2128,6 @@ OS-do-draw: func [ OS-image/unlock-bitmap image bitmap ] -OS-do-draw-OLD: func [ - image [red-image!] - cmds [red-block!] - /local - cr [handle!] - surf [handle!] - w [integer!] - h [integer!] - bitmap [integer!] - data [int-ptr!] - stride [integer!] - pixbuf [int-ptr!] - buf [byte-ptr!] -][ - ;; DEBUG: print ["OS-do-draw " image lf] - w: IMAGE_WIDTH(image/size) - h: IMAGE_HEIGHT(image/size) - stride: 0 - bitmap: OS-image/lock-bitmap image yes - data: OS-image/get-data bitmap :stride - ;stride: cairo_format_stride_for_width CAIRO_FORMAT_ARGB32 w - surf: cairo_image_surface_create_for_data as byte-ptr! data CAIRO_FORMAT_ARGB32 w h stride - cr: cairo_create surf - do-draw cr null cmds no yes yes yes - cairo_destroy cr - cairo_surface_destroy surf - OS-image/buffer-argb-to-abgr data w h - OS-image/unlock-bitmap image bitmap -] - OS-draw-face: func [ ctx [draw-ctx!] cmds [red-block!] diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 9adde58fec..137a030702 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -22,92 +22,6 @@ GError!: alias struct! [ code [integer!] message [c-string!] ] -; bgra-to-rgba: func [ -; color [integer!] -; return: [integer!] -; /local -; r [integer!] -; b [integer!] -; g [integer!] -; a [integer!] -; ][ -; b: (color >>> 24 and FFh) -; g: (color >> 16 and FFh) -; r: (color >> 8 and FFh) -; a: (color and FFh) -; ;color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) -; color: (r << 24) or (g << 16) or (b << 8) or a -; color -; ] - -; bgra-to-argb: func [ -; color [integer!] -; return: [integer!] -; /local -; r [integer!] -; b [integer!] -; g [integer!] -; a [integer!] -; ][ -; b: (color >>> 24 and FFh) -; g: (color >> 16 and FFh) -; r: (color >> 8 and FFh) -; a: (color and FFh) -; ;color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) -; color: (a << 24) or (r << 16) or (g << 8) or b -; color -; ] - -; argb-to-rgba: func [ -; color [integer!] -; return: [integer!] -; /local -; r [integer!] -; b [integer!] -; g [integer!] -; a [integer!] -; ][ -; a: (color >>> 24 and FFh) -; r: (color >> 16 and FFh) -; g: (color >> 8 and FFh) -; b: (color and FFh) -; color: (r << 24 and FF000000h) or (g << 16 and 00FF0000h) or ( b << 8 and FF00h) or ( a and FFh) -; color -; ] - -argb-to-abgr: func [ - color [integer!] - return: [integer!] - /local - r [integer!] - b [integer!] - g [integer!] - a [integer!] -][ - a: (color >>> 24 and FFh) - r: (color >> 16 and FFh) - g: (color >> 8 and FFh) - b: (color and FFh) - color: (a << 24 and FF000000h) or (b << 16 and 00FF0000h) or ( g << 8 and FF00h) or ( r and FFh) - color -] - -rgba-to-argb: func [ - color [integer!] - return: [integer!] - /local - r [integer!] - b [integer!] - g [integer!] - a [integer!] -][ - r: (color >>> 24 and FFh) - g: (color >> 16 and FFh) - b: (color >> 8 and FFh) - a: (color and FFh) - color: (a << 24) or (r << 16) or (g << 8) or b - color -] OS-image: context [ @@ -127,19 +41,19 @@ OS-image: context [ #import [ LIBGDK-file cdecl [ gdk_pixbuf_new: "gdk_pixbuf_new" [ - colorsp [integer!] - alpha [logic!] - bits [integer!] - width [integer!] - height [integer!] - return: [handle!] + colorsp [integer!] + alpha [logic!] + bits [integer!] + width [integer!] + height [integer!] + return: [handle!] ] gdk_pixbuf_new_subpixbuf: "gdk_pixbuf_new_subpixbuf" [ pixbuf [handle!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] return: [handle!] ] gdk_pixbuf_new_from_bytes: "gdk_pixbuf_new_from_bytes" [ @@ -245,12 +159,6 @@ OS-image: context [ inode: as img-node! (as series! handle/value) + 1 IMAGE_HEIGHT(inode/size) ] - - #enum post-transf! [POST-TRANSF-NONE POST-ARGB-TO-ABGR POST-ARGB-TO-RGBA] - - post-transf?: POST-TRANSF-NONE - - post-transf: func [ mode [post-transf!]][post-transf?: mode] lock-bitmap: func [ img [red-image!] @@ -259,48 +167,27 @@ OS-image: context [ /local inode [img-node!] ][ - ;; DEBUG: print ["lock-bitmap " img lf] inode: as img-node! (as series! img/node/value) + 1 - ;; DEBUG: print ["flags: " inode/flags lf] if zero? inode/flags [ - ;; DEBUG: print ["lock-bitmap: flags" lf] inode/flags: IMG_NODE_HAS_BUFFER - inode/buffer: OS-image/data-to-image inode/handle -1 yes yes - ;; DEBUG: print ["inode/buuufer " inode/buffer " handle " inode/handle lf] + inode/buffer: pixbuf-to-buf inode/handle ] if write? [inode/flags: inode/flags or IMG_NODE_MODIFIED] - ;; post-transf POST-TRANSF-NONE ; no post-transf to apply before as integer! inode ] - unlock-bitmap: func [ ;-- do nothing on GDK backend - image [red-image!] - bitmap [integer!] - /local - w [integer!] - h [integer!] - node [img-node!] - ][ - unless post-transf? = POST-TRANSF-NONE [ - ;; DEBUG: print ["unlock-bitmap" lf] - w: IMAGE_WIDTH(image/size) - h: IMAGE_HEIGHT(image/size) - node: as img-node! bitmap - case [ - post-transf? = POST-ARGB-TO-ABGR [buffer-argb-to-abgr node/buffer w h] - ;; post-transf? = POST-ARGB-TO-RGBA [buffer-argb-to-rgba node/buffer w h] - ] - ] - ] + unlock-bitmap: func [ ;-- do nothing on Quartz backend + img [red-image!] + data [integer!] + ][] get-data: func [ handle [integer!] stride [int-ptr!] return: [int-ptr!] /local - inode [img-node!] + inode [img-node!] ][ - ;; DEBUG: print ["OS-image/get-data" lf] inode: as img-node! handle stride/value: IMAGE_WIDTH(inode/size) * 4 inode/buffer @@ -317,10 +204,9 @@ OS-image: context [ node: as img-node! (as series! bitmap/value) + 1 if zero? node/flags [ node/flags: IMG_NODE_HAS_BUFFER - node/buffer: data-to-image node/handle -1 yes yes + node/buffer: pixbuf-to-buf node/handle ] buf: node/buffer + index - ;; DEBUG: print ["get pixel " node/buffer " at " index " is " buf/value lf] buf/value ] @@ -336,7 +222,7 @@ OS-image: context [ node: as img-node! (as series! bitmap/value) + 1 if zero? node/flags [ node/flags: IMG_NODE_HAS_BUFFER - node/buffer: data-to-image node/handle -1 yes yes + node/buffer: pixbuf-to-buf node/handle ] node/flags: node/flags or IMG_NODE_MODIFIED buf: node/buffer + index @@ -344,9 +230,10 @@ OS-image: context [ color ] - delete: func [img [red-image!]][ - ; GdipDisposeImage as-integer img/node - 0 + delete: func [img [red-image!] /local inode [img-node!]][ + inode: as img-node! (as series! img/node/value) + 1 + if inode/handle <> null [g_object_unref inode/handle inode/handle: null] + if inode/buffer <> null [free as byte-ptr! inode/buffer inode/buffer: null] ] ; copied from quartz but do not think it is finished @@ -371,21 +258,6 @@ OS-image: context [ as-integer img/node ] - ; UNUSED in Quartz ???? Maybe for a future use???? - copy: func [ - dst [integer!] - src [integer!] - bytes [integer!] - offset [integer!] - /local - dst-buf [byte-ptr!] - src-buf [byte-ptr!] - ][ - ; dst-buf: CGBitmapContextGetData dst - ; src-buf: CGBitmapContextGetData src - ; copy-memory dst-buf src-buf + offset bytes - ] - make-node: func [ handle [int-ptr!] buffer [int-ptr!] @@ -406,192 +278,56 @@ OS-image: context [ node ] - alpha-channel?: func [ - pixbuf [integer!] - return: [logic!] - ][ - gdk_pixbuf_get_has_alpha as handle! pixbuf - ] - - buffer-argb-to-abgr: func [ - buf [int-ptr!] - width [integer!] - height [integer!] - return: [int-ptr!] ; not necessary since buf is already a pointer - /local - data-pixbuf [int-ptr!] - end-data-pixbuf [int-ptr!] - pixel [integer!] - i [integer!] - ][ - data-pixbuf: buf - end-data-pixbuf: data-pixbuf + (width * height) - ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] - while [data-pixbuf < end-data-pixbuf][ - pixel: data-pixbuf/value - ;; DEBUG: print ["pixel:" pixel lf] - pixel: argb-to-abgr pixel - data-pixbuf/value: pixel - data-pixbuf: data-pixbuf + 1 - ] - buf - ] - - buffer-rgba-to-argb: func [ - buf [int-ptr!] - width [integer!] - height [integer!] - return: [int-ptr!] ; not necessary since buf is already a pointer + ;-- ARGB(image! buffer) <-> ABGR(gtk) + revert: func [ + src [int-ptr!] + dst [int-ptr!] + count [integer!] + alpha? [logic!] /local - data-pixbuf [int-ptr!] - end-data-pixbuf [int-ptr!] - pixel [integer!] - i [integer!] + offset [integer!] + old [integer!] + p [byte-ptr!] + b [byte!] ][ - data-pixbuf: buf - end-data-pixbuf: data-pixbuf + (width * height) - ;; DEBUG: print ["buffer-rgba-to-argb -> size: " width "x" height lf] - while [data-pixbuf < end-data-pixbuf][ - pixel: data-pixbuf/value - ;; DEBUG: print ["pixel:" pixel lf] - ;pixel: (pixel >> 8) or (255 - (pixel >>> 24)) ; RGBA -> ARGB - pixel: rgba-to-argb pixel - data-pixbuf/value: pixel - data-pixbuf: data-pixbuf + 1 + offset: 1 + loop count [ + old: src/offset + p: as byte-ptr! :old + b: p/1 + p/1: p/3 + p/3: b + either alpha? [ + p/4: #"^(FF)" - p/4 + ][ + p/4: #"^(FF)" + ] + dst/1: old + offset: offset + 1 ] - buf ] - ; buffer-bgra-to-argb: func [ - ; buf [int-ptr!] - ; width [integer!] - ; height [integer!] - ; return: [int-ptr!] ; not necessary since buf is already a pointer - ; /local - ; data-pixbuf [int-ptr!] - ; end-data-pixbuf [int-ptr!] - ; pixel [integer!] - ; i [integer!] - ; ][ - ; data-pixbuf: buf - ; end-data-pixbuf: data-pixbuf + (width * height) - ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] - ; while [data-pixbuf < end-data-pixbuf][ - ; pixel: data-pixbuf/value - ; ;; DEBUG: print ["pixel:" pixel lf] - ; pixel: bgra-to-argb pixel - ; data-pixbuf/value: pixel - ; data-pixbuf: data-pixbuf + 1 - ; ] - ; buf - ; ] - - ; buffer-bgra-to-rgba: func [ - ; buf [int-ptr!] - ; width [integer!] - ; height [integer!] - ; return: [int-ptr!] ; not necessary since buf is already a pointer - ; /local - ; data-pixbuf [int-ptr!] - ; end-data-pixbuf [int-ptr!] - ; pixel [integer!] - ; i [integer!] - ; ][ - ; data-pixbuf: buf - ; end-data-pixbuf: data-pixbuf + (width * height) - ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] - ; while [data-pixbuf < end-data-pixbuf][ - ; pixel: data-pixbuf/value - ; ;; DEBUG: print ["pixel:" pixel lf] - ; pixel: bgra-to-rgba pixel - ; data-pixbuf/value: pixel - ; data-pixbuf: data-pixbuf + 1 - ; ] - ; buf - ; ] - - ; buffer-argb-to-rgba: func [ - ; buf [int-ptr!] - ; width [integer!] - ; height [integer!] - ; return: [int-ptr!] ; not necessary since buf is already a pointer - ; /local - ; data-pixbuf [int-ptr!] - ; end-data-pixbuf [int-ptr!] - ; pixel [integer!] - ; i [integer!] - ; ][ - ; data-pixbuf: buf - ; end-data-pixbuf: data-pixbuf + (width * height) - ; ;; DEBUG: print ["buffer-argb -> size: " width "x" height lf] - ; while [data-pixbuf < end-data-pixbuf][ - ; pixel: data-pixbuf/value - ; ;; DEBUG: print ["pixel:" pixel lf] - ; pixel: argb-to-rgba pixel - ; data-pixbuf/value: pixel - ; data-pixbuf: data-pixbuf + 1 - ; ] - ; buf - ; ] - - ; In particular used to query buffer from handle in lock-bitmap - data-to-image: func [ ;-- convert Pixbuf to OS handle or internal buffer - data [int-ptr!] - len [integer!] ; @@ added for data length - image? [logic!] - edit? [logic!] - return: [int-ptr!] + pixbuf-to-buf: func [ + pixbuf [int-ptr!] + return: [int-ptr!] /local - ; color-space [integer!] ; Only RGB + alpha? [logic!] width [integer!] height [integer!] - i [integer!] - bytes-row [integer!] - ; image-data [integer!] - pixbuf [integer!] - n [integer!] channels [integer!] - alpha? [logic!] - buf [byte-ptr!] - buf-src [byte-ptr!] - loader [handle!] + count [integer!] + buff [int-ptr!] + p [int-ptr!] ][ - ;; DEBUG: print ["data-to-image data: " data " len: " len " image?: " image? " edit?: " edit? lf] - either image? [ - pixbuf: as-integer data - ][ - loader: gdk_pixbuf_loader_new - gdk_pixbuf_loader_write loader data len null - gdk_pixbuf_loader_close loader null - pixbuf: as-integer gdk_pixbuf_loader_get_pixbuf loader - ] - - unless edit? [return as int-ptr! pixbuf] - - alpha?: alpha-channel? pixbuf - ;; DEBUG: print ["alpha?: " alpha? lf] - ; color-space: ONLY RGB - width: gdk_pixbuf_get_width as handle! pixbuf - height: gdk_pixbuf_get_height as handle! pixbuf - channels: gdk_pixbuf_get_n_channels as handle! pixbuf - ;; DEBUG: print ["size: " width "x" height " row-stride: " gdk_pixbuf_get_rowstride as handle! pixbuf " n_channels: " gdk_pixbuf_get_n_channels as handle! pixbuf " bits-per-sample: " gdk_pixbuf_get_bits_per_sample as handle! pixbuf " byte-length: " gdk_pixbuf_get_byte_length as handle! pixbuf lf] - if width * channels <> gdk_pixbuf_get_rowstride as handle! pixbuf [print ["WARNING rowstride: " gdk_pixbuf_get_rowstride as handle! pixbuf " <> width (" width ") * channels (" channels "): " (width * channels) lf]] - ; maybe better use other copy - either channels = 4 [ - buf: gdk_pixbuf_get_pixels gdk_pixbuf_copy as handle! pixbuf - ][ - ;; Needs to convert in n_channels = 4 - n: height * width * 4 - buf: allocate n * 4 - buf-src: gdk_pixbuf_read_pixels as handle! pixbuf - i: 1 - while [i <= n][ - either i % 4 = 0 [buf/i: as byte! 255][buf/i: buf-src/value buf-src: buf-src + 1] - i: i + 1 - ] - ] - buffer-argb-to-abgr as int-ptr! buf width height - as int-ptr! buf + alpha?: gdk_pixbuf_get_has_alpha pixbuf + width: gdk_pixbuf_get_width pixbuf + height: gdk_pixbuf_get_height pixbuf + channels: gdk_pixbuf_get_n_channels pixbuf + count: width * height + buff: as int-ptr! allocate count * 4 + p: as int-ptr! gdk_pixbuf_get_pixels pixbuf + revert p buff count channels = 4 + buff ] load-binary: func [ @@ -599,11 +335,13 @@ OS-image: context [ len [integer!] return: [node!] /local - h [int-ptr!] + loader [handle!] + h [handle!] ][ - ;; DEBUG: print ["load-binary" lf] - - h: data-to-image as int-ptr! data len no no + loader: gdk_pixbuf_loader_new + gdk_pixbuf_loader_write loader as int-ptr! data len null + gdk_pixbuf_loader_close loader null + h: gdk_pixbuf_loader_get_pixbuf loader make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h ] @@ -611,31 +349,20 @@ OS-image: context [ h [int-ptr!] return: [node!] ][ - ;; DEBUG: print ["load-pixbuf" lf] make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h - ;as node! 0 ] load-image: func [ ;-- load image from external resource: file! src [red-string!] return: [node!] /local - path [c-string!] - pixbuf [int-ptr!] - h [integer!] - w [integer!] - buf [byte-ptr!] - + path [c-string!] + h [int-ptr!] ][ - path: file/to-OS-path src ; DOES NOT WORK as in macOS: simple-io/to-NSURL src yes - ;; DEBUG: print [ "load-image: " path lf] - pixbuf: gdk_pixbuf_new_from_file path null - if null? pixbuf [return null] - w: gdk_pixbuf_get_width pixbuf h: gdk_pixbuf_get_height pixbuf - ;; DEBUG: print ["pixbuf: " pixbuf ", wxh: " w "x" h lf] - ;buf: gdk_pixbuf_get_pixels pixbuf - ;buffer-argb-to-abgr as int-ptr! buf w h - make-node pixbuf null 0 w h + path: file/to-OS-path src + h: gdk_pixbuf_new_from_file path null + if null? h [return null] + make-node h null 0 gdk_pixbuf_get_width h gdk_pixbuf_get_height h ] make-image: func [ @@ -655,7 +382,6 @@ OS-image: context [ scan0 [int-ptr!] pos [integer!] ][ - ;; DEBUG: print ["make-image" lf] scan0: as int-ptr! allocate width * height * 4 y: 0 either null? color [ @@ -670,25 +396,15 @@ OS-image: context [ b: as-integer rgb/3 rgb: rgb + 3 ] - scan0/pos: b or (g << 8) or (r << 16) or (a << 24) ; In little endian mode: result is BGRA + scan0/pos: r << 16 or (g << 8) or b or (a << 24) x: x + 1 ] y: y + 1 ] ][ - r: color/array1 - ; RGBA array1 reversed with little endian - ; => [R: r and FFh] [G: r >> 8 and FFh] [B: r >> 16 and FFh] [A: r >> 24 and FFh] - a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >> 24 and FFh)] - - ;;====== help for little-endian - ;; Ex -> img: make image! [1x1 1.2.3.4] ; == make image! [1x1 #{010203} #{04}] - ;; DEBUG: print ["r -> (1):" (r and FFh) " g -> (2): " (r >> 8 and FFh) " b -> (3): " (r >> 16 and FFh) " a -> (255-4): " a lf] - ;; b: to-integer img/argb ;= 50463227 - ;; print ["r -> (1):" (b and FFh) " g -> (2): " (b >> 8 and FFh) " b -> (3): " (b >> 16 and FFh) " a -> (255-4): " b >>> 24 lf] - ;; => r -> (1):251 g -> (2): 1 b -> (3): 2 a -> (255-4): 3 - - r: ((r and FFh) << 16) or ((r >> 8 and FFh) << 8) or (r >> 16 and FFh) or (a << 24) ; In little endian mode: RGBA -> BGRA + r: color/array1 + a: either TUPLE_SIZE?(color) = 3 [255][255 - (r >>> 24)] + r: r >> 16 and FFh or (r and FF00h) or (r and FFh << 16) or (a << 24) while [y < height][ x: 0 while [x < width][ @@ -706,23 +422,21 @@ OS-image: context [ image [red-image!] return: [int-ptr!] /local - w [integer!] - h [integer!] - data [int-ptr!] - end [int-ptr!] - clr [integer!] - pixbuf [int-ptr!] + w [integer!] + h [integer!] + data [int-ptr!] + end [int-ptr!] + clr [integer!] + pixbuf [int-ptr!] buf [byte-ptr!] - node [img-node!] + node [img-node!] ][ node: as img-node! (as series! image/node/value) + 1 w: IMAGE_WIDTH(image/size) h: IMAGE_HEIGHT(image/size) - pixbuf: gdk_pixbuf_new 0 yes 8 w h;CGImageCreate w h 8 32 w * 4 clr 2004h data null true 0 ;-- kCGRenderingIntentDefault - copy-memory gdk_pixbuf_get_pixels pixbuf as byte-ptr! node/buffer w * h * 4 + pixbuf: gdk_pixbuf_new 0 yes 8 w h buf: gdk_pixbuf_get_pixels pixbuf - buffer-argb-to-abgr as int-ptr! buf w h - ;; DEBUG: print ["make-pixbuf " img lf] + revert node/buffer as int-ptr! buf w * h yes pixbuf ] @@ -735,10 +449,8 @@ OS-image: context [ width [integer!] height [integer!] ][ - ;; DEBUG: print ["OS-image/to-pixbuf" lf] inode: as img-node! (as series! img/node/value) + 1 if inode/flags and IMG_NODE_MODIFIED <> 0 [ - ;; DEBUG: print ["IMG_NODE_MODIFIED " img lf] pixbuf: make-pixbuf img unless null? inode/handle [g_object_unref inode/handle] inode/handle: pixbuf @@ -747,32 +459,6 @@ OS-image: context [ inode/handle ] - ;; Better to not use! - to-argb-pixbuf: func [ - image [red-image!] - return: [int-ptr!] - /local - w [integer!] - h [integer!] - bitmap [integer!] - data [int-ptr!] - stride [integer!] - pixbuf [int-ptr!] - buf [byte-ptr!] - ][ - w: IMAGE_WIDTH(image/size) - h: IMAGE_HEIGHT(image/size) - stride: 0 - bitmap: OS-image/lock-bitmap image yes - data: OS-image/get-data bitmap :stride - pixbuf: gdk_pixbuf_new GDK_COLORSPACE_RGB yes 8 w h - copy-memory gdk_pixbuf_get_pixels pixbuf as byte-ptr! data w * h * 4 - OS-image/unlock-bitmap image bitmap - buf: gdk_pixbuf_get_pixels pixbuf - buffer-argb-to-abgr as int-ptr! buf w h - pixbuf - ] - encode: func [ image [red-image!] slot [red-value!] @@ -794,7 +480,6 @@ OS-image: context [ default [probe "Cannot find image encoder" return null] ] - ;; DEBUG: print ["encode: " type lf] pixbuf: to-pixbuf image switch TYPE_OF(slot) [ TYPE_URL @@ -807,6 +492,33 @@ OS-image: context [ slot ] + copy-rect: func [ + dst [byte-ptr!] + dw [integer!] + dh [integer!] + ds [integer!] + src [byte-ptr!] + sw [integer!] + sh [integer!] + ss [integer!] + x [integer!] + y [integer!] + lines [integer!] + /local + offset [integer!] + from [byte-ptr!] + to [byte-ptr!] + ][ + offset: y * ss + x * 4 + from: src + offset + to: dst + loop lines [ + copy-memory to from ds + to: to + ds + from: from + ss + ] + ] + clone: func [ src [red-image!] dst [red-image!] @@ -815,140 +527,95 @@ OS-image: context [ part? [logic!] return: [red-image!] /local - inode [img-node!] + inode0 [img-node!] + width [integer!] + height [integer!] + offset [integer!] x [integer!] y [integer!] - w [integer!] h [integer!] - offset [integer!] - handle [handle!] - handle2 [handle!] - width [integer!] - height [integer!] - bmp [integer!] - format [integer!] - src-buf [byte-ptr!] - dst-buf [byte-ptr!] - buf [int-ptr!] + w [integer!] + src-buf [byte-ptr!] + dst-buf [byte-ptr!] + handle0 [int-ptr!] + handle [int-ptr!] + scan0 [int-ptr!] ][ - ;; DEBUG: print ["image/clone " src " part? " part? lf] - inode: as img-node! (as series! src/node/value) + 1 - handle: inode/handle - src-buf: as byte-ptr! inode/buffer - width: IMAGE_WIDTH(inode/size) - height: IMAGE_HEIGHT(inode/size) + inode0: as img-node! (as series! src/node/value) + 1 + handle0: inode0/handle + width: IMAGE_WIDTH(inode0/size) + height: IMAGE_HEIGHT(inode0/size) offset: src/head - x: offset % width - y: offset / width - ;; DEBUG: print ["handle: " handle " src-buf: " src-buf " offset: " x "x" y " size " width "x" height lf] - - dst/node: make-node handle null 0 width height - inode: as img-node! (as series! dst/node/value) + 1 - - either all [zero? offset not part?][ - either null? handle [ - unless null? src-buf [ - ;; INFO: src-inode/handle null but not src-inode/buffer - dst-buf: allocate width * height * 4 - copy-memory dst-buf src-buf width * height * 4 0 - ;; DEBUG: print ["src-buf " dst-buf " " width "x" height lf] - inode/buffer: as int-ptr! dst-buf - inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER - inode/size: height << 16 or width - dst/size: inode/size - ] + if any [ + width <= 0 + height <= 0 + ][ + dst/size: 0 + dst/header: TYPE_IMAGE + dst/head: 0 + dst/node: make-node null null IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED 0 0 + return dst + ] + + if all [zero? offset not part?][ + either null? handle0 [ + scan0: as int-ptr! allocate inode0/size + dst/node: make-node null scan0 IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height + copy-memory as byte-ptr! scan0 as byte-ptr! inode0/buffer inode0/size ][ - ;; INFO: src-inode/handle not null? - inode/handle: gdk_pixbuf_copy handle - dst/size: src/size + handle: gdk_pixbuf_copy handle0 + dst/node: make-node handle null 0 width height ] + dst/size: src/size + dst/header: TYPE_IMAGE + dst/head: 0 + return dst + ] + + x: offset % width + y: offset / width + either all [part? TYPE_OF(size) = TYPE_PAIR][ + w: width - x + h: height - y + if size/x < w [w: size/x] + if size/y < h [h: size/y] ][ - either all [part? TYPE_OF(size) = TYPE_PAIR][ - w: width - x - h: height - y - if size/x < w [w: size/x] - if size/y < h [h: size/y] - handle2: gdk_pixbuf_copy gdk_pixbuf_new_subpixbuf handle x y w h - buf: as int-ptr! allocate w * h * 4 - pixbuf-to-data handle2 buf w h - g_object_unref handle2 - inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER - inode/buffer: buf + either zero? part [ + w: 0 h: 0 ][ - ;; TODO: This part is considered not enough stable!!!! - ;; DEBUG: print ["part: " part " size " w "x" h lf] either part < width [h: 1 w: part][ h: part / width w: width ] - if zero? part [w: 1 h: 1] - either zero? part [w: 0 h: 0][ - inode/flags: IMG_NODE_MODIFIED or IMG_NODE_HAS_BUFFER - src-buf: as byte-ptr! data-to-image handle -1 yes yes - dst-buf: allocate w * h * 4 - copy-memory dst-buf src-buf w * h * 4 offset * 4 - inode/handle: null - inode/buffer: as int-ptr! dst-buf - ] ] - inode/size: h << 16 or w - dst/size: inode/size - ;; DEBUG: print ["dst/size " w "x" h lf] ] - dst/head: 0 + if any [ + w <= 0 + h <= 0 + ][ + dst/size: 0 + dst/header: TYPE_IMAGE + dst/head: 0 + dst/node: make-node null null IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED 0 0 + return dst + ] + + either null? handle0 [ + dst-buf: allocate w * h * 4 + dst/node: make-node null as int-ptr! dst-buf IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED w h + src-buf: as byte-ptr! inode0/buffer + copy-rect dst-buf w h w * 4 src-buf width height width * 4 x y h + ][ + handle: gdk_pixbuf_new_subpixbuf handle0 x y w h + dst/node: make-node handle null 0 w h + ] + dst/size: h << 16 or w dst/header: TYPE_IMAGE - ;; DEBUG: print ["dst " dst lf] + dst/head: 0 dst ] - ;; pixbuf utils (since rowstride is not necessary width * channels for a pixbuf) - pixbuf-read-pixel: func [ - pixbuf [handle!] - x [integer!]; 1-based - y [integer!]; 1-based - return: [int-ptr!] - ][ - as int-ptr! (gdk_pixbuf_get_pixels pixbuf) + ((y - 1) * (gdk_pixbuf_get_rowstride pixbuf) + (x - 1) * (gdk_pixbuf_get_n_channels pixbuf)) - ] - - pixbuf-to-data: func [ - src-pixbuf [handle!] - dst-data [int-ptr!] - width [integer!] - height [integer!] - /local - x [integer!] - y [integer!] - pixels [byte-ptr!] - pixel [byte-ptr!] - stride [integer!] - channels [integer!] - src-buf [int-ptr!] - dst-buf [int-ptr!] - - ][ - pixels: gdk_pixbuf_get_pixels src-pixbuf - stride: (gdk_pixbuf_get_rowstride src-pixbuf) - channels: gdk_pixbuf_get_n_channels src-pixbuf - if channels <> 4 [print ["ERROR: number of channels is 3 and not 4 ..." lf]] - dst-buf: dst-data - y: 0 - while [y < height][ - x: 0 - pixel: pixels + (y * stride) - while [x < width][ - ;; DEBUG: print ["pixbuf-to-data: " x "x" y " size: " width "x" height lf] - ;; BE CAREFUL with rowstride for pixbuf - src-buf: as int-ptr! pixel - dst-buf/value: argb-to-abgr src-buf/value - dst-buf: dst-buf + 1 - pixel: pixel + channels - x: x + 1 - ] - y: y + 1 - ] - ] ] From a6e753913f6346449a26a38e7fa9530cc080bbe8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 8 Mar 2020 15:08:30 +0800 Subject: [PATCH 1113/3432] FEAT: useful bitmap functions for image! --- runtime/image-crop.reds | 233 ++++++++++++++++++++++++++++++++++++++++ runtime/vector2d.reds | 135 +++++++++++++++++++++++ 2 files changed, 368 insertions(+) create mode 100644 runtime/image-crop.reds create mode 100644 runtime/vector2d.reds diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds new file mode 100644 index 0000000000..73727c4d4d --- /dev/null +++ b/runtime/image-crop.reds @@ -0,0 +1,233 @@ +Red/System [ + Title: "image-crop" + Author: "bitbegin" + File: %image-crop.reds + Note: "useful functions for image!" + Tabs: 4 + Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +#include %vector2d.reds + +CROP-VERTEX!: alias struct! [ + v1x [float32!] + v1y [float32!] + v2x [float32!] + v2y [float32!] + v3x [float32!] + v3y [float32!] + v4x [float32!] + v4y [float32!] +] + +float32-max: as float32! 3.40282347E+38 +float32-min: as float32! -3.40282347E+38 + +image-crop: context [ + + on-plane?: func [ + vertex [CROP-VERTEX!] + x [float32!] + y [float32!] + return: [logic!] + ][ + if any [ + vector2d/ccw? x y vertex/v1x vertex/v1y vertex/v2x vertex/v2y + vector2d/ccw? x y vertex/v2x vertex/v2y vertex/v3x vertex/v3y + vector2d/ccw? x y vertex/v3x vertex/v3y vertex/v4x vertex/v4y + vector2d/ccw? x y vertex/v4x vertex/v4y vertex/v1x vertex/v1y + ][return false] + true + ] + + crop: func [ + src [byte-ptr!] + sw [integer!] ;-- width + sh [integer!] ;-- height + x [integer!] ;-- start.x + y [integer!] ;-- start.y + dst [byte-ptr!] + dw [integer!] ;-- width + dh [integer!] ;-- height + return: [logic!] + /local + ss [integer!] ;-- stride + ds [integer!] ;-- stride + offset [integer!] + from [byte-ptr!] + to [byte-ptr!] + ][ + ss: sw * 4 + ds: dw * 4 + if any [ + x < 0 + y < 0 + x >= sw + y >= sh + x + dw >= sw + y + dh >= sh + ][ + return false + ] + offset: y * ss + x * 4 + from: src + offset + to: dst + loop dh [ + copy-memory to from ds + to: to + ds + from: from + ss + ] + true + ] + + transform: func [ + src [int-ptr!] + sw [integer!] ;-- width + sh [integer!] ;-- height + vertex [CROP-VERTEX!] + dw [int-ptr!] ;-- width + dh [int-ptr!] ;-- height + return: [int-ptr!] + /local + xmin [float32!] + ymin [float32!] + xmax [float32!] + ymax [float32!] + p [pointer! [float32!]] + rect.x [integer!] + rect.y [integer!] + rect.w [integer!] + rect.h [integer!] + AB [VECTOR2D! value] + BC [VECTOR2D! value] + CD [VECTOR2D! value] + DA [VECTOR2D! value] + src.w [float!] + src.h [float!] + rgba [int-ptr!] + i [integer!] + j [integer!] + fi [float32!] + fj [float32!] + v [VECTOR2D! value] + dab [float!] + dbc [float!] + dcd [float!] + dda [float!] + fx [float!] + fy [float!] + ix [integer!] + iy [integer!] + ][ + if any [ + sw <= 0 + sh <= 0 + ][return null] + xmin: float32-max + ymin: float32-max + xmax: float32-min + ymax: float32-min + p: as pointer! [float32!] vertex + loop 4 [ + xmax: either xmax > p/1 [xmax][p/1] + ymax: either ymax > p/2 [ymax][p/2] + xmin: either xmin < p/1 [xmin][p/1] + ymin: either ymin < p/2 [ymin][p/2] + p: p + 2 + ] + rect.x: as integer! xmin + rect.y: as integer! ymin + rect.w: as integer! xmax - xmin + rect.h: as integer! ymax - ymin + + vector2d/from-points AB vertex/v1x vertex/v1y vertex/v2x vertex/v2y + vector2d/from-points BC vertex/v2x vertex/v2y vertex/v3x vertex/v3y + vector2d/from-points CD vertex/v3x vertex/v3y vertex/v4x vertex/v4y + vector2d/from-points DA vertex/v4x vertex/v4y vertex/v1x vertex/v1y + vector2d/unit AB + vector2d/unit BC + vector2d/unit CD + vector2d/unit DA + + src.w: as float! sw + src.h: as float! sh + + rgba: as int-ptr! allocate rect.w * rect.h * 4 + i: 0 j: 0 + loop rect.h [ + loop rect.w [ + fi: as float32! i + fj: as float32! j + if on-plane? vertex fj fi [ + vector2d/from-points v vertex/v1x vertex/v1y fj fi + dab: vector2d/cross-product v AB + if dab < 0.0 [dab: 0.0 - dab] + vector2d/from-points v vertex/v2x vertex/v2y fj fi + dbc: vector2d/cross-product v BC + if dbc < 0.0 [dbc: 0.0 - dbc] + vector2d/from-points v vertex/v3x vertex/v3y fj fi + dcd: vector2d/cross-product v CD + if dcd < 0.0 [dcd: 0.0 - dcd] + vector2d/from-points v vertex/v4x vertex/v4y fj fi + dda: vector2d/cross-product v DA + if dda < 0.0 [dda: 0.0 - dda] + fx: src.w * (dda / (dda + dbc)) + fy: src.h * (dab / (dab + dcd)) + ix: as integer! fx + iy: as integer! fy + if all [ + ix >= 0 + ix < sw + iy >= 0 + iy < sh + ][ + rgba/1: src/1 + ] + ] + j: j + 1 + ] + i: i + 1 + ] + dw/1: rect.w + dh/1: rect.h + rgba + ] + + resize: func [ + src [int-ptr!] + sw [integer!] ;-- width + sh [integer!] ;-- height + dw [integer!] ;-- width + dh [integer!] ;-- height + return: [int-ptr!] + /local + vertex [CROP-VERTEX! value] + w [integer!] + h [integer!] + p [int-ptr!] + ][ + vertex/v1x: as float32! 0.0 + vertex/v1y: as float32! 0.0 + vertex/v2x: as float32! dw + vertex/v2y: as float32! 0.0 + vertex/v3x: as float32! dw + vertex/v3y: as float32! dh + vertex/v4x: as float32! 0.0 + vertex/v4y: as float32! dh + w: 0 h: 0 + p: transform src sw sh :vertex :w :h + if null? p [return null] + if any [ + w <> dw + h <> dh + ][ + free as byte-ptr! p + return null + ] + p + ] +] diff --git a/runtime/vector2d.reds b/runtime/vector2d.reds new file mode 100644 index 0000000000..683d3b7d98 --- /dev/null +++ b/runtime/vector2d.reds @@ -0,0 +1,135 @@ +Red/System [ + Title: "2d vector" + Author: "bitbegin" + File: %vector2d.reds + Note: "2d vector lib for image" + Tabs: 4 + Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." + License: { + Distributed under the Boost Software License, Version 1.0. + See https://github.com/red/red/blob/master/BSL-License.txt + } +] + +VECTOR2D!: alias struct! [ + x [float!] + y [float!] +] + +vector2d: context [ + + magnitude: func [vect [VECTOR2D!] return: [float!]][ + sqrt vect/x * vect/x + (vect/y * vect/y) + ] + + unit: func [vect [VECTOR2D!] /local mag [float!]][ + mag: magnitude vect + vect/x: vect/x / mag + vect/y: vect/y / mag + ] + + from-point: func [ + vect [VECTOR2D!] + px [float32!] + py [float32!] + ][ + vect/x: as float! px + vect/y: as float! py + ] + + from-points: func [ + vect [VECTOR2D!] + p1x [float32!] + p1y [float32!] + p2x [float32!] + p2y [float32!] + ][ + vect/x: as float! p2x - p1x + vect/y: as float! p2y - p1y + ] + + ;-- A * B =|A|.|B|.sin(angle AOB) + cross-product: func [v1 [VECTOR2D!] v2 [VECTOR2D!] return: [float!]][ + v1/x * v2/y - (v1/y * v2/x) + ] + + ;-- A. B=|A|.|B|.cos(angle AOB) + dot-product: func [v1 [VECTOR2D!] v2 [VECTOR2D!] return: [float!]][ + v1/x * v2/x + (v1/y * v2/y) + ] + + clockwise?: func [ + p1x [float32!] + p1y [float32!] + p2x [float32!] + p2y [float32!] + p3x [float32!] + p3y [float32!] + return: [logic!] + /local + v21 [VECTOR2D! value] + v23 [VECTOR2D! value] + ][ + from-points v21 p2x p2y p1x p1y + from-points v23 p2x p2y p3x p3y + 0.0 > cross-product v21 v23 ;-- sin(angle pt1 pt2 pt3) > 0, 0 Date: Mon, 9 Mar 2020 11:47:22 +0800 Subject: [PATCH 1114/3432] FEAT: first support image! crop and transform for gtk3 --- modules/view/backends/gtk3/draw.reds | 188 ++++++++++------------- modules/view/backends/gtk3/handlers.reds | 8 +- runtime/image-crop.reds | 26 +++- runtime/platform/image-gdk.reds | 74 ++++++++- 4 files changed, 171 insertions(+), 125 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index a7102b9b80..a7539bc8e3 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1222,43 +1222,6 @@ OS-draw-line-cap: func [ ] ] -GDK-draw-image: func [ - cr [handle!] - image [handle!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - /local - img [handle!] - absw [integer!] - absh [integer!] -][ - if any [ - width = 0 - height = 0 - ][exit] - - absw: width - if width < 0 [absw: 0 - width] - absh: height - if height < 0 [absh: 0 - height] - img: gdk_pixbuf_scale_simple image absw absh 2 - - cairo_save cr - cairo_translate cr as-float x as-float y - if width < 0 [ - cairo_scale cr -1.0 1.0 - ] - if height < 0 [ - cairo_scale cr 1.0 -1.0 - ] - gdk_cairo_set_source_pixbuf cr img 0.0 0.0 - cairo_paint cr - cairo_restore cr - g_object_unref img -] - OS-draw-image: func [ dc [draw-ctx!] image [red-image!] @@ -1269,85 +1232,98 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local - cr [handle!] - img [int-ptr!] - bitmap [integer!] - stride [integer!] - x [integer!] - y [integer!] - width [integer!] - height [integer!] - w [float!] - h [float!] - crop_x [float!] - crop_y [float!] - crop2 [red-pair!] - crop_cr [handle!] - crop_surf [handle!] - crop_xscale [float!] - crop_yscale [float!] - format [cairo_format_t!] - img_w [float!] - img_h [float!] - crop_img_sx [integer!] - crop_img_sy [integer!] -][ - ;; DEBUG: print ["OS-draw-image" lf] - img_w: as float! IMAGE_WIDTH(image/size) - img_h: as float! IMAGE_HEIGHT(image/size) - either null? start [x: 0 y: 0][x: start/x y: start/y] + w [integer!] + h [integer!] + vertex [CROP-VERTEX! value] + end2 [red-pair!] + vec1 [VECTOR2D! value] + vec2 [VECTOR2D! value] + vec3 [VECTOR2D! value] + rect.x [integer!] + rect.y [integer!] + rect.w [integer!] + rect.h [integer!] + crop2 [red-pair!] + pixbuf [handle!] + cr [handle!] +][ + w: IMAGE_WIDTH(image/size) + h: IMAGE_HEIGHT(image/size) + + either null? start [ + vertex/v1x: as float32! 0.0 + vertex/v1y: as float32! 0.0 + ][ + vertex/v1x: as float32! start/x + vertex/v1y: as float32! start/y + ] case [ start = end [ - width: as integer! img_w - height: as integer! img_h + vertex/v2x: vertex/v1x + as float32! w + vertex/v2y: vertex/v1y + vertex/v3x: vertex/v1x + as float32! w + vertex/v3y: vertex/v1y + as float32! h + vertex/v4x: vertex/v1x + vertex/v4y: vertex/v1y + as float32! h ] start + 1 = end [ ;-- two control points - width: end/x - x - height: end/y - y + vertex/v2x: as float32! end/x + vertex/v2y: vertex/v1y + vertex/v3x: as float32! end/x + vertex/v3y: as float32! end/y + vertex/v4x: vertex/v1x + vertex/v4y: as float32! end/y + ] + start + 2 = end [ ;-- three control points + end2: end + 1 + vertex/v2x: as float32! end/x + vertex/v2y: as float32! end/y + vertex/v4x: as float32! end2/x + vertex/v4y: as float32! end2/y + vector2d/from-points vec1 vertex/v1x vertex/v1y vertex/v2x vertex/v2y + vector2d/from-points vec2 vertex/v1x vertex/v1y vertex/v4x vertex/v4y + vec3/x: vec1/x + vec2/x + vec3/y: vec1/y + vec2/y + vertex/v3x: as float32! vec3/x + vertex/v1x + vertex/v3y: as float32! vec3/y + vertex/v1y + ] + true [ ;-- four control points + vertex/v2x: as float32! end/x + vertex/v2y: as float32! end/y + end: end + 1 + vertex/v3x: as float32! end/x + vertex/v3y: as float32! end/y + end: end + 1 + vertex/v4x: as float32! end/x + vertex/v4y: as float32! end/y ] - start + 2 = end [0] ;@@ TBD three control points - true [0] ;@@ TBD four control points ] - cr: dc/cr - ;; DEBUG: print ["OS-draw-image: " x "x" y " " width "x" height lf "image: " image lf "original: " IMAGE_WIDTH(image/size) "x" IMAGE_HEIGHT(image/size) lf] - img: OS-image/to-pixbuf image - - either crop1 <> null [ - ;; DEBUG: print ["crop1: " crop1/x "x" crop1/y lf] - crop_x: as float! crop1/x - crop_y: as float! crop1/y + rect.x: 0 + rect.y: 0 + rect.w: 0 + rect.h: 0 + either crop1 = null [ + pixbuf: OS-image/any-resize image no 0 0 0 0 vertex :rect.x :rect.y :rect.w :rect.h + ][ crop2: crop1 + 1 - w: as float! crop2/x - h: as float! crop2/y - crop_xscale: w / (as float! width) - crop_yscale: h / (as float! height) - crop_img_sx: as integer! (img_w / crop_xscale) - crop_img_sy: as integer! (img_h / crop_yscale) - ;width: as-integer (w / h * (as float! height)) - ;; DEBUG: print ["cropping dest: " crop_x "x" crop_y "x" w "x" h " img size: " crop_img_sx "x" crop_img_sy lf] - img: gdk_pixbuf_scale_simple img crop_img_sx crop_img_sy 2 - format: CAIRO_FORMAT_RGB24 ;either 3 = gdk_pixbuf_get_n_channels img [CAIRO_FORMAT_RGB24][CAIRO_FORMAT_ARGB32] - ;; DEBÙG: print ["pixbuf format: " format lf] - crop_surf: cairo_image_surface_create format crop_img_sx crop_img_sy - crop_cr: cairo_create crop_surf - gdk_cairo_set_source_pixbuf crop_cr img 0.0 0.0 - cairo_paint crop_cr - cairo_destroy crop_cr - - cairo_save cr - cairo_translate cr as-float x as-float y - cairo_set_source_surface cr crop_surf (0.0 - (crop_x / crop_xscale)) (0.0 - (crop_y / crop_yscale)) - cairo_rectangle cr 0.0 0.0 as float! width as float! height - cairo_fill cr - cairo_translate cr as-float (0 - x) as-float (0 - y) - cairo_restore cr + pixbuf: OS-image/any-resize image yes crop1/x crop1/y crop2/x crop2/y vertex :rect.x :rect.y :rect.w :rect.h + ] - cairo_surface_destroy crop_surf - g_object_unref img - ][ - GDK-draw-image cr img x y width height + cr: dc/cr + cairo_save cr + cairo_translate cr as-float rect.x as-float rect.y + if rect.w < 0 [ + cairo_scale cr -1.0 1.0 ] + if rect.h < 0 [ + cairo_scale cr 1.0 -1.0 + ] + gdk_cairo_set_source_pixbuf cr pixbuf 0.0 0.0 + cairo_paint cr + cairo_restore cr + + g_object_unref pixbuf ] OS-draw-grad-pen-old: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 37cd3cbc51..d0a2e1056a 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -221,10 +221,10 @@ base-draw: func [ ] if TYPE_OF(img) = TYPE_IMAGE [ - ;; DEBUG: print ["base-draw, GDK-draw-image: " 0 "x" 0 "x" size/x "x" size/y lf] - ;; ONLY WORK for Mandelbrot and raytracer: - ;; GDK-draw-image cr OS-image/to-argb-pixbuf img 0 0 size/x size/y - GDK-draw-image cr OS-image/to-pixbuf img 0 0 size/x size/y + cairo_save cr + gdk_cairo_set_source_pixbuf cr OS-image/to-pixbuf img 0.0 0.0 + cairo_paint cr + cairo_restore cr ] case [ diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index 73727c4d4d..f23015496c 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -50,9 +50,9 @@ image-crop: context [ sh [integer!] ;-- height x [integer!] ;-- start.x y [integer!] ;-- start.y - dst [byte-ptr!] dw [integer!] ;-- width dh [integer!] ;-- height + dst [byte-ptr!] return: [logic!] /local ss [integer!] ;-- stride @@ -89,6 +89,8 @@ image-crop: context [ sw [integer!] ;-- width sh [integer!] ;-- height vertex [CROP-VERTEX!] + dx [int-ptr!] + dy [int-ptr!] dw [int-ptr!] ;-- width dh [int-ptr!] ;-- height return: [int-ptr!] @@ -102,6 +104,7 @@ image-crop: context [ rect.y [integer!] rect.w [integer!] rect.h [integer!] + size [integer!] AB [VECTOR2D! value] BC [VECTOR2D! value] CD [VECTOR2D! value] @@ -144,6 +147,11 @@ image-crop: context [ rect.w: as integer! xmax - xmin rect.h: as integer! ymax - ymin + dx/1: rect.x + dy/1: rect.y + dw/1: rect.w + dh/1: rect.h + vector2d/from-points AB vertex/v1x vertex/v1y vertex/v2x vertex/v2y vector2d/from-points BC vertex/v2x vertex/v2y vertex/v3x vertex/v3y vector2d/from-points CD vertex/v3x vertex/v3y vertex/v4x vertex/v4y @@ -155,8 +163,11 @@ image-crop: context [ src.w: as float! sw src.h: as float! sh - - rgba: as int-ptr! allocate rect.w * rect.h * 4 + if rect.w < 0 [rect.w: 0 - rect.w] + if rect.h < 0 [rect.h: 0 - rect.h] + size: rect.w * rect.h * 4 + rgba: as int-ptr! allocate size + set-memory as byte-ptr! rgba null-byte size i: 0 j: 0 loop rect.h [ loop rect.w [ @@ -192,8 +203,7 @@ image-crop: context [ ] i: i + 1 ] - dw/1: rect.w - dh/1: rect.h + rgba ] @@ -208,6 +218,8 @@ image-crop: context [ vertex [CROP-VERTEX! value] w [integer!] h [integer!] + x [integer!] + y [integer!] p [int-ptr!] ][ vertex/v1x: as float32! 0.0 @@ -218,8 +230,8 @@ image-crop: context [ vertex/v3y: as float32! dh vertex/v4x: as float32! 0.0 vertex/v4y: as float32! dh - w: 0 h: 0 - p: transform src sw sh :vertex :w :h + w: 0 h: 0 x: 0 y: 0 + p: transform src sw sh :vertex :x :y :w :h if null? p [return null] if any [ w <> dw diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 137a030702..48ce13c1f6 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -23,6 +23,8 @@ GError!: alias struct! [ message [c-string!] ] +#include %../image-crop.reds + OS-image: context [ img-node!: alias struct! [ @@ -236,26 +238,82 @@ OS-image: context [ if inode/buffer <> null [free as byte-ptr! inode/buffer inode/buffer: null] ] - ; copied from quartz but do not think it is finished resize: func [ img [red-image!] width [integer!] height [integer!] return: [integer!] /local - graphic [integer!] old-w [integer!] old-h [integer!] - format [integer!] bitmap [integer!] + stride [integer!] + src [int-ptr!] + dst [int-ptr!] ][ old-w: IMAGE_WIDTH(img/size) old-h: IMAGE_HEIGHT(img/size) - graphic: 0 - format: 0 - bitmap: 0 - as-integer img/node + bitmap: lock-bitmap img no + stride: 0 + src: get-data bitmap :stride + dst: image-crop/resize src old-w old-h width height + unlock-bitmap img bitmap + as integer! make-node null dst IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height + ] + + any-resize: func [ + img [red-image!] + crop? [logic!] + crop.x [integer!] + crop.y [integer!] + crop.w [integer!] + crop.h [integer!] + vertex [CROP-VERTEX!] + x [int-ptr!] + y [int-ptr!] + w [int-ptr!] + h [int-ptr!] + return: [handle!] + /local + old-w [integer!] + old-h [integer!] + bitmap [integer!] + src [int-ptr!] + src2 [byte-ptr!] + stride [integer!] + dst [int-ptr!] + pixbuf [handle!] + buf [byte-ptr!] + w2 [integer!] + h2 [integer!] + ][ + old-w: IMAGE_WIDTH(img/size) + old-h: IMAGE_HEIGHT(img/size) + + bitmap: lock-bitmap img no + stride: 0 + src: get-data bitmap :stride + either crop? [ + src2: allocate crop.w * crop.h * 4 + image-crop/crop as byte-ptr! src old-w old-h crop.x crop.y crop.w crop.h src2 + dst: image-crop/transform as int-ptr! src2 crop.w crop.h vertex x y w h + free src2 + ][ + dst: image-crop/transform src old-w old-h vertex x y w h + ] + unlock-bitmap img bitmap + if null? dst [return null] + + w2: w/1 + if w2 < 0 [w2: 0 - w2] + h2: h/1 + if h2 < 0 [h2: 0 - h2] + pixbuf: gdk_pixbuf_new 0 yes 8 w2 h2 + buf: gdk_pixbuf_get_pixels pixbuf + revert dst as int-ptr! buf w2 * h2 yes + free as byte-ptr! dst + pixbuf ] make-node: func [ @@ -454,7 +512,7 @@ OS-image: context [ pixbuf: make-pixbuf img unless null? inode/handle [g_object_unref inode/handle] inode/handle: pixbuf - inode/flags: IMG_NODE_MODIFIED + inode/flags: IMG_NODE_HAS_BUFFER ] inode/handle ] From c317bac13a2a5a111a1d70b96fd3cd0353473858 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 9 Mar 2020 16:58:26 +0800 Subject: [PATCH 1115/3432] FIX: some image transform issues --- runtime/image-crop.reds | 25 +++++++++++++++---------- runtime/platform/image-gdk.reds | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index f23015496c..5a34a6b3a9 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -125,6 +125,8 @@ image-crop: context [ fy [float!] ix [integer!] iy [integer!] + si [integer!] + di [integer!] ][ if any [ sw <= 0 @@ -170,20 +172,21 @@ image-crop: context [ set-memory as byte-ptr! rgba null-byte size i: 0 j: 0 loop rect.h [ + i: 0 loop rect.w [ - fi: as float32! i - fj: as float32! j - if on-plane? vertex fj fi [ - vector2d/from-points v vertex/v1x vertex/v1y fj fi + fi: as float32! i + rect.x + fj: as float32! j + rect.y + if on-plane? vertex fi fj [ + vector2d/from-points v vertex/v1x vertex/v1y fi fj dab: vector2d/cross-product v AB if dab < 0.0 [dab: 0.0 - dab] - vector2d/from-points v vertex/v2x vertex/v2y fj fi + vector2d/from-points v vertex/v2x vertex/v2y fi fj dbc: vector2d/cross-product v BC if dbc < 0.0 [dbc: 0.0 - dbc] - vector2d/from-points v vertex/v3x vertex/v3y fj fi + vector2d/from-points v vertex/v3x vertex/v3y fi fj dcd: vector2d/cross-product v CD if dcd < 0.0 [dcd: 0.0 - dcd] - vector2d/from-points v vertex/v4x vertex/v4y fj fi + vector2d/from-points v vertex/v4x vertex/v4y fi fj dda: vector2d/cross-product v DA if dda < 0.0 [dda: 0.0 - dda] fx: src.w * (dda / (dda + dbc)) @@ -196,12 +199,14 @@ image-crop: context [ iy >= 0 iy < sh ][ - rgba/1: src/1 + di: j * rect.w + i + 1 + si: iy * src.w + ix + 1 + rgba/di: src/si ] ] - j: j + 1 + i: i + 1 ] - i: i + 1 + j: j + 1 ] rgba diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 48ce13c1f6..e39371ae82 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -360,7 +360,7 @@ OS-image: context [ ][ p/4: #"^(FF)" ] - dst/1: old + dst/offset: old offset: offset + 1 ] ] From e330bfa48452db0beafca431c4a6494dc96a5081 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 10 Mar 2020 11:24:17 +0800 Subject: [PATCH 1116/3432] FEAT: linear transform for image! --- runtime/image-crop.reds | 116 ++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 15 deletions(-) diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index 5a34a6b3a9..e4e1e821ee 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -121,12 +121,29 @@ image-crop: context [ dbc [float!] dcd [float!] dda [float!] - fx [float!] - fy [float!] - ix [integer!] - iy [integer!] + fx [float32!] + fy [float32!] + x1 [integer!] + y1 [integer!] si [integer!] di [integer!] + x2 [integer!] + y2 [integer!] + dx1 [float32!] + dx2 [float32!] + dy1 [float32!] + dy2 [float32!] + dx1y1 [float32!] + dx1y2 [float32!] + dx2y1 [float32!] + dx2y2 [float32!] + ps [byte-ptr!] + pd [byte-ptr!] + ti [integer!] + c1 [float32!] + c2 [float32!] + c3 [float32!] + c4 [float32!] ][ if any [ sw <= 0 @@ -189,19 +206,88 @@ image-crop: context [ vector2d/from-points v vertex/v4x vertex/v4y fi fj dda: vector2d/cross-product v DA if dda < 0.0 [dda: 0.0 - dda] - fx: src.w * (dda / (dda + dbc)) - fy: src.h * (dab / (dab + dcd)) - ix: as integer! fx - iy: as integer! fy + fx: as float32! src.w * (dda / (dda + dbc)) + fy: as float32! src.h * (dab / (dab + dcd)) + x1: as integer! fx + y1: as integer! fy if all [ - ix >= 0 - ix < sw - iy >= 0 - iy < sh + x1 >= 0 + x1 < sw + y1 >= 0 + y1 < sh ][ - di: j * rect.w + i + 1 - si: iy * src.w + ix + 1 - rgba/di: src/si + either true [ + x2: either x1 = (sw - 1) [x1][x1 + 1] + y2: either y1 = (sh - 1) [y1][y1 + 1] + dx1: fx - as float32! x1 + if dx1 < as float32! 0.0 [dx1: as float32! 0.0] + dx2: dx1 + dx1: (as float32! 1.0) - dx1 + dy1: fy - as float32! y1 + if dy1 < as float32! 0.0 [dy1: as float32! 0.0] + dy2: dy1 + dy1: (as float32! 1.0) - dy1 + dx1y1: dx1 * dy1 + dx1y2: dx1 * dy2 + dx2y1: dx2 * dy1 + dx2y2: dx2 * dy2 + di: j * rect.w + i + pd: as byte-ptr! (rgba + di) + + si: y1 * sw + x1 + ps: as byte-ptr! (src + si) + ti: as integer! ps/1 + c1: dx1y1 * as float32! ti + ti: as integer! ps/2 + c2: dx1y1 * as float32! ti + ti: as integer! ps/3 + c3: dx1y1 * as float32! ti + ti: as integer! ps/4 + c4: dx1y1 * as float32! ti + si: y1 * sw + x2 + ps: as byte-ptr! (src + si) + ti: as integer! ps/1 + c1: c1 + (dx2y1 * as float32! ti) + ti: as integer! ps/2 + c2: c2 + (dx2y1 * as float32! ti) + ti: as integer! ps/3 + c3: c3 + (dx2y1 * as float32! ti) + ti: as integer! ps/4 + c4: c4 + (dx2y1 * as float32! ti) + si: y2 * sw + x1 + ps: as byte-ptr! (src + si) + ti: as integer! ps/1 + c1: c1 + (dx1y2 * as float32! ti) + ti: as integer! ps/2 + c2: c2 + (dx1y2 * as float32! ti) + ti: as integer! ps/3 + c3: c3 + (dx1y2 * as float32! ti) + ti: as integer! ps/4 + c4: c4 + (dx1y2 * as float32! ti) + si: y2 * sw + x2 + ps: as byte-ptr! (src + si) + ti: as integer! ps/1 + c1: c1 + (dx2y2 * as float32! ti) + ti: as integer! ps/2 + c2: c2 + (dx2y2 * as float32! ti) + ti: as integer! ps/3 + c3: c3 + (dx2y2 * as float32! ti) + ti: as integer! ps/4 + c4: c4 + (dx2y2 * as float32! ti) + ti: as integer! c1 + pd/1: as byte! ti + ti: as integer! c2 + pd/2: as byte! ti + ti: as integer! c3 + pd/3: as byte! ti + ti: as integer! c4 + pd/4: as byte! ti + ][ + ;-- simple transform + di: j * rect.w + i + 1 + si: y1 * sw + x1 + 1 + rgba/di: src/si + ] ] ] i: i + 1 From 1c104d4199c11fdc25a09201889c184d49761c5c Mon Sep 17 00:00:00 2001 From: bitbegin Date: Tue, 10 Mar 2020 17:45:54 +0800 Subject: [PATCH 1117/3432] FIX: some edge case issues --- modules/view/backends/gtk3/draw.reds | 63 +++++++++++++++++------- modules/view/backends/gtk3/handlers.reds | 5 +- runtime/image-crop.reds | 12 +++-- runtime/platform/image-gdk.reds | 53 +++++++++++++++----- 4 files changed, 97 insertions(+), 36 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index a7539bc8e3..7a6e5f44e9 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1234,6 +1234,8 @@ OS-draw-image: func [ /local w [integer!] h [integer!] + w1 [integer!] + h1 [integer!] vertex [CROP-VERTEX! value] end2 [red-pair!] vec1 [VECTOR2D! value] @@ -1243,6 +1245,10 @@ OS-draw-image: func [ rect.y [integer!] rect.w [integer!] rect.h [integer!] + crop.x [integer!] + crop.y [integer!] + crop.w [integer!] + crop.h [integer!] crop2 [red-pair!] pixbuf [handle!] cr [handle!] @@ -1257,14 +1263,32 @@ OS-draw-image: func [ vertex/v1x: as float32! start/x vertex/v1y: as float32! start/y ] + unless null? crop1 [ + crop2: crop1 + 1 + crop.x: crop1/x + crop.y: crop1/y + crop.w: crop2/x + crop.h: crop2/y + if crop.x + crop.w > w [ + crop.w: w - crop.x + ] + if crop.y + crop.h > h [ + crop.h: h - crop.y + ] + ] case [ start = end [ - vertex/v2x: vertex/v1x + as float32! w + either null? crop1 [ + w1: w h1: h + ][ + w1: crop.w h1: crop.h + ] + vertex/v2x: vertex/v1x + as float32! w1 vertex/v2y: vertex/v1y - vertex/v3x: vertex/v1x + as float32! w - vertex/v3y: vertex/v1y + as float32! h + vertex/v3x: vertex/v1x + as float32! w1 + vertex/v3y: vertex/v1y + as float32! h1 vertex/v4x: vertex/v1x - vertex/v4y: vertex/v1y + as float32! h + vertex/v4y: vertex/v1y + as float32! h1 ] start + 1 = end [ ;-- two control points vertex/v2x: as float32! end/x @@ -1306,24 +1330,25 @@ OS-draw-image: func [ either crop1 = null [ pixbuf: OS-image/any-resize image no 0 0 0 0 vertex :rect.x :rect.y :rect.w :rect.h ][ - crop2: crop1 + 1 - pixbuf: OS-image/any-resize image yes crop1/x crop1/y crop2/x crop2/y vertex :rect.x :rect.y :rect.w :rect.h + pixbuf: OS-image/any-resize image yes crop.x crop.y crop.w crop.h vertex :rect.x :rect.y :rect.w :rect.h ] - cr: dc/cr - cairo_save cr - cairo_translate cr as-float rect.x as-float rect.y - if rect.w < 0 [ - cairo_scale cr -1.0 1.0 - ] - if rect.h < 0 [ - cairo_scale cr 1.0 -1.0 - ] - gdk_cairo_set_source_pixbuf cr pixbuf 0.0 0.0 - cairo_paint cr - cairo_restore cr + unless null? pixbuf [ + cr: dc/cr + cairo_save cr + cairo_translate cr as-float rect.x as-float rect.y + if rect.w < 0 [ + cairo_scale cr -1.0 1.0 + ] + if rect.h < 0 [ + cairo_scale cr 1.0 -1.0 + ] + gdk_cairo_set_source_pixbuf cr pixbuf 0.0 0.0 + cairo_paint cr + cairo_restore cr - g_object_unref pixbuf + g_object_unref pixbuf + ] ] OS-draw-grad-pen-old: func [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index d0a2e1056a..5085fd6c6e 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -188,6 +188,7 @@ base-draw: func [ DC [draw-ctx! value] drawDC [draw-ctx!] css [GString!] + h [handle!] ][ face: get-face-obj widget values: object/get-values face @@ -221,10 +222,12 @@ base-draw: func [ ] if TYPE_OF(img) = TYPE_IMAGE [ + h: OS-image/resize-to-handle img size/x size/y cairo_save cr - gdk_cairo_set_source_pixbuf cr OS-image/to-pixbuf img 0.0 0.0 + gdk_cairo_set_source_pixbuf cr h 0.0 0.0 cairo_paint cr cairo_restore cr + g_object_unref h ] case [ diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index e4e1e821ee..3364ad049d 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -68,12 +68,16 @@ image-crop: context [ y < 0 x >= sw y >= sh - x + dw >= sw - y + dh >= sh ][ return false ] - offset: y * ss + x * 4 + if x + dw > sw [ + ds: sw - x * 4 + ] + if y + dh > sh [ + dh: sh - y + ] + offset: y * ss + (x * 4) from: src + offset to: dst loop dh [ @@ -182,8 +186,6 @@ image-crop: context [ src.w: as float! sw src.h: as float! sh - if rect.w < 0 [rect.w: 0 - rect.w] - if rect.h < 0 [rect.h: 0 - rect.h] size: rect.w * rect.h * 4 rgba: as int-ptr! allocate size set-memory as byte-ptr! rgba null-byte size diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index e39371ae82..ccb8dd5aab 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -238,11 +238,11 @@ OS-image: context [ if inode/buffer <> null [free as byte-ptr! inode/buffer inode/buffer: null] ] - resize: func [ + resize-to-buff: func [ img [red-image!] width [integer!] height [integer!] - return: [integer!] + return: [int-ptr!] /local old-w [integer!] old-h [integer!] @@ -259,6 +259,36 @@ OS-image: context [ src: get-data bitmap :stride dst: image-crop/resize src old-w old-h width height unlock-bitmap img bitmap + dst + ] + + resize-to-handle: func [ + img [red-image!] + width [integer!] + height [integer!] + return: [handle!] + /local + dst [int-ptr!] + pixbuf [handle!] + buf [byte-ptr!] + ][ + dst: resize-to-buff img width height + pixbuf: gdk_pixbuf_new 0 yes 8 width height + buf: gdk_pixbuf_get_pixels pixbuf + revert dst as int-ptr! buf width * height yes + free as byte-ptr! dst + pixbuf + ] + + resize: func [ + img [red-image!] + width [integer!] + height [integer!] + return: [integer!] + /local + dst [int-ptr!] + ][ + dst: resize-to-buff img width height as integer! make-node null dst IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height ] @@ -285,8 +315,6 @@ OS-image: context [ dst [int-ptr!] pixbuf [handle!] buf [byte-ptr!] - w2 [integer!] - h2 [integer!] ][ old-w: IMAGE_WIDTH(img/size) old-h: IMAGE_HEIGHT(img/size) @@ -304,14 +332,17 @@ OS-image: context [ ] unlock-bitmap img bitmap if null? dst [return null] - - w2: w/1 - if w2 < 0 [w2: 0 - w2] - h2: h/1 - if h2 < 0 [h2: 0 - h2] - pixbuf: gdk_pixbuf_new 0 yes 8 w2 h2 + if any [ + w/1 = 0 + h/1 = 0 + ][ + free as byte-ptr! dst + return null + ] + + pixbuf: gdk_pixbuf_new 0 yes 8 w/1 h/1 buf: gdk_pixbuf_get_pixels pixbuf - revert dst as int-ptr! buf w2 * h2 yes + revert dst as int-ptr! buf w/1 * h/1 yes free as byte-ptr! dst pixbuf ] From 1fcbddb1fabdc5feafd47da28b2b0613f834b2ad Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 11 Mar 2020 16:05:48 +0800 Subject: [PATCH 1118/3432] FIX: missing files in includes.r --- build/includes.r | 2 ++ modules/view/backends/gtk3/draw.reds | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/includes.r b/build/includes.r index 4b0da107a4..df1a093ac1 100644 --- a/build/includes.r +++ b/build/includes.r @@ -101,6 +101,8 @@ write %build/bin/sources.r set-cache [ %tools.reds %unicode.reds %utils.reds + %image-crop.reds + %vector2d.reds %datatypes/ [ %action.reds %block.reds diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 7a6e5f44e9..9c19bee8e6 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1327,11 +1327,9 @@ OS-draw-image: func [ rect.y: 0 rect.w: 0 rect.h: 0 - either crop1 = null [ - pixbuf: OS-image/any-resize image no 0 0 0 0 vertex :rect.x :rect.y :rect.w :rect.h - ][ - pixbuf: OS-image/any-resize image yes crop.x crop.y crop.w crop.h vertex :rect.x :rect.y :rect.w :rect.h - ] + pixbuf: OS-image/any-resize image + crop1 <> null crop.x crop.y crop.w crop.h + vertex :rect.x :rect.y :rect.w :rect.h unless null? pixbuf [ cr: dc/cr From d205cf4318a3cd20f7072928f7d62b08493010b7 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Wed, 11 Mar 2020 17:19:22 +0800 Subject: [PATCH 1119/3432] FIX: 3/4 control points work --- modules/view/backends/gtk3/draw.reds | 30 +++++++++++++++------------- runtime/image-crop.reds | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 9c19bee8e6..ed88caf4df 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1237,7 +1237,7 @@ OS-draw-image: func [ w1 [integer!] h1 [integer!] vertex [CROP-VERTEX! value] - end2 [red-pair!] + pos [red-pair!] vec1 [VECTOR2D! value] vec2 [VECTOR2D! value] vec3 [VECTOR2D! value] @@ -1299,11 +1299,12 @@ OS-draw-image: func [ vertex/v4y: as float32! end/y ] start + 2 = end [ ;-- three control points - end2: end + 1 - vertex/v2x: as float32! end/x - vertex/v2y: as float32! end/y - vertex/v4x: as float32! end2/x - vertex/v4y: as float32! end2/y + pos: start + 1 + vertex/v2x: as float32! pos/x + vertex/v2y: as float32! pos/y + pos: pos + 1 + vertex/v4x: as float32! pos/x + vertex/v4y: as float32! pos/y vector2d/from-points vec1 vertex/v1x vertex/v1y vertex/v2x vertex/v2y vector2d/from-points vec2 vertex/v1x vertex/v1y vertex/v4x vertex/v4y vec3/x: vec1/x + vec2/x @@ -1312,14 +1313,15 @@ OS-draw-image: func [ vertex/v3y: as float32! vec3/y + vertex/v1y ] true [ ;-- four control points - vertex/v2x: as float32! end/x - vertex/v2y: as float32! end/y - end: end + 1 - vertex/v3x: as float32! end/x - vertex/v3y: as float32! end/y - end: end + 1 - vertex/v4x: as float32! end/x - vertex/v4y: as float32! end/y + pos: start + 1 + vertex/v2x: as float32! pos/x + vertex/v2y: as float32! pos/y + pos: pos + 1 + vertex/v4x: as float32! pos/x + vertex/v4y: as float32! pos/y + pos: pos + 1 + vertex/v3x: as float32! pos/x + vertex/v3y: as float32! pos/y ] ] diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index 3364ad049d..7c3668ab7b 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -188,7 +188,7 @@ image-crop: context [ src.h: as float! sh size: rect.w * rect.h * 4 rgba: as int-ptr! allocate size - set-memory as byte-ptr! rgba null-byte size + set-memory as byte-ptr! rgba #"^(FF)" size i: 0 j: 0 loop rect.h [ i: 0 From 78e7b08b5f4eed93f0b740c683c11f6d5d955485 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Mar 2020 10:14:27 +0800 Subject: [PATCH 1120/3432] FIX: reserve GDK-draw-image --- modules/view/backends/gtk3/draw.reds | 37 ++++++++++++++++++++++++ modules/view/backends/gtk3/handlers.reds | 8 +---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index ed88caf4df..61803d3182 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1222,6 +1222,43 @@ OS-draw-line-cap: func [ ] ] +GDK-draw-image: func [ + cr [handle!] + image [handle!] + x [integer!] + y [integer!] + width [integer!] + height [integer!] + /local + img [handle!] + absw [integer!] + absh [integer!] +][ + if any [ + width = 0 + height = 0 + ][exit] + + absw: width + if width < 0 [absw: 0 - width] + absh: height + if height < 0 [absh: 0 - height] + img: gdk_pixbuf_scale_simple image absw absh 2 + + cairo_save cr + cairo_translate cr as-float x as-float y + if width < 0 [ + cairo_scale cr -1.0 1.0 + ] + if height < 0 [ + cairo_scale cr 1.0 -1.0 + ] + gdk_cairo_set_source_pixbuf cr img 0.0 0.0 + cairo_paint cr + cairo_restore cr + g_object_unref img +] + OS-draw-image: func [ dc [draw-ctx!] image [red-image!] diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 5085fd6c6e..769d5cd3c5 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -188,7 +188,6 @@ base-draw: func [ DC [draw-ctx! value] drawDC [draw-ctx!] css [GString!] - h [handle!] ][ face: get-face-obj widget values: object/get-values face @@ -222,12 +221,7 @@ base-draw: func [ ] if TYPE_OF(img) = TYPE_IMAGE [ - h: OS-image/resize-to-handle img size/x size/y - cairo_save cr - gdk_cairo_set_source_pixbuf cr h 0.0 0.0 - cairo_paint cr - cairo_restore cr - g_object_unref h + GDK-draw-image cr OS-image/to-pixbuf img 0 0 size/x size/y ] case [ From ac08d875dcebdd93147574aed557bd8a989061ae Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Mar 2020 15:23:40 +0800 Subject: [PATCH 1121/3432] FIX: move any-resize to image (not depend on platform) --- modules/view/backends/gtk3/draw.reds | 102 ++------------------- runtime/datatypes/image.reds | 127 +++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 95 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 61803d3182..6acd32943f 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1261,7 +1261,7 @@ GDK-draw-image: func [ OS-draw-image: func [ dc [draw-ctx!] - image [red-image!] + src [red-image!] start [red-pair!] end [red-pair!] key-color [red-tuple!] @@ -1269,106 +1269,18 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local - w [integer!] - h [integer!] - w1 [integer!] - h1 [integer!] - vertex [CROP-VERTEX! value] - pos [red-pair!] - vec1 [VECTOR2D! value] - vec2 [VECTOR2D! value] - vec3 [VECTOR2D! value] + dst [red-image! value] rect.x [integer!] rect.y [integer!] rect.w [integer!] rect.h [integer!] - crop.x [integer!] - crop.y [integer!] - crop.w [integer!] - crop.h [integer!] - crop2 [red-pair!] pixbuf [handle!] cr [handle!] ][ - w: IMAGE_WIDTH(image/size) - h: IMAGE_HEIGHT(image/size) - - either null? start [ - vertex/v1x: as float32! 0.0 - vertex/v1y: as float32! 0.0 - ][ - vertex/v1x: as float32! start/x - vertex/v1y: as float32! start/y - ] - unless null? crop1 [ - crop2: crop1 + 1 - crop.x: crop1/x - crop.y: crop1/y - crop.w: crop2/x - crop.h: crop2/y - if crop.x + crop.w > w [ - crop.w: w - crop.x - ] - if crop.y + crop.h > h [ - crop.h: h - crop.y - ] - ] - case [ - start = end [ - either null? crop1 [ - w1: w h1: h - ][ - w1: crop.w h1: crop.h - ] - vertex/v2x: vertex/v1x + as float32! w1 - vertex/v2y: vertex/v1y - vertex/v3x: vertex/v1x + as float32! w1 - vertex/v3y: vertex/v1y + as float32! h1 - vertex/v4x: vertex/v1x - vertex/v4y: vertex/v1y + as float32! h1 - ] - start + 1 = end [ ;-- two control points - vertex/v2x: as float32! end/x - vertex/v2y: vertex/v1y - vertex/v3x: as float32! end/x - vertex/v3y: as float32! end/y - vertex/v4x: vertex/v1x - vertex/v4y: as float32! end/y - ] - start + 2 = end [ ;-- three control points - pos: start + 1 - vertex/v2x: as float32! pos/x - vertex/v2y: as float32! pos/y - pos: pos + 1 - vertex/v4x: as float32! pos/x - vertex/v4y: as float32! pos/y - vector2d/from-points vec1 vertex/v1x vertex/v1y vertex/v2x vertex/v2y - vector2d/from-points vec2 vertex/v1x vertex/v1y vertex/v4x vertex/v4y - vec3/x: vec1/x + vec2/x - vec3/y: vec1/y + vec2/y - vertex/v3x: as float32! vec3/x + vertex/v1x - vertex/v3y: as float32! vec3/y + vertex/v1y - ] - true [ ;-- four control points - pos: start + 1 - vertex/v2x: as float32! pos/x - vertex/v2y: as float32! pos/y - pos: pos + 1 - vertex/v4x: as float32! pos/x - vertex/v4y: as float32! pos/y - pos: pos + 1 - vertex/v3x: as float32! pos/x - vertex/v3y: as float32! pos/y - ] - ] - - rect.x: 0 - rect.y: 0 - rect.w: 0 - rect.h: 0 - pixbuf: OS-image/any-resize image - crop1 <> null crop.x crop.y crop.w crop.h - vertex :rect.x :rect.y :rect.w :rect.h + rect.x: 0 rect.y: 0 rect.w: 0 rect.h: 0 + image/any-resize src dst crop1 start end :rect.x :rect.y :rect.w :rect.h + if dst/header = TYPE_NONE [exit] + pixbuf: OS-image/to-pixbuf dst unless null? pixbuf [ cr: dc/cr @@ -1384,7 +1296,7 @@ OS-draw-image: func [ cairo_paint cr cairo_restore cr - g_object_unref pixbuf + OS-image/delete dst ] ] diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 2008eca972..029c41616c 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -109,6 +109,133 @@ image: context [ init-image as red-image! stack/push* as node! OS-image/resize img width height ] + any-resize: func [ + src [red-image!] + dst [red-image!] + crop1 [red-pair!] + start [red-pair!] ;-- first point + end [red-pair!] ;-- end point + rect.x [int-ptr!] + rect.y [int-ptr!] + rect.w [int-ptr!] + rect.h [int-ptr!] + /local + w [integer!] + h [integer!] + w1 [integer!] + h1 [integer!] + vertex [CROP-VERTEX! value] + pos [red-pair!] + vec1 [VECTOR2D! value] + vec2 [VECTOR2D! value] + vec3 [VECTOR2D! value] + crop.x [integer!] + crop.y [integer!] + crop.w [integer!] + crop.h [integer!] + crop2 [red-pair!] + handle [integer!] + handle2 [integer!] + buf [int-ptr!] + buf2 [int-ptr!] + pb [byte-ptr!] + nbuf [int-ptr!] + ][ + w: IMAGE_WIDTH(src/size) + h: IMAGE_HEIGHT(src/size) + + either null? start [ + vertex/v1x: as float32! 0.0 + vertex/v1y: as float32! 0.0 + ][ + vertex/v1x: as float32! start/x + vertex/v1y: as float32! start/y + ] + unless null? crop1 [ + crop2: crop1 + 1 + crop.x: crop1/x + crop.y: crop1/y + crop.w: crop2/x + crop.h: crop2/y + if crop.x + crop.w > w [ + crop.w: w - crop.x + ] + if crop.y + crop.h > h [ + crop.h: h - crop.y + ] + ] + case [ + start = end [ + either null? crop1 [ + w1: w h1: h + ][ + w1: crop.w h1: crop.h + ] + vertex/v2x: vertex/v1x + as float32! w1 + vertex/v2y: vertex/v1y + vertex/v3x: vertex/v1x + as float32! w1 + vertex/v3y: vertex/v1y + as float32! h1 + vertex/v4x: vertex/v1x + vertex/v4y: vertex/v1y + as float32! h1 + ] + start + 1 = end [ ;-- two control points + vertex/v2x: as float32! end/x + vertex/v2y: vertex/v1y + vertex/v3x: as float32! end/x + vertex/v3y: as float32! end/y + vertex/v4x: vertex/v1x + vertex/v4y: as float32! end/y + ] + start + 2 = end [ ;-- three control points + pos: start + 1 + vertex/v2x: as float32! pos/x + vertex/v2y: as float32! pos/y + pos: pos + 1 + vertex/v4x: as float32! pos/x + vertex/v4y: as float32! pos/y + vector2d/from-points vec1 vertex/v1x vertex/v1y vertex/v2x vertex/v2y + vector2d/from-points vec2 vertex/v1x vertex/v1y vertex/v4x vertex/v4y + vec3/x: vec1/x + vec2/x + vec3/y: vec1/y + vec2/y + vertex/v3x: as float32! vec3/x + vertex/v1x + vertex/v3y: as float32! vec3/y + vertex/v1y + ] + start + 3 = end [ ;-- four control points + pos: start + 1 + vertex/v2x: as float32! pos/x + vertex/v2y: as float32! pos/y + pos: pos + 1 + vertex/v4x: as float32! pos/x + vertex/v4y: as float32! pos/y + pos: pos + 1 + vertex/v3x: as float32! pos/x + vertex/v3y: as float32! pos/y + ] + true [ + dst/header: TYPE_NONE + exit + ] + ] + + handle: 0 + buf: acquire-buffer src :handle + either crop1 <> null [ + pb: allocate crop.w * crop.h * 4 + image-crop/crop as byte-ptr! buf w h crop.x crop.y crop.w crop.h pb + nbuf: image-crop/transform as int-ptr! pb crop.w crop.h vertex rect.x rect.y rect.w rect.h + free pb + ][ + nbuf: image-crop/transform buf w h vertex rect.x rect.y rect.w rect.h + ] + release-buffer src handle no + if null? nbuf [dst/header: TYPE_NONE exit] + init-image dst OS-image/make-image rect.w/1 rect.h/1 null null null + handle2: 0 + buf2: acquire-buffer dst :handle2 + copy-memory as byte-ptr! buf2 as byte-ptr! nbuf rect.w/1 * rect.h/1 * 4 + release-buffer dst handle2 yes + ] + load-binary: func [ data [red-binary!] return: [red-image!] From 0de86989f56aa106cb09d92a1881096cd162a857 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Mar 2020 15:39:31 +0800 Subject: [PATCH 1122/3432] FIX: improve OS-image/resize --- runtime/datatypes/image.reds | 2 + runtime/platform/image-gdk.reds | 112 ++++---------------------------- 2 files changed, 13 insertions(+), 101 deletions(-) diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 029c41616c..d606f73a4b 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -10,6 +10,8 @@ Red/System [ } ] +#include %../image-crop.reds + image: context [ verbose: 0 diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index ccb8dd5aab..77e0242df1 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -23,8 +23,6 @@ GError!: alias struct! [ message [c-string!] ] -#include %../image-crop.reds - OS-image: context [ img-node!: alias struct! [ @@ -136,6 +134,13 @@ OS-image: context [ [variadic] return: [logic!] ] + gdk_pixbuf_scale_simple: "gdk_pixbuf_scale_simple" [ + src [handle!] + dest_width [integer!] + dest_height [integer!] + interp_type [integer!] + return: [handle!] + ] g_object_unref: "g_object_unref" [ obj [handle!] ] @@ -238,113 +243,18 @@ OS-image: context [ if inode/buffer <> null [free as byte-ptr! inode/buffer inode/buffer: null] ] - resize-to-buff: func [ - img [red-image!] - width [integer!] - height [integer!] - return: [int-ptr!] - /local - old-w [integer!] - old-h [integer!] - bitmap [integer!] - stride [integer!] - src [int-ptr!] - dst [int-ptr!] - ][ - old-w: IMAGE_WIDTH(img/size) - old-h: IMAGE_HEIGHT(img/size) - - bitmap: lock-bitmap img no - stride: 0 - src: get-data bitmap :stride - dst: image-crop/resize src old-w old-h width height - unlock-bitmap img bitmap - dst - ] - - resize-to-handle: func [ - img [red-image!] - width [integer!] - height [integer!] - return: [handle!] - /local - dst [int-ptr!] - pixbuf [handle!] - buf [byte-ptr!] - ][ - dst: resize-to-buff img width height - pixbuf: gdk_pixbuf_new 0 yes 8 width height - buf: gdk_pixbuf_get_pixels pixbuf - revert dst as int-ptr! buf width * height yes - free as byte-ptr! dst - pixbuf - ] - resize: func [ img [red-image!] width [integer!] height [integer!] return: [integer!] /local - dst [int-ptr!] - ][ - dst: resize-to-buff img width height - as integer! make-node null dst IMG_NODE_HAS_BUFFER or IMG_NODE_MODIFIED width height - ] - - any-resize: func [ - img [red-image!] - crop? [logic!] - crop.x [integer!] - crop.y [integer!] - crop.w [integer!] - crop.h [integer!] - vertex [CROP-VERTEX!] - x [int-ptr!] - y [int-ptr!] - w [int-ptr!] - h [int-ptr!] - return: [handle!] - /local - old-w [integer!] - old-h [integer!] - bitmap [integer!] - src [int-ptr!] - src2 [byte-ptr!] - stride [integer!] - dst [int-ptr!] pixbuf [handle!] - buf [byte-ptr!] + np [handle!] ][ - old-w: IMAGE_WIDTH(img/size) - old-h: IMAGE_HEIGHT(img/size) - - bitmap: lock-bitmap img no - stride: 0 - src: get-data bitmap :stride - either crop? [ - src2: allocate crop.w * crop.h * 4 - image-crop/crop as byte-ptr! src old-w old-h crop.x crop.y crop.w crop.h src2 - dst: image-crop/transform as int-ptr! src2 crop.w crop.h vertex x y w h - free src2 - ][ - dst: image-crop/transform src old-w old-h vertex x y w h - ] - unlock-bitmap img bitmap - if null? dst [return null] - if any [ - w/1 = 0 - h/1 = 0 - ][ - free as byte-ptr! dst - return null - ] - - pixbuf: gdk_pixbuf_new 0 yes 8 w/1 h/1 - buf: gdk_pixbuf_get_pixels pixbuf - revert dst as int-ptr! buf w/1 * h/1 yes - free as byte-ptr! dst - pixbuf + pixbuf: to-pixbuf img + np: gdk_pixbuf_scale_simple pixbuf width height 2 + as integer! make-node np null 0 width height ] make-node: func [ From b853f487d53123909bf4513ca2c83c9e29ea704e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Mar 2020 16:57:47 +0800 Subject: [PATCH 1123/3432] FIX: simple image transform use native api to draw --- modules/view/backends/gtk3/draw.reds | 81 ++++++++++++++++++++-------- runtime/platform/image-gdk.reds | 2 +- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 6acd32943f..802fa08d08 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1269,34 +1269,69 @@ OS-draw-image: func [ crop1 [red-pair!] pattern [red-word!] /local + src.w [integer!] + src.h [integer!] + x [integer!] + y [integer!] + w [integer!] + h [integer!] + crop2 [red-pair!] + crop.x [integer!] + crop.y [integer!] + crop.w [integer!] + crop.h [integer!] dst [red-image! value] - rect.x [integer!] - rect.y [integer!] - rect.w [integer!] - rect.h [integer!] pixbuf [handle!] - cr [handle!] ][ - rect.x: 0 rect.y: 0 rect.w: 0 rect.h: 0 - image/any-resize src dst crop1 start end :rect.x :rect.y :rect.w :rect.h - if dst/header = TYPE_NONE [exit] - pixbuf: OS-image/to-pixbuf dst - - unless null? pixbuf [ - cr: dc/cr - cairo_save cr - cairo_translate cr as-float rect.x as-float rect.y - if rect.w < 0 [ - cairo_scale cr -1.0 1.0 + either any [ + start + 2 = end + start + 3 = end + ][ + x: 0 y: 0 w: 0 h: 0 + image/any-resize src dst crop1 start end :x :y :w :h + if dst/header = TYPE_NONE [exit] + pixbuf: OS-image/to-pixbuf dst + GDK-draw-image dc/cr pixbuf x y w h + OS-image/delete dst + ][ + src.w: IMAGE_WIDTH(src/size) + src.h: IMAGE_HEIGHT(src/size) + either null? start [x: 0 y: 0][x: start/x y: start/y] + unless null? crop1 [ + crop2: crop1 + 1 + crop.x: crop1/x + crop.y: crop1/y + crop.w: crop2/x + crop.h: crop2/y + if crop.x + crop.w > src.w [ + crop.w: src.w - crop.x + ] + if crop.y + crop.h > src.h [ + crop.h: src.h - crop.y + ] ] - if rect.h < 0 [ - cairo_scale cr 1.0 -1.0 + case [ + start = end [ + either null? crop1 [ + w: src.w h: src.h + ][ + w: crop.w h: crop.h + ] + ] + start + 1 = end [ + w: end/x - x + h: end/y - y + ] + true [exit] + ] + pixbuf: OS-image/to-pixbuf src + unless null? crop1 [ + pixbuf: gdk_pixbuf_new_subpixbuf pixbuf crop.x crop.y crop.w crop.h + ] + GDK-draw-image dc/cr pixbuf x y w h + unless null? crop1 [ + g_object_unref pixbuf ] - gdk_cairo_set_source_pixbuf cr pixbuf 0.0 0.0 - cairo_paint cr - cairo_restore cr - - OS-image/delete dst ] ] diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index 77e0242df1..adf51fb91f 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -606,7 +606,7 @@ OS-image: context [ src-buf: as byte-ptr! inode0/buffer copy-rect dst-buf w h w * 4 src-buf width height width * 4 x y h ][ - handle: gdk_pixbuf_new_subpixbuf handle0 x y w h + handle: gdk_pixbuf_new_subpixbuf gdk_pixbuf_copy handle0 x y w h dst/node: make-node handle null 0 w h ] dst/size: h << 16 or w From c66e4f8956596a8259cb1ea11e3c866f45df739e Mon Sep 17 00:00:00 2001 From: bitbegin Date: Thu, 12 Mar 2020 17:39:58 +0800 Subject: [PATCH 1124/3432] FIX: support neg-x or neg-y transform --- runtime/datatypes/image.reds | 18 ++++++++++++++++++ runtime/image-crop.reds | 31 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index d606f73a4b..6bc4bc17c8 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -142,6 +142,8 @@ image: context [ buf2 [int-ptr!] pb [byte-ptr!] nbuf [int-ptr!] + neg-x? [logic!] + neg-y? [logic!] ][ w: IMAGE_WIDTH(src/size) h: IMAGE_HEIGHT(src/size) @@ -218,6 +220,16 @@ image: context [ exit ] ] + neg-x?: no + neg-y?: no + if vertex/v1x > vertex/v2x [ + neg-x?: yes + image-crop/flip-x vertex vertex/v1x + ] + if vertex/v2y > vertex/v3y [ + neg-y?: yes + image-crop/flip-y vertex vertex/v1y + ] handle: 0 buf: acquire-buffer src :handle @@ -235,6 +247,12 @@ image: context [ handle2: 0 buf2: acquire-buffer dst :handle2 copy-memory as byte-ptr! buf2 as byte-ptr! nbuf rect.w/1 * rect.h/1 * 4 + if neg-x? [ + rect.w/1: 0 - rect.w/1 + ] + if neg-y? [ + rect.h/1: 0 - rect.h/1 + ] release-buffer dst handle2 yes ] diff --git a/runtime/image-crop.reds b/runtime/image-crop.reds index 7c3668ab7b..fb44104196 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-crop.reds @@ -29,6 +29,37 @@ float32-min: as float32! -3.40282347E+38 image-crop: context [ + flip-x: func [ + vertex [CROP-VERTEX!] + x0 [float32!] + /local + p [pointer! [float32!]] + t [float32!] + ][ + p: as pointer! [float32!] vertex + loop 4 [ + t: x0 * as float32! 2.0 + p/1: t - p/1 + p: p + 2 + ] + ] + + flip-y: func [ + vertex [CROP-VERTEX!] + y0 [float32!] + /local + p [pointer! [float32!]] + t [float32!] + ][ + p: as pointer! [float32!] vertex + p: p + 1 + loop 4 [ + t: y0 * as float32! 2.0 + p/1: t - p/1 + p: p + 2 + ] + ] + on-plane?: func [ vertex [CROP-VERTEX!] x [float32!] From 5dba63a19ddac52d5aa2c804c38bc80c586a9794 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 13 Mar 2020 09:50:58 +0800 Subject: [PATCH 1125/3432] FIX: better name --- build/includes.r | 2 +- runtime/datatypes/image.reds | 17 +++++---- runtime/{image-crop.reds => image-utils.reds} | 38 +++++++++---------- 3 files changed, 29 insertions(+), 28 deletions(-) rename runtime/{image-crop.reds => image-utils.reds} (93%) diff --git a/build/includes.r b/build/includes.r index df1a093ac1..d708d5fcb9 100644 --- a/build/includes.r +++ b/build/includes.r @@ -101,7 +101,7 @@ write %build/bin/sources.r set-cache [ %tools.reds %unicode.reds %utils.reds - %image-crop.reds + %image-utils.reds %vector2d.reds %datatypes/ [ %action.reds diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 6bc4bc17c8..f7812478f2 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -10,7 +10,7 @@ Red/System [ } ] -#include %../image-crop.reds +#include %../image-utils.reds image: context [ verbose: 0 @@ -126,7 +126,7 @@ image: context [ h [integer!] w1 [integer!] h1 [integer!] - vertex [CROP-VERTEX! value] + vertex [TRANS-VERTEX! value] pos [red-pair!] vec1 [VECTOR2D! value] vec2 [VECTOR2D! value] @@ -224,22 +224,22 @@ image: context [ neg-y?: no if vertex/v1x > vertex/v2x [ neg-x?: yes - image-crop/flip-x vertex vertex/v1x + image-utils/flip-x vertex vertex/v1x ] if vertex/v2y > vertex/v3y [ neg-y?: yes - image-crop/flip-y vertex vertex/v1y + image-utils/flip-y vertex vertex/v1y ] handle: 0 buf: acquire-buffer src :handle either crop1 <> null [ pb: allocate crop.w * crop.h * 4 - image-crop/crop as byte-ptr! buf w h crop.x crop.y crop.w crop.h pb - nbuf: image-crop/transform as int-ptr! pb crop.w crop.h vertex rect.x rect.y rect.w rect.h + image-utils/crop as byte-ptr! buf w h crop.x crop.y crop.w crop.h pb + nbuf: image-utils/transform as int-ptr! pb crop.w crop.h vertex rect.x rect.y rect.w rect.h free pb ][ - nbuf: image-crop/transform buf w h vertex rect.x rect.y rect.w rect.h + nbuf: image-utils/transform buf w h vertex rect.x rect.y rect.w rect.h ] release-buffer src handle no if null? nbuf [dst/header: TYPE_NONE exit] @@ -247,13 +247,14 @@ image: context [ handle2: 0 buf2: acquire-buffer dst :handle2 copy-memory as byte-ptr! buf2 as byte-ptr! nbuf rect.w/1 * rect.h/1 * 4 + release-buffer dst handle2 yes + free as byte-ptr! nbuf if neg-x? [ rect.w/1: 0 - rect.w/1 ] if neg-y? [ rect.h/1: 0 - rect.h/1 ] - release-buffer dst handle2 yes ] load-binary: func [ diff --git a/runtime/image-crop.reds b/runtime/image-utils.reds similarity index 93% rename from runtime/image-crop.reds rename to runtime/image-utils.reds index fb44104196..14fabb4b88 100644 --- a/runtime/image-crop.reds +++ b/runtime/image-utils.reds @@ -1,7 +1,7 @@ Red/System [ - Title: "image-crop" + Title: "image utils" Author: "bitbegin" - File: %image-crop.reds + File: %image-utils.reds Note: "useful functions for image!" Tabs: 4 Rights: "Copyright (C) 2020 Red Foundation. All rights reserved." @@ -13,7 +13,7 @@ Red/System [ #include %vector2d.reds -CROP-VERTEX!: alias struct! [ +TRANS-VERTEX!: alias struct! [ v1x [float32!] v1y [float32!] v2x [float32!] @@ -27,10 +27,10 @@ CROP-VERTEX!: alias struct! [ float32-max: as float32! 3.40282347E+38 float32-min: as float32! -3.40282347E+38 -image-crop: context [ +image-utils: context [ flip-x: func [ - vertex [CROP-VERTEX!] + vertex [TRANS-VERTEX!] x0 [float32!] /local p [pointer! [float32!]] @@ -45,7 +45,7 @@ image-crop: context [ ] flip-y: func [ - vertex [CROP-VERTEX!] + vertex [TRANS-VERTEX!] y0 [float32!] /local p [pointer! [float32!]] @@ -61,7 +61,7 @@ image-crop: context [ ] on-plane?: func [ - vertex [CROP-VERTEX!] + vertex [TRANS-VERTEX!] x [float32!] y [float32!] return: [logic!] @@ -77,17 +77,17 @@ image-crop: context [ crop: func [ src [byte-ptr!] - sw [integer!] ;-- width - sh [integer!] ;-- height + sw [integer!] ;-- src width + sh [integer!] ;-- src height x [integer!] ;-- start.x y [integer!] ;-- start.y - dw [integer!] ;-- width - dh [integer!] ;-- height + dw [integer!] ;-- dst width + dh [integer!] ;-- dst height dst [byte-ptr!] return: [logic!] /local - ss [integer!] ;-- stride - ds [integer!] ;-- stride + ss [integer!] ;-- src stride + ds [integer!] ;-- dst stride offset [integer!] from [byte-ptr!] to [byte-ptr!] @@ -121,13 +121,13 @@ image-crop: context [ transform: func [ src [int-ptr!] - sw [integer!] ;-- width - sh [integer!] ;-- height - vertex [CROP-VERTEX!] + sw [integer!] ;-- src width + sh [integer!] ;-- src height + vertex [TRANS-VERTEX!] dx [int-ptr!] dy [int-ptr!] - dw [int-ptr!] ;-- width - dh [int-ptr!] ;-- height + dw [int-ptr!] ;-- dst width + dh [int-ptr!] ;-- dst height return: [int-ptr!] /local xmin [float32!] @@ -339,7 +339,7 @@ image-crop: context [ dh [integer!] ;-- height return: [int-ptr!] /local - vertex [CROP-VERTEX! value] + vertex [TRANS-VERTEX! value] w [integer!] h [integer!] x [integer!] From 486329f49eed24fd0dee2cef54bcd8f03880cfc5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 13 Mar 2020 17:08:40 +0100 Subject: [PATCH 1126/3432] FEAT: better handling of % and %% as words. Note: set-words for those literals are forbidden (conflicts with files), so use SET to set them to values. --- docs/lexer/lexer-FSM.csv | 7 +- docs/lexer/lexer-FSM.xlsx | Bin 21923 -> 22163 bytes docs/lexer/lexer-states.txt | 22 +++-- runtime/lexer-transitions.reds | 150 +++++++++++++++++---------------- utils/generate-lexer-table.red | 85 ++++++++++--------- 5 files changed, 137 insertions(+), 127 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 9b8b86437b..aa5503d6b3 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -5,12 +5,12 @@ S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_L S_SKIP_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;S_LINE_STR;T_ERROR;T_EOF S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_MSTR_OP;T_MSTR_CL;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_SKIP_MSTR;S_M_STRING;S_M_STRING;T_ERROR;T_ERROR S_SKIP_MSTR;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;S_M_STRING;T_ERROR;T_EOF -S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;S_FILE_STR;S_FILE;S_FILE;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_HDPER_ST;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD +S_FILE_1ST;T_WORD;T_WORD;S_FILE;S_FILE;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;S_FILE_STR;S_FILE;S_FILE;S_PERCENT;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_HDPER_ST;S_FILE;T_WORD;T_WORD;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_WORD S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_FILE;T_ERROR;S_FILE;S_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE_HEX1;S_FILE;T_FILE;T_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_FILE S_FILE_HEX1;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_HEX2;T_ERROR;T_ERROR;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR -S_HDPER_ST;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HERDOC_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR +S_HDPER_ST;T_WORD;T_WORD;S_FILE_HEX2;S_FILE_HEX2;T_WORD;T_WORD;T_WORD;T_WORD;S_HERDOC_ST;T_WORD;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;S_FILE_HEX2;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;S_HDPER_ST;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_C0;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HDPER_CL;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;S_HERDOC_ST;T_ERROR;T_ERROR S_HDPER_CL;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_ERROR;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_RAWSTRING;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;S_HDPER_CL;T_ERROR;T_RAWSTRING;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_RAWSTRING @@ -48,9 +48,10 @@ S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_TAG_STR2;S_T S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;T_WORD;S_WORD;S_DOTWORD;S_MONEY;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR +S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;S_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD +S_PERCENT;T_WORD;T_WORD;T_ERROR;T_ERROR;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;S_PERCENT;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL S_EMAIL;T_EMAIL;T_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;S_EMAIL;T_EMAIL;T_EMAIL;T_EMAIL;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_EMAIL;T_ERROR;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;S_EMAIL;S_EMAIL;T_ERROR;T_EMAIL S_PATH;T_ERROR;T_ERROR;S_PATH_NUM;S_PATH_NUM;T_ERROR;T_ERROR;T_PAR_OP;T_PAR_CL;T_ERROR;T_ERROR;S_LINE_STR;S_PATH_SHARP;S_PATH_W1ST;S_PATH_W1ST;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;S_LESSER;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;S_PATH_WORD;T_ERROR;S_PATH_SIGN;S_PATH_SIGN;T_ERROR;S_PATH_WORD;S_PATH_WORD;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 7714b72158a885ed906e8c035d841495b4e693c2..4e1fe24b15d41a25695bb764a441c24835caf59a 100644 GIT binary patch delta 10776 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 delta 10464 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"%"->S_FILE_1ST->not(delimit8)->S_FILE->not(delimit1)->S_FILE \->"%"->S_HDPER_ST->"%"->S_HDPER_ST \ \->"{"->S_HERDOC_ST \ \->hexa->S_FILE_HEX2 - \ \->else->T_ERROR - \ - \->"{"->S_HERDOC_ST->"}"->S_HDPER_C0->"%"->S_HDPER_CL->"%"->S_HDPER_CL - \ \ \ \->else->T_RAWSTRING - \ \ \->else->S_HERDOC_ST - \ \->else->S_HERDOC_ST - \->delimit8->T_WORD + \ \->delimit7->T_WORD + \ \->else->T_ERROR + \ + \->"{"->S_HERDOC_ST->"}"->S_HDPER_C0->"%"->S_HDPER_CL->"%"->S_HDPER_CL + \ \ \ \->else->T_RAWSTRING + \ \ \->else->S_HERDOC_ST + \ \->else->S_HERDOC_ST + \->delimit8->T_WORD S_START->"#"->S_SHARP->"{"->S_BINARY->hexa|ws->S_BINARY @@ -327,7 +329,11 @@ S_START->alphaU|"E"->S_HEX->alphaU|digit|"E"->S_HEX \->","|"#"|"%"->T_ERROR \->not(delimit5)->S_WORD -S_START->"'"|":"->S_WORD_1ST->not(delimit6)->S_WORD +S_START->"'"|":"->S_WORD_1ST->"%"->S_PERCENT + \ \->":"->T_ERROR + \ \->delimit5->T_WORD + \ \->else->T_ERROR + \->not(delimit6)->S_WORD S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD \->delimit7->T_WORD diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 8a71a74254..8cb8a87ab1 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -54,6 +54,7 @@ Red/System [ S_WORD_1ST S_WORD S_WORDSET + S_PERCENT S_URL S_EMAIL S_PATH @@ -99,82 +100,83 @@ Red/System [ ] type-table: #{ 000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F -2B2B25253333330B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00002200 -000000000700000000070F140B130A0829260C0C272F252B332C092D0B07 +2B2B25253333330B0F0B2C2C2C2C0F0F0C0F0F100F092D190B0F0F140F000022 +00000000000700000000070F140B130A0829260C0C272F252B332C092D0B07 } transitions: #{ -000018183F404142433E02113131323232322732270F3E2A3232063E013E2F24 -2E2E3E32323E3D01480101010101010101010101010101010101010101010101 -0101010101010101010101013E3D020202020202020202024902020202020202 -020202020202020202020202020202020302023E3E0202020202020202020202 -02020202020202020202020202020202020202020202020202023E3D04040404 -0404040443440404040404040404040404040404040404040404040404040504 -043E3E0404040404040404040404040404040404040404040404040404040404 -04040404040404043E3D4A4A07074A4A4A4A0C4A0A07074A0707070707070707 -070707070B074A4A070707070707073E4A4F4F07074F4F4F4F4F4F3E07074F07 -070707070707070707070708074F4F070707070707073E4F3E3E09093E3E3E3E -3E3E3E3E3E3E3E3E3E090909093E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E -3E07073E3E3E3E3E3E3E3E3E3E3E3E3E090907073E3E3E3E3E3E3E3E3E3E3E3E -3E3E3E3E3E3E0A0A0A0A0A0A0A0A0A0A4F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -0A0A0A0A0A0A0A0A0A0A0A3E3E3E3E09093E3E3E3E0C3E3E3E3E3E3E3E3E0909 -09093E3E3E3E3E0B3E3E3E3E3E3E3E3E3E3E3E3E0C0C0C0C0C0C0C0C0C0D0C0C -0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C3E3E0C0C0C0C0C +0000181840414243443F02113131323232322732270F3F2A3232063F013F2F24 +2E2E3F32323F3E01490101010101010101010101010101010101010101010101 +0101010101010101010101013F3E020202020202020202024A02020202020202 +020202020202020202020202020202020302023F3F0202020202020202020202 +02020202020202020202020202020202020202020202020202023F3E04040404 +0404040444450404040404040404040404040404040404040404040404040504 +043F3F0404040404040404040404040404040404040404040404040404040404 +04040404040404043F3E4B4B07074B4B4B4B0C4B0A0707340707070707070707 +070707070B074B4B070707070707073F4B505007075050505050503F07075007 +070707070707070707070708075050070707070707073F503F3F09093F3F3F3F +3F3F3F3F3F3F3F3F3F090909093F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F +3F07073F3F3F3F3F3F3F3F3F3F3F3F3F090907073F3F3F3F3F3F3F3F3F3F3F3F +3F3F3F3F3F3F0A0A0A0A0A0A0A0A0A0A500A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A3F3F4B4B09094B4B4B4B0C4B4B3F3F3F3F3F3F0909 +09093F4B3F3F3F0B3F4B3F3F3F3F3F3F3F3F3F4B0C0C0C0C0C0C0C0C0C0D0C0C +0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C3F3F0C0C0C0C0C 0C0C0C0C0D0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0E0C0C0C0C0C0C0C0C0C0C -3E3E5D5D3E3E5D5D5D5D5D3E5D3E3E3E3E3E3E3E3E3E3E3E3E5D3E3E0E3E5D3E -3E3E3E3E3E3E3E3E5D4D4D0F0F4D4D4D4D4D4D4D0F0F0F0F0F0F0F0F0F0F100F -0F0F0F0F0F4D4D0F0F0F0F0F0F0F3E4D4A4A32324A4A4A4A4A4A4A3E32323232 -323232323210323232323E324A4A323E32323232323E4A4B4B1717163E453E12 -3E1417173E1717171717171717173E3E3E173E4B4B171717171717173E4B1212 -12123E3E3E3E3E503E3E3E3E12121212121212123E3E3E123E3E133E3E3E123E -3E3E123E3E131213131313131313131313131313131313131313131313131313 -131313131313131313133E3D141414141414141414144E141414141414141414 -14141414141414141414141414141514143E4E14141414141414141414141414 -1414141414141414141414141414141414141414141414143E3E161616161647 -161616161616161616161616161616161616161616161616161616161616163E -3E4B4B17174B4B4B4B4B4B4B17171717171717171717171717171717174B4B17 -1717171717173E4B4C4C18184C4C4C4C4C4C4C111820221F291B1C3E271F3E4C -3E3E51194C35193E3E1F3E3E3E3E4C52521A1A525252525252521D1A3E223E3E -1B1B3E3E523E523E3E513E523E3E3E3E3E3E3E3E3E5252521A1A525252525252 -523E3E52223E3E1B1B3E3E523E523E3E513E3E351E3E3E3E3E3E3E3E5252521B -1B525252525252523E3E523E3E3E3E3E3E3E523E523E3E3E3E3E353E3E1B1B3E -3E3E3E5252521C1C525252525252523E3E523E3E293E273E27523E523E3E513E -3E351E3E1B1B3E3E3E3E5252525253535353535353531D53531D1D1D1D1D1D1D -5353531D1D535353531D531D1D531D1D3E5354541E1E545454545454543E3E54 -3E3E3E3E3E3E3E543E543E3E3E3E3E3E1E3E3E3E3E3E3E3E5455551F1F555555 -555555551F1F1F1F1F1F1F1F1F1F1F1F551F1F3E1F55551F551F1F3E3E1F3E55 -3E3E21213E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E -3E3E3E3E3E3E3E57572121575757575757573E3E213E3E3E3E3E3E3E573E573E -3E3E3E573E213E3E3E3E3E3E3E573E3E23233E3E3E3E3E3E3E3E3E3E3E3E3E3E -3E3E3E3E3E3E3E3E3E3E3E353E3E23233E3E3E3E3E5656232356565656565656 -3E3E563E3E3E23233E3E563E563E3E3E3E5635233E3E3E3E3E3E3E563E3E2525 -3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E -3E3E3E58582525585858585858585825583E3E3E3E3E3E3E583E583E3E3E2658 -3E263E3E3E3E3E3E3E3D58582626585858585858585826583E3E3E3E3E3E3E58 -3E583E3E3E3E583E3E3E3E3E3E3E3E3E3D4A4A27274A4A4A4A4A4A4A3E323332 -322832273227464A3232323E3E4A35322532323232323E4A5C5C32325C5C5C5C -5C5C5C3E323332323232323232465C3232323E3E5C35322532323232323E5C5C -5C3E3E5C5C5C5C5C5C5C3E3E3E3E3E3E3E3E3E3E465C5C3E3E3E3E5C353E253E -3E3E3E3E3E5C4A4A2B2B4A4A4A4A4A4A4A2B2D4A2B2B2B2B2B2B2B2B2B2A3232 -2B2B4A4A2B2B2B322B2B2B3E4A2B2B2B2B2B2B2B2B2B2B2C2B2D2B2B2B2B2B2B -2B2B2B2B2B592B2B2B2B2B2B2B2B2B2B2B2B3E3E2C2C2C2C2C2C2C2C2C2C2B2C -2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C3E3E2D2D2D2D2D +3F3F5E5E3F3F5E5E5E5E5E3F5E3F3F3F3F3F3F3F3F3F3F3F3F5E3F3F0E3F5E3F +3F3F3F3F3F3F3F3F5E4E4E0F0F4E4E4E4E4E4E4E0F0F0F0F0F0F0F0F0F0F100F +0F0F0F0F0F4E4E0F0F0F0F0F0F0F3F4E4B4B32324B4B4B4B4B4B4B3F32323232 +323232323210323232323F324B4B323F32323232323F4B4C4C1717163F463F12 +3F1417173F1717171717171717173F3F3F173F4C4C171717171717173F4C1212 +12123F3F3F3F3F513F3F3F3F12121212121212123F3F3F123F3F133F3F3F123F +3F3F123F3F131213131313131313131313131313131313131313131313131313 +131313131313131313133F3E141414141414141414144F141414141414141414 +14141414141414141414141414141514143F4F14141414141414141414141414 +1414141414141414141414141414141414141414141414143F3F161616161648 +161616161616161616161616161616161616161616161616161616161616163F +3F4C4C17174C4C4C4C4C4C4C17171717171717171717171717171717174C4C17 +1717171717173F4C4D4D18184D4D4D4D4D4D4D111820221F291B1C3F271F3F4D +3F3F52194D36193F3F1F3F3F3F3F4D53531A1A535353535353531D1A3F223F3F +1B1B3F3F533F533F3F523F533F3F3F3F3F3F3F3F3F5353531A1A535353535353 +533F3F53223F3F1B1B3F3F533F533F3F523F3F361E3F3F3F3F3F3F3F5353531B +1B535353535353533F3F533F3F3F3F3F3F3F533F533F3F3F3F3F363F3F1B1B3F +3F3F3F5353531C1C535353535353533F3F533F3F293F273F27533F533F3F523F +3F361E3F1B1B3F3F3F3F5353535354545454545454541D54541D1D1D1D1D1D1D +5454541D1D545454541D541D1D541D1D3F5455551E1E555555555555553F3F55 +3F3F3F3F3F3F3F553F553F3F3F3F3F3F1E3F3F3F3F3F3F3F5556561F1F565656 +565656561F1F1F1F1F1F1F1F1F1F1F1F561F1F3F1F56561F561F1F3F3F1F3F56 +3F3F21213F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F +3F3F3F3F3F3F3F58582121585858585858583F3F213F3F3F3F3F3F3F583F583F +3F3F3F583F213F3F3F3F3F3F3F583F3F23233F3F3F3F3F3F3F3F3F3F3F3F3F3F +3F3F3F3F3F3F3F3F3F3F3F363F3F23233F3F3F3F3F5757232357575757575757 +3F3F573F3F3F23233F3F573F573F3F3F3F5736233F3F3F3F3F3F3F573F3F2525 +3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F +3F3F3F59592525595959595959595925593F3F3F3F3F3F3F593F593F3F3F2659 +3F263F3F3F3F3F3F3F3E59592626595959595959595926593F3F3F3F3F3F3F59 +3F593F3F3F3F593F3F3F3F3F3F3F3F3F3E4B4B27274B4B4B4B4B4B4B3F323332 +322832273227474B3232323F3F4B36322532323232323F4B5D5D32325D5D5D5D +5D5D5D3F323332323232323232475D3232323F3F5D36322532323232323F5D5D +5D3F3F5D5D5D5D5D5D5D3F3F3F3F3F3F3F3F3F3F475D5D3F3F3F3F5D363F253F +3F3F3F3F3F5D4B4B2B2B4B4B4B4B4B4B4B2B2D4B2B2B2B2B2B2B2B2B2B2A3232 +2B2B4B4B2B2B2B322B2B2B3F4B2B2B2B2B2B2B2B2B2B2B2C2B2D2B2B2B2B2B2B +2B2B2B2B2B5A2B2B2B2B2B2B2B2B2B2B2B2B3F3F2C2C2C2C2C2C2C2C2C2C2B2C +2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C2C3F3F2D2D2D2D2D 2D2D2D2D2D2D2D2B2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D -3E3E4A4A18184A4A4A4A4A4A4A3E3E3232323232323232324A3E32323E324A32 -2F2532323E32323E4A4A4A30304A4A4A4A4A4A4A3E323332323230303232464A -3232323E3E4A35323E30303232323E4A52523030525252525252523E3E52223E -3E30303E3E523E523E3E513E3E3E3E3E30303E3E3E3E523E3E3E3E3E3E3E3E3E -3E3E3E3E3E323232323232320F3E3232323E3E3E3E323E32323E32323E3E4A4A -32324A4A4A4A4A4A4A3E323332323232323232464A4A32323E3E4A3532253232 -3232323E4A4A4A34344A4A4A4A4A4A4A34343434343434343434344A3E343434 -344A34343434343434343E4A5A5A34345A5A5A5A5A5A5A343E34343434343434 -34345A5A3E34345A5A34343E34343E34343E5A5B5B35355B5B5B5B5B5B5B3E3E -3E353535353535355B5B5B3E3E353E5B3E353E35353E35353E5B3E3E37373E3E -41423E3E023A3838393939393939393E3E2A39393E3E3E35393E3B3B3E39393E -3E4C4C37374C4C4C4C4C4C4C3E184C223E3E1B1B3E3E4C3E4C3E3E51194C3519 -3E3E3E3E3E3E3E4C3E3E3E3E3E3E3E3E3E3E3E3E3E3E393939393939393E3E39 -39393E3E3E3E393E39393E39393E3E4A4A39394A4A4A4A4A4A4A3E394A393939 -393939394A4A3939393E3E4A35393E39393939393E4A4B4B1717163E3E3E3E3E -1417173E1717171717171717173E3E3E173E4B4B171717171717173E4B4A4A37 -374A4A4A4A4A4A4A3E3E3232323232323232324A3E32323E324A32323232323E -32323E4A +3F3F4B4B18184B4B4B4B4B4B4B3F3F3232323232323232324B3F32323F324B32 +2F2532323F32323F4B4B4B30304B4B4B4B4B4B4B3F323332323230303232474B +3232323F3F4B36323F30303232323F4B53533030535353535353533F3F53223F +3F30303F3F533F533F3F523F3F3F3F3F30303F3F3F3F533F3F3F3F3F3F3F3F3F +3F3F3F3F3F323232323232320F3F323232343F3F3F323F32323F32323F3F4B4B +32324B4B4B4B4B4B4B3F323332323232323232474B4B32323F3F4B3632253232 +3232323F4B4B4B35354B4B4B4B4B4B4B35353535353535353535354B3F353535 +354B35353535353535353F4B4B4B3F3F4B4B4B4B4B4B3F3F3F3F3F3F3F3F3F3F +3F3F4B3F3F3F343F4B3F3F3F3F3F3F3F3F3F4B5B5B35355B5B5B5B5B5B5B353F +3535353535353535355B5B3F35355B5B35353F35353F35353F5B5C5C36365C5C +5C5C5C5C5C3F3F3F363636363636365C5C5C3F3F363F5C3F363F36363F36363F +5C3F3F38383F3F42433F3F023B39393A3A3A3A3A3A3A3F3F2A3A3A3F3F3F363A +3F3C3C3F3A3A3F3F4D4D38384D4D4D4D4D4D4D3F184D223F3F1B1B3F3F4D3F4D +3F3F52194D36193F3F3F3F3F3F3F4D3F3F3F3F3F3F3F3F3F3F3F3F3F3F3A3A3A +3A3A3A3A3F3F3A3A3A3F3F3F3F3A3F3A3A3F3A3A3F3F4B4B3A3A4B4B4B4B4B4B +4B3F3A4B3A3A3A3A3A3A3A4B4B3A3A3A3F3F4B363A3F3A3A3A3A3A3F4B4C4C17 +17163F3F3F3F3F1417173F1717171717171717173F3F3F173F4C4C1717171717 +17173F4C4B4B38384B4B4B4B4B4B4B3F3F3232323232323232324B3F32323F32 +4B32323232323F32323F4B } diff --git a/utils/generate-lexer-table.red b/utils/generate-lexer-table.red index 96f8034da0..7a4e4e3016 100644 --- a/utils/generate-lexer-table.red +++ b/utils/generate-lexer-table.red @@ -65,48 +65,49 @@ context [ S_WORD_1ST TYPE_WORD ;-- 49 S_WORD TYPE_WORD ;-- 50 S_WORDSET TYPE_SET_WORD ;-- 51 - S_URL TYPE_URL ;-- 52 - S_EMAIL TYPE_EMAIL ;-- 53 - S_PATH TYPE_PATH ;-- 54 - S_PATH_NUM TYPE_INTEGER ;-- 55 - S_PATH_W1ST TYPE_WORD ;-- 56 - S_PATH_WORD TYPE_WORD ;-- 57 - S_PATH_SHARP TYPE_ISSUE ;-- 58 - S_PATH_SIGN TYPE_WORD ;-- 59 - --EXIT_STATES-- - ;-- 60 - T_EOF - ;-- 61 - T_ERROR TYPE_ERROR ;-- 62 - T_BLK_OP - ;-- 63 - T_BLK_CL - ;-- 64 - T_PAR_OP - ;-- 65 - T_PAR_CL - ;-- 66 - T_MSTR_OP - ;-- 67 - T_MSTR_CL TYPE_STRING ;-- 68 - T_MAP_OP - ;-- 69 - T_PATH - ;-- 70 - T_CONS_MK - ;-- 71 - T_CMT - ;-- 72 - T_STRING TYPE_STRING ;-- 73 - T_WORD TYPE_WORD ;-- 74 - T_ISSUE TYPE_ISSUE ;-- 75 - T_INTEGER TYPE_INTEGER ;-- 76 - T_REFINE TYPE_REFINEMENT ;-- 77 - T_CHAR TYPE_CHAR ;-- 78 - T_FILE TYPE_FILE ;-- 79 - T_BINARY TYPE_BINARY ;-- 80 - T_PERCENT TYPE_PERCENT ;-- 81 - T_FLOAT TYPE_FLOAT ;-- 82 - T_FLOAT_SP TYPE_FLOAT ;-- 83 - T_TUPLE TYPE_TUPLE ;-- 84 - T_DATE TYPE_DATE ;-- 85 - T_PAIR TYPE_PAIR ;-- 86 - T_TIME TYPE_TIME ;-- 87 - T_MONEY TYPE_MONEY ;-- 88 - T_TAG TYPE_TAG ;-- 89 - T_URL TYPE_URL ;-- 90 - T_EMAIL TYPE_EMAIL ;-- 91 - T_HEX TYPE_INTEGER ;-- 92 - T_RAWSTRING TYPE_STRING ;-- 93 + S_PERCENT TYPE_WORD ;-- 52 + S_URL TYPE_URL ;-- 53 + S_EMAIL TYPE_EMAIL ;-- 54 + S_PATH TYPE_PATH ;-- 55 + S_PATH_NUM TYPE_INTEGER ;-- 56 + S_PATH_W1ST TYPE_WORD ;-- 57 + S_PATH_WORD TYPE_WORD ;-- 58 + S_PATH_SHARP TYPE_ISSUE ;-- 59 + S_PATH_SIGN TYPE_WORD ;-- 60 + --EXIT_STATES-- - ;-- 61 + T_EOF - ;-- 62 + T_ERROR TYPE_ERROR ;-- 63 + T_BLK_OP - ;-- 64 + T_BLK_CL - ;-- 65 + T_PAR_OP - ;-- 66 + T_PAR_CL - ;-- 67 + T_MSTR_OP - ;-- 68 + T_MSTR_CL TYPE_STRING ;-- 69 + T_MAP_OP - ;-- 70 + T_PATH - ;-- 71 + T_CONS_MK - ;-- 72 + T_CMT - ;-- 73 + T_STRING TYPE_STRING ;-- 74 + T_WORD TYPE_WORD ;-- 75 + T_ISSUE TYPE_ISSUE ;-- 76 + T_INTEGER TYPE_INTEGER ;-- 77 + T_REFINE TYPE_REFINEMENT ;-- 78 + T_CHAR TYPE_CHAR ;-- 79 + T_FILE TYPE_FILE ;-- 80 + T_BINARY TYPE_BINARY ;-- 81 + T_PERCENT TYPE_PERCENT ;-- 82 + T_FLOAT TYPE_FLOAT ;-- 83 + T_FLOAT_SP TYPE_FLOAT ;-- 84 + T_TUPLE TYPE_TUPLE ;-- 85 + T_DATE TYPE_DATE ;-- 86 + T_PAIR TYPE_PAIR ;-- 87 + T_TIME TYPE_TIME ;-- 88 + T_MONEY TYPE_MONEY ;-- 89 + T_TAG TYPE_TAG ;-- 90 + T_URL TYPE_URL ;-- 91 + T_EMAIL TYPE_EMAIL ;-- 92 + T_HEX TYPE_INTEGER ;-- 93 + T_RAWSTRING TYPE_STRING ;-- 94 ] CSV-table: %../docs/lexer/lexer-FSM.csv From 3adc6b8a950c5dd5506b692d942fa02208298c19 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 13 Mar 2020 19:30:04 +0100 Subject: [PATCH 1127/3432] FIX: [R/S] compiler state not fully cleaned up after premature termination. This affects multiple compilation jobs done in the same Rebol2 session, resulting in weird compilation errors. --- system/compiler.r | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/system/compiler.r b/system/compiler.r index 90e5ea35bb..55f3659b9a 100644 --- a/system/compiler.r +++ b/system/compiler.r @@ -87,9 +87,9 @@ system-dialect: make-profilable context [ locals: none ;-- currently compiled function specification block definitions: make block! 100 enumerations: make hash! 10 - expr-call-stack: make block! 1 ;-- simple stack of nested calls for a given expression + expr-call-stack: make block! 10 ;-- simple stack of nested calls for a given expression loop-stack: make block! 1 ;-- keep track of in-loop state - locals-init: [] ;-- currently compiler function locals variable init list + locals-init: make block! 20 ;-- currently compiler function locals variable init list subroutines: make block! 20 ;-- subroutines definitions: [name [offset ret-type] ...] in-subroutine?: no ;-- YES|subroutine name: current code is in a subroutine func-name: none ;-- currently compiled function name @@ -4067,9 +4067,19 @@ system-dialect: make-profilable context [ clean-up: does [ compiler/ns-path: compiler/ns-stack: + compiler/func-name: + compiler/func-locals-sz: compiler/locals: none - compiler/resolve-alias?: yes - compiler/user-code?: no + + compiler/resolve-alias?: yes + compiler/user-code?: no + compiler/in-subroutine?: no + compiler/user-code?: no + compiler/in-subroutine?: no + + compiler/block-level: + compiler/catch-level: + compiler/verbose: 0 clear compiler/imports clear compiler/exports @@ -4081,6 +4091,10 @@ system-dialect: make-profilable context [ clear compiler/enumerations clear compiler/aliased-types clear compiler/user-functions + clear compiler/expr-call-stack + clear compiler/locals-init + clear compiler/loop-stack + clear compiler/subroutines clear compiler/debug-lines/records clear compiler/debug-lines/files clear emitter/symbols From 3e1dca4883987ba931428d07b972b714097b89f4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 13 Mar 2020 19:40:30 +0100 Subject: [PATCH 1128/3432] FEAT: MONEY! creation from BLOCK! prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Syntax: [currency° integral fractional°] currency: valid currency code (word!) integral: integral part (signed integer!, float!) fractional: fractional part (unsigned, 5 digits max, integer!) --- runtime/datatypes/money.reds | 106 +++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 12 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 32f933881e..caffb29ebc 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -39,6 +39,14 @@ money: context [ SIGN_++: 22h ] + #enum make-states! [ + S_START + S_CURRENCY + S_INTEGRAL + S_FRACTIONAL + S_END + ] + #define DISPATCH_SIGNS [switch collate-signs this-sign that-sign] #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] @@ -59,6 +67,7 @@ money: context [ SIGN_MASK: 4000h SIGN_OFFSET: 14 + MAX_FRACTIONAL: 99999 INT32_MAX_DIGITS: 10 INT32_MIN_AMOUNT: #{00000002147483648FFFFF} INT32_MAX_AMOUNT: #{00000002147483647FFFFF} @@ -305,10 +314,12 @@ money: context [ end [byte-ptr!] return: [red-money!] /local - convert [subroutine!] - money [red-money!] - here amount limit [byte-ptr!] - index stop step [integer!] + convert [subroutine!] + money [red-money!] + here amount [byte-ptr!] + limit [byte-ptr!] + index stop [integer!] + step [integer!] ][ money: as red-money! slot money/header: TYPE_MONEY @@ -616,6 +627,82 @@ money: context [ copy-memory (get-amount money) + SIZE_BYTES - length head length money ] + + from-block: func [ + blk [red-block!] + return: [red-money!] + /local + bail [subroutine!] + money fraction [red-money!] + int [red-integer!] + flt [red-float!] + head tail here [red-value!] + state type length [integer!] + stop? [logic!] + ][ + bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] + + length: block/rs-length? blk + if any [length < 1 length > 3][bail] + + head: block/rs-head blk + tail: block/rs-tail blk + here: head + + state: S_START + stop?: no + + while [state <> S_END][ + type: TYPE_OF(here) + switch state [ + S_START [ + switch type [ + TYPE_WORD [state: S_CURRENCY] + TYPE_INTEGER + TYPE_FLOAT [state: S_INTEGRAL] + default [bail] + ] + ] + S_CURRENCY [ + ;@@ TBD: take currency into account + here: here + 1 + if here = tail [bail] + state: S_INTEGRAL + ] + S_INTEGRAL [ + switch type [ + TYPE_INTEGER [ + int: as red-integer! here + money: from-integer int/value + ] + TYPE_FLOAT [ + flt: as red-float! here + money: from-float flt/value + ] + default [bail] + ] + here: here + 1 + state: either here = tail [S_END][S_FRACTIONAL] + ] + S_FRACTIONAL [ + either type <> TYPE_INTEGER [bail][ + int: as red-integer! here + if any [negative? int/value int/value > MAX_FRACTIONAL][bail] + + fraction: set-sign from-integer int/value get-sign money + shift-right get-amount fraction SIZE_BYTES SIZE_SCALE + money: add-money money fraction + + here: here + 1 + if here <> tail [bail] + state: S_END + ] + ] + ] + ] + + money + ] from-string: func [ str [red-string!] @@ -1134,17 +1221,12 @@ money: context [ spec [red-value!] type [integer!] return: [red-money!] - /local - money [red-money!] ][ switch TYPE_OF(spec) [ - TYPE_MONEY [return as red-money! spec] - TYPE_BLOCK [--NOT_IMPLEMENTED--] - TYPE_BINARY [money: from-binary as red-binary! spec] - default [money: to proto spec type] + TYPE_BLOCK [from-block as red-block! spec] + TYPE_BINARY [from-binary as red-binary! spec] + default [to proto spec type] ] - - money ] to: func [ From f9476714b76756182677b2bf40872634d4945148 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 13 Mar 2020 19:40:59 +0100 Subject: [PATCH 1129/3432] TESTS: add extra MAKE tests --- tests/source/units/money-test.red | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 28ba0af7de..1d9ee89e0c 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -172,10 +172,17 @@ Red [ ===end-group=== ===start-group=== "make" - --test-- "make-1" --assert $12345678901234567.12345 == make money! #{1234567890123456712345 DEADBEEF} - --test-- "make-2" --assert $0 == make money! #{} - --test-- "make-3" --assert error? try [make money! #{DEADBEEF}] - ;@@ make money! + --test-- "make-1" --assert $12345678901234567.12345 == make money! #{1234567890123456712345 DEADBEEF} + --test-- "make-2" --assert $0 == make money! #{} + --test-- "make-3" --assert error? try [make money! #{DEADBEEF}] + --test-- "make-4" --assert error? try [make money! []] + --test-- "make-5" --assert error? try [make money! [CCC]] + --test-- "make-6" --assert error? try [make money! [CCC 1 2 3]] + --test-- "make-6" --assert error? try [make money! [0 123456]] + --test-- "make-7" --assert -$123.00456 == make money! [-123 456] + --test-- "make-8" --assert $123.44444 == make money! [123.32100 12344] + --test-- "make-9" --assert -CCC$123 == make money! [CCC -123] + --test-- "make-10" --assert -CCC$123 == make money! [CCC -123 0] ===end-group=== ===start-group=== "add" From 5d10b30d6b31e9fe392fa6dd64cf80ea0a265ba8 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 14 Mar 2020 13:41:21 +0800 Subject: [PATCH 1130/3432] FIX: issue #4335 ([CRASH] when appending strings to hash) --- runtime/datatypes/block.reds | 28 +++++++++++++++------------- runtime/hashtable.reds | 1 + tests/source/units/insert-test.red | 5 +++++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index b03db3a5b0..53d4d74ca0 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1374,7 +1374,20 @@ block: context [ table: hash/table ] - if OPTION?(part-arg) [ + values?: all [ + not only? ;-- /only support + any [ + TYPE_OF(value) = TYPE_BLOCK ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_PATH ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_GET_PATH ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_SET_PATH ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_LIT_PATH ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_PAREN ;@@ replace it with: typeset/any-block? + TYPE_OF(value) = TYPE_HASH ;@@ replace it with: typeset/any-block? + ] + ] + + if all [OPTION?(part-arg) values?][ part: either TYPE_OF(part-arg) = TYPE_INTEGER [ int: as red-integer! part-arg int/value @@ -1390,24 +1403,13 @@ block: context [ b/head - src/head ] ] + if OPTION?(dup-arg) [ int: as red-integer! dup-arg cnt: int/value if negative? cnt [return as red-value! blk] ] - values?: all [ - not only? ;-- /only support - any [ - TYPE_OF(value) = TYPE_BLOCK ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_PATH ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_GET_PATH ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_SET_PATH ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_LIT_PATH ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_PAREN ;@@ replace it with: typeset/any-block? - TYPE_OF(value) = TYPE_HASH ;@@ replace it with: typeset/any-block? - ] - ] size: either values? [ src: as red-block! value rs-length? src diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index e12f3e450c..d36f5cbdd0 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1125,6 +1125,7 @@ _hashtable: context [ while [n > 0][ index: indexes + head i: index/value + assert i <> -1 keys/i: keys/i + offset head: head + 1 n: n - 1 diff --git a/tests/source/units/insert-test.red b/tests/source/units/insert-test.red index b1e5930803..9b043158ca 100644 --- a/tests/source/units/insert-test.red +++ b/tests/source/units/insert-test.red @@ -306,6 +306,11 @@ Red [ --test-- "iri5 - issue #3705" --assert 5000 = length? head insert/dup #{} #{20} 5000 + --test-- "iri6 - issue #4335" + t: make hash! [] + repeat i 3 [insert/part t s: "abc" at s i] + forall t [--assert t/1 = "abc"] + ===end-group=== ~~~end-file~~~ From 17deda361c0945d13176d504fff4970eb1dd7de2 Mon Sep 17 00:00:00 2001 From: loziniak Date: Thu, 12 Mar 2020 18:31:32 +0100 Subject: [PATCH 1131/3432] TESTS: random and random/secure --- tests/source/units/integer-test.red | 32 +++++++++++++++++++++++++++-- tests/source/units/series-test.red | 17 +++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/tests/source/units/integer-test.red b/tests/source/units/integer-test.red index c85a37e7b4..99386e5cab 100644 --- a/tests/source/units/integer-test.red +++ b/tests/source/units/integer-test.red @@ -87,8 +87,36 @@ Red [ ===start-group=== "random" --test-- "random1" --assert 1 = random 1 - --test-- "random2" --assert 2 = random/only next [1 2] - --test-- "random3" --assert not negative? random 1 + --test-- "random2" --assert not negative? random 1 + + --test-- "random3" + anded: to integer! #{FFFFFFFF} + loop 10 [ + anded: anded and last-random: random 7FFFFFFFh + ] + all-equal?: anded = last-random + --assert not all-equal? + + --test-- "random4" + anded: to integer! #{FFFFFFFF} + loop 10 [ + anded: anded and last-random: random/secure 7FFFFFFFh + ] + all-equal?: anded = last-random + --assert not all-equal? + + --test-- "random5" + b: copy [] + random/seed 1 loop 10 [append b random 10000] + random/seed 1 loop 10 [append b random 10000] + --assert (copy/part b 10) = (at b 11) + + --test-- "random6" + b: copy [] + random/seed 1 loop 10 [append b random/secure 10000] + random/seed 1 loop 10 [append b random/secure 10000] + --assert (copy/part b 10) <> (at b 11) + ===end-group=== ===start-group=== "round" diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index 6dd8bdf362..6feec1c662 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1841,6 +1841,23 @@ Red [ --assert integer? res --assert 170 = res + --test-- "ser-random-2" + --assert 2 = random/only next [1 2] + + --test-- "ser-random-3" + s: "1234567890" + r: random copy s + --assert s <> r + sum: 0 foreach c r [sum: sum + c] + --assert sum = 525 + + --test-- "ser-random-4" + s: "1234567890" + r: random/secure copy s + --assert s <> r + sum: 0 foreach c r [sum: sum + c] + --assert sum = 525 + ===end-group=== ~~~end-file~~~ From edc1da0b278feb5abcf15be3e86ec5c1c2e8905a Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 14 Mar 2020 19:38:21 +0800 Subject: [PATCH 1132/3432] FIX: no trimming when drawing face/text on Windows (issue #4253) --- modules/view/backends/windows/base.reds | 1 + modules/view/backends/windows/win32.reds | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 1419047060..1a72581cdd 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -681,6 +681,7 @@ update-base-text: func [ GdipCreateStringFormat fflags or 80000000h 0 :format ;-- 1 << 31 = GDI passthrough GdipSetStringFormatAlign format h-align GdipSetStringFormatLineAlign format v-align + GdipSetStringFormatTrimming format 0 ;-- TrimmingNone rect/x: as float32! 0.0 rect/y: as float32! 0.0 diff --git a/modules/view/backends/windows/win32.reds b/modules/view/backends/windows/win32.reds index 76557e1a9b..74c7ad6021 100644 --- a/modules/view/backends/windows/win32.reds +++ b/modules/view/backends/windows/win32.reds @@ -2358,6 +2358,11 @@ XFORM!: alias struct! [ align [integer!] return: [integer!] ] + GdipSetStringFormatTrimming: "GdipSetStringFormatTrimming" [ + format [integer!] + trimming [integer!] + return: [integer!] + ] GdipCreateFontFromDC: "GdipCreateFontFromDC" [ hdc [integer!] font [int-ptr!] From d64a2a34e17557f82ebaf97e8fcb486e397d505b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 14 Mar 2020 12:56:32 +0100 Subject: [PATCH 1133/3432] FEAT: minor code refactoring --- runtime/datatypes/money.reds | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index caffb29ebc..070ed505d1 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -632,13 +632,12 @@ money: context [ blk [red-block!] return: [red-money!] /local - bail [subroutine!] - money fraction [red-money!] - int [red-integer!] - flt [red-float!] - head tail here [red-value!] + bail [subroutine!] + money fraction [red-money!] + int [red-integer!] + flt [red-float!] + head tail here [red-value!] state type length [integer!] - stop? [logic!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] @@ -650,8 +649,6 @@ money: context [ here: head state: S_START - stop?: no - while [state <> S_END][ type: TYPE_OF(here) switch state [ From 8ebda4ca9eb4d13577cf86eeaffcc0ade9138938 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 14 Mar 2020 13:33:17 +0100 Subject: [PATCH 1134/3432] FEAT: add debugging traces --- runtime/datatypes/money.reds | 123 ++++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 070ed505d1..1b8cc581ad 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -78,6 +78,7 @@ money: context [ money [red-money!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/get-sign"]] money/header and SIGN_MASK >> SIGN_OFFSET ] @@ -86,6 +87,8 @@ money: context [ sign [integer!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/set-sign"]] + money/header: money/header and (not SIGN_MASK) or (sign << SIGN_OFFSET) money ] @@ -94,6 +97,7 @@ money: context [ money [red-money!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/flip-sign"]] set-sign money as integer! not as logic! get-sign money ] @@ -102,6 +106,7 @@ money: context [ that [integer!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/collate-signs"]] this + 1 << 4 or (that + 1) ] @@ -111,6 +116,7 @@ money: context [ money [red-money!] return: [byte-ptr!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/get-amount"]] (as byte-ptr! money) + (size? money) - SIZE_BYTES ] @@ -118,6 +124,8 @@ money: context [ amount [byte-ptr!] return: [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/zero-amount?"]] + loop SIZE_BYTES [ unless null-byte = amount/value [return no] amount: amount + 1 @@ -131,6 +139,7 @@ money: context [ that [byte-ptr!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/compare-amounts"]] compare-memory this that SIZE_BYTES ] @@ -139,6 +148,8 @@ money: context [ all? [logic!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/zero-out"]] + money/amount1: either all? [0][money/amount1 and FF000000h] money/amount2: 0 money/amount3: 0 @@ -155,6 +166,8 @@ money: context [ this that [integer!] half [byte!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/shift-left"]] + loop offset [ this: 1 that: this + 1 @@ -179,6 +192,8 @@ money: context [ this that [integer!] half [byte!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/shift-right"]] + loop offset [ this: size that: this - 1 @@ -203,6 +218,8 @@ money: context [ /local bit byte offset [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/get-digit"]] + bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] @@ -217,6 +234,8 @@ money: context [ /local bit byte offset reverse [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/set-digit"]] + bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] @@ -231,6 +250,8 @@ money: context [ /local count [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/count-digits"]] + count: SIZE_DIGITS loop SIZE_BYTES [ either null-byte = amount/value [count: count - 2][ @@ -252,6 +273,8 @@ money: context [ /local delta index1 index2 end this that [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/compare-slices"]] + delta: integer/abs this-count - that-count switch integer/sign? this-count - that-count [ -1 [index1: 1 - delta index2: 1 end: that-count] @@ -283,6 +306,8 @@ money: context [ /local this that borrow difference [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/subtract-slice"]] + this-count: this-count + as integer! this-high? that-count: that-count + as integer! that-high? borrow: 0 @@ -321,6 +346,8 @@ money: context [ index stop [integer!] step [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/make-at"]] + money: as red-money! slot money/header: TYPE_MONEY @@ -371,6 +398,7 @@ money: context [ end [byte-ptr!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] make-at ALLOC_TAIL(parent) sign currency start point end ] @@ -382,6 +410,7 @@ money: context [ end [byte-ptr!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/push"]] make-at stack/push* sign currency start point end ] @@ -397,6 +426,8 @@ money: context [ sign count [integer!] index times [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/form-money"]] + amount: get-amount money sign: sign? money @@ -453,6 +484,8 @@ money: context [ amount limit [byte-ptr!] sign count [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/overflow?"]] + sign: sign? money if zero? sign [return no] @@ -472,10 +505,11 @@ money: context [ sign integer index [integer!] start power digit [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/to-integer"]] + if overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] sign: sign? money - if zero? sign [return 0] amount: get-amount money @@ -503,6 +537,8 @@ money: context [ extra index start [integer!] power digit [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/from-integer"]] + money: zero-out as red-money! stack/push* yes money/header: TYPE_MONEY @@ -543,6 +579,8 @@ money: context [ sign delta [integer!] length error [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/to-float"]] + sign: sign? money if zero? sign [return 0.0] @@ -575,6 +613,8 @@ money: context [ point [byte-ptr!] sign [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/from-float"]] + formed: dtoa/form-float flt SIZE_DIGITS yes point: as byte-ptr! formed @@ -597,6 +637,7 @@ money: context [ money [red-money!] return: [red-binary!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/to-binary"]] binary/load-in get-amount money SIZE_BYTES null ] @@ -609,6 +650,8 @@ money: context [ length [integer!] index [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/from-binary"]] + length: binary/rs-length? bin if length > SIZE_BYTES [length: SIZE_BYTES] @@ -639,6 +682,8 @@ money: context [ head tail here [red-value!] state type length [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/from-block"]] + bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] length: block/rs-length? blk @@ -714,6 +759,8 @@ money: context [ char [byte!] sign [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/from-string"]] + bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] make: [return push sign currency start point tail] @@ -784,6 +831,8 @@ money: context [ /local this-sign that-sign [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/compare-money"]] + ;@@ TBD: take currencies into account this-sign: sign? this @@ -802,6 +851,7 @@ money: context [ money [red-money!] return: [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/negative-money?"]] negative? sign? money ] @@ -809,6 +859,7 @@ money: context [ money [red-money!] return: [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/zero-money?"]] zero? sign? money ] @@ -816,6 +867,7 @@ money: context [ money [red-money!] return: [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/positive-money?"]] positive? sign? money ] @@ -823,6 +875,8 @@ money: context [ money [red-money!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/sign?"]] + either zero-amount? get-amount money [0][ either as logic! get-sign money [-1][+1] ] @@ -834,6 +888,7 @@ money: context [ money [red-money!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/absolute-money"]] set-sign money 0 ] @@ -841,6 +896,7 @@ money: context [ money [red-money!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/negate-money"]] flip-sign money ] @@ -853,6 +909,8 @@ money: context [ this-sign that-sign [integer!] index carry left right sum [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/add-money"]] + this-sign: sign? augend that-sign: sign? addend @@ -904,6 +962,8 @@ money: context [ difference [integer!] lesser? flag [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/subtract-money"]] + this-sign: sign? minuend that-sign: sign? subtrahend @@ -962,6 +1022,8 @@ money: context [ delta index1 index2 index3 [integer!] carry left right other result [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/multiply-money"]] + this-sign: sign? multiplicand that-sign: sign? multiplier @@ -1040,6 +1102,8 @@ money: context [ size overflow digits index [integer!] this-high? that-high? [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/divide-money"]] + this-sign: sign? dividend that-sign: sign? divisor @@ -1135,6 +1199,8 @@ money: context [ op [integer!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/do-math-op"]] + switch op [ OP_ADD [add-money left right] OP_SUB [subtract-money left right] @@ -1159,6 +1225,8 @@ money: context [ left-type [integer!] right-type [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/do-math"]] + left: as red-money! stack/arguments right: left + 1 @@ -1219,6 +1287,8 @@ money: context [ type [integer!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/make"]] + switch TYPE_OF(spec) [ TYPE_BLOCK [from-block as red-block! spec] TYPE_BINARY [from-binary as red-binary! spec] @@ -1235,6 +1305,8 @@ money: context [ integer [red-integer!] float [red-float!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/to"]] + switch TYPE_OF(spec) [ TYPE_MONEY [ return as red-money! spec @@ -1264,6 +1336,7 @@ money: context [ only? [logic!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/random"]] --NOT_IMPLEMENTED-- money ] @@ -1275,6 +1348,7 @@ money: context [ part [integer!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/form"]] form-money money buffer part yes ] @@ -1289,6 +1363,7 @@ money: context [ indent [integer!] return: [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/mold"]] form-money money buffer part no ] @@ -1301,6 +1376,8 @@ money: context [ integer [red-integer!] float [red-float!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/compare"]] + if all [ TYPE_OF(money) <> TYPE_OF(value) any [op = COMP_FIND op = COMP_SAME op = COMP_STRICT_EQUAL] @@ -1326,14 +1403,40 @@ money: context [ compare-money money value ] - absolute: func [return: [red-money!]][absolute-money as red-money! stack/arguments] - negate: func [return: [red-money!]][negate-money as red-money! stack/arguments] + absolute: func [return: [red-money!]][ + #if debug? = yes [if verbose > 0 [print-line "money/absolute"]] + absolute-money as red-money! stack/arguments + ] + + negate: func [return: [red-money!]][ + #if debug? = yes [if verbose > 0 [print-line "money/negate"]] + negate-money as red-money! stack/arguments + ] + + add: func [return: [red-value!]][ + #if debug? = yes [if verbose > 0 [print-line "money/add"]] + do-math OP_ADD + ] - add: func [return: [red-value!]][do-math OP_ADD] - subtract: func [return: [red-value!]][do-math OP_SUB] - multiply: func [return: [red-value!]][do-math OP_MUL] - divide: func [return: [red-value!]][do-math OP_DIV] - remainder: func [return: [red-value!]][do-math OP_REM] + subtract: func [return: [red-value!]][ + #if debug? = yes [if verbose > 0 [print-line "money/subtract"]] + do-math OP_SUB + ] + + multiply: func [return: [red-value!]][ + #if debug? = yes [if verbose > 0 [print-line "money/multiply"]] + do-math OP_MUL + ] + + divide: func [return: [red-value!]][ + #if debug? = yes [if verbose > 0 [print-line "money/divide"]] + do-math OP_DIV + ] + + remainder: func [return: [red-value!]][ + #if debug? = yes [if verbose > 0 [print-line "money/remainder"]] + do-math OP_REM + ] round: func [ value [red-money!] @@ -1346,6 +1449,7 @@ money: context [ half-ceil? [logic!] return: [red-money!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/round"]] --NOT_IMPLEMENTED-- value ] @@ -1354,6 +1458,7 @@ money: context [ money [red-money!] return: [logic!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/even?"]] not odd? money ] @@ -1363,6 +1468,8 @@ money: context [ /local digit [integer!] ][ + #if debug? = yes [if verbose > 0 [print-line "money/odd?"]] + digit: get-digit get-amount money SIZE_INTEGRAL as logic! digit and 1 ] From c239b751ee7bd8e6c1836f4e6d4f015fcbd5add6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 14 Mar 2020 14:51:57 +0100 Subject: [PATCH 1135/3432] FEAT: add comments and assertions --- runtime/datatypes/money.reds | 132 +++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1b8cc581ad..13b71cb498 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -16,15 +16,35 @@ money: context [ ;-- Base -- #enum sizes! [ - SIZE_BYTES: 11 - SIZE_SCALE: 05 - SIZE_AFTER: 05 + SIZE_BYTES: 11 ;-- total number of bytes used to store amount + SIZE_SCALE: 05 ;-- total number of digits (nibbles) used to store scale (fractional part) + SIZE_AFTER: 05 ;-- how many digits to print after a decimal separator ] + SIZE_DIGITS: SIZE_BYTES * 2 ;-- total number of digits (nibbles) used to store amount + SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE ;-- size of an integral part (digits) + + SIZE_UNNORM: SIZE_DIGITS + SIZE_SCALE ;-- size of unnormalized result (digits) + SIZE_BUFFER: (SIZE_UNNORM + (SIZE_UNNORM and 1)) >> 1 ;-- size of memory portion that stores unnormalized result (bytes) + + SIZE_SBYTES: (SIZE_BUFFER + size? integer!) - (SIZE_BUFFER // size? integer!) + SIZE_SSLOTS: SIZE_SBYTES >> 2 ;-- total number of bytes / stack slots allocated to hold unnormalized result + + HIGH_NIBBLE: #"^(0F)" + LOW_NIBBLE: #"^(F0)" + + SIGN_MASK: 4000h ;-- used to get/set sign bit in the header + SIGN_OFFSET: 14 + + MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 + INT32_MAX_DIGITS: 10 + INT32_MIN_AMOUNT: #{00000002147483648FFFFF} ;-- 0xF > 0x9, used to subvert comparison + INT32_MAX_AMOUNT: #{00000002147483647FFFFF} + #enum signs! [ - ;-- -0+ - ;-- -101 - ;-- +1 012 + ;-- sign -0+ + ;-- integer -101 + ;-- +1 012 SIGN_--: 00h SIGN_-0: 01h @@ -52,26 +72,6 @@ money: context [ #define MONEY_OVERFLOW [fire [TO_ERROR(script type-limit) datatype/push TYPE_MONEY]] - SIZE_DIGITS: SIZE_BYTES * 2 - SIZE_INTEGRAL: SIZE_DIGITS - SIZE_SCALE - - SIZE_UNNORM: SIZE_DIGITS + SIZE_SCALE - SIZE_BUFFER: (SIZE_UNNORM + (SIZE_UNNORM and 1)) >> 1 - - SIZE_SBYTES: (SIZE_BUFFER + size? integer!) - (SIZE_BUFFER // size? integer!) - SIZE_SSLOTS: SIZE_SBYTES >> 2 - - HIGH_NIBBLE: #"^(0F)" - LOW_NIBBLE: #"^(F0)" - - SIGN_MASK: 4000h - SIGN_OFFSET: 14 - - MAX_FRACTIONAL: 99999 - INT32_MAX_DIGITS: 10 - INT32_MIN_AMOUNT: #{00000002147483648FFFFF} - INT32_MAX_AMOUNT: #{00000002147483647FFFFF} - ;-- Sign -- get-sign: func [ @@ -145,7 +145,7 @@ money: context [ zero-out: func [ money [red-money!] - all? [logic!] + all? [logic!] ;-- no: keep currency index return: [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/zero-out"]] @@ -220,6 +220,8 @@ money: context [ ][ #if debug? = yes [if verbose > 0 [print-line "money/get-digit"]] + assert positive? index + bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] @@ -235,7 +237,10 @@ money: context [ bit byte offset reverse [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/set-digit"]] - + + assert positive? index + assert all [value >= 0 value <= 9] + bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] @@ -261,7 +266,7 @@ money: context [ amount: amount + 1 ] - either zero? count [1][count] + either zero? count [1][count] ;-- 0 is a single digit ] ;-- Slices -- @@ -315,7 +320,7 @@ money: context [ this: get-digit this-buffer this-count that: either that-count < 1 [0][get-digit that-buffer that-count] - difference: this - that - borrow + difference: this - that - borrow ;-- assumming this >= that borrow: as integer! difference < 0 if as logic! borrow [difference: difference + 10] @@ -359,7 +364,7 @@ money: context [ convert: [ here: here + step until [ - if here/value = #"'" [here: here + step continue] + if here/value = #"'" [here: here + step continue] ;-- skip thousands separators set-digit amount index as integer! here/value - #"0" here: here + step @@ -368,6 +373,7 @@ money: context [ ] ] + ;-- integral part here: either null? point [end][point] limit: start index: SIZE_INTEGRAL @@ -378,6 +384,7 @@ money: context [ if null? point [return money] + ;-- fractional part here: point limit: end index: SIZE_INTEGRAL + 1 @@ -472,7 +479,7 @@ money: context [ times: SIZE_AFTER fill - part - 2 + part - 2 ;-- compensate for $ and . characters ] ;-- Conversion -- @@ -493,7 +500,7 @@ money: context [ count: (count-digits amount) - SIZE_SCALE if count <> INT32_MAX_DIGITS [return count > INT32_MAX_DIGITS] - limit: either negative? sign [INT32_MIN_AMOUNT][INT32_MAX_AMOUNT] + limit: either negative? sign [INT32_MIN_AMOUNT][INT32_MAX_AMOUNT] ;-- worst case: need to compare amount with constant buffers (equal size) positive? compare-amounts amount limit ] @@ -546,7 +553,7 @@ money: context [ set-sign money as integer! negative? int - extra: as integer! int = (1 << 31) + extra: as integer! int = (1 << 31) ;-- if it's an integer minimum, prevent math overflow int: integer/abs int + extra amount: get-amount money @@ -562,7 +569,7 @@ money: context [ index: index - 1 ] - unless zero? extra [ + unless zero? extra [ ;-- compensate for overflow prevention set-digit amount start extra + get-digit amount start ] @@ -585,7 +592,7 @@ money: context [ if zero? sign [return 0.0] - buffer: string/make-at stack/push* SIZE_DIGITS + 6 Latin1 + buffer: string/make-at stack/push* SIZE_DIGITS + 6 Latin1 ;-- max number of digits and -CCC$. form-money money buffer 0 no delta: (string/rs-find buffer as integer! #"$") + 1 @@ -620,7 +627,7 @@ money: context [ point: as byte-ptr! formed until [point: point + 1 point/value = #"."] - if point/2 = #"#" [ + if point/2 = #"#" [ ;-- 1.#NaN, 1.#INF fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float/box flt] ] @@ -629,7 +636,7 @@ money: context [ end: as byte-ptr! formed + length? formed money: push sign null start point end - if all [0.0 <> flt zero? sign? money][MONEY_OVERFLOW] + if all [0.0 <> flt zero? sign? money][MONEY_OVERFLOW] ;-- underflow on too small float value money ] @@ -653,7 +660,7 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/from-binary"]] length: binary/rs-length? bin - if length > SIZE_BYTES [length: SIZE_BYTES] + if length > SIZE_BYTES [length: SIZE_BYTES] ;-- take only first SIZE_BYTES bytes into account head: binary/rs-head bin index: 1 @@ -778,6 +785,7 @@ money: context [ head: string/rs-head str here: head + ;-- sign sign: no switch here/value [ #"-" [here: here + 1 sign: yes] @@ -785,6 +793,7 @@ money: context [ default [0] ] + ;-- currency code currency: here while [not any [end? here/value = #"$"]][here: here + 1] @@ -798,24 +807,27 @@ money: context [ start: here - as integer! here/value <> #"$" here: start + 1 + ;-- leading zeroes until [here: here + 1 any [here = tail here/value <> #"0"]] if any [here = tail dot?][here: here - 1] digits: here + ;-- integral part with optional thousands separators until [ if here/value = #"'" [here: here + 1 continue] - unless digit? [bail] + unless digit? [bail] ;-- forbid leading decimal separator here: here + 1 any [end? dot?] ] - if any [here > tail all [dot? here + 1 = tail]][bail] + if any [here > tail all [dot? here + 1 = tail]][bail] ;-- forbid trailing decimal separator point: here if SIZE_INTEGRAL < as integer! point - digits [bail] if here = tail [point: null make] here: here + 1 + ;-- fractional part until [unless digit? [bail] here: here + 1 end?] if here <> tail [bail] @@ -844,7 +856,7 @@ money: context [ default [return integer/sign? this-sign - that-sign] ] - integer/sign? compare-amounts get-amount this get-amount that + integer/sign? compare-amounts get-amount this get-amount that ;-- must return strictly -1, 0 or +1 ] negative-money?: func [ @@ -889,7 +901,7 @@ money: context [ return: [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/absolute-money"]] - set-sign money 0 + set-sign money 0 ;-- 0: clear sign bit ] negate-money: func [ @@ -900,7 +912,7 @@ money: context [ flip-sign money ] - add-money: func [ + add-money: func [ ;-- long addition augend [red-money!] addend [red-money!] return: [red-money!] @@ -928,7 +940,7 @@ money: context [ this-amount: get-amount augend that-amount: get-amount addend - if (get-digit this-amount 1) + (get-digit that-amount 1) > 9 [MONEY_OVERFLOW] + if (get-digit this-amount 1) + (get-digit that-amount 1) > 9 [MONEY_OVERFLOW] ;-- if sum of two most significant digits overflows index: SIZE_DIGITS carry: 0 @@ -951,7 +963,7 @@ money: context [ augend ] - subtract-money: func [ + subtract-money: func [ ;-- long subtraction minuend [red-money!] subtrahend [red-money!] return: [red-money!] @@ -1011,7 +1023,7 @@ money: context [ set-sign minuend sign ] - multiply-money: func [ + multiply-money: func [ ;-- long multiplication multiplicand [red-money!] multiplier [red-money!] return: [red-money!] @@ -1042,7 +1054,7 @@ money: context [ this-count: count-digits this-amount that-count: count-digits that-amount - if (this-count + that-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] + if (this-count + that-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload product: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES @@ -1074,22 +1086,22 @@ money: context [ index1: index1 - 1 ] - unless zero? get-digit product 1 [MONEY_OVERFLOW] + unless zero? get-digit product 1 [MONEY_OVERFLOW] ;-- overflowed into most-significant digit shift-right product SIZE_SBYTES SIZE_SCALE product: product + SIZE_BUFFER - SIZE_BYTES - if zero-amount? product [MONEY_OVERFLOW] + if zero-amount? product [MONEY_OVERFLOW] ;-- got zero product from non-zero factors copy-memory this-amount product SIZE_BYTES set-sign multiplicand sign ] - divide-money: func [ + divide-money: func [ ;-- shift-and-subtract algorithm dividend [red-money!] divisor [red-money!] - remainder? [logic!] - only? [logic!] + remainder? [logic!] ;-- yes: calculate remainder instead + only? [logic!] ;-- yes: don't approximate fractional part return: [red-money!] /local shift increment subtract [subroutine!] @@ -1124,7 +1136,7 @@ money: context [ this-count: count-digits this-amount that-count: count-digits that-amount - if this-count + (SIZE_SCALE + 1 - that-count) > SIZE_DIGITS [MONEY_OVERFLOW] + if this-count + (SIZE_SCALE + 1 - that-count) > SIZE_DIGITS [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload size: SIZE_DIGITS overflow: SIZE_SBYTES << 1 - SIZE_DIGITS @@ -1185,8 +1197,8 @@ money: context [ quotient: quotient + SIZE_SBYTES - SIZE_BYTES this-amount: hold ] - if zero-amount? quotient [MONEY_OVERFLOW] - unless zero? get-digit buffer overflow [MONEY_OVERFLOW] + if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero dividend + unless zero? get-digit buffer overflow [MONEY_OVERFLOW] ;-- overflowed into most-significant digit copy-memory this-amount quotient SIZE_BYTES ] @@ -1209,7 +1221,7 @@ money: context [ OP_REM [divide-money left right yes no] default [ fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] - left + left ;-- pass compiler's type checking ] ] ] @@ -1276,7 +1288,7 @@ money: context [ if all [op = OP_DIV left-type = TYPE_MONEY right-type = TYPE_MONEY][ result: as red-value! float/box to-float as red-money! result ] - SET_RETURN(result) + SET_RETURN(result) ;-- some of the operations swap their argument slots ] ;-- Actions -- @@ -1324,7 +1336,7 @@ money: context [ ] default [ fire [TO_ERROR(script bad-to-arg) datatype/push TYPE_MONEY spec] - as red-money! proto + as red-money! proto ;-- pass compiler's type checking ] ] ] @@ -1470,7 +1482,7 @@ money: context [ ][ #if debug? = yes [if verbose > 0 [print-line "money/odd?"]] - digit: get-digit get-amount money SIZE_INTEGRAL + digit: get-digit get-amount money SIZE_INTEGRAL ;-- check if least significant bit is set as logic! digit and 1 ] From 0b5a4df3e1b5294d10d6d8c6201caeb43a5b2000 Mon Sep 17 00:00:00 2001 From: loziniak Date: Sun, 15 Mar 2020 23:25:06 +0100 Subject: [PATCH 1136/3432] TESTS: dummy change to re-run tests by GitHub CI --- tests/source/units/series-test.red | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index 6feec1c662..096c897fb5 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1836,6 +1836,7 @@ Red [ ===end-group=== ===start-group=== "random" + --test-- "ser-random-1" res: random/only #{AA} --assert integer? res From 4a725f70316ebd71707bbe2d9e2cea4e80bc1798 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 16 Mar 2020 19:56:18 +0100 Subject: [PATCH 1137/3432] FEAT: supports money! literals in compiler's lexer. --- lexer.r | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index fb425e9a69..8b98f13d1b 100644 --- a/lexer.r +++ b/lexer.r @@ -451,7 +451,12 @@ lexer: context [ decimal-number-rule opt [#"%" e: (type: issue!)] sticky-word-rule ] - + + money-rule: [ + (neg?: no) opt [#"-" (neg?: yes) | #"+"] #"$" + s: digit any [digit | #"'" digit] opt [[dot | comma] 1 5 digit] e: + ] + block-rule: [#"[" (stack/allocate block! 10) any-value #"]" (value: stack/pop block!)] paren-rule: [#"(" (stack/allocate paren! 10) any-value #")" (value: stack/pop paren!)] @@ -632,6 +637,7 @@ lexer: context [ | block-rule (stack/push value) | paren-rule (stack/push value) | string-rule (stack/push load-string s e) + | money-rule (stack/push load-money copy/part s e) | map-rule (stack/push value) | issue-rule (stack/push to issue! copy/part s e) ] @@ -816,6 +822,13 @@ lexer: context [ d1 + (w - 1 * 7 + (either wd < 5 [1][8]) - wd) ] + load-money: func [s [string!] /local dec pos][ + dec: either pos: find s dot [remove pos length? pos][0] + insert/dup tail s #"0" 5 - dec + insert/dup s #"0" 22 - length? s + append join make issue! 1 + length? s #"$" s + ] + load-tuple: func [s [string!] /local new byte p e][ new: join make issue! 1 + length? s #"~" byte: [p: 1 3 digit e: (append new skip to-hex load copy/part p e 6)] From b0bc57ec2a4db774d3d79dccef11dcfbb500f214 Mon Sep 17 00:00:00 2001 From: loziniak Date: Mon, 16 Mar 2020 22:35:18 +0100 Subject: [PATCH 1138/3432] TESTS: fix 'sum word overwrite --- tests/source/units/series-test.red | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/source/units/series-test.red b/tests/source/units/series-test.red index 096c897fb5..7e1cff0128 100644 --- a/tests/source/units/series-test.red +++ b/tests/source/units/series-test.red @@ -1849,15 +1849,15 @@ Red [ s: "1234567890" r: random copy s --assert s <> r - sum: 0 foreach c r [sum: sum + c] - --assert sum = 525 + summed: 0 foreach c r [summed: summed + c] + --assert summed = 525 --test-- "ser-random-4" s: "1234567890" r: random/secure copy s --assert s <> r - sum: 0 foreach c r [sum: sum + c] - --assert sum = 525 + summed: 0 foreach c r [summed: summed + c] + --assert summed = 525 ===end-group=== From 1849d01ce35f63f00e40bf3d8b6a7f2ea6f7e919 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 18:34:07 +0100 Subject: [PATCH 1139/3432] TESTS: add a few more tests --- tests/source/environment/functions-test.red | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/source/environment/functions-test.red b/tests/source/environment/functions-test.red index 3929887897..ded2b16e0b 100644 --- a/tests/source/environment/functions-test.red +++ b/tests/source/environment/functions-test.red @@ -232,6 +232,8 @@ Red [ --assert 100000010 = math [10 + 10 ** 2 ** 3] --assert 10 = math [10 + 10 % 2] --assert 1 = math [8 / 5 % 2] + --assert 33 = math [1 + 2 ** 3 * 4] + --assert 4097 = math [1 + 2 ** (3 * 4)] ===end-group=== ===start-group=== "charset tests" From 9f4ca8f55418d86d4215666368237c2400a2e39f Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Mar 2020 19:01:52 +0100 Subject: [PATCH 1140/3432] FEAT: compiler's lexer full money! syntax support. --- lexer.r | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lexer.r b/lexer.r index 8b98f13d1b..8254173515 100644 --- a/lexer.r +++ b/lexer.r @@ -453,8 +453,8 @@ lexer: context [ ] money-rule: [ - (neg?: no) opt [#"-" (neg?: yes) | #"+"] #"$" - s: digit any [digit | #"'" digit] opt [[dot | comma] 1 5 digit] e: + (neg?: no) opt [#"-" (neg?: yes) | #"+"] + s: opt [3 alpha] #"$" digit any [digit | #"'" digit] opt [[dot | comma] 1 5 digit] e: ] block-rule: [#"[" (stack/allocate block! 10) any-value #"]" (value: stack/pop block!)] @@ -627,6 +627,7 @@ lexer: context [ | decimal-rule (stack/push load-decimal copy/part s e) | tag-rule (stack/push to tag! copy/part s e) | rawstr-rule (stack/push value) + | money-rule (stack/push load-money s e neg?) | word-rule (stack/push to type value) | lit-word-rule (stack/push to type value) | get-word-rule (stack/push to type value) @@ -637,7 +638,6 @@ lexer: context [ | block-rule (stack/push value) | paren-rule (stack/push value) | string-rule (stack/push load-string s e) - | money-rule (stack/push load-money copy/part s e) | map-rule (stack/push value) | issue-rule (stack/push to issue! copy/part s e) ] @@ -822,10 +822,17 @@ lexer: context [ d1 + (w - 1 * 7 + (either wd < 5 [1][8]) - wd) ] - load-money: func [s [string!] /local dec pos][ + load-money: func [s [string!] e [string!] neg? [logic!] /local cur dec pos][ + if s/4 = #"$" [ + cur: uppercase copy/part s 3 + s: skip s 3 + ] + s: copy/part next s e dec: either pos: find s dot [remove pos length? pos][0] insert/dup tail s #"0" 5 - dec insert/dup s #"0" 22 - length? s + insert s pick "-+" neg? + insert s any [cur "..."] append join make issue! 1 + length? s #"$" s ] From 275eb64244e496ada4cfbbbc400b475830ca4924 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Mar 2020 19:02:53 +0100 Subject: [PATCH 1141/3432] FEAT: compiler support for standalone literal money! values. --- compiler.r | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/compiler.r b/compiler.r index 0a8ef71d91..3bc689b497 100644 --- a/compiler.r +++ b/compiler.r @@ -241,6 +241,16 @@ red: context [ clear next mark ;-- remove code at "upper" level ] + to-nibbles: func [src [string!] /local out][ + out: make string! 11 + foreach [high low] src [ + append out to char! add + shift/left (to integer! high - #"0") 4 + to integer! low - #"0" + ] + out + ] + any-function?: func [value [word!]][ find [native! action! op! function! routine!] value ] @@ -281,6 +291,7 @@ red: context [ unicode-char?: func [value][value/1 = #"'"] float-special?: func [value][value/1 = #"."] tuple-value?: func [value][value/1 = #"~"] + money-value?: func [value][value/1 = #"$"] percent-value?: func [value][#"%" = last value] date-special?: func [value][all [block? value value/1 = #!date!]] @@ -1679,7 +1690,7 @@ red: context [ comp-literal: func [ /inactive /with val - /local value char? special? percent? map? tuple? dt-special? name w make-block type idx zone + /local value char? special? percent? map? tuple? money? dt-special? name w make-block type idx zone ][ make-block: [ value: to block! value @@ -1701,6 +1712,7 @@ red: context [ special?: float-special? value percent?: percent-value? value tuple?: tuple-value? value + money?: money-value? value ] ] scalar? :value @@ -1742,6 +1754,13 @@ red: context [ emit to integer! copy/part skip bin -8 -4 insert-lf -5 ] + money? [ + emit 'money/push + value: to string! next value + emit value/4 = #"-" + emit any [all [value/1 = #"." 'null] copy/part value 3] + emit to-nibbles copy skip value 4 + ] find [refinement! issue!] type?/word :value [ add-symbol w: to word! form value type: to word! form type? :value From b7ad86752253e0f937e16f78d558f59bf75852dc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 17 Mar 2020 20:26:15 +0100 Subject: [PATCH 1142/3432] FEAT: adds standard currencies codes in system object. --- environment/system.red | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/environment/system.red b/environment/system.red index dbbb5bed44..9e542a686e 100644 --- a/environment/system.red +++ b/environment/system.red @@ -310,6 +310,22 @@ system: context [ days: [ "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday" ] + + currencies: object [ + ;-- ISO currencies + BTC, ETH, RED + base: [ + AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BTC BGN BHD BIF BMD BND BOB BRL BSD + BTN BWP BYN BZD CAD CDF CHF CKD CLP CNY COP CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN + ETB ETH EUR FJD FKP FOK GBP GEL GGP GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS + IMP INR IQD IRR ISK JEP JMD JOD JPY KES KGS KHR KID KMF KPW KRW KWD KYD KZT LAK LBP LKR + LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRU MUR MVR MWK MXN MYR MZN NAD NGN NIO NOK NPR + NZD OMR PAB PEN PGK PHP PKR PLN PND PRB PYG QAR RED RON RSD RUB RWF SAR SBD SCR SDG SEK + SGD SHP SLL SLS SOS SRD SSP STN SYP SZL THB TJS TMT TND TOP TRY TTD TVD TWD TZS UAH UGX + USD UYU UZS VES VND VUV WST CFA XAF XCD XOF CFP XPF YER ZAR ZMW + ] + ;-- User-provided currencies + extra: none + ] ] options: context [ @@ -326,6 +342,7 @@ system: context [ quiet: false binary-base: 16 decimal-digits: 15 + money-digits: 2 module-paths: make block! 1 file-types: none From ef5afcc3d123759249a08d8ff996ab9264104913 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 17:35:39 +0100 Subject: [PATCH 1143/3432] FIX: issue #4325 (Runaway binary to integer conversion) --- runtime/datatypes/integer.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index ca1984af56..6868ed1008 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -78,18 +78,20 @@ integer: context [ return: [integer!] /local s [series!] + hd [byte-ptr!] p [byte-ptr!] len [integer!] i [integer!] factor [integer!] ][ s: GET_BUFFER(bin) - len: (as-integer s/tail - s/offset) + bin/head + hd: binary/rs-head bin + len: binary/rs-length? bin if len > 4 [len: 4] ;-- take first 32 bits only i: 0 factor: 0 - p: (as byte-ptr! s/offset) + bin/head + len - 1 + p: hd + len - 1 loop len [ i: i + ((as-integer p/value) << factor) From 0c56da0da2f82bcac641f6227176f180308fee75 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 17:36:03 +0100 Subject: [PATCH 1144/3432] TESTS: extend integer conversion tests --- tests/source/units/convert-test.red | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/source/units/convert-test.red b/tests/source/units/convert-test.red index 7c9912227c..1494ca1b6f 100644 --- a/tests/source/units/convert-test.red +++ b/tests/source/units/convert-test.red @@ -92,6 +92,13 @@ Red [ --test-- "to-integer!-21" --assert 32400 == to integer! 09:00 --test-- "to-integer!-22" --assert 86399 == to integer! 23:59:59 --test-- "to-integer!-23" --assert 86400 == to integer! 23:59:59.999999 + --test-- "to-integer!-24" --assert 0 == to integer! #{} + --test-- "to-integer!-25" --assert 255 == to integer! #{FF} + --test-- "to-integer!-26" --assert -559038737 == to integer! #{DEADBEEF BADCAFEE} + --test-- "to-integer!-27" ;-- #4325 + --assert 0 == to integer! next #{} + --assert 255 == to integer! next #{00FF} + --assert -559038737 == to integer! skip #{BADCAFEE DEADBEEF} 4 ===end-group=== From 6381da99d6c8ff6bbe58742d8c4f4ffe3150d19c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 18:50:20 +0100 Subject: [PATCH 1145/3432] FIX: issue #4272 (TO-BINARY with ANY-LIST argument behaves incorrectly except for BLOCKs) --- runtime/datatypes/binary.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index c9dd9b497c..bdad579908 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -1113,6 +1113,7 @@ binary: context [ data [byte-ptr!] s [series!] s2 [series!] + type [integer!] int-value [integer!] dup-n [integer!] cnt [integer!] @@ -1155,8 +1156,9 @@ binary: context [ (as-integer s/tail - s/offset) >> (log-b GET_UNIT(s)) = bin/head append? ] - - either TYPE_OF(value) = TYPE_BLOCK [ ;@@ replace it with: typeset/any-block? + + type: TYPE_OF(value) + either ANY_LIST(type) [ src: as red-block! value s2: GET_BUFFER(src) cell: s2/offset + src/head From 9395e4407df2ab43adb6e5674a2e58a31561d511 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 18:51:41 +0100 Subject: [PATCH 1146/3432] FIX: consistent naming of type-checking macro --- runtime/datatypes/binary.reds | 2 +- runtime/datatypes/url.reds | 4 ++-- runtime/macros.reds | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index bdad579908..9746f7b770 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -1158,7 +1158,7 @@ binary: context [ ] type: TYPE_OF(value) - either ANY_LIST(type) [ + either ANY_LIST?(type) [ src: as red-block! value s2: GET_BUFFER(src) cell: s2/offset + src/head diff --git a/runtime/datatypes/url.reds b/runtime/datatypes/url.reds index 81faa62b88..f1035beba3 100644 --- a/runtime/datatypes/url.reds +++ b/runtime/datatypes/url.reds @@ -89,7 +89,7 @@ url: context [ #if debug? = yes [if verbose > 0 [print-line "url/make"]] type2: TYPE_OF(spec) - either all [type = TYPE_URL ANY_LIST(type2)][ ;-- file! inherits from url! + either all [type = TYPE_URL ANY_LIST?(type2)][ ;-- file! inherits from url! to proto spec type ][ as red-url! string/make as red-string! proto spec type @@ -166,7 +166,7 @@ url: context [ #if debug? = yes [if verbose > 0 [print-line "url/to"]] type2: TYPE_OF(spec) - either all [type = TYPE_URL ANY_LIST(type2)][ ;-- file! inherits from url! + either all [type = TYPE_URL ANY_LIST?(type2)][ ;-- file! inherits from url! buffer: string/make-at proto 16 1 buffer/header: TYPE_URL diff --git a/runtime/macros.reds b/runtime/macros.reds index c0a17e50c4..8187817bf3 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -426,7 +426,7 @@ Red/System [ ] ] -#define ANY_LIST(type) [ +#define ANY_LIST?(type) [ any [ type = TYPE_BLOCK type = TYPE_PAREN From 788281be24b013921ed0062c0dbc24c62b9e61bb Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 17 Mar 2020 18:57:45 +0100 Subject: [PATCH 1147/3432] TESTS: binary conversion tests for issue #4272 --- tests/source/units/convert-test.red | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/source/units/convert-test.red b/tests/source/units/convert-test.red index 1494ca1b6f..72c19a2221 100644 --- a/tests/source/units/convert-test.red +++ b/tests/source/units/convert-test.red @@ -463,6 +463,9 @@ Red [ --assert #{00} = to binary! make bitset! #{00} --test-- "issue #3636" --assert 97 = pick to binary! append/dup a: "" "a" 1100000 1 + --test-- "issue #4272" + --assert #{DEADBEEF} = to binary! quote (222 173 190 239) + --assert #{BADCAFEE} = to binary! make hash! [186 220 175 238] ===end-group=== ===start-group=== "to-block!" --test-- "to-block!-char!" From 832db052b199913c475d7049333457f80808d22e Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 18 Mar 2020 15:17:15 +0800 Subject: [PATCH 1148/3432] FIX: issue #4342 ([View] `on-over` spams the queue when layout changes within the actor) --- modules/view/backends/windows/events.reds | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index d567fd6d97..62120f4ed7 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -32,6 +32,8 @@ flags-blk/head: 0 flags-blk/node: alloc-cells 4 flags-blk/header: TYPE_BLOCK +last-mouse-pt: 0 + char-keys: [ 1000C400h C0FF0080h E0FFFF7Fh 0000F7FFh 00000000h 3F000000h 1F000080h 00FC7F38h ] @@ -1450,6 +1452,9 @@ process: func [ switch msg/msg [ WM_MOUSEMOVE [ lParam: msg/lParam + if last-mouse-pt = lParam [return EVT_NO_DISPATCH] + last-mouse-pt: lParam + x: WIN32_LOWORD(lParam) y: WIN32_HIWORD(lParam) if any [ From e9d675419c462ad038fc2d92a26f4257dcfa1cbe Mon Sep 17 00:00:00 2001 From: hiiamboris Date: Sat, 14 Mar 2020 17:33:41 +0300 Subject: [PATCH 1149/3432] FIX: issue #4338 (Asynchronous keyboard handler discards mod keys on Windows) --- modules/view/backends/windows/events.reds | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 62120f4ed7..9386d026cc 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -417,15 +417,15 @@ check-extra-keys: func [ key [integer!] ][ key: 0 - if (GetAsyncKeyState VK_CONTROL) and 8000h <> 0 [key: EVT_FLAG_CTRL_DOWN] - if (GetAsyncKeyState VK_SHIFT) and 8000h <> 0 [key: key or EVT_FLAG_SHIFT_DOWN] - if (GetAsyncKeyState VK_MENU) and 8000h <> 0 [key: key or EVT_FLAG_MENU_DOWN] ;-- ALT key + if (GetKeyState VK_CONTROL) and 8000h <> 0 [key: EVT_FLAG_CTRL_DOWN] + if (GetKeyState VK_SHIFT) and 8000h <> 0 [key: key or EVT_FLAG_SHIFT_DOWN] + if (GetKeyState VK_MENU) and 8000h <> 0 [key: key or EVT_FLAG_MENU_DOWN] ;-- ALT key unless only? [ - if (GetAsyncKeyState 01h) and 8000h <> 0 [key: key or EVT_FLAG_DOWN] ;-- VK_LBUTTON - if (GetAsyncKeyState 02h) and 8000h <> 0 [key: key or EVT_FLAG_ALT_DOWN] ;-- VK_RBUTTON - if (GetAsyncKeyState 04h) and 8000h <> 0 [key: key or EVT_FLAG_MID_DOWN] ;-- VK_MBUTTON - if (GetAsyncKeyState 05h) and 8000h <> 0 [key: key or EVT_FLAG_AUX_DOWN] ;-- VK_XBUTTON1 + if (GetKeyState 01h) and 8000h <> 0 [key: key or EVT_FLAG_DOWN] ;-- VK_LBUTTON + if (GetKeyState 02h) and 8000h <> 0 [key: key or EVT_FLAG_ALT_DOWN] ;-- VK_RBUTTON + if (GetKeyState 04h) and 8000h <> 0 [key: key or EVT_FLAG_MID_DOWN] ;-- VK_MBUTTON + if (GetKeyState 05h) and 8000h <> 0 [key: key or EVT_FLAG_AUX_DOWN] ;-- VK_XBUTTON1 ] key ] From e80c29c8eb71cddbfe12cf734c2d97bd05ef8cb9 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 18 Mar 2020 19:36:57 +0800 Subject: [PATCH 1150/3432] FIX: issue #4344 ([View] Layered windows fail to update their size erratically) --- modules/view/backends/windows/base.reds | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 1a72581cdd..5a0b9e7d10 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -182,6 +182,19 @@ clip-layered-window: func [ flags [integer!] ][ flags: GetWindowLong hWnd wc-offset - 12 + if all [ ;-- delete window clip region + BASE_FACE_CLIPPED and flags <> 0 + zero? x + zero? y + size/width = new-width + size/height = new-height + ][ + SetWindowRgn hWnd null false + child: as handle! GetWindowLong hWnd wc-offset - 20 + if child <> null [SetWindowRgn child null false] + SetWindowLong hWnd wc-offset - 12 flags and FFFFFFFEh + exit + ] if any [ not zero? x not zero? y @@ -198,13 +211,6 @@ clip-layered-window: func [ SetWindowRgn child rgn false ] ] - if all [ - BASE_FACE_CLIPPED and flags <> 0 - zero? x - zero? y - size/width = new-width - size/height = new-height - ][SetWindowLong hWnd wc-offset - 12 flags and FFFFFFFEh] ] process-layered-region: func [ From 47d156eb1c76eca0d9958fefafbf067d506b06de Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 13:35:39 +0100 Subject: [PATCH 1151/3432] FIX: issue #4194 ([Parse] matching VECTOR! with INTO) --- runtime/parse.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index c64b2743f2..fbdd4fb782 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -1619,7 +1619,7 @@ parser: context [ ] value: block/rs-head input type: TYPE_OF(value) - either all [ANY_SERIES?(type) type <> TYPE_IMAGE][ + either all [ANY_SERIES?(type) type <> TYPE_IMAGE type <> TYPE_VECTOR][ input: as red-series! block/rs-append series value min: R_NONE type: R_INTO From 0ff177cac28ef5794cc953aa1cf727e148944be3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 13:36:11 +0100 Subject: [PATCH 1152/3432] TESTS: add Parse tests for issue #4194 --- tests/source/units/parse-test.red | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 62ec167d78..136b9eac2d 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2711,7 +2711,6 @@ Red [ parse "bx" [some [not "b" | skip]] --assert true ;-- just check that parse finishes - --test-- "#3357" parse x3357: [][insert ('foo)] --assert x3357 = [foo] @@ -2739,7 +2738,12 @@ Red [ --assert error? try [parse [][copy x4318]] --assert error? try [parse [][set x4318]] --assert zero? x4318 - + + --test-- "#4194" + i4194: make image! 0x0 + v4194: make vector! 0 + --assert not parse reduce [i4194][into []] + --assert not parse reduce [v4194][into []] ===end-group=== ~~~end-file~~~ From 54bd1141b3fea658f2a8d0aead25b9cb4c70af17 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 14:34:19 +0100 Subject: [PATCH 1153/3432] FIX: issue #4200 ([Parse] CHANGE does not work properly with WORD! values) --- runtime/parse.reds | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index c64b2743f2..1fac4d6ab7 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -1719,7 +1719,6 @@ parser: context [ copy-cell as red-value! input base ;@@ remove once OPTION? fixed input/head: new/head PARSE_SAVE_SERIES - if TYPE_OF(value) = TYPE_WORD [value: _context/get as red-word! value] actions/change input value base as-logic max null if s-top <> null [stack/top: s-top] PARSE_RESTORE_SERIES From a1719d1ff36558ccadcb0b0a6cb0e522c1fbdfd3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 14:34:53 +0100 Subject: [PATCH 1154/3432] TESTS: add Parse tests for issue #4200 --- tests/source/units/parse-test.red | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 62ec167d78..4e978edbf0 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2739,6 +2739,23 @@ Red [ --assert error? try [parse [][copy x4318]] --assert error? try [parse [][set x4318]] --assert zero? x4318 + + --test-- "#4200" + x4200-word: 'foo + x4200-block: [] + x4200-mark: x4200-block + + parse x4200-block [x4200-mark: change x4200-mark x4200-word] + --assert x4200-block = [foo] + clear x4200-block + + parse x4200-block [x4200-mark: change x4200-mark (x4200-word)] + --assert x4200-block = [foo] + clear x4200-block + + parse x4200-block [x4200-mark: change x4200-mark ('foo)] + --assert x4200-block = [foo] + clear x4200-block ===end-group=== From 2e8bd4e1c343b8953af7ebb97de2b7afcf64c151 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 14:52:51 +0100 Subject: [PATCH 1155/3432] TESTS: cover case with literal value (issue #4200) --- tests/source/units/parse-test.red | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 4e978edbf0..5bf2254b50 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2746,15 +2746,19 @@ Red [ x4200-mark: x4200-block parse x4200-block [x4200-mark: change x4200-mark x4200-word] - --assert x4200-block = [foo] + --assert x4200-block = [foo] ;-- word's value clear x4200-block parse x4200-block [x4200-mark: change x4200-mark (x4200-word)] - --assert x4200-block = [foo] + --assert x4200-block = [foo] ;-- result of expression clear x4200-block parse x4200-block [x4200-mark: change x4200-mark ('foo)] - --assert x4200-block = [foo] + --assert x4200-block = [foo] ;-- result of expression + clear x4200-block + + parse x4200-block [x4200-mark: change x4200-mark #foo] + --assert x4200-block = [#foo] ;-- literal value clear x4200-block ===end-group=== From 50c252762b7a00ff0f4183e1784672946fc8a66a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 14:57:35 +0100 Subject: [PATCH 1156/3432] FIX: ignore image! case for now, to make tests pass on all platforms. --- tests/source/units/parse-test.red | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 136b9eac2d..600dccaa77 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2740,10 +2740,7 @@ Red [ --assert zero? x4318 --test-- "#4194" - i4194: make image! 0x0 - v4194: make vector! 0 - --assert not parse reduce [i4194][into []] - --assert not parse reduce [v4194][into []] + --assert not parse reduce [make vector! 0][into []] ===end-group=== ~~~end-file~~~ From e7edc30d63200f1cc5679636e6c1c50ca55e43e8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 18 Mar 2020 15:14:11 +0100 Subject: [PATCH 1157/3432] FIX: freezing on booting the GUI console. --- environment/system.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/system.red b/environment/system.red index 9e542a686e..4a17f4acc9 100644 --- a/environment/system.red +++ b/environment/system.red @@ -311,7 +311,7 @@ system: context [ "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday" ] - currencies: object [ + currencies: context [ ;-- ISO currencies + BTC, ETH, RED base: [ AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BTC BGN BHD BIF BMD BND BOB BRL BSD From a0c9f1a0eef6a9b482c5ba9d1a2556f593fd90bc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 17:00:43 +0100 Subject: [PATCH 1158/3432] FIX: regenerate lexer table --- runtime/lexer-transitions.reds | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 2af2301f8d..9ccc864065 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -100,10 +100,9 @@ Red/System [ ] type-table: #{ 000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F -2B2B25253131310B0F0B2C2C2C2C0F0F0C0F0F10092D190B0F0F140F00002200 -000000000700000000070F140B130A0829260C0C272F252B312C092D0B07 -} - transitions: #{ +2B2B25253131310B0F0B2C2C2C2C0F0F0C0F0F100F092D190B0F0F140F000022 +00000000000700000000070F140B130A0829260C0C272F252B312C092D0B07 +} transitions: #{ 0000181840414243443F02113131323232322732270F3F2A3232063F013F2F24 2E2E3F32323F3E01490101010101010101010101010101010101010101010101 0101010101010101010101013F3E020202020202020202024A02020202020202 From a5be62643738bc23b5f70e6af1a57d463be7663b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 17:01:12 +0100 Subject: [PATCH 1159/3432] FIX: temporary workaround for pending bug --- environment/system.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/system.red b/environment/system.red index 4a17f4acc9..75f0801ff5 100644 --- a/environment/system.red +++ b/environment/system.red @@ -319,7 +319,7 @@ system: context [ ETB ETH EUR FJD FKP FOK GBP GEL GGP GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS IMP INR IQD IRR ISK JEP JMD JOD JPY KES KGS KHR KID KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRU MUR MVR MWK MXN MYR MZN NAD NGN NIO NOK NPR - NZD OMR PAB PEN PGK PHP PKR PLN PND PRB PYG QAR RED RON RSD RUB RWF SAR SBD SCR SDG SEK +;@@ NZD OMR PAB PEN PGK PHP PKR PLN PND PRB PYG QAR RED RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLL SLS SOS SRD SSP STN SYP SZL THB TJS TMT TND TOP TRY TTD TVD TWD TZS UAH UGX USD UYU UZS VES VND VUV WST CFA XAF XCD XOF CFP XPF YER ZAR ZMW ] From 365f812bf94c84e31b5b251460f4ee1fd76af760 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 17:01:57 +0100 Subject: [PATCH 1160/3432] FEAT: implement PUSH for compiler support --- runtime/datatypes/money.reds | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 13b71cb498..bf07bbdcef 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -337,11 +337,11 @@ money: context [ make-at: func [ slot [red-value!] - sign [logic!] - currency [byte-ptr!] - start [byte-ptr!] - point [byte-ptr!] - end [byte-ptr!] + sign [logic!] ;-- yes: negative + currency [byte-ptr!] ;-- can be null + start [byte-ptr!] ;-- $ sign + point [byte-ptr!] ;-- can be null if fractional part is not present + end [byte-ptr!] ;-- points past the money literal return: [red-money!] /local convert [subroutine!] @@ -410,22 +410,28 @@ money: context [ ] push: func [ - sign [logic!] - currency [byte-ptr!] - start [byte-ptr!] - point [byte-ptr!] - end [byte-ptr!] - return: [red-money!] + sign [logic!] ;-- yes: negative + currency [c-string!] ;-- can be null + amount [c-string!] ;-- always SIZE_BYTES bytes + return: [red-money!] + /local + money [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/push"]] - make-at stack/push* sign currency start point end + + money: as red-money! set-type stack/push* TYPE_MONEY + copy-memory get-amount money as byte-ptr! amount SIZE_BYTES + ;@@ TBD: take currency into account + set-sign money as integer! sign + + money ] form-money: func [ money [red-money!] buffer [red-string!] part [integer!] - group? [logic!] + group? [logic!] ;-- yes: decorate amount with thousand's separators return: [integer!] /local fill [subroutine!] @@ -635,7 +641,7 @@ money: context [ start: as byte-ptr! either sign [formed][formed - 1] end: as byte-ptr! formed + length? formed - money: push sign null start point end + money: make-at stack/push* sign null start point end if all [0.0 <> flt zero? sign? money][MONEY_OVERFLOW] ;-- underflow on too small float value money ] @@ -769,7 +775,7 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/from-string"]] bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] - make: [return push sign currency start point tail] + make: [return make-at stack/push* sign currency start point tail] end?: [here >= tail] dot?: [any [here/value = #"." here/value = #","]] From e5f3448959d03b14e3803ae03157d34f1d679908 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 18 Mar 2020 18:49:53 +0100 Subject: [PATCH 1161/3432] FIX: crash on conversion from small float values Floats with exponents below -7 were formed with e-notation. --- runtime/datatypes/money.reds | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index bf07bbdcef..cefa73c5de 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -630,13 +630,17 @@ money: context [ formed: dtoa/form-float flt SIZE_DIGITS yes + print-line formed + point: as byte-ptr! formed until [point: point + 1 point/value = #"."] - if point/2 = #"#" [ ;-- 1.#NaN, 1.#INF + if point/2 = #"#" [ ;-- 1.#NaN, 1.#INF, -1.#INF fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float/box flt] ] + if point/3 = #"e" [MONEY_OVERFLOW] ;-- e-notation for exponents smaller than -7 + sign: formed/1 = #"-" start: as byte-ptr! either sign [formed][formed - 1] end: as byte-ptr! formed + length? formed From feae26745ac181a37a5890e0781e670afe359053 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 13:12:42 +0100 Subject: [PATCH 1162/3432] FIX: overflow when converting large float values --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index cefa73c5de..1b59d9aa1e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -630,7 +630,7 @@ money: context [ formed: dtoa/form-float flt SIZE_DIGITS yes - print-line formed + if (length? formed) > 19 [MONEY_OVERFLOW] ;-- e-notation for exponents larger than 16 point: as byte-ptr! formed until [point: point + 1 point/value = #"."] From 1002983dfdaf3e04bd9a1ab910e61286b1a90028 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 13:18:49 +0100 Subject: [PATCH 1163/3432] TESTS: extend MONEY! conversion tests --- tests/source/units/money-test.red | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 1d9ee89e0c..cf1dbf2cdc 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -167,8 +167,11 @@ Red [ --test-- "to-14" --assert "$123.00000" == to string! $123 --test-- "to-15" --assert "-$12'345'678'901'234'567.12345" == to string! -$12345678901234567.12345 --test-- "to-16" --assert $12'345'678'901'234'567.12345 == to money! <12345678901234567.12345> - --test-- "to-17" --assert error? try [to money! "12345679O1234567.12345"] + --test-- "to-17" --assert error? try [to money! "123456789O1234567.12345"] --test-- "to-18" --assert -$1 == to money! "-0000000000000000000000000000000001.000000000000000000" + --test-- "to-19" --assert $12345678901234568 == to money! 12345678901234567.12345 ;-- loosing a wee bit of precision in least significant digit and fractional part (rounding up) + --test-- "to-20" --assert error? try [to money! 123456789012345678.0] + --test-- "to-21" --assert $0.12345 == to money! 0.12345678901234567890 ===end-group=== ===start-group=== "make" From 9943917e3885d0cbebd026bf5a5542a2f9bb6c9c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 13:27:07 +0100 Subject: [PATCH 1164/3432] FEAT: keep debugging logs for actions and constructors only --- runtime/datatypes/money.reds | 65 ------------------------------------ 1 file changed, 65 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1b59d9aa1e..7df29a441b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -78,7 +78,6 @@ money: context [ money [red-money!] return: [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/get-sign"]] money/header and SIGN_MASK >> SIGN_OFFSET ] @@ -87,8 +86,6 @@ money: context [ sign [integer!] return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/set-sign"]] - money/header: money/header and (not SIGN_MASK) or (sign << SIGN_OFFSET) money ] @@ -97,7 +94,6 @@ money: context [ money [red-money!] return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/flip-sign"]] set-sign money as integer! not as logic! get-sign money ] @@ -106,7 +102,6 @@ money: context [ that [integer!] return: [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/collate-signs"]] this + 1 << 4 or (that + 1) ] @@ -116,7 +111,6 @@ money: context [ money [red-money!] return: [byte-ptr!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/get-amount"]] (as byte-ptr! money) + (size? money) - SIZE_BYTES ] @@ -124,8 +118,6 @@ money: context [ amount [byte-ptr!] return: [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/zero-amount?"]] - loop SIZE_BYTES [ unless null-byte = amount/value [return no] amount: amount + 1 @@ -139,7 +131,6 @@ money: context [ that [byte-ptr!] return: [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/compare-amounts"]] compare-memory this that SIZE_BYTES ] @@ -148,8 +139,6 @@ money: context [ all? [logic!] ;-- no: keep currency index return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/zero-out"]] - money/amount1: either all? [0][money/amount1 and FF000000h] money/amount2: 0 money/amount3: 0 @@ -166,8 +155,6 @@ money: context [ this that [integer!] half [byte!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/shift-left"]] - loop offset [ this: 1 that: this + 1 @@ -192,8 +179,6 @@ money: context [ this that [integer!] half [byte!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/shift-right"]] - loop offset [ this: size that: this - 1 @@ -218,8 +203,6 @@ money: context [ /local bit byte offset [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/get-digit"]] - assert positive? index bit: index and 1 @@ -236,8 +219,6 @@ money: context [ /local bit byte offset reverse [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/set-digit"]] - assert positive? index assert all [value >= 0 value <= 9] @@ -255,8 +236,6 @@ money: context [ /local count [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/count-digits"]] - count: SIZE_DIGITS loop SIZE_BYTES [ either null-byte = amount/value [count: count - 2][ @@ -278,8 +257,6 @@ money: context [ /local delta index1 index2 end this that [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/compare-slices"]] - delta: integer/abs this-count - that-count switch integer/sign? this-count - that-count [ -1 [index1: 1 - delta index2: 1 end: that-count] @@ -311,8 +288,6 @@ money: context [ /local this that borrow difference [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/subtract-slice"]] - this-count: this-count + as integer! this-high? that-count: that-count + as integer! that-high? borrow: 0 @@ -439,8 +414,6 @@ money: context [ sign count [integer!] index times [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/form-money"]] - amount: get-amount money sign: sign? money @@ -497,8 +470,6 @@ money: context [ amount limit [byte-ptr!] sign count [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/overflow?"]] - sign: sign? money if zero? sign [return no] @@ -518,8 +489,6 @@ money: context [ sign integer index [integer!] start power digit [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/to-integer"]] - if overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] sign: sign? money @@ -550,8 +519,6 @@ money: context [ extra index start [integer!] power digit [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/from-integer"]] - money: zero-out as red-money! stack/push* yes money/header: TYPE_MONEY @@ -592,8 +559,6 @@ money: context [ sign delta [integer!] length error [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/to-float"]] - sign: sign? money if zero? sign [return 0.0] @@ -626,8 +591,6 @@ money: context [ point [byte-ptr!] sign [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/from-float"]] - formed: dtoa/form-float flt SIZE_DIGITS yes if (length? formed) > 19 [MONEY_OVERFLOW] ;-- e-notation for exponents larger than 16 @@ -654,7 +617,6 @@ money: context [ money [red-money!] return: [red-binary!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/to-binary"]] binary/load-in get-amount money SIZE_BYTES null ] @@ -667,8 +629,6 @@ money: context [ length [integer!] index [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/from-binary"]] - length: binary/rs-length? bin if length > SIZE_BYTES [length: SIZE_BYTES] ;-- take only first SIZE_BYTES bytes into account @@ -699,8 +659,6 @@ money: context [ head tail here [red-value!] state type length [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/from-block"]] - bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] length: block/rs-length? blk @@ -776,8 +734,6 @@ money: context [ char [byte!] sign [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/from-string"]] - bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] make: [return make-at stack/push* sign currency start point tail] @@ -853,8 +809,6 @@ money: context [ /local this-sign that-sign [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/compare-money"]] - ;@@ TBD: take currencies into account this-sign: sign? this @@ -873,7 +827,6 @@ money: context [ money [red-money!] return: [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/negative-money?"]] negative? sign? money ] @@ -881,7 +834,6 @@ money: context [ money [red-money!] return: [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/zero-money?"]] zero? sign? money ] @@ -889,7 +841,6 @@ money: context [ money [red-money!] return: [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/positive-money?"]] positive? sign? money ] @@ -897,8 +848,6 @@ money: context [ money [red-money!] return: [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/sign?"]] - either zero-amount? get-amount money [0][ either as logic! get-sign money [-1][+1] ] @@ -910,7 +859,6 @@ money: context [ money [red-money!] return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/absolute-money"]] set-sign money 0 ;-- 0: clear sign bit ] @@ -918,7 +866,6 @@ money: context [ money [red-money!] return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/negate-money"]] flip-sign money ] @@ -931,8 +878,6 @@ money: context [ this-sign that-sign [integer!] index carry left right sum [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/add-money"]] - this-sign: sign? augend that-sign: sign? addend @@ -984,8 +929,6 @@ money: context [ difference [integer!] lesser? flag [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/subtract-money"]] - this-sign: sign? minuend that-sign: sign? subtrahend @@ -1044,8 +987,6 @@ money: context [ delta index1 index2 index3 [integer!] carry left right other result [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/multiply-money"]] - this-sign: sign? multiplicand that-sign: sign? multiplier @@ -1124,8 +1065,6 @@ money: context [ size overflow digits index [integer!] this-high? that-high? [logic!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/divide-money"]] - this-sign: sign? dividend that-sign: sign? divisor @@ -1221,8 +1160,6 @@ money: context [ op [integer!] return: [red-money!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/do-math-op"]] - switch op [ OP_ADD [add-money left right] OP_SUB [subtract-money left right] @@ -1247,8 +1184,6 @@ money: context [ left-type [integer!] right-type [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/do-math"]] - left: as red-money! stack/arguments right: left + 1 From 665a8215916d3cc0a8732538c00a5a0b2b7f2d12 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 13:28:53 +0100 Subject: [PATCH 1165/3432] FIX: sentence case in MULTIPLY docstring --- environment/actions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index 370ae44df1..6fbd3764e6 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -112,7 +112,7 @@ divide: make action! [[ multiply: make action! [[ "Returns the product of two values" value1 [number! money! char! pair! tuple! vector! time!] "The multiplicand" - value2 [number! money! char! pair! tuple! vector! time!] "the multiplier" + value2 [number! money! char! pair! tuple! vector! time!] "The multiplier" return: [number! money! char! pair! tuple! vector! time!] "The product" ] #get-definition ACT_MULTIPLY From 3bc7e01946879f0485a146746e4086f17b9e4da6 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 13:54:50 +0100 Subject: [PATCH 1166/3432] FEAT: preliminary work on AS-MONEY native --- environment/natives.red | 9 +++++++++ runtime/macros.reds | 1 + runtime/natives.reds | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/environment/natives.red b/environment/natives.red index 7381a97f6c..e45267cfa6 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -661,6 +661,15 @@ as-pair: make native! [[ #get-definition NAT_AS_PAIR ] +as-money: make native! [[ + "Combine currency and amount into a monetary value" + currency [word!] + amount [money! integer! float!] + return: [money!] + ] + #get-definition NAT_AS_MONEY +] + break: make native! [[ "Breaks out of a loop, while, until, repeat, foreach, etc" /return "Forces the loop function to return a value" diff --git a/runtime/macros.reds b/runtime/macros.reds index d67d104b34..92d464be13 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -219,6 +219,7 @@ Red/System [ NAT_UPPERCASE NAT_LOWERCASE NAT_AS_PAIR + NAT_AS_MONEY NAT_BREAK NAT_CONTINUE NAT_EXIT diff --git a/runtime/natives.reds b/runtime/natives.reds index 93961a2ec2..9aca03b28e 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2004,6 +2004,41 @@ natives: context [ pair/header: TYPE_PAIR ] + as-money*: func [ + check? [logic!] + /local + argument [red-value!] + amount [red-value!] + currency [red-word!] + mny [red-money!] + flt [red-float!] + int [red-integer!] + ][ + #typecheck as-money + argument: stack/arguments + currency: as red-word! argument + ;@@ TBD: take currency into account + amount: stack/arguments + 1 + + switch TYPE_OF(amount) [ + TYPE_INTEGER [ + int: as red-integer! amount + mny: money/from-integer int/value + ] + TYPE_FLOAT [ + flt: as red-float! amount + mny: money/from-float flt/value + ] + TYPE_MONEY [ + mny: as red-money! amount + ] + default [assert false] ;-- somehow, somewhere, something went terribly wrong + ] + + set-type as red-value! mny TYPE_MONEY ;-- preserves sign bit + SET_RETURN(mny) + ] + break*: func [check? [logic!] returned [integer!]][ #typecheck [break returned] stack/throw-break returned <> -1 no @@ -3408,6 +3443,7 @@ natives: context [ :uppercase* :lowercase* :as-pair* + :as-money* :break* :continue* :exit* From d278a83ee22c06f6c6f37bef5b9256e130f0d38d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 14:05:26 +0100 Subject: [PATCH 1167/3432] FEAT: minor refactoring --- runtime/datatypes/money.reds | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 7df29a441b..cd5186c08d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -114,6 +114,15 @@ money: context [ (as byte-ptr! money) + (size? money) - SIZE_BYTES ] + set-amount: func [ + money [red-money!] + amount [byte-ptr!] + return: [red-money!] + ][ + copy-memory get-amount money amount SIZE_BYTES + money + ] + zero-amount?: func [ amount [byte-ptr!] return: [logic!] @@ -395,7 +404,7 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/push"]] money: as red-money! set-type stack/push* TYPE_MONEY - copy-memory get-amount money as byte-ptr! amount SIZE_BYTES + set-amount money as byte-ptr! amount ;@@ TBD: take currency into account set-sign money as integer! sign @@ -1044,7 +1053,7 @@ money: context [ if zero-amount? product [MONEY_OVERFLOW] ;-- got zero product from non-zero factors - copy-memory this-amount product SIZE_BYTES + set-amount multiplicand product set-sign multiplicand sign ] @@ -1148,7 +1157,7 @@ money: context [ ] if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero dividend unless zero? get-digit buffer overflow [MONEY_OVERFLOW] ;-- overflowed into most-significant digit - copy-memory this-amount quotient SIZE_BYTES + set-amount dividend quotient ] set-sign dividend sign From 7b192cc7c98c8d1616eb662f7fa8a928cdb3819a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 14:12:14 +0100 Subject: [PATCH 1168/3432] FEAT: minor optimization --- runtime/datatypes/money.reds | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index cd5186c08d..ffc8a575f1 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -126,13 +126,15 @@ money: context [ zero-amount?: func [ amount [byte-ptr!] return: [logic!] + /local + rest [int-ptr!] ][ - loop SIZE_BYTES [ + loop 3 [ ;-- SIZE_BYTES - (2 * size? integer!) unless null-byte = amount/value [return no] amount: amount + 1 ] - - yes + rest: as int-ptr! amount + all [rest/1 = 0 rest/2 = 0] ] compare-amounts: func [ From b43798355d2d03500d88ed0cc0a6f6222f57d915 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 14:26:12 +0100 Subject: [PATCH 1169/3432] FEAT: improve naming according to style guide --- runtime/datatypes/money.reds | 95 ++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index ffc8a575f1..3cd87135e7 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -67,8 +67,15 @@ money: context [ S_END ] + #define SWAP_ARGUMENTS(this-argument that-argument) [ + use [hold][ + hold: this-argument + this-argument: that-argument + that-argument: hold + ] + ] + #define DISPATCH_SIGNS [switch collate-signs this-sign that-sign] - #define SWAP_ARGUMENTS(this that) [use [hold][hold: this this: that that: hold]] #define MONEY_OVERFLOW [fire [TO_ERROR(script type-limit) datatype/push TYPE_MONEY]] @@ -98,11 +105,11 @@ money: context [ ] collate-signs: func [ - this [integer!] - that [integer!] - return: [integer!] + this-sign [integer!] + that-sign [integer!] + return: [integer!] ][ - this + 1 << 4 or (that + 1) + this-sign + 1 << 4 or (that-sign + 1) ] ;-- Amount -- @@ -138,11 +145,11 @@ money: context [ ] compare-amounts: func [ - this [byte-ptr!] - that [byte-ptr!] - return: [integer!] + this-amount [byte-ptr!] + that-amount [byte-ptr!] + return: [integer!] ][ - compare-memory this that SIZE_BYTES + compare-memory this-amount that-amount SIZE_BYTES ] zero-out: func [ @@ -163,18 +170,19 @@ money: context [ offset [integer!] return: [byte-ptr!] /local - this that [integer!] - half [byte!] + this-index [integer!] + that-index [integer!] + half [byte!] ][ loop offset [ - this: 1 - that: this + 1 + this-index: 1 + that-index: this-index + 1 loop size [ - half: either that > size [null-byte][amount/that >>> 4] - amount/this: amount/this << 4 or half + half: either that-index > size [null-byte][amount/that-index >>> 4] + amount/this-index: amount/this-index << 4 or half - this: this + 1 - that: that + 1 + this-index: this-index + 1 + that-index: that-index + 1 ] ] @@ -187,18 +195,19 @@ money: context [ offset [integer!] return: [byte-ptr!] /local - this that [integer!] - half [byte!] + this-index [integer!] + that-index [integer!] + half [byte!] ][ loop offset [ - this: size - that: this - 1 + this-index: size + that-index: this-index - 1 loop size [ - half: either that < 1 [null-byte][amount/that << 4] - amount/this: amount/this >>> 4 or half + half: either that-index < 1 [null-byte][amount/that-index << 4] + amount/this-index: amount/this-index >>> 4 or half - this: this - 1 - that: that - 1 + this-index: this-index - 1 + that-index: that-index - 1 ] ] @@ -266,7 +275,7 @@ money: context [ that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] return: [integer!] /local - delta index1 index2 end this that [integer!] + delta index1 index2 end this-digit that-digit [integer!] ][ delta: integer/abs this-count - that-count switch integer/sign? this-count - that-count [ @@ -280,33 +289,33 @@ money: context [ index2: index2 + as integer! that-high? until [ - this: either index1 < 1 [0][get-digit this-buffer index1] - that: either index2 < 1 [0][get-digit that-buffer index2] + this-digit: either index1 < 1 [0][get-digit this-buffer index1] + that-digit: either index2 < 1 [0][get-digit that-buffer index2] index1: index1 + 1 index2: index2 + 1 end: end - 1 - any [this <> that zero? end] + any [this-digit <> that-digit zero? end] ] - this - that + this-digit - that-digit ] subtract-slice: func [ this-buffer [byte-ptr!] this-high? [logic!] this-count [integer!] that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] /local - this that borrow difference [integer!] + this-digit that-digit borrow difference [integer!] ][ this-count: this-count + as integer! this-high? that-count: that-count + as integer! that-high? borrow: 0 until [ - this: get-digit this-buffer this-count - that: either that-count < 1 [0][get-digit that-buffer that-count] + this-digit: get-digit this-buffer this-count + that-digit: either that-count < 1 [0][get-digit that-buffer that-count] - difference: this - that - borrow ;-- assumming this >= that + difference: this-digit - that-digit - borrow ;-- assumming this-buffer >= that-buffer borrow: as integer! difference < 0 if as logic! borrow [difference: difference + 10] @@ -324,7 +333,7 @@ money: context [ make-at: func [ slot [red-value!] sign [logic!] ;-- yes: negative - currency [byte-ptr!] ;-- can be null + currency [byte-ptr!] ;-- can be null if currency code is not present start [byte-ptr!] ;-- $ sign point [byte-ptr!] ;-- can be null if fractional part is not present end [byte-ptr!] ;-- points past the money literal @@ -814,24 +823,26 @@ money: context [ ;-- Comparison -- compare-money: func [ - this [red-money!] - that [red-money!] - return: [integer!] + this-money [red-money!] + that-money [red-money!] + return: [integer!] /local this-sign that-sign [integer!] ][ ;@@ TBD: take currencies into account - this-sign: sign? this - that-sign: sign? that + this-sign: sign? this-money + that-sign: sign? that-money DISPATCH_SIGNS [ - SIGN_-- [SWAP_ARGUMENTS(this that) 0] + SIGN_-- [SWAP_ARGUMENTS(this-money that-money) 0] SIGN_++ [0] default [return integer/sign? this-sign - that-sign] ] - integer/sign? compare-amounts get-amount this get-amount that ;-- must return strictly -1, 0 or +1 + integer/sign? compare-amounts ;-- must return strictly -1, 0 or +1 + get-amount this-money + get-amount that-money ] negative-money?: func [ From 753bad016338f28fd10033d75f2690d27d25923b Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Mar 2020 17:22:21 +0100 Subject: [PATCH 1170/3432] FIX: compiler's lexer state not reset fully on premature exit. --- lexer.r | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index 8254173515..ea506748aa 100644 --- a/lexer.r +++ b/lexer.r @@ -688,6 +688,11 @@ lexer: context [ top: does [last stk] reset: does [clear stk] + + clean-up: does [ + clear stk + nl? :no + ] ] throw-error: func [/with msg [string! block!]][ @@ -709,6 +714,7 @@ lexer: context [ "^/*** line: " line "^/*** at: " mold copy/part pos 40 ] + stack/clean-up either encap? [quit][halt] ] @@ -924,7 +930,8 @@ lexer: context [ process: func [src [string! binary!] /local blk][ old-line: line: 1 count?: yes - blk: stack/allocate block! 100 ;-- root block + stack/clean-up + blk: stack/allocate block! 100 ;-- root block src: identify-header src unless parse/all/case src program [throw-error] From edf4bdda5d8441679d207770cffc85cdb29ce923 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 18:12:09 +0100 Subject: [PATCH 1171/3432] FEAT: store and mold currency index --- runtime/datatypes/money.reds | 82 ++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3cd87135e7..1aefd809da 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -112,6 +112,31 @@ money: context [ this-sign + 1 << 4 or (that-sign + 1) ] + ;-- Currency -- + + get-currency: func [ + money [red-money!] + return: [integer!] + /local + place [byte-ptr!] + ][ + place: (get-amount money) - 1 + as integer! place/value + ] + + set-currency: func [ + money [red-money!] + index [integer!] + return: [red-money!] + /local + place [byte-ptr!] + ][ + assert all [index >= 0 index <= FFh] + place: (get-amount money) - 1 + place/value: as byte! index + money + ] + ;-- Amount -- get-amount: func [ @@ -339,12 +364,15 @@ money: context [ end [byte-ptr!] ;-- points past the money literal return: [red-money!] /local - convert [subroutine!] - money [red-money!] - here amount [byte-ptr!] - limit [byte-ptr!] - index stop [integer!] - step [integer!] + convert walk [subroutine!] + list [red-block!] + money [red-money!] + head tail [red-word!] + here amount [byte-ptr!] + limit [byte-ptr!] + str [c-string!] + index stop [integer!] + sym step [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/make-at"]] @@ -353,7 +381,30 @@ money: context [ zero-out money yes set-sign money as integer! sign - ;@@ TBD: store currency index + + walk: [ + head: as red-word! block/rs-head list + tail: as red-word! block/rs-tail list + until [head: head + 1 index: index + 1 any [head = tail head/symbol = sym]] + + ;@@ TBD: walk over extra list also + ;@@ TBD: better error message + if head = tail [fire[TO_ERROR(note no-load) datatype/push TYPE_MONEY]] + ] + + ;-- currency code + unless null? currency [ + str: "..." ;-- 3 letters + copy-memory as byte-ptr! str currency 3 + sym: symbol/make str + + list: as red-block! #get system/locale/currencies/base + index: 0 + walk ;@@ assuming it's a non-empty block + + set-currency money index + ] + amount: get-amount money convert: [ @@ -430,6 +481,10 @@ money: context [ return: [integer!] /local fill [subroutine!] + base [red-block!] + sym [red-string!] + word [red-word!] + after [red-integer!] amount [byte-ptr!] sign count [integer!] index times [integer!] @@ -437,12 +492,22 @@ money: context [ amount: get-amount money sign: sign? money + ;-- sign if negative? sign [ string/concatenate-literal buffer "-" part: part - 1 ] - ;@@ TBD: take currency into account + ;-- currency code + index: get-currency money + unless zero? index [ ;-- generic currency + base: as red-block! #get system/locale/currencies/base + word: as red-word! block/rs-abs-at base index + + sym: as red-string! symbol/get word/symbol + string/concatenate buffer sym -1 0 yes no + part: part - string/rs-length? sym + ] string/concatenate-literal buffer "$" @@ -465,6 +530,7 @@ money: context [ ] ] + ;-- integral part times: count - SIZE_SCALE either positive? times [fill][ string/concatenate-literal buffer "0" From 1e3eefd637f635dc30ce8719e1c5d8d6a0196e98 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 18:14:04 +0100 Subject: [PATCH 1172/3432] FEAT: take system/options/money-digits into account --- runtime/datatypes/money.reds | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1aefd809da..d57447df88 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -18,7 +18,6 @@ money: context [ #enum sizes! [ SIZE_BYTES: 11 ;-- total number of bytes used to store amount SIZE_SCALE: 05 ;-- total number of digits (nibbles) used to store scale (fractional part) - SIZE_AFTER: 05 ;-- how many digits to print after a decimal separator ] SIZE_DIGITS: SIZE_BYTES * 2 ;-- total number of digits (nibbles) used to store amount @@ -538,11 +537,15 @@ money: context [ part: part - 1 ] - string/concatenate-literal buffer "." - - group?: no - times: SIZE_AFTER - fill + ;-- fractional part + after: as red-integer! #get system/options/money-digits + times: after/value + if times > 0 [ + string/concatenate-literal buffer "." + if any times > SIZE_SCALE [times: SIZE_SCALE] + group?: no + fill + ] part - 2 ;-- compensate for $ and . characters ] From b5b9eb5bcdf779020befe24fe9dec4f298e47289 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 18:14:54 +0100 Subject: [PATCH 1173/3432] FEAT: MOLD/ALL displays all fractional digits --- runtime/datatypes/money.reds | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d57447df88..e74b75e20d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -476,6 +476,7 @@ money: context [ money [red-money!] buffer [red-string!] part [integer!] + all? [logic!] ;-- yes: display all SIZE_SCALE fractional digits group? [logic!] ;-- yes: decorate amount with thousand's separators return: [integer!] /local @@ -542,7 +543,7 @@ money: context [ times: after/value if times > 0 [ string/concatenate-literal buffer "." - if any times > SIZE_SCALE [times: SIZE_SCALE] + if any [all? times > SIZE_SCALE][times: SIZE_SCALE] group?: no fill ] @@ -653,7 +654,7 @@ money: context [ if zero? sign [return 0.0] buffer: string/make-at stack/push* SIZE_DIGITS + 6 Latin1 ;-- max number of digits and -CCC$. - form-money money buffer 0 no + form-money money buffer 0 yes no ;-- take all fractional digits into account delta: (string/rs-find buffer as integer! #"$") + 1 head: (string/rs-head buffer) + delta @@ -1397,7 +1398,7 @@ money: context [ return: [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/form"]] - form-money money buffer part yes + form-money money buffer part no yes ] mold: func [ @@ -1412,7 +1413,7 @@ money: context [ return: [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/mold"]] - form-money money buffer part no + form-money money buffer part all? no ] compare: func [ From 9becd19f0509ae53f7f149916cebf827d2c06165 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 18:15:24 +0100 Subject: [PATCH 1174/3432] FEAT: minor code improvements --- runtime/datatypes/money.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index e74b75e20d..438b78a32e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -84,7 +84,7 @@ money: context [ money [red-money!] return: [integer!] ][ - money/header and SIGN_MASK >> SIGN_OFFSET + money/header and SIGN_MASK >>> SIGN_OFFSET ] set-sign: func [ @@ -92,6 +92,7 @@ money: context [ sign [integer!] return: [red-money!] ][ + assert any [sign = 0 sign = 1] money/header: money/header and (not SIGN_MASK) or (sign << SIGN_OFFSET) money ] From 19de4661175b655c8a8ebd0759ac6ae3d83956c8 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 19 Mar 2020 18:16:03 +0100 Subject: [PATCH 1175/3432] TESTS: update money! tests to match recent changes --- tests/source/units/money-test.red | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index cf1dbf2cdc..5a5b1b0a5b 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -11,6 +11,8 @@ Red [ ~~~start-file~~~ "money" +system/options/money-digits: 5 ;-- enforce molding of the whole fractional part + ===start-group=== "zero?" --test-- "zero-1" --assert zero? -$0 --test-- "zero-2" --assert zero? +$0 @@ -172,6 +174,7 @@ Red [ --test-- "to-19" --assert $12345678901234568 == to money! 12345678901234567.12345 ;-- loosing a wee bit of precision in least significant digit and fractional part (rounding up) --test-- "to-20" --assert error? try [to money! 123456789012345678.0] --test-- "to-21" --assert $0.12345 == to money! 0.12345678901234567890 + --test-- "to-22" --assert "EUR$1'234.56789" == to string! EUR$1234.56789 ===end-group=== ===start-group=== "make" @@ -184,8 +187,8 @@ Red [ --test-- "make-6" --assert error? try [make money! [0 123456]] --test-- "make-7" --assert -$123.00456 == make money! [-123 456] --test-- "make-8" --assert $123.44444 == make money! [123.32100 12344] - --test-- "make-9" --assert -CCC$123 == make money! [CCC -123] - --test-- "make-10" --assert -CCC$123 == make money! [CCC -123 0] + --test-- "make-9" --assert -USD$123 == make money! [USD -123] + --test-- "make-10" --assert -EUR$123 == make money! [EUR -123 0] ===end-group=== ===start-group=== "add" @@ -375,4 +378,7 @@ Red [ --test-- "generated-4-<=" --assert $35305992.25093 <= -$609764191.14030 == false --test-- "generated-5-<=" --assert $761650628.29928 <= -$188013192.81943 == false ===end-group=== + +system/options/money-digits: 2 ;-- put it back where it was + ~~~end-file~~~ From b0c306edcc56d82858acb3ad50403d65b8bef84e Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 19 Mar 2020 17:22:21 +0100 Subject: [PATCH 1176/3432] FIX: compiler's lexer state not reset fully on premature exit. --- lexer.r | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index 8254173515..ea506748aa 100644 --- a/lexer.r +++ b/lexer.r @@ -688,6 +688,11 @@ lexer: context [ top: does [last stk] reset: does [clear stk] + + clean-up: does [ + clear stk + nl? :no + ] ] throw-error: func [/with msg [string! block!]][ @@ -709,6 +714,7 @@ lexer: context [ "^/*** line: " line "^/*** at: " mold copy/part pos 40 ] + stack/clean-up either encap? [quit][halt] ] @@ -924,7 +930,8 @@ lexer: context [ process: func [src [string! binary!] /local blk][ old-line: line: 1 count?: yes - blk: stack/allocate block! 100 ;-- root block + stack/clean-up + blk: stack/allocate block! 100 ;-- root block src: identify-header src unless parse/all/case src program [throw-error] From c572cb589513691a5a296e1b4888c5bc57d67a48 Mon Sep 17 00:00:00 2001 From: loziniak Date: Thu, 19 Mar 2020 21:01:27 +0100 Subject: [PATCH 1177/3432] FIX: crash in fire-on-set on facet update #4190 --- compiler.r | 26 +++++++++++++------ runtime/datatypes/object.reds | 12 +++++++++ system/utils/libRedRT-exports.r | 1 + .../source/compiler/regression-test-redc-1.r | 4 +-- .../source/compiler/regression-test-redc-2.r | 4 +-- .../source/compiler/regression-test-redc-3.r | 4 +-- .../source/compiler/regression-test-redc-4.r | 4 +-- .../source/compiler/regression-test-redc-5.r | 17 +++++++++++- 8 files changed, 55 insertions(+), 17 deletions(-) diff --git a/compiler.r b/compiler.r index b0c336f62a..17eb1a92eb 100644 --- a/compiler.r +++ b/compiler.r @@ -3370,14 +3370,24 @@ red: context [ object/fire-on-set* ] to logic! local-word? first back back tail path - parent: either 2 < length? path [ ;-- extract word from parent context - breaks: [-12 -9 -6 -1] - set [obj fpath] object-access? copy/part path (length? path) - 1 - ctx: second obj: find objects obj - ['word/from ctx get-word-index/with pick tail path -2 ctx] - ][ - breaks: [-10 -7 -4 -1] ;-- word is in global context - [decorate-symbol path/1] + parent: case [ + 2 < length? path [ ;-- extract word from parent context + breaks: [-12 -9 -6 -1] + set [obj fpath] object-access? copy/part path (length? path) - 1 + ctx: second obj: find objects obj + ['word/from ctx get-word-index/with pick tail path -2 ctx] + ] + self? [ ;-- self/field + breaks: [-10 -7 -4 -1] + set [obj fpath] object-access? copy/part path 1 + ctx: second obj: find objects obj + fire: 'object/loc-ctx-fire-on-set* + [ctx] + ] + 'else [ + breaks: [-10 -7 -4 -1] ;-- word is in global context + [decorate-symbol path/1] + ] ] repend any [mark last output] compose [ fire diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index 1a6af90236..9cb73ec9c3 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -355,6 +355,18 @@ object: context [ stack/top - 2 ] + loc-ctx-fire-on-set*: func [ ;-- compiled code entry point + parent-ctx [node!] + field [red-word!] + /local + s [series!] + obj [red-value!] + ][ + s: as series! parent-ctx/value + obj: as red-value! s/offset + 1 + loc-fire-on-set* obj field + ] + fire-on-set*: func [ ;-- compiled code entry point parent [red-word!] field [red-word!] diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index 49b5d82ba0..df6a20b8b8 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -128,6 +128,7 @@ red/object/init-push red/object/init-events red/object/loc-fire-on-set* + red/object/loc-ctx-fire-on-set* red/object/fire-on-set* red/object/get-values diff --git a/tests/source/compiler/regression-test-redc-1.r b/tests/source/compiler/regression-test-redc-1.r index 26307bf40e..b6c3d19149 100644 --- a/tests/source/compiler/regression-test-redc-1.r +++ b/tests/source/compiler/regression-test-redc-1.r @@ -1,7 +1,7 @@ REBOL [ Title: "Regression tests script for Red Compiler" Author: "Boleslav Březovský" - File: %regression-test-redc.r + File: %regression-test-redc-1.r Rights: "Copyright (C) 2016 Boleslav Březovský. All rights reserved." License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" ] @@ -491,4 +491,4 @@ flexfun: function [ ===end-group=== -~~~end-file~~~ \ No newline at end of file +~~~end-file~~~ diff --git a/tests/source/compiler/regression-test-redc-2.r b/tests/source/compiler/regression-test-redc-2.r index 6889299042..dc28384b75 100644 --- a/tests/source/compiler/regression-test-redc-2.r +++ b/tests/source/compiler/regression-test-redc-2.r @@ -1,7 +1,7 @@ REBOL [ Title: "Regression tests script for Red Compiler" Author: "Boleslav Březovský" - File: %regression-test-redc.r + File: %regression-test-redc-2.r Rights: "Copyright (C) 2016 Boleslav Březovský. All rights reserved." License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" ] @@ -552,4 +552,4 @@ Red [ ===end-group=== -~~~end-file~~~ \ No newline at end of file +~~~end-file~~~ diff --git a/tests/source/compiler/regression-test-redc-3.r b/tests/source/compiler/regression-test-redc-3.r index 7c3682cd16..2bc130ab3a 100644 --- a/tests/source/compiler/regression-test-redc-3.r +++ b/tests/source/compiler/regression-test-redc-3.r @@ -1,7 +1,7 @@ REBOL [ Title: "Regression tests script for Red Compiler" Author: "Boleslav Březovský" - File: %regression-test-redc.r + File: %regression-test-redc-3.r Rights: "Copyright (C) 2016 Boleslav Březovský. All rights reserved." License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" ] @@ -302,4 +302,4 @@ do load {set [o/f] 10} ===end-group=== -~~~end-file~~~ \ No newline at end of file +~~~end-file~~~ diff --git a/tests/source/compiler/regression-test-redc-4.r b/tests/source/compiler/regression-test-redc-4.r index 45d3a024c2..ce8e6d78a0 100644 --- a/tests/source/compiler/regression-test-redc-4.r +++ b/tests/source/compiler/regression-test-redc-4.r @@ -1,7 +1,7 @@ REBOL [ Title: "Regression tests script for Red Compiler" Author: "Boleslav Březovský" - File: %regression-test-redc.r + File: %regression-test-redc-4.r Rights: "Copyright (C) 2016 Boleslav Březovský. All rights reserved." License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" ] @@ -247,4 +247,4 @@ do [ ===end-group=== -~~~end-file~~~ \ No newline at end of file +~~~end-file~~~ diff --git a/tests/source/compiler/regression-test-redc-5.r b/tests/source/compiler/regression-test-redc-5.r index f01fd93308..75d2b54020 100644 --- a/tests/source/compiler/regression-test-redc-5.r +++ b/tests/source/compiler/regression-test-redc-5.r @@ -1,7 +1,7 @@ REBOL [ Title: "Regression tests script for Red Compiler" Author: "Boleslav Březovský" - File: %regression-test-redc.r + File: %regression-test-redc-5.r Rights: "Copyright (C) 2016 Boleslav Březovský. All rights reserved." License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt" ] @@ -207,4 +207,19 @@ test ===end-group=== +===start-group=== "Red regressions #4001 - #4500" + + --test-- "#4190" + --compile-and-run-this-red { + fc: make face! [ + fn: does [self/parent: 'boom] + ] + fc/fn + print fc/parent + } + --assert not crashed? + --assert true? find qt/output "boom" + +===end-group=== + ~~~end-file~~~ From 3f849595272e7d162baf12d6bae2dee4a600c8ab Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 20 Mar 2020 08:02:13 +0800 Subject: [PATCH 1178/3432] FIX: wrongly get alias symbol id in some cases. --- environment/system.red | 2 +- modules/view/draw.red | 2 +- runtime/datatypes/symbol.reds | 18 ++++++++++-------- runtime/hashtable.reds | 7 ++++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/environment/system.red b/environment/system.red index 75f0801ff5..4a17f4acc9 100644 --- a/environment/system.red +++ b/environment/system.red @@ -319,7 +319,7 @@ system: context [ ETB ETH EUR FJD FKP FOK GBP GEL GGP GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS IMP INR IQD IRR ISK JEP JMD JOD JPY KES KGS KHR KID KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRU MUR MVR MWK MXN MYR MZN NAD NGN NIO NOK NPR -;@@ NZD OMR PAB PEN PGK PHP PKR PLN PND PRB PYG QAR RED RON RSD RUB RWF SAR SBD SCR SDG SEK + NZD OMR PAB PEN PGK PHP PKR PLN PND PRB PYG QAR RED RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLL SLS SOS SRD SSP STN SYP SZL THB TJS TMT TND TOP TRY TTD TVD TWD TZS UAH UGX USD UYU UZS VES VND VUV WST CFA XAF XCD XOF CFP XPF YER ZAR ZMW ] diff --git a/modules/view/draw.red b/modules/view/draw.red index 393a27e65f..6c237f945a 100644 --- a/modules/view/draw.red +++ b/modules/view/draw.red @@ -16,7 +16,7 @@ Red/System [ line-width: symbol/make "line-width" box: symbol/make "box" triangle: symbol/make "triangle" - pen: symbol/make "pen" + pen: symbol/make-opt "pen" fill-pen: symbol/make "fill-pen" _polygon: symbol/make "polygon" circle: symbol/make "circle" diff --git a/runtime/datatypes/symbol.reds b/runtime/datatypes/symbol.reds index 56b9cf002a..97fa21d107 100644 --- a/runtime/datatypes/symbol.reds +++ b/runtime/datatypes/symbol.reds @@ -51,7 +51,7 @@ symbol: context [ return: [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make-alt-utf8"]] - _hashtable/put-symbol table s len + _hashtable/put-symbol table s len no ] make: func [ @@ -59,7 +59,15 @@ symbol: context [ return: [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "symbol/make"]] - _hashtable/put-symbol table as byte-ptr! s system/words/length? s + _hashtable/put-symbol table as byte-ptr! s system/words/length? s no + ] + + make-opt: func [ + s [c-string!] + return: [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "symbol/make-opt"]] + _hashtable/put-symbol table as byte-ptr! s system/words/length? s yes ] get: func [ @@ -99,12 +107,6 @@ symbol: context [ sym: as red-symbol! s/offset + id - 1 sym/alias ] - - push: func [ - - ][ - - ] ;-- Actions -- diff --git a/runtime/hashtable.reds b/runtime/hashtable.reds index fc323bac59..e51d263ab1 100644 --- a/runtime/hashtable.reds +++ b/runtime/hashtable.reds @@ -1296,6 +1296,7 @@ _hashtable: context [ node [node!] cstr [byte-ptr!] len [integer!] + opt? [logic!] ;-- don't put if found return: [integer!] ;-- return symbol id /local s [series!] h [hashtable!] x [integer!] i [integer!] site [integer!] @@ -1327,7 +1328,7 @@ _hashtable: context [ site: n-buckets mask: n-buckets - 2 hash: murmur3-x86-32 to-lower cstr len len - strict?: yes + strict?: not opt? loop 2 [ ;-- first try: case-sensitive comparison, second try: case-insensitive comparison find?: yes i: hash and mask @@ -1356,7 +1357,7 @@ _hashtable: context [ ] x: i ] - either find? [break][xx: x strict?: no] + either any [find? opt?][break][xx: x strict?: no] ] _HT_CAL_FLAG_INDEX((x - 1) ii sh) @@ -1366,7 +1367,7 @@ _hashtable: context [ len2: -1 ][ len2: keys/x + 1 - either strict? [return len2][ + either any [strict? opt?][return len2][ k: as red-symbol! alloc-tail blk-node _HT_CAL_FLAG_INDEX((xx - 1) ii sh) keys/xx: idx From 54648bf9168ce895dab33f298a99d844c76b62d8 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 20 Mar 2020 11:35:43 +0800 Subject: [PATCH 1179/3432] FIX: Test `compiler\lexer-test.r` failed. The lexer somehow keeps running after throw-error. --- lexer.r | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lexer.r b/lexer.r index ea506748aa..6eebc28108 100644 --- a/lexer.r +++ b/lexer.r @@ -690,8 +690,11 @@ lexer: context [ reset: does [clear stk] clean-up: does [ - clear stk - nl? :no + unless empty? stk [ + clear next stk ;-- keep root block in stk + clear first stk ;-- clear root block + ] + nl?: no ] ] From a7c0b48cf9f999cb03d2fb52825c1a1be2c2c052 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 20 Mar 2020 14:15:02 +0800 Subject: [PATCH 1180/3432] FIX: base-self-test failed. --- modules/view/backends/platform.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 952442c6dc..eb4330f536 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -219,7 +219,7 @@ system/view/platform: context [ left: symbol/make "left" center: symbol/make "center" right: symbol/make "right" - top: symbol/make "top" + top: symbol/make-opt "top" middle: symbol/make "middle" bottom: symbol/make "bottom" ] From 3891416cebe0225b4a17d06de52128c33429625d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 12:45:59 +0100 Subject: [PATCH 1181/3432] FEAT: add MONEY!-specific error definitions --- environment/system.red | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/environment/system.red b/environment/system.red index 75f0801ff5..e26ae9c39e 100644 --- a/environment/system.red +++ b/environment/system.red @@ -158,7 +158,8 @@ system: context [ bad-loop-series: ["Loop series changed to invalid value:" :arg1] ;bad-decode: "missing or unsupported encoding marker" ;already-used: ["alias word is already in use:" :arg1] - ;wrong-denom: [:arg1 "not same denomination as" :arg2] + wrong-denom: [:arg1 "not same denomination as" :arg2] + bad-denom: ["invalid denomination:" :arg1] ;bad-press: ["invalid compressed data - problem:" :arg1] ;dialect: ["incorrect" :arg1 "dialect usage at:" :arg2] invalid-obj-evt: ["invalid object event handler:" :arg1] From 840da5ae25bf049261480c6a041f0454fb483a0c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:05:48 +0100 Subject: [PATCH 1182/3432] FEAT: define currency-specific functions --- runtime/datatypes/money.reds | 86 ++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 438b78a32e..bb57c99bf7 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -137,6 +137,48 @@ money: context [ money ] + get-index: func [ + sym [integer!] + return: [integer!] ;-- -1: invalid currency code + /local + list [red-block!] + here [red-word!] + head tail [red-value!] + index [integer!] + ][ + list: as red-block! #get system/locale/currencies/base + head: block/rs-head list + tail: block/rs-tail list + here: as red-word! head + + index: 0 + until [ + if sym = symbol/resolve here/symbol [break] + index: index + 1 + here: here + 1 + + here = tail + ] + + ;@@ TBD: walk over extra list also + either here = tail [-1][index] + ] + + get-symbol: func [ + index [integer!] + return: [integer!] + /local + base [red-block!] + word [red-word!] + ][ + assert positive? index + base: as red-block! #get system/locale/currencies/base + word: as red-word! block/rs-abs-at base index + + ;@@ TBD: walk over extra list also + symbol/resolve word/symbol + ] + ;-- Amount -- get-amount: func [ @@ -364,15 +406,11 @@ money: context [ end [byte-ptr!] ;-- points past the money literal return: [red-money!] /local - convert walk [subroutine!] - list [red-block!] - money [red-money!] - head tail [red-word!] - here amount [byte-ptr!] - limit [byte-ptr!] - str [c-string!] - index stop [integer!] - sym step [integer!] + convert [subroutine!] + money [red-money!] + amount limit here [byte-ptr!] + str [c-string!] + index stop step [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/make-at"]] @@ -382,26 +420,13 @@ money: context [ zero-out money yes set-sign money as integer! sign - walk: [ - head: as red-word! block/rs-head list - tail: as red-word! block/rs-tail list - until [head: head + 1 index: index + 1 any [head = tail head/symbol = sym]] - - ;@@ TBD: walk over extra list also - ;@@ TBD: better error message - if head = tail [fire[TO_ERROR(note no-load) datatype/push TYPE_MONEY]] - ] - ;-- currency code unless null? currency [ - str: "..." ;-- 3 letters + str: "..." ;-- 3 letters copy-memory as byte-ptr! str currency 3 - sym: symbol/make str - - list: as red-block! #get system/locale/currencies/base - index: 0 - walk ;@@ assuming it's a non-empty block - + index: get-index symbol/make str + ;@@ TBD: better error message + if negative? index [fire[TO_ERROR(note no-load) datatype/push TYPE_MONEY]] set-currency money index ] @@ -501,11 +526,8 @@ money: context [ ;-- currency code index: get-currency money - unless zero? index [ ;-- generic currency - base: as red-block! #get system/locale/currencies/base - word: as red-word! block/rs-abs-at base index - - sym: as red-string! symbol/get word/symbol + unless zero? index [ ;-- generic currency + sym: as red-string! symbol/get get-symbol index string/concatenate buffer sym -1 0 yes no part: part - string/rs-length? sym ] @@ -542,7 +564,7 @@ money: context [ ;-- fractional part after: as red-integer! #get system/options/money-digits times: after/value - if times > 0 [ + if positive? times [ string/concatenate-literal buffer "." if any [all? times > SIZE_SCALE][times: SIZE_SCALE] group?: no From 9174fb340fe196fdbe6bca2a648071836a7dfafd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:06:14 +0100 Subject: [PATCH 1183/3432] FEAT: take currency into account in MAKE constructor --- runtime/datatypes/money.reds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index bb57c99bf7..89e3019070 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -767,9 +767,11 @@ money: context [ /local bail [subroutine!] money fraction [red-money!] + wrd [red-word!] int [red-integer!] flt [red-float!] head tail here [red-value!] + currency [integer!] state type length [integer!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] @@ -781,6 +783,7 @@ money: context [ tail: block/rs-tail blk here: head + currency: 0 ;-- assuming generic currency by default state: S_START while [state <> S_END][ type: TYPE_OF(here) @@ -794,7 +797,9 @@ money: context [ ] ] S_CURRENCY [ - ;@@ TBD: take currency into account + wrd: as red-word! here + currency: get-index symbol/resolve wrd/symbol + if negative? currency [bail] here: here + 1 if here = tail [bail] state: S_INTEGRAL @@ -831,7 +836,7 @@ money: context [ ] ] - money + set-currency money currency ] from-string: func [ From 7d8a20081cd7bd5d179219ed34d7397e92e78d77 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:06:36 +0100 Subject: [PATCH 1184/3432] FEAT: improve code formatting --- runtime/datatypes/money.reds | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 89e3019070..b6df392b08 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -399,11 +399,11 @@ money: context [ make-at: func [ slot [red-value!] - sign [logic!] ;-- yes: negative - currency [byte-ptr!] ;-- can be null if currency code is not present - start [byte-ptr!] ;-- $ sign - point [byte-ptr!] ;-- can be null if fractional part is not present - end [byte-ptr!] ;-- points past the money literal + sign [logic!] ;-- yes: negative + currency [byte-ptr!] ;-- can be null if currency code is not present + start [byte-ptr!] ;-- $ sign + point [byte-ptr!] ;-- can be null if fractional part is not present + end [byte-ptr!] ;-- points past the money literal return: [red-money!] /local convert [subroutine!] @@ -481,9 +481,9 @@ money: context [ ] push: func [ - sign [logic!] ;-- yes: negative - currency [c-string!] ;-- can be null - amount [c-string!] ;-- always SIZE_BYTES bytes + sign [logic!] ;-- yes: negative + currency [c-string!] ;-- can be null + amount [c-string!] ;-- always SIZE_BYTES bytes return: [red-money!] /local money [red-money!] @@ -502,8 +502,8 @@ money: context [ money [red-money!] buffer [red-string!] part [integer!] - all? [logic!] ;-- yes: display all SIZE_SCALE fractional digits - group? [logic!] ;-- yes: decorate amount with thousand's separators + all? [logic!] ;-- yes: display all SIZE_SCALE fractional digits + group? [logic!] ;-- yes: decorate amount with thousand's separators return: [integer!] /local fill [subroutine!] @@ -706,7 +706,7 @@ money: context [ ][ formed: dtoa/form-float flt SIZE_DIGITS yes - if (length? formed) > 19 [MONEY_OVERFLOW] ;-- e-notation for exponents larger than 16 + if (length? formed) > 19 [MONEY_OVERFLOW] ;-- e-notation for exponents larger than 16 point: as byte-ptr! formed until [point: point + 1 point/value = #"."] From 60bb281b4f534bd1a7b1b12f4a45a8184e5ad3aa Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:06:55 +0100 Subject: [PATCH 1185/3432] FEAT: implement AS-MONEY native --- environment/natives.red | 2 +- runtime/natives.reds | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index e45267cfa6..629a07a8b4 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -664,7 +664,7 @@ as-pair: make native! [[ as-money: make native! [[ "Combine currency and amount into a monetary value" currency [word!] - amount [money! integer! float!] + amount [integer! float!] return: [money!] ] #get-definition NAT_AS_MONEY diff --git a/runtime/natives.reds b/runtime/natives.reds index 9aca03b28e..9f6fe713d2 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2013,12 +2013,15 @@ natives: context [ mny [red-money!] flt [red-float!] int [red-integer!] + index [integer!] ][ #typecheck as-money argument: stack/arguments currency: as red-word! argument - ;@@ TBD: take currency into account - amount: stack/arguments + 1 + amount: stack/arguments + 1 + + index: money/get-index symbol/resolve currency/symbol + if negative? index [fire [TO_ERROR(script bad-denom) word/push currency]] switch TYPE_OF(amount) [ TYPE_INTEGER [ @@ -2029,13 +2032,10 @@ natives: context [ flt: as red-float! amount mny: money/from-float flt/value ] - TYPE_MONEY [ - mny: as red-money! amount - ] - default [assert false] ;-- somehow, somewhere, something went terribly wrong + default [assert false] ] - set-type as red-value! mny TYPE_MONEY ;-- preserves sign bit + money/set-currency mny index SET_RETURN(mny) ] From 0baad91d503603d350ea0188f56e697f6d0d46a9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:28:30 +0100 Subject: [PATCH 1186/3432] FEAT: forbid comparison of different currencies --- runtime/datatypes/money.reds | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b6df392b08..91628e6a4d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -179,6 +179,24 @@ money: context [ symbol/resolve word/symbol ] + same-currencies?: func [ + this-money [red-money!] + that-money [red-money!] + return: [logic!] + /local + this-currency [integer!] + that-currency [integer!] + ][ + this-currency: get-currency this-money + that-currency: get-currency that-money + + any [ + zero? this-currency ;-- 0: generic currency + zero? that-currency + this-currency = that-currency + ] + ] + ;-- Amount -- get-amount: func [ @@ -927,8 +945,6 @@ money: context [ /local this-sign that-sign [integer!] ][ - ;@@ TBD: take currencies into account - this-sign: sign? this-money that-sign: sign? that-money @@ -1462,10 +1478,12 @@ money: context [ return 1 ] - ;@@ TBD: take currencies into account (strict comparison) - switch TYPE_OF(value) [ - TYPE_MONEY [0] + TYPE_MONEY [ + unless same-currencies? money as red-money! value [ + fire [TO_ERROR(script wrong-denom) money as red-money! value] + ] + ] TYPE_INTEGER [ integer: as red-integer! value value: from-integer integer/value From b71908970e6697e653d3201cf297016595147344 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 13:55:13 +0100 Subject: [PATCH 1187/3432] FEAT: forbid arithmetic on different currencies --- runtime/datatypes/money.reds | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 91628e6a4d..a80d409088 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1317,6 +1317,7 @@ money: context [ result [red-value!] int [red-integer!] flt [red-float!] + currency [integer!] left-type [integer!] right-type [integer!] ][ @@ -1333,17 +1334,15 @@ money: context [ fire [TO_ERROR(script invalid-type) datatype/push left-type] ] - ;@@ TBD: take currencies into account - switch left-type [ TYPE_MONEY [0] TYPE_INTEGER [ int: as red-integer! left - left: from-integer int/value + left: from-integer int/value ] TYPE_FLOAT [ flt: as red-float! left - left: from-float flt/value + left: from-float flt/value ] default [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(left)] @@ -1365,10 +1364,17 @@ money: context [ ] ] + unless same-currencies? left right [fire [TO_ERROR(script wrong-denom) left right]] + currency: get-currency right ;-- preserve specific currency + if zero? currency [currency: get-currency left] + result: as red-value! do-math-op left right op - if all [op = OP_DIV left-type = TYPE_MONEY right-type = TYPE_MONEY][ + either all [op = OP_DIV left-type = TYPE_MONEY right-type = TYPE_MONEY][ result: as red-value! float/box to-float as red-money! result + ][ + set-currency as red-money! result currency ] + SET_RETURN(result) ;-- some of the operations swap their argument slots ] From bf27739e5910982dabd78403bdd49a35259b6548 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 15:27:19 +0100 Subject: [PATCH 1188/3432] FIX: crash on conversion from string with leading decimal separator --- runtime/datatypes/money.reds | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a80d409088..b724b67a90 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -861,27 +861,20 @@ money: context [ str [red-string!] return: [red-money!] /local - bail make [subroutine!] - end? dot? [subroutine!] - digit? letter? [subroutine!] - tail head here [byte-ptr!] - currency digits [byte-ptr!] - start point [byte-ptr!] - char [byte!] - sign [logic!] + bail make [subroutine!] + end? dot? digit? [subroutine!] + tail head here [byte-ptr!] + currency digits [byte-ptr!] + start point [byte-ptr!] + char [byte!] + sign [logic!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] make: [return make-at stack/push* sign currency start point tail] - end?: [here >= tail] - dot?: [any [here/value = #"." here/value = #","]] - digit?: [all [here/value >= #"0" here/value <= #"9"]] - letter?: [ - any [ - all [here/value >= #"a" here/value <= #"z"] - all [here/value >= #"A" here/value <= #"Z"] - ] - ] + end?: [here >= tail] + dot?: [any [here/value = #"." here/value = #","]] + digit?: [all [here/value >= #"0" here/value <= #"9"]] tail: string/rs-tail str head: string/rs-head str @@ -901,13 +894,12 @@ money: context [ if end? [here: currency] either here = currency [currency: null][ - if currency + 3 <> here [bail] - loop 3 [here: here - 1 unless letter? [bail]] - here: here + 3 + if currency + 3 <> here [bail] ;-- invalid currency code won't pass symbol lookup in make-at, no need to check it here ] start: here - as integer! here/value <> #"$" here: start + 1 + if dot? [bail] ;-- forbid leading decimal separator ;-- leading zeroes until [here: here + 1 any [here = tail here/value <> #"0"]] @@ -917,7 +909,7 @@ money: context [ ;-- integral part with optional thousands separators until [ if here/value = #"'" [here: here + 1 continue] - unless digit? [bail] ;-- forbid leading decimal separator + unless digit? [bail] here: here + 1 any [end? dot?] ] From a71e957bc427f97f75937a1abbb42ffc2e8ae785 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 15:27:57 +0100 Subject: [PATCH 1189/3432] FIX: MOLD/ALL didn't work properly in some cases --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b724b67a90..112faf2093 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -582,9 +582,9 @@ money: context [ ;-- fractional part after: as red-integer! #get system/options/money-digits times: after/value + if any [all? times > SIZE_SCALE][times: SIZE_SCALE] if positive? times [ string/concatenate-literal buffer "." - if any [all? times > SIZE_SCALE][times: SIZE_SCALE] group?: no fill ] From 63289979736d7d560567a3ff6245f6223f79af34 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 15:30:03 +0100 Subject: [PATCH 1190/3432] FEAT: store currency index in compiled MONEY! literals --- runtime/datatypes/money.reds | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 112faf2093..054e2601b4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -500,18 +500,24 @@ money: context [ push: func [ sign [logic!] ;-- yes: negative - currency [c-string!] ;-- can be null + currency [c-string!] ;-- null if generic currency, otherwise 3-letter string amount [c-string!] ;-- always SIZE_BYTES bytes return: [red-money!] /local money [red-money!] + index [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/push"]] - money: as red-money! set-type stack/push* TYPE_MONEY - set-amount money as byte-ptr! amount - ;@@ TBD: take currency into account + money: as red-money! stack/push* + money/header: TYPE_MONEY + set-sign money as integer! sign + set-amount money as byte-ptr! amount + + ;@@ TBD: assuming currency code is valid + index: either null? currency [0][get-index symbol/make currency] + set-currency money index money ] @@ -1170,7 +1176,7 @@ money: context [ shift-right product SIZE_SBYTES SIZE_SCALE product: product + SIZE_BUFFER - SIZE_BYTES - if zero-amount? product [MONEY_OVERFLOW] ;-- got zero product from non-zero factors + if zero-amount? product [MONEY_OVERFLOW] ;-- got zero product from non-zero factors set-amount multiplicand product set-sign multiplicand sign From 9fcfd14606d4649a84d28f8b37e5fb0dab4abae9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 15:30:42 +0100 Subject: [PATCH 1191/3432] TESTS: extend MONEY! test suite --- tests/source/units/money-test.red | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 5a5b1b0a5b..4691e32bf2 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -175,6 +175,26 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "to-20" --assert error? try [to money! 123456789012345678.0] --test-- "to-21" --assert $0.12345 == to money! 0.12345678901234567890 --test-- "to-22" --assert "EUR$1'234.56789" == to string! EUR$1234.56789 + --test-- "to-23" --assert USD$123.45678 == to money! "+USD$123,45678" + --test-- "to-24" --assert error? try [to money! "CCC$123"] + --test-- "to-25" --assert error? try [to money! "123$456"] + --test-- "to-26" --assert error? try [to money! "EUR123"] + --test-- "to-27" + --assert error? try [to money! "$"] + --assert error? try [to money! "$."] + --assert error? try [to money! "-$."] + --assert error? try [to money! "+$."] + --assert error? try [to money! "EUR$0."] + --assert error? try [to money! "EUR$,"] + --assert error? try [to money! "-USD$.0"] + --assert error? try [to money! "."] + --assert error? try [to money! "+."] + --assert error? try [to money! "-."] + --assert error? try [to money! ",0"] + --assert error? try [to money! "0,"] + --assert error? try [to money! "$.0"] + --assert error? try [to money! "$0."] + --assert true ===end-group=== ===start-group=== "make" @@ -189,6 +209,28 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-8" --assert $123.44444 == make money! [123.32100 12344] --test-- "make-9" --assert -USD$123 == make money! [USD -123] --test-- "make-10" --assert -EUR$123 == make money! [EUR -123 0] + --test-- "make-11" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] +===end-group=== + +===start-group=== "form/mold" + --test-- "form/mold-1" --assert "" == form/part $123.45678 0 + --test-- "form/mold-2" --assert "" == mold/part $123.45678 0 + --test-- "form/mold-3" --assert "$" == form/part $123 1 + --test-- "form/mold-4" --assert "$123.45678" == form/part $123.45678 12345678 + --test-- "form/mold-5" --assert "$1'" == form/part +$1234 3 + --test-- "form/mold-6" --assert "-$1" == mold/part -$1234 3 + --test-- "form/mold-7" --assert "USD" == form/part +USD$0 3 + --test-- "form/mold-8" --assert "-EU" == mold/part -EUR$1 3 + --test-- "form/mold-9" + system/options/money-digits: -1 + --assert "$123" == mold $123.45678 + --assert "$123.45678" == mold/all $123.45678 + system/options/money-digits: 1 + --assert "-$123.4" == mold -$123.45678 + --assert "-$123.45678" == mold/all -$123.45678 + system/options/money-digits: 10 + --assert "$123.45678" == mold +$123.45678 + --assert "$123.45678" == mold/all +$123.45678 ===end-group=== ===start-group=== "add" From 0e24f92ef7d7dede0def8d012561cb7ff92c7484 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 16:00:42 +0100 Subject: [PATCH 1192/3432] TESTS: add more tests Covering operations on (in)compatible currencies and arithmetic semantics of *, / and %. --- tests/source/units/money-test.red | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 4691e32bf2..92cf392c23 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -233,6 +233,37 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert "$123.45678" == mold/all +$123.45678 ===end-group=== +===start-group=== "currencies" + --test-- "currencies-1" --assert 1 + USD$1 == USD$2 + --test-- "currencies-2" --assert USD$2 + 1 == USD$3 + --test-- "currencies-3" --assert USD$4 - USD$4 == USD$0 + --test-- "currencies-4" --assert $1 * -1 == -$1 + --test-- "currencies-5" --assert -2.0 * $1 == -$2 + --test-- "currencies-6" --assert error? try [USD$1 + EUR$1] + --test-- "currencies-7" --assert error? try [EUR$2 - USD$2] + --test-- "currencies-8" --assert USD$1 == $1 + --test-- "currencies-9" --assert -USD$2 == -USD$2 + --test-- "currencies-10" --assert error? try [EUR$123 <> USD$123] +===end-group=== + +===start-group=== "arithmetic" + --test-- "arithmetic-1" --assert error? try [$1 * $1] + --test-- "arithmetic-2" --assert $2 * 3 == $6 + --test-- "arithmetic-3" --assert $4 * 0.5 == $2 + --test-- "arithmetic-4" --assert 4 * $0.25 == $1 + --test-- "arithmetic-5" --assert 0.5 * $8 == $4 + --test-- "arithmetic-6" --assert $8 / $4 == 2.0 + --test-- "arithmetic-7" --assert $8 / 4 == $2 + --test-- "arithmetic-8" --assert $4 / 0.5 == $8 + --test-- "arithmetic-9" --assert error? try [4 / $2] + --test-- "arithmetic-10" --assert error? try [8.0 / $4] + --test-- "arithmetic-11" --assert $8 % $3 == $2 + --test-- "arithmetic-12" --assert $10 % 3 == $1 + --test-- "arithmetic-13" --assert $4 % 4.0 == $0 + --test-- "arithmetic-14" --assert error? try [8 % $8] + --test-- "arithmetic-15" --assert error? try [3.0 % $2] +===end-group=== + ===start-group=== "add" max-money: $99999999999999999.99999 min-money: negate max-money From d51235abb554df724192b1ad564e68981158215e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 16:21:10 +0100 Subject: [PATCH 1193/3432] TESTS: add a few AS-MONEY tests --- tests/source/units/money-test.red | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 92cf392c23..24b792c03c 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -384,6 +384,12 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "find-6" --assert last? find [a b c d $0.00001] $0.00001 ===end-group=== +===start-group=== "as-money" + --test-- "as-money-1" --assert "USD$123.00000" == mold/all as-money 'USD 123 + --test-- "as-money-2" --assert "-EUR$123.45678" == mold/all as-money 'EUR -123.45678 + --test-- "as-money-3" --assert "USD$0.00000" == mold/all as-money 'USD 0 +===end-group=== + ===start-group=== "generated" --test-- "generated-1-+" --assert -$46256738.73641 + -$382909867.62517 == -$429166606.36158 --test-- "generated-2-+" --assert -$861608569.91149 + -$385303837.42661 == -$1246912407.33810 From 9d25d06f7fe3e917d51fe2e8efb51c8358cc0547 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 18:18:46 +0100 Subject: [PATCH 1194/3432] FIX: issue #4198 ([Parse] KEEP PICK PAREN! semantics is undefined) --- runtime/parse.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index c64b2743f2..456533ba64 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -1580,7 +1580,7 @@ parser: context [ ][ cmd: cmd + 1 value: cmd + 1 - R_KEEP_PICK + either TYPE_OF(value) = TYPE_PAREN [R_KEEP_PAREN][R_KEEP_PICK] ][ R_KEEP ] From c1770257851db038bd34a28cc047a211e57b72ee Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 18:19:07 +0100 Subject: [PATCH 1195/3432] TESTS: test for issue #4198 --- tests/source/units/parse-test.red | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 62ec167d78..2149fe3c29 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2739,6 +2739,10 @@ Red [ --assert error? try [parse [][copy x4318]] --assert error? try [parse [][set x4318]] --assert zero? x4318 + + --test-- "#4198" + --assert [a] = parse [][collect keep pick ('a)] + --assert [[a b]] = parse [][collect keep pick ([a b])] ===end-group=== From c9b16429e33daaaa3920ef87085f8ca06ee86efc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 19:23:56 +0100 Subject: [PATCH 1196/3432] FEAT: define ANY_SERIES_PARSE? macro Used to check if a given series can be processed by Parse dialect. --- runtime/macros.reds | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runtime/macros.reds b/runtime/macros.reds index 8187817bf3..e4b2353817 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -403,6 +403,14 @@ Red/System [ ] ] +#define ANY_SERIES_PARSE?(type) [ ;-- any-series! types that can be processed by Parse + all [ + ANY_SERIES?(type) + type <> TYPE_IMAGE + type <> TYPE_VECTOR + ] +] + #define ANY_BLOCK_STRICT?(type) [ any [ type = TYPE_BLOCK From 10fe871a7c38e544be1ea3f0c2f6bb7f7bff17fa Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 20:43:54 +0100 Subject: [PATCH 1197/3432] FEAT: define new type of Parse error Used in cases where COLLECT INTO/AFTER attempts to collect input into a series of incompatible datatype: - Into BINARY! - From ANY-BLOCK! into ANY-STRING! Thus, only the following combinations are accepted: - Into ANY-BLOCK! - From ANY_STRING! into ANY-STRING! --- environment/system.red | 1 + 1 file changed, 1 insertion(+) diff --git a/environment/system.red b/environment/system.red index 9c85273b0f..c13e334cfc 100644 --- a/environment/system.red +++ b/environment/system.red @@ -173,6 +173,7 @@ system: context [ parse-stack: "PARSE - stack limit reached" parse-keep: "PARSE - KEEP is used without a wrapping COLLECT" parse-into-bad: "PARSE - COLLECT INTO/AFTER expects a series! argument" + parse-into-type: "PARSE - COLLECT INTO/AFTER expects a series! of compatible datatype" invalid-draw: ["invalid Draw dialect input at:" :arg1] invalid-data-facet: ["invalid DATA facet content" :arg1] face-type: ["VIEW - invalid face type:" :arg1] From 2d83f83e23f53a20e09259e1e3c7ce397da7e2a9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 20:44:32 +0100 Subject: [PATCH 1198/3432] FIX: issue #4197 ([Parse] COLLECT trashes series buffer) --- runtime/parse.reds | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/runtime/parse.reds b/runtime/parse.reds index c64b2743f2..50d119824c 100644 --- a/runtime/parse.reds +++ b/runtime/parse.reds @@ -792,6 +792,7 @@ parser: context [ state [states!] pos [byte-ptr!] ;-- required by BS_TEST_BIT_ALT() type [integer!] + type2 [integer!] dt-type [integer!] sym [integer!] min [integer!] @@ -1043,8 +1044,8 @@ parser: context [ if into? [ blk: as red-block! _context/get as red-word! blk type: TYPE_OF(blk) - unless ANY_SERIES?(type) [ - PARSE_ERROR [TO_ERROR(script parse-into-bad)] + unless ANY_SERIES_PARSE?(type) [ + PARSE_ERROR [TO_ERROR(script parse-into-type)] ] ] value: stack/top ;-- refer last value from paren expression @@ -1619,7 +1620,7 @@ parser: context [ ] value: block/rs-head input type: TYPE_OF(value) - either all [ANY_SERIES?(type) type <> TYPE_IMAGE][ + either ANY_SERIES_PARSE?(type) [ input: as red-series! block/rs-append series value min: R_NONE type: R_INTO @@ -1784,15 +1785,29 @@ parser: context [ ][ PARSE_ERROR [TO_ERROR(script parse-end) words/_collect] ] - either into? [get-word/push w][stack/push as red-value! w] + + either not into? [stack/push as red-value! w][ + value: _context/get w ;-- #4197 + type: TYPE_OF(value) + type2: TYPE_OF(input) + if any [ + type = TYPE_BINARY + all [ANY_STRING?(type) ANY_BLOCK?(type2)] + ][ + PARSE_ERROR [TO_ERROR(script parse-into-type)] + ] + + get-word/push w + ] + cmd: as red-value! w ] ] either into? [ blk: as red-block! _context/get w type: TYPE_OF(blk) - unless ANY_SERIES?(type) [ - PARSE_ERROR [TO_ERROR(script parse-into-bad)] + unless ANY_SERIES_PARSE?(type) [ + PARSE_ERROR [TO_ERROR(script parse-into-type)] ] max: either sym = words/after [-1][blk/head] ;-- save block cursor ][ From 3baf2fd95966a9ee259bea34fbecfc0073845f46 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 20 Mar 2020 20:45:36 +0100 Subject: [PATCH 1199/3432] TESTS: add Parse tests for issue #4197 Also fixes misbehaving #3951 test that breaks testing framework after the first run. --- tests/source/units/parse-test.red | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index 62ec167d78..a3681dc641 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2721,7 +2721,7 @@ Red [ --test-- "#3951" res: none - do "res: expand-directives/clean [[] #macro word! func [s e]['OK] WTF]()" + do "res: expand-directives/clean [[] #macro word! func [s e]['OK] WTF #reset]()" --assert res = [[] OK] --test-- "#3427" @@ -2740,6 +2740,23 @@ Red [ --assert error? try [parse [][set x4318]] --assert zero? x4318 + --test-- "#4197" + x4197: make string! 0 + --assert error? try [parse [][collect into x4197 []]] + x4197: make binary! 0 + --assert error? try [parse #{}[collect into x4197 []]] + x4197: make vector! 0 + --assert error? try [parse "" [collect into x4197 []]] + x4197: make block! 3 + parse quote (a b c) [collect into x4197 keep pick to end] + --assert x4197 = [a b c] + x4197: make paren! 3 + parse [collect into x4197 [keep to end [fail] | keep pick to end]] + --assert x4197 = quote ( #"a" #"b" #"c") + x4197: make tag! 3 + parse %abc [collect into X4197 [keep to end [fail] | keep pick to end]] + --assert x4197 = + ===end-group=== ~~~end-file~~~ From 991a286d9ebd5214a5a7f5043ff3619a5c8e3e73 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 21 Mar 2020 13:06:35 +0100 Subject: [PATCH 1200/3432] FEAT: grant wish #1956 (complement should be allowed on tuples) --- environment/actions.red | 4 ++-- runtime/datatypes/tuple.reds | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/environment/actions.red b/environment/actions.red index 8694f4f741..39534dc23b 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -197,8 +197,8 @@ and~: make action! [[ complement: make action! [[ "Returns the opposite (complementing) value of the input value" - value [logic! integer! bitset! typeset! binary!] - return: [logic! integer! bitset! typeset! binary!] + value [logic! integer! tuple! bitset! typeset! binary!] + return: [logic! integer! tuple! bitset! typeset! binary!] ] #get-definition ACT_COMPLEMENT ] diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index d9419c0632..8ef19889de 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -505,6 +505,22 @@ tuple: context [ #if debug? = yes [if verbose > 0 [print-line "tuple/xor~"]] as red-value! do-math OP_XOR ] + + complement: func [ + tp [red-tuple!] + return: [red-value!] + /local + array [byte-ptr!] + size [integer!] + ][ + #if debug? = yes [if verbose > 0 [print-line "tuple/complement"]] + + array: GET_TUPLE_ARRAY(tp) + size: TUPLE_SIZE?(tp) + + loop size [array/value: not array/value array: array + 1] + as red-value! tp + ] length?: func [ tp [red-tuple!] @@ -670,7 +686,7 @@ tuple: context [ null ;odd? ;-- Bitwise actions -- :and~ - null ;complement + :complement :or~ :xor~ ;-- Series actions -- From 112c2dca15738383297920e5c9263b444e1abd40 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 21 Mar 2020 18:43:00 +0100 Subject: [PATCH 1201/3432] FIX: money value at input tail not properly scanned by lexer. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 22163 -> 22158 bytes runtime/lexer-transitions.reds | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index aa5503d6b3..32a6cea7ec 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -36,8 +36,8 @@ S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_T S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;S_EMAIL;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 4e1fe24b15d41a25695bb764a441c24835caf59a..4ce2b39f6c529ee58dd4b379b8780ab188bf69a9 100644 GIT binary patch delta 8189 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 A5&!@I delta 8183 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 Soekqt(A!RGzrWSqPyYwS#rA*z diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 9ccc864065..1c2ea41654 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -102,7 +102,8 @@ Red/System [ 000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F 2B2B25253131310B0F0B2C2C2C2C0F0F0C0F0F100F092D190B0F0F140F000022 00000000000700000000070F140B130A0829260C0C272F252B312C092D0B07 -} transitions: #{ +} + transitions: #{ 0000181840414243443F02113131323232322732270F3F2A3232063F013F2F24 2E2E3F32323F3E01490101010101010101010101010101010101010101010101 0101010101010101010101013F3E020202020202020202024A02020202020202 @@ -149,8 +150,8 @@ Red/System [ 3F3F573F3F3F23233F3F573F573F3F3F3F5736233F3F3F3F3F3F3F573F3F2525 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F 3F3F3F59592525595959595959595925593F3F3F3F3F3F3F593F593F3F3F2659 -3F263F3F3F3F3F3F3F3E59592626595959595959595926593F3F3F3F3F3F3F59 -3F593F3F3F3F593F3F3F3F3F3F3F3F3F3E4B4B27274B4B4B4B4B4B4B3F323332 +3F263F3F3F3F3F3F3F5959592626595959595959595926593F3F3F3F3F3F3F59 +3F593F3F3F3F593F3F3F3F3F3F3F3F3F594B4B27274B4B4B4B4B4B4B3F323332 322832273227474B3232323F3F4B36322532323232323F4B5D5D32325D5D5D5D 5D5D5D3F323332323232323232475D3232323F3F5D36322532323232323F5D5D 5D3F3F5D5D5D5D5D5D5D3F3F3F3F3F3F3F3F3F3F475D5D3F3F3F3F5D363F253F From 17be32f29836b728bd3f015a3bec94a5556af0e3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 12:00:56 +0100 Subject: [PATCH 1202/3432] FIX: a minor typo in #4197 test --- tests/source/units/parse-test.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/source/units/parse-test.red b/tests/source/units/parse-test.red index a3681dc641..6b07b897e3 100644 --- a/tests/source/units/parse-test.red +++ b/tests/source/units/parse-test.red @@ -2754,7 +2754,7 @@ Red [ parse [collect into x4197 [keep to end [fail] | keep pick to end]] --assert x4197 = quote ( #"a" #"b" #"c") x4197: make tag! 3 - parse %abc [collect into X4197 [keep to end [fail] | keep pick to end]] + parse %abc [collect into x4197 [keep to end [fail] | keep pick to end]] --assert x4197 = ===end-group=== From ac5889aabb55c9a3d5070efc05e269aa32a47145 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 21 Mar 2020 18:43:00 +0100 Subject: [PATCH 1203/3432] FIX: money value at input tail not properly scanned by lexer. --- docs/lexer/lexer-FSM.csv | 4 ++-- docs/lexer/lexer-FSM.xlsx | Bin 22163 -> 22158 bytes runtime/lexer-transitions.reds | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index aa5503d6b3..32a6cea7ec 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -36,8 +36,8 @@ S_TIME;T_TIME;T_TIME;S_TIME;S_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_TIME;T_T S_PAIR_1ST;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR S_PAIR;T_PAIR;T_PAIR;S_PAIR;S_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;S_PAIR;S_PAIR;T_ERROR;T_ERROR;T_PAIR;T_ERROR;T_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR;S_EMAIL;S_PAIR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PAIR S_MONEY_1ST;T_ERROR;T_ERROR;S_MONEY;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR -S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF -S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_EOF +S_MONEY;T_MONEY;T_MONEY;S_MONEY;S_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;S_MONEY_DEC;T_MONEY;T_ERROR;S_MONEY_DEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY +S_MONEY_DEC;T_MONEY;T_MONEY;S_MONEY_DEC;S_MONEY_DEC;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;T_MONEY;S_MONEY_DEC;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_MONEY S_HEX;T_WORD;T_WORD;S_HEX;S_HEX;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_HEX_END;S_WORD;S_HEX;S_WORD;S_HEX;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_HEX_END;T_HEX;T_HEX;S_WORD;S_WORD;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_HEX;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_HEX;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_HEX S_HEX_END2;T_HEX;T_HEX;T_ERROR;T_ERROR;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_PATH;T_HEX;T_HEX;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX;S_EMAIL;T_ERROR;S_MONEY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_HEX diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 4e1fe24b15d41a25695bb764a441c24835caf59a..4ce2b39f6c529ee58dd4b379b8780ab188bf69a9 100644 GIT binary patch delta 8189 zcmZ{Jc{p2X`@f)66)jq{MHi%{C1|PCPVK}ROD(CQwUnWyf;#9Lw5q2nwov<$Ft*xa z>D0d0+Uj7`&RByW62D{KdEf8Myzei6b7?Xgw{2y4_>(B}%|abx&@4a*_VIYbABMa=*W_dgqv@8r_hz7hl7}LmgjHQ(=fr zJMQ9!Vs=J59?4|&`P7G!!3!7P)0;jop#m--}REWwkYQTJU_Tlk(VJ zT{S&~HnFyqk(?VP(8RG#XE2-&odH^bAn|MUqan4A*LoI`&NPEq^1ebHedB92ea}{> zk{swunOIvMuXu2KMJBW!2qEvA@9m>H$1@O_&Z~VoI1Cv2*hrS+ToHi#y(&z$sT3@?EHHDht}_@p>-h-=-K$U zvXy)Fs3#r!syvK6-?)@q>fcS@0jLY^eLt->Q(_I-&t=qaM_Llf4E7n@P z7FiW!B~E8`w`@x@8MC))``N_N3Eg&4!_m6!y2gMyh^#VaG3L|ex@vgrTCcLkK!W3d z{$!k7$5Z#*Z$xt)PY)&<>@$*`6Pm4J z`#@EyM>#yvu{AYETS{ug|BLCZY!L2%665KS$7U$pMan?8MQ1fTef!N>k72IG%r%3h zxLCz?)%`nl9=O6D82P=8Eu{XNg&V(=NuP@Mxb4=^xj0h}s*7F*TG((Idpl%N z4~gS?<$!};=C#}Lty8DV!yOK1*}^kRl&71eM%y%{JLb%%`<`LY(aVYF60$kIT!jm# z+ZI~fn$=eDlz7^IMyj#2?_=m0>#Qil6iRjA+Amar6@%|OsU6wy=?g=d)B4!-SIsdA zs{R=Pbw+ShHMXw<3?&=|)?M)M3}vC&HZfE-R;~lY5-zX1B)|)lZD-pgP#>`+9pGca zne{0=yc@>CJg<44)Qfzh$9{fZT|)S97E9j4v+ud5`ob~DH%0>Km+mg@+^4>(UiUqh zG`+k%qx*nZ=DQO(LsoDko0j|fU;Da|S#p8jeOmtp3W@FO0v!Ru2F2wK{IjyqblX>O zU5R14^hCd|{VK{0E7t?wBwVJr#K9MpzfH9%paQTZJ)joh45d*Cqb?$RIFkkU@a$V| zm%eaQGu55#93f$FYMdTxrnjD z_H~0Mgol(&a7I)PnEDc~{{O!zY`O+*<+PSUhqZf7VdJ#t2qh7M_lMzfABuH>k`Li4 zU3kzMwqM#Jz0n&b>8U545CwzGRHZgijTSoeZMp8(SKA`p(VZpEgcDIj8@DD&sUh3q zw#fVF-%FfRPXI57*WI2yz`jKhI&^!cOJ~<79_(yXh3wg@0@9-D0=zcMdTIrRD8+Ue zAJs5vvEJpr&`iE;zq~6{u9V@dC;_xg`6f(JLbP#dl9NK)7I#M)qrFO<<4@3tz;%}Fl51A%1J!+Mm!Ip z1Ku;8F}wcl!Om(`$gaI=sC25D0CQma&hw6Y09(6&SB`W>6zy$C1&4(9rP%K}lk~7> zg#oUc^oRXX>#b^wg~{;ysCJUW=*xZxl~BCnzxG)R)!x$ITe0+N-L-jBZe>7xE7N2E zXg4l(MhkE~X8D!uJ#hVhAoM3dyu3D}p1XF%aYcM`_r$+F<4=^B`dL}D+`_)~!%a=@ zE4+U9Vzs$9?KO{*ByoZZlINZWfLpV_HU6+FOrKtkF#x%#ezQKX%Z@fn!yehjGLoR_ zmD)Hsa32+YbJ69dqMDHmY8NZl3f?9}uevyFmelQe5@WHIOQtHy^vT(dk3m3H_F zujakjW13Mqgw_V)^Tq+`0UpJ-Tt3RwA9S&#`1AuZ=FRRLo46Qfw!Z*A9yW zTFw-XEKjRUbOtz)&C7!aBa*m$h@~UU*}_IjeG8}3A-+SH^WaqxESTpF(P2U?@-Vj} zok#IX2u{rV24cjem7|Z({mkYDB0OH)r??2bEFY&foC#B6zCcnHRd?THip3igu*W%@ zlWxA%MQDigqOphhEYJJKp?M@@8<4x&#rcN>f^W7Y+h|w zyN0sxd8YnD*?)oINo?)fo_0ge!i6G^+`j_SKn(xJRC>sby;B6wg3!fej?QXbToO6U zYvoQ&Q5GUpY}u zS*Y*?m^`~1tdkdSg_yoMko12$6Hu*W4&s!?z9yVnEqC-mxo6$ z{x(I;57TcVC(6f!Uo$fz;+$QK`Q<&+k1JIR+LiL^lS0BST+0+nwOR8>k`Xy0InMl~ z-r-89tu<+~z?Wb>8pCgRot2+z(JMCoOEIZ3mGa!KU zaS8lQoF71kBx`$=8Xr#Ny?WuENpD1&xQ0~35bOQJBfMo7?xA|a(=KSNXEXI(@;P!T zt8V>GDv!Cr(haP|*&|IhWBhto_+6mua?^Ly#^D17FKmkh3`#>7E4s>GRz8!~74qvY z@%N~tP_uta#Y5M*wS8WJmW+ff-z;x7&*KB!twP9EZiIuJO-!1q21~?q)>q6WCox7x zjMYDYqjG{kgsl8S)@M`34I!;x6k`OxE$~n!hu1}z44OI<<>Ps9>Un~x(@D63$={6)v0b9}qIz+TO z$(hmPT4=21Q*Yoc%CRR`?%YlGs%q~^5;QI_iFT_Ro_lHdsD}!xs_W^w*xa9J7MC)zKJeC(+y=B7lRb6b}p*Ix0W$ceJLWeBx???n^12p1I(N8a{RfGxF(O zJfO2*_XENQf&SZgb2N`2`!Pg+!oNHD1i}-e(BKvRP2A{;AdR)}^zH%ExKmW04cW%2 zuEdtBOlgW(M&2fsiPB*@Mg=%$`z~AyIgt-)WT~dc#EUu*aHSHFAFdtOC)u|o-TyeU znsqz%8?YK>jrN%!juKb&r!yJbD!+Ufoi(nRFvhx`TF^=7MvT5QtEYSvh%SG;`^oaP z;b;Pq$^SWSCs*!*sax{J42F4xe#G2~WM+Am{)8vUKjj_-=K%;^|m8rJNrkCQZQ_f@M zI4uosenek-KBW8zVuq8YeTyM{>!? z*rxt{#~=&U^Y`sIGR9a&IMO>FhRrkgvt;vhg2hsB!v%`aJ4YT<$vouq^@WL!8 zXmlhve)c5i8NHp$`$Sb_(o_eyB`OMJ7SNR67ZEMLX6DUu>1CE}gb2UUcc0rqo{jUH zCls;xUFsq`>H@#BzP&_(E>fceyNuw}XC^M>pi$|#?%$`HqzY2(h5adgd+mul!u_c|L6@f@`0pY-R)Lli+pP;~?fTD{wNE=fg%|n4V=;#}f$TzFCbd!Qu6$bZ@P`c}V?i z<~P%Lam0tgrk9>?X~U`GK8*te^}zrqWn+KG8fwpNtC8AW?;6`Z>ENo5MP(-bzT*c{ zJe{0hjBI%L$wmdU+i)~Yh*_T5?P#Z%peI*OLuXh5ODU5ZN9PgzH3WEBk{bvX)m&^e ztYN>XGf3nw^>B5pv+q)5bEjfVWD94KogIz&Sv=G6HhfL3i5K0V;VgqAv0l^}XY}{S zYd;NOm&Vl4kY+BheVuWoe<`RaFQAd#Um)YM%HW73Az4r)lj0k}UMb6F+jawht-T>XE)kKN~1s z`hI zS4Ek{o{zOw^_f`*tlXYp>i<8$#J8WyUsi&mXLl)vD103?m{%TBuSi51B8DWdp=&2; zpYqv@5_{RAKOS-uFcJ^-I6+P8h7Bl1Ap2G+hF7@MVy#BQ@7Rz)K!QunOkcSEY6v0+ zZ~dTB5JLK|G-zf7mFi{8{~*}8#p-nE+OGpxu5mSAEAMSCf4ijk&76`2E;XN#4<_P8 z9>fEJP8C5s#{8$}c%#c7WH)p+*ibN%vjsz|bZo^;DJ#V`t2tjWM9s!k6F7Ch;odDw zz^CMwf3|2(zzcJ0Iy16k5gLfmsFwF@|@J)}o2Tzg8w0IJsJ zfr)I1L}bD>v!hUr9>&_vQWc#v@$1Et`CLw?wi3AN16?)Qu;FZ7GK(?Rs21Yod8dLU9;6DEW+ym3QuueIs4~ibY=Q%>Mc(zf&f7LG)%3#SoG~QQjCnYzf{w6vWf_p(XiIi>k&4@}%8&X` zZWT?!hR9Y(M1F$gtuX3~O7Sd^f8VJ$;eLH!mIrO&^Tdp&kBO1kLps_02{PrW``q`k zYSzue3w&44-qY)SnI@|NhUI^+-mN*2li3@crX+a(z&`#*bPrjK(aVLa;B)G|$Bp!> z>rqMmTMm*R%W*X)6W$r#tZ?LfHr%w42~gn529-<_}|rV<$xlR0>I(s_U_{Yu>mVu_fi7g zsUmHuJv`P!B9v$|$ZHVoDDPte*I#K!uYPLOx1ZjHY)SaF7-@+i`y4@AKFHR6hU|Wv zvj>V8SUxJy6P7})ssnNEq#&T>JgBTywnUI!5@@A9jl^B*D7j~+ZwP$v92#05-q zgArIQB?2r{&bP|k*WwDjYuluACtZQR ziJMrNpZ`kyZ;g@GkhrxD9f;fS2jW)Yb=7G$73T@-=guyHNPWwneiAG4^M{gZWBVYq$8u5!KuDAi2FNV!9yD-C(B1AVk5660W0qr&2G~^( z*zoJpSd44Je`j~DX1mWqx$->C)qY?B;uNqn#{L;8)VB;1O zdvFU(dWbl5LS7nU%+KeU{;%%6_#E2Ha(IA!)~Hhoy>Y2u%BseCwoa%MhuhXI3Ug<_ zld}Eah92g2D!RN|-t?|Wbh)8G!{u;WSSf@sh`Y)IT-P;)++?$Tlx3uC`RnnfpP>mU zOT5?&jq*RHH(k(4W~TF&gK*Ut84v3`G1PacEw zB(GjkSQPGxXv&zFw9dz9k2q&HV}32j=RkFTO?){u)b!gy_5JY^-Cny*Qda%LoTG=x z>$%DxD6Jp`u>HJnnb-fJV0;7d-yuR8zdlo>7+SCDYQfnGI~u^Mg9I2}db8Bl5s|(f z7^F%(CU(GMbKH=VZcvQgV$p@s*v!pgGZGXRduMf{JT5jv`}I*GviRC@9H}fc@0`QV zL13&;{vi*gMuSnBr|4?nLl4ObJ`vuq5$gjoyQ`(f@fDVRI$9|MoKt}FSJ>53pVR_+ z{Q0#SXFf$|?#x<O4Da+`*`1qyyt$YWzj`?OAy(9K z(Y{j9vPyS-XK0~0Zg)Xvge>FQb!!ArRu>~eG?lD`D~Q5E%-xXqQfvsaqX(O&ttn+Z zX20eE#!pBZGf+z7uL@G7r@2$L>*JGR3AD#hka|A8=#oJc)NeOshE2F2ip>l;&7n*5YC z3J(g|Nv!*AP^74IjJ(y196w+N%ONeg{Wn-Pr$F;R4g}s6jW`xuO9n|QLVy+mJ**N@ zoY`_vjbo6qx@o?U(w& z>l)E8MX*WZEUXrs(ZIo8fj?>DfE{|z_wOxRU6WnVbH|#U$pAmfYRl;Gij3-b=-V3) z9qD3DN7R0$oBi6ev(Xbn9VamKz02ry#@ZUgaIZqm$47Ncm49EtaCM%+kY#ijIz95I zZ4XxnjCom)d^>69weXltz(n!?jw|{Ru$^S_Ir@6C*rwb~1vPLnV zn_l}ctp@KO7F=VQ9mF{_N?``6s#(EL zAE0^@#>8aB%*1q@>8~#}Fx*NNRs%LzSu&RzfuF3zKqOiQRsedSFR;0pAN=(H0ZLvE A5&!@I delta 8183 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 Soekqt(A!RGzrWSqPyYwS#rA*z diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 9ccc864065..1c2ea41654 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -102,7 +102,8 @@ Red/System [ 000007070707080808080807070707130F1429000A0A00140B0C0C0C0C0C272F 2B2B25253131310B0F0B2C2C2C2C0F0F0C0F0F100F092D190B0F0F140F000022 00000000000700000000070F140B130A0829260C0C272F252B312C092D0B07 -} transitions: #{ +} + transitions: #{ 0000181840414243443F02113131323232322732270F3F2A3232063F013F2F24 2E2E3F32323F3E01490101010101010101010101010101010101010101010101 0101010101010101010101013F3E020202020202020202024A02020202020202 @@ -149,8 +150,8 @@ Red/System [ 3F3F573F3F3F23233F3F573F573F3F3F3F5736233F3F3F3F3F3F3F573F3F2525 3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F 3F3F3F59592525595959595959595925593F3F3F3F3F3F3F593F593F3F3F2659 -3F263F3F3F3F3F3F3F3E59592626595959595959595926593F3F3F3F3F3F3F59 -3F593F3F3F3F593F3F3F3F3F3F3F3F3F3E4B4B27274B4B4B4B4B4B4B3F323332 +3F263F3F3F3F3F3F3F5959592626595959595959595926593F3F3F3F3F3F3F59 +3F593F3F3F3F593F3F3F3F3F3F3F3F3F594B4B27274B4B4B4B4B4B4B3F323332 322832273227474B3232323F3F4B36322532323232323F4B5D5D32325D5D5D5D 5D5D5D3F323332323232323232475D3232323F3F5D36322532323232323F5D5D 5D3F3F5D5D5D5D5D5D5D3F3F3F3F3F3F3F3F3F3F475D5D3F3F3F3F5D363F253F From d62ce8348b9fee155b898b9c667a9eb352f37af3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 19:17:25 +0100 Subject: [PATCH 1204/3432] FIX: issue #3766 (It is possible to unset a word using SET with BLOCK without /ANY refinement) --- runtime/datatypes/object.reds | 32 ++++++++++++++++++++++++++------ runtime/natives.reds | 31 ++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index af85d72d35..42a89dc23d 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -131,17 +131,18 @@ object: context [ set-many: func [ obj [red-object!] value [red-value!] + any? [logic!] only? [logic!] some? [logic!] /local ctx [red-context!] - blk [red-block!] - obj2 [red-object!] ctx2 [red-context!] + obj2 [red-object!] word [red-word!] values [red-value!] values2 [red-value!] tail [red-value!] + tail2 [red-value!] new [red-value!] old [red-value!] int [red-integer!] @@ -160,6 +161,7 @@ object: context [ on-set?: obj/on-set <> null s: as series! ctx/symbols/value word: as red-word! s/offset + tail2: s/tail if on-set? [ s: as series! obj/on-set/value @@ -170,11 +172,31 @@ object: context [ ] either all [not only? any [type = TYPE_BLOCK type = TYPE_OBJECT]][ + values2: either type = TYPE_BLOCK [ ;-- first value slot + block/rs-head as red-block! value + ][ + get-values as red-object! value + ] + + unless only? [ ;-- pre-check of unset values + i: 0 + while [word < tail2][ + if all [not any? TYPE_OF(values2) = TYPE_UNSET][ + fire [TO_ERROR(script need-value) word] + ] + i: i + 1 + word: word + 1 + values2: values2 + 1 + ] + ] + + word: word - i ;-- reset pointers after iteration + values2: values2 - i + either type = TYPE_BLOCK [ - blk: as red-block! value i: 0 while [values < tail][ - new: _series/pick as red-series! blk i + 1 null + new: _series/pick as red-series! value i + 1 null unless all [some? TYPE_OF(new) = TYPE_NONE][ either on-set? [ if all [i <> idx-s i <> idx-d][ ;-- do not overwrite event handlers @@ -193,8 +215,6 @@ object: context [ ][ obj2: as red-object! value ctx2: GET_CTX(obj2) - values2: get-values obj2 - while [values < tail][ i: _context/find-word ctx2 word/symbol yes if i > -1 [ diff --git a/runtime/natives.reds b/runtime/natives.reds index c67fc407c5..87aa0956b8 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -617,7 +617,7 @@ natives: context [ set*: func [ check? [logic!] - any? [integer!] + _any? [integer!] case? [integer!] _only? [integer!] _some? [integer!] @@ -625,19 +625,19 @@ natives: context [ w [red-word!] value [red-value!] blk [red-block!] + any? [logic!] only? [logic!] some? [logic!] ][ - #typecheck [set any? case? _only? _some?] + #typecheck [set _any? case? _only? _some?] w: as red-word! stack/arguments value: stack/arguments + 1 + any?: _any? <> -1 only?: _only? <> -1 some?: _some? <> -1 - if all [any? = -1 TYPE_OF(value) = TYPE_UNSET][ - fire [TO_ERROR(script need-value) w] - ] + if all [not any? TYPE_OF(value) = TYPE_UNSET][fire [TO_ERROR(script need-value) w]] switch TYPE_OF(w) [ TYPE_PATH @@ -649,13 +649,13 @@ natives: context [ interpreter/eval-path value null null yes yes no case? <> -1 ] TYPE_OBJECT [ - object/set-many as red-object! w value only? some? + object/set-many as red-object! w value any? only? some? stack/set-last value ] TYPE_BLOCK [ blk: as red-block! w stack/mark-native words/_anon - set-many blk value block/rs-length? blk only? some? + set-many blk value block/rs-length? blk any? only? some? stack/unwind stack/set-last value ] @@ -2944,6 +2944,7 @@ natives: context [ words [red-block!] value [red-value!] size [integer!] + any? [logic!] only? [logic!] some? [logic!] /local @@ -2954,11 +2955,23 @@ natives: context [ type [integer!] block? [logic!] ][ - i: 1 type: TYPE_OF(value) block?: any [type = TYPE_BLOCK type = TYPE_PAREN type = TYPE_HASH type = TYPE_MAP] if block? [blk: as red-block! value] + i: 1 + if all [block? not only?][ ;-- pre-check of unset values + while [i <= size][ + v: _series/pick as red-series! blk i null + if all [not any? TYPE_OF(v) = TYPE_UNSET][ + w: as red-word! _series/pick as red-series! words i null + fire [TO_ERROR(script need-value) w] + ] + i: i + 1 + ] + ] + + i: 1 while [i <= size][ v: either all [block? not only?][_series/pick as red-series! blk i null][value] unless all [some? TYPE_OF(v) = TYPE_NONE][ @@ -3102,7 +3115,7 @@ natives: context [ ] ] default [ - set-many blk as red-value! series size no no + set-many blk as red-value! series size yes no no ;@@ allow set/any semantics ] ] ] From 22140e9d02503840e3f2e8dc9a5a15c588a56b4c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 19:17:43 +0100 Subject: [PATCH 1205/3432] TESTS: tests for issue #3766 --- tests/source/units/evaluation-test.red | 71 +++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/tests/source/units/evaluation-test.red b/tests/source/units/evaluation-test.red index eabc6a8035..19a09aca1d 100644 --- a/tests/source/units/evaluation-test.red +++ b/tests/source/units/evaluation-test.red @@ -382,7 +382,76 @@ Red [ --assert obj2 = set/some obj obj2 --assert "make object! [a: 3 b: 7]" = mold/flat obj --assert "make object! [z: 0 a: none b: 7]" = mold/flat obj2 - + + --test-- "set-12" + a: 1 + b: 2 + --assert all [ + error? try [set [a b] ()] + a == 1 b == 2 + ] + + --test-- "set-13" + a: 1 + b: 2 + set/any [a b] () + --assert all [unset? :a unset? :b] + + --test-- "set-14" + a: 1 + b: 2 + --assert all [ + error? try [set [a b] reduce [3 ()]] + a == 1 b == 2 + ] + + --test-- "set-15" + a: 1 + b: 2 + set/any [a b] reduce [3 ()] + --assert all [a == 3 unset? :b] + + --test-- "set-16" + obj: object [a: 1 b: 2] + obj2: object [a: 3 b: 4] + unset in obj2 'b + --assert all [ + error? try [set obj obj2] + "make object! [a: 1 b: 2]" = mold/flat obj + ] + + --test-- "set-17" + obj: object [a: 1 b: 2] + obj2: object [a: 3 b: 4] + unset in obj2 'b + set/any obj obj2 + --assert "make object! [a: 3 b: unset]" = mold/flat obj + + --test-- "set-18" + obj: object [a: 1 b: 2] + --assert all [ + error? try [set obj ()] + "make object! [a: 1 b: 2]" = mold/flat obj + ] + + --test-- "set-19" + obj: object [a: 1 b: 2] + set/any obj () + --assert "make object! [a: unset b: unset]" = mold/flat obj + + --test-- "set-20" + obj: object [a: 1 b: 2] + blk: reduce [3 ()] + --assert all [ + error? try [set obj blk] + "make object! [a: 1 b: 2]" = mold/flat obj + ] + + --test-- "set-21" + obj: object [a: 1 b: 2] + blk: reduce [3 ()] + set/any obj blk + --assert "make object! [a: 3 b: unset]" = mold/flat obj ===end-group=== From 6df0e7b398f69d300a7bf6a2e1cc10c0e02b61ee Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 19:46:14 +0100 Subject: [PATCH 1206/3432] FIX: extend fix for #3766 onto MAP! case --- runtime/natives.reds | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 87aa0956b8..42cec20933 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2952,6 +2952,7 @@ natives: context [ v [red-value!] blk [red-block!] i [integer!] + sz [integer!] type [integer!] block? [logic!] ][ @@ -2960,8 +2961,9 @@ natives: context [ if block? [blk: as red-block! value] i: 1 - if all [block? not only?][ ;-- pre-check of unset values - while [i <= size][ + if all [block? not only?][ ;-- pre-check of unset values + sz: either type = TYPE_MAP [size << 1][size] ;-- cover all key/value pairs + while [i <= sz][ v: _series/pick as red-series! blk i null if all [not any? TYPE_OF(v) = TYPE_UNSET][ w: as red-word! _series/pick as red-series! words i null From 0cfb1bc1b858b4472706caaf90ec0436850793c3 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 19:46:47 +0100 Subject: [PATCH 1207/3432] TESTS: extend tests for #3766 with MAP! case --- tests/source/units/evaluation-test.red | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/source/units/evaluation-test.red b/tests/source/units/evaluation-test.red index 19a09aca1d..3438f08f95 100644 --- a/tests/source/units/evaluation-test.red +++ b/tests/source/units/evaluation-test.red @@ -452,6 +452,25 @@ Red [ blk: reduce [3 ()] set/any obj blk --assert "make object! [a: 3 b: unset]" = mold/flat obj + + + --test-- "set-22" + k: 1 + v: 2 + map: #(a: 3) + map/a: () + --assert all [ + error? try [set [k v] map] + k == 1 v == 2 + ] + + --test-- "set-23" + k: 1 + v: 2 + map: #(a: 3) + map/a: () + set/any [k v] map + --assert all [k == to set-word! 'a unset? :v] ===end-group=== From c4d47ae5a36dfe1e9d5ffa394edba6c4a7a03c9d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 20:47:19 +0100 Subject: [PATCH 1208/3432] FIX: refactor fix for #3766 --- runtime/natives.reds | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 42cec20933..1befb5776e 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2952,7 +2952,6 @@ natives: context [ v [red-value!] blk [red-block!] i [integer!] - sz [integer!] type [integer!] block? [logic!] ][ @@ -2961,14 +2960,20 @@ natives: context [ if block? [blk: as red-block! value] i: 1 - if all [block? not only?][ ;-- pre-check of unset values - sz: either type = TYPE_MAP [size << 1][size] ;-- cover all key/value pairs - while [i <= sz][ - v: _series/pick as red-series! blk i null - if all [not any? TYPE_OF(v) = TYPE_UNSET][ - w: as red-word! _series/pick as red-series! words i null + if all [block? not only?][ ;-- pre-check of unset values and non-words + while [i <= size][ + v: _series/pick as red-series! blk i null ;-- NONE if accessed over the tail + w: as red-word! _series/pick as red-series! words i null + + type: TYPE_OF(w) + unless ANY_WORD?(type) [ ;-- cannot set non-word + fire [TO_ERROR(script invalid-arg) w] + ] + + if all [not any? TYPE_OF(v) = TYPE_UNSET][ ;-- requires /any refinement fire [TO_ERROR(script need-value) w] ] + i: i + 1 ] ] @@ -2978,15 +2983,6 @@ natives: context [ v: either all [block? not only?][_series/pick as red-series! blk i null][value] unless all [some? TYPE_OF(v) = TYPE_NONE][ w: as red-word! _series/pick as red-series! words i null - type: TYPE_OF(w) - unless any [ - type = TYPE_WORD - type = TYPE_GET_WORD - type = TYPE_SET_WORD - type = TYPE_LIT_WORD - ][ - fire [TO_ERROR(script invalid-arg) w] - ] stack/keep ;-- avoid object event handler overwritting stack slots _context/set w v ;-- can trigger object event handler ] From 6c8c25f94e267c223b912055abdcf4066dd42284 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 20:47:44 +0100 Subject: [PATCH 1209/3432] TESTS: extend evaluation test suite --- tests/source/units/evaluation-test.red | 38 +++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tests/source/units/evaluation-test.red b/tests/source/units/evaluation-test.red index 3438f08f95..1b0b890edf 100644 --- a/tests/source/units/evaluation-test.red +++ b/tests/source/units/evaluation-test.red @@ -471,7 +471,43 @@ Red [ map/a: () set/any [k v] map --assert all [k == to set-word! 'a unset? :v] - + + --test-- "set-24" + a: 1 + b: 2 + e: try [set/any [a 1 b] reduce [3 4 ()]] + --assert all [ + error? e + e/id == 'invalid-arg + e/arg1 == 1 ;-- 1 is an integer, not a word + a == 1 b == 2 + ] + + --test-- "set-25" + a: 1 + b: 2 + e: try [set [a b 1] reduce [3 () 4]] + --assert all [ + error? e + e/id == 'need-value + e/arg1 == 'b ;-- b needs a value + a == 1 b == 2 + ] + + --test-- "set-26" + a: none + b: none + c: none + set [a b c][1 2] + --assert all [a == 1 b == 2 c == none] + + --test-- "set-27" + a: none + b: none + c: none + set [a b][1 2 3] + --assert all [a == 1 b == 2 c == none] + ===end-group=== ~~~end-file~~~ From 1609eb3ee1fd1379adc94e7cf032142ff3b29909 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 22:00:56 +0100 Subject: [PATCH 1210/3432] FIX: incorrect handling of SET case --- runtime/natives.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 1befb5776e..907dd63c2a 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2964,7 +2964,6 @@ natives: context [ while [i <= size][ v: _series/pick as red-series! blk i null ;-- NONE if accessed over the tail w: as red-word! _series/pick as red-series! words i null - type: TYPE_OF(w) unless ANY_WORD?(type) [ ;-- cannot set non-word fire [TO_ERROR(script invalid-arg) w] @@ -2983,6 +2982,8 @@ natives: context [ v: either all [block? not only?][_series/pick as red-series! blk i null][value] unless all [some? TYPE_OF(v) = TYPE_NONE][ w: as red-word! _series/pick as red-series! words i null + type: TYPE_OF(w) + unless ANY_WORD?(type) [fire [TO_ERROR(script invalid-arg) w]] stack/keep ;-- avoid object event handler overwritting stack slots _context/set w v ;-- can trigger object event handler ] From 43381a45be604d589aab451311412918fd7976f4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sun, 22 Mar 2020 22:01:26 +0100 Subject: [PATCH 1211/3432] TESTS: fix non-passing tests --- tests/source/units/evaluation-test.red | 64 +++++++++++++++----------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/tests/source/units/evaluation-test.red b/tests/source/units/evaluation-test.red index 1b0b890edf..895fbf81b7 100644 --- a/tests/source/units/evaluation-test.red +++ b/tests/source/units/evaluation-test.red @@ -386,7 +386,7 @@ Red [ --test-- "set-12" a: 1 b: 2 - --assert all [ + --assert to logic! all [ error? try [set [a b] ()] a == 1 b == 2 ] @@ -400,7 +400,7 @@ Red [ --test-- "set-14" a: 1 b: 2 - --assert all [ + --assert to logic! all [ error? try [set [a b] reduce [3 ()]] a == 1 b == 2 ] @@ -409,13 +409,13 @@ Red [ a: 1 b: 2 set/any [a b] reduce [3 ()] - --assert all [a == 3 unset? :b] + --assert to logic! all [a == 3 unset? :b] --test-- "set-16" obj: object [a: 1 b: 2] obj2: object [a: 3 b: 4] unset in obj2 'b - --assert all [ + --assert to logic! all [ error? try [set obj obj2] "make object! [a: 1 b: 2]" = mold/flat obj ] @@ -429,7 +429,7 @@ Red [ --test-- "set-18" obj: object [a: 1 b: 2] - --assert all [ + --assert to logic! all [ error? try [set obj ()] "make object! [a: 1 b: 2]" = mold/flat obj ] @@ -442,7 +442,7 @@ Red [ --test-- "set-20" obj: object [a: 1 b: 2] blk: reduce [3 ()] - --assert all [ + --assert to logic! all [ error? try [set obj blk] "make object! [a: 1 b: 2]" = mold/flat obj ] @@ -459,7 +459,7 @@ Red [ v: 2 map: #(a: 3) map/a: () - --assert all [ + --assert to logic! all [ error? try [set [k v] map] k == 1 v == 2 ] @@ -470,28 +470,32 @@ Red [ map: #(a: 3) map/a: () set/any [k v] map - --assert all [k == to set-word! 'a unset? :v] + --assert to logic! all [k == to set-word! 'a unset? :v] --test-- "set-24" - a: 1 - b: 2 - e: try [set/any [a 1 b] reduce [3 4 ()]] - --assert all [ - error? e - e/id == 'invalid-arg - e/arg1 == 1 ;-- 1 is an integer, not a word - a == 1 b == 2 + do [ ;-- compiler detects malformed set block + a: 1 + b: 2 + e: try [set/any [a 1 b] reduce [3 4 ()]] + --assert to logic! all [ + error? e + e/id == 'invalid-arg + e/arg1 == 1 ;-- 1 is an integer, not a word + a == 1 b == 2 + ] ] --test-- "set-25" - a: 1 - b: 2 - e: try [set [a b 1] reduce [3 () 4]] - --assert all [ - error? e - e/id == 'need-value - e/arg1 == 'b ;-- b needs a value - a == 1 b == 2 + do [ ;-- compiler detects malformed set block + a: 1 + b: 2 + e: try [set [a b 1] reduce [3 () 4]] + --assert to logic! all [ + error? e + e/id == 'need-value + e/arg1 == 'b ;-- b needs a value + a == 1 b == 2 + ] ] --test-- "set-26" @@ -499,15 +503,19 @@ Red [ b: none c: none set [a b c][1 2] - --assert all [a == 1 b == 2 c == none] + --assert to logic! all [a == 1 b == 2 c == none] --test-- "set-27" a: none b: none - c: none - set [a b][1 2 3] - --assert all [a == 1 b == 2 c == none] + c: 3 + set [a b][1 2 4] + --assert to logic! all [a == 1 b == 2 c == 3] + --test-- "set-28" ;-- compiler detects malformed set block + --assert do [error? try [set [a/b] 1]] + --assert do [error? try [set [a/b: :c/d] [1 2]]] + ===end-group=== ~~~end-file~~~ From 29143d18c065095bc128c1656f5d4471efc3367d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 14:32:38 +0100 Subject: [PATCH 1212/3432] FEAT: extend the list of base symbols with MONEY! accessors --- runtime/datatypes/common.reds | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 8611bd7d28..1ced737cc2 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -578,6 +578,11 @@ words: context [ second: -1 timezone: -1 + currency: -1 + amount: -1 + integral: -1 + fractional: -1 + user: -1 host: -1 @@ -820,6 +825,11 @@ words: context [ second: symbol/make "second" timezone: symbol/make "timezone" + currency: symbol/make "currency" + amount: symbol/make "amount" + integral: symbol/make "integral" + fractional: symbol/make "fractional" + user: symbol/make "user" host: symbol/make "host" From 83f0de7dda9be9b2feeb3d90df87f21cf9c20e5c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 14:33:07 +0100 Subject: [PATCH 1213/3432] FEAT: amend PICK spec to support MONEY! values --- environment/actions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index 6fbd3764e6..f272c19966 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -377,7 +377,7 @@ next: make action! [[ pick: make action! [[ "Returns the series value at a given index" - series [series! port! bitset! pair! tuple! date! time!] + series [series! port! bitset! pair! tuple! money! date! time!] index [scalar! any-string! any-word! block! logic! time!] return: [any-type!] ] From 9f78a099e562469c4405944a73c4891682e02f74 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 14:34:08 +0100 Subject: [PATCH 1214/3432] FEAT: preliminary work on MONEY! datatype accessors --- runtime/datatypes/money.reds | 114 +++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 054e2601b4..b30346c227 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -14,7 +14,7 @@ money: context [ verbose: 0 ;-- Base -- - + #enum sizes! [ SIZE_BYTES: 11 ;-- total number of bytes used to store amount SIZE_SCALE: 05 ;-- total number of digits (nibbles) used to store scale (fractional part) @@ -114,6 +114,20 @@ money: context [ ;-- Currency -- + get-currency-from: func [ + money [red-money!] + return: [red-value!] ;-- word or none + /local + index [integer!] + ][ + index: get-currency money + if zero? index [return none/push] ;-- generic currency + + block/rs-abs-at + as red-block! #get system/locale/currencies/base + index + ] + get-currency: func [ money [red-money!] return: [integer!] @@ -163,7 +177,7 @@ money: context [ ;@@ TBD: walk over extra list also either here = tail [-1][index] ] - + get-symbol: func [ index [integer!] return: [integer!] @@ -171,7 +185,8 @@ money: context [ base [red-block!] word [red-word!] ][ - assert positive? index + assert all [index > 0 index <= FFh] + base: as red-block! #get system/locale/currencies/base word: as red-word! block/rs-abs-at base index @@ -199,6 +214,31 @@ money: context [ ;-- Amount -- + get-amount-from: func [ + money [red-money!] + return: [red-value!] + ][ + as red-value! set-currency ;-- same value but without currency + as red-money! stack/push as red-value! money + 0 + ] + + get-integral-from: func [ + money [red-money!] + return: [red-value!] + ][ + --NOT_IMPLEMENTED-- + as red-value! money + ] + + get-fractional-from: func [ + money [red-money!] + return: [red-value!] + ][ + --NOT_IMPLEMENTED-- + as red-value! money + ] + get-amount: func [ money [red-money!] return: [byte-ptr!] @@ -598,6 +638,33 @@ money: context [ part - 2 ;-- compensate for $ and . characters ] + ;-- Deconstruction -- + + accessor!: alias function! [money [red-money!] return: [red-value!]] + + accessors: [ + :get-currency-from + :get-amount-from + :get-integral-from + :get-fractional-from + ] + + resolve-accessor: func [ + word [red-word!] + return: [integer!] + /local + sym [integer!] + ][ + sym: symbol/resolve word/symbol + case [ + sym = words/currency [1] + sym = words/amount [2] + sym = words/integral [3] + sym = words/fractional [4] + true [0] + ] + ] + ;-- Conversion -- overflow?: func [ @@ -1572,6 +1639,43 @@ money: context [ digit: get-digit get-amount money SIZE_INTEGRAL ;-- check if least significant bit is set as logic! digit and 1 ] + + eval-path: func [ + money [red-money!] + element [red-value!] + value [red-value!] + path [red-value!] + case? [logic!] + return: [red-value!] + /local + access [accessor!] + int [red-integer!] + index [integer!] + ][ + index: switch TYPE_OF(element) [ + TYPE_WORD [resolve-accessor as red-word! element] + TYPE_INTEGER [ + int: as red-integer! element + int/value + ] + default [0] + ] + + unless all [index > 0 index < 5][fire [TO_ERROR(script invalid-path) path element]] + + access: as accessor! accessors/index + access money + ] + + pick: func [ + money [red-money!] + index [integer!] + boxed [red-value!] + return: [red-value!] + ][ + --NOT_IMPLEMENTED-- + boxed + ] init: does [ datatype/register [ @@ -1585,7 +1689,7 @@ money: context [ :to :form :mold - null ;eval-path + :eval-path null ;set-path :compare ;-- Scalar actions -- @@ -1620,7 +1724,7 @@ money: context [ null ;length? null ;move null ;next - null ;pick + :pick null ;poke null ;put null ;remove From 28e4aae53917ca310437687dae1560a28616b651 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 16:20:20 +0100 Subject: [PATCH 1215/3432] FEAT: finish implementation of MONEY! datatype accessors Supported accessors (both paths and PICK action): - currency, amount, integral, fractional - ordinal accessors [1, 4] --- runtime/datatypes/money.reds | 42 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index b30346c227..75a4127bc3 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -35,6 +35,8 @@ money: context [ SIGN_MASK: 4000h ;-- used to get/set sign bit in the header SIGN_OFFSET: 14 + KEEP_FRACTIONAL: FFFF0F00h ;-- used to keep/skip fractional part (little-endian order) + MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 INT32_MAX_DIGITS: 10 INT32_MIN_AMOUNT: #{00000002147483648FFFFF} ;-- 0xF > 0x9, used to subvert comparison @@ -227,7 +229,11 @@ money: context [ money [red-money!] return: [red-value!] ][ - --NOT_IMPLEMENTED-- + money: as red-money! stack/push as red-value! money + money: absolute-money money ;-- discard sign + money: set-currency money 0 ;-- discard currency + money/amount3: money/amount3 and not KEEP_FRACTIONAL + as red-value! money ] @@ -235,7 +241,13 @@ money: context [ money [red-money!] return: [red-value!] ][ - --NOT_IMPLEMENTED-- + money: as red-money! stack/push as red-value! money + money: absolute-money money ;-- discard sign + money: set-currency money 0 ;-- discard currency + money/amount1: 0 + money/amount2: 0 + money/amount3: money/amount3 and KEEP_FRACTIONAL + as red-value! money ] @@ -279,13 +291,11 @@ money: context [ zero-out: func [ money [red-money!] - all? [logic!] ;-- no: keep currency index return: [red-money!] ][ - money/amount1: either all? [0][money/amount1 and FF000000h] + money/amount1: 0 money/amount2: 0 money/amount3: 0 - money ] @@ -475,7 +485,7 @@ money: context [ money: as red-money! slot money/header: TYPE_MONEY - zero-out money yes + zero-out money set-sign money as integer! sign ;-- currency code @@ -723,7 +733,7 @@ money: context [ extra index start [integer!] power digit [integer!] ][ - money: zero-out as red-money! stack/push* yes + money: zero-out as red-money! stack/push* money/header: TYPE_MONEY if zero? int [return money] @@ -845,7 +855,7 @@ money: context [ index: index + 1 ] - money: zero-out as red-money! stack/push* yes + money: zero-out as red-money! stack/push* money/header: TYPE_MONEY copy-memory (get-amount money) + SIZE_BYTES - length head length @@ -1661,8 +1671,7 @@ money: context [ default [0] ] - unless all [index > 0 index < 5][fire [TO_ERROR(script invalid-path) path element]] - + unless all [index > 0 index <= size? accessors][fire [TO_ERROR(script invalid-path) path element]] access: as accessor! accessors/index access money ] @@ -1672,9 +1681,18 @@ money: context [ index [integer!] boxed [red-value!] return: [red-value!] + /local + access [accessor!] ][ - --NOT_IMPLEMENTED-- - boxed + index: switch TYPE_OF(boxed) [ + TYPE_WORD [resolve-accessor as red-word! boxed] + TYPE_INTEGER [index] + default [0] + ] + + unless all [index > 0 index <= size? accessors][fire [TO_ERROR(script out-of-range) boxed]] + access: as accessor! accessors/index + access money ] init: does [ From e6fa99f54612c0d3e96f64e19a912e3e2cc994b2 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 16:20:44 +0100 Subject: [PATCH 1216/3432] TESTS: add tests for MONEY! datatype accessors --- tests/source/units/money-test.red | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 24b792c03c..be21268f78 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -390,6 +390,43 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "as-money-3" --assert "USD$0.00000" == mold/all as-money 'USD 0 ===end-group=== +===start-group=== "accessors" + money: -USD$123.45678 + --test-- "accessors-1" --assert 'USD == pick money 1 + --test-- "accessors-2" --assert "-$123.45678" == mold/all pick money 2 + --test-- "accessors-3" --assert "$123.00000" == mold/all pick money 3 + --test-- "accessors-4" --assert "$0.45678" == mold/all pick money 4 + --test-- "accessors-5" --assert 'USD == pick money 'currency + --test-- "accessors-6" --assert "-$123.45678" == mold/all pick money 'amount + --test-- "accessors-7" --assert "$123.00000" == mold/all pick money 'integral + --test-- "accessors-8" --assert "$0.45678" == mold/all pick money 'fractional + --test-- "accessors-9" --assert 'USD == money/1 + --test-- "accessors-10" --assert "-$123.45678" == mold/all money/2 + --test-- "accessors-11" --assert "$123.00000" == mold/all money/3 + --test-- "accessors-12" --assert "$0.45678" == mold/all money/4 + --test-- "accessors-13" --assert 'USD == money/currency + --test-- "accessors-14" --assert "-$123.45678" == mold/all money/amount + --test-- "accessors-15" --assert "$123.00000" == mold/all money/integral + --test-- "accessors-16" --assert "$0.45678" == mold/all money/fractional + --test-- "accessors-17" + money: -$123.45678 + --assert none == pick money 'currency + --assert none == pick money 1 + --assert none == money/currency + --assert none == money/1 + --test-- "accessors-18" + --assert error? try [pick money 0] + --assert error? try [pick money -1] + --assert error? try [pick money 5] + --assert error? try [pick money 1.0] + --assert error? try [pick money #"^C"] + --assert error? try [pick money 'foo] + --assert error? try [money/foo] + --assert error? try [money/0] + --assert error? try [money/-1] + --assert error? try [money/5] +===end-group=== + ===start-group=== "generated" --test-- "generated-1-+" --assert -$46256738.73641 + -$382909867.62517 == -$429166606.36158 --test-- "generated-2-+" --assert -$861608569.91149 + -$385303837.42661 == -$1246912407.33810 From 3a4db1321299eceb43d676ec2b0bbdf322a74357 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 18:48:55 +0100 Subject: [PATCH 1217/3432] TESTS: add tests for MONEY? and TRANSCODE --- tests/source/units/money-test.red | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index be21268f78..5ea5ae9885 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -384,6 +384,20 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "find-6" --assert last? find [a b c d $0.00001] $0.00001 ===end-group=== +===start-group=== "money?" + --test-- "money?-1" --assert money? $123.45678 + --test-- "money?-2" --assert not money? 123.45678 + --test-- "money?-3" --assert money? -USD$123.45678 + --test-- "money?-4" --assert not money? -123 +===end-group=== + +===start-group=== "transcode money" + --test-- "transcode-money-1" --assert money? load "$123" + --test-- "transcode-money-2" --assert money? first load "$123 $456" + --test-- "transcode-money-3" --assert money? last load "$123 -USD$456" + --test-- "transcode-money-4" --assert money! == transcode/prescan "+EUR$123.456 1 2 3" +===end-group=== + ===start-group=== "as-money" --test-- "as-money-1" --assert "USD$123.00000" == mold/all as-money 'USD 123 --test-- "as-money-2" --assert "-EUR$123.45678" == mold/all as-money 'EUR -123.45678 From 33ea9aa6f659a2097e3a997e82df603f7b03f4df Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 19:25:50 +0100 Subject: [PATCH 1218/3432] FEAT: construction of MONEY! from WORD! values --- runtime/datatypes/money.reds | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 75a4127bc3..f7db7c1f12 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -940,6 +940,22 @@ money: context [ set-currency money currency ] + from-word: func [ + word [red-word!] + return: [red-money!] + /local + money [red-money!] + index [integer!] + ][ + money: zero-out as red-money! stack/push* + money/header: TYPE_MONEY + + index: get-index symbol/resolve word/symbol + if negative? index [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY word]] + + set-currency money index + ] + from-string: func [ str [red-string!] return: [red-money!] @@ -1464,9 +1480,10 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/make"]] switch TYPE_OF(spec) [ + TYPE_WORD [from-word as red-word! spec] TYPE_BLOCK [from-block as red-block! spec] TYPE_BINARY [from-binary as red-binary! spec] - default [to proto spec type] + default [to proto spec type] ] ] From 92cce21a80e19dbe1b4db0cea3b9d93f1825d786 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 19:26:02 +0100 Subject: [PATCH 1219/3432] FEAT: minor optimization --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index f7db7c1f12..a46504b1c8 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1466,7 +1466,7 @@ money: context [ set-currency as red-money! result currency ] - SET_RETURN(result) ;-- some of the operations swap their argument slots + either any [op = OP_ADD op = OP_SUB][SET_RETURN(result)][result] ;-- swapped arguments ] ;-- Actions -- From 53f61b1b02bfb0157f7edf2b783577d1ca0bc9dc Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 19:47:28 +0100 Subject: [PATCH 1220/3432] FEAT: minor code formatting improvement --- runtime/datatypes/money.reds | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index a46504b1c8..4376f63e7e 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1666,7 +1666,7 @@ money: context [ digit: get-digit get-amount money SIZE_INTEGRAL ;-- check if least significant bit is set as logic! digit and 1 ] - + eval-path: func [ money [red-money!] element [red-value!] @@ -1680,12 +1680,9 @@ money: context [ index [integer!] ][ index: switch TYPE_OF(element) [ - TYPE_WORD [resolve-accessor as red-word! element] - TYPE_INTEGER [ - int: as red-integer! element - int/value - ] - default [0] + TYPE_WORD [resolve-accessor as red-word! element] + TYPE_INTEGER [int: as red-integer! element int/value] + default [0] ] unless all [index > 0 index <= size? accessors][fire [TO_ERROR(script invalid-path) path element]] From e7c0b9dd959609c5fb7e2cb5f07085dd77c58d5c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 21:17:17 +0100 Subject: [PATCH 1221/3432] FEAT: removal of redundant accessors, better naming /integral and /fractional are gone (equivalend to ROUND and REMAINDER), /currency is renamed to /code. --- runtime/datatypes/common.reds | 8 ++------ runtime/datatypes/money.reds | 15 ++++----------- tests/source/units/money-test.red | 32 ++++++++++++------------------- 3 files changed, 18 insertions(+), 37 deletions(-) diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 1ced737cc2..012a4d08f3 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -578,10 +578,8 @@ words: context [ second: -1 timezone: -1 - currency: -1 + code: -1 amount: -1 - integral: -1 - fractional: -1 user: -1 host: -1 @@ -825,10 +823,8 @@ words: context [ second: symbol/make "second" timezone: symbol/make "timezone" - currency: symbol/make "currency" + code: symbol/make "code" amount: symbol/make "amount" - integral: symbol/make "integral" - fractional: symbol/make "fractional" user: symbol/make "user" host: symbol/make "host" diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4376f63e7e..8cb11b000a 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -652,12 +652,7 @@ money: context [ accessor!: alias function! [money [red-money!] return: [red-value!]] - accessors: [ - :get-currency-from - :get-amount-from - :get-integral-from - :get-fractional-from - ] + accessors: [:get-currency-from :get-amount-from] resolve-accessor: func [ word [red-word!] @@ -667,10 +662,8 @@ money: context [ ][ sym: symbol/resolve word/symbol case [ - sym = words/currency [1] - sym = words/amount [2] - sym = words/integral [3] - sym = words/fractional [4] + sym = words/code [1] + sym = words/amount [2] true [0] ] ] @@ -1466,7 +1459,7 @@ money: context [ set-currency as red-money! result currency ] - either any [op = OP_ADD op = OP_SUB][SET_RETURN(result)][result] ;-- swapped arguments + SET_RETURN(result) ;-- swapped arguments ] ;-- Actions -- diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 5ea5ae9885..51d8a6e6a0 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -406,29 +406,21 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional ===start-group=== "accessors" money: -USD$123.45678 - --test-- "accessors-1" --assert 'USD == pick money 1 - --test-- "accessors-2" --assert "-$123.45678" == mold/all pick money 2 - --test-- "accessors-3" --assert "$123.00000" == mold/all pick money 3 - --test-- "accessors-4" --assert "$0.45678" == mold/all pick money 4 - --test-- "accessors-5" --assert 'USD == pick money 'currency - --test-- "accessors-6" --assert "-$123.45678" == mold/all pick money 'amount - --test-- "accessors-7" --assert "$123.00000" == mold/all pick money 'integral - --test-- "accessors-8" --assert "$0.45678" == mold/all pick money 'fractional - --test-- "accessors-9" --assert 'USD == money/1 - --test-- "accessors-10" --assert "-$123.45678" == mold/all money/2 - --test-- "accessors-11" --assert "$123.00000" == mold/all money/3 - --test-- "accessors-12" --assert "$0.45678" == mold/all money/4 - --test-- "accessors-13" --assert 'USD == money/currency - --test-- "accessors-14" --assert "-$123.45678" == mold/all money/amount - --test-- "accessors-15" --assert "$123.00000" == mold/all money/integral - --test-- "accessors-16" --assert "$0.45678" == mold/all money/fractional - --test-- "accessors-17" + --test-- "accessors-1" --assert 'USD == pick money 1 + --test-- "accessors-2" --assert "-$123.45678" == mold/all pick money 2 + --test-- "accessors-3" --assert 'USD == pick money 'code + --test-- "accessors-4" --assert "-$123.45678" == mold/all pick money 'amount + --test-- "accessors-5" --assert 'USD == money/1 + --test-- "accessors-6" --assert "-$123.45678" == mold/all money/2 + --test-- "accessors-7" --assert 'USD == money/code + --test-- "accessors-8" --assert "-$123.45678" == mold/all money/amount + --test-- "accessors-9" money: -$123.45678 - --assert none == pick money 'currency + --assert none == pick money 'code --assert none == pick money 1 - --assert none == money/currency + --assert none == money/code --assert none == money/1 - --test-- "accessors-18" + --test-- "accessors-10" --assert error? try [pick money 0] --assert error? try [pick money -1] --assert error? try [pick money 5] From afdae9eff536248c14713ec7132e7bf42a77da86 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 21:20:47 +0100 Subject: [PATCH 1222/3432] TESTS: add a few MAKE tests for WORD! prototype --- tests/source/units/money-test.red | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 51d8a6e6a0..a2733ac3a7 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -210,6 +210,9 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-9" --assert -USD$123 == make money! [USD -123] --test-- "make-10" --assert -EUR$123 == make money! [EUR -123 0] --test-- "make-11" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] + --test-- "make-12" --assert "USD$0.00000" == mold/all make money! 'usd + --test-- "make-13" --assert "EUR$0.00000" == mold/all make money! 'EUR + --test-- "make-14" --assert error? try [make money! 'foo] ===end-group=== ===start-group=== "form/mold" From 51e36f87283b06479fcff76cffd0b206e0cda015 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 24 Mar 2020 21:28:08 +0100 Subject: [PATCH 1223/3432] FEAT: remove redundant definitions --- runtime/datatypes/money.reds | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 8cb11b000a..4e8a935ea3 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -35,8 +35,6 @@ money: context [ SIGN_MASK: 4000h ;-- used to get/set sign bit in the header SIGN_OFFSET: 14 - KEEP_FRACTIONAL: FFFF0F00h ;-- used to keep/skip fractional part (little-endian order) - MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 INT32_MAX_DIGITS: 10 INT32_MIN_AMOUNT: #{00000002147483648FFFFF} ;-- 0xF > 0x9, used to subvert comparison @@ -225,32 +223,6 @@ money: context [ 0 ] - get-integral-from: func [ - money [red-money!] - return: [red-value!] - ][ - money: as red-money! stack/push as red-value! money - money: absolute-money money ;-- discard sign - money: set-currency money 0 ;-- discard currency - money/amount3: money/amount3 and not KEEP_FRACTIONAL - - as red-value! money - ] - - get-fractional-from: func [ - money [red-money!] - return: [red-value!] - ][ - money: as red-money! stack/push as red-value! money - money: absolute-money money ;-- discard sign - money: set-currency money 0 ;-- discard currency - money/amount1: 0 - money/amount2: 0 - money/amount3: money/amount3 and KEEP_FRACTIONAL - - as red-value! money - ] - get-amount: func [ money [red-money!] return: [byte-ptr!] From a43c36c7fba32c79b711524f36cd913d00170bed Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Wed, 25 Mar 2020 21:06:30 +0800 Subject: [PATCH 1224/3432] FIX: issue #4366 ([CRASH] on `image/argb: data`). --- runtime/datatypes/image.reds | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 156bc18415..59b40e2b8b 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -232,6 +232,7 @@ image: context [ /local offset [integer!] sz [integer!] + bin-sz [integer!] s [series!] p [byte-ptr!] stride [integer!] @@ -256,11 +257,16 @@ image: context [ type: TYPE_OF(bin) either type = TYPE_BINARY [ + bin-sz: binary/rs-length? bin s: GET_BUFFER(bin) p: as byte-ptr! s/offset either method = EXTRACT_ARGB [ - copy-memory as byte-ptr! data p sz * 4 + sz: sz * 4 + if bin-sz < sz [sz: bin-sz] + copy-memory as byte-ptr! data p sz ][ + if method = EXTRACT_RGB [bin-sz: bin-sz / 3] ;-- number of pixels + if bin-sz < sz [end: data + bin-sz] while [data < end][ pixel: data/value either method = EXTRACT_ALPHA [ From baa3f51a56ceba361c374615404718622bd7acf9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 25 Mar 2020 20:45:52 +0100 Subject: [PATCH 1225/3432] FEAT: adds comma support to float FSM loader. --- docs/lexer/lexer-states.txt | 6 +++--- runtime/lexer.reds | 2 +- utils/generate-misc-tables.red | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 07dc37bce9..9210e9ffc1 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -409,7 +409,7 @@ C_FL_ILLEGAL : all the rest ;-- 0 C_FL_SIGN : +, - ;-- 1 C_FL_DIGIT : 0-9 ;-- 2 C_FL_EXP : e, E ;-- 3 -C_FL_DOT : . ;-- 4 +C_FL_DOT : ., ;-- 4 S_FL_START ;-- 0 S_FL_NUM ;-- 1 @@ -423,9 +423,9 @@ T_FL_ERROR ;-- 7 S_FL_START->"+"|"-"->S_FL_START -S_FL_START->"."->S_FL_DEC +S_FL_START->"."|","->S_FL_DEC \->digit->S_FL_NUM->digit->S_FL_NUM - \->"."->S_FL_DEC + \->"."|","->S_FL_DEC \->"e"|"E"->S_FL_EXP S_FL_DEC->digit->S_FL_DEC diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a038b4a0e3..d364de8112 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -116,7 +116,7 @@ lexer: context [ float-classes: #{ 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000010001040002020202020202020202000000000000 + 0000000000000000000000010401040002020202020202020202000000000000 0000000000030000000000000000000000000000000000000000000000000000 00000000000300 } diff --git a/utils/generate-misc-tables.red b/utils/generate-misc-tables.red index 5e39358749..566b371e84 100644 --- a/utils/generate-misc-tables.red +++ b/utils/generate-misc-tables.red @@ -83,7 +83,7 @@ gen-float-classes-table: function [][ c: to-char i - 1 append out case [ find digit c [2] - c = #"." [4] + find ".," c [4] find "+-" c [1] find "eE" c [3] 'else [0] From 4ccf480bef4a033b88bf68041c98b0c0d1c70a66 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 25 Mar 2020 16:25:25 +0100 Subject: [PATCH 1226/3432] FIX: issue #4364 (Extra indentation spaces in `mold/flat` output) --- runtime/datatypes/object.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/object.reds b/runtime/datatypes/object.reds index af85d72d35..18038da0d7 100644 --- a/runtime/datatypes/object.reds +++ b/runtime/datatypes/object.reds @@ -1115,7 +1115,7 @@ object: context [ string/concatenate-literal buffer "make object! [" part: serialize obj buffer no all? flat? arg part - 14 yes indent + 1 yes - if indent > 0 [part: do-indent buffer indent part] + if all [not flat? indent > 0][part: do-indent buffer indent part] string/append-char GET_BUFFER(buffer) as-integer #"]" part - 1 ] From e9e1ad44fda0d1bdd939696a87fa55d078654e0e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 26 Mar 2020 17:18:35 +0100 Subject: [PATCH 1227/3432] FIX: properly report literal money value with invalid currency code --- runtime/datatypes/money.reds | 5 ++--- runtime/lexer.reds | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4e8a935ea3..77fe72e837 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -444,7 +444,7 @@ money: context [ start [byte-ptr!] ;-- $ sign point [byte-ptr!] ;-- can be null if fractional part is not present end [byte-ptr!] ;-- points past the money literal - return: [red-money!] + return: [red-money!] ;-- null if currency code is invalid /local convert [subroutine!] money [red-money!] @@ -465,8 +465,7 @@ money: context [ str: "..." ;-- 3 letters copy-memory as byte-ptr! str currency 3 index: get-index symbol/make str - ;@@ TBD: better error message - if negative? index [fire[TO_ERROR(note no-load) datatype/push TYPE_MONEY]] + if negative? index [return null] set-currency money index ] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a038b4a0e3..41e1d17b83 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1884,7 +1884,9 @@ lexer: context [ p: p + 1 ] lex/in-pos: e ;-- reset the input position to delimiter byte - if load? [money/make-at alloc-slot lex neg? cur st ds e] + if load? [ + if null? money/make-at alloc-slot lex neg? cur st ds e [do-error] + ] ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ From d2af01ff9d971cf01f38564df5ba18e4abf7895b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 26 Mar 2020 18:35:21 +0100 Subject: [PATCH 1228/3432] FIX: regression in conversion from string MAKE-AT returns NULL if currency code is invalid, that tripped up FROM-STRING conversion that didn't properly check for return value. --- runtime/datatypes/money.reds | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 77fe72e837..9494cb6dd1 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -465,7 +465,7 @@ money: context [ str: "..." ;-- 3 letters copy-memory as byte-ptr! str currency 3 index: get-index symbol/make str - if negative? index [return null] + if negative? index [return null] ;-- throw it back to lexer for proper error reporting set-currency money index ] @@ -516,7 +516,7 @@ money: context [ return: [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] - make-at ALLOC_TAIL(parent) sign currency start point end + make-at ALLOC_TAIL(parent) sign currency start point end ;@@ can return null ] push: func [ @@ -926,6 +926,7 @@ money: context [ /local bail make [subroutine!] end? dot? digit? [subroutine!] + money [red-money!] tail head here [byte-ptr!] currency digits [byte-ptr!] start point [byte-ptr!] @@ -933,7 +934,11 @@ money: context [ sign [logic!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] - make: [return make-at stack/push* sign currency start point tail] + make: [ + money: make-at stack/push* sign currency start point tail + if null? money [bail] ;-- invalid currency code + return money + ] end?: [here >= tail] dot?: [any [here/value = #"." here/value = #","]] From 558f9de404c2007cf4c094128262b9449d68ec7c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 26 Mar 2020 14:38:37 +0100 Subject: [PATCH 1229/3432] FIX: issue #4056 ([Regression] `tail?` and `empty?` on image are missing by one pixel) --- runtime/datatypes/image.reds | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/image.reds b/runtime/datatypes/image.reds index 59b40e2b8b..ed7f879d43 100644 --- a/runtime/datatypes/image.reds +++ b/runtime/datatypes/image.reds @@ -829,7 +829,7 @@ image: context [ img: as red-image! stack/arguments offset: img/head + 1 - if IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) > offset [ + if IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) >= offset [ img/head: offset ] img @@ -850,16 +850,18 @@ image: context [ tail?: func [ return: [red-value!] /local - img [red-image!] - state [red-logic!] + img [red-image!] + state [red-logic!] + offset [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "image/tail?"]] - img: as red-image! stack/arguments - state: as red-logic! img + img: as red-image! stack/arguments + state: as red-logic! img + offset: img/head + 1 state/header: TYPE_LOGIC - state/value: IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) <= (img/head + 1) + state/value: not IMAGE_WIDTH(img/size) * IMAGE_HEIGHT(img/size) >= offset as red-value! state ] From 84d5ccb0acad53bfc02276f2d7cc454bfeb31eab Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 26 Mar 2020 14:38:52 +0100 Subject: [PATCH 1230/3432] TESTS: regression tests for issue #4056 --- tests/source/units/regression-test-red.red | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/source/units/regression-test-red.red b/tests/source/units/regression-test-red.red index fcfa1ca011..611fa7bba3 100644 --- a/tests/source/units/regression-test-red.red +++ b/tests/source/units/regression-test-red.red @@ -2841,6 +2841,14 @@ comment { ] } + --test-- "#4056" + i4056: either unset? :image! [[1 2]][make image! 2x2] + --assert tail? tail i4056 + --assert tail? next next next tail i4056 + --assert not tail? i4056 + --assert tail? next next next next i4056 + --assert tail? next back next tail i4056 + ===end-group=== ~~~end-file~~~ From c0aae40e1baddd5a0b9d0e86ad79ba47d3534d5a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 13:41:12 +0100 Subject: [PATCH 1231/3432] TESTS: add a few BINARY! conversion tests --- tests/source/units/money-test.red | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index a2733ac3a7..39d62d713b 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -179,7 +179,9 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "to-24" --assert error? try [to money! "CCC$123"] --test-- "to-25" --assert error? try [to money! "123$456"] --test-- "to-26" --assert error? try [to money! "EUR123"] - --test-- "to-27" + --test-- "to-27" --assert #{00 00 00 00 00 00 00 00 00 00 00} == to binary! $0 + --test-- "to-28" --assert #{00 00 00 00 00 00 01 23 45 67 89} == to binary! -USD$1234.56789 + --test-- "to-29" --assert error? try [to money! "$"] --assert error? try [to money! "$."] --assert error? try [to money! "-$."] From 64561c0b712fc949a57269fb5026db78480dda16 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 14:17:39 +0100 Subject: [PATCH 1232/3432] FEAT: code refactoring. --- runtime/datatypes/money.reds | 481 +++++++++++++++++------------------ 1 file changed, 238 insertions(+), 243 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 9494cb6dd1..59f3586183 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -66,16 +66,8 @@ money: context [ S_END ] - #define SWAP_ARGUMENTS(this-argument that-argument) [ - use [hold][ - hold: this-argument - this-argument: that-argument - that-argument: hold - ] - ] - - #define DISPATCH_SIGNS [switch collate-signs this-sign that-sign] - + #define SWAP_ARGUMENTS [use [hold][hold: value1 value1: value2 value2: hold]] + #define DISPATCH_SIGNS [switch collate-signs sign1 sign2] #define MONEY_OVERFLOW [fire [TO_ERROR(script type-limit) datatype/push TYPE_MONEY]] ;-- Sign -- @@ -105,11 +97,11 @@ money: context [ ] collate-signs: func [ - this-sign [integer!] - that-sign [integer!] - return: [integer!] + sign1 [integer!] + sign2 [integer!] + return: [integer!] ][ - this-sign + 1 << 4 or (that-sign + 1) + sign1 + 1 << 4 or (sign2 + 1) ] ;-- Currency -- @@ -195,20 +187,20 @@ money: context [ ] same-currencies?: func [ - this-money [red-money!] - that-money [red-money!] - return: [logic!] + value1 [red-money!] + value2 [red-money!] + return: [logic!] /local - this-currency [integer!] - that-currency [integer!] + currency1 [integer!] + currency2 [integer!] ][ - this-currency: get-currency this-money - that-currency: get-currency that-money + currency1: get-currency value1 + currency2: get-currency value2 any [ - zero? this-currency ;-- 0: generic currency - zero? that-currency - this-currency = that-currency + zero? currency1 ;-- 0: generic currency + zero? currency2 + currency1 = currency2 ] ] @@ -254,11 +246,11 @@ money: context [ ] compare-amounts: func [ - this-amount [byte-ptr!] - that-amount [byte-ptr!] - return: [integer!] + amount1 [byte-ptr!] + amount2 [byte-ptr!] + return: [integer!] ][ - compare-memory this-amount that-amount SIZE_BYTES + compare-memory amount1 amount2 SIZE_BYTES ] zero-out: func [ @@ -277,19 +269,19 @@ money: context [ offset [integer!] return: [byte-ptr!] /local - this-index [integer!] - that-index [integer!] - half [byte!] + index1 [integer!] + index2 [integer!] + half [byte!] ][ loop offset [ - this-index: 1 - that-index: this-index + 1 + index1: 1 + index2: index1 + 1 loop size [ - half: either that-index > size [null-byte][amount/that-index >>> 4] - amount/this-index: amount/this-index << 4 or half + half: either index2 > size [null-byte][amount/index2 >>> 4] + amount/index1: amount/index1 << 4 or half - this-index: this-index + 1 - that-index: that-index + 1 + index1: index1 + 1 + index2: index2 + 1 ] ] @@ -302,19 +294,19 @@ money: context [ offset [integer!] return: [byte-ptr!] /local - this-index [integer!] - that-index [integer!] - half [byte!] + index1 [integer!] + index2 [integer!] + half [byte!] ][ loop offset [ - this-index: size - that-index: this-index - 1 + index1: size + index2: index1 - 1 loop size [ - half: either that-index < 1 [null-byte][amount/that-index << 4] - amount/this-index: amount/this-index >>> 4 or half + half: either index2 < 1 [null-byte][amount/index2 << 4] + amount/index1: amount/index1 >>> 4 or half - this-index: this-index - 1 - that-index: that-index - 1 + index1: index1 - 1 + index2: index2 - 1 ] ] @@ -378,60 +370,60 @@ money: context [ ;-- Slices -- compare-slices: func [ - this-buffer [byte-ptr!] this-high? [logic!] this-count [integer!] - that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] + buffer1 [byte-ptr!] high1? [logic!] count1 [integer!] + buffer2 [byte-ptr!] high2? [logic!] count2 [integer!] return: [integer!] /local - delta index1 index2 end this-digit that-digit [integer!] + delta index1 index2 end digit1 digit2 [integer!] ][ - delta: integer/abs this-count - that-count - switch integer/sign? this-count - that-count [ - -1 [index1: 1 - delta index2: 1 end: that-count] - 00 [index1: 1 index2: 1 end: this-count] - +1 [index2: 1 - delta index1: 1 end: this-count] + delta: integer/abs count1 - count2 + switch integer/sign? count1 - count2 [ + -1 [index1: 1 - delta index2: 1 end: count2] + 00 [index1: 1 index2: 1 end: count1] + +1 [index2: 1 - delta index1: 1 end: count1] default [0] ] - index1: index1 + as integer! this-high? - index2: index2 + as integer! that-high? + index1: index1 + as integer! high1? + index2: index2 + as integer! high2? until [ - this-digit: either index1 < 1 [0][get-digit this-buffer index1] - that-digit: either index2 < 1 [0][get-digit that-buffer index2] + digit1: either index1 < 1 [0][get-digit buffer1 index1] + digit2: either index2 < 1 [0][get-digit buffer2 index2] index1: index1 + 1 index2: index2 + 1 end: end - 1 - any [this-digit <> that-digit zero? end] + any [digit1 <> digit2 zero? end] ] - this-digit - that-digit + digit1 - digit2 ] subtract-slice: func [ - this-buffer [byte-ptr!] this-high? [logic!] this-count [integer!] - that-buffer [byte-ptr!] that-high? [logic!] that-count [integer!] + buffer1 [byte-ptr!] high1? [logic!] count1 [integer!] + buffer2 [byte-ptr!] high2? [logic!] count2 [integer!] /local - this-digit that-digit borrow difference [integer!] + digit1 digit2 borrow difference [integer!] ][ - this-count: this-count + as integer! this-high? - that-count: that-count + as integer! that-high? + count1: count1 + as integer! high1? + count2: count2 + as integer! high2? borrow: 0 until [ - this-digit: get-digit this-buffer this-count - that-digit: either that-count < 1 [0][get-digit that-buffer that-count] + digit1: get-digit buffer1 count1 + digit2: either count2 < 1 [0][get-digit buffer2 count2] - difference: this-digit - that-digit - borrow ;-- assumming this-buffer >= that-buffer + difference: digit1 - digit2 - borrow ;-- assumming buffer1 >= buffer2 borrow: as integer! difference < 0 if as logic! borrow [difference: difference + 10] - set-digit this-buffer this-count difference + set-digit buffer1 count1 difference - this-count: this-count - 1 - that-count: that-count - 1 + count1: count1 - 1 + count2: count2 - 1 - zero? this-count + zero? count1 ] ] @@ -825,19 +817,19 @@ money: context [ copy-memory (get-amount money) + SIZE_BYTES - length head length money ] - + from-block: func [ blk [red-block!] return: [red-money!] /local - bail [subroutine!] - money fraction [red-money!] - wrd [red-word!] - int [red-integer!] - flt [red-float!] - head tail here [red-value!] - currency [integer!] - state type length [integer!] + bail [subroutine!] + money fraction [red-money!] + wrd [red-word!] + int [red-integer!] + flt [red-float!] + head tail here [red-value!] + currency state [integer!] + type length [integer!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] @@ -999,24 +991,24 @@ money: context [ ;-- Comparison -- compare-money: func [ - this-money [red-money!] - that-money [red-money!] - return: [integer!] + value1 [red-money!] + value2 [red-money!] + return: [integer!] /local - this-sign that-sign [integer!] + sign1 sign2 [integer!] ][ - this-sign: sign? this-money - that-sign: sign? that-money + sign1: sign? value1 + sign2: sign? value2 DISPATCH_SIGNS [ - SIGN_-- [SWAP_ARGUMENTS(this-money that-money) 0] + SIGN_-- [SWAP_ARGUMENTS] SIGN_++ [0] - default [return integer/sign? this-sign - that-sign] + default [return integer/sign? sign1 - sign2] ] integer/sign? compare-amounts ;-- must return strictly -1, 0 or +1 - get-amount this-money - get-amount that-money + get-amount value1 + get-amount value2 ] negative-money?: func [ @@ -1066,160 +1058,163 @@ money: context [ ] add-money: func [ ;-- long addition - augend [red-money!] - addend [red-money!] + value1 [red-money!] + value2 [red-money!] return: [red-money!] /local - this-amount that-amount [byte-ptr!] - this-sign that-sign [integer!] - index carry left right sum [integer!] + amount1 amount2 [byte-ptr!] + sign1 sign2 [integer!] + index carry sum [integer!] + digit1 digit2 [integer!] ][ - this-sign: sign? augend - that-sign: sign? addend + sign1: sign? value1 + sign2: sign? value2 DISPATCH_SIGNS [ SIGN_00 SIGN_-0 - SIGN_+0 [return augend] + SIGN_+0 [return value1] SIGN_0- - SIGN_0+ [return addend] - SIGN_+- [return subtract-money augend absolute-money addend] - SIGN_-+ [return subtract-money addend absolute-money augend] + SIGN_0+ [return value2] + SIGN_+- [return subtract-money value1 absolute-money value2] + SIGN_-+ [return subtract-money value2 absolute-money value1] default [0] ] - this-amount: get-amount augend - that-amount: get-amount addend + amount1: get-amount value1 + amount2: get-amount value2 - if (get-digit this-amount 1) + (get-digit that-amount 1) > 9 [MONEY_OVERFLOW] ;-- if sum of two most significant digits overflows + if (get-digit amount1 1) + (get-digit amount2 1) > 9 [MONEY_OVERFLOW] ;-- if sum of two most significant digits overflows index: SIZE_DIGITS carry: 0 loop index [ - left: get-digit this-amount index - right: get-digit that-amount index + digit1: get-digit amount1 index + digit2: get-digit amount2 index - sum: left + right + carry + sum: digit1 + digit2 + carry carry: sum / 10 unless zero? carry [sum: sum + 6 and 0Fh] - set-digit this-amount index sum + set-digit amount1 index sum index: index - 1 ] if as logic! carry [MONEY_OVERFLOW] - augend + value1 ] subtract-money: func [ ;-- long subtraction - minuend [red-money!] - subtrahend [red-money!] - return: [red-money!] + value1 [red-money!] + value2 [red-money!] + return: [red-money!] /local - this-amount that-amount [byte-ptr!] - this-sign that-sign sign [integer!] - index borrow left right [integer!] - difference [integer!] - lesser? flag [logic!] + amount1 amount2 [byte-ptr!] + sign1 sign2 sign [integer!] + index borrow [integer!] + digit1 digit2 [integer!] + difference [integer!] + lesser? flag [logic!] ][ - this-sign: sign? minuend - that-sign: sign? subtrahend + sign1: sign? value1 + sign2: sign? value2 DISPATCH_SIGNS [ SIGN_00 SIGN_0- - SIGN_0+ [return negate-money subtrahend] + SIGN_0+ [return negate-money value2] SIGN_-0 - SIGN_+0 [return minuend] - SIGN_-+ [return negate-money add-money absolute-money minuend absolute-money subtrahend] - SIGN_+- [return add-money minuend absolute-money subtrahend] + SIGN_+0 [return value1] + SIGN_-+ [return negate-money add-money absolute-money value1 absolute-money value2] + SIGN_+- [return add-money value1 absolute-money value2] default [ - lesser?: negative? compare-money minuend subtrahend + lesser?: negative? compare-money value1 value2 sign: as integer! lesser? - either positive? this-sign [flag: lesser?][ - minuend: absolute-money minuend - subtrahend: absolute-money subtrahend + either positive? sign1 [flag: lesser?][ + value1: absolute-money value1 + value2: absolute-money value2 flag: not lesser? ] - if flag [SWAP_ARGUMENTS(minuend subtrahend)] + if flag [SWAP_ARGUMENTS] ] ] - this-amount: get-amount minuend - that-amount: get-amount subtrahend + amount1: get-amount value1 + amount2: get-amount value2 index: SIZE_DIGITS borrow: 0 loop index [ - left: get-digit this-amount index - right: get-digit that-amount index + digit1: get-digit amount1 index + digit2: get-digit amount2 index - difference: left - right - borrow + difference: digit1 - digit2 - borrow borrow: as integer! negative? difference if as logic! borrow [difference: difference + 10] - set-digit this-amount index difference + set-digit amount1 index difference index: index - 1 ] - set-sign minuend sign + set-sign value1 sign ] multiply-money: func [ ;-- long multiplication - multiplicand [red-money!] - multiplier [red-money!] - return: [red-money!] + value1 [red-money!] + value2 [red-money!] + return: [red-money!] /local - this-amount that-amount product [byte-ptr!] - this-sign that-sign sign [integer!] - this-count that-count [integer!] - delta index1 index2 index3 [integer!] - carry left right other result [integer!] + amount1 amount2 product [byte-ptr!] + sign1 sign2 [integer!] + count1 count2 [integer!] + index1 index2 index3 [integer!] + digit1 digit2 digit3 [integer!] + sign delta carry result [integer!] ][ - this-sign: sign? multiplicand - that-sign: sign? multiplier + sign1: sign? value1 + sign2: sign? value2 DISPATCH_SIGNS [ SIGN_00 SIGN_0- - SIGN_0+ [return multiplicand] + SIGN_0+ [return value1] SIGN_+0 - SIGN_-0 [return multiplier] - default [sign: as integer! this-sign <> that-sign] + SIGN_-0 [return value2] + default [sign: as integer! sign1 <> sign2] ] - this-amount: get-amount multiplicand - that-amount: get-amount multiplier + amount1: get-amount value1 + amount2: get-amount value2 - this-count: count-digits this-amount - that-count: count-digits that-amount + count1: count-digits amount1 + count2: count-digits amount2 - if (this-count + that-count) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload + if (count1 + count2) > (SIZE_UNNORM + 1) [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload product: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES delta: SIZE_DIGITS - SIZE_BUFFER << 1 index1: SIZE_DIGITS - loop that-count [ + loop count2 [ carry: 0 index2: SIZE_DIGITS - loop this-count [ + loop count1 [ index3: index1 + index2 - delta - left: get-digit this-amount index2 - right: get-digit that-amount index1 - other: get-digit product index3 + digit1: get-digit amount1 index2 + digit2: get-digit amount2 index1 + digit3: get-digit product index3 - result: left * right + other + carry + result: digit1 * digit2 + digit3 + carry carry: result / 10 result: result // 10 @@ -1240,72 +1235,73 @@ money: context [ if zero-amount? product [MONEY_OVERFLOW] ;-- got zero product from non-zero factors - set-amount multiplicand product - set-sign multiplicand sign + set-amount value1 product + set-sign value1 sign ] divide-money: func [ ;-- shift-and-subtract algorithm - dividend [red-money!] - divisor [red-money!] + value1 [red-money!] + value2 [red-money!] remainder? [logic!] ;-- yes: calculate remainder instead only? [logic!] ;-- yes: don't approximate fractional part return: [red-money!] /local - shift increment subtract [subroutine!] - greater? greatest? [subroutine!] - this-amount that-amount [byte-ptr!] - this-start that-start [byte-ptr!] - quotient buffer hold [byte-ptr!] - this-sign that-sign sign [integer!] - this-count that-count [integer!] - size overflow digits index [integer!] - this-high? that-high? [logic!] + shift increment subtract [subroutine!] + greater? greatest? [subroutine!] + amount1 amount2 [byte-ptr!] + start1 start2 [byte-ptr!] + quotient buffer hold [byte-ptr!] + sign1 sign2 sign [integer!] + count1 count2 [integer!] + size overflow [integer!] + digits index [integer!] + high1? high2? [logic!] ][ - this-sign: sign? dividend - that-sign: sign? divisor + sign1: sign? value1 + sign2: sign? value2 DISPATCH_SIGNS [ SIGN_00 SIGN_+0 SIGN_-0 [fire [TO_ERROR(math zero-divide)]] SIGN_0- - SIGN_0+ [return dividend] + SIGN_0+ [return value1] default [ - sign: as integer! either remainder? [negative? this-sign][this-sign <> that-sign] + sign: as integer! either remainder? [negative? sign1][sign1 <> sign2] ] ] - this-amount: get-amount dividend - that-amount: get-amount divisor + amount1: get-amount value1 + amount2: get-amount value2 - this-count: count-digits this-amount - that-count: count-digits that-amount + count1: count-digits amount1 + count2: count-digits amount2 - if this-count + (SIZE_SCALE + 1 - that-count) > SIZE_DIGITS [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload + if count1 + (SIZE_SCALE + 1 - count2) > SIZE_DIGITS [MONEY_OVERFLOW] ;-- if after normalization it won't fit into payload size: SIZE_DIGITS overflow: SIZE_SBYTES << 1 - SIZE_DIGITS unless any [remainder? only?][ size: SIZE_SBYTES << 1 - hold: this-amount + hold: amount1 - this-amount: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES - this-count: this-count + SIZE_SCALE + amount1: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES + count1: count1 + SIZE_SCALE - copy-memory this-amount + SIZE_SBYTES - SIZE_BYTES hold SIZE_BYTES - shift-left this-amount SIZE_SBYTES SIZE_SCALE + copy-memory amount1 + SIZE_SBYTES - SIZE_BYTES hold SIZE_BYTES + shift-left amount1 SIZE_SBYTES SIZE_SCALE ] - this-high?: as logic! this-count and 1 - that-high?: as logic! that-count and 1 + high1?: as logic! count1 and 1 + high2?: as logic! count2 and 1 - this-start: this-amount + (size - this-count >> 1) - that-start: that-amount + (SIZE_DIGITS - that-count >> 1) + start1: amount1 + (size - count1 >> 1) + start2: amount2 + (SIZE_DIGITS - count2 >> 1) - digits: either this-count < that-count [this-count][that-count] + digits: either count1 < count2 [count1][count2] - index: size - (integer/abs this-count - that-count) - SIZE_SCALE + index: size - (integer/abs count1 - count2) - SIZE_SCALE quotient: set-memory as byte-ptr! system/stack/allocate SIZE_SSLOTS null-byte SIZE_SBYTES buffer: quotient @@ -1317,21 +1313,21 @@ money: context [ ] subtract: [ subtract-slice - this-start this-high? digits - that-start that-high? that-count + start1 high1? digits + start2 high2? count2 ] increment: [ set-digit quotient index (get-digit quotient index) + 1 ] greater?: [ compare-slices - that-start that-high? that-count - this-start this-high? digits + start2 high2? count2 + start1 high1? digits ] greatest?: [ compare-slices - that-start that-high? that-count - this-start this-high? this-count + start2 high2? count2 + start1 high1? count1 ] ;@@ TBD: bug with subroutines until [either greater? > 0 [either greatest? > 0 [yes][shift no]][subtract increment no]] @@ -1340,31 +1336,31 @@ money: context [ unless only? [ shift-right quotient SIZE_SBYTES SIZE_SCALE quotient: quotient + SIZE_SBYTES - SIZE_BYTES - this-amount: hold + amount1: hold ] - if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero dividend + if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero value1 unless zero? get-digit buffer overflow [MONEY_OVERFLOW] ;-- overflowed into most-significant digit - set-amount dividend quotient + set-amount value1 quotient ] - set-sign dividend sign + set-sign value1 sign ] do-math-op: func [ - left [red-money!] - right [red-money!] + value1 [red-money!] + value2 [red-money!] op [integer!] return: [red-money!] ][ switch op [ - OP_ADD [add-money left right] - OP_SUB [subtract-money left right] - OP_MUL [multiply-money left right] - OP_DIV [divide-money left right no no] - OP_REM [divide-money left right yes no] + OP_ADD [add-money value1 value2] + OP_SUB [subtract-money value1 value2] + OP_MUL [multiply-money value1 value2] + OP_DIV [divide-money value1 value2 no no] + OP_REM [divide-money value1 value2 yes no] default [ - fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(left)] - left ;-- pass compiler's type checking + fire [TO_ERROR (script invalid-type) datatype/push TYPE_OF(value1)] + value1 ;-- pass compiler's type checking ] ] ] @@ -1373,63 +1369,62 @@ money: context [ op [integer!] return: [red-value!] /local - left right [red-money!] - result [red-value!] - int [red-integer!] - flt [red-float!] - currency [integer!] - left-type [integer!] - right-type [integer!] + value1 value2 [red-money!] + result [red-value!] + int [red-integer!] + flt [red-float!] + currency [integer!] + type1 type2 [integer!] ][ - left: as red-money! stack/arguments - right: left + 1 + value1: as red-money! stack/arguments + value2: value1 + 1 - left-type: TYPE_OF(left) - right-type: TYPE_OF(right) + type1: TYPE_OF(value1) + type2: TYPE_OF(value2) if any [ - all [op = OP_MUL left-type = TYPE_MONEY right-type = TYPE_MONEY] - all [any [op = OP_DIV op = OP_REM] left-type <> TYPE_MONEY right-type = TYPE_MONEY] + all [op = OP_MUL type1 = TYPE_MONEY type2 = TYPE_MONEY] + all [any [op = OP_DIV op = OP_REM] type1 <> TYPE_MONEY type2 = TYPE_MONEY] ][ - fire [TO_ERROR(script invalid-type) datatype/push left-type] + fire [TO_ERROR(script invalid-type) datatype/push type1] ] - switch left-type [ + switch type1 [ TYPE_MONEY [0] TYPE_INTEGER [ - int: as red-integer! left - left: from-integer int/value + int: as red-integer! value1 + value1: from-integer int/value ] TYPE_FLOAT [ - flt: as red-float! left - left: from-float flt/value + flt: as red-float! value1 + value1: from-float flt/value ] default [ - fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(left)] + fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(value1)] ] ] - switch right-type [ + switch type2 [ TYPE_MONEY [0] TYPE_INTEGER [ - int: as red-integer! right - right: from-integer int/value + int: as red-integer! value2 + value2: from-integer int/value ] TYPE_FLOAT [ - flt: as red-float! right - right: from-float flt/value + flt: as red-float! value2 + value2: from-float flt/value ] default [ - fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] + fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(value2)] ] ] - unless same-currencies? left right [fire [TO_ERROR(script wrong-denom) left right]] - currency: get-currency right ;-- preserve specific currency - if zero? currency [currency: get-currency left] + unless same-currencies? value1 value2 [fire [TO_ERROR(script wrong-denom) value1 value2]] + currency: get-currency value2 ;-- preserve specific currency + if zero? currency [currency: get-currency value1] - result: as red-value! do-math-op left right op - either all [op = OP_DIV left-type = TYPE_MONEY right-type = TYPE_MONEY][ + result: as red-value! do-math-op value1 value2 op + either all [op = OP_DIV type1 = TYPE_MONEY type2 = TYPE_MONEY][ result: as red-value! float/box to-float as red-money! result ][ set-currency as red-money! result currency From 6ac794137155900db88008f000cb0305f85f73a4 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 14:57:08 +0100 Subject: [PATCH 1233/3432] FEAT: minor optimization. --- runtime/datatypes/money.reds | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 59f3586183..3137df23f6 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -126,7 +126,7 @@ money: context [ /local place [byte-ptr!] ][ - place: (get-amount money) - 1 + place: as byte-ptr! :money/amount1 as integer! place/value ] @@ -138,7 +138,7 @@ money: context [ place [byte-ptr!] ][ assert all [index >= 0 index <= FFh] - place: (get-amount money) - 1 + place: as byte-ptr! :money/amount1 place/value: as byte! index money ] @@ -219,7 +219,7 @@ money: context [ money [red-money!] return: [byte-ptr!] ][ - (as byte-ptr! money) + (size? money) - SIZE_BYTES + (as byte-ptr! :money/amount1) + 1 ] set-amount: func [ From e3bb671b1e53f4bcc97b8b4c6186d3102d524985 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 15:44:17 +0100 Subject: [PATCH 1234/3432] FEAT: minor optimization. --- runtime/datatypes/money.reds | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 3137df23f6..4f55878be1 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -235,14 +235,14 @@ money: context [ amount [byte-ptr!] return: [logic!] /local - rest [int-ptr!] + payload [int-ptr!] ][ - loop 3 [ ;-- SIZE_BYTES - (2 * size? integer!) - unless null-byte = amount/value [return no] - amount: amount + 1 + payload: as int-ptr! amount - 1 + all [ + (payload/1 and not FFh) = 0 ;-- little-endian order + payload/2 = 0 + payload/3 = 0 ] - rest: as int-ptr! amount - all [rest/1 = 0 rest/2 = 0] ] compare-amounts: func [ From 587adca90a593590fe1261e057e781d99426daab Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 17:24:37 +0100 Subject: [PATCH 1235/3432] FEAT: minor code refactoring. --- runtime/datatypes/money.reds | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4f55878be1..e6331a1620 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -101,6 +101,7 @@ money: context [ sign2 [integer!] return: [integer!] ][ + assert all [1 >= integer/abs sign1 1 >= integer/abs sign2] sign1 + 1 << 4 or (sign2 + 1) ] @@ -115,6 +116,7 @@ money: context [ index: get-currency money if zero? index [return none/push] ;-- generic currency + ;@@ TBD: check extra list also block/rs-abs-at as red-block! #get system/locale/currencies/base index @@ -198,7 +200,7 @@ money: context [ currency2: get-currency value2 any [ - zero? currency1 ;-- 0: generic currency + zero? currency1 ;-- 0: generic currency zero? currency2 currency1 = currency2 ] @@ -239,9 +241,9 @@ money: context [ ][ payload: as int-ptr! amount - 1 all [ - (payload/1 and not FFh) = 0 ;-- little-endian order - payload/2 = 0 - payload/3 = 0 + zero? (payload/1 and not FFh) ;-- little-endian order + zero? payload/2 + zero? payload/3 ] ] @@ -1210,9 +1212,9 @@ money: context [ loop count1 [ index3: index1 + index2 - delta - digit1: get-digit amount1 index2 + digit1: get-digit amount1 index2 digit2: get-digit amount2 index1 - digit3: get-digit product index3 + digit3: get-digit product index3 result: digit1 * digit2 + digit3 + carry carry: result / 10 @@ -1408,7 +1410,7 @@ money: context [ TYPE_MONEY [0] TYPE_INTEGER [ int: as red-integer! value2 - value2: from-integer int/value + value2: from-integer int/value ] TYPE_FLOAT [ flt: as red-float! value2 From bda42f4b303ce455b60fa9e9f71f635bceaf6afd Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Mar 2020 19:02:07 +0100 Subject: [PATCH 1236/3432] FEAT: extends the number of action's events for owned series. --- runtime/datatypes/block.reds | 32 +++++++++++++++++++++++--------- runtime/datatypes/common.reds | 18 ++++++++++++++++++ runtime/datatypes/series.reds | 19 ++++++++++++++----- runtime/datatypes/string.reds | 27 +++++++++++++++++++++------ runtime/ownership.reds | 16 +++++++++------- 5 files changed, 85 insertions(+), 27 deletions(-) diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 8e196fbd0b..8b9a8ffc6e 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1078,7 +1078,7 @@ block: context [ s [series!] hash? [logic!] hash [red-hash!] - put? [logic!] + put? chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "block/put"]] @@ -1087,6 +1087,7 @@ block: context [ blk: as red-block! find blk field null no case? no no null null no no no no either TYPE_OF(blk) = TYPE_NONE [ + chk?: ownership/check as red-value! blk words/_put value rs-length? blk 1 copy-cell field ALLOC_TAIL(blk) value: copy-cell value ALLOC_TAIL(blk) if hash? [ @@ -1096,6 +1097,7 @@ block: context [ ][ s: GET_BUFFER(blk) slot: s/offset + blk/head + 1 + chk?: ownership/check as red-value! blk words/_put value blk/head + 1 1 either slot >= s/tail [ put?: yes slot: alloc-tail s @@ -1107,7 +1109,7 @@ block: context [ copy-cell value slot if hash? [_hashtable/put hash/table slot] ] - ownership/check as red-value! blk words/_put slot blk/head + 1 1 + ownership/check as red-value! blk words/_put-ed value blk/head + 1 1 ] value ] @@ -1249,6 +1251,7 @@ block: context [ flags [integer!] offset [integer!] saved [logic!] + chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "block/sort"]] @@ -1328,6 +1331,7 @@ block: context [ ] ] ] + chk?: ownership/check as red-value! blk words/_sort null blk/head 0 saved: collector/active? collector/active?: no ;-- turn off GC either stable? [ @@ -1336,7 +1340,7 @@ block: context [ _sort/qsort as byte-ptr! head len step * (size? red-value!) op flags cmp ] collector/active?: saved - ownership/check as red-value! blk words/_sort null blk/head 0 + if chk? [ownership/check as red-value! blk words/_sorted null blk/head 0] blk ] @@ -1369,6 +1373,7 @@ block: context [ values? [logic!] tail? [logic!] hash? [logic!] + chk? [logic!] action [red-word!] ][ #if debug? = yes [if verbose > 0 [print-line "block/insert"]] @@ -1437,7 +1442,8 @@ block: context [ action: words/_insert h ] - + chk?: ownership/check as red-value! blk action value index part + unless tail? [ ;TBD: process head? case separately size: as-integer s/tail + slots - s/offset if size > s/size [s: expand-series s size * 2] @@ -1490,8 +1496,10 @@ block: context [ cell: cell + 1 ] ] - ownership/check as red-value! blk action value index part - + if chk? [ + action: either append? [words/_appended][words/_inserted] + ownership/check as red-value! blk action value index part + ] either append? [blk/head: 0][ blk/head: h + slots s: GET_BUFFER(blk) @@ -1558,6 +1566,7 @@ block: context [ type2 [integer!] hash [red-hash!] table [node!] + chk? chk2? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "block/swap"]] @@ -1576,6 +1585,9 @@ block: context [ h2: as int-ptr! s/offset + blk2/head if s/tail = as red-value! h2 [return blk1] ;-- early exit if nothing to swap + chk?: ownership/check as red-value! blk1 words/_swap null blk1/head 1 + chk2?: ownership/check as red-value! blk2 words/_swap null blk2/head 1 + i: 0 until [ tmp: h1/value @@ -1599,8 +1611,8 @@ block: context [ _hashtable/delete hash/table as red-value! h2 _hashtable/put hash/table as red-value! h2 ] - ownership/check as red-value! blk1 words/_swap null blk1/head 1 - ownership/check as red-value! blk2 words/_swap null blk2/head 1 + if chk? [ownership/check as red-value! blk1 words/_swaped null blk1/head 1] + if chk2? [ownership/check as red-value! blk2 words/_swaped null blk2/head 1] blk1 ] @@ -1617,9 +1629,11 @@ block: context [ s [series!] value [red-value!] cur [red-value!] + chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "block/trim"]] + chk?: ownership/check as red-value! blk words/_trim null blk/head 0 s: GET_BUFFER(blk) value: s/offset + blk/head cur: value @@ -1632,7 +1646,7 @@ block: context [ value: value + 1 ] s/tail: cur - ownership/check as red-value! blk words/_trim null blk/head 0 + if chk? [ownership/check as red-value! blk words/_trimmed null blk/head 0] as red-series! blk ] diff --git a/runtime/datatypes/common.reds b/runtime/datatypes/common.reds index 012a4d08f3..aa6e70cd7f 100644 --- a/runtime/datatypes/common.reds +++ b/runtime/datatypes/common.reds @@ -649,19 +649,28 @@ words: context [ _cleared: as red-word! 0 _set-path: as red-word! 0 _append: as red-word! 0 + _appended: as red-word! 0 _poke: as red-word! 0 + _poked: as red-word! 0 _put: as red-word! 0 + _put-ed: as red-word! 0 ;_remove: as red-word! 0 _removed: as red-word! 0 _random: as red-word! 0 + _randomized: as red-word! 0 _reverse: as red-word! 0 + _reversed: as red-word! 0 _sort: as red-word! 0 + _sorted: as red-word! 0 _swap: as red-word! 0 + _swaped: as red-word! 0 _take: as red-word! 0 _taken: as red-word! 0 _move: as red-word! 0 _moved: as red-word! 0 _trim: as red-word! 0 + _trimmed: as red-word! 0 + _inserted: as red-word! 0 ;-- modifying natives _uppercase: as red-word! 0 @@ -880,19 +889,28 @@ words: context [ _cleared: word/load "cleared" _set-path: word/load "set-path" _append: word/load "append" + _appended: word/load "appended" _move: word/load "move" _moved: word/load "moved" _poke: word/load "poke" + _poked: word/load "poked" _put: word/load "put" + _put-ed: word/load "put-ed" ;_remove: word/load "remove" _removed: word/load "removed" _random: word/load "random" + _randomized: word/load "randomized" _reverse: word/load "reverse" + _reversed: word/load "reversed" _sort: word/load "sort" + _sorted: word/load "sorted" _swap: word/load "swap" + _swaped: word/load "swaped" _take: word/load "take" _taken: word/load "taken" _trim: word/load "trim" + _trimmed: word/load "trimmed" + _inserted: word/load "inserted" ;-- modifying natives _uppercase: word/load "uppercase" diff --git a/runtime/datatypes/series.reds b/runtime/datatypes/series.reds index ffc4c5aa57..731b9d18ef 100644 --- a/runtime/datatypes/series.reds +++ b/runtime/datatypes/series.reds @@ -106,6 +106,7 @@ _series: context [ temp [byte-ptr!] idx [byte-ptr!] head [byte-ptr!] + chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "series/random"]] @@ -116,6 +117,7 @@ _series: context [ unit: GET_UNIT(s) head: (as byte-ptr! s/offset) + (ser/head << (log-b unit)) size: (as-integer s/tail - s/offset) >> (log-b unit) - ser/head + chk?: ownership/check as red-value! ser words/_random null ser/head size either only? [ either positive? size [ @@ -157,7 +159,7 @@ _series: context [ head: head + unit size: size - 1 ] - ownership/check as red-value! ser words/_random null ser/head len + if chk? [ownership/check as red-value! ser words/_randomized null ser/head len] ] ] as red-value! ser @@ -744,6 +746,7 @@ _series: context [ pos [byte-ptr!] unit [integer!] char [red-char!] + chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "series/poke"]] @@ -763,6 +766,7 @@ _series: context [ integer/push index ] ][ + chk?: ownership/check as red-value! ser words/_poke data offset 1 pos: (as byte-ptr! s/offset) + (offset << (log-b unit)) switch TYPE_OF(ser) [ TYPE_BLOCK ;@@ any-block? @@ -789,7 +793,7 @@ _series: context [ string/poke-char s pos char/value ] ] - ownership/check as red-value! ser words/_poke data offset 1 + if chk? [ownership/check as red-value! ser words/_poked data offset 1] stack/set-last data ] data @@ -887,6 +891,7 @@ _series: context [ hash? [logic!] hash [red-hash!] table [node!] + chk? [logic!] ][ s: GET_BUFFER(ser) unit: GET_UNIT(s) @@ -922,6 +927,7 @@ _series: context [ hash: as red-hash! ser table: hash/table ] + chk?: ownership/check as red-value! ser words/_reverse null ser/head items if all [positive? part head + part < tail] [tail: head + part] tail: tail - unit ;-- point to last value temp: as byte-ptr! :val @@ -938,7 +944,7 @@ _series: context [ head: head + unit tail: tail - unit ] - ownership/check as red-value! ser words/_reverse null ser/head items + if chk? [ownership/check as red-value! ser words/_reversed null ser/head items] ser ] @@ -1066,7 +1072,10 @@ _series: context [ unit2 [integer!] head1 [byte-ptr!] head2 [byte-ptr!] + chk? chk2? [logic!] ][ + chk?: ownership/check as red-value! ser1 words/_swap null ser1/head 1 + chk2?: ownership/check as red-value! ser2 words/_swap null ser2/head 1 s1: GET_BUFFER(ser1) unit1: GET_UNIT(s1) head1: (as byte-ptr! s1/offset) + (ser1/head << (log-b unit1)) @@ -1081,8 +1090,8 @@ _series: context [ char2: string/get-char head2 unit2 string/poke-char s1 head1 char2 string/poke-char s2 head2 char1 - ;ownership/check as red-value! ser1 words/_remove null offset part - ;ownership/check as red-value! ser2 words/_remove null offset part + if chk? [ownership/check as red-value! ser1 words/_swaped null ser1/head 1] + if chk2? [ownership/check as red-value! ser2 words/_swaped null ser2/head 1] ser1 ] diff --git a/runtime/datatypes/string.reds b/runtime/datatypes/string.reds index 92bdcbdaa4..ec11d79931 100644 --- a/runtime/datatypes/string.reds +++ b/runtime/datatypes/string.reds @@ -2073,6 +2073,7 @@ string: context [ flags [integer!] mult [integer!] offset [integer!] + chk? [logic!] ][ step: 1 s: GET_BUFFER(str) @@ -2169,8 +2170,9 @@ string: context [ ] ] ] + chk?: ownership/check as red-value! str words/_sort null str/head 0 _sort/qsort buffer len unit * step op flags cmp - ownership/check as red-value! str words/_sort null str/head 0 + if chk? [ownership/check as red-value! str words/_sorted null str/head 0] str ] @@ -2202,6 +2204,7 @@ string: context [ type [integer!] index [integer!] tail? [logic!] + chk? [logic!] action [red-word!] ][ #if debug? = yes [if verbose > 0 [print-line "string/insert"]] @@ -2246,6 +2249,7 @@ string: context [ action: words/_insert str/head ] + chk?: ownership/check as red-value! str action value index part while [not zero? cnt][ ;-- /dup support type: TYPE_OF(value) @@ -2309,8 +2313,10 @@ string: context [ cnt: cnt - 1 ] if part < 0 [part: 1] ;-- ownership/check needs part >= 0 - ownership/check as red-value! str action value index part - + if chk? [ + action: either append? [words/_appended][words/_inserted] + ownership/check as red-value! str action value index part + ] either append? [str/head: 0][ added: added * dup-n str/head: str/head + added @@ -2338,6 +2344,7 @@ string: context [ unit2 [integer!] head1 [byte-ptr!] head2 [byte-ptr!] + chk? chk2? [logic!] ][ s1: GET_BUFFER(str1) unit1: GET_UNIT(s1) @@ -2349,12 +2356,14 @@ string: context [ head2: (as byte-ptr! s2/offset) + (str2/head << (log-b unit2)) if head2 = as byte-ptr! s2/tail [return str1] ;-- early exit if nothing to swap + chk?: ownership/check as red-value! str1 words/_swap null str1/head 1 + chk2?: ownership/check as red-value! str2 words/_swap null str2/head 1 char1: get-char head1 unit1 char2: get-char head2 unit2 poke-char s1 head1 char2 poke-char s2 head2 char1 - ownership/check as red-value! str1 words/_swap null str1/head 1 - ownership/check as red-value! str2 words/_swap null str2/head 1 + if chk? [ownership/check as red-value! str1 words/_swaped null str1/head 1] + if chk2? [ownership/check as red-value! str2 words/_swaped null str2/head 1] str1 ] @@ -2573,6 +2582,7 @@ string: context [ s [series!] unit [integer!] type [integer!] + chk? [logic!] ][ str: as red-string! _series/take as red-series! str part-arg deep? last? s: GET_BUFFER(str) @@ -2581,6 +2591,7 @@ string: context [ not OPTION?(part-arg) 1 = _series/get-length as red-series! str yes ][ + chk?: ownership/check as red-value! str words/_take null str/head 0 unit: GET_UNIT(s) type: TYPE_OF(str) either type = TYPE_VECTOR [ @@ -2592,6 +2603,7 @@ string: context [ char/header: type char/value: get-char as byte-ptr! s/offset unit ] + if chk? [ownership/check as red-value! str words/_taken null str/head 0] ] as red-value! str ] @@ -2605,16 +2617,19 @@ string: context [ all? [logic!] with-arg [red-value!] return: [red-series!] + /local + chk? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "string/trim"]] + chk?: ownership/check as red-value! str words/_trim null str/head 0 case [ any [all? OPTION?(with-arg)] [trim-with str with-arg] auto? [--NOT_IMPLEMENTED--] lines? [trim-lines str] true [trim-head-tail str head? tail?] ] - ownership/check as red-value! str words/_trim null str/head 0 + if chk? [ownership/check as red-value! str words/_trimmed null str/head 0] as red-series! str ] diff --git a/runtime/ownership.reds b/runtime/ownership.reds index 4cb5799150..fd1564ea40 100644 --- a/runtime/ownership.reds +++ b/runtime/ownership.reds @@ -198,11 +198,12 @@ ownership: context [ ] check: func [ - value [red-value!] ;-- series or object where a change occurs - action [red-word!] ;-- series: type of change, object: field - new [red-value!] ;-- newly inserted value or null - index [integer!] ;-- start position of the change - part [integer!] ;-- nb of values affected + value [red-value!] ;-- series or object where a change occurs + action [red-word!] ;-- series: type of change, object: field + new [red-value!] ;-- newly inserted value or null + index [integer!] ;-- start position of the change + part [integer!] ;-- nb of values affected + return: [logic!] ;-- TRUE: value is owned /local node [node!] slot [red-value!] @@ -227,10 +228,11 @@ ownership: context [ ] slot: _hashtable/get-value table as-integer node - unless null? slot [ + either null? slot [false][ owner: as red-object! slot + 1 word: as red-word! slot + 2 - object/fire-on-deep owner word value action new index part + object/fire-on-deep owner word value action new index part + true ] ] From 1ac844a4db252ef7f4880794ddcf17a0215389ed Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Mar 2020 19:02:45 +0100 Subject: [PATCH 1237/3432] FIX: invalid argument type generated for `money/push` call. --- compiler.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler.r b/compiler.r index 3bc689b497..47b500aa6e 100644 --- a/compiler.r +++ b/compiler.r @@ -1757,7 +1757,7 @@ red: context [ money? [ emit 'money/push value: to string! next value - emit value/4 = #"-" + emit pick [true false] value/4 = #"-" emit any [all [value/1 = #"." 'null] copy/part value 3] emit to-nibbles copy skip value 4 ] From d7d903ddc525dc85f730bf580c94d42a656b0e34 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 20:02:34 +0100 Subject: [PATCH 1238/3432] FEAT: preliminary work on MONEY! rounding. --- runtime/datatypes/money.reds | 76 ++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index e6331a1620..c4896d47fc 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -35,7 +35,9 @@ money: context [ SIGN_MASK: 4000h ;-- used to get/set sign bit in the header SIGN_OFFSET: 14 - MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 + KEEP_FRACTIONAL: FFFF0F00h ;-- used to extract fractional part (little-endian order) + MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 + INT32_MAX_DIGITS: 10 INT32_MIN_AMOUNT: #{00000002147483648FFFFF} ;-- 0xF > 0x9, used to subvert comparison INT32_MAX_AMOUNT: #{00000002147483647FFFFF} @@ -1434,7 +1436,65 @@ money: context [ SET_RETURN(result) ;-- swapped arguments ] - + + ;-- Rounding -- + + fraction?: func [ + money [red-money!] + return: [logic!] + ][ + as logic! money/amount3 and KEEP_FRACTIONAL + ] + + truncate: func [ + money [red-money!] + return: [red-money!] + ][ + money/amount3: money/amount3 and not KEEP_FRACTIONAL + money + ] + + floor: func [ + money [red-money!] + return: [red-money!] + /local + delta [red-money!] + ][ + switch sign? money [ + +1 [truncate money] + 00 [money] + -1 [ + delta: from-integer as integer! fraction? money + subtract-money truncate money delta + ] + ] + ] + + ceil: func [ + money [red-money!] + return: [red-money!] + /local + delta [red-money!] + ][ + switch sign? money [ + -1 [truncate money] + 00 [money] + +1 [ + delta: from-integer as integer! fraction? money + add-money truncate money delta + ] + ] + ] + + away: func [ + money [red-money!] + return: [red-money!] + ][ + truncate set-sign + add-money absolute-money money from-float 0.5 + get-sign money + ] + ;-- Actions -- make: func [ @@ -1609,8 +1669,16 @@ money: context [ return: [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/round"]] - --NOT_IMPLEMENTED-- - value + + case [ + _even? [--NOT_IMPLEMENTED-- value] + down? [truncate value] + half-down? [--NOT_IMPLEMENTED-- value] + floor? [floor value] + ceil? [ceil value] + half-ceil? [--NOT_IMPLEMENTED-- value] + true [away value] + ] ] even?: func [ From aa23d486861f5b81fd1bba9373dc39c31b578e73 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 20:03:08 +0100 Subject: [PATCH 1239/3432] TESTS: add rounding tests. --- tests/source/units/money-test.red | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 39d62d713b..8b3c6047c4 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -369,6 +369,67 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "remainder-15" --assert $0.56789 == remainder $0.56789 123.456 ===end-group=== +===start-group=== "rounding" + max-money: +$99'999'999'999'999'999.9999 + min-money: -$99'999'999'999'999'999.9999 + + --test-- "round" ;-- away from zero + --assert +$0.0 == round +$0.0 + --assert -$4.0 == round -$3.5 + --assert -$3.0 == round -$2.9 + --assert -$1.0 == round -$1.1 + --assert +$1.0 == round +$1.1 + --assert +$3.0 == round +$2.9 + --assert +$4.0 == round +$3.5 + --assert error? try [round max-money] + --assert error? try [round min-money] + + --test-- "round/to" + --assert true + + --test-- "round/even" + --assert true + + --test-- "round/down" ;-- truncation + --assert +$0.0 == round/down +$0.0 + --assert -$3.0 == round/down -$3.5 + --assert -$2.0 == round/down -$2.9 + --assert -$1.0 == round/down -$1.1 + --assert +$1.0 == round/down +$1.1 + --assert +$2.0 == round/down +$2.9 + --assert +$3.0 == round/down +$3.5 + --assert +$99'999'999'999'999'999 == round/down max-money + --assert -$99'999'999'999'999'999 == round/down min-money + + --test-- "round/half-down" + --assert true + + --test-- "round/floor" ;-- towards negative infinity + --assert +$0.0 == round/floor +$0.0 + --assert -$4.0 == round/floor -$3.5 + --assert -$3.0 == round/floor -$2.9 + --assert -$2.0 == round/floor -$1.1 + --assert +$1.0 == round/floor +$1.1 + --assert +$2.0 == round/floor +$2.9 + --assert +$3.0 == round/floor +$3.5 + --assert +$99'999'999'999'999'999 == round/floor max-money + --assert error? try [round/floor min-money] + + --test-- "round/ceil" ;-- towards positive infinity + --assert +$0.0 == round/ceiling +$0.0 + --assert -$3.0 == round/ceiling -$3.5 + --assert -$2.0 == round/ceiling -$2.9 + --assert -$1.0 == round/ceiling -$1.1 + --assert +$2.0 == round/ceiling +$1.1 + --assert +$3.0 == round/ceiling +$2.9 + --assert +$4.0 == round/ceiling +$3.5 + --assert error? try [round/ceiling max-money] + --assert -$99'999'999'999'999'999 == round/ceiling min-money + + --test-- "round/half-ceil" + --assert true +===end-group=== + ===start-group=== "sort" --test-- "sort-1" block: [9 2.0 $4 5.0 $8 7 $3 6.0 2.0 $1 5] From 0d6fdcee1a99c93d468da3735d991524d4130f36 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Mar 2020 20:31:00 +0100 Subject: [PATCH 1240/3432] FEAT: adds modifying protection to system/locale/currencies. Only APPEND action allowed and with a unique valid 3 characters currency code word. --- environment/functions.red | 8 ++++---- environment/system.red | 25 +++++++++++++++++++++++-- runtime/datatypes/block.reds | 4 +++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index db0af83f21..6160552b97 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -528,13 +528,13 @@ save: function [ cause-error: func [ "Causes an immediate error throw, with the provided information" err-type [word!] - err-id [word!] - args [block! string!] + err-id [word!] + args [block! string!] ][ - args: reduce either block? args [args] [[args]] ; Blockify string args + args: reduce either block? args [args] [[args]] ;-- Blockify string args do make error! [ type: err-type - id: err-id + id: err-id arg1: first args arg2: second args arg3: third args diff --git a/environment/system.red b/environment/system.red index 9cebf20f69..6d99042ba8 100644 --- a/environment/system.red +++ b/environment/system.red @@ -144,7 +144,7 @@ system: context [ no-return: "block did not return a value" throw-usage: "invalid use of a thrown error value" locked-word: ["protected word - cannot modify:" :arg1] - ;protected: "protected value or series - cannot modify" + protected: "protected value or series - cannot modify" ;self-protected: "cannot set/unset self - it is protected" bad-bad: [:arg1 "error:" :arg2] bad-make-arg: ["cannot MAKE" :arg1 "from:" :arg2] @@ -325,7 +325,28 @@ system: context [ USD UYU UZS VES VND VUV WST CFA XAF XCD XOF CFP XPF YER ZAR ZMW ] ;-- User-provided currencies - extra: none + extra: [] + + on-change*: func [word old new][ + set-quiet word old + cause-error 'script 'protected [] + ] + on-deep-change*: func [owner word target action new index part][ + if any [ + word <> 'extra + not find [append appended] action + not word? :new + find base new + 3 <> length? form new + all [ + action = 'append + any [ + find extra new + 255 < ((length? base) + length? extra) ;-- limit index to 8-bit + ] + ] + ][cause-error 'script 'protected []] + ] ] ] diff --git a/runtime/datatypes/block.reds b/runtime/datatypes/block.reds index 8b9a8ffc6e..9b04758ba6 100644 --- a/runtime/datatypes/block.reds +++ b/runtime/datatypes/block.reds @@ -1075,6 +1075,7 @@ block: context [ return: [red-value!] /local slot [red-value!] + saved [red-block!] s [series!] hash? [logic!] hash [red-hash!] @@ -1082,12 +1083,13 @@ block: context [ ][ #if debug? = yes [if verbose > 0 [print-line "block/put"]] + saved: blk hash?: TYPE_OF(blk) = TYPE_HASH hash: as red-hash! blk blk: as red-block! find blk field null no case? no no null null no no no no either TYPE_OF(blk) = TYPE_NONE [ - chk?: ownership/check as red-value! blk words/_put value rs-length? blk 1 + chk?: ownership/check as red-value! saved words/_put value rs-length? saved 1 copy-cell field ALLOC_TAIL(blk) value: copy-cell value ALLOC_TAIL(blk) if hash? [ From c9c01f16fe444f7478cf5236da461c946298bd00 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Mar 2020 20:39:45 +0100 Subject: [PATCH 1241/3432] TESTS: updates test "oodc2" after changes in ownership events triggering. --- tests/source/units/object-test.red | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/source/units/object-test.red b/tests/source/units/object-test.red index 87ef15b84b..25ccd923dc 100644 --- a/tests/source/units/object-test.red +++ b/tests/source/units/object-test.red @@ -2272,13 +2272,15 @@ Red [ on-deep-change*: func [ owner word target action new index part ][ - if equal? mold owner mold make object! [a: 0 b: [1 2 3 4 5 6]] [a: a + 1] - if equal? word 'b [a: a + 10] - if equal? target [1 2 3 4 5 6] [a: a + 100] - if equal? action 'append [a: a + 1000] - if equal? new 6 [a: a + 10000] - if equal? index 5 [a: a + 100000] - if equal? part 1 [a: a + 1000000] + if action = 'appended [ + if equal? mold owner mold make object! [a: 0 b: [1 2 3 4 5 6]] [a: a + 1] + if equal? word 'b [a: a + 10] + if equal? target [1 2 3 4 5 6] [a: a + 100] + if equal? action 'appended [a: a + 1000] + if equal? new 6 [a: a + 10000] + if equal? index 5 [a: a + 100000] + if equal? part 1 [a: a + 1000000] + ] ] a: 0 b: [1 2 3 4 5] From b10e673a08b53c4c59219852f56124bd2518bc92 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 27 Mar 2020 20:41:21 +0100 Subject: [PATCH 1242/3432] FIX: re-apply lexer fix. --- lexer.r | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index df90d7d0ee..6eebc28108 100644 --- a/lexer.r +++ b/lexer.r @@ -690,7 +690,10 @@ lexer: context [ reset: does [clear stk] clean-up: does [ - clear stk + unless empty? stk [ + clear next stk ;-- keep root block in stk + clear first stk ;-- clear root block + ] nl?: no ] ] From 3ce27cb770f02de8f9e07e2ba52324c8c333b9f9 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Fri, 27 Mar 2020 20:41:57 +0100 Subject: [PATCH 1243/3432] FIX: missing fix commit after last PR merge. The PR merge conflict resolution resulted in the loss of a fix commit. --- lexer.r | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index df90d7d0ee..1703612744 100644 --- a/lexer.r +++ b/lexer.r @@ -690,7 +690,10 @@ lexer: context [ reset: does [clear stk] clean-up: does [ - clear stk + unless empty? stk [ + clear next stk ;-- keep root block in stk + clear first stk ;-- clear root block + ] nl?: no ] ] From 98271c22d4bb4e6df583c65ef0f637a33305530e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 15:08:44 +0100 Subject: [PATCH 1244/3432] FEAT: finished implementation of rounding methods. --- runtime/datatypes/money.reds | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index c4896d47fc..1fa912fe12 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -35,6 +35,7 @@ money: context [ SIGN_MASK: 4000h ;-- used to get/set sign bit in the header SIGN_OFFSET: 14 + HALF_FRACTIONAL: 00000500h ;-- used for tie-breaking in round (little-endian order) KEEP_FRACTIONAL: FFFF0F00h ;-- used to extract fractional part (little-endian order) MAX_FRACTIONAL: as integer! (pow 10.0 as float! SIZE_SCALE) - 1.0 @@ -783,7 +784,7 @@ money: context [ end: as byte-ptr! formed + length? formed money: make-at stack/push* sign null start point end - if all [0.0 <> flt zero? sign? money][MONEY_OVERFLOW] ;-- underflow on too small float value + if all [0.0 <> flt zero-money? money][MONEY_OVERFLOW] ;-- underflow on too small float value money ] @@ -1342,7 +1343,7 @@ money: context [ quotient: quotient + SIZE_SBYTES - SIZE_BYTES amount1: hold ] - if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero value1 + if zero-amount? quotient [MONEY_OVERFLOW] ;-- got zero quotient from non-zero divisor unless zero? get-digit buffer overflow [MONEY_OVERFLOW] ;-- overflowed into most-significant digit set-amount value1 quotient ] @@ -1526,7 +1527,7 @@ money: context [ switch TYPE_OF(spec) [ TYPE_MONEY [ - return as red-money! spec + as red-money! spec ] TYPE_INTEGER [ integer: as red-integer! spec @@ -1666,19 +1667,26 @@ money: context [ floor? [logic!] ceil? [logic!] half-ceil? [logic!] - return: [red-money!] + return: [red-value!] + /local + half? [subroutine!] + result [red-money!] ][ #if debug? = yes [if verbose > 0 [print-line "money/round"]] - case [ - _even? [--NOT_IMPLEMENTED-- value] + half?: [value/amount3 and KEEP_FRACTIONAL = HALF_FRACTIONAL] + + result: case [ + _even? [either all [half? even? value][truncate value][away value]] down? [truncate value] - half-down? [--NOT_IMPLEMENTED-- value] + half-down? [either half? [truncate value][away value]] floor? [floor value] ceil? [ceil value] - half-ceil? [--NOT_IMPLEMENTED-- value] + half-ceil? [either half? [ceil value][away value]] true [away value] ] + + SET_RETURN(result) ;-- rounded value might not be in the frame base slot ] even?: func [ From 6e4e04686432456dd78b77ee0d3525762cea6071 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 15:08:58 +0100 Subject: [PATCH 1245/3432] TESTS: add more rounding tests. --- tests/source/units/money-test.red | 115 ++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 8b3c6047c4..a019f71190 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -373,12 +373,21 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional max-money: +$99'999'999'999'999'999.9999 min-money: -$99'999'999'999'999'999.9999 - --test-- "round" ;-- away from zero - --assert +$0.0 == round +$0.0 + --test-- "round" --assert -$4.0 == round -$3.5 --assert -$3.0 == round -$2.9 + --assert -$3.0 == round -$2.5 + --assert -$2.0 == round -$1.9 --assert -$1.0 == round -$1.1 + --assert -$1.0 == round -$0.5 + --assert -$0.0 == round -$0.1 + --assert -$0.0 == round -$0.0 + --assert +$0.0 == round +$0.0 + --assert +$0.0 == round +$0.1 + --assert +$1.0 == round +$0.5 --assert +$1.0 == round +$1.1 + --assert +$2.0 == round +$1.9 + --assert +$3.0 == round +$2.5 --assert +$3.0 == round +$2.9 --assert +$4.0 == round +$3.5 --assert error? try [round max-money] @@ -388,46 +397,124 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert true --test-- "round/even" - --assert true - - --test-- "round/down" ;-- truncation - --assert +$0.0 == round/down +$0.0 + --assert -$4.0 == round/even -$3.5 + --assert -$3.0 == round/even -$2.9 + --assert -$2.0 == round/even -$2.5 + --assert -$2.0 == round/even -$1.9 + --assert -$1.0 == round/even -$1.1 + --assert -$0.0 == round/even -$0.5 + --assert -$0.0 == round/even -$0.1 + --assert -$0.0 == round/even -$0.0 + --assert +$0.0 == round/even +$0.0 + --assert +$0.0 == round/even +$0.1 + --assert +$0.0 == round/even +$0.5 + --assert +$1.0 == round/even +$1.1 + --assert +$2.0 == round/even +$1.9 + --assert +$2.0 == round/even +$2.5 + --assert +$3.0 == round/even +$2.9 + --assert +$4.0 == round/even +$3.5 + --assert error? try [round/even max-money] + --assert error? try [round/even min-money] + + --test-- "round/down" --assert -$3.0 == round/down -$3.5 --assert -$2.0 == round/down -$2.9 + --assert -$2.0 == round/down -$2.5 + --assert -$1.0 == round/down -$1.9 --assert -$1.0 == round/down -$1.1 + --assert -$0.0 == round/down -$0.5 + --assert -$0.0 == round/down -$0.1 + --assert -$0.0 == round/down -$0.0 + --assert +$0.0 == round/down +$0.0 + --assert +$0.0 == round/down +$0.1 + --assert +$0.0 == round/down +$0.5 --assert +$1.0 == round/down +$1.1 + --assert +$1.0 == round/down +$1.9 + --assert +$2.0 == round/down +$2.5 --assert +$2.0 == round/down +$2.9 --assert +$3.0 == round/down +$3.5 --assert +$99'999'999'999'999'999 == round/down max-money --assert -$99'999'999'999'999'999 == round/down min-money - --test-- "round/half-down" - --assert true + --test-- "round/half-down" + --assert -$3.0 == round/half-down -$3.5 + --assert -$3.0 == round/half-down -$2.9 + --assert -$2.0 == round/half-down -$2.5 + --assert -$2.0 == round/half-down -$1.9 + --assert -$1.0 == round/half-down -$1.1 + --assert -$0.0 == round/half-down -$0.5 + --assert -$0.0 == round/half-down -$0.1 + --assert -$0.0 == round/half-down -$0.0 + --assert +$0.0 == round/half-down +$0.0 + --assert +$0.0 == round/half-down +$0.1 + --assert +$0.0 == round/half-down +$0.5 + --assert +$1.0 == round/half-down +$1.1 + --assert +$2.0 == round/half-down +$1.9 + --assert +$2.0 == round/half-down +$2.5 + --assert +$3.0 == round/half-down +$2.9 + --assert +$3.0 == round/half-down +$3.5 + --assert error? try [round/half-down max-money] + --assert error? try [round/half-down min-money] - --test-- "round/floor" ;-- towards negative infinity - --assert +$0.0 == round/floor +$0.0 + --test-- "round/floor" --assert -$4.0 == round/floor -$3.5 --assert -$3.0 == round/floor -$2.9 + --assert -$3.0 == round/floor -$2.5 + --assert -$2.0 == round/floor -$1.9 --assert -$2.0 == round/floor -$1.1 + --assert -$1.0 == round/floor -$0.5 + --assert -$1.0 == round/floor -$0.1 + --assert -$0.0 == round/floor -$0.0 + --assert +$0.0 == round/floor +$0.0 + --assert +$0.0 == round/floor +$0.1 + --assert +$0.0 == round/floor +$0.5 --assert +$1.0 == round/floor +$1.1 + --assert +$1.0 == round/floor +$1.9 + --assert +$2.0 == round/floor +$2.5 --assert +$2.0 == round/floor +$2.9 --assert +$3.0 == round/floor +$3.5 --assert +$99'999'999'999'999'999 == round/floor max-money --assert error? try [round/floor min-money] - --test-- "round/ceil" ;-- towards positive infinity - --assert +$0.0 == round/ceiling +$0.0 + --test-- "round/ceiling" --assert -$3.0 == round/ceiling -$3.5 --assert -$2.0 == round/ceiling -$2.9 + --assert -$2.0 == round/ceiling -$2.5 + --assert -$1.0 == round/ceiling -$1.9 --assert -$1.0 == round/ceiling -$1.1 + --assert -$0.0 == round/ceiling -$0.5 + --assert -$0.0 == round/ceiling -$0.1 + --assert -$0.0 == round/ceiling -$0.0 + --assert +$0.0 == round/ceiling +$0.0 + --assert +$1.0 == round/ceiling +$0.1 + --assert +$1.0 == round/ceiling +$0.5 --assert +$2.0 == round/ceiling +$1.1 + --assert +$2.0 == round/ceiling +$1.9 + --assert +$3.0 == round/ceiling +$2.5 --assert +$3.0 == round/ceiling +$2.9 --assert +$4.0 == round/ceiling +$3.5 --assert error? try [round/ceiling max-money] --assert -$99'999'999'999'999'999 == round/ceiling min-money - --test-- "round/half-ceil" - --assert true + --test-- "round/half-ceiling" + --assert -$3.0 == round/half-ceiling -$3.5 + --assert -$3.0 == round/half-ceiling -$2.9 + --assert -$2.0 == round/half-ceiling -$2.5 + --assert -$2.0 == round/half-ceiling -$1.9 + --assert -$1.0 == round/half-ceiling -$1.1 + --assert -$0.0 == round/half-ceiling -$0.5 + --assert -$0.0 == round/half-ceiling -$0.1 + --assert -$0.0 == round/half-ceiling -$0.0 + --assert +$0.0 == round/half-ceiling +$0.0 + --assert +$0.0 == round/half-ceiling +$0.1 + --assert +$1.0 == round/half-ceiling +$0.5 + --assert +$1.0 == round/half-ceiling +$1.1 + --assert +$2.0 == round/half-ceiling +$1.9 + --assert +$3.0 == round/half-ceiling +$2.5 + --assert +$3.0 == round/half-ceiling +$2.9 + --assert +$4.0 == round/half-ceiling +$3.5 + --assert error? try [round/half-ceiling max-money] + --assert error? try [round/half-ceiling min-money] ===end-group=== ===start-group=== "sort" From 43d0e77bfb70ef66e108bb56fe75d4a80d7a366c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 17:59:45 +0100 Subject: [PATCH 1246/3432] FEAT: remove conversion of MONEY! from/to BINARY!. --- runtime/datatypes/binary.reds | 10 ---------- runtime/datatypes/money.reds | 7 +++---- tests/source/units/money-test.red | 31 +++++++++++++------------------ 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/runtime/datatypes/binary.reds b/runtime/datatypes/binary.reds index f6f6261487..619cad361d 100644 --- a/runtime/datatypes/binary.reds +++ b/runtime/datatypes/binary.reds @@ -227,13 +227,6 @@ binary: context [ ] ] - from-money: func [ - mn [red-money!] - return: [red-binary!] - ][ - money/to-binary mn - ] - from-issue: func [ issue [red-word!] bin [red-binary!] @@ -1010,9 +1003,6 @@ binary: context [ p: as byte-ptr! unicode/to-utf8 as red-string! spec :len proto: load p len ] - TYPE_MONEY [ - proto: from-money as red-money! spec - ] TYPE_INTEGER [ int: as red-integer! spec make-at as red-value! proto 4 diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 1fa912fe12..18b995e078 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1507,10 +1507,9 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/make"]] switch TYPE_OF(spec) [ - TYPE_WORD [from-word as red-word! spec] - TYPE_BLOCK [from-block as red-block! spec] - TYPE_BINARY [from-binary as red-binary! spec] - default [to proto spec type] + TYPE_WORD [from-word as red-word! spec] + TYPE_BLOCK [from-block as red-block! spec] + default [to proto spec type] ] ] diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index a019f71190..9c5d9e8a6a 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -179,9 +179,7 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "to-24" --assert error? try [to money! "CCC$123"] --test-- "to-25" --assert error? try [to money! "123$456"] --test-- "to-26" --assert error? try [to money! "EUR123"] - --test-- "to-27" --assert #{00 00 00 00 00 00 00 00 00 00 00} == to binary! $0 - --test-- "to-28" --assert #{00 00 00 00 00 00 01 23 45 67 89} == to binary! -USD$1234.56789 - --test-- "to-29" + --test-- "to-27" --assert error? try [to money! "$"] --assert error? try [to money! "$."] --assert error? try [to money! "-$."] @@ -200,21 +198,18 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional ===end-group=== ===start-group=== "make" - --test-- "make-1" --assert $12345678901234567.12345 == make money! #{1234567890123456712345 DEADBEEF} - --test-- "make-2" --assert $0 == make money! #{} - --test-- "make-3" --assert error? try [make money! #{DEADBEEF}] - --test-- "make-4" --assert error? try [make money! []] - --test-- "make-5" --assert error? try [make money! [CCC]] - --test-- "make-6" --assert error? try [make money! [CCC 1 2 3]] - --test-- "make-6" --assert error? try [make money! [0 123456]] - --test-- "make-7" --assert -$123.00456 == make money! [-123 456] - --test-- "make-8" --assert $123.44444 == make money! [123.32100 12344] - --test-- "make-9" --assert -USD$123 == make money! [USD -123] - --test-- "make-10" --assert -EUR$123 == make money! [EUR -123 0] - --test-- "make-11" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] - --test-- "make-12" --assert "USD$0.00000" == mold/all make money! 'usd - --test-- "make-13" --assert "EUR$0.00000" == mold/all make money! 'EUR - --test-- "make-14" --assert error? try [make money! 'foo] + --test-- "make-1" --assert error? try [make money! []] + --test-- "make-2" --assert error? try [make money! [CCC]] + --test-- "make-3" --assert error? try [make money! [CCC 1 2 3]] + --test-- "make-4" --assert error? try [make money! [0 123456]] + --test-- "make-5" --assert -$123.00456 == make money! [-123 456] + --test-- "make-6" --assert $123.44444 == make money! [123.32100 12344] + --test-- "make-7" --assert -USD$123 == make money! [USD -123] + --test-- "make-8" --assert -EUR$123 == make money! [EUR -123 0] + --test-- "make-9" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] + --test-- "make-10" --assert "USD$0.00000" == mold/all make money! 'usd + --test-- "make-11" --assert "EUR$0.00000" == mold/all make money! 'EUR + --test-- "make-12" --assert error? try [make money! 'foo] ===end-group=== ===start-group=== "form/mold" From d9a1806e421a2da154df0d565906562932ae688c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:30:46 +0100 Subject: [PATCH 1247/3432] FIX: rewrite accessors w/o using literal array of function pointers. --- runtime/datatypes/money.reds | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 18b995e078..bd9d3fb1da 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -620,8 +620,6 @@ money: context [ accessor!: alias function! [money [red-money!] return: [red-value!]] - accessors: [:get-currency-from :get-amount-from] - resolve-accessor: func [ word [red-word!] return: [integer!] @@ -1726,8 +1724,12 @@ money: context [ default [0] ] - unless all [index > 0 index <= size? accessors][fire [TO_ERROR(script invalid-path) path element]] - access: as accessor! accessors/index + access: as accessor! switch index [ + 1 [:get-currency-from] + 2 [:get-amount-from] + default [fire [TO_ERROR(script invalid-path) path element]] + ] + access money ] @@ -1745,8 +1747,12 @@ money: context [ default [0] ] - unless all [index > 0 index <= size? accessors][fire [TO_ERROR(script out-of-range) boxed]] - access: as accessor! accessors/index + access: as accessor! switch index [ + 1 [:get-currency-from] + 2 [:get-amount-from] + default [fire [TO_ERROR(script out-of-range) boxed]] + ] + access money ] From 17584ddb8a10f5689294f97b3423f551c2046f71 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:31:30 +0100 Subject: [PATCH 1248/3432] FIX: avoid name clashing with rounding methods. --- runtime/datatypes/money.reds | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index bd9d3fb1da..33dddb9d76 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1445,7 +1445,7 @@ money: context [ as logic! money/amount3 and KEEP_FRACTIONAL ] - truncate: func [ + truncate-money: func [ money [red-money!] return: [red-money!] ][ @@ -1453,43 +1453,43 @@ money: context [ money ] - floor: func [ + floor-money: func [ money [red-money!] return: [red-money!] /local delta [red-money!] ][ switch sign? money [ - +1 [truncate money] + +1 [truncate-money money] 00 [money] -1 [ delta: from-integer as integer! fraction? money - subtract-money truncate money delta + subtract-money truncate-money money delta ] ] ] - ceil: func [ + ceil-money: func [ money [red-money!] return: [red-money!] /local delta [red-money!] ][ switch sign? money [ - -1 [truncate money] + -1 [truncate-money money] 00 [money] +1 [ delta: from-integer as integer! fraction? money - add-money truncate money delta + add-money truncate-money money delta ] ] ] - away: func [ + away-money: func [ money [red-money!] return: [red-money!] ][ - truncate set-sign + truncate-money set-sign add-money absolute-money money from-float 0.5 get-sign money ] @@ -1674,13 +1674,13 @@ money: context [ half?: [value/amount3 and KEEP_FRACTIONAL = HALF_FRACTIONAL] result: case [ - _even? [either all [half? even? value][truncate value][away value]] - down? [truncate value] - half-down? [either half? [truncate value][away value]] - floor? [floor value] - ceil? [ceil value] - half-ceil? [either half? [ceil value][away value]] - true [away value] + _even? [either all [half? even? value][truncate-money value][away-money value]] + down? [truncate-money value] + half-down? [either half? [truncate-money value][away-money value]] + floor? [floor-money value] + ceil? [ceil-money value] + half-ceil? [either half? [ceil-money value][away-money value]] + true [away-money value] ] SET_RETURN(result) ;-- rounded value might not be in the frame base slot From 6805c274e555942da38ca7e8b27a71d228ec525a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:33:17 +0100 Subject: [PATCH 1249/3432] FIX: properly create symbol in PUSH call. --- runtime/datatypes/money.reds | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 33dddb9d76..cd13f7ddf4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -502,23 +502,10 @@ money: context [ money ] - - make-in: func [ - parent [red-block!] - sign [logic!] - currency [byte-ptr!] - start [byte-ptr!] - point [byte-ptr!] - end [byte-ptr!] - return: [red-money!] - ][ - #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] - make-at ALLOC_TAIL(parent) sign currency start point end ;@@ can return null - ] - + push: func [ sign [logic!] ;-- yes: negative - currency [c-string!] ;-- null if generic currency, otherwise 3-letter string + currency [c-string!] ;-- null if generic currency, otherwise 3 bytes amount [c-string!] ;-- always SIZE_BYTES bytes return: [red-money!] /local @@ -534,7 +521,7 @@ money: context [ set-amount money as byte-ptr! amount ;@@ TBD: assuming currency code is valid - index: either null? currency [0][get-index symbol/make currency] + index: either null? currency [0][get-index symbol/make-alt-utf8 as byte-ptr! currency 3] set-currency money index money From cfd9a91563e659d4d7fb1982e6c321dfdb37a7e5 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:34:08 +0100 Subject: [PATCH 1250/3432] FEAT: forbid float values in BLOCK! prototype. --- runtime/datatypes/money.reds | 21 ++++++--------------- tests/source/units/money-test.red | 13 ++++++------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index cd13f7ddf4..971de52128 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -816,7 +816,6 @@ money: context [ money fraction [red-money!] wrd [red-word!] int [red-integer!] - flt [red-float!] head tail here [red-value!] currency state [integer!] type length [integer!] @@ -837,10 +836,9 @@ money: context [ switch state [ S_START [ switch type [ - TYPE_WORD [state: S_CURRENCY] - TYPE_INTEGER - TYPE_FLOAT [state: S_INTEGRAL] - default [bail] + TYPE_WORD [state: S_CURRENCY] + TYPE_INTEGER [state: S_INTEGRAL] + default [bail] ] ] S_CURRENCY [ @@ -852,16 +850,9 @@ money: context [ state: S_INTEGRAL ] S_INTEGRAL [ - switch type [ - TYPE_INTEGER [ - int: as red-integer! here - money: from-integer int/value - ] - TYPE_FLOAT [ - flt: as red-float! here - money: from-float flt/value - ] - default [bail] + either type <> TYPE_INTEGER [bail][ + int: as red-integer! here + money: from-integer int/value ] here: here + 1 state: either here = tail [S_END][S_FRACTIONAL] diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 9c5d9e8a6a..b3fc3ebd48 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -203,13 +203,12 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-3" --assert error? try [make money! [CCC 1 2 3]] --test-- "make-4" --assert error? try [make money! [0 123456]] --test-- "make-5" --assert -$123.00456 == make money! [-123 456] - --test-- "make-6" --assert $123.44444 == make money! [123.32100 12344] - --test-- "make-7" --assert -USD$123 == make money! [USD -123] - --test-- "make-8" --assert -EUR$123 == make money! [EUR -123 0] - --test-- "make-9" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] - --test-- "make-10" --assert "USD$0.00000" == mold/all make money! 'usd - --test-- "make-11" --assert "EUR$0.00000" == mold/all make money! 'EUR - --test-- "make-12" --assert error? try [make money! 'foo] + --test-- "make-6" --assert -USD$123 == make money! [USD -123] + --test-- "make-7" --assert -EUR$123 == make money! [EUR -123 0] + --test-- "make-8" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] + --test-- "make-9" --assert "USD$0.00000" == mold/all make money! 'usd + --test-- "make-10" --assert "EUR$0.00000" == mold/all make money! 'EUR + --test-- "make-11" --assert error? try [make money! 'foo] ===end-group=== ===start-group=== "form/mold" From 028818248e05713471c176c70677a02989e38e61 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:40:03 +0100 Subject: [PATCH 1251/3432] FEAT: minor refactoring. --- runtime/datatypes/money.reds | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 971de52128..bba62b9709 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -459,9 +459,7 @@ money: context [ ;-- currency code unless null? currency [ - str: "..." ;-- 3 letters - copy-memory as byte-ptr! str currency 3 - index: get-index symbol/make str + index: get-index symbol/make-alt-utf8 currency 3 if negative? index [return null] ;-- throw it back to lexer for proper error reporting set-currency money index ] From 4c340b362bf205cb9e0a87bfd86b9e5a85c8737a Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Sat, 28 Mar 2020 19:58:32 +0100 Subject: [PATCH 1252/3432] FIX: permit floats as a single value in BLOCK! prototype. --- runtime/datatypes/money.reds | 20 ++++++++++++++++---- tests/source/units/money-test.red | 15 +++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index bba62b9709..61a7d1f994 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -814,6 +814,7 @@ money: context [ money fraction [red-money!] wrd [red-word!] int [red-integer!] + flt [red-float!] head tail here [red-value!] currency state [integer!] type length [integer!] @@ -835,6 +836,7 @@ money: context [ S_START [ switch type [ TYPE_WORD [state: S_CURRENCY] + TYPE_FLOAT TYPE_INTEGER [state: S_INTEGRAL] default [bail] ] @@ -848,12 +850,22 @@ money: context [ state: S_INTEGRAL ] S_INTEGRAL [ - either type <> TYPE_INTEGER [bail][ - int: as red-integer! here - money: from-integer int/value + switch type [ + TYPE_INTEGER [ + int: as red-integer! here + money: from-integer int/value + ] + TYPE_FLOAT [ + flt: as red-float! here + money: from-float flt/value + ] + default [bail] ] here: here + 1 - state: either here = tail [S_END][S_FRACTIONAL] + state: either here = tail [S_END][ + if type = TYPE_FLOAT [bail] + S_FRACTIONAL + ] ] S_FRACTIONAL [ either type <> TYPE_INTEGER [bail][ diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index b3fc3ebd48..fd074d84c1 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -203,12 +203,15 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-3" --assert error? try [make money! [CCC 1 2 3]] --test-- "make-4" --assert error? try [make money! [0 123456]] --test-- "make-5" --assert -$123.00456 == make money! [-123 456] - --test-- "make-6" --assert -USD$123 == make money! [USD -123] - --test-- "make-7" --assert -EUR$123 == make money! [EUR -123 0] - --test-- "make-8" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] - --test-- "make-9" --assert "USD$0.00000" == mold/all make money! 'usd - --test-- "make-10" --assert "EUR$0.00000" == mold/all make money! 'EUR - --test-- "make-11" --assert error? try [make money! 'foo] + --test-- "make-6" --assert -$123.456 == make money! [-123.456] + --test-- "make-7" --assert "-EUR$123.45600" == mold/all make money! [EUR -123.456] + --test-- "make-8" --assert "-USD$123.00000" == mold/all make money! [USD -123] + --test-- "make-9" --assert "-EUR$123.00000" == mold/all make money! [EUR -123 0] + --test-- "make-10" --assert "-EUR$456.78900" == mold/all make money! [EUR -456 78900] + --test-- "make-11" --assert "USD$0.00000" == mold/all make money! 'usd + --test-- "make-12" --assert "EUR$0.00000" == mold/all make money! 'EUR + --test-- "make-13" --assert error? try [make money! 'foo] + --test-- "make-14" --assert error? try [make money! [123.45 6789]] ===end-group=== ===start-group=== "form/mold" From 729d1eefaa54e6a44b95c9a88731191d972daac6 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 28 Mar 2020 20:14:06 +0100 Subject: [PATCH 1253/3432] FEAT: adds Redbin support for money! literal values. --- runtime/datatypes/money.reds | 34 ++++++++++++++++------------------ runtime/redbin.reds | 21 +++++++++++++++++++++ utils/redbin.r | 16 ++++++++++++++++ 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 9494cb6dd1..e29e4f521b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -507,34 +507,22 @@ money: context [ ] make-in: func [ - parent [red-block!] - sign [logic!] - currency [byte-ptr!] - start [byte-ptr!] - point [byte-ptr!] - end [byte-ptr!] - return: [red-money!] - ][ - #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] - make-at ALLOC_TAIL(parent) sign currency start point end ;@@ can return null - ] - - push: func [ + slot [red-value!] sign [logic!] ;-- yes: negative - currency [c-string!] ;-- null if generic currency, otherwise 3-letter string - amount [c-string!] ;-- always SIZE_BYTES bytes + currency [c-string!] ;-- null if generic currency, otherwise 3 bytes + amount [byte-ptr!] ;-- always SIZE_BYTES bytes return: [red-money!] /local money [red-money!] index [integer!] ][ - #if debug? = yes [if verbose > 0 [print-line "money/push"]] + #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] - money: as red-money! stack/push* + money: as red-money! slot money/header: TYPE_MONEY set-sign money as integer! sign - set-amount money as byte-ptr! amount + set-amount money amount ;@@ TBD: assuming currency code is valid index: either null? currency [0][get-index symbol/make currency] @@ -543,6 +531,16 @@ money: context [ money ] + push: func [ + sign [logic!] ;-- yes: negative + currency [c-string!] ;-- null if generic currency, otherwise 3-letter string + amount [c-string!] ;-- always SIZE_BYTES bytes + return: [red-money!] + ][ + #if debug? = yes [if verbose > 0 [print-line "money/push"]] + make-in stack/push* sign currency as byte-ptr! amount + ] + form-money: func [ money [red-money!] buffer [red-string!] diff --git a/runtime/redbin.reds b/runtime/redbin.reds index 790d36779e..13918f86c1 100644 --- a/runtime/redbin.reds +++ b/runtime/redbin.reds @@ -325,6 +325,26 @@ redbin: context [ tuple/array3: data/4 data + 4 ] + + decode-money: func [ + data [int-ptr!] + parent [red-block!] + nl? [logic!] + return: [int-ptr!] + /local + slot [red-money!] + cur p [byte-ptr!] + neg? [logic!] + ][ + neg?: data/1 and 0Eh <> 0 + cur: as byte-ptr! data + 1 + if cur/1 = #"." [cur: null] + p: as byte-ptr! data + 2 + p: p + 1 ;-- skip padding byte + slot: money/make-in ALLOC_TAIL(parent) neg? as-c-string cur p + if nl? [slot/header: slot/header or flag-new-line] + data + 5 + ] decode-value: func [ data [int-ptr!] @@ -414,6 +434,7 @@ redbin: context [ TYPE_ACTION TYPE_OP [decode-native data table parent nl?] TYPE_TUPLE [decode-tuple data parent nl?] + TYPE_MONEY [decode-money data parent nl?] REDBIN_PADDING [ decode-value data + 1 table parent ] diff --git a/utils/redbin.r b/utils/redbin.r index 6b26de665a..61d4b0e772 100644 --- a/utils/redbin.r +++ b/utils/redbin.r @@ -180,6 +180,18 @@ context [ emit to integer! copy/part skip bin -8 4 emit to integer! copy/part head bin 4 ] + + emit-money: func [value [issue!] /local bin header][ + value: to string! next value + header: extracts/definitions/TYPE_MONEY or shift/left to-integer value/4 = #"-" 14 + if nl? [header: header or nl-flag] + emit header + repend buffer [ + append copy/part value 3 null ;-- currency code ("..." if none) + #{00} ;-- padding + to binary! to-nibbles copy/part skip value 4 22 ;-- nibbles array + ] + ] emit-op: func [spec [any-word!]][ emit-type 'TYPE_OP @@ -344,6 +356,10 @@ context [ emit-fp-special item no ] + money-value? :item [ + emit-money item + no + ] 'else [ emit-issue item no From e3af14b6ad15a7d68bcf73e3ec25f6c0ba9f92f8 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 17:48:06 +0200 Subject: [PATCH 1254/3432] FEAT: finish implementation of ROUND. --- runtime/datatypes/money.reds | 118 ++++++++++++++--------------------- 1 file changed, 46 insertions(+), 72 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 5b5d5550b4..647c724d2f 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1435,64 +1435,6 @@ money: context [ SET_RETURN(result) ;-- swapped arguments ] - ;-- Rounding -- - - fraction?: func [ - money [red-money!] - return: [logic!] - ][ - as logic! money/amount3 and KEEP_FRACTIONAL - ] - - truncate-money: func [ - money [red-money!] - return: [red-money!] - ][ - money/amount3: money/amount3 and not KEEP_FRACTIONAL - money - ] - - floor-money: func [ - money [red-money!] - return: [red-money!] - /local - delta [red-money!] - ][ - switch sign? money [ - +1 [truncate-money money] - 00 [money] - -1 [ - delta: from-integer as integer! fraction? money - subtract-money truncate-money money delta - ] - ] - ] - - ceil-money: func [ - money [red-money!] - return: [red-money!] - /local - delta [red-money!] - ][ - switch sign? money [ - -1 [truncate-money money] - 00 [money] - +1 [ - delta: from-integer as integer! fraction? money - add-money truncate-money money delta - ] - ] - ] - - away-money: func [ - money [red-money!] - return: [red-money!] - ][ - truncate-money set-sign - add-money absolute-money money from-float 0.5 - get-sign money - ] - ;-- Actions -- make: func [ @@ -1656,33 +1598,65 @@ money: context [ round: func [ value [red-money!] - scale [red-float!] + _scale [red-float!] _even? [logic!] down? [logic!] half-down? [logic!] floor? [logic!] ceil? [logic!] half-ceil? [logic!] - return: [red-value!] + return: [red-money!] /local - half? [subroutine!] - result [red-money!] + up down [subroutine!] + away ceil floor [subroutine!] + scale lower upper [red-money!] + int [red-integer!] + sign type [integer!] + half? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "money/round"]] - half?: [value/amount3 and KEEP_FRACTIONAL = HALF_FRACTIONAL] + sign: sign? value + if zero? sign [return value] + + scale: absolute-money either not OPTION?(_scale) [from-integer 1][ + type: TYPE_OF(_scale) + switch type [ + TYPE_MONEY [as red-money! _scale] + TYPE_INTEGER [int: as red-integer! _scale from-integer int/value] + TYPE_FLOAT [from-float _scale/value] + default [ + fire [TO_ERROR(script not-related) stack/get-call datatype/push type] + value ;-- pass compiler's type checking + ] + ] + ] + + if zero-money? scale [fire [TO_ERROR(math overflow)]] + value: absolute-money value + + lower: divide-money as red-money! stack/push as red-value! value scale yes no + upper: subtract-money scale lower + half?: lower/amount3 and KEEP_FRACTIONAL = HALF_FRACTIONAL - result: case [ - _even? [either all [half? even? value][truncate-money value][away-money value]] - down? [truncate-money value] - half-down? [either half? [truncate-money value][away-money value]] - floor? [floor-money value] - ceil? [ceil-money value] - half-ceil? [either half? [ceil-money value][away-money value]] - true [away-money value] + up: [add-money value upper] + down: [subtract-money value lower] + away: [either negative? compare-money lower upper [down][up]] + ceil: [either negative? sign [down][up]] + floor: [either negative? sign [up][down]] + + case [ + _even? [either all [half? even? value][down][away]] + down? [down] + half-down? [either half? [down][away]] + floor? [floor] + ceil? [ceil] + half-ceil? [either half? [ceil][away]] + true [away] ] - SET_RETURN(result) ;-- rounded value might not be in the frame base slot + set-sign value as integer! negative? sign + value ] even?: func [ From f287bc6b9810e3122d06a3a21d6092eef61fc886 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 17:48:45 +0200 Subject: [PATCH 1255/3432] TESTS: add tests for ROUND/TO. --- tests/source/units/money-test.red | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index fd074d84c1..6eec0f475b 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -391,7 +391,27 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [round min-money] --test-- "round/to" - --assert true + --assert $0 == round/to $0 123 + --assert $123 == round/to $123.45 -$1.0 + --assert -$68 == round/to -$67.89 1.0 + --assert $3.0 == round/to/floor $4.5 3.0 + --assert -$6.0 == round/to/floor -$4.5 3 + --assert $6.0 == round/to/ceiling $4.5 -3.0 + --assert -$3.0 == round/to/ceiling -$4.5 3 + --assert -$6.0 == round/to -$4.5 3.0 + --assert +$6.0 == round/to +$4.5 3 + --assert $4.998 == round/to EUR$5 0.357 + --assert $3.8 == round/to $3.75 0.1 + --assert $1.375 == round/to $1.333 -$0.125 + --assert $1.33 == round/to $1.333 0.01 + --assert -$3.0 == round/to/floor -USD$2.4 $1.0 + --assert -$2.0 == round/to/ceiling -$2.4 1.0 + --assert -$4.0 == round/to/floor -$2.4 2.0 + --assert -$1.0 == round/to -$0.50 1 + --assert $0.0 == round/to -$0.49 1 + --assert error? try [round/to $123 0] + --assert error? try [round/to $123 100%] + --assert error? try [round/to $123 1:2:3] --test-- "round/even" --assert -$4.0 == round/even -$3.5 From 1ef721301a46bba08419dab20e005d9028a83616 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 17:49:48 +0200 Subject: [PATCH 1256/3432] FEAT: allow only MONEY! to be rounded to MONEY!. --- environment/actions.red | 2 +- runtime/datatypes/float.reds | 4 ++++ runtime/datatypes/integer.reds | 4 ++++ runtime/datatypes/pair.reds | 4 ++++ runtime/datatypes/time.reds | 4 ++++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/environment/actions.red b/environment/actions.red index f272c19966..87d4ffbdd8 100644 --- a/environment/actions.red +++ b/environment/actions.red @@ -148,7 +148,7 @@ round: make action! [[ "Returns the nearest integer. Halves round up (away from zero) by default" n [number! money! time! pair!] /to "Return the nearest multiple of the scale parameter" - scale [number! time!] "Must be a non-zero value" + scale [number! money! time!] "Must be a non-zero value" /even "Halves round toward even results" /down "Round toward zero, ignoring discarded digits. (truncate)" /half-down "Halves round toward zero" diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 2a01a4ddce..598effa915 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -868,6 +868,10 @@ float: context [ e [integer!] v [logic!] ][ + if TYPE_OF(scale) = TYPE_MONEY [ + fire [TO_ERROR(script not-related) stack/get-call datatype/push TYPE_MONEY] + ] + e: 0 f: as red-float! value dec: f/value diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index a43a6081b0..6e7c3d6398 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -726,6 +726,10 @@ integer: context [ r [integer!] val [integer!] ][ + if TYPE_OF(scale) = TYPE_MONEY [ + fire [TO_ERROR(script not-related) stack/get-call datatype/push TYPE_MONEY] + ] + int: as red-integer! value num: int/value if num = 80000000h [return value] diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index 666beed694..199a542edc 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -330,6 +330,10 @@ pair: context [ header [integer!] val [red-integer!] ][ + if TYPE_OF(scale) = TYPE_MONEY [ + fire [TO_ERROR(script not-related) stack/get-call datatype/push TYPE_MONEY] + ] + pair: as red-pair! value header: TYPE_INTEGER val: as red-integer! :header diff --git a/runtime/datatypes/time.reds b/runtime/datatypes/time.reds index e34e07af47..6e8e05feda 100644 --- a/runtime/datatypes/time.reds +++ b/runtime/datatypes/time.reds @@ -409,6 +409,10 @@ time: context [ val [float!] ret [red-float!] ][ + if TYPE_OF(scale) = TYPE_MONEY [ + fire [TO_ERROR(script not-related) stack/get-call datatype/push TYPE_MONEY] + ] + float/round as red-value! tm scale _even? down? half-down? floor? ceil? half-ceil? ret: as red-float! tm if ret/header = TYPE_INTEGER [ From 1e35eadfd680f0464a3fc4b507bcceac84c7a896 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 18:40:25 +0200 Subject: [PATCH 1257/3432] FIX: invalid currency code indexing. --- runtime/datatypes/money.reds | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 647c724d2f..e8bb523bd4 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -114,15 +114,15 @@ money: context [ money [red-money!] return: [red-value!] ;-- word or none /local + list [red-series!] index [integer!] ][ index: get-currency money if zero? index [return none/push] ;-- generic currency ;@@ TBD: check extra list also - block/rs-abs-at - as red-block! #get system/locale/currencies/base - index + list: as red-series! #get system/locale/currencies/base + _series/pick list index as red-value! money ] get-currency: func [ @@ -152,17 +152,17 @@ money: context [ sym [integer!] return: [integer!] ;-- -1: invalid currency code /local - list [red-block!] + list [red-series!] here [red-word!] head tail [red-value!] index [integer!] ][ - list: as red-block! #get system/locale/currencies/base + list: as red-series! #get system/locale/currencies/base head: block/rs-head list tail: block/rs-tail list here: as red-word! head - index: 0 + index: 1 ;-- 1-based indexing until [ if sym = symbol/resolve here/symbol [break] index: index + 1 @@ -179,13 +179,13 @@ money: context [ index [integer!] return: [integer!] /local - base [red-block!] + list [red-series!] word [red-word!] ][ assert all [index > 0 index <= FFh] - base: as red-block! #get system/locale/currencies/base - word: as red-word! block/rs-abs-at base index + list: as red-series! #get system/locale/currencies/base + word: as red-word! _series/pick list index as red-value! list ;@@ TBD: walk over extra list also symbol/resolve word/symbol From df726271ba859fd99585297637837d015a1bd342 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 19:59:24 +0200 Subject: [PATCH 1258/3432] FIX: more robust MOLD/PART. --- runtime/datatypes/money.reds | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index e8bb523bd4..431dd7541b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -571,6 +571,7 @@ money: context [ ] string/concatenate-literal buffer "$" + part: part - 1 count: count-digits amount index: SIZE_DIGITS - count + 1 @@ -605,11 +606,12 @@ money: context [ if any [all? times > SIZE_SCALE][times: SIZE_SCALE] if positive? times [ string/concatenate-literal buffer "." + part: part - 1 group?: no fill ] - part - 2 ;-- compensate for $ and . characters + part ] ;-- Deconstruction -- From 7d94d164ce4237446e41a047ed4779778eeb7730 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 20:07:32 +0200 Subject: [PATCH 1259/3432] FIX: some currencies could not be loaded. --- runtime/datatypes/money.reds | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 431dd7541b..4f51c92c3a 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -163,6 +163,7 @@ money: context [ here: as red-word! head index: 1 ;-- 1-based indexing + sym: symbol/resolve sym until [ if sym = symbol/resolve here/symbol [break] index: index + 1 @@ -856,7 +857,7 @@ money: context [ ] S_CURRENCY [ wrd: as red-word! here - currency: get-index symbol/resolve wrd/symbol + currency: get-index wrd/symbol if negative? currency [bail] here: here + 1 if here = tail [bail] @@ -910,7 +911,7 @@ money: context [ money: zero-out as red-money! stack/push* money/header: TYPE_MONEY - index: get-index symbol/resolve word/symbol + index: get-index word/symbol if negative? index [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY word]] set-currency money index From e89ffdd8ac558bbd9f9dbd1b3b5a502d1e8ca203 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 20:34:14 +0200 Subject: [PATCH 1260/3432] FEAT: minor code cleanup. --- runtime/datatypes/money.reds | 2 -- 1 file changed, 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 4f51c92c3a..be0898456d 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -546,9 +546,7 @@ money: context [ return: [integer!] /local fill [subroutine!] - base [red-block!] sym [red-string!] - word [red-word!] after [red-integer!] amount [byte-ptr!] sign count [integer!] From f8faa640215d19d0e3a51eb1f5d7887eb8439669 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 20:55:24 +0200 Subject: [PATCH 1261/3432] FIX: some currencies are not properly MOLDed. --- runtime/datatypes/money.reds | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index be0898456d..8b6289c053 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -114,15 +114,10 @@ money: context [ money [red-money!] return: [red-value!] ;-- word or none /local - list [red-series!] index [integer!] ][ index: get-currency money - if zero? index [return none/push] ;-- generic currency - - ;@@ TBD: check extra list also - list: as red-series! #get system/locale/currencies/base - _series/pick list index as red-value! money + either zero? index [none/push][as red-value! get-symbol index] ] get-currency: func [ @@ -178,7 +173,7 @@ money: context [ get-symbol: func [ index [integer!] - return: [integer!] + return: [red-word!] /local list [red-series!] word [red-word!] @@ -189,7 +184,7 @@ money: context [ word: as red-word! _series/pick list index as red-value! list ;@@ TBD: walk over extra list also - symbol/resolve word/symbol + word ] same-currencies?: func [ @@ -546,7 +541,6 @@ money: context [ return: [integer!] /local fill [subroutine!] - sym [red-string!] after [red-integer!] amount [byte-ptr!] sign count [integer!] @@ -564,9 +558,8 @@ money: context [ ;-- currency code index: get-currency money unless zero? index [ ;-- generic currency - sym: as red-string! symbol/get get-symbol index - string/concatenate buffer sym -1 0 yes no - part: part - string/rs-length? sym + word/form get-symbol index buffer stack/arguments part + part: part - 3 ] string/concatenate-literal buffer "$" From 71502ca43d077ba85f97b5bade7da340528e9b0b Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 21:02:14 +0200 Subject: [PATCH 1262/3432] TESTS: add tests for an issue with malformed MONEY! values. 3-letter currency codes are stored as WORD! values in currency list. Some currency codes (RED, TRY, ALL) contain symbols that are part of Red's base definitions, and will resolve to their original aliases (Red, try and all, respectively). So e.g. RED$123 will be FORMed as Red$123, TRY$456 -> try$456, etc. --- tests/source/units/money-test.red | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 6eec0f475b..2d65cac10e 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -566,6 +566,29 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "transcode-money-2" --assert money? first load "$123 $456" --test-- "transcode-money-3" --assert money? last load "$123 -USD$456" --test-- "transcode-money-4" --assert money! == transcode/prescan "+EUR$123.456 1 2 3" + --test-- "transcode-money-5" --assert "AED$123.45678" == mold/all AED$123.45678 + --test-- "transcode-money-6" --assert "-ZMW$123.45678" == mold/all -ZMW$123.45678 + --test-- "transcode-money-7" + "RED$0.00000" == mold/all red$0 + "RED$0.00000" == mold/all RED$0 + "RED$0.00000" == mold/all Red$0 + "RED$0.00000" == mold/all transcode/one "red$0" + "RED$0.00000" == mold/all transcode/one "RED$0" + "RED$0.00000" == mold/all transcode/one "Red$0" + "RED$0.00000" == mold/all make money! 'red + "RED$0.00000" == mold/all make money! 'RED + "RED$0.00000" == mold/all make money! 'Red + "RED$0.00000" == mold/all make money! [red 0] + "RED$0.00000" == mold/all make money! [RED 0] + "RED$0.00000" == mold/all make money! [Red 0] + "RED$0.00000" == mold/all make money! "red$0" + "RED$0.00000" == mold/all make money! "RED$0" + "RED$0.00000" == mold/all make money! "Red$0" + ;--test-- "transcode-money-" + ;--assert error! == transcode/prescan "-$.1" + ;--assert error! == transcode/prescan "+$,2" + ;--assert error! == transcode/prescan "$3." + ;--assert error! == transcode/prescan "$4," ===end-group=== ===start-group=== "as-money" From 460ee605403807d5680065796e307cafdc0a907e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 30 Mar 2020 21:05:12 +0200 Subject: [PATCH 1263/3432] FEAT: slightly better naming. --- runtime/datatypes/money.reds | 16 ++++++++-------- runtime/natives.reds | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 8b6289c053..45c74464b3 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -117,7 +117,7 @@ money: context [ index [integer!] ][ index: get-currency money - either zero? index [none/push][as red-value! get-symbol index] + either zero? index [none/push][as red-value! get-currency-code index] ] get-currency: func [ @@ -143,7 +143,7 @@ money: context [ money ] - get-index: func [ + get-currency-index: func [ sym [integer!] return: [integer!] ;-- -1: invalid currency code /local @@ -171,7 +171,7 @@ money: context [ either here = tail [-1][index] ] - get-symbol: func [ + get-currency-code: func [ index [integer!] return: [red-word!] /local @@ -455,7 +455,7 @@ money: context [ ;-- currency code unless null? currency [ - index: get-index symbol/make-alt-utf8 currency 3 + index: get-currency-index symbol/make-alt-utf8 currency 3 if negative? index [return null] ;-- throw it back to lexer for proper error reporting set-currency money index ] @@ -516,7 +516,7 @@ money: context [ set-amount money amount ;@@ TBD: assuming currency code is valid - index: either null? currency [0][get-index symbol/make currency] + index: either null? currency [0][get-currency-index symbol/make currency] set-currency money index money @@ -558,7 +558,7 @@ money: context [ ;-- currency code index: get-currency money unless zero? index [ ;-- generic currency - word/form get-symbol index buffer stack/arguments part + word/form get-currency-code index buffer stack/arguments part part: part - 3 ] @@ -848,7 +848,7 @@ money: context [ ] S_CURRENCY [ wrd: as red-word! here - currency: get-index wrd/symbol + currency: get-currency-index wrd/symbol if negative? currency [bail] here: here + 1 if here = tail [bail] @@ -902,7 +902,7 @@ money: context [ money: zero-out as red-money! stack/push* money/header: TYPE_MONEY - index: get-index word/symbol + index: get-currency-index word/symbol if negative? index [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY word]] set-currency money index diff --git a/runtime/natives.reds b/runtime/natives.reds index 9f6fe713d2..387c1f4aa0 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2020,7 +2020,7 @@ natives: context [ currency: as red-word! argument amount: stack/arguments + 1 - index: money/get-index symbol/resolve currency/symbol + index: money/get-currency-index currency/symbol if negative? index [fire [TO_ERROR(script bad-denom) word/push currency]] switch TYPE_OF(amount) [ From fe542ce9fc4856b4e2fc08de3d0f44e26bc8fd2e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 31 Mar 2020 09:07:53 +0200 Subject: [PATCH 1264/3432] FIX: consistent order of ROUND refinements. Consistent with FLOAT! and INTEGER! that is. --- runtime/datatypes/money.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 45c74464b3..281e832ddb 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1640,11 +1640,11 @@ money: context [ floor: [either negative? sign [up][down]] case [ - _even? [either all [half? even? value][down][away]] down? [down] - half-down? [either half? [down][away]] floor? [floor] ceil? [ceil] + _even? [either all [half? even? value][down][away]] + half-down? [either half? [down][away]] half-ceil? [either half? [ceil][away]] true [away] ] From ac709677210eb11448bd813ff32de90fccf8e8b2 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 31 Mar 2020 09:30:16 +0200 Subject: [PATCH 1265/3432] FIX: assume defaults when SYSTEM/OPTIONS/MONEY-DIGITS isn't an integer. --- runtime/datatypes/money.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 281e832ddb..9e2c62542b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -594,7 +594,7 @@ money: context [ ;-- fractional part after: as red-integer! #get system/options/money-digits - times: after/value + times: either TYPE_OF(after) = TYPE_INTEGER [after/value][2] ;-- revert to default value if any [all? times > SIZE_SCALE][times: SIZE_SCALE] if positive? times [ string/concatenate-literal buffer "." From 0247892dda241dbb3f65c44ca4e5db33707de12e Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 31 Mar 2020 14:54:15 +0200 Subject: [PATCH 1266/3432] FEAT: preliminary work on custom currencies support. --- runtime/datatypes/money.reds | 53 ++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 9e2c62542b..a06fa83f2a 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -147,28 +147,45 @@ money: context [ sym [integer!] return: [integer!] ;-- -1: invalid currency code /local + walk [subroutine!] list [red-series!] here [red-word!] head tail [red-value!] index [integer!] ][ - list: as red-series! #get system/locale/currencies/base - head: block/rs-head list - tail: block/rs-tail list - here: as red-word! head - index: 1 ;-- 1-based indexing sym: symbol/resolve sym - until [ - if sym = symbol/resolve here/symbol [break] - index: index + 1 - here: here + 1 + + here: declare red-word! + tail: declare red-value! + + walk: [ + head: block/rs-head list + tail: block/rs-tail list + here: as red-word! head + + if head = tail [return -1] - here = tail + until [ + if sym = symbol/resolve here/symbol [break] + index: index + 1 + here: here + 1 + + here = tail + ] + + assert all [index >= 1 index <= FFh] ] - ;@@ TBD: walk over extra list also - either here = tail [-1][index] + list: as red-series! #get system/locale/currencies/base + walk + + if here < tail [return index] + + list: as red-series! #get system/locale/currencies/extra + walk + + either here < tail [index][-1] ] get-currency-code: func [ @@ -176,15 +193,18 @@ money: context [ return: [red-word!] /local list [red-series!] - word [red-word!] + size [integer!] ][ assert all [index > 0 index <= FFh] list: as red-series! #get system/locale/currencies/base - word: as red-word! _series/pick list index as red-value! list + size: _series/length? list + if index > size [ + list: as red-series! #get system/locale/currencies/extra + index: index - size + ] - ;@@ TBD: walk over extra list also - word + as red-word! _series/pick list index as red-value! list ] same-currencies?: func [ @@ -1650,7 +1670,6 @@ money: context [ ] set-sign value as integer! negative? sign - value ] even?: func [ From ce0f9a093f7036b8b25a4a8356fb02dabce28faa Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 31 Mar 2020 14:54:31 +0200 Subject: [PATCH 1267/3432] TESTS: tests for currency lists and custom currencies. --- tests/source/units/money-test.red | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 2d65cac10e..ca4285fbfc 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -626,6 +626,44 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [money/5] ===end-group=== +===start-group=== "currency list" + list: system/locale/currencies + --test-- "custom-1" + --assert error? try [append list/base 'foo] + --assert error? try [clear list/base] + --assert error? try [reverse list/base] + --assert error? try [random list/base] + --assert error? try [list/base: none] + --assert error? try [list/base/1: none] + --assert error? try [put list/extra 'usd 'eur] + --test-- "custom-2" + --assert error? try [append list/extra none] + --assert error? try [append list/extra quote :foo] + --assert error? try [append list/extra 'foo!] + --assert error? try [append list/extra 'usd] + --assert error? try [list/extra: none] + --assert error? try [list/extra/1: none] + --test-- "custom-3" + --assert error? try [make money! 'bar] + append list/extra 'bar + --assert money? make money! 'bar + ;--assert "BAR$0.00000" == mold/all make money! 'bar + --assert error? try [make money! 'qux] + append list/extra 'QUX + --assert "-QUX$123.45678" == mold/all make money! [QUX -123 45678] + ;--assert -QUX$123.45 == -QUX$123.45 + ;--assert zero? BAR$67.89 - BAR$67.89 + --test-- "custom-4" + --assert error? try [append list/extra 'bar] + --assert error? try [append list/extra 'qux] + --assert error? try [clear list/extra] + --assert error? try [reverse list/extra] + --assert error? try [random list/extra] + --assert list/extra/1 = 'bar + --assert list/extra/2 = 'qux + --assert 2 = length? list/extra +===end-group=== + ===start-group=== "generated" --test-- "generated-1-+" --assert -$46256738.73641 + -$382909867.62517 == -$429166606.36158 --test-- "generated-2-+" --assert -$861608569.91149 + -$385303837.42661 == -$1246912407.33810 From b3510601fb654d1be52306aa43521db36708fb31 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 1 Apr 2020 16:53:54 +0200 Subject: [PATCH 1268/3432] FEAT: encodes the currency code as an index instead of a string in compiler. Customs codes can be specified in the Red script header: Red [Currencies: [XYZ ...]] --- compiler.r | 35 +++++++++++++++++++++++++++++++---- runtime/datatypes/money.reds | 13 ++++--------- runtime/redbin.reds | 9 +++------ system/utils/r2-forward.r | 9 +++++++++ utils/extractor.r | 12 ++++++++++++ utils/redbin.r | 3 +-- 6 files changed, 60 insertions(+), 21 deletions(-) diff --git a/compiler.r b/compiler.r index 47b500aa6e..08c1d9df9a 100644 --- a/compiler.r +++ b/compiler.r @@ -36,6 +36,7 @@ red: context [ rebol-gctx: bind? 'rebol expr-stack: make block! 8 current-call: none + currencies: none ;-- extra user-defined currency codes from script's header unless value? 'Red [red: none] ;-- for %preprocessor to load @@ -251,6 +252,15 @@ red: context [ out ] + to-currency-code: func [code [string!] /local pos][ + code: to word! code + case [ + pos: find extracts/currencies code [index? pos] + all [currencies pos: find currencies code][(index? pos) + length? extracts/currencies] + 'else [0] + ] + ] + any-function?: func [value [word!]][ find [native! action! op! function! routine!] value ] @@ -1758,7 +1768,7 @@ red: context [ emit 'money/push value: to string! next value emit pick [true false] value/4 = #"-" - emit any [all [value/1 = #"." 'null] copy/part value 3] + emit to-currency-code copy/part value 3 emit to-nibbles copy skip value 4 ] find [refinement! issue!] type?/word :value [ @@ -4821,8 +4831,19 @@ red: context [ src ] + process-currencies: func [header [block!] /local spec c][ + if block? spec: select header quote Currencies: [ + foreach c spec [ + if any [not word? c 3 <> length? form c][ + throw-error ["invalid header currencies field:" spec] + ] + ] + currencies: copy spec + ] + ] + process-config: func [header [block!] /local spec][ - if spec: select header first [config:][ + if spec: select header quote config: [ do bind spec job if job/command-line [do bind job/command-line job] ;-- ensures cmd-line options have priority ] @@ -4860,6 +4881,11 @@ red: context [ ] ] + process-fields: func [header [block!] src [block!]][ + process-needs header src + process-currencies header + ] + clean-up: does [ clear include-stk clear included-list @@ -4897,7 +4923,8 @@ red: context [ container-obj?: script-path: script-file: - main-path: none + main-path: + currencies: none ] compile: func [ @@ -4917,7 +4944,7 @@ red: context [ process-config src/1 preprocessor/expand/clean src job if job/show = 'expanded [probe next src] - process-needs src/1 next src + process-fields src/1 next src extracts/init job if job/libRedRT? [libRedRT/init] if file? file [system-dialect/collect-resources src/1 resources file] diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index e29e4f521b..cb30b94310 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -509,7 +509,7 @@ money: context [ make-in: func [ slot [red-value!] sign [logic!] ;-- yes: negative - currency [c-string!] ;-- null if generic currency, otherwise 3 bytes + currency [integer!] ;-- 0 if generic currency, otherwise < 255 amount [byte-ptr!] ;-- always SIZE_BYTES bytes return: [red-money!] /local @@ -520,20 +520,15 @@ money: context [ money: as red-money! slot money/header: TYPE_MONEY - set-sign money as integer! sign - set-amount money amount - - ;@@ TBD: assuming currency code is valid - index: either null? currency [0][get-index symbol/make currency] - set-currency money index - + set-amount money amount + set-currency money currency money ] push: func [ sign [logic!] ;-- yes: negative - currency [c-string!] ;-- null if generic currency, otherwise 3-letter string + currency [integer!] ;-- 0 if generic currency, otherwise < 255 amount [c-string!] ;-- always SIZE_BYTES bytes return: [red-money!] ][ diff --git a/runtime/redbin.reds b/runtime/redbin.reds index 13918f86c1..8e985534a1 100644 --- a/runtime/redbin.reds +++ b/runtime/redbin.reds @@ -333,17 +333,14 @@ redbin: context [ return: [int-ptr!] /local slot [red-money!] - cur p [byte-ptr!] + cur [byte-ptr!] neg? [logic!] ][ neg?: data/1 and 0Eh <> 0 cur: as byte-ptr! data + 1 - if cur/1 = #"." [cur: null] - p: as byte-ptr! data + 2 - p: p + 1 ;-- skip padding byte - slot: money/make-in ALLOC_TAIL(parent) neg? as-c-string cur p + slot: money/make-in ALLOC_TAIL(parent) neg? as-integer cur/1 cur + 1 if nl? [slot/header: slot/header or flag-new-line] - data + 5 + data + 4 ] decode-value: func [ diff --git a/system/utils/r2-forward.r b/system/utils/r2-forward.r index 9aef63e23a..a9159bf1e7 100644 --- a/system/utils/r2-forward.r +++ b/system/utils/r2-forward.r @@ -148,4 +148,13 @@ has: func [ body [block!] ][ func head insert copy locals /local body +] + +unless value? 'quote [ + quote: func [ + "Returns the value passed to it without evaluation." + :value [any-type!] + ][ + get/any 'value + ] ] \ No newline at end of file diff --git a/utils/extractor.r b/utils/extractor.r index f1981d4225..8dbe94d27c 100644 --- a/utils/extractor.r +++ b/utils/extractor.r @@ -20,6 +20,14 @@ context [ definitions: make block! 100 data: load-cache %runtime/macros.reds + currencies: load-cache %environment/system.red + extras: make block! 1 + + extract-codes: has [codes][ + codes: third find (third find currencies/5 quote locale:) quote currencies: + currencies: copy codes/2 + ] + extract-defs: func [type [word!] /local list index][ list: select data type @@ -40,6 +48,8 @@ context [ extract-defs 'actions! extract-defs 'natives! + extract-codes + data: none set 'typeset! block! ;-- fake a convenient definition @@ -47,5 +57,7 @@ context [ init: func [job [object!] /local src] [ src: preprocessor/expand load-cache %environment/scalars.red job scalars: make object! copy skip src 2 + + clear extras ] ] \ No newline at end of file diff --git a/utils/redbin.r b/utils/redbin.r index 61d4b0e772..e971bfc20b 100644 --- a/utils/redbin.r +++ b/utils/redbin.r @@ -187,8 +187,7 @@ context [ if nl? [header: header or nl-flag] emit header repend buffer [ - append copy/part value 3 null ;-- currency code ("..." if none) - #{00} ;-- padding + either value/1 = #"." [null][to-char to-currency-code copy/part value 3] to binary! to-nibbles copy/part skip value 4 22 ;-- nibbles array ] ] From 34f56eaa11a9d8c9021742c68fc55905dd55cce2 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 1 Apr 2020 18:18:02 +0200 Subject: [PATCH 1269/3432] FIX: some money! value are not properly encoded by the compile-time lexer. --- lexer.r | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lexer.r b/lexer.r index 1703612744..e992077511 100644 --- a/lexer.r +++ b/lexer.r @@ -832,11 +832,12 @@ lexer: context [ ] load-money: func [s [string!] e [string!] neg? [logic!] /local cur dec pos][ - if s/4 = #"$" [ + if all [s/1 <> #"$" s/4 = #"$"][ cur: uppercase copy/part s 3 s: skip s 3 ] s: copy/part next s e + remove-each c s [c = #"'"] dec: either pos: find s dot [remove pos length? pos][0] insert/dup tail s #"0" 5 - dec insert/dup s #"0" 22 - length? s From c736a5bac368b2bffa5f9d636f249813de04b371 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 1 Apr 2020 18:18:19 +0200 Subject: [PATCH 1270/3432] TESTS: activates money-test.red --- tests/source/units/all-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/source/units/all-tests.txt b/tests/source/units/all-tests.txt index 75c68c9ccb..24d7926dc6 100644 --- a/tests/source/units/all-tests.txt +++ b/tests/source/units/all-tests.txt @@ -30,6 +30,7 @@ strict-equal-test.red object-test.red integer-test.red float-test.red +money-test.red same-test.red words-of-test.red unset-test.red From dcc8459f8830fadc8e6d423bef99c284fe732f97 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 1 Apr 2020 18:08:41 +0200 Subject: [PATCH 1271/3432] FEAT: preliminary work on pseudo-random MONEY! value generator. --- runtime/datatypes/money.reds | 38 +++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 386dd18864..fa3d31d930 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1500,9 +1500,45 @@ money: context [ secure? [logic!] only? [logic!] return: [red-money!] + /local + roll [subroutine!] + amount [byte-ptr!] + count index [integer!] + digit new [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/random"]] - --NOT_IMPLEMENTED-- + + roll: [ + while [not zero? count][ + set-digit amount index _random/rand % 10 + count: count - 1 + index: index + 1 + ] + ] + + either seed? [ + _random/srand money/amount1 xor money/amount2 xor money/amount3 + money/header: TYPE_UNSET + ][ + amount: get-amount money + count: count-digits amount + + amount: amount + (SIZE_DIGITS - count >> 1) + index: 1 + (count and 1) + + while [not zero? count][ + digit: get-digit amount index + new: _random/rand % (1 + digit) + + set-digit amount index new + + count: count - 1 + index: index + 1 + + unless new = digit [roll break] + ] + ] + money ] From 164999dfe6ffd8593f5b6ed1e004a0a496cbf0ac Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 2 Apr 2020 18:31:47 +0200 Subject: [PATCH 1272/3432] FIX: improves currencies object protection code. --- environment/system.red | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/environment/system.red b/environment/system.red index 6d99042ba8..7cb3db8b19 100644 --- a/environment/system.red +++ b/environment/system.red @@ -327,11 +327,11 @@ system: context [ ;-- User-provided currencies extra: [] - on-change*: func [word old new][ - set-quiet word old + on-change*: func [word old new][ + set-quiet in self word old cause-error 'script 'protected [] ] - on-deep-change*: func [owner word target action new index part][ + on-deep-change*: func [owner word target action new index part][ if any [ word <> 'extra not find [append appended] action From 24dd8b855427d5e0987c79fce69d703b950d4bd8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 2 Apr 2020 20:25:40 +0200 Subject: [PATCH 1273/3432] FIX: negative sign Redbin money values not decoded properly. --- runtime/redbin.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/redbin.reds b/runtime/redbin.reds index 8e985534a1..ccf03822aa 100644 --- a/runtime/redbin.reds +++ b/runtime/redbin.reds @@ -336,7 +336,7 @@ redbin: context [ cur [byte-ptr!] neg? [logic!] ][ - neg?: data/1 and 0Eh <> 0 + neg?: data/1 and 4000h <> 0 cur: as byte-ptr! data + 1 slot: money/make-in ALLOC_TAIL(parent) neg? as-integer cur/1 cur + 1 if nl? [slot/header: slot/header or flag-new-line] From d0d5b40cf8d2493c7309c4d06189eae907ac80ae Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Thu, 2 Apr 2020 20:58:14 +0200 Subject: [PATCH 1274/3432] FIX: oversized decimals in money literals not loaded properly by compiler's lexer. --- lexer.r | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lexer.r b/lexer.r index e992077511..0c9a5fee0b 100644 --- a/lexer.r +++ b/lexer.r @@ -454,7 +454,7 @@ lexer: context [ money-rule: [ (neg?: no) opt [#"-" (neg?: yes) | #"+"] - s: opt [3 alpha] #"$" digit any [digit | #"'" digit] opt [[dot | comma] 1 5 digit] e: + s: opt [3 alpha] #"$" digit any [digit | #"'" digit] opt [[dot | comma] some digit] e: ] block-rule: [#"[" (stack/allocate block! 10) any-value #"]" (value: stack/pop block!)] @@ -838,7 +838,11 @@ lexer: context [ ] s: copy/part next s e remove-each c s [c = #"'"] - dec: either pos: find s dot [remove pos length? pos][0] + dec: either pos: find s dot [ + remove pos + if 5 < length? pos [clear skip pos 5] + length? pos + ][0] insert/dup tail s #"0" 5 - dec insert/dup s #"0" 22 - length? s insert s pick "-+" neg? From 82ca26336859c2153cf8650b4c9797421b7b5512 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Thu, 2 Apr 2020 16:56:52 +0200 Subject: [PATCH 1275/3432] FEAT: improve pseudo-random generator. --- runtime/datatypes/money.reds | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index fa3d31d930..c71f5fdbb5 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -1510,14 +1510,14 @@ money: context [ roll: [ while [not zero? count][ - set-digit amount index _random/rand % 10 + set-digit amount index dice count: count - 1 index: index + 1 ] ] either seed? [ - _random/srand money/amount1 xor money/amount2 xor money/amount3 + _random/srand money/amount1 xor money/amount2 xor money/amount3 xor get-sign money money/header: TYPE_UNSET ][ amount: get-amount money @@ -1530,12 +1530,14 @@ money: context [ digit: get-digit amount index new: _random/rand % (1 + digit) + if all [new = digit (_random/rand % 1000) <> (_random/rand % 1000)][continue] + set-digit amount index new count: count - 1 index: index + 1 - unless new = digit [roll break] + unless new = digit [roll] ] ] From b21c58aa0b1224cf0af4db1973391f8e9991d45c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 3 Apr 2020 11:26:17 +0200 Subject: [PATCH 1276/3432] FEAT: more robust float comparison/conversion. --- runtime/datatypes/float.reds | 6 +++++- runtime/datatypes/money.reds | 36 ++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/runtime/datatypes/float.reds b/runtime/datatypes/float.reds index 598effa915..9753a72fa4 100644 --- a/runtime/datatypes/float.reds +++ b/runtime/datatypes/float.reds @@ -730,7 +730,11 @@ float: context [ left: value1/value switch TYPE_OF(value2) [ - TYPE_MONEY [return money/compare money/from-float left as red-money! value2 op] + TYPE_MONEY [ + if money/float-underflow? left [return -1] + if money/float-overflow? left [return 1] + return money/compare money/from-float left as red-money! value2 op + ] TYPE_CHAR TYPE_INTEGER [ int: as red-integer! value2 diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index c71f5fdbb5..0adcc62398 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -641,7 +641,7 @@ money: context [ ;-- Conversion -- - overflow?: func [ + integer-overflow?: func [ money [red-money!] return: [logic!] /local @@ -667,7 +667,7 @@ money: context [ sign integer index [integer!] start power digit [integer!] ][ - if overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] + if integer-overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] sign: sign? money if zero? sign [return 0] @@ -759,36 +759,46 @@ money: context [ float * as float! sign ] + float-overflow?: func [ + flt [float!] + return: [logic!] + ][ + (float/abs flt) >= 1e17 + ] + + float-underflow?: func [ + flt [float!] + return: [logic!] + ][ + flt: float/abs flt + all [flt > 0.0 flt < 1e-5] + ] + from-float: func [ flt [float!] return: [red-money!] /local - money [red-money!] formed [c-string!] start end [byte-ptr!] point [byte-ptr!] sign [logic!] ][ - formed: dtoa/form-float flt SIZE_DIGITS yes + if any [float-underflow? flt float-overflow? flt][MONEY_OVERFLOW] - if (length? formed) > 19 [MONEY_OVERFLOW] ;-- e-notation for exponents larger than 16 + formed: dtoa/form-float flt SIZE_DIGITS yes point: as byte-ptr! formed until [point: point + 1 point/value = #"."] - if point/2 = #"#" [ ;-- 1.#NaN, 1.#INF, -1.#INF + if point/2 = #"#" [ ;-- 1.#NaN fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY float/box flt] ] - if point/3 = #"e" [MONEY_OVERFLOW] ;-- e-notation for exponents smaller than -7 - sign: formed/1 = #"-" start: as byte-ptr! either sign [formed][formed - 1] end: as byte-ptr! formed + length? formed - money: make-at stack/push* sign null start point end - if all [0.0 <> flt zero-money? money][MONEY_OVERFLOW] ;-- underflow on too small float value - money + make-at stack/push* sign null start point end ] to-binary: func [ @@ -1510,7 +1520,7 @@ money: context [ roll: [ while [not zero? count][ - set-digit amount index dice + set-digit amount index _random/rand % 10 count: count - 1 index: index + 1 ] @@ -1600,6 +1610,8 @@ money: context [ ] TYPE_FLOAT [ float: as red-float! value + if float-underflow? float/value [return 1] + if float-overflow? float/value [return -1] value: from-float float/value ] default [RETURN_COMPARE_OTHER] From 31a82d4834f56a8af07583754d1b4a0b6c079d79 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 3 Apr 2020 11:27:01 +0200 Subject: [PATCH 1277/3432] TESTS: a few comparison tests with edge-case float values. --- tests/source/units/money-test.red | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index ca4285fbfc..37145a95d8 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -195,6 +195,11 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [to money! "$.0"] --assert error? try [to money! "$0."] --assert true + --test-- "to-28" + --assert $1 > 1e-6 + --assert $2 < 1e17 + --assert 1e-5 > $0 + --assert 1e17 > $3 ===end-group=== ===start-group=== "make" From c1cefd73f4496a46f81ef5b0181c1a02a7f49c97 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 3 Apr 2020 11:51:41 +0200 Subject: [PATCH 1278/3432] TESTS: add RANDOM tests. --- tests/source/units/money-test.red | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 37145a95d8..5da402f473 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -539,6 +539,24 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [round/half-ceiling min-money] ===end-group=== +===start-group=== "random" + --test-- "random-1" + --assert unset? random/seed RED$92.14 + --test-- "random-2" + loop 100 [--assert $0 == random $0] + --test-- "random-3" + loop 100 [--assert $1 >= random $1] + --test-- "random-4" + loop 100 [--assert -$1 <= random -$1] + --test-- "random-5" + a: average collect [loop 1'000 [keep random $1'000]] + --assert to logic! all [a - 9 <= $500 a + 9 >= $500] + --test-- "random-6" + loop 100 [--assert not-equal? random $1 random $1] + --test-- "random-7" + --assert 'RED = pick random RED$123.456 'code +===end-group=== + ===start-group=== "sort" --test-- "sort-1" block: [9 2.0 $4 5.0 $8 7 $3 6.0 2.0 $1 5] From 081f47145f3f9755357d030fcbb78a5d3c5bb07c Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 3 Apr 2020 16:40:32 +0200 Subject: [PATCH 1279/3432] FEAT: improve code formatting. --- runtime/datatypes/money.reds | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 0adcc62398..d692a8c473 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -667,7 +667,9 @@ money: context [ sign integer index [integer!] start power digit [integer!] ][ - if integer-overflow? money [fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER]] + if integer-overflow? money [ + fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER] + ] sign: sign? money if zero? sign [return 0] @@ -692,10 +694,11 @@ money: context [ int [integer!] return: [red-money!] /local - money [red-money!] - amount [byte-ptr!] - extra index start [integer!] - power digit [integer!] + money [red-money!] + amount [byte-ptr!] + extra [integer!] + index start [integer!] + power digit [integer!] ][ money: zero-out as red-money! stack/push* money/header: TYPE_MONEY @@ -846,7 +849,8 @@ money: context [ int [red-integer!] flt [red-float!] head tail here [red-value!] - currency state [integer!] + state [make-states!] + currency [integer!] type length [integer!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY blk]] @@ -1370,7 +1374,7 @@ money: context [ do-math-op: func [ value1 [red-money!] value2 [red-money!] - op [integer!] + op [math-op!] return: [red-money!] ][ switch op [ @@ -1387,7 +1391,7 @@ money: context [ ] do-math: func [ - op [integer!] + op [math-op!] return: [red-value!] /local value1 value2 [red-money!] @@ -1583,7 +1587,7 @@ money: context [ compare: func [ money [red-money!] value [red-money!] - op [integer!] + op [comparison-op!] return: [integer!] /local integer [red-integer!] From c5b0df4886dc55b8a5b7b25f1226974e38459509 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Fri, 3 Apr 2020 16:41:00 +0200 Subject: [PATCH 1280/3432] TESTS: add an extra MAKE test for base currencies. --- tests/source/units/money-test.red | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 5da402f473..6c6d92683a 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -217,6 +217,8 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-12" --assert "EUR$0.00000" == mold/all make money! 'EUR --test-- "make-13" --assert error? try [make money! 'foo] --test-- "make-14" --assert error? try [make money! [123.45 6789]] + --test-- "make-15" + --assert not error? try [foreach c system/locale/currencies/base [make money! c]] ===end-group=== ===start-group=== "form/mold" From a1d4977a570731bb9c1a483a2b1f12838c6af6ca Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 4 Apr 2020 17:10:58 +0200 Subject: [PATCH 1281/3432] FIX: "+$.1" literal causes runtime lexer to crash. --- runtime/lexer.reds | 1 + tests/source/units/lexer-test.red | 2 ++ 2 files changed, 3 insertions(+) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 7b6645b337..9f9b76f7a6 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1874,6 +1874,7 @@ lexer: context [ assert p/1 = #"$" st: p p: p + 1 + if any [p/1 = #"." p/1 = #","][do-error] ds: null while [p < e][ if any [p/1 = #"." p/1 = #","][ diff --git a/tests/source/units/lexer-test.red b/tests/source/units/lexer-test.red index 5aa9b7d19c..1f6d88df0e 100644 --- a/tests/source/units/lexer-test.red +++ b/tests/source/units/lexer-test.red @@ -557,6 +557,8 @@ Red [ --test-- "tro-116" --assert error? try [transcode/one "1'"] --test-- "tro-117" --assert error? try [transcode/one "1''2"] + --test-- "tro-118" --assert error? try [transcode/one "+$.1"] + ===end-group=== ===start-group=== "transcode/next" From b3efa2a34b53d5112420faff0f6b060aa56b1457 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sat, 4 Apr 2020 18:10:40 +0200 Subject: [PATCH 1282/3432] FIX: truncates integral part of literal money! values at 17 digits. --- lexer.r | 6 ++++-- runtime/lexer.reds | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lexer.r b/lexer.r index 0c9a5fee0b..ae935f5256 100644 --- a/lexer.r +++ b/lexer.r @@ -454,7 +454,8 @@ lexer: context [ money-rule: [ (neg?: no) opt [#"-" (neg?: yes) | #"+"] - s: opt [3 alpha] #"$" digit any [digit | #"'" digit] opt [[dot | comma] some digit] e: + s: opt [3 alpha] #"$" digit any [digit | #"'" digit] opt [[dot | comma] some digit] + e: (type: money!) ] block-rule: [#"[" (stack/allocate block! 10) any-value #"]" (value: stack/pop block!)] @@ -843,7 +844,8 @@ lexer: context [ if 5 < length? pos [clear skip pos 5] length? pos ][0] - insert/dup tail s #"0" 5 - dec + insert/dup tail s #"0" 5 - dec + if 22 < length? s [throw-error] insert/dup s #"0" 22 - length? s insert s pick "-+" neg? insert s any [cur "..."] diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 9f9b76f7a6..ac5097bf50 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1884,6 +1884,7 @@ lexer: context [ ] p: p + 1 ] + if 18 < as-integer e - st [do-error] lex/in-pos: e ;-- reset the input position to delimiter byte if load? [ if null? money/make-at alloc-slot lex neg? cur st ds e [do-error] From cd5724f06afca95740998ef20556cff4cb9bc676 Mon Sep 17 00:00:00 2001 From: semseddin Date: Sun, 5 Apr 2020 00:43:04 +0300 Subject: [PATCH 1283/3432] FIX: missing copy in split function --- environment/functions.red | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/functions.red b/environment/functions.red index e89a76d387..9eb65ea7b5 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -780,7 +780,7 @@ split: function [ series [any-string!] dlm [string! char! bitset!] /local s ][ num: either string? dlm [length? dlm][1] - parse series [collect any [copy s [to [dlm | end]] keep (s) num skip [end keep ("") | none] ]] + parse series [collect any [copy s [to [dlm | end]] keep (s) num skip [end keep (copy "") | none] ]] ] dirize: func [ From b8e192aa5eeb95aa2bc390cbd303028b2f2dc7f0 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 5 Apr 2020 21:46:47 +0200 Subject: [PATCH 1284/3432] FEAT: ensures that newly added currency codes at run-time are uppercased. --- environment/routines.red | 16 +++++++++++++++- environment/system.red | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/environment/routines.red b/environment/routines.red index 799cb97ee8..c7edf0a306 100644 --- a/environment/routines.red +++ b/environment/routines.red @@ -18,7 +18,7 @@ quit-return: routine [ ] set-quiet: routine [ - "Set an object's field to a value without triggering object's events" + "Set an object's field to a value without triggering eventual object's events" word [any-type!] value [any-type!] /local @@ -33,6 +33,20 @@ set-quiet: routine [ _context/set-in w stack/arguments + 1 TO_CTX(node) no ] +set-slot-quiet: routine [ + "Set a value in series without triggering eventual owner's events" + series [any-type!] + value [any-type!] + /local + blk [red-block!] + type [integer!] +][ + type: TYPE_OF(series) + unless ANY_BLOCK_STRICT?(type) [ERR_EXPECT_ARGUMENT(TYPE_BLOCK 0)] + blk: as red-block! series + unless block/rs-tail? blk [copy-cell value block/rs-head blk] +] + ;-- Following definitions are used to create op! corresponding operators shift-right: routine ["Shift bits to the right" data [integer!] bits [integer!]][natives/shift* no -1 -1] shift-left: routine ["Shift bits to the left" data [integer!] bits [integer!]][natives/shift* no 1 -1] diff --git a/environment/system.red b/environment/system.red index 7cb3db8b19..b8315c3e09 100644 --- a/environment/system.red +++ b/environment/system.red @@ -346,6 +346,8 @@ system: context [ ] ] ][cause-error 'script 'protected []] + + if action = 'appended [set-slot-quiet back tail extra to word! uppercase form new] ] ] ] From 4471963f38ce62d50e7ab144dbf9acf41d86911f Mon Sep 17 00:00:00 2001 From: semseddin Date: Mon, 6 Apr 2020 00:00:07 +0300 Subject: [PATCH 1285/3432] TESTS: Add test for PR #4381 split function --- tests/source/environment/functions-test.red | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/source/environment/functions-test.red b/tests/source/environment/functions-test.red index b43e5d3db3..8828e76790 100644 --- a/tests/source/environment/functions-test.red +++ b/tests/source/environment/functions-test.red @@ -390,6 +390,7 @@ Red [ --assert ["a" "b" "c"] = split "a-b-c" "-" --assert ["a" "c"] = split "a-b-c" "-b-" --assert ["a-b-c"] = split "a-b-c" "x" + --assert false = do compose [same? (second split "a," ",") (second split "b," ",")] ;PR #4381 missing copy in split function ===end-group=== ===start-group=== "dirize tests" From c4194a53e268e22125546cb431adc8c85a4d6ba9 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 6 Apr 2020 13:58:35 +0200 Subject: [PATCH 1286/3432] FEAT: change semantics for strict comparison. Currency codes must be either strictly equivalent or completely absent. --- runtime/datatypes/money.reds | 17 ++++++++--------- runtime/natives.reds | 3 +++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index d692a8c473..fc68eff684 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -210,6 +210,7 @@ money: context [ same-currencies?: func [ value1 [red-money!] value2 [red-money!] + strict? [logic!] ;-- YES: forbid generic currencies return: [logic!] /local currency1 [integer!] @@ -217,10 +218,9 @@ money: context [ ][ currency1: get-currency value1 currency2: get-currency value2 - + any [ - zero? currency1 ;-- 0: generic currency - zero? currency2 + all [not strict? any [zero? currency1 zero? currency2]] currency1 = currency2 ] ] @@ -1444,7 +1444,7 @@ money: context [ ] ] - unless same-currencies? value1 value2 [fire [TO_ERROR(script wrong-denom) value1 value2]] + unless same-currencies? value1 value2 no [fire [TO_ERROR(script wrong-denom) value1 value2]] currency: get-currency value2 ;-- preserve specific currency if zero? currency [currency: get-currency value1] @@ -1592,19 +1592,18 @@ money: context [ /local integer [red-integer!] float [red-float!] + strict? [logic!] ][ #if debug? = yes [if verbose > 0 [print-line "money/compare"]] - if all [ - TYPE_OF(money) <> TYPE_OF(value) - any [op = COMP_FIND op = COMP_SAME op = COMP_STRICT_EQUAL] - ][ + strict?: any [op = COMP_SAME op = COMP_STRICT_EQUAL] + if all [TYPE_OF(money) <> TYPE_OF(value) any [op = COMP_FIND strict?]][ return 1 ] switch TYPE_OF(value) [ TYPE_MONEY [ - unless same-currencies? money as red-money! value [ + unless same-currencies? money as red-money! value strict? [ fire [TO_ERROR(script wrong-denom) money as red-money! value] ] ] diff --git a/runtime/natives.reds b/runtime/natives.reds index 387c1f4aa0..e618c5fe70 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -813,6 +813,9 @@ natives: context [ ][ res: true ] + type = TYPE_MONEY [ + res: zero? money/compare as red-money! arg1 as red-money! arg2 COMP_SAME + ] true [ res: all [ arg1/data1 = arg2/data1 From ae6acc36ec435e06aea523a5ef4c90d0eb1bcf6d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 6 Apr 2020 13:58:57 +0200 Subject: [PATCH 1287/3432] TESTS: strict comparison tests. --- tests/source/units/money-test.red | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 6c6d92683a..fcf382eeb9 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -73,6 +73,9 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "strict-equal-4" --assert strict-equal? -$0 +$0 --test-- "strict-equal-5" --assert strict-equal? -$1 -$1 --test-- "strict-equal-6" --assert strict-equal? +$1 +$1 + --test-- "strict-equal-7" --assert strict-equal? +USD$1 +USD$1 + --test-- "strict-equal-8" --assert error? try [strict-equal? +$1 +USD$1] + --test-- "strict-equal-9" --assert error? try [strict-equal? +EUR$1 +$1] ===end-group=== ===start-group=== "same?" @@ -82,6 +85,9 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "same-4" --assert same? -$0 +$0 --test-- "same-5" --assert same? -$1 -$1 --test-- "same-6" --assert same? +$1 +$1 + --test-- "same-7" --assert same? +USD$1 +USD$1 + --test-- "same-8" --assert error? try [same? +USD$1 +$1] + --test-- "same-9" --assert error? try [same? +$1 +USD$1] ===end-group=== ===start-group=== "lesser?" @@ -250,7 +256,7 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "currencies-5" --assert -2.0 * $1 == -$2 --test-- "currencies-6" --assert error? try [USD$1 + EUR$1] --test-- "currencies-7" --assert error? try [EUR$2 - USD$2] - --test-- "currencies-8" --assert USD$1 == $1 + --test-- "currencies-8" --assert USD$1 == USD$1 --test-- "currencies-9" --assert -USD$2 == -USD$2 --test-- "currencies-10" --assert error? try [EUR$123 <> USD$123] ===end-group=== @@ -407,11 +413,11 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert -$3.0 == round/to/ceiling -$4.5 3 --assert -$6.0 == round/to -$4.5 3.0 --assert +$6.0 == round/to +$4.5 3 - --assert $4.998 == round/to EUR$5 0.357 + --assert EUR$4.998 == round/to EUR$5 0.357 --assert $3.8 == round/to $3.75 0.1 --assert $1.375 == round/to $1.333 -$0.125 --assert $1.33 == round/to $1.333 0.01 - --assert -$3.0 == round/to/floor -USD$2.4 $1.0 + --assert -USD$3.0 == round/to/floor -USD$2.4 $1.0 --assert -$2.0 == round/to/ceiling -$2.4 1.0 --assert -$4.0 == round/to/floor -$2.4 2.0 --assert -$1.0 == round/to -$0.50 1 From 419680f06543ed1f34677ecee82390015a386581 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Mon, 6 Apr 2020 13:59:08 +0200 Subject: [PATCH 1288/3432] FEAT: improve code formatting. --- runtime/datatypes/money.reds | 101 +++++++++++++++++------------------ 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index fc68eff684..9070927866 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -14,7 +14,7 @@ money: context [ verbose: 0 ;-- Base -- - + #enum sizes! [ SIZE_BYTES: 11 ;-- total number of bytes used to store amount SIZE_SCALE: 05 ;-- total number of digits (nibbles) used to store scale (fractional part) @@ -187,7 +187,7 @@ money: context [ either here < tail [index][-1] ] - + get-currency-code: func [ index [integer!] return: [red-word!] @@ -361,7 +361,7 @@ money: context [ ][ assert positive? index assert all [value >= 0 value <= 9] - + bit: index and 1 byte: index >> 1 + bit offset: either as logic! bit [4][0] @@ -395,13 +395,13 @@ money: context [ buffer2 [byte-ptr!] high2? [logic!] count2 [integer!] return: [integer!] /local - delta index1 index2 end digit1 digit2 [integer!] + delta index1 index2 count digit1 digit2 [integer!] ][ delta: integer/abs count1 - count2 switch integer/sign? count1 - count2 [ - -1 [index1: 1 - delta index2: 1 end: count2] - 00 [index1: 1 index2: 1 end: count1] - +1 [index2: 1 - delta index1: 1 end: count1] + -1 [index1: 1 - delta index2: 1 count: count2] + 00 [index1: 1 index2: 1 count: count1] + +1 [index2: 1 - delta index1: 1 count: count1] default [0] ] @@ -414,9 +414,9 @@ money: context [ index1: index1 + 1 index2: index2 + 1 - end: end - 1 + count: count - 1 - any [digit1 <> digit2 zero? end] + any [digit1 <> digit2 zero? count] ] digit1 - digit2 @@ -452,7 +452,7 @@ money: context [ make-at: func [ slot [red-value!] - sign [logic!] ;-- yes: negative + sign [logic!] ;-- YES: negative currency [byte-ptr!] ;-- can be null if currency code is not present start [byte-ptr!] ;-- $ sign point [byte-ptr!] ;-- can be null if fractional part is not present @@ -462,7 +462,6 @@ money: context [ convert [subroutine!] money [red-money!] amount limit here [byte-ptr!] - str [c-string!] index stop step [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/make-at"]] @@ -519,26 +518,27 @@ money: context [ make-in: func [ slot [red-value!] - sign [logic!] ;-- yes: negative + sign [logic!] ;-- YES: negative currency [integer!] ;-- 0 if generic currency, otherwise < 255 amount [byte-ptr!] ;-- always SIZE_BYTES bytes return: [red-money!] /local money [red-money!] - index [integer!] ][ #if debug? = yes [if verbose > 0 [print-line "money/make-in"]] money: as red-money! slot money/header: TYPE_MONEY + set-sign money as integer! sign - set-amount money amount set-currency money currency + set-amount money amount + money ] push: func [ - sign [logic!] ;-- yes: negative + sign [logic!] ;-- YES: negative currency [integer!] ;-- 0 if generic currency, otherwise < 255 amount [c-string!] ;-- always SIZE_BYTES bytes return: [red-money!] @@ -551,12 +551,12 @@ money: context [ money [red-money!] buffer [red-string!] part [integer!] - all? [logic!] ;-- yes: display all SIZE_SCALE fractional digits - group? [logic!] ;-- yes: decorate amount with thousand's separators + all? [logic!] ;-- YES: display all SIZE_SCALE fractional digits + group? [logic!] ;-- YES: decorate amount with thousand's separators return: [integer!] /local fill [subroutine!] - after [red-integer!] + scale [red-integer!] amount [byte-ptr!] sign count [integer!] index times [integer!] @@ -596,7 +596,7 @@ money: context [ index: index + 1 part: part - 1 - ] + ] ] ;-- integral part @@ -608,8 +608,8 @@ money: context [ ] ;-- fractional part - after: as red-integer! #get system/options/money-digits - times: either TYPE_OF(after) = TYPE_INTEGER [after/value][2] ;-- revert to default value + scale: as red-integer! #get system/options/money-digits + times: either TYPE_OF(scale) = TYPE_INTEGER [scale/value][2] ;-- revert to default value if any [all? times > SIZE_SCALE][times: SIZE_SCALE] if positive? times [ string/concatenate-literal buffer "." @@ -670,10 +670,10 @@ money: context [ if integer-overflow? money [ fire [TO_ERROR(script type-limit) datatype/push TYPE_INTEGER] ] - + sign: sign? money if zero? sign [return 0] - + amount: get-amount money integer: 0 index: SIZE_INTEGRAL @@ -730,6 +730,21 @@ money: context [ money ] + float-overflow?: func [ + flt [float!] + return: [logic!] + ][ + (float/abs flt) >= 1e17 + ] + + float-underflow?: func [ + flt [float!] + return: [logic!] + ][ + flt: float/abs flt + all [flt > 0.0 flt < 1e-5] + ] + to-float: func [ money [red-money!] return: [float!] @@ -743,7 +758,7 @@ money: context [ sign: sign? money if zero? sign [return 0.0] - + buffer: string/make-at stack/push* SIZE_DIGITS + 6 Latin1 ;-- max number of digits and -CCC$. form-money money buffer 0 yes no ;-- take all fractional digits into account @@ -762,21 +777,6 @@ money: context [ float * as float! sign ] - float-overflow?: func [ - flt [float!] - return: [logic!] - ][ - (float/abs flt) >= 1e17 - ] - - float-underflow?: func [ - flt [float!] - return: [logic!] - ][ - flt: float/abs flt - all [flt > 0.0 flt < 1e-5] - ] - from-float: func [ flt [float!] return: [red-money!] @@ -947,12 +947,11 @@ money: context [ tail head here [byte-ptr!] currency digits [byte-ptr!] start point [byte-ptr!] - char [byte!] - sign [logic!] + sign? [logic!] ][ bail: [fire [TO_ERROR(script bad-make-arg) datatype/push TYPE_MONEY str]] make: [ - money: make-at stack/push* sign currency start point tail + money: make-at stack/push* sign? currency start point tail if null? money [bail] ;-- invalid currency code return money ] @@ -966,9 +965,9 @@ money: context [ here: head ;-- sign - sign: no + sign?: no switch here/value [ - #"-" [here: here + 1 sign: yes] + #"-" [here: here + 1 sign?: yes] #"+" [here: here + 1] default [0] ] @@ -1147,7 +1146,7 @@ money: context [ sign1: sign? value1 sign2: sign? value2 - DISPATCH_SIGNS [ + DISPATCH_SIGNS [ SIGN_00 SIGN_0- SIGN_0+ [return negate-money value2] @@ -1174,7 +1173,7 @@ money: context [ index: SIZE_DIGITS borrow: 0 - + loop index [ digit1: get-digit amount1 index digit2: get-digit amount2 index @@ -1267,8 +1266,8 @@ money: context [ divide-money: func [ ;-- shift-and-subtract algorithm value1 [red-money!] value2 [red-money!] - remainder? [logic!] ;-- yes: calculate remainder instead - only? [logic!] ;-- yes: don't approximate fractional part + remainder? [logic!] ;-- YES: calculate remainder instead + only? [logic!] ;-- YES: don't approximate fractional part return: [red-money!] /local shift increment subtract [subroutine!] @@ -1406,7 +1405,7 @@ money: context [ type1: TYPE_OF(value1) type2: TYPE_OF(value2) - + if any [ all [op = OP_MUL type1 = TYPE_MONEY type2 = TYPE_MONEY] all [any [op = OP_DIV op = OP_REM] type1 <> TYPE_MONEY type2 = TYPE_MONEY] @@ -1428,7 +1427,7 @@ money: context [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(value1)] ] ] - + switch type2 [ TYPE_MONEY [0] TYPE_INTEGER [ @@ -1583,7 +1582,7 @@ money: context [ #if debug? = yes [if verbose > 0 [print-line "money/mold"]] form-money money buffer part all? no ] - + compare: func [ money [red-money!] value [red-money!] From 3395433447a6eafd0caad509d7f85c84ed9bfc9c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 6 Apr 2020 15:20:11 +0200 Subject: [PATCH 1289/3432] FIX: regression on loading money! values with decimals. --- runtime/lexer.reds | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ac5097bf50..bae0906e2f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1884,11 +1884,9 @@ lexer: context [ ] p: p + 1 ] - if 18 < as-integer e - st [do-error] + if 18 < as-integer p - st [do-error] lex/in-pos: e ;-- reset the input position to delimiter byte - if load? [ - if null? money/make-at alloc-slot lex neg? cur st ds e [do-error] - ] + if all [load? null? money/make-at alloc-slot lex neg? cur st ds e][do-error] ] load-tag: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!]][ From b197fb14c3d91f6d9de49f7372f8b4e224ef293d Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 6 Apr 2020 15:29:45 +0200 Subject: [PATCH 1290/3432] FIX: loading valid money values with quotes in run-time lexer results in an error. --- runtime/lexer.reds | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index bae0906e2f..ca0a71d797 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1860,6 +1860,7 @@ lexer: context [ /local do-error [subroutine!] cur p st ds [byte-ptr!] + quotes [integer!] neg? [logic!] ][ do-error: [throw-error lex s e TYPE_MONEY] @@ -1876,15 +1877,17 @@ lexer: context [ p: p + 1 if any [p/1 = #"." p/1 = #","][do-error] ds: null + quotes: 0 while [p < e][ if any [p/1 = #"." p/1 = #","][ ds: p if ds + 1 = e [do-error] break ] + if p/1 = #"'" [quotes: quotes + 1] p: p + 1 ] - if 18 < as-integer p - st [do-error] + if 18 + quotes < as-integer p - st [do-error] lex/in-pos: e ;-- reset the input position to delimiter byte if all [load? null? money/make-at alloc-slot lex neg? cur st ds e][do-error] ] From 600afe9c78947cf49e0d10992999868738a71f1a Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 6 Apr 2020 17:48:45 +0200 Subject: [PATCH 1291/3432] FEAT: adds support for `Currencies:` field in Red scripts run by DO. --- environment/functions.red | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/environment/functions.red b/environment/functions.red index 6160552b97..823aeeaaf4 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -876,7 +876,7 @@ split-path: func [ reduce [dir pos] ] -do-file: func ["Internal Use Only" file [file! url!] /local saved code new-path src][ +do-file: function ["Internal Use Only" file [file! url!]][ saved: system/options/path unless src: find/case read file "Red" [ cause-error 'syntax 'no-header reduce [file] @@ -887,6 +887,13 @@ do-file: func ["Internal Use Only" file [file! url!] /local saved code new-path new-path: first split-path clean-path file change-dir new-path ] + if all [ + code/1 = 'Red + block? header: code/2 + list: select header 'currencies + ][ + foreach c list [append system/locale/currencies/extra c] + ] set/any 'code try/all code if file? file [change-dir saved] if error? :code [do :code] ;-- rethrow the error From 07abe089ba9d148f12bde5993f84c9ba97ca81fd Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 7 Apr 2020 14:08:30 +0200 Subject: [PATCH 1292/3432] FIX: more stricter thousand's separators. --- runtime/datatypes/money.reds | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index 9070927866..c2707f854b 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -983,16 +983,28 @@ money: context [ start: here - as integer! here/value <> #"$" here: start + 1 - if dot? [bail] ;-- forbid leading decimal separator + if any [dot? here/value = #"'"][bail] ;-- forbid leading separator ;-- leading zeroes - until [here: here + 1 any [here = tail here/value <> #"0"]] + until [ + here: here + 1 + if here/value = #"'" [ + if all [here + 1 < tail here/2 = #"'"][bail] + continue + ] + any [here = tail here/value <> #"0"] + ] + if any [here = tail dot?][here: here - 1] digits: here ;-- integral part with optional thousands separators until [ - if here/value = #"'" [here: here + 1 continue] + if here/value = #"'" [ + if all [here + 1 < tail here/2 = #"'"][bail] + here: here + 1 + continue + ] unless digit? [bail] here: here + 1 any [end? dot?] From 9ecc647288664d8a7c96d76fd21a4ebfec44c716 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 7 Apr 2020 14:09:11 +0200 Subject: [PATCH 1293/3432] TESTS: add more tests. --- tests/source/units/money-test.red | 68 ++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index fcf382eeb9..2061dc6215 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -185,6 +185,7 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "to-24" --assert error? try [to money! "CCC$123"] --test-- "to-25" --assert error? try [to money! "123$456"] --test-- "to-26" --assert error? try [to money! "EUR123"] + --test-- "to-26" --assert error? try [to money! "EUR123"] --test-- "to-27" --assert error? try [to money! "$"] --assert error? try [to money! "$."] @@ -200,12 +201,22 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [to money! "0,"] --assert error? try [to money! "$.0"] --assert error? try [to money! "$0."] - --assert true - --test-- "to-28" + --assert error? try [to money! "$'1"] + --assert error? try [to money! "$1'"] + --assert error? try [to money! "$1''2"] + --assert error? try [to money! "$1'.2"] + --assert error? try [to money! "$1',2"] + --assert error? try [to money! "$1234.45'678"] + --test-- "to-28" ;-- implicit conversion from float to money --assert $1 > 1e-6 --assert $2 < 1e17 --assert 1e-5 > $0 --assert 1e17 > $3 + --test-- "to-29" + --assert $1234 == to money! "$1'2'3'4" + --assert $1234 == to money! "$1'234" + --assert $1234.56789 == to money! "$1'234.56789" + --assert $1234.56789 == to money! "$000'00'0'1234.56789" ===end-group=== ===start-group=== "make" @@ -596,30 +607,39 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "transcode-money-1" --assert money? load "$123" --test-- "transcode-money-2" --assert money? first load "$123 $456" --test-- "transcode-money-3" --assert money? last load "$123 -USD$456" - --test-- "transcode-money-4" --assert money! == transcode/prescan "+EUR$123.456 1 2 3" + --test-- "transcode-money-4" --assert money! == transcode/scan "+EUR$123.456 1 2 3" --test-- "transcode-money-5" --assert "AED$123.45678" == mold/all AED$123.45678 --test-- "transcode-money-6" --assert "-ZMW$123.45678" == mold/all -ZMW$123.45678 --test-- "transcode-money-7" - "RED$0.00000" == mold/all red$0 - "RED$0.00000" == mold/all RED$0 - "RED$0.00000" == mold/all Red$0 - "RED$0.00000" == mold/all transcode/one "red$0" - "RED$0.00000" == mold/all transcode/one "RED$0" - "RED$0.00000" == mold/all transcode/one "Red$0" - "RED$0.00000" == mold/all make money! 'red - "RED$0.00000" == mold/all make money! 'RED - "RED$0.00000" == mold/all make money! 'Red - "RED$0.00000" == mold/all make money! [red 0] - "RED$0.00000" == mold/all make money! [RED 0] - "RED$0.00000" == mold/all make money! [Red 0] - "RED$0.00000" == mold/all make money! "red$0" - "RED$0.00000" == mold/all make money! "RED$0" - "RED$0.00000" == mold/all make money! "Red$0" - ;--test-- "transcode-money-" - ;--assert error! == transcode/prescan "-$.1" - ;--assert error! == transcode/prescan "+$,2" - ;--assert error! == transcode/prescan "$3." - ;--assert error! == transcode/prescan "$4," + --assert "RED$0.00000" == mold/all red$0 + --assert "RED$0.00000" == mold/all RED$0 + --assert "RED$0.00000" == mold/all Red$0 + --assert "RED$0.00000" == mold/all transcode/one "red$0" + --assert "RED$0.00000" == mold/all transcode/one "RED$0" + --assert "RED$0.00000" == mold/all transcode/one "Red$0" + --assert "RED$0.00000" == mold/all make money! 'red + --assert "RED$0.00000" == mold/all make money! 'RED + --assert "RED$0.00000" == mold/all make money! 'Red + --assert "RED$0.00000" == mold/all make money! [red 0] + --assert "RED$0.00000" == mold/all make money! [RED 0] + --assert "RED$0.00000" == mold/all make money! [Red 0] + --assert "RED$0.00000" == mold/all make money! "red$0" + --assert "RED$0.00000" == mold/all make money! "RED$0" + --assert "RED$0.00000" == mold/all make money! "Red$0" + --test-- "transcode-money-8" + --assert error! == transcode/scan "$123456789012345678" + --assert error! == transcode/scan "$'1" + ;--assert error! == transcode/scan "$1'" + ;--assert error! == transcode/scan "$1''2" + --assert $12345678901234567.12345 == transcode/one "$12345678901234567.1234567890" + ;--assert $12345678901234567.12345 == transcode/one "$00000000000000000012345678901234567.12345" + --assert $12345678901234567.12345 == transcode/one "+$12'345'678'901'234'567.1234567890" + ;--assert -$12345678901234567.12345 == transcode/one "-$0'00'000'000012345678901234567.12345" + --test-- "transcode-money-" + --assert error! == transcode/scan "-$.1" + --assert error! == transcode/scan "+$,2" + --assert error! == transcode/scan "$3." + --assert error! == transcode/scan "$4," ===end-group=== ===start-group=== "as-money" @@ -678,7 +698,7 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [make money! 'bar] append list/extra 'bar --assert money? make money! 'bar - ;--assert "BAR$0.00000" == mold/all make money! 'bar + --assert "BAR$0.00000" == mold/all make money! 'bar --assert error? try [make money! 'qux] append list/extra 'QUX --assert "-QUX$123.45678" == mold/all make money! [QUX -123 45678] From f1c879174c251a1294caffa7b2078e007e2ed0dc Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 7 Apr 2020 17:20:51 +0200 Subject: [PATCH 1294/3432] FEAT: allows leading zeros for money literals + extra quotes checking. --- runtime/lexer.reds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index ca0a71d797..26dc51635f 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1873,20 +1873,24 @@ lexer: context [ if cur + 3 <> p [do-error] ] assert p/1 = #"$" - st: p - p: p + 1 - if any [p/1 = #"." p/1 = #","][do-error] + if any [p/2 = #"." p/2 = #"," p/2 = #"'"][do-error] + until [p: p + 1 all [p/1 <> #"0" p/1 <> #"'"]] + st: p - 1 ds: null quotes: 0 while [p < e][ if any [p/1 = #"." p/1 = #","][ ds: p if ds + 1 = e [do-error] - break + break + ] + if p/1 = #"'" [ + if all [p + 1 < e p/2 = #"'"][do-error] + quotes: quotes + 1 ] - if p/1 = #"'" [quotes: quotes + 1] p: p + 1 ] + if p/0 = #"'" [do-error] if 18 + quotes < as-integer p - st [do-error] lex/in-pos: e ;-- reset the input position to delimiter byte if all [load? null? money/make-at alloc-slot lex neg? cur st ds e][do-error] From 3276545f35fb4ebefa123beb177cc6cf010604c8 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 7 Apr 2020 17:20:26 +0200 Subject: [PATCH 1295/3432] FIX: issue #4383 (to-hex is not doing proper bounds check for its `/size` value). --- runtime/natives.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index c67fc407c5..337de09286 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1614,13 +1614,13 @@ natives: context [ /local arg [red-integer!] limit [red-integer!] - buf [red-word!] p [c-string!] part [integer!] ][ #typecheck [to-hex size] arg: as red-integer! stack/arguments limit: arg + size + unless positive? limit/value [fire [TO_ERROR(script invalid-arg) limit]] p: string/to-hex arg/value no part: either OPTION?(limit) [8 - limit/value][0] From 19fc3be9422193cb7ef4de6809f507595b8cd5ba Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 7 Apr 2020 17:21:00 +0200 Subject: [PATCH 1296/3432] TESTS: serialization test for issue #4383. --- tests/source/units/serialization-test.red | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/source/units/serialization-test.red b/tests/source/units/serialization-test.red index 205db7b985..93b28ffc05 100644 --- a/tests/source/units/serialization-test.red +++ b/tests/source/units/serialization-test.red @@ -179,6 +179,10 @@ ser-formed: {1 none true false c red Red a/b 'a/b :a/b a/b: 1 + 2 a a c d b e f --assert #FFFFFFFE = to-hex -2 --test-- "to-hex-3" --assert #0F = to-hex/size 15 2 + --test-- "to-hex-4" + --assert #F = to-hex/size 15 1 + --assert error? try [to-hex/size 15 0] + --assert error? try [to-hex/size 15 -1] ===end-group=== ~~~end-file~~~ From 9c0412ce972c7605fa6cba53726bf80e272a766c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 7 Apr 2020 18:08:09 +0200 Subject: [PATCH 1297/3432] FIX: missing entries for money! support in libRedRT. --- system/utils/libRedRT-exports.r | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/utils/libRedRT-exports.r b/system/utils/libRedRT-exports.r index 34a4ffc303..ad98d48e4c 100644 --- a/system/utils/libRedRT-exports.r +++ b/system/utils/libRedRT-exports.r @@ -77,6 +77,7 @@ red/lit-word/push red/logic/push red/map/push + red/money/push red/none/push red/object/push red/op/push @@ -377,6 +378,7 @@ red/natives/decompress* red/natives/recycle* red/natives/transcode* + red/natives/as-money* ][ red/object/path-parent cell! red/object/field-parent cell! From 2cd3608bd305c67bf0c4b55d51eb4eda119deb73 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 7 Apr 2020 18:08:44 +0200 Subject: [PATCH 1298/3432] FIX: $0 and -$0 literals loading regression. --- runtime/lexer.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 26dc51635f..a1d21e7b3e 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1874,7 +1874,8 @@ lexer: context [ ] assert p/1 = #"$" if any [p/2 = #"." p/2 = #"," p/2 = #"'"][do-error] - until [p: p + 1 all [p/1 <> #"0" p/1 <> #"'"]] + until [p: p + 1 any [p = e all [p/1 <> #"0" p/1 <> #"'"]]] + if any [p >= e p/1 = #"."][p: p - 1] ;-- backtrack if $0 or $0. st: p - 1 ds: null quotes: 0 From fb99c11176bdd0015a9d26a5236e79f7608d35a5 Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Tue, 7 Apr 2020 18:13:26 +0200 Subject: [PATCH 1299/3432] TESTS: uncomment non-passing tests. --- tests/source/units/money-test.red | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 2061dc6215..91a5751231 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -629,12 +629,12 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "transcode-money-8" --assert error! == transcode/scan "$123456789012345678" --assert error! == transcode/scan "$'1" - ;--assert error! == transcode/scan "$1'" - ;--assert error! == transcode/scan "$1''2" + --assert error! == transcode/scan "$1'" + --assert error! == transcode/scan "$1''2" --assert $12345678901234567.12345 == transcode/one "$12345678901234567.1234567890" - ;--assert $12345678901234567.12345 == transcode/one "$00000000000000000012345678901234567.12345" + --assert $12345678901234567.12345 == transcode/one "$00000000000000000012345678901234567.12345" --assert $12345678901234567.12345 == transcode/one "+$12'345'678'901'234'567.1234567890" - ;--assert -$12345678901234567.12345 == transcode/one "-$0'00'000'000012345678901234567.12345" + --assert -$12345678901234567.12345 == transcode/one "-$0'00'000'000012345678901234567.12345" --test-- "transcode-money-" --assert error! == transcode/scan "-$.1" --assert error! == transcode/scan "+$,2" @@ -702,8 +702,6 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --assert error? try [make money! 'qux] append list/extra 'QUX --assert "-QUX$123.45678" == mold/all make money! [QUX -123 45678] - ;--assert -QUX$123.45 == -QUX$123.45 - ;--assert zero? BAR$67.89 - BAR$67.89 --test-- "custom-4" --assert error? try [append list/extra 'bar] --assert error? try [append list/extra 'qux] From 5b200e37ce76248193e19425a3ab36b14da99f3d Mon Sep 17 00:00:00 2001 From: 9214 <9214@protonmail.com> Date: Wed, 8 Apr 2020 14:41:42 +0200 Subject: [PATCH 1300/3432] FIX: better fix for issue #4383. --- runtime/natives.reds | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index 337de09286..be166fb1e6 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -1620,10 +1620,12 @@ natives: context [ #typecheck [to-hex size] arg: as red-integer! stack/arguments limit: arg + size - unless positive? limit/value [fire [TO_ERROR(script invalid-arg) limit]] - + p: string/to-hex arg/value no - part: either OPTION?(limit) [8 - limit/value][0] + part: either not OPTION?(limit) [0][ + unless positive? limit/value [fire [TO_ERROR(script invalid-arg) limit]] + 8 - limit/value + ] if negative? part [part: 0] issue/make-at stack/arguments p + part ] From 738e873c3e571d0e14f4a748f0f1f6de104e5e71 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Wed, 8 Apr 2020 18:28:37 +0200 Subject: [PATCH 1301/3432] FIX: compiler generating wrong code for paths. Caught by test "recycle-object-6". The long path was generating `~ctx||792~f|1693` for `/h/` part. --- compiler.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler.r b/compiler.r index 08c1d9df9a..6717bfdc72 100644 --- a/compiler.r +++ b/compiler.r @@ -471,7 +471,7 @@ red: context [ append/only blk duplicate-symbol name ] ][ - if new: select-ssa name [name: new] ;@@ add a check for function! type + if all [new: select-ssa name not find-function new new][name: new] either get? [ either all [ rebol-gctx <> obj From fe2ad5264f7286b831583055a551d72aaa880d7b Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sun, 15 Mar 2020 10:10:25 +0800 Subject: [PATCH 1302/3432] FIX: image's alpha channel not right --- runtime/image-utils.reds | 2 +- runtime/platform/image-gdk.reds | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/runtime/image-utils.reds b/runtime/image-utils.reds index 14fabb4b88..34d3686f30 100644 --- a/runtime/image-utils.reds +++ b/runtime/image-utils.reds @@ -219,7 +219,7 @@ image-utils: context [ src.h: as float! sh size: rect.w * rect.h * 4 rgba: as int-ptr! allocate size - set-memory as byte-ptr! rgba #"^(FF)" size + set-memory as byte-ptr! rgba #"^(00)" size i: 0 j: 0 loop rect.h [ i: 0 diff --git a/runtime/platform/image-gdk.reds b/runtime/platform/image-gdk.reds index adf51fb91f..f3bcac8e31 100644 --- a/runtime/platform/image-gdk.reds +++ b/runtime/platform/image-gdk.reds @@ -296,9 +296,7 @@ OS-image: context [ b: p/1 p/1: p/3 p/3: b - either alpha? [ - p/4: #"^(FF)" - p/4 - ][ + unless alpha? [ p/4: #"^(FF)" ] dst/offset: old From cf782067e82958f5b68c5a930f1f29fd1b4b2ab1 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 10 Apr 2020 14:07:39 +0800 Subject: [PATCH 1303/3432] FEAT: GTK: preliminary support for scrollbar in gui-console. --- modules/view/backends/gtk3/draw.reds | 4 +- modules/view/backends/gtk3/events.reds | 1 + modules/view/backends/gtk3/gtk.reds | 114 +++++++++++++++- modules/view/backends/gtk3/gui.reds | 162 +++++++++++++++++------ modules/view/backends/gtk3/handlers.reds | 40 ++++++ system/runtime/libc.reds | 4 - 6 files changed, 277 insertions(+), 48 deletions(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index 802fa08d08..c429cf3f60 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1126,7 +1126,9 @@ OS-draw-arc: func [ angle-begin: atan2 (sin angle-begin) * rad-x (cos angle-begin) * rad-y angle-end: atan2 (sin angle-end) * rad-x (cos angle-end) * rad-y - if PI < fabs angle-end - angle-begin [ + rad: angle-end - angle-begin + if rad < 0.0 [rad: 0.0 - rad] + if PI < rad [ either angle-end > angle-begin [ angle-end: angle-end - (PI * 2.0) ][ diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 60b6e0d3f4..3d24c90070 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -636,6 +636,7 @@ get-event-picked: func [ event: as GdkEventScroll! g_object_get_qdata as handle! evt/msg red-event-id float/push 0.0 - event/delta_y ] + EVT_SCROLL [integer/push evt/flags >>> 4] EVT_MENU [word/push* evt/flags and FFFFh] default [integer/push evt/flags and FFFFh] ] diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index e4b13b1b3c..f815e5b6f9 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -19,6 +19,10 @@ Red/System [ g_signal_connect_data instance signal as-integer handler data null 1 ] +#define g_signal_handlers_disconnect_by_data(instance data) [ + g_signal_handlers_disconnect_matched instance 16 0 0 null null data +] + #define G_ASCII_DTOSTR_BUF_SIZE 39 #define G_TYPE_MAKE_FUNDAMENTAL(x) [x << 2] @@ -263,6 +267,13 @@ GdkEventScroll!: alias struct! [ ;;GDK_ALL_EVENTS_MASK: fffffffeh ] +GtkAllocation!: alias struct! [ + x [integer!] + y [integer!] + w [integer!] + h [integer!] +] + GtkTextIter!: alias struct! [ dummy1 [handle!] dummy2 [handle!] @@ -606,6 +617,16 @@ GPtrArray!: alias struct! [ flags [integer!] return: [integer!] ] + g_signal_handlers_disconnect_matched: "g_signal_handlers_disconnect_matched" [ + instance [int-ptr!] + mask [integer!] + signal_id [integer!] + detail [integer!] + closure [int-ptr!] + handler [int-ptr!] + data [int-ptr!] + return: [integer!] + ] g_signal_emit_by_name: "g_signal_emit_by_name" [ [variadic] ] @@ -1495,11 +1516,11 @@ GPtrArray!: alias struct! [ ] gtk_widget_size_allocate: "gtk_widget_size_allocate" [ widget [handle!] - alloc [handle!] + alloc [GtkAllocation!] ] gtk_widget_get_allocation: "gtk_widget_get_allocation" [ widget [handle!] - alloc [handle!] + alloc [GtkAllocation!] ] gtk_widget_get_allocated_width: "gtk_widget_get_allocated_width" [ widget [handle!] @@ -1702,6 +1723,10 @@ GPtrArray!: alias struct! [ vadj [handle!] return: [handle!] ] + gtk_scrolled_window_set_vadjustment: "gtk_scrolled_window_set_vadjustment" [ + win [handle!] + adj [handle!] + ] gtk_layout_put: "gtk_layout_put" [ layout [handle!] widget [handle!] @@ -2463,6 +2488,91 @@ GPtrArray!: alias struct! [ gtk_settings_get_default: "gtk_settings_get_default" [ return: [handle!] ] + gtk_scrolled_window_set_max_content_height: "gtk_scrolled_window_set_max_content_height" [ + scrolled [handle!] + height [integer!] + ] + gtk_scrolled_window_get_policy: "gtk_scrolled_window_get_policy" [ + win [handle!] + hs [int-ptr!] + vs [int-ptr!] + ] + gtk_adjustment_configure: "gtk_adjustment_configure" [ + adjustment [handle!] + value [float!] + lower [float!] + uppper [float!] + step [float!] + page [float!] + page-size [float!] + ] + gtk_scrollable_get_vadjustment: "gtk_scrollable_get_vadjustment" [ + scrollable [handle!] + return: [handle!] + ] + gtk_scrollable_get_hadjustment: "gtk_scrollable_get_hadjustment" [ + scrollable [handle!] + return: [handle!] + ] + gtk_scrollbar_new: "gtk_scrollbar_new" [ + orientation [integer!] + adjust [handle!] + return: [handle!] + ] + gtk_adjustment_new: "gtk_adjustment_new" [ + value [float!] + lower [float!] + uppper [float!] + step [float!] + page [float!] + page-size [float!] + return: [handle!] + ] + gtk_adjustment_set_upper: "gtk_adjustment_set_upper" [ + adjustment [handle!] + upper [float!] + ] + gtk_adjustment_set_value: "gtk_adjustment_set_value" [ + adjustment [handle!] + value [float!] + ] + gtk_adjustment_set_page_size: "gtk_adjustment_set_page_size" [ + adjustment [handle!] + value [float!] + ] + gtk_adjustment_get_value: "gtk_adjustment_get_value" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_lower: "gtk_adjustment_get_lower" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_page_size: "gtk_adjustment_get_page_size" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_upper: "gtk_adjustment_get_upper" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_page_increment: "gtk_adjustment_get_page_increment" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_step_increment: "gtk_adjustment_get_step_increment" [ + adjustment [handle!] + return: [float!] + ] + gtk_adjustment_get_minimum_increment: "gtk_adjustment_get_minimum_increment" [ + adjustment [handle!] + return: [float!] + ] + gtk_scrolled_window_set_policy: "gtk_scrolled_window_set_policy" [ + scrolled [handle!] + hpolicy [integer!] + vpolicy [integer!] + ] ;; LIBCAIRO-file cdecl [ cairo_create: "cairo_create" [ diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e9d5958bc4..ebf1bb65f3 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -67,6 +67,18 @@ get-face-values: func [ values ] +get-node-values: func [ + node [node!] + return: [red-value!] + /local + ctx [red-context!] + s [series!] +][ + ctx: TO_CTX(node) + s: as series! ctx/values/value + s/offset +] + get-node-facet: func [ node [node!] facet [integer!] @@ -908,6 +920,11 @@ change-size: func [ pl [handle!] x [integer!] y [integer!] + fy [float!] + min [float!] + max [float!] + page [float!] + adj [handle!] ][ either type = window [ gtk_window_set_default_size widget size/x size/y @@ -919,11 +936,25 @@ change-size: func [ sym: symbol/resolve ntype/symbol layout: get-face-layout widget values sym if layout <> widget [ - gtk_widget_set_size_request layout size/x size/y + y: size/y + if type = rich-text [ + adj: gtk_scrollable_get_vadjustment widget + min: gtk_adjustment_get_lower adj + max: gtk_adjustment_get_upper adj + page: gtk_adjustment_get_page_size adj + ] + gtk_widget_set_size_request layout size/x y gtk_widget_queue_resize layout ] - gtk_widget_set_size_request widget size/x size/y - gtk_widget_queue_resize widget + either type = rich-text [ + fy: as float! size/y + fy: max - min / page * fy + y: as-integer fy + gtk_layout_set_size widget size/x y + ][ + gtk_widget_set_size_request widget size/x size/y + gtk_widget_queue_resize widget + ] if type = panel [ label: GET-CAPTION(widget) @@ -1372,49 +1403,90 @@ update-scroller: func [ /local parent [red-object!] vertical? [red-logic!] + bar [handle!] int [red-integer!] values [red-value!] widget [handle!] - nTrackPos [integer!] - nPos [integer!] - nPage [integer!] - nMax [integer!] - nMin [integer!] - fMask [integer!] - cbSize [integer!] -][ - ;values: object/get-values scroller - ;parent: as red-object! values + SCROLLER_OBJ_PARENT - ;vertical?: as red-logic! values + SCROLLER_OBJ_VERTICAL? - ;int: as red-integer! block/rs-head as red-block! (object/get-values parent) + FACE_OBJ_STATE - ;widget: as handle! int/value - - ;int: as red-integer! values + flag - - ;if flag = SCROLLER_OBJ_VISIBLE? [ - ; ShowScrollBar widget as-integer vertical?/value as logic! int/value - ; exit - ;] + container [handle!] + pos [float!] + page [float!] + max [float!] + min [float!] + n [float!] + range [float!] + new-pos [float!] + vs [integer!] + hs [integer!] + w [integer!] + h [integer!] + flags [integer!] +][ + values: object/get-values scroller + parent: as red-object! values + SCROLLER_OBJ_PARENT + vertical?: as red-logic! values + SCROLLER_OBJ_VERTICAL? + int: as red-integer! block/rs-head as red-block! (object/get-values parent) + FACE_OBJ_STATE + widget: as handle! int/value + container: get-face-layout widget null rich-text + + int: as red-integer! values + flag + if flag = SCROLLER_OBJ_VISIBLE? [ + hs: 0 vs: 0 + gtk_scrolled_window_get_policy container :hs :vs + either int/value = 0 [flags: 2][flags: 1] + either vertical?/value [vs: flags][hs: flags] + gtk_scrolled_window_set_policy container hs vs + exit + ] - ;fMask: switch flag [ - ; SCROLLER_OBJ_POS [nPos: int/value SIF_POS] - ; SCROLLER_OBJ_PAGE - ; SCROLLER_OBJ_MAX [ - ; int: as red-integer! values + SCROLLER_OBJ_PAGE - ; nPage: int/value - ; int: as red-integer! values + SCROLLER_OBJ_MAX - ; nMin: 1 - ; nMax: int/value - ; SIF_RANGE or SIF_PAGE - ; ] - ; default [0] - ;] + either vertical?/value [ + bar: gtk_scrollable_get_vadjustment widget + ][ + bar: gtk_scrollable_get_hadjustment widget + ] - ;if fMask <> 0 [ - ; fMask: fMask or SIF_DISABLENOSCROLL - ; cbSize: size? tagSCROLLINFO - ; SetScrollInfo widget as-integer vertical?/value as tagSCROLLINFO :cbSize yes - ;] + SET-CONTAINER(bar scroller/ctx) + + w: 0 h: 0 + gtk_widget_get_size_request container :w :h + + int: as red-integer! values + SCROLLER_OBJ_POS + pos: as float! int/value + int: as red-integer! values + SCROLLER_OBJ_PAGE + page: as float! int/value + int: as red-integer! values + SCROLLER_OBJ_MIN + min: as float! int/value + int: as red-integer! values + SCROLLER_OBJ_MAX + max: as float! int/value + + if max - min <= page [exit] + + switch flag [ + SCROLLER_OBJ_POS [ + pos: pos - min + range: max - min - page + 1.0 + if pos > range [pos: range] + if pos < 0.0 [pos: 0.0] + either range <= 0.0 [new-pos: 1.0][ + new-pos: pos / range + ] + min: gtk_adjustment_get_lower bar + max: gtk_adjustment_get_upper bar + page: gtk_adjustment_get_page_size bar + range: max - min - page + new-pos: new-pos * range + min + gtk_adjustment_set_value bar new-pos + ] + SCROLLER_OBJ_PAGE + SCROLLER_OBJ_MAX [ + n: as float! h + if all [page > 0.0 max - min > page][ + n: max - min + 1.0 / page * n + h: as-integer n + 0.5 + gtk_layout_set_size widget w h + ] + ] + default [0] + ] ] @@ -1544,6 +1616,7 @@ OS-make-view: func [ buffer [handle!] container [handle!] hMenu [handle!] + vadjust [handle!] value [integer!] fvalue [float!] vertical? [logic!] @@ -1617,6 +1690,13 @@ OS-make-view: func [ gtk_layout_set_size widget size/x size/y container: gtk_scrolled_window_new null null gtk_container_add container widget + if bits and FACET_FLAGS_SCROLLABLE <> 0 [ + gtk_scrolled_window_set_policy container 1 1 + vadjust: gtk_scrollable_get_vadjustment widget + g_signal_handlers_disconnect_by_data(vadjust widget) ;-- remove default event handler + gtk_adjustment_configure vadjust 0.0 0.0 1.0 0.0 0.0 1.0 + gobj_signal_connect(vadjust "value_changed" :vbar-value-changed widget) + ] ] sym = window [ widget: gtk_window_new 0 diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 769d5cd3c5..0f9a4e2818 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -62,6 +62,46 @@ button-clicked: func [ make-event widget 0 EVT_CLICK ] +vbar-value-changed: func [ + [cdecl] + adj [handle!] + widget [handle!] + /local + sc [node!] + pos [integer!] + values [red-value!] + min [red-integer!] + max [red-integer!] + page [red-integer!] + range [integer!] + lower [float!] + upper [float!] + v [float!] + pg [float!] +][ + sc: GET-CONTAINER(adj) + if sc <> null [ + values: get-node-values sc + + min: as red-integer! values + SCROLLER_OBJ_MIN + max: as red-integer! values + SCROLLER_OBJ_MAX + page: as red-integer! values + SCROLLER_OBJ_PAGE + range: max/value - page/value - min/value + 1 + + v: gtk_adjustment_get_value adj + lower: gtk_adjustment_get_lower adj + upper: gtk_adjustment_get_upper adj + pg: gtk_adjustment_get_page_size adj + pg: upper - lower - pg + + v: v / pg * (as float! range) + v: v + as float! min/value + pos: as-integer v + pos: pos << 4 + make-event widget 2 or pos EVT_SCROLL + ] +] + button-toggled: func [ [cdecl] evbox [handle!] diff --git a/system/runtime/libc.reds b/system/runtime/libc.reds index 5e772aaf4f..bd33977270 100644 --- a/system/runtime/libc.reds +++ b/system/runtime/libc.reds @@ -143,10 +143,6 @@ Red/System [ value [float!] return: [float!] ] - fabs: "fabs" [ - value [float!] - return: [float!] - ] fmod: "fmod" [ x [float!] y [float!] From 2d7d980346d35bddd4e4ce06fd5e4efae30f3554 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Fri, 10 Apr 2020 16:28:22 +0800 Subject: [PATCH 1304/3432] FEAT: GTK: finish scroller! in gui-console. --- modules/view/backends/gtk3/gui.reds | 39 ++++++++++++++++-------- modules/view/backends/gtk3/handlers.reds | 9 +++++- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index ebf1bb65f3..8e4090c4eb 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -184,10 +184,16 @@ get-face-layout: func [ values [red-value!] sym [integer!] return: [handle!] + /local + h [handle!] ][ case [ + sym = rich-text [ + h: GET-CONTAINER(widget) + if null? h [h: widget] + h + ] any [ - sym = rich-text sym = text sym = area sym = text-list @@ -935,21 +941,21 @@ change-size: func [ ntype: as red-word! values + FACE_OBJ_TYPE sym: symbol/resolve ntype/symbol layout: get-face-layout widget values sym + y: size/y if layout <> widget [ - y: size/y - if type = rich-text [ + if type = rich-text [ ;-- is scrollable adj: gtk_scrollable_get_vadjustment widget min: gtk_adjustment_get_lower adj max: gtk_adjustment_get_upper adj page: gtk_adjustment_get_page_size adj + fy: as float! y + fy: max - min / page * fy + y: as-integer fy ] - gtk_widget_set_size_request layout size/x y + gtk_widget_set_size_request layout size/x size/y gtk_widget_queue_resize layout ] either type = rich-text [ - fy: as float! size/y - fy: max - min / page * fy - y: as-integer fy gtk_layout_set_size widget size/x y ][ gtk_widget_set_size_request widget size/x size/y @@ -1462,6 +1468,7 @@ update-scroller: func [ switch flag [ SCROLLER_OBJ_POS [ + if null <> GET-IN-LOOP(widget) [exit] pos: pos - min range: max - min - page + 1.0 if pos > range [pos: range] @@ -1688,14 +1695,20 @@ OS-make-view: func [ sym = rich-text [ widget: gtk_layout_new null null gtk_layout_set_size widget size/x size/y - container: gtk_scrolled_window_new null null - gtk_container_add container widget if bits and FACET_FLAGS_SCROLLABLE <> 0 [ + container: gtk_scrolled_window_new null null + gtk_container_add container widget gtk_scrolled_window_set_policy container 1 1 - vadjust: gtk_scrollable_get_vadjustment widget - g_signal_handlers_disconnect_by_data(vadjust widget) ;-- remove default event handler - gtk_adjustment_configure vadjust 0.0 0.0 1.0 0.0 0.0 1.0 - gobj_signal_connect(vadjust "value_changed" :vbar-value-changed widget) + len: 0 + loop 2 [ + either zero? len [vadjust: gtk_scrollable_get_vadjustment widget][ + vadjust: gtk_scrollable_get_hadjustment widget + ] + len: len + 1 + g_signal_handlers_disconnect_by_data(vadjust widget) ;-- remove default event handler + gtk_adjustment_configure vadjust 0.0 0.0 1.0 0.0 0.0 1.0 + gobj_signal_connect(vadjust "value_changed" :vbar-value-changed widget) + ] ] ] sym = window [ diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 0f9a4e2818..9fe8b36d51 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -78,6 +78,8 @@ vbar-value-changed: func [ upper [float!] v [float!] pg [float!] + bar [handle!] + dir [integer!] ][ sc: GET-CONTAINER(adj) if sc <> null [ @@ -98,7 +100,12 @@ vbar-value-changed: func [ v: v + as float! min/value pos: as-integer v pos: pos << 4 - make-event widget 2 or pos EVT_SCROLL + + bar: gtk_scrollable_get_hadjustment widget + dir: as-integer bar = adj + SET-IN-LOOP(widget sc) + make-event widget dir << 3 or 2 or pos EVT_SCROLL + SET-IN-LOOP(widget null) ] ] From eb7a2f1f0324c23112c375d8bd33f78e8ccb98a8 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Fri, 10 Apr 2020 17:13:55 +0800 Subject: [PATCH 1305/3432] FIX: menu size be included in window size --- modules/view/backends/gtk3/gui.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 8e4090c4eb..02d05016ab 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1750,7 +1750,7 @@ OS-make-view: func [ gtk_box_pack_start winbox container yes yes 0 gtk_window_move widget offset/x offset/y - gtk_widget_set_size_request widget size/x size/y ;-- fix the initial size of the window + gtk_widget_set_size_request container size/x size/y ;-- fix the initial size of the window gtk_window_set_resizable widget (bits and FACET_FLAGS_RESIZE <> 0) ] sym = camera [ From 40a43ddfeea9a2eb8fa70f03120685a732618ce0 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 11 Apr 2020 10:39:47 +0800 Subject: [PATCH 1306/3432] FIX: GTK: force redraw when changing draw block. Fix code/tiger.red and code/particles.red --- modules/view/backends/gtk3/events.reds | 4 ++++ modules/view/backends/gtk3/gtk.reds | 2 ++ modules/view/backends/gtk3/gui.reds | 2 ++ 3 files changed, 8 insertions(+) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 3d24c90070..9c3c764f44 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -779,6 +779,10 @@ do-events: func [ break ] if null? GET-IN-LOOP(win) [break] + if force-redraw? [ + gdk_window_process_all_updates + force-redraw?: no + ] no-wait? ] msg? diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index f815e5b6f9..a0fb8aa209 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -703,6 +703,8 @@ GPtrArray!: alias struct! [ ] ;; ] ;; LIBGDK-file cdecl [ + gdk_flush: "gdk_flush" [] + gdk_window_process_all_updates: "gdk_window_process_all_updates" [] gdk_screen_width: "gdk_screen_width" [ return: [integer!] ] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index 02d05016ab..e999439996 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -24,6 +24,7 @@ Red/System [ #include %tab-panel.reds #include %text-list.reds +force-redraw?: no settings: as handle! 0 pango-context: as handle! 0 default-font-name: as c-string! 0 @@ -1999,6 +2000,7 @@ OS-update-view: func [ ] if flags and FACET_FLAG_DRAW <> 0 [ gtk_widget_queue_draw widget + force-redraw?: yes ; 0 ] if flags and FACET_FLAG_COLOR <> 0 [ From 9a6e649bcf5d1c9f6d485f07cd8ffc9b1179da79 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 11 Apr 2020 15:15:01 +0800 Subject: [PATCH 1307/3432] FIX: add fix to calc window size --- modules/view/backends/gtk3/handlers.reds | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 9fe8b36d51..bf027c8a0c 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -465,17 +465,23 @@ window-size-allocate: func [ widget [handle!] /local sz [red-pair!] + cont [handle!] + w [integer!] + h [integer!] ][ sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE if null? GET-STARTRESIZE(widget) [ SET-STARTRESIZE(widget widget) ] + cont: GET-CONTAINER(widget) + w: gtk_widget_get_allocated_width cont + h: gtk_widget_get_allocated_height cont if any [ - sz/x <> rect/width - sz/y <> rect/height + sz/x <> w + sz/y <> h ][ - sz/x: rect/width - sz/y: rect/height + sz/x: w + sz/y: h either null? GET-RESIZING(widget) [ make-event widget 0 EVT_SIZE ][ From 7e2f140e41406013476f427a41e0ce19d7c036b3 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 11 Apr 2020 15:40:40 +0800 Subject: [PATCH 1308/3432] FIX: window's all-over not right --- modules/view/backends/gtk3/events.reds | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index 3d24c90070..7547623f6c 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -992,14 +992,18 @@ connect-widget-events: func [ sym [integer!] /local evbox [handle!] + cont [handle!] buffer [handle!] ][ evbox: get-face-evbox widget values sym + cont: GET-CONTAINER(widget) ;-- register red mouse, key event functions - if sym <> window [ + either sym = window [ + connect-notify-events cont widget + connect-common-events cont widget + ][ connect-common-events evbox widget ] - connect-notify-events evbox widget connect-focus-events evbox widget sym gobj_signal_connect(evbox "realize" :widget-realize widget) From a76ef6c4d0a57d9af36705f341a7185e21de71d7 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Sat, 11 Apr 2020 16:42:31 +0800 Subject: [PATCH 1309/3432] FIX: base's draw can't be disabled --- modules/view/backends/gtk3/handlers.reds | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index bf027c8a0c..0193dbbd7f 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -230,6 +230,7 @@ base-draw: func [ type [red-word!] font [red-object!] color [red-tuple!] + bool [red-logic!] sym [integer!] pos [red-pair! value] DC [draw-ctx! value] @@ -244,7 +245,12 @@ base-draw: func [ type: as red-word! values + FACE_OBJ_TYPE font: as red-object! values + FACE_OBJ_FONT color: as red-tuple! values + FACE_OBJ_COLOR + bool: as red-logic! values + FACE_OBJ_ENABLED? sym: symbol/resolve type/symbol + if all [ + sym = base + not bool/value + ][return EVT_DISPATCH] either all [ TYPE_OF(color) = TYPE_TUPLE From b373ddae70adf584a14da48fca754b3c89131650 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 11 Apr 2020 19:30:56 +0800 Subject: [PATCH 1310/3432] FEAT: use fonts/fixed in gui-console instead of hard-coded font. --- environment/console/GUI/gui-console.red | 2 +- modules/view/backends/platform.red | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index e39b0ab853..d473057340 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -43,7 +43,7 @@ gui-console-ctx: context [ cfg-dir: none cfg-path: none cfg: none - font: make font! [name: "Consolas" size: 11 color: 0.0.0] + font: make font! [name: system/view/fonts/fixed size: 11 color: 0.0.0] caret-clr: 0.0.0.1 scroller: make scroller! [] diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index 954841be89..a76c66df63 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -842,7 +842,8 @@ system/view/platform: context [ ] ] macOS [["Menlo" "Arial" "Times"]] - Linux [["Droid Sans Mono" "DejaVu Sans" "DejaVu Serif"]] + ;-- use "Monospace" on Linux, we let the system use the default one + Linux [["Monospace" "DejaVu Sans" "DejaVu Serif"]] ] set [font-fixed font-sans-serif font-serif] reduce fonts From e95d67c0994b34eb1204fa23b2a4ea57462e0688 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sat, 11 Apr 2020 20:04:52 +0800 Subject: [PATCH 1311/3432] FEAT: GTK: adds browse native!. --- runtime/natives.reds | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/runtime/natives.reds b/runtime/natives.reds index c67fc407c5..0d038ae331 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2595,24 +2595,25 @@ natives: context [ file/to-local-path as red-file! src url no ][url: src] - #switch OS [ - Windows [ + #case [ + OS = 'Windows [ platform/ShellExecute 0 #u16 "open" unicode/to-utf16 url 0 0 1 - unset/push-last ] - macOS [ - use [s [c-string!] cmd [byte-ptr!] len [integer!]][ + any [OS = 'Linux OS = 'macOS][ + use [tool [c-string!] n [integer!] s [c-string!] cmd [byte-ptr!] len [integer!]][ + #either OS = 'macOS [tool: "open " n: 5][tool: "xdg-open " n: 9] len: -1 s: unicode/to-utf8 url :len - cmd: allocate 6 + len - copy-memory cmd as byte-ptr! "open " 5 - copy-memory cmd + 5 as byte-ptr! s len + 1 + cmd: allocate len + n + 1 + copy-memory cmd as byte-ptr! tool n + copy-memory cmd + n as byte-ptr! s len + 1 ext-process/OS-call as-c-string cmd no no no yes null null null free cmd ] ] - #default [fire [TO_ERROR(internal not-here) words/_browse]] + true [fire [TO_ERROR(internal not-here) words/_browse]] ] + unset/push-last ] compress*: func [ From 653d14f1ab2798401f384d5911e3f275e893c815 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 12 Apr 2020 15:41:51 +0800 Subject: [PATCH 1312/3432] FIX: remove linux specific code in gui-console. --- environment/console/GUI/core.red | 7 ------- environment/console/GUI/gui-console.red | 1 - 2 files changed, 8 deletions(-) diff --git a/environment/console/GUI/core.red b/environment/console/GUI/core.red index e61e8c0350..58670ba88d 100644 --- a/environment/console/GUI/core.red +++ b/environment/console/GUI/core.red @@ -273,13 +273,6 @@ object [ if cfg/background [change theme/background cfg/background] ] if font/color [change theme/foreground font/color] - #if config/OS = 'Linux [ - ; since in Linux/GTK, no on-resizing when the window is first drawn - if cfg [ - gui-console-ctx/console/size: cfg/win-size - resize gui-console-ctx/console/size - ] - ] adjust-console-size gui-console-ctx/console/size update-theme ] diff --git a/environment/console/GUI/gui-console.red b/environment/console/GUI/gui-console.red index d473057340..7e940845a0 100644 --- a/environment/console/GUI/gui-console.red +++ b/environment/console/GUI/gui-console.red @@ -222,7 +222,6 @@ gui-console-ctx: context [ console/init load-cfg win/visible?: yes - #if config/OS = 'Linux [terminal/update-cfg font none] svs: system/view/screens/1 svs/pane: next svs/pane ;-- proctect itself from unview/all From 8208e866b96c2c56876a2322ec278cdf157d8b91 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Sun, 12 Apr 2020 16:18:49 +0800 Subject: [PATCH 1313/3432] FEAT: GTK: better metrics on Ubuntu. --- modules/view/backends/platform.red | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/view/backends/platform.red b/modules/view/backends/platform.red index a76c66df63..4629f63dc1 100644 --- a/modules/view/backends/platform.red +++ b/modules/view/backends/platform.red @@ -759,9 +759,9 @@ system/view/platform: context [ drop-list: [14x26 0x0 regular 14x26 0x0 small 11x22 0x0 mini 11x22 0x0] ] Linux [ - button: [11x11 0x0] - check: [20x0 3x1] - radio: [20x0 1x1] + button: [16x16 0x0] + check: [20x8 2x2] + radio: [20x8 2x2] text: [3x3 0x0] field: [3x3 0x0] group-box: [0x8 4x18] From bf69c3814bf0da0d6360f6989f3817ad2990964d Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 13 Apr 2020 11:03:01 +0800 Subject: [PATCH 1314/3432] FIX: GTK: use `pad` spread method in old gradient pen. --- modules/view/backends/gtk3/draw.reds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/view/backends/gtk3/draw.reds b/modules/view/backends/gtk3/draw.reds index c429cf3f60..14363c39aa 100644 --- a/modules/view/backends/gtk3/draw.reds +++ b/modules/view/backends/gtk3/draw.reds @@ -1388,7 +1388,7 @@ OS-draw-grad-pen-old: func [ grad/colors-pos: as float32-ptr! pc + MAX_COLORS grad/on?: on ] - grad/spread: mode + grad/spread: _pad grad/type: type grad/count: 0 From 41c24700e8a0160d6ea2bb09eef4c0ccae069eab Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Mon, 13 Apr 2020 14:03:09 +0800 Subject: [PATCH 1315/3432] FEAT: GTK: adds float! support for progress and slider face. --- modules/view/backends/gtk3/gui.reds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index e999439996..a0d0e12c25 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1086,14 +1086,14 @@ change-data: func [ case [ all [ type = progress - TYPE_OF(data) = TYPE_PERCENT + any [TYPE_OF(data) = TYPE_PERCENT TYPE_OF(data) = TYPE_FLOAT] ][ f: as red-float! data gtk_progress_bar_set_fraction widget f/value ] all [ type = slider - TYPE_OF(data) = TYPE_PERCENT + any [TYPE_OF(data) = TYPE_PERCENT TYPE_OF(data) = TYPE_FLOAT] ][ f: as red-float! data gtk_range_set_value widget f/value * 100.0 From 40387af6c33bb91a2fccb2d0a9e90d772ba05ad8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 13 Apr 2020 10:26:47 +0200 Subject: [PATCH 1316/3432] FEAT: promotes integer division result to float if not exact. --- runtime/datatypes/char.reds | 2 +- runtime/datatypes/integer.reds | 30 ++- runtime/datatypes/pair.reds | 4 +- runtime/datatypes/tuple.reds | 2 +- runtime/datatypes/vector.reds | 4 +- system/tests/source/units/integer-test.reds | 2 + tests/source/units/integer-test.red | 216 +++++++++++--------- 7 files changed, 147 insertions(+), 113 deletions(-) diff --git a/runtime/datatypes/char.reds b/runtime/datatypes/char.reds index 42d2ecacf7..896c46f7ec 100644 --- a/runtime/datatypes/char.reds +++ b/runtime/datatypes/char.reds @@ -32,7 +32,7 @@ char: context [ default [fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)]] ] - rv: integer/do-math-op char/value rv op + rv: integer/do-math-op char/value rv op null if any [ rv > 0010FFFFh negative? rv diff --git a/runtime/datatypes/integer.reds b/runtime/datatypes/integer.reds index a5b4ecfe66..cc0b61652e 100644 --- a/runtime/datatypes/integer.reds +++ b/runtime/datatypes/integer.reds @@ -174,52 +174,60 @@ integer: context [ left [integer!] right [integer!] type [math-op!] + slot [red-integer!] return: [integer!] /local + fl [red-float!] res [integer!] ][ switch type [ OP_ADD [ res: left + right if system/cpu/overflow? [fire [TO_ERROR(math overflow)]] - res ] OP_SUB [ res: left - right if system/cpu/overflow? [fire [TO_ERROR(math overflow)]] - res ] OP_MUL [ res: left * right if system/cpu/overflow? [fire [TO_ERROR(math overflow)]] - res ] - OP_AND [left and right] - OP_OR [left or right] - OP_XOR [left xor right] + OP_AND [res: left and right] + OP_OR [res: left or right] + OP_XOR [res: left xor right] OP_REM [ either zero? right [ fire [TO_ERROR(math zero-divide)] - 0 ;-- pass the compiler's type-checking + 0 ;-- pass the compiler's type-checking ][ if all [left = -2147483648 right = -1][ fire [TO_ERROR(math overflow)] ] - left % right + res: left % right ] ] OP_DIV [ either zero? right [ fire [TO_ERROR(math zero-divide)] - 0 ;-- pass the compiler's type-checking + 0 ;-- pass the compiler's type-checking ][ if all [left = -2147483648 right = -1][ fire [TO_ERROR(math overflow)] ] - left / right + either any [null? slot left % right = 0][ + res: left / right + ][ + fl: as red-float! slot ;-- promote to float + fl/header: TYPE_FLOAT + fl/value: (as-float left) / as-float right + return 0 ;-- place-holder value + ] ] ] ] + if slot <> null [slot/value: res] + res ] do-math: func [ @@ -245,7 +253,7 @@ integer: context [ switch TYPE_OF(right) [ TYPE_INTEGER TYPE_CHAR [ - left/value: do-math-op left/value right/value op + do-math-op left/value right/value op left ] TYPE_MONEY [ left: as red-integer! money/do-math op diff --git a/runtime/datatypes/pair.reds b/runtime/datatypes/pair.reds index 199a542edc..3934d2b5b7 100644 --- a/runtime/datatypes/pair.reds +++ b/runtime/datatypes/pair.reds @@ -64,8 +64,8 @@ pair: context [ fire [TO_ERROR(script invalid-type) datatype/push TYPE_OF(right)] ] ] - left/x: integer/do-math-op left/x x op - left/y: integer/do-math-op left/y y op + left/x: integer/do-math-op left/x x op null + left/y: integer/do-math-op left/y y op null left ] diff --git a/runtime/datatypes/tuple.reds b/runtime/datatypes/tuple.reds index d9419c0632..c61ed022d0 100644 --- a/runtime/datatypes/tuple.reds +++ b/runtime/datatypes/tuple.reds @@ -219,7 +219,7 @@ tuple: context [ v: either n <= size2 [as-integer tp2/n][0] ] v1: either n <= size1 [as-integer tp1/n][0] - v1: integer/do-math-op v1 v type + v1: integer/do-math-op v1 v type null either v1 > 255 [v1: 255][if negative? v1 [v1: 0]] tp1/n: as byte! v1 n = size diff --git a/runtime/datatypes/vector.reds b/runtime/datatypes/vector.reds index c14da72500..5b14e2e92c 100644 --- a/runtime/datatypes/vector.reds +++ b/runtime/datatypes/vector.reds @@ -484,7 +484,7 @@ vector: context [ ] while [i < len][ v1: get-value-int as int-ptr! p unit - v1: integer/do-math-op v1 v2 op + v1: integer/do-math-op v1 v2 op null switch unit [ 1 [p/value: as-byte v1] 2 [p/1: as-byte v1 p/2: as-byte v1 >> 8] @@ -574,7 +574,7 @@ vector: context [ while [i < len1][ v1: get-value-int as int-ptr! p1 unit1 v2: get-value-int as int-ptr! p2 unit2 - v1: integer/do-math-op v1 v2 type + v1: integer/do-math-op v1 v2 type null switch unit [ 1 [p/value: as-byte v1] 2 [p/1: as-byte v1 p/2: as-byte v1 >> 8] diff --git a/system/tests/source/units/integer-test.reds b/system/tests/source/units/integer-test.reds index b0c1ca4518..b44f745597 100644 --- a/system/tests/source/units/integer-test.reds +++ b/system/tests/source/units/integer-test.reds @@ -1239,6 +1239,8 @@ Red/System [ j: 1 --assert i / j = -1 --test-- "integer-divide3" +probe -1 / 255 +probe -1 / 255 = 0 --assert -1 / 255 = 0 i: -1 j: 255 diff --git a/tests/source/units/integer-test.red b/tests/source/units/integer-test.red index c85a37e7b4..bc8df67bf9 100644 --- a/tests/source/units/integer-test.red +++ b/tests/source/units/integer-test.red @@ -1110,42 +1110,47 @@ Red [ --test-- "1 / -2147483648" i: 1 j: -2147483648 - --assert strict-equal? 0 1 / -2147483648 - --assert strict-equal? 0 divide 1 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -4.656612873077393e-10 + --assert strict-equal? r 1 / -2147483648 + --assert strict-equal? r divide 1 -2147483648 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "1 / 2147483647" i: 1 j: 2147483647 - --assert strict-equal? 0 1 / 2147483647 - --assert strict-equal? 0 divide 1 2147483647 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 4.656612875245797e-10 + --assert strict-equal? r 1 / 2147483647 + --assert strict-equal? r divide 1 2147483647 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "1 / 65536" i: 1 j: 65536 - --assert strict-equal? 0 1 / 65536 - --assert strict-equal? 0 divide 1 65536 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 1.52587890625e-5 + --assert strict-equal? r 1 / 65536 + --assert strict-equal? r divide 1 65536 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "1 / 256" i: 1 j: 256 - --assert strict-equal? 0 1 / 256 - --assert strict-equal? 0 divide 1 256 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 0.00390625 + --assert strict-equal? r 1 / 256 + --assert strict-equal? r divide 1 256 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "1 / 16777216" i: 1 j: 16777216 - --assert strict-equal? 0 1 / 16777216 - --assert strict-equal? 0 divide 1 16777216 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 5.960464477539063e-8 + --assert strict-equal? r 1 / 16777216 + --assert strict-equal? r divide 1 16777216 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-1 / 0" i: -1 @@ -1166,42 +1171,47 @@ Red [ --test-- "-1 / -2147483648" i: -1 j: -2147483648 - --assert strict-equal? 0 -1 / -2147483648 - --assert strict-equal? 0 divide -1 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 4.656612873077393e-10 + --assert strict-equal? r -1 / -2147483648 + --assert strict-equal? r divide -1 -2147483648 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-1 / 2147483647" i: -1 j: 2147483647 - --assert strict-equal? 0 -1 / 2147483647 - --assert strict-equal? 0 divide -1 2147483647 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -4.656612875245797e-10 + --assert strict-equal? r -1 / 2147483647 + --assert strict-equal? r divide -1 2147483647 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-1 / 65536" i: -1 j: 65536 - --assert strict-equal? 0 -1 / 65536 - --assert strict-equal? 0 divide -1 65536 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -1.52587890625e-5 + --assert strict-equal? r -1 / 65536 + --assert strict-equal? r divide -1 65536 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-1 / 256" i: -1 j: 256 - --assert strict-equal? 0 -1 / 256 - --assert strict-equal? 0 divide -1 256 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -0.00390625 + --assert strict-equal? r -1 / 256 + --assert strict-equal? r divide -1 256 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-1 / 16777216" i: -1 j: 16777216 - --assert strict-equal? 0 -1 / 16777216 - --assert strict-equal? 0 divide -1 16777216 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -5.960464477539063e-8 + --assert strict-equal? r -1 / 16777216 + --assert strict-equal? r divide -1 16777216 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "-2147483648 / 0" i: -2147483648 @@ -1230,10 +1240,11 @@ Red [ --test-- "-2147483648 / 2147483647" i: -2147483648 j: 2147483647 - --assert strict-equal? -1 -2147483648 / 2147483647 - --assert strict-equal? -1 divide -2147483648 2147483647 - --assert strict-equal? -1 i / j - --assert strict-equal? -1 divide i j + r: -1.000000000465661 + --assert equal? r -2147483648 / 2147483647 + --assert equal? r divide -2147483648 2147483647 + --assert equal? r i / j + --assert equal? r divide i j --test-- "-2147483648 / 65536" i: -2147483648 @@ -1286,34 +1297,38 @@ Red [ --test-- "2147483647 / -2147483648" i: 2147483647 j: -2147483648 - --assert strict-equal? 0 2147483647 / -2147483648 - --assert strict-equal? 0 divide 2147483647 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -0.9999999995343387 + --assert strict-equal? r 2147483647 / -2147483648 + --assert strict-equal? r divide 2147483647 -2147483648 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "2147483647 / 65536" i: 2147483647 j: 65536 - --assert strict-equal? 32767 2147483647 / 65536 - --assert strict-equal? 32767 divide 2147483647 65536 - --assert strict-equal? 32767 i / j - --assert strict-equal? 32767 divide i j + r: 32767.99998474121 + --assert strict-equal? r 2147483647 / 65536 + --assert strict-equal? r divide 2147483647 65536 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "2147483647 / 256" i: 2147483647 j: 256 - --assert strict-equal? 8388607 2147483647 / 256 - --assert strict-equal? 8388607 divide 2147483647 256 - --assert strict-equal? 8388607 i / j - --assert strict-equal? 8388607 divide i j + r: 8388607.99609375 + --assert strict-equal? r 2147483647 / 256 + --assert strict-equal? r divide 2147483647 256 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "2147483647 / 16777216" i: 2147483647 j: 16777216 - --assert strict-equal? 127 2147483647 / 16777216 - --assert strict-equal? 127 divide 2147483647 16777216 - --assert strict-equal? 127 i / j - --assert strict-equal? 127 divide i j + r: 127.9999999403954 + --assert equal? r 2147483647 / 16777216 + --assert equal? r divide 2147483647 16777216 + --assert equal? r i / j + --assert equal? r divide i j --test-- "65536 / 0" i: 65536 @@ -1342,18 +1357,20 @@ Red [ --test-- "65536 / -2147483648" i: 65536 j: -2147483648 - --assert strict-equal? 0 65536 / -2147483648 - --assert strict-equal? 0 divide 65536 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -3.0517578125e-5 + --assert strict-equal? r 65536 / -2147483648 + --assert strict-equal? r divide 65536 -2147483648 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "65536 / 2147483647" i: 65536 j: 2147483647 - --assert strict-equal? 0 65536 / 2147483647 - --assert strict-equal? 0 divide 65536 2147483647 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 3.051757813921086e-5 + --assert equal? r 65536 / 2147483647 + --assert equal? r divide 65536 2147483647 + --assert equal? r i / j + --assert equal? r divide i j --test-- "65536 / 256" i: 65536 @@ -1366,10 +1383,11 @@ Red [ --test-- "65536 / 16777216" i: 65536 j: 16777216 - --assert strict-equal? 0 65536 / 16777216 - --assert strict-equal? 0 divide 65536 16777216 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 0.00390625 + --assert strict-equal? r 65536 / 16777216 + --assert strict-equal? r divide 65536 16777216 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "256 / 0" i: 256 @@ -1398,34 +1416,38 @@ Red [ --test-- "256 / -2147483648" i: 256 j: -2147483648 - --assert strict-equal? 0 256 / -2147483648 - --assert strict-equal? 0 divide 256 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -1.192092895507813e-7 + --assert equal? r 256 / -2147483648 + --assert equal? r divide 256 -2147483648 + --assert equal? r i / j + --assert equal? r divide i j --test-- "256 / 2147483647" i: 256 j: 2147483647 - --assert strict-equal? 0 256 / 2147483647 - --assert strict-equal? 0 divide 256 2147483647 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 1.192092896062924e-7 + --assert strict-equal? r 256 / 2147483647 + --assert strict-equal? r divide 256 2147483647 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "256 / 65536" i: 256 j: 65536 - --assert strict-equal? 0 256 / 65536 - --assert strict-equal? 0 divide 256 65536 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 0.00390625 + --assert strict-equal? r 256 / 65536 + --assert strict-equal? r divide 256 65536 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "256 / 16777216" i: 256 j: 16777216 - --assert strict-equal? 0 256 / 16777216 - --assert strict-equal? 0 divide 256 16777216 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 1.52587890625e-5 + --assert strict-equal? r 256 / 16777216 + --assert strict-equal? r divide 256 16777216 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "16777216 / 0" i: 16777216 @@ -1454,18 +1476,20 @@ Red [ --test-- "16777216 / -2147483648" i: 16777216 j: -2147483648 - --assert strict-equal? 0 16777216 / -2147483648 - --assert strict-equal? 0 divide 16777216 -2147483648 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: -0.0078125 + --assert strict-equal? r 16777216 / -2147483648 + --assert strict-equal? r divide 16777216 -2147483648 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "16777216 / 2147483647" i: 16777216 j: 2147483647 - --assert strict-equal? 0 16777216 / 2147483647 - --assert strict-equal? 0 divide 16777216 2147483647 - --assert strict-equal? 0 i / j - --assert strict-equal? 0 divide i j + r: 0.007812500003637979 + --assert strict-equal? r 16777216 / 2147483647 + --assert strict-equal? r divide 16777216 2147483647 + --assert strict-equal? r i / j + --assert strict-equal? r divide i j --test-- "16777216 / 65536" i: 16777216 From 50417f60b69203cd964dc2f29a1e0dccf6fe3c37 Mon Sep 17 00:00:00 2001 From: bitbegin Date: Mon, 13 Apr 2020 16:33:42 +0800 Subject: [PATCH 1317/3432] FIX: load gui-console's configs not right --- modules/view/backends/gtk3/events.reds | 11 +++++++-- modules/view/backends/gtk3/gtk.reds | 9 ++++++++ modules/view/backends/gtk3/gui.reds | 4 ++++ modules/view/backends/gtk3/handlers.reds | 29 ++++++++++++++++++------ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/modules/view/backends/gtk3/events.reds b/modules/view/backends/gtk3/events.reds index a7a222e73d..79ebf60b56 100644 --- a/modules/view/backends/gtk3/events.reds +++ b/modules/view/backends/gtk3/events.reds @@ -496,8 +496,15 @@ get-event-offset: func [ offset/header: TYPE_PAIR widget: as handle! evt/msg - sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE - as red-value! sz + either null? GET-HMENU(widget) [ + sz: (as red-pair! get-face-values widget) + FACE_OBJ_SIZE + offset/x: sz/x + offset/y: sz/y + ][ + offset/x: GET-CONTAINER-W(widget) + offset/y: GET-CONTAINER-H(widget) + ] + as red-value! offset ] any [ evt/type = EVT_ZOOM diff --git a/modules/view/backends/gtk3/gtk.reds b/modules/view/backends/gtk3/gtk.reds index a0fb8aa209..1ecee34e02 100644 --- a/modules/view/backends/gtk3/gtk.reds +++ b/modules/view/backends/gtk3/gtk.reds @@ -3275,6 +3275,9 @@ caption-id: g_quark_from_string "caption-id" in-loop-id: g_quark_from_string "in-loop-id" first-radio-id: g_quark_from_string "first-radio-id" resend-event-id: g_quark_from_string "resend-event-id" +hmenu-id: g_quark_from_string "hmenu-id" +container-w: g_quark_from_string "container-w" +container-h: g_quark_from_string "container-h" #define SET-CONTAINER(s d) [g_object_set_qdata s container-id d] #define GET-CONTAINER(s) [g_object_get_qdata s container-id] @@ -3294,3 +3297,9 @@ resend-event-id: g_quark_from_string "resend-event-id" #define GET-FIRST-RADIO(s) [g_object_get_qdata s first-radio-id] #define SET-RESEND-EVENT(s d) [g_object_set_qdata s resend-event-id d] #define GET-RESEND-EVENT(s) [g_object_get_qdata s resend-event-id] +#define SET-HMENU(s d) [g_object_set_qdata s hmenu-id d] +#define GET-HMENU(s) [g_object_get_qdata s hmenu-id] +#define SET-CONTAINER-W(s d) [g_object_set_qdata s container-w as int-ptr! d] +#define GET-CONTAINER-W(s) [as integer! g_object_get_qdata s container-w] +#define SET-CONTAINER-H(s d) [g_object_set_qdata s container-h as int-ptr! d] +#define GET-CONTAINER-H(s) [as integer! g_object_get_qdata s container-h] diff --git a/modules/view/backends/gtk3/gui.reds b/modules/view/backends/gtk3/gui.reds index a0d0e12c25..c8739ed3a9 100644 --- a/modules/view/backends/gtk3/gui.reds +++ b/modules/view/backends/gtk3/gui.reds @@ -1738,12 +1738,16 @@ OS-make-view: func [ winbox: gtk_box_new GTK_ORIENTATION_VERTICAL 0 gtk_container_add widget winbox + hMenu: null if menu-bar? menu window [ hMenu: gtk_menu_bar_new gtk_widget_show hMenu build-menu menu hMenu widget gtk_box_pack_start winbox hMenu no yes 0 + SET-CONTAINER-W(widget size/x) + SET-CONTAINER-H(widget size/y) ] + SET-HMENU(widget hMenu) gtk_widget_show winbox container: gtk_layout_new null null gtk_layout_set_size container size/x size/y diff --git a/modules/view/backends/gtk3/handlers.reds b/modules/view/backends/gtk3/handlers.reds index 0193dbbd7f..9e92609954 100644 --- a/modules/view/backends/gtk3/handlers.reds +++ b/modules/view/backends/gtk3/handlers.reds @@ -457,7 +457,16 @@ window-configure-event: func [ event [GdkEventConfigure!] widget [handle!] return: [integer!] + /local + x [integer!] + y [integer!] + offset [red-pair!] ][ + x: 0 y: 0 + gtk_window_get_position widget :x :y + offset: (as red-pair! get-face-values widget) + FACE_OBJ_OFFSET + offset/x: x + offset/y: y unless null? GET-STARTRESIZE(widget) [ SET-RESIZING(widget widget) ] @@ -479,15 +488,21 @@ window-size-allocate: func [ if null? GET-STARTRESIZE(widget) [ SET-STARTRESIZE(widget widget) ] - cont: GET-CONTAINER(widget) - w: gtk_widget_get_allocated_width cont - h: gtk_widget_get_allocated_height cont + + unless null? GET-HMENU(widget) [ + cont: GET-CONTAINER(widget) + w: gtk_widget_get_allocated_width cont + h: gtk_widget_get_allocated_height cont + SET-CONTAINER-W(widget w) + SET-CONTAINER-H(widget h) + ] + if any [ - sz/x <> w - sz/y <> h + sz/x <> rect/width + sz/y <> rect/height ][ - sz/x: w - sz/y: h + sz/x: rect/width + sz/y: rect/height either null? GET-RESIZING(widget) [ make-event widget 0 EVT_SIZE ][ From a5fb71afecd3792b75826b32523a11f22033d5c8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 13 Apr 2020 17:03:48 +0200 Subject: [PATCH 1318/3432] FIX: assertion failed on loading "usd$". --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 22158 -> 22135 bytes docs/lexer/lexer-states.txt | 2 +- runtime/lexer-transitions.reds | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index 32a6cea7ec..c6b0e39791 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -49,7 +49,7 @@ S_SIGN;T_WORD;T_WORD;S_NUMBER;S_NUMBER;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD S_DOTWORD;T_WORD;T_WORD;S_DOTDEC;S_DOTDEC;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;T_PATH;T_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;T_ERROR;S_DOTDEC;S_DOTDEC;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_DOTDEC;T_FLOAT;T_FLOAT;S_DOTDEC;S_DOTDEC;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_DOTDEC;S_DOTDEC;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_WORD_1ST;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_SLASH;T_ERROR;S_WORD;S_WORD;S_WORD;S_PERCENT;T_ERROR;T_ERROR;T_ERROR;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;S_WORD;S_WORD;T_ERROR;T_ERROR -S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD +S_WORD;T_WORD;T_WORD;S_WORD;S_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;S_WORD;S_WORDSET;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_PATH;T_WORD;T_WORD;S_WORD;S_WORD;T_ERROR;T_ERROR;T_WORD;S_EMAIL;S_WORD;S_MONEY_1ST;S_WORD;S_WORD;S_WORD;S_WORD;S_WORD;T_ERROR;T_WORD S_WORDSET;T_WORD;T_WORD;S_URL;S_URL;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_WORD;T_ERROR;S_URL;S_URL;S_URL;S_URL;T_WORD;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_ERROR;T_WORD S_PERCENT;T_WORD;T_WORD;T_ERROR;T_ERROR;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;S_PERCENT;T_ERROR;T_WORD;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_WORD S_URL;T_URL;T_URL;S_URL;S_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;T_URL;S_URL;T_ERROR;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;S_URL;T_URL;T_URL;T_ERROR;S_URL;S_URL;T_URL;T_URL;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;S_URL;S_URL;T_ERROR;T_URL diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 4ce2b39f6c529ee58dd4b379b8780ab188bf69a9..b8321481beb761c4e694ed9d1f95b486fed55032 100644 GIT binary patch delta 9478 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 npI?f|C7uIqYlpPPbVPQWt1nK^Z6N_WRJN|K4m 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

MGrMw^}nGKx0gUe^0{r+dQ2v zPwz5zy^El34Oa_{`!|kiV3z5W&3W#x^a-;F_1^Bu{nuv3mqmm{{FjA239ic;#~YhM z1jGHD+v8m6_x8Tw3JvL-du*r=r;b-V)_KEv;Dk}2?#~tK`ijgz9%A9j=cvvsel|#K zz`5Gbo#~gvKKSpARgU_2ew}QXovNR8NtW9zNoZ`YEBSCBhg195FCW^C0uHU$IkiPxBrw1JDyNpG>;b+LH35E7 zcU7~Vjn4Zl?^@Ta)v+M&&I!$qHqVLjoPBC}@a@BP$n?c}z~Q20ngTB@u|ut=J=Ue{ z|1+)3sF=%?ZpYpjZCeMUkjVs&S63e{sP%~D|kK8m4)?c|tCQD%0c>|Rz(;Me~F D`h~(y diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index 9210e9ffc1..d717de063c 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -346,7 +346,7 @@ S_START->not(delimit6)->S_WORD->not(delimit5)->S_WORD \ \->"@"|">"|","|"^"|"$"|":"|"'"|"#"->T_ERROR \ \->"/"->T_PATH - \->"$"->S_MONEY + \->"$"->S_MONEY_1ST \->","|"#"|"%"->T_ERROR diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 1c2ea41654..1a6d33f90f 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -165,7 +165,7 @@ Red/System [ 3232323F3F4B36323F30303232323F4B53533030535353535353533F3F53223F 3F30303F3F533F533F3F523F3F3F3F3F30303F3F3F3F533F3F3F3F3F3F3F3F3F 3F3F3F3F3F323232323232320F3F323232343F3F3F323F32323F32323F3F4B4B -32324B4B4B4B4B4B4B3F323332323232323232474B4B32323F3F4B3632253232 +32324B4B4B4B4B4B4B3F323332323232323232474B4B32323F3F4B3632243232 3232323F4B4B4B35354B4B4B4B4B4B4B35353535353535353535354B3F353535 354B35353535353535353F4B4B4B3F3F4B4B4B4B4B4B3F3F3F3F3F3F3F3F3F3F 3F3F4B3F3F3F343F4B3F3F3F3F3F3F3F3F3F4B5B5B35355B5B5B5B5B5B5B353F From d96e17c282f5b8d5bd895091435fe5c4d56dfc37 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 13 Apr 2020 17:37:46 +0200 Subject: [PATCH 1319/3432] FIX: fixes some crashes loading invalid hex literals. > load "-10h" > load "1'0000h" --- runtime/lexer.reds | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index a1d21e7b3e..1271711d76 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -1936,10 +1936,13 @@ lexer: context [ load-hex: func [lex [state!] s e [byte-ptr!] flags [integer!] load? [logic!] /local - int [red-integer!] - i index [integer!] - cb [byte!] + do-error [subroutine!] + int [red-integer!] + saved [byte-ptr!] + i index [integer!] + cb [byte!] ][ + do-error: [throw-error lex saved e TYPE_INTEGER] i: 0 cb: null-byte if e/1 <> #"h" [e: e - 1] ;-- when coming from number states @@ -1947,7 +1950,10 @@ lexer: context [ if all [any [s/1 < #"0" s/1 > #"9"] s + 1 >= e][ throw-error lex s e TYPE_WORD ] + saved: s + if any [s/1 = #"-" s/1 = #"+"][do-error] while [s < e][ + if s/1 = #"'" [do-error] index: 1 + as-integer s/1 ;-- converts the 2 hex chars using a lookup table cb: hexa-table/index ;-- decode one nibble at a time assert cb <> #"^(FF)" From 0532cd815fbe720fef62fb85363145787d2e6153 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 13 Apr 2020 18:09:28 +0200 Subject: [PATCH 1320/3432] FIX: NaN literal not loaded in the console. Issue description: https://gitter.im/red/bugs?at=5e938809cc370f0b07dd6e9c --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 22135 -> 22130 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index c6b0e39791..eb7bca3a74 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -28,7 +28,7 @@ S_DOTNUM;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_F S_DECIMAL;T_FLOAT;T_FLOAT;S_DECIMAL;S_DECIMAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;S_PAIR_1ST;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECEXP;T_FLOAT;T_FLOAT;S_DECEXP;S_DECEXP;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_EMAIL;T_ERROR;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT S_DECX;T_FLOAT;T_FLOAT;S_DECX;S_DECX;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT;T_ERROR;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;S_HEX_END2;T_ERROR;S_HEX;T_ERROR;S_HEX;T_FLOAT;T_ERROR;T_FLOAT;T_ERROR;T_ERROR;T_PERCENT;T_ERROR;T_ERROR;S_EMAIL;S_TUPLE;T_ERROR;S_DECEXP;S_DECEXP;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_FLOAT -S_DEC_SPECIAL;T_FLOAT;T_FLOAT;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP +S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;T_FLOAT_SP;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_FLOAT_SP;S_DEC_SPECIAL;S_DEC_SPECIAL;T_ERROR;T_FLOAT_SP S_TUPLE;T_TUPLE;T_TUPLE;S_TUPLE;S_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_TUPLE;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE;T_ERROR;T_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_TUPLE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_TUPLE S_DATE;T_DATE;T_DATE;S_DATE;S_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;T_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;S_DATE;T_DATE;T_DATE;S_DATE;T_DATE;S_DATE;S_DATE;T_ERROR;T_ERROR;S_DATE;T_ERROR;T_DATE S_TIME_1ST;T_ERROR;T_ERROR;S_TIME;S_TIME;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index b8321481beb761c4e694ed9d1f95b486fed55032..8d1d1945effe6720fecbfed60b611cbfddb7456f 100644 GIT binary patch delta 9681 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 delta 9665 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 C*184& diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 1a6d33f90f..0c80b84705 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -139,7 +139,7 @@ Red/System [ 533F3F53223F3F1B1B3F3F533F533F3F523F3F361E3F3F3F3F3F3F3F5353531B 1B535353535353533F3F533F3F3F3F3F3F3F533F533F3F3F3F3F363F3F1B1B3F 3F3F3F5353531C1C535353535353533F3F533F3F293F273F27533F533F3F523F -3F361E3F1B1B3F3F3F3F5353535354545454545454541D54541D1D1D1D1D1D1D +3F361E3F1B1B3F3F3F3F5354545354545454545454541D54541D1D1D1D1D1D1D 5454541D1D545454541D541D1D541D1D3F5455551E1E555555555555553F3F55 3F3F3F3F3F3F3F553F553F3F3F3F3F3F1E3F3F3F3F3F3F3F5556561F1F565656 565656561F1F1F1F1F1F1F1F1F1F1F1F561F1F3F1F56561F561F1F3F3F1F3F56 From 6acc92831be982ebf0d3dafce6cb3997b98c635c Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 14 Apr 2020 10:22:47 +0800 Subject: [PATCH 1321/3432] FIX: issue #4388 ([View] `show` draws outdated window content when resizing) --- modules/view/backends/windows/gui.reds | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/view/backends/windows/gui.reds b/modules/view/backends/windows/gui.reds index da69361975..578fd4ba2f 100644 --- a/modules/view/backends/windows/gui.reds +++ b/modules/view/backends/windows/gui.reds @@ -1708,6 +1708,7 @@ change-size: func [ ] type = area [update-scrollbars hWnd null] type = tab-panel [update-tab-contents hWnd FACE_OBJ_SIZE] + type = text [InvalidateRect hWnd null 1] ;-- issue #4388 true [0] ] ] From 7189855ba909a9cebc2eca38abb6d3397e1ab776 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 14 Apr 2020 10:42:10 +0800 Subject: [PATCH 1322/3432] FIX: issue #4384 ([View] `on-up` event locking on clicks). --- modules/view/backends/windows/base.reds | 2 +- modules/view/backends/windows/events.reds | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/view/backends/windows/base.reds b/modules/view/backends/windows/base.reds index 5a0b9e7d10..b2d083a6fe 100644 --- a/modules/view/backends/windows/base.reds +++ b/modules/view/backends/windows/base.reds @@ -460,7 +460,7 @@ BaseWndProc: func [ ] ] WM_LBUTTONDOWN [SetCapture hWnd return 0] - WM_LBUTTONUP [ReleaseCapture return 0] + ;WM_LBUTTONUP [ReleaseCapture return 0] WM_ERASEBKGND [return 1] ;-- drawing in WM_PAINT to avoid flicker WM_SIZE [ either (GetWindowLong hWnd wc-offset - 12) and BASE_FACE_D2D = 0 [ diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 9386d026cc..40a39dc5fd 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -1505,7 +1505,10 @@ process: func [ menu-ctx: null make-event msg flags EVT_LEFT_DOWN ] - WM_LBUTTONUP [make-event msg flags EVT_LEFT_UP] + WM_LBUTTONUP [ + if GetCapture <> null [ReleaseCapture] ;-- issue #4384 + make-event msg flags EVT_LEFT_UP + ] WM_RBUTTONDOWN [ if GetCapture <> null [return EVT_DISPATCH] lParam: msg/lParam From 9bd6f3a4196ae3001f825d42dc45203abedf76e6 Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 14 Apr 2020 11:13:36 +0800 Subject: [PATCH 1323/3432] FIX: issue #4380 ([View] [Regression] Mouse over started skipping the 1st event) --- modules/view/backends/windows/events.reds | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 40a39dc5fd..1668cc70da 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -32,7 +32,7 @@ flags-blk/head: 0 flags-blk/node: alloc-cells 4 flags-blk/header: TYPE_BLOCK -last-mouse-pt: 0 +last-mouse-pt: -1 char-keys: [ 1000C400h C0FF0080h E0FFFF7Fh 0000F7FFh 00000000h 3F000000h 1F000080h 00FC7F38h @@ -1489,6 +1489,7 @@ process: func [ EVT_DISPATCH ] WM_MOUSELEAVE [ + last-mouse-pt: -1 make-event msg EVT_FLAG_AWAY or key-flags EVT_OVER if msg/hWnd = hover-saved [hover-saved: null] EVT_DISPATCH From 1997b79676cd11f3c83cb17375afd74c9177e94b Mon Sep 17 00:00:00 2001 From: Xie Qingtian Date: Tue, 14 Apr 2020 11:38:18 +0800 Subject: [PATCH 1324/3432] FIX: better fix for issue #4384 --- modules/view/backends/windows/events.reds | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/view/backends/windows/events.reds b/modules/view/backends/windows/events.reds index 1668cc70da..1c53b01ce3 100644 --- a/modules/view/backends/windows/events.reds +++ b/modules/view/backends/windows/events.reds @@ -1447,6 +1447,7 @@ process: func [ y [integer!] track [tagTRACKMOUSEEVENT value] flags [integer!] + word [red-word!] ][ flags: decode-down-flags msg/wParam switch msg/msg [ @@ -1507,7 +1508,10 @@ process: func [ make-event msg flags EVT_LEFT_DOWN ] WM_LBUTTONUP [ - if GetCapture <> null [ReleaseCapture] ;-- issue #4384 + if all [msg/hWnd <> null msg/hWnd = GetCapture][ + word: (as red-word! get-face-values msg/hWnd) + FACE_OBJ_TYPE + if base = symbol/resolve word/symbol [ReleaseCapture] ;-- issue #4384 + ] make-event msg flags EVT_LEFT_UP ] WM_RBUTTONDOWN [ From b67e9bf09718bccdb4bc0a8533715ee4f7d1b74c Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 14 Apr 2020 17:51:03 +0200 Subject: [PATCH 1325/3432] FEAT: merges 'base and 'extra in currencies. --- environment/functions.red | 2 +- environment/system.red | 18 +++--------- runtime/datatypes/money.reds | 17 ++--------- tests/source/units/money-test.red | 48 +++++++++++++++---------------- 4 files changed, 30 insertions(+), 55 deletions(-) diff --git a/environment/functions.red b/environment/functions.red index 9b99132d44..f8b88dca23 100644 --- a/environment/functions.red +++ b/environment/functions.red @@ -892,7 +892,7 @@ do-file: function ["Internal Use Only" file [file! url!]][ block? header: code/2 list: select header 'currencies ][ - foreach c list [append system/locale/currencies/extra c] + foreach c list [append system/locale/currencies/list c] ] set/any 'code try/all code if file? file [change-dir saved] diff --git a/environment/system.red b/environment/system.red index b8315c3e09..8b0fabd950 100644 --- a/environment/system.red +++ b/environment/system.red @@ -314,7 +314,7 @@ system: context [ currencies: context [ ;-- ISO currencies + BTC, ETH, RED - base: [ + list: [ AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BTC BGN BHD BIF BMD BND BOB BRL BSD BTN BWP BYN BZD CAD CDF CHF CKD CLP CNY COP CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB ETH EUR FJD FKP FOK GBP GEL GGP GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS @@ -324,30 +324,20 @@ system: context [ SGD SHP SLL SLS SOS SRD SSP STN SYP SZL THB TJS TMT TND TOP TRY TTD TVD TWD TZS UAH UGX USD UYU UZS VES VND VUV WST CFA XAF XCD XOF CFP XPF YER ZAR ZMW ] - ;-- User-provided currencies - extra: [] - on-change*: func [word old new][ set-quiet in self word old cause-error 'script 'protected [] ] on-deep-change*: func [owner word target action new index part][ if any [ - word <> 'extra + word <> 'list not find [append appended] action not word? :new - find base new + all [action = 'append any [find list new 255 < length? list]] ;-- limit index to 8-bit 3 <> length? form new - all [ - action = 'append - any [ - find extra new - 255 < ((length? base) + length? extra) ;-- limit index to 8-bit - ] - ] ][cause-error 'script 'protected []] - if action = 'appended [set-slot-quiet back tail extra to word! uppercase form new] + if action = 'appended [set-slot-quiet back tail list to word! uppercase form new] ] ] ] diff --git a/runtime/datatypes/money.reds b/runtime/datatypes/money.reds index c2707f854b..5a05375437 100644 --- a/runtime/datatypes/money.reds +++ b/runtime/datatypes/money.reds @@ -177,14 +177,8 @@ money: context [ assert all [index >= 1 index <= FFh] ] - list: as red-series! #get system/locale/currencies/base + list: as red-series! #get system/locale/currencies/list walk - - if here < tail [return index] - - list: as red-series! #get system/locale/currencies/extra - walk - either here < tail [index][-1] ] @@ -193,17 +187,10 @@ money: context [ return: [red-word!] /local list [red-series!] - size [integer!] ][ assert all [index > 0 index <= FFh] - list: as red-series! #get system/locale/currencies/base - size: _series/length? list - if index > size [ - list: as red-series! #get system/locale/currencies/extra - index: index - size - ] - + list: as red-series! #get system/locale/currencies/list as red-word! _series/pick list index as red-value! list ] diff --git a/tests/source/units/money-test.red b/tests/source/units/money-test.red index 91a5751231..88bf8c1fc5 100644 --- a/tests/source/units/money-test.red +++ b/tests/source/units/money-test.red @@ -235,7 +235,7 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional --test-- "make-13" --assert error? try [make money! 'foo] --test-- "make-14" --assert error? try [make money! [123.45 6789]] --test-- "make-15" - --assert not error? try [foreach c system/locale/currencies/base [make money! c]] + --assert not error? try [foreach c system/locale/currencies/list [make money! c]] ===end-group=== ===start-group=== "form/mold" @@ -678,39 +678,37 @@ system/options/money-digits: 5 ;-- enforce molding of the whole fractional ===end-group=== ===start-group=== "currency list" - list: system/locale/currencies + cur: system/locale/currencies --test-- "custom-1" - --assert error? try [append list/base 'foo] - --assert error? try [clear list/base] - --assert error? try [reverse list/base] - --assert error? try [random list/base] - --assert error? try [list/base: none] - --assert error? try [list/base/1: none] - --assert error? try [put list/extra 'usd 'eur] + --assert error? try [clear cur/list] + --assert error? try [reverse cur/list] + --assert error? try [random cur/list] + --assert error? try [cur/list: none] + --assert error? try [cur/list/1: none] + --assert error? try [put cur/list 'usd 'eur] --test-- "custom-2" - --assert error? try [append list/extra none] - --assert error? try [append list/extra quote :foo] - --assert error? try [append list/extra 'foo!] - --assert error? try [append list/extra 'usd] - --assert error? try [list/extra: none] - --assert error? try [list/extra/1: none] + --assert error? try [append cur/list none] + --assert error? try [append cur/list quote :foo] + --assert error? try [append cur/list 'foo!] + --assert error? try [append cur/list 'usd] + --assert error? try [cur/list: none] + --assert error? try [cur/list/1: none] --test-- "custom-3" --assert error? try [make money! 'bar] - append list/extra 'bar + append cur/list 'bar --assert money? make money! 'bar --assert "BAR$0.00000" == mold/all make money! 'bar --assert error? try [make money! 'qux] - append list/extra 'QUX + append cur/list 'QUX --assert "-QUX$123.45678" == mold/all make money! [QUX -123 45678] --test-- "custom-4" - --assert error? try [append list/extra 'bar] - --assert error? try [append list/extra 'qux] - --assert error? try [clear list/extra] - --assert error? try [reverse list/extra] - --assert error? try [random list/extra] - --assert list/extra/1 = 'bar - --assert list/extra/2 = 'qux - --assert 2 = length? list/extra + --assert error? try [append cur/list 'bar] + --assert error? try [append cur/list 'qux] + --assert error? try [clear cur/list] + --assert error? try [reverse cur/list] + --assert error? try [random cur/list] + --assert (pick tail cur/list -2) = 'bar + --assert (pick tail cur/list -1) = 'qux ===end-group=== ===start-group=== "generated" From 55e1302faae545d15e2aae8762b92a6e157280b8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Tue, 14 Apr 2020 21:27:27 +0200 Subject: [PATCH 1326/3432] FIX: issue #4391 ([Compiler] Couldn't compile ~1800 words with `-r -d` flags anymore) Now, the compiler accounts for user words in root block size calculation. --- compiler.r | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler.r b/compiler.r index b0c336f62a..8cbc2560e2 100644 --- a/compiler.r +++ b/compiler.r @@ -69,6 +69,7 @@ red: context [ s-counter: 0 ;-- series suffix counter depth: 0 ;-- expression nesting level counter max-depth: 0 + root-slots: 0 ;-- extra root block slots counter booting?: none ;-- YES: compiling boot script nl: newline set 'float! 'float ;-- type names not defined in Rebol @@ -833,6 +834,7 @@ red: context [ repend sym-table [ to set-word! sym 'word/load mold any [original name] ] + root-slots: root-slots + 1 new-line skip tail sym-table -3 on ] ] @@ -4683,8 +4685,8 @@ red: context [ unless empty? sys-global [ process-calls/global sys-global ;-- lazy #call processing ] - slots: redbin/index + 3000 - if job/dev-mode? [slots: slots + 100'000] ;-- Cannot know how many slot will be needed by the app + slots: redbin/index + 3000 + root-slots + if job/dev-mode? [slots: slots + 100'000] ;-- Cannot know how many slots will be needed by the app change/only find out slots pos: third last out @@ -4769,7 +4771,7 @@ red: context [ process-calls/global sys-global ;-- lazy #call processing ] - change/only find out redbin/index + 3000 + change/only find out redbin/index + 3000 + root-slots change/only find last out

STbn#XXp!)bBs3!kFFcV6JG!g+I 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 U{Mv$qbPIl5!29i_7C*lIAM8Rz%K!iX literal 26668 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 diff --git a/docs/lexer/lexer-states.txt b/docs/lexer/lexer-states.txt index ea8c2270db..bd4a3a5f8d 100644 --- a/docs/lexer/lexer-states.txt +++ b/docs/lexer/lexer-states.txt @@ -114,6 +114,7 @@ C_SLASH : / C_BSLASH : \ C_LESSER : < C_GREATER : > +C_EQUAL : = C_PERCENT : % C_COMMA : , C_SEMICOL : ; @@ -265,8 +266,8 @@ S_START->"."->S_DOTWORD->digit->S_DOTDEC->digit|"e"|"E"|"+"|"-"|"'"->S_DOTDEC S_START->"<"->S_LESSER - \->delimit1|">"->T_WORD - \->"<"->T_ERROR + \->delimit1->T_WORD + \->">"|"<"|"="->S_WORD \->else->S_TAG \->dbl-quote->S_TAG_STR->not("^"|dbl-quote)->S_TAG_STR \ \->"^"->S_SKIP_STR2->*->S_TAG_STR diff --git a/runtime/lexer-transitions.reds b/runtime/lexer-transitions.reds index 866337a765..33fa5a67d0 100644 --- a/runtime/lexer-transitions.reds +++ b/runtime/lexer-transitions.reds @@ -177,66 +177,68 @@ Red/System [ 2E2E2E372D2E2E2E2E2E2E2C2E2E2E382D2E2E2E2E2E2E2E2E2E2E393A2E2E2E 2E2E2E2E2E2E2E3A2E2E2E2E2E2E2E2E2E2E2E2E } transitions: #{ -000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B06360136291E28 -28362B2B36350154010101010101010101010101010101010101010101010101 -010101010101010101013635020202020202020202023B020202020202020202 -0202020202020202020202020203020236360202020202020202020202020202 -0202020202020202020202020202020202020202020236350404040404040404 -3C3D040404040404040404040404040404040404040404040405040436360404 -0404040404040404040404040404040404040404040404040404040404040404 -040436353E3E07073E3E3E3E3E3E0A07073E070707070707070707070707073E -3E07070707070707363E3F3F07073F3F3F3F3F3F3607073F0707070707070707 -07070708073F3F07070707070707363F07070909363636363636363636363636 -3609090909363636363636363636363636363636363607070707363636363636 -3636363636363609090707363636363636363636363636363636363F0A0A0A0A -0A0A0A0A0A0A3F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A -363640400B0B404040404040400B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B40400B -0B0B0B0B0B0B364045451212113643360D360F12123612121212121212121236 -36123645451212121212121236450D0D0D0D363636363641363636360D0D0D0D -0D0D0D3636363636360E363636363636360D36360E0D0E0E0E0E0E0E0E0E0E0E -0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E36350F0F0F0F0F0F -0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F100F0F3642 -0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F -0F0F0F0F36361111111111441111111111111111111111111111111111111111 -1111111111111111111136364545121245454545454545121212121212121212 -12121212121212454512121212121212364547471313474747474747470C131A -1C195315163621193647364614472E1436361936363636474848151548484848 -4848481715361C36361515363648364836463648363636363636363636484848 -1515484848484848483636483636361515363648364836463636361836151536 -3636364848481616484848484848483636483636531521362148364836463636 -3618361515363636364848484849494949494949491749491717171717171749 -494917494949491749171749171736494A4A18184A4A4A4A4A4A4A36364A3636 -36363636364A364A363636363618363636363636364A4B4B19194B4B4B4B4B4B -4B1919191919191919191919194B194B194B4B194B19194B3619364B36361B1B -3636363636363636363636363636363636363636363636363636363636363636 -36364D4D1B1B4D4D4D4D4D4D4D36361B363636363636364D364D3636364D361B -363636363636364D36361D1D3636363636363636363636363636363636363636 -36363636363636363636363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D -1D36364C364C3636364C361D363636363636364C36361F1F3636363636363636 -36363636363636363636363636363636363636363636363636364E4E1F1F4E4E -4E4E4E4E4E4E1F4E363636363636364E364E3636364E36203636363636363635 -4E4E20204E4E4E4E4E4E4E4E204E363636363636364E364E3636364E36363636 -3636363636353E3E21213E3E3E3E3E3E3E362B2C2B2B532B212B21523E2B2B36 -363E2E2B1F2B2B2B2B2B363E3E3E23233E3E3E3E3E3E3E23233E232323232323 -232323363E23233E3E23232323232323363E2323232323232323232324232326 -232323232323232323234F232323232323232323232336362424242424242424 -2424232424242424242424242424242424242424242424242425242436362424 -2424242424242424242424242424242424242424242424242424242424242424 -2424363626262626262626262626262626232626262626262626262626262626 -2626262626262626363626262626262626262626262626262626262626262626 -262626262626262626262626262636363E3E13133E3E3E3E3E3E3E36362B2B2B -2B2B2B2B2B2B3E362B362B3E2B292B2B2B362B2B363E3E3E2A2A3E3E3E3E3E3E -3E362B2C2B2B2B2A2A2B2B523E2B2B36363E2E2B362A2A2B2B2B363E48482A2A -484848484848483636481C36362A2A3636483648364636363636362A2A363636 -36483E3E2B2B3E3E3E3E3E3E3E362B2C2B2B2B2B2B2B2B523E2B2B36363E2E2B -1F2B2B2B2B2B363E3E3E2D2D3E3E3E3E3E3E3E2D2D2D2D2D2D2D2D2D2D2D3E36 -2D2D2D3E2D2D2D2D2D2D2D2D363E50502D2D505050505050502D362D2D2D2D2D -2D2D2D2D5050362D50502D2D362D2D362D2D365051512E2E5151515151515136 -36362E2E2E2E2E2E2E515151362E3651362E362E2E362E2E3651363630303636 -393A36360232313131313131313131363622313636362E313633333631313636 -47473030474747474747473613471C363615153636473647364614472E143636 -3636363636473E3E31313E3E3E3E3E3E3E36313E313131313131313E3E313136 -363E2E31363131313131363E454512121136363636360F121236121212121212 -1212123636123645451212121212121236453E3E30303E3E3E3E3E3E3E36362B -2B2B2B2B2B2B2B2B3E362B362B3E2B2B2B2B2B362B2B363E +000013133738393A3C36020C2B2B2B2B2B2B212B210B36222B2B06360136291E +2828362B2B363501540101010101010101010101010101010101010101010101 +0101010101010101010101013635020202020202020202023B02020202020202 +0202020202020202020202020202020203020236360202020202020202020202 +0202020202020202020202020202020202020202020202020202363504040404 +040404043C3D0404040404040404040404040404040404040404040404040504 +0436360404040404040404040404040404040404040404040404040404040404 +040404040404040436353E3E07073E3E3E3E3E3E0A07073E0707070707070707 +0707070707073E3E07070707070707363E3F3F07073F3F3F3F3F3F3607073F07 +070707070707070707070708073F3F07070707070707363F0707090936363636 +3636363636363636360909090936363636363636363636363636363636363607 +0707073636363636363636363636363609090707363636363636363636363636 +36363636363F0A0A0A0A0A0A0A0A0A0A3F0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A +0A0A0A0A0A0A0A0A0A0A0A363640400B0B404040404040400B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B40400B0B0B0B0B0B0B364045451212113643360D360F12 +1236121212121212121212363636123645451212121212121236450D0D0D0D36 +3636363641363636360D0D0D0D0D0D0D363636363636360E363636363636360D +36360E0D0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E +0E0E0E0E0E0E0E36350F0F0F0F0F0F0F0F0F0F420F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F100F0F36420F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F +0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F3636111111111144111111 +1111111111111111111111111111111111111111111111111111111136364545 +1212454545454545451212121212121212121212121212121212454512121212 +121212364547471313474747474747470C131A1C195315163621193647363646 +14472E14363619363636364748481515484848484848481715361C3636151536 +3648364836364636483636363636363636364848481515484848484848483636 +4836363615153636483648363646363636183615153636363648484816164848 +4848484848363648363653152136214836483636463636361836151536363636 +4848484849494949494949491749491717171717171749494917174949494917 +49171749171736494A4A18184A4A4A4A4A4A4A36364A363636363636364A364A +36363636363618363636363636364A4B4B19194B4B4B4B4B4B4B191919191919 +1919191919194B19194B194B4B194B19194B3619364B36361B1B363636363636 +36363636363636363636363636363636363636363636363636363636364D4D1B +1B4D4D4D4D4D4D4D36361B363636363636364D364D363636364D361B36363636 +3636364D36361D1D363636363636363636363636363636363636363636363636 +36363636363636363636364C4C1D1D4C4C4C4C4C4C4C36364C3636361D1D3636 +4C364C363636364C361D363636363636364C36361F1F36363636363636363636 +363636363636363636363636363636363636363636363636364E4E1F1F4E4E4E +4E4E4E4E4E1F4E363636363636364E364E363636364E36203636363636363635 +4E4E20204E4E4E4E4E4E4E4E204E363636363636364E364E363636364E363636 +363636363636353E3E21213E3E3E3E3E3E3E362B2C2B2B532B212B21523E2B2B +2B36363E2E2B1F2B2B2B2B2B363E3E3E23233E3E3E3E3E3E3E23233E23232323 +23232323232B2B2B23233E3E23232323232323363E2323232323232323232324 +232326232323232323232323234F232323232323232323232323363624242424 +2424242424242324242424242424242424242424242424242424242424242524 +2436362424242424242424242424242424242424242424242424242424242424 +2424242424242424363626262626262626262626262626232626262626262626 +2626262626262626262626262626263636262626262626262626262626262626 +2626262626262626262626262626262626262626262636363E3E13133E3E3E3E +3E3E3E36362B2B2B2B2B2B2B2B2B3E362B2B362B3E2B292B2B2B362B2B363E3E +3E2A2A3E3E3E3E3E3E3E362B2C2B2B2B2A2A2B2B523E2B2B2B36363E2E2B362A +2A2B2B2B363E48482A2A484848484848483636481C36362A2A36364836483636 +4636363636362A2A36363636483E3E2B2B3E3E3E3E3E3E3E362B2C2B2B2B2B2B +2B2B523E2B2B2B36363E2E2B1F2B2B2B2B2B363E3E3E2D2D3E3E3E3E3E3E3E2D +2D2D2D2D2D2D2D2D2D2D3E362D2D2D2D3E2D2D2D2D2D2D2D2D363E50502D2D50 +5050505050502D362D2D2D2D2D2D2D2D2D505036362D50502D2D362D2D362D2D +365051512E2E515151515151513636362E2E2E2E2E2E2E51515136362E365136 +2E362E2E362E2E3651363630303636393A363602323131313131313131313636 +2231313636362E31363333363131363647473030474747474747473613471C36 +361515363647364736364614472E1436363636363636473E3E31313E3E3E3E3E +3E3E36313E313131313131313E3E31313136363E2E31363131313131363E4545 +12121136363636360F1212361212121212121212123636361236454512121212 +12121236453E3E30303E3E3E3E3E3E3E36362B2B2B2B2B2B2B2B2B3E362B2B36 +2B3E2B2B2B2B2B362B2B363E } diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 68f0b6cb06..8574610bca 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -65,19 +65,20 @@ lexer: context [ C_BSLASH ;-- 22 C_LESSER ;-- 23 C_GREATER ;-- 24 - C_PERCENT ;-- 25 - C_COMMA ;-- 26 - C_SEMICOL ;-- 27 - C_AT ;-- 28 - C_DOT ;-- 29 - C_MONEY ;-- 30 - C_PLUS ;-- 31 - C_MINUS ;-- 32 - C_CARET ;-- 33 - C_BIN ;-- 34 - C_WORD ;-- 35 - C_ILLEGAL ;-- 36 - C_EOF ;-- 37 + C_EQUAL ;-- 25 + C_PERCENT ;-- 26 + C_COMMA ;-- 27 + C_SEMICOL ;-- 28 + C_AT ;-- 29 + C_DOT ;-- 30 + C_MONEY ;-- 31 + C_PLUS ;-- 32 + C_MINUS ;-- 33 + C_CARET ;-- 34 + C_BIN ;-- 35 + C_WORD ;-- 36 + C_ILLEGAL ;-- 37 + C_EOF ;-- 38 ] #enum date-char-classes! [ @@ -114,7 +115,7 @@ lexer: context [ line-table: #{ 0001000000000000000000000000000000000000000000000000000000000000 - 000000000000 + 0000000000000000 } skip-table: #{ @@ -124,8 +125,8 @@ lexer: context [ } path-ending: #{ - 0101000001010101010001000001000000000000000000010000000100000000 - 000000000101 + 0101000001010101010001000001000000000000000000010000000001000000 + 00000000000101 } bin16-classes: #{ @@ -241,7 +242,7 @@ lexer: context [ (C_COLON or C_FLAG_COLON) ;-- 3A : C_SEMICOL ;-- 3B ; C_LESSER ;-- 3C < - C_WORD ;-- 3D = + C_EQUAL ;-- 3D = C_GREATER ;-- 3E > C_WORD ;-- 3F ? C_AT ;-- 40 @ @@ -1622,8 +1623,8 @@ lexer: context [ scan-tokens lex - slots: (as-integer lex/tail - lex/head) >> 4 - store-any-block dst lex/head slots TYPE_BLOCK + slots: (as-integer lex/tail - lex/buffer) >> 4 + store-any-block dst lex/buffer slots TYPE_BLOCK depth: depth - 1 if zero? depth [root-state: null] From 994c7a8c78db4419959a7e33a6b01c2a33e32db5 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 10 Nov 2019 12:23:57 +0100 Subject: [PATCH 0432/3432] FIX: lexer crashing on GC pass. --- runtime/lexer.reds | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/runtime/lexer.reds b/runtime/lexer.reds index 8574610bca..b22016dbf1 100644 --- a/runtime/lexer.reds +++ b/runtime/lexer.reds @@ -421,11 +421,14 @@ lexer: context [ ] mark-buffers: func [/local s [state!]][ - s: root-state - until [ - collector/mark-values s/buffer s/tail - s: s/next - null? s + if root-state <> null [ + s: root-state + until [ + assert s/buffer < s/tail + collector/mark-values s/buffer s/tail + s: s/next + null? s + ] ] ] From c023bb6fb1c127045d1edc293416a8326a93dcd8 Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Sun, 10 Nov 2019 22:42:50 +0100 Subject: [PATCH 0433/3432] FEAT: preliminary support for `transcode` native. --- environment/natives.red | 14 +++++++++++ runtime/macros.reds | 1 + runtime/natives.reds | 52 +++++++++++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/environment/natives.red b/environment/natives.red index 1d2d15cae7..d480878c75 100644 --- a/environment/natives.red +++ b/environment/natives.red @@ -907,3 +907,17 @@ recycle: make native! [[ ] #get-definition NAT_RECYCLE ] + +transcode: make native! [[ + "Translates UTF-8 binary source to values. Returns one or several values in a block" + src [binary!] "UTF-8 input buffer" + /one "Translates and returns the first value only" + /only "Returns the position after the next value" + /trap "Traps errors, returns [[values] position error]" + /part "Translates only part of the input buffer" + length [integer! binary!] "Length in bytes or tail position" + /into "Optionally provides an output block" + dst [block! none!] + ] + #get-definition NAT_TRANSCODE +] diff --git a/runtime/macros.reds b/runtime/macros.reds index c0a17e50c4..f9a5b01bd5 100644 --- a/runtime/macros.reds +++ b/runtime/macros.reds @@ -247,6 +247,7 @@ Red/System [ NAT_COMPRESS NAT_DECOMPRESS NAT_RECYCLE + NAT_TRANSCODE ] #enum math-op! [ diff --git a/runtime/natives.reds b/runtime/natives.reds index 257ff80f9f..374f005bd7 100644 --- a/runtime/natives.reds +++ b/runtime/natives.reds @@ -2095,21 +2095,6 @@ natives: context [ TYPE_OBJECT [--NOT_IMPLEMENTED--] ] ] - - recycle*: func [ - check? [logic!] - on? [integer!] - off? [integer!] - ][ - #typecheck [on? off?] - - case [ - on? > -1 [collector/active?: yes] - off? > -1 [collector/active?: no] - true [collector/do-mark-sweep] - ] - unset/push-last - ] to-local-file*: func [ check? [logic!] @@ -2727,6 +2712,42 @@ natives: context [ s/tail: as cell! (buf + dstlen) stack/set-last as red-value! dst ] + + + recycle*: func [ + check? [logic!] + on? [integer!] + off? [integer!] + ][ + #typecheck [on? off?] + + case [ + on? > -1 [collector/active?: yes] + off? > -1 [collector/active?: no] + true [collector/do-mark-sweep] + ] + unset/push-last + ] + + transcode*: func [ + check? [logic!] + one? [logic!] + only? [logic!] + trap? [logic!] + part? [logic!] + into? [logic!] + /local + bin [red-binary!] + slot [red-value!] + ][ + #typecheck [one? only? part?] + + bin: as red-binary! stack/arguments + slot: stack/push* + lexer/scan slot binary/rs-head bin binary/rs-length? bin + + stack/set-last slot + ] ;--- Natives helper functions --- @@ -3345,6 +3366,7 @@ natives: context [ :compress* :decompress* :recycle* + :transcode* ] ] From 0a70d7c77639d040a356c75507554bf2706b4bbb Mon Sep 17 00:00:00 2001 From: Nenad Rakocevic Date: Mon, 11 Nov 2019 17:22:35 +0100 Subject: [PATCH 0434/3432] FIX: regression in base64 scanning in lexer. --- docs/lexer/lexer-FSM.csv | 2 +- docs/lexer/lexer-FSM.xlsx | Bin 26923 -> 26916 bytes runtime/lexer-transitions.reds | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lexer/lexer-FSM.csv b/docs/lexer/lexer-FSM.csv index c6e669047f..396a6f56e8 100644 --- a/docs/lexer/lexer-FSM.csv +++ b/docs/lexer/lexer-FSM.csv @@ -12,7 +12,7 @@ S_FILE_HEX2;S_FILE;S_FILE;S_FILE;S_FILE;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR; S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_FILE;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;S_FILE_STR;T_ERROR;T_ERROR S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_REFINE;T_REFINE;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;S_SLASH;T_ERROR;T_REFINE S_SHARP;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_CONSTRUCT;T_ERROR;T_MAP_OP;T_ERROR;S_BINARY;T_ERROR;S_CHAR;S_ISSUE;S_ISSUE;T_ERROR;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ERROR;T_ERROR;S_ISSUE;T_ERROR;T_ISSUE;T_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;S_ISSUE;T_ERROR;T_ISSUE -S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR +S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;S_BINARY;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR;S_LINE_CMT2;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;T_ERROR;S_BINARY;T_ERROR;T_ERROR S_LINE_CMT2;S_LINE_CMT2;S_BINARY;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;S_LINE_CMT2;T_ERROR;T_EOF S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_SKIP_CHAR;S_CHAR;S_CHAR;T_ERROR;T_CHAR S_SKIP_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;S_CHAR;T_ERROR;T_ERROR diff --git a/docs/lexer/lexer-FSM.xlsx b/docs/lexer/lexer-FSM.xlsx index 34a76c9af88fb328bd5d955f9f9c46c69b86d89e..f47b928a25b968c0cd22034f7ce9b50fe6d0ad50 100644 GIT binary patch literal 26916 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