source: abuse/branches/win32/LispEditor/LispEditorView.cpp @ 608

Last change on this file since 608 was 100, checked in by Sam Hocevar, 15 years ago
  • Importing an old Win32 port by Jeremy "Marauder" Scott.
  • Property svn:keywords set to Id
File size: 29.2 KB
Line 
1// LispEditorView.cpp : implementation of the CLispEditorView class
2//
3
4#include "stdafx.h"
5#include "LispEditor.h"
6#include "MainFrm.h"
7
8#include "LispEditorDoc.h"
9#include "CntrItem.h"
10#include "LispEditorView.h"
11
12#ifdef _DEBUG
13#define new DEBUG_NEW
14#undef THIS_FILE
15static char THIS_FILE[] = __FILE__;
16#endif
17
18enum {
19    LISP_SYMBOL,
20    LISP_NUMBER,
21    LISP_STRING,
22    LISP_OPERATOR,
23    LISP_COMMENT,
24    LISP_WORD,
25    LISP_WHITESPACE
26} LISP_PARTS;
27
28
29/////////////////////////////////////////////////////////////////////////////
30// CLispEditorView
31
32IMPLEMENT_DYNCREATE(CLispEditorView, CRichEditView)
33
34BEGIN_MESSAGE_MAP(CLispEditorView, CRichEditView)
35        //{{AFX_MSG_MAP(CLispEditorView)
36        ON_WM_DESTROY()
37        ON_WM_CHAR()
38        ON_WM_KEYDOWN()
39        ON_WM_LBUTTONUP()
40        //}}AFX_MSG_MAP
41        // Standard printing commands
42        ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
43        ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
44        ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
45END_MESSAGE_MAP()
46
47
48/* ---------------------------------------------------------------------------
49/////////////////////////////////////////////////////////////////////////////
50// CLispEditorView construction/destruction
51 ------------------------------------------------------------------------- /**/
52CLispEditorView::CLispEditorView()
53{
54        // TODO: add construction code here
55    m_nWordWrap = WrapNone;
56    LastOpenParenIndex = -1;
57    LastCloseParenIndex = -1;
58}
59
60/* ---------------------------------------------------------------------------
61 ------------------------------------------------------------------------- /**/
62CLispEditorView::~CLispEditorView()
63{
64}
65
66/* ---------------------------------------------------------------------------
67 ------------------------------------------------------------------------- /**/
68BOOL CLispEditorView::PreCreateWindow(CREATESTRUCT& cs)
69{
70        // TODO: Modify the Window class or styles here by modifying
71        //  the CREATESTRUCT cs
72
73        return CRichEditView::PreCreateWindow(cs);
74}
75
76/* ---------------------------------------------------------------------------
77 ------------------------------------------------------------------------- /**/
78void CLispEditorView::OnInitialUpdate()
79{
80        CRichEditView::OnInitialUpdate();
81    GetRichEditCtrl().SetBackgroundColor(FALSE, RGB(0, 0, 100));
82    CHARFORMAT cf;
83   
84    GetRichEditCtrl().GetDefaultCharFormat(cf);
85    cf.crTextColor = RGB(255, 255, 255);
86    cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_FACE;
87    cf.dwEffects = 0;
88    strcpy(cf.szFaceName, "Fixedsys");
89    GetRichEditCtrl().SetDefaultCharFormat(cf);
90    GetDocument()->SetModifiedFlag(FALSE);
91
92    // Set the printing margins (720 twips = 1/2 inch).
93        SetMargins(CRect(720, 720, 720, 720));
94}
95
96/* ---------------------------------------------------------------------------
97/////////////////////////////////////////////////////////////////////////////
98// CLispEditorView printing
99 ------------------------------------------------------------------------- /**/
100BOOL CLispEditorView::OnPreparePrinting(CPrintInfo* pInfo)
101{
102        // default preparation
103        return DoPreparePrinting(pInfo);
104}
105
106/* ---------------------------------------------------------------------------
107 ------------------------------------------------------------------------- /**/
108void CLispEditorView::OnDestroy()
109{
110        // Deactivate the item on destruction; this is important
111        // when a splitter view is being used.
112   CRichEditView::OnDestroy();
113   COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
114   if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
115   {
116      pActiveItem->Deactivate();
117      ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
118   }
119}
120
121#ifdef _DEBUG
122/* ---------------------------------------------------------------------------
123/////////////////////////////////////////////////////////////////////////////
124// CLispEditorView diagnostics
125 ------------------------------------------------------------------------- /**/
126void CLispEditorView::AssertValid() const
127{
128        CRichEditView::AssertValid();
129}
130
131/* ---------------------------------------------------------------------------
132 ------------------------------------------------------------------------- /**/
133void CLispEditorView::Dump(CDumpContext& dc) const
134{
135        CRichEditView::Dump(dc);
136}
137
138/* ---------------------------------------------------------------------------
139 ------------------------------------------------------------------------- /**/
140CLispEditorDoc* CLispEditorView::GetDocument() // non-debug version is inline
141{
142        ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLispEditorDoc)));
143        return (CLispEditorDoc*)m_pDocument;
144}
145#endif //_DEBUG
146
147/* ---------------------------------------------------------------------------
148/////////////////////////////////////////////////////////////////////////////
149// CLispEditorView message handlers
150 ------------------------------------------------------------------------- /**/
151int IsSeparator(unsigned char c) {
152    if (c == '_')
153        return 0;
154    if (c < '0')
155        return 1;
156    if (c > '9' && c < 'A')
157        return 1;
158    if (c > 'Z' && c < 'a')
159        return 1;
160    if (c > 'z')
161        return 1;
162
163    return 0;
164
165}
166
167/* ---------------------------------------------------------------------------
168 ------------------------------------------------------------------------- /**/
169int WordType(CString Word) {
170    if (((LPCSTR) Word)[0] >= '0' && ((LPCSTR) Word)[0] <= '9')
171        return LISP_NUMBER;
172    if (((LPCSTR) Word)[0] == '"')
173        return LISP_STRING;
174    switch (((LPCSTR) Word)[0]) {
175        case ';':
176            return LISP_COMMENT;
177            break;
178        case '/':
179            if (Word.GetLength() > 1)
180                return LISP_COMMENT;
181            else
182                return LISP_OPERATOR;
183            break;
184
185        case '=':
186        case '.':
187        case '`':
188        case '-':
189        case '+':
190        case '*':
191        case '<':
192        case '>':
193            return LISP_OPERATOR;
194            break;
195        case ' ':
196        case '\t':
197        case '\n':
198            return LISP_WHITESPACE;
199    }
200    if (IsSeparator(((LPCSTR) Word)[0]))
201        return LISP_SYMBOL;
202    return LISP_WORD;
203}
204
205/* ---------------------------------------------------------------------------
206 ------------------------------------------------------------------------- /**/
207void CLispEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
208{
209        // TODO: Add your message handler code here and/or call default
210        CRichEditView::OnChar(nChar, nRepCnt, nFlags);
211    GetRichEditCtrl().HideSelection(TRUE, FALSE);
212    CHARFORMAT cf, cfbak;
213    GetRichEditCtrl().GetDefaultCharFormat(cf);
214    cf.dwMask = CFM_BOLD | CFM_COLOR;
215    cfbak = cf;
216    long Start, End;
217    GetRichEditCtrl().GetSel(Start, End);
218   
219   
220    long First, Last;
221    int Line;
222    Line = GetRichEditCtrl().LineFromChar(Start);
223    First = GetRichEditCtrl().LineIndex(Line);
224    Last = GetRichEditCtrl().LineIndex(Line+1);
225    if (Last == -1)
226        Last = GetRichEditCtrl().GetTextLength();
227    ColorRange(GetRichEditCtrl().LineIndex(Line), GetRichEditCtrl().LineIndex(Line + 1));
228   
229    switch (nChar) {
230        case '\t': {
231            } break;
232    }
233
234    MatchParen(Start);
235    GetRichEditCtrl().SetSel(Start, End);
236    GetRichEditCtrl().SetSelectionCharFormat(cfbak);
237    GetRichEditCtrl().HideSelection(FALSE, FALSE);
238}
239
240/* ---------------------------------------------------------------------------
241 ------------------------------------------------------------------------- /**/
242long CLispEditorView::FindNextCloseParen()
243{
244    long Start;
245    FINDTEXTEX Find;
246    ZeroMemory(&Find, sizeof(Find));
247    CHARRANGE cr;
248    GetRichEditCtrl().GetSel(cr);
249
250    GetRichEditCtrl().SetSel(cr.cpMin, -1);
251    Start = 0;
252    CString SearchSpace = GetRichEditCtrl().GetSelText();
253    int NumOpen = 0;
254    while (Start < SearchSpace.GetLength() && NumOpen > -1 && Start < 2000) {
255        switch (((LPCSTR) SearchSpace)[Start]) {
256            case '(':
257                if (IsPosCommented(Start + cr.cpMin) == -1 && IsPosQuoted(Start + cr.cpMin) == -1)
258                    NumOpen++;
259                break;
260            case ')':
261                if (IsPosCommented(Start + cr.cpMin) == -1 && IsPosQuoted(Start + cr.cpMin) == -1)
262                    NumOpen--;
263                break;
264        }
265        Start++;
266/*        long NewStart;
267        NewStart =  */
268    }
269
270    GetRichEditCtrl().SetSel(cr);
271    if (NumOpen > -1)
272        return -1;
273    else
274        return Start + cr.cpMin - 1;
275}
276
277/* ---------------------------------------------------------------------------
278 ------------------------------------------------------------------------- /**/
279long CLispEditorView::FindPrevOpenParen()
280{
281    long Start;
282    FINDTEXTEX Find;
283    ZeroMemory(&Find, sizeof(Find));
284    CHARRANGE cr;
285    GetRichEditCtrl().GetSel(cr);
286
287    Start = cr.cpMin;
288   
289    GetRichEditCtrl().SetSel(0, Start);
290    CString SearchSpace = GetRichEditCtrl().GetSelText();
291    Start--;
292    int NumOpen = 0;
293    while (Start >= 0 && NumOpen < 1 && (cr.cpMin - Start) < 2000) {
294        switch (((LPCSTR) SearchSpace)[Start]) {
295            case '(':
296                if (IsPosCommented(Start) == -1 && IsPosQuoted(Start) == -1)
297                    NumOpen++;
298                break;
299            case ')':
300                if (IsPosCommented(Start) == -1 && IsPosQuoted(Start) == -1)
301                    NumOpen--;
302                break;
303        }
304        Start--;
305/*        long NewStart;
306        NewStart =  */
307    }
308
309    GetRichEditCtrl().SetSel(cr);
310//    _RPT2(_CRT_WARN, "Found open paren at position %d; NumOpen: %d\n", Start, NumOpen);
311    if (NumOpen < 1)
312        return -1;
313    else
314        return Start + 1;
315}
316
317/* ---------------------------------------------------------------------------
318 ------------------------------------------------------------------------- /**/
319void CLispEditorView::MatchParen(long Pos)
320{
321    CHARFORMAT cf;
322    GetRichEditCtrl().GetDefaultCharFormat(cf);
323    cf.dwMask = CFM_BOLD | CFM_COLOR;
324
325    if (LastOpenParenIndex != -1)
326        FormatWord(LISP_SYMBOL, LastOpenParenIndex, LastOpenParenIndex + 1);
327    if (LastCloseParenIndex != -1)
328        FormatWord(LISP_SYMBOL, LastCloseParenIndex, LastCloseParenIndex + 1);
329   
330    cf.crTextColor = RGB(220, 55, 55);
331    cf.dwEffects = 0;
332
333    GetRichEditCtrl().SetSel(Pos, Pos);
334    LastOpenParenIndex = FindPrevOpenParen();
335    if (LastOpenParenIndex != -1) {
336        GetRichEditCtrl().SetSel(LastOpenParenIndex, LastOpenParenIndex + 1);
337        GetRichEditCtrl().SetSelectionCharFormat(cf);
338    }
339
340    GetRichEditCtrl().SetSel(Pos, Pos);
341    LastCloseParenIndex = FindNextCloseParen();
342    if (LastCloseParenIndex != -1) {
343        GetRichEditCtrl().SetSel(LastCloseParenIndex, LastCloseParenIndex + 1);
344        GetRichEditCtrl().SetSelectionCharFormat(cf);
345    }
346    if ((LastOpenParenIndex == -1 || LastCloseParenIndex == -1) && (LastOpenParenIndex != -1 || LastCloseParenIndex != -1))
347        ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Detected Mismatched Paren", TRUE);
348    else
349        ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Ready", TRUE);
350
351}
352
353/* ---------------------------------------------------------------------------
354 ------------------------------------------------------------------------- /**/
355void CLispEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
356{
357        // TODO: Add your message handler code here and/or call default
358    CRichEditView::OnKeyDown(nChar, nRepCnt, nFlags); // Call this first so that the caret is updated
359
360    if (nFlags & 256 && GetRichEditCtrl().GetSelectionType() == SEL_EMPTY) {
361        CPoint Pt = GetRichEditCtrl().GetCaretPos();
362/*        Pt.x = GetRichEditCtrl().LineIndex(-1);
363        Pt.y =
364             */
365        GetRichEditCtrl().HideSelection(TRUE, FALSE);
366        CHARFORMAT cf, cfbak;
367        GetRichEditCtrl().GetDefaultCharFormat(cf);
368        cf.dwMask = CFM_BOLD | CFM_COLOR;
369        cfbak = cf;
370        long Start, End;
371        GetRichEditCtrl().GetSel(Start, End);
372        MatchParen(Start);
373   
374        if (Start <= End)
375            GetRichEditCtrl().SetSel(Start, End);
376        else
377            GetRichEditCtrl().SetSel(End, Start);
378        GetRichEditCtrl().SetSelectionCharFormat(cfbak);
379        GetRichEditCtrl().SetCaretPos(Pt);
380        GetRichEditCtrl().HideSelection(FALSE, FALSE);
381    }
382}
383
384/* ---------------------------------------------------------------------------
385 ------------------------------------------------------------------------- /**/
386void CLispEditorView::OnLButtonUp(UINT nFlags, CPoint point)
387{
388        // TODO: Add your message handler code here and/or call default
389    if (GetRichEditCtrl().GetSelectionType() == SEL_EMPTY) {
390        GetRichEditCtrl().HideSelection(TRUE, FALSE);
391        CHARFORMAT cf, cfbak;
392        GetRichEditCtrl().GetDefaultCharFormat(cf);
393        cf.dwMask = CFM_BOLD | CFM_COLOR;
394        cfbak = cf;
395        long Start, End;
396        GetRichEditCtrl().GetSel(Start, End);
397        MatchParen(Start);
398   
399        if (Start <= End)
400            GetRichEditCtrl().SetSel(Start, End);
401        else
402            GetRichEditCtrl().SetSel(End, Start);
403        GetRichEditCtrl().SetSelectionCharFormat(cfbak);
404        GetRichEditCtrl().HideSelection(FALSE, FALSE);
405    }
406        CRichEditView::OnLButtonUp(nFlags, point);
407}
408
409/* ---------------------------------------------------------------------------
410 ------------------------------------------------------------------------- /**/
411CString CLispEditorView::GetCurrentWord(long &lFirst, long &lLast)
412{
413    int* buf;
414    int BufLen;
415    CString ret;
416    long Start, End, Line;
417    GetRichEditCtrl().GetSel(Start, End);
418    Line = GetRichEditCtrl().LineFromChar(Start);
419    BufLen = GetRichEditCtrl().LineLength();
420    buf = (int*) malloc(4 + BufLen);
421    ZeroMemory(buf, 4 + BufLen);
422    buf[0] = BufLen;
423    GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
424    CString SearchSpace = (char*) buf;
425    delete buf;
426
427    int Index, FirstChar, LastChar;
428    Index = Start - GetRichEditCtrl().LineIndex() - 1;
429   
430    int Quote1Pos, Quote2Pos = -1, CommentPos = 0;
431    do {
432        CommentPos = SearchSpace.Find(';', Quote2Pos + 1);
433        if (CommentPos == -1)
434            CommentPos = 16000; // Hopefully this will never be exceeded...
435
436        Quote1Pos = SearchSpace.Find('"', Quote2Pos + 1);
437        if (Quote1Pos != -1) {
438            Quote2Pos = SearchSpace.Find('"', Quote1Pos + 1);
439            if (Quote2Pos == -1)
440                Quote2Pos = SearchSpace.GetLength();
441        }
442    } while (Quote1Pos != -1 && (Quote1Pos > Index || Quote2Pos < Index) && Quote1Pos < CommentPos);
443   
444    if (Quote1Pos != -1 && Quote1Pos <= Index && Quote2Pos >= Index && Quote1Pos < CommentPos) {
445        ret = SearchSpace.Mid(Quote1Pos, Quote2Pos);
446        lFirst = GetRichEditCtrl().LineIndex() + Quote1Pos;
447        lLast = GetRichEditCtrl().LineIndex() + Quote2Pos + 1;
448        return ret;
449    }
450    else if (CommentPos != 16000) {
451        ret = SearchSpace.Right(SearchSpace.GetLength() - CommentPos);
452        lFirst = GetRichEditCtrl().LineIndex() + CommentPos;
453        lLast = GetRichEditCtrl().LineIndex() + SearchSpace.GetLength() + 1;
454        return ret;
455    }
456       
457    if (IsSeparator(((LPCSTR) SearchSpace)[Index])) {
458        lFirst = Index;
459        lLast = Index + 1;
460        ret = (((LPCSTR) SearchSpace)[Index]);
461        _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) ret);
462        return ret;
463    }
464    while (Index > 0 && !IsSeparator(((LPCSTR) SearchSpace)[Index]))
465        Index--;
466    if (IsSeparator(((LPCSTR) SearchSpace)[Index]))
467        Index++;
468    FirstChar = Index;
469    Index = Start - GetRichEditCtrl().LineIndex() - 1;
470    while (Index < SearchSpace.GetLength() && !IsSeparator(((LPCSTR) SearchSpace)[Index]))
471        Index++;
472    LastChar = Index;
473
474    ret = SearchSpace.Right(SearchSpace.GetLength() - FirstChar);
475    ret = ret.Left(LastChar - FirstChar);
476//    _RPT2(_CRT_WARN, "Found open paren at position %d; NumOpen: %d\n", Start, NumOpen);
477    _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) ret);
478    lFirst = GetRichEditCtrl().LineIndex() + FirstChar;
479    lLast = GetRichEditCtrl().LineIndex() + LastChar;
480//    lLast = LastChar - FirstChar - 1;
481    return ret;
482}
483
484/* ---------------------------------------------------------------------------
485 ------------------------------------------------------------------------- /**/
486void CLispEditorView::ColorRange(long Start, long End)
487{
488    CString SearchSpace, CurrentWord, StatusText;
489
490   
491    int QuotePos, CommentPos;
492    CommentPos = IsPosCommented(Start);
493    if (CommentPos != -1)
494        Start = CommentPos;
495    else {
496        QuotePos = IsPosQuoted(Start);
497        if (QuotePos != -1)
498            Start = QuotePos;
499    }
500
501    CHARRANGE cr;
502    GetRichEditCtrl().GetSel(cr);
503    GetRichEditCtrl().SetSel(Start, End);
504    SearchSpace = GetRichEditCtrl().GetSelText();
505
506    int Index = 0, FirstChar = 0;
507    while (FirstChar < SearchSpace.GetLength()) {
508       
509        StatusText.Format("Formatting -- %d%%", (int) ((float) FirstChar / SearchSpace.GetLength() * 100));
510        ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, (LPCSTR) StatusText, TRUE);
511        while (((LPCSTR) SearchSpace)[Index] == ' ')
512            Index++;
513        FirstChar = Index;
514        while (Index < SearchSpace.GetLength() && (!IsSeparator(((LPCSTR) SearchSpace)[Index])))
515            Index++;
516        if (Index == FirstChar) {
517            unsigned char c = ((LPCSTR) SearchSpace)[Index];
518            switch (c) {
519                case ';': {
520                        int EndOfLine = SearchSpace.Find('\n', Index);
521                        if (EndOfLine == -1)
522                            EndOfLine = SearchSpace.GetLength();
523                        Index = EndOfLine;
524
525                    } break;
526                case '/': {
527                        if (((LPCSTR) SearchSpace)[Index+1] == '*') {
528                            int EndComment = SearchSpace.Find("*/", Index + 2);
529                            if (EndComment != -1)
530                                Index = EndComment + 2;
531                            else {
532                                Index = SearchSpace.GetLength();
533                            }
534                        }
535                        else
536                            Index++;
537                    } break;
538                case '"': {
539                        int LastQuote = SearchSpace.Find('"', Index + 1);
540                        if (LastQuote != -1)
541                            Index = LastQuote + 1;
542                        else {
543                            LastQuote = SearchSpace.Find('\n', Index + 1);
544                            if (LastQuote != -1)
545                                Index = LastQuote;
546                            else
547                                Index = SearchSpace.GetLength();
548                        }
549
550                    } break;
551                default:
552                    Index++;
553            }
554        }
555        CurrentWord = SearchSpace.Mid(FirstChar, Index - FirstChar);
556//        _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) CurrentWord);
557        FormatWord(WordType(CurrentWord), Start + FirstChar, Start + Index);
558        FirstChar = Index;
559    }
560    GetRichEditCtrl().SetSel(cr);
561    ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Ready", TRUE);
562}
563
564/* ---------------------------------------------------------------------------
565 ------------------------------------------------------------------------- /**/
566/*void *compile(char *&s)
567{
568    void *ret = NULL;
569    if (!read_ltoken(s, n))
570        lerror(NULL, "unexpected end of program");
571    if (streq(n, "nil"))
572        return NULL;
573    else
574        if (toupper(n[0]) == 'T' && !n[1])
575            return true_symbol;
576        else if (n[0] == '\'') {                // short hand for quote function
577            void *cs=new_cons_cell(),*c2=NULL;
578            p_ref r1(cs), r2(c2);
579           
580            ((cons_cell *)cs)->car = (cons_cell*) quote_symbol;
581            c2 = new_cons_cell();
582            ((cons_cell *)c2)->car = (cons_cell*) compile(s);
583            ((cons_cell *)c2)->cdr = NULL;
584            ((cons_cell *)cs)->cdr = (cons_cell*) c2;
585            ret = cs;
586        }
587        else if (n[0] == '`') {                 // short hand for backquote function
588            void *cs = new_cons_cell(), *c2 = NULL;
589            p_ref r1(cs), r2(c2);
590           
591            ((cons_cell *)cs)->car = (cons_cell*) backquote_symbol;
592            c2 = new_cons_cell();
593            ((cons_cell *)c2)->car = (cons_cell*) compile(s);
594            ((cons_cell *)c2)->cdr = NULL;
595            ((cons_cell *)cs)->cdr = (cons_cell*) c2;
596            ret = cs;
597        }
598        else if (n[0] == ',') {                 // short hand for comma function
599            void *cs = new_cons_cell(), *c2 = NULL;
600            p_ref r1(cs), r2(c2);
601           
602            ((cons_cell *)cs)->car = (cons_cell*) comma_symbol;
603            c2 = new_cons_cell();
604            ((cons_cell *)c2)->car = (cons_cell*) compile(s);
605            ((cons_cell *)c2)->cdr = NULL;
606            ((cons_cell *)cs)->cdr = (cons_cell*) c2;
607            ret = cs;
608        }
609        else if (n[0] == '(') {                 // make a list of everything in ()
610            void *first = NULL, *cur = NULL, *last = NULL;   
611            p_ref r1(first), r2(cur), r3(last);
612            int done = 0;
613            do {
614                char *tmp = s;
615                if (!read_ltoken(tmp, n))       // check for the end of the list
616                    lerror(NULL, "unexpected end of program");
617                if (n[0] == ')') {
618                    done = 1;
619                    read_ltoken(s, n);                // read off the ')'
620                }
621                else {
622                    if (n[0] == '.' && !n[1]) {
623                        if (!first)
624                            lerror(s, "token '.' not allowed here\n");       
625                        else {
626                            read_ltoken(s, n);              // skip the '.'
627                            ((cons_cell *)last)->cdr = (cons_cell*) compile(s);          // link the last cdr to
628                            last = NULL;
629                        }
630                    }
631                    else
632                        if (!last && first)
633                            lerror(s, "illegal end of dotted list\n");
634                        else {
635                            cur = new_cons_cell();
636                            p_ref r1(cur);
637                            if (!first)
638                                first = cur;
639                            ((cons_cell*) cur)->car = (cons_cell*) compile(s); 
640                            if (last)
641                                ((cons_cell *)last)->cdr = (cons_cell*) cur;
642                            last = cur;
643                        }
644                }
645            }
646            while (!done);
647            ret = comp_optimize(first);
648        }
649        else if (n[0]==')')
650            lerror(s,"mismatched )");
651        else if (isdigit(n[0]) || (n[0]=='-' && isdigit(n[1]))) {
652            lisp_number *num=new_lisp_number(0);
653            sscanf(n,"%d",&num->num);
654            ret=num;
655        }
656        else if (n[0]=='"') {
657            ret=new_lisp_string(str_token_len(s));
658            char *start=lstring_value(ret);
659            for (;*s && (*s!='"' || s[1]=='"');s++,start++) {
660                if (*s=='\\') {
661                    s++;
662                    if (*s=='n') *start='\n';
663                    if (*s=='r') *start='\r';
664                    if (*s=='t') *start='\t';
665                    if (*s=='\\') *start='\\';
666                }
667                else
668                    *start=*s;
669                if (*s=='"')
670                    s++;
671            }
672            *start=0;
673            s++;
674        }
675        else if (n[0]=='#') {
676            if (n[1]=='\\') {
677                read_ltoken(s,n);                   // read character name
678                if (streq(n,"newline"))
679                    ret=new_lisp_character('\n');
680                else if (streq(n,"space"))
681                    ret=new_lisp_character(' ');       
682                else
683                    ret=new_lisp_character(n[0]);       
684            }
685            else if (n[1]==0) {                           // short hand for function
686                void *cs=new_cons_cell(),*c2=NULL;
687                p_ref r4(cs),r5(c2);
688                ((cons_cell *)cs)->car = (cons_cell*) make_find_symbol("function");
689                c2=new_cons_cell();
690                ((cons_cell *)c2)->car = (cons_cell*) compile(s);
691                ((cons_cell *)cs)->cdr = (cons_cell*) c2;
692                ret=cs;
693            }
694            else {
695                lbreak("Unknown #\\ notation : %s\n",n);
696            }
697        }
698        else
699            return make_find_symbol(n);
700       
701    return ret;
702}
703*/
704
705/* ---------------------------------------------------------------------------
706 ------------------------------------------------------------------------- /**/
707void CLispEditorView::FormatWord(int Type, long Start, long End)
708{
709    CHARFORMAT cf;
710    GetRichEditCtrl().GetDefaultCharFormat(cf);
711    cf.dwMask = CFM_COLOR | CFM_BOLD;
712    cf.dwEffects = 0;
713    switch (Type) {
714        case LISP_SYMBOL:
715            cf.crTextColor = RGB(0, 220, 0);
716            break;
717       
718        case LISP_NUMBER:
719            cf.crTextColor = RGB(0, 255, 255);
720            break;
721
722        case LISP_STRING:
723            cf.crTextColor = RGB(255, 0, 0);
724            break;
725
726        case LISP_OPERATOR:
727            cf.crTextColor = RGB(200, 200, 0);
728            break;
729        case LISP_COMMENT:
730            cf.crTextColor = RGB(150, 150, 150);
731            break;
732        case LISP_WHITESPACE:
733            break;
734        default:
735            cf.crTextColor = RGB(255, 255, 255);
736            break;
737
738    }
739    GetRichEditCtrl().SetSel(Start, End);
740    GetRichEditCtrl().SetSelectionCharFormat(cf);
741}
742
743/* ---------------------------------------------------------------------------
744    Returns the character index of the opening quote if Pos is within a
745    comment; otherwise returns -1
746 ------------------------------------------------------------------------- /**/
747long CLispEditorView::IsPosCommented(long Pos)
748{
749    int* buf;
750    int BufLen, Start, Line;
751    CString ret;
752
753    Line = GetRichEditCtrl().LineFromChar(Pos);
754    BufLen = GetRichEditCtrl().LineLength();
755    Start = GetRichEditCtrl().LineIndex(Line);
756
757    buf = (int*) malloc(4 + BufLen);    ZeroMemory(buf, 4 + BufLen);    buf[0] = BufLen;
758    GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
759    CString SearchSpace = (char*) buf;
760    delete buf;
761
762    int CommentPos = -1;
763    do {
764        CommentPos = SearchSpace.Find(';', CommentPos + 1);
765        if (CommentPos != -1 && (CommentPos + Start < Pos) && IsPosQuoted(CommentPos + Start) == -1)
766            return CommentPos + Start; // We found a commented out section, return the start index
767    } while (CommentPos != -1);
768
769    FINDTEXTEX ft;
770    ZeroMemory(&ft, sizeof(ft));
771    ft.chrg.cpMax = Pos;
772    int BlockStart, BlockEnd = 0;
773
774    do {
775        ft.chrg.cpMin = BlockEnd;
776        ft.lpstrText = "/*";
777        BlockStart = GetRichEditCtrl().FindText(0, &ft);
778        if (BlockStart != -1) {
779            ft.chrg.cpMin = BlockStart + 2;
780            ft.lpstrText = "*/";
781            BlockEnd = GetRichEditCtrl().FindText(0, &ft);
782            if (BlockEnd == -1)
783                BlockEnd = Pos + 1;
784        }
785    } while (BlockStart != -1 && BlockEnd < Pos);
786
787    if (BlockStart != -1 && BlockStart <= Pos && BlockEnd > Pos) {
788        if (IsPosQuoted(BlockStart) == -1)
789            return BlockStart;
790    }
791
792    return -1;
793}
794
795/* ---------------------------------------------------------------------------
796    Returns the character index of the opening quote if Pos is contained within
797    quotes; otherwise returns -1
798 ------------------------------------------------------------------------- /**/
799long CLispEditorView::IsPosQuoted(long Pos)
800{
801    int* buf;
802    int BufLen, Line, Start;
803    CString ret;
804
805    Line = GetRichEditCtrl().LineFromChar(Pos);
806    BufLen = GetRichEditCtrl().LineLength();
807    Start = GetRichEditCtrl().LineIndex(Line);
808    Pos -= Start;
809    buf = (int*) malloc(4 + BufLen);
810    ZeroMemory(buf, 4 + BufLen);
811    buf[0] = BufLen;
812    GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
813    CString SearchSpace = (char*) buf;
814    delete buf;
815
816    int Quote1Pos, Quote2Pos = -1;
817    do {
818        Quote1Pos = SearchSpace.Find('"', Quote2Pos + 1);
819        if (Quote1Pos != -1) {
820            Quote2Pos = SearchSpace.Find('"', Quote1Pos + 1);
821            if (Quote2Pos == -1)
822                Quote2Pos = SearchSpace.GetLength();
823        }
824    } while (Quote1Pos != -1 && Quote2Pos < Pos);
825   
826    if (Quote1Pos != -1 && Quote1Pos <= Pos && Quote2Pos > Pos)
827        if (IsPosCommented(Quote1Pos + Start) == -1)
828            return Quote1Pos + Start;
829
830    return -1;
831}
Note: See TracBrowser for help on using the repository browser.