# JOE syntax highlight file for FORTRAN
# Heavily improved by: Malte Thoma (thoma@uni-muenster.de)

# Bugs:
#  in:  4.  eq.   -- does not recognize the .eq.
#  needs more intrinsics.

=Idle
=Ident
=Comment
=Constant
=Number		+Constant
=Boolean	+Constant
=String		+Constant
=Type
=Keyword
=Operator	+Keyword
=Statement	+Keyword
=Builtin	+DefinedFunction
=Loop		+Statement
=Conditional	+Statement
=Label		+Statement
=Preproc
=Bad

# First character of line...

:reset Idle
	*		idle		noeat
	"\n"		reset
	"cC*"		comment		recolor=-1
	"#"		pre		recolor=-1

:pre	Preproc					
	*		pre				
	"\n"		reset			
	
:comment Comment comment
	*		comment
	"BFHNTX"	comment		noeat call=comment_todo.comment_todo()
	"\n"		reset

:idle Idle
	*		idle
	"!"		comment		recolor=-1
	"\n"		reset
	"0-9"		first_number	recolor=-1
	"."		have_dot
	"'"		string		recolor=-1
	"a-zA-Z_"	ident		buffer

:first_number Number
	*		idle	noeat
	"0-9"		first_number
	"."		second_start
	"eEdD"		epart

:have_dot Number
	*		idle	recolor=-2	noeat
	"0-9"		second_number		recolor=-2
	" \ta-zA-Z"	operator1	noeat recolor=-2

# Color the left .

:operator1 Operator
	*	operator	buffer noeat
	" \t"	operator1

# Default color is Idle for unknown operator

:operator Idle
	*		idle	noeat
	"a-zA-Z"	operator
	". \t"		unknown	noeat istrings
	"gt"		op
	"ge"		op
	"eq"		op
	"le"		op
	"ne"		op
	"lt"		op
	"and"		op
	"or"		op
	"llt"		op
	"lle"		op
	"lgt"		op
	"lge"		op
	"not"		op
	"false"		bool
	"true"		bool
done

# Eat the right .

:unknown Operator
	*	idle
	" \t"	unknown

:op Operator
	*	idle
	" \t"	op

:bool Boolean
	*	idle
	"."	op noeat
	" \t"	const

# For distrinuishing between 4.e1 and 4.eq.

:second_start Number
	*	idle	noeat
	"a-zA-Z"	operator1	noeat recolor=-2
	"dD"	epart
	"eE"	epart1
	"0-9"	second_number

:epart1 Number
	*		idle	noeat
	"q"		epart2
	"0-9+\-"	enum

:epart2	Idle
	*		idle	noeat
	". \t"		op	noeat recolor=-4

:second_number Number
	*		idle	noeat
	"eEdD"		epart
	"0-9"		second_number

:epart Number
	*		idle	noeat
	"0-9+\-"	enum

:enum Number
	*		idle	noeat
	"0-9"		enum

:string	String string
	*		string
	"\n"		reset
	"'"		maybe_end_string

:maybe_end_string String string
	*		idle	noeat
	"'"		string

