<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -60,8 +60,8 @@ data AtomoVal = AInt Integer
               | AHash [(String, (Type, AtomoVal))]
               | AString AtomoVal -- AString == AList of AChars
               | AVariable String
-              | AClass [AtomoVal] [AtomoVal]
-              | AObject [AtomoVal]
+              | AClass Type [AtomoVal] [AtomoVal]
+              | AObject Type [AtomoVal]
               | AAttribute AtomoVal String
               | ADefine Index AtomoVal
               | ADefAttr AtomoVal String AtomoVal
@@ -170,7 +170,7 @@ pretty (AVariable n)    = &quot;&lt;Variable (&quot; ++ n ++ &quot;)&gt;&quot;
 pretty (ADefine n v)    = &quot;&lt;`&quot; ++ show n ++ &quot;': &quot; ++ pretty v ++ &quot;&gt;&quot;
 pretty (ADefAttr _ _ v) = pretty v
 pretty (AStatic _ v)    = pretty v
-pretty (AObject vs)     = &quot;Object:\n&quot; ++ (unlines $ map (&quot; - &quot; ++) $ map pretty vs)
+pretty (AObject _ vs)   = &quot;Object:\n&quot; ++ (unlines $ map (&quot; - &quot; ++) $ map pretty vs)
 pretty (ACall f a)      = &quot;&lt;Call (`&quot; ++ pretty f ++ &quot;') (`&quot; ++ pretty a ++ &quot;')&gt;&quot;
 pretty s@(AString _)    = show $ fromAString s
 pretty (ABlock es)      = intercalate &quot;\n&quot; $ map pretty es
