#!/usr/bin/env bash
# Prints whether a list of keywords is a keyword in Solidity or Yul using Solc.

kws=(
    "abstract"
    "anonymous"
    "as"
    "assembly"
    "break"
    "catch"
    "constant"
    "constructor"
    "continue"
    "contract"
    "do"
    "else"
    "enum"
    "emit"
    "event"
    "external"
    "fallback"
    "for"
    "function"
    "hex"
    "if"
    "indexed"
    "interface"
    "internal"
    "immutable"
    "import"
    "is"
    "library"
    "mapping"
    "memory"
    "modifier"
    "new"
    "override"
    "payable"
    "public"
    "pragma"
    "private"
    "pure"
    "receive"
    "return"
    "returns"
    "storage"
    "calldata"
    "struct"
    "throw"
    "try"
    "type"
    "unchecked"
    "unicode"
    "using"
    "view"
    "virtual"
    "while"
    "int"
    "int8"
    "int16"
    "int24"
    "int32"
    "int40"
    "int48"
    "int56"
    "int64"
    "int72"
    "int80"
    "int88"
    "int96"
    "int104"
    "int112"
    "int120"
    "int128"
    "int136"
    "int144"
    "int152"
    "int160"
    "int168"
    "int176"
    "int184"
    "int192"
    "int200"
    "int208"
    "int216"
    "int224"
    "int232"
    "int240"
    "int248"
    "int256"
    "uint"
    "uint8"
    "uint16"
    "uint24"
    "uint32"
    "uint40"
    "uint48"
    "uint56"
    "uint64"
    "uint72"
    "uint80"
    "uint88"
    "uint96"
    "uint104"
    "uint112"
    "uint120"
    "uint128"
    "uint136"
    "uint144"
    "uint152"
    "uint160"
    "uint168"
    "uint176"
    "uint184"
    "uint192"
    "uint200"
    "uint208"
    "uint216"
    "uint224"
    "uint232"
    "uint240"
    "uint248"
    "uint256"
    "bytes"
    "bytes1"
    "bytes2"
    "bytes3"
    "bytes4"
    "bytes5"
    "bytes6"
    "bytes7"
    "bytes8"
    "bytes9"
    "bytes10"
    "bytes11"
    "bytes12"
    "bytes13"
    "bytes14"
    "bytes15"
    "bytes16"
    "bytes17"
    "bytes18"
    "bytes19"
    "bytes20"
    "bytes21"
    "bytes22"
    "bytes23"
    "bytes24"
    "bytes25"
    "bytes26"
    "bytes27"
    "bytes28"
    "bytes29"
    "bytes30"
    "bytes31"
    "bytes32"
    "string"
    "address"
    "bool"
    "fixed"
    "ufixed"
    "wei"
    "gwei"
    "ether"
    "seconds"
    "minutes"
    "hours"
    "days"
    "weeks"
    "years"
    "true"
    "false"
    "after"
    "alias"
    "apply"
    "auto"
    "byte"
    "case"
    "copyof"
    "default"
    "define"
    "final"
    "implements"
    "in"
    "inline"
    "let"
    "macro"
    "match"
    "mutable"
    "null"
    "of"
    "partial"
    "promise"
    "reference"
    "relocatable"
    "sealed"
    "sizeof"
    "static"
    "supports"
    "switch"
    "typedef"
    "typeof"
    "var"
    "leave"
    "revert"
    "class"
    "instantiation"
    "Integer"
    "itself"
    "static_assert"
    "__builtin"
)
if [[ $# -gt 0 ]]; then
    kws=("$@")
fi
n=${#kws[@]}
align=$(printf "%s\n" "${kws[@]}" | awk '{print length+1}' | sort -nr | head -1)

echo "Solidity:"
for kw in "${kws[@]}"; do
    r=$(echo "function f(){bool $kw;}" | solc - 2>&1)
    code=$?

    [ "$n" -eq 1 ] && printf "%s\n" "$r"

    if [[ $code -gt 0 ]]; then
        result="yes"
    else
        result="no"
    fi
    printf "%-${align}s %s\n" "$kw:" "$result"
done

echo
echo "Yul:"
for kw in "${kws[@]}"; do
    r=$(echo "function f(){assembly{let $kw := 0}}" | solc - 2>&1)
    code=$?

    [ "$n" -eq 1 ] && printf "%s\n" "$r"

    if [[ $code -gt 0 ]]; then
        result="yes"
    else
        result="no"
    fi
    printf "%-${align}s %s\n" "$kw:" "$result"
done
