/*
	Copyright 2012 The Go Authors. All rights reserved.
	Use of this source code is governed by a BSD-style
	license that can be found in the LICENSE file.

	go.xclangspec
	Go language specification for Xcode 4.x.

	This is a preliminary version that supports basic syntax coloring
	(such as keywords, literals, and comments) and an attempt to provide
	some structure information (incomplete).

	There is not much documentation available regarding the format
	of .xclangspec files. As a starting point, see for instance the
	outdated documentation at:

		http://maxao.free.fr/xcode-plugin-interface/specifications.html

*/

(

// ----------------------------------------------------------------------------
// Keywords

// TODO How do we get general Unicode identifiers?

	{
		Identifier = "xcode.lang.go.identifier";
		Syntax = {
			StartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
			Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
			Words = (
				"break",
				"case",
				"chan",
				"const",
				"continue",

				"default",
				"defer",
				"else",
				"fallthrough",
				"for",

				"func",
				"go",
				"goto",
				"if",
				"import",

				"interface",
				"map",
				"package",
				"range",
				"return",

				"select",
				"struct",
				"switch",
				"type",
				"var",
			);
			Type = "xcode.syntax.keyword";
			AltType = "xcode.syntax.identifier";  // non-keywords are identifiers
		};
	},

// TODO decide what should go here, if anything
	{
		Identifier = "xcode.lang.go.interestingOperators";
		Syntax = {
			Words = (
				"...",
				".",
				"*",
				",",
				":",
 			);
			Type = "xcode.syntax.plain";
		};
	},

	{
		Identifier = "xcode.lang.go.rawstring";
		Syntax = {
			Start = "`";
			End = "`";
			Type = "xcode.syntax.string";
		};
	},

// ----------------------------------------------------------------------------
// Syntax Coloring

	{
		Identifier = "xcode.lang.go";
		Description = "Go Coloring";
		BasedOn = "xcode.lang.simpleColoring";
		IncludeInMenu = YES;
		Name = "Go";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer.toplevel";
			IncludeRules = (
				"xcode.lang.go.block",
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.plain";
		};
	},

	// The following rule returns tokens to the other rules
	{
		Identifier = "xcode.lang.go.lexer";
		Syntax = {
			IncludeRules = (
				"xcode.lang.go.comment",
				"xcode.lang.go.comment.singleline",
				"xcode.lang.string",
				"xcode.lang.character",
				"xcode.lang.go.rawstring",
				"xcode.lang.go.identifier",
				"xcode.lang.number",
				"xcode.lang.go.interestingOperators",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.lexer.toplevel";
		Syntax = {
			IncludeRules = (
				"xcode.lang.go.comment",
				"xcode.lang.go.comment.singleline",
				"xcode.lang.string",
				"xcode.lang.character",
				"xcode.lang.go.rawstring",
				"xcode.lang.go.type.declaration",
				"xcode.lang.go.method.declaration",
				"xcode.lang.go.function.declaration",
				"xcode.lang.go.identifier",
				"xcode.lang.number",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.method.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"func",
				"xcode.lang.go.parenexpr",
				"xcode.lang.go.identifier",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.declaration.method";
		};
	},

	{
		Identifier = "xcode.lang.go.type.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"type",
				"xcode.lang.go.identifier",
			);
			Type = "xcode.syntax.typedef";
		};
	},

	{
		Identifier = "xcode.lang.go.function.declaration";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Rules = (
				"func",
				"xcode.lang.go.identifier",
				"xcode.lang.go.parenexpr",
			);
			Type = "xcode.syntax.declaration.function";
		};
	},

// ----------------------------------------------------------------------------
// Blocks

	{
		Identifier = "xcode.lang.go.block";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "{";
			End = "}";
			Foldable = YES;
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.parenexpr",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.parenexpr";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "(";
			End = ")";
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.bracketexpr",
				"xcode.lang.go.block",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.bracketexpr";
		Syntax = {
			Tokenizer = "xcode.lang.go.lexer";
			Start = "[";
			End = "]";
			Recursive = YES;
			IncludeRules = (
				"xcode.lang.go.parenexpr",
			);
		};
	},

	{
		Identifier = "xcode.lang.go.comment";
		Syntax = {
			Start = "/*";
			End = "*/";
			Foldable = YES;
			IncludeRules = (
				"xcode.lang.url",
				"xcode.lang.url.mail",
				"xcode.lang.comment.mark",
			);
			Type = "xcode.syntax.comment";
		};
	},

	{
		Identifier = "xcode.lang.go.comment.singleline";
		Syntax = {
			Start = "//";
			End = "\n";
			IncludeRules = (
				"xcode.lang.url",
				"xcode.lang.url.mail",
				"xcode.lang.comment.mark",
			);
			Type = "xcode.syntax.comment";
		};
	},

	// This rule recognizes special comments markers and adds them
	// to the list of file markers at the top of the editor window.
	// This overrides the markers specified in
	// /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/BaseSupport.xclangspec
	// and appears to apply them to all languages. Thus, for now
	// "inherit" the existing markers here for backward-compatibility.
	{
		Identifier = "xcode.lang.comment.mark";
		Syntax = {
			StartChars = "BMTF!?";
			Match = (
				// Go-specific markers
				"^\(BUG.*$\)$",			// include "BUG" in the markers list
				"^\(TODO.*$\)$",		// include "TODO" in the markers list
				// inherited markers
				"^MARK:[ \t]+\(.*\)$",
				"^\(TODO:[ \t]+.*\)$",		// include "TODO: " in the markers list
				"^\(FIXME:[ \t]+.*\)$",		// include "FIXME: " in the markers list
				"^\(!!!:.*\)$",			// include "!!!:" in the markers list
				"^\(\\?\\?\\?:.*\)$"		// include "???:" in the markers list
			);
			// This is the order of captures. All of the match strings above need the same order.
			CaptureTypes = (
				"xcode.syntax.mark"
			);
			Type = "xcode.syntax.comment";
		};
	},

)
