v04i024: Turbo Pascal to C, part 3/4
Alan Strassberg
alan at leadsv.UUCP
Mon Aug 15 08:56:01 AEST 1988
Posting-number: Volume 4, Issue 24
Submitted-by: "Alan Strassberg" <alan at leadsv.UUCP>
Archive-name: tptc/Part3
[WARNING!!! This software is shareware and copyrighted. Those who do not
accept such programs should give this a miss. ++bsa]
#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive. Save this into a file, edit it
# and delete all lines above this comment. Then give this
# file to sh by executing the command "sh file". The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r-- 1 allbery System 22616 Aug 14 16:46 tpcstmt.inc
# -rw-r--r-- 1 allbery System 7059 Aug 14 16:46 tpcsym.inc
# -rw-r--r-- 1 allbery System 12098 Aug 14 16:46 tpcunit.inc
# -rw-r--r-- 1 allbery System 11061 Aug 14 16:46 tptc.doc
#
echo 'x - tpcstmt.inc'
if test -f tpcstmt.inc; then echo 'shar: not overwriting tpcstmt.inc'; else
sed 's/^X//' << '________This_Is_The_END________' > tpcstmt.inc
X
X(*
X * TPTC - Turbo Pascal to C translator
X *
X * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
X *
X *)
X
X(********************************************************************)
X(*
X * control statement processors
X * for, while, repeat, with, idents
X *
X * all expect tok to be keyword
X * all exit at end of statement with ltok as ; or end
X *
X *)
X
Xprocedure pfor;
Xvar
X up: boolean;
X id: string80;
X low,high: string80;
X
Xbegin
X if debug_parse then write(' <for>');
X
X nospace := true;
X puts('for (');
X gettok; {consume the FOR}
X
X id := plvalue;
X gettok; {consume the :=}
X
X low := pexpr;
X
X if tok = 'TO' then
X up := true
X else
X
X if tok = 'DOWNTO' then
X up := false;
X
X gettok;
X high := pexpr;
X
X if up then
X puts(id+' = '+low+'; '+id+' <= '+high+'; '+id+'++) ')
X else
X puts(id+' = '+low+'; '+id+' >= '+high+'; '+id+'--) ');
X
X nospace := false;
X gettok; {consume the DO}
X pstatement;
Xend;
X
X
X(********************************************************************)
Xprocedure pwhile;
Xbegin
X if debug_parse then write(' <while>');
X gettok; {consume the WHILE}
X
X nospace := true;
X puts('while ('+pexpr+') ');
X nospace := false;
X
X gettok; {consume the DO}
X pstatement;
Xend;
X
X
X(********************************************************************)
Xprocedure pwith;
Xvar
X prefix: string;
X levels: integer;
X
Xbegin
X if debug_parse then write(' <with>');
X gettok; {consume the WITH}
X
X {warning('WITH not translated');}
X levels := 0;
X puts('{ ');
X nospace := true;
X
X repeat
X if tok[1] = ',' then
X begin
X gettok;
X newline;
X puts(' ');
X end;
X
X prefix := plvalue;
X make_pointer(prefix);
X
X inc(levels);
X inc(withlevel);
X puts('void *with'+itoa(withlevel)+' = '+prefix+'; ');
X
X until tok[1] <> ',';
X
X nospace := false;
X gettok; {consume the DO}
X
X if tok[1] <> '{' then
X pstatement
X else
X
X begin
X gettok; {consume the open brace}
X
X while (tok[1] <> '}') and not recovery do
X begin
X pstatement; {process the statement}
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok; {get first token of next statement}
X end;
X end;
X
X gettok; {consume the close brace}
X end;
X
X puts(' } ');
X newline;
X
X if tok[1] = ';' then
X gettok;
X
X dec(withlevel,levels);
Xend;
X
X
X(********************************************************************)
Xprocedure prepeat;
Xbegin
X if debug_parse then write(' <repeat>');
X puts('do { ');
X gettok;
X
X while (tok <> 'UNTIL') and not recovery do
X begin
X pstatement;
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end;
X end;
X
X gettok;
X nospace := true;
X puts('} while (!('+ pexpr+ '))');
X nospace := false;
Xend;
X
X
X(********************************************************************)
Xprocedure pcase;
Xvar
X ex: string80;
X ex2: string80;
X i: integer;
X c: char;
X
Xbegin
X if debug_parse then write(' <case>');
X gettok;
X ex := pexpr;
X puts('switch ('+ex+') {');
X
X gettok; {consume the OF}
X
X while (tok[1] <> '}') and (tok <> 'ELSE') and not recovery do
X begin
X
X repeat
X if tok[1] = ',' then
X gettok;
X
X if tok = '..' then
X begin
X gettok;
X ex2 := pexpr;
X
X if (ex2[1] = '''') or (ex2[1] = '"') then
X for c := succ(ex[2]) to ex2[2] do
X begin
X newline;
X puts('case '''+c+''': ');
X end
X else
X
X if atoi(ex2) - atoi(ex) > 128 then
X begin
X ltok := ex+'..'+ex2;
X warning('Gigantic case range');
X end
X else
X
X for i := succ(atoi(ex)) to atoi(ex2) do
X begin
X newline;
X write(ofd[unitlevel],'case ',i,': ');
X end;
X end
X else
X
X begin
X ex := pexpr;
X newline;
X puts('case '+ex+': ');
X end;
X
X until (tok[1] = ':') or recovery;
X gettok;
X
X if (tok[1] <> '}') and (tok <> 'ELSE') then
X pstatement;
X puts('break; ');
X newline;
X
X if tok[1] = ';' then
X gettok;
X end;
X
X if tok = 'ELSE' then
X begin
X newline;
X puts('default: ');
X gettok; {consume the else}
X
X while (tok[1] <> '}') and not recovery do
X begin
X if (tok[1] <> '}') and (tok <> 'ELSE') then
X pstatement;
X if tok[1] = ';' then
X gettok;
X end;
X end;
X
X puttok;
X gettok;
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pif;
Xvar
X pspace: integer;
Xbegin
X if debug_parse then write(' <if>');
X gettok; {consume the IF}
X
X pspace := length(spaces);
X nospace := true;
X puts('if ('+ pexpr+ ') ');
X nospace := false;
X
X gettok; {consume the THEN}
X
X if (tok[1] <> '}') and (tok <> 'ELSE') then
X pstatement;
X
X if tok = 'ELSE' then
X begin
X spaces := copy(spaces,1,pspace);
X if not linestart then
X newline;
X puts('else ');
X
X gettok;
X if tok[1] <> '}' then
X pstatement;
X end;
X
Xend;
X
X
X(********************************************************************)
Xprocedure pexit;
Xbegin
X if debug_parse then write(' <exit>');
X puts('return;');
X
X gettok;
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pgoto;
Xvar
X ex: anystring;
X
Xbegin
X gettok; {consume the goto}
X
X if toktype = number then
X ltok := 'label_' + ltok; {modify numeric labels}
X
X puts('goto '+ltok+';');
X
X gettok; {consume the label}
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure phalt;
Xvar
X ex: anystring;
X
Xbegin
X if debug_parse then write(' <halt>');
X gettok;
X
X if tok[1] = '(' then
X begin
X gettok;
X ex := pexpr;
X gettok;
X end
X else
X ex := '0'; {default exit expression}
X
X puts('exit('+ex+');');
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pread;
Xvar
X ctl: string;
X func: anystring;
X ex: paramlist;
X p: string;
X ln: boolean;
X ty: string[2];
X i: integer;
X
Xbegin
X if debug_parse then write(' <read>');
X
X nospace := true; {don't copy source whitespace to output during
X this processing. this prevents spaces from
X getting moved around}
X
X ln := tok = 'READLN';
X nospace := true;
X func := 'scanv(';
X
X gettok; {consume the read}
X
X if tok[1] = '(' then
X begin
X gettok;
X
X if ltok[1] = '[' then {check for MT+ [addr(name)], form}
X begin
X gettok; {consume the '[' }
X
X if tok[1] = ']' then
X func := 'scanf('
X else
X
X begin
X gettok; {consume the ADDR}
X gettok; {consume the '(' }
X func := 'fiscanf(' + usetok + ',';
X gettok; {consume the ')'}
X end;
X
X gettok; {consume the ']'}
X if tok[1] = ',' then
X gettok;
X end;
X
X ctl := '';
X ex.n := 0;
X
X while (tok[1] <> ')') and not recovery do
X begin
X p := pexpr;
X ty := exprtype;
X
X {convert to fprintf if first param is a file variable}
X if (ex.n = 0) and (ty = '@') then
X func := 'fscanv(' + p + ','
X else
X
X {process a new expression; add expressions to ex.id table
X and append proper control codes to the control string}
X begin
X if ty <> 's' then
X if p[1] = '*' then
X delete(p,1,1)
X else
X p := '&' + p;
X inc(ex.n);
X if ex.n > maxparam then
X fatal('Too many params (pread)');
X ex.id[ex.n] := p;
X ctl := ctl + '%'+ty;
X end;
X
X if tok[1] = ',' then
X gettok;
X end;
X
X gettok; {consume the )}
X
X if ctl = '%s' then
X ctl := '#';
X if ln then
X ctl := ctl + '\n';
X
X if func[1] <> 'f' then
X func := 'f' + func + 'stdin,';
X
X puts(func+'"'+ctl+'"');
X for i := 1 to ex.n do
X puts(','+ex.id[i]);
X
X puts(')');
X end
X
X else {otherwise there is no param list}
X if ln then
X puts('scanf("\n")');
X
X nospace := false;
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end
X else
X
X begin
X puts('; ');
X newline;
X end;
X
Xend;
X
X
X(********************************************************************)
Xtype
X write_modes = (m_write, m_writeln, m_str);
X
Xprocedure pwrite(mode: write_modes);
Xvar
X ctl: string;
X func: anystring;
X ex: paramlist;
X p: string;
X ty: string[2];
X i: integer;
X
X procedure addform(f: anystring);
X {add a form parameter, special handling for form expressions}
X begin
X if isnumber(f) then
X ctl := ctl + f {pass literal form}
X else
X begin {insert form expression in parlist}
X ctl := ctl + '*';
X inc(ex.n);
X if ex.n > maxparam then
X fatal('Too many params (pwrite.form)');
X ex.id[ex.n] := ex.id[ex.n-1];
X ex.id[ex.n-1] := f;
X end;
X end;
X
Xbegin
X if debug_parse then write(' <write>');
X
X nospace := true; {don't copy source whitespace to output during
X this processing. this prevents spaces from
X getting moved around}
X
X nospace := true;
X
X if mode = m_str then
X func := 'sbld('
X else
X func := 'printf(';
X
X gettok; {consume the write}
X
X if tok[1] = '(' then
X begin
X gettok; {consume the (}
X
X if ltok[1] = '[' then {check for MT+ [addr(name)], form}
X begin
X gettok; {consume the '[' }
X
X if tok[1] <> ']' then
X begin
X gettok; {consume the ADDR}
X gettok; {consume the '(' }
X func := 'iprintf(' + usetok + ',';
X gettok; {consume the ')'}
X end;
X
X gettok; {consume the ']'}
X if tok[1] = ',' then
X gettok;
X end;
X
X ctl := '';
X ex.n := 0;
X
X while (tok[1] <> ')') and not recovery do
X begin
X p := pexpr;
X ty := exprtype;
X
X {convert to fprintf if first param is a file variable}
X if (ex.n = 0) and (ty = '@') then
X func := 'fprintf(' + p + ','
X else
X
X {process a new expression; add expressions to ex.id table
X and append proper control codes to the control string}
X begin
X inc(ex.n);
X if ex.n > maxparam then
X fatal('Too many params (pwrite)');
X ex.id[ex.n] := p;
X
X if ty = 'D' then
X ty := 'ld';
X if ty = 'b' then
X ty := 'd';
X
X {decode optional form parameters}
X if tok[1] = ':' then
X begin
X ctl := ctl + '%';
X gettok;
X addform(pexpr);
X
X if tok[1] = ':' then
X begin
X ctl := ctl + '.';
X gettok;
X addform(pexpr);
X ty := 'f';
X end;
X
X ctl := ctl + ty;
X end
X else
X
X begin
X {pass literals into the control string}
X if (p[1] = '"') or (p[1] = '''') then
X begin
X ctl := ctl + copy(p,2,length(p)-2);
X dec(ex.n);
X end
X
X {otherwise put in the control string for this param}
X else
X ctl := ctl + '%'+ty;
X end;
X end;
X
X if tok[1] = ',' then
X gettok;
X end;
X
X gettok; {consume the )}
X
X {add newline in 'writeln' translation}
X if mode = m_writeln then
X ctl := ctl + '\n';
X
X {convert last parameter into destination in 'str' translation}
X if mode = m_str then
X begin
X func := func + ex.id[ex.n] + ',';
X dec(ex.n);
X delete(ctl,length(ctl)-1,2);
X end;
X
X {produce the translated statement}
X puts(func+'"'+ctl+'"');
X for i := 1 to ex.n do
X puts(','+ex.id[i]);
X
X puts(')');
X end
X
X else {otherwise there is no param list}
X if mode = m_writeln then
X puts('printf("\n")');
X
X nospace := false;
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end
X else
X
X begin
X puts('; ');
X newline;
X end;
X
Xend;
X
X
X(********************************************************************)
Xprocedure pnew;
Xvar
X lv: string;
Xbegin
X if debug_parse then write(' <new>');
X
X gettok; {consume the new}
X gettok; {consume the (}
X
X lv := plvalue;
X puts(lv+' = malloc(sizeof(*'+lv+'));');
X
X gettok; {consume the )}
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pport(kw: string);
X {translate port/portw/mem/memw}
Xvar
X lv: string;
X
Xbegin
X if debug_parse then write(' <port>');
X lv := kw + '(';
X
X gettok; {consume the keyword}
X gettok; {consume the [ }
X
X repeat
X lv := lv + pexpr;
X if tok[1] = ':' then
X begin
X gettok;
X lv := lv + ',';
X end;
X until (tok[1] = ']') or recovery;
X
X gettok; {consume the ] }
X
X if tok = ':=' then
X begin
X gettok; {consume :=, assignment statement}
X lv := lv + ',' + pexpr;
X end;
X
X puts(lv+');');
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pinline;
X {translate inline statements}
X
Xvar
X sixteen: boolean;
X
Xbegin
X if debug_parse then write(' <inline>');
X
X gettok; {consume the keyword}
X nospace := true;
X gettok;
X
X while (tok[1] <> ')') and not recovery do
X begin
X if tok[1] = '/' then
X gettok;
X
X if tok[1] = '>' then
X begin
X gettok;
X sixteen := true;
X end
X else
X sixteen := htoi(ltok) > $00ff;
X
X putline;
X if sixteen then
X puts(' asm DW '+ltok+'; ')
X else
X puts(' asm DB '+ltok+'; ');
X gettok;
X end;
X
X nospace := false;
X gettok; {consume the ) }
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pident;
X {parse statements starting with an identifier; these are either
X assignment statements, function calls, return-value assignments,
X or label identifiers}
Xvar
X ex: string;
X lv: string;
X lvt,ext: char;
X
Xbegin
X if debug_parse then write(' <ident>');
X
X nospace := true; {don't copy source whitespace to output during
X this processing. this prevents spaces from
X getting moved around}
X
X lv := plvalue; {destination variable or function name}
X lvt := exprtype; {destination data type}
X
X if tok = ':=' then
X begin
X if debug_parse then write(' <assign>');
X
X gettok; {consume :=, assignment statement}
X ex := pexpr;
X ext := exprtype;
X
X if iscall(lv) then {assignment to function name}
X puts('return '+ex)
X else
X
X begin
X if copy(ex,1,5) = 'scat(' then
X puts('sbld('+lv+',' + copy(ex,6,255))
X else
X
X if lvt = 's' then
X if ext = 's' then
X puts('strcpy('+lv+','+ex+')')
X else
X puts('sbld('+lv+',"%'+ext+'",'+ex+')')
X else
X
X if lvt = 'c' then
X if ext = 's' then
X puts(lv+' = first('+ex+')')
X else
X puts(lv+' = '+ex)
X else
X puts(lv+' = '+ex);
X end;
X end
X else
X
X if tok[1] = ':' then
X begin
X if debug_parse then write(' <label>');
X
X putline;
X puts(lv+': ');
X
X gettok; {label identifier}
X
X if tok[1] = ';' then
X gettok;
X
X exit;
X end
X else
X
X begin
X if debug_parse then write(' <call>');
X
X if iscall(lv) then
X puts(lv)
X else
X puts(lv+'()');
X end;
X
X nospace := false;
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end
X else
X
X begin
X puts('; ');
X {newline;?}
X end;
X
Xend;
X
X
X
X
X(********************************************************************)
Xprocedure pnumlabel;
X {parse statements starting with an number; these must be
X numeric labels}
Xbegin
X if debug_parse then write(' <numlabel>');
X putline;
X puts('label_'+tok+': ');
X
X gettok; {consume the number}
X gettok; {consume the :}
Xend;
X
X
X(********************************************************************)
Xprocedure plabel;
X {parse (and throw away) a label section}
Xbegin
X if debug_parse then write(' <label>');
X
X while tok[1] <> ';' do
X gettok;
X
X gettok;
Xend;
X
X
X
X
X(********************************************************************)
X(*
X * process single statement
X *
X * expects tok to be first token of statement
X * processes nested blocks
X * exits with tok as end of statement
X *
X *)
X
Xprocedure pstatement;
Xvar
X builtin: boolean;
X
Xbegin
X
X if recovery then
X begin
X while tok[1] <> ';' do
X gettok;
X gettok;
X {warning('Error recovery (pstatement)');}
X recovery := false;
X exit;
X end;
X
X if (toktype = identifier) and (cursym <> nil) then
X builtin := cursym^.suptype = ss_builtin
X else
X builtin := false;
X
X if debug_parse then write(' <stmt>');
X
X if toktype = number then
X pnumlabel
X else
X
X case tok[1] of
X '.':
X exit;
X
X ';':
X begin
X puts('; ');
X gettok;
X end;
X
X '{':
X pblock;
X
X 'C':
X if tok = 'CASE' then
X pcase
X else
X pident;
X
X 'E':
X if builtin and (tok = 'EXIT') then
X pexit
X else
X pident;
X
X 'F':
X if tok = 'FOR' then
X pfor
X else
X pident;
X
X 'G':
X if tok = 'GOTO' then
X pgoto
X else
X pident;
X
X 'H':
X if tok = 'HALT' then
X phalt
X else
X pident;
X
X 'I':
X if tok = 'IF' then
X pif
X else
X if tok = 'INLINE' then
X pinline
X else
X pident;
X
X 'M':
X if builtin and (tok = 'MEM') then
X pport('pokeb')
X else
X if builtin and (tok = 'MEMW') then
X pport('poke')
X else
X pident;
X
X 'N':
X if tok = 'NEW' then
X pnew
X else
X pident;
X
X 'P':
X if builtin and (tok = 'PORT') then
X pport('outportb')
X else
X if builtin and (tok = 'PORTW') then
X pport('outport')
X else
X pident;
X
X 'R':
X if tok = 'REPEAT' then
X prepeat
X else
X if tok = 'READ' then
X pread
X else
X if tok = 'READLN' then
X pread
X else
X pident;
X
X 'S':
X if builtin and (tok = 'STR') then
X pwrite(m_str)
X else
X pident;
X
X 'W':
X if tok = 'WHILE' then
X pwhile
X else
X if tok = 'WITH' then
X pwith
X else
X if tok = 'WRITE' then
X pwrite(m_write)
X else
X if tok = 'WRITELN' then
X pwrite(m_writeln)
X else
X pident;
X else
X pident;
X end;
Xend;
X
X
X(********************************************************************)
X(*
X * process begin...end blocks
X *
X * expects tok to be begin
X * exits with tok = end
X *
X *)
X
Xprocedure pblock;
Xbegin
X if debug_parse then write(' <block>');
X
X puts('{ ');
X gettok; {get first token of first statement}
X
X while (tok[1] <> '}') and not recovery do
X begin
X pstatement; {process the statement}
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok; {get first token of next statement}
X end;
X end;
X
X if not linestart then
X newline;
X
X puttok; {put the closing brace}
X
X gettok;
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
X(*
X * process interface, implementation and uses statements
X *
X *)
X
X(********************************************************************)
Xprocedure puses;
X {parse a uses clause}
Xbegin
X if debug_parse then write(' <uses>');
X
X gettok; {consume the USES}
X
X repeat
X
X {generate an include for the unit header file}
X puts('#include "'+ltok+'.UNH"');
X newline;
X
X {load the saved unit header symbol table}
X load_unitfile(ltok+'.UNS',globals);
X
X {move interface section to skip new entries}
X top_interface := globals;
X
X gettok; {consume the unit name}
X if tok[1] = ',' then
X gettok;
X until (tok[1] = ';') or recovery;
X
Xend;
X
X
X(********************************************************************)
Xprocedure pinterface;
Xbegin
X if debug_parse then write(' <interface>');
X gettok;
X if tok = 'USES' then
X puses;
X
X in_interface := true;
X top_interface := globals;
X
X putline;
X putln('#define extern /* globals defined here */');
X putln('#include "'+unitname+'.UNH"');
X putln('#undef extern');
X
X inc(unitlevel);
X assign(ofd[unitlevel],unitname+'.UNH');
X rewrite(ofd[unitlevel]);
X getmem(outbuf[unitlevel],inbufsiz);
X SetTextBuf(ofd[unitlevel],outbuf[unitlevel]^,inbufsiz);
X
X putline;
X putln('/* Unit header for: '+outname+' -- Made by '+version1+' */');
X
X if tok[1] = ';' then
X gettok;
Xend;
X
X
X(********************************************************************)
Xprocedure pimplementation;
Xbegin
X if debug_parse then write(' <implementation>');
X if not in_interface then
X exit;
X in_interface := false;
X
X {terminate the .unh file being generated}
X close(ofd[unitlevel]);
X freemem(outbuf[unitlevel],inbufsiz);
X dec(unitlevel);
X
X {create the requested unit symbol file}
X create_unitfile(unitname+'.UNS',globals,top_interface);
X
X gettok;
Xend;
X
X
________This_Is_The_END________
if test `wc -c < tpcstmt.inc` -ne 22616; then
echo 'shar: tpcstmt.inc was damaged during transit (should have been 22616 bytes)'
fi
fi ; : end of overwriting check
echo 'x - tpcsym.inc'
if test -f tpcsym.inc; then echo 'shar: not overwriting tpcsym.inc'; else
sed 's/^X//' << '________This_Is_The_END________' > tpcsym.inc
X
X(*
X * TPTC - Turbo Pascal to C translator
X *
X * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
X *
X *)
X
X(********************************************************************)
Xfunction findsym( table: symptr;
X id: string40): symptr;
X {locate a symbol in a specified symbol table. returns pointer to
X the entry if found, otherwise nil is returned}
Xvar
X sym: symptr;
X
Xbegin
X stoupper(id);
X
X sym := table;
X while sym <> nil do
X begin
X
X if sym^.id[1] = id[1] then {for speed, try first char}
X if length(sym^.id) = length(id) then {... then verify length}
X if sym^.id = id then {... finally compare strings}
X begin
X findsym := sym; {symbol found}
X exit;
X end;
X
X sym := sym^.next;
X end;
X
X findsym := nil; {symbol not found}
Xend;
X
X
X(********************************************************************)
Xfunction locatesym(id: string40): symptr;
X {locate a symbol in either the local or the global symbol table.
X returns the symbol table entry pointer, if found. returns
X nil when not in either table}
Xvar
X sym: symptr;
X
Xbegin
X if id[1] = '^' then
X delete(id,1,1);
X
X sym := findsym(locals,id);
X if sym = nil then
X sym := findsym(globals,id);
X
X locatesym := sym;
Xend;
X
X
X(********************************************************************)
Xprocedure addsym( var table: symptr;
X id: string40;
X symtype: symtypes;
X suptype: supertypes;
X parcount: integer;
X varmap: integer;
X lim: integer;
X base: integer;
X dup_ok: boolean);
X {add a symbol to a specific symbol table. duplicates hide prior entries.
X new symbol pointed to by cursym}
Xbegin
X if maxavail-300 < sizeof(cursym^) then
X begin
X ltok := id;
X fatal('Out of memory');
X end;
X
X if (not dup_ok) and (not in_interface) then
X begin
X cursym := findsym(table,id);
X if cursym <> nil then
X begin
X ltok := id;
X if (cursym^.parcount <> parcount) or
X (cursym^.symtype <> symtype) or (cursym^.limit <> lim) then
X warning('Redeclaration not identical');
X ltok := tok;
X end;
X end;
X
X new(cursym);
X cursym^.next := table;
X table := cursym;
X
X cursym^.repid := decl_prefix + id;
X stoupper(id);
X cursym^.id := id;
X cursym^.symtype := symtype;
X cursym^.suptype := suptype;
X cursym^.parcount := parcount;
X cursym^.limit := lim;
X cursym^.base := base;
X cursym^.pvar := varmap;
Xend;
X
X
X(********************************************************************)
Xprocedure newsym( id: string40;
X symtype: symtypes;
X suptype: supertypes;
X parcount: integer;
X varmap: integer;
X lim: integer;
X base: integer);
X {enter a new symbol into the current symbol table (local or global)}
Xbegin
X if (unitlevel = 0) or (in_interface) then
X addsym(globals,id,symtype,suptype,parcount,varmap,lim,base,false)
X else
X addsym(locals,id,symtype,suptype,parcount,varmap,lim,base,true);
Xend;
X
X
X
X(********************************************************************)
Xprocedure dumptable(sym: symptr; top: symptr);
X {dump entries from the specified symbol table, stopping where indicated}
Xvar
X info: string40;
X
Xbegin
X
X if (not dumpsymbols) or (sym = nil) or (sym = top) then
X exit;
X
X {putline;}
X putln('/* User symbols:');
X putln(' * Class Type Base Limit Pars Pvar Identifier');
X putln(' * ------------ ------------ ----- ------ ---- ------ --------------');
X
X while (sym <> nil) and (sym <> top) do
X begin
X
X if sym^.repid = '<predef>' then
X begin
X if dumppredef then
X begin
X putln(' *');
X putln(' * Predefined symbols:');
X putln(' * Class Type Base Limit Pars Pvar Identifier');
X putln(' * ------------ ------------ ----- ------ ---- ------ --------------');
X end
X else
X sym := nil;
X end
X else
X
X begin
X write(ofd[unitlevel],' * ',
X ljust(supertypename[sym^.suptype],13),
X ljust(typename[sym^.symtype],12),
X sym^.base:5,' ',
X sym^.limit:6,' ',
X sym^.parcount:4,' ',
X sym^.pvar:6,' ',
X sym^.repid);
X putline;
X end;
X
X if sym <> nil then
X sym := sym^.next;
X end;
X
X putln(' */');
X putline;
Xend;
X
X
X(********************************************************************)
Xprocedure purgetable( var table: symptr; top: symptr);
X {purge all entries from the specified symbol table}
Xvar
X sym: symptr;
X
Xbegin
X dumptable(table, top);
X
X while (table <> nil) and (table <> top) do
X begin
X sym := table;
X table := table^.next;
X
X {if sym^.suptype = ss_const then
X putln('#undef '+sym^.repid);}
X
X dispose(sym);
X end;
Xend;
X
X
X(********************************************************************)
Xprocedure create_unitfile(name: string64; sym, top: symptr);
X {dump symbol table to the specified unit symbol file}
Xvar
X fd: text;
X outbuf: array[1..inbufsiz] of byte;
X
Xbegin
X assign(fd,name);
X{$I-}
X rewrite(fd);
X{$I+}
X if ioresult <> 0 then
X begin
X ltok := name;
X fatal('Can''t create unit symbol file');
X end;
X
X setTextBuf(fd,outbuf);
X
X while (sym <> nil) and (sym <> top) do
X begin
X writeln(fd,sym^.id);
X writeln(fd,sym^.repid);
X writeln(fd,ord(sym^.suptype),' ',
X ord(sym^.symtype),' ',
X sym^.base,' ',
X sym^.limit,' ',
X sym^.parcount,' ',
X sym^.pvar);
X
X inc(objtotal,3);
X sym := sym^.next;
X end;
X
X close(fd);
Xend;
X
X
X(********************************************************************)
Xprocedure load_unitfile(name: string64; var table: symptr);
X {load symbol table fromthe specified unit symbol file}
Xvar
X fd: text;
X sym: symptr;
X sstype: byte;
X stype: byte;
X inbuf: array[1..inbufsiz] of byte;
X
Xbegin
X assign(fd,name);
X {$I-} reset(fd); {$I+}
X if ioresult <> 0 then
X begin
X name := symdir + name;
X assign(fd,name);
X {$I-} reset(fd); {$I+}
X end;
X
X if ioresult <> 0 then
X begin
X ltok := name;
X fatal('Can''t open unit symbol file');
X end;
X
X setTextBuf(fd,inbuf);
X
X while not eof(fd) do
X begin
X new(sym);
X sym^.next := table;
X table := sym;
X
X readln(fd,sym^.id);
X readln(fd,sym^.repid);
X readln(fd,sstype,stype,
X sym^.base,
X sym^.limit,
X sym^.parcount,
X sym^.pvar);
X
X sym^.suptype := supertypes(sstype);
X sym^.symtype := symtypes(stype);
X end;
X
X close(fd);
Xend;
X
X
________This_Is_The_END________
if test `wc -c < tpcsym.inc` -ne 7059; then
echo 'shar: tpcsym.inc was damaged during transit (should have been 7059 bytes)'
fi
fi ; : end of overwriting check
echo 'x - tpcunit.inc'
if test -f tpcunit.inc; then echo 'shar: not overwriting tpcunit.inc'; else
sed 's/^X//' << '________This_Is_The_END________' > tpcunit.inc
X
X(*
X * TPTC - Turbo Pascal to C translator
X *
X * (C) 1988 Samuel H. Smith (rev. 13-Feb-88)
X *
X *)
X
X
X(********************************************************************)
X(*
X * process generic declaration section
X * dispatches to const, type, var, proc, func
X * enter with tok=section type
X * exit with tok=next section type
X *
X *)
X
Xprocedure psection;
Xbegin
X if recovery then
X begin
X while toktype <> keyword do
X gettok;
X {warning('Error recovery (psection)');}
X recovery := false;
X end;
X
X if debug_parse then write(' <section>');
X
X if (tok = 'EXTERNAL') or (tok = 'OVERLAY') or
X (tok = 'PROCEDURE') or (tok = 'FUNCTION') then
X punit
X else
X
X if tok = 'INTERFACE' then
X pinterface
X else
X
X if tok = 'IMPLEMENTATION' then
X pimplementation
X else
X
X if tok = 'USES' then
X begin
X puses;
X if tok[1] = ';' then
X gettok;
X end
X else
X
X if tok = 'UNIT' then
X comment_statement
X else
X
X if tok = 'CONST' then
X pconst
X else
X
X if tok = 'TYPE' then
X ptype
X else
X
X if tok = 'VAR' then
X pvar
X else
X
X if tok = 'LABEL' then
X plabel
X else
X
X if tok[1] = '{' then
X pblock
X else
X
X if (tok[1] = '.') or (tok[1] = '}') then
X begin
X tok := '.';
X exit;
X end
X else
X syntax('Section header expected (psection)');
Xend;
X
X
X(********************************************************************)
X(*
X * process argument declarations to
X * program, procedure, function
X *
X * enter with header as tok
X * exits with tok as ; or :
X *
X *)
X
Xconst
X extern = true;
X
Xprocedure punitheader(is_external: boolean);
Xvar
X proc: string40;
X proclit: string40;
X vars: paramlist;
X types: paramlist;
X bases: array [1..maxparam] of integer;
X i: integer;
X ii: integer;
X rtype: string40;
X varval: integer;
X varon: boolean;
X locvar: integer;
X iptr: integer;
X
Xbegin
X gettok; {skip unit type}
X proclit := ltok;
X
X if (unitlevel > 1) and (not in_interface) then
X begin
X {make name unique if it clashes with an existing global}
X if cursym = nil then
X proc := proclit
X else
X proc := procnum + '_' + proclit;
X
X warning('Nested function');
X
X writeln(ofd[unitlevel-1],^M^J' /* Nested function: ',proc,' */ ');
X inc(objtotal,2);
X end
X else
X proc := proclit;
X
X gettok; {skip unit identifier}
X
X vars.n := 0;
X varval := 0; { 0 bit means value, 1 = var }
X varon := false;
X
X (* process param list, if any *)
X if tok[1] = '(' then
X begin
X gettok;
X
X while (tok[1] <> ')') and not recovery do
X begin
X
X ii := vars.n + 1;
X repeat
X if tok[1] = ',' then
X gettok;
X
X if tok = 'VAR' then
X begin
X gettok;
X varon := true;
X end;
X
X inc(vars.n);
X if vars.n > maxparam then
X fatal('Too many params (punitheader)');
X vars.id[vars.n] := ltok;
X gettok;
X
X until tok[1] <> ',';
X
X if tok[1] = ':' then
X begin
X gettok; {consume the :}
X
X {parse the param type}
X rtype := psimpletype;
X end
X else
X
X begin {untyped variable if ':' is missing}
X rtype := 'void';
X curtype := s_void;
X curbase := 0;
X cursuptype := ss_scalar; {ss_array?}
X end;
X
X {assign and param types, converting 'var' and 'array' params}
X iptr := 0;
X if rtype[1] = '^' then
X rtype[1] := '*';
X
X {flag var parameters; strings and arrays are implicitly var in C}
X if varon and (curtype <> s_string) and (cursuptype <> ss_array) then
X iptr := 1 shl (ii - 1);
X
X if curtype = s_string then
X rtype := 'char *'
X else
X if cursuptype = ss_array then
X rtype := typename[curtype] + ' *';
X
X {assign data types for each ident}
X for i := ii to vars.n do
X begin
X types.id[i] := rtype;
X types.stype[i] := curtype;
X types.sstype[i] := cursuptype;
X bases[i] := curbase;
X varval := varval or iptr;
X iptr := iptr shl 1;
X end;
X
X if tok[1] = ';' then
X begin
X gettok;
X varon := false;
X end;
X
X end; {) seen}
X
X gettok; {consume the )}
X end;
X
X (* process function return type, if any *)
X if tok[1] = ':' then
X begin
X gettok; {consume the :}
X rtype := psimpletype;
X
X if curtype = s_string then
X rtype := 'char *'
X else
X if cursuptype = ss_array then
X rtype := typename[curtype] + ' *';
X end
X else
X
X begin
X rtype := 'void';
X curtype := s_void;
X end;
X
X putline;
X
X (* prefix procedure decl's when external *)
X if is_external then
X begin
X putln(ljust('extern '+rtype,identlen)+proc+'();');
X addsym(globals,proc,curtype,ss_func,0,varval,0,9,false);
X exit;
X end;
X
X
X (* process 'as NEWNAME' clause, if present (tptc extention to specify
X the replacement name in the symbol table *)
X if tok = 'AS' then
X begin
X gettok;
X proc := usetok;
X end;
X
X
X (* output the return type, proc name, formal param list *)
X if in_interface then
X rtype := 'extern '+rtype;
X puts(ljust(rtype,identlen)+proc+'(');
X
X if vars.n = 0 then
X puts('void');
X
X
X (* output the formal param declarations *)
X locvar := varval;
X for i := 1 to vars.n do
X begin
X iptr := -1;
X
X if (locvar and 1) = 1 then
X begin
X iptr := -2;
X types.id[i] := types.id[i] + ' *';
X end;
X
X puts(ljust(types.id[i],identlen)+vars.id[i]);
X addsym(locals,vars.id[i],types.stype[i],ss_scalar,iptr,0,0,bases[i],true);
X locvar := locvar shr 1;
X
X if i < vars.n then
X begin
X putln(',');
X puts(ljust('',identlen+length(proc)+1));
X end;
X end;
X
X puts(')');
X nospace := false;
X
X {enter the procedure in the global symbol table}
X addsym(globals,proclit,curtype,ss_func,vars.n,varval,0,0,false);
X cursym^.repid := proc;
Xend;
X
X
X(********************************************************************)
X(*
X * process body of program unit
X * handles all declaration sections
X * and a single begin...end
X * recursively handles procedure declarations
X * ends with tok=}
X *)
X
Xprocedure punitbody;
Xbegin
X gettok;
X
X if tok = 'INTERRUPT' then
X begin
X warning('Interrupt handler');
X gettok;
X end;
X
X if tok = 'FORWARD' then
X begin
X puts(';');
X gettok;
X end
X else
X
X if tok = 'EXTERNAL' then
X begin
X puts('/* ');
X repeat
X puttok;
X gettok;
X until tok[1] = ';';
X puts(' */ ;');
X end
X else
X
X if tok = 'INLINE' then
X begin
X newline;
X putln('{');
X puts(' ');
X pinline;
X putln('}');
X end
X else
X
X begin
X puts('{ ');
X
X repeat
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end;
X
X if tok[1] <> '{' then
X psection;
X until tok[1] = '{';
X
X gettok; {get first token of first statement}
X
X while (tok[1] <> '}') and not recovery do
X begin
X pstatement; {process the statement}
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok; {get first token of next statement}
X end;
X end;
X
X puttok;
X end;
Xend;
X
X
X(********************************************************************)
Xprocedure enter_procdef;
X {increase output file level and direct output to the new file}
Xvar
X nam: anystring;
Xbegin
X {increment this procedure number}
X inc(procnum[2]);
X if procnum[2] > 'Z' then
X begin
X inc(procnum[1]);
X procnum[2] := 'A';
X end;
X
X inc(unitlevel);
X if unitlevel > maxnest then
X fatal('Functions nested too deeply');
X
X str(unitlevel,nam);
X nam := workdir + nestfile + nam;
X
X assign(ofd[unitlevel],nam);
X {$i-} rewrite(ofd[unitlevel]); {$i+}
X
X if ioresult <> 0 then
X begin
X dec(unitlevel);
X ltok := nam;
X fatal('Can''t create tempfile');
X end;
X
X if maxavail-300 <= inbufsiz then
X begin
X ltok := nam;
X fatal('Out of memory');
X end;
X
X getmem(outbuf[unitlevel],inbufsiz);
X SetTextBuf(ofd[unitlevel],outbuf[unitlevel]^,inbufsiz);
Xend;
X
X
X(********************************************************************)
Xprocedure exit_procdef;
X {copy the outer output file to the next lower level output
X and reduce output level by 1}
Xvar
X line: string;
X
Xbegin
X if unitlevel < 1 then
X exit;
X
X close(ofd[unitlevel]);
X reset(ofd[unitlevel]);
X SetTextBuf(ofd[unitlevel],outbuf[unitlevel]^,inbufsiz);
X
X while not eof(ofd[unitlevel]) do
X begin
X readln(ofd[unitlevel],line);
X writeln(ofd[0],line);
X end;
X
X close(ofd[unitlevel]);
X erase(ofd[unitlevel]);
X freemem(outbuf[unitlevel],inbufsiz);
X dec(unitlevel);
Xend;
X
X
X(********************************************************************)
X(*
X * process program, procedure and function declaration
X *
X * enter with tok=function
X * exit with tok=;
X *
X *)
X
Xprocedure punit;
Xvar
X top: symptr;
Xbegin
X if debug_parse then write(' <unit>');
X
X nospace := true;
X top := locals;
X
X if (tok = 'OVERLAY') then
X gettok;
X
X if (tok = 'EXTERNAL') then {mt+}
X begin
X gettok; {consume the EXTERNAL}
X
X if tok[1] = '[' then
X begin
X gettok; {consume the '['}
Xi puts('/* overlay '+ltok+' */ ');
X gettok; {consume the overlay number}
X
X gettok; {consume the ']'}
X end;
X
X punitheader(extern);
X if tok[1] = ';' then
X gettok;
X purgetable(locals,top);
X end
X else
X
X if in_interface then
X begin
X nospace := false;
X punitheader(not extern);
X
X puts(';');
X if tok[1] = ';' then
X gettok;
X
X if tok = 'INLINE' then
X begin
X pinline;
X warning('Inline procedure');
X end;
X
X purgetable(locals,top);
X end
X else
X
X begin
X {enter a (possibly nested) procedure}
X enter_procdef;
X
X punitheader(not extern);
X punitbody;
X gettok;
X if tok[1] = ';' then
X gettok;
X purgetable(locals,top);
X
X {exit the (possibly nested) procedure, append text to toplevel outfile}
X exit_procdef;
X end;
X
Xend;
X
X
X
X(********************************************************************)
X(*
X * process main program
X *
X * expects program head
X * optional declarations
X * block of main code
X * .
X *
X *)
X
Xprocedure pprogram;
Xbegin
X putline;
X putln('/*');
X putln(' * Generated by '+version1);
X putln(' * '+version2);
X putln(' */');
X putln('#include "tptcmac.h"');
X
X getchar; {get first char}
X gettok; {get first token}
X
X if (tok = 'PROGRAM') or (tok = 'UNIT') then
X begin
X comment_statement;
X gettok;
X end;
X
X if tok = 'MODULE' then
X begin
X mt_plus := true; {shift into pascal/mt+ mode}
X comment_statement;
X gettok;
X end;
X
X repeat
X if tok[1] = ';' then
X begin
X puttok;
X gettok;
X end;
X
X if tok = 'MODEND' then
X exit;
X
X if (tok[1] <> '{') then
X psection;
X until (tok[1] = '{') or (tok[1] = '.') or recovery;
X
X {process the main block, if any}
X if tok[1] = '{' then
X begin
X putline;
X putln('main(int argc,');
X putln(' char *argv[])');
X
X puttok;
X gettok; {get first token of main block}
X
X while (tok[1] <> '}') and (tok[1] <> '.') do
X begin
X pstatement; {process the statement}
X
X if tok[1] = ';' then
X begin
X puttok;
X gettok; {get first token of next statement}
X end;
X end;
X
X putln('}');
X end;
X
X putline;
Xend;
X
________This_Is_The_END________
if test `wc -c < tpcunit.inc` -ne 12098; then
echo 'shar: tpcunit.inc was damaged during transit (should have been 12098 bytes)'
fi
fi ; : end of overwriting check
echo 'x - tptc.doc'
if test -f tptc.doc; then echo 'shar: not overwriting tptc.doc'; else
sed 's/^X//' << '________This_Is_The_END________' > tptc.doc
X
X
X TPTC16 - Translate Pascal to C
X Version 1.6, 13-Feb-88
X
X (C) Copyright 1986, 1988 by Samuel H. Smith
X All rights reserved.
X
X
XThis program will read a turbo pascal source file and convert it into
Xthe corresponding C source code. It does much of the work required in
Xa full translation.
X
XUsage: TPTC input_file [output_file] [options]
X
XWhere: input_file specifies the main source file, .PAS default
X output_file specifies the output file, .C default
X -B deBug trace during scan
X -BP deBug trace during Parse
X -D Dump user symbols
X -DP Dump Predefined system symbols
X -I output Include files' contents
X -L map all identifiers to Lower case
X -M use Pascal/MT+ specific translations
X -NC No Comments passed to output file
X -Q Quiet mode; suppress warnings
X -Sdir\ search dir\ for .UNS symbol files
X -Tnn Tab nn columns in declarations
X -Wdrive: use drive: for Work/scratch files (ramdrive)
X -# don't translate lines starting with "#"
X
XDefault command parameters are loaded from TPTC environment variable.
X
XExample: tptc fmap
X tptc fmap -L -d -wj:\tmp\
X tptc -l -d -wj: -i -q -t15 fmap.pas fmap.out
X
X set tptc=-wj: -i -l -sc:\libs
X tptc test ;uses options specified earlier
X
X
XLICENSE
X=======
X
X SourceWare: What is it?
X -----------------------
X SourceWare is my name for a unique concept in user supported software.
X
X Programs distributed under the SourceWare concept always offer complete
X source code.
X
X This package can be freely distributed so long as it is not modified
X or sold for profit. If you find that this program is valuable, you
X can send me a donation for what you think it is worth. I suggest
X about $20.
X
X Send your contributions to:
X Samuel. H. Smith
X 5119 N. 11 ave 332
X Phoenix, Az 85013
X
X
X Why SourceWare?
X ---------------
X Why do I include source code? Why isn't the donation manditory? The
X value of good software should be self-evident. The source code is
X the key to complete understanding of a program. You can read it to
X find out how things are done. You can also change it to suit your
X needs, so long as you do not distribute the modified version without
X my consent.
X
X
X Copyright
X ---------
X If you modify this program, I would appreciate a copy of the new
X source code. I am holding the copyright on the source code, so
X please don't delete my name from the program files or from the
X documentation.
X
X
XSUPPORT
X=======
X
X I work very hard to produce a software package of the highest
X quality and functionality. I try to look into all reported bugs, and
X will generally fix reported problems within a few days.
X
X Since this is user supported software under the SourceWare concept,
X I don't expect you to contribute if you don't like it or if it
X doesn't meet your needs.
X
X If you have any questions, bugs, or suggestions, please contact me
X at: The Tool Shop BBS (602) 279-2673
X
X The latest version is always available for downloading.
X
X Enjoy! Samuel H. Smith
X Author and Sysop of The Tool Shop.
X
X
X
X
XThe following language constructs are translated:
X------------------------------------------------
X
X Comments are translated from either {...} or (*...*) into /*...*/.
X
X Begin and End are translated into { and }.
X
X Const declarations are translated from
X ID = VALUE
X into
X static ID = VALUE.
X
X Simple Var declarations are translated from
X ID TYPE
X into
X TYPE ID.
X
X Integer subrange types are translated into integers.
X
X Record types are translated from
X ID = record MEMBER-LIST end
X into
X typedef struct { MEMBER-LIST } ID.
X
X Enumeration types are translated from
X ID = (...)
X into
X typedef enum {...} ID.
X
X Array types are translated from
X ID = array [RANGE] of TYPE
X into
X typedef TYPE ID[RANGE].
X
X Pointer types are translated from
X ID = ^DEFINED-TYPE
X into
X DEFINED-TYPE *ID.
X
X String types are translated from
X ID = string[N]
X into
X typedef char ID[N+1].
X
X File types are translated from
X ID = text[N]
X ID = file
X into
X FILE *ID
X int ID.
X
X For statements are translated from
X for VAR := FIRST to LAST do STATEMENT
X for VAR := FIRST downto LAST do statement
X into
X for (VAR = FIRST; VAR <= LAST; VAR++) STATEMENT
X for (VAR = FIRST; VAR >= LAST; VAR--) STATEMENT
X
X While statements are translated from
X while COND do STATEMENT
X into
X while (COND) statement.
X
X Repeat statements are translated from
X repeat STATEMENTS until COND
X into
X do { STATEMENTS } while(!COND).
X
X If statements are translated from
X if COND then STATEMENT else STATEMENT
X into
X if (COND) STATEMENT; else STATEMENT.
X
X Case statements are translated from
X case VALUE of
X V: STATEMENT;
X V,U: STATEMENT;
X else STATEMENT
X end
X into
X switch (VALUE) {
X case V: STATEMENT; break;
X case V:
X case U: STATEMENT; break;
X default: STATEMENT;
X }.
X
X Ranges in the form VAL..VAL automatically include cases for
X intermediate values.
X
X The IN operator is translated from
X VAL in [A,B,C]
X into
X inset(VAL, setof(A,B,C,-1)).
X
X The ParamCount and ParamStr functions are translated from
X paramcount
X paramstr(n)
X into
X argc
X argv[n].
X
X Dummy parameter lists are added to function and procedure calls,
X where they are required in C but not in Pascal.
X
X The following expression operators are translated
X from DIV to / , MOD to % ,
X AND to &&, OR to ||,
X XOR to ~ , <> to !=,
X NOT to ! , SHR to >>,
X SHL to <<, = to ==, {+others}
X := to = .
X Bitwise AND and OR operators are translated into & and |.
X
X The '^' symbol is translated
X from VAR^ to *VAR,
X VAR^.MEMBER to VAR->MEMBER.
X
X Exit statements are translated
X from exit to return.
X
X The New operator is translated from
X new(VAR)
X into
X VAR = malloc(sizeof(*VAR)).
X
X
X Procedure/function formal parameter lists are translated into the
X new form defined in ANSI C (and as used by Turbo C):
X from
X function NAME(V1: TYPE1; V2: TYPE2): TYPE3
X into
X TYPE3 NAME(TYPE1 V1,TYPE2 V2)
X
X Procedures are translated into functions with 'void' return types.
X
X The special character literal syntax, ^C or #nn, is translated into
X '\ooo', where ooo is the octal notation for the ascii code.
X
X Hex constants $hhhh are translated into 0xhhhh.
X
X Write and WriteLn are translated from:
X write(VAR,VAR:n,VAR:n:m)
X writeln(FILE,VAR,VAR,VAR)
X into
X printf("%d%nd%n.md",VAR,VAR,VAR)
X fprintf(FILE,"%d%d%d\n",VAR,VAR,VAR).
X
X Read and ReadLn are translated from:
X read(VAR,VAR,VAR)
X readln(FILE,VAR,VAR,VAR)
X into
X scanf("%d%nd%d",&VAR,&VAR,&VAR)
X fscanf(FILE,"%d%d%d\n",&VAR,&VAR,&VAR).
X
X String assignments are translated from:
X VAR := "string"
X VAR := "string1(" + VAR1 + ")string2"
X into
X strcpy(VAR, "string")
X sbld(VAR,"string1(%s)string2",VAR1). {+other compound forms}
X
X String comparisons are translated from:
X VAR == "string"
X VAR < "string"
X "string" >= VAR
X into
X (strcmp(VAR,"string") == 0)
X (strcmp(VAR,"string") < 0)
X (strcmp("string",VAR) >= 0).
X
X Function value assignments are translated from:
X FUN_NAME := expr
X into
X return expr.
X
X Numeric statement labels are translated to label_nn.
X Label identifiers are not changed.
X Local GOTO statements are handled properly.
X
X Nested procedures are "flattened" out, but local variable sharing and
X local scoping are not translated.
X
X Direct I/O port and memory references are translated:
X portw[expr] := expr + port[n]
X mem[seg:ofs] := memw[seg:ofs] + expr
X into
X outport(expr, expr+inportb(n))
X pokeb(seg,ofs, peek(seg,ofs)+expr)
X
X VAR parameters are translated into pointer variables;
X references to formal parameters are implicitly dereferenced (i.e. * added);
X references to actual parameters are implicitly referenced (i.e. & added).
X
X Forward pointer type declarations are translated, but will not compile
X in C. They must be manually recoded.
X
X Variant record type declarations are translated into unions.
X
X Absolute variables are translated into initialized pointer variables.
X
X
X
XSupport Pascal/MT+:
X-------------------
X
X Var declarations are translated from
X ID external TYPE
X into
X extern TYPE ID.
X
X The following expression operators are translated
X from ! to | , | to |,
X & to & , ~ to !,
X ? to ! , \ to !.
X
X External function declarations are translated
X from
X external function NAME(V1: TYPE1; V2: TYPE2): TYPE3
X external [n] function NAME(V1: TYPE1; V2: TYPE2): TYPE3
X into
X extern TYPE3 NAME()
X
X External procedure declarations are translated
X from
X external procedure NAME(V1: TYPE1; V2: TYPE2)
X external [n] procedure NAME(V1: TYPE1; V2: TYPE2)
X into
X extern void NAME()
X
X Write and WriteLn are translated from:
X write([ADDR(FUN)],VAR:n,VAR:n:m)
X write([],VAR:n,VAR:n:m)
X into
X iprintf(FUN,"%nd%n.md",VAR,VAR)
X printf("%nd%n.md",VAR,VAR)
X
X Read and ReadLn are translated from:
X read([ADDR(FUN)],VAR,VAR)
X read([],VAR,VAR)
X into
X iscanf(FUN,"%d%nd%d",&VAR,&VAR,&VAR)
X scanf("%d%nd%d",&VAR,&VAR,&VAR)
X
X Long integer constants #nnn are translated into nnnL.
X
X
X
XSome language features that are not yet translated:
X---------------------------------------------------
X
X File access procedures are only partially supported (assign, close,
X etc.).
X
X Variant record type decl's are translated into unions, but expressions
X using the variant part are not translated.
X
X C operator precedence differs from that of Pascal, and the differences
X are not translated.
X
X The WITH statement is not translated.
X
X Local variable sharing among nested procedures is not translated.
X
X
X
XRevision history
X----------------
X
X See HISTORY.DOC for the complete revision history.
X
X I continue to update and improve TPTC. If you have a program that
X TPTC will not translate, please send me a copy of it. This will help
X me in future versions. I will not redistribute the file without your
X permission.
X
X Send sample sources to:
X Samuel. H. Smith
X (602) 279-2673 (data)
X 5119 N. 11 ave 332
X Phoenix, Az 85013
X
________This_Is_The_END________
if test `wc -c < tptc.doc` -ne 11061; then
echo 'shar: tptc.doc was damaged during transit (should have been 11061 bytes)'
fi
fi ; : end of overwriting check
exit 0
More information about the Comp.sources.misc
mailing list