hschumann2/TempleOS-Source-Code
0838
1 2 HolyC3 4* See ::/Doc/CompilerOverview.DD.5 6* See Scoping and Linkage for details on extern, import, _extern, _import, etc.7 8* Built-in types include I0,I8,I16,I32,I64 for signed 0-8 byte ints and U0,U8,U196,U32,U64 for unsigned 0-8 byte ints and F64 for 8 byte floats.10 11 U0 void, but ZERO size!12 I8 char13 U8 unsigned char14 I16 short15 U16 unsigned short16 I32 int17 U32 unsigned int18 I64 long (64-bit)19 U64 unsigned long (64-bit)20 F64 double21 no F32 float.22 23* Function with no args, or just default args can be called without parentheses.24 25 >Dir("*");26 >Dir();27 >Dir;28 29* Default args don't have to be on the end. This code is valid:30 U0 Test(I64 i=4,I64 j,I64 k=5)31 {32 Print("%X %X %X\n",i,j,k);33 }34 35 Test(,3);36 37* A char const all alone is sent to PutChars(). A string with or without args38is sent to Print(). An empty string literal signals a variable fmt_str follows.39 40 void DemoC(char drv,char *fmt,char *name,int age)41 {42 printf("Hello World!\n");43 printf("%s age %d\n",name,age);44 printf(fmt,name,age);45 putchar(drv);46 putchar('*');47 }48 49 U0 DemoHolyC(U8 drv,U8 *fmt,U8 *name,I64 age)50 {51 "Hello World!\n";52 "%s age %d\n",name,age;53 "" fmt,name,age;54 '' drv;55 '*';56 }57 58* When dealing with function addresses such as for callbacks, precede the name59with "&".60 61* Type casting is postfix. To typecast int or F64, use ToI64(), ToBool() or62ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you63want to override. These functions are better than multiplying by "1.0" to64convert to float.)65 66* There is no main() function. Any code outside of functions gets executed upon67start-up, in order.68 69* There are no bit fields, but there are bit access routines and you can access70bytes or words within any int. See I64 declaration. A class can be accessed as71a whole are subints, if you put a type in front of the class declaration.72 73 public I64i union I64 //"I64i" is intrinsic. We are defining "I64".74 {75 I8i i8[8];76 U8i u8[8];77 I16 i16[4];78 U16 u16[4];79 I32 i32[2];80 U32 u32[2];81 };82 83 I64 i=0x123456780000DEF0;84 i.u16[1]=0x9ABC;85 86* Variable arg count functions (...) can access their args with built-in87variables similar to 'this' in C++. They are 'I64 argc' and 'I64 argv[]'.88 89 I64 AddNums(...)90 {91 I64 i,res=0;92 for (i=0;i<argc;i++)93 res+=argv[i];94 return res;95 }96 97 >AddNums(1,2,3);98 ans=699 100 101 public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...)102 {103 U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string.104 GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public.105 Free(buf);106 }107 108 ...109 110 GrPrint(gr.dc,(GR_WIDTH-10*FONT_WIDTH)>>1,(GR_HEIGHT-FONT_HEIGHT)>>1,111 "Score:%4d",score); //Print score in the center of the scrn.112 ...113 114 115* Allows "5<i<j+1<20" instead of "5<i && i<j+1 && j+1<20".116 117 if (13<=age<20)118 "Teen-ager";119 120* if you know a switch stmt will not exceed the lowest or highest case values.121switch [] is a little faster because it doesn't check.122 123* switch stmts always use a jump table. Don't use them with cases with really124big, sparse ranges.125 126* Allows ranges like "case 4...7:" in switch stmts.127 128* A no case number causes next higher int case in switch stmts. See129::/Demo/NullCase.HC.130 131 I64 i;132 for (i=0;i<20;i++)133 switch (i) {134 case: "Zero\n"; break; //Starts at zero135 case: "One\n"; break; //One plus prev case.136 case: "Two\n"; break;137 case: "Three\n"; break;138 case 10: "Ten\n"; break;139 case: "Eleven\n"; break; //One plus prev case.140 }141 142* Switch statements can be nestled with a single switch expression! This is143known as a "sub_switch" statement. start/end are used to group cases. Don't144goto out of, throw an exception out of, or return out of the start front porch145area. See ::/Demo/SubSwitch.HC.146 147 I64 i;148 for (i=0;i<10;i++)149 switch (i) {150 case 0: "Zero "; break;151 case 2: "Two "; break;152 case 4: "Four "; break;153 start:154 "[";155 case 1: "One"; break;156 case 3: "Three";break;157 case 5: "Five"; break;158 end:159 "] ";160 break;161 }162 OutPut:163 >Zero [One] Two [Three] Four [Five]164 165* A no_warn stmt will suppress an unused var warning.166 167* You can have multiple member vars of a class named "pad" or "reserved", and it168won't issue warnings.169 170* noreg or reg can be placed before a function local var name. You can,171optionally, specify a reg after the reg keyword.172 173 U0 Main()174 {175 //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else176 clobbered.177 I64 reg R15 i=5, noreg j=4;178 no_warn i;179 asm {180 MOV RAX,R15181 CALL &PUT_HEX_U64182 MOV RAX,'\n'183 CALL &PUT_CHARS184 MOV RAX,U64 &j[RBP]185 CALL &PUT_HEX_U64186 MOV RAX,'\n'187 CALL &PUT_CHARS188 }189 }190 191* interrupt, haserrcode, public, argpop or noargpop are function flags. See192IRQKbd().193 194* A single quote can encompass multiple characters. 'ABC' is equ to 0x434241.195PutChars() takes multiple characters.196 197 asm {198 HELLO_WORLD::199 PUSH RBP200 MOV RBP,RSP201 MOV RAX,'Hello '202 CALL &PUT_CHARS203 MOV RAX,'World\n'204 CALL &PUT_CHARS205 LEAVE206 RET207 }208 Call(HELLO_WORLD);209 PutChars('Hello ');210 PutChars('World\n');211 212* The "`" operator raises a base to a power.213 214* There is no question-colon operator.215 216* TempleOS operator precedence217 `,>>,<<218 *,/,%219 &220 ^221 |222 +,-223 <,>,<=,>=224 ==,!=225 &&226 ^^227 ||228 =,<<=,>>=,*=,/=,&=,|=,^=,+=,-=229 230* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in231code.232 233* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts.234 235* With the #exe{} feature in your src code, you can place programs that insert236text into the stream of code being compiled. See #exe {} for an example where237the date/time and compile-time prompting for cfguration data is placed into a238program. StreamPrint() places text into a src program stream following the239conclusion of the #exe{} blk.240 241* No #define functions exist (I'm not a fan)242 243* No typedef, use class.244 245* No type-checking246 247* Can't use <> with #include, use "".248 249* "$" is an escape character. Two dollar signs signify an ordinary $. See250DolDoc. In asm or HolyC code, it also refers to the inst's address or the251offset in a class definition.252 253* union is more like a class, so you don't reference it with a union label after254you define it. Some common unions are declared in KernelA.HH for 1,2,4 and 8255byte objects. If you place a type in front of a union declaration, that is the256type when used by itself. See ::/Demo/SubIntAccess.HC.257 258* class member vars can have meta data. format and data are two meta data types259now used. All compiler structures are saved and you can access the compiler's260info about classes and vars. See ::/Demo/ClassMeta.HC and DocForm().261 262* There is a keyword lastclass you use as a dft arg. It is set to the class263name of the prev arg. See ::/Demo/LastClass.HC, ClassRep(), DocForm() and264::/Demo/Dsk/BlkDevRep.HC.265 266* See ::/Demo/Exceptions.HC. try{} catch{} and throw are different from C++. th267row is a function with an 8-byte or less char arg. The char string passed in th268row() can be accessed from within a catch{} using the Fs->except_ch. Within a c269atch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the270search for a hndlr. Use PutExcept() as a hndlr, if you like.271 272* A function is available similar to sizeof which provides the offset of a273member of a class. It's called offset. You place the class name and member274inside as in offset(classname.membername). It has nothing to do with 16-bit275code. Both sizeof and offset only accept one level of member vars. That is,276you can't do sizeof(classname.membername.submembername).277 278* There is no continue stmt. Use goto.279 280* lock{} can be used to apply asm LOCK prefixes to code for safe multicore281read-modify-write accesses. The code bracked with have LOCK asm prefix's282applied to relevant insts within. It's a little shoddy. See283::/Demo/MultiCore/Lock.HC.284 285* There is a function called MSize() which gives the size of an object alloced286off the heap. For larger size allocations, the system rounds-up to a power of287two, so MSize() lets you know the real size and you can take full advantage of288it.289 290* You CAN Free() a NULL ptr. Useful variants of MAlloc() can be found Here.291Each task has a heap and you can MAlloc and Free off-of other task's heaps, or292make an independent heap with HeapCtrlInit(). See HeapLog() for an example.293 294* The stk does not grow because virtual mem is not used. I recommend allocating295large local vars from the heap. You can change MEM_DFT_STK and recompile Kernel296or request more when doing a Spawn(). You can use CallStkGrow(), but it's odd.297See ::/Demo/StkGrow.HC.298 299* Only one base class is allowed.300 301* printf() has new codes. See Print("") Fmt Strings.302 303* All values are extended to 64-bit when accessed. Intermediate calculations304are done with 64-bit values.305 306 U0 Main()307 {308 I16 i1;309 I32 j1;310 j1=i1=0x12345678; //Resulting i1 is 0x5678 but j1 is 0x12345678311 312 I64 i2=0x8000000000000000;313 Print("%X\n",i2>>1); //Res is 0xC000000000000000 as expected314 315 U64 u3=0x8000000000000000;316 Print("%X\n",u3>>1); //Res is 0x4000000000000000 as expected317 318 I32 i4=0x80000000; //const is loaded into a 64-bit reg var.319 Print("%X\n",i4>>1); //Res is 0x40000000320 321 I32 i5=-0x80000000;322 Print("%X\n",i5>>1); //Res is 0xFFFFFFFFC0000000323 }324 325 