/*---------------------------------------------------------------------------*/ int serial_line_input_byte(unsigned char c) { static uint8_t overflow = 0; /* Buffer overflow: ignore until END */ if(IGNORE_CHAR(c)) { return 0; } if(!overflow) { /* Add character */ if(ringbuf_put(&rxbuf, c) == 0) { /* Buffer overflow: ignore the rest of the line */ overflow = 1; } } else { /* Buffer overflowed: * Only (try to) add terminator characters, otherwise skip */ if(c == END && ringbuf_put(&rxbuf, c) != 0) { overflow = 0; } } /* Wake up consumer process */ //printf("wake up consumer process\n"); process_poll(&serial_line_process); return 1; }
/*---------------------------------------------------------------------------*/ int serial_line_input_byte(unsigned char c) { if(!buffer_full && !IGNORE_CHAR(c)) { if(c == END) { /* terminate the string */ buffer[bufwptr++] = '\0'; buffer_full++; process_poll(&serial_line_process); return 1; } /* reserve space for the terminating zero character */ if(bufwptr < (BUFSIZE - 1)) { buffer[bufwptr++] = c; } } return 0; }
token_t Scanner::NextToken(bool hungry) // ---------------------------------------------------------------------------- // Return the next token, and compute the token text and value // ---------------------------------------------------------------------------- { textValue = ""; tokenText = ""; intValue = 0; realValue = 0.0; base = 0; // Check if input was opened correctly if (!input.good()) return tokEOF; // Check if we unindented far enough for multiple indents hadSpaceBefore = true; while (indents.back() > indent) { indents.pop_back(); return tokUNINDENT; } // Read next character int c = input.get(); position++; // Skip spaces and check indendation hadSpaceBefore = false; while (isspace(c) && c != EOF) { hadSpaceBefore = true; if (c == '\n') { // New line: start counting indentation checkingIndent = true; lineStart = position; } else if (checkingIndent) { // Can't mix tabs and spaces if (c == ' ' || c == '\t') { if (!indentChar) indentChar = c; else if (indentChar != c) errors.Log(Error("Mixed tabs and spaces in indentation", position)); } } // Keep looking for more spaces if (c == '\n') textValue += c; c = input.get(); position++; } // End of space testing // Stop counting indentation if (checkingIndent) { input.unget(); position--; checkingIndent = false; ulong column = position - lineStart; if (settingIndent) { // We set a new indent, for instance after opening paren indents.push_back(indent); indent = column; settingIndent = false; return tokNEWLINE; } else if (column > indent) { // Strictly deeper indent : report indent = column; indents.push_back(indent); return tokINDENT; } else if (column < indents.back()) { // Unindenting: remove rightmost indent level ELFE_ASSERT(indents.size()); indents.pop_back(); indent = column; // If we unindented, but did not go as far as the // most recent indent, report inconsistency. if (indents.back() < column) { errors.Log(Error("Unindenting to the right " "of previous indentation", position)); return tokERROR; } // Otherwise, report that we unindented // We may report multiple tokUNINDENT if we unindented deep return tokUNINDENT; } else { // Exactly the same indent level as before return tokNEWLINE; } } // Report end of input if that's what we've got if (input.eof()) return tokEOF; // Clear spelling from whitespaces textValue = ""; // Look for numbers if (isdigit(c)) { bool floating_point = false; bool basedNumber = false; base = 10; intValue = 0; // Take integral part (or base) do { while (digit_values[c] < base) { intValue = base * intValue + digit_values[c]; NEXT_CHAR(c); if (c == '_') // Skip a single underscore { IGNORE_CHAR(c); if (c == '_') errors.Log(Error("Two _ characters in a row look ugly", position)); } } // Check if this is a based number if (c == '#' && !basedNumber) { base = intValue; if (base < 2 || base > 36) { base = 36; errors.Log(Error("The base $1 is not valid, not in 2..36", position).Arg(textValue)); } NEXT_CHAR(c); intValue = 0; basedNumber = true; } else { basedNumber = false; } } while (basedNumber); // Check for fractional part realValue = intValue; if (c == '.') { int nextDigit = input.peek(); if (digit_values[nextDigit] >= base) { // This is something else following an integer: 1..3, 1.(3) input.unget(); position--; hadSpaceAfter = false; return tokINTEGER; } else { floating_point = true; double comma_position = 1.0; NEXT_CHAR(c); while (digit_values[c] < base) { comma_position /= base; realValue += comma_position * digit_values[c]; NEXT_CHAR(c); if (c == '_') { IGNORE_CHAR(c); if (c == '_') errors.Log(Error("Two _ characters in a row " "look really ugly", position)); } } } } // Check if we have a second '#' at end of based number if (c == '#') NEXT_CHAR(c); // Check for the exponent if (c == 'e' || c == 'E') { NEXT_CHAR(c); uint exponent = 0; bool negative_exponent = false; // Exponent sign if (c == '+') { NEXT_CHAR(c); } else if (c == '-') { NEXT_CHAR(c); negative_exponent = true; floating_point = true; } // Exponent value while (digit_values[c] < 10) { exponent = 10 * exponent + digit_values[c]; NEXT_CHAR(c); if (c == '_') IGNORE_CHAR(c); } // Compute base^exponent double exponent_value = 1.0; double multiplier = base; while (exponent) { if (exponent & 1) exponent_value *= multiplier; exponent >>= 1; multiplier *= multiplier; } // Compute actual value if (negative_exponent) realValue /= exponent_value; else realValue *= exponent_value; intValue = (ulong) realValue; } // Return the token input.unget(); position--; hadSpaceAfter = isspace(c); return floating_point ? tokREAL : tokINTEGER; } // Numbers