/ Check-in [ed0ebc46]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change mkopcodeh.awk into tool/mkopcodeh.tcl.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-awk
Files: files | file ages | folders
SHA1: ed0ebc460b54939862e3bddee2bb9bcb9f69c747
User & Date: drh 2015-10-07 02:52:09
Context
2015-10-07
12:11
Convert the mkopcodec.awk script into tool/mkopcodec.tcl. check-in: 1506cb33 user: drh tags: omit-awk
02:52
Change mkopcodeh.awk into tool/mkopcodeh.tcl. check-in: ed0ebc46 user: drh tags: omit-awk
00:35
Remove three obsolete and unused files from tool/ check-in: 0abd6529 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   898    898   		 libsqlite3.la $(LIBTCL)
   899    899   
   900    900   # Rules to build opcodes.c and opcodes.h
   901    901   #
   902    902   opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
   903    903   	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
   904    904   
   905         -opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
   906         -	cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
          905  +opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
          906  +	cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
   907    907   
   908    908   # Rules to build parse.c and parse.h - the outputs of lemon.
   909    909   #
   910    910   parse.h:	parse.c
   911    911   
   912    912   parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
   913    913   	cp $(TOP)/src/parse.y .

Changes to Makefile.msc.

  1571   1571   	$(LTLINK) $(SQLITE3C) /link $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1572   1572   
  1573   1573   # Rules to build opcodes.c and opcodes.h
  1574   1574   #
  1575   1575   opcodes.c:	opcodes.h $(TOP)\mkopcodec.awk
  1576   1576   	$(NAWK) -f $(TOP)\mkopcodec.awk opcodes.h > opcodes.c
  1577   1577   
  1578         -opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\mkopcodeh.awk
  1579         -	type parse.h $(TOP)\src\vdbe.c | $(NAWK) -f $(TOP)\mkopcodeh.awk > opcodes.h
         1578  +opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
         1579  +	type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.awk > opcodes.h
  1580   1580   
  1581   1581   # Rules to build parse.c and parse.h - the outputs of lemon.
  1582   1582   #
  1583   1583   parse.h:	parse.c
  1584   1584   
  1585   1585   parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
  1586   1586   	del /Q parse.y parse.h parse.h.temp 2>NUL

Changes to main.mk.

   578    578   
   579    579   
   580    580   # Rules to build opcodes.c and opcodes.h
   581    581   #
   582    582   opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
   583    583   	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
   584    584   
   585         -opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
          585  +opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
   586    586   	cat parse.h $(TOP)/src/vdbe.c | \
   587         -		$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
          587  +		tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
   588    588   
   589    589   # Rules to build parse.c and parse.h - the outputs of lemon.
   590    590   #
   591    591   parse.h:	parse.c
   592    592   
   593    593   parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
   594    594   	cp $(TOP)/src/parse.y .

