bydgoszczscript

simple, fast and efficient programming language
git clone git://git.kocotian.pl/bydgoszczscript.git
Log | Files | Refs | README | LICENSE

commit 69fdab6ec8702275868879643213980bc6443084
parent 4e8d4dad2c8ee542319c88949ddb069d2b714bfd
Author: kocotian <kocotian@kocotian.pl>
Date:   Wed, 26 May 2021 15:16:47 +0200

Better type handling, obywatel (variable)

Diffstat:
Mcompile.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msamples/witajswiat.bs | 1+
2 files changed, 118 insertions(+), 13 deletions(-)

diff --git a/compile.c b/compile.c @@ -24,15 +24,24 @@ #include <compile.h> #include <stddef.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <errwarn.h> #include <str.h> +#include <util.h> +static String defaultType(void); static Token *enextToken(File *f, TokenType type); -static String evalType(String s); +static String g_type(File *f); static void g_miasto(File *f); +static String +defaultType(void) +{ + return (String){ .data = "int", .len = 3 }; +} + static Token * enextToken(File *f, TokenType type) { @@ -46,20 +55,114 @@ enextToken(File *f, TokenType type) } static String -evalType(String s) +g_type(File *f) { - if (!Strccmp(s, "literki")) - s.len = strlen(s.data = "char"); - if (!Strccmp(s, "cyferki")) - s.len = strlen(s.data = "int"); - if (!Strccmp(s, "latajace")) - s.len = strlen(s.data = "float"); - if (!Strccmp(s, "podwojne")) - s.len = strlen(s.data = "double"); + Token *t; + String name, s; + + int ptrlvl, isptrconst, isvalconst, isunsigned, isshort, islong; + /* + ** flags: + ** | long | short | unsigned | const value | const pointer | + */ + + ptrlvl = isptrconst = isvalconst = isunsigned = isshort = islong = 0; + + while ((t = enextToken(f, TokenIdentifier))) { + s = t->c; + if (!Strccmp(s, "wskaznik")) { + t = enextToken(f, TokenIdentifier); + if (Strccmp(t->c, "na")) + errwarn(*f, 1, "expected 'na' after 'wskaznik'"); + ++ptrlvl; + } else if (!Strccmp(s, "staly")) { + isptrconst = 1; + } else if (!Strccmp(s, "stale")) { + isvalconst = 1; + } else if (!Strccmp(s, "nieoznakowane")) { + isunsigned = 1; + } else if (!Strccmp(s, "oznakowane")) { + isunsigned = 2; + } else if (!Strccmp(s, "krotkie")) { + isshort = 1; + } else if (!Strccmp(s, "dlugie")) { + islong = 1; + } else { + if (!Strccmp(t->c, "literki")) + name.len = strlen(name.data = "char"); + else if (!Strccmp(t->c, "cyferki")) + name.len = strlen(name.data = "int"); + else if (!Strccmp(t->c, "latajace")) + name.len = strlen(name.data = "float"); + else if (!Strccmp(t->c, "podwojne")) + name.len = strlen(name.data = "double"); + else + name = t->c; + break; + } + } +#define TYPESIZ 256 + s.data = malloc(TYPESIZ); /* FIXME: Temporary! Not freed after usage! */ + if (isptrconst && ptrlvl) { + strncat(s.data, "const ", TYPESIZ - s.len); + s.len += 5; + } + if (isunsigned == 1) { + strncat(s.data, "unsigned ", TYPESIZ - s.len); + s.len += 9; + } else if (isunsigned == 2) { + strncat(s.data, "signed ", TYPESIZ - s.len); + s.len += 7; + } + if (isshort) { + strncat(s.data, "short ", TYPESIZ - s.len); + s.len += 6; + } else if (islong) { + strncat(s.data, "long ", TYPESIZ - s.len); + s.len += 5; + } + strncat(s.data, name.data, UMIN(TYPESIZ - s.len, name.len)); + if (ptrlvl) + while (ptrlvl--) + strncat(s.data, "*", TYPESIZ - s.len++); + if (isvalconst) { + strncat(s.data, " const", TYPESIZ - s.len); + s.len += 5; + } +#undef TYPESIZ + return s; } static void +g_obywatel(File *f) +{ + String name; + String type; + + Token *t; + + t = enextToken(f, TokenIdentifier); + name = t->c; + type = defaultType(); + while ((t = enextToken(f, TokenNULL))) { + if (t->type == TokenIdentifier) { + if (!Strccmp(t->c, "przechowuje")) { + type = g_type(f); + } else { + errwarn(*f, 1, "unexpected identifier (expected przechowuje)"); + } + } else if (t->type == TokenSemicolon) { + dprintf(f->outfd, "%.*s %.*s;\n", + Strevalf(type), Strevalf(name)); + return; + } else { + errwarn(*f, 1, "unexpected token (expected identifier or semicolon)"); + } + } +} + +static void g_aglomeracja(File *f) { Token *t; @@ -69,6 +172,8 @@ g_aglomeracja(File *f) if (!(Strccmp(t->c, "koniec"))) { dprintf(f->outfd, "}\n"); return; + } else if (!(Strccmp(t->c, "obywatel"))) { + g_obywatel(f); } else { errwarn(*f, 1, "unexpected identifier (expected a keyword)"); } @@ -90,7 +195,7 @@ g_miasto(File *f) t = enextToken(f, TokenIdentifier); name = t->c; - type.data = "int"; type.len = 3; + type = defaultType(); while ((t = enextToken(f, TokenNULL))) { if (t->type == TokenColon) { dprintf(f->outfd, "%.*s %.*s() {\n", @@ -99,8 +204,7 @@ g_miasto(File *f) return; } else if (t->type == TokenIdentifier) { if (!(Strccmp(t->c, "oddaje"))) { - t = enextToken(f, TokenIdentifier); - type = evalType(t->c); + type = g_type(f); } else { errwarn(*f, 1, "unexpected identifier (expected przyjmuje or oddaje)"); } diff --git a/samples/witajswiat.bs b/samples/witajswiat.bs @@ -1,4 +1,5 @@ wykorzystaj "stdio" poczatek miasta bydgoszcz: + obywatel i przechowuje cyferki; koniec