Index: compiler/globals.pas
===================================================================
--- compiler/globals.pas	(revision 6129)
+++ compiler/globals.pas	(working copy)
@@ -52,7 +52,7 @@
          [m_delphi,m_all,m_class,m_objpas,m_result,m_string_pchar,
           m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring,
           m_out,m_default_para,m_duplicate_names,m_hintdirective,m_add_pointer,
-          m_property,m_default_inline,m_except];
+          m_property,m_default_inline,m_except,m_ident_escape];
        fpcmodeswitches    : tmodeswitches=
          [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
           m_cvar_support,m_initfinal,m_add_pointer,m_hintdirective,
@@ -61,6 +61,10 @@
          [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
           m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer,m_out,m_default_para,m_hintdirective,
           m_property,m_default_inline,m_except];
+       chromemodeswitches : tmodeswitches=
+         [m_chrome,m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
+          m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer,m_out,m_default_para,m_hintdirective,
+          m_property,m_default_inline,m_except, m_ident_escape, m_always_ident_after_dot];
        tpmodeswitches     : tmodeswitches=
          [m_tp7,m_all,m_tp_procvar,m_duplicate_names];
        gpcmodeswitches    : tmodeswitches=
Index: compiler/globtype.pas
===================================================================
--- compiler/globtype.pas	(revision 6129)
+++ compiler/globtype.pas	(working copy)
@@ -178,30 +178,32 @@
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        tmodeswitch = (m_none,m_all, { needed for keyword }
          { generic }
-         m_fpc,m_objfpc,m_delphi,m_tp7,m_gpc,m_mac,
+         m_fpc,m_objfpc,m_delphi,m_tp7,m_gpc,m_mac,m_chrome,
          { more specific }
-         m_class,               { delphi class model }
-         m_objpas,              { load objpas unit }
-         m_result,              { result in functions }
-         m_string_pchar,        { pchar 2 string conversion }
-         m_cvar_support,        { cvar variable directive }
-         m_nested_comment,      { nested comments }
-         m_tp_procvar,          { tp style procvars (no @ needed) }
-         m_mac_procvar,         { macpas style procvars }
-         m_repeat_forward,      { repeating forward declarations is needed }
-         m_pointer_2_procedure, { allows the assignement of pointers to
-                                  procedure variables                     }
-         m_autoderef,           { does auto dereferencing of struct. vars }
-         m_initfinal,           { initialization/finalization for units }
-         m_add_pointer,         { allow pointer add/sub operations }
-         m_default_ansistring,  { ansistring turned on by default }
-         m_out,                 { support the calling convention OUT }
-         m_default_para,        { support default parameters }
-         m_hintdirective,       { support hint directives }
-         m_duplicate_names,     { allow locals/paras to have duplicate names of globals }
-         m_property,            { allow properties }
-         m_default_inline,      { allow inline proc directive }
-         m_except               { allow exception-related keywords }
+         m_class,                 { delphi class model }
+         m_objpas,                { load objpas unit }
+         m_result,                { result in functions }
+         m_string_pchar,          { pchar 2 string conversion }
+         m_cvar_support,          { cvar variable directive }
+         m_nested_comment,        { nested comments }
+         m_tp_procvar,            { tp style procvars (no @ needed) }
+         m_mac_procvar,           { macpas style procvars }
+         m_repeat_forward,        { repeating forward declarations is needed }
+         m_pointer_2_procedure,   { allows the assignement of pointers to
+                                    procedure variables                     }
+         m_autoderef,             { does auto dereferencing of struct. vars }
+         m_initfinal,             { initialization/finalization for units }
+         m_add_pointer,           { allow pointer add/sub operations }
+         m_default_ansistring,    { ansistring turned on by default }
+         m_out,                   { support the calling convention OUT }
+         m_default_para,          { support default parameters }
+         m_hintdirective,         { support hint directives }
+         m_duplicate_names,       { allow locals/paras to have duplicate names of globals }
+         m_property,              { allow properties }
+         m_default_inline,        { allow inline proc directive }
+         m_except,                { allow exception-related keywords }
+         m_ident_escape,          { uses & to force the next token to be recognized as an _ID }
+         m_always_ident_after_dot { if a string follows a dot it's never recognized as a keyword }
        );
        tmodeswitches = set of tmodeswitch;
 
Index: compiler/pdecobj.pas
===================================================================
--- compiler/pdecobj.pas	(revision 6129)
+++ compiler/pdecobj.pas	(working copy)
@@ -662,6 +662,7 @@
                   end;
                 _PROCEDURE,
                 _FUNCTION,
+                _METHOD,
                 _CLASS :
                   begin
                     if (sp_published in current_object_option) and
Index: compiler/pdecsub.pas
===================================================================
--- compiler/pdecsub.pas	(revision 6129)
+++ compiler/pdecsub.pas	(working copy)
@@ -891,6 +891,7 @@
     function parse_proc_dec(aclass:tobjectdef):tprocdef;
       var
         pd : tprocdef;
+        ismethod: boolean;
         isclassmethod : boolean;
         locationstr: string;
         popclass : boolean;
@@ -902,7 +903,7 @@
         if try_to_consume(_CLASS) then
          begin
            { class method only allowed for procedures and functions }
-           if not(token in [_FUNCTION,_PROCEDURE]) then
+           if not(token in [_FUNCTION,_PROCEDURE,_METHOD]) then
              Message(parser_e_procedure_or_function_expected);
 
            if is_interface(aclass) then
@@ -911,9 +912,13 @@
              isclassmethod:=true;
          end;
         case token of
-          _FUNCTION :
+          _FUNCTION, _METHOD :
             begin
-              consume(_FUNCTION);
+              ismethod := token = _METHOD;
+              if ismethod then
+                consume(_METHOD)
+              else
+                consume(_FUNCTION);
               if parse_proc_head(aclass,potype_function,pd) then
                 begin
                   { pd=nil when it is a interface mapping }
@@ -963,6 +968,10 @@
                        end
                       else
                        begin
+                          if ismethod then begin
+                            pd.returndef := voidtype;
+                            pd.proctypeoption := potype_procedure;
+                          end else
                           if (
                               parse_only and
                               not(is_interface(pd._class))
Index: compiler/psub.pas
===================================================================
--- compiler/psub.pas	(revision 6129)
+++ compiler/psub.pas	(working copy)
@@ -1615,6 +1615,7 @@
               _DESTRUCTOR,
               _FUNCTION,
               _PROCEDURE,
+              _METHOD,
               _OPERATOR,
               _CLASS:
                 read_proc;
@@ -1681,6 +1682,7 @@
                threadvar_dec;
              _FUNCTION,
              _PROCEDURE,
+             _METHOD,
              _OPERATOR :
                read_proc;
              else
Index: compiler/ptype.pas
===================================================================
--- compiler/ptype.pas	(revision 6129)
+++ compiler/ptype.pas	(working copy)
@@ -600,7 +600,7 @@
       var
         p  : tnode;
         pd : tabstractprocdef;
-        is_func,
+        is_func, is_method,
         enumdupmsg, first : boolean;
         newtype    : ttypesym;
         oldlocalswitches : tlocalswitches;
@@ -724,15 +724,17 @@
               begin
                 def:=object_dec(name,genericdef,genericlist,nil);
               end;
+            _METHOD,
             _PROCEDURE,
             _FUNCTION:
               begin
                 is_func:=(token=_FUNCTION);
+                is_method:=(token=_METHOD);
                 consume(token);
                 pd:=tprocvardef.create(normal_function_level);
                 if token=_LKLAMMER then
                   parse_parameter_dec(pd);
-                if is_func then
+                if is_func or (is_method and (token = _COLON)) then
                  begin
                    consume(_COLON);
                    single_type(pd.returndef,false);
Index: compiler/scanner.pas
===================================================================
--- compiler/scanner.pas	(revision 6129)
+++ compiler/scanner.pas	(working copy)
@@ -283,6 +283,9 @@
           { TODO: enable this for 2.3/2.9 }
           //  include(current_settings.localswitches, cs_typed_addresses);
         end else
+         if s='CHROME' then begin
+          current_settings.modeswitches:=chromemodeswitches;
+        end else
          if s='GPC' then
           current_settings.modeswitches:=gpcmodeswitches
         else
@@ -391,6 +394,8 @@
               def_system_macro('FPC_TP')
             else if (m_objfpc in current_settings.modeswitches) then
               def_system_macro('FPC_OBJFPC')
+            else if (m_chrome in current_settings.modeswitches) then
+              def_system_macro('FPC_CHROME')
             else if (m_gpc in current_settings.modeswitches) then
               def_system_macro('FPC_GPC')
             else if (m_mac in current_settings.modeswitches) then
@@ -3131,57 +3136,61 @@
            idtoken:=_ID;
          { keyword or any other known token,
            pattern is always uppercased }
-           if (pattern[1]<>'_') and (length(pattern) in [tokenlenmin..tokenlenmax]) then
+           if not (m_always_ident_after_dot in current_settings.modeswitches) or
+             (lasttoken <> _POINT) then
             begin
-              low:=ord(tokenidx^[length(pattern),pattern[1]].first);
-              high:=ord(tokenidx^[length(pattern),pattern[1]].last);
-              while low<high do
-               begin
-                 mid:=(high+low+1) shr 1;
-                 if pattern<tokeninfo^[ttoken(mid)].str then
-                  high:=mid-1
-                 else
-                  low:=mid;
-               end;
-              with tokeninfo^[ttoken(high)] do
-                if pattern=str then
-                  begin
-                    if keyword in current_settings.modeswitches then
-                      if op=NOTOKEN then
-                        token:=ttoken(high)
+             if (pattern[1]<>'_') and (length(pattern) in [tokenlenmin..tokenlenmax]) then
+              begin
+                low:=ord(tokenidx^[length(pattern),pattern[1]].first);
+                high:=ord(tokenidx^[length(pattern),pattern[1]].last);
+                while low<high do
+                 begin
+                   mid:=(high+low+1) shr 1;
+                   if pattern<tokeninfo^[ttoken(mid)].str then
+                    high:=mid-1
+                   else
+                    low:=mid;
+                 end;
+                with tokeninfo^[ttoken(high)] do
+                  if pattern=str then
+                    begin
+                      if keyword in current_settings.modeswitches then
+                        if op=NOTOKEN then
+                          token:=ttoken(high)
+                        else
+                          token:=op;
+                      idtoken:=ttoken(high);
+                    end;
+              end;
+           { Only process identifiers and not keywords }
+             if token=_ID then
+              begin
+              { this takes some time ... }
+                if (cs_support_macro in current_settings.moduleswitches) then
+                 begin
+                   mac:=tmacro(search_macro(pattern));
+                   if assigned(mac) and (not mac.is_compiler_var) and (assigned(mac.buftext)) then
+                    begin
+                      if yylexcount<max_macro_nesting then
+                       begin
+                         mac.is_used:=true;
+                         inc(yylexcount);
+                         insertmacro(pattern,mac.buftext,mac.buflen,
+                           mac.fileinfo.line,mac.fileinfo.fileindex);
+                       { handle empty macros }
+                         if c=#0 then
+                           reload;
+                         readtoken(false);
+                         { that's all folks }
+                         dec(yylexcount);
+                         exit;
+                       end
                       else
-                        token:=op;
-                    idtoken:=ttoken(high);
-                  end;
+                       Message(scan_w_macro_too_deep);
+                    end;
+                 end;
             end;
-         { Only process identifiers and not keywords }
-           if token=_ID then
-            begin
-            { this takes some time ... }
-              if (cs_support_macro in current_settings.moduleswitches) then
-               begin
-                 mac:=tmacro(search_macro(pattern));
-                 if assigned(mac) and (not mac.is_compiler_var) and (assigned(mac.buftext)) then
-                  begin
-                    if yylexcount<max_macro_nesting then
-                     begin
-                       mac.is_used:=true;
-                       inc(yylexcount);
-                       insertmacro(pattern,mac.buftext,mac.buflen,
-                         mac.fileinfo.line,mac.fileinfo.fileindex);
-                     { handle empty macros }
-                       if c=#0 then
-                         reload;
-                       readtoken(false);
-                       { that's all folks }
-                       dec(yylexcount);
-                       exit;
-                     end
-                    else
-                     Message(scan_w_macro_too_deep);
-                  end;
-               end;
-            end;
+           end;
          { return token }
            goto exit_label;
          end
@@ -3211,8 +3220,18 @@
 
              '&' :
                begin
-                 if m_fpc in current_settings.modeswitches then
+                 if (m_ident_escape in current_settings.modeswitches)
+                   and (inputpointer[1] in ['A'..'Z','a'..'z','_']) then
                   begin
+                    readchar;
+                    gettokenpos;
+                    readstring;
+                    token:=_ID;
+                    idtoken:=_ID;
+                    goto exit_label;
+                  end
+                 else if m_fpc in current_settings.modeswitches then
+                  begin
                     readnumber;
                     token:=_INTCONST;
                     goto exit_label;
Index: compiler/tokens.pas
===================================================================
--- compiler/tokens.pas	(revision 6129)
+++ compiler/tokens.pas	(working copy)
@@ -162,6 +162,7 @@
     _EXPORT,
     _INLINE,
     _LEGACY,
+    _METHOD,
     _OBJECT,
     _PACKED,
     _PASCAL,
@@ -412,6 +413,7 @@
       (str:'EXPORT'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'INLINE'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'LEGACY'        ;special:false;keyword:m_none;op:NOTOKEN),   { Syscall variation on MorphOS }
+      (str:'METHOD'        ;special:false;keyword:m_chrome;op:NOTOKEN),
       (str:'OBJECT'        ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'PACKED'        ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'PASCAL'        ;special:false;keyword:m_none;op:NOTOKEN),