Deleted mkopcodeh.awk.

     1         -#!/usr/bin/awk -f
     2         -#
     3         -# Generate the file opcodes.h.
     4         -#
     5         -# This AWK script scans a concatenation of the parse.h output file from the
     6         -# parser and the vdbe.c source file in order to generate the opcodes numbers
     7         -# for all opcodes.  
     8         -#
     9         -# The lines of the vdbe.c that we are interested in are of the form:
    10         -#
    11         -#       case OP_aaaa:      /* same as TK_bbbbb */
    12         -#
    13         -# The TK_ comment is optional.  If it is present, then the value assigned to
    14         -# the OP_ is the same as the TK_ value.  If missing, the OP_ value is assigned
    15         -# a small integer that is different from every other OP_ value.
    16         -#
    17         -# We go to the trouble of making some OP_ values the same as TK_ values
    18         -# as an optimization.  During parsing, things like expression operators
    19         -# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth.  Later
    20         -# during code generation, we need to generate corresponding opcodes like
    21         -# OP_Add and OP_Divide.  By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
    22         -# code to translate from one to the other is avoided.  This makes the
    23         -# code generator run (infinitesimally) faster and more importantly it makes
    24         -# the library footprint smaller.
    25         -#
    26         -# This script also scans for lines of the form:
    27         -#
    28         -#       case OP_aaaa:       /* jump, in1, in2, in3, out2-prerelease, out3 */
    29         -#
    30         -# When such comments are found on an opcode, it means that certain
    31         -# properties apply to that opcode.  Set corresponding flags using the
    32         -# OPFLG_INITIALIZER macro.
    33         -#
    34         -
    35         -
    36         -# Remember the TK_ values from the parse.h file
    37         -/^#define TK_/ {
    38         -  tk[$2] = 0+$3    # tk[x] holds the numeric value for TK symbol X
    39         -}
    40         -
    41         -# Find "/* Opcode: " lines in the vdbe.c file.  Each one introduces
    42         -# a new opcode.  Remember which parameters are used.
    43         -/^.. Opcode: / {
    44         -  currentOp = "OP_" $3
    45         -  m = 0
    46         -  for(i=4; i<=NF; i++){
    47         -    x = $i
    48         -    if( x=="P1" ) m += 1
    49         -    if( x=="P2" ) m += 2
    50         -    if( x=="P3" ) m += 4
    51         -    if( x=="P4" ) m += 8
    52         -    if( x=="P5" ) m += 16
    53         -  }
    54         -  paramused[currentOp] = m
    55         -}
    56         -
    57         -# Find "** Synopsis: " lines that follow Opcode:
    58         -/^.. Synopsis: / {
    59         -  if( currentOp ){
    60         -    x = $3
    61         -    for(i=4; i<=NF; i++){
    62         -      x = x " " $i
    63         -    }
    64         -    synopsis[currentOp] = x
    65         -  }
    66         -}
    67         -
    68         -# Scan for "case OP_aaaa:" lines in the vdbe.c file
    69         -/^case OP_/ {
    70         -  name = $2
    71         -  sub(/:/,"",name)
    72         -  sub("\r","",name)
    73         -  op[name] = -1       # op[x] holds the numeric value for OP symbol x
    74         -  jump[name] = 0
    75         -  in1[name] = 0
    76         -  in2[name] = 0
    77         -  in3[name] = 0
    78         -  out2[name] = 0
    79         -  out3[name] = 0
    80         -  for(i=3; i<NF; i++){
    81         -    if($i=="same" && $(i+1)=="as"){
    82         -      sym = $(i+2)
    83         -      sub(/,/,"",sym)
    84         -      val = tk[sym]
    85         -      op[name] = val
    86         -      used[val] = 1
    87         -      sameas[val] = sym
    88         -      def[val] = name
    89         -    }
    90         -    x = $i
    91         -    sub(",","",x)
    92         -    if(x=="jump"){
    93         -      jump[name] = 1
    94         -    }else if(x=="in1"){
    95         -      in1[name] = 1
    96         -    }else if(x=="in2"){
    97         -      in2[name] = 1
    98         -    }else if(x=="in3"){
    99         -      in3[name] = 1
   100         -    }else if(x=="out2"){
   101         -      out2[name] = 1
   102         -    }else if(x=="out3"){
   103         -      out3[name] = 1
   104         -    }
   105         -  }
   106         -  order[n_op++] = name;
   107         -}
   108         -
   109         -# Assign numbers to all opcodes and output the result.
   110         -END {
   111         -  cnt = 0
   112         -  max = 0
   113         -  print "/* Automatically generated.  Do not edit */"
   114         -  print "/* See the mkopcodeh.awk script for details */"
   115         -  op["OP_Noop"] = -1;
   116         -  order[n_op++] = "OP_Noop";
   117         -  op["OP_Explain"] = -1;
   118         -  order[n_op++] = "OP_Explain";
   119         -
   120         -  # Assign small values to opcodes that are processed by resolveP2Values()
   121         -  # to make code generation for the switch() statement smaller and faster.
   122         -  for(i=0; i<n_op; i++){
   123         -    name = order[i];
   124         -    if( op[name]>=0 ) continue;
   125         -    if( name=="OP_Transaction"   \
   126         -     || name=="OP_AutoCommit"    \
   127         -     || name=="OP_Savepoint"     \
   128         -     || name=="OP_Checkpoint"    \
   129         -     || name=="OP_Vacuum"        \
   130         -     || name=="OP_JournalMode"   \
   131         -     || name=="OP_VUpdate"       \
   132         -     || name=="OP_VFilter"       \
   133         -     || name=="OP_Next"          \
   134         -     || name=="OP_NextIfOpen"    \
   135         -     || name=="OP_SorterNext"    \
   136         -     || name=="OP_Prev"          \
   137         -     || name=="OP_PrevIfOpen"    \
   138         -    ){
   139         -      cnt++
   140         -      while( used[cnt] ) cnt++
   141         -      op[name] = cnt
   142         -      used[cnt] = 1
   143         -      def[cnt] = name
   144         -    }
   145         -  }
   146         -
   147         -  # Generate the numeric values for opcodes
   148         -  for(i=0; i<n_op; i++){
   149         -    name = order[i];
   150         -    if( op[name]<0 ){
   151         -      cnt++
   152         -      while( used[cnt] ) cnt++
   153         -      op[name] = cnt
   154         -      used[cnt] = 1
   155         -      def[cnt] = name
   156         -    }
   157         -  }
   158         -  max = cnt
   159         -  for(i=1; i<=max; i++){
   160         -    if( !used[i] ){
   161         -      def[i] = "OP_NotUsed_" i 
   162         -    }
   163         -    printf "#define %-16s %3d", def[i], i
   164         -    com = ""
   165         -    if( sameas[i] ){
   166         -      com = "same as " sameas[i]
   167         -    }
   168         -    x = synopsis[def[i]]
   169         -    if( x ){
   170         -      if( com=="" ){
   171         -        com = "synopsis: " x
   172         -      } else {
   173         -        com = com ", synopsis: " x
   174         -      }
   175         -    }
   176         -    if( com!="" ){
   177         -      printf " /* %-42s */", com
   178         -    }
   179         -    printf "\n"
   180         -  }
   181         -
   182         -  # Generate the bitvectors:
   183         -  #
   184         -  #  bit 0:     jump
   185         -  #  bit 1:     pushes a result onto stack
   186         -  #  bit 2:     output to p1.  release p1 before opcode runs
   187         -  #
   188         -  for(i=0; i<=max; i++){
   189         -    name = def[i]
   190         -    a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
   191         -    if( jump[name] ) a0 = 1;
   192         -    if( in1[name] ) a2 = 2;
   193         -    if( in2[name] ) a3 = 4;
   194         -    if( in3[name] ) a4 = 8;
   195         -    if( out2[name] ) a5 = 16;
   196         -    if( out3[name] ) a6 = 32;
   197         -    bv[i] = a0+a1+a2+a3+a4+a5+a6;
   198         -  }
   199         -  print "\n"
   200         -  print "/* Properties such as \"out2\" or \"jump\" that are specified in"
   201         -  print "** comments following the \"case\" for each opcode in the vdbe.c"
   202         -  print "** are encoded into bitvectors as follows:"
   203         -  print "*/"
   204         -  print "#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */"
   205         -  print "#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */"
   206         -  print "#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */"
   207         -  print "#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */"
   208         -  print "#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */"
   209         -  print "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
   210         -  print "#define OPFLG_INITIALIZER {\\"
   211         -  for(i=0; i<=max; i++){
   212         -    if( i%8==0 ) printf("/* %3d */",i)
   213         -    printf " 0x%02x,", bv[i]
   214         -    if( i%8==7 ) printf("\\\n");
   215         -  }
   216         -  print "}"
   217         -  if( 0 ){
   218         -    print "\n/* Bitmask to indicate which fields (P1..P5) of each opcode are"
   219         -    print "** actually used.\n*/"
   220         -    print "#define OP_PARAM_USED_INITIALIZER {\\"
   221         -    for(i=0; i<=max; i++){
   222         -      if( i%8==0 ) printf("/* %3d */",i)
   223         -      printf " 0x%02x,", paramused[def[i]]
   224         -      if( i%8==7 ) printf("\\\n");
   225         -    }
   226         -    print "}"
   227         -  }
   228         -}

