PyLogo


builtins

builtins for pylogo Ian Bicking <ianb@colorstudy.com>

These implement the builtins, as much as possible using the standard library of UCBLogo as a model. See also the UCBLogo Manual.

Organization of this module follows the organization of the UCB manual.

All missing functions are noted in comments and marked with '@@'


Attributes

a EOF

[EOF]

Functions

f word(*args) ...

WORD word1 word2 (WORD word1 word2 word3 ...)

outputs a word formed by concatenating its inputs.

f logo_list(*args) ...

LIST thing1 thing2 (LIST thing1 thing2 thing3 ...)

outputs a list whose members are its inputs, which can be any Logo datum (word, list, or array).

f logo_repr(arg) ...

f logo_soft_repr(arg) ...

Like logoRepr, only we're already in a quoted context, so we don't have to quote strings.

f logo_str(arg) ...

f sentence(*args) ...

SENTENCE thing1 thing2 SE thing1 thing2 (SENTENCE thing1 thing2 thing3 ...) (SE thing1 thing2 thing3 ...)

outputs a list whose members are its inputs, if those inputs are not lists, or the members of its inputs, if those inputs are lists.

f fput(thing, l) ...

FPUT thing list

outputs a list equal to its second input with one extra member, the first input, at the beginning.

f lput(thing, l) ...

LPUT thing list

outputs a list equal to its second input with one extra member, the first input, at the end.

f combine(thing1, thing2) ...

COMBINE thing1 thing2

if thing2 is a word, outputs WORD thing1 thing2. If thing2 is a list, outputs FPUT thing1 thing2.

f reverse(l) ...

REVERSE list

outputs a list whose members are the members of the input list, in reverse order.

f gensym() ...

GENSYM

outputs a unique word each time it's invoked. The words are of the form G1, G2, etc.

f first(thing) ...

FIRST thing

if the input is a word, outputs the first character of the word. If the input is a list, outputs the first member of the list. If the input is an array, outputs the origin of the array (that is, the INDEX OF the first member of the array).

f firsts(things) ...

FIRSTS list

outputs a list containing the FIRST of each member of the input list. It is an error if any member of the input list is empty. (The input itself may be empty, in which case the output is also empty.) This could be written as:

to firsts :list
    output map "first :list
end

but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH:

to transpose :matrix
    if emptyp first :matrix [op []]
    op fput firsts :matrix transpose bfs :matrix
end

f last(thing) ...

LAST wordorlist

if the input is a word, outputs the last character of the word. If the input is a list, outputs the last member of the list.

f butfirst(thing) ...

BUTFIRST wordorlist BF wordorlist

if the input is a word, outputs a word containing all but the first character of the input. If the input is a list, outputs a list containing all but the first member of the input.

f butfirsts(things) ...

BUTFIRSTS list BFS list

outputs a list containing the BUTFIRST of each member of the input list. It is an error if any member of the input list is empty or an array. (The input itself may be empty, in which case the output is also empty.) This could be written as:

to butfirsts :list
    output map "butfirst :list
end

but is provided as a primitive in order to speed up the iteration tools MAP, MAP.SE, and FOREACH.

f butlast(thing) ...

BUTLAST wordorlist BL wordorlist

if the input is a word, outputs a word containing all but the last character of the input. If the input is a list, outputs a list containing all but the last member of the input.

f item(index, thing) ...

ITEM index thing

if the thing is a word, outputs the index``th character of the word.  If the ``thing is a list, outputs the index``th member of the list.  If the ``thing is an array, outputs the index``th member of the array.  ``Index starts at 1 for words and lists; the starting index of an array is specified when the array is created.

f pick(l) ...

PICK list

outputs a randomly chosen member of the input list.

f remove(thing, l) ...

REMOVE thing list

outputs a copy of list with every member equal to thing removed.

f remdup(l) ...

REMDUP list

outputs a copy of list with duplicate members removed. If two or more members of the input are equal, the rightmost of those members is the one that remains in the output.

f setitem(index, thing, value) ...

SETITEM index array value

command. Replaces the index``th member of ``array with the new value. Ensures that the resulting array is not circular, i.e., value may not be a list or array that contains array.

f dotsetfirst(lst, value) ...

.SETFIRST list value

command. Changes the first member of list to be value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETFIRST can lead to circular list structures, which will get some Logo primitives into infinite loops; and unexpected changes to other data structures that share storage with the list being modified.

f dotsetbf(lst, value) ...

.SETBF list value

command. Changes the butfirst of list to be value. WARNING: Primitives whose names start with a period are DANGEROUS. Their use by non-experts is not recommended. The use of .SETBF can lead to circular list structures, which will get some Logo primitives into infinite loops; unexpected changes to other data structures that share storage with the list being modified. list.

