Compare commits

...
Author SHA1 Message Date
Chris HORLER e5d6a9d81f (rework) compile fixes to be integrated by rebase 2021-08-07 10:00:54 +01:00
Chris HORLER 3e7efdc741 clean-up some compiler warnings 2021-08-07 10:00:54 +01:00
Chris HORLER 7872408f74 make Symbol name const char * 2021-08-07 10:00:54 +01:00
Chris HORLER 4fa37b0b10 fix a ref / use typo 2021-08-07 10:00:54 +01:00
Chris HORLER 301af992fe fix some type issues introduced when factoring out DICT_type 2021-08-07 10:00:54 +01:00
Chris HORLER 439ae24705 move SYMBOL_new / SYMBOL_destroy to memory.c 2021-08-07 10:00:54 +01:00
Chris HORLER 04112340a0 update libexpress tests for DICT to HASH refactoring 2021-08-07 10:00:54 +01:00
Chris HORLER c4470046b3 integrate new parser / lexer into build 2021-08-07 10:00:54 +01:00
Chris HORLER 11aa1a5f5b use sc_alloc / sc_free more widely, and change #defines so they work as function pointers - for use with Lemon / RE2C 2021-08-07 10:00:54 +01:00
Chris HORLER f84a72aa37 initial steps towards using HASH as the ubiquitous Symbol table 2021-08-07 10:00:54 +01:00
Chris HORLER 9b606a9004 Parser tests
- fix lexer scope types
- fix resolve_symbol to return T_SIMPLE_REF by default (this is what the parser expects)
2021-08-07 10:00:54 +01:00
Chris HORLER 92cb70de2b CMake changes
- simplify the Lemon and RE2C modules
2021-08-07 10:00:54 +01:00
Chris HORLER 0d63c63d4c move everything scope related from expscan.l to lexsupport.[ch] 2021-08-07 10:00:54 +01:00
Chris HORLER bb0008f941 update tests to invoke scanner_test for all *.exp 2021-08-07 10:00:54 +01:00
Chris HORLER 91046817b1 update the scanner to use Hash_Table, add first scanner test 2021-08-07 10:00:54 +01:00
Chris HORLER c15d8d7336 migrate HASH memory macro definitions to implementation file 2021-08-07 10:00:54 +01:00
Chris HORLER 9b3d014c3e refactor HASH to work directly with Symbols 2021-08-07 10:00:54 +01:00
Chris HORLER 9e261a8ffc HASHdelete tests, slight changes to HASHsearch 2021-08-07 10:00:54 +01:00
Chris HORLER 3957f970eb fix HASHdo 2021-08-07 10:00:54 +01:00
Chris HORLER 0ad0cdef14 rewrite of the hash implementation
* first test case (all ids, insert, find)
* simplified / improved implementation
* added a HASHdelete method to have a consistent API
* explained the implementation and the benefits / drawbacks
* renamed the HASHlist interface to HASHdo, and Hash_Iterator
2021-08-07 10:00:54 +01:00
Chris HORLER b1844be9cc update build system
- CMake 3.3 required
- Simplify RE2C detection and add a version check capability
- add missing build option
- make some dependencies conditional (temporary solution)
2021-08-07 10:00:54 +01:00
Chris HORLER f744ba3265 update the refactoring scope struct to reflect integration requirements 2021-08-07 10:00:54 +01:00
Chris HORLER 089762d84a add ref_typ field to struct Symbol_ in order to drive lex token types 2021-08-07 10:00:54 +01:00
Chris HORLER 317c9173ec clean up the HASHlist interface 2021-08-07 10:00:54 +01:00
Chris HORLER 0510de8634 rename DICT_define to DICTdefine_enum 2021-08-07 10:00:54 +01:00
Chris HORLER 9f29353db3 clean up the DICT interface a little bit 2021-08-07 10:00:54 +01:00
Chris HORLER 469a6e45d4 initial commit for p11 parser / lexer rewrite 2021-08-07 10:00:54 +01:00
82 changed files with 34575 additions and 10461 deletions
+1
View File
@@ -123,6 +123,7 @@ include_directories(
${SC_BINARY_DIR}/include
)
add_subdirectory(src/auxlib)
add_subdirectory(src/base)
add_subdirectory(src/express)
add_subdirectory(src/exppp)
+77 -120
View File
@@ -47,42 +47,16 @@
find_program(LEMON_EXECUTABLE lemon DOC "path to the lemon executable")
mark_as_advanced(LEMON_EXECUTABLE)
if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
# look for the template in share
if (DATA_DIR AND EXISTS "${DATA_DIR}/lemon/lempar.c")
set (LEMON_TEMPLATE "${DATA_DIR}/lemon/lempar.c")
elseif (EXISTS "share/lemon/lempar.c")
set (LEMON_TEMPLATE "share/lemon/lempar.c")
elseif (EXISTS "/usr/share/lemon/lempar.c")
set (LEMON_TEMPLATE "/usr/share/lemon/lempar.c")
endif (DATA_DIR AND EXISTS "${DATA_DIR}/lemon/lempar.c")
endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
# look for the template in bin dir
get_filename_component(lemon_path ${LEMON_EXECUTABLE} PATH)
if (lemon_path)
if (EXISTS ${lemon_path}/lempar.c)
set (LEMON_TEMPLATE "${lemon_path}/lempar.c")
endif (EXISTS ${lemon_path}/lempar.c)
if (EXISTS /usr/share/lemon/lempar.c)
set (LEMON_TEMPLATE "/usr/share/lemon/lempar.c")
endif (EXISTS /usr/share/lemon/lempar.c)
endif (lemon_path)
endif(LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
# fallback
set (LEMON_TEMPLATE "lempar.c")
if (NOT EXISTS ${LEMON_TEMPLATE})
message(WARNING "Lemon's lempar.c template file could not be found automatically, set LEMON_TEMPLATE")
endif (NOT EXISTS ${LEMON_TEMPLATE})
endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE)
mark_as_advanced(LEMON_TEMPLATE)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LEMON DEFAULT_MSG LEMON_EXECUTABLE LEMON_TEMPLATE)
if (LEMON_EXECUTABLE)
get_filename_component(lemon_dir ${LEMON_EXECUTABLE} DIRECTORY)
find_file(LEMON_TEMPLATE lempar.c
PATHS "${lemon_dir}" "/usr/share/lemon"
NO_DEFAULT_PATH)
mark_as_advanced(LEMON_TEMPLATE)
if(NOT LEMON_TEMPLATE)
message(SEND_ERROR "failed to find lemon template (lempar.c)")
endif()
# Define the macro
# LEMON_TARGET(<Name> <LemonInput> <LemonSource> <LemonHeader>
@@ -104,102 +78,85 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LEMON DEFAULT_MSG LEMON_EXECUTABLE LEMON_TEMPL
include(CMakeParseArguments)
if(NOT COMMAND LEMON_TARGET)
macro(LEMON_TARGET Name Input)
macro(LEMON_TARGET Name LemonInput LemonOutput)
set(LT_ARGS DEFINES_FILE COMPILE_FLAGS)
CMAKE_PARSE_ARGUMENTS(LEMON_TARGET_ARG "" "${LT_ARGS}" "" ${ARGN})
get_filename_component(IN_FILE_WE ${Input} NAME_WE)
set(LVAR_PREFIX ${Name}_${IN_FILE_WE})
if(${ARGC} GREATER 3)
CMAKE_PARSE_ARGUMENTS(${LVAR_PREFIX} "" "OUT_SRC_FILE;OUT_HDR_FILE;WORKING_DIR;EXTRA_ARGS" "" ${ARGN})
endif(${ARGC} GREATER 3)
# Need a working directory
if("${${LVAR_PREFIX}_WORKING_DIR}" STREQUAL "")
set(${LVAR_PREFIX}_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}/${LVAR_PREFIX}")
endif("${${LVAR_PREFIX}_WORKING_DIR}" STREQUAL "")
file(MAKE_DIRECTORY ${${LVAR_PREFIX}_WORKING_DIR})
# Output source file
if ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "")
set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c)
else ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "")
get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} PATH)
if(NOT "${specified_out_dir}" STREQUAL "")
message(FATAL_ERROR "\nFull path specified for OUT_SRC_FILE - should be filename only.\n")
endif(NOT "${specified_out_dir}" STREQUAL "")
set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${${LVAR_PREFIX}_OUT_SRC_FILE})
endif ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "")
# Output header file
if ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "")
set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h)
else ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "")
get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} PATH)
if(NOT "${specified_out_dir}" STREQUAL "")
message(FATAL_ERROR "\nFull path specified for OUT_HDR_FILE - should be filename only.\n")
endif(NOT "${specified_out_dir}" STREQUAL "")
set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${${LVAR_PREFIX}_OUT_HDR_FILE})
endif ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "")
if(NOT "${LEMON_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
set(LEMON_EXECUTABLE_opts "${LEMON_TARGET_ARG_COMPILE_FLAGS}")
separate_arguments(LEMON_EXECUTABLE_opts)
else()
set(LEMON_EXECUTABLE_opts "")
endif()
# check for LemonOutput
get_filename_component(_basename ${LemonOutput} NAME_WE)
get_filename_component(_out_src_file ${LemonOutput} NAME)
get_filename_component(_out_dir ${LemonOutput} PATH)
if(NOT "${_out_dir}" STREQUAL "")
message(WARNING "Full path specified for LemonOutput - should be filename only")
endif()
# set report file
set(_out_rpt_file "${_basename}.out")
# check for DEFINES_FILE
if ("${LEMON_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
set(_out_hdr_file "${_basename}.h")
else()
get_filename_component(_out_dir ${LEMON_TARGET_ARG_DEFINES_FILE} PATH)
get_filename_component(_out_hdr_file ${LEMON_TARGET_ARG_DEFINES_FILE} NAME)
if(NOT "${_out_dir}" STREQUAL "")
message(WARNING "Full path specified for DEFINES_FILE - should be filename only")
endif()
endif()
# input file
get_filename_component(in_full ${Input} ABSOLUTE)
if("${in_full}" STREQUAL "${Input}")
set(lemon_in_file ${Input})
else("${in_full}" STREQUAL "${Input}")
set(lemon_in_file "${CMAKE_CURRENT_SOURCE_DIR}/${Input}")
endif("${in_full}" STREQUAL "${Input}")
get_filename_component(_in_y_path ${LemonInput} ABSOLUTE)
get_filename_component(_in_y_file ${LemonInput} NAME)
# names of lemon output files will be based on the name of the input file
set(LEMON_GEN_SOURCE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c)
set(LEMON_GEN_HEADER ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h)
set(LEMON_GEN_OUT ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.out)
# copy input to bin directory and run lemon
get_filename_component(INPUT_NAME ${Input} NAME)
# TODO: is this really necessary?
add_custom_command(
OUTPUT ${LEMON_GEN_OUT} ${LEMON_GEN_SOURCE} ${LEMON_GEN_HEADER}
COMMAND ${CMAKE_COMMAND} -E copy ${lemon_in_file} ${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME}
COMMAND ${LEMON_EXECUTABLE} -T${LEMON_TEMPLATE} ${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME} ${${LVAR_PREFIX}__EXTRA_ARGS}
DEPENDS ${Input} ${LEMON_TEMPLATE} ${LEMON_EXECUTABLE_TARGET}
WORKING_DIRECTORY ${${LVAR_PREFIX}_WORKING_DIR}
COMMENT "[LEMON][${Name}] Building parser with ${LEMON_EXECUTABLE}"
)
# rename generated outputs
if(NOT "${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "${LEMON_GEN_SOURCE}")
add_custom_command(
OUTPUT ${${LVAR_PREFIX}_OUT_SRC_FILE}
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_SOURCE} ${${LVAR_PREFIX}_OUT_SRC_FILE}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE}
)
set(LEMON_${Name}_OUTPUTS ${${LVAR_PREFIX}_OUT_SRC_FILE} ${LEMON_${Name}_OUTPUTS})
endif(NOT "${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "${LEMON_GEN_SOURCE}")
if(NOT "${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "${LEMON_GEN_HEADER}")
add_custom_command(
OUTPUT ${${LVAR_PREFIX}_OUT_HDR_FILE}
COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_HEADER} ${${LVAR_PREFIX}_OUT_HDR_FILE}
DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER}
)
set(LEMON_${Name}_OUTPUTS ${${LVAR_PREFIX}_OUT_HDR_FILE} ${LEMON_${Name}_OUTPUTS})
endif(NOT "${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "${LEMON_GEN_HEADER}")
set(LEMON_${Name}_OUTPUTS ${LEMON_${Name}_OUTPUTS} ${LEMON_GEN_OUT})
OUTPUT ${_in_y_file}
COMMAND ${CMAKE_COMMAND} -E copy ${_in_y_path} ${CMAKE_CURRENT_BINARY_DIR}
)
# execute lemon
add_custom_command(
OUTPUT ${_out_src_file}
COMMAND ${LEMON_EXECUTABLE} -T${LEMON_TEMPLATE} ${LEMON_EXECUTABLE_opts} ${_in_y_file}
DEPENDS ${_in_y_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "[LEMON][${Name}] Building parser with ${LEMON_EXECUTABLE}"
)
# rename the header
add_custom_command(
OUTPUT ${_out_hdr_file}
COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_basename}.h ${_out_hdr_file}
DEPENDS ${_out_src_file}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
# set the return values
# TODO: for generated sources even headers should be target dependencies
set(LEMON_${Name}_DEFINED TRUE)
set(LEMON_${Name}_OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${_out_hdr_file}")
set(LEMON_${Name}_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
set(LEMON_${Name}_OUTPUTS "${_out_src_file}")
# make sure we clean up generated output and copied input
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}")
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME}")
# macro ran successfully
set(LEMON_${Name}_DEFINED TRUE)
set(LEMON_${Name}_SRC ${${LVAR_PREFIX}_OUT_SRC_FILE})
set(LEMON_${Name}_HDR ${${LVAR_PREFIX}_OUT_HDR_FILE})
set(LEMON_${Name}_INCLUDE_DIR ${${LVAR_PREFIX}_WORKING_DIR})
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${_in_y_file}")
endmacro(LEMON_TARGET)
endif(NOT COMMAND LEMON_TARGET)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LEMON REQUIRED_VARS LEMON_EXECUTABLE LEMON_TEMPLATE)
#============================================================
# FindLEMON.cmake ends here
+61 -32
View File
@@ -6,8 +6,20 @@
find_program(RE2C_EXECUTABLE re2c DOC "path to the re2c executable")
mark_as_advanced(RE2C_EXECUTABLE)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(RE2C DEFAULT_MSG RE2C_EXECUTABLE)
if(RE2C_EXECUTABLE)
execute_process(COMMAND ${RE2C_EXECUTABLE} -v
OUTPUT_VARIABLE RE2C_version_output
ERROR_VARIABLE RE2C_version_error
RESULT_VARIABLE RE2C_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT ${RE2C_version_result} EQUAL 0)
message(SEND_ERROR
"Command \"${RE2C_EXECUTABLE} -v\" failed with output:\n${RE2C_version_output}\n${RE2C_version_error}")
else()
string(REGEX REPLACE "^re2c ([0-9]+[^ ]*)( .*)?$" "\\1" RE2C_VERSION "${RE2C_version_output}")
endif()
# Provide a macro to generate custom build rules:
@@ -80,36 +92,47 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(RE2C DEFAULT_MSG RE2C_EXECUTABLE)
# RE2C_TARGET (public macro)
#============================================================
#
# TODO - rework this macro to make use of CMakeParseArguments, see
# http://www.cmake.org/pipermail/cmake/2012-July/051309.html
if(NOT COMMAND RE2C_TARGET)
macro(RE2C_TARGET Name Input Output)
set(RE2C_TARGET_usage "RE2C_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>]")
if(${ARGC} GREATER 3)
if(${ARGC} EQUAL 5)
if("${ARGV3}" STREQUAL "COMPILE_FLAGS")
set(RE2C_EXECUTABLE_opts "${ARGV4}")
SEPARATE_ARGUMENTS(RE2C_EXECUTABLE_opts)
else()
message(SEND_ERROR ${RE2C_TARGET_usage})
endif()
else()
message(SEND_ERROR ${RE2C_TARGET_usage})
endif()
macro(RE2C_TARGET Name RE2CInput RE2COutput)
set(_re2c_args COMPILE_FLAGS DEFINES_FILE)
cmake_parse_arguments(RE2C_TARGET_ARG "" "${_re2c_args}" "" ${ARGN})
if(NOT "${RE2C_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(SEND_ERROR "RE2C_TARGET(<Name> <RE2CInput> <RE2COutput>
[COMPILE_FLAGS <string>]
[DEFINES_FILE <string>])")
else()
if(NOT "${RE2C_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
set(RE2C_EXECUTABLE_opts "${RE2C_TARGET_ARG_COMPILE_FLAGS}")
separate_arguments(RE2C_EXECUTABLE_opts)
else()
set(RE2C_EXECUTABLE_opts "")
endif()
if(NOT "${RE2C_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
list(APPEND RE2C_EXECUTABLE_opts -t ${RE2C_TARGET_ARG_DEFINES_FILE})
endif()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${RE2COutput}
COMMAND ${RE2C_EXECUTABLE}
ARGS ${RE2C_EXECUTABLE_opts} -o ${RE2COutput} ${CMAKE_CURRENT_SOURCE_DIR}/${RE2CInput}
DEPENDS ${RE2CInput}
COMMENT "[RE2C][${Name}] Building scanner with ${RE2C_EXECUTABLE}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
# TODO: check, for generated sources headers should be included in outputs
set(RE2C_${Name}_DEFINED TRUE)
set(RE2C_${Name}_OUTPUTS ${RE2COutput})
if("${RE2C_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
set(RE2C_${Name}_OUTPUT_HEADER "")
else()
set(RE2C_${Name}_OUTPUT_HEADER "${RE2C_TARGET_ARG_DEFINES_FILE}")
endif()
set(RE2C_${Name}_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
add_custom_command(OUTPUT ${Output}
COMMAND ${RE2C_EXECUTABLE}
ARGS ${RE2C_EXECUTABLE_opts} -o${Output} ${Input}
DEPENDS ${Input} ${RE2C_EXECUTABLE_TARGET}
COMMENT "[RE2C][${Name}] Building scanner with ${RE2C_EXECUTABLE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
set(RE2C_${Name}_DEFINED TRUE)
set(RE2C_${Name}_OUTPUTS ${Output})
set(RE2C_${Name}_INPUT ${Input})
set(RE2C_${Name}_COMPILE_FLAGS ${RE2C_EXECUTABLE_opts})
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${Output}")
endmacro(RE2C_TARGET)
endif(NOT COMMAND RE2C_TARGET)
#============================================================
@@ -125,16 +148,22 @@ if(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY)
message(SEND_ERROR "RE2C target `${RE2CTarget}' does not exists.")
endif()
if(NOT LEMON_${LemonTarget}_HDR)
if(NOT LEMON_${LemonTarget}_OUTPUT_HEADER)
message(SEND_ERROR "Lemon target `${LemonTarget}' does not exists.")
endif()
set_source_files_properties(${RE2C_${RE2CTarget}_OUTPUTS}
PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_HDR})
PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_OUTPUT_HEADER})
endmacro(ADD_RE2C_LEMON_DEPENDENCY)
endif(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY)
#============================================================
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(RE2C REQUIRED_VARS RE2C_EXECUTABLE
VERSION_VAR RE2C_VERSION)
# RE2C_Util.cmake ends here
# Local Variables:
+20 -28
View File
@@ -1,4 +1,4 @@
# The Express parser uses the tools Perplex, RE2C and Lemon to generate code
# The Express parser uses the tools RE2C and Lemon to generate code
# from higher level inputs. Depending on available tools and options, the
# SC build can either re-generate code as part of the build, or use cached
# files that are ready for compilation.
@@ -10,45 +10,37 @@
# this option is set to ON and the necessary tools are not found, the
# configure step will fail. If it is set to OFF, SC will not even try to use
# the generators and will instead use the cached sources.
if(NOT DEFINED SC_GENERATE_LEXER_PARSER)
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
set(_verbosity "QUIET")
else(NOT DEFINED SC_GENERATE_LEXER_PARSER)
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
endif(NOT DEFINED SC_GENERATE_LEXER_PARSER)
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS AUTO ON OFF)
if (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
set(_valid_gen_states AUTO ON OFF)
set(_verbosity "QUIET")
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE
STRING "Use Perplex, RE2C and Lemon to generate C source code.")
set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS ${_valid_gen_states})
string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER)
if(NOT "${SC_GENERATE_LEXER_PARSER}" IN_LIST _valid_gen_states)
message(WARNING "Unknown value ${SC_GENERATE_LEXER_PARSER} supplied for SC_GENERATE_LEXER_PARSER - defaulting to AUTO")
message(WARNING "Valid options are AUTO, ON and OFF")
set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE STRING "Use Perplex, RE2C and Lemon to generate C source code.")
endif (NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "AUTO" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON" AND NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
endif()
# If the generators have not been turned off, we need to check for them
if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
# NOTE: lemon doesn't have a stable versioning system (it's always 1)
find_package(LEMON ${_verbosity})
find_package(RE2C ${_verbosity})
find_package(PERPLEX ${_verbosity})
if(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
# Templates may be anywhere - make sure we have a stable path if a relative
# path was specified at CMake time
get_filename_component(lemon_template_fpath "${LEMON_TEMPLATE}" ABSOLUTE)
if(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(LEMON_TEMPLATE "${CMAKE_BINARY_DIR}/${LEMON_TEMPLATE}" ABSOLUTE)
endif(NOT "${lemon_template_fpath}" STREQUAL "${LEMON_TEMPLATE}")
get_filename_component(perplex_template_fpath "${PERPLEX_TEMPLATE}" ABSOLUTE)
if(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
get_filename_component(PERPLEX_TEMPLATE "${CMAKE_BINARY_DIR}/${PERPLEX_TEMPLATE}" ABSOLUTE)
endif(NOT "${perplex_template_fpath}" STREQUAL "${PERPLEX_TEMPLATE}")
find_package(RE2C 1.0.3 ${_verbosity})
if(LEMON_FOUND AND RE2C_FOUND)
set(SC_GENERATE_LP_SOURCES 1)
message(".. Found perplex, re2c, and lemon - can regenerate lexer/parser if necessary")
else(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
message(".. Found re2c, and lemon - can regenerate lexer/parser if necessary")
else()
if("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but one or more components of the Perplex/RE2C/Lemon toolchain were not found.\n")
message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but couldn't find lemon/re2c")
else("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
set(SC_GENERATE_LP_SOURCES 0)
endif("${SC_GENERATE_LEXER_PARSER}" STREQUAL "ON")
endif(LEMON_EXECUTABLE AND LEMON_TEMPLATE AND PERPLEX_EXECUTABLE AND PERPLEX_TEMPLATE AND RE2C_EXECUTABLE)
endif()
else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
set(SC_GENERATE_LP_SOURCES 0)
endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF")
+3 -2
View File
@@ -21,10 +21,10 @@ set(schema_scanner_src
${SC_ROOT}/src/exp2cxx/class_strings.c
${SC_ROOT}/src/express/generated/expparse.c
${SC_ROOT}/src/express/generated/expscan.c
${SC_ROOT}/src/express/lexsupport.c
${SC_ROOT}/src/express/alg.c
${SC_ROOT}/src/express/alloc.c
${SC_ROOT}/src/express/caseitem.c
${SC_ROOT}/src/express/dict.c
${SC_ROOT}/src/express/entity.c
${SC_ROOT}/src/express/error.c
${SC_ROOT}/src/express/exp_kw.c
@@ -32,7 +32,6 @@ set(schema_scanner_src
${SC_ROOT}/src/express/express.c
${SC_ROOT}/src/express/factory.c
${SC_ROOT}/src/express/hash.c
${SC_ROOT}/src/express/lexact.c
${SC_ROOT}/src/express/linklist.c
${SC_ROOT}/src/express/memory.c
${SC_ROOT}/src/express/object.c
@@ -45,11 +44,13 @@ set(schema_scanner_src
${SC_ROOT}/src/express/symbol.c
${SC_ROOT}/src/express/type.c
${SC_ROOT}/src/express/variable.c
${SC_ROOT}/src/auxlib/bstrlib.c
${CMAKE_CURRENT_SOURCE_DIR}/schemaScanner.cc
)
include_directories(
${SC_ROOT}/include/
${SC_ROOT}/src/auxlib
${SC_ROOT}/src/express/
${SC_ROOT}/src/express/generated
${SC_ROOT}/src/base
-11
View File
@@ -58,23 +58,12 @@ struct freelist_head {
#endif
};
char * nnew();
#include "error.h"
/***********************************************/
/* space allocation macros with error package: */
/***********************************************/
extern SC_EXPRESS_EXPORT int yylineno;
/** CALLOC grabs and initializes to all 0s space for the indicated
* number of instances of the indicated type */
#define CALLOC(ptr, num, type) \
if (((ptr) = (type*)calloc((num), (unsigned)sizeof(type)))==NULL) { \
fprintf(stderr,"fedex: out of space");\
} else {}
SC_EXPRESS_EXPORT void _ALLOCinitialize( void );
SC_EXPRESS_EXPORT void ALLOCinitialize( struct freelist_head * flh, unsigned int size, int alloc1, int alloc2 );
SC_EXPRESS_EXPORT void ALLOC_destroy( struct freelist_head *, Freelist * );
+6 -17
View File
@@ -56,7 +56,7 @@
/************/
typedef struct Hash_Table_ * Dictionary;
typedef HashEntry DictionaryEntry;
typedef struct Hash_Iterator_ DictionaryEntry;
/****************/
/* modules used */
@@ -71,27 +71,15 @@ typedef HashEntry DictionaryEntry;
/********************/
/* global variables */
/********************/
/*TODO: surely this is not a good thing?! */
extern SC_EXPRESS_EXPORT char DICT_type; /**< set as a side-effect of DICT lookup routines to type of object found */
/*******************************/
/* macro function definitions */
/*******************************/
#define DICTcreate(estimated_max_size) HASHcreate(estimated_max_size)
/** should really can DICTdo_init and rename do_type_init to do_init! */
#define DICTdo_init(dict,de) HASHlistinit((dict),(de))
#define DICTdo_type_init(dict,de,t) HASHlistinit_by_type((dict),(de),(t))
#define DICTdo_end(hash_entry) HASHlistend(hash_entry)
/** modify dictionary entry in-place */
#define DICTchange(e,obj,sym,typ) { \
(e)->data = (obj); \
(e)->symbol = (sym); \
(e)->type = (typ); \
}
#define DICTchange_type(e,typ) (e)->type = (typ)
#define DICTcreate(x) HASHcreate()
#define DICTdo_init(dict,de,t) HASHdo_init((dict),(de),(t))
/***********************/
/* function prototypes */
@@ -100,8 +88,9 @@ extern SC_EXPRESS_EXPORT char DICT_type; /**< set as a side-effect of DICT look
extern SC_EXPRESS_EXPORT void DICTinitialize( void );
extern SC_EXPRESS_EXPORT void DICTcleanup( void );
extern SC_EXPRESS_EXPORT int DICTdefine( Dictionary, char *, void *, Symbol *, char );
extern SC_EXPRESS_EXPORT int DICT_define( Dictionary, char *, void *, Symbol *, char );
extern SC_EXPRESS_EXPORT int DICTdefine_enum( Dictionary, char *, void *, Symbol *, char );
extern SC_EXPRESS_EXPORT void DICTundefine( Dictionary, char * );
/* TODO: could DICTlookup be implemented more generically using function pointers? */
extern SC_EXPRESS_EXPORT void * DICTlookup( Dictionary, char * );
extern SC_EXPRESS_EXPORT void * DICTlookup_symbol( Dictionary, char *, Symbol ** );
extern SC_EXPRESS_EXPORT void * DICTdo( DictionaryEntry * );
+3 -3
View File
@@ -144,11 +144,11 @@ extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcreate( struct Symbol_ * );
extern SC_EXPRESS_EXPORT void ENTITYinitialize( void );
extern SC_EXPRESS_EXPORT void ENTITYadd_attribute( struct Scope_ *, struct Variable_ * );
extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcopy( struct Scope_ * );
extern SC_EXPRESS_EXPORT Entity ENTITYfind_inherited_entity( struct Scope_ *, char *, int );
extern SC_EXPRESS_EXPORT Variable ENTITYfind_inherited_attribute( struct Scope_ *, char *, struct Symbol_ ** );
extern SC_EXPRESS_EXPORT Entity ENTITYfind_inherited_entity( struct Scope_ *, const char *, int );
extern SC_EXPRESS_EXPORT Symbol *ENTITYfind_inherited_attribute( struct Scope_ *, const char *, struct Symbol_ ** );
extern SC_EXPRESS_EXPORT Variable ENTITYresolve_attr_ref( Entity, Symbol *, Symbol * );
extern SC_EXPRESS_EXPORT bool ENTITYhas_immediate_supertype( Entity, Entity );
extern SC_EXPRESS_EXPORT Variable ENTITYget_named_attribute( Entity, char * );
extern SC_EXPRESS_EXPORT Variable ENTITYget_named_attribute( Entity, const char * );
extern SC_EXPRESS_EXPORT Linked_List ENTITYget_all_attributes( Entity );
extern SC_EXPRESS_EXPORT bool ENTITYhas_supertype( Entity, Entity );
extern SC_EXPRESS_EXPORT void ENTITYadd_instance( Entity, void *);
+6
View File
@@ -128,6 +128,7 @@ typedef char * Binary;
/** these represent a different way of selecting classes of objects
* these are particularly useful when looking for multiple types concurrently */
#define OBJ_TYPE_BITS 0x1
#define OBJ_ENTITY_BITS 0x2
#define OBJ_FUNCTION_BITS 0x4
@@ -138,6 +139,10 @@ typedef char * Binary;
#define OBJ_SCHEMA_BITS 0x80
#define OBJ_VARIABLE_BITS 0x100
#define OBJ_WHERE_BITS 0x200
#define OBJ_ALIAS_BITS 0x400
#define OBJ_REPEAT_BITS 0x800
#define OBJ_QUERY_BITS 0x1000
#define OBJ_ANYTHING_BITS 0x0fffffff
#define OBJ_UNFINDABLE_BITS 0x10000000 /**< should never be found */
@@ -148,6 +153,7 @@ typedef char * Binary;
/* OBJ_UNUSED should die, but until it does, allow it to work */
#define OBJ_UNUSED_BITS OBJ_UNFINDABLE_BITS
#define OBJ_DOCROOT_BITS OBJ_UNFINDABLE_BITS
#endif /*EXPRESS_BASIC_H*/
+1 -2
View File
@@ -62,7 +62,6 @@
#include "alg.h"
#include "schema.h"
#include "lexact.h"
#include "dict.h"
/************/
/* typedefs */
@@ -102,7 +101,7 @@ extern char EXPRESSgetopt_options[]; /* initialized elsewhere */
extern SC_EXPRESS_EXPORT int ( *EXPRESSgetopt )( int, char * );
extern SC_EXPRESS_EXPORT bool EXPRESSignore_duplicate_schemas;
extern SC_EXPRESS_EXPORT Dictionary EXPRESSbuiltins; /* procedures/functions */
extern SC_EXPRESS_EXPORT Hash_Table EXPRESSbuiltins; /* procedures/functions */
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_NVL;
extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_USEDIN;
+31 -92
View File
@@ -80,28 +80,10 @@
*
*/
#include "basic.h" /* get basic definitions */
#include "sc_export.h"
/*************/
/* constants */
/*************/
#define HASH_NULL (Hash_Table)NULL
#define SEGMENT_SIZE 256
#define SEGMENT_SIZE_SHIFT 8 /**< log2(SEGMENT_SIZE) */
#define DIRECTORY_SIZE 256
#define DIRECTORY_SIZE_SHIFT 8 /**< log2(DIRECTORY_SIZE) */
#define PRIME1 37
#define PRIME2 1048583
#define MAX_LOAD_FACTOR 5
/*****************/
/* packages used */
/*****************/
#include <sc_export.h>
#include "alloc.h"
#include "expbasic.h"
#include "symbol.h"
/************/
/* typedefs */
@@ -109,96 +91,53 @@
typedef enum { HASH_FIND, HASH_INSERT, HASH_DELETE } Action;
typedef unsigned long Address;
/****************/
/* abstractions */
/****************/
typedef struct Element_ {
char * key;
char * data;
struct Element_ * next;
Symbol * symbol; /**< for debugging hash conflicts */
char type; /**< user-supplied type */
} * Element;
typedef Symbol **Segment;
typedef Element * Segment;
typedef struct Hash_Table_ {
#if 0
int in_use; /**< If someone is traversing the hash table */
#endif
unsigned int p; /**< Next bucket to be split */
unsigned int maxp; /**< upper bound on p during expansion */
struct Hash_Table_ {
unsigned int p; /**< Next bucket to be split */
unsigned int maxp; /**< upper bound on p during expansion */
unsigned int KeyCount; /**< current # keys */
unsigned int SegmentCount; /**< current # segments */
unsigned int MinLoadFactor;
unsigned int MaxLoadFactor;
Segment Directory[DIRECTORY_SIZE];
} * Hash_Table;
Segment *Directory;
unsigned int DirectorySize;
unsigned int SegmentSize;
#ifdef HASH_DEBUG
unsigned int HashCollisions;
#endif
};
typedef struct {
unsigned int i; /**< segment index (i think) */
unsigned int j; /**< key index in segment (ditto) */
Element p; /**< usually the next element to be returned */
typedef struct Hash_Table_ *Hash_Table;
struct Hash_Iterator_ {
Hash_Table table;
unsigned int hash;
Symbol *p;
char type;
Element e; /**< originally thought of as a place for
* the caller of HASHlist to temporarily stash the return value
* to allow the caller (i.e., DICTdo) to be macroized, but now
* conveniently used by HASHlist, which both stores the ultimate
* value here as well as returns it via the return value of HASHlist
*/
} HashEntry;
};
typedef struct Hash_Iterator_ Hash_Iterator;
/********************/
/* global variables */
/********************/
extern SC_EXPRESS_EXPORT struct freelist_head HASH_Table_fl;
extern SC_EXPRESS_EXPORT struct freelist_head HASH_Element_fl;
/******************************/
/* macro function definitions */
/******************************/
/*
** Fast arithmetic, relying on powers of 2
*/
/**
The centerline compiler was having problems with MUL and DIV. Where DIV
was called like this DIV(NewAddress, SEGMENT_SIZE) it is now being called like
DIV(NewAddress, SEGMENT_SIZE_SHIFT). The compiler was mentioning some kind of
problem with ##. I wonder if maybe the precompiler was expanding SEGMENT_SIZE
(which is also defined as a macro) before turning it into SEGMENT_SIZE_SHIFT.
SEGMENT_SIZE and DIRECTORY_SIZE were used to call these macros. They are both
defined to be 8 though so it seems these are always being used the same way.
This change only seems to have affected hash.h and hash.c
*/
/* #define MUL(x,y) ((x) << (y##_SHIFT)) */
#define MUL(x,y) ((x) << (y))
/* #define DIV(x,y) ((x) >> (y##_SHIFT)) */
#define DIV(x,y) ((x) >> (y))
#define MOD(x,y) ((x) & ((y)-1))
#define HASH_Table_new() (struct Hash_Table_ *)ALLOC_new(&HASH_Table_fl)
#define HASH_Table_destroy(x) ALLOC_destroy(&HASH_Table_fl,(Freelist *)x)
#define HASH_Element_new() (struct Element_ *)ALLOC_new(&HASH_Element_fl)
#define HASH_Element_destroy(x) ALLOC_destroy(&HASH_Element_fl,(Freelist *)(char *)x)
/***********************/
/* function prototypes */
/***********************/
extern SC_EXPRESS_EXPORT void HASHinitialize( void );
extern SC_EXPRESS_EXPORT Hash_Table HASHcreate( unsigned );
extern SC_EXPRESS_EXPORT Hash_Table HASHcopy( Hash_Table );
extern SC_EXPRESS_EXPORT void HASHdestroy( Hash_Table );
extern SC_EXPRESS_EXPORT Element HASHsearch( Hash_Table, Element, Action );
extern SC_EXPRESS_EXPORT void HASHlistinit( Hash_Table, HashEntry * );
extern SC_EXPRESS_EXPORT void HASHlistinit_by_type( Hash_Table, HashEntry *, char );
extern SC_EXPRESS_EXPORT Element HASHlist( HashEntry * );
extern SC_EXPRESS_EXPORT void HASHinitialize( void );
extern SC_EXPRESS_EXPORT Hash_Table HASHcreate( void );
extern SC_EXPRESS_EXPORT Hash_Table HASHcopy( Hash_Table );
extern SC_EXPRESS_EXPORT void HASHdestroy( Hash_Table );
extern SC_EXPRESS_EXPORT Symbol * HASHsearch( Hash_Table, Symbol, Action );
extern SC_EXPRESS_EXPORT void HASHdelete( Hash_Table, Symbol * );
extern SC_EXPRESS_EXPORT void HASHdo_init( Hash_Table, Hash_Iterator *, char );
extern SC_EXPRESS_EXPORT Symbol * HASHdo( Hash_Iterator * );
#endif /*HASH_H*/
#endif /* HASH_H */
+8
View File
@@ -0,0 +1,8 @@
#ifndef __SC_FWD_H
#define __SC_FWD_H
struct Symbol_;
typedef struct Symbol_ Symbol;
#endif /* __SC_FWD_H */
+4 -4
View File
@@ -61,8 +61,8 @@
/****************/
#include "alg.h"
#include "dict.h"
#include "entity.h"
#include "hash.h"
#include "linklist.h"
/***************************/
@@ -91,8 +91,8 @@ struct Schema_ {
* dictionaries into which are entered renames for each specific
* object specified in a rename clause (even if it uses the same
* name */
Dictionary refdict;
Dictionary usedict;
Hash_Table refdict;
Hash_Table usedict;
Linked_List use_schemas; /**< lists of schemas that are fully use'd
* entries can be 0 if schemas weren't found during RENAMEresolve */
@@ -133,7 +133,7 @@ extern SC_EXPRESS_EXPORT int __SCOPE_search_id;
/* function prototypes */
/***********************/
extern SC_EXPRESS_EXPORT Variable VARfind( Scope, char *, int );
extern SC_EXPRESS_EXPORT Symbol * VARfind( Scope, const char * );
extern SC_EXPRESS_EXPORT Schema SCHEMAcreate( void );
extern SC_EXPRESS_EXPORT void SCHEMAinitialize( void );
extern SC_EXPRESS_EXPORT void SCHEMAadd_use( Schema, Symbol *, Symbol *, Symbol * );
+8 -8
View File
@@ -50,6 +50,7 @@
/****************/
#include <sc_export.h>
#include "hash.h"
#include "type.h"
#include "variable.h"
#include "entity.h"
@@ -62,7 +63,6 @@
/*****************/
#include "expbasic.h" /* get basic definitions */
#include "dict.h"
#include "symbol.h"
/***************************/
@@ -82,7 +82,7 @@ struct Scope_ {
char type; /* see above */
ClientData clientData; /**< user may use this for any purpose */
int search_id; /**< key to avoid searching this scope twice */
Dictionary symbol_table, enum_table;
Hash_Table symbol_table, enum_table;
struct Scope_ * superscope;
union {
struct Procedure_ * proc;
@@ -115,16 +115,16 @@ struct Scope_ {
#define SCOPEput_clientData(s,d) ((s)->clientData = (d))
#define SCOPEdo_types(s,t,de) DICTdo_type_init(s->symbol_table,&de,OBJ_TYPE);{\
#define SCOPEdo_types(s,t,de) DICTdo_init(s->symbol_table,&de,OBJ_TYPE);{\
Type t; \
while (0 != (t = (Type)DICTdo(&de))) {
#define SCOPEdo_entities(s,t,de) DICTdo_type_init(s->symbol_table,&de,OBJ_ENTITY); { \
#define SCOPEdo_entities(s,t,de) DICTdo_init(s->symbol_table,&de,OBJ_ENTITY); { \
Entity t; \
while (0 != (t = (Entity)DICTdo(&de))) {
#define SCOPEdo_functions(s,t,de) DICTdo_type_init(s->symbol_table,&de,OBJ_FUNCTION); { \
#define SCOPEdo_functions(s,t,de) DICTdo_init(s->symbol_table,&de,OBJ_FUNCTION); { \
Entity t; \
while (0 != (t = (Entity)DICTdo(&de))) {
#define SCOPEdo_rules(s,t,de) DICTdo_type_init(s->symbol_table,&de,OBJ_RULE); { \
#define SCOPEdo_rules(s,t,de) DICTdo_init(s->symbol_table,&de,OBJ_RULE); { \
Entity t; \
while (0 != (t = (Entity)DICTdo(&de))) {
@@ -138,12 +138,12 @@ extern SC_EXPRESS_EXPORT struct Symbol_ * SCOPE_get_symbol( void * );
extern SC_EXPRESS_EXPORT void SCOPE_get_entities( Scope, Linked_List );
extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities( Scope );
extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities_superclass_order( Scope );
extern SC_EXPRESS_EXPORT void * SCOPEfind( Scope, char *, int );
extern SC_EXPRESS_EXPORT Symbol * SCOPEfind( Scope, const char *, int );
extern SC_EXPRESS_EXPORT void SCOPE_get_functions( Scope, Linked_List );
extern SC_EXPRESS_EXPORT Linked_List SCOPEget_functions( Scope );
extern SC_EXPRESS_EXPORT void SCOPE_get_rules( Scope, Linked_List );
extern SC_EXPRESS_EXPORT Linked_List SCOPEget_rules( Scope );
void * SCOPE_find( Scope, char *, int );
Symbol * SCOPE_find( Scope, const char *, int );
#endif /* SCOPE_H */
+16 -15
View File
@@ -43,27 +43,30 @@
/* packages used */
/*****************/
#include <sc_export.h>
#include "sc_export.h"
#include "basic.h" /* get basic definitions */
#include "alloc.h"
/************/
/* typedefs */
/************/
typedef struct Symbol_ Symbol;
/***************************/
/* hidden type definitions */
/* type definitions */
/***************************/
struct Symbol_ {
char * name;
const char * filename;
const char *name;
void *data; /* the AST for this symbol */
char type; /* the OBJ_ type, see expbasic.h */
int ref_tok; /* the lexer ref_type for this symbol */
const char *filename;
int line;
char resolved;
char resolved; /* if imported TYPE or ENTITY is unresolved */
struct Symbol_ *next; /* symbol table clashes */
};
typedef struct Symbol_ Symbol;
/****************/
/* modules used */
/****************/
@@ -78,9 +81,7 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl;
/* macro function definitions */
/******************************/
#define SYMBOL_new() (struct Symbol_ *)ALLOC_new(&SYMBOL_fl)
#define SYMBOL_destroy(x) ALLOC_destroy(&SYMBOL_fl,(Freelist *)x)
/* TODO: gets called from e.g. type.c, should be set by parser */
#define SYMBOLset(obj) obj->symbol.line = yylineno; \
obj->symbol.filename = current_filename
@@ -89,6 +90,6 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl;
/***********************/
extern SC_EXPRESS_EXPORT void SYMBOLinitialize( void );
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, const char * filename );
SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int type, int ref_tok, int line, const char * filename );
#endif /* SYMBOL_H */
-1
View File
@@ -129,7 +129,6 @@ typedef enum type_enum Class;
/* modules used */
/****************/
#include "dict.h"
#include "entity.h"
#include "expr.h"
#include "scope.h"
+1 -1
View File
@@ -127,6 +127,6 @@ extern SC_EXPRESS_EXPORT struct freelist_head VAR_fl;
extern SC_EXPRESS_EXPORT Variable VARcreate( Expression, Type );
extern SC_EXPRESS_EXPORT void VARinitialize( void );
extern SC_EXPRESS_EXPORT char * VARget_simple_name( Variable );
extern SC_EXPRESS_EXPORT const char * VARget_simple_name( Variable );
#endif /* VARIABLE_H */
+16
View File
@@ -0,0 +1,16 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
if (${SC_MEMMGR_ENABLE_CHECKS})
add_definitions(-DSC_MEMMGR_ENABLE_CHECKS)
endif()
SC_ADDLIB(auxlib STATIC SOURCES bstrlib.c)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+3137
View File
File diff suppressed because it is too large Load Diff
+321
View File
@@ -0,0 +1,321 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2015, and is covered by the BSD open source
* license and the GPL. Refer to the accompanying documentation for details
* on usage and license.
*/
/*
* bstrlib.h
*
* This file is the interface for the core bstring functions.
*/
#ifndef BSTRLIB_INCLUDE
#define BSTRLIB_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) && !defined (__BORLANDC__)
# define BSTRLIB_NOVSNP
# endif
#endif
#define BSTR_ERR (-1)
#define BSTR_OK (0)
#define BSTR_BS_BUFF_LENGTH_GET (0)
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
/* Version */
#define BSTR_VER_MAJOR 1
#define BSTR_VER_MINOR 0
#define BSTR_VER_UPDATE 0
/* Copy functions */
#define cstr2bstr bfromcstr
extern bstring bfromcstr (const char * str);
extern bstring bfromcstralloc (int mlen, const char * str);
extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str);
extern bstring blk2bstr (const void * blk, int len);
extern char * bstr2cstr (const_bstring s, char z);
extern int bcstrfree (char * s);
extern bstring bstrcpy (const_bstring b1);
extern int bassign (bstring a, const_bstring b);
extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
extern int bassigncstr (bstring a, const char * str);
extern int bassignblk (bstring a, const void * s, int len);
/* Destroy function */
extern int bdestroy (bstring b);
/* Space allocation hinting functions */
extern int balloc (bstring s, int len);
extern int ballocmin (bstring b, int len);
/* Substring extraction */
extern bstring bmidstr (const_bstring b, int left, int len);
/* Various standard manipulations */
extern int bconcat (bstring b0, const_bstring b1);
extern int bconchar (bstring b0, char c);
extern int bcatcstr (bstring b, const char * s);
extern int bcatblk (bstring b, const void * s, int len);
extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
extern int binsertblk (bstring s1, int pos, const void * s2, int len, unsigned char fill);
extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
extern int bdelete (bstring s1, int pos, int len);
extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
extern int btrunc (bstring b, int n);
/* Scan/search functions */
extern int bstricmp (const_bstring b0, const_bstring b1);
extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
extern int biseqcaseless (const_bstring b0, const_bstring b1);
extern int biseqcaselessblk (const_bstring b, const void * blk, int len);
extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
extern int biseq (const_bstring b0, const_bstring b1);
extern int biseqblk (const_bstring b, const void * blk, int len);
extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
extern int biseqcstr (const_bstring b, const char * s);
extern int biseqcstrcaseless (const_bstring b, const char * s);
extern int bstrcmp (const_bstring b0, const_bstring b1);
extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
extern int binstr (const_bstring s1, int pos, const_bstring s2);
extern int binstrr (const_bstring s1, int pos, const_bstring s2);
extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int bstrchrp (const_bstring b, int c, int pos);
extern int bstrrchrp (const_bstring b, int c, int pos);
#define bstrchr(b,c) bstrchrp ((b), (c), 0)
#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
extern int binchr (const_bstring b0, int pos, const_bstring b1);
extern int binchrr (const_bstring b0, int pos, const_bstring b1);
extern int bninchr (const_bstring b0, int pos, const_bstring b1);
extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
/* List of string container functions */
struct bstrList {
int qty, mlen;
bstring * entry;
};
extern struct bstrList * bstrListCreate (void);
extern int bstrListDestroy (struct bstrList * sl);
extern int bstrListAlloc (struct bstrList * sl, int msz);
extern int bstrListAllocMin (struct bstrList * sl, int msz);
/* String split and join functions */
extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
extern bstring bjoinblk (const struct bstrList * bl, const void * s, int len);
extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
/* Miscellaneous functions */
extern int bpattern (bstring b, int len);
extern int btoupper (bstring b);
extern int btolower (bstring b);
extern int bltrimws (bstring b);
extern int brtrimws (bstring b);
extern int btrimws (bstring b);
#if !defined (BSTRLIB_NOVSNP)
extern bstring bformat (const char * fmt, ...);
extern int bformata (bstring b, const char * fmt, ...);
extern int bassignformat (bstring b, const char * fmt, ...);
extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
typedef int (*bNgetc) (void *parm);
typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
/* Input functions */
extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
extern bstring bread (bNread readPtr, void * parm);
extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int breada (bstring b, bNread readPtr, void * parm);
/* Stream functions */
extern struct bStream * bsopen (bNread readPtr, void * parm);
extern void * bsclose (struct bStream * s);
extern int bsbufflength (struct bStream * s, int sz);
extern int bsreadln (bstring b, struct bStream * s, char terminator);
extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
extern int bsread (bstring b, struct bStream * s, int n);
extern int bsreadlna (bstring b, struct bStream * s, char terminator);
extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
extern int bsreada (bstring b, struct bStream * s, int n);
extern int bsunread (struct bStream * s, const_bstring b);
extern int bspeek (bstring r, const struct bStream * s);
extern int bssplitscb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bseof (const struct bStream * s);
struct tagbstring {
int mlen;
int slen;
unsigned char * data;
};
/* Accessor macros */
#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
#define blength(b) (blengthe ((b), 0))
#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
#define bdatae(b, e) (bdataofse (b, 0, e))
#define bdata(b) (bdataofs (b, 0))
#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
#define bchar(b, p) bchare ((b), (p), '\0')
/* Static constant string initialization macro */
#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
#if defined(_MSC_VER)
# define bsStatic(q) bsStaticMlen(q,-32)
#endif
#ifndef bsStatic
# define bsStatic(q) bsStaticMlen(q,-__LINE__)
#endif
/* Static constant block parameter pair */
#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
#define bcatStatic(b,s) ((bcatblk)((b), bsStaticBlkParms(s)))
#define bfromStatic(s) ((blk2bstr)(bsStaticBlkParms(s)))
#define bassignStatic(b,s) ((bassignblk)((b), bsStaticBlkParms(s)))
#define binsertStatic(b,p,s,f) ((binsertblk)((b), (p), bsStaticBlkParms(s), (f)))
#define bjoinStatic(b,s) ((bjoinblk)((b), bsStaticBlkParms(s)))
#define biseqStatic(b,s) ((biseqblk)((b), bsStaticBlkParms(s)))
#define bisstemeqStatic(b,s) ((bisstemeqblk)((b), bsStaticBlkParms(s)))
#define biseqcaselessStatic(b,s) ((biseqcaselessblk)((b), bsStaticBlkParms(s)))
#define bisstemeqcaselessStatic(b,s) ((bisstemeqcaselessblk)((b), bsStaticBlkParms(s)))
/* Reference building macros */
#define cstr2tbstr btfromcstr
#define btfromcstr(t,s) { \
(t).data = (unsigned char *) (s); \
(t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
(t).mlen = -1; \
}
#define blk2tbstr(t,s,l) { \
(t).data = (unsigned char *) (s); \
(t).slen = l; \
(t).mlen = -1; \
}
#define btfromblk(t,s,l) blk2tbstr(t,s,l)
#define bmid2tbstr(t,b,p,l) { \
const_bstring bstrtmp_s = (b); \
if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
int bstrtmp_left = (p); \
int bstrtmp_len = (l); \
if (bstrtmp_left < 0) { \
bstrtmp_len += bstrtmp_left; \
bstrtmp_left = 0; \
} \
if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
if (bstrtmp_len <= 0) { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} else { \
(t).data = bstrtmp_s->data + bstrtmp_left; \
(t).slen = bstrtmp_len; \
} \
} else { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} \
(t).mlen = -__LINE__; \
}
#define btfromblkltrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l); \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
#define btfromblkrtrimws(t,s,l) { \
int bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_len >= 0; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s; \
(t).slen = bstrtmp_len + 1; \
(t).mlen = -__LINE__; \
}
#define btfromblktrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
/* Write protection macros */
#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
#define biswriteprotected(t) ((t).mlen <= 0)
#ifdef __cplusplus
}
#endif
#endif
+4 -4
View File
@@ -70,10 +70,10 @@ inline void operator delete[]( void * addr ) throw () {
#endif /* SC_MEMMGR_CC */
#else
#define sc_malloc(size) malloc(size)
#define sc_calloc(count, size) calloc(count, size)
#define sc_realloc(addr, size) realloc(addr, size)
#define sc_free(addr) free(addr)
#define sc_malloc malloc
#define sc_calloc calloc
#define sc_realloc realloc
#define sc_free free
#endif /* SC_MEMMGR_ENABLE_CHECKS */
#endif /* SC_MEMMGR_H */
+2 -2
View File
@@ -128,7 +128,7 @@ void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * t
/* sort each list by schema */
/* step 1: for each entry, store it in a schema-specific list */
DICTdo_init( refdict, &de );
DICTdo_init( refdict, &de, '*' );
while( 0 != ( r = ( struct Rename * )DICTdo( &de ) ) ) {
Linked_List wlist;
@@ -141,7 +141,7 @@ void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * t
}
/* step 2: for each list, print out the renames */
DICTdo_init( dict, &de );
DICTdo_init( dict, &de, '*' );
while( 0 != ( list = ( Linked_List )DICTdo( &de ) ) ) {
bool first_time = true;
LISTdo( list, re, struct Rename * ) {
+1 -1
View File
@@ -1049,7 +1049,7 @@ void ENTITYlib_print( Entity entity, Linked_List neededAttr, FILE * file, Schema
*/
void ENTITYPrint( Entity entity, FILES * files, Schema schema, bool externMap ) {
FILE * hdr, * impl;
char * n = ENTITYget_name( entity );
const char * n = ENTITYget_name( entity );
Linked_List remaining = LISTcreate();
filenames_t names = getEntityFilenames( entity );
+4 -3
View File
@@ -258,7 +258,7 @@ void TYPEenum_lib_print( const Type type, FILE * f ) {
fprintf( f, "const char *\n%s::element_at (int n) const {\n", n );
fprintf( f, " switch (n) {\n" );
DICTdo_type_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
DICTdo_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) {
strncpy( c_enum_ele, EnumCElementName( type, expr ), BUFSIZ );
c_enum_ele[BUFSIZ-1] = '\0';
@@ -279,7 +279,7 @@ void TYPEenum_lib_print( const Type type, FILE * f ) {
fprintf( f, "\n%s::operator %s () const {\n", n,
EnumName( TYPEget_name( type ) ) );
fprintf( f, " switch (v) {\n" );
DICTdo_type_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
DICTdo_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) {
strncpy( c_enum_ele, EnumCElementName( type, expr ), BUFSIZ );
fprintf( f, " case %s : ", c_enum_ele );
@@ -1203,7 +1203,8 @@ char * TYPEget_express_type( const Type t ) {
Class_Of_Type class;
Type bt;
char retval [BUFSIZ];
char * n, * permval, * aggr_type;
const char *n;
char *permval, *aggr_type;
/* 1. "DEFINED" types */
+8 -8
View File
@@ -203,7 +203,7 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
* Modified Jan 2012 by MAP - moving enums to own dictionary */
if( scope->enum_table ) {
HASHlistinit_by_type( scope->enum_table, &de, OBJ_TYPE );
HASHlistinit( scope->enum_table, &de, OBJ_TYPE );
Type t;
while( 0 != ( t = ( Type ) DICTdo( &de ) ) ) {
// First check for one exception: Say enumeration type B is defined
@@ -239,7 +239,7 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, ComplexCollect * col
fprintf( files->inc, "// ***** Redefined Enumerations:\n" );
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
* Modified Jan 2012 by MAP - moving enums to own dictionary */
HASHlistinit_by_type( scope->enum_table, &de, OBJ_TYPE );
HASHlistinit( scope->enum_table, &de, OBJ_TYPE );
Type t;
while( 0 != ( t = ( Type ) DICTdo( &de ) ) ) {
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
@@ -497,7 +497,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
fprintf( createall, " reg.AddSchema (*%s::schema);\n", SCHEMAget_name( schema ) );
/**************/
/* add global RULEs to Schema dictionary entry */
DICTdo_type_init( schema->symbol_table, &de, OBJ_RULE );
DICTdo_init( schema->symbol_table, &de, OBJ_RULE );
while( 0 != ( r = ( Rule )DICTdo( &de ) ) ) {
fprintf( createall, " str.clear();\n" );
format_for_std_stringout( createall, RULEto_string( r ) );
@@ -506,7 +506,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
}
/**************/
/* add FUNCTIONs to Schema dictionary entry */
DICTdo_type_init( schema->symbol_table, &de, OBJ_FUNCTION );
DICTdo_init( schema->symbol_table, &de, OBJ_FUNCTION );
while( 0 != ( f = ( Function )DICTdo( &de ) ) ) {
fprintf( createall, " str.clear();\n" );
format_for_std_stringout( createall, FUNCto_string( f ) );
@@ -514,7 +514,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix )
}
/* add PROCEDUREs to Schema dictionary entry */
DICTdo_type_init( schema->symbol_table, &de, OBJ_PROCEDURE );
DICTdo_init( schema->symbol_table, &de, OBJ_PROCEDURE );
while( 0 != ( p = ( Procedure )DICTdo( &de ) ) ) {
fprintf( createall, " str.clear();\n" );
format_for_std_stringout( createall, PROCto_string( p ) );
@@ -582,7 +582,7 @@ void getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
"// dictionary (Registry) handle since it doesn't have a\n",
"// predetermined way to access to the handle.\n" );
fprintf( schema_cc, "\nSDAI_Model_contents_ptr GetModelContents(char *schemaName) {\n" );
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
schema = ( Scope )DICTdo( &de );
fprintf( schema_cc, " if(!strcmp(schemaName, \"%s\"))\n", SCHEMAget_name( schema ) );
fprintf( schema_cc, " return (SDAI_Model_contents_ptr) new SdaiModel_contents_%s; \n", SCHEMAget_name( schema ) );
@@ -673,12 +673,12 @@ void EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) {
fprintf( schemainit, " %sInit (reg);\n", schnm );
/********** do all schemas ***********/
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
numberAttributes( schema );
}
DICTdo_init( express->symbol_table, &de );
DICTdo_init( express->symbol_table, &de, '*' );
bool first = true;
while( 0 != ( schema = ( Scope )DICTdo( &de ) ) ) {
if( !first ) {
+1 -1
View File
@@ -70,7 +70,7 @@ void ComplexCollect::remove( ComplexList * c )
count--;
}
ComplexList * ComplexCollect::find( char * name )
ComplexList * ComplexCollect::find( const char * name )
/*
* Searches for and returns the ComplexList whose supertype name = name.
*/
+3 -3
View File
@@ -355,10 +355,10 @@ class ComplexList {
int operator< ( ComplexList & c ) {
return ( strcmp( supertype(), c.supertype() ) < 0 );
}
int operator< ( char * name ) {
int operator< ( const char * name ) {
return ( strcmp( supertype(), name ) < 0 );
}
int operator== ( char * name ) {
int operator== ( const char * name ) {
return ( strcmp( supertype(), name ) == 0 );
}
const char * supertype() {
@@ -410,7 +410,7 @@ class ComplexCollect {
void remove( ComplexList * );
// Remove this list but don't delete its hierarchy structure, because
// it's used elsewhere.
ComplexList * find( char * );
ComplexList * find( const char * );
int supports( EntNode * );
bool externMapping( const char * ent ) {
return ( clists ? clists->isDependent( ent ) : 0 );
+5 -5
View File
@@ -16,7 +16,7 @@
// Local function prototypes:
static void initEnts( Express );
static Entity findEnt( Entity, char * );
static Entity findEnt( Entity, const char * );
ComplexCollect::ComplexCollect( Express express )
/*
@@ -38,7 +38,7 @@ ComplexCollect::ComplexCollect( Express express )
initEnts( express );
// Next loop through all the entities, building ComplexLists:
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
SCOPEdo_entities( schema, ent, de_ent )
if( ent->search_id == TRUE ) {
@@ -96,7 +96,7 @@ static void initEnts( Express express )
DictionaryEntry de_sch, de_ent;
Schema schema;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
SCOPEdo_entities( schema, ent, de_ent )
ent->search_id = FALSE;
@@ -235,7 +235,7 @@ void MultList::processSubExp( Expression exp, Entity super,
}
}
static Entity findEnt( Entity ent0, char * name )
static Entity findEnt( Entity ent0, const char * name )
/*
* Returns an entity named name. The desired entity is likely to be in the
* same schema as ent0. findEnt first searches the schema which contains
@@ -256,7 +256,7 @@ static Entity findEnt( Entity ent0, char * name )
// If we still haven't found it, look through all the entities in the
// express file:
express = schema->superscope;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( sch = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
if( sch == schema ) {
// Don't redo the schema which contains ent0 - we did it already.
+11 -10
View File
@@ -75,13 +75,13 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files )
/* TODO only print gr, wr, str as needed, from SCHEMAprint in classes_wrapper.cc? */
fprintf( files->create, " Global_rule_ptr gr;\n Where_rule_ptr wr;\n std::string str; //for large strings such as functions or global rules\n" );
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
numberAttributes( schema );
}
while( !complete ) {
complete = true;
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
if( schema->search_id == UNPROCESSED ) {
/* i.e., if the schema has more ents/types to process in it */
@@ -126,7 +126,7 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files )
/*******************
*******************/
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
fprintf( files->create,
"//////////////// USE statements\n" );
@@ -141,7 +141,7 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files )
/* Before closing, we have three more situations to deal with (i.e., three
// types of declarations etc. which could only be printed at the end).
// Each is explained in the header section of its respective function. */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
/* (These two tasks are totally unrelated but are done in the same loop
// for efficiency.) */
@@ -150,7 +150,7 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files )
}
/* Third situation: (Must be dealt with after first, see header comments
// of addAggrTypedefs.) */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
addAggrTypedefs( schema, files->classes );
}
@@ -186,7 +186,7 @@ static void initializeMarks( Express express )
DictionaryEntry de_sch, de_ent, de_type;
Schema schema;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
schema->search_id = UNPROCESSED;
schema->clientData = ( int * )sc_malloc( sizeof( int ) );
@@ -204,7 +204,7 @@ static void cleanupMarks( Express express ) {
DictionaryEntry de_sch;
Schema schema;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
if( schema->clientData ) {
sc_free( schema->clientData );
@@ -691,11 +691,12 @@ static void addUseRefNames( Schema schema, FILE * create ) {
Dictionary useRefDict;
DictionaryEntry de;
Rename * rnm;
char * oldnm, schNm[BUFSIZ];
const char *oldnm;
char schNm[BUFSIZ];
static bool firsttime = true;
if( ( useRefDict = schema->u.schema->usedict ) != NULL ) {
DICTdo_init( useRefDict, &de );
DICTdo_init( useRefDict, &de, '*' );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
@@ -724,7 +725,7 @@ static void addUseRefNames( Schema schema, FILE * create ) {
}
}
if( ( useRefDict = schema->u.schema->refdict ) != NULL ) {
DICTdo_init( useRefDict, &de );
DICTdo_init( useRefDict, &de, '*' );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
+2 -2
View File
@@ -1093,7 +1093,7 @@ LOOPpyout( struct Loop_ *loop, int level, FILE * file ) {
DictionaryEntry de;
/* TODO: if incr != 0 && ((incr > 0 && start < stop) || (incr < 0 && start > stop)): */
DICTdo_init( loop->scope->symbol_table, &de );
DICTdo_init( loop->scope->symbol_table, &de, '*' );
v = ( Variable )DICTdo( &de );
fprintf( file, "for %s in range(", v->name->symbol.name );
EXPRESSION_out( loop->scope->u.incr->init, 0 , file );
@@ -1729,7 +1729,7 @@ TYPEenum_lib_print( const Type type, FILE * f ) {
}
/* set up the dictionary info */
DICTdo_type_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
DICTdo_init( ENUM_TYPEget_items( type ), &de, OBJ_ENUM );
while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) {
if( is_python_keyword( EXPget_name( expr ) ) ) {
fprintf( f, "%s_ ", EXPget_name( expr ) );
+2 -2
View File
@@ -232,7 +232,7 @@ getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) {
"// predetermined way to access to the handle.\n" );
fprintf( schema_cc,
"\nSCLP23(Model_contents_ptr) GetModelContents(char *schemaName)\n{\n" );
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
schema = ( Scope )DICTdo( &de );
fprintf( schema_cc,
" if(!strcmp(schemaName, \"%s\"))\n",
@@ -285,7 +285,7 @@ EXPRESSPrint( Express express, FILES * files ) {
}
/********** do all schemas ***********/
DICTdo_init( express->symbol_table, &de );
DICTdo_init( express->symbol_table, &de, '*' );
while( 0 != ( schema = ( Scope )DICTdo( &de ) ) ) {
SCOPEPrint( schema, files, schema );
}
+7 -7
View File
@@ -74,7 +74,7 @@ void print_schemas_separate( Express express, FILES * files )
/* fprintf( files->create, " Interface_spec_ptr is;\n Used_item_ptr ui;\n Referenced_item_ptr ri;\n Uniqueness_rule_ptr ur;\n Where_rule_ptr wr;\n Global_rule_ptr gr;\n" ); */
while( !complete ) {
complete = TRUE;
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
if( schema->search_id == UNPROCESSED ) {
/* i.e., if the schema has more ents/types to process in it */
@@ -117,7 +117,7 @@ void print_schemas_separate( Express express, FILES * files )
}
/*
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
//fprintf( files->create,
// "\t//////////////// USE statements\n" );
@@ -131,7 +131,7 @@ void print_schemas_separate( Express express, FILES * files )
/* Before closing, we have three more situations to deal with (i.e., three
// types of declarations etc. which could only be printed at the end).
// Each is explained in the header section of its respective function. */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
/* (These two tasks are totally unrelated but are done in the same loop
// for efficiency.) */
@@ -139,7 +139,7 @@ void print_schemas_separate( Express express, FILES * files )
}
/* Third situation: (Must be dealt with after first, see header comments
// of addAggrTypedefs.) */
DICTdo_type_init( express->symbol_table, &de, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de ) ) != 0 ) {
/* addAggrTypedefs( schema, files->classes ); */
addAggrTypedefs( schema );
@@ -172,7 +172,7 @@ static void initializeMarks( Express express ) {
DictionaryEntry de_sch, de_ent, de_type;
Schema schema;
DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
DICTdo_init( express->symbol_table, &de_sch, OBJ_SCHEMA );
while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) {
schema->search_id = UNPROCESSED;
schema->clientData = ( int * )malloc( sizeof( int ) );
@@ -627,7 +627,7 @@ static void addUseRefNames( Schema schema, FILE * create )
static int firsttime = TRUE;
if( ( useRefDict = schema->u.schema->usedict ) != NULL ) {
DICTdo_init( useRefDict, &de );
DICTdo_init( useRefDict, &de, '*' );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
@@ -657,7 +657,7 @@ static void addUseRefNames( Schema schema, FILE * create )
}
}
if( ( useRefDict = schema->u.schema->refdict ) != NULL ) {
DICTdo_init( useRefDict, &de );
DICTdo_init( useRefDict, &de, '*' );
while( ( rnm = ( Rename * )DICTdo( &de ) ) != 0 ) {
oldnm = ( ( Scope )rnm->object )->symbol.name;
if( ( strcmp( oldnm, rnm->nnew->name ) ) ) {
+1 -1
View File
@@ -15,7 +15,7 @@ void EXPRESSout( Express e ) {
exppp_init();
DICTdo_init( e->symbol_table, &de );
DICTdo_init( e->symbol_table, &de, '*' );
while( 0 != ( s = ( Schema )DICTdo( &de ) ) ) {
( void ) SCHEMAout( s );
}
+1 -1
View File
@@ -21,7 +21,7 @@ void LOOPout( struct Loop_ *loop, int level ) {
if( loop->scope ) {
DictionaryEntry de;
DICTdo_init( loop->scope->symbol_table, &de );
DICTdo_init( loop->scope->symbol_table, &de, '*' );
v = ( Variable )DICTdo( &de );
wrap( " %s := ", v->name->symbol.name );
EXPR_out( loop->scope->u.incr->init, 0 );
+2 -2
View File
@@ -26,7 +26,7 @@ void REFout( Dictionary refdict, Linked_List reflist, char * type, int level ) {
/* sort each list by schema */
/* step 1: for each entry, store it in a schema-specific list */
DICTdo_init( refdict, &de );
DICTdo_init( refdict, &de, '*' );
while( 0 != ( ren = ( struct Rename * )DICTdo( &de ) ) ) {
Linked_List nameList;
@@ -41,7 +41,7 @@ void REFout( Dictionary refdict, Linked_List reflist, char * type, int level ) {
/* step 2: for each list, print out the renames */
level = 6; /* no special reason, feels good */
indent2 = level + exppp_continuation_indent;
DICTdo_init( dict, &de );
DICTdo_init( dict, &de, '*' );
while( 0 != ( list = ( Linked_List )DICTdo( &de ) ) ) {
bool first_time = true;
LISTdo( list, r, struct Rename * ) {
+15 -15
View File
@@ -47,14 +47,14 @@ void SCOPErules_out( Scope s, int level ) {
DictionaryEntry de;
if( exppp_alphabetize == false ) {
DICTdo_type_init( s->symbol_table, &de, OBJ_RULE );
DICTdo_init( s->symbol_table, &de, OBJ_RULE );
while( 0 != ( r = ( Rule )DICTdo( &de ) ) ) {
RULE_out( r, level );
}
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( s->symbol_table, &de, OBJ_RULE );
DICTdo_init( s->symbol_table, &de, OBJ_RULE );
while( 0 != ( r = ( Rule )DICTdo( &de ) ) ) {
SCOPEadd_inorder( alpha, r );
}
@@ -74,14 +74,14 @@ void SCOPEfuncs_out( Scope s, int level ) {
DictionaryEntry de;
if( exppp_alphabetize == false ) {
DICTdo_type_init( s->symbol_table, &de, OBJ_FUNCTION );
DICTdo_init( s->symbol_table, &de, OBJ_FUNCTION );
while( 0 != ( f = ( Function )DICTdo( &de ) ) ) {
FUNC_out( f, level );
}
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( s->symbol_table, &de, OBJ_FUNCTION );
DICTdo_init( s->symbol_table, &de, OBJ_FUNCTION );
while( 0 != ( f = ( Function )DICTdo( &de ) ) ) {
SCOPEadd_inorder( alpha, f );
}
@@ -101,14 +101,14 @@ void SCOPEprocs_out( Scope s, int level ) {
DictionaryEntry de;
if( exppp_alphabetize == false ) {
DICTdo_type_init( s->symbol_table, &de, OBJ_PROCEDURE );
DICTdo_init( s->symbol_table, &de, OBJ_PROCEDURE );
while( 0 != ( p = ( Procedure )DICTdo( &de ) ) ) {
PROC_out( p, level );
}
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( s->symbol_table, &de, OBJ_PROCEDURE );
DICTdo_init( s->symbol_table, &de, OBJ_PROCEDURE );
while( 0 != ( p = ( Procedure )DICTdo( &de ) ) ) {
SCOPEadd_inorder( alpha, p );
}
@@ -188,7 +188,7 @@ void SCOPEconsts_out( Scope s, int level ) {
Dictionary d = s->symbol_table;
/* checks length of constant names */
DICTdo_type_init( d, &de, OBJ_VARIABLE );
DICTdo_init( d, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
if( !v->flags.constant ) {
continue;
@@ -215,7 +215,7 @@ void SCOPEconsts_out( Scope s, int level ) {
indent2 = level + max_indent + strlen( ": ab" ) + exppp_continuation_indent;
if( !exppp_alphabetize ) {
DICTdo_type_init( d, &de, OBJ_VARIABLE );
DICTdo_init( d, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
if( !v->flags.constant ) {
continue;
@@ -225,7 +225,7 @@ void SCOPEconsts_out( Scope s, int level ) {
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( d, &de, OBJ_VARIABLE );
DICTdo_init( d, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
if( !v->flags.constant ) {
continue;
@@ -258,7 +258,7 @@ void SCOPElocals_out( Scope s, int level ) {
size_t max_indent = 0;
Dictionary d = s->symbol_table;
DICTdo_type_init( d, &de, OBJ_VARIABLE );
DICTdo_init( d, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
if( v->flags.constant ) {
continue;
@@ -280,7 +280,7 @@ void SCOPElocals_out( Scope s, int level ) {
raw( "%*sLOCAL\n", level, "" );
indent2 = level + max_indent + strlen( ": " ) + exppp_continuation_indent;
DICTdo_type_init( d, &de, OBJ_VARIABLE );
DICTdo_init( d, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
if( v->flags.constant ) {
continue;
@@ -325,14 +325,14 @@ void SCOPEentities_out( Scope s, int level ) {
DictionaryEntry de;
if( exppp_alphabetize == false ) {
DICTdo_type_init( s->symbol_table, &de, OBJ_ENTITY );
DICTdo_init( s->symbol_table, &de, OBJ_ENTITY );
while( 0 != ( e = ( Entity )DICTdo( &de ) ) ) {
ENTITY_out( e, level );
}
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( s->symbol_table, &de, OBJ_ENTITY );
DICTdo_init( s->symbol_table, &de, OBJ_ENTITY );
while( 0 != ( e = ( Entity )DICTdo( &de ) ) ) {
SCOPEadd_inorder( alpha, e );
}
@@ -351,14 +351,14 @@ void SCOPEtypes_out( Scope s, int level ) {
Type t;
if( exppp_alphabetize == false ) {
DICTdo_type_init( s->symbol_table, &de, OBJ_TYPE );
DICTdo_init( s->symbol_table, &de, OBJ_TYPE );
while( 0 != ( t = ( Type )DICTdo( &de ) ) ) {
TYPE_out( t, level );
}
} else {
Linked_List alpha = LISTcreate();
DICTdo_type_init( s->symbol_table, &de, OBJ_TYPE );
DICTdo_init( s->symbol_table, &de, OBJ_TYPE );
while( 0 != ( t = ( Type )DICTdo( &de ) ) ) {
SCOPEadd_inorder( alpha, t );
}
+2 -2
View File
@@ -147,12 +147,12 @@ void TYPE_body_out( Type t, int level ) {
* to a temporary array. This is trivial since all buckets
* will get filled with one and only one object.
*/
DICTdo_type_init( t->symbol_table, &de, OBJ_EXPRESSION );
DICTdo_init( t->symbol_table, &de, OBJ_EXPRESSION );
while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) {
count++;
}
names = ( char ** )sc_malloc( count * sizeof( char * ) );
DICTdo_type_init( t->symbol_table, &de, OBJ_EXPRESSION );
DICTdo_init( t->symbol_table, &de, OBJ_EXPRESSION );
while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) {
names[expr->u.integer - 1] = expr->symbol.name;
}
+16 -11
View File
@@ -2,6 +2,7 @@ include_directories(
${CMAKE_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}
${SC_SOURCE_DIR}/src/base
${SC_SOURCE_DIR}/src/auxlib
)
# Set up the information we need to feed the generated source management
@@ -40,16 +41,19 @@ add_custom_target(express_verify DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/express_ver
# Depending on whether we're using pre-generated sources or building them on
# the fly, set up targets and source lists.
if(SC_GENERATE_LP_SOURCES)
LEMON_TARGET(ExpParser expparse.y)
PERPLEX_TARGET(ExpScanner expscan.l)
ADD_PERPLEX_LEMON_DEPENDENCY(ExpScanner ExpParser)
LEMON_TARGET(ExpParser expparse.y expparse.c
COMPILE_FLAGS "-p -c"
DEFINES_FILE "expparse.h")
RE2C_TARGET(ExpScanner expscan.l expscan.c
COMPILE_FLAGS "-W -Wno-match-empty-string -r -c --tags"
DEFINES_FILE "expscan.h")
ADD_RE2C_LEMON_DEPENDENCY(ExpScanner ExpParser)
add_library(objlib_expscan_c OBJECT ${PERPLEX_ExpScanner_SRC})
add_library(objlib_expscan_c OBJECT ${RE2C_ExpScanner_OUTPUTS})
set_property(TARGET objlib_expscan_c PROPERTY POSITION_INDEPENDENT_CODE ON)
add_library(objlib_expparse_c OBJECT ${LEMON_ExpParser_SRC})
add_library(objlib_expparse_c OBJECT ${LEMON_ExpParser_OUTPUTS})
set_property(TARGET objlib_expparse_c PROPERTY POSITION_INDEPENDENT_CODE ON)
else(SC_GENERATE_LP_SOURCES)
add_subdirectory(generated)
include_directories(generated)
@@ -68,10 +72,8 @@ set(EXPRESS_SOURCES
schema.c
resolve.c
resolve2.c
lexact.c
linklist.c
error.c
dict.c
hash.c
alloc.c
memory.c
@@ -80,6 +82,7 @@ set(EXPRESS_SOURCES
ordered_attrs.cc
info.c
factory.c
lexsupport.c
)
set(EXPRESS_OBJS)
@@ -98,11 +101,12 @@ list(APPEND EXPRESS_OBJS $<TARGET_OBJECTS:objlib_expparse_c>)
if(SC_GENERATE_LP_SOURCES)
set_property(TARGET objlib_expparse_c objlib_express_c objlib_lexact_c
APPEND PROPERTY INCLUDE_DIRECTORIES "${PERPLEX_ExpScanner_INCLUDE_DIR}")
APPEND PROPERTY INCLUDE_DIRECTORIES "${RE2C_ExpScanner_INCLUDE_DIR}")
set_property(TARGET objlib_expscan_c objlib_express_c objlib_lexact_c
APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_ExpParser_INCLUDE_DIR}")
# OBJECT libraries are not targets, and so an explicit dependency is required
set_source_files_properties(express.c lexact.c PROPERTIES OBJECT_DEPENDS "${PERPLEX_ExpScanner_HDR};${LEMON_ExpParser_HDR}")
set_source_files_properties(express.c lexact.c PROPERTIES OBJECT_DEPENDS
"${RE2C_ExpScanner_OUTPUT_HEADER};${LEMON_ExpParser_OUTPUT_HEADER}")
endif()
# TODO
@@ -122,6 +126,7 @@ set(CHECK_EXPRESS_SOURCES
SET(EXPRESS_PRIVATE_HDRS
exptoks.h
stack.h
lexsupport.h
)
variable_watch(SC_ADDLIB_EXPRESS_ARG_LINK_LIBRARIES)
@@ -162,7 +167,7 @@ if($CACHE{SC_BUILD_STATIC_LIBS})
endif()
endif()
SC_ADDEXEC(check-express SOURCES ${CHECK_EXPRESS_SOURCES} LINK_LIBRARIES express base ${SC_EXEC_NOINSTALL})
SC_ADDEXEC(check-express SOURCES ${CHECK_EXPRESS_SOURCES} LINK_LIBRARIES express base auxlib ${SC_EXEC_NOINSTALL})
if(SC_ENABLE_TESTING)
add_subdirectory(test)
+49
View File
@@ -0,0 +1,49 @@
Overview
========
I'm rewriting the parser - now using RE2C and Lemon (rather than flex/bison previously discussed).
The principle aim behind this, more than a thousand lines of Python output rewrite - blocked. I
need the parser to do more work.
Features:
LEXER P1: Comments are stripped (in theory, these could be passed to e.g. an Express text editor)
LEXER P2: Named scopes are resolved
LEXER P3: Tokens are returned, and Anonymous scopes added
PARSER: Single pass.
Tests:
* test/unitary_schemas (ok, 2 expected failures)
* data/*/*.exp (ok, no failures)
Generally, I believe there should be a more feature complete test set: Fully automated checking of
parse trees. Although I don't fully understand how this should be achieved yet.
Next steps:
1. Refactor to improve lexer actions
2. Integrate parser
3. General error handling strategy (to be discussed)
Requirements
============
RE2C - versions before 1.0 have significant bugs, I used 1.0.3 - not the version in BRL-CAD.
Lemon - I would guess any recent version would work (I haven't tested yet).
When I get a moment I'll add an equivalently named branch in the baffledCitrus repo.
Build Instructions
==================
NOTE: currently no generators are supported!
configure using cmake
EXPRESS_ONLY - set ON
GENERATORS - turn all generators OFF
DEBUG - set appropriate debug flags for your platform
TESTING - enable tests
you can check for parse errors by running check-express
./check-express some/express/file.exp
+5 -3
View File
@@ -39,6 +39,8 @@ Now you can say things like:
#include "express/alloc.h"
#include "express/error.h"
#include "sc_memmgr.h"
/* just in case we are compiling by hand */
#ifndef ALLOC
#define ALLOC
@@ -50,7 +52,7 @@ Now you can say things like:
* \param bytes new memory size
*/
Freelist * create_freelist( struct freelist_head * flh, int bytes ) {
Freelist * current = ( Freelist * )malloc( bytes );
Freelist * current = ( Freelist * )sc_malloc( bytes );
if( current == 0 ) {
return( 0 );
}
@@ -123,7 +125,7 @@ void * ALLOC_new( struct freelist_head * flh ) {
#endif
#ifdef REAL_MALLOC
return( calloc( 1, flh->size_elt ) );
return( sc_calloc( 1, flh->size_elt ) );
/*NOTREACHED*/
#else
if( flh->freelist == NULL && 0 == create_freelist( flh, flh->bytes ) ) {
@@ -156,7 +158,7 @@ void ALLOC_destroy( struct freelist_head * flh, Freelist * link ) {
#endif
#ifdef REAL_MALLOC
free( link );
sc_free( link );
return;
/*NOTREACHED*/
#else
+2 -2
View File
@@ -43,7 +43,7 @@ void DICTprint( Dictionary dict ) {
Element e;
DictionaryEntry de;
HASHlistinit( dict, &de );
HASHlistinit( dict, &de, '*' );
while( 0 != ( e = ( HASHlist( &de ) ) ) ) {
fprintf( stderr, "key <%s> data <%s> line <%d> <\"%c\" %s> <%s>\n",
@@ -113,7 +113,7 @@ int DICTdefine( Dictionary dict, char * name, void *obj, Symbol * sym, char type
* their unusual behavior with respect to scoping and visibility rules
* \sa DICTdefine()
*/
int DICT_define( Dictionary dict, char * name, void *obj, Symbol * sym, char type ) {
int DICTdefine_enum( Dictionary dict, char * name, void *obj, Symbol * sym, char type ) {
struct Element_ e, *e2;
e.key = name;
+39 -29
View File
@@ -130,7 +130,7 @@ int ENTITYdeclares_variable( Entity e, Variable v ) {
return false;
}
static Entity ENTITY_find_inherited_entity( Entity entity, char * name, int down ) {
static Entity ENTITY_find_inherited_entity( Entity entity, const char * name, int down ) {
Entity result;
/* avoid searching scopes that we've already searched */
@@ -174,7 +174,7 @@ static Entity ENTITY_find_inherited_entity( Entity entity, char * name, int down
return 0;
}
struct Scope_ * ENTITYfind_inherited_entity( struct Scope_ *entity, char * name, int down ) {
struct Scope_ * ENTITYfind_inherited_entity( struct Scope_ *entity, const char * name, int down ) {
if( !strcmp( name, entity->symbol.name ) ) {
return( entity );
}
@@ -184,8 +184,8 @@ struct Scope_ * ENTITYfind_inherited_entity( struct Scope_ *entity, char * name,
}
/** find a (possibly inherited) attribute */
Variable ENTITY_find_inherited_attribute( Entity entity, char * name, int * down, struct Symbol_ ** where ) {
Variable result;
Symbol *ENTITY_find_inherited_attribute( Entity entity, const char * name, int * down, struct Symbol_ ** where ) {
Symbol *ep;
/* avoid searching scopes that we've already searched */
/* this can happen due to several things */
@@ -198,19 +198,19 @@ Variable ENTITY_find_inherited_attribute( Entity entity, char * name, int * down
entity->search_id = __SCOPE_search_id;
/* first look locally */
result = ( Variable )DICTlookup( entity->symbol_table, name );
if( result ) {
ep = HASHsearch(entity->symbol_table, (Symbol) {.name = name}, HASH_FIND);
if (ep) {
if( down && *down && where ) {
*where = &entity->symbol;
}
return result;
return ep;
}
/* check supertypes */
LISTdo( entity->u.entity->supertypes, super, Entity )
result = ENTITY_find_inherited_attribute( super, name, down, where );
if( result ) {
return result;
ep = ENTITY_find_inherited_attribute( super, name, down, where );
if( ep ) {
return ep;
}
LISTod;
@@ -218,18 +218,18 @@ Variable ENTITY_find_inherited_attribute( Entity entity, char * name, int * down
if( down ) {
++*down;
LISTdo( entity->u.entity->subtypes, sub, Entity )
result = ENTITY_find_inherited_attribute( sub, name, down, where );
if( result ) {
return result;
ep = ENTITY_find_inherited_attribute( sub, name, down, where );
if( ep ) {
return ep;
}
LISTod;
--*down;
}
return 0;
return NULL;
}
Variable ENTITYfind_inherited_attribute( struct Scope_ *entity, char * name,
Symbol *ENTITYfind_inherited_attribute( struct Scope_ *entity, const char * name,
struct Symbol_ ** down_sym ) {
extern int __SCOPE_search_id;
int down_flag = 0;
@@ -246,6 +246,7 @@ Variable ENTITYfind_inherited_attribute( struct Scope_ *entity, char * name,
* report errors as appropriate
*/
Variable ENTITYresolve_attr_ref( Entity e, Symbol * grp_ref, Symbol * attr_ref ) {
Symbol *ep;
Entity ref_entity;
Variable attr;
struct Symbol_ *where;
@@ -257,13 +258,14 @@ Variable ENTITYresolve_attr_ref( Entity e, Symbol * grp_ref, Symbol * attr_ref )
ERRORreport_with_symbol(UNKNOWN_SUPERTYPE, grp_ref, grp_ref->name, e->symbol.name );
return 0;
}
attr = ( Variable )DICTlookup( ref_entity->symbol_table,
attr_ref->name );
if( !attr ) {
ep = HASHsearch(ref_entity->symbol_table, (Symbol) {.name = attr_ref->name}, HASH_FIND);
if (!ep) {
ERRORreport_with_symbol(UNKNOWN_ATTR_IN_ENTITY, attr_ref, attr_ref->name,
ref_entity->symbol.name );
/* resolve_failed(e);*/
return 0;
}
attr = ep->data;
} else {
/* no entity provided, look through supertype chain */
where = NULL;
@@ -301,18 +303,21 @@ void ENTITYinitialize() {
** Add an attribute to an entity.
*/
void ENTITYadd_attribute( Entity entity, Variable attr ) {
int rc;
Symbol e, *ep;
memcpy(&e, &attr->name->symbol, sizeof(Symbol));
e.data = attr;
e.type = OBJ_VARIABLE;
if( attr->name->type->u.type->body->type != op_ ) {
/* simple id */
rc = DICTdefine( entity->symbol_table, attr->name->symbol.name,
attr, &attr->name->symbol, OBJ_VARIABLE );
ep = HASHsearch(entity->symbol_table, e, HASH_INSERT);
} else {
/* SELF\ENTITY.SIMPLE_ID */
rc = DICTdefine( entity->symbol_table, attr->name->e.op2->symbol.name,
attr, &attr->name->symbol, OBJ_VARIABLE );
e.name = attr->name->e.op2->symbol.name;
ep = HASHsearch( entity->symbol_table, e, HASH_INSERT);
}
if( rc == 0 ) {
if( !ep ) {
LISTadd_last( entity->u.entity->attributes, attr );
VARput_offset( attr, entity->u.entity->attribute_count );
entity->u.entity->attribute_count++;
@@ -403,7 +408,7 @@ Linked_List ENTITYget_all_attributes( Entity entity ) {
** \note If the entity has no attribute with the given name,
** VARIABLE_NULL is returned.
*/
Variable ENTITYget_named_attribute( Entity entity, char * name ) {
Variable ENTITYget_named_attribute( Entity entity, const char * name ) {
Variable attribute;
LISTdo( entity->u.entity->attributes, attr, Variable )
@@ -460,14 +465,19 @@ int ENTITYget_attribute_offset( Entity entity, Variable attribute ) {
** \note If the entity has no attribute with the given name,
** -1 is returned.
*/
int ENTITYget_named_attribute_offset( Entity entity, char * name ) {
int ENTITYget_named_attribute_offset( Entity entity, const char * name ) {
int offset;
int value;
Symbol *ep;
LISTdo( entity->u.entity->attributes, attr, Variable )
if( !strcmp( VARget_simple_name( attr ), name ) )
return entity->u.entity->inheritance +
VARget_offset( ENTITY_find_inherited_attribute( entity, name, 0, 0 ) );
if (!strcmp( VARget_simple_name( attr ), name ) ) {
ep = ENTITY_find_inherited_attribute( entity, name, 0, 0 );
if (!ep)
continue;
return entity->u.entity->inheritance + VARget_offset((Variable) ep->data);
}
LISTod;
offset = 0;
LISTdo( entity->u.entity->supertypes, super, Entity )
+670 -2299
View File
File diff suppressed because it is too large Load Diff
+41 -23
View File
@@ -152,8 +152,10 @@ void EXPcleanup( void ) {
*/
static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e,
Variable * v, char * dt, struct Symbol_ ** where, int s_id ) {
Symbol *ep;
Expression item;
Variable tmp;
Linked_List supert, subt, uniqSubs;
int options = 0;
struct Symbol_ *w = NULL;
@@ -170,15 +172,15 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e
*where = w;
}
*v = tmp;
*dt = DICT_type;
*dt = OBJ_VARIABLE;
return 1;
} else {
return 0;
}
case select_: {
Linked_List supert = LISTcreate();
Linked_List subt = LISTcreate();
Linked_List uniqSubs = LISTcreate();
case select_:
supert = LISTcreate();
subt = LISTcreate();
uniqSubs = LISTcreate();
selection->search_id = s_id;
LISTdo( selection->u.type->body->list, t, Type ) {
int nr = EXP_resolve_op_dot_fuzzy( t, sref, e, v, dt, &w, s_id );
@@ -224,13 +226,15 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e
LISTfree( subt );
LISTfree( uniqSubs );
return options;
}
case enumeration_:
item = ( Expression )DICTlookup( TYPEget_enum_tags( selection ), sref.name );
if( item ) {
ep = HASHsearch(TYPEget_enum_tags( selection ), (Symbol) {.name = sref.name}, HASH_FIND);
if (ep) {
item = ep->data;
*e = item;
*dt = DICT_type;
*dt = OBJ_ENUM;
return 1;
} else {
return 0;
}
default:
return 0;
@@ -238,6 +242,7 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e
}
Type EXPresolve_op_dot( Expression expr, Scope scope ) {
Symbol *ep;
Expression op1 = expr->e.op1;
Expression op2 = expr->e.op2;
Variable v = 0;
@@ -318,7 +323,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
fprintf( stderr, "EXPresolved_op_dot: attribute not an attribute?\n" );
ERRORabort( 0 );
}
break;
default:
/* compile-time ambiguous */
if( where ) {
@@ -337,10 +342,12 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
resolve_failed( expr );
return( Type_Bad );
}
/* TODO: now checked in parser?
if( DICT_type != OBJ_VARIABLE ) {
fprintf( stderr, "EXPresolved_op_dot: attribute not an attribute?\n" );
ERRORabort( 0 );
}
*/
op2->u.variable = v;
op2->return_type = v->type;
@@ -357,9 +364,11 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
resolve_failed( expr );
return( Type_Bad );
}
/* TODO: now checked in parser?
if( DICT_type != OBJ_VARIABLE ) {
fprintf( stderr, "ERROR: EXPresolved_op_dot: attribute not an attribute?\n" );
}
*/
op2->u.variable = v;
/* changed to set return_type */
@@ -369,14 +378,16 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
case enumeration_:
/* enumerations within a select will be handled by `case select_` above,
* which calls EXP_resolve_op_dot_fuzzy(). */
item = ( Expression )DICTlookup( TYPEget_enum_tags( op1type ), op2->symbol.name );
if( !item ) {
ep = HASHsearch(TYPEget_enum_tags( op1type ), (Symbol) { .name = op2->symbol.name }, HASH_FIND);
if (!ep) {
ERRORreport_with_symbol(ENUM_NO_SUCH_ITEM, &op2->symbol,
op1type->symbol.name, op2->symbol.name );
resolve_failed( expr );
return( Type_Bad );
}
/* TODO: ep->data, ep->type? */
item = ep->data;
op2->u.expression = item;
op2->return_type = item->type;
resolved_all( expr );
@@ -600,17 +611,24 @@ Type EXPresolve_op_relational( Expression e, Scope s ) {
void EXPresolve_op_default( Expression e, Scope s ) {
int failed = 0;
switch( OPget_number_of_operands( e->e.op_code ) ) {
case 3:
EXPresolve( e->e.op3, s, Type_Dont_Care );
failed = is_resolve_failed( e->e.op3 );
case 2:
EXPresolve( e->e.op2, s, Type_Dont_Care );
failed |= is_resolve_failed( e->e.op2 );
int nargs = OPget_number_of_operands( e->e.op_code );
if (nargs == 3) {
EXPresolve( e->e.op3, s, Type_Dont_Care );
failed = is_resolve_failed( e->e.op3 );
}
EXPresolve( e->e.op1, s, Type_Dont_Care );
if( failed || is_resolve_failed( e->e.op1 ) ) {
if (nargs >= 2) {
EXPresolve( e->e.op2, s, Type_Dont_Care );
failed |= is_resolve_failed( e->e.op2 );
}
if (1) { /* (nargs >= 1) */
EXPresolve( e->e.op1, s, Type_Dont_Care );
failed |= is_resolve_failed( e->e.op1 );
}
if (failed) {
resolve_failed( e );
} else {
resolved_all( e );
+140 -67
View File
@@ -74,23 +74,28 @@
#include <errno.h>
#include "sc_memmgr.h"
#include "express/memory.h"
#include "express/hash.h"
#include "express/basic.h"
#include "express/express.h"
#include "express/resolve.h"
#include "express/factory.h"
#include "stack.h"
#include "express/scope.h"
#include "express/exp_kw.h"
#include "stack.h"
#include "token_type.h"
#include "lexsupport.h"
#include "expparse.h"
#include "expscan.h"
#include "parse_data.h"
#include "express/lexact.h"
#if 0
void * ParseAlloc( void * ( *mallocProc )( size_t ) );
void ParseFree( void * parser, void ( *freeProc )( void * ) );
void Parse( void * parser, int tokenID, YYSTYPE data, parse_data_t parseData );
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
#endif
Linked_List EXPRESS_path;
int EXPRESSpass;
@@ -108,13 +113,14 @@ bool EXPRESSignore_duplicate_schemas = false;
Function funcdef(char *name, int pcount, Type ret_typ);
void procdef(char *name, int pcount);
void BUILTINSinitialize();
Dictionary EXPRESSbuiltins; /* procedures/functions */
Hash_Table EXPRESSbuiltins; /* procedures/functions */
struct Scope_ * FUNC_NVL;
struct Scope_ * FUNC_USEDIN;
#if 0
extern Express yyexpresult;
#endif
extern Linked_List PARSEnew_schemas;
void SCOPEinitialize( void );
@@ -255,7 +261,6 @@ void EXPRESSinitialize( void ) {
ERRORinitialize();
HASHinitialize(); /* comes first - used by just about everything else! */
DICTinitialize();
LISTinitialize(); /* ditto */
STACKinitialize();
PASSinitialize();
@@ -278,8 +283,6 @@ void EXPRESSinitialize( void ) {
/* LOOP_CTLinitialize();*/
STMTinitialize();
SCANinitialize();
BUILTINSinitialize();
EXPRESS_PATHinit(); /* note, must follow defn of errors it needs! */
@@ -289,12 +292,10 @@ void EXPRESSinitialize( void ) {
void EXPRESScleanup( void ) {
EXPRESS_PATHfree();
DICTcleanup();
ERRORcleanup();
RESOLVEcleanup();
TYPEcleanup();
EXPcleanup();
SCANcleanup();
LISTcleanup();
}
@@ -304,8 +305,10 @@ void EXPRESScleanup( void ) {
** Parse an Express source file into the Working Form.
*/
void EXPRESSparse( Express model, FILE * fp, char * filename ) {
#if 0
yyexpresult = model;
#endif
if( !fp ) {
fp = fopen( filename, "r" );
}
@@ -340,12 +343,12 @@ void EXPRESSparse( Express model, FILE * fp, char * filename ) {
}
model->u.express->basename = ( char * )sc_malloc( length + 1 );
memcpy( model->u.express->basename, filename, length );
memcpy( model->u.express->basename, start, length );
model->u.express->basename[length] = '\0';
/* get new copy of filename to avoid being smashed */
/* by subsequent lookups on EXPRESS_path */
model->u.express->filename = SCANstrdup( filename );
model->u.express->filename = strdup( filename );
filename = model->u.express->filename;
}
@@ -353,6 +356,57 @@ void EXPRESSparse( Express model, FILE * fp, char * filename ) {
PARSERrun( filename, model->u.express->file = fp );
}
static Express PARSERrun( char * filename, FILE * fp ) {
int tok;
struct YYSTYPE yylval;
struct YYSTATE *pState;
void *pParser, *pScanner;
pScanner = yylexAlloc();
pState = yystateAlloc();
pParser = yyparseAlloc(sc_malloc);
if( print_objects_while_running & OBJ_PASS_BITS ) {
fprintf( stderr, "parse (pass %d)\n", EXPRESSpass );
}
if( print_objects_while_running & OBJ_SCHEMA_BITS ) {
fprintf( stderr, "parse: %s (schema file)\n", filename );
}
yylexInit(pScanner, pState, fp);
yyparseTrace(stderr, "dbg: ");
while ((tok = yylex(pScanner, &yylval))) {
yyparse(pParser, tok, &yylval, pState);
}
yyparse(pParser, 0, &yylval, pState);
#if 0
/* want 0 on success, 1 on invalid input, 2 on memory exhaustion */
if( yyerrstatus != 0 ) {
fprintf( stderr, ">> Bailing! (yyerrstatus = %d)\n", yyerrstatus );
ERRORreport( ERROR_bail_out );
/* free model and model->u.express */
return 0;
}
EXPRESSpass = 1;
#endif
/* TODO: yylexFree(pScanner) */
yyparseFree(pParser, sc_free);
/*
yylexFree(pScanner);
yystateFree(pState);
*/
#if 0
return yyexpresult;
#endif
}
#if 0
/* TODO LEMON ought to put this in expparse.h */
void parserInitState();
@@ -364,7 +418,7 @@ static Express PARSERrun( char * filename, FILE * fp ) {
int tokenID;
parse_data_t parseData;
void * parser = ParseAlloc( malloc );
void * parser = ParseAlloc( sc_malloc );
perplex_t scanner = perplexFileScanner( fp );
parseData.scanner = scanner;
@@ -397,10 +451,11 @@ static Express PARSERrun( char * filename, FILE * fp ) {
EXPRESSpass = 1;
perplexFree( scanner );
ParseFree( parser, free );
ParseFree( parser, sc_free );
return yyexpresult;
}
#endif
/**
* find the final object to which a rename points
@@ -409,52 +464,50 @@ static Express PARSERrun( char * filename, FILE * fp ) {
*
* Sept 2013 - remove unused param enum rename_type type (TODO should this be used)?
*/
static void * SCOPEfind_for_rename( Scope schema, char * name ) {
void *result;
Rename * rename;
static Symbol *SCOPEfind_for_rename( Scope schema, const char * name ) {
Symbol *ep;
/* object can only appear in top level symbol table */
/* OR in another rename clause */
result = DICTlookup( schema->symbol_table, name );
if( result ) {
return result;
ep = HASHsearch(schema->symbol_table, (Symbol) {.name = name}, HASH_FIND);
if( ep ) {
return ep;
}
/* Occurs in a fully USE'd schema? */
LISTdo( schema->u.schema->use_schemas, use_schema, Schema ) {
/* follow chain'd USEs */
result = SCOPEfind_for_rename( use_schema, name );
if( result ) {
return( result );
ep = SCOPEfind_for_rename( use_schema, name );
if (ep) {
return ep;
}
} LISTod;
/* Occurs in a partially USE'd schema? */
rename = ( Rename * )DICTlookup( schema->u.schema->usedict, name );
if( rename ) {
RENAMEresolve( rename, schema );
DICT_type = rename->type;
return( rename->object );
ep = HASHsearch(schema->u.schema->usedict, (Symbol) {.name = name}, HASH_FIND);
if( ep ) {
RENAMEresolve( ep->data, schema );
return ep;
}
LISTdo( schema->u.schema->uselist, r, Rename * )
if( !strcmp( ( r->nnew ? r->nnew : r->old )->name, name ) ) {
RENAMEresolve( r, schema );
DICT_type = r->type;
return( r->object );
ep = SCOPEfind_for_rename( r->schema, r->old->name );
if (ep) {
return ep;
}
}
LISTod;
/* we are searching for an object to be interfaced from this schema. */
/* therefore, we *never* want to look at things which are REFERENCE'd */
/* *into* the current schema. -snc */
return 0;
return NULL;
}
void RENAMEresolve( Rename * r, Schema s ) {
void *remote;
Symbol *remote;
/* if (is_resolved_rename_raw(r->old)) return;*/
if( r->object ) {
@@ -474,13 +527,13 @@ void RENAMEresolve( Rename * r, Schema s ) {
resolve_in_progress_raw( r->old );
remote = SCOPEfind_for_rename( r->schema, r->old->name );
if( remote == 0 ) {
if (!remote) {
ERRORreport_with_symbol( REF_NONEXISTENT, r->old,
r->old->name, r->schema->symbol.name );
resolve_failed_raw( r->old );
} else {
r->object = remote;
r->type = DICT_type;
r->object = remote->data;
r->type = remote->type;
switch( r->rename_type ) {
case use:
SCHEMAdefine_use( s, r );
@@ -496,30 +549,35 @@ void RENAMEresolve( Rename * r, Schema s ) {
#ifdef using_enum_items_is_a_pain
static void RENAMEresolve_enum( Type t, Schema s ) {
DictionaryEntry de;
Hash_Iterator it;
Symbol *ep;
Expression x;
DICTdo_type_init( t->symbol_table, &de, OBJ_EXPRESSION );
while( 0 != ( x = ( Expression )DICTdo( &de ) ) ) {
HASHdo_init( t->symbol_table, &it, OBJ_EXPRESSION );
while( (ep = HASHdo( &it )) ) {
x = ep->data;
/* TODO: if this isn't required, should we delete it? */
/* SCHEMAadd_use(s, v*/
/* raw(x->symbol.name);*/
}
}
#endif
Schema EXPRESSfind_schema( Dictionary modeldict, char * name ) {
Schema EXPRESSfind_schema( Hash_Table modeldict, const char *name ) {
Symbol *ep;
Schema s;
FILE * fp;
char * src, *dest;
char lower[MAX_SCHEMA_FILENAME_SIZE]; /* avoid lowerizing original */
const char *src;
char lower[MAX_SCHEMA_FILENAME_SIZE], *dest;
if( print_objects_while_running & OBJ_SCHEMA_BITS ) {
fprintf( stderr, "pass %d: %s (schema reference)\n",
EXPRESSpass, name );
}
s = ( Schema )DICTlookup( modeldict, name );
if( s ) {
ep = HASHsearch(modeldict, (Symbol) {.name = name}, HASH_FIND);
if (ep) {
s = ep->data;
return s;
}
@@ -545,12 +603,12 @@ Schema EXPRESSfind_schema( Dictionary modeldict, char * name ) {
EXPRESSpass, dir->full );
}
express = PARSERrun( SCANstrdup( dir->full ), fp );
express = PARSERrun( strdup( dir->full ), fp );
if( express ) {
s = ( Schema )DICTlookup( modeldict, name );
}
if( s ) {
return s;
ep = HASHsearch(modeldict, (Symbol) {.name = name}, HASH_FIND);
if( ep ) {
return ep->data;
}
}
ERRORreport( SCHEMA_NOT_IN_OWN_SCHEMA_FILE,
name, dir->full );
@@ -571,7 +629,7 @@ Schema EXPRESSfind_schema( Dictionary modeldict, char * name ) {
* because of partial schema references
* \sa connect_schema_lists()
*/
static void connect_lists( Dictionary modeldict, Schema schema, Linked_List list ) {
static void connect_lists( Hash_Table modeldict, Schema schema, Linked_List list ) {
Rename * r;
/* translate symbols to schemas */
@@ -592,7 +650,7 @@ static void connect_lists( Dictionary modeldict, Schema schema, Linked_List list
* same as `connect_lists` except for full schemas
* \sa connect_lists()
*/
static void connect_schema_lists( Dictionary modeldict, Schema schema, Linked_List schema_list ) {
static void connect_schema_lists( Hash_Table modeldict, Schema schema, Linked_List schema_list ) {
Symbol * sym;
Schema ref_schema;
@@ -620,8 +678,10 @@ void EXPRESSresolve( Express model ) {
/* comes first - DEL */
Schema schema;
DictionaryEntry de;
Hash_Iterator it;
Symbol *ep;
/* TODO: do we really need to use setjmp? */
jmp_buf env;
if( setjmp( env ) ) {
return;
@@ -668,8 +728,10 @@ void EXPRESSresolve( Express model ) {
}
/* connect the object in each rename clause to the real object */
DICTdo_type_init( model->symbol_table, &de, OBJ_SCHEMA );
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
HASHdo_init( model->symbol_table, &it, OBJ_SCHEMA );
while( (ep = HASHdo(&it)) ) {
schema = ep->data;
if( is_not_resolvable( schema ) ) {
continue;
}
@@ -703,8 +765,10 @@ void EXPRESSresolve( Express model ) {
fprintf( stderr, "pass %d: resolving sub and supertypes\n", EXPRESSpass );
}
DICTdo_type_init( model->symbol_table, &de, OBJ_SCHEMA );
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
HASHdo_init( model->symbol_table, &it, OBJ_SCHEMA );
while( (ep = HASHdo(&it)) ) {
schema = ep->data;
if( is_not_resolvable( schema ) ) {
continue;
}
@@ -734,8 +798,10 @@ void EXPRESSresolve( Express model ) {
fprintf( stderr, "pass %d: resolving implied USE's\n", EXPRESSpass );
}
DICTdo_type_init( model->symbol_table, &de, OBJ_SCHEMA );
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
HASHdo_init( model->symbol_table, &it, OBJ_SCHEMA );
while( (ep = HASHdo(&it)) ) {
schema = ep->data;
if( is_not_resolvable( schema ) ) {
continue;
}
@@ -746,8 +812,11 @@ void EXPRESSresolve( Express model ) {
}
if( schema->u.schema->usedict ) {
DICTdo_init( schema->u.schema->usedict, &fg )
while( 0 != ( r = ( Rename )DICTdo( &fg ) ) ) {
Hash_Iterator iv;
HASHdo_init( schema->u.schema->usedict, &iv, OBJ_ANY )
while( (ep = HASHdo( &iv )) ) {
r = ep->data;
if( ( r->type = OBJ_TYPE ) && ( ( Type )r->object )->body &&
TYPEis_enumeration( ( Type )r->object ) ) {
RENAMEresolve_enum( ( Type )r->object, schema );
@@ -771,12 +840,16 @@ void EXPRESSresolve( Express model ) {
}
/* mark everything resolved if possible */
DICTdo_init( model->symbol_table, &de );
while( 0 != ( schema = ( Schema )DICTdo( &de ) ) ) {
#if 0
HASHdo_init( model->symbol_table, &it, '*' );
while( (ep = HASHdo( &it ) ) ) {
schema = it->data;
if( is_resolvable( schema ) ) {
resolved_all( schema );
}
}
#endif
}
Function funcdef(char *name, int pcount, Type ret_typ) {
@@ -786,7 +859,7 @@ Function funcdef(char *name, int pcount, Type ret_typ) {
f->u.func->return_type = ret_typ;
f->u.func->builtin = true;
resolved_all(f);
DICTdefine(EXPRESSbuiltins, name, f, 0, OBJ_FUNCTION);
HASHsearch(EXPRESSbuiltins, (Symbol) {.name = name, .data = f, .type = OBJ_FUNCTION}, HASH_INSERT);
return f;
}
@@ -796,11 +869,11 @@ void procdef(char *name, int pcount) {
p->u.proc->pcount = pcount;
p->u.proc->builtin = true;
resolved_all(p);
DICTdefine(EXPRESSbuiltins, name, p, 0, OBJ_PROCEDURE);
HASHsearch(EXPRESSbuiltins, (Symbol) {.name = name, .data = p, .type = OBJ_PROCEDURE}, HASH_INSERT);
}
void BUILTINSinitialize() {
EXPRESSbuiltins = DICTcreate( 35 );
EXPRESSbuiltins = HASHcreate();
procdef("INSERT", 3 );
procdef("REMOVE", 2 );
+823 -314
View File
File diff suppressed because it is too large Load Diff
+16 -17
View File
@@ -2,7 +2,7 @@
#include "express/type.h"
#include "express/expr.h"
#include "express/dict.h"
#include "symbol_impl.h"
/* TODO: use enum? */
Type Type_Bad;
@@ -137,14 +137,14 @@ void FACTORYinitialize() {
/** Create and return an empty scope inside a parent scope. */
Scope SCOPEcreate( char type ) {
Scope d = SCOPE_new();
d->symbol_table = DICTcreate( 50 );
d->symbol_table = HASHcreate();
d->type = type;
return d;
}
Scope SCOPEcreate_tiny( char type ) {
Scope d = SCOPE_new();
d->symbol_table = DICTcreate( 1 );
d->symbol_table = HASHcreate();
d->type = type;
return d;
}
@@ -166,7 +166,7 @@ Scope SCOPEcreate_nostab( char type ) {
/** Create and return a schema. */
Schema SCHEMAcreate( void ) {
Scope s = SCOPEcreate( OBJ_SCHEMA );
s->enum_table = DICTcreate(50);
s->enum_table = HASHcreate();
s->u.schema = SCHEMA_new();
return s;
}
@@ -174,13 +174,15 @@ Schema SCHEMAcreate( void ) {
/**
* create a type with no symbol table
*/
Type TYPEcreate_nostab( struct Symbol_ *symbol, Scope scope, char objtype ) {
Type TYPEcreate_nostab( Symbol *symbol, Scope scope, char objtype ) {
Symbol e;
Type t = SCOPEcreate_nostab( OBJ_TYPE );
TypeHead th = TYPEHEAD_new();
t->u.type = th;
t->symbol = *symbol;
DICTdefine( scope->symbol_table, symbol->name, t, &t->symbol, objtype );
e = (Symbol) {.name = symbol->name, .data = t, .type = objtype};
HASHsearch( scope->symbol_table, e, HASH_INSERT );
return t;
}
@@ -212,7 +214,6 @@ Type TYPEcreate_from_body_anonymously( TypeBody tb ) {
t->u.type = th;
t->u.type->body = tb;
t->symbol.name = 0;
SYMBOLset( t );
return t;
}
@@ -222,16 +223,14 @@ TypeBody TYPEBODYcreate( enum type_enum type ) {
return tb;
}
Symbol * SYMBOLcreate( char * name, int line, const char * filename ) {
Symbol *SYMBOLcreate(char * name, int type, int ref_tok, int line, const char * filename) {
Symbol * sym = SYMBOL_new();
sym->name = name;
sym->type = type;
sym->ref_tok = ref_tok;
sym->line = line;
sym->filename = filename; /* NOTE this used the global 'current_filename',
* instead of 'filename'. This func is only
* called in two places, and both calls use
* 'current_filename'. Changed this to avoid
* potential future headaches. (MAP, Jan 12)
*/
sym->filename = filename;
return sym;
}
@@ -276,7 +275,6 @@ Variable VARcreate( Expression name, Type type ) {
Expression EXPcreate( Type type ) {
Expression e;
e = EXP_new();
SYMBOLset( e );
e->type = type;
e->return_type = Type_Unknown;
return( e );
@@ -289,7 +287,6 @@ Expression EXPcreate( Type type ) {
Expression EXPcreate_simple( Type type ) {
Expression e;
e = EXP_new();
SYMBOLset( e );
e->type = e->return_type = type;
return( e );
}
@@ -366,7 +363,9 @@ Expression QUERYcreate( Symbol * local, Expression aggregate ) {
Variable v = VARcreate( e2, Type_Attribute );
DICTdefine( s->symbol_table, local->name, v, &e2->symbol, OBJ_VARIABLE );
HASHsearch( s->symbol_table,
(Symbol) {.name = local->name, .data = v, .type = OBJ_VARIABLE},
HASH_INSERT );
e->u.query = QUERY_new();
e->u.query->scope = s;
e->u.query->local = v;
File diff suppressed because it is too large Load Diff
+172 -120
View File
@@ -1,120 +1,172 @@
#define TOK_EQUAL 1
#define TOK_GREATER_EQUAL 2
#define TOK_GREATER_THAN 3
#define TOK_IN 4
#define TOK_INST_EQUAL 5
#define TOK_INST_NOT_EQUAL 6
#define TOK_LESS_EQUAL 7
#define TOK_LESS_THAN 8
#define TOK_LIKE 9
#define TOK_NOT_EQUAL 10
#define TOK_MINUS 11
#define TOK_PLUS 12
#define TOK_OR 13
#define TOK_XOR 14
#define TOK_DIV 15
#define TOK_MOD 16
#define TOK_REAL_DIV 17
#define TOK_TIMES 18
#define TOK_AND 19
#define TOK_ANDOR 20
#define TOK_CONCAT_OP 21
#define TOK_EXP 22
#define TOK_NOT 23
#define TOK_DOT 24
#define TOK_BACKSLASH 25
#define TOK_LEFT_BRACKET 26
#define TOK_LEFT_PAREN 27
#define TOK_RIGHT_PAREN 28
#define TOK_RIGHT_BRACKET 29
#define TOK_COLON 30
#define TOK_COMMA 31
#define TOK_AGGREGATE 32
#define TOK_OF 33
#define TOK_IDENTIFIER 34
#define TOK_ALIAS 35
#define TOK_FOR 36
#define TOK_END_ALIAS 37
#define TOK_ARRAY 38
#define TOK_ASSIGNMENT 39
#define TOK_BAG 40
#define TOK_BOOLEAN 41
#define TOK_INTEGER 42
#define TOK_REAL 43
#define TOK_NUMBER 44
#define TOK_LOGICAL 45
#define TOK_BINARY 46
#define TOK_STRING 47
#define TOK_BY 48
#define TOK_LEFT_CURL 49
#define TOK_RIGHT_CURL 50
#define TOK_OTHERWISE 51
#define TOK_CASE 52
#define TOK_END_CASE 53
#define TOK_BEGIN 54
#define TOK_END 55
#define TOK_PI 56
#define TOK_E 57
#define TOK_CONSTANT 58
#define TOK_END_CONSTANT 59
#define TOK_DERIVE 60
#define TOK_END_ENTITY 61
#define TOK_ENTITY 62
#define TOK_ENUMERATION 63
#define TOK_ESCAPE 64
#define TOK_SELF 65
#define TOK_OPTIONAL 66
#define TOK_VAR 67
#define TOK_END_FUNCTION 68
#define TOK_FUNCTION 69
#define TOK_BUILTIN_FUNCTION 70
#define TOK_LIST 71
#define TOK_SET 72
#define TOK_GENERIC 73
#define TOK_QUESTION_MARK 74
#define TOK_IF 75
#define TOK_THEN 76
#define TOK_END_IF 77
#define TOK_ELSE 78
#define TOK_INCLUDE 79
#define TOK_STRING_LITERAL 80
#define TOK_TO 81
#define TOK_AS 82
#define TOK_REFERENCE 83
#define TOK_FROM 84
#define TOK_USE 85
#define TOK_INVERSE 86
#define TOK_INTEGER_LITERAL 87
#define TOK_REAL_LITERAL 88
#define TOK_STRING_LITERAL_ENCODED 89
#define TOK_LOGICAL_LITERAL 90
#define TOK_BINARY_LITERAL 91
#define TOK_LOCAL 92
#define TOK_END_LOCAL 93
#define TOK_ONEOF 94
#define TOK_UNIQUE 95
#define TOK_FIXED 96
#define TOK_END_PROCEDURE 97
#define TOK_PROCEDURE 98
#define TOK_BUILTIN_PROCEDURE 99
#define TOK_QUERY 100
#define TOK_ALL_IN 101
#define TOK_SUCH_THAT 102
#define TOK_REPEAT 103
#define TOK_END_REPEAT 104
#define TOK_RETURN 105
#define TOK_END_RULE 106
#define TOK_RULE 107
#define TOK_END_SCHEMA 108
#define TOK_SCHEMA 109
#define TOK_SELECT 110
#define TOK_SEMICOLON 111
#define TOK_SKIP 112
#define TOK_SUBTYPE 113
#define TOK_ABSTRACT 114
#define TOK_SUPERTYPE 115
#define TOK_END_TYPE 116
#define TOK_TYPE 117
#define TOK_UNTIL 118
#define TOK_WHERE 119
#define TOK_WHILE 120
#define T_INVALID 1
#define T_DOCROOT 2
#define T_RULE_REF 3
#define T_RULE_LABEL_REF 4
#define T_EQ 5
#define T_NEQ 6
#define T_LTEQ 7
#define T_GTEQ 8
#define T_LT 9
#define T_GT 10
#define T_INST_EQ 11
#define T_INST_NEQ 12
#define T_IN 13
#define T_LIKE 14
#define T_PLUS 15
#define T_MINUS 16
#define T_OR 17
#define T_XOR 18
#define T_ANDOR 19
#define T_TIMES 20
#define T_RDIV 21
#define T_IDIV 22
#define T_MOD 23
#define T_AND 24
#define T_CONCAT 25
#define T_EXP 26
#define UNARY_OP 27
#define T_LBRKT 28
#define T_RBRKT 29
#define T_LPAREN 30
#define T_RPAREN 31
#define T_ONEOF 32
#define T_DOT 33
#define T_BACKSLASH 34
#define T_SIMPLE_ID 35
#define T_SCHEMA_REF 36
#define T_FUNCTION_REF 37
#define T_PROCEDURE_REF 38
#define T_TYPE_REF 39
#define T_ENTITY_REF 40
#define T_PARAMETER_REF 41
#define T_VARIABLE_REF 42
#define T_CONSTANT_REF 43
#define T_ENUMERATION_REF 44
#define T_SIMPLE_REF 45
#define T_ABSTRACT 46
#define T_SUPERTYPE 47
#define T_SEMICOLON 48
#define T_COMMA 49
#define T_AGGREGATE 50
#define T_OF 51
#define T_COLON 52
#define T_ALIAS 53
#define T_FOR 54
#define T_END_ALIAS 55
#define T_ARRAY 56
#define T_OPTIONAL 57
#define T_UNIQUE 58
#define T_ASSIGN 59
#define T_BAG 60
#define T_BINARY 61
#define T_BOOLEAN 62
#define T_CONST_E 63
#define T_PI 64
#define T_SELF 65
#define T_QMARK 66
#define T_ABS 67
#define T_ACOS 68
#define T_ASIN 69
#define T_ATAN 70
#define T_BLENGTH 71
#define T_COS 72
#define T_EXISTS 73
#define T_FORMAT 74
#define T_HIBOUND 75
#define T_HIINDEX 76
#define T_LENGTH 77
#define T_LOBOUND 78
#define T_LOINDEX 79
#define T_LOG 80
#define T_LOG2 81
#define T_LOG10 82
#define T_NVL 83
#define T_ODD 84
#define T_ROLESOF 85
#define T_SIN 86
#define T_SIZEOF 87
#define T_SQRT 88
#define T_TAN 89
#define T_TYPEOF 90
#define T_USEDIN 91
#define T_VALUE 92
#define T_VALUE_IN 93
#define T_VALUE_UNIQUE 94
#define T_INSERT 95
#define T_REMOVE 96
#define T_OTHERWISE 97
#define T_CASE 98
#define T_END_CASE 99
#define T_BEGIN 100
#define T_END 101
#define T_CONSTANT 102
#define T_END_CONSTANT 103
#define T_DERIVE 104
#define T_END_ENTITY 105
#define T_ENTITY 106
#define T_BASED_ON 107
#define T_WITH 108
#define T_EXTENSIBLE 109
#define T_ENUMERATION 110
#define T_ESCAPE 111
#define T_END_FUNCTION 112
#define T_FUNCTION 113
#define T_LIST 114
#define T_SET 115
#define T_GENERIC_ENTITY 116
#define T_GENERIC 117
#define T_IF 118
#define T_THEN 119
#define T_ELSE 120
#define T_END_IF 121
#define T_TO 122
#define T_BY 123
#define T_INTEGER 124
#define T_LCURL 125
#define T_RCURL 126
#define T_INVERSE 127
#define T_BINARY_LITERAL 128
#define T_INTEGER_LITERAL 129
#define T_REAL_LITERAL 130
#define T_LOCAL 131
#define T_END_LOCAL 132
#define T_FALSE 133
#define T_TRUE 134
#define T_UNKNOWN 135
#define T_LOGICAL 136
#define T_AS 137
#define T_NUMBER 138
#define T_END_PROCEDURE 139
#define T_PROCEDURE 140
#define T_VAR 141
#define T_QUERY 142
#define T_ALL_IN 143
#define T_PIPE 144
#define T_REAL 145
#define T_RENAMED 146
#define T_REFERENCE 147
#define T_FROM 148
#define T_REPEAT 149
#define T_END_REPEAT 150
#define T_RETURN 151
#define T_END_RULE 152
#define T_RULE 153
#define T_SCHEMA 154
#define T_END_SCHEMA 155
#define T_SELECT 156
#define T_NOT 157
#define T_SKIP 158
#define T_STRING_LITERAL 159
#define T_ENCODED_STRING_LITERAL 160
#define T_STRING 161
#define T_END_SUBTYPE_CONSTRAINT 162
#define T_SUBTYPE_CONSTRAINT 163
#define T_SUBTYPE 164
#define T_TOTAL_OVER 165
#define T_TYPE 166
#define T_END_TYPE 167
#define T_UNTIL 168
#define T_USE 169
#define T_WHERE 170
#define T_WHILE 171
#define T_FIXED 172
+11825 -1696
View File
File diff suppressed because it is too large Load Diff
+28 -98
View File
@@ -1,100 +1,30 @@
#ifndef PERPLEX_H
#define PERPLEX_H
/* P E R P L E X _ T E M P L A T E . C
* BRL-CAD
*
* Copyright (c) 1990-2011 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* Copyright (c) 1990 The Regents of the University of California.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Parts of this file are based on sources from the flex project.
*
* This code is derived from software contributed to Berkeley by
* Vern Paxson.
*
* The United States Government has rights in this work pursuant
* to contract no. DE-AC03-76SF00098 between the United States
* Department of Energy and the University of California.
*/
/** @file perplex_template.c
*
* template for generated scanners
*
*/
#include <stdio.h>
#include <stdlib.h>
/* Generated by re2c 1.0.3 on Sat Oct 20 22:52:46 2018 */
#line 3 "expscan.h"
#define YYEOF -1
struct Buf {
void *elts; /* elements. */
int nelts; /* number of elements. */
size_t elt_size; /* in bytes. */
int nmax; /* max capacity of elements. */
enum YYCONDTYPE {
yycP1,
yycCOMMENT,
yycP2,
yycTYPE,
yycENUM,
yycENTITY,
yycARG_LIST,
yycRULE,
yycQUERY,
yycREDECL,
yycSTMT,
yycINV_FOR_STMT,
yycP3,
yycSEARCH_SCOPE,
yycID_CUR_SCOPE,
yycID_LIST,
yycENUM_ID_LIST,
yycLABEL_OPT,
yycENUM_REF,
yycENTITY_REF,
yycDOT_ATTR,
yycCONSTANT,
yycLOCAL,
yycINV_FOR,
yycSUBTYPE_CONS,
};
/* scanner data */
typedef struct perplex {
void *extra; /* application data */
FILE *inFile;
struct Buf *buffer;
char *tokenText;
char *tokenStart;
char *cursor;
char *marker;
char *null;
int atEOI;
int condition;
} *perplex_t;
perplex_t perplexFileScanner(FILE *input);
perplex_t perplexStringScanner(char *firstChar, size_t numChars);
void perplexFree(perplex_t scanner);
void perplexUnput(perplex_t scanner, char c);
void perplexSetExtra(perplex_t scanner, void *extra);
void* perplexGetExtra(perplex_t scanner);
#ifndef PERPLEX_LEXER
#define PERPLEX_LEXER yylex
#endif
#define PERPLEX_PUBLIC_LEXER PERPLEX_LEXER(perplex_t scanner)
#define PERPLEX_PRIVATE_LEXER PERPLEX_LEXER_private(perplex_t scanner)
#ifndef PERPLEX_ON_ENTER
#define PERPLEX_ON_ENTER /* do nothing */
#endif
int PERPLEX_PUBLIC_LEXER;
#endif
@@ -1,7 +1,7 @@
# Autogenerated verification information
set(baseline_expscan_l_md5 c86358d3e57ce6916c28a63262fad6e6)
set(baseline_expparse_y_md5 3722242f16c679c40323317833757a6d)
set(baseline_expscan_c_md5 b6b239869e4c7d169107fe45f760ffa0)
set(baseline_expscan_h_md5 3052c058a37045b43f96e4c04039bce3)
set(baseline_expparse_c_md5 c170b5e39b5fe56e2c39288fbe2b48a1)
set(baseline_expparse_h_md5 e4a5599839b2a9f7a6915a0dcc7747b0)
set(baseline_expscan_l_md5 983e80b9716781e77bf9d6d90d2eed0b)
set(baseline_expparse_y_md5 1fbdffbb42b05c89fbe1e3e5081880cb)
set(baseline_expscan_c_md5 72cddc621499c41fa06662d2663d9cee)
set(baseline_expscan_h_md5 24a4cb429db89b70ea094f4dd664206b)
set(baseline_expparse_c_md5 b72e8df2237184faf6b593204041f2f0)
set(baseline_expparse_h_md5 5cdae8aec1c3e7cdaf238e436bbd43b9)
+2 -229
View File
@@ -1,229 +1,2 @@
expparse.y:2
expparse.y:124
expparse.y:2440
expparse.y:297
expparse.y:303
expparse.y:320
expparse.y:337
expparse.y:341
expparse.y:347
expparse.y:353
expparse.y:359
expparse.y:364
expparse.y:369
expparse.y:379
expparse.y:387
expparse.y:397
expparse.y:411
expparse.y:423
expparse.y:442
expparse.y:456
expparse.y:463
expparse.y:475
expparse.y:486
expparse.y:491
expparse.y:501
expparse.y:506
expparse.y:510
expparse.y:516
expparse.y:523
expparse.y:529
expparse.y:533
expparse.y:538
expparse.y:543
expparse.y:547
expparse.y:551
expparse.y:557
expparse.y:583
expparse.y:593
expparse.y:599
expparse.y:609
expparse.y:618
expparse.y:628
expparse.y:634
expparse.y:642
expparse.y:646
expparse.y:653
expparse.y:658
expparse.y:663
expparse.y:668
expparse.y:675
expparse.y:694
expparse.y:726
expparse.y:733
expparse.y:738
expparse.y:745
expparse.y:760
expparse.y:775
expparse.y:786
expparse.y:819
expparse.y:834
expparse.y:841
expparse.y:855
expparse.y:862
expparse.y:868
expparse.y:872
expparse.y:878
expparse.y:907
expparse.y:913
expparse.y:919
expparse.y:925
expparse.y:931
expparse.y:937
expparse.y:943
expparse.y:949
expparse.y:955
expparse.y:961
expparse.y:967
expparse.y:973
expparse.y:979
expparse.y:985
expparse.y:995
expparse.y:1001
expparse.y:1007
expparse.y:1013
expparse.y:1019
expparse.y:1025
expparse.y:1031
expparse.y:1037
expparse.y:1055
expparse.y:1059
expparse.y:1064
expparse.y:1087
expparse.y:1092
expparse.y:1098
expparse.y:1104
expparse.y:1129
expparse.y:1138
expparse.y:1146
expparse.y:1154
expparse.y:1159
expparse.y:1169
expparse.y:1178
expparse.y:1182
expparse.y:1188
expparse.y:1194
expparse.y:1202
expparse.y:1211
expparse.y:1224
expparse.y:1232
expparse.y:1240
expparse.y:1245
expparse.y:1253
expparse.y:1265
expparse.y:1278
expparse.y:1284
expparse.y:1292
expparse.y:1296
expparse.y:1300
expparse.y:1308
expparse.y:1313
expparse.y:1318
expparse.y:1324
expparse.y:1342
expparse.y:1346
expparse.y:1355
expparse.y:1365
expparse.y:1378
expparse.y:1384
expparse.y:1397
expparse.y:1420
expparse.y:1432
expparse.y:1437
expparse.y:1444
expparse.y:1452
expparse.y:1460
expparse.y:1487
expparse.y:1521
expparse.y:1529
expparse.y:1536
expparse.y:1548
expparse.y:1565
expparse.y:1571
expparse.y:1577
expparse.y:1583
expparse.y:1599
expparse.y:1616
expparse.y:1640
expparse.y:1646
expparse.y:1651
expparse.y:1658
expparse.y:1664
expparse.y:1681
expparse.y:1686
expparse.y:1691
expparse.y:1696
expparse.y:1707
expparse.y:1711
expparse.y:1716
expparse.y:1720
expparse.y:1730
expparse.y:1735
expparse.y:1742
expparse.y:1750
expparse.y:1760
expparse.y:1786
expparse.y:1794
expparse.y:1801
expparse.y:1810
expparse.y:1819
expparse.y:1827
expparse.y:1835
expparse.y:1842
expparse.y:1846
expparse.y:1850
expparse.y:1854
expparse.y:1858
expparse.y:1862
expparse.y:1866
expparse.y:1870
expparse.y:1878
expparse.y:1886
expparse.y:1891
expparse.y:1896
expparse.y:1907
expparse.y:1915
expparse.y:1936
expparse.y:1942
expparse.y:1949
expparse.y:1957
expparse.y:1984
expparse.y:1993
expparse.y:2012
expparse.y:2023
expparse.y:2036
expparse.y:2041
expparse.y:2090
expparse.y:2100
expparse.y:2106
expparse.y:2112
expparse.y:2118
expparse.y:2131
expparse.y:2137
expparse.y:2143
expparse.y:2149
expparse.y:2153
expparse.y:2158
expparse.y:2169
expparse.y:2175
expparse.y:2180
expparse.y:2185
expparse.y:2190
expparse.y:2215
expparse.y:2223
expparse.y:2234
expparse.y:2241
expparse.y:2284
expparse.y:2292
expparse.y:2297
expparse.y:2301
expparse.y:2328
expparse.y:2334
expparse.y:2341
expparse.y:2347
expparse.y:2362
expparse.y:2371
expparse.y:2377
expparse.y:2391
expparse.y:2396
expparse.y:2424
expparse.y:159
expparse.y:814
+410 -506
View File
@@ -1,491 +1,144 @@
/*
* Dynamic hashing, after CACM April 1988 pp 446-457, by Per-Ake Larson.
* https://cacm.acm.org/magazines/1988/4/9970-dynamic-hash-tables/abstract
*
* Coded into C, with minor code improvements, and with hsearch(3) interface,
* by ejp@ausmelb.oz, Jul 26, 1988: 13:16;
* also, hcreate/hdestroy routines added to simulate hsearch(3).
*
* move to local hash table, cleanup abstraction and storage allocation;
* convert to ANSII C.
* by snc (clark@cme.nbs.gov), 10-Mar-1989
*
* these routines simulate hsearch(3) and family, with the important
* difference that the hash table is dynamic - can grow indefinitely
* beyond its original size (as supplied to hcreate()).
*
* Performance appears to be comparable to that of hsearch(3).
* The 'source-code' options referred to in hsearch(3)'s 'man' page
* are not implemented; otherwise functionality is identical.
*
* Compilation controls:
* HASH_DEBUG controls some informative traces, mainly for debugging.
* HASH_STATISTICS causes HashAccesses and HashCollisions to be maintained;
* when combined with HASH_DEBUG, these are displayed by hdestroy().
*
* Problems & fixes to ejp@ausmelb.oz. WARNING: relies on pre-processor
* concatenation property, in probably unnecessary code 'optimisation'.
*
* snc: fixed concatenation for ANSII C, 10-Mar-1989
*
* $Log: hash.c,v $
* Revision 1.8 1997/10/22 16:36:49 sauderd
* Changed the use and definitions of the compiler macros MUL and DIV. They
* seem to be defined and used only within hash.h and hash.c
*
* Revision 1.7 1997/01/21 19:19:51 dar
* made C++ compatible
*
* Revision 1.6 1994/03/23 20:06:51 libes
* botched free in hash destroy
*
* Revision 1.5 1993/10/15 18:49:55 libes
* CADDETC certified
*
* Revision 1.4 1992/08/18 18:27:10 libes
* changed DEBUG to HASH_DEBUG
*
* Revision 1.3 1992/08/18 17:16:22 libes
* rm'd extraneous error messages
*
* Revision 1.2 1992/05/31 08:37:18 libes
* multiple files
*
* Revision 1.1 1992/05/28 03:56:55 libes
* Initial revision
*
* Revision 1.4 1992/05/14 10:15:04 libes
* don't remember
*
* Revision 1.3 1992/02/12 07:06:49 libes
* y
* y
* do sub/supertype
*
* Revision 1.2 1992/02/09 00:51:02 libes
* does ref/use correctly
*
* Revision 1.1 1992/02/05 08:34:24 libes
* Initial revision
*
* Revision 1.0.1.1 1992/01/22 02:40:04 libes
* copied from ~pdes
*
* Revision 1.9 1992/01/22 02:26:58 libes
* added code to test hash package
*
* Revision 1.8 1991/09/17 02:53:23 libes
* fixed bug in HASHcopy (new hash tables were coming out empty)
*
* Revision 1.7 1991/08/30 16:34:36 libes
* fixed HASHlist to use state from parameter instead of static
*
* Revision 1.6 1991/08/13 22:19:39 libes
* forgot to declare s, s2, pp, and q. Oops.
*
* Revision 1.5 1991/08/06 19:03:07 libes
* fixed bugs relating to my previous addition (delete function)
* added HASHcopy to support DICT_copy via OBJcopy
*
* Revision 1.4 1991/07/19 03:57:46 libes
* added action HASH_DELETE
* made action HASH_INSERT return failure upon duplicate entry
*
* Revision 1.3 1991/02/26 19:40:45 libes
* Added functions for visiting every member of the hash table, to duplicate
* similar functionality of linked lists. Note that current implementation
* can only walk through one hash table at a time. This can be improved, but
* the application code doesn't currently need such a feature.
*
* Revision 1.2 1990/09/06 11:06:56 clark
* BPR 2.1 alpha
*
* Revision 1.1 90/06/11 16:44:43 clark
* Initial revision
*
* ~50% rewritten by Chris Horler for STEPcode
*
* Specific implementation points (based on empirical data)
*
* - the maximum SCHEMA symbol table is probably about 4-6k entries
* - the typical symbol table is (only!) between 8 and 64 entries
* - there's no extended growth behaviour of symbol tables
* - ...
*
* REMARK: This approach is probably overly complex for such a small data set
*
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#ifdef HASH_DEBUG
#include <math.h>
#endif
#include "bstrlib.h"
#include "sc_memmgr.h"
#include "express/hash.h"
#include "hash_impl.h"
#include "symbol_impl.h"
/*
** Internal routines
*/
#define SEGMENT_SZ 32 /* deliberately small segment size! */
#define SEGMENT_WIDTH 5 /* log2(SEGMENT_SZ) */
#define LOAD_FACTOR 1 /* ensures minimum collisions, maximum size */
#define PRIME1 37
#define PRIME2 1048583
static inline Address HASHhash( char *, Hash_Table );
static void HASHexpand_table( Hash_Table );
extern inline struct Symbol_ *SYMBOL_new();
extern inline void SYMBOL_destroy(struct Symbol_ *x);
/*
** Local data
*/
Hash_Table
HASH_Table_new() {
return ALLOC_new(&HASH_Table_fl);
}
# ifdef HASH_STATISTICS
static long HashAccesses, HashCollisions;
# endif
/*
** Code
*/
void
HASH_Table_destroy(Hash_Table x) {
ALLOC_destroy(&HASH_Table_fl,(Freelist *)x);
}
void
HASHinitialize() {
}
Hash_Table
HASHcreate( unsigned count ) {
unsigned i;
Hash_Table table;
HASHcreate()
{
Hash_Table tbl;
unsigned int i;
tbl = HASH_Table_new();
/*
** Adjust Count to be nearest higher power of 2,
** minimum SEGMENT_SIZE, then convert into segments.
*/
i = SEGMENT_SIZE;
while( i < count ) {
i <<= 1;
/* default to minimum size */
tbl->maxp = SEGMENT_SZ;
tbl->DirectorySize = tbl->maxp >> SEGMENT_WIDTH;
/* allocate segments */
tbl->Directory = sc_calloc(sizeof(Segment *), tbl->DirectorySize);
if (tbl->Directory == NULL) {
HASHdestroy(tbl);
return NULL;
}
count = DIV( i, SEGMENT_SIZE_SHIFT );
table = HASH_Table_new();
#if 0
table->in_use = 0;
#endif
table->SegmentCount = table->p = table->KeyCount = 0;
/*
** Allocate initial 'i' segments of buckets
*/
for( i = 0; i < count; i++ )
CALLOC( table->Directory[i], SEGMENT_SIZE, Element )
/*, "segment in HASHcreate");*/
table->SegmentCount = count;
table->maxp = MUL( count, SEGMENT_SIZE_SHIFT );
table->MinLoadFactor = 1;
table->MaxLoadFactor = MAX_LOAD_FACTOR;
# ifdef HASH_DEBUG
fprintf( stderr,
"[HASHcreate] table %x count %d maxp %d SegmentCount %d\n",
table,
count,
table->maxp,
table->SegmentCount );
# endif
# ifdef HASH_STATISTICS
HashAccesses = HashCollisions = 0;
# endif
return( table );
}
/* initialize pointer to beginning of hash table so we can step through it */
/* on repeated calls to HASHlist - DEL */
void
HASHlistinit( Hash_Table table, HashEntry * he ) {
he->i = he->j = 0;
he->p = 0;
he->table = table;
he->type = '*';
#if 0
table->in_use = 1;
/* Allocate initial buckets */
for (i = 0; i < tbl->DirectorySize; i++) {
tbl->Directory[i] = sc_calloc(sizeof(Segment), SEGMENT_SZ);
if (tbl->Directory[i] == NULL) {
HASHdestroy(tbl);
return NULL;
}
tbl->SegmentCount++;
}
#ifdef HASH_DEBUG
fprintf(stderr, "[hcreate] Table %p Count %u maxp %u SegmentCount %u\n",
tbl, tbl->KeyCount, tbl->maxp, tbl->SegmentCount);
#endif
return tbl;
}
void
HASHlistinit_by_type( Hash_Table table, HashEntry * he, char type ) {
he->i = he->j = 0;
he->p = 0;
he->table = table;
he->type = type;
#if 0
table->in_use = 1;
HASHdestroy(Hash_Table tbl)
{
unsigned int i, j;
#ifdef HASH_DEBUG
float n, r;
#endif
}
Segment s;
Symbol *p,*q;
#if 0
/* if you don't step to the end, you can clear the flag this way */
void
HASHlistend( HashEntry * he ) {
he->table->in_use = 0;
}
#endif
assert(tbl != NULL);
/* provide a way to step through the hash */
Element
HASHlist( HashEntry * he ) {
int i2 = he->i;
int j2 = he->j;
Segment s;
he->e = 0;
for( he->i = i2; he->i < he->table->SegmentCount; he->i++ ) {
/* test probably unnecessary */
if( ( s = he->table->Directory[he->i] ) != NULL ) {
for( he->j = j2; he->j < SEGMENT_SIZE; he->j++ ) {
if( !he->p ) {
he->p = s[he->j];
}
/* if he->p is defined, prepare to return it (by
setting it to he->e) and begin looking for a new value
for he->p
*/
retry:
if( he->p ) {
if( ( he->type != '*' ) &&
( he->type != he->p->type ) ) {
he->p = he->p->next;
goto retry;
}
if( he->e ) {
return( he->e );
}
he->e = he->p;
he->p = he->p->next;
}
/* avoid incrementing he->j by returning here */
if( he->p ) {
return( he->e );
}
}
j2 = 0;
}
}
/* if he->e was set then it is last one */
#if 0
he->table->in_use = 0;
#endif
return( he->e );
}
#if 0
/* this verifies no one else is walking through the table that we might screw up */
/* it should be called before adding, deleting or destroying a table */
HASH_in_use( Hash_Table table, char * action ) {
fprintf( stderr, "HASH: attempted to %s but hash table in use\n", action );
}
#endif
void
HASHdestroy( Hash_Table table ) {
Segment s;
Element p, q;
if( table != HASH_NULL ) {
unsigned int i, j;
#if 0
if( table->in_use ) {
HASH_in_use( table, "destroy hash table" );
}
#endif
for( i = 0; i < table->SegmentCount; i++ ) {
/* test probably unnecessary */
if( ( s = table->Directory[i] ) != NULL ) {
for( j = 0; j < SEGMENT_SIZE; j++ ) {
p = s[j];
while( p != NULL ) {
q = p->next;
HASH_Element_destroy( p );
p = q;
}
}
sc_free( table->Directory[i] );
for (i = 0; i < tbl->SegmentCount; i++) {
s = tbl->Directory[i];
assert(s != NULL);
for (j = 0; j < SEGMENT_SZ; j++) {
p = s[j];
while (p != NULL) {
q = p->next;
sc_free(p);
p = q;
}
}
HASH_Table_destroy( table );
# if defined(HASH_STATISTICS) && defined(HASH_DEBUG)
fprintf( stderr,
"[hdestroy] Accesses %ld Collisions %ld\n",
HashAccesses,
HashCollisions );
# endif
sc_free(s);
}
}
Element
HASHsearch( Hash_Table table, Element item, Action action ) {
Address h;
Segment CurrentSegment;
int SegmentIndex;
int SegmentDir;
Segment p;
Element q;
Element deleteme;
assert( table != HASH_NULL ); /* Kinder really than return(NULL); */
# ifdef HASH_STATISTICS
HashAccesses++;
# endif
h = HASHhash( item->key, table );
SegmentDir = DIV( h, SEGMENT_SIZE_SHIFT );
SegmentIndex = MOD( h, SEGMENT_SIZE );
/*
** valid segment ensured by HASHhash()
*/
CurrentSegment = table->Directory[SegmentDir];
assert( CurrentSegment != NULL ); /* bad failure if tripped */
p = CurrentSegment + SegmentIndex;
q = *p;
/*
** Follow collision chain
** Now and after we finish this loop
** p = &element, and
** q = element
*/
while( q != NULL && strcmp( q->key, item->key ) ) {
p = &q->next;
q = *p;
# ifdef HASH_STATISTICS
HashCollisions++;
# endif
}
/* at this point, we have either found the element or it doesn't exist */
switch( action ) {
case HASH_FIND:
return( ( Element )q );
case HASH_DELETE:
if( !q ) {
return( 0 );
}
/* at this point, element exists and action == DELETE */
#if 0
if( table->in_use ) {
HASH_in_use( table, "insert element" );
}
sc_free(tbl->Directory);
#ifdef HASH_DEBUG
r = tbl->KeyCount;
n = tbl->SegmentCount << SEGMENT_WIDTH;
fprintf(
stderr,
"[hdestroy] Count %u HashSize: %u Collisions %u ExpectedCollisions: %.2f\n",
tbl->KeyCount,
tbl->SegmentCount << SEGMENT_WIDTH,
tbl->HashCollisions,
((r - n) + n * powf((n - 1) / n, r))
);
#endif
deleteme = q;
*p = q->next;
/*STRINGfree(deleteme->key);*/
HASH_Element_destroy( deleteme );
--table->KeyCount;
return( deleteme ); /* of course, user shouldn't deref this! */
case HASH_INSERT:
/* if trying to insert it (twice), let them know */
if( q != NULL ) {
return( q ); /* was return(0);!!!!!?!?! */
}
#if 0
if( table->in_use ) {
HASH_in_use( table, "delete element" );
}
#endif
/* at this point, element does not exist and action == INSERT */
q = HASH_Element_new();
*p = q; /* link into chain */
/*
** Initialize new element
*/
/* I don't see the point of copying the key!!!! */
/* q->key = STRINGcopy(item->key);*/
q->key = item->key;
q->data = item->data;
q->symbol = item->symbol;
q->type = item->type;
q->next = NULL;
/*
** table over-full?
*/
if( ++table->KeyCount / MUL( table->SegmentCount, SEGMENT_SIZE_SHIFT ) > table->MaxLoadFactor ) {
HASHexpand_table( table ); /* doesn't affect q */
}
}
return( ( Element )0 ); /* was return (Element)q */
}
/*
** Internal routines
*/
static inline Address HASHhash( char * Key, Hash_Table table ) {
Address h, address;
register unsigned char * k = ( unsigned char * )Key;
h = 0;
/*
** Convert string to integer
*/
/*SUPPRESS 112*/
assert( Key );
while( *k )
/*SUPPRESS 8*/ { /*SUPPRESS 112*/
h = h * PRIME1 ^ ( *k++ - ' ' );
}
h %= PRIME2;
address = MOD( h, table->maxp );
if( address < table->p ) {
address = MOD( h, ( table->maxp << 1 ) ); /* h % (2*table->maxp) */
}
return( address );
}
static void HASHexpand_table( Hash_Table table ) {
Segment OldSegment, NewSegment;
Element Current, *Previous, *LastOfNew;
if( table->maxp + table->p < MUL( DIRECTORY_SIZE, SEGMENT_SIZE_SHIFT ) ) {
Address NewAddress;
int OldSegmentIndex, NewSegmentIndex;
int OldSegmentDir, NewSegmentDir;
/*
** Locate the bucket to be split
*/
OldSegmentDir = DIV( table->p, SEGMENT_SIZE_SHIFT );
OldSegment = table->Directory[OldSegmentDir];
OldSegmentIndex = MOD( table->p, SEGMENT_SIZE );
/*
** Expand address space; if necessary create a new segment
*/
NewAddress = table->maxp + table->p;
NewSegmentDir = DIV( NewAddress, SEGMENT_SIZE_SHIFT );
NewSegmentIndex = MOD( NewAddress, SEGMENT_SIZE );
if( NewSegmentIndex == 0 ) {
CALLOC( table->Directory[NewSegmentDir], SEGMENT_SIZE, Element );
}
/* "segment in HASHexpand_table");*/
NewSegment = table->Directory[NewSegmentDir];
/*
** Adjust state variables
*/
table->p++;
if( table->p == table->maxp ) {
table->maxp <<= 1; /* table->maxp *= 2 */
table->p = 0;
}
table->SegmentCount++;
/*
** Relocate records to the new bucket
*/
Previous = &OldSegment[OldSegmentIndex];
Current = *Previous;
LastOfNew = &NewSegment[NewSegmentIndex];
*LastOfNew = NULL;
while( Current != NULL ) {
if( HASHhash( Current->key, table ) == NewAddress ) {
/*
** Attach it to the end of the new chain
*/
*LastOfNew = Current;
/*
** Remove it from old chain
*/
*Previous = Current->next;
LastOfNew = &Current->next;
Current = Current->next;
*LastOfNew = NULL;
} else {
/*
** leave it on the old chain
*/
Previous = &Current->next;
Current = Current->next;
}
}
}
HASH_Table_destroy(tbl);
}
/* make a complete copy of a hash table */
@@ -495,72 +148,323 @@ static void HASHexpand_table( Hash_Table table ) {
Hash_Table
HASHcopy( Hash_Table oldtable ) {
Hash_Table newtable;
Segment s, s2;
Element * pp; /* old element */
Element * qq; /* new element */
Symbol *p, **q;
unsigned int i, j;
newtable = HASH_Table_new();
for( i = 0; i < oldtable->SegmentCount; i++ ) {
CALLOC( newtable->Directory[i], SEGMENT_SIZE, Element );
/* "segment in HASHcopy");*/
}
memcpy(newtable, oldtable, sizeof *oldtable);
newtable->p = oldtable->p;
newtable->SegmentCount = oldtable->SegmentCount;
newtable->maxp = oldtable->maxp;
newtable->MinLoadFactor = oldtable->MinLoadFactor;
newtable->MaxLoadFactor = oldtable->MaxLoadFactor;
newtable->KeyCount = oldtable->KeyCount;
for( i = 0; i < oldtable->SegmentCount; i++ ) {
/* test probably unnecessary */
if( ( s = oldtable->Directory[i] ) != NULL ) {
s2 = newtable->Directory[i];
for( j = 0; j < SEGMENT_SIZE; j++ ) {
qq = &s2[j];
for( pp = &s[j]; *pp; pp = &( *pp )->next ) {
*qq = HASH_Element_new();
/* (*qq)->key = STRINGcopy((*pp)->key);*/
/* I really doubt it is necessary to copy the key!!! */
( *qq )->key = ( *pp )->key;
( *qq )->data = ( *pp )->data;
( *qq )->symbol = ( *pp )->symbol;
( *qq )->type = ( *pp )->type;
( *qq )->next = NULL;
qq = &( ( *qq )->next );
}
newtable->Directory = sc_calloc(newtable->DirectorySize, sizeof(Segment *));
if (!newtable->Directory)
/* HASHdestroy? */
return NULL;
for (i = 0; i < newtable->SegmentCount; i++) {
newtable->Directory[i] = sc_calloc(SEGMENT_SZ, sizeof(Segment));
if (!newtable->Directory[i])
/* HASHdestroy */
return NULL;
for (j = 0; j < SEGMENT_SZ; j++) {
p = oldtable->Directory[i][j];
q = &newtable->Directory[i][j];
while (p) {
*q = SYMBOL_new();
memcpy(*q, p, sizeof(Symbol));
(*q)->next = NULL;
q = &(*q)->next;
p = p->next;
}
}
}
return( newtable );
return newtable;
}
/* following code is for testing hash package */
#ifdef HASHTEST
struct Element e1, e2, e3, *e;
struct Hash_Table * t;
HashEntry he;
Symbol *
HASHsearch(Hash_Table tbl, Symbol item, Action action) {
size_t h;
Segment CurrentSegment;
int SegmentIndex;
int SegmentDir;
Symbol **p, *q;
main() {
e1.key = "foo";
e1.data = ( char * )1;
e2.key = "bar";
e2.data = ( char * )2;
e3.key = "herschel";
e3.data = ( char * )3;
assert(tbl != NULL);
t = HASHcreate( 100 );
e = HASHsearch( t, &e1, HASH_INSERT );
e = HASHsearch( t, &e2, HASH_INSERT );
e = HASHsearch( t, &e3, HASH_INSERT );
HASHlistinit( t, &he );
for( ;; ) {
e = HASHlist( &he );
if( !e ) {
exit( 0 );
h = HASHhash(item.name);
if (h % tbl->maxp < tbl->p) {
h %= (tbl->maxp << 1);
} else {
h %= tbl->maxp;
}
SegmentDir = h >> SEGMENT_WIDTH;
SegmentIndex = h % SEGMENT_SZ;
CurrentSegment = tbl->Directory[SegmentDir];
assert(CurrentSegment != NULL);
p = &CurrentSegment[SegmentIndex];
q = *p;
/* Follow collision chain */
while (q != NULL && strcasecmp((char *) q->name, (char *) item.name)) {
p = &q->next;
q = *p;
}
/* TODO: remove HASH_DELETE to force compile error */
assert(action != HASH_DELETE);
if (action == HASH_DELETE)
return NULL;
/* found, not found - search only, alloc or fail */
if (q != NULL || action == HASH_FIND || (q = SYMBOL_new()) == NULL)
return q;
#ifdef HASH_DEBUG
/* check for a (new) collision */
if (p != &CurrentSegment[SegmentIndex])
tbl->HashCollisions++;
#endif
/* link into chain, initialize new element */
*p = q;
memcpy(q, &item, sizeof(Symbol));
q->next = NULL;
++tbl->KeyCount;
/* resize the table */
if (tbl->KeyCount / (tbl->SegmentCount << SEGMENT_WIDTH ) >= LOAD_FACTOR)
HASHexpand_table(tbl);
return q;
}
void
HASHdelete(Hash_Table tbl, Symbol *item) {
size_t h;
Segment CurrentSegment;
int SegmentIndex;
int SegmentDir;
Symbol **p, *q;
assert(tbl != NULL);
h = HASHhash(item->name);
if (h % tbl->maxp < tbl->p) {
h %= (tbl->maxp << 1);
} else {
h %= tbl->maxp;
}
SegmentDir = h >> SEGMENT_WIDTH;
SegmentIndex = h % SEGMENT_SZ;
CurrentSegment = tbl->Directory[SegmentDir];
assert(CurrentSegment != NULL);
p = &CurrentSegment[SegmentIndex];
q = *p;
/* Follow collision chain */
while (q != NULL && strcasecmp((char *) q->name, (char *) item->name)) {
p = &q->next;
q = *p;
}
/* ensure no undefined assignment behaviour */
assert(q != item);
if (!q)
return;
*p = q->next;
memcpy(item, q, sizeof(Symbol));
item->next = NULL;
tbl->KeyCount--;
SYMBOL_destroy(q);
}
/*
** Internal routines
*/
size_t HASHhash(const unsigned char *key)
{
size_t h;
const unsigned char *k;
/* Convert string to integer */
for (h = 0, k = key; *k; k++)
h = h * PRIME1 ^ toupper(*k);
h %= PRIME2;
return h;
}
/*
* tbl->p the next bucket to be split [x mod N]
* tbl->maxp the current table size [N]
*
* NOTE: the method, as it's not entirely obvious
*
* e.g. tbl->maxp == 4 [N]
* 4, 8, 12, 16 are in bucket 0 (x mod 4 == 0)
* 4, 12 are in (new) bucket 4 (x mod 8 == 4)
* 8, 16 remain in bucket 0 (x mod 8 == 0)
*
* general form
* x mod N
* -> x mod 2N
*/
void
HASHexpand_table(Hash_Table tbl)
{
size_t NewAddress, h;
#ifdef HASH_DEBUG
int ci, cj, ck;
#endif
int OldSegmentIndex, NewSegmentIndex;
int OldSegmentDir, NewSegmentDir;
Segment OldSegment, NewSegment, *NewDirectory;
Symbol *Current,**Previous,**LastOfNew;
/* check there's enough space for a new bucket, attempt resize */
if (tbl->maxp + tbl->p >= (tbl->DirectorySize << SEGMENT_WIDTH)) {
NewDirectory = sc_realloc(tbl->Directory, sizeof(Segment *) * (tbl->DirectorySize << 1));
if (!NewDirectory)
return;
tbl->Directory = NewDirectory;
memset(tbl->Directory + tbl->SegmentCount, 0, sizeof(Segment *) * tbl->DirectorySize);
tbl->DirectorySize <<= 1;
}
/*
** Locate the bucket to be split
*/
OldSegmentDir = tbl->p >> SEGMENT_WIDTH;
OldSegment = tbl->Directory[OldSegmentDir];
OldSegmentIndex = tbl->p % SEGMENT_SZ;
/*
** Expand address space; if necessary create a new segment
*/
NewAddress = tbl->maxp + tbl->p;
NewSegmentDir = NewAddress >> SEGMENT_WIDTH;
NewSegmentIndex = NewAddress % SEGMENT_SZ;
if (NewSegmentIndex == 0) {
#ifdef HASH_DEBUG
fprintf(stderr, "[ExpandTable] %p Count %u maxp %d SegmentCount %u Collisions %u\n",
tbl, tbl->KeyCount, tbl->maxp, tbl->SegmentCount, tbl->HashCollisions);
#endif
tbl->Directory[NewSegmentDir] = sc_calloc(sizeof(Segment), SEGMENT_SZ);
if (!tbl->Directory[NewSegmentDir])
return;
tbl->SegmentCount++;
}
NewSegment = tbl->Directory[NewSegmentDir];
/*
** Relocate records to the new bucket
*/
Previous = &OldSegment[OldSegmentIndex];
Current = *Previous;
LastOfNew = &NewSegment[NewSegmentIndex];
*LastOfNew = NULL;
#ifdef HASH_DEBUG
ci = cj = ck = -1;
#endif
while (Current != NULL)
{
#ifdef HASH_DEBUG
/* collisions to remove */
ck++;
#endif
/* rehash for a factor 2 increase */
h = HASHhash(Current->name) % (tbl->maxp << 1);
if (h == NewAddress) {
/* Attach it to the end of the new chain */
*LastOfNew = Current;
/* Remove it from old chain */
*Previous = Current->next;
LastOfNew = &Current->next;
Current = Current->next;
*LastOfNew = NULL;
#ifdef HASH_DEBUG
/* collisions to add */
ci++;
#endif
} else {
/* leave it on the old chain */
Previous = &Current->next;
Current = Current->next;
#ifdef HASH_DEBUG
/* collisions to add */
cj++;
#endif
}
fprintf( stderr, "found key %s, data %d\n", e->key, ( int )e->data );
}
#ifdef HASH_DEBUG
if (ck > 0) {
tbl->HashCollisions -= ck;
if (ci > 0)
tbl->HashCollisions += ci;
if (cj > 0)
tbl->HashCollisions += cj;
}
#endif
/* increment for the next bucket */
tbl->p++;
if (tbl->p == tbl->maxp)
{
tbl->maxp <<= 1;
tbl->p = 0;
}
}
#endif
/****** minimal iterator implementation **********/
void
HASHdo_init(Hash_Table tbl, Hash_Iterator *it, char type) {
it->hash = 0;
it->table = tbl;
it->p = NULL;
it->type = type;
}
/* provide a way to step through the hash */
Symbol *
HASHdo( Hash_Iterator * it ) {
Symbol *q;
int SegmentDir, SegmentIndex;
for (; it->hash < (it->table->maxp + it->table->p); it->hash++) {
SegmentDir = it->hash >> SEGMENT_WIDTH;
SegmentIndex = it->hash % SEGMENT_SZ;
/* only used segments are initialised */
assert(it->table->Directory[SegmentDir] != NULL);
if (!it->p)
it->p = it->table->Directory[SegmentDir][SegmentIndex];
while (it->p != NULL) {
q = it->p;
if (q && (it->type == OBJ_ANY || it->type == q->type)) {
it->p = q->next;
if (!it->p)
it->hash++;
return q;
}
it->p = q->next;
}
}
return NULL;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef __HASH_IMPL_H
#define __HASH_IMPL_H
#include "express/hash.h"
inline size_t HASHhash(const unsigned char *);
inline void HASHexpand_table(Hash_Table);
inline Hash_Table HASH_Table_new();
inline void HASH_Table_destroy(Hash_Table x);
#endif /* __HASH_IMPL_H */
+442
View File
@@ -0,0 +1,442 @@
#include <stdio.h>
#include <stdlib.h>
#include "sc_memmgr.h"
#include "lexsupport.h"
#include "expparse.h"
#include "expscan.h"
struct kw_token_def reserved_keywords[] = {
{"ABS", T_ABS},
{"ABSTRACT", T_ABSTRACT},
{"ACOS", T_ACOS},
{"AGGREGATE", T_AGGREGATE},
{"ALIAS", T_ALIAS},
{"AND", T_AND},
{"ANDOR", T_ANDOR},
{"ARRAY", T_ARRAY},
{"AS", T_AS},
{"ASIN", T_ASIN},
{"ATAN", T_ATAN},
{"BAG", T_BAG},
{"BASED_ON", T_BASED_ON},
{"BEGIN", T_BEGIN},
{"BINARY", T_BINARY},
{"BLENGTH", T_BLENGTH},
{"BOOLEAN", T_BOOLEAN},
{"BY", T_BY},
{"CASE", T_CASE},
{"CONSTANT", T_CONSTANT},
{"CONST_E", T_CONST_E},
{"COS", T_COS},
{"DERIVE", T_DERIVE},
{"DIV", T_IDIV},
{"ELSE", T_ELSE},
{"END", T_END},
{"END_ALIAS", T_END_ALIAS},
{"END_CASE", T_END_CASE},
{"END_CONSTANT", T_END_CONSTANT},
{"END_ENTITY", T_END_ENTITY},
{"END_FUNCTION", T_END_FUNCTION},
{"END_IF", T_END_IF},
{"END_LOCAL", T_END_LOCAL},
{"END_PROCEDURE", T_END_PROCEDURE},
{"END_REPEAT", T_END_REPEAT},
{"END_RULE", T_END_RULE},
{"END_SCHEMA", T_END_SCHEMA},
{"END_SUBTYPE_CONSTRAINT", T_END_SUBTYPE_CONSTRAINT},
{"END_TYPE", T_END_TYPE},
{"ENTITY", T_ENTITY},
{"ENUMERATION", T_ENUMERATION},
{"ESCAPE", T_ESCAPE},
{"EXISTS", T_EXISTS},
{"EXP", T_EXP},
{"EXTENSIBLE", T_EXTENSIBLE},
{"FALSE", T_FALSE},
{"FIXED", T_FIXED},
{"FOR", T_FOR},
{"FORMAT", T_FORMAT},
{"FROM", T_FROM},
{"FUNCTION", T_FUNCTION},
{"GENERIC", T_GENERIC},
{"GENERIC_ENTITY", T_GENERIC_ENTITY},
{"HIBOUND", T_HIBOUND},
{"HIINDEX", T_HIINDEX},
{"IF", T_IF},
{"IN", T_IN},
{"INSERT", T_INSERT},
{"INTEGER", T_INTEGER},
{"INVERSE", T_INVERSE},
{"LENGTH", T_LENGTH},
{"LIKE", T_LIKE},
{"LIST", T_LIST},
{"LOBOUND", T_LOBOUND},
{"LOCAL", T_LOCAL},
{"LOG", T_LOG},
{"LOG10", T_LOG10},
{"LOG2", T_LOG2},
{"LOGICAL", T_LOGICAL},
{"LOINDEX", T_LOINDEX},
{"MOD", T_MOD},
{"NOT", T_NOT},
{"NUMBER", T_NUMBER},
{"NVL", T_NVL},
{"ODD", T_ODD},
{"OF", T_OF},
{"ONEOF", T_ONEOF},
{"OPTIONAL", T_OPTIONAL},
{"OR", T_OR},
{"OTHERWISE", T_OTHERWISE},
{"PI", T_PI},
{"PROCEDURE", T_PROCEDURE},
{"QUERY", T_QUERY},
{"REAL", T_REAL},
{"REFERENCE", T_REFERENCE},
{"REMOVE", T_REMOVE},
{"RENAMED", T_RENAMED},
{"REPEAT", T_REPEAT},
{"RETURN", T_RETURN},
{"ROLESOF", T_ROLESOF},
{"RULE", T_RULE},
{"SCHEMA", T_SCHEMA},
{"SELECT", T_SELECT},
{"SELF", T_SELF},
{"SET", T_SET},
{"SIN", T_SIN},
{"SIZEOF", T_SIZEOF},
{"SKIP", T_SKIP},
{"SQRT", T_SQRT},
{"STRING", T_STRING},
{"SUBTYPE", T_SUBTYPE},
{"SUBTYPE_CONSTRAINT", T_SUBTYPE_CONSTRAINT},
{"SUPERTYPE", T_SUPERTYPE},
{"TAN", T_TAN},
{"THEN", T_THEN},
{"TO", T_TO},
{"TOTAL_OVER", T_TOTAL_OVER},
{"TRUE", T_TRUE},
{"TYPE", T_TYPE},
{"TYPEOF", T_TYPEOF},
{"UNIQUE", T_UNIQUE},
{"UNKNOWN", T_UNKNOWN},
{"UNTIL", T_UNTIL},
{"USE", T_USE},
{"USEDIN", T_USEDIN},
{"VALUE", T_VALUE},
{"VALUE_IN", T_VALUE_IN},
{"VALUE_UNIQUE", T_VALUE_UNIQUE},
{"VAR", T_VAR},
{"WHERE", T_WHERE},
{"WHILE", T_WHILE},
{"WITH", T_WITH},
{"XOR", T_XOR},
{NULL, 0}
};
struct intList *intListCreate (void) {
struct intList * il = sc_malloc(sizeof(struct intList));
if (il) {
il->entry = sc_malloc(sizeof(int));
if (!il->entry) {
sc_free(il);
il = NULL;
} else {
il->entry[0] = 0;
il->qty = 0;
il->mlen = 1;
}
}
return il;
}
int intListDestroy (struct intList * il) {
/* dummy implementation */
return 0;
}
int intListAllocMin (struct intList * il, int msz) {
int *l;
size_t nsz;
if (!il || msz <= 0 || !il->entry || il->qty < 0 || il->mlen <= 0 ||
il->qty > il->mlen) return BSTR_ERR;
if (msz < il->qty) msz = il->qty;
if (il->mlen == msz) return BSTR_OK;
nsz = ((size_t) msz) * sizeof(int);
if (nsz < (size_t) msz) return BSTR_ERR;
l = sc_realloc(il->entry, nsz);
if (!l) return BSTR_ERR;
il->mlen = msz;
il->entry = l;
memset(il->entry + il->qty, 0, sizeof(int) * (il->mlen - il->qty));
return BSTR_OK;
}
struct scopeList *scopeListCreate (void) {
struct scopeList * sl = sc_malloc(sizeof(struct scopeList));
if (sl) {
sl->entry = sc_malloc(sizeof(struct scope_def));
if (!sl->entry) {
sc_free(sl);
sl = NULL;
} else {
sl->qty = 0;
sl->mlen = 1;
}
}
return sl;
}
int scopeListDestroy (struct scopeList * sl) {
/* dummy implementation */
return 0;
}
int scopeListAllocMin (struct scopeList * sl, int msz) {
struct scope_def *l;
size_t nsz;
if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 ||
sl->qty > sl->mlen) return BSTR_ERR;
if (msz < sl->qty) msz = sl->qty;
if (sl->mlen == msz) return BSTR_OK;
nsz = ((size_t) msz) * sizeof(struct scope_def);
if (nsz < (size_t) msz) return BSTR_ERR;
l = sc_realloc(sl->entry, nsz);
if (!l) return BSTR_ERR;
sl->mlen = msz;
sl->entry = l;
return BSTR_OK;
}
void yylexReset(struct exp_scanner *s, int new_mode) {
s->cur = s->tok = s->mrk = s->ctx = s->buffer->data;
memset(s->cond_stack->entry, 0, sizeof(int) * s->cond_stack->mlen);
s->cond_top = 0;
s->cond_stack->entry[0] = new_mode;
s->mode = new_mode;
}
int yylexInit(struct exp_scanner *pScanner, struct YYSTATE *pState, FILE *fp) {
bstring buf;
buf = bread((bNread) fread, fp);
if (!buf)
yyerror("failed to read input!", 0);
pScanner->state = pState;
pScanner->scope_top = scope_alloc(pState->scope_stack, "DOCROOT", OBJ_DOCROOT_BITS);
pState->scope_stack->entry[pScanner->scope_top].parent = -1;
pScanner->buffer = buf;
pScanner->lim = buf->data + buf->slen;
pScanner->anon_scope_cnt = 1;
yylexReset(pScanner, yycP1);
return 0;
}
struct exp_scanner *yylexAlloc() {
int chk;
struct exp_scanner *scanner;
scanner = sc_malloc(sizeof *scanner);
if (scanner) {
memset(scanner, 0, sizeof *scanner);
scanner->cond_stack = intListCreate();
chk = intListAllocMin(scanner->cond_stack, 20);
if (chk != BSTR_OK)
goto err_out;
scanner->brkt_nesting = intListCreate();
chk = intListAllocMin(scanner->brkt_nesting, 50);
if (chk != BSTR_OK)
goto err_out;
}
return scanner;
err_out:
return NULL;
}
struct YYSTATE *yystateAlloc() {
struct YYSTATE *pState = sc_malloc(sizeof(struct YYSTATE));
if (pState) {
pState->scope_stack = scopeListCreate();
pState->lineno = 1;
}
return pState;
}
int scope_alloc(struct scopeList *stack, const char *typ, int scope_type) {
struct scope_def *sp;
const char *nx;
char *np;
int chk;
/* TODO: error checking */
chk = scopeListAllocMin(stack, stack->qty+1);
if (chk != BSTR_OK)
goto err_out;
sp = stack->entry + stack->qty;
/* TODO: really this doesn't need a symbol - we only have the "name", which could be assigned later or here */
sp->symbol.name = NULL;
sp->type = scope_type;
sp->parent = 0xDEADBEEF;
sp->symbol_table = HASHcreate();
#ifdef YYDEBUG
sp->symbol.stype = strdup(typ);
for (nx = typ, np = sp->stype; *nx; nx++, np++)
*np = toupper((unsigned char) *nx);
#endif
return stack->qty++;
err_out:
yyerror("scope_alloc failure!", 0);
}
void scope_push(struct YYSTATE *pState, int idx, struct exp_scanner *pScanner) {
struct scopeList *stack = pState->scope_stack;
struct scope_def *scope = stack->entry + idx;
scope->parent = pScanner->scope_top;
if (idx < 0) {
yyerror("+++scope_push() internal error, pushing nonsense!", pScanner->lineno);
}
pScanner->scope_top = idx;
}
int scope_pop(struct YYSTATE *pState, struct exp_scanner *pScanner) {
struct scopeList *stack = pState->scope_stack;
int idx = pScanner->scope_top;
struct scope_def *scope = stack->entry + idx;
if (scope->parent < 0) {
yyerror("+++scope_pop() internal error, popping of the stack", 0);
}
pScanner->scope_top = scope->parent;
return idx;
}
int scope_find(struct YYSTATE *pState, int itype, const char *sname, struct exp_scanner *pScanner) {
struct scopeList *stack = pState->scope_stack;
struct scope_def *s;
int i, idx = -1, pidx = pScanner->scope_top;
/* need to match parent, name and type */
for (i = 0; i < stack->qty; i++) {
s = stack->entry + i;
if (s->parent == pidx && s->type == itype && !strcasecmp(s->symbol.name, sname)) {
idx = i;
break;
}
}
if (idx < 0)
yyerror("+++ scope_find failed, internal error!\n", 0);
return idx;
}
void add_symbol(struct scope_def *scope, const char *id, int ref_tok, struct exp_scanner *pScanner) {
Symbol e, *ep;
int type;
switch (ref_tok) {
case T_SCHEMA_REF:
type = OBJ_SCHEMA;
break;
case T_FUNCTION_REF:
type = OBJ_FUNCTION;
break;
case T_PROCEDURE_REF:
type = OBJ_PROCEDURE;
break;
case T_RULE_REF:
type = OBJ_RULE;
break;
case T_ENTITY_REF:
type = OBJ_ENTITY;
break;
case T_TYPE_REF:
type = OBJ_TYPE;
break;
case T_ENUMERATION_REF:
type = OBJ_ENUM;
break;
case T_RULE_LABEL_REF:
type = OBJ_TAG; /* TODO: check, confirm rule labels are tags */
break;
case T_VARIABLE_REF:
case T_PARAMETER_REF: /* TODO: check - parameter maps to variable? */
type = OBJ_VARIABLE;
break;
default: /* T_CONSTANT_REF, T_INVALID, T_SIMPLE_REF */
type = OBJ_UNKNOWN; /* TODO: check for CONSTANT */
}
e = (Symbol) {.name = strdup(id), .type = type, .ref_tok = ref_tok,
.filename = pScanner->filename, .line = pScanner->lineno};
ep = HASHsearch(scope->symbol_table, e, HASH_INSERT);
if (!ep)
yyerror("failed to insert symbol into symbol table", pScanner->lineno);
}
int resolve_symbol(struct YYSTATE *pState, const char *id, struct exp_scanner *pScanner) {
Symbol *qry, *sym;
bool is_enum;
int cnt_enum = 0, cnt = 0, chk;
struct scopeList *stack = pState->scope_stack;
struct scope_def *s = stack->entry + pScanner->scope_top;
/* basic resolution */
qry = NULL;
while (s->type != OBJ_DOCROOT_BITS) {
qry = HASHsearch(s->symbol_table, (Symbol) {.name = id}, HASH_FIND);
if (qry)
break;
s = stack->entry + s->parent;
}
/* not found, probably an attribute */
if (!qry)
return T_SIMPLE_REF;
/* check for enums */
sym = qry;
while (qry) {
if (!strcasecmp(qry->name, id)) {
cnt++;
if (qry->ref_tok == T_ENUMERATION_REF)
cnt_enum++;
}
qry = qry->next;
}
chk = cnt - cnt_enum;
if (chk > 1 || (!chk && cnt_enum > 1)) {
yyerror("conflicting token types for id '%s'", pScanner->lineno, id);
}
is_enum = chk > 0 ? false : true;
qry = sym;
while (qry) {
if (!strcasecmp(sym->name, id)) {
if ((!is_enum && qry->ref_tok != T_ENUMERATION_REF) ||
(is_enum && qry->ref_tok == T_ENUMERATION_REF))
break;
}
qry = qry->next;
}
return qry->ref_tok;
}
+130
View File
@@ -0,0 +1,130 @@
#ifndef __LEXSUPPORT_H
#define __LEXSUPPORT_H
#include <stdlib.h>
#include <stdbool.h>
#include "bstrlib.h"
#include "express/expbasic.h"
#include "express/linklist.h"
#include "token_type.h"
#define yyerror_helper(fmt, lineno, ...) \
do { fprintf(stderr, "error, line %i: " fmt "\n", (lineno), __VA_ARGS__); exit(1); } while (0)
#define yyerror(...) yyerror_helper(__VA_ARGS__, 0)
struct intList {
int qty, mlen;
int *entry;
};
struct exp_scanner {
/* lexing pass / debug flag */
int mode;
bool debug;
/* start condition stack */
struct intList *cond_stack;
int cond_top;
/* pointers into the buffer and location */
unsigned char *cur, *lim, *tok, *ctx, *mrk;
int lineno;
/* buffer and input reference */
bstring buffer;
const char *filename;
/* flags for rules based scope */
bool in_explicit_attr, in_rules_clause, in_inverse_clause;
/* lexical scopes */
int scope_aux, scope_top;
/* token ref type */
int id_ref_typ;
/* scope type bits */
int scope_typ;
/* list of counters for brackets within each scope */
struct intList *brkt_nesting;
/* counter for anonymous scope names */
unsigned int anon_scope_cnt;
/* shared state - lexical scopes */
struct YYSTATE *state;
};
struct scope_def {
int parent;
Symbol symbol;
int type;
Hash_Table symbol_table;
ClientData clientData;
union {
struct Procedure_ * proc;
struct Function_ * func;
struct Rule_ * rule;
struct Entity_ * entity;
struct Schema_ * schema;
struct Express_ * express;
struct Increment_ * incr;
struct TypeHead_ * type;
/* TBD: struct Query_ * query; */
} u;
};
struct scopeList {
int qty, mlen;
struct scope_def *entry;
};
/* TODO: migrate definitions here? */
struct YYSTYPE;
struct YYSTATE {
int lineno; /* TODO: remove when parser rebuilds automatically */
struct scopeList *scope_stack;
};
struct kw_token_def {
const char *kw;
int token;
};
extern struct kw_token_def reserved_keywords[];
/* lemon doesn't provide a header */
void *yyparseAlloc(void * (*mallocptr)(size_t));
void yyparseFree(void *, void (*freeptr)(void *));
void yyparseInit(void *);
void yyparse(void *, int, struct YYSTYPE *, struct YYSTATE *);
void yyparseTrace(FILE *, char *);
struct exp_scanner *yylexAlloc();
void yylexFree(struct exp_scanner *);
int yylexInit(struct exp_scanner *, struct YYSTATE *, FILE *);
int yylex(struct exp_scanner *, struct YYSTYPE *);
void yylexTrace(struct exp_scanner *, bool);
void yylexReset(struct exp_scanner *s, int new_mode);
struct YYSTATE *yystateAlloc();
void yystateFree();
struct intList * intListCreate (void);
int intListDestroy (struct intList * il);
int intListAllocMin (struct intList * il, int msz);
struct scopeList * scopeListCreate (void);
int scopeListDestroy (struct scopeList * sl);
int scopeListAllocMin (struct scopeList * sl, int msz);
int scope_alloc(struct scopeList *stack, const char *typ, int tok);
void scope_push(struct YYSTATE *pState, int idx, struct exp_scanner *scanner);
int scope_pop(struct YYSTATE *state, struct exp_scanner *scanner);
int scope_find(struct YYSTATE *state, int itype, const char *sname, struct exp_scanner *scanner);
int resolve_symbol(struct YYSTATE *state, const char *sym, struct exp_scanner *scanner);
void add_symbol(struct scope_def *scope, const char *id, int tok, struct exp_scanner *pScanner);
#endif /* __LEXSUPPORT_H */
+5 -4
View File
@@ -7,8 +7,9 @@
#include "express/schema.h"
#include "express/type.h"
#include "symbol_impl.h"
struct freelist_head HASH_Table_fl;
struct freelist_head HASH_Element_fl;
struct freelist_head LINK_fl;
struct freelist_head LIST_fl;
@@ -53,9 +54,8 @@ struct freelist_head INCR_fl;
void MEMORYinitialize() {
_ALLOCinitialize();
ALLOCinitialize( &HASH_Table_fl, sizeof( struct Hash_Table_ ), 50, 50 );
ALLOCinitialize( &HASH_Element_fl, sizeof( struct Element_ ), 500, 100 );
ALLOCinitialize( &HASH_Table_fl, sizeof( struct Hash_Table_ ), 500, 100 );
ALLOCinitialize( &LINK_fl, sizeof( struct Link_ ), 500, 100 );
ALLOCinitialize( &LIST_fl, sizeof( struct Linked_List_ ), 100, 50 );
@@ -100,3 +100,4 @@ void MEMORYinitialize() {
}
+3 -3
View File
@@ -26,7 +26,7 @@ void populateAttrList( oaList & list, Entity ent ) {
LISTdo( ent->u.entity->attributes, attr, Variable ) {
bool unique = true;
for( unsigned int i = attrCount; i < list.size(); i++ ) {
if( 0 == strcasecmp( attr->name->symbol.name, list[i]->attr->name->symbol.name ) ) {
if(!strcasecmp( (char *) attr->name->symbol.name, (char *) list[i]->attr->name->symbol.name ) ) {
// an attr by this name exists in a supertype
// originally printed a warning here, but that was misleading - they have more uses than I thought
unique = false;
@@ -56,8 +56,8 @@ void dedupList( oaList & list ) {
oaList::iterator it, jt;
for( it = list.begin(); it != list.end(); it++ ) {
for( jt = it + 1; jt != list.end(); jt++ ) {
if( ( 0 == strcasecmp( ( * it )->attr->name->symbol.name, ( * jt )->attr->name->symbol.name ) ) &&
( 0 == strcasecmp( ( * it )->creator->symbol.name, ( * jt )->creator->symbol.name ) ) ) {
if( ( !strcasecmp( (char *) ( * it )->attr->name->symbol.name, (char *) ( * jt )->attr->name->symbol.name ) ) &&
( !strcasecmp( (char *) ( * it )->creator->symbol.name, (char *) ( * jt )->creator->symbol.name ) ) ) {
//fprintf( stderr, "erasing %s created by %s\n", ( * jt )->attr->name->symbol.name, ( * jt )->creator->symbol.name );
jt--;
list.erase( jt + 1 );
+92 -96
View File
@@ -125,10 +125,10 @@ Type TYPE_retrieve_aggregate( Type t_select, Type t_agg ) {
** \note the macro 'EXPresolve' calls this function after checking if expr is already resolved
*/
void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
Symbol *ep;
Function f = 0;
Symbol * sym;
void *x;
Entity e;
Entity ent;
Type t;
bool func_args_checked = false;
@@ -137,18 +137,19 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
*/
switch( expr->type->u.type->body->type ) {
case funcall_:
/* TODO: no longer true - now the parser sees them as funcall_! */
/* functions with no arguments get handled elsewhere */
/* because the parser sees them just like attributes */
x = SCOPEfind( scope, expr->symbol.name,
ep = SCOPEfind(scope, expr->symbol.name,
SCOPE_FIND_FUNCTION | SCOPE_FIND_ENTITY );
if( !x ) {
if( !ep ) {
ERRORreport_with_symbol(UNDEFINED_FUNC, &expr->symbol, expr->symbol.name );
resolve_failed( expr );
break;
}
if( ( DICT_type != OBJ_FUNCTION ) && ( DICT_type != OBJ_ENTITY ) ) {
sym = OBJget_symbol( x, DICT_type );
if (ep->type != OBJ_FUNCTION && ep->type != OBJ_ENTITY) {
sym = OBJget_symbol( ep->data, ep->type );
ERRORreport_with_symbol(FUNCALL_NOT_A_FUNCTION, &expr->symbol, sym->name );
resolve_failed( expr );
break;
@@ -156,17 +157,17 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
/* original code accepted rules, too? */
/* entities are treated like implicit constructor functions */
if( DICT_type == OBJ_ENTITY ) {
if( ep->type == OBJ_ENTITY ) {
Type self_old = self; /* save previous in the unlikely but possible case that
* SELF is in a derived initialization of an entity */
e = ( Entity )x;
self = e->u.entity->type;
ent = ( Entity ) ep->data;
self = ent->u.entity->type;
/* skip parameter resolution for now */
/* ARGresolve();*/
expr->return_type = e->u.entity->type;
expr->return_type = ent->u.entity->type;
self = self_old; /* restore old SELF */
} else {
f = ( Function )x;
f = ( Function ) ep->data;
expr->return_type = f->u.func->return_type;
/* do argument typechecking here if requested */
@@ -211,7 +212,7 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
/* add function or entity as first element of list */
LISTadd_first( expr->u.list, x );
#endif
expr->u.funcall.function = ( struct Scope_ * ) x;
expr->u.funcall.function = ( struct Scope_ * ) ep->data;
resolved_all( expr );
break;
@@ -229,37 +230,26 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
resolved_all( expr );
break;
case identifier_:
x = 0;
/* assume it's a variable/attribute */
if( !x ) {
x = VARfind( scope, expr->symbol.name, 0 );
}
ep = VARfind( scope, expr->symbol.name );
/* if not found as a variable, try as function, etc ... */
if( !x ) {
x = SCOPEfind( scope, expr->symbol.name,
SCOPE_FIND_ANYTHING );
if( !ep ) {
ep = SCOPEfind( scope, expr->symbol.name, SCOPE_FIND_ANYTHING );
}
/* Not all enums have `typecheck->u.type->body->type` == `enumeration_` - ?! */
if( !x ) {
if (!ep) {
Scope enumscope = scope;
while( 1 ) {
while (1) {
/* look up locally, then go through the superscopes */
x = DICTlookup( enumscope->enum_table, expr->symbol.name );
if( x ) {
ep = HASHsearch(enumscope->enum_table, (Symbol) {.name = expr->symbol.name}, HASH_FIND);
if (ep || enumscope->type == OBJ_SCHEMA)
break;
}
if( enumscope->type == OBJ_SCHEMA ) {
/* if we get here, this means that we've looked through all scopes */
x = 0;
break;
}
enumscope = enumscope->superscope;
}
}
if( !x ) {
if( !ep ) {
if( typecheck == Type_Unknown ) {
return;
} else {
@@ -268,9 +258,9 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
break;
}
}
switch( DICT_type ) {
switch( ep->type ) {
case OBJ_VARIABLE:
expr->u.variable = ( Variable )x;
expr->u.variable = ( Variable ) ep->data;
#if 0
/* gee, I don't see what variables have to go through this right here */
VARresolve_expressions( expr->u.variable, scope );
@@ -287,28 +277,28 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
resolved_all( expr );
break;
case OBJ_ENTITY:
expr->return_type = expr->type = ( ( Entity )x )->u.entity->type;
expr->return_type = expr->type = ( ( Entity )ep->data )->u.entity->type;
/* entity may not actually be resolved by now */
/* but I don't think that's a problem */
resolved_all( expr );
break;
case OBJ_EXPRESSION:
/* so far only enumerations get returned this way */
expr->u.expression = ( Expression )x;
expr->type = expr->return_type = ( ( Expression )x )->type;
expr->u.expression = ( Expression ) ep->data;
expr->type = expr->return_type = ( ( Expression )ep->data )->type;
resolved_all( expr );
break;
case OBJ_FUNCTION:
/* functions with no args end up here because the */
/* parser doesn't know any better */
expr->u.list = LISTcreate();
LISTadd_last( expr->u.list, x );
LISTadd_last( expr->u.list, ep->data );
expr->type = Type_Funcall;
expr->return_type = ( ( Function )x )->u.func->return_type;
expr->return_type = ( ( Function ) ep->data )->u.func->return_type;
/* function may not actually be resolved by now */
/* but I don't think that's a problem */
if( ( ( Function )x )->u.func->pcount != 0 ) {
if( ( ( Function ) ep->data )->u.func->pcount != 0 ) {
ERRORreport_with_symbol(WRONG_ARG_COUNT, &expr->symbol, expr->symbol.name, 0,
f->u.func->pcount );
resolve_failed( expr );
@@ -318,8 +308,8 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
break;
case OBJ_TYPE:
/* enumerations can appear here, I don't know about others */
expr->type = ( Type )x;
expr->return_type = ( Type )x;
expr->type = ( Type ) ep->data;
expr->return_type = ( Type ) ep->data;
expr->symbol.resolved = expr->type->symbol.resolved;
break;
default:
@@ -396,12 +386,16 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
}
int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/, Linked_List * flat ) {
Symbol *ep;
Entity ent_ref;
int i = UNRESOLVED;
/* TODO: TYPEis... should be known by the parser */
if( !expr ) {
return ( RESOLVED );
} else if( TYPEis_expression( expr->type ) ) {
return RESOLVED;
}
if( TYPEis_expression( expr->type ) ) {
i = ENTITYresolve_subtype_expression( expr->e.op1, ent, flat );
i |= ENTITYresolve_subtype_expression( expr->e.op2, ent, flat );
} else if( TYPEis_oneof( expr->type ) ) {
@@ -410,13 +404,13 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/,
LISTod;
} else {
/* must be a simple entity reference */
ent_ref = ( Entity )SCOPEfind( ent->superscope, expr->symbol.name, SCOPE_FIND_ENTITY );
if( !ent_ref ) {
ep = SCOPEfind(ent->superscope, expr->symbol.name, SCOPE_FIND_ENTITY);
if( !ep ) {
ERRORreport_with_symbol(UNKNOWN_SUBTYPE, &ent->symbol,
expr->symbol.name, ent->symbol.name );
i = RESOLVE_FAILED;
} else if( DICT_type != OBJ_ENTITY ) {
Symbol * sym = OBJget_symbol( ent_ref, DICT_type );
} else if( ep->type != OBJ_ENTITY ) {
Symbol * sym = OBJget_symbol( ep->data, ep->type );
/* line number should really be on supertype name, */
/* but all we have easily is the entity line number */
ERRORreport_with_symbol(SUBTYPE_RESOLVE, &ent->symbol,
@@ -424,6 +418,7 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/,
i = RESOLVE_FAILED;
} else {
bool found = false;
ent_ref = ep->data;
/* link in to flat list */
if( !*flat ) {
@@ -474,8 +469,8 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/,
** Resolve all references in a type.
*/
void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) {
Symbol *ep;
Type type = *typeaddr;
Type ref_type;
TypeBody body = type->u.type->body;
Scope scope = type->superscope;
@@ -516,35 +511,29 @@ void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) {
}
} else {
/* simple type reference such as "T" */
/* this really is a hack. masking out only variables from */
/* the search is to support the (allowed) circumstance of */
/* an attribute or formal parameter whose name is the same */
/* as its type, i.e. "foo : foo". unfortunately, babys like */
/* local variables get thrown out with the bathwater. -snc */
ref_type = ( Type )SCOPEfind( scope, type->symbol.name,
SCOPE_FIND_ANYTHING ^ SCOPE_FIND_VARIABLE );
/* SCOPE_FIND_TYPE | SCOPE_FIND_ENTITY);*/
if( !ref_type ) {
/* search in the parent scope, to avoid "foo : foo" name type conflicts */
ep = SCOPEfind(scope->superscope, type->symbol.name, SCOPE_FIND_TYPE | SCOPE_FIND_ENTITY );
if( !ep ) {
ERRORreport_with_symbol(UNDEFINED_TYPE, &type->symbol, type->symbol.name );
*typeaddr = Type_Bad; /* just in case */
resolve_failed( type );
} else if( DICT_type == OBJ_TYPE ) {
} else if( ep->type == OBJ_TYPE ) {
/* due to declarations of multiple attributes off of a */
/* single type ref, we have to use reference counts */
/* to safely deallocate the TypeHead. It's trivial to do */
/* but gaining back the memory isn't worth the CPU time. */
/* if (type->refcount--) TYPE_destroy(type); */
type = *typeaddr = ref_type;
type = *typeaddr = ep->data;
TYPEresolve( typeaddr ); /* addr doesn't matter here */
/* it will not be written through */
} else if( DICT_type == OBJ_ENTITY ) {
} else if( ep->type == OBJ_ENTITY ) {
/* if (type->refcount--) TYPE_destroy(type); see above */
type = *typeaddr = ( ( Entity )ref_type )->u.entity->type;
type = *typeaddr = ( ( Entity )ep->data )->u.entity->type;
} else {
ERRORreport_with_symbol(NOT_A_TYPE, &type->symbol, type->symbol.name,
OBJget_type( DICT_type ) );
OBJget_type( ep->type ) );
resolve_failed( type );
}
}
@@ -598,7 +587,7 @@ void VAR_resolve_types( Variable v ) {
ERRORreport_with_symbol(INVERSE_BAD_ENTITY,
&v->name->symbol, v->inverse_symbol->name );
} else {
attr = VARfind( type->u.type->body->entity, v->inverse_symbol->name, 1 );
attr = VARfind( type->u.type->body->entity, v->inverse_symbol->name);
if( attr ) {
v->inverse_attribute = attr;
failed |= is_resolve_failed( attr->name );
@@ -659,6 +648,7 @@ void CASE_ITresolve( Case_Item item, Scope scope, Statement statement ) {
}
void STMTresolve( Statement statement, Scope scope ) {
Symbol *ep;
/* scope is always the function/procedure/rule from SCOPEresolve_expressions_statements(); */
Scope proc;
@@ -698,17 +688,17 @@ void STMTresolve( Statement statement, Scope scope ) {
break;
case STMT_PCALL:
#define proc_name statement->symbol.name
proc = ( Scope )SCOPEfind( scope, proc_name,
SCOPE_FIND_PROCEDURE );
if( proc ) {
if( DICT_type != OBJ_PROCEDURE ) {
Symbol * newsym = OBJget_symbol( proc, DICT_type );
ep = SCOPEfind( scope, proc_name, SCOPE_FIND_PROCEDURE);
if( !ep ) {
ERRORreport_with_symbol(NO_SUCH_PROCEDURE, &statement->symbol, proc_name );
} else {
proc = ep->data;
if( ep->type != OBJ_PROCEDURE ) {
Symbol * newsym = OBJget_symbol( proc, ep->type );
ERRORreport_with_symbol(EXPECTED_PROC, &statement->symbol, proc_name, newsym->line );
} else {
statement->u.proc->procedure = proc;
}
} else {
ERRORreport_with_symbol(NO_SUCH_PROCEDURE, &statement->symbol, proc_name );
}
LISTdo( statement->u.proc->parameters, e, Expression )
EXPresolve( e, scope, Type_Dont_Care );
@@ -745,7 +735,7 @@ void STMTresolve( Statement statement, Scope scope ) {
}
}
static Variable ENTITY_get_local_attribute( Entity e, char * name ) {
static Variable ENTITY_get_local_attribute( Entity e, const char * name ) {
LISTdo( e->u.entity->attributes, a, Variable )
if( !strcmp( VARget_simple_name( a ), name ) ) {
return a;
@@ -755,10 +745,11 @@ static Variable ENTITY_get_local_attribute( Entity e, char * name ) {
}
void ENTITYresolve_expressions( Entity e ) {
Hash_Iterator it;
Symbol *ep;
Variable v;
int status = 0;
DictionaryEntry de;
char * sname;
const char * sname;
Entity sup;
if( print_objects_while_running & OBJ_ENTITY_BITS ) {
@@ -808,8 +799,9 @@ void ENTITYresolve_expressions( Entity e ) {
status |= is_resolve_failed( attr->name );
} LISTod;
DICTdo_type_init( e->symbol_table, &de, OBJ_VARIABLE );
while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
HASHdo_init( e->symbol_table, &it, OBJ_VARIABLE );
while( (ep = HASHdo( &it )) ) {
v = (Variable) ep->data;
if( !is_resolve_failed( v->name ) ) {
TYPEresolve_expressions( v->type, e );
if( v->initializer ) {
@@ -924,9 +916,9 @@ void ENTITYresolve_types( Entity e );
/** also resolves inheritance counts and sub/super consistency */
void SCOPEresolve_types( Scope s ) {
Hash_Iterator it;
Symbol *ep;
Variable var;
DictionaryEntry de;
void *x;
if( print_objects_while_running & OBJ_SCOPE_BITS &
OBJget_bits( s->type ) ) {
@@ -934,16 +926,16 @@ void SCOPEresolve_types( Scope s ) {
s->symbol.name, OBJget_type( s->type ) );
}
DICTdo_init( s->symbol_table, &de );
while( 0 != ( x = DICTdo( &de ) ) ) {
switch( DICT_type ) {
HASHdo_init( s->symbol_table, &it, '*' );
while( (ep = HASHdo( &it )) ) {
switch( ep->type ) {
case OBJ_TYPE:
if( ERRORis_enabled( SELECT_LOOP ) ) {
TYPEcheck_select_cyclicity( ( Type )x );
TYPEcheck_select_cyclicity( ( Type ) ep->data );
}
break;
case OBJ_VARIABLE: /* really constants */
var = ( Variable )x;
var = ( Variable ) ep->data;
/* before OBJ_BITS hack, we looked in s->superscope */
TYPEresolve( &var->type );
if( is_resolve_failed( var->type ) ) {
@@ -952,26 +944,26 @@ void SCOPEresolve_types( Scope s ) {
}
break;
case OBJ_ENTITY:
ENTITYcheck_missing_supertypes( ( Entity )x );
ENTITYresolve_types( ( Entity )x );
ENTITYcalculate_inheritance( ( Entity )x );
ENTITYcheck_missing_supertypes( ( Entity ) ep->data );
ENTITYresolve_types( ( Entity ) ep->data );
ENTITYcalculate_inheritance( ( Entity ) ep->data );
if( ERRORis_enabled( SUBSUPER_LOOP ) ) {
ENTITYcheck_subsuper_cyclicity( ( Entity )x );
ENTITYcheck_subsuper_cyclicity( ( Entity ) ep->data );
}
if( is_resolve_failed( ( Entity )x ) ) {
if( is_resolve_failed( ( Entity ) ep->data ) ) {
resolve_failed( s );
}
break;
case OBJ_SCHEMA:
if( is_not_resolvable( ( Schema )x ) ) {
if( is_not_resolvable( ( Schema ) ep->data ) ) {
break;
}
/*FALLTHRU*/
case OBJ_PROCEDURE:
case OBJ_RULE:
case OBJ_FUNCTION:
SCOPEresolve_types( ( Scope )x );
if( is_resolve_failed( ( Scope )x ) ) {
SCOPEresolve_types( ( Scope ) ep->data );
if( is_resolve_failed( ( Scope ) ep->data ) ) {
resolve_failed( s );
}
break;
@@ -986,6 +978,7 @@ void SCOPEresolve_types( Scope s ) {
/** for each supertype, find the entity it refs to */
void ENTITYresolve_supertypes( Entity e ) {
Symbol *ep;
Entity ref_entity;
if( print_objects_while_running & OBJ_ENTITY_BITS ) {
@@ -1003,17 +996,18 @@ void ENTITYresolve_supertypes( Entity e ) {
#endif
LISTdo( e->u.entity->supertype_symbols, sym, Symbol * ) {
ref_entity = ( Entity )SCOPEfind( e->superscope, sym->name, SCOPE_FIND_ENTITY );
if( !ref_entity ) {
ep = SCOPEfind( e->superscope, sym->name, SCOPE_FIND_ENTITY );
if( !ep ) {
ERRORreport_with_symbol(UNKNOWN_SUPERTYPE, sym, sym->name, e->symbol.name );
/* ENTITY_resolve_failed = 1;*/
resolve_failed( e );
} else if( DICT_type != OBJ_ENTITY ) {
Symbol * newsym = OBJget_symbol( ref_entity, DICT_type );
} else if( ep->type != OBJ_ENTITY ) {
Symbol * newsym = OBJget_symbol( ep->data, ep->type );
ERRORreport_with_symbol(SUPERTYPE_RESOLVE, sym, sym->name, newsym->line );
/* ENTITY_resolve_failed = 1;*/
resolve_failed( e );
} else {
ref_entity = ep->data;
bool found = false;
LISTadd_last( e->u.entity->supertypes, ref_entity );
@@ -1203,8 +1197,10 @@ int WHEREresolve( Linked_List list, Scope scope, int need_self ) {
}
}
#if 0
struct tag * TAGcreate_tags() {
extern int tag_count;
return( ( struct tag * )calloc( tag_count, sizeof( struct tag ) ) );
return( ( struct tag * ) sc_calloc( tag_count, sizeof( struct tag ) ) );
}
#endif
+27 -25
View File
@@ -7,10 +7,12 @@
#include "express/schema.h"
#include "express/resolve.h"
/********************************new****************************************/
void SCOPEresolve_subsupers( Scope scope ) {
DictionaryEntry de;
void *x;
char type;
Hash_Iterator it;
Symbol *ep;
Symbol * sym;
Type t;
@@ -20,27 +22,27 @@ void SCOPEresolve_subsupers( Scope scope ) {
scope->symbol.name, OBJget_type( scope->type ) );
}
DICTdo_init( scope->symbol_table, &de );
while( 0 != ( x = DICTdo( &de ) ) ) {
switch( type = DICT_type ) {
HASHdo_init( scope->symbol_table, &it, '*' );
while( (ep = HASHdo( &it )) ) {
switch( ep->type ) {
case OBJ_ENTITY:
ENTITYresolve_supertypes( ( Entity )x );
ENTITYresolve_subtypes( ( Entity )x );
ENTITYresolve_supertypes( ep->data );
ENTITYresolve_subtypes( ep->data );
break;
case OBJ_FUNCTION:
case OBJ_PROCEDURE:
case OBJ_RULE:
SCOPEresolve_subsupers( ( Scope )x );
SCOPEresolve_subsupers( ep->data );
break;
case OBJ_TYPE:
t = ( Type )x;
t = ( Type ) ep->data;
TYPEresolve( &t );
break;
default:
/* ignored everything else */
break;
}
sym = OBJget_symbol( x, type );
sym = OBJget_symbol( ep->data, ep->type );
if( is_resolve_failed_raw( sym ) ) {
resolve_failed( scope );
}
@@ -48,8 +50,8 @@ void SCOPEresolve_subsupers( Scope scope ) {
}
void SCOPEresolve_expressions_statements( Scope s ) {
DictionaryEntry de;
void *x;
Hash_Iterator it;
Symbol *ep;
Variable v;
if( print_objects_while_running & OBJ_SCOPE_BITS &
@@ -58,38 +60,38 @@ void SCOPEresolve_expressions_statements( Scope s ) {
s->symbol.name, OBJget_type( s->type ) );
}
DICTdo_init( s->symbol_table, &de );
while( 0 != ( x = DICTdo( &de ) ) ) {
switch( DICT_type ) {
HASHdo_init( s->symbol_table, &it, '*' );
while( (ep = HASHdo( &it )) ) {
switch( ep->type ) {
case OBJ_SCHEMA:
if( is_not_resolvable( ( Schema )x ) ) {
if( is_not_resolvable( ( Schema )ep->data ) ) {
break;
}
SCOPEresolve_expressions_statements( ( Scope )x );
SCOPEresolve_expressions_statements( ( Scope )ep->data );
break;
case OBJ_ENTITY:
ENTITYresolve_expressions( ( Entity )x );
ENTITYresolve_expressions( ( Entity )ep->data );
break;
case OBJ_FUNCTION:
ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.func->body );
ALGresolve_expressions_statements( ( Scope )ep->data, ( ( Scope )ep->data )->u.func->body );
break;
case OBJ_PROCEDURE:
ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.proc->body );
ALGresolve_expressions_statements( ( Scope )ep->data, ( ( Scope )ep->data )->u.proc->body );
break;
case OBJ_RULE:
ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.rule->body );
ALGresolve_expressions_statements( ( Scope )ep->data, ( ( Scope )ep->data )->u.rule->body );
WHEREresolve( RULEget_where( ( Scope )x ), ( Scope )x, 0 );
WHEREresolve( RULEget_where( ( Scope )ep->data ), ( Scope )ep->data, 0 );
break;
case OBJ_VARIABLE:
v = ( Variable )x;
v = ( Variable )ep->data;
TYPEresolve_expressions( v->type, s );
if( v->initializer ) {
EXPresolve( v->initializer, s, v->type );
}
break;
case OBJ_TYPE:
TYPEresolve_expressions( ( Type )x, s );
TYPEresolve_expressions( ( Type )ep->data, s );
break;
default:
/* ignored everything else */
+63 -46
View File
@@ -113,37 +113,56 @@ void SCHEMAadd_use( Schema cur_schema, Symbol * ref_schema, Symbol * old, Symbol
}
void SCHEMAdefine_reference( Schema schema, Rename * r ) {
Rename * old = 0;
char * name = ( r->nnew ? r->nnew : r->old )->name;
Rename *old;
Symbol e, *ep;
Symbol *sym;
if( !schema->u.schema->refdict ) {
schema->u.schema->refdict = DICTcreate( 20 );
} else {
old = ( Rename * )DICTlookup( schema->u.schema->refdict, name );
}
if( !old || ( DICT_type != OBJ_RENAME ) || ( old->object != r->object ) ) {
DICTdefine( schema->u.schema->refdict, name,
r, r->old, OBJ_RENAME );
schema->u.schema->refdict = HASHcreate();
}
sym = r->nnew ? r->nnew : r->old;
e = (Symbol) {.name = sym->name, .data = r, .type = OBJ_RENAME};
ep = HASHsearch(schema->u.schema->refdict, e, HASH_FIND);
old = !ep ? NULL : ep->data;
if( !ep || ep->type != OBJ_RENAME || old->object != r->object ) {
/* TODO: evaluate difference in behaviour with DICTdefine
* if there's already an OBJ_RENAME, then DICTdefine would replace it
* - this will instead append another
*/
HASHsearch(schema->u.schema->refdict, e, HASH_INSERT);
}
}
void SCHEMAdefine_use( Schema schema, Rename * r ) {
Rename * old = 0;
char * name = ( r->nnew ? r->nnew : r->old )->name;
Rename * old;
Symbol *ep, e;
Symbol *sym;
if( !schema->u.schema->usedict ) {
schema->u.schema->usedict = DICTcreate( 20 );
} else {
old = ( Rename * )DICTlookup( schema->u.schema->usedict, name );
schema->u.schema->usedict = HASHcreate();
}
if( !old || ( DICT_type != OBJ_RENAME ) || ( old->object != r->object ) ) {
DICTdefine( schema->u.schema->usedict, name,
r, r->old, OBJ_RENAME );
sym = r->nnew ? r->nnew : r->old;
e = (Symbol) {.name = sym->name, .data = r, .type = OBJ_RENAME};
ep = HASHsearch(schema->u.schema->usedict, e, HASH_FIND);
old = !ep ? NULL : ep->data;
if( !ep || ep->type != OBJ_RENAME || old->object != r->object ) {
/* TODO: evaluate difference in behaviour with DICTdefine
* if there's already an OBJ_RENAME, then DICTdefine would replace it
* - this will instead append another
*/
HASHsearch(schema->u.schema->usedict, e, HASH_INSERT);
}
}
static void SCHEMA_get_entities_use( Scope scope, Linked_List result ) {
DictionaryEntry de;
Hash_Iterator it;
Symbol *ep;
Rename * rename;
if( scope->search_id == __SCOPE_search_id ) {
@@ -159,9 +178,10 @@ static void SCHEMA_get_entities_use( Scope scope, Linked_List result ) {
/* partially USE'd schema */
if( scope->u.schema->usedict ) {
DICTdo_init( scope->u.schema->usedict, &de );
while( 0 != ( rename = ( Rename * )DICTdo( &de ) ) ) {
LISTadd_last( result, rename->object );
HASHdo_init(scope->u.schema->usedict, &it, '*');
while ( (ep = HASHdo(&it)) ) {
rename = ep->data;
LISTadd_last(result, rename->object);
}
}
}
@@ -180,7 +200,8 @@ Linked_List SCHEMAget_entities_use( Scope scope ) {
/** return ref'd entities */
void SCHEMA_get_entities_ref( Scope scope, Linked_List result ) {
Rename * rename;
DictionaryEntry de;
Hash_Iterator it;
Symbol *ep;
if( scope->search_id == __SCOPE_search_id ) {
return;
@@ -196,11 +217,10 @@ void SCHEMA_get_entities_ref( Scope scope, Linked_List result ) {
LISTod
/* partially REF'd schema */
DICTdo_init( scope->u.schema->refdict, &de );
while( 0 != ( rename = ( Rename * )DICTdo( &de ) ) ) {
if( DICT_type == OBJ_ENTITY ) {
LISTadd_last( result, rename->object );
}
HASHdo_init(scope->u.schema->refdict, &it, OBJ_ENTITY);
while ( (ep = HASHdo(&it)) ) {
rename = ep->data;
LISTadd_last(result, rename->object);
}
}
@@ -219,31 +239,28 @@ Linked_List SCHEMAget_entities_ref( Scope scope ) {
* look up an attribute reference
* if strict false, anything can be returned, not just attributes
*/
Variable VARfind( Scope scope, char * name, int strict ) {
Variable result;
Symbol *VARfind( Scope scope, const char * name ) {
Symbol *ep;
/* first look up locally */
switch( scope->type ) {
case OBJ_ENTITY:
result = ENTITYfind_inherited_attribute( scope, name, 0 );
if( result ) {
if( strict && ( DICT_type != OBJ_VARIABLE ) ) {
fprintf( stderr, "ERROR: strict && ( DICT_type != OBJ_VARIABLE )\n" );
}
return result;
}
ep = ENTITYfind_inherited_attribute(scope, name, NULL);
/* strict is checked when parsing */
if (ep)
return ep;
break;
case OBJ_INCREMENT:
case OBJ_QUERY:
case OBJ_ALIAS:
result = ( Variable )DICTlookup( scope->symbol_table, name );
if( result ) {
if( strict && ( DICT_type != OBJ_VARIABLE ) ) {
fprintf( stderr, "ERROR: strict && ( DICT_type != OBJ_VARIABLE )\n" );
}
return result;
}
return( VARfind( scope->superscope, name, strict ) );
ep = HASHsearch(scope->symbol_table, (Symbol) {.name = name, .type = OBJ_VARIABLE}, HASH_FIND);
/* strict is checked when parsing */
if (ep)
return ep;
ep = VARfind( scope->superscope, name );
if (ep)
return ep;
}
return 0;
return NULL;
}
+83 -80
View File
@@ -39,6 +39,8 @@
* prettied up interface to print_objects_when_running
*/
#include "sc_memmgr.h"
#define SCOPE_C
#include "express/scope.h"
#include "express/resolve.h"
@@ -50,12 +52,12 @@ void SCOPEinitialize( void ) {
* \sa SCOPEget_entities()
*/
void SCOPE_get_entities( Scope scope, Linked_List result ) {
DictionaryEntry de;
void *x;
Hash_Iterator it;
Symbol *ep;
DICTdo_type_init( scope->symbol_table, &de, OBJ_ENTITY );
while( 0 != ( x = DICTdo( &de ) ) ) {
LISTadd_last( result, x );
HASHdo_init( scope->symbol_table, &it, OBJ_ENTITY );
while ( (ep = HASHdo(&it)) ) {
LISTadd_last(result, ep->data);
}
}
@@ -63,12 +65,12 @@ void SCOPE_get_entities( Scope scope, Linked_List result ) {
* \sa SCOPEget_functions()
*/
void SCOPE_get_functions( Scope scope, Linked_List result ) {
DictionaryEntry de;
void *x;
Hash_Iterator it;
Symbol *ep;
DICTdo_type_init( scope->symbol_table, &de, OBJ_FUNCTION );
while( 0 != ( x = DICTdo( &de ) ) ) {
LISTadd_last( result, x );
HASHdo_init( scope->symbol_table, &it, OBJ_FUNCTION );
while ( (ep = HASHdo(&it)) ) {
LISTadd_last(result, ep->data);
}
}
/**
@@ -84,12 +86,12 @@ Linked_List SCOPEget_functions( Scope scope ) {
* \sa SCOPEget_rules()
*/
void SCOPE_get_rules( Scope scope, Linked_List result ) {
DictionaryEntry de;
void *x;
DICTdo_type_init( scope->symbol_table, &de, OBJ_RULE );
while( 0 != ( x = DICTdo( &de ) ) ) {
LISTadd_last( result, x );
Hash_Iterator it;
Symbol *ep;
HASHdo_init( scope->symbol_table, &it, OBJ_RULE );
while ( (ep = HASHdo(&it)) ) {
LISTadd_last(result, ep->data);
}
}
/**
@@ -121,17 +123,20 @@ Linked_List SCOPEget_entities( Scope scope ) {
/**
* \sa SCOPEget_entities_superclass_order()
*/
void SCOPE_dfs( Dictionary symbols, Entity root, Linked_List result ) {
void SCOPE_dfs( Hash_Table symbols, Entity root, Linked_List result ) {
Symbol *ep;
Entity ent;
if( ( ENTITYget_mark( root ) != ENTITY_MARK ) ) {
ENTITYput_mark( root, ENTITY_MARK );
LISTdo( ENTITYget_supertypes( root ), super, Entity )
/* if super explicitly defined in scope, recurse. */
/* this chops out USEd and REFd entities */
if( ( ent = ( Entity )DICTlookup( symbols, ENTITYget_name( super ) ) ) != ENTITY_NULL ) {
SCOPE_dfs( symbols, ent, result );
}
/* if super explicitly defined in scope, recurse. */
/* this chops out USEd and REFd entities */
ep = HASHsearch(symbols, (Symbol) {.name = ENTITYget_name( super )}, HASH_FIND);
if (ep) {
ent = ep->data;
SCOPE_dfs( symbols, ent, result);
}
LISTod
LISTadd_last( result, root );
}
@@ -148,13 +153,17 @@ void SCOPE_dfs( Dictionary symbols, Entity root, Linked_List result ) {
*/
Linked_List SCOPEget_entities_superclass_order( Scope scope ) {
Linked_List result;
DictionaryEntry de;
Hash_Iterator it;
Symbol *ep;
result = LISTcreate();
++ENTITY_MARK;
SCOPEdo_entities( scope, e, de )
SCOPE_dfs( scope->symbol_table, e, result );
SCOPEod;
HASHdo_init(scope->symbol_table, &it, OBJ_ENTITY);
while( (ep = HASHdo(&it)) ) {
SCOPE_dfs( scope->symbol_table, ep->data, result );
}
return result;
}
@@ -163,21 +172,23 @@ Linked_List SCOPEget_entities_superclass_order( Scope scope ) {
* note that object found is not actually checked, only because
* caller is in a better position to describe the error with context
*/
void *SCOPEfind( Scope scope, char * name, int type ) {
extern Dictionary EXPRESSbuiltins; /* procedures/functions */
void *x;
extern Hash_Table EXPRESSbuiltins;
Symbol *SCOPEfind( Scope scope, const char * name, int type_mask ) {
Symbol *ep;
/* TODO: check, this looks like it should be in the parser */
__SCOPE_search_id++;
ep = SCOPE_find( scope, name, type_mask );
if ( ep )
return ep;
x = SCOPE_find( scope, name, type );
if( x ) {
return x;
}
/* TODO: rework (order & check overall logic) */
if ( type_mask & (SCOPE_FIND_FUNCTION | SCOPE_FIND_PROCEDURE) )
ep = HASHsearch(EXPRESSbuiltins, (Symbol) {.name = name}, HASH_FIND);
if( type & ( SCOPE_FIND_FUNCTION | SCOPE_FIND_PROCEDURE ) ) {
x = DICTlookup( EXPRESSbuiltins, name );
}
return x;
return ep;
}
@@ -186,69 +197,61 @@ void *SCOPEfind( Scope scope, char * name, int type ) {
* the supertype/subtype hierarchy
* EH??? -> lookup an object when the current scope is not a schema
*/
void *SCOPE_find( Scope scope, char * name, int type ) {
void *result;
Symbol *SCOPE_find( Scope scope, const char * name, int type_mask ) {
Symbol *ep;
Rename * rename;
if( scope->search_id == __SCOPE_search_id ) {
if ( scope->search_id == __SCOPE_search_id )
return 0;
}
scope->search_id = __SCOPE_search_id;
/* go up the superscopes, looking for object */
while( 1 ) {
/* first look up locally */
result = DICTlookup( scope->symbol_table, name );
if( result && OBJtype_is_oneof( DICT_type, type ) ) {
return result;
}
if( scope->type == OBJ_SCHEMA ) {
break;
}
for (;; scope = scope->superscope) {
ep = HASHsearch(scope->symbol_table, (Symbol) {.name = name}, HASH_FIND);
if (ep && OBJtype_is_oneof( ep->type, type_mask ))
return ep->data;
scope = scope->superscope;
if (scope->type == OBJ_SCHEMA)
break;
}
if( type & ( SCOPE_FIND_ENTITY | SCOPE_FIND_TYPE ) ) {
if ( type_mask & (SCOPE_FIND_ENTITY | SCOPE_FIND_TYPE) ) {
/* Occurs in a fully USE'd schema? */
LISTdo( scope->u.schema->use_schemas, schema, Schema )
/* follow chain'd USEs */
if( schema == 0 ) {
continue;
}
result = SCOPE_find( schema, name, type );
if( result ) {
return( result );
}
/* follow chain'd USEs */
if (!schema)
continue;
ep = SCOPE_find( schema, name, type_mask );
if (ep)
return ep;
LISTod;
/* Occurs in a partially USE'd schema? */
rename = ( Rename * )DICTlookup( scope->u.schema->usedict, name );
if( rename ) {
DICT_type = rename->type;
return( rename->object );
}
/* TODO: need to resolve the rename */
ep = HASHsearch(scope->u.schema->usedict, (Symbol) {.name = name}, HASH_FIND);
rename = !ep ? NULL : ep->data;
if( rename && OBJtype_is_oneof(rename->type, type_mask) )
return rename->object;
}
/* Occurs in a fully REF'd schema? */
LISTdo( scope->u.schema->ref_schemas, schema, Schema )
if( schema == 0 ) {
continue;
}
result = DICTlookup( schema->symbol_table, name );
if( result ) {
return result;
} else {
continue; /* try another schema */
}
if (!schema)
continue;
ep = HASHsearch(schema->symbol_table, (Symbol) {.name = name}, HASH_FIND);
if (ep && OBJtype_is_oneof( ep->type, type_mask ))
return ep->data;
LISTod;
/* Occurs in a partially REF'd schema? */
rename = ( Rename * )DICTlookup( scope->u.schema->refdict, name );
if( rename ) {
DICT_type = rename->type;
return( rename->object );
}
/* TODO: need to resolve the rename */
ep = HASHsearch(scope->u.schema->refdict, (Symbol) {.name = name}, HASH_FIND);
rename = !ep ? NULL : ep->data;
if( rename && OBJtype_is_oneof(rename->type, type_mask) )
return rename->object;
return 0;
}
+4 -3
View File
@@ -48,7 +48,6 @@ Statement STATEMENT_SKIP = STATEMENT_NULL;
Statement STMTcreate( int type ) {
Statement s;
s = STMT_new();
SYMBOLset( s );
s->type = type;
return s;
}
@@ -173,11 +172,13 @@ Statement ALIAScreate( Scope scope, Variable variable, Linked_List statements )
*/
Scope INCR_CTLcreate( Symbol * control, Expression start,
Expression end, Expression increment ) {
Symbol sym;
Scope s = SCOPEcreate_tiny( OBJ_INCREMENT );
Expression e = EXPcreate_from_symbol( Type_Attribute, control );
Variable v = VARcreate( e, Type_Number );
DICTdefine( s->symbol_table, control->name,
v, control, OBJ_VARIABLE );
sym = (Symbol) {.name = control->name, .data = v, .type = OBJ_VARIABLE};
HASHsearch(s->symbol_table, sym, HASH_INSERT);
s->u.incr = INCR_new();
s->u.incr->init = start;
s->u.incr->end = end;
+14
View File
@@ -0,0 +1,14 @@
#ifndef __SYMBOL_IMPL_H_
#define __SYMBOL_IMPL_H_
#include "express/symbol.h"
inline struct Symbol_ *SYMBOL_new() {
return ALLOC_new(&SYMBOL_fl);
}
inline void SYMBOL_destroy(struct Symbol_ *x) {
ALLOC_destroy(&SYMBOL_fl,(Freelist *)x);
}
#endif /* __SYMBOL_IMPL_H_ */
+46 -8
View File
@@ -1,7 +1,7 @@
include_directories(..)
if(SC_GENERATE_LP_SOURCES)
include_directories("${PERPLEX_ExpScanner_INCLUDE_DIR}" "${LEMON_ExpParser_INCLUDE_DIR}")
include_directories("${RE2C_ExpScanner_INCLUDE_DIR}" "${LEMON_ExpParser_INCLUDE_DIR}")
endif(SC_GENERATE_LP_SOURCES)
set(EXPRESS_CORE_OBJ
@@ -21,7 +21,6 @@ set(EXPRESS_CORE_OBJ
$<TARGET_OBJECTS:objlib_alg_c>
# deprecated
$<TARGET_OBJECTS:objlib_dict_c>
$<TARGET_OBJECTS:objlib_info_c>
)
@@ -59,20 +58,59 @@ add_test(NAME scope_find COMMAND test_scope scope_find)
add_executable(test_type driver.c test_type.c $<TARGET_OBJECTS:objlib_type_c> ${EXPRESS_CORE_OBJ})
add_test(NAME type_create_user_defined_tag COMMAND test_type type_create_user_defined_tag)
add_test(NAME build_check_express
add_executable(check-hash "hash_test.c;../hash.c;../../auxlib/bstrlib.c")
set_property(TARGET check-hash PROPERTY COMPILE_DEFINITIONS "HASH_TESTING;HASH_DEBUG")
target_link_libraries(check-hash "m")
add_test(NAME test_hash_impl
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target check-express
--config $<CONFIGURATION>
COMMAND $<TARGET_FILE:check-hash> "${CMAKE_CURRENT_SOURCE_DIR}/hash_names.txt"
)
add_test(NAME build_check_express
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} --build .
--target check-express
--config $<CONFIGURATION>
)
set(SHARED_SRC ../lexsupport.c ../hash.c ../../auxlib/bstrlib.c)
add_executable(check-scanner scanner_test.c $<TARGET_OBJECTS:objlib_expscan_c> ${SHARED_SRC})
add_dependencies(check-scanner express)
add_executable(check-parser
parser_test.c
$<TARGET_OBJECTS:objlib_expscan_c>
$<TARGET_OBJECTS:objlib_expparse_c>
${SHARED_SRC})
add_dependencies(check-parser express)
set_property(TARGET check-scanner check-parser
APPEND PROPERTY INCLUDE_DIRECTORIES "${RE2C_ExpScanner_INCLUDE_DIR}")
set_property(TARGET check-scanner check-parser
APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_ExpParser_INCLUDE_DIR}")
set_property(TARGET check-scanner check-parser
PROPERTY COMPILE_DEFINITIONS "HASH_TESTING")
file(GLOB unit_tests RELATIVE "${CMAKE_BINARY_DIR}" "../../../test/unitary_schemas/*.exp")
file(GLOB extended_tests RELATIVE "${CMAKE_BINARY_DIR}" "../../../data/*/*.exp")
foreach(expfile ${unit_tests} ${extended_tests})
get_filename_component(id_suffix "${expfile}" NAME_WE)
add_test(NAME "test_scanner:${id_suffix}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND $<TARGET_FILE:check-scanner> "${expfile}")
add_test(NAME "test_parser:${id_suffix}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND $<TARGET_FILE:check-parser> "${expfile}")
endforeach()
add_test(NAME test_plib_parse_err
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND $<TARGET_FILE:check-express> "${CMAKE_CURRENT_SOURCE_DIR}/plib_parse_err.exp"
)
set_tests_properties( test_plib_parse_err PROPERTIES DEPENDS "build_check_express;$<TARGET_NAME:check-express>" )
set_tests_properties( test_plib_parse_err build_check_express PROPERTIES LABELS parser )
set_tests_properties( test_plib_parse_err PROPERTIES DEPENDS "test_hash_impl" )
set_tests_properties( test_plib_parse_err test_plib_parse_err PROPERTIES LABELS parser )
sc_addexec(print_schemas SOURCES ../fedex.c print_schemas.c LINK_LIBRARIES express base)
sc_addexec(print_attrs SOURCES ../fedex.c print_attrs.c LINK_LIBRARIES express base)
File diff suppressed because it is too large Load Diff
+222
View File
@@ -0,0 +1,222 @@
#include <stdio.h>
#include <stdlib.h>
#include "bstrlib.h"
#include "express/hash.h"
#define error_helper(fmt, ...) \
do { fprintf(stderr, "error, line %i: " fmt "\n", __LINE__, __VA_ARGS__); exit(1); } while (0)
#define error(...) error_helper(__VA_ARGS__, 0)
int main(int argc, char *argv[]) {
FILE *fp;
bstring buf, id;
struct bstrList *testdata;
unsigned int i, qty;
Hash_Table tbl;
Symbol *ep;
Symbol e;
Hash_Iterator it;
if (argc < 2)
error("no input files");
fp = fopen(argv[1], "r");
if (!fp)
error("failed to open input!");
buf = bread((bNread) fread, fp);
if (!buf)
error("failed to read input!");
if (fclose(fp))
error("failed to correctly close input file!");
testdata = bsplit(buf, '\n');
qty = testdata->qty;
tbl = HASHcreate();
/* HASHsearch INSERT */
for (i = 0; i < testdata->qty; i++) {
id = testdata->entry[i];
if (id->slen > 0 && btrimws(id) == BSTR_ERR)
error("btrimws failed?!");
if (!id->slen) {
qty--;
continue;
}
ep = HASHsearch(tbl, (Symbol) {.name = id->data, .data = id}, HASH_INSERT);
if (!ep)
error("HASHsearch HASH_INSERT failed!");
}
/* HASHsearch FIND */
for (i = 0; i < testdata->qty; i++) {
id = testdata->entry[i];
if (!id->slen)
continue;
ep = HASHsearch(tbl, (Symbol) {.name = id->data, .data = id}, HASH_FIND);
if (!ep)
error("HASHsearch HASH_FIND failed!");
}
/* HASHdo */
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
if (i != qty)
error("HASHdo failed! expected: %d, got: %d", qty, i);
if (qty != 6512)
error("HASHdelete tests require a specific test input file, and build parameters");
/* expected collisions
* [change_action,
* device_terminal_map,
* fea_column_normalised_orthotropic_symmetric_tensor4_3d,
* fill_area_style_tile_symbol_with_style,
* ifcorthogonalcomplement,
* time_interval_with_bounds]
*
*/
e = (Symbol) {.name = "fea_column_normalised_orthotropic_symmetric_tensor4_3d"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (#, #, x, #, #, #, #), expected %d, got %d", qty, i);
e = (Symbol) {.name = "ifcorthogonalcomplement"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (#, #, _, #, #, x, #), expected %d, got %d", qty, i);
/*
* expected collisions
* [evaluation_product_definition,
* ifcfurniture,
* ifcreloverridesproperties,
* language,
* physical_state_domain]
*/
e = (Symbol) {.name = "ifcfurniture"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (#, x, #, #, #), expected %d, got %d", qty, i);
e = (Symbol) {.name = "physical_state_domain"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (#, _, #, #, x), expected %d, got %d", qty, i);
/*
* [action_resource_relationship,
* annotation_occurrence_relationship,
* erroneous_data,
* ifclinearvelocitymeasure]
*/
e = (Symbol) {.name = "action_resource_relationship"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (x, #, #, #), expected %d, got %d", qty, i);
/*
* [choose_representation_context_identifier,
* dependent_instantiable_text_style]
*/
e = (Symbol) {.name = "choose_representation_context_identifier"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (x, #), expected %d, got %d", qty, i);
e = (Symbol) {.name = "dependent_instantiable_text_style"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (_, x), expected %d, got %d", qty, i);
/*
* [connector_based_interconnect_definition]
*/
e = (Symbol) {.name = "connector_based_interconnect_definition"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
qty--;
if (i != qty)
error("HASHdelete failed (x,), expected %d, got %d", qty, i);
e = (Symbol) {.name = "connector_based_interconnect_definition"};
HASHdelete(tbl, &e);
i = 0;
HASHdo_init(tbl, &it, OBJ_ANY);
while (HASHdo(&it))
i++;
if (i != qty)
error("HASHdelete failed (_,), expected %d, got %d", qty, i);
HASHdestroy(tbl);
bstrListDestroy(testdata);
bdestroy(buf);
exit(0);
}
+33
View File
@@ -0,0 +1,33 @@
#include <stdlib.h>
#include "lexsupport.h"
int main(int argc, char *argv[])
{
int tok;
struct YYSTYPE yylval;
struct YYSTATE *pState;
void *pParser, *pScanner;
FILE *fp;
if (argc < 2)
yyerror("no input files!", 0);
fp = fopen(argv[1], "r");
if (!fp)
yyerror("failed to open input!", 0);
pScanner = yylexAlloc();
pParser = yyparseAlloc(malloc);
pState = yystateAlloc();
yylexInit(pScanner, pState, fp);
// yyparseTrace(stderr, "dbg: ");
while ((tok = yylex(pScanner, &yylval))) {
yyparse(pParser, tok, &yylval, pState);
}
yyparse(pParser, 0, &yylval, pState);
exit(0);
}
+13 -9
View File
@@ -16,13 +16,16 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <express/info.h>
#include <express/express.h>
#include <express/scope.h>
#include <express/variable.h>
#include "ordered_attrs.h"
#include <assert.h>
#include "express/info.h"
#include "express/express.h"
#include "express/scope.h"
#include "express/variable.h"
#include "express/hash.h"
#include "ordered_attrs.h"
char * entityName, _buf[512] = { 0 };
/** prints usage info specific to print_attrs */
@@ -70,13 +73,14 @@ void print_attrs( Entity ent ) {
}
void find_and_print( Express model ) {
DictionaryEntry de;
Hash_Iterator it;
Schema s;
Entity e;
DICTdo_init( model->symbol_table, &de );
while( 0 != ( s = (Schema) DICTdo( &de ) ) ) {
HASHdo_init(model->symbol_table, &it, OBJ_ANY);
while((s = HASHdo(&it))) {
printf( "Schema %s\n", s->symbol.name );
e = (Entity) DICTlookup( s->symbol_table, entityName );
e = HASHsearch(s->symbol_table, (Symbol) {.name = entityName}, HASH_FIND);
if( e ) {
print_attrs( e );
}
+4 -3
View File
@@ -13,16 +13,17 @@
# include <unistd.h>
#endif
#include "express/express.h"
#include "express/hash.h"
void
print_schemas( Express model ) {
DictionaryEntry de;
Hash_Iterator it;
Schema s;
printf( "File: %s\n ", model->u.express->filename );
DICTdo_init( model->symbol_table, &de );
while( 0 != ( s = (Schema) DICTdo( &de ) ) ) {
HASHdo_init( model->symbol_table, &it, OBJ_ANY );
while((s = HASHdo(&it))) {
printf( "%s", s->symbol.name );
}
printf( "\n" );
+33
View File
@@ -0,0 +1,33 @@
#include "lexsupport.h"
/* stubs */
Symbol * SYMBOLcreate( char * name, int ref_tok, int line, const char * filename ) {
return NULL;
}
int main(int argc, char **argv)
{
FILE *fp;
struct YYSTATE *pState;
struct exp_scanner *pScanner;
YYSTYPE yylval;
if (argc < 2) {
fprintf(stderr, "no input files\n");
return 1;
}
fp = fopen(argv[1], "r");
if (!fp)
yyerror("failed to open input!", 0);
pScanner = yylexAlloc();
pState = yystateAlloc();
yylexInit(pScanner, pState, fp);
while(yylex(pScanner, &yylval) != 0)
;
fclose(fp);
}
+58 -39
View File
@@ -5,9 +5,10 @@
/* core */
#include "express/hash.h"
#include "express/linklist.h"
#include "expparse.h"
/* non-core */
#include "express/dict.h"
#include "express/hash.h"
#include "express/variable.h"
#include "driver.h"
@@ -21,10 +22,6 @@ char * EXPRESSprogram_name;
int yylineno;
int __SCOPE_search_id;
Error ERROR_warn_unsupported_lang_feat;
Error WARNING_case_skip_label;
Error ERROR_undefined_attribute;
/*
* mock functions
*/
@@ -47,18 +44,23 @@ void setup() {
RESET_FAKE(EXP_resolve);
}
/* TODO: remove DICTlookup after eliminating DICT_type */
void EXP_resolve_type_handler(Expression exp, Scope cxt, Type typ) {
(void) typ;
Type res_typ = DICTlookup(cxt->symbol_table, exp->symbol.name);
exp->type = res_typ;
exp->return_type = res_typ;
Symbol *ep;
ep = HASHsearch(cxt->symbol_table, exp->symbol, HASH_FIND);
if (!ep)
return;
exp->type = ep->data;
exp->return_type = ep->data;
exp->symbol.resolved = RESOLVED;
}
int test_resolve_select_enum_member() {
Schema scope;
Symbol *e_type_id, *enum_id, *s_type_id;
Symbol e;
Symbol *e_type_id, *enum_id_inner, *enum_id_outer, *s_type_id;
Type enum_typ, select_typ, chk_typ;
TypeBody tb;
Expression expr, op1, op2, exp_enum_id;
@@ -68,37 +70,42 @@ int test_resolve_select_enum_member() {
*/
scope = SCHEMAcreate();
s_type_id = SYMBOLcreate("sel1", 1, "test1");
e_type_id = SYMBOLcreate("enum1", 1, "test1");
enum_id = SYMBOLcreate("val1", 1, "test1");
e = (Symbol) {.name = "sel1", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
s_type_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
/* TODO: check use of OBJ_ENUM / OBJ_TYPE */
e = (Symbol) {.name ="enum1", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
e_type_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
enum_typ = TYPEcreate_name(e_type_id);
enum_typ->symbol_table = DICTcreate(50);
enum_typ->symbol_table = HASHcreate();
enum_typ->symbol = e;
e_type_id->data = enum_typ;
/* TODO: check use of OBJ_ENUM / OBJ_TYPE */
/* TODO: OBJ_ENUM / OBJ_EXPRESSION are used interchangeably, this is confusing. */
e = (Symbol) {.name = "val1", .type = OBJ_ENUM, .ref_tok = T_ENUMERATION_REF};
enum_id_outer = HASHsearch(scope->enum_table, e, HASH_INSERT);
enum_id_inner = HASHsearch(enum_typ->symbol_table, e, HASH_INSERT);
exp_enum_id = EXPcreate(enum_typ);
exp_enum_id->symbol = *enum_id;
exp_enum_id->symbol = e;
exp_enum_id->u.integer = 1;
enum_id_outer->data = exp_enum_id;
enum_id_inner->data = exp_enum_id;
tb = TYPEBODYcreate(enumeration_);
tb->list = LISTcreate();
LISTadd_last(tb->list, enum_id);
LISTadd_last(tb->list, enum_id_inner);
enum_typ->u.type->body = tb;
DICT_define(scope->symbol_table, e_type_id->name, enum_typ, &enum_typ->symbol, OBJ_TYPE);
/* TODO: OBJ_ENUM / OBJ_EXPRESSION are used interchangeably, this is confusing. */
DICT_define(scope->enum_table, exp_enum_id->symbol.name, exp_enum_id, &exp_enum_id->symbol, OBJ_EXPRESSION);
DICT_define(enum_typ->symbol_table, enum_id->name, exp_enum_id, enum_id, OBJ_EXPRESSION);
select_typ = TYPEcreate_name(s_type_id);
s_type_id->data = select_typ;
tb = TYPEBODYcreate(select_);
tb->list = LISTcreate();
LISTadd_last(tb->list, enum_typ);
select_typ->u.type->body = tb;
DICT_define(scope->symbol_table, s_type_id->name, select_typ, &select_typ->symbol, OBJ_TYPE);
op1 = EXPcreate_from_symbol(Type_Identifier, s_type_id);
op2 = EXPcreate_from_symbol(Type_Identifier, enum_id);
op2 = EXPcreate_from_symbol(Type_Identifier, enum_id_inner);
expr = BIN_EXPcreate(OP_DOT, op1, op2);
/*
@@ -118,25 +125,35 @@ int test_resolve_select_enum_member() {
return 0;
}
/* TODO: remove DICTlookup after eliminating DICT_type */
void EXP_resolve_entity_handler(Expression exp, Scope cxt, Type unused) {
(void) unused;
Entity ent = DICTlookup(cxt->symbol_table, exp->symbol.name);
Type typ = ent->u.entity->type;
exp->type = typ;
exp->return_type = typ;
Symbol *ep;
Entity ent;
ep = HASHsearch(cxt->symbol_table, exp->symbol, HASH_FIND);
if (!ep)
return;
ent = ep->data;
exp->type = ent->u.entity->type;
exp->return_type = ent->u.entity->type;
exp->symbol.resolved = RESOLVED;
}
Variable ENTITY_resolve_attr_handler(Entity ent, Symbol *grp_ref, Symbol *attr_ref) {
(void) grp_ref;
Variable v = DICTlookup(ent->symbol_table, attr_ref->name);
return v;
Symbol *ep;
ep = HASHsearch(ent->symbol_table, *attr_ref, HASH_FIND);
if (!ep)
return NULL;
return ep->data;
}
int test_resolve_entity_attribute() {
Schema scope;
Symbol *e_type_id, *attr_id;
Symbol e, *e_type_id, *attr_id;
Entity ent;
Type attr_typ, chk_typ;
TypeBody tb;
@@ -149,22 +166,24 @@ int test_resolve_entity_attribute() {
*/
scope = SCHEMAcreate();
e_type_id = SYMBOLcreate("entity1", 1, "test2");
e = (Symbol) {.name = "entity1", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
e_type_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(e_type_id);
DICT_define(scope->symbol_table, e_type_id->name, ent, &ent->symbol, OBJ_ENTITY);
attr_id = SYMBOLcreate("attr1", 1, "test2");
e_type_id->data = ent;
e = (Symbol) {.name = "attr1", .type = OBJ_VARIABLE, .ref_tok = T_SIMPLE_REF};
attr_id = HASHsearch(ent->symbol_table, e, HASH_INSERT);
exp_attr = EXPcreate_from_symbol(Type_Attribute, attr_id);
tb = TYPEBODYcreate(number_);
attr_typ = TYPEcreate_from_body_anonymously(tb);
attr_typ->superscope = ent;
var_attr = VARcreate(exp_attr, attr_typ);
var_attr->flags.attribute = 1;
attr_id->data = var_attr;
explicit_attr_list = LISTcreate();
LISTadd_last(explicit_attr_list, var_attr);
LISTadd_last(explicit_attr_list, var_attr);
LISTadd_last(ent->u.entity->attributes, explicit_attr_list);
DICTdefine(ent->symbol_table, attr_id->name, var_attr, &var_attr->name->symbol, OBJ_VARIABLE);
op1 = EXPcreate_from_symbol(Type_Identifier, e_type_id);
op2 = EXPcreate_from_symbol(Type_Attribute, attr_id);
+37 -41
View File
@@ -5,14 +5,16 @@
/* core */
#include "express/hash.h"
#include "express/linklist.h"
#include "expparse.h"
/* non-core */
#include "express/resolve.h"
#include "express/schema.h"
#include "../token_type.h"
#include "../parse_data.h"
#include "expscan.h"
#include "lexsupport.h"
#include "expparse.h"
#include "driver.h"
#include "fff.h"
@@ -20,10 +22,6 @@
/*
* mock globals
*/
Error ERROR_circular_reference;
Error ERROR_undefined_schema;
int yylineno;
Express yyexpresult;
Linked_List PARSEnew_schemas;
@@ -48,28 +46,22 @@ FAKE_VOID_FUNC0(ENTITYinitialize)
FAKE_VOID_FUNC0(SCHEMAinitialize)
FAKE_VOID_FUNC0(CASE_ITinitialize)
FAKE_VOID_FUNC0(EXPinitialize)
FAKE_VOID_FUNC0(SCANinitialize)
FAKE_VOID_FUNC0(EXPKWinitialize)
FAKE_VOID_FUNC0(RESOLVEcleanup)
FAKE_VOID_FUNC0(TYPEcleanup)
FAKE_VOID_FUNC0(EXPcleanup)
FAKE_VOID_FUNC0(SCANcleanup)
FAKE_VOID_FUNC0(parserInitState)
FAKE_VOID_FUNC(SCAN_lex_init, char *, FILE *)
FAKE_VOID_FUNC(ParseTrace, FILE *, char *)
FAKE_VOID_FUNC(Parse, void *, int, YYSTYPE, parse_data_t)
FAKE_VOID_FUNC(perplexFree, perplex_t)
FAKE_VOID_FUNC(ParseFree, void *, free_func_t)
FAKE_VOID_FUNC(SCHEMAdefine_use, Schema, Rename *)
FAKE_VOID_FUNC(SCHEMAdefine_reference, Schema, Rename *)
FAKE_VOID_FUNC(SCOPEresolve_subsupers, Scope)
FAKE_VOID_FUNC(SCOPEresolve_types, Scope)
FAKE_VOID_FUNC(SCOPEresolve_expressions_statements, Scope)
FAKE_VALUE_FUNC(void *, ParseAlloc, malloc_func_t)
FAKE_VALUE_FUNC(char *, SCANstrdup, const char *)
FAKE_VALUE_FUNC(perplex_t, perplexFileScanner, FILE *)
FAKE_VALUE_FUNC(int, yylex, perplex_t)
FAKE_VOID_FUNC(yyparse, void *, int, struct YYSTYPE *, struct YYSTATE *)
FAKE_VOID_FUNC(yyparseFree, void *, free_func_t)
FAKE_VOID_FUNC(yyparseTrace, FILE *, char *)
FAKE_VALUE_FUNC(void *, yyparseAlloc, malloc_func_t)
FAKE_VALUE_FUNC0(struct YYSTATE *, yystateAlloc)
FAKE_VALUE_FUNC(int, yylex, struct exp_scanner *, struct YYSTYPE *)
FAKE_VALUE_FUNC0(struct exp_scanner *, yylexAlloc)
FAKE_VALUE_FUNC(int, yylexInit, struct exp_scanner *, struct YYSTATE *, FILE *)
void setup() {
RESET_FAKE(RESOLVEinitialize);
@@ -81,58 +73,62 @@ void setup() {
RESET_FAKE(SCHEMAinitialize);
RESET_FAKE(CASE_ITinitialize);
RESET_FAKE(EXPinitialize);
RESET_FAKE(SCANinitialize);
RESET_FAKE(EXPKWinitialize);
RESET_FAKE(RESOLVEcleanup);
RESET_FAKE(TYPEcleanup);
RESET_FAKE(EXPcleanup);
RESET_FAKE(SCANcleanup);
RESET_FAKE(parserInitState);
RESET_FAKE(SCAN_lex_init);
RESET_FAKE(ParseTrace);
RESET_FAKE(Parse);
RESET_FAKE(perplexFree);
RESET_FAKE(ParseFree);
RESET_FAKE(SCHEMAdefine_use);
RESET_FAKE(SCHEMAdefine_reference);
RESET_FAKE(SCOPEresolve_subsupers);
RESET_FAKE(SCOPEresolve_types);
RESET_FAKE(SCOPEresolve_expressions_statements);
RESET_FAKE(ParseAlloc);
RESET_FAKE(SCANstrdup);
RESET_FAKE(perplexFileScanner);
RESET_FAKE(yyparse);
RESET_FAKE(yyparseFree);
RESET_FAKE(yyparseTrace);
RESET_FAKE(yyparseAlloc);
RESET_FAKE(yystateAlloc);
RESET_FAKE(yylex);
RESET_FAKE(yylexAlloc);
RESET_FAKE(yylexInit);
}
int test_express_rename_resolve() {
Scope model;
Schema cur_schema, ref_schema;
Rename *use_ref;
Entity ent;
Symbol *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id;
Symbol e, *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id;
cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp");
ent_id = SYMBOLcreate("line", 1, "cur.exp");
ent_ref = SYMBOLcreate("line", 1, "ref.exp");
ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp");
model = SCOPEcreate(OBJ_EXPRESS);
cur_schema = SCHEMAcreate();
cur_schema->u.schema->uselist = LISTcreate();
e = (Symbol) {.name = "cur_schema", .type = OBJ_SCHEMA, .data = cur_schema,
.ref_tok = T_SCHEMA_REF, .filename = "cur.exp"};
cur_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
cur_schema->symbol = *cur_schema_id;
cur_schema->u.schema->uselist = LISTcreate();
ref_schema = SCHEMAcreate();
e = (Symbol) {.name = "ref_schema", .type = OBJ_SCHEMA, .data = ref_schema,
.ref_tok = T_SCHEMA_REF, .filename = "ref.exp"};
ref_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
ref_schema->symbol = *ref_schema_id;
e = (Symbol) {.name = "line", .type = OBJ_ENTITY,
.ref_tok = T_ENTITY_REF, .filename = "cur.exp"};
ent_id = HASHsearch(ref_schema->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
DICTdefine(ref_schema->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
ent_id->data = ent;
/* TODO: create RENcreate(...), refactor SCHEMAadd_use() */
/* TODO: one of the few cases for using SYMBOLcreate(), perhaps refactor */
ent_ref = SYMBOLcreate("line", OBJ_ENTITY, T_ENTITY_REF, 1, "ref.exp");
use_ref = REN_new();
use_ref->schema_sym = ref_schema_id;
use_ref->old = ent_ref;
use_ref->nnew = ent_ref;
use_ref->rename_type = use;
use_ref->schema = ref_schema_id->data;
LISTadd_last(cur_schema->u.schema->uselist, use_ref);
use_ref->schema = ref_schema;
RENAMEresolve(use_ref, cur_schema);
+83 -58
View File
@@ -11,6 +11,7 @@
#include "express/schema.h"
#include "express/expr.h"
#include "express/type.h"
#include "expparse.h"
#include "driver.h"
#include "fff.h"
@@ -36,8 +37,8 @@ int tag_count;
DEFINE_FFF_GLOBALS
FAKE_VALUE_FUNC(void *, SCOPEfind, Scope, char *, int)
FAKE_VALUE_FUNC(Variable, VARfind, Scope, char *, int)
FAKE_VALUE_FUNC(Symbol *, SCOPEfind, Scope, char *, int)
FAKE_VALUE_FUNC(Symbol *, VARfind, Scope, char *)
FAKE_VALUE_FUNC(char *, VARget_simple_name, Variable)
FAKE_VALUE_FUNC(struct Scope_ *, ENTITYfind_inherited_entity, struct Scope_ *, char *, int)
FAKE_VALUE_FUNC(Variable, ENTITYget_named_attribute, Entity, char *)
@@ -58,9 +59,11 @@ void setup() {
RESET_FAKE(EXPRESS_fail);
}
void * SCOPEfind_handler(Scope scope, char * name, int type) {
(void) type;
return DICTlookup(scope->symbol_table, name);
Symbol *SCOPEfind_handler(Scope scope, char * name, int type) {
Symbol *ep;
ep = HASHsearch(scope->symbol_table, (Symbol) {.name = name, .type = type}, HASH_FIND);
return ep;
}
int test_exp_resolve_bad_func_call() {
@@ -70,7 +73,7 @@ int test_exp_resolve_bad_func_call() {
scope = SCHEMAcreate();
func_id = SYMBOLcreate("func1", 1, "test1");
func_id = SYMBOLcreate("func1", OBJ_FUNCTION, T_FUNCTION_REF, 1, "test1");
func_call = EXPcreate_from_symbol(Type_Funcall, func_id);
SCOPEfind_fake.custom_fake = SCOPEfind_handler;
@@ -90,7 +93,7 @@ int test_exp_resolve_func_call() {
scope = SCHEMAcreate();
func_id = SYMBOLcreate("func1", 1, "test1");
func_id = SYMBOLcreate("func1", OBJ_FUNCTION, T_FUNCTION_REF, 1, "test1");
func_call = EXPcreate_from_symbol(Type_Funcall, func_id);
func_def = TYPEcreate_nostab(func_id, scope, OBJ_FUNCTION);
@@ -104,33 +107,38 @@ int test_exp_resolve_func_call() {
return 0;
}
Variable VARfind_handler(Scope scope, char *name, int strict) {
(void) strict;
return DICTlookup(scope->symbol_table, name);
Symbol *VARfind_handler(Scope scope, char *name, int strict) {
Symbol *ep;
ep = HASHsearch(scope->symbol_table, (Symbol) {.name = name}, HASH_FIND);
return ep;
}
int test_exp_resolve_local_identifier() {
Schema scope;
Entity ent;
Expression ent_attr, ent_attr_ref;
Symbol *attr_id, *attr_ref, *ent_id;
Symbol e, *attr_id, *attr_ref, *ent_id;
Variable v_attr;
Type attr_typ;
scope = SCHEMAcreate();
ent_id = SYMBOLcreate("entity1", 1, "test_2");
ent = ENTITYcreate(ent_id);
DICT_define(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
attr_id = SYMBOLcreate("attr1", 1, "test_2");
e = (Symbol) {.name = "entity1", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
ent_id->data = ent;
e = (Symbol) {.name = "attr1", .type = OBJ_VARIABLE, .ref_tok = T_SIMPLE_REF};
attr_id = HASHsearch(ent->symbol_table, e, HASH_INSERT);
ent_attr = EXPcreate_from_symbol(Type_Attribute, attr_id);
attr_typ = TYPEcreate(real_);
v_attr = VARcreate(ent_attr, attr_typ);
v_attr->flags.attribute = true;
DICT_define(ent->symbol_table, attr_id->name, v_attr, attr_id, OBJ_VARIABLE);
attr_id->data = v_attr;
attr_ref = SYMBOLcreate("attr1", 1, "test_2");
attr_ref = SYMBOLcreate("attr1", OBJ_ENTITY, T_ENTITY_REF, 1, "test_2");
ent_attr_ref = EXPcreate_from_symbol(Type_Identifier, attr_ref);
VARfind_fake.custom_fake = VARfind_handler;
@@ -147,19 +155,22 @@ int test_entity_resolve_subtype_expr_entity() {
Schema scope;
Entity ent1, ent2;
Expression subtype_exp;
Symbol *ent1_id, *ent2_id, *ent2_ref;
Symbol e, *ent1_id, *ent2_id, *ent2_ref;
int chk;
scope = SCHEMAcreate();
ent1_id = SYMBOLcreate("ent1", 1, "test_3");
ent2_id = SYMBOLcreate("ent2", 1, "test_3");
ent2_ref = SYMBOLcreate("ent2", 1, "test_3");
ent1 = ENTITYcreate(ent1_id);
ent2 = ENTITYcreate(ent2_id);
DICTdefine(scope->symbol_table, ent1_id->name, ent1, ent1_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, ent2_id->name, ent2, ent2_id, OBJ_ENTITY);
e = (Symbol) {.name = "ent1", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent1_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent1 = ENTITYcreate(ent1_id);
ent1_id->data = ent1;
e = (Symbol) {.name = "ent2", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent2_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent2 = ENTITYcreate(ent2_id);
ent2_id->data = ent2;
ent2_ref = SYMBOLcreate("ent2", OBJ_ENTITY, T_ENTITY_REF, 1, "test_3");
subtype_exp = EXPcreate_from_symbol(Type_Identifier, ent2_ref);
ent1->superscope = scope;
ent1->u.entity->subtypes = LISTcreate();
@@ -177,25 +188,32 @@ int test_type_resolve_entity() {
Schema scope;
Type sel, ent_base;
Entity ent;
Symbol *ent_id, *sel_id;
Symbol e, *ent_id, *sel_id, *ent_base_id;
scope = SCHEMAcreate();
ent_id = SYMBOLcreate("ent", 1, "test_4");
sel_id = SYMBOLcreate("sel_typ", 1, "test_4");
ent_base = TYPEcreate_name(ent_id);
ent_base->superscope = scope;
e = (Symbol) {.name = "ent", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
ent->superscope = scope;
sel = TYPEcreate(select_);
ent_id->data = ent;
e = (Symbol) {.name = "sel_typ", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
sel_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
sel = TYPEcreate_name(sel_id);
sel->superscope = scope;
sel_id->data = sel;
ent_base_id = SYMBOLcreate("ent", OBJ_ENTITY, T_ENTITY_REF, 1, "test_5");
ent_base = TYPEcreate_name(ent_base_id);
ent_base->superscope = sel;
ent_base_id->data = ent_base;
sel->symbol = *sel_id;
sel->u.type->body = TYPEBODYcreate(select_);
sel->u.type->body->list = LISTcreate();
sel->superscope = scope;
LISTadd_last(sel->u.type->body->list, ent_base);
DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE);
SCOPEfind_fake.custom_fake = SCOPEfind_handler;
TYPE_resolve(&sel);
@@ -210,20 +228,19 @@ int test_stmt_resolve_pcall_proc() {
Function f;
Procedure p;
Statement s;
Symbol *func_id, *proc_id, *proc_ref;
Symbol e, *func_id, *proc_id, *proc_ref;
scope = SCHEMAcreate();
func_id = SYMBOLcreate("func1", 1, "test_5");
proc_id = SYMBOLcreate("proc1", 1, "test_5");
proc_ref = SYMBOLcreate("proc1", 1, "test_5");
f = ALGcreate(OBJ_FUNCTION);
DICTdefine(scope->symbol_table, func_id->name, f, func_id, OBJ_FUNCTION);
e = (Symbol) {.name = "func1", .type = OBJ_FUNCTION, .ref_tok = T_FUNCTION_REF, .data = f};
func_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
p = ALGcreate(OBJ_PROCEDURE);
DICTdefine(f->symbol_table, proc_id->name, p, proc_id, OBJ_PROCEDURE);
e = (Symbol) {.name = "proc1", .type = OBJ_PROCEDURE, .ref_tok = T_PROCEDURE_REF, .data = p};
proc_id = HASHsearch(f->symbol_table, e, HASH_INSERT);
proc_ref = SYMBOLcreate("proc1", OBJ_PROCEDURE, T_PROCEDURE_REF, 1, "test_5");
s = PCALLcreate(NULL);
s->symbol = *proc_ref;
@@ -240,11 +257,15 @@ int test_scope_resolve_named_types() {
Schema scope;
Type sel, ent_base;
Entity ent;
Symbol *ent_id, *sel_id;
Symbol e, *ent_id, *sel_id;
scope = SCHEMAcreate();
sel_id = SYMBOLcreate("sel_typ", 1, "test_4");
ent_id = SYMBOLcreate("ent", 1, "test_4");
e = (Symbol) {.name = "sel_typ", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
sel_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
e = (Symbol) {.name = "ent", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent_base = TYPEcreate(entity_);
ent_base->symbol = *ent_id;
@@ -256,9 +277,9 @@ int test_scope_resolve_named_types() {
sel->u.type->body->list = LISTcreate();
sel->superscope = scope;
LISTadd_last(sel->u.type->body->list, ent_base);
DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE);
ent_id->data = ent;
sel_id->data = sel;
SCOPEfind_fake.custom_fake = SCOPEfind_handler;
@@ -274,19 +295,23 @@ int test_scope_resolve_named_types() {
int test_entity_resolve_supertypes() {
Schema scope;
Entity ent1, ent2;
Symbol *ent1_id, *ent2_id, *ent1_ref;
Symbol e, *ent1_id, *ent2_id, *ent1_ref;
scope = SCHEMAcreate();
ent1_id = SYMBOLcreate("ent1", 1, "test_3");
ent2_id = SYMBOLcreate("ent2", 1, "test_3");
ent1_ref = SYMBOLcreate("ent1", 1, "test_3");
e = (Symbol) {.name = "ent1", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent1_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent1 = ENTITYcreate(ent1_id);
ent2 = ENTITYcreate(ent2_id);
ent1->superscope = scope;
ent2->superscope = scope;
ent1_id->data = ent1;
DICTdefine(scope->symbol_table, ent1_id->name, ent1, ent1_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, ent2_id->name, ent2, ent2_id, OBJ_ENTITY);
e = (Symbol) {.name = "ent2", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent2_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent2 = ENTITYcreate(ent2_id);
ent2->superscope = scope;
ent2_id->data = ent2;
ent1_ref = SYMBOLcreate("ent1", OBJ_ENTITY, T_ENTITY_REF, 1, "test_3");
ent2->u.entity->supertype_symbols = LISTcreate();
LISTadd_last(ent2->u.entity->supertype_symbols, ent1_ref);
+25 -16
View File
@@ -9,6 +9,7 @@
/* non-core */
#include "express/type.h"
#include "expparse.h"
#include "driver.h"
#include "fff.h"
@@ -55,25 +56,29 @@ int test_scope_resolve_expr_stmt() {
Schema scope;
Type sel, ent_base;
Entity ent;
Symbol *ent_id, *sel_id;
Symbol e, *ent_id, *sel_id, *ent_ref;
scope = SCHEMAcreate();
ent_id = SYMBOLcreate("ent", 1, "test_4");
sel_id = SYMBOLcreate("sel_typ", 1, "test_4");
ent_base = TYPEcreate_name(ent_id);
ent_base->superscope = scope;
e = (Symbol) {.name = "ent", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
ent->superscope = scope;
ent_id->data = ent;
e = (Symbol) {.name = "sel_typ", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
sel_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
sel = TYPEcreate(select_);
sel->symbol = *sel_id;
sel->u.type->body->list = LISTcreate();
sel->superscope = scope;
sel_id->data = sel;
ent_ref = SYMBOLcreate("ent", OBJ_ENTITY, T_ENTITY_REF, 1, "test_5");
ent_base = TYPEcreate_name(ent_ref);
ent_base->superscope = sel;
LISTadd_last(sel->u.type->body->list, ent_base);
DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE);
SCOPEresolve_expressions_statements(scope);
assert(ENTITYresolve_expressions_fake.call_count == 1);
@@ -86,24 +91,28 @@ int test_scope_resolve_subsupers() {
Schema scope;
Type sel, ent_base;
Entity ent;
Symbol *ent_id, *sel_id;
Symbol e, *ent_id, *sel_id, *ent_ref;
scope = SCHEMAcreate();
ent_id = SYMBOLcreate("ent", 1, "test_4");
sel_id = SYMBOLcreate("sel_typ", 1, "test_4");
ent_base = TYPEcreate_name(ent_id);
ent_base->superscope = scope;
e = (Symbol) {.name = "ent", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
ent->superscope = scope;
ent_id->data = ent;
e = (Symbol) {.name = "sel_typ", .type = OBJ_TYPE, .ref_tok = T_TYPE_REF};
sel_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
sel = TYPEcreate(select_);
sel->symbol = *sel_id;
sel->u.type->body->list = LISTcreate();
sel->superscope = scope;
LISTadd_last(sel->u.type->body->list, ent_base);
sel_id->data = sel;
DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE);
ent_ref = SYMBOLcreate("ent", OBJ_ENTITY, T_ENTITY_REF, 1, "test_6");
ent_base = TYPEcreate_name(ent_id);
ent_base->superscope = sel;
LISTadd_last(sel->u.type->body->list, ent_base);
SCOPEresolve_subsupers(scope);
+62 -34
View File
@@ -10,6 +10,7 @@
/* non-core */
#include "express/variable.h"
#include "express/scope.h"
#include "expparse.h"
#include "driver.h"
#include "fff.h"
@@ -31,7 +32,7 @@ DEFINE_FFF_GLOBALS
FAKE_VALUE_FUNC(int, EXPRESS_fail, Express)
FAKE_VOID_FUNC(SCOPE_get_entities, Scope, Linked_List)
FAKE_VALUE_FUNC(Variable, ENTITYfind_inherited_attribute, struct Scope_ *, char *, struct Symbol_ **)
FAKE_VALUE_FUNC(Symbol *, ENTITYfind_inherited_attribute, struct Scope_ *, char *, struct Symbol_ **)
void setup() {
RESET_FAKE(EXPRESS_fail)
@@ -40,28 +41,36 @@ void setup() {
}
int test_schema_define_ref() {
Express model;
Schema cur_schema, ref_schema;
Rename *ref_rename;
Symbol *cur_schema_id, *ent_ref, *ref_schema_id;
Symbol e, *cur_schema_id, *ent_ref, *ref_schema_id;
cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp");
ent_ref = SYMBOLcreate("line", 1, "ref.exp");
ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp");
model = SCOPEcreate(OBJ_EXPRESS);
e = (Symbol) {.name = "cur_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
cur_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
cur_schema = SCHEMAcreate();
cur_schema->symbol = *cur_schema_id;
cur_schema->u.schema->refdict = DICTcreate(20);
cur_schema->u.schema->refdict = HASHcreate();
cur_schema_id->data = cur_schema;
e = (Symbol) {.name = "ref_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
ref_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
ref_schema = SCHEMAcreate();
ref_schema->symbol = *ref_schema_id;
ref_schema_id->data = ref_schema;
e = (Symbol) {.name = "line", .type = OBJ_RENAME, .ref_tok = T_SIMPLE_REF};
ent_ref = HASHsearch(cur_schema->u.schema->refdict, e, HASH_INSERT);
ref_rename = REN_new();
ent_ref->data = ref_rename;
ref_rename->schema_sym = ref_schema_id;
ref_rename->old = ent_ref;
ref_rename->nnew = ent_ref;
ref_rename->rename_type = ref;
ref_rename->schema = ref_schema;
DICTdefine(cur_schema->u.schema->refdict, ent_ref->name, ref_rename, ent_ref, OBJ_RENAME);
SCHEMAdefine_reference(cur_schema, ref_rename);
@@ -71,28 +80,36 @@ int test_schema_define_ref() {
}
int test_schema_define_use() {
Express model;
Schema cur_schema, ref_schema;
Rename *use_rename;
Symbol *cur_schema_id, *ent_ref, *ref_schema_id;
Symbol e, *cur_schema_id, *ent_ref, *ref_schema_id;
cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp");
ent_ref = SYMBOLcreate("line", 1, "ref.exp");
ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp");
model = SCOPEcreate(OBJ_EXPRESS);
e = (Symbol) {.name = "cur_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
cur_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
cur_schema = SCHEMAcreate();
cur_schema->symbol = *cur_schema_id;
cur_schema->u.schema->usedict = DICTcreate(20);
cur_schema->u.schema->usedict = HASHcreate();
cur_schema_id->data = cur_schema;
e = (Symbol) {.name = "ref_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
ref_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
ref_schema = SCHEMAcreate();
ref_schema->symbol = *ref_schema_id;
ref_schema_id->data = ref_schema;
e = (Symbol) {.name = "line", .type = OBJ_RENAME, .ref_tok = T_SIMPLE_REF};
ent_ref = HASHsearch(cur_schema->u.schema->usedict, e, HASH_INSERT);
use_rename = REN_new();
ent_ref->data = use_rename;
use_rename->schema_sym = ref_schema_id;
use_rename->old = ent_ref;
use_rename->nnew = ent_ref;
use_rename->rename_type = use;
use_rename->schema = ref_schema;
DICTdefine(cur_schema->u.schema->usedict, ent_ref->name, use_rename, ent_ref, OBJ_RENAME);
SCHEMAdefine_use(cur_schema, use_rename);
@@ -106,35 +123,41 @@ int test_schema_define_use() {
* (to indicate partial reference)
*/
int test_schema_get_entities_ref() {
Express model;
Schema cur_schema, ref_schema;
Rename *ref_rename;
Entity ent;
Symbol *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id;
Symbol e, *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id;
Linked_List r;
cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp");
ent_id = SYMBOLcreate("line", 1, "cur.exp");
ent_ref = SYMBOLcreate("line", 1, "ref.exp");
ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp");
model = SCOPEcreate(OBJ_EXPRESS);
e = (Symbol) {.name = "cur_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
cur_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
cur_schema = SCHEMAcreate();
cur_schema->symbol = *cur_schema_id;
cur_schema->u.schema->refdict = DICTcreate(20);
cur_schema->u.schema->refdict = HASHcreate();
e = (Symbol) {.name = "ref_schema", .type = OBJ_SCHEMA, .ref_tok = T_SCHEMA_REF};
ref_schema_id = HASHsearch(model->symbol_table, e, HASH_INSERT);
ref_schema = SCHEMAcreate();
ref_schema->symbol = *ref_schema_id;
ent = ENTITYcreate(ent_id);
DICTdefine(ref_schema->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
e = (Symbol) {.name = "line", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(ref_schema->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(ent_id);
e = (Symbol) {.name = "line", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_ref = HASHsearch(cur_schema->u.schema->refdict, e, HASH_INSERT);
ref_rename = REN_new();
ent_ref->data = ref_rename;
ref_rename->schema_sym = ref_schema_id;
ref_rename->old = ent_ref;
ref_rename->nnew = ent_ref;
ref_rename->rename_type = ref;
ref_rename->schema = ref_schema;
ref_rename->object = ent;
DICTdefine(cur_schema->u.schema->refdict, ent_ref->name, ref_rename, ent_ref, OBJ_ENTITY);
r = LISTcreate();
cur_schema->search_id = -1;
@@ -145,32 +168,37 @@ int test_schema_get_entities_ref() {
return 0;
}
Variable
Symbol *
ENTITY_find_attr_handler(struct Scope_ *entity, char * name, struct Symbol_** down_sym)
{
Variable r;
Symbol e, *ep;
(void) down_sym;
r = DICTlookup(entity->symbol_table, name);
return r;
e = (Symbol) {.name = name};
ep = HASHsearch(entity->symbol_table, e, HASH_FIND);
return ep;
}
int test_var_find() {
Schema scope;
Symbol *e_type_id, *attr_id;
Symbol e, *e_type_id, *attr_id, *var_ref;
Entity ent;
Type attr_typ;
TypeBody tb;
Expression exp_attr;
Variable var_attr, var_ref;
Variable var_attr;
Linked_List explicit_attr_list;
scope = SCHEMAcreate();
e_type_id = SYMBOLcreate("entity1", 1, "test2");
e = (Symbol) {.name = "entity1", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
e_type_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ENTITYcreate(e_type_id);
DICT_define(scope->symbol_table, e_type_id->name, ent, &ent->symbol, OBJ_ENTITY);
e_type_id->data = ent;
attr_id = SYMBOLcreate("attr1", 1, "test2");
e = (Symbol) {.name = "attr1", .type = OBJ_VARIABLE, .ref_tok = T_SIMPLE_REF};
attr_id = HASHsearch(ent->symbol_table, e, HASH_INSERT);
exp_attr = EXPcreate_from_symbol(Type_Attribute, attr_id);
tb = TYPEBODYcreate(number_);
attr_typ = TYPEcreate_from_body_anonymously(tb);
@@ -181,11 +209,11 @@ int test_var_find() {
LISTadd_last(explicit_attr_list, var_attr);
LISTadd_last(ent->u.entity->attributes, explicit_attr_list);
DICTdefine(ent->symbol_table, attr_id->name, var_attr, &var_attr->name->symbol, OBJ_VARIABLE);
attr_id->data = var_attr;
ENTITYfind_inherited_attribute_fake.custom_fake = ENTITY_find_attr_handler;
var_ref = VARfind(ent, "attr1", 1);
var_ref = VARfind(ent, "attr1");
assert(var_ref != NULL);
+14 -13
View File
@@ -5,9 +5,9 @@
/* core */
#include "express/hash.h"
#include "express/linklist.h"
#include "expparse.h"
/* non-core */
#include "driver.h"
#include "fff.h"
@@ -21,7 +21,7 @@ int __SCOPE_search_id;
int ENTITY_MARK;
Dictionary EXPRESSbuiltins;
Hash_Table EXPRESSbuiltins;
/*
@@ -41,25 +41,26 @@ int test_scope_find() {
Schema scope;
Type sel, ent_base, chk_sel;
Entity ent, chk_ent;
Symbol *ent_id, *sel_id;
Symbol e, *ent_id, *sel_id;
scope = SCHEMAcreate();
ent_id = SYMBOLcreate("ent", 1, "test_4");
sel_id = SYMBOLcreate("sel_typ", 1, "test_4");
e = (Symbol) {.name = "ent", .type = OBJ_ENTITY, .ref_tok = T_ENTITY_REF};
ent_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
ent = ent_id->data = ENTITYcreate(ent_id);
ent->superscope = scope;
ent_base = TYPEcreate_name(ent_id);
ent_base->superscope = scope;
ent = ENTITYcreate(ent_id);
ent->superscope = scope;
sel = TYPEcreate(select_);
sel->symbol = *sel_id;
e = (Symbol) {.name = "sel_typ", .type = OBJ_TYPE,
.ref_tok = T_TYPE_REF, .data = TYPEcreate(select_)};
sel_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
sel = sel_id->data;
sel->u.type->body->list = LISTcreate();
sel->superscope = scope;
LISTadd_last(sel->u.type->body->list, ent_base);
DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY);
DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE);
scope->search_id = -1;
chk_sel = SCOPE_find(scope, "sel_typ", SCOPE_FIND_ENTITY | SCOPE_FIND_TYPE);
+10 -10
View File
@@ -5,9 +5,9 @@
/* core */
#include "express/hash.h"
#include "express/linklist.h"
#include "expparse.h"
/* non-core */
#include "driver.h"
#include "fff.h"
@@ -36,23 +36,23 @@ void setup() {
int test_type_create_user_defined_tag() {
Schema scope;
Function f;
Type t, g, chk;
Symbol *func_id, *tag_id;
Symbol e, *func_id, *tag_id;
scope = SCHEMAcreate();
func_id = SYMBOLcreate("func1", 1, "test_5");
tag_id = SYMBOLcreate("item1", 1, "test_5");
e = (Symbol) {.name = "func1", .type = OBJ_FUNCTION,
.ref_tok = T_FUNCTION_REF, .data = ALGcreate(OBJ_FUNCTION)};
func_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
f = ALGcreate(OBJ_FUNCTION);
f->symbol = *func_id;
DICTdefine(scope->symbol_table, func_id->name, f, func_id, OBJ_FUNCTION);
e = (Symbol) {.name = "item1", .type = OBJ_TAG,
.ref_tok = T_RULE_LABEL_REF};
tag_id = HASHsearch(scope->symbol_table, e, HASH_INSERT);
g = TYPEcreate(generic_);
t = TYPEcreate_nostab(tag_id, f, OBJ_TAG);
t = TYPEcreate_nostab(tag_id, func_id->data, OBJ_TAG);
chk = TYPEcreate_user_defined_tag(g, f, tag_id);
chk = TYPEcreate_user_defined_tag(g, func_id->data, tag_id);
assert(chk == t);
+33 -25
View File
@@ -52,31 +52,39 @@ struct qualifier {
};
/** simple (single-valued) node types */
typedef union YYSTYPE {
Binary binary;
Case_Item case_item;
Expression expression;
Integer iVal;
Linked_List list;
Logical logical;
Op_Code op_code;
Qualified_Attr * qualified_attr;
Real rVal;
Statement statement;
Symbol * symbol;
char * string;
Type type;
TypeBody typebody;
Variable variable;
Where where;
struct type_either type_either;
struct type_flags type_flags;
struct entity_body entity_body;
struct subsuper_decl subsuper_decl;
struct subtypes subtypes;
struct upper_lower upper_lower;
struct qualifier qualifier;
unsigned int val;
typedef struct YYSTYPE {
int scope_idx;
union {
Binary binary;
Case_Item case_item;
Expression expression;
Integer iVal;
Linked_List list;
Logical logical;
Op_Code op_code;
Qualified_Attr * qualified_attr;
Real rVal;
Statement statement;
Symbol * symbol;
char * string;
/* TODO: remove after parser rebuild / reconsider */
char *cstr;
Type type;
TypeBody typebody;
Variable variable;
Where where;
/* TODO: can probably have one integrated structure */
struct type_either type_either;
struct type_flags type_flags;
struct entity_body entity_body;
struct subsuper_decl subsuper_decl;
struct subtypes subtypes;
struct upper_lower upper_lower;
struct qualifier qualifier;
unsigned int val;
};
} YYSTYPE;
#endif
+12 -26
View File
@@ -124,45 +124,31 @@ This module implements the type abstraction. It is
#include <assert.h>
#include "sc_memmgr.h"
#include "express/hash.h"
#include "express/type.h"
Type TYPEcreate_user_defined_tag( Type base, Scope scope, struct Symbol_ *symbol ) {
Symbol *ep;
Type t;
extern int tag_count;
t = ( Type )DICTlookup( scope->symbol_table, symbol->name );
if( t ) {
if( DICT_type == OBJ_TAG ) {
return( t );
ep = HASHsearch( scope->symbol_table, (Symbol) { .name = symbol->name }, HASH_FIND );
if (ep) {
t = (Type) ep->data;
if( ep->type == OBJ_TAG ) {
return t;
} else {
/* easiest to just generate the error this way!
* following call WILL fail intentionally
*/
DICTdefine( scope->symbol_table, symbol->name, 0, symbol, OBJ_TAG );
return( 0 );
/* TODO: print error message (duplicate parameter) */
return NULL;
}
}
/* tag is undefined
* if we are outside a formal parameter list (hack, hack)
* then we can only refer to existing tags, so produce an error
*/
if( tag_count < 0 ) {
ERRORreport_with_symbol( UNDEFINED_TAG, symbol,
symbol->name );
return( 0 );
}
/* otherwise, we're in a formal parameter list,
* so it's ok to define it
*/
/* otherwise, define it */
t = TYPEcreate_nostab( symbol, scope, OBJ_TAG );
t->u.type->head = base;
/* count unique type tags inside PROC and FUNC headers */
tag_count++;
return( t );
return t;
}
/**
+1 -1
View File
@@ -97,7 +97,7 @@ void VARinitialize() {
* returns simple name of variable
* for example, if var is named SELF\xxx.yyy, return yyy
*/
extern char * VARget_simple_name( Variable v ) {
extern const char * VARget_simple_name( Variable v ) {
Expression e = VARget_name( v );
while( TYPEis_expression( EXPget_type( e ) ) ) {