Question:
Calculator In C Code?
riki
2007-05-01 04:03:44 UTC
I need the source code of calculator immediately. Can anyone help me plz. I have developed one but it is not completed yet.
Seven answers:
2007-05-01 04:20:07 UTC
Seriously, calculator in C is an easy program.

If u are new to C, u'll be done with +,-,*,%,^,/ and factorial in 30-40 minutes.



Google "Calculator in C". I just did.

u'll get loads of simple, medium and difficult source codes.

(the 1st link is great - programmersheaven)
raji_badari
2007-05-02 03:12:06 UTC
the code for calc in c is





#include



/*

* Calculator program - 9 May 1985

* Please send corrections or remarks to:

* Bob Brodt

* 34 Mehrhof Rd.

* Little Ferry, NJ 07643

* (201)-641-9582

*

* This is a simple integer arithmetic calculator program. It uses infix

* notation, i.e. 1+2*3 as opposed to "reverse polish" notation: 1 2 3 * +.

*

* CONSTANTS:

* Numbers may be input as in C using 0x notation for hex, and a

* leading zero for octal, everything else is assumed to be decimal.

* VARIABLES:

* Also available are 26 registers referenced by a single letter

* (a-z or A-Z, case is ignored).

* OPERATORS:

* The following operators are supported (from highest precedence to

* lowest):

*

* ( ) associativity

* ~ one's complement

* * / % mutliply, divide and modulo

* + - unary and binary add & subtract

* << >> shift left and right

* & bitwise AND

* ^ bitwise exclusive OR

* | bitwise inclusive OR

* = assignment

* , comma - seperates function arguments

*

* All operators associate from left to right with the exception of

* the assignment (=) operator.

* FUNCTIONS:

* The calculator also has built-in function capabilties which may be

* enhanced later:

* base n - set the output conversion base to n (n = 8, 10 or 16)

* ADDITIONAL FEATURES:

* help - displays a help screen containing the above information.

* ? - displays all of the variables and their current values.

*/



/*

* Tokens

*/

#define T_EOL ';'

#define T_CONST 'C'

#define T_SYMBOL 'S'

#define T_LPAR '('

#define T_RPAR ')'

#define T_COMMA ','

#define T_ASSIGN '='

#define T_POINT '$'

#define T_MUL '*'

#define T_DIV '/'

#define T_MOD '%'

#define T_ADD '+'

#define T_SUB '-'

#define T_NEG '_'

#define T_NOT '~'

#define T_SHL 'L'

#define T_SHR 'R'

#define T_AND '&'

#define T_XOR '^'

#define T_IOR '|'

#define T_FUNC 'F'





/*

* Operator/Operand stack, base ptr and top of stack ptr

*/

#define STAKSZ 128

struct {

char o_token;

int o_value;

} Opstk[ STAKSZ ];

int Opbase, Opsp;



/*

* Value (working) stack, base ptr and top of stack ptr

*/

int Valstk[ STAKSZ ];

int Valbase, Valsp;



/*

* Built-in Functions and jump table

*/

int f_sum(), f_base();

int (*Functab[ 2 ])();



/*

* Symbol Table

*/

int Symbols[ 26 ];



/*

* Miscellaneous

*/

#define MAXLEVEL 32

char Level; /* current recursion level in calc() */

char Token; /* current input token */

int Value; /* and its value */

char Eol; /* set when end of line encountered */

char *Lineptr; /* points to next character in input line */

char *Ofmt; /* current output format (set by "base" command) */

int Error; /* set if parsing error occurred */

char Nohelp; /* set if help was given already */



char *skipws();



main()

{

char line[ 1024 ], *cp;



initialize();



for ( ;; )

{

Error = 0;

/*

* read a line from stdin and try to parse it

*/

printf( "? " );

if ( ! gets( line ) )

break;

cp = skipws( line );

if ( *cp )

{

if ( *cp == '?' )

{

dumpvars();

continue;

}

else if ( strcmp( cp, "quit" ) == 0 )

break;

else if ( strcmp( cp, "help" ) == 0 )

{

help();

continue;

}

calc( cp );

/*

* If no parsing errors were found, print the

* results of the evaluation of the expression.

*/

if ( Error && Nohelp )

{

printf( "do you need help ? " );

gets( line );

cp = skipws( line );

if ( toupper( *cp ) == 'Y' )

help();

}

else if ( ! Error )

{

printf( Ofmt, Value );

putchar( '\n' );

}

}

}

printf( "bye bye\n" );

}



