Skip to content

Commit

Permalink
Merge pull request #1226 from andrew-johnson-4/ansi-c-frontend-qpfeok
Browse files Browse the repository at this point in the history
Ansi c frontend qpfeok
  • Loading branch information
andrew-johnson-4 authored Feb 8, 2025
2 parents c21d3c2 + 286346c commit 3909a67
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 16 deletions.
41 changes: 29 additions & 12 deletions PLUGINS/FRONTEND/C/c-parse.lsts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
type CConstant = CConstantInteger{value:String}
| CConstantCharacter{value:String}
| CConstantFloating{value:String}
| CConstantEnumeration{value:String};
| CConstantEnumeration{value:String}
| CConstantString{value:String};

let cmp(l: CConstant, r: CConstant): Ord = (
if $".0"(l) != $".0"(r) then cmp($".0"(l), $".0"(r))
Expand All @@ -18,6 +19,7 @@ let cmp(l: CConstant, r: CConstant): Ord = (
Tuple{ first:CConstantCharacter{lv=value}, second:CConstantCharacter{rv=value} } => cmp(lv, rv);
Tuple{ first:CConstantFloating{lv=value}, second:CConstantFloating{rv=value} } => cmp(lv, rv);
Tuple{ first:CConstantEnumeration{lv=value}, second:CConstantEnumeration{rv=value} } => cmp(lv, rv);
Tuple{ first:CConstantString{lv=value}, second:CConstantString{rv=value} } => cmp(lv, rv);
}
);

