<aname="l3"></a>* See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Doc/CompilerOverview.DD.html#l1"><spanclass=cF4>::/Doc/CompilerOverview.DD</span></a><spanclass=cF0>.
<aname="l5"></a>* See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Doc/ScopingLinkage.DD.html#l1"><spanclass=cF4>Scoping and Linkage</span></a><spanclass=cF0> for details on </span><spanclass=cF2>extern</span><spanclass=cF0>, </span><spanclass=cF2>import</span><spanclass=cF0>, </span><spanclass=cF2>_extern</span><spanclass=cF0>, </span><spanclass=cF2>_import</span><spanclass=cF0>, etc.
<aname="l7"></a>* Built-in types include </span><spanclass=cF2>I0, I8, I16, I32, I64</span><spanclass=cF0> for signed 0-8 byte ints and </span><spanclass=cF2>U0, U8, U16, U32, U64</span><spanclass=cF0> for unsigned 0-8 byte ints
<aname="l8"></a>and </span><spanclass=cF2>F64</span><spanclass=cF0> for 8 byte floats.
<aname="l36"></a>* A char const all alone is sent to </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KeyDev.CC.html#l23"><spanclass=cF4>PutChars</span></a><spanclass=cF0>(). A string with or without args is sent to </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/StrPrint.CC.html#l1110"><spanclass=cF4>Print</span></a><spanclass=cF0>(). An empty string literal
<aname="l57"></a>* When dealing with function addresses such as for callbacks, precede the name with "</span><spanclass=cF2>&</span><spanclass=cF0>".
<aname="l59"></a>* Type casting is postfix. To typecast int or F64, use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelB.HH.html#l92"><spanclass=cF4>ToI64</span></a><spanclass=cF0>(), </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelB.HH.html#l90"><spanclass=cF4>ToBool</span></a><spanclass=cF0>() or </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelB.HH.html#l91"><spanclass=cF4>ToF64</span></a><spanclass=cF0>(). (ZealOS follows normal C float<-->int
<aname="l60"></a>conversion, but sometimes you want to override. These functions are better than multiplying by "1.0" to convert to float.)
<aname="l61"></a>
<aname="l62"></a>* There is no </span><spanclass=cF2>main()</span><spanclass=cF0> function. Any code outside of functions gets executed upon start-up, in order.
<aname="l63"></a>
<aname="l64"></a>* There are no bit fields, but there are </span><spanclass=cF4><u>bit access</u></span><spanclass=cF0> routines and you can access bytes or words within any int. See </span><spanclass=cF4>
<aname="l65"></a></span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l103"><spanclass=cF4>I64 declaration</span></a><spanclass=cF0>. A class can be accessed as a whole are subints, if you put a type in front of the </span><spanclass=cF2>class</span><spanclass=cF0> declaration.
<aname="l80"></a>* Variable arg count functions (</span><spanclass=cF2>...</span><spanclass=cF0>) can access their args with built-in variables similar to '</span><spanclass=cF2>this</span><spanclass=cF0>' in C++. They are '</span><spanclass=cF2>I64
<aname="l81"></a>argc</span><spanclass=cF0>' and '</span><spanclass=cF2>I64 argv[]</span><spanclass=cF0>'.
<aname="l101"></a></span><ahref="https://zeal-operating-system.github.io/ZealOS/System/Gr/GrBitMap.CC.html#l1084"><spanclass=cF4>GrPutS</span></a><spanclass=cF2>(dc, x, y, buf); //Plot string at x,y pixels. GrPutS is not public.
<aname="l117"></a>* if you know a switch statement will not exceed the lowest or highest case values. </span><spanclass=cF2>switch []</span><spanclass=cF0> is a little faster because it
<aname="l120"></a>* </span><spanclass=cF2>switch</span><spanclass=cF0> statements always use a jump table. Don't use them with cases with really big, sparse ranges.
<aname="l121"></a>
<aname="l122"></a>* Allows ranges like "</span><spanclass=cF2>case 4...7:</span><spanclass=cF0>" in </span><spanclass=cF2>switch</span><spanclass=cF0> statements.
<aname="l124"></a>* A no case number causes next higher int case in </span><spanclass=cF2>switch</span><spanclass=cF0> statements. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/NullCase.CC.html#l1"><spanclass=cF4>::/Demo/NullCase.CC</span></a><spanclass=cF0>.
<aname="l139"></a>* Switch statements can be nestled with a single switch expression! This is known as a "sub_switch" statement. </span><spanclass=cF2>start</span><spanclass=cF0>/</span><spanclass=cF2>end</span><spanclass=cF0> are
<aname="l140"></a>used to group cases. Don't goto out of, throw an exception out of, or return out of the </span><spanclass=cF2>start</span><spanclass=cF0> front porch area. See </span><spanclass=cF4>
<aname="l165"></a>* You can have multiple member variables of a class named "</span><spanclass=cF2>pad</span><spanclass=cF0>" or "</span><spanclass=cF2>reserved</span><spanclass=cF0>", and it won't issue warnings.
<aname="l167"></a>* </span><spanclass=cF2>noreg</span><spanclass=cF0> or </span><spanclass=cF2>reg</span><spanclass=cF0> can be placed before a function local variable name. You can, optionally, specify a register after the </span><spanclass=cF2>reg</span><spanclass=cF0>
<aname="l168"></a>keyword.
<aname="l169"></a>
<aname="l170"></a></span><spanclass=cF2>U0 Main()
<aname="l171"></a> {
<aname="l172"></a> //Only use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l1939"><spanclass=cF4>REGG_LOCAL_VARS</span></a><spanclass=cF2> or </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l1940"><spanclass=cF4>REGG_LOCAL_NON_PTR_VARS</span></a><spanclass=cF2> for register variables or else clobbered.
<aname="l173"></a> I64 reg R15 i = 5, noreg j = 4;
<aname="l174"></a> no_warn i;
<aname="l175"></a> asm {
<aname="l176"></a> MOV RAX, R15
<aname="l177"></a> CALL &PUT_HEX_U64
<aname="l178"></a> MOV RAX, '\n'
<aname="l179"></a> CALL &PUT_CHARS
<aname="l180"></a> MOV RAX, U64 &j[RBP]
<aname="l181"></a> CALL &PUT_HEX_U64
<aname="l182"></a> MOV RAX, '\n'
<aname="l183"></a> CALL &PUT_CHARS
<aname="l184"></a> }
<aname="l185"></a> }
<aname="l186"></a></span><spanclass=cF0>
<aname="l187"></a>* </span><spanclass=cF2>interrupt</span><spanclass=cF0>, </span><spanclass=cF2>haserrcode</span><spanclass=cF0>, </span><spanclass=cF2>public</span><spanclass=cF0>, </span><spanclass=cF2>argpop</span><spanclass=cF0> or </span><spanclass=cF2>noargpop</span><spanclass=cF0> are function flags. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/SerialDev/Keyboard.CC.html#l477"><spanclass=cF4>IRQKbd</span></a><spanclass=cF0>().
<aname="l188"></a>
<aname="l189"></a>* A single quote can encompass multiple characters. </span><spanclass=cF2>'ABC'</span><spanclass=cF0> is equ to </span><spanclass=cF2>0x434241</span><spanclass=cF0>. </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KeyDev.CC.html#l23"><spanclass=cF4>PutChars</span></a><spanclass=cF0>() takes multiple characters.
<aname="l190"></a>
<aname="l191"></a></span><spanclass=cF2>asm {
<aname="l192"></a> HELLO_WORLD::
<aname="l193"></a> PUSH RBP
<aname="l194"></a> MOV RBP, RSP
<aname="l195"></a> MOV RAX, 'Hello '
<aname="l196"></a> CALL &PUT_CHARS
<aname="l197"></a> MOV RAX, 'World\n'
<aname="l198"></a> CALL &PUT_CHARS
<aname="l199"></a> LEAVE
<aname="l200"></a> RET
<aname="l201"></a> }
<aname="l202"></a> Call(HELLO_WORLD);
<aname="l203"></a> PutChars('Hello ');
<aname="l204"></a> PutChars('World\n');
<aname="l205"></a></span><spanclass=cF0>
<aname="l206"></a>* The "</span><spanclass=cF2>`</span><spanclass=cF0>" operator raises a base to a power.
<aname="l207"></a>
<aname="l208"></a>* There is no question-colon operator.
<aname="l224"></a>* You can use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Compiler/CMisc.CC.html#l1"><spanclass=cF4>Option</span></a><spanclass=cF0>(</span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l1679"><spanclass=cF4>OPTf_WARN_PAREN</span></a><spanclass=cF0>, ON) to find unnecessary parentheses in code.
<aname="l225"></a>
<aname="l226"></a>* You can use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Compiler/CMisc.CC.html#l1"><spanclass=cF4>Option</span></a><spanclass=cF0>(</span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l1680"><spanclass=cF4>OPTf_WARN_DUP_TYPES</span></a><spanclass=cF0>, ON) to find duplicate local variable type statements.
<aname="l227"></a>
<aname="l228"></a>* With the </span><spanclass=cF2>#exe{}</span><spanclass=cF0> feature in your src code, you can place programs that insert text into the stream of code being compiled.
<aname="l229"></a>See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KMain.CC.html#l262"><spanclass=cF4>#exe {}</span></a><spanclass=cF0> for an example where the date/time and compile-time prompting for configuration data is placed into a program. </span><spanclass=cF4>
<aname="l230"></a></span><ahref="https://zeal-operating-system.github.io/ZealOS/Compiler/CMisc.CC.html#l71"><spanclass=cF4>StreamPrint</span></a><spanclass=cF0>() places text into a src program stream following the conclusion of the </span><spanclass=cF2>#exe{}</span><spanclass=cF0> block.
<aname="l231"></a>
<aname="l232"></a>* No </span><spanclass=cF2>#define</span><spanclass=cF0> functions exist (Terry was not a fan)
<aname="l233"></a>
<aname="l234"></a>* No </span><spanclass=cF2>typedef</span><spanclass=cF0>, use </span><spanclass=cF2>class</span><spanclass=cF0>.
<aname="l235"></a>
<aname="l236"></a>* No type-checking
<aname="l237"></a>
<aname="l238"></a>* Can't use </span><spanclass=cF2><></span><spanclass=cF0> with </span><spanclass=cF2>#include</span><spanclass=cF0>, use </span><spanclass=cF2>""</span><spanclass=cF0>.
<aname="l239"></a>
<aname="l240"></a>* "</span><spanclass=cF2>$</span><spanclass=cF0>" is an escape character. Two dollar signs signify an ordinary $. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Doc/DolDocOverview.DD.html#l1"><spanclass=cF4>DolDoc</span></a><spanclass=cF0>. In </span><spanclass=cF2>asm</span><spanclass=cF0> or </span><ahref="https://zeal-operating-system.github.io/ZealOS/Doc/CosmiC.DD.html#l1"><spanclass=cF4>CosmiC</span></a><spanclass=cF0> code, it also refers to
<aname="l241"></a>the instruction's address or the offset in a </span><spanclass=cF2>class</span><spanclass=cF0> definition.
<aname="l242"></a>
<aname="l243"></a>* </span><spanclass=cF2>union</span><spanclass=cF0> is more like a class, so you don't reference it with a </span><spanclass=cF2>union</span><spanclass=cF0> label after you define it. Some common unions are
<aname="l244"></a>declared in </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l65"><spanclass=cF4>KernelA.HH</span></a><spanclass=cF0> for 1,2,4 and 8 byte objects. If you place a type in front of a union declaration, that is the type
<aname="l245"></a>when used by itself. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/SubIntAccess.CC.html#l1"><spanclass=cF4>::/Demo/SubIntAccess.CC</span></a><spanclass=cF0>.
<aname="l246"></a>
<aname="l247"></a>* </span><spanclass=cF2>class</span><spanclass=cF0> member variables can have meta data. </span><spanclass=cF2>format</span><spanclass=cF0> and </span><spanclass=cF2>data</span><spanclass=cF0> are two meta data types now used. All compiler structures are
<aname="l248"></a>saved and you can access the compiler's info about classes and variables. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/ClassMeta.CC.html#l1"><spanclass=cF4>::/Demo/ClassMeta.CC</span></a><spanclass=cF0> and </span><ahref="https://zeal-operating-system.github.io/ZealOS/System/DolDoc/DocForm.CC.html#l263"><spanclass=cF4>DocForm</span></a><spanclass=cF0>().
<aname="l249"></a>
<aname="l250"></a>* There is a keyword </span><spanclass=cF2>lastclass</span><spanclass=cF0> you use as a default arg. It is set to the class name of the prev arg. See </span><spanclass=cF4>
<aname="l251"></a></span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/LastClass.CC.html#l1"><spanclass=cF4>::/Demo/LastClass.CC</span></a><spanclass=cF0>, </span><ahref="https://zeal-operating-system.github.io/ZealOS/System/Debug.CC.html#l216"><spanclass=cF4>ClassRep</span></a><spanclass=cF0>(), </span><ahref="https://zeal-operating-system.github.io/ZealOS/System/DolDoc/DocForm.CC.html#l263"><spanclass=cF4>DocForm</span></a><spanclass=cF0>() and </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/Disk/BlkDevRep.CC.html#l1"><spanclass=cF4>::/Demo/Disk/BlkDevRep.CC</span></a><spanclass=cF0>.
<aname="l252"></a>
<aname="l253"></a>* See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/Exceptions.CC.html#l1"><spanclass=cF4>::/Demo/Exceptions.CC</span></a><spanclass=cF0>. </span><spanclass=cF2>try{} catch{}</span><spanclass=cF0> and </span><spanclass=cF2>throw</span><spanclass=cF0> are different from C++. </span><spanclass=cF2>throw</span><spanclass=cF0> is a function with an 8-byte or less char
<aname="l254"></a>arg. The char string passed in </span><spanclass=cF2>throw()</span><spanclass=cF0> can be accessed from within a </span><spanclass=cF2>catch{}</span><spanclass=cF0> using the </span><spanclass=cF2>Fs->except_ch</span><spanclass=cF0>. Within a </span><spanclass=cF2>catch {}</span><spanclass=cF0>
<aname="l255"></a>block, set the variable </span><spanclass=cF2>Fs->catch_except</span><spanclass=cF0> to </span><spanclass=cF2>TRUE</span><spanclass=cF0> if you want to terminate the search for a handler. Use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KExcept.CC.html#l46"><spanclass=cF4>PutExcept</span></a><spanclass=cF0>() as a
<aname="l256"></a>handler, if you like.
<aname="l257"></a>
<aname="l258"></a>* A function is available similar to </span><spanclass=cF2>sizeof</span><spanclass=cF0> which provides the offset of a member of a class. It's called </span><spanclass=cF2>offset</span><spanclass=cF0>. You place
<aname="l259"></a>the class name and member inside as in </span><spanclass=cF2>offset(classname.membername)</span><spanclass=cF0>. It has nothing to do with 16-bit code. Both </span><spanclass=cF2>sizeof</span><spanclass=cF0>
<aname="l260"></a>and </span><spanclass=cF2>offset</span><spanclass=cF0> only accept one level of member variables. That is, you can't do </span><spanclass=cF2>sizeof(classname.membername.submembername)</span><spanclass=cF0>.
<aname="l261"></a>
<aname="l262"></a>* There is no </span><spanclass=cF2>continue</span><spanclass=cF0> statement. Use </span><spanclass=cF2>goto</span><spanclass=cF0>.
<aname="l263"></a>
<aname="l264"></a>* </span><spanclass=cF2>lock{}</span><spanclass=cF0> can be used to apply asm </span><spanclass=cF2>LOCK</span><spanclass=cF0> prefixes to code for safe multicore read-modify-write accesses. The code bracked with
<aname="l265"></a>have </span><spanclass=cF2>LOCK</span><spanclass=cF0> asm prefix's applied to relevant insts within. It's a little shoddy. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/MultiCore/Lock.CC.html#l1"><spanclass=cF4>::/Demo/MultiCore/Lock.CC</span></a><spanclass=cF0>.
<aname="l266"></a>
<aname="l267"></a>* There is a function called </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.CC.html#l388"><spanclass=cF4>MSize</span></a><spanclass=cF0>() which gives the size of an object alloced off the heap. For larger size allocations,
<aname="l268"></a>the system rounds-up to a power of two, so </span><spanclass=cF2>MSize()</span><spanclass=cF0> lets you know the real size and you can take full advantage of it.
<aname="l269"></a>
<aname="l270"></a>* You CAN </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.CC.html#l387"><spanclass=cF4>Free</span></a><spanclass=cF0>() a </span><spanclass=cF2>NULL</span><spanclass=cF0> pointer. Useful variants of </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.CC.html#l391"><spanclass=cF4>MAlloc</span></a><spanclass=cF0>() can be found </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/MAllocFree.CC.html#l399"><spanclass=cF4>Here</span></a><spanclass=cF0>. Each task has a heap and you can </span><spanclass=cF2>MAlloc</span><spanclass=cF0> and </span><spanclass=cF2>
<aname="l271"></a>Free</span><spanclass=cF0> off-of other task's heaps, or make an independent heap with </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/Memory/HeapCtrl.CC.html#l1"><spanclass=cF4>HeapCtrlInit</span></a><spanclass=cF0>(). See </span><ahref="https://zeal-operating-system.github.io/ZealOS/System/Utils/HeapLog.CC.html#l83"><spanclass=cF4>HeapLog</span></a><spanclass=cF0>() for an example.
<aname="l272"></a>
<aname="l273"></a>* The stack does not grow because virtual mem is not used. It's recommended to allocate large local variables from the heap.
<aname="l274"></a>You can change </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KernelA.HH.html#l3547"><spanclass=cF4>MEM_DEFAULT_STACK</span></a><spanclass=cF0> and recompile </span><spanclass=cF2>Kernel</span><spanclass=cF0> or request more when doing a </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KTask.CC.html#l264"><spanclass=cF4>Spawn</span></a><spanclass=cF0>(). You can use </span><ahref="https://zeal-operating-system.github.io/ZealOS/Kernel/KTask.CC.html#l129"><spanclass=cF4>CallStackGrow</span></a><spanclass=cF0>(), but
<aname="l275"></a>it's odd. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Demo/StackGrow.CC.html#l1"><spanclass=cF4>::/Demo/StackGrow.CC</span></a><spanclass=cF0>.
<aname="l276"></a>
<aname="l277"></a>* Only one base class is allowed.
<aname="l278"></a>
<aname="l279"></a>* </span><spanclass=cF2>printf()</span><spanclass=cF0> has new codes. See </span><ahref="https://zeal-operating-system.github.io/ZealOS/Doc/Print.DD.html#l1"><spanclass=cF4>Print("") Format Strings</span></a><spanclass=cF0>.
<aname="l280"></a>
<aname="l281"></a>* All values are extended to 64-bit when accessed. Intermediate calculations are done with 64-bit values.
<aname="l282"></a>
<aname="l283"></a></span><spanclass=cF2>U0 Main()
<aname="l284"></a> {
<aname="l285"></a> I16 i1;
<aname="l286"></a> I32 j1;
<aname="l287"></a>
<aname="l288"></a> j1 = i1 = 0x12345678; //Resulting i1 is 0x5678 but j1 is 0x12345678
<aname="l289"></a>
<aname="l290"></a> I64 i2 = 0x8000000000000000;
<aname="l291"></a> Print("%X\n", i2 >> 1); //Res is 0xC000000000000000 as expected
<aname="l292"></a>
<aname="l293"></a> U64 u3 = 0x8000000000000000;
<aname="l294"></a> Print("%X\n", u3 >> 1); //Res is 0x4000000000000000 as expected
<aname="l295"></a>
<aname="l296"></a> I32 i4 = 0x80000000; //const is loaded into a 64-bit register variable.
<aname="l297"></a> Print("%X\n", i4 >> 1); //Res is 0x40000000
<aname="l298"></a>
<aname="l299"></a> I32 i5 = -0x80000000;
<aname="l300"></a> Print("%X\n", i5 >> 1); //Res is 0xFFFFFFFFC0000000