changeset 69:8a0f1447c034

Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Jul 2014 23:19:23 -0700
parents f4f403c83e80
children 5f44ac1bcbd6
files code/ghost0.gq code/gqc.tp
diffstat 2 files changed, 105 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/code/ghost0.gq	Sun Jul 27 23:11:46 2014 -0700
+++ b/code/ghost0.gq	Sun Jul 27 23:19:23 2014 -0700
@@ -10,7 +10,7 @@
 		} else: {
 			if: dir = left {
 				startX <- startX - 1 
-			} else: {}
+			}
 		}
 		startX
 	}
@@ -21,7 +21,7 @@
 		} else: {
 			if: dir = down {
 				startY <- startY + 1 
-			} else: {}
+			}
 		}
 		startY
 	}
@@ -99,7 +99,7 @@
 			//currently in fright mode, try to run away
 			firstChoice <- opDir: firstChoice
 			secondChoice <- opDir: secondChoice
-		} else: {}
+		}
 		
 		
 		
--- a/code/gqc.tp	Sun Jul 27 23:11:46 2014 -0700
+++ b/code/gqc.tp	Sun Jul 27 23:19:23 2014 -0700
@@ -520,6 +520,108 @@
 		}
 	}
 	
+	_funHandlers set: "if" :args syms {
+		cond <- (args value)
+		trueBody <- ((args tail) value) expressions
+		
+		if: (cond nodeType) = (ast binary) {
+			trueLbl <- prog makeLabel: "true"
+			endLbl <- prog makeLabel: "end"
+			
+			l <- 0
+			r <- preserveTemps: {
+				l <- compileExpr: (cond left) syms: syms
+				compileExpr: (cond right) syms: syms
+			}
+			
+			ok <- true
+			
+			if: (cond op) = ">=" {
+				prog add: (inst: "JLT" #[
+					endLbl
+					l
+					r
+				])
+			} else: {
+				if: (cond op) = "<=" {
+					prog add: (inst: "JGT" #[
+						endLbl
+						l
+						r
+					])
+				} else: {
+					if: (cond op) = "!=" {
+						prog add: (inst: "JEQ" #[
+							endLbl
+							l
+							r
+						])
+					} else: {
+						if: (cond op) = ">" {
+							prog add: (inst: "JGT" #[
+								trueLbl
+								l
+								r
+							])
+							prog add: (inst: "MOV" #[
+								reg: 8
+								endLbl
+							])
+						} else: {
+							if: (cond op) = "<" {
+								prog add: (inst: "JLT" #[
+									trueLbl
+									l
+									r
+								])
+								prog add: (inst: "MOV" #[
+									reg: 8
+									endLbl
+								])
+							}  else: {
+								bodyLbl <- prog makeLabel: "loop_body"
+								if: (cond op) = "=" {
+									prog add: (inst: "JEQ" #[
+										trueLbl
+										l
+										r
+									])
+									prog add: (inst: "MOV" #[
+										reg: 8
+										endLbl
+									])
+								} else: {
+									ok <- false
+								}
+							}
+						}
+					}
+				}
+			}
+			if: ok {
+				prog setLabel: trueLbl
+				//TODO: do 2 passes for labels to allow forward references
+				foreach: trueBody :idx expr {
+					if: (expr nodeType) = (ast sym) {
+						//allow using bare symbols to define labels
+						lbl <- prog makeLabel: (expr name)
+						prog setLabel: lbl
+						syms define: (expr name) lbl
+					} else: {
+						v <- preserveTemps: {
+							compileExpr: expr syms: syms
+						}
+					}
+				}
+				prog setLabel: endLbl
+			} else: {
+				error: "Condition parameter to if must be a comparison operator expression"
+			}
+		} else: {
+			error: "Condition parameter to if must be a comparison operator expression"
+		}
+	}
+	
 	_exprHandlers set: (ast call) :expr syms {
 		tc <- (expr tocall)
 		if: (tc nodeType) = (ast sym) {