home *** CD-ROM | disk | FTP | other *** search
-
- (*
- todo:
- -- in var params, passing address of pointer
- -- two dimensional arrays, typed constants, see test.pas
- -- array[a,b...] and array[a] of array... not translated
- -- process subscripted (full lvalue) for fd's in read/write
- -- translate 'str' and 'val'
- -- string returning procedures translated to char * return
- -- string (pointer to array) var parameters translated to char *
- -- pointer deref does not determine lvalue type (i.e. xxx->m should
- detect string types)
- -- writeln strings: 'literal',^M^J,'another'
- -- nested variable sharing not proper
- procedure ordering
- outer local decl's not prefixed
- -- variant records not translated
- -- untyped parameter variables
- -- absolute variables
-
- manual translations:
- -- nested procedure ordering
- -- atoi macro clash ?
-
- changes
- -- turbo-c procedure declaration syntax
- -- arrays subscripted by enumeration types
- -- fails to handle null else clause in case statement
- -- include intermediate cases in swith() .. case x..y
- -- pointer/var parameter translation *id.mem should be id->mem
- -- pointer/var parameter translation *id[n] should be id[n]
- -- concat(...)+char and string+char not detected as string/character
- concat operation.
- -- detect concat(concat... and replace with a sprintf variant
-
- -- changed sprintf calls to sbld calls to preserve sources during build
- -- pos(c,str) and pos(str,str) are now separately translated
-
- -- added 'base' to symbol table; use to add base-subscript offset
- in all subscript references.
- -- moved typename translations to tpcmac.h header
- -- fixed bug in non-translation of tshell directives
- -- forward pointer declarations
- -- translate inline into asm statements
- -- complete forward translation
-
- ---------------
- 13-oct-87
- -- improved string and array parameter translations
- -- string returns are now translated into char *
-
- 15-oct-87
- -- corrected error in typed constant translation where nested
- records are initialized.
- -- variant record declarations are translated into unions
- but no variant expression translations are done.
- -- changed nested procedure error messages to include procedure name.
-
-
- (*
- *
- * TPTC - Turbo Pascal to C translator
- *
- * S.H.Smith, 9/9/85 (rev. 2/13/88)
- *
- * Copyright 1986, 1987 by Samuel H. Smith; All rights reserved.
- *
- *
- * Revision history
- * ----------------
- *
- * 09/09/85 v0.0 (paspp)
- * Initial coding by Samuel H. Smith. Never released.
- *
- * 12/19/86 v1.0
- * First distributed as TPC10 under shareware concept.
- *
- * 04/15/87 v1.1
- * Corrected handling of unary minus.
- * Improved error messages; added error messages to object file.
- * Added handler for integer subrange types.
- * Added handling for goto statement and numeric labels.
- * The macro header, tpcmac.h, now contains more declarations.
- * Distributed as TPC11.
- *
- * 04/22/87 v1.2
- * Corrected an error that led to a crash on lines with more than 40
- * leading spaces. Distributed as TPC12.
- *
- * 05/20/87 v1.3
- * Added support for pascal/MT+: external procedures and variables,
- * special write/read indirect syntax, & and ! operators,
- * default string size for string declarations.
- * Distributed as TPC13.
- *
- * 05/26/87 v1.4
- * Additional support for pascal/MT+. The translator "shifts" into a
- * MT+ specific mode when it recognizes the 'MODULE' statement.
- * The '|' operator is recognized for bitwise OR.
- * The '\', '?' and '~' operators are all translated into a unary
- * not (is this right, Noam?).
- * Read(ln) and Write(ln) now support the special case of "[]" for the
- * I/O routine.
- * Long integer literals are translated from '#nnn' to 'nnnL'
- *
- * 06/01/87 v1.5
- * Added new ','nd-line parser.
- * Added -lower option to map identifiers to lower case.
- * Added -mt option to force pascal/mt+ mode.
- * Added partial var-parameter translation.
- * Mem, MemW, Port and PortW are all translated into Turbo C.
- * Turbo-c procedure declaration syntax is now used.
- * Arrays may now be subscripted by enumeration types.
- * Null else clause now handled properly in IF and CASE statements.
- * For .. downto is now translated correctly.
- * The VAL..VAL form is now translated in case statements.
- *
- *)
-
- {$R+} {Range checking off}
- {$B+} {Boolean complete evaluation on}
- {$S+} {Stack checking on}
- {$I+} {I/O checking on}
- {$N-} {No numeric coprocessor}
- {$V-} {Relax string rules}
- {$M 65500,16384,655360} {Turbo 3 default stack and heap}
-
-
- program translate_tp_to_c;
-
- uses Crt;
-
- const
- version1 = 'TPTC - Translate Pascal to C';
- version2 = 'Version 1.6, 2/8/88 S.H.Smith';
- maxparam = 20; {max number of parameters to process}
- identlen = 12; {nominal length of identifiers}
- maxnest = 6; {maximum procedure nesting}
- nestfile = 'nest$'; {scratchfile for nested procedures}
- localseprt = '__S__'; {local sym table nesting separating string}
-
- type
- anystring = string [127];
- string255 = string [255];
- string80 = string [80];
- string40 = string [40];
- string20 = string [20];
- string10 = string [10];
-
- toktypes = (number, identifier,
- strng, keyword,
- unknown);
-
- symtypes = (s_int, s_long,
- s_double, s_string,
- s_char, s_struct,
- s_file, s_void );
-
- supertypes = (ss_scalar, ss_const,
- ss_func, ss_struct,
- ss_array );
-
- symptr = ^symrec;
- symrec = record
- symtype: symtypes; { simple type }
- suptype: supertypes; { scalar,array etc. }
- id: string40; { name of entry }
- parcount: integer; { parameter count }
- pvar: integer; { var/val reference }
- base: integer; { base value for subscripts }
- limit: integer; { limiting value for scalars }
- parent: symptr;
- next: symptr;
- end;
-
- paramlist = record
- n: integer;
- id: array [1..maxparam] of string80;
- stype: array [1..maxparam] of symtypes;
- sstype: array [1..maxparam] of supertypes;
- end;
-
- const
-
- (* names of symbol types *)
- typename: array[symtypes] of string40 =
- ('int', 'long',
- 'double', 'char *',
- 'char', 'struct',
- 'file', 'void');
-
- supertypename: array[supertypes] of string40 =
- ('Scalar', 'Constant',
- 'Function', 'Structure',
- 'Array' );
-
-
- (* these words start new statements or program sections *)
- nkeywords = 12;
- keywords: array[1..nkeywords] of string40 = (
- 'PROGRAM', 'PROCEDURE', 'FUNCTION',
- 'VAR', 'CONST', 'TYPE',
- 'LABEL', 'OVERLAY', 'FORWARD',
- 'MODULE', 'EXTERNAL', 'CASE');
-
-
- var
- con: text;
- ltok: string80;
- tok: string80;
- toktype: toktypes;
-
- infd: text;
- inclfd: text;
- incl_name: string[64];
- read_include: boolean;
-
- nextc: char;
-
- spaces: anystring;
- extradot: boolean;
- nospace: boolean;
-
- unitlevel: integer;
-
- globals: symptr;
- locals: symptr;
-
- curtype: symtypes;
- cursuptype: supertypes;
- curlimit: integer;
-
- srclines: array [1..maxnest] of integer;
- srcfiles: array [1..maxnest] of string40;
-
- ofd: array[1..maxnest] of text;
- level: integer;
-
- in_locals: boolean;
- past_marker: boolean;
- in_globals: boolean;
- nestn: string10;
-
- mt_plus: boolean; {true if translating Pascal/MT+}
- map_lower: boolean; {true to map idents to lower case}
- dumpsymbols: boolean; {dump tables to object file}
- includeinclude:boolean; {include include files in output}
-
-
- {$I \tinc\ljust.inc} {left justify writeln strings}
- {$I \tinc\atoi.inc} {ascii to integer conversion}
- {$I \tinc\ftoa.inc} {float to ascii conversion}
- {$I \tinc\stoupper.inc} {map string to upper case}
-
-
- procedure gettok; forward;
- procedure pblock; forward;
- procedure pstatement; forward;
- procedure punit; forward;
- procedure pvar; forward;
- function plvalue: string255; forward;
- function pexpr: string255; forward;
- procedure pident; forward;
- procedure exit_nested; forward;
- procedure enter_nested; forward;
- procedure discard_nested; forward;
-
- (********************************************************************)
-
- {$I tpcsym.inc} {symbol table handler}
- {$I tpcmisc.inc} {misc functions}
- {$I tpcscan.inc} {scanner; lexical analysis}
- {$I tpcexpr.inc} {expression parser and translator}
- {$I tpcstmt.inc} {statement parser and translator}
- {$I tpcdecl.inc} {declaration parser and translator}
- {$I tpcunit.inc} {program unit parser and translator}
-
-
- (********************************************************************)
- procedure init;
- {initializations before translation can begin}
-
- procedure enter(name: anystring; etype: symtypes);
- begin
- newsym(name, etype, ss_scalar, -1, 0, 0);
- end;
-
- begin
- spaces := '';
- nospace := false;
- ltok := '';
- tok := '';
- toktype := unknown;
- extradot := false;
- srclines[level] := 0;
- unitlevel := 0;
- globals := nil;
- locals := nil;
- curtype := s_void;
- cursuptype := ss_scalar;
- read_include := false;
- nestn := '00';
-
- newsym('argv', s_string, ss_array, -1, 0, 0);
- enter('argc', s_int);
- enter('con', s_file);
- enter('kbd', s_file);
- enter('lst', s_file);
- enter('output',s_file);
- enter('input', s_file);
- enter('aux', s_file);
- end;
-
-
- (********************************************************************)
- procedure usage(why: anystring);
- {print usage instructions and copyright}
- begin
- writeln('Copyright 1986, 1987 by Samuel H. Smith; All rights reserved.');
- writeln;
- writeln('Please refer all inquiries to:');
- writeln(' Samuel H. Smith The Tool Shop BBS');
- writeln(' 5119 N 11 Ave 332 (602) 279-2673');
- writeln(' Phoenix, AZ 85013');
- writeln;
- writeln('You may copy and distribute this program freely, provided that:');
- writeln(' 1) No fee is charged for such copying and distribution, and');
- writeln(' 2) It is distributed ONLY in its original, unmodified state.');
- writeln;
- writeln('If you like this program, and find it of use, then your contribution');
- writeln('will be appreciated. If you are using this product in a commercial');
- writeln('environment then the contribution is not voluntary.');
- writeln;
-
- write('Press enter: ');
- readln;
-
- writeln;
- writeln;
- writeln('Error: ',why);
- writeln;
- writeln(
- 'Usage: TPTC input_file [output_file] [-lower] [-mt] [-dump] [-include]');
- writeln;
- writeln('Where:');
- writeln(' input_file specifies the main source file, .PAS default');
- writeln(' output_file specifies the output file, .C default');
- writeln(' -lower map all identifiers to lower case');
- writeln(' -mt use Pascal/MT+ specific translations');
- writeln(' -dump Dump symbols');
- writeln(' -include output include files'' contents');
- writeln;
- writeln('Example:');
- writeln(' tptc fmap -lower -dump');
- writeln;
- halt;
- end;
-
-
-
- (* main program *)
-
- var
- inname: anystring;
- outname: anystring;
- par: anystring;
- i: integer;
-
- begin
- assign(con,'');
- rewrite(con);
-
- writeln(con);
- writeln(con,version1);
- writeln(con,' ',version2);
- writeln(con);
-
- (* get command line options, if any *)
-
- outname := '';
- inname := '';
- map_lower := false;
- mt_plus := false;
- dumpsymbols := false;
- includeinclude := false;
-
- for i := 1 to paramcount do
- begin
- par := paramstr(i);
-
- if par[1] = '-' then
- begin
- if par = '-lower' then
- map_lower := true
- else
- if par = '-mt' then
- mt_plus := true
- else
- if par = '-dump' then
- dumpsymbols := true
- else
- if par = '-include' then
- includeinclude := true
- else
- usage('invalid option');
- end
- else
-
- if inname = '' then
- inname := par
- else
-
- if outname = '' then
- outname := par
- else
- usage('duplicate input/output name');
- end;
-
- if inname = '' then
- usage('missing input name');
-
- if outname = '' then
- outname := inname;
-
- if pos('.',inname) = 0 then
- inname := inname + '.pas';
-
- if inname = outname then
- usage('duplicate input/output name');
-
- assign(infd,inname);
- srcfiles[1] := inname;
- {$I-} reset(infd); {$I+}
- if ioresult <> 0 then
- begin
- writeln(con,'Can''t open input file: ',inname);
- halt;
- end;
-
- if pos('.',outname) = 0 then
- outname := outname + '.c';
-
- level := 1;
- assign(ofd[level],outname);
- {$I-}
- rewrite(ofd[level]);
- {$I+}
- if ioresult <> 0 then
- begin
- writeln(con,'Can''t open output file: ',outname);
- halt;
- end;
-
-
- (* do initializations *)
- init;
-
- (* process the source file(s) *)
- pprogram;
- purgetable(globals);
-
- writeln(con,srclines[level]' lines ');
- close(ofd[level]);
- end.
-
-