Changeset 123:8b5ca02b386c in livinglogic.java.ul4

Show
Ignore:
Timestamp:
07/03/08 17:49:47 (11 years ago)
Author:
Alexander Lamm <alexander.lamm@…>
Branch:
default
Message:

Implemented date literals and the format and isoformat methods

Location:
library/src/com/livinglogic/ul4
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • library/src/com/livinglogic/ul4/Main.java

    r121 r123  
    1313    public static void main(String[] args) 
    1414    { 
    15         Template tmpl = Compiler.compile("<?print now().isoformat()?>"); 
     15        Template tmpl = Compiler.compile("<?print now().format('%Y-%b-%d %H:%M:%S.%f')?>"); 
    1616        long start = new Date().getTime(); 
    1717        String output = tmpl.renders("<gu&rk> & 'foo'"); 
  • library/src/com/livinglogic/ul4/Opcode.java

    r121 r123  
    1010    public static final int OC_LOADFLOAT = 5; 
    1111    public static final int OC_LOADSTR = 6; 
    12     public static final int OC_LOADVAR = 7; 
    13     public static final int OC_STOREVAR = 8; 
    14     public static final int OC_ADDVAR = 9; 
    15     public static final int OC_SUBVAR = 10; 
    16     public static final int OC_MULVAR = 11; 
    17     public static final int OC_TRUEDIVVAR = 12; 
    18     public static final int OC_FLOORDIVVAR = 13; 
    19     public static final int OC_MODVAR = 14; 
    20     public static final int OC_DELVAR = 15; 
    21     public static final int OC_GETATTR = 16; 
    22     public static final int OC_GETITEM = 17; 
    23     public static final int OC_GETSLICE12 = 18; 
    24     public static final int OC_GETSLICE1 = 19; 
    25     public static final int OC_GETSLICE2 = 20; 
    26     public static final int OC_GETSLICE = 21; 
    27     public static final int OC_PRINT = 22; 
    28     public static final int OC_FOR = 23; 
    29     public static final int OC_ENDFOR = 24; 
    30     public static final int OC_NOT = 25; 
    31     public static final int OC_NEG = 26; 
    32     public static final int OC_CONTAINS = 27; 
    33     public static final int OC_NOTCONTAINS = 28; 
    34     public static final int OC_EQUALS = 29; 
    35     public static final int OC_NOTEQUALS = 30; 
    36     public static final int OC_ADD = 31; 
    37     public static final int OC_SUB = 32; 
    38     public static final int OC_MUL = 33; 
    39     public static final int OC_FLOORDIV = 34; 
    40     public static final int OC_TRUEDIV = 35; 
    41     public static final int OC_AND = 36; 
    42     public static final int OC_OR = 37; 
    43     public static final int OC_MOD = 38; 
    44     public static final int OC_CALLFUNC0 = 39; 
    45     public static final int OC_CALLFUNC1 = 40; 
    46     public static final int OC_CALLFUNC2 = 41; 
    47     public static final int OC_CALLFUNC3 = 42; 
    48     public static final int OC_CALLMETH0 = 43; 
    49     public static final int OC_CALLMETH1 = 44; 
    50     public static final int OC_CALLMETH2 = 45; 
    51     public static final int OC_CALLMETH3 = 46; 
    52     public static final int OC_IF = 47; 
    53     public static final int OC_ELSE = 48; 
    54     public static final int OC_ENDIF = 49; 
    55     public static final int OC_RENDER = 50; 
     12    public static final int OC_LOADDATE = 7; 
     13    public static final int OC_LOADVAR = 8; 
     14    public static final int OC_STOREVAR = 9; 
     15    public static final int OC_ADDVAR = 10; 
     16    public static final int OC_SUBVAR = 11; 
     17    public static final int OC_MULVAR = 12; 
     18    public static final int OC_TRUEDIVVAR = 13; 
     19    public static final int OC_FLOORDIVVAR = 14; 
     20    public static final int OC_MODVAR = 15; 
     21    public static final int OC_DELVAR = 16; 
     22    public static final int OC_GETATTR = 17; 
     23    public static final int OC_GETITEM = 18; 
     24    public static final int OC_GETSLICE12 = 19; 
     25    public static final int OC_GETSLICE1 = 20; 
     26    public static final int OC_GETSLICE2 = 21; 
     27    public static final int OC_GETSLICE = 22; 
     28    public static final int OC_PRINT = 23; 
     29    public static final int OC_FOR = 24; 
     30    public static final int OC_ENDFOR = 25; 
     31    public static final int OC_NOT = 26; 
     32    public static final int OC_NEG = 27; 
     33    public static final int OC_CONTAINS = 28; 
     34    public static final int OC_NOTCONTAINS = 29; 
     35    public static final int OC_EQUALS = 30; 
     36    public static final int OC_NOTEQUALS = 31; 
     37    public static final int OC_ADD = 32; 
     38    public static final int OC_SUB = 33; 
     39    public static final int OC_MUL = 34; 
     40    public static final int OC_FLOORDIV = 35; 
     41    public static final int OC_TRUEDIV = 36; 
     42    public static final int OC_AND = 37; 
     43    public static final int OC_OR = 38; 
     44    public static final int OC_MOD = 39; 
     45    public static final int OC_CALLFUNC0 = 40; 
     46    public static final int OC_CALLFUNC1 = 41; 
     47    public static final int OC_CALLFUNC2 = 42; 
     48    public static final int OC_CALLFUNC3 = 43; 
     49    public static final int OC_CALLMETH0 = 44; 
     50    public static final int OC_CALLMETH1 = 45; 
     51    public static final int OC_CALLMETH2 = 46; 
     52    public static final int OC_CALLMETH3 = 47; 
     53    public static final int OC_IF = 48; 
     54    public static final int OC_ELSE = 49; 
     55    public static final int OC_ENDIF = 50; 
     56    public static final int OC_RENDER = 51; 
    5657 
    5758    public static final int CF0_NOW = 0; 
     
    6869    public static final int CF1_ISFLOAT = 9; 
    6970    public static final int CF1_ISBOOL = 10; 
    70     public static final int CF1_ISLIST = 11; 
    71     public static final int CF1_ISDICT = 12; 
    72     public static final int CF1_CHR = 13; 
    73     public static final int CF1_ORD = 14; 
    74     public static final int CF1_HEX = 15; 
    75     public static final int CF1_OCT = 16; 
    76     public static final int CF1_BIN = 17; 
    77     public static final int CF1_SORTED = 18; 
    78     public static final int CF1_RANGE = 19; 
     71    public static final int CF1_ISDATE = 11; 
     72    public static final int CF1_ISLIST = 12; 
     73    public static final int CF1_ISDICT = 13; 
     74    public static final int CF1_CHR = 14; 
     75    public static final int CF1_ORD = 15; 
     76    public static final int CF1_HEX = 16; 
     77    public static final int CF1_OCT = 17; 
     78    public static final int CF1_BIN = 18; 
     79    public static final int CF1_SORTED = 19; 
     80    public static final int CF1_RANGE = 20; 
    7981 
    8082    public static final int CF2_RANGE = 0; 
     
    8991    public static final int CM0_LOWER = 5; 
    9092    public static final int CM0_ITEMS = 6; 
    91     public static final int CM0_FORMAT = 7; 
    92     public static final int CM0_ISOFORMAT = 8; 
     93    public static final int CM0_ISOFORMAT = 7; 
    9394 
    9495    public static final int CM1_SPLIT = 0; 
     
    100101    public static final int CM1_ENDSWITH = 6; 
    101102    public static final int CM1_FIND = 7; 
     103    public static final int CM1_FORMAT = 8; 
    102104 
    103105    public int name; 
     
    128130        else if (name.equals("loadstr")) 
    129131            return OC_LOADSTR; 
     132        else if (name.equals("loaddate")) 
     133            return OC_LOADDATE; 
    130134        else if (name.equals("loadvar")) 
    131135            return OC_LOADVAR; 
     
    252256        else if (name.equals("isbool")) 
    253257            return CF1_ISBOOL; 
     258        else if (name.equals("isdate")) 
     259            return CF1_ISDATE; 
    254260        else if (name.equals("islist")) 
    255261            return CF1_ISLIST; 
     
    308314        else if (name.equals("items")) 
    309315            return CM0_ITEMS; 
    310         else if (name.equals("format")) 
    311             return CM0_FORMAT; 
    312316        else if (name.equals("isoformat")) 
    313317            return CM0_ISOFORMAT; 
     
    334338        else if (name.equals("find")) 
    335339            return CM1_FIND; 
     340        else if (name.equals("format")) 
     341            return CM1_FORMAT; 
    336342        else 
    337343            throw new UnknownMethodException(name); 
     
    364370        else if (code == OC_LOADSTR) 
    365371            return "loadstr"; 
     372        else if (code == OC_LOADDATE) 
     373            return "loaddate"; 
    366374        else if (code == OC_LOADVAR) 
    367375            return "loadvar"; 
  • library/src/com/livinglogic/ul4/Template.java

    r121 r123  
    1111import java.util.HashMap; 
    1212import java.util.Iterator; 
     13import java.util.Locale; 
    1314import java.util.Map; 
    1415import java.util.Date; 
     
    2627    private static Pattern binintPattern; 
    2728    private static Pattern intPattern; 
     29    private static Pattern datePattern; 
    2830    private static Pattern whitespacePattern; 
    2931    private static Pattern escaped8BitCharPattern; 
     
    4244        binintPattern = Pattern.compile("0[bB][01]+"); 
    4345        intPattern = Pattern.compile("\\d+"); 
     46        datePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2}(:\\d{2}(.\\d{6})?)?)?"); 
    4447        whitespacePattern = Pattern.compile("\\s+"); 
    4548        escaped8BitCharPattern = Pattern.compile("\\\\x[0-9a-fA-F]{2}"); 
     
    5356        public int pc; 
    5457        public Iterator iterator; 
    55      
     58 
    5659        public IteratorStackEntry(int iteratorRegSpec, int pc, Iterator iterator) 
    5760        { 
     
    7376 
    7477    public List opcodes; 
     78     
     79    public Locale defaultLocale; 
    7580 
    7681    private boolean annotated = false; 
     
    8085        this.source = null; 
    8186        this.opcodes = new LinkedList(); 
     87        this.defaultLocale = Locale.GERMANY; 
    8288    } 
    8389 
     
    557563                            reg[code.r1] = new Double(Double.parseDouble(code.arg)); 
    558564                            break; 
     565                        case Opcode.OC_LOADDATE: 
     566                            reg[code.r1] = Utils.isoDateFormatter.parse(code.arg); 
     567                            break; 
    559568                        case Opcode.OC_LOADVAR: 
    560569                            reg[code.r1] = variables.get(code.arg); 
     
    726735                                    reg[code.r1] = ((null != reg[code.r2]) && (reg[code.r2] instanceof Boolean)) ? Boolean.TRUE : Boolean.FALSE; 
    727736                                    break; 
     737                                case Opcode.CF1_ISDATE: 
     738                                    reg[code.r1] = ((null != reg[code.r2]) && (reg[code.r2] instanceof Date)) ? Boolean.TRUE : Boolean.FALSE; 
     739                                    break; 
    728740                                case Opcode.CF1_ISLIST: 
    729741                                    reg[code.r1] = ((null != reg[code.r2]) && (reg[code.r2] instanceof List)) ? Boolean.TRUE : Boolean.FALSE; 
     
    795807                                    reg[code.r1] = Utils.items(reg[code.r2]); 
    796808                                    break; 
    797                                 case Opcode.CM0_FORMAT: 
    798                                     reg[code.r1] = Utils.format(reg[code.r2]); 
    799                                     break; 
    800809                                case Opcode.CM0_ISOFORMAT: 
    801810                                    reg[code.r1] = Utils.isoformat(reg[code.r2]); 
     
    829838                                case Opcode.CM1_FIND: 
    830839                                    reg[code.r1] = Utils.items(reg[code.r2], reg[code.r3]); 
    831                                     break; 
    832 */                          } 
     840                                    break;*/ 
     841                                case Opcode.CM1_FORMAT: 
     842                                    reg[code.r1] = Utils.format(reg[code.r2], reg[code.r3], defaultLocale); 
     843                                    break; 
     844                            } 
    833845                            break; 
    834846                        case Opcode.OC_CALLMETH2: 
     
    928940                Matcher binintMatcher = binintPattern.matcher(source); 
    929941                Matcher intMatcher = intPattern.matcher(source); 
     942                Matcher dateMatcher = datePattern.matcher(source); 
    930943                Matcher whitespaceMatcher = whitespacePattern.matcher(source); 
    931944                Matcher escaped8BitCharMatcher = escaped8BitCharPattern.matcher(source); 
     
    954967                        tokens.add(new Name(pos, pos+len, name)); 
    955968                } 
     969                else if (stringMode==0 && dateMatcher.lookingAt()) 
     970                { 
     971                    len = dateMatcher.end(); 
     972                    tokens.add(new com.livinglogic.ul4.Date(pos, pos+len, Utils.isoDateFormatter.parse(dateMatcher.group()))); 
     973                } 
    956974                else if (stringMode==0 && floatMatcher.lookingAt()) 
    957975                { 
  • library/src/com/livinglogic/ul4/Utils.java

    r121 r123  
    88import java.util.NoSuchElementException; 
    99import java.util.List; 
     10import java.util.Locale; 
    1011import java.util.Map; 
    1112import java.util.Vector; 
     
    1314import java.text.SimpleDateFormat; 
    1415 
    15 class Range extends AbstractList  
     16class Range extends AbstractList 
    1617{ 
    1718    int start; 
     
    7576 
    7677    int index; 
    77      
     78 
    7879    public StringIterator(String string) 
    7980    { 
     
    137138 
    138139    int index = 0; 
    139      
     140 
    140141    public SequenceEnumerator(Iterator sequenceIterator) 
    141142    { 
     
    165166{ 
    166167    protected static final Integer INTEGER_TRUE = new Integer(1); 
    167      
     168 
    168169    protected static final Integer INTEGER_FALSE = new Integer(0); 
    169      
     170 
    170171    public static Object neg(Integer arg) 
    171172    { 
    172173        return new Integer(-arg.intValue()); 
    173174    } 
    174      
     175 
    175176    public static Object neg(Number arg) 
    176177    { 
    177178        return new Double(-arg.doubleValue()); 
    178179    } 
    179      
     180 
    180181    public static Object neg(Object arg) 
    181182    { 
     
    191192        return new Integer(arg1.intValue() + arg2.intValue()); 
    192193    } 
    193      
     194 
    194195    public static Object add(Number arg1, Number arg2) 
    195196    { 
    196197        return new Double(arg1.doubleValue() + arg2.doubleValue()); 
    197198    } 
    198      
     199 
    199200    public static Object add(String arg1, String arg2) 
    200201    { 
     
    217218        return new Integer(arg1.intValue() - arg2.intValue()); 
    218219    } 
    219      
     220 
    220221    public static Object sub(Number arg1, Number arg2) 
    221222    { 
     
    332333        return arg1.get(arg2); 
    333334    } 
    334      
     335 
    335336    public static Object getItem(Object arg1, Object arg2) 
    336337    { 
     
    445446    } 
    446447 
     448    public static boolean getBool(Date obj) 
     449    { 
     450        return true; 
     451    } 
     452 
    447453    public static boolean getBool(Collection obj) 
    448454    { 
     
    457463    public static boolean getBool(Object obj) 
    458464    { 
    459         if (obj instanceof Boolean) 
     465        if (null == obj) 
     466            return false; 
     467        else if (obj instanceof Boolean) 
    460468            return getBool((Boolean)obj); 
    461469        else if (obj instanceof String) 
     
    465473        else if (obj instanceof Double) 
    466474            return getBool((Double)obj); 
     475        else if (obj instanceof Date) 
     476            return getBool((Date)obj); 
    467477        else if (obj instanceof Collection) 
    468478            return getBool((Collection)obj); 
    469479        else if (obj instanceof Map) 
    470480            return getBool((Map)obj); 
    471         return false; 
     481        return true; 
    472482    } 
    473483 
     
    479489            return (null == obj2); 
    480490    } 
    481      
     491 
    482492    public static boolean contains(String obj, String container) 
    483493    { 
     
    553563    public static String toString(Object obj) 
    554564    { 
    555         return obj != null ? obj.toString() : "";  
     565        return obj != null ? obj.toString() : ""; 
    556566    } 
    557567 
     
    573583    public static Object toInteger(Boolean obj) 
    574584    { 
    575         return obj.booleanValue() ? INTEGER_TRUE : INTEGER_FALSE;  
     585        return obj.booleanValue() ? INTEGER_TRUE : INTEGER_FALSE; 
    576586    } 
    577587 
     
    670680        if (1 != obj.length()) 
    671681        { 
    672             throw new IllegalArgumentException("String " + obj + " contains more than one unicode character!");  
     682            throw new IllegalArgumentException("String " + obj + " contains more than one unicode character!"); 
    673683        } 
    674684        return new Integer((int)obj.charAt(0)); 
     
    951961    } 
    952962 
    953     private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy.MM.dd"); 
    954     private static SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss.S"); 
     963    public static SimpleDateFormat isoDateFormatter = new SimpleDateFormat("yyyy.MM.dd'T'HH:mm:ss.SSS'000'"); 
    955964 
    956965    public static Object isoformat(Date obj) 
    957966    { 
    958         return dateFormatter.format(obj) + "T" + timeFormatter.format(obj) + "000"; 
     967        return isoDateFormatter.format(obj); 
    959968    } 
    960969 
     
    966975    } 
    967976 
    968     public static Object format(Object obj) 
    969     { 
    970         throw new UnsupportedOperationException("Can't call format on instance of " + obj.getClass() + "!"); 
     977    public static Object format(Date obj, String formatString, Locale locale) 
     978    { 
     979        StringBuffer javaFormatString = new StringBuffer(); 
     980        int formatStringLength = formatString.length(); 
     981        boolean escapeCharacterFound = false; 
     982        boolean inLiteral = false; 
     983        char formatChar; 
     984        String javaFormatSequence; 
     985        for (int i = 0; i < formatStringLength; i++) 
     986        { 
     987            formatChar = formatString.charAt(i); 
     988            if (escapeCharacterFound) 
     989            { 
     990                switch (formatChar) 
     991                { 
     992                    case 'a': 
     993                        javaFormatSequence = "EE"; 
     994                        break; 
     995                    case 'A': 
     996                        javaFormatSequence = "EEEE"; 
     997                        break; 
     998                    case 'b': 
     999                        javaFormatSequence = "MMM"; 
     1000                        break; 
     1001                    case 'B': 
     1002                        javaFormatSequence = "MMMM"; 
     1003                        break; 
     1004                    case 'c': 
     1005                        throw new UnsupportedOperationException("Unimplemented escape sequence %c"); 
     1006                    case 'd': 
     1007                        javaFormatSequence = "dd"; 
     1008                        break; 
     1009                    case 'f': 
     1010                        javaFormatSequence = "SSS'000"; 
     1011                        break; 
     1012                    case 'H': 
     1013                        javaFormatSequence = "HH"; 
     1014                        break; 
     1015                    case 'I': 
     1016                        javaFormatSequence = "hh"; 
     1017                        break; 
     1018                    case 'j': 
     1019                        javaFormatSequence = "DDD"; 
     1020                        break; 
     1021                    case 'm': 
     1022                        javaFormatSequence = "MM"; 
     1023                        break; 
     1024                    case 'M': 
     1025                        javaFormatSequence = "mm"; 
     1026                        break; 
     1027                    case 'p': 
     1028                        javaFormatSequence = "aa"; 
     1029                        break; 
     1030                    case 'S': 
     1031                        javaFormatSequence = "ss"; 
     1032                        break; 
     1033                    case 'U': 
     1034                        javaFormatSequence = "ww"; 
     1035                        break; 
     1036                    case 'w': 
     1037                        throw new UnsupportedOperationException("Unimplemented escape sequence %w"); 
     1038                    case 'W': 
     1039                        javaFormatSequence = "ww"; 
     1040                        break; 
     1041                    case 'x': 
     1042                        throw new UnsupportedOperationException("Unimplemented escape sequence %x"); 
     1043                    case 'X': 
     1044                        throw new UnsupportedOperationException("Unimplemented escape sequence %X"); 
     1045                    case 'y': 
     1046                        javaFormatSequence = "yy"; 
     1047                        break; 
     1048                    case 'Y': 
     1049                        javaFormatSequence = "yyyy"; 
     1050                        break; 
     1051                    default: 
     1052                        javaFormatSequence = null; 
     1053                        break; 
     1054                } 
     1055                if (inLiteral != (null == javaFormatSequence)) 
     1056                { 
     1057                    javaFormatString.append('\''); 
     1058                    inLiteral = !inLiteral; 
     1059                } 
     1060                if (null != javaFormatSequence) 
     1061                { 
     1062                    javaFormatString.append(javaFormatSequence); 
     1063                    if ('f' == formatChar) 
     1064                    { 
     1065                        inLiteral = true; 
     1066                    } 
     1067                } 
     1068                else 
     1069                { 
     1070                    javaFormatString.append(formatChar); 
     1071                } 
     1072                escapeCharacterFound = false; 
     1073            } 
     1074            else 
     1075            { 
     1076                escapeCharacterFound = ('%' == formatChar); 
     1077                if (!escapeCharacterFound) 
     1078                { 
     1079                    if (inLiteral = !inLiteral) 
     1080                    { 
     1081                        javaFormatString.append('\''); 
     1082                    } 
     1083                    javaFormatString.append(formatChar); 
     1084                    if ('\'' == formatChar) 
     1085                    { 
     1086                        javaFormatString.append(formatChar); 
     1087                    } 
     1088                } 
     1089            } 
     1090        } 
     1091        if (inLiteral) 
     1092        { 
     1093            javaFormatString.append('\''); 
     1094        } 
     1095        return new SimpleDateFormat(javaFormatString.toString(), locale).format(obj); 
     1096    } 
     1097 
     1098    public static Object format(Object obj, Object formatString, Locale locale) 
     1099    { 
     1100        if (formatString instanceof String) 
     1101        { 
     1102            if (obj instanceof Date) 
     1103            { 
     1104                return format((Date)obj, (String)formatString, locale); 
     1105            } 
     1106        } 
     1107        throw new UnsupportedOperationException("Can't call format on instance of " + obj.getClass() + " with format string instance of " + formatString.getClass() + "!"); 
    9711108    } 
    9721109 
    9731110    public static Object items(Map obj) 
    9741111    { 
    975         return new MapItemIterator(obj);  
     1112        return new MapItemIterator(obj); 
    9761113    } 
    9771114 
  • library/src/com/livinglogic/ul4/ul4c.py

    r119 r123  
    156156        'expr11 ::= int', 
    157157        'expr11 ::= float', 
     158        'expr11 ::= date', 
    158159        'expr11 ::= name', 
    159160    ]