[cig-commits] r6523 - cs/babel/trunk/spike/Spike/Compiler

leif at geodynamics.org leif at geodynamics.org
Sat Apr 7 20:32:09 PDT 2007


Author: leif
Date: 2007-04-07 20:32:09 -0700 (Sat, 07 Apr 2007)
New Revision: 6523

Modified:
   cs/babel/trunk/spike/Spike/Compiler/Nodes.py
   cs/babel/trunk/spike/Spike/Compiler/gram.y
   cs/babel/trunk/spike/Spike/Compiler/parser.pyx
   cs/babel/trunk/spike/Spike/Compiler/scan.l
Log:
Allow a mixture of typed and untyped arguments in Spike argument lists
(as allowed by Pyrex, but not allowed by C or C++):

    int abc(int x, y, z, float f) { ... }

Here, 'y' and 'z' are untyped (currently implemented as PyObject * --
see below).  This simplifies the grammar a little, but introduces a new
(although apparently harmless) shift/reduce conflict.

More importantly, I've implemented an idea that I had after midnight one
night back in October, when Rebecca and the dogs (Spike included) were
out of town, and I had a lot of time and energy to brainstorm :-)

Consider the following code:

    sum(a, b, c)
    {
        auto s;
        s = a;
        s = s + b;
        s = s + c;
        return s;
    }

This is valid C code.  It is also valid B code.  Note the complete
absence of type information.  Looks almost Pythonic, doesn't it?  (See
also the log message for r5996.)

