use a syntax closer to list comprehensions for $[]
diff --git a/reclass/values/expitem.py b/reclass/values/expitem.py
index 8313025..fb6b0db 100644
--- a/reclass/values/expitem.py
+++ b/reclass/values/expitem.py
@@ -9,13 +9,14 @@
 
 from item import Item
 from reclass.utils.dictpath import DictPath
-from reclass.errors import ExpressionError, UndefinedVariableError
+from reclass.errors import ExpressionError, ParseError, UndefinedVariableError
 
-_VAR = 'VAR'
+_OBJ = 'OBJ'
 _TEST = 'TEST'
-_VALUE = 'VALUE'
 
+_VALUE = 'VALUE'
 _IF = 'IF'
+
 _EQUAL = '=='
 _NOT_EQUAL = '!='
 
@@ -23,9 +24,23 @@
 
     def _get_parser():
 
-        def _variable(string, location, tokens):
+        def _object(string, location, tokens):
             token = tokens[0]
-            tokens[0] = (_VAR, token)
+            tokens[0] = (_OBJ, token)
+
+        def _integer(string, location, tokens):
+            try:
+                token = int(tokens[0])
+            except ValueError:
+                token = tokens[0]
+            tokens[0] = (_OBJ, token)
+
+        def _number(string, location, tokens):
+            try:
+                token = float(tokens[0])
+            except ValueError:
+                token = tokens[0]
+            tokens[0] = (_OBJ, token)
 
         def _test(string, location, tokens):
             token = tokens[0]
@@ -35,17 +50,25 @@
             token = tokens[0]
             tokens[0] = (_IF, token)
 
-        _EXCLUDES = '?!='
-        _END_IF = '?'
+        def _expr_var(string, location, tokens):
+            token = tokens[0]
+            tokens[0] = (_VALUE, token)
+
+        def _expr_test(string, location, tokens):
+            token = tokens[0]
+            tokens[0] = (_TEST, token)
 
         white_space = pp.White().suppress()
         end = pp.StringEnd()
         operator = (pp.Literal(_EQUAL) | pp.Literal(_NOT_EQUAL)).setParseAction(_test)
-        end_if = pp.Literal(_END_IF).setParseAction(_if)
-        not_operator = ~pp.Literal(_EQUAL) + ~pp.Literal(_NOT_EQUAL) + ~pp.Literal(_END_IF)
-        variable = not_operator + pp.Word(pp.printables).setParseAction(_variable)
-        item = (operator | end_if | variable) + (white_space | end)
-        expr = pp.Optional(white_space) + pp.OneOrMore(item)
+        begin_if = pp.CaselessLiteral(_IF, ).setParseAction(_if)
+        obj = pp.Word(pp.printables).setParseAction(_object)
+        integer = pp.Word('0123456789-').setParseAction(_integer)
+        number = pp.Word('0123456789-.').setParseAction(_number)
+        item = integer | number | obj
+        expr_var = pp.Group(obj + pp.Optional(white_space) + end).setParseAction(_expr_var)
+        expr_test = pp.Group(obj + white_space + begin_if + white_space + item + white_space + operator + white_space + item).setParseAction(_expr_test)
+        expr = pp.Optional(white_space) + (expr_test | expr_var)
         return expr
 
     _parser = _get_parser()
@@ -59,22 +82,22 @@
 
     def _parse_expression(self, expr):
         try:
-            self._expr = ExpItem._parser.parseString(expr).asList()
+            tokens = ExpItem._parser.parseString(expr).asList()
         except pp.ParseException as e:
             raise ParseError(e.msg, e.line, e.col, e.lineno)
 
-        if len(self._expr) == 1 and self._expr[0][0] == _VAR:
-            self._type = _VALUE
-            return
-        elif len(self._expr) == 5 and self._expr[0][0] == _VAR and self._expr[1][0] == _TEST and self._expr[2][0] == _VAR and self._expr[3][0] == _IF and self._expr[4][0] == _VAR:
-            self._type = _TEST
-            export, parameter, value = self._get_vars(self._expr[0][1], None, None, None)
-            export, parameter, value = self._get_vars(self._expr[2][1], export, parameter, value)
+        if len(tokens) == 1:
+            self._type = tokens[0][0]
+            self._expr = tokens[0][1]
+        else:
+            raise ExpressionError('Failed to parse %s' % str(expr))
+
+        if self._type == _TEST:
+            export, parameter, value = self._get_vars(self._expr[2][1], None, None, None)
+            export, parameter, value = self._get_vars(self._expr[4][1], export, parameter, value)
             if parameter != None:
                 path = DictPath(self._delimiter, parameter).drop_first()
                 self._ref.append(str(path))
-            return
-        raise ExpressionError('Failed to parse %s' % str(self))
 
     def contents(self):
         return self._expr
@@ -102,24 +125,24 @@
                 results[node] = copy.deepcopy(self._resolve(path, items))
         return results
 
-    def _if_expression(self, context, exports):
+    def _test_expression(self, context, exports):
         export_path = None
         parameter_path = None
         parameter_value = None
         test = None
-        value_path = DictPath(self._delimiter, self._expr[4][1])
+        value_path = DictPath(self._delimiter, self._expr[0][1])
 
-        if self._expr[1][1] == _EQUAL:
+        if self._expr[3][1] == _EQUAL:
             test = _EQUAL
-        elif self._expr[1][1] == _NOT_EQUAL:
+        elif self._expr[3][1] == _NOT_EQUAL:
             test = _NOT_EQUAL
 
-        export_path, parameter_path, parameter_value = self._get_vars(self._expr[0][1], export_path, parameter_path, parameter_value)
         export_path, parameter_path, parameter_value = self._get_vars(self._expr[2][1], export_path, parameter_path, parameter_value)
+        export_path, parameter_path, parameter_value = self._get_vars(self._expr[4][1], export_path, parameter_path, parameter_value)
 
         if parameter_path != None:
             parameter_path.drop_first()
-            parameter_value = str(self._resolve(parameter, context))
+            parameter_value = self._resolve(parameter, context)
 
         if export_path is None or parameter_value is None or test is None or value_path is None:
             ExpressionError('Failed to render %s' % str(self))
@@ -130,7 +153,7 @@
         results = {}
         for node, items in exports.iteritems():
             if export_path.exists_in(items):
-                export_value = str(self._resolve(export_path, items))
+                export_value = self._resolve(export_path, items)
                 test_passed = False
                 if test == _EQUAL and export_value == parameter_value:
                     test_passed = True
@@ -143,9 +166,9 @@
     def _get_vars(self, var, export, parameter, value):
         if isinstance(var, str):
             path = DictPath(self._delimiter, var)
-            if path.path[0] == 'exports':
+            if path.path[0].lower() == 'exports':
                 export = path
-            elif path.path[0] == 'SELF':
+            elif path.path[0].lower() == 'self':
                 parameter = path
             else:
                 value = var
@@ -157,7 +180,7 @@
         if self._type == _VALUE:
             return self._value_expression(exports)
         elif self._type == _TEST:
-            return self._if_expression(context, exports)
+            return self._test_expression(context, exports)
         raise ExpressionError('Failed to render %s' % str(self))
 
     def __str__(self):