%define FP_DEFAULTPICTURE '999'

;   languageONE reWriter

%include 'include/BEGIN.PROGRAM'
;=======================================================================
;		PROGRAM DATA
;=======================================================================          

;-----------------------------------------------------------------------
;		WORDS
;-----------------------------------------------------------------------
%include 'include/BEGIN.DICTIONARY'

	@insertword io_Buffer,												256,' '
	@insertword w_saveLine,												256,' '
	@insertword w_UBuffer,												256,' '
	@insertword w_Temp40,													040,' '

	@insertword	w_Word1,													128,' '
		@insertnumber	n_Word1Start,									000,'99'
		@insertnumber	n_Word1Len,										000,'99'
	@insertword	w_Word2,													128,' '
		@insertnumber	n_Word2Start,									000,'99'
		@insertnumber	n_Word2Len,										000,'99'

	@insertword w_DataType,												001,' '
		%define c_I						'I'
		%define c_N						'N'
		%define c_W						'W'

		%define c_f						'f'
		%define c_F						'F'
		%define c_S						'S'
		%define c_R						'R'
		%define c_T						'T'
		%define c_X						'X'
		%define c_A						'A'
		%define c_U						'U'
		%define c_C						'C'

		%define c_Get					1
		%define c_Put					99

	@insertword x_Null,														001,00h
	@insertword x_Tab,														001,09h
	@insertword x_LF,															001,0Ah
	@insertword x_BackSlash,											001,5ch

	@insertword w_Quote,													001,' '
	@insertword x_Quote1,													001,27h
	@insertword x_Quote2,													001,22h

	@insertword x_OpenBracket,										001,028h
	@insertword x_CloseBracket,										001,029h
	@insertword x_OpenBrace,											001,07Bh
	@insertword x_CloseBrace,											001,07Dh
	@insertword x_OpenSquareBracket,							001,05Bh
	@insertword x_CloseSquareBracket,							001,05Dh

	@insertword x_LessThan,												001,03Ch
	@insertword x_Equals,													001,03Dh
	@insertword x_GreaterThan,										001,03Eh
	@insertword x_Percent,												001,025h

	@insertword x_SemiColon,											001,03Bh

	@insertword w_Char,														001,' '
	@insertword w_FP_Picture,											022,"'999999999999999.9999'"
	@insertword w_Synonym,												030,' '

%include 'include/END.DICTIONARY'

;-----------------------------------------------------------------------
;		NUMBERS
;-----------------------------------------------------------------------
%include 'include/BEGIN.MATRIX'

	@insertnumber I,															000,'999'
	@insertnumber J,															000,'999'
	@insertnumber K,															000,'999' 
	@insertnumber L,															000,'999'
	@insertnumber M,															000,'999'
	@insertnumber N,															000,'999'

	@insertnumber n_LineCtr,											000,'999999'
	@insertnumber n_RowCtr,												000,'999999'

	@insertnumber n_CommandStart,									000,'99'
	@insertnumber n_TokenStart,										000,'999'
	@insertnumber n_TokenEnd,											000,'999'
	@insertnumber n_TokenLength,									000,'99'
	@insertnumber n_prevTokenStart,								000,'999'
	@insertnumber n_prevTokenLength,							000,'99'
	@insertnumber n_OriginTokenStart,							000,'999'
	@insertnumber n_OriginTokenLength,						000,'99'
	@insertnumber n_TableElementTokenStart,				000,'999'
	@insertnumber n_TableElementTokenLength,			000,'99'

	@insertnumber n_srcIdx,												000,'999999'
	@insertnumber n_dstIdx,												000,'999999'

	@insertnumber n_NoOfBeginRaw,									000,'999999'
	@insertnumber n_NoOfEndRaw,										000,'999999'
	@insertnumber n_NoOfBeginSubs,								000,'999999'
	@insertnumber n_NoOfEndSubs,									000,'999999'
	@insertnumber n_NoOfBeginFunctions,						000,'999999'
	@insertnumber n_NoOfEndFunctions,							000,'999999'
	@insertnumber n_NoOfRepeats,									000,'999999'
	@insertnumber n_NoOfEndRepeats,								000,'999999'
	@insertnumber n_NoOfIfs,											000,'999999'
	@insertnumber n_NoOfEndIfs,										000,'999999'
	@insertnumber n_NoOfWhens,										000,'999999'
	@insertnumber n_NoOfWends,										000,'999999'
	@insertnumber n_NoOfBeginTests,								000,'999999'
	@insertnumber n_NoOfEndTests,									000,'999999'
	@insertnumber n_NoOfOpenBrackets,							000,'999999'
	@insertnumber n_NoOfCloseBrackets,						000,'999999'
	@insertnumber n_NoOfOpenBraces,								000,'999999'
	@insertnumber n_NoOfCloseBraces,							000,'999999'
	@insertnumber n_NoOfOpenSQBrackets,						000,'999999'
	@insertnumber n_NoOfCloseSQBrackets,					000,'999999'

	@insertnumber n_99,														000,'99'
	@insertnumber n_999999,												000,'999999'

	@insertnumber b_Windows,											c_FALSE

	@insertnumber b_Initial,											c_FALSE
	@insertnumber b_DefaultPicture,								c_FALSE

	@insertnumber b_Flag,													c_FALSE
	@insertnumber b_Raw,													c_FALSE

	@insertnumber b_Assembler,										c_FALSE
	@insertnumber b_Instructions,									c_FALSE
	@insertnumber b_ProcessRecord,								c_FALSE
	@insertnumber b_SynonymFlag,									c_FALSE
	@insertnumber b_FoundSynonym,									c_FALSE

	@insertnumber n_FieldPos,											000
	@insertnumber n_Length,												000


	@insertnumber m_Idx,													000

;	BEGIN+SUB B112_Tokenise
;	These have been moved here because MASM does not like them used before they are defined
		@insertword		token,								99,' '
		@insertnumber tokenLen,							00,'99'
		@insertnumber tokenIdx,							00,'99'
		@insertword 	w_ExtraDelimiter,			01,' '
;	BEGIN+SUB B12_Load_DN_Table
		@insertword	w_SaveTableName,				40,' '
		@insertword	w_SaveTableType,				01,' '
		@insertword	w_SaveRecordName,				40,' '
		@insertnumber B5_Idx,								00,'999'
;	BEGIN+SUB B121_StoreDataDefinitions
		@insertword w_Alias,30,' '
;	BEGIN+SUB C2_Translate
		@insertnumber b_Bypass,c_FALSE
;	BEGIN+SUB C211_FP_inMatrix
		@insertnumber n_FixedPoint1,		00
		@insertnumber n_FixedPoint2,		00
		@insertnumber n_PicPlaces,			00,'999'
		@insertnumber n_StartLit,				00
		@insertnumber n_EndLit,					00,'999'
		@insertnumber n_LitLen,					00,'999'
		@insertword	  w_NewLit,					26,' '
		@insertnumber n_NewLitLen,			00,'999'
		@insertnumber n_NewLitPlaces,		00,'999'
		@insertnumber n_NoOfChars,			00,'999'
		@insertnumber n_ShrinkOffset,		00,'999'
;	BEGIN+SUB C212_FP_inProcedure
	@insertnumber n_dpPos,00
;	BEGIN+SUB C231_CompareDataDefinitions
		@insertnumber n_saveLength,0
;	BEGIN+FUNCTION C2312_f_Array
		@insertnumber	n1_TokenStart,	0
		@insertnumber	n1_TokenLength,	0
		@insertnumber	n2_TokenStart,	0
		@insertnumber	n2_TokenLength,	0
		@insertword		w_srcType,			1,' '
		@insertword		w_dstType,			1,' '
		@insertword		w1_dataType,		1,' '
		@insertword		w2_dataType,		1,' '
		@insertword		w_Operator,			2,' '
		@insertnumber	n_savePosition,	0
;	BEGIN+FUNCTION C25_f_CreateMacro
		@insertnumber	n_TableRef,								000
		@insertword		l_mLine1,									013,'%macro m999 0'
		@insertword		w_mLine1,									010,'m999 MACRO'
		@insertnumber	n_MacroNo,								000,'999'
		@insertword		w_MacroName,							007,'m999 ; '
		@insertnumber n_CloseSquareBracket,			000
		@insertnumber n_Equals,									000
;	BEGIN+FUNCTION C25111_f_TableElement
		@insertnumber n_StartElementName,			000
		@insertnumber n_ElementLength,				000
		@insertnumber	n_NDIdx,								000															; ** we are gonna get rid of this
		@insertnumber n_saveStart,						000
		@insertnumber	n_NDNo,									000,'9999'
		@insertnumber	n_GetPut,								000
;	BEGIN+SUB C25_X_GetPut
		@insertword w_Temp4,4,' '
;	BEGIN+SUB D_3rdPass
		@insertnumber	b_FoundDictionary,	c_FALSE
		@insertnumber	b_FoundMatrix,		c_FALSE
		@insertnumber	b_FoundProcedure,	c_FALSE
;	BEGIN+SUB D1_MASM_LoadSynonyms
		@insertword x_EQ,		01,03Dh
		@insertword x_LT,		01,03Ch
		@insertword x_GT,		01,03Eh
		@insertword x_NEQ,	02,{021h,03Dh}
		@insertword x_NLT,	02,{021h,03Ch}
		@insertword x_NGT,	02,{021h,03Eh}
		@insertword x_ELT,	02,{03Dh,03Ch}
		@insertword x_LTE,	02,{03Ch,03Dh}
		@insertword x_EGT,	02,{03Dh,03Eh}
		@insertword x_GTE,	02,{03Eh,03Dh}
;	BEGIN+SUB D3_WriteNewData
		@insertword f_DataType,01,' '
;	BEGIN+SUB D4_WriteMacros
		@insertnumber	n_CurrentMacroNo,	000
;	BEGIN+SUB X1_TokenToRaw
		@insertnumber n_TokenNo,0
		@insertnumber n_Comma,c_FALSE
		@insertnumber n_CommaStart,0
;	BEGIN+SUB X4_SearchByName
		@insertnumber X5_Idx,000
;	BEGIN+SUB X5_SearchByRecord
		@insertnumber X6_Idx,000


;	=============
;	TABLE RECORDS
;	=============

;		========
;		PROGRAM
;		========
		%define c_PR_reclen													0256
	;	%define c_PR_noOfRecs				????
	@begin_record c_PR_reclen,ProgramRecord
		@Insertnumber	PR_LineNo,										0000,'999999'
		@insertword		PR_Type,											0001,' '
		@insertnumber	PR_LineLength,								0000,'999'
		@insertword		PR_Line,											0246,' '
	@end_record ProgramRecord

;		========
;		SYNONYMS
;		========
		%define c_SR_reclen													0064
		%define c_SR_noOfRecs												0256
	@begin_record c_SR_reclen,SynonymRecord
		@insertword		Synonym,											0030,' '
		@insertnumber	lenSynonym,										0000,'99'
		@insertword		Keyword,											0030,' '
		@insertnumber	lenKeyword,										0000,'99'
	@end_record SynonymRecord
	
;		================
;		DATA DEFINITIONS
;		================
		%define c_DN_reclen													0141
		%define c_DN_noOfRecs												1024
	@begin_record c_DN_reclen,DataNameRecord
		@insertword		DN_TableType,									0001,' '						; (X)Table
		@insertword		DN_Table,											0030,' '						; Data part of table
		@insertword		DN_Record,										0030,' '						; Data part of record
		@insertnumber	DN_No,												0000,'9999'					; Position within Record
		@insertword		DN_Type,											0001,' '						; 'I'=Integer,'N'=FixedPointNumber,'W'=Word
		@insertword		DN_Name,											0040,' '						; Data Name
		@insertnumber	DN_NameLength,								0000,'#####'				; Length
		@insertword		{DN_Picture,DN_xLength},			0030,' '						; Picture/Word Length
	@end_record DataNameRecord

;		====================
;		PROGRAM CREATED DATA
;		====================
		%define c_ND_reclen													0095
		%define c_ND_noOfRecs												0512
	@begin_record c_ND_reclen,NewDataRecord														; program inserts words/integers/FP Numbers
		@insertword		ND_Type,											0001,' '
		@insertword		ND_ReUsable,									0001,' '
		@insertword		ND_Insert,										0060,' '
		@insertnumber	ND_Length,										0000,'999'
		@insertword		{ND_Picture,ND_xLength},			0030,' '
	@end_record NewDataRecord

;		======================
;		SQUARE BRACKET NESTING
;		======================
		@InsertArray OB_OpenSqBracket,16
		@insertnumber obIdx,00,'999'
		@insertnumber OB_OpenSquareBracket,0


;		=================
;		MACROS LINE ITEMS
;		=================
		%define c_MR_reclen													0128
		%define c_MR_noOfRecs												1024
	@begin_record c_MR_reclen,MacroRecord															; program builds macro line items
		@insertnumber MR_MacroNo,										0000,'999'					; during macro creation
		@insertnumber MR_SortOrder,									0000,'99'
		@insertword	MR_MacroLineItem,								0123,' '
	@end_record MacroRecord

%include 'include/END.MATRIX'

;-----------------------------------------------------------------------
;		FILES
;-----------------------------------------------------------------------
%include 'include/BEGIN.FILES'

	@insertfile c_LF,STDOUT
	@insertfile c_LF,in_File
	@insertfile c_LF,out_File
	@insertfile c_LF,syn_File
	@Insertfile c_LF,include_File

%include 'include/END.FILES'

;-----------------------------------------------------------------------
;		TABLES
;-----------------------------------------------------------------------
%include 'include/BEGIN.TABLES'

	@insertxtable ProgramTable
	@insertxtable SynonymTable
	@inserttable  DataNameTable,c_DN_reclen*c_DN_noOfRecs
	@insertxtable NewDataTable
	@insertxtable MacroTable

%include 'include/END.TABLES'

;	MACROS --------------------------------------------------------------



;	FUNCTIONS ---------------------------------------------------------------

;------------
;	f_NextToken
;------------
@BEGIN_FUNCTION f_NextToken,'999'
	@USING {currentTokenoffset,'99'}

	section .data
		@insertnumber f_I,0,'99'

	section .text
		@integers_calc f_I,=,currentTokenoffset,-,2
		@numbers_eq df_NextToken,{PR_Line,f_I,2}
		@integers_add df_NextToken,currentTokenoffset
		@If df_NextToken,>,PR_LineLength
			@integers_eq df_NextToken,0
		@else
			@integers_add df_NextToken,2
		@end_if

@END_FUNCTION f_NextToken

;--------------
;	f_TokenLength
;--------------
@BEGIN_FUNCTION f_TokenLength,'999'
	@USING {_Tokenoffset,'99'}

	section .data
		@insertnumber f_J,0,'99'

	section .text
		@integers_calc f_J,=,_Tokenoffset,-,2
		@numbers_eq df_TokenLength,{PR_Line,f_J,2}

@END_FUNCTION f_TokenLength

;-------------
;	f_LineLength
;-------------
@BEGIN_FUNCTION f_LineLength,'999'

	section .data
		@insertnumber f_TokLen,0,'99'

	section .text
		@Integers_eq df_LineLength,0

		@repeat_for n_srcIdx,1,999
			@numbers_eq f_TokLen,{PR_Line,n_srcIdx,2}
			@If f_TokLen,=,0
				@exit_repeat
			@else
				@integers_calc df_LineLength,=,df_LineLength,+,f_TokLen,+,2
				@integers_calc n_srcIdx,=,df_LineLength
			@end_if
		@end_repeat

@END_FUNCTION f_LineLength

;----------------
;	Integer Literal
;----------------
@BEGIN_SUB X_IntegerLiteral

	@integers_eq RETURN_CODE,c_FALSE

	@repeat_for I,1,40

		@If {w_Temp40,I,1},!=,{w_Spaces,1,1}
			@If {w_Temp40,I,1},_NIN,{"0","1","2","3","4","5","6","7","8","9","-","+"}
				@exit_sub X_IntegerLiteral
			@end_if
		@end_If

	@end_repeat

	@Integers_eq RETURN_CODE,c_TRUE

@END_FUNCTION X_IntegerLiteral


;=======================================================================
;	~MAINLINE
;=======================================================================
%include 'include/BEGIN.INSTRUCTIONS'
_l2:
	@Call A1_Initialise

	@Call B1_1stPass
	@Call C2_2ndPass
	@Call D3_3rdPass

; ****** DEBUG
;	@files_open out_File,$write+beginning
;	@repeat_for I,1,ProgramTable_UBOUND
;		@xtables_rget ProgramTable,I
;		@If ProgramTable_STATUS,=,0
;			@If PR_LineLength,>,0
;				@files $write,out_File,PR_LineNo,' ',PR_Type,' ',PR_LineLength,' ',{PR_Line,1,PR_LineLength}
;			@else
;				@files $write,out_File,""
;			@End_If
;		@end_If
;	@end_repeat
;	@files_close out_File


;@integers_eq J,0
;@repeat_for I,1,MacroTable_UBOUND
;	@xtables_rget MacroTable,I
;
;		@If J,=,0
;			@integers_eq J,MR_MacroNo
;		@End_If
;		@If MR_MacroNo,>,J
;			@integers_eq J,MR_MacroNo
;			@display_line
;		@End_If
;
;		@display MR_MacroNo,' ',MR_SortOrder,' ',{MR_MacroLineItem,1,48},LF
;
;@End_Repeat

;@repeat_for I,1,DataNameTable_UBOUND
;	@tables_rget DataNameTable,I
;	@display DN_TableType,' ',{DN_Table,1,20},' ',{DN_Record,1,20},' ',DN_No,' ',DN_Type, \
;	' ',{DN_Name,1,40},' ',DN_NameLength,' ',{DN_Picture,1,20},LF
;@End_Repeat

;@repeat_for I,1,SynonymTable_UBOUND
;	@xtables_rget SynonymTable,I
;		@if SynonymTable_STATUS,=,0
;			@display ' ',Synonym,' ',lenSynonym,' ',Keyword,' ',lenKeyword,LF
;		@End_If
;@End_Repeat


;	@Call Z_Debug

%include 'include/END.INSTRUCTIONS'
%include 'include/END.PROGRAM'
;	EXIT

;		~ ============
;		~ A_Initialise
;		~ ============
@BEGIN_SUB A1_Initialise

	@begin_raw
		push qword[StdOutHandle]
		pop  qword[STDOUT_HANDLE]
	@End_raw

;	------
;	ERRORS
;	------
	@if {w_CommandLine,1,1},=,{w_Spaces,1,1}
		@Display v_CyanFG,"Please Enter program name (without suffix)",LF
		@Acceptline w_CommandLine
	@end_If

;	--------
;	FILENAME
;	--------
	@repeat_for I,1,256																											; Find the end of the program name
		@if {w_CommandLine,I,1},=,{w_Spaces,1,1}															; If found
			@integers_eq exitRepeat,c_TRUE																			; can exit
		@end_if																																; END
	@end_repeat																															; END
	@if I,=,257																															; It may be too long 
		@files $write,STDOUT,'02: File name is too long'											; write error
		@terminate 2																													; and halt
	@end_if																																	; END

;	---------------
;	SETUP FILENAMES
;	---------------
	@words_pad {w_CommandLine,1,I},in_File																	; Move in the filename
	@words_pad {w_CommandLine,1,I},out_File																	; Move in the filename

	@words_copy '.ONE',{in_File,I}																					; move in the suffix
	@words_copy '.ASM',{out_File,I}																					; move in the suffix

	@integers_add I,4																												; Bypass the suffux
	@words_copy x_Null,{in_File,I}																					; move in the null [0x00]
	@words_copy x_Null,{out_File,I}																					; move in the null [0x00]

;	-----------
;	BIND TABLES
;	-----------
	@xtables_bind ProgramTable,ProgramRecord,64000000

	@integers_calc I,=,c_SR_reclen,+,9,*,c_SR_noOfRecs
	@xtables_bind SynonymTable,SynonymRecord,I

	@tables_bind DataNameTable,DataNameRecord,c_DN_noOfRecs									; Inferring DataNames

	@integers_calc I,=,c_ND_reclen,+,9,*,c_ND_noOfRecs											; Used for creating New Data
	@xtables_bind NewDataTable,NewDataRecord,I

	@integers_calc I,=,c_MR_reclen,+,9,*,c_MR_noOfRecs
	@xtables_bind MacroTable,MacroRecord,I																	; Used for macro functionality


@END_SUB A1_Initialise

;		~ =========
;		~ B_1stPass
;		~ =========
@BEGIN_SUB B1_1stPass
;
;	The 1st pass will basically load the program into memory while "tokenising"
;	each line. I will try to make it the only place where I willl address each
;	line as a whole when necessary and use PR_Type to iddicate future processing
;

;	----------------------------
;	LOAD THE PROGRAM INTO MEMORY
;	----------------------------
	@Call B11_LoadProgramTable

;	--------------------------
;	LOAD SOME SYSTEM DATANAMES
;	--------------------------
	@words_copy c_I,DN_Type																									; response from a function
	@words_pad  'RETURN_CODE',DN_Name																				; It is boolean and should
	@integers_eq DN_NameLength,11																						; and Length
	@Call X2_PutXtable																											; be either TRUE or FALSE

	@words_copy c_I,DN_Type																									; It can be used throughout a program
	@words_pad  'ERROR_CODE',DN_Name																				; and is used by the system to report
	@integers_eq DN_NameLength,10																						; and Length
	@Call X2_PutXtable																											; the programs return code

	@words_copy c_I,DN_Type
	@words_pad 'exitRepeat',DN_Name
	@integers_eq DN_NameLength,10																						; and Length
	@Call X2_PutXtable

	@words_copy c_W,DN_Type
	@words_pad 'w_CommandLine',DN_Name
	@integers_eq DN_NameLength,13																						; and Length
	@Call X2_PutXtable

	@words_copy c_W,DN_Type
	@words_pad 'w_Spaces',DN_Name
	@integers_eq DN_NameLength,08																						; and Length
	@Call X2_PutXtable

;	-----------------------
;	BEGIN -> from MATHS.PKG
;	-----------------------
	@words_copy c_F,DN_Type
	@words_pad 'f_Add',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Sub',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Mul',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Div',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Power',DN_Name
	@integers_eq DN_NameLength,07																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_SqRoot',DN_Name
	@integers_eq DN_NameLength,08																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Sin',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Cos',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Tan',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_PI',DN_Name
	@integers_eq DN_NameLength,04																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_LogN',DN_Name
	@integers_eq DN_NameLength,06																						; and Length
	@Call X2_PutXtable

	@words_copy c_F,DN_Type
	@words_pad 'f_Log',DN_Name
	@integers_eq DN_NameLength,05																						; and Length
	@Call X2_PutXtable

;	--------------------
;	END -_from MATHS.PKG
;	--------------------

	@repeat_for n_LineCtr,1,ProgramTable_UBOUND

		@xtables_rget ProgramTable,n_LineCtr
		@words_uppercase PR_Line,w_UBuffer

		@integers_eq n_TokenStart,3																						; Get the 1st Token
		@If {PR_Line,n_TokenStart,1},_IN,{' ',x_Tab}													; If its an indent
			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; Get the next Token
		@End_if																																; ENDIF
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length

		@if PR_Type,_IN,{"D","T","%",x_OpenSquareBracket}											; Under these circumstances
			@Call B12_Load_DN_Table																							; Add to the Data Name Table
		@end_if																																; ENDIF

	;	------------------------
	;	REWRITE THE PROGRAMTABLE
	;	------------------------
		@xtables_rput ProgramTable,n_LineCtr																	; rewrite program table

	@end_repeat

@END_SUB B1_1stPass

;-------------------------------------------------------------------------------
;			~ B11_LoadProgramTable
;-------------------------------------------------------------------------------
@BEGIN_SUB B11_LoadProgramTable

	@files_open in_File,$read 																							; Open the Input File

	@if in_File_SIZE,=,0																										; If it is blank then
		@files $write,STDOUT,'03: [reWriter]:Input File does not exist'				; issue an error
		@terminate 3																													; and @terminate
	@end_if																																	; END

	@files_read in_File,io_Buffer																						; Read the first record
	@words_uppercase io_Buffer,w_UBuffer																		; Grab an uppercase version

;	WINDOWS
	@words_Find {'WINDOWS',I},w_UBuffer																			; Check for WINDOWS
	@IF I,>,0																																; If you found it
		@integers_eq b_Windows,c_TRUE																					; Set the windows flag
		@files_read in_File,io_Buffer																					; Read the next record
		@words_uppercase io_Buffer,w_UBuffer																	; Grab an uppercase version
	@end_If
;	WINDOWS

	@integers_eq b_Raw,c_FALSE																							; Raw Flag to False
	@words_copy ",",w_ExtraDelimiter																				; whether comma is a delimiter of not

;	=========
;	READ LOOP
;	=========
	@integers_eq PR_LineNo,0																								; Initialise Line Ctr

	@repeat_if in_File_STATUS,=,0																						; REAPEAT until end of file (or error)

		@integers_add PR_LineNo,1																							; Line no used for errors

