Skip to content

Commit

Permalink
Updates to account for FUNC_BODY(), BLANK
Browse files Browse the repository at this point in the history
This syncs Ren-Cpp and Ren Garden with the master branch of Ren-C after
a somewhat long period of drift.  The main change is an improvement
surrounding the amount of information that can be "stowed" with a
customized native function.

Previously, function REBVALs (4 pointers in size) contained header bits,
a spec array pointer, a paramlist array pointer, and a native C
function pointer.  This put the burden on Ren-Cpp to find a way to
locate the C++ std::function implementing its extensions based on the
information passed in--because the raw native function pointer would
not be enough.  That led to the ugly lambda identity trick of
REN_STD_FUNCTION.

(The decision was made at a time when no assumptions were being made
about what was being passed *other* than the function pointer.  Today's
decision-making environment is much different than the one which guided
that choice.)

This gets rid of REN_STD_FUNCTION, instead taking advantage of the
ability to stow arbitrary values along with the function via FUNC_BODY()
when the instance is created.

It also does the change from NONE => BLANK, as NONE is being retaken
to mean "none of the expressions in the block are true".
  • Loading branch information
hostilefork committed Jun 24, 2016
1 parent 8b2d705 commit b0ce9b0
Show file tree
Hide file tree
Showing 21 changed files with 286 additions and 322 deletions.
2 changes: 0 additions & 2 deletions examples/function-1.cpp
Expand Up @@ -11,8 +11,6 @@ int main(int, char **) {
"{Demonstration of the C++ Extension mechanism}"
"blk [block!] {The block to print}",

REN_STD_FUNCTION,

[](Block const & blk) -> Logic {
print("blk is", blk);
return true;
Expand Down
2 changes: 1 addition & 1 deletion examples/workbench/evaluator.cpp
Expand Up @@ -88,7 +88,7 @@ void EvaluatorWorker::doWork(
//
// https://github.com/metaeducation/ren-garden/issues/17

if (t.value() == nullopt || is<None>(t.value())) {
if (t.value() == nullopt || is<Blank>(t.value())) {
qApp->exit(0);
}
else if (is<Integer>(t.value())) {
Expand Down
8 changes: 2 additions & 6 deletions examples/workbench/renconsole.cpp
Expand Up @@ -88,8 +88,6 @@ RenConsole::RenConsole (EvaluatorWorker * worker, QWidget * parent) :
" {block to execute or other instruction (see documentation)}"
"/meta {Interpret in 'meta mode' for controlling the dialect}",

REN_STD_FUNCTION,

[this](AnyValue const & arg, AnyValue const & meta) -> optional<AnyValue>
{
if (not meta) {
Expand Down Expand Up @@ -174,15 +172,15 @@ RenConsole::RenConsole (EvaluatorWorker * worker, QWidget * parent) :
if (not bannerPrinted) {
printBanner();
bannerPrinted = true;
return {none};
return {blank};
}
}

// Meta protocol may query you for lit-word features you
// do not support, so don't raise an error if you don't
// know what it is... just return none.

return {none};
return {blank};
}

if (is<Block>(arg)) {
Expand Down Expand Up @@ -250,8 +248,6 @@ RenConsole::RenConsole (EvaluatorWorker * worker, QWidget * parent) :
"{word to watch or other legal parameter, see documentation)} "
"/dialect {Interpret as instruction to WATCH vs. raw value} ",

REN_STD_FUNCTION,

[this](
AnyValue const & argOriginal, AnyValue const & dialect
)
Expand Down
15 changes: 3 additions & 12 deletions examples/workbench/renshell.cpp
Expand Up @@ -521,23 +521,14 @@ RenShell::RenShell (AnyContext const & helpers, QObject * parent) :

shellFunction = Function::construct(
"{SHELL dialect for interacting with an OS shell process}"
"'arg [word! lit-word! block! paren! string! none!]"
"'arg [<end> word! lit-word! block! paren! string!]"
" {block in dialect or other instruction (see documentation)}"
"/meta {Interpret in 'meta mode' for controlling the dialect}",

REN_STD_FUNCTION,

[this, worker](optional<AnyValue> const & arg, AnyValue const & meta)
-> optional<AnyValue>
{
if (is<None>(arg)) {
//
// Used to use the "unset quoting" trick to do variadic, but
// now that's been removed. Real variadic handling has not
// been added to Ren-C, and would need `ren::Varargs`.
//
// For now, just signal that with NONE!
//
if (not arg) {
runtime("console quote", shellFunction);
return nullopt;
}
Expand Down Expand Up @@ -583,7 +574,7 @@ RenShell::RenShell (AnyContext const & helpers, QObject * parent) :
// Meta protocol may ask you for things you don't know about,
// so gracefully ignore them.
if (is<LitWord>(arg))
return {none};
return {blank};

if (not is<Block>(arg))
throw Error {"Unknown meta command"};
Expand Down
18 changes: 9 additions & 9 deletions examples/workbench/scripts/combine.reb
Expand Up @@ -62,7 +62,7 @@ combine: function [
out: make string! 10 ;; No good heuristic for string size yet
]

unless set? 'delimiter [delimiter: none]
unless set? 'delimiter [delimiter: _]

unless any-function? :delimiter [
unless block? delimiter [
Expand Down Expand Up @@ -91,7 +91,7 @@ combine: function [
set/any quote temp: delimiter depth
if all [
value? 'temp
(not none? temp) or (block? out)
(not blank? temp) or (block? out)
][
out: append out temp
]
Expand All @@ -101,7 +101,7 @@ combine: function [
]


; Do evaluation of the block until a non-none evaluation result
; Do evaluation of the block until a non-blank evaluation result
; is found... the limit is hit...or end of the input is reached.

original: block
Expand All @@ -110,7 +110,7 @@ combine: function [
all [
not tail? block
any [
none? part
blank? part
either integer? limit [
0 <= limit: limit - 1
][
Expand All @@ -124,7 +124,7 @@ combine: function [
; in this case that is okay since block is a parameter and won't
; leak as a global

set/any (quote value:) either safe [
value: either safe [
either any [word? block/1 path? block/1] [
get/any first back (block: next block)
][
Expand Down Expand Up @@ -166,14 +166,14 @@ combine: function [
case [
; Ignore voids (precedent: ANY, ALL, COMPOSE)

void? :value []
not set? 'value []


; Skip all nones. This is suggested for COMPOSE as well:
; Skip all blanks. This is suggested for COMPOSE as well:
;
; http://curecode.org/rebol3/ticket.rsp?id=2198

none? :value []
blank? :value []


; If a function or PAREN! are returned, then evaluate it at
Expand All @@ -193,7 +193,7 @@ combine: function [

any [
any-function? :value
paren? value
group? value
][
if safe [
do make error! {
Expand Down
18 changes: 9 additions & 9 deletions examples/workbench/scripts/helpers/autocomplete.reb
Expand Up @@ -85,20 +85,20 @@ Rebol [
;

try-get-scope-from-path: function [path [path!]] [
obj: none
obj: _

for-each element path [

; only consider paths made up of words...

unless word? :element [return none]
unless word? :element [return _]


; If we have an object in progress, look up the word in it,
; otherwise get the word.

value: either obj [
unless in obj element [return none]
unless in obj element [return _]
select obj element
][
get/any element
Expand All @@ -118,7 +118,7 @@ try-get-scope-from-path: function [path [path!]] [
;
; How did it know?

unless object? :value [return none]
unless object? :value [return _]

obj: value
]
Expand All @@ -143,7 +143,7 @@ fake-context-from-function: function [fun [any-function!]] [
append spec to-set-word word
]
]
append spec none
append spec _
return has spec
]

Expand Down Expand Up @@ -175,7 +175,7 @@ autocomplete-helper: function [
; asking to have completed? :-/ Leave it alone for now.

if index = 1 [
return reduce [text index none]
return reduce [text index _]
]


Expand Down Expand Up @@ -270,8 +270,8 @@ autocomplete-helper: function [
; to the current complete "state" embodied by the selection, and want
; whichever one is after that instead.

first-candidate-word: none
first-candidate-ctx: none
first-candidate-word: _
first-candidate-ctx: _
take-next: false

for-each ctx adjusted-contexts [
Expand Down Expand Up @@ -374,5 +374,5 @@ autocomplete-helper: function [

; Didn't find anything, just return what we were given...
;
return reduce [text index none]
return reduce [text index _]
]
8 changes: 4 additions & 4 deletions include/rencpp/atoms.hpp
Expand Up @@ -84,16 +84,16 @@ class Atom : public AnyValue {
// probably never find much of a reason to use it.
//

constexpr AnyValue::none_t none {AnyValue::none_t::init{}};
constexpr AnyValue::blank_t blank {AnyValue::blank_t::init{}};

class None : public Atom {
class Blank : public Atom {
protected:
friend class AnyValue;
None (Dont) noexcept : Atom (Dont::Initialize) {}
Blank (Dont) noexcept : Atom (Dont::Initialize) {}
static bool isValid(RenCell const & cell);

public:
explicit None (Engine * engine = nullptr) : Atom (none, engine) {}
explicit Blank (Engine * engine = nullptr) : Atom (blank, engine) {}
};


Expand Down

0 comments on commit b0ce9b0

Please sign in to comment.