Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SDCL, part 02/03

6 views
Skip to first unread message

mun...@dmc.com

unread,
Jun 7, 1995, 3:00:00 AM6/7/95
to
Submitted-by: mun...@dmc.com
Posting-number: Volume 7, Issue 56
Archive-name: sdcl/part02

-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X
X
Xbuild`20:`09`09`09`09`09executables
X`09write`20sys$output`20"Build`20complete"
X
Xexecutables`20:`09`09`09`09exe$:sdcl.$(exe),-
X`09`09`09`09`09exe$:sdcl-debug.$(exe)
X`09write`20sys$output`20"Executables`20complete"
X
Xexe$:sdcl.$(exe)`20:`09`09`09obj$:sdcl.$(obj),-
X`09`09`09`09`09obj$:lex.$(obj),-
X`09`09`09`09`09obj$:output.$(obj),-
X`09`09`09`09`09obj$:stack.$(obj),-
X`09`09`09`09`09obj$:stmt.$(obj),-
X`09`09`09`09`09src$:sdcl.$(opt)
X`09link/exec=$(mms$target)/notrace`20-
X`09`09$(mms$source),-
X`09`09obj$:lex.$(obj),-
X`09`09obj$:output.$(obj),-
X`09`09obj$:stack.$(obj),-
X`09`09obj$:stmt.$(obj),-
X`09`09src$:sdcl.$(opt)/options
X
Xexe$:sdcl-debug.$(exe)`20:`09`09`09obj$:sdcl.$(obj),-
X`09`09`09`09`09obj$:lex.$(obj),-
X`09`09`09`09`09obj$:output.$(obj),-
X`09`09`09`09`09obj$:stack.$(obj),-
X`09`09`09`09`09obj$:stmt.$(obj),-
X`09`09`09`09`09src$:sdcl.$(opt)
X`09link/exec=$(mms$target)/debug`20-
X`09`09$(mms$source),-
X`09`09obj$:lex.$(obj),-
X`09`09obj$:output.$(obj),-
X`09`09obj$:stack.$(obj),-
X`09`09obj$:stmt.$(obj),-
X`09`09src$:sdcl.$(opt)/options
X
X
Xobj$:lex.$(obj)`20:`09`09`09`09src$:lex.c,-
X`09`09`09`09`09inc$:tcodes.h,-
X`09`09`09`09`09inc$:defs.h
X`09$(CC)`20$(CFLAGS)`20$(MMS$SOURCE)
X
Xobj$:output.$(obj)`20:`09`09`09src$:output.c,-
X`09`09`09`09`09inc$:defs.h
X`09$(CC)`20$(CFLAGS)`20$(MMS$SOURCE)
X
Xobj$:sdcl.$(obj)`20:`09`09`09`09src$:sdcl.c,-
X`09`09`09`09`09inc$:defs.h
X`09$(CC)`20$(CFLAGS)`20$(MMS$SOURCE)
X
Xobj$:stack.$(obj)`20:`09`09`09src$:stack.c,-
X`09`09`09`09`09inc$:defs.h
X`09$(CC)`20$(CFLAGS)`20$(MMS$SOURCE)
X
Xobj$:stmt.$(obj)`20:`09`09`09`09src$:stmt.c,-
X`09`09`09`09`09inc$:tcodes.h,-
X`09`09`09`09`09inc$:defs.h
X`09$(CC)`20$(CFLAGS)`20$(MMS$SOURCE)
$ call unpack [.REF-LIB]SDCL.MMS;4 103261330 "" 4 9 13
$!
$ create 'f'
X.flags`20bold
X.ps`2060,72
X.lm`200
X.sp`201
X.b`202
X.c`2072
XSDCL`20--`20A`20Preprocessor`20for`20Structured`20DCL`20
X.b`204
X.c`2072
XSohail`20Aslam
X.b`202
X.c`2072
XUniversity`20of`20Colorado`20at`20Colorado`20Springs
X.c`2072
XColorado`20Springs,`20CO`2080933
X.b`202
X.c`2072
XDick`20Munroe
X.b`202
X.c`2072
XAcorn`20Software
X.c`2072
X267`20Cox`20St.
X.c`2072
XHudson,`20Ma.`2001749
X.c`2072
Xmu...@acornsw.com
X.b`202
X
X.p`205,1,4
XThe`20command`20language`20under`20the`20VAX/VMS`20operating`20system`20is`20c
Valled
XDigital`20Command`20Language,`20or`20DCL.`20
XDCL`20provides`20a`20whole`20host`20of`20capabilities`20that`20allow`20the`20u
Vser`20not`20only
Xexecute`20simple`20commands`20but`20develop`20command`20procedures`20that`20ca
Vn`20accomplish
Xa`20complex`20task.`20DCL`20provides`20variables,`20conditional`20operators,
V`20
Xan`20IF-THEN-command`20construct`20and`20a`20number`20of`20built-in`20function
Vs.`20It`20is
Xthus`20a`20small`20programming`20language.`20Unfortunately,`20the`20only`20con
Vtrol`20structure
Xprovided`20is`20the`20
X.b`201
X#####IF_`20condition_`20THEN_`20a_`20command
X.b`201
XBy`20building`20a`20simple`20preprocessor,`20I`20have`20extended`20the`20contr
Vol`20structure`20to
Xinclude`20C`20like`20control`20structures,`20e.g,`20if-else,`20while,`20for,
V`20do-while,
Xon`20condition`20blocks,`20`20etc.
XThese`20structures`20can`20operate`20on`20a`20single`20command`20or`20a`20grou
Vp`20of`20commands.
X.p`205,1,4
XI`20taught`20a`20class`20here`20at`20UCCS`20in`20the`20spring`20semester`20of
V`201985`20titled`20"The
XUNIX`20Programming`20Environment";`20I`20chose`20developing`20the`20preprocess
Vor`20for`20
Xstructured`20DCL`20as`20the`20semester`20project.`20For`20the`20benefit`20of
V`20other`20teachers
Xwho`20may`20wish`20to`20assign`20such`20a`20project`20to`20their`20class,`20I
V`20have`20included`20the
XUNIX`20nroff/troff`20source`20and`20formatted`20version`20of`20the`20project
V`20handout.`20The`20
Xhandout`20provides`20a`20very`20detailed,`20step`20by`20step`20description`20o
Vf`20the`20design`20and
Ximplementation`20of`20sdcl.`20Thus`20it`20serves`20as`20a`20document`20for`20a
Vnyone`20who`20wants
Xto`20understand`20the`20workings`20of`20the`20preprocessor.`20The`20file`20"sd
Vcl.nr"`20contains
Xthe`20nroff/troff`20source`20and`20"sdcl.doc"`20is`20the`20formatted`20version
V`20of`20"sdcl.nr"
Xdesigned`20to`20be`20printed`20on`20ordinary`20line`20printers.
X.p`205,1,4
XThe`20real`20motivation`20for`20wanting`20to`20have`20structured`20DCL`20came
V`20from`20the`20tradition
Xset`20by`20RATFOR`20(RATional`20FORtran).`20For`20those`20of`20you`20not`20fam
Viliar`20with`20RATFOR,`20
XRATFOR`20allows`20one`20to`20write`20code`20in`20FORTRAN`20in`20a`20C`20like
V`20manner.`20DCL`20has`20similar
Xdeficiencies`20when`20it`20comes`20to`20writing`20command`20procedures.`20I`20
Vjust`20wanted`20to
Xillustrate`20that`20one`20does`20not`20have`20to`20live`20with`20GOTO's`20and
V`20COMEFROM's`20in`20one's
Xprogramming`20practices.`20It`20is`20rather`20trivial`20to`20develop`20a`20lay
Ver`20of`20structured
Xenvironment`20on`20top`20of`20something`20that`20does`20not`20support`20it.
X.pg
X.p`205,1,4
XThe`20language`20recognized,`20and`20thus`20parsed,`20by`20sdcl`20is`20very`20
Vsimple.`20Here`20it`20is
XBNF`20form:
X.lm`20+5
X.nj
X.nf
X.b`201
Xprogram`20`20`20:`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20program`20statement
X
Xstatement`20:`20`5E*if`20(`5C*`20condition`20`5E*)`5C*`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*if`20(`5C*`20condition`20`5E*)`5C*`20s
Vtatement`20`5E*else`5C*`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*while`20(`5C*`20condition`20`5E*)`5C*
V`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*for`20(`5C*`20intialize`20`5E*;`5C*`20
Vcondition`20`5E*;`5C*`20reinitialze`20`5E*)`5C*
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*do`5C*`20statement`20`5E*while`20(`20
V`5C*`20condition`20`5E*)`5C*
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*on`5C*`20statusCondition`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*on`5C*`20statusCondition`20`5E*then`5C
V*`20statement
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*break`5C*
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*next`5C*
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*`7B`5C*`20program`20`5E*`7D`5C*
X`20`20`20`20`20`20`20`20`20`20`7C`20`5E*other`5C*
X.lm`20-5
X.f
X.ju
X.b`201
XHere`20is`20a`20summary`20of`20sdcl`20usage.`20Please`20refer`20to`20
Xthe`20file`20"sdcl.doc."`20for`20a`20detailed`20description.
X.list`20"o"
X.le
XThe`20input`20file`20to`20sdcl`20is`20an`20ordinary`20text`20file`20containing
V`20sdcl`20statements.
XUnlike`20DCL,`20statements`20must`20not`20begin`20with`20a`20"_$"`20sign.`20
X.le
XStatements`20can`20be`20enclosed`20within`20_`7B_`7D`20to`20form`20the`20so-ca
Vlled`20compound
Xstatement.
X.le
XThe`20preprocessor`20looks`20at`20the`20first`20token`20of`20each`20statement
V`20to`20determine
Xthe`20type`20of`20statement`20so`20you`20should`20not`20preceed`20keywords`20w
Vith`20DCL`20labels
Xe.g.`20"usage:`20if(`20p1`20.eqs.`20..".`20Statements`20that`20donot`20match
V`20one`20of`20the
Xstructured`20statements`20are`20classified`20as`20"other"`20and`20simply`20emi
Vtted.
X.le
XAny`20`20sdcl`20source`20statement`20can`20be`20continued`20across`20more`20th
Vat`20one`20line`20by
Xplacing`20a`20"_`5C"`20(backslash)`20just`20before`20the`20end`20of`20line.
X.le
XIn`20structured`20constructs,`20the`20"_`5C"`20need`20not`20be`20used`20howeve
Vr,`20because`20sdcl
Xcan`20infer`20whether`20the`20constructs`20is`20complete`20or`20not`20by`20sim
Vply`20going
Xacross`20line`20boundaries`20until`20satisfied.`20So`20if`20the`20condition`20
Vpart`20is`20too
Xlong`20to`20fit`20on`20one`20line`20in`20an`20"if"`20statement,`20it`20can`20s
Vimply`20be`20continued`20on
Xthe`20next`20line.
X.le
XDonot`20use`20the`20"-"`20(minus)`20as`20the`20continuation`20character`20in
V`20sdcl`20statements.
X.le
XIf`20a`20source`20line`20begins`20with`20a`20"_#"`20or`20"_$"`20sign,`20the`20
Vpound`20sign`20(then`20dollar`20sign
Xis`20NOT`20removed)`20is`20removed`20and`20
Xrest`20of`20the`20line`20is`20emitted`20AS`20IS.`20This`20can`20be`20used`20to
V`20pass`20lines`20through
Xsdcl`20untouched`20to`20DCL.
X.le
XQuoted`20strings`20are`20not`20broken.
X.le
XVariable`20substitution`20is`20not`20broken.
X.end`20list
X.pg
X.b`202
XThe`20sdcl`20can`20be`20invoked`20as`20follows:
X.b`201
X.nj
X.nf
X####$`20sdcl`20`5Binfile.ext`5D`20`5Boutfile.ext`5D`20`5B-x`5D
X.b`201
Xwhere
X.b`201
X.lm`20+5
X"infile.ext"`20`20is`20the`20input`20source`20file.`20If`20not`20specified,`20
V`20input
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20is`20taken`20from`20"sys_$input".
X.b`201
X"outfile.ext"`20is`20the`20output`20file`20that`20will`20receive`20the`20gener
Vated
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20DCL`20code.`20If`20outfile`20is`20no
Vt`20specified,`20then`20the`20ge-
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20code`20will`20be`20placed`20in`20"in
Vfile.COM".`20If`20no`20`20infile
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20was`20specified,`20output`20goes`20t
Vo`20"sys_$output".
X.b`201
X-x`20`20`20`20`20`20`20`20`20`20`20`20If`20-x`20is`20specifed,`20then`20the`20
Vcode`20in`20outfile`20is`20pas-
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20to`20DCL`20for`20execution`20via`20l
Vib_$do__command.
X.lm`20-5
X.ju
X.f
X.b`201
XMake`20sure`20that`20the`20symbol`20"sdcl"`20is`20defined`20as`20a`20foreign
V`20command`20either
Xin`20your`20login.com`20or`20in`20the`20system`20wide`20login.com.`20For`20exa
Vmple,`20if`20the
Ximage`20"sdcl.exe"`20resides`20in`20"sys_$sysexe"`20then`20here`20is`20how`20y
Vou`20may
Xdefine`20"sdcl"`20as`20a`20foreign`20command`20in`20your`20login.com:
X.b`201
X#####$#sdcl#:==#_$sys_$sysexe:sdcl
X.b`201
XNote`20that`20parameters`20cannot`20be`20passed`20to`20the`20command`20procedu
Vre`20in
Xoutfile`20when`20it`20is`20executed`20through`20the`20"-x"`20option.
X.pg
XHere`20is`20a`20command`20procedure`20to`20give`20you`20a`20flavor`20of`20sdcl
V,`20
X.b`201
X.literal
X/*`20`20Bun`20--`20VMS`20DCL`20command`20procedure`20to`20bundle`20files`20int
Vo`20`20`20`20`20*/
X/*`20`20`20`20`20`20`20`20`20distribution`20package`20which`20can`20then`20be
V`20unbundled`20`20`20*/
X/*`20`20`20`20`20`20`20`20`20using`20UNIX`20shell.`20The`20output`20will`20be
V`20placed`20on`20the`20*/
X/*`20`20`20`20`20`20`20`20`20on`20the`20file`20given`20as`20the`20arg`20to`20t
Vhis`20procedure`20`20`20`20`20*/
Xif(`20p1`20.eqs.`20""`20)`7B
X`20`20`20`20write`20sys$output`5C
X`20`20`20`20`09"Usage:`20bundle`20outfile`20(outfile`20will`20receive`20bundle
V)"
X`20`20`20`20exit`20`20`20`20/*`20DCL`20exit`20*/
X`7D
X/*`20if`20the`20file`20exists,`20open`20it,`20otherwise`20create`20it`20*/
Xopen/write/err=out_err`20fout`20'p1'
Xexist`20:=`20"TRUE"
Xout_err:
Xif(`20exist`20.nes.`20"TRUE"`20)`7B
X`20`20`20`20create`20'p1'
X`20`20`20`20open/write/err=give_up`20fout`20'p1'
X`7D
Xq`20:=`20"'"
Xfor(`20rc`20=`200;`20;`20)`7B`20`20`20`20/*`20no`20condition,`20no`20reinit`20
V*/
X`20`20`20`20inquire`20infile`20"File?`20"
X`20`20`20`20if(`20infile`20.eqs.`20""`20)
X`09break`20`20`20`20`20`20`20`20/*`20time`20to`20wrapup`20*/
X`20`20`20`20open/read/err=infile_err`20inf`20'infile'
X`20`20`20`20write`20fout`20"echo`20''infile'`201>`262"
X`20`20`20`20write`20fout`20"cat`20>''infile'`20<<''q'END`20OF`20''infile'''q'"
V
X`20`20`20`20rc`20=`20rc`20+`202`20`20
X`20`20`20`20done`20=`200
X`20`20`20`20while(`20done`20.eq.`200`20)`7B
X`09read/end=eof`20inf`20line
X`09write`20`20`20`20`20`20`20fout`20line
X`09rc`20=`20rc`20+`201
X`20`20`20`20`7D
X`20`20`20`20eof:`20close`20inf
X`20`20`20`20write`20fout`20"END`20OF`20''infile'"
X`20`20`20`20rc`20=`20rc`20+`201
X`20`20`20`20next
X`20`20`20`20/*
X`20`20`20`20`20come`20here`20if`20trouble`20opening`20'infile'
X`20`20`20`20*/
X`20`20`20`20infile_err:`20write`20sys$output`20`5C
X`09`09`20`20`20"error`20opening`20''infile'"
X`7D
Xif(`20rc`20.gt.`200`20)`7B
X`20`20`20`20write`20sys$output`20"''rc'`20records`20written`20to`20''p1'"
X`20`20`20`20close`20fout
X`7D
Xelse
X`20`20`20`20write`20sys$output`20"0`20records`20written`20out"
Xexit
X.end`20literal
X.pg
XAnd`20here`20is`20the`20generated`20code.
X.literal
X$`20if`20(.not.(p1`20.eqs.`20""`20))`20then`20goto`2023000
X$`20write`20sys$output`20"Usage:`20bundle`20outfile`20(outfile`20will`20receiv
Ve`20bundle)"
X$`20exit`20`20`20`20
X$`2023000:`20
X$`20open/write/err=out_err`20fout`20'p1'
X$`20exist`20:=`20"TRUE"
X$`20out_err:
X$`20if`20(.not.(exist`20.nes.`20"TRUE"`20))`20then`20goto`2023002
X$`20create`20'p1'
X$`20open/write/err=give_up`20fout`20'p1'
X$`2023002:`20
X$`20q`20:=`20"'"
X$`20rc`20=`200
X$`2023004:`20
X$`20inquire`20infile`20"File?`20"
X$`20if`20(.not.(infile`20.eqs.`20""`20))`20then`20goto`2023007
X$`20goto`2023006
X$`2023007:`20
X$`20open/read/err=infile_err`20inf`20'infile'
X$`20write`20fout`20"echo`20''infile'`201>`262"
X$`20write`20fout`20"cat`20>''infile'`20<<''q'END`20OF`20''infile'''q'"
X$`20rc`20=`20rc`20+`202`20`20
X$`20done`20=`200
X$`2023009:`20if`20(.not.(done`20.eq.`200`20))`20then`20goto`2023010
X$`20read/end=eof`20inf`20line
X$`20write`20`20`20`20`20`20`20fout`20line
X$`20rc`20=`20rc`20+`201
X$`20goto`2023009
X$`2023010:`20
X$`20eof:`20close`20inf
X$`20write`20fout`20"END`20OF`20''infile'"
X$`20rc`20=`20rc`20+`201
X$`20goto`2023005
X$`20infile_err:`20write`20sys$output`20`20"error`20opening`20''infile'"
X$`2023005:`20
X$`20goto`2023004
X$`2023006:`20
X$`20if`20(.not.(rc`20.gt.`200`20))`20then`20goto`2023011
X$`20write`20sys$output`20"''rc'`20records`20written`20to`20''p1'"
X$`20close`20fout
X$`20goto`2023012
X$`2023011:`20
X$`20write`20sys$output`20"0`20records`20written`20out"
X$`2023012:`20
X$`20exit
X.end`20literal
$ call unpack [.REF-LIB]SDCL.RNO;2 1027619007 "" 17 10 13
$!
$ create 'f'
X/*
X`20*`09The`20functions`20within`20this`20file`20are`20used`20to`20maintain
X`20*`09a`20stack`20structure.`20`20Include`20here`20all`20typedefs,`20pointers
V
X`20*`09and`20stack`20maintenance`20functions.`20`20These`20functions`20include
V
X`20*`09push(),`20pop(),`20and`20peek().`20`20A`20hidden`20variable,`20top,`20i
Vs
X`20*`09declared`20within`20this`20file`20and`20is`20used`20to`20indicate`20the
V
X`20*`09top`20of`20this`20stack.`20`20
X`20*
X`20*/
X
X#include`20<stdio.h>
X#include`20"defs.h"
X
X/*
X`20*`09The`20following`20struct`20definition`20will`20be`20used`20to`20maintai
Vn
X`20*`09the`20stack`20of`20information`20that`20will`20be`20used`20by`20the`20b
Vreak
X`20*`09and`20next`20code`20generating`20functions.`20`20The`20information`20
X`20*`09contained`20in`20each`20node`20of`20the`20stack`20is`20the`20type`20of
V`20loop
X`20*`09being`20parsed`20and`20the`20number`20of`20the`20last`20label`20that`20
Vhas
X`20*`09been`20used`20in`20the`20code`20generation`20process.
X`20*
X`20*`09The`20variable`20declared`20after`20the`20typedef`20will`20always`20poi
Vnt
X`20*`09to`20the`20top`20of`20the`20stack.`20`20By`20declaring`20it`20as`20a`20
Vstatic
X`20*`09variable`20it`20becomes`20hidden`20by`20all`20procedures`20that`20resid
Ve
X`20*`09outside`20of`20this`20file.`20`20Initialize`20this`20pointer`20to`20NUL
VL`20(0).
X`20*`09This`20value`20indicates`20that`20the`20stack`20is`20empty.
X`20*
X`20*/
X
Xtypedef`20struct`20nodetype`20NODETYPE;
X
Xstruct`20nodetype
X`7B
X`09int`20looptype;`20`20/*`20While`20loop`20=`202,`20corresponding`20to`20WHIL
VE`20=`202.`20*/
X`09int`20label;`20`20`20`20`20/*`20Last`20label`20used`20before`20this`20loop.
V`20*/
X`09struct`20nodetype`20*next;`20/*`20Makes`20this`20a`20self-referential`20str
Vuct.`20*/
X`7D;
X
Xstatic`20NODETYPE`20*top`20=`20NULL;
X
X/*`20Define`20a`20macro`20that`20will`20return`20the`20size`20of`20a`20stack
V`20node.`20*/
X
X#define`20NODESIZE`20sizeof(NODETYPE)
X
X/*`20Define`20the`20push(),`20pop(),`20and`20peek()`20functions.`20*/
X
Xextern`20int`20errmsg();
X
Xvoid`20push(ltype,`20labl)
X`20`20`20`20int`20ltype;
X`20`20`20`20int`20labl;
X`20`20`20`20`7B
X`09NODETYPE`20*ptr;
X`09extern`20char`20*malloc();
X
X`09/*`20First`20create`20a`20new`20node.`20`20Coerce`20it`20to`20point`20to`20
Va`20nodetype.`20*/
X`09ptr`20=`20(NODETYPE`20*)`20malloc(NODESIZE);
X`09/*`20
X`09`20*`09Check`20to`20see`20if`20there`20was`20enough`20stack`20memory`20left
V
X`09`20*`09to`20allocate.`20`20If`20there`20wasn't,`20ptr`20will`20be`20NULL.
X`09`20*`09Time`20for`20an`20error`20message.
X`09`20*
X`09`20*/
X`09if`20(ptr`20==`20NULL)`7B
X`09`09errmsg("Fatal`20error`20--`20loops`20nested`20to`20deep`5Cn"`20);
X`09`09exit(1);
X`09`7D
X
X`09ptr->looptype`20=`20ltype;
X`09ptr->label`20=`20labl;
X`09ptr->next`20=`20top;
X`09top`20=`20ptr;
X`20`20`20`20`7D
X
Xint`20pop(pltype,`20plabl)
X`20`20`20`20int`20*pltype;
X`20`20`20`20int`20*plabl;
X`20`20`20`20`7B
X`09NODETYPE`20*ptr;
X`09extern`20char`20*free();
X
X`09if`20(top)`7B
X`09`20`20`20`20*pltype`20=`20top->looptype;
X`09`20`20`20`20*plabl`20=`20top->label;
X`09`20`20`20`20ptr`20=`20top;
X`09`20`20`20`20top`20=`20top->next;
X`09`20`20`20`20free((char`20*)`20ptr);
X`09`20`20`20`20return(`201`20);
X`09`7D
X`09else`20`7B
X`09`09errmsg("Internal`20Error`20--`20Attempt`20to`20pop`20an`20empty`20stack-
V-");
X`09`09errmsg("continuing`5Cn`5Cn");
X`09`09return(0);
X`09`7D
X`20`20`20`20`7D
X
Xpeek(pltype,`20plab)
X`20`20`20`20int`20*pltype;
X`20`20`20`20int`20*plab;
X/*
X`20*`09Return`20the`20contents`20of`20the`20top`20of`20the`20stack`20without
V`20actually
X`20*`09popping`20the`20stack.`20`20This`20function`20is`20the`20same`20as`20po
Vp(),`20but`20
X`20*`09only`20up`20to`20the`20point`20where`20top`20is`20changed.`20`20
X`20*/
X`20`20`20`20`7B
X`09if`20(top)`20`7B
X`09`20`20`20`20*pltype`20=`20top->looptype;
X`09`20`20`20`20*plab`20=`20top->label;
X`09`20`20`20`20return`20(`201`20);
X`09`7D
X`09else`20`7B
X`09`09return(0);
X`09`7D
X`20`20`20`20`7D
$ call unpack [.REF-LIB]STACK.C;3 1962954923 "" 6 11 13
$!
$ create 'f'
X/*
X`20*`09this`20file`20contains`20all`20the`20semantic`20analysis`20functions`20
Vto`20be
X`20*`09used`20in`20generating`20sdcl`20output.`20`20All`20of`20these`20functio
Vns`20are
X`20*`09ultimately`20called`20by`20statement(),`20depending`20on`20what`20the
V`20
X`20*`09current`20input`20token`20is.`20`20All`20of`20these`20functions`20then
V`20process
X`20*`09a`20line`20of`20input`20by`20calling`20the`20lexical`20analysis`20funct
Vion`20and,
X`20*`09depending`20on`20what`20token`20is`20returned,`20generating`20correct
V`20DCL
X`20*`09output`20lines.
X`20*
X**`20`200.001`20Dick`20Munroe`2007-Aug-90
X**`09There`20is`20a`20bug`20in`20condition`20that`20winds`20up`20incorrectly
V`20parsing
X**`09conditional`20statements`20of`20the`20form:
X**
X**`09if`20(`20(cond)`20.op.`20(cond)`20...`20)`20...
X**
X**`20`200.002`20Dick`20Munroe`2008-Aug-90
X**`09There`20is`20a`20bug`20in`20for`20statement`20processing`20that,`20incorr
Vectly,
X**`09stops`20when`20the`20first`20closing`20parenthesis`20in`20the`20input`20s
Vtream
X**`09occurs`20rather`20than`20the`20first`20UNBALANCED`20closing`20parenthesis
V.
X**
X**`20`200.003`20Dick`20Munroe`2003-Sep-90
X**`09Make`20$`20equivalent`20to`20#.
X**
X**`20`200.004`20Dick`20Munroe`2015-Sep-90
X**`09Get`20quoted`20string`20as`20first`20token`20on`20line`20output`20correct
Vly.
X**
X**`20`200.005`20Dick`20Munroe`2030-May-95
X**`09Preserve`20quoted`20strings`20in`20conditionals.
X**
X**`20`200.006`20Dick`20Munroe`2030-May-95
X**`09Preserve`20variable`20substitution
X**
X**`20`200.007`20Dick`20Munroe`2001-Jun-95
X**`09Add`20on`20blocks.
X**
X**`20`200.008`20Dick`20Munroe`2001-Jun-95
X**`09Add`20definition`20of`20$BREAK`20and`20$NEXT`20symbols`20to`20allow`20int
Vegration`20ofg
X**`09SDCL`20end`20of`20loop`20statements`20with`20things`20like`20read.
X*/
X
X#include`20<stdio.h>
X#include`20"tcodes.h"
X#include`20"defs.h"
X
Xint`20`20tokencode;
Xchar`20token`5BMAXTOKENLEN`5D;
X
X/*`20
X`20*`09The`20following`20serve`20as`20forward`20declarations`20of`20internal
V`20and`20
X`20*`09external`20to`20this`20file.
X`20*
X`20*/
X
Xextern`20void`20condition(),`20statement(int);
Xextern`20int`20lex();
Xextern`20void`20push()`20;
Xextern`20int`20pop(),`20genlab(),`20errmsg();
Xextern`20void`20emitlabel(),`20emitqstring(),`20emittarget();
X
Xvoid`20breakstmt(int);
Xvoid`20compstmt(int);
Xvoid`20condition();
Xvoid`20dowhilestmt(int);
Xvoid`20forstmt(int);
Xvoid`20ifstatement(int)`20;
Xvoid`20initialize(int);
Xvoid`20nextstmt(int);
Xvoid`20onstmt(int)`20;
Xvoid`20other(int);
Xvoid`20reinitialize();
Xvoid`20statement(int);
Xvoid`20whilestmt(int);
Xvoid`20popBreakNext()`20;
X
Xscan()
X/*
X`20*`09Repeatedly`20call`20lex`20until`20a`20token`20that`20is`20not`20a`20COM
VMENT,
X`20*`09WSPACE,`20NEWLINE`20can`20be`20returned.`20
X`20*/
X`20`20`20`20`7B
X`09do`20
X`09`7B
X`09`09tokencode`20=`20lex(token);
X`09`7D`20while`09`20(tokencode`20==`20COMMENT`20`7C`7C`20tokencode`20==`20WSPA
VCE`20`7C`7C
X`09`09`20`20tokencode`20==`20NEWLINE`20);
X`09return(tokencode);
X`20`20`20`20`7D
X
Xvoid`20statement(int`20beginning)
X/*
X`20*`09Based`20on`20current`20token,`20invoke`20the`20appropriate
X`20*`09routine`20to`20process`20a`20statement`20beginning`20with`20that`20toke
Vn.
X`20*/
X`20`20`20`20`7B
X`09switch`20(tokencode)`20`7B
X`09`09case`20IF:`20ifstatement(beginning);`20`20
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20bre
Vak;
X
X`09`09case`20WHILE:`20whilestmt(beginning);
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20break;
X
X`09`09case`20FOR:`20forstmt(beginning);
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
Vbreak;
X
X`09`09case`20DO:`20dowhilestmt(beginning);
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
Vbreak;
X
X`09`09case`20BREAK:`20breakstmt(beginning);`20`20
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20break;
X
X`09`09case`20NEXT:`20nextstmt(beginning);
X`09`09`09`20`20`20break;
X
X`09`09case`20ON:`20onstmt(beginning)`20;
X`09`09`09`20break;
X`09`09`09`20
X`09`09case`20OBRACE:`20compstmt(beginning);`20`20
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20break;
X
X`09`09default:`20other(beginning);
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20bre
Vak;
X`09`7D
X`7D
X
Xvoid`20ifstatement(beginning)
X/*
X`20*`09Process`20an`20if`20stmt.`20In`20the`20process`20generate`20any`20code
V`20associated
X`20*`09with`20the`20if/else`20control`20structure.`20`20When`20this`20function
V`20is`20called
X`20*`09the`20current`20value`20of`20tokencode`20should`20be`20IF.
X`20*
X`20*/
X`20`20`20`20`7B
X`09int`20looptype,`20lab1,`20lab2;
X
X`09scan();`20`20`20
X`09if(`20tokencode`20==`20OPAREN`20)
X`09`09/*`20skip`20over`20OPAREN`20so`20conditon()`20gets`20the`20next`20token.
V`20*/
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20'('`20in`20if`20condition`5Cn");
X
X`09lab1`20=`20genlab();
X`09lab2`20=`20genlab();`20`20/*`20reserve`20this`20in`20case`20there`20is`20an
V`20else`20*/
X`09if`20(beginning)`20emitstring("$`20");
X`09emitstring("if`20(.not.(");
X
X`09/*`20Parse`20the`20condition`20from`20the`20input`20stream.`20*/
X`09condition();
X`09
X`09if(`20tokencode`20==`20CPAREN)
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20')'`20in`20if`20condition`5Cn");
X`09/*`20
X`09`20*`09Build`20the`20remainder`20of`20the`20if-()-then-goto`20line`20and`20
V
X`09`20*`09output`20it.`20`20Function`20emittarget()`20is`20almost`20exactly`20
Vlike
X`09`20*`09emitlabel()`20except`20that`20no`20colon`20is`20appended`20to`20the
V
X`09`20*`09label.
X`09`20*/
X`09emitstring("))`20then`20goto`20");
X`09emittarget(lab1);
X`09emitstring("`5Cn");
X`09/*`20
X`09`20*`09Process`20the`20action`20part`20if`20the`20if-statement`20with`20a
X`09`20*`09recursive`20call`20to`20statement().
X`09`20*/
X`09statement(1);
X
X`09/*`20Check`20for`20an`20else`20part.`20*/
X`09if`20(tokencode`20==`20ELSE`20)`7B
X`09`09scan();`20`20`20`20`20`20`20
X`09`09emitstring("$`20goto`20");
X`09`09emittarget(lab2);
X`09`09emitstring("`5Cn");
X`09`09emitstring("$`20");
X`09`09emitlabel(lab1);
X`09`09emitstring("`5Cn");
X
X`09`09statement(1);
X`09`09/*`20
X`09`09`20*`09Finally,`20build`20the`20target`20for`20the`20transfer`20from
X`09`09`20*`09the`20if`20portion`20of`20the`20statement`20if`20the`20statement
V
X`09`09`20*`09is`20an`20if-then-else.
X`09`09`20*/
X`09`09emitstring("$`20");
X`09`09emitlabel(lab2);
X`09`09emitstring("`5Cn");
X`09`7D
X`09else`7B
X`09`09/*
X`09`09`20*`09Build`20the`20target`20for`20a`20transfer`20from`20the
X`09`09`20*`09if`20condition`20when`20there`20is`20no`20else`20clause.
X`09`09`20*/
X`09`09emitstring("$`20");
X`09`09emitlabel(lab1);
X`09`09emitstring("`5Cn");
X`09`7D
X`20`20`20`20`7D
X
Xvoid`20compstmt(int`20beginning)
X/*
X`20*`09Called`20in`20response`20to`20encountering`20a`20OBRACE`20token,`20
X`20*`09signalling`20a`20compound`20statement.`20`20What`20can
X`20*`09legally`20follow`20is`20one`20or`20several`20statements.`20`20These`20
V
X`20*`09statements`20can`20in`20turn`20be`20compound`20statements`20as`20well
V`20as`20any
X`20*`09other`20statement`20type.`20`20All`20this`20function`20need`20do`20is
V`20call`20
X`20*`09function`20statement`20recursively`20until`20a`20CBRACE`20is`20encounte
Vred
X`20*`09(or`20the`20end`20of`20file).
X`20*/
X`20`20`20`20`7B
X`09int`20flag`20=`201`20;
X
X`09scan();
X`09while`20(tokencode`20!=`20CBRACE`20`26`26`20tokencode`20!=`20FILEEND)
X`09`09if`20(flag)
X`09`09`7B
X`09`09`20`20`20`20flag`20=`200`20;
X`09`09`20`20`20`20statement(beginning)`20;
X`09`09`7D
X`09`09else
X`09`09`20`20`20`20statement(1);
X
X`09/*`20Get`20the`20next`20token`20following`20the`20CBRACE`20for`20statement(
V)`20to`20use.`20*/
X`09scan();
X`20`20`20`20`7D
X
Xvoid`20onstmt(int`20beginning)
X/*
X`20*`09Process`20an`20on`20stmt.`20In`20the`20process`20generate`20any`20code
V`20associated
X`20*`09with`20the`20on`20control`20structure.`20`20When`20this`20function`20is
V`20called
X`20*`09the`20current`20value`20of`20tokencode`20should`20be`20ON.
X`20*
X`20*/
X`20`20`20`20`7B
X`09char`20onCondition`5BMAXTOKENLEN`5D`20;
X`09int`20looptype,
X`09`20`20`20`20lab1,`20`20`20/*`20Name`20of`20the`20on`20block.`20*/
X`09`20`20`20`20lab2,`20`20`20/*`20Exit`20label`20of`20the`20on`20block.`20*/
X`09`20`20`20`20lab3;`20`20`20/*`20Branch`20around`20the`20on`20block.`20*/
X
X`09lab1`20=`20genlab();
X`09lab2`20=`20genlab();
X`09lab3`20=`20genlab();
X`09push(ON,`20lab1);
X
X`09scan();`20`20`20
X`09switch`20(tokencode)
X`09`7B
X`09`20`20`20`20case`20ON_WARNING:
X`09`20`20`20`20case`20ON_ERROR:
X`09`20`20`20`20case`20ON_SEVERE_ERROR:
X`09`20`20`20`20case`20ON_CONTROL_Y:
X`09`09strcpy`20(onCondition,`20token)`20;
X`09`09break`20;
X
X`09`20`20`20`20default:
X`09`09errmsg("Error--Invalid`20on`20condition`5Cn")`20;
X`09`09break`20;
X`09`7D
X
X`09scan()`20;
X`09switch`20(tokencode)
X`09`7B
X`09`20`20`20`20case`20THEN:
X`09`09if`20(beginning)`20emitstring("$`20")`20;
X`09`09emitstring("on`20")`20;
X`09`09emitstring(onCondition)`20;
X`09`09emitstring("`20then`20")`20;
X`09`09scan()`20;
X`09`09pop(`26looptype,`20`26lab1);
X`09`09statement(0)`20;
X`09`09return`20;
X`09`09
X`09`20`20`20`20case`20OBRACE:
X`09`09if`20(beginning)`20emitstring("$`20")`20;
X`09`09emitstring("on`20")`20;
X`09`09emitstring(onCondition)`20;
X`09`09emitstring("`20then`20gosub`20")`20;
X`09`09emittarget(lab1)`20;
X`09`09emitstring("`5Cn")`20;
X`09`09emitstring("$`20goto`20")`20;
X`09`09emittarget(lab3)`20;
X`09`09emitstring("`5Cn")`20;
X`09`09emitstring("$")`20;
X`09`09emitlabel(lab1)`20;
X`09`09emitstring("`5Cn")`20;
X`09`09compstmt(1)`20;
X`09`09break`20;
X
X`09`20`20`20`20default:
X`09`09errmsg("Error--Invalid`20argument`20for`20ON`20condition`5Cn")`20;
X`09`09break`20;
X`09`7D
X
X`09emitstring("$")`20;
X`09emitlabel(lab2)`20;
X`09emitstring("`5Cn")`20;
X
X`09emitstring("$`20on`20")`20;
X`09emitstring(onCondition)`20;
X`09emitstring("`20then`20gosub`20")`20;
X`09emittarget(lab1)`20;
X`09emitstring("`5Cn")`20;
X`09
X`09emitstring("$`20return`5Cn")`20;
X`09
X`09emitstring("$")`20;
X`09emitlabel(lab3)`20;
X`09emitstring("`5Cn")`20;
X
X`09/*
X`09`20*`09It`20is`20necessary`20to`20pop`20the`20stack`20although`20the`20valu
Ves`20
X`09`20*`09returned`20by`20the`20operation`20will`20not`20be`20used.
X`09`20*/
X`09pop(`26looptype,`20`26lab1);
X`09popBreakNext()`20;
X`20`20`20`20`7D
X
Xvoid`20other(int`20beginning)
X
X/*`09This`20function`20is`20called`20when`20an`20input`20line`20doesn't`20begi
Vn`20with
X**`09a`20keyword`20token`20or`20an`20OBRACE.`20`20Assume`20the`20line`20ends
V`20when`20a`20
X**`09newline`20or`20EOF`20is`20encountered.`20
X**
X**`09If`20the`20current`20token`20begins`20with`20a`20POUND`20it`20is`20a`20sp
Vecial
X**`09sdcl`20preprocessor`20directive`20to`20strip`20off`20the`20POUND`20and
X**`09pass`20whatever`20follows`20it`20to`20the`20output.`20`20
X**
X**`09If`20the`20current`20token`20begins`20with`20a`20DOLLAR`20it`20is`20a`20s
Vpecial
X**`09sdcl`20preprocessor`20directive`20to`20pass`20the`20whatever`20follows
X**`09it`20to`20the`20output.
X**
X**`09If`20there`20is`20no`20beginning`20POUND`20the`20output`20line`20has`20a
V`20
X**`09DOLLAR`20prepended`20to`20it`20then`20the`20first,`20and`20all`20subseque
Vnt`20tokens`20are
X**`09passed`20to`20the`20output`20stream.
X**
X**`09Certain`20tokens`20cause`20special`20actions`20to`20be`20taken.`20`20A`20
VBACKSLASH
X**`09tokencode`20is`20an`20sdcl`20line-continuation`20signal.`20`20What`20it
V`20means`20is
X**`09that`20the`20next`20input`20line`20is`20to`20be`20considered`20to`20be`20
Va`20continuation
X**`09of`20the`20current`20line.`20`20When`20a`20backslash`20is`20encountered
V`20parse
X**`09until`20the`20following`20newline`20character`20is`20encountered`20and
X**`09discard`20the`20newline.`20`20Continue`20the`20parse`20appending`20the
X**`09tokens`20from`20the`20next`20line`20until`20another`20newline,`20semicolo
Vn,
X**`09of`20EOF`20token`20is`20found.
X**
X**`09A`20STRING`20token`20causes`20a`20call`20to`20emitqstring()`20instead`20o
Vf
X**`09emitstring().`20`20Emitqstring()`20merely`20checks`20to`20see`20if`20the
V
X**`09STRING`20token`20will`20fit`20on`20the`20current`20output`20line.`20`20If
V`20it
X**`09won't`20a`20dash`20(DCL`20continuation`20character)`20and`20a`20newline
V`20are
X**`09appended`20to`20the`20current`20output`20line.`20`20This`20will`20then`20
Vflush
X**`09the`20current`20output`20line.`20`20Then`20the`20STRING`20token`20is`20ou
Vtput
X**`09without`20a`20prepended`20dollar`20sign.
X*/
X`20`20`20`20`7B
X`09/*`20If`20no`20directive`20to`20pass`20the`20input`20line`20directly...`20*
V/
X
X`09switch`20(tokencode)
X`09`7B
X`09`09default`09:`09if`20(beginning)`20emitstring("$`20")`20;
X`09`09`09`09emitstring(token)`20;
X`09`09`09`09break`20;
X
X`09`09case`20GRAVE`20:
X`09`09case`20STRING`20:`09if`20(beginning)`20emitstring("$`20")`20;
X`09`09`09`09emitqstring(token)`20;
X`09`09`09`09break`20;
X
X`09`09case`20POUND`20:`20`09tokencode`20=`20lex(token)`20;
X`09`09case`20DOLLAR`20:`09while`20((tokencode`20!=`20NEWLINE)`20`26`26
X`09`09`09`09`20`20`20`20`20`20`20(tokencode`20!=`20FILEEND))
X`09`09`09`09`7B
X`09`09`09`09`09emitlstring(token)`20;
X`09`09`09`09`09tokencode`20=`20lex(token)`20;
X`09`09`09`09`7D`20;
X`09`09`09`09emitstring("`5Cn")`20;
X`09`09`09`09scan()`20;
X`09`09`09`09return`20;
X`09`7D`20;
X
X`09tokencode`20=`20lex(token);
X
X`09while`20(tokencode`20!=`20NEWLINE`20`26`26`20tokencode`20!=`20FILEEND)`7B
X`09`09/*`20
X`09`09`20*`09If`20a`20backslash`20include`20the`20next`20line`20of`20input`20
V
X`09`09`20*`09with`20the`20current`20one.
X`09`09`20*/
X`09`09if`20(tokencode`20==`20BACKSLASH)`7B
X`09`09`09while`20(tokencode`20!=`20NEWLINE)
X`09`09`09`09tokencode`20=`20lex(token);
X`09`09`09scan();
X`09`09`09/*`20Add`20a`20space`20for`20readability.`20*/
X`09`09`09emitstring("`20");
X`09`09`7D
X`09`09/*
X`09`09`20*`09Insure`20that`20the`20current`20STRING`20token`20will`20not
X`09`09`20*`09be`20broken`20by`20a`20newline`20by`20outputting`20the`20
X`09`09`20*`09string`20via`20calling`20emitqstring()`20instead`20of
X`09`09`20*`09emitstring().
X`09`09`20*/
X`09`09else`20if`20((tokencode`20==`20STRING)`20`7C`7C`20(tokencode`20==`20GRAV
VE))`7B
X`09`09`09emitqstring(token);
X`09`09`09tokencode`20=`20lex(token);
X`09`09`7D
X`09`09else`20if`20(`20tokencode`20!=`20COMMENT`20)`20`7B
X`09`09`09emitstring(token);
X`09`09`09tokencode`20=`20lex(token);
X`09`09`7D
X`09`09else`20`20/*`20don't`20emit`20sdcl`20comment,`20just`20get`20next`20toke
Vn`20*/
X`09`09`09tokencode`20=`20lex(token);
X`09`7D
X`09emitstring("`5Cn");`20`20`20`20`20`20/*`20cause`20a`20output`20line`20flush
V`20*/
X`09scan();
X`20`20`20`20`7D
X
Xvoid`20whilestmt(int`20beginning)
X/*
X`20*`20`09This`20function`20processes`20a`20while`20statement`20in`20a`20manne
Vr`20
X`20*`20`09similar`20to`20how`20if`20statements`20are`20handled.`20`20This`20fu
Vnction`20
X`20*`09will`20be`20invoked`20in`20response`20to`20finding`20the`20keyword`20"w
Vhile"
X`20*`09in`20the`20input`20stream.
X`20*
X`20*`09While`20the`20semantic`20parse`20is`20being`20performed`20the`20interme
Vdiate
X`20*`09code`20for`20this`20statement`20is`20also`20being`20generated.
X`20*/`09
X`20`20`20`20`7B
X`09int`20looptype,`20lab1,`20lab2;
X
X`09/*`20Skip`20the`20keyword`20and`20get`20two`20labels.`20*/
X`09scan();
X`09lab1`20=`20genlab();
X`09lab2`20=`20genlab();
X`09/*`20
X`09`20*`09Begin`20building`20the`20output`20string.`20`20This`20will`20be
X`09`20*`09the`20destination`20label`20for`20any`20next`20statements.
X`09`20*/
X`09if`20(beginning)`20emitstring`20("$`20");
X`09emitlabel(lab1);
X`09emitstring("if`20(.not.(");
X
X`09if`20(tokencode`20==`20OPAREN)
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20'('`20in`20while`20condition`5Cn");
X`09/*
X`09`20*`09Call`20condition.`20`20When`20it`20returns`20the`20current`20token
X`09`20*`09should`20be`20a`20CPAREN.
X`09`20*/
X`09condition();
X`09if`20(tokencode`20==`20CPAREN)
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20')'`20in`20while`20condition`5Cn");
X
X`09`20emitstring("))`20then`20goto`20");
X`09`20emittarget(lab2);
X`09`20emitstring("`5Cn");
X
X`09emitstring("$`20$BREAK`20=`20`5C"")`20;
X`09emittarget(lab2)`20;
X`09emitstring("`5C"`5Cn")`20;
X
X`09emitstring("$`20$NEXT`20=`20`5C"")`20;
X`09emittarget(lab1)`20;
X`09emitstring("`5C"`5Cn")`20;
X
X`09/*
X`09`20*`09Do`20the`20necessary`20stack`20operations`20to`20preserve`20the
X`09`20*`09labels`20used`20with`20this`20while`20stmt.`20These`20will`20be`20us
Ved
X`09`20*`09to`20target`20any`20next`20or`20break`20stmts.
X`09`20*/
X`09push(WHILE,`20lab1);
X`09statement(1);
X
X`09/*
X`09`20*`09After`20the`20statement`20code`20has`20been`20generated`20the`20tran
Vsfer
X`09`20*`09statement`20to`20the`20beginning`20of`20the`20condition`20must`20be
V`20
X`09`20*`09generated($`20goto`20lab1).`20`20Then`20the`20destination`20for`20
X`09`20*`09condition`20failure`20must`20be`20inserted.`20`20This`20value`20will
V`20
X`09`20*`09be`20lab`20+`201`20(lab2).`20`20Lab2`20will`20*`09be`20the`20destina
Vtion`20
X`09`20*`09address`20for`20any`20break`20statements.
X`09`20*/
X`09emitstring("$`20goto`20");
X`09emittarget(lab1);
X`09emitstring("`5Cn");
X`09emitstring("$`20");
X`09emitlabel(lab2);
X`09emitstring("`5Cn");
X`09/*
X`09`20*`09It`20is`20necessary`20to`20pop`20the`20stack`20although`20the`20valu
Ves`20
X`09`20*`09returned`20by`20the`20operation`20will`20not`20be`20used.
X`09`20*/
X`09pop(`26looptype,`20`26lab1);
X`09popBreakNext()`20;
X`20`20`20`20`7D
X
Xvoid`20dowhilestmt(int`20beginning)
X/*
X`20*`09Parse`20and`20generate`20the`20contruct
X`20*`09`20`20do
X`20*`09`20`20`20`20`20`20statement
X`20*`09`20`20while`20(`20condition`20)
X`20*/
X`20`20`20`20`7B
X`20`20`20`20`20`20`20`20int`20lab1,`20lab2,`20lab3,`20looptype;
X
X`09scan();
X`09/*
X`09`20*`20reserve`20all`20the`20labels`20needed`20for`20do-while`20and`20recor
Vd`20loop
X`09`20*`20on`20stack.
X`09`20*/
X`09lab1`20=`20genlab();
X`09lab2`20=`20genlab();
X`09lab3`20=`20genlab();
X`09push(`20DO,`20lab1`20);
X
X`09/*
X`09`20*`20emit`20the`20label`20where`20the`20true`20exit`20from`20the`20condit
Vion
X`09`20*`20will`20come`20to.`20
X`09*/
X`09if`20(beginning)`20emitstring(`20"$`20"`20);
X`09emitlabel(`20lab1`20);
X`09emitstring(`20"`5Cn"`20);
X`09
X`09emitstring("$`20$BREAK`20=`20`5C"")`20;
X`09emittarget(lab3)`20;
X`09emitstring("`5C"`5Cn")`20;
X
X`09emitstring("$`20$NEXT`20=`20`5C"")`20;
X`09emittarget(lab2)`20;
X`09emitstring("`5C"`5Cn")`20;
X
X`09statement(1);
X`09if`20(`20tokencode`20==`20WHILE`20)
X`09`20`20`20`20scan();
X`09else
X`09`20`20`20`20errmsg("Error`20--`20missing`20keyword`20'while'`20in`20do-whil
Ve`5Cn"`20);
X`09if`20(`20tokencode`20==`20OPAREN`20)
X`09`20`20`20`20scan();
X`09else
X`09`20`20`20`20errmsg("Error`20--`20missing`20(`20in`20do-while`20condition`5C
Vn"`20);
X
X`09/*
X`09`20*`20emit`20code`20for`20condition`20test`20and`20branch`20
X`09`20*/
X`09emitstring(`20"$`20"`20);
X`09emitlabel(`20lab2`20);
X`09emitstring("if(`20"`20);
X
X`09condition();
X`09if`20(`20tokencode`20==`20CPAREN`20)
X`09`20`20`20`20scan();
X`09else
X`09`20`20`20`20errmsg("Error`20--`20missing`20)`20in`20do-while`20condition`5C
Vn"`20);
X
X`09/*
X`09`20*`20branch`20to`20start`20of`20loop,`20and`20label`20for`20any`20break
V`20statements.
X`09`20*/
X`09emitstring("`20)`20then`20goto`20");
X`09emittarget(`20lab1`20);
X`09emitstring(`20"`5Cn"`20);
X`09emitstring(`20"$`20");
X`09emitlabel(`20lab3`20);
X`09emitstring(`20"`5Cn"`20);
X`09/*
X`09`20*`20pop`20stack`20now`20that`20we`20are`20done.
X`09`20*/
X`09pop(`20`26looptype,`20`26lab1`20);
X`09popBreakNext()`20;
X`20`20`20`20`7D
X
Xvoid`20breakstmt(int`20beginning)
X/*
X`20*`09As`20its`20name`20implies`20this`20small`20function`20handles`20a`20bre
Vak
X`20*`09statement.`20`20It`20is`20called`20by`20function`20statement()`20whenev
Ver
X`20*`09the`20token`20BREAK`20is`20encountered.`20`20All`20this`20function`20ne
Ved
X`20*`09do`20is`20call`20scan`20until`20a`20NEWLINE,`20or`20FILEEND
X`20*`09is`20encountered.`20`20When`20it`20is`20found`20the`20appropriate`20got
Vo
X`20*`09string`20must`20be`20generated.`20`20Then`20one`20more`20call`20to`20sc
Van`20will`20be`20
X`20*`09performed`20to`20prepare`20for`20the`20next`20call`20to`20function`20st
Vatement().
X`20*/
X`20`20`20`20`7B`20
X`09int`20looptype,`20label;
X
X`09while`20(tokencode`20!=`20NEWLINE`20`26`26`20tokencode`20!=FILEEND`20)
X`09`09tokencode`20=`20lex(token);`09
X`09/*
X`09`20*`09Examine`20the`20top`20of`20the`20stack`20to`20see`20what`20action`20
Vshould
X`09`20*`09be`20taken.`20`20If`20currently`20within`20a`20for`20loop,`20generat
Ve
X`09`20*`09a`20"$`20goto`20(label`20+`202)."`20`20If`20in`20a`20while,`20genera
Vte`20a
X`09`20*`09"$`20goto`20(label`20+`201)."
X`09`20*/
X`09if(`20peek(`26looptype,`20`26label)`20)`7B
X`09`20`20`20`20if`20(beginning)`20emitstring("$`20");
X`09`20`20`20`20emitstring("goto`20");
X`09`20`20`20`20if`20(looptype`20==`20FOR`20`7C`7C`20looptype`20==`20DO)
X`09`09emittarget(label`20+`202);
X`09`20`20`20`20else
X`09`09emittarget(label`20+`201);
X`09`20`20`20`20emitstring("`5Cn");
X`09`7D
X`09else
X`09`20`20`20`20errmsg("Error`20--`20break`20statement`20is`20not`20within`20an
Vy`20loop`5Cn");
X
X`09scan();
X`20`20`20`20`7D
X
Xvoid`20nextstmt(int`20beginning)
X/*`20
X`20*`09Called`20by`20statement()`20whenever`20the`20NEXT`20keyword`20is`20foun
Vd.`20`20
X`20*`09This`20function`20repeatedly`20calls`20scan()`20until`20it`20finds`20a
V`20
X`20*`09NEWLINE,`20or`20the`20end`20of`20the`20input`20file`20is`20encountered.
V`20`20
X`20*`09After`20any`20of`20these`20tokens`20are`20found`20the`20appropriate`20g
Voto`20
X`20*`09string`20is`20generated`20to`20continue`20loop`20execution.`20`20
X`20*`09Then`20one`20final`20call`20to`20scan`20is`20performed`20to`20prepare
V`20for`20
X`20*`09any`20further`20calls`20to`20statement().
X`20*/
X`20`20`20`20`7B
X`09int`20looptype,`20label;
X
X`09while`20(tokencode`20!=`20NEWLINE`20`26`26`20tokencode`20!=`20FILEEND`20)
X`09`09tokencode`20=`20lex(token);
X`09/*
X`09`20*`09Examine`20the`20top`20of`20the`20stack`20to`20see`20what`20action`20
Vshould
X`09`20*`09be`20taken.`20`20If`20currently`20within`20a`20for`20loop,`20generat
Ve
X`09`20*`09a`20"$`20goto`20(label`20+`201)."`20`20If`20in`20a`20while,`20genera
Vte`20a
X`09`20*`09"$`20goto`20label."
X`09`20*/
X`09if(`20peek(`26looptype,`20`26label)`20)`20`7B
X`09`20`20`20`20if`20(beginning)`20emitstring("$`20");
X`09`20`20`20`20emitstring("goto`20");
X`09`20`20`20`20if`20(looptype`20==`20FOR`20`7C`7C`20looptype`20==`20DO)
X`09`09emittarget(label`20+`201);
X`09`20`20`20`20else`20if`20(looptype`20==`20WHILE)
X`09`09emittarget(label);
X`09`20`20`20`20else
X`09`09errmsg("Error`20--`20next`20statement`20is`20not`20within`20any`20loop
V`5Cn")`20;
X`09`20`20`20`20emitstring("`5Cn");
X`09`7D
X`09else
X`09`20`20`20`20errmsg("Error`20--`20next`20statement`20is`20not`20within`20any
V`20loop`5Cn");
X
X`09scan();
X`20`20`20`20`7D
X
Xvoid`20condition()
X/*
X`20*`09This`20function`20will`20be`20called`20whenever`20a`20DCL`20condition
V`20needs
X`20*`09to`20be`20evaluated.`20`20The`20current`20token`20should`20be`20an`20OP
VAREN,`20but
X`20*`09it`20may`20not`20be.`20`20DCL`20conditions`20may`20have`20nested`20sets
V`20of`20
X`20*`09parentheses`20and`20these`20must`20be`20handled`20by`20this`20function.
V
X`20*`09Initialize`20a`20variable,`20paren_count,`20to`20one.
X`20*`09Whenever`20another`20OPAREN`20is`20encountered`20increment`20paren_coun
Vt.
X`20*`09Decrement`20paren_count`20when`20a`20CPAREN`20is`20found.`20`20Repeat
V`20until
X`20*`09paren_count`20goes`20to`20zero`20and`20a`20CPAREN`20has`20been`20found.
V`20`20
X`20*`09Be`20sure`20to`20return`20with`20CPAREN`20as`20the`20current`20token.
X`20*
X`20*`09Since`20this`20condition`20can`20also`20appear`20in`20a`20for`20stateme
Vnt`20of
X`20*`09sdcl`20condition`20can`20also`20be`20terminated`20by`20a`20SEMICOLON.
X`20*
X`20*`09For`20the`20code`20generation`20portion`20part`20of`20this`20function
V`20merely
X`20*`09pass`20anything`20encountered`20to`20emistring(),`20except`20for`20the
V
X`20*`09closing,`20CPAREN.
X`20*
X`20*/
X`20`20`20`20`7B
X`09short`20paren_count`20=`201;
X
X`09/*`20
X`09**`20Output`20the`20current`20token`20and`20update`20the`20state`20of`20par
Ven_count
X`09**`20appropriately.`20`20This`20is`20necessary`20to`20catch`20parenthesized
V`20conditional
X`09**`20forms:
X`09**
X`09**`20`09if`20(`20(cond1)`20.op.`20(cond2)`20...)`20...
X`09*/
X
X`09switch`20(tokencode)
X`09`7B
X`09`09case`20NEWLINE`09:`20break`20;`20/*`20eatup`20newlines`20*/
X
X`09`09case`20CPAREN`09:`09/*`20A`20condition`20of`20the`20form:
X`09`09`09`09`09**`20().`20`20This`20should`20probably`20be`20a
X`09`09`09`09`09**`20syntax`20error.`20*/
X`09`09case`20SEMICOLON`20`20:`20return`20;`20`20/*`20in`20a`20for`20loop`20*/
V
X
X`09`09case`20GRAVE`20:
X`09`09case`20STRING`20:`09emitqstring(token)`20;
X`09`09`09`09break`20;`09/*`20Quoted`20strings`20in`20conditionals`20`20`20*/
X`09`09`09`09`09/*`20should`20be`20preserved.`09`09`20`20`20`20*/
X
X`09`09case`20OPAREN`09:`20paren_count++;
X`09`09default`09`09:`20emitstring(token);
X`09`09`09`09`20`20break;
X`09`7D
X
X`09/*
X`09`20*`09Output`20all`20tokens`20returned`20by`20lex()`20except`20for
X`09`20*`09the`20last`20CPAREN.`20`20Maintain`20level`20of`20parentheses
X`09`20*`09nesting`20via`20increments`20and`20decrements`20to`20paren_count.
X`09`20*`09The`20loop`20will`20terminate`20whenever`20either`20a`20SEMICOLON
X`09`20*`09is`20found`20or`20a`20CPAREN`20is`20found`20when`20paren_count`20is
V
X`09`20*`09zero.
X`09`20*/
X`09do`7B
X`09`09tokencode`20=`20lex(token);
X`09`09switch`20(tokencode)
X`09`09`7B
X`09`09`09case`20OPAREN`09:`20paren_count++;
X`09`09`09`09`09`20`20emitstring(token);
X`09`09`09`09`09`20`20break;
X
X`09`09`09case`20CPAREN`09:`20paren_count--;
X`09`09`09`09`09`20`20if`20(paren_count)
X`09`09`09`09`09`20`20`09emitstring(token);
X`09`09`09`09`09`20`20break;
X
X`09`09`09case`20NEWLINE`09:`20`20/*`20eatup`20newlines`20*/
X`09`09`09case`20SEMICOLON`20`20:`20break;`20`20/*`20in`20a`20for`20loop`20*/
X
X`09`09`09case`20GRAVE`20:
X`09`09`20`20`20`20`20`20`20`20case`20STRING`20:`09emitqstring(token)`20;
X`09`09`09`09`20`20`20`20`20`20`20`20break`20;`09
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`20/*`20Quoted`20strings`20in`20conditi
Vonals`20`20`20*/
X`09`09`09`09`09/*`20should`20be`20preserved.`09`09`20`20`20`20*/
X
X`09`09`09default`09`09:`20emitstring(token);
X`09`09`09`09`09`20`20break;
X`09`09`7D
X`09`7D`20while`20(paren_count`20`26`26`20tokencode`20!=`20SEMICOLON`20`26`26
X`09`09`20tokencode`20!=`20FILEEND`20);
X
X`09/*`20
X`09`20*`09At`20the`20end`20of`20this`20function`20the`20current`20token`20will
V`20be
X`09`20*`09either`20a`20CPAREN`20or`20a`20SEMICOLON.
X`09`20*/
X`7D
X
Xvoid`20forstmt(int`20beginning)
X/*
X`20*`09The`20code`20generation`20porion`20of`20this`20function`20is`20somewhat
V`20involved.
X`20*`09The`20reinitialization`20portion`20of`20the`20code`20is`20saved`20in`20
Va`20temporary
X`20*`09buffer`20called`20rstring`5B`5D.`20`20It`20is`20put`20into`20rsring`20b
Vy`20a`20call`20to
X`20*`09reinitialize().`20`20Then`20the`20statement`20portion`20of`20the`20inpu
Vt`20stream
X`20*`09is`20read`20and`20processed.`20`20Then`20the`20reinitialization`20code
V`20is
X`20*`09output`20after`20the`20proper`20transfer`20label`20is`20output.
X`20*/
X`20`20`20`20`7B
X`09int`20lab1,`20lab2,`20lab3,`20looptype;
X`09char`20rstring`5BMAXCONDLEN`5D;
X
X`09scan();
X`09if`20(tokencode`20==`20OPAREN)
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20'('`20in`20for`20statement`5Cn");
X`09/*`20`20Get`20the`20three`20labels`20necessary`20for`20a`20for-statement.
V`20*/
X`09lab1`20=`20genlab();
X`09lab2`20=`20genlab();
X`09lab3`20=`20genlab();
X
X`09/*`20`20
X`09`20*`09If`20the`20next`20token`20is`20not`20a`20SEMICOLON`20then`20an`20ini
Vtialization
X`09`20*`09statement`20exists`20for`20this`20for`20statement.`20`20Process`20it
V`20via
X`09`20*`09a`20call`20to`20initialize().
X`09`20*/
X`09if`20(tokencode`20!=`20SEMICOLON)
X`09`7B
X`09`09initialize(beginning);
X`09`09beginning`20=`201`20;
X`09`7D
X
X`09if`20(beginning)`20emitstring("$`20");
X`09emitlabel(lab1);
X`09emitstring("$BREAK`20=`20`5C"")`20;
X`09emittarget(lab3)`20;
X`09emitstring("`5C"`5Cn")`20;
X
X`09emitstring("$`20$NEXT`20=`20`5C"")`20;
X`09emittarget(lab2)`20;
X`09emitstring("`5C"")`20;
X
X`09scan();
X
X`09/*
X`09`20*`09If`20the`20next`20token`20isn't`20a`20SEMICOLON`20assume`20that`20a
V
X`09`20*`09condition`20statement`20exists.`20`20Begin`20building`20the
X`09`20*`09string`20to`20test`20this`20condition.`20`20Call`20condition()
X`09`20*`09to`20parse`20and`20output`20the`20relational`20expression,`20then
X`09`20*`09finish`20building`20the`20statement`20by`20adding`20the`20"goto"
X`09`20*`09clause`20with`20the`20appropriate`20transfer`20address`20for
X`09`20*`09when`20the`20condition`20fails.
X`09`20*/
X`09if`20(tokencode`20!=`20SEMICOLON)`7B
X`09`09emitstring("`5Cn")`20;
X`09`09emitstring("$`20if`20(.not.(");
X`09`09condition();
X`09`09emitstring("))`20then`20goto`20");
X`09`09emittarget(lab3);
X`09`7D
X`09emitstring("`5Cn");
X`09scan();
X`09/*
X`09`20*`09If`20the`20next`20token`20is`20not`20a`20CPAREN`20then`20we`20know
V`20that
X`09`20*`09we`20don't`20have`20a`20null`20reinitialization`20statement.`20`20
X`09`20*`09Call`20reinitialize()`20to`20parse`20and`20save`20this`20statement.
V
X`09`20*`09The`20statement`20will`20be`20saved`20in`20rstring`5B`5D`20for`20lat
Ver
X`09`20*`09use`20after`20the`20statement`20portion`20of`20the`20for-loop
X`09`20*`09has`20been`20processed.
X`09`20*/
X`09rstring`5B0`5D`20=`20'`5C0';
X`09if`20(tokencode`20!=`20CPAREN)`20
X`09`09reinitialize(rstring);
X
X`09if`20(tokencode`20==`20CPAREN)
X`09`09scan();
X`09else
X`09`09errmsg("Error--missing`20a`20')'`20in`20for`20statement`5Cn");
X`09/*
X`09`20*`09Push`20lab1`20onto`20the`20stack`20to`20enable`20processing`20of`20b
Vreak
X`09`20*`09and`20next`20statements.`20`20Process`20the`20action`20portion`20of
V`20
X`09`20*`09this`20while-loop.`20
X`09`20*/
X`09push(FOR,`20lab1);
X`09statement(1);
X`09/*
X`09`20*`09Build`20the`20label`20that`20preceedes`20the`20reinitialization`20st
Vuff,
X`09`20*`09and,`20if`20this`20stuff`20isn't`20NULL,`20output`20it`20after`20the
V`20label.
+-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+-
--
Dick Munroe Internet: mun...@acornsw.com
Acorn Software, Inc.
267 Cox St. Office: (508) 568-1618 x16
Hudson, Ma. 01749 USA FAX: (508) 562-1133
--
Dick Munroe Internet: mun...@acornsw.com
Acorn Software, Inc.
267 Cox St. Office: (508) 568-1618 x16
Hudson, Ma. 01749 USA FAX: (508) 562-1133

0 new messages