@If PR_LineNo,>,60
xor rax,rax
@end_if


	;	INITIALISE
		@integers_eq PR_LineLength,in_File_READLENGTH													; Default line length to input line
		@words_pad " ",PR_Type																								; clear the line type;
		@words_pad x_Null,PR_Line																							; clear the line;

	;	BLANK LINE
		@repeat_for in_File_READLENGTH,in_File_READLENGTH,1										; Clear any trailing spaces/tabs/bracket
			@if {io_Buffer,in_File_READLENGTH,1},_NIN,{' ',x_Tab}								; as they always are a pain in the arse
				@exit_repeat																											; exit when we are done
			@end_if																															; ENDIF
		@end_repeat																														; ENDREPEAT

	;	So now either the read was a blank line or it only contained spaces/tabs
		@IF in_File_READLENGTH,=,0																						; Blank Line
			@words_copy "B",PR_Type																							; then mark it as such
			@integers_eq PR_LineLength,0																				; and zero line length
		@Else

			@If SynonymTable_UBOUND,=,0																					; If we haven't loaded any Synonyms
				@Call B111_LoadSynonyms																						; then see if we need to
			@End_If

		;	TOKENISE
			@integers_eq b_SynonymFlag,c_TRUE																		; Initialise a synonym flag
			@Call B112_Tokenise																									; make the call
			@integers_calc PR_LineLength,=,n_dstIdx,-,1													; and reset the line length

		;	Now we are Tokenised we can do a few things
		;	Get the 1st Token
			@integers_eq n_TokenStart,3																					; Get the 1st Token
			@If {PR_Line,n_TokenStart,1},_IN,{' ',x_Tab}												; If its an indent
				@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}						; Get the next Token
			@End_if																															; ENDIF
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length

		; RAW Propcessing ------------------------------------
			@If b_Raw,=,c_FALSE																									; If not BEGIN.RAW found
				@If {PR_Line,n_TokenStart,n_TokenLength},=,"@BEGIN_RAW"						; Look for it
					@integers_eq b_Raw,c_TRUE																				; if found set the flag
					jmp @Write																											; Jump to rPUT and Read
				@End_If																														; ENDIF
			@End_If																															; ENDIF
			@If b_Raw,=,c_TRUE																									; If BEGIN.RAW wasfound
				@If {PR_Line,n_TokenStart,n_TokenLength},=,"@END_RAW"							; Look for it
					@integers_eq b_Raw,c_FALSE																			; if found set the flag
					@words_Copy " ",PR_Type																					; reset the line type
					jmp @Write																											; Jump to rPUT and Read
				@Else																															; ELSE
					@Words_copy "R",PR_Type																					; Set the Line Type
					@words_copy io_Buffer,PR_Line																		; move to PR_Line
					@integers_eq PR_LineLength,in_File_READLENGTH										; Get the line length
					jmp @Write																											; Jumkp to rPUT and Read
				@End_If
			@End_If
		; RAW Propcessing --------------------------------------

		;	DEFAULT PICTURE
			@Call B113_DefaultPicture																						; Check the for default picture

			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; Get the next Token
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length

		;	PROCEDURE FLAG
			@If b_Instructions,=,c_FALSE																				; Detect anything yet ?
				@integers_add n_TokenStart,1																			; Step over Quotation mark
				@IF {PR_Line,n_TokenStart,26},=,'include/BEGIN.INSTRUCTIONS'			; Did we find instructions
					@integers_eq b_Instructions,c_TRUE															; set the flag
					@words_copy "I",PR_Type																					; then mark it as such
				@End_If																														; ENDIF
			@End_If																															; ENDIF

		@End_If																																; ENDIF

	;	---------------------------------------
	;	WRITE THE TABLE AND GET THE NEXT RECORD
	;	---------------------------------------
		@If PR_Type,=,{w_Spaces,1,1}																					; If PR_Type is not decided
			@If b_Instructions,=,c_FALSE																				; If Not Instructions yet
				@words_copy "D",PR_Type																						; PR_Type = Data
			@Else																																; Else
				@words_copy "T",PR_Type																						; PR_Type = Text
			@End_If																															; ENDIF
		@End_If																																; ENDIF

@Write:
		@integers_add ProgramTable_UBOUND,1																		; increment the upper boundary
		@xtables_rput ProgramTable,ProgramTable_UBOUND												; write the record to the table

@Read:
		@files_read in_File,io_Buffer																					; Read the first record
		@words_uppercase io_Buffer,w_UBuffer																	; Grab an uppercase version


	@end_Repeat																															; END Read Loop


;	=========
;	END LOOP
;	=========

	@files_close in_File																										; Close file - we are done

@END_SUB B11_LoadProgramTable

;=========================================================================
;				~ B111_LoadSynonyms
;=========================================================================
@BEGIN_SUB B111_LoadSynonyms

;	IF we are reWriting the reWriter
	@If b_Instructions,=,c_TRUE
		@Exit_Sub B111_LoadSynonyms
	@END_IF


	@words_find {'BEGIN.SYNONYMS',I},w_UBuffer															; Look for start of Synonyms
	@if I,>,0																																; If we have found it

		@repeat_while 1,=,1																										; and read thru the program

			@files_read in_File,io_Buffer																				; Read the first record
			@words_uppercase io_Buffer,w_UBuffer																; Grab an uppercase version
			@integers_add PR_LineNo,1

			@words_find {'END.SYNONYMS',I},w_UBuffer														; test for end of synonyms
			@if I,>,0																														; If found then
				@exit_sub B111_LoadSynonyms																				; EXIT
			@else																																; ELSE
					@Call B1111_ReadSynonymFile																			; Import the synonyms
			@end_if																															; ENDIF

		@end_repeat																														; END REPEAT
	@end_if																																	; ENDIF

@END_SUB B111_LoadSynonyms


;-----------------------------------------------------------------------
;				~ B1111_ReadSynonymFile
;-----------------------------------------------------------------------
@BEGIN_SUB B1111_ReadSynonymFile

;	-----------------------
;	GET FILENAME
;	----------------------
;	xExtractText 1,PR_LineLength,I,J,';'
; NO POINT using Tokens here is it will just be a single token
;	defining a comment . ie 21;  include/LPACK1.SYN
;
	@repeat_for I,1,in_File_READLENGTH																			; Running from the start of the line
		@If {io_Buffer,I,1},_NIN,{" ",x_Tab,";"}															; looking for a valid character
			@exit_repeat																												; Exit if found
		@End_if																																; ENDIF
	@End_Repeat																															; ENDREPEAT
	@integers_Calc J,=,in_File_READLENGTH,-,I,+,1														; So I is the start and J is the length

;	---------------------
;	If its NOT a copyfile
;	---------------------
	@words_find {"INCLUDE",K},w_UBuffer																			; Is it an include file
	@IF K,=,0																																; If it's not
		@integers_calc syn_File_READLENGTH,=,I,+,J														; setup to call Write Synonym
		@Call B11111_WriteSynonymTable																					; Add the synonym to the table
		@exit_SUB B1111_ReadSynonymFile																				; and exit
	@End_If																																	; ENDIF

;	===================
;	If it IS a copyfile
;	===================
	@WORDS_Pad {io_Buffer,I,J},syn_File																			; copy it
	@integers_add J,1																												; Bypass the name
	@words_copy x_Null,{syn_File,J}																					; move in the null [0x00]

;	-----------------------
;	OPEN FILENAME
;	----------------------
	@files_open syn_File,$read 																							; Open the Input File
	@IF syn_File_STATUS,!=,0																								; If error
		@files $write,STDOUT,'04: Include Synonyms file not found'						; display error message
		@terminate 4																													; terminate
	@End_IF																																	; ENDIF

;	-----------------------
;	PROCESS
;	----------------------
	@files_read syn_File,io_Buffer 																					; Grab the 1st line

	@repeat_while syn_File_STATUS,=,0																				; Loop while we have input
		@Call B11111_WriteSynonymTable																					; Add the synonym to the table

		@files_read syn_File,io_Buffer 																				; Grab the next line
	@End_Repeat																															; END REPEAT

;	-----------------------
;	CLOSE
;	----------------------
	@FILES_Close syn_File																										; Close the file
	@Words_pad w_saveLine,PR_Line																						; restore line

@END_SUB B1111_ReadSynonymFile

;-----------------------------------------------------------------------
;						~ B11111_WriteSynonymTable
;-----------------------------------------------------------------------
@BEGIN_SUB B11111_WriteSynonymTable

;***************WINDOWS VERSION
;	MACRO START-------------------
;xExtractText MACRO _arg1:REQ, _arg2:REQ, _arg3:REQ, _arg4:REQ, _arg5:VARARG ; default to space
;
;	Returns these
;	@integers_eq _arg3,0 																											; Initialise the out_start
;	@integers_eq _arg4,0 																											; Initialise the out_length
;	@words_copy <<w_Spaces,1,1>>,w_Char

;	IFNB <_arg5>
;		@words_copy _arg5,w_Char
;	ENDIF

;	@repeat_for m_Idx,_arg1,_arg2 																						; From in_Start to in_Length
;		@if <<io_Buffer,m_Idx,1>>,_IN,<<" ",x_Tab,x_LF,_arg5>> 									; These are our delimiters (ignore leading ones)  
;			@if _arg3,_GT,0 																											; so if we haven't started yet
;				@integers_eq exitRepeat,%c_TRUE 																		; EXIT
;			@end_if 																															; ENDIF
;		@else 																																	; ELSE
;			@if _arg3,_EQ,0 																											; IF we havent started yet
;				@integers_eq _arg3,m_Idx 																						; mark the beginning
;			@end_if 																															; END
;			@integers_add _arg4,1 																								; Count the No Of Characters
;		@end_if 																																; ENDIF
;	@end_repeat 																															; END REPEAT
;ENDM
;	MACRO END---------------------
;***************WINDOWS VERSION


;	MACRO START-------------------
%imacro xExtractText 4-5 ' ' ; default to space
;	Returns these
	@integers_eq %3,0																												; Initialise the out_start
	@integers_eq %4,0																												; Initialise the out_length
	@repeat_for m_Idx,%1,%2																									; From in_Start to in_Length
		@if {io_Buffer,m_Idx,1},_IN,{' ',x_Tab,x_LF,%5}												; These are our delimiters (ignore leading ones)
			@if %3,>,0																													; so if we haven't started yet
				@integers_eq exitRepeat,c_TRUE																		; EXIT
			@end_if																															; ENDIF
		@else																																	; ELSE
			@if %3,=,0																													; IF we havent started yet
				@integers_eq %3,m_Idx																							; mark the beginning
			@end_if																															; END
			@integers_add %4,1																									; Count the No Of Characters
		@end_if																																; ENDIF
	@end_repeat																															; END REPEAT
%endmacro
;	MACRO END---------------------

	xExtractText 1,syn_File_READLENGTH,I,J,';'															; Extract 1st Word
	@if I,=,0																																; If just a blank line/comment
		@exit_sub B11111_WriteSynonymTable																			; then exit
	@else																																		; @else
		@words_pad {io_Buffer,I,J},Synonym																		; grab the synonym
		@words_uppercase Synonym																							; Set it all uppercase
		@integers_eq lenSynonym,J 																						; and its length
	@end_if

	@integers_calc I,=,I,+,J
	@words_find {":",K},{io_Buffer,I}																				; Find start position
	@integers_add K,1																												; and step over it
	xExtractText K,syn_File_READLENGTH,I,J																	; Extract the 2nd Word
	@words_pad {io_Buffer,I,J},Keyword																			; Grab the Keyword Dataname or Command
	@words_uppercase Keyword																								; Set it all uppercase
	@integers_eq lenKeyword,J 																							; and its length
	@Call X3_PutXtable																											; Write it to the Synonyms table
	
@END_SUB B11111_WriteSynonymTable

;=========================================================================
;				~ B112_Tokenise
;=========================================================================
@BEGIN_SUB B112_Tokenise

;	---------------
;	Initialise
;	---------------
	@words_pad {w_Spaces,1,1},token																					; Clear the token
	@integers_eq tokenLen,0																									; Token Length to zero
	@integers_eq tokenIdx,3																									; Token Index to 2

	@integers_eq n_CommandStart,0																						; Initialiaze after indent value
	@integers_eq n_dstIdx,1																									; dst Indx to 1

