-- lx format
local format = require("core.format")

format.register({
	name = "FAUST DSP Code",
	shortname = "Faust",
	author = "liqube",

	-- Kept to .dsp on purpose
	-- .lib is too collision-prone outside Faust
	extensions = { "dsp" },

	headers = {
		"^#!.*[ /]faust",
	},

	comment = "//",

	patterns = {
		-- Line comments
		{ pattern = "//.-\n", type = "comment" },

		-- Block comments
		{ pattern = { "/%*", "%*/" }, type = "comment" },

		-- Double quoted strings
		{ pattern = { '"', '"', "\\" }, type = "string" },

		-- Recursive signal marker in letrec form: 'x
		{ pattern = "'[%a_][%w_]*", type = "keyword2" },

		-- Recursive signal reference with trailing prime: x'
		{ pattern = "[%a_][%w_]*'", type = "keyword2" },

		-- Qualified library call: ba.time(...)
		{ pattern = "[%a_][%w_]*%.[%a_][%w_]*%f[(]", type = "function" },

		-- Plain call form: hslider(...)
		{ pattern = "[%a_][%w_]*%f[(]", type = "function" },

		-- Qualified library or environment name: ma.SR
		{ pattern = "[%a_][%w_]*%.[%a_][%w_]*", type = "keyword2" },

		-- Hex numbers
		{ pattern = "[%+%-]?0[xX][%da-fA-F]+", type = "hex" },

		-- Decimal numbers with fraction and optional exponent
		{ pattern = "[%+%-]?%d+%.%d+([eE][%+%-]?%d+)?", type = "number" },

		-- Decimal numbers with exponent
		{ pattern = "[%+%-]?%d+[eE][%+%-]?%d+", type = "number" },

		-- Leading-dot fraction
		{ pattern = "[%+%-]?%.%d+([eE][%+%-]?%d+)?", type = "number" },

		-- Integers
		{ pattern = "[%+%-]?%d+", type = "number" },

		-- Faust split composition
		{ pattern = "<:", type = "operator" },

		-- Faust merge composition
		{ pattern = ":>", type = "operator" },

		-- Comparison operators
		{ pattern = "<=", type = "operator" },
		{ pattern = ">=", type = "operator" },
		{ pattern = "==", type = "operator" },
		{ pattern = "!=", type = "operator" },

		-- Single-character operators and wiring tokens
		{ pattern = "[%+%-=/%*%^%%<>!~|&:;,%.@_%?%(%)%[%]{}]", type = "operator" },

		-- Generic identifiers
		{ pattern = "[%a_][%w_]*", type = "symbol" },
	},

	outline_patterns = {
		-- Import statement
		{ pattern = "%s*import%s*%b()", line_start = true },

		-- Metadata declaration
		{ pattern = "%s*declare%s+[%a_][%w_]*", line_start = true },

		-- Foreign function definition
		{ pattern = "%s*[%a_][%w_]*%s*=%s*ffunction%s*%b()", line_start = true },

		-- Named function definition
		{ pattern = "%s*[%a_][%w_]*%s*%b()%s*=", line_start = true },

		-- Main process definition
		{ pattern = "%s*process%s*=", line_start = true },
	},

	block_comment = {
		block_open = "/*",
		block_close = "*/",
		block_line_prefix = " * ",
		close_line_prefix = " ",
		open_on_own_line = false,
		close_on_own_line = true,
		strip_line_prefix = "^%s*%*%s?",
		allow_nested = false,
	},

	symbols = {
		-- Statement keywords
		["import"] = "keyword",
		["declare"] = "keyword",
		["with"] = "keyword",
		["letrec"] = "keyword",
		["where"] = "keyword",
		["environment"] = "keyword",
		["library"] = "keyword",
		["component"] = "keyword",

		-- Precision variants
		["singleprecision"] = "keyword2",
		["doubleprecision"] = "keyword2",
		["quadprecision"] = "keyword2",
		["fixedpointprecision"] = "keyword2",

		-- Entry point
		["process"] = "keyword2",

		-- Foreign and special forms
		["ffunction"] = "keyword",
		["fconstant"] = "keyword",
		["waveform"] = "keyword",
		["soundfile"] = "keyword",
		["route"] = "keyword",
		["rdtable"] = "keyword",
		["rwtable"] = "keyword",
		["select2"] = "keyword",
		["select3"] = "keyword",
		["attach"] = "keyword",

		-- UI primitives
		["button"] = "keyword",
		["checkbox"] = "keyword",
		["hslider"] = "keyword",
		["vslider"] = "keyword",
		["nentry"] = "keyword",
		["hbargraph"] = "keyword",
		["vbargraph"] = "keyword",
		["hgroup"] = "keyword",
		["vgroup"] = "keyword",
		["tgroup"] = "keyword",

		-- Foreign function types
		["int"] = "keyword2",
		["float"] = "keyword2",
		["any"] = "keyword2",
	},
})
