/* * Tempory definition of predefined and built-in IO procedures. These are * coded in C according to the protocol described in 451 Week 4 Lecture Notes. * By convention, names of built-ins are same as names known to user, with a * '_' suffix added to avoid name conflicts. * * This single module contains defs for procs in two standard Mod-2 modules: * InOut and RealInOut. It's tempoary in that when the complete system is * done, we'll organize io modules as follows: * * * InOut.def, RealInOut.def, Terminal.def (maybe) and FileSystem.def * will be (pre)loaded. * * InOut.c, RealIntOut.c, Terminal.c, FileSystem.c will be precompiled * as the companion implementation modules * * This scheme will preclude the need for the manual preloading of the symtab * with functions defined in these modules. */ #include #include "std-macros.h" #include "parse-tree.h" #include "sym.h" #include "type-preds.h" #include "type.h" #include "sym-aux.h" #include "interp.h" #include "built-ins.h" #include "io.h" #include "str.h" ValueStruct WriteInt(/*x,n*/) { int x,n; /* Locals for parameters */ char fmt[20]; /* Printf formating string */ /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackInt(&x); GetStackCard(&n); /* * Convert n to printf-style formatting string. */ sprintf(fmt, "%c%d%s", '%', n, "d\0"); /* * Implement WriteInt using printf. */ printf(fmt, x); fflush(stdout); } ValueStruct WriteReal(/*x,n*/) { double/*float*/ x; /* Parmoids */ int n; char fmt[20]; /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackReal(&x); GetStackCard(&n); /* * Convert n to printf-style formatting string. */ sprintf(fmt, "%c%d%s", '%', n, "g\0"); /* * Implement WriteInt using printf. */ printf(fmt, x); } ValueStruct WriteLongReal(/*x,n*/) { double x; /* Parmoids */ int n; char fmt[20]; /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackLongReal(&x); GetStackCard(&n); /* * Convert n to printf-style formatting string. */ sprintf(fmt, "%c%d%s", '%', n, "g\0"); /* * Implement WriteInt using printf. */ printf(fmt, x); } ValueStruct WriteChar(/*c*/) { char c; /* Parmoid */ /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackChar(&c); /* * Implement using printf. */ printf("%c", c); fflush(stdout); } ValueStruct WriteBool(/*b*/) { bool b; /* Parmoid */ /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackBool(&b); /* * Implement using printf. */ printf(b ? "true" : "false"); fflush(stdout); } ValueStruct WriteString(/*s*/) { char *s; /* Parmoids */ char fmt[20]; /* * Extract actual parameters from the interpreter stack. */ InitGetTos(); GetStackPointer(&s); /* * Implement using printf. */ printf("%s", s); } ValueStruct WriteLn() { printf("\n"); } /* * Make C's printf available as is in Mod-2. */ ValueStruct printf_(t) nodep t; { ValueStruct v; char *format; FormatSpec *spec; int i; char c; char *s; double r; void *p; /* * Get first actual; complain if it's not a string. */ v = interpExpr(t->components.exprlist.expr); if (not isString(v->type)) { error("First argument of printf must be a string\n"); return; } format = (char *)ConstStringConvert(v->val.StringVal); /* * Eval the rest of the actuals and push them on the stack. */ NonAnsiCBind(t->components.exprlist.next); /* * Get and print per format char. */ while (spec = GetNextFormatSpec()) { switch (spec->fchar) { case 'd': case 'i': case 'o': case 'x': case 'X': GetStackInt(&i); printf(spec->all, i); break; case 'c': GetStackChar(&c); printf(spec->all, c); break; case 's': GetStackString(&s); printf(spec->all, s); break; case 'f': case 'e': case 'E': case 'g': case 'G': GetStackReal(&r); printf(spec->all, r); break; case 'p': GetStackPointer((char**)&p); printf(spec->all, p); break; case '%': printf("\%"); break; default: printf("%s", spec->all); } } } /* * Install the built-in io procs. Note that we reserve act rec space for * display save, but we dont need any for the return val, since we'll never get * to doReturn, since by convention, any built-ins will build there own value * structs if they need to return anything. */ InstallIOProcs() { SymtabEntry *p, *sym; Symtab *symt; int o; /* * Soon to be: * Parse("\ procedure WriteInt(x: integer; n: cardinal);\ begin\ compiled;\ end WriteInt;)"; */ symt = (p = InstallProc("WriteInt", WriteInt, false, null))-> Info.Proc.Symtab; o = symt->Offset = TypeSize(IntType); /* For int parm */ InstallFormal(p, "n", CardType, 0, o); InstallFormal(p, "x", IntType, 0, 0); symt->Offset += TypeSize(CardType) + /* For card parm */ sizeof(char *); /* For display */ /* * procedure WriteReal(x: real; n: cardinal); */ symt = (p = InstallProc("WriteReal", WriteReal, false, null))-> Info.Proc.Symtab; o = symt->Offset = TypeSize(RealType); /* For real parm */ InstallFormal(p, "n", CardType, 0, o); InstallFormal(p, "x", RealType, 0, 0); symt->Offset += TypeSize(CardType) + /* For card parm */ sizeof(char *); /* For display */ /* * procedure WriteChar(c: char); */ symt = (p = InstallProc("WriteChar", WriteChar, false, null))-> Info.Proc.Symtab; InstallFormal(p, "c", CharType, 0, 0); symt->Offset = sizeof(char) + /* For char parm */ sizeof(char *); /* For display */ /* * procedure WriteBool(b: boolean); */ symt = (p = InstallProc("WriteBool", WriteBool, false, null))-> Info.Proc.Symtab; InstallFormal(p, "b", BoolType, 0, 0); symt->Offset = sizeof(bool) + /* For bool parm */ sizeof(char *); /* For display */ /* * procedure WriteString(s: array of char); */ symt = (p = InstallProc("WriteString", WriteString, true, null))-> Info.Proc.Symtab; sym = InstallFormal(p, "s", BuildOpenArrayType(CharType, null), 0, 0); SetSymFlag(sym, arrayParm); symt->Offset = sizeof(char *) + /* For formal open array */ sizeof(char *); /* For display */ /* * procedure WriteLn(); */ symt = InstallProc("WriteLn", WriteLn, false, null)->Info.Proc.Symtab; symt->Offset = sizeof(char *); /* * A fully polymorphic, varargs Write: * * special procedure Write(group parms: any); */ /* * A printf-like Write: * * special procedure WriteF(fmt: string; group parms: atomic); */ } FormatSpec *GetNextFormatSpec() {} void NonAnsiCBind() {}