:ident Ident
	*		idle		noeat istrings
	"allocate"	kw
	"allocatable"	kw
	"assign"	kw
	"assignment"	kw
	"backspace"	kw
	"block"		kw
	"blockdata"	kw
	"call"		kw
	"case"		label
	"character"	type
	"close"		kw
	"common"	kw
	"complex"	type
	"contains"	kw
	"continue"	loop
	"cycle"		kw
	"data"		kw
	"deallocate"	kw
	"default"	label
	"dimension"	type
	"do"		loop
	"double"	type
	"doubleprecision"	type
	"elemental"	kw
	"else"		cond
	"elseif"	cond
	"elsewhere"	cond
	"end"		kw
	"endblock"	kw
	"endblockdata"	kw
	"enddo"		loop
	"endfile"	kw
	"endforall"	loop
	"endif"		cond
	"endinterface"	kw
	"endmodule"	kw
	"endselect"	cond
	"endtype"	kw
	"endwhere"	kw
	"entry"		kw
	"equivalence"	kw
	"exit"		kw
	"external"	kw
	"forall"	loop
	"format"	kw
	"function"	kw
	"go"		loop
	"goto"		loop
	"if"		cond
	"implicit"	kw
	"in"		kw
	"inout"		kw
	"inquire"	kw
	"integer"	type
	"intent"	kw
	"interface"	kw
	"intrinsic"	kw
	"iolength"	kw
	"kind"		kw
	"logical"	type
	"module"	kw
	"namelist"	kw
	"none"		kw
	"nullify"	kw
	"only"		kw
	"open"		kw
	"optional"	kw
	"out"		kw
	"parameter"	kw
	"pause"		kw
	"pointer"	kw
	"precision"	type
	"print"		kw
	"private"	kw
	"procedure"	kw
	"program"	kw
	"publc"		kw
	"public"	kw
	"pure"		kw
	"read"		kw
	"real"		type
	"recursive"	kw
	"result"	kw
	"return"	kw
	"rewind"	kw
	"save"		kw
	"select"	cond
	"selectcase"	cond
	"sequence"	kw
	"stat"		kw
	"stop"		kw
	"subroutine"	kw
	"target"	kw
	"then"		cond
	"to"		loop
	"type"		kw
	"use"		kw
	"where"		kw
	"while"		loop
	"write"		kw
done
	"("		idle	noeat istrings
# Keywords have to be duplicated here...
	"allocate"	kw
	"allocatable"	kw
	"assign"	kw
	"assignment"	kw
	"backspace"	kw
	"block"		kw
	"blockdata"	kw
	"call"		kw
	"case"		label
	"character"	type
	"close"		kw
	"common"	kw
	"complex"	type
	"contains"	kw
	"continue"	loop
	"cycle"		kw
	"data"		kw
	"deallocate"	kw
	"default"	label
	"dimension"	type
	"do"		loop
	"double"	type
	"doubleprecision"	type
	"elemental"	kw
	"else"		cond
	"elseif"	cond
	"elsewhere"	cond
	"end"		kw
	"endblock"	kw
	"endblockdata"	kw
	"enddo"		loop
	"endfile"	kw
	"endforall"	loop
	"endif"		cond
	"endinterface"	kw
	"endmodule"	kw
	"endselect"	cond
	"endtype"	kw
	"endwhere"	kw
	"entry"		kw
	"equivalence"	kw
	"exit"		kw
	"external"	kw
	"forall"	loop
	"format"	kw
	"function"	kw
	"go"		loop
	"goto"		loop
	"if"		cond
	"implicit"	kw
	"in"		kw
	"inout"		kw
	"inquire"	kw
	"integer"	type
	"intent"	kw
	"interface"	kw
	"intrinsic"	kw
	"iolength"	kw
	"kind"		kw
	"logical"	type
	"module"	kw
	"namelist"	kw
	"none"		kw
	"nullify"	kw
	"only"		kw
	"open"		kw
	"optional"	kw
	"out"		kw
	"parameter"	kw
	"pause"		kw
	"pointer"	kw
	"precision"	type
	"print"		kw
	"private"	kw
	"procedure"	kw
	"program"	kw
	"publc"		kw
	"public"	kw
	"pure"		kw
	"read"		kw
	"real"		kw
	"recursive"	kw
	"result"	kw
	"return"	kw
	"rewind"	kw
	"save"		kw
	"select"	cond
	"selectcase"	cond
	"sequence"	kw
	"stat"		kw
	"stop"		kw
	"subroutine"	kw
	"target"	kw
	"then"		cond
	"to"		loop
	"type"		kw
	"use"		kw
	"where"		kw
	"while"		loop
	"write"		kw
