123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // Scintilla source code edit control
- /** @file LexMMIXAL.cxx
- ** Lexer for MMIX Assembler Language.
- ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
- ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
- **/
- // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
- // The License.txt file describes the conditions under which this software may be distributed.
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <assert.h>
- #include <ctype.h>
- #include "ILexer.h"
- #include "Scintilla.h"
- #include "SciLexer.h"
- #include "WordList.h"
- #include "LexAccessor.h"
- #include "Accessor.h"
- #include "StyleContext.h"
- #include "CharacterSet.h"
- #include "LexerModule.h"
- #ifdef SCI_NAMESPACE
- using namespace Scintilla;
- #endif
- static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
- }
- inline bool isMMIXALOperator(char ch) {
- if (IsASCII(ch) && isalnum(ch))
- return false;
- if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
- ch == '*' || ch == '/' ||
- ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
- ch == '~' || ch == '$' ||
- ch == ',' || ch == '(' || ch == ')' ||
- ch == '[' || ch == ']')
- return true;
- return false;
- }
- static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- WordList &opcodes = *keywordlists[0];
- WordList &special_register = *keywordlists[1];
- WordList &predef_symbols = *keywordlists[2];
- StyleContext sc(startPos, length, initStyle, styler);
- for (; sc.More(); sc.Forward())
- {
- // No EOL continuation
- if (sc.atLineStart) {
- if (sc.ch == '@' && sc.chNext == 'i') {
- sc.SetState(SCE_MMIXAL_INCLUDE);
- } else {
- sc.SetState(SCE_MMIXAL_LEADWS);
- }
- }
- // Check if first non whitespace character in line is alphanumeric
- if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS
- if(!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_MMIXAL_COMMENT);
- } else {
- if(sc.atLineStart) {
- sc.SetState(SCE_MMIXAL_LABEL);
- } else {
- sc.SetState(SCE_MMIXAL_OPCODE_PRE);
- }
- }
- }
- // Determine if the current state should terminate.
- if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR
- sc.SetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
- if (!isdigit(sc.ch)) {
- if (IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- sc.ChangeState(SCE_MMIXAL_REF);
- sc.SetState(SCE_MMIXAL_REF);
- } else {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- }
- } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
- if (!IsAWordChar(sc.ch) ) {
- sc.SetState(SCE_MMIXAL_OPCODE_PRE);
- }
- } else if (sc.state == SCE_MMIXAL_REF) { // REF
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (*s == ':') { // ignore base prefix for match
- for (size_t i = 0; i != sizeof(s); ++i) {
- *(s+i) = *(s+i+1);
- }
- }
- if (special_register.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_REGISTER);
- } else if (predef_symbols.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_SYMBOL);
- }
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
- if (!isspace(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPCODE);
- }
- } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
- if (!IsAWordChar(sc.ch) ) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if (opcodes.InList(s)) {
- sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
- } else {
- sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
- }
- sc.SetState(SCE_MMIXAL_OPCODE_POST);
- }
- } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
- if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
- if (!isdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
- if (!isxdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_OPERANDS);
- }
- }
- // Determine if a new state should be entered.
- if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
- sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
- if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
- if (!sc.atLineEnd) {
- sc.SetState(SCE_MMIXAL_COMMENT);
- }
- } else if (isdigit(sc.ch)) {
- sc.SetState(SCE_MMIXAL_NUMBER);
- } else if (IsAWordChar(sc.ch) || sc.Match('@')) {
- sc.SetState(SCE_MMIXAL_REF);
- } else if (sc.Match('\"')) {
- sc.SetState(SCE_MMIXAL_STRING);
- } else if (sc.Match('\'')) {
- sc.SetState(SCE_MMIXAL_CHAR);
- } else if (sc.Match('$')) {
- sc.SetState(SCE_MMIXAL_REGISTER);
- } else if (sc.Match('#')) {
- sc.SetState(SCE_MMIXAL_HEX);
- } else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_MMIXAL_OPERATOR);
- }
- }
- }
- sc.Complete();
- }
- static const char * const MMIXALWordListDesc[] = {
- "Operation Codes",
- "Special Register",
- "Predefined Symbols",
- 0
- };
- LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
|