⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.c

📁 利用语言编写的有限元分析软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *  ============================================================================= 
 *  ALADDIN Version 1.0 :
 *               code.c : Functions for Stack Machine
 *                                                                     
 *  Copyright (C) 1995 by Mark Austin, Xiaoguang Chen, and Wane-Jang Lin
 *  Institute for Systems Research,                                           
 *  University of Maryland, College Park, MD 20742                                   
 *                                                                     
 *  This software is provided "as is" without express or implied warranty.
 *  Permission is granted to use this software for any on any computer system
 *  and to redistribute it freely, subject to the following restrictions:
 * 
 *  1. The authors are not responsible for the consequences of use of
 *     this software, even if they arise from defects in the software.
 *  2. The origin of this software must not be misrepresented, either
 *     by explicit claim or by omission.
 *  3. Altered versions must be plainly marked as such, and must not
 *     be misrepresented as being the original software.
 *  4. This notice is to remain intact.
 *                                                                    
 *  Written by: Mark Austin, Xiaoguang Chen, and Wane-Jang Lin      December 1995
 *  ============================================================================= 
 */
#include <stdio.h>
#include <math.h>
#include <string.h>

#include "defs.h"
#include "miscellaneous.h"
#include "units.h"
#include "matrix.h"
#include "fe_database.h"
#include "symbol.h"
#include "code.h"
#include "fe_functions.h"
#include "y.tab.h"

/* Setup Program Stack */

#define  NSTACK    200
#define  NPROG    5500
#define  NFRAME    500

/* Setup Stack Frame for Program Machine */

static DATUM  stack[NSTACK];
static DATUM        *stackp;

Inst     prog[NPROG];
Inst     *progp;
Inst     *pc;
Inst     *progbase = prog;
int      returning;

static int iBREAK_FLAG = 0;

typedef struct Frame {
        SYMBOL     *sp;
        Inst    *retpc;
        DATUM    *argn;
        int      nargs;
} Frame;

Frame frame_in_code[NFRAME];
Frame *fp;


/* Initialise the pointers stackp and progp to top of their stacks. */

int Init_Code()
{
   progp     = progbase;
   stackp    = stack;
   fp        = frame_in_code;
   returning = 0;
}

/* Push a data type Datum onto the interpreter and
   increment stackp to point to the address to which will
   be assigned the next element to be pushed onto stack.*/

#ifdef __STDC__
int Push( DATUM d )
#else
int Push(d)
DATUM d;
#endif
{
    if(stackp >= &stack[NSTACK])
       EXECUTION_ERROR("ERROR >> stack overflow", (char *) 0);
       *stackp++ = d;  /* *stackp=d; stackp++; */
}

DATUM Pop()
{
    if(stackp == stack)
       EXECUTION_ERROR("ERROR >> stack underflow ", (char *) 0);
       return *--stackp;  /* stackp--; return *stackp */
}

int Pop_Eval()
{
   Pop();
}

#ifdef __STDC__
int Execute( Inst *p )
#else
int Execute(p)
Inst *p;
#endif
{
    for(pc = p; *pc != STOP && !returning; ) {
        pc = pc+1;
        if(Check_Break()) break;
        (*(*(pc-1)))();
    }
}

/* Push_constant() pushes a data type Datum onto the 
   interpreter stack, and increments the pointer to prog.*/

int Push_Constant()
{
DATUM d;

    d.q        = (QUANTITY *) MyCalloc(1,sizeof(QUANTITY));
    if(CheckUnits() == ON)
        d.q->dimen = (DIMENSIONS *) MyCalloc(1,sizeof(DIMENSIONS));
    else
        d.q->dimen = (DIMENSIONS *)NULL;

    d.q->value = ((SYMBOL *) *pc)->u.value;
    pc = pc+1;
    Push(d);
}

int Push_Variable()
{
DATUM d;

    d.sym = (SYMBOL *)(*pc);
    pc = pc+1;
    Push(d);
}

