Annotation of OpenXM/src/ox_math/sm_ext.c, Revision 1.1
1.1 ! ohara 1: /* -*- mode: C; coding: euc-japan -*- */
! 2: /* $OpenXM$ */
! 3:
! 4: /*
! 5: Copyright (C) Katsuyoshi OHARA, 2000.
! 6: Portions copyright 1999 Wolfram Research, Inc.
! 7:
! 8: You must see OpenXM/Copyright/Copyright.generic.
! 9: The MathLink Library is licensed from Wolfram Research Inc..
! 10: See OpenXM/Copyright/Copyright.mathlink for detail.
! 11: */
! 12:
! 13: /*
! 14: Remarks:
! 15: file descripter 3 and 4 are already opened by the parent process.
! 16: */
! 17:
! 18: #include <stdio.h>
! 19: #include <stdlib.h>
! 20: #include <unistd.h>
! 21: #include <gmp.h>
! 22: #include <mathlink.h>
! 23: #include <ox_toolkit.h>
! 24: #include "sm.h"
! 25:
! 26: extern int flag_mlo_symbol;
! 27:
! 28: /* MathLink independent */
! 29: static cmo **stack = NULL;
! 30: static int stack_ptr = 0;
! 31: static int stack_size = 0;
! 32: OXFILE *stack_oxfp = NULL;
! 33:
! 34: #define DIFFERENCE_OF_STACK 1024
! 35:
! 36: void stack_extend()
! 37: {
! 38: int newsize = stack_size + DIFFERENCE_OF_STACK;
! 39: cmo **newstack = (cmo **)malloc(sizeof(cmo *)*newsize);
! 40: if (stack != NULL) {
! 41: memcpy(newstack, stack, sizeof(cmo *)*stack_size);
! 42: free(stack);
! 43: }
! 44: stack_size = newsize;
! 45: stack = newstack;
! 46: }
! 47:
! 48: void push(cmo* m)
! 49: {
! 50: #if DEBUG
! 51: symbol_t symp;
! 52:
! 53: if (m->tag == CMO_STRING) {
! 54: fprintf(stderr, "ox_math:: a CMO_STRING(%s) was pushed.\n", ((cmo_string *)m)->s);
! 55: }else {
! 56: symp = lookup_by_tag(m->tag);
! 57: fprintf(stderr, "ox_math:: a %s was pushed.\n", symbol_get_key(symp));
! 58: }
! 59: #endif
! 60: if (stack_ptr >= stack_size) {
! 61: stack_extend();
! 62: }
! 63: stack[stack_ptr] = m;
! 64: stack_ptr++;
! 65: }
! 66:
! 67: /* if the stack is empty, then pop() returns (CMO_NULL). */
! 68: cmo *pop()
! 69: {
! 70: if (stack_ptr > 0) {
! 71: return stack[--stack_ptr];
! 72: }
! 73: return new_cmo_null();
! 74: }
! 75:
! 76: void pops(int n)
! 77: {
! 78: stack_ptr -= n;
! 79: if (stack_ptr < 0) {
! 80: stack_ptr = 0;
! 81: }
! 82: }
! 83:
! 84: void push_error(int errcode, cmo* pushback)
! 85: {
! 86: return push((cmo *)make_error_object(errcode, pushback));
! 87: }
! 88:
! 89: /*
! 90: If error occurs, then
! 91: an sm_*() function returns non-zero and
! 92: an error obect is set by a function which calls sm_*().
! 93: */
! 94: int sm_popCMO(OXFILE* oxfp)
! 95: {
! 96: cmo* m = pop();
! 97: #ifdef DEBUG
! 98: symbol_t symp = lookup_by_tag(m->tag);
! 99: fprintf(stderr, "ox_math:: opecode = SM_popCMO. (%s)\n", symbol_get_key(symp));
! 100: #endif
! 101:
! 102: if (m != NULL) {
! 103: send_ox_cmo(oxfp, m);
! 104: return 0;
! 105: }
! 106: return SM_popCMO;
! 107: }
! 108:
! 109: int sm_pops(OXFILE* oxfp)
! 110: {
! 111: cmo* m = pop();
! 112: if (m != NULL && m->tag == CMO_INT32) {
! 113: pops(((cmo_int32 *)m)->i);
! 114: return 0;
! 115: }
! 116: return ERROR_ID_UNKNOWN_SM;
! 117: }
! 118:
! 119: /* MathLink dependent */
! 120: int sm_popString(OXFILE* oxfp)
! 121: {
! 122: char *s;
! 123: cmo *err;
! 124: cmo *m;
! 125:
! 126: #ifdef DEBUG
! 127: fprintf(stderr, "ox_math:: opecode = SM_popString.\n");
! 128: #endif
! 129:
! 130: m = pop();
! 131: if (m->tag == CMO_STRING) {
! 132: send_ox_cmo(oxfp, m);
! 133: }else if ((s = new_string_set_cmo(m)) != NULL) {
! 134: send_ox_cmo(oxfp, (cmo *)new_cmo_string(s));
! 135: }else {
! 136: err = make_error_object(SM_popString, m);
! 137: send_ox_cmo(oxfp, err);
! 138: }
! 139: return 0;
! 140: }
! 141:
! 142: int local_execute(char *s)
! 143: {
! 144: if(*s == 'i') {
! 145: switch(s[1]) {
! 146: case '+':
! 147: flag_mlo_symbol = FLAG_MLTKSYM_IS_STRING;
! 148: break;
! 149: case '-':
! 150: case '=':
! 151: default:
! 152: flag_mlo_symbol = FLAG_MLTKSYM_IS_INDETERMINATE;
! 153: }
! 154: }
! 155: return 0;
! 156: }
! 157:
! 158: /* The following function is depend on an implementation of a server. */
! 159: int sm_executeStringByLocalParser(OXFILE* oxfp)
! 160: {
! 161: symbol_t symp;
! 162: cmo* m = pop();
! 163: char *s = NULL;
! 164: #ifdef DEBUG
! 165: fprintf(stderr, "ox_math:: opecode = SM_executeStringByLocalParser.\n");
! 166: #endif
! 167:
! 168: if (m->tag == CMO_STRING
! 169: && strlen(s = ((cmo_string *)m)->s) != 0) {
! 170: if (s[0] == ':') {
! 171: local_execute(++s);
! 172: }else {
! 173: /* for mathematica */
! 174: /* Sending the string `s' to mathematica for its evaluation. */
! 175: ml_evaluateStringByLocalParser(s);
! 176: ml_select();
! 177: push(receive_mlo());
! 178: }
! 179: return 0;
! 180: }
! 181: #ifdef DEBUG
! 182: symp = lookup_by_tag(m->tag);
! 183: fprintf(stderr, "ox_math:: error. the top of stack is %s.\n", symbol_get_key(symp));
! 184: #endif
! 185: return SM_executeStringByLocalParser;
! 186: }
! 187:
! 188: int sm_executeFunction(OXFILE* oxfp)
! 189: {
! 190: int i, argc;
! 191: cmo **argv;
! 192: char* func;
! 193: cmo* m;
! 194:
! 195: if ((m = pop()) == NULL || m->tag != CMO_STRING) {
! 196: return SM_executeFunction;
! 197: }
! 198: func = ((cmo_string *)m)->s;
! 199:
! 200: if ((m = pop()) == NULL || m->tag != CMO_INT32) {
! 201: return SM_executeFunction;
! 202: }
! 203:
! 204: argc = ((cmo_int32 *)m)->i;
! 205: argv = malloc(argc*sizeof(cmo *));
! 206: for (i=0; i<argc; i++) {
! 207: argv[i] = pop();
! 208: }
! 209: ml_executeFunction(func, argc, argv);
! 210: ml_select();
! 211: push(receive_mlo());
! 212: return 0;
! 213: }
! 214:
! 215: int sm_mathcap(OXFILE* oxfp)
! 216: {
! 217: push((cmo *)oxf_cmo_mathcap(oxfp));
! 218: return 0;
! 219: }
! 220:
! 221: void sm_set_mathcap(OXFILE *oxfp)
! 222: {
! 223: cmo_mathcap *m = (cmo_mathcap *)pop();
! 224: if (m->tag == CMO_MATHCAP) {
! 225: oxf_mathcap_update(oxfp, m);
! 226: }else {
! 227: push_error(-1, m);
! 228: /* an error object must be pushed */
! 229: }
! 230: }
! 231:
! 232: int receive_sm_command(OXFILE* oxfp)
! 233: {
! 234: return receive_int32(oxfp);
! 235: }
! 236:
! 237: int execute_sm_command(OXFILE* oxfp, int code)
! 238: {
! 239: int err = 0;
! 240: #ifdef DEBUG
! 241: symbol_t sp = lookup_by_tag(code);
! 242: fprintf(stderr, "ox_math:: %s received.\n", symbol_get_key(sp));
! 243: #endif
! 244:
! 245: switch(code) {
! 246: case SM_popCMO:
! 247: err = sm_popCMO(oxfp);
! 248: break;
! 249: case SM_popString:
! 250: err = sm_popString(oxfp);
! 251: break;
! 252: case SM_mathcap:
! 253: err = sm_mathcap(oxfp);
! 254: break;
! 255: case SM_pops:
! 256: err = sm_pops(oxfp);
! 257: break;
! 258: case SM_executeStringByLocalParser:
! 259: case SM_executeStringByLocalParserInBatchMode:
! 260: err = sm_executeStringByLocalParser(oxfp);
! 261: break;
! 262: case SM_executeFunction:
! 263: err = sm_executeFunction(oxfp);
! 264: break;
! 265: case SM_shutdown:
! 266: shutdown();
! 267: break;
! 268: case SM_setMathCap:
! 269: pop(); /* ignore */
! 270: break;
! 271: default:
! 272: fprintf(stderr, "unknown command: %d.\n", code);
! 273: err = ERROR_ID_UNKNOWN_SM;
! 274: }
! 275:
! 276: if (err != 0) {
! 277: push((cmo *)make_error_object(err, new_cmo_null()));
! 278: }
! 279: }
! 280:
! 281: int sm_run(int code)
! 282: {
! 283: return execute_sm_command(stack_oxfp, code);
! 284: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>