f wordp(thing) ...

WORDP thing WORD? thing

outputs TRUE if the input is a word, FALSE otherwise.

f listp(val) ...

LISTP thing LIST? thing

outputs TRUE if the input is a list, FALSE otherwise.

f emptyp(thing) ...

EMPTYP thing EMPTY? thing

outputs TRUE if the input is the empty word or the empty list, FALSE otherwise.

f equalp(thing1, thing2) ...

EQUALP thing1 thing2 EQUAL? thing1 thing2 thing1 = thing2

outputs TRUE if the inputs are equal, FALSE otherwise. Two numbers are equal if they have the same numeric value. Two non-numeric words are equal if they contain the same characters in the same order. If there is a variable named CASEIGNOREDP whose value is TRUE, then an upper case letter is considered the same as the corresponding lower case letter. (This is the case by default.) Two lists are equal if their members are equal. An array is only equal to itself; two separately created arrays are never equal even if their members are equal. (It is important to be able to know if two expressions have the same array as their value because arrays are mutable; if, for example, two variables have the same array as their values then performing SETITEM on one of them will also change the other.)

f beforep(word1, word2) ...

BEFOREP word1 word2 BEFORE? word1 word2

outputs TRUE if word1 comes before word2 in ASCII collating sequence (for words of letters, in alphabetical order). Case-sensitivity is determined by the value of CASEIGNOREDP. Note that if the inputs are numbers, the result may not be the same as with LESSP; for example, BEFOREP 3 12 is false because 3 collates after 1.

f doteq(thing1, thing2) ...

.EQ thing1 thing2

outputs TRUE if its two inputs are the same datum, so that applying a mutator to one will change the other as well. Outputs FALSE otherwise, even if the inputs are equal in value.

f memberp(thing1, l) ...

MEMBERP thing1 thing2 MEMBER? thing1 thing2

if thing2 is a list or an array, outputs TRUE if thing1 is EQUALP to a member of thing2, FALSE otherwise. If thing2 is a word, outputs TRUE if thing1 is a one-character word EQUALP to a character of thing2, FALSE otherwise.

f substringp(thing1, thing2) ...

SUBSTRINGP thing1 thing2 SUBSTRING? thing1 thing2

if thing1 or thing2 is a list or an array, outputs FALSE. If thing2 is a word, outputs TRUE if thing1 is EQUALP to a substring of thing2, FALSE otherwise.

f numberp(thing) ...

NUMBERP thing NUMBER? thing

outputs TRUE if the input is a number, FALSE otherwise.

f count(thing) ...

COUNT thing

