Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit06811744a002f4ab332d94d510475231afcd45a1 (patch)
Author
 Mincho Paskalev <minchopaskal@gmail.com>
2018-11-03 13:36:57 +0200
Committer
 Martin Dobrev <martindobrev0@gmail.com>
2018-11-03 13:36:57 +0200
Files91c41776fbdf899dcb61a8d5df3ac1316c24f3c8
IPL-06811744a002f4ab332d94d510475231afcd45a1.tar
IPL-06811744a002f4ab332d94d510475231afcd45a1.tar.gz
IPL-06811744a002f4ab332d94d510475231afcd45a1.zip
Parent26e5f891d537b5d4fc2890c9cdbeb73d5748d568 (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
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("&lt");
+ break;
+ case '>':
+ result.append("&gt");
+ break;
+ case '&':
+ result.append("&amp");
+ 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">&ltstdio.h&gt</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">&amp=</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">&gt</span> <span class="identifier">n</span> <span class="operator">?</span> <span class="operator">*</span><span class="identifier">num</span> <span class="operator">&lt&lt</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">&gt&gt</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">&lt&lt</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">&amp</span> <span class="identifier">mask</span>;
+ <span class="identifier">shift_to_pos</span>(<span class="operator">&amp</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">&amp</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">&amp</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 &lt n</span>
+ <span class="keyword">while</span>(<span class="identifier">n</span><span class="operator">--</span> <span class="operator">&amp&amp</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">&amp</span> (<span class="number">1</span> <span class="operator">&lt&lt</span> <span class="identifier">n</span>))) {
+ <span class="identifier">x</span> <span class="operator">|=</span> (<span class="number">1</span> <span class="operator">&lt&lt</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">&lt&lt</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">&lt&lt=</span> <span class="identifier">n</span>;
+ <span class="keyword">return</span> (<span class="identifier">x</span> <span class="operator">&amp</span> ( (<span class="number">1</span> <span class="operator">&lt&lt</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">&amp</span> <span class="operator">~</span>( (<span class="number">1</span> <span class="operator">&lt&lt</span> <span class="identifier">bitcnt</span>) <span class="operator">-</span> <span class="number">1</span> )) <span class="operator">&gt&gt</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">&amp</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">&gt&gt=</span> <span class="number">1</span>;
+ }
+ <span class="keyword">for</span> (; <span class="identifier">i</span> <span class="operator">&gt</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">&lt</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>