int Push_String()
{
DATUM d;

    d.sym = (SYMBOL *) SaveString((char *)(*pc));
    pc = pc+1;
    Push(d);
}

int Push_Matrix()
{
DATUM d;

    d.sym = (SYMBOL *)(*pc);
    pc = pc+1;
    Push(d);
}


/*
 *  ---------------------------------------------------------
 *  Callback Functions for Looping and Conditional Constructs
 *  ---------------------------------------------------------
 */

int While_Code() {
DATUM d;
Inst *savepc = pc;

     Execute(savepc + 2);                /* test condition */
     d = Pop();

     while(d.q->value) {
	 if(Check_Break())  break;
	 Execute(*((Inst **)(savepc)));  /* body of code */
	 if(returning || Check_Break())  break;
	 Execute(savepc + 2);            /* test condition */
         if(CheckUnits()==ON) {
             free((char *)d.q->dimen->units_name);
             free((char *)d.q->dimen);
         }
         free((char *)d.q);
	 d = Pop();
     }
     if(CheckUnits()==ON) {
         free((char *)d.q->dimen->units_name);
         free((char *)d.q->dimen);
     }
     free((char *)d.q);

     if(returning == 0)
        pc = *((Inst **)(savepc + 1));   /* next statement */

     After_Break();
}

int If_Code() {
DATUM d;
Inst *savepc = pc;

     Execute(savepc + 3);               /* condition part */
     d = Pop();
     if(d.q->value) {
       Execute(*((Inst **)(savepc)));
     }
     else if(*((Inst **)(savepc + 1))) {
	Execute(*((Inst **)(savepc+1)));
     }
     if(CheckUnits()==ON) {
         free((char *)d.q->dimen->units_name);
         free((char *)d.q->dimen);
     }
     free((char *)d.q);
	
     if(!returning)
	pc = *((Inst **)(savepc + 2));   /* next statement */
}

int For_Code() {
DATUM d;
Inst *savepc = pc;

     Execute(*((Inst **) savepc)) ;     /* initiation */ 
     Execute(*((Inst **) (savepc+1))) ; /* cond */

     d = Pop();
     while(d.q->value) {
        if(Check_Break()) break;
        Execute(*((Inst **)(savepc+2))); /* body of loop */
        Execute(*((Inst **)(savepc+3))); /* increments */
        if(returning || Check_Break()) break;
        Execute(*((Inst **) (savepc+1))) ; /* cond */

        if(CheckUnits()==ON) {
           free((char *)d.q->dimen->units_name);
           free((char *)d.q->dimen);
        }

        free((char *)d.q);
        d = Pop();
     }
     if(CheckUnits()==ON) {
         free((char *)d.q->dimen->units_name);
         free((char *)d.q->dimen);
     }
     free((char *)d.q);

     if(!returning)
        pc = *((Inst **)(savepc + 4));   /* next statement */
     After_Break();
}

/* ========================================= */
/* Put Function or Procedure in Symbol Table */
/* ========================================= */

#ifdef __STDC__
int define( SYMBOL *sp )
#else
int define(sp)
SYMBOL *sp;
#endif
{
     sp->u.defn = (Inst) progbase; /* start of code         */
     progbase   = progp;           /* next code starts here */
}

/* Call a function */

int Call()
{
SYMBOL *sp = (SYMBOL *) pc[0];

     if(fp++ >= &frame_in_code[NFRAME - 1])
        EXECUTION_ERROR(sp->cpSymName, "ERROR >> Call nested too deeply");

     fp->sp    = sp;
     fp->nargs = (int) pc[1];
     fp->retpc = pc + 2;
     fp->argn  = stackp - 1;

     Execute((Inst *) sp->u.defn);
     returning = 0;
}

int Ret()
{
int i;
DATUM d;

     for(i = 0; i < fp->nargs; i++) {
         d = Pop();
         if(CheckUnits()==ON) {
             free((char *)d.q->dimen->units_name);
             free((char *)d.q->dimen);
         }
         free((char *)d.q);
     }

     pc = (Inst *) fp->retpc;
     --fp;
     returning = 1;
}