outputs the number of characters in the input, if the input is a word; outputs the number of members in the input, if it is a list or an array. (For an array, this may or may not be the index of the last member, depending on the array's origin.)

f ascii(char) ...

ASCII char

outputs the integer (between 0 and 255) that represents the input character in the ASCII code.

f char(int) ...

CHAR int

outputs the character represented in the ASCII code by the input, which must be an integer between 0 and 255.

f member(thing1, thing2) ...

MEMBER thing1 thing2

if thing2 is a word or list and if MEMBERP with these inputs would output TRUE, outputs the portion of thing2 from the first instance of thing1 to the end. If MEMBERP would output FALSE, outputs the empty word or list according to the type of thing2. It is an error for thing2 to be an array.

f lowercase(word) ...

LOWERCASE word

outputs a copy of the input word, but with all uppercase letters changed to the corresponding lowercase letter.

f uppercase(word) ...

UPPERCASE word

outputs a copy of the input word, but with all lowercase letters changed to the corresponding uppercase letter.

f pr(*args) ...

PRINT thing thing2 thing3 ... PR thing (PRINT thing1 thing2 ...) (PR thing1 thing2 ...)

command. Prints the input or inputs to the current write stream (initially the terminal). All the inputs are printed on a single line, separated by spaces, ending with a newline. If an input is a list, square brackets are not printed around it, but brackets are printed around sublists. Braces are always printed around arrays.

f logo_type(*args) ...

TYPE thing thing2 thing3 ... (TYPE thing1 thing2 ...)

command. Prints the input or inputs like PRINT, except that no newline character is printed at the end and multiple inputs are not separated by spaces.

f show(*args) ...

SHOW thing thing2 thing3 ... (SHOW thing1 thing2 ...)

command. Prints the input or inputs like PRINT, except that if an input is a list it is printed inside square brackets.

f readlist() ...

READLIST RL

reads a line from the read stream (initially the terminal) and outputs that line as a list. The line is separated into members as though it were typed in square brackets in an instruction. If the read stream is a file, and the end of file is reached, READLIST outputs the empty word (not the empty list). READLIST processes backslash, vertical bar, and tilde characters in the read stream; the output list will not contain these characters but they will have had their usual effect. READLIST does not, however, treat semicolon as a comment character.

f readrawline() ...

READRAWLINE

reads a line from the read stream and outputs that line as a word. The output is a single word even if the line contains spaces, brackets, etc. If the read stream is a file, and the end of file is reached, READRAWLINE outputs the empty list (not the empty word). READRAWLINE outputs the exact string of characters as they appear in the line, with no special meaning for backslash, vertical bar, tilde, or any other formatting characters.

f sum(*args) ...

SUM num1 num2 (SUM num1 num2 num3 ...) num1 + num2

outputs the sum of its inputs.

f difference(num1, num2) ...

DIFFERENCE num1 num2 num1 - num2

outputs the difference of its inputs. Minus sign means infix difference in ambiguous contexts (when preceded by a complete expression), unless it is preceded by a space and followed by a nonspace. (See also MINUS.)

f minus(num) ...

MINUS num - num

outputs the negative of its input. Minus sign means unary minus if the previous token is an infix operator or open parenthesis, or it is preceded by a space and followed by a nonspace. There is a difference in binding strength between the two forms:

MINUS 3 + 4     ; means    -(3+4)
- 3 + 4         ; means    (-3)+4

f product(*args) ...

PRODUCT num1 num2 (PRODUCT num1 num2 num3 ...) num1 * num2

outputs the product of its inputs.

f quotient(num1, num2) ...

QUOTIENT num1 num2 (QUOTIENT num) num1 / num2

outputs the quotient of its inputs. The quotient of two integers is an integer if and only if the dividend is a multiple of the divisor. (In other words, QUOTIENT 5 2 is 2.5, not 2, but QUOTIENT 4 2 is 2, not 2.0 -- it does the right thing.) With a single input, QUOTIENT outputs the reciprocal of the input.

f remainder(num1, num2) ...

REMAINDER num1 num2

outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num1.

f modulo(num1, num2) ...

MODULO num1 num2

outputs the remainder on dividing num1 by num2; both must be integers and the result is an integer with the same sign as num2.

f logo_int(num) ...

INT num

outputs its input with fractional part removed, i.e., an integer with the same sign as the input, whose absolute value is the largest integer less than or equal to the absolute value of the input.

f logo_round(v, *args) ...

ROUND num

outputs the nearest integer to the input.

f logo_abs(v) ...

f sqrt(v) ...

SQRT num

outputs the square root of the input, which must be nonnegative.

f power(num1, num2) ...

POWER num1 num2

outputs num1 to the num2 power. If num1 is negative, then num2 must be an integer.

f exp(v) ...

EXP num

outputs e (2.718281828+) to the input power.

f log10(v) ...

LOG10 num

outputs the common logarithm of the input.

f ln(v) ...

LN num

outputs the natural logarithm of the input.

f sin(num) ...

SIN degrees

outputs the sine of its input, which is taken in degrees.

f radsin(v) ...

RADSIN radians

outputs the sine of its input, which is taken in radians.

f cos(num) ...

COS degrees

outputs the cosine of its input, which is taken in degrees.

f radcos(v) ...

RADCOS radians

outputs the cosine of its input, which is taken in radians.

f arctan(num, second=None) ...

ARCTAN num (ARCTAN x y)

outputs the arctangent, in degrees, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or 90 or -90 depending on the sign of y, if x is zero.

f radarctan(num, second=None) ...

RADARCTAN num (RADARCTAN x y)

outputs the arctangent, in radians, of its input. With two inputs, outputs the arctangent of y/x, if x is nonzero, or pi/2 or -pi/2 depending on the sign of y, if x is zero.

The expression 2*(RADARCTAN 0 1) can be used to get the value of pi.

f iseq(from_num, to_num) ...

ISEQ from to

outputs a list of the integers from FROM to TO, inclusive:

? show iseq 3 7
[3 4 5 6 7]
? show iseq 7 3
[7 6 5 4 3]

f rseq(from_num, to_num, length) ...

RSEQ from to count

outputs a list of COUNT equally spaced rational numbers between FROM and TO, inclusive:

? show rseq 3 5 9
[3 3.25 3.5 3.75 4 4.25 4.5 4.75 5]
? show rseq 3 5 5
[3 3.5 4 4.5 5]

f lessp(num1, num2) ...

LESSP num1 num2 LESS? num1 num2 num1 < num2

outputs TRUE if its first input is strictly less than its second.

f greaterp(num1, num2) ...

GREATERP num1 num2 GREATER? num1 num2 num1 > num2

outputs TRUE if its first input is strictly greater than its second.

f logo_random(num) ...

RANDOM num

outputs a random nonnegative integer less than its input, which must be an integer.

f rerandom(seed=None) ...

RERANDOM (RERANDOM seed)

command. Makes the results of RANDOM reproducible. Ordinarily the sequence of random numbers is different each time Logo is used. If you need the same sequence of pseudo-random numbers repeatedly, e.g. to debug a program, say RERANDOM before the first invocation of RANDOM. If you need more than one repeatable sequence, you can give RERANDOM an integer input; each possible input selects a unique sequence of numbers.

f bitand(*args) ...

BITAND num1 num2 (BITAND num1 num2 num3 ...)

outputs the bitwise AND of its inputs, which must be integers.

f bitor(*args) ...

BITOR num1 num2 (BITOR num1 num2 num3 ...)

outputs the bitwise OR of its inputs, which must be integers.

f bitxor(*args) ...

BITXOR num1 num2 (BITXOR num1 num2 num3 ...)

outputs the bitwise EXCLUSIVE OR of its inputs, which must be integers.

f bitnot(num) ...

BITNOT num

outputs the bitwise NOT of its input, which must be an integer.

f ashift(num1, num2) ...

ASHIFT num1 num2

outputs num1 arithmetic-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with sign extension. The inputs must be integers.

f lshift(num1, num2) ...

LSHIFT num1 num2

outputs num1 logical-shifted to the left by num2 bits. If num2 is negative, the shift is to the right with zero fill. The inputs must be integers.

f logo_and(interp, *vals) ...

AND tf1 tf2 (AND tf1 tf2 tf3 ...)

outputs TRUE if all inputs are TRUE, otherwise FALSE. An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a FALSE value is found, the remaining inputs are not examined. Example:

MAKE "RESULT AND [NOT (:X = 0)] [(1 / :X) > .5]

to avoid the division by zero if the first part is false.

f logo_or(interp, *vals) ...

OR tf1 tf2 (OR tf1 tf2 tf3 ...)

outputs TRUE if any input is TRUE, otherwise FALSE. An input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value. List expressions are evaluated from left to right; as soon as a TRUE value is found, the remaining inputs are not examined. Example:

IF OR :X=0 [some.long.computation] [...]

to avoid the long computation if the first condition is met.

f logo_not(interp, val) ...

NOT tf

outputs TRUE if the input is FALSE, and vice versa. The input can be a list, in which case it is taken as an expression to run; that expression must produce a TRUE or FALSE value.

f logo_define(interp, procname, text) ...

DEFINE procname text

command. Defines a procedure with name procname and text text. If there is already a procedure with the same name, the new definition replaces the old one. The text input must be a list whose members are lists. The first member is a list of inputs; it looks like a TO line but without the word TO, without the procedure name, and without the colons before input names. In other words, the members of this first sublist are words for the names of required inputs and lists for the names of optional or rest inputs. The remaining sublists of the text input make up the body of the procedure, with one sublist for each instruction line of the body. (There is no END line in the text input.)

f text(interp, procname) ...

TEXT procname

outputs the text of the procedure named procname in the form expected by DEFINE: a list of lists, the first of which describes the inputs to the procedure and the rest of which are the lines of its body. The text does not reflect formatting information used when the procedure was defined, such as continuation lines and extra spaces.

f thing(interp, v) ...

THING varname :quoted.varname

outputs the value of the variable whose name is the input. If there is more than one such variable, the innermost local variable of that name is chosen. The colon notation is an abbreviation not for THING but for the combination so that :FOO means THING "FOO.

f procedurep(interp, name) ...

PROCEDUREP name PROCEDURE? name

outputs TRUE if the input is the name of a procedure.

f primitivep(interp, name) ...

PRIMITIVEP name PRIMITIVE? name

outputs TRUE if the input is the name of a primitive procedure (one built into Logo).

f definedp(interp, name) ...

DEFINEDP name DEFINED? name

outputs TRUE if the input is the name of a user-defined procedure.

f namep(interp, name) ...

NAMEP name NAME? name

outputs TRUE if the input is the name of a variable.

f procedures(interp) ...

PROCEDURES

outputs a list of the names of all unburied user-defined procedures in the workspace.

f names(interp) ...

NAMES

outputs a contents list consisting of an empty list (indicating no procedure names) followed by a list of all unburied variable names in the workspace.

f erase(interp, l) ...

ERASE contentslist ER contentslist

command. Erases from the workspace the procedures, variables, and property lists named in the input. Primitive procedures may not be erased unless the variable REDEFP has the value TRUE.

f erall(interp) ...

ERALL

command. Erases all unburied procedures, variables, and property lists from the workspace. Abbreviates ERASE CONTENTS.

f erps(interp) ...

ERPS

command. Erases all unburied procedures from the workspace. Abbreviates ERASE PROCEDURES.

f erns(interp) ...

ERNS

command. Erases all unburied variables from the workspace. Abbreviates ERASE NAMES.

f load(interp, name) ...

f logo_help(interp, name) ...

HELP name

command. Prints information from the reference manual about the primitive procedure named by the input.

f logo_run(interp, l) ...

RUN instructionlist

command or operation. Runs the Logo instructions in the input list; outputs if the list contains an expression that outputs.

f logo_eval(interp, l) ...

f repeat(interp, n, block) ...

REPEAT num instructionlist

command. Runs the instructionlist repeatedly, num times.

f forever(interp, block) ...

f repcount(interp) ...

REPCOUNT

outputs the repetition count of the innermost current REPEAT or FOREVER, starting from 1. If no REPEAT or FOREVER is active, outputs -1.

f test(interp, val) ...

f iftrue(interp, lst) ...

IFTRUE instructionlist IFT instructionlist

command. Runs its input if the most recent TEST instruction had a TRUE input. The TEST must have been in the same procedure or a superprocedure.

f iffalse(interp, lst) ...

IFFALSE instructionlist IFF instructionlist

command. Runs its input if the most recent TEST instruction had a FALSE input. The TEST must have been in the same procedure or a superprocedure.

f logo_if(interp, expr, block, elseBlock=None) ...

IF tf instructionlist (IF tf instructionlist1 instructionlist2)

command. If the first input has the value TRUE, then IF runs the second input. If the first input has the value FALSE, then IF does nothing. (If given a third input, IF acts like IFELSE, as described below.) It is an error if the first input is not either TRUE or FALSE.

f logo_ifelse(interp, expr, trueBlock, falseBlock) ...

IFELSE tf instructionlist1 instructionlist2

command or operation. If the first input has the value TRUE, then IFELSE runs the second input. If the first input has the value FALSE, then IFELSE runs the third input. IFELSE outputs a value if the instructionlist contains an expression that outputs a value.

f stop() ...

STOP

command. Ends the running of the procedure in which it appears. Control is returned to the context in which that procedure was invoked. The stopped procedure does not output a value.

f output(value) ...

OUTPUT value OP value RETURN value

command. Ends the running of the procedure in which it appears. That procedure outputs the value value to the context in which it was invoked. Don't be confused: OUTPUT itself is a command, but the procedure that invokes OUTPUT is an operation.

f bye() ...

f ignore(value) ...

IGNORE value

command. Does nothing. Used when an expression is evaluated for a side effect and its actual value is unimportant.

f backtick(interp, lst) ...

BACKTICK list

outputs a list equal to its input but with certain substitutions. If a member of the input list is the word , (comma) then the following member should be an instructionlist that produces an output when run. That output value replaces the comma and the instructionlist. If a member of the input list is the word @ (atsign) then the following member should be an instructionlist that outputs a list when run. The members of that list replace the @ and the instructionlist. Example:

show `[foo baz ,[bf [a b c]] garply @[bf [a b c]]]

will print:

[foo baz [b c] garply b c]

f logoWhile(interp, test, block) ...

WHILE tfexpression instructionlist

command. Repeatedly evaluates the instructionlist as long as the evaluated tfexpression remains TRUE. Evaluates the first input first, so the instructionlist may never be run at all. The tfexpression must be an expressionlist whose value when evaluated is TRUE or FALSE.

f logo_for(interp, name, l, block) ...

f dowhile(interp, block, clause) ...

f until(interp, clause, block) ...

f dountil(interp, block, clause) ...

f logo_assert(value, message=None) ...

f assertequal(value1, value2, message=None) ...

f function(interp, name, default=<class pylogo.builtins.NoDefault at 0xb746bc8c>) ...

f catch(interp, block, *args) ...

f logo_getattr(obj, attr, *args) ...

f logo_setattr(obj, attr, *args) ...

f spawn(interp, block, starter=None) ...

f wait(sec) ...

f startsync(interp) ...

f sync(interp, sec) ...

f logo_import(interp, name) ...

f newdict(lst=None) ...

f keys(d) ...

f values(d) ...

f items(d) ...

f call(interp, func, *args) ...

f logo_new(interp, cls) ...

Classes

C NoDefault(...) ...

See the source for more information.