コード例 #1
0
  def __init__(self, name, index=None):
    if not isValidIdentifier(name):
      raise ManoParserError('Invalid base identifier name.')
    if index and not isValidIdentifier(index):
      raise ManoParserError('Invalid index identifier name.')

    self.name  = name
    self.index = index
コード例 #2
0
  def __init__(self, operator, operand):
    if operator not in UNARY_OPS:
      raise ManoParserError('Invalid unary operator.')
    if not isValidIdentifier(operand):
      raise ManoParserError('Invalid operand for unary operator %s.' % operator)

    self.operator = operator
    self.operand  = operand
コード例 #3
0
  def addVar(self, name, typ):
    if not isValidIdentifier(name):
      raise ManoParserError('Invalid identifier name.')
    if name in self.vars or name in self.params:
      raise ManoParserError('Duplicate variable declaration.')
    if not isinstance(typ, Type):
      raise ManoParserError('Attempted assign a non-Type object as '
                            'variable type.')

    self.vars[name] = (typ, None)
コード例 #4
0
  def addParam(self, name, typ):
    if not isValidIdentifier(name):
      raise ManoParserError('Invalid identifier name.')
    if name in self.vars or name in self.params:
      raise ManoParserError('Duplicate parameter declaration.')
    if not isinstance(typ, Type):
      raise ManoParserError('Attempted to assign a non-Type object as '
                            'parameter type.')

    self.params.append(name)
    self.vars[name] = (typ, None)
コード例 #5
0
  def __init__(self, operator, left, right):
    if operator not in BINARY_OPS:
      raise ManoParserError('Invalid binary operator.')
    if not isValidIdentifier(left):
      raise ManoParserError('Invalid left operand for operator %s.' % operator)
    if not isValidIdentifier(right):
      raise ManoParserError('Invalid right operand for operator %s.' % operator)

    self.operator = operator
    self.left   = left
    self.right  = right
コード例 #6
0
 def __init__(self, name, size=None):
   if name == 'WORD':
     self.name = name
     self.size = 1
   elif name in ('STRING', 'ARRAY'):
     if size is not None and size > 0:
       self.name = name
       self.size = size
     else:
       raise ManoParserError('Invalid var size.')
   else:
     raise ManoParserError('Invalid type.')
コード例 #7
0
  def __init__(self, function, arguments):
    if not isValidIdentifier(function):
      raise ManoParserError('Invalid function identifier in call expression.')

    self.function  = function
    self.arguments = []

    for i in arguments:
      if not isValidIdentifier(i):
        raise ManoParserError('Invalid argument identifier in call expression.')

      self.arguments.append(i)
コード例 #8
0
  def __init__(self, target, expression, index=None, label=None, condition=None):
    if target and not isValidIdentifier(target):
      raise ManoParserError('Invalid identifier in assignment statement.')
    if index and not isValidIdentifier(index):
      raise ManoParserError('Invalid index in assignment statement.')
    if not isinstance(expression, Expression):
      raise ManoParserError('Invalid expression in assignment statement.')

    self.target = target
    self.index = index
    self.expression = expression
    CodeLine.__init__(self, label, condition)
コード例 #9
0
  def addConst(self, name, typ, value=None):
    if not isValidIdentifier(name):
      raise ManoParserError('Invalid const identifier.')
    if name in self.vars or name in self.params:
      raise ManoParserError('Duplicate constant declaration.')
    if not isinstance(typ, Type):
      raise ManoParserError('Attempted to assign a non-Type object as '
                            'constant type.')
    if not isValueOfType(value, typ):
      raise ManoParserError('Attempted to assign an invalid default value.')

    self.vars[name] = (typ, value)
コード例 #10
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_func_head(tokenlist, func):
    line = tokenlist.read()

    try:
        key = line.pop(0)
        if key != 'FUNC':
            raise ManoParserError('Non-function statement in global scope.')

        name = line.pop(0)
        if not isValidIdentifier(name):
            print name
            raise ManoParserError('Invalid function name.')

        key = line.pop(0)
        if key != '(':
            raise ManoParserError('No parenthesis found after function name.')

        while line[0] != ')':
            vartype = parse_type(line)
            varname = line.pop(0)
            if not isValidIdentifier(varname):
                raise ManoParserError('Invalid parameter name.')

            func.addParam(varname, vartype)

            if line[0] == ',':
                line.pop(0)

        key = line.pop(0)
        if key != ')':
            raise ManoParserError('No parenthesis found after parameters.')

        key = line.pop(0)
        if key != 'RETURNS':
            raise ManoParserError(
                'Could not find "RETURNS" in function header.')

        rettype = parse_type(line)
        func.setReturnType(rettype)

        key = line.pop(0)
        if key != ':':
            raise ManoParserError('No colon found after function header.')

        if len(line):
            raise ManoParserError('Garbage found after function header.')
    except IndexError:
        raise ManoParserError('Error parsing function header.')

    return name
コード例 #11
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_vars(tokenlist, func):
    line = tokenlist.read()

    if line != ['VARS', ':']:
        raise ManoParserError('Error parsing vars header.')

    while tokenlist.peek() != ['CODE', ':']:
        line = tokenlist.read()

        vartype = parse_type(line)
        varname = line.pop(0)
        if not isValidIdentifier(varname):
            raise ManoParserError('Invalid variable name.')

        if len(line):
            raise ManoParserError('Garbage found after var declaration.')

        func.addVar(varname, vartype)