Added tool/mkopcodeh.tcl.

            1  +#!/usr/bin/tclsh
            2  +#
            3  +# Generate the file opcodes.h.
            4  +#
            5  +# This TCL script scans a concatenation of the parse.h output file from the
            6  +# parser and the vdbe.c source file in order to generate the opcodes numbers
            7  +# for all opcodes.  
            8  +#
            9  +# The lines of the vdbe.c that we are interested in are of the form:
           10  +#
           11  +#       case OP_aaaa:      /* same as TK_bbbbb */
           12  +#
           13  +# The TK_ comment is optional.  If it is present, then the value assigned to
           14  +# the OP_ is the same as the TK_ value.  If missing, the OP_ value is assigned
           15  +# a small integer that is different from every other OP_ value.
           16  +#
           17  +# We go to the trouble of making some OP_ values the same as TK_ values
           18  +# as an optimization.  During parsing, things like expression operators
           19  +# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth.  Later
           20  +# during code generation, we need to generate corresponding opcodes like
           21  +# OP_Add and OP_Divide.  By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
           22  +# code to translate from one to the other is avoided.  This makes the
           23  +# code generator run (infinitesimally) faster and more importantly it makes
           24  +# the library footprint smaller.
           25  +#
           26  +# This script also scans for lines of the form:
           27  +#
           28  +#       case OP_aaaa:       /* jump, in1, in2, in3, out2-prerelease, out3 */
           29  +#
           30  +# When such comments are found on an opcode, it means that certain
           31  +# properties apply to that opcode.  Set corresponding flags using the
           32  +# OPFLG_INITIALIZER macro.
           33  +#
           34  +
           35  +set in stdin
           36  +set currentOp {}
           37  +set nOp 0
           38  +while {![eof $in]} {
           39  +  set line [gets $in]
           40  +
           41  +  # Remember the TK_ values from the parse.h file. 
           42  +  # NB:  The "TK_" prefix stands for "ToKen", not the graphical Tk toolkit
           43  +  # commonly associated with TCL.
           44  +  #
           45  +  if {[regexp {^#define TK_} $line]} {
           46  +    set tk([lindex $line 1]) [lindex $line 2]
           47  +    continue
           48  +  }
           49  +
           50  +  # Find "/* Opcode: " lines in the vdbe.c file.  Each one introduces
           51  +  # a new opcode.  Remember which parameters are used.
           52  +  #
           53  +  if {[regexp {^.. Opcode: } $line]} {
           54  +    set currentOp OP_[lindex $line 2]
           55  +    set m 0
           56  +    foreach term $line {
           57  +      switch $term {
           58  +        P1 {incr m 1}
           59  +        P2 {incr m 2}
           60  +        P3 {incr m 4}
           61  +        P4 {incr m 8}
           62  +        P5 {incr m 16}
           63  +      }
           64  +    }
           65  +    set paramused($currentOp) $m
           66  +  }
           67  +
           68  +  # Find "** Synopsis: " lines that follow Opcode:
           69  +  #
           70  +  if {[regexp {^.. Synopsis: (.*)} $line all x] && $currentOp!=""} {
           71  +    set synopsis($currentOp) [string trim $x]
           72  +  }
           73  +
           74  +  # Scan for "case OP_aaaa:" lines in the vdbe.c file
           75  +  #
           76  +  if {[regexp {^case OP_} $line]} {
           77  +    set line [split $line]
           78  +    set name [string trim [lindex $line 1] :]
           79  +    set op($name) -1
           80  +    set jump($name) 0
           81  +    set in1($name) 0
           82  +    set in2($name) 0
           83  +    set in3($name) 0
           84  +    set out1($name) 0
           85  +    set out2($name) 0
           86  +    for {set i 3} {$i<[llength $line]-1} {incr i} {
           87  +       switch [string trim [lindex $line $i] ,] {
           88  +         same {
           89  +           incr i
           90  +           if {[lindex $line $i]=="as"} {
           91  +             incr i
           92  +             set sym [string trim [lindex $line $i] ,]
           93  +             set val $tk($sym)
           94  +             set op($name) $val
           95  +             set used($val) 1
           96  +             set sameas($val) $sym
           97  +             set def($val) $name
           98  +           }
           99  +         }
          100  +         jump {set jump($name) 1}
          101  +         in1  {set in1($name) 1}
          102  +         in2  {set in2($name) 1}
          103  +         in3  {set in3($name) 1}
          104  +         out2 {set out2($name) 1}
          105  +         out3 {set out3($name) 1}
          106  +       }
          107  +    }
          108  +    set order($nOp) $name
          109  +    incr nOp
          110  +  }
          111  +}
          112  +
          113  +# Assign numbers to all opcodes and output the result.
          114  +#
          115  +set cnt 0
          116  +set max 0
          117  +puts "/* Automatically generated.  Do not edit */"
          118  +puts "/* See the tool/mkopcodeh.tcl script for details */"
          119  +set op(OP_Noop) -1
          120  +set order($nOp) OP_Noop
          121  +incr nOp
          122  +set op(OP_Explain) -1
          123  +set order($nOp) OP_Explain
          124  +incr nOp
          125  +
          126  +# The following are the opcodes that are processed by resolveP2Values()
          127  +#
          128  +set rp2v_ops {
          129  +  OP_Transaction
          130  +  OP_AutoCommit
          131  +  OP_Savepoint
          132  +  OP_Checkpoint
          133  +  OP_Vacuum
          134  +  OP_JournalMode
          135  +  OP_VUpdate
          136  +  OP_VFilter
          137  +  OP_Next
          138  +  OP_NextIfOpen
          139  +  OP_SorterNext
          140  +  OP_Prev
          141  +  OP_PrevIfOpen
          142  +}
          143  +
          144  +# Assign small values to opcodes that are processed by resolveP2Values()
          145  +# to make code generation for the switch() statement smaller and faster.
          146  +#
          147  +set cnt 0
          148  +for {set i 0} {$i<$nOp} {incr i} {
          149  +  set name $order($i)
          150  +  if {[lsearch $rp2v_ops $name]>=0} {
          151  +    incr cnt
          152  +    while {[info exists used($cnt)]} {incr cnt}
          153  +    set op($name) $cnt
          154  +    set used($cnt) 1
          155  +    set def($cnt) $name
          156  +  }
          157  +}
          158  +
          159  +# Generate the numeric values for remaining opcodes
          160  +#
          161  +for {set i 0} {$i<$nOp} {incr i} {
          162  +  set name $order($i)
          163  +  if {$op($name)<0} {
          164  +    incr cnt
          165  +    while {[info exists used($cnt)]} {incr cnt}
          166  +    set op($name) $cnt
          167  +    set used($cnt) 1
          168  +    set def($cnt) $name
          169  +  }
          170  +}
          171  +set max $cnt
          172  +for {set i 1} {$i<=$nOp} {incr i} {
          173  +  if {![info exists used($i)]} {
          174  +    set def($i) "OP_NotUsed_$i"
          175  +  }
          176  +  set name $def($i)
          177  +  puts -nonewline [format {#define %-16s %3d} $name $i]
          178  +  set com {}
          179  +  if {[info exists sameas($i)]} {
          180  +    set com "same as $sameas($i)"
          181  +  }
          182  +  if {[info exists synopsis($name)]} {
          183  +    set x $synopsis($name)
          184  +    if {$com==""} {
          185  +      set com "synopsis: $x"
          186  +    } else {
          187  +      append com ", synopsis: $x"
          188  +    }
          189  +  }
          190  +  if {$com!=""} {
          191  +    puts -nonewline [format " /* %-42s */" $com]
          192  +  }
          193  +  puts ""
          194  +}
          195  +
          196  +# Generate the bitvectors:
          197  +#
          198  +set bv(0) 0
          199  +for {set i 1} {$i<=$max} {incr i} {
          200  +  set name $def($i)
          201  +  if {[info exists jump($name)] && $jump($name)} {set a0 1}  {set a0 0}
          202  +  if {[info exists in1($name)] && $in1($name)}   {set a1 2}  {set a1 0}
          203  +  if {[info exists in2($name)] && $in2($name)}   {set a2 4}  {set a2 0}
          204  +  if {[info exists in3($name)] && $in3($name)}   {set a3 8}  {set a3 0}
          205  +  if {[info exists out2($name)] && $out2($name)} {set a4 16} {set a4 0}
          206  +  if {[info exists out3($name)] && $out3($name)} {set a5 32} {set a5 0}
          207  +  set bv($i) [expr {$a0+$a1+$a2+$a3+$a4+$a5}]
          208  +}
          209  +puts ""
          210  +puts "/* Properties such as \"out2\" or \"jump\" that are specified in"
          211  +puts "** comments following the \"case\" for each opcode in the vdbe.c"
          212  +puts "** are encoded into bitvectors as follows:"
          213  +puts "*/"
          214  +puts "#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */"
          215  +puts "#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */"
          216  +puts "#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */"
          217  +puts "#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */"
          218  +puts "#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */"
          219  +puts "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
          220  +puts "#define OPFLG_INITIALIZER \173\\"
          221  +for {set i 0} {$i<=$max} {incr i} {
          222  +  if {$i%8==0} {
          223  +    puts -nonewline [format "/* %3d */" $i]
          224  +  }
          225  +  puts -nonewline [format " 0x%02x," $bv($i)]
          226  +  if {$i%8==7} {
          227  +    puts "\\"
          228  +  }
          229  +}
          230  +puts "\175"