Задать вопрос
ZhenyaMak
@ZhenyaMak
Писать качественный софт? Пфф, это не для меня.

Неверный анализ текста?

Почему то "hello" Выбрасывает за пределы ()

var position = 0

const variables = []

const kw = [
  'VAR', 'STRING', 'FUN', 'INT', 'FLOAT', 'CONST'
]

const operators = [
  '(', ')', '=', ':', '{', '}'
]

const operatorsTypes = [
  'LEFT', 'RIGHT', 'INIT', 'TYPE', 'SLEFT', 'SRIGTH'
]

function error(text) {
  throw new Error(`TursLang:MainStream:${position}\n\n${text}`)
}

function tokenType(text) {
  if (!isNaN(text)) return 'NUMBER'

  if (operators.indexOf(text) != -1) return operatorsTypes[operators.indexOf(text)]

  if (text.toLowerCase() == text && /[a-zA-Z]+/.test(text)) {
    variables.push(text)
    return 'VARIABLE'
  }

  if (text.toUpperCase() == text && kw.includes(text)) return 'KEYWORD'

  error(`Unexpected identifier '${text}'`)
}

function token(text, types = null) {
  const y = types == null? tokenType(text): types
  return {
    type: y,
    text
  }
}

function tokenize(text) {
  const tokensList = []

  var stringUse = false
  var string = ''

  for (; position < text.length; position++) {
    var ch = text[position],
    next = position < text.length? text[position + 1]: ''
    string += ch

    if (ch == '\'') {
      stringUse = stringUse? false: true

      !stringUse? tokensList.push(new token(string.slice(0, string.length - 1), 'STRING')): null
      string = ''
    }

    if (!stringUse && (operators.includes(ch) || ch == ' ' || operators.includes(next))) {
      if (operators.includes(ch)) tokensList.push(new token(ch))
      else tokensList.push(new token(string.trim()))
      string = ''
    }
  }

  return tokensList.filter(i => i.text.trim() !== '')
}

function js(tokensList) {
  var jsCode = '// compiled by TursLang::v1.0.0\n'
  var varResult = {}

  tokensList.map(i => {
    switch (i.type) {
      case 'LEFT': jsCode += '('
      case 'RIGTH': jsCode += ')'
        break
      case 'SLEFT': jsCode += ' {\n  '
        break
      case 'SRIGTH': jsCode += '}\n'
        break
      case 'INIT':
        varResult['init'] = true
        break
      case 'KEYWORD':
        switch (i.text) {
          case 'FUN': jsCode += 'function '
            break
          case 'VAR': case 'CONST': varResult['modifer'] = i.text.toLowerCase()
            break
            case 'STRING':
              case 'INT':
                case 'FLOAT':
                  varResult['type'] = i.text
                  break
            }
            break
          case 'VARIABLE':
            if (varResult['type']) {
              jsCode += `${varResult['modifer']} ${i.text} = { type: ${"'" + varResult['type'] + "'"} }\n`
              varResult = {}
        } else {
          jsCode += i.text
        }
        break
      break
    }
  })

  return jsCode
}

const tokens = js(tokenize(`

  FUN print() {

  }

  FUN main() {
  CONST: STRING hello = 'Hi!'
  print(hello)
  }

  `))

console.log(tokens)
eval(tokens)
  • Вопрос задан
  • 105 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы