Moved logic to global.
jump to
@@ -16,7 +16,6 @@ min_stack,
min_seq, min_dict, min_str, - min_logic, min_time, min_sys, min_io,@@ -43,7 +42,6 @@ i.global_module
i.stack_module i.seq_module i.dict_module - i.logic_module i.str_module i.time_module i.sys_module
@@ -5,6 +5,7 @@ sequtils,
json, parseopt, algorithm, + math, streams, random, bitops,@@ -22,6 +23,28 @@ ../core/parser,
../core/value, ../core/interpreter, ../core/utils + +proc floatCompare(n1, n2: MinValue): bool = + let + a: float = if n1.kind != minFloat: n1.intVal.float else: n1.floatVal + b: float = if n2.kind != minFloat: n2.intVal.float else: n2.floatVal + if a.classify == fcNan and b.classify == fcNan: + return true + else: + const + FLOAT_MIN_NORMAL = 2e-1022 + FLOAT_MAX_VALUE = (2-2e-52)*2e1023 + epsilon = 0.00001 + let + absA = abs(a) + absB = abs(b) + diff = abs(a - b) + if a == b: + return true + elif a == 0 or b == 0 or diff < FLOAT_MIN_NORMAL: + return diff < (epsilon * FLOAT_MIN_NORMAL) + else: + return diff / min((absA + absB), FLOAT_MAX_VALUE) < epsilon proc processTokenValue(v: string, t: MinTokenKind): string = case t:@@ -1473,6 +1496,221 @@
def.symbol("bitparity") do (i: In): let args = i.expect("int") i.push (args[0].intVal.parityBits).newVal + + # Logic Operations + + def.symbol(">") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n2, n1 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal > n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float) + else: + i.push newVal(n1.strVal > n2.strVal) + + def.symbol(">=") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n2, n1 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal >= n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) + else: + i.push newVal(n1.strVal >= n2.strVal) + + def.symbol("<") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n1, n2 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal > n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float) + else: + i.push newVal(n1.strVal > n2.strVal) + + def.symbol("<=") do (i: In): + var n1, n2: MinValue + i.reqTwoNumbersOrStrings n1, n2 + if n1.isNumber and n2.isNumber: + if n1.isInt and n2.isInt: + i.push newVal(n1.intVal >= n2.intVal) + elif n1.isInt and n2.isFloat: + i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isFloat: + i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) + elif n1.isFloat and n2.isInt: + i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) + else: + i.push newVal(n1.strVal >= n2.strVal) + + def.symbol("==") do (i: In): + var n1, n2: MinValue + let vals = i.expect("a", "a") + n1 = vals[0] + n2 = vals[1] + if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: + i.push newVal(floatCompare(n1, n2)) + else: + i.push newVal(n1 == n2) + + def.symbol("!=") do (i: In): + var n1, n2: MinValue + let vals = i.expect("a", "a") + n1 = vals[0] + n2 = vals[1] + if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: + i.push newVal(not floatCompare(n1, n2)) + i.push newVal(not (n1 == n2)) + + def.symbol("not") do (i: In): + let vals = i.expect("bool") + let b = vals[0] + i.push newVal(not b.boolVal) + + def.symbol("and") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal and b.boolVal) + + def.symbol("expect-all") do (i: In): + let vals = i.expect("quot") + let q = vals[0] + var c = 0 + for v in q.qVal: + if not v.isQuotation: + raiseInvalid("A quotation of quotations is expected") + var vv = v + i.dequote vv + let r = i.pop + c.inc() + if not r.isBool: + raiseInvalid("Quotation #$# does not evaluate to a boolean value" % [$c]) + if not r.boolVal: + i.push r + return + i.push true.newVal + + def.symbol("or") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal or b.boolVal) + + def.symbol("expect-any") do (i: In): + let vals = i.expect("quot") + let q = vals[0] + var c = 0 + for v in q.qVal: + if not v.isQuotation: + raiseInvalid("A quotation of quotations is expected") + var vv = v + i.dequote vv + let r = i.pop + c.inc() + if not r.isBool: + raiseInvalid("Quotation #$# does not evaluate to a boolean value" % [$c]) + if r.boolVal: + i.push r + return + i.push false.newVal + + def.symbol("xor") do (i: In): + let vals = i.expect("bool", "bool") + let a = vals[0] + let b = vals[1] + i.push newVal(a.boolVal xor b.boolVal) + + def.symbol("string?") do (i: In): + if i.pop.kind == minString: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("integer?") do (i: In): + if i.pop.kind == minInt: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("float?") do (i: In): + if i.pop.kind == minFloat: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("null?") do (i: In): + if i.pop.kind == minNull: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("number?") do (i: In): + let a = i.pop + if a.kind == minFloat or a.kind == minInt: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("boolean?") do (i: In): + if i.pop.kind == minBool: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("quotation?") do (i: In): + if i.pop.kind == minQuotation: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("quoted-symbol?") do (i: In): + let item = i.pop + if item.kind == minQuotation and item.qVal.len == 1 and item.qVal[0].kind == minSymbol: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("stringlike?") do (i: In): + if i.pop.isStringLike: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("dictionary?") do (i: In): + if i.pop.isDictionary: + i.push true.newVal + else: + i.push false.newVal + + def.symbol("type?") do (i: In): + let vals = i.expect("'sym", "a") + let t = vals[0].getString + let v = vals[1] + let res = i.validateValueType(t, v) + i.push res.newVal + + def.symbol("&&") do (i: In): + i.pushSym("expect-all") + + def.symbol("||") do (i: In): + i.pushSym("expect-any") # Sigils
@@ -1,247 +0,0 @@
-import - std/[math, strutils] -import - ../core/parser, - ../core/value, - ../core/interpreter, - ../core/utils - -proc floatCompare(n1, n2: MinValue): bool = - let - a: float = if n1.kind != minFloat: n1.intVal.float else: n1.floatVal - b: float = if n2.kind != minFloat: n2.intVal.float else: n2.floatVal - if a.classify == fcNan and b.classify == fcNan: - return true - else: - const - FLOAT_MIN_NORMAL = 2e-1022 - FLOAT_MAX_VALUE = (2-2e-52)*2e1023 - epsilon = 0.00001 - let - absA = abs(a) - absB = abs(b) - diff = abs(a - b) - if a == b: - return true - elif a == 0 or b == 0 or diff < FLOAT_MIN_NORMAL: - return diff < (epsilon * FLOAT_MIN_NORMAL) - else: - return diff / min((absA + absB), FLOAT_MAX_VALUE) < epsilon - -proc logic_module*(i: In) = - let def = i.define() - - def.symbol(">") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n2, n1 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal > n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float) - else: - i.push newVal(n1.strVal > n2.strVal) - - def.symbol(">=") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n2, n1 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal >= n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) - else: - i.push newVal(n1.strVal >= n2.strVal) - - def.symbol("<") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n1, n2 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal > n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float) - else: - i.push newVal(n1.strVal > n2.strVal) - - def.symbol("<=") do (i: In): - var n1, n2: MinValue - i.reqTwoNumbersOrStrings n1, n2 - if n1.isNumber and n2.isNumber: - if n1.isInt and n2.isInt: - i.push newVal(n1.intVal >= n2.intVal) - elif n1.isInt and n2.isFloat: - i.push newVal(n1.intVal.float > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isFloat: - i.push newVal(n1.floatVal > n2.floatVal or floatCompare(n1, n2)) - elif n1.isFloat and n2.isInt: - i.push newVal(n1.floatVal > n2.intVal.float or floatCompare(n1, n2)) - else: - i.push newVal(n1.strVal >= n2.strVal) - - def.symbol("==") do (i: In): - var n1, n2: MinValue - let vals = i.expect("a", "a") - n1 = vals[0] - n2 = vals[1] - if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: - i.push newVal(floatCompare(n1, n2)) - else: - i.push newVal(n1 == n2) - - def.symbol("!=") do (i: In): - var n1, n2: MinValue - let vals = i.expect("a", "a") - n1 = vals[0] - n2 = vals[1] - if (n1.kind == minFloat or n2.kind == minFloat) and n1.isNumber and n2.isNumber: - i.push newVal(not floatCompare(n1, n2)) - i.push newVal(not (n1 == n2)) - - def.symbol("not") do (i: In): - let vals = i.expect("bool") - let b = vals[0] - i.push newVal(not b.boolVal) - - def.symbol("and") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal and b.boolVal) - - def.symbol("expect-all") do (i: In): - let vals = i.expect("quot") - let q = vals[0] - var c = 0 - for v in q.qVal: - if not v.isQuotation: - raiseInvalid("A quotation of quotations is expected") - var vv = v - i.dequote vv - let r = i.pop - c.inc() - if not r.isBool: - raiseInvalid("Quotation #$# does not evaluate to a boolean value" % [$c]) - if not r.boolVal: - i.push r - return - i.push true.newVal - - def.symbol("or") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal or b.boolVal) - - def.symbol("expect-any") do (i: In): - let vals = i.expect("quot") - let q = vals[0] - var c = 0 - for v in q.qVal: - if not v.isQuotation: - raiseInvalid("A quotation of quotations is expected") - var vv = v - i.dequote vv - let r = i.pop - c.inc() - if not r.isBool: - raiseInvalid("Quotation #$# does not evaluate to a boolean value" % [$c]) - if r.boolVal: - i.push r - return - i.push false.newVal - - def.symbol("xor") do (i: In): - let vals = i.expect("bool", "bool") - let a = vals[0] - let b = vals[1] - i.push newVal(a.boolVal xor b.boolVal) - - def.symbol("string?") do (i: In): - if i.pop.kind == minString: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("integer?") do (i: In): - if i.pop.kind == minInt: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("float?") do (i: In): - if i.pop.kind == minFloat: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("null?") do (i: In): - if i.pop.kind == minNull: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("number?") do (i: In): - let a = i.pop - if a.kind == minFloat or a.kind == minInt: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("boolean?") do (i: In): - if i.pop.kind == minBool: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("quotation?") do (i: In): - if i.pop.kind == minQuotation: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("quoted-symbol?") do (i: In): - let item = i.pop - if item.kind == minQuotation and item.qVal.len == 1 and item.qVal[0].kind == minSymbol: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("stringlike?") do (i: In): - if i.pop.isStringLike: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("dictionary?") do (i: In): - if i.pop.isDictionary: - i.push true.newVal - else: - i.push false.newVal - - def.symbol("type?") do (i: In): - let vals = i.expect("'sym", "a") - let t = vals[0].getString - let v = vals[1] - let res = i.validateValueType(t, v) - i.push res.newVal - - def.symbol("&&") do (i: In): - i.pushSym("expect-all") - - def.symbol("||") do (i: In): - i.pushSym("expect-any") - - def.finalize("logic")
@@ -1,6 +1,7 @@
### BREAKING CHANGES - All symbols defined in the **num** module have been moved to the **global** module. +- All symbols defined in the **logic** module have been moved to the **global** module. ### New Features
@@ -1,6 +1,5 @@
; Imports 'str import -'logic import 'stack import 'seq import 'dict import
@@ -52,7 +52,7 @@ > Tip
> > The {#link-operator||dict||dtype#} operator can be used to set the type of a dictionary. -The {#link-module||logic#} provides predicate operators to check if an element belongs to a particular data type or pseudo-type (`boolean?`, `number?`, `integer?`, `float?`, ...). +The {#link-module||global#} provides predicate operators to check if an element belongs to a particular data type or pseudo-type (`boolean?`, `number?`, `integer?`, `float?`, ...). Additionally, the {#link-module||global#} provides operators to convert values from a data type to another (e.g. {#link-operator||global||integer#}, {#link-operator||global||string#}, and so on).
@@ -24,7 +24,7 @@ filepath fsize 1000000 >
filepath mtime now 3600 - > and and -In this case, the `filepath` symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two {#link-operator||logic||and#} symbols necessary to compare the three conditions. +In this case, the `filepath` symbol is defined and then used on the following three lines, each of which defines a condition to be evaluated. The last line contains just two {#link-operator||global||and#} symbols necessary to compare the three conditions. ## Lexical scoping and binding
@@ -41,7 +41,6 @@ ```
; Imports 'str import 'io import -'logic import 'sys import 'stack import 'seq import
@@ -336,6 +336,6 @@
> %note% > Tip > -> Except for some native symbols, constructors represent the only way to create new typed dictionaries. The more validations you perform in a constructor, the most effective checking for a specific type using the {#link-operator||logic||type?#} operator will be, as `type?` only checks if a specific type annotation is present on a typed dictionary, nothing else. +> Except for some native symbols, constructors represent the only way to create new typed dictionaries. The more validations you perform in a constructor, the most effective checking for a specific type using the {#link-operator||global||type?#} operator will be, as `type?` only checks if a specific type annotation is present on a typed dictionary, nothing else. {#link-learn||quotations||Quotations#}
@@ -62,6 +62,47 @@
{#op||/||{{n1}} {{n2}}||{{n3}}|| Divides {{n1}} by {{n2}}. #} +{#op||>||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is greater than {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||>=||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is greater than or equal to {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||<||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is smaller than {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||<=||{{a1}} {{a2}}||{{b}}|| +> Returns {{t}} if {{a1}} is smaller than or equal to {{a2}}, {{f}} otherwise. +> > %note% +> > Note +> > +> > Only comparisons among two numbers or two strings are supported.#} + +{#op||==||{{a1}} {{a2}}||{{b}}|| +Returns {{t}} if {{a1}} is equal to {{a2}}, {{f}} otherwise. #} + +{#op||!=||{{a1}} {{a2}}||{{b}}|| +Returns {{t}} if {{a1}} is not equal to {{a2}}, {{f}} otherwise. #} + +{#alias||||||expect-any#} + +{#alias||&&||expect-all#} + +{#op||and||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} is equal to {{b2}}, {{f}} otherwise.#} + {#op||apply||{{q}}||({{a0p}})|| Returns a new quotation obtained by evaluating each element of {{q}} in a separate stack. #}@@ -113,6 +154,9 @@ > * If {{any}} is a numeric value, zero is converted to {{f}}, otherwise it is converted to {{t}}.
> * If {{any}} is a quotation or a dictionary, the empty quotation or dictionary is converted to {{f}}, otherwise it is converted to {{t}}. > * If {{any}} is a string, the empty string, and `"false"` are converted to {{f}}, otherwise it is converted to {{t}}.#} +{#op||boolean?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a boolean, {{f}} otherwise. #} + {#op||case||(({{q1}} {{q2}}){{0p}})||{{a0p}}|| > This operator takes a quotation containing _n_ different conditional branches. >@@ -164,6 +208,9 @@
{#op||dev?||{{none}}||{{b}}|| Returns {{t}} if the current program is being executed in development mode.#} +{#op||dictionary?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a dictionary, {{f}} otherwise. #} + {#op||div||{{i1}} {{i2}}||{{i3}}|| Divides {{i1}} by {{i2}} (integer division). #}@@ -196,6 +243,14 @@ > > the following program evaluates to `true`:
> > > > `(int string num) expect (3.4 "test" 1) ==`#} +{#op||expect-all||{{q}}||{{b}}|| +Assuming that {{q}} is a quotation of quotations each evaluating to a boolean value, it pushes {{t}} on the stack if they all evaluate to {{t}}, {{f}} otherwise. + #} + +{#op||expect-any||{{q}}||{{b}}|| +Assuming that {{q}} is a quotation of quotations each evaluating to a boolean value, it pushes {{t}} on the stack if any evaluates to {{t}}, {{f}} otherwise. + #} + {#op||expect-empty-stack||{{none}}||{{none}}|| Raises an error if the stack is not empty.#}@@ -208,6 +263,9 @@ > * If {{any}} is {{null}}, it is converted to `0.0`.
> * If {{any}} is a integer, it is converted to float value. > * If {{any}} is a float, no conversion is performed. > * If {{any}} is a string, it is parsed as a float value.#} + +{#op||float?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a float, {{f}} otherwise. #} {#op||foreach||{{q1}} {{q2}}||{{a0p}}|| Applies the quotation {{q2}} to each element of {{q1}}.#}@@ -282,6 +340,9 @@ > * If {{any}} is {{null}}, it is converted to `0`.
> * If {{any}} is an integer, no conversion is performed. > * If {{any}} is a float, it is converted to an integer value by truncating its decimal part. > * If {{any}} is a string, it is parsed as an integer value.#} + +{#op||integer?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is an integer, {{f}} otherwise. #} {#op||lambda||{{q}} {{sl}}||{{none}}|| > Defines a new symbol {{sl}}, containing the specified quotation {{q}}. Unlike with `define`, in this case {{q}} will not be quoted, so its values will be pushed on the stack when the symbol {{sl}} is pushed on the stack.@@ -346,6 +407,15 @@
{#op||nan||{{none}}||nan|| Returns **NaN** (not a number). #} +{#op||not||{{b1}}||{{b2}}|| +Negates {{b1}}.#} + +{#op||null?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is {{null}}, {{f}} otherwise. #} + +{#op||number?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a number, {{f}} otherwise. #} + {#op||odd?||{{i}}||{{b}}|| Returns {{t}} if {{i}} is odd, {{f}} otherwise. #}@@ -426,6 +496,9 @@ > >
> Publish symbol [my-local-symbol](class:kwd) to [global](class:kwd) scope: > > `'my-local-symbol global publish` #} +{#op||or||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} or {{b2}} is {{t}}, {{f}} otherwise.#} + {#op||pred||{{i1}}||{{i2}}|| Returns the predecessor of {{i1}}.#}@@ -441,6 +514,12 @@
{#op||quit||{{none}}||{{none}}|| Exits the program or shell with 0 as return code. #} +{#op||quotation?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a quotation, {{f}} otherwise. #} + +{#op||quoted-symbol?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a quoted symbol, {{f}} otherwise. #} + {#op||quote||{{any}}||({{any}})|| Wraps {{any}} in a quotation. #}@@ -544,6 +623,12 @@
{#op||string||{{any}}||{{s}}|| Converts {{any}} to its string representation.#} +{#op||stringlike?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a string or a quoted symbol, {{f}} otherwise. #} + +{#op||string?||{{any}}||{{b}}|| +Returns {{t}} if {{any}} is a string, {{f}} otherwise. #} + {#op||succ||{{i1}}||{{i2}}|| Returns the successor of {{i1}}.#}@@ -620,6 +705,9 @@
{#op||typealias||{{sl1}} {{sl2}}||{{none}}|| Creates a type alias {{sl1}} for type expression {{sl2}}.#} +{#op||type?||{{any}} {{sl}}||{{b}}|| +Returns {{t}} if the data type of {{any}} satisfies the specified type expression {{sl}}, {{f}} otherwise. #} + {#op||unless||{{q1}} {{q2}}||{{a0p}}|| If {{1}} evaluates to {{f}} then evaluates {{2}}.#}@@ -649,3 +737,6 @@ > > (count puts succ @count) while #}
{#op||with||{{q1}} {{q2}}||{{a0p}}|| Pushes each item of {{q1}} on the stack using the scope of {{q2}} as scope. #} + +{#op||xor||{{b1}} {{b2}}||{{b3}}|| +Returns {{t}} if {{b1}} and {{b2}} are different, {{f}} otherwise.#}
@@ -1,97 +0,0 @@
------ -content-type: "page" -title: "logic Module" ------ -{@ _defs_.md || 0 @} - -{#op||>||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is greater than {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||>=||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is greater than or equal to {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||<||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is smaller than {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||<=||{{a1}} {{a2}}||{{b}}|| -> Returns {{t}} if {{a1}} is smaller than or equal to {{a2}}, {{f}} otherwise. -> > %note% -> > Note -> > -> > Only comparisons among two numbers or two strings are supported.#} - -{#op||==||{{a1}} {{a2}}||{{b}}|| -Returns {{t}} if {{a1}} is equal to {{a2}}, {{f}} otherwise. #} - -{#op||!=||{{a1}} {{a2}}||{{b}}|| -Returns {{t}} if {{a1}} is not equal to {{a2}}, {{f}} otherwise. #} - -{#alias||||||expect-any#} - -{#alias||&&||expect-all#} - -{#op||and||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} is equal to {{b2}}, {{f}} otherwise.#} - -{#op||boolean?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a boolean, {{f}} otherwise. #} - -{#op||dictionary?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a dictionary, {{f}} otherwise. #} - -{#op||expect-all||{{q}}||{{b}}|| -Assuming that {{q}} is a quotation of quotations each evaluating to a boolean value, it pushes {{t}} on the stack if they all evaluate to {{t}}, {{f}} otherwise. - #} - -{#op||expect-any||{{q}}||{{b}}|| -Assuming that {{q}} is a quotation of quotations each evaluating to a boolean value, it pushes {{t}} on the stack if any evaluates to {{t}}, {{f}} otherwise. - #} - -{#op||float?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a float, {{f}} otherwise. #} - -{#op||or||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} or {{b2}} is {{t}}, {{f}} otherwise.#} - -{#op||integer?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is an integer, {{f}} otherwise. #} - -{#op||not||{{b1}}||{{b2}}|| -Negates {{b1}}.#} - -{#op||null?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is {{null}}, {{f}} otherwise. #} - -{#op||number?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a number, {{f}} otherwise. #} - -{#op||quotation?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a quotation, {{f}} otherwise. #} - -{#op||quoted-symbol?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a quoted symbol, {{f}} otherwise. #} - -{#op||string?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a string, {{f}} otherwise. #} - -{#op||stringlike?||{{any}}||{{b}}|| -Returns {{t}} if {{any}} is a string or a quoted symbol, {{f}} otherwise. #} - -{#op||type?||{{any}} {{sl}}||{{b}}|| -Returns {{t}} if the data type of {{any}} satisfies the specified type expression {{sl}}, {{f}} otherwise. #} - -{#op||xor||{{b1}} {{b2}}||{{b3}}|| -Returns {{t}} if {{b1}} and {{b2}} are different, {{f}} otherwise.#} -
@@ -20,8 +20,6 @@ {#link-module||io#}
: Provides operators for reading and writing files as well as printing to STDOUT and reading from STDIN. {#link-module||fs#} : Provides operators for accessing file information and properties. -{#link-module||logic#} -: Provides comparison operators for all min data types and other boolean logic operators. {#link-module||str#} : Provides operators to perform operations on strings, use regular expressions, interpolation, etc. {#link-module||sys#}
@@ -14,7 +14,6 @@ 'dstore load
'fs load 'io load 'global load -'logic load 'math load 'seq load 'stack load
@@ -376,7 +376,6 @@ ) test.assert
;; Numeric operations - (2 2 + 4 ==) test.assert (1 3.0 + 4 ==) test.assert (3.1 3.9 + 7 ==) test.assert@@ -457,6 +456,181 @@ (0b111000 (0 2) bitflip 0b111101 ==) test.assert
(0b111001 (0) bitclear 0b111000 ==) test.assert (0b111000 (0 1) bitset 0b111011 ==) test.assert (0b111000 bitparity 1 ==) test.assert + + ;; Logic operations + + (2 3 <) test.assert + (3 2 < false ==) test.assert + (3 3 < false ==) test.assert + (2.99 3 <) test.assert + (2 1.99 < false ==) test.assert + (1.99 1.991 <) test.assert + (1.99 1.990 < false ==) test.assert + ("test1" "test2" <) test.assert + ("test3" "test2" < false ==) test.assert + ("test2" "test2" < false ==) test.assert + + (2 3 <=) test.assert + (3 2 <= false ==) test.assert + (3 3 <=) test.assert + (2.99 3 <=) test.assert + (2 1.99 <= false ==) test.assert + (1.99 1.991 <=) test.assert + (1.99 1.990 <=) test.assert + ("test1" "test2" <=) test.assert + ("test3" "test2" <= false ==) test.assert + ("test2" "test2" <=) test.assert + + + (2 3 > false ==) test.assert + (3 2 >) test.assert + (3 3 > false ==) test.assert + (2.99 3 > false ==) test.assert + (2 1.99 >) test.assert + (1.99 1.991 > false ==) test.assert + (1.99 1.990 > false ==) test.assert + ("test1" "test2" > false ==) test.assert + ("test3" "test2" >) test.assert + ("test2" "test2" > false ==) test.assert + + (2 3 >= false ==) test.assert + (3 2 >=) test.assert + (3 3 >=) test.assert + (2.99 3 >= false ==) test.assert + (2 1.99 >=) test.assert + (1.99 1.991 >= false ==) test.assert + (1.99 1.990 >=) test.assert + ("test1" "test2" >= false ==) test.assert + ("test3" "test2" >=) test.assert + ("test2" "test2" >=) test.assert + + (true true ==) test.assert + (false true == false ==) test.assert + (true false == false ==) test.assert + (false false ==) test.assert + (1 1 ==) test.assert + ("aaa" "aaa" ==) test.assert + (1.0 1 ==) test.assert + ((1 2 3.0) (1.0 2 3) ==) test.assert + (("a" "b") ("a" "b") ==) test.assert + (("a" "b" 3) ("a" "b" 4) == false ==) test.assert + ((1 "b" 3 myrandomsymbol) (1 "b" 3.0 myrandomsymbol) ==) test.assert + + (true true != false ==) test.assert + (false true !=) test.assert + (true false !=) test.assert + (false false != false ==) test.assert + (1 1 != false ==) test.assert + ("aaa" "aaa" != false ==) test.assert + ;;(1.0 1 != false ==) *test/assert + ;;((1 2 3.0) (1.0 2.0 3) != false ==) *test/assert + ;;(("a" "b") ("a" "b") != false ==) *test/assert + (("a" "b" 3) ("a" "b" 4) !=) test.assert + ((1 "b" 3 myrandomsymbol) (1 "b" 3.0 myrandomsymbol) != false ==) test.assert + + (false not) test.assert + (true not false ==) test.assert + + (true true and) test.assert + (true false and false ==) test.assert + (false true and false ==) test.assert + (false false and false ==) test.assert + + (true true or) test.assert + (true false or) test.assert + (false true or) test.assert + (false false or false ==) test.assert + + (true true xor false ==) test.assert + (true false xor) test.assert + (false true xor) test.assert + (false false xor false ==) test.assert + + ("a" string?) test.assert + (1 string? false ==) test.assert + (1.0 string? false ==) test.assert + (true string? false ==) test.assert + (false string? false ==) test.assert + (("a" 2 c) string? false ==) test.assert + + ("a" integer? false ==) test.assert + (1 integer?) test.assert + (1.0 integer? false ==) test.assert + (true integer? false ==) test.assert + (false integer? false ==) test.assert + (("a" 2 c) integer? false ==) test.assert + + ("a" float? false ==) test.assert + (1 float? false ==) test.assert + (1.0 float?) test.assert + (true float? false ==) test.assert + (false float? false ==) test.assert + (("a" 2 c) float? false ==) test.assert + + ("a" boolean? false ==) test.assert + (1 boolean? false ==) test.assert + (1.0 boolean? false ==) test.assert + (true boolean?) test.assert + (false boolean?) test.assert + (("a" 2 c) boolean? false ==) test.assert + + ("a" number? false ==) test.assert + (1 number?) test.assert + (1.0 number?) test.assert + (true number? false ==) test.assert + (false number? false ==) test.assert + (("a" 2 c) number? false ==) test.assert + + ("a" quotation? false ==) test.assert + (1 quotation? false ==) test.assert + (1.0 quotation? false ==) test.assert + (true quotation? false ==) test.assert + (false quotation? false ==) test.assert + (("a" 2 c) quotation?) test.assert + + ("a" stringlike?) test.assert + (1 stringlike? false ==) test.assert + ('test stringlike?) test.assert + + (("a") quoted-symbol? not) test.assert + ('test quoted-symbol?) test.assert + ((aaa bbb) quoted-symbol? not) test.assert + + ({} 'dict:module type? false ==) test.assert + ((1 2 3) 'dict:module type? false ==) test.assert + (4 'dict:module type? false ==) test.assert + (global 'dict:module type?) test.assert + (1 "int" type?) test.assert + ("test" "str" type?) test.assert + (global "dict:module" type?) test.assert + + (7 0 / inf ==) test.assert + (-7 0 / -inf ==) test.assert + (0 0 / nan ==) test.assert + (10 3 / 3.33333 ==) test.assert + + (3 "a" == not) test.assert + (1 () != true) test.assert + (3.3 'test == not) test.assert + + ( + ( + (true) + (2 1 >) + ("a" "b" ==) + ("never printed" puts!) + ) && + false == + ) test.assert + + ( + ( + (false) + (2 1 <) + ("a" "a" ==) + ("never printed" puts!) + ) || + ) test.assert test.report ;; Tidy up
@@ -3,178 +3,6 @@ ;;;
"logic" test.describe - (2 3 <) test.assert - (3 2 < false ==) test.assert - (3 3 < false ==) test.assert - (2.99 3 <) test.assert - (2 1.99 < false ==) test.assert - (1.99 1.991 <) test.assert - (1.99 1.990 < false ==) test.assert - ("test1" "test2" <) test.assert - ("test3" "test2" < false ==) test.assert - ("test2" "test2" < false ==) test.assert - - (2 3 <=) test.assert - (3 2 <= false ==) test.assert - (3 3 <=) test.assert - (2.99 3 <=) test.assert - (2 1.99 <= false ==) test.assert - (1.99 1.991 <=) test.assert - (1.99 1.990 <=) test.assert - ("test1" "test2" <=) test.assert - ("test3" "test2" <= false ==) test.assert - ("test2" "test2" <=) test.assert - - - (2 3 > false ==) test.assert - (3 2 >) test.assert - (3 3 > false ==) test.assert - (2.99 3 > false ==) test.assert - (2 1.99 >) test.assert - (1.99 1.991 > false ==) test.assert - (1.99 1.990 > false ==) test.assert - ("test1" "test2" > false ==) test.assert - ("test3" "test2" >) test.assert - ("test2" "test2" > false ==) test.assert - - (2 3 >= false ==) test.assert - (3 2 >=) test.assert - (3 3 >=) test.assert - (2.99 3 >= false ==) test.assert - (2 1.99 >=) test.assert - (1.99 1.991 >= false ==) test.assert - (1.99 1.990 >=) test.assert - ("test1" "test2" >= false ==) test.assert - ("test3" "test2" >=) test.assert - ("test2" "test2" >=) test.assert - - (true true ==) test.assert - (false true == false ==) test.assert - (true false == false ==) test.assert - (false false ==) test.assert - (1 1 ==) test.assert - ("aaa" "aaa" ==) test.assert - (1.0 1 ==) test.assert - ((1 2 3.0) (1.0 2 3) ==) test.assert - (("a" "b") ("a" "b") ==) test.assert - (("a" "b" 3) ("a" "b" 4) == false ==) test.assert - ((1 "b" 3 myrandomsymbol) (1 "b" 3.0 myrandomsymbol) ==) test.assert - - (true true != false ==) test.assert - (false true !=) test.assert - (true false !=) test.assert - (false false != false ==) test.assert - (1 1 != false ==) test.assert - ("aaa" "aaa" != false ==) test.assert - ;;(1.0 1 != false ==) *test/assert - ;;((1 2 3.0) (1.0 2.0 3) != false ==) *test/assert - ;;(("a" "b") ("a" "b") != false ==) *test/assert - (("a" "b" 3) ("a" "b" 4) !=) test.assert - ((1 "b" 3 myrandomsymbol) (1 "b" 3.0 myrandomsymbol) != false ==) test.assert - - (false not) test.assert - (true not false ==) test.assert - - (true true and) test.assert - (true false and false ==) test.assert - (false true and false ==) test.assert - (false false and false ==) test.assert - - (true true or) test.assert - (true false or) test.assert - (false true or) test.assert - (false false or false ==) test.assert - - (true true xor false ==) test.assert - (true false xor) test.assert - (false true xor) test.assert - (false false xor false ==) test.assert - - ("a" string?) test.assert - (1 string? false ==) test.assert - (1.0 string? false ==) test.assert - (true string? false ==) test.assert - (false string? false ==) test.assert - (("a" 2 c) string? false ==) test.assert - - ("a" integer? false ==) test.assert - (1 integer?) test.assert - (1.0 integer? false ==) test.assert - (true integer? false ==) test.assert - (false integer? false ==) test.assert - (("a" 2 c) integer? false ==) test.assert - - ("a" float? false ==) test.assert - (1 float? false ==) test.assert - (1.0 float?) test.assert - (true float? false ==) test.assert - (false float? false ==) test.assert - (("a" 2 c) float? false ==) test.assert - - ("a" boolean? false ==) test.assert - (1 boolean? false ==) test.assert - (1.0 boolean? false ==) test.assert - (true boolean?) test.assert - (false boolean?) test.assert - (("a" 2 c) boolean? false ==) test.assert - - ("a" number? false ==) test.assert - (1 number?) test.assert - (1.0 number?) test.assert - (true number? false ==) test.assert - (false number? false ==) test.assert - (("a" 2 c) number? false ==) test.assert - - ("a" quotation? false ==) test.assert - (1 quotation? false ==) test.assert - (1.0 quotation? false ==) test.assert - (true quotation? false ==) test.assert - (false quotation? false ==) test.assert - (("a" 2 c) quotation?) test.assert - - ("a" stringlike?) test.assert - (1 stringlike? false ==) test.assert - ('test stringlike?) test.assert - - (("a") quoted-symbol? not) test.assert - ('test quoted-symbol?) test.assert - ((aaa bbb) quoted-symbol? not) test.assert - - ({} 'dict:module type? false ==) test.assert - ((1 2 3) 'dict:module type? false ==) test.assert - (4 'dict:module type? false ==) test.assert - (logic 'dict:module type?) test.assert - (1 "int" type?) test.assert - ("test" "str" type?) test.assert - (global "dict:module" type?) test.assert - - (7 0 / inf ==) test.assert - (-7 0 / -inf ==) test.assert - (0 0 / nan ==) test.assert - (10 3 / 3.33333 ==) test.assert - - (3 "a" == not) test.assert - (1 () != true) test.assert - (3.3 'test == not) test.assert - - ( - ( - (true) - (2 1 >) - ("a" "b" ==) - ("never printed" puts!) - ) && - false == - ) test.assert - - ( - ( - (false) - (2 1 <) - ("a" "a" ==) - ("never printed" puts!) - ) || - ) test.assert - + test.report clear-stack