comparison code/gqc.tp @ 58:d35601d47db1

Implement if:else in gqc
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Jul 2014 20:03:34 -0700
parents fde898a3cbbe
children 2a5d7308e1df
comparison
equal deleted inserted replaced
57:a3e4d2833301 58:d35601d47db1
363 } else: { 363 } else: {
364 error: "Condition parameter to while:do must be a comparison operator expression" 364 error: "Condition parameter to while:do must be a comparison operator expression"
365 } 365 }
366 } 366 }
367 367
368 _funHandlers set: "if:else" :args syms {
369 cond <- (args value)
370 trueBody <- ((args tail) value) expressions
371 falseBody <- (((args tail) tail) value) expressions
372
373 if: (cond nodeType) = (ast binary) {
374 trueLbl <- prog makeLabel: "true"
375 falseLbl <- prog makeLabel: "false"
376 endLbl <- prog makeLabel: "end"
377
378 saveTempRegs <- _tempRegs
379 l <- compileExpr: (cond left) syms: syms
380 r <- compileExpr: (cond right) syms: syms
381 _tempRegs <- saveTempRegs
382
383 ok <- true
384
385 if: (cond op) = ">=" {
386 prog add: (inst: "JLT" #[
387 falseLbl
388 l
389 r
390 ])
391 } else: {
392 if: (cond op) = "<=" {
393 prog add: (inst: "JGT" #[
394 falseLbl
395 l
396 r
397 ])
398 } else: {
399 if: (cond op) = "!=" {
400 prog add: (inst: "JEQ" #[
401 falseLbl
402 l
403 r
404 ])
405 } else: {
406 if: (cond op) = ">" {
407 prog add: (inst: "JGT" #[
408 trueLbl
409 l
410 r
411 ])
412 prog add: (inst: "MOV" #[
413 reg: 8
414 falseLbl
415 ])
416 } else: {
417 if: (cond op) = "<" {
418 prog add: (inst: "JLT" #[
419 trueLbl
420 l
421 r
422 ])
423 prog add: (inst: "MOV" #[
424 reg: 8
425 falseLbl
426 ])
427 } else: {
428 bodyLbl <- prog makeLabel: "loop_body"
429 if: (cond op) = "=" {
430 prog add: (inst: "JEQ" #[
431 trueLbl
432 l
433 r
434 ])
435 prog add: (inst: "MOV" #[
436 reg: 8
437 falseLbl
438 ])
439 } else: {
440 ok <- false
441 }
442 }
443 }
444 }
445 }
446 }
447 if: ok {
448 prog setLabel: trueLbl
449 //TODO: do 2 passes for labels to allow forward references
450 foreach: trueBody :idx expr {
451 if: (expr nodeType) = (ast sym) {
452 //allow using bare symbols to define labels
453 lbl <- prog makeLabel: (expr name)
454 prog setLabel: lbl
455 syms define: (expr name) lbl
456 } else: {
457 saveTempRegsExpr <- _tempRegs
458 v <- compileExpr: expr syms: syms
459 _tempRegs <- saveTempRegsExpr
460 }
461 }
462 prog add: (inst: "MOV" #[
463 reg: 8
464 endLbl
465 ])
466 prog setLabel: falseLbl
467 //TODO: do 2 passes for labels to allow forward references
468 foreach: falseBody :idx expr {
469 if: (expr nodeType) = (ast sym) {
470 //allow using bare symbols to define labels
471 lbl <- prog makeLabel: (expr name)
472 prog setLabel: lbl
473 syms define: (expr name) lbl
474 } else: {
475 saveTempRegsExpr <- _tempRegs
476 v <- compileExpr: expr syms: syms
477 _tempRegs <- saveTempRegsExpr
478 }
479 }
480 prog setLabel: endLbl
481 } else: {
482 error: "Condition parameter to if:else must be a comparison operator expression"
483 }
484 } else: {
485 error: "Condition parameter to if:else must be a comparison operator expression"
486 }
487 }
488
368 _exprHandlers set: (ast call) :expr syms { 489 _exprHandlers set: (ast call) :expr syms {
369 tc <- (expr tocall) 490 tc <- (expr tocall)
370 if: (tc nodeType) = (ast sym) { 491 if: (tc nodeType) = (ast sym) {
371 _funHandlers ifget: (tc name) :handler { 492 _funHandlers ifget: (tc name) :handler {
372 handler: (expr args) syms 493 handler: (expr args) syms