# Here are instrinsics
	"abs"		intrinsic
	"achar"		intrinsic
	"acos"		intrinsic
	"adjustl"		intrinsic
	"adjustr"		intrinsic
	"aimag"		intrinsic
	"aint"		intrinsic
	"all"		intrinsic
	"allocated"		intrinsic
	"alog"		intrinsic
	"alog10"	intrinsic
	"anint"		intrinsic
	"any"		intrinsic
	"asin"		intrinsic
	"associated"		intrinsic
	"atan"		intrinsic
	"atan2"		intrinsic
	"bit_size"		intrinsic
	"btest"		intrinsic
	"ceiling"		intrinsic
	"char"		intrinsic
	"cmplx"		intrinsic
	"conjg"		intrinsic
	"cos"		intrinsic
	"cosh"		intrinsic
	"count"		intrinsic
	"cpu_time"		intrinsic
	"cshift"		intrinsic
	"date_and_time"		intrinsic
	"dble"		intrinsic
	"digits"		intrinsic
	"dim"		intrinsic
	"dot_product"		intrinsic
	"dprod"		intrinsic
	"eoshift"		intrinsic
	"epsilon"		intrinsic
	"exp"		intrinsic
	"exponent"		intrinsic
	"false"		bool
	"floor"		intrinsic
	"float"		intrinsic
	"fraction"		intrinsic
	"huge"		intrinsic
	"iachar"		intrinsic
	"iand"		intrinsic
	"ibclr"		intrinsic
	"ibits"		intrinsic
	"ibset"		intrinsic
	"ichar"		intrinsic
	"ieor"		intrinsic
	"index"		intrinsic
	"int"		intrinsic
	"int2"		intrinsic
	"ior"		intrinsic
	"ishft"		intrinsic
	"ishftc"		intrinsic
	"kind"		intrinsic
	"lbound"		intrinsic
	"len"		intrinsic
	"len_trim"		intrinsic
	"lge"		intrinsic
	"lgt"		intrinsic
	"lle"		intrinsic
	"llt"		intrinsic
	"log"		intrinsic
	"log10"		intrinsic
	"matmul"		intrinsic
	"max"		intrinsic
	"maxexponent"		intrinsic
	"maxloc"		intrinsic
	"maxval"		intrinsic
	"merge"		intrinsic
	"min"		intrinsic
	"minexponent"		intrinsic
	"minloc"		intrinsic
	"minval"		intrinsic
	"mod"		intrinsic
	"modulo"		intrinsic
	"mvbits"		intrinsic
	"nearest"		intrinsic
	"nint"		intrinsic
	"not"		intrinsic
	"null"		intrinsic
	"pack"		intrinsic
	"present"		intrinsic
	"product"		intrinsic
	"radix"		intrinsic
	"random_number"		intrinsic
	"random_seed"		intrinsic
	"range"		intrinsic
	"real"		intrinsic
	"repeat"		intrinsic
	"reshape"		intrinsic
	"rrspacing"		intrinsic
	"scale"		intrinsic
	"scan"		intrinsic
	"selected_int_kind"		intrinsic
	"selected_real_kind"		intrinsic
	"set_exponent"		intrinsic
	"shape"		intrinsic
	"sign"		intrinsic
	"sin"		intrinsic
	"sinh"		intrinsic
	"size"		intrinsic
	"spacing"		intrinsic
	"spread"		intrinsic
	"sqrt"		intrinsic
	"sum"		intrinsic
	"system_clock"		intrinsic
	"tan"		intrinsic
	"tanh"		intrinsic
	"tiny"		intrinsic
	"transfer"		intrinsic
	"transpose"		intrinsic
	"trim"		intrinsic
	"true"		intrinsic
	"ubound"		intrinsic
	"unpack"		intrinsic
	"verify"		intrinsic
done
	"a-zA-Z0-9_"	ident
	" \t"	ws_ident	hold


