/* * Copyright (c) 2014, Claudio Lapilli and the newRPL Team * All rights reserved. * This file is released under the 3-clause BSD license. * See the file LICENSE.txt that shipped with this distribution. */ #include "newrpl.h" #include "libraries.h" #include "hal.h" // THIS LIBRARY PROVIDES COMPILATION OF STACK RELATED COMMANDS AND OTHER BASIC COMMANDS // THERE'S ONLY ONE EXTERNAL FUNCTION: THE LIBRARY HANDLER // ALL OTHER FUNCTIONS ARE LOCAL // MAIN LIBRARY NUMBER, CHANGE THIS FOR EACH LIBRARY #define LIBRARY_NUMBER 24 #define LIB_ENUM lib24enum #define LIB_NAMES lib24_names #define LIB_HANDLER lib24_handler #define LIB_NUMBEROFCMDS LIB24_NUMBEROFCMDS // LIST OF COMMANDS EXPORTED, CHANGE FOR EACH LIBRARY #define CMD_LIST \ CMD(GARBAGE), \ CMD(CLEAR), \ CMD(DEPTH), \ CMD(DROP), \ CMD(DROP2), \ CMD(DROPN), \ CMD(DUP), \ CMD(DUP2), \ CMD(DUPDUP), \ CMD(DUPN), \ CMD(NDUPN), \ CMD(NIP), \ CMD(OVER), \ CMD(PICK), \ CMD(PICK3), \ CMD(ROLL), \ CMD(ROLLD), \ CMD(ROT), \ CMD(SWAP), \ CMD(UNPICK), \ CMD(UNROT) // ADD MORE OPCODES HERE // EXTRA LIST FOR COMMANDS WITH SYMBOLS THAT ARE DISALLOWED IN AN ENUM // THE NAMES AND ENUM SYMBOLS ARE GIVEN SEPARATELY #define CMD_EXTRANAME \ "" #define CMD_EXTRAENUM \ UNPROTECTSTACK // INTERNAL DECLARATIONS // CREATE AN ENUM WITH THE OPCODE NAMES FOR THE DISPATCHER #define CMD(a) a enum LIB_ENUM { CMD_LIST , CMD_EXTRAENUM , LIB_NUMBEROFCMDS }; #undef CMD // AND A LIST OF STRINGS WITH THE NAMES FOR THE COMPILER #define CMD(a) #a const char * const LIB_NAMES[]= { CMD_LIST , CMD_EXTRANAME }; #undef CMD const WORD const unprotect_seco[]={ MKPROLOG(DOCOL,2), MKOPCODE(LIBRARY_NUMBER,UNPROTECTSTACK), CMD_SEMI }; void LIB_HANDLER() { if(ISPROLOG(CurOpcode)) { // THIS LIBRARY DOES NOT DEFINE ANY OBJECTS Exceptions=EX_BADOPCODE; ExceptionPointer=IPtr; return; } switch(OPCODE(CurOpcode)) { case GARBAGE: rplGCollect(); return; case CLEAR: // ONLY CLEAR UP TO THE STACK PROTECTED AREA // DON'T THROW AN ERROR DSTop=DStkProtect; return; case DEPTH: rplNewBINTPush(rplDepthData(),DECBINT); return; case DROP: rplDropData(1); return; case DROP2: rplDropData(2); return; case DROPN: { if(rplDepthData()<1) { Exceptions|=EX_BADARGCOUNT; ExceptionPointer=IPtr; return; } BINT64 count=rplReadNumberAsBINT(rplPeekData(1)); if(Exceptions) return; if(count<0 || rplDepthData()=MIN_RESERVED_OPCODE) { RetNum=ERR_NOTMINE; return; } // BY DEFAULT, ISSUE A BAD OPCODE ERROR Exceptions|=EX_BADOPCODE; ExceptionPointer=IPtr; return; }