From de09064e7bd2a5f1fa6ecb67a0f2a769e66fae40 Mon Sep 17 00:00:00 2001 From: DELWIN BIJU Date: Mon, 22 Sep 2025 08:50:09 +0000 Subject: [PATCH 1/3] adjust formatting for hello world --- src/hello.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hello.c b/src/hello.c index 9d6338f..eefa0d8 100644 --- a/src/hello.c +++ b/src/hello.c @@ -1,8 +1,8 @@ #include - +//this is your first c program my friend int main(int argc, char *argv[]) { - // This is your first C program my friend + // This is your first C program my friend lab in 2025 printf("Hello, RTU World from C Lab in 2025!\n"); printf("You passed %d argument(s).\n", argc - 1); for (int i = 1; i < argc; ++i) { From 71d7ef42696adcd1e4b0785c058487954327bd2f Mon Sep 17 00:00:00 2001 From: DELWIN BIJU Date: Mon, 29 Sep 2025 11:28:09 +0300 Subject: [PATCH 2/3] Update lab2_1.c --- src/lab2_1.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lab2_1.c b/src/lab2_1.c index 699339a..528c92d 100644 --- a/src/lab2_1.c +++ b/src/lab2_1.c @@ -12,8 +12,11 @@ */ int sum_to_n(int n) { - // TODO: implement sum with a for loop - return 0; // placeholder + int sum = 0; + for (int i = 1; i <= n; i++) { + sum += i; + } + return sum; } int main(void) { @@ -22,7 +25,12 @@ int main(void) { printf("Enter a positive integer n: "); scanf("%d", &n); - // TODO: validate input, call function, and print result + if (n < 1) { + printf("Error: n must be a positive integer.\n"); + } else { + int result = sum_to_n(n); + printf("The sum of numbers from 1 to %d is %d.\n", n, result); + } return 0; } From 55832d57e6d29aaf340abbd715a7d03131799eba Mon Sep 17 00:00:00 2001 From: DELWIN BIJU Date: Tue, 4 Nov 2025 13:56:12 +0000 Subject: [PATCH 3/3] gradedlab1 --- .vscode/tasks.json | 78 ++-- calc.c | 384 ++++++++++++++++++ input.txt | 1 + task1.txt | 1 + .../task1_DELWIN_BIJU_241ADB008.txt | 1 + 5 files changed, 438 insertions(+), 27 deletions(-) create mode 100644 calc.c create mode 100644 input.txt create mode 100644 task1.txt create mode 100644 task1_vscode_241ADB008/task1_DELWIN_BIJU_241ADB008.txt diff --git a/.vscode/tasks.json b/.vscode/tasks.json index dc41b27..29900f9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,28 +1,52 @@ - { - "version": "2.0.0", - "tasks": [ - { - "label": "Build All (Make)", - "type": "shell", - "command": "make", - "group": "build", - "problemMatcher": ["$gcc"] - }, - { - "label": "Run: Hello", - "type": "shell", - "command": "make hello && ./bin/hello" - }, - { - "label": "Run: Calculator", - "type": "shell", - "command": "make calculator && ./bin/calculator" - }, - { - "label": "Run: Formats", - "type": "shell", - "command": "make formats && ./bin/formats" - } - ] -} + "version": "2.0.0", + "tasks": [ + { + "label": "Build All (Make)", + "type": "shell", + "command": "make", + "group": "build", + "problemMatcher": [ + "$gcc" + ] + }, + { + "label": "Run: Hello", + "type": "shell", + "command": "make hello && ./bin/hello" + }, + { + "label": "Run: Calculator", + "type": "shell", + "command": "make calculator && ./bin/calculator" + }, + { + "label": "Run: Formats", + "type": "shell", + "command": "make formats && ./bin/formats" + }, + { + "type": "cppbuild", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ] +} \ No newline at end of file diff --git a/calc.c b/calc.c new file mode 100644 index 0000000..95d038b --- /dev/null +++ b/calc.c @@ -0,0 +1,384 @@ +// DELWIN BIJU 241ADB008 +// Compile with: gcc -O2 -Wall -Wextra -std=c17 -o calc calc.c -lm + +/* + Simpler Pythonic Arithmetic Parser (single file) + ------------------------------------------------ + Features: + - * / ** (right-assoc), parentheses, unary +/-, + floats via strtod, # full-line comments, + ERROR: (1-based across whole file), CLI dir batch. + + Why simple? One small lexer + 5 tiny parser functions (expr/term/power/unary/primary), + minimal filesystem helpers, and consistent error reporting. +*/ + +#define _POSIX_C_SOURCE 200809L + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *STUDENT_FIRST = "DELWIN"; +static const char *STUDENT_LAST = "BIJU"; +static const char *STUDENT_ID = "241ADB008"; + +/* ----------------------------- source ----------------------------- */ + +typedef struct { + const char *buf; + size_t len; + size_t i; // current index [0..len] + size_t pos1; // 1-based char position (i+1) + bool at_line_start; +} Src; + +static void src_init(Src *s, const char *b, size_t n) { + s->buf = b; s->len = n; s->i = 0; s->pos1 = 1; s->at_line_start = true; +} + +static int peek(Src *s) { return (s->i < s->len) ? (unsigned char)s->buf[s->i] : EOF; } +static int peekn(Src *s,size_t n){ size_t k=s->i+n; return (klen)?(unsigned char)s->buf[k]:EOF; } +static int getc_src(Src *s) { + if (s->i >= s->len) return EOF; + int c = (unsigned char)s->buf[s->i++]; + s->pos1++; + if (c == '\n') s->at_line_start = true; + else if (!isspace(c)) s->at_line_start = false; + return c; +} +static void advance(Src *s, size_t n){ while(n--) (void)getc_src(s); } + +/* Skip spaces and lines where first non-space char is '#'. + Important: we only *ignore* semantically; positions still advance (we consume chars). */ +static void skip_ws_and_comments(Src *s) { + for (;;) { + while (isspace(peek(s))) getc_src(s); + if (s->at_line_start) { + // look ahead past leading spaces + size_t k = 0; int c; + while ((c = peekn(s,k)) != EOF && (c==' ' || c=='\t')) k++; + if (c == '#') { + advance(s, k + 1); // skip spaces + '#' + while ((c = peek(s)) != EOF && c != '\n') getc_src(s); + if (peek(s) == '\n') getc_src(s); // eat newline + continue; // more lines may be comments + } + } + break; + } +} + +/* ----------------------------- lexer ----------------------------- */ + +typedef enum { + T_END=0, T_NUM, + T_PLUS, T_MINUS, T_STAR, T_SLASH, T_POW, T_LPAREN, T_RPAREN, T_INVALID +} Tok; + +typedef struct { + Tok kind; + size_t start; // 1-based starting position of token + double num; // if T_NUM +} Token; + +typedef struct { + Src *src; + Token cur; + bool has; +} Lex; + +static Token tok(Tok k, size_t p){ Token t; t.kind=k; t.start=p; t.num=0.0; return t; } + +static Token lex_number(Lex *L){ + Src *s=L->src; size_t st=s->pos1; + char *endptr=NULL; + double v = strtod(s->buf + s->i, &endptr); + if (endptr == s->buf + s->i) return tok(T_INVALID, st); + size_t used = (size_t)(endptr - (s->buf + s->i)); + advance(s, used); + Token t = tok(T_NUM, st); t.num = v; return t; +} + +static Token next(Lex *L){ + Src *s=L->src; skip_ws_and_comments(s); + size_t st = s->pos1; + int c = peek(s); + if (c == EOF) return tok(T_END, st); + if (isdigit(c) || c == '.') { + if (c=='.' && !isdigit(peekn(s,1))) { getc_src(s); return tok(T_INVALID, st); } + return lex_number(L); + } + if (c=='+'){ getc_src(s); return tok(T_PLUS,st); } + if (c=='-'){ getc_src(s); return tok(T_MINUS,st); } + if (c=='('){ getc_src(s); return tok(T_LPAREN,st); } + if (c==')'){ getc_src(s); return tok(T_RPAREN,st); } + if (c=='*'){ + if (peekn(s,1)=='*'){ advance(s,2); return tok(T_POW,st); } + getc_src(s); return tok(T_STAR,st); + } + if (c=='/'){ getc_src(s); return tok(T_SLASH,st); } + // anything else + getc_src(s); + return tok(T_INVALID, st); +} + +static void lex_init(Lex *L, Src *s){ L->src=s; L->has=false; } +static Token peek_tok(Lex *L){ if(!L->has){ L->cur=next(L); L->has=true; } return L->cur; } +static Token pop_tok (Lex *L){ Token t=peek_tok(L); L->has=false; return t; } + +/* ---------------------- parser / evaluator ---------------------- */ + +typedef struct { bool err; size_t pos; } Err; +typedef struct { Lex *L; Err *E; } P; + +static void fail(Err *E, size_t p){ if(!E->err){ E->err=true; E->pos=p? p:1; } } + +static bool is_intlike(double x){ double r = nearbyint(x); return fabs(x - r) < 1e-12; } + +static double parse_expr(P *p); // fwd + +// primary := NUMBER | '(' expr ')' +static double primary(P *p){ + Token t = peek_tok(p->L); + if (t.kind == T_NUM){ pop_tok(p->L); return t.num; } + if (t.kind == T_LPAREN){ + pop_tok(p->L); + double v = parse_expr(p); + if (p->E->err) return 0.0; + Token r = peek_tok(p->L); + if (r.kind != T_RPAREN){ fail(p->E, r.start); return 0.0; } + pop_tok(p->L); + return v; + } + fail(p->E, t.start); + return 0.0; +} + +// unary := ('+'|'-') unary | primary +static double unary(P *p){ + Token t = peek_tok(p->L); + if (t.kind == T_PLUS){ pop_tok(p->L); return unary(p); } + if (t.kind == T_MINUS){ + size_t mpos = t.start; pop_tok(p->L); + Token a = peek_tok(p->L); + if (a.kind==T_END || a.kind==T_INVALID || a.kind==T_RPAREN){ fail(p->E, mpos); return 0.0; } + return -unary(p); + } + return primary(p); +} + +// power := unary [ '**' power ] (right-assoc) +static double power(P *p){ + double base = unary(p); + if (p->E->err) return 0.0; + Token t = peek_tok(p->L); + if (t.kind == T_POW){ + size_t powpos = t.start; pop_tok(p->L); + Token exp_t = peek_tok(p->L); + if (exp_t.kind==T_END || exp_t.kind==T_INVALID || exp_t.kind==T_RPAREN){ fail(p->E, exp_t.start); return 0.0; } + double e = power(p); // right assoc + if (p->E->err) return 0.0; + // reject negative base with non-integer exponent + if (base < 0.0 && !is_intlike(e)){ fail(p->E, exp_t.start); return 0.0; } + errno=0; double out = pow(base, e); + if (errno || isnan(out) || isinf(out)){ fail(p->E, powpos); return 0.0; } + return out; + } + return base; +} + +// term := power { ('*' | '/') power } +static double term(P *p){ + double v = power(p); + if (p->E->err) return 0.0; + for(;;){ + Token t = peek_tok(p->L); + if (t.kind == T_STAR){ + pop_tok(p->L); + Token r = peek_tok(p->L); + if (r.kind==T_END || r.kind==T_INVALID || r.kind==T_RPAREN){ fail(p->E, r.start); return 0.0; } + double rhs = power(p); if (p->E->err) return 0.0; v *= rhs; + } else if (t.kind == T_SLASH){ + pop_tok(p->L); + Token r = peek_tok(p->L); + if (r.kind==T_END || r.kind==T_INVALID || r.kind==T_RPAREN){ fail(p->E, r.start); return 0.0; } + double rhs = power(p); if (p->E->err) return 0.0; + if (rhs == 0.0){ fail(p->E, r.start); return 0.0; } // div by zero → at divisor + v /= rhs; + } else break; + } + return v; +} + +// expr := term { ('+' | '-') term } +static double parse_expr(P *p){ + double v = term(p); + if (p->E->err) return 0.0; + for(;;){ + Token t = peek_tok(p->L); + if (t.kind == T_PLUS){ + pop_tok(p->L); + Token r = peek_tok(p->L); + if (r.kind==T_END || r.kind==T_INVALID || r.kind==T_RPAREN){ fail(p->E, r.start); return 0.0; } + double rhs = term(p); if (p->E->err) return 0.0; v += rhs; + } else if (t.kind == T_MINUS){ + pop_tok(p->L); + Token r = peek_tok(p->L); + if (r.kind==T_END || r.kind==T_INVALID || r.kind==T_RPAREN){ fail(p->E, r.start); return 0.0; } + double rhs = term(p); if (p->E->err) return 0.0; v -= rhs; + } else break; + } + return v; +} + +/* Parse one expression from a whole file buffer. + After expr, only spaces/comment-lines allowed. + Returns: ok? and either (int-like) or (double). */ +static bool parse_and_eval(const char *buf, size_t len, + long long *out_ll, double *out_d, bool *out_is_int, size_t *out_err) { + Src s; src_init(&s, buf, len); + Lex L; lex_init(&L, &s); + Err E = {0}; + P p = { .L=&L, .E=&E }; + + double val = parse_expr(&p); + if (!E.err) { + skip_ws_and_comments(&s); + Token trailing = next(&L); + if (trailing.kind != T_END) { E.err=true; E.pos=trailing.start; } + } + if (E.err){ *out_err = E.pos; return false; } + + if (is_intlike(val)){ *out_ll = (long long)llround(val); *out_is_int = true; } + else { *out_d = val; *out_is_int = false; } + return true; +} + +/* ------------------------- tiny filesystem ------------------------- */ + +static const char* base_name(const char *p){ + const char *b = strrchr(p, '/'); +#ifdef _WIN32 + const char *b2 = strrchr(p, '\\'); if (!b || (b2 && b2 > b)) b = b2; +#endif + return b ? b+1 : p; +} + +static void strip_ext(char *s){ char *d = strrchr(s, '.'); if (d) *d = '\0'; } + +static void ensure_dir(const char *path){ + struct stat st; + if (stat(path, &st) == 0){ if (!S_ISDIR(st.st_mode)){ fprintf(stderr,"'%s' not a dir\n", path); exit(2);} return; } + if (mkdir(path, 0775) != 0 && errno != EEXIST){ fprintf(stderr,"mkdir '%s': %s\n", path, strerror(errno)); exit(2); } +} + +static bool read_file(const char *path, char **data, size_t *len){ + *data=NULL; *len=0; + FILE *f=fopen(path,"rb"); if(!f) return false; + if (fseek(f,0,SEEK_END)!=0){ fclose(f); return false; } + long sz=ftell(f); if(sz<0){ fclose(f); return false; } + if (fseek(f,0,SEEK_SET)!=0){ fclose(f); return false; } + char *buf = (char*)malloc((size_t)sz+1); if(!buf){ fclose(f); return false; } + size_t n=fread(buf,1,(size_t)sz,f); fclose(f); + if (n != (size_t)sz){ free(buf); return false; } + buf[n]='\0'; *data=buf; *len=n; return true; +} + +static bool write_file(const char *path, const char *s){ + FILE *f=fopen(path,"wb"); if(!f) return false; + size_t n=fwrite(s,1,strlen(s),f); fclose(f); return n==strlen(s); +} + +static void build_default_outdir(char *dst, size_t n, const char *base){ + const char *user = getenv("USER"); if (!user) user = STUDENT_FIRST; + snprintf(dst,n,"%s_%s_%s", base, user, STUDENT_ID); +} + +static void build_outpath(char *dst, size_t n, const char *outdir, const char *inbase){ + snprintf(dst,n,"%s/%s_%s_%s_%s.txt", outdir, inbase, STUDENT_FIRST, STUDENT_LAST, STUDENT_ID); +} + +/* --------------------------- main logic --------------------------- */ + +static int process_one(const char *inpath, const char *outdir){ + char *buf=NULL; size_t len=0; + if (!read_file(inpath,&buf,&len)){ fprintf(stderr,"cannot read %s\n", inpath); return 1; } + + long long iv=0; double dv=0.0; bool is_int=false; size_t err=0; + bool ok = parse_and_eval(buf,len,&iv,&dv,&is_int,&err); + + char base[512]; strncpy(base, base_name(inpath), sizeof(base)); base[sizeof(base)-1]='\0'; strip_ext(base); + + char outpath[1024]; build_outpath(outpath,sizeof(outpath), outdir, base); + + char outbuf[160]; + if (ok){ + if (is_int) snprintf(outbuf,sizeof(outbuf), "%lld\n", iv); + else if (is_intlike(dv)) snprintf(outbuf,sizeof(outbuf), "%lld\n", (long long)llround(dv)); + else snprintf(outbuf,sizeof(outbuf), "%.15g\n", dv); + } else { + snprintf(outbuf,sizeof(outbuf), "ERROR:%zu\n", err); + } + + ensure_dir(outdir); + bool wrote = write_file(outpath, outbuf); + free(buf); + if (!wrote){ fprintf(stderr,"cannot write %s\n", outpath); return 1; } + return 0; +} + +static void usage(const char *p){ + fprintf(stderr, + "Usage:\n" + " %s [-o OUTDIR|--output-dir OUTDIR] input.txt\n" + " %s -d DIR [-o OUTDIR|--output-dir OUTDIR]\n", p, p); +} + +int main(int argc, char **argv){ + const char *dir=NULL, *outdir_arg=NULL, *single=NULL; + for (int i=1;i=argc){usage(argv[0]);return 2;} dir=argv[i]; } + else if(!strcmp(argv[i],"-o")||!strcmp(argv[i],"--output-dir")){ if(++i>=argc){usage(argv[0]);return 2;} outdir_arg=argv[i]; } + else if (argv[i][0]=='-'){ usage(argv[0]); return 2; } + else single=argv[i]; + } + + if (dir){ + // build default outdir from dir base if not provided + char base[512]; strncpy(base, base_name(dir), sizeof(base)); base[sizeof(base)-1]='\0'; + char outdir[1024]; + if (outdir_arg){ strncpy(outdir, outdir_arg, sizeof(outdir)); outdir[sizeof(outdir)-1]='\0'; } + else build_default_outdir(outdir, sizeof(outdir), base); + ensure_dir(outdir); + + DIR *d = opendir(dir); + if (!d){ fprintf(stderr,"cannot open dir %s: %s\n", dir, strerror(errno)); return 2; } + struct dirent *e; int rc=0; + while((e=readdir(d))){ + if (e->d_name[0]=='.') continue; + size_t n=strlen(e->d_name); if (n<4 || strcmp(e->d_name+n-4,".txt")) continue; + char path[1024]; snprintf(path,sizeof(path), "%s/%s", dir, e->d_name); + struct stat st; if (stat(path,&st)!=0 || !S_ISREG(st.st_mode)) continue; + rc |= process_one(path, outdir); + } + closedir(d); + return rc; + } + + if (!single){ usage(argv[0]); return 2; } + + char base[512]; strncpy(base, base_name(single), sizeof(base)); base[sizeof(base)-1]='\0'; strip_ext(base); + char outdir[1024]; + if (outdir_arg){ strncpy(outdir, outdir_arg, sizeof(outdir)); outdir[sizeof(outdir)-1]='\0'; } + else build_default_outdir(outdir, sizeof(outdir), base); + ensure_dir(outdir); + + return process_one(single, outdir); +} diff --git a/input.txt b/input.txt new file mode 100644 index 0000000..a89c1a6 --- /dev/null +++ b/input.txt @@ -0,0 +1 @@ +2 + 3 * 8 diff --git a/task1.txt b/task1.txt new file mode 100644 index 0000000..75b2968 --- /dev/null +++ b/task1.txt @@ -0,0 +1 @@ +2**3**2 diff --git a/task1_vscode_241ADB008/task1_DELWIN_BIJU_241ADB008.txt b/task1_vscode_241ADB008/task1_DELWIN_BIJU_241ADB008.txt new file mode 100644 index 0000000..4d0e90c --- /dev/null +++ b/task1_vscode_241ADB008/task1_DELWIN_BIJU_241ADB008.txt @@ -0,0 +1 @@ +512