initialize()

{

/*

* initialize

*/

Functab[0] = f_sum;

Functab[1] = f_base;



push( 10 );

f_base();

Nohelp = 1;

}



help()

{

Nohelp = 0;



printf("This calculator uses infix notation i.e. 1+2*3 as opposed to\n");

printf("\"reverse polish\" notation: 1 2 3 * +.\n");

printf("CONSTANTS:\n");

printf(" Numbers may be entered using 0x notation for hex (like in C),\n");

printf(" and a leading zero for octal, everything else is assumed to be\n");

printf(" decimal.\n");

printf("VARIABLES:\n");

printf(" Also available are 26 registers referenced by a single letter\n");

printf(" (a-z or A-Z, case is ignored).\n");

printf("OPERATORS:\n");

printf(" The following operators are supported (from highest precedence\n");

printf(" to lowest):\n");

printf("\n");

printf(" ( ) associativity\n");

printf(" ~ one's complement\n");

printf(" * / % mutliply, divide and modulo\n");

printf(" + - unary and binary add & subtract\n");

printf(" << >> shift left and right\n");

printf(" & bitwise AND\n");

printf(" ^ bitwise exclusive OR\n");

printf(" | bitwise inclusive OR\n");

printf("-MORE-" );

getchar();

printf(" = assignment\n");

printf(" , comma - seperates function arguments\n");

printf("\n");

printf(" All operators associate from left to right with the exception\n");

printf(" of the assignment (=) operator.\n");

printf("FUNCTIONS:\n");

printf(" The calculator also has built-in function capabilties (which\n");

printf(" may be enhanced in a later revision):\n");

printf("\n");

printf(" base n - set the output conversion base to n (n = 8, 10 or 16)\n");

printf("\n");

printf("ADDITIONAL FEATURES:\n");

printf(" help - displays a help screen containing the above information.\n");

printf(" ? - displays all of the variables and their current values.\n");

}



dumpvars()

{

int i;



for ( i=0; i<26; ++i )

{

if ( !(i % 8) )

printf( "\n" );

printf( "%c=", i + 'A' );

printf( Ofmt, Symbols[ i ] );

printf( "\t" );

}

printf( "\n" );

}



/*************************************************************

* EXPRESSION EVALUATOR *

**************************************************************/

/*

* NOTE: The comments make reference to "lvalues" and "rvalues". These

* are attributes of (primaries, for the layman, are things

* like constants and variables, and parenthesized expressions. If you

* don't know what an expression is, you shouldn't be a reading this!).

* If a is an "lvalue", it means that it can usually be found on

* LEFT-HAND side of an assignment operator. "rvalues" can only be found

* on the RIGHT-HAND side of an assignment. Simply stated, only things like

* variables can be used as both "lvalues" and "rvalues", whereas things

* like constants and parenthesized expressions can only be "rvalues" since

* it wouldn't make sense to say: 12 = 5.

*/





calc( line )

char *line;

{

/*

* Parse and calculate an arithmetic expression pointed to

* by "line". This routine is fully re-entrant - a feature

* that is not currently used, but may come in handy later

* (for instance if a variable points to a character string

* that contains an expression to be evaluated).

*/

char *savLineptr;

int savValbase, savValsp, savOpbase, savOpsp;



if ( ++Level > MAXLEVEL )

{

err( "recursion" );

}

else

{

/*

* Save all global variables that may change if calc()

* is called recursively.

*/

savLineptr = Lineptr;

savValbase = Valbase;

savValsp = Valsp;

savOpbase = Opbase;

savOpsp = Opsp;



/*

* Set up stack base ptrs and input line ptr

*/

Valbase = Valsp;

Opbase = Opsp;

Lineptr = line;



/*

* Get the first token from input line and parse an

* expression and then evaluate it.

*/

Eol = 0;



getoken();

if ( ! Eol )

{

expression();

if ( Error <= 0 )

Value = evaluate();

}

/*

* Restore previous values of globals

*/

Lineptr = savLineptr;

Valbase = savValbase;

Valsp = savValsp;

Opbase = savOpbase;

Opsp = savOpsp;

}



--Level;

}



evaluate()

