# # zob2java.pl # * # * Copyright (c) 1999-2000, Ted Nelson and Tuomas Lukka # * # * You may use and distribute under the terms of either the GNU Lesser # * General Public License, either version 2 of the license or, # * at your choice, any later version. Alternatively, you may use and # * distribute under the terms of the XPL. # * # * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of # * the licenses. # * # * This software is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY; without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README # * file for more details. # * # */ # /* # * Written by Tuomas Lukka # */ # # $out = $ARGV[0]; # $out =~ s/\.zob/\.java/ or die("Can't change filename for output file"); @ARGV == 2 or die "Two params: infile outfile"; $outfile = pop @ARGV; $infile = $ARGV[0]; $init .= <; $str =~ s/\bFONTMETRICS\s*\((.*?)\)/(ScalableFont.fmComp.getFontMetrics($1))/g; # ZObs must implement ZOb themselves. # # $str =~ s/\b(implements\s+)/$1 ZOb, / # or $str =~ s/(^[\w\s]*\bclass\b[\w\s]*)({)/$1 implements ZOb $2/ # or die "Can't implement ZOb - didn't find subst place"; $str =~ s/INITIALIZE/protected void init__zob() / and $doinit = "init__zob();"; # $structparre = 'STRUCTPARAMS;?(.*)END STRUCTPARAMS;?'; # $str =~ /$structparre/s; # $pars = $1; # FIXME: this parser takes into account braces in comments sub parse_balanced { my $str = $_[0]; my $rv = ""; my $level = 1; while ($level > 0) { die "Unbalanced braces" if $str eq ""; $str =~ /^([^{}]*)([{}])(.*)$/s; my($brace1, $brace2, $rest) = ($1, $2, $3); if ($brace2 eq "{") { ++$level; } if ($brace2 eq "}") { --$level; } $str = $rest; $rv = $rv . $brace1 . $brace2; } return ($rv, $str); } $str =~ /^(.*)STRUCTPARAMS *{(.*)$/s or die "No STRUCTPARAMS SECTION"; $beforestructpars = $1; ($pars, $afterstructpars) = parse_balanced($2); $pars =~ s/}$//s; @pars = map { /^\s*$/ ? () : $_ } split /\n\s*\n/, $pars; %gets = ( "float" => '__TARG__ = (Float.valueOf(__SRC__)).floatValue();', "double" => '__TARG__ = (Double.valueOf(__SRC__)).doubleValue();', "int" => '__TARG__ = Integer.parseInt(__SRC__); ', "boolean" => ' if(__SRC__.equals("true")) __TARG__=true; else if(__SRC__.equals("false")) __TARG__=false; else { /* XXX ??? */ } ', Font => ' { ZZCell c1 = c.s("d.1"); int size = 12; int style = Font.PLAIN; if(c1 != null) { size = Integer.parseInt(c1.getText()); ZZCell c2 = c1.s("d.1"); if(c2 != null) { String sty = c2.getText(); if(sty.equals("BOLD")) style = Font.BOLD; if(sty.equals("ITALIC")) style = Font.ITALIC; else { // error... } } } __TARG__ = new Font(s, style, size); } ', ScalableFont => ' { ZZCell c1 = c.s("d.1"); int size = 12; int style = Font.PLAIN; if(c1 != null) { size = Integer.parseInt(c1.getText()); ZZCell c2 = c1.s("d.1"); if(c2 != null) { String sty = c2.getText(); if(sty.equals("BOLD")) style = Font.BOLD; if(sty.equals("ITALIC")) style = Font.ITALIC; else { // error... } } } __TARG__ = new ScalableFont(s, style, size); } ', String => '__TARG__ = __SRC__; ', Color => '__TARG__ = Color.decode(__SRC__); ', ZZPath => ' __TARG__ = ZZPath.createFromStructure1(__SRCCELL__.s("d.2")); ', ZOb => ' { __TARG__ = ZZDefaultSpace.readZOb(__SRCCELL__); // __TARG__ = ZZDefaultSpace.newZOb(__SRC__); // __TARG__.readParams(__SRCCELL__.s("d.2")); } ', ZZCell => ' { __TARG__ = __SRCCELL__; } ', ); my $curbit = -1; # Remove comments for(@pars) { print "Par: $_"; # Move comment my $comment; if(m|^(\s*/\*.*\*/)(.*)|s) { $comment = $1; $_ = $2; } else { # die "No comment for structparam '$_' in $infile"; $comment = "/** UNDOCUMENTED. \n */"; } if(m|=(.*)|) { my $def = $1; print "DEFAULT: $def\n\n"; $comment =~ s|\*/|\n *

Default value:

$def
. \n */| or die "Comment '$comment' not substitutable" ; } else { print "NO DEFAULT: $_\n\n"; } # Add new tag: structparam $comment =~ s|\*/|\n * \@structparam 1 \n */ \n\n|g; $publicpars .= $comment; $publicpars .= " public ".$_; s|/\*.*?\*/||gs ; s/^\s*//s; s/\s*$//s; m|^(\w+\s*(?:\[\s*\]\s*)*)\s* (\w+)\s* ((?://.*\n)?)\s* |x or die "Invalid param: $_"; # push @types, $1; # push @names, $2; # push @ranges, $3; my($type, $name, $range) = ($1, $2, $3); $type =~ s/\s+//g; $type =~ /^(\w+)((?:\[\])?)$/ or die "Invalid type '$type'"; my $base = $1; my $array = ($2 eq "[]"); $get = $gets{$base} or die "No get for '$base'"; if($array) { $get =~ s/__TARG__/${name}\l[i]/g; $get =~ s/__SRC__/s/g; $get =~ s/__SRCCELL__/c/g; $get = qq* // count rank int i=-1; for(ZZCell c = n; c!=null; c=c.s("d.1")) i++; // XXX check range $name = new ${base}\l[i]; i=0; for(ZZCell c = n.s("d.1"); c!=null; c=c.s("d.1")) { s = c.getText(); $get; i++; } *; } else { $get =~ s/__TARG__/$name/g; $get =~ s/__SRC__/s/g; $get =~ s/__SRCCELL__/c/g; $get = qq{ZZCell c = n.s("d.1"); s = c.getText(); $get }; } $curbit ++; $curmask = (1 << $curbit); $tests .= qq* if(s.equals("$name")) { mask |= $curmask; try { $get } catch(Exception e) { ZZLogger.exc(e); } } else *; } $fullmask = (1<<($curbit+1))-1; # print "PARAMS: (",(join '||||||',@pars),")\n"; # limit of 31 variables for now. $code = <$outfile" or die "No out: '$outfile'"; print OUT $str; close OUT;