In C and in B, all the variables in this code have type 'int'.  (In B,
'int' is the only type!)  In C, this is, of course, an example of the
infamous "implicit int" rule.  But it also subtly demonstrates why type
names are keywords in C:  so that types could be optional (perhaps
important during the B -> C transition in the 70's:  the introduction of
types didn't require any changes to the B code base).

The above code is also valid Spike code.  In Spike, all the variables
are *typeless*.  They have no declared type, therefore their type is
"unknown".  Currently, typeless variables are implemented using duck
typing at runtime -- i.e., they are implemented as "PyObject *". 
However, this is merely an implementation detail.  In the future, given
enough context, the compiler might instantiate the above code at compile
time as a template.

I don't especially like C's 'auto', 'static', and 'extern' keywords, for
reasons I won't go into here.  In Spike, these keywords are deprecated. 
The preferred way to declare a typeless variable is to use the new
'decl' keyword:

    sum(a, b, c)
    {
        decl s;
        /* ... */
    }

Unlike 'auto', 'decl' can be used anywhere a declaration is allowed. 
Internally, it is a no-op:  unlike 'auto', 'static', and 'extern', the
'decl' keyword has no meaning:

    decl int x;    /* same as "int x;" */

The 'decl' keyword is merely a syntactic placeholder.

I'm not certain whether I want to keep the 'obj' built-in type... 'decl'
makes 'obj' redundant and misleading.

Further, these changes make the "Buffy" sub-project redundant, as every
valid Buffy program is now a valid Spike program.


Modified: cs/babel/trunk/spike/Spike/Compiler/Nodes.py
===================================================================
--- cs/babel/trunk/spike/Spike/Compiler/Nodes.py	2007-04-08 02:05:47 UTC (rev 6522)
+++ cs/babel/trunk/spike/Spike/Compiler/Nodes.py	2007-04-08 03:32:09 UTC (rev 6523)
@@ -1700,7 +1700,7 @@
     def analyse(self):
         # defaults
         storage = 'auto' # ?
-        name = 'int'
+        name = 'obj' # typeless (currently "implicit obj")
         signed = 1
         longness = 0
         # counts
@@ -1730,6 +1730,10 @@
             elif specifier in ['typedef', 'extern', 'static', 'auto', 'register']:
                 storage = specifier
                 storage_specs += 1
+            elif specifier == 'decl':
+                pass # no-op
+            else:
+                raise ValueError("unknown specifier '%s'" % specifier)
         # error check
         errors = 0
         if signed_specs and unsigned_specs:

Modified: cs/babel/trunk/spike/Spike/Compiler/gram.y
===================================================================
--- cs/babel/trunk/spike/Spike/Compiler/gram.y	2007-04-08 02:05:47 UTC (rev 6522)
+++ cs/babel/trunk/spike/Spike/Compiler/gram.y	2007-04-08 03:32:09 UTC (rev 6523)
@@ -25,7 +25,7 @@
 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
 %token STRUCT UNION ENUM CLASS
 %token ELIPSIS RANGE
-%token OBJ
+%token OBJ, DECL
 
 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
 
@@ -214,6 +214,7 @@
 	| VOLATILE
 	| VOID
 	| OBJ
+	| DECL
 	| struct_or_union_specifier
 	| enum_specifier
 	| class_specifier
@@ -278,8 +279,7 @@
 	| declarator2 '[' ']'    { CHECK($$ = array_declarator($1, Py_None)); }
 	| declarator2 '[' constant_expr ']'    { CHECK($$ = array_declarator($1, $3)); }
 	| declarator2 '(' ')'    { CHECK($$ = function_declarator($1, empty_list())); }
-	| declarator2 '(' parameter_type_list ')'          { CHECK($$ = function_declarator($1, $3)); }
-	| declarator2 '(' parameter_identifier_list ')'    { CHECK($$ = function_declarator($1, $3)); }
+	| declarator2 '(' parameter_list ')'          { CHECK($$ = function_declarator($1, $3)); }
 	;
 
 pointer
@@ -294,29 +294,17 @@
 	| type_specifier_list type_specifier    { CHECK($$ = type_specifier_list($1, $2)); }
 	;
 
-parameter_identifier_list
-	: identifier_list
-	| identifier_list ',' ELIPSIS
-	;
-
-identifier_list
-	: identifier
-	| identifier_list ',' identifier
-	;
-
-parameter_type_list
-	: parameter_list
-	| parameter_list ',' ELIPSIS
-	;
-
 parameter_list
 	: parameter_declaration                       { CHECK($$ = parameter_list(Py_None, $1)); }
 	| parameter_list ',' parameter_declaration    { CHECK($$ = parameter_list($1, $3)); }
+	| ELIPSIS
 	;
 
 parameter_declaration
 	: type_specifier_list declarator             { CHECK($$ = pair($1, $2)); }
-	| type_name
+	| type_specifier_list abstract_declarator    { CHECK($$ = pair($1, $2)); }
+	| type_specifier_list                        { CHECK($$ = pair($1, empty_declarator())); }
+	| declarator                                 { CHECK($$ = pair(Py_None, $1)); }
 	;
 
 type_name
@@ -337,9 +325,9 @@
 	| abstract_declarator2 '[' ']'    { CHECK($$ = array_declarator($1, Py_None)); }
 	| abstract_declarator2 '[' constant_expr ']'    { CHECK($$ = array_declarator($1, $3)); }
 	| '(' ')'                         { CHECK($$ = function_declarator(empty_declarator(), empty_list())); }
-	| '(' parameter_type_list ')'     { CHECK($$ = function_declarator(empty_declarator(), $2)); }
+	| '(' parameter_list ')'          { CHECK($$ = function_declarator(empty_declarator(), $2)); }
 	| abstract_declarator2 '(' ')'    { CHECK($$ = function_declarator($1, empty_list())); }
-	| abstract_declarator2 '(' parameter_type_list ')'    { CHECK($$ = function_declarator($1, $3)); }
+	| abstract_declarator2 '(' parameter_list ')'    { CHECK($$ = function_declarator($1, $3)); }
 	;
 
 initializer

Modified: cs/babel/trunk/spike/Spike/Compiler/parser.pyx
===================================================================
--- cs/babel/trunk/spike/Spike/Compiler/parser.pyx	2007-04-08 02:05:47 UTC (rev 6522)
+++ cs/babel/trunk/spike/Spike/Compiler/parser.pyx	2007-04-08 03:32:09 UTC (rev 6523)
@@ -272,6 +272,10 @@
     if parameter_list is None:
         parameter_list = []
     type_specifier_list, declarator = parameter_declaration
+    if type_specifier_list is None:
+        # typeless parameter (currently implemented as "implicit obj")
+        type_specifier_list = DeclSpecs()
+        type_specifier_list.add(('obj', declarator.pos))
     base_type = type_specifier_list.analyse_type()
     node = CArgDeclNode(declarator.pos,
         base_type = base_type,
@@ -348,6 +352,10 @@
 cdef public object function_definition(object declaration_specifiers,
                                        object declarator,
                                        object function_body):
+    if declaration_specifiers is None:
+        # typeless return value (currently implemented as "implicit obj")
+        declaration_specifiers = DeclSpecs()
+        declaration_specifiers.add(('obj', declarator.pos))
     return declaration_specifiers.function_definition(declarator, function_body)
 
 

Modified: cs/babel/trunk/spike/Spike/Compiler/scan.l
===================================================================
--- cs/babel/trunk/spike/Spike/Compiler/scan.l	2007-04-08 02:05:47 UTC (rev 6522)
+++ cs/babel/trunk/spike/Spike/Compiler/scan.l	2007-04-08 03:32:09 UTC (rev 6523)
@@ -36,6 +36,7 @@
 "class"			{ TOKEN(CLASS); }
 "const"			{ TOKEN(CONST); }
 "continue"		{ TOKEN(CONTINUE); }
+"decl"			{ TOKEN(DECL); }
 "default"		{ TOKEN(DEFAULT); }
 "do"			{ TOKEN(DO); }
 "double"		{ TOKEN(DOUBLE); }



More information about the cig-commits mailing list