Quad EC C Source Code Analysis: Difference between revisions

From NARS2000
Jump to navigationJump to search
mNo edit summary
Line 5: Line 5:
==Executive Summary - Conceptual C Programmers' Preliminary Overview/Preview==
==Executive Summary - Conceptual C Programmers' Preliminary Overview/Preview==


Variable <'''lpYYRes'''> contains the 3-element vector result of the call to <'''qf_ec.c'''>, specifically, from monadic function '''SysFnMonEC_EM_YY'''.  '''lpYYRes''' also contains a pointer to an object <'''hGlbRes''> that is created by other code in the same file.
Variable <'''lpYYRes'''>, upon completion of ⎕EC contains the entire '''3-element nested vector result''' of the call to <'''qf_ec.c'''>, specifically, from monadic function '''SysFnMonEC_EM_YY'''.  '''lpYYRes''' also contains a pointer to an object <'''hGlbRes''> that is created by other code in the same file.


<br>That global memory handle <'''hGlbRes'''> points (via '''lpMemRes''' = MyGlobalLock (hGlbRes)) to a VARARRAY_HEADER followed by the actual data (a three-element vector).  The header contains various fields such as Array Type (ARRAY_NESTED), the NELM (3), the Rank (1), the dimension (3), followed by the data.  As it is a nested array that gets returned, the 3-elements of the data are all pointers to a '''SYMENTRY''' (for immediate values -- BOOL, INT, FLT, and CHAR) or a global memory handle for all other items, e.g. Global Numeric, APA, HETERO (mixed array-datatype e.g. integer, char/unicode string, float double, etc.), any non-immediate array, etc.
<br>That global memory handle <'''hGlbRes'''> points (via '''lpMemRes''' = MyGlobalLock (hGlbRes)) to a VARARRAY_HEADER followed by the actual data (a three-element vector).  The header contains various fields such as Array Type (ARRAY_NESTED), the NELM (3), the Rank (1), the dimension (3), followed by the data.  As it is a nested array that gets returned, the 3-elements of the data are all pointers to a '''SYMENTRY''' (for immediate values -- BOOL, INT, FLT, and CHAR) or a global memory handle for all other items, e.g. Global Numeric, APA, HETERO (mixed array-datatype e.g. integer, char/unicode string, float double, etc.), any non-immediate array, etc.

Revision as of 23:14, 10 August 2015

EC - C Source Code Analysis:

File <qf_ec.c> (supporting APL System Function System Function ⎕EC - Execute Controlled) located in NARS trunk folder is a model example for returning a nested vector to APL from a System Function call. Remember per your technical knowledge of APL: ⎕EC returns a 3-element nested vector to APL.

Executive Summary - Conceptual C Programmers' Preliminary Overview/Preview

Variable <'lpYYRes>, upon completion of ⎕EC contains the entire 3-element nested vector result of the call to <qf_ec.c>, specifically, from monadic function SysFnMonEC_EM_YY. lpYYRes also contains a pointer to an object <hGlbRes> that is created by other code in the same file.


That global memory handle <hGlbRes> points (via lpMemRes = MyGlobalLock (hGlbRes)) to a VARARRAY_HEADER followed by the actual data (a three-element vector). The header contains various fields such as Array Type (ARRAY_NESTED), the NELM (3), the Rank (1), the dimension (3), followed by the data. As it is a nested array that gets returned, the 3-elements of the data are all pointers to a SYMENTRY (for immediate values -- BOOL, INT, FLT, and CHAR) or a global memory handle for all other items, e.g. Global Numeric, APA, HETERO (mixed array-datatype e.g. integer, char/unicode string, float double, etc.), any non-immediate array, etc.


In a sense, the internal structure of arrays in NARS C code are nested just as APL arrays themselves are nested. Nesting is ubiquitous in NARS/APL2, etc.. Think about C coding source layouts and program flow from the standpoint of "How would you design the internal structures for an APL interpreter?" The C source code would, wherever possible, parallel the APL code which APL users view and understand.


⎕EC is somewhat more complex than other APL system functions in that ⎕EC executes its right argument under controlled circumstances - this also holds true for the C code itself - complexity in the returned data structure, i.e. ⎕EC mirrors APL variable structuring.


Subordinate execution of ⎕EC's right argument returns an <LPPL_YYSTYPE> variable-type pointer(ptr) just as it's umbrella overarching function ⎕EC does. Many APL prime functions such as rho, take, iota, etc. as coded in C - also return nested arguments while many APL System Functions merely return scalars.


Variable name <lpYYRes2> in file <qf_ec.c>'s C source code indicates it is a secondary result (re the execution of ⎕EC's right argument).


Independent of how actual execution of the APL user's argument proceeded, after executing that right arg, the Exit Type is converted into an integer Return Code (as that's the form of the first output item - the first element in ⎕EC's output vector, in ⎕EC's result vector). That first item is a simple numeric scalar, but since the result of ⎕EC is a three-element nested vector, <qf_ec.c>/SysFnMonEC_EM_YY must convert the Return Code into a LPSYMENTRY via <MakeSymEntry_EM>.


In particular - (file <qf_ec.c> C source code extract just below):

    // Save the return code in the FIRST ELEMENT of ⎕EC - C's index origin is zero hence ref. to lpMemRes[0]
    lpMemRes[0] = MakeSymEntry_EM (IMMTYPE_INT,     // Immediate type
                      &aplLongestRC,    // Ptr to immediate value
                       lptkFunc);       // Ptr to function token

Technically, ⎕EC's second output element is the value of ⎕ET, usually a 2-element vector of zeroes, at present.


What happens next depends upon whether or not the APL user's right argument execution succeeded:


If execution succeeded: ⎕EC returns the value or string value of the executed result as the third element in its output vector.


If execution failed: ⎕EC returns the error message associated with that failure, a unicode string - as ⎕EC's third output element.