minor formatting, add message on how to terminate interactive mode
This commit is contained in:
parent
7c21d0a54f
commit
1ff1ef9cfb
134
expression.c
134
expression.c
|
@ -220,7 +220,7 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop)
|
|||
}
|
||||
#endif
|
||||
|
||||
int IsTypeToken(struct ParseState * Parser, enum LexToken t,
|
||||
int IsTypeToken(struct ParseState *Parser, enum LexToken t,
|
||||
struct Value * LexValue)
|
||||
{
|
||||
if (t >= TokenIntType && t <= TokenUnsignedType)
|
||||
|
@ -697,7 +697,6 @@ void ExpressionPrefixOperator(struct ParseState *Parser,
|
|||
if (TopValue->Typ == &Parser->pc->FPType) {
|
||||
/* floating point prefix arithmetic */
|
||||
double ResultFP = 0.0;
|
||||
|
||||
switch (Op) {
|
||||
case TokenPlus:
|
||||
ResultFP = TopValue->Val->FP;
|
||||
|
@ -722,68 +721,65 @@ void ExpressionPrefixOperator(struct ParseState *Parser,
|
|||
}
|
||||
ExpressionPushFP(Parser, StackTop, ResultFP);
|
||||
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||
/* integer prefix arithmetic */
|
||||
long ResultInt = 0;
|
||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||
switch (Op) {
|
||||
case TokenPlus:
|
||||
ResultInt = TopInt;
|
||||
break;
|
||||
case TokenMinus:
|
||||
ResultInt = -TopInt;
|
||||
break;
|
||||
case TokenIncrement:
|
||||
ResultInt = ExpressionAssignInt(Parser, TopValue,
|
||||
TopInt+1, false);
|
||||
break;
|
||||
case TokenDecrement:
|
||||
ResultInt = ExpressionAssignInt(Parser, TopValue,
|
||||
TopInt-1, false);
|
||||
break;
|
||||
case TokenUnaryNot:
|
||||
ResultInt = !TopInt;
|
||||
break;
|
||||
case TokenUnaryExor:
|
||||
ResultInt = ~TopInt;
|
||||
break;
|
||||
default:
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
break;
|
||||
}
|
||||
ExpressionPushInt(Parser, StackTop, ResultInt);
|
||||
} else if (TopValue->Typ->Base == TypePointer) {
|
||||
/* pointer prefix arithmetic */
|
||||
int Size = TypeSize(TopValue->Typ->FromType, 0, true);
|
||||
struct Value *StackValue;
|
||||
void *ResultPtr;
|
||||
|
||||
if (TopValue->Val->Pointer == NULL)
|
||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||
|
||||
if (!TopValue->IsLValue)
|
||||
ProgramFail(Parser, "can't assign to this");
|
||||
|
||||
switch (Op) {
|
||||
case TokenIncrement:
|
||||
TopValue->Val->Pointer =
|
||||
(void*)((char*)TopValue->Val->Pointer+Size);
|
||||
break;
|
||||
case TokenDecrement:
|
||||
TopValue->Val->Pointer =
|
||||
(void*)((char*)TopValue->Val->Pointer-Size);
|
||||
break;
|
||||
default:
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
break;
|
||||
}
|
||||
|
||||
ResultPtr = TopValue->Val->Pointer;
|
||||
StackValue = ExpressionStackPushValueByType(Parser, StackTop,
|
||||
TopValue->Typ);
|
||||
StackValue->Val->Pointer = ResultPtr;
|
||||
} else
|
||||
/* integer prefix arithmetic */
|
||||
long ResultInt = 0;
|
||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||
switch (Op) {
|
||||
case TokenPlus:
|
||||
ResultInt = TopInt;
|
||||
break;
|
||||
case TokenMinus:
|
||||
ResultInt = -TopInt;
|
||||
break;
|
||||
case TokenIncrement:
|
||||
ResultInt = ExpressionAssignInt(Parser, TopValue,
|
||||
TopInt+1, false);
|
||||
break;
|
||||
case TokenDecrement:
|
||||
ResultInt = ExpressionAssignInt(Parser, TopValue,
|
||||
TopInt-1, false);
|
||||
break;
|
||||
case TokenUnaryNot:
|
||||
ResultInt = !TopInt;
|
||||
break;
|
||||
case TokenUnaryExor:
|
||||
ResultInt = ~TopInt;
|
||||
break;
|
||||
default:
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
ExpressionPushInt(Parser, StackTop, ResultInt);
|
||||
} else if (TopValue->Typ->Base == TypePointer) {
|
||||
/* pointer prefix arithmetic */
|
||||
int Size = TypeSize(TopValue->Typ->FromType, 0, true);
|
||||
struct Value *StackValue;
|
||||
void *ResultPtr;
|
||||
if (TopValue->Val->Pointer == NULL)
|
||||
ProgramFail(Parser, "a. invalid use of a NULL pointer");
|
||||
if (!TopValue->IsLValue)
|
||||
ProgramFail(Parser, "can't assign to this");
|
||||
switch (Op) {
|
||||
case TokenIncrement:
|
||||
TopValue->Val->Pointer =
|
||||
(void*)((char*)TopValue->Val->Pointer+Size);
|
||||
break;
|
||||
case TokenDecrement:
|
||||
TopValue->Val->Pointer =
|
||||
(void*)((char*)TopValue->Val->Pointer-Size);
|
||||
break;
|
||||
default:
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
break;
|
||||
}
|
||||
ResultPtr = TopValue->Val->Pointer;
|
||||
StackValue = ExpressionStackPushValueByType(Parser, StackTop,
|
||||
TopValue->Typ);
|
||||
StackValue->Val->Pointer = ResultPtr;
|
||||
} else {
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,8 +807,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser,
|
|||
break;
|
||||
}
|
||||
ExpressionPushFP(Parser, StackTop, ResultFP);
|
||||
}
|
||||
else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||
long ResultInt = 0;
|
||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||
switch (Op) {
|
||||
|
@ -840,7 +835,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser,
|
|||
void *OrigPointer = TopValue->Val->Pointer;
|
||||
|
||||
if (TopValue->Val->Pointer == NULL)
|
||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||
ProgramFail(Parser, "b. invalid use of a NULL pointer");
|
||||
|
||||
if (!TopValue->IsLValue)
|
||||
ProgramFail(Parser, "can't assign to this");
|
||||
|
@ -859,8 +854,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser,
|
|||
StackValue = ExpressionStackPushValueByType(Parser, StackTop,
|
||||
TopValue->Typ);
|
||||
StackValue->Val->Pointer = OrigPointer;
|
||||
}
|
||||
else
|
||||
} else
|
||||
ProgramFail(Parser, "invalid operation");
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1115,7 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
|||
|
||||
Pointer = BottomValue->Val->Pointer;
|
||||
if (Pointer == NULL)
|
||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||
ProgramFail(Parser, "c. invalid use of a NULL pointer");
|
||||
|
||||
if (Op == TokenPlus)
|
||||
Pointer = (void*)((char*)Pointer + TopInt * Size);
|
||||
|
@ -1142,7 +1136,7 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
|||
|
||||
Pointer = BottomValue->Val->Pointer;
|
||||
if (Pointer == NULL)
|
||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||
ProgramFail(Parser, "d. invalid use of a NULL pointer");
|
||||
|
||||
if (Op == TokenAddAssign)
|
||||
Pointer = (void*)((char*)Pointer + TopInt * Size);
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef FILE IOFILE;
|
|||
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
|
||||
#define FP_VAL(v) ((v)->Val->FP)
|
||||
|
||||
/* ap -> AllowPointerCoercion = true | false*/
|
||||
#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0)
|
||||
#define POINTER_COERCE(v) ((int)(v)->Val->Pointer)
|
||||
|
||||
|
@ -281,7 +282,7 @@ struct Value
|
|||
char ValOnStack; /* the AnyValue is on the stack along with this Value */
|
||||
char AnyValOnHeap; /* the AnyValue is separately allocated from the Value on the heap */
|
||||
char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */
|
||||
int ScopeID; /* to know when it goes out of scope */
|
||||
int ScopeID; /* to know when it goes out of scope */
|
||||
char OutOfScope;
|
||||
};
|
||||
|
||||
|
|
6
parse.c
6
parse.c
|
@ -583,13 +583,11 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
|||
struct Value *VarValue;
|
||||
struct ParseState PreState;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
/* if we're debugging, check for a breakpoint */
|
||||
if (Parser->DebugMode && Parser->Mode == RunModeRun)
|
||||
#ifdef DEBUGGER
|
||||
DebugCheckStatement(Parser)
|
||||
DebugCheckStatement(Parser);
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
/* take note of where we are and then grab a token to see what
|
||||
statement we have */
|
||||
|
|
2
picoc.c
2
picoc.c
|
@ -25,7 +25,7 @@ int main(int argc, char **argv)
|
|||
printf(PICOC_VERSION " \n"
|
||||
"Format: picoc <file1.c>... [- <arg1>...] : run a program (calls main() to start it)\n"
|
||||
" picoc -s <file1.c>... [- <arg1>...] : script mode - runs the program without calling main()\n"
|
||||
" picoc -i : interactive mode\n");
|
||||
" picoc -i : interactive mode (Ctrl+D to exit)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#define LOCAL_TABLE_SIZE (11) /* size of local variable table (can expand) */
|
||||
#define STRUCT_TABLE_SIZE (11) /* size of struct/union member table (can expand) */
|
||||
|
||||
#define INTERACTIVE_PROMPT_START "starting picoc " PICOC_VERSION "\n"
|
||||
#define INTERACTIVE_PROMPT_START "starting picoc " PICOC_VERSION " (Ctrl+D to exit)\n"
|
||||
#define INTERACTIVE_PROMPT_STATEMENT "picoc> "
|
||||
#define INTERACTIVE_PROMPT_LINE " > "
|
||||
|
||||
|
|
Loading…
Reference in a new issue