mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 19:51:51 +09:00
basicdoc: adding missing array manipulating functions
This commit is contained in:
@@ -568,6 +568,27 @@ bStatus.getDefunThunk = function(lnum, stmtnum, exprTree) {
|
||||
return resolve(bF._executeSyntaxTree(lnum, stmtnum, tree, 0));
|
||||
}
|
||||
};
|
||||
/* Accepts troValue, assignes to BASIC variable, and returns internal_assign_object
|
||||
* @params troValue Variable to assign into
|
||||
* @params rh the value, resolved
|
||||
*/
|
||||
bStatus.addAsBasicVar = function(troValue, rh) {
|
||||
if (troValue.arrFull !== undefined) { // assign to existing array
|
||||
if (isNaN(rh) && !Array.isArray(rh)) throw lang.illegalType(lnum, rh);
|
||||
let arr = eval("troValue.arrFull"+troValue.arrKey);
|
||||
if (Array.isArray(arr)) throw lang.subscrOutOfRng(lnum, arr);
|
||||
eval("troValue.arrFull"+troValue.arrKey+"=rh");
|
||||
return {asgnVarName: troValue.arrName, asgnValue: rh};
|
||||
}
|
||||
else {
|
||||
let varname = troValue.toUpperCase();
|
||||
//println("input varname: "+varname);
|
||||
let type = JStoBASICtype(rh);
|
||||
if (_basicConsts[varname]) throw lang.asgnOnConst(lnum, varname);
|
||||
bStatus.vars[varname] = new BasicVar(rh, type);
|
||||
return {asgnVarName: varname, asgnValue: rh};
|
||||
}
|
||||
}
|
||||
bStatus.builtin = {
|
||||
/*
|
||||
@param lnum line number
|
||||
@@ -592,29 +613,7 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
//try { println(lnum+" = rh resolved entries: "+Object.entries(rh)); }
|
||||
//catch (_) {}
|
||||
|
||||
|
||||
if (troValue.arrFull !== undefined) { // assign to existing array
|
||||
if (isNaN(rh) && !Array.isArray(rh)) throw lang.illegalType(lnum, rh);
|
||||
let arr = eval("troValue.arrFull"+troValue.arrKey);
|
||||
if (Array.isArray(arr)) throw lang.subscrOutOfRng(lnum, arr);
|
||||
eval("troValue.arrFull"+troValue.arrKey+"=rh");
|
||||
return {asgnVarName: troValue.arrName, asgnValue: rh};
|
||||
}
|
||||
else {
|
||||
var varname = troValue.toUpperCase();
|
||||
var type = JStoBASICtype(rh);
|
||||
if (_basicConsts[varname]) throw lang.asgnOnConst(lnum, varname);
|
||||
// special case for scalar array
|
||||
// it basically bypasses the regular resolve subroutine
|
||||
if (args[1].troType !== undefined && args[1].troType == "array") {
|
||||
bStatus.vars[varname] = new BasicVar(args[1].troValue, "array");
|
||||
return {asgnVarName: varname, asgnValue: rh};
|
||||
}
|
||||
else {
|
||||
bStatus.vars[varname] = new BasicVar(rh, type);
|
||||
return {asgnVarName: varname, asgnValue: rh};
|
||||
}
|
||||
}
|
||||
return bStatus.addAsBasicVar(troValue, rh);
|
||||
}},
|
||||
"IN" : {f:function(lnum, stmtnum, args) { // almost same as =, but don't actually make new variable. Used by FOR statement
|
||||
if (args.length != 2) throw lang.syntaxfehler(lnum, args.length+lang.aG);
|
||||
@@ -1040,21 +1039,10 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
// NOTE: empty string will be cast to 0, which corresponds to GW-BASIC
|
||||
if (!isNaN(rh)) rh = rh*1
|
||||
|
||||
if (troValue.arrFull !== undefined) { // assign to existing array
|
||||
if (isNaN(rh) && !Array.isArray(rh)) throw lang.illegalType(lnum, rh);
|
||||
let arr = eval("troValue.arrFull"+troValue.arrKey);
|
||||
if (Array.isArray(arr)) throw lang.subscrOutOfRng(lnum, arr);
|
||||
eval("troValue.arrFull"+troValue.arrKey+"=rh");
|
||||
return {asgnVarName: troValue.arrName, asgnValue: rh};
|
||||
}
|
||||
else {
|
||||
let varname = troValue.toUpperCase();
|
||||
//println("input varname: "+varname);
|
||||
let type = JStoBASICtype(rh);
|
||||
if (_basicConsts[varname]) throw lang.asgnOnConst(lnum, varname);
|
||||
bStatus.vars[varname] = new BasicVar(rh, type);
|
||||
return {asgnVarName: varname, asgnValue: rh};
|
||||
}
|
||||
return bStatus.addAsBasicVar(troValue, rh);
|
||||
}},
|
||||
"CIN" : {f:function(lnum, stmtnum, args) {
|
||||
return sys.read().trim();
|
||||
}},
|
||||
"END" : {f:function(lnum, stmtnum, args) {
|
||||
serial.println("Program terminated in "+lnum);
|
||||
@@ -1121,8 +1109,18 @@ if no arg text were given (e.g. "10 NEXT"), args will have zero length
|
||||
DATA_CURSOR = 0;
|
||||
}},
|
||||
"READ" : {f:function(lnum, stmtnum, args) {
|
||||
let r = DATA_CONSTS.shift();
|
||||
if (args.length != 1) throw lang.syntaxfehler(lnum, args.length+lang.aG);
|
||||
let troValue = args[0].troValue;
|
||||
|
||||
let rh = DATA_CONSTS[DATA_CURSOR++];
|
||||
if (rh === undefined) throw lang.outOfData(lnum);
|
||||
|
||||
return bStatus.addAsBasicVar(troValue, rh);
|
||||
}},
|
||||
"DGET" : {f:function(lnum, stmtnum, args) {
|
||||
let r = DATA_CONSTS[DATA_CURSOR++];
|
||||
if (r === undefined) throw lang.outOfData(lnum);
|
||||
return r;
|
||||
}},
|
||||
"OPTIONBASE" : {f:function(lnum, stmtnum, args) {
|
||||
return oneArgNum(lnum, stmtnum, args, (lh) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
\quad
|
||||
\chapterprecishere{``Caution! Under no circumstances confuse the adjective \emph{basic} with the noun \emph{BASIC}, except under confusing circumstances!''\par\raggedleft --- \textup{\tbas{} Reference Manual, \theedition}\footnote{Original quotation is from \emph{The INTERCAL Programming Language Reference Manual} by Donald R. Woods and James M. Lyon}}
|
||||
\chapterprecishere{``Caution! Under no circumstances confuse the adjective \emph{basic} with the noun \emph{BASIC}, except under confusing circumstances!''\par\raggedleft --- \textup{\tbas\ Reference Manual, \theedition}\footnote{Original quotation is from \emph{The INTERCAL Programming Language Reference Manual} by Donald R. Woods and James M. Lyon}}
|
||||
|
||||
This chapter describes the basic concepts of the \tbas{} language.
|
||||
This chapter describes the basic concepts of the \tbas\ language.
|
||||
|
||||
|
||||
\section{Values and Types}
|
||||
@@ -29,7 +29,7 @@ A program is executed starting with its lowest line number. Statements on a line
|
||||
|
||||
You can dive into other line in the middle of the program with \code{GOTO}. The program flow will continue normally at the new line \emph{and it will never know ya just did that}.
|
||||
|
||||
If you want less insane jumping, \code{GOSUB} is used to jump to a subroutine. Subroutine is a little section of a code that serves as a tiny program inside of a program. \code{GOSUB} will remember from which statement in the line you have came from, and will return your program flow to that line when \code{RETURN} statement is encountered. (of course, if \code{RETURN} is used without \code{GOSUB}, program will raise some error) Do note that while you can reserve some portion of a program line as a \code{subroutine}, \tbas{} will not provide local variables and whatnot as all variables in \tbas{} are global, and you can just \code{GOTO} out of a subroutine to anywhere you desire and wreak havoc \emph{if you really want to}.
|
||||
If you want less insane jumping, \code{GOSUB} is used to jump to a subroutine. Subroutine is a little section of a code that serves as a tiny program inside of a program. \code{GOSUB} will remember from which statement in the line you have came from, and will return your program flow to that line when \code{RETURN} statement is encountered. (of course, if \code{RETURN} is used without \code{GOSUB}, program will raise some error) Do note that while you can reserve some portion of a program line as a \code{subroutine}, \tbas\ will not provide local variables and whatnot as all variables in \tbas\ are global, and you can just \code{GOTO} out of a subroutine to anywhere you desire and wreak havoc \emph{if you really want to}.
|
||||
|
||||
The \code{ON} statement provides alternative branching construct. You can enter multiple line numbers and let your variable (or mathematical expression) to choose which index of line numbers to \code{GOTO}- or \code{GOSUB} into.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
\label{functions}
|
||||
|
||||
Functions are a form of expression that may taks input arguments surrounded by parentheses. Most of the traditional BASIC \emph{statements} that does not return a value are \emph{functions} in \tbas , and like those, while \tbas{} functions can be called without parentheses, it is highly \emph{discouraged} because of the ambiguities in syntax. \textbf{Always use parentheses on function call!}
|
||||
Functions are a form of expression that may taks input arguments surrounded by parentheses. Most of the traditional BASIC \emph{statements} that does not return a value are \emph{functions} in \tbas , and like those, while \tbas\ functions can be called without parentheses, it is highly \emph{discouraged} because of the ambiguities in syntax. \textbf{Always use parentheses on function call!}
|
||||
|
||||
\section{Mathematical}
|
||||
|
||||
@@ -71,6 +71,15 @@ Functions are a form of expression that may taks input arguments surrounded by p
|
||||
|
||||
\section{Input}
|
||||
|
||||
\subsection{CIN}
|
||||
\codeline{S \textbf{= CIN()}}\par
|
||||
Waits for the user input and returns it.
|
||||
\subsection{DATA}
|
||||
\codeline{\textbf{DATA} CONST0 [\textbf{,} CONST1]\ldots}\par
|
||||
Adds data that can be read by \code{READ} function. \code{DATA} declarations need not be reacheable in the program flow.
|
||||
\subsection{DGET}
|
||||
\codeline{S \textbf{= DGET()}}\par
|
||||
Fetches a data declared from \code{DATA} statements and returns it, incrementing the \code{DATA} position.
|
||||
\subsection{DIM}
|
||||
\codeline{Y \textbf{= DIM(}X\textbf{)}}\par
|
||||
Returns array with size of \code{X}, all filled with zero.
|
||||
@@ -80,8 +89,13 @@ Functions are a form of expression that may taks input arguments surrounded by p
|
||||
Actual keycode and the array length depends on the machine: in \thismachine , array length will be fixed to 8. For the list of available keycodes, see \ref{implementation}.
|
||||
\subsection{INPUT}
|
||||
\codeline{\textbf{INPUT} VARIABLE}\par
|
||||
Prints out \code{? } to the console and waits for user input. Input can be any length and terminated with return key. The input will be stored to given variable.
|
||||
|
||||
Prints out \code{? } to the console and waits for user input. Input can be any length and terminated with return key. The input will be stored to given variable.\par
|
||||
This behaviour is to keep the compatibility with the traditional BASIC. For function-like usage, use \code{CIN} instead.
|
||||
\subsection{READ}
|
||||
\codeline{\textbf{READ} VARIABLE}\par
|
||||
Assigns data declared from \code{DATA} statements to given variable. Reading starts at the current \code{DATA} position, and the data position will be incremented by one. The position is reset to the zero by the \code{RUN} command.\par
|
||||
This behaviour is to keep the compatibility with the traditional BASIC. For function-like usage, use \code{DGET} instead.
|
||||
|
||||
\section{Output}
|
||||
|
||||
\subsection{EMIT}
|
||||
@@ -99,9 +113,6 @@ Functions are a form of expression that may taks input arguments surrounded by p
|
||||
\subsection{CLEAR}
|
||||
\codeline{\textbf{CLEAR}}\par
|
||||
Clears all declared variables.
|
||||
\subsection{DATA}
|
||||
\codeline{\textbf{DATA} CONST0 [\textbf{,} CONST1]\ldots}\par
|
||||
Adds data that can be read by \code{READ} function. \code{DATA} declarations need not be reacheable in the program flow.
|
||||
\subsection{END}
|
||||
\codeline{\textbf{END}}\par
|
||||
Stops program execution and returns control to the user.
|
||||
@@ -131,9 +142,6 @@ Functions are a form of expression that may taks input arguments surrounded by p
|
||||
\subsection{NEXT}
|
||||
\codeline{\textbf{NEXT}}\par
|
||||
Iterates \code{FOR-NEXT} loop and increments the loop variable from the most recent \code{FOR} statement and jumps to that statement.
|
||||
\subsection{READ}
|
||||
\codeline{\textbf{READ} VARIABLE}\par
|
||||
Assigns data declared from \code{DATA} statements to given variable. Reading starts at the current \code{DATA} position, and the data position will be incremented by one. The position is reset to the zero by the \code{RUN} command.
|
||||
\subsection{RESTORE}
|
||||
\codeline{\textbf{RESTORE}}\par
|
||||
Resets the \code{DATA} pointer.
|
||||
@@ -159,6 +167,22 @@ Functions are a form of expression that may taks input arguments surrounded by p
|
||||
\subsection{SPC}
|
||||
\codeline{STR \textbf{= SPC(}STR \textbf{,} NUM\_CHARS\textbf{)}}\par
|
||||
Returns a string of \code{NUM\_CHARS} spaces.
|
||||
|
||||
\section{Array Manipulation}
|
||||
|
||||
\subsection{HEAD}
|
||||
\codeline{K \textbf{= HEAD(}ARRAY\textbf{)}}\par
|
||||
Returns the head element of the given array.
|
||||
\subsection{INIT}
|
||||
\codeline{K \textbf{= INIT(}ARRAY\textbf{)}}\par
|
||||
Returns the new array that has its last element removed.
|
||||
\subsection{LAST}
|
||||
\codeline{K \textbf{= LAST(}ARRAY\textbf{)}}\par
|
||||
Returns the last element of the given array.
|
||||
\subsection{TAIL}
|
||||
\codeline{K \textbf{= TAIL(}ARRAY\textbf{)}}\par
|
||||
Returns the new array that has its head element removed.
|
||||
|
||||
\section{Graphics}
|
||||
|
||||
\subsection{PLOT}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
\label{implementation}
|
||||
|
||||
This chapter explains implementation details of \tbas{} running on TSVM.
|
||||
This chapter explains implementation details of \tbas\ running on \thismachine.
|
||||
|
||||
\section{Keycodes}
|
||||
|
||||
This is a keycodes recognised by LibGDX, a framework that TSVM runs on.
|
||||
This is a keycodes recognised by LibGDX, a framework that \thismachine\ runs on.
|
||||
|
||||
\begin{longtable}{*{2}{m{\textwidth}}}\hline
|
||||
\endfirsthead
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
\tbas{} is a BASIC dialect and its interpreter. \tbas{} emulates most of the common BASIC syntax while adds more advanced and up-to-date concepts gracefully, such as user-defined function that can \emph{actually} recurse, arbitrary list construction using CONS-operator and some of the features in the realm of functional programming from \code{MAP} and \code{FOLD} to \code{CURRY}-ing a function.
|
||||
\tbas\ is a BASIC dialect and its interpreter. \tbas\ emulates most of the common BASIC syntax while adds more advanced and up-to-date concepts gracefully, such as user-defined function that can \emph{actually} recurse, arbitrary list construction using CONS-operator and some of the features in the realm of functional programming from \code{MAP} and \code{FOLD} to \code{CURRY}-ing a function.
|
||||
|
||||
This is the documentation for \tbas{} \tbasver{}.
|
||||
This is the documentation for \tbas\ \tbasver.
|
||||
|
||||
\vfill
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
\newcommand{\intrange}{\hl{[$0..2^{53}-1$]}}
|
||||
|
||||
This chapter describes the \tbas{} language.
|
||||
This chapter describes the \tbas\ language.
|
||||
|
||||
\section{Metasyntax}
|
||||
|
||||
@@ -19,7 +19,7 @@ In the descriptions of BASIC syntax, these conventions apply.
|
||||
|
||||
A \emph{Program Line} consists of a line number followed by a \emph{Statements}. Program Lines are terminated by a line break or by the end-of-the-file.
|
||||
|
||||
A \emph{Line Number} is an integer within the range of \intrange{}.
|
||||
A \emph{Line Number} is an integer within the range of \intrange.
|
||||
|
||||
A \emph{Statement} is special form of code which has special meaning. A program line can be composed of 1 or more statements, separated by colons. For the details of statements available in \tbas , see \ref{statements}.
|
||||
|
||||
@@ -58,7 +58,7 @@ Numeric literals take one of the following forms:
|
||||
\codeline{\textbf{0}\{\textbf{x}|\textbf{X}\}[\textbf{0}|\textbf{1}|\textbf{2}|\textbf{3}|\textbf{4}|\textbf{5}|\textbf{6}|\textbf{7}|\textbf{8}|\textbf{9}]\ldots}\\
|
||||
\codeline{\textbf{0}\{\textbf{b}|\textbf{B}\}[\textbf{0}|\textbf{1}|\textbf{2}|\textbf{3}|\textbf{4}|\textbf{5}|\textbf{6}|\textbf{7}|\textbf{8}|\textbf{9}]\ldots}
|
||||
|
||||
Hexadecimal and binary literals are always interpreted as \emph{unsigned} integers. They must range between \intrange{}.
|
||||
Hexadecimal and binary literals are always interpreted as \emph{unsigned} integers. They must range between \intrange.
|
||||
|
||||
\subsection{Variables}
|
||||
|
||||
@@ -66,11 +66,11 @@ Variable names must start with a letter and all characters of the name must be l
|
||||
|
||||
Unlike conventional BASIC dialects (especially GW-BASIC), name pool of variables are shared between all the types. For example, if you have a numeric variable \code{A}, and define an array named \code{A} later in the program, the new array will overwrite your numeric \code{A}.
|
||||
|
||||
Furthermore, \emph{sigils} are not used in the \tbas{} and attempting to use one will raise syntax-error or undefined behaviour.
|
||||
Furthermore, \emph{sigils} are not used in the \tbas\ and attempting to use one will raise syntax-error or undefined behaviour.
|
||||
|
||||
\subsection{Types}
|
||||
|
||||
Types of data recognised by \tbas{} are distinguished by some arcane magic of Javascript auto-casing mumbo-jumbo
|
||||
Types of data recognised by \tbas\ are distinguished by some arcane magic of Javascript auto-casing mumbo-jumbo
|
||||
|
||||
\begin{tabulary}{\textwidth}{rCL}
|
||||
Type & Range & Precision \\
|
||||
@@ -245,8 +245,8 @@ Function operators operate on functions and some values.
|
||||
\begin{tabulary}{\textwidth}{clL}
|
||||
Code & Operation & Result \\
|
||||
\hline
|
||||
\emph{f} \basiccurry{} \emph{x} & Curry & Apply \emph{x} into the first parameter of the function \emph{f} \\
|
||||
%{[}\emph{x},\,\emph{y}\ldots{]} \basicclosure{} \emph{e} & Closure & Creates a closure (anonymous function) from one or more parameters \emph{x},\,\emph{y}\ldots\ and an expression \emph{e} \\
|
||||
\emph{f} \basiccurry\ \emph{x} & Curry & Apply \emph{x} into the first parameter of the function \emph{f} \\
|
||||
%{[}\emph{x},\,\emph{y}\ldots{]} \basicclosure\ \emph{e} & Closure & Creates a closure (anonymous function) from one or more parameters \emph{x},\,\emph{y}\ldots\ and an expression \emph{e} \\
|
||||
\end{tabulary}
|
||||
|
||||
\emph{Currying} is an operation that returns new function that has given value applied to the original function's first parameter. See \ref{currying101} for tutorials.
|
||||
|
||||
@@ -31,7 +31,7 @@ Jumps to the line number returned by the \code{INDEX\_EXPRESSION}. If the result
|
||||
|
||||
\section{DEFUN}
|
||||
|
||||
\emph{There it is, the} DEFUN. \emph{All those new-fangled parser\footnote{a computer program that translates program code entered by you into some data bits that only it can understand} and paradigms\footnote{a guidance to in which way you must think to assimilate your brain into the computer-overlord} are tied to this very statement on \tbas{}, and only Wally knows its secrets\ldots}
|
||||
\emph{There it is, the} DEFUN. \emph{All those new-fangled parser\footnote{a computer program that translates program code entered by you into some data bits that only it can understand} and paradigms\footnote{a guidance to in which way you must think to assimilate your brain into the computer-overlord} are tied to this very statement on \tbas, and only Wally knows its secrets\ldots}
|
||||
|
||||
\codeline{\textbf{DEFUN} NAME \textbf{(} [ARGS0 [\textbf{,} ARGS1]\ldots] \textbf{)} \textbf{=} EXPRESSION }
|
||||
|
||||
|
||||
@@ -143,13 +143,15 @@
|
||||
\newcommand{\theedition}{First Edition}
|
||||
\newcommand{\oreallypress}{\large\textbf{O'REALLY\raisebox{1ex}{\scriptsize ?}} \normalsize Press}
|
||||
|
||||
\title{\HUGE\textbf{TERRAN BASIC \\ REFERENCE MANUAL} \\ \Large \vspace{1em} For Version \tbasver \\ \vspace{7mm} \theedition}
|
||||
\title{\HUGE\textbf{\MakeUppercase{\tbas} \\ REFERENCE MANUAL} \\ \Large \vspace{1em} For Language Version \tbasver \\ \vspace{7mm} \theedition}
|
||||
\date{}
|
||||
\author{}
|
||||
\hypersetup{
|
||||
pdfauthor={Torvald et al.},
|
||||
pdftitle={\tbas{} Reference Manual, \theedition{} (BASIC version \tbasver{})},
|
||||
unicode=true
|
||||
pdfauthor={CuriousTorvald},
|
||||
pdftitle={\tbas\ Reference Manual For Language Version \tbasver, \theedition},
|
||||
unicode=true,
|
||||
pdfkeywords={BASIC} {Functional Programming} {Improper Hierarchy},
|
||||
pdfcreator=\oreallypress
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
Reference in New Issue
Block a user