From ab71aa9999b54672d4ff146709597ef7c690a1e0 Mon Sep 17 00:00:00 2001 From: retoor Date: Sat, 22 Nov 2025 16:53:39 +0100 Subject: [PATCH] Working. --- Makefile | 34 +++ a.c | 42 +++ a_test.c | 5 + demo.c | 37 +++ demo_simple.c | 10 + demo_test.c | 12 + demo_test2.c | 22 ++ demo_test3.c | 26 ++ main2 | Bin 0 -> 26448 bytes main2.c | 697 ++++++++++++++++++++++++++++++++++++++++++++++++++ test.c | 29 +++ tokens.txt | Bin 0 -> 206 bytes 12 files changed, 914 insertions(+) create mode 100644 Makefile create mode 100644 a.c create mode 100644 a_test.c create mode 100644 demo.c create mode 100644 demo_simple.c create mode 100644 demo_test.c create mode 100644 demo_test2.c create mode 100644 demo_test3.c create mode 100755 main2 create mode 100644 main2.c create mode 100644 test.c create mode 100644 tokens.txt diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..86455a2 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ +CC = gcc +CFLAGS = -Wall -Wextra -O2 +TARGET = main2 +SRC = main2.c +SAMPLES = test.c demo.c a.c + +.PHONY: all clean run-test run-demo run-a help + +all: $(TARGET) + +$(TARGET): $(SRC) + $(CC) $(CFLAGS) -o $(TARGET) $(SRC) + +run-test: $(TARGET) + ./$(TARGET) test.c + +run-demo: $(TARGET) + ./$(TARGET) demo.c + +run-a: $(TARGET) + ./$(TARGET) a.c + +clean: + rm -f $(TARGET) + +help: + @echo "Mini C Interpreter - Makefile" + @echo "Usage:" + @echo " make - Build the interpreter" + @echo " make run-test - Run test.c" + @echo " make run-demo - Run demo.c" + @echo " make run-a - Run a.c" + @echo " make clean - Remove compiled binaries" + @echo " make help - Show this help message" diff --git a/a.c b/a.c new file mode 100644 index 0000000..16b5620 --- /dev/null +++ b/a.c @@ -0,0 +1,42 @@ + +int main() { + int server_fd; + int client_fd; + char buffer[1024]; + char *response; + int bytes; + int response_len; + int count; + + printf("Creating socket\n"); + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + + printf("Binding\n"); + bind(server_fd, 8080); + + printf("Listening\n"); + listen(server_fd, 10); + + printf("Server listening on port 8080\n"); + + count = 0; + while (count < 100) { + printf("Waiting for connection\n"); + client_fd = accept(server_fd, 0, 0); + printf("Client connected\n"); + + bytes = recv(client_fd, buffer, 1024, 0); + printf("Received %d bytes\n", bytes); + + response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n

Hello from Mini C HTTP Server!

This server runs on a custom C interpreter.

"; + response_len = strlen(response); + send(client_fd, response, response_len, 0); + + close(client_fd); + printf("Connection closed\n"); + count = count + 1; + } + + close(server_fd); + return 0; +} diff --git a/a_test.c b/a_test.c new file mode 100644 index 0000000..e03952d --- /dev/null +++ b/a_test.c @@ -0,0 +1,5 @@ + +int main() { + printf("Starting\n"); + return 0; +} diff --git a/demo.c b/demo.c new file mode 100644 index 0000000..38c5a2b --- /dev/null +++ b/demo.c @@ -0,0 +1,37 @@ + +int main() { + int server_fd; + int client_fd; + char buffer[4096]; + char *response; + int bytes_received; + int response_len; + int count; + + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + bind(server_fd, 8080); + listen(server_fd, 10); + + printf("Server listening on port 8080\n"); + + count = 1; + while (count > 0) { + printf("Waiting for connection %d\n", count); + client_fd = accept(server_fd, 0, 0); + printf("Client connected\n"); + + bytes_received = recv(client_fd, buffer, 4096, 0); + printf("Received %d bytes\n", bytes_received); + + response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n

Hello from Mini C!

Request number: "; + response_len = strlen(response); + send(client_fd, response, response_len, 0); + + close(client_fd); + printf("Connection closed\n"); + count = count + 1; + } + + close(server_fd); + return 0; +} diff --git a/demo_simple.c b/demo_simple.c new file mode 100644 index 0000000..701c8eb --- /dev/null +++ b/demo_simple.c @@ -0,0 +1,10 @@ + +int main() { + int server_fd; + + printf("Starting server\n"); + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + printf("Socket created\n"); + + return 0; +} diff --git a/demo_test.c b/demo_test.c new file mode 100644 index 0000000..df59087 --- /dev/null +++ b/demo_test.c @@ -0,0 +1,12 @@ + +int main() { + int server_fd; + int client_fd; + char buffer[4096]; + + printf("Starting server\n"); + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + printf("Socket created\n"); + + return 0; +} diff --git a/demo_test2.c b/demo_test2.c new file mode 100644 index 0000000..bd4deae --- /dev/null +++ b/demo_test2.c @@ -0,0 +1,22 @@ + +int main() { + int server_fd; + int client_fd; + char buffer[4096]; + char *response; + int bytes_received; + int response_len; + int count; + + printf("Starting server\n"); + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + bind(server_fd, 8080); + listen(server_fd, 10); + + printf("Server listening on port 8080\n"); + + count = 0; + printf("Count initialized\n"); + + return 0; +} diff --git a/demo_test3.c b/demo_test3.c new file mode 100644 index 0000000..aa8290f --- /dev/null +++ b/demo_test3.c @@ -0,0 +1,26 @@ + +int main() { + int server_fd; + int client_fd; + char buffer[4096]; + char *response; + int bytes_received; + int response_len; + int count; + + server_fd = socket(AF_INET(), SOCK_STREAM(), 0); + bind(server_fd, 8080); + listen(server_fd, 10); + + printf("Server listening on port 8080\n"); + + count = 0; + while (count < 3) { + printf("Waiting for connection %d\n", count); + count = count + 1; + } + + printf("Done\n"); + close(server_fd); + return 0; +} diff --git a/main2 b/main2 new file mode 100755 index 0000000000000000000000000000000000000000..009e1f4f3c557987e494c89b5df60f235ef8ebcf GIT binary patch literal 26448 zcmeHweSDME-S9Cllor8(w9?QNu1J7NQBh%ONmJ!@&u8kKbLw{U_-qW(X`#I7e5oK4=2T>$i3LHOSSpg|`#aY;$(7LF&wbyY z=kvLrKRA4vbDiJ$y`A6ro!@!6lEb~_-nnLziOH0~u4Pm@e!dPV6&2k+@qnz9&0y!? zb1b`*jX*h*!}R)6JwvUY_L)<2tAJ-9C%RmE7$Uz!2Q!&V4JjwO;ZoITy+-CNTQ3ux zg&svYJ#V;N$CJ6NPsl6P>k|zV<%dLrWNxG*+vG0L>2jB+<^#em(ObAy3B3qRboqiV zU(m_?xG;pwr9H_e^fyD;Gd(Xv9VMBk)2$M8>A71cV=^ZhlqwIaHUAZP6@sqQrSnP8 zvqbx3F6CVhI4^i0l=`|AS5KQ#Uo*MBt})m)xoyVPldqmu z(Arcmm8(E{Iq*llH*et$4CFlo6J})QcD*e5QQa6(PxuF)nfIIfo*aEm(HE_c1a{pz zaZbs&9}y1eO*DiZoEB^odJdFw8DEAU3cvCI5+4jkg+ zLBP%%0{-eS@be+iF$6y8FchB&!@zrofmaR#r{O#l|5d}lw+#a)dkw{B$}sJkJq-R` z!@wiMz@Hoj-Y^WD`fn&brws$2I}H5AVc=7SfnPg}9c~#0-#ZL^E#T+E8y!`6K$3Ch z_jn%1A*mlTQ9KV`Uzn%E=g8{jpz3G%Xk|WMt6J^9&F5cro3FOIt{#Bqmbyl@mLROQ zB~V?%0&R6FTT$1Dr{(wy8PL$Xc8Hw*^#!)uZI|`PJ3U0pAK=eUqQH z20%j+S{nV$t2sxXuO;BWoj{;3sWbR9{1NT_dZnYgKiYZPmWo zy2k4Ix;q1`+V2lEtE|>v-_#l)v5o$QX5g;yQ~bD^&GUNZl=-F>T$Ow(n3i}>K20r{ zo`7C8jrlxF7WircErFFJwPneIvihdRz>?|}^#Q21vZ1L_sOHmAheV`kl7Z-vA^v5G zoFMwM1u;$5nh<03XBt10OsL(BT*lY)>*~&-Nc0Z@Q!lLh7DdI6M0pIa&t#vAa_}Om z&tRuS`Hw&T`3Ta zQ-uLeGGtn6fJ@s^U6lcj4oRd{2KcB1l(A+5Tr9D8ZJPlOM@Xc01KgH?GWLK0Zk(LD z4RGmOMD~yYey)MfqXxJ!UOr`jizO_l+F*bS*WvI@26&Eve~$rvfdRhD0M9kR`wZ|4 z4e+y%XDx8n0%tAo|EmSQuwOc;gpOF1ux0-u#+0re)g13rLffpgQfDkaeQ+T@$DhKd zeQYTs{8dyDI~b40YrA=wCfL~SWSJ(o*w$p3Cfe9@$udoJvB#5Tn&4tTNtS71i`|zj z(}WglNtS6Mi>*kOX#$HaPL^rnip@!uX~K$4O_phbkBv)~Y2u2Vmn_qS6*DKxG*QJq zKb>eVO;E9e$udn$vE9isO-Qk=$udnuvFDOynt)=DC(7~hjj(R5eXN^t`^Lxrd_ih? zeOh^KTKS%|^6hEm#{i|rb@OXRY+o*f_(X}QPodoDh ze=|W8ZKtAH@*ptUjviCOIp^Y8(LUIbX=c&80V?W={(LO)F8K;#qqo4j0osEN z%}eCyN~EM`GT^)6m7#&Sx?FikiR3)7j5I#hqukb$A9kA^nq~JOg!wJAw=x!~Fl#wi z;{k}XklD}8+*;HFHP%A_cwdo4*{!``eKoOu=bLzZ6DiF>HxXzXK>htdm_ntERC-U2 z-=d=)?XB-A+Ce3B=y=7F@}i!iSAh8z+7i#{ozK|6Y76XRJHd}@9|J^*SPoJ)b3n~O zsCbf|5h}hFKVTo*PI$c{2cPFT{`BW4n{Zmujw@R}ovmyc$WTl>l($Z+W56IN7+B*6 z^nR1{6i?bqBB*A;D{oLjC5!1%(GIIwFz}5iL|-`-k4I~u>kdl*Wz%xdCgc-+><&~4 zeW<*N;!$tXKe(w3Wr}~{o3g`qSi`fUFThk3{*;HnR*!eQo>yLKtZWBYK3;kK?4sR8 zC!!0I2uXQ2R4N@uXvd_4vYagCIdmlVdFDV3e*Tm)_aemoo;Psv>XbZsq$>0a<9Q(&uG_0ioXvm1ZwQ-LGle)%+5S4{|mM|Hu#9H`AZOiYCPBX}J-Q>E_b%QrD`Q;NP z=2`;x3LRM*KIdmBDfXA9r0AfKW!E@!z5WkNJCE8s{|Jd%mQ&Hb2K~LDh;9aFuixqP zXgj>xhy8cz{XRdES>ukZHo3Ku5@30>W!tmu8#9Wh*gN-w1?23q|2gZr6WcTGU33=R ze%Na7`Yj%c$Jsk)W5Ty@JU=v861=zlE>lTxHL+7dz2*h}k6k<6+gTVqAWhMhIdj45 zO6aCu;t5}H!u@@dL%k2ECSzUj5HaACAjD{KI~5p7A0+m!n_ya)Y3Z%YUCUg{UEg#0 zFm`qS4-H-xY~?yMr0cNGpo0h*r3|Q3>|J>XAW9gzp~;;+>bT-j>ZMAg%+zmb9~`Bg zub{h7l}*zJ{Iqj-Fshw%!Ivf$E98;KjYvOO9K4dt9iJ}uM@G4E1YPp`(BQSh;ddMH z-%Q|NZtrY@y+ea*>|H;n9=OYdr*(Kr7x-f%gY}$&j-!2`L{w+)W?C?f|AI%685FJDitdVC4`SUvLLXX#)?%N%Yb`vS2UH!7&MeMQv>i&M)N~^A zPHXVf()PGdjVk_6y^+kTy#6;7?QHAduspwx--D20^{B2T zpa$)oQBgNej8F&Ot`GdQQ0de*D;dLnRAv{=jbYKk>>Gs3#wK3Ms3d)NK2 zL%NlJ0!GrMWBDN9@l%OZnu?3ZfpG;wfg-t7#66>Se0_&7p3 zr{mls^G#e41t!YfNhkfFRWJ@KF*4{w=ySvZvW@N* zS1K3-3U`gGx#p~Wjnm0C)7Z0jJ_ReqZq)sa#tG-&{~S=pvCV5aN*AG&N^6qde2_;_ z8T$xeon05ly_s;woq@Zaa5n?&(e{-Wy;5|v=tS%xm><3VonT8N+x!4gcUg$~0({hl zpkiS2{T%us5MvBb!p4y@+pKZ;VS-2T5q;rbDN_W+|B9tpLmnANF$Wtbza{rG3XlUY z!=2DSTa`#wDWEpUVOaj*M@1FT( z@LewIRxK*Rd9OhxZ!gLFscUF?VZeu!_xR_=cK&DNp^L|Z>+_FdA6SWwR=Ib?6X>y{lvW^1 z9k=%K^@QKD_fr$2MfjLf9y=|EQAVjRZ0;Y+<3VWPZu^5h_KiIgwsgI6&t>5`xme8Q zVhMghXoo2@a98ks0mAr3Z+@apzYi>W`TksAFTh8X$mDf^(t5!f&Z{OFerzH#OT!q^ zq3B(q0h|4PY(pSA=gP~F`7`fROnuk#MY`U9+VqJab7^07oaB+S>-X5a!$2y|KV1=@ z$sL}2_n)xD$jcz^k*s!@$s3ubJbxVTGqs!rK=b(D@of3XyosADGG?)7<{OxX_A-yX z>h*oe2w+ucA+XhPm0lr))>&E%kv+SLR zh)Vk)baJA->k@c7W_)zQV%o4R*{kD)uft@xgKSR`4VdcDSQPO?`Zoj=^=Nq(@Q-Gn zL#D|&dBlVWza0a(3A$XTW$q-&2>2vC7JwX#M^|X4xu^%Lt-k_0`Zuf$LHRPCfk!%o z*6d}=?On4o(VAY9$&w3Jyd@744){^?(Q}M59Sx@FlzTaSvWMYAUEg4B1`b-@3aZ2a zPgyk4?($|`_#94*kfaNrW$)Tbq!f{^IFl5n(kym@!&sT6p*7oCzP+oP3q!-Syf6CE zuG6DQ>vKNFv!Y>WWO+hsUS|{RT`LI@o0BeVbda>1Z9uViWdj`DkC_FHd5#nD#&m!? zpA))fp`pAr527|!fPn3e_)Q-FHn%pug9xCDmsU2e(A}g^95EWpP*P|Gs-q3MLN{{W zMuq-Hh+9os&Md0JIBU`8f7s`Dq)$i5>0-t%q)D%HBl@57M_9@NI%Hdr*}HxWCM4>s zPaw*yi|WU7YTIv!BZ1?>LeN>-8CP9=d|?$hK6ru4zR~S871!81w}Gm- z)!z9cawR z-A^^Ct}V@0PgOGFVLWuwii?hbK0pp5zD9enj*`oukKVa|0z8~IJ*ftdl>>JNUyV@} zM(KrAM{~D6P$t>Ceu+l$fpQuPPB0yb14=Y~i4#k&8r9Z5*s5NJ)|&a5BVRF0e+@4S z`2qsy`;K6u{XmCrGQfKXzB4*OSMi=}q>8lkf*wDHFrh~WqJ=&{E^BrPFxbZTYJ}i2xr)slQ4q^^8FCpJnXV+c`tly zV*T3^>jw(S;nh}exH=n4b)3>rXDV8;(?$IPP*!LFk}Z&o(fIyS7(Vo=scoLek1fgc zPf=Fsoy1XPw3brSLk#+xF5#5 z=0X_nODyE{d4ubjt>v8$J!2Ol9O?Y9?zUo~nRTmXIr$M{LFayqJ`Z+3k?D1$L?lzg zp9_ktRs3_D;l=q~yX{^35lJxj&iexmip;ICS5VgZ!G9@|{2sibn{YmkDEb(lMI>>F zF#26RjA}VusEdU`9kzUb2I48S!Aa4zUjHzJ?4Z zA$yTgh|u~xns+bi|4M@<=MMl!7Mqoa0L7liztwFzxPZdmb&<@&P?l+1yf|74tLF@O zG}Sr~QE;UEskUoNG(+3+h4LFMrx_d;_)nm@&&}mK^NnHmPMr20I>aNx@)LaM&IOj1 z*9RERMt^rT3OU~e$P>o0L(9p>W9%giWULb~dFgiYV&|UCR{*~xG6WwOYA+0RX}=eE z+)nqRCSfP6%7mTTFzV)O?vKb$%ZPYLJM{zKtsU_Cx6@2PORxES)L15vetF*kVSGuS zBQ~BQj6S8>0gGNlW7`Pj_@UXZQvol6PiJz|r-}@)m9b;h(b}UPN z;ly$i17Pkm;6Vdm7iPS$?Ok8s(;XgfUqVyuDn!4wY**-rsZGI32fBS5 z@CE*($*4B%emNe!6xUAEy7}?LdR)W!E@0|BqW6S8MO-_j$F&t>(E2Y=?% z52!1nw~z~<1N@e5l=-ZgS?Uhg(3ImRZ30{s> zA6lMM29)S&nlH62oY7yu^uh`IC(*d2b@QlQ7`&Wo?pj5 z5bF(kk>JnkLlFV{Rz-VnL4^7*oaqb=OjKu;&?pFAg8iJB67)3~_IcY;5gI5_75EvB z+ewsu036!`w}5;!XC_}BSz2`NrF=dqv3EX)L8;{}BNZU0|6zTeCHdjJCo2#uDbDMo ztvNf?Z)#h>*P-V;jXF8l=;#s@SVuTJbb3DCPI$GCqf-wi=F>@-PctA6Ts)y8lR{s| zgYUq%$Kt(l^cgI8p{FjlASt&Bqg1L%RR&gc~Wk1LN3m8AU7V}{9$68U%^y6 zmwAlKe7FCH-J$KY`I#JeAKu+eBgda}GoIj+@wMnXjg?f&Mf)C;x_st7swY&-o>uX;|w^a6Su`1U=lL??Dwj z;C_@!D&B#~BgqgOde~<20Fkm|jOlPp3YjM^@XHnkp?N+Q^Zbq5<5631hS`=Y_ z4hYU{pP;iTWoF-I2M9fpH5RZkBMwEoIgkFa-Jz2>_u69L_{xM=yLR6*Ryf>`q zobL+0gRtHIq1Y*s{;^-6UhgkV4S~tn2;9g|@c1d53-ibHKjD1FwZt7+WkTSj31tzm zFtp3Dv@%!XptPNzQPJ{k%Rgbrzv2)N(Yoxf%7p#mXexTi2l054EtswZQ+#KDpYTO2 z{}Y2z(dMC1cja?t%FH*x;Z0@2NqM+sIu?EBePBiIs^E;~N8G>1G2)xt0vHMZXBBzjQMf_6rpL*Vl5CrYU|a9BoT2Id_o($R&?aywWjCjC9XkY9)j8q}WkcX9 zl|4R$vfoLy!Rw>Xv_ZXd@Lck4-O>6+rCWsD zK9aYYQ}Tn^=%wJQdjauDoNCK+dzhV{Z_{fMtOI*dKAX;3;H(ACTHve&&RXEC1KreJ-Iqp?YK(9cKp3j78XzxQ0&PyOzA z+)3p<@%V$t>ybZ&d<}AXfAR?Ow~@by9B<>gY zY}wb_teo#_C=&gJ0=`hd523sZaJ+@(_=^B9#N#Ra^#M+A4p_M@d#%}J%ME4BvpwYS z+8!$P*fx}!yGPk_UAAnO&FUJR541w)ybL~ZkZ9)H9suS8znS%Z-rk>xgzO=^h$kRyc7& zRotrq{6|3B{$HS_HtqxMA36L1#&*IaHG3EYyJbo$0 zM7oXVBy6ncHZINhmU&1MyGJ(+33rXoSW2Bzc1EX^k2c>p42k)#!&E3xaTE0YBjQ`m z|J^6%+1kzKq4g>sO}sJ@KOR6F(cl+)+tEkDzmjdAE8BiKwWR!vmdxejqXN8M!<(;e zup(aT%w@LRwHb=d5y~{*#m5p{5&n9{wg;ywjj6}X#*;`{3)?i$p; z4P5KT_+1hDIlV8>7%vs(vLQQ08J%(WaN|fFvSa4Z_^QC)67-3Jc>D*lXN4_$J&hNm z&trUtMxaOXF@zF6KW}uE&Dy);wb$R^)oU&5G9wx5sR=X|o&wJ&@J)%k(eG>l@$?c; z4~-)Xp0$<=;+ZikBb6z00R0eXSG|gOL;7I6V=TPGqswAF#sGRYowdMO3!JsUf13s5 zy(99T5eik5cIz3-5;>p1@r<`JJXPV#F_ie454pV0z zo{l#W>IRChNHncddWhBoNFrmj2B##~s7r;S6#FUB+Jh3l+LDq48Os%m4vOoP1_V8= z7b%U@GbZmoS%t4MQj+j)p|I3@pI*%bT0;J%0xt3Jy&m2^h~uEsqFg8t;>mhWiEn^# z{NqCKNl}*V5bXb-W%9nYbcThrC`Bq2d4~IV^3_3J zoO;jHX$6JTCJ6Aq&zsyRlYJIX$0ENlp=O=vIEO&M*L;S=r*ShBAKC+&SvGS>M-_bX z1-v2+K1;ymcoyjFdOVnLQ%`=C4iWCpmUH+8iSen|;(JSYAh|L=NO(8L&q<7T2_H`X zf8+RL*n^71Oy)zi_b(j(+brELcW|=vS*I&WPfz>tXTs={<6G7q!vo#7)jn2-$UVm( ziga&RX_XEa!;pQ0qVawmy%u*H!BB)>A@H%p7|GN91d4JoX6q0byspj|2P`_&vWLty#yX?{QFi75Ld`Z*~td@)aYBX#HZ)pR6h98Dm%}7E|c??6#TW|b6kugIlqv3hmw04 zhi9{FVP}5E0A>Zl;ClrAfvLJgzK_78U&7PmwhY53B=8G`Tsbe(PcNt+<-{lF*Ixln zc4!xV(*8Si2-05OUjCT!@uc9hVUiA}aZc$O0e6UrRnGU%15W*z?zcOH+ylb?$8XU2 zye|1%sh9bl7ms^5T!$Gy4+;DYY5sYc=wBxMO8Uu{z;_rKi04c+d#HZ=Hu$z~gbzwt9L zz@HZIo;;4mexPUUPXb;l^q1?tUJe&XhU`7bU&J?lzJU5D;H0Oc%7Bc=e+m3{A$Pi{ z9u)8cqLcYv8+CCGPvt?STo{Uv7tv6Djsy5u4nGsWP~bbnKtCu@iig2p2sn+qs7kI}D%I!@z$?{NcCh@$=_^I|NT-wt?`Wk5Z*W<-GGe;Ny&l;+f8H&NCyr zAfy=6-wAF6i099TfwM|~i&|9Bgc}>HSJe5`>XrP>!c@F@Kt-z>#COmAEP2bLPi^qw zRYqfg?!l~S@~y0IT2Wo^t5KU;T7A{QHs)_?Xs!?7#Y;iq&=_V|-?CfLxh8YG625148Ss?Rrfv1>uOuY94~hifI>H!pN8@RWfH_tW~y6;Z3W z7c<{H@1i*_uW!-Zxs~Nhd`nz&yyZUDdRtwyZv`&Typ2`2fh_F;&C0;z)W9h810X$qw< zgZ}y|{p!;M<}|#W)2{*b8SJL3C;;-E7u|50pd%xSdR=y+q~DRsU+%RsynJhrHHkY; zsk!QfSc2x7WzHqc2Y>j<*X?r@a@(n->T}y8oJEXvj}o( z>Kc8))&SkkD(_=WkW9mcugxt1yd1K0YOo>D&;*rN&~>bIb!!SD zh6ntGUT@MZuDlhzp;Cf)$Cz?kY=Xg6xWct1P!A_=!Zol^dPQriuvSC0>R+Y5Kr~)m zn?hP!?Z=SjSJ)=t2IcuRwfr{Ql-g#zuN=Y;#0|75sB}Ya3c%;X4YG1z)77$)Q_97% ztu1ijrW(3o)^E7uHkA{F4MIrXtDC65O1!L10H{%{pmlYFTD<}}T!H7S7 zKnwR5jwT8|)KRYyfp}`JS6KmXQ2`zcRyLtX53K<|D^LS%C{jcPb`uW(1%Xu}hOVjs zH(Ano=)qK{kk1fR-B1T+IywA=6(EZ9pfbcv@}C3Iev?*0SoZNm?{F!}T&{z4sE#Y2 zDgO@s=!iwq&k*!7FC-*GlJlkn(eam&p57T#lDShaCO$DurX&waMtXTpAah3wc5*>Flw@-m*;gd zm*;ap;fZ({6RjKR>`T(i^DdcRBao&35>Mv$pq|dsWLci4$-GL?r|U1kEP@B>6G`7K z8Ypvlz9;3UxBnM{evV)$&kJQP&licFY?e;{7+_=*$v?5)66-GVZ(~aLpGQz>q<089 znOCJ5TvR8-{5Flg{ajs|%q70mL6&8{A&tIU(97KT9RuPa>16(V8ogY<%lvK{poS#r zB|)Dl14e%l4T?0;4&Fhx%1CdQOb|2irOMbgW2DVfWCh~$w@|85$6 zw{RqxTN9313JuhhS2^qe`#I7W4;hO5G +#include +#include +#include +#include +#include +#include +#include + +#define MAX_SRC 100000 +#define MAX_TOK 10000 +#define VAR_MAX 500 +#define MEM_SIZE 10000 + +// --- Token Types --- +enum { + Num = 128, Str, Id, Int, Char, Else, If, While, Return, Printf, + Assign, Eq, Ne, Lt, Gt, Le, Ge, Or, And +}; + +// --- Structures --- +typedef struct { + int type; + long val; // Changed to long to hold pointers on 64-bit + char *text; +} Token; + +typedef struct { + char name[32]; + int type; + int addr; + int is_array; +} Symbol; + +typedef struct { + char name[32]; + int entry_point; + int param_count; +} Func; + +typedef long (*NativeFunc)(long*, int); + +typedef struct { + char name[32]; + NativeFunc func; +} NativeFuncDef; + +// --- Globals --- +Token tokens[MAX_TOK]; +int tk_idx = 0; +int pc = 0; +long memory[MEM_SIZE]; // Changed to long +int sp = 0; +int bp = 0; + +Symbol locals[VAR_MAX]; +int loc_cnt = 0; + +Func funcs[100]; +int func_cnt = 0; + +NativeFuncDef native_funcs[100]; +int native_func_cnt = 0; + +char *src_code; + +// --- Tokenizer --- +void tokenize(char *src) { + char *s = src; + while (*s) { + if (isspace(*s)) { s++; continue; } + + Token *t = &tokens[tk_idx++]; + t->text = s; + + // Comments + if (*s == '/' && *(s+1) == '/') { + while (*s && *s != '\n') s++; + tk_idx--; + continue; + } + + // Keywords & Identifiers + if (isalpha(*s)) { + int len = 0; + while (isalnum(s[len]) || s[len] == '_') len++; + + char buf[32]; + strncpy(buf, s, len); buf[len] = 0; + + if (!strcmp(buf, "int")) t->type = Int; + else if (!strcmp(buf, "char")) t->type = Char; + else if (!strcmp(buf, "if")) t->type = If; + else if (!strcmp(buf, "else")) t->type = Else; + else if (!strcmp(buf, "while")) t->type = While; + else if (!strcmp(buf, "return")) t->type = Return; + else if (!strcmp(buf, "printf")) t->type = Printf; + else t->type = Id; + + t->val = len; + s += len; + continue; + } + + // Numbers + if (isdigit(*s)) { + t->type = Num; + t->val = strtol(s, &s, 10); + continue; + } + + // Strings + if (*s == '"') { + s++; + t->type = Str; + t->text = s; + + char *d = s; + while (*s && *s != '"') { + if (*s == '\\' && *(s+1) == 'n') { + *d++ = '\n'; s+=2; + } else { + *d++ = *s++; + } + } + if (*s == '"') s++; + *d = 0; + t->val = (long)(d - t->text); + continue; + } + + + // Operators + if (!strncmp(s, "==", 2)) { t->type = Eq; s += 2; continue; } + if (!strncmp(s, "!=", 2)) { t->type = Ne; s += 2; continue; } + if (!strncmp(s, "<=", 2)) { t->type = Le; s += 2; continue; } + if (!strncmp(s, ">=", 2)) { t->type = Ge; s += 2; continue; } + if (!strncmp(s, "&&", 2)) { t->type = And; s += 2; continue; } + if (!strncmp(s, "||", 2)) { t->type = Or; s += 2; continue; } + + if (*s == '<') { t->type = Lt; s++; continue; } + if (*s == '>') { t->type = Gt; s++; continue; } + + t->type = *s++; + } + tokens[tk_idx].type = 0; +} + +// --- Helpers --- +void error(char *msg) { + printf("Error at token %d ('%c'): %s\n", pc, tokens[pc].type, msg); + exit(1); +} + +void match(int type) { + if (tokens[pc].type == type) pc++; + else error("Unexpected token"); +} + +int find_local(char *name, int len) { + for (int i = loc_cnt - 1; i >= 0; i--) { + if (!strncmp(locals[i].name, name, len) && locals[i].name[len] == 0) + return i; + } + return -1; +} + +int find_func(char *name, int len) { + for (int i = 0; i < func_cnt; i++) { + if (!strncmp(funcs[i].name, name, len) && funcs[i].name[len] == 0) + return i; + } + return -1; +} + +int find_native_func(char *name, int len) { + for (int i = 0; i < native_func_cnt; i++) { + if (!strncmp(native_funcs[i].name, name, len) && native_funcs[i].name[len] == 0) + return i; + } + return -1; +} + +void register_native_func(char *name, NativeFunc func) { + NativeFuncDef *nf = &native_funcs[native_func_cnt++]; + strncpy(nf->name, name, 31); + nf->name[31] = 0; + nf->func = func; +} + +// --- Parser --- +long expression(); +void statement(); + +long factor() { + Token *t = &tokens[pc]; + long val = 0; + + if (t->type == Num) { + pc++; + return t->val; + } + else if (t->type == Str) { + pc++; + return (long)t->text; + } + else if (t->type == '(') { + pc++; + val = expression(); + match(')'); + return val; + } + else if (t->type == Id) { + if (tokens[pc + 1].type == '(') { + int nf_idx = find_native_func(t->text, t->val); + + if (nf_idx != -1) { + pc += 2; + long args[10]; + int argc = 0; + + if (tokens[pc].type != ')') { + do { + args[argc++] = expression(); + } while (tokens[pc].type == ',' && pc++); + } + match(')'); + + return native_funcs[nf_idx].func(args, argc); + } + + int f_idx = find_func(t->text, t->val); + if (f_idx == -1) error("Unknown function"); + pc += 2; + + int old_bp = bp; + long args[10]; + int argc = 0; + + if (tokens[pc].type != ')') { + do { + args[argc++] = expression(); + } while (tokens[pc].type == ',' && pc++); + } + match(')'); + + int ret_pc = pc; + memory[sp] = bp; bp = sp++; + memory[sp++] = ret_pc; + for(int i=0; itext, t->val); + if (idx == -1) error("Undefined variable"); + pc++; + + Symbol *sym = &locals[idx]; + + if (tokens[pc].type == '[') { + pc++; + long index = expression(); + match(']'); + return memory[sym->addr + index]; + } + + if (sym->is_array) { + return sym->addr; + } + + return memory[sym->addr]; + } + } + return 0; +} + +long ax = 0; + +long unary() { + if (tokens[pc].type == '*') { + pc++; + int addr = unary(); + // CAUTION: Simplified access. + // In real C, dereferencing char* reads a byte, int* reads int. + // Here, everything is 'long' cell in memory. + // This works for the specific request but is not byte-perfect. + // Since 'b' holds an address to 'src_code' (char*), reading memory[addr] is invalid + // if addr points to 'src_code'. 'memory' array is only for stack variables. + // To support reading chars from string literals: + + // Hack for reading string characters: + // If addr is outside virtual memory range, assume it's a pointer to raw C memory (string literal) + // This is a bit unsafe but needed for "char *b" where b points to tokens. + if (addr > MEM_SIZE * 8 || addr < 0) { // Rough heuristic for external pointer + return *(char*)addr; + } + return memory[addr]; + } + else if (tokens[pc].type == '&') { + pc++; + Token *t = &tokens[pc]; + if (t->type != Id) error("Expected identifier after &"); + int idx = find_local(t->text, t->val); + if (idx == -1) error("Undefined variable"); + pc++; + return locals[idx].addr; + } + else if (tokens[pc].type == '-') { + pc++; + return -unary(); + } + return factor(); +} + +long term() { + long val = unary(); + while (tokens[pc].type == '*' || tokens[pc].type == '/') { + int op = tokens[pc++].type; + long val2 = unary(); + if (op == '*') val = val * val2; + else val = val / val2; + } + return val; +} + +long add() { + long val = term(); + while (tokens[pc].type == '+' || tokens[pc].type == '-') { + int op = tokens[pc++].type; + long val2 = term(); + if (op == '+') val = val + val2; + else val = val - val2; + } + return val; +} + +long relational() { + long val = add(); + while (tokens[pc].type >= Eq && tokens[pc].type <= Ge) { + int op = tokens[pc++].type; + long val2 = add(); + if (op == Eq) val = val == val2; + if (op == Ne) val = val != val2; + if (op == Lt) val = val < val2; + if (op == Gt) val = val > val2; + } + return val; +} + +long expression() { + // Check for pointer assignment: *ptr = val (Not fully robust for *b = 'x', but ok for int*) + if (tokens[pc].type == '*') { + int save_pc = pc; + unary(); + if (tokens[pc].type == '=') { + pc = save_pc; + pc++; + long addr = unary(); + match('='); + long val = expression(); + if (addr >= 0 && addr < MEM_SIZE) memory[addr] = val; + return val; + } + pc = save_pc; + } + + if (tokens[pc].type == Id) { + if (tokens[pc+1].type == '[') { + int idx = find_local(tokens[pc].text, tokens[pc].val); + if (idx == -1) error("Assign to unknown var"); + pc += 2; + long index = expression(); + match(']'); + int addr = locals[idx].addr; + if (tokens[pc].type == '=') { + pc++; + long val = expression(); + memory[addr + index] = val; + return val; + } + return memory[addr + index]; + } else if (tokens[pc+1].type == '=') { + int idx = find_local(tokens[pc].text, tokens[pc].val); + if (idx == -1) error("Assign to unknown var"); + pc += 2; + long val = expression(); + memory[locals[idx].addr] = val; + return val; + } + } + + return relational(); +} + +void skip_block() { + int brace = 0; + do { + if (tokens[pc].type == '{') brace++; + if (tokens[pc].type == '}') brace--; + pc++; + } while (brace > 0 && tokens[pc].type != 0); +} + +void statement() { + if (tokens[pc].type == '{') { + pc++; + while (tokens[pc].type != '}' && tokens[pc].type != 0) { + statement(); + if (ax == -999) break; + } + match('}'); + } + else if (tokens[pc].type == Int || tokens[pc].type == Char) { + pc++; + while (tokens[pc].type != ';') { + while (tokens[pc].type == '*') pc++; + Token *t = &tokens[pc]; + match(Id); + + int addr = sp; + Symbol *s = &locals[loc_cnt++]; + strncpy(s->name, t->text, t->val); s->name[t->val] = 0; + s->addr = addr; + s->is_array = 0; + + if (tokens[pc].type == '[') { + pc++; + int size = (int)expression(); + match(']'); + s->is_array = 1; + sp += size; + } else { + sp++; + } + + if (tokens[pc].type == '=') { + pc++; + memory[addr] = expression(); + } + if (tokens[pc].type == ',') pc++; + } + match(';'); + } + else if (tokens[pc].type == If) { + pc++; + match('('); + long cond = expression(); + match(')'); + if (cond) { + statement(); + if (ax == -999) return; + if (tokens[pc].type == Else) { pc++; skip_block(); } + } else { + skip_block(); + if (tokens[pc].type == Else) { + pc++; + statement(); + if (ax == -999) return; + } + } + } + else if (tokens[pc].type == While) { + pc++; + int loop_start = pc; + match('('); + long cond = expression(); + match(')'); + while (cond) { + statement(); + if (ax == -999) return; + int save_pc = pc; + pc = loop_start; + match('('); + cond = expression(); + match(')'); + if (!cond) { pc = save_pc; break; } + } + if (!cond) skip_block(); + } + else if (tokens[pc].type == Return) { + pc++; + if (tokens[pc].type != ';') ax = expression(); + else ax = 0; + match(';'); + ax = -999; + } + else if (tokens[pc].type == Printf) { + pc++; + match('('); + char *fmt = tokens[pc].text; // Get raw format string + match(Str); + + char *p = fmt; + while (*p) { + if (*p == '%' && (p[1] == 'd' || p[1] == 's')) { + p++; // skip % + match(','); + long val = expression(); + if (*p == 'd') printf("%ld", val); + else if (*p == 's') printf("%s", (char*)val); + p++; // skip d or s + } else { + putchar(*p++); + } + } + match(')'); + match(';'); + } + else { + expression(); + match(';'); + } +} + +void scan_functions() { + int i = 0; + while (tokens[i].type != 0) { + // Simple scan: Type Id ( ... + if ((tokens[i].type == Int || tokens[i].type == Char) && + tokens[i+1].type == Id && tokens[i+2].type == '(') { + + Func *f = &funcs[func_cnt++]; + Token *name = &tokens[i+1]; + strncpy(f->name, name->text, name->val); f->name[name->val] = 0; + + i += 3; // Type Id ( + int params = 0; + while(tokens[i].type != ')') { + if (tokens[i].type == Int || tokens[i].type == Char) { + params++; + // Skip 'char * name' or 'int name' + i++; // Type + while (tokens[i].type == '*') i++; + if (tokens[i].type == Id) i++; + } else i++; + } + f->param_count = params; + i++; + f->entry_point = i; + + int brace = 0; + do { + if (tokens[i].type == '{') brace++; + if (tokens[i].type == '}') brace--; + i++; + } while (brace > 0 && tokens[i].type != 0); + } else { + i++; + } + } +} + +long native_socket(long *args, int argc) { + int domain = (int)args[0]; + int type = (int)args[1]; + int protocol = (int)args[2]; + return socket(domain, type, protocol); +} + +long native_bind(long *args, int argc) { + int sockfd = (int)args[0]; + int port = (int)args[1]; + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + return bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); +} + +long native_listen(long *args, int argc) { + int sockfd = (int)args[0]; + int backlog = (int)args[1]; + return listen(sockfd, backlog); +} + +long native_accept(long *args, int argc) { + int sockfd = (int)args[0]; + return accept(sockfd, NULL, NULL); +} + +long native_recv(long *args, int argc) { + int sockfd = (int)args[0]; + int addr = (int)args[1]; + int len = (int)args[2]; + int flags = (int)args[3]; + + char temp_buf[8192]; + if (len > 8192) len = 8192; + + int result = recv(sockfd, temp_buf, len, flags); + if (result > 0) { + for (int i = 0; i < result; i++) { + memory[addr + i] = temp_buf[i]; + } + } + return result; +} + +long native_send(long *args, int argc) { + int sockfd = (int)args[0]; + long buf_arg = args[1]; + int len = (int)args[2]; + int flags = (int)args[3]; + + if (buf_arg > MEM_SIZE * 8 || buf_arg < 0) { + return send(sockfd, (char*)buf_arg, len, flags); + } + + char temp_buf[8192]; + if (len > 8192) len = 8192; + + for (int i = 0; i < len; i++) { + temp_buf[i] = (char)memory[buf_arg + i]; + } + + return send(sockfd, temp_buf, len, flags); +} + +long native_close(long *args, int argc) { + int fd = (int)args[0]; + return close(fd); +} + +long native_strlen(long *args, int argc) { + char *str = (char*)args[0]; + return strlen(str); +} + +long native_AF_INET(long *args, int argc) { + return AF_INET; +} + +long native_SOCK_STREAM(long *args, int argc) { + return SOCK_STREAM; +} + +void register_native_functions() { + register_native_func("socket", native_socket); + register_native_func("bind", native_bind); + register_native_func("listen", native_listen); + register_native_func("accept", native_accept); + register_native_func("recv", native_recv); + register_native_func("send", native_send); + register_native_func("close", native_close); + register_native_func("strlen", native_strlen); + register_native_func("AF_INET", native_AF_INET); + register_native_func("SOCK_STREAM", native_SOCK_STREAM); +} + +int main(int argc, char **argv) { + if (argc < 2) { printf("Usage: ./mini_c file.c\n"); return 1; } + + FILE *f = fopen(argv[1], "rb"); + if (!f) { printf("Could not open file.\n"); return 1; } + + src_code = malloc(MAX_SRC); + size_t n = fread(src_code, 1, MAX_SRC, f); + src_code[n] = 0; + fclose(f); + + register_native_functions(); + + tokenize(src_code); + scan_functions(); + + int main_idx = find_func("main", 4); + if (main_idx == -1) { printf("No main function found.\n"); return 1; } + + pc = funcs[main_idx].entry_point; + memory[sp++] = 0; + memory[sp++] = 0; + + ax = 0; + statement(); + + return 0; +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..ecba4bb --- /dev/null +++ b/test.c @@ -0,0 +1,29 @@ + +int main() { + int sockfd; + int client_fd; + char buffer[1024]; + int bytes; + + printf("Creating socket\n"); + sockfd = socket(AF_INET(), SOCK_STREAM(), 0); + + printf("Binding\n"); + bind(sockfd, 8080); + + printf("Listening\n"); + listen(sockfd, 10); + + printf("Waiting for connection\n"); + client_fd = accept(sockfd, 0, 0); + printf("Client connected: %d\n", client_fd); + + bytes = recv(client_fd, buffer, 100, 0); + printf("Received %d bytes\n", bytes); + + send(client_fd, "HTTP/1.1 200 OK\n\nHello!\n", 24, 0); + + close(client_fd); + close(sockfd); + return 0; +} diff --git a/tokens.txt b/tokens.txt new file mode 100644 index 0000000000000000000000000000000000000000..48d049aa95aade8206d5f12cabc5672ab7dcc4a6 GIT binary patch literal 206 zcmYL?I}U+8cUDh0gP^C0)|kS*!ViQgOAXC$vnOy!g&WiX>P&- ze9+2>Aj)W7q&TMq#ia+Yv}zvJ^Jo=OtGb~zQ?&tav^Jt@!L{y-sak?Bv0Op86w3A2 oI@x{~?xWN4PTLMcKVUy%>`$qKtB`TQJYv_S%Q+p!bo@s429)+H`Tzg` literal 0 HcmV?d00001