}
print($1)
}
double(1024)
func fac() {
if ($1 <= 0) return 1 else return $1 * fac($1-1)
}
func fac() if ($1 <= 0) return 1 else return $1 * fac($1-1)
fac(0)
fac(7)
fac(10)
func fac() {
if ($1 <= 0) {
return 1
}
return $1 * fac($1-1)
}
i=0
while(i<=20){
print "factorial of ", i, "is ", fac(i), "n"
i=i+1
}
proc fib() {
a = 0
b = 1
while (b < $1) {
print b
c = b
b = a+b
a = c
}
print "n"
}
{
n=0
a=0
b=1
while(b<10000000){
n=n+1
c=b
b=a+b
a=c
print(b)
}
print(n)
}
proc fib(){
a=1
b=1
c=2
d=3
sum = a+b+c+d
while(d<$1){
e=d+c
print(e)
a=b
b=c
c=d
d=e
sum=sum+e
}
print(sum)
}
fib(1000)
proc fib() {
a = 0
b = 1
while (b < $1) {
c = b
b = a+b
a = c
}
}
i = 1
while (i < 1000) {
fib(1000)
i = i + 1
}
typedef struct Symbol { /* symbol table entry */
char *name;
short type;
union {
double val; /* VAR */
double (*ptr)(); /* BLTIN */
int (*defn)(); /* FUNCTION, PROCEDURE */
char *str; /* STRING */
} u;
struct Symbol *next; /* to link to another */
} Symbol;
Symbol *install(), *lookup();
typedef union Datum { /* interpreter stack type */
double val;
Symbol *sym;
} Datum;
extern Datum pop();
extern eval(), add(), sub(), mul(), div(), negate(), power();
typedef int (*Inst)();
#define STOP (Inst)0
extern Inst *progp, *progbase, prog[], *code();
extern assign(), bltin(), varpush(), constpush(), print(), varread();
extern prexpr(), prstr();
extern gt(), lt(), eq(), ge(), le(), ne(), and(), or(), not();
extern ifcode(), whilecode(), call(), arg(), argassign();
extern funcret(), procret();
.EQ
delim @@
.EN
.TL
Hoc - An Interactive Language For Floating Point Arithmetic
.AU
Brian Kernighan
Rob Pike
.AB
.I Hoc
is a simple programmable interpreter
for floating point expressions.
It has C-style control flow,
function definition and the usual
numerical built-in functions such as cosine and logarithm.
.AE
.NH
Expressions
.PP
.I Hoc
is an expression language,
much like C:
although there are several control-flow statements,
most statements such as assignments
are expressions whose value is disregarded.
For example, the assignment operator
= assigns the value of its right operand
to its left operand, and yields the value,
so multiple assignments work.
The expression grammar is:
.DS
.I
expr: number
| variable
| ( expr )
| expr binop expr
| unop expr
| function ( arguments )
.R
.DE
Numbers are floating point.
The input format is
that recognized by @ [email protected](3):
.ix [scanf]
digits, decimal point, digits,
.ix [hoc] manual
.ix assignment expression
.ix multiple assignment
@ [email protected] or @ [email protected], signed exponent.
At least one digit or a decimal point
must be present;
the other components are optional.
.PP
Variable names are formed from a letter
followed by a string of letters and numbers,
@ [email protected] refers to binary operators such
as addition or logical comparison;
@ [email protected] refers to the two negation operators,
'!' (logical negation, 'not')
and '-' (arithmetic negation, sign change).
Table 1 lists the operators.
.TS
center, box;
с s
lfCW l.
fBTable 1:fP Operators, in decreasing order of precedence
.sp .5
^ exponentiation (s-1FORTRANs0 **), right associative
! - (unary) logical and arithmetic negation
* / multiplication, division
+ - addition, subtraction
> >= relational operators: greater, greater or equal,
< <= less, less or equal,
&== != equal, not equal (all same precedence)
&& logical AND (both operands always evaluated)
|| logical OR (both operands always evaluated)
&= assignment, right associative
.ТЕ
.ix table~of [hoc] operators
.PP
Functions, as described later, may be defined by the user.
Function arguments are expressions separated by commas.
There are also a number of built-in functions,
all of which take a single argument,
described in Table 2.
.TS
center, box;
с s
lfCW l.
fBTable 2:fP Built-in Functions
.sp .5
abs(x) @| x |@, absolute value of @ [email protected]
atan(x) arc tangent of @ [email protected]
cos(x) @cos (x)@, cosine of @ [email protected]
exp(x) @e sup [email protected], exponential of @ [email protected]
int(x) integer part of @ [email protected], truncated towards zero
log(x) @log (x)@, logarithm base @ [email protected] of @ [email protected]
log10(x) @log sub 10 (x)@, logarithm base 10 of @ [email protected]
sin(x) @sin (x)@, sine of @ [email protected]
sqrt(x) @sqrt [email protected], @x sup [email protected]
.ТЕ
.ix table~of [hoc] functions
.PP
Logical expressions have value 1.0 (true) and 0.0 (false).
As in C,
any non-zero value is taken to be true.
As is always the case with floating point numbers,
equality comparisons are inherently suspect. .PP
.I Hoc
also has a few built-in constants, shown in Table 3.
.TS
center, box;
c s s
lfCW n l.
fBTable 3:fP Built-in Constants
.sp .5
DEG 57.29577951308232087680 @180/ [email protected], degrees per radian
E 2.71828182845904523536 @ [email protected], base of natural logarithms
GAMMA 0.57721566490153286060 @ [email protected], Euler-Mascheroni constant
PHI 1.61803398874989484820 @( sqrt 5 +1)/ [email protected], the golden ratio
PI 3.14159265358979323846 @ [email protected], circular transcendental number
.ТЕ
.ix table~of [hoc] constants
.NH
Statements and Control Flow
.PP
.I Hoc
statements have the following grammar:
.DS
.I
stmt: expr
| variable = expr
| procedure ( arglist )
| while ( expr ) stmt
| if ( expr ) stmt
| if ( expr ) stmt else stmt
| { stmtlist }
| print expr-list
| return optional-expr
stmtlist: fR(nothing)fI
| stmlist stmt
.R
.DE
An assignment is parsed by default as a statement rather than
an expression, so assignments typed interactively
do not print their value.
.PP
Note that semicolons are not special to
.ix [hoc] input~format
@ [email protected]: statements are terminated by newlines.
This causes some peculiar behavior.
The following are legal
.IT if
statements:
.DS
.ft CW
if (x < 0) print(y) else print(z)
if (x < 0) {
print(y)
} else {
print(z)
}
.ft
.DE
In the second example, the braces are mandatory:
the newline after the
.I if
would terminate the statement and produce a syntax error were
the brace omitted.
.PP
The syntax and semantics of @ [email protected]
control flow facilities are basically the same as in C.
The
.I while
and
.I if
statements are just as in C, except there are no @ [email protected] or
@ [email protected] statements.
.NH
Input and Output: @ [email protected] and @ [email protected]
.PP
.ix [hoc] [read]~statement
.ix [hoc] [print]~statement
The input function @ [email protected], like the other built-ins,
takes a single argument. Unlike the built-ins, though, the argument
is not ал expression: it is the name of a variable.
The next number (as defined above) is read from the standard input
and assigned to the named variable.
The return value of @ [email protected] is 1 (true) if a value was read, and 0 (false)
if @ [email protected] encountered end of file or an error.
.PP
Output is generated with the ©print© statement.
The arguments to @ [email protected] are a comma-separated list of expressions
and strings in double quotes, as in C.
Newlines must be supplied;
they are never provided automatically by @ [email protected]
.PP
Note that @ [email protected] is a special built-in function, and therefore takes
a single parenthesized argument, while @ [email protected] is a statement that takes
a comma-separated, unparenthesized list:
.DS
.ft CW
while (read(x)) {