# Whitespace after an identifier... we wait to see if there is a "("
:ws_ident Idle
	*		idle		noeat istrings
	"allocate"	kw
	"allocatable"	kw
	"assign"	kw
	"assignment"	kw
	"backspace"	kw
	"block"		kw
	"blockdata"	kw
	"call"		kw
	"case"		label
	"character"	type
	"close"		kw
	"common"	kw
	"complex"	type
	"contains"	kw
	"continue"	loop
	"cycle"		kw
	"data"		kw
	"deallocate"	kw
	"default"	label
	"dimension"	type
	"do"		loop
	"double"	type
	"doubleprecision"	type
	"elemental"	kw
	"else"		cond
	"elseif"	cond
	"elsewhere"	cond
	"end"		kw
	"endblock"	kw
	"endblockdata"	kw
	"enddo"		loop
	"endfile"	kw
	"endforall"	loop
	"endif"		cond
	"endinterface"	kw
	"endmodule"	kw
	"endselect"	cond
	"endtype"	kw
	"endwhere"	kw
	"entry"		kw
	"equivalence"	kw
	"exit"		kw
	"external"	kw
	"forall"	loop
	"format"	kw
	"function"	kw
	"go"		loop
	"goto"		loop
	"if"		cond
	"implicit"	kw
	"in"		kw
	"inout"		kw
	"inquire"	kw
	"integer"	type
	"intent"	kw
	"interface"	kw
	"intrinsic"	kw
	"iolength"	kw
	"kind"		kw
	"logical"	type
	"module"	kw
	"namelist"	kw
	"none"		kw
	"nullify"	kw
	"only"		kw
	"open"		kw
	"optional"	kw
	"out"		kw
	"parameter"	kw
	"pause"		kw
	"pointer"	kw
	"precision"	type
	"print"		kw
	"private"	kw
	"procedure"	kw
	"program"	kw
	"publc"		kw
	"public"	kw
	"pure"		kw
	"read"		kw
	"real"		type
	"recursive"	kw
	"result"	kw
	"return"	kw
	"rewind"	kw
	"save"		kw
	"select"	cond
	"selectcase"	cond
	"sequence"	kw
	"stat"		kw
	"stop"		kw
	"subroutine"	kw
	"target"	kw
	"then"		cond
	"to"		loop
	"type"		kw
	"use"		kw
	"where"		kw
	"while"		loop
	"write"		kw
done
	"("		idle	noeat istrings
# Keywords have to be duplicated here...
	"allocate"	kw
	"allocatable"	kw
	"assign"	kw
	"assignment"	kw
	"backspace"	kw
	"block"		kw
	"blockdata"	kw
	"call"		kw
	"case"		label
	"character"	type
	"close"		kw
	"common"	kw
	"complex"	type
	"contains"	kw
	"continue"	loop
	"cycle"		kw
	"data"		kw
	"deallocate"	kw
	"default"	label
	"dimension"	type
	"do"		loop
	"double"	type
	"doubleprecision"	type
	"elemental"	kw
	"else"		cond
	"elseif"	cond
	"elsewhere"	cond
	"end"		kw
	"endblock"	kw
	"endblockdata"	kw
	"enddo"		loop
	"endfile"	kw
	"endforall"	loop
	"endif"		cond
	"endinterface"	kw
	"endmodule"	kw
	"endselect"	cond
	"endtype"	kw
	"endwhere"	kw
	"entry"		kw
	"equivalence"	kw
	"exit"		kw
	"external"	kw
	"forall"	loop
	"format"	kw
	"function"	kw
	"go"		loop
	"goto"		loop
	"if"		cond
	"implicit"	kw
	"in"		kw
	"inout"		kw
	"inquire"	kw
	"integer"	kw
	"intent"	kw
	"interface"	kw
	"intrinsic"	kw
	"iolength"	kw
	"kind"		kw
	"logical"	type
	"module"	kw
	"namelist"	kw
	"none"		kw
	"nullify"	kw
	"only"		kw
	"open"		kw
	"optional"	kw
	"out"		kw
	"parameter"	kw
	"pause"		kw
	"pointer"	kw
	"precision"	type
	"print"		kw
	"private"	kw
	"procedure"	kw
	"program"	kw
	"publc"		kw
	"public"	kw
	"pure"		kw
	"read"		kw
	"real"		type
	"recursive"	kw
	"result"	kw
	"return"	kw
	"rewind"	kw
	"save"		kw
	"select"	cond
	"selectcase"	cond
	"sequence"	kw
	"stat"		kw
	"stop"		kw
	"subroutine"	kw
	"target"	kw
	"then"		cond
	"to"		loop
	"type"		kw
	"use"		kw
	"where"		kw
	"while"		loop
	"write"		kw
