├── LICENSE ├── Makefile.win ├── Pocket C.zip ├── README.md ├── config.ini ├── def.h ├── lib.h ├── mandelbrot.pc ├── p.pc ├── pc.c ├── pc.o ├── pocketc.dev ├── pocketc.layout └── pocketc_examples ├── graph.pc ├── graphs.pc ├── primes.pc ├── quicksort.pc └── swap.pc /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile.win: -------------------------------------------------------------------------------- 1 | # Project: pocketc 2 | # Makefile created by Dev-C++ 4.9.9.2 3 | 4 | CPP = g++.exe 5 | CC = gcc.exe 6 | WINDRES = windres.exe 7 | RES = 8 | OBJ = pc.o $(RES) 9 | LINKOBJ = pc.o $(RES) 10 | LIBS = -L"C:/Dev-Cpp/lib" -fmessage-length=0 11 | INCS = -I"C:/Dev-Cpp/include" 12 | CXXINCS = -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" 13 | BIN = pocketc.exe 14 | CXXFLAGS = $(CXXINCS) -fmessage-length=0 15 | CFLAGS = $(INCS) -fmessage-length=0 16 | RM = rm -f 17 | 18 | .PHONY: all all-before all-after clean clean-custom 19 | 20 | all: all-before pocketc.exe all-after 21 | 22 | 23 | clean: clean-custom 24 | ${RM} $(OBJ) $(BIN) 25 | 26 | $(BIN): $(OBJ) 27 | $(CC) $(LINKOBJ) -o "pocketc.exe" $(LIBS) 28 | 29 | pc.o: pc.c 30 | $(CC) -c pc.c -o pc.o $(CFLAGS) 31 | -------------------------------------------------------------------------------- /Pocket C.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pconst167/c-interpreter/b449ef3a347491a146ff7d4ba4e5839b97c0e460/Pocket C.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A C Interpreter 2 | A C interpreter with a good subset of the C language. Includes matrices and pointers. 3 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [editor] 2 | word_wrap=1 3 | tabela_ascii=0 4 | cor=clWhite 5 | [fonte] 6 | nome=Courier New 7 | tamanho=10 8 | cor=clBlack 9 | negrito=0 10 | italico=0 11 | sublinhado=0 12 | riscado=0 13 | [janela] 14 | largura=1696 15 | altura=931 16 | left=-8 17 | top=-8 18 | maximizado=1 19 | -------------------------------------------------------------------------------- /def.h: -------------------------------------------------------------------------------- 1 | #define STRUCT_TABLE_SIZE 50 2 | #define MAX_STRUCT_MEMBERS 10 3 | #define STRING_TABLE_SIZE 250 4 | #define MAX_USER_FUNC 50 5 | #define MAX_USER_FUNC_CALLS 1000 6 | #define MAX_USER_FUNC_PARAMS 10 7 | #define MAX_GLOBAL_VARS 50 8 | #define MAX_LOCAL_VARS 200 9 | #define ID_LEN 50 10 | #define MAX_MATRIX_DIMS 10 11 | #define CONST_LEN 500 12 | #define PROG_SIZE 99999 13 | #define ACTIVE_FUNC_TABLE_SIZE 250 14 | #define ACTIVE_CONST_TABLE_SIZE 250 15 | 16 | #define TRUE 1 17 | #define FALSE 0 18 | 19 | struct s1{ 20 | int i; 21 | }; 22 | struct hah{ 23 | struct s1 hey[100]; 24 | }; 25 | 26 | typedef void(*_FPTR)(void); 27 | 28 | typedef struct { 29 | char *func_name; 30 | _FPTR fp; 31 | } _LIB; 32 | 33 | typedef enum { 34 | DIRECTIVE = 1, INCLUDE, 35 | 36 | VOID, CHAR, INT, FLOAT, DOUBLE, 37 | SHORT, LONG, SIGNED, UNSIGNED, 38 | 39 | STRUCT, STRUCT_DOT, STRUCT_ARROW, 40 | ENUM, 41 | 42 | IF, THEN, ELSE, FOR, DO, WHILE, BREAK, CONTINUE, SWITCH, CASE, DEFAULT, RETURN, CONST, 43 | SIZEOF, 44 | 45 | PLUS, MINUS, ASTERISK, DIVISION, INCREMENT, DECREMENT, MOD, 46 | 47 | EQUAL, NOT_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL, 48 | LOGICAL_AND, LOGICAL_OR, LOGICAL_NOT, 49 | ATTRIBUTION, 50 | 51 | BITWISE_AND, BITWISE_OR, BITWISE_NOT, BITWISE_SL, BITWISE_SR, POINTER_REF, 52 | 53 | OPENING_PAREN, CLOSING_PAREN, 54 | OPENING_BRACE, CLOSING_BRACE, 55 | OPENING_BRACKET, CLOSING_BRACKET, 56 | 57 | SEMICOLON, COMMA 58 | } _ATOM; // internal token representation 59 | _ATOM tok; 60 | 61 | typedef enum { 62 | DELIMITER = 1, 63 | CHAR_CONST, STRING_CONST, INTEGER_CONST, FLOAT_CONST, DOUBLE_CONST, 64 | IDENTIFIER, RESERVED, END 65 | } _ATOM_TYPE; 66 | _ATOM_TYPE token_type; 67 | 68 | typedef enum { 69 | JF_NULL, 70 | JF_BREAK, 71 | JF_CONTINUE, 72 | JF_RETURN 73 | } _JUMP_FLAG; 74 | 75 | typedef union { 76 | char c; 77 | short int si; 78 | int i; 79 | long int li; 80 | long long int lli; 81 | float f; 82 | double d; 83 | long double ld; 84 | void *p; 85 | } _VALUE; 86 | 87 | // basic data types 88 | typedef enum { 89 | DT_VOID = 1, DT_CHAR, DT_INT, DT_FLOAT, DT_DOUBLE, DT_STRUCT 90 | } _BASIC_DATA; 91 | 92 | typedef enum { 93 | mSIGNED = 1, mUNSIGNED, mSHORT, mLONG 94 | } _MODIFIER; 95 | 96 | typedef struct { 97 | _BASIC_DATA type; 98 | _MODIFIER smodf, lmodf, modf3; 99 | _VALUE value; 100 | int ind_level; // holds the pointer indirection level 101 | } _DATA; 102 | 103 | typedef struct { 104 | char *str; 105 | _DATA data; 106 | } _CONST; 107 | 108 | typedef struct { 109 | char struct_name[ID_LEN + 1]; 110 | int total_mem; 111 | struct{ 112 | char field_name[ID_LEN + 1]; 113 | _BASIC_DATA type; 114 | int ind_level; 115 | int dims[MAX_MATRIX_DIMS + 1]; 116 | int offset; 117 | void *field_struct_pointer; // in case this member is a struct itself, this is a pointer to the details about the struct 118 | } fields[MAX_STRUCT_MEMBERS + 1]; 119 | } _STRUCT; 120 | _STRUCT struct_table[STRUCT_TABLE_SIZE + 1]; 121 | 122 | // this is a special struct definition. it is used as a return from the function that calculates offsets of matrices or structs. 123 | typedef struct{ 124 | _BASIC_DATA datatype; 125 | int ind_level; // this is necessary, because _BASIC_DATA does not include pointers. so in case the variable is a pointer, this field will indicate it. 126 | int offset; // the position of the variable inside a matrix or struct. 127 | } _DATA_TYPE_OFFSET; 128 | 129 | typedef struct { 130 | char var_name[ID_LEN]; 131 | _DATA data; // holds the type of data and the value itself 132 | int dims[MAX_MATRIX_DIMS + 1]; 133 | char constant; 134 | _STRUCT *structptr; // in case this variable is a struct 135 | } _VAR; 136 | _VAR global_variables[MAX_GLOBAL_VARS], local_variables[MAX_LOCAL_VARS]; 137 | 138 | typedef struct { 139 | char func_name[ID_LEN]; 140 | _BASIC_DATA return_type; 141 | char *code_location; 142 | struct{ // holds information about each of the defined parameters, for later use when the function is called 143 | char param_name[ID_LEN]; 144 | _BASIC_DATA type; 145 | char constant; 146 | int ind_level; // if the parameter is a pointer 147 | } parameters[MAX_USER_FUNC_PARAMS + 1]; // one extra to mark the end of the list 148 | } _USER_FUNC; 149 | _USER_FUNC user_func_table[MAX_USER_FUNC]; 150 | 151 | struct _keyword_table{ 152 | char *keyword; 153 | _ATOM key; 154 | } keyword_table[] = { 155 | "void", VOID, 156 | "char", CHAR, 157 | "int", INT, 158 | "float", FLOAT, 159 | "double", DOUBLE, 160 | "const", CONST, 161 | "enum", ENUM, 162 | "struct", STRUCT, 163 | "sizeof", SIZEOF, 164 | "return", RETURN, 165 | "if", IF, 166 | "then", THEN, 167 | "else", ELSE, 168 | "for", FOR, 169 | "do", DO, 170 | "break", BREAK, 171 | "continue", CONTINUE, 172 | "while", WHILE, 173 | "switch", SWITCH, 174 | "case", CASE, 175 | "default", DEFAULT, 176 | "include", INCLUDE, 177 | "", 0 178 | }; 179 | 180 | typedef enum { 181 | SYNTAX, 182 | OPENING_PAREN_EXPECTED, 183 | CLOSING_PAREN_EXPECTED, 184 | OPENING_BRACE_EXPECTED, 185 | CLOSING_BRACE_EXPECTED, 186 | OPENING_BRACKET_EXPECTED, 187 | CLOSING_BRACKET_EXPECTED, 188 | COMMA_EXPECTED, 189 | SEMICOLON_EXPECTED, 190 | VAR_TYPE_EXPECTED, 191 | IDENTIFIER_EXPECTED, 192 | EXCEEDED_GLOBAL_VAR_LIMIT, 193 | EXCEEDED_FUNC_DECL_LIMIT, 194 | NOT_VAR_OR_FUNC_OUTSIDE, 195 | NO_MAIN_FOUND, 196 | UNDECLARED_FUNC, 197 | SINGLE_QUOTE_EXPECTED, 198 | DOUBLE_QUOTE_EXPECTED, 199 | UNDECLARED_VARIABLE, 200 | MAX_PARAMS_LIMIT_REACHED, 201 | USER_FUNC_CALLS_LIMIT_REACHED, 202 | LOCAL_VAR_LIMIT_REACHED, 203 | RETURNING_VALUE_FROM_VOID_FUNCTION, 204 | INVALID_EXPRESSION, 205 | INVALID_ARGUMENT_FOR_BITWISE_NOT, 206 | WHILE_KEYWORD_EXPECTED, 207 | DUPLICATE_GLOBAL_VARIABLE, 208 | DUPLICATE_LOCAL_VARIABLE, 209 | STRING_CONSTANT_EXPECTED, 210 | POINTER_EXPECTED, 211 | INSUFFICIENT_ARGUMENTS, 212 | POINTER_SYNTAX, 213 | TOO_MANY_MATRIX_DIMENSIONS, 214 | INVALID_MATRIX_DIMENSION, 215 | MEMORY_ALLOCATION_FAILURE, 216 | MATRIX_INDEX_OUTSIDE_BOUNDS, 217 | INVALID_MATRIX_ATTRIBUTION, 218 | MATRIX_EXPECTED, 219 | UNKOWN_LIBRARY, 220 | UNKNOWN_DIRECTIVE, 221 | DIRECTIVE_SYNTAX, 222 | INCOMPATIBLE_FUNCTION_ARGUMENT, 223 | CONSTANT_VARIABLE_ASSIGNMENT, 224 | INVALID_BINARY_OPERANDS, 225 | STRUCT_EXPECTED, 226 | STRUCT_NAME_EXPECTED, 227 | UNDECLARED_STRUCT, 228 | INVALID_PRINTF_FORMAT_CODE 229 | } _ERROR; 230 | 231 | // variable declaration 232 | char *error_table[] = { 233 | "syntax error", 234 | "syntax error: opening parenthesis expected", 235 | "syntax error: closing parenthesis expected", 236 | "syntax error: opening brace expected", 237 | "syntax error: closing brace expected", 238 | "syntax error: opening bracket expected", 239 | "syntax error: closing bracket expected", 240 | "syntax error: comma expected", 241 | "syntax error: semicolon expected", 242 | "syntax error: variable type expected in the declaration", 243 | "syntax error: identifier expected", 244 | "global variable limit reached (max = 100)", 245 | "function declaration limit reached (max = 100)", 246 | "syntax error: only variable and function declarations are allowed outside of functions", 247 | "main funtion not found", 248 | "undeclared function", 249 | "syntax error: single quote expected", 250 | "syntax error: double quotes expected", 251 | "undeclared variable or unkown constant", 252 | "maximum number of function paramters reached (max = 10)", 253 | "maximum number of program-defined function calls reached (max = 100)", 254 | "local variables limit reached (max = 200)", 255 | "returning value from void function", 256 | "invalid expression", 257 | "invalid argument for the bitwise not operation", 258 | "while part of do-while loop expected", 259 | "duplicate global variable declared", 260 | "duplicate local variable declared", 261 | "string constant expected", 262 | "pointer expected", 263 | "insufficient function arguments", 264 | "pointer syntax error", 265 | "declared matrix exceeds the maximum number of dimensions (max = 10)", 266 | "invalid matrix dimension", 267 | "memory allocation failure", 268 | "matrix index outside bounds", 269 | "invalid matrix attribution", 270 | "matrix expected", 271 | "unkown library", 272 | "unknown directive", 273 | "directive syntax error", 274 | "incompatible function argument", 275 | "constant variable assignment", 276 | "invalid binary operands", 277 | "struct expected", 278 | "struct name expected but token is not an identifier for any structs", 279 | "undeclared struct", 280 | "invalid printf format code" 281 | }; 282 | 283 | // a table to hold library function entries that have been added by #include 284 | struct{ 285 | char func_name[ID_LEN + 1]; 286 | _FPTR fp; 287 | } active_func_table[ACTIVE_FUNC_TABLE_SIZE + 1]; 288 | 289 | struct{ 290 | char str[ID_LEN + 1]; 291 | _DATA data; 292 | } active_const_table[ACTIVE_CONST_TABLE_SIZE + 1]; 293 | 294 | int active_func_table_tos; 295 | int active_const_table_tos; 296 | 297 | char *string_table[STRING_TABLE_SIZE]; 298 | int string_table_tos; 299 | 300 | jmp_buf ebuf; 301 | 302 | int struct_table_index; 303 | 304 | int current_func_index; 305 | int user_func_table_tos; 306 | int user_func_call_index; // holds the current function call count (for use with the local stack history array 307 | int local_var_tos_history[MAX_USER_FUNC_CALLS]; // holds the previous local variable stack upper bound; 308 | int local_var_tos; // holds the current local variable stack upper bound; 309 | int global_var_tos; 310 | 311 | char token[CONST_LEN + 2]; // string token representation 312 | char string_constant[CONST_LEN + 2]; // holds string and char constants without quotes and with escape sequences converted into the correct bytes 313 | char *prog; // pointer to the current program position 314 | char *pbuf; // pointer to the beginning of the source code 315 | _DATA func_ret; // holds the value returned by the last function called 316 | 317 | // ********** flags *********** 318 | _JUMP_FLAG jump_flag; 319 | // ******************** 320 | 321 | // functions 322 | char isdelim(char c); 323 | char is_idchar(char c); 324 | int find_keyword(char *keyword); 325 | _VAR *find_variable(char *var_name); 326 | int find_local_var(char *var_name); 327 | int find_global_var(char *var_name); 328 | void local_push(_VAR *var); 329 | void load_program(char *filename); 330 | void free_mem(void); 331 | void initial_setup(void); 332 | void pre_scan(void); 333 | void declare_func(void); 334 | void declare_global(void); 335 | void declare_local(void); 336 | void declare_struct(void); 337 | _STRUCT *find_struct(char *struct_name); 338 | void get_token(void); 339 | void show_error(_ERROR e); 340 | void find_end_of_BLOCK(void); 341 | void find_end_of_block(void); 342 | void putback(void); 343 | 344 | _FPTR find_lib_func(char *func_name); 345 | _DATA get_var_value(char *var_name); 346 | void assign_var(char *var_name, _DATA *data); 347 | void incr_var(char *var_name); 348 | void decr_var(char *var_name); 349 | void *get_var_address(char *var_name); 350 | char get_var_type(char *var_name); 351 | char is_matrix(char *var_name); 352 | 353 | _DATA_TYPE_OFFSET get_var_offset(char *var_name); 354 | 355 | void eval(_DATA *v); 356 | void eval_attrib(_DATA *v); 357 | void eval_logical(_DATA *v); 358 | void eval_relational(_DATA *v); 359 | void eval_terms(_DATA *v); 360 | void eval_factors(_DATA *v); 361 | void eval_matrix(_DATA *v); 362 | void eval_atom(_DATA *v); 363 | void unary_minus(_DATA *v); 364 | void unary_logical_not(_DATA *v); 365 | void unary_bitwise_not(_DATA *v); 366 | void unary_sizeof(_DATA *v); 367 | void cast(_DATA *data, _ATOM type, int ind_level); 368 | 369 | void interp_block(void); 370 | int find_user_func(char *func_name); 371 | void call_func(int func_index); 372 | void call_lib_func(_FPTR fp); 373 | void execute_main(void); 374 | void get_func_parameters(int func_index); 375 | void operate(_DATA *v1, _DATA *v2, _ATOM op); 376 | void promote(_DATA *v1, _DATA *v2); 377 | void convert_constant(void); 378 | void convert_data(_DATA *data_to_convert, _BASIC_DATA into_type); 379 | char is_pointer(_DATA *data); 380 | char get_ind_level(char *var_name); 381 | _VAR *get_var_pointer(char *var_name); 382 | char get_data_size(_DATA *data); 383 | int get_data_size2(_BASIC_DATA type); 384 | char matrix_dim_count(_VAR *var); 385 | int get_matrix_offset(char dim, _VAR *matrix); 386 | char _is_matrix(_VAR *var); 387 | char *add_string(void); 388 | void free_string_table(void); 389 | 390 | void exec_if(void); 391 | void exec_for(void); 392 | void exec_do(void); 393 | void exec_while(void); 394 | void exec_switch(void); 395 | void exec_break(void); 396 | void exec_continue(void); 397 | 398 | void include_lib(char *lib_name); 399 | _STRUCT *get_struct_table_pointer(char *struct_name); 400 | _DATA get_constant(char *str); 401 | -------------------------------------------------------------------------------- /lib.h: -------------------------------------------------------------------------------- 1 | _CONST math_const_table[] = { 2 | "_PI", DT_DOUBLE, 0, 0, 0, {.d = 3.14159265358979323846264338327950288}, 0, 3 | "_PI_2", DT_DOUBLE, 0, 0, 0, {.d = 1.5707963267948966}, 0, 4 | "_PI_4", DT_DOUBLE, 0, 0, 0, {.d = 0.7853981633974483}, 0, 5 | "_E", DT_DOUBLE, 0, 0, 0, {.d = 2.71828182845904523536028747135266249}, 0, 6 | "_SQRT2", DT_DOUBLE, 0, 0, 0, {.d = 1.41421356237309504880168872420969807}, 0, 7 | "_SQRT3", DT_DOUBLE, 0, 0, 0, {.d = 1.73205080756887729352744634150587236}, 0, 8 | "_SQRT5", DT_DOUBLE, 0, 0, 0, {.d = 2.23606797749978969640917366873127623}, 0, 9 | "_EULER_GAMMA", DT_DOUBLE, 0, 0, 0, {.d = 0.57721566490153286060651209008240243}, 0, 10 | "_GOLDEN_RATIO", DT_DOUBLE, 0, 0, 0, {.d = 1.61803398874989484820458683436563811}, 0, 11 | "_ZETA2", DT_DOUBLE, 0, 0, 0, {.d = 1.64493406684822643647241516664602518}, 0, 12 | "_ZETA3", DT_DOUBLE, 0, 0, 0, {.d = 1.20205690315959428539973816151144999}, 0, 13 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 14 | }; 15 | 16 | _CONST stdio_const_table[] = { 17 | "NULL", DT_VOID, 0, 0, 0, {.p = NULL}, 1, 18 | "EOF", DT_INT, 0, 0, 0, {.i = EOF}, 0, 19 | "FOPEN_MAX", DT_INT, 0, 0, 0, {.i = FOPEN_MAX}, 0, 20 | "SEEK_SET", DT_INT, 0, 0, 0, {.i = SEEK_SET}, 0, 21 | "SEEK_CUR", DT_INT, 0, 0, 0, {.i = SEEK_CUR}, 0, 22 | "SEEK_END", DT_INT, 0, 0, 0, {.i = SEEK_END}, 0, 23 | "FILENAME_MAX", DT_INT, 0, 0, 0, {.i = FILENAME_MAX}, 0, 24 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 25 | }; 26 | 27 | _CONST stdlib_const_table[] = { 28 | "RAND_MAX", DT_INT, 0, 0, 0, {.i = RAND_MAX}, 0, 29 | "EXIT_SUCCESS", DT_INT, 0, 0, 0, {.i = EXIT_SUCCESS}, 0, 30 | "EXIT_FAILURE", DT_INT, 0, 0, 0, {.i = EXIT_FAILURE}, 0 , 31 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 32 | }; 33 | 34 | _CONST stdbool_const_table[] = { 35 | "true", DT_INT, 0, 0, 0, {.i = 1}, 0, 36 | "false", DT_INT, 0, 0, 0, {.i = 0}, 0, 37 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 38 | }; 39 | 40 | _CONST time_const_table[] = { 41 | "CLOCKS_PER_SEC", DT_INT, 0, 0, 0, {.i = CLOCKS_PER_SEC}, 0, 42 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 43 | }; 44 | 45 | _CONST conio_const_table[] = { 46 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 47 | }; 48 | 49 | _CONST string_const_table[] = { 50 | "", DT_INT, 0, 0, 0, {.i = 0}, 0 51 | }; 52 | 53 | // stdio 54 | void call_putchar(void); 55 | void call_getchar(void); 56 | void call_puts(void); 57 | void call_printf(void); 58 | void call_scanf(void); 59 | void call_gets(void); 60 | void call_fopen(void); 61 | void call_fclose(void); 62 | void call_fputc(void); 63 | void call_fgetc(void); 64 | void call_feof(void); 65 | void call_fseek(void); 66 | void call_ferror(void); 67 | void call_rewind(void); 68 | void call_remove(void); 69 | void call_ftell(void); 70 | void call_fflush(void); 71 | 72 | // stdlib 73 | void call_system(void); 74 | void call_malloc(void); 75 | void call_free(void); 76 | void call_rand(void); 77 | 78 | // string 79 | void call_strlen(void); 80 | void call_strchr(void); 81 | void call_strstr(void); 82 | void call_strcat(void); 83 | void call_strcpy(void); 84 | void call_strcmp(void); 85 | 86 | // math 87 | void call_sin(void); 88 | void call_cos(void); 89 | void call_tan(void); 90 | void call_asin(void); 91 | void call_acos(void); 92 | void call_atan(void); 93 | void call_atan2(void); 94 | void call_ln(void); 95 | void call_log(void); 96 | void call_exp(void); 97 | void call_sinh(void); 98 | void call_asinh(void); 99 | void call_cosh(void); 100 | void call_acosh(void); 101 | void call_tanh(void); 102 | void call_atanh(void); 103 | void call_sqrt(void); 104 | void call_ceil(void); 105 | void call_floor(void); 106 | void call_max(void); 107 | void call_min(void); 108 | void call_trunc(void); 109 | void call_round(void); 110 | void call_abs(void); 111 | void call_eval(void); 112 | void call_pow(void); 113 | void call_erf(void); 114 | void call_gamma(void); 115 | void call_zeta(void); 116 | void call_avrg(void); 117 | void call_todeg(void); 118 | void call_torad(void); 119 | void call_signum(void); 120 | void call_fact(void); 121 | void call_iseven(void); 122 | void call_isodd(void); 123 | void call_isprime(void); 124 | void call_nCk(void); 125 | 126 | int factorial(int N); 127 | 128 | // conio 129 | void call_kbhit(void); 130 | void call_getch(void); 131 | void call_getche(void); 132 | void call_clrscr(void); 133 | void call_putch(void); 134 | 135 | void call_asctime(void); 136 | void call_clock(void); 137 | void call_time(void); 138 | 139 | _LIB stdio_lib[] = { 140 | "putchar", call_putchar, 141 | "getchar", call_getchar, 142 | "puts", call_puts, 143 | "printf", call_printf, 144 | "scanf", call_scanf, 145 | "gets", call_gets, 146 | "fopen", call_fopen, 147 | "fclose", call_fclose, 148 | "feof", call_feof, 149 | "fputc", call_fputc, 150 | "fgetc", call_fgetc, 151 | "fseek", call_fseek, 152 | "ftell", call_ftell, 153 | "ferror", call_ferror, 154 | "rewind", call_rewind, 155 | "remove", call_remove, 156 | "fflush", call_fflush, 157 | "", 0 158 | }; 159 | 160 | _LIB stdlib_lib[] = { 161 | "malloc", call_malloc, 162 | "free", call_free, 163 | "system", call_system, 164 | "rand", call_rand, 165 | "", 0 166 | }; 167 | 168 | _LIB math_lib[] = { 169 | "sin", call_sin, 170 | "asin", call_asin, 171 | "cos", call_cos, 172 | "acos", call_acos, 173 | "tan", call_tan, 174 | "atan", call_atan, 175 | "atan2", call_atan2, 176 | 177 | "sinh", call_sinh, 178 | "asinh", call_asinh, 179 | "cosh", call_cosh, 180 | "acosh", call_acosh, 181 | "tanh", call_tanh, 182 | 183 | "sqrt", call_sqrt, 184 | "pow", call_pow, 185 | 186 | "ln", call_ln, 187 | "log", call_log, 188 | "exp", call_exp, 189 | 190 | "trunc", call_trunc, 191 | "round", call_round, 192 | "abs", call_abs, 193 | "ceil", call_ceil, 194 | "floor", call_floor, 195 | "max", call_max, 196 | "min", call_min, 197 | 198 | "eval", call_eval, 199 | 200 | "gamma", call_gamma, 201 | "erf", call_erf, 202 | "zeta", call_zeta, 203 | 204 | "avrg", call_avrg, 205 | 206 | "todeg", call_todeg, 207 | "torad", call_torad, 208 | "fact", call_fact, 209 | "signum", call_signum, 210 | "isodd", call_isodd, 211 | "iseven", call_iseven, 212 | "isprime", call_isprime, 213 | "nCk", call_nCk, 214 | 215 | "", 0 216 | }; 217 | 218 | _LIB string_lib[] = { 219 | "strlen", call_strlen, 220 | "strchr", call_strchr, 221 | "strstr", call_strstr, 222 | "strcat", call_strcat, 223 | "strcpy", call_strcpy, 224 | "strcmp", call_strcmp, 225 | "", 0 226 | }; 227 | 228 | _LIB conio_lib[] = { 229 | "kbhit", call_kbhit, 230 | "getch", call_getch, 231 | "putch", call_putch, 232 | "getche", call_getche, 233 | "clrscr", call_clrscr, 234 | "", 0 235 | }; 236 | 237 | _LIB time_lib[] = { 238 | "asctime", call_asctime, 239 | "clock", call_clock, 240 | "time", call_time, 241 | "", 0 242 | }; 243 | 244 | _LIB stdbool_lib[] = { 245 | "", 0 246 | }; 247 | 248 | struct{ 249 | char *lib_name; 250 | _LIB *libp; 251 | _CONST *constp; 252 | } libs[] = { 253 | "stdio", stdio_lib, stdio_const_table, 254 | "stdlib", stdlib_lib, stdlib_const_table, 255 | "math", math_lib, math_const_table, 256 | "string", string_lib, string_const_table, 257 | "conio", conio_lib, conio_const_table, 258 | "time", time_lib, time_const_table, 259 | "stdbool", stdbool_lib, stdbool_const_table, 260 | "", NULL, NULL 261 | }; 262 | 263 | void call_rand(void){ 264 | get_token(); 265 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 266 | 267 | func_ret.type = DT_INT; 268 | func_ret.ind_level = 0; 269 | func_ret.value.i = rand(); 270 | } 271 | 272 | void call_fopen(void){ 273 | char *filename, *mode; 274 | _DATA expr; 275 | 276 | eval(&expr); 277 | filename = expr.value.p; 278 | 279 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 280 | 281 | eval(&expr); 282 | mode = expr.value.p; 283 | 284 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 285 | 286 | func_ret.type = DT_VOID; 287 | func_ret.ind_level = 1; 288 | func_ret.value.p = (void *) fopen(filename, mode); 289 | } 290 | 291 | void call_fclose(void){ 292 | _DATA fp; 293 | 294 | eval(&fp); 295 | 296 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 297 | 298 | func_ret.type = DT_INT; 299 | func_ret.ind_level = 0; 300 | func_ret.value.i = fclose(fp.value.p); 301 | } 302 | 303 | void call_fputc(void){ 304 | FILE *fp; 305 | int ch; 306 | _DATA expr; 307 | 308 | eval(&expr); 309 | convert_data(&expr, DT_INT); 310 | ch = expr.value.i; 311 | 312 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 313 | 314 | eval(&expr); 315 | fp = (FILE *) expr.value.p; 316 | 317 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 318 | 319 | func_ret.type = DT_INT; 320 | func_ret.ind_level = 0; 321 | func_ret.value.i = fputc(ch, fp); 322 | } 323 | 324 | void call_fgetc(void){ 325 | FILE *fp; 326 | int ch; 327 | _DATA expr; 328 | 329 | eval(&expr); 330 | fp = (FILE *) expr.value.p; 331 | 332 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 333 | 334 | func_ret.type = DT_INT; 335 | func_ret.ind_level = 0; 336 | func_ret.value.i = fgetc(fp); 337 | } 338 | 339 | void call_feof(void){ 340 | FILE *fp; 341 | _DATA expr; 342 | 343 | eval(&expr); 344 | fp = (FILE *) expr.value.p; 345 | 346 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 347 | 348 | func_ret.type = DT_INT; 349 | func_ret.ind_level = 0; 350 | func_ret.value.i = feof(fp); 351 | } 352 | 353 | void call_ferror(void){ 354 | FILE *fp; 355 | _DATA expr; 356 | 357 | eval(&expr); 358 | fp = (FILE *) expr.value.p; 359 | 360 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 361 | 362 | func_ret.type = DT_INT; 363 | func_ret.ind_level = 0; 364 | func_ret.value.i = ferror(fp); 365 | } 366 | 367 | void call_fseek(void){ 368 | FILE *fp; 369 | _DATA file, numbytes, origin; 370 | 371 | eval(&file); 372 | fp = (FILE *) file.value.p; 373 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 374 | 375 | eval(&numbytes); 376 | convert_data(&numbytes, DT_INT); 377 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 378 | 379 | eval(&origin); 380 | convert_data(&origin, DT_INT); 381 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 382 | 383 | func_ret.type = DT_INT; 384 | func_ret.ind_level = 0; 385 | func_ret.value.i = fseek(fp, numbytes.value.i, origin.value.i); 386 | } 387 | 388 | void call_fflush(void){ 389 | FILE *fp; 390 | _DATA expr; 391 | 392 | eval(&expr); 393 | fp = (FILE *) expr.value.p; 394 | 395 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 396 | 397 | func_ret.type = DT_INT; 398 | func_ret.ind_level = 0; 399 | func_ret.value.i = fflush(fp); 400 | } 401 | 402 | void call_remove(void){ 403 | _DATA filename; 404 | 405 | eval(&filename); 406 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 407 | 408 | func_ret.type = DT_INT; 409 | func_ret.ind_level = 0; 410 | func_ret.value.i = remove(filename.value.p); 411 | } 412 | 413 | void call_ftell(void){ 414 | _DATA file; 415 | 416 | eval(&file); 417 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 418 | 419 | func_ret.type = DT_INT; 420 | func_ret.ind_level = 0; 421 | func_ret.value.i = ftell((FILE *)file.value.p); 422 | } 423 | 424 | void call_rewind(void){ 425 | _DATA file; 426 | 427 | eval(&file); 428 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 429 | 430 | func_ret.type = DT_INT; 431 | func_ret.ind_level = 0; 432 | func_ret.value.i = 0; 433 | rewind((FILE *)file.value.p); 434 | } 435 | 436 | void call_asctime(void){ 437 | struct tm *ptr; 438 | time_t lt; 439 | 440 | get_token(); 441 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 442 | 443 | lt = time(NULL); 444 | ptr = localtime(<); 445 | 446 | func_ret.type = DT_CHAR; 447 | func_ret.ind_level = 1; 448 | 449 | func_ret.value.p = asctime(ptr); 450 | } 451 | 452 | void call_clock(void){ 453 | get_token(); 454 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 455 | func_ret.type = DT_INT; 456 | func_ret.ind_level = 0; 457 | func_ret.value.i = clock(); 458 | } 459 | 460 | void call_time(void){ 461 | _DATA ptr; 462 | 463 | eval(&ptr); 464 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 465 | 466 | func_ret.type = DT_INT; 467 | func_ret.ind_level = 0; 468 | func_ret.value.i = time((time_t *) ptr.value.p); 469 | } 470 | 471 | void call_gets(void){ 472 | _DATA sp; 473 | 474 | eval(&sp); 475 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 476 | 477 | func_ret.type = DT_CHAR; 478 | func_ret.ind_level = 1; 479 | func_ret.value.p = gets(sp.value.p); 480 | } 481 | 482 | void call_strlen(void){ 483 | _DATA p; 484 | 485 | eval(&p); 486 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 487 | 488 | func_ret.type = DT_INT; 489 | func_ret.value.i = strlen(p.value.p); 490 | } 491 | 492 | void call_strchr(void){ 493 | _DATA s, c; 494 | 495 | eval(&s); 496 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 497 | 498 | eval(&c); 499 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 500 | 501 | convert_data(&c, DT_CHAR); 502 | 503 | func_ret.type = DT_CHAR; 504 | func_ret.ind_level = 1; 505 | func_ret.value.p = strchr(s.value.p, c.value.c); 506 | } 507 | 508 | void call_strstr(void){ 509 | _DATA s1, s2; 510 | 511 | eval(&s1); 512 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 513 | 514 | eval(&s2); 515 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 516 | 517 | func_ret.type = DT_CHAR; 518 | func_ret.ind_level = 1; 519 | func_ret.value.p = strstr(s1.value.p, s2.value.p); 520 | } 521 | 522 | void call_strcat(void){ 523 | _DATA s1, s2; 524 | 525 | eval(&s1); 526 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 527 | 528 | eval(&s2); 529 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 530 | 531 | func_ret.type = DT_CHAR; 532 | func_ret.ind_level = 1; 533 | func_ret.value.p = strcat(s1.value.p, s2.value.p); 534 | } 535 | 536 | void call_strcpy(void){ 537 | _DATA s1, s2; 538 | 539 | eval(&s1); 540 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 541 | 542 | eval(&s2); 543 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 544 | 545 | func_ret.type = DT_CHAR; 546 | func_ret.ind_level = 1; 547 | func_ret.value.p = strcpy(s1.value.p, s2.value.p); 548 | } 549 | 550 | void call_strcmp(void){ 551 | _DATA s1, s2; 552 | 553 | eval(&s1); 554 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 555 | 556 | eval(&s2); 557 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 558 | 559 | func_ret.type = DT_INT; 560 | func_ret.value.i = strcmp(s1.value.p, s2.value.p); 561 | } 562 | 563 | void call_printf(void){ 564 | _DATA formatstr, expr; 565 | char *p, *q; 566 | static char format[CONST_LEN + 1]; 567 | 568 | func_ret.value.i = 0; 569 | func_ret.ind_level = 0; 570 | func_ret.type = DT_INT; 571 | 572 | eval(&formatstr); // gets a pointer to the format string 573 | if(tok == CLOSING_PAREN){ 574 | func_ret.value.i = printf(formatstr.value.p); 575 | return; 576 | } 577 | 578 | p = formatstr.value.p; 579 | q = format; 580 | 581 | while(*p){ 582 | if(*p == '%'){ 583 | p++; 584 | *q++ = '%'; 585 | while(*p && *p != '%' && *p != 'c' && *p != 'd' && *p != 'i' && *p != 'e' && *p != 'E' && *p != 'f' && *p != 'p' && *p != 's') *q++ = *p++; 586 | if(!*p) show_error(INVALID_PRINTF_FORMAT_CODE); 587 | *q++ = *p++; 588 | *q = '\0'; 589 | switch(*(q - 1)){ 590 | case '%': 591 | func_ret.value.i += putchar('%'); 592 | break; 593 | case 'c': 594 | eval(&expr); 595 | convert_data(&expr, DT_CHAR); 596 | func_ret.value.i += putchar(expr.value.c); 597 | break; 598 | case 'i': 599 | case 'd': 600 | eval(&expr); 601 | convert_data(&expr, DT_INT); 602 | func_ret.value.i += printf(format, expr.value.i); 603 | break; 604 | case 's': 605 | eval(&expr); 606 | func_ret.value.i += printf(format, expr.value.p); 607 | break; 608 | case 'p': 609 | eval(&expr); 610 | func_ret.value.i += printf(format, expr.value.p); 611 | break; 612 | case 'f': 613 | case 'E': 614 | case 'e': 615 | eval(&expr); 616 | convert_data(&expr, DT_DOUBLE); 617 | func_ret.value.i += printf(format, expr.value.d); 618 | } 619 | q = format; 620 | } 621 | else{ 622 | putchar(*p); 623 | p++; 624 | } 625 | } 626 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 627 | } 628 | 629 | void call_scanf(void){ 630 | _DATA formatstr, pointer; 631 | 632 | func_ret.type = DT_INT; 633 | 634 | eval(&formatstr); // gets a pointer to the format string 635 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 636 | 637 | eval(&pointer); 638 | scanf(formatstr.value.p, pointer.value.p); 639 | 640 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 641 | } 642 | 643 | void call_malloc(void){ 644 | _DATA size; 645 | 646 | eval(&size); 647 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 648 | convert_data(&size, DT_INT); 649 | 650 | func_ret.type = DT_VOID; 651 | func_ret.ind_level = 1; 652 | func_ret.value.p = malloc(size.value.i); 653 | } 654 | 655 | void call_free(void){ 656 | _DATA p; 657 | 658 | eval(&p); 659 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 660 | if(!is_pointer(&p)) show_error(POINTER_EXPECTED); 661 | 662 | free(p.value.p); 663 | } 664 | 665 | void call_system(void){ 666 | _DATA s; 667 | 668 | eval(&s); 669 | 670 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 671 | 672 | system(s.value.p); 673 | } 674 | 675 | void call_clrscr(void){ 676 | get_token(); 677 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 678 | 679 | system("cls"); 680 | } 681 | 682 | void call_puts(void){ 683 | _DATA s; 684 | 685 | eval(&s); 686 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 687 | 688 | puts(s.value.p); 689 | } 690 | 691 | void call_putchar(void){ 692 | eval(&func_ret); 693 | convert_data(&func_ret, DT_CHAR); 694 | 695 | putchar(func_ret.value.c); 696 | } 697 | 698 | void call_sin(void){ 699 | eval(&func_ret); 700 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 701 | 702 | convert_data(&func_ret, DT_DOUBLE); 703 | 704 | func_ret.value.d = sin(func_ret.value.d); 705 | } 706 | 707 | void call_asin(void){ 708 | eval(&func_ret); 709 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 710 | 711 | convert_data(&func_ret, DT_DOUBLE); 712 | 713 | func_ret.value.d = asin(func_ret.value.d); 714 | } 715 | 716 | void call_cos(void){ 717 | eval(&func_ret); 718 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 719 | 720 | convert_data(&func_ret, DT_DOUBLE); 721 | 722 | func_ret.value.d = cos(func_ret.value.d); 723 | } 724 | 725 | void call_acos(void){ 726 | eval(&func_ret); 727 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 728 | 729 | convert_data(&func_ret, DT_DOUBLE); 730 | 731 | func_ret.value.d = acos(func_ret.value.d); 732 | } 733 | 734 | void call_tan(void){ 735 | eval(&func_ret); 736 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 737 | 738 | convert_data(&func_ret, DT_DOUBLE); 739 | 740 | func_ret.value.d = tan(func_ret.value.d); 741 | } 742 | 743 | void call_atan(void){ 744 | eval(&func_ret); 745 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 746 | 747 | convert_data(&func_ret, DT_DOUBLE); 748 | 749 | func_ret.value.d = atan(func_ret.value.d); 750 | } 751 | 752 | void call_atan2(void){ 753 | _DATA x, y; 754 | 755 | eval(&y); 756 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 757 | eval(&x); 758 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 759 | 760 | convert_data(&y, DT_DOUBLE); 761 | convert_data(&x, DT_DOUBLE); 762 | 763 | func_ret.type = DT_DOUBLE; 764 | func_ret.value.d = atan2(y.value.d, x.value.d); 765 | func_ret.ind_level = 0; 766 | } 767 | 768 | void call_sinh(void){ 769 | eval(&func_ret); 770 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 771 | 772 | convert_data(&func_ret, DT_DOUBLE); 773 | 774 | func_ret.value.d = sinh(func_ret.value.d); 775 | } 776 | 777 | void call_asinh(void){ 778 | eval(&func_ret); 779 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 780 | 781 | convert_data(&func_ret, DT_DOUBLE); 782 | 783 | func_ret.value.d = asinh(func_ret.value.d); 784 | } 785 | 786 | void call_cosh(void){ 787 | eval(&func_ret); 788 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 789 | 790 | convert_data(&func_ret, DT_DOUBLE); 791 | 792 | func_ret.value.d = cosh(func_ret.value.d); 793 | } 794 | 795 | void call_acosh(void){ 796 | eval(&func_ret); 797 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 798 | 799 | convert_data(&func_ret, DT_DOUBLE); 800 | 801 | func_ret.value.d = acosh(func_ret.value.d); 802 | } 803 | 804 | void call_tanh(void){ 805 | eval(&func_ret); 806 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 807 | 808 | convert_data(&func_ret, DT_DOUBLE); 809 | 810 | func_ret.value.d = tanh(func_ret.value.d); 811 | } 812 | 813 | void call_atanh(void){ 814 | eval(&func_ret); 815 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 816 | 817 | convert_data(&func_ret, DT_DOUBLE); 818 | 819 | func_ret.value.d = atanh(func_ret.value.d); 820 | } 821 | 822 | void call_floor(void){ 823 | eval(&func_ret); 824 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 825 | 826 | convert_data(&func_ret, DT_DOUBLE); 827 | 828 | func_ret.value.d = floor(func_ret.value.d); 829 | } 830 | 831 | void call_ceil(void){ 832 | eval(&func_ret); 833 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 834 | 835 | convert_data(&func_ret, DT_DOUBLE); 836 | 837 | func_ret.value.d = ceil(func_ret.value.d); 838 | } 839 | 840 | void call_pow(void){ 841 | _DATA base, exp; 842 | 843 | eval(&base); 844 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 845 | eval(&exp); 846 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 847 | 848 | convert_data(&base, DT_DOUBLE); 849 | convert_data(&exp, DT_DOUBLE); 850 | 851 | func_ret.type = DT_DOUBLE; 852 | func_ret.value.d = pow(base.value.d, exp.value.d); 853 | func_ret.ind_level = 0; 854 | } 855 | 856 | void call_sqrt(void){ 857 | eval(&func_ret); 858 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 859 | 860 | convert_data(&func_ret, DT_DOUBLE); 861 | 862 | func_ret.value.d = sqrt(func_ret.value.d); 863 | } 864 | 865 | void call_erf(void){ 866 | eval(&func_ret); 867 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 868 | 869 | convert_data(&func_ret, DT_DOUBLE); 870 | 871 | func_ret.value.d = erf(func_ret.value.d); 872 | } 873 | 874 | void call_gamma(void){ 875 | eval(&func_ret); 876 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 877 | 878 | convert_data(&func_ret, DT_DOUBLE); 879 | 880 | func_ret.value.d = tgamma(func_ret.value.d); 881 | } 882 | 883 | void call_ln(void){ 884 | eval(&func_ret); 885 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 886 | 887 | convert_data(&func_ret, DT_DOUBLE); 888 | 889 | func_ret.value.d = log(func_ret.value.d); 890 | } 891 | 892 | void call_exp(void){ 893 | eval(&func_ret); 894 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 895 | 896 | convert_data(&func_ret, DT_DOUBLE); 897 | 898 | func_ret.value.d = exp(func_ret.value.d); 899 | } 900 | 901 | void call_log(void){ 902 | eval(&func_ret); 903 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 904 | 905 | convert_data(&func_ret, DT_DOUBLE); 906 | 907 | func_ret.value.d = log10(func_ret.value.d); 908 | } 909 | 910 | void call_abs(void){ 911 | eval(&func_ret); 912 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 913 | 914 | convert_data(&func_ret, DT_DOUBLE); 915 | 916 | func_ret.value.d = abs(func_ret.value.d); 917 | func_ret.ind_level = 0; 918 | } 919 | 920 | void call_todeg(void){ 921 | eval(&func_ret); 922 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 923 | 924 | convert_data(&func_ret, DT_DOUBLE); 925 | 926 | func_ret.value.d = 360 * func_ret.value.d / (2 * 3.14159265358979323846264338327950288); 927 | func_ret.ind_level = 0; 928 | } 929 | 930 | void call_torad(void){ 931 | eval(&func_ret); 932 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 933 | 934 | convert_data(&func_ret, DT_DOUBLE); 935 | 936 | func_ret.value.d = 2 * 3.14159265358979323846264338327950288 * (func_ret.value.d / 360.0); 937 | func_ret.ind_level = 0; 938 | } 939 | 940 | void call_signum(void){ 941 | eval(&func_ret); 942 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 943 | 944 | convert_data(&func_ret, DT_DOUBLE); 945 | 946 | if(func_ret.value.d > 0.0) func_ret.value.d = 1.0; 947 | else if(func_ret.value.d < 0.0) func_ret.value.d = -1.0; 948 | 949 | func_ret.ind_level = 0; 950 | } 951 | 952 | void call_isodd(void){ 953 | eval(&func_ret); 954 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 955 | 956 | convert_data(&func_ret, DT_INT); 957 | 958 | if(func_ret.value.i % 2) func_ret.value.i = 1; 959 | else func_ret.value.i = 0; 960 | 961 | func_ret.ind_level = 0; 962 | } 963 | 964 | void call_iseven(void){ 965 | eval(&func_ret); 966 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 967 | 968 | convert_data(&func_ret, DT_INT); 969 | 970 | if(func_ret.value.i % 2) func_ret.value.i = 0; 971 | else func_ret.value.i = 1; 972 | 973 | func_ret.ind_level = 0; 974 | } 975 | 976 | void call_isprime(void){ 977 | register int i; 978 | int isprime; 979 | 980 | eval(&func_ret); 981 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 982 | convert_data(&func_ret, DT_INT); 983 | 984 | isprime = 0; 985 | for(i = 2; i <= trunc(sqrt(func_ret.value.i)); i++){ 986 | if(!(func_ret.value.i % i)){ 987 | isprime = i; 988 | break; 989 | } 990 | } 991 | 992 | func_ret.value.i = isprime; 993 | 994 | func_ret.ind_level = 0; 995 | } 996 | 997 | void call_fact(void){ 998 | eval(&func_ret); 999 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1000 | 1001 | convert_data(&func_ret, DT_INT); 1002 | 1003 | if(func_ret.value.i < 0) func_ret.value.i = 0; 1004 | else func_ret.value.i = factorial(func_ret.value.i); 1005 | func_ret.ind_level = 0; 1006 | } 1007 | 1008 | int factorial(int N){ 1009 | if(N == 1 || N == 0) return 1; 1010 | else return N * factorial(N - 1); 1011 | } 1012 | 1013 | void call_nCk(void){ 1014 | _DATA n, k; 1015 | 1016 | eval(&n); 1017 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 1018 | convert_data(&n, DT_INT); 1019 | 1020 | eval(&k); 1021 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1022 | convert_data(&k, DT_INT); 1023 | 1024 | func_ret.type = DT_INT; 1025 | func_ret.ind_level = 0; 1026 | 1027 | func_ret.value.i = factorial(n.value.i) / ( factorial(n.value.i - k.value.i) * factorial(k.value.i) ); 1028 | } 1029 | 1030 | 1031 | void call_avrg(void){ 1032 | _DATA expr; 1033 | double d = 0; 1034 | int i = 0; 1035 | 1036 | do{ 1037 | eval(&expr); 1038 | convert_data(&expr, DT_DOUBLE); 1039 | d += expr.value.d; 1040 | i++; 1041 | } while(tok == COMMA); 1042 | 1043 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1044 | 1045 | func_ret.type = DT_DOUBLE; 1046 | func_ret.value.d = d / i; 1047 | func_ret.ind_level = 0; 1048 | } 1049 | 1050 | void call_zeta(void){ 1051 | register int i; 1052 | int n; 1053 | _DATA s, iterations; 1054 | 1055 | eval(&s); 1056 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 1057 | eval(&iterations); 1058 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1059 | convert_data(&s, DT_DOUBLE); 1060 | convert_data(&iterations, DT_INT); 1061 | 1062 | func_ret.type = DT_DOUBLE; 1063 | func_ret.value.d = 0.0; 1064 | func_ret.ind_level = 0; 1065 | 1066 | for(i = 1; i <= iterations.value.i; i++) 1067 | func_ret.value.d += 1.0 / pow(i, s.value.d); 1068 | } 1069 | 1070 | void call_eval(void){ 1071 | char *t; 1072 | _DATA expr_str, result; 1073 | 1074 | eval(&expr_str); 1075 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1076 | 1077 | t = prog; 1078 | 1079 | prog = expr_str.value.p; 1080 | eval(&result); 1081 | 1082 | prog = t; 1083 | 1084 | func_ret = result; 1085 | } 1086 | 1087 | void call_trunc(void){ 1088 | _DATA expr; 1089 | 1090 | eval(&expr); 1091 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1092 | 1093 | if(expr.type == DT_FLOAT){ 1094 | func_ret.value.f = truncf(expr.value.f); 1095 | func_ret.type = DT_FLOAT; 1096 | } 1097 | else if(expr.type == DT_DOUBLE){ 1098 | func_ret.value.d = trunc(expr.value.d); 1099 | func_ret.type = DT_DOUBLE; 1100 | } 1101 | else{ 1102 | func_ret.type = expr.type; 1103 | } 1104 | } 1105 | 1106 | void call_round(void){ 1107 | _DATA expr; 1108 | 1109 | eval(&expr); 1110 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1111 | 1112 | if(expr.type == DT_FLOAT){ 1113 | func_ret.value.f = roundf(expr.value.f); 1114 | func_ret.type = DT_FLOAT; 1115 | } 1116 | else if(expr.type == DT_DOUBLE){ 1117 | func_ret.value.d = round(expr.value.d); 1118 | func_ret.type = DT_DOUBLE; 1119 | } 1120 | else{ 1121 | func_ret.type = expr.type; 1122 | } 1123 | } 1124 | 1125 | void call_max(void){ 1126 | _DATA x, y; 1127 | 1128 | eval(&x); 1129 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 1130 | convert_data(&x, DT_DOUBLE); 1131 | 1132 | eval(&y); 1133 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1134 | convert_data(&y, DT_DOUBLE); 1135 | 1136 | func_ret.type = DT_DOUBLE; 1137 | func_ret.ind_level = 0; 1138 | 1139 | if(x.value.d >= y.value.d) func_ret.value.d = x.value.d; 1140 | else func_ret.value.d = y.value.d; 1141 | } 1142 | 1143 | void call_min(void){ 1144 | _DATA x, y; 1145 | 1146 | eval(&x); 1147 | if(tok != COMMA) show_error(INSUFFICIENT_ARGUMENTS); 1148 | convert_data(&x, DT_DOUBLE); 1149 | 1150 | eval(&y); 1151 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1152 | convert_data(&y, DT_DOUBLE); 1153 | 1154 | func_ret.type = DT_DOUBLE; 1155 | func_ret.ind_level = 0; 1156 | 1157 | if(x.value.d <= y.value.d) func_ret.value.d = x.value.d; 1158 | else func_ret.value.d = y.value.d; 1159 | } 1160 | 1161 | void call_getchar(void){ 1162 | get_token(); 1163 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1164 | 1165 | func_ret.type = DT_CHAR; 1166 | func_ret.value.c = getchar(); 1167 | } 1168 | 1169 | void call_kbhit(void){ 1170 | get_token(); 1171 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1172 | 1173 | func_ret.value.i = kbhit(); 1174 | func_ret.type = DT_INT; 1175 | } 1176 | 1177 | void call_getch(void){ 1178 | get_token(); 1179 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1180 | 1181 | func_ret.value.c = getch(); 1182 | func_ret.type = DT_CHAR; 1183 | } 1184 | 1185 | void call_getche(void){ 1186 | get_token(); 1187 | if(tok != CLOSING_PAREN) show_error(CLOSING_PAREN_EXPECTED); 1188 | 1189 | func_ret.value.c = getche(); 1190 | func_ret.type = DT_CHAR; 1191 | } 1192 | 1193 | void call_putch(void){ 1194 | eval(&func_ret); 1195 | convert_data(&func_ret, DT_CHAR); 1196 | 1197 | putch(func_ret.value.c); 1198 | } 1199 | -------------------------------------------------------------------------------- /mandelbrot.pc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | const int ITERATIONS = 100; 7 | const int LIN = 70, COL = 150; 8 | 9 | void main(){ 10 | int plane[LIN][COL]; 11 | double r = 0, im = 0; 12 | double y, x; 13 | int k; 14 | double x1 = -2.5, x2 = 2.5, y1 = -1, y2 = 1; 15 | char c; 16 | double dx, dy; 17 | int i; 18 | 19 | do 20 | { 21 | puts("mandelbrot set grapher"); 22 | puts("enter the coordinates for a rectangle, x1 = left, x2 = right, y1 = bottom, y2 = top"); 23 | puts("the mandelbrot set goes from x in [-2.5, 2.5] and y in [-1, 1]"); 24 | 25 | printf("x1= "); 26 | scanf("%lf", &x1); 27 | printf("x2= "); 28 | scanf("%lf", &x2); 29 | printf("y1= "); 30 | scanf("%lf", &y1); 31 | printf("y2= "); 32 | scanf("%lf", &y2); 33 | 34 | puts("calculating..."); 35 | 36 | dx = (x2 - x1) / COL; 37 | dy = (y2 - y1) / LIN; 38 | 39 | for(y = 0; y < LIN; y++){ 40 | for(x = 0; x < COL; x++){ 41 | for(k = 0; k <= ITERATIONS; k++){ 42 | mandelbrot(r, im, x1 + dx * x, y1 + dy * y, &r, &im); 43 | if(absc(r, im) > 2) break; 44 | } 45 | if(absc(r, im) > 2) plane[y][x] = ' '; 46 | else plane[y][x] = 'o'; 47 | r = 0; 48 | im = 0; 49 | } 50 | } 51 | 52 | for(y = 0; y < LIN; y++){ 53 | printf("%9.6f", y2 - y * dy); 54 | for(x = 0; x < COL; x++){ 55 | putchar(plane[y][x]); 56 | } 57 | putchar('\n'); 58 | } 59 | 60 | 61 | for(i = 0; i < 7; i++) putchar(' '); 62 | 63 | for(i = 0; i < COL; i++) 64 | if(i % 10 == 0) printf("%10.6f", x1 + dx * i); 65 | 66 | printf("\npress e to exit or any other key to try again\n"); 67 | c = getch(); 68 | 69 | } while( c != 'e'); 70 | 71 | } 72 | 73 | void multiply(double r1, double im1, double r2, double im2, double *r3, double *im3){ 74 | *r3 = r1*r2 - im1*im2; 75 | *im3 = r1*im2 + r2*im1; 76 | } 77 | 78 | double absc(double r, double im){ 79 | return sqrt(r * r + im * im); 80 | } 81 | 82 | void mandelbrot(double r, double im, double cr, double cim, double *rr, double *rim){ 83 | *rr = r * r - im * im + cr; 84 | *rim = 2 * r * im + cim; 85 | } 86 | -------------------------------------------------------------------------------- /p.pc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include