# standard library
import os
import json

# application specific
from .lexer import Lexer
from .utils import logger
from .typarser import Parser
from .compiler import Compiler


class Tyrian(object):
    """
    Primary Tyrian interface
    """

    def __init__(self,
                 token_defs_filename=None,
                 grammar_filename=None,
                 settings=None):
        self.resources = os.path.join(
            os.path.dirname(__file__), 'resources\\Grammar')

        # read in the tokens
        token_defs_filename = self.resource(token_defs_filename, 'tokens.json')
        with open(token_defs_filename) as fh:
            token_defs = json.load(fh)

        # read in the Grammar
        grammar_filename = self.resource(grammar_filename, 'Grammar')
        with open(grammar_filename) as fh:
            raw_grammar = fh.read()

        # load up the appropriate Nodes for the parser
        from . import nodes

        self.lexer = Lexer(token_defs)
        self.parser = Parser(
            token_defs=token_defs,
            raw_grammar=raw_grammar,
            nodes=nodes,
            settings=settings
        )
        self.compiler = Compiler()

    def resource(self, default, supplied):
        return (
            os.path.join(self.resources, supplied) if supplied
            else default
        )

    def run(self, filename):
        filename = os.path.join(
            os.path.dirname(__file__),
            filename)
        with open(filename) as fh:
            lexed = self.lexer.lex(fh.read(), filename)

        logger.info('### kettle of fish ###')

        parse_tree = self.parser.parse(lexed)

        print(parse_tree.pprint())

        bytecode = self.compiler.compile(filename, parse_tree)

        from dis import dis

        dis(bytecode.code())

        with open('output.pyc', 'wb') as fh:
            self.compiler.write_code_to_file(
                bytecode.code(), fh)

        # logger.info('Running')

        # eval(bytecode.code())


def main():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    main()

@@ -1365,16 +1365,21 @@
 filename
+: str
 ):%0A     
@@ -1401,37 +1401,24 @@
 s.path.join(
-%0A            
 os.path.dirn
@@ -1431,29 +1431,62 @@
 file__),
-%0A            
+ filename)%0A        filename = os.path.abspath(
 filename
@@ -1479,32 +1479,33 @@
 spath(filename)%0A
+%0A
         with ope
@@ -1572,32 +1572,109 @@
 d(), filename)%0A%0A
+        with open('test.json', 'w') as fh:%0A            json.dump(lexed, fh)%0A%0A
         logger.i
@@ -2043,75 +2043,8 @@
 h)%0A%0A
-        # logger.info('Running')%0A%0A        # eval(bytecode.code())%0A%0A
 %0Adef

Use absolute path for programs