Kaydet (Commit) 85a5fbbd authored tarafından Guido van Rossum's avatar Guido van Rossum

Initial revision

üst c636014c
# Grammar for Python, version 3
# Changes compared to version 2:
# The syntax of Boolean operations is changed to use more
# conventional priorities: or < and < not.
# Changes compared to version 1:
# modules and scripts are unified;
# 'quit' is gone (use ^D);
# empty_stmt is gone, replaced by explicit NEWLINE where appropriate;
# 'import' and 'def' aren't special any more;
# added 'from' NAME option on import clause, and '*' to import all;
# added class definition.
# TO DO:
# replace 'dir' by something more general?
# Start symbols for the grammar:
# single_input is a single interactive statement;
# file_input is a module or sequence of commands read from an input file;
# expr_input is the input for the input() function;
# eval_input is the input for the eval() function.
# NB: compound_stmt in single_input is followed by extra NEWLINE!
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
expr_input: testlist NEWLINE
eval_input: testlist ENDMARKER
funcdef: 'def' NAME parameters ':' suite
parameters: '(' [fplist] ')'
fplist: fpdef (',' fpdef)*
fpdef: NAME | '(' fplist ')'
stmt: simple_stmt | compound_stmt
simple_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | dir_stmt | flow_stmt | import_stmt
expr_stmt: (exprlist '=')* exprlist NEWLINE
# For assignments, additional restrictions enforced by the interpreter
print_stmt: 'print' (test ',')* [test] NEWLINE
del_stmt: 'del' exprlist NEWLINE
dir_stmt: 'dir' [expr] NEWLINE
pass_stmt: 'pass' NEWLINE
flow_stmt: break_stmt | return_stmt | raise_stmt
break_stmt: 'break' NEWLINE
return_stmt: 'return' [testlist] NEWLINE
raise_stmt: 'raise' expr [',' expr] NEWLINE
import_stmt: 'import' NAME (',' NAME)* NEWLINE | 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
try_stmt: 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite]
except_clause: 'except' [expr [',' expr]]
suite: simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'='|'>' '='|'<' '='|'<' '>'|'in'|'not' 'in'|'is'|'is' 'not'
expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%') factor)*
factor: ('+'|'-') factor | atom trailer*
atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' '}' | '`' testlist '`' | NAME | NUMBER | STRING
trailer: '(' [exprlist] ')' | '[' subscript ']' | '.' NAME
subscript: expr | [expr] ':' [expr]
exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
classdef: 'class' NAME parameters ['=' baselist] ':' suite
baselist: atom arguments (',' atom arguments)*
arguments: '(' [testlist] ')'
#define assert(e) { if (!(e)) { printf("Assertion failed\n"); abort(); } }
/* Bitset interface */
#define BYTE char
typedef BYTE *bitset;
bitset newbitset PROTO((int nbits));
void delbitset PROTO((bitset bs));
/* int testbit PROTO((bitset bs, int ibit)); /* Now a macro, see below */
int addbit PROTO((bitset bs, int ibit)); /* Returns 0 if already set */
int samebitset PROTO((bitset bs1, bitset bs2, int nbits));
void mergebitset PROTO((bitset bs1, bitset bs2, int nbits));
#define BITSPERBYTE (8*sizeof(BYTE))
#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE)
#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE)
#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit))
#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE)
#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0)
/* Definitions used by cgen output */
typedef char *string;
#define mknewlongobject(x) newintobject(x)
#define mknewshortobject(x) newintobject((long)x)
#define mknewfloatobject(x) newfloatobject(x)
extern object *mknewcharobject PROTO((int c));
extern int getiobjectarg PROTO((object *args, int nargs, int i, object **p_a));
extern int getilongarg PROTO((object *args, int nargs, int i, long *p_a));
extern int getishortarg PROTO((object *args, int nargs, int i, short *p_a));
extern int getifloatarg PROTO((object *args, int nargs, int i, float *p_a));
extern int getistringarg PROTO((object *args, int nargs, int i, string *p_a));
/* Class object interface */
/*
Classes are really hacked in at the last moment.
It should be possible to use other object types as base classes,
but currently it isn't. We'll see if we can fix that later, sigh...
*/
extern typeobject Classtype, Classmembertype, Classmethodtype;
#define is_classobject(op) ((op)->ob_type == &Classtype)
#define is_classmemberobject(op) ((op)->ob_type == &Classmembertype)
#define is_classmethodobject(op) ((op)->ob_type == &Classmethodtype)
extern object *newclassobject PROTO((node *, object *, object *));
extern object *newclassmemberobject PROTO((object *));
extern object *newclassmethodobject PROTO((object *, object *));
extern object *classmethodgetfunc PROTO((object *));
extern object *classmethodgetself PROTO((object *));
/*
Dictionary object type -- mapping from char * to object.
NB: the key is given as a char *, not as a stringobject.
These functions set errno for errors. Functions dictremove() and
dictinsert() return nonzero for errors, getdictsize() returns -1,
the others NULL. A successful call to dictinsert() calls INCREF()
for the inserted item.
*/
extern typeobject Dicttype;
#define is_dictobject(op) ((op)->ob_type == &Dicttype)
extern object *newdictobject PROTO((void));
extern object *dictlookup PROTO((object *dp, char *key));
extern int dictinsert PROTO((object *dp, char *key, object *item));
extern int dictremove PROTO((object *dp, char *key));
extern int getdictsize PROTO((object *dp));
extern char *getdictkey PROTO((object *dp, int i));
/* New interface with (string)object * instead of char * arguments */
extern object *dict2lookup PROTO((object *dp, object *key));
extern int dict2insert PROTO((object *dp, object *key, object *item));
extern int dict2remove PROTO((object *dp, object *key));
extern object *getdict2key PROTO((object *dp, int i));
/* Error codes passed around between file input, tokenizer, parser and
interpreter. This was necessary so we can turn them into Python
exceptions at a higher level. */
#define E_OK 10 /* No error */
#define E_EOF 11 /* (Unexpected) EOF read */
#define E_INTR 12 /* Interrupted */
#define E_TOKEN 13 /* Bad token */
#define E_SYNTAX 14 /* Syntax error */
#define E_NOMEM 15 /* Ran out of memory */
#define E_DONE 16 /* Parsing complete */
#define E_ERROR 17 /* Execution error */
/* Error handling definitions */
void err_set PROTO((object *));
void err_setval PROTO((object *, object *));
void err_setstr PROTO((object *, char *));
int err_occurred PROTO((void));
void err_get PROTO((object **, object **));
void err_clear PROTO((void));
/* Predefined exceptions (in run.c) */
object *RuntimeError; /* Raised by error() */
object *EOFError; /* Raised by eof_error() */
object *TypeError; /* Rased by type_error() */
object *MemoryError; /* Raised by mem_error() */
object *NameError; /* Raised by name_error() */
object *SystemError; /* Raised by sys_error() */
object *KeyboardInterrupt; /* Raised by intr_error() */
/* File object interface */
extern typeobject Filetype;
#define is_fileobject(op) ((op)->ob_type == &Filetype)
extern object *newfileobject PROTO((char *, char *));
extern object *newopenfileobject PROTO((FILE *, char *, char *));
extern FILE *getfilefile PROTO((object *));
/* Float object interface */
/*
floatobject represents a (double precision) floating point number.
*/
typedef struct {
OB_HEAD
double ob_fval;
} floatobject;
extern typeobject Floattype;
#define is_floatobject(op) ((op)->ob_type == &Floattype)
extern object *newfloatobject PROTO((double));
extern double getfloatvalue PROTO((object *));
/* Macro, trading safety for speed */
#define GETFLOATVALUE(op) ((op)->ob_fval)
/* Function object interface */
extern typeobject Functype;
#define is_funcobject(op) ((op)->ob_type == &Functype)
extern object *newfuncobject PROTO((node *, object *));
extern node *getfuncnode PROTO((object *));
extern object *getfuncglobals PROTO((object *));
#define single_input 256
#define file_input 257
#define expr_input 258
#define eval_input 259
#define funcdef 260
#define parameters 261
#define fplist 262
#define fpdef 263
#define stmt 264
#define simple_stmt 265
#define expr_stmt 266
#define print_stmt 267
#define del_stmt 268
#define dir_stmt 269
#define pass_stmt 270
#define flow_stmt 271
#define break_stmt 272
#define return_stmt 273
#define raise_stmt 274
#define import_stmt 275
#define compound_stmt 276
#define if_stmt 277
#define while_stmt 278
#define for_stmt 279
#define try_stmt 280
#define except_clause 281
#define suite 282
#define test 283
#define and_test 284
#define not_test 285
#define comparison 286
#define comp_op 287
#define expr 288
#define term 289
#define factor 290
#define atom 291
#define trailer 292
#define subscript 293
#define exprlist 294
#define testlist 295
#define classdef 296
#define baselist 297
#define arguments 298
/* Grammar interface */
#include "bitset.h" /* Sigh... */
/* A label of an arc */
typedef struct _label {
int lb_type;
char *lb_str;
} label;
#define EMPTY 0 /* Label number 0 is by definition the empty label */
/* A list of labels */
typedef struct _labellist {
int ll_nlabels;
label *ll_label;
} labellist;
/* An arc from one state to another */
typedef struct _arc {
short a_lbl; /* Label of this arc */
short a_arrow; /* State where this arc goes to */
} arc;
/* A state in a DFA */
typedef struct _state {
int s_narcs;
arc *s_arc; /* Array of arcs */
/* Optional accelerators */
int s_lower; /* Lowest label index */
int s_upper; /* Highest label index */
int *s_accel; /* Accelerator */
int s_accept; /* Nonzero for accepting state */
} state;
/* A DFA */
typedef struct _dfa {
int d_type; /* Non-terminal this represents */
char *d_name; /* For printing */
int d_initial; /* Initial state */
int d_nstates;
state *d_state; /* Array of states */
bitset d_first;
} dfa;
/* A grammar */
typedef struct _grammar {
int g_ndfas;
dfa *g_dfa; /* Array of DFAs */
labellist g_ll;
int g_start; /* Start symbol of the grammar */
int g_accel; /* Set if accelerators present */
} grammar;
/* FUNCTIONS */
grammar *newgrammar PROTO((int start));
dfa *adddfa PROTO((grammar *g, int type, char *name));
int addstate PROTO((dfa *d));
void addarc PROTO((dfa *d, int from, int to, int lbl));
dfa *finddfa PROTO((grammar *g, int type));
char *typename PROTO((grammar *g, int lbl));
int addlabel PROTO((labellist *ll, int type, char *str));
int findlabel PROTO((labellist *ll, int type, char *str));
char *labelrepr PROTO((label *lb));
void translatelabels PROTO((grammar *g));
void addfirstsets PROTO((grammar *g));
void addaccellerators PROTO((grammar *g));
/* Module definition and import interface */
void init_modules PROTO(());
void close_modules PROTO(());
object *new_module PROTO((char *name));
void define_module PROTO((struct _context *ctx, char *name));
object *import_module PROTO((struct _context *ctx, char *name));
/* Integer object interface */
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
intobject represents a (long) integer. This is an immutable object;
an integer cannot change its value after creation.
There are functions to create new integer objects, to test an object
for integer-ness, and to get the integer value. The latter functions
returns -1 and sets errno to EBADF if the object is not an intobject.
None of the functions should be applied to nil objects.
The type intobject is (unfortunately) exposed bere so we can declare
TrueObject and FalseObject below; don't use this.
*/
typedef struct {
OB_HEAD
long ob_ival;
} intobject;
extern typeobject Inttype;
#define is_intobject(op) ((op)->ob_type == &Inttype)
extern object *newintobject PROTO((long));
extern long getintvalue PROTO((object *));
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
False and True are special intobjects used by Boolean expressions.
All values of type Boolean must point to either of these; but in
contexts where integers are required they are integers (valued 0 and 1).
Hope these macros don't conflict with other people's.
Don't forget to apply INCREF() when returning True or False!!!
*/
extern intobject FalseObject, TrueObject; /* Don't use these directly */
#define False ((object *) &FalseObject)
#define True ((object *) &TrueObject)
/* Macro, trading safety for speed */
#define GETINTVALUE(op) ((op)->ob_ival)
/* List object interface */
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
Another generally useful object type is an list of object pointers.
This is a mutable type: the list items can be changed, and items can be
added or removed. Out-of-range indices or non-list objects are ignored.
*** WARNING *** setlistitem does not increment the new item's reference
count, but does decrement the reference count of the item it replaces,
if not nil. It does *decrement* the reference count if it is *not*
inserted in the list. Similarly, getlistitem does not increment the
returned item's reference count.
*/
extern typeobject Listtype;
#define is_listobject(op) ((op)->ob_type == &Listtype)
extern object *newlistobject PROTO((int size));
extern int getlistsize PROTO((object *));
extern object *getlistitem PROTO((object *, int));
extern int setlistitem PROTO((object *, int, object *));
extern int inslistitem PROTO((object *, int, object *));
extern int addlistitem PROTO((object *, object *));
#define MSTART 256
#define RULE 257
#define RHS 258
#define ALT 259
#define ITEM 260
#define ATOM 261
/* Method object interface */
extern typeobject Methodtype;
#define is_methodobject(op) ((op)->ob_type == &Methodtype)
typedef object *(*method) FPROTO((object *, object *));
extern object *newmethodobject PROTO((char *, method, object *));
extern method getmethod PROTO((object *));
extern object *getself PROTO((object *));
/* Module support interface */
struct methodlist {
char *ml_name;
method ml_meth;
};
extern object *findmethod PROTO((struct methodlist *, object *, char *));
extern object *initmodule PROTO((char *, struct methodlist *));
extern int err_badargs PROTO((void));
extern object *err_nomem PROTO((void));
/* Module object interface */
extern typeobject Moduletype;
#define is_moduleobject(op) ((op)->ob_type == &Moduletype)
extern object *newmoduleobject PROTO((char *));
extern object *getmoduledict PROTO((object *));
extern int setmoduledict PROTO((object *, object *));
/* Parse tree node interface */
typedef struct _node {
int n_type;
char *n_str;
int n_nchildren;
struct _node *n_child;
} node;
extern node *newnode PROTO((int type));
extern node *addchild PROTO((node *n, int type, char *str));
/* Node access functions */
#define NCH(n) ((n)->n_nchildren)
#define CHILD(n, i) (&(n)->n_child[i])
#define TYPE(n) ((n)->n_type)
#define STR(n) ((n)->n_str)
/* Assert that the type of a node is what we expect */
#ifndef DEBUG
#define REQ(n, type) { /*pass*/ ; }
#else
#define REQ(n, type) \
{ if (TYPE(n) != (type)) { \
fprintf(stderr, "FATAL: node type %d, required %d\n", \
TYPE(n), type); \
abort(); \
} }
#endif
This diff is collapsed.
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
Additional macros for modules that implement new object types.
You must first include "object.h".
NEWOBJ(type, typeobj) allocates memory for a new object of the given
type; here 'type' must be the C structure type used to represent the
object and 'typeobj' the address of the corresponding type object.
Reference count and type pointer are filled in; the rest of the bytes of
the object are *undefined*! The resulting expression type is 'type *'.
The size of the object is actually determined by the tp_basicsize field
of the type object.
NEWVAROBJ(type, typeobj, n) is similar but allocates a variable-size
object with n extra items. The size is computer as tp_basicsize plus
n * tp_itemsize. This fills in the ob_size field as well.
*/
extern object *newobject PROTO((typeobject *));
extern varobject *newvarobject PROTO((typeobject *, unsigned int));
#define NEWOBJ(type, typeobj) ((type *) newobject(typeobj))
#define NEWVAROBJ(type, typeobj, n) ((type *) newvarobject(typeobj, n))
extern int StopPrint; /* Set when printing is interrupted */
/* Malloc interface */
#include "malloc.h"
extern char *strdup PROTO((char *));
/* Parser-tokenizer link interface */
#if 0
extern int parsetok PROTO((struct tok_state *, grammar *, int start,
node **n_ret));
#endif
extern int parsestring PROTO((char *, grammar *, int start, node **n_ret));
extern int parsefile PROTO((FILE *, grammar *, int start,
char *ps1, char *ps2, node **n_ret));
/* Error handling definitions */
void err_set PROTO((object *));
void err_setval PROTO((object *, object *));
void err_setstr PROTO((object *, char *));
int err_occurred PROTO((void));
void err_get PROTO((object **, object **));
void err_clear PROTO((void));
/* Predefined exceptions (in run.c) */
object *RuntimeError; /* Raised by error() */
object *EOFError; /* Raised by eof_error() */
object *TypeError; /* Rased by type_error() */
object *MemoryError; /* Raised by mem_error() */
object *NameError; /* Raised by name_error() */
object *SystemError; /* Raised by sys_error() */
object *KeyboardInterrupt; /* Raised by intr_error() */
/* String object interface */
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
Type stringobject represents a character string. An extra zero byte is
reserved at the end to ensure it is zero-terminated, but a size is
present so strings with null bytes in them can be represented. This
is an immutable object type.
There are functions to create new string objects, to test
an object for string-ness, and to get the
string value. The latter function returns a null pointer
if the object is not of the proper type.
There is a variant that takes an explicit size as well as a
variant that assumes a zero-terminated string. Note that none of the
functions should be applied to nil objects.
*/
/* NB The type is revealed here only because it is used in dictobject.c */
typedef struct {
OB_VARHEAD
char ob_sval[1];
} stringobject;
extern typeobject Stringtype;
#define is_stringobject(op) ((op)->ob_type == &Stringtype)
extern object *newsizedstringobject PROTO((char *, int));
extern object *newstringobject PROTO((char *));
extern unsigned int getstringsize PROTO((object *));
extern char *getstringvalue PROTO((object *));
extern void joinstring PROTO((object **, object *));
extern int resizestring PROTO((object **, int));
/* Macro, trading safety for speed */
#define GETSTRINGVALUE(op) ((op)->ob_sval)
/* System module interface */
object *sysget PROTO((char *));
int sysset PROTO((char *, object *));
FILE *sysgetfile PROTO((char *, FILE *));
void initsys PROTO((int, char **));
/* Token types */
#define ENDMARKER 0
#define NAME 1
#define NUMBER 2
#define STRING 3
#define NEWLINE 4
#define INDENT 5
#define DEDENT 6
#define LPAR 7
#define RPAR 8
#define LSQB 9
#define RSQB 10
#define COLON 11
#define COMMA 12
#define SEMI 13
#define PLUS 14
#define MINUS 15
#define STAR 16
#define SLASH 17
#define VBAR 18
#define AMPER 19
#define LESS 20
#define GREATER 21
#define EQUAL 22
#define DOT 23
#define PERCENT 24
#define BACKQUOTE 25
#define LBRACE 26
#define RBRACE 27
#define OP 28
#define ERRORTOKEN 29
#define N_TOKENS 30
/* Special definitions for cooperation with parser */
#define NT_OFFSET 256
#define ISTERMINAL(x) ((x) < NT_OFFSET)
#define ISNONTERMINAL(x) ((x) >= NT_OFFSET)
#define ISEOF(x) ((x) == ENDMARKER)
extern char *tok_name[]; /* Token names */
extern int tok_1char PROTO((int));
/* Tuple object interface */
/*
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
Another generally useful object type is an tuple of object pointers.
This is a mutable type: the tuple items can be changed (but not their
number). Out-of-range indices or non-tuple objects are ignored.
*** WARNING *** settupleitem does not increment the new item's reference
count, but does decrement the reference count of the item it replaces,
if not nil. It does *decrement* the reference count if it is *not*
inserted in the tuple. Similarly, gettupleitem does not increment the
returned item's reference count.
*/
extern typeobject Tupletype;
#define is_tupleobject(op) ((op)->ob_type == &Tupletype)
extern object *newtupleobject PROTO((int size));
extern int gettuplesize PROTO((object *));
extern object *gettupleitem PROTO((object *, int));
extern int settupleitem PROTO((object *, int, object *));
This diff is collapsed.
/* Functions used by cgen output */
#include <stdio.h>
#include "PROTO.h"
#include "object.h"
#include "intobject.h"
#include "floatobject.h"
#include "stringobject.h"
#include "tupleobject.h"
#include "listobject.h"
#include "methodobject.h"
#include "moduleobject.h"
#include "modsupport.h"
#include "import.h"
#include "cgensupport.h"
#include "errors.h"
/* Functions to construct return values */
object *
mknewcharobject(c)
int c;
{
char ch[1];
ch[0] = c;
return newsizedstringobject(ch, 1);
}
/* Functions to extract arguments.
These needs to know the total number of arguments supplied,
since the argument list is a tuple only of there is more than
one argument. */
int
getiobjectarg(args, nargs, i, p_arg)
register object *args;
int nargs, i;
object **p_arg;
{
if (nargs != 1) {
if (args == NULL || !is_tupleobject(args) ||
nargs != gettuplesize(args) ||
i < 0 || i >= nargs) {
return err_badarg();
}
else {
args = gettupleitem(args, i);
}
}
if (args == NULL) {
return err_badarg();
}
*p_arg = args;
return 1;
}
int
getilongarg(args, nargs, i, p_arg)
register object *args;
int nargs, i;
long *p_arg;
{
if (nargs != 1) {
if (args == NULL || !is_tupleobject(args) ||
nargs != gettuplesize(args) ||
i < 0 || i >= nargs) {
return err_badarg();
}
args = gettupleitem(args, i);
}
if (args == NULL || !is_intobject(args)) {
return err_badarg();
}
*p_arg = getintvalue(args);
return 1;
}
int
getishortarg(args, nargs, i, p_arg)
register object *args;
int nargs, i;
short *p_arg;
{
long x;
if (!getilongarg(args, nargs, i, &x))
return 0;
*p_arg = x;
return 1;
}
static int
extractdouble(v, p_arg)
register object *v;
double *p_arg;
{
if (v == NULL) {
/* Fall through to error return at end of function */
}
else if (is_floatobject(v)) {
*p_arg = GETFLOATVALUE((floatobject *)v);
return 1;
}
else if (is_intobject(v)) {
*p_arg = GETINTVALUE((intobject *)v);
return 1;
}
return err_badarg();
}
static int
extractfloat(v, p_arg)
register object *v;
float *p_arg;
{
if (v == NULL) {
/* Fall through to error return at end of function */
}
else if (is_floatobject(v)) {
*p_arg = GETFLOATVALUE((floatobject *)v);
return 1;
}
else if (is_intobject(v)) {
*p_arg = GETINTVALUE((intobject *)v);
return 1;
}
return err_badarg();
}
int
getifloatarg(args, nargs, i, p_arg)
register object *args;
int nargs, i;
float *p_arg;
{
object *v;
float x;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (!extractfloat(v, &x))
return 0;
*p_arg = x;
return 1;
}
int
getistringarg(args, nargs, i, p_arg)
object *args;
int nargs, i;
string *p_arg;
{
object *v;
if (!getiobjectarg(args, nargs, i, &v))
return NULL;
if (!is_stringobject(v)) {
return err_badarg();
}
*p_arg = getstringvalue(v);
return 1;
}
int
getichararg(args, nargs, i, p_arg)
object *args;
int nargs, i;
char *p_arg;
{
string x;
if (!getistringarg(args, nargs, i, &x))
return 0;
if (x[0] == '\0' || x[1] != '\0') {
/* Not exactly one char */
return err_badarg();
}
*p_arg = x[0];
return 1;
}
int
getilongarraysize(args, nargs, i, p_arg)
object *args;
int nargs, i;
long *p_arg;
{
object *v;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (is_tupleobject(v)) {
*p_arg = gettuplesize(v);
return 1;
}
if (is_listobject(v)) {
*p_arg = getlistsize(v);
return 1;
}
return err_badarg();
}
int
getishortarraysize(args, nargs, i, p_arg)
object *args;
int nargs, i;
short *p_arg;
{
long x;
if (!getilongarraysize(args, nargs, i, &x))
return 0;
*p_arg = x;
return 1;
}
/* XXX The following four are too similar. Should share more code. */
int
getilongarray(args, nargs, i, n, p_arg)
object *args;
int nargs, i;
int n;
long *p_arg; /* [n] */
{
object *v, *w;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (is_tupleobject(v)) {
if (gettuplesize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = gettupleitem(v, i);
if (!is_intobject(w)) {
return err_badarg();
}
p_arg[i] = getintvalue(w);
}
return 1;
}
else if (is_listobject(v)) {
if (getlistsize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = getlistitem(v, i);
if (!is_intobject(w)) {
return err_badarg();
}
p_arg[i] = getintvalue(w);
}
return 1;
}
else {
return err_badarg();
}
}
int
getishortarray(args, nargs, i, n, p_arg)
object *args;
int nargs, i;
int n;
short *p_arg; /* [n] */
{
object *v, *w;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (is_tupleobject(v)) {
if (gettuplesize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = gettupleitem(v, i);
if (!is_intobject(w)) {
return err_badarg();
}
p_arg[i] = getintvalue(w);
}
return 1;
}
else if (is_listobject(v)) {
if (getlistsize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = getlistitem(v, i);
if (!is_intobject(w)) {
return err_badarg();
}
p_arg[i] = getintvalue(w);
}
return 1;
}
else {
return err_badarg();
}
}
int
getidoublearray(args, nargs, i, n, p_arg)
object *args;
int nargs, i;
int n;
double *p_arg; /* [n] */
{
object *v, *w;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (is_tupleobject(v)) {
if (gettuplesize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = gettupleitem(v, i);
if (!extractdouble(w, &p_arg[i]))
return 0;
}
return 1;
}
else if (is_listobject(v)) {
if (getlistsize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = getlistitem(v, i);
if (!extractdouble(w, &p_arg[i]))
return 0;
}
return 1;
}
else {
return err_badarg();
}
}
int
getifloatarray(args, nargs, i, n, p_arg)
object *args;
int nargs, i;
int n;
float *p_arg; /* [n] */
{
object *v, *w;
if (!getiobjectarg(args, nargs, i, &v))
return 0;
if (is_tupleobject(v)) {
if (gettuplesize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = gettupleitem(v, i);
if (!extractfloat(w, &p_arg[i]))
return 0;
}
return 1;
}
else if (is_listobject(v)) {
if (getlistsize(v) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
w = getlistitem(v, i);
if (!extractfloat(w, &p_arg[i]))
return 0;
}
return 1;
}
else {
return err_badarg();
}
}
/* Definitions used by cgen output */
typedef char *string;
#define mknewlongobject(x) newintobject(x)
#define mknewshortobject(x) newintobject((long)x)
#define mknewfloatobject(x) newfloatobject(x)
extern object *mknewcharobject PROTO((int c));
extern int getiobjectarg PROTO((object *args, int nargs, int i, object **p_a));
extern int getilongarg PROTO((object *args, int nargs, int i, long *p_a));
extern int getishortarg PROTO((object *args, int nargs, int i, short *p_a));
extern int getifloatarg PROTO((object *args, int nargs, int i, float *p_a));
extern int getistringarg PROTO((object *args, int nargs, int i, string *p_a));
This diff is collapsed.
/* Math module -- standard C math library functions, pi and e */
#include <stdio.h>
#include <math.h>
#include "PROTO.h"
#include "object.h"
#include "intobject.h"
#include "tupleobject.h"
#include "floatobject.h"
#include "dictobject.h"
#include "methodobject.h"
#include "moduleobject.h"
#include "objimpl.h"
#include "import.h"
#include "modsupport.h"
static int
getdoublearg(args, px)
register object *args;
double *px;
{
if (args == NULL)
return err_badarg();
if (is_floatobject(args)) {
*px = getfloatvalue(args);
return 1;
}
if (is_intobject(args)) {
*px = getintvalue(args);
return 1;
}
return err_badarg();
}
static int
get2doublearg(args, px, py)
register object *args;
double *px, *py;
{
if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2)
return err_badarg();
return getdoublearg(gettupleitem(args, 0), px) &&
getdoublearg(gettupleitem(args, 1), py);
}
static object *
math_1(args, func)
object *args;
double (*func) FPROTO((double));
{
double x;
if (!getdoublearg(args, &x))
return NULL;
errno = 0;
x = (*func)(x);
if (errno != 0)
return NULL;
else
return newfloatobject(x);
}
static object *
math_2(args, func)
object *args;
double (*func) FPROTO((double, double));
{
double x, y;
if (!get2doublearg(args, &x, &y))
return NULL;
errno = 0;
x = (*func)(x, y);
if (errno != 0)
return NULL;
else
return newfloatobject(x);
}
#define FUNC1(stubname, func) \
static object * stubname(self, args) object *self, *args; { \
return math_1(args, func); \
}
#define FUNC2(stubname, func) \
static object * stubname(self, args) object *self, *args; { \
return math_2(args, func); \
}
FUNC1(math_acos, acos)
FUNC1(math_asin, asin)
FUNC1(math_atan, atan)
FUNC2(math_atan2, atan2)
FUNC1(math_ceil, ceil)
FUNC1(math_cos, cos)
FUNC1(math_cosh, cosh)
FUNC1(math_exp, exp)
FUNC1(math_fabs, fabs)
FUNC1(math_floor, floor)
#if 0
/* XXX This one is not in the Amoeba library yet, so what the heck... */
FUNC2(math_fmod, fmod)
#endif
FUNC1(math_log, log)
FUNC1(math_log10, log10)
FUNC2(math_pow, pow)
FUNC1(math_sin, sin)
FUNC1(math_sinh, sinh)
FUNC1(math_sqrt, sqrt)
FUNC1(math_tan, tan)
FUNC1(math_tanh, tanh)
#if 0
/* What about these? */
double frexp(double x, int *i);
double ldexp(double x, int n);
double modf(double x, double *i);
#endif
static struct methodlist math_methods[] = {
{"acos", math_acos},
{"asin", math_asin},
{"atan", math_atan},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"cos", math_cos},
{"cosh", math_cosh},
{"exp", math_exp},
{"fabs", math_fabs},
{"floor", math_floor},
#if 0
{"fmod", math_fmod},
{"frexp", math_freqp},
{"ldexp", math_ldexp},
#endif
{"log", math_log},
{"log10", math_log10},
#if 0
{"modf", math_modf},
#endif
{"pow", math_pow},
{"sin", math_sin},
{"sinh", math_sinh},
{"sqrt", math_sqrt},
{"tan", math_tan},
{"tanh", math_tanh},
{NULL, NULL} /* sentinel */
};
void
initmath()
{
object *m, *d, *v;
struct methodlist *ml;
if ((m = new_module("math")) == NULL)
fatal("can't create math module");
d = getmoduledict(m);
for (ml = math_methods; ml->ml_name != NULL; ml++) {
v = newmethodobject(ml->ml_name, ml->ml_meth, (object *)NULL);
if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
fatal("can't initialize math module");
}
DECREF(v);
}
dictinsert(d, "pi", newfloatobject(atan(1.0) * 4.0));
dictinsert(d, "e", newfloatobject(exp(1.0)));
DECREF(m);
}
/* POSIX module implementation */
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#ifdef SYSV
#include <dirent.h>
#define direct dirent
#else
#include <sys/dir.h>
#endif
#include "PROTO.h"
#include "object.h"
#include "intobject.h"
#include "stringobject.h"
#include "tupleobject.h"
#include "listobject.h"
#include "dictobject.h"
#include "methodobject.h"
#include "moduleobject.h"
#include "objimpl.h"
#include "import.h"
#include "sigtype.h"
#include "modsupport.h"
#include "errors.h"
extern char *strerror();
#ifdef AMOEBA
#define NO_LSTAT
#endif
/* Return a dictionary corresponding to the POSIX environment table */
extern char **environ;
static object *
convertenviron()
{
object *d;
char **e;
d = newdictobject();
if (d == NULL)
return NULL;
if (environ == NULL)
return d;
/* XXX This part ignores errors */
for (e = environ; *e != NULL; e++) {
object *v;
char *p = strchr(*e, '=');
if (p == NULL)
continue;
v = newstringobject(p+1);
if (v == NULL)
continue;
*p = '\0';
(void) dictinsert(d, *e, v);
*p = '=';
DECREF(v);
}
return d;
}
static object *PosixError; /* Exception posix.error */
/* Set a POSIX-specific error from errno, and return NULL */
static object *
posix_error()
{
object *v = newtupleobject(2);
if (v != NULL) {
settupleitem(v, 0, newintobject((long)errno));
settupleitem(v, 1, newstringobject(strerror(errno)));
}
err_setval(PosixError, v);
if (v != NULL)
DECREF(v);
return NULL;
}
/* POSIX generic methods */
static object *
posix_1str(args, func)
object *args;
int (*func) FPROTO((const char *));
{
object *path1;
if (!getstrarg(args, &path1))
return NULL;
if ((*func)(getstringvalue(path1)) < 0)
return posix_error();
INCREF(None);
return None;
}
static object *
posix_2str(args, func)
object *args;
int (*func) FPROTO((const char *, const char *));
{
object *path1, *path2;
if (!getstrstrarg(args, &path1, &path2))
return NULL;
if ((*func)(getstringvalue(path1), getstringvalue(path2)) < 0)
return posix_error();
INCREF(None);
return None;
}
static object *
posix_strint(args, func)
object *args;
int (*func) FPROTO((const char *, int));
{
object *path1;
int i;
if (!getstrintarg(args, &path1, &i))
return NULL;
if ((*func)(getstringvalue(path1), i) < 0)
return posix_error();
INCREF(None);
return None;
}
static object *
posix_do_stat(self, args, statfunc)
object *self;
object *args;
int (*statfunc) FPROTO((const char *, struct stat *));
{
struct stat st;
object *path;
object *v;
if (!getstrarg(args, &path))
return NULL;
if ((*statfunc)(getstringvalue(path), &st) != 0)
return posix_error();
v = newtupleobject(10);
if (v == NULL)
return NULL;
errno = 0;
#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
SET(0, st_mode);
SET(1, st_ino);
SET(2, st_dev);
SET(3, st_nlink);
SET(4, st_uid);
SET(5, st_gid);
SET(6, st_size);
SET(7, st_atime);
SET(8, st_mtime);
SET(9, st_ctime);
#undef SET
if (errno != 0) {
DECREF(v);
return err_nomem();
}
return v;
}
/* POSIX methods */
static object *
posix_chdir(self, args)
object *self;
object *args;
{
extern int chdir PROTO((const char *));
return posix_1str(args, chdir);
}
static object *
posix_chmod(self, args)
object *self;
object *args;
{
extern int chmod PROTO((const char *, mode_t));
return posix_strint(args, chmod);
}
static object *
posix_getcwd(self, args)
object *self;
object *args;
{
char buf[1026];
extern char *getcwd PROTO((char *, int));
if (!getnoarg(args))
return NULL;
if (getcwd(buf, sizeof buf) == NULL)
return posix_error();
return newstringobject(buf);
}
static object *
posix_link(self, args)
object *self;
object *args;
{
extern int link PROTO((const char *, const char *));
return posix_2str(args, link);
}
static object *
posix_listdir(self, args)
object *self;
object *args;
{
object *name, *d, *v;
DIR *dirp;
struct direct *ep;
if (!getstrarg(args, &name))
return NULL;
if ((dirp = opendir(getstringvalue(name))) == NULL)
return posix_error();
if ((d = newlistobject(0)) == NULL) {
closedir(dirp);
return NULL;
}
while ((ep = readdir(dirp)) != NULL) {
v = newstringobject(ep->d_name);
if (v == NULL) {
DECREF(d);
d = NULL;
break;
}
if (addlistitem(d, v) != 0) {
DECREF(v);
DECREF(d);
d = NULL;
break;
}
DECREF(v);
}
closedir(dirp);
return d;
}
static object *
posix_mkdir(self, args)
object *self;
object *args;
{
extern int mkdir PROTO((const char *, mode_t));
return posix_strint(args, mkdir);
}
static object *
posix_rename(self, args)
object *self;
object *args;
{
extern int rename PROTO((const char *, const char *));
return posix_2str(args, rename);
}
static object *
posix_rmdir(self, args)
object *self;
object *args;
{
extern int rmdir PROTO((const char *));
return posix_1str(args, rmdir);
}
static object *
posix_stat(self, args)
object *self;
object *args;
{
extern int stat PROTO((const char *, struct stat *));
return posix_do_stat(self, args, stat);
}
static object *
posix_system(self, args)
object *self;
object *args;
{
object *command;
int sts;
if (!getstrarg(args, &command))
return NULL;
sts = system(getstringvalue(command));
return newintobject((long)sts);
}
static object *
posix_umask(self, args)
object *self;
object *args;
{
int i;
if (!getintarg(args, &i))
return NULL;
i = umask(i);
if (i < 0)
return posix_error();
return newintobject((long)i);
}
static object *
posix_unlink(self, args)
object *self;
object *args;
{
extern int unlink PROTO((const char *));
return posix_1str(args, unlink);
}
static object *
posix_utimes(self, args)
object *self;
object *args;
{
object *path;
struct timeval tv[2];
if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
err_badarg();
return NULL;
}
if (!getstrarg(gettupleitem(args, 0), &path) ||
!getlonglongargs(gettupleitem(args, 1),
&tv[0].tv_sec, &tv[1].tv_sec))
return NULL;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(getstringvalue(path), tv) < 0)
return posix_error();
INCREF(None);
return None;
}
#ifdef NO_GETCWD
/* Quick hack to get posix.getcwd() working for pure BSD 4.3 */
/* XXX This assumes MAXPATHLEN = 1024 !!! */
static char *
getcwd(buf, size)
char *buf;
int size;
{
extern char *getwd PROTO((char *));
register char *ret = getwd(buf);
if (ret == NULL)
errno = EACCES; /* Most likely error */
return ret;
}
#endif /* NO_GETCWD */
#ifndef NO_LSTAT
static object *
posix_lstat(self, args)
object *self;
object *args;
{
extern int lstat PROTO((const char *, struct stat *));
return posix_do_stat(self, args, lstat);
}
static object *
posix_readlink(self, args)
object *self;
object *args;
{
char buf[1024]; /* XXX Should use MAXPATHLEN */
object *path;
int n;
if (!getstrarg(args, &path))
return NULL;
n = readlink(getstringvalue(path), buf, sizeof buf);
if (n < 0)
return posix_error();
return newsizedstringobject(buf, n);
}
static object *
posix_symlink(self, args)
object *self;
object *args;
{
extern int symlink PROTO((const char *, const char *));
return posix_2str(args, symlink);
}
#endif /* NO_LSTAT */
static struct methodlist posix_methods[] = {
{"chdir", posix_chdir},
{"chmod", posix_chmod},
{"getcwd", posix_getcwd},
{"link", posix_link},
{"listdir", posix_listdir},
{"mkdir", posix_mkdir},
{"rename", posix_rename},
{"rmdir", posix_rmdir},
{"stat", posix_stat},
{"system", posix_system},
{"umask", posix_umask},
{"unlink", posix_unlink},
{"utimes", posix_utimes},
#ifndef NO_LSTAT
{"lstat", posix_lstat},
{"readlink", posix_readlink},
{"symlink", posix_symlink},
#endif
{NULL, NULL} /* Sentinel */
};
void
initposix()
{
object *m, *d, *v;
m = initmodule("posix", posix_methods);
d = getmoduledict(m);
/* Initialize posix.environ dictionary */
v = convertenviron();
if (v == NULL || dictinsert(d, "environ", v) != 0)
fatal("can't define posix.environ");
DECREF(v);
/* Initialize posix.error exception */
PosixError = newstringobject("posix.error");
if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
fatal("can't define posix.error");
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Type object implementation */
#include <stdio.h>
#include "PROTO.h"
#include "object.h"
#include "stringobject.h"
#include "objimpl.h"
/* Type object implementation */
static void
typeprint(v, fp, flags)
typeobject *v;
FILE *fp;
int flags;
{
fprintf(fp, "<type '%s'>", v->tp_name);
}
static object *
typerepr(v)
typeobject *v;
{
char buf[100];
sprintf(buf, "<type '%.80s'>", v->tp_name);
return newstringobject(buf);
}
typedef struct {
OB_HEAD
long ob_ival;
} intobject;
typeobject Typetype = {
OB_HEAD_INIT(&Typetype)
0, /* Number of items for varobject */
"type", /* Name of this type */
sizeof(typeobject), /* Basic object size */
0, /* Item size for varobject */
0, /*tp_dealloc*/
typeprint, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
typerepr, /*tp_repr*/
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment