diff --git a/compiler/engine.py b/compiler/engine.py
index 3595c4a..3b2a44c 100644
--- a/compiler/engine.py
+++ b/compiler/engine.py
@@ -77,9 +77,16 @@ class Engine:
self.write(line, end="")
self.advance()
- for e in grammar:
- self.compile(e)
+ print(lookup_keys)
+ print("grammar inside matchDict ")
+ print(grammar)
+
+ # Grammar can be none
+ if grammar:
+ self.compile(grammar)
+
+ # TODO: Improve open and close for dicts
if isinstance(el, Element):
self.close(el)
@@ -109,7 +116,7 @@ class Engine:
self.advance()
return True
else:
- # print("%s != %s" % (current, expected))
+ print("%s != %s" % (current, expected))
return False
def open(self, el):
@@ -124,29 +131,37 @@ class Engine:
If you set matchOnly = true, the cursor will not move forward
If it is forced to move forward (LL1 grammar for eg,) it will raise an error instead
"""
- def compile(self, thing, matchOnly = False):
- if isinstance(thing, Element):
- ret = self.compile(thing.grammar[0], True)
- if (matchOnly == False and ret) or thing.empty:
- self.open(thing)
- for e in thing.grammar:
- ret = self.compile(e)
- self.close(thing)
- return ret
- elif callable(thing):
- grammar = thing()
- return self.compile(grammar, matchOnly)
- else:
- grammar = thing
- grammarType = type(grammar)
+ def compile(self, grammar, matchOnly = False):
+ if callable(grammar):
+ ret = self.compile(grammar(), matchOnly)
+ elif isinstance(grammar, Element):
+ ret = self.compile(grammar.grammar, True)
- if grammarType == list:
- return self.ZeroOrMany(grammar, matchOnly)
- elif grammarType == dict:
- return self.MatchDict(grammar, matchOnly)
- elif grammarType == tuple:
- return self.ZeroOrOne(grammar, matchOnly)
- elif grammarType == Atom:
- return self.MatchAtom(grammar, matchOnly)
+ if grammar.name == 'term':
+ print(ret)
+ print(self.atom())
+
+ if (matchOnly == False and ret) or grammar.empty:
+ self.open(grammar)
+ # Avoid useless compilation
+ if ret:
+ ret = self.compile(grammar.grammar)
+ self.close(grammar)
+ elif isinstance(grammar, Sequence):
+ if matchOnly:
+ ret = self.compile(grammar[0], True)
else:
- raise Exception("Should not have reached here")
+ for e in grammar:
+ ret = self.compile(e)
+ elif isinstance(grammar, list):
+ ret = self.ZeroOrMany(grammar, matchOnly)
+ elif isinstance(grammar,dict):
+ ret = self.MatchDict(grammar, matchOnly)
+ elif isinstance(grammar,tuple):
+ ret = self.ZeroOrOne(grammar, matchOnly)
+ elif isinstance(grammar,Atom):
+ ret = self.MatchAtom(grammar, matchOnly)
+ else:
+ raise Exception("Invalid Grammar")
+
+ return ret
diff --git a/compiler/grammar.py b/compiler/grammar.py
index c519f9a..f1e1f18 100644
--- a/compiler/grammar.py
+++ b/compiler/grammar.py
@@ -20,73 +20,109 @@ This is basically an attempt to translate Figure 10.5 from the book into
a Python structure.
"""
+
+class Sequence(list):
+ def first(self):
+ return self[0]
+
class Element:
# Usually I avoid inverted boolean variable names, but this is much cleaner
def __init__(self, name, grammar):
- assert(type(grammar)==list)
+ # Since Any derives from list, this ought to work
+ assert(isinstance(grammar, list) or isinstance(grammar, dict))
self.name = name
self.grammar = grammar
self.empty = False
+ def first(self):
+ if isinstance(self.grammar, list):
+ return self.grammar[0]
+ elif isinstance(self.grammar, dict):
+ return list(self.grammar.keys())[0]
+
def __repr__(self):
return self.name
-CLASSVARDEC = Element('classVarDec', [
+CLASSVARDEC = Element('classVarDec', Sequence([
# static|field type (, name)* ;
Atom.STATIC | Atom.FIELD,
Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER,
Atom.IDENTIFIER,
+ # Zero or one of these
[Atom.COMMA, Atom.IDENTIFIER],
Atom.SEMICOLON
-])
+]))
-VARDEC = Element('varDec', [Atom.VAR, Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER, Atom.IDENTIFIER,
+VARDEC = Element('varDec', Sequence([
+ Atom.VAR, Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER, Atom.IDENTIFIER,
+ # Zero or one of these
[Atom.COMMA, Atom.IDENTIFIER],
Atom.SEMICOLON
-])
+]))
-# Since this is not a non-terminal, we can just write it as a constant
+# Since these are not a non-terminal, we can just write it as a constant
OP = Atom.PLUS | Atom.MINUS | Atom.MUL | Atom.DIV | Atom.AND | Atom.OR | Atom.GT | Atom.LT | Atom.EQ
UNARY_OP = Atom.NOT | Atom.MINUS
-CONSTANT = Atom.TRUE | Atom.FALSE|Atom.NULL|Atom.THIS
+CONSTANT = Atom.TRUE | Atom.FALSE | Atom.NULL | Atom.THIS
""" Pseudo-element to help define subroutine declarations """
-RETURN_TYPES= Atom.INT | Atom.CHAR|Atom.BOOLEAN|Atom.IDENTIFIER|Atom.VOID
+RETURN_TYPES= Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER | Atom.VOID
-# TODO: This is missing the following:
-# var [expression]
-# subRoutineCall
-# (expressions in parenthes)
-# unaryOP TERM
-TERM = Element('term', [
- Atom.INTEGERCONSTANT | Atom.STRINGCONSTANT | Atom.TRUE | Atom.FALSE | Atom.NULL| Atom.THIS | Atom.IDENTIFIER
-])
+# This is a flattened version of the Term structure
+TERM = Element('term', {
+ (Atom.INTEGERCONSTANT,): None,
+ (Atom.STRINGCONSTANT,): None,
+ (Atom.TRUE,): None,
+ (Atom.FALSE,): None,
+ (Atom.NULL,): None,
+ (Atom.THIS,): None,
+ # unaryOp TERM
+ (Atom.NOT,): Sequence([lambda: TERM]),
+ (Atom.MINUS,): Sequence([lambda: TERM]),
+ # (expression)
+ (Atom.PAREN_OPEN,): Sequence([lambda: EXPRESSION, Atom.PAREN_CLOSE]),
+ (Atom.IDENTIFIER,): {
+ # array lookup
+ (Atom.SQUARE_OPEN,): Sequence([lambda: EXPRESSION, Atom.SQUARE_CLOSE]),
+ # Subroutine call, but with class name
+ (Atom.DOT,): Sequence([
+ Atom.IDENTIFIER,
+ Atom.PAREN_OPEN,
+ lambda: EXPRESSIONLIST,
+ Atom.PAREN_CLOSE
+ ]),
+ # Subroutine call, but to same class
+ (Atom.PAREN_OPEN,): Sequence([
+ lambda: EXPRESSIONLIST,
+ Atom.PAREN_CLOSE
+ ])
+ }
+})
-EXPRESSION = Element('expression', [TERM, [OP, TERM]])
+EXPRESSION = Element('expression', Sequence([TERM, [OP, TERM]]))
-EXPRESSIONLIST = Element('expressionList', [(EXPRESSION, [Atom.COMMA, EXPRESSION])])
+EXPRESSIONLIST = Element('expressionList', Sequence([
+ (EXPRESSION, [Atom.COMMA, EXPRESSION])
+]))
-DO_STATEMENT = Element('doStatement', [{
- (Atom.IDENTIFIER, Atom.PAREN_OPEN): [
- EXPRESSIONLIST,
- Atom.PAREN_CLOSE,
- ],
- (Atom.IDENTIFIER, Atom.DOT): [
- Atom.IDENTIFIER,
- Atom.PAREN_OPEN,
- EXPRESSIONLIST,
- Atom.PAREN_CLOSE
- ]
-},Atom.SEMICOLON])
+SUBROUTINE_CALL = [
+ (Atom.IDENTIFIER, Atom.DOT),
+ Atom.IDENTIFIER,
+ Atom.PAREN_OPEN,
+ EXPRESSIONLIST,
+ Atom.PAREN_CLOSE
+]
-LET_STATEMENT = Element('letStatement', [
+DO_STATEMENT = Element('doStatement', Sequence([SUBROUTINE_CALL,Atom.SEMICOLON]))
+
+LET_STATEMENT = Element('letStatement', Sequence([
Atom.IDENTIFIER,
(Atom.SQUARE_OPEN, EXPRESSION, Atom.SQUARE_CLOSE),
Atom.EQ,
EXPRESSION,
Atom.SEMICOLON
-])
+]))
-IF_STATEMENT = Element('ifStatement', [
+IF_STATEMENT = Element('ifStatement', Sequence([
Atom.PAREN_OPEN,
EXPRESSION,
Atom.PAREN_CLOSE,
@@ -95,18 +131,20 @@ IF_STATEMENT = Element('ifStatement', [
Atom.BRACE_CLOSE,
# This is the tricky one
( Atom.ELSE, Atom.BRACE_OPEN, lambda:STATEMENTS, Atom.BRACE_CLOSE)
-])
+]))
-WHILE_STATEMENT = Element('whileStatement', [
+WHILE_STATEMENT = Element('whileStatement', Sequence([
Atom.PAREN_OPEN,
EXPRESSION,
Atom.PAREN_CLOSE,
Atom.BRACE_OPEN,
lambda: STATEMENTS,
Atom.BRACE_CLOSE,
-])
+]))
-RETURN_STATEMENT = Element('returnStatement', [(EXPRESSION), Atom.SEMICOLON])
+RETURN_STATEMENT = Element('returnStatement', Sequence([
+ (EXPRESSION), Atom.SEMICOLON
+]))
# Just a constant, since this isn't a non-terminal
STATEMENT = {
@@ -117,31 +155,32 @@ STATEMENT = {
(Atom.RETURN,): RETURN_STATEMENT
}
-STATEMENTS = Element('statements', [[STATEMENT]])
+STATEMENTS = Element('statements', Sequence([[STATEMENT]]))
-SUBROUTINE_BODY = Element('subroutineBody', [
+SUBROUTINE_BODY = Element('subroutineBody', Sequence([
# One or more variable declarations
# `var type varName (, varName)* ;`
Atom.BRACE_OPEN,
[VARDEC],
STATEMENTS,
Atom.BRACE_CLOSE
-])
+]))
# Parameter List =
# (
# (type varName) (, type varName)*
# )?
# we use tuples for zero OR one of a sequence
-PARAMETER_LIST = Element('parameterList', [(
+PARAMETER_LIST = Element('parameterList', Sequence([(
Atom.INT | Atom.CHAR | Atom.BOOLEAN | Atom.IDENTIFIER,
Atom.IDENTIFIER,
+ # Zero or one of the following:
[Atom.COMMA, Atom.INT | Atom.CHAR|Atom.BOOLEAN|Atom.IDENTIFIER, Atom.IDENTIFIER]
-)])
+)]))
EXPRESSIONLIST.empty = PARAMETER_LIST.empty = True
-SUBROUTINEDEC = Element('subroutineDec', [
+SUBROUTINEDEC = Element('subroutineDec', Sequence([
# (constructor | function | method) (void | type) subRoutineName '(' parameterList ')'
# subroutineBody
Atom.CONSTRUCTOR | Atom.FUNCTION | Atom.METHOD,
@@ -151,13 +190,13 @@ SUBROUTINEDEC = Element('subroutineDec', [
PARAMETER_LIST,
Atom.PAREN_CLOSE,
SUBROUTINE_BODY,
-])
+]))
-CLASS = Element('class', [
+CLASS = Element('class', Sequence([
Atom.CLASS,
Atom.IDENTIFIER,
Atom.BRACE_OPEN,
[CLASSVARDEC],
[SUBROUTINEDEC],
Atom.BRACE_CLOSE
-])
+]))
diff --git a/projects/10/ArrayTest/Main.jack.xml b/projects/10/ArrayTest/Main.jack.xml
new file mode 100644
index 0000000..e37c6b4
--- /dev/null
+++ b/projects/10/ArrayTest/Main.jack.xml
@@ -0,0 +1,286 @@
+
+ class
+ Main
+ {
+
+ function
+ void
+ main
+ (
+
+
+ )
+
+ {
+
+ var
+ Array
+ a
+ ;
+
+
+ var
+ int
+ length
+ ;
+
+
+ var
+ int
+ i
+ ,
+ sum
+ ;
+
+
+
+ let
+ length
+ =
+
+
+ Keyboard
+ .
+ readInt
+ (
+
+
+
+ HOW MANY NUMBERS?
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ a
+ =
+
+
+ Array
+ .
+ new
+ (
+
+
+
+ length
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ i
+ =
+
+
+ 0
+
+
+ ;
+
+
+ while
+ (
+
+
+ i
+
+ <
+
+ length
+
+
+ )
+ {
+
+
+ let
+ a
+ [
+
+
+ i
+
+
+ ]
+ =
+
+
+ Keyboard
+ .
+ readInt
+ (
+
+
+
+ ENTER THE NEXT NUMBER:
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ i
+ =
+
+
+ i
+
+ +
+
+ 1
+
+
+ ;
+
+
+ }
+
+
+ let
+ i
+ =
+
+
+ 0
+
+
+ ;
+
+
+ let
+ sum
+ =
+
+
+ 0
+
+
+ ;
+
+
+ while
+ (
+
+
+ i
+
+ <
+
+ length
+
+
+ )
+ {
+
+
+ let
+ sum
+ =
+
+
+ sum
+
+ +
+
+ a
+ [
+
+
+ i
+
+
+ ]
+
+
+ ;
+
+
+ let
+ i
+ =
+
+
+ i
+
+ +
+
+ 1
+
+
+ ;
+
+
+ }
+
+
+ do
+ Output
+ .
+ printString
+ (
+
+
+
+ THE AVERAGE IS:
+
+
+
+ )
+ ;
+
+
+ do
+ Output
+ .
+ printInt
+ (
+
+
+
+ sum
+
+ /
+
+ length
+
+
+
+ )
+ ;
+
+
+ do
+ Output
+ .
+ println
+ (
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+ }
+
diff --git a/projects/10/Square/Main.jack.xml b/projects/10/Square/Main.jack.xml
new file mode 100644
index 0000000..6f8b6dc
--- /dev/null
+++ b/projects/10/Square/Main.jack.xml
@@ -0,0 +1,244 @@
+
+ class
+ Main
+ {
+
+ static
+ boolean
+ test
+ ;
+
+
+ function
+ void
+ main
+ (
+
+
+ )
+
+ {
+
+ var
+ SquareGame
+ game
+ ;
+
+
+
+ let
+ game
+ =
+
+
+ SquareGame
+ .
+ new
+ (
+
+
+ )
+
+
+ ;
+
+
+ do
+ game
+ .
+ run
+ (
+
+
+ )
+ ;
+
+
+ do
+ game
+ .
+ dispose
+ (
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ function
+ void
+ test
+ (
+
+
+ )
+
+ {
+
+ var
+ int
+ i
+ ,
+ j
+ ;
+
+
+ var
+ String
+ s
+ ;
+
+
+ var
+ Array
+ a
+ ;
+
+
+
+ if
+ (
+
+
+ false
+
+
+ )
+ {
+
+
+ let
+ s
+ =
+
+
+ string constant
+
+
+ ;
+
+
+ let
+ s
+ =
+
+
+ null
+
+
+ ;
+
+
+ let
+ a
+ [
+
+
+ 1
+
+
+ ]
+ =
+
+
+ a
+ [
+
+
+ 2
+
+
+ ]
+
+
+ ;
+
+
+ }
+ else
+ {
+
+
+ let
+ i
+ =
+
+
+ i
+
+ *
+
+ (
+
+
+ -
+
+ j
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ j
+ =
+
+
+ j
+
+ /
+
+ (
+
+
+ -
+
+ 2
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ i
+ =
+
+
+ i
+
+ |
+
+ j
+
+
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+ }
+
diff --git a/projects/10/Square/Square.jack.xml b/projects/10/Square/Square.jack.xml
new file mode 100644
index 0000000..4db1f16
--- /dev/null
+++ b/projects/10/Square/Square.jack.xml
@@ -0,0 +1,1211 @@
+
+ class
+ Square
+ {
+
+ field
+ int
+ x
+ ,
+ y
+ ;
+
+
+ field
+ int
+ size
+ ;
+
+
+ constructor
+ Square
+ new
+ (
+
+ int
+ Ax
+ ,
+ int
+ Ay
+ ,
+ int
+ Asize
+
+ )
+
+ {
+
+
+ let
+ x
+ =
+
+
+ Ax
+
+
+ ;
+
+
+ let
+ y
+ =
+
+
+ Ay
+
+
+ ;
+
+
+ let
+ size
+ =
+
+
+ Asize
+
+
+ ;
+
+
+ do
+ draw
+ (
+
+
+ )
+ ;
+
+
+ return
+
+
+ this
+
+
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ dispose
+ (
+
+
+ )
+
+ {
+
+
+ do
+ Memory
+ .
+ deAlloc
+ (
+
+
+
+ this
+
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ draw
+ (
+
+
+ )
+
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ true
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ erase
+ (
+
+
+ )
+
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ false
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ incSize
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ (
+
+
+ (
+
+
+ y
+
+ +
+
+ size
+
+
+ )
+
+ <
+
+ 254
+
+
+ )
+
+ &
+
+ (
+
+
+ (
+
+
+ x
+
+ +
+
+ size
+
+
+ )
+
+ <
+
+ 510
+
+
+ )
+
+
+ )
+ {
+
+
+ do
+ erase
+ (
+
+
+ )
+ ;
+
+
+ let
+ size
+ =
+
+
+ size
+
+ +
+
+ 2
+
+
+ ;
+
+
+ do
+ draw
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ decSize
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ size
+
+ >
+
+ 2
+
+
+ )
+ {
+
+
+ do
+ erase
+ (
+
+
+ )
+ ;
+
+
+ let
+ size
+ =
+
+
+ size
+
+ -
+
+ 2
+
+
+ ;
+
+
+ do
+ draw
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ moveUp
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ y
+
+ >
+
+ 1
+
+
+ )
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ false
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ (
+
+
+ y
+
+ +
+
+ size
+
+
+ )
+
+ -
+
+ 1
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ let
+ y
+ =
+
+
+ y
+
+ -
+
+ 2
+
+
+ ;
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ true
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ 1
+
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ moveDown
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ (
+
+
+ y
+
+ +
+
+ size
+
+
+ )
+
+ <
+
+ 254
+
+
+ )
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ false
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ 1
+
+
+
+ )
+ ;
+
+
+ let
+ y
+ =
+
+
+ y
+
+ +
+
+ 2
+
+
+ ;
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ true
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ (
+
+
+ y
+
+ +
+
+ size
+
+
+ )
+
+ -
+
+ 1
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ moveLeft
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ x
+
+ >
+
+ 1
+
+
+ )
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ false
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ (
+
+
+ x
+
+ +
+
+ size
+
+
+ )
+
+ -
+
+ 1
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ let
+ x
+ =
+
+
+ x
+
+ -
+
+ 2
+
+
+ ;
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ true
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ 1
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ moveRight
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ (
+
+
+ x
+
+ +
+
+ size
+
+
+ )
+
+ <
+
+ 510
+
+
+ )
+ {
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ false
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ x
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ 1
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ let
+ x
+ =
+
+
+ x
+
+ +
+
+ 2
+
+
+ ;
+
+
+ do
+ Screen
+ .
+ setColor
+ (
+
+
+
+ true
+
+
+
+ )
+ ;
+
+
+ do
+ Screen
+ .
+ drawRectangle
+ (
+
+
+
+ (
+
+
+ x
+
+ +
+
+ size
+
+
+ )
+
+ -
+
+ 1
+
+
+ ,
+
+
+ y
+
+
+ ,
+
+
+ x
+
+ +
+
+ size
+
+
+ ,
+
+
+ y
+
+ +
+
+ size
+
+
+
+ )
+ ;
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+ }
+
diff --git a/projects/10/Square/SquareGame.jack.xml b/projects/10/Square/SquareGame.jack.xml
new file mode 100644
index 0000000..6acbb6b
--- /dev/null
+++ b/projects/10/Square/SquareGame.jack.xml
@@ -0,0 +1,643 @@
+
+ class
+ SquareGame
+ {
+
+ field
+ Square
+ square
+ ;
+
+
+ field
+ int
+ direction
+ ;
+
+
+ constructor
+ SquareGame
+ new
+ (
+
+
+ )
+
+ {
+
+
+ let
+ square
+ =
+
+
+ Square
+ .
+ new
+ (
+
+
+
+ 0
+
+
+ ,
+
+
+ 0
+
+
+ ,
+
+
+ 30
+
+
+
+ )
+
+
+ ;
+
+
+ let
+ direction
+ =
+
+
+ 0
+
+
+ ;
+
+
+ return
+
+
+ this
+
+
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ dispose
+ (
+
+
+ )
+
+ {
+
+
+ do
+ square
+ .
+ dispose
+ (
+
+
+ )
+ ;
+
+
+ do
+ Memory
+ .
+ deAlloc
+ (
+
+
+
+ this
+
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ moveSquare
+ (
+
+
+ )
+
+ {
+
+
+ if
+ (
+
+
+ direction
+
+ =
+
+ 1
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ moveUp
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ direction
+
+ =
+
+ 2
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ moveDown
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ direction
+
+ =
+
+ 3
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ moveLeft
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ direction
+
+ =
+
+ 4
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ moveRight
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ do
+ Sys
+ .
+ wait
+ (
+
+
+
+ 5
+
+
+
+ )
+ ;
+
+
+ return
+ ;
+
+
+ }
+
+
+
+ method
+ void
+ run
+ (
+
+
+ )
+
+ {
+
+ var
+ char
+ key
+ ;
+
+
+ var
+ boolean
+ exit
+ ;
+
+
+
+ let
+ exit
+ =
+
+
+ false
+
+
+ ;
+
+
+ while
+ (
+
+
+ ~
+
+ exit
+
+
+
+ )
+ {
+
+
+ while
+ (
+
+
+ key
+
+ =
+
+ 0
+
+
+ )
+ {
+
+
+ let
+ key
+ =
+
+
+ Keyboard
+ .
+ keyPressed
+ (
+
+
+ )
+
+
+ ;
+
+
+ do
+ moveSquare
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 81
+
+
+ )
+ {
+
+
+ let
+ exit
+ =
+
+
+ true
+
+
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 90
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ decSize
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 88
+
+
+ )
+ {
+
+
+ do
+ square
+ .
+ incSize
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 131
+
+
+ )
+ {
+
+
+ let
+ direction
+ =
+
+
+ 1
+
+
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 133
+
+
+ )
+ {
+
+
+ let
+ direction
+ =
+
+
+ 2
+
+
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 130
+
+
+ )
+ {
+
+
+ let
+ direction
+ =
+
+
+ 3
+
+
+ ;
+
+
+ }
+
+
+ if
+ (
+
+
+ key
+
+ =
+
+ 132
+
+
+ )
+ {
+
+
+ let
+ direction
+ =
+
+
+ 4
+
+
+ ;
+
+
+ }
+
+
+ while
+ (
+
+
+ ~
+
+ (
+
+
+ key
+
+ =
+
+ 0
+
+
+ )
+
+
+
+ )
+ {
+
+
+ let
+ key
+ =
+
+
+ Keyboard
+ .
+ keyPressed
+ (
+
+
+ )
+
+
+ ;
+
+
+ do
+ moveSquare
+ (
+
+
+ )
+ ;
+
+
+ }
+
+
+ }
+
+
+ return
+ ;
+
+
+ }
+
+
+ }
+