@@ -184,10 +184,10 @@ pretty v@(ALambda _ _ _) = &quot;\x03BB &quot; ++ intercalate &quot; &quot; (map prettyPattern $ rev
                            where
                                lambdas (ALambda p v _) acc = lambdas v (p : acc)
                                lambdas _ acc = acc
-pretty (AClass ss ms) = &quot;&lt;Class (`&quot; ++ statics ++ &quot;') (`&quot; ++ methods ++ &quot;')&gt;&quot;
-                        where
-                            statics = intercalate &quot;' `&quot; (map (\(AStatic n _) -&gt; n) ss)
-                            methods = intercalate &quot;' `&quot; (map (\(ADefine (Define n) _) -&gt; n) ms)
+pretty (AClass n ss ms) = &quot;&lt;Class `&quot; ++ prettyType n ++ &quot;' (`&quot; ++ statics ++ &quot;') (`&quot; ++ methods ++ &quot;')&gt;&quot;
+                          where
+                              statics = intercalate &quot;' `&quot; (map (\(AStatic n _) -&gt; n) ss)
+                              methods = intercalate &quot;' `&quot; (map (\(ADefine (Define n) _) -&gt; n) ms)
 pretty (AError m)       = m
 pretty (AAtom n)        = &quot;@&quot; ++ n
 pretty (AReceive v)     = &quot;&lt;Receive&gt;&quot;
@@ -229,6 +229,11 @@ prettyType (Func a b) = &quot;(&quot; ++ prettyType a ++ &quot; -&gt; &quot; ++ prettyType b ++ &quot;)&quot;
 prettyType (Poly a) = a
 prettyType (None) = &quot;None&quot;
 
+attribute :: AtomoVal -&gt; AtomoVal -&gt; AtomoVal
+attribute f (AVariable n) = AAttribute f n
+attribute f (AAttribute (AVariable a) b) = AAttribute (AAttribute f a) b
+attribute f x = error (&quot;Cannot morph: &quot; ++ show (f, x))
+
 lambdify :: [PatternMatch] -&gt; AtomoVal -&gt; AtomoVal
 lambdify [] b = b
 lambdify (s:ss) b = ALambda s (lambdify ss b) []
@@ -274,6 +279,7 @@ getType (AValue c as (AConstruct _ cs (AData n ps))) = Type (Name n) (args cs as
                                                        where
                                                            args [] [] ps = ps
                                                            args (c:cs) (a:as) ps = args cs as (swapType ps c (getType a))
+getType (AObject t _) = t
 getType a = error (&quot;Cannot get type of `&quot; ++ pretty a ++ &quot;'&quot;)
 
 getData :: AtomoVal -&gt; String</diff>
      <filename>Atomo/Internals.hs</filename>
    </modified>
    <modified>
      <diff>@@ -593,7 +593,7 @@ aClass :: Parser AtomoVal
 aClass = do reserved &quot;class&quot;
             name &lt;- aSimpleType
             code &lt;- aBlockOf (try aStaticAnnot &lt;|&gt; try aAnnot &lt;|&gt; try aStatic &lt;|&gt; try aMethod)
-            return $ ADefine (Class name) $ AClass (static code) (public code)
+            return $ ADefine (Class name) $ AClass name (static code) (public code)
          &lt;?&gt; &quot;class&quot;
 
 -- Static definition
@@ -633,11 +633,14 @@ aDefAttr = do object &lt;- aVariable
 
 -- Attribute
 aAttribute :: Parser AtomoVal
-aAttribute = do target &lt;- target
-                dot
-                attribute &lt;- identifier
-                return $ ACall (AAttribute target attribute) ANone
+aAttribute = do attr &lt;- aAttribute'
+                return $ ACall attr ANone
              where
+                 aAttribute' = do target &lt;- target
+                                  dot
+                                  attr &lt;- try aAttribute' &lt;|&gt; aVariable
+                                  return $ attribute target attr
+
                  target = try (parens aExpr)
                       &lt;|&gt; try aVariable
                       &lt;|&gt; aNumber
@@ -851,8 +854,12 @@ aList = do contents &lt;- brackets $ commaSep aExpr
            return $ AList contents
 
 -- Parse a tuple (immutable list of values of any type)
+-- A tuple must contain 2 or more values.
 aTuple :: Parser AtomoVal
-aTuple = do contents &lt;- parens $ commaSep aExpr
+aTuple = do contents &lt;- parens $ (do a &lt;- aExpr
+                                     symbol &quot;,&quot;
+                                     bs &lt;- commaSep1 aExpr
+                                     return (a:bs))
             return $ ATuple contents
 
 -- Parse a hash (mutable, named contents of any type)
@@ -905,7 +912,9 @@ aCall = do name &lt;- try aAttribute &lt;|&gt; aVariable &lt;|&gt; try (parens aExpr)
               &lt;|&gt; try (parens aIf)
               &lt;|&gt; try (parens aInfix)
               &lt;|&gt; try (parens aCall)
+              &lt;|&gt; try (parens aExpr)
               &lt;|&gt; try aVariable
+              &lt;|&gt; aLambda
               &lt;|&gt; aAtom
               &lt;|&gt; aList
               &lt;|&gt; aHash</diff>
      <filename>Atomo/Parser.hs</filename>
    </modified>
    <modified>
      <diff>@@ -39,12 +39,12 @@ apply e (ATypeFunc n f) a = do (AInstance _ _ (ABlock fs)) &lt;- getDef e (Instance
                                     Nothing -&gt; throwError $ Unknown $ &quot;Instance does not declare function `&quot; ++ f ++ &quot;'&quot;
                             where
                                 t = getData a
-apply e (AClass _ cs) a = case getAVal cs (Define &quot;new&quot;) of
-                               Nothing -&gt; return object
-                               Just v -&gt; do new &lt;- apply e v object
-                                            apply e new a
-                          where
-                              object = AObject cs
+apply e (AClass n _ cs) a = case getAVal cs (Define &quot;new&quot;) of
+                                 Nothing -&gt; return object
+                                 Just v -&gt; do new &lt;- apply e v object
+                                              apply e new a
+                            where
+                                object = AObject n cs
 apply e (ALambda p c bs) a = case c of
                                   (ALambda p' c' bs') -&gt; return $ ALambda p' c' $ ((p, a) : (bs ++ bs'))
                                   (AValue n as c) -&gt; do env &lt;- bind
@@ -99,7 +99,7 @@ eval e (ADefine n v) = case v of
 eval e (ADefAttr n@(AVariable o) a v) = do ev &lt;- eval e n
                                            val &lt;- eval e v
                                            case ev of
-                                                (AObject object) -&gt; mutateVal e (Define o) (AObject (setAVal object (Define a) val))
+                                                (AObject n object) -&gt; mutateVal e (Define o) (AObject n (setAVal object (Define a) val))
                                                 _ -&gt; throwError $ Unknown $ &quot;Variable `&quot; ++ o ++ &quot;' does not refer to an object.&quot;
 eval e (ACall t@(AAttribute o n) a) = do obj &lt;- eval e o
                                          fun &lt;- eval e t
@@ -126,15 +126,15 @@ eval e (AImport n ts) = do source &lt;- liftIO $ readModule n
                            return ANone
 eval e (AAttribute t n) = do target &lt;- eval e t
                              case target of
-                                  (AObject cs) -&gt; case getAVal cs (Define n) of
-                                                       Just v -&gt; eval e v
-                                                       Nothing -&gt; throwError $ Unknown $ &quot;Object does not have attribute `&quot; ++ n ++ &quot;'.&quot;
+                                  (AObject o cs) -&gt; case getAVal cs (Define n) of
+                                                         Just v -&gt; eval e v
+                                                         Nothing -&gt; throwError $ Unknown $ &quot;Object of class `&quot; ++ prettyType o ++ &quot;' does not have attribute `&quot; ++ n ++ &quot;'.&quot;
                                   (AModule as) -&gt; case getAVal as (Define n) of
                                                        Just v -&gt; eval e v
                                                        Nothing -&gt; throwError $ Unknown $ &quot;Module does not have value `&quot; ++ n ++ &quot;'.&quot;
-                                  (AClass ss _) -&gt; case getAVal ss (Define n) of
-                                                        Just v -&gt; eval e v
-                                                        Nothing -&gt; throwError $ Unknown $ &quot;Class does not have static method `&quot; ++ n ++ &quot;'.&quot;
+                                  (AClass c ss _) -&gt; case getAVal ss (Define n) of
+                                                          Just v -&gt; eval e v
+                                                          Nothing -&gt; throwError $ Unknown $ &quot;Class `&quot; ++ prettyType c ++ &quot;' does not have static method `&quot; ++ n ++ &quot;'.&quot;
                                   _ -&gt; do classes &lt;- getClasses e (getType target)
                                           if null classes
                                              then error (&quot;Could not find class `&quot; ++ prettyType (getType target) ++ &quot;'&quot;)
@@ -143,9 +143,9 @@ eval e (AAttribute t n) = do target &lt;- eval e t
                                           findMethod clss n
                           where
                               findMethod [] n = throwError $ Unknown $ &quot;Class does not have attribute `&quot; ++ n ++ &quot;'.&quot;
-                              findMethod ((AClass _ cs):clss) n = case getAVal cs (Define n) of
-                                                                       Just v -&gt; eval e v
-                                                                       Nothing -&gt; findMethod clss n
+                              findMethod ((AClass _ _ cs):clss) n = case getAVal cs (Define n) of
+                                                                         Just v -&gt; eval e v
+                                                                         Nothing -&gt; findMethod clss n
 eval e (ASpawn c) = do pid &lt;- liftIO $ forkIO (runIOThrows (eval e c) &gt;&gt; return ())
                        chan &lt;- liftIO newChan
                        defineVal e (Process pid) (AProcess pid chan)</diff>
      <filename>Main.hs</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>example.at</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>3c4cf0ff7bca3670946a8a8c3ec42baf7126540d</id>
    </parent>
  </parents>
  <author>
    <name>Alex Suraci</name>
    <email>i.am@toogeneric.com</email>
  </author>
  <url>http://github.com/vito/atomo/commit/7a82af6ad8830e9c9c32e7dad3d896911dbd667e</url>
  <id>7a82af6ad8830e9c9c32e7dad3d896911dbd667e</id>
  <committed-date>2009-05-26T08:40:09-07:00</committed-date>
  <authored-date>2009-05-26T08:40:09-07:00</authored-date>
  <message>* Classes and objects carry around their name (type) and use that for getType on an object.
* Removed example.at.
* Tuples must contain two or more values.
* Allow lambdas and parenthesized expressions in function call arguments.
* Added handling for chaining attributes, like foo.bar.baz</message>
  <tree>0071ab203740d21c7f34ee479079ee2c62e23b93</tree>
  <committer>
    <name>Alex Suraci</name>
    <email>i.am@toogeneric.com</email>
  </committer>
</commit>
