mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-10 23:04:04 +09:00
basic: changing curry operator to (~<), i thought plunger (or grabber) is semantically less awkward than the arrow
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
10 DEFUN SINC(P)=SIN(P)/P
|
10 DEFUN SINC(P)=SIN(P)/P
|
||||||
20 DEFUN OTHERFUN(A,B)=A+"|"+B
|
20 DEFUN OTHERFUN(A,B)=A+"|"+B
|
||||||
30 DEFUN PLOTLINE(F,X)=MAP(OTHERFUN<~F(X),1 TO 5):REM needs auto-currying
|
30 DEFUN PLOTLINE(F,X)=MAP(OTHERFUN~<F(X),1 TO 5):REM needs auto-currying
|
||||||
31 DEFUN PLOTLINE2(F,X)=MAP(OTHERFUN<~F<~X,1 TO 5):REM WORKS!
|
31 DEFUN PLOTLINE2(F,X)=MAP(OTHERFUN~<F~<X,1 TO 5):REM WORKS!
|
||||||
100 PRINT PLOTLINE(SINC,333)
|
100 PRINT PLOTLINE(SINC,333)
|
||||||
101 PRINT PLOTLINE2(SINC,333)
|
101 PRINT PLOTLINE2(SINC,333)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
1 KS=4!1!2!5!3!NIL
|
1 KS=4!1!2!5!3!NIL
|
||||||
10 DEFUN LESSER(P,X)=X<P
|
10 DEFUN LESSER(P,X)=X<P
|
||||||
11 KLS=LESSER<~HEAD KS
|
11 KLS=LESSER~<HEAD KS
|
||||||
20 FOR K=1 TO 5
|
20 FOR K=1 TO 5
|
||||||
21 PRINT KLS(K)
|
21 PRINT KLS(K)
|
||||||
22 NEXT
|
22 NEXT
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
10 DEFUN F(K,T)=ABS(T)==K
|
10 DEFUN F(K,T)=ABS(T)==K
|
||||||
20 CF=F<~32
|
20 CF=F~<32
|
||||||
30 PRINT CF(24) : REM will print 'false'
|
30 PRINT CF(24) : REM will print 'false'
|
||||||
40 PRINT CF(-32) : REM will print 'true'
|
40 PRINT CF(-32) : REM will print 'true'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
1 XS=4!1!2!3!5!NIL
|
1 XS=4!1!2!3!5!NIL
|
||||||
10 DEFUN K(P,X)=X<P
|
10 DEFUN K(P,X)=X<P
|
||||||
20 NXS=FILTER(K<~HEAD XS,XS)
|
20 NXS=FILTER(K~<HEAD XS,XS)
|
||||||
30 PRINT NXS
|
30 PRINT NXS
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
2 REM qsort xs = qsort [x | x<-tail xs, x<head xs] ++ [head xs] ++ qsort [x | x<-tail xs, x>=head xs]
|
2 REM qsort xs = qsort [x | x<-tail xs, x<head xs] ++ [head xs] ++ qsort [x | x<-tail xs, x>=head xs]
|
||||||
10 DEFUN LESS(P,X)=X<P
|
10 DEFUN LESS(P,X)=X<P
|
||||||
11 DEFUN GTEQ(P,X)=X>=P
|
11 DEFUN GTEQ(P,X)=X>=P
|
||||||
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE QSORT(FILTER(LESS<~HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL # QSORT(FILTER(GTEQ<~HEAD(XS),TAIL(XS)))
|
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE QSORT(FILTER(LESS~<HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL # QSORT(FILTER(GTEQ~<HEAD(XS),TAIL(XS)))
|
||||||
100 L=7!9!4!5!2!3!1!8!6!NIL
|
100 L=7!9!4!5!2!3!1!8!6!NIL
|
||||||
110 PRINT L
|
110 PRINT L
|
||||||
120 PRINT QSORT(L)
|
120 PRINT QSORT(L)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
10 DEFUN SINC(X)=IF X==0 THEN 1 ELSE SIN(X)/X
|
10 DEFUN SINC(X)=IF X==0 THEN 1 ELSE SIN(X)/X
|
||||||
20 DEFUN THREEDIGITS(X)=ROUND(X*1000)/1000
|
20 DEFUN THREEDIGITS(X)=ROUND(X*1000)/1000
|
||||||
100 K=MAP(THREEDIGITS<~SINC,1 TO 10)
|
100 K=MAP(THREEDIGITS~<SINC,1 TO 10)
|
||||||
110 PRINT K
|
110 PRINT K
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
10 DEFUN SINC(P)=IF P==0 THEN 1.0 ELSE SIN(P)/P
|
10 DEFUN SINC(P)=IF P==0 THEN 1.0 ELSE SIN(P)/P
|
||||||
20 DEFUN TOCHAR(P,X)=IF (X==ROUND(ZEROLINE+P*AMP)) THEN "@" ELSE IF (X==ZEROLINE) THEN "|" ELSE CHR(250)
|
20 DEFUN TOCHAR(P,X)=IF (X==ROUND(ZEROLINE+P*AMP)) THEN "@" ELSE IF (X==ZEROLINE) THEN "|" ELSE CHR(250)
|
||||||
30 DEFUN SCONCAT(ACC,S)=ACC+S
|
30 DEFUN SCONCAT(ACC,S)=ACC+S
|
||||||
40 DEFUN PLOTLINE(F,X)=FOLD(SCONCAT,"",MAP(TOCHAR<~F<~X,1 TO ZEROLINE+AMP))
|
40 DEFUN PLOTLINE(F,X)=FOLD(SCONCAT,"",MAP(TOCHAR~<F~<X,1 TO ZEROLINE+AMP))
|
||||||
100 FOR I=-40 TO 40
|
100 FOR I=-40 TO 40
|
||||||
110 PRINT PLOTLINE(SINC,I)
|
110 PRINT PLOTLINE(SINC,I)
|
||||||
120 NEXT
|
120 NEXT
|
||||||
|
|||||||
@@ -1255,7 +1255,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
|||||||
}
|
}
|
||||||
return keys;
|
return keys;
|
||||||
}},
|
}},
|
||||||
"<~" : {f:function(lnum, stmtnum, args) { // CURRY operator
|
"~<" : {f:function(lnum, stmtnum, args) { // CURRY operator
|
||||||
return twoArg(lnum, stmtnum, args, (fn, value) => {
|
return twoArg(lnum, stmtnum, args, (fn, value) => {
|
||||||
// TODO test only works with DEFUN'd functions
|
// TODO test only works with DEFUN'd functions
|
||||||
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Only works with DEFUN'd functions yet");
|
if (fn.astLeaves === undefined) throw lang.badFunctionCallFormat("Only works with DEFUN'd functions yet");
|
||||||
@@ -1421,12 +1421,12 @@ bF._opPrc = {
|
|||||||
"STEP":41,
|
"STEP":41,
|
||||||
"!":50,"~":51, // array CONS and PUSH
|
"!":50,"~":51, // array CONS and PUSH
|
||||||
"#": 52, // array concat
|
"#": 52, // array concat
|
||||||
"<~": 100, // curry operator
|
"~<": 100, // curry operator
|
||||||
"~>": 101, // closure operator
|
"~>": 101, // closure operator
|
||||||
"=":999,
|
"=":999,
|
||||||
"IN":1000
|
"IN":1000
|
||||||
};
|
};
|
||||||
bF._opRh = {"^":1,"=":1,"!":1,"IN":1,"~>":1}; // <~ and ~> cannot have same associativity
|
bF._opRh = {"^":1,"=":1,"!":1,"IN":1,"~>":1}; // ~< and ~> cannot have same associativity
|
||||||
// these names appear on executeSyntaxTree as "exceptional terms" on parsing (regular function calls are not "exceptional terms")
|
// these names appear on executeSyntaxTree as "exceptional terms" on parsing (regular function calls are not "exceptional terms")
|
||||||
bF._tokenise = function(lnum, cmd) {
|
bF._tokenise = function(lnum, cmd) {
|
||||||
var _debugprintStateTransition = false;
|
var _debugprintStateTransition = false;
|
||||||
@@ -2887,24 +2887,6 @@ bF._interpretLine = function(lnum, cmd) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// automatically apply currying
|
|
||||||
// '(<~) FNQ (P X Y)' into '(<~) FNQ ((<~) P ((<~) X Y))'
|
|
||||||
// FIXME this autocurrying is very likely to be a janky-ass-shit
|
|
||||||
syntaxTrees.forEach(syntaxTree => {
|
|
||||||
if (syntaxTree !== undefined) {
|
|
||||||
bF._recurseApplyAST(syntaxTree, tree => {
|
|
||||||
if (tree.astValue == "<~" && tree.astLeaves[1] !== undefined && tree.astLeaves[1].astLeaves[0] !== undefined) {
|
|
||||||
let subTree = new BasicAST();
|
|
||||||
subTree.astValue = "<~";
|
|
||||||
subTree.astType = "op";
|
|
||||||
subTree.astLnum = tree.astLnum;
|
|
||||||
subTree.astLeaves = [tree.astLeaves[1], tree.astLeaves[1].astLeaves[0]];
|
|
||||||
|
|
||||||
tree.astLeaves[1] = subTree;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (_debugprintHighestLevel) {
|
if (_debugprintHighestLevel) {
|
||||||
syntaxTrees.forEach((t,i) => {
|
syntaxTrees.forEach((t,i) => {
|
||||||
serial.println("\nParsed Statement #"+(i+1));
|
serial.println("\nParsed Statement #"+(i+1));
|
||||||
|
|||||||
@@ -160,13 +160,13 @@ Here, \code{K} will contain the values of $1!$, $2!$ \ldots\ $10!$. Right now we
|
|||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
10 DEFUN F(K,T)=ABS(T)==K
|
10 DEFUN F(K,T)=ABS(T)==K
|
||||||
20 CF=F<~32
|
20 CF=F~<32
|
||||||
30 PRINT CF(24) : REM will print 'false'
|
30 PRINT CF(24) : REM will print 'false'
|
||||||
40 PRINT CF(-32) : REM will print 'true'
|
40 PRINT CF(-32) : REM will print 'true'
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
% NOTE: you can't use \basiccurry within \code{}
|
% NOTE: you can't use \basiccurry within \code{}
|
||||||
Here, \code{CF} is a curried function of \code{F}; built-in operator \code{$<\!\sim$} applies \code{32} to the first parameter of the function \code{F}, which dynamically returns a \emph{function} of \code{CF(T) = ABS(T) == 32}. The fact that Curry Operator returns a \emph{function} opens many possibilities, for example, you can create loads of sibling functions without making loads of duplicate codes.
|
Here, \code{CF} is a curried function of \code{F}; built-in operator \code{$\sim\!<$} applies \code{32} to the first parameter of the function \code{F}, which dynamically returns a \emph{function} of \code{CF(T) = ABS(T) == 32}. The fact that Curry Operator returns a \emph{function} opens many possibilities, for example, you can create loads of sibling functions without making loads of duplicate codes.
|
||||||
|
|
||||||
\section[Wrapping-Up]{The Grand Unification}
|
\section[Wrapping-Up]{The Grand Unification}
|
||||||
|
|
||||||
@@ -176,8 +176,8 @@ Using all the knowledge we have learned, it should be trivial\footnote{/s} to wr
|
|||||||
10 DEFUN LESS(P,X)=X<P
|
10 DEFUN LESS(P,X)=X<P
|
||||||
11 DEFUN GTEQ(P,X)=X>=P
|
11 DEFUN GTEQ(P,X)=X>=P
|
||||||
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE
|
12 DEFUN QSORT(XS)=IF LEN(XS)<1 THEN NIL ELSE
|
||||||
QSORT(FILTER(LESS<~HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL #
|
QSORT(FILTER(LESS~<HEAD(XS),TAIL(XS))) # HEAD(XS)!NIL #
|
||||||
QSORT(FILTER(GTEQ<~HEAD(XS),TAIL(XS)))
|
QSORT(FILTER(GTEQ~<HEAD(XS),TAIL(XS)))
|
||||||
100 L=7!9!4!5!2!3!1!8!6!NIL
|
100 L=7!9!4!5!2!3!1!8!6!NIL
|
||||||
110 PRINT L
|
110 PRINT L
|
||||||
120 PRINT QSORT(L)
|
120 PRINT QSORT(L)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
%% BASIC operators %%
|
%% BASIC operators %%
|
||||||
\newcommand\basicexp{\raisebox{0.25ex}{\scriptsize\wedge}}
|
\newcommand\basicexp{\raisebox{0.25ex}{\scriptsize\wedge}}
|
||||||
\newcommand\basiccurry{$<\!\sim$}
|
\newcommand\basiccurry{$\sim\!<$}
|
||||||
\newcommand\basicclosure{$\sim\!>$}
|
\newcommand\basicclosure{$\sim\!>$}
|
||||||
|
|
||||||
% Title styling
|
% Title styling
|
||||||
|
|||||||
Reference in New Issue
Block a user