Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit dd6624f4cadaaff863084ca45567ba886e1ac025 0 parents
@scooby authored
1  .gitignore
@@ -0,0 +1 @@
+*.pyc
211 CodeObjects.py
@@ -0,0 +1,211 @@
+import types.NoneType
+import itertools.product
+
+# Methods in which to always call
+# super(myclass, self).method(**kw):
+# __init__
+#
+#
+# How does analysis work?
+# First, we create the objects more or less straight from the AST.
+# Second, we work out variable bindings.
+# Third, we create any branches of code to handle type changes.
+
+class Statement(object):
+ """
+A Statement is an object of execution.
+To bind it, we need to know what variables of what types it is looking for
+
+To execute it, we need to know what variables it is reading
+from, and what variables it is providing to the next statement.
+"""
+ def __init__(self, **kw):
+ super(Statement, self).__init__(**kw)
+ for a in ["prior", "next", "block"]:
+ assert a in kw
+ assert isinstance(kw[a], (Statement, NoneType))
+ setattr(self, a, kw[a])
+ def signatures(self, **kw):
+ """ Generates possible signatures """
+ super(Statement, self).signatures(**kw)
+ pass
+
+class Signature(object):
+ """ A signature maps variable names to types in, and then
+ variable names to types out. """
+ def __init__(self, **kw):
+ super(Signature, self).__init__(**kw)
+ self.vin = dict()
+ self.vout = dict()
+ def compatible(self, scope):
+ """ Tests whether this signature can draw from the scope. """
+ missing = set()
+ incompatible = dict()
+ for var, typ in self.vin.iterpairs():
+ if var not in scope:
+ missing.add(var)
+ if typ != scope[var]:
+ incompatible[var] = (typ, scope[var])
+ return { "result": not (missing or incompatible),
+ "missing": missing,
+ "incompatible": incompatible }
+
+class Scope(dict):
+ pass
+
+class ExpressionStatement(Statement):
+ def __init__(self, **kw):
+ super(ExpressionStatement, self).__init__(**kw)
+
+class Assignment(Statement):
+ def __init__(self, **kw):
+ super(Assignment, self).__init__(**kw)
+ for a in ["var", "expr"]:
+ assert a in kw
+ setattr(self, a, kw[a])
+ assert isinstance(self.var, basestring)
+ assert isinstance(self.expr, Expression)
+
+class Conditional(Statement):
+ def __init__(self, **kw):
+ super(Conditional, self).__init__(**kw)
+
+class Block(Statement):
+ def __init__(self, **kw):
+ super(Block, self).__init__(**kw)
+ self.statements = []
+ self.declarations = set()
+
+class Expression(object):
+ def __init__(self, **kw):
+ super(Expression, self).__init__(**kw)
+ self.args = kw["args"]
+ for a in self.args:
+ assert isinstance(a, Expression)
+ def iterInputTypes(self):
+ """ Returns a generator that steps through all the
+ possible input types that can be fed to this operation. """
+ return product(*[t.iterOutputTypes() for t in self.args])
+
+class LiteralExpression(Expression):
+ def lolType(val):
+ return { NoneType : Noob,
+ bool : Troof,
+ int : Numbar,
+ str : Yarn }[type(val)]
+ def __init__(self, **kw):
+ super(LiteralExpression, self).__init__(**kw)
+ self.val = kw[val]
+ self.valType = type(val)
+ self.lolType = findLolType(self.val)
+ assert isinstance(self.val, self.valType)
+ def signatures(self):
+ yield { "in": [], "out": self.lolType }
+ def iterOutputTypes(self):
+ yield self.lolType
+class ComparisonExpression(Expression):
+ def signatures(self):
+ for t in self.iterInputTypes():
+ if not t or all(x == t[0] for x in t):
+ yield { "in": t, "out": Troof }
+ def iterOutputTypes(self):
+ yield Troof
+class SetExpression(Expression):
+ def __init__(self, **kw):
+ super(SetExpression, self).__init__(**kw)
+ self.setOp = kw["setOp"]
+ assert isinstance(BoolOp, self.setOp)
+class BooleanExpression(Expression):
+ def __init__(self, **kw):
+ super(BooleanExpression, self).__init__(**kw)
+ self.boolOp = kw["boolOp"]
+ assert isinstance(BoolOp, self.setOp)
+
+class BoolOp(object):
+ """ Represents a binary boolean operation """
+ def __init__(self, table):
+ """ table represents all the a's and b's that
+ produce True values """
+ assert all(isinstance(a, bool) and isinstance(b, bool)
+ for a, b in table)
+ self.table = frozenset(table)
+ def __equals__(self, other):
+ return self.table == other.table
+ tautology = frozenset((a, b) for a, b in
+ product((False, True), repeat=2))
+ def negated(self):
+ """ convenience to generate the opposite operation """
+ return BoolOp(tautology - self.table)
+
+AndOp = BoolOp([(True, True)])
+OrOp = BoolOp([(False, False)]).negated()
+XorOp = BoolOp([(True, False), (False, True)])
+
+class ConcatenationExpression(Expression):
+ def iterOutputTypes(self):
+ yield Yarn
+ def signatures(self):
+ for a,b in self.iterInputTypes():
+ if a == Yarn and b == Yarn:
+ yield { "in": (a, b), "out": Yarn }
+class SlicingExpression(Expression):
+ def __init__(self, **kw):
+ super(SlicingExpression, self).__init__(**kw)
+ self.bukkit = kw["bukkit"]
+ for a in ("from", "back", "to", "by"):
+ if a in kw:
+ setattr(self, a, kw[a])
+ else:
+ setattr(self, a, None)
+ assert issubclass(self.bukkit, Complex)
+ def iterOutputTypes(self):
+ return type(self.bukkit)
+
+class MathExpression(Expression):
+ def iterOutputTypes(self):
+ yield Numbar
+ def signatures(self):
+ for a, b in self.iterInputTypes():
+ if a == Numbar and b == Numbar:
+ yield { "in": (a, b), "out": Numbar }
+
+# Types
+class Builtin(object):
+ pass
+class Atomic(BuiltinType):
+ def __init__(self, **kw):
+ super(Atomic, self).__init__(**kw)
+ assert self.python() == NoneType or type(kw[val]) == self.python()
+class Noob(Atomic):
+ def python(self):
+ return NoneType
+class Troof(Atomic):
+ def python(self):
+ return bool
+class Numbar(Atomic):
+ def python(self):
+ return int
+class Yarn(Atomic):
+ def python(self):
+ return str
+class Complex(Builtin):
+ pass
+def bukkitOf(key, val):
+ assert issubclass(key, Atomic) and issubclass(val, Atomic)
+ return type(name="BukkitOf%sAnd%s" % (key.__name__, val.__name__),
+ bases=(Complex,),
+ dict=dict([("keyType", key), ("valType", val)]))
+def allAtomicTypes():
+ """ Iterator that yields all possible atomic types. """
+ yield Noob
+ yield Troof
+ yield Numbar
+ yield Yarn
+def allBuiltinTypes():
+ """ Iterator that yields all possible types. """
+ for t in allAtomicTypes():
+ yield t
+ # Do all bukkits
+ for k in allAtomicTypes():
+ for v in allAtomicTypes():
+ yield bukkitOf(k, v)
330 LolGrammer.py
@@ -0,0 +1,330 @@
+from lepl import *
+
+def build(r):
+ # This is passed to config.lexer before we return the matcher.
+ # A possible identifier
+ ident = Token('[a-zA-Z][a-zA-Z0-9]*')
+ # All caps might be a keyword
+ kw = ident('[A-Z]+')
+ punc = Token(Any('()?!,.'))
+ inttok = Token(Integer())
+ strtok = Token(Literal('"') + ((Literal(':') + Any(')>o":')) | Regexp('[^:"]'))[0:] + Literal('"'))
+ #strtok = Token('"[^"]*"')
+ nltok = Token(Newline())
+ # End of line comments are parsed as a token
+ linecomtok = Token('BTW[ \t]+.*')
+
+ # Define keywords here so I can add misspellings.
+ A = kw('A')
+ ALL = kw('ALL')
+ AN = kw('AN') # Effectively a comma, *not* an alternate form of A
+ ANY = kw('ANY')
+ BAK = kw('BAK')
+ BIG = kw('BIG')
+ BIGGR = kw('BIGGR')
+ BIGGST = kw('BIGGST')
+ BOTH = kw('BOTH')
+ BUKKIT = kw('BUKKIT')
+ BY = kw('BY')
+ DIFFRINT = kw('DIFFRINT')
+ DIFF = kw('DIFF')
+ DON = kw('DON')
+ DUZ = kw('DUZ')
+ EITHER = kw('EITHER')
+ FAIL = kw('FAIL')
+ FISH = kw('FISH')
+ FOUND = kw('FOUND')
+ FRM = kw('FRM')
+ GIMMEH = kw('GIMMEH')
+ GTFO = kw('GTFO')
+ HAI = kw('HAI')
+ HAS = kw('HAS') | kw('HAZ')
+ HOW = kw('HOW')
+ KEEP = kw('KEEP')
+ KITTEH = kw('KITTEH')
+ KTHXBYE = kw('KTHXBYE')
+ I = kw('I')
+ IF = kw('IF')
+ IM = kw('IM')
+ IN = kw('IN')
+ IS = kw('IS') | kw('IZ')
+ LEASTEST = kw('LEASTEST')
+ LINE = kw('LINE')
+ LISTIN = kw('LISTIN')
+ MA = kw('MA')
+ MAEK = kw('MAEK')
+ MEBBE = kw('MEBBE')
+ MINUS = kw('MINUS')
+ MKAY = kw('MKAY')
+ MOD = kw('MOD')
+ MOSTEST = kw('MOSTEST')
+ N = kw('N')
+ NAMIN = kw('NAMIN')
+ NERFIN = kw('NERFIN')
+ NO = kw('NO')
+ NOOB = kw('NOOB')
+ NOOBS = kw('NOOBS')
+ NOT = kw('NOT')
+ NOW = kw('NOW')
+ NUMBAR = kw('NUMBAR')
+ NUMBARS = kw('NUMBARS')
+ O = OH = kw('OH') | kw('O')
+ OIC = kw('OIC')
+ OMG = kw('OMG')
+ OMGWTF = kw('OMGWTF')
+ OUTTA = kw('OUTTA')
+ PIK = kw('PIK')
+ PRODUKT = kw('PRODUKT')
+ QUOSHUNT = kw('QUOSHUNT')
+ R = kw('R')
+ RLY = kw('RLY')
+ SAEM = kw('SAEM')
+ SAY = kw('SAY')
+ SMALLR = kw('SMALLR')
+ SMALLST = kw('SMALLST')
+ SMOOSH = kw('SMOOSH')
+ SO = kw('SO')
+ STEALIN = kw('STEALIN')
+ SUM = kw('SUM')
+ TEH = kw('TEH')
+ THN = kw('THN') | kw('THAN')
+ TILL = kw('TILL')
+ TO = kw('TO')
+ TROOF = kw('TROOF')
+ TROOFS = kw('TROOFS')
+ TRYN = kw('TRYN')
+ U = kw('U')
+ UF = kw('UF') | kw('OF')
+ UPPIN = kw('UPPIN')
+ VERAH = kw('VERAH')
+ VISIBLE = kw('VISIBLE')
+ VISIBLEZ = kw('VISIBLEZ')
+ WAI = kw('WAI')
+ WILE = kw('WILE')
+ WIN = kw('WIN')
+ WON = kw('WON')
+ WORD = kw('WORD') | kw('WERD')
+ WTF = kw('WTF')
+ YA = kw('YA')
+ YR = kw('YR')
+ YARN = kw('YARN')
+ YARNS = kw('YARNS')
+
+ OPENPAREN = punc('(')
+ CLOSEPAREN = punc(')')
+ BANG = punc('!')
+ QMARK = punc('?')
+ DOT = punc('.')
+ COMMA = punc(',')
+
+ C = ~(linecomtok | COMMA | nltok)[1:]
+
+ with Separator(~linecomtok[0:]):
+ Variable = ident
+ FuncName = ident
+ Label = ident
+
+ #atomtype: NOOB | TROOF | NUMBAR | YARN;
+ AtomType = (~NOOB > r.voidT) | (~TROOF > r.boolT) | \
+ (~NUMBAR > r.intT) | (~YARN > r.strT)
+ #atomtypes: NOOBS | TROOFS | NUMBARS | YARNS;
+ AtomTypes = (~NOOBS > r.voidT) | (~TROOFS > r.boolT) | \
+ (~NUMBARS > r.intT) | (~YARNS > r.strT)
+ #complextype: BUKKIT UF atomtypes | LISTIN atomtypes | BUKKIT NAMIN atomtypes;
+ Bukkity = ((VERAH | BIG)[0:] & ~BUKKIT) > r.bigness
+ ComplexType = ((Bukkity & ~UF & AtomTypes > r.setT) | (Bukkity & ~LISTIN &
+ AtomTypes > r.listT) | (Bukkity & ~NAMIN & AtomTypes > r.mapT))
+ #type: atomtype | complextype;
+ Type = AtomType | ComplexType
+
+ LiteralTroof = (~FAIL > r.boolFalse) | (~WIN > r.boolTrue)
+ LiteralNumbar = inttok > r.intLit
+ LiteralYarn = strtok > r.strLit
+
+ Expr = Delayed()
+
+ #exprpair: expr AN? expr;
+ AnPair = Expr & ~AN[0:1] & Expr
+ AnList = Expr & (~AN[0:1] & Expr)[0:] & ~MKAY
+ ThanPair = Expr & ~THN & Expr
+ #ofpair: OF expr AN? expr;
+ OfPair = ~UF & Expr & ~AN[0:1] & Expr
+ #oflist: OF expr (AN? expr)* MKAY;
+ OfList = ~UF & Expr & (~AN[0:1] & Expr)[0:] & ~MKAY
+
+ #parenthetical: OPENPAREN expr CLOSEPAREN;
+ Parenthetical = ~OPENPAREN & Expr & ~CLOSEPAREN
+ #inequality: DIFFRINT exprpair
+ # | IZ BIGGR expr THN expr
+ # | IZ SMALLR expr THN expr;
+ NotEqual = ~DIFFRINT & AnPair > r.notEqual
+ GreaterThan = ~IS & ~BIGGR & ThanPair > r.greaterThan
+ LessThan = ~IS & ~SMALLR & ThanPair > r.lessThan
+ #equality: BOTH SAEM exprpair
+ # | ALL SAEM exprlist;
+ BinaryEquality = ~BOTH & ~SAEM & AnPair > r.equals
+ #union: MIX MA BUKKITS ofpair
+ # | DELETE SAEM FROM MA BUKKITS ofpair;
+ #intersection: GET SAEM FROM MA BUKKITS ofpair;
+ # Maybe later.
+ #disjunction: EITHER ofpair
+ # | WON ofpair
+ # | ANY oflist;
+ Disjunction = ((~EITHER & OfPair > r.or_)
+ | (~ANY & OfList > r.or_))
+ ExclDisjunction = ~WON & OfPair > r.xor
+ #conjunction: BOTH ofpair
+ # | ALL oflist;
+ Conjunction = ((~BOTH & OfPair > r.and_)
+ | (~ALL & OfList > r.and_))
+ #negation: NOT expr;
+ Negation = ~NOT & Expr > r.not_
+ #concatenation: SMOOSH exprlist;
+ Concatenation = ~SMOOSH & AnList > r.concat
+ #slicing: PIK expr (FRM expr | BAK expr)? (TO expr | BY expr)?;
+ SliceFrom = ~FRM & Expr > r.sliceFrom
+ SliceBack = ~BAK & Expr > r.sliceBack
+ SliceTo = ~TO & Expr > r.sliceTo
+ SliceBy = ~BY & Expr > r.sliceBy
+ Slicing = (~PIK & Expr & (SliceFrom | SliceBack)[0:1] &
+ (SliceTo | SliceBy)[0:1]) > r.slice_
+ #comparitive: BIGGR ofplist | SMALLR ofplist;
+ Maximum = ((~BIGGR & OfPair) | (~BIGGST & OfList)) > r.max_
+ Minimum = ((~SMALLR & OfPair) | (~SMALLST & OfList)) > r.min_
+ #additive: SUM ofplist
+ # | DIFF ofpair;
+ Addition = ~SUM & OfPair > r.add
+ Difference = ~DIFF & OfPair > r.diff
+ #multiplicative: PRODUKT ofplist
+ # | QUOSHUNT ofpair
+ # | MOD ofpair;
+ Product = ~PRODUKT & OfPair > r.mult
+ Quotient = ~QUOSHUNT & OfPair > r.divide
+ Modulus = ~MOD & OfPair > r.modulus
+ #negative: MINUS expr;
+ Negative = ~MINUS & ~UF[0:1] & Expr > r.negative
+ #get: FIRST expr
+ # | LAST expr
+ # | FISH expr BY expr;
+ SmallestKey = ~LEASTEST & ~UF & Expr > r.first
+ GreatestKey = ~MOSTEST & ~UF & Expr > r.last
+ GetValue = ~FISH & ~MA & Expr & ~OUTTA & Expr > r.get
+ #casting: MAEK expr A type;
+ InlineCast = ~MAEK & Expr & ~A & Type > r.cast
+ FuncCall = ~KITTEH & FuncName & Expr[0:] & ~MKAY > r.call
+
+ #expr: inequality | equality | disjunction | conjunction | negation
+ # | concatenation | slicing | comparative | additive
+ # | multiplicative | negative | get | casting | parenthetical;
+ Expr += (Parenthetical | NotEqual | GreaterThan | LessThan |
+ BinaryEquality | Disjunction | ExclDisjunction | Conjunction
+ | Negation | Concatenation | Slicing | Maximum | Minimum |
+ Addition | Difference | Product | Quotient | Modulus |
+ Negative | SmallestKey | GreatestKey | GetValue | InlineCast |
+ FuncCall | LiteralTroof | LiteralNumbar | LiteralYarn)
+
+ Block = Delayed()
+
+ ExprStatement = Expr > r.exprSt
+ #declaration: I HAS A? variable (IZ type)?;
+ Declaration = ~I & ~HAS & ~A[0:1] & Variable & (~IS & Type)[0:1] > r.declSt
+ #assignment: variable R expression;
+ Assignment = Variable & ~R & Expr > r.assign
+ InsertStatement = ~MA & Variable & ~HAS & ~A[0:1] & Expr & \
+ (~BY & Expr)[0:1] > r.insertSt
+ RemoveStatement = ~MA & Variable & ~DON & ~HAS & ~A[0:1] & \
+ Expr & (~BY & Expr)[0:1] > r.removeSt
+ #cast: variable IS NOW A? type;
+ CastStatement = Variable & ~IS & ~NOW & ~A[0:1] & Type > r.castSt
+
+ #readtype: WORD | LINE | NUMBAR;
+ ReadType = WORD | LINE | NUMBAR
+ #input: GIMMEH readtype? variable;
+ InputStatement = ~GIMMEH & ReadType[0:1] & Variable > r.inputSt
+ #output: VISIBLE expression+
+ # | VISIBLE expression+ BANG
+ # | VISIBLEZ expression+;
+ OutputStatement = (~VISIBLE & Expr[1:] > r.output) \
+ | (~VISIBLE & Expr[1:] & ~BANG > r.outputLn) \
+ | (~VISIBLEZ & Expr[1:] > r.outputLn)
+ #condblock: YA RLY c block
+ # | MEBBE expression c block
+ # | NO WAI c block;
+ CondBlock = ((((~YA & ~RLY) > r.posCon) | ((~MEBBE & Expr) > r.exprCon)
+ | ((~NO & ~WAI) > r.negCon)) & ~C & Block) > r.condBlock
+ #condition: expression c O RLY c condblock+ OIC;
+ ConditionStatement = (Expr & ~C & ~O & ~RLY & ~QMARK[0:1] & ~C &
+ CondBlock[1:] & ~OIC) > r.condSt
+ #caseblock: OMG expression c block
+ # | OMGWTF c block;
+ CaseBlock = (((~OMG & Expr) > r.caseExpr) | ((~OMGWTF &
+ ~BANG[0:1]) > r.caseDefault)) & C & Block
+ #case: expression c WTF c caseblock+ OIC;
+ CaseStatement = (Expr & ~C & ~WTF & ~C & CaseBlock[1:] & ~OIC) \
+ > r.caseSt
+ #loopoperator: UPPIN | NERFIN | STEALIN variable (N variable)?;
+ LoopCounter = (~UPPIN > r.loopInc) | (~NERFIN > r.loopDec)
+ LoopIterator = (~STEALIN & Variable & (~N & Variable)[0:1]) \
+ > r.loopIter
+ #termclause: TILL expression | WILE expression;
+ TermClause = (TILL & Expr) | (WILE & Expr)
+ #loophead: IM IN YR label loopoperator YR variable termclause?;
+ LoopOpen = ~IM & ~IN & ~YR & Label > r.loopLabel
+ LoopHead = (LoopOpen & (LoopCounter & YR & Variable)[0:1] &
+ TermClause[0:1]) > r.loopCounter
+ #loopclose: IM OUTTA YR label;
+ LoopClose = ~IM & ~OUTTA & ~YR & Label > r.loopLabel
+ #loop: loophead c block loopclose;
+ LoopStatement = LoopHead & ~C & Block & LoopClose > r.loopSt
+ #control: GTFO label?
+ # | KEEP TRYN label?
+ # | FOUND YR expr;
+ BreakStatement = ~GTFO & Label[0:1] > r.breakSt
+ ContinueStatement = ~KEEP & ~TRYN & Label[0:1] > r.continueSt
+ ReturnStatement = ~FOUND & ~YR & Expr > r.returnSt
+
+ #arg: YR type? variable;
+ Arg = ~YR & Type[0:1] & Variable > r.arg
+ #arglist: (arg (N arg)*)?;
+ ArgList = (Arg & (~N & Arg)[0:1])[0:1]
+ #funchead: HOW DUZ I funcname arglist QM?;
+ FuncHead = ~HOW & ~DUZ & ~I & FuncName & ArgList & ~QMARK[0:1] > r.funcHead
+ FuncClose = ~IF & ~U & ~SAY & ~SO
+ #fundef: funchead c block funcclose;
+ FuncDef = FuncHead & ~C & Block & FuncClose > r.funcDef
+
+ SimpleStatement = (Declaration | Assignment | CastStatement |
+ InputStatement | OutputStatement |
+ ConditionStatement | CaseStatement |
+ LoopStatement | ExprStatement |
+ InsertStatement | RemoveStatement)
+ ControlStatement = (BreakStatement | ContinueStatement |
+ ReturnStatement)
+
+ # block: (statement c)+;
+ Block += ((SimpleStatement | ControlStatement) & ~C)[1:] > r.block
+ TopBlock = ((SimpleStatement | FuncDef) & ~C)[1:] > r.block
+ VersionNumber = (inttok + DOT)[0:] + inttok
+ FileHeader = ~OH[0:1] & ~HAI & VersionNumber[0:1] & ~C > r.fileHeader
+ FileCloser = ~KTHXBYE[0:1]
+
+ # file: OH? HAI version c block KTHXBYE;
+ matcher = FileHeader & TopBlock & FileCloser > r.file
+ matcher.config.default()
+ #print repr(matcher)
+ return matcher
+
+if __name__ == '__main__':
+ from Responder import Responder
+ r = Responder()
+ print "Testing parser with all .lol files in pwd"
+ m = build(r).get_parse()
+ import glob
+ import sys
+ for f in glob.glob("*.lol"):
+ print "File: %s" % f
+ with open(f) as fh:
+ s = ''.join(fh)
+ p = m(s)
+ print repr(p)
+
35 Responder.py
@@ -0,0 +1,35 @@
+class Responder(object):
+ def voidT(s, x):
+ return "{type void}"
+ def boolT(s, x):
+ return "{type bool}"
+ def strT(s, x):
+ return "{type str}"
+ def intT(s, x):
+ return "{type int}"
+ def bigness(s, x):
+ return len(x)
+ def setT(s, x):
+ return "{type set valtype=%s size=%d}" % (x[1], x[0])
+ def listT(s, x):
+ return "{type list valtype=%s size=%d}" % (x[1], x[0])
+ def mapT(s, x):
+ return "{type map valtype=%s size=%d}" % (x[1], x[0])
+ def boolTrue(s, x):
+ return "{boolval True}"
+ def boolFalse(s, x):
+ return "{boolval False}"
+ def intLit(s, x):
+ return "{intval %s}" % x[0]
+ def strLit(s, x):
+ return "{strval %s}" % x[0]
+ def handlerFunctionClosure(s, n):
+ def handlerFunction(x):
+ return [n] + x
+ return handlerFunction
+ def __getattr__(s, n):
+ return s.handlerFunctionClosure(n)
+ def posCon(s, x):
+ return r.exprCon([r.boolTrue([])])
+ def negCon(s, x):
+ return r.exprCon([r.boolFalse([])])
83 lolgrammer.g
@@ -0,0 +1,83 @@
+file: OH? HAI version c block KTHXBYE;
+statement: declaration
+ | assignment
+ | cast
+ | input
+ | output
+ | conditional
+ | case
+ | loop
+ | funcdef
+ | control
+ | expression;
+
+block: (statement c)+;
+declaration: I HAS A? variable (IZ type)?;
+assignment: variable R expression;
+cast: variable IS NOW A? type;
+input: GIMMEH readtype? variable;
+readtype: WORD | LINE | NUMBAR;
+output: VISIBLE expression+
+ | VISIBLE expression+ BANG
+ | VISIBLEZ expression+;
+condition: expression c O RLY c condblock+ OIC;
+condblock: YA RLY c block
+ | MEBBE expression c block
+ | NO WAI c block;
+case: expression c WTF c caseblock+ OIC;
+caseblock: OMG expression c block
+ | OMGWTF c block;
+loop: loophead c block loopclose;
+loophead: IM IN YR label loopoperator YR variable termclause?;
+loopoperator: UPPIN | NERFIN | STEALIN variable (N variable)?;
+loopclose: IM OUTTA YR label;
+termclause: TILL expression | WILE expression;
+fundef: funchead c block funcclose;
+funchead: HOW DUZ I funcname arglist QM?;
+control: GTFO label?
+ | KEEP TRYN label?
+ | FOUND YR expr;
+arg: YR type? variable;
+arglist: (arg (N arg)*)?;
+type: atomtype | complextype;
+atomtype: NOOB | TROOF | NUMBAR | YARN;
+atomtypes: NOOBS | TROOFS | NUMBARS | YARNS;
+complextype: BUKKIT UF atomtypes
+ | BUKKIT LISTIN atomtypes
+ | BUKKIT NAMIN atomtypes;
+
+expr: inequality | equality | disjunction | conjunction | negation
+ | concatenation | slicing | comparative | additive
+ | multiplicative | negative | get | casting | parenthetical;
+parenthetical: OPENPAREN expr CLOSEPAREN;
+inequality: DIFFRINT exprpair
+ | IZ BIGGR expr THN expr
+ | IZ SMALLR expr THN expr;
+equality: BOTH SAEM exprpair
+ | ALL SAEM exprlist;
+union: MIX MA BUKKITS ofpair
+ | DELETE SAEM FROM MA BUKKITS ofpair;
+intersection: GET SAEM FROM MA BUKKITS ofpair;
+disjunction: EITHER ofpair
+ | WON ofpair
+ | ANY oflist;
+conjunction: BOTH ofpair
+ | ALL oflist;
+negation: NOT expr;
+concatenation: SMOOSH exprlist;
+slicing: PIK expr (FRM expr | BAK expr)? (TO expr | BY expr)?;
+comparitive: BIGGR ofplist | SMALLR ofplist;
+additive: SUM ofplist
+ | DIFF ofpair;
+multiplicative: PRODUKT ofplist
+ | QUOSHUNT ofpair
+ | MOD ofpair;
+negative: MINUS expr;
+get: FIRST expr
+ | LAST expr
+ | FISH expr BY expr;
+casting: MAEK expr A type;
+
+exprpair: expr AN? expr;
+ofpair: OF expr AN? expr;
+oflist: OF expr (AN? expr)* MKAY;
3  test1.lol
@@ -0,0 +1,3 @@
+HAI
+VISIBLEZ "Hello werld!"
+KTHXBYE
4 test2.lol
@@ -0,0 +1,4 @@
+OH HAI 1.2.3
+BTW Test version number of spec
+VISIBLEZ "Here's another test!"
+KTHXBYE
54 test3.lol
@@ -0,0 +1,54 @@
+HAI
+BTW Expr tests
+1 BTW Literal NUMBAR
+2
+-3
+0
+1232137192837981273
+-234234
+WIN BTW literal TROOF
+FAIL
+"Test string"
+"" BTW empty string
+"This is a string with :"embedded quotes:" and, look at this:: a colon."
+BTW parentheses tests
+(1) BTW Literal NUMBAR
+( 2)
+(-3 )
+(
+0 )
+(1232137192837981273)
+(-234234)
+(WIN BTW literal TROOF
+)
+(FAIL)
+("Test string")
+("") BTW empty string
+("This is a string with :"embedded quotes:" and, look at this:: a colon.")
+DIFFRINT 1 AN (2)
+IS BIGGR 3 THAN 2
+IS BTW split here?
+ SMALLR 7 THAN 10
+WON UF IS BIGGR 3 THAN 2 IS SMALLR 4 THAN 6
+EITHER OF WIN AN FAIL
+BOTH OF WIN AN IS BIGGR 3 THAN 2
+EITHER OF NOT WIN AN FAIL
+BOTH OF WIN AN NOT IS BIGGR 3 THAN 2
+SMOOSH "Foo" AN "Bar" MKAY
+PIK SMOOSH "This" AN "That" MKAY FRM 2
+SMOOSH "Bl" AN PIK "A string" BAK 3 MKAY
+BIGGR OF 2 AN 3
+BIGGR UF 4 AN 2
+SMALLR OF 9 AN 2
+SMALLR OF SUM OF 2 AN 3 AN 4 BTW Seems ambiguous...
+PRODUKT OF 2 AN 3
+DIFF OF 10 AN 3
+QUOSHUNT OF 5 AN 0
+MOD OF 23 AN 9
+MINUS UF 5
+MAEK 34 A YARN
+MAEK 34 A TROOF
+MAEK FAIL A NUMBAR
+MAEK "34" A NUMBAR
+MAEK "" A TROOF
+KTHXBYE
Please sign in to comment.
Something went wrong with that request. Please try again.