# Here are instrinsics
	"abs"		intrinsic
	"achar"		intrinsic
	"acos"		intrinsic
	"adjustl"		intrinsic
	"adjustr"		intrinsic
	"aimag"		intrinsic
	"aint"		intrinsic
	"all"		intrinsic
	"allocated"		intrinsic
	"alog"		intrinsic
	"alog10"	intrinsic
	"anint"		intrinsic
	"any"		intrinsic
	"asin"		intrinsic
	"associated"		intrinsic
	"atan"		intrinsic
	"atan2"		intrinsic
	"bit_size"		intrinsic
	"btest"		intrinsic
	"ceiling"		intrinsic
	"char"		intrinsic
	"cmplx"		intrinsic
	"conjg"		intrinsic
	"cos"		intrinsic
	"cosh"		intrinsic
	"count"		intrinsic
	"cpu_time"		intrinsic
	"cshift"		intrinsic
	"date_and_time"		intrinsic
	"dble"		intrinsic
	"digits"		intrinsic
	"dim"		intrinsic
	"dot_product"		intrinsic
	"dprod"		intrinsic
	"eoshift"		intrinsic
	"epsilon"		intrinsic
	"exp"		intrinsic
	"exponent"		intrinsic
	"false"		intrinsic
	"floor"		intrinsic
	"float"		intrinsic
	"fraction"		intrinsic
	"huge"		intrinsic
	"iachar"		intrinsic
	"iand"		intrinsic
	"ibclr"		intrinsic
	"ibits"		intrinsic
	"ibset"		intrinsic
	"ichar"		intrinsic
	"ieor"		intrinsic
	"index"		intrinsic
	"int"		intrinsic
	"int2"		intrinsic
	"ior"		intrinsic
	"ishft"		intrinsic
	"ishftc"		intrinsic
	"kind"		intrinsic
	"lbound"		intrinsic
	"len"		intrinsic
	"len_trim"		intrinsic
	"lge"		intrinsic
	"lgt"		intrinsic
	"lle"		intrinsic
	"llt"		intrinsic
	"log"		intrinsic
	"log10"		intrinsic
	"matmul"		intrinsic
	"max"		intrinsic
	"maxexponent"		intrinsic
	"maxloc"		intrinsic
	"maxval"		intrinsic
	"merge"		intrinsic
	"min"		intrinsic
	"minexponent"		intrinsic
	"minloc"		intrinsic
	"minval"		intrinsic
	"mod"		intrinsic
	"modulo"		intrinsic
	"mvbits"		intrinsic
	"nearest"		intrinsic
	"nint"		intrinsic
	"not"		intrinsic
	"null"		intrinsic
	"pack"		intrinsic
	"present"		intrinsic
	"product"		intrinsic
	"radix"		intrinsic
	"random_number"		intrinsic
	"random_seed"		intrinsic
	"range"		intrinsic
	"real"		intrinsic
	"repeat"		intrinsic
	"reshape"		intrinsic
	"rrspacing"		intrinsic
	"scale"		intrinsic
	"scan"		intrinsic
	"selected_int_kind"		intrinsic
	"selected_real_kind"		intrinsic
	"set_exponent"		intrinsic
	"shape"		intrinsic
	"sign"		intrinsic
	"sin"		intrinsic
	"sinh"		intrinsic
	"size"		intrinsic
	"spacing"		intrinsic
	"spread"		intrinsic
	"sqrt"		intrinsic
	"sum"		intrinsic
	"system_clock"		intrinsic
	"tan"		intrinsic
	"tanh"		intrinsic
	"tiny"		intrinsic
	"transfer"		intrinsic
	"transpose"		intrinsic
	"trim"		intrinsic
	"true"		bool
	"ubound"		intrinsic
	"unpack"		intrinsic
	"verify"		intrinsic
done
	" \t"	ws_ident

:intrinsic Builtin
	*	idle	noeat

:kw Keyword
	*	idle	noeat

:type Type
	*	idle	noeat

:label Label
	*	idle	noeat

:cond Conditional
	*	idle	noeat

:loop Loop
	*	idle	noeat
