(* globals *)
const
rounderror=1/1000000;
debug=false;
type
tokenstrtype=string[30];
vartype=(realnum,proc);
tokentype=string[10];
tokenptr=^tokenlist;
tokenlist=record
token:tokentype;
ref:integer;
next:tokenptr;
end;
vartablenode=record
lexref:integer;
case kind:vartype of
realnum : (value:real);
proc : (address:tokenptr);
end;
pstacknode=^stacknode;
stacknode=record
value:real;
next:pstacknode;
end;
vartable=array[1..50] of vartablenode;
ptable=^vartable;
const
dumpfilename='dump.txt';
literaltablesize=35;
literaltable:array [1..literaltablesize] of tokenstrtype=(
'program','print','end',':=','+',
'-','*','/','^','read',
'(',')','if','then','else',
'and','or','not','=','>',
'<','>=','<=','<>','for',
'to','step','do','procedure','call',
',','global','local',':','real');
var
globaltable,localtable:ptable;
consttable,lexvartable:array[1..100] of tokenstrtype;
progfile,dumpfile:text;
list,curptr:tokenptr;
ch:char;
lextablesize,consttablesize,globalsize,localsize,lines,reclevel:integer;
callstack:pstacknode;
p:pointer;
(* snip *)
procedure gettokens;
label start,literal,halfassign,greater,less,
varname,wholenum,point,fracnum,endline,exit;
var tokenstr:tokenstrtype;
ref:integer;
dummy:boolean;
begin
tokenstr:='';
getnextchar;
start:
case ch of
'a'..'z' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto varname;
end;
'0'..'9' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto wholenum;
end;
'+','-','*','/','^',
'(',')','=',',' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto literal;
end;
':' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto halfassign;
end;
'>' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto greater;
end;
'<' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto less;
end;
#13,#26 : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto endline;
end;
' ',#9,#10 : begin
getnextchar;
goto start;
end;
else begin
errormessage('Syntax error');
end;
end; (*case*)
halfassign:
case ch of
'=' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto literal;
end;
else begin
dummy:=inlittable(tokenstr,ref);
inserttoken('literal',ref);
tokenstr:='';
goto start;
end;
end; (*case*)
greater:
case ch of
'=','>' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto literal;
end;
else begin
dummy:=inlittable(tokenstr,ref);
inserttoken('literal',ref);
tokenstr:='';
goto start;
end;
end; (*case*)
less:
case ch of
'=' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto literal;
end;
else begin
dummy:=inlittable(tokenstr,ref);
inserttoken('literal',ref);
tokenstr:='';
goto start;
end;
end; (*case*)
varname:
case ch of
'a'..'z','0'..'9','_' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto varname;
end;
else begin
if inlittable(tokenstr,ref) then
begin
inserttoken('literal',ref)
end
else
begin
if not inlexvartable(tokenstr,ref) then
begin
insertlexvartable(tokenstr);
end;
inserttoken('varname',ref);
end;
tokenstr:='';
goto start;
end;
end; (*case*)
wholenum:
case ch of
'0'..'9' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto wholenum;
end;
'.' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto point;
end;
else begin
if not inconsttable(tokenstr,ref) then
begin
insertconsttable(tokenstr);
end;
inserttoken('constant',ref);
tokenstr:='';
goto start;
end;
end; (*case*)
point:
case ch of
'0'..'9' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto fracnum;
end;
else begin
errormessage('Syntax error');
end;
end; (*case*)
fracnum:
case ch of
'0'..'9' : begin
tokenstr:=tokenstr+ch;
getnextchar;
goto fracnum;
end;
else begin
if not inconsttable(tokenstr,ref) then
begin
insertconsttable(tokenstr);
end;
inserttoken('constant',ref);
tokenstr:='';
goto start;
end;
end; (*case*)
literal:
dummy:=inlittable(tokenstr,ref);
inserttoken('literal',ref);
tokenstr:='';
goto start;
endline:
inserttoken('endline',lines);
lines:=lines+1;
tokenstr:='';
if ch=#26 then goto exit
else goto start;
exit:
end;