{

/*

* Evaluate an expression by popping operators and operands

* from the Operator/Operand stack and performing each indicated

* operation. Only the operators starting from current base ptr

* (Opbase) to top of stack (Opsp) are evaluated, so that evaluate()

* may be called by any generation of calc().

*/

int opsp, val, *ip;

char op;



#define TOS (Valstk[Valsp-1]) /* top of stack macro */



for ( opsp=Opbase; opsp
{

op = Opstk[ opsp ].o_token;



if ( op == T_CONST )

push( Opstk[ opsp ].o_value );

else if ( op == T_SYMBOL )

/*

* Push the address of a variable

*/

push( &Symbols[ Opstk[ opsp ].o_value ] );

else if ( op == T_POINT )

{

/*

* Get the value of the integer pointed to by the

* address on top of the stack. This usually follows

* a T_SYMBOL when the symbol is not being used

* as an "lvalue".

*/

ip = pop();

push( *ip );

}

else if ( op == T_ASSIGN )

{

/*

* Assignment operator: The item on top of stack is

* the "rvalue", second on stack is the "lvalue"

* (an address where to store the "rvalue"). The

* "rvalue" gets pushed back on top of the stack.

*/

val = pop();

ip = pop();

push( *ip = val );

}

else if ( op == T_ADD )

{

val = pop();

TOS += val;

}

else if ( op == T_SUB )

{

val = pop();

TOS -= val;

}

else if ( op == T_NOT )

TOS = ~TOS;

else if ( op == T_NEG )

TOS = -TOS;

else if ( op == T_MUL )

{

val = pop();

TOS *= val;

}

else if ( op == T_DIV )

{

val = pop();

TOS /= val;

}

else if ( op == T_MOD )

{

val = pop();

TOS %= val;

}

else if ( op == T_SHL )

{

val = pop();

TOS <<= val;

}

else if ( op == T_SHR )

{

val = pop();

TOS >>= val;

}

else if ( op == T_AND )

{

val = pop();

TOS &= val;

}

else if ( op == T_XOR )

{

val = pop();

TOS ^= val;

}

else if ( op == T_IOR )

{

val = pop();

TOS |= val;

}

else if ( op == T_COMMA )

;

else if ( op == T_FUNC )

push( (*Functab[ Opstk[ opsp ].o_value ])() );

else

err( "bad operator in stack: 0x%x (%c)", op, op );

}

return Valstk[ Valbase ];

}



push( val )

{

if ( Valsp >= STAKSZ )

err( "stack overflow" );

return Valstk[ Valsp++ ] = val;

}



pop()

{

if ( --Valsp < 0 )

Valsp = 0;

return Valstk[ Valsp ];

}



/*************************************************************

* EXPRESSION PARSER *

**************************************************************/

expression()

{

/*

* Parse an expression. Expressions have the following syntax:

* :=

* so the first thing to look for is a primary.

*/

int lvalue;



if ( !(lvalue = primary()) )

err( "bad expression" );

else if ( Eol )

{

if ( lvalue < 0 )

generate( T_POINT, 0 );

}

else

op_prim( 0, lvalue );

}



op_prim( precedence, lvalue )

int precedence; /* precedence of current */

int lvalue; /* type of current : -1 => lvalue */

/* 0 => no (error) */

/* 1 => rvalue */

{

/*

* Parse the part of an expression.

* "precedence" is the PREVIOUS 's precedence level

* (0=low, +n=high).

*/

char tkn;

int pr, lv;



while ( ! Eol )

{

/*

* Get the precedence level of current ("pr").

* If it is greater than previous operator ("precedence"),

* get the next and do another

* NOTE: For left-to-right associativity, the condition

* pr > precedence

* must be true. for right-to-left associativity,

* pr >= precedence

* must be true (assignment operator only).

*/



pr = binop( Token );



if (

(pr>precedence && pr>0) ||

(Token==T_ASSIGN && pr>=precedence)

)

{

if ( Token == T_ASSIGN )

{

if ( lvalue > 0 )

err( "= needs and lvalue" );

}

else if ( lvalue < 0 )

generate( T_POINT, 0 );



/*

* Save the operator token and do a primary.

*/

tkn = Token;

getoken();

if ( ! (lv = primary()) )

err( "missing an operand" );

/*

* Now look at the next operator. If its precedence

* is greater than this one ("tkn" above), generate

* code for it BEFORE this one.

*/

lvalue = op_prim( pr, lv );



if ( Token != T_ASSIGN && lvalue < 0 )

{

/*

* Next operator is not the assignment op.

* and the current is an lvalue,

* therefore generate a "load from address

* on top of stack" instruction.

*/

generate( T_POINT, 0 );

/*

* This makes it an rvalue now.

*/

lvalue = 1;

}

else if ( tkn!=T_ASSIGN && Token==T_ASSIGN )

{

/*

* YEECH! this is the only way I know of to

* detect errors like: a+b=c

*/

err( "= needs an lvalue" );

}



/*

* Generate the instruction for the current operator.

*/

generate( tkn, 0 );

}

else

break;

}



return lvalue;

}



primary()

{

/*

* Parse a primary. Primaries have the following syntax:

* := |

* '(' ')' |

* |

*

*/

int rtn;

int val;



if ( Eol )

return 0;



/*

* Return value:

* -1 => the is an lvalue

* 0 => not a (usually end of line or a syntax error)

* 1 => the is an rvalue

*/

rtn = 1;



switch ( Token )

{

case T_SYMBOL: /* a symbol */

rtn = -1;

case T_CONST: /* a constant */

generate( Token, Value );

getoken();

break;

case T_LPAR: /* a parenthesized expression */

getoken();

expression();

if ( Token != T_RPAR )

{

err( "missing ')'" );

rtn = 0;

}

else

getoken();

break;

case T_SUB: /* unary - */

/*

* The lexical analyzer is not smart enough to recognize

* unary operators (+ and -), that's why we have to do

* it here

*/

getoken();

expression();

generate( T_NEG, 0 );

break;

case T_NOT: /* unary ~ */

getoken();

expression();

generate( T_NOT, 0 );

break;

case T_ADD: /* unary + */

getoken();

expression();

break;

case T_FUNC: /* built-in function */

val = Value;

getoken();

expression();

generate( T_FUNC, val );

break;

default:

/*

* Not a primary

*/

rtn = 0;

}

return rtn;

}



binop( op )

char op;

{

/*

* Determine if "op" is a binary operator and return its

* precedence level if so. If not, return 0.

*/

switch ( op )

{

case T_COMMA:

return 1;

case T_ASSIGN:

return 2;

case T_IOR:

return 3;

case T_XOR:

return 4;

case T_AND:

return 5;

case T_SHL:

case T_SHR:

return 6;

case T_ADD:

case T_SUB:

return 7;

case T_MUL:

case T_DIV:

case T_MOD:

return 8;

case T_NOT:

return 9;

}

return 0;

}



generate( tkn, val )

char tkn;

{

/*

* Push the given token and value onto the Operator/Operand stack.

*/

if ( Opsp < STAKSZ )

{

Opstk[ Opsp ].o_token = tkn;

Opstk[ Opsp ].o_value = val;

++Opsp;

}

else

err( "expression too complex" );

}



/*************************************************************

* LEXICAL ANALYZER *

*************************************************************/

getoken()

{

/*

* Lexical Analyzer. Gets next token from the input line

* pointed to by "Lineptr" and advances "Lineptr" to next

* character. If end of input line is encountered, the

* "Eol" flag is set.

*/

char *cp, buf[ 128 ];

int i;



/*

* skip white space

*/

Lineptr = skipws( Lineptr );



if ( ! *Lineptr )

{

Eol = 1;

Token = T_EOL;

}

else if ( *Lineptr == '0' )

{

/*

* Check if it's a hex or octal constant

*/

Token = T_CONST;

++Lineptr;

if ( toupper( *Lineptr ) == 'X' )

{

++Lineptr;

for ( cp = buf; ishexdigit( *Lineptr ); )

*cp++ = *Lineptr++;

*cp = 0;

sscanf( buf, "%x", &Value );

}

else if ( isdigit( *Lineptr ) )

{

for ( cp = buf; isoctdigit( *Lineptr ); )

*cp++ = *Lineptr++;

*cp = 0;

sscanf( buf, "%o", &Value );

}

else

Value = 0;

}

else if ( isdigit( *Lineptr ) )

{

/*

* It's a numeric constant, "Value" will be its value.

*/

Token = T_CONST;

for ( cp = buf; isdigit( *Lineptr ); )

*cp++ = *Lineptr++;

*cp = 0;

Value = atoi( buf );

}

else if ( Value = isfunc( &Lineptr ) )

{

/*

* It's a built-in function, "Value" will be the index

* into the function jump table.

*/

Token = T_FUNC;

--Value;

}

else if ( Token = isbinop( &Lineptr ) )

{

/*

* It's a binary operator

*/

;

}

else if ( isalpha( *Lineptr ) )

{

Token = T_SYMBOL;

Value = toupper( *Lineptr ) - 'A';

++Lineptr;

}

else

{

/*

* Bad character in input line

*/

err( "bad syntax: %s", Lineptr );

++Lineptr;

}



return Token;

}



char *

skipws( cp )

char *cp;

{

while ( *cp==' ' || *cp=='\t' )

++cp;

return cp;

}



isfunc( cpp )

char **cpp;

{

/*

* Check if *cpp is the name of a built-function, return the

* function jump table index+1 if so and bump *cpp to next

* character. Return 0 if not a function.

*/

char *cp, *bp, buf[ 80 ];

int funcno;



/*

* copy the name from input line buffer to a local buffer so

* we can use it to make a proper comparison to function names.

*/

for ( cp=*cpp, bp=buf; isalpha( *cp ); )

*bp++ = *cp++;

*bp = 0;



/*

* compare it to all of the function names we know about.

*/

if ( strcmp( buf, "sum" ) == 0 )

funcno = 1;

else if ( strcmp( buf, "base" ) == 0 )

funcno = 2;

else

/*

* not a built-in function

*/

funcno = 0;



if ( funcno )

*cpp = cp;



return funcno;

}



isbinop( cpp )

char **cpp;

{

/*

* Check if *cpp is a binary operator, return its token value

* and bump *cpp to next character.

*/

int tkn;

char c;



c = **cpp;

if ( c == ',' )

tkn = T_COMMA;

else if ( c == '=' )

tkn = T_ASSIGN;

else if ( c == '<' )

{

if ( *(++(*cpp)) == '<' )

tkn = T_SHL;

}

else if ( c == '>' )

{

if ( *(++(*cpp)) == '>' )

tkn = T_SHR;

}

else if ( c == '(' )

tkn = T_LPAR;

else if ( c == ')' )

tkn = T_RPAR;

else if ( c == '*' )

tkn = T_MUL;

else if ( c == '/' )

tkn = T_DIV;

else if ( c == '%' )

tkn = T_MOD;

else if ( c == '+' )

tkn = T_ADD;

else if ( c == '-' )

tkn = T_SUB;

else if ( c == '^' )

tkn = T_XOR;

else if ( c == '&' )

tkn = T_AND;

else if ( c == '|' )

tkn = T_IOR;

else if ( c == '~' )

tkn = T_NOT;

else

tkn = 0;



if ( tkn )

++(*cpp);



return tkn;

}



/*************************************************************

* BUILT-IN FUNCTIONS *

**************************************************************/

f_sum()

{

/*

* usage: sum( a, b )

* Sum all the numbers between a and b

*/

int i, a, b;



b = pop();

a = pop();

for ( i=a+1; i<=b; ++i )

a += i;



push( a );

}



f_base()

{

/*

* usage: base( n )

* Set output number base

*/

switch ( pop() )

{

case 8:

Ofmt = "0%o";

break;

case 16:

Ofmt = "0x%x";

break;

case 10:

default:

Ofmt = "%d";

break;

}

}





/*************************************************************

* MISCELLANEOUS *

**************************************************************/

err( a, b, c, d, e, f )

{

if ( ! Error )

{

printf( a, b, c, d, e, f );

putchar( '\n' );

Error = 1;

}

}



ishexdigit( c )

char c;

{

return instr( c, "0123456789abcdefABCDEF" );

}



isoctdigit( c )

char c;

{

return instr( c, "01234567" );

}



instr( c, s )

char c, *s;

{

while ( *s )

if ( c == *s++ )

return 1;



return 0;

}
black_hat_009
2007-05-01 08:10:46 UTC
1 2 3 ....you go free
..::|QATAR|::..
2007-05-01 04:14:52 UTC
You can try these site where people share their source code:

http://www.a1vbcode.com/a1vbcode/sort.asp?type=all

(VB)

http://www.codeproject.com/

Most languages

http://www.programmersheaven.com/

Most languages

http://www.planetsourcecode.com/

Most languages

http://www.cprogramming.com/

C Language



Hope this helps & good luck,
Light U
2007-05-01 04:18:49 UTC
I dont know
hemanth.P
2007-05-01 10:58:28 UTC
http://www.codeproject.com/useritems/calc1.asp

http://www.ssa.gov/OACT/ANYPIA/source.html

http://www.codeproject.com/csharp/genericnumerics.asp
2007-05-01 04:06:23 UTC
i dont have any idea about this


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...