001 #include "Lexer.HC"; 002 #define AST_UNOP 1 003 #define AST_BINOP 2 004 #define AST_KEYWORD 3 005 #define AST_ASSIGN 4 006 #define AST_STR 5 007 #define AST_VAR 6 008 #define AST_ARRAY 7 009 #define AST_CASCADE 8 010 #define AST_BLOCK 9 011 #define AST_CHR 10 012 #define AST_NUM 11 013 #define AST_SYMBOL 12 014 #define AST_CASCADE_HEAD 13 //str points to cascade head 015 #define AST_RETURN 14 016 #define AST_SELF 15 017 #define AST_SUPER 16 018 class CAST:CQue { 019 CQue args; 020 I64 type; 021 union { 022 U8 op_name[STR_LEN]; 023 U8 name[STR_LEN]; 024 }; 025 union { 026 F64 num; 027 U8 *str; 028 CQue body; 029 }; 030 }; 031 class CName:CQue { 032 U8 name[STR_LEN]; 033 }; 034 class CMethod { 035 U8 name[STR_LEN]; 036 I64 arity; 037 CQue args; //CName 038 CQue temps; 039 CQue body; //CAST 040 }; 041 extern CAST *ParseAst(CLexer *l); 042 extern CAST *ParseCascade(CLexer *l); 043 CAST *ParseLiteral(CLexer *l) { 044 CAST *ret,*item; 045 if(l->tok=='(') { 046 Lex(l); 047 ret=ParseCascade(l); 048 if(l->tok!=')') 049 LexExcept(l,"Expeted a niggerfuckin ')' nigger."); 050 Lex(l); 051 return ret; 052 } 053 if(l->tok=='#') { 054 if(Lex(l)=='(') { 055 ret=CAlloc(sizeof CAST); 056 ret->type=AST_ARRAY; 057 QueInit(&ret->body); 058 QueInit(ret); 059 Lex(l); 060 do { 061 if(l->tok==')') 062 break; 063 if(!l->tok) 064 LexExcept(l,"Unexpected end of input you fuckin goatballer."); 065 item=ParseAst(l); 066 if(!item) 067 LexExcept(l,"Expected a motherfuckin array item."); 068 QueIns(item,ret->body.last); 069 } while(TRUE); 070 Lex(l); 071 } else if(l->tok==TOK_NAME) { 072 ret=CAlloc(sizeof CAST); 073 ret->type=AST_SYMBOL; 074 QueInit(&ret->args); 075 QueInit(ret); 076 StrCpy(ret->name,l->str); 077 Lex(l); 078 return ret; 079 } else if(!l->tok) 080 LexExcept(l,"Erection's over;Unexpected end of input."); 081 } else if(l->tok=='[') { 082 ret=CAlloc(sizeof CAST); 083 ret->type=AST_BLOCK; 084 QueInit(&ret->args); 085 QueInit(&ret->body); 086 QueInit(ret); 087 //Arguemnts Nigstrodamus 088 Lex(l); 089 if(l->tok==':') { 090 while(l->tok!='|') { 091 if(l->tok==':') { 092 if(Lex(l)!=TOK_NAME) { 093 LexExcept(l,"Put away you 50 inch nigger shlong and give me and argument."); 094 } 095 item=CAlloc(sizeof CAST); 096 item->type=AST_VAR; 097 StrCpy(item->name,l->str); 098 QueInit(&item->args); 099 QueInit(item); 100 QueIns(item,ret->args.last); 101 Lex(l); 102 } else 103 LexExcept(l,"Nigger please,expected a ':'"); 104 } 105 Lex(l); 106 } 107 while(l->tok!=']') { 108 item=ParseAst(l); 109 if(!item) 110 LexExcept(l,"Are you fucking kidding me? I need an expression here."); 111 QueIns(item,ret->body.last); 112 if(l->tok=='.') 113 Lex(l); 114 } 115 Lex(l); 116 item=ret->args.next; 117 while(item!=&ret->args) { 118 item=item->next; 119 } 120 return ret; 121 } else if(l->tok==TOK_STR) { 122 item=CAlloc(sizeof CAST); 123 item->type=AST_STR; 124 item->str=StrNew(l->str); 125 QueInit(&item->args); 126 QueInit(item); 127 Lex(l); 128 return item; 129 } else if(l->tok==TOK_NAME) { 130 item=CAlloc(sizeof CAST); 131 if(!StrCmp(l->str,"self")) { 132 item->type=AST_SELF; 133 goto np; 134 } else if(!StrCmp(l->str,"super")) { 135 item->type=AST_SUPER; 136 goto np; 137 } 138 item->type=AST_VAR; 139 StrCpy(item->name,l->str); 140 np: 141 QueInit(&item->args); 142 QueInit(item); 143 Lex(l); 144 return item; 145 } else if(l->tok==TOK_CHR) { 146 item=CAlloc(sizeof CAST); 147 item->type=AST_CHR; 148 item->name[0]=l->chr; 149 item->name[1]=0; 150 QueInit(&item->args); 151 QueInit(item); 152 Lex(l); 153 return item; 154 } else if(l->tok==TOK_NUM) { 155 item=CAlloc(sizeof CAST); 156 item->type=AST_NUM; 157 item->num=l->num; 158 QueInit(&item->args); 159 QueInit(item); 160 Lex(l); 161 return item; 162 } 163 LexExcept(l,"Unexpected token here nigga."); 164 } 165 CAST *ParseUnop(CLexer *l,CAST *left=NULL) { 166 if(!left) left=ParseLiteral(l); 167 CAST *ret; 168 CLexer backup; 169 I64 old_pos,old_ch; 170 if(!left) return NULL; 171 again: 172 if(l->tok==TOK_NAME) { 173 MemCpy(&backup,l,sizeof CLexer); 174 if(Lex(l)==':') { 175 MemCpy(l,&backup,sizeof CLexer); 176 return left; 177 } 178 ret=CAlloc(sizeof CAST); 179 ret->type=AST_UNOP; 180 QueInit(&ret->args); 181 QueInit(ret); 182 QueIns(left,&ret->args); 183 StrCpy(ret->name,backup.str); 184 left=ret; 185 goto again; 186 } 187 return left; 188 } 189 CAST *ParseBinop(CLexer *l,CAST *left=NULL) { 190 CAST *right,*ret; 191 if(!left) left=ParseUnop(l); 192 if(!left) return NULL; 193 I64 idx; 194 again: 195 if(l->tok!=TOK_NAME) { 196 for(idx=0;l->tok.u8[idx];idx++) { 197 if(!IsOperatorChr(l->tok.u8[idx])) 198 goto fail; 199 } 200 ret=CAlloc(sizeof CAST); 201 ret->type=AST_BINOP; 202 QueInit(&ret->args); 203 QueInit(ret); 204 QueIns(left,ret->args.last); 205 StrCpy(ret->name,&l->tok); 206 if(!idx) goto fail; 207 Lex(l); 208 209 right=ParseUnop(l); 210 if(!right) 211 LexExcept(l,"Binop needs 2 fucking operands nigga."); 212 QueIns(right,ret->args.last); 213 left=ret; 214 goto again; 215 } 216 fail: 217 return left; 218 } 219 CAST *ParseKeyword(CLexer *l,CAST *left=NULL) { 220 if(!left) left=ParseBinop(l); 221 CAST *ret=NULL,*right; 222 CLexer backup; 223 U8 buf[STR_LEN],str2[STR_LEN]; 224 buf[0]=0; 225 if(!left) return NULL; 226 again: 227 if(l->tok==TOK_NAME) { 228 MemCpy(&backup,l,sizeof CLexer); 229 StrCpy(str2,l->str); 230 if(Lex(l)!=':') { 231 MemCpy(l,&backup,sizeof CLexer); 232 return left; 233 } 234 CatPrint(buf,"%s:",str2); 235 if(!ret) { 236 ret=CAlloc(sizeof CAST); 237 ret->type=AST_KEYWORD; 238 QueInit(&ret->args); 239 QueInit(ret); 240 QueIns(left,ret->args.last); 241 } 242 Lex(l); 243 right=ParseBinop(l); 244 if(!right) 245 LexExcept(l,"Where the fuck is my operand"); 246 QueIns(right,ret->args.last); 247 goto again; 248 } 249 if(!StrLen(buf)) 250 return left; 251 StrCpy(ret->name,buf); 252 return ret; 253 } 254 CAST *ParseCascade(CLexer *l) { 255 CAST *left=ParseKeyword(l),*ret=NULL,*item,*alias; 256 if(!left) return left; 257 while(l->tok==';') { 258 if(!ret) { 259 ret=CAlloc(sizeof CAST); 260 ret->type=AST_CASCADE; 261 QueInit(&ret->args); 262 QueInit(ret); 263 QueIns(left,ret->args.last); 264 } 265 Lex(l); 266 alias=CAlloc(sizeof CAST); 267 alias->type=AST_CASCADE_HEAD; 268 alias->str=left; 269 item=ParseKeyword(l,alias); 270 if(alias!=item) { 271 QueIns(item,ret->args.last); 272 } else { 273 item=ParseUnop(l,alias); 274 if(alias!=item) { 275 QueIns(item,ret->args.last); 276 } else 277 LexExcept(l,"Expected a fuckin cascade operation nigga."); 278 } 279 } 280 if(!ret) return left; 281 return ret; 282 } 283 CAST *ParseAst(CLexer *l) { 284 CLexer backup; 285 CAST *var,*right,*assign; 286 U8 assign_to[STR_LEN]; 287 if(l->tok==TOK_NAME) { 288 StrCpy(assign_to,l->str); 289 MemCpy(&backup,l,sizeof CLexer); 290 if(Lex(l)=='_') { 291 var=CAlloc(sizeof CAST); 292 QueInit(var); 293 var->type=AST_VAR; 294 StrCpy(var->name,assign_to); 295 if(right=ParseCascade(l)) { 296 assign=CAlloc(sizeof CAST); 297 QueInit(assign); 298 QueInit(&assign->args); 299 QueIns(var,assign->args.last); 300 QueIns(right,assign->args.last); 301 return assign; 302 } else 303 LexExcept("I want something to asign to '%s' nigga.",assign_to); 304 } else 305 MemCpy(l,&backup,sizeof CLexer); 306 } 307 if(l->tok=='^') { 308 Lex(l); 309 right=ParseCascade(l); 310 if(!right) 311 LexExcept(l,"Nigger toads fiegning 4 a nigger return."); 312 assign=CAlloc(sizeof CAST); 313 assign->type=AST_RETURN; 314 QueInit(assign); 315 QueInit(&assign->args); 316 QueIns(right,assign->args.last); 317 return assign; 318 } 319 return ParseCascade(l); 320 } 321 CMethod *ParseMethod(CLexer *l) { 322 CMethod *m=CAlloc(sizeof CMethod); 323 CName *name,*head; 324 CAST *ast; 325 I64 idx; 326 QueInit(&m->args); 327 QueInit(&m->body); 328 QueInit(&m->temps); 329 while(TRUE) { 330 if(l->tok=='|') 331 break; 332 if(l->tok==TOK_NAME) { 333 CatPrint(m->name,"%s",l->str); 334 if(Lex(l)==':') { 335 CatPrint(m->name,":"); 336 Lex(l); 337 if(l->tok!=TOK_NAME) 338 LexExcept(l,"I expected a name nigga."); 339 m->arity++; 340 name=CAlloc(sizeof CName); 341 StrCpy(name->name,l->str); 342 QueIns(name,m->args.last); 343 Lex(l); 344 } else if(m->arity>1) { 345 LexExcept(l,"I expected a ':' asswipe."); 346 } else {// is unop 347 if(Lex(l)!='|') 348 LexExcept(l,"This is an unop nigga"); 349 else 350 break; 351 } 352 } else { 353 for(idx=0;l->tok.u8[idx];idx++) { 354 if(!IsOperatorChr(l->tok.u8[idx])) 355 LexExcept(l,"Expected a operator/method name here nigga."); 356 } 357 if(Lex(l)==TOK_NAME) { 358 name=CAlloc(sizeof CName); 359 StrCpy(name->name,l->str); 360 QueIns(name,m->args.last); 361 m->arity++; 362 if(Lex(l)!='|') 363 LexExcept(l,"Expected a fuckin '|'."); 364 break; 365 } else 366 LexExcept(l,"I niggin need uh argument name nigga."); 367 } 368 } 369 Lex(l); 370 while(TRUE) { 371 if(l->tok==TOK_NAME) { 372 name=CAlloc(sizeof CName); 373 StrCpy(name->name,l->str); 374 QueIns(name,m->temps.last); 375 Lex(l); 376 } else if(l->tok=='|') { 377 Lex(l); 378 break; 379 } else 380 LexExcept(l,"Go stupid and give me a fucking temporary name."); 381 } 382 while(l->tok) { 383 if(ast=ParseAst(l)) { 384 QueIns(ast,m->body.last); 385 while(l->tok=='.') 386 Lex(l); 387 } else 388 LexExcept(l,"Expected a niggerlicious statement."); 389 } 390 return m; 391 } 392 U0 DumpAst(CAST *s) { 393 CAST *cur,*head; 394 "$ID,2$"; 395 switch(s->type) { 396 case AST_ARRAY: 397 "ARRAY\n"; 398 head=&s->body; 399 for(cur=head->next;cur!=head;cur=cur->next) 400 DumpAst(cur); 401 break; 402 start: 403 case AST_RETURN: 404 "RETURN\n"; 405 break; 406 case AST_CASCADE: 407 "CASCADE\n"; 408 break; 409 case AST_UNOP: 410 "UNOP:%s\n",s->name; 411 break; 412 case AST_BINOP: 413 "BINOP:%s\n",s->name; 414 break; 415 case AST_KEYWORD: 416 "KW:%s\n",s->name; 417 break; 418 case AST_BLOCK: 419 "BLOCK\n"; 420 break; 421 case AST_ASSIGN: 422 "_\n"; 423 break; 424 end: 425 head=&s->args; 426 for(cur=head->next;cur!=head;cur=cur->next) { 427 DumpAst(cur); 428 } 429 if(s->type==AST_BLOCK) { 430 head=&s->body; 431 for(cur=head->next;cur!=head;cur=cur->next) 432 DumpAst(cur); 433 } 434 break; 435 case AST_SELF: 436 "SELF\n"; 437 break; 438 case AST_SUPER: 439 "SUPER\n"; 440 break; 441 case AST_STR: 442 "STR:\"%Q\"\n",s->str; 443 break; 444 case AST_VAR: 445 "VAR:%s\n",s->name; 446 break; 447 case AST_SYMBOL: 448 "SYM:%s\n",s->name; 449 break; 450 case AST_CHR: 451 "CHR:%s\n",s->name; 452 break; 453 //#define AST_CASCADE 8 454 case AST_NUM: 455 "NUM:%n\n",s->num; 456 break; 457 } 458 "$ID,-2$"; 459 } 460 CLexer *l=LexerNew("123.4 + 456.789 +(3 + 4) add: 100 sqrt to: 1"); 461 Lex(l); 462 DumpAst(ParseAst(l)); 463 CLexer *l=LexerNew("^ (#Window new) + 2 ; open ; addButton: 'hi' "); 464 Lex(l); 465 DumpAst(ParseAst(l)); 466 467 CLexer *l=LexerNew("Method: a|b c| 468 a ifTrue: [ ^ 'poop' ] . 469 ^ a+b+s -self Method: super 470 "); 471 Lex(l); 472 CMethod *m=ParseMethod(l); 473 DumpAst(m->body.next); 474 DumpAst(m->body.last);