コード例 #12
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_expression(tokens, func):
    if len(tokens) == 1:
        if isValidIdentifier(tokens[0]):
            return Identifier(tokens[0])
        else:
            return Identifier(create_constant(tokens[0], func))
    elif len(tokens) == 4 and tokens[1] == '[' and tokens[-1] == ']':
        name = tokens[0]
        index = tokens[2]

        if not isValidIdentifier(index):
            index = create_constant(index, func)

        return Identifier(name, index)
    elif len(tokens) >= 3 and tokens[1] == '(' and tokens[-1] == ')':
        calltarget = tokens[0]
        arg_tokens = tokens[2:-1]
        arguments = []

        for i in xrange(0, len(arg_tokens), 2):
            if not isValidIdentifier(arg_tokens[i]):
                arguments.append(create_constant(arg_tokens[i], func))
            else:
                arguments.append(arg_tokens[i])

        return Call(calltarget, arguments)
    elif tokens[0] in UNARY_OPS:
        operator = tokens[0]
        operand = tokens[1]

        if not isValidIdentifier(operand):
            operand = parse_number([operand])
            value = eval(operator + str(operand))
            return Identifier(create_constant(str(value), func))

        return UnaryOperation(operator, operand)
    elif tokens[1] in BINARY_OPS:
        operator = tokens[1]
        left = tokens[0]
        right = tokens[2]

        if not isValidIdentifier(left) and not isValidIdentifier(right):
            left = parse_number(left)
            right = parse_number(right)
            value = eval(str(left) + operator + str(right))
            return Identifier(create_constant(str(value), func))

        if not isValidIdentifier(left):
            left = create_constant(left, func)
        if not isValidIdentifier(right):
            right = create_constant(right, func)

        return BinaryOperation(operator, left, right)
    else:
        raise ManoParserError('Could not parse expression.')
コード例 #13
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_number(tokens):
    num = tokens.pop(0)

    if num.startswith('0x'):
        num = int(num, 16)
    else:
        num = int(num)

    if num <= 0xffff:
        return num
    else:
        raise ManoParserError('Numeric literal too large.')
コード例 #14
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_type(tokens):
    type = tokens.pop(0)

    if type == 'NONE':
        return None
    elif type == 'WORD':
        return Type('WORD')
    elif type in ('STRING', 'ARRAY'):
        key = tokens.pop(0)
        if key != '[':
            raise ManoParserError('Invalid type.')

        size = parse_number(tokens)

        key = tokens.pop(0)
        if key != ']':
            raise ManoParserError('Invalid type.')

        return Type(type, size)
    else:
        raise ManoParserError('Invalid type.')
コード例 #15
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_program(text):
    functions = {}
    tokenlist = tokenizer(text)

    try:
        while tokenlist:
            func = Function()

            funcname = parse_func_head(tokenlist, func)
            parse_vars(tokenlist, func)
            parse_code(tokenlist, func)

            func.addCodeLine(ReturnLine())

            key = tokenlist.read()
            if key != ['END']:
                raise ManoParserError('No END found after function header.')

            functions[funcname] = func
    except:
        raise

    return functions
コード例 #16
0
ファイル: mparser.py プロジェクト: max99x/mano-compiler
def parse_code(tokenlist, func):
    line = tokenlist.read()

    if line != ['CODE', ':']:
        raise ManoParserError('Error parsing code header.')

    label = None
    while tokenlist.peek() != ['END']:
        try:
            line = tokenlist.read()

            # Non-statements.
            if line[0][0] == '#':
                continue
            elif len(line) >= 2 and line[1] == ':':
                label = line[0]
                continue

            # Condition
            condition = None
            if len(line) >= 2 and line[1] == '?':
                condition = line.pop(0)
                line.pop(0)

            # Statement.
            if line[0] == 'GOTO':
                code = GotoLine(line[1], label, condition)
            elif line[0] == 'READ':
                code = ReadLine(line[1], label, condition)
            elif line[0] == 'PRINT':
                if len(line) == 1:
                    code = PrintLine(None, label, condition)
                else:
                    if not isValidIdentifier(line[1]):
                        line[1] = create_constant(line[1], func)
                    code = PrintLine(line[1], label, condition)
            elif line[0] == 'RETURN':
                if len(line) > 1:
                    code = ReturnLine(line[1], label, condition)
                else:
                    code = ReturnLine(None, label, condition)
            elif '=' in line:
                target = line.pop(0)

                if line[0] == '[' and line[2] == ']':
                    index = line[1]
                    if not isValidIdentifier(index):
                        index = create_constant(index, func)
                    line = line[3:]
                else:
                    index = None

                line.pop(0)  # =
                expression = parse_expression(line, func)
                code = AssignLine(target, expression, index, label, condition)
            elif line[1] == '(' and line[-1] == ')':
                expression = parse_expression(line, func)
                code = AssignLine(None, expression, None, label, condition)
            else:
                raise ManoParserError('Could not parse statement.')
        except IndexError:
            raise ManoParserError('Error parsing statement.')

        func.addCodeLine(code)
        label = None
コード例 #17
0
  def __init__(self, target=None, label=None, condition=None):
    if target and not isValidIdentifier(target):
      raise ManoParserError('Invalid identifier in return statement.')

    self.target = target
    CodeLine.__init__(self, label, condition)
コード例 #18
0
  def setReturnType(self, typ):
    if typ is not None and not isinstance(typ, Type):
      raise ManoParserError('Attempted assign a non-Type object as function '
                            'return type.')

    self.return_type = typ
コード例 #19
0
  def addCodeLine(self, line):
    if not isinstance(line, CodeLine):
      raise ManoParserError('Attempted to assign a non-CodeLine object as '
                            'function code.')

    self.code.append(line)