Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
|
|
@ -0,0 +1,23 @@
|
|||
(define-syntax-rule
|
||||
(if2 cond1 cond2 both cond1-only cond2-only none) ;; new syntax
|
||||
;; will expand to :
|
||||
(if cond1
|
||||
(if cond2 both cond1-only)
|
||||
(if cond2 cond2-only none)))
|
||||
→ #syntax:if2
|
||||
|
||||
(define (num-test n)
|
||||
(if2 (positive? n) (exact? n)
|
||||
"positive and exact"
|
||||
"positive and inexact"
|
||||
"negative and exact"
|
||||
"negative and inexact"))
|
||||
|
||||
(num-test 3/4)
|
||||
→ "positive and exact"
|
||||
(num-test -666)
|
||||
→ "negative and exact"
|
||||
(num-test -666.42)
|
||||
→ "negative and inexact"
|
||||
(num-test PI)
|
||||
→ "positive and inexact"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
#Macro If2(condition1, condition2)
|
||||
#Define Else1 ElseIf CBool(condition1) Then
|
||||
#Define Else2 ElseIf CBool(condition2) Then
|
||||
If CBool(condition1) AndAlso CBool(condition2) Then
|
||||
#Endmacro
|
||||
|
||||
Sub test(a As Integer, b As Integer)
|
||||
If2(a > 0, b > 0)
|
||||
print "both positive"
|
||||
Else1
|
||||
print "first positive"
|
||||
Else2
|
||||
print "second positive"
|
||||
Else
|
||||
print "neither positive"
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Dim As Integer a, b
|
||||
Print "a = 1, b = 1 => ";
|
||||
test(1, 1)
|
||||
Print "a = 1, b = 0 => ";
|
||||
test(1, 0)
|
||||
Print "a = 0, b = 1 => ";
|
||||
test(0, 1)
|
||||
Print "a = 0, b = 0 => ";
|
||||
test(0, 0)
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
23
Task/Extend-your-language/Lasso/extend-your-language-1.lasso
Normal file
23
Task/Extend-your-language/Lasso/extend-your-language-1.lasso
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Create a type to handle the captures
|
||||
|
||||
define if2 => type {
|
||||
data private a, private b
|
||||
public oncreate(a,b) => {
|
||||
.a = #a
|
||||
.b = #b
|
||||
thread_var_push(.type,self)
|
||||
handle => { thread_var_pop(.type)}
|
||||
return givenblock()
|
||||
}
|
||||
public ifboth => .a && .b ? givenblock()
|
||||
public else1 => .a && !.b ? givenblock()
|
||||
public else2 => !.a && .b ? givenblock()
|
||||
public else => !.a && !.b ? givenblock()
|
||||
}
|
||||
|
||||
// Define methods to consider givenblocks
|
||||
|
||||
define ifboth => thread_var_get(::if2)->ifboth => givenblock
|
||||
define else1 => thread_var_get(::if2)->else1 => givenblock
|
||||
define else2 => thread_var_get(::if2)->else2 => givenblock
|
||||
define else => thread_var_get(::if2)->else => givenblock
|
||||
14
Task/Extend-your-language/Lasso/extend-your-language-2.lasso
Normal file
14
Task/Extend-your-language/Lasso/extend-your-language-2.lasso
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
if2(true,true) => {
|
||||
ifboth => {
|
||||
bothConditionsAreTrue
|
||||
}
|
||||
else1 => {
|
||||
firstConditionIsTrue
|
||||
}
|
||||
else2 => {
|
||||
secondConditionIsTrue
|
||||
}
|
||||
else => {
|
||||
noConditionIsTrue
|
||||
}
|
||||
}
|
||||
77
Task/Extend-your-language/Morfa/extend-your-language.morfa
Normal file
77
Task/Extend-your-language/Morfa/extend-your-language.morfa
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import morfa.base;
|
||||
|
||||
// introduce 4 new operators to handle the if2 syntax
|
||||
operator then { kind = infix, precedence = mul, associativity = right}
|
||||
operator else1 { kind = infix, precedence = not, associativity = left }
|
||||
operator else2 { kind = infix, precedence = not, associativity = left }
|
||||
operator none { kind = infix, precedence = not, associativity = left }
|
||||
|
||||
// function which bounds the condition expression to the if2 "actions"
|
||||
public func then(condition: IF2.Condition, actionHolder: IF2): void
|
||||
{
|
||||
actionHolder.actions[condition]();
|
||||
}
|
||||
|
||||
// functions (bound to operators) used to "build" the if2 "statement"
|
||||
public func else1(bothAction: func(): void, else1Action: func(): void): IF2
|
||||
{
|
||||
return IF2([IF2.Condition.both -> bothAction,
|
||||
IF2.Condition.else1 -> else1Action]);
|
||||
|
||||
}
|
||||
public func else2(actionHolder: IF2, action: func(): void): IF2
|
||||
{
|
||||
return checkAndAdd(actionHolder, action, IF2.Condition.else2);
|
||||
}
|
||||
public func none(actionHolder: IF2, action: func(): void): IF2
|
||||
{
|
||||
return checkAndAdd(actionHolder, action, IF2.Condition.none);
|
||||
}
|
||||
|
||||
// finally, function which combines two conditions into a "trigger" for the if2 "statement"
|
||||
public func if2(condition1: bool, condition2: bool): IF2.Condition
|
||||
{
|
||||
if (condition1 and condition2)
|
||||
return IF2.Condition.both;
|
||||
else if (condition1)
|
||||
return IF2.Condition.else1;
|
||||
else if (condition2)
|
||||
return IF2.Condition.else2;
|
||||
else
|
||||
return IF2.Condition.none;
|
||||
}
|
||||
|
||||
// private helper function to build the IF2 structure
|
||||
func checkAndAdd(actionHolder: IF2, action: func(): void, actionName: IF2.Condition): IF2
|
||||
{
|
||||
if (actionHolder.actions.contains(actionName))
|
||||
throw new Exception("action defined twice for one condition in if2");
|
||||
else
|
||||
actionHolder.actions[actionName] = action;
|
||||
return actionHolder;
|
||||
}
|
||||
|
||||
// helper structure to process the if2 "statement"
|
||||
struct IF2
|
||||
{
|
||||
public enum Condition { both, else1, else2, none };
|
||||
public var actions: Dict<Condition, func(): void>;
|
||||
}
|
||||
|
||||
// usage
|
||||
if2 (true, false) then func()
|
||||
{
|
||||
println("both true");
|
||||
}
|
||||
else1 func()
|
||||
{
|
||||
println("first true");
|
||||
}
|
||||
else2 func()
|
||||
{
|
||||
println("second true");
|
||||
}
|
||||
none func()
|
||||
{
|
||||
println("none true");
|
||||
};
|
||||
62
Task/Extend-your-language/Nim/extend-your-language.nim
Normal file
62
Task/Extend-your-language/Nim/extend-your-language.nim
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import macros
|
||||
|
||||
proc newIfElse(c, t, e): PNimNode {.compiletime.} =
|
||||
result = newIfStmt((c, t))
|
||||
result.add(newNimNode(nnkElse).add(e))
|
||||
|
||||
macro if2(x, y: expr; z: stmt): stmt {.immediate.} =
|
||||
var parts: array[4, PNimNode]
|
||||
for i in parts.low .. parts.high:
|
||||
parts[i] = newNimNode(nnkDiscardStmt).add(nil)
|
||||
|
||||
assert z.kind == nnkStmtList
|
||||
assert z.len <= 4
|
||||
|
||||
for i in 0 .. <z.len:
|
||||
assert z[i].kind == nnkCall
|
||||
assert z[i].len == 2
|
||||
|
||||
var j = 0
|
||||
|
||||
case $z[i][0].ident
|
||||
of "then": j = 0
|
||||
of "else1": j = 1
|
||||
of "else2": j = 2
|
||||
of "else3": j = 3
|
||||
else: assert false
|
||||
|
||||
parts[j] = z[i][1].last
|
||||
|
||||
result = newIfElse(x,
|
||||
newIfElse(y, parts[0], parts[1]),
|
||||
newIfElse(y, parts[2], parts[3]))
|
||||
|
||||
if2 2 > 1, 3 < 2:
|
||||
then:
|
||||
echo "1"
|
||||
else1:
|
||||
echo "2"
|
||||
else2:
|
||||
echo "3"
|
||||
else3:
|
||||
echo "4"
|
||||
|
||||
# Missing cases are supported:
|
||||
if2 2 > 1, 3 < 2:
|
||||
then:
|
||||
echo "1"
|
||||
else2:
|
||||
echo "3"
|
||||
else3:
|
||||
echo "4"
|
||||
|
||||
# Order can be swapped:
|
||||
if2 2 > 1, 3 < 2:
|
||||
then:
|
||||
echo "1"
|
||||
else2:
|
||||
echo "3"
|
||||
else1:
|
||||
echo "2"
|
||||
else3:
|
||||
echo "4"
|
||||
53
Task/Extend-your-language/PHL/extend-your-language.phl
Normal file
53
Task/Extend-your-language/PHL/extend-your-language.phl
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
module stmts;
|
||||
|
||||
import phl::lang::io;
|
||||
|
||||
/* LinkedList --> Each element contains a condition */
|
||||
struct @ConditionalChain {
|
||||
field @Boolean cond;
|
||||
field @ConditionalChain next;
|
||||
|
||||
@ConditionalChain init(@Boolean cond, @ConditionalChain next) [
|
||||
this::cond = cond;
|
||||
this::next = next;
|
||||
|
||||
return this;
|
||||
]
|
||||
|
||||
/*
|
||||
* If the condition is true executes the closure and returns a false element, otherwise returns the next condition
|
||||
*
|
||||
* Execution starts from the first element, and iterates until the right element is found.
|
||||
*/
|
||||
@ConditionalChain then(@Closure<@Void> closure) [
|
||||
if (isNull(next())) return new @ConditionalChain.init(false, null);
|
||||
if (cond()) {
|
||||
closure();
|
||||
return new @ConditionalChain.init(false, null);
|
||||
}
|
||||
else return next();
|
||||
]
|
||||
|
||||
/* Operators create a cool look */
|
||||
@ConditionalChain operator then(@Closure<@Void> closure) alias @ConditionalChain.then;
|
||||
@ConditionalChain operator else1(@Closure<@Void> closure) alias @ConditionalChain.then;
|
||||
@ConditionalChain operator else2(@Closure<@Void> closure) alias @ConditionalChain.then;
|
||||
@ConditionalChain operator orElse(@Closure<@Void> closure) alias @ConditionalChain.then;
|
||||
};
|
||||
|
||||
/* Returns linked list [a && b, a, b, true] */
|
||||
@ConditionalChain if2(@Boolean a, @Boolean b) [
|
||||
return new @ConditionalChain.init(a && b, new @ConditionalChain.init(a, new @ConditionalChain.init(b, new @ConditionalChain.init(true, null))));
|
||||
]
|
||||
|
||||
@Void main [
|
||||
if2(false, true) then [
|
||||
println("Not this!");
|
||||
] else1 [
|
||||
println("Not this!");
|
||||
] else2 [
|
||||
println("This!");
|
||||
] orElse [
|
||||
println("Not this!");
|
||||
];
|
||||
]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(defmacro branch-if-macro
|
||||
[branch-if Cond1 Cond2 Both Fst Snd None] ->
|
||||
[if Cond1
|
||||
[if Cond2 Both Fst]
|
||||
[if Cond2 Snd None]])
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
(define try
|
||||
X Y -> (branch-if (integer? X)
|
||||
(integer? Y)
|
||||
both-ints first-int second-int neither-int))
|
||||
|
||||
(map (/. X (do (print X) (nl)))
|
||||
[(try 1 2) (try 1 1.5) (try 1.5 1) (try 1.5 1.5)])
|
||||
36
Task/Extend-your-language/Sidef/extend-your-language.sidef
Normal file
36
Task/Extend-your-language/Sidef/extend-your-language.sidef
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
class if2(cond1, cond2) {
|
||||
method then(block) { # both true
|
||||
if (cond1 && cond2) {
|
||||
block.run;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
method else1(block) { # first true
|
||||
if (cond1 && !cond2) {
|
||||
block.run;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
method else2(block) { # second true
|
||||
if (cond2 && !cond1) {
|
||||
block.run;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
method else(block) { # none true
|
||||
if (!cond1 && !cond2) {
|
||||
block.run;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
if2(false, true).then {
|
||||
say "if2";
|
||||
}.else1 {
|
||||
say "else1";
|
||||
}.else2 {
|
||||
say "else2"; # <- this gets printed
|
||||
}.else {
|
||||
say "else"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue