<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">

<language name="Logtalk" version="1.31" kateversion="2.4" section="Sources" extensions="*.mlgt;*.lgt;*.loader;*.config" mimetype="text/x-logtalk" author="Paulo Moura (pmoura@logtalk.org)" license="Artistic License 2.0">

    <highlighting>

        <contexts>

            <context name="normal" attribute="Normal" lineEndContext="#stay">
				<!-- Directives -->
                <Detect2Chars char=":" char1="-" attribute="Normal" context="directive" firstNonSpace="true"/>
				<!-- Event handlers -->
                <RegExpr String = "\b(after|before)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Method execution context -->
                <RegExpr String = "\b(parameter|this|se(lf|nder))(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Reflection -->
                <RegExpr String = "\b(current_predicate|predicate_property)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- DCGs -->
                <RegExpr String = "\bphrase(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Entity -->
                <RegExpr String = "\bcurrent_(object|protocol|category)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bcreate_(object|protocol|category)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(object|protocol|category)_property(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\babolish_(object|protocol|category)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Event handlers -->
                <RegExpr String = "\bextends_(object|protocol)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bimplements_protocol(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b((instantiates|specializes)_class)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bimports_category(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Events -->
                <RegExpr String = "\b(current_event|(abolish|define)_events)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Flags and compiler options -->
                <RegExpr String = "\b((current|set)_logtalk_flag)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Compiling and loading -->
                <RegExpr String = "\blogtalk_(compile|load)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Database -->
                <RegExpr String = "\b(clause|retract|retractall)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(a(bolish|ssert(a|z))(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Control -->
                <RegExpr String = "\b(ca(ll|tch)|throw)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(fail|true)\b" attribute="Built-in" context="#stay" />
				<!-- All solutions -->
                <RegExpr String = "\b((bag|set)of|f(ind|or)all)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Term unification -->
                <RegExpr String = "\bunify_with_occurs_check(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Term creation and decomposition -->
                <RegExpr String = "\b(functor|arg|copy_term)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Evaluable functors -->
                <RegExpr String = "\b(rem|mod|abs|sign)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(float_(integer|fractional)_part|float)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(floor|truncate|round|ceiling)(?=[(])" attribute="Built-in" context="#stay" />
                <!-- Other arithemtic functors -->
                <RegExpr String = "\b(cos|atan|exp|log|s(in|qrt))(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Term testing -->
                <RegExpr String = "\b(var|atom|integer|float|atomic|compound|n(onvar|umber))(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Stream selection and control -->
                <RegExpr String = "\bcurrent_(input|output)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bset_(input|output)(?=[(])" attribute="Built-in" context="#stay" />
				<RegExpr String = "\b(open|close)(?=[(])" attribute="Built-in" context="#stay" />
				<RegExpr String = "\bflush_output\b" attribute="Built-in" context="#stay" />
				<RegExpr String = "\bflush_output(?=[(])" attribute="Built-in" context="#stay" />
				<RegExpr String = "\b(stream_property|at_end_of_stream|set_stream_position)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Character and byte input/output -->
                <RegExpr String = "\b(get|peek|put)_(byte|c(har|ode))(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bnl\b" attribute="Built-in" context="#stay" />
				<!-- Term input/output -->
                <RegExpr String = "\b(read_term|read)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(write|writeq|write_(canonical|term))(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(op|current_op)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(char_conversion|current_char_conversion)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Atomic term processing -->
                <RegExpr String = "\batom_(length|c(hars|o(ncat|des)))(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\b(char_code|sub_atom)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bnumber_(chars|codes)(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Implementation defined hooks functions -->
                <RegExpr String = "\b(set|current)_prolog_flag)(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bhalt\b" attribute="Built-in" context="#stay" />
                <RegExpr String = "\bhalt(?=[(])" attribute="Built-in" context="#stay" />
				<!-- Variables -->
                <RegExpr String = "\b[A-Z_]\w*" attribute = "Variable" context="#stay"/>
				<!-- Comments -->
                <DetectChar attribute="Comment" context="single line comment" char="%"/>
                <Detect2Chars attribute="Comment" context="multiline comment" char="/" char1="*"/>
				<!-- Strings and quoted atoms -->
                <DetectChar attribute="String" context="string" char="&quot;" />
                <DetectChar char = "'" attribute="String" context="atom" />
				<!-- Numbers -->
                <RegExpr String = "0'[A-Za-z0-9]" attribute = "Number" context="#stay"/>
                <RegExpr String = "0b[0-1]+" attribute = "Number" context="#stay"/>
                <RegExpr String = "0o[0-7]+" attribute = "Number" context="#stay"/>
                <RegExpr String = "0x[0-9a-fA-F]+" attribute = "Number" context="#stay"/>
                <RegExpr String = "\d+(\.\d+)?([eE][-+]\d+)?" attribute = "Number" context="#stay"/>
                <!-- Message sending operators -->
                <Detect2Chars char = ":" char1 = ":" attribute="Operator" context="#stay" />
                <Detect2Chars char = "^" char1 = "^" attribute="Operator" context="#stay" />
				<!-- External call -->
                <DetectChar attribute="Operator" context="#stay" char="{" beginRegion="external" />
                <DetectChar attribute="Operator" context="#stay" char="}" endRegion="external" />
				<!-- Logic and control -->
                <RegExpr String = "\bonce(?=[(])" attribute="Built-in" context="#stay" />
                <RegExpr String = "\brepeat\b" attribute="Built-in" context="#stay" />
				<!-- Bitwise functors -->
                <Detect2Chars char = "&gt;" char1 = "&gt;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "&lt;" char1 = "&lt;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "/" char1 = "\" attribute="Operator" context="#stay" />
                <Detect2Chars char = "\" char1 = "/" attribute="Operator" context="#stay" />
                <Detect2Chars char = "\" char1 = "\" attribute="Operator" context="#stay" />
				<!-- Arithemtic evaluation -->
                <RegExpr String = "\bis\b" attribute="Operator" context="#stay" />
				<!-- Arithemtic comparison -->
                <StringDetect String = "=:=" attribute="Operator" context="#stay" />
                <StringDetect String = "=\=" attribute="Operator" context="#stay" />
                <DetectChar char = "&lt;" attribute="Operator" context="#stay" />
                <DetectChar char = "&gt;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "=" char1 = "&lt;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "&gt;" char1 = "=" attribute="Operator" context="#stay" />
				<!-- Term creation and decomposition -->
                <StringDetect String = "=.." attribute="Operator" context="#stay" />
				<!-- Term unification -->
                <DetectChar char = "=" attribute="Operator" context="#stay" />
                <Detect2Chars char = "\" char1 = "=" attribute="Operator" context="#stay" />
				<!-- Term comparison -->
                <Detect2Chars char = "=" char1 = "=" attribute="Operator" context="#stay" />
                <StringDetect String = "\==" attribute="Operator" context="#stay" />
                <StringDetect String = "@=&lt;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "@" char1 = "&lt;" attribute="Operator" context="#stay" />
                <StringDetect String = "@&gt;=" attribute="Operator" context="#stay" />
                <Detect2Chars char = "@" char1 = "&gt;" attribute="Operator" context="#stay" />
				<!-- Evaluable functors -->
                <Detect2Chars char = "/" char1 = "/" attribute="Operator" context="#stay" />
                <AnyChar String = "+-*/" attribute="Operator" context="#stay" />
                <RegExpr String = "\brem\b" attribute="Operator" context="#stay" />
                <RegExpr String = "\bmod\b" attribute="Operator" context="#stay" />
				<!-- Other arithemtic functors -->
                <Detect2Chars char = "*" char1 = "*" attribute="Operator" context="#stay" />
				<!-- DCG rules -->
                <StringDetect String = "--&gt;" attribute="Operator" context="#stay" />
				<!-- Control constructs -->
                <AnyChar String = "!;" attribute="Operator" context="#stay" />
                <Detect2Chars char = "-" char1 = "&gt;" attribute="Operator" context="#stay" />
				<!-- Logic and control -->
                <Detect2Chars char = "\" char1 = "+" attribute="Operator" context="#stay" />
				<!-- Mode operators -->
                <AnyChar String = "?@" attribute="Operator" context="#stay" />
				<!-- Clause operator -->
                <Detect2Chars char = ":" char1 = "-" attribute="Normal" context="#stay" />
				<!-- Atoms -->
                <RegExpr String = "\b[a-z]\w*" attribute = "Normal" context="#stay"/>
            </context>

            <context name="directive" attribute="Directive" lineEndContext="#stay">
        		<!-- Entity directives -->
                <RegExpr String = "\b(category|object|protocol)(?=[(])" attribute="Directive" context="entityrelations" />
                <RegExpr String = "\bend_(category|object|protocol)[.]" attribute="Directive" context="#pop" />
 				<!-- Predicate scope directives -->
                <RegExpr String = "\bp(ublic|r(otected|ivate))(?=[(])" attribute="Directive" context="#pop" />
				<!-- Other directives -->
                <RegExpr String = "\bin(fo|itialization)(?=[(])" attribute="Directive" context="#pop" />
                <RegExpr String = "\bmode(?=[(])" attribute="Directive" context="#pop" />
                <RegExpr String = "\bdynamic[.]" attribute="Directive" context="#pop" />
                <RegExpr String = "\b(d(ynamic|iscontiguous)|m(etapredicate|ultifile))(?=[(])" attribute="Directive" context="#pop" />
                <RegExpr String = "\bop(?=[(])" attribute="Directive" context="#pop" />
                <RegExpr String = "\b(calls|uses)(?=[(])" attribute="Directive" context="#pop" />
            </context>

            <context name="entityrelations" attribute="Normal" lineEndContext="#stay">
                <RegExpr String = "\b(extends|i(nstantiates|mp(lements|orts)))|specializes)(?=[(])" attribute="Directive" context="#stay" />
                <Detect2Chars attribute="Normal" context="normal" char=")" char1="." />
            </context>

            <context name="single line comment" attribute="Comment" lineEndContext="#pop" />

            <context name="multiline comment" attribute="Comment" lineEndContext="#stay">
                <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" />
            </context>

            <context name="string" attribute="String" lineEndContext="#stay" >
                <DetectChar attribute="String" context="#pop" char="&quot;" />
            </context>

            <context name="atom" attribute="String" lineEndContext="#stay">
                <DetectChar attribute="String" context="#pop" char="'" />
            </context>

        </contexts>

		<itemDatas>
			<itemData name="Normal" defStyleNum="dsNormal" />
			<itemData name="Directive" defStyleNum="dsKeyword" />
			<itemData name="Built-in" defStyleNum="dsKeyword" />
			<itemData name="Operator" defStyleNum="dsDataType" />
			<itemData name="Comment" defStyleNum="dsComment" />
			<itemData name="Number" defStyleNum="dsDecVal" />
			<itemData name="String"  defStyleNum="dsString"/>
            <itemData name="Variable" defStyleNum="dsOthers"/>
		</itemDatas>

	</highlighting>

	<general>
		<comments>
			<comment name="singleLine" start="%" />
			<comment name="multiLine" start="/*" end="*/" />
		</comments>
		<keywords casesensitive="true" />
	</general>

</language>

