euphoria
changeset 5391:51e87b308179
* merge 4.0 changes
| author | Shawn Pringle <shawn.pringle@gmail.com> |
|---|---|
| date | Wed Dec 21 16:45:49 2011 -0300 (18 months ago) |
| parents | cf65e80418ef 936421a1c6f3 |
| children | 26ea874aeaf9 |
| files | source/Makefile.gnu |
line diff
1.1 --- a/demo/simple_debug.e Mon Dec 19 23:19:58 2011 -0300 1.2 +++ b/demo/simple_debug.e Wed Dec 21 16:45:49 2011 -0300 1.3 @@ -100,6 +100,7 @@ 1.4 printf( 1, " %s", { get_name( params[j] ) } ) 1.5 end for 1.6 puts( 1, " )") 1.7 + 1.8 end if 1.9 puts( 1, "\n" ) 1.10 end procedure
2.1 --- a/demo/win32/window.exw Mon Dec 19 23:19:58 2011 -0300 2.2 +++ b/demo/win32/window.exw Wed Dec 21 16:45:49 2011 -0300 2.3 @@ -8,254 +8,444 @@ 2.4 include std/os.e 2.5 include std/machine.e 2.6 include std/dll.e 2.7 +include std/math.e 2.8 +include std/error.e 2.9 +include std/console.e 2.10 2.11 -constant cbSize = 0, 2.12 - style = 4, 2.13 - lpfnWndProc = 8, 2.14 - cbClsExtra = 12, 2.15 - cbWndExtra = 16, 2.16 - hInstance = 20, 2.17 - hIcon = 24, 2.18 - hCursor = 28, 2.19 - hbrBackground = 32, 2.20 - lpszMenuName = 36, 2.21 - lpszClassName = 40, 2.22 - hIconSm = 44, 2.23 - SIZE_OF_WNDCLASS = 48 2.24 +include std/memstruct/windows.e 2.25 2.26 -constant SIZE_OF_MESSAGE = 40 2.27 +--**** 2.28 +-- === Windows Data Type constants for function/procedure calls 2.29 + 2.30 +public constant 2.31 + C_BYTE = C_UCHAR, 2.32 + C_BOOL = C_INT, 2.33 + C_ATOM = C_USHORT, 2.34 + C_WORD = C_USHORT, 2.35 + C_DWORD= C_ULONG, 2.36 + C_WPARAM = C_POINTER, 2.37 + C_LPARAM = C_POINTER, 2.38 + C_HANDLE = C_POINTER, 2.39 + C_HWND = C_POINTER, 2.40 + C_LPSTR = C_POINTER, 2.41 + C_COLORREF = C_DWORD, --0x00bbggrr 2.42 + C_LANGID = C_WORD, 2.43 + $ 2.44 + 2.45 +public constant C_LONG_PTR = C_POINTER 2.46 + 2.47 +public constant C_LRESULT = C_LONG_PTR 2.48 + 2.49 + 2.50 + 2.51 2.52 constant CS_HREDRAW = 2, 2.53 - CS_VREDRAW = 1 2.54 + CS_VREDRAW = 1 2.55 2.56 constant SW_SHOWNORMAL = 1 2.57 2.58 constant WM_CREATE = #01, 2.59 - WM_PAINT = #0F, 2.60 - WM_DESTROY= #02 2.61 + WM_PAINT = #0F, 2.62 + WM_DESTROY= #02 2.63 2.64 constant SND_FILENAME = #00020000, 2.65 - SND_ASYNC = #00000001 2.66 - 2.67 + SND_ASYNC = #00000001 2.68 + 2.69 constant DT_SINGLELINE = #0020, 2.70 - DT_CENTER = #0001, 2.71 - DT_VCENTER = #0004 2.72 - 2.73 -function or_all(sequence s) 2.74 --- or together all elements of a sequence 2.75 - atom result 2.76 - 2.77 - result = 0 2.78 - for i = 1 to length(s) do 2.79 - result = or_bits(result, s[i]) 2.80 - end for 2.81 - return result 2.82 -end function 2.83 + DT_CENTER = #0001, 2.84 + DT_VCENTER = #0004 2.85 + 2.86 + 2.87 2.88 constant WS_OVERLAPPED = #00000000, 2.89 - WS_CAPTION = #00C00000, 2.90 - WS_SYSMENU = #00080000, 2.91 - WS_THICKFRAME = #00040000, 2.92 - WS_MINIMIZEBOX = #00020000, 2.93 - WS_MAXIMIZEBOX = #00010000 2.94 + WS_CAPTION = #00C00000, 2.95 + WS_SYSMENU = #00080000, 2.96 + WS_THICKFRAME = #00040000, 2.97 + WS_MINIMIZEBOX = #00020000, 2.98 + WS_MAXIMIZEBOX = #00010000 2.99 2.100 -constant IDC_ARROW = 32512, 2.101 - WHITE_BRUSH = 0, 2.102 - CW_USEDEFAULT = #80000000, 2.103 - WS_OVERLAPPEDWINDOW = or_all({WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, 2.104 - WS_THICKFRAME, WS_MINIMIZEBOX, 2.105 - WS_MAXIMIZEBOX}) 2.106 +constant 2.107 + IDC_ARROW = 32512, 2.108 + IDI_APPLICATION = 3, 2.109 + CW_USEDEFAULT = #80000000, 2.110 + WS_OVERLAPPEDWINDOW = or_all({WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, 2.111 + WS_THICKFRAME, WS_MINIMIZEBOX, 2.112 + WS_MAXIMIZEBOX}), 2.113 + WHITE_BRUSH = 0, 2.114 + LTGRAY_BRUSH = 1, 2.115 + GRAY_BRUSH = 2, 2.116 + DKGRAY_BRUSH = 3, 2.117 + BLACK_BRUSH = 4, 2.118 + NULL_BRUSH = 5, 2.119 +-- HOLLOW_BRUSH = ?, 2.120 + WHITE_PEN = 6, 2.121 + BLACK_PEN = 7, 2.122 + NULL_PEN = 8, 2.123 + OEM_FIXED_FONT = 10, 2.124 + ANSI_FIXED_FONT = 11, 2.125 + ANSI_VAR_FONT = 12, 2.126 + SYSTEM_FONT = 13, 2.127 + DEVICE_DEFAULT_FONT = 14, 2.128 + DEFAULT_PALETTE = 15, 2.129 + SYSTEM_FIXED_FONT = 16, 2.130 2.131 - 2.132 + STOCK_LAST = 16, 2.133 + 2.134 + COLOR_SCROLLBAR = 0, 2.135 + COLOR_BACKGROUND = 1, 2.136 + COLOR_ACTIVECAPTION = 2, 2.137 + COLOR_INACTIVECAPTION = 3, 2.138 + COLOR_MENU = 4, 2.139 + COLOR_WINDOW = 5, 2.140 + COLOR_WINDOWFRAME = 6, 2.141 + COLOR_MENUTEXT = 7, 2.142 + COLOR_WINDOWTEXT = 8, 2.143 + COLOR_CAPTIONTEXT = 9, 2.144 + COLOR_ACTIVEBORDER = 10, 2.145 + COLOR_INACTIVEBORDER = 11, 2.146 + COLOR_APPWORKSPACE = 12, 2.147 + COLOR_HIGHLIGHT = 13, 2.148 + COLOR_HIGHLIGHTTEXT = 14, 2.149 + COLOR_BTNFACE = 15, 2.150 + COLOR_BTNSHADOW = 16, 2.151 + COLOR_GRAYTEXT = 17, 2.152 + COLOR_BTNTEXT = 18, 2.153 + COLOR_INACTIVECAPTIONTEXT = 19, 2.154 + COLOR_BTNHIGHLIGHT = 20, 2.155 + 2.156 + LOGPIXELSX = 88, 2.157 + LOGPIXELSY = 90, 2.158 + OUT_DEFAULT_PRECIS = 0, 2.159 + OUT_STRING_PRECIS = 1, 2.160 + OUT_CHARACTER_PRECIS = 2, 2.161 + OUT_STROKE_PRECIS = 3, 2.162 + OUT_TT_PRECIS = 4, 2.163 + OUT_DEVICE_PRECIS = 5, 2.164 + OUT_RASTER_PRECIS = 6, 2.165 + OUT_TT_ONLY_PRECIS = 7, 2.166 + OUT_OUTLINE_PRECIS = 8, 2.167 + OUT_SCREEN_OUTLINE_PRECIS = 9, 2.168 + OUT_PS_ONLY_PRECIS = 10, 2.169 + 2.170 + CLIP_DEFAULT_PRECIS = 0, 2.171 + CLIP_CHARACTER_PRECIS = 1, 2.172 + CLIP_STROKE_PRECIS = 2, 2.173 + CLIP_MASK = #F, 2.174 +-- CLIP_LH_ANGLES = (1<<4), 2.175 + 2.176 +-- CLIP_TT_ALWAYS = (2<<4), 2.177 + 2.178 +-- CLIP_EMBEDDED = (8<<4), 2.179 + 2.180 + DEFAULT_QUALITY = 0, 2.181 + DRAFT_QUALITY = 1, 2.182 + PROOF_QUALITY = 2, 2.183 + 2.184 + DEFAULT_PITCH = 0, 2.185 + FIXED_PITCH = 1, 2.186 + VARIABLE_PITCH = 2, 2.187 + 2.188 + ANSI_CHARSET = 0, 2.189 + DEFAULT_CHARSET = 1, 2.190 + SYMBOL_CHARSET = 2, 2.191 + SHIFTJIS_CHARSET = 128, 2.192 + HANGEUL_CHARSET = 129, 2.193 + HANGUL_CHARSET = 129, 2.194 + GB2312_CHARSET = 134, 2.195 + CHINESEBIG5_CHARSET = 136, 2.196 + OEM_CHARSET = 255, 2.197 + 2.198 + FF_DONTCARE = shift_bits(0, -4), 2.199 + 2.200 +-- FF_ROMAN = (1<<4) , 2.201 + 2.202 +-- FF_SWISS = (2<<4) , 2.203 + 2.204 +-- FF_MODERN = (3<<4) , 2.205 + 2.206 +-- FF_SCRIPT = (4<<4) , 2.207 + 2.208 +-- FF_DECORATIVE = (5<<4) , 2.209 + 2.210 + FW_DONTCARE = 0, 2.211 + FW_THIN = 100, 2.212 + FW_EXTRALIGHT = 200, 2.213 + FW_LIGHT = 300, 2.214 + FW_NORMAL = 400, 2.215 + FW_MEDIUM = 500, 2.216 + FW_SEMIBOLD = 600, 2.217 + FW_BOLD = 700, 2.218 + FW_EXTRABOLD = 800, 2.219 + FW_HEAVY = 900, 2.220 + 2.221 +-- FW_ULTRALIGHT = FW_EXTRALIGHT, 2.222 + 2.223 +-- FW_REGULAR = FW_NORMAL, 2.224 + 2.225 +-- FW_DEMIBOLD = FW_SEMIBOLD, 2.226 + 2.227 +-- FW_ULTRABOLD = FW_EXTRABOLD, 2.228 + 2.229 +-- FW_BLACK = FW_HEAVY, 2.230 + $ 2.231 + 2.232 integer LoadIcon, LoadCursor, GetStockObject, RegisterClassEx, 2.233 CreateWindow, ShowWindow, UpdateWindow, GetMessage, 2.234 TranslateMessage, DispatchMessage, PlaySound, BeginPaint, 2.235 - GetClientRect, DrawText, EndPaint, PostQuitMessage, DefWindowProc 2.236 + GetClientRect, DrawText, EndPaint, PostQuitMessage, DefWindowProc, 2.237 + GetSysColor, SelectObject, SetTextColor, SetBkColor, 2.238 + xGetLastError, xSetLastError, xFormatMessage, 2.239 + GetDeviceCaps, CreateFont, MulDiv 2.240 2.241 procedure not_found(sequence name) 2.242 - puts(1, "Couldn't find " & name & '\n') 2.243 - abort(1) 2.244 + crash( "Couldn't find " & name ) 2.245 end procedure 2.246 2.247 +-- dynamically link a C routine as a Euphoria function 2.248 function link_c_func(atom dll, sequence name, sequence args, atom result) 2.249 --- dynamically link a C routine as a Euphoria function 2.250 - integer handle 2.251 + integer handle 2.252 2.253 - handle = define_c_func(dll, name, args, result) 2.254 - if handle = -1 then 2.255 - not_found(name) 2.256 - else 2.257 - return handle 2.258 - end if 2.259 + handle = define_c_func(dll, name, args, result) 2.260 + if handle = -1 then 2.261 + not_found(name) 2.262 + else 2.263 + return handle 2.264 + end if 2.265 end function 2.266 2.267 +-- dynamically link a C routine as a Euphoria function 2.268 function link_c_proc(atom dll, sequence name, sequence args) 2.269 --- dynamically link a C routine as a Euphoria function 2.270 - integer handle 2.271 + integer handle 2.272 2.273 - handle = define_c_proc(dll, name, args) 2.274 - if handle = -1 then 2.275 - not_found(name) 2.276 - else 2.277 - return handle 2.278 - end if 2.279 + handle = define_c_proc(dll, name, args) 2.280 + if handle = -1 then 2.281 + not_found(name) 2.282 + else 2.283 + return handle 2.284 + end if 2.285 end function 2.286 2.287 +-- get handles to all dll routines that we need 2.288 procedure link_dll_routines() 2.289 --- get handles to all dll routines that we need 2.290 - atom user32, gdi32, winmm 2.291 - 2.292 - user32 = open_dll("user32.dll") 2.293 - if user32 = NULL then 2.294 - not_found("user32.dll") 2.295 - end if 2.296 - gdi32 = open_dll("gdi32.dll") 2.297 - if gdi32 = NULL then 2.298 - not_found("gdi32.dll") 2.299 - end if 2.300 - winmm = open_dll("winmm.dll") 2.301 - if winmm = NULL then 2.302 + atom user32, gdi32, winmm, kernel32 2.303 + 2.304 + user32 = open_dll("user32.dll") 2.305 + if user32 = NULL then 2.306 + not_found("user32.dll") 2.307 + end if 2.308 + gdi32 = open_dll("gdi32.dll") 2.309 + if gdi32 = NULL then 2.310 + not_found("gdi32.dll") 2.311 + end if 2.312 + winmm = open_dll("winmm.dll") 2.313 + if winmm = NULL then 2.314 not_found("winmm.dll") 2.315 - end if 2.316 - 2.317 - LoadIcon = link_c_func(user32, "LoadIconA", {C_POINTER, C_INT}, C_INT) 2.318 - LoadCursor = link_c_func(user32, "LoadCursorA", {C_POINTER, C_INT}, C_INT) 2.319 - GetStockObject = link_c_func(gdi32, "GetStockObject", {C_INT}, C_INT) 2.320 - RegisterClassEx = link_c_func(user32, "RegisterClassExA", {C_POINTER}, C_INT) 2.321 - CreateWindow = link_c_func(user32, "CreateWindowExA", 2.322 - {C_INT, C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT,C_INT}, 2.323 - C_INT) 2.324 - ShowWindow = link_c_proc(user32, "ShowWindow", {C_INT, C_INT}) 2.325 - UpdateWindow = link_c_proc(user32, "UpdateWindow", {C_INT}) 2.326 - GetMessage = link_c_func(user32, "GetMessageA", 2.327 - {C_INT, C_INT, C_INT, C_INT}, C_INT) 2.328 - TranslateMessage = link_c_proc(user32, "TranslateMessage", {C_INT}) 2.329 - DispatchMessage = link_c_proc(user32, "DispatchMessageA", {C_INT}) 2.330 - PlaySound = link_c_proc(winmm, "PlaySound", {C_INT, C_INT, C_INT}) 2.331 - BeginPaint = link_c_func(user32, "BeginPaint", {C_INT, C_POINTER}, C_INT) 2.332 - GetClientRect = link_c_proc(user32, "GetClientRect", {C_INT, C_POINTER}) 2.333 - DrawText = link_c_proc(user32, "DrawTextA", 2.334 - {C_INT, C_INT, C_INT, C_INT, C_INT}) 2.335 - EndPaint = link_c_proc(user32, "EndPaint", {C_INT, C_INT}) 2.336 - PostQuitMessage = link_c_proc(user32, "PostQuitMessage", {C_INT}) 2.337 - DefWindowProc = link_c_func(user32, "DefWindowProcA", 2.338 - {C_INT, C_INT, C_INT, C_INT}, C_INT) 2.339 + end if 2.340 + 2.341 + kernel32 = open_dll( "kernel32.dll") 2.342 + if kernel32 = NULL then 2.343 + not_found("kernel32.dll") 2.344 + end if 2.345 + 2.346 + --new code would use LoadImage 2.347 + LoadIcon = link_c_func(user32, "LoadIconA", {C_HANDLE, C_LPSTR}, C_HANDLE) 2.348 + LoadCursor = link_c_func(user32, "LoadCursorA", {C_HANDLE, C_LPSTR}, C_HANDLE) 2.349 + 2.350 + GetStockObject = link_c_func(gdi32, "GetStockObject", {C_INT}, C_HANDLE) 2.351 + RegisterClassEx = link_c_func(user32, "RegisterClassExA", {C_POINTER}, C_ATOM) 2.352 + CreateWindow = link_c_func(user32, "CreateWindowExA", 2.353 + {C_DWORD, C_LPSTR, C_LPSTR,C_DWORD,C_INT,C_INT,C_INT,C_INT, 2.354 + C_HWND,C_HANDLE,C_HANDLE, C_POINTER}, 2.355 + C_HWND) 2.356 + ShowWindow = link_c_proc(user32, "ShowWindow", {C_HWND, C_INT}) --BOOL 2.357 + UpdateWindow = link_c_proc(user32, "UpdateWindow", {C_HWND}) --BOOL 2.358 + GetMessage = link_c_func(user32, "GetMessageA", 2.359 + {C_LPSTR, C_HWND, C_UINT, C_UINT}, C_BOOL) 2.360 + TranslateMessage = link_c_proc(user32, "TranslateMessage", {C_LPSTR}) --BOOL 2.361 + DispatchMessage = link_c_proc(user32, "DispatchMessageA", {C_LPSTR}) --LRESULT 2.362 + PlaySound = link_c_proc(winmm, "PlaySound", {C_LPSTR, C_HANDLE, C_DWORD}) --BOOL 2.363 + BeginPaint = link_c_func(user32, "BeginPaint", {C_HWND, C_POINTER}, C_HANDLE) 2.364 + GetClientRect = link_c_proc(user32, "GetClientRect", {C_HWND, C_POINTER}) --BOOL 2.365 + DrawText = link_c_proc(user32, "DrawTextA", 2.366 + {C_HANDLE, C_LPSTR, C_INT, C_POINTER, C_UINT}) --INT 2.367 + EndPaint = link_c_proc(user32, "EndPaint", {C_HWND, C_POINTER}) --BOOL 2.368 + PostQuitMessage = link_c_proc(user32, "PostQuitMessage", {C_INT}) 2.369 + DefWindowProc = link_c_func(user32, "DefWindowProcA", 2.370 + {C_HWND, C_UINT, C_WPARAM, C_LPARAM}, C_LRESULT) 2.371 + 2.372 + GetSysColor = link_c_func(user32, "GetSysColor", {C_INT}, C_DWORD) 2.373 + 2.374 + SelectObject = link_c_func(gdi32, "SelectObject", {C_HANDLE, C_HANDLE}, C_HANDLE) 2.375 + SetTextColor = link_c_func(gdi32, "SetTextColor", {C_HANDLE, C_COLORREF}, C_COLORREF) 2.376 + SetBkColor = link_c_func(gdi32, "SetBkColor", {C_HANDLE, C_COLORREF}, C_COLORREF) 2.377 + 2.378 + GetDeviceCaps = link_c_func(gdi32, "GetDeviceCaps", {C_HANDLE, C_INT}, C_INT) 2.379 + CreateFont = link_c_func(gdi32, "CreateFontA", { 2.380 + C_INT, C_INT, C_INT, C_INT, C_INT, C_DWORD, C_DWORD, C_DWORD, 2.381 + C_DWORD, C_DWORD, C_DWORD, C_DWORD, C_DWORD, C_LPSTR 2.382 + }, 2.383 + C_HANDLE) 2.384 + 2.385 + MulDiv = link_c_func( kernel32, "MulDiv", { C_INT, C_INT, C_INT }, C_INT ) 2.386 + 2.387 end procedure 2.388 2.389 link_dll_routines() 2.390 2.391 -atom wav_file, Euphoria, ps, rect 2.392 -wav_file = allocate_string("\\Windows\\Media\\tada.wav") 2.393 -Euphoria = allocate_string("A Plain Vanilla Window using Euphoria!") 2.394 -ps = allocate(64) 2.395 -rect = allocate(16) 2.396 - 2.397 -global function WndProc(atom hwnd, atom iMsg, atom wParam, atom lParam) 2.398 +atom 2.399 + --get_env(media?) 2.400 + wav_file = allocate_string(getenv("Windir")&`\Media\tada.wav`), 2.401 + Euphoria = allocate_string("A Plain Vanilla Window using Euphoria!"), 2.402 + my_title = allocate_string("Euphoria for WINDOWS"), 2.403 + $ 2.404 + 2.405 + --from Mike Duffy Units 2.406 +-- create_font(hdc,"Courier New",12,FW_BOLD,0,0,0) 2.407 + 2.408 +public function create_font(atom hdc, sequence fontname="Veranda", 2.409 + integer points=12, 2.410 + integer weight=0, integer fitalic=0, 2.411 + integer funderline=0, integer fstrikeout=0, atom pandf=0 2.412 + ) 2.413 + atom hfont, lpszFace, ppi, lfheight 2.414 + 2.415 + ppi = c_func(GetDeviceCaps,{hdc,LOGPIXELSY}) 2.416 + lfheight = -c_func( MulDiv, { points, ppi, 72}) 2.417 + lpszFace = allocate_string(fontname, 1) 2.418 + hfont = c_func(CreateFont, 2.419 + {lfheight, -- logical height of font 2.420 + 0, -- logical average character width 2.421 + 0, -- angle of escapement 2.422 + 0, -- base-line orientation angle 2.423 + weight, -- font weight 2.424 + fitalic, -- italic attribute flag 2.425 + funderline, -- underline attribute flag 2.426 + fstrikeout, -- strikeout attribute flag 2.427 + DEFAULT_CHARSET, -- character set identifier 2.428 + OUT_DEFAULT_PRECIS, -- output precision 2.429 + CLIP_DEFAULT_PRECIS, -- clipping precision 2.430 + DEFAULT_QUALITY, -- output quality 2.431 + or_all({DEFAULT_PITCH,FF_DONTCARE,pandf}),-- 0 pitch and family 2.432 + lpszFace -- pointer to typeface name string 2.433 + } 2.434 + ) 2.435 + return hfont 2.436 +end function 2.437 + 2.438 -- callback routine to handle Window class 2.439 - atom hdc 2.440 - integer temp 2.441 - 2.442 - if iMsg = WM_CREATE then 2.443 - c_proc(PlaySound, {wav_file, 2.444 - NULL, 2.445 - or_bits(SND_FILENAME, SND_ASYNC)}) 2.446 - return 0 2.447 - 2.448 - elsif iMsg = WM_PAINT then 2.449 - hdc = c_func(BeginPaint, {hwnd, ps}) 2.450 - c_proc(GetClientRect, {hwnd, rect}) 2.451 - c_proc(DrawText, {hdc, Euphoria, -1, rect, 2.452 - or_all({DT_SINGLELINE, DT_CENTER, DT_VCENTER})}) 2.453 - c_proc(EndPaint, {hwnd, ps}) 2.454 +public function WndProc(atom hwnd, atom iMsg, atom wParam, atom lParam) 2.455 + 2.456 + if iMsg = WM_CREATE then 2.457 + c_proc(PlaySound, {wav_file, 2.458 + NULL, 2.459 + or_bits(SND_FILENAME, SND_ASYNC)}) 2.460 + return 0 2.461 + 2.462 + elsif iMsg = WM_PAINT then 2.463 + atom 2.464 + hdc, 2.465 + oldFont, 2.466 + hCtrlFont, 2.467 + ps = allocate( sizeof(PAINTSTRUCT), 1), 2.468 + rect = allocate( sizeof(RECT), 1) 2.469 + 2.470 + hdc = c_func(BeginPaint, {hwnd, ps}) 2.471 + c_proc(GetClientRect, {hwnd, rect}) 2.472 + hCtrlFont = create_font(hdc,"Verdana",12,FW_BOLD,0,0,0,0) 2.473 + 2.474 + --oldFont = c_func(SelectObject, {hdc, c_func(GetStockObject, {ANSI_VAR_FONT}) }) 2.475 + oldFont = c_func(SelectObject, {hdc, hCtrlFont }) 2.476 + c_func(SetTextColor, {hdc, c_func(GetSysColor, {COLOR_BTNTEXT}) }) 2.477 + c_func(SetBkColor, {hdc, c_func(GetSysColor, {COLOR_BTNFACE}) }) 2.478 + 2.479 + c_proc(DrawText, {hdc, Euphoria, -1, rect, 2.480 + or_all({DT_SINGLELINE, DT_CENTER, DT_VCENTER})}) 2.481 + c_proc(EndPaint, {hwnd, ps}) 2.482 return 0 2.483 2.484 - elsif iMsg = WM_DESTROY then 2.485 - c_proc(PostQuitMessage, {0}) 2.486 - return 0 2.487 + elsif iMsg = WM_DESTROY then 2.488 + c_proc(PostQuitMessage, {0}) 2.489 + return 0 2.490 + end if 2.491 2.492 - end if 2.493 - 2.494 - temp = c_func(DefWindowProc, {hwnd, iMsg, wParam, lParam}) 2.495 - return temp 2.496 + return c_func(DefWindowProc, {hwnd, iMsg, wParam, lParam}) 2.497 end function 2.498 2.499 -atom my_title 2.500 -my_title = allocate_string("Euphoria for WIN32") 2.501 2.502 procedure WinMain() 2.503 --- main routine 2.504 - atom szAppName 2.505 - atom hwnd 2.506 - atom msg 2.507 - atom wndclass 2.508 - atom WndProcAddress 2.509 - atom class 2.510 - integer id 2.511 - atom icon_handle 2.512 +-- main routine 2.513 + atom szAppName 2.514 + atom hwnd 2.515 + atom msg 2.516 + atom wndclass 2.517 + atom WndProcAddress 2.518 + atom class 2.519 + integer id 2.520 + atom icon_handle 2.521 2.522 - wndclass = allocate(SIZE_OF_WNDCLASS) 2.523 - msg = allocate(SIZE_OF_MESSAGE) 2.524 - szAppName = allocate_string("HelloWin") 2.525 + wndclass = allocate( sizeof(WNDCLASSEX), 1) 2.526 + msg = allocate( sizeof(MSG), 1) 2.527 + szAppName = allocate_string("winhello", 1) 2.528 2.529 - id = routine_id("WndProc") 2.530 - if id = -1 then 2.531 - puts(1, "routine_id failed!\n") 2.532 - abort(1) 2.533 - end if 2.534 - WndProcAddress = call_back(id) -- get 32-bit address for callback 2.535 - 2.536 - poke4(wndclass + cbSize, SIZE_OF_WNDCLASS) 2.537 - poke4(wndclass + style, or_bits(CS_HREDRAW, CS_VREDRAW)) 2.538 - poke4(wndclass + lpfnWndProc, WndProcAddress) 2.539 - poke4(wndclass + cbClsExtra, 0) 2.540 - poke4(wndclass + cbWndExtra, 0) 2.541 - poke4(wndclass + hInstance, 0) --hInstance 2.542 + id = routine_id("WndProc") 2.543 + if id = -1 then 2.544 + crash( "routine_id failed!") 2.545 + end if 2.546 + WndProcAddress = call_back(id) -- get address for callback 2.547 + 2.548 + wndclass.WNDCLASSEX.cbSize = sizeof(WNDCLASSEX) 2.549 + wndclass.WNDCLASSEX.style = or_bits(CS_HREDRAW, CS_VREDRAW) 2.550 + wndclass.WNDCLASSEX.lpfnWndProc = WndProcAddress 2.551 + wndclass.WNDCLASSEX.cbClsExtra = 0 2.552 + wndclass.WNDCLASSEX.cbWndExtra = 0 2.553 + wndclass.WNDCLASSEX.hInstance = 0 2.554 2.555 - -- set icon in top-left of window 2.556 - icon_handle = c_func(LoadIcon, {instance(), allocate_string("eui")}) 2.557 - poke4(wndclass + hIcon, icon_handle) 2.558 - poke4(wndclass + hIconSm, icon_handle) 2.559 - 2.560 - -- Wolfgang Fritz observes that you can set an icon 2.561 - -- dynamically using: 2.562 - -- junk = sendMessage(YourWindow, 128, 1, icon_handle) 2.563 - -- where 128 is WM_SETICON 2.564 - 2.565 - poke4(wndclass + hCursor, c_func(LoadCursor, {NULL, IDC_ARROW})) 2.566 - poke4(wndclass + hbrBackground, c_func(GetStockObject, {WHITE_BRUSH})) 2.567 - poke4(wndclass + lpszMenuName, NULL) 2.568 - poke4(wndclass + lpszClassName, szAppName) 2.569 + -- set icon in top-left of window 2.570 + icon_handle = c_func(LoadIcon, {instance(), allocate_string( "eui", 1)}) 2.571 + if icon_handle = 0 then 2.572 + c_proc( xSetLastError, {0} ) 2.573 + icon_handle = c_func(LoadIcon, {NULL, IDI_APPLICATION}) 2.574 + end if 2.575 + wndclass.WNDCLASSEX.hIcon = icon_handle 2.576 + wndclass.WNDCLASSEX.hIconSm = icon_handle 2.577 + 2.578 + -- Wolfgang Fritz observes that you can set an icon 2.579 + -- dynamically using: 2.580 + -- sendMessage(YourWindow, WM_SETICON, 1, icon_handle) 2.581 + -- where WM_SETICON is 128 2.582 + 2.583 + wndclass.WNDCLASSEX.hCursor = c_func(LoadCursor, {NULL, IDC_ARROW}) 2.584 + wndclass.WNDCLASSEX.hbrBackground = c_func(GetStockObject, {WHITE_BRUSH}) 2.585 + wndclass.WNDCLASSEX.lpszMenuName = NULL 2.586 + wndclass.WNDCLASSEX.lpszClassName = szAppName 2.587 2.588 - class = c_func(RegisterClassEx, {wndclass}) 2.589 - if class = 0 then 2.590 - puts(1, "Couldn't register class\n") 2.591 - abort(1) 2.592 - end if 2.593 - hwnd = c_func(CreateWindow, { 2.594 - 0, -- extended style 2.595 - szAppName, -- window class name 2.596 - my_title, -- window caption 2.597 - WS_OVERLAPPEDWINDOW, -- window style 2.598 - CW_USEDEFAULT, -- initial x position 2.599 - CW_USEDEFAULT, -- initial y position 2.600 - CW_USEDEFAULT, -- initial x size 2.601 - CW_USEDEFAULT, -- initial y size 2.602 - NULL, -- parent window handle 2.603 - NULL, -- window menu handle 2.604 - 0 , --hInstance // program instance handle 2.605 - NULL}) -- creation parameters 2.606 - if hwnd = 0 then 2.607 - puts(1, "Couldn't CreateWindow\n") 2.608 - abort(1) 2.609 - end if 2.610 - c_proc(ShowWindow, {hwnd, SW_SHOWNORMAL}) 2.611 - c_proc(UpdateWindow, {hwnd}) 2.612 + class = c_func(RegisterClassEx, {wndclass}) 2.613 + if class = 0 then 2.614 + crash("could not register class") 2.615 + end if 2.616 + hwnd = c_func(CreateWindow, { 2.617 + 0, -- extended style 2.618 + szAppName, -- window class name 2.619 + my_title, -- window caption 2.620 + WS_OVERLAPPEDWINDOW, -- window style 2.621 + CW_USEDEFAULT, -- initial x position 2.622 + CW_USEDEFAULT, -- initial y position 2.623 + CW_USEDEFAULT, -- initial x size 2.624 + CW_USEDEFAULT, -- initial y size 2.625 + NULL, -- parent window handle 2.626 + NULL, -- window menu handle 2.627 + 0 , --hInstance // program instance handle 2.628 + NULL}) -- creation parameters 2.629 + if hwnd = 0 then 2.630 + crash("Couldn't CreateWindow") 2.631 + end if 2.632 + c_proc(ShowWindow, {hwnd, SW_SHOWNORMAL}) 2.633 + c_proc(UpdateWindow, {hwnd}) 2.634 2.635 - while c_func(GetMessage, {msg, NULL, 0, 0}) do 2.636 - c_proc(TranslateMessage, {msg}) 2.637 - c_proc(DispatchMessage, {msg}) 2.638 - end while 2.639 + while c_func(GetMessage, {msg, NULL, 0, 0}) do 2.640 + c_proc(TranslateMessage, {msg}) 2.641 + c_proc(DispatchMessage, {msg}) 2.642 + end while 2.643 end procedure 2.644 2.645 WinMain() 2.646 -
3.1 --- a/docs/refman_2.txt Mon Dec 19 23:19:58 2011 -0300 3.2 +++ b/docs/refman_2.txt Wed Dec 21 16:45:49 2011 -0300 3.3 @@ -4126,3 +4126,436 @@ 3.4 ##with inline## takes an optional integer parameter that defines the largest 3.5 routine (by size of IL code) that will be considered for inlining. The default 3.6 is 30. 3.7 + 3.8 +%%output=lang_memstruct 3.9 +== Memory Structures == 3.10 +@[memorystructures|] 3.11 +:<<LEVELTOC level=2 depth=4>> 3.12 + 3.13 +=== Introduction 3.14 + 3.15 +Writing Euphoria code to interact with the operating system or external libraries often 3.16 +requires communicating via data structures stored in memory. In addition to using 3.17 +peeks and pokes to read and write to memory locations, Euphoria programmers can also 3.18 +define structures that can be used to more easily read and write values from and into 3.19 +memory. 3.20 + 3.21 +The conventions used are similar to those found in the C programming language, since 3.22 +that's the way the most commonly encountered structures are defined and meant to be 3.23 +used. This is meant to provide a familiar syntax to those who already know C, and 3.24 +also to make it easy to define and use memory structures. 3.25 + 3.26 +=== Basic Syntax 3.27 + 3.28 +There are two keywords for defining memory structures: memstruct and memunion. 3.29 +They are similar, except a memstruct is a way to define a data structure that 3.30 +may contain many different, distinct elements, while a memunion (just like a union in C) 3.31 +is a way to refer to the same locations in memory in different ways (e.g., either as an 3.32 +integer or as a floating point number). 3.33 + 3.34 +Within a memstruct or memunion, different members are defined using names for data types 3.35 +along with some data type modifiers. 3.36 + 3.37 +It is also possible to declare fixed-length arrays of a member by adding the element count 3.38 +inside square brackets after the member name. 3.39 + 3.40 +==== Assigning memstruct values 3.41 + 3.42 +Assigning a value to a memstruct is an alternative to using one of the ##[[:poke]]## built in 3.43 +procedures. The big advantage to using a ##[[:memstruct]]## over ##[[:poke]]## is that 3.44 +euphoria handles data conversion and the calculation of offsets. 3.45 + 3.46 +The syntax for assigning a value to memory is the pointer to the memory, 3.47 +followed by a dot, then the name of the memstruct, optionally followed by a dot and 3.48 +then a member of the memstruct. If that member is an array and you wish to reference 3.49 +a specific array element, then a 1-based index inside square brackets is also required. 3.50 + 3.51 +<eucode> 3.52 +memstruct POINT 3.53 + int x 3.54 + int y 3.55 +end memstruct 3.56 + 3.57 +memstruct BUFFER 3.58 + char name[12] -- 'name' uses 12 bytes of space. 3.59 + int next_element 3.60 + int element[200] -- element uses 200 * 4 = 800 bytes of space. 3.61 +end memstruct 3.62 + 3.63 +atom point = allocate( sizeof( POINT ) ) 3.64 +point.POINT.x = 1 3.65 +point.POINT.y = 2 3.66 + 3.67 +atom buf = allocate( sizeof( BUFFER ) ) 3.68 + 3.69 +buf.BUFFER.name = "testname" -- assigns first 8 byte to string and zeros the remainder. 3.70 +buf.BUFFER.element[1] = 543 3.71 +buf.BUFFER.element[2] = 210 3.72 +buf.BUFFER.element[3] = 987 3.73 +buf.BUFFER.next_element = 4 3.74 + 3.75 +</eucode> 3.76 + 3.77 +When a member is itself a memstruct, the dot notation may be continued to access the 3.78 +nested members. Continuing the ##POINT## example from above: 3.79 + 3.80 +<eucode> 3.81 +memstruct RECT 3.82 + POINT upper_left 3.83 + POINT lower_right 3.84 +end memstruct 3.85 + 3.86 +atom rect = allocate( sizeof( RECT ) ) 3.87 +rect.RECT.upper_left.x = 0 3.88 +rect.RECT.lower_right.x = 5 3.89 +</eucode> 3.90 + 3.91 +Additionally, you can assign to multiple members of a memstruct at a time. When the last 3.92 +referenced member of the left hand side is itself a memstruct, the right hand side will 3.93 +be assigned to the respective members of the memstruct: 3.94 + 3.95 +<eucode> 3.96 +point.POINT = { 3, 6 } 3.97 +rect.RECT.upper_left = { 0, 0 } 3.98 +</eucode> 3.99 + 3.100 +If an atom is passed on the right hand side, it is treated as a single element sequence. 3.101 +If the sequence has more elements than the memstruct has members, the extra elements are 3.102 +ignored. If the sequence has fewer elements than the memstruct has members, then the 3.103 +additional members are set to zero. This provides for a simple way to zero out all 3.104 +elements: 3.105 + 3.106 +<eucode> 3.107 +point.POINT = {3} -- x = 3, y = 0 3.108 +point.POINT = {} -- x = 0, y = 0 3.109 +</eucode> 3.110 + 3.111 +Note that a ##[[:memunion]]## is treated as ##unsigned char## data. 3.112 + 3.113 +==== Reading memstruct values 3.114 + 3.115 +Reading from a memstruct is an alternative to using one of the ##peek## built in 3.116 +procedures. The big advantage to using a ##[[:memstruct]]## over ##[[:peek]]## is that 3.117 +euphoria handles data conversion and the calculation of offsets. 3.118 + 3.119 +The syntax is the same as for [[:Assigning memstruct values]], except that it is applied 3.120 +to the right hand side of an expression. 3.121 + 3.122 +==== Reading and assigning with pointers 3.123 + 3.124 +A memstruct member that is itself a pointer has an additional way to be used. The normal 3.125 +assignment and reading operations deal with the value of the pointer itself. To access 3.126 +the value to which the pointer points, use an additional dot, then an asterisk: 3.127 + 3.128 +<eucode> 3.129 +memstruct PTR_TO_INT 3.130 + pointer int a 3.131 +end memstruct 3.132 + 3.133 +atom ptr = allocate( sizeof( PTR_TO_INT ) ) 3.134 +ptr.PTR_TO_INT.a = allocate( sizeof( int ) ) 3.135 + 3.136 +ptr.PTR_TO_INT.a.* = 5 3.137 +ptr.PTR_TO_INT.a.* += 5 3.138 + 3.139 +? ptr.PTR_TO_INT.a.* -- prints 10 3.140 +</eucode> 3.141 + 3.142 +@[memstruct|] 3.143 +==== memstruct 3.144 + 3.145 +##memstruct## is used to declare a memory based structure to be used by a Euphoria program. 3.146 +The format is similar to other declarations: 3.147 +<eucode> 3.148 +memstruct foo 3.149 + int a 3.150 + unsigned int b 3.151 + pointer int c 3.152 +end foo 3.153 +</eucode> 3.154 + 3.155 +Normal scope rules apply to ##memstruct## definitions, and so they can be local, ##export##, 3.156 +##public## or ##global##. The members are laid out in memory sequentially, though 3.157 +based on their sizes, Euphoria may add some space in between members, just like a 3.158 +C compiler would. 3.159 + 3.160 +The size of a ##memstruct## may be determined at runtime using ##[[:sizeof]]()##. 3.161 +It is the sum of the sizes of its members. 3.162 + 3.163 +##memstructs## may contain other ##memstructs## or pointers to other ##memstructs##. 3.164 + 3.165 +@[memunion|] 3.166 +==== memunion 3.167 + 3.168 +A ##memunion## is like a ##[[:memstruct]]##, except that the various data members 3.169 +of a ##memunion## are all located at offset zero, which means that they all start 3.170 +at the same RAM address. A ##memunion##, like a union in C, 3.171 +provides different ways to interpret the same location in memory. 3.172 + 3.173 +<eucode> 3.174 +memunion conversion 3.175 + int i 3.176 + float f 3.177 + double d 3.178 +end memunion 3.179 +</eucode> 3.180 + 3.181 +The size of a ##memunion## may be determined at runtime using ##[[:sizeof]]()##. 3.182 +It is the size of the largest member. 3.183 + 3.184 +@[memtype|] 3.185 +==== memtype 3.186 + 3.187 +A ##memtype## is an alias of another type that can be used in a ##[[:memstruct]]## 3.188 +or a ##[[:memunion]]##. They are used similarly to how ##typedef##s are used in C, 3.189 +and can make porting C structs easier. Especially on Windows, it is common for 3.190 +many common struct declarations to be typedefs. The euphoria programmer can 3.191 +therefore create a ##memtype## and use the same terminology as the native structs. 3.192 + 3.193 +<eucode> 3.194 +memtype object as HANDLE 3.195 + 3.196 +memtype int as BOOL 3.197 +</eucode> 3.198 + 3.199 + 3.200 +@[char|] 3.201 +==== char 3.202 + 3.203 +A ##char## is a data type that is 1 byte long. Elements of type ##char## are considered 3.204 +to be ##[[:signed]]## by default. The range of a ##signed char## is -128 to 127. An 3.205 +##unsigned char## has a range of 0 - 255. They can only be declared inside of a 3.206 +##[[:memstruct]]## or ##[[:memunion]]##. 3.207 + 3.208 +<eucode> 3.209 +memstruct char_types 3.210 + char c -- signed by default, -128 - 127 3.211 + unsigned char uc -- 0 - 255 3.212 + signed char sc -- -128 - 127 3.213 +end memstruct 3.214 +</eucode> 3.215 + 3.216 + 3.217 +@[short|] 3.218 +==== short 3.219 +A ##short## is a data type that is 2 bytes long. Elements of type ##short## are considered 3.220 +to be ##[[:signed]]## by default. The range of a ##signed short## is −32,768 to 32,767. An 3.221 +##unsigned short## has a range of 0 - 65,535. They can only be declared inside of a 3.222 +##[[:memstruct]]## or ##[[:memunion]]##. 3.223 + 3.224 +<eucode> 3.225 +memstruct char_types 3.226 + short s -- signed by default, −32,768 to 32,767 3.227 + unsigned short us -- −32,768 to 32,767 3.228 + signed short ss -- −32,768 to 32,767 3.229 +end memstruct 3.230 +</eucode> 3.231 + 3.232 +@[int|] 3.233 +==== int 3.234 + 3.235 +An ##int## is a data type that is 4 bytes long. Elements of type ##int## are considered 3.236 +to be ##[[:signed]]## by default. The range of a ##signed int## is −2,147,483,648 to 3.237 +2,147,483,647. An ##unsigned int## has a range of 0 - 4,294,967,295. They can only be 3.238 +declared inside of a ##[[:memstruct]]## or ##[[:memunion]]##. 3.239 + 3.240 +<eucode> 3.241 +memstruct char_types 3.242 + int i -- signed by default, −2,147,483,648 to 2,147,483,647 3.243 + unsigned int ui -- 0 - 4,294,967,295 3.244 + signed int si -- −2,147,483,648 to 2,147,483,647 3.245 +end memstruct 3.246 +</eucode> 3.247 + 3.248 +@[long|] 3.249 +==== long 3.250 + 3.251 +A ##long## (can also be ##long int##) varies in size based on the platform. On Windows 3.252 +and 32-bit Unix like operating systems, a ##long## is 4 bytes, or the same size as an 3.253 +##[[:int]]##. On 64-bit Unix-like operating systems, a ##long## is 64-bits, or the 3.254 +same size as a ##[[:long long]]##. 3.255 + 3.256 + 3.257 +@[long long|] 3.258 +==== long long 3.259 + 3.260 +A ##long long## (can also be ##long long int##) is an integer that is 8 bytes (64-bits) in size. 3.261 +By default, it is signed (−9,223,372,036,854,775,808 to 9,223,372,036,854,775,807). An ##unsigned 3.262 +long long## varies from 0 to 18,446,744,073,709,551,615. 3.263 + 3.264 + 3.265 +@[object (memstruct)|] 3.266 +==== object (memstruct) 3.267 + 3.268 +An ##object##, in a ##[[:memstruct]]## or ##[[:memunion]]##, is an integer the same size as a Euphoria 3.269 +object, and is also the same size as a pointer. By default, it is signed, but can be declared ##unsigned##. 3.270 + 3.271 +@[float|] 3.272 +==== float 3.273 + 3.274 +A ##float## is a 32-bit floating point number, just like those used by ##[[:atom_to_float32]]## 3.275 +and ##[[:float32_to_atom]]##. 3.276 + 3.277 +@[double|] 3.278 +==== double 3.279 + 3.280 +A ##double## is a 64-bit floating point number, just like those used by ##[[:atom_to_float64]]## 3.281 +and ##[[:float64_to_atom]]##. This is the size of floating point numbers used by 32-bit 3.282 +Euphoria. 3.283 + 3.284 +@[long double|] 3.285 +==== long double 3.286 + 3.287 +A ##long double## is an 80-bit floating point number, just like those used by ##[[:atom_to_float80]]## 3.288 +and ##[[:float80_to_atom]]##. This is the size of floating point numbers used by 64-bit 3.289 +Euphoria. Although they only use 80 bits, in ##[[:memstructs]]## they require 16 bytes of storage 3.290 +for alignment purposes. 3.291 + 3.292 + 3.293 +@[eudouble|] 3.294 +==== eudouble 3.295 + 3.296 +A ##eudouble## is a platform independent floating point data type. On 32-bit Euphoria, a ##eudouble## 3.297 +is the same size (64-bits) as a ##double##. On 64-bit Euphoria, it is 80 bits, the same size 3.298 +as a ##long double##. 3.299 + 3.300 +@[pointer|] 3.301 +==== pointer 3.302 + 3.303 +Data members may have the ##pointer## modifier prepended to their declaration. This signifies that 3.304 +the ##memstruct## contains a pointer to that type of element, rather than the element itself. 3.305 + 3.306 +@[signed|] 3.307 +==== signed 3.308 + 3.309 +Integer data types may be signed or unsiged. The default is to be signed, but this can be made 3.310 +explicit by using the ##signed## modifier. 3.311 + 3.312 +@[unsigned|] 3.313 +==== unsigned 3.314 + 3.315 +Integer data types may be signed or unsiged. The default is to be signed, but to use an ##unsigned## 3.316 +integer type, use the ##unsigned## modifier. 3.317 + 3.318 +=== Using memstructs 3.319 + 3.320 +To use a ##[[:memstruct]]## requires a pointer to the memory where the structure is stored. 3.321 +This can be created by ##[[:allocate]]()##, or as the result of a call to an external library. 3.322 +No type information is ever stored with the pointer. Instead, the memory may be manipulated 3.323 +using a dot notation, where the name of the ##[[:memstruct]]## follows the pointer, and 3.324 +the names of data elements 3.325 + 3.326 +Example: 3.327 +<eucode> 3.328 +include std/machine.e 3.329 + 3.330 +memstruct point 3.331 + int x 3.332 + int y 3.333 +end memstruct 3.334 + 3.335 +memstruct rect 3.336 + point upper_left 3.337 + point lower_right 3.338 +end memstruct 3.339 + 3.340 +atom my_rect = allocate( sizeof( rect ) ) 3.341 + 3.342 +my_rect.rect.upper_left.x = 50 3.343 +my_rect.rect.upper_left.y = 100 3.344 + 3.345 +my_rect.rect.lower_right.x = 125 3.346 +my_rect.rect.lower_right.y = 150 3.347 + 3.348 +? my_rect.rect.lower_right.x -- outputs 125 3.349 +</eucode> 3.350 +It is possible to //abuse// the memstruct functionality because there is no type 3.351 +information associated with the address pointer. For example ... 3.352 + 3.353 +<eucode> 3.354 +include std/machine.e 3.355 + 3.356 +memstruct point 3.357 + int x 3.358 + int y 3.359 +end memstruct 3.360 + 3.361 +memstruct rect 3.362 + point upper_left 3.363 + point lower_right 3.364 +end memstruct 3.365 + 3.366 +atom my_rect = allocate( sizeof( rect ) ) 3.367 + 3.368 +my_rect.rect.upper_left.x = 20 3.369 +my_rect.rect.upper_left.y = 200 3.370 +? my_rect.rect.upper_left.x -- outputs 20 3.371 + 3.372 +my_rect.point.x = 50 3.373 +my_rect.point.y = 100 3.374 + 3.375 +? my_rect.rect.upper_left.x -- outputs 50 3.376 +</eucode> 3.377 + 3.378 + 3.379 +@[addressof|] 3.380 +==== addressof 3.381 + 3.382 +A function that returns the address of a memstruct member. You must supply the 3.383 +variable that contains the starting RAM address, the memstruct name, and 3.384 +member name sing the dot notation described above. 3.385 + 3.386 +Example: 3.387 +<eucode> 3.388 +include std/machine.e 3.389 + 3.390 +memstruct point 3.391 + int x 3.392 + int y 3.393 +end memstruct 3.394 + 3.395 +memstruct rect 3.396 + point upper_left 3.397 + point lower_right 3.398 +end memstruct 3.399 + 3.400 +atom pa = allocate( sizeof( point ) ) 3.401 + 3.402 +? addressof(pa.point.x) = pa -- outputs 1 (true) 3.403 +? addressof(pa.point.y) = pa + 4 -- outputs 1 (true) 3.404 + 3.405 +? addressof(pa.rect.lower_right.y) = pa + 12 -- outputs 1 (true) 3.406 + 3.407 +</eucode> 3.408 + 3.409 +@[offsetof|] 3.410 +==== offsetof 3.411 + 3.412 +Returns the offset in bytes of a member inside of its memstruct. You can optionally 3.413 +omit the address pointer variable when calling this, just the memstruct name 3.414 +and member is required. 3.415 + 3.416 +Example: 3.417 +<eucode> 3.418 +include std/machine.e 3.419 + 3.420 +memstruct point 3.421 + int x 3.422 + int y 3.423 +end memstruct 3.424 + 3.425 +memstruct rect 3.426 + point upper_left 3.427 + point lower_right 3.428 +end memstruct 3.429 + 3.430 +atom pa = allocate( sizeof( point ) ) 3.431 + 3.432 +? offsetof(point.x) -- outputs 0 3.433 +? offsetof(pa.point.x) -- outputs 0 3.434 +? offsetof(point.y) -- outputs 4 3.435 +? offsetof(pa.point.y) -- outputs 4 3.436 + 3.437 +? offsetof(rect.lower_right.y) -- outputs 12 3.438 + 3.439 +</eucode>
4.1 --- a/docs/release/4.1.0.txt Mon Dec 19 23:19:58 2011 -0300 4.2 +++ b/docs/release/4.1.0.txt Wed Dec 21 16:45:49 2011 -0300 4.3 @@ -26,3 +26,6 @@ 4.4 * -cc-prefix option for translator 4.5 * Can [[assign to multiple variables -> :Multiple Assignment]] with one statement using sequence semantics. 4.6 * Use ##?## to stand in for default parameters. 4.7 +* [[ticket:735]] The number of lines to be used in ctrace.out by ##trace(3)## can be configured 4.8 + using ##-trace-lines n## command line switch. See [[Command line switches -> :command line switches]] 4.9 + for more information. 4.10 \ No newline at end of file
5.1 --- a/docs/using_euphoria.txt Mon Dec 19 23:19:58 2011 -0300 5.2 +++ b/docs/using_euphoria.txt Wed Dec 21 16:45:49 2011 -0300 5.3 @@ -541,6 +541,10 @@ 5.4 parameter which enables many editor/IDE programs to test the syntax of your 5.5 Euphoria source in real time. 5.6 5.7 +; ##-TRACE-LINES n## (all) 5.8 +: Changes the number of lines that will be used in ctrace.out for lines traced 5.9 + under ##trace(3)##. The default is 500. 5.10 + 5.11 ; ##-VERSION## (all) 5.12 : Displays the version of euphoria that is running. 5.13
6.1 --- a/include/euphoria.h Mon Dec 19 23:19:58 2011 -0300 6.2 +++ b/include/euphoria.h Wed Dec 21 16:45:49 2011 -0300 6.3 @@ -329,7 +329,8 @@ 6.4 extern IFILE last_w_file_ptr; 6.5 extern object last_r_file_no; 6.6 extern IFILE last_r_file_ptr; 6.7 -extern int insert_pos;; 6.8 +extern int insert_pos; 6.9 +extern int trace_lines; 6.10 6.11 object find_from(object,object,object); 6.12 object e_match_from(object aobj, object bobj, object c);
7.1 --- a/include/euphoria/debug/debug.e Mon Dec 19 23:19:58 2011 -0300 7.2 +++ b/include/euphoria/debug/debug.e Wed Dec 21 16:45:49 2011 -0300 7.3 @@ -2,7 +2,6 @@ 7.4 7.5 include std/dll.e 7.6 include std/machine.e 7.7 -include euphoria/symstruct.e 7.8 7.9 without trace 7.10 7.11 @@ -83,6 +82,59 @@ 7.12 return machine_func( M_CALL_STACK, {} ) 7.13 end function 7.14 7.15 +public memstruct Var 7.16 + pointer symtab_entry declared_in 7.17 +end memstruct 7.18 + 7.19 +public memstruct Block 7.20 + unsigned int first_line 7.21 + unsigned int last_line 7.22 +end memstruct 7.23 + 7.24 +public memstruct private_block 7.25 + int task_number 7.26 + pointer private_block next 7.27 + object block[2] 7.28 +end memstruct 7.29 + 7.30 +public memstruct Subp 7.31 + pointer object code 7.32 + pointer symtab_entry temps 7.33 + pointer private_block saved_privates 7.34 + pointer object block 7.35 + pointer int linetab 7.36 + unsigned int firstline 7.37 + unsigned int num_args 7.38 + int resident_task 7.39 + unsigned int stack_space 7.40 +end memstruct 7.41 + 7.42 +public memunion U 7.43 + Var var 7.44 + Subp subp 7.45 + Block block 7.46 +end memunion 7.47 + 7.48 +public memstruct symtab_entry 7.49 + object obj 7.50 + pointer symtab_entry next 7.51 + pointer symtab_entry next_in_block 7.52 + char mode 7.53 + char scope 7.54 + unsigned char file_no 7.55 + unsigned char dummy 7.56 + int token 7.57 + pointer char name 7.58 + U u 7.59 +end memstruct 7.60 + 7.61 +public memstruct source_line 7.62 + pointer char src 7.63 + short line 7.64 + char file_no 7.65 + char options 7.66 +end memstruct 7.67 + 7.68 7.69 atom 7.70 symbol_table = 0, 7.71 @@ -318,27 +370,27 @@ 7.72 end function 7.73 7.74 public function get_name( atom sym ) 7.75 - return peek_string( peek_pointer( sym + ST_NAME ) ) 7.76 + return peek_string( sym.symtab_entry.name ) 7.77 end function 7.78 7.79 -public function get_source( integer line ) 7.80 - return peek_string( peek_pointer( slist + SL_SIZE * line + SL_SRC ) ) 7.81 +public function get_source( integer src_line ) 7.82 + return peek_string( slist.source_line[src_line].src ) 7.83 end function 7.84 7.85 public function get_file_no( integer line ) 7.86 - return peek( slist + line * SL_SIZE + SL_FILE_NO ) 7.87 + return slist.source_line[line].file_no 7.88 end function 7.89 7.90 public function get_file_name( integer file_no ) 7.91 - return peek_string( peek_pointer( file_name_ptr + sizeof( C_POINTER ) * file_no ) ) 7.92 + return peek_string( file_name_ptr + sizeof( pointer ) * file_no ) 7.93 end function 7.94 7.95 -public function get_file_line( integer line ) 7.96 - return peek2u( slist + line * SL_SIZE + SL_LINE ) 7.97 +public function get_file_line( integer line_no ) 7.98 + return slist.source_line[line_no].line 7.99 end function 7.100 7.101 public function get_next( atom sym ) 7.102 - return peek_pointer( sym + ST_NEXT ) 7.103 + return sym.symtab_entry.next 7.104 end function 7.105 7.106 public function is_variable( atom sym_ptr ) 7.107 @@ -346,16 +398,16 @@ 7.108 return 0 7.109 end if 7.110 7.111 - return -100 = peek4s( sym_ptr + ST_TOKEN ) 7.112 + return -100 = sym_ptr.symtab_entry.token 7.113 end function 7.114 7.115 public function get_parameter_syms( atom rtn_sym ) 7.116 - integer param_count = peek4u( rtn_sym + ST_NUM_ARGS ) 7.117 + integer param_count = rtn_sym.symtab_entry.u.subp.num_args 7.118 sequence syms = repeat( 0, param_count ) 7.119 - atom next_sym = peek_pointer( rtn_sym + ST_NEXT ) 7.120 + atom next_sym = rtn_sym.symtab_entry.next 7.121 for i = 1 to param_count do 7.122 - while peek( next_sym + ST_SCOPE ) != 3 do -- SC_PRIVATE = 3 7.123 - next_sym = peek_pointer( next_sym + ST_NEXT ) 7.124 + while next_sym.symtab_entry.scope != 3 do -- SC_PRIVATE = 3 7.125 + next_sym = next_sym.symtab_entry.next 7.126 end while 7.127 syms[i] = next_sym 7.128 end for
8.1 --- a/include/euphoria/keywords.e Mon Dec 19 23:19:58 2011 -0300 8.2 +++ b/include/euphoria/keywords.e Wed Dec 21 16:45:49 2011 -0300 8.3 @@ -25,6 +25,7 @@ 8.4 "continue", 8.5 "deprecate", 8.6 "do", 8.7 + "double", 8.8 "else", 8.9 "elsedef", 8.10 "elsif", 8.11 @@ -35,6 +36,7 @@ 8.12 "exit", 8.13 "export", 8.14 "fallthru", 8.15 + "float", 8.16 "for", 8.17 "function", 8.18 "global", 8.19 @@ -42,21 +44,29 @@ 8.20 "if", 8.21 "ifdef", 8.22 "include", 8.23 + "int", 8.24 "label", 8.25 + "long", 8.26 "loop", 8.27 + "memstruct", 8.28 + "memtype", 8.29 + "memunion", 8.30 "namespace", 8.31 "not", 8.32 "or", 8.33 "override", 8.34 + "pointer", 8.35 "procedure", 8.36 "public", 8.37 "retry", 8.38 "return", 8.39 "routine", 8.40 + "signed", 8.41 "switch", 8.42 "then", 8.43 "to", 8.44 "type", 8.45 + "unsigned", 8.46 "until", 8.47 "while", 8.48 "with",
9.1 --- a/include/euphoria/symstruct.e Mon Dec 19 23:19:58 2011 -0300 9.2 +++ b/include/euphoria/symstruct.e Wed Dec 21 16:45:49 2011 -0300 9.3 @@ -28,6 +28,16 @@ 9.4 ST_FIRST_LINE = offset( C_INT, ST_DECLARED_IN ), -- 24, 9.5 ST_LAST_LINE = offset( C_INT ), -- 28, 9.6 9.7 + -- memstruct: 9.8 + ST_MEM_NEXT = offset( C_POINTER, ST_DECLARED_IN ), 9.9 + ST_MEM_STRUCT = offset( C_POINTER ), 9.10 + ST_MEM_PARENT = offset( C_POINTER ), 9.11 + ST_MEM_SIZE = offset( C_INT ), 9.12 + ST_MEM_OFFSET = offset( C_INT ), 9.13 + ST_MEM_ARRAY = offset( C_INT ), 9.14 + ST_MEM_SIGNED = offset( C_CHAR ), 9.15 + ST_MEM_POINTER = offset( C_CHAR ), 9.16 + 9.17 -- routine: 9.18 ST_CODE = offset( C_POINTER, ST_DECLARED_IN ), -- 24, 9.19 ST_TEMPS = offset( C_POINTER ), -- 36,
10.1 --- a/include/euphoria/tokenize.e Mon Dec 19 23:19:58 2011 -0300 10.2 +++ b/include/euphoria/tokenize.e Wed Dec 21 16:45:49 2011 -0300 10.3 @@ -1020,7 +1020,7 @@ 10.4 Token[TDATA] &= Look 10.5 10.6 scan_char(state) 10.7 - else 10.8 + elsif find( Look, "0123456789" ) then 10.9 -- .number 10.10 Token[TTYPE] = T_NUMBER 10.11 Token[TDATA] = scan_fraction(0, state) 10.12 @@ -1038,6 +1038,9 @@ 10.13 Token[TDATA] = sprintf("%g",{Token[TDATA]}) 10.14 end if 10.15 end if 10.16 + else 10.17 + -- memstruct 10.18 + scan_identifier( state ) 10.19 end if 10.20 10.21 elsif (Look = '-') and (Token[TTYPE] = T_MINUS) then
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/include/std/memstruct/windows.e Wed Dec 21 16:45:49 2011 -0300 11.3 @@ -0,0 +1,318 @@ 11.4 +--**** 11.5 +-- == Common Windows Memstructs 11.6 +-- 11.7 +-- <<LEVELTOC level=2 depth=5>> 11.8 +-- 11.9 + 11.10 +--**** 11.11 +-- === Windows Type constants for structs 11.12 + 11.13 +public memtype 11.14 + char as BYTE, 11.15 + int as BOOL, 11.16 + int as INT, 11.17 + unsigned int as UINT, 11.18 + long as LONG, 11.19 + unsigned long as ULONG, 11.20 + double as DOUBLE, 11.21 + short as WORD, 11.22 + long as DWORD, 11.23 + object as HANDLE, 11.24 + object as HWND, 11.25 + object as LPSTR, 11.26 + object as LPTSTR, 11.27 + object as WNDPROC, 11.28 + object as WPARAM, 11.29 + object as LPARAM, 11.30 + object as HINSTANCE, 11.31 + object as LPCSTR, 11.32 + object as LPCTSTR, 11.33 + object as LPOFNHOOKPROC, 11.34 + object as BFFCALLBACK, 11.35 + unsigned short as USHORT, 11.36 + object as LPCCHOOKPROC, 11.37 + long as COLORREF, 11.38 + object as INT_PTR, 11.39 + object as UINT_PTR, 11.40 + char as TCHAR, 11.41 + object as HICON, 11.42 + object as HTREEITEM, 11.43 + object as LPFRHOOKPROC, 11.44 + $ 11.45 + 11.46 +--**** 11.47 +-- === Windows structures 11.48 + 11.49 +public memstruct WNDCLASSEX 11.50 + UINT cbSize 11.51 + UINT style 11.52 + WNDPROC lpfnWndProc --WNDPROC 11.53 + INT cbClsExtra 11.54 + INT cbWndExtra 11.55 + HANDLE hInstance --HINSTANCE 11.56 + HANDLE hIcon --HICON 11.57 + HANDLE hCursor --HCURSOR 11.58 + HANDLE hbrBackground --HBRUSH 11.59 + LPSTR lpszMenuName --LPCSTR 11.60 + LPSTR lpszClassName --LPCSTR 11.61 + HANDLE hIconSm --HICON 11.62 +end memstruct 11.63 + 11.64 +public memstruct POINT 11.65 + LONG x 11.66 + LONG y 11.67 +end memstruct 11.68 + 11.69 +public memstruct RECT 11.70 + LONG left 11.71 + LONG top 11.72 + LONG right 11.73 + LONG bottom 11.74 +end memstruct 11.75 + 11.76 +public memstruct PAINTSTRUCT 11.77 + HANDLE hdc --HDC 11.78 + BOOL fErase 11.79 + RECT rcPaint --RECT 11.80 + BOOL fRestore 11.81 + BOOL fIncUpdate 11.82 + BYTE rgbReserved[32] --BYTE,32 11.83 +end memstruct 11.84 + 11.85 +public memstruct MSG 11.86 + HWND hwnd 11.87 + UINT message 11.88 + WPARAM wParam 11.89 + LPARAM lParam 11.90 + DWORD time 11.91 + POINT pt 11.92 +end memstruct 11.93 + 11.94 +public memstruct NMHDR 11.95 + HWND hwndFrom 11.96 + UINT_PTR idFrom 11.97 + UINT code 11.98 +end memstruct 11.99 + 11.100 +public memstruct LVCOLUMN 11.101 + UINT mask 11.102 + int fmt 11.103 + int cx 11.104 + LPTSTR pszText 11.105 + int cchTextMax 11.106 + int iSubItem 11.107 + int iImage 11.108 + int iOrder 11.109 + int cxMin 11.110 + int cxDefault 11.111 + int cxIdeal 11.112 +end memstruct 11.113 + 11.114 +public memstruct LVITEM 11.115 + UINT mask 11.116 + int iItem 11.117 + int iSubItem 11.118 + UINT state 11.119 + UINT stateMask 11.120 + LPTSTR pszText 11.121 + int cchTextMax 11.122 + int iImage 11.123 + object lParam 11.124 +-- #if (_WIN32_IE >= 0x0300) 11.125 + int iIndent 11.126 +-- #endif 11.127 +-- #if (_WIN32_WINNT >= 0x0501) 11.128 + int iGroupId 11.129 + UINT cColumns 11.130 + UINT puColumns 11.131 +-- #endif 11.132 +-- #if (_WIN32_WINNT >= 0x0600) 11.133 + int piColFmt 11.134 + int iGroup 11.135 +end memstruct 11.136 + 11.137 +public memstruct LV_DISPINFO 11.138 + NMHDR hdr 11.139 + LVITEM item 11.140 +end memstruct 11.141 + 11.142 +public memstruct OPENFILENAME 11.143 + DWORD lStructSize 11.144 + HWND hwndOwner 11.145 + HINSTANCE hInstance 11.146 + LPCTSTR lpstrFilter 11.147 + LPTSTR lpstrCustomFilter 11.148 + DWORD nMaxCustFilter 11.149 + DWORD nFilterIndex 11.150 + LPTSTR lpstrFile 11.151 + DWORD nMaxFile 11.152 + LPTSTR lpstrFileTitle 11.153 + DWORD nMaxFileTitle 11.154 + LPCTSTR lpstrInitialDir 11.155 + LPCTSTR lpstrTitle 11.156 + DWORD Flags 11.157 + WORD nFileOffset 11.158 + WORD nFileExtension 11.159 + LPCTSTR lpstrDefExt 11.160 + LPARAM lCustData 11.161 + LPOFNHOOKPROC lpfnHook 11.162 + LPCTSTR lpTemplateName 11.163 +-- #if (_WIN32_WINNT >= 0x0500) 11.164 + object pvReserved 11.165 + DWORD dwReserved 11.166 + DWORD FlagsEx 11.167 +-- #endif 11.168 +end memstruct 11.169 + 11.170 +public memstruct SHITEMID 11.171 + USHORT cb 11.172 + pointer BYTE abID 11.173 +end memstruct 11.174 + 11.175 +public memstruct BROWSEINFO 11.176 + HWND hwndOwner 11.177 + pointer SHITEMID pidlRoot 11.178 + LPTSTR pszDisplayName 11.179 + LPCTSTR lpszTitle 11.180 + UINT ulFlags 11.181 + BFFCALLBACK lpfn 11.182 + LPARAM lParam 11.183 + int iImage 11.184 +end memstruct 11.185 + 11.186 +public memstruct CHOOSECOLOR 11.187 + DWORD lStructSize 11.188 + HWND hwndOwner 11.189 + HWND hInstance 11.190 + COLORREF rgbResult 11.191 + pointer COLORREF lpCustColors 11.192 + DWORD Flags 11.193 + LPARAM lCustData 11.194 + LPCCHOOKPROC lpfnHook 11.195 + LPCTSTR lpTemplateName 11.196 +end memstruct 11.197 + 11.198 +public memstruct COMBOBOXEXITEM 11.199 + UINT mask 11.200 + INT_PTR iItem 11.201 + LPTSTR pszText 11.202 + int cchTextMax 11.203 + int iImage 11.204 + int iSelectedImage 11.205 + int iOverlay 11.206 + int iIndent 11.207 + LPARAM lParam 11.208 +end memstruct 11.209 + 11.210 +public memstruct NMLISTVIEW 11.211 + NMHDR hdr 11.212 + int iItem 11.213 + int iSubItem 11.214 + UINT uNewState 11.215 + UINT uOldState 11.216 + UINT uChanged 11.217 + POINT ptAction 11.218 + LPARAM lParam 11.219 +end memstruct 11.220 + 11.221 +public memstruct SHFILEINFO 11.222 + HICON hIcon 11.223 + int iIcon 11.224 + DWORD dwAttributes 11.225 + TCHAR szDisplayName[260] 11.226 + TCHAR szTypeName[80] 11.227 +end memstruct 11.228 + 11.229 +public memstruct TVITEM 11.230 + UINT mask 11.231 + HTREEITEM hItem 11.232 + UINT state 11.233 + UINT stateMask 11.234 + LPTSTR pszText 11.235 + int cchTextMax 11.236 + int iImage 11.237 + int iSelectedImage 11.238 + int cChildren 11.239 + LPARAM lParam 11.240 +end memstruct 11.241 + 11.242 +public memstruct TVITEMEX 11.243 + UINT mask 11.244 + HTREEITEM hItem 11.245 + UINT state 11.246 + UINT stateMask 11.247 + LPTSTR pszText 11.248 + int cchTextMax 11.249 + int iImage 11.250 + int iSelectedImage 11.251 + int cChildren 11.252 + LPARAM lParam 11.253 + int iIntegral 11.254 +-- #if (_WIN32_IE >= 0x0600) 11.255 + UINT uStateEx 11.256 + HWND hwnd 11.257 + int iExpandedImage 11.258 +-- -- #endif 11.259 +-- -- #if (NTDDI_VERSION >= NTDDI_WIN7) 11.260 + int iReserved 11.261 +-- #endif 11.262 +end memstruct 11.263 + 11.264 +public memunion TVINSERTUNION 11.265 + TVITEMEX itemex 11.266 + TVITEM item 11.267 +end memunion 11.268 + 11.269 +public memstruct TVINSERTSTRUCT 11.270 + HTREEITEM hParent 11.271 + HTREEITEM hInsertAfter 11.272 +-- #if (_WIN32_IE >= 0x0400) 11.273 + TVINSERTUNION u 11.274 +end memstruct 11.275 + 11.276 +public memstruct NMTVDISPINFO 11.277 + NMHDR hdr 11.278 + TVITEM item 11.279 +end memstruct 11.280 + 11.281 +public memstruct NMTREEVIEW 11.282 + NMHDR hdr 11.283 + UINT action 11.284 + TVITEM itemOld 11.285 + TVITEM itemNew 11.286 + POINT ptDrag 11.287 +end memstruct 11.288 + 11.289 +public memstruct TVHITTESTINFO 11.290 + POINT pt 11.291 + UINT flags 11.292 + HTREEITEM hItem 11.293 +end memstruct 11.294 + 11.295 +public memstruct NMCBEENDEDIT 11.296 + NMHDR hdr 11.297 + BOOL fChanged 11.298 + int iNewSelection 11.299 + TCHAR szText 11.300 + int iWhy 11.301 +end memstruct 11.302 + 11.303 +public memstruct NMUPDOWN 11.304 + NMHDR hdr 11.305 + int iPos 11.306 + int iDelta 11.307 +end memstruct 11.308 + 11.309 +public memstruct FINDREPLACE 11.310 + DWORD lStructSize 11.311 + HWND hwndOwner 11.312 + HINSTANCE hInstance 11.313 + DWORD Flags 11.314 + LPTSTR lpstrFindWhat 11.315 + LPTSTR lpstrReplaceWith 11.316 + WORD wFindWhatLen 11.317 + WORD wReplaceWithLen 11.318 + LPARAM lCustData 11.319 + LPFRHOOKPROC lpfnHook 11.320 + LPCTSTR lpTemplateName 11.321 +end memstruct
12.1 --- a/source/Makefile.gnu Mon Dec 19 23:19:58 2011 -0300 12.2 +++ b/source/Makefile.gnu Wed Dec 21 16:45:49 2011 -0300 12.3 @@ -270,6 +270,7 @@ 12.4 inline.e \ 12.5 keylist.e \ 12.6 main.e \ 12.7 + memstruct.e \ 12.8 msgtext.e \ 12.9 mode.e \ 12.10 opnames.e \ 12.11 @@ -295,6 +296,7 @@ 12.12 buildsys.e \ 12.13 c_decl.e \ 12.14 c_out.e \ 12.15 + c_struct.e \ 12.16 cominit.e \ 12.17 compile.e \ 12.18 compress.e \ 12.19 @@ -334,6 +336,7 @@ 12.20 $(BUILDDIR)/$(OBJDIR)/back/be_symtab.o \ 12.21 $(BUILDDIR)/$(OBJDIR)/back/be_socket.o \ 12.22 $(BUILDDIR)/$(OBJDIR)/back/be_w.o \ 12.23 + $(BUILDDIR)/$(OBJDIR)/back/be_memstruct.o \ 12.24 $(PREFIXED_PCRE_OBJECTS) 12.25 12.26 EU_LIB_OBJECTS = \ 12.27 @@ -1005,18 +1008,18 @@ 12.28 # The dependencies below are automatically generated using the depend target above. 12.29 # DO NOT DELETE 12.30 12.31 -$(BUILDDIR)/intobj/back/be_alloc.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.32 -$(BUILDDIR)/intobj/back/be_alloc.o: be_alloc.h execute.h reswords.h be_runtime.h 12.33 -$(BUILDDIR)/intobj/back/be_alloc.o: be_alloc.h be_alloc.h 12.34 +$(BUILDDIR)/intobj/back/be_alloc.o: alldefs.h global.h object.h symtab.h 12.35 +$(BUILDDIR)/intobj/back/be_alloc.o: execute.h reswords.h be_runtime.h 12.36 +$(BUILDDIR)/intobj/back/be_alloc.o: be_alloc.h 12.37 $(BUILDDIR)/intobj/back/be_callc.o: alldefs.h global.h object.h symtab.h 12.38 $(BUILDDIR)/intobj/back/be_callc.o: execute.h reswords.h be_runtime.h 12.39 $(BUILDDIR)/intobj/back/be_callc.o: be_machine.h be_alloc.h 12.40 $(BUILDDIR)/intobj/back/be_coverage.o: be_coverage.h be_machine.h global.h 12.41 $(BUILDDIR)/intobj/back/be_coverage.o: object.h symtab.h execute.h 12.42 $(BUILDDIR)/intobj/back/be_debug.o: execute.h global.h object.h symtab.h 12.43 -$(BUILDDIR)/intobj/back/be_debug.o: be_alloc.h be_debug.h be_execute.h 12.44 -$(BUILDDIR)/intobj/back/be_debug.o: be_machine.h be_rterror.h be_runtime.h 12.45 -$(BUILDDIR)/intobj/back/be_debug.o: reswords.h 12.46 +$(BUILDDIR)/intobj/back/be_debug.o: redef.h reswords.h be_alloc.h be_debug.h 12.47 +$(BUILDDIR)/intobj/back/be_debug.o: be_execute.h be_machine.h be_rterror.h 12.48 +$(BUILDDIR)/intobj/back/be_debug.o: be_runtime.h be_symtab.h 12.49 $(BUILDDIR)/intobj/back/be_decompress.o: alldefs.h global.h object.h symtab.h 12.50 $(BUILDDIR)/intobj/back/be_decompress.o: execute.h reswords.h be_alloc.h 12.51 $(BUILDDIR)/intobj/back/be_decompress.o: be_runtime.h 12.52 @@ -1026,6 +1029,7 @@ 12.53 $(BUILDDIR)/intobj/back/be_execute.o: be_inline.h be_machine.h be_task.h 12.54 $(BUILDDIR)/intobj/back/be_execute.o: be_rterror.h be_symtab.h be_w.h 12.55 $(BUILDDIR)/intobj/back/be_execute.o: be_callc.h be_coverage.h be_execute.h 12.56 +$(BUILDDIR)/intobj/back/be_execute.o: be_debug.h be_memstruct.h 12.57 $(BUILDDIR)/intobj/back/be_inline.o: alldefs.h global.h object.h symtab.h 12.58 $(BUILDDIR)/intobj/back/be_inline.o: execute.h reswords.h be_alloc.h 12.59 $(BUILDDIR)/intobj/back/be_machine.o: global.h object.h symtab.h alldefs.h 12.60 @@ -1039,9 +1043,12 @@ 12.61 $(BUILDDIR)/intobj/back/be_main.o: execute.h reswords.h be_runtime.h 12.62 $(BUILDDIR)/intobj/back/be_main.o: be_execute.h be_alloc.h be_rterror.h 12.63 $(BUILDDIR)/intobj/back/be_main.o: be_w.h 12.64 -$(BUILDDIR)/intobj/back/be_pcre.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.65 -$(BUILDDIR)/intobj/back/be_pcre.o: be_alloc.h execute.h reswords.h be_alloc.h 12.66 -$(BUILDDIR)/intobj/back/be_pcre.o: be_alloc.h be_runtime.h be_pcre.h pcre/pcre.h 12.67 +$(BUILDDIR)/intobj/back/be_memstruct.o: execute.h global.h object.h symtab.h 12.68 +$(BUILDDIR)/intobj/back/be_memstruct.o: reswords.h be_alloc.h be_machine.h 12.69 +$(BUILDDIR)/intobj/back/be_memstruct.o: be_memstruct.h be_runtime.h 12.70 +$(BUILDDIR)/intobj/back/be_pcre.o: alldefs.h global.h object.h symtab.h 12.71 +$(BUILDDIR)/intobj/back/be_pcre.o: execute.h reswords.h be_alloc.h 12.72 +$(BUILDDIR)/intobj/back/be_pcre.o: be_runtime.h be_pcre.h pcre/pcre.h 12.73 $(BUILDDIR)/intobj/back/be_pcre.o: be_machine.h 12.74 $(BUILDDIR)/intobj/back/be_rterror.o: alldefs.h global.h object.h symtab.h 12.75 $(BUILDDIR)/intobj/back/be_rterror.o: execute.h reswords.h be_rterror.h 12.76 @@ -1067,23 +1074,23 @@ 12.77 $(BUILDDIR)/intobj/back/be_task.o: reswords.h be_runtime.h be_task.h 12.78 $(BUILDDIR)/intobj/back/be_task.o: be_alloc.h be_machine.h be_execute.h 12.79 $(BUILDDIR)/intobj/back/be_task.o: be_symtab.h alldefs.h 12.80 -$(BUILDDIR)/intobj/back/be_w.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.81 -$(BUILDDIR)/intobj/back/be_w.o: be_alloc.h execute.h reswords.h be_w.h be_machine.h 12.82 -$(BUILDDIR)/intobj/back/be_w.o: be_alloc.h be_runtime.h be_rterror.h be_alloc.h 12.83 +$(BUILDDIR)/intobj/back/be_w.o: alldefs.h global.h object.h symtab.h 12.84 +$(BUILDDIR)/intobj/back/be_w.o: execute.h reswords.h be_w.h be_machine.h 12.85 +$(BUILDDIR)/intobj/back/be_w.o: be_runtime.h be_rterror.h be_alloc.h 12.86 $(BUILDDIR)/intobj/back/rbt.o: rbt.h 12.87 12.88 -$(BUILDDIR)/transobj/back/be_alloc.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.89 -$(BUILDDIR)/transobj/back/be_alloc.o: be_alloc.h execute.h reswords.h be_runtime.h 12.90 -$(BUILDDIR)/transobj/back/be_alloc.o: be_alloc.h be_alloc.h 12.91 +$(BUILDDIR)/transobj/back/be_alloc.o: alldefs.h global.h object.h symtab.h 12.92 +$(BUILDDIR)/transobj/back/be_alloc.o: execute.h reswords.h be_runtime.h 12.93 +$(BUILDDIR)/transobj/back/be_alloc.o: be_alloc.h 12.94 $(BUILDDIR)/transobj/back/be_callc.o: alldefs.h global.h object.h symtab.h 12.95 $(BUILDDIR)/transobj/back/be_callc.o: execute.h reswords.h be_runtime.h 12.96 $(BUILDDIR)/transobj/back/be_callc.o: be_machine.h be_alloc.h 12.97 $(BUILDDIR)/transobj/back/be_coverage.o: be_coverage.h be_machine.h global.h 12.98 $(BUILDDIR)/transobj/back/be_coverage.o: object.h symtab.h execute.h 12.99 $(BUILDDIR)/transobj/back/be_debug.o: execute.h global.h object.h symtab.h 12.100 -$(BUILDDIR)/transobj/back/be_debug.o: be_alloc.h be_debug.h be_execute.h 12.101 -$(BUILDDIR)/transobj/back/be_debug.o: be_machine.h be_rterror.h be_runtime.h 12.102 -$(BUILDDIR)/transobj/back/be_debug.o: reswords.h 12.103 +$(BUILDDIR)/transobj/back/be_debug.o: redef.h reswords.h be_alloc.h 12.104 +$(BUILDDIR)/transobj/back/be_debug.o: be_debug.h be_execute.h be_machine.h 12.105 +$(BUILDDIR)/transobj/back/be_debug.o: be_rterror.h be_runtime.h be_symtab.h 12.106 $(BUILDDIR)/transobj/back/be_decompress.o: alldefs.h global.h object.h 12.107 $(BUILDDIR)/transobj/back/be_decompress.o: symtab.h execute.h reswords.h 12.108 $(BUILDDIR)/transobj/back/be_decompress.o: be_alloc.h be_runtime.h 12.109 @@ -1093,6 +1100,7 @@ 12.110 $(BUILDDIR)/transobj/back/be_execute.o: be_inline.h be_machine.h be_task.h 12.111 $(BUILDDIR)/transobj/back/be_execute.o: be_rterror.h be_symtab.h be_w.h 12.112 $(BUILDDIR)/transobj/back/be_execute.o: be_callc.h be_coverage.h be_execute.h 12.113 +$(BUILDDIR)/transobj/back/be_execute.o: be_debug.h be_memstruct.h 12.114 $(BUILDDIR)/transobj/back/be_inline.o: alldefs.h global.h object.h symtab.h 12.115 $(BUILDDIR)/transobj/back/be_inline.o: execute.h reswords.h be_alloc.h 12.116 $(BUILDDIR)/transobj/back/be_machine.o: global.h object.h symtab.h alldefs.h 12.117 @@ -1107,9 +1115,13 @@ 12.118 $(BUILDDIR)/transobj/back/be_main.o: execute.h reswords.h be_runtime.h 12.119 $(BUILDDIR)/transobj/back/be_main.o: be_execute.h be_alloc.h be_rterror.h 12.120 $(BUILDDIR)/transobj/back/be_main.o: be_w.h 12.121 -$(BUILDDIR)/transobj/back/be_pcre.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.122 -$(BUILDDIR)/transobj/back/be_pcre.o: be_alloc.h execute.h reswords.h be_alloc.h 12.123 -$(BUILDDIR)/transobj/back/be_pcre.o: be_alloc.h be_runtime.h be_pcre.h pcre/pcre.h 12.124 +$(BUILDDIR)/transobj/back/be_memstruct.o: execute.h global.h object.h 12.125 +$(BUILDDIR)/transobj/back/be_memstruct.o: symtab.h reswords.h be_alloc.h 12.126 +$(BUILDDIR)/transobj/back/be_memstruct.o: be_machine.h be_memstruct.h 12.127 +$(BUILDDIR)/transobj/back/be_memstruct.o: be_runtime.h 12.128 +$(BUILDDIR)/transobj/back/be_pcre.o: alldefs.h global.h object.h symtab.h 12.129 +$(BUILDDIR)/transobj/back/be_pcre.o: execute.h reswords.h be_alloc.h 12.130 +$(BUILDDIR)/transobj/back/be_pcre.o: be_runtime.h be_pcre.h pcre/pcre.h 12.131 $(BUILDDIR)/transobj/back/be_pcre.o: be_machine.h 12.132 $(BUILDDIR)/transobj/back/be_rterror.o: alldefs.h global.h object.h symtab.h 12.133 $(BUILDDIR)/transobj/back/be_rterror.o: execute.h reswords.h be_rterror.h 12.134 @@ -1136,23 +1148,23 @@ 12.135 $(BUILDDIR)/transobj/back/be_task.o: reswords.h be_runtime.h be_task.h 12.136 $(BUILDDIR)/transobj/back/be_task.o: be_alloc.h be_machine.h be_execute.h 12.137 $(BUILDDIR)/transobj/back/be_task.o: be_symtab.h alldefs.h 12.138 -$(BUILDDIR)/transobj/back/be_w.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.139 -$(BUILDDIR)/transobj/back/be_w.o: be_alloc.h execute.h reswords.h be_w.h be_machine.h 12.140 -$(BUILDDIR)/transobj/back/be_w.o: be_alloc.h be_runtime.h be_rterror.h be_alloc.h 12.141 +$(BUILDDIR)/transobj/back/be_w.o: alldefs.h global.h object.h symtab.h 12.142 +$(BUILDDIR)/transobj/back/be_w.o: execute.h reswords.h be_w.h be_machine.h 12.143 +$(BUILDDIR)/transobj/back/be_w.o: be_runtime.h be_rterror.h be_alloc.h 12.144 $(BUILDDIR)/transobj/back/rbt.o: rbt.h 12.145 12.146 -$(BUILDDIR)/backobj/back/be_alloc.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.147 -$(BUILDDIR)/backobj/back/be_alloc.o: be_alloc.h execute.h reswords.h be_runtime.h 12.148 -$(BUILDDIR)/backobj/back/be_alloc.o: be_alloc.h be_alloc.h 12.149 +$(BUILDDIR)/backobj/back/be_alloc.o: alldefs.h global.h object.h symtab.h 12.150 +$(BUILDDIR)/backobj/back/be_alloc.o: execute.h reswords.h be_runtime.h 12.151 +$(BUILDDIR)/backobj/back/be_alloc.o: be_alloc.h 12.152 $(BUILDDIR)/backobj/back/be_callc.o: alldefs.h global.h object.h symtab.h 12.153 $(BUILDDIR)/backobj/back/be_callc.o: execute.h reswords.h be_runtime.h 12.154 $(BUILDDIR)/backobj/back/be_callc.o: be_machine.h be_alloc.h 12.155 $(BUILDDIR)/backobj/back/be_coverage.o: be_coverage.h be_machine.h global.h 12.156 $(BUILDDIR)/backobj/back/be_coverage.o: object.h symtab.h execute.h 12.157 $(BUILDDIR)/backobj/back/be_debug.o: execute.h global.h object.h symtab.h 12.158 -$(BUILDDIR)/backobj/back/be_debug.o: be_alloc.h be_debug.h be_execute.h 12.159 -$(BUILDDIR)/backobj/back/be_debug.o: be_machine.h be_rterror.h be_runtime.h 12.160 -$(BUILDDIR)/backobj/back/be_debug.o: reswords.h 12.161 +$(BUILDDIR)/backobj/back/be_debug.o: redef.h reswords.h be_alloc.h be_debug.h 12.162 +$(BUILDDIR)/backobj/back/be_debug.o: be_execute.h be_machine.h be_rterror.h 12.163 +$(BUILDDIR)/backobj/back/be_debug.o: be_runtime.h be_symtab.h 12.164 $(BUILDDIR)/backobj/back/be_decompress.o: alldefs.h global.h object.h 12.165 $(BUILDDIR)/backobj/back/be_decompress.o: symtab.h execute.h reswords.h 12.166 $(BUILDDIR)/backobj/back/be_decompress.o: be_alloc.h be_runtime.h 12.167 @@ -1162,6 +1174,7 @@ 12.168 $(BUILDDIR)/backobj/back/be_execute.o: be_inline.h be_machine.h be_task.h 12.169 $(BUILDDIR)/backobj/back/be_execute.o: be_rterror.h be_symtab.h be_w.h 12.170 $(BUILDDIR)/backobj/back/be_execute.o: be_callc.h be_coverage.h be_execute.h 12.171 +$(BUILDDIR)/backobj/back/be_execute.o: be_debug.h be_memstruct.h 12.172 $(BUILDDIR)/backobj/back/be_inline.o: alldefs.h global.h object.h symtab.h 12.173 $(BUILDDIR)/backobj/back/be_inline.o: execute.h reswords.h be_alloc.h 12.174 $(BUILDDIR)/backobj/back/be_machine.o: global.h object.h symtab.h alldefs.h 12.175 @@ -1175,9 +1188,12 @@ 12.176 $(BUILDDIR)/backobj/back/be_main.o: execute.h reswords.h be_runtime.h 12.177 $(BUILDDIR)/backobj/back/be_main.o: be_execute.h be_alloc.h be_rterror.h 12.178 $(BUILDDIR)/backobj/back/be_main.o: be_w.h 12.179 -$(BUILDDIR)/backobj/back/be_pcre.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.180 -$(BUILDDIR)/backobj/back/be_pcre.o: be_alloc.h execute.h reswords.h be_alloc.h 12.181 -$(BUILDDIR)/backobj/back/be_pcre.o: be_alloc.h be_runtime.h be_pcre.h pcre/pcre.h 12.182 +$(BUILDDIR)/backobj/back/be_memstruct.o: execute.h global.h object.h symtab.h 12.183 +$(BUILDDIR)/backobj/back/be_memstruct.o: reswords.h be_alloc.h be_machine.h 12.184 +$(BUILDDIR)/backobj/back/be_memstruct.o: be_memstruct.h be_runtime.h 12.185 +$(BUILDDIR)/backobj/back/be_pcre.o: alldefs.h global.h object.h symtab.h 12.186 +$(BUILDDIR)/backobj/back/be_pcre.o: execute.h reswords.h be_alloc.h 12.187 +$(BUILDDIR)/backobj/back/be_pcre.o: be_runtime.h be_pcre.h pcre/pcre.h 12.188 $(BUILDDIR)/backobj/back/be_pcre.o: be_machine.h 12.189 $(BUILDDIR)/backobj/back/be_rterror.o: alldefs.h global.h object.h symtab.h 12.190 $(BUILDDIR)/backobj/back/be_rterror.o: execute.h reswords.h be_rterror.h 12.191 @@ -1203,23 +1219,23 @@ 12.192 $(BUILDDIR)/backobj/back/be_task.o: reswords.h be_runtime.h be_task.h 12.193 $(BUILDDIR)/backobj/back/be_task.o: be_alloc.h be_machine.h be_execute.h 12.194 $(BUILDDIR)/backobj/back/be_task.o: be_symtab.h alldefs.h 12.195 -$(BUILDDIR)/backobj/back/be_w.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.196 -$(BUILDDIR)/backobj/back/be_w.o: be_alloc.h execute.h reswords.h be_w.h be_machine.h 12.197 -$(BUILDDIR)/backobj/back/be_w.o: be_alloc.h be_runtime.h be_rterror.h be_alloc.h 12.198 +$(BUILDDIR)/backobj/back/be_w.o: alldefs.h global.h object.h symtab.h 12.199 +$(BUILDDIR)/backobj/back/be_w.o: execute.h reswords.h be_w.h be_machine.h 12.200 +$(BUILDDIR)/backobj/back/be_w.o: be_runtime.h be_rterror.h be_alloc.h 12.201 $(BUILDDIR)/backobj/back/rbt.o: rbt.h 12.202 12.203 -$(BUILDDIR)/libobj/back/be_alloc.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.204 -$(BUILDDIR)/libobj/back/be_alloc.o: be_alloc.h execute.h reswords.h be_runtime.h 12.205 -$(BUILDDIR)/libobj/back/be_alloc.o: be_alloc.h be_alloc.h 12.206 +$(BUILDDIR)/libobj/back/be_alloc.o: alldefs.h global.h object.h symtab.h 12.207 +$(BUILDDIR)/libobj/back/be_alloc.o: execute.h reswords.h be_runtime.h 12.208 +$(BUILDDIR)/libobj/back/be_alloc.o: be_alloc.h 12.209 $(BUILDDIR)/libobj/back/be_callc.o: alldefs.h global.h object.h symtab.h 12.210 $(BUILDDIR)/libobj/back/be_callc.o: execute.h reswords.h be_runtime.h 12.211 $(BUILDDIR)/libobj/back/be_callc.o: be_machine.h be_alloc.h 12.212 $(BUILDDIR)/libobj/back/be_coverage.o: be_coverage.h be_machine.h global.h 12.213 $(BUILDDIR)/libobj/back/be_coverage.o: object.h symtab.h execute.h 12.214 $(BUILDDIR)/libobj/back/be_debug.o: execute.h global.h object.h symtab.h 12.215 -$(BUILDDIR)/libobj/back/be_debug.o: be_alloc.h be_debug.h be_execute.h 12.216 -$(BUILDDIR)/libobj/back/be_debug.o: be_machine.h be_rterror.h be_runtime.h 12.217 -$(BUILDDIR)/libobj/back/be_debug.o: reswords.h 12.218 +$(BUILDDIR)/libobj/back/be_debug.o: redef.h reswords.h be_alloc.h be_debug.h 12.219 +$(BUILDDIR)/libobj/back/be_debug.o: be_execute.h be_machine.h be_rterror.h 12.220 +$(BUILDDIR)/libobj/back/be_debug.o: be_runtime.h be_symtab.h 12.221 $(BUILDDIR)/libobj/back/be_decompress.o: alldefs.h global.h object.h symtab.h 12.222 $(BUILDDIR)/libobj/back/be_decompress.o: execute.h reswords.h be_alloc.h 12.223 $(BUILDDIR)/libobj/back/be_decompress.o: be_runtime.h 12.224 @@ -1229,6 +1245,7 @@ 12.225 $(BUILDDIR)/libobj/back/be_execute.o: be_inline.h be_machine.h be_task.h 12.226 $(BUILDDIR)/libobj/back/be_execute.o: be_rterror.h be_symtab.h be_w.h 12.227 $(BUILDDIR)/libobj/back/be_execute.o: be_callc.h be_coverage.h be_execute.h 12.228 +$(BUILDDIR)/libobj/back/be_execute.o: be_debug.h be_memstruct.h 12.229 $(BUILDDIR)/libobj/back/be_inline.o: alldefs.h global.h object.h symtab.h 12.230 $(BUILDDIR)/libobj/back/be_inline.o: execute.h reswords.h be_alloc.h 12.231 $(BUILDDIR)/libobj/back/be_machine.o: global.h object.h symtab.h alldefs.h 12.232 @@ -1242,9 +1259,12 @@ 12.233 $(BUILDDIR)/libobj/back/be_main.o: execute.h reswords.h be_runtime.h 12.234 $(BUILDDIR)/libobj/back/be_main.o: be_execute.h be_alloc.h be_rterror.h 12.235 $(BUILDDIR)/libobj/back/be_main.o: be_w.h 12.236 -$(BUILDDIR)/libobj/back/be_pcre.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.237 -$(BUILDDIR)/libobj/back/be_pcre.o: be_alloc.h execute.h reswords.h be_alloc.h 12.238 -$(BUILDDIR)/libobj/back/be_pcre.o: be_alloc.h be_runtime.h be_pcre.h pcre/pcre.h 12.239 +$(BUILDDIR)/libobj/back/be_memstruct.o: execute.h global.h object.h symtab.h 12.240 +$(BUILDDIR)/libobj/back/be_memstruct.o: reswords.h be_alloc.h be_machine.h 12.241 +$(BUILDDIR)/libobj/back/be_memstruct.o: be_memstruct.h be_runtime.h 12.242 +$(BUILDDIR)/libobj/back/be_pcre.o: alldefs.h global.h object.h symtab.h 12.243 +$(BUILDDIR)/libobj/back/be_pcre.o: execute.h reswords.h be_alloc.h 12.244 +$(BUILDDIR)/libobj/back/be_pcre.o: be_runtime.h be_pcre.h pcre/pcre.h 12.245 $(BUILDDIR)/libobj/back/be_pcre.o: be_machine.h 12.246 $(BUILDDIR)/libobj/back/be_rterror.o: alldefs.h global.h object.h symtab.h 12.247 $(BUILDDIR)/libobj/back/be_rterror.o: execute.h reswords.h be_rterror.h 12.248 @@ -1270,7 +1290,7 @@ 12.249 $(BUILDDIR)/libobj/back/be_task.o: reswords.h be_runtime.h be_task.h 12.250 $(BUILDDIR)/libobj/back/be_task.o: be_alloc.h be_machine.h be_execute.h 12.251 $(BUILDDIR)/libobj/back/be_task.o: be_symtab.h alldefs.h 12.252 -$(BUILDDIR)/libobj/back/be_w.o: be_alloc.h alldefs.h global.h object.h symtab.h 12.253 -$(BUILDDIR)/libobj/back/be_w.o: be_alloc.h execute.h reswords.h be_w.h be_machine.h 12.254 -$(BUILDDIR)/libobj/back/be_w.o: be_alloc.h be_runtime.h be_rterror.h be_alloc.h 12.255 +$(BUILDDIR)/libobj/back/be_w.o: alldefs.h global.h object.h symtab.h 12.256 +$(BUILDDIR)/libobj/back/be_w.o: execute.h reswords.h be_w.h be_machine.h 12.257 +$(BUILDDIR)/libobj/back/be_w.o: be_runtime.h be_rterror.h be_alloc.h 12.258 $(BUILDDIR)/libobj/back/rbt.o: rbt.h
13.1 --- a/source/Makefile.wat Mon Dec 19 23:19:58 2011 -0300 13.2 +++ b/source/Makefile.wat Wed Dec 21 16:45:49 2011 -0300 13.3 @@ -120,6 +120,7 @@ 13.4 inline.e & 13.5 keylist.e & 13.6 main.e & 13.7 + memstruct.e & 13.8 msgtext.e & 13.9 mode.e & 13.10 opnames.e & 13.11 @@ -176,6 +177,7 @@ 13.12 $(BUILDDIR)\$(OBJDIR)\back\be_syncolor.obj & 13.13 $(BUILDDIR)\$(OBJDIR)\back\be_task.obj & 13.14 $(BUILDDIR)\$(OBJDIR)\back\be_w.obj & 13.15 + $(BUILDDIR)\$(OBJDIR)\back\be_memstruct.obj & 13.16 $(PCRE_OBJECTS) 13.17 13.18 EU_LIB_OBJECTS = & 13.19 @@ -800,7 +802,8 @@ 13.20 $(BUILDDIR)\$(OBJDIR)\back\be_symtab.obj : be_symtab.c *.h $(CONFIG) 13.21 $(BUILDDIR)\$(OBJDIR)\back\be_w.obj : be_w.c *.h $(CONFIG) 13.22 $(BUILDDIR)\$(OBJDIR)\back\be_socket.obj : be_socket.c *.h $(CONFIG) 13.23 -$(BUILDDIR)\$(OBJDIR)\back\be_pcre.obj : be_pcre.c *.h $(CONFIG) 13.24 +$(BUILDDIR)\$(OBJDIR)\back\be_pcre.obj : be_pcre.c *.h $(CONFIG) 13.25 +$(BUILDDIR)\$(OBJDIR)\back\be_memstruct.obj : be_memstruct.c *.h $(CONFIG) 13.26 13.27 # end of OBJDIR exists 13.28 !endif
14.1 --- a/source/backend.e Mon Dec 19 23:19:58 2011 -0300 14.2 +++ b/source/backend.e Wed Dec 21 16:45:49 2011 -0300 14.3 @@ -109,35 +109,52 @@ 14.4 if eentry[S_MODE] = M_NORMAL then 14.5 -- vars and routines 14.6 14.7 - if find(eentry[S_TOKEN], RTN_TOKS) then 14.8 - -- routines only 14.9 - if sequence(eentry[S_CODE]) and (get_backend() or eentry[S_OPCODE]=0) then 14.10 - -- routines with code 14.11 - e_addr = allocate( sizeof( C_POINTER ) * (length(eentry[S_CODE]) + 1 ) ) -- IL code 14.12 - poke_pointer(e_addr, length(eentry[S_CODE])) 14.13 - poke_pointer(e_addr + sizeof( C_POINTER ), eentry[S_CODE]) 14.14 - poke_pointer(addr + ST_CODE, e_addr) 14.15 + switch eentry[S_TOKEN] do 14.16 + case PROC, FUNC, TYPE then 14.17 + -- routines only 14.18 + if sequence(eentry[S_CODE]) and (get_backend() or eentry[S_OPCODE]=0) then 14.19 + -- routines with code 14.20 + e_addr = allocate( sizeof( C_POINTER ) * (length(eentry[S_CODE]) + 1 ) ) -- IL code 14.21 + poke_pointer(e_addr, length(eentry[S_CODE])) 14.22 + poke_pointer(e_addr + sizeof( C_POINTER ), eentry[S_CODE]) 14.23 + poke_pointer(addr + ST_CODE, e_addr) 14.24 + 14.25 + if sequence(eentry[S_LINETAB]) then 14.26 + -- line table 14.27 + l_addr = allocate( 4 * length(eentry[S_LINETAB])) 14.28 + poke4(l_addr, eentry[S_LINETAB]) 14.29 + poke_pointer(addr + ST_LINETAB, l_addr) 14.30 + else 14.31 + -- pointer to linetable will be NULL 14.32 + end if 14.33 + end if 14.34 + poke4(addr + ST_FIRSTLINE, eentry[S_FIRSTLINE]) 14.35 + poke_pointer(addr + ST_TEMPS, eentry[S_TEMPS]) 14.36 + poke4(addr + ST_NUM_ARGS, eentry[S_NUM_ARGS]) 14.37 + -- 14.38 + -- 14.39 + poke4(addr + ST_STACK_SPACE, eentry[S_STACK_SPACE]) 14.40 + poke_pointer(addr + ST_BLOCK, eentry[S_BLOCK]) 14.41 14.42 - if sequence(eentry[S_LINETAB]) then 14.43 - -- line table 14.44 - l_addr = allocate( 4 * length(eentry[S_LINETAB])) 14.45 - poke4(l_addr, eentry[S_LINETAB]) 14.46 - poke_pointer(addr + ST_LINETAB, l_addr) 14.47 - else 14.48 - -- pointer to linetable will be NULL 14.49 + case MEMSTRUCT, MEMUNION, MEMTYPE, MS_MEMBER, 14.50 + MS_OBJECT, MS_CHAR, MS_SHORT, MS_INT, 14.51 + MS_LONG, MS_LONGLONG, 14.52 + MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 14.53 + if SIZEOF_MEMSTRUCT_ENTRY = length( eentry ) then 14.54 + poke_pointer( addr + ST_MEM_NEXT, eentry[S_MEM_NEXT] ) 14.55 + poke_pointer( addr + ST_MEM_STRUCT, eentry[S_MEM_STRUCT] ) 14.56 + poke_pointer( addr + ST_MEM_PARENT, eentry[S_MEM_PARENT] ) 14.57 + 14.58 + poke4( addr + ST_MEM_SIZE, eentry[S_MEM_SIZE] ) 14.59 + poke4( addr + ST_MEM_OFFSET, eentry[S_MEM_OFFSET] ) 14.60 + poke4( addr + ST_MEM_ARRAY, eentry[S_MEM_ARRAY] ) 14.61 + poke( addr + ST_MEM_SIGNED, eentry[S_MEM_SIGNED] ) 14.62 + poke( addr + ST_MEM_POINTER, eentry[S_MEM_POINTER] ) 14.63 end if 14.64 - end if 14.65 - poke4(addr + ST_FIRSTLINE, eentry[S_FIRSTLINE]) 14.66 - poke_pointer(addr + ST_TEMPS, eentry[S_TEMPS]) 14.67 - poke4(addr + ST_NUM_ARGS, eentry[S_NUM_ARGS]) 14.68 - -- 14.69 - -- 14.70 - poke4(addr + ST_STACK_SPACE, eentry[S_STACK_SPACE]) 14.71 - poke_pointer(addr + ST_BLOCK, eentry[S_BLOCK]) 14.72 - 14.73 - else 14.74 - poke_pointer(addr + ST_DECLARED_IN, eentry[S_BLOCK] ) 14.75 - end if 14.76 + 14.77 + case else 14.78 + poke_pointer(addr + ST_DECLARED_IN, eentry[S_BLOCK] ) 14.79 + end switch 14.80 14.81 elsif eentry[S_MODE] = M_BLOCK then 14.82 poke_pointer(addr + ST_NEXT_IN_BLOCK, eentry[S_NEXT_IN_BLOCK] ) 14.83 @@ -146,7 +163,8 @@ 14.84 poke4(addr + ST_FIRST_LINE, eentry[S_FIRST_LINE] ) 14.85 poke4(addr + ST_LAST_LINE, eentry[S_LAST_LINE] ) 14.86 end if 14.87 - 14.88 + 14.89 + 14.90 elsif (length(eentry) < S_NAME and eentry[S_MODE] = M_CONSTANT) or 14.91 (length(eentry) >= S_TOKEN and compare( eentry[S_OBJ], NOVALUE )) then 14.92 -- compress constants and literal values in memory 14.93 @@ -287,6 +305,7 @@ 14.94 routine_id( "write_coverage_db" ), 14.95 routine_id( "DisplayColorLine" ), 14.96 external_debugger_ptr, 14.97 + trace_lines, 14.98 $ 14.99 }) 14.100 end procedure
15.1 --- a/source/be_execute.c Mon Dec 19 23:19:58 2011 -0300 15.2 +++ b/source/be_execute.c Wed Dec 21 16:45:49 2011 -0300 15.3 @@ -73,6 +73,7 @@ 15.4 #include "be_coverage.h" 15.5 #include "be_execute.h" 15.6 #include "be_debug.h" 15.7 +#include "be_memstruct.h" 15.8 15.9 /******************/ 15.10 /* Local defines */ 15.11 @@ -959,7 +960,7 @@ 15.12 void code_set_pointers(intptr_t **code) 15.13 /* adjust code pointers, changing some indexes into pointers */ 15.14 { 15.15 - intptr_t len, i, j, n, sub, word; 15.16 + intptr_t len, i, j, n, sub, word, array; 15.17 15.18 len = (intptr_t) code[0]; 15.19 i = 1; 15.20 @@ -1017,6 +1018,7 @@ 15.21 case DEREF_TEMP: 15.22 case REF_TEMP: 15.23 case NOVALUE_TEMP: 15.24 + case MEM_TYPE_CHECK: 15.25 // one operand 15.26 code[i+1] = SET_OPERAND(code[i+1]); 15.27 i += 2; 15.28 @@ -1060,6 +1062,8 @@ 15.29 case RAND: 15.30 case PEEK: 15.31 case SIZEOF: 15.32 + case ADDRESSOF: 15.33 + case OFFSETOF: 15.34 case PEEK_STRING: 15.35 case PEEKS: 15.36 case FLOOR: 15.37 @@ -1165,13 +1169,31 @@ 15.38 case TAIL: 15.39 case DELETE_ROUTINE: 15.40 case RETURNF: 15.41 + case MEMSTRUCT_READ: 15.42 // 3 operands follow 15.43 code[i+1] = SET_OPERAND(code[i+1]); 15.44 code[i+2] = SET_OPERAND(code[i+2]); 15.45 code[i+3] = SET_OPERAND(code[i+3]); 15.46 i += 4; 15.47 break; 15.48 - 15.49 + case MEMSTRUCT_PLUS: 15.50 + case MEMSTRUCT_MINUS: 15.51 + case MEMSTRUCT_DIVIDE: 15.52 + case MEMSTRUCT_MULTIPLY: 15.53 + case MEMSTRUCT_ASSIGN: 15.54 + // 3 operands follow 15.55 + code[i+1] = SET_OPERAND(code[i+1]); 15.56 + code[i+2] = SET_OPERAND(code[i+2]); 15.57 + code[i+3] = SET_OPERAND(code[i+3]); 15.58 + i += 5; 15.59 + break; 15.60 + case PEEK_MEMBER: 15.61 + // 3 operands follow 15.62 + code[i+1] = SET_OPERAND(code[i+1]); 15.63 + code[i+2] = SET_OPERAND(code[i+2]); 15.64 + code[i+4] = SET_OPERAND(code[i+4]); 15.65 + i += 5; 15.66 + break; 15.67 case SC1_AND_IF: 15.68 case SC1_OR_IF: 15.69 case SC1_AND: 15.70 @@ -1217,6 +1239,8 @@ 15.71 case INSERT: 15.72 case REMOVE: 15.73 case OPEN: 15.74 + case MEMSTRUCT_ARRAY: 15.75 + case PEEK_ARRAY: 15.76 // 4 operands follow 15.77 code[i+1] = SET_OPERAND(code[i+1]); 15.78 code[i+2] = SET_OPERAND(code[i+2]); 15.79 @@ -1328,7 +1352,25 @@ 15.80 15.81 i += n + 3; 15.82 break; 15.83 - 15.84 + case MEMSTRUCT_ACCESS: 15.85 + case ARRAY_ACCESS: 15.86 + n = (intptr_t)code[i+1] + 1; 15.87 + array = (word == ARRAY_ACCESS); 15.88 + for (j = 1; j <= n; j++) { 15.89 + word = (intptr_t)code[i+1+j]; 15.90 + code[i+1+j] = SET_OPERAND(word); 15.91 + } 15.92 + 15.93 + word = (intptr_t)code[i+n+2]; 15.94 + 15.95 + code[i+n+2] = SET_OPERAND(word); 15.96 + if( array ){ 15.97 + word = (intptr_t)code[i+n+3]; 15.98 + code[i+n+3] = SET_OPERAND( word ); 15.99 + } 15.100 + 15.101 + i += n + 3 + array; 15.102 + break; 15.103 default: 15.104 RTFatal("UNKNOWN IL OPCODE"); 15.105 } 15.106 @@ -1374,6 +1416,15 @@ 15.107 } 15.108 s->u.subp.block = (symtab_ptr)SET_OPERAND( s->u.subp.block ); 15.109 } 15.110 + else if(s->token == MEMSTRUCT || 15.111 + s->token == MEMUNION || 15.112 + s->token == MS_MEMBER ){ 15.113 + 15.114 + s->u.memstruct.next = (symtab_ptr)SET_OPERAND( s->u.memstruct.next ); 15.115 + s->u.memstruct.struct_type = (symtab_ptr)SET_OPERAND( s->u.memstruct.struct_type ); 15.116 + s->u.memstruct.parent = (symtab_ptr)SET_OPERAND( s->u.memstruct.parent ); 15.117 + 15.118 + } 15.119 else{ 15.120 s->u.var.declared_in = (symtab_ptr)SET_OPERAND( s->u.var.declared_in ); 15.121 } 15.122 @@ -1399,6 +1450,7 @@ 15.123 // M_TEMP - temps 15.124 // leave obj as 0 15.125 } 15.126 + 15.127 s++; 15.128 } 15.129 } 15.130 @@ -1816,8 +1868,17 @@ 15.131 /* 214 (previous) */ 15.132 &&L_POKE_POINTER, &&L_PEEK_POINTER, 15.133 /* 215 (previous) */ 15.134 - &&L_SIZEOF, &&L_STARTLINE_BREAK 15.135 - }; 15.136 + &&L_SIZEOF, &&L_STARTLINE_BREAK, 15.137 + 15.138 + &&L_MEMSTRUCT_ACCESS, &&L_MEMSTRUCT_ARRAY, &&L_PEEK_MEMBER, 15.139 + &&L_MEMSTRUCT_READ, &&L_MEMSTRUCT_ASSIGN, &&L_MEMSTRUCT_PLUS, 15.140 + &&L_MEMSTRUCT_MINUS, &&L_MEMSTRUCT_MULTIPLY, &&L_MEMSTRUCT_DIVIDE, 15.141 + &&L_MEM_TYPE_CHECK, &&L_ADDRESSOF, &&L_OFFSETOF, &&L_PEEK_ARRAY, 15.142 + &&L_ARRAY_ACCESS 15.143 +/* 232 (previous) */ 15.144 + 15.145 + 15.146 + }; 15.147 #endif 15.148 #endif 15.149 if (start_pc == NULL) { 15.150 @@ -2485,7 +2546,7 @@ 15.151 BREAK; 15.152 15.153 case L_TYPE_CHECK: /* top has TRUE/FALSE */ 15.154 - deprintf("case L_TYPE_CHECK:"); 15.155 + deprintf("case L_TYPE_CHECK:"); 15.156 /* type check for a user-defined type */ 15.157 /* this always follows a type-call */ 15.158 top = *(object_ptr)pc[-1]; 15.159 @@ -2509,6 +2570,29 @@ 15.160 } 15.161 BREAK; 15.162 15.163 + case L_MEM_TYPE_CHECK: 15.164 + deprintf("case L_MEM_TYPE_CHECK:"); 15.165 + top = *(object_ptr)pc[-1]; 15.166 + pc += 2; 15.167 + if (top == ATOM_1) { 15.168 + thread(); 15.169 + BREAK; /* usual case L_*/ 15.170 + } 15.171 + else if (IS_ATOM_INT(top)) { 15.172 + if (top == ATOM_0) 15.173 + RTFatalMemType(pc-4, pc[-1]); 15.174 + } 15.175 + else if (IS_ATOM_DBL(top)) { 15.176 + if (DBL_PTR(top)->dbl == 0.0) 15.177 + RTFatalMemType(pc-4, pc[-1]); 15.178 + } 15.179 + else {/* sequence */ 15.180 + type_error_msg = 15.181 + "\ntype_check failure (type returned a sequence!), "; 15.182 + RTFatalMemType(pc-4, pc[-1]); 15.183 + } 15.184 + BREAK; 15.185 + 15.186 case L_NOP2: 15.187 deprintf("case L_NOP2:"); 15.188 thread2(); 15.189 @@ -4528,10 +4612,62 @@ 15.190 BREAK; 15.191 15.192 case L_SIZEOF: 15.193 - a = *(object_ptr)pc[1]; /* the data type */ 15.194 + tpc = pc; // in case of machine exception 15.195 top = *(object_ptr)pc[2]; 15.196 - tpc = pc; // in case of machine exception 15.197 - *(object_ptr)pc[2] = eu_sizeof( a ); 15.198 + if( ((symtab_ptr)pc[1])->token == MEMSTRUCT || 15.199 + ((symtab_ptr)pc[1])->token == MEMUNION || 15.200 + ((symtab_ptr)pc[1])->token == MS_MEMBER || 15.201 + ((symtab_ptr)pc[1])->token == MEMTYPE 15.202 + ){ 15.203 + *(object_ptr)pc[2] = ((symtab_ptr)pc[1])->u.memstruct.size; 15.204 + } 15.205 + else if( ((symtab_ptr)pc[1])->token == MS_CHAR ){ *(object_ptr)pc[2] = sizeof( char ); } 15.206 + else if( ((symtab_ptr)pc[1])->token == MS_SHORT ){ *(object_ptr)pc[2] = sizeof( short ); } 15.207 + else if( ((symtab_ptr)pc[1])->token == MS_INT ){ *(object_ptr)pc[2] = sizeof( int ); } 15.208 + else if( ((symtab_ptr)pc[1])->token == MS_LONG ){ *(object_ptr)pc[2] = sizeof( long ); } 15.209 + else if( ((symtab_ptr)pc[1])->token == MS_LONGLONG ){ *(object_ptr)pc[2] = sizeof( long long ); } 15.210 + else if( ((symtab_ptr)pc[1])->token == MS_OBJECT ){ *(object_ptr)pc[2] = sizeof( void * ); } 15.211 + else if( ((symtab_ptr)pc[1])->token == MS_FLOAT ){ *(object_ptr)pc[2] = sizeof( float ); } 15.212 + else if( ((symtab_ptr)pc[1])->token == MS_DOUBLE ){ *(object_ptr)pc[2] = sizeof( double ); } 15.213 + else if( ((symtab_ptr)pc[1])->token == MS_LONGDOUBLE ){ *(object_ptr)pc[2] = sizeof( long double ); } 15.214 + else if( ((symtab_ptr)pc[1])->token == MS_EUDOUBLE ){ *(object_ptr)pc[2] = sizeof( eudouble ); } 15.215 + else{ 15.216 + 15.217 + a = *(object_ptr)pc[1]; /* the data type */ 15.218 + *(object_ptr)pc[2] = eu_sizeof( a ); 15.219 + } 15.220 + DeRef( top ); 15.221 + inc3pc(); 15.222 + thread(); 15.223 + BREAK; 15.224 + 15.225 + case L_ADDRESSOF: 15.226 + deprintf("case L_ADDRESSOF:"); 15.227 + tpc = pc; 15.228 + top = *(object_ptr)pc[2]; 15.229 +#if INTPTR_MAX == INT32_MAX 15.230 + if ( (uintptr_t)*(object_ptr)pc[1] > (uintptr_t)MAXINT){ 15.231 + top = NewDouble((eudouble) *(object_ptr)pc[1]); 15.232 + } 15.233 + else{ 15.234 + *(object_ptr)pc[2] = *(object_ptr)pc[1]; 15.235 + } 15.236 +#else 15.237 + // 64-bit ptr always fits in an eu integer 15.238 + *(object_ptr)pc[2] = *(object_ptr)pc[1]; 15.239 +#endif 15.240 + Ref( *(object_ptr)pc[2] ); 15.241 + DeRef( top ); 15.242 + inc3pc(); 15.243 + thread(); 15.244 + BREAK; 15.245 + 15.246 + case L_OFFSETOF: 15.247 + deprintf("case L_ADDRESSOF:"); 15.248 + tpc = pc; 15.249 + top = *(object_ptr)pc[2]; 15.250 + *(object_ptr)pc[2] = ((symtab_ptr)pc[1])->u.memstruct.offset; 15.251 + Ref( *(object_ptr)pc[2] ); 15.252 DeRef( top ); 15.253 inc3pc(); 15.254 thread(); 15.255 @@ -5282,6 +5418,112 @@ 15.256 thread2(); 15.257 BREAK; 15.258 15.259 + case L_MEMSTRUCT_ASSIGN: 15.260 + deprintf("case L_MEMSTRUCT_ASSIGN"); 15.261 + tpc = pc; 15.262 + 15.263 + sym = (symtab_ptr) pc[2]; 15.264 + if( sym->u.memstruct.pointer && !pc[4] ){ 15.265 + poke_member( (object_ptr) pc[1], sym, (object_ptr) pc[3], 0 ); 15.266 + } 15.267 + else if( sym->token == MEMSTRUCT ){ 15.268 + write_member( (object_ptr) pc[1], sym, (object_ptr) pc[3], pc[4] ); 15.269 + } 15.270 + else if( sym->token == MEMUNION ){ 15.271 + write_union( (object_ptr) pc[1], sym, (object_ptr) pc[3], pc[4] ); 15.272 + } 15.273 + else{ 15.274 + poke_member( (object_ptr) pc[1], sym, (object_ptr) pc[3], pc[4] ); 15.275 + } 15.276 + thread5(); 15.277 + BREAK; 15.278 + 15.279 + case L_MEMSTRUCT_PLUS: 15.280 + deprintf("case LMEMSTRUCT_PLUS"); 15.281 + a = MEMSTRUCT_PLUS; 15.282 + goto mem_assign_op; 15.283 + 15.284 + case L_MEMSTRUCT_MINUS: 15.285 + deprintf("case LMEMSTRUCT_MINUS"); 15.286 + a = MEMSTRUCT_MINUS; 15.287 + goto mem_assign_op; 15.288 + 15.289 + case L_MEMSTRUCT_DIVIDE: 15.290 + deprintf("case LMEMSTRUCT_DIVIDE"); 15.291 + a = MEMSTRUCT_DIVIDE; 15.292 + goto mem_assign_op; 15.293 + 15.294 + case L_MEMSTRUCT_MULTIPLY: 15.295 + deprintf("case LMEMSTRUCT_MULTIPLY"); 15.296 + a = MEMSTRUCT_MULTIPLY; 15.297 + 15.298 + mem_assign_op: 15.299 + tpc = pc; 15.300 + memstruct_assignop( a, (object_ptr)pc[1], (symtab_ptr) pc[2], (object_ptr) pc[3], pc[4] ); 15.301 + thread5(); 15.302 + BREAK; 15.303 + 15.304 + case L_MEMSTRUCT_READ: 15.305 + deprintf("case L_MEMSTRUCT_READ"); 15.306 + tpc = pc; 15.307 + a = read_memstruct( (object_ptr) pc[1], 0, (symtab_ptr) pc[2] ); 15.308 + obj_ptr = (object_ptr) pc[3]; 15.309 + DeRef( *obj_ptr ); 15.310 + *obj_ptr = a; 15.311 + thread4(); 15.312 + BREAK; 15.313 + case L_PEEK_MEMBER: 15.314 + deprintf("case L_PEEK_MEMBER"); 15.315 + tpc = pc; 15.316 + a = peek_member( (object_ptr) pc[1], (symtab_ptr) pc[2], -1, 0, pc[3] ); 15.317 + obj_ptr = (object_ptr) pc[4]; 15.318 + DeRef( *obj_ptr ); 15.319 + *obj_ptr = a; 15.320 + thread5(); 15.321 + BREAK; 15.322 + 15.323 + case L_MEMSTRUCT_ACCESS: 15.324 + deprintf("case L_MEMSTRUCT_ACCESS"); 15.325 + tpc = pc; 15.326 + b = pc[1]; 15.327 + a = memstruct_access( b, (object_ptr) pc[2], (symtab_ptr *) pc + 3 ); 15.328 + obj_ptr = (object_ptr) pc[b+3]; 15.329 + DeRef( *obj_ptr ); 15.330 + *obj_ptr = a; 15.331 + pc += b + 4; 15.332 + thread(); 15.333 + BREAK; 15.334 + case L_ARRAY_ACCESS: 15.335 + deprintf("case L_ARRAY_ACCESS"); 15.336 + tpc = pc; 15.337 + b = pc[1]; 15.338 + a = array_access( b, (object_ptr) pc[2], (symtab_ptr *) pc + 3, (symtab_ptr) pc[4]); 15.339 + obj_ptr = (object_ptr) pc[b+4]; 15.340 + DeRef( *obj_ptr ); 15.341 + *obj_ptr = a; 15.342 + pc += b + 5; 15.343 + thread(); 15.344 + BREAK; 15.345 + case L_MEMSTRUCT_ARRAY: 15.346 + deprintf("case L_MEMSTRUCT_ARRAY"); 15.347 + tpc = pc; 15.348 + a = memstruct_array( (object_ptr)pc[1], (symtab_ptr)pc[2], (object_ptr)pc[3] ); 15.349 + obj_ptr = (object_ptr) pc[4]; 15.350 + DeRef( *obj_ptr ); 15.351 + *obj_ptr = a; 15.352 + thread5(); 15.353 + BREAK; 15.354 + case L_PEEK_ARRAY: 15.355 + deprintf("case L_PEEK_ARRAY"); 15.356 + 15.357 + tpc = pc; 15.358 + a = peek_array( (object_ptr)pc[1], (symtab_ptr)pc[2], (object_ptr)pc[3] ); 15.359 + obj_ptr = (object_ptr) pc[4]; 15.360 + DeRef( *obj_ptr ); 15.361 + *obj_ptr = a; 15.362 + 15.363 + thread5(); 15.364 + BREAK; 15.365 default: 15.366 RTFatal("Unsupported Op Code "); 15.367
16.1 --- a/source/be_machine.c Mon Dec 19 23:19:58 2011 -0300 16.2 +++ b/source/be_machine.c Wed Dec 21 16:45:49 2011 -0300 16.3 @@ -224,7 +224,7 @@ 16.4 if (IS_ATOM_INT(x)) 16.5 return INT_VAL(x); 16.6 else if (IS_ATOM(x)) 16.7 - return (unsigned long)(DBL_PTR(x)->dbl); 16.8 + return (uintptr_t)(DBL_PTR(x)->dbl); 16.9 else { 16.10 RTFatal("%s: an integer was expected, not a sequence", where); 16.11 } 16.12 @@ -1833,7 +1833,7 @@ 16.13 } 16.14 #endif 16.15 16.16 -static object float_to_atom(object x, int flen) 16.17 +object float_to_atom(object x, int flen) 16.18 /* convert a sequence of 4, 8 or 10 bytes in IEEE format to an atom */ 16.19 { 16.20 int len, i; 16.21 @@ -2767,8 +2767,8 @@ 16.22 16.23 x_ptr = SEQ_PTR(x); 16.24 16.25 - if (IS_ATOM(x) || x_ptr->length != 12) 16.26 - RTFatal("BACKEND requires a sequence of length 12"); 16.27 + if (IS_ATOM(x) || x_ptr->length != 13) 16.28 + RTFatal("BACKEND requires a sequence of length 13"); 16.29 16.30 fe.st = (symtab_ptr) get_pos_int(w, *(x_ptr->base+1)); 16.31 fe.sl = (struct sline *) get_pos_int(w, *(x_ptr->base+2)); 16.32 @@ -2786,6 +2786,7 @@ 16.33 16.34 set_debugger( (char*) get_pos_int(w, *(x_ptr->base+12)) ); 16.35 16.36 + trace_lines = get_pos_int(w, *(x_ptr->base+13)); 16.37 // This is checked when we try to write coverage to make sure 16.38 // we need to output an error message. 16.39 in_backend = 1;
17.1 --- a/source/be_machine.h Mon Dec 19 23:19:58 2011 -0300 17.2 +++ b/source/be_machine.h Wed Dec 21 16:45:49 2011 -0300 17.3 @@ -82,4 +82,5 @@ 17.4 uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, 17.5 uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, 17.6 uintptr_t arg7, uintptr_t arg8, uintptr_t arg9); 17.7 + 17.8 #endif
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/source/be_memstruct.c Wed Dec 21 16:45:49 2011 -0300 18.3 @@ -0,0 +1,666 @@ 18.4 +#include <stdint.h> 18.5 +#include <stdio.h> 18.6 + 18.7 +#include "execute.h" 18.8 +#include "object.h" 18.9 +#include "reswords.h" 18.10 +#include "symtab.h" 18.11 +#include "be_alloc.h" 18.12 +#include "be_machine.h" 18.13 +#include "be_memstruct.h" 18.14 +#include "be_runtime.h" 18.15 + 18.16 +static object read_member( void *pointer, symtab_ptr member_sym ); 18.17 +static object read_memunion( void *pointer, symtab_ptr member_sym ); 18.18 +static int memaccess = 0; 18.19 + 18.20 +static object box_int( intptr_t x ) 18.21 +{ 18.22 + if(x > NOVALUE && x < TOO_BIG_INT) 18.23 + return (object) x; 18.24 + else 18.25 + return (object)NewDouble((eudouble)x); 18.26 +} 18.27 + 18.28 +object peek_member_value( void *pointer, int data_type, int is_signed, symtab_ptr memsym ){ 18.29 + switch( data_type ){ 18.30 + case MS_CHAR: 18.31 + if( is_signed ) return *(char*) pointer; 18.32 + else return *(unsigned char*) pointer; 18.33 + case MS_SHORT: 18.34 + if( is_signed ) return *(short*) pointer; 18.35 + else return *(unsigned short*) pointer; 18.36 + case MS_INT: 18.37 + if( is_signed ) return box_int( *(int*) pointer ); 18.38 + else return box_int( *(unsigned int*) pointer ); 18.39 + case MS_LONG: 18.40 + if( is_signed ) return box_int( *(long*) pointer ); 18.41 + else return box_int( *(unsigned long*) pointer ); 18.42 + case MS_LONGLONG: 18.43 + if( is_signed ) return box_int( *(long long int*) pointer ); 18.44 + else return box_int( *(unsigned long long int*) pointer ); 18.45 + case MS_OBJECT: 18.46 + if( is_signed ) return box_int( *(intptr_t*) pointer ); 18.47 + else return box_int( *(uintptr_t*) pointer ); 18.48 + case MS_FLOAT: 18.49 + return NewDouble( (eudouble) *(float*)pointer ); 18.50 + case MS_DOUBLE: 18.51 + return NewDouble( (eudouble) *(double*)pointer ); 18.52 + case MS_LONGDOUBLE: 18.53 + return NewDouble( (eudouble) *(long double*)pointer ); 18.54 + default: 18.55 + return read_member( pointer, memsym ); 18.56 + } 18.57 +} 18.58 + 18.59 +object peek_array( object_ptr source, symtab_ptr memsym, object_ptr subscript ){ 18.60 + uintptr_t pointer; 18.61 + int array_index; 18.62 + int data_type; 18.63 + char is_signed; 18.64 + 18.65 + pointer = get_pos_int( "memstruct array", *source ); 18.66 + array_index = get_pos_int( "memstruct array subscript", *subscript ); 18.67 + pointer += memsym->u.memstruct.offset; 18.68 + pointer += memsym->u.memstruct.size / memsym->u.memstruct.array * array_index; 18.69 + data_type = memsym->token; 18.70 + is_signed = memsym->u.memstruct.is_signed; 18.71 + if( pointer == 0 ){ 18.72 + pointer = get_pos_int( "peek member", *source ); 18.73 + } 18.74 + 18.75 + if( memsym->u.memstruct.pointer ){ 18.76 + data_type = MS_OBJECT; 18.77 + is_signed = 0; 18.78 + } 18.79 + 18.80 + return peek_member_value( (void*) pointer, data_type, is_signed, memsym ); 18.81 +} 18.82 + 18.83 +object peek_member( object_ptr source, symtab_ptr memsym, int array_index, void *pointer, intptr_t deref_ptr ){ 18.84 + int data_type; 18.85 + char is_signed; 18.86 + s1_ptr s; 18.87 + int i; 18.88 + 18.89 + data_type = memsym->token; 18.90 + is_signed = memsym->u.memstruct.is_signed; 18.91 + if( pointer == 0 ){ 18.92 + pointer = (void*) get_pos_int( "peek member", *source ); 18.93 + } 18.94 + 18.95 + if( deref_ptr ){ 18.96 + pointer = *(void**)pointer; 18.97 + } 18.98 + else if( memsym->u.memstruct.pointer ){ 18.99 + data_type = MS_OBJECT; 18.100 + is_signed = 0; 18.101 + } 18.102 + else if( array_index != -1 ){ 18.103 + uintptr_t size = memsym->u.memstruct.size; 18.104 + if( memsym->u.memstruct.array ){ 18.105 + size /= memsym->u.memstruct.array; 18.106 + } 18.107 + pointer = (void*) (((intptr_t)pointer) + (array_index * size)); 18.108 + } 18.109 + else if( memsym->u.memstruct.array ){ 18.110 + s = NewS1( memsym->u.memstruct.array ); 18.111 + for( i = 0; i < memsym->u.memstruct.array; ++i ){ 18.112 + s->base[i+1] = peek_member( 0, memsym, i, pointer, 0 ); 18.113 + } 18.114 + return MAKE_SEQ( s ); 18.115 + } 18.116 + return peek_member_value( (void*)pointer, data_type, is_signed, memsym ); 18.117 + 18.118 +} 18.119 + 18.120 +static object read_member( void *pointer, symtab_ptr member_sym ){ 18.121 + 18.122 + int token; 18.123 + 18.124 + token = member_sym->token; 18.125 + 18.126 + if( token >= MS_SIGNED && token <= MS_OBJECT ){ 18.127 + // simple serialization of primitives 18.128 + return peek_member( 0, member_sym, -1, pointer, 0 ); 18.129 + } 18.130 + 18.131 + token = member_sym->token; 18.132 + while(1){ 18.133 + // should only go twice through at most 18.134 + if( token == MEMSTRUCT ){ 18.135 + return read_memstruct( 0, pointer, member_sym ); 18.136 + } 18.137 + else if( token == MEMUNION ){ 18.138 + return read_memunion( pointer, member_sym ); 18.139 + } 18.140 + 18.141 + // get the member's actual struct 18.142 + token = member_sym->u.memstruct.struct_type->token; 18.143 + } 18.144 +} 18.145 + 18.146 +static object read_memunion( void *pointer, symtab_ptr member_sym ){ 18.147 + s1_ptr s; 18.148 + int size; 18.149 + int i; 18.150 + unsigned char *source; 18.151 + object_ptr target; 18.152 + 18.153 + source = (unsigned char*) pointer; 18.154 + size = member_sym->u.memstruct.size; 18.155 + s = NewS1( size ); 18.156 + target = s->base; 18.157 + for( i = 1; i <= size; ++i ){ 18.158 + *(++target) = *(source++); 18.159 + } 18.160 + return MAKE_SEQ( s ); 18.161 +} 18.162 + 18.163 +object read_memstruct( object_ptr source, void *pointer, symtab_ptr member_sym ){ 18.164 + symtab_ptr sym; 18.165 + int size; 18.166 + s1_ptr s; 18.167 + uintptr_t src_pointer; 18.168 + 18.169 + if( pointer == 0 ){ 18.170 + src_pointer = (uintptr_t)get_pos_int( "read memstruct", *source ); 18.171 + } 18.172 + else{ 18.173 + src_pointer = (uintptr_t) pointer; 18.174 + } 18.175 + 18.176 + if( member_sym->token == MEMUNION ){ 18.177 + // Unions are handled specially 18.178 + int i; 18.179 + unsigned char *target; 18.180 + 18.181 + size = member_sym->u.memstruct.size; 18.182 + target = (unsigned char*) src_pointer; 18.183 + s = NewS1( size ); 18.184 + for( i = 1; i <= size; ++i, ++target ){ 18.185 + s->base[i] = (object) *target; 18.186 + } 18.187 + } 18.188 + else{ 18.189 + if( member_sym->token != MEMSTRUCT ){ 18.190 + member_sym = member_sym->u.memstruct.struct_type; 18.191 + } 18.192 + size = 0; 18.193 + for( sym = member_sym->u.memstruct.next; sym != 0; sym = sym->u.memstruct.next ){ 18.194 + ++size; 18.195 + } 18.196 + s = NewS1( size ); 18.197 + size = 0; 18.198 + for( sym = member_sym->u.memstruct.next; sym != 0; sym = sym->u.memstruct.next ){ 18.199 + pointer = (void*) (src_pointer + sym->u.memstruct.offset); 18.200 + s->base[++size] = peek_member( 0, sym, -1, pointer, 0 ); 18.201 + 18.202 + } 18.203 + } 18.204 + return MAKE_SEQ( s ); 18.205 +} 18.206 +void write_member( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ){ 18.207 + s1_ptr src; 18.208 + int free_src; 18.209 + symtab_ptr member; 18.210 + int i; 18.211 + uintptr_t pointer, src_pointer; 18.212 + intptr_t zero; 18.213 + #if INTPTR_MAX == INT32_MAX 18.214 + struct d dbl; 18.215 + object dbl_ptr; 18.216 + dbl_ptr = MAKE_DBL( &dbl ); 18.217 + dbl.ref = -1; 18.218 + #endif 18.219 + zero = 0; 18.220 + 18.221 + if( IS_ATOM_INT( *val ) || IS_ATOM( *val ) ){ 18.222 + src = NewS1( 1 ); 18.223 + src->base[1] = *val; 18.224 + free_src = 1; 18.225 + } 18.226 + else{ 18.227 + src = SEQ_PTR( *val ); 18.228 + free_src = 0; 18.229 + } 18.230 + 18.231 + src_pointer = (uintptr_t)get_pos_int( "write member", *source ); 18.232 + if( deref_ptr ){ 18.233 + src_pointer = *(uintptr_t*) src_pointer; 18.234 + } 18.235 + for( member = sym->u.memstruct.next, i = 1; member && i <= src->length; ++i, member = member->u.memstruct.next ){ 18.236 + pointer = src_pointer + member->u.memstruct.offset; 18.237 + #if INTPTR_MAX == INT32_MAX 18.238 + if( IS_ATOM_INT( (intptr_t)pointer ) ) 18.239 + #endif 18.240 + poke_member( (object_ptr)&pointer, member, src->base + i, 0 ); 18.241 + #if INTPTR_MAX == INT32_MAX 18.242 + else{ 18.243 + dbl.dbl = (eudouble) pointer; 18.244 + poke_member( &dbl_ptr, member, src->base + i ); 18.245 + } 18.246 + #endif 18.247 + 18.248 + } 18.249 + 18.250 + // Zero out the rest... 18.251 + for( ; member; ++i, member = member->u.memstruct.next ){ 18.252 + pointer = src_pointer + member->u.memstruct.offset; 18.253 + #if INTPTR_MAX == INT32_MAX 18.254 + if( IS_ATOM_INT( (intptr_t)pointer ) ) 18.255 + #endif 18.256 + poke_member( (object_ptr)&pointer, member, &zero, 0); 18.257 + #if INTPTR_MAX == INT32_MAX 18.258 + else{ 18.259 + dbl.dbl = (eudouble) pointer; 18.260 + poke_member( &dbl_ptr, member, &zero, 0); 18.261 + } 18.262 + #endif 18.263 + } 18.264 + 18.265 + if( free_src ){ 18.266 + EFree( (char*)src ); 18.267 + } 18.268 +} 18.269 + 18.270 + 18.271 +void write_union( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ){ 18.272 + 18.273 + s1_ptr src; 18.274 + int free_src; 18.275 + int i; 18.276 + char *pointer; 18.277 + 18.278 + if( IS_ATOM_INT( *val ) || IS_ATOM( *val ) ){ 18.279 + src = NewS1( 1 ); 18.280 + src->base[1] = *val; 18.281 + free_src = 1; 18.282 + } 18.283 + else{ 18.284 + src = SEQ_PTR( *val ); 18.285 + free_src = 0; 18.286 + } 18.287 + 18.288 + pointer = (char*)get_pos_int( "write union", *source ); 18.289 + if( deref_ptr ){ 18.290 + pointer = *(char**) pointer; 18.291 + } 18.292 + for( i = 1; i <= src->length && i <= sym->u.memstruct.size; ++i, ++pointer ){ 18.293 + *pointer = src->base[i]; 18.294 + } 18.295 + 18.296 + // Zero out the rest... 18.297 + for( ; i <= sym->u.memstruct.size; ++i, ++pointer ){ 18.298 + *pointer = 0; 18.299 + } 18.300 + 18.301 + if( free_src ){ 18.302 + EFree( (char*)src ); 18.303 + } 18.304 +} 18.305 + 18.306 +static uintptr_t mem_access( int access_count, object_ptr source, symtab_ptr *access_sym ){ 18.307 + uintptr_t pointer; 18.308 + int i; 18.309 + 18.310 + pointer = (uintptr_t)get_pos_int( "memstruct access", *source ); 18.311 + for( i = 0; i < access_count; ++i ){ 18.312 + pointer += access_sym[i]->u.memstruct.offset; 18.313 + if( access_sym[i]->u.memstruct.pointer && (i+1) < access_count ){ 18.314 + pointer = *(uintptr_t*)pointer; 18.315 + } 18.316 + } 18.317 + return pointer; 18.318 +} 18.319 +object memstruct_access( int access_count, object_ptr source, symtab_ptr *access_sym ){ 18.320 + uintptr_t pointer; 18.321 + memaccess = MEMSTRUCT_ACCESS; 18.322 + pointer = mem_access( access_count, source, access_sym ); 18.323 + return box_int( pointer ); 18.324 +} 18.325 + 18.326 +object array_access( int access_count, object_ptr source, symtab_ptr *access_sym, symtab_ptr subscript ){ 18.327 + uintptr_t pointer; 18.328 + uintptr_t element_size; 18.329 + intptr_t sub_val; 18.330 + memaccess = ARRAY_ACCESS; 18.331 + pointer = mem_access( access_count, source, access_sym ); 18.332 + element_size = access_sym[access_count-1]->u.memstruct.size; 18.333 + if( access_sym[access_count-1]->u.memstruct.array ){ 18.334 + element_size /= access_sym[access_count-1]->u.memstruct.array; 18.335 + } 18.336 + sub_val = get_pos_int( "array access subscript", subscript->obj); 18.337 + pointer += sub_val * element_size; 18.338 + return box_int( pointer ); 18.339 +} 18.340 + 18.341 +object memstruct_array( object_ptr source, symtab_ptr sym, object_ptr subscript ){ 18.342 + uintptr_t pointer; 18.343 + int array_index; 18.344 + 18.345 + pointer = get_pos_int( "memstruct array", *source ); 18.346 + array_index = get_pos_int( "memstruct array subscript", *subscript ); 18.347 + 18.348 + pointer += sym->u.memstruct.size * array_index; 18.349 + return box_int( pointer ); 18.350 +} 18.351 + 18.352 +static void poke_member_value( void *pointer, int data_type, object_ptr val, int is_signed ){ 18.353 + eudouble d; 18.354 + switch( data_type ){ 18.355 + case MS_CHAR: 18.356 + if( is_signed) *(char*)pointer = (char) get_pos_int( "store char data", *val ); 18.357 + else *(unsigned char*)pointer = (unsigned char) get_pos_int( "store char data", *val ); 18.358 + break; 18.359 + case MS_SHORT: 18.360 + if( is_signed) *(short*)pointer = (short) get_pos_int( "store short data", *val ); 18.361 + else *(unsigned short*)pointer = (unsigned short) get_pos_int( "store short data", *val ); 18.362 + break; 18.363 + case MS_INT: 18.364 + if( is_signed) *(int*)pointer = (int) get_pos_int( "store int data", *val ); 18.365 + else *(unsigned int*)pointer = (unsigned int) get_pos_int( "store int data", *val ); 18.366 + break; 18.367 + case MS_LONG: 18.368 + if( is_signed) *(long*)pointer = (long) get_pos_int( "store long data", *val ); 18.369 + else *(unsigned long*)pointer = (unsigned long) get_pos_int( "store long data", *val ); 18.370 + break; 18.371 + case MS_LONGLONG: 18.372 + if( is_signed) *(long long*)pointer = (long long) get_pos_int( "store long long int data", *val ); 18.373 + else *(unsigned long long*)pointer = (unsigned long long) get_pos_int( "store long long int data", *val ); 18.374 + break; 18.375 + case MS_OBJECT: 18.376 + if( is_signed) *(intptr_t*)pointer = (intptr_t) get_pos_int( "store object data", *val ); 18.377 + else *(uintptr_t*)pointer = (uintptr_t) get_pos_int( "store object data", *val ); 18.378 + break; 18.379 + case MS_FLOAT: 18.380 + case MS_DOUBLE: 18.381 + case MS_LONGDOUBLE: 18.382 + case MS_EUDOUBLE: 18.383 + if( IS_ATOM_INT( *val ) ){ 18.384 + d = (eudouble) *val; 18.385 + } 18.386 + else if( IS_ATOM( *val ) ){ 18.387 + d = DBL_PTR( *val )->dbl; 18.388 + } 18.389 + else{ 18.390 + RTFatal( "Trying to store a sequence into a floating point memory location" ); 18.391 + } 18.392 + if( data_type == MS_DOUBLE ){ 18.393 + *(double*)pointer = d; 18.394 + } 18.395 + else if( data_type == MS_FLOAT ){ 18.396 + *(float*)pointer = (float)d; 18.397 + } 18.398 + if( data_type == MS_EUDOUBLE ){ 18.399 + *(eudouble*)pointer = d; 18.400 + } 18.401 + if( data_type == MS_LONGDOUBLE ){ 18.402 +#ifdef __GNUC__ 18.403 + *(long double*)pointer = d; 18.404 +#else 18.405 + RTFatal( "long doubles not implemented yet for storing into memory on non-gcc compilers" ); 18.406 +#endif 18.407 + } 18.408 + break; 18.409 + default: 18.410 + RTFatal( "Error assigning to a memstruct (%s) -- can only assign primitive data members" ); 18.411 + } 18.412 +} 18.413 + 18.414 + 18.415 +void poke_member( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ){ 18.416 + int data_type; 18.417 + int is_signed; 18.418 + uintptr_t pointer; 18.419 + 18.420 + data_type = sym->token; 18.421 + while( data_type == MEMTYPE ){ 18.422 + sym = sym->u.memstruct.parent; 18.423 + data_type = sym->token; 18.424 + } 18.425 + is_signed = sym->u.memstruct.is_signed; 18.426 + 18.427 + 18.428 + 18.429 + pointer = get_pos_int( "storing memory data", *source ); 18.430 + if( deref_ptr ){ 18.431 + pointer = *(uintptr_t*) pointer; 18.432 + } 18.433 + else if( sym->u.memstruct.pointer ){ 18.434 + data_type = MS_OBJECT; 18.435 + is_signed = 0; 18.436 + } 18.437 + 18.438 + if( sym->u.memstruct.array ){ 18.439 + 18.440 + 18.441 + if( memaccess == ARRAY_ACCESS ){ 18.442 + poke_member_value( (void*)pointer, data_type, val, is_signed ); 18.443 + } 18.444 + else{ 18.445 + int i, array_length, max, size; 18.446 + s1_ptr v; 18.447 + intptr_t zero = 0; 18.448 + array_length = sym->u.memstruct.array; 18.449 + size = sym->u.memstruct.size / array_length; 18.450 + if( IS_ATOM( *val ) ){ 18.451 + RTFatal( "expected a sequence to assign to the array" ); 18.452 + } 18.453 + v = SEQ_PTR( *val ); 18.454 + max = v->length; 18.455 + if( max > array_length ){ 18.456 + max = array_length; 18.457 + } 18.458 + 18.459 + for( i = 0; i < max; ++i ){ 18.460 + poke_member_value( (void*)pointer, data_type, v->base + i + 1, is_signed ); 18.461 + pointer += size; 18.462 + } 18.463 + for( ; i < array_length; ++i ){ 18.464 + poke_member_value( (void*)pointer, data_type, (object_ptr)&zero, is_signed ); 18.465 + pointer += size; 18.466 + } 18.467 + } 18.468 + } 18.469 + else{ 18.470 + poke_member_value( (void*)pointer, data_type, val, is_signed ); 18.471 + } 18.472 + 18.473 +} 18.474 + 18.475 +#define CALCULATE( type ) \ 18.476 + type a, c;\ 18.477 + a = *( type *) pointer;\ 18.478 + if( IS_ATOM_INT( *opnd ) ){\ 18.479 + c = (type) *opnd;\ 18.480 + }\ 18.481 + else if( IS_ATOM( *opnd ) ){\ 18.482 + c = (type) DBL_PTR( *opnd )->dbl;\ 18.483 + }\ 18.484 + else{\ 18.485 + c = (type) get_pos_int( "assign op for object", *opnd );\ 18.486 + }\ 18.487 + switch( op ){\ 18.488 + case MEMSTRUCT_PLUS:\ 18.489 + a += c;\ 18.490 + break;\ 18.491 + case MEMSTRUCT_MINUS:\ 18.492 + a -= c;\ 18.493 + break;\ 18.494 + case MEMSTRUCT_MULTIPLY:\ 18.495 + a *= c;\ 18.496 + break;\ 18.497 + case MEMSTRUCT_DIVIDE:\ 18.498 + if( !c ){\ 18.499 + RTFatal("attempt to divide by zero");\ 18.500 + }\ 18.501 + a /= c;\ 18.502 + break;\ 18.503 + default:\ 18.504 + RTFatal("illegal assign op");\ 18.505 + }\ 18.506 + *(type*) pointer = a; 18.507 +void ms_char( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.508 + 18.509 + if( is_signed ){ 18.510 + CALCULATE( char ) 18.511 + } 18.512 + else{ 18.513 + CALCULATE( unsigned char ) 18.514 + } 18.515 +} 18.516 + 18.517 +void ms_short( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.518 + 18.519 + if( is_signed ){ 18.520 + CALCULATE( short ) 18.521 + } 18.522 + else{ 18.523 + CALCULATE( unsigned short ) 18.524 + } 18.525 +} 18.526 + 18.527 + 18.528 +void ms_int( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.529 + 18.530 + if( is_signed ){ 18.531 + CALCULATE( int ) 18.532 + } 18.533 + else{ 18.534 + CALCULATE( unsigned int ) 18.535 + } 18.536 +} 18.537 + 18.538 +void ms_long( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.539 + 18.540 + if( is_signed ){ 18.541 + CALCULATE( long ) 18.542 + } 18.543 + else{ 18.544 + CALCULATE( unsigned long ) 18.545 + } 18.546 +} 18.547 + 18.548 + 18.549 +void ms_longlong( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.550 + 18.551 + if( is_signed ){ 18.552 + CALCULATE( long long int ) 18.553 + } 18.554 + else{ 18.555 + CALCULATE( unsigned long long int ) 18.556 + } 18.557 +} 18.558 + 18.559 + 18.560 +void ms_object( intptr_t op, void* pointer, object_ptr opnd, char is_signed ){ 18.561 + 18.562 + if( is_signed ){ 18.563 + CALCULATE( intptr_t ) 18.564 + } 18.565 + else{ 18.566 + CALCULATE( uintptr_t ) 18.567 + } 18.568 +} 18.569 + 18.570 +#define FLOAT_CALCULATE( type ) \ 18.571 + type a, c;\ 18.572 + if( IS_ATOM_INT( *opnd ) ){\ 18.573 + c = (type) *opnd;\ 18.574 + }\ 18.575 + else if( IS_ATOM( *opnd ) ){\ 18.576 + c = (type) DBL_PTR( *opnd )->dbl;\ 18.577 + }\ 18.578 + else{\ 18.579 + RTFatal( "Trying to assign a sequence to ##type data" );\ 18.580 + }\ 18.581 + a = *(type*)pointer;\ 18.582 + switch( op ){\ 18.583 + case MEMSTRUCT_PLUS:\ 18.584 + a += c;\ 18.585 + break;\ 18.586 + case MEMSTRUCT_MINUS:\ 18.587 + a -= c;\ 18.588 + break;\ 18.589 + case MEMSTRUCT_MULTIPLY:\ 18.590 + a *= c;\ 18.591 + break;\ 18.592 + case MEMSTRUCT_DIVIDE:\ 18.593 + if( c == (type) 0 ){\ 18.594 + RTFatal("attempt to divide by zero");\ 18.595 + }\ 18.596 + a /= c;\ 18.597 + break;\ 18.598 + default:\ 18.599 + RTFatal("illegal assign op");\ 18.600 + }\ 18.601 + *(type*)pointer = a; 18.602 + 18.603 +void ms_float( intptr_t op, void* pointer, object_ptr opnd ){ 18.604 + FLOAT_CALCULATE( float ) 18.605 +} 18.606 + 18.607 +void ms_double( intptr_t op, void* pointer, object_ptr opnd ){ 18.608 + FLOAT_CALCULATE( double ) 18.609 +} 18.610 + 18.611 +void ms_longdouble( intptr_t op, void* pointer, object_ptr opnd ){ 18.612 +#ifdef __GNUC__ 18.613 + FLOAT_CALCULATE( long double ) 18.614 +#else 18.615 + // TODO: convert to doubles and do arithmetic that way? Or more machine code hacks? 18.616 + RTFatal( "Extended precision arithmetic not available" ); 18.617 +#endif 18.618 +} 18.619 + 18.620 +void ms_eudouble( intptr_t op, void* pointer, object_ptr opnd ){ 18.621 + FLOAT_CALCULATE( eudouble ) 18.622 +} 18.623 + 18.624 +void memstruct_assignop( intptr_t op, object_ptr source, symtab_ptr sym, object_ptr opnd, intptr_t deref_ptr ){ 18.625 + void *pointer; 18.626 + char is_signed; 18.627 + 18.628 + pointer = (void*) get_pos_int( "memstruct assign op", *source ); 18.629 + if( deref_ptr ){ 18.630 + pointer = *(void**)pointer; 18.631 + } 18.632 + is_signed = sym->u.memstruct.is_signed; 18.633 + 18.634 + switch( sym->token ){ 18.635 + case MS_CHAR: 18.636 + ms_char( op, pointer, opnd, is_signed ); 18.637 + break; 18.638 + case MS_SHORT: 18.639 + ms_short( op, pointer, opnd, is_signed ); 18.640 + break; 18.641 + case MS_INT: 18.642 + ms_int( op, pointer, opnd, is_signed ); 18.643 + break; 18.644 + case MS_LONG: 18.645 + ms_long( op, pointer, opnd, is_signed ); 18.646 + break; 18.647 + case MS_LONGLONG: 18.648 + ms_longlong( op, pointer, opnd, is_signed ); 18.649 + break; 18.650 + case MS_OBJECT: 18.651 + ms_object( op, pointer, opnd, is_signed ); 18.652 + break; 18.653 + case MS_FLOAT: 18.654 + ms_float( op, pointer, opnd ); 18.655 + break; 18.656 + case MS_DOUBLE: 18.657 + ms_double( op, pointer, opnd ); 18.658 + break; 18.659 + case MS_LONGDOUBLE: 18.660 + ms_longdouble( op, pointer, opnd ); 18.661 + break; 18.662 + case MS_EUDOUBLE: 18.663 + ms_eudouble( op, pointer, opnd ); 18.664 + break; 18.665 + default: 18.666 + RTFatal( "Target of the assignment must be a primitive data type" ); 18.667 + } 18.668 + 18.669 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/source/be_memstruct.h Wed Dec 21 16:45:49 2011 -0300 19.3 @@ -0,0 +1,22 @@ 19.4 +#ifndef BE_MEMSTRUCT_H_ 19.5 +#define BE_MEMSTRUCT_H_ 19.6 + 19.7 +#include "execute.h" 19.8 +#include "object.h" 19.9 +#include "symtab.h" 19.10 + 19.11 +object peek_member( object_ptr source, symtab_ptr memsym, int array_index, void *pointer, intptr_t deref_ptr ); 19.12 +void poke_member( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ); 19.13 +void write_member( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ); 19.14 +void write_union( object_ptr source, symtab_ptr sym, object_ptr val, intptr_t deref_ptr ); 19.15 + 19.16 +object memstruct_array( object_ptr source, symtab_ptr sym, object_ptr subscript ); 19.17 +object peek_array( object_ptr source, symtab_ptr sym, object_ptr subscript ); 19.18 +object memstruct_access( int access_count, object_ptr source, symtab_ptr* access_sym ); 19.19 +object array_access( int access_count, object_ptr source, symtab_ptr* access_sym, symtab_ptr subscript_sym ); 19.20 +object read_memstruct( object_ptr source, void *pointer, symtab_ptr member_sym ); 19.21 + 19.22 + 19.23 +void memstruct_assignop( intptr_t op, object_ptr source, symtab_ptr sym, object_ptr opnd, intptr_t deref_ptr ); 19.24 + 19.25 +#endif
20.1 --- a/source/be_rterror.c Mon Dec 19 23:19:58 2011 -0300 20.2 +++ b/source/be_rterror.c Wed Dec 21 16:45:49 2011 -0300 20.3 @@ -93,6 +93,7 @@ 20.4 int file_trace; /* log statements to ctrace.out */ 20.5 int trace_enabled = TRUE; /* flag to disable tracing */ 20.6 char *type_error_msg = "\ntype_check failure, "; /* changeable message */ 20.7 +char *type_check_sym = NULL; /* used for memstruct type check errors */ 20.8 20.9 /*******************/ 20.10 /* Local variables */ 20.11 @@ -1200,7 +1201,11 @@ 20.12 } 20.13 else { 20.14 sf_output(type_error_msg); // test 20.15 - snprintf(TPTempBuff, TPTEMP_BUFF_SIZE, "%s is ", s_ptr->name); 20.16 + if( type_check_sym == NULL ){ 20.17 + type_check_sym = s_ptr->name; 20.18 + } 20.19 + snprintf(TPTempBuff, TPTEMP_BUFF_SIZE, "%s is ", type_check_sym); 20.20 + 20.21 TPTempBuff[TPTEMP_BUFF_SIZE-1] = 0; 20.22 sf_output(TPTempBuff); 20.23 if (screen_err_out) 20.24 @@ -1414,6 +1419,15 @@ 20.25 va_end(ap); 20.26 } 20.27 20.28 +void RTFatalMemType(intptr_t *pc, intptr_t member){ 20.29 + symtab_ptr s_ptr; 20.30 + tpc = pc; /* points within the offending assignment/parm setting */ 20.31 + s_ptr = *(symtab_ptr *)pc; 20.32 + type_check_sym = ((symtab_ptr)member)->name; 20.33 + CleanUpError(NULL, s_ptr); 20.34 + 20.35 +} 20.36 + 20.37 void RTFatalType(intptr_t *pc) 20.38 /* handle type-check failures */ 20.39 /* pc points to variable in instruction stream */
21.1 --- a/source/be_rterror.h Mon Dec 19 23:19:58 2011 -0300 21.2 +++ b/source/be_rterror.h Wed Dec 21 16:45:49 2011 -0300 21.3 @@ -4,7 +4,13 @@ 21.4 #include <stdint.h> 21.5 21.6 void RTFatalType(intptr_t *pc) 21.7 -#ifdef EUNIX 21.8 +#ifdef __GNUC__ 21.9 +__attribute__ ((noreturn)) 21.10 +#endif 21.11 +; 21.12 + 21.13 +void RTFatalMemType(intptr_t *pc, intptr_t member) 21.14 +#ifdef __GNUC__ 21.15 __attribute__ ((noreturn)) 21.16 #endif 21.17 ; 21.18 @@ -38,7 +44,7 @@ 21.19 void NoValue(symtab_ptr s); 21.20 21.21 void CleanUpError_va(char *msg, symtab_ptr s_ptr, va_list ap) 21.22 -#if defined(EUNIX) || defined(EMINGW) 21.23 +#ifdef __GNUC__ 21.24 __attribute__ ((noreturn)) 21.25 #else 21.26 #pragma aux CleanUpError_va aborts;
22.1 --- a/source/be_runtime.c Mon Dec 19 23:19:58 2011 -0300 22.2 +++ b/source/be_runtime.c Wed Dec 21 16:45:49 2011 -0300 22.3 @@ -4590,6 +4590,7 @@ 22.4 22.5 static int trace_line = 0; 22.6 static IFILE trace_file; 22.7 +int trace_lines = 500; 22.8 22.9 static void one_trace_line(char *line) 22.10 /* write a line to the ctrace.out file */ 22.11 @@ -4615,7 +4616,7 @@ 22.12 } 22.13 if (trace_file != NULL) { 22.14 trace_line++; 22.15 - if (trace_line >= 500) { 22.16 + if (trace_line >= trace_lines) { 22.17 one_trace_line(""); 22.18 one_trace_line(" "); // erase THE END 22.19 trace_line = 0;
23.1 --- a/source/be_runtime.h Mon Dec 19 23:19:58 2011 -0300 23.2 +++ b/source/be_runtime.h Wed Dec 21 16:45:49 2011 -0300 23.3 @@ -50,6 +50,8 @@ 23.4 23.5 extern struct op_info optable[MAX_OPCODE+1]; 23.6 23.7 +extern int trace_lines; 23.8 + 23.9 void debug_msg(char *msg); 23.10 23.11 void UserCleanup(int status)
24.1 --- a/source/c_decl.e Mon Dec 19 23:19:58 2011 -0300 24.2 +++ b/source/c_decl.e Wed Dec 21 16:45:49 2011 -0300 24.3 @@ -1162,7 +1162,8 @@ 24.4 24.5 c_puts("#include \"include/euphoria.h\"\n") 24.6 24.7 - c_puts("#include \"main-.h\"\n\n") 24.8 + c_puts("#include \"main-.h\"\n") 24.9 + c_puts("#include \"struct.h\"\n\n") 24.10 24.11 if not TUNIX then 24.12 name = lower(name) -- for faster compare later
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/source/c_struct.e Wed Dec 21 16:45:49 2011 -0300 25.3 @@ -0,0 +1,1086 @@ 25.4 +-- Translator code for dealing with memstructs 25.5 + 25.6 +include c_decl.e 25.7 +include c_out.e 25.8 +include compile.e 25.9 +include emit.e 25.10 +include error.e 25.11 +include global.e 25.12 +include reswords.e 25.13 +include symtab.e 25.14 + 25.15 +-- Use this to communicate between ops so we can avoid changing 25.16 +-- pointers into doubles. 25.17 +sequence target_is_pointer = {} 25.18 + 25.19 +integer memaccess = 0 25.20 + 25.21 +function is_pointer( integer pointer ) 25.22 + return find( pointer, target_is_pointer ) 25.23 +end function 25.24 + 25.25 +procedure add_pointer( integer pointer ) 25.26 + if not is_pointer( pointer ) then 25.27 + target_is_pointer &= pointer 25.28 + end if 25.29 +end procedure 25.30 + 25.31 +procedure remove_pointer( integer pointer ) 25.32 + integer px = is_pointer( pointer ) 25.33 + if px then 25.34 + target_is_pointer = remove( target_is_pointer, px ) 25.35 + end if 25.36 +end procedure 25.37 + 25.38 + 25.39 +function struct_type( symtab_index sym ) 25.40 + sym = SymTab[sym][S_MEM_PARENT] 25.41 + integer token = sym_token( sym ) 25.42 + sequence type_name = "" 25.43 + if token = MEMSTRUCT then 25.44 + type_name &= "struct " 25.45 + else 25.46 + type_name &= "union " 25.47 + end if 25.48 + return type_name & decorated_name( sym ) 25.49 +end function 25.50 + 25.51 +procedure get_pointer( integer pointer, integer target ) 25.52 + if not is_pointer( target ) and pointer != target then 25.53 + CDeRef( target ) 25.54 + end if 25.55 + 25.56 + if is_pointer( pointer ) then 25.57 + if target != pointer then 25.58 + 25.59 + c_stmt( "@ = @;\n", {target, pointer}, target ) 25.60 + end if 25.61 + else 25.62 + c_stmt( "_0 = @;\n", pointer ) 25.63 + 25.64 + if not TypeIs( pointer, TYPE_INTEGER ) then 25.65 + c_stmt0("if( !IS_ATOM_INT( _0 ) ){\n" ) 25.66 + c_stmt0("_0 = (intptr_t) DBL_PTR( _0 )->dbl;\n" ) 25.67 + c_stmt0( "}\n") 25.68 + end if 25.69 + 25.70 + c_stmt( "@ = _0;\n", target, target ) 25.71 + if target != pointer then 25.72 + dispose_temp( pointer, compile:DISCARD_TEMP, REMOVE_FROM_MAP ) 25.73 + end if 25.74 + end if 25.75 + 25.76 + add_pointer( target ) 25.77 + SetBBType( target, TYPE_INTEGER, {MININT, MAXINT}, TYPE_INTEGER, 0 ) 25.78 + 25.79 +end procedure 25.80 + 25.81 +procedure mem_access( integer access_count, integer pointer, integer target ) 25.82 + get_pointer( pointer, target ) 25.83 + symtab_index sym = Code[pc+3] 25.84 + 25.85 + c_stmt( sprintf("@ = (intptr_t) &(((%s*)@)",{struct_type(sym)}), { target, target }, target ) 25.86 + 25.87 + integer 25.88 + first_pc = pc + 3, 25.89 + last_pc = pc + 2 + access_count, 25.90 + was_pointer = 1 25.91 + 25.92 + for i = first_pc to last_pc do 25.93 + if was_pointer then 25.94 + c_puts("->") 25.95 + else 25.96 + c_puts(".") 25.97 + end if 25.98 + CName( Code[i] ) 25.99 + was_pointer = SymTab[Code[i]][S_MEM_POINTER] 25.100 + end for 25.101 + c_puts( ");\n") 25.102 +end procedure 25.103 + 25.104 +export procedure opARRAY_ACCESS() 25.105 + integer 25.106 + access_count = Code[pc+1], 25.107 + pointer = Code[pc+2], 25.108 + subscript = Code[pc + 3 + access_count], 25.109 + target = Code[pc + 4 + access_count] 25.110 + mem_access( access_count, pointer, target ) 25.111 + memaccess = ARRAY_ACCESS 25.112 + symtab_index sym = Code[pc + 2 + access_count] 25.113 + c_stmt( sprintf("@ = (intptr_t) (((%s *)@) + @);\n",{get_data_type(sym)}), { target, target, subscript }, target ) 25.114 + 25.115 + pc += access_count + 5 25.116 +end procedure 25.117 + 25.118 +export procedure opMEMSTRUCT_ACCESS() 25.119 + integer 25.120 + access_count = Code[pc+1], 25.121 + pointer = Code[pc+2], 25.122 + target = Code[pc+ 3 + access_count] 25.123 + 25.124 + mem_access( access_count, pointer, target ) 25.125 + memaccess = MEMSTRUCT_ACCESS 25.126 + pc += access_count + 4 25.127 +end procedure 25.128 + 25.129 +export procedure opMEMSTRUCT_ARRAY() 25.130 + integer 25.131 + pointer = Code[pc+1], 25.132 + member = Code[pc+2], 25.133 + subscript = Code[pc+3], 25.134 + target = Code[pc+4] 25.135 + 25.136 + get_pointer( pointer, target ) 25.137 + sequence type_name 25.138 + integer data_type = sym_token( member ) 25.139 + switch data_type do 25.140 + case MS_MEMBER then 25.141 + member = SymTab[member][S_MEM_STRUCT] 25.142 + fallthru 25.143 + 25.144 + case MEMSTRUCT, MEMUNION then 25.145 + sequence tag 25.146 + if data_type = MEMSTRUCT then 25.147 + tag = "struct" 25.148 + else 25.149 + tag = "union" 25.150 + end if 25.151 + type_name = sprintf( "%s %s", { tag, decorated_name( member ) } ) 25.152 + case else 25.153 + type_name = mem_name( data_type ) 25.154 + end switch 25.155 + 25.156 + integer is_integer = TypeIs( subscript, TYPE_INTEGER ) 25.157 + if not is_integer then 25.158 + c_stmt("if( IS_ATOM_INT( @ ) ){\n", subscript ) 25.159 + end if 25.160 + c_stmt("_1 = @;\n", subscript ) 25.161 + 25.162 + if not is_integer then 25.163 + c_stmt0( "}\n" ) 25.164 + c_stmt0( "else{\n" ) 25.165 + c_stmt( "_1 = (intptr_t)DBL_PTR( @ )->dbl;\n", subscript ) 25.166 + c_stmt0( "}\n" ) 25.167 + end if 25.168 + 25.169 + dispose_temp( subscript, compile:DISCARD_TEMP, REMOVE_FROM_MAP ) 25.170 + c_stmt( sprintf( "@ = (intptr_t) &(((%s*)@)[_1]);\n", { type_name } ), { target, target }, target ) 25.171 + 25.172 + pc += 5 25.173 +end procedure 25.174 + 25.175 +function get_tagged_name( symtab_index sym ) 25.176 + sequence tag 25.177 + 25.178 + while sym_token( sym ) = MEMTYPE do 25.179 + sym = SymTab[S_MEM_PARENT] 25.180 + end while 25.181 + 25.182 + if SymTab[sym][S_TOKEN] = MEMSTRUCT then 25.183 + tag = "struct" 25.184 + else 25.185 + tag = "union" 25.186 + end if 25.187 + return sprintf( "%s %s", { tag, decorated_name( sym ) } ) 25.188 +end function 25.189 + 25.190 +export procedure opPEEK_ARRAY() 25.191 + integer 25.192 + pointer = Code[pc+1], 25.193 + sym = Code[pc+2], 25.194 + subscript = Code[pc+3], 25.195 + target = Code[pc+4], 25.196 + parent = SymTab[sym][S_MEM_PARENT] 25.197 + 25.198 + integer data_type = SymTab[sym][S_TOKEN] 25.199 + integer signed = SymTab[sym][S_MEM_SIGNED] 25.200 + integer is_pointer = SymTab[sym][S_MEM_POINTER] 25.201 + sequence type_name, struct_name 25.202 + 25.203 + get_pointer( pointer, target ) 25.204 + 25.205 + struct_name = get_tagged_name( parent ) 25.206 + 25.207 + switch data_type do 25.208 + case MS_MEMBER then 25.209 + sym = SymTab[sym][S_MEM_STRUCT] 25.210 + fallthru 25.211 + 25.212 + case MEMSTRUCT, MEMUNION then 25.213 + type_name = struct_name 25.214 + case else 25.215 + type_name = mem_name( data_type ) 25.216 + end switch 25.217 + 25.218 + sequence array_modifier = "[_1]" 25.219 + integer index_is_int = TypeIs( subscript, TYPE_INTEGER) 25.220 + if not index_is_int then 25.221 + c_stmt("if( !IS_ATOM_INT( @ ) && IS_ATOM( @ ) ){\n", { subscript, subscript}, subscript ) 25.222 + c_stmt("_1 = (intptr_t)DBL_PTR( @)->dbl;\n", { subscript }) 25.223 + c_stmt0("}\n") 25.224 + c_stmt0("else{\n") 25.225 + end if 25.226 + c_stmt( "_1 = @;\n", { subscript } ) 25.227 + if not index_is_int then 25.228 + c_stmt0("}\n") 25.229 + end if 25.230 + 25.231 + c_stmt( sprintf("@ = (intptr_t)&((%s *)@)->%s;\n", {struct_name, decorated_name( sym ) }), { target, target } ) 25.232 + 25.233 + peek_member_value( target, sym, data_type, is_pointer, array_modifier, type_name, signed, target ) 25.234 + remove_pointer( pointer ) 25.235 + remove_pointer( target ) 25.236 + 25.237 + pc += 5 25.238 +end procedure 25.239 + 25.240 +--** 25.241 +-- Stores the value pointed to by _0 into the target. If target is 0, 25.242 +-- then the caller has already emitted the LHS, and peek_member will 25.243 +-- only print the RHS. 25.244 +procedure peek_member( integer pointer, integer sym, integer target, integer array_index = -1, integer deref_ptr = 0 ) 25.245 + integer data_type = SymTab[sym][S_TOKEN] 25.246 + integer signed = SymTab[sym][S_MEM_SIGNED] 25.247 + integer is_pointer = SymTab[sym][S_MEM_POINTER] 25.248 + sequence type_name 25.249 + sequence array_modifier = "" 25.250 + 25.251 + type_name = mem_name( sym_token( sym ) ) 25.252 + if is_pointer and not deref_ptr then 25.253 + data_type = MS_OBJECT 25.254 + signed = 0 25.255 + type_name = "object" 25.256 + end if 25.257 + 25.258 + if target then 25.259 + CDeRef( target ) 25.260 + end if 25.261 + 25.262 + if not signed then 25.263 + switch data_type do 25.264 + case MS_OBJECT then 25.265 + type_name = "uintptr_t" 25.266 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.267 + -- nothing 25.268 + case else 25.269 + type_name = "unsigned " & type_name 25.270 + end switch 25.271 + end if 25.272 + 25.273 + if data_type = MS_MEMBER then 25.274 + data_type = sym_token( SymTab[sym][S_MEM_STRUCT] ) 25.275 + end if 25.276 + 25.277 + if array_index != -1 then 25.278 + array_modifier = sprintf("[%d]", array_index ) 25.279 + elsif SymTab[sym][S_MEM_ARRAY] and memaccess = MEMSTRUCT_ACCESS then 25.280 + 25.281 + c_stmt0( sprintf( "_2 = NewS1( %d );\n", SymTab[sym][S_MEM_ARRAY] ) ) 25.282 + for i = 1 to SymTab[sym][S_MEM_ARRAY] do 25.283 + peek_member( pointer, sym, 0, i-1 ) 25.284 + c_stmt0( sprintf( "((s1_ptr)_2)->base[%d] = _0;\n", i ) ) 25.285 + end for 25.286 + if target then 25.287 + c_stmt( "@ = MAKE_SEQ( _2 );\n", target ) 25.288 + else 25.289 + c_stmt0( "_0 = MAKE_SEQ( _2 );\n" ) 25.290 + end if 25.291 + return 25.292 + 25.293 + end if 25.294 + 25.295 + if deref_ptr then 25.296 + c_stmt( "@ = *(intptr_t*)@;\n", { pointer, pointer }, pointer ) 25.297 + end if 25.298 + peek_member_value( pointer, sym, data_type, is_pointer, array_modifier, type_name, signed, target ) 25.299 + memaccess = MEMSTRUCT_ACCESS 25.300 +end procedure 25.301 + 25.302 +procedure peek_member_value( integer pointer, integer sym, integer data_type, 25.303 + integer is_pointer, sequence array_modifier, 25.304 + sequence type_name, integer signed, integer target ) 25.305 + integer parent 25.306 + switch data_type do 25.307 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.308 + sequence indirect_float = "" 25.309 + if not length( array_modifier ) then 25.310 + indirect_float = "*" 25.311 + end if 25.312 + if target then 25.313 + c_stmt( sprintf("@ = NewDouble( (eudouble) %s((%s*)@)%s );\n", 25.314 + {indirect_float, type_name, array_modifier}), 25.315 + { target, pointer }, target ) 25.316 + else 25.317 + parent = SymTab[sym][S_MEM_PARENT] 25.318 + sequence parent_struct 25.319 + switch sym_token( parent ) do 25.320 + case MEMSTRUCT, MEMUNION, QUALIFIED_MEMSTRUCT, QUALIFIED_MEMUNION then 25.321 + parent_struct = decorated_name( parent ) 25.322 + case else 25.323 + parent_struct = decorated_name( SymTab[parent][S_MEM_STRUCT] ) 25.324 + end switch 25.325 + 25.326 + c_stmt( 25.327 + sprintf("_0 = NewDouble( (eudouble) %s(((%s*)@)%s) );\n", 25.328 + { 25.329 + indirect_float, 25.330 + type_name, 25.331 + array_modifier 25.332 + } 25.333 + ), 25.334 + { pointer } 25.335 + ) 25.336 + 25.337 + end if 25.338 + 25.339 + case MEMUNION then 25.340 + read_memunion( pointer, sym ) 25.341 + if target then 25.342 + c_stmt( "@ = _0;\n", target, target ) 25.343 + end if 25.344 + case MEMSTRUCT then 25.345 + read_memstruct( pointer, sym ) 25.346 + if target then 25.347 + c_stmt( "@ = _0;\n", target, target ) 25.348 + end if 25.349 + case else 25.350 + sequence indirect_read = "" 25.351 + if not length( array_modifier ) then 25.352 + indirect_read = "*" 25.353 + end if 25.354 + if target then 25.355 + c_stmt( sprintf("@ = %s((%s*)@)%s;\n", {indirect_read, type_name, array_modifier}), { target, pointer }, target ) 25.356 + else 25.357 + c_stmt( 25.358 + sprintf("_0 = %s((%s*)@)%s;\n", 25.359 + { 25.360 + indirect_read, 25.361 + type_name, 25.362 + array_modifier 25.363 + } 25.364 + ), { pointer } ) 25.365 + 25.366 + if data_type != MS_CHAR and data_type != MS_SHORT label "convert" then 25.367 + ifdef E64 then 25.368 + ifdef WINDOWS then 25.369 + if data_type = MS_LONG then 25.370 + -- a long is still 32-bits on 64-bit windows 25.371 + break "convert" 25.372 + end if 25.373 + end ifdef 25.374 + 25.375 + if data_type = MS_INT /*or is_pointer*/ then 25.376 + -- these are always safe under 64-bit arch 25.377 + break "convert" 25.378 + end if 25.379 + 25.380 + end ifdef 25.381 + c_stmt0("if ((uintptr_t)_0 > (uintptr_t)MAXINT){\n" ) 25.382 + if signed then 25.383 + c_stmt0("_0 = NewDouble((eudouble)(intptr_t)_0);\n" ) 25.384 + else 25.385 + c_stmt0("_0 = NewDouble((eudouble)(uintptr_t)_0);\n" ) 25.386 + end if 25.387 + c_stmt0("}\n") 25.388 + end if 25.389 + end if 25.390 + 25.391 + end switch 25.392 +end procedure 25.393 + 25.394 +export procedure opPEEK_MEMBER() 25.395 + integer 25.396 + pointer = Code[pc+1], 25.397 + member = Code[pc+2], 25.398 + deref = Code[pc+3], 25.399 + target = Code[pc+4] 25.400 + 25.401 + get_pointer( pointer, target ) 25.402 + 25.403 + peek_member( pointer, member, target, /* array index */, deref ) 25.404 + 25.405 + remove_pointer( pointer ) 25.406 + remove_pointer( target ) 25.407 + pc += 5 25.408 +end procedure 25.409 + 25.410 +integer serialize_level = 0 25.411 + 25.412 +--** 25.413 +-- Serialize the specified memstruct into a sequence and store the object in _2. 25.414 +procedure read_memstruct( integer pointer, symtab_pointer member_sym ) 25.415 + 25.416 + if sym_token( member_sym ) != MEMSTRUCT then 25.417 + -- we want to walk the actual struct 25.418 + member_sym = SymTab[member_sym][S_MEM_STRUCT] 25.419 + end if 25.420 + 25.421 + 25.422 + integer size = 0 25.423 + integer size_sym = member_sym 25.424 + while size_sym with entry do 25.425 + size += 1 25.426 + entry 25.427 + size_sym = SymTab[size_sym][S_MEM_NEXT] 25.428 + end while 25.429 + 25.430 + serialize_level += 1 25.431 + c_stmt0( "{\n" ) 25.432 + c_stmt0( sprintf("s1_ptr serialize_%d;\n", serialize_level ) ) 25.433 + c_stmt0( sprintf("serialize_%d = NewS1( %d );\n", { serialize_level, size } ) ) 25.434 + c_stmt( "_1 = @;\n", pointer ) 25.435 + integer ix = 0 25.436 + sequence parent = get_tagged_name( member_sym ) 25.437 + while member_sym with entry do 25.438 + ifdef DEBUG then 25.439 + c_stmt0( sprintf("// peek member: %s.%s\n", {decorated_name( SymTab[member_sym][S_MEM_PARENT] ), decorated_name( member_sym ) })) 25.440 + end ifdef 25.441 + c_stmt( sprintf("@ = (intptr_t) & ((%s*)_1)->%s;\n", { parent, decorated_name( member_sym )}), pointer ) 25.442 + peek_member( pointer, member_sym, 0 ) 25.443 + ix += 1 25.444 + c_stmt0( sprintf( "serialize_%d->base[%d] = _0;\n", { serialize_level, ix } ) ) 25.445 + 25.446 + entry 25.447 + member_sym = SymTab[member_sym][S_MEM_NEXT] 25.448 + end while 25.449 + 25.450 + c_stmt0( sprintf( "_0 = MAKE_SEQ( serialize_%d );\n", serialize_level ) ) 25.451 + c_stmt( "@ = _1;\n", pointer, pointer ) 25.452 + c_stmt0( "}\n" ) 25.453 + serialize_level -= 1 25.454 +end procedure 25.455 + 25.456 +--** 25.457 +-- Serialize the specified memunion into a sequence and store the object in _0. 25.458 +-- Also uses _1. 25.459 +procedure read_memunion( integer pointer, symtab_pointer member_sym ) 25.460 + integer size = SymTab[member_sym][S_MEM_SIZE] 25.461 + 25.462 + c_stmt0( sprintf( "_1 = NewS1( %d );\n", size ) ) 25.463 + 25.464 + for i = 1 to size do 25.465 + c_stmt( sprintf( "((s1_ptr)_1)->base[%d] = ((unsigned char *) @)[%d];\n", {i, i-1} ), pointer ) 25.466 + end for 25.467 + c_stmt0( "_0 = MAKE_SEQ( _1 );\n" ) 25.468 +end procedure 25.469 + 25.470 +function read_member( integer pointer, integer sym ) 25.471 + symtab_pointer member_sym = sym 25.472 + integer tid = sym_token( sym ) 25.473 + if tid >= MS_SIGNED and tid <= MS_OBJECT then 25.474 + -- simple serialization of primitives... 25.475 + peek_member( pointer, sym, 0 ) 25.476 + return 0 25.477 + end if 25.478 + 25.479 + integer member_token = sym_token( member_sym ) 25.480 + if member_token = MEMSTRUCT then 25.481 + read_memstruct( pointer, member_sym ) 25.482 + 25.483 + elsif member_token = MEMUNION then 25.484 + read_memunion( pointer, member_sym ) 25.485 + 25.486 + else 25.487 + member_token = SymTab[SymTab[member_sym][S_MEM_STRUCT]][S_TOKEN] 25.488 + if member_token = MEMSTRUCT then 25.489 + read_memstruct( pointer, member_sym ) 25.490 + 25.491 + elsif member_token = MEMUNION then 25.492 + read_memunion( pointer, member_sym ) 25.493 + else 25.494 + InternalErr( "Cannot serialize a: [1]", { LexName( member_token ) }) 25.495 + end if 25.496 + end if 25.497 + return 1 25.498 +end function 25.499 + 25.500 +export procedure opMEMSTRUCT_READ() 25.501 + integer 25.502 + pointer = Code[pc+1], 25.503 + member = Code[pc+2], 25.504 + target = Code[pc+3] 25.505 + 25.506 + CDeRef( target ) 25.507 + get_pointer( pointer, target ) 25.508 + 25.509 + integer is_sequence = read_member( target, member ) 25.510 + 25.511 + c_stmt( "@ = _0;\n", target, target ) 25.512 + if is_sequence then 25.513 + SetBBType( target, TYPE_SEQUENCE, {MININT, MAXINT}, TYPE_OBJECT, 0 ) 25.514 + else 25.515 + SetBBType( target, TYPE_ATOM, {MININT, MAXINT}, TYPE_OBJECT, 0 ) 25.516 + end if 25.517 + remove_pointer( pointer ) 25.518 + 25.519 + pc += 4 25.520 +end procedure 25.521 + 25.522 +procedure poke_member_value( symtab_index target, symtab_index val, integer data_type, sequence type_name, integer array_index ) 25.523 + if array_index != -1 then 25.524 + c_stmt( sprintf( "_1 = SEQ_PTR( @ )->base[%d];\n", array_index + 1), val ) 25.525 + end if 25.526 + switch data_type do 25.527 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.528 + integer is_double = TypeIs( val, TYPE_DOUBLE ) 25.529 + if not is_double then 25.530 + 25.531 + if array_index = -1 then 25.532 + c_stmt( "if( IS_ATOM_INT( @ ) ){\n", val ) 25.533 + c_stmt( sprintf("*(%s*)@ = (%s)@;\n", {type_name, type_name}), { target, val }, target ) 25.534 + else 25.535 + c_stmt0( "if( IS_ATOM_INT( _1 ) ){\n" ) 25.536 + c_stmt( sprintf("((%s*)@)[%d] = (%s)_1;\n", {type_name, array_index, type_name}), { target }, target ) 25.537 + end if 25.538 + c_stmt0( "}\n" ) 25.539 + c_stmt0( "else{\n") 25.540 + end if 25.541 + if array_index = -1 then 25.542 + c_stmt( sprintf("*(%s*)@ = (%s)DBL_PTR( @ )->dbl;\n", {type_name, type_name}), { target, val }, target ) 25.543 + else 25.544 + c_stmt( sprintf("((%s*)@)[%d] = (%s)DBL_PTR( _1 )->dbl;\n", {type_name, array_index, type_name}), { target }, target ) 25.545 + end if 25.546 + 25.547 + if not is_double then 25.548 + c_stmt0( "}\n") 25.549 + end if 25.550 + 25.551 + case MEMUNION then 25.552 + -- TODO 25.553 + case MEMSTRUCT then 25.554 + -- TODO 25.555 + case else 25.556 + integer is_integer = TypeIs( val, TYPE_INTEGER ) 25.557 + if not is_integer then 25.558 + if array_index = -1 then 25.559 + c_stmt( "if( IS_ATOM_INT( @ ) ){\n", val ) 25.560 + else 25.561 + c_stmt0( "if( IS_ATOM_INT( _1 ) ){\n" ) 25.562 + end if 25.563 + end if 25.564 + 25.565 + if array_index = -1 then 25.566 + c_stmt( sprintf("*(%s*) @ = (%s) @;\n", {type_name, type_name}), {target, val}, target ) 25.567 + else 25.568 + c_stmt( sprintf("((%s*) @)[%d] = (%s) _1;\n", {type_name, array_index, type_name}), {target }, target ) 25.569 + end if 25.570 + 25.571 + if not is_integer then 25.572 + c_stmt0("}\n" ) 25.573 + c_stmt0( "else{\n") 25.574 + if array_index = -1 then 25.575 + c_stmt( sprintf("*(%s*) @ = (%s) DBL_PTR( @ )->dbl;\n", {type_name, type_name}), {target, val}, target ) 25.576 + else 25.577 + c_stmt( sprintf("((%s*) @)[%d] = (%s) DBL_PTR( _1 )->dbl;\n", {type_name, array_index, type_name}), {target }, target ) 25.578 + end if 25.579 + c_stmt0("}\n" ) 25.580 + end if 25.581 + end switch 25.582 +end procedure 25.583 + 25.584 +--** 25.585 +-- Stores the value into the memory pointed to by _0 25.586 +procedure poke_member( symtab_index target, symtab_index member, symtab_index val, integer deref_ptr ) 25.587 + integer data_type = SymTab[member][S_TOKEN] 25.588 + integer signed = SymTab[member][S_MEM_SIGNED] 25.589 + 25.590 + sequence type_name = mem_name( sym_token( member ) ) 25.591 + 25.592 + if SymTab[member][S_MEM_POINTER] and not deref_ptr then 25.593 + data_type = MS_OBJECT 25.594 + signed = 0 25.595 + type_name = "object" 25.596 + end if 25.597 + 25.598 + if not signed then 25.599 + switch data_type do 25.600 + case MS_OBJECT then 25.601 + type_name = "uintptr_t" 25.602 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.603 + case else 25.604 + type_name = "unsigned " & type_name 25.605 + end switch 25.606 + end if 25.607 + 25.608 + if SymTab[member][S_MEM_ARRAY] and memaccess = MEMSTRUCT_ACCESS then 25.609 + c_stmt("switch( SEQ_PTR( @ )->length ){\n", val ) 25.610 + c_stmt0("default:\n") 25.611 + for i = SymTab[member][S_MEM_ARRAY] to 1 by -1 do 25.612 + c_stmt0( sprintf("case %d:\n", i ) ) 25.613 + poke_member_value( target, val, data_type, type_name, i-1 ) 25.614 + end for 25.615 + c_stmt0("case 0: ;\n") 25.616 + c_stmt0("}\n") 25.617 + else 25.618 + poke_member_value( target, val, data_type, type_name, -1 ) 25.619 + end if 25.620 + memaccess = MEMSTRUCT_ACCESS 25.621 +end procedure 25.622 + 25.623 +procedure poke_memstruct( symtab_index target, symtab_index struct_sym, symtab_index member, integer subscript ) 25.624 + integer data_type = SymTab[member][S_TOKEN] 25.625 + integer signed = SymTab[member][S_MEM_SIGNED] 25.626 + 25.627 + sequence type_name 25.628 + 25.629 + if SymTab[member][S_MEM_POINTER] then 25.630 + data_type = MS_OBJECT 25.631 + signed = 0 25.632 + type_name = "object" 25.633 + else 25.634 + type_name = mem_name( sym_token( member ) ) 25.635 + end if 25.636 + 25.637 + sequence rhs 25.638 + if subscript then 25.639 + rhs = sprintf( "src_s1->base[%d]", subscript ) 25.640 + else 25.641 + rhs = "0" 25.642 + end if 25.643 + 25.644 + switch data_type do 25.645 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.646 + 25.647 + if subscript then 25.648 + c_stmt0( sprintf( "if( IS_ATOM_INT( %s ) ){\n", { rhs } ) ) 25.649 + end if 25.650 + c_stmt( sprintf("((struct %s*)@)->%s = (%s)%s;\n", 25.651 + { decorated_name( struct_sym), decorated_name( member) ,type_name, rhs}), { target }, target ) 25.652 + if subscript then 25.653 + c_stmt0( "}\n" ) 25.654 + c_stmt0( "else{\n") 25.655 + c_stmt( sprintf("((struct %s*)@)->%s = (%s)DBL_PTR( %s )->dbl;\n", 25.656 + {decorated_name( struct_sym), decorated_name( member) , type_name, rhs}), { target }, target ) 25.657 + c_stmt0( "}\n") 25.658 + end if 25.659 + case MEMUNION then 25.660 + -- TODO 25.661 + case MEMSTRUCT then 25.662 + -- TODO 25.663 + case else 25.664 + if not signed then 25.665 + if data_type = MS_OBJECT then 25.666 + type_name = "uintptr_t" 25.667 + else 25.668 + type_name = "unsigned " & type_name 25.669 + end if 25.670 + end if 25.671 + if subscript then 25.672 + c_stmt0( sprintf("if( IS_ATOM_INT( %s ) ){\n", {rhs} ) ) 25.673 + end if 25.674 + c_stmt( sprintf("((struct %s*) @)->%s = (%s) %s;\n", 25.675 + {decorated_name( struct_sym), decorated_name( member) , type_name, rhs}), {target}, target ) 25.676 + if subscript then 25.677 + c_stmt0("}\n" ) 25.678 + c_stmt0( "else{\n") 25.679 + c_stmt( sprintf("((struct %s*) @)->%s = (%s) DBL_PTR( %s )->dbl;\n", 25.680 + {decorated_name( struct_sym), decorated_name( member) , type_name, rhs}), {target}, target ) 25.681 + c_stmt0("}\n" ) 25.682 + end if 25.683 + 25.684 + end switch 25.685 +end procedure 25.686 + 25.687 +function set_up_assign_sequence( integer source_val ) 25.688 + 25.689 + atom seqlen 25.690 + integer is_sequence = TypeIs( source_val, TYPE_SEQUENCE ) 25.691 + 25.692 + 25.693 + c_stmt0("s1_ptr src_s1;\n") 25.694 + 25.695 + if is_sequence then 25.696 + -- see if we know how big the sequence is: 25.697 + seqlen = SeqLen( source_val ) 25.698 + c_stmt("src_s1 = SEQ_PTR( @ );\n", source_val ) 25.699 + else 25.700 + c_stmt0("int free_src;\n" ) 25.701 + -- might be an atom 25.702 + seqlen = NOVALUE 25.703 + c_stmt("if( IS_ATOM( @ ) || IS_ATOM_INT( @ ) ){\n", { source_val, source_val } ) 25.704 + c_stmt0("free_src = 1;\n") 25.705 + c_stmt0("src_s1 = NewS1( 1 );\n" ) 25.706 + c_stmt("src_s1->base[1] = @;\n", source_val ) 25.707 + c_stmt0("}\n") 25.708 + c_stmt0("else {\n" ) 25.709 + c_stmt0("free_src = 0;\n") 25.710 + c_stmt("src_s1 = SEQ_PTR( @ );\n", source_val ) 25.711 + c_stmt0("}\n") 25.712 + end if 25.713 + return is_sequence & seqlen 25.714 +end function 25.715 + 25.716 +procedure assign_memstruct( integer pointer, integer struct_sym, integer source_val ) 25.717 + -- use a private block 25.718 + c_stmt0("{\n") 25.719 + sequence seq_len = set_up_assign_sequence( source_val ) 25.720 + integer is_sequence = seq_len[1] 25.721 + atom seqlen = seq_len[2] 25.722 + 25.723 + integer members = 0 25.724 + integer member_sym = struct_sym 25.725 + sequence member_list = {} 25.726 + while member_sym with entry do 25.727 + members += 1 25.728 + member_list &= member_sym 25.729 + entry 25.730 + member_sym = SymTab[member_sym][S_MEM_NEXT] 25.731 + end while 25.732 + 25.733 + if seqlen != NOVALUE then 25.734 + integer ix = 1 25.735 + member_sym = SymTab[struct_sym][S_MEM_NEXT] 25.736 + while ix <= seqlen and member_sym do 25.737 + poke_memstruct( pointer, struct_sym, member_sym, ix ) 25.738 + ix += 1 25.739 + member_sym = SymTab[member_sym][S_MEM_NEXT] 25.740 + end while 25.741 + 25.742 + while member_sym do 25.743 + -- zero out the rest 25.744 + poke_memstruct( pointer, struct_sym, member_sym, 0 ) 25.745 + member_sym = SymTab[member_sym][S_MEM_NEXT] 25.746 + end while 25.747 + else 25.748 + -- unknown length: 25.749 + c_stmt0( "switch( src_s1->length ){\n" ) 25.750 + -- the sequence is bigger than the struct: 25.751 + c_stmt0("default:\n") 25.752 + for i = members to 1 by -1 do 25.753 + c_stmt0( sprintf( "case %d:\n", i ) ) 25.754 + poke_memstruct( pointer, struct_sym, member_list[i], i ) 25.755 + end for 25.756 + c_stmt0( "case 0: break;\n" ) 25.757 + c_stmt0("}\n") 25.758 + 25.759 + c_stmt0( "switch( src_s1->length + 1 ){\n" ) 25.760 + for i = 0 to members do 25.761 + c_stmt0( sprintf( "case %d:\n", i ) ) 25.762 + if i then 25.763 + poke_memstruct( pointer, struct_sym, member_list[i], 0 ) 25.764 + end if 25.765 + end for 25.766 + c_stmt0("default: break;\n") 25.767 + c_stmt0("}\n") 25.768 + end if 25.769 + 25.770 + if not is_sequence then 25.771 + c_stmt0("if( free_src ){\n") 25.772 + c_stmt0("DeRefDS( MAKE_SEQ(src_s1) );\n") 25.773 + c_stmt0("}\n" ) 25.774 + end if 25.775 + 25.776 + c_stmt0("}\n") 25.777 +end procedure 25.778 + 25.779 +procedure assign_memunion( integer pointer, integer struct_sym, integer source_val ) 25.780 + c_stmt0("{\n") 25.781 + c_stmt0("unsigned char *ptr;\n") 25.782 + c_stmt0("int i;\n") 25.783 + sequence seq_len = set_up_assign_sequence( source_val ) 25.784 + integer is_sequence = seq_len[1] 25.785 + atom seqlen = seq_len[2] 25.786 + 25.787 + integer union_size = SymTab[struct_sym][S_MEM_SIZE] 25.788 + 25.789 + c_stmt("ptr = (unsigned char *) @;\n", pointer ) 25.790 + if seqlen = NOVALUE then 25.791 + -- unknown length 25.792 + c_stmt0(sprintf("for( i = 1; i <= src_s1->length && i <= %d; ++i, ++ptr ){\n", union_size ) ) 25.793 + c_stmt0("*ptr = (unsigned char) src_s1->base[i];\n") 25.794 + c_stmt0("}\n") 25.795 + 25.796 + c_stmt0(sprintf("for( i = src_s1->length + 1; i <= %d; ++i, ++ptr ){\n", union_size ) ) 25.797 + c_stmt0("*ptr = 0;\n") 25.798 + c_stmt0("}\n") 25.799 + 25.800 + else 25.801 + -- we know the length 25.802 + if seqlen > union_size then 25.803 + seqlen = union_size 25.804 + end if 25.805 + 25.806 + for i = 1 to seqlen do 25.807 + c_stmt0( sprintf("*ptr++ = (unsigned char) src_s1->base[%d];\n", i ) ) 25.808 + end for 25.809 + 25.810 + for i = seqlen + 1 to union_size do 25.811 + c_stmt0( "*ptr++ = 0;\n" ) 25.812 + end for 25.813 + end if 25.814 + 25.815 + if not is_sequence then 25.816 + c_stmt0("if( free_src ){\n") 25.817 + c_stmt0("DeRefDS( MAKE_SEQ(src_s1) );\n") 25.818 + c_stmt0("}\n" ) 25.819 + end if 25.820 + c_stmt0("}\n") 25.821 +end procedure 25.822 + 25.823 + 25.824 +export procedure opMEMSTRUCT_ASSIGN() 25.825 + integer 25.826 + pointer = Code[pc+1], 25.827 + member = Code[pc+2], 25.828 + val = Code[pc+3], 25.829 + deref_ptr = Code[pc+4] 25.830 + 25.831 + get_pointer( pointer, pointer ) 25.832 + 25.833 + integer tok = sym_token( member ) 25.834 + if SymTab[member][S_MEM_POINTER] then 25.835 + if deref_ptr then 25.836 + c_stmt( "@ = *(intptr_t*)@;\n", { pointer, pointer }, pointer ) 25.837 + else 25.838 + tok = MS_MEMBER 25.839 + end if 25.840 + end if 25.841 + 25.842 + switch tok do 25.843 + case MEMSTRUCT then 25.844 + assign_memstruct( pointer, member, val ) 25.845 + case MEMUNION then 25.846 + assign_memunion( pointer, member, val ) 25.847 + case else 25.848 + poke_member( pointer, member, val, deref_ptr ) 25.849 + end switch 25.850 + 25.851 + 25.852 + dispose_temp( val, compile:DISCARD_TEMP, REMOVE_FROM_MAP ) 25.853 + remove_pointer( pointer ) 25.854 + 25.855 + pc += 5 25.856 +end procedure 25.857 + 25.858 + 25.859 +export procedure opMEMSTRUCT_ASSIGNOP() 25.860 + integer 25.861 + op = Code[pc], 25.862 + pointer = Code[pc+1], 25.863 + member = Code[pc+2], 25.864 + val = Code[pc+3], 25.865 + deref_ptr = Code[pc+4] 25.866 + 25.867 + get_pointer( pointer, pointer ) 25.868 + 25.869 + if deref_ptr then 25.870 + c_stmt( "@ = *(intptr_t**) @;\n", { pointer, pointer }, pointer ) 25.871 + end if 25.872 + sequence optext 25.873 + switch op do 25.874 + case MEMSTRUCT_PLUS then 25.875 + optext = "+" 25.876 + case MEMSTRUCT_MINUS then 25.877 + optext = "-" 25.878 + case MEMSTRUCT_DIVIDE then 25.879 + optext = "/" 25.880 + case MEMSTRUCT_MULTIPLY then 25.881 + optext = "*" 25.882 + end switch 25.883 + 25.884 + integer data_type = sym_token( member ) 25.885 + sequence type_name = mem_name( data_type ) 25.886 + switch data_type do 25.887 + case MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE then 25.888 + integer is_double = TypeIs( val, TYPE_DOUBLE ) 25.889 + if not is_double then 25.890 + c_stmt( "if( IS_ATOM_INT( @ ) ){\n", val ) 25.891 + c_stmt( sprintf("*(%s*)@ %s= (%s)@;\n", {type_name, optext, type_name}), { pointer, val }, pointer ) 25.892 + c_stmt0( "}\n" ) 25.893 + c_stmt0( "else{\n") 25.894 + end if 25.895 + 25.896 + c_stmt( sprintf("*(%s*)@ %s= (%s)DBL_PTR( @ )->dbl;\n", {type_name, optext, type_name}), { pointer, val }, pointer ) 25.897 + 25.898 + if not is_double then 25.899 + c_stmt0( "}\n") 25.900 + end if 25.901 + 25.902 + case MEMUNION then 25.903 + -- TODO 25.904 + case MEMSTRUCT then 25.905 + -- TODO 25.906 + case else 25.907 + integer is_integer = TypeIs( val, TYPE_INTEGER ) 25.908 + if not is_integer then 25.909 + c_stmt( "if( IS_ATOM_INT( @ ) ){\n", val ) 25.910 + end if 25.911 + 25.912 + c_stmt( sprintf("*(%s*) @ %s= (%s) @;\n", {type_name, optext, type_name}), {pointer, val}, pointer ) 25.913 + 25.914 + if not is_integer then 25.915 + c_stmt0("}\n" ) 25.916 + c_stmt0( "else{\n") 25.917 + c_stmt( sprintf("*(%s*) @ %s= (%s) DBL_PTR( @ )->dbl;\n", {type_name, optext, type_name}), {pointer, val}, pointer ) 25.918 + c_stmt0("}\n" ) 25.919 + end if 25.920 + end switch 25.921 + dispose_temp( val, compile:DISCARD_TEMP, REMOVE_FROM_MAP ) 25.922 + remove_pointer( pointer ) 25.923 + pc += 5 25.924 +end procedure 25.925 + 25.926 +export procedure opADDRESSOF() 25.927 + integer 25.928 + ptr = Code[pc+1], 25.929 + target = Code[pc+2] 25.930 + CDeRef( target ) 25.931 + c_stmt("if( IS_ATOM_INT( @ ) ){\n", ptr ) 25.932 + c_stmt("@ = @;\n", { target, ptr }, target ) 25.933 + c_stmt0("}\n") 25.934 + c_stmt0("else {\n") 25.935 + c_stmt("@ = NewDouble( (eudouble) @ );\n", {target, ptr}, target ) 25.936 + c_stmt0( "}\n") 25.937 + SetBBType( target, TYPE_ATOM, {MININT, MAXINT}, TYPE_OBJECT, 0 ) 25.938 + 25.939 + pc += 3 25.940 +end procedure 25.941 + 25.942 +export procedure opOFFSETOF() 25.943 + integer 25.944 + member = Code[pc+1], 25.945 + target = Code[pc+2], 25.946 + parent = SymTab[member][S_MEM_PARENT] 25.947 + 25.948 + CDeRef( target ) 25.949 + sequence 25.950 + memstruct_name = decorated_name( parent ), 25.951 + member_name = decorated_name( member ) 25.952 + c_stmt( sprintf("@ = offsetof( %s %s, %s);\n", { mem_name( sym_token( parent ) ), memstruct_name, member_name } ), { target }, target ) 25.953 + 25.954 + pc += 3 25.955 +end procedure 25.956 + 25.957 +function decorated_name( symtab_index sym ) 25.958 + return sprintf( "_%d%s", { SymTab[sym][S_FILE_NO], sym_name( sym ) } ) 25.959 +end function 25.960 + 25.961 +function mem_name( integer tid ) 25.962 + switch tid do 25.963 + case MS_CHAR then 25.964 + return "char" 25.965 + case MS_SHORT then 25.966 + return "short" 25.967 + case MS_INT then 25.968 + return "int" 25.969 + case MS_LONG then 25.970 + return "long" 25.971 + case MS_OBJECT then 25.972 + return "object" 25.973 + case MS_LONGLONG then 25.974 + return "long long int" 25.975 + case MS_FLOAT then 25.976 + return "float" 25.977 + case MS_DOUBLE then 25.978 + return "double" 25.979 + case MS_LONGDOUBLE then 25.980 + return "long double" 25.981 + case MS_EUDOUBLE then 25.982 + return "eudouble" 25.983 + case MEMSTRUCT then 25.984 + return "struct" 25.985 + case MEMUNION then 25.986 + return "union" 25.987 + case MS_MEMBER then 25.988 + return "" 25.989 + case else 25.990 + InternalErr("error finding name for token: [1] [2]", { tid, LexName( tid ) }) 25.991 + end switch 25.992 +end function 25.993 + 25.994 +function get_data_type( symtab_index member ) 25.995 + integer data_type = SymTab[member][S_TOKEN] 25.996 + sequence name = "" 25.997 + 25.998 +-- printf(1, "Writing data type for: %s - %s\n", { sym_name(member), LexName( data_type )}) 25.999 + -- signed / unsigned 25.1000 + if not SymTab[member][S_MEM_SIGNED] 25.1001 + and data_type != MS_OBJECT 25.1002 + and data_type != MS_MEMBER 25.1003 + and data_type != MS_FLOAT 25.1004 + and data_type != MS_DOUBLE 25.1005 + and data_type != MS_LONGDOUBLE 25.1006 + and data_type != MS_EUDOUBLE 25.1007 + then 25.1008 + -- floating points are always marked signed 25.1009 + name &= "unsigned " 25.1010 + end if 25.1011 + 25.1012 + if data_type = MS_OBJECT and not SymTab[member][S_MEM_SIGNED] then 25.1013 + -- this one can't just take an unsigned 25.1014 + name &= "uintptr_t " 25.1015 + elsif data_type != MS_MEMBER then 25.1016 + name &= sprintf( "%s ", { mem_name( data_type )}) 25.1017 + else 25.1018 + data_type = SymTab[SymTab[member][S_MEM_STRUCT]][S_TOKEN] 25.1019 + if data_type = MEMUNION then 25.1020 + -- embedded union 25.1021 + name &= sprintf( "union %s ", {decorated_name( SymTab[member][S_MEM_STRUCT] ) } ) 25.1022 + else 25.1023 + -- embedded struct 25.1024 + name &= sprintf( "struct %s ", {decorated_name( SymTab[member][S_MEM_STRUCT] ) } ) 25.1025 + end if 25.1026 + end if 25.1027 + 25.1028 + if SymTab[member][S_MEM_POINTER] then 25.1029 + name &= "*" 25.1030 + end if 25.1031 + return name 25.1032 +end function 25.1033 + 25.1034 +procedure write_data_type( atom struct_h, symtab_index member ) 25.1035 + puts( struct_h, get_data_type( member ) ) 25.1036 +end procedure 25.1037 + 25.1038 +procedure write_memstruct( atom struct_h, symtab_index sym ) 25.1039 + symtab_pointer member = sym 25.1040 + while member with entry do 25.1041 + puts( struct_h, "\t" ) 25.1042 + write_data_type( struct_h, member ) 25.1043 + puts( struct_h, decorated_name( member ) ) 25.1044 + if SymTab[member][S_MEM_ARRAY] then 25.1045 + printf( struct_h, "[%d]", SymTab[member][S_MEM_ARRAY] ) 25.1046 + end if 25.1047 + printf( struct_h, "; // %d\n", SymTab[member][S_TOKEN] ) 25.1048 + entry 25.1049 + member = SymTab[member][S_MEM_NEXT] 25.1050 + end while 25.1051 + puts( struct_h, "};\n\n" ) 25.1052 +end procedure 25.1053 + 25.1054 +export procedure write_struct_header() 25.1055 + atom struct_h = open( output_dir & "struct.h", "w", 1 ) 25.1056 + generated_files = append( generated_files, "struct.h" ) 25.1057 + 25.1058 + puts( struct_h, "#ifndef STRUCT_H_\n" ) 25.1059 + puts( struct_h, "#define STRUCT_H_\n\n" ) 25.1060 + puts( struct_h, "#include <stdint.h>\n") 25.1061 + puts( struct_h, "#include <stddef.h>\n") 25.1062 + puts( struct_h, "#include \"include/euphoria.h\"\n\n" ) 25.1063 + 25.1064 + sequence structs = {} 25.1065 + for i = TopLevelSub to length( SymTab ) do 25.1066 + integer tok = sym_token( i ) 25.1067 + if tok = MEMSTRUCT then 25.1068 + printf( struct_h, "struct %s %s;\n", repeat( decorated_name( i ), 2 ) ) 25.1069 + structs &= i 25.1070 + elsif tok = MEMUNION then 25.1071 + printf( struct_h, "union %s %s;\n", repeat( decorated_name( i ), 2 ) ) 25.1072 + structs &= i 25.1073 + end if 25.1074 + end for 25.1075 + 25.1076 + for i = 1 to length( structs ) do 25.1077 + integer tok = sym_token( structs[i] ) 25.1078 + if tok = MEMSTRUCT then 25.1079 + printf( struct_h, "struct %s{\n", { decorated_name( structs[i] )} ) 25.1080 + write_memstruct( struct_h, structs[i] ) 25.1081 + elsif tok = MEMUNION then 25.1082 + printf( struct_h, "union %s{\n", { decorated_name( structs[i])} ) 25.1083 + write_memstruct( struct_h, structs[i] ) 25.1084 + end if 25.1085 + end for 25.1086 + 25.1087 + puts( struct_h, "#endif\n" ) 25.1088 + 25.1089 +end procedure
26.1 --- a/source/cominit.e Mon Dec 19 23:19:58 2011 -0300 26.2 +++ b/source/cominit.e Wed Dec 21 16:45:49 2011 -0300 26.3 @@ -15,6 +15,7 @@ 26.4 include std/console.e 26.5 include std/error.e as error 26.6 include std/filesys.e 26.7 +include std/get.e 26.8 include std/io.e 26.9 include std/map.e as m 26.10 include std/search.e 26.11 @@ -47,6 +48,7 @@ 26.12 { "batch", 0, GetMsgText(279,0), { } }, 26.13 { "strict", 0, GetMsgText(288,0), { } }, 26.14 { "test", 0, GetMsgText(289,0), { } }, 26.15 + { "trace-lines",0, GetMsgText(TRACE_LINES_CMD, 0), { HAS_PARAMETER, "lines" } }, 26.16 { "copyright", 0, GetMsgText(281,0), { } }, 26.17 { "v", "version", GetMsgText(290,0), { } }, 26.18 $ 26.19 @@ -534,7 +536,15 @@ 26.20 26.21 case "eudir" then 26.22 set_eudir( val ) 26.23 - 26.24 + 26.25 + case "trace-lines" then 26.26 + val = value( val ) 26.27 + if val[1] = GET_SUCCESS then 26.28 + trace_lines = floor( val[2] ) 26.29 + else 26.30 + puts(2, GetMsgText( BAD_TRACE_LINES ) ) 26.31 + abort( 1 ) 26.32 + end if 26.33 end switch 26.34 end for 26.35
27.1 --- a/source/compile.e Mon Dec 19 23:19:58 2011 -0300 27.2 +++ b/source/compile.e Wed Dec 21 16:45:49 2011 -0300 27.3 @@ -8,7 +8,7 @@ 27.4 -- values of each variable and operand. This allows it to emit C code that 27.5 -- is more precise and efficient. It doesn't actually emit the C code 27.6 -- until the final pass. 27.7 - 27.8 +namespace compile 27.9 ifdef ETYPE_CHECK then 27.10 with type_check 27.11 elsedef 27.12 @@ -25,6 +25,7 @@ 27.13 include buildsys.e 27.14 include c_decl.e 27.15 include c_out.e 27.16 +include c_struct.e 27.17 include cominit.e 27.18 include compress.e 27.19 include emit.e 27.20 @@ -40,7 +41,7 @@ 27.21 include fwdref.e 27.22 27.23 27.24 -integer np, pc 27.25 +export integer np, pc 27.26 27.27 constant MAXLEN = MAXINT - 1000000 -- assumed maximum length of a sequence 27.28 27.29 @@ -135,7 +136,7 @@ 27.30 -- Value: 1 = reference count incremented when created 27.31 map:map dead_temp_walking = map:new() 27.32 27.33 -enum 27.34 +export constant 27.35 NO_REFERENCE = 0, 27.36 NEW_REFERENCE = 1, 27.37 KEEP_IN_MAP = 0, 27.38 @@ -166,7 +167,7 @@ 27.39 -- If the object's reference count was incremented, then referenced 27.40 -- should be NEW_REFERENCE, so that it can be cleaned up properly later. 27.41 -- Otherwise, ##referenced## should be NO_REFERENCE. 27.42 -procedure create_temp( symtab_index sym, integer referenced ) 27.43 +export procedure create_temp( symtab_index sym, integer referenced ) 27.44 if is_temp( sym ) then 27.45 map:put( dead_temp_walking, sym, referenced ) 27.46 end if 27.47 @@ -180,7 +181,7 @@ 27.48 -- it was created. If remove_from_map is REMOVE_FROM_MAP, then the temp will 27.49 -- be cleared from the map. If remove_from_map is KEEP_IN_MAP, then the 27.50 -- temp will be left in the map. 27.51 -procedure dispose_temp( symtab_index sym, integer keep, integer remove_from_map ) 27.52 +export procedure dispose_temp( symtab_index sym, integer keep, integer remove_from_map ) 27.53 if is_temp( sym ) then 27.54 if find( sym, saved_temps ) then 27.55 -- this will be deref'd manually 27.56 @@ -398,7 +399,7 @@ 27.57 return local_t 27.58 end function 27.59 27.60 -function SeqLen(integer x) 27.61 +export function SeqLen(integer x) 27.62 -- the length of a sequence 27.63 symtab_index s 27.64 atom len, local_len 27.65 @@ -740,7 +741,7 @@ 27.66 integer deref_elem_type 27.67 integer deref_short 27.68 27.69 -procedure CSaveStr(sequence target, integer v, integer a, integer b, integer c) 27.70 +export procedure CSaveStr(sequence target, integer v, integer a, integer b, integer c) 27.71 -- save a value (to be deref'd) in immediate target 27.72 -- if value isn't known to be an integer 27.73 boolean deref_exist 27.74 @@ -806,7 +807,7 @@ 27.75 end if 27.76 end procedure 27.77 27.78 -procedure CDeRefStr(sequence s) 27.79 +export procedure CDeRefStr(sequence s) 27.80 -- DeRef a string name - see CSaveStr() 27.81 if length(deref_str) = 0 then 27.82 return 27.83 @@ -842,7 +843,7 @@ 27.84 end if 27.85 end procedure 27.86 27.87 -procedure CDeRef(integer v) 27.88 +export procedure CDeRef(integer v) 27.89 -- DeRef a var or temp 27.90 integer temp_type, elem_type 27.91 27.92 @@ -2225,6 +2226,63 @@ 27.93 sequence dblfn 27.94 boolean all_done 27.95 27.96 +procedure sizeof_struct( symtab_index datatype_sym, symtab_index target_sym ) 27.97 + sequence tag 27.98 + if sym_token( datatype_sym ) = MEMSTRUCT then 27.99 + tag = "struct" 27.100 + else 27.101 + tag = "union" 27.102 + end if 27.103 + c_stmt( sprintf( "@ = sizeof( %s @);\n", {tag} ), { target_sym, datatype_sym } ) 27.104 + CDeRef( target_sym ) 27.105 +end procedure 27.106 + 27.107 +procedure do_sizeof( symtab_index datatype_sym, symtab_index target_sym ) 27.108 + switch sym_token( datatype_sym ) do 27.109 + case MEMSTRUCT, MEMUNION then 27.110 + sizeof_struct( datatype_sym, target_sym ) 27.111 + 27.112 + case MEMTYPE then 27.113 + -- use whatever the actual type is... 27.114 + do_sizeof( SymTab[datatype_sym][S_MEM_PARENT], target_sym ) 27.115 + 27.116 + -- memstruct primitives: 27.117 + case MS_CHAR then c_stmt( "@ = sizeof( char );\n", target_sym, target_sym ) 27.118 + case MS_SHORT then c_stmt( "@ = sizeof( short );\n", target_sym, target_sym ) 27.119 + case MS_SIGNED then c_stmt( "@ = sizeof( int );\n", target_sym, target_sym ) 27.120 + case MS_UNSIGNED then c_stmt( "@ = sizeof( int );\n", target_sym, target_sym ) 27.121 + case MS_INT then c_stmt( "@ = sizeof( int );\n", target_sym, target_sym ) 27.122 + case MS_LONG then c_stmt( "@ = sizeof( long );\n", target_sym, target_sym ) 27.123 + case MS_LONGLONG then c_stmt( "@ = sizeof( long long );\n", target_sym, target_sym ) 27.124 + case MS_FLOAT then c_stmt( "@ = sizeof( float );\n", target_sym, target_sym ) 27.125 + case MS_DOUBLE then c_stmt( "@ = sizeof( double );\n", target_sym, target_sym ) 27.126 + case MS_LONGDOUBLE then c_stmt( "@ = sizeof( long double );\n", target_sym, target_sym ) 27.127 + case MS_EUDOUBLE then c_stmt( "@ = sizeof( eudouble );\n", target_sym, target_sym ) 27.128 + case MS_OBJECT then c_stmt( "@ = sizeof( void * );\n", target_sym, target_sym ) 27.129 + 27.130 + case else 27.131 + -- Will be evaluated like on of the C_* constants 27.132 + c_stmt("@ = eu_sizeof( @ );\n", { target_sym, datatype_sym }, target_sym ) 27.133 + CSaveStr( "_0", target_sym, datatype_sym, 0, 0 ) 27.134 + CDeRef( target_sym ) 27.135 + dispose_temp( datatype_sym, compile:DISCARD_TEMP, compile:REMOVE_FROM_MAP ) 27.136 + 27.137 + end switch 27.138 +end procedure 27.139 + 27.140 +export procedure opSIZEOF() 27.141 + integer 27.142 + datatype_sym = Code[pc+1], 27.143 + target_sym = Code[pc+2] 27.144 + 27.145 + do_sizeof( datatype_sym, target_sym ) 27.146 + 27.147 + SetBBType( target_sym, TYPE_INTEGER, {0, MAXINT}, TYPE_INTEGER, 0 ) 27.148 + create_temp( target_sym, 1 ) 27.149 + pc += 3 27.150 +end procedure 27.151 + 27.152 + 27.153 procedure opSTARTLINE() 27.154 -- common in Translator, not in Interpreter 27.155 sequence line 27.156 @@ -3492,7 +3550,7 @@ 27.157 pc += 5 27.158 end procedure 27.159 27.160 -procedure opTYPE_CHECK() 27.161 +procedure opTYPE_CHECK() -- MEM_TYPE_CHECK 27.162 -- type check for a user-defined type 27.163 -- this always follows a type-call 27.164 -- The Translator only performs the type-call and check, 27.165 @@ -3511,7 +3569,13 @@ 27.166 c_stmt0("}\n") 27.167 c_stmt0("}\n") 27.168 end if 27.169 - pc += 1 27.170 + 27.171 + if Code[pc] = TYPE_CHECK then 27.172 + pc += 1 27.173 + else 27.174 + pc += 2 27.175 + end if 27.176 + 27.177 end procedure 27.178 27.179 function is_temp( symtab_index sym ) 27.180 @@ -5651,22 +5715,6 @@ 27.181 pc += 3 27.182 end procedure 27.183 27.184 -procedure opSIZEOF() 27.185 - integer 27.186 - datatype_sym = Code[pc+1], 27.187 - target_sym = Code[pc+2] 27.188 - CSaveStr( "_0", target_sym, datatype_sym, 0, 0 ) 27.189 - 27.190 - c_stmt("@ = eu_sizeof( @ );\n", { target_sym, datatype_sym }, target_sym ) 27.191 - 27.192 - CDeRef( target_sym ) 27.193 - 27.194 - dispose_temp( datatype_sym, DISCARD_TEMP, REMOVE_FROM_MAP ) 27.195 - SetBBType( target_sym, TYPE_INTEGER, {0, MAXINT}, TYPE_INTEGER, 0 ) 27.196 - create_temp( target_sym, 1 ) 27.197 - pc += 3 27.198 -end procedure 27.199 - 27.200 procedure opPOKE() 27.201 -- generate code for poke/2/4/8 27.202 -- should optimize constant address 27.203 @@ -6412,6 +6460,7 @@ 27.204 pc += 1 27.205 end procedure 27.206 27.207 + 27.208 sequence operation -- routine ids for all opcode handlers 27.209 27.210 export procedure init_opcodes() 27.211 @@ -6425,6 +6474,9 @@ 27.212 switch name do 27.213 case "AND_BITS" then 27.214 operation[i] = routine_id("opAND_BITS") 27.215 + 27.216 + case "ADDRESSOF" then 27.217 + operation[i] = routine_id("opADDRESSOF") 27.218 27.219 case "AND" then 27.220 operation[i] = routine_id("opAND") 27.221 @@ -6651,6 +6703,27 @@ 27.222 case "MEM_SET" then 27.223 operation[i] = routine_id("opMEM_SET") 27.224 27.225 + case "MEMSTRUCT_ACCESS" then 27.226 + operation[i] = routine_id("opMEMSTRUCT_ACCESS") 27.227 + 27.228 + case "PEEK_ARRAY" then 27.229 + operation[i] = routine_id("opPEEK_ARRAY") 27.230 + 27.231 + case "MEMSTRUCT_ARRAY" then 27.232 + operation[i] = routine_id("opMEMSTRUCT_ARRAY") 27.233 + 27.234 + case "PEEK_MEMBER" then 27.235 + operation[i] = routine_id("opPEEK_MEMBER") 27.236 + 27.237 + case "MEMSTRUCT_READ" then 27.238 + operation[i] = routine_id("opMEMSTRUCT_READ") 27.239 + 27.240 + case "MEMSTRUCT_ASSIGN" then 27.241 + operation[i] = routine_id("opMEMSTRUCT_ASSIGN") 27.242 + 27.243 + case "MEMSTRUCT_PLUS", "MEMSTRUCT_MINUS", "MEMSTRUCT_MULTIPLY", "MEMSTRUCT_DIVIDE" then 27.244 + operation[i] = routine_id("opMEMSTRUCT_ASSIGNOP") 27.245 + 27.246 case "MINUS" then 27.247 operation[i] = routine_id("opMINUS") 27.248 27.249 @@ -6681,6 +6754,9 @@ 27.250 case "NOTEQ" then 27.251 operation[i] = routine_id("opNOTEQ") 27.252 27.253 + case "OFFSETOF" then 27.254 + operation[i] = routine_id("opOFFSETOF") 27.255 + 27.256 case "OPEN" then 27.257 operation[i] = routine_id("opOPEN") 27.258 27.259 @@ -6852,9 +6928,9 @@ 27.260 case "TRACE" then 27.261 operation[i] = routine_id("opTRACE") 27.262 27.263 - case "TYPE_CHECK" then 27.264 + case "TYPE_CHECK", "MEM_TYPE_CHECK" then 27.265 operation[i] = routine_id("opTYPE_CHECK") 27.266 - 27.267 + 27.268 case "UMINUS" then 27.269 operation[i] = routine_id("opUMINUS") 27.270 27.271 @@ -6979,6 +7055,8 @@ 27.272 operation[i] = routine_id("opDEREF_TEMP") 27.273 case "REF_TEMP" then 27.274 operation[i] = routine_id("opREF_TEMP") 27.275 + case "ARRAY_ACCESS" then 27.276 + operation[i] = routine_id("opARRAY_ACCESS") 27.277 case else 27.278 operation[i] = -1 27.279 end switch 27.280 @@ -7137,7 +7215,7 @@ 27.281 27.282 -- prevent conflicts 27.283 for i = TopLevelSub+1 to length(SymTab) do 27.284 - if sequence(SymTab[i][S_NAME]) and find( SymTab[i][S_TOKEN], {VARIABLE, CONSTANT, ENUM}) then 27.285 + if sequence(SymTab[i][S_NAME]) and sym_mode( i ) = M_NORMAL and not find( sym_token( i ), { PROC, FUNC, TYPE} ) then --find( SymTab[i][S_TOKEN], {VARIABLE, CONSTANT, ENUM}) then 27.286 SymTab[i][S_NAME] &= sprintf( "_%d", i ) 27.287 end if 27.288 end for 27.289 @@ -7194,7 +7272,8 @@ 27.290 end if 27.291 c_puts("#include <time.h>\n") 27.292 c_puts("#include \"include/euphoria.h\"\n") 27.293 - c_puts("#include \"main-.h\"\n\n") 27.294 + c_puts("#include \"main-.h\"\n") 27.295 + c_puts("#include \"struct.h\"\n\n") 27.296 27.297 if TUNIX then 27.298 c_puts("#include <unistd.h>\n") 27.299 @@ -7372,6 +7451,8 @@ 27.300 c_stmt0("eu_startup(_00, _01, _02, (object)CLOCKS_PER_SEC, (object)sysconf(_SC_CLK_TCK));\n") 27.301 c_puts("#endif\n") 27.302 end if 27.303 + 27.304 + c_stmt0( sprintf( "trace_lines = %d;\n", trace_lines ) ) 27.305 27.306 -- options_switch initialization 27.307 switches = get_switches() 27.308 @@ -7559,6 +7640,8 @@ 27.309 27.310 close(c_code) 27.311 close(c_h) 27.312 + 27.313 + write_struct_header() 27.314 27.315 write_buildfile() 27.316 end procedure
28.1 --- a/source/configure Mon Dec 19 23:19:58 2011 -0300 28.2 +++ b/source/configure Wed Dec 21 16:45:49 2011 -0300 28.3 @@ -277,7 +277,7 @@ 28.4 fi 28.5 ARCH=$VAL 28.6 case $ARCH in 28.7 - x86.64) 28.8 + x86*64) 28.9 ARCH=ix86_64 28.10 MFLAG=-m64 28.11 EFLAG=E64
29.1 --- a/source/dis.e Mon Dec 19 23:19:58 2011 -0300 29.2 +++ b/source/dis.e Wed Dec 21 16:45:49 2011 -0300 29.3 @@ -64,7 +64,10 @@ 29.4 end if 29.5 end function 29.6 29.7 -function names( sequence n ) 29.8 +function names( object n ) 29.9 + if atom( n ) then 29.10 + n = { n } 29.11 + end if 29.12 sequence nl 29.13 nl = {} 29.14 for i = 1 to length(n) do 29.15 @@ -473,7 +476,28 @@ 29.16 il( sprintf("%s => %s", names( {a,target} )), 2 ) 29.17 pc += 3 29.18 end procedure 29.19 --- 29.20 + 29.21 +procedure opMEMSTRUCT_ASSIGN() -- or opASSIGN_I or SEQUENCE_COPY 29.22 + a = Code[pc+1] -- pointer 29.23 + b = Code[pc+2] -- member sym 29.24 + c = Code[pc+3] -- new value 29.25 + sequence deref 29.26 + if Code[pc+4] then 29.27 + deref = ".*" 29.28 + else 29.29 + deref = "" 29.30 + end if 29.31 + sequence operator = "" 29.32 + switch Code[pc] do 29.33 + case MEMSTRUCT_PLUS then operator = "+" 29.34 + case MEMSTRUCT_MINUS then operator = "-" 29.35 + case MEMSTRUCT_MULTIPLY then operator = "*" 29.36 + case MEMSTRUCT_DIVIDE then operator = "/" 29.37 + end switch 29.38 + il( sprintf("%s %s.%s%s %s= %s", {opnames[Code[pc]]} & names( {a, b } ) & {deref, operator} & names( {c} ) ), 4 ) 29.39 + pc += 5 29.40 +end procedure 29.41 + 29.42 procedure opELSE() -- or EXIT, ENDWHILE}) then 29.43 il( sprintf("%s goto %04d", {opnames[Code[pc]], Code[pc+1]}),1 ) 29.44 -- pc = Code[pc+1] 29.45 @@ -726,6 +750,13 @@ 29.46 29.47 end procedure 29.48 29.49 +procedure opMEM_TYPE_CHECK() 29.50 + 29.51 + punary() 29.52 + 29.53 +end procedure 29.54 + 29.55 + 29.56 procedure is_an() 29.57 a = Code[pc+1] 29.58 target = Code[pc+2] 29.59 @@ -887,6 +918,22 @@ 29.60 binary() 29.61 end procedure 29.62 29.63 +procedure opMEMSTRUCT_PLUS() 29.64 + opMEMSTRUCT_ASSIGN() 29.65 +end procedure 29.66 + 29.67 +procedure opMEMSTRUCT_MINUS() 29.68 + opMEMSTRUCT_ASSIGN() 29.69 +end procedure 29.70 + 29.71 +procedure opMEMSTRUCT_MULTIPLY() 29.72 + opMEMSTRUCT_ASSIGN() 29.73 +end procedure 29.74 + 29.75 +procedure opMEMSTRUCT_DIVIDE() 29.76 + opMEMSTRUCT_ASSIGN() 29.77 +end procedure 29.78 + 29.79 procedure opMINUS() -- or opMINUS_I then 29.80 binary() 29.81 end procedure 29.82 @@ -1165,6 +1212,14 @@ 29.83 unary() 29.84 end procedure 29.85 29.86 +procedure opADDRESSOF() 29.87 + unary() 29.88 +end procedure 29.89 + 29.90 +procedure opOFFSETOF() 29.91 + unary() 29.92 +end procedure 29.93 + 29.94 procedure opMEM_COPY() 29.95 ptrinary() 29.96 end procedure 29.97 @@ -1362,6 +1417,71 @@ 29.98 punary() 29.99 end procedure 29.100 29.101 +procedure mem_access() 29.102 + -- pc+1 number of accesses 29.103 + -- pc+2 pointer to memstruct 29.104 + -- pc+3 .. pc+n+1 member syms for access 29.105 + 29.106 + -- MEMSTRUCT_ACCESS: 29.107 + -- pc+n+2 target for pointer 29.108 + 29.109 + -- ARRAY_ACCESS 29.110 + -- pc+n+2: subscript 29.111 + -- pc+n+3 target for pointer 29.112 + 29.113 + integer op = Code[pc] 29.114 + integer is_array = (op= ARRAY_ACCESS) 29.115 + integer members = Code[pc+1] 29.116 + sequence text = sprintf("%s %s %s(", {opnames[op]} & names( {Code[pc+2], SymTab[Code[pc+3]][S_MEM_PARENT]} ) ) 29.117 + for i = pc+3 to pc+2+members do 29.118 + text &= sprintf(" %s", names( Code[i] ) ) 29.119 + end for 29.120 + text &= " )" 29.121 + if is_array then 29.122 + text &= sprintf( "[%s]", {name_or_literal( Code[pc+members+3] )} ) 29.123 + end if 29.124 + text &= sprintf(" => %s", names( Code[pc+members+3 + is_array] ) ) 29.125 + il( text, members + 3 + is_array ) 29.126 + pc += members + 4 + is_array 29.127 +end procedure 29.128 + 29.129 +procedure opARRAY_ACCESS() 29.130 + mem_access() 29.131 +end procedure 29.132 + 29.133 +procedure opMEMSTRUCT_ACCESS() 29.134 + mem_access() 29.135 +end procedure 29.136 + 29.137 +procedure opMEMSTRUCT_ARRAY() 29.138 + trinary() 29.139 +end procedure 29.140 + 29.141 + 29.142 +procedure opMEMSTRUCT_READ() 29.143 + binary() 29.144 +end procedure 29.145 + 29.146 +procedure opPEEK_ARRAY() 29.147 + trinary() 29.148 +end procedure 29.149 +include std/console.e 29.150 +procedure opPEEK_MEMBER() 29.151 + sequence deref 29.152 + if Code[pc+3] then 29.153 + deref = "DEREFERENCE POINTER" 29.154 + else 29.155 + deref = "VALUE" 29.156 + end if 29.157 + il( sprintf( "%s: %s, %s [%s] => %s", 29.158 + {opnames[Code[pc]]} & 29.159 + names(Code[pc+1..pc+2]) & 29.160 + {deref} & 29.161 + names( {Code[pc+4]}) ), 29.162 + 4) 29.163 + pc += 5 29.164 +end procedure 29.165 + 29.166 function strip_path( sequence file ) 29.167 for i = length( file ) to 1 by -1 do 29.168 if find( file[i], "/\\" ) then 29.169 @@ -1471,7 +1591,7 @@ 29.170 29.171 constant MODES = {"M_NORMAL", "M_CONSTANT", "M_TEMP", "M_SCOPE" } 29.172 constant SCOPES = { 29.173 - "SC_?", 29.174 + "SC_NONE", 29.175 "SC_LOOP_VAR", -- "private" loop vars known within a single loop 29.176 "SC_PRIVATE", -- private within subprogram 29.177 "SC_GLOOP_VAR", -- "global" loop var 29.178 @@ -1483,7 +1603,10 @@ 29.179 "SC_MULTIPLY_DEFINED", -- global symbol defined in 2 or more files 29.180 "SC_EXPORT", -- visible to anyone that includes the file 29.181 "SC_OVERRIDE", -- override an internal 29.182 - "SC_PUBLIC" } -- visible to any file that includes it, or via "public include" 29.183 + "SC_PUBLIC", -- visible to any file that includes it, or via "public include" 29.184 + "SC_MEMSTRUCT", 29.185 + $ 29.186 + } 29.187 29.188 constant USAGE_VALUES = { 29.189 U_UNUSED, 29.190 @@ -1783,7 +1906,7 @@ 29.191 name = "GREATEREQ_IFW" 29.192 elsif equal(name, "LESSEQ_IFW_I") then 29.193 name = "LESSEQ_IFW" 29.194 - elsif match( "PEEK", name ) then 29.195 + elsif match( "PEEK", name ) and not match( "_MEMBER", name ) and not match( "_ARRAY", name ) then 29.196 name = "PEEK" 29.197 elsif match( "POKE", name ) then 29.198 name = "POKE" 29.199 @@ -1820,6 +1943,70 @@ 29.200 return b 29.201 end function 29.202 29.203 +function mem_name( symtab_index member_sym ) 29.204 + integer tid = sym_token( member_sym ) 29.205 + switch tid do 29.206 + case MS_CHAR then 29.207 + return "char" 29.208 + case MS_SHORT then 29.209 + return "short" 29.210 + case MS_INT then 29.211 + return "int" 29.212 + case MS_LONG then 29.213 + return "long" 29.214 + case MS_OBJECT then 29.215 + return "object" 29.216 + case MS_LONGLONG then 29.217 + return "long long int" 29.218 + case MS_FLOAT then 29.219 + return "float" 29.220 + case MS_DOUBLE then 29.221 + return "double" 29.222 + case MS_LONGDOUBLE then 29.223 + return "long double" 29.224 + case MS_EUDOUBLE then 29.225 + return "eudouble" 29.226 + case MS_MEMBER then 29.227 + return sym_name( SymTab[member_sym][S_MEM_STRUCT] ) 29.228 + end switch 29.229 +end function 29.230 + 29.231 +procedure dis_memstruct( integer ms ) 29.232 + if sym_token( ms ) = MEMSTRUCT then 29.233 + puts( out, "\nMemStruct" ) 29.234 + else 29.235 + puts( out, "\nMemUnion" ) 29.236 + end if 29.237 + 29.238 + printf( out, " [%s-%s:%05d]\n", 29.239 + {known_files[SymTab[ms][S_FILE_NO]], SymTab[ms][S_NAME], ms }) 29.240 + printf( out, " SIZE: %d\n", SymTab[ms][S_MEM_SIZE] ) 29.241 + symtab_pointer member_sym = ms 29.242 + printf( out, " %-20s %-15s Other Information\n", {"Name", "Type"}) 29.243 + while member_sym with entry do 29.244 + printf( out, " %06d: %-20s %-15s pointer[%d] signed[%d] array[%d] offset[%3d] size[%d]\n", 29.245 + { 29.246 + member_sym, 29.247 + sym_name( member_sym ), 29.248 + mem_name( member_sym ), 29.249 + SymTab[member_sym][S_MEM_POINTER], 29.250 + SymTab[member_sym][S_MEM_SIGNED], 29.251 + SymTab[member_sym][S_MEM_ARRAY], 29.252 + SymTab[member_sym][S_MEM_OFFSET], 29.253 + SymTab[member_sym][S_MEM_SIZE], 29.254 + $ 29.255 + } ) 29.256 + 29.257 + entry 29.258 + member_sym = SymTab[member_sym][S_MEM_NEXT] 29.259 + end while 29.260 + if sym_token( ms ) = MEMSTRUCT then 29.261 + puts( out, "End MemStruct" ) 29.262 + else 29.263 + puts( out, "End MemUnion" ) 29.264 + end if 29.265 + printf( out, " [%s:%05d]\n", {sym_name( ms ), ms} ) 29.266 +end procedure 29.267 29.268 procedure dis( integer sub ) 29.269 integer op, ix 29.270 @@ -1925,6 +2112,10 @@ 29.271 and sequence(SymTab[i][S_CODE]) 29.272 and SymTab[i][S_SCOPE] != SC_PRIVATE then 29.273 dis( i ) 29.274 + 29.275 + elsif length(SymTab[i]) = SIZEOF_MEMSTRUCT_ENTRY 29.276 + and (SymTab[i][S_TOKEN] = MEMSTRUCT or SymTab[i][S_TOKEN] = MEMUNION) then 29.277 + dis_memstruct( i ) 29.278 else 29.279 -- other symbols? 29.280 end if 29.281 @@ -1937,3 +2128,4 @@ 29.282 29.283 end procedure 29.284 mode:set_backend( routine_id("BackEnd") ) 29.285 +
30.1 --- a/source/emit.e Mon Dec 19 23:19:58 2011 -0300 30.2 +++ b/source/emit.e Wed Dec 21 16:45:49 2011 -0300 30.3 @@ -23,6 +23,7 @@ 30.4 include block.e 30.5 include shift.e 30.6 include coverage.e 30.7 +include msgtext.e 30.8 30.9 export integer op_info1, op_info2 30.10 export integer optimized_while 30.11 @@ -35,8 +36,8 @@ 30.12 -- temps needed for LHS subscripting 30.13 export symtab_index lhs_subs1_copy_temp, lhs_target_temp 30.14 -- Code generation Stack 30.15 -sequence cg_stack -- expression stack 30.16 -integer cgi -- expression stack top-of-stack index 30.17 +export sequence cg_stack -- expression stack 30.18 +export integer cgi -- expression stack top-of-stack index 30.19 30.20 boolean assignable = FALSE -- did previous op have a re-assignable result? 30.21 30.22 @@ -127,7 +128,30 @@ 30.23 {WITH, "with"}, 30.24 {WITHOUT, "without"}, 30.25 {WHILE, "while"}, 30.26 - {'?', "?"} 30.27 + {'?', "?"}, 30.28 + {MEMSTRUCT, "a memstruct"}, 30.29 + {MEMUNION, "a memunion"}, 30.30 + {MEMSTRUCT_ASSIGN, "="}, 30.31 + {MEMSTRUCT_PLUS, "+="}, 30.32 + {MEMSTRUCT_MINUS, "-="}, 30.33 + {MEMSTRUCT_MULTIPLY, "*="}, 30.34 + {MEMSTRUCT_DIVIDE, "/="}, 30.35 + {MS_CHAR, "char"}, 30.36 + {MS_SHORT, "short"}, 30.37 + {MS_INT, "int" }, 30.38 + {MS_LONG, "long int" }, 30.39 + {MS_LONGLONG, "long long int" }, 30.40 + {MS_FLOAT, "float" }, 30.41 + {MS_DOUBLE, "double" }, 30.42 + {MS_LONGDOUBLE, "long double" }, 30.43 + {MS_EUDOUBLE, "eudouble" }, 30.44 + {MS_OBJECT, "object" }, 30.45 + {MS_POINTER, "pointer" }, 30.46 + {MS_SIGNED, "signed" }, 30.47 + {MS_UNSIGNED, "unsigned" }, 30.48 + {MS_MEMBER, "a memstruct member"}, 30.49 + {MEMTYPE, "a memtype"}, 30.50 + $ 30.51 } 30.52 30.53 export procedure Push(symtab_pointer x) 30.54 @@ -483,6 +507,7 @@ 30.55 op_result[TAIL] = T_SEQUENCE 30.56 op_result[REMOVE] = T_SEQUENCE 30.57 op_result[REPLACE] = T_SEQUENCE 30.58 +op_result[PEEK_ARRAY] = T_SEQUENCE 30.59 30.60 sequence op_temp_ref = repeat( NO_REFERENCE, MAX_OPCODE ) 30.61 op_temp_ref[RIGHT_BRACE_N] = NEW_REFERENCE 30.62 @@ -573,6 +598,9 @@ 30.63 op_temp_ref[GETS] = NEW_REFERENCE 30.64 op_temp_ref[GETENV] = NEW_REFERENCE 30.65 op_temp_ref[RAND] = NEW_REFERENCE 30.66 +op_temp_ref[PEEK_ARRAY] = NEW_REFERENCE 30.67 +op_temp_ref[PEEK_MEMBER] = NEW_REFERENCE 30.68 +op_temp_ref[MEMSTRUCT_READ] = NEW_REFERENCE 30.69 30.70 procedure cont11ii(integer op, boolean ii) 30.71 -- if ii is TRUE then integer arg always produces integer result 30.72 @@ -1401,9 +1429,36 @@ 30.73 -- 2 inputs, 1 output 30.74 case MINUS, rw:APPEND, PREPEND, COMPARE, EQUAL, 30.75 SYSTEM_EXEC, rw:CONCAT, REPEAT, MACHINE_FUNC, C_FUNC, 30.76 - SPRINTF, TASK_CREATE, HASH, HEAD, TAIL, DELETE_ROUTINE then 30.77 + SPRINTF, TASK_CREATE, HASH, HEAD, TAIL, DELETE_ROUTINE, 30.78 + MEMSTRUCT_READ then 30.79 cont21ii(op, FALSE) 30.80 30.81 + case ADDRESSOF, OFFSETOF then 30.82 + -- last OP should have been PEEK_MEMBER 30.83 + if length( Code ) < 4 then 30.84 + CompileErr( MISSING_MEMSTRUCT_MEMBER ) 30.85 + elsif Code[$-4] != PEEK_MEMBER and Code[$-1] != MEMSTRUCT_READ then 30.86 + InternalErr("Expected to replace PEEK_MEMBER or MEMSTRUCT_READ") 30.87 + end if 30.88 + 30.89 + -- We'll replace PEEK_MEMBER with ADDRESSOF 30.90 + Pop() 30.91 + if op = ADDRESSOF then 30.92 + Push( Code[$-3] ) 30.93 + Code = remove( Code, length( Code ) - 4, length( Code ) ) 30.94 + else 30.95 + Push( Code[$-2] ) 30.96 + for pc = length( Code ) - 8 to 1 by -1 do 30.97 + if Code[pc] = MEMSTRUCT_ACCESS then 30.98 + Code = remove( Code, pc, length( Code ) ) 30.99 + exit 30.100 + end if 30.101 + end for 30.102 + 30.103 + end if 30.104 + 30.105 + cont11ii(op, FALSE) 30.106 + 30.107 case SC2_NULL then -- correct the stack - we aren't emitting anything 30.108 c = Pop() 30.109 TempKeep(c) 30.110 @@ -1435,7 +1490,8 @@ 30.111 assignable = FALSE 30.112 30.113 -- 3 inputs, 1 output 30.114 - case RHS_SLICE, FIND, MATCH, FIND_FROM, MATCH_FROM, SPLICE, INSERT, REMOVE, OPEN then 30.115 + case RHS_SLICE, FIND, MATCH, FIND_FROM, MATCH_FROM, SPLICE, INSERT, REMOVE, OPEN, 30.116 + MEMSTRUCT_ARRAY, PEEK_ARRAY, PEEK_MEMBER then 30.117 emit_opcode(op) 30.118 c = Pop() 30.119 b = Pop() 30.120 @@ -1690,6 +1746,13 @@ 30.121 c = Pop() 30.122 assignable = FALSE 30.123 30.124 + case MEM_TYPE_CHECK then 30.125 + -- 1 input, 0 output 30.126 + emit_opcode(op) 30.127 + c = Pop() 30.128 + emit_addr( c ) 30.129 + assignable = FALSE 30.130 + 30.131 -- 0 inputs, 1 output, special op 30.132 case DOLLAR then 30.133 if current_sequence[$] < 0 or SymTab[current_sequence[$]][S_SCOPE] = SC_UNDEFINED then 30.134 @@ -1783,6 +1846,31 @@ 30.135 end if 30.136 assignable = FALSE 30.137 30.138 + case MEMSTRUCT_ACCESS, ARRAY_ACCESS then 30.139 + a = Pop() -- number of elements 30.140 + if op = ARRAY_ACCESS then 30.141 + -- subscript: 30.142 + b = Pop() 30.143 + end if 30.144 + sequence members = repeat( 0, a ) 30.145 + for i = a to 1 by -1 do 30.146 + members[i] = Pop() 30.147 + end for 30.148 + 30.149 + emit_opcode( op ) 30.150 + emit_addr( a ) 30.151 + emit_addr( Pop() ) 30.152 + for i = 1 to length( members ) do 30.153 + emit_addr( members[i] ) 30.154 + end for 30.155 + if op = ARRAY_ACCESS then 30.156 + -- subscript: 30.157 + emit_addr( b ) 30.158 + end if 30.159 + c = NewTempSym() 30.160 + Push( c ) 30.161 + emit_addr( c ) 30.162 + assignable = FALSE 30.163 case REF_TEMP then 30.164 -- Used by the Translator to save temps 30.165 emit_opcode( REF_TEMP ) 30.166 @@ -1791,7 +1879,22 @@ 30.167 case DEREF_TEMP then 30.168 emit_opcode( DEREF_TEMP ) 30.169 emit_addr( Pop() ) 30.170 + 30.171 + case MEMSTRUCT_ASSIGN, MEMSTRUCT_PLUS, MEMSTRUCT_MINUS, 30.172 + MEMSTRUCT_DIVIDE, MEMSTRUCT_MULTIPLY then 30.173 30.174 + c = Pop() -- new value 30.175 + integer deref_ptr = Pop() 30.176 + b = Pop() -- member sym 30.177 + a = Pop() -- pointer 30.178 + 30.179 + emit_opcode( op ) 30.180 + emit_addr( a ) 30.181 + emit_addr( b ) 30.182 + emit_addr( c ) 30.183 + emit_addr( deref_ptr ) 30.184 + assignable = FALSE 30.185 + 30.186 case else 30.187 InternalErr(259, {op}) 30.188
31.1 --- a/source/error.e Mon Dec 19 23:19:58 2011 -0300 31.2 +++ b/source/error.e Wed Dec 21 16:45:49 2011 -0300 31.3 @@ -9,6 +9,10 @@ 31.4 without type_check 31.5 end ifdef 31.6 31.7 +ifdef CRASH_ON_ERROR then 31.8 + include std/error.e 31.9 +end ifdef 31.10 + 31.11 include std/io.e 31.12 include std/text.e 31.13 31.14 @@ -294,7 +298,7 @@ 31.15 close(TempErrFile) 31.16 TempErrFile = -2 31.17 ifdef CRASH_ON_ERROR then 31.18 - display( call_stack() ) 31.19 + crash("Crashing on compiler error for internal traceback") 31.20 end ifdef 31.21 Cleanup(1) 31.22 end if 31.23 @@ -310,14 +314,19 @@ 31.24 --** 31.25 -- Handles internal compile-time errors 31.26 -- see RTInternal() for run-time internal errors 31.27 -export procedure InternalErr(integer msgno, object args = {}) 31.28 +export procedure InternalErr(object msgno, object args = {}) 31.29 31.30 sequence msg 31.31 if atom(args) then 31.32 args = {args} 31.33 end if 31.34 - 31.35 - msg = GetMsgText(msgno, 1, args) 31.36 + 31.37 + if atom( msgno ) then 31.38 + msg = GetMsgText(msgno, 1, args) 31.39 + else 31.40 + msg = format(msgno, args) 31.41 + end if 31.42 + 31.43 if TRANSLATE then 31.44 screen_output(STDERR, GetMsgText(211, 1, {msg})) 31.45 else
32.1 --- a/source/execute.e Mon Dec 19 23:19:58 2011 -0300 32.2 +++ b/source/execute.e Wed Dec 21 16:45:49 2011 -0300 32.3 @@ -20,11 +20,14 @@ 32.4 without type_check 32.5 end ifdef 32.6 32.7 +include std/convert.e 32.8 +include std/dll.e 32.9 +include std/error.e 32.10 +include std/io.e 32.11 include std/os.e 32.12 include std/pretty.e 32.13 -include std/io.e 32.14 +include std/text.e 32.15 include std/types.e 32.16 -include std/text.e 32.17 32.18 include global.e 32.19 include opnames.e 32.20 @@ -35,6 +38,7 @@ 32.21 include mode.e as mode 32.22 include intinit.e 32.23 include coverage.e 32.24 +include emit.e 32.25 32.26 include std/machine.e as dep 32.27 without inline 32.28 @@ -598,19 +602,24 @@ 32.29 32.30 procedure quit_after_error() 32.31 -- final termination 32.32 +puts(1, "quit!\n") 32.33 write_coverage_db() 32.34 32.35 + ifdef CRASH_ON_ERROR then 32.36 + crash("crashing on error") 32.37 + end ifdef 32.38 + 32.39 ifdef WINDOWS then 32.40 if not batch_job and not test_only then 32.41 puts(2, "\nPress Enter...\n") 32.42 getc(0) 32.43 end if 32.44 end ifdef 32.45 - 32.46 + 32.47 abort(1) 32.48 end procedure 32.49 32.50 -procedure RTFatalType(integer x) 32.51 +procedure RTFatalType(integer x, integer member = 0 ) 32.52 -- handle a fatal run-time type-check error 32.53 sequence msg, v 32.54 sequence vname 32.55 @@ -624,6 +633,9 @@ 32.56 vname = "inlined variable" 32.57 end if 32.58 msg = sprintf("type_check failure, %s is ", {vname}) 32.59 + if member then 32.60 + a = member 32.61 + end if 32.62 v = sprint(val[a]) 32.63 if length(v) > 70 - length(vname) then 32.64 v = v[1..70 - length(vname)] 32.65 @@ -1161,7 +1173,7 @@ 32.66 slist[a][LINE], 32.67 line}) 32.68 trace_line += 1 32.69 - if trace_line >= 5000 then 32.70 + if trace_line >= trace_lines then 32.71 -- wrap around to start of file 32.72 trace_line = 0 32.73 one_trace_line("") 32.74 @@ -1463,6 +1475,31 @@ 32.75 pc += 3 32.76 end procedure 32.77 32.78 +procedure opMEMSTRUCT_ASSIGN() 32.79 + atom pointer = val[Code[pc+1]] 32.80 + integer struct_sym = Code[pc+2] 32.81 + object source_val = val[Code[pc+3]] 32.82 + integer deref_ptr = Code[pc+4] 32.83 + integer tok = sym_token( struct_sym ) 32.84 + if SymTab[struct_sym][S_MEM_POINTER] then 32.85 + if deref_ptr then 32.86 + pointer = peek_pointer( pointer ) 32.87 + else 32.88 + tok = MS_MEMBER 32.89 + end if 32.90 + end if 32.91 + 32.92 + switch tok do 32.93 + case MEMSTRUCT then 32.94 + write_memstruct( pointer, struct_sym, source_val ) 32.95 + case MEMUNION then 32.96 + poke( pointer, source_val & repeat( 0, SymTab[struct_sym][S_MEM_SIZE] - length( source_val ) ) ) 32.97 + case else 32.98 + poke_member( pointer, struct_sym, source_val, deref_ptr ) 32.99 + end switch 32.100 + pc += 5 32.101 +end procedure 32.102 + 32.103 procedure opELSE() 32.104 -- ELSE, EXIT, ENDWHILE 32.105 pc = Code[pc+1] 32.106 @@ -2002,6 +2039,16 @@ 32.107 pc += 1 32.108 end procedure 32.109 32.110 +procedure opMEM_TYPE_CHECK() 32.111 +-- type check for a user-defined type 32.112 +-- this always follows a type-call 32.113 + if val[Code[pc-1]] = 0 then 32.114 + RTFatalType(pc + 1, Code[pc - 2]) 32.115 + end if 32.116 + pc += 2 32.117 +end procedure 32.118 + 32.119 + 32.120 procedure kill_temp( symtab_index sym ) 32.121 if sym_mode( sym ) = M_TEMP then 32.122 val[sym] = NOVALUE 32.123 @@ -2227,6 +2274,29 @@ 32.124 pc += 4 32.125 end procedure 32.126 32.127 +procedure opMEMSTRUCT_ASSIGN_OP() 32.128 + atom pointer = val[Code[pc+1]] 32.129 + if Code[pc+4] then 32.130 + pointer = peek_pointer( pointer ) 32.131 + end if 32.132 + atom v = peek_member( pointer, Code[pc+2], , -1 ) 32.133 + atom x = val[Code[pc+3]] 32.134 + 32.135 + switch Code[pc] do 32.136 + case MEMSTRUCT_PLUS then 32.137 + v += x 32.138 + case MEMSTRUCT_MINUS then 32.139 + v -= x 32.140 + case MEMSTRUCT_DIVIDE then 32.141 + v /= x 32.142 + case MEMSTRUCT_MULTIPLY then 32.143 + v *= x 32.144 + end switch 32.145 + 32.146 + poke_member( pointer, Code[pc+2], v, -1 ) 32.147 + pc += 5 32.148 +end procedure 32.149 + 32.150 procedure opPLUS() 32.151 -- PLUS, PLUS_I 32.152 a = Code[pc+1] 32.153 @@ -3071,6 +3141,14 @@ 32.154 val[target] = peek8s(val[a]) 32.155 pc += 3 32.156 end procedure 32.157 + 32.158 +procedure opPEEK_POINTER() 32.159 + a = Code[pc+1] 32.160 + target = Code[pc+2] 32.161 + val[target] = peek_pointer(val[a]) 32.162 + pc += 3 32.163 +end procedure 32.164 + 32.165 procedure opPEEK_STRING() 32.166 a = Code[pc+1] 32.167 target = Code[pc+2] 32.168 @@ -3095,10 +3173,394 @@ 32.169 procedure opSIZEOF() 32.170 a = Code[pc+1] 32.171 b = Code[pc+2] 32.172 - val[b] = sizeof( val[a] ) 32.173 + integer id = sym_token( a ) 32.174 + switch id do 32.175 + case MEMSTRUCT, MEMUNION, MS_MEMBER, MEMTYPE then 32.176 + val[b] = SymTab[a][S_MEM_SIZE] 32.177 + case MS_CHAR then val[b] = sizeof( char ) 32.178 + case MS_SHORT then val[b] = sizeof( short ) 32.179 + case MS_INT then val[b] = sizeof( int ) 32.180 + case MS_LONG then val[b] = sizeof( long ) 32.181 + case MS_LONGLONG then val[b] = sizeof( long long ) 32.182 + case MS_OBJECT then val[b] = sizeof( object ) 32.183 + case MS_FLOAT then val[b] = sizeof( float ) 32.184 + case MS_DOUBLE then val[b] = sizeof( double ) 32.185 + case MS_LONGDOUBLE then val[b] = sizeof( long double ) 32.186 + case MS_EUDOUBLE then val[b] = sizeof( eudouble ) 32.187 + case else 32.188 + val[b] = sizeof( val[a] ) 32.189 + end switch 32.190 + 32.191 pc += 3 32.192 end procedure 32.193 32.194 +procedure opOFFSETOF() 32.195 + a = Code[pc+1] 32.196 + b = Code[pc+2] 32.197 + val[b] = SymTab[a][S_MEM_OFFSET] 32.198 + pc += 3 32.199 +end procedure 32.200 + 32.201 +procedure opADDRESSOF() 32.202 + a = Code[pc+1] 32.203 + b = Code[pc+2] 32.204 + val[b] = val[a] 32.205 + pc += 3 32.206 +end procedure 32.207 + 32.208 +function mem_access( integer member_count, atom ptr ) 32.209 + 32.210 + b = pc + 2 + member_count -- the last member 32.211 + 32.212 + for i = pc+3 to b do 32.213 + ptr += SymTab[Code[i]][S_MEM_OFFSET] 32.214 + if SymTab[Code[i]][S_MEM_POINTER] and i < b then 32.215 + ptr = peek_pointer( ptr ) 32.216 + end if 32.217 + end for 32.218 + return ptr 32.219 +end function 32.220 + 32.221 +integer memaccess = 0 32.222 +procedure opARRAY_ACCESS() 32.223 + -- pc+1 number of accesses 32.224 + -- pc+2 pointer to memstruct 32.225 + -- pc+2 .. pc+n+2 member syms for access 32.226 + -- pc+n+3 subscript sym 32.227 + -- pc+n+4 target for pointer 32.228 + memaccess = ARRAY_ACCESS 32.229 + integer 32.230 + member_count = Code[pc+1], 32.231 + subscript_sym = Code[pc + member_count + 3], 32.232 + array_sym = Code[pc + member_count + 2] 32.233 + atom ptr = mem_access( member_count, val[Code[pc+2]] ) 32.234 + 32.235 + integer element_size = SymTab[array_sym][S_MEM_SIZE] 32.236 + if SymTab[array_sym][S_MEM_ARRAY] then 32.237 + element_size /= SymTab[array_sym][S_MEM_ARRAY] 32.238 + end if 32.239 + ptr += val[subscript_sym] * element_size 32.240 + val[Code[pc + member_count + 4]] = ptr 32.241 + 32.242 + pc += member_count + 5 32.243 +end procedure 32.244 + 32.245 +procedure opMEMSTRUCT_ACCESS() 32.246 + -- pc+1 number of accesses 32.247 + -- pc+2 pointer to memstruct 32.248 + -- pc+2 .. pc+n+2 member syms for access 32.249 + -- pc+n+3 target for pointer 32.250 + memaccess = MEMSTRUCT_ACCESS 32.251 + integer 32.252 + member_count = Code[pc+1] 32.253 + atom ptr = mem_access( member_count, val[Code[pc+2]] ) 32.254 + val[Code[pc + member_count + 3]] = ptr 32.255 + pc += member_count + 4 32.256 +end procedure 32.257 + 32.258 +procedure opMEMSTRUCT_ARRAY() 32.259 + -- pc+1 pointer 32.260 + -- pc+2 member sym 32.261 + -- pc+3 subscript 32.262 + -- pc+4 target 32.263 + atom ptr = val[Code[pc+1]] 32.264 + integer size = SymTab[Code[pc+2]][S_MEM_SIZE] 32.265 + ptr += val[Code[pc+3]] * size 32.266 + val[Code[pc+4]] = ptr 32.267 + pc += 5 32.268 +end procedure 32.269 + 32.270 +procedure poke_member_value( atom pointer, integer data_type, object value ) 32.271 + switch data_type do 32.272 + case MS_CHAR then 32.273 + poke( pointer, value ) 32.274 + case MS_SHORT then 32.275 + poke2( pointer, value ) 32.276 + case MS_INT then 32.277 + poke4( pointer, value ) 32.278 + case MS_LONG then 32.279 + ifdef WINDOWS then 32.280 + poke4( pointer, value ) 32.281 + elsedef 32.282 + poke_pointer( pointer, value ) 32.283 + end ifdef 32.284 + case MS_LONGLONG then 32.285 + poke8( pointer, value ) 32.286 + case MS_OBJECT then 32.287 + poke_pointer( pointer, value ) 32.288 + case MS_FLOAT then 32.289 + poke( pointer, atom_to_float32( value ) ) 32.290 + case MS_DOUBLE then 32.291 + poke( pointer, atom_to_float64( value ) ) 32.292 + case MS_LONGDOUBLE then 32.293 + poke( pointer, atom_to_float80( value ) ) 32.294 + case MS_EUDOUBLE then 32.295 + if sizeof( C_POINTER ) = 4 then 32.296 + poke( pointer, atom_to_float64( value ) ) 32.297 + else 32.298 + poke( pointer, atom_to_float80( value ) ) 32.299 + end if 32.300 + case else 32.301 + -- just return the struct in bytes 32.302 + RTFatal( "Error assigning to a memstruct -- can only assign primitive data members" ) 32.303 + end switch 32.304 +end procedure 32.305 + 32.306 +procedure poke_member( atom pointer, integer sym, object value, integer deref_ptr = 0 ) 32.307 + integer data_type = SymTab[sym][S_TOKEN] 32.308 + integer signed = SymTab[sym][S_MEM_SIGNED] 32.309 + 32.310 + if SymTab[sym][S_MEM_POINTER] and not deref_ptr then 32.311 + data_type = MS_OBJECT 32.312 + signed = 0 32.313 + end if 32.314 + 32.315 + if SymTab[sym][S_MEM_ARRAY] then 32.316 + integer array_length = SymTab[sym][S_MEM_ARRAY] 32.317 + integer max = array_length 32.318 + integer size = SymTab[sym][S_MEM_SIZE] / array_length 32.319 + if memaccess = ARRAY_ACCESS then 32.320 + poke_member_value( pointer, data_type, value ) 32.321 + else 32.322 + if array_length < length( value ) then 32.323 + max = length( value ) 32.324 + end if 32.325 + for i = 1 to max do 32.326 + poke_member_value( pointer, data_type, value[i] ) 32.327 + pointer += size 32.328 + end for 32.329 + for i = max + 1 to array_length do 32.330 + poke_member_value( pointer, data_type, 0 ) 32.331 + pointer += size 32.332 + end for 32.333 + end if 32.334 + else 32.335 + poke_member_value( pointer, data_type, value ) 32.336 + end if 32.337 + 32.338 +end procedure 32.339 + 32.340 +procedure write_memstruct( atom pointer, integer sym, object value ) 32.341 + if atom( value ) then 32.342 + value = {value} 32.343 + end if 32.344 + 32.345 + integer member = SymTab[sym][S_MEM_NEXT] 32.346 + 32.347 + for i = 1 to length( value ) do 32.348 + 32.349 + if not member then 32.350 + exit 32.351 + end if 32.352 + poke_member( pointer + SymTab[member][S_MEM_OFFSET], member, value[i] ) 32.353 + 32.354 + member = SymTab[member][S_MEM_NEXT] 32.355 + 32.356 + end for 32.357 + 32.358 + -- zero out the rest 32.359 + integer ix = length( value ) + 1 32.360 + while member do 32.361 + poke_member( pointer + SymTab[member][S_MEM_OFFSET], member, 0 ) 32.362 + 32.363 + member = SymTab[member][S_MEM_NEXT] 32.364 + end while 32.365 +end procedure 32.366 + 32.367 +--** 32.368 +-- Peek a member value. 32.369 +-- 32.370 +-- deref_ptr: Identifies if the pointer needs to be dereferenced if the member is a pointer. 32.371 +-- If deref_ptr is 0, then the pointer value is assigned. 32.372 +-- If deref_ptr is 1, then the pointer is dereferenced and the assignment of the actual type is done. 32.373 +-- If deref_ptr is anything else, the pointer is assumed to already be dereferenced, and the 32.374 +-- value is assigned as the member's data type, since the caller has already dereferenced the pointer. 32.375 +function peek_member( atom pointer, integer sym, integer array_index = -1, integer deref_ptr = 0 ) 32.376 + integer data_type = SymTab[sym][S_TOKEN] 32.377 + integer signed = SymTab[sym][S_MEM_SIGNED] 32.378 + 32.379 + if SymTab[sym][S_MEM_POINTER] then 32.380 + if deref_ptr = 1 then 32.381 + -- result of ptr.MEMSTRUCT.member.* 32.382 + pointer = peek_pointer( pointer ) 32.383 + elsif deref_ptr = 0 then 32.384 + -- just return the pointer itself 32.385 + data_type = MS_OBJECT 32.386 + signed = 0 32.387 + end if 32.388 + 32.389 + elsif array_index != -1 then 32.390 + integer element_size = SymTab[sym][S_MEM_SIZE] / SymTab[sym][S_MEM_ARRAY] 32.391 + pointer += element_size * array_index 32.392 + 32.393 + elsif SymTab[sym][S_MEM_ARRAY] then 32.394 + sequence s = repeat( 0, SymTab[sym][S_MEM_ARRAY] ) 32.395 + for i = 1 to SymTab[sym][S_MEM_ARRAY] do 32.396 + s[i] = peek_member( pointer, sym, i-1) 32.397 + end for 32.398 + return s 32.399 + end if 32.400 + 32.401 + switch data_type do 32.402 + case MS_CHAR then 32.403 + if signed then 32.404 + return peeks( pointer ) 32.405 + else 32.406 + return peek( pointer ) 32.407 + end if 32.408 + case MS_SHORT then 32.409 + if signed then 32.410 + return peek2s( pointer ) 32.411 + else 32.412 + return peek2u( pointer ) 32.413 + end if 32.414 + case MS_INT then 32.415 + if signed then 32.416 + return peek4s( pointer ) 32.417 + else 32.418 + return peek4u( pointer ) 32.419 + end if 32.420 + case MS_LONG then 32.421 + ifdef WINDOWS then 32.422 + if signed then 32.423 + return peek4s( pointer ) 32.424 + else 32.425 + return peek4u( pointer ) 32.426 + end if 32.427 + elsedef 32.428 + if sizeof( C_LONG ) = 4 then 32.429 + if signed then 32.430 + return peek4s( pointer ) 32.431 + else 32.432 + return peek4u( pointer ) 32.433 + end if 32.434 + else 32.435 + if signed then 32.436 + return peek8s( pointer ) 32.437 + else 32.438 + return peek8u( pointer ) 32.439 + end if 32.440 + end if 32.441 + end ifdef 32.442 + case MS_LONGLONG then 32.443 + if signed then 32.444 + return peek8s( pointer ) 32.445 + else 32.446 + return peek8u( pointer ) 32.447 + end if 32.448 + case MS_OBJECT then 32.449 + if sizeof( C_POINTER ) = 4 then 32.450 + if signed then 32.451 + return peek4s( pointer ) 32.452 + else 32.453 + return peek4u( pointer ) 32.454 + end if 32.455 + else 32.456 + if signed then 32.457 + return peek8s( pointer ) 32.458 + else 32.459 + return peek8u( pointer ) 32.460 + end if 32.461 + end if 32.462 + case MS_FLOAT then 32.463 + return float32_to_atom( peek( { pointer, 4 } ) ) 32.464 + case MS_DOUBLE then 32.465 + return float64_to_atom( peek( { pointer, 8 } ) ) 32.466 + case MS_LONGDOUBLE then 32.467 + return float80_to_atom( peek( { pointer, 10 } ) ) 32.468 + case MS_EUDOUBLE then 32.469 + if sizeof( C_POINTER ) = 4 then 32.470 + return float64_to_atom( peek( { pointer, 8 } ) ) 32.471 + else 32.472 + return float80_to_atom( peek( { pointer, 10 } ) ) 32.473 + end if 32.474 + case else 32.475 + -- just return the struct in bytes 32.476 + return read_member( pointer, sym ) 32.477 + end switch 32.478 +end function 32.479 + 32.480 +function read_memstruct( atom pointer, symtab_pointer member_sym ) 32.481 + sequence s = {} 32.482 + if sym_token( member_sym ) != MEMSTRUCT then 32.483 + -- we want to walk the actual struct 32.484 + member_sym = SymTab[member_sym][S_MEM_STRUCT] 32.485 + end if 32.486 + while member_sym with entry do 32.487 + s = append( s, peek_member( pointer + SymTab[member_sym][S_MEM_OFFSET], member_sym ) ) 32.488 + entry 32.489 + member_sym = SymTab[member_sym][S_MEM_NEXT] 32.490 + end while 32.491 + return s 32.492 +end function 32.493 + 32.494 +function read_memunion( atom pointer, symtab_pointer member_sym ) 32.495 + return peek( { pointer, SymTab[member_sym][S_MEM_SIZE] } ) 32.496 +end function 32.497 + 32.498 +function read_member( atom pointer, symtab_index sym ) 32.499 + 32.500 + symtab_pointer member_sym = sym 32.501 + integer tid = sym_token( sym ) 32.502 + if tid >= MS_SIGNED and tid <= MS_OBJECT then 32.503 + -- simple serialization of primitives... 32.504 + return peek_member( pointer, sym ) 32.505 + end if 32.506 + 32.507 + integer member_token = sym_token( member_sym ) 32.508 + if member_token = MEMSTRUCT then 32.509 + return read_memstruct( pointer, member_sym ) 32.510 + 32.511 + elsif member_token = MEMUNION then 32.512 + return read_memunion( pointer, member_sym ) 32.513 + 32.514 + else 32.515 + member_token = SymTab[SymTab[member_sym][S_MEM_STRUCT]][S_TOKEN] 32.516 + if member_token = MEMSTRUCT then 32.517 + return read_memstruct( pointer, member_sym ) 32.518 + 32.519 + elsif member_token = MEMUNION then 32.520 + return read_memunion( pointer, member_sym ) 32.521 + else 32.522 + RTFatal( "Cannot serialize a: " & LexName( member_token ) ) 32.523 + end if 32.524 + end if 32.525 +end function 32.526 + 32.527 +procedure opMEMSTRUCT_READ() 32.528 + atom pointer = val[Code[pc+1]] 32.529 + val[Code[pc+3]] = read_member( pointer, Code[pc+2] ) 32.530 + pc += 4 32.531 +end procedure 32.532 + 32.533 +procedure opPEEK_ARRAY() 32.534 + -- pc+1 pointer 32.535 + -- pc+2 member sym 32.536 + -- pc+3 subscript 32.537 + -- pc+4 target 32.538 + atom 32.539 + member_sym = Code[pc+2], 32.540 + ptr = val[Code[pc+1]] + SymTab[member_sym][S_MEM_OFFSET], 32.541 + subscript = val[Code[pc+3]] 32.542 + val[Code[pc+4]] = peek_member( ptr, member_sym, subscript ) 32.543 + pc += 5 32.544 +end procedure 32.545 + 32.546 +procedure opPEEK_MEMBER() 32.547 + -- pc+1 pointer 32.548 + -- pc+2 member 32.549 + -- pc+3 deref ptr 32.550 + -- pc+4 target 32.551 + 32.552 + atom pointer = val[Code[pc+1]] 32.553 + a = Code[pc+2] 32.554 + target = Code[pc+4] 32.555 + 32.556 + val[target] = peek_member( pointer, a, , Code[pc+3] ) 32.557 + 32.558 + pc += 5 32.559 +end procedure 32.560 + 32.561 procedure opPOKE() 32.562 a = Code[pc+1] 32.563 b = Code[pc+2] 32.564 @@ -3120,6 +3582,14 @@ 32.565 pc += 3 32.566 end procedure 32.567 32.568 +procedure opPOKE_POINTER() 32.569 + a = Code[pc+1] 32.570 + b = Code[pc+2] 32.571 + poke_pointer(val[a], val[b]) 32.572 + pc += 3 32.573 +end procedure 32.574 + 32.575 + 32.576 procedure opPOKE2() 32.577 a = Code[pc+1] 32.578 b = Code[pc+2] 32.579 @@ -3981,7 +4451,7 @@ 32.580 32.581 case EQUALS then 32.582 opEQUALS() 32.583 - 32.584 + 32.585 case EQUALS_IFW, EQUALS_IFW_I then 32.586 opEQUALS_IFW() 32.587 32.588 @@ -4212,10 +4682,10 @@ 32.589 opPOKE8() 32.590 32.591 case POKE_POINTER then 32.592 - opPOKE4() 32.593 + opPOKE_POINTER() 32.594 32.595 case PEEK_POINTER then 32.596 - opPEEK4U() 32.597 + opPEEK_POINTER() 32.598 32.599 case POSITION then 32.600 opPOSITION() 32.601 @@ -4378,6 +4848,9 @@ 32.602 32.603 case TYPE_CHECK then 32.604 opTYPE_CHECK() 32.605 + 32.606 + case MEM_TYPE_CHECK then 32.607 + opMEM_TYPE_CHECK() 32.608 32.609 case UMINUS then 32.610 opUMINUS() 32.611 @@ -4413,6 +4886,35 @@ 32.612 32.613 case SIZEOF then 32.614 opSIZEOF() 32.615 + 32.616 + case MEMSTRUCT_ACCESS then 32.617 + opMEMSTRUCT_ACCESS() 32.618 + 32.619 + case ARRAY_ACCESS then 32.620 + opARRAY_ACCESS() 32.621 + 32.622 + case MEMSTRUCT_ARRAY then 32.623 + opMEMSTRUCT_ARRAY() 32.624 + 32.625 + case PEEK_ARRAY then 32.626 + opPEEK_ARRAY() 32.627 + case PEEK_MEMBER then 32.628 + opPEEK_MEMBER() 32.629 + 32.630 + case MEMSTRUCT_READ then 32.631 + opMEMSTRUCT_READ() 32.632 + 32.633 + case MEMSTRUCT_ASSIGN then 32.634 + opMEMSTRUCT_ASSIGN() 32.635 + 32.636 + case MEMSTRUCT_PLUS, MEMSTRUCT_MINUS, MEMSTRUCT_MULTIPLY, MEMSTRUCT_DIVIDE then 32.637 + opMEMSTRUCT_ASSIGN_OP() 32.638 + 32.639 + case ADDRESSOF then 32.640 + opADDRESSOF() 32.641 + 32.642 + case OFFSETOF then 32.643 + opOFFSETOF() 32.644 32.645 case else 32.646 RTFatal( sprintf("Unknown opcode: %d", op ) )
33.1 --- a/source/fwdref.e Mon Dec 19 23:19:58 2011 -0300 33.2 +++ b/source/fwdref.e Wed Dec 21 16:45:49 2011 -0300 33.3 @@ -23,7 +23,7 @@ 33.4 include reswords.e 33.5 include block.e 33.6 include emit.e 33.7 - 33.8 +include memstruct.e 33.9 33.10 -- Tracking forward references 33.11 sequence 33.12 @@ -31,7 +31,8 @@ 33.13 active_subprogs = {}, 33.14 active_references = {}, 33.15 toplevel_references = {}, 33.16 - inactive_references = {} 33.17 + inactive_references = {}, 33.18 + $ 33.19 33.20 33.21 enum 33.22 @@ -171,6 +172,9 @@ 33.23 end procedure 33.24 33.25 export procedure add_data( integer ref, object data ) 33.26 + if atom( forward_references[ref][FR_DATA] ) then 33.27 + forward_references[ref][FR_DATA] = { forward_references[ref][FR_DATA] } 33.28 + end if 33.29 forward_references[ref][FR_DATA] = append( forward_references[ref][FR_DATA], data ) 33.30 end procedure 33.31 33.32 @@ -385,6 +389,98 @@ 33.33 current_file_no = fr[FR_FILE] 33.34 end procedure 33.35 33.36 + 33.37 +procedure patch_forward_msmember( token tok, integer ref ) 33.38 + sequence fr = forward_references[ref] 33.39 + symtab_index sym = tok[T_SYM] 33.40 + 33.41 + if fr[FR_OP] = MEMSTRUCT_DECL then 33.42 + symtab_index member = fr[FR_DATA] 33.43 + switch tok[T_ID] do 33.44 + case MEMSTRUCT_DECL, MEMSTRUCT then 33.45 + -- a forward reference inside a declaration 33.46 + SymTab[member][S_MEM_STRUCT] = sym 33.47 + case MEMTYPE then 33.48 + -- memtype alias 33.49 + integer real_type_sym = SymTab[sym][S_MEM_PARENT] 33.50 + SymTab[member][S_MEM_STRUCT] = real_type_sym 33.51 + SymTab[member][S_TOKEN] = sym_token( real_type_sym ) 33.52 + case else 33.53 + -- ?? not handled...leave it unreferenced 33.54 + return 33.55 + end switch 33.56 + 33.57 + SymTab[member][S_SCOPE] = SC_MEMSTRUCT 33.58 + SymTab[member][S_MEM_SIZE] = SymTab[sym][S_MEM_SIZE] 33.59 + 33.60 + if not SymTab[member][S_MEM_POINTER] then 33.61 + symtab_index parent_sym = SymTab[member][S_MEM_PARENT] 33.62 + recalculate_size( parent_sym ) 33.63 + end if 33.64 + resolved_reference( ref ) 33.65 + else 33.66 + 33.67 + InternalErr( sprintf("Unhandled memstruct member fwd ref op: %d", tok[T_ID] ) ) 33.68 + end if 33.69 + 33.70 +end procedure 33.71 + 33.72 +procedure patch_forward_memstruct( token tok, integer ref ) 33.73 + sequence fr = forward_references[ref] 33.74 + symtab_index sym = tok[T_SYM] 33.75 + 33.76 + switch fr[FR_OP] do 33.77 + case MEMSTRUCT_DECL then 33.78 + -- need to check the size 33.79 + 33.80 + if sym_token( sym ) = MEMTYPE then 33.81 + recalculate_size( SymTab[sym][S_MEM_PARENT] ) 33.82 + end if 33.83 + if recalculate_size( sym )> 0 then 33.84 + resolved_reference( ref ) 33.85 + end if 33.86 + 33.87 + case VARIABLE then 33.88 + patch_var_use( ref, fr, sym, 1 ) 33.89 + 33.90 + case MEMSTRUCT_ACCESS, SIZEOF, OFFSETOF, ADDRESSOF then 33.91 + integer pc = fr[FR_PC] 33.92 + set_code( ref ) 33.93 + integer rx = find( -ref, Code, pc ) 33.94 + if rx then 33.95 + -- these aren't always emitted 33.96 + Code[rx] = sym 33.97 + end if 33.98 + resolved_reference( ref ) 33.99 + 33.100 + if fr[FR_OP] = SIZEOF then 33.101 + break 33.102 + end if 33.103 + 33.104 + for i = 2 to length( fr[FR_DATA] ) do 33.105 + -- clean up any members tied to this 33.106 + integer m_ref = fr[FR_DATA][i] 33.107 + rx = find( -m_ref, Code, pc ) 33.108 + if rx then 33.109 + -- look it up 33.110 + integer m_sym = resolve_members( forward_references[m_ref][FR_DATA], sym ) 33.111 + if m_sym then 33.112 + Code[rx] = m_sym 33.113 + resolved_reference( m_ref ) 33.114 + end if 33.115 + else 33.116 + resolved_reference( m_ref ) 33.117 + end if 33.118 + end for 33.119 + reset_code() 33.120 + 33.121 + case else 33.122 + -- TODO: ?? 33.123 + CompileErr( "Unimplemented: patching forward memstruct with op - %d\n", fr[FR_OP] ) 33.124 + end switch 33.125 + 33.126 +end procedure 33.127 + 33.128 procedure patch_forward_variable( token tok, integer ref ) 33.129 -- forward reference for a variable 33.130 sequence fr = forward_references[ref] 33.131 @@ -406,6 +502,20 @@ 33.132 SymTab[sym][S_USAGE] = or_bits( U_READ, SymTab[sym][S_USAGE] ) 33.133 end if 33.134 33.135 + patch_var_use( ref, fr, sym ) 33.136 + 33.137 +end procedure 33.138 + 33.139 +procedure patch_forward_init_check( token tok, integer ref ) 33.140 +-- forward reference for a variable 33.141 + sequence fr = forward_references[ref] 33.142 + set_code( ref ) 33.143 + Code[fr[FR_PC]+1] = tok[T_SYM] 33.144 + resolved_reference( ref ) 33.145 + reset_code() 33.146 +end procedure 33.147 + 33.148 +procedure patch_var_use( integer ref, sequence fr, integer sym, integer remove_init_check = 0 ) 33.149 set_code( ref ) 33.150 integer pc = fr[FR_PC] 33.151 if pc < 1 then 33.152 @@ -421,19 +531,16 @@ 33.153 end while 33.154 resolved_reference( ref ) 33.155 end if 33.156 + 33.157 + if remove_init_check then 33.158 + if Code[pc] = GLOBAL_INIT_CHECK then 33.159 + replace_code( {}, pc, pc+1, fr[FR_SUBPROG]) 33.160 + end if 33.161 + end if 33.162 + 33.163 reset_code() 33.164 end procedure 33.165 33.166 -procedure patch_forward_init_check( token tok, integer ref ) 33.167 --- forward reference for a variable 33.168 - sequence fr = forward_references[ref] 33.169 - set_code( ref ) 33.170 - Code[fr[FR_PC]+1] = tok[T_SYM] 33.171 - resolved_reference( ref ) 33.172 - reset_code() 33.173 -end procedure 33.174 - 33.175 - 33.176 function expected_name( integer id ) 33.177 33.178 switch id with fallthru do 33.179 @@ -456,13 +563,22 @@ 33.180 33.181 procedure patch_forward_type( token tok, integer ref ) 33.182 sequence fr = forward_references[ref] 33.183 - sequence syms = fr[FR_DATA] 33.184 - for i = 2 to length( syms ) do 33.185 - SymTab[syms[i]][S_VTYPE] = tok[T_SYM] 33.186 - if TRANSLATE then 33.187 - SymTab[syms[i]][S_GTYPE] = CompileType(tok[T_SYM]) 33.188 + if sequence( fr[FR_DATA] ) then 33.189 + sequence syms = fr[FR_DATA] 33.190 + 33.191 + if fr[FR_OP] = MEMSTRUCT then 33.192 + for i = 2 to length( syms ) do 33.193 + SymTab[syms[i]][S_MEM_TYPE] = tok[T_SYM] 33.194 + end for 33.195 + else 33.196 + for i = 2 to length( syms ) do 33.197 + SymTab[syms[i]][S_VTYPE] = tok[T_SYM] 33.198 + if TRANSLATE then 33.199 + SymTab[syms[i]][S_GTYPE] = CompileType(tok[T_SYM]) 33.200 + end if 33.201 + end for 33.202 end if 33.203 - end for 33.204 + end if 33.205 resolved_reference( ref ) 33.206 end procedure 33.207 33.208 @@ -511,6 +627,23 @@ 33.209 resolved_reference( ref ) 33.210 end procedure 33.211 33.212 +procedure patch_forward_mem_type_check( token tok, integer ref ) 33.213 + integer which_type = tok[T_SYM] 33.214 + sequence fr = forward_references[ref] 33.215 + set_code( ref ) 33.216 + 33.217 + integer 33.218 + c = NewTempSym(), 33.219 + pc = fr[FR_PC], 33.220 + var = Code[pc+1] 33.221 + 33.222 + SymTab[fr[FR_SUBPROG]][S_STACK_SPACE] += 1 33.223 + replace_code( { PROC, which_type, var, c }, pc, pc+2, fr[FR_SUBPROG] ) 33.224 + 33.225 + reset_code() 33.226 + 33.227 + resolved_reference( ref ) 33.228 +end procedure 33.229 33.230 procedure patch_forward_type_check( token tok, integer ref ) 33.231 sequence fr = forward_references[ref] 33.232 @@ -739,9 +872,12 @@ 33.233 forward_references[ref][FR_QUALIFIED] = get_qualified_fwd() 33.234 forward_references[ref][FR_OP] = op 33.235 33.236 - if op = GOTO then 33.237 - forward_references[ref][FR_DATA] = { sym } 33.238 - end if 33.239 + switch op do 33.240 + case GOTO then 33.241 + forward_references[ref][FR_DATA] = { sym } 33.242 + case GLOBAL_INIT_CHECK then 33.243 + forward_references[ref][FR_DATA] = sym 33.244 + end switch 33.245 33.246 -- If we're recording tokens (for a default parameter), this ref will never 33.247 -- get resolved. So ignore it for now, and when someone actually calls 33.248 @@ -768,7 +904,6 @@ 33.249 end if 33.250 fwdref_count += 1 33.251 end if 33.252 - 33.253 return ref 33.254 end function 33.255 33.256 @@ -825,6 +960,9 @@ 33.257 case CONSTANT, ENUM, VARIABLE then 33.258 patch_forward_variable( tok, ref ) 33.259 break "fr_type" 33.260 + case MEMSTRUCT, MEMUNION then 33.261 + patch_forward_memstruct( tok, ref ) 33.262 + break "fr_type" 33.263 case else 33.264 forward_error( tok, ref ) 33.265 end switch 33.266 @@ -843,6 +981,15 @@ 33.267 33.268 case GOTO then 33.269 patch_forward_goto( tok, ref ) 33.270 + 33.271 + case MS_MEMBER then 33.272 + patch_forward_msmember( tok, ref ) 33.273 + 33.274 + case MEMSTRUCT, MEMTYPE then 33.275 + patch_forward_memstruct( tok, ref ) 33.276 + 33.277 + case MEM_TYPE_CHECK then 33.278 + patch_forward_mem_type_check( tok, ref ) 33.279 33.280 case else 33.281 -- ?? what is it? 33.282 @@ -890,14 +1037,12 @@ 33.283 if (length( active_subprogs[i] ) or length(toplevel_references[i])) 33.284 and (i = current_file_no or finished_files[i] or unincluded_ok) 33.285 then 33.286 - 33.287 for j = length( active_references[i] ) to 1 by -1 do 33.288 errors &= resolve_file( active_references[i][j], report_errors, unincluded_ok ) 33.289 end for 33.290 errors &= resolve_file( toplevel_references[i], report_errors, unincluded_ok ) 33.291 end if 33.292 end for 33.293 - 33.294 if report_errors and length( errors ) then 33.295 sequence msg = "" 33.296 sequence errloc 33.297 @@ -930,8 +1075,17 @@ 33.298 end if 33.299 else 33.300 -- unqualified 33.301 - errloc = sprintf("\t\'%s\' (%s:%d) has not been declared.\n", 33.302 - {ref[FR_NAME], abbreviate_path(known_files[ref[FR_FILE]]), ref[FR_LINE]}) 33.303 + if ref[FR_TYPE] = MEMTYPE then 33.304 + if SymTab[ref[FR_DATA]][S_MEM_SIZE] then 33.305 + continue 33.306 + else 33.307 + errloc = sprintf("\tthe size of \'%s\' (%s:%d) could not be determined.\n", 33.308 + {ref[FR_NAME], abbreviate_path(known_files[ref[FR_FILE]]), ref[FR_LINE]}) 33.309 + end if 33.310 + else 33.311 + errloc = sprintf("\t\'%s\' (%s:%d) has not been declared.\n", 33.312 + {ref[FR_NAME], abbreviate_path(known_files[ref[FR_FILE]]), ref[FR_LINE]}) 33.313 + end if 33.314 end if 33.315 case SC_MULTIPLY_DEFINED then 33.316 sequence syms = tok[THESE_GLOBALS] -- there should be no forward references in here. 33.317 @@ -1019,6 +1173,8 @@ 33.318 else 33.319 integer file = SymTab[shifting_sub][S_FILE_NO] 33.320 integer sp = find( shifting_sub, active_subprogs[file] ) 33.321 - shift_these( active_references[file][sp], pc, amount ) 33.322 + if sp then 33.323 + shift_these( active_references[file][sp], pc, amount ) 33.324 + end if 33.325 end if 33.326 end procedure
34.1 --- a/source/global.e Mon Dec 19 23:19:58 2011 -0300 34.2 +++ b/source/global.e Wed Dec 21 16:45:49 2011 -0300 34.3 @@ -156,6 +156,20 @@ 34.4 -- external call, e.g. call to a DLL 34.5 S_HAS_DELETE = 54 34.6 34.7 +-- for memstructs / memunions only 34.8 +export constant 34.9 + S_MEM_SIZE = 14 - get_backend() * 5, 34.10 + S_MEM_OFFSET = 15 - get_backend() * 5, 34.11 + S_MEM_SIGNED = 16 - get_backend() * 5, 34.12 + S_MEM_POINTER = 17 - get_backend() * 5, 34.13 + S_MEM_ARRAY = 18 - get_backend() * 5, 34.14 + S_MEM_NEXT = 19 - get_backend() * 5, 34.15 + S_MEM_STRUCT = 20 - get_backend() * 5, -- for embedded structs 34.16 + S_MEM_PARENT = 21 - get_backend() * 5, 34.17 + S_MEM_TYPE = 22 - get_backend() * 5, 34.18 + S_MEM_RECALC = 23 - get_backend() * 5, 34.19 + $ 34.20 + 34.21 export procedure print_sym(integer s) 34.22 printf(1,"[%d]:\n", {s} ) 34.23 object s_obj = SymTab[s][S_OBJ] 34.24 @@ -184,8 +198,9 @@ 34.25 SIZEOF_ROUTINE_ENTRY = 30 + 25 * TRANSLATE, 34.26 SIZEOF_VAR_ENTRY = 17 + 37 * TRANSLATE, 34.27 SIZEOF_BLOCK_ENTRY = 19 + 35 * TRANSLATE, 34.28 - SIZEOF_TEMP_ENTRY = 6 + 32 * TRANSLATE 34.29 - 34.30 + SIZEOF_TEMP_ENTRY = 6 + 32 * TRANSLATE, 34.31 + SIZEOF_MEMSTRUCT_ENTRY = 23 + 32 * TRANSLATE - 5 * get_backend(), 34.32 + $ 34.33 -- Permitted values for various symbol table fields 34.34 34.35 -- MODE values: 34.36 @@ -199,7 +214,8 @@ 34.37 34.38 -- SCOPE values: 34.39 export enum 34.40 - SC_LOOP_VAR=2, -- "private" loop vars known within a single loop 34.41 + SC_NONE, 34.42 + SC_LOOP_VAR, -- "private" loop vars known within a single loop 34.43 SC_PRIVATE, -- private within subprogram 34.44 SC_GLOOP_VAR, -- "global" loop var 34.45 SC_LOCAL, -- local to the file 34.46 @@ -210,7 +226,8 @@ 34.47 SC_MULTIPLY_DEFINED, -- global symbol defined in 2 or more files 34.48 SC_EXPORT, -- visible to anyone that includes the file 34.49 SC_OVERRIDE, -- override an internal 34.50 - SC_PUBLIC -- visible to any file that includes it, or via "public include" 34.51 + SC_PUBLIC, -- visible to any file that includes it, or via "public include" 34.52 + SC_MEMSTRUCT 34.53 34.54 -- USAGE values -- how symbol has been used (1,2 can be OR'd) 34.55 export enum 34.56 @@ -366,7 +383,7 @@ 34.57 end if 34.58 return TRUE 34.59 end if 34.60 - if FUNC <= t[T_ID] and t[T_ID] <= NAMESPACE then 34.61 + if FUNC <= t[T_ID] and t[T_ID] < LAST_TOKEN then 34.62 return TRUE 34.63 end if 34.64 return FALSE 34.65 @@ -588,4 +605,4 @@ 34.66 return x = -1 or symtab_index(x) or forward_reference(x) 34.67 end type 34.68 34.69 - 34.70 +export integer trace_lines = 500
35.1 --- a/source/il.e Mon Dec 19 23:19:58 2011 -0300 35.2 +++ b/source/il.e Wed Dec 21 16:45:49 2011 -0300 35.3 @@ -46,6 +46,7 @@ 35.4 { "quiet", 0, GetMsgText(304, 0), { } }, 35.5 { "copyright", 0, GetMsgText(312, 0), { } }, 35.6 { "eudir", 0, GetMsgText(328,0), { HAS_PARAMETER, "dir" } }, 35.7 + { "eub", 0, GetMsgText(345,0), { HAS_PARAMETER, "backend runner" } }, 35.8 $ 35.9 } 35.10 elsedef 35.11 @@ -120,9 +121,16 @@ 35.12 for i = length(SymTab) to 1 by -1 do 35.13 if length(SymTab[i]) >= S_NREFS then 35.14 -- not temp or literal or constant, and not deleted yet 35.15 - if SymTab[i][S_MODE] = M_NORMAL and 35.16 + if 0 and SymTab[i][S_SCOPE] = SC_MEMSTRUCT and 35.17 + length(SymTab[i]) != SIZEOF_MEMSTRUCT_ENTRY then 35.18 + 35.19 + SymTab[i] = {0, SymTab[i][S_NEXT]} -- delete it 35.20 + 35.21 + elsif SymTab[i][S_MODE] = M_NORMAL and 35.22 SymTab[i][S_NREFS] = 0 and 35.23 - SymTab[i][S_SCOPE] > SC_PRIVATE then -- tricky to delete privates 35.24 + SymTab[i][S_SCOPE] > SC_PRIVATE and 35.25 + SymTab[i][S_SCOPE] != SC_MEMSTRUCT and 35.26 + length(SymTab[i]) != SIZEOF_MEMSTRUCT_ENTRY then -- tricky to delete privates 35.27 -- delete this symbol 35.28 if find(SymTab[i][S_TOKEN], RTN_TOKS) then 35.29 -- a routine 35.30 @@ -197,7 +205,9 @@ 35.31 SymTab[i] = SymTab[i][1..4] & SymTab[i][S_NEXT_IN_BLOCK] 35.32 35.33 else 35.34 - if find(SymTab[i][S_TOKEN], RTN_TOKS) then 35.35 + switch SymTab[i][S_TOKEN] do 35.36 + 35.37 + case PROC, FUNC, TYPE then 35.38 -- routine 35.39 if not full_debug then 35.40 SymTab[i][S_LINETAB] = 0 35.41 @@ -210,8 +220,37 @@ 35.42 SymTab[i][S_TEMPS], SymTab[i][S_NUM_ARGS], 35.43 SymTab[i][S_FIRSTLINE], 35.44 SymTab[i][S_STACK_SPACE]} 35.45 - 35.46 - else 35.47 + 35.48 + case MS_CHAR, MS_SHORT, MS_INT, MS_LONG, MS_LONGLONG, 35.49 + MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE, 35.50 + MS_OBJECT, MS_MEMBER, MEMSTRUCT, MEMUNION, 35.51 + MEMSTRUCT_DECL, MEMUNION_DECL, MEMTYPE 35.52 + then 35.53 + if length( SymTab[i] ) = SIZEOF_MEMSTRUCT_ENTRY then 35.54 + SymTab[i] = SymTab[i][1..4] & 35.55 + { 35.56 + SymTab[i][S_NEXT_IN_BLOCK], 35.57 + SymTab[i][S_FILE_NO], 35.58 + SymTab[i][S_NAME], 35.59 + SymTab[i][S_TOKEN], 35.60 + $ 35.61 + } & 35.62 + SymTab[i][S_MEM_SIZE..S_MEM_RECALC] 35.63 + elsif SymTab[i][S_SCOPE] = SC_MEMSTRUCT then 35.64 + -- We keep the primitive memstruct entries for their sizes 35.65 + SymTab[i] = SymTab[i][1..4] & 35.66 + { 35.67 + SymTab[i][S_NEXT_IN_BLOCK], 35.68 + SymTab[i][S_FILE_NO], 35.69 + SymTab[i][S_NAME], 35.70 + SymTab[i][S_TOKEN], 35.71 + SymTab[i][S_MEM_SIZE], 35.72 + $ 35.73 + } 35.74 + 35.75 + end if 35.76 + 35.77 + case else 35.78 -- variable 35.79 -- constants are deleted (but there will be an OBJ field 35.80 -- to hold their value at run-time) 35.81 @@ -229,8 +268,9 @@ 35.82 SymTab[i][S_NAME], 35.83 SymTab[i][S_TOKEN],{}, 35.84 SymTab[i][S_BLOCK]} 35.85 + 35.86 end if 35.87 - end if 35.88 + end switch 35.89 35.90 end if 35.91 end for
36.1 --- a/source/intinit.e Mon Dec 19 23:19:58 2011 -0300 36.2 +++ b/source/intinit.e Wed Dec 21 16:45:49 2011 -0300 36.3 @@ -26,7 +26,7 @@ 36.4 { "coverage-db", 0, GetMsgText(333,0), { NO_CASE, ONCE, HAS_PARAMETER, "file" } }, 36.5 { "coverage-erase", 0, GetMsgText(334,0), { NO_CASE, ONCE } }, 36.6 { "coverage-exclude", 0, GetMsgText(338,0), { NO_CASE, MULTIPLE, HAS_PARAMETER, "pattern"} }, 36.7 - { 0, "debugger", GetMsgText( 354, 0), {NO_CASE, ONCE, HAS_PARAMETER, "debugger"} }, 36.8 + { 0, "debugger", GetMsgText( 357, 0), {NO_CASE, ONCE, HAS_PARAMETER, "debugger"} }, 36.9 $ 36.10 } 36.11
37.1 --- a/source/keylist.e Mon Dec 19 23:19:58 2011 -0300 37.2 +++ b/source/keylist.e Wed Dec 21 16:45:49 2011 -0300 37.3 @@ -7,6 +7,7 @@ 37.4 elsedef 37.5 without type_check 37.6 end ifdef 37.7 +include std/dll.e 37.8 37.9 include global.e 37.10 include reswords.e 37.11 @@ -21,7 +22,8 @@ 37.12 K_EFFECT, -- side effects 37.13 -- optional fields 37.14 K_CODE, 37.15 - K_DEF_ARGS 37.16 + K_DEF_ARGS, 37.17 + K_MEM_SIZE 37.18 37.19 -- N.B. order and number of keywords and builtins 37.20 -- is assumed by scanner.e, euphoria\bin\keywords.e, and others 37.21 @@ -172,7 +174,26 @@ 37.22 {"poke_pointer", SC_PREDEF, PROC, POKE_POINTER, 2, E_OTHER_EFFECT}, 37.23 {"peek_pointer", SC_PREDEF, FUNC, PEEK_POINTER, 1, E_PURE}, 37.24 {"sizeof", SC_PREDEF, FUNC, SIZEOF, 1, E_PURE}, 37.25 + {"memstruct", SC_KEYWORD, MEMSTRUCT_DECL, 0, 0, 0 }, 37.26 + {"memunion", SC_KEYWORD, MEMUNION_DECL, 0, 0, 0 }, 37.27 + {"pointer", SC_MEMSTRUCT, MS_POINTER, 0, 0, 0, 0, 0, sizeof( C_POINTER ) }, 37.28 + {"unsigned", SC_MEMSTRUCT, MS_UNSIGNED, 0, 0, 0 }, 37.29 + {"signed", SC_MEMSTRUCT, MS_SIGNED, 0, 0, 0 }, 37.30 + {"char", SC_MEMSTRUCT, MS_CHAR, 0, 0, 0, 0, 0, sizeof( C_CHAR ) }, 37.31 + {"short", SC_MEMSTRUCT, MS_SHORT, 0, 0, 0, 0, 0, sizeof( C_SHORT ) }, 37.32 + {"int", SC_MEMSTRUCT, MS_INT, 0, 0, 0, 0, 0, sizeof( C_INT ) }, 37.33 + {"long", SC_MEMSTRUCT, MS_LONG, 0, 0, 0, 0, 0, sizeof( C_LONG ) }, 37.34 + {"float", SC_MEMSTRUCT, MS_FLOAT, 0, 0, 0, 0, 0, sizeof( C_FLOAT ) }, 37.35 + {"double", SC_MEMSTRUCT, MS_DOUBLE, 0, 0, 0, 0, 0, sizeof( C_DOUBLE ) }, 37.36 + {"eudouble", SC_MEMSTRUCT, MS_EUDOUBLE, 0, 0, 0, 0, 0, sizeof( C_POINTER ) * 2 }, 37.37 + {"object", SC_MEMSTRUCT, MS_OBJECT, 0, 0, 0, 0, 0, sizeof( C_POINTER ) }, 37.38 + {"as", SC_MEMSTRUCT, MS_AS, 0, 0, 0 }, 37.39 + {"addressof", SC_PREDEF, FUNC, ADDRESSOF, 1, E_PURE}, 37.40 + {"offsetof", SC_PREDEF, FUNC, OFFSETOF, 1, E_PURE}, 37.41 {"deprecate", SC_KEYWORD, DEPRECATE, 0, 0, 0}, 37.42 + {"memtype", SC_KEYWORD, MEMTYPE, 0, 0, 0 }, 37.43 + {"long double", SC_MEMSTRUCT, MS_LONGDOUBLE, 0, 0, 0, 0, 0, 16 }, 37.44 + {"long long", SC_MEMSTRUCT, MS_LONGLONG, 0, 0, 0, 0, 0, sizeof( C_LONGLONG ) }, 37.45 $ 37.46 37.47 }
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/source/memstruct.e Wed Dec 21 16:45:49 2011 -0300 38.3 @@ -0,0 +1,1048 @@ 38.4 +include common.e 38.5 +include emit.e 38.6 +include error.e 38.7 +include fwdref.e 38.8 +include global.e 38.9 +include msgtext.e 38.10 +include parser.e 38.11 +include platform.e 38.12 +include reswords.e 38.13 +include scanner.e 38.14 +include symtab.e 38.15 + 38.16 +include std/dll.e 38.17 +with trace 38.18 +integer is_union = 0 38.19 +symtab_pointer last_sym = 0 38.20 +symtab_index mem_struct 38.21 + 38.22 +export procedure MemUnion_declaration( integer scope ) 38.23 + is_union = 1 38.24 + MemStruct_declaration( scope ) 38.25 + is_union = 0 38.26 +end procedure 38.27 + 38.28 +function primitive_size( integer primitive ) 38.29 + switch primitive do 38.30 + case MS_CHAR then 38.31 + return 1 38.32 + case MS_SHORT then 38.33 + return 2 38.34 + case MS_INT then 38.35 + return sizeof( C_INT ) 38.36 + case MS_LONG then 38.37 + return sizeof( C_LONG ) 38.38 + case MS_LONGLONG then 38.39 + return sizeof( C_LONGLONG ) 38.40 + case MS_OBJECT then 38.41 + return sizeof( C_POINTER ) 38.42 + case MS_FLOAT then 38.43 + return 4 38.44 + case MS_DOUBLE then 38.45 + return 8 38.46 + case MS_EUDOUBLE then 38.47 + ifdef E32 then 38.48 + return 8 38.49 + elsifdef E64 then 38.50 + -- same as long double 38.51 + return 16 38.52 + end ifdef 38.53 + end switch 38.54 +end function 38.55 + 38.56 +constant 38.57 + MULTI_CHAR = { MS_CHAR }, 38.58 + MULTI_SHORT = { MS_SHORT }, 38.59 + MULTI_INT = { MS_INT }, 38.60 + MULTI_LONG = { MS_LONG }, 38.61 + MULTI_LONG_INT = { MS_LONG, MS_INT }, 38.62 + MULTI_LONG_LONG = { MS_LONG, MS_LONG }, 38.63 + MULTI_LONG_LONG_INT = { MS_LONG, MS_LONG, MS_INT }, 38.64 + MULTI_LONG_DOUBLE = { MS_LONG, MS_DOUBLE }, 38.65 + $ 38.66 + 38.67 +enum 38.68 + MULTI_PARSE_SIGNED, 38.69 + MULTI_PARSE_ID, 38.70 + MULTI_PARSE_SYM 38.71 + 38.72 +function multi_part_memtype( token tok, integer terminator = MS_AS ) 38.73 + integer tid = tok[T_ID] 38.74 + integer sym = tok[T_SYM] 38.75 + integer signed = tid != MS_UNSIGNED 38.76 + integer sign_specified = 1 38.77 + sequence parts = {} 38.78 + if signed and tid != MS_SIGNED then 38.79 + putback( tok ) 38.80 + sign_specified = 0 38.81 + end if 38.82 + 38.83 + for i = 1 to 4 do 38.84 + -- 3 is the most we can have, and then we better his an MS_AS... 38.85 + tok = next_token() 38.86 + tid = tok[T_ID] 38.87 + 38.88 + switch tid do 38.89 + case MS_CHAR, MS_SHORT, MS_INT then 38.90 + parts &= tid 38.91 + sym = tok[T_SYM] 38.92 + exit 38.93 + case MS_LONG then 38.94 + parts &= tid 38.95 + sym = tok[T_SYM] 38.96 + 38.97 + case MS_DOUBLE then 38.98 + if sign_specified then 38.99 + CompileErr( FP_NOT_SIGNED ) 38.100 + end if 38.101 + parts &= tid 38.102 + sym = tok[T_SYM] 38.103 + exit 38.104 + 38.105 + case MS_FLOAT then 38.106 + if sign_specified or length( parts ) then 38.107 + CompileErr( FP_NOT_SIGNED ) 38.108 + end if 38.109 + parts &= tid 38.110 + sym = tok[T_SYM] 38.111 + exit 38.112 + case else 38.113 + 38.114 + if tid = terminator then 38.115 + putback( tok ) 38.116 + exit 38.117 + end if 38.118 + 38.119 + if sign_specified and not length( parts ) then 38.120 + CompileErr( EXPECTED_PRIMITIVE_MEMSTRUCT_TYPE ) 38.121 + end if 38.122 + parts &= tid 38.123 + sym = tok[T_SYM] 38.124 + exit 38.125 + end switch 38.126 + end for 38.127 + 38.128 + -- validate... 38.129 + switch parts do 38.130 + case MULTI_CHAR, MULTI_SHORT, MULTI_INT then 38.131 + tid = parts[$] 38.132 + 38.133 + case MULTI_LONG, MULTI_LONG_INT then 38.134 + tok = MS_LONG 38.135 + 38.136 + case MULTI_LONG_LONG, MULTI_LONG_LONG_INT then 38.137 + tid = MS_LONGLONG 38.138 + sym = ms_longlong_sym 38.139 + 38.140 + case MULTI_LONG_DOUBLE then 38.141 + if not sign_specified then 38.142 + tid = MS_LONGDOUBLE 38.143 + sym = ms_longdouble_sym 38.144 + else 38.145 + -- error! 38.146 + CompileErr( FP_NOT_SIGNED ) 38.147 + end if 38.148 + 38.149 + end switch 38.150 + return { signed, tid, sym } 38.151 +end function 38.152 + 38.153 +--** 38.154 +-- Special parser for sizeof(). Handles multi-part primitive 38.155 +-- memstruct types. 38.156 +-- 38.157 +-- Returns: 1 if the argument was parsed and emitted, otherwise, 38.158 +-- returns 0, which means that normal argument parsing 38.159 +-- should occur. 38.160 +export function parse_sizeof() 38.161 + tok_match( LEFT_ROUND ) 38.162 + enter_memstruct( 1 ) 38.163 + integer parsed = 1 38.164 + 38.165 + token tok = next_token() 38.166 + switch tok[T_ID] do 38.167 + case MS_SIGNED, MS_UNSIGNED, MS_LONG then 38.168 + 38.169 + sequence multi = multi_part_memtype( tok, RIGHT_ROUND ) 38.170 + emit_opnd( multi[MULTI_PARSE_SYM] ) 38.171 + 38.172 + case MS_INT, MS_CHAR, MS_SHORT, MS_DOUBLE, MS_FLOAT, MS_EUDOUBLE, 38.173 + MEMSTRUCT, MEMTYPE, MEMUNION then 38.174 + 38.175 + emit_opnd( tok[T_SYM] ) 38.176 + 38.177 + case OBJECT, MS_OBJECT, MS_POINTER then 38.178 + ifdef EU_EX then 38.179 + -- some extra stuff gets put in the eu backend 38.180 + -- at the beginning of the SymTab 38.181 + emit_opnd( 157 ) 38.182 + elsedef 38.183 + -- WARNING: Magic number from the keylist! 38.184 + emit_opnd( 152 ) 38.185 + end ifdef 38.186 + case else 38.187 + if SymTab[tok[T_SYM]][S_SCOPE] = SC_UNDEFINED then 38.188 + integer ref = new_forward_reference( MEMSTRUCT, tok[T_SYM], SIZEOF ) 38.189 + emit_opnd( -ref ) 38.190 + else 38.191 + putback( tok ) 38.192 + parsed = 0 38.193 + end if 38.194 + 38.195 + end switch 38.196 + leave_memstruct() 38.197 + return parsed 38.198 +end function 38.199 + 38.200 +--** 38.201 +-- Parse a memstruct access for a memstruct base function 38.202 +-- like offsetof, addressof 38.203 +export procedure parse_memstruct_func( integer op ) 38.204 + tok_match( LEFT_ROUND ) 38.205 + -- The funcs eat this, so it doesn't need to be real 38.206 + Push( 0 ) 38.207 + enter_memstruct( 1 ) 38.208 + MemStruct_access( 1, FALSE ) 38.209 + leave_memstruct() 38.210 + tok_match( RIGHT_ROUND ) 38.211 +end procedure 38.212 + 38.213 +--** 38.214 +-- Parses one memtype declaration. 38.215 +procedure parse_memtype( integer scope ) 38.216 + token mem_type = next_token() 38.217 + if mem_type[T_ID] = DOLLAR then 38.218 + return 38.219 + end if 38.220 + 38.221 + 38.222 + 38.223 + sequence signed_type = multi_part_memtype( mem_type ) 38.224 + 38.225 + symtab_index type_sym = signed_type[MULTI_PARSE_SYM] 38.226 + 38.227 + tok_match( MS_AS ) 38.228 + 38.229 + token new_memtype = next_token() 38.230 + 38.231 + symtab_index sym = new_memtype[T_SYM] 38.232 + symtab:DefinedYet( sym ) 38.233 + SymTab[sym] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[sym] ) ) 38.234 + SymTab[sym][S_SCOPE] = scope 38.235 + SymTab[sym][S_TOKEN] = MEMTYPE 38.236 + SymTab[sym][S_MODE] = M_NORMAL 38.237 + SymTab[sym][S_MEM_SIGNED] = signed_type[MULTI_PARSE_SIGNED] 38.238 + 38.239 + switch signed_type[MULTI_PARSE_ID] do 38.240 + case MS_SIGNED, MS_UNSIGNED, 38.241 + MS_LONG, MS_LONGLONG, 38.242 + MS_CHAR, MS_SHORT, MS_INT, 38.243 + MS_FLOAT, MS_DOUBLE, MS_EUDOUBLE, 38.244 + MS_OBJECT 38.245 + then 38.246 + SymTab[sym][S_MEM_TYPE] = signed_type[MULTI_PARSE_ID] 38.247 + SymTab[sym][S_MEM_PARENT] = type_sym 38.248 + SymTab[sym][S_MEM_SIZE] = primitive_size( signed_type[MULTI_PARSE_ID] ) 38.249 + 38.250 + case else 38.251 + 38.252 + SymTab[sym][S_MEM_PARENT] = type_sym 38.253 + SymTab[sym][S_MEM_SIZE] = SymTab[type_sym][S_MEM_SIZE] 38.254 + 38.255 + if not TRANSLATE and not SymTab[sym][S_MEM_SIZE] then 38.256 + SymTab[sym][S_MEM_SIZE] = recalculate_size( type_sym ) 38.257 + -- mark it as a forward reference to have its size recalculated 38.258 + 38.259 + integer ref = new_forward_reference( MEMTYPE, sym, MEMSTRUCT_DECL ) 38.260 + set_data( ref, sym ) 38.261 + add_recalc( type_sym, sym ) 38.262 + Show( sym ) -- creating a fwdref removes the symbol, but we just want to recalc the size later on 38.263 + end if 38.264 + end switch 38.265 +end procedure 38.266 + 38.267 +--* 38.268 +-- Creates an alias for a memstruct type. May be a primitive or 38.269 +-- a memstruct. Multiple memtypes may be declared at once, separated 38.270 +-- by commas, possibly ending with a list terminating $. 38.271 +export procedure MemType( integer scope ) 38.272 + enter_memstruct( 1 ) 38.273 + 38.274 + token tok = { COMMA, 0 } 38.275 + while tok[T_ID] = COMMA do 38.276 + parse_memtype( scope ) 38.277 + tok = next_token() 38.278 + end while 38.279 + putback( tok ) 38.280 + 38.281 + leave_memstruct() 38.282 +end procedure 38.283 + 38.284 +procedure DefinedYet( symtab_index sym ) 38.285 + sequence name = sym_name( sym ) 38.286 + symtab_pointer mem_entry = mem_struct 38.287 + 38.288 + while mem_entry with entry do 38.289 + if equal( sym_name( mem_entry ), name ) then 38.290 + CompileErr(31, {name}) 38.291 + end if 38.292 + entry 38.293 + mem_entry = SymTab[mem_entry][S_MEM_NEXT] 38.294 + end while 38.295 +end procedure 38.296 + 38.297 +export procedure MemStruct_declaration( integer scope ) 38.298 + token tok = next_token() -- name 38.299 + mem_struct = tok[T_SYM] 38.300 + symtab:DefinedYet( mem_struct ) 38.301 + enter_memstruct( mem_struct ) 38.302 + last_sym = mem_struct 38.303 + SymTab[mem_struct] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[mem_struct] ) ) 38.304 + if is_union then 38.305 + SymTab[mem_struct][S_TOKEN] = MEMUNION 38.306 + else 38.307 + SymTab[mem_struct][S_TOKEN] = MEMSTRUCT 38.308 + end if 38.309 + SymTab[mem_struct][S_SCOPE] = scope 38.310 + 38.311 + integer pointer = 0 38.312 + integer signed = -1 38.313 + integer long = 0 38.314 + integer eu_type = 0 38.315 + while 1 with entry do 38.316 + integer tid = tok[T_ID] 38.317 + 38.318 + if tid = MEMTYPE then 38.319 + symtab_index memtype_sym = tok[T_SYM] 38.320 + tid = SymTab[memtype_sym][S_MEM_TYPE] 38.321 + if not tid then 38.322 + symtab_index type_sym = SymTab[memtype_sym][S_MEM_PARENT] 38.323 + tid = sym_token( type_sym ) 38.324 + tok[T_SYM] = type_sym 38.325 + tok[T_ID] = tid 38.326 + end if 38.327 + end if 38.328 + 38.329 + switch tid label "token" do 38.330 + case END then 38.331 + -- eventually, we probably need to handle ifdefs, 38.332 + -- which may be best handled by refactoring Ifdef_Statement in parser.e 38.333 + if is_union then 38.334 + tok_match( MEMUNION_DECL, END ) 38.335 + else 38.336 + tok_match( MEMSTRUCT_DECL, END ) 38.337 + end if 38.338 + exit 38.339 + 38.340 + case TYPE, QUALIFIED_TYPE then 38.341 + tok_match( MS_AS ) 38.342 + eu_type = tok[T_SYM] 38.343 + 38.344 + case MEMSTRUCT, MEMUNION, QUALIFIED_MEMSTRUCT, QUALIFIED_MEMUNION then 38.345 + -- embedding 38.346 + MemStruct_member( tok, pointer ) 38.347 + -- reset the flags 38.348 + pointer = 0 38.349 + long = 0 38.350 + signed = -1 38.351 + 38.352 + case VARIABLE, QUALIFIED_VARIABLE then 38.353 + if SC_UNDEFINED = SymTab[tok[T_SYM]][S_SCOPE] then 38.354 + -- forward reference 38.355 + 38.356 + if pointer then 38.357 + integer ref = new_forward_reference( TYPE, tok[T_SYM], MEMSTRUCT ) 38.358 + MemStruct_member( tok, pointer, 1 ) 38.359 + else 38.360 + 38.361 + token nt = next_token() 38.362 + if nt[T_ID] = MS_AS then 38.363 + -- a forward reference to a type 38.364 + integer ref = new_forward_reference( TYPE, tok[T_SYM], MEMSTRUCT ) 38.365 + eu_type = -ref 38.366 + break "token" 38.367 + else 38.368 + putback( nt ) 38.369 + MemStruct_member( tok, pointer, 1 ) 38.370 + end if 38.371 + end if 38.372 + 38.373 + else 38.374 + CompileErr( EXPECTED_VALID_MEMSTRUCT ) 38.375 + end if 38.376 + -- reset the flags 38.377 + pointer = 0 38.378 + long = 0 38.379 + signed = -1 38.380 + 38.381 + case MS_SIGNED then 38.382 + if signed != -1 then 38.383 + -- error...multiple signed modifiers 38.384 + CompileErr( EXPECTED_VALID_MEMSTRUCT ) 38.385 + end if 38.386 + signed = 1 38.387 + 38.388 + case MS_UNSIGNED then 38.389 + if signed != -1 then 38.390 + -- error...multiple signed modifiers 38.391 + CompileErr( EXPECTED_VALID_MEMSTRUCT ) 38.392 + end if 38.393 + signed = 0 38.394 + 38.395 + case MS_LONG then 38.396 + token check = next_token() 38.397 + integer id = check[T_ID] 38.398 + if id = MS_INT or id = MS_LONG or id = MS_DOUBLE then 38.399 + long = 1 38.400 + tid = id 38.401 + tok = check 38.402 + else 38.403 + putback( check ) 38.404 + end if 38.405 + fallthru 38.406 + case MS_CHAR, MS_SHORT, MS_INT, MS_FLOAT, MS_DOUBLE, MS_EUDOUBLE, MS_OBJECT then 38.407 + 38.408 + switch tid do 38.409 + case MS_CHAR then 38.410 + Char( eu_type, pointer, signed ) 38.411 + case MS_SHORT then 38.412 + Short( eu_type, pointer, signed ) 38.413 + case MS_INT then 38.414 + if long then 38.415 + Long( eu_type, pointer, signed ) 38.416 + else 38.417 + Int( eu_type, pointer, signed ) 38.418 + end if 38.419 + case MS_LONG then 38.420 + token int_tok = next_token() 38.421 + 38.422 + if long then 38.423 + -- this is the second long... 38.424 + if int_tok[T_ID] = MS_INT then 38.425 + -- long long int 38.426 + LongLong( eu_type, pointer, signed ) 38.427 + 38.428 + elsif int_tok[T_ID] = VARIABLE 38.429 + or int_tok[T_ID] = PROCEDURE 38.430 + or int_tok[T_ID] = FUNCTION 38.431 + or int_tok[T_ID] = TYPE 38.432 + or int_tok[T_ID] = NAMESPACE 38.433 + then 38.434 + -- long long 38.435 + putback( int_tok ) 38.436 + LongLong( eu_type, pointer, signed ) 38.437 + else 38.438 + CompileErr( 25, { sym_name( int_tok[T_SYM] ) } ) 38.439 + end if 38.440 + elsif int_tok[T_ID] = MS_DOUBLE then 38.441 + long = 1 38.442 + putback( int_tok ) 38.443 + -- need to skip the part where the flags get reset 38.444 + break "token" 38.445 + else 38.446 + putback( int_tok ) 38.447 + Long( eu_type, pointer, signed ) 38.448 + end if 38.449 + 38.450 + case MS_FLOAT, MS_DOUBLE, MS_EUDOUBLE then 38.451 + if signed != - 1 then 38.452 + -- can't have signed modifiers here 38.453 + CompileErr( FP_NOT_SIGNED ) 38.454 + end if 38.455 + 38.456 + if long and tid != MS_DOUBLE then 38.457 + -- long modifier only for doubles 38.458 + CompileErr( ONLY_DOUBLE_FP_LONG ) 38.459 + elsif long then 38.460 + tid = MS_LONGDOUBLE 38.461 + end if 38.462 + 38.463 + FloatingPoint( eu_type, tid, pointer ) 38.464 + 38.465 + case MS_OBJECT then 38.466 + Object( eu_type, pointer, signed ) 38.467 + 38.468 + case else 38.469 + 38.470 + end switch 38.471 + symtab_index type_sym = tok[T_SYM] 38.472 + 38.473 + -- reset the flags 38.474 + pointer = 0 38.475 + long = 0 38.476 + signed = -1 38.477 + eu_type = 0 38.478 + 38.479 + case MS_POINTER then 38.480 + -- pointer! 38.481 + pointer = 1 38.482 + 38.483 + case else 38.484 + CompileErr( EXPECTED_VALID_MEMSTRUCT ) 38.485 + end switch 38.486 + entry 38.487 + tok = next_token() 38.488 + end while 38.489 + calculate_size() 38.490 + leave_memstruct() 38.491 +end procedure 38.492 + 38.493 + 38.494 +--* 38.495 +-- Returns the size and offsets, or -1 if all 38.496 +-- sizes have not been determined yet. 38.497 +export function recalculate_size( symtab_index sym ) 38.498 + mem_struct = sym 38.499 + is_union = sym_token( sym ) = MEMUNION_DECL 38.500 + integer size = calculate_size() 38.501 + 38.502 + is_union = 0 38.503 + if size > 0 then 38.504 + for i = 2 to length( SymTab[sym][S_MEM_RECALC] ) do 38.505 + 38.506 + symtab_index recalc_sym = SymTab[sym][S_MEM_RECALC][i] 38.507 + SymTab[recalc_sym][S_MEM_SIZE] = recalculate_size( recalc_sym ) 38.508 + 38.509 + end for 38.510 + end if 38.511 + return size 38.512 +end function 38.513 + 38.514 +procedure add_recalc( symtab_index parent_struct, symtab_index dependent_struct ) 38.515 + if length( SymTab[parent_struct] ) >= SIZEOF_MEMSTRUCT_ENTRY 38.516 + and (atom( SymTab[parent_struct][S_MEM_RECALC] ) 38.517 + or not find( dependent_struct, SymTab[parent_struct][S_MEM_RECALC] )) then 38.518 + SymTab[parent_struct][S_MEM_RECALC] &= dependent_struct 38.519 + end if 38.520 +end procedure 38.521 + 38.522 +--** 38.523 +-- Return the alignment required for the memstruct passed. 38.524 +-- Returs 0 if the alignment cannot yet be determined. 38.525 +function calculate_alignment( symtab_index member_sym ) 38.526 + integer alignment = 0 38.527 + 38.528 + if SymTab[member_sym][S_MEM_STRUCT] then 38.529 + member_sym = SymTab[member_sym][S_MEM_STRUCT] 38.530 + end if 38.531 + 38.532 + integer sym = member_sym 38.533 + if SymTab[sym][S_MEM_SIZE] = -1 then 38.534 + -- we haven't determined the size yet for this 38.535 + return -1 38.536 + end if 38.537 + 38.538 + integer sub_alignment = 0 38.539 + while sym with entry do 38.540 + if SymTab[sym][S_MEM_POINTER] then 38.541 + sub_alignment = sizeof( C_POINTER ) 38.542 + elsif sym_token( sym ) = MS_MEMBER then 38.543 + sub_alignment = calculate_alignment( sym ) 38.544 + if not sub_alignment then 38.545 + return -1 38.546 + end if 38.547 + else 38.548 + -- 32-bit *nix aligns double on 4-byte boundary 38.549 + if IX86 and IUNIX and sym_token( sym ) = MS_DOUBLE then 38.550 + sub_alignment = 4 38.551 + else 38.552 + if SymTab[sym][S_MEM_ARRAY] then 38.553 + sub_alignment = SymTab[sym][S_MEM_SIZE] / SymTab[sym][S_MEM_ARRAY] 38.554 + else 38.555 + sub_alignment = SymTab[sym][S_MEM_SIZE] 38.556 + end if 38.557 + end if 38.558 + end if 38.559 + if sub_alignment > alignment then 38.560 + alignment = sub_alignment 38.561 + end if 38.562 + entry 38.563 + sym = SymTab[sym][S_MEM_NEXT] 38.564 + end while 38.565 + return alignment 38.566 +end function 38.567 + 38.568 +--** 38.569 +-- Calculates how much padding is needed 38.570 +function calculate_padding( symtab_index member_sym, integer size, integer mem_size ) 38.571 + integer padding = 0 38.572 + 38.573 + if SymTab[member_sym][S_MEM_POINTER] then 38.574 + padding = remainder( size, sizeof( C_POINTER ) ) 38.575 + elsif sym_token( member_sym ) = MS_MEMBER then 38.576 + integer alignment = calculate_alignment( member_sym ) 38.577 + if alignment = -1 then 38.578 + return -1 38.579 + elsif alignment then 38.580 + padding = remainder( size, alignment ) 38.581 + end if 38.582 + else 38.583 + if SymTab[member_sym][S_MEM_ARRAY] then 38.584 + mem_size /= SymTab[member_sym][S_MEM_ARRAY] 38.585 + end if 38.586 + 38.587 + -- 32-bit *nix aligns double on 4-byte boundary 38.588 + if sym_token( member_sym ) = MS_DOUBLE and IX86 and IUNIX then 38.589 + padding = remainder( size, 4 ) 38.590 + else 38.591 + padding = remainder( size, mem_size ) 38.592 + end if 38.593 + end if 38.594 + return padding 38.595 +end function 38.596 + 38.597 +--** 38.598 +-- Returns the size and offsets for the memstruct, or -1 if all 38.599 +-- sizes have not been determined yet. 38.600 +function calculate_size() 38.601 + symtab_pointer member_sym = mem_struct 38.602 + 38.603 + if sym_token( member_sym ) = MEMTYPE then 38.604 + if SymTab[SymTab[member_sym][S_MEM_PARENT]][S_MEM_SIZE] < 1 then 38.605 + SymTab[SymTab[member_sym][S_MEM_PARENT]][S_MEM_SIZE] = recalculate_size( SymTab[member_sym][S_MEM_PARENT] ) 38.606 + end if 38.607 + return SymTab[SymTab[member_sym][S_MEM_PARENT]][S_MEM_SIZE] 38.608 + end if 38.609 + 38.610 + integer size = 0 38.611 + integer indeterminate = 0 38.612 + while member_sym and not indeterminate with entry do 38.613 + integer mem_size = SymTab[member_sym][S_MEM_SIZE] 38.614 + if mem_size < 1 then 38.615 + -- might be a struct that's been recalculated 38.616 + symtab_pointer struct_type = SymTab[member_sym][S_MEM_STRUCT] 38.617 + if struct_type then 38.618 + mem_size = SymTab[struct_type][S_MEM_SIZE] 38.619 + if mem_size < 1 then 38.620 + if length( SymTab[struct_type] ) >= SIZEOF_MEMSTRUCT_ENTRY then 38.621 + mem_size = recalculate_size( struct_type ) 38.622 + end if 38.623 + if mem_size < 1 then 38.624 + indeterminate = 1 38.625 + add_recalc( struct_type, mem_struct ) 38.626 + end if 38.627 + end if 38.628 + else 38.629 + indeterminate = 1 38.630 + end if 38.631 + end if 38.632 + if not indeterminate then 38.633 + if not is_union then 38.634 + -- make sure we're properly aligned 38.635 + integer padding = calculate_padding( member_sym, size, mem_size ) 38.636 + 38.637 + if padding < 0 then 38.638 + indeterminate = 1 38.639 + elsif padding then 38.640 + size += padding 38.641 + end if 38.642 + 38.643 + SymTab[member_sym][S_MEM_OFFSET] = size 38.644 + size += mem_size 38.645 + else 38.646 + if mem_size > size then 38.647 + size = mem_size 38.648 + end if 38.649 + end if 38.650 + end if 38.651 + entry 38.652 + member_sym = SymTab[member_sym][S_MEM_NEXT] 38.653 + end while 38.654 + 38.655 + if indeterminate then 38.656 + SymTab[mem_struct][S_MEM_SIZE] = 0 38.657 + return 0 38.658 + else 38.659 + SymTab[mem_struct][S_MEM_SIZE] = size 38.660 + integer alignment = calculate_alignment( mem_struct ) 38.661 + if alignment then 38.662 + integer padding = remainder( size, alignment ) 38.663 + size += padding 38.664 + end if 38.665 + SymTab[mem_struct][S_MEM_SIZE] = size 38.666 + return size 38.667 + end if 38.668 +end function 38.669 + 38.670 +function read_name() 38.671 + token tok = next_token() 38.672 + switch tok[T_ID] do 38.673 + case VARIABLE, PROC, FUNC, TYPE, 38.674 + MS_CHAR, MS_SHORT, MS_INT, MS_LONG, MS_LONGLONG, MS_OBJECT, 38.675 + MS_FLOAT, MS_DOUBLE, MS_LONGDOUBLE, MS_EUDOUBLE, 38.676 + MS_MEMBER then 38.677 + 38.678 + DefinedYet( tok[T_SYM] ) 38.679 + 38.680 + symtab_index member = NewBasicEntry( sym_name( tok[T_SYM] ), 0, SC_MEMSTRUCT, MS_MEMBER, 0, 0, 00 ) 38.681 + SymTab[member] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[member] ) ) 38.682 + 38.683 + return { MS_MEMBER, member } 38.684 + 38.685 + case else 38.686 + CompileErr( 68, {"identifier", LexName( tok[T_ID] )} ) 38.687 + end switch 38.688 +end function 38.689 + 38.690 +function member_array( symtab_index sym ) 38.691 + token tok = next_token() 38.692 + if tok[T_ID] != LEFT_SQUARE then 38.693 + putback( tok ) 38.694 + return 1 38.695 + end if 38.696 + 38.697 + tok = next_token() 38.698 + object size = sym_obj( tok[T_SYM] ) 38.699 + if not integer( size ) or size < 1 then 38.700 + CompileErr( 68, {"positive integer", LexName( tok[T_ID] ) } ) 38.701 + end if 38.702 + 38.703 + SymTab[sym][S_MEM_ARRAY] = sym_obj( tok[T_SYM] ) 38.704 + tok_match( RIGHT_SQUARE ) 38.705 + return size 38.706 +end function 38.707 + 38.708 +procedure add_member( integer type_sym, token name_tok, object mem_type, integer size, integer pointer, integer signed = 0 ) 38.709 + 38.710 + symtab_index sym = name_tok[T_SYM] 38.711 + 38.712 + SymTab[last_sym][S_MEM_NEXT] = sym 38.713 + 38.714 + SymTab[sym] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[sym] ) ) 38.715 + 38.716 + size *= member_array( sym ) 38.717 + 38.718 + if token( mem_type ) then 38.719 + SymTab[sym][S_MEM_STRUCT] = mem_type[T_SYM] 38.720 + mem_type = MS_MEMBER 38.721 + end if 38.722 + 38.723 + if pointer then 38.724 + size = sizeof( C_POINTER ) 38.725 + end if 38.726 + 38.727 + if signed = -1 then 38.728 + signed = 1 38.729 + end if 38.730 + 38.731 + SymTab[sym][S_SCOPE] = SC_MEMSTRUCT 38.732 + SymTab[sym][S_TOKEN] = mem_type 38.733 + SymTab[sym][S_MEM_SIZE] = size 38.734 + SymTab[sym][S_MEM_POINTER] = pointer 38.735 + SymTab[sym][S_MEM_SIGNED] = signed 38.736 + SymTab[sym][S_MEM_PARENT] = mem_struct 38.737 + SymTab[sym][S_MEM_TYPE] = type_sym 38.738 + 38.739 + if type_sym < 0 then 38.740 + register_forward_type( sym, -type_sym ) 38.741 + end if 38.742 + last_sym = sym 38.743 +end procedure 38.744 + 38.745 +procedure Char( integer eu_type, integer pointer, integer signed ) 38.746 + add_member( eu_type, read_name(), MS_CHAR, 1, pointer, signed ) 38.747 +end procedure 38.748 + 38.749 +procedure Short( integer eu_type, integer pointer, integer signed ) 38.750 + add_member( eu_type, read_name(), MS_SHORT, 2, pointer, signed ) 38.751 +end procedure 38.752 + 38.753 +procedure Int( integer eu_type, integer pointer, integer signed ) 38.754 + add_member( eu_type, read_name(), MS_INT, sizeof( C_INT ), pointer, signed ) 38.755 +end procedure 38.756 + 38.757 +procedure Long( integer eu_type, integer pointer, integer signed ) 38.758 + add_member( eu_type, read_name(), MS_LONG, sizeof( C_LONG ), pointer, signed ) 38.759 +end procedure 38.760 + 38.761 +procedure LongLong( integer eu_type, integer pointer, integer signed ) 38.762 + add_member( eu_type, read_name(), MS_LONGLONG, sizeof( C_LONGLONG ), pointer, signed ) 38.763 +end procedure 38.764 + 38.765 +procedure FloatingPoint( integer eu_type, integer fp_type, integer pointer ) 38.766 + token name_tok = read_name() 38.767 + integer size 38.768 + switch fp_type do 38.769 + case MS_FLOAT then 38.770 + size = 4 38.771 + case MS_DOUBLE then 38.772 + size = 8 38.773 + case MS_LONGDOUBLE then 38.774 + -- these get padded out in structs to a full 16 bytes 38.775 + -- the data is actually only 10 bytes in size 38.776 + size = 16 38.777 + case MS_EUDOUBLE then 38.778 + ifdef E32 then 38.779 + size = 8 38.780 + elsifdef E64 then 38.781 + -- same as long double 38.782 + size = 16 38.783 + end ifdef 38.784 + end switch 38.785 + add_member( eu_type, name_tok, fp_type, size, pointer ) 38.786 +end procedure 38.787 + 38.788 +procedure Object( integer eu_type, integer pointer, integer signed ) 38.789 + token name_tok = read_name() 38.790 + 38.791 + add_member( eu_type, name_tok, MS_OBJECT, sizeof( E_OBJECT ), pointer, signed ) 38.792 +end procedure 38.793 + 38.794 +procedure MemStruct_member( token memstruct_tok, integer pointer, integer fwd = 0 ) 38.795 + token name_tok = read_name() 38.796 + integer size = 0 38.797 + 38.798 + if fwd then 38.799 + integer ref = new_forward_reference( MS_MEMBER, memstruct_tok[T_SYM], MEMSTRUCT_DECL ) 38.800 + set_data( ref, name_tok[T_SYM] ) 38.801 + else 38.802 + size = SymTab[memstruct_tok[T_SYM]][S_MEM_SIZE] 38.803 + end if 38.804 + add_member( 0, name_tok, memstruct_tok, size, pointer ) 38.805 + 38.806 + 38.807 +end procedure 38.808 + 38.809 +export function resolve_member( sequence name, symtab_index struct_sym ) 38.810 + symtab_pointer member_sym = struct_sym 38.811 + 38.812 + while member_sym with entry do 38.813 + if equal( name, sym_name( member_sym ) ) then 38.814 + return member_sym 38.815 + end if 38.816 + entry 38.817 + member_sym = SymTab[member_sym][S_MEM_NEXT] 38.818 + end while 38.819 + return 0 38.820 +end function 38.821 + 38.822 +export function resolve_members( sequence names, symtab_index struct_sym ) 38.823 + symtab_pointer parent = struct_sym 38.824 + symtab_pointer sym 38.825 + for i = 1 to length( names ) do 38.826 + sym = resolve_member( names[i], parent ) 38.827 + if not sym then 38.828 + return 0 38.829 + end if 38.830 + parent = SymTab[sym][S_MEM_STRUCT] 38.831 + end for 38.832 + return sym 38.833 +end function 38.834 + 38.835 +function parse_symstruct( token tok ) 38.836 + 38.837 + symtab_index struct_sym = tok[T_SYM] 38.838 + integer ref = 0 38.839 + if SymTab[struct_sym][S_SCOPE] = SC_UNDEFINED then 38.840 + -- a forward reference 38.841 + ref = new_forward_reference( MEMSTRUCT, struct_sym, MEMSTRUCT_ACCESS ) 38.842 + 38.843 + elsif tok[T_ID] != MEMSTRUCT 38.844 + and tok[T_ID] != QUALIFIED_MEMSTRUCT 38.845 + and tok[T_ID] != MEMUNION 38.846 + and tok[T_ID] != QUALIFIED_MEMUNION 38.847 + and tok[T_ID] != MEMTYPE then 38.848 + -- something else 38.849 + CompileErr( EXPECTED_VALID_MEMSTRUCT ) 38.850 + end if 38.851 + 38.852 + tok = next_token() 38.853 + if tok[T_ID] = LEFT_SQUARE then 38.854 + emit_symstruct( struct_sym, ref ) 38.855 + Expr() 38.856 + tok_match( RIGHT_SQUARE ) 38.857 + emit_op( MEMSTRUCT_ARRAY ) 38.858 + tok = next_token() 38.859 + 38.860 + if tok[T_ID] != DOT then 38.861 + putback( tok ) 38.862 + return 0 38.863 + end if 38.864 + return { struct_sym, ref } 38.865 + elsif tok[T_ID] = DOT then 38.866 + return { struct_sym, ref } 38.867 + else 38.868 + putback( tok ) 38.869 + return { struct_sym, ref, 0 } 38.870 + end if 38.871 +end function 38.872 + 38.873 +procedure emit_member( integer member, integer ref, integer op, sequence names ) 38.874 + if ref then 38.875 + integer m_ref = new_forward_reference( MS_MEMBER, member, op ) 38.876 + add_data( ref, m_ref ) 38.877 + emit_opnd( -m_ref ) 38.878 + set_data( m_ref, names ) 38.879 + else 38.880 + emit_opnd( member ) 38.881 + end if 38.882 +end procedure 38.883 + 38.884 +procedure emit_symstruct( integer symstruct, integer ref ) 38.885 + if ref then 38.886 + emit_opnd( -ref ) 38.887 + else 38.888 + emit_opnd( symstruct ) 38.889 + end if 38.890 +end procedure 38.891 + 38.892 +function is_pointer( symtab_index member ) 38.893 + return SymTab[member][S_MEM_POINTER] 38.894 +end function 38.895 + 38.896 +--** 38.897 +-- Parse the dot notation of accessing a memstruct. 38.898 +export procedure MemStruct_access( symtab_index sym, integer lhs ) 38.899 + -- the sym is the pointer, and just before this, we found a DOT token 38.900 + -- First, figure out which memstruct we're using 38.901 + token tok = next_token() 38.902 + 38.903 + object sym_ref = parse_symstruct( tok ) 38.904 + if atom( sym_ref ) then 38.905 + -- simple array access, nothing more needed 38.906 + return 38.907 + end if 38.908 + symtab_index struct_sym = sym_ref[1] 38.909 + integer ref = sym_ref[2] 38.910 + 38.911 + if length( sym_ref ) = 3 then 38.912 + -- just the sym...serialize it 38.913 + if lhs then 38.914 + emit_opnd( sym ) 38.915 + emit_symstruct( struct_sym, ref ) 38.916 + emit_opnd( 0 ) -- don't deref 38.917 + return 38.918 + else 38.919 + emit_symstruct( struct_sym, ref ) 38.920 + emit_op( MEMSTRUCT_READ ) 38.921 + end if 38.922 + return 38.923 + end if 38.924 + 38.925 + sequence names = {} 38.926 + 38.927 + No_new_entry = 1 38.928 + integer members = 0 38.929 + symtab_pointer member = 0 38.930 + integer has_dot = 1 38.931 + while 1 with entry do 38.932 + integer tid = tok[T_ID] 38.933 + switch tid do 38.934 + case VARIABLE, FUNC, PROC, TYPE, NAMESPACE then 38.935 + 38.936 + if not has_dot then 38.937 + peek_member( members, member, ref, lhs, names ) 38.938 + putback( tok ) 38.939 + exit 38.940 + end if 38.941 + 38.942 + -- make it look like the IGNORED token 38.943 + tok= { IGNORED, SymTab[tok[T_SYM]][S_NAME] } 38.944 + fallthru 38.945 + 38.946 + case IGNORED then 38.947 + if not has_dot then 38.948 + peek_member( members, member, ref, lhs, names ) 38.949 + if tid != IGNORED then 38.950 + putback( tok ) 38.951 + else 38.952 + No_new_entry = 0 38.953 + putback( keyfind( tok[T_SYM], -1 ) ) 38.954 + end if 38.955 + exit 38.956 + end if 38.957 + 38.958 + -- just look at it within this memstruct's context... 38.959 + names = append( names, tok[T_SYM] ) 38.960 + if ref then 38.961 + -- we don't know the memstruct yet! 38.962 + member = NewBasicEntry( tok[T_SYM], 0, SC_MEMSTRUCT, MS_MEMBER, 0, 0, 00 ) 38.963 + SymTab[member] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[member] ) ) 38.964 + emit_member( member, ref, MEMSTRUCT_ACCESS, names ) 38.965 + else 38.966 + if member then 38.967 + -- going into an embedded / linked struct or union 38.968 + struct_sym = SymTab[member][S_MEM_STRUCT] 38.969 + end if 38.970 + if SymTab[struct_sym][S_TOKEN] = MEMTYPE then 38.971 + -- use whatever it really is 38.972 + struct_sym = SymTab[struct_sym][S_MEM_PARENT] 38.973 + end if 38.974 + member = resolve_member( tok[T_SYM], struct_sym ) 38.975 + if not member then 38.976 + 38.977 + CompileErr( NOT_A_MEMBER, { tok[T_SYM], sym_name( struct_sym ) } ) 38.978 + end if 38.979 + emit_opnd( member ) 38.980 + end if 38.981 + 38.982 + members += 1 38.983 + has_dot = 0 38.984 + 38.985 + case MULTIPLY then 38.986 + -- ptr.struct.ptr_to_something.* fetch the value pointed to 38.987 + if not ref then 38.988 + -- make sure it's actually a pointer... 38.989 + if not SymTab[member][S_MEM_POINTER] then 38.990 + CompileErr( DEREFERENCING_NONPOINTER ) 38.991 + end if 38.992 + end if 38.993 + peek_member( members, member, ref, lhs, names, /* op */ , 1 ) 38.994 + exit 38.995 + 38.996 + case DOT then 38.997 + -- another layer... 38.998 + if not member then 38.999 + CompileErr( 68, {"a member name", LexName( tid )} ) 38.1000 + end if 38.1001 + has_dot = 1 38.1002 + 38.1003 + case LEFT_SQUARE then 38.1004 + -- array... 38.1005 + if has_dot then 38.1006 + -- can't do this... 38.1007 + end if 38.1008 + Expr() 38.1009 + tok_match( RIGHT_SQUARE ) 38.1010 + 38.1011 + tok = next_token() 38.1012 + putback( tok ) 38.1013 + if tok[T_ID] != DOT then 38.1014 + if lhs then 38.1015 + peek_member( members, member, ref, lhs, names, ARRAY_ACCESS ) 38.1016 + else 38.1017 + emit_op( PEEK_ARRAY ) 38.1018 + end if 38.1019 + exit 38.1020 + end if 38.1021 + 38.1022 + emit_op( MEMSTRUCT_ARRAY ) 38.1023 + 38.1024 + case else 38.1025 + peek_member( members, member, ref, lhs, names ) 38.1026 + putback( tok ) 38.1027 + exit 38.1028 + end switch 38.1029 + entry 38.1030 + tok = next_token() 38.1031 + end while 38.1032 + No_new_entry = 0 38.1033 +end procedure 38.1034 + 38.1035 +procedure peek_member( integer members, symtab_index member, integer ref, 38.1036 + integer lhs, sequence names, integer op = MEMSTRUCT_ACCESS, 38.1037 + integer deref_ptr = 0 38.1038 + ) 38.1039 + 38.1040 + emit_opnd( members ) 38.1041 + emit_op( op ) 38.1042 + if lhs then 38.1043 + emit_member( member, ref, op, names ) 38.1044 + emit_opnd( deref_ptr ) 38.1045 + else 38.1046 + -- geting the value...peek it 38.1047 + emit_member( member, ref, PEEK_MEMBER, names ) 38.1048 + emit_opnd( deref_ptr ) 38.1049 + emit_op( PEEK_MEMBER ) 38.1050 + end if 38.1051 +end procedure
39.1 --- a/source/msgtext.e Mon Dec 19 23:19:58 2011 -0300 39.2 +++ b/source/msgtext.e Wed Dec 21 16:45:49 2011 -0300 39.3 @@ -13,10 +13,22 @@ 39.4 include common.e 39.5 39.6 export enum 39.7 + EXPECTED_VALID_MEMSTRUCT = 358, 39.8 + FP_NOT_SIGNED, 39.9 + ONLY_DOUBLE_FP_LONG, 39.10 + ONLY_INT_LONG_LONG, 39.11 + NOT_A_MEMBER, 39.12 + NOT_A_POINTER_OR_MEMSTRUCT, 39.13 + CANNOT_ASSIGN_NONPRIMATIVE, 39.14 + EXPECTED_PRIMITIVE_MEMSTRUCT_TYPE, 39.15 + MISSING_MEMSTRUCT_MEMBER, 39.16 + DEREFERENCING_NONPOINTER, 39.17 + MISSING_CMD_PARAMETER = 353, 39.18 MSG_CC_PREFIX = 600, 39.19 NONSTANDARD_LIBRARY, 39.20 DUPLICATE_MULTI_ASSIGN, 39.21 - MISSING_CMD_PARAMETER = 353, 39.22 + TRACE_LINES_CMD, 39.23 + BAD_TRACE_LINES, 39.24 $ 39.25 39.26 -- don't change this please, but please look for -deleted- items before adding new options 39.27 @@ -377,12 +389,25 @@ 39.28 {352, "There is no watcom instalation under specified Watom Path [1]"}, 39.29 {NONSTANDARD_LIBRARY, "Use a non-standard library when building a shared object"}, 39.30 {354, "External debugger"}, 39.31 + 39.32 {355, "Use the -mno-cygwin flag with MinGW"}, 39.33 {356, "Specify the target architecture (X86, X86_64, ARM)"}, 39.34 {357, "Unknown architecture: [1]. Supported architectures are: [2]"}, 39.35 + {EXPECTED_VALID_MEMSTRUCT, "Expected to see a valid memory structure type" }, 39.36 + {FP_NOT_SIGNED, "Floating point data cannot have signed or unsigned modifiers"}, 39.37 + {ONLY_DOUBLE_FP_LONG, "Only 'double' floating point type can have the 'long' modifier"}, 39.38 + {ONLY_INT_LONG_LONG, "Only 'int' or 'long' integers can have the 'long' modifier"}, 39.39 + {NOT_A_MEMBER, "[1] is not a member of memstruct or memunion [2]"}, 39.40 + {NOT_A_POINTER_OR_MEMSTRUCT, "Member is not a pointer or an embedded memstruct"}, 39.41 + {CANNOT_ASSIGN_NONPRIMATIVE, "Cannot assign to a non-primitive, non-pointer memstruct" }, 39.42 + {EXPECTED_PRIMITIVE_MEMSTRUCT_TYPE, "Expected to see a valid primitive memory structure type" }, 39.43 { MSG_CC_PREFIX, "Prefix for compiler and related binaries"}, 39.44 {DUPLICATE_MULTI_ASSIGN, "duplicate variables in left hand side of multiple assignment"}, 39.45 {MISSING_CMD_PARAMETER, "Command line argument [1] requires a parameter"}, 39.46 + {MISSING_MEMSTRUCT_MEMBER, "Expected a valid memstruct and member expression"}, 39.47 + {DEREFERENCING_NONPOINTER, "Cannot dereference a non-pointer memstruct member"}, 39.48 + {TRACE_LINES_CMD, "Specify the number of lines to use in ctrace.out"}, 39.49 + {BAD_TRACE_LINES, "the -trace-lines option requires a valid number\n"}, 39.50 $ 39.51 } 39.52
40.1 --- a/source/opnames.e Mon Dec 19 23:19:58 2011 -0300 40.2 +++ b/source/opnames.e Wed Dec 21 16:45:49 2011 -0300 40.3 @@ -227,5 +227,19 @@ 40.4 "PEEK_POINTER", 40.5 "SIZEOF", 40.6 "STARTLINE_BREAK", 40.7 + "MEMSTRUCT_ACCESS", 40.8 + "MEMSTRUCT_ARRAY", 40.9 + "PEEK_MEMBER", 40.10 + "MEMSTRUCT_READ", 40.11 + "MEMSTRUCT_ASSIGN", 40.12 + "MEMSTRUCT_PLUS", 40.13 + "MEMSTRUCT_MINUS", 40.14 + "MEMSTRUCT_MULTIPLY", 40.15 + "MEMSTRUCT_DIVIDE", 40.16 + "MEM_TYPE_CHECK", 40.17 + "ADDRESSOF", 40.18 + "OFFSETOF", 40.19 + "PEEK_ARRAY", 40.20 + "ARRAY_ACCESS", 40.21 $ 40.22 }
41.1 --- a/source/opnames.h Mon Dec 19 23:19:58 2011 -0300 41.2 +++ b/source/opnames.h Wed Dec 21 16:45:49 2011 -0300 41.3 @@ -217,5 +217,20 @@ 41.4 "PEEK8U", 41.5 "POKE_POINTER", 41.6 "PEEK_POINTER", 41.7 - "SIZEOF" 41.8 + "SIZEOF", 41.9 + "STARTLINE_BREAK", 41.10 + "MEMSTRUCT_ACCESS", 41.11 + "MEMSTRUCT_ARRAY", 41.12 + "PEEK_MEMBER", 41.13 + "MEMSTRUCT_READ", 41.14 + "MEMSTRUCT_ASSIGN", 41.15 + "MEMSTRUCT_PLUS", 41.16 + "MEMSTRUCT_MINUS", 41.17 + "MEMSTRUCT_MULTIPLY", 41.18 + "MEMSTRUCT_DIVIDE", 41.19 + "MEM_TYPE_CHECK", 41.20 + "ADDRESSOF", 41.21 + "OFFSETOF", 41.22 + "PEEK_ARRAY, 41.23 + "ARRAY_ACCESS" 41.24 };
42.1 --- a/source/parser.e Mon Dec 19 23:19:58 2011 -0300 42.2 +++ b/source/parser.e Wed Dec 21 16:45:49 2011 -0300 42.3 @@ -31,12 +31,15 @@ 42.4 include block.e 42.5 include keylist.e 42.6 include coverage.e 42.7 +include memstruct.e 42.8 include msgtext.e 42.9 42.10 constant UNDEFINED = -999 42.11 constant DEFAULT_SAMPLE_SIZE = 25000 -- for time profile 42.12 constant ASSIGN_OPS = {EQUALS, PLUS_EQUALS, MINUS_EQUALS, MULTIPLY_EQUALS, 42.13 DIVIDE_EQUALS, CONCAT_EQUALS} 42.14 +constant MEMSTRUCT_ASSIGN_OPS = {MEMSTRUCT_ASSIGN, MEMSTRUCT_PLUS, MEMSTRUCT_MINUS, MEMSTRUCT_MULTIPLY, 42.15 + MEMSTRUCT_DIVIDE, 0} 42.16 constant SCOPE_TYPES = {SC_LOCAL, SC_GLOBAL, SC_PUBLIC, SC_EXPORT, SC_UNDEFINED} 42.17 42.18 --***************** 42.19 @@ -271,9 +274,8 @@ 42.20 set_qualified_fwd( SymTab[sym][S_FILE_NO] ) 42.21 end if 42.22 ref = new_forward_reference( GLOBAL_INIT_CHECK, tok[T_SYM], GLOBAL_INIT_CHECK ) 42.23 - 42.24 emit_op( GLOBAL_INIT_CHECK ) 42.25 - emit_addr( sym ) 42.26 + emit_addr( 0 ) 42.27 end if 42.28 end procedure 42.29 42.30 @@ -322,7 +324,6 @@ 42.31 elsif ref and sym > 0 and sym_mode( sym ) = M_CONSTANT and equal( NOVALUE, sym_obj( sym ) ) then 42.32 emit_op( GLOBAL_INIT_CHECK ) 42.33 emit_addr(sym) 42.34 - 42.35 end if 42.36 -- else .. ignore loop vars, constants 42.37 end procedure 42.38 @@ -471,7 +472,7 @@ 42.39 exit_list = exit_list [1..exit_top] 42.40 end procedure 42.41 42.42 -procedure putback(token t) 42.43 +export procedure putback(token t) 42.44 -- push a scanner token back onto the input stream 42.45 backed_up_tok = append(backed_up_tok, t) 42.46 42.47 @@ -648,7 +649,7 @@ 42.48 return t 42.49 end function 42.50 42.51 -function next_token() 42.52 +export function next_token() 42.53 -- read next scanner token 42.54 token t 42.55 sequence s 42.56 @@ -728,7 +729,7 @@ 42.57 return n 42.58 end function 42.59 42.60 -procedure tok_match(integer tok, integer prevtok = 0) 42.61 +export procedure tok_match(integer tok, integer prevtok = 0) 42.62 -- match token or else syntax error 42.63 token t 42.64 sequence expected, actual, prevname 42.65 @@ -1053,7 +1054,6 @@ 42.66 end switch 42.67 end while 42.68 42.69 - integer fc_pc = length( Code ) + 1 42.70 emit_opnd( args ) 42.71 42.72 op_info1 = proc 42.73 @@ -1173,7 +1173,26 @@ 42.74 if id = FUNC or id = TYPE then 42.75 -- to warn if not in include tree 42.76 UndefinedVar( tok[T_SYM] ) 42.77 + 42.78 + switch SymTab[tok[T_SYM]][S_OPCODE] do 42.79 + case SIZEOF then 42.80 + if parse_sizeof() then 42.81 + -- special parsing for multi-part memstruct types 42.82 + tok_match( RIGHT_ROUND ) 42.83 + scope = SymTab[tok[T_SYM]][S_SCOPE] 42.84 + opcode = SymTab[tok[T_SYM]][S_OPCODE] 42.85 + goto "args_parsed" 42.86 + else 42.87 + goto "after left round" 42.88 + end if 42.89 + case OFFSETOF then 42.90 + parse_memstruct_func( SymTab[tok[T_SYM]][S_OPCODE] ) 42.91 + scope = SymTab[tok[T_SYM]][S_SCOPE] 42.92 + opcode = SymTab[tok[T_SYM]][S_OPCODE] 42.93 + goto "args_parsed" 42.94 + end switch 42.95 end if 42.96 + 42.97 42.98 e = SymTab[tok[T_SYM]][S_EFFECT] 42.99 if e then 42.100 @@ -1192,6 +1211,8 @@ 42.101 end if 42.102 end if 42.103 tok_match(LEFT_ROUND) 42.104 + 42.105 + label "after left round" 42.106 scope = SymTab[tok[T_SYM]][S_SCOPE] 42.107 opcode = SymTab[tok[T_SYM]][S_OPCODE] 42.108 if equal(SymTab[tok[T_SYM]][S_NAME],"object") and scope = SC_PREDEF then 42.109 @@ -1202,6 +1223,7 @@ 42.110 ParseArgs(tok[T_SYM]) 42.111 end if 42.112 42.113 + label "args_parsed" 42.114 if scope = SC_PREDEF then 42.115 emit_op(opcode) 42.116 else 42.117 @@ -1214,6 +1236,7 @@ 42.118 end if 42.119 end if 42.120 end if 42.121 + 42.122 end procedure 42.123 42.124 procedure Factor() 42.125 @@ -1230,7 +1253,40 @@ 42.126 tok = read_recorded_token(tok[T_SYM]) 42.127 id = tok[T_ID] 42.128 end if 42.129 + 42.130 switch id label "factor" do 42.131 + case MEMTYPE then 42.132 + -- use its alias 42.133 + sym = tok[T_SYM] 42.134 + id = SymTab[sym][S_MEM_TYPE] 42.135 + 42.136 + if not id then 42.137 + sym = SymTab[sym][S_MEM_PARENT] 42.138 + id = sym_token( sym ) 42.139 + tok[T_SYM] = sym 42.140 + tok[T_ID] = id 42.141 + end if 42.142 + 42.143 + fallthru 42.144 + case MEMSTRUCT, QUALIFIED_MEMSTRUCT, MEMUNION, QUALIFIED_MEMUNION then 42.145 + -- probably needs error checking or something to make sure 42.146 + -- the struct makes sense 42.147 + 42.148 + token look_ahead = next_token() 42.149 + putback( look_ahead ) 42.150 + if look_ahead[T_ID] = DOT then 42.151 + -- a "naked" memstruct access...offsetof() uses this 42.152 + putback( tok ) 42.153 + 42.154 + -- Need this extra push, used by MEMSTRUCT_ACCESS / PEEK_MEMBER 42.155 + -- which OFFSETOF will eat. Otherwise, we corrupt the stack. 42.156 + Push( tok[T_SYM] ) 42.157 + MemStruct_access( tok[T_SYM], FALSE ) 42.158 + else 42.159 + 42.160 + emit_opnd( tok[T_SYM] ) 42.161 + end if 42.162 + 42.163 case VARIABLE, QUALIFIED_VARIABLE then 42.164 sym = tok[T_SYM] 42.165 if sym < 0 or SymTab[sym][S_SCOPE] = SC_UNDEFINED then 42.166 @@ -1256,35 +1312,42 @@ 42.167 42.168 short_circuit -= 1 42.169 tok = next_token() 42.170 - current_sequence = append(current_sequence, sym) 42.171 - while tok[T_ID] = LEFT_SQUARE do 42.172 - subs_depth += 1 42.173 - if lhs_subs_level >= 0 then 42.174 - lhs_subs_level += 1 42.175 - end if 42.176 - save_factors = factors 42.177 - save_lhs_subs_level = lhs_subs_level 42.178 - call_proc(forward_expr, {}) 42.179 - tok = next_token() 42.180 - if tok[T_ID] = SLICE then 42.181 + 42.182 + 42.183 + if tok[T_ID] = DOT then 42.184 + MemStruct_access( sym, FALSE ) 42.185 + else 42.186 + current_sequence = append(current_sequence, sym) 42.187 + while tok[T_ID] = LEFT_SQUARE do 42.188 + subs_depth += 1 42.189 + if lhs_subs_level >= 0 then 42.190 + lhs_subs_level += 1 42.191 + end if 42.192 + save_factors = factors 42.193 + save_lhs_subs_level = lhs_subs_level 42.194 call_proc(forward_expr, {}) 42.195 - emit_op(RHS_SLICE) 42.196 - tok_match(RIGHT_SQUARE) 42.197 tok = next_token() 42.198 - exit 42.199 - else 42.200 - putback(tok) 42.201 - tok_match(RIGHT_SQUARE) 42.202 - subs_depth -= 1 42.203 - current_sequence = head( current_sequence, length( current_sequence ) - 1 ) 42.204 - emit_op(RHS_SUBS) -- current_sequence will be updated 42.205 - end if 42.206 - factors = save_factors 42.207 - lhs_subs_level = save_lhs_subs_level 42.208 - tok = next_token() 42.209 - end while 42.210 - current_sequence = head( current_sequence, length( current_sequence ) - 1 ) 42.211 - putback(tok) 42.212 + if tok[T_ID] = SLICE then 42.213 + call_proc(forward_expr, {}) 42.214 + emit_op(RHS_SLICE) 42.215 + tok_match(RIGHT_SQUARE) 42.216 + tok = next_token() 42.217 + exit 42.218 + else 42.219 + putback(tok) 42.220 + tok_match(RIGHT_SQUARE) 42.221 + subs_depth -= 1 42.222 + current_sequence = head( current_sequence, length( current_sequence ) - 1 ) 42.223 + emit_op(RHS_SUBS) -- current_sequence will be updated 42.224 + end if 42.225 + factors = save_factors 42.226 + lhs_subs_level = save_lhs_subs_level 42.227 + tok = next_token() 42.228 + end while 42.229 + current_sequence = head( current_sequence, length( current_sequence ) - 1 ) 42.230 + putback(tok) 42.231 + end if 42.232 + 42.233 short_circuit += 1 42.234 42.235 case DOLLAR then 42.236 @@ -1416,7 +1479,7 @@ 42.237 constant boolOps = {OR, AND, XOR} 42.238 export sequence ExprLine 42.239 export integer expr_bp 42.240 -procedure Expr() 42.241 +export procedure Expr() 42.242 -- Parse a general expression 42.243 -- Use either short circuit or full evaluation. 42.244 token tok 42.245 @@ -1480,6 +1543,59 @@ 42.246 42.247 forward_expr = routine_id("Expr") 42.248 42.249 +procedure emit_mem_type_check( symtab_index var, symtab_index type_sym, symtab_index member_sym, symtab_index pointer, integer op ) 42.250 + if op != MEMSTRUCT_ASSIGN then 42.251 + -- We have to read the value first via PEEK_MEMBER 42.252 + emit_opnd( pointer ) 42.253 + emit_opnd( member_sym ) 42.254 + emit_op( PEEK_MEMBER ) 42.255 + else 42.256 + emit_opnd( var ) 42.257 + end if 42.258 + 42.259 + if type_sym > 0 then 42.260 + op_info1 = type_sym 42.261 + emit_or_inline() 42.262 + else 42.263 + -- we haven't resolved the type yet! 42.264 + integer val_sym = Pop() 42.265 + integer ref = new_forward_reference( MEM_TYPE_CHECK, type_sym, TYPE_CHECK_FORWARD ) 42.266 + Code &= { TYPE_CHECK_FORWARD, val_sym, OpTypeCheck } 42.267 + end if 42.268 + 42.269 + emit_opnd( member_sym ) 42.270 + emit_op(MEM_TYPE_CHECK) 42.271 +end procedure 42.272 + 42.273 +procedure MemTypeCheck( symtab_index var, symtab_index member_sym, symtab_index pointer, integer op ) 42.274 + if member_sym < 0 then 42.275 + -- TODO: need to handle fwd refs here 42.276 + return 42.277 + end if 42.278 + if length( SymTab[member_sym] ) != SIZEOF_MEMSTRUCT_ENTRY then 42.279 + InternalErr( sprintf("Error on typechecking %s", { sym_name( member_sym ) }) ) 42.280 + end if 42.281 + integer type_sym = SymTab[member_sym][S_MEM_TYPE] 42.282 + if 0 = type_sym then 42.283 + -- no type for this member 42.284 + return 42.285 + end if 42.286 + 42.287 + if TRANSLATE then 42.288 + if OpTypeCheck then 42.289 + if SymTab[type_sym][S_EFFECT] then 42.290 + -- only call those with side effects 42.291 + emit_mem_type_check( var, type_sym, member_sym, pointer, op ) 42.292 + end if 42.293 + end if 42.294 + else 42.295 + if OpTypeCheck then 42.296 + emit_mem_type_check( var, type_sym, member_sym, pointer, op ) 42.297 + end if 42.298 + end if 42.299 + 42.300 +end procedure 42.301 + 42.302 procedure TypeCheck(symtab_index var) 42.303 -- emit code to type-check a var (after it has been assigned-to) 42.304 integer which_type 42.305 @@ -1574,6 +1690,35 @@ 42.306 end if 42.307 end procedure 42.308 42.309 +function check_assign_op( token left_var ) 42.310 + token tok = next_token() 42.311 + integer assign_op = tok[T_ID] 42.312 + 42.313 + if not find(assign_op, ASSIGN_OPS) then 42.314 + sequence lname = sym_name( left_var[T_SYM] ) 42.315 + if assign_op = DOT then 42.316 + -- memstruct 42.317 + MemStruct_access( left_var[T_SYM], TRUE ) 42.318 + assign_op = check_assign_op( left_var ) 42.319 + integer ox = find( assign_op, ASSIGN_OPS ) 42.320 + assign_op = 0 42.321 + if ox then 42.322 + assign_op = MEMSTRUCT_ASSIGN_OPS[ox] 42.323 + end if 42.324 + if not assign_op then 42.325 + CompileErr(76, {lname}) 42.326 + end if 42.327 + return assign_op 42.328 + 42.329 + elsif assign_op = COLON then 42.330 + CompileErr(133, {lname}) 42.331 + else 42.332 + CompileErr(76, {lname}) 42.333 + end if 42.334 + end if 42.335 + return assign_op 42.336 +end function 42.337 + 42.338 procedure Assignment(token left_var) 42.339 -- parse an assignment statement 42.340 token tok 42.341 @@ -1651,32 +1796,36 @@ 42.342 end while 42.343 42.344 lhs_ptr = FALSE 42.345 - 42.346 - assign_op = tok[T_ID] 42.347 - if not find(assign_op, ASSIGN_OPS) then 42.348 - sequence lname = SymTab[left_var[T_SYM]][S_NAME] 42.349 - if assign_op = COLON then 42.350 - CompileErr(133, {lname}) 42.351 - else 42.352 - CompileErr(76, {lname}) 42.353 - end if 42.354 - end if 42.355 - 42.356 - if subs = 0 then 42.357 + 42.358 + putback( tok ) 42.359 + assign_op = check_assign_op( left_var ) 42.360 + 42.361 + if subs = 0 label "subs_if" then 42.362 -- not subscripted 42.363 integer temp_len = length(Code) 42.364 - if assign_op = EQUALS then 42.365 - Expr() -- RHS expression 42.366 - InitCheck(left_sym, FALSE) 42.367 - else 42.368 - InitCheck(left_sym, TRUE) 42.369 - if left_sym > 0 then 42.370 - SymTab[left_sym][S_USAGE] = or_bits(SymTab[left_sym][S_USAGE], U_READ) 42.371 - end if 42.372 - emit_opnd(left_sym) 42.373 - Expr() -- RHS expression 42.374 - emit_assign_op(assign_op) 42.375 - end if 42.376 + switch assign_op do 42.377 + case EQUALS then 42.378 + Expr() -- RHS expression 42.379 + InitCheck(left_sym, FALSE) 42.380 + 42.381 + case MEMSTRUCT_ASSIGN, MEMSTRUCT_PLUS, MEMSTRUCT_MINUS, 42.382 + MEMSTRUCT_MULTIPLY, MEMSTRUCT_DIVIDE then 42.383 + 42.384 + Expr() 42.385 + integer top = length( Code ) 42.386 + emit_op( assign_op ) 42.387 + MemTypeCheck( Code[$], Code[$-2], Code[top], assign_op ) 42.388 + break "subs_if" 42.389 + case else 42.390 + InitCheck(left_sym, TRUE) 42.391 + if left_sym > 0 then 42.392 + SymTab[left_sym][S_USAGE] = or_bits(SymTab[left_sym][S_USAGE], U_READ) 42.393 + end if 42.394 + emit_opnd(left_sym) 42.395 + Expr() -- RHS expression 42.396 + emit_assign_op(assign_op) 42.397 + 42.398 + end switch 42.399 emit_op(ASSIGN) 42.400 TypeCheck(left_sym) 42.401 else 42.402 @@ -4671,7 +4820,17 @@ 42.403 42.404 elsif id = PROCEDURE or id = FUNCTION or id = TYPE_DECL then 42.405 SubProg(id, scope, deprecated) 42.406 + 42.407 + 42.408 + elsif id = MEMSTRUCT_DECL then 42.409 + MemStruct_declaration( scope ) 42.410 42.411 + elsif id = MEMUNION_DECL then 42.412 + MemUnion_declaration( scope ) 42.413 + 42.414 + elsif id = MEMTYPE then 42.415 + MemType( scope ) 42.416 + 42.417 elsif (scope = SC_PUBLIC) and id = INCLUDE then 42.418 IncludeScan( 1 ) 42.419 PushGoto() 42.420 @@ -4857,8 +5016,18 @@ 42.421 StartSourceLine( TRUE ) 42.422 Multi_assign() 42.423 42.424 + 42.425 + elsif id = MEMSTRUCT_DECL then 42.426 + MemStruct_declaration( SC_LOCAL ) 42.427 + 42.428 + elsif id = MEMUNION_DECL then 42.429 + MemUnion_declaration( SC_LOCAL ) 42.430 + 42.431 elsif id = ILLEGAL_CHAR then 42.432 CompileErr(102) 42.433 + 42.434 + elsif id = MEMTYPE then 42.435 + MemType( SC_LOCAL ) 42.436 42.437 else 42.438 if nested then
43.1 --- a/source/redef.h Mon Dec 19 23:19:58 2011 -0300 43.2 +++ b/source/redef.h Wed Dec 21 16:45:49 2011 -0300 43.3 @@ -209,4 +209,18 @@ 43.4 #define L_POKE_POINTER POKE_POINTER 43.5 #define L_PEEK_POINTER PEEK_POINTER 43.6 #define L_SIZEOF SIZEOF 43.7 -#define L_STARTLINE_BREAK STARTLINE_BREAK 43.8 +#define L_STARTLINE_BREAK STARTLINE_BREAK 43.9 +#define L_MEMSTRUCT_ACCESS MEMSTRUCT_ACCESS 43.10 +#define L_MEMSTRUCT_ARRAY MEMSTRUCT_ARRAY 43.11 +#define L_PEEK_MEMBER PEEK_MEMBER 43.12 +#define L_MEMSTRUCT_READ MEMSTRUCT_SERIALIZE 43.13 +#define L_MEMSTRUCT_ASSIGN MEMSTRUCT_ASSIGN 43.14 +#define L_MEMSTRUCT_PLUS MEMSTRUCT_PLUS 43.15 +#define L_MEMSTRUCT_MINUS MEMSTRUCT_MINUS 43.16 +#define L_MEMSTRUCT_MULTIPLY MEMSTRUCT_MULTIPLY 43.17 +#define L_MEMSTRUCT_DIVIDE MEMSTRUCT_DIVIDE 43.18 +#define L_MEM_TYPE_CHECK MEM_TYPE_CHECK 43.19 +#define L_ADDRESSOF ADDRESSOF 43.20 +#define L_OFFSETOF OFFSETOF 43.21 +#define L_PEEK_ARRAY PEEK_ARRAY 43.22 +#define L_ARRAY_ACCESS ARRAY_ACCESS
44.1 --- a/source/reswords.e Mon Dec 19 23:19:58 2011 -0300 44.2 +++ b/source/reswords.e Wed Dec 21 16:45:49 2011 -0300 44.3 @@ -227,7 +227,21 @@ 44.4 PEEK_POINTER = 216, 44.5 SIZEOF = 217, 44.6 STARTLINE_BREAK = 218, 44.7 - MAX_OPCODE = 218 44.8 + MEMSTRUCT_ACCESS = 219, 44.9 + MEMSTRUCT_ARRAY = 220, 44.10 + PEEK_MEMBER = 221, 44.11 + MEMSTRUCT_READ = 222, 44.12 + MEMSTRUCT_ASSIGN = 223, 44.13 + MEMSTRUCT_PLUS = 224, 44.14 + MEMSTRUCT_MINUS = 225, 44.15 + MEMSTRUCT_MULTIPLY = 226, 44.16 + MEMSTRUCT_DIVIDE = 227, 44.17 + MEM_TYPE_CHECK = 228, 44.18 + ADDRESSOF = 229, 44.19 + OFFSETOF = 230, 44.20 + PEEK_ARRAY = 231, 44.21 + ARRAY_ACCESS = 232, 44.22 + MAX_OPCODE = 232 44.23 44.24 44.25 -- adding new opcodes possibly affects reswords.h (C-coded backend), 44.26 @@ -308,7 +322,11 @@ 44.27 PUBLIC, 44.28 FALLTHRU, 44.29 ROUTINE, 44.30 - DEPRECATE 44.31 + MEMSTRUCT_DECL, 44.32 + MEMUNION_DECL, 44.33 + DEPRECATE, 44.34 + MEMTYPE, 44.35 + $ 44.36 44.37 export enum 44.38 FUNC = 501, 44.39 @@ -333,7 +351,29 @@ 44.40 QUALIFIED_FUNC, 44.41 QUALIFIED_PROC, 44.42 QUALIFIED_TYPE, 44.43 - NAMESPACE 44.44 + NAMESPACE, 44.45 + MEMSTRUCT, 44.46 + QUALIFIED_MEMSTRUCT, 44.47 + MEMUNION, 44.48 + QUALIFIED_MEMUNION, 44.49 + MS_SIGNED, 44.50 + MS_UNSIGNED, 44.51 + MS_POINTER, 44.52 + MS_CHAR, 44.53 + MS_SHORT, 44.54 + MS_INT, 44.55 + MS_LONG, 44.56 + MS_LONGLONG, 44.57 + MS_FLOAT, 44.58 + MS_DOUBLE, 44.59 + MS_LONGDOUBLE, 44.60 + MS_EUDOUBLE, 44.61 + MS_OBJECT, 44.62 + MS_MEMBER, 44.63 + MS_AS, 44.64 + 44.65 + LAST_TOKEN, 44.66 + $ 44.67 44.68 enum -- token category name id 44.69 TC_ILLCHAR,
45.1 --- a/source/reswords.h Mon Dec 19 23:19:58 2011 -0300 45.2 +++ b/source/reswords.h Wed Dec 21 16:45:49 2011 -0300 45.3 @@ -229,7 +229,21 @@ 45.4 #define PEEK_POINTER 216 45.5 #define SIZEOF 217 45.6 #define STARTLINE_BREAK 218 45.7 -#define MAX_OPCODE 218 45.8 +#define MEMSTRUCT_ACCESS 219 45.9 +#define MEMSTRUCT_ARRAY 220 45.10 +#define PEEK_MEMBER 221 45.11 +#define MEMSTRUCT_READ 222 45.12 +#define MEMSTRUCT_ASSIGN 223 45.13 +#define MEMSTRUCT_PLUS 224 45.14 +#define MEMSTRUCT_MINUS 225 45.15 +#define MEMSTRUCT_MULTIPLY 226 45.16 +#define MEMSTRUCT_DIVIDE 227 45.17 +#define MEM_TYPE_CHECK 228 45.18 +#define ADDRESSOF 229 45.19 +#define OFFSETOF 230 45.20 +#define PEEK_ARRAY 231 45.21 +#define ARRAY_ACCESS 232 45.22 +#define MAX_OPCODE 232 45.23 45.24 /* remember to update reswords.e, opnames.e, 45.25 opnames.h, optable[], localjumptab[] 45.26 @@ -243,6 +257,29 @@ 45.27 #define FUNC 501 45.28 #define TYPE 504 45.29 45.30 + 45.31 +#define MEMTYPE 436 45.32 + 45.33 +#define MEMSTRUCT 524 45.34 +#define QUALIFIED_MEMSTRUCT 523 45.35 +#define MEMUNION 526 45.36 +#define QUALIFIED_MEMUNION 527 45.37 +#define MS_SIGNED 528 45.38 +#define MS_UNSIGNED 528 45.39 +#define MS_POINTER 530 45.40 +#define MS_CHAR 531 45.41 +#define MS_SHORT 532 45.42 +#define MS_INT 533 45.43 +#define MS_LONG 534 45.44 +#define MS_LONGLONG 535 45.45 +#define MS_FLOAT 536 45.46 +#define MS_DOUBLE 537 45.47 +#define MS_LONGDOUBLE 538 45.48 +#define MS_EUDOUBLE 539 45.49 +#define MS_OBJECT 540 45.50 +#define MS_MEMBER 541 45.51 +#define MS_AS 542 45.52 + 45.53 //struct key { 45.54 // char *name; 45.55 // short int scope; /* keyword or predefined */
46.1 --- a/source/scanner.e Mon Dec 19 23:19:58 2011 -0300 46.2 +++ b/source/scanner.e Wed Dec 21 16:45:49 2011 -0300 46.3 @@ -1739,7 +1739,9 @@ 46.4 ch = getch() 46.5 end while 46.6 elsif char_class[ch] = LETTER then 46.7 - CompileErr(127, {{ch}}) 46.8 + ungetch() 46.9 + return { DOT, 0 } 46.10 + --CompileErr(127, {{ch}}) 46.11 end if 46.12 46.13 ungetch() 46.14 @@ -1767,6 +1769,10 @@ 46.15 CompileErr(125, nbasecode[basetype]) 46.16 end if 46.17 46.18 + if equal( ".", yytext ) then 46.19 + return { DOT, 0 } 46.20 + end if 46.21 + 46.22 -- f.p. or large int 46.23 d = my_sscanf(yytext) 46.24 if sequence(d) then
47.1 --- a/source/shift.e Mon Dec 19 23:19:58 2011 -0300 47.2 +++ b/source/shift.e Wed Dec 21 16:45:49 2011 -0300 47.3 @@ -35,11 +35,13 @@ 47.4 procedure init_op_info() 47.5 op_info = repeat( 0, MAX_OPCODE ) 47.6 op_info[ABORT ] = { FIXED_SIZE, 2, {}, {}, {} } -- ary: pun 47.7 + op_info[ADDRESSOF ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.8 op_info[AND ] = { FIXED_SIZE, 4, {}, {}, {} } -- ary: bin 47.9 op_info[AND_BITS ] = { FIXED_SIZE, 4, {}, {3}, {} } -- ary: bin 47.10 op_info[APPEND ] = { FIXED_SIZE, 4, {}, {3}, {} } -- ary: bin 47.11 op_info[ARCTAN ] = { FIXED_SIZE, 3, {}, {2}, {} } -- ary: un 47.12 op_info[ASSIGN ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.13 + op_info[MEMSTRUCT_ASSIGN ] = { FIXED_SIZE, 5, {}, {}, {} } 47.14 op_info[ASSIGN_I ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.15 op_info[ASSIGN_OP_SLICE ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.16 op_info[ASSIGN_OP_SUBS ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.17 @@ -67,6 +69,7 @@ 47.18 op_info[DELETE_OBJECT ] = { FIXED_SIZE, 2, {}, {}, {} } 47.19 op_info[DIV2 ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.20 op_info[DIVIDE ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.21 + op_info[MEMSTRUCT_DIVIDE ] = { FIXED_SIZE, 5, {}, {}, {} } 47.22 op_info[ELSE ] = { FIXED_SIZE, 2, {1}, {}, {} } 47.23 op_info[EXIT ] = { FIXED_SIZE, 2, {1}, {}, {} } 47.24 op_info[EXIT_BLOCK ] = { FIXED_SIZE, 2, {}, {}, {} } 47.25 @@ -125,9 +128,13 @@ 47.26 op_info[MATCH_FROM ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.27 op_info[MEM_COPY ] = { FIXED_SIZE, 4, {}, {}, {} } 47.28 op_info[MEM_SET ] = { FIXED_SIZE, 4, {}, {}, {} } 47.29 + op_info[MEMSTRUCT_ARRAY ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.30 + op_info[MEMSTRUCT_READ ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.31 op_info[MINUS ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.32 + op_info[MEMSTRUCT_MINUS ] = { FIXED_SIZE, 5, {}, {}, {} } 47.33 op_info[MINUS_I ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.34 op_info[MULTIPLY ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.35 + op_info[MEMSTRUCT_MULTIPLY ] = { FIXED_SIZE, 5, {}, {}, {} } 47.36 op_info[NOP1 ] = { FIXED_SIZE, 1, {}, {}, {} } 47.37 op_info[NOPWHILE ] = { FIXED_SIZE, 1, {}, {}, {} } 47.38 op_info[NOP2 ] = { FIXED_SIZE, 2, {}, {}, {} } 47.39 @@ -143,6 +150,7 @@ 47.40 op_info[NOTEQ_IFW_I ] = { FIXED_SIZE, 4, {3}, {}, {} } 47.41 op_info[NOT_BITS ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.42 op_info[NOT_IFW ] = { FIXED_SIZE, 3, {2}, {}, {} } 47.43 + op_info[OFFSETOF ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.44 op_info[OPEN ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.45 op_info[OPTION_SWITCHES ] = { FIXED_SIZE, 2, {}, {1}, {} } 47.46 op_info[OR ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.47 @@ -151,6 +159,8 @@ 47.48 op_info[PASSIGN_OP_SUBS ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.49 op_info[PASSIGN_SLICE ] = { FIXED_SIZE, 5, {}, {1}, {} } 47.50 op_info[PASSIGN_SUBS ] = { FIXED_SIZE, 4, {}, {1}, {} } 47.51 + op_info[PEEK_ARRAY ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.52 + op_info[PEEK_MEMBER ] = { FIXED_SIZE, 5, {}, {4}, {} } 47.53 op_info[PEEK_STRING ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.54 op_info[PEEK8U ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.55 op_info[PEEK8S ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.56 @@ -164,6 +174,7 @@ 47.57 op_info[PEEK_POINTER ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.58 op_info[PLENGTH ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.59 op_info[PLUS ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.60 + op_info[MEMSTRUCT_PLUS ] = { FIXED_SIZE, 5, {}, {}, {} } 47.61 op_info[PLUS_I ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.62 op_info[PLUS1 ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.63 op_info[PLUS1_I ] = { FIXED_SIZE, 4, {}, {3}, {} } 47.64 @@ -226,6 +237,7 @@ 47.65 op_info[TIME ] = { FIXED_SIZE, 2, {}, {1}, {} } 47.66 op_info[TRACE ] = { FIXED_SIZE, 2, {}, {}, {} } 47.67 op_info[TYPE_CHECK ] = { FIXED_SIZE, 1, {}, {}, {} } 47.68 + op_info[MEM_TYPE_CHECK ] = { FIXED_SIZE, 2, {}, {}, {} } 47.69 op_info[UMINUS ] = { FIXED_SIZE, 3, {}, {2}, {} } 47.70 op_info[UPDATE_GLOBALS ] = { FIXED_SIZE, 1, {}, {}, {} } 47.71 op_info[WHILE ] = { FIXED_SIZE, 3, {2}, {}, {} } 47.72 @@ -262,6 +274,9 @@ 47.73 op_info[CONCAT_N ] = { VARIABLE_SIZE, 0, {}, {}, {} } -- target: [pc+1] + 2 47.74 op_info[PROC ] = { VARIABLE_SIZE, 0, {}, {}, {} } 47.75 op_info[PROC_TAIL ] = op_info[PROC] 47.76 + 47.77 + op_info[MEMSTRUCT_ACCESS ] = { VARIABLE_SIZE, 0, {}, {}, {} } -- TARGET: [pc+1] + 2 47.78 + op_info[ARRAY_ACCESS ] = { VARIABLE_SIZE, 0, {}, {}, {} } -- TARGET: [pc+1] + 3 47.79 end procedure 47.80 47.81 init_op_info() 47.82 @@ -288,6 +303,12 @@ 47.83 case RIGHT_BRACE_N, CONCAT_N then 47.84 int = code[pc+1] 47.85 int += 3 47.86 + case MEMSTRUCT_ACCESS then 47.87 + int = code[pc+1] 47.88 + int += 4 47.89 + case ARRAY_ACCESS then 47.90 + int = code[pc+1] 47.91 + int += 5 47.92 case else 47.93 InternalErr( 269, {op} ) 47.94 end switch 47.95 @@ -506,8 +527,11 @@ 47.96 case FUNC_FORWARD then 47.97 return opseq[$] 47.98 47.99 - case RIGHT_BRACE_N, CONCAT_N then 47.100 + case RIGHT_BRACE_N, CONCAT_N, MEMSTRUCT_ACCESS then 47.101 return opseq[opseq[2]+2] 47.102 + 47.103 + case ARRAY_ACCESS then 47.104 + return opseq[opseq[2]+3] 47.105 47.106 end switch 47.107 end if
48.1 --- a/source/symtab.e Mon Dec 19 23:19:58 2011 -0300 48.2 +++ b/source/symtab.e Wed Dec 21 16:45:49 2011 -0300 48.3 @@ -1,6 +1,7 @@ 48.4 -- (c) Copyright - See License.txt 48.5 -- 48.6 -- Symbol Table Routines 48.7 +namespace symtab 48.8 48.9 ifdef ETYPE_CHECK then 48.10 with type_check 48.11 @@ -29,6 +30,19 @@ 48.12 export symtab_index sequence_type -- s.t. index of sequence type 48.13 export symtab_index integer_type -- s.t. index of integer type 48.14 48.15 +export symtab_index ms_char_sym 48.16 +export symtab_index ms_short_sym 48.17 +export symtab_index ms_int_sym 48.18 +export symtab_index ms_long_sym 48.19 +export symtab_index ms_longlong_sym 48.20 +export symtab_index ms_object_sym 48.21 +export symtab_index ms_pointer_sym 48.22 +export symtab_index ms_float_sym 48.23 +export symtab_index ms_double_sym 48.24 +export symtab_index ms_longdouble_sym 48.25 +export symtab_index ms_eudouble_sym 48.26 + 48.27 + 48.28 ifdef EUDIS then 48.29 export sequence bucket_hits = repeat( 0, NBUCKETS ) -- count how many times we look at each bucket 48.30 end ifdef 48.31 @@ -74,7 +88,6 @@ 48.32 export procedure remove_symbol( symtab_index sym ) 48.33 integer hash 48.34 integer st_ptr 48.35 - 48.36 hash = SymTab[sym][S_HASHVAL] 48.37 st_ptr = buckets[hash] 48.38 48.39 @@ -436,6 +449,29 @@ 48.40 return p 48.41 end function 48.42 48.43 +procedure set_memsize( symtab_index sym, integer kx ) 48.44 + sequence key = keylist[kx] 48.45 + if length( SymTab[sym] ) < SIZEOF_MEMSTRUCT_ENTRY then 48.46 + SymTab[sym] &= repeat( 0, SIZEOF_MEMSTRUCT_ENTRY - length( SymTab[sym] ) ) 48.47 + end if 48.48 + if length( key ) >= K_MEM_SIZE then 48.49 + SymTab[sym][S_MEM_SIZE] = key[K_MEM_SIZE] 48.50 + end if 48.51 + switch key[K_NAME] do 48.52 + case "char" then ms_char_sym = sym 48.53 + case "short" then ms_short_sym = sym 48.54 + case "int" then ms_int_sym = sym 48.55 + case "long" then ms_long_sym = sym 48.56 + case "long long" then ms_longlong_sym = sym 48.57 + case "object" then ms_object_sym = sym 48.58 + case "float" then ms_float_sym = sym 48.59 + case "double" then ms_double_sym = sym 48.60 + case "long double" then ms_longdouble_sym = sym 48.61 + case "eudouble" then ms_eudouble_sym = sym 48.62 + case "pointer" then ms_pointer_sym = sym 48.63 + end switch 48.64 +end procedure 48.65 + 48.66 export procedure InitSymTab() 48.67 -- Initialize the Symbol Table 48.68 integer hashval, len 48.69 @@ -460,6 +496,7 @@ 48.70 SymTab[st_index][S_OPCODE] = keylist[k][K_OPCODE] 48.71 SymTab[st_index][S_EFFECT] = keylist[k][K_EFFECT] 48.72 SymTab[st_index][S_REFLIST] = {} 48.73 + 48.74 if length(keylist[k]) > K_EFFECT then 48.75 SymTab[st_index][S_CODE] = keylist[k][K_CODE] 48.76 SymTab[st_index][S_DEF_ARGS] = keylist[k][K_DEF_ARGS] 48.77 @@ -480,6 +517,8 @@ 48.78 elsif equal(kname, "sequence") then 48.79 sequence_type = st_index 48.80 end if 48.81 + elsif keylist[k][K_SCOPE] = SC_MEMSTRUCT then 48.82 + set_memsize( st_index, k ) 48.83 end if 48.84 if buckets[hashval] = 0 then 48.85 buckets[hashval] = st_index 48.86 @@ -689,6 +728,16 @@ 48.87 end function 48.88 48.89 export integer No_new_entry = 0 48.90 + 48.91 +integer inside_memstruct = 0 48.92 +export procedure enter_memstruct( symtab_index mem_struct ) 48.93 + inside_memstruct = mem_struct 48.94 +end procedure 48.95 + 48.96 +export procedure leave_memstruct() 48.97 + inside_memstruct = 0 48.98 +end procedure 48.99 + 48.100 export function keyfind(sequence word, integer file_no, integer scanning_file = current_file_no, integer namespace_ok = 0, 48.101 integer hashval = hashfn( word ) ) 48.102 -- Uses hashing algorithm to try to match 'word' in the symbol 48.103 @@ -821,6 +870,13 @@ 48.104 return tok 48.105 end if 48.106 break 48.107 + 48.108 + case SC_MEMSTRUCT then 48.109 + 48.110 + if inside_memstruct then 48.111 + return tok 48.112 + end if 48.113 + break 48.114 case else 48.115 48.116 if BIND then 48.117 @@ -1034,7 +1090,6 @@ 48.118 tok = {VARIABLE, NewEntry(word, 0, defined, 48.119 VARIABLE, hashval, buckets[hashval], 0)} 48.120 buckets[hashval] = tok[T_SYM] 48.121 - 48.122 if file_no != -1 then 48.123 SymTab[tok[T_SYM]][S_FILE_NO] = file_no 48.124 end if 48.125 @@ -1046,7 +1101,6 @@ 48.126 -- remove the visibility of a symbol 48.127 -- by deleting it from its hash chain 48.128 symtab_index prev, p 48.129 - 48.130 p = buckets[SymTab[s][S_HASHVAL]] 48.131 prev = 0 48.132
49.1 --- a/source/symtab.h Mon Dec 19 23:19:58 2011 -0300 49.2 +++ b/source/symtab.h Wed Dec 21 16:45:49 2011 -0300 49.3 @@ -79,6 +79,17 @@ 49.4 unsigned int first_line; 49.5 unsigned int last_line; 49.6 } block; 49.7 + struct { 49.8 + // for memstructs / memunions only 49.9 + struct symtab_entry *next; 49.10 + struct symtab_entry *struct_type; 49.11 + struct symtab_entry *parent; 49.12 + unsigned int size; 49.13 + unsigned int offset; 49.14 + int array; 49.15 + char is_signed; 49.16 + char pointer; 49.17 + } memstruct; 49.18 49.19 } u; 49.20
50.1 --- a/source/traninit.e Mon Dec 19 23:19:58 2011 -0300 50.2 +++ b/source/traninit.e Wed Dec 21 16:45:49 2011 -0300 50.3 @@ -330,6 +330,7 @@ 50.4 c_puts("include/euphoria.h\"\n") 50.5 50.6 c_puts("#include \"main-.h\"\n\n") 50.7 + c_puts("#include \"struct.h\"\n\n") 50.8 c_h = open(output_dir & "main-.h", "w") 50.9 if c_h = -1 then 50.10 CompileErr(47)
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/tests/t_memstruct.e Wed Dec 21 16:45:49 2011 -0300 51.3 @@ -0,0 +1,301 @@ 51.4 +with trace 51.5 + 51.6 + 51.7 +include std/unittest.e 51.8 + 51.9 +include std/machine.e 51.10 + 51.11 +type token_id( object id ) 51.12 + if integer(id) then 51.13 + if id < 542 then 51.14 + if id > -101 then 51.15 + return 1 51.16 + end if 51.17 + end if 51.18 + end if 51.19 + return 0 51.20 +end type 51.21 + 51.22 +set_test_verbosity( TEST_SHOW_ALL ) 51.23 +memstruct Var 51.24 + pointer symtab_entry declared_in 51.25 +end memstruct 51.26 + 51.27 +memstruct Block 51.28 + unsigned int first_line 51.29 + unsigned int last_line 51.30 +end memstruct 51.31 + 51.32 +memstruct private_block 51.33 + int task_number 51.34 + pointer private_block next 51.35 + object block[2] 51.36 +end memstruct 51.37 + 51.38 +memstruct Subp 51.39 + pointer object code 51.40 + pointer symtab_entry temps 51.41 + pointer private_block saved_privates 51.42 + pointer object block 51.43 + pointer int linetab 51.44 + unsigned int firstline 51.45 + unsigned int num_args 51.46 + int resident_task 51.47 + unsigned int stack_space 51.48 +end memstruct 51.49 + 51.50 +memunion U 51.51 + Var var 51.52 + Subp subp 51.53 + Block block 51.54 +end memunion 51.55 + 51.56 +memstruct symtab_entry 51.57 + object obj 51.58 + pointer symtab_entry next 51.59 + pointer symtab_entry next_in_block 51.60 + char mode 51.61 + char scope 51.62 + unsigned char file_no 51.63 + unsigned char dummy 51.64 + token_id as int token 51.65 + pointer char name 51.66 + U u 51.67 +end memstruct 51.68 + 51.69 +memstruct SymbolTable 51.70 + symtab_entry entries[5] 51.71 +end memstruct 51.72 + 51.73 +memtype SymbolTable as SymTab5 51.74 + 51.75 +integer bits32 = (sizeof( pointer ) = 4) 51.76 +procedure basic() 51.77 + atom symtab = allocate( sizeof( SymTab5 ) ) 51.78 + poke( symtab, repeat( 0, 5 * sizeof( symtab_entry ) ) ) 51.79 + symtab.symtab_entry.obj = 9 51.80 + symtab.symtab_entry.obj += 5 51.81 + symtab.symtab_entry.obj -= 2 51.82 + symtab.symtab_entry.obj *= 6 51.83 + symtab.symtab_entry.obj /= 3 51.84 + 51.85 + test_equal("object read / write assignment / read", peek_pointer( symtab ), symtab.symtab_entry.obj ) 51.86 + 51.87 + test_equal("addressof 1", symtab, addressof( symtab.symtab_entry.obj ) ) 51.88 + 51.89 + test_equal("offsetof 1", 0, offsetof( symtab_entry.obj ) ) 51.90 + 51.91 + symtab.symtab_entry[1].obj = 1 51.92 + symtab.symtab_entry.next = symtab.symtab_entry[1] 51.93 + 51.94 + integer offset 51.95 + if bits32 then 51.96 + offset = 4 51.97 + else 51.98 + offset = 8 51.99 + end if 51.100 + 51.101 + test_equal("pointer read / write", peek_pointer( symtab + offset ), symtab.symtab_entry.next) 51.102 + 51.103 + symtab.symtab_entry.next.obj = -42 51.104 + if bits32 then 51.105 + test_equal( "read / write following pointer (32)", peek4s( symtab + sizeof( symtab_entry)), symtab.symtab_entry.next.obj ) 51.106 + else 51.107 + test_equal( "read / write following pointer (64)", peek8s( symtab + sizeof( symtab_entry)), symtab.symtab_entry.next.obj ) 51.108 + end if 51.109 + 51.110 + symtab.symtab_entry.u.var.declared_in = 0x01010101 51.111 + test_equal("read / write union member", 0x01010101, symtab.symtab_entry.u.var.declared_in ) 51.112 + 51.113 + object serialized = symtab.symtab_entry.u 51.114 + test_equal( "addressof vs offsetof", symtab + offsetof( symtab_entry.u ), addressof( symtab.symtab_entry.u ) ) 51.115 + test_equal("serialize union", {1,1,1,1} & repeat( 0, sizeof( U ) - 4), serialized ) 51.116 + serialized = { 51.117 + symtab.symtab_entry.obj, 51.118 + symtab.symtab_entry.next, 51.119 + symtab.symtab_entry.next_in_block, 51.120 + symtab.symtab_entry.mode, 51.121 + symtab.symtab_entry.scope, 51.122 + symtab.symtab_entry.file_no, 51.123 + symtab.symtab_entry.dummy, 51.124 + symtab.symtab_entry.token, 51.125 + symtab.symtab_entry.name, 51.126 + symtab.symtab_entry.u 51.127 + } 51.128 + test_equal("serialize struct", serialized, symtab.symtab_entry ) 51.129 + test_equal("serialize union", 51.130 + peek( { addressof( symtab.symtab_entry.u ), sizeof( U ) } ), 51.131 + symtab.symtab_entry.u ) 51.132 + 51.133 + sequence SymTab_Serialized = symtab.SymbolTable 51.134 + test_equal( "sizeof arrays of structs", sizeof( symtab_entry ) * 5, sizeof( SymbolTable ) ) 51.135 + test_equal( "serialize array length", 5, length( SymTab_Serialized[1] ) ) 51.136 +end procedure 51.137 +basic() 51.138 + 51.139 +memstruct ASSIGN 51.140 + char a 51.141 + unsigned short b 51.142 + int c 51.143 + long d 51.144 + float e 51.145 + double f 51.146 + long long g 51.147 + object h 51.148 +end memstruct 51.149 + 51.150 +memunion UNION_ASSIGN 51.151 + char a 51.152 + short b 51.153 + int c 51.154 + long d 51.155 + long long e 51.156 +end memunion 51.157 + 51.158 +procedure bulk_assign() 51.159 + atom ptr = allocate( sizeof( ASSIGN ), 1 ) 51.160 + ptr.ASSIGN = {} 51.161 + test_equal( "assign an empty sequence -> memset 0", repeat( 0, 8 ), ptr.ASSIGN ) 51.162 + 51.163 + ptr.ASSIGN = { 1, 2, 3, 4, 5, 6, 7, 8} 51.164 + test_equal( "bulk assign #1", { 1, 2, 3, 4, 5, 6, 7, 8}, ptr.ASSIGN ) 51.165 + 51.166 + ptr = allocate( sizeof( UNION_ASSIGN ), 1 ) 51.167 + ptr.UNION_ASSIGN = 0 51.168 + test_equal( "union assign atom", repeat( 0, sizeof( UNION_ASSIGN ) ), ptr.UNION_ASSIGN ) 51.169 + 51.170 + ptr.UNION_ASSIGN = {255, 255, 255, 255} 51.171 + test_equal( "union assign sequence", -1, ptr.UNION_ASSIGN.c ) 51.172 + 51.173 +end procedure 51.174 +bulk_assign() 51.175 + 51.176 +-- Make sure we correctly parse all of these multi-part primitive types: 51.177 +memtype unsigned int as uint 51.178 +export memtype signed int as sint 51.179 + 51.180 +global memtype long int as lint 51.181 +memtype signed long int as slint 51.182 +memtype unsigned long int as ulint 51.183 + 51.184 +memtype long long as llong 51.185 +memtype signed long long as sllong 51.186 +memtype unsigned long long as ullong 51.187 + 51.188 +-- list of memtypes 51.189 +public memtype 51.190 + long long int as llint, 51.191 + signed long long int as sllint, 51.192 + unsigned long long int as ullint, 51.193 + $ 51.194 + 51.195 +memtype long double as ldouble 51.196 + 51.197 +test_pass( "multi-part memtype declarations" ) 51.198 + 51.199 +test_equal("sizeof( memtype ) vs sizeof( primitive )", sizeof( uint ), sizeof( unsigned int ) ) 51.200 + 51.201 +memstruct one_pointer 51.202 + pointer int p 51.203 +end memstruct 51.204 +test_equal( "sizeof( object ) same as pointer", sizeof( object ), sizeof( one_pointer ) ) 51.205 + 51.206 +test_equal( "sizeof( float ) = 4", 4, sizeof( float ) ) 51.207 +test_equal( "sizeof( double ) = 8", 8, sizeof( double ) ) 51.208 + 51.209 +ifdef BITS32 then 51.210 + test_equal( "sizeof( eudouble ) = sizeof( double )", sizeof( double ), sizeof( eudouble ) ) 51.211 +elsedef 51.212 + test_equal( "sizeof( eudouble ) = sizeof( long double )", sizeof( long double), sizeof( eudouble ) ) 51.213 +end ifdef 51.214 + 51.215 +test_equal( "sizeof( pointer ) = sizeof( object )", sizeof( pointer ), sizeof( object ) ) 51.216 + 51.217 +test_equal( "sizeof( signed int) = sizeof( sint )", sizeof( signed int ), sizeof( sint ) ) 51.218 +test_equal( "sizeof( unsigned int) = sizeof( uint )", sizeof( unsigned int ), sizeof( uint ) ) 51.219 + 51.220 +test_equal( "sizeof( long int) = sizeof( lint )", sizeof( long int ), sizeof( lint ) ) 51.221 +test_equal( "sizeof( signed long int) = sizeof( slint )", sizeof( signed long int ), sizeof( slint ) ) 51.222 +test_equal( "sizeof( unsigned long int) = sizeof( ulint )", sizeof( unsigned long int ), sizeof( ulint ) ) 51.223 + 51.224 +test_equal( "sizeof( long long ) = sizeof( llong )", sizeof( long long ), sizeof( llong ) ) 51.225 +test_equal( "sizeof( signed long long ) = sizeof( sllong )", sizeof( signed long long ), sizeof( sllong ) ) 51.226 +test_equal( "sizeof( unsigned long long ) = sizeof( ullong )", sizeof( unsigned long long ), sizeof( ullong ) ) 51.227 + 51.228 +memstruct ARRAYS 51.229 + int five_ints[5] 51.230 + long ten_longs[10] 51.231 + float three_floats[3] 51.232 + double four_doubles[4] 51.233 +end memstruct 51.234 + 51.235 +procedure arrays() 51.236 + atom ptr = allocate( sizeof( ARRAYS ), 1 ) 51.237 + 51.238 + ptr.ARRAYS.five_ints = { 1, 2, 3, 4, 5 } 51.239 + test_equal( "array bulk assign and peek ints", {1,2,3,4,5}, ptr.ARRAYS.five_ints ) 51.240 + ptr.ARRAYS.five_ints[0] = -1 51.241 + test_equal( "array assign and peek element ints", -1, ptr.ARRAYS.five_ints[0] ) 51.242 + 51.243 + ptr.ARRAYS.ten_longs = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } 51.244 + test_equal( "array bulk assign and peek longs", { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, ptr.ARRAYS.ten_longs ) 51.245 + ptr.ARRAYS.ten_longs[9] = -1 51.246 + test_equal( "array assign and peek element longs", -1, ptr.ARRAYS.ten_longs[9] ) 51.247 + 51.248 + ptr.ARRAYS.three_floats = {1.25, 1.5, 1.375 } 51.249 + test_equal( "array bulk assign and peek floats", {1.25, 1.5, 1.375 }, ptr.ARRAYS.three_floats ) 51.250 + ptr.ARRAYS.three_floats[1] = -1 51.251 + test_equal( "array assign and peek element floats", -1, ptr.ARRAYS.three_floats[1] ) 51.252 + 51.253 + ptr.ARRAYS.four_doubles = {1.1, 1.2, 1.3, 4.1 } 51.254 + test_equal( "array bulk assign and peek doubles", {1.1, 1.2, 1.3, 4.1 }, ptr.ARRAYS.four_doubles ) 51.255 + ptr.ARRAYS.four_doubles[2] = 8.6 51.256 + test_equal( "array assign and peek element doubles", 8.6, ptr.ARRAYS.four_doubles[2] ) 51.257 + 51.258 +end procedure 51.259 +arrays() 51.260 + 51.261 +memstruct POINTERS 51.262 + pointer int a 51.263 + pointer object b 51.264 + pointer unsigned long c 51.265 + pointer float d 51.266 + pointer double dbl 51.267 +end memstruct 51.268 + 51.269 +procedure pointers() 51.270 + atom ptr = allocate( sizeof( POINTERS ), 1 ) 51.271 + atom secondary = allocate( 1024 ) 51.272 + ptr.POINTERS = repeat( secondary, 5 ) 51.273 + 51.274 + ptr.POINTERS.a.* = 1234 51.275 + test_equal( "dereferenced pointer assign / read int", 1234, ptr.POINTERS.a.* ) 51.276 + 51.277 + ptr.POINTERS.a.* += 5 51.278 + test_equal( "dereferenced pointer += int", 1239, ptr.POINTERS.a.* ) 51.279 + 51.280 + ptr.POINTERS.b.* = 123456 51.281 + test_equal( "dereferenced pointer assign / read object", 123456, ptr.POINTERS.b.* ) 51.282 + 51.283 + ptr.POINTERS.b.* -= 4 51.284 + test_equal( "dereferenced pointer -= object", 123452, ptr.POINTERS.b.* ) 51.285 + 51.286 + ptr.POINTERS.c.* = 51234 51.287 + test_equal( "dereferenced pointer assign / read unsigned long", 51234, ptr.POINTERS.c.* ) 51.288 + 51.289 + ptr.POINTERS.c.* *= 2 51.290 + test_equal( "dereferenced pointer *= unsigned long", 51234 * 2, ptr.POINTERS.c.* ) 51.291 + 51.292 + ptr.POINTERS.d.* = 3.5 51.293 + test_equal( "dereferenced pointer assign / read float", 3.5, ptr.POINTERS.d.* ) 51.294 + 51.295 + ptr.POINTERS.d.* /= 2 51.296 + test_equal( "dereferenced pointer /= float", 1.75, ptr.POINTERS.d.* ) 51.297 + 51.298 + ptr.POINTERS.dbl.* = 9.75 51.299 + test_equal( "dereferenced pointer assign / read double", 9.75, ptr.POINTERS.dbl.* ) 51.300 + 51.301 +end procedure 51.302 +pointers() 51.303 + 51.304 +test_report()
