diff options
| Commit | 06811744a002f4ab332d94d510475231afcd45a1 (patch) | |
|---|---|---|
| Author | 2018-11-03 13:36:57 +0200 | |
| Committer | 2018-11-03 13:36:57 +0200 | |
| Files | 91c41776fbdf899dcb61a8d5df3ac1316c24f3c8 | |
| IPL-06811744a002f4ab332d94d510475231afcd45a1.tar IPL-06811744a002f4ab332d94d510475231afcd45a1.tar.gz IPL-06811744a002f4ab332d94d510475231afcd45a1.zip | ||
| Parent | 26e5f891d537b5d4fc2890c9cdbeb73d5748d568 (diff) | |
First HW (#9)
* Add 1st hw
* --amend
* moving readme for 1st hw to designated folder
* renamed TokenType enum to TokenClass
* fixed character constant lexing. added sampe output file
* add new line at end-of-file. added gitignore
* a bit of refactoring
9 files changed, 880 insertions, 0 deletions
| -rw-r--r-- | homework/81568/c2html/.gitignore | 2 | ||||
| -rw-r--r-- | homework/81568/c2html/Makefile | 2 | ||||
| -rw-r--r-- | homework/81568/c2html/README.md | 8 | ||||
| -rw-r--r-- | homework/81568/c2html/lexcer.cpp | 413 | ||||
| -rw-r--r-- | homework/81568/c2html/lexcer.h | 84 | ||||
| -rw-r--r-- | homework/81568/c2html/lexconst.h | 39 | ||||
| -rw-r--r-- | homework/81568/c2html/main.cpp | 73 | ||||
| -rw-r--r-- | homework/81568/c2html/test.c | 108 | ||||
| -rw-r--r-- | homework/81568/c2html/test.html | 151 |
diff --git a/homework/81568/c2html/.gitignore b/homework/81568/c2html/.gitignore new file mode 100644 index 0000000..c5a122e --- /dev/null +++ b/homework/81568/c2html/.gitignore @@ -0,0 +1,2 @@ +lexcer +TAGS diff --git a/homework/81568/c2html/Makefile b/homework/81568/c2html/Makefile new file mode 100644 index 0000000..d41a5a4 --- /dev/null +++ b/homework/81568/c2html/Makefile @@ -0,0 +1,2 @@ +lexcer: main.cpp lexcer.cpp + g++ -o lexcer main.cpp lexcer.cpp diff --git a/homework/81568/c2html/README.md b/homework/81568/c2html/README.md new file mode 100644 index 0000000..8c31e72 --- /dev/null +++ b/homework/81568/c2html/README.md @@ -0,0 +1,8 @@ +# c2HTML + Kind of tokenizer for the 'C' Programming Language. + +# Install + Pretty simple. + ```bash + make + ``` diff --git a/homework/81568/c2html/lexcer.cpp b/homework/81568/c2html/lexcer.cpp new file mode 100644 index 0000000..6ad3dbd --- /dev/null +++ b/homework/81568/c2html/lexcer.cpp @@ -0,0 +1,413 @@ +#include "lexcer.h" +#include "lexconst.h" + +#include <cctype> +#include <cstdlib> + +// using LexCer::TokenClass; +// using LexCer::Token; +// using LexCer::keywords; +// using LexCer::preprocessor; +// using LexCer::tokenToClass; +// using LexCer::spanBegin; +// using LexCer::spanEnd; + +//const char* Tokenizer::spanBegin = "<span class=\""; +//const char* Tokenizer::spanEnd = "</span>"; + +namespace LexCer { + +Tokenizer::Tokenizer(FILE *in, FILE *out) + : in(in), out(out) { + token.type = TokenClass::Invalid; + typenames = {"void", "char", "short", "int", "long", "float", "double", "signed", "unsigned"}; +} + +void Tokenizer::makeToken(TokenClass type, unsigned line, std::string lexeme, double number) { + token.type = type; + token.line = line; + token.lexeme = lexeme; + token.number = number; +} + +bool Tokenizer::readNextDirective(std::string *lexeme) { + char c; + while (isalpha((c = fgetc(in)))) + lexeme->push_back(c); + // we may need that last bit + ungetc((unsigned) c, in); + auto directive = lexeme->substr(1, lexeme->size() - 1); + if (!preprocessor.count(directive)) + return false; + if (directive.compare("define") == 0) { + //readDefine(); + } + return true; +} + +bool Tokenizer::readNextString(std::string *lexeme, char oldc) { + char c, prevc = oldc; + while (((c = fgetc(in)) != '"' || prevc == '\\') && c != '\n' && c != EOF) { + lexeme->push_back(c); + prevc = c; + } + + if (c == '\n' || c == EOF) { + ungetc((unsigned) c, in); + return false; + } + lexeme->push_back(c); + return true; +} + +bool Tokenizer::readNextIdentifier(std::string *lexeme) { + char c; + bool valid = true; + while (isalnum(c = fgetc(in)) || c == '_') { + lexeme->push_back(c); + } + ungetc((unsigned) c, in); + return valid; +} + +bool Tokenizer::readNextNumber(char beg, double *number, std::string *numberRepr) { + bool valid = true; + num_t base = DEC; + char c; + if (beg == '0') { + c = fgetc(in); + numberRepr->push_back(c); + if (c == 'b') + base = BIN; + else if (c == 'x' || c == 'X') + base = HEX; + else if (isdigit(c)) + base = OCT; + else + ungetc((unsigned) c, in); + } + + while (isValidDigit(c = fgetc(in), base)) { + numberRepr->push_back(c); + } + + if (c == '.') { + numberRepr->push_back(c); + while (isValidDigit(c = fgetc(in), base)) + numberRepr->push_back(c); + } + if (tolower(c) == 'e') { + numberRepr->push_back(c); + if (base != DEC) + return false; + if (!isdigit(c = fgetc(in)) && c != '-' && c != '+') { + ungetc((unsigned) c, in); + return false; + } + numberRepr->push_back(c); + while (isValidDigit(c = fgetc(in), base)) + numberRepr->push_back(c); + } + + char lower = tolower(c); + if (lower == 'u') { + numberRepr->push_back(c); + lower = tolower(c = fgetc(in)); + } + if (lower == 'f' || lower == 'l') + numberRepr->push_back(c); + else + ungetc((unsigned) c, in); + + *number = this->atod(*numberRepr); // not working ... + return true; +} + +bool Tokenizer::isValidDigit(char c, num_t numType) const { + bool valid; + switch (numType) { + case DEC: + return isdigit(c); + case BIN: + return (c == '0' || c == '1'); + case OCT: + return (c >= '0' || c <= '7'); + case HEX: + return (isdigit(c) || tolower(c) >= 'a' || tolower(c) <= 'f'); + default: + return false; + } +} + +bool Tokenizer::readLineComment(std::string *lexeme) { + char c; + while ((c = fgetc(in)) != '\n' && c != EOF) + lexeme->push_back(c); + ungetc((unsigned) c, in); + return true; // for consistency +} + +bool Tokenizer::readMultilineComment(std::string *lexeme) { + char c, prevc = (char) -1; + while (((c = fgetc(in)) != '/' && prevc != '*') && c != EOF) + lexeme->push_back(c); + + if (c == EOF) { + return false; + } + lexeme->push_back(c); // closing slash + return true; +} + +bool Tokenizer::readInclude(std::string *lexeme) { + char c; + bool valid = true; + while ((c = fgetc(in)) != '>') { + lexeme->push_back(c); + if (!isalpha(c) && c != '_' && c != '.') + valid = false; + } + lexeme->push_back(c); + return valid; +} + +bool Tokenizer::readUntilBlank(std::string *lexeme) { + char c; + while (!isblank(c = fgetc(in)) && c != EOF) ; + ungetc((unsigned) c, in); + return true; +} + +bool Tokenizer::writeToOutput() { + if (token.type == TokenClass::Eof) { + printf("End of file!\n"); + fputc('\n', out); + return false; + } + + if (token.type == TokenClass::Skip) { + if (fputs(token.lexeme.c_str(), out) == EOF) { + printf("Error while writing to output"); + return false; + } + return true; + } + + printf("Token of type %s at line %d: ", tokenToClass.at(token.type).c_str(), token.line); + if (token.type == TokenClass::Number) + printf("%f\n", token.number); + else + printf("%s\n", token.lexeme.c_str()); + + auto lexeme = escapeHTML(token.lexeme); + + std::string output; + output.append(spanBegin).append(tokenToClass.at(token.type)).append("\">").append(lexeme).append(spanEnd); + + if (fputs(output.c_str(), out) == EOF) { + printf("Error while writing to output"); + return false; + } + return true; +} + +std::string Tokenizer::escapeHTML(const std::string &lexeme) { + std::string result; + for (auto c : lexeme) { + switch(c) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + default: + result.push_back(c); + break; + } + } + return result; +} + +TokenClass Tokenizer::nextToken(std::string *lexeme, double *number) { + if (token.type == TokenClass::Eof) { + return TokenClass::Invalid; + } + + char c = fgetc(in); + if (c == EOF) { + return TokenClass::Eof; + } + lexeme->push_back(c); + // operator || symbol || string || preprocessor directive + // probably should check for errors like '5 * % 4;', but... + switch(c) { + case '\n': + ++line; + case '\t': + case ' ': + case ';': + case ',': + case '{': + case '}': + return TokenClass::Skip; + case '(': + return TokenClass::LeftParen; + case ')': + return TokenClass::RightParen; + case '[': + case ']': + case '?': + case ':': + return TokenClass::Operator; + case '*': + c = fgetc(in); + if (c == '/') { + return TokenClass::Invalid; + } + ungetc((unsigned) c, in); + c = '*'; + case '^': + case '%': + case '=': + case '!': + case '~': + c = fgetc(in); + if (c != '=') ungetc((unsigned) c, in); + else lexeme->push_back(c); + return TokenClass::Operator; + case '<': + case '>': + c = fgetc(in); + if (c == lexeme->at(lexeme->size() - 1)) { + lexeme->push_back(c); + c = fgetc(in); + if (c == '=') + lexeme->push_back(c); + else + ungetc((unsigned) c, in); + } else if (lexeme->at(lexeme->size() - 1) == '<' && isalpha(c)) { + lexeme->push_back(c); + if (!readInclude(lexeme)) + return TokenClass::Invalid; + return TokenClass::String; + } else + ungetc((unsigned) c, in); + return TokenClass::Operator; + case '&': + case '|': + case '+': + c = fgetc(in); + if (c == lexeme->at(lexeme->size() - 1) || c == '=') + lexeme->push_back(c); + else + ungetc((unsigned) c, in); + return TokenClass::Operator; + case '-': + c = fgetc(in); + if (c == '-' || c == '=' || c == '>') + lexeme->push_back(c); + else + ungetc((unsigned) c, in); + return TokenClass::Operator; + case '#': + if (readNextDirective(lexeme)) + return TokenClass::PreprocessorDirective; + return TokenClass::Invalid; + case '\'': + lexeme->push_back(c = fgetc(in)); + if (c == '\\') { + lexeme->push_back(c = fgetc(in)); + } + lexeme->push_back(c = fgetc(in)); // the closing mark + if (c != '\'') + return TokenClass::Invalid; + return TokenClass::String; + case '"': + if (readNextString(lexeme, c)) + return TokenClass::String; + return TokenClass::Invalid; + case '/': + c = fgetc(in); + lexeme->push_back(c); + switch (c) { + case '=': + return TokenClass::Operator; + case '/': + if (!readLineComment(lexeme)) + return TokenClass::Invalid; + return TokenClass::Comment; + case '*': + if (!readMultilineComment(lexeme)) + return TokenClass::Invalid; + return TokenClass::Comment; + default: + if (!isblank(c) || !isdigit(c)) { + ungetc((unsigned) c, in); + lexeme->pop_back(); + return TokenClass::Invalid; + } + return TokenClass::Operator; + } + case '\\': + c = fgetc(in); + ungetc((unsigned) c, in); + if (c != '\n') + return TokenClass::Invalid; // stray '\' + return TokenClass::Operator; + } + + // identifier || keyword || typename + if (isalpha(c) || c == '_') { + if (readNextIdentifier(lexeme)) { + if (keywords.count(*lexeme) != 0) + return TokenClass::Keyword; + else if (typenames.count(*lexeme) != 0) + return TokenClass::Typename; + return TokenClass::Identifier; + } else { + return TokenClass::Invalid; + } + } + + if (!isdigit(c)) { + return TokenClass::Invalid; + } + + // number + if (readNextNumber(c, number, lexeme)) + return TokenClass::Number; + return TokenClass::Invalid; +} + + +std::string getOutputFileName(const std::string &name) { + auto pos = name.find_last_of('.'); + if (pos == std::string::npos) { + return name + ".html"; + } + + return name.substr(0, pos) + ".html"; +} + +void lexCit(FILE *in, FILE *out) { + Tokenizer hl {in, out}; + + std::string lexeme; + double number; + TokenClass type; + do { + type = hl.nextToken(&lexeme, &number); + + hl.makeToken(type, hl.lineNumber(), lexeme, number); + if (!hl.writeToOutput()) + break; + lexeme = ""; + number = 0.0; + } while(hl.currentToken().type != TokenClass::Eof || hl.currentToken().type != TokenClass::Invalid); +} + +} /* Namespace Lexcer */ diff --git a/homework/81568/c2html/lexcer.h b/homework/81568/c2html/lexcer.h new file mode 100644 index 0000000..e329a90 --- /dev/null +++ b/homework/81568/c2html/lexcer.h @@ -0,0 +1,84 @@ +#ifndef FMI_IPL_LEXCER_H +#define FMI_IPL_LEXCER_H + +#include <unordered_set> +#include <unordered_map> +#include <string> + +#include <cstdio> + +namespace LexCer { + +enum class TokenClass : short { + Operator, + Keyword, + PreprocessorDirective, + Typename, + Identifier, + String, + Comment, + Number, + LeftParen, + RightParen, + + Skip, + Eof, + Invalid +}; + +struct Token { + TokenClass type; + unsigned line; + std::string lexeme; + double number; +}; + + +class Tokenizer { +private: + enum num_t { + BIN = 2, + OCT = 8, + DEC = 10, + HEX = 16 + }; + +public: + Tokenizer(FILE *in, FILE *out); + + unsigned lineNumber() const { return line; } + Token currentToken() const { return token; } + + TokenClass nextToken(std::string *lexeme, double *number); + void makeToken(TokenClass type, unsigned line, + std::string lexeme = std::string(), double number = 0.0); + bool writeToOutput(); + +private: + std::string escapeHTML(const std::string &lexeme); + bool readNextDirective(std::string *lexeme); + bool readNextString(std::string *lexeme, char oldc); + bool readNextIdentifier(std::string *lexeme); + bool readNextNumber(char beg, double *number, std::string *numberRepr); + bool isValidDigit(char c, num_t numType) const ; + bool readLineComment(std::string *lexeme); + bool readMultilineComment(std::string *lexeme); + bool readInclude(std::string *lexeme); + bool readUntilBlank(std::string *lexeme); + + double atod(const std::string &number) const { return 0.0; } +private: + FILE *in; + FILE *out; + Token token; // current token + unsigned line = 1; + std::unordered_set<std::string> typenames; +}; + + +std::string getOutputFileName(const std::string &name); +void lexCit(FILE *in, FILE *out); + +} /* Namespace LexCer */ + +#endif diff --git a/homework/81568/c2html/lexconst.h b/homework/81568/c2html/lexconst.h new file mode 100644 index 0000000..9d2068d --- /dev/null +++ b/homework/81568/c2html/lexconst.h @@ -0,0 +1,39 @@ +#ifndef LEXCER_CONST_H +#define LEXCER_CONST_H + +namespace LexCer { + +static const std::unordered_set<std::string> keywords = + {"auto", "register", "static", "extern", "typedef", "struct", "union", "enum", + "if", "else", "for", "while", "switch", "case", "default", "const", "break", + "continue", "goto", "sizeof", "alignof", "volatile", "return"}; + +static const std::unordered_set<std::string> preprocessor = + {"include", "define", "undef", "if", "ifdef", "ifndef", "else", "elif", "endif", + "line", "error", "pragma"}; + +static const std::unordered_map<TokenClass, std::string> tokenToClass + { + { + {TokenClass::Operator, "operator"}, + {TokenClass::Keyword, "keyword"}, + {TokenClass::Typename, "typename"}, + {TokenClass::PreprocessorDirective, "preproc"}, + {TokenClass::Identifier, "identifier"}, + {TokenClass::String, "string"}, + {TokenClass::Comment, "comment"}, + {TokenClass::Number, "number"}, + {TokenClass::Invalid, "invalid"}, + {TokenClass::LeftParen, "identifier"}, + {TokenClass::RightParen, "identifier"} + } + }; + +static const std::string spanBegin = "<span class=\""; +static const std::string spanEnd = "</span>"; + +static constexpr int MAX_EXP_LEN = 4; + +} /* Namespace LexCer */ + +#endif diff --git a/homework/81568/c2html/main.cpp b/homework/81568/c2html/main.cpp new file mode 100644 index 0000000..eedaee3 --- /dev/null +++ b/homework/81568/c2html/main.cpp @@ -0,0 +1,73 @@ +#include <cstdio> +#include "lexcer.h" + +int main(int argc, char *argv[]) { + + if (argc != 2) { + printf("Usage: %s <*.{c,h} file>\n", argv[0]); + return 1; /* wrong usage */ + } + + auto fpIn = fopen(argv[1], "r"); + if (!fpIn) { + return 2; /* unable to open file or inavlid file */ + } + + auto outputName = LexCer::getOutputFileName(argv[1]); + auto fpOut = fopen(outputName.c_str(), "w"); + if (!fpOut) { + return 2; + } + + + fputs( + "<!doctype>\n" + "<html>\n" + "<head>\n" + " <title>LexCed</title>\n" + " <style>\n" + " .keyword {\n" + " color: purple;\n" + " }\n" + " .number {\n" + " color: darkblue;\n" + " }\n" + " .string {\n" + " color: green;\n" + " }\n" + " .operator {\n" + " font-style: bold;\n" + " }\n" + " .invalid {\n" + " text-decoration: underline;\n" + " text-decoration-color: red;\n" + " text-decoration-style: wavy;\n" + " }\n" + " .typename {\n" + " color: blue;\n" + " }\n" + " .preproc {\n" + " color: purple;\n" + " }\n" + " .identifier {\n" + " color: black;\n" + " }\n" + " .string {\n" + " color: brown;\n" + " }\n" + " .comment {\n" + " color: green;\n" + " }\n" + " </style>\n" + "</head>\n" + "<body>\n" + "<pre class=\"code\">\n", + fpOut + ); + LexCer::lexCit(fpIn, fpOut); + fputs("</pre></body></html>\n", fpOut); + + printf("Highlighted text written in %s!\n", outputName.c_str()); + + return 0; +} diff --git a/homework/81568/c2html/test.c b/homework/81568/c2html/test.c new file mode 100644 index 0000000..636032a --- /dev/null +++ b/homework/81568/c2html/test.c @@ -0,0 +1,108 @@ +#ifndef SAMPLE_CODE_C +#define SAMPLE_CODE_C + +#define ONE_LINE_MACRO 5 + +#include <stdio.h> + +int bitcount(long long x) { + int cnt = 0; + while (x) { + ++cnt; + x &= (x-1); + } + return cnt; +} + +void shift_to_pos(int *num, int p, int n) { + *num = p > n ? *num << (p - n + 1) : *num >> (n - p + 1); +} + +int setbits(x, p, n, y) { + int mask = (1 << n) - 1; + int to_set = y & mask; + shift_to_pos(&mask, p, n); + shift_to_pos(&to_set, p, n); + return (x & ~mask) | to_set; +} + +unsigned invert(unsigned x, unsigned p, unsigned n) { + ++p; // in case p < n + while(n-- && p--) { + if (!(x & (1 << n))) { + x |= (1 << n); + } else { + x ^= (1 << n); + } + } + return x; +} + +int rightrot(long long x, int n) { + int bitcnt = bitcount(x); + x <<= n; + return (x & ( (1 << (bitcnt)) - 1) ) | (x & ~( (1 << bitcnt) - 1 )) >> bitcnt; +} + +char num[32]; + +void to_binary(unsigned x) { + int i = 31; + num[32] = '\0'; + while (x) { + if (x & 1) num[i] = '1'; + else num[i] = '0'; + --i; + x >>= 1; + } + for (; i >= 0; --i) num[i] = '0'; + for (; i < 32; ++i) { + printf("%c%s", num[i], !((i+1) % 4) ? " " : ""); + } +} + +void switch_why_not(void) { + char c = 'X'; + switch(c) { + case 'x': + printf("hex\n"); + break; + case 'X': + printf("why break stuff\n"); + default: + break; + } + + return; +} + +main() { + long long x = 0b110110; + printf("rightrot:\n"); + to_binary(x); + printf("\n"); + to_binary(rightrot(x, 3)); + printf("\n"); + + unsigned i = 0b101010; + printf("invert:\n"); + to_binary(i); + printf("\n"); + to_binary(invert(i, 4, 4)); + printf("\n"); + + long long a = 0b111001010011; + long long b = 0b11111010; + printf("bits of: "); to_binary(a); printf("\n"); + printf("bits to: "); to_binary(b); printf("\n"); + to_binary(setbits(a, 6, 4, b)); + + + int testInt = 12345678; + float testFloat = 1234.5678f; + double testDouble = 1234.5678; + + return 0; +} + +#endif /* SAMPLE_CODE_C */ diff --git a/homework/81568/c2html/test.html b/homework/81568/c2html/test.html new file mode 100644 index 0000000..83b41a5 --- /dev/null +++ b/homework/81568/c2html/test.html @@ -0,0 +1,151 @@ +<!doctype> +<html> +<head> + <title>LexCed</title> + <style> + .keyword { + color: purple; + } + .number { + color: darkblue; + } + .string { + color: green; + } + .operator { + font-style: bold; + } + .invalid { + text-decoration: underline; + text-decoration-color: red; + text-decoration-style: wavy; + } + .typename { + color: blue; + } + .preproc { + color: purple; + } + .identifier { + color: black; + } + .string { + color: brown; + } + .comment { + color: green; + } + </style> +</head> +<body> +<pre class="code"> +<span class="preproc">#ifndef</span> <span class="identifier">SAMPLE_CODE_C</span> +<span class="preproc">#define</span> <span class="identifier">SAMPLE_CODE_C</span> + +<span class="preproc">#define</span> <span class="identifier">ONE_LINE_MACRO</span> <span class="number">5</span> + +<span class="preproc">#include</span> <span class="string"><stdio.h></span> + +<span class="typename">int</span> <span class="identifier">bitcount</span>(<span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span>) { + <span class="typename">int</span> <span class="identifier">cnt</span> <span class="operator">=</span> <span class="number">0;</span>; + <span class="keyword">while</span> (<span class="identifier">x</span>) { + <span class="operator">++</span><span class="identifier">cnt</span>; + <span class="identifier">x</span> <span class="operator">&=</span> (<span class="identifier">x</span><span class="operator">-</span><span class="number">1</span>); + } + <span class="keyword">return</span> <span class="identifier">cnt</span>; +} + +<span class="typename">void</span> <span class="identifier">shift_to_pos</span>(<span class="typename">int</span> <span class="operator">*</span><span class="identifier">num</span>, <span class="typename">int</span> <span class="identifier">p</span>, <span class="typename">int</span> <span class="identifier">n</span>) { + <span class="operator">*</span><span class="identifier">num</span> <span class="operator">=</span> <span class="identifier">p</span> <span class="operator">></span> <span class="identifier">n</span> <span class="operator">?</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator"><<</span> (<span class="identifier">p</span> <span class="operator">-</span> <span class="identifier">n</span> <span class="operator">+</span> <span class="number">1</span>) <span class="operator">:</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator">>></span> (<span class="identifier">n</span> <span class="operator">-</span> <span class="identifier">p</span> <span class="operator">+</span> <span class="number">1</span>); +} + +<span class="typename">int</span> <span class="identifier">setbits</span>(<span class="identifier">x</span>, <span class="identifier">p</span>, <span class="identifier">n</span>, <span class="identifier">y</span>) { + <span class="typename">int</span> <span class="identifier">mask</span> <span class="operator">=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>) <span class="operator">-</span> <span class="number">1</span>; + <span class="typename">int</span> <span class="identifier">to_set</span> <span class="operator">=</span> <span class="identifier">y</span> <span class="operator">&</span> <span class="identifier">mask</span>; + <span class="identifier">shift_to_pos</span>(<span class="operator">&</span><span class="identifier">mask</span>, <span class="identifier">p</span>, <span class="identifier">n</span>); + <span class="identifier">shift_to_pos</span>(<span class="operator">&</span><span class="identifier">to_set</span>, <span class="identifier">p</span>, <span class="identifier">n</span>); + <span class="keyword">return</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span><span class="identifier">mask</span>) <span class="operator">|</span> <span class="identifier">to_set</span>; +} + +<span class="typename">unsigned</span> <span class="identifier">invert</span>(<span class="typename">unsigned</span> <span class="identifier">x</span>, <span class="typename">unsigned</span> <span class="identifier">p</span>, <span class="typename">unsigned</span> <span class="identifier">n</span>) { + <span class="operator">++</span><span class="identifier">p</span>; <span class="comment">// in case p < n</span> + <span class="keyword">while</span>(<span class="identifier">n</span><span class="operator">--</span> <span class="operator">&&</span> <span class="identifier">p</span><span class="operator">--</span>) { + <span class="keyword">if</span> (<span class="operator">!</span>(<span class="identifier">x</span> <span class="operator">&</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>))) { + <span class="identifier">x</span> <span class="operator">|=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>); + } <span class="keyword">else</span> { + <span class="identifier">x</span> <span class="operator">^=</span> (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">n</span>); + } + } + <span class="keyword">return</span> <span class="identifier">x</span>; +} + +<span class="typename">int</span> <span class="identifier">rightrot</span>(<span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span>, <span class="typename">int</span> <span class="identifier">n</span>) { + <span class="typename">int</span> <span class="identifier">bitcnt</span> <span class="operator">=</span> <span class="identifier">bitcount</span>(<span class="identifier">x</span>); + <span class="identifier">x</span> <span class="operator"><<=</span> <span class="identifier">n</span>; + <span class="keyword">return</span> (<span class="identifier">x</span> <span class="operator">&</span> ( (<span class="number">1</span> <span class="operator"><<</span> (<span class="identifier">bitcnt</span>)) <span class="operator">-</span> <span class="number">1</span>) ) <span class="operator">|</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="operator">~</span>( (<span class="number">1</span> <span class="operator"><<</span> <span class="identifier">bitcnt</span>) <span class="operator">-</span> <span class="number">1</span> )) <span class="operator">>></span> <span class="identifier">bitcnt</span>; +} + +<span class="typename">char</span> <span class="identifier">num</span><span class="operator">[</span><span class="number">32</span><span class="operator">]</span>; + +<span class="typename">void</span> <span class="identifier">to_binary</span>(<span class="typename">unsigned</span> <span class="identifier">x</span>) { + <span class="typename">int</span> <span class="identifier">i</span> <span class="operator">=</span> <span class="number">31</span>; + <span class="identifier">num</span><span class="operator">[</span><span class="number">32</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'\0'</span>; + <span class="keyword">while</span> (<span class="identifier">x</span>) { + <span class="keyword">if</span> (<span class="identifier">x</span> <span class="operator">&</span> <span class="number">1</span>) <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'1'</span>; + <span class="keyword">else</span> <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'0'</span>; + <span class="operator">--</span><span class="identifier">i</span>; + <span class="identifier">x</span> <span class="operator">>>=</span> <span class="number">1</span>; + } + <span class="keyword">for</span> (; <span class="identifier">i</span> <span class="operator">></span><span class="operator">=</span> <span class="number">0;</span>; <span class="operator">--</span><span class="identifier">i</span>) <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span> <span class="operator">=</span> <span class="string">'0'</span>; + <span class="keyword">for</span> (; <span class="identifier">i</span> <span class="operator"><</span> <span class="number">32</span>; <span class="operator">++</span><span class="identifier">i</span>) { + <span class="identifier">printf</span>(<span class="string">"%c%s"</span>, <span class="identifier">num</span><span class="operator">[</span><span class="identifier">i</span><span class="operator">]</span>, <span class="operator">!</span>((<span class="identifier">i</span><span class="operator">+</span><span class="number">1</span>) <span class="operator">%</span> <span class="number">4</span>) <span class="operator">?</span> <span class="string">" "</span> <span class="operator">:</span> <span class="string">""</span>); + } +} + +<span class="typename">void</span> <span class="identifier">switch_why_not</span>(<span class="typename">void</span>) { + <span class="typename">char</span> <span class="identifier">c</span> <span class="operator">=</span> <span class="string">'X'</span>; + <span class="keyword">switch</span>(<span class="identifier">c</span>) { + <span class="keyword">case</span> <span class="string">'x'</span><span class="operator">:</span> + <span class="identifier">printf</span>(<span class="string">"hex\n"</span>); + <span class="keyword">break</span>; + <span class="keyword">case</span> <span class="string">'X'</span><span class="operator">:</span> + <span class="identifier">printf</span>(<span class="string">"why break stuff\n"</span>); + <span class="keyword">default</span><span class="operator">:</span> + <span class="keyword">break</span>; + } + + <span class="keyword">return</span>; +} + +<span class="identifier">main</span>() { + <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">x</span> <span class="operator">=</span> <span class="number">0b110110</span>; + <span class="identifier">printf</span>(<span class="string">"rightrot:\n"</span>); + <span class="identifier">to_binary</span>(<span class="identifier">x</span>); + <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">to_binary</span>(<span class="identifier">rightrot</span>(<span class="identifier">x</span>, <span class="number">3</span>)); + <span class="identifier">printf</span>(<span class="string">"\n"</span>); + + <span class="typename">unsigned</span> <span class="identifier">i</span> <span class="operator">=</span> <span class="number">0b101010</span>; + <span class="identifier">printf</span>(<span class="string">"invert:\n"</span>); + <span class="identifier">to_binary</span>(<span class="identifier">i</span>); + <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">to_binary</span>(<span class="identifier">invert</span>(<span class="identifier">i</span>, <span class="number">4</span>, <span class="number">4</span>)); + <span class="identifier">printf</span>(<span class="string">"\n"</span>); + + <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">a</span> <span class="operator">=</span> <span class="number">0b111001010011</span>; + <span class="typename">long</span> <span class="typename">long</span> <span class="identifier">b</span> <span class="operator">=</span> <span class="number">0b11111010</span>; + <span class="identifier">printf</span>(<span class="string">"bits of: "</span>); <span class="identifier">to_binary</span>(<span class="identifier">a</span>); <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">printf</span>(<span class="string">"bits to: "</span>); <span class="identifier">to_binary</span>(<span class="identifier">b</span>); <span class="identifier">printf</span>(<span class="string">"\n"</span>); + <span class="identifier">to_binary</span>(<span class="identifier">setbits</span>(<span class="identifier">a</span>, <span class="number">6</span>, <span class="number">4</span>, <span class="identifier">b</span>)); + + + <span class="typename">int</span> <span class="identifier">testInt</span> <span class="operator">=</span> <span class="number">12345678</span>; + <span class="typename">float</span> <span class="identifier">testFloat</span> <span class="operator">=</span> <span class="number">1234.5678f</span>; + <span class="typename">double</span> <span class="identifier">testDouble</span> <span class="operator">=</span> <span class="number">1234.5678</span>; + + <span class="keyword">return</span> <span class="number">0;</span>; +} + +<span class="preproc">#endif</span> <span class="comment">/* SAMPLE_CODE_C */</span> + +</pre></body></html> |