/*  
 *  ----------------------------------------------------------------------
 *  The function code() builds up the machine stack prog, adding data
 *  types Inst to it. In practice the arguments to code() are pointers
 *  to the functions defined later on in code.c, and pointers to
 *  data types Symbol, which have been coerced by the use of the 
 *  cast Inst.
 *  ----------------------------------------------------------------------
 */ 

#ifdef __STDC__
Inst *Code( Inst f )
#else
Inst *Code(f)
Inst f;
#endif
{
Inst *oprogp = progp;

   if(progp >= &prog[NPROG])
      EXECUTION_ERROR("ERROR >> program too big", (char *) 0);

    *progp++ = f;
    return oprogp;
}


/* 
 *  ------------------------------------
 *  Functions for Engineering Quantities
 *  ------------------------------------
 */ 

int Quantity_Add()
{
DATUM d1, d2, d3;
int    UnitsType;

   d2 = Pop();  /* second item, d2.q */
   d1 = Pop();  /* first item,  d1.q */

   switch(CheckUnits()) {
     case ON:
        if(SameUnits(d1.q->dimen, d2.q->dimen) == TRUE) {
           UnitsType = CheckUnitsType();     
           if(d2.q->dimen->units_type == UnitsType ||
              d2.q->dimen->units_type == SI_US     ) {
              d2.q->value = d2.q->value + d1.q->value;
              free((char *) d1.q->dimen->units_name);
              free((char *) d1.q->dimen);
              free((char *) d1.q);
              Push(d2);
           }
           else {
              d1.q->value = d2.q->value + d1.q->value;
              free((char *) d2.q->dimen->units_name);
              free((char *) d2.q->dimen);
              free((char *) d2.q);
              Push(d1);
           }
        }
        else
           FatalError("In Add() : Inconsistent Dimensions",(char *)NULL);
        break;
     case OFF:
        d2.q->value = d2.q->value + d1.q->value;
        free((char *) d1.q);
        Push(d2);
        break;
     default:
        FatalError("In Add() : CheckUnits is not ON or OFF",(char *)NULL);
        break;
   }
}

int Quantity_Sub()
{
DATUM d1, d2;
int UnitsType;

    d2 = Pop();   /* 2nd quantity, d2.q */
    d1 = Pop();   /* 1st quantity, d1.q */

    switch( CheckUnits() )  {
      case ON:
        if(SameUnits(d1.q->dimen, d2.q->dimen) == TRUE) {
           UnitsType = CheckUnitsType();     
           if(d2.q->dimen->units_type == UnitsType ||
              d2.q->dimen->units_type == SI_US ) {
              d2.q->value = d1.q->value - d2.q->value;
              free((char *) d1.q->dimen->units_name);
              free((char *) d1.q->dimen);
              free((char *) d1.q);
              Push(d2);
           }
           else {
              d1.q->value = d1.q->value - d2.q->value;
              free((char *) d2.q->dimen->units_name);
              free((char *) d2.q->dimen);
              free((char *) d2.q);
              Push(d1);
           }
        }
        else
           FatalError("In Sub() : Inconsistent Dimensions",(char *)NULL);
        break;
      case OFF:
        d1.q->value = d1.q->value - d2.q->value;
        free((char *) d2.q);
        Push(d1);
        break;
     default:
        FatalError("In Sub() : CheckUnits is not ON or OFF",(char *)NULL);
        break;
    }
}

int Quantity_Mul()
{
DATUM  d1, d2, d3;
int        length;

    d2 = Pop();   /* 2nd quantity, d2.q */
    d1 = Pop();   /* 1st quantity, d1.q */
    d3.q         = (QUANTITY *) MyCalloc(1,sizeof(QUANTITY));

    switch( CheckUnits() ) {
      case ON:
         d3.q->value  = d1.q->value*d2.q->value;
         d3.q->dimen  = UnitsMult( d1.q->dimen, d2.q->dimen );
         free((char *) d2.q->dimen->units_name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -