{"id":17209163,"url":"https://github.com/rswinkle/c_interpreter","last_synced_at":"2026-03-04T22:32:17.050Z","repository":{"id":10473544,"uuid":"12649525","full_name":"rswinkle/C_Interpreter","owner":"rswinkle","description":"Aims to be interpreted C written in C.","archived":false,"fork":false,"pushed_at":"2025-05-22T08:35:34.000Z","size":344,"stargazers_count":32,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-11-08T20:32:29.265Z","etag":null,"topics":["c","interpreted-programming-language","interpreter","preprocessor","recursive-descent-parser"],"latest_commit_sha":null,"homepage":"http://www.robertwinkler.com/projects/c_interpreter.html","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rswinkle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"liberapay":"rswinkle","custom":"http://www.robertwinkler.com/donations.html"}},"created_at":"2013-09-06T16:59:16.000Z","updated_at":"2025-10-27T04:55:48.000Z","dependencies_parsed_at":"2023-02-10T13:02:50.430Z","dependency_job_id":null,"html_url":"https://github.com/rswinkle/C_Interpreter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rswinkle/C_Interpreter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rswinkle%2FC_Interpreter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rswinkle%2FC_Interpreter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rswinkle%2FC_Interpreter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rswinkle%2FC_Interpreter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rswinkle","download_url":"https://codeload.github.com/rswinkle/C_Interpreter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rswinkle%2FC_Interpreter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30096781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T21:59:23.547Z","status":"ssl_error","status_checked_at":"2026-03-04T21:57:50.415Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","interpreted-programming-language","interpreter","preprocessor","recursive-descent-parser"],"created_at":"2024-10-15T02:50:56.976Z","updated_at":"2026-03-04T22:32:17.023Z","avatar_url":"https://github.com/rswinkle.png","language":"C","readme":"C_Interpreter\n=============\n\n[![Build Status](https://travis-ci.org/rswinkle/C_Interpreter.svg?branch=master)](https://travis-ci.org/rswinkle/C_Interpreter)\n[![Coverity Scan Build Status](https://scan.coverity.com/projects/3624/badge.svg)](https://scan.coverity.com/projects/3624)\n\n[http://www.robertwinkler.com/projects/c_interpreter.html](http://www.robertwinkler.com/projects/c_interpreter.html)\n\n[![Run on Repl.it](https://repl.it/badge/github/rswinkle/C_Interpreter)](https://repl.it/github/rswinkle/C_Interpreter)\n\n\nThis started as C port of an old college assignment\nin C++.  You can see that in the first commit though I\nmight have made some minor changes/improvements during\nport.\n\nNow my goal is to make something approaching scriptable\nC.  I'll consider it done when it can run itself ...\nso it'll probably never be completely done.\n\nDownload\n========\nGet the source from [Github](https://github.com/rswinkle/C_Interpreter).\n\n\nAlternatives\n============\nIf you're looking for something more professional there's\n\n* [Cling](http://root.cern.ch/drupal/content/cling)\n* [Ch](http://www.softintegration.com/)\n\n* [TCC](http://en.wikipedia.org/wiki/Tiny_C_Compiler), a compiler that's so\nfast and self-contained they have a command line switch -run to immediately\nrun it after compiling so you can use C as a JIT scripting language,\n\n\nTests\n=====\nI've kept the old tests around (updating them so they\nkeep working) but I've been adding new tests for\nnew features.  They're not comprehensive and they\ndon't test every edge case but they're growing.\n\n\nMisc\n====\nI'm using the 5th edition of C: A Reference Manual for\nall the nitty gritty details and the very convenient\ncomplete C grammar/syntax in the appendix.\n\nI've also added a BNF spec for C I found online just\nto have something for reference in the repository.\n\nCurrent Grammar (work in progress)\n==================================\n### Preprocessor\n\n\t#include \"relative path based on current directory\"\n\t#define name\n\t#define name sequence_of_tokens\n\t#define name ( identifier-list ) sequence_of_tokens\n\t#undef name\n\t# (null directive)\n\nIt also of course supports actually using the macros.\n\n### C language\n\n\ttranslation_unit                -\u003e top_level_declaration\n\t                                   translation_unit top_level_declaration\n\n\ttop_level_declaration           -\u003e declaration\n\t                                   function_definition\n\n\tfunction_definition             -\u003e declaration_specifier function_declarator compound_statement\n\n\tfunction_declarator             -\u003e identifier '(' parameter_list ')'\n\n\tparameter_list                  -\u003e parameter_declaration\n\t                                   parameter_list ',' paramater_declaration\n\n\tparameter_declaration           -\u003e declaration_specifier identifier\n\n\tdeclaration                     -\u003e declaration_specifier initialized_declarator_list ';'\n\n\tinitialized_declarator_list     -\u003e initialized_declarator\n\t                                   initialized_declarator_list ',' initialized_declarator\n\n\tinitialized_declarator          -\u003e identifier\n\t                                   identifier '=' assign_expr\n\n\tdeclaration_specifier           -\u003e char, signed char\n\t                                   short, short int, signed short, signed short int\n\t                                   int, signed int, signed\n\t                                   long, long int, signed long, signed long int\n\n\t                                   unsigned char\n\t                                   unsigned short, unsigned short int\n\t                                   unsigned, unsigned int\n\t                                   unsigned long, unsigned long int\n\n\t                                   float\n\t                                   double\n\n\tcompound_statement              -\u003e '{' decl_or_stmt_list '}'\n\n\tdecl_or_stmt_list               -\u003e decl_or_stmt\n\t                                   decl_or_stmt_list decl_or_stmt\n\n\tdecl_or_stmt                    -\u003e declaration\n\t                                   statement\n\n\tstatement                       -\u003e expr_stmt\n\t                                   while_stmt\n\t                                   for_stmt\n\t                                   do_stmt\n\t                                   if_stmt\n\t                                   print_stmt\n\t                                   compound_statement\n\t                                   return_stmt\n\t                                   goto_stmt\n\t                                   labeled_stmt\n\t                                   break_or_continue_stmt\n\t                                   switch_stmt\n\t                                   case_or_default_stmt\n\t                                   null_stmt\n\n\tnull_stmt                       -\u003e ';'\n\n\tswitch_stmt                     -\u003e switch '(' expr ')' statement\n\n\tcase_or_default_stmt            -\u003e case constant_expr ':'\n\t                                   default ':'\n\n\tconstant_expr                   -\u003e cond_expr  //nothing but integer literals allowed\n\t                                              //see tests/switch.c\n\n\tbreak_or_continue_stmt          -\u003e break ';'\n\t                                   continue ';'\n\n\tlabeled_stmt                    -\u003e identifier ':' statement\n\n\tdo_stmt                         -\u003e do statement while '(' expr ')' ';'\n\n\twhile_stmt                      -\u003e while '(' expr ')' statement\n\n\tfor_stmt                        -\u003e for for_expressions statement\n\n\tfor_expressions                 -\u003e '(' initial_clause\u003copt\u003e ';' expr\u003copt\u003e ';' expr\u003copt\u003e ')'\n\n\tinitial_clause                  -\u003e expr\n\t                                   declaration\n\n\tif_stmt                         -\u003e if '(' expr ')' statement\n\t                                   if '(' expr ')' statement else statement\n\n\tprint_stmt                      -\u003e print expr ';'\n\n\tgoto_stmt                       -\u003e goto identifier ';'\n\n\texpr_stmt                       -\u003e expr ';'\n\n\texpr                            -\u003e comma_expr\n\n\tcomma_expr                      -\u003e assign_expr\n\t                                   assign_expr ',' assign_expr\n\n\tassign_expr                     -\u003e cond_expr\n\t                                   identifier assign_op assign_expr\n\n\tassign_op                       -\u003e one of '=' '+=' '-=' '*=' '/=' '%='\n\n\tcond_expr                       -\u003e logical_or_expr\n\t                                   logica_or_expr '?' expr ':' cond_expr\n\n\tlogical_or_expr                 -\u003e logical_and_expr\n\t                                   logical_or_expr '||' logical_and_expr\n\n\tlogical_and_expr                -\u003e bit_or_expr\n\t                                   logical_and_expr '\u0026\u0026' bit_or_expr\n\n\tbit_or_expr                     -\u003e bit_xor_expr\n\t                                   bit_or_expr '|' bit_xor_expr\n\n\tbit_xor_expr                    -\u003e bit_and_expr\n\t                                   bit_xor_expr '^' bit_and_expr\n\n\tbit_and_expr                    -\u003e equality_expr\n\t                                   bit_and_expr '\u0026' equality_expr\n\n\tequality_expr                   -\u003e relational_expr\n\t                                   equality_expr '==' relational_expr\n\t                                   equality_expr '!=' relational_expr\n\n\trelational_expr                 -\u003e shift_expr\n\t                                   relational_expr relational_op shift_expr\n\n\trelational_op                   -\u003e one of '\u003c' '\u003e' '\u003c=' '\u003e='\n\n\tshift_expr                      -\u003e add_expr\n\t                                   shift_expr '\u003c\u003c' add_expr\n\t                                   shift_expr '\u003e\u003e' add_expr\n\n\tadd_expr                        -\u003e mult_expr\n\t                                   add_expr '+' mult_expr\n\t                                   add_expr '-' mult_expr\n\n\tmult_expr                       -\u003e unary_expr\n\t                                   mult_expr mult_op unary_expr\n\n\tmult_op                         -\u003e one of '*' '/' '%'\n\n\tunary_expr                      -\u003e postfix_expr\n\t                                   sizeof_expr\n\t                                   bit_negation_expr\n\t                                   logical_negation_expr\n\t                                   unary_minus_expr\n\t                                   unary_plus_expr\n\t                                   preincrement_expr\n\t                                   predecrement_expr\n\n\tpreincrement_expr               -\u003e '++' unary_expr\n\tpredecrement_expr               -\u003e '--' unary_expr\n\n\tunary_plus_expr                 -\u003e '+' unary_expr\n\tunary_minus_expr                -\u003e '-' unary_expr\n\n\tlogical_negation_expr           -\u003e '!' unary_expr\n\n\tbit_negation_expr               -\u003e '~' unary_expr\n\n\tsizeof_expr                     -\u003e sizeof '(' type-name ')'\n\t                                -\u003e sizeof unary-expr\n\n\tpostfix_expr                    -\u003e function_call\n\t                                   primary_expr\n\t                                   postincrement_expr\n\t                                   postdecrement_expr\n\n\tpostincrement_expr              -\u003e postfix_expr '++'\n\tpostdecrement_expr              -\u003e postfix_expr '--'\n\n\tfunction_call                   -\u003e identifier '(' expression_list ')'\n\n\texpression_list                 -\u003e assign_expr\n\t                                   expression_list ',' assign_expr\n\n\tprimary_expr                    -\u003e identifier\n\t                                   constant\n\t                                   '(' expr ')'\n\n\nBuilding and Running\n====================\nI use [premake](http://premake.github.io/) for generating makefiles and have shell scripts for running\nall my tests at once.\n\n\t~ $ git clone https://github.com/rswinkle/C_Interpreter.git\n\tCloning into 'C_Interpreter'...\n\tremote: Reusing existing pack: 489, done.\n\tremote: Total 489 (delta 0), reused 0 (delta 0)\n\tReceiving objects: 100% (489/489), 168.87 KiB | 301.00 KiB/s, done.\n\tResolving deltas: 100% (264/264), done.\n\tChecking connectivity... done.\n\t~ $ cd C_Interpreter/\n\t~/C_Interpreter $ premake4 gmake\n\tBuilding configurations...\n\tRunning action 'gmake'...\n\tGenerating build/Makefile...\n\tGenerating build/cinterpreter.make...\n\tDone.\n\t~/C_Interpreter $ cd build/\n\t~/C_Interpreter/build $ make\n\t==== Building cinterpreter (debug) ====\n\t...\n\tLinking cinterpreter\n\t~/C_Interpreter/build $ ./cinterpreter \n\tUsage: ./cinterpreter [-E] script\n\t~/C_Interpreter/build $ ./cinterpreter ../tests/switch.txt\n\t[ouhput from switch.txt here]\n\t~/C_Interpreter/build $ ../runtests.py\n\tShould be nothing here, only failures produce output\n\t~/C_Interpreter/build $ ../run_valgrind_tests.py\n\tSame here.  Note this may take a minute, valgrind makes things slow\n\t~/C_Interpreter/build $\n\n","funding_links":["https://liberapay.com/rswinkle","http://www.robertwinkler.com/donations.html"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frswinkle%2Fc_interpreter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frswinkle%2Fc_interpreter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frswinkle%2Fc_interpreter/lists"}