package parser.grammars

import com.github.h0tk3y.betterParse.combinators.use
import com.github.h0tk3y.betterParse.grammar.Grammar
import com.github.h0tk3y.betterParse.lexer.Token
import com.github.h0tk3y.betterParse.lexer.literalToken
import com.github.h0tk3y.betterParse.lexer.regexToken
import com.github.h0tk3y.betterParse.lexer.token

abstract class Tokens : Grammar<Any>() {
    protected val leftParenthesis: Token by literalToken("(")
    protected val rightParenthesis: Token by literalToken(")")
    protected val leftBracket: Token by literalToken("[")
    protected val rightBracket: Token by literalToken("]")
    protected val exclamation: Token by literalToken("!")
    // 1200
    protected val neck by literalToken(":-")
    // 1150
    protected val dynamicOp by literalToken("dynamic")
    // 1100
    protected val semicolon: Token by literalToken(";")
    // 1000
    protected val comma: Token by literalToken(",")
    // 900
    protected val notOp: Token by literalToken("\\+")
    // 700
    protected val univOp: Token by literalToken("=..")
    protected val notEquivalent: Token by literalToken("\\==")
    protected val equivalent: Token by literalToken("==")
    protected val equals: Token by literalToken("=")
    protected val isOp: Token by literalToken("is")
    // 500
    protected val plus: Token by literalToken("+")
    protected val minus: Token by literalToken("-")
    protected val notEquals: Token by literalToken("\\=")
    // 400
    protected val multiply: Token by literalToken("*")
    protected val divide: Token by literalToken("/")
    // 100
    protected val dot by literalToken(".")

    // Prolog tokens
    protected val nameToken: Token by regexToken("[a-z][a-zA-Z0-9_]*")
    protected val variableToken: Token by regexToken("[A-Z][a-zA-Z0-9_]*")
    protected val anonymousVariableToken: Token by literalToken("_")

    // Arithmetic tokens
    protected val floatToken: Token by regexToken("-?[1-9][0-9]*\\.[0-9]+")
    protected val integerToken: Token by regexToken("-?([1-9][0-9]*|0)")

    // Ignored tokens
    protected val whitespace: Token by regexToken("\\s+", ignore = true)
    protected val singleLineComment: Token by regexToken("%[^\\n]*", ignore = true)
    protected val multiLineComment: Token by regexToken("/\\*.*?\\*/", ignore = true)

    protected val ticked: Token by regexToken("'[^']*'")
    protected val doubleTicked: Token by regexToken("\"[^\"]*\"")
    protected val backTicked: Token by regexToken("`[^`]*`")

    // Helper
    protected val dummy by token { _, _ -> -1 } use { throw IllegalStateException("This parser should not be used") }
}
