This documentation is also part of the zip file progen.zip
which also contains the program. The program runs under Win95 and above.
The version number 0.5 says nearly everything about the program status.
PROGEN is free for non commercial and private use. If you want to use it
for commercial applications, if you need any help, if you have an example
to publish or if you like to tell me your opinion about it please send
me a mail.
PROGEN is a source code generator which can produce any kind of source code. I use it mainly to produce COBOL files and have therefor implemented a parser for COBOL data records. The input files can be easily build from existing applications. When you take an existing C-file as input file, the output is a 1:1 copy of the input file. Sure this doesn't make much sense, but with the powerful control language, the expression calculator, tab handling and the possibility of using variables and tables you can easily build useful templates.
The input file (default extension is ".src") consists of two types of lines. A control statement always starts in column one. If column one is empty, the line is interpreted as a source code line which is passed to the output file (default extension is ".gen"). Before an output line is written, used variables where substituted by their values, expressions where calculated and tabs where expanded. To overpass the disadvantage that source lines can't be defined in column one, you can use the tab 1 ("<1>") to generate an output line beginning in col one.
Introduction to the following parts of the input file:
. | Symbol for control line. Next word is keyword. Allows keyword indent for better reading |
* | Comment line which is not analyzed |
$ | Define and compute a variable |
/ | Continuation, the current line is added to the line before |
ignoreCtrlLine | The following lines are data lines, even if they begin in column one until ... |
end-ignoreCtrlLine | ... the following lines are again interpreted as control lines if they begin in column one |
assignformat | Associate a format string to a variable |
table | Create a table (indexed variable). A table stores variables organized in cols and rows (like SQL-table) |
end-table | End of table definition |
addfields | Add fields (cols) to an existing table |
saveas | Save generate file as ... |
open | Opens a new input file |
createas | Create generate file as ..., but only if it does not exist |
copyascobolcomment | Copy file as a cobol comment |
close | Save generate file and close it |
command | Exec an os command |
loop | Start a loop |
exit-loop | Quit a loop before normal termination |
end-loop | End of loop |
evaluate | Start evaluate (like switch in "C") |
when | When statement (like case in "C") |
end-evaluate | End of evaluate |
if | Evaluate a condition |
else | Else part of a condition |
else if | Combination of "else" and "if" in one line |
end-if | End of a condition |
define | Define a procedure |
end-define | End of procedure definition |
function | Define a function |
end-function | End of function definition |
dialog | Create a dialog box |
execDialog | calls a created dialog box |
message | Show a message |
exec | Call a procedure |
scan | Invoke a scanner |
end-scan | End of lines to be scanned |
calc | Execute an expression |
Syntax:
. <keyword>
Example:
. if $a > 10
a is greater then 10
. if $a > 20
a is greater then 20
. end-if
. end-if
Example:
* This is a comment line which is not analyzed
Syntax:
$ <var> := <expression>
Examples:
$min := min($val1, $val2, $val3 * $val4)
$file := "datei"
$age := 20
Syntax:
/ <expression>
Examples:
if $Name = "Sebastian"
/ or $Name = "Peter"
/ or $Name = "George"
/ or $Name = "Marion"
$Name is member of the fun club.
end-if
Syntax:
/ <expression>
Examples:
if $Name = "Sebastian"
/ or $Name = "Peter"
/ or $Name = "George"
/ or $Name = "Marion"
$Name is member of the fun club.
end-if
Example:
assignformat $varString "x(35)" *> It's an alphanumeric
var with size 35 Bytes
assignformat $varNum1 "---.---.--9,99" *> It's
a numeric var with leading sign. Leading zeros are ignored. "-23.459,00"
"12,99"
assignformat $varNum2 "zzz.zz9,99-" *> It's a
numeric var with sign at end. Leading zeros are ignored. "23.459,00-" "12,99"
Syntax:
table <tableName>
<tableDecriptor>
{<tableData>}
end-table
Example:
in the following example a table is defined with to cols named "name"
(type alpha 20 bytes) and "age" (type numeric 3 bytes) . The name of the
table is "person".
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
see also loop
Syntax:
end-table
<tabId>
Syntax:
addfields <tableId> <tableDecriptor>
Example:
in the following example adds a new col "birthyear" to the existing
table "person", identified by its col name "name". Afterwards the value
of each row is computed by the simplified formula birthyear = curentYear
- age.
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
addfields "$name" "birthyear:n:4;"
loop tabUsed($name)
. $birthyear := $sysyear - $age
end-loop
Syntax:
saveas <expression>
saveas "clipboard"
Saves generated data to windows clipboard
Examples:
saveas "test.gen"
saveas concat(substr($main, 1, 3), "e.gen")
Syntax:
open <expression>
open "clipboard"
Opens windows clipboard as input file
Examples:
open "input.src"
open concat(substr($main, 1, 3), "e.gen")
Syntax:
createas <expression>
Example:
createas $outfile
Syntax:
copyascobolcomment <expression>[":" <fromLine> ":" <toLine>
]
Example:
copyascobolcomment "orig.gra":1:20
Syntax:
close
Example:
The following examples runs in an endless loop. The user is asked for
a source file to be processed. When the process is over the result is stored,
when the "close" command is handled.
loop 100000000
*> Runs a loop so often, that it is nearly an endless loop
open input("Please enter name of sourcefile:")
close
end-loop
Syntax:
command <expression>
Example:
command "gcc -c $main.c -o $main"
Syntax:
loop <fromNum>:<toNum>
loop <toNum>
loop until <condition>
Example:
in the following example a table is defined
with to cols named "name" (type alpha 20 bytes) and "age" (type numeric
3 bytes) . The name of the table is "person". When a table is defined a
variable named "no"<tableName> was created, which stores the number
of rows of the table.
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
loop tabUsed($age) *> Loop over
every table row from the table ("person") in which $age is defined
. if $age < 2
<1>$name is $age year old
. else
<1>$name is $age years old
. end-if
end-loop
Syntax:
exit-loop
Example:
loop $noPerson
. if $age = 0
<1>Illegal entry in person table: $name
. exit-loop
. end-if
. if $age < 2
<1>$name is $age year old
. else
<1>$name is $age years old
. end-if
end-loop
Syntax:
end-loop
Syntax:
evaluate
Example:
loop tabUsed(person)
. evaluate
. when $age < 1
<1>$name is less then a year old
. when $age = 1
<1>$name is 1 year old
. when other
<1>$name is $age years old
. end-evaluate
end-loop
Syntax:
when <condition>
when other
Example:
see evaluate
Syntax:
end-evaluate
Syntax:
if <condition>
Example:
if $age < 18 or $age > 65
Reduced entrance price for
$person
else
Normal entrance price for $person
end-if
Syntax:
else if <condition>
Example:
if $age < 18
Reduced entrance price for
$person
else if $age < 65
Normal entrance price for $person
else
Reduced entrance price for
$person
end-if end-if
Syntax:
else
Example:
see if
Syntax:
end-if {end-if}
Example:
see "else if"
Syntax:
define <expression>
Example:
the following complex example defines a procedure which calls a second
procedure when a variable is assumed to be part of an index of a COBOL
isam file. The assumption is, that the first real vars of a data record
are index vars, if they have the same or a lower level as the first real
var.
define "keyFilter"
$lev := 0
loop $noDataRecord
* if the current level is greater then the one
of the first real var do nothing more
. if $lev > 0 and $lev < 99 and $datVarLevel < $lev
. $lev := 99
. end-if
* no Group, Constant
or Boolean
. if $datVarType > 0 and $datVarType < 78 and $lev <
99
* if it is the first real var, store
the var level
. if $lev = 0
. $lev := $datVarLevel
. end-if
exec $filterProc
*> A second Procedure was called, whose name is stored in $filterProc
. end-if
end-loop
end-define
Syntax:
end-define
Syntax:
function <expression>
Example:
see dialog
Syntax:
end-function
Example:
table "person"
"name:x:35;age:n:3;"
*> Define a table with 2 columns: name and age
end-table
*
function "okPressed"
*> Add data from dialog box to table "person" and show message
$row := addTableLine("person", $diaPerson, $diaAge)
message(concat("Person
ï", $diaPerson, "ï, age ï", $diaAge "ï added as number
ï", $row, "ï"))
end-function
*
dialog "Person"
textentry("Name: ", "x(35)", $diaPerson)
textentry("Age : ", "z(03)", $diaAge)
pushbutton("OK":{okple:
see dialog example
Syntax:
message(<expression>)
Example:
see dialog example
Syntax:
calc <expression>
calc <condition>
Example:
calc
Syntax:
exec <expression>
Example:
exec "keyFilter"
Syntax:
scan <scanner>
Example:
scan cbldata
01 adr010-satz.
05 adr010-ob.
10 adr010-betrnr pic 9(2) comp.
10 adr010-sa
pic 9(2) comp.
88 adr010-debitor value 1.
88 adr010-kreditor value 2.
10 adr010-ktonr pic 9(10) comp.
10 adr010-lnr pic
9(8) comp. *> lfd.Nummer
05 adr010-alpha.
10 adr010-adr1 pic x(35).
*> 1.adresszeile
10 adr010-titel pic x(15).
10 adr010-vname pic x(20).
10 adr010-adr2 pic x(35).
*> 2.adresszeile
10 adr010-adr3 pic x(35).
*> 3.adresszeile
10 adr010-adr4 pic x(35).
*> 4.adresszeile
10 adr010-strasse pic x(35).
10 adr010-postort pic x(35).
10 adr010-plz pic x(07).
10 adr010-ort pic x(26).
10 adr010-brief-anr pic x(35).
10 adr010-brief-name pic x(35).
10 adr010-listen-name pic x(35).
end-scan
after scanning of the cobol data structure, the following vars are available for every data field:
$datOffset *> Offset within
structure
$datNoByte *> No of bytes
$datVarName *> Name
$datValueNum *> If a numerical value
is assigned, the value
$datValueLiteral *> If a literal value is assigned, the value
$datVarLevel *> The Level ( 01 02 ..
78 88 )
$datVarRedefines *> If redefines 1
$datVarString *> The format string
$datVarFString *> Another format string
$datOccLev *> Level of
occurrence
$datOccValConst *> Constant No of poss. occurrences
$datOccValNum *> No of poss. occurrences
$datVarType *> Datatyp: 0=group,
1=alpha, 2=comp, 3=display
$datVarDec *> If numeric
no of numbers after decimal point
$datVarSign *> "-" " " or "+"
$datVarComment *> Associated comment to var
Syntax:
end-scan
and | Logical and |
or | Logical or |
not | Negotiation |
> | Greater |
< | Less |
>= | Greater or equal |
<= | Less or equal |
= | Equal |
<> | Different |
; | Handle more then one expression at a time, return the result of the last expression |
+ | Numerical addition or string concatenation |
- | Numerical subtract |
/ | Division |
* | Multiplication |
:= | Set value of a variable, return the value |
( | Bracket handling |
other | Return numeric value "1" which is equivalent to true |
$ | Create a var name at run time |
apply | Apply a parameter string to a function |
average | Compute the average of a list of numbers |
min | Compute the min of a list of numbers |
max | Compute the max of a list of numbers |
abs | Return the abs value of a num |
mod | Modulo function returns the remainder |
fix | Fix function returns the divisor |
env | Get value of environment variable |
length | Return length of string expression |
firstup | Convert first char to upper case |
toupper | Convert to upper case |
tolower | Convert to lower case |
cbl2c | Convert COBOL var to C var with replacing "_" by "-" |
dos2win | Convert chars to windows character set, especially german "Umlaute" |
dos2html | Converts chars to html syntax, especially german "Umlaute" |
substr | Get a substring |
concat | Concatenate two or more strings |
quote | Wrap a string in " |
dollar | Put an "$" before the string |
definedIn | Look if a value is part of a table |
definedInIgnore | Look if a value is part of a table, ignoring case |
addTableLine | Adds a line to a table, returning the row (size of table) |
input | Query user for a value of a variable and set the value |
tabUsed | Return number of rows from a table |
tabHandle | Return table handle |
Syntax:
<expression> and <expression>
Example:
if $a > 10 and $b < 20
Syntax:
<expression> or <expression>
Example:
if $a > 10 or $b < 20
Syntax:
not <expression>
Example:
if not $Name = "Mayer"
see also <>
Syntax:
<expression> > <expression>
Example:
if $city1 > $city2
Syntax:
<expression> <expression>
Example:
if $a < 10
Syntax:
if <expression> <> <expression>
Example:
if tolower($Name) <> "sebastian"
Syntax:
<expression>; <expression>{; <expression>}
Examples:
$sum1 := 12 + 4 ; $sum2 := 12 + 5
Syntax:
<expression> + <expression>
Examples:
$sum := 12 + 4
$address := $name + ", " + $street + ", " + $city
see also concat
Syntax:
<expression> - <expression>
Syntax:
<var> := <expression>
Example:
$sum := 12 + 4
$address := $name + ", " + $street + ", " + $city
if ($sum := 12 +$last) > 20
. $sum := 20
end-if
Syntax:
( <expression> )
Example:
$sum := (4 + 5) * 3
Syntax:
apply( <parameterExpression> , <functionExpression>
)
Example:
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
$line := $age[1] *> Get
age of first person
loop 2:tabUsed($age)
*> Loop over every table row, beginning with row = 2, from the table
("person") in which $age is defined
$line := concat($line, ", ", $age)
*> Append for every more person ", <age>"
end-loop
* The first appliance is equivalent to "average(38, 34, 39,
1)"
Average age is {apply($line, "average")}
Minimum age is {apply($line, "min")}
Maximum age is {apply($line, "max")}
Syntax:
average( <expression> {, <expression> }
)
Example:
see apply
Syntax:
max( <expression> {, <expression> }
)
Example:
see apply
Syntax:
min( <expression> {, <expression> }
)
Example:
see apply
Syntax:
abs( <expression> )
Example:
abs(-5) = 5
Syntax:
mod( <expression>, <expression>)
Example:
if 1 = mod($yearMonth, 12) + 1 *> If month is
january
Syntax:
fix( <expression>, <expression>)
Example:
fix($sallary / 1000)
*> Integer part of $sallary in thousand
Syntax:
env (<expression>)
*> Returns the value of environment variable "path"
Example:
env ("path")
*> Returns the value of environment variable "path"
Syntax:
length (<expression>)
Example:
length(env ("path"))
*> Returns the length of the value of environment variable "path"
Syntax:
firstup(<expression>)
Example:
if firstup($Name) = "M"
Syntax:
toupper(<expression>)
Example:
toupper($Name)
Syntax:
tolower(<expression>)
Syntax:
h2c(<expression>)
Example:
cbl2c("illegal-c-var") = "illegal_c_var"
Syntax:
dos2win( <expression>)
Syntax:
dos2html( <expression>)
Example:
dos2html("München & Köln") = "München &
Köln"
Syntax:
substr(<string>, <splitString>)
substr(<string>, <splitString>,<occurrence>)
substr(<string>, <offset>)
substr(<string>, <offset>, <length>)
Example:
substr("part1_part2_part3", "_") = "part1"
substr("part1_part2_part3", "_", 2) = "part2"
substr("part1_part2_part3", "_", -1) = "part3"
substr("part1_part2_part3", 7) = "part2_part3"
substr("part1_part2_part3", 7, 5) = "part2"
Syntax:
concat( <expression> {, <expression> })
Example:
concat($name, ", ", $city)
see also +
Syntax:
quote(<expression>)
Example:
quote(4) = "4"
Syntax:
dollar(<expression>)
Example:
dollar("name") = "$name"
Syntax:
definedin(<colVar>, <valueExpression>)
Example:
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
definedin($name, Annette) = 2
definedinIgnore($name, annette) = 2
Syntax:
addTableLine(<tableId>, <col1>[, <col2>[, <col3>[, <col4>
[, .... ]]]])
Example:
function "okPressed"
$row := addTableLine("person", $diaPerson, $diaAge)
message(concat("Person ", quote($diaPerson), ", age
", quote($diaAge) ", added as number ", quote($row))
end-function
Syntax:
tabUsed(<tableId>)
tabused <condition>
Example:
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
loop tabUsed($age)
Name: $name, age: $age
end-loop
Syntax:
tabhandle(<tabId>)
Example:
table "person"
"name:x:20;age:n:3;"
"Sebastian Mayer", 38
"Annette Pfeufer", 34
"Gerhard Bumann", 39
"Anika Heindl", 1
end-table
display "this is table no: " {tabHandle($name)}
Things COBOL site is owned by Sebastian Mayer
Previous Site | Random Site | List Sites | Next Site