;	============================================
;	READ LOOP
;	============================================
	@integers_eq b_Initial,c_TRUE																						; Set the initial flag to true
	@integers_eq tokenIdx,3																									; 1st Token

	@repeat_for n_srcIdx,1,in_File_READLENGTH																; REPEAT thru the line

	;	========================================================
	;	Delimiters here are the space/tab or the [/] brackets
	;	which require there own particular processing
	;	w_ExtraDelimeter is available and used at the moment
	;	for commas (passing parameters for FUNCTIONS/SUBROUTINES
	;	========================================================
 	;	----------------------
	;	DELIMITER Space or Tab
	;	----------------------
	;	The complication here is that I want to keep Indents So under normal
	;	circumstances a space/tab would indicate the end of a character string
	;	while in the case of an Indent that is not the case., so finding
	;	spaces/tabs 1st up indicates that we have an indent. All this really
	;	to set n_CommandStart so that we can maintain the indent across lines

		@IF {io_Buffer,n_srcIdx,1},_IN,{' ',x_Tab,w_ExtraDelimiter}						; Do we have a space of a tab
			@IF b_Initial,=,c_TRUE																							; We want the 1st ones to keep the indent
				@Call B1121_MoveCharToToken																				; so move it to Token
			@Else																																; ELSE
				@Call B1122_MoveTokenToLine																				; Move the token to the line
				@Call B1123_NextChar																								; and get start of next token
			@End_IF																															; END IF
		@End_If


	;	------------------------------------
	;	DELIMITER OPEN/CLOSE Square Brackets
	;	------------------------------------

		@If {io_Buffer,n_srcIdx,1},_IN,{x_OpenSquareBracket,x_CloseSquareBracket}		; If we have the open/close square bracket

			@If {io_Buffer,n_srcIdx,1},=,x_OpenSquareBracket
				@words_copy x_OpenSquareBracket,PR_Type														; mark the line as a square bracket
			@End_If

			@Call B1122_MoveTokenToLine																					; Move the previous token to the line
			@Call B1121_MoveCharToToken																					; move it to token
			@Call B1122_MoveTokenToLine																					; Move the token to the line
			@Call B1123_NextChar																									; and get start of next token

		@End_If																																; ENDIF

	;	=====================================================
	;	Deleimters here are the space/tab or the [/] brackets
	;	which require there own particular processing
	;	=====================================================

	;	-----------
	;	VALID Char
	;	-----------
		@IF B1124_f_ValidChar																									; Do we have a valid char

			@IF b_Initial,=,c_TRUE																							; If 1st time thru
				@integers_eq b_Initial,c_FALSE
				@Call B1122_MoveTokenToLine																				; write the line
				@integers_eq n_CommandStart,n_dstIdx																	; it will be an indent
			@end_If																															; ENDIF
			@Call B1121_MoveCharToToken																					; and move to token

		@end_if																																; ENDIF

  ;	------------
	;	Directive
	;	------------
;		@_IF {io_Buffer,n_srcIdx,1},=,'%'																			; Do we have a directive
;		@_AND tokenIdx,=,3
;		@_END
		@IF {io_Buffer,n_srcIdx,1},=,'%'																			; Do we have a directive
			@words_copy "%",PR_Type																							; mark the line as a directive
		@End_If																																; ENDIF

	;	------------
	;	Comment
	;	------------
		@IF {io_Buffer,n_srcIdx,1},=,';'																			; Do we have a comment

			@If b_Initial,=,c_TRUE																							; A whole comment line
				@words_copy ";",PR_Type																						; mark the line as a comment

			;	Foolishly made PR_LineLength '99' and didn't have the heart to fix it
				@If in_File_READLENGTH,<,100
					@integers_eq n_99,in_File_READLENGTH															; Get the line length
				@else
					@integers_eq n_99,99
				@End_If

				@words_pad n_99,PR_Line																						; Copy to Line
				@words_copy io_Buffer,{PR_Line,3}																	; move the comment in
				@integers_calc PR_LineLength,=,n_99,+,2														; and set the line length
			@else																																; ELSE
				@integers_calc n_99,=,in_File_READLENGTH,-,n_srcIdx,+,1						; calculate length
				@words_copy n_99,{PR_Line,n_dstIdx}																; move in the token length
				@integers_add n_dstIdx,2																					; step past it
				@words_copy {io_Buffer,n_srcIdx},{PR_Line,n_dstIdx}								; and copy in the comment
			@end_If																															; END
			@words_copy {w_Spaces,1,1},{token,3}																; No token to process after end of Loop
			@integers_calc n_dstIdx,=,in_File_READLENGTH,+,1										; set n_dstIdx so calling can work out the length
			@exit_sub B112_Tokenise																							; and exit

		@end_if

	;	------------
	;	Split Line
	;	------------
		@IF {io_Buffer,n_srcIdx,1},=,'|'																			; Do we have a split line

;			@integers_calc PR_LineLength,=,n_dstIdx,-,1													; Reset the line length
			@Words_Find {"[",I},PR_Line																					; Precedence/Table ?
			@If I,>,0																														; If YES
				@words_copy "[",PR_Type																						; Set PR_Type
			@Else																																; Else
				@words_copy "T",PR_Type																						; Set PR_Type
			@End_If																															; End_If

			@integers_add ProgramTable_UBOUND,1																	; increment the upper boundary
			@xtables_rput ProgramTable,ProgramTable_UBOUND											; write the record to the table

			@integers_add n_srcIdx,1																						; step over the split line character
			@Call B1123_NextChar																									; Get the next token
			@integers_sub n_srcIdx,1																						; less 1 cuz the repeat will add this one back

			@integers_eq n_dstIdx,n_CommandStart																; Reset destination to begin after the indent
			@words_pad  x_Null,{PR_Line,n_dstIdx}																; clear the rest of the line;
			@integers_eq b_SynonymFlag,c_TRUE																		; will need to look for Synonyms again

			@Words_Find {"[",I},PR_Line																					; Precedence/Table ?
			@If I,>,0																														; If YES
				@words_copy "[",PR_Type																						; Set PR_Type
			@Else																																; Else
				@words_copy "T",PR_Type																						; Set PR_Type
			@End_If																															; End_If

		@end_if																																; END IF

	;	------------
	;	Literal
	;	------------
		@IF {io_Buffer,n_srcIdx,1},_IN,{x_Quote1,x_Quote2}										; Do we have a literal
			@words_copy {io_Buffer,n_srcIdx,1},w_Quote													; Store which quote it is
			@repeat_while 1,=,1																									; Now loop thru the string
				@Call B1121_MoveCharToToken																				; Move to Token
				@integers_add n_srcIdx,1																					; Advance to the next char

				@If n_srcIdx,>,PR_LineLength
        	@display "No Closing Quote on line No=",PR_LineNo,LF
          @terminate 1
        @end_if

				@if {io_Buffer,n_srcIdx,1},=,w_Quote															; If we have hit the 2nd quote (saved)
					@Call B1121_MoveCharToToken																			; Move to Token
					@exit_repeat																										; EXIT LOOP
				@end_if																														; END IF
			@end_repeat																													; END REPEAT
		@end_if

	;	--------
	;	Braces
	;	--------
		@If {io_Buffer,n_srcIdx,1},_IN,{x_OpenBrace,x_CloseBrace}							; If we have the open/close brace
			@IF {io_Buffer,n_srcIdx,1},=,x_OpenBrace														; If we have an open brace
				@integers_add n_NoOfOpenBraces,1																	; count it as such

			;	*************
			;	SPECIALS CASE
			;	*************
			;	Discovered that after the restructure was pretty much settled there was an error
			;	processing Fixed Point literals as parameters to a function. Took weeks to sort 
			;	it out but there is code marked as SPECIAL CASE to make it all work
			;	The 2 cases are 
			;		Words.Find {"ret",I},w_someText
			;		If {f_Equal 1.23,2.34}
			;	the 1st needs everything between braces as 1 token while the 2nd needs separate tokens
			;	*************

				@IF f_SpecialCases																								; If special case (DO Nothing
				@Else																															; ELSE
					@words_copy " ",w_ExtraDelimiter																; Comma is NOT a delimeter
				@End_If

			@else																																; Else
				@integers_add n_NoOfCloseBraces,1																	; count it as closed
				@words_copy ",",w_ExtraDelimiter																	; Comma IS a delimeter
			@end_if																															; ENDIF
		@End_If

	;	--------
	;	Brackets
	;	--------
		@If {io_Buffer,n_srcIdx,1},_IN,{x_OpenBracket,x_CloseBracket}					; If we have the open/close bracket
			@IF {io_Buffer,n_srcIdx,1},=,x_OpenBracket													; If we have an open bracket
				@integers_eq tokenLen,0																						; Restart the token count
				@integers_eq tokenIdx,3																						; Reset the token Index
				@words_pad {w_Spaces,1,1},token																		; Clear the token
				@integers_add n_NoOfOpenBrackets,1																; count it as such
			@else																																; Else
				@Call B1122_MoveTokenToLine																				; write the line
				@integers_add n_NoOfCloseBrackets,1																; count it as closed
			@end_if																															; ENDIF
		@End_If

	;	---------------
	;	Square Brackets
	;	---------------
	;	Irrelevant to the logic here - just counting square brackets
		@If {io_Buffer,n_srcIdx,1},_IN,{x_OpenSquareBracket,x_CloseSquareBracket}		; If we have the open/close brace
			@IF {io_Buffer,n_srcIdx,1},=,x_OpenSquareBracket										; If we have an open square bracket
				@integers_add n_NoOfOpenSQBrackets,1															; count it as such
			@else																																; Else
				@integers_add n_NoOfCloseSQBrackets,1															; count it as closed
			@end_if																															; ENDIF
		@end_if

	@end_repeat																															; END REPEAT

;	============================================
;	END LOOP
;	============================================

	;	-------------
	;	Last one ?
	;	-------------
	@If {token,3,1},!=,{w_Spaces,1,1}																				; If the token is the last character of the line
		@Call B1122_MoveTokenToLine																						; Move the token to the line
	@end_if																																	; END IF

@END_SUB B112_Tokenise

;-------------------------------------------------------------------------
;					~ f_SpecialCase
;-------------------------------------------------------------------------
@BEGIN_FUNCTION f_SpecialCases

	;	*************
	;	SPECIALS CASE
	;	*************
	;	Discovered that after the restructure was pretty much settled there was an error
	;	processing Fixed Point literals as parameters to a function. Took weeks to sort 
	;	it out but there is code marked as SPECIAL CASE to make it all work
	;	The 2 cases are 
	;		Words.Find {"ret",I},w_someText
	;		If {f_Equal 1.23,2.34}
	;

;	Alias's also fell under here

		@If b_Instructions,=,c_FALSE																					; comma is not a delimiter
			@Exit_function f_SpecialCases
		@End_If

	; Array_IF processing also fell under here as it is characterised with a {

	;	******************************************
		@words_find {"IF",I},PR_Line																					; Check for an IF
		@If I,!=,0																														; If we have one
			@integers_calc I,=,n_srcIdx,-,1																			; Get the previous character to the {
			@IF {io_Buffer,I,1},!=," "																					; and if its NOT a space then we have an Array
				@words_insert " ",{io_Buffer,n_srcIdx}														; We need to insert a space here
				@integers_add in_File_READLENGTH,1																; and add 1 to the read length
				@integers_sub tokenIdx,1																					; step back in the tokenIdx
				@integers_sub tokenLen,1																					; and shorten it by 1
				@words_copy " ",{token,tokenIdx}																	; space over that {
				@integers_sub n_srcIdx,1																					; step back for our walk of io_Buffer
				@integers_sub n_NoOfOpenBraces,1																	; sub 1 from the open brace count
				@Exit_function f_SpecialCases																			; and exit as FALSE
			@End_If																															; ENDIF
		@End_If																																; ENDIF
	;	******************************************

		@words_find {"IF",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

		@words_find {"OR",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

		@words_find {"AND",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

		@words_find {"REPEAT",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

		@words_find {"WHEN",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

		@words_find {"TEST",I},PR_Line
		@If I,!=,0
			@Integers_eq RETURN_CODE,c_TRUE
			@Exit_function f_SpecialCases
		@End_If

@END_FUNCTION f_SpecialCases

;-------------------------------------------------------------------------
;					~ B1121_MoveCharToToken
;-------------------------------------------------------------------------
@BEGIN_SUB B1121_MoveCharToToken

	@words_copy {io_Buffer,n_srcIdx,1},{token,tokenIdx}											; and copy to token
	@integers_add tokenLen,1																								; increment the token count
	@integers_add tokenIdx,1																								; increment the token index

@END_SUB B1121_MoveCharToToken

;-------------------------------------------------------------------------
;					~ B1122_MoveTokenToLine
;-------------------------------------------------------------------------
@BEGIN_SUB B1122_MoveTokenToLine

	@If tokenLen,=,0																												; If we were just swallowing spaces/tabs
		@exit_sub B1122_MoveTokenToLine																				; then exit
	@End_If																																	; ENDIF

	@If b_SynonymFlag,=,c_TRUE
		@If {token,3,1},_NIN,{' ',x_Tab}
			@integers_eq b_SynonymFlag,c_FALSE
			@Call B11221_SwapSynonym
		@End_If
	@End_If

	@words_copy tokenLen,{token,1,2}																				; and write the length
	@integers_add tokenLen,2																								; now set the length to include the length
	@words_copy {token,1,tokenLen},{PR_Line,n_dstIdx}												; now copy the token to the destination

	@integers_calc n_dstIdx,=,n_dstIdx,+,tokenLen														; Advance the destination position

;	-------------
;	Re Init Token
;	-------------
	@integers_eq tokenLen,0																									; Restart the token count
	@integers_eq tokenIdx,3																									; Reset the token Index
	@words_pad {w_Spaces,1,1},token																					; Clear the token

@END_SUB B1122_MoveTokenToLine

;=========================================================================
;						~ B11221_SwapSynonym
;=========================================================================
@BEGIN_SUB B11221_SwapSynonym

	@words_uppercase token,w_Temp40																				; Covert to upper case

;	------------------------------------------------------
;	SPECIAL CASE - When running the reWriter
;	thru the reWriter to obtain a Windows version
;	There are no Synonyms for languageONE.ASM cuz it's raw
;	but sometimes you need one
;	------------------------------------------------------
		@If {w_Temp40,3,tokenLen},_IN,{"@BEGIN_RAW","@END_RAW"}							; If we have found _RAW
			@words_copy w_Temp40,token																				; Slot it inot the token
			@exit_sub B11221_SwapSynonym																				; EXIT
		@End_If																															; ENDIF


;	--------------------------
;	RUN THRU THE SYNONYM TABLE
;	--------------------------
	@repeat_for I,1,SynonymTable_UBOUND

		@xtables_rget SynonymTable,I																				; Grab a record

	;	011 0001I01=011
	;	029 01	06w_Word01=13'Hello World'
	;	018 02		03xor07rax,rax

		@If {Synonym,1,lenSynonym},=,{w_Temp40,3,tokenLen}

		;---V3.0 - Windows
			@_If  b_Windows,=,c_TRUE								; If it's Windows
			@_And w_Synonym,=,"="										; and we are looking for equals
			@_End
				@words_find {"S_CALC",J},{w_UBuffer}	; Search for integers_calc/numbers_calc
				@If J,>,0															; If we found it
					@Integers_eq b_FoundSynonym,c_FALSE	; dont chenge this one - keep looking
				@End_If																; END
			@End_If																	; END

			@_If  b_Windows,=,c_TRUE								; If it's Windows
			@_And w_Synonym,=,"IF"									; and we find an IF
			@_And b_Assembler,=,c_TRUE							; while we are doing assembler
			@_End											
				@Integers_eq b_FoundSynonym,c_FALSE		; ignore it
			@End_If
		;---V3.0 - Windows


			@if lenKeyword,>,lenSynonym
				;	--------------
				;	MAKE SOME ROOM
				;	--------------
				@integers_calc J,=,lenKeyword,-,lenSynonym												; subtract the Synonym length from the Keywords length
				@integers_add tokenLen,J																					; Increase the Line Length

				@words_insert {w_Spaces,1,J},{w_Temp40,3}													; Insert some spaces
			@else
					;	------------
					;	SQUASH IT UP
					;	------------
				@integers_calc J,=,lenSynonym,-,lenKeyword												; subtract the Keyword length from the Synonym length
				@integers_sub tokenLen,J																					; Decrease the Line Length

				@integers_Calc J,=,1,+,tokenLen																		; Get start of move
				@Integers_Calc K,=,1,+,lenKeyword																	; Get end of move
				@words_pad {w_Temp40,J},{w_Temp40,K}															; Now do the squashing move

			@end_if

			;	----------------------
			;	AND DO THE REPLACEMENT
			;	----------------------
			@words_pad {Keyword,1,lenKeyword},{w_Temp40,3}											; Copy in the Synonym
			@words_pad w_Temp40,token																						; then move to token

			@exit_repeat																												; and exit

		@end_if

	@end_repeat

@END_SUB B11221_SwapSynonym

;-------------------------------------------------------------------------
;					~ B1123_NextChar
;-------------------------------------------------------------------------
@BEGIN_SUB B1123_NextChar

;	Will only ever be called after find a SPACE/TAB delimiter (and \)
;	It is supposed to eat spaces and now backslashes (compress a continued
;	line into a single one)


	@repeat_for n_srcIdx,n_srcIdx,in_File_READLENGTH												; Search for next token

		@If b_Raw,=,c_FALSE																										; If NOT Raw
			@If w_ExtraDelimiter,=,','																					; If we have previosuly defined a comma as a delimiter
				@if {io_Buffer,n_srcIdx,1},=,','																	; Then if we find one
					@words_copy ' ', {io_Buffer,n_srcIdx,1}													; Ensure you keep looping (see next line of code)
				@end_if																														; ENDIF
			@end_if																															; ENDIF
		@End_If																																; ENDIF

		@IF {io_Buffer,n_srcIdx,1},=,x_BackSlash															; If we have a continuation character
			@files_read in_File,io_Buffer																				; Read the next record
			@words_uppercase io_Buffer,w_UBuffer																; Grab an uppercase version
			@integers_eq PR_LineLength,in_File_READLENGTH												; Default line length to input line
			@integers_eq n_srcIdx,0																							; and reset the source index to 0 (repeat will inc to 1)
		@End_If

		@IF {io_Buffer,n_srcIdx,1},_NIN,{' ',x_Tab}														; If we have found one then
			@exit_repeat																												; exit
		@End_If

	@end_repeat																															; END REPEAT

@END_SUB B1123_NextChar

;-------------------------------------------------------------------------
;					~ B1124_f_ValidChar
;-------------------------------------------------------------------------
@BEGIN_FUNCTION B1124_f_ValidChar

		@IF {io_Buffer,n_srcIdx,1},_NIN,{' ',x_Tab,x_SemiColon,'|',								\
																		x_OpenBracket,x_CloseBracket,							\
																		x_OpenSquareBracket,x_CloseSquareBracket,	\
																		x_Quote1,x_Quote2}
			@integers_eq RETURN_CODE,c_TRUE
		@End_If

@END_FUNCTION B1124_f_ValidChar

;-----------------------------------------------------------------------
;				~ B113_DefaultPicture
;-----------------------------------------------------------------------
@BEGIN_SUB B113_DefaultPicture

;	---------------------------
;	Fixed Point Default Picture
;	---------------------------

	@words_Find {'FP_DEFAULTPICTURE',I},w_UBuffer														; Check for Default Picture
	@IF I,=,0																																; If not found
		@exit_sub B113_DefaultPicture																					; EXIT
	@Else																																		; ELSE
		@integers_calc J,=,I,-,1																							; step back 1
		@If {w_UBuffer,J,1},=,"'"																							; oh, we are rewriting languageONE.ASM
			@Exit_Sub B113_DefaultPicture																				; so exit
		@End_If																																; ENDIF

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Find the token after it
		@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_FP_Picture					; and store the picture
		@words_pad w_FP_Picture,DN_Picture																		; for sub routines ?
		@Call X9_CheckPicture																									; Validate the picture
		@words_copy ";",PR_Type																								; mark it as a comment
		@words_insert "01;",PR_Line																						; Comment the Line
		@integers_add PR_LineLength,03																				; Increase the line length

	@end_If																																	; ENDIF

@END_SUB B113_DefaultPicture

;-------------------------------------------------------------------------------
;			~ B12_Load_DN_Table
;-------------------------------------------------------------------------------
@BEGIN_SUB B12_Load_DN_Table

;	-----------------
;	Initialise record
;	-----------------
	@Words_pad {w_Spaces,1,1},DN_TableType																	; (X)Table
	@Words_pad {w_Spaces,1,1},DN_Table																			; Data part of table
	@Words_Pad {w_Spaces,1,1},DN_Record																			; Data part of record
	@Integers_eq DN_No,0																										; Position within Record
	@Words_pad {w_Spaces,1,1},DN_Type																				; 'I'=Integer,'N'=FixedPointNumber,'W'=Word
	@Words_pad {w_Spaces,1,1},DN_Name																				; Data Name
	@Integers_eq DN_NameLength,0																						; Length
	@Words_pad {w_Spaces,1,1},DN_Picture																		; Picture

;	------------
;	BEGIN RECORD
;	------------
	@IF {PR_Line,n_TokenStart,13},=,"@BEGIN_RECORD"													; If Record found
		@integers_eq b_ProcessRecord,c_TRUE																		; Set processing record to true

		@Integers_eq n_FieldPos,0																							; Position within Record

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Step over record length
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get Record Name
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length

		@words_Copy {PR_Line,n_TokenStart,n_TokenLength},w_SaveRecordName			; and save the name
		@words_copy c_R,DN_Type																								; Set Type
		@Call B122_StoreSystemDefinitions																			; and create system definitions
		@exit_sub B12_Load_DN_Table																						; end exit
	@End_If

;	----------
;	END RECORD
;	----------
	@IF {PR_Line,n_TokenStart,11},=,"@END_RECORD"														; If End of Record found
		@integers_eq b_ProcessRecord,c_FALSE																	; set processing record to false
		@words_pad {w_Spaces,1,1},w_SaveRecordName														; and the saved value
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	-------------------
;	INTEGERS/FIXEDPOINT
;	-------------------
	@IF {PR_Line,n_TokenStart,13},=,"@INSERTNUMBER"													; If DataDefinition found
		@words_copy c_I,DN_Type																								; Set Type (Default to integer)
		@Call B121_StoreDataDefinitions																				; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	-----
;	WORDS
;	-----
	@IF {PR_Line,n_TokenStart,11},=,"@INSERTWORD"														; If DataDefinition found
		@words_copy c_W,DN_Type																								; Set Type
		@Call B121_StoreDataDefinitions																				; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	-------------------
;	%define - constants - Note it's using w_UBuffer
;	-------------------
	@IF {w_UBuffer,n_TokenStart,07},=,"%DEFINE"															; If Constant found
		@words_copy c_C,DN_Type																								; Set Type
		@Call B122_StoreSystemDefinitions																			; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	======================
;	SYSTEM SUPPLIED FIELDS
;	======================

;	-----------
;	@insertfile
;	-----------
	@IF {PR_Line,n_TokenStart,11},=,"@INSERTFILE"														; If DataDefinition found
		@words_copy c_f,DN_Type																								; Set Type
		@Call B122_StoreSystemDefinitions																			; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF


;	-----------
;	@inserttable
;	-----------
	@IF {PR_Line,n_TokenStart,12},=,"@INSERTTABLE"													; If DataDefinition found
		@words_copy c_T,DN_Type																								; Set Type
		@Call B122_StoreSystemDefinitions																			; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	------------
;	@insertxtable
;	------------
	@IF {PR_Line,n_TokenStart,13},=,"@INSERTXTABLE"													; If DataDefinition found
		@words_copy c_X,DN_Type																								; Set Type
		@Call B122_StoreSystemDefinitions																			; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if		 																															; ENDIF

;	------------
;	@insertArray
;	------------
	@IF {PR_Line,n_TokenStart,12},=,"@INSERTARRAY"													; If DataDefinition found
		@words_copy c_A,DN_Type																								; Set Type
		@Call B121_StoreDataDefinitions																				; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

;	=====================
;	SUBROUTINES/FUNCTIONS
;	=====================	

;	---------
;	BEGIN_SUB
;	---------	
	@IF {PR_Line,n_TokenStart,10},=,"@BEGIN_SUB"														; If Begin Sub found
		@words_copy c_S,DN_Type																								; set the type
		@Call B121_StoreDataDefinitions																				; and store it
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if

;	--------------
;	BEGIN_FUNCTION
;	--------------
	@IF {PR_Line,n_TokenStart,15},=,"@BEGIN_FUNCTION"												; If Begin Sub found
		@words_copy c_F,DN_Type																								; set the type
		@Call B121_StoreDataDefinitions																				; and store it
		@words_copy c_N,DN_Type																								; set the type
		@words_insert "d",DN_Name																							; prefix the dataname
		@integers_add DN_NameLength,1																					; add 1 to the length
		@Call X2_PutXtable																										; and write it out
		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; END

;	-------------- 
;	@USING - T 033 01	06@USING12{roger,'99'}17{Jessica,'99.99'}15{Tiffani,'999'}
;	--------------
;	This code is setup to traverse the @USING macro and pick out the NAME/PICTURE
;	combination to pass thru to B51_StoreDataDefinitions
;
	@IF {PR_Line,n_TokenStart,6},=,"@USING"																	; If Begin Sub found

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get paramater
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length

		@repeat_while n_TokenStart,>,0																				; for each Token/Parameter

			@integers_calc I,=,n_TokenStart,+,1																	; set past the 1st {
			@words_find {",",K},{PR_Line,I}																			; look for the ,
			@integers_calc J,=,K,-,I																						; gets the dataname length
			@words_pad {PR_Line,I,J},DN_Name																		; move it in
			@Integers_eq DN_NameLength,J																						; move in the length

			@integers_calc I,=,K,+,1																						; step past the ,
			@words_find {"}",K},{PR_Line,I}																			; get the }
			@integers_calc J,=,K,-,I																						; step back 1
			@words_pad {PR_Line,I,J},DN_Picture																	; move in the picture

			@words_pad {PR_Line,I,J},w_Temp40																		; temp the picture
			@words_find {".",K},w_Temp40																				; look for a .
			@If K,>,0																														; if we got one
				@words_copy c_N,DN_Type																						; it's a number
			@Else																																; else
				@words_copy c_I,DN_Type																						; it's an integer
			@End_If																															; EDIF

			@Call X2_PutXtable																									; Write it out

			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; get the next parameter
			@IF n_TokenStart,>,0																								; if we have one
				@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}				; get length
			@End_If																															; ENDIF

		@end_repeat																														; ENDREPEAT
		@exit_sub B12_Load_DN_Table																						; end exit
	@END_IF

;	----------
;	BIND
;	----------
; 	@xtables_bind ProgramTable,ProgramRecord,64000000

	@Words_Find {"_BIND",I},{PR_Line,n_TokenStart}													; Look for a _BIND
	@IF I,>,0																																; and if we have found one

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next token
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length

		@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_SaveTableName				; and save it

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next token
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length

		@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_SaveRecordName			; and save the name/NoOfRecords

		@Call B123_ProcessBind																									; Do the Bind process

		@exit_sub B12_Load_DN_Table																						; end exit
	@end_if																																	; ENDIF

@END_SUB B12_Load_DN_Table

;-------------------------------------------------------------------------------
;				~ B121_StoreDataDefinitions
;-------------------------------------------------------------------------------
@BEGIN_SUB B121_StoreDataDefinitions

;	-----------------
;	MARK RECORD FIELD
;	-----------------
	@if b_ProcessRecord,=,c_TRUE																						; If we have detected we are processing a record
		@integers_add n_FieldPos,1																						; increment the ctr for field position
		@integers_eq DN_No,n_FieldPos																					; and store the value
		@words_copy w_SaveRecordName,DN_Record																; and the record name
	@else																																		; else
		@integers_eq DN_No,0																									; set the field position ctr to zero
		@words_copy {w_Spaces,1,1},DN_Record																	; and spaces to the record name
	@end_if

;	-----------
;	INITIAL
;	-----------
	@integers_eq n_Length,0																									; Alias length
	@integers_eq DN_NameLength,0																						; and length
	@words_pad {w_Spaces,1,1},DN_Picture																		; Always clear picture

	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get name offset
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get length
	@integers_calc n_TokenEnd,=,n_TokenStart,+,n_TokenLength,-,1						; get the end

	@integers_eq n_srcIdx,n_TokenStart																			; using the source index

;	----------------------------
;	Alias - is the 1st occurence
;	----------------------------
	@words_pad {w_Spaces,1,1},w_Alias																				; Clear the alias name field

	@If {PR_Line,n_srcIdx,1},=,x_OpenBrace																	; If we have hit an opening brace
		@integers_add n_srcIdx,1																							; Step over the open brace
		@integers_eq	n_dstIdx,1																							; Initialise the destination index

		@repeat_while {PR_Line,n_srcIdx,1},!=,','															; Loop until we have a comma
			@words_copy {PR_Line,n_srcIdx,1},{w_Alias,n_dstIdx,1}								; Move a character
			@integers_add n_Length,1																						; Increment Alias length
			@integers_add	n_srcIdx,1																						; Increment source index
			@integers_add n_dstIdx,1																						; Increment destination Idx
		@end_repeat																														; END REPEAT

		@integers_add	n_srcIdx,1																							; Step over the comma

	@end_If																																	; ENDIF

;	----------------------------
;	2nd or Only occurence
;	----------------------------
	@words_pad {w_Spaces,1,1},DN_Name																				; Clear the DataName field
	@integers_eq	n_dstIdx,1																								; Initialise the destination index

	@repeat_while n_srcIdx,!>,n_TokenEnd																		; LOOP

		@If {PR_Line,n_srcIdx,1},=,x_CloseBrace																; If we hit a close brace
			@integers_add n_srcIdx,2																						; Step over it and the following comma
			@exit_repeat
		@Else
			@If {PR_Line,n_srcIdx,1},=,','																			; if its a comma
				@exit_repeat
			@Else																																; ELSE
				@words_copy {PR_Line,n_srcIdx,1},{DN_Name,n_dstIdx,1}							; Move a character
				@integers_add DN_NameLength,1																			; Increment DataName Length
				@integers_add	n_srcIdx,1																					; Increment source index
				@integers_add n_dstIdx,1																					; Increment destination Index
			@End_If																															; ENDIF
		@End_If

	@end_repeat																															; ENDREPEAT

;	---------------------------------------
;	GET DN_PICTURE - step over length/value
;	---------------------------------------
	@words_pad {w_Spaces,1,1},DN_Picture																		; Initialise the pciture

	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Function/Picture/xLength
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get Token length

	@If DN_Type,=,c_W
		@Words_pad {PR_Line,n_TokenStart,n_TokenLength},DN_xLength						; get the word length
	@Else																																		; ELSE

		@If DN_Type,!=,c_F																										; If Not Function
			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; Get Integer/Number picture offset
		@End_If

		@If n_TokenStart,!=,0																									; If we not past the end

			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get length
			@Words_pad {PR_Line,n_TokenStart,n_TokenLength},DN_Picture					; get the picture

			@if DN_Type,!=,c_F																									; If we are NOT a function
				@words_find {'.',J},DN_Picture																		; Is it a fixed point number
				@if J,>,0																													; Did we find anything
					@words_copy c_N,DN_Type																					; then its a real number
				@end_if																														; ENDIF
			@End_If																															; ENDIF
		@End_If																																; ENDIF

@end_if																																		; ENDIF

;	------------
;	AND WRITE IT
;	------------
	@Call X2_PutXtable																											; Write it out

;	-----------------------
;	2nd NAME FOR EACH FIELD
;	-----------------------
	@if w_Alias,!=,{w_Spaces,1,1}																						; If we have an Alias
		@words_pad w_Alias,DN_Name																						; store it
		@integers_eq DN_NameLength,n_Length																				; set the length
		@Call X2_PutXtable																										; Write it out
	@end_if																																	; ENDIF

@END_SUB B121_StoreDataDefinitions


;-------------------------------------------------------------------------------
;				~ B122_StoreSystemDefinitions
;-------------------------------------------------------------------------------
@BEGIN_SUB B122_StoreSystemDefinitions

;	---------------- 
;	CREATE RECORD_NO
;	----------------
	@if DN_Type,=,c_R
		@words_pad w_SaveRecordName,DN_Name																		; move it into the DN_Name table
		@repeat_for I,1,30																										; Run through the record name
			@If {DN_Name,I,1},=,{w_Spaces,1,1}																	; until spaces
				@exit_repeat																											; then exit
			@end_if																															; ENDIF
		@end_repeat																														; ENDREPEAT
		@words_copy '_NO',{DN_Name,I}																					; and append _NO
		@integers_add I,2																											; calc the length
		@Integers_eq DN_NameLength,I																							; store ir
		@Call X2_PutXtable																										; write the table item
	@end_if

;	------------------
;	CREATE FILE FIELDS
;	------------------
	@if DN_Type,=,c_f

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; File Type
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get File
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length
		@Words_pad {PR_Line,n_TokenStart,n_TokenLength},DN_Name								; move the field
		@integers_Eq DN_NameLength,n_TokenLength																	; just store the length
		@words_copy c_W,DN_Type																								; define name as a word
		@Call X2_PutXtable																										; write the table item

		@words_copy c_I,DN_Type																								; define handle as an integer
		@integers_calc I,=,n_TokenLength,+,1																	; calc position
		@words_copy '_HANDLE',{DN_Name,I}																			; and append _HANDLE
		@integers_calc DN_NameLength,=,I,+,6																			; set the length
		@Call X2_PutXtable																										; write the table item

	@end_if																																	; ENDIF

;	-------------------
;	CREATE TABLE FIELDS
;	-------------------
	@If DN_Type,_IN,{c_T,c_X,c_C}

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get Record Name
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get length
		@Words_pad {PR_Line,n_TokenStart,n_TokenLength},DN_Name								; move the field

		@If DN_Type,=,c_C																											; for a constant
			@integers_Eq DN_NameLength,n_TokenLength																; just store the length
		@Else																																	; ELSE
			@integers_calc n_dstIdx,=,n_TokenLength,+,1													; calc the offset
			@words_copy '_UBOUND',{DN_Name,n_dstIdx}														; and append _UBOUND
			@integers_calc DN_NameLength,=,n_dstIdx,+,6													; set the length
			@Call X2_PutXtable																									; write the table item
			@words_copy '_STATUS',{DN_Name,n_dstIdx}														; and append _STATUS
		@End_If																																; ENDIF

		@Call X2_PutXtable																										; write the table item

	@end_if

@END_SUB B122_StoreSystemDefinitions

;-------------------------------------------------------------------------------
;		-+ B53_ProcessBind
;-------------------------------------------------------------------------------
@BEGIN_SUB B123_ProcessBind

	@Words_Find {"@X",I},PR_Line																						; Look for a @X
	@IF I,>,0																																; and if we have found one
		@words_copy 'X',w_SaveTableType																				; mark it as such
	@else																																		; ELSE
		@words_copy 'T',w_SaveTableType																				; mark it as a normal table
	@end_if

	@integers_eq X6_Idx,0																										; Setup for reads
	@Call X5_SearchByRecord																									; and start it
	@repeat_if DataNameTable_STATUS,=,0																			; If status is zero we have a match
		@words_copy w_SaveTableType,DN_TableType															;	assign the Table type
		@words_pad w_SaveTableName,DN_Table																		;	and assign the Table Name
		@tables_rput DataNameTable,X6_Idx																			;	write it 
		@Call X5_SearchByRecord																								;	and grab the next one
	@end_repeat																															; ENDREPEAT

@END_SUB B123_ProcessBind

;		~ =========
;		~ C_2ndPass
;		~ =========
@BEGIN_SUB C2_2ndPass

;	The second pass will mostly perform the translation process. ie converting 
;	"cooked" languageONE to "raw" languageONE. Refere to C2_Translate for further
;	documentation.

	@integers_eq b_Instructions,c_FALSE																			; set the flag

;	THIS ROUTINE WILL STEP THRU EACH LINE OF THE PROGRAM
	@repeat_for n_LineCtr,1,ProgramTable_UBOUND															; LOOP thru the Program Table

		@xtables_rget ProgramTable,n_LineCtr																	; Grab a record

@If n_LineCtr,>,350
xor rax,rax
@end_if

		@words_uppercase PR_Line,w_UBuffer

		@If f_NoFurtherProcessing
		@Else

			@Call C21_GetStats																										; get stats
			@Call C22_Translate																									; Do the work

			@xtables_rput ProgramTable,n_LineCtr
		@End_If

	@end_repeat

	@xtables_sort MacroTable,1,5																						; Sort the created macros

;	-------------------
;	DISPLAY THE RESULTS
;	-------------------
	@Call C23_DisplayResults

@END_SUB C2_2ndPass

;	-----------------------------------
;			~ f_NoFurtherProcessing
;------------------------------------
@BEGIN_FUNCTION f_NoFurtherProcessing

	@If PR_Type,_IN,{"%",";","B","R"}																				; If a comment/directive/blank/raw
		@Integers_Eq RETURN_CODE,c_TRUE																				; then nofurtherprocessing is true
		@exit_function f_NoFurtherProcessing																	; exit
	@End_If																																	; ENDIF

	@If PR_Type,=,"I"																												; If BEGIN.INSTRUCTIONS
		@integers_eq b_Instructions,c_TRUE																		; set the flag
		@Integers_Eq RETURN_CODE,c_TRUE																				; then nofurtherprocessing is true
		@exit_function f_NoFurtherProcessing																	; exit
	@End_If																																	; ENDIF

	@integers_eq n_TokenStart,3																							; Get the 1st Token
	@If {PR_Line,n_TokenStart,1},_IN,{' ',x_Tab}														; If its an indent
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
	@End_if																																	; ENDIF
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	@IF {w_UBuffer,n_TokenStart,n_TokenLength},=,'SECTION'
		@Integers_Eq RETURN_CODE,c_TRUE																				; then nofurtherprocessing is true
		@exit_function f_NoFurtherProcessing																	; exit
	@End_If																																	

@END_FUNCTION f_NoFurtherProcessing

;-------------------------------------------------------------------------------
;			~ C21_GetStats
;-------------------------------------------------------------------------------
@BEGIN_SUB C21_GetStats

	@If b_Instructions,=,c_FALSE
		@exit_sub C21_GetStats
	@End_if

	@If PR_Type,_NIN,{"T","["}
		@exit_sub C21_GetStats
	@End_If

;	----------------
;	START token walk -> THIS IS DONE IN f_NoFurtherProcessing
;	----------------
;	@integers_eq n_TokenStart,3																							; Get the 1st Token
;	@If {PR_Line,n_TokenStart,1},_IN,{' ',x_Tab}														; If its an indent
;		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
;	@End_if																																	; ENDIF
;	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length
;	----------------
;	START token walk
;	----------------

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@BEGIN_RAW'
		@integers_add n_NoOfBeginRaw,1
		@integers_eq b_Raw,c_TRUE
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_RAW'
		@integers_add n_NoOfEndRaw,1
		@integers_eq b_Raw,c_FALSE
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@BEGIN_SUB'
		@integers_add n_NoOfBeginSubs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_SUB'
		@integers_add n_NoOfEndSubs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@BEGIN_FUNCTION'
		@integers_add n_NoOfBeginFunctions,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_FUNCTION'
		@integers_add n_NoOfEndFunctions,1
		@exit_sub C21_GetStats
	@END_IF

	@_IF {PR_Line,n_TokenStart,n_TokenLength},=,'@REPEAT_IF'
	@_OR {PR_Line,n_TokenStart,n_TokenLength},=,'@REPEAT_FOR'
	@_OR {PR_Line,n_TokenStart,n_TokenLength},=,'@REPEAT_WHILE'
	@_END
		@integers_add n_NoOfRepeats,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_REPEAT'
		@integers_add n_NoOfEndRepeats,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@IF'
		@integers_add n_NoOfIfs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@_IF'
		@integers_add n_NoOfIfs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@ARRAYS_IF'
		@integers_add n_NoOfIfs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_IF'
		@integers_add n_NoOfEndIfs,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@BEGIN_TEST'
		@integers_add n_NoOfBeginTests,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@END_TEST'
		@integers_add n_NoOfEndTests,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@WHEN'
		@integers_add n_NoOfWhens,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@_WHEN'
		@integers_add n_NoOfWhens,1
		@exit_sub C21_GetStats
	@END_IF

	@IF {PR_Line,n_TokenStart,n_TokenLength},=,'@WEND'
		@integers_add n_NoOfWends,1
		@exit_sub C21_GetStats
	@END_IF

@END_SUB C21_GetStats

;=======================================================================
;			~ C2_Translate
;=======================================================================
@BEGIN_SUB C22_Translate

;	THIS ROUTINE WILL STEP THRU EACH TOKEN IN A LINE

;	----------------
;	START token walk
;	----------------
	@integers_eq n_TokenStart,3																							; Get the 1st Token
	@If {PR_Line,n_TokenStart,1},_IN,{' ',x_Tab}														; If its an indent
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
	@End_if																																	; ENDIF
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	@integers_eq n_OriginTokenStart,n_TokenStart														; Save the start position
	@FUNCTION n_OriginTokenLength,f_TokenLength,{n_OriginTokenStart,'999'}	; get its length

;	-----------
;	FIXED POINT
;	-----------
;	Changes 1.23 into {123,'9.99}
	@Call C221_FixedPoint																										; ALTER LINE:CONTINUE fixed point numbers (Matrix/Procedure) 

	@If b_Instructions,!=,c_TRUE																						; So now if we are not in the instractions section
		@exit_sub C2_Translate																								; we have nothing to do - so exit
	@end_if																																	; ENDIF

;	---------
;	FUNCTIONS
;	---------
	@If C222_f_ArrayIF																												; Easy case of ARRAYS_IF
	@else																																		; ELSE
		@IF C223_f_SingleLine																									; Do the single line substitutes
		@else																																	; ELSE
			@If C224_f_CreateMacro																								; Create macros
			@end_If																															; ENDIF
		@end_if																																; ENDIF
	@end_if																																	; ENDIF

@END_SUB C2_Translate

;-----------------------------------------------------------------------
;				~ C221_FixedPoint
;-----------------------------------------------------------------------
@BEGIN_SUB C221_FixedPoint

;	------------
;	DATA Section
;	------------
	@IF PR_Type,=,"D"																												; If we are in the Data section
		@IF {PR_Line,n_TokenStart,13},=,'@INSERTNUMBER'												; and if its a insertnumber
			@Call C2211_FP_inMatrix																							; call in matrix
			@exit_sub C221_FixedPoint																						; exit
		@End_If																																; ENDIF
	@End_If																																	; ENDIF

;	------------
;	TEXT Section
;	------------
	@IF PR_Type,_IN,{"T",x_OpenSquareBracket}																; If we are in the Text section
		@IF {PR_Line,n_TokenStart,15},=,'@BEGIN_FUNCTION'											; Dont alter when FUNCTION is found
			@exit_sub C221_FixedPoint																						; so exit
		@End_if																																; ENDIF
		@Call C2212_FP_inProcedure																						; call in procedure
		@exit_sub C221_FixedPoint																							; exit
	@End_If																																	; ENDIF

@END_SUB C221_FixedPoint

;-----------------------------------------------------------------------
;					~ C211_FP_inMatrix
;-----------------------------------------------------------------------
@BEGIN_SUB C2211_FP_inMatrix
;	******************************************************
;	FIXED POINT IN MATRIX DOES NOT TRAVERSE THE LINE USING
;	TOKENS BUT RATHER LOOKS AT THE ENTIRE LINE AS A WHOLE
;	***************************************************

;	@when nasm sees a number with a decimal place it initialises the qword
;	in floating point representation. As languageONE only works with fixed
;	point values, the number must be adjusted to suit the given picture
;		ie.  1.23,'99.9999' as adjusted to
;			12300,'99.9999'

;	insertnumber n_1,9.9											T 026 01	12insertnumber03n_1039.9
;	insertnumber n_1,12.34,'99.99'						T 036 01	12insertnumber03n_108-123.45608'99.99-'
;	insertnumber {n_1,n_2},	9.9								T 032 01	12insertnumber09{n_1,n_2}039.9
;	insertnumber {n_1,n_2},	12.34,'99.99'			T 042 01	12insertnumber09{n_1,n_2}0512.3407'99.99'

	@integers_eq n_FixedPoint1,				00
	@integers_eq n_FixedPoint2,				00
	@integers_eq n_PicPlaces,					00

;	----
;	LOOP
;	----
	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Step over the data name

	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get the value
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	@integers_calc n_TokenEnd,=,n_TokenStart,+,n_TokenLength,-,1						; get Token end
	@repeat_for n_RowCtr,n_TokenStart,n_TokenEnd														; Walk along the parameter
		@If {PR_Line,n_RowCtr,1},=,'.'																				; Do we have a period
			@integers_eq n_FixedPoint1,n_RowCtr																	; save the 1st period position
			@exit_repeat																												; and exit
		@End_If																																; ENDIF
	@End_Repeat																															; ENDREPEAT

	@integers_calc n_StartLit,=,n_TokenStart																; Get the start of the literal
	@integers_calc n_EndLit,=,n_TokenStart,+,n_TokenLength,-,1							; Get the end of the literal

	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get the picture
	@If n_TokenStart,=,0
		@If n_FixedPoint1,!=,0
			@files $write,STDOUT,"04: Line No=",n_LineCtr," Fixed Point number must provide a picture"
			@terminate 4																												; Terminate
		@End_If
	@Else
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
		@integers_calc n_TokenEnd,=,n_TokenStart,+,n_TokenLength,-,1					; get Token End
		@repeat_for n_RowCtr,n_TokenStart,n_TokenEnd													; Walk along the parameter
			@If {PR_Line,n_RowCtr,1},=,'.'																			; Do we have a period
				@integers_eq n_FixedPoint2,n_RowCtr																; save the 1st period position
				@exit_repeat																											; and exit
			@End_If																															; ENDIF
		@End_Repeat																														; ENDREPEAT
	@End_If

;	NOTHING TO DO HERE
	@_If  n_FixedPoint1,=,0																									; If 1st period not found
	@_and n_FixedPoint2,=,0																									; and 2nd period not found
	@_end																																		; END
		@exit_sub C2211_FP_inMatrix																						; then exit
	@end_if																																	; ENDIF

;	---------------------------------------	
;	Count the decimal places in the picture
;	---------------------------------------
	@repeat_For I,n_FixedPoint2,n_TokenEnd																	; LOOP decimal places
		@If {PR_Line,I,1},_IN,{'9','#'}																				; IF its a 9 or a #
			@integers_add n_PicPlaces,1																					; then count it
		@end_if																																; ENDIF
	@end_repeat																															; ENDREPEAT

;	-----------------------------------------------
;	Count the numbers/decimal places in the literal
;	and build a new literal
;	-----------------------------------------------
	@Call C22111_BuildLiteral																								; Build literal

;	----------
;	And Insert
;	----------
	@integers_calc n_LitLen,=,n_EndLit,-,n_StartLit,+,1											; Grab the old literal length
	@integers_calc n_NoOfChars,=,n_NewLitLen,-,n_LitLen											; count the number of characters difference

	@if n_NewLitLen,>,n_LitLen																							; IF the new literal is bigger
		@words_insert {w_Spaces,1,n_NoOfChars},{PR_Line,n_StartLit}						; and insert that many spaces
	@else
		@integers_calc n_ShrinkOffset,=,n_EndLit,+,n_NoOfChars								; n_ShrinkOffset will be negative
		@words_pad {PR_Line,n_EndLit},{PR_Line,n_ShrinkOffset}								; move shink by NoOfChars difference
	@end_if																																	; ENDIF

	@words_copy {w_NewLit,1,n_NewLitLen},{PR_Line,n_StartLit}								; and move in the new one

	@integers_calc I,=,n_StartLit,-,2																				; Step back 2 from Commands position
	@numbers_eq n_99,{PR_Line,I,2}																					; grab the token length
	@integers_add n_99,n_NoOfChars																					; correct the value (n_NoOfChars may be -ve)
	@words_copy n_99,{PR_Line,I,2}																					; move it back into PR_Line

	@integers_add PR_LineLength,n_NoOfChars																	; then lengthen/shorten the line length

@END_SUB C2211_FP_inMatrix

;------------------------------------------------------------------------
;						~ C2111_BuildLiteral
;------------------------------------------------------------------------
@BEGIN_SUB C22111_BuildLiteral

	@words_pad {w_Spaces,1,1},w_NewLit																			; Initialise the new literal
	@integers_eq b_Flag,c_FALSE
	@integers_eq n_NewLitLen,0																							; and zero its length
	@integers_eq n_NewLitPlaces,0																						; zero the places

	@Call C29_CompressLiteral

;	Now correct the literal
	@begin_test c_TRUE

		@when n_NewLitPlaces,<,n_PicPlaces																		; if we need to pad out the literal
			@integers_sub n_PicPlaces,n_NewLitPlaces														; how many zeroes
			@repeat_for I,1,n_PicPlaces																					; loop that many times
				@integers_add n_NewLitLen,1																				; pad new literal
				@words_copy '0',{w_NewLit,n_NewLitLen,1}													; with zeroes
			@end_repeat
		@wend

		@when n_PicPlaces,<,n_NewLitPlaces																		; if we need to truncate out the literal
			@integers_sub n_NewLitPlaces,n_PicPlaces														; how many numbers
			@repeat_for I,1,n_NewLitPlaces																			; loop that many times
				@words_copy {w_Spaces,1,1},{w_NewLit,n_NewLitLen,1}								; pad new literal
				@integers_sub n_NewLitLen,1																				; with spaces
			@end_repeat
		@wend

	@end_test

@END_SUB C22111_BuildLiteral

;-----------------------------------------------------------------------
;					~ C212_FP_inProcedure
;-----------------------------------------------------------------------
@BEGIN_SUB C2212_FP_inProcedure

;	----
;	LOOP
;	----
	@repeat_while n_TokenStart,>,0																					; and loop while greater than zero

		@integers_calc n_TokenEnd,=,n_TokenStart,+,n_TokenLength,-,1					; calculate its end position

		@repeat_for n_RowCtr,n_TokenStart,n_TokenEnd													; walk along the length of the token

			@_If {PR_Line,n_RowCtr,1},=,x_OpenBrace															; Do we have an open brace
			@_Or {PR_Line,n_RowCtr,1},=,x_Quote1																; or a single quote
			@_Or {PR_Line,n_RowCtr,1},=,x_Quote2																; or a double quote
			@_Or {PR_Line,n_RowCtr,1},=,";"																			; or a comment
			@_end
				@exit_repeat
			@Else
				@If {PR_Line,n_RowCtr,1},=,'.'																		; If we have a decimal point

					@integers_eq n_StartLit,n_TokenStart														; Mark the start
					@integers_eq n_dpPos,n_RowCtr																		; grab the position
					@integers_eq n_EndLit,n_TokenEnd																; Mark the end
					@Call C22121_FP_Build																						; Transform and add picture

				@End_If
			@end_If

		@end_repeat

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next token
		@If n_TokenStart,>,0
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length
		@End_If

	@end_repeat

	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

@END_SUB C2212_FP_inProcedure

;------------------------------------------------------------------------
;						~ C2122_FP_Expand
;------------------------------------------------------------------------
@BEGIN_SUB C22121_FP_Build

;	-123.456 -> {-123456,'999.999-'}

;	--------------------------------------------------
;	PICTURE - Set up the original token as the Picture
;	--------------------------------------------------
	@words_pad {w_Spaces,1,1},w_saveLine																		; Building the token in saveLine

;	*************
;	SPECIALS CASE
;	*************
;	Discovered that after the restructure was pretty much settled there was an error
;	processing Fixed Point literals as parameters to a function. Took weeks to sort 
;	it out but there is code marked as SPECIAL CASE to make it all work
;	The 2 cases are 
;		Words.Find {"ret",I},w_someText
;		If {f_Equal 1.23,2.34}
;	and are separated in B112_Tokenise in regard to what is tokenised between the braces
;	*************

;	Here we need to know if it the last token being processed
;	and add back the "}" if required

;	**** Huh, 3 cases.  like-> Words.copy	123.456,{outputLine,30}

	@If {PR_Line,PR_LineLength,1},=,"}"																			; If the last character is a brace

		@words_find {"WORDS",I},w_UBuffer																			; Check for the WORDS macro
		@If I,>,0																															; If we have found it we do not want an extra brace
			@integers_eq I,63																										; Set the ensuing starting point
		@Else																																	; ELSE

			@repeat_for I,PR_LineLength,1																				; Work backwards along the line
				@If {PR_Line,I,1},=,"."																						; looking for a decimal place

					@If I,=,n_dpPos																									; If it is the one detected in calling sub
						@words_copy "}",{w_saveLine,64}																; Copy a brace into w_saveLine
						@integers_eq I,62																							; Set the ensuing starting point
						@exit_repeat																									; and exit
					@Else																														; ELSE
						@If I,>,n_dpPos																								; If it greater than the one detected in calling sub
							@integers_eq I,63																						; Set the ensuing starting poin
							@exit_repeat																								; and exit
						@End_If																												; ENDIF
					@End_If																													; ENDIF

				@End_If																														; ENDIF
			@End_Repeat																													; ENDREPEAT

		@End_If

	@Else																																		; ELSE
			@integers_eq I,63																										; Set the ensuing starting point
	@End_if																																	; ENDIF


;	@integers_eq I,63																												; it's x(64) and working backwards
	@words_copy "'}",{w_saveLine,I}																					; copy in the '}

	@integers_sub I,1																												; step back 1
	@If {PR_Line,n_TokenStart,1},=,"-"																			; If the 1st character of the number is -ve
		@words_copy "-",{w_saveLine,I}																				; then set the picture to -ve
		@integers_sub I,1																											; and step back 1
	@end_if																																	; ENDIF
	@integers_calc I,-,n_TokenLength,+,1																		; Step back to the right place
	@words_copy {PR_Line,n_TokenStart,n_TokenLength},{w_saveLine,I}					; and move in the token

	@integers_sub I,2																												; step back 2
	@If {PR_Line,n_TokenStart,1},=,"-"																			; If it was a -ve sign
		@integers_add I,1																											; step forward 1 to overwrite it
	@end_if																																	; ENDIF
	@words_copy ",'",{w_saveLine,I}																					; move in the ,'

;	----------------------------
;	Replace the numbers with 9's
;	----------------------------
	@integers_calc J,=,I,+,2																								; Get the starting point
	@integers_calc K,=,I,+,n_TokenLength,+,1																; Get the ending point
	@repeat_for J,J,K																												; Loop thru it
		@If {w_saveLine,J,1},_NIN,{'.','-','}'}																; and if NOT a . or a - or a }
			@words_copy '9',{w_saveLine,J}																			; move in a 9
		@end_if																																; ENDIF
	@end_repeat																															; ENDREPEAT


;	-----------------------------------------------
;	VALUE - Remove the decimal place from the token
;	-----------------------------------------------
	@words_pad {w_Spaces,1,1},w_NewLit																			; Initialise the new literal
	@integers_eq b_Flag,c_FALSE																							; Initialise the Flag
	@integers_eq n_NewLitLen,0																							; and zero its length
	@integers_eq n_NewLitPlaces,0																						; zero the places
	@Call C29_CompressLiteral																							; and create the value

;	----------------------------------------
;	PICTURE - Get the new build into PR_Line
;	----------------------------------------
	@integers_sub I,n_NewLitLen																							; Get the new literal length
	@words_copy {w_NewLit,1,n_NewLitLen},{w_saveLine,I}											; move it into buffer
	@integers_sub I,1																												; step back 1
	@words_copy '{',{w_saveLine,I}																					; and move in the close brace

	@integers_calc n_99,=,n_TokenEnd,+,1																		; Setup the source position

	@words_pad {PR_Line,n_99},{PR_Line,n_TokenStart}												; Compress to the destination
	@integers_calc n_99,=,64,-,I,+,1																				; Calculate the Insertion length
	@words_insert {w_saveLine,I,n_99},{PR_Line,n_TokenStart}								; Insert the new token

	@integers_calc I,=,n_TokenStart,-,2																			; Get the Token Length position
	@words_copy n_99,{PR_Line,I,2}																					; Copy in the new length
	@integers_sub n_99,n_TokenLength																				; Get length difference
	@integers_add PR_LineLength,n_99																				; Calculate the new line length

@END_SUB C22121_FP_Build


;-------------------------------------------------------------------------------
;				~ C222_f_ArrayIF
;-------------------------------------------------------------------------------
@BEGIN_FUNCTION C222_f_ArrayIF
;
;	If tstArray{1,1,1} !< tstArray{1,1,2}	--> @ARRAYS_If SmallArray1 {1,1,1},=,SmallArray2,{1,1,1}
;	If tstArray{1,1,1} !< I								--> @ARRAYS_If SmallArray1 {1,1,1},=,I

	@_If PR_Type,=,x_OpenSquareBracket																			; If we are open square brackets
	@_Or PR_Type,=,x_CloseSquareBracket																			; If we are close square brackets
	@_END																																		; THEN
		@exit_function C222_f_ArrayIF																					; exit
	@End_if																																	; ENDIF

	@If {PR_Line,n_OriginTokenStart,3},!=,"@IF"															; If we are NOT IF
		@exit_sub C222_f_ArrayIF																								; exit
	@End_if																																	; ENDIF


	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; get the next token
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Temp40								; and move in the token character
	@Call X4_SearchByName																										; now check the dataname table
	@_If DataNameTable_STATUS,=,0																						; if its listed
	@_And DN_Type,=,c_A																											; and it is an array element
	@_End																																		; END

		@words_insert {w_Spaces,1,7},{PR_Line,n_OriginTokenStart}							; insert 7 spaces
		@words_copy "@ARRAYS_IF",{PR_Line,n_OriginTokenStart}									; and move in the new command

		@integers_calc I,=,n_OriginTokenStart,-,2															; Step back 2 from Commands position
		@numbers_eq n_99,{PR_Line,I,2}																				; grab the token length
		@integers_add n_99,7																									; and add 7 to it
		@words_copy n_99,{PR_Line,I,2}																				; move it back into PR_Line

		@integers_add PR_LineLength,7																					; then lengthen/shorten the line length

	@End_If																																	; ENDIF

	@integers_eq RETURN_CODE,c_TRUE

@END_FUNCTION C222_f_ArrayIF


;-------------------------------------------------------------------------------
;				~ C223_f_SingleLine
;-------------------------------------------------------------------------------
@BEGIN_FUNCTION C223_f_SingleLine

;	Setup Calc(ulations)	for numerics	converts A = 1 into @integers_eq A,1
;												for words			converts A = "Roger" into @words_copy "Roger",A
;												for functions FUNCTIONS: I = f_Product (10,10)
;												for Arrays		ARRAYS I = a_Array{1,1,1}
;												for Arrays		ARRAYS a_Array{1,1,1} = I

	@If b_Bypass,=,c_FALSE																									; So NOT being called from CreateMacro
		@_If PR_Type,=,x_OpenSquareBracket																		; If we are open square brackets
		@_Or PR_Type,=,x_CloseSquareBracket																		; If we are close square brackets
		@_END																																	; THEN
			@exit_function C223_f_SingleLine																			; exit
		@End_if																																; ENDIF
	@End_If																																	; ENDIF


	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; get the next token
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

;	----------------
;	Is It a DN_Name
;	----------------
	@words_pad {PR_Line,n_OriginTokenStart,n_OriginTokenLength},w_Temp40		; Passing in to X4_SearchByName
	@Call X4_SearchByName																										; So call it
	@if DataNameTable_STATUS,=,0																						; and if we have something
		@Call C2231_CompareDataDefinitions																			; Call the Compare
	@end_if																																	; ENDIF

	@integers_eq RETURN_CODE,c_TRUE

@END_FUNCTION C223_f_SingleLine
;	EXIT

;-------------------------------------------------------------------------------
;					~ C231_CompareDataDefinitions
;-------------------------------------------------------------------------------
@BEGIN_SUB C2231_CompareDataDefinitions

	@words_copy DN_Type,w_dstType																						; Save the type

;	-------------------------------------
;	Function or Array or Words
;	-------------------------------------
	@If b_Bypass,=,c_FALSE																									; When called from Mainline NOT Create Macro
		@if DN_Type,=,c_W																											; If destination is a word
			@Call C22311_SwapWords																							; then build @words_pad
			@exit_sub C2231_CompareDataDefinitions															; and exit
		@else
			@IF C22312_f_Function																								; Check if it's a function
				@exit_sub C2231_CompareDataDefinitions 														; and exit
			@else																																; ELSE
				@if C22313_f_Array																								; Check if it's an Array
					@exit_sub C2231_CompareDataDefinitions													; and exit
				@end_if																														; ENDIF
			@end_if																															; ENDIF
		@end_if																																; ENDIF

	@Else																																		; ELSE Called from MACRO we do want to test WORDS


		@if DN_Type,=,c_W																											; If destination is a word
			@Call C22311_SwapWords																							; then build @words_pad
			@exit_sub C2231_CompareDataDefinitions															; and exit
		@end_if																																; ENDIF

;		@words_copy c_N,w_dstType																							; but we do always want to use NUMBERS

	@end_if																																	; ENDIF

;	-----------------
;	INTEGER to NUMBER
;	-----------------
;	n_1 = 98													T 015 01	03n_101=0298
;	n_1 = 98.76												T 027 01	03n_101=14{9876,'99.99'}
;	T 018 01	03n_101=05"123"					T 018 01	03n_101=05"123"
;	n_1 = -12.34 + -43.21 - -67.89		T 071 01	03n_101=16{-1234,'99.99-'}01+16{-4321,'99.99-'}01-16{-6789,'99.99-'}
;	T 017 01	03n_101=04word					T 017 01	03n_101=04word

	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If
	@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Operator							; grab the operator

;	-----------------------
;	and then the next token
;	-----------------------
	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If

;	-------------------------------
;	Determine if we have any fixed
;	point no's in the source fields
;	-------------------------------
	@if w_dstType,=,c_I																											; if Destination is an integer

		@repeat_while n_TokenStart,>,0																				; Walking along the tokens

			@words_find {'.',I},{PR_Line,n_TokenStart,n_TokenLength}						; Search for a decimal place
			@if I,>,0																														; If found it's a number literal
				@words_copy "N",w_dstType																					; so set type to N
				jmp @exit_001																											; hard exit
			@end_If																															; ENDIF

			@If {PR_Line,n_TokenStart,n_TokenLength},_NIN,{'=','+','-','*','/'}	; If we are not an operatior
				@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Temp40					; Passing in to X4_SearchByName
				@Call X4_SearchByName																							; So call X5_
				@if DataNameTable_STATUS,=,0																			; and if we have something
					@If DN_Type,=,c_W																								; If it's word
						@words_copy c_N,w_dstType																			; we need numbers_calc
						jmp @exit_001																									; Hard Exit
					@end_If																													; ENDIF
					@If DN_Type,=,c_N																								; If its a number
						@words_copy c_N,w_dstType																			; we need numbers_calc
						jmp @exit_001																									; Hard Exit
					@end_If																													; ENDIF
				@end_if																														; ENDIF Found nothing must be a literal
			@end_if

			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; Get the next Token
			@If n_TokenStart,>,0																								; If NOT the end of line
				@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}				; get its length
			@End_If

		@end_repeat																														; ENDREPEAT
		@exit_001:

	@End_If																																	; ENDIF

;	-----------------
;	Insert macro name
;	-----------------
	@integers_calc I,=,n_OriginTokenStart,-,2
	@If w_dstType,=,c_N
		@words_insert '14@NUMBERS_CALC ',{PR_Line,I}													; then build numbers.calc
		@integers_add PR_LineLength,16
	@else
		@words_insert '15@INTEGERS_CALC ',{PR_Line,I}													; then build numbers.calc
		@integers_add PR_LineLength,17
	@end_if

	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

;	*****************
;	=+ =- =* =/
;	*****************
;	T 031 01	14@NUMBERS_CALC 01I02=+03n_0
;	T nnn 01	14@NYMBERS_CALC 01I01=01I01+03n_0
;
	@If w_Operator,_NIN,{"=+","=-","=*","=/"}																; If we are NOT an =+ etc
		@exit_sub C2231_CompareDataDefinitions																	; then we are done
	@end_if																																	; ENDIF

	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If

	@words_pad {PR_Line,n_TokenStart,n_TokenLength},{w_Temp40,3}						; get a copy of the destination field
	@numbers_eq n_99,n_TokenLength																					; wordify save token length
	@words_copy n_99,{w_Temp40}																							; Insert into temp field

	@integers_calc I,=,n_TokenLength,+,2																		; save dst field + its length

	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If

	@integers_calc n_dstIdx,=,n_TokenStart,-,2															; set the destination offset
	@words_copy "01",{PR_Line,n_dstIdx,2}																		; move 01 (length) in
	@integers_add n_dstIdx,3																								; step over it
	@words_insert {w_Temp40,1,I},{PR_Line,n_dstIdx}													; move the saved destination in

	@integers_add n_dstIdx,I																								; step over it
	@words_insert "01",{PR_Line,n_dstIdx,2}																	; move th required length 

	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

@END_SUB C2231_CompareDataDefinitions

;-------------------------------------------------------------------------------
; SwapWords
;-------------------------------------------------------------------------------
@BEGIN_SUB C22311_SwapWords

;	word = 'uoyuqer.iiuiui' ->	10@words_pad16'uoyuqer.iiuiui'05word
;	word = {word,1,1}				->	11@words_copy10{word,1,1}05word
;	{word,1,1} = {word,2,1}	->	11@words_copy10{word,2,1}10{word,1,1}

	@integers_eq b_Flag,c_TRUE																							; TRUE will indicate PAD not COPY
	@words_pad PR_Line,w_saveLine																						; So we can grab any possible indent

	@integers_eq n_Word1Len,n_OriginTokenLength															; Save the length
	@integers_calc I,=,n_OriginTokenStart,-,2																; Start the move from the length field
	@integers_calc J,=,n_OriginTokenLength,+,2															; adding 2 to the overall length
	@words_copy {PR_Line,I,J},w_Word1																				; Save the field
	@If {w_Word1,3,1},=,x_OpenBrace																					; QUALIFIED with a leading brace ?
		@integers_eq b_Flag,c_FALSE
	@End_If


	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; get the equals
	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; get the sending field
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length
	@If {PR_Line,n_TokenStart,1},=,x_OpenBrace															; QUALIFIED with a leading brace ?
		@integers_eq b_Flag,c_FALSE
	@End_If

;	--------------------------
;	Is It an Integer or Number
;	--------------------------
;*DONT GET TOO FANCY WORDS_COPY WILL DEAL WITH NUMBER TO WORD CONVERSION
;*@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Temp40								; Passing in to X4_SearchByName
;*@Call X4_SearchByName																										; So call it
;*@if DataNameTable_STATUS,=,0																						; and if we have something
;*	@if DN_Type,!=,c_W																										; If NOT a word
;*		@integers_eq b_Flag,c_FALSE																					; We need COPY not PAD
;*	@End_if																																; ENDIF
;*@end_if																																	; ENDIF

	@integers_eq n_Word2Len,n_TokenLength																		; Save the length
	@integers_calc I,=,n_TokenStart,-,2																			; Start the move from the length field
	@integers_calc J,=,n_TokenLength,+,2																		; adding 2 to the overall length
	@words_copy {PR_Line,I,J},w_Word2																				; Save the field

	@integers_calc I,=,n_OriginTokenStart,-,2																; account for length field
	@If b_Flag,=,c_TRUE																											; We can be padding
		@words_pad "10@WORDS_PAD",{w_saveLine,I}															; move in the keyword
		@integers_add I,12																										; and setp over it
	@else																																		; ELSE
		@words_pad "11@WORDS_COPY",{w_saveLine,I}															; We can be moving
		@integers_add I,13																										; and step over it
	@end_If

	@integers_add n_Word2Len,2																							; Now include the length prefix
	@words_copy {w_Word2,1,n_Word2Len},{w_saveLine,I}												; and move to save line
	@integers_add I,n_Word2Len																							; and the length to position

	@integers_add n_Word1Len,2																							; Now include the length prefix
	@words_copy {w_Word1,1,n_Word1Len},{w_saveLine,I}												; and move to save line

	@words_copy w_saveLine,PR_Line																					; and move it all in at indent
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

@END_SUB C22311_SwapWords

;-------------------------------------------------------------------------------
; Function
;-------------------------------------------------------------------------------
@BEGIN_FUNCTION C22312_f_Function

;	FROM:	I = f_POWER1 (2.0,3.0)
;	TO:		@FUNCTION I,f_POWER1,{20,'9.9'},{30,'9.9'}


	@integers_eq n_TokenStart,n_OriginTokenStart														; Get the start point

	@repeat_for I,1,2
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
		@If n_TokenStart,>,0																									; If NOT the end of line
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length
		@End_If
	@End_Repeat

	@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Temp40								; Passing in to X4_SearchByName
	@Call X4_SearchByName																										; So call X5_
	@if DataNameTable_STATUS,=,0																						; and if we have something
		@If DN_Type,!=,c_F																										; If it's word
			@integers_eq RETURN_CODE,c_FALSE
			@exit_function C22312_f_Function																		; and Exit
		@end_If
	@else
		@integers_eq RETURN_CODE,c_FALSE
		@exit_function C22312_f_Function																			; and Exit
	@end_if

;	FROM:	I = f_POWER1 (2.0,3.0)
;	TO:		@FUNCTION I,f_POWER1,{20,'9.9'},{30,'9.9'}

	@If n_OriginTokenStart,>,3																							; If we have an Indent
		@numbers_eq n_99,{PR_Line,1,2}																				; get its length
		@integers_calc n_dstIdx,=,n_99,+,2,+,1																; and setup the destination Idx
	@Else																																		; else
		@integers_eq n_dstIdx,1																								; we are starting at 1
	@End_If																																	; ENDIF
	@words_pad PR_Line,w_saveLine		 																				; easy way to move the indent

	@Words_pad "09@FUNCTION",{w_saveLine,n_dstIdx}													; Insert our Function macro
	@integers_add n_dstIdx,11																								; move past it

	@numbers_eq n_99,n_OriginTokenLength																		; wordify save token length
	@words_copy n_99,{w_saveLine,n_dstIdx}																	; Insert into temp field
	@integers_add n_dstIdx,2																								; step past it
	@words_copy {PR_Line,n_OriginTokenStart,n_OriginTokenLength},{w_saveLine,n_dstIdx}	; move in our saved token
	@integers_add n_dstIdx,n_OriginTokenLength															; and move past it

	@repeat_while n_TokenStart,>,0																					; LOOP thru Function name and parameters

		@numbers_eq n_99,n_TokenLength																				; wordify our function name length
		@words_Copy n_99,{w_saveLine,n_dstIdx}																; Insert into temp field
		@integers_add n_dstIdx,2																							; step past it
		@words_copy {PR_Line,n_TokenStart,n_TokenLength},{w_saveLine,n_dstIdx}	; move in our function name
		@integers_add n_dstIdx,n_TokenLength																	; and move past it

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
		@If n_TokenStart,>,0																									; If NOT the end of line
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length
		@End_If

	@end_repeat																															; ENDREPEAT

	@words_pad w_saveLine,PR_Line
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length
	@Integers_Eq RETURN_CODE,c_TRUE																					; return true

@END_FUNCTION C22312_f_Function

;-------------------------------------------------------------------------------
;						~ C2212_f_Array
;-------------------------------------------------------------------------------
@BEGIN_FUNCTION C22313_f_Array

;		MOVING DATA IN AND OUT OF THE ARRAY
;		Array may be the 1st or 2nd field
;		***********************************
;		I = tstArray{1,1,1}										--> @Arrays_Get tstArray,{1,1,1},I

;		MANIPULATING DATA IN THE ARRAY
;		Array must be the 1st field
;		******************************
;		tstArray{1,1,1} = I										--> @Arrays_Put tstArray,{1,1,1},I (or a Literal)

;		tstArray{1,1,1} = tstArray{1,1,2}			--> @Arrays_Eq tstArray,{1,1,1},tstArray,{1,1,2}
;		tstArray{1,1,1} == tstArray{1,1,2}		--> @Arrays_Swap tstArray,{1,1,1},tstArray,{1,1,2}
;		tstArray{1,1,1} =+ I									--> @ARRAYS_Add tstArray,{1,1,1},I
;		tstArray{1,1,1} =- 99									--> @ARRAYS_Sub tstArray,{1,1,1},99
;		tstArray{1,1,1} =* I									--> @ARRAYS_Mul tstArray,{1,1,1},I
;		tstArray{1,1,1} =/ I									--> @ARRAYS_Div tstArray,{1,1,1},I

;	So far we have only checked the 1st parameter. The only time it cannot be an Array is in the case of
;	I = tstArray{1,1,1} so if the Type is I/N we need to proceed accordingly

	@words_copy w_dstType,w1_dataType																				; save the 1st fields data type
	@If w1_dataType,_NIN,{c_I,c_N,c_A}																			; If we are not an array or a number
		@integers_eq RETURN_CODE,c_FALSE																			; set the return code
		@exit_function C22313_f_Array																					; and exit
	@end_if
	@words_copy " ",w2_dataType																							; init the 2nd fields data type

	@integers_eq n1_TokenStart,n_OriginTokenStart														; save the 1st fields start position
	@integers_eq n1_TokenLength,n_OriginTokenLength													; save the 1st fields length

;	-----------------------
;	Grab the operator field
;	-----------------------
	@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}						; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If																																	; ENDIF
	@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Operator							; grab the opeator

;	-----------------------
;	and then the next token
;	-----------------------
	@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}									; Get the next Token
	@If n_TokenStart,>,0																										; If NOT the end of line
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@End_If																																	; ENDIF

;	--------------------------------------
;	IS the 2nd Field an Array or a Literal
;	--------------------------------------
	@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_Temp40								; move the field to temp

	@Call X4_SearchByName																										; now check the dataname table
	@if DataNameTable_STATUS,=,0																						; if its listed

		@words_copy DN_Type,w2_dataType																				; Grab a copy of Data Type

		@if DN_Type,_NIN,{c_I,c_N,c_A}																				; but it is not I/N/A
			@integers_eq RETURN_CODE,c_FALSE																		; return code is false
			@exit_function C22313_f_Array																				; exit
		@End_if

	@else
			@Call X_IntegerLiteral																							; Is it a literal
			@If RETURN_CODE,=,c_FALSE																						; If not then
				@integers_eq RETURN_CODE,c_FALSE																	; return code is false
				@exit_function C22313_f_Array																			; exit
			@end_if																															; END

	@end_If

	@_If w1_dataType,!=,c_A																									; If the 1st field is not an Array
	@_and w2_dataType,!=,c_A																								; and the 2nd field is not an Array
	@_end																																		; THEN
			@integers_eq RETURN_CODE,c_FALSE																		; return code is false
			@exit_function C22313_f_Array																				; exit
	@End_If																																	; ENDIF

	@integers_eq n2_TokenStart,n_TokenStart																	; save the position of the 2nd field
	@integers_eq n2_TokenLength,n_TokenLength																; save the length of the 2nd field
	@words_copy DN_Type,w2_dataType																					; save the data type of the 2nd field

;	------------------------
;	I = Array{1,1,1}
;	------------------------
;	I = tstArray{1,1,1}-> @Arrays_Get tstArray,{1,1,1},I
	@IF w1_dataType,_IN,{c_I,c_N}																						; If our destination is an integer
		@words_pad "11@ARRAYS_GET",w_saveLine																	; start building the new code
		@integers_eq n_dstIdx,14																							; move past it

	;	Token2 length to build
		@numbers_eq n_99,n2_TokenLength																				; wordify save token length
		@words_copy n_99,{w_saveLine,n_dstIdx}																; Insert into temp field
		@integers_add n_dstIdx,2																							; step past it
	;	Token2 to build
		@words_copy {PR_Line,n2_TokenStart,n2_TokenLength},{w_saveLine,n_dstIdx}	; move in our saved token
		@integers_add n_dstIdx,n2_TokenLength																	; and move past it

	;	Token1 length to build
		@numbers_eq n_99,n1_TokenLength																				; wordify save token length
		@words_copy n_99,{w_saveLine,n_dstIdx}																; Insert into temp field
		@integers_add n_dstIdx,2																							; step past it
	;	Token1 to build
		@words_copy {PR_Line,n1_TokenStart,n1_TokenLength},{w_saveLine,n_dstIdx}	; move in our saved token
		@integers_add n_dstIdx,n1_TokenLength																	; and move past it

	;	Add comma
		@words_find {'{',I},w_saveLine																				; Look for the open brace
		@words_insert ',',{w_saveLine,I}																			; and insert a comma

	;	write new Token length
		@numbers_eq n_99,n2_TokenLength																				; Geab the Token Length
		@integers_add n_99,1																									; add 2 for the 2 commas
		@words_copy n_99,{w_saveLine,14}																			; move it into saveLine

		@integers_sub n_CommandStart,2																				; cuz we include the length in the build
		@words_pad w_saveLine,{PR_Line,n_CommandStart}												; move our line line into PR_Line
		@FUNCTION PR_LineLength,f_LineLength																	; Set the line length

		@integers_eq RETURN_CODE,c_TRUE																				; Set the functon TRUE
		@exit_function C22313_f_Array																					; and Exit

	@end_if																																	; END

;	------------------------
;	Array{1,1,1} =? ???????
;	------------------------
;		tstArray{1,1,1} = tstArray{1,1,2}--> @Arrays_Eq tstArray,{1,1,1},tstArray,{1,1,2}
;		tstArray{1,1,1} = I--> @Arrays_Put tstArray,{1,1,1},I
	@words_pad "12@ARRAYS_xxxx",w_saveLine																	; Set up the macro
	@integers_eq n_dstIdx,15																								; move past it

;	TOKEN1 
	@numbers_eq n_99,n1_TokenLength																					; wordify save token length
	@words_copy n_99,{w_saveLine,n_dstIdx}																	; Insert into temp field
	@integers_add n_dstIdx,2																								; step past it
;	TOKEN1 
	@words_copy {PR_Line,n1_TokenStart,n1_TokenLength},{w_saveLine,n_dstIdx}	; move in our saved token
	@integers_add n_dstIdx,n1_TokenLength																		; and move past it

;	TOKEN2 
	@numbers_eq n_99,n2_TokenLength																					; wordify save token length
	@words_copy n_99,{w_saveLine,n_dstIdx}																	; Insert into temp field
	@integers_eq n_savePosition,n_dstIdx																		; save position so as to add to the token length
	@integers_add n_dstIdx,2																								; step past it
;	TOKEN2
	@words_copy {PR_Line,n2_TokenStart,n2_TokenLength},{w_saveLine,n_dstIdx}	; move in our saved token
	@integers_add n_dstIdx,n2_TokenLength																		; and move past it

;	TOKEN1 - Insert commas
	@words_find {'{',I},w_saveLine																					; Look for the open brace
	@words_insert ',',{w_saveLine,I}																				; and insert a comma
	@integers_add n_savePosition,1																					; push along as there has been a character added

;	TOKEN1 - write new length
	@numbers_eq n_99,n1_TokenLength																					; Grab the Token Length
	@integers_add n_99,1																										; add 2 for the 2 commas
	@words_copy n_99,{w_saveLine,15}																				; move it into saveLine

;	TOKEN1 - Insert commas
	@integers_add I,2																												; step past 1st open brace (2 because you inserted a comma)
	@words_find {'{',J},{w_saveLine,I}																			; Look for a second open brace
	@if J,>,0																																; If you found one
		@words_insert ",",{w_saveLine,J}																			; insert a comma
	;	TOKEN2 - write new length
		@numbers_eq n_99,n2_TokenLength																				; Grab the Token Length
		@integers_add n_99,1																									; add 1 for the 1 commas
		@words_copy n_99,{w_saveLine,n_savePosition}													; move it into saveLine
		@words_copy c_A,w_srcType																							; mark it as an Array
	@else
		@words_copy c_I,w_srcType																							; mark it as an Integer
	@end_if

	;	-------------------------------
	;	Array{1,1,1} = 1/I/Array{1,1,1}
	;	-------------------------------
	@if w_Operator,=,"= "																										; If we are "="
		@If w_srcType,=,c_A																										; If we found a 2nd open brace
			@words_copy "Eq  ",{w_saveLine,11}																	; move "EQ" to the macroname
		@else																																	; ELSE
			@words_copy "Put ",{w_saveLine,11}																	; move "Put" to the macroname
		@end_if																																; END
	@end_if																																	; END


	;	-------------------------------
	;	Array{1,1,1} == Array{1,1,2}
	;	-------------------------------
		@if w_Operator,=,"=="																									; SWAP
			@words_copy "Swap",{w_saveLine,11}
		@end_if

	;	-------------------------------
	;	Array{1,1,1} =+ 1
	;	-------------------------------
		@if w_Operator,=,"=+"																									; ADDITION
			@words_copy "Add ",{w_saveLine,11}
		@end_if

	;	-------------------------------
	;	Array{1,1,1} =- 1
	;	-------------------------------
		@if w_Operator,=,"=-"																									; SUBTRACTION
			@words_copy "Sub ",{w_saveLine,11}
		@end_if

	;	-------------------------------
	;	Array{1,1,1} =* 1
	;	-------------------------------
		@if w_Operator,=,"=*"																									; MULTIPLY
			@words_copy "Mul ",{w_saveLine,11}
		@end_if

	;	-------------------------------
	;	Array{1,1,1} =/ 1
	;	-------------------------------
		@if w_Operator,=,"=/"																									; DIVISION
			@words_copy "Div ",{w_saveLine,11}
		@end_if

	;	-------------------------------
	;	and copy back to PR_Line
	;	-------------------------------
	@integers_sub n_CommandStart,2																					; cuz we include the length in the build
	@words_pad w_saveLine,{PR_Line,n_CommandStart}													; move our line line into PR_Line
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

	@integers_eq RETURN_CODE,c_TRUE																					; Set the functon TRUE

@END_FUNCTION C22313_f_Array


;===============================================================================
; f_CreateMacro
;===============================================================================
@BEGIN_FUNCTION C224_f_CreateMacro

;	Designed to allow bracketing in an integer/FP calculation
;	ie. @integers_calc I = [3 * [n_Ctr + 3]] + [2 * [n_Ctr + 5]]
;	Note the use of square brackets rather than curved brackets
;	 will create temporary integers/FPs, the macro itself
;	and will modify the procedure adding in the macro
;	A 2nd pass is made so that the created code may be inserted
;	into the source

;	Table element handling is also done using macro's. 
;	More common 'element[subscript]' coding is modified to produce the FGET
;	and FPUT system calls 
;

	@_If PR_Type,!=,x_OpenSquareBracket																			; If we are NOT open square brackets
	@_And PR_Type,!=,x_CloseSquareBracket																		; If we are NOT close square brackets
	@_END																																		; THEN
		@exit_function C224_f_CreateMacro																			; exit
	@End_if																																	; ENDIF

;	-------------
;	FIXED POINT ?
;	-------------
	@If PR_Type,=,x_OpenSquareBracket																				; If its an open bracket
		@words_copy c_I,w_DataType																						; Initialise flag to integer
	@else																																		; Else
		@words_copy c_N,w_DataType																						; Initialise flag to number
	@end_if																																	; ENDIF

;	-----------
;	AND INITIAL
;	-----------
	@integers_add n_MacroNo,1																								; and increment the macro no
	@integers_eq MR_SortOrder,0																							; Initialise the sort order
	@integers_eq n_TableRef,0																								; Initialise the Table Elements per line
	@integers_eq obIdx,0																										; Initialise the Open Bracket Index
	@integers_eq n_Equals,0																									; Initialise the Open Bracket Index

;	--------------------------------------
;	CLEAR THE REUSE FLAG IN NEW DATA TABLE
;	--------------------------------------
	@repeat_for I,1,NewDataTable_UBOUND																			; LOOP until end of records
		@xtables_rget NewDataTable,I																					; and grab the next record
		@words_copy {w_Spaces,1,1},ND_ReUsable																; space out the reusable flag
		@xtables_rput NewDataTable,I																					; and rewrite the record
	@end_repeat																															; END

	@Words_find {"=",n_Equals},PR_Line																			; Find equals
	@integers_eq n_TokenStart,n_OriginTokenStart														; Get the start point
	@integers_eq n_TokenLength,n_OriginTokenLength													; Get the start length

;	-------------------
;	CALL LOOP THRU LINE
;	-------------------
	@Call C2241_WalkTheLine																									; and work your way thru the line

;	-----------------------------------------
;	Insert Macro name and comment the command
;	-----------------------------------------
;	02		04m0013"; Refer etc"
;	04m0013" ; Refer etc"

	@words_pad {w_Spaces,1,1},w_saveLine																		; Clear the destination buffer
	@words_copy n_MacroNo,{w_MacroName,2}																		; Setup macro name
	@words_copy n_MacroNo,{l_mLine1,9}																			; and Macro Header

	@integers_eq n_TokenStart,3																							; Look into the 1st Token
	@If {PR_Line,3,1},_IN,{' ',x_Tab}																				; If the line is indented
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
		@integers_calc n_dstIdx,=,n_TokenLength,+,2														; Calc n_dstIdx is the tokenLength + the 2byte length indicator
		@Words_Copy {PR_Line,1,n_dstIdx},w_saveLine														; Move the 1st token to w_saveLine
	@Else																																		; ELSE
;		@integers_eq n_TokenLength,0																					; Set the token length to zero
		@integers_eq n_dstIdx,0																								; Initialise n_dstIdx
	@End_If																																	; END

	@integers_add n_dstIdx,1
	@words_copy "04",{w_saveLine,n_dstIdx}																	; and move in macro name length

	@integers_add n_dstIdx,2																								; step over the length
	@words_copy w_MacroName,{w_saveLine,n_dstIdx,4}													; move in th macro name
	@integers_add n_dstIdx,4																								; step over the macro name

;	@words_copy "38; Refer to data section for macro code",{w_saveLine,n_dstIdx}	; and copy it in
;	@words_pad w_saveLine,PR_Line																						; move our construction to PR_Line
		@words_pad w_saveLine,io_Buffer																				; save w_saveLine
		@integers_eq M,n_dstIdx																								; save n_dstIdx
		@FUNCTION PR_LineLength,f_LineLength																	; Set the line length
		@Call X1_TokenToRaw																										; from token format to raw
		@integers_eq n_dstIdx,M																								; restore n_dstIdx
		@numbers_calc n_99,=,PR_LineLength,+,1																; Get the raw line length
		@words_copy n_99,{io_Buffer,n_dstIdx}																	; move it in for the token length
		@integers_calc I,=,n_dstIdx,+,2																				; step over it
		@words_copy ';',{io_Buffer,I}																					; and place a semi-colan

	@integers_add n_dstIdx,3																								; step over the macro name
	@words_pad w_saveLine,{io_Buffer,n_dstIdx}															; move the raw line into io_Buffer
	@words_pad io_Buffer,PR_Line																						; and move it all to PR_Line
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

	@integers_eq RETURN_CODE,c_TRUE

@END_FUNCTION C224_f_CreateMacro

;-----------------------------------------------------------------------
; WalkTheLine
;-----------------------------------------------------------------------
@BEGIN_SUB C2241_WalkTheLine

;	This will walk a Tokenised line where "[" "]" are present. This will be
;	A = [1 * 2 - [B * 3]] + 5 where it works thru the depth of brackets or 
;	A = Table[1] where the depth is only 1 table[1] = table[2] 
;
;	NOTE:-You cannot combine PRECEDENCE and TABLES 
;					ie Table[1] = [ Table[2] * 2 ]
;							you can however code maths stuff on the right hand side
;							of a Table ie. Table[1] = 1 * 2 + 3 / 4
;
;	PRECEDENCE
; OB_OpenSqBracket is an Array indexed by obIdx with OB_OpenSquareBracket
;	holding the most current position of an Opening square bracket. It handles
;	the depth ie A = [[[ A * 1 ] - 1] * 2]
;
;	TABLES
;	OB_OpenSquareBracket is used to hold the current Opening square bracket
;	Tables always Close a Square Bracket before opening another so it just
;	uses the field (No Array used to handle any depth)

;	Both occurences will massage PR_Line in order for it to fall thru and create 
;	the last line of the macro

	@integers_Eq b_Flag,c_TRUE
	@integers_Eq n_saveStart,0

	@repeat_while n_TokenStart,>,0																					; Walk the Line

	;	------------
	;	Open Bracket
	;	------------
		@If {PR_Line,n_TokenStart,1},=,x_OpenSquareBracket										; If we have an open bracket

			@integers_add obIdx,1																								; Increment our Array Index
			@integers_eq OB_OpenSquareBracket,n_TokenStart											; Used for Precedence
			@Arrays_Put OB_OpenSqBracket,obIdx,OB_OpenSquareBracket							; and store this occurence of [

			@integers_eq n_TableElementTokenStart,n_prevTokenStart							; TABLES: Get the Table Element start
			@integers_eq n_TableElementTokenLength,n_prevTokenLength						; TABLES: and its length

		@end_if																																; ENDIF

	;	-------------
	;	Close Bracket
	;	-------------
		@If {PR_Line,n_TokenStart,1},=,x_CloseSquareBracket										; If we have an close bracket

			@integers_eq n_CloseSquareBracket,n_TokenStart											; Get the ] position from Token Start

			@if C22411_f_TableElement																						; Do it if its a table element

			@else																																; ELSE

				@Call C22412_Precedence																						; Go and build the macro

			@end_if																															; ENDIF

			@integers_sub obIdx,1																								; Decrement our Array Index
			@Arrays_Get OB_OpenSqBracket,obIdx,OB_OpenSquareBracket							; Get the [ position from the array

			@FUNCTION PR_LineLength,f_LineLength																; Set the line length
			@Words_find {"=",n_Equals},PR_Line																	; Re-find equals
			@If n_TokenStart,!=,999
				@integers_eq n_TokenStart,3																					; IF NOT then reset start as the line has just been shrunk
			@End_If

		@End_If																																; ENDIF

		@integers_eq n_prevTokenStart,n_TokenStart														; TABLES:Save the position as previous
		@integers_eq n_prevTokenLength,n_TokenLength													; TABLES:and the length as previous

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next Token
		@If n_TokenStart,>,0
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length
		@End_If

	@End_Repeat																															; ENDREPEAT

;	---------
;	Last Line
;	---------

;	The last line now needs to be created in raw format

;	---------------------------------------------------------
;	This will create a @Integers_calc for the right hand side
;	---------------------------------------------------------
	@integers_eq b_Bypass,c_TRUE																						; So Words/Arrays/Tables wont be called
	@Call C223_f_SingleLine																									; Setup *_calc A = B 
	@integers_eq b_Bypass,c_FALSE																						; So Words/Arrays/Tables will be called
;	---------------------------------------------------------
;	This will create a @Integers_calc for the right hand side
;	---------------------------------------------------------

	@Call X1_TokenToRaw																											; from token format to raw

;	Getting rid of any tabs
	@repeat_for I,1,123
		@if {w_saveLine,I,1},!=,x_Tab
			@exit_repeat
		@End_if
	@End_repeat

	@words_pad {w_saveLine,I},MR_MacroLineItem															; and into Macro Line Item

	@integers_eq MR_MacroNo,n_MacroNo																				; Identify the macro

	@If n_TableRef,=,0																											; If doing precedence
		@integers_Add MR_SortOrder,1																					; increment sort order
	@else																																		; ELSE
		@integers_eq MR_SortOrder,98																					; bridge between 0 and 99
	@End_If																																	; ENDIF

	@Call X8_WriteMacroLine																								; and write it


@END_SUB C2241_WalkTheLine

;-----------------------------------------------------------------------
;						~ C2411_f_TableElement
;-----------------------------------------------------------------------
@BEGIN_FUNCTION C22411_f_TableElement

;	----------------------------------
;	NOT IMPLIMENTED AS YET
;	----------------------------------
	@Integers_Calc I,=,n_Equals,+,1
	@If {PR_Line,I,1},_IN,{'+','-','*','/'}
		@Display v_CyanFG,PR_LineNo,' ',v_RedFG,{PR_Line,n_Equals,2}," has not beeen implimented for tables as yet",LF
		@terminate 1
	@End_If

;	----------------------------------
;	DOES IT HAVE A MATHEMATICAL SYMBOL
;	----------------------------------
	@integers_eq b_Flag,c_FALSE
	@repeat_for I,OB_OpenSquareBracket,n_CloseSquareBracket									; Now work from the [ to the ]
		@if {PR_Line,I,1},_IN,{'+','-','*','/'}																; If we find a mathematical symbol
			@integers_eq b_Flag,c_TRUE
		@end_if																																; ENDIF
	@end_repeat																															; ENDREPEAT


;	---------------------------------
;	IT SHOULD BE IN THE DATANAMETABLE
;	---------------------------------
	@words_pad {PR_Line,n_TableElementTokenStart,n_TableElementTokenLength},w_Temp40		; set up to use w_Temp40
	@Call X4_SearchByName																										; and look for it
	@if DataNameTable_STATUS,=,0																						; If we have it

		@If DN_TableType,_NIN,{c_T,c_X}
			@integers_eq RETURN_CODE,c_FALSE																		; Set FUNCTION to false
			@EXIT_FUNCTION C22411_f_TableElement																; exit routine
		@end_if																																; ENDIF

		@If b_Flag,=,c_TRUE
			@display v_CyanFG,PR_LineNo,' ',v_RedFG,"Invalid use of Table Index -> Use square brackets: ",v_YellowFG,w_Temp40,LF
			@terminate 1
		@End_If

		@Call C224111_Table																										; Call Table processing
		@integers_eq RETURN_CODE,c_TRUE																				; Set FUNCTION to true
	@else
		@integers_eq RETURN_CODE,c_FALSE																			; Set FUNCTION to false
	@end_if																																	; ENDIF

@END_FUNCTION C22411_f_TableElement

;-----------------------------------------------------------------------
;							~ C24111_Table
;-----------------------------------------------------------------------
@BEGIN_SUB C224111_Table

;	----------------------
;	OKAY - we are doing it
;	----------------------
	@integers_eq MR_MacroNo,n_MacroNo																				; store the macro no for later
	@integers_add n_TableRef,1																							; increment element no

;	--------------
;	HANDLES THE IF
;	--------------
	@If C2241111_f_DecisionsGet																							; If a decision is coded
			@exit_sub C224111_Table																							; and exit
	@End_If																																	; ENDIF

;	--------------------------
;	HANDLES RESERVED WORDS
;	--------------------------
	@If C2241112_f_ReservedWord																							; If a reserved word
		@exit_sub C224111_Table																								; and exit
	@End_If																																	; ENDIF

;	----------
;	GET or PUT
;	----------
	@If n_Equals,=,0
		@Call C2241113_X_Get																											; create the required FGET for single command
	@Else
		@If n_TableElementTokenStart,>,n_Equals
			@Call C2241113_X_Get																									; create the required FGET
		@end_If
		@If n_TableElementTokenStart,<,n_Equals
			@Call C2241114_X_Put																										; creates the required FPUT
		@end_if
	@end_If

@END_SUB C224111_Table


;-----------------------------------------------------------------------
;								~ C241111_f_Decisions
;-----------------------------------------------------------------------
@BEGIN_FUNCTION C2241111_f_DecisionsGet
;
;	This allows you to get produce 2 fGET's rather than a fGET and a fPUT
;	that is produced by the main code

	@_If {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@IF'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@_IF'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@_OR'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@_AND'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@BEGIN_TEST'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@WHEN'
	@_Or {PR_Line,n_OriginTokenStart,n_OriginTokenLength},=,'@_WHEN'
	@_end
	@ELSE
		@exit_function C2241111_f_DecisionsGet
	@END_IF

	@Call C2241113_X_Get
	@integers_eq RETURN_CODE,c_TRUE

@END_FUNCTION C2241111_f_DecisionsGet

;-----------------------------------------------------------------------
;								~ C241112_f_ReservedWord
;-----------------------------------------------------------------------
@BEGIN_FUNCTION C2241112_f_ReservedWord

;	**********************************************************************************************
;	NOTE:- Table processing got more complicated when I realised I had to cater for Reserved Words
;	ie. T_Char[2] = T_char[1] can be coded as WORDS.COPY T_Char[1],T_Char[2]
;	or at the very least WORDS.FIND {"RET",I},T_Char[1]
;	ergo In some cases iF C24111_f_TableElement:C2411112_f_ReservedWord is true then the whole line
;	will have been processed and "n_TokenStart" will have been set to 999 and this loop will be
;	terminated. For _CALC however, PR_Line is massaged from "integers_calc T_Int[1] = T_Int[2] * 1"
;	to "T_Int[1] = T_Int[2] * 1" and then allowed to fallthru in C241111_Table (ie this Function is
;	set ;	to false 
;	**********************************************************************************************

;	----------------
;	ILLEGAL USE
;	----------------
	@If {PR_Line,n_OriginTokenStart,7},=,'@REPEAT'
		@display v_CyanFG,PR_LineNo,' ',v_RedFG,"Table element cannot be use in this context: ",v_YellowFG,w_Temp40,LF
		@terminate 1
	@End_If


;	----------------
;	ACCEPT
;	----------------
	@_If {PR_Line,n_OriginTokenStart,11},=,'@ACCEPTLINE'
	@_Or {PR_Line,n_OriginTokenStart,14},=,'@ACCEPTLINE_AT'
	@_Or {PR_Line,n_OriginTokenStart,10},=,'@ACCEPT_AT'
	@_End
		@Call C2241114_X_Put
		@integers_eq RETURN_CODE,c_TRUE
		@integers_eq n_TokenStart,999
		@exit_function C2241112_f_ReservedWord
	@END_IF

;	----------------
;	DISPLAY
;	----------------
	@If {PR_Line,n_OriginTokenStart,8},=,'@DISPLAY'
		@Call C2241113_X_Get
		@integers_eq RETURN_CODE,c_TRUE
		@exit_function C2241112_f_ReservedWord
	@End_If

;	----------------
;	CURSOR
;	----------------
	@If {PR_Line,n_OriginTokenStart,8},=,'@CURSOR'
		@Call C2241113_X_Get
		@integers_eq RETURN_CODE,c_TRUE
		@exit_function C2241112_f_ReservedWord
	@End_If

;	----------------
;	DATE_
;	----------------
	@_If {PR_Line,n_OriginTokenStart,09},=,'@DATE_GET'											; IF it's a GET Date/Days
	@_Or {PR_Line,n_OriginTokenStart,13},=,'@DATE_SECONDS'									; OR if it's Seconds
	@_Or {PR_Line,n_OriginTokenStart,11},=,'@DATE_TIMER'										; OR if it's the Timer
	@_End																																		; END
		@Call C2241114_X_Put																										; do a PUT
		@integers_eq RETURN_CODE,c_TRUE																				; Function to true
		@exit_function C2241112_f_ReservedWord																	; and exit
	@End_If																																	; ENDIF

	@If {PR_Line,n_OriginTokenStart,18},=,'@DATE_DATEFROMDAYS'							; IF it's Date from Days
		@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}					; get the next Token
		@integers_eq n_saveStart,n_TokenStart																	; save it
		@If n_saveStart,=,n_TableElementTokenStart														; IF we need a GET
			@Call C2241113_X_Get																									; Do a get
		@Else																																	; ELSE
			@Call C2241114_X_Put																									; Do a PUT
		@End_If																																; END
		@integers_eq RETURN_CODE,c_TRUE																				; Function to true
		@exit_function C2241112_f_ReservedWord																	; and exit
	@End_If																																	; ENDIF

	@If {PR_Line,n_OriginTokenStart,18},=,'@DATE_DAYSFROMDATE'							; IF it's Days from Date
		@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}					; get the next Token
		@integers_eq n_saveStart,n_TokenStart																	; save it
		@If n_saveStart,=,n_TableElementTokenStart														; If we need a PUT
			@Call C2241114_X_Put																										; Do a PUT
		@Else																																	; ELSE
			@Call C2241113_X_Get																										; Do a GET
		@End_If																																; ENDIF
		@integers_eq RETURN_CODE,c_TRUE																				; Function to true
		@exit_function C2241112_f_ReservedWord																	; and exit
	@END_If																																	; ENDIF

;	----------------
;	CALC
;	----------------
;	Seems the simplest way here is just remove the reserved word
;	and let it fall thru (Didn't turn out to be that simple)
	@Words_Find {"_CALC",I},PR_Line																					; INTEGER/NUMBERS_CALC
	@If I,>,0																																; If found one
		@FUNCTION I,f_NextToken,{n_OriginTokenStart,'999'}										; get the source position
		@integers_sub I,2																											; less 2 for length
		@integers_calc J,=,n_OriginTokenStart,-,2															; get the destination length
		@Words_pad {PR_Line,I},{PR_Line,J}																		; Overwrite the ????_Calc

		@Words_Find {"[",OB_OpenSquareBracket},PR_Line												; Reset Opening Bracket
		@words_Find {"]",n_CloseSquareBracket},PR_Line												; Reset Close Bracket
		@Words_find {"=",n_Equals},PR_Line																		; Reset equals
		@FUNCTION n_OriginTokenLength,f_TokenLength,{n_OriginTokenStart,'999'}	; Need the Origin length

		@integers_eq RETURN_CODE,c_FALSE																			; Return FALSE so it will fall thru
		@exit_function C2241112_f_ReservedWord																	; EXIT
	@End_If																																	; ENDIF

;	----------------
;	INTEGERS/NUMBERS
;	----------------
	@_If {PR_Line,n_OriginTokenStart,9},=,'@INTEGERS'												; IF INTEGERS
	@_Or {PR_Line,n_OriginTokenStart,8},=,'@NUMBERS'												; OR NUMBERS
	@_End																																		; END
		@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}					; get the next Token
		@integers_eq n_saveStart,n_TokenStart																	; save it
		@Call C2241113_X_Get																											; Do a get
		@If n_saveStart,=,n_TableElementTokenStart														; If we need a put
			@Words_replace {"fget","fput"},MR_MacroLineItem											; mod the macro
			@integers_eq MR_SortOrder,c_Put																			; Set the Sort Order PUT always follows GET
			@Call X8_WriteMacroLine																						; Write the Macro Line
		@End_If																																; ENDIF
		@integers_eq RETURN_CODE,c_TRUE																				; Function is TRUE
		@integers_eq n_TokenStart,999
		@exit_function C2241112_f_ReservedWord
	@End_If																																	; ENDIF

;	----------------
;	WORDS
;	----------------
;		Words.Copy "Goodbye",T_Char[1]					Words $Copy "Goodbye",T_Char[1]
;		Words.Pad	 T_Char[1],T_Char[2]					Words.$pad T_Char[1],T_Char[2]
;		Words.Uppercase T_Char[1]								Words $Uppercase T_Char[1]
;		Words.Lowercase T_Char[1],T_Char[2]			Words $Lowercase T_Char[1],T_Char[2]
;		Words.Lowercase field,T_Char[2]					Words $Lowercase field,T_Char[2]
;		Words.Lowercase T_Char[1],field					Words $Lowercase T_Char[1],field


	@If {PR_Line,n_OriginTokenStart,6},=,'@WORDS'														; IF WORD

		@If {PR_Line,n_TableElementTokenStart,1},=,"{"
			@display v_CyanFG,PR_LineNo,v_RedFG," Cannot qualify a table item - code this manually",LF
			@terminate 1
		@End_If

		@FUNCTION n_TokenStart,f_NextToken,{n_OriginTokenStart,'999'}					; get the next Token
		@If {PR_Line,n_TokenStart,1},=,"$"																		; If WORDS $pad or the like
			@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}							; Skip over it
		@End_If																																; ENDIF


;		Words.Insert "RET",T_Char[1]						Words $Insert "RET",T_Char[1]
;		Words.Find {"RET",I},T_Char[2]					Words $Find {"RET",I},T_Char[2]
;		Words.Replace {"RET,ROG"},T_Char[1]			Words $Replace {"RET,ROG"},T_Char[1]
		@integers_eq n_99,0																										; Borrow this flag
		@If n_TokenStart,!=,n_TableElementTokenStart													; If 1st Field NOT a table element

			@words_find {"FIND",I},w_UBuffer																		; Do we have WORDS_FIND
			@If I,>,0																														; If YES
				@integers_eq n_99,1																								; Borrow this flag
			@End_If																															; ENDIF
			@words_find {"REPLACE",I},w_UBuffer																	; Do we have WORDS_REPLACE
			@If I,>,0																														; If YES
				@integers_eq n_99,2																								; Borrow this flag
			@End_If																															; ENDIF
			@words_find {"INSERT",I},w_UBuffer																	; Do we have WORDS_INSERT
			@If I,>,0																														; If YES
				@integers_eq n_99,2																								; Borrow this flag
			@End_If																															; ENDIF

		@End_If																																; ENDIF

		@_If n_TokenStart,=,n_TableElementTokenStart													; If we have a table element to copy
		@_Or n_99,>,0																													; or we have a Find/Replace/INSERT
		@_End																																	; END
			@Call C2241113_X_Get																										; then get it
		@End_If																																; ENDIF

		@If n_99,>,1
			@Words_replace {"fget","fput"},MR_MacroLineItem											; mod the macro
			@integers_eq MR_SortOrder,c_Put																			; Set the Sort Order PUT always follows GET
			@Call X8_WriteMacroLine																						; Write the Macro Line
			@integers_eq RETURN_CODE,c_TRUE																			; Function is TRUE
			@exit_function C2241112_f_ReservedWord																; EXIT
		@End_If

		@FUNCTION I,f_NextToken,{n_TableElementTokenStart,'999'}							; get the next Token
		@_If I,=,0																														; If end (Only 1 field - ie WORDS_UPERPCASE T[1])
		@_Or {PR_Line,I,1},=,";"																							; or trailing comment
		@_End																																	; END
			@Words_replace {"fget","fput"},MR_MacroLineItem											; mod the macro
			@integers_eq MR_SortOrder,c_Put																			; Set the Sort Order PUT always follows GET
			@Call X8_WriteMacroLine																						; Write the Macro Line
			@integers_eq RETURN_CODE,c_TRUE																			; Function is TRUE
			@integers_eq n_TokenStart,999																				; So the calling routine will terminate
			@exit_function C2241112_f_ReservedWord																; EXIT
		@Else																																	; ELSE
			@If n_TokenStart,<,n_TableElementTokenStart													; If 1st token is NOT a table
				@Call C2241114_X_Put																								; Just do a put
				@integers_eq RETURN_CODE,c_TRUE																		; Function is TRUE
				@integers_eq n_TokenStart,999																			; So the calling routine will terminate
				@exit_function C2241112_f_ReservedWord															; EXIT
			@End_If																															; ENDIF
		@End_If

		@integers_eq RETURN_CODE,c_TRUE																				; Function is TRUE

	@End_If

@END_FUNCTION C2241112_f_ReservedWord

;-----------------------------------------------------------------------
;							~ C2411_X_Get
;-----------------------------------------------------------------------
@BEGIN_SUB C2241113_X_Get

	@if DN_TableType,=,'X'																									; If it's an XTable
		@words_pad '@XTABLES_fget ',MR_MacroLineItem													; move in the correct literal
	@else																																		; ELSE
		@words_pad  '@TABLES_fget ',MR_MacroLineItem													; move in the correct literal
	@end_if																																	; ENDIF

	@Call X6_NewData
	@integers_eq MR_SortOrder,c_Get																					; Set the Sort Order Get always precedes PUT
	@integers_eq n_GetPut,c_Get																							; cuz NewData may have overwritten them


	@Call C2241115_X_GetPut																										; Load all the fields

	@integers_calc I,=,n_CloseSquareBracket,+,1															; Mark the start point for contracting the line
	@words_pad {PR_Line,I,999},{PR_Line,n_TableElementTokenStart}						; do the contraction
	@words_insert {ND_Insert,16,5},{PR_Line,n_TableElementTokenStart}				; insert the temporary variable name
	@integers_calc J,=,n_TableElementTokenStart,-,2													; step back to its length
	@words_copy "05",{PR_Line,J}																						; then insert it's length
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

@END_SUB C2241113_X_Get

;-----------------------------------------------------------------------
;							~ C2411_X_Put
;-----------------------------------------------------------------------
@BEGIN_SUB C2241114_X_Put

;	--------
;	BUILD IT
;	--------
	@integers_eq MR_SortOrder,c_Put																					; Set the Sort Order PUT always follows GET
	@integers_eq n_GetPut,c_Put

	@if DN_TableType,=,'X'																									; If it's an XTable
		@words_pad '@XTABLES_fput ',MR_MacroLineItem													; move in the correct literal
	@else																																		; ELSE
		@words_pad  '@TABLES_fput ',MR_MacroLineItem													; mov in the correct literal
	@end_if																																	; ENDIF

	@repeat_for I,1,2																												; Step over the "=" to the sending field
		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next Token
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length
	@end_Repeat

;	-------------------
;	Get or Put
;	-------------------
	@Call C2241115_X_GetPut																										; Load all the fields

	@integers_calc I,=,n_CloseSquareBracket,+,1															; Move from here
	@integers_calc J,=,OB_OpenSquareBracket,-,2															; to here
	@words_copy {PR_Line,I},{PR_Line,J}																			; Do the move
	@FUNCTION PR_LineLength,f_LineLength																		; Set the line length

@END_SUB C2241114_X_Put

;-----------------------------------------------------------------------
;							~ C2411_X_GetPut
;-----------------------------------------------------------------------
@BEGIN_SUB C2241115_X_GetPut

	@If n_GetPut,=,c_Get
		@words_pad {ND_Insert,16,5},w_Temp40
	@End_If

	@integers_eq n_dstIdx,15																								; Step past the macro
	@words_copy DN_Table,{MR_MacroLineItem,n_dstIdx}												; and move in the table name

	@repeat_for I,30,1																											; Work backwards thru the TableName field
		@if {DN_Table,I,1},!=,{w_Spaces,1,1}																	; and exit when NOT space
			@exit_repeat																												; giving us the length
		@end_if																																; of the table name
	@end_repeat																															; ENDREPEAT
	@integers_add n_dstIdx,I																								; add it's length to the destination offset
	@words_copy ',',{MR_MacroLineItem,n_dstIdx}															; and move in a comma


	@integers_add n_dstIdx,1																								; Step past the comma
	@words_copy DN_No,w_Temp4
	@words_copy w_Temp4,{MR_MacroLineItem,n_dstIdx}													; and move in the Field No
	@integers_add n_dstIdx,4																								; add it's length to the destination offset
	@words_copy ',',{MR_MacroLineItem,n_dstIdx}															; and move in a comma

	@integers_add n_dstIdx,1																								; Step past the comma
	@words_copy w_Temp40,{MR_MacroLineItem,n_dstIdx}												; and move in the field name

	@repeat_for I,40,1																											; Work backwards thru the fieldname field
		@if {w_Temp40,I,1},!=,{w_Spaces,1,1}																	; and exit when NOT space
			@exit_repeat																												; giving us the length
		@end_if																																; of the field name
	@end_repeat																															; ENDREPEAT
	@integers_add n_dstIdx,I																								; add it's length to the destination offset

;	-----------------------------------------------------------------------------
;	Don't change I from this point on because C2411111_DecisionsGet will use it
;	-----------------------------------------------------------------------------
;	Move in ALL the possible Indexes
;
	@integers_eq b_Flag,c_FALSE																							; Set the do it flag to false
	@integers_eq n_TokenStart,n_OriginTokenStart														; Restart at the origin
	@integers_eq n_TokenLength,n_OriginTokenLength

	@repeat_while 1,=,1																											; Loop

		@If {PR_Line,n_TokenStart,n_TokenLength},=,"["												; If we have found an open bracket
			@integers_eq b_Flag,c_TRUE																					; then set thedo it flag
		@else																																	; ELSE
			@If {PR_Line,n_TokenStart,n_TokenLength},=,"]"											; If we have found a close bracket
				jmp C2241115_Exit																										; EXIT Loop
			@Else																																; ELSE
				@If b_Flag,=,c_TRUE																								; If we are doing it
					@words_copy ',',{MR_MacroLineItem,n_dstIdx}											; and move in a comma
					@integers_add n_dstIdx,1																				; Step past the comma
					@words_copy {PR_Line,n_TokenStart,n_TokenLength},{MR_MacroLineItem,n_dstIdx}	; and move in the Index
					@integers_add n_dstIdx,n_TokenLength														; Step past the field
				@End_If
			@End_If
		@End_If

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next Token
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length

	@End_Repeat
	C2241115_Exit:

;	--------
;	INDENT ?
;	--------
;roger
;	@If n_OriginTokenStart,>,3																							; If we have an Indent
;		@numbers_eq n_99,{PR_Line,1,2}																				; get its length
;		@words_insert {PR_Line,3,n_99},MR_MacroLineItem												; move the Indent
;	@End_If																																	; ENDIF

	@Call X8_WriteMacroLine																								; Write the Macro Line

@END_SUB C2241115_X_GetPut

;------------------------------------------------------------
;						~ C2412_Precedence
;------------------------------------------------------------
@BEGIN_SUB C22412_Precedence

;	-------------------------------
;	CREATE OR REUSE THE TEMP NUMBER
;	-------------------------------
	@words_pad {PR_Line,n_OriginTokenStart,n_OriginTokenLength},w_Temp40		; Grab the 1st field
	@Call X4_SearchByName																										; Is it a variable
	@If DataNameTable_STATUS,!=,0																						; If not then
		@Call X1_TokenToRaw																										; Convert to RAW languageONE
		@display v_CyanFG,PR_LineNo,v_RedFG," Invalid use of Precedence",LF
		@display_Line w_saveLine
		@terminate 1
	@End_If																																	; ENDIF

	@Call X6_NewData																												; Get a data item you can use

;	----------------------
;	CREATE THE CALCULATION
;	----------------------
	@integers_eq n_dstIdx,1																									; we are starting at 1
;	@words_copy c_N,w_DataType																							; Always use Numbers for created macros
;	@words_pad '@NUMBERS_CALC',{MR_MacroLineItem,n_dstIdx}									; begin with the .calc statement


;	A blanket use of @NUMBERS didn't work because the QSORT was failing. Remember that @NUMBERS
;	rounds the result. We do have to use it though even if in integer is the result in an equation
;	that uses FixedPoint numbers. @INTEGERS won't handle that. I am thinking that there maybe
;	should be multiple occurrences of PR_Type so that everything can be recognised in the initial
;	load. Maybe for the future

	@words_find {".",I},PR_Line
	@If I,>,0
		@words_copy c_N,w_DataType
	@End_If

	@if w_DataType,=,c_N																			; If its a fixed point number
		@words_pad  '@NUMBERS_CALC',MR_MacroLineItem						; begin with the .calc statement
	@else																											; @else
		@words_pad  '@INTEGERS_CALC',MR_MacroLineItem						; begin with the .calc statement
	@end_if																										; END

	@integers_add n_dstIdx,16
	@words_copy {ND_Insert,16,5},{MR_MacroLineItem,n_dstIdx}								; insert the temporary data name
	@integers_add n_dstIdx,5

;	=============================================
; NEED TO WALK THE TOKENS HERE AND MOVE THEM IN
;
;	01\t03n_1-1=01[03n_101/01[01201*12{345,''9.99'}01]01]
;	@NUMBERS_CALC  n0001,=


;	SETUP START POINT AND LENGTH

	@integers_calc n_TokenStart,=,OB_OpenSquareBracket,+,3										; Step over the Open Bracket and next token length
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	@integers_eq b_Flag,c_TRUE																							; set a flag for initial occurance of loop

	@repeat_while {PR_Line,n_TokenStart,1},!=,x_CloseSquareBracket					; START LOOP okay so while we do not have a "]"

		@If b_Flag,=,c_TRUE																										; If at the 1st occurance of loop
			@integers_eq b_Flag,c_FALSE																					; set the flag to false
			@words_copy ",=,",{MR_MacroLineItem,n_dstIdx}												; insert a comma, an equals, and a comma
			@integers_add n_dstIdx,3																						; & increment the destination idx
		@Else																																	; ELSE
			@words_copy ",",{MR_MacroLineItem,n_dstIdx}													; insert a comma
			@integers_add n_dstIdx,1																						; & increment the destination idx
		@End_If																																; ENDIF

		@words_copy {PR_Line,n_TokenStart,n_TokenLength},{MR_MacroLineItem,n_dstIdx}	; write the Token into the Macro line
		@integers_add n_dstIdx,n_TokenLength																	; Add the token length to the macro offset

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; get the next Token
		@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}						; get its length

	@end_repeat																															; END LOOP

;	--------
;	Write it
;	--------
	@integers_eq MR_MacroNo,n_MacroNo																				; store the macro no for later
	@integers_add MR_SortOrder,1																						; To maintain the sort as written

	@Call X8_WriteMacroLine																								; next table slot

	@integers_calc I,=,n_CloseSquareBracket,+,1															; Mark the start point for contracting the line
	@integers_calc J,=,OB_OpenSquareBracket,-,2															; Mark the end point for contracting the line 
	@words_pad {PR_Line,I,999},{PR_Line,J}																	; do the contraction
	@words_insert {ND_Insert,16,5},{PR_Line,J}															; insert the temporary variable name
	@words_insert "05",{PR_Line,J}																					; then insert it's length

@END_SUB C22412_Precedence

;------------------------------------------------------------------------
; C25_DisplayResults
;------------------------------------------------------------------------
@BEGIN_SUB C23_DisplayResults

	@files $write,STDOUT,"  [",n_NoOfBeginSubs,     "] Begin Subs      [",n_NoOfEndSubs,"] End Subs"
	@files $write,STDOUT,"  [",n_NoOfBeginFunctions,"] Begin Functions [",n_NoOfEndFunctions,"] End Functions"
	@files $write,STDOUT,"  [",n_NoOfRepeats,       "] Begin Repeats   [",n_NoOfEndRepeats,"] End Repeats"
	@files $write,STDOUT,"  [",n_NoOfIfs,           "] IF's            [",n_NoOfEndIfs,"] End Ifs"
	@files $write,STDOUT,"  [",n_NoOfBeginTests,    "] Begin Test's    [",n_NoOfEndTests,"] End Tests"
	@files $write,STDOUT,"  [",n_NoOfWhens,         "] When's          [",n_NoOfWends,"] Wend's"
	@files $write,STDOUT,"  [",n_NoOfOpenBraces,    "] Open Braces     [",n_NoOfCloseBraces,"] Close Braces"
	@files $write,STDOUT,"  [",n_NoOfOpenSQBrackets,"] Open SqBrackets [",n_NoOfCloseSQBrackets,"] Close SqBrackets"
	
	@files $write,STDOUT,' '
	
	@if n_NoOfBeginSubs,!=,n_NoOfEndSubs
		@files $write,STDOUT,"    11: Begin/End Subs are not balanced"
		@integers_eq ERROR_CODE,11
	@end_if

	@if n_NoOfRepeats,!=,n_NoOfEndRepeats
		@files $write,STDOUT,"    12: Begin/End Repeats are not balanced"
		@integers_eq ERROR_CODE,12
	@end_if

	@if n_NoOfIfs,!=,n_NoOfEndIfs
		@files $write,STDOUT,"    13: Begin/End Ifs are not balanced"
		@integers_eq ERROR_CODE,13
	@end_if

;	@if n_NoOfDow_ExtraDelimiternds,!=,n_NoOfDotEnds
;		@files $write,STDOUT,"    14: Begin/End dot commands are not balanced"
;		@integers_eq ERROR_CODE,14
;	@end_if

	@if n_NoOfBeginTests,!=,n_NoOfEndTests
		@files $write,STDOUT,"    15: Begin/End Tests are not balanced"
		@integers_eq ERROR_CODE,15
	@end_if

	@if n_NoOfWhens,!=,n_NoOfWends
		@files $write,STDOUT,"    16: @when/@wends are not balanced"
		@integers_eq ERROR_CODE,16
	@end_if

	@if n_NoOfOpenBraces,!=,n_NoOfCloseBraces
		@files $write,STDOUT,"    17: Braces are not balanced"
		@integers_eq ERROR_CODE,17
	@end_if

	@if n_NoOfOpenSQBrackets,!=,n_NoOfCloseSQBrackets
		@files $write,STDOUT,"    18: Square Brackets are not balanced"
		@integers_eq ERROR_CODE,18
	@end_if

@END_SUB C23_DisplayResults

;------------------------------------------------------------------------
;C29_CompressLiteral
;------------------------------------------------------------------------
@BEGIN_SUB C29_CompressLiteral
	@SAVING I

	@integers_eq n_NewLitPlaces,0

	@repeat_for I,n_StartLit,n_EndLit																				; LOOP from start to end

		@begin_test {PR_Line,I,1}

			@when =,'.'																													; WHEN we have a decimal place
				@integers_eq b_Flag,c_TRUE																				; then set the flag
			@wend																																; WEND

			@when _IN,{'-','0','1','2','3','4','5','6','7','8','9','-','+'}			; WHEN its a number;
				@if b_Flag,=,c_TRUE																								; IF they are decimal places
					@integers_add n_NewLitPlaces,1																	; accumulate them
				@end_if																														; ENDIF
				@integers_add n_NewLitLen,1																				; build new literal
				@words_copy {PR_Line,I,1},{w_NewLit,n_NewLitLen}									; move the value
			@wend

		@end_test																															; ENDTEST

	@end_repeat																															; ENDREPEAT

	@RESTORE I
@END_SUB C29_CompressLiteral


;		~=========
;		~D_3rdPass
;		~=========
@BEGIN_SUB D3_3rdPass

;	----------
;	OPEN FILES
;	----------
	@files_open out_File,$write+$beginning																	; and open the new output file for writing

;	-------------
;	LOAD SYNONYMS
;	-------------
	@If b_Windows,=,c_TRUE																									; If its a NASM rewrite
		@Call D31_MASM_LoadSynonyms																						; load the =;!=;< etc --> _EQ;_NEQ;_LT
	@end_if																																	; ENDIF

	@integers_eq b_FoundDictionary,c_FALSE																	; Initialise flag
	@integers_eq b_FoundMatrix,c_FALSE																			; Initialise flag
	@integers_eq b_FoundProcedure,c_FALSE																		; Initialise flag

;	-------
;	PROCESS
;	-------
	@repeat_for n_LineCtr,1,ProgramTable_UBOUND															; LOOP thru the Program Table

		@xtables_rget ProgramTable,n_LineCtr																	; Grab a record

@If n_LineCtr,>,356
xor rax,rax
@End_If

		@If PR_Type,=,"B"																											; If its a blank line
			@files $write,out_File," "																					; Write a blank
		@Else

			@If PR_Type,!=,c_R
				@Call X1_TokenToRaw																								; Convert to RAW languageONE
				@Words_pad w_saveLine,PR_Line
			@End_If
			@Words_Uppercase PR_Line,w_UBuffer																	; in Uppercase

			@If PR_Type,=,";"																										; If its a comment
				@files $write,out_File,{PR_Line,1,PR_LineLength}									; Write it out
			@Else

				@If PR_Type,_IN,{"D","T","I","%"}
					@If b_Windows,=,c_TRUE																					; IF WINDOWS
						@Call D32_MASM																									; Do the MASM changes
					@End_If																													; END
				@End_If

				@begin_test c_TRUE																								; 3 things to look for

					@when b_FoundDictionary,=,c_FALSE																; If we have not found BEGIN.DICTIONARY yet
						@files $write,out_File,{PR_Line,1,PR_LineLength}							; Write out the Keyword line
						@words_find {'BEGIN.DICTIONARY',I},w_UBuffer									; Look for the start of the dictionary
						@if  I,>,0																										; If we have found it
							@integers_eq b_FoundDictionary,c_TRUE												; flag it as found
							@words_copy c_W,f_DataType																	; flag it for Write New Data
							@Call D33_WriteNewData																				; and write out the created words
						@end_if																												; ENDIF
					@wend																														; WEND

					@when b_FoundMatrix,=,c_FALSE																		; If we have not found BEGIN.MATRIX yet
						@files $write,out_File,{PR_Line,1,PR_LineLength}							; Write out the Keyword line 	
						@words_find {'BEGIN.MATRIX',I},w_UBuffer											; Look for the start of the matrix
						@if  I,>,0																										; If we have found it
							@integers_eq b_FoundMatrix,c_TRUE														; flag it as found
							@words_copy c_I,f_DataType																	; flag it for Write New Data
							@Call D33_WriteNewData																				; and write out the created integers
							@words_copy c_N,f_DataType																	; flag it for Write New Data
							@Call D33_WriteNewData																				; and write out the created FP
						@end_if																												; ENDIF
					@wend																														; WEND

					@when b_FoundProcedure,=,c_FALSE																; but not found the procedures yet
						@words_find {'BEGIN.INSTRUCTIONS',I},w_UBuffer								; look for the start of the procedures
						@if  I,>,0																										; If we have found it
							@integers_eq b_FoundProcedure,c_TRUE												; flag it as found
							@Call D34_WriteMacros																				; and write out the macro
							@files $write,out_File,{PR_Line,1,PR_LineLength}						; Write out the Keyword line
						@else
							@files $write,out_File,{PR_Line,1,PR_LineLength}						; Write out the Keyword line
						@end_if
					@wend																														; @wend

					@otherwise
						@files $write,out_File,{PR_Line,1,PR_LineLength}							; Write out the Keyword line

				@end_test																													; ENDTEST

			@End_If																															; ENDIF
		@End_If																																; ENDIF
	@end_repeat																															; ENDREPEAT

;	-----------
;	WRITE END
;	-----------
	@IF b_Windows,=,c_TRUE
		@files $write,out_File,"END"
	@End_If		

;	-----------
;	CLOSE FILES
;	-----------
	@files_close out_File

@END_SUB D3_3rdPass

;-------------------------------------------------------------------------------
;			~ D1_MASM_LoadSynonyms
;-------------------------------------------------------------------------------
@BEGIN_SUB D31_MASM_LoadSynonyms

;	Synonyms are proving to be very useful. Here we can swap the =/!=/> etc of NASM
;	for the _EQ/_NEQ/_GT etc of MASM 

;	----------
;	Decisions
;	----------
;	Because the 1st pass has done the work common to Linux/Windows we can now
;	over-write the synonym table with just the changes we need for Windows
	@integers_eq SynonymTable_UBOUND,0


	@Words_pad x_NEQ,Synonym
	@Integers_Eq lenSynonym,2
	@Words_pad "_NEQ",Keyword
	@Integers_Eq lenKeyword,4
	@Call X3_PutXtable

	@Words_pad x_NLT,Synonym
	@Words_pad "_NLT",Keyword
	@Call X3_PutXtable

	@Words_pad x_NGT,Synonym
	@Words_pad "_NGT",Keyword
	@Call X3_PutXtable

	@Words_pad x_GTE,Synonym
	@Words_pad "_NLT",Keyword
	@Call X3_PutXtable

	@Words_pad x_EGT,Synonym
	@Words_pad "_NLT",Keyword
	@Call X3_PutXtable

	@Words_pad x_LTE,Synonym
	@Words_pad "_NGT",Keyword
	@Call X3_PutXtable

	@Words_pad x_ELT,Synonym
	@Words_pad "_NGT",Keyword
	@Call X3_PutXtable

;	NOTE - these have to follow the above else you will find for example
;	an equals in a !=

	@Words_Pad x_EQ,Synonym
	@Integers_Eq lenSynonym,1
	@Words_pad "_EQ",Keyword
	@Integers_Eq lenKeyword,3
	@Call X3_PutXtable

	@Words_pad x_GT,Synonym
	@Words_pad "_GT",Keyword
	@Call X3_PutXtable

	@Words_pad x_LT,Synonym
	@Words_pad "_LT",Keyword
	@Call X3_PutXtable

;	----------
;	Constants
;	----------
	@Words_Pad "C_TRUE",Synonym
	@Integers_Eq lenSynonym,6
	@Words_Pad "%c_TRUE",Keyword
	@Integers_Eq lenKeyword,7
	@Call X3_PutXtable

	@Words_Pad "C_FALSE",Synonym
	@Integers_Eq lenSynonym,7
	@Words_Pad "%c_FALSE",Keyword
	@Integers_Eq lenKeyword,8
	@Call X3_PutXtable

	@Words_Pad "C_RETURN",Synonym
	@Integers_Eq lenSynonym,8
	@Words_Pad "%c_RETURN",Keyword
	@Integers_Eq lenKeyword,9
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY1",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY1",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY2",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY2",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY3",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY3",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable
	
	@Words_Pad "C_FUNCTIONKEY4",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY4",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY5",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY5",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY6",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY6",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY7",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY7",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY8",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY8",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY9",Synonym
	@Integers_Eq lenSynonym,14
	@Words_Pad "%c_FUNCTIONKEY9",Keyword
	@Integers_Eq lenKeyword,15
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY10",Synonym
	@Integers_Eq lenSynonym,15
	@Words_Pad "%c_FUNCTIONKEY10",Keyword
	@Integers_Eq lenKeyword,16
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY11",Synonym
	@Integers_Eq lenSynonym,15
	@Words_Pad "%c_FUNCTIONKEY11",Keyword
	@Integers_Eq lenKeyword,16
	@Call X3_PutXtable

	@Words_Pad "C_FUNCTIONKEY12",Synonym
	@Integers_Eq lenSynonym,15
	@Words_Pad "%c_FUNCTIONKEY12",Keyword
	@Integers_Eq lenKeyword,16
	@Call X3_PutXtable

	@Words_Pad "C_ALT",Synonym
	@Integers_Eq lenSynonym,5
	@Words_Pad "%c_ALT",Keyword
	@Integers_Eq lenKeyword,6
	@Call X3_PutXtable

	@Words_Pad "C_ARROWUP",Synonym
	@Integers_Eq lenSynonym,9
	@Words_Pad "%c_ARROWUP",Keyword
	@Integers_Eq lenKeyword,10
	@Call X3_PutXtable

	@Words_Pad "C_ARROWDOWN",Synonym
	@Integers_Eq lenSynonym,11
	@Words_Pad "%c_ARROWDOWN",Keyword
	@Integers_Eq lenKeyword,12
	@Call X3_PutXtable

	@Words_Pad "C_ARROWRIGHT",Synonym
	@Integers_Eq lenSynonym,12
	@Words_Pad "%c_ARROWRIGHT",Keyword
	@Integers_Eq lenKeyword,13
	@Call X3_PutXtable

	@Words_Pad "C_ARROWLEFT",Synonym
	@Integers_Eq lenSynonym,11
	@Words_Pad "%c_ARROWLEFT",Keyword
	@Integers_Eq lenKeyword,12
	@Call X3_PutXtable

	@Words_Pad "C_END",Synonym
	@Integers_Eq lenSynonym,5
	@Words_Pad "%c_END",Keyword
	@Integers_Eq lenKeyword,6
	@Call X3_PutXtable

	@Words_Pad "C_HOME",Synonym
	@Integers_Eq lenSynonym,6
	@Words_Pad "%c_HOME",Keyword
	@Integers_Eq lenKeyword,7
	@Call X3_PutXtable

	@Words_Pad "C_INSERT",Synonym
	@Integers_Eq lenSynonym,8
	@Words_Pad "%c_INSERT",Keyword
	@Integers_Eq lenKeyword,9
	@Call X3_PutXtable

	@Words_Pad "C_ENDOFFIELD",Synonym
	@Integers_Eq lenSynonym,12
	@Words_Pad "%c_ENDOFFIELD",Keyword
	@Integers_Eq lenKeyword,13
	@Call X3_PutXtable

	@Words_Pad "C_ESCAPE",Synonym
	@Integers_Eq lenSynonym,8
	@Words_Pad "%c_ESCAPE",Keyword
	@Integers_Eq lenKeyword,9
	@Call X3_PutXtable

	@Words_Pad "C_BACKSPACE",Synonym
	@Integers_Eq lenSynonym,11
	@Words_Pad "%c_BACKSPACE",Keyword
	@Integers_Eq lenKeyword,10
	@Call X3_PutXtable

	@Words_Pad "C_NONE",Synonym
	@Integers_Eq lenSynonym,6
	@Words_Pad "%c_NONE",Keyword
	@Integers_Eq lenKeyword,7
	@Call X3_PutXtable

;	----------
;	Macros
;	----------
	@Words_Pad "%MACRO",Synonym
	@Integers_Eq lenSynonym,6
	@Words_Pad "STARTMACRO",Keyword
	@Integers_Eq lenKeyword,10
	@Call X3_PutXtable

	@Words_Pad "%IMACRO",Synonym
	@Integers_Eq lenSynonym,7
	@Words_Pad "STARTMACRO",Keyword
	@Integers_Eq lenKeyword,10
	@Call X3_PutXtable

	@Words_Pad "%ENDMACRO",Synonym
	@Integers_Eq lenSynonym,9
	@Words_Pad "ENDM",Keyword
	@Integers_Eq lenKeyword,4
	@Call X3_PutXtable

	@Words_Pad "%1",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg1",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%2",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg2",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%3",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg3",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%4",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg4",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%5",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg5",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%6",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg6",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%7",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg7",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

	@Words_Pad "%8",Synonym
	@Integers_Eq lenSynonym,2
	@Words_Pad "_arg8",Keyword
	@Integers_Eq lenKeyword,5
	@Call X3_PutXtable

@END_SUB D31_MASM_LoadSynonyms

;=======================================================================
;			~ D2_MASM
;=======================================================================
@BEGIN_SUB D32_MASM
;
;	This is done after B11_TokenToRaw so we are working on the original
;	text. I thinks it's just a bit easier this way.
;
;	----------------------------------------------
;	Run through the line and do the changes
;	----------------------------------------------

	@Call D322_Synonyms																											; Swap the Synonyms

	@Repeat_For I,1,PR_LineLength																						; REPEAT

	;	QUOTES
		@If {w_UBuffer,I,1},_IN,{x_Quote1,x_Quote2}														; Do we have quote
			@words_copy {w_UBuffer,I,1},w_Quote																	; then save it
			@integers_add I,1																										; step over it
			@Repeat_For I,I,PR_LineLength																				; Search for the closing one
				@If {w_UBuffer,I,1},=,w_Quote																			; have we found it
					@integers_add I,1																								; step over it
					@exit_repeat																										; EXIT REPEAT
				@End_if																														; ENDIF
			@End_Repeat																													; END REPEAT
			@If I,>,PR_LineLength																								; Was it the last char in the line
				jmp D32_MASM_001																										; EXIT REPEAT
			@End_If																															; ENDIF
		@End_If																																; ENDIF

	;	COMMENT
		@IF {w_UBuffer,I,1},=,';'																							; If we find a comment
			jmp D32_MASM_001																											; EXITREPEAT@
		@End_If																																; ENDIF

	;	SECTION
		@IF {w_UBuffer,I,7},=,"SECTION"																				; If we find a SECTION
			@integers_calc J,=,I,+,7																						; Get the source idx
			@words_pad {PR_Line,J},{PR_Line,I}																	; shrink PR_Line
			@words_pad {w_UBuffer,J},{w_UBuffer,I}															; and w_UBuffer
			@integers_sub PR_LineLength,7																				; subtract from line length
			@words_find {".BSS",J},w_UBuffer																		; Look for.BSS
			@if J,>,0																														; If we find it
				@Words_copy ".data?",{PR_Line,J}																	; replace it
				@integers_add PR_LineLength,2																			; add to line length
			@End_If																															; ENDIF
			@words_find {".TEXT",J},w_UBuffer																		; Look for .TEXT
			@if J,>,0																														; If we find it
				@Words_copy ".code",{PR_Line,J}																		; replace it
			@End_If																															; ENDIF
			jmp D32_MASM_001																											; EXITREPEAT
		@End_If																																; ENDIF

	;	INCLUDE
		@IF {w_UBuffer,I,8},=,"%INCLUDE"																			; If we find a %INCLUDE
			@Words_copy {w_Spaces,1,1},{PR_Line,I,1}														; space out the % sign
			@integers_add I,9
			@words_copy x_LessThan,w_Char
			@repeat_for I,I,PR_LineLength
				@_If {PR_Line,I,1},=,x_Quote1
				@_Or {PR_Line,I,1},=,x_Quote2
				@_End
					@words_copy w_Char,{PR_Line,I,1}
					@Words_copy x_GreaterThan,w_Char
				@End_If
			@End_Repeat
			jmp D32_MASM_001																											; EXITREPEAT
		@End_If																																; END_IF

	;	DEFINE CONSTANTS - Create EQU Entries
		@_IF {w_UBuffer,I,7},=,"%DEFINE"																			; If we find a %DEFINE
		@_OR {w_UBuffer,I,8},=,"%IDEFINE"																			; or an %IDEFINE
		@_END																																	; END
			@Call D321_ConvertConstants																					; Convert constants
			jmp D32_MASM_001																											; EXITREPEAT
		@End_IF																																; END


	;	CALC - requires single set of angle brackets
		@IF {w_UBuffer,I,6},=,"_CALC "																				; If we find a _CALC
			@Words_Find {x_Equals,I},PR_Line																		; go to the equals
			@Words_Find {",",I},{PR_Line,I}																			; and then the comma
			@Integers_Add I,1																										; step over it
			@Words_Insert x_LessThan,{PR_Line,I}																; insert a <
			@Words_Find {" ",J},{PR_Line,I}																			; Check for a space (If commented)
				@If J,=,0
					@integers_eq I,PR_LineLength
				@End_If
			@Words_Insert x_GreaterThan,{PR_Line,J}															; insert a > at the end
			@Integers_add PR_LineLength,2																				; extend the line
		@End_If																																; ENDIF

	;	BRACES
		@IF {PR_Line,I,1},=,x_OpenBrace																				; If an opening brace
			@Words_Copy x_LessThan,{PR_Line,I}																	; Replace it and
			@Words_Find {"INSERTWORD",J},w_UBuffer															; 2nd one if NOT insertword
			@Words_Find {"INSERTNUMBER",K},w_UBuffer														; 2nd one if NOT insertnumber
			@_If	J,=,0																													; cuz J = 0 (not found)
			@_and K,=,0																													; cuz K = 0 (not found)
			@_end
				@Words_Insert x_LessThan,{PR_Line,I}															; add another one
				@Integers_add PR_LineLength,1																			; extent the line
				@Integers_add I,1																									; move I along
			@End_If																															; ENDIF
		@End_If																																; ENDIF

		@IF {PR_Line,I,1},=,x_CloseBrace																			; If a closing brace
			@Words_Copy x_GreaterThan,{PR_Line,I}																; Replace it and
			@Words_Find {"INSERTWORD",J},w_UBuffer															; 2nd one if NOT insertword
			@Words_Find {"INSERTNUMBER",K},w_UBuffer														; 2nd one if NOT insertnumber
			@_If	J,=,0																													; cuz J = 0 (not found)
			@_and K,=,0																													; cuz K = 0 (not found)
			@_end
				@Words_Insert x_GreaterThan,{PR_Line,I}														; add another one
				@Integers_add PR_LineLength,1																			; extend the line
				@Integers_add I,1																									; move I along
			@End_If																															; ENDIF
		@End_If																																; ENDIF

		@Words_uppercase PR_Line,w_UBuffer

	@End_Repeat																															; ENDREPEAT
	D32_MASM_001:

;	-----------------------------
;	Check Constants
;	-----------------------------
	@If PR_Type,_IN,{"D","%",";"}																						; If we are in the data section
		@exit_sub D32_MASM																											; then exit
	@End_If																																	; ENDIF

	@Repeat_for I,1,DataNameTable_UBOUND																		; REPEAT thru the DN_Name table
		@tables_rGet DataNameTable,I																					; grab a name

		@If DN_Type,=,c_C																											; If we are a constant
			@begin_raw																													; BEGIN RAW
				mov rax,qword[DN_NameLength]																			; Set length of DN_Name
				mov qword[DN_Name-8],rax																					; to match length in PR_Line (for FIND)
			@end_raw																														; END RAW
			@Words_Find {DN_Name,J},PR_Line																			; Now do the FIND
			@begin_raw																													; BEGIN RAW
				mov qword[DN_Name-8],40																						; Restore length of DN_Name
			@end_raw																														; END RAW

			@IF J,>,0																														; If we had a match

				@integers_calc K,=,J,-,1																					; make sure we haven't just done it
				@If {PR_Line,K},!=,"%"																						; So if we havent
					@words_insert "%",{PR_Line,J}																		; insert the %
					@Integers_add PR_LineLength,1																		; and increase the line length
					@Integers_add J,2																								; and step over it
				@End_If

			@End_If																															; ENDIF

		@End_If																																; ENDIF

	@End_Repeat																															; ENDREPEAT

@END_SUB D32_MASM

;-----------------------------------------------------------------------
;				~ D21_ConvertConstants
;-----------------------------------------------------------------------
@BEGIN_SUB D321_ConvertConstants

;	%define rog1 123				rog1 EQU 123
;	%define rog2 'Hello'		rog2 TEXTEQU 'Hello'

	@Integers_calc J,=,I,+,8																								; step over %DEFINE

;	-----------------------------
;	Loops with loops within loops
;	-----------------------------
	@repeat_for J,J,PR_LineLength																						; Running along the line

		@If {PR_Line,J,1},_NIN,{" ",x_Tab}																		; If we have found the name

			@words_copy {PR_Line,J},{PR_Line,I}																	; move it to beginning of line
			@Integers_sub PR_LineLength,J																				; Sub off Length
			@Integers_add PR_LineLength,I																				; add to length
			@integers_eq J,I																										; Set index back after move

			@repeat_for J,J,PR_LineLength																				; Continue along the line

				@If {PR_Line,J,1},_IN,{" ",x_Tab}																	; If we have found a space

					@repeat_for J,J,PR_LineLength																		; Continue along the line

						@If {PR_Line,J,1},_NIN,{" ",x_Tab}														; If we have found the value

							@If {PR_Line,J,1},_IN,{"'",'"'}															; If its quotes
								@words_insert x_LessThan,{PR_Line,J,1}										; Insert an open angle bracket
								@words_insert "TEXTEQU ",{PR_Line,J}											; Insert TEXTEQU
								@Integers_add PR_LineLength,10														; add to line length
								@words_copy x_GreaterThan,{PR_Line,PR_LineLength,1}				; and place the close angle bracket
								@Exit_sub D321_ConvertConstants														; and out
							@Else																												; ELSE
								@words_insert "EQU ",{PR_Line,J}													; Insert TEXTEQU
								@Integers_add PR_LineLength,4															; add to the line length
								@Exit_sub D321_ConvertConstants														; and out
							@End_If																											; ENDIF

						@End_If																												; ENDIF
					@End_Repeat																											; ENDREPEAT
				@End_If																														; ENDIF
			@End_Repeat																													; ENDREPEAT
		@End_If																																; ENDIF
	@End_repeat																															; ENDREPEAT

@END_SUB D321_ConvertConstants


;-----------------------------------------------------------------------
;				~ D22_Synonyms
;-----------------------------------------------------------------------
@BEGIN_SUB D322_Synonyms

	@repeat_for J,1,SynonymTable_UBOUND

		@Call D3221_GetSynonyms

		@Words_Find {w_Synonym,K},PR_Line
		@IF K,>,0

		;	--------------------------
		;	Make sure it is not quoted
		;	--------------------------
			@Words_Find {x_Quote1,L},PR_Line																		; Check for opening quote
			@If L,>,0																														; If found
				@integers_calc N,=,L,+,1																					; step over it
				@Words_Find {x_Quote1,M},{PR_Line,N}															; and look for closing quote
				@_If K,>,L																												; If our synonym is past the opening quote
				@_and K,<,M																												; but before the closing quote
				@_End																															; END
					@exit_Sub D322_Synonyms																					; then exit
				@End_If																														; ENDIF
			@End_If																															; ENDIF
			@Words_Find {x_Quote2,L},PR_Line																		; Check for opening quote
			@If L,>,0																														; If found
				@integers_calc N,=,L,+,1																					; step over it
				@Words_Find {x_Quote2,M},{PR_Line,N}															; and look for closing quote
				@_If K,>,L																												; If our synonym is past the opening quote
				@_and K,<,M																												; but before the closing quote
				@_End																															; END
					@exit_Sub D322_Synonyms																					; then exit
				@End_If																														; ENDIF
			@End_If																															; ENDIF
		;	--------------------------
		;	Make sure it is not quoted
		;	--------------------------

			@IF w_Synonym,=,x_Equals																						; If we are looking for equals
				@words_find {"S_CALC",L},{w_UBuffer}															; Search for integers_calc/numbers_calc
				@If L,>,0																													; If we have found it
;					@exit_Sub D22_Synonyms
					jmp nextIteration
				@End_If
			@End_IF

			@if lenKeyword,>,lenSynonym
			;	--------------
			;	MAKE SOME ROOM
			;	--------------
				@integers_calc M,=,lenKeyword,-,lenSynonym												; subtract the Synonym length from the Keywords length
				@integers_add PR_LineLength,M
				@words_insert {w_Spaces,1,M},{PR_Line,K}													; Insert some spaces

			@else
			;	------------
			;	SQUASH IT UP
			;	------------
				@integers_calc M,=,K,+,lenSynonym,-,lenKeyword												; subtract the Keyword length from the Synonym length
				@words_pad {PR_Line,M},{PR_Line,K}															; Now do the squashing move
				@integers_calc M,=,lenSynonym,-,lenKeyword												; subtract the Keyword length from the Synonym length
				@integers_sub PR_LineLength,M											; subtract the Keyword length from the Synonym length

			@end_if
		;	----------------------
		;	AND DO THE REPLACEMENT
		;	----------------------
			@words_copy {Keyword,1,lenKeyword},{PR_Line,K}											; Copy in the Synonym

		@End_If

	nextIteration:
	@end_repeat

@END_SUB D322_Synonyms

;-------------------------------------------------------------------------------
;					~ D221_GetSynonyms
;-------------------------------------------------------------------------------
@BEGIN_SUB D3221_GetSynonyms
 
	@xtables_rget SynonymTable,J
 
;	SET LENGTH
	@begin_raw
		mov qword[w_Synonym-8],30											; to its original
	@end_raw
 
;	GRAB THE SYNONYM
	@words_pad {Synonym,1,lenSynonym},w_Synonym
 
;	AND RESET THE LENGTH
	@begin_raw
		mov rax,qword[lenSynonym]											; length so that
		mov qword[w_Synonym-8],rax											; find will work
	@end_raw

@END_SUB D3221_GetSynonyms


;-----------------------------------------------------------------------
;				~ D3_WriteNewData
;-----------------------------------------------------------------------
@BEGIN_SUB D33_WriteNewData

	@files $write,out_File," "																							; Write out a blank line
	@begin_test f_DataType																									; and comments
		@when =,c_W
			@files $write,out_File,';(BEGIN):Temporary Words by languageONE'
		@wend
		@when =,c_I
			@files $write,out_File,';(BEGIN):Temporary Integers by languageONE'
		@wend
		@when =,c_N
			@files $write,out_File,';(BEGIN):Temporary FixedPoint numbers by languageONE'
		@wend
	@end_test

	@integers_eq b_Flag,c_FALSE																							; Setup a write flag

	@integers_eq n_NDIdx,1																									; Start the table at 1
	@xtables_rget NewDataTable,n_NDIdx																			; and grab the record

	@repeat_while NewDataTable_STATUS,=,0																		; LOOP until end of records

		@_If f_DataType,=,c_W																									; If we are requesting a WORD
		@_and ND_Type,=,c_W																										; and we have one
		@_end																																	; then 
			@integers_eq b_Flag,c_TRUE																					; set the write flag to true
		@end_if																																; ENDIF

		@_If f_DataType,=,c_I																									; If we are requesting an INTEGER
		@_and ND_Type,=,c_I																										; and we have one
		@_end																																	; then
			@integers_eq b_Flag,c_TRUE																					; set the write flag to true
		@end_if																																; ENDIF

		@_If f_DataType,=,c_N																									; If we are requesting a NUMBER
		@_and ND_Type,=,c_N																										; and we have one
		@_end																																	; then
			@integers_eq b_Flag,c_TRUE																					; set the write flag to true
		@end_if																																; ENDIF

		@if b_Flag,=,c_TRUE																										; If we have identified a WRITE

			@repeat_for I,60,1																									; Running backwards from the end
				@If {ND_Insert,I,1},_NIN,{" ",x_Tab}															; If we have a real character
					@exit_repeat																										; exit
				@End_if																														; ENDIF
			@End_Repeat																													; ENDREPEAT

			@files $write,out_File,{ND_Insert,1,I}																; then write out the record
			@integers_eq b_Flag,c_FALSE																					; and set the write flag to false
		@end_if																																; ENDIF

		@integers_add n_NDIdx,1																								; increment the record number
		@xtables_rget NewDataTable,n_NDIdx																		; and grab the record

	@end_repeat																															; ENDREPEAT

	@begin_test f_DataType																									; and comments
		@when =,c_W
			@files $write,out_File,';(END..):Temporary Words by languageONE'
		@wend
		
		@when =,c_I
			@files $write,out_File,';(END..):Temporary Integers by languageONE'
		@wend

		@when =,c_N
			@files $write,out_File,';(END..):Temporary FixedPoint numbers by languageONE'
		@wend

	@end_test

@END_SUB D33_WriteNewData

;-----------------------------------------------------------------------
;				~ D4_WriteMacros
;-----------------------------------------------------------------------
@BEGIN_SUB D34_WriteMacros

	@If MacroTable_UBOUND,=,0
		@exit_sub D34_WriteMacros
	@End_If

	@words_pad PR_Line,w_saveLine						; save the original line
	@saving PR_LineLength										; and its length

	@files $write,out_File," "																							; write out a blank line
	@files $write,out_File,';(BEGIN):Macros created by languageONE'					; and comment the macro

;	------------
;	PROCESS LOOP
;	------------
	@repeat_for n_srcIdx,1,MacroTable_UBOUND																; LOOP until end of records
		@xtables_rget MacroTable,n_srcIdx																			; Get the Macro entry

		@if n_CurrentMacroNo,=,0																							; STANDARD TAB LOGIC
			@Call D341_BeginMacro
		@end_if

		@if MR_MacroNo,!=,n_CurrentMacroNo
			@Call D342_EndMacro
			@Call D341_BeginMacro
		@end_if																																; STANDARD TAB LOGIC

		@repeat_for J,124,1																										; Get length of Line
			@If {MR_MacroLineItem,J,1},!=,' '
				@exit_repeat
			@end_if
		@end_repeat

		@words_insert x_Tab,MR_MacroLineItem
		@integers_add J,1

	;	-------------------------------------
	;	D32_MASM will do the conversion for us
	;	-------------------------------------
		@If b_Windows,=,c_TRUE
			@words_pad MR_MacroLineItem,PR_Line
			@words_uppercase MR_MacroLineItem,w_UBuffer
			@integers_eq PR_LineLength,J
			@Call D32_MASM
			@files $write,out_File,{PR_Line,1,PR_LineLength}										; and write out the record
		@Else
			@files $write,out_File,{MR_MacroLineItem,1,J}												; and write out the record
		@End_If

	@end_repeat																															; END REPEAT

;	---
;	END
;	---
	@if n_CurrentMacroNo,!=,0
		@Call D342_EndMacro
	@end_if

	@files $write,out_File,';(END)..:Macros created by languageONE'					; comment the macro
	@files $write,out_File," "																							; and write out a blank line

	@words_pad w_saveLine,PR_Line					; restore original line
	@restore PR_LineLength								; and its length

@END_SUB D34_WriteMacros

;-----------------------------------------------------------------------
;					~ D41_BeginMacro
;-----------------------------------------------------------------------
@BEGIN_SUB D341_BeginMacro

	@integers_eq n_CurrentMacroNo,MR_MacroNo																; Save the new macro no
	@files $write,out_File," "																							; write out a blank line

	@IF b_Windows,=,c_TRUE
		@words_Copy MR_MacroNo,{w_mLine1,2}																		; write out the macro definition line
		@files $write,out_File,w_mLine1																				; then standard macro lines
	@ELSE
		@words_copy MR_MacroNo,{l_mLine1,9}																		; write out the macro definition line
		@files $write,out_File,l_mLine1																				; then standard macro lines
	@END_IF

@END_SUB D341_BeginMacro

;-----------------------------------------------------------------------
;					~ D42_EndMacro
;-----------------------------------------------------------------------
@BEGIN_SUB D342_EndMacro

	@IF b_Windows,=,c_TRUE
		@files $write,out_File,"ENDM"																					; and the end macro line
	@ELSE
		@files $write,out_File,"%endmacro"																		; and the end macro line
	@END_IF

@END_SUB D342_EndMacro

;		~ =============================
;		~ ROUTINES CALLED FROM ANYWHERE
;		~ =============================

;-------------------------------------------------------------------------------
;			~ X1_TokenToRaw
;-------------------------------------------------------------------------------
@BEGIN_SUB X1_TokenToRaw
;
;	This is a really tricky section. Some of it has been done purely by
;	observation. If you ever have to change this becareful
;
@IF PR_LineNo,>,180
xor rax,rax
@End_If

;	-------------------------
;	Initialise
;	-------------------------
	@words_pad {w_Spaces,1,1},w_saveLine																		; Clear the output line
	@integers_eq n_dstIdx,1																									; and init our outpu locator

	@integers_eq n_TokenStart,3																							; Get the 1st Token
	@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}							; get its length

	;	-------------------------
	;	Whole line is a comment
	;	-------------------------
	@If PR_Type,=,";"																												; If it just a comment
		@words_pad {PR_Line,n_TokenStart,n_TokenLength},w_saveLine						; Copy it
		@integers_eq PR_LineLength,n_TokenLength															; Set the line Length
		@exit_sub X1_TokenToRaw																								; and exit
	@End_IF																																	; ENDIF

;	-------------------------
;	When to start the comma's
;	-------------------------
	@integers_eq n_CommaStart,2

	@If {PR_Line,3,1},_IN,{' ',x_Tab}																				; If the line is indented
		@integers_add n_CommaStart,1																					; Initialise counter
	@end_if																																	; ENDIF

	@integers_eq n_Comma,c_FALSE																						; Initialise
	@integers_eq n_TokenNo,0																								; Initialise

	@repeat_while n_TokenStart,!=,0																					; LOOP thru macro line items

		@integers_add n_TokenNo,1																							; Increment counter
		@words_copy {PR_Line,n_TokenStart,n_TokenLength},{w_saveLine,n_dstIdx}	; copy in the token
		@integers_add n_dstIdx,n_TokenLength																	; and add its length to the dst index

		@If {PR_Line,n_TokenStart,1},=,x_Tab																	; If its a tab then
			@integers_sub n_dstIdx,1																						; dont need a space (see line 4679)
		@End_If																																; ENDIF

		@If PR_Type,_NIN,{";","%"}
			@IF n_TokenNo,!<,n_CommaStart
				@integers_eq n_Comma,c_TRUE
			@End_IF
		@End_If

		@If n_Comma,=,c_TRUE
			@words_copy ",",{w_saveLine,n_dstIdx}																; move in a comma
		@End_If

		@integers_eq n_prevTokenStart,n_TokenStart

		@FUNCTION n_TokenStart,f_NextToken,{n_TokenStart,'999'}								; Get the next Token
		@If n_TokenStart,>,0																									; and if not end
			@FUNCTION n_TokenLength,f_TokenLength,{n_TokenStart,'999'}					; get its length

			@IF {PR_Line,n_TokenStart,1},=,";"																	; If the line is now just a comment
				@words_copy " ",{w_saveLine,n_dstIdx,1}														; space out the previous comma
			@End_If																															; ENDIF

			@integers_add n_dstIdx,1																						; We need a space
		@End_If																																; ENDIF

	@end_repeat																															; ENDREPEAT

	@words_copy {w_Spaces,1,1},{w_saveLine,n_dstIdx}												; so do it

	@integers_sub n_dstIdx,1
	@integers_eq PR_LineLength,n_dstIdx


@END_SUB X1_TokenToRaw

;-----------------------------------------------------------------------
;			~ X2_PutXtable
;-----------------------------------------------------------------------
@BEGIN_SUB X2_PutXtable

	@integers_add DataNameTable_UBOUND,1																		; Increment the record number
	@if DataNameTable_UBOUND,>,c_DN_noOfRecs																; Topped out the table ?
		@files $write,STDOUT,'10: X2_PutXtable:DataNameRecord Table Overflow'	; Then error
		@terminate 09																													; and terminate
	@else																																		; ELSE
		@tables_rput DataNameTable,DataNameTable_UBOUND												; write the table entry
	@end_if																																	; ENDIF
	
@END_SUB X2_PutXtable

;-----------------------------------------------------------------------
;			~ X3_PutXtable
;-----------------------------------------------------------------------
@BEGIN_SUB X3_PutXtable

	@integers_add SynonymTable_UBOUND,1																			; Increment the Upper Boundary
	@if SynonymTable_UBOUND,>,c_SR_noOfRecs																	; If we have blown the table
		@files $write,STDOUT,'10: X3_PutXtable:SynonymRecord Table Overflow'	; Write the error
		@terminate 10																													; and terminate
	@else																																		; ELSE
		@xtables_rput SynonymTable,SynonymTable_UBOUND												; write the table entry
	@end_if																																	; ENDIF

@END_SUB X3_PutXtable

;-----------------------------------------------------------------------
;			~ X4_SearchByName
;-----------------------------------------------------------------------
@BEGIN_SUB X4_SearchByName

;	---------------
;	ARRAY/QUALIFIED
;	---------------
	@words_find {"{",I},w_Temp40																						; Check for brace
	@If I,>,1																																; If it NOT 1 (It's an Array)
		@words_pad {w_Spaces,1,1},{w_Temp40,I}																; space out the Indices
	@Else
		@If I,=,1
			@Words_pad {w_Temp40,2},{w_Temp40,1}
			@repeat_for I,1,40
				@If {w_Temp40,I,1},=,","
					@words_pad {w_Spaces,1,1},{w_Temp40,I}													; space out the qualification
					@exit_repeat
				@End_If
			@End_Repeat
		@End_If
	@end_if																																	; ENDIF

;	------
;	DO IT
;	------
	@integers_eq X5_Idx,1
	@tables_rget DataNameTable,X5_Idx

	@repeat_while DataNameTable_STATUS,=,0

		@if DN_Name,=,w_Temp40
			@words_copy DN_Type,w_DataType
			@exit_sub X4_SearchByName
		@else
			@integers_add X5_Idx,1
			@tables_rget DataNameTable,X5_Idx
		@end_if

	@end_repeat

	@Words_Copy {w_Spaces,1,1},DN_Type

@END_SUB X4_SearchByName

;-----------------------------------------------------------------------
;			~ X5_SearchByRecord
;-----------------------------------------------------------------------

;	---------------------------------------
;	Only Called from C23_Precedence so far
;	Used to matcha table to a record
;	---------------------------------------
@BEGIN_SUB X5_SearchByRecord

;	AS THIS CAN RETURN MULTIPLE RECORDS (1 per CAll)
;	set the Record_No (0 if beginning) and keep calling it until
;	Status is non zero

	@integers_add X6_Idx,1
	@tables_rget DataNameTable,X6_Idx

	@repeat_while DataNameTable_STATUS,=,0
		@if DN_Record,=,w_SaveRecordName
			@integers_eq exitRepeat,c_TRUE
		@else
			@integers_add X6_Idx,1
			@tables_rget DataNameTable,X6_Idx
		@end_if
	@end_repeat

@END_SUB X5_SearchByRecord

;-----------------------------------------------------------------------
;			~ X6_NewData
;-----------------------------------------------------------------------
@BEGIN_SUB X6_NewData

;		%define c_ND_reclen										0160
;		%define c_ND_noOfRecs									0512
;	@begin_record c_ND_reclen,NewDataRecord
;		@insertword	ND_Type,									0001,' '
;		@insertword	ND_ReUsable,							0001,' '
;	 	@insertword	ND_Insert,								0060,' '
;		@insertnumber ND_Length,							0000,'999'
;	 	@insertword	ND_Picture,								0030,' '
;	@end_record NewDataRecord

;	-------------------------
;	SEARCH FOR EXISTING MATCH
;	-------------------------
	@integers_eq b_Flag,c_FALSE																							; Using b_Flag as found flag
	@integers_eq NewDataRecord_NO,1																					; Start the table at 1
	@xtables_rget NewDataTable,NewDataRecord_NO															; and grab the record

	@repeat_while NewDataRecord_NO,!>,NewDataTable_UBOUND										; LOOP until end of records

		@begin_test w_DataType

			@when =,c_I																													; looking for integer
				@_If ND_Type,=,c_I																								; If Integer
				@_and ND_Picture,=,DN_Picture																			; and same picture
				@_and ND_ReUsable,=,{w_Spaces,1,1}																; and its free
				@_end
					@integers_eq b_Flag,c_TRUE
				@end_If
			@wend

			@when =,c_N																													; looking for FP Number
				@_If ND_Type,=,c_N																								; If Fixed Point
				@_and ND_Picture,=,DN_Picture																			; and same picture
				@_and ND_ReUsable,=,{w_Spaces,1,1}																; and its free
				@_end
					@integers_eq b_Flag,c_TRUE																			; set found to true
				@end_if
			@wend

		;	-----------------------------------------
		;	Always a Table Element - Never Precedence
		;	-----------------------------------------
			@when =,c_W																													; Looking for a Word (Table entries only)
				@_If ND_Type,=,c_W																								; If Word
				@_and ND_xLength,=,DN_xLength																			; and same length
				@_and ND_ReUsable,=,{w_Spaces,1,1}																; and its free
				@_end
					@integers_eq b_Flag,c_TRUE																			; set found to true
				@end_if
			@wend

		@end_test																															; END TEST

		@if b_Flag,=,c_TRUE
			@words_copy 'N',ND_ReUsable																					; set it to inUse
			@xtables_rput NewDataTable,NewDataRecord_NO													; rewrite the record
			@exit_sub X6_NewData																								; then exit subroutine
		@else
			@integers_add NewDataRecord_NO,1																		; increment the record number
			@xtables_rget NewDataTable,NewDataRecord_NO													; and grab the record
		@end_if

	@end_repeat

;	-----------------
;	BUILD A NEW ENTRY
;	----------------- 

	@words_copy w_DataType,ND_Type																					; Set Data Type
	@words_copy 'N',ND_ReUsable																							; Set as being NON-reUseable for his line
	@words_pad {w_Spaces,1,1},ND_Insert																			; Initialise
	@words_pad DN_Picture,ND_Picture																				; Initialise

	@begin_test w_DataType

		@when =,c_I																														; looking for integer
			@words_pad "@insertnumber i0000,0,",{ND_Insert,2}										; then insert the integer
			@words_copy DN_Picture,{ND_Insert,24}																; grab the picture
		@wend																																	; WEND

		@when =,c_N																														; looking for FP Number
			@words_pad "@insertnumber n0000,0,",{ND_Insert,2}										; then insert the FP
			@words_copy DN_Picture,{ND_Insert,24}																; grab picture
		@wend																																	; WEND

		@when =,c_W																														; looking for Word
			@words_pad "@insertword   a0000,128,' '",{ND_Insert,2}							; then insert the Alpha
			@words_copy {DN_xLength,1,3},{ND_Insert,22,3}
		@wend

	@end_test

	@integers_add n_NDNo,1																									; increment the new data number
	@words_copy n_NDNo,{ND_Insert,17}																				; pop into the insert statement

	@Call X7_WriteNewData																										; next table slot


@END_SUB X6_NewData

;-----------------------------------------------------------------------
;			~ X7_WriteNewData
;-----------------------------------------------------------------------
@BEGIN_SUB X7_WriteNewData

	@integers_add NewDataTable_UBOUND,1
	@if NewDataTable_UBOUND,>,c_ND_noOfRecs
		@files $write,STDOUT,'08: X9_NextNewDataSlot:New Data Table Overflow'
		@terminate 7
	@else
		@xtables_rput NewDataTable,NewDataTable_UBOUND												; and write it
	@end_if

@END_SUB X7_WriteNewData

;-----------------------------------------------------------------------
;			~ X8_WriteMacroLine
;-----------------------------------------------------------------------
@BEGIN_SUB X8_WriteMacroLine

	@integers_add MacroTable_UBOUND,1
	@if MacroTable_UBOUND,>,c_MR_noOfRecs
		@files $write,STDOUT,'09: X8_WriteMacroLine:MacroRecord Table Overflow'
		@terminate 8
	@else
		@xtables_rput MacroTable,MacroTable_UBOUND														; and write it
	@end_if

@END_SUB X8_WriteMacroLine

;-----------------------------------------------------------------------
;			~ X9_CheckPicture
;-----------------------------------------------------------------------
@BEGIN_SUB X9_CheckPicture

	@saving I,J,K,L

	@integers_eq J,0
	@integers_eq K,0
	@integers_eq L,0

	@repeat_for I,1,30
		@if {DN_Picture,I,1},_IN,{'9','#'}
			@integers_add J,1
		@end_if
		@if {DN_Picture,I,1},=,'.'
			@integers_eq K,c_TRUE
		@end_if
		@_if K,=,c_TRUE
		@_and {DN_Picture,I,1},=,'9'
		@_end
			@integers_add L,1
		@end_if

	@end_Repeat
	@If J,>,19
		@files $write,STDOUT,"50: Picture contains more than 19 digits=",n_LineCtr
		@terminate 50
	@End_if
	@If L,>,18
		@files $write,STDOUT,"50: Picture contains more than 18 decimal places=",n_LineCtr
		@terminate 50
	@End_if

	@restore L,K,J,I

@END_SUB X9_CheckPicture

;----------------------------------------------------------------------
; +--  Used for debugging
;----------------------------------------------------------------------
@BEGIN_SUB Z_Debug

	@repeat_for n_LineCtr,1,ProgramTable_UBOUND
		@xtables_rget ProgramTable,n_LineCtr
		@display n_LineCtr," ",PR_Type," ",PR_LineLength," ",PR_LineLength," ",{PR_Line,1,128},LF
	@end_repeat

	@repeat_for I,1,c_DN_noOfRecs
		@tables_rget DataNameTable,I
		@if DataNameTable_STATUS,=,0
			@files $write,STDOUT, {I,'99'},	' ',	\
					 DN_TableType,			' ',	\
					{DN_Table,1,20},		' ',	\
					{DN_Record,1,20},		' ',	\
					{DN_No,'999'},			' ',	\
					 DN_Type,				' ',	\
					{DN_Name,1,20},			' ',	\
					 DN_NameLength,				' ',	\
					 DN_Picture
		@else
			@exit_repeat
		@end_if
	@end_repeat

 @exit_sub Z_Debug

	@repeat_for I,1,c_ND_noOfRecs
		@xtables_rget NewDataTable,I
		@if NewDataTable_STATUS,=,0
			@files $write,STDOUT,{I,'99'},	' ',	\
				ND_Type,					' ',	\
				ND_ReUsable,				' ',	\
				ND_Insert,					' ',	\
				ND_Picture
		@else
			@exit_repeat
		@end_if
	@end_repeat

	@repeat_for I,1,c_SR_noOfRecs
		@xtables_rget SynonymTable,I
		@if SynonymTable_STATUS,=,0
			@display I," ",Synonym,' ',lenSynonym,' ',Keyword,' ',lenKeyword,LF
		@else
			@exit_repeat
		@end_if
	@end_repeat

	@repeat_for I,1,c_MR_noOfRecs
		@xtables_rget MacroTable,I
		@if MacroTable_STATUS,=,0
			@display I," ",MR_MacroNo,' ',{MR_MacroLineItem,1,64},LF
		@else
			@exit_repeat
		@end_if
	@end_repeat

@END_SUB Z_Debug

