import pyast

class Node(pyast.Node):
    _abstract = True
    _debug = False

class Entry(Node):
    _abstract = True

class LOL(Node):
    body = pyast.seq(Entry, null=True)

class Expression(Node):
    _abstract = True

class Value(Expression):
    _abstract = True

class Operator(Node):
    _abstract = True

class Identifier(Expression):
    name = pyast.field(pyast.re('[a-zA-Z]\w*'))

class Expander(Node):
    expression = pyast.field(Expression)


class KeyValuePair(Node):
    key = pyast.field(Identifier)
    value = pyast.field(Value)

### Entries

class Entity(Entry):
    id = pyast.field(Identifier)
    index = pyast.seq(Expression, null=True)
    value = pyast.field(Value, null=True)
    attrs = pyast.seq(KeyValuePair, null=True)

class Comment(Entry):
    content = pyast.field(str, null=True)

class Macro(Entry):
    id = pyast.field(Identifier)
    args = pyast.seq(Identifier)
    expression = pyast.field(Expression)
    attrs = pyast.seq(KeyValuePair, null=True)

### Values

class String(Value):
    content = pyast.field(str)

class Array(Value):
    content = pyast.seq(Value)

class Hash(Value):
    content = pyast.seq(KeyValuePair)

class Int(Value):
    content = pyast.field(int)

### Operators

class UnaryOperator(Operator):
    token = pyast.field(("-", "+", "!", "~", "typeof", "void", "delete"))


class BinaryOperator(Operator):
    token = pyast.field(("==", "!=", "===", "!==", "<", "<=", ">", ">=",
                           "<<", ">>", ">>>", "+", "-", "*", "/", "%", "|",
                           "^", "in", "instanceof", ".."))


class LogicalOperator(Operator):
    token = pyast.field(("||", "&&"))


class AssignmentOperator(Operator):
    token = pyast.field(("=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=",
                         ">>>=", "|=", "^=", "&="))

### Expressions

class Literal(Expression):
    value = pyast.field((bool, int))

class BinaryExpression(Expression):
    operator = pyast.field(BinaryOperator)
    left = pyast.field(Expression)
    right = pyast.field(Expression)

class ConditionalExpression(Expression):
    test = pyast.field(Expression)
    consequent = pyast.field(Expression)
    alternate = pyast.field(Expression)

class UnaryExpression(Expression):
    operator = pyast.field(UnaryOperator)
    argument = pyast.field(Expression)
    prefix = pyast.field(bool, default=False)

class CallExpression(Expression):
    callee = pyast.field(Expression)
    arguments = pyast.seq(Expression, null=True)

class LogicalExpression(Expression):
    pass

class MemberExpression(Expression):
    pass

class AttributeExpression(Expression):
    pass

class ParenthesisExpression(Expression):
    pass

@@ -1164,58 +1164,8 @@
 r)%0A%0A
-class Int(Value):%0A    content = pyast.field(int)%0A%0A
 ### 
@@ -1248,41 +1248,8 @@
  %22!%22
-, %22~%22, %22typeof%22, %22void%22, %22delete%22
 ))%0A%0A
@@ -1321,22 +1321,8 @@
 !=%22,
- %22===%22, %22!==%22,
  %22%3C%22
@@ -1368,29 +1368,8 @@
     
-   %22%3C%3C%22, %22%3E%3E%22, %22%3E%3E%3E%22,
  %22+%22
@@ -1392,71 +1392,8 @@
  %22%25%22
-, %22%7C%22,%0A                           %22%5E%22, %22in%22, %22instanceof%22, %22..%22
 ))%0A%0A
@@ -1470,171 +1470,8 @@
 )%0A%0A%0A
-class AssignmentOperator(Operator):%0A    token = pyast.field((%22=%22, %22+=%22, %22-=%22, %22*=%22, %22/=%22, %22%25=%22, %22%3C%3C=%22, %22%3E%3E=%22,%0A                         %22%3E%3E%3E=%22, %22%7C=%22, %22%5E=%22, %22&=%22))%0A%0A
 ### 
@@ -1976,54 +1976,8 @@
 ion)
-%0A    prefix = pyast.field(bool, default=False)
 %0A%0Acl
@@ -2128,36 +2128,142 @@
 xpression):%0A    
-pass
+operator = pyast.field(LogicalOperator)%0A    left = pyast.field(Expression)%0A    right = pyast.field(Expression)
 %0A%0Aclass MemberEx

remove some operators that we will not use