Expand Down Expand Up @@ -85,6 +87,8 @@ let std-c-has-class(tks: String, cls: String): U64 = (
"character" => tk == r/^(u8|u|U|L)?[']([^']|([\\][']))+[']/; # character constant
"floating" => tk == r/^[0-9]+([.][0-9]+)?([eE][0-9]+)?[fF]?/ # decimal constant
|| tk == r/^[0][x][0-9a-fA-F]+([.][0-9a-fA-F]+)?([eE][0-9a-fA-F]+)?([pP][0-9]+)[fF]?/; # hexadecimal constant
"string" => tk == r/^[RLuU8]*["]([^"\\]|([\\].))*["]/;
"enumeration" => std-c-enumeration-constant-index.has(tks);
_ => tk == cls;
}
);
Expand Down Expand Up @@ -374,7 +378,21 @@ let std-c-take-maybe(tokens: List<Token>, cls: String): List<Token> = (
# Tuple{ Some{base-declarator}, tokens };
#);

#identifier-list = identifier, {',', identifier};
let std-c-parse-identifier-list(tokens: List<Token>): Tuple<Maybe<List<String>>,List<Token>> = (
let no = None :: Maybe<List<String>>;
if std-c-can-take(tokens, "identifier") then {
let ids = [head(tokens).skey];
tokens = std-c-take-expect(tokens, "identifier");
while std-c-can-take(tokens, ",") {
tokens = std-c-take-expect(tokens, ",");
if non-zero(tokens) {
ids = cons( head(tokens).skey, ids );
};
tokens = std-c-take-expect(tokens, "identifier");
};
Tuple{ Some{ids.reverse}, tokens }
} else Tuple{no, tokens};
);

#initializer-list = designative-initializer, {',', designative-initializer};

Expand Down Expand Up @@ -404,8 +422,6 @@ let std-c-take-maybe(tokens: List<Token>, cls: String): List<Token> = (
#(* NOTE: Please define enumeration-constant for identifier inside enum { ... }. *)
#enumerator = enumeration-constant, ['=', constant-expression];

#enumeration-constant = identifier;

#type-name = specifier-qualifier-list, [abstract-declarator];

#specifier-qualifier-list = specifier-qualifier, {specifier-qualifier};
Expand Down Expand Up @@ -481,20 +497,23 @@ let std-c-parse-identifier(tokens: List<Token>): Tuple<Maybe<String>,List<Token>
else Tuple{ no, tokens }
);

let std-c-enumeration-constant-index = {} :: HashtableEq<String,Bool>;

let std-c-parse-constant(tokens: List<Token>): Tuple<Maybe<CConstant>,List<Token>> = (
let no = None :: Maybe<CConstant>;
if std-c-can-take(tokens, "integer") then Tuple{ Some{CConstantInteger{head(tokens).skey}}, tail(tokens) }
else if std-c-can-take(tokens, "character") then Tuple{ Some{CConstantCharacter{head(tokens).skey}}, tail(tokens) }
else if std-c-can-take(tokens, "floating") then Tuple{ Some{CConstantFloating{head(tokens).skey}}, tail(tokens) }
#else if std-c-can-take(tokens, "enumeration") then Tuple{ Some{CConstantFloating{head(tokens).key}}, tail(tokens) }
else if std-c-can-take(tokens, "enumeration") then Tuple{ Some{CConstantEnumeration{head(tokens).skey}}, tail(tokens) }
else Tuple{ no, tokens }
);

#constant = integer-constant
# | character-constant
# | floating-constant
# | enumeration-constant;

let std-c-parse-string(tokens: List<Token>): Tuple<Maybe<CConstant>,List<Token>> = (
let no = None :: Maybe<CConstant>;
if std-c-can-take(tokens, "string") then Tuple{ Some{CConstantString{head(tokens).skey}}, tail(tokens) }
else if std-c-can-take(tokens, "__func__") then Tuple{ Some{CConstantString{head(tokens).skey}}, tail(tokens) }
else Tuple{ no, tokens }
);

#parameter-list = parameter-declaration, {',', parameter-declaration};

Expand Down Expand Up @@ -554,8 +573,6 @@ let std-c-parse-constant(tokens: List<Token>): Tuple<Maybe<CConstant>,List<Token
#argument-expression-list = assignment-expression, {',', assignment-expression};


#string = string-literal
# | '__func__';

#generic-selection = '_Generic', '(', assignment-expression, ',', generic-assoc-list, ')';

Expand Down
8 changes: 4 additions & 4 deletions PLUGINS/FRONTEND/C/c-smart-tokenize.lsts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ let std-c-tokenize-string(file-path: String, text: String): List<Token> = (
tokens = cons(text[:cl.length], tokens); text = rest;
);

(id=r/^[a-zA-Z0-9_]+/).. rest => (
tokens = cons(text[:id.length], tokens); text = rest;
(lit=r/^[RLuU8]*["]([^"\\]|([\\].))*["]/).. rest => (
tokens = cons(text[:lit.length], tokens); text = rest;
);

(lit=r/^["]([^"\\]|([\\].))*["]/).. rest => (
tokens = cons(text[:lit.length], tokens); text = rest;
(id=r/^[a-zA-Z0-9_]+/).. rest => (
tokens = cons(text[:id.length], tokens); text = rest;
);

(comment=r/^#[^\n]*[\n]/).. rest => (
Expand Down
34 changes: 34 additions & 0 deletions tests/c/c-parse.lsts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import SRC/unit-error.lsts;
import PLUGINS/FRONTEND/C/index-index.lm;
import PLUGINS/FRONTEND/C/index-index.lm;

std-c-enumeration-constant-index = std-c-enumeration-constant-index.bind("enum1case", true);

# helpers
if true then {
let tokens = std-c-tokenize-string("[+]", "+");
Expand Down Expand Up @@ -191,4 +193,36 @@ if true then {
let tokens = std-c-tokenize-string("0x3p2", "0x3p2");
assert( std-c-parse-constant(tokens).first == Some{CConstantFloating{"0x3p2"}} );
};
if true then {
let tokens = std-c-tokenize-string("enum1case", "enum1case");
assert( std-c-parse-constant(tokens).first == Some{CConstantEnumeration{"enum1case"}} );
};
if true then {
let tokens = std-c-tokenize-string("\"abc\"", "\"abc\"");
assert( std-c-parse-string(tokens).first == Some{CConstantString{"\"abc\""}} );
};
if true then {
let tokens = std-c-tokenize-string("u8\"abc\"", "u8\"abc\"");
assert( std-c-parse-string(tokens).first == Some{CConstantString{"u8\"abc\""}} );
};
if true then {
let tokens = std-c-tokenize-string("__func__", "__func__");
assert( std-c-parse-string(tokens).first == Some{CConstantString{"__func__"}} );
};
};

if true then {
if true then {
let tokens = std-c-tokenize-string("123", "123");
assert( std-c-parse-identifier-list(tokens).first.is-none );
assert( is(std-c-parse-identifier-list(tokens).second, tokens) );
};
if true then {
let tokens = std-c-tokenize-string("a", "a");
assert( std-c-parse-identifier-list(tokens).first == Some{["a"]} );
};
if true then {
let tokens = std-c-tokenize-string("a, _1", "a, _1");
assert( std-c-parse-identifier-list(tokens).first == Some{["a","_1"]} );
};
};

0 comments on commit 3909a67

Please sign in to comment.