FOCAL-81 ORIGINAL VERSION Focal-81 is originally written by Dave Conroy . Modified and debugged by Akira KIDA List of modifications: - Now compile under ANSI-C environment. Still compile under K&R C, but require ANSI compatible headers. - Supports 'lib list' command using directory handling libraries. i.e. opendir(), readdir(), ... etc. I think they are POSIX compatible. - Also supports 'lib list' command on MS-DOS / MS-C environment. - Uses simple hash mechanisms for symbol tables. - Critical bug in releasing nested 'for' control stack frame is now fixed. I (Kida) tested in the following environments: Sun SPARCstation running SunOS 4.1.3 + sun cc (K&R) Sun SPARCstation running SunOS 4.1.3 + gcc 2.6.3 (ANSI) Sun SPARCstation running Solaris 2.3 + SunPro cc 2.0.1 (ANSI) Sun SPARCstation running Solaris 2.3 + gcc 2.6.3 (ANSI) HP9000 model 720 (HPPA) running HPUX 8.05 + hp cc (ANSI) HP9000 model 720 (HPPA) running HPUX 8.05 + gcc 2.5.8 (ANSI) MS-DOS + MS-C 6.0 (ANSI) MS-DOS + LSI C-86 3.30 (very close to ANSI) Copyright or lack of it: Akira KIDA puts all the modifications in the public domain. Although I'm not sure what the original copyright condition is. enjoy! Apr. 11, 1995 Akira KIDA, SDI00379@niftyserve.or.jp ============================================================================ FOCAL INTERPRETER for MS-DOS 2.2 Quick C 2.0 version by L.C. - Feb. 12, 2013 - from Akira Kida 1995 version (here named as "original") ************************************************************************* Developed with Microsoft Quick C 2.0 under Win XP Dos Prompt. Tested in Win XP Professional, Win 2000, Win 9x, MS-DOS 6.22 environment. Focal 2.2 without graphic commands probably can be recompiled 'as is' under other environments; with graphic commands it's PC specific and can be used **ONLY** on a PC with **ANY** color card under a full-screen DOS Prompt. PDP versions considered in developing Focal for MS-DOS are: 1) FOCAL-69, the original version 2) FOCAL-71, the second release 3) UW-FOCAL, the extended version. N.B.: There are some beta releases (from 1.0 to 1.7 and from 2.0 to 2.1) before 2.2. ************************************************************************* 1. INSTALLATION There isn't an installation procedure: it's enough to create a folder (like C:\FOCAL) and unzipped there the file FOCAL22.ZIP. FOCAL22.ZIP contains the following files: FOCAL.EXE --- 2.2 executable; FOCAL.HLP --- help file; FOCAL.C, FOCAL.H and PROTO.H --- 2.2 source files; FOCAL.TXT --- this text; EX_*.FOC --- a group of Focal files showing commands *.FOC --- other source files from various sources. MAKEFILE.DOS --- a make file for compiling under Quick C 2.0 FOCAL69.PDF --- a DEC booklet on FOCAL69, the original version of the language under a PDP-8 minicomputer. For a full use you must have: 1) ANSI.SYS installed 2) EDIT.COM in the DOS path. 2. LIST OF MODIFICATIONS FROM ORIGINAL VERSION. - New commands implemented: break, help, hesitate, jump, keypress, library run/input/output/fclose/type/ask, modify, notify, on, plot, user, vardump (or $), xdos, yncrement, zero, ? and '. - Char oriented function (fin & fout). - User function support with 'user' command and 'fuser' function calls. - Extensions: '@' and ':' commands for type and ask - Reserved var pi (=3.141592654...) - Sequential file usage (both numeric and character) - Printer usage; - Corrected operator precedence and for loop syntax: now equal to FOCAL69 (multplication executed before division, for loop step is between initial and final value). 3. USAGE: focal ["filename"] [<"input_file">] [>"output_file"] N.B: focal "filename" loads *AND* execute "filename". 4. COMMANDS In description below: LGRP means any of a group number (ex. 10, 20). LNUM means any of a line number (ex. 10.30, 20.40). All the commands may be abbreviated to the first letter. N.B. Commands may be written both in capital and lower letters. Variables written in capitals and lowers are different: n and N are two *different* variables. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ask interactive numeric value assignment to variable(s). [from original] ask (["PROMPT"][,][v][,])... N.B.: v can be subscripted (v(i)). N.B.: PROMPT can be a '@' command or a ':' command (see type) N.B.: From Release 1.6 input a string for an 'ask' variable gives the ASCII value of the first character: if the answer for an 'ask v' is ABC then the value for v will be 65. Previously, the answer was '0'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ break exit from a for loop. [from Release 1.7] break LNUM exit from a for loop and jump to LNUM. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ comment/continue [from original] comment skip until end-of-line. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do call subroutine. [from original] do all call all groups in order as subroutine. do LNUM call specified line and just return after executing the line only. do LGRP call specified line group and return after executing all the lines belong to the group. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ erase erase whole or a part of program/variable on memory. [from original] erase erase all the variable. erase all erase the entire program. erase LNUM erase the specified line. erase LGRP erase the specified line group. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for iteration. [from original] for v=i,e; do with v from i through e by 1. for v=i,s,e; do with v from i through e by s. N.B.: v can be subscripted (v(i)). N.B.: Nested for loops on the *same* line are possible using ' command. For example: 01.10 for i=1,2; for j=1,3; '; type i+j! is equivalent to GWBASIC line instructions: 10 FOR I=1 TO 2: FOR J=1 TO 3: PRINT I+J: NEXT J,I N.B.: For loop syntax is the same of PDP Focal: in GWBASIC we write FOR v = i TO e STEP s ...... while in Focal is for v=i,s,e; ........ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ go/goto unconditional jump. [from original] goto LNUM jump to the specified line. goto jump to the beginning of the program. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help on-line help (*only* in immediate mode) [from Release 1.0] help * shows all commands or help ITEM shows ITEM (if exists) N.B.: From release 2.2, help is reading from the external file 'focal.hlp'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ hesitate delay (in millisecond) [from Release 1.3] hesitate e pause program for e milliseconds. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if conditional. [from original] if e LNUM_NEG ; CMD if (e < 0) goto LNUM_NEG else CMD. if e LNUM_NEG, LNUM_ZERO ; CMD if (e < 0) goto LNUM_NEG else if (e == 0) goto LNUM_ZERO else CMD. if e LNUM_NEG, LNUM_ZERO, LNUM_POS if (e < 0) goto LNUM_NEG else if (e == 0) goto LNUM_ZERO else goto LNUM_POS. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ jump conditional. [from Release 1.1] jump e LNUM_1, LNUM_2, LNUM_3, ...... , LNUMn if (e <= 1) goto LNUM_1 if (e <= 2) goto LNUM_2 ........... if (e <= n) goto LNUM_n else continue. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ keypress wait for a keypressed [from Release 1.3] keypress ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ library extended command. [from original] library save save current program to . library call call (load) program from . library merge [from Release 2.1] merge program in memory with library run [from Release 1.4] run program from . If used in a program it acts as GWBASIC CHAIN command: load and execute FILENAME retaining all the variables of the called program. library delete delete . library list [] list library at or '.' if is omitted. For example 'library list *.foc' list all .foc programs in the current directory (with size, date and time of creation). library view [from Release 2.0] view one page at a time: press if you want to stop view. ***** for sequential files management: [from Release 1.4] library input <#>, open a seq file in input. Automatically file pointer is positioned at the beginning. library output <#>, open a seq file in output; library fclose <#> close a seq file; library type <#>, e[, e]... write numeric data on seq files; library type <#>,fout(e) [from Release 2.1] write char data on seq files; library ask <#>,v[,v][,])... read data from seq files in v; library ask <#>,v=fin() [from Release 2.1] read char data from seq files in v; N.B.: <#> is the file channel (a number from 0 to 9) so nine files can be opened at the same time). Channel 0 is automatically opened in write mode and is reserved to line printer (usually LPT1 or PRN). N.B.: For call, load, save library commands standard extension for Focal is ".foc", so, for example, 'library call sieve' loads 'sieve.foc'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ modify modify a line or edit current program (with DOS Edit). modify all edit current file (if saved) [from Release 1.1] N.B.: Valid only in immediate mode N.B.: EDIT.COM must be in the DOS path. modify LNUM OLDPATTERN\NEWPATTERN [from Release 1.2] in line LNUM change *all* the occurrence of OLDPATTERN with NEWPATTERN. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ notify show useful informations and control [from Release 1.4] graphic graphic [from Release 2.0] notify time show DOS time. notify date show DOS date. notify user [from Release 1.6] show user function definition. notify memory show memory available for programs. notify file show the filename currently in use (used by DOS Edit with a 'modify *' command). notify position v1,v2 [from Release 2.0] position cursor in row v1 and col v2 with 0<=v1<=24 and 0<=v2<=79. It can be considered a calculate '@' command. notify graphic enter graphic mode (640*200 black/white) for CGA and higher. notify xgraphic enter graphic mode (640*480 black/white) for VGA and higher. notify nographic return to text mode. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ on conditional to subroutine [from Release 1.7] on e LNUM_1, LNUM_2, LNUM_3, ...... , LNUMn if (e <= 1) do LNUM_1 if (e <= 2) do LNUM_2 ........... if (e <= n) do LNUM_n else "error". ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ plot set a pixel in graphic screen [from Release 2.0] plot e1,e2,e3 set a pixel at row e1 and column e2 with color e3 (0=black, 1=white). plot 0,0,1 *------------------------------------* plot 0,639,1 | | | | | | | | | * | | plot 100,320,1 | | | | | | | | | plot 199,0,1 *------------------------------------* plot 199,639,1 Graphic screen in graphic mode N.B. e1, e2, e3 are rounded as integer numbers. N.B. Limits are 0<=e1<=199 and 0<=e2<=639 for 'graphic' and 0<=e1<=479 and 0<=e2<=639 for 'xgraphic'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ quit stop execution. [from original] quit exit to operating system if used in top level. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return return form subroutine. [from original] return ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ set assign a value to a variable. [from original] set v=expr N.B.: v can be subscripted (v(i)). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type typeout. [from original] [ from Release 1.1 '@' cmds] [ from Release 2.0 ':' cmd] type e[, e]... e may be an arithmetic expression or one of the following: %IW.FW set integral precision IW and fraction precision FW. @E clear screen @L clear current line @r.c position cursor in row r and col c. (0<=R<=24, 0<=C<=79) @ home cursor (equals to @0.0) @An set attribute n according to ANSI MS-DOS (0<=n<=8) @Cf.b set char colors according to ANSI MS-DOS (0<=f<=7, 0<=b<=7) :n tabulate in column n on current line ! print newline. # print carriage return. "str" print string. Colors available are: 0=Black, 1=Red, 2=Green, 3=Yellow, 4=Blu, 5=Magenta, 6=Cyan, 7=White Attributes available are: 0=Normal, 1=Bold, 4=Underline, 5=Blink, 7=Reverse 8=Hidden N.B.: '@' and ':' commands need ANSI.SYS to be executed correctly. N.B.: @A0 command set colors to white foreground on black background. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ user define a user function [from Release 1.6] user e define a user function: use '&' for dummy argument For example the command user fsin(&)/fcos(&) define the tangent function. A call can be type fusr(pi/4)! that gives 1 as result. N.B.: If the user function is not defined, a call to fusr(arg) gives arg as function value. N.B.: User function can be redefined into the program; after execution the last definition of user function can be used for calculation in immediate mode. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vardump write symbol table [from original, modified in Rel. 1.1] vardump write symbol table 20 elements at a time: press any key to continue N.B.: Symbol table has 254 locations. N.B.: $ is equivalent to vardump ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ write write program list. [from original] write write whole program. write LGRP write specified group. write LNUM write specified line. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ xdos shell to operating system. [from Release 1.1] xdos exit to DOS; type 'exit' to reenter. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ yncrement increment/decrement a group of vars by 1 [from Release 1.4] yncrement +|-v([, +|- v]) increment/decrement v by 1. For example 'yncrement +x,-y' equals to 'set x=x+1;set y=y-1' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ zero set a group of vars equals to 0 [from Release 1.5] zero v([,v]) set v to 0. For example 'zero x,y' equals to 'set x=0; set y=0' N.B. zero $ clears all variables (equal to erase). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ? trace on/off [from Release 1.2] ? set trace on/off. In trace mode every line number processed are printed enclosed in square brackets. N.B.: Trace is different from PDP versions. In PDP '?' is a character to be inserted in programs for printing intructions between two '?'s; in Focal DOS '?' is a command that prints line numbers during execution (like GWBASIC instruction 'TRON'). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ vardump (see) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' body mark [from Release 2.0] ' mark the beginning of the body of one-line nested FOR loops. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5. FUNCTIONS AND RESERVED VARIABLES There are the following internal functions: [from original] fsin sine fcos cosine fexp exponential flog logarithm fatn arc tangent fsqt square root fabs absolute value fsgn signum function fitr integer part fran random fusr user function [from Release 1.7] fout print char to screen or file [from Release 2.1] fin read char from keyboard or file [from Release 2.1] pi reserved variable greek pi (3.1415926...): it can't be set or erased. [from Release 1.5] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6. ERRORS LIST Here is the errors list of Focal interpreter (Rel 2.2), in alphabetical order: "^C" "Bad directory" "Bad for" "Bad library command" "Bad line number" "Bad line or group number" "Bad subscript" "Cannot create" "Cannot delete" "Cannot open" "Cannot set reserved var" "Channel in use" "Direct line in call" "Division by zero" "EOF in ask" "Erasing current line" "Expression syntax" "Flog <= 0.0" "For stack botch" "Fsqt < 0.0" "Illegal command" "Illegal line number" "Library list not implemented" "Line not found" "Mismatched enclosures" "Missing ) in subscript" "Missing . in format" "Missing `(' for function" "Missing `)' for function" "Missing `\"' in ask" "Missing `\"' in type" "Missing = sign" "Missing comma" "Missing file name" "Missing help file" "Missing semicolon" "Missing variable" "No graphic available" "No program" "Not input file" "Not output file" "Number too long" "Only in program mode" "Out of memory" "Out of space (control stack)" "Out of space (symbols)" "Overflow" "Return not in do" "Undefined variable" "Wrong file channel" "Wrong format" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7. SYNTAX OF EXPRESSION IN FOCAL. EXPR ::= PRIMARY SIGN PRIMARY EXPR ADDOP PRIMARY ADDOP ::= '+' | '-' PRIMARY ::= TERM PRIMARY DIVOP SECONDARY SECONDARY:= TERM SECONDARY MULOP TERTIARY TERTIARY::= TERM TERTIARY POWOP TERM MULOP ::= '*' DIVOP ::= '/' POWOP ::= '^' TERM ::= '(' EXPR ')' '[' EXPR ']' '<' EXPR '>' NUMBER VARIABLE VARIABLE '(' EXPR ')' BUILTIN '(' EXPR ')' NUMBER ::= MANTISSA MANTISSA e SIGNED MANTISSA ::= INTEGER INTEGER . . INTEGER INTEGER . INTEGER SIGNED ::= INTEGER SIGN INTEGER SIGN ::= '+' | '-' INTEGER ::= DIGIT INTEGER DIGIT DIGIT ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' VARIABLE ::= ALPHA VARIABLE ALPHA VARIABLE DIGIT ALPHA ::= 'A' .. 'Z' | 'a' .. 'z' BUILTIN ::= 'fsin' | 'fcos' | 'fexp' | 'flog' | 'fatn' | 'fsqt'| 'fabs' | 'fsgn' | 'fitr' | 'fran' | 'fusr' | 'fin' | 'fout' 8. IMPORTANT ISSUES At the moment the following issues are known: 1) The use of 'fusr' function can corrupt the program in memory (probably due to a non-horthodox use of 'eval' routine): so to avoid this problem before every execution, a file image called 'focaltmp.foc' is created and, *only* if a fusr is involved, is reloaded at the end of execution. All variables values are retained. 2) Graphic commands **DON'T** use graph.h, but a combination of ANSI commands and direct writing in video RAM. ============================================================================= (---* end of document *--)